diff options
author | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-06-06 07:26:02 -0400 |
---|---|---|
committer | Mark Brown <broonie@opensource.wolfsonmicro.com> | 2011-06-06 07:26:02 -0400 |
commit | aa72f6899b9fb3dc824c458234ae3507a60e462d (patch) | |
tree | 97480a3cefc3d864ffd6eb994ec09ab5d680eabe /sound | |
parent | e6a9be0bb018466896632969ba4b496d1a7caea9 (diff) | |
parent | 05d3962cc921c51059df69488c7f70ab8b6a5d88 (diff) |
Merge branch 'for-3.0' into for-3.1
Diffstat (limited to 'sound')
93 files changed, 9620 insertions, 7854 deletions
diff --git a/sound/aoa/codecs/tas.c b/sound/aoa/codecs/tas.c index 58804c7acfcf..fd2188c3df2b 100644 --- a/sound/aoa/codecs/tas.c +++ b/sound/aoa/codecs/tas.c | |||
@@ -170,7 +170,7 @@ static void tas_set_volume(struct tas *tas) | |||
170 | /* analysing the volume and mixer tables shows | 170 | /* analysing the volume and mixer tables shows |
171 | * that they are similar enough when we shift | 171 | * that they are similar enough when we shift |
172 | * the mixer table down by 4 bits. The error | 172 | * the mixer table down by 4 bits. The error |
173 | * is minuscule, in just one item the error | 173 | * is miniscule, in just one item the error |
174 | * is 1, at a value of 0x07f17b (mixer table | 174 | * is 1, at a value of 0x07f17b (mixer table |
175 | * value is 0x07f17a) */ | 175 | * value is 0x07f17a) */ |
176 | tmp = tas_gaintable[left]; | 176 | tmp = tas_gaintable[left]; |
diff --git a/sound/core/control.c b/sound/core/control.c index a08ad57c49b6..f8c5be464510 100644 --- a/sound/core/control.c +++ b/sound/core/control.c | |||
@@ -366,6 +366,70 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) | |||
366 | EXPORT_SYMBOL(snd_ctl_add); | 366 | EXPORT_SYMBOL(snd_ctl_add); |
367 | 367 | ||
368 | /** | 368 | /** |
369 | * snd_ctl_replace - replace the control instance of the card | ||
370 | * @card: the card instance | ||
371 | * @kcontrol: the control instance to replace | ||
372 | * @add_on_replace: add the control if not already added | ||
373 | * | ||
374 | * Replaces the given control. If the given control does not exist | ||
375 | * and the add_on_replace flag is set, the control is added. If the | ||
376 | * control exists, it is destroyed first. | ||
377 | * | ||
378 | * Returns zero if successful, or a negative error code on failure. | ||
379 | * | ||
380 | * It frees automatically the control which cannot be added or replaced. | ||
381 | */ | ||
382 | int snd_ctl_replace(struct snd_card *card, struct snd_kcontrol *kcontrol, | ||
383 | bool add_on_replace) | ||
384 | { | ||
385 | struct snd_ctl_elem_id id; | ||
386 | unsigned int idx; | ||
387 | struct snd_kcontrol *old; | ||
388 | int ret; | ||
389 | |||
390 | if (!kcontrol) | ||
391 | return -EINVAL; | ||
392 | if (snd_BUG_ON(!card || !kcontrol->info)) { | ||
393 | ret = -EINVAL; | ||
394 | goto error; | ||
395 | } | ||
396 | id = kcontrol->id; | ||
397 | down_write(&card->controls_rwsem); | ||
398 | old = snd_ctl_find_id(card, &id); | ||
399 | if (!old) { | ||
400 | if (add_on_replace) | ||
401 | goto add; | ||
402 | up_write(&card->controls_rwsem); | ||
403 | ret = -EINVAL; | ||
404 | goto error; | ||
405 | } | ||
406 | ret = snd_ctl_remove(card, old); | ||
407 | if (ret < 0) { | ||
408 | up_write(&card->controls_rwsem); | ||
409 | goto error; | ||
410 | } | ||
411 | add: | ||
412 | if (snd_ctl_find_hole(card, kcontrol->count) < 0) { | ||
413 | up_write(&card->controls_rwsem); | ||
414 | ret = -ENOMEM; | ||
415 | goto error; | ||
416 | } | ||
417 | list_add_tail(&kcontrol->list, &card->controls); | ||
418 | card->controls_count += kcontrol->count; | ||
419 | kcontrol->id.numid = card->last_numid + 1; | ||
420 | card->last_numid += kcontrol->count; | ||
421 | up_write(&card->controls_rwsem); | ||
422 | for (idx = 0; idx < kcontrol->count; idx++, id.index++, id.numid++) | ||
423 | snd_ctl_notify(card, SNDRV_CTL_EVENT_MASK_ADD, &id); | ||
424 | return 0; | ||
425 | |||
426 | error: | ||
427 | snd_ctl_free_one(kcontrol); | ||
428 | return ret; | ||
429 | } | ||
430 | EXPORT_SYMBOL(snd_ctl_replace); | ||
431 | |||
432 | /** | ||
369 | * snd_ctl_remove - remove the control from the card and release it | 433 | * snd_ctl_remove - remove the control from the card and release it |
370 | * @card: the card instance | 434 | * @card: the card instance |
371 | * @kcontrol: the control instance to remove | 435 | * @kcontrol: the control instance to remove |
@@ -640,13 +704,12 @@ static int snd_ctl_elem_list(struct snd_card *card, | |||
640 | struct snd_ctl_elem_list list; | 704 | struct snd_ctl_elem_list list; |
641 | struct snd_kcontrol *kctl; | 705 | struct snd_kcontrol *kctl; |
642 | struct snd_ctl_elem_id *dst, *id; | 706 | struct snd_ctl_elem_id *dst, *id; |
643 | unsigned int offset, space, first, jidx; | 707 | unsigned int offset, space, jidx; |
644 | 708 | ||
645 | if (copy_from_user(&list, _list, sizeof(list))) | 709 | if (copy_from_user(&list, _list, sizeof(list))) |
646 | return -EFAULT; | 710 | return -EFAULT; |
647 | offset = list.offset; | 711 | offset = list.offset; |
648 | space = list.space; | 712 | space = list.space; |
649 | first = 0; | ||
650 | /* try limit maximum space */ | 713 | /* try limit maximum space */ |
651 | if (space > 16384) | 714 | if (space > 16384) |
652 | return -ENOMEM; | 715 | return -ENOMEM; |
diff --git a/sound/core/init.c b/sound/core/init.c index a0080aa45ae9..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; |
@@ -514,7 +511,7 @@ static void snd_card_set_id_no_lock(struct snd_card *card, const char *nid) | |||
514 | id = card->id; | 511 | id = card->id; |
515 | 512 | ||
516 | if (*id == '\0') | 513 | if (*id == '\0') |
517 | strcpy(id, "default"); | 514 | strcpy(id, "Default"); |
518 | 515 | ||
519 | while (1) { | 516 | while (1) { |
520 | if (loops-- == 0) { | 517 | if (loops-- == 0) { |
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 64449cb8f873..f1341308beda 100644 --- a/sound/core/pcm_lib.c +++ b/sound/core/pcm_lib.c | |||
@@ -189,6 +189,7 @@ static void xrun(struct snd_pcm_substream *substream) | |||
189 | #define XRUN_LOG_CNT 10 | 189 | #define XRUN_LOG_CNT 10 |
190 | 190 | ||
191 | struct hwptr_log_entry { | 191 | struct hwptr_log_entry { |
192 | unsigned int in_interrupt; | ||
192 | unsigned long jiffies; | 193 | unsigned long jiffies; |
193 | snd_pcm_uframes_t pos; | 194 | snd_pcm_uframes_t pos; |
194 | snd_pcm_uframes_t period_size; | 195 | snd_pcm_uframes_t period_size; |
@@ -204,7 +205,7 @@ struct snd_pcm_hwptr_log { | |||
204 | }; | 205 | }; |
205 | 206 | ||
206 | static void xrun_log(struct snd_pcm_substream *substream, | 207 | static void xrun_log(struct snd_pcm_substream *substream, |
207 | snd_pcm_uframes_t pos) | 208 | snd_pcm_uframes_t pos, int in_interrupt) |
208 | { | 209 | { |
209 | struct snd_pcm_runtime *runtime = substream->runtime; | 210 | struct snd_pcm_runtime *runtime = substream->runtime; |
210 | struct snd_pcm_hwptr_log *log = runtime->hwptr_log; | 211 | struct snd_pcm_hwptr_log *log = runtime->hwptr_log; |
@@ -220,6 +221,7 @@ static void xrun_log(struct snd_pcm_substream *substream, | |||
220 | return; | 221 | return; |
221 | } | 222 | } |
222 | entry = &log->entries[log->idx]; | 223 | entry = &log->entries[log->idx]; |
224 | entry->in_interrupt = in_interrupt; | ||
223 | entry->jiffies = jiffies; | 225 | entry->jiffies = jiffies; |
224 | entry->pos = pos; | 226 | entry->pos = pos; |
225 | entry->period_size = runtime->period_size; | 227 | entry->period_size = runtime->period_size; |
@@ -246,9 +248,11 @@ static void xrun_log_show(struct snd_pcm_substream *substream) | |||
246 | entry = &log->entries[idx]; | 248 | entry = &log->entries[idx]; |
247 | if (entry->period_size == 0) | 249 | if (entry->period_size == 0) |
248 | break; | 250 | break; |
249 | snd_printd("hwptr log: %s: j=%lu, pos=%ld/%ld/%ld, " | 251 | snd_printd("hwptr log: %s: %sj=%lu, pos=%ld/%ld/%ld, " |
250 | "hwptr=%ld/%ld\n", | 252 | "hwptr=%ld/%ld\n", |
251 | name, entry->jiffies, (unsigned long)entry->pos, | 253 | name, entry->in_interrupt ? "[Q] " : "", |
254 | entry->jiffies, | ||
255 | (unsigned long)entry->pos, | ||
252 | (unsigned long)entry->period_size, | 256 | (unsigned long)entry->period_size, |
253 | (unsigned long)entry->buffer_size, | 257 | (unsigned long)entry->buffer_size, |
254 | (unsigned long)entry->old_hw_ptr, | 258 | (unsigned long)entry->old_hw_ptr, |
@@ -262,7 +266,7 @@ static void xrun_log_show(struct snd_pcm_substream *substream) | |||
262 | #else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ | 266 | #else /* ! CONFIG_SND_PCM_XRUN_DEBUG */ |
263 | 267 | ||
264 | #define hw_ptr_error(substream, fmt, args...) do { } while (0) | 268 | #define hw_ptr_error(substream, fmt, args...) do { } while (0) |
265 | #define xrun_log(substream, pos) do { } while (0) | 269 | #define xrun_log(substream, pos, in_interrupt) do { } while (0) |
266 | #define xrun_log_show(substream) do { } while (0) | 270 | #define xrun_log_show(substream) do { } while (0) |
267 | 271 | ||
268 | #endif | 272 | #endif |
@@ -326,7 +330,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream, | |||
326 | } | 330 | } |
327 | pos -= pos % runtime->min_align; | 331 | pos -= pos % runtime->min_align; |
328 | if (xrun_debug(substream, XRUN_DEBUG_LOG)) | 332 | if (xrun_debug(substream, XRUN_DEBUG_LOG)) |
329 | xrun_log(substream, pos); | 333 | xrun_log(substream, pos, in_interrupt); |
330 | hw_base = runtime->hw_ptr_base; | 334 | hw_base = runtime->hw_ptr_base; |
331 | new_hw_ptr = hw_base + pos; | 335 | new_hw_ptr = hw_base + pos; |
332 | if (in_interrupt) { | 336 | if (in_interrupt) { |
@@ -1752,8 +1756,18 @@ static int wait_for_avail(struct snd_pcm_substream *substream, | |||
1752 | wait_queue_t wait; | 1756 | wait_queue_t wait; |
1753 | int err = 0; | 1757 | int err = 0; |
1754 | snd_pcm_uframes_t avail = 0; | 1758 | snd_pcm_uframes_t avail = 0; |
1755 | long tout; | 1759 | long wait_time, tout; |
1756 | 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 | } | ||
1757 | init_waitqueue_entry(&wait, current); | 1771 | init_waitqueue_entry(&wait, current); |
1758 | add_wait_queue(&runtime->tsleep, &wait); | 1772 | add_wait_queue(&runtime->tsleep, &wait); |
1759 | for (;;) { | 1773 | for (;;) { |
@@ -1761,9 +1775,8 @@ static int wait_for_avail(struct snd_pcm_substream *substream, | |||
1761 | err = -ERESTARTSYS; | 1775 | err = -ERESTARTSYS; |
1762 | break; | 1776 | break; |
1763 | } | 1777 | } |
1764 | set_current_state(TASK_INTERRUPTIBLE); | ||
1765 | snd_pcm_stream_unlock_irq(substream); | 1778 | snd_pcm_stream_unlock_irq(substream); |
1766 | tout = schedule_timeout(msecs_to_jiffies(10000)); | 1779 | tout = schedule_timeout_interruptible(wait_time); |
1767 | snd_pcm_stream_lock_irq(substream); | 1780 | snd_pcm_stream_lock_irq(substream); |
1768 | switch (runtime->status->state) { | 1781 | switch (runtime->status->state) { |
1769 | 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/firewire/Kconfig b/sound/firewire/Kconfig index e486f48660fb..26071489970b 100644 --- a/sound/firewire/Kconfig +++ b/sound/firewire/Kconfig | |||
@@ -22,4 +22,15 @@ config SND_FIREWIRE_SPEAKERS | |||
22 | To compile this driver as a module, choose M here: the module | 22 | To compile this driver as a module, choose M here: the module |
23 | will be called snd-firewire-speakers. | 23 | will be called snd-firewire-speakers. |
24 | 24 | ||
25 | config SND_ISIGHT | ||
26 | tristate "Apple iSight microphone" | ||
27 | select SND_PCM | ||
28 | select SND_FIREWIRE_LIB | ||
29 | help | ||
30 | Say Y here to include support for the front and rear microphones | ||
31 | of the Apple iSight web camera. | ||
32 | |||
33 | To compile this driver as a module, choose M here: the module | ||
34 | will be called snd-isight. | ||
35 | |||
25 | endif # SND_FIREWIRE | 36 | endif # SND_FIREWIRE |
diff --git a/sound/firewire/Makefile b/sound/firewire/Makefile index e5b1634d9ad4..d71ed8935f76 100644 --- a/sound/firewire/Makefile +++ b/sound/firewire/Makefile | |||
@@ -1,6 +1,8 @@ | |||
1 | snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \ | 1 | snd-firewire-lib-objs := lib.o iso-resources.o packets-buffer.o \ |
2 | fcp.o cmp.o amdtp.o | 2 | fcp.o cmp.o amdtp.o |
3 | snd-firewire-speakers-objs := speakers.o | 3 | snd-firewire-speakers-objs := speakers.o |
4 | snd-isight-objs := isight.o | ||
4 | 5 | ||
5 | obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o | 6 | obj-$(CONFIG_SND_FIREWIRE_LIB) += snd-firewire-lib.o |
6 | obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o | 7 | obj-$(CONFIG_SND_FIREWIRE_SPEAKERS) += snd-firewire-speakers.o |
8 | obj-$(CONFIG_SND_ISIGHT) += snd-isight.o | ||
diff --git a/sound/firewire/amdtp.c b/sound/firewire/amdtp.c index b18140ff2b93..87657dd7714c 100644 --- a/sound/firewire/amdtp.c +++ b/sound/firewire/amdtp.c | |||
@@ -396,6 +396,7 @@ static void out_packet_callback(struct fw_iso_context *context, u32 cycle, | |||
396 | 396 | ||
397 | for (i = 0; i < packets; ++i) | 397 | for (i = 0; i < packets; ++i) |
398 | queue_out_packet(s, ++cycle); | 398 | queue_out_packet(s, ++cycle); |
399 | fw_iso_context_queue_flush(s->context); | ||
399 | } | 400 | } |
400 | 401 | ||
401 | static int queue_initial_skip_packets(struct amdtp_out_stream *s) | 402 | static int queue_initial_skip_packets(struct amdtp_out_stream *s) |
diff --git a/sound/firewire/cmp.c b/sound/firewire/cmp.c index 4a37f3a6fab9..14cacbc655dd 100644 --- a/sound/firewire/cmp.c +++ b/sound/firewire/cmp.c | |||
@@ -49,10 +49,9 @@ static int pcr_modify(struct cmp_connection *c, | |||
49 | enum bus_reset_handling bus_reset_handling) | 49 | enum bus_reset_handling bus_reset_handling) |
50 | { | 50 | { |
51 | struct fw_device *device = fw_parent_device(c->resources.unit); | 51 | struct fw_device *device = fw_parent_device(c->resources.unit); |
52 | __be32 *buffer = c->resources.buffer; | ||
53 | int generation = c->resources.generation; | 52 | int generation = c->resources.generation; |
54 | int rcode, errors = 0; | 53 | int rcode, errors = 0; |
55 | __be32 old_arg; | 54 | __be32 old_arg, buffer[2]; |
56 | int err; | 55 | int err; |
57 | 56 | ||
58 | buffer[0] = c->last_pcr_value; | 57 | buffer[0] = c->last_pcr_value; |
diff --git a/sound/firewire/isight.c b/sound/firewire/isight.c new file mode 100644 index 000000000000..86ee16ca365e --- /dev/null +++ b/sound/firewire/isight.c | |||
@@ -0,0 +1,755 @@ | |||
1 | /* | ||
2 | * Apple iSight audio driver | ||
3 | * | ||
4 | * Copyright (c) Clemens Ladisch <clemens@ladisch.de> | ||
5 | * Licensed under the terms of the GNU General Public License, version 2. | ||
6 | */ | ||
7 | |||
8 | #include <asm/byteorder.h> | ||
9 | #include <linux/delay.h> | ||
10 | #include <linux/device.h> | ||
11 | #include <linux/firewire.h> | ||
12 | #include <linux/firewire-constants.h> | ||
13 | #include <linux/module.h> | ||
14 | #include <linux/mod_devicetable.h> | ||
15 | #include <linux/mutex.h> | ||
16 | #include <linux/string.h> | ||
17 | #include <sound/control.h> | ||
18 | #include <sound/core.h> | ||
19 | #include <sound/initval.h> | ||
20 | #include <sound/pcm.h> | ||
21 | #include <sound/tlv.h> | ||
22 | #include "lib.h" | ||
23 | #include "iso-resources.h" | ||
24 | #include "packets-buffer.h" | ||
25 | |||
26 | #define OUI_APPLE 0x000a27 | ||
27 | #define MODEL_APPLE_ISIGHT 0x000008 | ||
28 | #define SW_ISIGHT_AUDIO 0x000010 | ||
29 | |||
30 | #define REG_AUDIO_ENABLE 0x000 | ||
31 | #define AUDIO_ENABLE 0x80000000 | ||
32 | #define REG_DEF_AUDIO_GAIN 0x204 | ||
33 | #define REG_GAIN_RAW_START 0x210 | ||
34 | #define REG_GAIN_RAW_END 0x214 | ||
35 | #define REG_GAIN_DB_START 0x218 | ||
36 | #define REG_GAIN_DB_END 0x21c | ||
37 | #define REG_SAMPLE_RATE_INQUIRY 0x280 | ||
38 | #define REG_ISO_TX_CONFIG 0x300 | ||
39 | #define SPEED_SHIFT 16 | ||
40 | #define REG_SAMPLE_RATE 0x400 | ||
41 | #define RATE_48000 0x80000000 | ||
42 | #define REG_GAIN 0x500 | ||
43 | #define REG_MUTE 0x504 | ||
44 | |||
45 | #define MAX_FRAMES_PER_PACKET 475 | ||
46 | |||
47 | #define QUEUE_LENGTH 20 | ||
48 | |||
49 | struct isight { | ||
50 | struct snd_card *card; | ||
51 | struct fw_unit *unit; | ||
52 | struct fw_device *device; | ||
53 | u64 audio_base; | ||
54 | struct fw_address_handler iris_handler; | ||
55 | struct snd_pcm_substream *pcm; | ||
56 | struct mutex mutex; | ||
57 | struct iso_packets_buffer buffer; | ||
58 | struct fw_iso_resources resources; | ||
59 | struct fw_iso_context *context; | ||
60 | bool pcm_active; | ||
61 | bool pcm_running; | ||
62 | bool first_packet; | ||
63 | int packet_index; | ||
64 | u32 total_samples; | ||
65 | unsigned int buffer_pointer; | ||
66 | unsigned int period_counter; | ||
67 | s32 gain_min, gain_max; | ||
68 | unsigned int gain_tlv[4]; | ||
69 | }; | ||
70 | |||
71 | struct audio_payload { | ||
72 | __be32 sample_count; | ||
73 | __be32 signature; | ||
74 | __be32 sample_total; | ||
75 | __be32 reserved; | ||
76 | __be16 samples[2 * MAX_FRAMES_PER_PACKET]; | ||
77 | }; | ||
78 | |||
79 | MODULE_DESCRIPTION("iSight audio driver"); | ||
80 | MODULE_AUTHOR("Clemens Ladisch <clemens@ladisch.de>"); | ||
81 | MODULE_LICENSE("GPL v2"); | ||
82 | |||
83 | static struct fw_iso_packet audio_packet = { | ||
84 | .payload_length = sizeof(struct audio_payload), | ||
85 | .interrupt = 1, | ||
86 | .header_length = 4, | ||
87 | }; | ||
88 | |||
89 | static void isight_update_pointers(struct isight *isight, unsigned int count) | ||
90 | { | ||
91 | struct snd_pcm_runtime *runtime = isight->pcm->runtime; | ||
92 | unsigned int ptr; | ||
93 | |||
94 | smp_wmb(); /* update buffer data before buffer pointer */ | ||
95 | |||
96 | ptr = isight->buffer_pointer; | ||
97 | ptr += count; | ||
98 | if (ptr >= runtime->buffer_size) | ||
99 | ptr -= runtime->buffer_size; | ||
100 | ACCESS_ONCE(isight->buffer_pointer) = ptr; | ||
101 | |||
102 | isight->period_counter += count; | ||
103 | if (isight->period_counter >= runtime->period_size) { | ||
104 | isight->period_counter -= runtime->period_size; | ||
105 | snd_pcm_period_elapsed(isight->pcm); | ||
106 | } | ||
107 | } | ||
108 | |||
109 | static void isight_samples(struct isight *isight, | ||
110 | const __be16 *samples, unsigned int count) | ||
111 | { | ||
112 | struct snd_pcm_runtime *runtime; | ||
113 | unsigned int count1; | ||
114 | |||
115 | if (!ACCESS_ONCE(isight->pcm_running)) | ||
116 | return; | ||
117 | |||
118 | runtime = isight->pcm->runtime; | ||
119 | if (isight->buffer_pointer + count <= runtime->buffer_size) { | ||
120 | memcpy(runtime->dma_area + isight->buffer_pointer * 4, | ||
121 | samples, count * 4); | ||
122 | } else { | ||
123 | count1 = runtime->buffer_size - isight->buffer_pointer; | ||
124 | memcpy(runtime->dma_area + isight->buffer_pointer * 4, | ||
125 | samples, count1 * 4); | ||
126 | samples += count1 * 2; | ||
127 | memcpy(runtime->dma_area, samples, (count - count1) * 4); | ||
128 | } | ||
129 | |||
130 | isight_update_pointers(isight, count); | ||
131 | } | ||
132 | |||
133 | static void isight_pcm_abort(struct isight *isight) | ||
134 | { | ||
135 | unsigned long flags; | ||
136 | |||
137 | if (ACCESS_ONCE(isight->pcm_active)) { | ||
138 | snd_pcm_stream_lock_irqsave(isight->pcm, flags); | ||
139 | if (snd_pcm_running(isight->pcm)) | ||
140 | snd_pcm_stop(isight->pcm, SNDRV_PCM_STATE_XRUN); | ||
141 | snd_pcm_stream_unlock_irqrestore(isight->pcm, flags); | ||
142 | } | ||
143 | } | ||
144 | |||
145 | static void isight_dropped_samples(struct isight *isight, unsigned int total) | ||
146 | { | ||
147 | struct snd_pcm_runtime *runtime; | ||
148 | u32 dropped; | ||
149 | unsigned int count1; | ||
150 | |||
151 | if (!ACCESS_ONCE(isight->pcm_running)) | ||
152 | return; | ||
153 | |||
154 | runtime = isight->pcm->runtime; | ||
155 | dropped = total - isight->total_samples; | ||
156 | if (dropped < runtime->buffer_size) { | ||
157 | if (isight->buffer_pointer + dropped <= runtime->buffer_size) { | ||
158 | memset(runtime->dma_area + isight->buffer_pointer * 4, | ||
159 | 0, dropped * 4); | ||
160 | } else { | ||
161 | count1 = runtime->buffer_size - isight->buffer_pointer; | ||
162 | memset(runtime->dma_area + isight->buffer_pointer * 4, | ||
163 | 0, count1 * 4); | ||
164 | memset(runtime->dma_area, 0, (dropped - count1) * 4); | ||
165 | } | ||
166 | isight_update_pointers(isight, dropped); | ||
167 | } else { | ||
168 | isight_pcm_abort(isight); | ||
169 | } | ||
170 | } | ||
171 | |||
172 | static void isight_packet(struct fw_iso_context *context, u32 cycle, | ||
173 | size_t header_length, void *header, void *data) | ||
174 | { | ||
175 | struct isight *isight = data; | ||
176 | const struct audio_payload *payload; | ||
177 | unsigned int index, length, count, total; | ||
178 | int err; | ||
179 | |||
180 | if (isight->packet_index < 0) | ||
181 | return; | ||
182 | index = isight->packet_index; | ||
183 | payload = isight->buffer.packets[index].buffer; | ||
184 | length = be32_to_cpup(header) >> 16; | ||
185 | |||
186 | if (likely(length >= 16 && | ||
187 | payload->signature == cpu_to_be32(0x73676874/*"sght"*/))) { | ||
188 | count = be32_to_cpu(payload->sample_count); | ||
189 | if (likely(count <= (length - 16) / 4)) { | ||
190 | total = be32_to_cpu(payload->sample_total); | ||
191 | if (unlikely(total != isight->total_samples)) { | ||
192 | if (!isight->first_packet) | ||
193 | isight_dropped_samples(isight, total); | ||
194 | isight->first_packet = false; | ||
195 | isight->total_samples = total; | ||
196 | } | ||
197 | |||
198 | isight_samples(isight, payload->samples, count); | ||
199 | isight->total_samples += count; | ||
200 | } | ||
201 | } | ||
202 | |||
203 | err = fw_iso_context_queue(isight->context, &audio_packet, | ||
204 | &isight->buffer.iso_buffer, | ||
205 | isight->buffer.packets[index].offset); | ||
206 | if (err < 0) { | ||
207 | dev_err(&isight->unit->device, "queueing error: %d\n", err); | ||
208 | isight_pcm_abort(isight); | ||
209 | isight->packet_index = -1; | ||
210 | return; | ||
211 | } | ||
212 | |||
213 | if (++index >= QUEUE_LENGTH) | ||
214 | index = 0; | ||
215 | isight->packet_index = index; | ||
216 | } | ||
217 | |||
218 | static int isight_connect(struct isight *isight) | ||
219 | { | ||
220 | int ch, err, rcode, errors = 0; | ||
221 | __be32 value; | ||
222 | |||
223 | retry_after_bus_reset: | ||
224 | ch = fw_iso_resources_allocate(&isight->resources, | ||
225 | sizeof(struct audio_payload), | ||
226 | isight->device->max_speed); | ||
227 | if (ch < 0) { | ||
228 | err = ch; | ||
229 | goto error; | ||
230 | } | ||
231 | |||
232 | value = cpu_to_be32(ch | (isight->device->max_speed << SPEED_SHIFT)); | ||
233 | for (;;) { | ||
234 | rcode = fw_run_transaction( | ||
235 | isight->device->card, | ||
236 | TCODE_WRITE_QUADLET_REQUEST, | ||
237 | isight->device->node_id, | ||
238 | isight->resources.generation, | ||
239 | isight->device->max_speed, | ||
240 | isight->audio_base + REG_ISO_TX_CONFIG, | ||
241 | &value, 4); | ||
242 | if (rcode == RCODE_COMPLETE) { | ||
243 | return 0; | ||
244 | } else if (rcode == RCODE_GENERATION) { | ||
245 | fw_iso_resources_free(&isight->resources); | ||
246 | goto retry_after_bus_reset; | ||
247 | } else if (rcode_is_permanent_error(rcode) || ++errors >= 3) { | ||
248 | err = -EIO; | ||
249 | goto err_resources; | ||
250 | } | ||
251 | msleep(5); | ||
252 | } | ||
253 | |||
254 | err_resources: | ||
255 | fw_iso_resources_free(&isight->resources); | ||
256 | error: | ||
257 | return err; | ||
258 | } | ||
259 | |||
260 | static int isight_open(struct snd_pcm_substream *substream) | ||
261 | { | ||
262 | static const struct snd_pcm_hardware hardware = { | ||
263 | .info = SNDRV_PCM_INFO_MMAP | | ||
264 | SNDRV_PCM_INFO_MMAP_VALID | | ||
265 | SNDRV_PCM_INFO_BATCH | | ||
266 | SNDRV_PCM_INFO_INTERLEAVED | | ||
267 | SNDRV_PCM_INFO_BLOCK_TRANSFER, | ||
268 | .formats = SNDRV_PCM_FMTBIT_S16_BE, | ||
269 | .rates = SNDRV_PCM_RATE_48000, | ||
270 | .rate_min = 48000, | ||
271 | .rate_max = 48000, | ||
272 | .channels_min = 2, | ||
273 | .channels_max = 2, | ||
274 | .buffer_bytes_max = 4 * 1024 * 1024, | ||
275 | .period_bytes_min = MAX_FRAMES_PER_PACKET * 4, | ||
276 | .period_bytes_max = 1024 * 1024, | ||
277 | .periods_min = 2, | ||
278 | .periods_max = UINT_MAX, | ||
279 | }; | ||
280 | struct isight *isight = substream->private_data; | ||
281 | |||
282 | substream->runtime->hw = hardware; | ||
283 | |||
284 | return iso_packets_buffer_init(&isight->buffer, isight->unit, | ||
285 | QUEUE_LENGTH, | ||
286 | sizeof(struct audio_payload), | ||
287 | DMA_FROM_DEVICE); | ||
288 | } | ||
289 | |||
290 | static int isight_close(struct snd_pcm_substream *substream) | ||
291 | { | ||
292 | struct isight *isight = substream->private_data; | ||
293 | |||
294 | iso_packets_buffer_destroy(&isight->buffer, isight->unit); | ||
295 | |||
296 | return 0; | ||
297 | } | ||
298 | |||
299 | static int isight_hw_params(struct snd_pcm_substream *substream, | ||
300 | struct snd_pcm_hw_params *hw_params) | ||
301 | { | ||
302 | struct isight *isight = substream->private_data; | ||
303 | int err; | ||
304 | |||
305 | err = snd_pcm_lib_alloc_vmalloc_buffer(substream, | ||
306 | params_buffer_bytes(hw_params)); | ||
307 | if (err < 0) | ||
308 | return err; | ||
309 | |||
310 | ACCESS_ONCE(isight->pcm_active) = true; | ||
311 | |||
312 | return 0; | ||
313 | } | ||
314 | |||
315 | static int reg_read(struct isight *isight, int offset, __be32 *value) | ||
316 | { | ||
317 | return snd_fw_transaction(isight->unit, TCODE_READ_QUADLET_REQUEST, | ||
318 | isight->audio_base + offset, value, 4); | ||
319 | } | ||
320 | |||
321 | static int reg_write(struct isight *isight, int offset, __be32 value) | ||
322 | { | ||
323 | return snd_fw_transaction(isight->unit, TCODE_WRITE_QUADLET_REQUEST, | ||
324 | isight->audio_base + offset, &value, 4); | ||
325 | } | ||
326 | |||
327 | static void isight_stop_streaming(struct isight *isight) | ||
328 | { | ||
329 | if (!isight->context) | ||
330 | return; | ||
331 | |||
332 | fw_iso_context_stop(isight->context); | ||
333 | fw_iso_context_destroy(isight->context); | ||
334 | isight->context = NULL; | ||
335 | fw_iso_resources_free(&isight->resources); | ||
336 | reg_write(isight, REG_AUDIO_ENABLE, 0); | ||
337 | } | ||
338 | |||
339 | static int isight_hw_free(struct snd_pcm_substream *substream) | ||
340 | { | ||
341 | struct isight *isight = substream->private_data; | ||
342 | |||
343 | ACCESS_ONCE(isight->pcm_active) = false; | ||
344 | |||
345 | mutex_lock(&isight->mutex); | ||
346 | isight_stop_streaming(isight); | ||
347 | mutex_unlock(&isight->mutex); | ||
348 | |||
349 | return snd_pcm_lib_free_vmalloc_buffer(substream); | ||
350 | } | ||
351 | |||
352 | static int isight_start_streaming(struct isight *isight) | ||
353 | { | ||
354 | unsigned int i; | ||
355 | int err; | ||
356 | |||
357 | if (isight->context) { | ||
358 | if (isight->packet_index < 0) | ||
359 | isight_stop_streaming(isight); | ||
360 | else | ||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | err = reg_write(isight, REG_SAMPLE_RATE, cpu_to_be32(RATE_48000)); | ||
365 | if (err < 0) | ||
366 | goto error; | ||
367 | |||
368 | err = isight_connect(isight); | ||
369 | if (err < 0) | ||
370 | goto error; | ||
371 | |||
372 | err = reg_write(isight, REG_AUDIO_ENABLE, cpu_to_be32(AUDIO_ENABLE)); | ||
373 | if (err < 0) | ||
374 | goto err_resources; | ||
375 | |||
376 | isight->context = fw_iso_context_create(isight->device->card, | ||
377 | FW_ISO_CONTEXT_RECEIVE, | ||
378 | isight->resources.channel, | ||
379 | isight->device->max_speed, | ||
380 | 4, isight_packet, isight); | ||
381 | if (IS_ERR(isight->context)) { | ||
382 | err = PTR_ERR(isight->context); | ||
383 | isight->context = NULL; | ||
384 | goto err_resources; | ||
385 | } | ||
386 | |||
387 | for (i = 0; i < QUEUE_LENGTH; ++i) { | ||
388 | err = fw_iso_context_queue(isight->context, &audio_packet, | ||
389 | &isight->buffer.iso_buffer, | ||
390 | isight->buffer.packets[i].offset); | ||
391 | if (err < 0) | ||
392 | goto err_context; | ||
393 | } | ||
394 | |||
395 | isight->first_packet = true; | ||
396 | isight->packet_index = 0; | ||
397 | |||
398 | err = fw_iso_context_start(isight->context, -1, 0, | ||
399 | FW_ISO_CONTEXT_MATCH_ALL_TAGS/*?*/); | ||
400 | if (err < 0) | ||
401 | goto err_context; | ||
402 | |||
403 | return 0; | ||
404 | |||
405 | err_context: | ||
406 | fw_iso_context_destroy(isight->context); | ||
407 | isight->context = NULL; | ||
408 | err_resources: | ||
409 | fw_iso_resources_free(&isight->resources); | ||
410 | reg_write(isight, REG_AUDIO_ENABLE, 0); | ||
411 | error: | ||
412 | return err; | ||
413 | } | ||
414 | |||
415 | static int isight_prepare(struct snd_pcm_substream *substream) | ||
416 | { | ||
417 | struct isight *isight = substream->private_data; | ||
418 | int err; | ||
419 | |||
420 | isight->buffer_pointer = 0; | ||
421 | isight->period_counter = 0; | ||
422 | |||
423 | mutex_lock(&isight->mutex); | ||
424 | err = isight_start_streaming(isight); | ||
425 | mutex_unlock(&isight->mutex); | ||
426 | |||
427 | return err; | ||
428 | } | ||
429 | |||
430 | static int isight_trigger(struct snd_pcm_substream *substream, int cmd) | ||
431 | { | ||
432 | struct isight *isight = substream->private_data; | ||
433 | |||
434 | switch (cmd) { | ||
435 | case SNDRV_PCM_TRIGGER_START: | ||
436 | ACCESS_ONCE(isight->pcm_running) = true; | ||
437 | break; | ||
438 | case SNDRV_PCM_TRIGGER_STOP: | ||
439 | ACCESS_ONCE(isight->pcm_running) = false; | ||
440 | break; | ||
441 | default: | ||
442 | return -EINVAL; | ||
443 | } | ||
444 | return 0; | ||
445 | } | ||
446 | |||
447 | static snd_pcm_uframes_t isight_pointer(struct snd_pcm_substream *substream) | ||
448 | { | ||
449 | struct isight *isight = substream->private_data; | ||
450 | |||
451 | return ACCESS_ONCE(isight->buffer_pointer); | ||
452 | } | ||
453 | |||
454 | static int isight_create_pcm(struct isight *isight) | ||
455 | { | ||
456 | static struct snd_pcm_ops ops = { | ||
457 | .open = isight_open, | ||
458 | .close = isight_close, | ||
459 | .ioctl = snd_pcm_lib_ioctl, | ||
460 | .hw_params = isight_hw_params, | ||
461 | .hw_free = isight_hw_free, | ||
462 | .prepare = isight_prepare, | ||
463 | .trigger = isight_trigger, | ||
464 | .pointer = isight_pointer, | ||
465 | .page = snd_pcm_lib_get_vmalloc_page, | ||
466 | .mmap = snd_pcm_lib_mmap_vmalloc, | ||
467 | }; | ||
468 | struct snd_pcm *pcm; | ||
469 | int err; | ||
470 | |||
471 | err = snd_pcm_new(isight->card, "iSight", 0, 0, 1, &pcm); | ||
472 | if (err < 0) | ||
473 | return err; | ||
474 | pcm->private_data = isight; | ||
475 | strcpy(pcm->name, "iSight"); | ||
476 | isight->pcm = pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; | ||
477 | isight->pcm->ops = &ops; | ||
478 | |||
479 | return 0; | ||
480 | } | ||
481 | |||
482 | static int isight_gain_info(struct snd_kcontrol *ctl, | ||
483 | struct snd_ctl_elem_info *info) | ||
484 | { | ||
485 | struct isight *isight = ctl->private_data; | ||
486 | |||
487 | info->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
488 | info->count = 1; | ||
489 | info->value.integer.min = isight->gain_min; | ||
490 | info->value.integer.max = isight->gain_max; | ||
491 | |||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | static int isight_gain_get(struct snd_kcontrol *ctl, | ||
496 | struct snd_ctl_elem_value *value) | ||
497 | { | ||
498 | struct isight *isight = ctl->private_data; | ||
499 | __be32 gain; | ||
500 | int err; | ||
501 | |||
502 | err = reg_read(isight, REG_GAIN, &gain); | ||
503 | if (err < 0) | ||
504 | return err; | ||
505 | |||
506 | value->value.integer.value[0] = (s32)be32_to_cpu(gain); | ||
507 | |||
508 | return 0; | ||
509 | } | ||
510 | |||
511 | static int isight_gain_put(struct snd_kcontrol *ctl, | ||
512 | struct snd_ctl_elem_value *value) | ||
513 | { | ||
514 | struct isight *isight = ctl->private_data; | ||
515 | |||
516 | if (value->value.integer.value[0] < isight->gain_min || | ||
517 | value->value.integer.value[0] > isight->gain_max) | ||
518 | return -EINVAL; | ||
519 | |||
520 | return reg_write(isight, REG_GAIN, | ||
521 | cpu_to_be32(value->value.integer.value[0])); | ||
522 | } | ||
523 | |||
524 | static int isight_mute_get(struct snd_kcontrol *ctl, | ||
525 | struct snd_ctl_elem_value *value) | ||
526 | { | ||
527 | struct isight *isight = ctl->private_data; | ||
528 | __be32 mute; | ||
529 | int err; | ||
530 | |||
531 | err = reg_read(isight, REG_MUTE, &mute); | ||
532 | if (err < 0) | ||
533 | return err; | ||
534 | |||
535 | value->value.integer.value[0] = !mute; | ||
536 | |||
537 | return 0; | ||
538 | } | ||
539 | |||
540 | static int isight_mute_put(struct snd_kcontrol *ctl, | ||
541 | struct snd_ctl_elem_value *value) | ||
542 | { | ||
543 | struct isight *isight = ctl->private_data; | ||
544 | |||
545 | return reg_write(isight, REG_MUTE, | ||
546 | (__force __be32)!value->value.integer.value[0]); | ||
547 | } | ||
548 | |||
549 | static int isight_create_mixer(struct isight *isight) | ||
550 | { | ||
551 | static const struct snd_kcontrol_new gain_control = { | ||
552 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
553 | .name = "Mic Capture Volume", | ||
554 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
555 | SNDRV_CTL_ELEM_ACCESS_TLV_READ, | ||
556 | .info = isight_gain_info, | ||
557 | .get = isight_gain_get, | ||
558 | .put = isight_gain_put, | ||
559 | }; | ||
560 | static const struct snd_kcontrol_new mute_control = { | ||
561 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
562 | .name = "Mic Capture Switch", | ||
563 | .info = snd_ctl_boolean_mono_info, | ||
564 | .get = isight_mute_get, | ||
565 | .put = isight_mute_put, | ||
566 | }; | ||
567 | __be32 value; | ||
568 | struct snd_kcontrol *ctl; | ||
569 | int err; | ||
570 | |||
571 | err = reg_read(isight, REG_GAIN_RAW_START, &value); | ||
572 | if (err < 0) | ||
573 | return err; | ||
574 | isight->gain_min = be32_to_cpu(value); | ||
575 | |||
576 | err = reg_read(isight, REG_GAIN_RAW_END, &value); | ||
577 | if (err < 0) | ||
578 | return err; | ||
579 | isight->gain_max = be32_to_cpu(value); | ||
580 | |||
581 | isight->gain_tlv[0] = SNDRV_CTL_TLVT_DB_MINMAX; | ||
582 | isight->gain_tlv[1] = 2 * sizeof(unsigned int); | ||
583 | |||
584 | err = reg_read(isight, REG_GAIN_DB_START, &value); | ||
585 | if (err < 0) | ||
586 | return err; | ||
587 | isight->gain_tlv[2] = (s32)be32_to_cpu(value) * 100; | ||
588 | |||
589 | err = reg_read(isight, REG_GAIN_DB_END, &value); | ||
590 | if (err < 0) | ||
591 | return err; | ||
592 | isight->gain_tlv[3] = (s32)be32_to_cpu(value) * 100; | ||
593 | |||
594 | ctl = snd_ctl_new1(&gain_control, isight); | ||
595 | if (ctl) | ||
596 | ctl->tlv.p = isight->gain_tlv; | ||
597 | err = snd_ctl_add(isight->card, ctl); | ||
598 | if (err < 0) | ||
599 | return err; | ||
600 | |||
601 | err = snd_ctl_add(isight->card, snd_ctl_new1(&mute_control, isight)); | ||
602 | if (err < 0) | ||
603 | return err; | ||
604 | |||
605 | return 0; | ||
606 | } | ||
607 | |||
608 | static void isight_card_free(struct snd_card *card) | ||
609 | { | ||
610 | struct isight *isight = card->private_data; | ||
611 | |||
612 | fw_iso_resources_destroy(&isight->resources); | ||
613 | fw_unit_put(isight->unit); | ||
614 | fw_device_put(isight->device); | ||
615 | mutex_destroy(&isight->mutex); | ||
616 | } | ||
617 | |||
618 | static u64 get_unit_base(struct fw_unit *unit) | ||
619 | { | ||
620 | struct fw_csr_iterator i; | ||
621 | int key, value; | ||
622 | |||
623 | fw_csr_iterator_init(&i, unit->directory); | ||
624 | while (fw_csr_iterator_next(&i, &key, &value)) | ||
625 | if (key == CSR_OFFSET) | ||
626 | return CSR_REGISTER_BASE + value * 4; | ||
627 | return 0; | ||
628 | } | ||
629 | |||
630 | static int isight_probe(struct device *unit_dev) | ||
631 | { | ||
632 | struct fw_unit *unit = fw_unit(unit_dev); | ||
633 | struct fw_device *fw_dev = fw_parent_device(unit); | ||
634 | struct snd_card *card; | ||
635 | struct isight *isight; | ||
636 | int err; | ||
637 | |||
638 | err = snd_card_create(-1, NULL, THIS_MODULE, sizeof(*isight), &card); | ||
639 | if (err < 0) | ||
640 | return err; | ||
641 | snd_card_set_dev(card, unit_dev); | ||
642 | |||
643 | isight = card->private_data; | ||
644 | isight->card = card; | ||
645 | mutex_init(&isight->mutex); | ||
646 | isight->unit = fw_unit_get(unit); | ||
647 | isight->device = fw_device_get(fw_dev); | ||
648 | isight->audio_base = get_unit_base(unit); | ||
649 | if (!isight->audio_base) { | ||
650 | dev_err(&unit->device, "audio unit base not found\n"); | ||
651 | err = -ENXIO; | ||
652 | goto err_unit; | ||
653 | } | ||
654 | fw_iso_resources_init(&isight->resources, unit); | ||
655 | |||
656 | card->private_free = isight_card_free; | ||
657 | |||
658 | strcpy(card->driver, "iSight"); | ||
659 | strcpy(card->shortname, "Apple iSight"); | ||
660 | snprintf(card->longname, sizeof(card->longname), | ||
661 | "Apple iSight (GUID %08x%08x) at %s, S%d", | ||
662 | fw_dev->config_rom[3], fw_dev->config_rom[4], | ||
663 | dev_name(&unit->device), 100 << fw_dev->max_speed); | ||
664 | strcpy(card->mixername, "iSight"); | ||
665 | |||
666 | err = isight_create_pcm(isight); | ||
667 | if (err < 0) | ||
668 | goto error; | ||
669 | |||
670 | err = isight_create_mixer(isight); | ||
671 | if (err < 0) | ||
672 | goto error; | ||
673 | |||
674 | err = snd_card_register(card); | ||
675 | if (err < 0) | ||
676 | goto error; | ||
677 | |||
678 | dev_set_drvdata(unit_dev, isight); | ||
679 | |||
680 | return 0; | ||
681 | |||
682 | err_unit: | ||
683 | fw_unit_put(isight->unit); | ||
684 | fw_device_put(isight->device); | ||
685 | mutex_destroy(&isight->mutex); | ||
686 | error: | ||
687 | snd_card_free(card); | ||
688 | return err; | ||
689 | } | ||
690 | |||
691 | static int isight_remove(struct device *dev) | ||
692 | { | ||
693 | struct isight *isight = dev_get_drvdata(dev); | ||
694 | |||
695 | isight_pcm_abort(isight); | ||
696 | |||
697 | snd_card_disconnect(isight->card); | ||
698 | |||
699 | mutex_lock(&isight->mutex); | ||
700 | isight_stop_streaming(isight); | ||
701 | mutex_unlock(&isight->mutex); | ||
702 | |||
703 | snd_card_free_when_closed(isight->card); | ||
704 | |||
705 | return 0; | ||
706 | } | ||
707 | |||
708 | static void isight_bus_reset(struct fw_unit *unit) | ||
709 | { | ||
710 | struct isight *isight = dev_get_drvdata(&unit->device); | ||
711 | |||
712 | if (fw_iso_resources_update(&isight->resources) < 0) { | ||
713 | isight_pcm_abort(isight); | ||
714 | |||
715 | mutex_lock(&isight->mutex); | ||
716 | isight_stop_streaming(isight); | ||
717 | mutex_unlock(&isight->mutex); | ||
718 | } | ||
719 | } | ||
720 | |||
721 | static const struct ieee1394_device_id isight_id_table[] = { | ||
722 | { | ||
723 | .match_flags = IEEE1394_MATCH_SPECIFIER_ID | | ||
724 | IEEE1394_MATCH_VERSION, | ||
725 | .specifier_id = OUI_APPLE, | ||
726 | .version = SW_ISIGHT_AUDIO, | ||
727 | }, | ||
728 | { } | ||
729 | }; | ||
730 | MODULE_DEVICE_TABLE(ieee1394, isight_id_table); | ||
731 | |||
732 | static struct fw_driver isight_driver = { | ||
733 | .driver = { | ||
734 | .owner = THIS_MODULE, | ||
735 | .name = KBUILD_MODNAME, | ||
736 | .bus = &fw_bus_type, | ||
737 | .probe = isight_probe, | ||
738 | .remove = isight_remove, | ||
739 | }, | ||
740 | .update = isight_bus_reset, | ||
741 | .id_table = isight_id_table, | ||
742 | }; | ||
743 | |||
744 | static int __init alsa_isight_init(void) | ||
745 | { | ||
746 | return driver_register(&isight_driver.driver); | ||
747 | } | ||
748 | |||
749 | static void __exit alsa_isight_exit(void) | ||
750 | { | ||
751 | driver_unregister(&isight_driver.driver); | ||
752 | } | ||
753 | |||
754 | module_init(alsa_isight_init); | ||
755 | module_exit(alsa_isight_exit); | ||
diff --git a/sound/firewire/iso-resources.c b/sound/firewire/iso-resources.c index 775dbd5f3445..ffe20b877e9f 100644 --- a/sound/firewire/iso-resources.c +++ b/sound/firewire/iso-resources.c | |||
@@ -11,7 +11,6 @@ | |||
11 | #include <linux/jiffies.h> | 11 | #include <linux/jiffies.h> |
12 | #include <linux/mutex.h> | 12 | #include <linux/mutex.h> |
13 | #include <linux/sched.h> | 13 | #include <linux/sched.h> |
14 | #include <linux/slab.h> | ||
15 | #include <linux/spinlock.h> | 14 | #include <linux/spinlock.h> |
16 | #include "iso-resources.h" | 15 | #include "iso-resources.h" |
17 | 16 | ||
@@ -25,10 +24,6 @@ | |||
25 | */ | 24 | */ |
26 | int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit) | 25 | int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit) |
27 | { | 26 | { |
28 | r->buffer = kmalloc(2 * 4, GFP_KERNEL); | ||
29 | if (!r->buffer) | ||
30 | return -ENOMEM; | ||
31 | |||
32 | r->channels_mask = ~0uLL; | 27 | r->channels_mask = ~0uLL; |
33 | r->unit = fw_unit_get(unit); | 28 | r->unit = fw_unit_get(unit); |
34 | mutex_init(&r->mutex); | 29 | mutex_init(&r->mutex); |
@@ -36,6 +31,7 @@ int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit) | |||
36 | 31 | ||
37 | return 0; | 32 | return 0; |
38 | } | 33 | } |
34 | EXPORT_SYMBOL(fw_iso_resources_init); | ||
39 | 35 | ||
40 | /** | 36 | /** |
41 | * fw_iso_resources_destroy - destroy a resource manager | 37 | * fw_iso_resources_destroy - destroy a resource manager |
@@ -44,10 +40,10 @@ int fw_iso_resources_init(struct fw_iso_resources *r, struct fw_unit *unit) | |||
44 | void fw_iso_resources_destroy(struct fw_iso_resources *r) | 40 | void fw_iso_resources_destroy(struct fw_iso_resources *r) |
45 | { | 41 | { |
46 | WARN_ON(r->allocated); | 42 | WARN_ON(r->allocated); |
47 | kfree(r->buffer); | ||
48 | mutex_destroy(&r->mutex); | 43 | mutex_destroy(&r->mutex); |
49 | fw_unit_put(r->unit); | 44 | fw_unit_put(r->unit); |
50 | } | 45 | } |
46 | EXPORT_SYMBOL(fw_iso_resources_destroy); | ||
51 | 47 | ||
52 | static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed) | 48 | static unsigned int packet_bandwidth(unsigned int max_payload_bytes, int speed) |
53 | { | 49 | { |
@@ -131,7 +127,7 @@ retry_after_bus_reset: | |||
131 | 127 | ||
132 | bandwidth = r->bandwidth + r->bandwidth_overhead; | 128 | bandwidth = r->bandwidth + r->bandwidth_overhead; |
133 | fw_iso_resource_manage(card, r->generation, r->channels_mask, | 129 | fw_iso_resource_manage(card, r->generation, r->channels_mask, |
134 | &channel, &bandwidth, true, r->buffer); | 130 | &channel, &bandwidth, true); |
135 | if (channel == -EAGAIN) { | 131 | if (channel == -EAGAIN) { |
136 | mutex_unlock(&r->mutex); | 132 | mutex_unlock(&r->mutex); |
137 | goto retry_after_bus_reset; | 133 | goto retry_after_bus_reset; |
@@ -152,6 +148,7 @@ retry_after_bus_reset: | |||
152 | 148 | ||
153 | return channel; | 149 | return channel; |
154 | } | 150 | } |
151 | EXPORT_SYMBOL(fw_iso_resources_allocate); | ||
155 | 152 | ||
156 | /** | 153 | /** |
157 | * fw_iso_resources_update - update resource allocations after a bus reset | 154 | * fw_iso_resources_update - update resource allocations after a bus reset |
@@ -184,7 +181,7 @@ int fw_iso_resources_update(struct fw_iso_resources *r) | |||
184 | bandwidth = r->bandwidth + r->bandwidth_overhead; | 181 | bandwidth = r->bandwidth + r->bandwidth_overhead; |
185 | 182 | ||
186 | fw_iso_resource_manage(card, r->generation, 1uLL << r->channel, | 183 | fw_iso_resource_manage(card, r->generation, 1uLL << r->channel, |
187 | &channel, &bandwidth, true, r->buffer); | 184 | &channel, &bandwidth, true); |
188 | /* | 185 | /* |
189 | * When another bus reset happens, pretend that the allocation | 186 | * When another bus reset happens, pretend that the allocation |
190 | * succeeded; we will try again for the new generation later. | 187 | * succeeded; we will try again for the new generation later. |
@@ -203,6 +200,7 @@ int fw_iso_resources_update(struct fw_iso_resources *r) | |||
203 | 200 | ||
204 | return channel; | 201 | return channel; |
205 | } | 202 | } |
203 | EXPORT_SYMBOL(fw_iso_resources_update); | ||
206 | 204 | ||
207 | /** | 205 | /** |
208 | * fw_iso_resources_free - frees allocated resources | 206 | * fw_iso_resources_free - frees allocated resources |
@@ -220,7 +218,7 @@ void fw_iso_resources_free(struct fw_iso_resources *r) | |||
220 | if (r->allocated) { | 218 | if (r->allocated) { |
221 | bandwidth = r->bandwidth + r->bandwidth_overhead; | 219 | bandwidth = r->bandwidth + r->bandwidth_overhead; |
222 | fw_iso_resource_manage(card, r->generation, 1uLL << r->channel, | 220 | fw_iso_resource_manage(card, r->generation, 1uLL << r->channel, |
223 | &channel, &bandwidth, false, r->buffer); | 221 | &channel, &bandwidth, false); |
224 | if (channel < 0) | 222 | if (channel < 0) |
225 | dev_err(&r->unit->device, | 223 | dev_err(&r->unit->device, |
226 | "isochronous resource deallocation failed\n"); | 224 | "isochronous resource deallocation failed\n"); |
@@ -230,3 +228,4 @@ void fw_iso_resources_free(struct fw_iso_resources *r) | |||
230 | 228 | ||
231 | mutex_unlock(&r->mutex); | 229 | mutex_unlock(&r->mutex); |
232 | } | 230 | } |
231 | EXPORT_SYMBOL(fw_iso_resources_free); | ||
diff --git a/sound/firewire/iso-resources.h b/sound/firewire/iso-resources.h index 3f0730e4d841..5a9af7c61657 100644 --- a/sound/firewire/iso-resources.h +++ b/sound/firewire/iso-resources.h | |||
@@ -24,7 +24,6 @@ struct fw_iso_resources { | |||
24 | unsigned int bandwidth_overhead; | 24 | unsigned int bandwidth_overhead; |
25 | int generation; /* in which allocation is valid */ | 25 | int generation; /* in which allocation is valid */ |
26 | bool allocated; | 26 | bool allocated; |
27 | __be32 *buffer; | ||
28 | }; | 27 | }; |
29 | 28 | ||
30 | int fw_iso_resources_init(struct fw_iso_resources *r, | 29 | int fw_iso_resources_init(struct fw_iso_resources *r, |
diff --git a/sound/firewire/packets-buffer.c b/sound/firewire/packets-buffer.c index 1e20e60ba6a6..3c61ca2e6152 100644 --- a/sound/firewire/packets-buffer.c +++ b/sound/firewire/packets-buffer.c | |||
@@ -60,6 +60,7 @@ err_packets: | |||
60 | error: | 60 | error: |
61 | return err; | 61 | return err; |
62 | } | 62 | } |
63 | EXPORT_SYMBOL(iso_packets_buffer_init); | ||
63 | 64 | ||
64 | /** | 65 | /** |
65 | * iso_packets_buffer_destroy - frees packet buffer resources | 66 | * iso_packets_buffer_destroy - frees packet buffer resources |
@@ -72,3 +73,4 @@ void iso_packets_buffer_destroy(struct iso_packets_buffer *b, | |||
72 | fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card); | 73 | fw_iso_buffer_destroy(&b->iso_buffer, fw_parent_device(unit)->card); |
73 | kfree(b->packets); | 74 | kfree(b->packets); |
74 | } | 75 | } |
76 | EXPORT_SYMBOL(iso_packets_buffer_destroy); | ||
diff --git a/sound/i2c/other/Makefile b/sound/i2c/other/Makefile index 2dad40f3f622..c95d8f1aae87 100644 --- a/sound/i2c/other/Makefile +++ b/sound/i2c/other/Makefile | |||
@@ -14,4 +14,4 @@ snd-tea575x-tuner-objs := tea575x-tuner.o | |||
14 | obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o | 14 | obj-$(CONFIG_SND_PDAUDIOCF) += snd-ak4117.o |
15 | obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o | 15 | obj-$(CONFIG_SND_ICE1712) += snd-ak4xxx-adda.o |
16 | obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o | 16 | obj-$(CONFIG_SND_ICE1724) += snd-ak4114.o snd-ak4113.o snd-ak4xxx-adda.o snd-pt2258.o |
17 | obj-$(CONFIG_SND_FM801_TEA575X) += snd-tea575x-tuner.o | 17 | obj-$(CONFIG_SND_TEA575X) += snd-tea575x-tuner.o |
diff --git a/sound/i2c/other/tea575x-tuner.c b/sound/i2c/other/tea575x-tuner.c index ee538f1ae846..4831800239d3 100644 --- a/sound/i2c/other/tea575x-tuner.c +++ b/sound/i2c/other/tea575x-tuner.c | |||
@@ -37,8 +37,8 @@ static int radio_nr = -1; | |||
37 | module_param(radio_nr, int, 0); | 37 | module_param(radio_nr, int, 0); |
38 | 38 | ||
39 | #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) | 39 | #define RADIO_VERSION KERNEL_VERSION(0, 0, 2) |
40 | #define FREQ_LO (87 * 16000) | 40 | #define FREQ_LO (50UL * 16000) |
41 | #define FREQ_HI (108 * 16000) | 41 | #define FREQ_HI (150UL * 16000) |
42 | 42 | ||
43 | /* | 43 | /* |
44 | * definitions | 44 | * definitions |
@@ -77,27 +77,95 @@ static struct v4l2_queryctrl radio_qctrl[] = { | |||
77 | * lowlevel part | 77 | * lowlevel part |
78 | */ | 78 | */ |
79 | 79 | ||
80 | static void snd_tea575x_write(struct snd_tea575x *tea, unsigned int val) | ||
81 | { | ||
82 | u16 l; | ||
83 | u8 data; | ||
84 | |||
85 | tea->ops->set_direction(tea, 1); | ||
86 | udelay(16); | ||
87 | |||
88 | for (l = 25; l > 0; l--) { | ||
89 | data = (val >> 24) & TEA575X_DATA; | ||
90 | val <<= 1; /* shift data */ | ||
91 | tea->ops->set_pins(tea, data | TEA575X_WREN); | ||
92 | udelay(2); | ||
93 | tea->ops->set_pins(tea, data | TEA575X_WREN | TEA575X_CLK); | ||
94 | udelay(2); | ||
95 | tea->ops->set_pins(tea, data | TEA575X_WREN); | ||
96 | udelay(2); | ||
97 | } | ||
98 | |||
99 | if (!tea->mute) | ||
100 | tea->ops->set_pins(tea, 0); | ||
101 | } | ||
102 | |||
103 | static unsigned int snd_tea575x_read(struct snd_tea575x *tea) | ||
104 | { | ||
105 | u16 l, rdata; | ||
106 | u32 data = 0; | ||
107 | |||
108 | tea->ops->set_direction(tea, 0); | ||
109 | tea->ops->set_pins(tea, 0); | ||
110 | udelay(16); | ||
111 | |||
112 | for (l = 24; l--;) { | ||
113 | tea->ops->set_pins(tea, TEA575X_CLK); | ||
114 | udelay(2); | ||
115 | if (!l) | ||
116 | tea->tuned = tea->ops->get_pins(tea) & TEA575X_MOST ? 0 : 1; | ||
117 | tea->ops->set_pins(tea, 0); | ||
118 | udelay(2); | ||
119 | data <<= 1; /* shift data */ | ||
120 | rdata = tea->ops->get_pins(tea); | ||
121 | if (!l) | ||
122 | tea->stereo = (rdata & TEA575X_MOST) ? 0 : 1; | ||
123 | if (rdata & TEA575X_DATA) | ||
124 | data++; | ||
125 | udelay(2); | ||
126 | } | ||
127 | |||
128 | if (tea->mute) | ||
129 | tea->ops->set_pins(tea, TEA575X_WREN); | ||
130 | |||
131 | return data; | ||
132 | } | ||
133 | |||
134 | static void snd_tea575x_get_freq(struct snd_tea575x *tea) | ||
135 | { | ||
136 | unsigned long freq; | ||
137 | |||
138 | freq = snd_tea575x_read(tea) & TEA575X_BIT_FREQ_MASK; | ||
139 | /* freq *= 12.5 */ | ||
140 | freq *= 125; | ||
141 | freq /= 10; | ||
142 | /* crystal fixup */ | ||
143 | if (tea->tea5759) | ||
144 | freq += TEA575X_FMIF; | ||
145 | else | ||
146 | freq -= TEA575X_FMIF; | ||
147 | |||
148 | tea->freq = freq * 16; /* from kHz */ | ||
149 | } | ||
150 | |||
80 | static void snd_tea575x_set_freq(struct snd_tea575x *tea) | 151 | static void snd_tea575x_set_freq(struct snd_tea575x *tea) |
81 | { | 152 | { |
82 | unsigned long freq; | 153 | unsigned long freq; |
83 | 154 | ||
84 | freq = tea->freq / 16; /* to kHz */ | 155 | freq = clamp(tea->freq, FREQ_LO, FREQ_HI); |
85 | if (freq > 108000) | 156 | freq /= 16; /* to kHz */ |
86 | freq = 108000; | ||
87 | if (freq < 87000) | ||
88 | freq = 87000; | ||
89 | /* crystal fixup */ | 157 | /* crystal fixup */ |
90 | if (tea->tea5759) | 158 | if (tea->tea5759) |
91 | freq -= tea->freq_fixup; | 159 | freq -= TEA575X_FMIF; |
92 | else | 160 | else |
93 | freq += tea->freq_fixup; | 161 | freq += TEA575X_FMIF; |
94 | /* freq /= 12.5 */ | 162 | /* freq /= 12.5 */ |
95 | freq *= 10; | 163 | freq *= 10; |
96 | freq /= 125; | 164 | freq /= 125; |
97 | 165 | ||
98 | tea->val &= ~TEA575X_BIT_FREQ_MASK; | 166 | tea->val &= ~TEA575X_BIT_FREQ_MASK; |
99 | tea->val |= freq & TEA575X_BIT_FREQ_MASK; | 167 | tea->val |= freq & TEA575X_BIT_FREQ_MASK; |
100 | tea->ops->write(tea, tea->val); | 168 | snd_tea575x_write(tea, tea->val); |
101 | } | 169 | } |
102 | 170 | ||
103 | /* | 171 | /* |
@@ -109,29 +177,34 @@ static int vidioc_querycap(struct file *file, void *priv, | |||
109 | { | 177 | { |
110 | struct snd_tea575x *tea = video_drvdata(file); | 178 | struct snd_tea575x *tea = video_drvdata(file); |
111 | 179 | ||
112 | strcpy(v->card, tea->tea5759 ? "TEA5759" : "TEA5757"); | ||
113 | strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); | 180 | strlcpy(v->driver, "tea575x-tuner", sizeof(v->driver)); |
114 | strlcpy(v->card, "Maestro Radio", sizeof(v->card)); | 181 | strlcpy(v->card, tea->card, sizeof(v->card)); |
115 | sprintf(v->bus_info, "PCI"); | 182 | strlcat(v->card, tea->tea5759 ? " TEA5759" : " TEA5757", sizeof(v->card)); |
183 | strlcpy(v->bus_info, tea->bus_info, sizeof(v->bus_info)); | ||
116 | v->version = RADIO_VERSION; | 184 | v->version = RADIO_VERSION; |
117 | v->capabilities = V4L2_CAP_TUNER; | 185 | v->capabilities = V4L2_CAP_TUNER | V4L2_CAP_RADIO; |
118 | return 0; | 186 | return 0; |
119 | } | 187 | } |
120 | 188 | ||
121 | static int vidioc_g_tuner(struct file *file, void *priv, | 189 | static int vidioc_g_tuner(struct file *file, void *priv, |
122 | struct v4l2_tuner *v) | 190 | struct v4l2_tuner *v) |
123 | { | 191 | { |
192 | struct snd_tea575x *tea = video_drvdata(file); | ||
193 | |||
124 | if (v->index > 0) | 194 | if (v->index > 0) |
125 | return -EINVAL; | 195 | return -EINVAL; |
126 | 196 | ||
197 | snd_tea575x_read(tea); | ||
198 | |||
127 | strcpy(v->name, "FM"); | 199 | strcpy(v->name, "FM"); |
128 | v->type = V4L2_TUNER_RADIO; | 200 | v->type = V4L2_TUNER_RADIO; |
201 | v->capability = V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_STEREO; | ||
129 | v->rangelow = FREQ_LO; | 202 | v->rangelow = FREQ_LO; |
130 | v->rangehigh = FREQ_HI; | 203 | v->rangehigh = FREQ_HI; |
131 | v->rxsubchans = V4L2_TUNER_SUB_MONO|V4L2_TUNER_SUB_STEREO; | 204 | v->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO; |
132 | v->capability = V4L2_TUNER_CAP_LOW; | 205 | v->audmode = tea->stereo ? V4L2_TUNER_MODE_STEREO : V4L2_TUNER_MODE_MONO; |
133 | v->audmode = V4L2_TUNER_MODE_MONO; | 206 | v->signal = tea->tuned ? 0xffff : 0; |
134 | v->signal = 0xffff; | 207 | |
135 | return 0; | 208 | return 0; |
136 | } | 209 | } |
137 | 210 | ||
@@ -148,7 +221,10 @@ static int vidioc_g_frequency(struct file *file, void *priv, | |||
148 | { | 221 | { |
149 | struct snd_tea575x *tea = video_drvdata(file); | 222 | struct snd_tea575x *tea = video_drvdata(file); |
150 | 223 | ||
224 | if (f->tuner != 0) | ||
225 | return -EINVAL; | ||
151 | f->type = V4L2_TUNER_RADIO; | 226 | f->type = V4L2_TUNER_RADIO; |
227 | snd_tea575x_get_freq(tea); | ||
152 | f->frequency = tea->freq; | 228 | f->frequency = tea->freq; |
153 | return 0; | 229 | return 0; |
154 | } | 230 | } |
@@ -158,6 +234,9 @@ static int vidioc_s_frequency(struct file *file, void *priv, | |||
158 | { | 234 | { |
159 | struct snd_tea575x *tea = video_drvdata(file); | 235 | struct snd_tea575x *tea = video_drvdata(file); |
160 | 236 | ||
237 | if (f->tuner != 0 || f->type != V4L2_TUNER_RADIO) | ||
238 | return -EINVAL; | ||
239 | |||
161 | if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) | 240 | if (f->frequency < FREQ_LO || f->frequency > FREQ_HI) |
162 | return -EINVAL; | 241 | return -EINVAL; |
163 | 242 | ||
@@ -209,10 +288,8 @@ static int vidioc_g_ctrl(struct file *file, void *priv, | |||
209 | 288 | ||
210 | switch (ctrl->id) { | 289 | switch (ctrl->id) { |
211 | case V4L2_CID_AUDIO_MUTE: | 290 | case V4L2_CID_AUDIO_MUTE: |
212 | if (tea->ops->mute) { | 291 | ctrl->value = tea->mute; |
213 | ctrl->value = tea->mute; | 292 | return 0; |
214 | return 0; | ||
215 | } | ||
216 | } | 293 | } |
217 | return -EINVAL; | 294 | return -EINVAL; |
218 | } | 295 | } |
@@ -224,11 +301,11 @@ static int vidioc_s_ctrl(struct file *file, void *priv, | |||
224 | 301 | ||
225 | switch (ctrl->id) { | 302 | switch (ctrl->id) { |
226 | case V4L2_CID_AUDIO_MUTE: | 303 | case V4L2_CID_AUDIO_MUTE: |
227 | if (tea->ops->mute) { | 304 | if (tea->mute != ctrl->value) { |
228 | tea->ops->mute(tea, ctrl->value); | ||
229 | tea->mute = ctrl->value; | 305 | tea->mute = ctrl->value; |
230 | return 0; | 306 | snd_tea575x_set_freq(tea); |
231 | } | 307 | } |
308 | return 0; | ||
232 | } | 309 | } |
233 | return -EINVAL; | 310 | return -EINVAL; |
234 | } | 311 | } |
@@ -293,18 +370,16 @@ static struct video_device tea575x_radio = { | |||
293 | /* | 370 | /* |
294 | * initialize all the tea575x chips | 371 | * initialize all the tea575x chips |
295 | */ | 372 | */ |
296 | void snd_tea575x_init(struct snd_tea575x *tea) | 373 | int snd_tea575x_init(struct snd_tea575x *tea) |
297 | { | 374 | { |
298 | int retval; | 375 | int retval; |
299 | unsigned int val; | ||
300 | struct video_device *tea575x_radio_inst; | 376 | struct video_device *tea575x_radio_inst; |
301 | 377 | ||
302 | val = tea->ops->read(tea); | 378 | tea->mute = 1; |
303 | if (val == 0x1ffffff || val == 0) { | 379 | |
304 | snd_printk(KERN_ERR | 380 | snd_tea575x_write(tea, 0x55AA); |
305 | "tea575x-tuner: Cannot find TEA575x chip\n"); | 381 | if (snd_tea575x_read(tea) != 0x55AA) |
306 | return; | 382 | return -ENODEV; |
307 | } | ||
308 | 383 | ||
309 | tea->in_use = 0; | 384 | tea->in_use = 0; |
310 | tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; | 385 | tea->val = TEA575X_BIT_BAND_FM | TEA575X_BIT_SEARCH_10_40; |
@@ -313,7 +388,7 @@ void snd_tea575x_init(struct snd_tea575x *tea) | |||
313 | tea575x_radio_inst = video_device_alloc(); | 388 | tea575x_radio_inst = video_device_alloc(); |
314 | if (tea575x_radio_inst == NULL) { | 389 | if (tea575x_radio_inst == NULL) { |
315 | printk(KERN_ERR "tea575x-tuner: not enough memory\n"); | 390 | printk(KERN_ERR "tea575x-tuner: not enough memory\n"); |
316 | return; | 391 | return -ENOMEM; |
317 | } | 392 | } |
318 | 393 | ||
319 | memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio)); | 394 | memcpy(tea575x_radio_inst, &tea575x_radio, sizeof(tea575x_radio)); |
@@ -328,17 +403,13 @@ void snd_tea575x_init(struct snd_tea575x *tea) | |||
328 | if (retval) { | 403 | if (retval) { |
329 | printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); | 404 | printk(KERN_ERR "tea575x-tuner: can't register video device!\n"); |
330 | kfree(tea575x_radio_inst); | 405 | kfree(tea575x_radio_inst); |
331 | return; | 406 | return retval; |
332 | } | 407 | } |
333 | 408 | ||
334 | snd_tea575x_set_freq(tea); | 409 | snd_tea575x_set_freq(tea); |
335 | |||
336 | /* mute on init */ | ||
337 | if (tea->ops->mute) { | ||
338 | tea->ops->mute(tea, 1); | ||
339 | tea->mute = 1; | ||
340 | } | ||
341 | tea->vd = tea575x_radio_inst; | 410 | tea->vd = tea575x_radio_inst; |
411 | |||
412 | return 0; | ||
342 | } | 413 | } |
343 | 414 | ||
344 | void snd_tea575x_exit(struct snd_tea575x *tea) | 415 | void snd_tea575x_exit(struct snd_tea575x *tea) |
diff --git a/sound/oss/Kconfig b/sound/oss/Kconfig index 76c090218073..6c93e051f9ae 100644 --- a/sound/oss/Kconfig +++ b/sound/oss/Kconfig | |||
@@ -22,10 +22,6 @@ config SOUND_VWSND | |||
22 | <file:Documentation/sound/oss/vwsnd> for more info on this driver's | 22 | <file:Documentation/sound/oss/vwsnd> for more info on this driver's |
23 | capabilities. | 23 | capabilities. |
24 | 24 | ||
25 | config SOUND_AU1550_AC97 | ||
26 | tristate "Au1550/Au1200 AC97 Sound" | ||
27 | depends on SOC_AU1550 || SOC_AU1200 | ||
28 | |||
29 | config SOUND_MSNDCLAS | 25 | config SOUND_MSNDCLAS |
30 | tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" | 26 | tristate "Support for Turtle Beach MultiSound Classic, Tahiti, Monterey" |
31 | depends on (m || !STANDALONE) && ISA | 27 | depends on (m || !STANDALONE) && ISA |
diff --git a/sound/oss/Makefile b/sound/oss/Makefile index 90ffb99c6b17..77f21b68bf0f 100644 --- a/sound/oss/Makefile +++ b/sound/oss/Makefile | |||
@@ -25,7 +25,6 @@ obj-$(CONFIG_SOUND_WAVEARTIST) += waveartist.o | |||
25 | obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o | 25 | obj-$(CONFIG_SOUND_MSNDCLAS) += msnd.o msnd_classic.o |
26 | obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o | 26 | obj-$(CONFIG_SOUND_MSNDPIN) += msnd.o msnd_pinnacle.o |
27 | obj-$(CONFIG_SOUND_VWSND) += vwsnd.o | 27 | obj-$(CONFIG_SOUND_VWSND) += vwsnd.o |
28 | obj-$(CONFIG_SOUND_AU1550_AC97) += au1550_ac97.o ac97_codec.o | ||
29 | obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o | 28 | obj-$(CONFIG_SOUND_BCM_CS4297A) += swarm_cs4297a.o |
30 | 29 | ||
31 | obj-$(CONFIG_DMASOUND) += dmasound/ | 30 | obj-$(CONFIG_DMASOUND) += dmasound/ |
diff --git a/sound/oss/ac97_codec.c b/sound/oss/ac97_codec.c deleted file mode 100644 index 0cd23d94888f..000000000000 --- a/sound/oss/ac97_codec.c +++ /dev/null | |||
@@ -1,1203 +0,0 @@ | |||
1 | /* | ||
2 | * ac97_codec.c: Generic AC97 mixer/modem module | ||
3 | * | ||
4 | * Derived from ac97 mixer in maestro and trident driver. | ||
5 | * | ||
6 | * Copyright 2000 Silicon Integrated System Corporation | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
21 | * | ||
22 | ************************************************************************** | ||
23 | * | ||
24 | * The Intel Audio Codec '97 specification is available at: | ||
25 | * http://download.intel.com/support/motherboards/desktop/sb/ac97_r23.pdf | ||
26 | * | ||
27 | ************************************************************************** | ||
28 | * | ||
29 | * History | ||
30 | * May 02, 2003 Liam Girdwood <lrg@slimlogic.co.uk> | ||
31 | * Removed non existent WM9700 | ||
32 | * Added support for WM9705, WM9708, WM9709, WM9710, WM9711 | ||
33 | * WM9712 and WM9717 | ||
34 | * Mar 28, 2002 Randolph Bentson <bentson@holmsjoen.com> | ||
35 | * corrections to support WM9707 in ViewPad 1000 | ||
36 | * v0.4 Mar 15 2000 Ollie Lho | ||
37 | * dual codecs support verified with 4 channels output | ||
38 | * v0.3 Feb 22 2000 Ollie Lho | ||
39 | * bug fix for record mask setting | ||
40 | * v0.2 Feb 10 2000 Ollie Lho | ||
41 | * add ac97_read_proc for /proc/driver/{vendor}/ac97 | ||
42 | * v0.1 Jan 14 2000 Ollie Lho <ollie@sis.com.tw> | ||
43 | * Isolated from trident.c to support multiple ac97 codec | ||
44 | */ | ||
45 | #include <linux/module.h> | ||
46 | #include <linux/kernel.h> | ||
47 | #include <linux/slab.h> | ||
48 | #include <linux/string.h> | ||
49 | #include <linux/errno.h> | ||
50 | #include <linux/bitops.h> | ||
51 | #include <linux/delay.h> | ||
52 | #include <linux/pci.h> | ||
53 | #include <linux/ac97_codec.h> | ||
54 | #include <asm/uaccess.h> | ||
55 | #include <linux/mutex.h> | ||
56 | |||
57 | #define CODEC_ID_BUFSZ 14 | ||
58 | |||
59 | static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel); | ||
60 | static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel, | ||
61 | unsigned int left, unsigned int right); | ||
62 | static void ac97_set_mixer(struct ac97_codec *codec, unsigned int oss_mixer, unsigned int val ); | ||
63 | static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask); | ||
64 | static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg); | ||
65 | |||
66 | static int ac97_init_mixer(struct ac97_codec *codec); | ||
67 | |||
68 | static int wolfson_init03(struct ac97_codec * codec); | ||
69 | static int wolfson_init04(struct ac97_codec * codec); | ||
70 | static int wolfson_init05(struct ac97_codec * codec); | ||
71 | static int wolfson_init11(struct ac97_codec * codec); | ||
72 | static int wolfson_init13(struct ac97_codec * codec); | ||
73 | static int tritech_init(struct ac97_codec * codec); | ||
74 | static int tritech_maestro_init(struct ac97_codec * codec); | ||
75 | static int sigmatel_9708_init(struct ac97_codec *codec); | ||
76 | static int sigmatel_9721_init(struct ac97_codec *codec); | ||
77 | static int sigmatel_9744_init(struct ac97_codec *codec); | ||
78 | static int ad1886_init(struct ac97_codec *codec); | ||
79 | static int eapd_control(struct ac97_codec *codec, int); | ||
80 | static int crystal_digital_control(struct ac97_codec *codec, int slots, int rate, int mode); | ||
81 | static int cmedia_init(struct ac97_codec * codec); | ||
82 | static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode); | ||
83 | static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode); | ||
84 | |||
85 | |||
86 | /* | ||
87 | * AC97 operations. | ||
88 | * | ||
89 | * If you are adding a codec then you should be able to use | ||
90 | * eapd_ops - any codec that supports EAPD amp control (most) | ||
91 | * null_ops - any ancient codec that supports nothing | ||
92 | * | ||
93 | * The three functions are | ||
94 | * init - used for non AC97 standard initialisation | ||
95 | * amplifier - used to do amplifier control (1=on 0=off) | ||
96 | * digital - switch to digital modes (0 = analog) | ||
97 | * | ||
98 | * Not all codecs support all features, not all drivers use all the | ||
99 | * operations yet | ||
100 | */ | ||
101 | |||
102 | static struct ac97_ops null_ops = { NULL, NULL, NULL }; | ||
103 | static struct ac97_ops default_ops = { NULL, eapd_control, NULL }; | ||
104 | static struct ac97_ops default_digital_ops = { NULL, eapd_control, generic_digital_control}; | ||
105 | static struct ac97_ops wolfson_ops03 = { wolfson_init03, NULL, NULL }; | ||
106 | static struct ac97_ops wolfson_ops04 = { wolfson_init04, NULL, NULL }; | ||
107 | static struct ac97_ops wolfson_ops05 = { wolfson_init05, NULL, NULL }; | ||
108 | static struct ac97_ops wolfson_ops11 = { wolfson_init11, NULL, NULL }; | ||
109 | static struct ac97_ops wolfson_ops13 = { wolfson_init13, NULL, NULL }; | ||
110 | static struct ac97_ops tritech_ops = { tritech_init, NULL, NULL }; | ||
111 | static struct ac97_ops tritech_m_ops = { tritech_maestro_init, NULL, NULL }; | ||
112 | static struct ac97_ops sigmatel_9708_ops = { sigmatel_9708_init, NULL, NULL }; | ||
113 | static struct ac97_ops sigmatel_9721_ops = { sigmatel_9721_init, NULL, NULL }; | ||
114 | static struct ac97_ops sigmatel_9744_ops = { sigmatel_9744_init, NULL, NULL }; | ||
115 | static struct ac97_ops crystal_digital_ops = { NULL, eapd_control, crystal_digital_control }; | ||
116 | static struct ac97_ops ad1886_ops = { ad1886_init, eapd_control, NULL }; | ||
117 | static struct ac97_ops cmedia_ops = { NULL, eapd_control, NULL}; | ||
118 | static struct ac97_ops cmedia_digital_ops = { cmedia_init, eapd_control, cmedia_digital_control}; | ||
119 | |||
120 | /* sorted by vendor/device id */ | ||
121 | static const struct { | ||
122 | u32 id; | ||
123 | char *name; | ||
124 | struct ac97_ops *ops; | ||
125 | int flags; | ||
126 | } ac97_codec_ids[] = { | ||
127 | {0x41445303, "Analog Devices AD1819", &null_ops}, | ||
128 | {0x41445340, "Analog Devices AD1881", &null_ops}, | ||
129 | {0x41445348, "Analog Devices AD1881A", &null_ops}, | ||
130 | {0x41445360, "Analog Devices AD1885", &default_ops}, | ||
131 | {0x41445361, "Analog Devices AD1886", &ad1886_ops}, | ||
132 | {0x41445370, "Analog Devices AD1981", &null_ops}, | ||
133 | {0x41445372, "Analog Devices AD1981A", &null_ops}, | ||
134 | {0x41445374, "Analog Devices AD1981B", &null_ops}, | ||
135 | {0x41445460, "Analog Devices AD1885", &default_ops}, | ||
136 | {0x41445461, "Analog Devices AD1886", &ad1886_ops}, | ||
137 | {0x414B4D00, "Asahi Kasei AK4540", &null_ops}, | ||
138 | {0x414B4D01, "Asahi Kasei AK4542", &null_ops}, | ||
139 | {0x414B4D02, "Asahi Kasei AK4543", &null_ops}, | ||
140 | {0x414C4326, "ALC100P", &null_ops}, | ||
141 | {0x414C4710, "ALC200/200P", &null_ops}, | ||
142 | {0x414C4720, "ALC650", &default_digital_ops}, | ||
143 | {0x434D4941, "CMedia", &cmedia_ops, AC97_NO_PCM_VOLUME }, | ||
144 | {0x434D4942, "CMedia", &cmedia_ops, AC97_NO_PCM_VOLUME }, | ||
145 | {0x434D4961, "CMedia", &cmedia_digital_ops, AC97_NO_PCM_VOLUME }, | ||
146 | {0x43525900, "Cirrus Logic CS4297", &default_ops}, | ||
147 | {0x43525903, "Cirrus Logic CS4297", &default_ops}, | ||
148 | {0x43525913, "Cirrus Logic CS4297A rev A", &default_ops}, | ||
149 | {0x43525914, "Cirrus Logic CS4297A rev B", &default_ops}, | ||
150 | {0x43525923, "Cirrus Logic CS4298", &null_ops}, | ||
151 | {0x4352592B, "Cirrus Logic CS4294", &null_ops}, | ||
152 | {0x4352592D, "Cirrus Logic CS4294", &null_ops}, | ||
153 | {0x43525931, "Cirrus Logic CS4299 rev A", &crystal_digital_ops}, | ||
154 | {0x43525933, "Cirrus Logic CS4299 rev C", &crystal_digital_ops}, | ||
155 | {0x43525934, "Cirrus Logic CS4299 rev D", &crystal_digital_ops}, | ||
156 | {0x43585430, "CXT48", &default_ops, AC97_DELUDED_MODEM }, | ||
157 | {0x43585442, "CXT66", &default_ops, AC97_DELUDED_MODEM }, | ||
158 | {0x44543031, "Diamond Technology DT0893", &default_ops}, | ||
159 | {0x45838308, "ESS Allegro ES1988", &null_ops}, | ||
160 | {0x49434511, "ICE1232", &null_ops}, /* I hope --jk */ | ||
161 | {0x4e534331, "National Semiconductor LM4549", &null_ops}, | ||
162 | {0x53494c22, "Silicon Laboratory Si3036", &null_ops}, | ||
163 | {0x53494c23, "Silicon Laboratory Si3038", &null_ops}, | ||
164 | {0x545200FF, "TriTech TR?????", &tritech_m_ops}, | ||
165 | {0x54524102, "TriTech TR28022", &null_ops}, | ||
166 | {0x54524103, "TriTech TR28023", &null_ops}, | ||
167 | {0x54524106, "TriTech TR28026", &null_ops}, | ||
168 | {0x54524108, "TriTech TR28028", &tritech_ops}, | ||
169 | {0x54524123, "TriTech TR A5", &null_ops}, | ||
170 | {0x574D4C03, "Wolfson WM9703/07/08/17", &wolfson_ops03}, | ||
171 | {0x574D4C04, "Wolfson WM9704M/WM9704Q", &wolfson_ops04}, | ||
172 | {0x574D4C05, "Wolfson WM9705/WM9710", &wolfson_ops05}, | ||
173 | {0x574D4C09, "Wolfson WM9709", &null_ops}, | ||
174 | {0x574D4C12, "Wolfson WM9711/9712", &wolfson_ops11}, | ||
175 | {0x574D4C13, "Wolfson WM9713", &wolfson_ops13, AC97_DEFAULT_POWER_OFF}, | ||
176 | {0x83847600, "SigmaTel STAC????", &null_ops}, | ||
177 | {0x83847604, "SigmaTel STAC9701/3/4/5", &null_ops}, | ||
178 | {0x83847605, "SigmaTel STAC9704", &null_ops}, | ||
179 | {0x83847608, "SigmaTel STAC9708", &sigmatel_9708_ops}, | ||
180 | {0x83847609, "SigmaTel STAC9721/23", &sigmatel_9721_ops}, | ||
181 | {0x83847644, "SigmaTel STAC9744/45", &sigmatel_9744_ops}, | ||
182 | {0x83847652, "SigmaTel STAC9752/53", &default_ops}, | ||
183 | {0x83847656, "SigmaTel STAC9756/57", &sigmatel_9744_ops}, | ||
184 | {0x83847666, "SigmaTel STAC9750T", &sigmatel_9744_ops}, | ||
185 | {0x83847684, "SigmaTel STAC9783/84?", &null_ops}, | ||
186 | {0x57454301, "Winbond 83971D", &null_ops}, | ||
187 | }; | ||
188 | |||
189 | /* this table has default mixer values for all OSS mixers. */ | ||
190 | static struct mixer_defaults { | ||
191 | int mixer; | ||
192 | unsigned int value; | ||
193 | } mixer_defaults[SOUND_MIXER_NRDEVICES] = { | ||
194 | /* all values 0 -> 100 in bytes */ | ||
195 | {SOUND_MIXER_VOLUME, 0x4343}, | ||
196 | {SOUND_MIXER_BASS, 0x4343}, | ||
197 | {SOUND_MIXER_TREBLE, 0x4343}, | ||
198 | {SOUND_MIXER_PCM, 0x4343}, | ||
199 | {SOUND_MIXER_SPEAKER, 0x4343}, | ||
200 | {SOUND_MIXER_LINE, 0x4343}, | ||
201 | {SOUND_MIXER_MIC, 0x0000}, | ||
202 | {SOUND_MIXER_CD, 0x4343}, | ||
203 | {SOUND_MIXER_ALTPCM, 0x4343}, | ||
204 | {SOUND_MIXER_IGAIN, 0x4343}, | ||
205 | {SOUND_MIXER_LINE1, 0x4343}, | ||
206 | {SOUND_MIXER_PHONEIN, 0x4343}, | ||
207 | {SOUND_MIXER_PHONEOUT, 0x4343}, | ||
208 | {SOUND_MIXER_VIDEO, 0x4343}, | ||
209 | {-1,0} | ||
210 | }; | ||
211 | |||
212 | /* table to scale scale from OSS mixer value to AC97 mixer register value */ | ||
213 | static struct ac97_mixer_hw { | ||
214 | unsigned char offset; | ||
215 | int scale; | ||
216 | } ac97_hw[SOUND_MIXER_NRDEVICES]= { | ||
217 | [SOUND_MIXER_VOLUME] = {AC97_MASTER_VOL_STEREO,64}, | ||
218 | [SOUND_MIXER_BASS] = {AC97_MASTER_TONE, 16}, | ||
219 | [SOUND_MIXER_TREBLE] = {AC97_MASTER_TONE, 16}, | ||
220 | [SOUND_MIXER_PCM] = {AC97_PCMOUT_VOL, 32}, | ||
221 | [SOUND_MIXER_SPEAKER] = {AC97_PCBEEP_VOL, 16}, | ||
222 | [SOUND_MIXER_LINE] = {AC97_LINEIN_VOL, 32}, | ||
223 | [SOUND_MIXER_MIC] = {AC97_MIC_VOL, 32}, | ||
224 | [SOUND_MIXER_CD] = {AC97_CD_VOL, 32}, | ||
225 | [SOUND_MIXER_ALTPCM] = {AC97_HEADPHONE_VOL, 64}, | ||
226 | [SOUND_MIXER_IGAIN] = {AC97_RECORD_GAIN, 16}, | ||
227 | [SOUND_MIXER_LINE1] = {AC97_AUX_VOL, 32}, | ||
228 | [SOUND_MIXER_PHONEIN] = {AC97_PHONE_VOL, 32}, | ||
229 | [SOUND_MIXER_PHONEOUT] = {AC97_MASTER_VOL_MONO, 64}, | ||
230 | [SOUND_MIXER_VIDEO] = {AC97_VIDEO_VOL, 32}, | ||
231 | }; | ||
232 | |||
233 | /* the following tables allow us to go from OSS <-> ac97 quickly. */ | ||
234 | enum ac97_recsettings { | ||
235 | AC97_REC_MIC=0, | ||
236 | AC97_REC_CD, | ||
237 | AC97_REC_VIDEO, | ||
238 | AC97_REC_AUX, | ||
239 | AC97_REC_LINE, | ||
240 | AC97_REC_STEREO, /* combination of all enabled outputs.. */ | ||
241 | AC97_REC_MONO, /*.. or the mono equivalent */ | ||
242 | AC97_REC_PHONE | ||
243 | }; | ||
244 | |||
245 | static const unsigned int ac97_rm2oss[] = { | ||
246 | [AC97_REC_MIC] = SOUND_MIXER_MIC, | ||
247 | [AC97_REC_CD] = SOUND_MIXER_CD, | ||
248 | [AC97_REC_VIDEO] = SOUND_MIXER_VIDEO, | ||
249 | [AC97_REC_AUX] = SOUND_MIXER_LINE1, | ||
250 | [AC97_REC_LINE] = SOUND_MIXER_LINE, | ||
251 | [AC97_REC_STEREO]= SOUND_MIXER_IGAIN, | ||
252 | [AC97_REC_PHONE] = SOUND_MIXER_PHONEIN | ||
253 | }; | ||
254 | |||
255 | /* indexed by bit position */ | ||
256 | static const unsigned int ac97_oss_rm[] = { | ||
257 | [SOUND_MIXER_MIC] = AC97_REC_MIC, | ||
258 | [SOUND_MIXER_CD] = AC97_REC_CD, | ||
259 | [SOUND_MIXER_VIDEO] = AC97_REC_VIDEO, | ||
260 | [SOUND_MIXER_LINE1] = AC97_REC_AUX, | ||
261 | [SOUND_MIXER_LINE] = AC97_REC_LINE, | ||
262 | [SOUND_MIXER_IGAIN] = AC97_REC_STEREO, | ||
263 | [SOUND_MIXER_PHONEIN] = AC97_REC_PHONE | ||
264 | }; | ||
265 | |||
266 | static LIST_HEAD(codecs); | ||
267 | static LIST_HEAD(codec_drivers); | ||
268 | static DEFINE_MUTEX(codec_mutex); | ||
269 | |||
270 | /* reads the given OSS mixer from the ac97 the caller must have insured that the ac97 knows | ||
271 | about that given mixer, and should be holding a spinlock for the card */ | ||
272 | static int ac97_read_mixer(struct ac97_codec *codec, int oss_channel) | ||
273 | { | ||
274 | u16 val; | ||
275 | int ret = 0; | ||
276 | int scale; | ||
277 | struct ac97_mixer_hw *mh = &ac97_hw[oss_channel]; | ||
278 | |||
279 | val = codec->codec_read(codec , mh->offset); | ||
280 | |||
281 | if (val & AC97_MUTE) { | ||
282 | ret = 0; | ||
283 | } else if (AC97_STEREO_MASK & (1 << oss_channel)) { | ||
284 | /* nice stereo mixers .. */ | ||
285 | int left,right; | ||
286 | |||
287 | left = (val >> 8) & 0x7f; | ||
288 | right = val & 0x7f; | ||
289 | |||
290 | if (oss_channel == SOUND_MIXER_IGAIN) { | ||
291 | right = (right * 100) / mh->scale; | ||
292 | left = (left * 100) / mh->scale; | ||
293 | } else { | ||
294 | /* these may have 5 or 6 bit resolution */ | ||
295 | if(oss_channel == SOUND_MIXER_VOLUME || oss_channel == SOUND_MIXER_ALTPCM) | ||
296 | scale = (1 << codec->bit_resolution); | ||
297 | else | ||
298 | scale = mh->scale; | ||
299 | |||
300 | right = 100 - ((right * 100) / scale); | ||
301 | left = 100 - ((left * 100) / scale); | ||
302 | } | ||
303 | ret = left | (right << 8); | ||
304 | } else if (oss_channel == SOUND_MIXER_SPEAKER) { | ||
305 | ret = 100 - ((((val & 0x1e)>>1) * 100) / mh->scale); | ||
306 | } else if (oss_channel == SOUND_MIXER_PHONEIN) { | ||
307 | ret = 100 - (((val & 0x1f) * 100) / mh->scale); | ||
308 | } else if (oss_channel == SOUND_MIXER_PHONEOUT) { | ||
309 | scale = (1 << codec->bit_resolution); | ||
310 | ret = 100 - (((val & 0x1f) * 100) / scale); | ||
311 | } else if (oss_channel == SOUND_MIXER_MIC) { | ||
312 | ret = 100 - (((val & 0x1f) * 100) / mh->scale); | ||
313 | /* the low bit is optional in the tone sliders and masking | ||
314 | it lets us avoid the 0xf 'bypass'.. */ | ||
315 | } else if (oss_channel == SOUND_MIXER_BASS) { | ||
316 | ret = 100 - ((((val >> 8) & 0xe) * 100) / mh->scale); | ||
317 | } else if (oss_channel == SOUND_MIXER_TREBLE) { | ||
318 | ret = 100 - (((val & 0xe) * 100) / mh->scale); | ||
319 | } | ||
320 | |||
321 | #ifdef DEBUG | ||
322 | printk("ac97_codec: read OSS mixer %2d (%s ac97 register 0x%02x), " | ||
323 | "0x%04x -> 0x%04x\n", | ||
324 | oss_channel, codec->id ? "Secondary" : "Primary", | ||
325 | mh->offset, val, ret); | ||
326 | #endif | ||
327 | |||
328 | return ret; | ||
329 | } | ||
330 | |||
331 | /* write the OSS encoded volume to the given OSS encoded mixer, again caller's job to | ||
332 | make sure all is well in arg land, call with spinlock held */ | ||
333 | static void ac97_write_mixer(struct ac97_codec *codec, int oss_channel, | ||
334 | unsigned int left, unsigned int right) | ||
335 | { | ||
336 | u16 val = 0; | ||
337 | int scale; | ||
338 | struct ac97_mixer_hw *mh = &ac97_hw[oss_channel]; | ||
339 | |||
340 | #ifdef DEBUG | ||
341 | printk("ac97_codec: wrote OSS mixer %2d (%s ac97 register 0x%02x), " | ||
342 | "left vol:%2d, right vol:%2d:", | ||
343 | oss_channel, codec->id ? "Secondary" : "Primary", | ||
344 | mh->offset, left, right); | ||
345 | #endif | ||
346 | |||
347 | if (AC97_STEREO_MASK & (1 << oss_channel)) { | ||
348 | /* stereo mixers */ | ||
349 | if (left == 0 && right == 0) { | ||
350 | val = AC97_MUTE; | ||
351 | } else { | ||
352 | if (oss_channel == SOUND_MIXER_IGAIN) { | ||
353 | right = (right * mh->scale) / 100; | ||
354 | left = (left * mh->scale) / 100; | ||
355 | if (right >= mh->scale) | ||
356 | right = mh->scale-1; | ||
357 | if (left >= mh->scale) | ||
358 | left = mh->scale-1; | ||
359 | } else { | ||
360 | /* these may have 5 or 6 bit resolution */ | ||
361 | if (oss_channel == SOUND_MIXER_VOLUME || | ||
362 | oss_channel == SOUND_MIXER_ALTPCM) | ||
363 | scale = (1 << codec->bit_resolution); | ||
364 | else | ||
365 | scale = mh->scale; | ||
366 | |||
367 | right = ((100 - right) * scale) / 100; | ||
368 | left = ((100 - left) * scale) / 100; | ||
369 | if (right >= scale) | ||
370 | right = scale-1; | ||
371 | if (left >= scale) | ||
372 | left = scale-1; | ||
373 | } | ||
374 | val = (left << 8) | right; | ||
375 | } | ||
376 | } else if (oss_channel == SOUND_MIXER_BASS) { | ||
377 | val = codec->codec_read(codec , mh->offset) & ~0x0f00; | ||
378 | left = ((100 - left) * mh->scale) / 100; | ||
379 | if (left >= mh->scale) | ||
380 | left = mh->scale-1; | ||
381 | val |= (left << 8) & 0x0e00; | ||
382 | } else if (oss_channel == SOUND_MIXER_TREBLE) { | ||
383 | val = codec->codec_read(codec , mh->offset) & ~0x000f; | ||
384 | left = ((100 - left) * mh->scale) / 100; | ||
385 | if (left >= mh->scale) | ||
386 | left = mh->scale-1; | ||
387 | val |= left & 0x000e; | ||
388 | } else if(left == 0) { | ||
389 | val = AC97_MUTE; | ||
390 | } else if (oss_channel == SOUND_MIXER_SPEAKER) { | ||
391 | left = ((100 - left) * mh->scale) / 100; | ||
392 | if (left >= mh->scale) | ||
393 | left = mh->scale-1; | ||
394 | val = left << 1; | ||
395 | } else if (oss_channel == SOUND_MIXER_PHONEIN) { | ||
396 | left = ((100 - left) * mh->scale) / 100; | ||
397 | if (left >= mh->scale) | ||
398 | left = mh->scale-1; | ||
399 | val = left; | ||
400 | } else if (oss_channel == SOUND_MIXER_PHONEOUT) { | ||
401 | scale = (1 << codec->bit_resolution); | ||
402 | left = ((100 - left) * scale) / 100; | ||
403 | if (left >= mh->scale) | ||
404 | left = mh->scale-1; | ||
405 | val = left; | ||
406 | } else if (oss_channel == SOUND_MIXER_MIC) { | ||
407 | val = codec->codec_read(codec , mh->offset) & ~0x801f; | ||
408 | left = ((100 - left) * mh->scale) / 100; | ||
409 | if (left >= mh->scale) | ||
410 | left = mh->scale-1; | ||
411 | val |= left; | ||
412 | /* the low bit is optional in the tone sliders and masking | ||
413 | it lets us avoid the 0xf 'bypass'.. */ | ||
414 | } | ||
415 | #ifdef DEBUG | ||
416 | printk(" 0x%04x", val); | ||
417 | #endif | ||
418 | |||
419 | codec->codec_write(codec, mh->offset, val); | ||
420 | |||
421 | #ifdef DEBUG | ||
422 | val = codec->codec_read(codec, mh->offset); | ||
423 | printk(" -> 0x%04x\n", val); | ||
424 | #endif | ||
425 | } | ||
426 | |||
427 | /* a thin wrapper for write_mixer */ | ||
428 | static void ac97_set_mixer(struct ac97_codec *codec, unsigned int oss_mixer, unsigned int val ) | ||
429 | { | ||
430 | unsigned int left,right; | ||
431 | |||
432 | /* cleanse input a little */ | ||
433 | right = ((val >> 8) & 0xff) ; | ||
434 | left = (val & 0xff) ; | ||
435 | |||
436 | if (right > 100) right = 100; | ||
437 | if (left > 100) left = 100; | ||
438 | |||
439 | codec->mixer_state[oss_mixer] = (right << 8) | left; | ||
440 | codec->write_mixer(codec, oss_mixer, left, right); | ||
441 | } | ||
442 | |||
443 | /* read or write the recmask, the ac97 can really have left and right recording | ||
444 | inputs independently set, but OSS doesn't seem to want us to express that to | ||
445 | the user. the caller guarantees that we have a supported bit set, and they | ||
446 | must be holding the card's spinlock */ | ||
447 | static int ac97_recmask_io(struct ac97_codec *codec, int rw, int mask) | ||
448 | { | ||
449 | unsigned int val; | ||
450 | |||
451 | if (rw) { | ||
452 | /* read it from the card */ | ||
453 | val = codec->codec_read(codec, AC97_RECORD_SELECT); | ||
454 | #ifdef DEBUG | ||
455 | printk("ac97_codec: ac97 recmask to set to 0x%04x\n", val); | ||
456 | #endif | ||
457 | return (1 << ac97_rm2oss[val & 0x07]); | ||
458 | } | ||
459 | |||
460 | /* else, write the first set in the mask as the | ||
461 | output */ | ||
462 | /* clear out current set value first (AC97 supports only 1 input!) */ | ||
463 | val = (1 << ac97_rm2oss[codec->codec_read(codec, AC97_RECORD_SELECT) & 0x07]); | ||
464 | if (mask != val) | ||
465 | mask &= ~val; | ||
466 | |||
467 | val = ffs(mask); | ||
468 | val = ac97_oss_rm[val-1]; | ||
469 | val |= val << 8; /* set both channels */ | ||
470 | |||
471 | #ifdef DEBUG | ||
472 | printk("ac97_codec: setting ac97 recmask to 0x%04x\n", val); | ||
473 | #endif | ||
474 | |||
475 | codec->codec_write(codec, AC97_RECORD_SELECT, val); | ||
476 | |||
477 | return 0; | ||
478 | }; | ||
479 | |||
480 | static int ac97_mixer_ioctl(struct ac97_codec *codec, unsigned int cmd, unsigned long arg) | ||
481 | { | ||
482 | int i, val = 0; | ||
483 | |||
484 | if (cmd == SOUND_MIXER_INFO) { | ||
485 | mixer_info info; | ||
486 | memset(&info, 0, sizeof(info)); | ||
487 | strlcpy(info.id, codec->name, sizeof(info.id)); | ||
488 | strlcpy(info.name, codec->name, sizeof(info.name)); | ||
489 | info.modify_counter = codec->modcnt; | ||
490 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | ||
491 | return -EFAULT; | ||
492 | return 0; | ||
493 | } | ||
494 | if (cmd == SOUND_OLD_MIXER_INFO) { | ||
495 | _old_mixer_info info; | ||
496 | memset(&info, 0, sizeof(info)); | ||
497 | strlcpy(info.id, codec->name, sizeof(info.id)); | ||
498 | strlcpy(info.name, codec->name, sizeof(info.name)); | ||
499 | if (copy_to_user((void __user *)arg, &info, sizeof(info))) | ||
500 | return -EFAULT; | ||
501 | return 0; | ||
502 | } | ||
503 | |||
504 | if (_IOC_TYPE(cmd) != 'M' || _SIOC_SIZE(cmd) != sizeof(int)) | ||
505 | return -EINVAL; | ||
506 | |||
507 | if (cmd == OSS_GETVERSION) | ||
508 | return put_user(SOUND_VERSION, (int __user *)arg); | ||
509 | |||
510 | if (_SIOC_DIR(cmd) == _SIOC_READ) { | ||
511 | switch (_IOC_NR(cmd)) { | ||
512 | case SOUND_MIXER_RECSRC: /* give them the current record source */ | ||
513 | if (!codec->recmask_io) { | ||
514 | val = 0; | ||
515 | } else { | ||
516 | val = codec->recmask_io(codec, 1, 0); | ||
517 | } | ||
518 | break; | ||
519 | |||
520 | case SOUND_MIXER_DEVMASK: /* give them the supported mixers */ | ||
521 | val = codec->supported_mixers; | ||
522 | break; | ||
523 | |||
524 | case SOUND_MIXER_RECMASK: /* Arg contains a bit for each supported recording source */ | ||
525 | val = codec->record_sources; | ||
526 | break; | ||
527 | |||
528 | case SOUND_MIXER_STEREODEVS: /* Mixer channels supporting stereo */ | ||
529 | val = codec->stereo_mixers; | ||
530 | break; | ||
531 | |||
532 | case SOUND_MIXER_CAPS: | ||
533 | val = SOUND_CAP_EXCL_INPUT; | ||
534 | break; | ||
535 | |||
536 | default: /* read a specific mixer */ | ||
537 | i = _IOC_NR(cmd); | ||
538 | |||
539 | if (!supported_mixer(codec, i)) | ||
540 | return -EINVAL; | ||
541 | |||
542 | /* do we ever want to touch the hardware? */ | ||
543 | /* val = codec->read_mixer(codec, i); */ | ||
544 | val = codec->mixer_state[i]; | ||
545 | break; | ||
546 | } | ||
547 | return put_user(val, (int __user *)arg); | ||
548 | } | ||
549 | |||
550 | if (_SIOC_DIR(cmd) == (_SIOC_WRITE|_SIOC_READ)) { | ||
551 | codec->modcnt++; | ||
552 | if (get_user(val, (int __user *)arg)) | ||
553 | return -EFAULT; | ||
554 | |||
555 | switch (_IOC_NR(cmd)) { | ||
556 | case SOUND_MIXER_RECSRC: /* Arg contains a bit for each recording source */ | ||
557 | if (!codec->recmask_io) return -EINVAL; | ||
558 | if (!val) return 0; | ||
559 | if (!(val &= codec->record_sources)) return -EINVAL; | ||
560 | |||
561 | codec->recmask_io(codec, 0, val); | ||
562 | |||
563 | return 0; | ||
564 | default: /* write a specific mixer */ | ||
565 | i = _IOC_NR(cmd); | ||
566 | |||
567 | if (!supported_mixer(codec, i)) | ||
568 | return -EINVAL; | ||
569 | |||
570 | ac97_set_mixer(codec, i, val); | ||
571 | |||
572 | return 0; | ||
573 | } | ||
574 | } | ||
575 | return -EINVAL; | ||
576 | } | ||
577 | |||
578 | /** | ||
579 | * codec_id - Turn id1/id2 into a PnP string | ||
580 | * @id1: Vendor ID1 | ||
581 | * @id2: Vendor ID2 | ||
582 | * @buf: CODEC_ID_BUFSZ byte buffer | ||
583 | * | ||
584 | * Fills buf with a zero terminated PnP ident string for the id1/id2 | ||
585 | * pair. For convenience the return is the passed in buffer pointer. | ||
586 | */ | ||
587 | |||
588 | static char *codec_id(u16 id1, u16 id2, char *buf) | ||
589 | { | ||
590 | if(id1&0x8080) { | ||
591 | snprintf(buf, CODEC_ID_BUFSZ, "0x%04x:0x%04x", id1, id2); | ||
592 | } else { | ||
593 | buf[0] = (id1 >> 8); | ||
594 | buf[1] = (id1 & 0xFF); | ||
595 | buf[2] = (id2 >> 8); | ||
596 | snprintf(buf+3, CODEC_ID_BUFSZ - 3, "%d", id2&0xFF); | ||
597 | } | ||
598 | return buf; | ||
599 | } | ||
600 | |||
601 | /** | ||
602 | * ac97_check_modem - Check if the Codec is a modem | ||
603 | * @codec: codec to check | ||
604 | * | ||
605 | * Return true if the device is an AC97 1.0 or AC97 2.0 modem | ||
606 | */ | ||
607 | |||
608 | static int ac97_check_modem(struct ac97_codec *codec) | ||
609 | { | ||
610 | /* Check for an AC97 1.0 soft modem (ID1) */ | ||
611 | if(codec->codec_read(codec, AC97_RESET) & 2) | ||
612 | return 1; | ||
613 | /* Check for an AC97 2.x soft modem */ | ||
614 | codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0L); | ||
615 | if(codec->codec_read(codec, AC97_EXTENDED_MODEM_ID) & 1) | ||
616 | return 1; | ||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | |||
621 | /** | ||
622 | * ac97_alloc_codec - Allocate an AC97 codec | ||
623 | * | ||
624 | * Returns a new AC97 codec structure. AC97 codecs may become | ||
625 | * refcounted soon so this interface is needed. Returns with | ||
626 | * one reference taken. | ||
627 | */ | ||
628 | |||
629 | struct ac97_codec *ac97_alloc_codec(void) | ||
630 | { | ||
631 | struct ac97_codec *codec = kzalloc(sizeof(struct ac97_codec), GFP_KERNEL); | ||
632 | if(!codec) | ||
633 | return NULL; | ||
634 | |||
635 | spin_lock_init(&codec->lock); | ||
636 | INIT_LIST_HEAD(&codec->list); | ||
637 | return codec; | ||
638 | } | ||
639 | |||
640 | EXPORT_SYMBOL(ac97_alloc_codec); | ||
641 | |||
642 | /** | ||
643 | * ac97_release_codec - Release an AC97 codec | ||
644 | * @codec: codec to release | ||
645 | * | ||
646 | * Release an allocated AC97 codec. This will be refcounted in | ||
647 | * time but for the moment is trivial. Calls the unregister | ||
648 | * handler if the codec is now defunct. | ||
649 | */ | ||
650 | |||
651 | void ac97_release_codec(struct ac97_codec *codec) | ||
652 | { | ||
653 | /* Remove from the list first, we don't want to be | ||
654 | "rediscovered" */ | ||
655 | mutex_lock(&codec_mutex); | ||
656 | list_del(&codec->list); | ||
657 | mutex_unlock(&codec_mutex); | ||
658 | /* | ||
659 | * The driver needs to deal with internal | ||
660 | * locking to avoid accidents here. | ||
661 | */ | ||
662 | if(codec->driver) | ||
663 | codec->driver->remove(codec, codec->driver); | ||
664 | kfree(codec); | ||
665 | } | ||
666 | |||
667 | EXPORT_SYMBOL(ac97_release_codec); | ||
668 | |||
669 | /** | ||
670 | * ac97_probe_codec - Initialize and setup AC97-compatible codec | ||
671 | * @codec: (in/out) Kernel info for a single AC97 codec | ||
672 | * | ||
673 | * Reset the AC97 codec, then initialize the mixer and | ||
674 | * the rest of the @codec structure. | ||
675 | * | ||
676 | * The codec_read and codec_write fields of @codec are | ||
677 | * required to be setup and working when this function | ||
678 | * is called. All other fields are set by this function. | ||
679 | * | ||
680 | * codec_wait field of @codec can optionally be provided | ||
681 | * when calling this function. If codec_wait is not %NULL, | ||
682 | * this function will call codec_wait any time it is | ||
683 | * necessary to wait for the audio chip to reach the | ||
684 | * codec-ready state. If codec_wait is %NULL, then | ||
685 | * the default behavior is to call schedule_timeout. | ||
686 | * Currently codec_wait is used to wait for AC97 codec | ||
687 | * reset to complete. | ||
688 | * | ||
689 | * Some codecs will power down when a register reset is | ||
690 | * performed. We now check for such codecs. | ||
691 | * | ||
692 | * Returns 1 (true) on success, or 0 (false) on failure. | ||
693 | */ | ||
694 | |||
695 | int ac97_probe_codec(struct ac97_codec *codec) | ||
696 | { | ||
697 | u16 id1, id2; | ||
698 | u16 audio; | ||
699 | int i; | ||
700 | char cidbuf[CODEC_ID_BUFSZ]; | ||
701 | u16 f; | ||
702 | struct list_head *l; | ||
703 | struct ac97_driver *d; | ||
704 | |||
705 | /* wait for codec-ready state */ | ||
706 | if (codec->codec_wait) | ||
707 | codec->codec_wait(codec); | ||
708 | else | ||
709 | udelay(10); | ||
710 | |||
711 | /* will the codec power down if register reset ? */ | ||
712 | id1 = codec->codec_read(codec, AC97_VENDOR_ID1); | ||
713 | id2 = codec->codec_read(codec, AC97_VENDOR_ID2); | ||
714 | codec->name = NULL; | ||
715 | codec->codec_ops = &null_ops; | ||
716 | for (i = 0; i < ARRAY_SIZE(ac97_codec_ids); i++) { | ||
717 | if (ac97_codec_ids[i].id == ((id1 << 16) | id2)) { | ||
718 | codec->type = ac97_codec_ids[i].id; | ||
719 | codec->name = ac97_codec_ids[i].name; | ||
720 | codec->codec_ops = ac97_codec_ids[i].ops; | ||
721 | codec->flags = ac97_codec_ids[i].flags; | ||
722 | break; | ||
723 | } | ||
724 | } | ||
725 | |||
726 | codec->model = (id1 << 16) | id2; | ||
727 | if ((codec->flags & AC97_DEFAULT_POWER_OFF) == 0) { | ||
728 | /* reset codec and wait for the ready bit before we continue */ | ||
729 | codec->codec_write(codec, AC97_RESET, 0L); | ||
730 | if (codec->codec_wait) | ||
731 | codec->codec_wait(codec); | ||
732 | else | ||
733 | udelay(10); | ||
734 | } | ||
735 | |||
736 | /* probing AC97 codec, AC97 2.0 says that bit 15 of register 0x00 (reset) should | ||
737 | * be read zero. | ||
738 | * | ||
739 | * FIXME: is the following comment outdated? -jgarzik | ||
740 | * Probing of AC97 in this way is not reliable, it is not even SAFE !! | ||
741 | */ | ||
742 | if ((audio = codec->codec_read(codec, AC97_RESET)) & 0x8000) { | ||
743 | printk(KERN_ERR "ac97_codec: %s ac97 codec not present\n", | ||
744 | (codec->id & 0x2) ? (codec->id&1 ? "4th" : "Tertiary") | ||
745 | : (codec->id&1 ? "Secondary": "Primary")); | ||
746 | return 0; | ||
747 | } | ||
748 | |||
749 | /* probe for Modem Codec */ | ||
750 | codec->modem = ac97_check_modem(codec); | ||
751 | |||
752 | /* enable SPDIF */ | ||
753 | f = codec->codec_read(codec, AC97_EXTENDED_STATUS); | ||
754 | if((codec->codec_ops == &null_ops) && (f & 4)) | ||
755 | codec->codec_ops = &default_digital_ops; | ||
756 | |||
757 | /* A device which thinks its a modem but isn't */ | ||
758 | if(codec->flags & AC97_DELUDED_MODEM) | ||
759 | codec->modem = 0; | ||
760 | |||
761 | if (codec->name == NULL) | ||
762 | codec->name = "Unknown"; | ||
763 | printk(KERN_INFO "ac97_codec: AC97 %s codec, id: %s (%s)\n", | ||
764 | codec->modem ? "Modem" : (audio ? "Audio" : ""), | ||
765 | codec_id(id1, id2, cidbuf), codec->name); | ||
766 | |||
767 | if(!ac97_init_mixer(codec)) | ||
768 | return 0; | ||
769 | |||
770 | /* | ||
771 | * Attach last so the caller can override the mixer | ||
772 | * callbacks. | ||
773 | */ | ||
774 | |||
775 | mutex_lock(&codec_mutex); | ||
776 | list_add(&codec->list, &codecs); | ||
777 | |||
778 | list_for_each(l, &codec_drivers) { | ||
779 | d = list_entry(l, struct ac97_driver, list); | ||
780 | if ((codec->model ^ d->codec_id) & d->codec_mask) | ||
781 | continue; | ||
782 | if(d->probe(codec, d) == 0) | ||
783 | { | ||
784 | codec->driver = d; | ||
785 | break; | ||
786 | } | ||
787 | } | ||
788 | |||
789 | mutex_unlock(&codec_mutex); | ||
790 | return 1; | ||
791 | } | ||
792 | |||
793 | static int ac97_init_mixer(struct ac97_codec *codec) | ||
794 | { | ||
795 | u16 cap; | ||
796 | int i; | ||
797 | |||
798 | cap = codec->codec_read(codec, AC97_RESET); | ||
799 | |||
800 | /* mixer masks */ | ||
801 | codec->supported_mixers = AC97_SUPPORTED_MASK; | ||
802 | codec->stereo_mixers = AC97_STEREO_MASK; | ||
803 | codec->record_sources = AC97_RECORD_MASK; | ||
804 | if (!(cap & 0x04)) | ||
805 | codec->supported_mixers &= ~(SOUND_MASK_BASS|SOUND_MASK_TREBLE); | ||
806 | if (!(cap & 0x10)) | ||
807 | codec->supported_mixers &= ~SOUND_MASK_ALTPCM; | ||
808 | |||
809 | |||
810 | /* detect bit resolution */ | ||
811 | codec->codec_write(codec, AC97_MASTER_VOL_STEREO, 0x2020); | ||
812 | if(codec->codec_read(codec, AC97_MASTER_VOL_STEREO) == 0x2020) | ||
813 | codec->bit_resolution = 6; | ||
814 | else | ||
815 | codec->bit_resolution = 5; | ||
816 | |||
817 | /* generic OSS to AC97 wrapper */ | ||
818 | codec->read_mixer = ac97_read_mixer; | ||
819 | codec->write_mixer = ac97_write_mixer; | ||
820 | codec->recmask_io = ac97_recmask_io; | ||
821 | codec->mixer_ioctl = ac97_mixer_ioctl; | ||
822 | |||
823 | /* initialize mixer channel volumes */ | ||
824 | for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) { | ||
825 | struct mixer_defaults *md = &mixer_defaults[i]; | ||
826 | if (md->mixer == -1) | ||
827 | break; | ||
828 | if (!supported_mixer(codec, md->mixer)) | ||
829 | continue; | ||
830 | ac97_set_mixer(codec, md->mixer, md->value); | ||
831 | } | ||
832 | |||
833 | /* codec specific initialization for 4-6 channel output or secondary codec stuff */ | ||
834 | if (codec->codec_ops->init != NULL) { | ||
835 | codec->codec_ops->init(codec); | ||
836 | } | ||
837 | |||
838 | /* | ||
839 | * Volume is MUTE only on this device. We have to initialise | ||
840 | * it but its useless beyond that. | ||
841 | */ | ||
842 | if(codec->flags & AC97_NO_PCM_VOLUME) | ||
843 | { | ||
844 | codec->supported_mixers &= ~SOUND_MASK_PCM; | ||
845 | printk(KERN_WARNING "AC97 codec does not have proper volume support.\n"); | ||
846 | } | ||
847 | return 1; | ||
848 | } | ||
849 | |||
850 | #define AC97_SIGMATEL_ANALOG 0x6c /* Analog Special */ | ||
851 | #define AC97_SIGMATEL_DAC2INVERT 0x6e | ||
852 | #define AC97_SIGMATEL_BIAS1 0x70 | ||
853 | #define AC97_SIGMATEL_BIAS2 0x72 | ||
854 | #define AC97_SIGMATEL_MULTICHN 0x74 /* Multi-Channel programming */ | ||
855 | #define AC97_SIGMATEL_CIC1 0x76 | ||
856 | #define AC97_SIGMATEL_CIC2 0x78 | ||
857 | |||
858 | |||
859 | static int sigmatel_9708_init(struct ac97_codec * codec) | ||
860 | { | ||
861 | u16 codec72, codec6c; | ||
862 | |||
863 | codec72 = codec->codec_read(codec, AC97_SIGMATEL_BIAS2) & 0x8000; | ||
864 | codec6c = codec->codec_read(codec, AC97_SIGMATEL_ANALOG); | ||
865 | |||
866 | if ((codec72==0) && (codec6c==0)) { | ||
867 | codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba); | ||
868 | codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x1000); | ||
869 | codec->codec_write(codec, AC97_SIGMATEL_BIAS1, 0xabba); | ||
870 | codec->codec_write(codec, AC97_SIGMATEL_BIAS2, 0x0007); | ||
871 | } else if ((codec72==0x8000) && (codec6c==0)) { | ||
872 | codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba); | ||
873 | codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x1001); | ||
874 | codec->codec_write(codec, AC97_SIGMATEL_DAC2INVERT, 0x0008); | ||
875 | } else if ((codec72==0x8000) && (codec6c==0x0080)) { | ||
876 | /* nothing */ | ||
877 | } | ||
878 | codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x0000); | ||
879 | return 0; | ||
880 | } | ||
881 | |||
882 | |||
883 | static int sigmatel_9721_init(struct ac97_codec * codec) | ||
884 | { | ||
885 | /* Only set up secondary codec */ | ||
886 | if (codec->id == 0) | ||
887 | return 0; | ||
888 | |||
889 | codec->codec_write(codec, AC97_SURROUND_MASTER, 0L); | ||
890 | |||
891 | /* initialize SigmaTel STAC9721/23 as secondary codec, decoding AC link | ||
892 | sloc 3,4 = 0x01, slot 7,8 = 0x00, */ | ||
893 | codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x00); | ||
894 | |||
895 | /* we don't have the crystal when we are on an AMR card, so use | ||
896 | BIT_CLK as our clock source. Write the magic word ABBA and read | ||
897 | back to enable register 0x78 */ | ||
898 | codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba); | ||
899 | codec->codec_read(codec, AC97_SIGMATEL_CIC1); | ||
900 | |||
901 | /* sync all the clocks*/ | ||
902 | codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x3802); | ||
903 | |||
904 | return 0; | ||
905 | } | ||
906 | |||
907 | |||
908 | static int sigmatel_9744_init(struct ac97_codec * codec) | ||
909 | { | ||
910 | // patch for SigmaTel | ||
911 | codec->codec_write(codec, AC97_SIGMATEL_CIC1, 0xabba); | ||
912 | codec->codec_write(codec, AC97_SIGMATEL_CIC2, 0x0000); // is this correct? --jk | ||
913 | codec->codec_write(codec, AC97_SIGMATEL_BIAS1, 0xabba); | ||
914 | codec->codec_write(codec, AC97_SIGMATEL_BIAS2, 0x0002); | ||
915 | codec->codec_write(codec, AC97_SIGMATEL_MULTICHN, 0x0000); | ||
916 | return 0; | ||
917 | } | ||
918 | |||
919 | static int cmedia_init(struct ac97_codec *codec) | ||
920 | { | ||
921 | /* Initialise the CMedia 9739 */ | ||
922 | /* | ||
923 | We could set various options here | ||
924 | Register 0x20 bit 0x100 sets mic as center bass | ||
925 | Also do multi_channel_ctrl &=~0x3000 |=0x1000 | ||
926 | |||
927 | For now we set up the GPIO and PC beep | ||
928 | */ | ||
929 | |||
930 | u16 v; | ||
931 | |||
932 | /* MIC */ | ||
933 | codec->codec_write(codec, 0x64, 0x3000); | ||
934 | v = codec->codec_read(codec, 0x64); | ||
935 | v &= ~0x8000; | ||
936 | codec->codec_write(codec, 0x64, v); | ||
937 | codec->codec_write(codec, 0x70, 0x0100); | ||
938 | codec->codec_write(codec, 0x72, 0x0020); | ||
939 | return 0; | ||
940 | } | ||
941 | |||
942 | #define AC97_WM97XX_FMIXER_VOL 0x72 | ||
943 | #define AC97_WM97XX_RMIXER_VOL 0x74 | ||
944 | #define AC97_WM97XX_TEST 0x5a | ||
945 | #define AC97_WM9704_RPCM_VOL 0x70 | ||
946 | #define AC97_WM9711_OUT3VOL 0x16 | ||
947 | |||
948 | static int wolfson_init03(struct ac97_codec * codec) | ||
949 | { | ||
950 | /* this is known to work for the ViewSonic ViewPad 1000 */ | ||
951 | codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808); | ||
952 | codec->codec_write(codec, AC97_GENERAL_PURPOSE, 0x8000); | ||
953 | return 0; | ||
954 | } | ||
955 | |||
956 | static int wolfson_init04(struct ac97_codec * codec) | ||
957 | { | ||
958 | codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808); | ||
959 | codec->codec_write(codec, AC97_WM97XX_RMIXER_VOL, 0x0808); | ||
960 | |||
961 | // patch for DVD noise | ||
962 | codec->codec_write(codec, AC97_WM97XX_TEST, 0x0200); | ||
963 | |||
964 | // init vol as PCM vol | ||
965 | codec->codec_write(codec, AC97_WM9704_RPCM_VOL, | ||
966 | codec->codec_read(codec, AC97_PCMOUT_VOL)); | ||
967 | |||
968 | /* set rear surround volume */ | ||
969 | codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000); | ||
970 | return 0; | ||
971 | } | ||
972 | |||
973 | /* WM9705, WM9710 */ | ||
974 | static int wolfson_init05(struct ac97_codec * codec) | ||
975 | { | ||
976 | /* set front mixer volume */ | ||
977 | codec->codec_write(codec, AC97_WM97XX_FMIXER_VOL, 0x0808); | ||
978 | return 0; | ||
979 | } | ||
980 | |||
981 | /* WM9711, WM9712 */ | ||
982 | static int wolfson_init11(struct ac97_codec * codec) | ||
983 | { | ||
984 | /* stop pop's during suspend/resume */ | ||
985 | codec->codec_write(codec, AC97_WM97XX_TEST, | ||
986 | codec->codec_read(codec, AC97_WM97XX_TEST) & 0xffbf); | ||
987 | |||
988 | /* set out3 volume */ | ||
989 | codec->codec_write(codec, AC97_WM9711_OUT3VOL, 0x0808); | ||
990 | return 0; | ||
991 | } | ||
992 | |||
993 | /* WM9713 */ | ||
994 | static int wolfson_init13(struct ac97_codec * codec) | ||
995 | { | ||
996 | codec->codec_write(codec, AC97_RECORD_GAIN, 0x00a0); | ||
997 | codec->codec_write(codec, AC97_POWER_CONTROL, 0x0000); | ||
998 | codec->codec_write(codec, AC97_EXTENDED_MODEM_ID, 0xDA00); | ||
999 | codec->codec_write(codec, AC97_EXTEND_MODEM_STAT, 0x3810); | ||
1000 | codec->codec_write(codec, AC97_PHONE_VOL, 0x0808); | ||
1001 | codec->codec_write(codec, AC97_PCBEEP_VOL, 0x0808); | ||
1002 | |||
1003 | return 0; | ||
1004 | } | ||
1005 | |||
1006 | static int tritech_init(struct ac97_codec * codec) | ||
1007 | { | ||
1008 | codec->codec_write(codec, 0x26, 0x0300); | ||
1009 | codec->codec_write(codec, 0x26, 0x0000); | ||
1010 | codec->codec_write(codec, AC97_SURROUND_MASTER, 0x0000); | ||
1011 | codec->codec_write(codec, AC97_RESERVED_3A, 0x0000); | ||
1012 | return 0; | ||
1013 | } | ||
1014 | |||
1015 | |||
1016 | /* copied from drivers/sound/maestro.c */ | ||
1017 | static int tritech_maestro_init(struct ac97_codec * codec) | ||
1018 | { | ||
1019 | /* no idea what this does */ | ||
1020 | codec->codec_write(codec, 0x2A, 0x0001); | ||
1021 | codec->codec_write(codec, 0x2C, 0x0000); | ||
1022 | codec->codec_write(codec, 0x2C, 0XFFFF); | ||
1023 | return 0; | ||
1024 | } | ||
1025 | |||
1026 | |||
1027 | |||
1028 | /* | ||
1029 | * Presario700 workaround | ||
1030 | * for Jack Sense/SPDIF Register mis-setting causing | ||
1031 | * no audible output | ||
1032 | * by Santiago Nullo 04/05/2002 | ||
1033 | */ | ||
1034 | |||
1035 | #define AC97_AD1886_JACK_SENSE 0x72 | ||
1036 | |||
1037 | static int ad1886_init(struct ac97_codec * codec) | ||
1038 | { | ||
1039 | /* from AD1886 Specs */ | ||
1040 | codec->codec_write(codec, AC97_AD1886_JACK_SENSE, 0x0010); | ||
1041 | return 0; | ||
1042 | } | ||
1043 | |||
1044 | |||
1045 | |||
1046 | |||
1047 | /* | ||
1048 | * This is basically standard AC97. It should work as a default for | ||
1049 | * almost all modern codecs. Note that some cards wire EAPD *backwards* | ||
1050 | * That side of it is up to the card driver not us to cope with. | ||
1051 | * | ||
1052 | */ | ||
1053 | |||
1054 | static int eapd_control(struct ac97_codec * codec, int on) | ||
1055 | { | ||
1056 | if(on) | ||
1057 | codec->codec_write(codec, AC97_POWER_CONTROL, | ||
1058 | codec->codec_read(codec, AC97_POWER_CONTROL)|0x8000); | ||
1059 | else | ||
1060 | codec->codec_write(codec, AC97_POWER_CONTROL, | ||
1061 | codec->codec_read(codec, AC97_POWER_CONTROL)&~0x8000); | ||
1062 | return 0; | ||
1063 | } | ||
1064 | |||
1065 | static int generic_digital_control(struct ac97_codec *codec, int slots, int rate, int mode) | ||
1066 | { | ||
1067 | u16 reg; | ||
1068 | |||
1069 | reg = codec->codec_read(codec, AC97_SPDIF_CONTROL); | ||
1070 | |||
1071 | switch(rate) | ||
1072 | { | ||
1073 | /* Off by default */ | ||
1074 | default: | ||
1075 | case 0: | ||
1076 | reg = codec->codec_read(codec, AC97_EXTENDED_STATUS); | ||
1077 | codec->codec_write(codec, AC97_EXTENDED_STATUS, (reg & ~AC97_EA_SPDIF)); | ||
1078 | if(rate == 0) | ||
1079 | return 0; | ||
1080 | return -EINVAL; | ||
1081 | case 1: | ||
1082 | reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_48K; | ||
1083 | break; | ||
1084 | case 2: | ||
1085 | reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_44K; | ||
1086 | break; | ||
1087 | case 3: | ||
1088 | reg = (reg & AC97_SC_SPSR_MASK) | AC97_SC_SPSR_32K; | ||
1089 | break; | ||
1090 | } | ||
1091 | |||
1092 | reg &= ~AC97_SC_CC_MASK; | ||
1093 | reg |= (mode & AUDIO_CCMASK) << 6; | ||
1094 | |||
1095 | if(mode & AUDIO_DIGITAL) | ||
1096 | reg |= 2; | ||
1097 | if(mode & AUDIO_PRO) | ||
1098 | reg |= 1; | ||
1099 | if(mode & AUDIO_DRS) | ||
1100 | reg |= 0x4000; | ||
1101 | |||
1102 | codec->codec_write(codec, AC97_SPDIF_CONTROL, reg); | ||
1103 | |||
1104 | reg = codec->codec_read(codec, AC97_EXTENDED_STATUS); | ||
1105 | reg &= (AC97_EA_SLOT_MASK); | ||
1106 | reg |= AC97_EA_VRA | AC97_EA_SPDIF | slots; | ||
1107 | codec->codec_write(codec, AC97_EXTENDED_STATUS, reg); | ||
1108 | |||
1109 | reg = codec->codec_read(codec, AC97_EXTENDED_STATUS); | ||
1110 | if(!(reg & 0x0400)) | ||
1111 | { | ||
1112 | codec->codec_write(codec, AC97_EXTENDED_STATUS, reg & ~ AC97_EA_SPDIF); | ||
1113 | return -EINVAL; | ||
1114 | } | ||
1115 | return 0; | ||
1116 | } | ||
1117 | |||
1118 | /* | ||
1119 | * Crystal digital audio control (CS4299) | ||
1120 | */ | ||
1121 | |||
1122 | static int crystal_digital_control(struct ac97_codec *codec, int slots, int rate, int mode) | ||
1123 | { | ||
1124 | u16 cv; | ||
1125 | |||
1126 | if(mode & AUDIO_DIGITAL) | ||
1127 | return -EINVAL; | ||
1128 | |||
1129 | switch(rate) | ||
1130 | { | ||
1131 | case 0: cv = 0x0; break; /* SPEN off */ | ||
1132 | case 48000: cv = 0x8004; break; /* 48KHz digital */ | ||
1133 | case 44100: cv = 0x8104; break; /* 44.1KHz digital */ | ||
1134 | case 32768: /* 32Khz */ | ||
1135 | default: | ||
1136 | return -EINVAL; | ||
1137 | } | ||
1138 | codec->codec_write(codec, 0x68, cv); | ||
1139 | return 0; | ||
1140 | } | ||
1141 | |||
1142 | /* | ||
1143 | * CMedia digital audio control | ||
1144 | * Needs more work. | ||
1145 | */ | ||
1146 | |||
1147 | static int cmedia_digital_control(struct ac97_codec *codec, int slots, int rate, int mode) | ||
1148 | { | ||
1149 | u16 cv; | ||
1150 | |||
1151 | if(mode & AUDIO_DIGITAL) | ||
1152 | return -EINVAL; | ||
1153 | |||
1154 | switch(rate) | ||
1155 | { | ||
1156 | case 0: cv = 0x0001; break; /* SPEN off */ | ||
1157 | case 48000: cv = 0x0009; break; /* 48KHz digital */ | ||
1158 | default: | ||
1159 | return -EINVAL; | ||
1160 | } | ||
1161 | codec->codec_write(codec, 0x2A, 0x05c4); | ||
1162 | codec->codec_write(codec, 0x6C, cv); | ||
1163 | |||
1164 | /* Switch on mix to surround */ | ||
1165 | cv = codec->codec_read(codec, 0x64); | ||
1166 | cv &= ~0x0200; | ||
1167 | if(mode) | ||
1168 | cv |= 0x0200; | ||
1169 | codec->codec_write(codec, 0x64, cv); | ||
1170 | return 0; | ||
1171 | } | ||
1172 | |||
1173 | |||
1174 | /* copied from drivers/sound/maestro.c */ | ||
1175 | #if 0 /* there has been 1 person on the planet with a pt101 that we | ||
1176 | know of. If they care, they can put this back in :) */ | ||
1177 | static int pt101_init(struct ac97_codec * codec) | ||
1178 | { | ||
1179 | printk(KERN_INFO "ac97_codec: PT101 Codec detected, initializing but _not_ installing mixer device.\n"); | ||
1180 | /* who knows.. */ | ||
1181 | codec->codec_write(codec, 0x2A, 0x0001); | ||
1182 | codec->codec_write(codec, 0x2C, 0x0000); | ||
1183 | codec->codec_write(codec, 0x2C, 0xFFFF); | ||
1184 | codec->codec_write(codec, 0x10, 0x9F1F); | ||
1185 | codec->codec_write(codec, 0x12, 0x0808); | ||
1186 | codec->codec_write(codec, 0x14, 0x9F1F); | ||
1187 | codec->codec_write(codec, 0x16, 0x9F1F); | ||
1188 | codec->codec_write(codec, 0x18, 0x0404); | ||
1189 | codec->codec_write(codec, 0x1A, 0x0000); | ||
1190 | codec->codec_write(codec, 0x1C, 0x0000); | ||
1191 | codec->codec_write(codec, 0x02, 0x0404); | ||
1192 | codec->codec_write(codec, 0x04, 0x0808); | ||
1193 | codec->codec_write(codec, 0x0C, 0x801F); | ||
1194 | codec->codec_write(codec, 0x0E, 0x801F); | ||
1195 | return 0; | ||
1196 | } | ||
1197 | #endif | ||
1198 | |||
1199 | |||
1200 | EXPORT_SYMBOL(ac97_probe_codec); | ||
1201 | |||
1202 | MODULE_LICENSE("GPL"); | ||
1203 | |||
diff --git a/sound/oss/au1550_ac97.c b/sound/oss/au1550_ac97.c deleted file mode 100644 index a8f626d99c5b..000000000000 --- a/sound/oss/au1550_ac97.c +++ /dev/null | |||
@@ -1,2147 +0,0 @@ | |||
1 | /* | ||
2 | * au1550_ac97.c -- Sound driver for Alchemy Au1550 MIPS Internet Edge | ||
3 | * Processor. | ||
4 | * | ||
5 | * Copyright 2004 Embedded Edge, LLC | ||
6 | * dan@embeddededge.com | ||
7 | * | ||
8 | * Mostly copied from the au1000.c driver and some from the | ||
9 | * PowerMac dbdma driver. | ||
10 | * We assume the processor can do memory coherent DMA. | ||
11 | * | ||
12 | * Ported to 2.6 by Matt Porter <mporter@kernel.crashing.org> | ||
13 | * | ||
14 | * This program is free software; you can redistribute it and/or modify it | ||
15 | * under the terms of the GNU General Public License as published by the | ||
16 | * Free Software Foundation; either version 2 of the License, or (at your | ||
17 | * option) any later version. | ||
18 | * | ||
19 | * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | ||
20 | * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
21 | * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN | ||
22 | * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | ||
23 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | ||
24 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | ||
25 | * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | ||
26 | * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
27 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | ||
28 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
29 | * | ||
30 | * You should have received a copy of the GNU General Public License along | ||
31 | * with this program; if not, write to the Free Software Foundation, Inc., | ||
32 | * 675 Mass Ave, Cambridge, MA 02139, USA. | ||
33 | * | ||
34 | */ | ||
35 | |||
36 | #undef DEBUG | ||
37 | |||
38 | #include <linux/module.h> | ||
39 | #include <linux/string.h> | ||
40 | #include <linux/ioport.h> | ||
41 | #include <linux/sched.h> | ||
42 | #include <linux/delay.h> | ||
43 | #include <linux/sound.h> | ||
44 | #include <linux/slab.h> | ||
45 | #include <linux/soundcard.h> | ||
46 | #include <linux/init.h> | ||
47 | #include <linux/interrupt.h> | ||
48 | #include <linux/kernel.h> | ||
49 | #include <linux/poll.h> | ||
50 | #include <linux/bitops.h> | ||
51 | #include <linux/spinlock.h> | ||
52 | #include <linux/ac97_codec.h> | ||
53 | #include <linux/mutex.h> | ||
54 | |||
55 | #include <asm/io.h> | ||
56 | #include <asm/uaccess.h> | ||
57 | #include <asm/hardirq.h> | ||
58 | #include <asm/mach-au1x00/au1xxx_psc.h> | ||
59 | #include <asm/mach-au1x00/au1xxx_dbdma.h> | ||
60 | #include <asm/mach-au1x00/au1xxx.h> | ||
61 | |||
62 | #undef OSS_DOCUMENTED_MIXER_SEMANTICS | ||
63 | |||
64 | /* misc stuff */ | ||
65 | #define POLL_COUNT 0x50000 | ||
66 | #define AC97_EXT_DACS (AC97_EXTID_SDAC | AC97_EXTID_CDAC | AC97_EXTID_LDAC) | ||
67 | |||
68 | /* The number of DBDMA ring descriptors to allocate. No sense making | ||
69 | * this too large....if you can't keep up with a few you aren't likely | ||
70 | * to be able to with lots of them, either. | ||
71 | */ | ||
72 | #define NUM_DBDMA_DESCRIPTORS 4 | ||
73 | |||
74 | #define err(format, arg...) printk(KERN_ERR format "\n" , ## arg) | ||
75 | |||
76 | /* Boot options | ||
77 | * 0 = no VRA, 1 = use VRA if codec supports it | ||
78 | */ | ||
79 | static DEFINE_MUTEX(au1550_ac97_mutex); | ||
80 | static int vra = 1; | ||
81 | module_param(vra, bool, 0); | ||
82 | MODULE_PARM_DESC(vra, "if 1 use VRA if codec supports it"); | ||
83 | |||
84 | static struct au1550_state { | ||
85 | /* soundcore stuff */ | ||
86 | int dev_audio; | ||
87 | |||
88 | struct ac97_codec *codec; | ||
89 | unsigned codec_base_caps; /* AC'97 reg 00h, "Reset Register" */ | ||
90 | unsigned codec_ext_caps; /* AC'97 reg 28h, "Extended Audio ID" */ | ||
91 | int no_vra; /* do not use VRA */ | ||
92 | |||
93 | spinlock_t lock; | ||
94 | struct mutex open_mutex; | ||
95 | struct mutex sem; | ||
96 | fmode_t open_mode; | ||
97 | wait_queue_head_t open_wait; | ||
98 | |||
99 | struct dmabuf { | ||
100 | u32 dmanr; | ||
101 | unsigned sample_rate; | ||
102 | unsigned src_factor; | ||
103 | unsigned sample_size; | ||
104 | int num_channels; | ||
105 | int dma_bytes_per_sample; | ||
106 | int user_bytes_per_sample; | ||
107 | int cnt_factor; | ||
108 | |||
109 | void *rawbuf; | ||
110 | unsigned buforder; | ||
111 | unsigned numfrag; | ||
112 | unsigned fragshift; | ||
113 | void *nextIn; | ||
114 | void *nextOut; | ||
115 | int count; | ||
116 | unsigned total_bytes; | ||
117 | unsigned error; | ||
118 | wait_queue_head_t wait; | ||
119 | |||
120 | /* redundant, but makes calculations easier */ | ||
121 | unsigned fragsize; | ||
122 | unsigned dma_fragsize; | ||
123 | unsigned dmasize; | ||
124 | unsigned dma_qcount; | ||
125 | |||
126 | /* OSS stuff */ | ||
127 | unsigned mapped:1; | ||
128 | unsigned ready:1; | ||
129 | unsigned stopped:1; | ||
130 | unsigned ossfragshift; | ||
131 | int ossmaxfrags; | ||
132 | unsigned subdivision; | ||
133 | } dma_dac, dma_adc; | ||
134 | } au1550_state; | ||
135 | |||
136 | static unsigned | ||
137 | ld2(unsigned int x) | ||
138 | { | ||
139 | unsigned r = 0; | ||
140 | |||
141 | if (x >= 0x10000) { | ||
142 | x >>= 16; | ||
143 | r += 16; | ||
144 | } | ||
145 | if (x >= 0x100) { | ||
146 | x >>= 8; | ||
147 | r += 8; | ||
148 | } | ||
149 | if (x >= 0x10) { | ||
150 | x >>= 4; | ||
151 | r += 4; | ||
152 | } | ||
153 | if (x >= 4) { | ||
154 | x >>= 2; | ||
155 | r += 2; | ||
156 | } | ||
157 | if (x >= 2) | ||
158 | r++; | ||
159 | return r; | ||
160 | } | ||
161 | |||
162 | static void | ||
163 | au1550_delay(int msec) | ||
164 | { | ||
165 | if (in_interrupt()) | ||
166 | return; | ||
167 | |||
168 | schedule_timeout_uninterruptible(msecs_to_jiffies(msec)); | ||
169 | } | ||
170 | |||
171 | static u16 | ||
172 | rdcodec(struct ac97_codec *codec, u8 addr) | ||
173 | { | ||
174 | struct au1550_state *s = codec->private_data; | ||
175 | unsigned long flags; | ||
176 | u32 cmd, val; | ||
177 | u16 data; | ||
178 | int i; | ||
179 | |||
180 | spin_lock_irqsave(&s->lock, flags); | ||
181 | |||
182 | for (i = 0; i < POLL_COUNT; i++) { | ||
183 | val = au_readl(PSC_AC97STAT); | ||
184 | au_sync(); | ||
185 | if (!(val & PSC_AC97STAT_CP)) | ||
186 | break; | ||
187 | } | ||
188 | if (i == POLL_COUNT) | ||
189 | err("rdcodec: codec cmd pending expired!"); | ||
190 | |||
191 | cmd = (u32)PSC_AC97CDC_INDX(addr); | ||
192 | cmd |= PSC_AC97CDC_RD; /* read command */ | ||
193 | au_writel(cmd, PSC_AC97CDC); | ||
194 | au_sync(); | ||
195 | |||
196 | /* now wait for the data | ||
197 | */ | ||
198 | for (i = 0; i < POLL_COUNT; i++) { | ||
199 | val = au_readl(PSC_AC97STAT); | ||
200 | au_sync(); | ||
201 | if (!(val & PSC_AC97STAT_CP)) | ||
202 | break; | ||
203 | } | ||
204 | if (i == POLL_COUNT) { | ||
205 | err("rdcodec: read poll expired!"); | ||
206 | data = 0; | ||
207 | goto out; | ||
208 | } | ||
209 | |||
210 | /* wait for command done? | ||
211 | */ | ||
212 | for (i = 0; i < POLL_COUNT; i++) { | ||
213 | val = au_readl(PSC_AC97EVNT); | ||
214 | au_sync(); | ||
215 | if (val & PSC_AC97EVNT_CD) | ||
216 | break; | ||
217 | } | ||
218 | if (i == POLL_COUNT) { | ||
219 | err("rdcodec: read cmdwait expired!"); | ||
220 | data = 0; | ||
221 | goto out; | ||
222 | } | ||
223 | |||
224 | data = au_readl(PSC_AC97CDC) & 0xffff; | ||
225 | au_sync(); | ||
226 | |||
227 | /* Clear command done event. | ||
228 | */ | ||
229 | au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT); | ||
230 | au_sync(); | ||
231 | |||
232 | out: | ||
233 | spin_unlock_irqrestore(&s->lock, flags); | ||
234 | |||
235 | return data; | ||
236 | } | ||
237 | |||
238 | |||
239 | static void | ||
240 | wrcodec(struct ac97_codec *codec, u8 addr, u16 data) | ||
241 | { | ||
242 | struct au1550_state *s = codec->private_data; | ||
243 | unsigned long flags; | ||
244 | u32 cmd, val; | ||
245 | int i; | ||
246 | |||
247 | spin_lock_irqsave(&s->lock, flags); | ||
248 | |||
249 | for (i = 0; i < POLL_COUNT; i++) { | ||
250 | val = au_readl(PSC_AC97STAT); | ||
251 | au_sync(); | ||
252 | if (!(val & PSC_AC97STAT_CP)) | ||
253 | break; | ||
254 | } | ||
255 | if (i == POLL_COUNT) | ||
256 | err("wrcodec: codec cmd pending expired!"); | ||
257 | |||
258 | cmd = (u32)PSC_AC97CDC_INDX(addr); | ||
259 | cmd |= (u32)data; | ||
260 | au_writel(cmd, PSC_AC97CDC); | ||
261 | au_sync(); | ||
262 | |||
263 | for (i = 0; i < POLL_COUNT; i++) { | ||
264 | val = au_readl(PSC_AC97STAT); | ||
265 | au_sync(); | ||
266 | if (!(val & PSC_AC97STAT_CP)) | ||
267 | break; | ||
268 | } | ||
269 | if (i == POLL_COUNT) | ||
270 | err("wrcodec: codec cmd pending expired!"); | ||
271 | |||
272 | for (i = 0; i < POLL_COUNT; i++) { | ||
273 | val = au_readl(PSC_AC97EVNT); | ||
274 | au_sync(); | ||
275 | if (val & PSC_AC97EVNT_CD) | ||
276 | break; | ||
277 | } | ||
278 | if (i == POLL_COUNT) | ||
279 | err("wrcodec: read cmdwait expired!"); | ||
280 | |||
281 | /* Clear command done event. | ||
282 | */ | ||
283 | au_writel(PSC_AC97EVNT_CD, PSC_AC97EVNT); | ||
284 | au_sync(); | ||
285 | |||
286 | spin_unlock_irqrestore(&s->lock, flags); | ||
287 | } | ||
288 | |||
289 | static void | ||
290 | waitcodec(struct ac97_codec *codec) | ||
291 | { | ||
292 | u16 temp; | ||
293 | u32 val; | ||
294 | int i; | ||
295 | |||
296 | /* codec_wait is used to wait for a ready state after | ||
297 | * an AC97C_RESET. | ||
298 | */ | ||
299 | au1550_delay(10); | ||
300 | |||
301 | /* first poll the CODEC_READY tag bit | ||
302 | */ | ||
303 | for (i = 0; i < POLL_COUNT; i++) { | ||
304 | val = au_readl(PSC_AC97STAT); | ||
305 | au_sync(); | ||
306 | if (val & PSC_AC97STAT_CR) | ||
307 | break; | ||
308 | } | ||
309 | if (i == POLL_COUNT) { | ||
310 | err("waitcodec: CODEC_READY poll expired!"); | ||
311 | return; | ||
312 | } | ||
313 | |||
314 | /* get AC'97 powerdown control/status register | ||
315 | */ | ||
316 | temp = rdcodec(codec, AC97_POWER_CONTROL); | ||
317 | |||
318 | /* If anything is powered down, power'em up | ||
319 | */ | ||
320 | if (temp & 0x7f00) { | ||
321 | /* Power on | ||
322 | */ | ||
323 | wrcodec(codec, AC97_POWER_CONTROL, 0); | ||
324 | au1550_delay(100); | ||
325 | |||
326 | /* Reread | ||
327 | */ | ||
328 | temp = rdcodec(codec, AC97_POWER_CONTROL); | ||
329 | } | ||
330 | |||
331 | /* Check if Codec REF,ANL,DAC,ADC ready | ||
332 | */ | ||
333 | if ((temp & 0x7f0f) != 0x000f) | ||
334 | err("codec reg 26 status (0x%x) not ready!!", temp); | ||
335 | } | ||
336 | |||
337 | /* stop the ADC before calling */ | ||
338 | static void | ||
339 | set_adc_rate(struct au1550_state *s, unsigned rate) | ||
340 | { | ||
341 | struct dmabuf *adc = &s->dma_adc; | ||
342 | struct dmabuf *dac = &s->dma_dac; | ||
343 | unsigned adc_rate, dac_rate; | ||
344 | u16 ac97_extstat; | ||
345 | |||
346 | if (s->no_vra) { | ||
347 | /* calc SRC factor | ||
348 | */ | ||
349 | adc->src_factor = ((96000 / rate) + 1) >> 1; | ||
350 | adc->sample_rate = 48000 / adc->src_factor; | ||
351 | return; | ||
352 | } | ||
353 | |||
354 | adc->src_factor = 1; | ||
355 | |||
356 | ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS); | ||
357 | |||
358 | rate = rate > 48000 ? 48000 : rate; | ||
359 | |||
360 | /* enable VRA | ||
361 | */ | ||
362 | wrcodec(s->codec, AC97_EXTENDED_STATUS, | ||
363 | ac97_extstat | AC97_EXTSTAT_VRA); | ||
364 | |||
365 | /* now write the sample rate | ||
366 | */ | ||
367 | wrcodec(s->codec, AC97_PCM_LR_ADC_RATE, (u16) rate); | ||
368 | |||
369 | /* read it back for actual supported rate | ||
370 | */ | ||
371 | adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE); | ||
372 | |||
373 | pr_debug("set_adc_rate: set to %d Hz\n", adc_rate); | ||
374 | |||
375 | /* some codec's don't allow unequal DAC and ADC rates, in which case | ||
376 | * writing one rate reg actually changes both. | ||
377 | */ | ||
378 | dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE); | ||
379 | if (dac->num_channels > 2) | ||
380 | wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, dac_rate); | ||
381 | if (dac->num_channels > 4) | ||
382 | wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, dac_rate); | ||
383 | |||
384 | adc->sample_rate = adc_rate; | ||
385 | dac->sample_rate = dac_rate; | ||
386 | } | ||
387 | |||
388 | /* stop the DAC before calling */ | ||
389 | static void | ||
390 | set_dac_rate(struct au1550_state *s, unsigned rate) | ||
391 | { | ||
392 | struct dmabuf *dac = &s->dma_dac; | ||
393 | struct dmabuf *adc = &s->dma_adc; | ||
394 | unsigned adc_rate, dac_rate; | ||
395 | u16 ac97_extstat; | ||
396 | |||
397 | if (s->no_vra) { | ||
398 | /* calc SRC factor | ||
399 | */ | ||
400 | dac->src_factor = ((96000 / rate) + 1) >> 1; | ||
401 | dac->sample_rate = 48000 / dac->src_factor; | ||
402 | return; | ||
403 | } | ||
404 | |||
405 | dac->src_factor = 1; | ||
406 | |||
407 | ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS); | ||
408 | |||
409 | rate = rate > 48000 ? 48000 : rate; | ||
410 | |||
411 | /* enable VRA | ||
412 | */ | ||
413 | wrcodec(s->codec, AC97_EXTENDED_STATUS, | ||
414 | ac97_extstat | AC97_EXTSTAT_VRA); | ||
415 | |||
416 | /* now write the sample rate | ||
417 | */ | ||
418 | wrcodec(s->codec, AC97_PCM_FRONT_DAC_RATE, (u16) rate); | ||
419 | |||
420 | /* I don't support different sample rates for multichannel, | ||
421 | * so make these channels the same. | ||
422 | */ | ||
423 | if (dac->num_channels > 2) | ||
424 | wrcodec(s->codec, AC97_PCM_SURR_DAC_RATE, (u16) rate); | ||
425 | if (dac->num_channels > 4) | ||
426 | wrcodec(s->codec, AC97_PCM_LFE_DAC_RATE, (u16) rate); | ||
427 | /* read it back for actual supported rate | ||
428 | */ | ||
429 | dac_rate = rdcodec(s->codec, AC97_PCM_FRONT_DAC_RATE); | ||
430 | |||
431 | pr_debug("set_dac_rate: set to %d Hz\n", dac_rate); | ||
432 | |||
433 | /* some codec's don't allow unequal DAC and ADC rates, in which case | ||
434 | * writing one rate reg actually changes both. | ||
435 | */ | ||
436 | adc_rate = rdcodec(s->codec, AC97_PCM_LR_ADC_RATE); | ||
437 | |||
438 | dac->sample_rate = dac_rate; | ||
439 | adc->sample_rate = adc_rate; | ||
440 | } | ||
441 | |||
442 | static void | ||
443 | stop_dac(struct au1550_state *s) | ||
444 | { | ||
445 | struct dmabuf *db = &s->dma_dac; | ||
446 | u32 stat; | ||
447 | unsigned long flags; | ||
448 | |||
449 | if (db->stopped) | ||
450 | return; | ||
451 | |||
452 | spin_lock_irqsave(&s->lock, flags); | ||
453 | |||
454 | au_writel(PSC_AC97PCR_TP, PSC_AC97PCR); | ||
455 | au_sync(); | ||
456 | |||
457 | /* Wait for Transmit Busy to show disabled. | ||
458 | */ | ||
459 | do { | ||
460 | stat = au_readl(PSC_AC97STAT); | ||
461 | au_sync(); | ||
462 | } while ((stat & PSC_AC97STAT_TB) != 0); | ||
463 | |||
464 | au1xxx_dbdma_reset(db->dmanr); | ||
465 | |||
466 | db->stopped = 1; | ||
467 | |||
468 | spin_unlock_irqrestore(&s->lock, flags); | ||
469 | } | ||
470 | |||
471 | static void | ||
472 | stop_adc(struct au1550_state *s) | ||
473 | { | ||
474 | struct dmabuf *db = &s->dma_adc; | ||
475 | unsigned long flags; | ||
476 | u32 stat; | ||
477 | |||
478 | if (db->stopped) | ||
479 | return; | ||
480 | |||
481 | spin_lock_irqsave(&s->lock, flags); | ||
482 | |||
483 | au_writel(PSC_AC97PCR_RP, PSC_AC97PCR); | ||
484 | au_sync(); | ||
485 | |||
486 | /* Wait for Receive Busy to show disabled. | ||
487 | */ | ||
488 | do { | ||
489 | stat = au_readl(PSC_AC97STAT); | ||
490 | au_sync(); | ||
491 | } while ((stat & PSC_AC97STAT_RB) != 0); | ||
492 | |||
493 | au1xxx_dbdma_reset(db->dmanr); | ||
494 | |||
495 | db->stopped = 1; | ||
496 | |||
497 | spin_unlock_irqrestore(&s->lock, flags); | ||
498 | } | ||
499 | |||
500 | |||
501 | static void | ||
502 | set_xmit_slots(int num_channels) | ||
503 | { | ||
504 | u32 ac97_config, stat; | ||
505 | |||
506 | ac97_config = au_readl(PSC_AC97CFG); | ||
507 | au_sync(); | ||
508 | ac97_config &= ~(PSC_AC97CFG_TXSLOT_MASK | PSC_AC97CFG_DE_ENABLE); | ||
509 | au_writel(ac97_config, PSC_AC97CFG); | ||
510 | au_sync(); | ||
511 | |||
512 | switch (num_channels) { | ||
513 | case 6: /* stereo with surround and center/LFE, | ||
514 | * slots 3,4,6,7,8,9 | ||
515 | */ | ||
516 | ac97_config |= PSC_AC97CFG_TXSLOT_ENA(6); | ||
517 | ac97_config |= PSC_AC97CFG_TXSLOT_ENA(9); | ||
518 | |||
519 | case 4: /* stereo with surround, slots 3,4,7,8 */ | ||
520 | ac97_config |= PSC_AC97CFG_TXSLOT_ENA(7); | ||
521 | ac97_config |= PSC_AC97CFG_TXSLOT_ENA(8); | ||
522 | |||
523 | case 2: /* stereo, slots 3,4 */ | ||
524 | case 1: /* mono */ | ||
525 | ac97_config |= PSC_AC97CFG_TXSLOT_ENA(3); | ||
526 | ac97_config |= PSC_AC97CFG_TXSLOT_ENA(4); | ||
527 | } | ||
528 | |||
529 | au_writel(ac97_config, PSC_AC97CFG); | ||
530 | au_sync(); | ||
531 | |||
532 | ac97_config |= PSC_AC97CFG_DE_ENABLE; | ||
533 | au_writel(ac97_config, PSC_AC97CFG); | ||
534 | au_sync(); | ||
535 | |||
536 | /* Wait for Device ready. | ||
537 | */ | ||
538 | do { | ||
539 | stat = au_readl(PSC_AC97STAT); | ||
540 | au_sync(); | ||
541 | } while ((stat & PSC_AC97STAT_DR) == 0); | ||
542 | } | ||
543 | |||
544 | static void | ||
545 | set_recv_slots(int num_channels) | ||
546 | { | ||
547 | u32 ac97_config, stat; | ||
548 | |||
549 | ac97_config = au_readl(PSC_AC97CFG); | ||
550 | au_sync(); | ||
551 | ac97_config &= ~(PSC_AC97CFG_RXSLOT_MASK | PSC_AC97CFG_DE_ENABLE); | ||
552 | au_writel(ac97_config, PSC_AC97CFG); | ||
553 | au_sync(); | ||
554 | |||
555 | /* Always enable slots 3 and 4 (stereo). Slot 6 is | ||
556 | * optional Mic ADC, which we don't support yet. | ||
557 | */ | ||
558 | ac97_config |= PSC_AC97CFG_RXSLOT_ENA(3); | ||
559 | ac97_config |= PSC_AC97CFG_RXSLOT_ENA(4); | ||
560 | |||
561 | au_writel(ac97_config, PSC_AC97CFG); | ||
562 | au_sync(); | ||
563 | |||
564 | ac97_config |= PSC_AC97CFG_DE_ENABLE; | ||
565 | au_writel(ac97_config, PSC_AC97CFG); | ||
566 | au_sync(); | ||
567 | |||
568 | /* Wait for Device ready. | ||
569 | */ | ||
570 | do { | ||
571 | stat = au_readl(PSC_AC97STAT); | ||
572 | au_sync(); | ||
573 | } while ((stat & PSC_AC97STAT_DR) == 0); | ||
574 | } | ||
575 | |||
576 | /* Hold spinlock for both start_dac() and start_adc() calls */ | ||
577 | static void | ||
578 | start_dac(struct au1550_state *s) | ||
579 | { | ||
580 | struct dmabuf *db = &s->dma_dac; | ||
581 | |||
582 | if (!db->stopped) | ||
583 | return; | ||
584 | |||
585 | set_xmit_slots(db->num_channels); | ||
586 | au_writel(PSC_AC97PCR_TC, PSC_AC97PCR); | ||
587 | au_sync(); | ||
588 | au_writel(PSC_AC97PCR_TS, PSC_AC97PCR); | ||
589 | au_sync(); | ||
590 | |||
591 | au1xxx_dbdma_start(db->dmanr); | ||
592 | |||
593 | db->stopped = 0; | ||
594 | } | ||
595 | |||
596 | static void | ||
597 | start_adc(struct au1550_state *s) | ||
598 | { | ||
599 | struct dmabuf *db = &s->dma_adc; | ||
600 | int i; | ||
601 | |||
602 | if (!db->stopped) | ||
603 | return; | ||
604 | |||
605 | /* Put two buffers on the ring to get things started. | ||
606 | */ | ||
607 | for (i=0; i<2; i++) { | ||
608 | au1xxx_dbdma_put_dest(db->dmanr, virt_to_phys(db->nextIn), | ||
609 | db->dma_fragsize, DDMA_FLAGS_IE); | ||
610 | |||
611 | db->nextIn += db->dma_fragsize; | ||
612 | if (db->nextIn >= db->rawbuf + db->dmasize) | ||
613 | db->nextIn -= db->dmasize; | ||
614 | } | ||
615 | |||
616 | set_recv_slots(db->num_channels); | ||
617 | au1xxx_dbdma_start(db->dmanr); | ||
618 | au_writel(PSC_AC97PCR_RC, PSC_AC97PCR); | ||
619 | au_sync(); | ||
620 | au_writel(PSC_AC97PCR_RS, PSC_AC97PCR); | ||
621 | au_sync(); | ||
622 | |||
623 | db->stopped = 0; | ||
624 | } | ||
625 | |||
626 | static int | ||
627 | prog_dmabuf(struct au1550_state *s, struct dmabuf *db) | ||
628 | { | ||
629 | unsigned user_bytes_per_sec; | ||
630 | unsigned bufs; | ||
631 | unsigned rate = db->sample_rate; | ||
632 | |||
633 | if (!db->rawbuf) { | ||
634 | db->ready = db->mapped = 0; | ||
635 | db->buforder = 5; /* 32 * PAGE_SIZE */ | ||
636 | db->rawbuf = kmalloc((PAGE_SIZE << db->buforder), GFP_KERNEL); | ||
637 | if (!db->rawbuf) | ||
638 | return -ENOMEM; | ||
639 | } | ||
640 | |||
641 | db->cnt_factor = 1; | ||
642 | if (db->sample_size == 8) | ||
643 | db->cnt_factor *= 2; | ||
644 | if (db->num_channels == 1) | ||
645 | db->cnt_factor *= 2; | ||
646 | db->cnt_factor *= db->src_factor; | ||
647 | |||
648 | db->count = 0; | ||
649 | db->dma_qcount = 0; | ||
650 | db->nextIn = db->nextOut = db->rawbuf; | ||
651 | |||
652 | db->user_bytes_per_sample = (db->sample_size>>3) * db->num_channels; | ||
653 | db->dma_bytes_per_sample = 2 * ((db->num_channels == 1) ? | ||
654 | 2 : db->num_channels); | ||
655 | |||
656 | user_bytes_per_sec = rate * db->user_bytes_per_sample; | ||
657 | bufs = PAGE_SIZE << db->buforder; | ||
658 | if (db->ossfragshift) { | ||
659 | if ((1000 << db->ossfragshift) < user_bytes_per_sec) | ||
660 | db->fragshift = ld2(user_bytes_per_sec/1000); | ||
661 | else | ||
662 | db->fragshift = db->ossfragshift; | ||
663 | } else { | ||
664 | db->fragshift = ld2(user_bytes_per_sec / 100 / | ||
665 | (db->subdivision ? db->subdivision : 1)); | ||
666 | if (db->fragshift < 3) | ||
667 | db->fragshift = 3; | ||
668 | } | ||
669 | |||
670 | db->fragsize = 1 << db->fragshift; | ||
671 | db->dma_fragsize = db->fragsize * db->cnt_factor; | ||
672 | db->numfrag = bufs / db->dma_fragsize; | ||
673 | |||
674 | while (db->numfrag < 4 && db->fragshift > 3) { | ||
675 | db->fragshift--; | ||
676 | db->fragsize = 1 << db->fragshift; | ||
677 | db->dma_fragsize = db->fragsize * db->cnt_factor; | ||
678 | db->numfrag = bufs / db->dma_fragsize; | ||
679 | } | ||
680 | |||
681 | if (db->ossmaxfrags >= 4 && db->ossmaxfrags < db->numfrag) | ||
682 | db->numfrag = db->ossmaxfrags; | ||
683 | |||
684 | db->dmasize = db->dma_fragsize * db->numfrag; | ||
685 | memset(db->rawbuf, 0, bufs); | ||
686 | |||
687 | pr_debug("prog_dmabuf: rate=%d, samplesize=%d, channels=%d\n", | ||
688 | rate, db->sample_size, db->num_channels); | ||
689 | pr_debug("prog_dmabuf: fragsize=%d, cnt_factor=%d, dma_fragsize=%d\n", | ||
690 | db->fragsize, db->cnt_factor, db->dma_fragsize); | ||
691 | pr_debug("prog_dmabuf: numfrag=%d, dmasize=%d\n", db->numfrag, db->dmasize); | ||
692 | |||
693 | db->ready = 1; | ||
694 | return 0; | ||
695 | } | ||
696 | |||
697 | static int | ||
698 | prog_dmabuf_adc(struct au1550_state *s) | ||
699 | { | ||
700 | stop_adc(s); | ||
701 | return prog_dmabuf(s, &s->dma_adc); | ||
702 | |||
703 | } | ||
704 | |||
705 | static int | ||
706 | prog_dmabuf_dac(struct au1550_state *s) | ||
707 | { | ||
708 | stop_dac(s); | ||
709 | return prog_dmabuf(s, &s->dma_dac); | ||
710 | } | ||
711 | |||
712 | |||
713 | static void dac_dma_interrupt(int irq, void *dev_id) | ||
714 | { | ||
715 | struct au1550_state *s = (struct au1550_state *) dev_id; | ||
716 | struct dmabuf *db = &s->dma_dac; | ||
717 | u32 ac97c_stat; | ||
718 | |||
719 | spin_lock(&s->lock); | ||
720 | |||
721 | ac97c_stat = au_readl(PSC_AC97STAT); | ||
722 | if (ac97c_stat & (AC97C_XU | AC97C_XO | AC97C_TE)) | ||
723 | pr_debug("AC97C status = 0x%08x\n", ac97c_stat); | ||
724 | db->dma_qcount--; | ||
725 | |||
726 | if (db->count >= db->fragsize) { | ||
727 | if (au1xxx_dbdma_put_source(db->dmanr, | ||
728 | virt_to_phys(db->nextOut), db->fragsize, | ||
729 | DDMA_FLAGS_IE) == 0) { | ||
730 | err("qcount < 2 and no ring room!"); | ||
731 | } | ||
732 | db->nextOut += db->fragsize; | ||
733 | if (db->nextOut >= db->rawbuf + db->dmasize) | ||
734 | db->nextOut -= db->dmasize; | ||
735 | db->count -= db->fragsize; | ||
736 | db->total_bytes += db->dma_fragsize; | ||
737 | db->dma_qcount++; | ||
738 | } | ||
739 | |||
740 | /* wake up anybody listening */ | ||
741 | if (waitqueue_active(&db->wait)) | ||
742 | wake_up(&db->wait); | ||
743 | |||
744 | spin_unlock(&s->lock); | ||
745 | } | ||
746 | |||
747 | |||
748 | static void adc_dma_interrupt(int irq, void *dev_id) | ||
749 | { | ||
750 | struct au1550_state *s = (struct au1550_state *)dev_id; | ||
751 | struct dmabuf *dp = &s->dma_adc; | ||
752 | u32 obytes; | ||
753 | char *obuf; | ||
754 | |||
755 | spin_lock(&s->lock); | ||
756 | |||
757 | /* Pull the buffer from the dma queue. | ||
758 | */ | ||
759 | au1xxx_dbdma_get_dest(dp->dmanr, (void *)(&obuf), &obytes); | ||
760 | |||
761 | if ((dp->count + obytes) > dp->dmasize) { | ||
762 | /* Overrun. Stop ADC and log the error | ||
763 | */ | ||
764 | spin_unlock(&s->lock); | ||
765 | stop_adc(s); | ||
766 | dp->error++; | ||
767 | err("adc overrun"); | ||
768 | return; | ||
769 | } | ||
770 | |||
771 | /* Put a new empty buffer on the destination DMA. | ||
772 | */ | ||
773 | au1xxx_dbdma_put_dest(dp->dmanr, virt_to_phys(dp->nextIn), | ||
774 | dp->dma_fragsize, DDMA_FLAGS_IE); | ||
775 | |||
776 | dp->nextIn += dp->dma_fragsize; | ||
777 | if (dp->nextIn >= dp->rawbuf + dp->dmasize) | ||
778 | dp->nextIn -= dp->dmasize; | ||
779 | |||
780 | dp->count += obytes; | ||
781 | dp->total_bytes += obytes; | ||
782 | |||
783 | /* wake up anybody listening | ||
784 | */ | ||
785 | if (waitqueue_active(&dp->wait)) | ||
786 | wake_up(&dp->wait); | ||
787 | |||
788 | spin_unlock(&s->lock); | ||
789 | } | ||
790 | |||
791 | static loff_t | ||
792 | au1550_llseek(struct file *file, loff_t offset, int origin) | ||
793 | { | ||
794 | return -ESPIPE; | ||
795 | } | ||
796 | |||
797 | |||
798 | static int | ||
799 | au1550_open_mixdev(struct inode *inode, struct file *file) | ||
800 | { | ||
801 | mutex_lock(&au1550_ac97_mutex); | ||
802 | file->private_data = &au1550_state; | ||
803 | mutex_unlock(&au1550_ac97_mutex); | ||
804 | return 0; | ||
805 | } | ||
806 | |||
807 | static int | ||
808 | au1550_release_mixdev(struct inode *inode, struct file *file) | ||
809 | { | ||
810 | return 0; | ||
811 | } | ||
812 | |||
813 | static int | ||
814 | mixdev_ioctl(struct ac97_codec *codec, unsigned int cmd, | ||
815 | unsigned long arg) | ||
816 | { | ||
817 | return codec->mixer_ioctl(codec, cmd, arg); | ||
818 | } | ||
819 | |||
820 | static long | ||
821 | au1550_ioctl_mixdev(struct file *file, unsigned int cmd, unsigned long arg) | ||
822 | { | ||
823 | struct au1550_state *s = file->private_data; | ||
824 | struct ac97_codec *codec = s->codec; | ||
825 | int ret; | ||
826 | |||
827 | mutex_lock(&au1550_ac97_mutex); | ||
828 | ret = mixdev_ioctl(codec, cmd, arg); | ||
829 | mutex_unlock(&au1550_ac97_mutex); | ||
830 | |||
831 | return ret; | ||
832 | } | ||
833 | |||
834 | static /*const */ struct file_operations au1550_mixer_fops = { | ||
835 | .owner = THIS_MODULE, | ||
836 | .llseek = au1550_llseek, | ||
837 | .unlocked_ioctl = au1550_ioctl_mixdev, | ||
838 | .open = au1550_open_mixdev, | ||
839 | .release = au1550_release_mixdev, | ||
840 | }; | ||
841 | |||
842 | static int | ||
843 | drain_dac(struct au1550_state *s, int nonblock) | ||
844 | { | ||
845 | unsigned long flags; | ||
846 | int count, tmo; | ||
847 | |||
848 | if (s->dma_dac.mapped || !s->dma_dac.ready || s->dma_dac.stopped) | ||
849 | return 0; | ||
850 | |||
851 | for (;;) { | ||
852 | spin_lock_irqsave(&s->lock, flags); | ||
853 | count = s->dma_dac.count; | ||
854 | spin_unlock_irqrestore(&s->lock, flags); | ||
855 | if (count <= s->dma_dac.fragsize) | ||
856 | break; | ||
857 | if (signal_pending(current)) | ||
858 | break; | ||
859 | if (nonblock) | ||
860 | return -EBUSY; | ||
861 | tmo = 1000 * count / (s->no_vra ? | ||
862 | 48000 : s->dma_dac.sample_rate); | ||
863 | tmo /= s->dma_dac.dma_bytes_per_sample; | ||
864 | au1550_delay(tmo); | ||
865 | } | ||
866 | if (signal_pending(current)) | ||
867 | return -ERESTARTSYS; | ||
868 | return 0; | ||
869 | } | ||
870 | |||
871 | static inline u8 S16_TO_U8(s16 ch) | ||
872 | { | ||
873 | return (u8) (ch >> 8) + 0x80; | ||
874 | } | ||
875 | static inline s16 U8_TO_S16(u8 ch) | ||
876 | { | ||
877 | return (s16) (ch - 0x80) << 8; | ||
878 | } | ||
879 | |||
880 | /* | ||
881 | * Translates user samples to dma buffer suitable for AC'97 DAC data: | ||
882 | * If mono, copy left channel to right channel in dma buffer. | ||
883 | * If 8 bit samples, cvt to 16-bit before writing to dma buffer. | ||
884 | * If interpolating (no VRA), duplicate every audio frame src_factor times. | ||
885 | */ | ||
886 | static int | ||
887 | translate_from_user(struct dmabuf *db, char* dmabuf, char* userbuf, | ||
888 | int dmacount) | ||
889 | { | ||
890 | int sample, i; | ||
891 | int interp_bytes_per_sample; | ||
892 | int num_samples; | ||
893 | int mono = (db->num_channels == 1); | ||
894 | char usersample[12]; | ||
895 | s16 ch, dmasample[6]; | ||
896 | |||
897 | if (db->sample_size == 16 && !mono && db->src_factor == 1) { | ||
898 | /* no translation necessary, just copy | ||
899 | */ | ||
900 | if (copy_from_user(dmabuf, userbuf, dmacount)) | ||
901 | return -EFAULT; | ||
902 | return dmacount; | ||
903 | } | ||
904 | |||
905 | interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor; | ||
906 | num_samples = dmacount / interp_bytes_per_sample; | ||
907 | |||
908 | for (sample = 0; sample < num_samples; sample++) { | ||
909 | if (copy_from_user(usersample, userbuf, | ||
910 | db->user_bytes_per_sample)) { | ||
911 | return -EFAULT; | ||
912 | } | ||
913 | |||
914 | for (i = 0; i < db->num_channels; i++) { | ||
915 | if (db->sample_size == 8) | ||
916 | ch = U8_TO_S16(usersample[i]); | ||
917 | else | ||
918 | ch = *((s16 *) (&usersample[i * 2])); | ||
919 | dmasample[i] = ch; | ||
920 | if (mono) | ||
921 | dmasample[i + 1] = ch; /* right channel */ | ||
922 | } | ||
923 | |||
924 | /* duplicate every audio frame src_factor times | ||
925 | */ | ||
926 | for (i = 0; i < db->src_factor; i++) | ||
927 | memcpy(dmabuf, dmasample, db->dma_bytes_per_sample); | ||
928 | |||
929 | userbuf += db->user_bytes_per_sample; | ||
930 | dmabuf += interp_bytes_per_sample; | ||
931 | } | ||
932 | |||
933 | return num_samples * interp_bytes_per_sample; | ||
934 | } | ||
935 | |||
936 | /* | ||
937 | * Translates AC'97 ADC samples to user buffer: | ||
938 | * If mono, send only left channel to user buffer. | ||
939 | * If 8 bit samples, cvt from 16 to 8 bit before writing to user buffer. | ||
940 | * If decimating (no VRA), skip over src_factor audio frames. | ||
941 | */ | ||
942 | static int | ||
943 | translate_to_user(struct dmabuf *db, char* userbuf, char* dmabuf, | ||
944 | int dmacount) | ||
945 | { | ||
946 | int sample, i; | ||
947 | int interp_bytes_per_sample; | ||
948 | int num_samples; | ||
949 | int mono = (db->num_channels == 1); | ||
950 | char usersample[12]; | ||
951 | |||
952 | if (db->sample_size == 16 && !mono && db->src_factor == 1) { | ||
953 | /* no translation necessary, just copy | ||
954 | */ | ||
955 | if (copy_to_user(userbuf, dmabuf, dmacount)) | ||
956 | return -EFAULT; | ||
957 | return dmacount; | ||
958 | } | ||
959 | |||
960 | interp_bytes_per_sample = db->dma_bytes_per_sample * db->src_factor; | ||
961 | num_samples = dmacount / interp_bytes_per_sample; | ||
962 | |||
963 | for (sample = 0; sample < num_samples; sample++) { | ||
964 | for (i = 0; i < db->num_channels; i++) { | ||
965 | if (db->sample_size == 8) | ||
966 | usersample[i] = | ||
967 | S16_TO_U8(*((s16 *) (&dmabuf[i * 2]))); | ||
968 | else | ||
969 | *((s16 *) (&usersample[i * 2])) = | ||
970 | *((s16 *) (&dmabuf[i * 2])); | ||
971 | } | ||
972 | |||
973 | if (copy_to_user(userbuf, usersample, | ||
974 | db->user_bytes_per_sample)) { | ||
975 | return -EFAULT; | ||
976 | } | ||
977 | |||
978 | userbuf += db->user_bytes_per_sample; | ||
979 | dmabuf += interp_bytes_per_sample; | ||
980 | } | ||
981 | |||
982 | return num_samples * interp_bytes_per_sample; | ||
983 | } | ||
984 | |||
985 | /* | ||
986 | * Copy audio data to/from user buffer from/to dma buffer, taking care | ||
987 | * that we wrap when reading/writing the dma buffer. Returns actual byte | ||
988 | * count written to or read from the dma buffer. | ||
989 | */ | ||
990 | static int | ||
991 | copy_dmabuf_user(struct dmabuf *db, char* userbuf, int count, int to_user) | ||
992 | { | ||
993 | char *bufptr = to_user ? db->nextOut : db->nextIn; | ||
994 | char *bufend = db->rawbuf + db->dmasize; | ||
995 | int cnt, ret; | ||
996 | |||
997 | if (bufptr + count > bufend) { | ||
998 | int partial = (int) (bufend - bufptr); | ||
999 | if (to_user) { | ||
1000 | if ((cnt = translate_to_user(db, userbuf, | ||
1001 | bufptr, partial)) < 0) | ||
1002 | return cnt; | ||
1003 | ret = cnt; | ||
1004 | if ((cnt = translate_to_user(db, userbuf + partial, | ||
1005 | db->rawbuf, | ||
1006 | count - partial)) < 0) | ||
1007 | return cnt; | ||
1008 | ret += cnt; | ||
1009 | } else { | ||
1010 | if ((cnt = translate_from_user(db, bufptr, userbuf, | ||
1011 | partial)) < 0) | ||
1012 | return cnt; | ||
1013 | ret = cnt; | ||
1014 | if ((cnt = translate_from_user(db, db->rawbuf, | ||
1015 | userbuf + partial, | ||
1016 | count - partial)) < 0) | ||
1017 | return cnt; | ||
1018 | ret += cnt; | ||
1019 | } | ||
1020 | } else { | ||
1021 | if (to_user) | ||
1022 | ret = translate_to_user(db, userbuf, bufptr, count); | ||
1023 | else | ||
1024 | ret = translate_from_user(db, bufptr, userbuf, count); | ||
1025 | } | ||
1026 | |||
1027 | return ret; | ||
1028 | } | ||
1029 | |||
1030 | |||
1031 | static ssize_t | ||
1032 | au1550_read(struct file *file, char *buffer, size_t count, loff_t *ppos) | ||
1033 | { | ||
1034 | struct au1550_state *s = file->private_data; | ||
1035 | struct dmabuf *db = &s->dma_adc; | ||
1036 | DECLARE_WAITQUEUE(wait, current); | ||
1037 | ssize_t ret; | ||
1038 | unsigned long flags; | ||
1039 | int cnt, usercnt, avail; | ||
1040 | |||
1041 | if (db->mapped) | ||
1042 | return -ENXIO; | ||
1043 | if (!access_ok(VERIFY_WRITE, buffer, count)) | ||
1044 | return -EFAULT; | ||
1045 | ret = 0; | ||
1046 | |||
1047 | count *= db->cnt_factor; | ||
1048 | |||
1049 | mutex_lock(&s->sem); | ||
1050 | add_wait_queue(&db->wait, &wait); | ||
1051 | |||
1052 | while (count > 0) { | ||
1053 | /* wait for samples in ADC dma buffer | ||
1054 | */ | ||
1055 | do { | ||
1056 | spin_lock_irqsave(&s->lock, flags); | ||
1057 | if (db->stopped) | ||
1058 | start_adc(s); | ||
1059 | avail = db->count; | ||
1060 | if (avail <= 0) | ||
1061 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1062 | spin_unlock_irqrestore(&s->lock, flags); | ||
1063 | if (avail <= 0) { | ||
1064 | if (file->f_flags & O_NONBLOCK) { | ||
1065 | if (!ret) | ||
1066 | ret = -EAGAIN; | ||
1067 | goto out; | ||
1068 | } | ||
1069 | mutex_unlock(&s->sem); | ||
1070 | schedule(); | ||
1071 | if (signal_pending(current)) { | ||
1072 | if (!ret) | ||
1073 | ret = -ERESTARTSYS; | ||
1074 | goto out2; | ||
1075 | } | ||
1076 | mutex_lock(&s->sem); | ||
1077 | } | ||
1078 | } while (avail <= 0); | ||
1079 | |||
1080 | /* copy from nextOut to user | ||
1081 | */ | ||
1082 | if ((cnt = copy_dmabuf_user(db, buffer, | ||
1083 | count > avail ? | ||
1084 | avail : count, 1)) < 0) { | ||
1085 | if (!ret) | ||
1086 | ret = -EFAULT; | ||
1087 | goto out; | ||
1088 | } | ||
1089 | |||
1090 | spin_lock_irqsave(&s->lock, flags); | ||
1091 | db->count -= cnt; | ||
1092 | db->nextOut += cnt; | ||
1093 | if (db->nextOut >= db->rawbuf + db->dmasize) | ||
1094 | db->nextOut -= db->dmasize; | ||
1095 | spin_unlock_irqrestore(&s->lock, flags); | ||
1096 | |||
1097 | count -= cnt; | ||
1098 | usercnt = cnt / db->cnt_factor; | ||
1099 | buffer += usercnt; | ||
1100 | ret += usercnt; | ||
1101 | } /* while (count > 0) */ | ||
1102 | |||
1103 | out: | ||
1104 | mutex_unlock(&s->sem); | ||
1105 | out2: | ||
1106 | remove_wait_queue(&db->wait, &wait); | ||
1107 | set_current_state(TASK_RUNNING); | ||
1108 | return ret; | ||
1109 | } | ||
1110 | |||
1111 | static ssize_t | ||
1112 | au1550_write(struct file *file, const char *buffer, size_t count, loff_t * ppos) | ||
1113 | { | ||
1114 | struct au1550_state *s = file->private_data; | ||
1115 | struct dmabuf *db = &s->dma_dac; | ||
1116 | DECLARE_WAITQUEUE(wait, current); | ||
1117 | ssize_t ret = 0; | ||
1118 | unsigned long flags; | ||
1119 | int cnt, usercnt, avail; | ||
1120 | |||
1121 | pr_debug("write: count=%d\n", count); | ||
1122 | |||
1123 | if (db->mapped) | ||
1124 | return -ENXIO; | ||
1125 | if (!access_ok(VERIFY_READ, buffer, count)) | ||
1126 | return -EFAULT; | ||
1127 | |||
1128 | count *= db->cnt_factor; | ||
1129 | |||
1130 | mutex_lock(&s->sem); | ||
1131 | add_wait_queue(&db->wait, &wait); | ||
1132 | |||
1133 | while (count > 0) { | ||
1134 | /* wait for space in playback buffer | ||
1135 | */ | ||
1136 | do { | ||
1137 | spin_lock_irqsave(&s->lock, flags); | ||
1138 | avail = (int) db->dmasize - db->count; | ||
1139 | if (avail <= 0) | ||
1140 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1141 | spin_unlock_irqrestore(&s->lock, flags); | ||
1142 | if (avail <= 0) { | ||
1143 | if (file->f_flags & O_NONBLOCK) { | ||
1144 | if (!ret) | ||
1145 | ret = -EAGAIN; | ||
1146 | goto out; | ||
1147 | } | ||
1148 | mutex_unlock(&s->sem); | ||
1149 | schedule(); | ||
1150 | if (signal_pending(current)) { | ||
1151 | if (!ret) | ||
1152 | ret = -ERESTARTSYS; | ||
1153 | goto out2; | ||
1154 | } | ||
1155 | mutex_lock(&s->sem); | ||
1156 | } | ||
1157 | } while (avail <= 0); | ||
1158 | |||
1159 | /* copy from user to nextIn | ||
1160 | */ | ||
1161 | if ((cnt = copy_dmabuf_user(db, (char *) buffer, | ||
1162 | count > avail ? | ||
1163 | avail : count, 0)) < 0) { | ||
1164 | if (!ret) | ||
1165 | ret = -EFAULT; | ||
1166 | goto out; | ||
1167 | } | ||
1168 | |||
1169 | spin_lock_irqsave(&s->lock, flags); | ||
1170 | db->count += cnt; | ||
1171 | db->nextIn += cnt; | ||
1172 | if (db->nextIn >= db->rawbuf + db->dmasize) | ||
1173 | db->nextIn -= db->dmasize; | ||
1174 | |||
1175 | /* If the data is available, we want to keep two buffers | ||
1176 | * on the dma queue. If the queue count reaches zero, | ||
1177 | * we know the dma has stopped. | ||
1178 | */ | ||
1179 | while ((db->dma_qcount < 2) && (db->count >= db->fragsize)) { | ||
1180 | if (au1xxx_dbdma_put_source(db->dmanr, | ||
1181 | virt_to_phys(db->nextOut), db->fragsize, | ||
1182 | DDMA_FLAGS_IE) == 0) { | ||
1183 | err("qcount < 2 and no ring room!"); | ||
1184 | } | ||
1185 | db->nextOut += db->fragsize; | ||
1186 | if (db->nextOut >= db->rawbuf + db->dmasize) | ||
1187 | db->nextOut -= db->dmasize; | ||
1188 | db->total_bytes += db->dma_fragsize; | ||
1189 | if (db->dma_qcount == 0) | ||
1190 | start_dac(s); | ||
1191 | db->dma_qcount++; | ||
1192 | } | ||
1193 | spin_unlock_irqrestore(&s->lock, flags); | ||
1194 | |||
1195 | count -= cnt; | ||
1196 | usercnt = cnt / db->cnt_factor; | ||
1197 | buffer += usercnt; | ||
1198 | ret += usercnt; | ||
1199 | } /* while (count > 0) */ | ||
1200 | |||
1201 | out: | ||
1202 | mutex_unlock(&s->sem); | ||
1203 | out2: | ||
1204 | remove_wait_queue(&db->wait, &wait); | ||
1205 | set_current_state(TASK_RUNNING); | ||
1206 | return ret; | ||
1207 | } | ||
1208 | |||
1209 | |||
1210 | /* No kernel lock - we have our own spinlock */ | ||
1211 | static unsigned int | ||
1212 | au1550_poll(struct file *file, struct poll_table_struct *wait) | ||
1213 | { | ||
1214 | struct au1550_state *s = file->private_data; | ||
1215 | unsigned long flags; | ||
1216 | unsigned int mask = 0; | ||
1217 | |||
1218 | if (file->f_mode & FMODE_WRITE) { | ||
1219 | if (!s->dma_dac.ready) | ||
1220 | return 0; | ||
1221 | poll_wait(file, &s->dma_dac.wait, wait); | ||
1222 | } | ||
1223 | if (file->f_mode & FMODE_READ) { | ||
1224 | if (!s->dma_adc.ready) | ||
1225 | return 0; | ||
1226 | poll_wait(file, &s->dma_adc.wait, wait); | ||
1227 | } | ||
1228 | |||
1229 | spin_lock_irqsave(&s->lock, flags); | ||
1230 | |||
1231 | if (file->f_mode & FMODE_READ) { | ||
1232 | if (s->dma_adc.count >= (signed)s->dma_adc.dma_fragsize) | ||
1233 | mask |= POLLIN | POLLRDNORM; | ||
1234 | } | ||
1235 | if (file->f_mode & FMODE_WRITE) { | ||
1236 | if (s->dma_dac.mapped) { | ||
1237 | if (s->dma_dac.count >= | ||
1238 | (signed)s->dma_dac.dma_fragsize) | ||
1239 | mask |= POLLOUT | POLLWRNORM; | ||
1240 | } else { | ||
1241 | if ((signed) s->dma_dac.dmasize >= | ||
1242 | s->dma_dac.count + (signed)s->dma_dac.dma_fragsize) | ||
1243 | mask |= POLLOUT | POLLWRNORM; | ||
1244 | } | ||
1245 | } | ||
1246 | spin_unlock_irqrestore(&s->lock, flags); | ||
1247 | return mask; | ||
1248 | } | ||
1249 | |||
1250 | static int | ||
1251 | au1550_mmap(struct file *file, struct vm_area_struct *vma) | ||
1252 | { | ||
1253 | struct au1550_state *s = file->private_data; | ||
1254 | struct dmabuf *db; | ||
1255 | unsigned long size; | ||
1256 | int ret = 0; | ||
1257 | |||
1258 | mutex_lock(&au1550_ac97_mutex); | ||
1259 | mutex_lock(&s->sem); | ||
1260 | if (vma->vm_flags & VM_WRITE) | ||
1261 | db = &s->dma_dac; | ||
1262 | else if (vma->vm_flags & VM_READ) | ||
1263 | db = &s->dma_adc; | ||
1264 | else { | ||
1265 | ret = -EINVAL; | ||
1266 | goto out; | ||
1267 | } | ||
1268 | if (vma->vm_pgoff != 0) { | ||
1269 | ret = -EINVAL; | ||
1270 | goto out; | ||
1271 | } | ||
1272 | size = vma->vm_end - vma->vm_start; | ||
1273 | if (size > (PAGE_SIZE << db->buforder)) { | ||
1274 | ret = -EINVAL; | ||
1275 | goto out; | ||
1276 | } | ||
1277 | if (remap_pfn_range(vma, vma->vm_start, page_to_pfn(virt_to_page(db->rawbuf)), | ||
1278 | size, vma->vm_page_prot)) { | ||
1279 | ret = -EAGAIN; | ||
1280 | goto out; | ||
1281 | } | ||
1282 | vma->vm_flags &= ~VM_IO; | ||
1283 | db->mapped = 1; | ||
1284 | out: | ||
1285 | mutex_unlock(&s->sem); | ||
1286 | mutex_unlock(&au1550_ac97_mutex); | ||
1287 | return ret; | ||
1288 | } | ||
1289 | |||
1290 | #ifdef DEBUG | ||
1291 | static struct ioctl_str_t { | ||
1292 | unsigned int cmd; | ||
1293 | const char *str; | ||
1294 | } ioctl_str[] = { | ||
1295 | {SNDCTL_DSP_RESET, "SNDCTL_DSP_RESET"}, | ||
1296 | {SNDCTL_DSP_SYNC, "SNDCTL_DSP_SYNC"}, | ||
1297 | {SNDCTL_DSP_SPEED, "SNDCTL_DSP_SPEED"}, | ||
1298 | {SNDCTL_DSP_STEREO, "SNDCTL_DSP_STEREO"}, | ||
1299 | {SNDCTL_DSP_GETBLKSIZE, "SNDCTL_DSP_GETBLKSIZE"}, | ||
1300 | {SNDCTL_DSP_SAMPLESIZE, "SNDCTL_DSP_SAMPLESIZE"}, | ||
1301 | {SNDCTL_DSP_CHANNELS, "SNDCTL_DSP_CHANNELS"}, | ||
1302 | {SOUND_PCM_WRITE_CHANNELS, "SOUND_PCM_WRITE_CHANNELS"}, | ||
1303 | {SOUND_PCM_WRITE_FILTER, "SOUND_PCM_WRITE_FILTER"}, | ||
1304 | {SNDCTL_DSP_POST, "SNDCTL_DSP_POST"}, | ||
1305 | {SNDCTL_DSP_SUBDIVIDE, "SNDCTL_DSP_SUBDIVIDE"}, | ||
1306 | {SNDCTL_DSP_SETFRAGMENT, "SNDCTL_DSP_SETFRAGMENT"}, | ||
1307 | {SNDCTL_DSP_GETFMTS, "SNDCTL_DSP_GETFMTS"}, | ||
1308 | {SNDCTL_DSP_SETFMT, "SNDCTL_DSP_SETFMT"}, | ||
1309 | {SNDCTL_DSP_GETOSPACE, "SNDCTL_DSP_GETOSPACE"}, | ||
1310 | {SNDCTL_DSP_GETISPACE, "SNDCTL_DSP_GETISPACE"}, | ||
1311 | {SNDCTL_DSP_NONBLOCK, "SNDCTL_DSP_NONBLOCK"}, | ||
1312 | {SNDCTL_DSP_GETCAPS, "SNDCTL_DSP_GETCAPS"}, | ||
1313 | {SNDCTL_DSP_GETTRIGGER, "SNDCTL_DSP_GETTRIGGER"}, | ||
1314 | {SNDCTL_DSP_SETTRIGGER, "SNDCTL_DSP_SETTRIGGER"}, | ||
1315 | {SNDCTL_DSP_GETIPTR, "SNDCTL_DSP_GETIPTR"}, | ||
1316 | {SNDCTL_DSP_GETOPTR, "SNDCTL_DSP_GETOPTR"}, | ||
1317 | {SNDCTL_DSP_MAPINBUF, "SNDCTL_DSP_MAPINBUF"}, | ||
1318 | {SNDCTL_DSP_MAPOUTBUF, "SNDCTL_DSP_MAPOUTBUF"}, | ||
1319 | {SNDCTL_DSP_SETSYNCRO, "SNDCTL_DSP_SETSYNCRO"}, | ||
1320 | {SNDCTL_DSP_SETDUPLEX, "SNDCTL_DSP_SETDUPLEX"}, | ||
1321 | {SNDCTL_DSP_GETODELAY, "SNDCTL_DSP_GETODELAY"}, | ||
1322 | {SNDCTL_DSP_GETCHANNELMASK, "SNDCTL_DSP_GETCHANNELMASK"}, | ||
1323 | {SNDCTL_DSP_BIND_CHANNEL, "SNDCTL_DSP_BIND_CHANNEL"}, | ||
1324 | {OSS_GETVERSION, "OSS_GETVERSION"}, | ||
1325 | {SOUND_PCM_READ_RATE, "SOUND_PCM_READ_RATE"}, | ||
1326 | {SOUND_PCM_READ_CHANNELS, "SOUND_PCM_READ_CHANNELS"}, | ||
1327 | {SOUND_PCM_READ_BITS, "SOUND_PCM_READ_BITS"}, | ||
1328 | {SOUND_PCM_READ_FILTER, "SOUND_PCM_READ_FILTER"} | ||
1329 | }; | ||
1330 | #endif | ||
1331 | |||
1332 | static int | ||
1333 | dma_count_done(struct dmabuf *db) | ||
1334 | { | ||
1335 | if (db->stopped) | ||
1336 | return 0; | ||
1337 | |||
1338 | return db->dma_fragsize - au1xxx_get_dma_residue(db->dmanr); | ||
1339 | } | ||
1340 | |||
1341 | |||
1342 | static int | ||
1343 | au1550_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
1344 | { | ||
1345 | struct au1550_state *s = file->private_data; | ||
1346 | unsigned long flags; | ||
1347 | audio_buf_info abinfo; | ||
1348 | count_info cinfo; | ||
1349 | int count; | ||
1350 | int val, mapped, ret, diff; | ||
1351 | |||
1352 | mapped = ((file->f_mode & FMODE_WRITE) && s->dma_dac.mapped) || | ||
1353 | ((file->f_mode & FMODE_READ) && s->dma_adc.mapped); | ||
1354 | |||
1355 | #ifdef DEBUG | ||
1356 | for (count = 0; count < ARRAY_SIZE(ioctl_str); count++) { | ||
1357 | if (ioctl_str[count].cmd == cmd) | ||
1358 | break; | ||
1359 | } | ||
1360 | if (count < ARRAY_SIZE(ioctl_str)) | ||
1361 | pr_debug("ioctl %s, arg=0x%lxn", ioctl_str[count].str, arg); | ||
1362 | else | ||
1363 | pr_debug("ioctl 0x%x unknown, arg=0x%lx\n", cmd, arg); | ||
1364 | #endif | ||
1365 | |||
1366 | switch (cmd) { | ||
1367 | case OSS_GETVERSION: | ||
1368 | return put_user(SOUND_VERSION, (int *) arg); | ||
1369 | |||
1370 | case SNDCTL_DSP_SYNC: | ||
1371 | if (file->f_mode & FMODE_WRITE) | ||
1372 | return drain_dac(s, file->f_flags & O_NONBLOCK); | ||
1373 | return 0; | ||
1374 | |||
1375 | case SNDCTL_DSP_SETDUPLEX: | ||
1376 | return 0; | ||
1377 | |||
1378 | case SNDCTL_DSP_GETCAPS: | ||
1379 | return put_user(DSP_CAP_DUPLEX | DSP_CAP_REALTIME | | ||
1380 | DSP_CAP_TRIGGER | DSP_CAP_MMAP, (int *)arg); | ||
1381 | |||
1382 | case SNDCTL_DSP_RESET: | ||
1383 | if (file->f_mode & FMODE_WRITE) { | ||
1384 | stop_dac(s); | ||
1385 | synchronize_irq(); | ||
1386 | s->dma_dac.count = s->dma_dac.total_bytes = 0; | ||
1387 | s->dma_dac.nextIn = s->dma_dac.nextOut = | ||
1388 | s->dma_dac.rawbuf; | ||
1389 | } | ||
1390 | if (file->f_mode & FMODE_READ) { | ||
1391 | stop_adc(s); | ||
1392 | synchronize_irq(); | ||
1393 | s->dma_adc.count = s->dma_adc.total_bytes = 0; | ||
1394 | s->dma_adc.nextIn = s->dma_adc.nextOut = | ||
1395 | s->dma_adc.rawbuf; | ||
1396 | } | ||
1397 | return 0; | ||
1398 | |||
1399 | case SNDCTL_DSP_SPEED: | ||
1400 | if (get_user(val, (int *) arg)) | ||
1401 | return -EFAULT; | ||
1402 | if (val >= 0) { | ||
1403 | if (file->f_mode & FMODE_READ) { | ||
1404 | stop_adc(s); | ||
1405 | set_adc_rate(s, val); | ||
1406 | } | ||
1407 | if (file->f_mode & FMODE_WRITE) { | ||
1408 | stop_dac(s); | ||
1409 | set_dac_rate(s, val); | ||
1410 | } | ||
1411 | if (s->open_mode & FMODE_READ) | ||
1412 | if ((ret = prog_dmabuf_adc(s))) | ||
1413 | return ret; | ||
1414 | if (s->open_mode & FMODE_WRITE) | ||
1415 | if ((ret = prog_dmabuf_dac(s))) | ||
1416 | return ret; | ||
1417 | } | ||
1418 | return put_user((file->f_mode & FMODE_READ) ? | ||
1419 | s->dma_adc.sample_rate : | ||
1420 | s->dma_dac.sample_rate, | ||
1421 | (int *)arg); | ||
1422 | |||
1423 | case SNDCTL_DSP_STEREO: | ||
1424 | if (get_user(val, (int *) arg)) | ||
1425 | return -EFAULT; | ||
1426 | if (file->f_mode & FMODE_READ) { | ||
1427 | stop_adc(s); | ||
1428 | s->dma_adc.num_channels = val ? 2 : 1; | ||
1429 | if ((ret = prog_dmabuf_adc(s))) | ||
1430 | return ret; | ||
1431 | } | ||
1432 | if (file->f_mode & FMODE_WRITE) { | ||
1433 | stop_dac(s); | ||
1434 | s->dma_dac.num_channels = val ? 2 : 1; | ||
1435 | if (s->codec_ext_caps & AC97_EXT_DACS) { | ||
1436 | /* disable surround and center/lfe in AC'97 | ||
1437 | */ | ||
1438 | u16 ext_stat = rdcodec(s->codec, | ||
1439 | AC97_EXTENDED_STATUS); | ||
1440 | wrcodec(s->codec, AC97_EXTENDED_STATUS, | ||
1441 | ext_stat | (AC97_EXTSTAT_PRI | | ||
1442 | AC97_EXTSTAT_PRJ | | ||
1443 | AC97_EXTSTAT_PRK)); | ||
1444 | } | ||
1445 | if ((ret = prog_dmabuf_dac(s))) | ||
1446 | return ret; | ||
1447 | } | ||
1448 | return 0; | ||
1449 | |||
1450 | case SNDCTL_DSP_CHANNELS: | ||
1451 | if (get_user(val, (int *) arg)) | ||
1452 | return -EFAULT; | ||
1453 | if (val != 0) { | ||
1454 | if (file->f_mode & FMODE_READ) { | ||
1455 | if (val < 0 || val > 2) | ||
1456 | return -EINVAL; | ||
1457 | stop_adc(s); | ||
1458 | s->dma_adc.num_channels = val; | ||
1459 | if ((ret = prog_dmabuf_adc(s))) | ||
1460 | return ret; | ||
1461 | } | ||
1462 | if (file->f_mode & FMODE_WRITE) { | ||
1463 | switch (val) { | ||
1464 | case 1: | ||
1465 | case 2: | ||
1466 | break; | ||
1467 | case 3: | ||
1468 | case 5: | ||
1469 | return -EINVAL; | ||
1470 | case 4: | ||
1471 | if (!(s->codec_ext_caps & | ||
1472 | AC97_EXTID_SDAC)) | ||
1473 | return -EINVAL; | ||
1474 | break; | ||
1475 | case 6: | ||
1476 | if ((s->codec_ext_caps & | ||
1477 | AC97_EXT_DACS) != AC97_EXT_DACS) | ||
1478 | return -EINVAL; | ||
1479 | break; | ||
1480 | default: | ||
1481 | return -EINVAL; | ||
1482 | } | ||
1483 | |||
1484 | stop_dac(s); | ||
1485 | if (val <= 2 && | ||
1486 | (s->codec_ext_caps & AC97_EXT_DACS)) { | ||
1487 | /* disable surround and center/lfe | ||
1488 | * channels in AC'97 | ||
1489 | */ | ||
1490 | u16 ext_stat = | ||
1491 | rdcodec(s->codec, | ||
1492 | AC97_EXTENDED_STATUS); | ||
1493 | wrcodec(s->codec, | ||
1494 | AC97_EXTENDED_STATUS, | ||
1495 | ext_stat | (AC97_EXTSTAT_PRI | | ||
1496 | AC97_EXTSTAT_PRJ | | ||
1497 | AC97_EXTSTAT_PRK)); | ||
1498 | } else if (val >= 4) { | ||
1499 | /* enable surround, center/lfe | ||
1500 | * channels in AC'97 | ||
1501 | */ | ||
1502 | u16 ext_stat = | ||
1503 | rdcodec(s->codec, | ||
1504 | AC97_EXTENDED_STATUS); | ||
1505 | ext_stat &= ~AC97_EXTSTAT_PRJ; | ||
1506 | if (val == 6) | ||
1507 | ext_stat &= | ||
1508 | ~(AC97_EXTSTAT_PRI | | ||
1509 | AC97_EXTSTAT_PRK); | ||
1510 | wrcodec(s->codec, | ||
1511 | AC97_EXTENDED_STATUS, | ||
1512 | ext_stat); | ||
1513 | } | ||
1514 | |||
1515 | s->dma_dac.num_channels = val; | ||
1516 | if ((ret = prog_dmabuf_dac(s))) | ||
1517 | return ret; | ||
1518 | } | ||
1519 | } | ||
1520 | return put_user(val, (int *) arg); | ||
1521 | |||
1522 | case SNDCTL_DSP_GETFMTS: /* Returns a mask */ | ||
1523 | return put_user(AFMT_S16_LE | AFMT_U8, (int *) arg); | ||
1524 | |||
1525 | case SNDCTL_DSP_SETFMT: /* Selects ONE fmt */ | ||
1526 | if (get_user(val, (int *) arg)) | ||
1527 | return -EFAULT; | ||
1528 | if (val != AFMT_QUERY) { | ||
1529 | if (file->f_mode & FMODE_READ) { | ||
1530 | stop_adc(s); | ||
1531 | if (val == AFMT_S16_LE) | ||
1532 | s->dma_adc.sample_size = 16; | ||
1533 | else { | ||
1534 | val = AFMT_U8; | ||
1535 | s->dma_adc.sample_size = 8; | ||
1536 | } | ||
1537 | if ((ret = prog_dmabuf_adc(s))) | ||
1538 | return ret; | ||
1539 | } | ||
1540 | if (file->f_mode & FMODE_WRITE) { | ||
1541 | stop_dac(s); | ||
1542 | if (val == AFMT_S16_LE) | ||
1543 | s->dma_dac.sample_size = 16; | ||
1544 | else { | ||
1545 | val = AFMT_U8; | ||
1546 | s->dma_dac.sample_size = 8; | ||
1547 | } | ||
1548 | if ((ret = prog_dmabuf_dac(s))) | ||
1549 | return ret; | ||
1550 | } | ||
1551 | } else { | ||
1552 | if (file->f_mode & FMODE_READ) | ||
1553 | val = (s->dma_adc.sample_size == 16) ? | ||
1554 | AFMT_S16_LE : AFMT_U8; | ||
1555 | else | ||
1556 | val = (s->dma_dac.sample_size == 16) ? | ||
1557 | AFMT_S16_LE : AFMT_U8; | ||
1558 | } | ||
1559 | return put_user(val, (int *) arg); | ||
1560 | |||
1561 | case SNDCTL_DSP_POST: | ||
1562 | return 0; | ||
1563 | |||
1564 | case SNDCTL_DSP_GETTRIGGER: | ||
1565 | val = 0; | ||
1566 | spin_lock_irqsave(&s->lock, flags); | ||
1567 | if (file->f_mode & FMODE_READ && !s->dma_adc.stopped) | ||
1568 | val |= PCM_ENABLE_INPUT; | ||
1569 | if (file->f_mode & FMODE_WRITE && !s->dma_dac.stopped) | ||
1570 | val |= PCM_ENABLE_OUTPUT; | ||
1571 | spin_unlock_irqrestore(&s->lock, flags); | ||
1572 | return put_user(val, (int *) arg); | ||
1573 | |||
1574 | case SNDCTL_DSP_SETTRIGGER: | ||
1575 | if (get_user(val, (int *) arg)) | ||
1576 | return -EFAULT; | ||
1577 | if (file->f_mode & FMODE_READ) { | ||
1578 | if (val & PCM_ENABLE_INPUT) { | ||
1579 | spin_lock_irqsave(&s->lock, flags); | ||
1580 | start_adc(s); | ||
1581 | spin_unlock_irqrestore(&s->lock, flags); | ||
1582 | } else | ||
1583 | stop_adc(s); | ||
1584 | } | ||
1585 | if (file->f_mode & FMODE_WRITE) { | ||
1586 | if (val & PCM_ENABLE_OUTPUT) { | ||
1587 | spin_lock_irqsave(&s->lock, flags); | ||
1588 | start_dac(s); | ||
1589 | spin_unlock_irqrestore(&s->lock, flags); | ||
1590 | } else | ||
1591 | stop_dac(s); | ||
1592 | } | ||
1593 | return 0; | ||
1594 | |||
1595 | case SNDCTL_DSP_GETOSPACE: | ||
1596 | if (!(file->f_mode & FMODE_WRITE)) | ||
1597 | return -EINVAL; | ||
1598 | abinfo.fragsize = s->dma_dac.fragsize; | ||
1599 | spin_lock_irqsave(&s->lock, flags); | ||
1600 | count = s->dma_dac.count; | ||
1601 | count -= dma_count_done(&s->dma_dac); | ||
1602 | spin_unlock_irqrestore(&s->lock, flags); | ||
1603 | if (count < 0) | ||
1604 | count = 0; | ||
1605 | abinfo.bytes = (s->dma_dac.dmasize - count) / | ||
1606 | s->dma_dac.cnt_factor; | ||
1607 | abinfo.fragstotal = s->dma_dac.numfrag; | ||
1608 | abinfo.fragments = abinfo.bytes >> s->dma_dac.fragshift; | ||
1609 | pr_debug("ioctl SNDCTL_DSP_GETOSPACE: bytes=%d, fragments=%d\n", abinfo.bytes, abinfo.fragments); | ||
1610 | return copy_to_user((void *) arg, &abinfo, | ||
1611 | sizeof(abinfo)) ? -EFAULT : 0; | ||
1612 | |||
1613 | case SNDCTL_DSP_GETISPACE: | ||
1614 | if (!(file->f_mode & FMODE_READ)) | ||
1615 | return -EINVAL; | ||
1616 | abinfo.fragsize = s->dma_adc.fragsize; | ||
1617 | spin_lock_irqsave(&s->lock, flags); | ||
1618 | count = s->dma_adc.count; | ||
1619 | count += dma_count_done(&s->dma_adc); | ||
1620 | spin_unlock_irqrestore(&s->lock, flags); | ||
1621 | if (count < 0) | ||
1622 | count = 0; | ||
1623 | abinfo.bytes = count / s->dma_adc.cnt_factor; | ||
1624 | abinfo.fragstotal = s->dma_adc.numfrag; | ||
1625 | abinfo.fragments = abinfo.bytes >> s->dma_adc.fragshift; | ||
1626 | return copy_to_user((void *) arg, &abinfo, | ||
1627 | sizeof(abinfo)) ? -EFAULT : 0; | ||
1628 | |||
1629 | case SNDCTL_DSP_NONBLOCK: | ||
1630 | spin_lock(&file->f_lock); | ||
1631 | file->f_flags |= O_NONBLOCK; | ||
1632 | spin_unlock(&file->f_lock); | ||
1633 | return 0; | ||
1634 | |||
1635 | case SNDCTL_DSP_GETODELAY: | ||
1636 | if (!(file->f_mode & FMODE_WRITE)) | ||
1637 | return -EINVAL; | ||
1638 | spin_lock_irqsave(&s->lock, flags); | ||
1639 | count = s->dma_dac.count; | ||
1640 | count -= dma_count_done(&s->dma_dac); | ||
1641 | spin_unlock_irqrestore(&s->lock, flags); | ||
1642 | if (count < 0) | ||
1643 | count = 0; | ||
1644 | count /= s->dma_dac.cnt_factor; | ||
1645 | return put_user(count, (int *) arg); | ||
1646 | |||
1647 | case SNDCTL_DSP_GETIPTR: | ||
1648 | if (!(file->f_mode & FMODE_READ)) | ||
1649 | return -EINVAL; | ||
1650 | spin_lock_irqsave(&s->lock, flags); | ||
1651 | cinfo.bytes = s->dma_adc.total_bytes; | ||
1652 | count = s->dma_adc.count; | ||
1653 | if (!s->dma_adc.stopped) { | ||
1654 | diff = dma_count_done(&s->dma_adc); | ||
1655 | count += diff; | ||
1656 | cinfo.bytes += diff; | ||
1657 | cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) + diff - | ||
1658 | virt_to_phys(s->dma_adc.rawbuf); | ||
1659 | } else | ||
1660 | cinfo.ptr = virt_to_phys(s->dma_adc.nextIn) - | ||
1661 | virt_to_phys(s->dma_adc.rawbuf); | ||
1662 | if (s->dma_adc.mapped) | ||
1663 | s->dma_adc.count &= (s->dma_adc.dma_fragsize-1); | ||
1664 | spin_unlock_irqrestore(&s->lock, flags); | ||
1665 | if (count < 0) | ||
1666 | count = 0; | ||
1667 | cinfo.blocks = count >> s->dma_adc.fragshift; | ||
1668 | return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)); | ||
1669 | |||
1670 | case SNDCTL_DSP_GETOPTR: | ||
1671 | if (!(file->f_mode & FMODE_READ)) | ||
1672 | return -EINVAL; | ||
1673 | spin_lock_irqsave(&s->lock, flags); | ||
1674 | cinfo.bytes = s->dma_dac.total_bytes; | ||
1675 | count = s->dma_dac.count; | ||
1676 | if (!s->dma_dac.stopped) { | ||
1677 | diff = dma_count_done(&s->dma_dac); | ||
1678 | count -= diff; | ||
1679 | cinfo.bytes += diff; | ||
1680 | cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) + diff - | ||
1681 | virt_to_phys(s->dma_dac.rawbuf); | ||
1682 | } else | ||
1683 | cinfo.ptr = virt_to_phys(s->dma_dac.nextOut) - | ||
1684 | virt_to_phys(s->dma_dac.rawbuf); | ||
1685 | if (s->dma_dac.mapped) | ||
1686 | s->dma_dac.count &= (s->dma_dac.dma_fragsize-1); | ||
1687 | spin_unlock_irqrestore(&s->lock, flags); | ||
1688 | if (count < 0) | ||
1689 | count = 0; | ||
1690 | cinfo.blocks = count >> s->dma_dac.fragshift; | ||
1691 | return copy_to_user((void *) arg, &cinfo, sizeof(cinfo)); | ||
1692 | |||
1693 | case SNDCTL_DSP_GETBLKSIZE: | ||
1694 | if (file->f_mode & FMODE_WRITE) | ||
1695 | return put_user(s->dma_dac.fragsize, (int *) arg); | ||
1696 | else | ||
1697 | return put_user(s->dma_adc.fragsize, (int *) arg); | ||
1698 | |||
1699 | case SNDCTL_DSP_SETFRAGMENT: | ||
1700 | if (get_user(val, (int *) arg)) | ||
1701 | return -EFAULT; | ||
1702 | if (file->f_mode & FMODE_READ) { | ||
1703 | stop_adc(s); | ||
1704 | s->dma_adc.ossfragshift = val & 0xffff; | ||
1705 | s->dma_adc.ossmaxfrags = (val >> 16) & 0xffff; | ||
1706 | if (s->dma_adc.ossfragshift < 4) | ||
1707 | s->dma_adc.ossfragshift = 4; | ||
1708 | if (s->dma_adc.ossfragshift > 15) | ||
1709 | s->dma_adc.ossfragshift = 15; | ||
1710 | if (s->dma_adc.ossmaxfrags < 4) | ||
1711 | s->dma_adc.ossmaxfrags = 4; | ||
1712 | if ((ret = prog_dmabuf_adc(s))) | ||
1713 | return ret; | ||
1714 | } | ||
1715 | if (file->f_mode & FMODE_WRITE) { | ||
1716 | stop_dac(s); | ||
1717 | s->dma_dac.ossfragshift = val & 0xffff; | ||
1718 | s->dma_dac.ossmaxfrags = (val >> 16) & 0xffff; | ||
1719 | if (s->dma_dac.ossfragshift < 4) | ||
1720 | s->dma_dac.ossfragshift = 4; | ||
1721 | if (s->dma_dac.ossfragshift > 15) | ||
1722 | s->dma_dac.ossfragshift = 15; | ||
1723 | if (s->dma_dac.ossmaxfrags < 4) | ||
1724 | s->dma_dac.ossmaxfrags = 4; | ||
1725 | if ((ret = prog_dmabuf_dac(s))) | ||
1726 | return ret; | ||
1727 | } | ||
1728 | return 0; | ||
1729 | |||
1730 | case SNDCTL_DSP_SUBDIVIDE: | ||
1731 | if ((file->f_mode & FMODE_READ && s->dma_adc.subdivision) || | ||
1732 | (file->f_mode & FMODE_WRITE && s->dma_dac.subdivision)) | ||
1733 | return -EINVAL; | ||
1734 | if (get_user(val, (int *) arg)) | ||
1735 | return -EFAULT; | ||
1736 | if (val != 1 && val != 2 && val != 4) | ||
1737 | return -EINVAL; | ||
1738 | if (file->f_mode & FMODE_READ) { | ||
1739 | stop_adc(s); | ||
1740 | s->dma_adc.subdivision = val; | ||
1741 | if ((ret = prog_dmabuf_adc(s))) | ||
1742 | return ret; | ||
1743 | } | ||
1744 | if (file->f_mode & FMODE_WRITE) { | ||
1745 | stop_dac(s); | ||
1746 | s->dma_dac.subdivision = val; | ||
1747 | if ((ret = prog_dmabuf_dac(s))) | ||
1748 | return ret; | ||
1749 | } | ||
1750 | return 0; | ||
1751 | |||
1752 | case SOUND_PCM_READ_RATE: | ||
1753 | return put_user((file->f_mode & FMODE_READ) ? | ||
1754 | s->dma_adc.sample_rate : | ||
1755 | s->dma_dac.sample_rate, | ||
1756 | (int *)arg); | ||
1757 | |||
1758 | case SOUND_PCM_READ_CHANNELS: | ||
1759 | if (file->f_mode & FMODE_READ) | ||
1760 | return put_user(s->dma_adc.num_channels, (int *)arg); | ||
1761 | else | ||
1762 | return put_user(s->dma_dac.num_channels, (int *)arg); | ||
1763 | |||
1764 | case SOUND_PCM_READ_BITS: | ||
1765 | if (file->f_mode & FMODE_READ) | ||
1766 | return put_user(s->dma_adc.sample_size, (int *)arg); | ||
1767 | else | ||
1768 | return put_user(s->dma_dac.sample_size, (int *)arg); | ||
1769 | |||
1770 | case SOUND_PCM_WRITE_FILTER: | ||
1771 | case SNDCTL_DSP_SETSYNCRO: | ||
1772 | case SOUND_PCM_READ_FILTER: | ||
1773 | return -EINVAL; | ||
1774 | } | ||
1775 | |||
1776 | return mixdev_ioctl(s->codec, cmd, arg); | ||
1777 | } | ||
1778 | |||
1779 | static long | ||
1780 | au1550_unlocked_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | ||
1781 | { | ||
1782 | int ret; | ||
1783 | |||
1784 | mutex_lock(&au1550_ac97_mutex); | ||
1785 | ret = au1550_ioctl(file, cmd, arg); | ||
1786 | mutex_unlock(&au1550_ac97_mutex); | ||
1787 | |||
1788 | return ret; | ||
1789 | } | ||
1790 | |||
1791 | static int | ||
1792 | au1550_open(struct inode *inode, struct file *file) | ||
1793 | { | ||
1794 | int minor = MINOR(inode->i_rdev); | ||
1795 | DECLARE_WAITQUEUE(wait, current); | ||
1796 | struct au1550_state *s = &au1550_state; | ||
1797 | int ret; | ||
1798 | |||
1799 | #ifdef DEBUG | ||
1800 | if (file->f_flags & O_NONBLOCK) | ||
1801 | pr_debug("open: non-blocking\n"); | ||
1802 | else | ||
1803 | pr_debug("open: blocking\n"); | ||
1804 | #endif | ||
1805 | |||
1806 | file->private_data = s; | ||
1807 | mutex_lock(&au1550_ac97_mutex); | ||
1808 | /* wait for device to become free */ | ||
1809 | mutex_lock(&s->open_mutex); | ||
1810 | while (s->open_mode & file->f_mode) { | ||
1811 | ret = -EBUSY; | ||
1812 | if (file->f_flags & O_NONBLOCK) | ||
1813 | goto out; | ||
1814 | add_wait_queue(&s->open_wait, &wait); | ||
1815 | __set_current_state(TASK_INTERRUPTIBLE); | ||
1816 | mutex_unlock(&s->open_mutex); | ||
1817 | schedule(); | ||
1818 | remove_wait_queue(&s->open_wait, &wait); | ||
1819 | set_current_state(TASK_RUNNING); | ||
1820 | ret = -ERESTARTSYS; | ||
1821 | if (signal_pending(current)) | ||
1822 | goto out2; | ||
1823 | mutex_lock(&s->open_mutex); | ||
1824 | } | ||
1825 | |||
1826 | stop_dac(s); | ||
1827 | stop_adc(s); | ||
1828 | |||
1829 | if (file->f_mode & FMODE_READ) { | ||
1830 | s->dma_adc.ossfragshift = s->dma_adc.ossmaxfrags = | ||
1831 | s->dma_adc.subdivision = s->dma_adc.total_bytes = 0; | ||
1832 | s->dma_adc.num_channels = 1; | ||
1833 | s->dma_adc.sample_size = 8; | ||
1834 | set_adc_rate(s, 8000); | ||
1835 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
1836 | s->dma_adc.sample_size = 16; | ||
1837 | } | ||
1838 | |||
1839 | if (file->f_mode & FMODE_WRITE) { | ||
1840 | s->dma_dac.ossfragshift = s->dma_dac.ossmaxfrags = | ||
1841 | s->dma_dac.subdivision = s->dma_dac.total_bytes = 0; | ||
1842 | s->dma_dac.num_channels = 1; | ||
1843 | s->dma_dac.sample_size = 8; | ||
1844 | set_dac_rate(s, 8000); | ||
1845 | if ((minor & 0xf) == SND_DEV_DSP16) | ||
1846 | s->dma_dac.sample_size = 16; | ||
1847 | } | ||
1848 | |||
1849 | if (file->f_mode & FMODE_READ) { | ||
1850 | if ((ret = prog_dmabuf_adc(s))) | ||
1851 | goto out; | ||
1852 | } | ||
1853 | if (file->f_mode & FMODE_WRITE) { | ||
1854 | if ((ret = prog_dmabuf_dac(s))) | ||
1855 | goto out; | ||
1856 | } | ||
1857 | |||
1858 | s->open_mode |= file->f_mode & (FMODE_READ | FMODE_WRITE); | ||
1859 | mutex_init(&s->sem); | ||
1860 | ret = 0; | ||
1861 | out: | ||
1862 | mutex_unlock(&s->open_mutex); | ||
1863 | out2: | ||
1864 | mutex_unlock(&au1550_ac97_mutex); | ||
1865 | return ret; | ||
1866 | } | ||
1867 | |||
1868 | static int | ||
1869 | au1550_release(struct inode *inode, struct file *file) | ||
1870 | { | ||
1871 | struct au1550_state *s = file->private_data; | ||
1872 | |||
1873 | mutex_lock(&au1550_ac97_mutex); | ||
1874 | |||
1875 | if (file->f_mode & FMODE_WRITE) { | ||
1876 | mutex_unlock(&au1550_ac97_mutex); | ||
1877 | drain_dac(s, file->f_flags & O_NONBLOCK); | ||
1878 | mutex_lock(&au1550_ac97_mutex); | ||
1879 | } | ||
1880 | |||
1881 | mutex_lock(&s->open_mutex); | ||
1882 | if (file->f_mode & FMODE_WRITE) { | ||
1883 | stop_dac(s); | ||
1884 | kfree(s->dma_dac.rawbuf); | ||
1885 | s->dma_dac.rawbuf = NULL; | ||
1886 | } | ||
1887 | if (file->f_mode & FMODE_READ) { | ||
1888 | stop_adc(s); | ||
1889 | kfree(s->dma_adc.rawbuf); | ||
1890 | s->dma_adc.rawbuf = NULL; | ||
1891 | } | ||
1892 | s->open_mode &= ((~file->f_mode) & (FMODE_READ|FMODE_WRITE)); | ||
1893 | mutex_unlock(&s->open_mutex); | ||
1894 | wake_up(&s->open_wait); | ||
1895 | mutex_unlock(&au1550_ac97_mutex); | ||
1896 | return 0; | ||
1897 | } | ||
1898 | |||
1899 | static /*const */ struct file_operations au1550_audio_fops = { | ||
1900 | .owner = THIS_MODULE, | ||
1901 | .llseek = au1550_llseek, | ||
1902 | .read = au1550_read, | ||
1903 | .write = au1550_write, | ||
1904 | .poll = au1550_poll, | ||
1905 | .unlocked_ioctl = au1550_unlocked_ioctl, | ||
1906 | .mmap = au1550_mmap, | ||
1907 | .open = au1550_open, | ||
1908 | .release = au1550_release, | ||
1909 | }; | ||
1910 | |||
1911 | MODULE_AUTHOR("Advanced Micro Devices (AMD), dan@embeddededge.com"); | ||
1912 | MODULE_DESCRIPTION("Au1550 AC97 Audio Driver"); | ||
1913 | MODULE_LICENSE("GPL"); | ||
1914 | |||
1915 | |||
1916 | static int __devinit | ||
1917 | au1550_probe(void) | ||
1918 | { | ||
1919 | struct au1550_state *s = &au1550_state; | ||
1920 | int val; | ||
1921 | |||
1922 | memset(s, 0, sizeof(struct au1550_state)); | ||
1923 | |||
1924 | init_waitqueue_head(&s->dma_adc.wait); | ||
1925 | init_waitqueue_head(&s->dma_dac.wait); | ||
1926 | init_waitqueue_head(&s->open_wait); | ||
1927 | mutex_init(&s->open_mutex); | ||
1928 | spin_lock_init(&s->lock); | ||
1929 | |||
1930 | s->codec = ac97_alloc_codec(); | ||
1931 | if(s->codec == NULL) { | ||
1932 | err("Out of memory"); | ||
1933 | return -1; | ||
1934 | } | ||
1935 | s->codec->private_data = s; | ||
1936 | s->codec->id = 0; | ||
1937 | s->codec->codec_read = rdcodec; | ||
1938 | s->codec->codec_write = wrcodec; | ||
1939 | s->codec->codec_wait = waitcodec; | ||
1940 | |||
1941 | if (!request_mem_region(CPHYSADDR(AC97_PSC_SEL), | ||
1942 | 0x30, "Au1550 AC97")) { | ||
1943 | err("AC'97 ports in use"); | ||
1944 | } | ||
1945 | |||
1946 | /* Allocate the DMA Channels | ||
1947 | */ | ||
1948 | if ((s->dma_dac.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_MEM_CHAN, | ||
1949 | DBDMA_AC97_TX_CHAN, dac_dma_interrupt, (void *)s)) == 0) { | ||
1950 | err("Can't get DAC DMA"); | ||
1951 | goto err_dma1; | ||
1952 | } | ||
1953 | au1xxx_dbdma_set_devwidth(s->dma_dac.dmanr, 16); | ||
1954 | if (au1xxx_dbdma_ring_alloc(s->dma_dac.dmanr, | ||
1955 | NUM_DBDMA_DESCRIPTORS) == 0) { | ||
1956 | err("Can't get DAC DMA descriptors"); | ||
1957 | goto err_dma1; | ||
1958 | } | ||
1959 | |||
1960 | if ((s->dma_adc.dmanr = au1xxx_dbdma_chan_alloc(DBDMA_AC97_RX_CHAN, | ||
1961 | DBDMA_MEM_CHAN, adc_dma_interrupt, (void *)s)) == 0) { | ||
1962 | err("Can't get ADC DMA"); | ||
1963 | goto err_dma2; | ||
1964 | } | ||
1965 | au1xxx_dbdma_set_devwidth(s->dma_adc.dmanr, 16); | ||
1966 | if (au1xxx_dbdma_ring_alloc(s->dma_adc.dmanr, | ||
1967 | NUM_DBDMA_DESCRIPTORS) == 0) { | ||
1968 | err("Can't get ADC DMA descriptors"); | ||
1969 | goto err_dma2; | ||
1970 | } | ||
1971 | |||
1972 | pr_info("DAC: DMA%d, ADC: DMA%d", DBDMA_AC97_TX_CHAN, DBDMA_AC97_RX_CHAN); | ||
1973 | |||
1974 | /* register devices */ | ||
1975 | |||
1976 | if ((s->dev_audio = register_sound_dsp(&au1550_audio_fops, -1)) < 0) | ||
1977 | goto err_dev1; | ||
1978 | if ((s->codec->dev_mixer = | ||
1979 | register_sound_mixer(&au1550_mixer_fops, -1)) < 0) | ||
1980 | goto err_dev2; | ||
1981 | |||
1982 | /* The GPIO for the appropriate PSC was configured by the | ||
1983 | * board specific start up. | ||
1984 | * | ||
1985 | * configure PSC for AC'97 | ||
1986 | */ | ||
1987 | au_writel(0, AC97_PSC_CTRL); /* Disable PSC */ | ||
1988 | au_sync(); | ||
1989 | au_writel((PSC_SEL_CLK_SERCLK | PSC_SEL_PS_AC97MODE), AC97_PSC_SEL); | ||
1990 | au_sync(); | ||
1991 | |||
1992 | /* cold reset the AC'97 | ||
1993 | */ | ||
1994 | au_writel(PSC_AC97RST_RST, PSC_AC97RST); | ||
1995 | au_sync(); | ||
1996 | au1550_delay(10); | ||
1997 | au_writel(0, PSC_AC97RST); | ||
1998 | au_sync(); | ||
1999 | |||
2000 | /* need to delay around 500msec(bleech) to give | ||
2001 | some CODECs enough time to wakeup */ | ||
2002 | au1550_delay(500); | ||
2003 | |||
2004 | /* warm reset the AC'97 to start the bitclk | ||
2005 | */ | ||
2006 | au_writel(PSC_AC97RST_SNC, PSC_AC97RST); | ||
2007 | au_sync(); | ||
2008 | udelay(100); | ||
2009 | au_writel(0, PSC_AC97RST); | ||
2010 | au_sync(); | ||
2011 | |||
2012 | /* Enable PSC | ||
2013 | */ | ||
2014 | au_writel(PSC_CTRL_ENABLE, AC97_PSC_CTRL); | ||
2015 | au_sync(); | ||
2016 | |||
2017 | /* Wait for PSC ready. | ||
2018 | */ | ||
2019 | do { | ||
2020 | val = au_readl(PSC_AC97STAT); | ||
2021 | au_sync(); | ||
2022 | } while ((val & PSC_AC97STAT_SR) == 0); | ||
2023 | |||
2024 | /* Configure AC97 controller. | ||
2025 | * Deep FIFO, 16-bit sample, DMA, make sure DMA matches fifo size. | ||
2026 | */ | ||
2027 | val = PSC_AC97CFG_SET_LEN(16); | ||
2028 | val |= PSC_AC97CFG_RT_FIFO8 | PSC_AC97CFG_TT_FIFO8; | ||
2029 | |||
2030 | /* Enable device so we can at least | ||
2031 | * talk over the AC-link. | ||
2032 | */ | ||
2033 | au_writel(val, PSC_AC97CFG); | ||
2034 | au_writel(PSC_AC97MSK_ALLMASK, PSC_AC97MSK); | ||
2035 | au_sync(); | ||
2036 | val |= PSC_AC97CFG_DE_ENABLE; | ||
2037 | au_writel(val, PSC_AC97CFG); | ||
2038 | au_sync(); | ||
2039 | |||
2040 | /* Wait for Device ready. | ||
2041 | */ | ||
2042 | do { | ||
2043 | val = au_readl(PSC_AC97STAT); | ||
2044 | au_sync(); | ||
2045 | } while ((val & PSC_AC97STAT_DR) == 0); | ||
2046 | |||
2047 | /* codec init */ | ||
2048 | if (!ac97_probe_codec(s->codec)) | ||
2049 | goto err_dev3; | ||
2050 | |||
2051 | s->codec_base_caps = rdcodec(s->codec, AC97_RESET); | ||
2052 | s->codec_ext_caps = rdcodec(s->codec, AC97_EXTENDED_ID); | ||
2053 | pr_info("AC'97 Base/Extended ID = %04x/%04x", | ||
2054 | s->codec_base_caps, s->codec_ext_caps); | ||
2055 | |||
2056 | if (!(s->codec_ext_caps & AC97_EXTID_VRA)) { | ||
2057 | /* codec does not support VRA | ||
2058 | */ | ||
2059 | s->no_vra = 1; | ||
2060 | } else if (!vra) { | ||
2061 | /* Boot option says disable VRA | ||
2062 | */ | ||
2063 | u16 ac97_extstat = rdcodec(s->codec, AC97_EXTENDED_STATUS); | ||
2064 | wrcodec(s->codec, AC97_EXTENDED_STATUS, | ||
2065 | ac97_extstat & ~AC97_EXTSTAT_VRA); | ||
2066 | s->no_vra = 1; | ||
2067 | } | ||
2068 | if (s->no_vra) | ||
2069 | pr_info("no VRA, interpolating and decimating"); | ||
2070 | |||
2071 | /* set mic to be the recording source */ | ||
2072 | val = SOUND_MASK_MIC; | ||
2073 | mixdev_ioctl(s->codec, SOUND_MIXER_WRITE_RECSRC, | ||
2074 | (unsigned long) &val); | ||
2075 | |||
2076 | return 0; | ||
2077 | |||
2078 | err_dev3: | ||
2079 | unregister_sound_mixer(s->codec->dev_mixer); | ||
2080 | err_dev2: | ||
2081 | unregister_sound_dsp(s->dev_audio); | ||
2082 | err_dev1: | ||
2083 | au1xxx_dbdma_chan_free(s->dma_adc.dmanr); | ||
2084 | err_dma2: | ||
2085 | au1xxx_dbdma_chan_free(s->dma_dac.dmanr); | ||
2086 | err_dma1: | ||
2087 | release_mem_region(CPHYSADDR(AC97_PSC_SEL), 0x30); | ||
2088 | |||
2089 | ac97_release_codec(s->codec); | ||
2090 | return -1; | ||
2091 | } | ||
2092 | |||
2093 | static void __devinit | ||
2094 | au1550_remove(void) | ||
2095 | { | ||
2096 | struct au1550_state *s = &au1550_state; | ||
2097 | |||
2098 | if (!s) | ||
2099 | return; | ||
2100 | synchronize_irq(); | ||
2101 | au1xxx_dbdma_chan_free(s->dma_adc.dmanr); | ||
2102 | au1xxx_dbdma_chan_free(s->dma_dac.dmanr); | ||
2103 | release_mem_region(CPHYSADDR(AC97_PSC_SEL), 0x30); | ||
2104 | unregister_sound_dsp(s->dev_audio); | ||
2105 | unregister_sound_mixer(s->codec->dev_mixer); | ||
2106 | ac97_release_codec(s->codec); | ||
2107 | } | ||
2108 | |||
2109 | static int __init | ||
2110 | init_au1550(void) | ||
2111 | { | ||
2112 | return au1550_probe(); | ||
2113 | } | ||
2114 | |||
2115 | static void __exit | ||
2116 | cleanup_au1550(void) | ||
2117 | { | ||
2118 | au1550_remove(); | ||
2119 | } | ||
2120 | |||
2121 | module_init(init_au1550); | ||
2122 | module_exit(cleanup_au1550); | ||
2123 | |||
2124 | #ifndef MODULE | ||
2125 | |||
2126 | static int __init | ||
2127 | au1550_setup(char *options) | ||
2128 | { | ||
2129 | char *this_opt; | ||
2130 | |||
2131 | if (!options || !*options) | ||
2132 | return 0; | ||
2133 | |||
2134 | while ((this_opt = strsep(&options, ","))) { | ||
2135 | if (!*this_opt) | ||
2136 | continue; | ||
2137 | if (!strncmp(this_opt, "vra", 3)) { | ||
2138 | vra = 1; | ||
2139 | } | ||
2140 | } | ||
2141 | |||
2142 | return 1; | ||
2143 | } | ||
2144 | |||
2145 | __setup("au1550_audio=", au1550_setup); | ||
2146 | |||
2147 | #endif /* MODULE */ | ||
diff --git a/sound/pci/Kconfig b/sound/pci/Kconfig index 389cd7931668..e90d103e177e 100644 --- a/sound/pci/Kconfig +++ b/sound/pci/Kconfig | |||
@@ -534,6 +534,14 @@ config SND_ES1968_INPUT | |||
534 | If you say N the buttons will directly control the master volume. | 534 | If you say N the buttons will directly control the master volume. |
535 | It is recommended to say Y. | 535 | It is recommended to say Y. |
536 | 536 | ||
537 | config SND_ES1968_RADIO | ||
538 | bool "Enable TEA5757 radio tuner support for es1968" | ||
539 | depends on SND_ES1968 | ||
540 | depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_ES1968 | ||
541 | help | ||
542 | Say Y here to include support for TEA5757 radio tuner integrated on | ||
543 | some MediaForte cards (e.g. SF64-PCE2). | ||
544 | |||
537 | config SND_FM801 | 545 | config SND_FM801 |
538 | tristate "ForteMedia FM801" | 546 | tristate "ForteMedia FM801" |
539 | select SND_OPL3_LIB | 547 | select SND_OPL3_LIB |
@@ -552,13 +560,13 @@ config SND_FM801_TEA575X_BOOL | |||
552 | depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801 | 560 | depends on VIDEO_V4L2=y || VIDEO_V4L2=SND_FM801 |
553 | help | 561 | help |
554 | Say Y here to include support for soundcards based on the ForteMedia | 562 | Say Y here to include support for soundcards based on the ForteMedia |
555 | FM801 chip with a TEA5757 tuner connected to GPIO1-3 pins (Media | 563 | FM801 chip with a TEA5757 tuner (MediaForte SF256-PCS, SF256-PCP and |
556 | Forte SF256-PCS-02) into the snd-fm801 driver. | 564 | SF64-PCR) into the snd-fm801 driver. |
557 | 565 | ||
558 | config SND_FM801_TEA575X | 566 | config SND_TEA575X |
559 | tristate | 567 | tristate |
560 | depends on SND_FM801_TEA575X_BOOL | 568 | depends on SND_FM801_TEA575X_BOOL || SND_ES1968_RADIO |
561 | default SND_FM801 | 569 | default SND_FM801 || SND_ES1968 |
562 | 570 | ||
563 | source "sound/pci/hda/Kconfig" | 571 | source "sound/pci/hda/Kconfig" |
564 | 572 | ||
@@ -658,6 +666,15 @@ config SND_KORG1212 | |||
658 | To compile this driver as a module, choose M here: the module | 666 | To compile this driver as a module, choose M here: the module |
659 | will be called snd-korg1212. | 667 | will be called snd-korg1212. |
660 | 668 | ||
669 | config SND_LOLA | ||
670 | tristate "Digigram Lola" | ||
671 | select SND_PCM | ||
672 | help | ||
673 | Say Y to include support for Digigram Lola boards. | ||
674 | |||
675 | To compile this driver as a module, choose M here: the module | ||
676 | will be called snd-lola. | ||
677 | |||
661 | config SND_LX6464ES | 678 | config SND_LX6464ES |
662 | tristate "Digigram LX6464ES" | 679 | tristate "Digigram LX6464ES" |
663 | select SND_PCM | 680 | select SND_PCM |
diff --git a/sound/pci/Makefile b/sound/pci/Makefile index 9cf4348ec137..54fe325e3aa5 100644 --- a/sound/pci/Makefile +++ b/sound/pci/Makefile | |||
@@ -64,6 +64,7 @@ obj-$(CONFIG_SND) += \ | |||
64 | ca0106/ \ | 64 | ca0106/ \ |
65 | cs46xx/ \ | 65 | cs46xx/ \ |
66 | cs5535audio/ \ | 66 | cs5535audio/ \ |
67 | lola/ \ | ||
67 | lx6464es/ \ | 68 | lx6464es/ \ |
68 | echoaudio/ \ | 69 | echoaudio/ \ |
69 | emu10k1/ \ | 70 | emu10k1/ \ |
diff --git a/sound/pci/asihpi/asihpi.c b/sound/pci/asihpi/asihpi.c index f8ccc9677c6f..2ca6f4f85b41 100644 --- a/sound/pci/asihpi/asihpi.c +++ b/sound/pci/asihpi/asihpi.c | |||
@@ -42,10 +42,29 @@ | |||
42 | #include <sound/tlv.h> | 42 | #include <sound/tlv.h> |
43 | #include <sound/hwdep.h> | 43 | #include <sound/hwdep.h> |
44 | 44 | ||
45 | |||
45 | MODULE_LICENSE("GPL"); | 46 | MODULE_LICENSE("GPL"); |
46 | MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); | 47 | MODULE_AUTHOR("AudioScience inc. <support@audioscience.com>"); |
47 | MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); | 48 | MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); |
48 | 49 | ||
50 | #if defined CONFIG_SND_DEBUG | ||
51 | /* copied from pcm_lib.c, hope later patch will make that version public | ||
52 | and this copy can be removed */ | ||
53 | static void pcm_debug_name(struct snd_pcm_substream *substream, | ||
54 | char *name, size_t len) | ||
55 | { | ||
56 | snprintf(name, len, "pcmC%dD%d%c:%d", | ||
57 | substream->pcm->card->number, | ||
58 | substream->pcm->device, | ||
59 | substream->stream ? 'c' : 'p', | ||
60 | substream->number); | ||
61 | } | ||
62 | #define DEBUG_NAME(substream, name) char name[16]; pcm_debug_name(substream, name, sizeof(name)) | ||
63 | #else | ||
64 | #define pcm_debug_name(s, n, l) do { } while (0) | ||
65 | #define DEBUG_NAME(name, substream) do { } while (0) | ||
66 | #endif | ||
67 | |||
49 | #if defined CONFIG_SND_DEBUG_VERBOSE | 68 | #if defined CONFIG_SND_DEBUG_VERBOSE |
50 | /** | 69 | /** |
51 | * snd_printddd - very verbose debug printk | 70 | * snd_printddd - very verbose debug printk |
@@ -58,7 +77,7 @@ MODULE_DESCRIPTION("AudioScience ALSA ASI5000 ASI6000 ASI87xx ASI89xx"); | |||
58 | #define snd_printddd(format, args...) \ | 77 | #define snd_printddd(format, args...) \ |
59 | __snd_printk(3, __FILE__, __LINE__, format, ##args) | 78 | __snd_printk(3, __FILE__, __LINE__, format, ##args) |
60 | #else | 79 | #else |
61 | #define snd_printddd(format, args...) do { } while (0) | 80 | #define snd_printddd(format, args...) do { } while (0) |
62 | #endif | 81 | #endif |
63 | 82 | ||
64 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ | 83 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; /* index 0-MAX */ |
@@ -101,13 +120,6 @@ static int adapter_fs = DEFAULT_SAMPLERATE; | |||
101 | #define PERIOD_BYTES_MIN 2048 | 120 | #define PERIOD_BYTES_MIN 2048 |
102 | #define BUFFER_BYTES_MAX (512 * 1024) | 121 | #define BUFFER_BYTES_MAX (512 * 1024) |
103 | 122 | ||
104 | /* convert stream to character */ | ||
105 | #define SCHR(s) ((s == SNDRV_PCM_STREAM_PLAYBACK) ? 'P' : 'C') | ||
106 | |||
107 | /*#define TIMER_MILLISECONDS 20 | ||
108 | #define FORCE_TIMER_JIFFIES ((TIMER_MILLISECONDS * HZ + 999)/1000) | ||
109 | */ | ||
110 | |||
111 | #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7) | 123 | #define MAX_CLOCKSOURCES (HPI_SAMPLECLOCK_SOURCE_LAST + 1 + 7) |
112 | 124 | ||
113 | struct clk_source { | 125 | struct clk_source { |
@@ -136,7 +148,7 @@ struct snd_card_asihpi { | |||
136 | u32 h_mixer; | 148 | u32 h_mixer; |
137 | struct clk_cache cc; | 149 | struct clk_cache cc; |
138 | 150 | ||
139 | u16 support_mmap; | 151 | u16 can_dma; |
140 | u16 support_grouping; | 152 | u16 support_grouping; |
141 | u16 support_mrx; | 153 | u16 support_mrx; |
142 | u16 update_interval_frames; | 154 | u16 update_interval_frames; |
@@ -155,6 +167,7 @@ struct snd_card_asihpi_pcm { | |||
155 | unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */ | 167 | unsigned int pcm_buf_host_rw_ofs; /* Host R/W pos */ |
156 | unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */ | 168 | unsigned int pcm_buf_dma_ofs; /* DMA R/W offset in buffer */ |
157 | unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */ | 169 | unsigned int pcm_buf_elapsed_dma_ofs; /* DMA R/W offset in buffer */ |
170 | unsigned int drained_count; | ||
158 | struct snd_pcm_substream *substream; | 171 | struct snd_pcm_substream *substream; |
159 | u32 h_stream; | 172 | u32 h_stream; |
160 | struct hpi_format format; | 173 | struct hpi_format format; |
@@ -288,19 +301,26 @@ static u16 handle_error(u16 err, int line, char *filename) | |||
288 | #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) | 301 | #define hpi_handle_error(x) handle_error(x, __LINE__, __FILE__) |
289 | 302 | ||
290 | /***************************** GENERAL PCM ****************/ | 303 | /***************************** GENERAL PCM ****************/ |
291 | static void print_hwparams(struct snd_pcm_hw_params *p) | 304 | |
305 | static void print_hwparams(struct snd_pcm_substream *substream, | ||
306 | struct snd_pcm_hw_params *p) | ||
292 | { | 307 | { |
293 | snd_printd("HWPARAMS \n"); | 308 | DEBUG_NAME(substream, name); |
294 | snd_printd("samplerate %d \n", params_rate(p)); | 309 | snd_printd("%s HWPARAMS\n", name); |
295 | snd_printd("Channels %d \n", params_channels(p)); | 310 | snd_printd(" samplerate %d Hz\n", params_rate(p)); |
296 | snd_printd("Format %d \n", params_format(p)); | 311 | snd_printd(" channels %d\n", params_channels(p)); |
297 | snd_printd("subformat %d \n", params_subformat(p)); | 312 | snd_printd(" format %d\n", params_format(p)); |
298 | snd_printd("Buffer bytes %d \n", params_buffer_bytes(p)); | 313 | snd_printd(" subformat %d\n", params_subformat(p)); |
299 | snd_printd("Period bytes %d \n", params_period_bytes(p)); | 314 | snd_printd(" buffer %d B\n", params_buffer_bytes(p)); |
300 | snd_printd("access %d \n", params_access(p)); | 315 | snd_printd(" period %d B\n", params_period_bytes(p)); |
301 | snd_printd("period_size %d \n", params_period_size(p)); | 316 | snd_printd(" access %d\n", params_access(p)); |
302 | snd_printd("periods %d \n", params_periods(p)); | 317 | snd_printd(" period_size %d\n", params_period_size(p)); |
303 | snd_printd("buffer_size %d \n", params_buffer_size(p)); | 318 | snd_printd(" periods %d\n", params_periods(p)); |
319 | snd_printd(" buffer_size %d\n", params_buffer_size(p)); | ||
320 | snd_printd(" %d B/s\n", params_rate(p) * | ||
321 | params_channels(p) * | ||
322 | snd_pcm_format_width(params_format(p)) / 8); | ||
323 | |||
304 | } | 324 | } |
305 | 325 | ||
306 | static snd_pcm_format_t hpi_to_alsa_formats[] = { | 326 | static snd_pcm_format_t hpi_to_alsa_formats[] = { |
@@ -451,7 +471,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
451 | int width; | 471 | int width; |
452 | unsigned int bytes_per_sec; | 472 | unsigned int bytes_per_sec; |
453 | 473 | ||
454 | print_hwparams(params); | 474 | print_hwparams(substream, params); |
455 | err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); | 475 | err = snd_pcm_lib_malloc_pages(substream, params_buffer_bytes(params)); |
456 | if (err < 0) | 476 | if (err < 0) |
457 | return err; | 477 | return err; |
@@ -459,10 +479,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
459 | if (err) | 479 | if (err) |
460 | return err; | 480 | return err; |
461 | 481 | ||
462 | snd_printdd("format %d, %d chans, %d_hz\n", | ||
463 | format, params_channels(params), | ||
464 | params_rate(params)); | ||
465 | |||
466 | hpi_handle_error(hpi_format_create(&dpcm->format, | 482 | hpi_handle_error(hpi_format_create(&dpcm->format, |
467 | params_channels(params), | 483 | params_channels(params), |
468 | format, params_rate(params), 0, 0)); | 484 | format, params_rate(params), 0, 0)); |
@@ -477,8 +493,7 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
477 | } | 493 | } |
478 | 494 | ||
479 | dpcm->hpi_buffer_attached = 0; | 495 | dpcm->hpi_buffer_attached = 0; |
480 | if (card->support_mmap) { | 496 | if (card->can_dma) { |
481 | |||
482 | err = hpi_stream_host_buffer_attach(dpcm->h_stream, | 497 | err = hpi_stream_host_buffer_attach(dpcm->h_stream, |
483 | params_buffer_bytes(params), runtime->dma_addr); | 498 | params_buffer_bytes(params), runtime->dma_addr); |
484 | if (err == 0) { | 499 | if (err == 0) { |
@@ -509,8 +524,6 @@ static int snd_card_asihpi_pcm_hw_params(struct snd_pcm_substream *substream, | |||
509 | dpcm->bytes_per_sec = bytes_per_sec; | 524 | dpcm->bytes_per_sec = bytes_per_sec; |
510 | dpcm->buffer_bytes = params_buffer_bytes(params); | 525 | dpcm->buffer_bytes = params_buffer_bytes(params); |
511 | dpcm->period_bytes = params_period_bytes(params); | 526 | dpcm->period_bytes = params_period_bytes(params); |
512 | snd_printdd("buffer_bytes=%d, period_bytes=%d, bps=%d\n", | ||
513 | dpcm->buffer_bytes, dpcm->period_bytes, bytes_per_sec); | ||
514 | 527 | ||
515 | return 0; | 528 | return 0; |
516 | } | 529 | } |
@@ -564,9 +577,10 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
564 | struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); | 577 | struct snd_card_asihpi *card = snd_pcm_substream_chip(substream); |
565 | struct snd_pcm_substream *s; | 578 | struct snd_pcm_substream *s; |
566 | u16 e; | 579 | u16 e; |
580 | DEBUG_NAME(substream, name); | ||
581 | |||
582 | snd_printdd("%s trigger\n", name); | ||
567 | 583 | ||
568 | snd_printdd("%c%d trigger\n", | ||
569 | SCHR(substream->stream), substream->number); | ||
570 | switch (cmd) { | 584 | switch (cmd) { |
571 | case SNDRV_PCM_TRIGGER_START: | 585 | case SNDRV_PCM_TRIGGER_START: |
572 | snd_pcm_group_for_each_entry(s, substream) { | 586 | snd_pcm_group_for_each_entry(s, substream) { |
@@ -580,8 +594,8 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
580 | if (substream->stream != s->stream) | 594 | if (substream->stream != s->stream) |
581 | continue; | 595 | continue; |
582 | 596 | ||
583 | if ((s->stream == SNDRV_PCM_STREAM_PLAYBACK) && | 597 | ds->drained_count = 0; |
584 | (card->support_mmap)) { | 598 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
585 | /* How do I know how much valid data is present | 599 | /* How do I know how much valid data is present |
586 | * in buffer? Must be at least one period! | 600 | * in buffer? Must be at least one period! |
587 | * Guessing 2 periods, but if | 601 | * Guessing 2 periods, but if |
@@ -599,9 +613,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
599 | } | 613 | } |
600 | 614 | ||
601 | if (card->support_grouping) { | 615 | if (card->support_grouping) { |
602 | snd_printdd("\t%c%d group\n", | 616 | snd_printdd("%d group\n", s->number); |
603 | SCHR(s->stream), | ||
604 | s->number); | ||
605 | e = hpi_stream_group_add( | 617 | e = hpi_stream_group_add( |
606 | dpcm->h_stream, | 618 | dpcm->h_stream, |
607 | ds->h_stream); | 619 | ds->h_stream); |
@@ -618,7 +630,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
618 | /* start the master stream */ | 630 | /* start the master stream */ |
619 | snd_card_asihpi_pcm_timer_start(substream); | 631 | snd_card_asihpi_pcm_timer_start(substream); |
620 | if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || | 632 | if ((substream->stream == SNDRV_PCM_STREAM_CAPTURE) || |
621 | !card->support_mmap) | 633 | !card->can_dma) |
622 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); | 634 | hpi_handle_error(hpi_stream_start(dpcm->h_stream)); |
623 | break; | 635 | break; |
624 | 636 | ||
@@ -636,9 +648,7 @@ static int snd_card_asihpi_trigger(struct snd_pcm_substream *substream, | |||
636 | s->runtime->status->state = SNDRV_PCM_STATE_SETUP; | 648 | s->runtime->status->state = SNDRV_PCM_STATE_SETUP; |
637 | 649 | ||
638 | if (card->support_grouping) { | 650 | if (card->support_grouping) { |
639 | snd_printdd("\t%c%d group\n", | 651 | snd_printdd("%d group\n", s->number); |
640 | SCHR(s->stream), | ||
641 | s->number); | ||
642 | snd_pcm_trigger_done(s, substream); | 652 | snd_pcm_trigger_done(s, substream); |
643 | } else | 653 | } else |
644 | break; | 654 | break; |
@@ -732,9 +742,9 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
732 | int loops = 0; | 742 | int loops = 0; |
733 | u16 state; | 743 | u16 state; |
734 | u32 buffer_size, bytes_avail, samples_played, on_card_bytes; | 744 | u32 buffer_size, bytes_avail, samples_played, on_card_bytes; |
745 | DEBUG_NAME(substream, name); | ||
735 | 746 | ||
736 | snd_printdd("%c%d snd_card_asihpi_timer_function\n", | 747 | snd_printdd("%s snd_card_asihpi_timer_function\n", name); |
737 | SCHR(substream->stream), substream->number); | ||
738 | 748 | ||
739 | /* find minimum newdata and buffer pos in group */ | 749 | /* find minimum newdata and buffer pos in group */ |
740 | snd_pcm_group_for_each_entry(s, substream) { | 750 | snd_pcm_group_for_each_entry(s, substream) { |
@@ -756,6 +766,9 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
756 | /* number of bytes in on-card buffer */ | 766 | /* number of bytes in on-card buffer */ |
757 | runtime->delay = on_card_bytes; | 767 | runtime->delay = on_card_bytes; |
758 | 768 | ||
769 | if (!card->can_dma) | ||
770 | on_card_bytes = bytes_avail; | ||
771 | |||
759 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 772 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { |
760 | pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail; | 773 | pcm_buf_dma_ofs = ds->pcm_buf_host_rw_ofs - bytes_avail; |
761 | if (state == HPI_STATE_STOPPED) { | 774 | if (state == HPI_STATE_STOPPED) { |
@@ -763,12 +776,18 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
763 | (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { | 776 | (on_card_bytes < ds->pcm_buf_host_rw_ofs)) { |
764 | hpi_handle_error(hpi_stream_start(ds->h_stream)); | 777 | hpi_handle_error(hpi_stream_start(ds->h_stream)); |
765 | snd_printdd("P%d start\n", s->number); | 778 | snd_printdd("P%d start\n", s->number); |
779 | ds->drained_count = 0; | ||
766 | } | 780 | } |
767 | } else if (state == HPI_STATE_DRAINED) { | 781 | } else if (state == HPI_STATE_DRAINED) { |
768 | snd_printd(KERN_WARNING "P%d drained\n", | 782 | snd_printd(KERN_WARNING "P%d drained\n", |
769 | s->number); | 783 | s->number); |
770 | /*snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); | 784 | ds->drained_count++; |
771 | continue; */ | 785 | if (ds->drained_count > 2) { |
786 | snd_pcm_stop(s, SNDRV_PCM_STATE_XRUN); | ||
787 | continue; | ||
788 | } | ||
789 | } else { | ||
790 | ds->drained_count = 0; | ||
772 | } | 791 | } |
773 | } else | 792 | } else |
774 | pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs; | 793 | pcm_buf_dma_ofs = bytes_avail + ds->pcm_buf_host_rw_ofs; |
@@ -786,16 +805,18 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
786 | newdata); | 805 | newdata); |
787 | } | 806 | } |
788 | 807 | ||
789 | snd_printdd("hw_ptr x%04lX, appl_ptr x%04lX\n", | 808 | snd_printdd("hw_ptr 0x%04lX, appl_ptr 0x%04lX\n", |
790 | (unsigned long)frames_to_bytes(runtime, | 809 | (unsigned long)frames_to_bytes(runtime, |
791 | runtime->status->hw_ptr), | 810 | runtime->status->hw_ptr), |
792 | (unsigned long)frames_to_bytes(runtime, | 811 | (unsigned long)frames_to_bytes(runtime, |
793 | runtime->control->appl_ptr)); | 812 | runtime->control->appl_ptr)); |
794 | 813 | ||
795 | snd_printdd("%d %c%d S=%d, rw=%04X, dma=x%04X, left=x%04X," | 814 | snd_printdd("%d S=%d, " |
796 | " aux=x%04X space=x%04X\n", | 815 | "rw=0x%04X, dma=0x%04X, left=0x%04X, " |
797 | loops, SCHR(s->stream), s->number, | 816 | "aux=0x%04X space=0x%04X\n", |
798 | state, ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, (int)bytes_avail, | 817 | s->number, state, |
818 | ds->pcm_buf_host_rw_ofs, pcm_buf_dma_ofs, | ||
819 | (int)bytes_avail, | ||
799 | (int)on_card_bytes, buffer_size-bytes_avail); | 820 | (int)on_card_bytes, buffer_size-bytes_avail); |
800 | loops++; | 821 | loops++; |
801 | } | 822 | } |
@@ -814,7 +835,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
814 | 835 | ||
815 | next_jiffies = max(next_jiffies, 1U); | 836 | next_jiffies = max(next_jiffies, 1U); |
816 | dpcm->timer.expires = jiffies + next_jiffies; | 837 | dpcm->timer.expires = jiffies + next_jiffies; |
817 | snd_printdd("jif %d buf pos x%04X newdata x%04X xfer x%04X\n", | 838 | snd_printdd("jif %d buf pos 0x%04X newdata 0x%04X xfer 0x%04X\n", |
818 | next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); | 839 | next_jiffies, pcm_buf_dma_ofs, newdata, xfercount); |
819 | 840 | ||
820 | snd_pcm_group_for_each_entry(s, substream) { | 841 | snd_pcm_group_for_each_entry(s, substream) { |
@@ -826,30 +847,63 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
826 | 847 | ||
827 | ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs; | 848 | ds->pcm_buf_dma_ofs = pcm_buf_dma_ofs; |
828 | 849 | ||
829 | if (xfercount && (on_card_bytes <= ds->period_bytes)) { | 850 | if (xfercount && |
830 | if (card->support_mmap) { | 851 | /* Limit use of on card fifo for playback */ |
831 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { | 852 | ((on_card_bytes <= ds->period_bytes) || |
832 | snd_printddd("P%d write x%04x\n", | 853 | (s->stream == SNDRV_PCM_STREAM_CAPTURE))) |
854 | |||
855 | { | ||
856 | |||
857 | unsigned int buf_ofs = ds->pcm_buf_host_rw_ofs % ds->buffer_bytes; | ||
858 | unsigned int xfer1, xfer2; | ||
859 | char *pd = &s->runtime->dma_area[buf_ofs]; | ||
860 | |||
861 | if (card->can_dma) { /* buffer wrap is handled at lower level */ | ||
862 | xfer1 = xfercount; | ||
863 | xfer2 = 0; | ||
864 | } else { | ||
865 | xfer1 = min(xfercount, ds->buffer_bytes - buf_ofs); | ||
866 | xfer2 = xfercount - xfer1; | ||
867 | } | ||
868 | |||
869 | if (s->stream == SNDRV_PCM_STREAM_PLAYBACK) { | ||
870 | snd_printddd("P%d write1 0x%04X 0x%04X\n", | ||
871 | s->number, xfer1, buf_ofs); | ||
872 | hpi_handle_error( | ||
873 | hpi_outstream_write_buf( | ||
874 | ds->h_stream, pd, xfer1, | ||
875 | &ds->format)); | ||
876 | |||
877 | if (xfer2) { | ||
878 | pd = s->runtime->dma_area; | ||
879 | |||
880 | snd_printddd("P%d write2 0x%04X 0x%04X\n", | ||
833 | s->number, | 881 | s->number, |
834 | ds->period_bytes); | 882 | xfercount - xfer1, buf_ofs); |
835 | hpi_handle_error( | 883 | hpi_handle_error( |
836 | hpi_outstream_write_buf( | 884 | hpi_outstream_write_buf( |
837 | ds->h_stream, | 885 | ds->h_stream, pd, |
838 | &s->runtime-> | 886 | xfercount - xfer1, |
839 | dma_area[0], | ||
840 | xfercount, | ||
841 | &ds->format)); | 887 | &ds->format)); |
842 | } else { | 888 | } |
843 | snd_printddd("C%d read x%04x\n", | 889 | } else { |
844 | s->number, | 890 | snd_printddd("C%d read1 0x%04x\n", |
845 | xfercount); | 891 | s->number, xfer1); |
892 | hpi_handle_error( | ||
893 | hpi_instream_read_buf( | ||
894 | ds->h_stream, | ||
895 | pd, xfer1)); | ||
896 | if (xfer2) { | ||
897 | pd = s->runtime->dma_area; | ||
898 | snd_printddd("C%d read2 0x%04x\n", | ||
899 | s->number, xfer2); | ||
846 | hpi_handle_error( | 900 | hpi_handle_error( |
847 | hpi_instream_read_buf( | 901 | hpi_instream_read_buf( |
848 | ds->h_stream, | 902 | ds->h_stream, |
849 | NULL, xfercount)); | 903 | pd, xfer2)); |
850 | } | 904 | } |
851 | ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; | 905 | } |
852 | } /* else R/W will be handled by read/write callbacks */ | 906 | ds->pcm_buf_host_rw_ofs = ds->pcm_buf_host_rw_ofs + xfercount; |
853 | ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs; | 907 | ds->pcm_buf_elapsed_dma_ofs = pcm_buf_dma_ofs; |
854 | snd_pcm_period_elapsed(s); | 908 | snd_pcm_period_elapsed(s); |
855 | } | 909 | } |
@@ -863,7 +917,7 @@ static void snd_card_asihpi_timer_function(unsigned long data) | |||
863 | static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, | 917 | static int snd_card_asihpi_playback_ioctl(struct snd_pcm_substream *substream, |
864 | unsigned int cmd, void *arg) | 918 | unsigned int cmd, void *arg) |
865 | { | 919 | { |
866 | snd_printdd(KERN_INFO "Playback ioctl %d\n", cmd); | 920 | snd_printddd(KERN_INFO "P%d ioctl %d\n", substream->number, cmd); |
867 | return snd_pcm_lib_ioctl(substream, cmd, arg); | 921 | return snd_pcm_lib_ioctl(substream, cmd, arg); |
868 | } | 922 | } |
869 | 923 | ||
@@ -873,7 +927,7 @@ static int snd_card_asihpi_playback_prepare(struct snd_pcm_substream * | |||
873 | struct snd_pcm_runtime *runtime = substream->runtime; | 927 | struct snd_pcm_runtime *runtime = substream->runtime; |
874 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | 928 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; |
875 | 929 | ||
876 | snd_printdd("playback prepare %d\n", substream->number); | 930 | snd_printdd("P%d prepare\n", substream->number); |
877 | 931 | ||
878 | hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); | 932 | hpi_handle_error(hpi_outstream_reset(dpcm->h_stream)); |
879 | dpcm->pcm_buf_host_rw_ofs = 0; | 933 | dpcm->pcm_buf_host_rw_ofs = 0; |
@@ -890,7 +944,7 @@ snd_card_asihpi_playback_pointer(struct snd_pcm_substream *substream) | |||
890 | snd_pcm_uframes_t ptr; | 944 | snd_pcm_uframes_t ptr; |
891 | 945 | ||
892 | ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); | 946 | ptr = bytes_to_frames(runtime, dpcm->pcm_buf_dma_ofs % dpcm->buffer_bytes); |
893 | snd_printddd("playback_pointer=x%04lx\n", (unsigned long)ptr); | 947 | snd_printddd("P%d pointer = 0x%04lx\n", substream->number, (unsigned long)ptr); |
894 | return ptr; | 948 | return ptr; |
895 | } | 949 | } |
896 | 950 | ||
@@ -986,11 +1040,9 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) | |||
986 | SNDRV_PCM_INFO_DOUBLE | | 1040 | SNDRV_PCM_INFO_DOUBLE | |
987 | SNDRV_PCM_INFO_BATCH | | 1041 | SNDRV_PCM_INFO_BATCH | |
988 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | 1042 | SNDRV_PCM_INFO_BLOCK_TRANSFER | |
989 | SNDRV_PCM_INFO_PAUSE; | 1043 | SNDRV_PCM_INFO_PAUSE | |
990 | 1044 | SNDRV_PCM_INFO_MMAP | | |
991 | if (card->support_mmap) | 1045 | SNDRV_PCM_INFO_MMAP_VALID; |
992 | snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_MMAP | | ||
993 | SNDRV_PCM_INFO_MMAP_VALID; | ||
994 | 1046 | ||
995 | if (card->support_grouping) | 1047 | if (card->support_grouping) |
996 | snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START; | 1048 | snd_card_asihpi_playback.info |= SNDRV_PCM_INFO_SYNC_START; |
@@ -998,7 +1050,7 @@ static int snd_card_asihpi_playback_open(struct snd_pcm_substream *substream) | |||
998 | /* struct is copied, so can create initializer dynamically */ | 1050 | /* struct is copied, so can create initializer dynamically */ |
999 | runtime->hw = snd_card_asihpi_playback; | 1051 | runtime->hw = snd_card_asihpi_playback; |
1000 | 1052 | ||
1001 | if (card->support_mmap) | 1053 | if (card->can_dma) |
1002 | err = snd_pcm_hw_constraint_pow2(runtime, 0, | 1054 | err = snd_pcm_hw_constraint_pow2(runtime, 0, |
1003 | SNDRV_PCM_HW_PARAM_BUFFER_BYTES); | 1055 | SNDRV_PCM_HW_PARAM_BUFFER_BYTES); |
1004 | if (err < 0) | 1056 | if (err < 0) |
@@ -1028,58 +1080,6 @@ static int snd_card_asihpi_playback_close(struct snd_pcm_substream *substream) | |||
1028 | return 0; | 1080 | return 0; |
1029 | } | 1081 | } |
1030 | 1082 | ||
1031 | static int snd_card_asihpi_playback_copy(struct snd_pcm_substream *substream, | ||
1032 | int channel, | ||
1033 | snd_pcm_uframes_t pos, | ||
1034 | void __user *src, | ||
1035 | snd_pcm_uframes_t count) | ||
1036 | { | ||
1037 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1038 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | ||
1039 | unsigned int len; | ||
1040 | |||
1041 | len = frames_to_bytes(runtime, count); | ||
1042 | |||
1043 | if (copy_from_user(runtime->dma_area, src, len)) | ||
1044 | return -EFAULT; | ||
1045 | |||
1046 | snd_printddd("playback copy%d %u bytes\n", | ||
1047 | substream->number, len); | ||
1048 | |||
1049 | hpi_handle_error(hpi_outstream_write_buf(dpcm->h_stream, | ||
1050 | runtime->dma_area, len, &dpcm->format)); | ||
1051 | |||
1052 | dpcm->pcm_buf_host_rw_ofs += len; | ||
1053 | |||
1054 | return 0; | ||
1055 | } | ||
1056 | |||
1057 | static int snd_card_asihpi_playback_silence(struct snd_pcm_substream * | ||
1058 | substream, int channel, | ||
1059 | snd_pcm_uframes_t pos, | ||
1060 | snd_pcm_uframes_t count) | ||
1061 | { | ||
1062 | /* Usually writes silence to DMA buffer, which should be overwritten | ||
1063 | by real audio later. Our fifos cannot be overwritten, and are not | ||
1064 | free-running DMAs. Silence is output on fifo underflow. | ||
1065 | This callback is still required to allow the copy callback to be used. | ||
1066 | */ | ||
1067 | return 0; | ||
1068 | } | ||
1069 | |||
1070 | static struct snd_pcm_ops snd_card_asihpi_playback_ops = { | ||
1071 | .open = snd_card_asihpi_playback_open, | ||
1072 | .close = snd_card_asihpi_playback_close, | ||
1073 | .ioctl = snd_card_asihpi_playback_ioctl, | ||
1074 | .hw_params = snd_card_asihpi_pcm_hw_params, | ||
1075 | .hw_free = snd_card_asihpi_hw_free, | ||
1076 | .prepare = snd_card_asihpi_playback_prepare, | ||
1077 | .trigger = snd_card_asihpi_trigger, | ||
1078 | .pointer = snd_card_asihpi_playback_pointer, | ||
1079 | .copy = snd_card_asihpi_playback_copy, | ||
1080 | .silence = snd_card_asihpi_playback_silence, | ||
1081 | }; | ||
1082 | |||
1083 | static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { | 1083 | static struct snd_pcm_ops snd_card_asihpi_playback_mmap_ops = { |
1084 | .open = snd_card_asihpi_playback_open, | 1084 | .open = snd_card_asihpi_playback_open, |
1085 | .close = snd_card_asihpi_playback_close, | 1085 | .close = snd_card_asihpi_playback_close, |
@@ -1211,18 +1211,16 @@ static int snd_card_asihpi_capture_open(struct snd_pcm_substream *substream) | |||
1211 | snd_card_asihpi_capture_format(card, dpcm->h_stream, | 1211 | snd_card_asihpi_capture_format(card, dpcm->h_stream, |
1212 | &snd_card_asihpi_capture); | 1212 | &snd_card_asihpi_capture); |
1213 | snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); | 1213 | snd_card_asihpi_pcm_samplerates(card, &snd_card_asihpi_capture); |
1214 | snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED; | 1214 | snd_card_asihpi_capture.info = SNDRV_PCM_INFO_INTERLEAVED | |
1215 | 1215 | SNDRV_PCM_INFO_MMAP | | |
1216 | if (card->support_mmap) | 1216 | SNDRV_PCM_INFO_MMAP_VALID; |
1217 | snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_MMAP | | ||
1218 | SNDRV_PCM_INFO_MMAP_VALID; | ||
1219 | 1217 | ||
1220 | if (card->support_grouping) | 1218 | if (card->support_grouping) |
1221 | snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START; | 1219 | snd_card_asihpi_capture.info |= SNDRV_PCM_INFO_SYNC_START; |
1222 | 1220 | ||
1223 | runtime->hw = snd_card_asihpi_capture; | 1221 | runtime->hw = snd_card_asihpi_capture; |
1224 | 1222 | ||
1225 | if (card->support_mmap) | 1223 | if (card->can_dma) |
1226 | err = snd_pcm_hw_constraint_pow2(runtime, 0, | 1224 | err = snd_pcm_hw_constraint_pow2(runtime, 0, |
1227 | SNDRV_PCM_HW_PARAM_BUFFER_BYTES); | 1225 | SNDRV_PCM_HW_PARAM_BUFFER_BYTES); |
1228 | if (err < 0) | 1226 | if (err < 0) |
@@ -1246,28 +1244,6 @@ static int snd_card_asihpi_capture_close(struct snd_pcm_substream *substream) | |||
1246 | return 0; | 1244 | return 0; |
1247 | } | 1245 | } |
1248 | 1246 | ||
1249 | static int snd_card_asihpi_capture_copy(struct snd_pcm_substream *substream, | ||
1250 | int channel, snd_pcm_uframes_t pos, | ||
1251 | void __user *dst, snd_pcm_uframes_t count) | ||
1252 | { | ||
1253 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
1254 | struct snd_card_asihpi_pcm *dpcm = runtime->private_data; | ||
1255 | u32 len; | ||
1256 | |||
1257 | len = frames_to_bytes(runtime, count); | ||
1258 | |||
1259 | snd_printddd("capture copy%d %d bytes\n", substream->number, len); | ||
1260 | hpi_handle_error(hpi_instream_read_buf(dpcm->h_stream, | ||
1261 | runtime->dma_area, len)); | ||
1262 | |||
1263 | dpcm->pcm_buf_host_rw_ofs = dpcm->pcm_buf_host_rw_ofs + len; | ||
1264 | |||
1265 | if (copy_to_user(dst, runtime->dma_area, len)) | ||
1266 | return -EFAULT; | ||
1267 | |||
1268 | return 0; | ||
1269 | } | ||
1270 | |||
1271 | static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { | 1247 | static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { |
1272 | .open = snd_card_asihpi_capture_open, | 1248 | .open = snd_card_asihpi_capture_open, |
1273 | .close = snd_card_asihpi_capture_close, | 1249 | .close = snd_card_asihpi_capture_close, |
@@ -1279,18 +1255,6 @@ static struct snd_pcm_ops snd_card_asihpi_capture_mmap_ops = { | |||
1279 | .pointer = snd_card_asihpi_capture_pointer, | 1255 | .pointer = snd_card_asihpi_capture_pointer, |
1280 | }; | 1256 | }; |
1281 | 1257 | ||
1282 | static struct snd_pcm_ops snd_card_asihpi_capture_ops = { | ||
1283 | .open = snd_card_asihpi_capture_open, | ||
1284 | .close = snd_card_asihpi_capture_close, | ||
1285 | .ioctl = snd_card_asihpi_capture_ioctl, | ||
1286 | .hw_params = snd_card_asihpi_pcm_hw_params, | ||
1287 | .hw_free = snd_card_asihpi_hw_free, | ||
1288 | .prepare = snd_card_asihpi_capture_prepare, | ||
1289 | .trigger = snd_card_asihpi_trigger, | ||
1290 | .pointer = snd_card_asihpi_capture_pointer, | ||
1291 | .copy = snd_card_asihpi_capture_copy | ||
1292 | }; | ||
1293 | |||
1294 | static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, | 1258 | static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, |
1295 | int device, int substreams) | 1259 | int device, int substreams) |
1296 | { | 1260 | { |
@@ -1303,17 +1267,10 @@ static int __devinit snd_card_asihpi_pcm_new(struct snd_card_asihpi *asihpi, | |||
1303 | if (err < 0) | 1267 | if (err < 0) |
1304 | return err; | 1268 | return err; |
1305 | /* pointer to ops struct is stored, dont change ops afterwards! */ | 1269 | /* pointer to ops struct is stored, dont change ops afterwards! */ |
1306 | if (asihpi->support_mmap) { | ||
1307 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, | 1270 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, |
1308 | &snd_card_asihpi_playback_mmap_ops); | 1271 | &snd_card_asihpi_playback_mmap_ops); |
1309 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | 1272 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, |
1310 | &snd_card_asihpi_capture_mmap_ops); | 1273 | &snd_card_asihpi_capture_mmap_ops); |
1311 | } else { | ||
1312 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, | ||
1313 | &snd_card_asihpi_playback_ops); | ||
1314 | snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, | ||
1315 | &snd_card_asihpi_capture_ops); | ||
1316 | } | ||
1317 | 1274 | ||
1318 | pcm->private_data = asihpi; | 1275 | pcm->private_data = asihpi; |
1319 | pcm->info_flags = 0; | 1276 | pcm->info_flags = 0; |
@@ -1413,14 +1370,16 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control, | |||
1413 | struct hpi_control *hpi_ctl, | 1370 | struct hpi_control *hpi_ctl, |
1414 | char *name) | 1371 | char *name) |
1415 | { | 1372 | { |
1416 | char *dir = ""; | 1373 | char *dir; |
1417 | memset(snd_control, 0, sizeof(*snd_control)); | 1374 | memset(snd_control, 0, sizeof(*snd_control)); |
1418 | snd_control->name = hpi_ctl->name; | 1375 | snd_control->name = hpi_ctl->name; |
1419 | snd_control->private_value = hpi_ctl->h_control; | 1376 | snd_control->private_value = hpi_ctl->h_control; |
1420 | snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 1377 | snd_control->iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
1421 | snd_control->index = 0; | 1378 | snd_control->index = 0; |
1422 | 1379 | ||
1423 | if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) | 1380 | if (hpi_ctl->src_node_type + HPI_SOURCENODE_NONE == HPI_SOURCENODE_CLOCK_SOURCE) |
1381 | dir = ""; /* clock is neither capture nor playback */ | ||
1382 | else if (hpi_ctl->dst_node_type + HPI_DESTNODE_NONE == HPI_DESTNODE_ISTREAM) | ||
1424 | dir = "Capture "; /* On or towards a PCM capture destination*/ | 1383 | dir = "Capture "; /* On or towards a PCM capture destination*/ |
1425 | else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) && | 1384 | else if ((hpi_ctl->src_node_type + HPI_SOURCENODE_NONE != HPI_SOURCENODE_OSTREAM) && |
1426 | (!hpi_ctl->dst_node_type)) | 1385 | (!hpi_ctl->dst_node_type)) |
@@ -1433,7 +1392,7 @@ static void asihpi_ctl_init(struct snd_kcontrol_new *snd_control, | |||
1433 | dir = "Playback "; /* PCM Playback source, or output node */ | 1392 | dir = "Playback "; /* PCM Playback source, or output node */ |
1434 | 1393 | ||
1435 | if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) | 1394 | if (hpi_ctl->src_node_type && hpi_ctl->dst_node_type) |
1436 | sprintf(hpi_ctl->name, "%s%d %s%d %s%s", | 1395 | sprintf(hpi_ctl->name, "%s %d %s %d %s%s", |
1437 | asihpi_src_names[hpi_ctl->src_node_type], | 1396 | asihpi_src_names[hpi_ctl->src_node_type], |
1438 | hpi_ctl->src_node_index, | 1397 | hpi_ctl->src_node_index, |
1439 | asihpi_dst_names[hpi_ctl->dst_node_type], | 1398 | asihpi_dst_names[hpi_ctl->dst_node_type], |
@@ -2875,14 +2834,14 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2875 | if (err) | 2834 | if (err) |
2876 | asihpi->update_interval_frames = 512; | 2835 | asihpi->update_interval_frames = 512; |
2877 | 2836 | ||
2878 | if (!asihpi->support_mmap) | 2837 | if (!asihpi->can_dma) |
2879 | asihpi->update_interval_frames *= 2; | 2838 | asihpi->update_interval_frames *= 2; |
2880 | 2839 | ||
2881 | hpi_handle_error(hpi_instream_open(asihpi->adapter_index, | 2840 | hpi_handle_error(hpi_instream_open(asihpi->adapter_index, |
2882 | 0, &h_stream)); | 2841 | 0, &h_stream)); |
2883 | 2842 | ||
2884 | err = hpi_instream_host_buffer_free(h_stream); | 2843 | err = hpi_instream_host_buffer_free(h_stream); |
2885 | asihpi->support_mmap = (!err); | 2844 | asihpi->can_dma = (!err); |
2886 | 2845 | ||
2887 | hpi_handle_error(hpi_instream_close(h_stream)); | 2846 | hpi_handle_error(hpi_instream_close(h_stream)); |
2888 | 2847 | ||
@@ -2894,8 +2853,8 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2894 | asihpi->out_max_chans = 2; | 2853 | asihpi->out_max_chans = 2; |
2895 | } | 2854 | } |
2896 | 2855 | ||
2897 | snd_printk(KERN_INFO "supports mmap:%d grouping:%d mrx:%d\n", | 2856 | snd_printk(KERN_INFO "has dma:%d, grouping:%d, mrx:%d\n", |
2898 | asihpi->support_mmap, | 2857 | asihpi->can_dma, |
2899 | asihpi->support_grouping, | 2858 | asihpi->support_grouping, |
2900 | asihpi->support_mrx | 2859 | asihpi->support_mrx |
2901 | ); | 2860 | ); |
@@ -2925,10 +2884,7 @@ static int __devinit snd_asihpi_probe(struct pci_dev *pci_dev, | |||
2925 | by enable_hwdep module param*/ | 2884 | by enable_hwdep module param*/ |
2926 | snd_asihpi_hpi_new(asihpi, 0, NULL); | 2885 | snd_asihpi_hpi_new(asihpi, 0, NULL); |
2927 | 2886 | ||
2928 | if (asihpi->support_mmap) | 2887 | strcpy(card->driver, "ASIHPI"); |
2929 | strcpy(card->driver, "ASIHPI-MMAP"); | ||
2930 | else | ||
2931 | strcpy(card->driver, "ASIHPI"); | ||
2932 | 2888 | ||
2933 | sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type); | 2889 | sprintf(card->shortname, "AudioScience ASI%4X", asihpi->type); |
2934 | sprintf(card->longname, "%s %i", | 2890 | sprintf(card->longname, "%s %i", |
diff --git a/sound/pci/asihpi/hpi6000.c b/sound/pci/asihpi/hpi6000.c index 8c8aac4c567e..df4aed5295dd 100644 --- a/sound/pci/asihpi/hpi6000.c +++ b/sound/pci/asihpi/hpi6000.c | |||
@@ -200,8 +200,8 @@ static void hpi_read_block(struct dsp_obj *pdo, u32 address, u32 *pdata, | |||
200 | static void subsys_create_adapter(struct hpi_message *phm, | 200 | static void subsys_create_adapter(struct hpi_message *phm, |
201 | struct hpi_response *phr); | 201 | struct hpi_response *phr); |
202 | 202 | ||
203 | static void subsys_delete_adapter(struct hpi_message *phm, | 203 | static void adapter_delete(struct hpi_adapter_obj *pao, |
204 | struct hpi_response *phr); | 204 | struct hpi_message *phm, struct hpi_response *phr); |
205 | 205 | ||
206 | static void adapter_get_asserts(struct hpi_adapter_obj *pao, | 206 | static void adapter_get_asserts(struct hpi_adapter_obj *pao, |
207 | struct hpi_message *phm, struct hpi_response *phr); | 207 | struct hpi_message *phm, struct hpi_response *phr); |
@@ -222,9 +222,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) | |||
222 | case HPI_SUBSYS_CREATE_ADAPTER: | 222 | case HPI_SUBSYS_CREATE_ADAPTER: |
223 | subsys_create_adapter(phm, phr); | 223 | subsys_create_adapter(phm, phr); |
224 | break; | 224 | break; |
225 | case HPI_SUBSYS_DELETE_ADAPTER: | ||
226 | subsys_delete_adapter(phm, phr); | ||
227 | break; | ||
228 | default: | 225 | default: |
229 | phr->error = HPI_ERROR_INVALID_FUNC; | 226 | phr->error = HPI_ERROR_INVALID_FUNC; |
230 | break; | 227 | break; |
@@ -279,6 +276,10 @@ static void adapter_message(struct hpi_adapter_obj *pao, | |||
279 | adapter_get_asserts(pao, phm, phr); | 276 | adapter_get_asserts(pao, phm, phr); |
280 | break; | 277 | break; |
281 | 278 | ||
279 | case HPI_ADAPTER_DELETE: | ||
280 | adapter_delete(pao, phm, phr); | ||
281 | break; | ||
282 | |||
282 | default: | 283 | default: |
283 | hw_message(pao, phm, phr); | 284 | hw_message(pao, phm, phr); |
284 | break; | 285 | break; |
@@ -333,26 +334,22 @@ void HPI_6000(struct hpi_message *phm, struct hpi_response *phr) | |||
333 | { | 334 | { |
334 | struct hpi_adapter_obj *pao = NULL; | 335 | struct hpi_adapter_obj *pao = NULL; |
335 | 336 | ||
336 | /* subsytem messages get executed by every HPI. */ | ||
337 | /* All other messages are ignored unless the adapter index matches */ | ||
338 | /* an adapter in the HPI */ | ||
339 | /*HPI_DEBUG_LOG(DEBUG, "O %d,F %x\n", phm->wObject, phm->wFunction); */ | ||
340 | |||
341 | /* if Dsp has crashed then do not communicate with it any more */ | ||
342 | if (phm->object != HPI_OBJ_SUBSYSTEM) { | 337 | if (phm->object != HPI_OBJ_SUBSYSTEM) { |
343 | pao = hpi_find_adapter(phm->adapter_index); | 338 | pao = hpi_find_adapter(phm->adapter_index); |
344 | if (!pao) { | 339 | if (!pao) { |
345 | HPI_DEBUG_LOG(DEBUG, | 340 | hpi_init_response(phr, phm->object, phm->function, |
346 | " %d,%d refused, for another HPI?\n", | 341 | HPI_ERROR_BAD_ADAPTER_NUMBER); |
347 | phm->object, phm->function); | 342 | HPI_DEBUG_LOG(DEBUG, "invalid adapter index: %d \n", |
343 | phm->adapter_index); | ||
348 | return; | 344 | return; |
349 | } | 345 | } |
350 | 346 | ||
347 | /* Don't even try to communicate with crashed DSP */ | ||
351 | if (pao->dsp_crashed >= 10) { | 348 | if (pao->dsp_crashed >= 10) { |
352 | hpi_init_response(phr, phm->object, phm->function, | 349 | hpi_init_response(phr, phm->object, phm->function, |
353 | HPI_ERROR_DSP_HARDWARE); | 350 | HPI_ERROR_DSP_HARDWARE); |
354 | HPI_DEBUG_LOG(DEBUG, " %d,%d dsp crashed.\n", | 351 | HPI_DEBUG_LOG(DEBUG, "adapter %d dsp crashed\n", |
355 | phm->object, phm->function); | 352 | phm->adapter_index); |
356 | return; | 353 | return; |
357 | } | 354 | } |
358 | } | 355 | } |
@@ -463,15 +460,9 @@ static void subsys_create_adapter(struct hpi_message *phm, | |||
463 | phr->error = 0; | 460 | phr->error = 0; |
464 | } | 461 | } |
465 | 462 | ||
466 | static void subsys_delete_adapter(struct hpi_message *phm, | 463 | static void adapter_delete(struct hpi_adapter_obj *pao, |
467 | struct hpi_response *phr) | 464 | struct hpi_message *phm, struct hpi_response *phr) |
468 | { | 465 | { |
469 | struct hpi_adapter_obj *pao = NULL; | ||
470 | |||
471 | pao = hpi_find_adapter(phm->obj_index); | ||
472 | if (!pao) | ||
473 | return; | ||
474 | |||
475 | delete_adapter_obj(pao); | 466 | delete_adapter_obj(pao); |
476 | hpi_delete_adapter(pao); | 467 | hpi_delete_adapter(pao); |
477 | phr->error = 0; | 468 | phr->error = 0; |
diff --git a/sound/pci/asihpi/hpi6205.c b/sound/pci/asihpi/hpi6205.c index 22e9f08dea6d..9d5df54a6b46 100644 --- a/sound/pci/asihpi/hpi6205.c +++ b/sound/pci/asihpi/hpi6205.c | |||
@@ -152,8 +152,8 @@ static void hw_message(struct hpi_adapter_obj *pao, struct hpi_message *phm, | |||
152 | 152 | ||
153 | static void subsys_create_adapter(struct hpi_message *phm, | 153 | static void subsys_create_adapter(struct hpi_message *phm, |
154 | struct hpi_response *phr); | 154 | struct hpi_response *phr); |
155 | static void subsys_delete_adapter(struct hpi_message *phm, | 155 | static void adapter_delete(struct hpi_adapter_obj *pao, |
156 | struct hpi_response *phr); | 156 | struct hpi_message *phm, struct hpi_response *phr); |
157 | 157 | ||
158 | static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | 158 | static u16 create_adapter_obj(struct hpi_adapter_obj *pao, |
159 | u32 *pos_error_code); | 159 | u32 *pos_error_code); |
@@ -223,15 +223,13 @@ static u16 boot_loader_test_pld(struct hpi_adapter_obj *pao, int dsp_index); | |||
223 | 223 | ||
224 | /*****************************************************************************/ | 224 | /*****************************************************************************/ |
225 | 225 | ||
226 | static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) | 226 | static void subsys_message(struct hpi_adapter_obj *pao, |
227 | struct hpi_message *phm, struct hpi_response *phr) | ||
227 | { | 228 | { |
228 | switch (phm->function) { | 229 | switch (phm->function) { |
229 | case HPI_SUBSYS_CREATE_ADAPTER: | 230 | case HPI_SUBSYS_CREATE_ADAPTER: |
230 | subsys_create_adapter(phm, phr); | 231 | subsys_create_adapter(phm, phr); |
231 | break; | 232 | break; |
232 | case HPI_SUBSYS_DELETE_ADAPTER: | ||
233 | subsys_delete_adapter(phm, phr); | ||
234 | break; | ||
235 | default: | 233 | default: |
236 | phr->error = HPI_ERROR_INVALID_FUNC; | 234 | phr->error = HPI_ERROR_INVALID_FUNC; |
237 | break; | 235 | break; |
@@ -279,6 +277,10 @@ static void adapter_message(struct hpi_adapter_obj *pao, | |||
279 | struct hpi_message *phm, struct hpi_response *phr) | 277 | struct hpi_message *phm, struct hpi_response *phr) |
280 | { | 278 | { |
281 | switch (phm->function) { | 279 | switch (phm->function) { |
280 | case HPI_ADAPTER_DELETE: | ||
281 | adapter_delete(pao, phm, phr); | ||
282 | break; | ||
283 | |||
282 | default: | 284 | default: |
283 | hw_message(pao, phm, phr); | 285 | hw_message(pao, phm, phr); |
284 | break; | 286 | break; |
@@ -371,36 +373,17 @@ static void instream_message(struct hpi_adapter_obj *pao, | |||
371 | /** Entry point to this HPI backend | 373 | /** Entry point to this HPI backend |
372 | * All calls to the HPI start here | 374 | * All calls to the HPI start here |
373 | */ | 375 | */ |
374 | void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) | 376 | void _HPI_6205(struct hpi_adapter_obj *pao, struct hpi_message *phm, |
377 | struct hpi_response *phr) | ||
375 | { | 378 | { |
376 | struct hpi_adapter_obj *pao = NULL; | 379 | if (pao && (pao->dsp_crashed >= 10) |
377 | 380 | && (phm->function != HPI_ADAPTER_DEBUG_READ)) { | |
378 | /* subsytem messages are processed by every HPI. | 381 | /* allow last resort debug read even after crash */ |
379 | * All other messages are ignored unless the adapter index matches | 382 | hpi_init_response(phr, phm->object, phm->function, |
380 | * an adapter in the HPI | 383 | HPI_ERROR_DSP_HARDWARE); |
381 | */ | 384 | HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", phm->object, |
382 | /* HPI_DEBUG_LOG(DEBUG, "HPI Obj=%d, Func=%d\n", phm->wObject, | 385 | phm->function); |
383 | phm->wFunction); */ | 386 | return; |
384 | |||
385 | /* if Dsp has crashed then do not communicate with it any more */ | ||
386 | if (phm->object != HPI_OBJ_SUBSYSTEM) { | ||
387 | pao = hpi_find_adapter(phm->adapter_index); | ||
388 | if (!pao) { | ||
389 | HPI_DEBUG_LOG(DEBUG, | ||
390 | " %d,%d refused, for another HPI?\n", | ||
391 | phm->object, phm->function); | ||
392 | return; | ||
393 | } | ||
394 | |||
395 | if ((pao->dsp_crashed >= 10) | ||
396 | && (phm->function != HPI_ADAPTER_DEBUG_READ)) { | ||
397 | /* allow last resort debug read even after crash */ | ||
398 | hpi_init_response(phr, phm->object, phm->function, | ||
399 | HPI_ERROR_DSP_HARDWARE); | ||
400 | HPI_DEBUG_LOG(WARNING, " %d,%d dsp crashed.\n", | ||
401 | phm->object, phm->function); | ||
402 | return; | ||
403 | } | ||
404 | } | 387 | } |
405 | 388 | ||
406 | /* Init default response */ | 389 | /* Init default response */ |
@@ -412,7 +395,7 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) | |||
412 | case HPI_TYPE_MESSAGE: | 395 | case HPI_TYPE_MESSAGE: |
413 | switch (phm->object) { | 396 | switch (phm->object) { |
414 | case HPI_OBJ_SUBSYSTEM: | 397 | case HPI_OBJ_SUBSYSTEM: |
415 | subsys_message(phm, phr); | 398 | subsys_message(pao, phm, phr); |
416 | break; | 399 | break; |
417 | 400 | ||
418 | case HPI_OBJ_ADAPTER: | 401 | case HPI_OBJ_ADAPTER: |
@@ -444,6 +427,26 @@ void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) | |||
444 | } | 427 | } |
445 | } | 428 | } |
446 | 429 | ||
430 | void HPI_6205(struct hpi_message *phm, struct hpi_response *phr) | ||
431 | { | ||
432 | struct hpi_adapter_obj *pao = NULL; | ||
433 | |||
434 | if (phm->object != HPI_OBJ_SUBSYSTEM) { | ||
435 | /* normal messages must have valid adapter index */ | ||
436 | pao = hpi_find_adapter(phm->adapter_index); | ||
437 | } else { | ||
438 | /* subsys messages don't address an adapter */ | ||
439 | _HPI_6205(NULL, phm, phr); | ||
440 | return; | ||
441 | } | ||
442 | |||
443 | if (pao) | ||
444 | _HPI_6205(pao, phm, phr); | ||
445 | else | ||
446 | hpi_init_response(phr, phm->object, phm->function, | ||
447 | HPI_ERROR_BAD_ADAPTER_NUMBER); | ||
448 | } | ||
449 | |||
447 | /*****************************************************************************/ | 450 | /*****************************************************************************/ |
448 | /* SUBSYSTEM */ | 451 | /* SUBSYSTEM */ |
449 | 452 | ||
@@ -491,13 +494,11 @@ static void subsys_create_adapter(struct hpi_message *phm, | |||
491 | } | 494 | } |
492 | 495 | ||
493 | /** delete an adapter - required by WDM driver */ | 496 | /** delete an adapter - required by WDM driver */ |
494 | static void subsys_delete_adapter(struct hpi_message *phm, | 497 | static void adapter_delete(struct hpi_adapter_obj *pao, |
495 | struct hpi_response *phr) | 498 | struct hpi_message *phm, struct hpi_response *phr) |
496 | { | 499 | { |
497 | struct hpi_adapter_obj *pao; | ||
498 | struct hpi_hw_obj *phw; | 500 | struct hpi_hw_obj *phw; |
499 | 501 | ||
500 | pao = hpi_find_adapter(phm->obj_index); | ||
501 | if (!pao) { | 502 | if (!pao) { |
502 | phr->error = HPI_ERROR_INVALID_OBJ_INDEX; | 503 | phr->error = HPI_ERROR_INVALID_OBJ_INDEX; |
503 | return; | 504 | return; |
@@ -563,11 +564,12 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
563 | } | 564 | } |
564 | 565 | ||
565 | err = adapter_boot_load_dsp(pao, pos_error_code); | 566 | err = adapter_boot_load_dsp(pao, pos_error_code); |
566 | if (err) | 567 | if (err) { |
568 | HPI_DEBUG_LOG(ERROR, "DSP code load failed\n"); | ||
567 | /* no need to clean up as SubSysCreateAdapter */ | 569 | /* no need to clean up as SubSysCreateAdapter */ |
568 | /* calls DeleteAdapter on error. */ | 570 | /* calls DeleteAdapter on error. */ |
569 | return err; | 571 | return err; |
570 | 572 | } | |
571 | HPI_DEBUG_LOG(INFO, "load DSP code OK\n"); | 573 | HPI_DEBUG_LOG(INFO, "load DSP code OK\n"); |
572 | 574 | ||
573 | /* allow boot load even if mem alloc wont work */ | 575 | /* allow boot load even if mem alloc wont work */ |
@@ -604,6 +606,7 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
604 | control_cache.number_of_controls, | 606 | control_cache.number_of_controls, |
605 | interface->control_cache.size_in_bytes, | 607 | interface->control_cache.size_in_bytes, |
606 | p_control_cache_virtual); | 608 | p_control_cache_virtual); |
609 | |||
607 | if (!phw->p_cache) | 610 | if (!phw->p_cache) |
608 | err = HPI_ERROR_MEMORY_ALLOC; | 611 | err = HPI_ERROR_MEMORY_ALLOC; |
609 | } | 612 | } |
@@ -675,16 +678,14 @@ static u16 create_adapter_obj(struct hpi_adapter_obj *pao, | |||
675 | } | 678 | } |
676 | 679 | ||
677 | /** Free memory areas allocated by adapter | 680 | /** Free memory areas allocated by adapter |
678 | * this routine is called from SubSysDeleteAdapter, | 681 | * this routine is called from AdapterDelete, |
679 | * and SubSysCreateAdapter if duplicate index | 682 | * and SubSysCreateAdapter if duplicate index |
680 | */ | 683 | */ |
681 | static void delete_adapter_obj(struct hpi_adapter_obj *pao) | 684 | static void delete_adapter_obj(struct hpi_adapter_obj *pao) |
682 | { | 685 | { |
683 | struct hpi_hw_obj *phw; | 686 | struct hpi_hw_obj *phw = pao->priv; |
684 | int i; | 687 | int i; |
685 | 688 | ||
686 | phw = pao->priv; | ||
687 | |||
688 | if (hpios_locked_mem_valid(&phw->h_control_cache)) { | 689 | if (hpios_locked_mem_valid(&phw->h_control_cache)) { |
689 | hpios_locked_mem_free(&phw->h_control_cache); | 690 | hpios_locked_mem_free(&phw->h_control_cache); |
690 | hpi_free_control_cache(phw->p_cache); | 691 | hpi_free_control_cache(phw->p_cache); |
@@ -1275,6 +1276,7 @@ static u16 adapter_boot_load_dsp(struct hpi_adapter_obj *pao, | |||
1275 | case HPI_ADAPTER_FAMILY_ASI(0x6300): | 1276 | case HPI_ADAPTER_FAMILY_ASI(0x6300): |
1276 | boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400); | 1277 | boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6400); |
1277 | break; | 1278 | break; |
1279 | case HPI_ADAPTER_FAMILY_ASI(0x5500): | ||
1278 | case HPI_ADAPTER_FAMILY_ASI(0x5600): | 1280 | case HPI_ADAPTER_FAMILY_ASI(0x5600): |
1279 | case HPI_ADAPTER_FAMILY_ASI(0x6500): | 1281 | case HPI_ADAPTER_FAMILY_ASI(0x6500): |
1280 | boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600); | 1282 | boot_code_id[1] = HPI_ADAPTER_FAMILY_ASI(0x6600); |
@@ -2059,7 +2061,6 @@ static int wait_dsp_ack(struct hpi_hw_obj *phw, int state, int timeout_us) | |||
2059 | static void send_dsp_command(struct hpi_hw_obj *phw, int cmd) | 2061 | static void send_dsp_command(struct hpi_hw_obj *phw, int cmd) |
2060 | { | 2062 | { |
2061 | struct bus_master_interface *interface = phw->p_interface_buffer; | 2063 | struct bus_master_interface *interface = phw->p_interface_buffer; |
2062 | |||
2063 | u32 r; | 2064 | u32 r; |
2064 | 2065 | ||
2065 | interface->host_cmd = cmd; | 2066 | interface->host_cmd = cmd; |
diff --git a/sound/pci/asihpi/hpi_internal.h b/sound/pci/asihpi/hpi_internal.h index 3b9fd115da36..bf5eced76bac 100644 --- a/sound/pci/asihpi/hpi_internal.h +++ b/sound/pci/asihpi/hpi_internal.h | |||
@@ -294,7 +294,7 @@ enum HPI_CONTROL_ATTRIBUTES { | |||
294 | 294 | ||
295 | /* These defines are used to fill in protocol information for an Ethernet packet | 295 | /* These defines are used to fill in protocol information for an Ethernet packet |
296 | sent using HMI on CS18102 */ | 296 | sent using HMI on CS18102 */ |
297 | /** ID supplied by Cirrius for ASI packets. */ | 297 | /** ID supplied by Cirrus for ASI packets. */ |
298 | #define HPI_ETHERNET_PACKET_ID 0x85 | 298 | #define HPI_ETHERNET_PACKET_ID 0x85 |
299 | /** Simple packet - no special routing required */ | 299 | /** Simple packet - no special routing required */ |
300 | #define HPI_ETHERNET_PACKET_V1 0x01 | 300 | #define HPI_ETHERNET_PACKET_V1 0x01 |
@@ -307,7 +307,7 @@ enum HPI_CONTROL_ATTRIBUTES { | |||
307 | /** This packet must make its way to the host across the HPI interface */ | 307 | /** This packet must make its way to the host across the HPI interface */ |
308 | #define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41 | 308 | #define HPI_ETHERNET_PACKET_HOSTED_VIA_HPI_V1 0x41 |
309 | 309 | ||
310 | #define HPI_ETHERNET_UDP_PORT (44600) /*!< UDP messaging port */ | 310 | #define HPI_ETHERNET_UDP_PORT 44600 /**< HPI UDP service */ |
311 | 311 | ||
312 | /** Default network timeout in milli-seconds. */ | 312 | /** Default network timeout in milli-seconds. */ |
313 | #define HPI_ETHERNET_TIMEOUT_MS 500 | 313 | #define HPI_ETHERNET_TIMEOUT_MS 500 |
@@ -397,14 +397,14 @@ enum HPI_FUNCTION_IDS { | |||
397 | HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1), | 397 | HPI_SUBSYS_OPEN = HPI_FUNC_ID(SUBSYSTEM, 1), |
398 | HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2), | 398 | HPI_SUBSYS_GET_VERSION = HPI_FUNC_ID(SUBSYSTEM, 2), |
399 | HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3), | 399 | HPI_SUBSYS_GET_INFO = HPI_FUNC_ID(SUBSYSTEM, 3), |
400 | HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), | 400 | /* HPI_SUBSYS_FIND_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 4), */ |
401 | HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5), | 401 | HPI_SUBSYS_CREATE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 5), |
402 | HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6), | 402 | HPI_SUBSYS_CLOSE = HPI_FUNC_ID(SUBSYSTEM, 6), |
403 | HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), | 403 | /* HPI_SUBSYS_DELETE_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 7), */ |
404 | HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8), | 404 | HPI_SUBSYS_DRIVER_LOAD = HPI_FUNC_ID(SUBSYSTEM, 8), |
405 | HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9), | 405 | HPI_SUBSYS_DRIVER_UNLOAD = HPI_FUNC_ID(SUBSYSTEM, 9), |
406 | HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), | 406 | /* HPI_SUBSYS_READ_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 10), */ |
407 | HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), | 407 | /* HPI_SUBSYS_WRITE_PORT_8 = HPI_FUNC_ID(SUBSYSTEM, 11), */ |
408 | HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12), | 408 | HPI_SUBSYS_GET_NUM_ADAPTERS = HPI_FUNC_ID(SUBSYSTEM, 12), |
409 | HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13), | 409 | HPI_SUBSYS_GET_ADAPTER = HPI_FUNC_ID(SUBSYSTEM, 13), |
410 | HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14), | 410 | HPI_SUBSYS_SET_NETWORK_INTERFACE = HPI_FUNC_ID(SUBSYSTEM, 14), |
@@ -433,7 +433,8 @@ enum HPI_FUNCTION_IDS { | |||
433 | HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18), | 433 | HPI_ADAPTER_DEBUG_READ = HPI_FUNC_ID(ADAPTER, 18), |
434 | HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19), | 434 | HPI_ADAPTER_IRQ_QUERY_AND_CLEAR = HPI_FUNC_ID(ADAPTER, 19), |
435 | HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20), | 435 | HPI_ADAPTER_IRQ_CALLBACK = HPI_FUNC_ID(ADAPTER, 20), |
436 | #define HPI_ADAPTER_FUNCTION_COUNT 20 | 436 | HPI_ADAPTER_DELETE = HPI_FUNC_ID(ADAPTER, 21), |
437 | #define HPI_ADAPTER_FUNCTION_COUNT 21 | ||
437 | 438 | ||
438 | HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1), | 439 | HPI_OSTREAM_OPEN = HPI_FUNC_ID(OSTREAM, 1), |
439 | HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2), | 440 | HPI_OSTREAM_CLOSE = HPI_FUNC_ID(OSTREAM, 2), |
@@ -1561,8 +1562,6 @@ void hpi_send_recv(struct hpi_message *phm, struct hpi_response *phr); | |||
1561 | u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, | 1562 | u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, |
1562 | u16 *pw_adapter_index); | 1563 | u16 *pw_adapter_index); |
1563 | 1564 | ||
1564 | u16 hpi_subsys_delete_adapter(u16 adapter_index); | ||
1565 | |||
1566 | u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer, | 1565 | u16 hpi_outstream_host_buffer_get_info(u32 h_outstream, u8 **pp_buffer, |
1567 | struct hpi_hostbuffer_status **pp_status); | 1566 | struct hpi_hostbuffer_status **pp_status); |
1568 | 1567 | ||
@@ -1584,9 +1583,7 @@ void hpi_stream_response_to_legacy(struct hpi_stream_res *pSR); | |||
1584 | 1583 | ||
1585 | /*////////////////////////////////////////////////////////////////////////// */ | 1584 | /*////////////////////////////////////////////////////////////////////////// */ |
1586 | /* declarations for individual HPI entry points */ | 1585 | /* declarations for individual HPI entry points */ |
1587 | hpi_handler_func HPI_1000; | ||
1588 | hpi_handler_func HPI_6000; | 1586 | hpi_handler_func HPI_6000; |
1589 | hpi_handler_func HPI_6205; | 1587 | hpi_handler_func HPI_6205; |
1590 | hpi_handler_func HPI_COMMON; | ||
1591 | 1588 | ||
1592 | #endif /* _HPI_INTERNAL_H_ */ | 1589 | #endif /* _HPI_INTERNAL_H_ */ |
diff --git a/sound/pci/asihpi/hpicmn.c b/sound/pci/asihpi/hpicmn.c index 3e9c5c289764..b15a02e91f82 100644 --- a/sound/pci/asihpi/hpicmn.c +++ b/sound/pci/asihpi/hpicmn.c | |||
@@ -227,8 +227,9 @@ static unsigned int control_cache_alloc_check(struct hpi_control_cache *pC) | |||
227 | if (info->control_type) { | 227 | if (info->control_type) { |
228 | pC->p_info[info->control_index] = info; | 228 | pC->p_info[info->control_index] = info; |
229 | cached++; | 229 | cached++; |
230 | } else /* dummy cache entry */ | 230 | } else { /* dummy cache entry */ |
231 | pC->p_info[info->control_index] = NULL; | 231 | pC->p_info[info->control_index] = NULL; |
232 | } | ||
232 | 233 | ||
233 | byte_count += info->size_in32bit_words * 4; | 234 | byte_count += info->size_in32bit_words * 4; |
234 | 235 | ||
@@ -298,7 +299,7 @@ struct pad_ofs_size { | |||
298 | unsigned int field_size; | 299 | unsigned int field_size; |
299 | }; | 300 | }; |
300 | 301 | ||
301 | static struct pad_ofs_size pad_desc[] = { | 302 | static const struct pad_ofs_size pad_desc[] = { |
302 | HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */ | 303 | HPICMN_PAD_OFS_AND_SIZE(c_channel), /* HPI_PAD_CHANNEL_NAME */ |
303 | HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */ | 304 | HPICMN_PAD_OFS_AND_SIZE(c_artist), /* HPI_PAD_ARTIST */ |
304 | HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */ | 305 | HPICMN_PAD_OFS_AND_SIZE(c_title), /* HPI_PAD_TITLE */ |
@@ -617,6 +618,10 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *p_cache, | |||
617 | } | 618 | } |
618 | } | 619 | } |
619 | 620 | ||
621 | /** Allocate control cache. | ||
622 | |||
623 | \return Cache pointer, or NULL if allocation fails. | ||
624 | */ | ||
620 | struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, | 625 | struct hpi_control_cache *hpi_alloc_control_cache(const u32 control_count, |
621 | const u32 size_in_bytes, u8 *p_dsp_control_buffer) | 626 | const u32 size_in_bytes, u8 *p_dsp_control_buffer) |
622 | { | 627 | { |
@@ -667,7 +672,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr) | |||
667 | phr->u.s.num_adapters = adapters.gw_num_adapters; | 672 | phr->u.s.num_adapters = adapters.gw_num_adapters; |
668 | break; | 673 | break; |
669 | case HPI_SUBSYS_CREATE_ADAPTER: | 674 | case HPI_SUBSYS_CREATE_ADAPTER: |
670 | case HPI_SUBSYS_DELETE_ADAPTER: | ||
671 | break; | 675 | break; |
672 | default: | 676 | default: |
673 | phr->error = HPI_ERROR_INVALID_FUNC; | 677 | phr->error = HPI_ERROR_INVALID_FUNC; |
diff --git a/sound/pci/asihpi/hpicmn.h b/sound/pci/asihpi/hpicmn.h index 590f0b69e655..d53cdf6e535f 100644 --- a/sound/pci/asihpi/hpicmn.h +++ b/sound/pci/asihpi/hpicmn.h | |||
@@ -60,3 +60,5 @@ void hpi_cmn_control_cache_sync_to_msg(struct hpi_control_cache *pC, | |||
60 | struct hpi_message *phm, struct hpi_response *phr); | 60 | struct hpi_message *phm, struct hpi_response *phr); |
61 | 61 | ||
62 | u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); | 62 | u16 hpi_validate_response(struct hpi_message *phm, struct hpi_response *phr); |
63 | |||
64 | hpi_handler_func HPI_COMMON; | ||
diff --git a/sound/pci/asihpi/hpifunc.c b/sound/pci/asihpi/hpifunc.c index c38fc9487560..7397b169b89f 100644 --- a/sound/pci/asihpi/hpifunc.c +++ b/sound/pci/asihpi/hpifunc.c | |||
@@ -105,33 +105,6 @@ u16 hpi_subsys_get_version_ex(u32 *pversion_ex) | |||
105 | return hr.error; | 105 | return hr.error; |
106 | } | 106 | } |
107 | 107 | ||
108 | u16 hpi_subsys_create_adapter(const struct hpi_resource *p_resource, | ||
109 | u16 *pw_adapter_index) | ||
110 | { | ||
111 | struct hpi_message hm; | ||
112 | struct hpi_response hr; | ||
113 | |||
114 | hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, | ||
115 | HPI_SUBSYS_CREATE_ADAPTER); | ||
116 | hm.u.s.resource = *p_resource; | ||
117 | |||
118 | hpi_send_recv(&hm, &hr); | ||
119 | |||
120 | *pw_adapter_index = hr.u.s.adapter_index; | ||
121 | return hr.error; | ||
122 | } | ||
123 | |||
124 | u16 hpi_subsys_delete_adapter(u16 adapter_index) | ||
125 | { | ||
126 | struct hpi_message hm; | ||
127 | struct hpi_response hr; | ||
128 | hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, | ||
129 | HPI_SUBSYS_DELETE_ADAPTER); | ||
130 | hm.obj_index = adapter_index; | ||
131 | hpi_send_recv(&hm, &hr); | ||
132 | return hr.error; | ||
133 | } | ||
134 | |||
135 | u16 hpi_subsys_get_num_adapters(int *pn_num_adapters) | 108 | u16 hpi_subsys_get_num_adapters(int *pn_num_adapters) |
136 | { | 109 | { |
137 | struct hpi_message hm; | 110 | struct hpi_message hm; |
diff --git a/sound/pci/asihpi/hpimsgx.c b/sound/pci/asihpi/hpimsgx.c index 360028b9abf5..7352a5f7b4f7 100644 --- a/sound/pci/asihpi/hpimsgx.c +++ b/sound/pci/asihpi/hpimsgx.c | |||
@@ -211,24 +211,6 @@ static void subsys_message(struct hpi_message *phm, struct hpi_response *phr, | |||
211 | HPIMSGX__init(phm, phr); | 211 | HPIMSGX__init(phm, phr); |
212 | break; | 212 | break; |
213 | 213 | ||
214 | case HPI_SUBSYS_DELETE_ADAPTER: | ||
215 | HPIMSGX__cleanup(phm->obj_index, h_owner); | ||
216 | { | ||
217 | struct hpi_message hm; | ||
218 | struct hpi_response hr; | ||
219 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, | ||
220 | HPI_ADAPTER_CLOSE); | ||
221 | hm.adapter_index = phm->obj_index; | ||
222 | hw_entry_point(&hm, &hr); | ||
223 | } | ||
224 | if ((phm->obj_index < HPI_MAX_ADAPTERS) | ||
225 | && hpi_entry_points[phm->obj_index]) { | ||
226 | hpi_entry_points[phm->obj_index] (phm, phr); | ||
227 | hpi_entry_points[phm->obj_index] = NULL; | ||
228 | } else | ||
229 | phr->error = HPI_ERROR_INVALID_OBJ_INDEX; | ||
230 | |||
231 | break; | ||
232 | default: | 214 | default: |
233 | /* Must explicitly handle every subsys message in this switch */ | 215 | /* Must explicitly handle every subsys message in this switch */ |
234 | hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, | 216 | hpi_init_response(phr, HPI_OBJ_SUBSYSTEM, phm->function, |
@@ -247,6 +229,19 @@ static void adapter_message(struct hpi_message *phm, struct hpi_response *phr, | |||
247 | case HPI_ADAPTER_CLOSE: | 229 | case HPI_ADAPTER_CLOSE: |
248 | adapter_close(phm, phr); | 230 | adapter_close(phm, phr); |
249 | break; | 231 | break; |
232 | case HPI_ADAPTER_DELETE: | ||
233 | HPIMSGX__cleanup(phm->adapter_index, h_owner); | ||
234 | { | ||
235 | struct hpi_message hm; | ||
236 | struct hpi_response hr; | ||
237 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, | ||
238 | HPI_ADAPTER_CLOSE); | ||
239 | hm.adapter_index = phm->adapter_index; | ||
240 | hw_entry_point(&hm, &hr); | ||
241 | } | ||
242 | hw_entry_point(phm, phr); | ||
243 | break; | ||
244 | |||
250 | default: | 245 | default: |
251 | hw_entry_point(phm, phr); | 246 | hw_entry_point(phm, phr); |
252 | break; | 247 | break; |
diff --git a/sound/pci/asihpi/hpioctl.c b/sound/pci/asihpi/hpioctl.c index cd624f13ff8e..d8e7047512f8 100644 --- a/sound/pci/asihpi/hpioctl.c +++ b/sound/pci/asihpi/hpioctl.c | |||
@@ -25,6 +25,7 @@ Common Linux HPI ioctl and module probe/remove functions | |||
25 | #include "hpidebug.h" | 25 | #include "hpidebug.h" |
26 | #include "hpimsgx.h" | 26 | #include "hpimsgx.h" |
27 | #include "hpioctl.h" | 27 | #include "hpioctl.h" |
28 | #include "hpicmn.h" | ||
28 | 29 | ||
29 | #include <linux/fs.h> | 30 | #include <linux/fs.h> |
30 | #include <linux/slab.h> | 31 | #include <linux/slab.h> |
@@ -161,26 +162,24 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
161 | goto out; | 162 | goto out; |
162 | } | 163 | } |
163 | 164 | ||
164 | pa = &adapters[hm->h.adapter_index]; | 165 | switch (hm->h.function) { |
166 | case HPI_SUBSYS_CREATE_ADAPTER: | ||
167 | case HPI_ADAPTER_DELETE: | ||
168 | /* Application must not use these functions! */ | ||
169 | hr->h.size = sizeof(hr->h); | ||
170 | hr->h.error = HPI_ERROR_INVALID_OPERATION; | ||
171 | hr->h.function = hm->h.function; | ||
172 | uncopied_bytes = copy_to_user(puhr, hr, hr->h.size); | ||
173 | if (uncopied_bytes) | ||
174 | err = -EFAULT; | ||
175 | else | ||
176 | err = 0; | ||
177 | goto out; | ||
178 | } | ||
179 | |||
165 | hr->h.size = res_max_size; | 180 | hr->h.size = res_max_size; |
166 | if (hm->h.object == HPI_OBJ_SUBSYSTEM) { | 181 | if (hm->h.object == HPI_OBJ_SUBSYSTEM) { |
167 | switch (hm->h.function) { | 182 | hpi_send_recv_f(&hm->m0, &hr->r0, file); |
168 | case HPI_SUBSYS_CREATE_ADAPTER: | ||
169 | case HPI_SUBSYS_DELETE_ADAPTER: | ||
170 | /* Application must not use these functions! */ | ||
171 | hr->h.size = sizeof(hr->h); | ||
172 | hr->h.error = HPI_ERROR_INVALID_OPERATION; | ||
173 | hr->h.function = hm->h.function; | ||
174 | uncopied_bytes = copy_to_user(puhr, hr, hr->h.size); | ||
175 | if (uncopied_bytes) | ||
176 | err = -EFAULT; | ||
177 | else | ||
178 | err = 0; | ||
179 | goto out; | ||
180 | |||
181 | default: | ||
182 | hpi_send_recv_f(&hm->m0, &hr->r0, file); | ||
183 | } | ||
184 | } else { | 183 | } else { |
185 | u16 __user *ptr = NULL; | 184 | u16 __user *ptr = NULL; |
186 | u32 size = 0; | 185 | u32 size = 0; |
@@ -188,8 +187,9 @@ long asihpi_hpi_ioctl(struct file *file, unsigned int cmd, unsigned long arg) | |||
188 | /* -1=no data 0=read from user mem, 1=write to user mem */ | 187 | /* -1=no data 0=read from user mem, 1=write to user mem */ |
189 | int wrflag = -1; | 188 | int wrflag = -1; |
190 | u32 adapter = hm->h.adapter_index; | 189 | u32 adapter = hm->h.adapter_index; |
190 | pa = &adapters[adapter]; | ||
191 | 191 | ||
192 | if ((hm->h.adapter_index > HPI_MAX_ADAPTERS) || (!pa->type)) { | 192 | if ((adapter > HPI_MAX_ADAPTERS) || (!pa->type)) { |
193 | hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, | 193 | hpi_init_response(&hr->r0, HPI_OBJ_ADAPTER, |
194 | HPI_ADAPTER_OPEN, | 194 | HPI_ADAPTER_OPEN, |
195 | HPI_ERROR_BAD_ADAPTER_NUMBER); | 195 | HPI_ERROR_BAD_ADAPTER_NUMBER); |
@@ -317,7 +317,7 @@ out: | |||
317 | int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, | 317 | int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, |
318 | const struct pci_device_id *pci_id) | 318 | const struct pci_device_id *pci_id) |
319 | { | 319 | { |
320 | int err, idx, nm; | 320 | int idx, nm; |
321 | unsigned int memlen; | 321 | unsigned int memlen; |
322 | struct hpi_message hm; | 322 | struct hpi_message hm; |
323 | struct hpi_response hr; | 323 | struct hpi_response hr; |
@@ -351,11 +351,8 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, | |||
351 | nm = HPI_MAX_ADAPTER_MEM_SPACES; | 351 | nm = HPI_MAX_ADAPTER_MEM_SPACES; |
352 | 352 | ||
353 | for (idx = 0; idx < nm; idx++) { | 353 | for (idx = 0; idx < nm; idx++) { |
354 | HPI_DEBUG_LOG(INFO, "resource %d %s %08llx-%08llx %04llx\n", | 354 | HPI_DEBUG_LOG(INFO, "resource %d %pR\n", idx, |
355 | idx, pci_dev->resource[idx].name, | 355 | &pci_dev->resource[idx]); |
356 | (unsigned long long)pci_resource_start(pci_dev, idx), | ||
357 | (unsigned long long)pci_resource_end(pci_dev, idx), | ||
358 | (unsigned long long)pci_resource_flags(pci_dev, idx)); | ||
359 | 356 | ||
360 | if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) { | 357 | if (pci_resource_flags(pci_dev, idx) & IORESOURCE_MEM) { |
361 | memlen = pci_resource_len(pci_dev, idx); | 358 | memlen = pci_resource_len(pci_dev, idx); |
@@ -395,17 +392,20 @@ int __devinit asihpi_adapter_probe(struct pci_dev *pci_dev, | |||
395 | 392 | ||
396 | adapter.index = hr.u.s.adapter_index; | 393 | adapter.index = hr.u.s.adapter_index; |
397 | adapter.type = hr.u.s.adapter_type; | 394 | adapter.type = hr.u.s.adapter_type; |
395 | |||
396 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, | ||
397 | HPI_ADAPTER_OPEN); | ||
398 | hm.adapter_index = adapter.index; | 398 | hm.adapter_index = adapter.index; |
399 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); | ||
399 | 400 | ||
400 | err = hpi_adapter_open(adapter.index); | 401 | if (hr.error) |
401 | if (err) | ||
402 | goto err; | 402 | goto err; |
403 | 403 | ||
404 | adapter.snd_card_asihpi = NULL; | 404 | adapter.snd_card_asihpi = NULL; |
405 | /* WARNING can't init mutex in 'adapter' | 405 | /* WARNING can't init mutex in 'adapter' |
406 | * and then copy it to adapters[] ?!?! | 406 | * and then copy it to adapters[] ?!?! |
407 | */ | 407 | */ |
408 | adapters[hr.u.s.adapter_index] = adapter; | 408 | adapters[adapter.index] = adapter; |
409 | mutex_init(&adapters[adapter.index].mutex); | 409 | mutex_init(&adapters[adapter.index].mutex); |
410 | pci_set_drvdata(pci_dev, &adapters[adapter.index]); | 410 | pci_set_drvdata(pci_dev, &adapters[adapter.index]); |
411 | 411 | ||
@@ -440,10 +440,9 @@ void __devexit asihpi_adapter_remove(struct pci_dev *pci_dev) | |||
440 | struct hpi_adapter *pa; | 440 | struct hpi_adapter *pa; |
441 | pa = pci_get_drvdata(pci_dev); | 441 | pa = pci_get_drvdata(pci_dev); |
442 | 442 | ||
443 | hpi_init_message_response(&hm, &hr, HPI_OBJ_SUBSYSTEM, | 443 | hpi_init_message_response(&hm, &hr, HPI_OBJ_ADAPTER, |
444 | HPI_SUBSYS_DELETE_ADAPTER); | 444 | HPI_ADAPTER_DELETE); |
445 | hm.obj_index = pa->index; | 445 | hm.adapter_index = pa->index; |
446 | hm.adapter_index = HPI_ADAPTER_INDEX_INVALID; | ||
447 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); | 446 | hpi_send_recv_ex(&hm, &hr, HOWNER_KERNEL); |
448 | 447 | ||
449 | /* unmap PCI memory space, mapped during device init. */ | 448 | /* unmap PCI memory space, mapped during device init. */ |
diff --git a/sound/pci/au88x0/au8810.h b/sound/pci/au88x0/au8810.h index 5d69c31fe3f4..79fbee3845eb 100644 --- a/sound/pci/au88x0/au8810.h +++ b/sound/pci/au88x0/au8810.h | |||
@@ -4,7 +4,7 @@ | |||
4 | 4 | ||
5 | #define CHIP_AU8810 | 5 | #define CHIP_AU8810 |
6 | 6 | ||
7 | #define CARD_NAME "Aureal Advantage 3D Sound Processor" | 7 | #define CARD_NAME "Aureal Advantage" |
8 | #define CARD_NAME_SHORT "au8810" | 8 | #define CARD_NAME_SHORT "au8810" |
9 | 9 | ||
10 | #define NR_ADB 0x10 | 10 | #define NR_ADB 0x10 |
diff --git a/sound/pci/au88x0/au8820.h b/sound/pci/au88x0/au8820.h index abbe85e4f7a9..cafdb9668a34 100644 --- a/sound/pci/au88x0/au8820.h +++ b/sound/pci/au88x0/au8820.h | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | #define CHIP_AU8820 | 12 | #define CHIP_AU8820 |
13 | 13 | ||
14 | #define CARD_NAME "Aureal Vortex 3D Sound Processor" | 14 | #define CARD_NAME "Aureal Vortex" |
15 | #define CARD_NAME_SHORT "au8820" | 15 | #define CARD_NAME_SHORT "au8820" |
16 | 16 | ||
17 | /* Number of ADB and WT channels */ | 17 | /* Number of ADB and WT channels */ |
diff --git a/sound/pci/au88x0/au8830.h b/sound/pci/au88x0/au8830.h index 04ece1b1c218..999b29ab34ad 100644 --- a/sound/pci/au88x0/au8830.h +++ b/sound/pci/au88x0/au8830.h | |||
@@ -11,7 +11,7 @@ | |||
11 | 11 | ||
12 | #define CHIP_AU8830 | 12 | #define CHIP_AU8830 |
13 | 13 | ||
14 | #define CARD_NAME "Aureal Vortex 2 3D Sound Processor" | 14 | #define CARD_NAME "Aureal Vortex 2" |
15 | #define CARD_NAME_SHORT "au8830" | 15 | #define CARD_NAME_SHORT "au8830" |
16 | 16 | ||
17 | #define NR_ADB 0x20 | 17 | #define NR_ADB 0x20 |
diff --git a/sound/pci/au88x0/au88x0_pcm.c b/sound/pci/au88x0/au88x0_pcm.c index 33f0ba5559a7..c5f7ae46afef 100644 --- a/sound/pci/au88x0/au88x0_pcm.c +++ b/sound/pci/au88x0/au88x0_pcm.c | |||
@@ -44,10 +44,10 @@ static struct snd_pcm_hardware snd_vortex_playback_hw_adb = { | |||
44 | .channels_min = 1, | 44 | .channels_min = 1, |
45 | .channels_max = 2, | 45 | .channels_max = 2, |
46 | .buffer_bytes_max = 0x10000, | 46 | .buffer_bytes_max = 0x10000, |
47 | .period_bytes_min = 0x1, | 47 | .period_bytes_min = 0x20, |
48 | .period_bytes_max = 0x1000, | 48 | .period_bytes_max = 0x1000, |
49 | .periods_min = 2, | 49 | .periods_min = 2, |
50 | .periods_max = 32, | 50 | .periods_max = 1024, |
51 | }; | 51 | }; |
52 | 52 | ||
53 | #ifndef CHIP_AU8820 | 53 | #ifndef CHIP_AU8820 |
@@ -140,6 +140,9 @@ static int snd_vortex_pcm_open(struct snd_pcm_substream *substream) | |||
140 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0) | 140 | SNDRV_PCM_HW_PARAM_PERIOD_BYTES)) < 0) |
141 | return err; | 141 | return err; |
142 | 142 | ||
143 | snd_pcm_hw_constraint_step(runtime, 0, | ||
144 | SNDRV_PCM_HW_PARAM_BUFFER_BYTES, 64); | ||
145 | |||
143 | if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { | 146 | if (VORTEX_PCM_TYPE(substream->pcm) != VORTEX_PCM_WT) { |
144 | #ifndef CHIP_AU8820 | 147 | #ifndef CHIP_AU8820 |
145 | if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) { | 148 | if (VORTEX_PCM_TYPE(substream->pcm) == VORTEX_PCM_A3D) { |
@@ -423,11 +426,11 @@ static struct snd_pcm_ops snd_vortex_playback_ops = { | |||
423 | */ | 426 | */ |
424 | 427 | ||
425 | static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = { | 428 | static char *vortex_pcm_prettyname[VORTEX_PCM_LAST] = { |
426 | "AU88x0 ADB", | 429 | CARD_NAME " ADB", |
427 | "AU88x0 SPDIF", | 430 | CARD_NAME " SPDIF", |
428 | "AU88x0 A3D", | 431 | CARD_NAME " A3D", |
429 | "AU88x0 WT", | 432 | CARD_NAME " WT", |
430 | "AU88x0 I2S", | 433 | CARD_NAME " I2S", |
431 | }; | 434 | }; |
432 | static char *vortex_pcm_name[VORTEX_PCM_LAST] = { | 435 | static char *vortex_pcm_name[VORTEX_PCM_LAST] = { |
433 | "adb", | 436 | "adb", |
@@ -524,7 +527,8 @@ static int __devinit snd_vortex_new_pcm(vortex_t *chip, int idx, int nr) | |||
524 | nr_capt, &pcm); | 527 | nr_capt, &pcm); |
525 | if (err < 0) | 528 | if (err < 0) |
526 | return err; | 529 | return err; |
527 | strcpy(pcm->name, vortex_pcm_name[idx]); | 530 | snprintf(pcm->name, sizeof(pcm->name), |
531 | "%s %s", CARD_NAME_SHORT, vortex_pcm_name[idx]); | ||
528 | chip->pcm[idx] = pcm; | 532 | chip->pcm[idx] = pcm; |
529 | // This is an evil hack, but it saves a lot of duplicated code. | 533 | // This is an evil hack, but it saves a lot of duplicated code. |
530 | VORTEX_PCM_TYPE(pcm) = idx; | 534 | VORTEX_PCM_TYPE(pcm) = idx; |
diff --git a/sound/pci/emu10k1/emufx.c b/sound/pci/emu10k1/emufx.c index 7a9401462c1c..dae4050ede5c 100644 --- a/sound/pci/emu10k1/emufx.c +++ b/sound/pci/emu10k1/emufx.c | |||
@@ -303,6 +303,9 @@ static const u32 db_table[101] = { | |||
303 | static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); | 303 | static const DECLARE_TLV_DB_SCALE(snd_emu10k1_db_scale1, -4000, 40, 1); |
304 | static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0); | 304 | static const DECLARE_TLV_DB_LINEAR(snd_emu10k1_db_linear, TLV_DB_GAIN_MUTE, 0); |
305 | 305 | ||
306 | /* EMU10K1 bass/treble db gain */ | ||
307 | static const DECLARE_TLV_DB_SCALE(snd_emu10k1_bass_treble_db_scale, -1200, 60, 0); | ||
308 | |||
306 | static const u32 onoff_table[2] = { | 309 | static const u32 onoff_table[2] = { |
307 | 0x00000000, 0x00000001 | 310 | 0x00000000, 0x00000001 |
308 | }; | 311 | }; |
@@ -2163,6 +2166,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) | |||
2163 | ctl->min = 0; | 2166 | ctl->min = 0; |
2164 | ctl->max = 40; | 2167 | ctl->max = 40; |
2165 | ctl->value[0] = ctl->value[1] = 20; | 2168 | ctl->value[0] = ctl->value[1] = 20; |
2169 | ctl->tlv = snd_emu10k1_bass_treble_db_scale; | ||
2166 | ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; | 2170 | ctl->translation = EMU10K1_GPR_TRANSLATION_BASS; |
2167 | ctl = &controls[i + 1]; | 2171 | ctl = &controls[i + 1]; |
2168 | ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 2172 | ctl->id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
@@ -2172,6 +2176,7 @@ static int __devinit _snd_emu10k1_init_efx(struct snd_emu10k1 *emu) | |||
2172 | ctl->min = 0; | 2176 | ctl->min = 0; |
2173 | ctl->max = 40; | 2177 | ctl->max = 40; |
2174 | ctl->value[0] = ctl->value[1] = 20; | 2178 | ctl->value[0] = ctl->value[1] = 20; |
2179 | ctl->tlv = snd_emu10k1_bass_treble_db_scale; | ||
2175 | ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE; | 2180 | ctl->translation = EMU10K1_GPR_TRANSLATION_TREBLE; |
2176 | 2181 | ||
2177 | #define BASS_GPR 0x8c | 2182 | #define BASS_GPR 0x8c |
diff --git a/sound/pci/emu10k1/emumixer.c b/sound/pci/emu10k1/emumixer.c index 05afe06e353a..9d890a5aec5a 100644 --- a/sound/pci/emu10k1/emumixer.c +++ b/sound/pci/emu10k1/emumixer.c | |||
@@ -1729,8 +1729,6 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, | |||
1729 | "Master Mono Playback Volume", | 1729 | "Master Mono Playback Volume", |
1730 | "PCM Out Path & Mute", | 1730 | "PCM Out Path & Mute", |
1731 | "Mono Output Select", | 1731 | "Mono Output Select", |
1732 | "Front Playback Switch", | ||
1733 | "Front Playback Volume", | ||
1734 | "Surround Playback Switch", | 1732 | "Surround Playback Switch", |
1735 | "Surround Playback Volume", | 1733 | "Surround Playback Volume", |
1736 | "Center Playback Switch", | 1734 | "Center Playback Switch", |
@@ -1879,6 +1877,8 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, | |||
1879 | emu->rear_ac97 = 1; | 1877 | emu->rear_ac97 = 1; |
1880 | snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT); | 1878 | snd_emu10k1_ptr_write(emu, AC97SLOT, 0, AC97SLOT_CNTR|AC97SLOT_LFE|AC97SLOT_REAR_LEFT|AC97SLOT_REAR_RIGHT); |
1881 | snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202); | 1879 | snd_ac97_write_cache(emu->ac97, AC97_HEADPHONE, 0x0202); |
1880 | remove_ctl(card,"Front Playback Volume"); | ||
1881 | remove_ctl(card,"Front Playback Switch"); | ||
1882 | } | 1882 | } |
1883 | /* remove unused AC97 controls */ | 1883 | /* remove unused AC97 controls */ |
1884 | snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202); | 1884 | snd_ac97_write_cache(emu->ac97, AC97_SURROUND_MASTER, 0x0202); |
@@ -1913,6 +1913,12 @@ int __devinit snd_emu10k1_mixer(struct snd_emu10k1 *emu, | |||
1913 | for (; *c; c += 2) | 1913 | for (; *c; c += 2) |
1914 | rename_ctl(card, c[0], c[1]); | 1914 | rename_ctl(card, c[0], c[1]); |
1915 | 1915 | ||
1916 | if (emu->card_capabilities->subsystem == 0x80401102) { /* SB Live! Platinum CT4760P */ | ||
1917 | remove_ctl(card, "Center Playback Volume"); | ||
1918 | remove_ctl(card, "LFE Playback Volume"); | ||
1919 | remove_ctl(card, "Wave Center Playback Volume"); | ||
1920 | remove_ctl(card, "Wave LFE Playback Volume"); | ||
1921 | } | ||
1916 | if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ | 1922 | if (emu->card_capabilities->subsystem == 0x20071102) { /* Audigy 4 Pro */ |
1917 | rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume"); | 1923 | rename_ctl(card, "Line2 Capture Volume", "Line1/Mic Capture Volume"); |
1918 | rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume"); | 1924 | rename_ctl(card, "Analog Mix Capture Volume", "Line2 Capture Volume"); |
diff --git a/sound/pci/es1968.c b/sound/pci/es1968.c index 7c17f45d876d..ab0a6156a704 100644 --- a/sound/pci/es1968.c +++ b/sound/pci/es1968.c | |||
@@ -112,6 +112,10 @@ | |||
112 | #include <sound/ac97_codec.h> | 112 | #include <sound/ac97_codec.h> |
113 | #include <sound/initval.h> | 113 | #include <sound/initval.h> |
114 | 114 | ||
115 | #ifdef CONFIG_SND_ES1968_RADIO | ||
116 | #include <sound/tea575x-tuner.h> | ||
117 | #endif | ||
118 | |||
115 | #define CARD_NAME "ESS Maestro1/2" | 119 | #define CARD_NAME "ESS Maestro1/2" |
116 | #define DRIVER_NAME "ES1968" | 120 | #define DRIVER_NAME "ES1968" |
117 | 121 | ||
@@ -553,6 +557,10 @@ struct es1968 { | |||
553 | spinlock_t ac97_lock; | 557 | spinlock_t ac97_lock; |
554 | struct tasklet_struct hwvol_tq; | 558 | struct tasklet_struct hwvol_tq; |
555 | #endif | 559 | #endif |
560 | |||
561 | #ifdef CONFIG_SND_ES1968_RADIO | ||
562 | struct snd_tea575x tea; | ||
563 | #endif | ||
556 | }; | 564 | }; |
557 | 565 | ||
558 | static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); | 566 | static irqreturn_t snd_es1968_interrupt(int irq, void *dev_id); |
@@ -2571,6 +2579,63 @@ static int __devinit snd_es1968_input_register(struct es1968 *chip) | |||
2571 | } | 2579 | } |
2572 | #endif /* CONFIG_SND_ES1968_INPUT */ | 2580 | #endif /* CONFIG_SND_ES1968_INPUT */ |
2573 | 2581 | ||
2582 | #ifdef CONFIG_SND_ES1968_RADIO | ||
2583 | #define GPIO_DATA 0x60 | ||
2584 | #define IO_MASK 4 /* mask register offset from GPIO_DATA | ||
2585 | bits 1=unmask write to given bit */ | ||
2586 | #define IO_DIR 8 /* direction register offset from GPIO_DATA | ||
2587 | bits 0/1=read/write direction */ | ||
2588 | /* mask bits for GPIO lines */ | ||
2589 | #define STR_DATA 0x0040 /* GPIO6 */ | ||
2590 | #define STR_CLK 0x0080 /* GPIO7 */ | ||
2591 | #define STR_WREN 0x0100 /* GPIO8 */ | ||
2592 | #define STR_MOST 0x0200 /* GPIO9 */ | ||
2593 | |||
2594 | static void snd_es1968_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) | ||
2595 | { | ||
2596 | struct es1968 *chip = tea->private_data; | ||
2597 | unsigned long io = chip->io_port + GPIO_DATA; | ||
2598 | u16 val = 0; | ||
2599 | |||
2600 | val |= (pins & TEA575X_DATA) ? STR_DATA : 0; | ||
2601 | val |= (pins & TEA575X_CLK) ? STR_CLK : 0; | ||
2602 | val |= (pins & TEA575X_WREN) ? STR_WREN : 0; | ||
2603 | |||
2604 | outw(val, io); | ||
2605 | } | ||
2606 | |||
2607 | static u8 snd_es1968_tea575x_get_pins(struct snd_tea575x *tea) | ||
2608 | { | ||
2609 | struct es1968 *chip = tea->private_data; | ||
2610 | unsigned long io = chip->io_port + GPIO_DATA; | ||
2611 | u16 val = inw(io); | ||
2612 | |||
2613 | return (val & STR_DATA) ? TEA575X_DATA : 0 | | ||
2614 | (val & STR_MOST) ? TEA575X_MOST : 0; | ||
2615 | } | ||
2616 | |||
2617 | static void snd_es1968_tea575x_set_direction(struct snd_tea575x *tea, bool output) | ||
2618 | { | ||
2619 | struct es1968 *chip = tea->private_data; | ||
2620 | unsigned long io = chip->io_port + GPIO_DATA; | ||
2621 | u16 odir = inw(io + IO_DIR); | ||
2622 | |||
2623 | if (output) { | ||
2624 | outw(~(STR_DATA | STR_CLK | STR_WREN), io + IO_MASK); | ||
2625 | outw(odir | STR_DATA | STR_CLK | STR_WREN, io + IO_DIR); | ||
2626 | } else { | ||
2627 | outw(~(STR_CLK | STR_WREN | STR_DATA | STR_MOST), io + IO_MASK); | ||
2628 | outw((odir & ~(STR_DATA | STR_MOST)) | STR_CLK | STR_WREN, io + IO_DIR); | ||
2629 | } | ||
2630 | } | ||
2631 | |||
2632 | static struct snd_tea575x_ops snd_es1968_tea_ops = { | ||
2633 | .set_pins = snd_es1968_tea575x_set_pins, | ||
2634 | .get_pins = snd_es1968_tea575x_get_pins, | ||
2635 | .set_direction = snd_es1968_tea575x_set_direction, | ||
2636 | }; | ||
2637 | #endif | ||
2638 | |||
2574 | static int snd_es1968_free(struct es1968 *chip) | 2639 | static int snd_es1968_free(struct es1968 *chip) |
2575 | { | 2640 | { |
2576 | #ifdef CONFIG_SND_ES1968_INPUT | 2641 | #ifdef CONFIG_SND_ES1968_INPUT |
@@ -2585,6 +2650,10 @@ static int snd_es1968_free(struct es1968 *chip) | |||
2585 | outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */ | 2650 | outw(0, chip->io_port + ESM_PORT_HOST_IRQ); /* disable IRQ */ |
2586 | } | 2651 | } |
2587 | 2652 | ||
2653 | #ifdef CONFIG_SND_ES1968_RADIO | ||
2654 | snd_tea575x_exit(&chip->tea); | ||
2655 | #endif | ||
2656 | |||
2588 | if (chip->irq >= 0) | 2657 | if (chip->irq >= 0) |
2589 | free_irq(chip->irq, chip); | 2658 | free_irq(chip->irq, chip); |
2590 | snd_es1968_free_gameport(chip); | 2659 | snd_es1968_free_gameport(chip); |
@@ -2723,6 +2792,15 @@ static int __devinit snd_es1968_create(struct snd_card *card, | |||
2723 | 2792 | ||
2724 | snd_card_set_dev(card, &pci->dev); | 2793 | snd_card_set_dev(card, &pci->dev); |
2725 | 2794 | ||
2795 | #ifdef CONFIG_SND_ES1968_RADIO | ||
2796 | chip->tea.private_data = chip; | ||
2797 | chip->tea.ops = &snd_es1968_tea_ops; | ||
2798 | strlcpy(chip->tea.card, "SF64-PCE2", sizeof(chip->tea.card)); | ||
2799 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | ||
2800 | if (!snd_tea575x_init(&chip->tea)) | ||
2801 | printk(KERN_INFO "es1968: detected TEA575x radio\n"); | ||
2802 | #endif | ||
2803 | |||
2726 | *chip_ret = chip; | 2804 | *chip_ret = chip; |
2727 | 2805 | ||
2728 | return 0; | 2806 | return 0; |
diff --git a/sound/pci/fm801.c b/sound/pci/fm801.c index e1baad74ea4b..eacd4901a308 100644 --- a/sound/pci/fm801.c +++ b/sound/pci/fm801.c | |||
@@ -38,7 +38,6 @@ | |||
38 | 38 | ||
39 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL | 39 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
40 | #include <sound/tea575x-tuner.h> | 40 | #include <sound/tea575x-tuner.h> |
41 | #define TEA575X_RADIO 1 | ||
42 | #endif | 41 | #endif |
43 | 42 | ||
44 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); | 43 | MODULE_AUTHOR("Jaroslav Kysela <perex@perex.cz>"); |
@@ -53,7 +52,7 @@ static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; /* Enable this card * | |||
53 | /* | 52 | /* |
54 | * Enable TEA575x tuner | 53 | * Enable TEA575x tuner |
55 | * 1 = MediaForte 256-PCS | 54 | * 1 = MediaForte 256-PCS |
56 | * 2 = MediaForte 256-PCPR | 55 | * 2 = MediaForte 256-PCP |
57 | * 3 = MediaForte 64-PCR | 56 | * 3 = MediaForte 64-PCR |
58 | * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card | 57 | * 16 = setup tuner only (this is additional bit), i.e. SF64-PCR FM card |
59 | * High 16-bits are video (radio) device number + 1 | 58 | * High 16-bits are video (radio) device number + 1 |
@@ -67,7 +66,7 @@ MODULE_PARM_DESC(id, "ID string for the FM801 soundcard."); | |||
67 | module_param_array(enable, bool, NULL, 0444); | 66 | module_param_array(enable, bool, NULL, 0444); |
68 | MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); | 67 | MODULE_PARM_DESC(enable, "Enable FM801 soundcard."); |
69 | module_param_array(tea575x_tuner, int, NULL, 0444); | 68 | module_param_array(tea575x_tuner, int, NULL, 0444); |
70 | MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (1 = SF256-PCS, 2=SF256-PCPR, 3=SF64-PCR, +16=tuner-only)."); | 69 | MODULE_PARM_DESC(tea575x_tuner, "TEA575x tuner access method (0 = auto, 1 = SF256-PCS, 2=SF256-PCP, 3=SF64-PCR, 8=disable, +16=tuner-only)."); |
71 | 70 | ||
72 | #define TUNER_ONLY (1<<4) | 71 | #define TUNER_ONLY (1<<4) |
73 | #define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF) | 72 | #define TUNER_TYPE_MASK (~TUNER_ONLY & 0xFFFF) |
@@ -196,7 +195,7 @@ struct fm801 { | |||
196 | spinlock_t reg_lock; | 195 | spinlock_t reg_lock; |
197 | struct snd_info_entry *proc_entry; | 196 | struct snd_info_entry *proc_entry; |
198 | 197 | ||
199 | #ifdef TEA575X_RADIO | 198 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
200 | struct snd_tea575x tea; | 199 | struct snd_tea575x tea; |
201 | #endif | 200 | #endif |
202 | 201 | ||
@@ -715,310 +714,89 @@ static int __devinit snd_fm801_pcm(struct fm801 *chip, int device, struct snd_pc | |||
715 | * TEA5757 radio | 714 | * TEA5757 radio |
716 | */ | 715 | */ |
717 | 716 | ||
718 | #ifdef TEA575X_RADIO | 717 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
719 | |||
720 | /* 256PCS GPIO numbers */ | ||
721 | #define TEA_256PCS_DATA 1 | ||
722 | #define TEA_256PCS_WRITE_ENABLE 2 /* inverted */ | ||
723 | #define TEA_256PCS_BUS_CLOCK 3 | ||
724 | |||
725 | static void snd_fm801_tea575x_256pcs_write(struct snd_tea575x *tea, unsigned int val) | ||
726 | { | ||
727 | struct fm801 *chip = tea->private_data; | ||
728 | unsigned short reg; | ||
729 | int i = 25; | ||
730 | 718 | ||
731 | spin_lock_irq(&chip->reg_lock); | 719 | /* GPIO to TEA575x maps */ |
732 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | 720 | struct snd_fm801_tea575x_gpio { |
733 | /* use GPIO lines and set write enable bit */ | 721 | u8 data, clk, wren, most; |
734 | reg |= FM801_GPIO_GS(TEA_256PCS_DATA) | | 722 | char *name; |
735 | FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) | | 723 | }; |
736 | FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK); | ||
737 | /* all of lines are in the write direction */ | ||
738 | /* clear data and clock lines */ | ||
739 | reg &= ~(FM801_GPIO_GD(TEA_256PCS_DATA) | | ||
740 | FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) | | ||
741 | FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) | | ||
742 | FM801_GPIO_GP(TEA_256PCS_DATA) | | ||
743 | FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK) | | ||
744 | FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE)); | ||
745 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
746 | udelay(1); | ||
747 | |||
748 | while (i--) { | ||
749 | if (val & (1 << i)) | ||
750 | reg |= FM801_GPIO_GP(TEA_256PCS_DATA); | ||
751 | else | ||
752 | reg &= ~FM801_GPIO_GP(TEA_256PCS_DATA); | ||
753 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
754 | udelay(1); | ||
755 | reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK); | ||
756 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
757 | reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK); | ||
758 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
759 | udelay(1); | ||
760 | } | ||
761 | 724 | ||
762 | /* and reset the write enable bit */ | 725 | static struct snd_fm801_tea575x_gpio snd_fm801_tea575x_gpios[] = { |
763 | reg |= FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE) | | 726 | { .data = 1, .clk = 3, .wren = 2, .most = 0, .name = "SF256-PCS" }, |
764 | FM801_GPIO_GP(TEA_256PCS_DATA); | 727 | { .data = 1, .clk = 0, .wren = 2, .most = 3, .name = "SF256-PCP" }, |
765 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 728 | { .data = 2, .clk = 0, .wren = 1, .most = 3, .name = "SF64-PCR" }, |
766 | spin_unlock_irq(&chip->reg_lock); | 729 | }; |
767 | } | ||
768 | 730 | ||
769 | static unsigned int snd_fm801_tea575x_256pcs_read(struct snd_tea575x *tea) | 731 | static void snd_fm801_tea575x_set_pins(struct snd_tea575x *tea, u8 pins) |
770 | { | 732 | { |
771 | struct fm801 *chip = tea->private_data; | 733 | struct fm801 *chip = tea->private_data; |
772 | unsigned short reg; | 734 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
773 | unsigned int val = 0; | 735 | struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; |
774 | int i; | ||
775 | |||
776 | spin_lock_irq(&chip->reg_lock); | ||
777 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
778 | /* use GPIO lines, set data direction to input */ | ||
779 | reg |= FM801_GPIO_GS(TEA_256PCS_DATA) | | ||
780 | FM801_GPIO_GS(TEA_256PCS_WRITE_ENABLE) | | ||
781 | FM801_GPIO_GS(TEA_256PCS_BUS_CLOCK) | | ||
782 | FM801_GPIO_GD(TEA_256PCS_DATA) | | ||
783 | FM801_GPIO_GP(TEA_256PCS_DATA) | | ||
784 | FM801_GPIO_GP(TEA_256PCS_WRITE_ENABLE); | ||
785 | /* all of lines are in the write direction, except data */ | ||
786 | /* clear data, write enable and clock lines */ | ||
787 | reg &= ~(FM801_GPIO_GD(TEA_256PCS_WRITE_ENABLE) | | ||
788 | FM801_GPIO_GD(TEA_256PCS_BUS_CLOCK) | | ||
789 | FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK)); | ||
790 | |||
791 | for (i = 0; i < 24; i++) { | ||
792 | reg &= ~FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK); | ||
793 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
794 | udelay(1); | ||
795 | reg |= FM801_GPIO_GP(TEA_256PCS_BUS_CLOCK); | ||
796 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
797 | udelay(1); | ||
798 | val <<= 1; | ||
799 | if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCS_DATA)) | ||
800 | val |= 1; | ||
801 | } | ||
802 | 736 | ||
803 | spin_unlock_irq(&chip->reg_lock); | 737 | reg &= ~(FM801_GPIO_GP(gpio.data) | |
738 | FM801_GPIO_GP(gpio.clk) | | ||
739 | FM801_GPIO_GP(gpio.wren)); | ||
804 | 740 | ||
805 | return val; | 741 | reg |= (pins & TEA575X_DATA) ? FM801_GPIO_GP(gpio.data) : 0; |
806 | } | 742 | reg |= (pins & TEA575X_CLK) ? FM801_GPIO_GP(gpio.clk) : 0; |
743 | /* WRITE_ENABLE is inverted */ | ||
744 | reg |= (pins & TEA575X_WREN) ? 0 : FM801_GPIO_GP(gpio.wren); | ||
807 | 745 | ||
808 | /* 256PCPR GPIO numbers */ | ||
809 | #define TEA_256PCPR_BUS_CLOCK 0 | ||
810 | #define TEA_256PCPR_DATA 1 | ||
811 | #define TEA_256PCPR_WRITE_ENABLE 2 /* inverted */ | ||
812 | |||
813 | static void snd_fm801_tea575x_256pcpr_write(struct snd_tea575x *tea, unsigned int val) | ||
814 | { | ||
815 | struct fm801 *chip = tea->private_data; | ||
816 | unsigned short reg; | ||
817 | int i = 25; | ||
818 | |||
819 | spin_lock_irq(&chip->reg_lock); | ||
820 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
821 | /* use GPIO lines and set write enable bit */ | ||
822 | reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) | | ||
823 | FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) | | ||
824 | FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK); | ||
825 | /* all of lines are in the write direction */ | ||
826 | /* clear data and clock lines */ | ||
827 | reg &= ~(FM801_GPIO_GD(TEA_256PCPR_DATA) | | ||
828 | FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) | | ||
829 | FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) | | ||
830 | FM801_GPIO_GP(TEA_256PCPR_DATA) | | ||
831 | FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK) | | ||
832 | FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE)); | ||
833 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 746 | outw(reg, FM801_REG(chip, GPIO_CTRL)); |
834 | udelay(1); | ||
835 | |||
836 | while (i--) { | ||
837 | if (val & (1 << i)) | ||
838 | reg |= FM801_GPIO_GP(TEA_256PCPR_DATA); | ||
839 | else | ||
840 | reg &= ~FM801_GPIO_GP(TEA_256PCPR_DATA); | ||
841 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
842 | udelay(1); | ||
843 | reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK); | ||
844 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
845 | reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK); | ||
846 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
847 | udelay(1); | ||
848 | } | ||
849 | |||
850 | /* and reset the write enable bit */ | ||
851 | reg |= FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE) | | ||
852 | FM801_GPIO_GP(TEA_256PCPR_DATA); | ||
853 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
854 | spin_unlock_irq(&chip->reg_lock); | ||
855 | } | 747 | } |
856 | 748 | ||
857 | static unsigned int snd_fm801_tea575x_256pcpr_read(struct snd_tea575x *tea) | 749 | static u8 snd_fm801_tea575x_get_pins(struct snd_tea575x *tea) |
858 | { | 750 | { |
859 | struct fm801 *chip = tea->private_data; | 751 | struct fm801 *chip = tea->private_data; |
860 | unsigned short reg; | 752 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
861 | unsigned int val = 0; | 753 | struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; |
862 | int i; | ||
863 | |||
864 | spin_lock_irq(&chip->reg_lock); | ||
865 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
866 | /* use GPIO lines, set data direction to input */ | ||
867 | reg |= FM801_GPIO_GS(TEA_256PCPR_DATA) | | ||
868 | FM801_GPIO_GS(TEA_256PCPR_WRITE_ENABLE) | | ||
869 | FM801_GPIO_GS(TEA_256PCPR_BUS_CLOCK) | | ||
870 | FM801_GPIO_GD(TEA_256PCPR_DATA) | | ||
871 | FM801_GPIO_GP(TEA_256PCPR_DATA) | | ||
872 | FM801_GPIO_GP(TEA_256PCPR_WRITE_ENABLE); | ||
873 | /* all of lines are in the write direction, except data */ | ||
874 | /* clear data, write enable and clock lines */ | ||
875 | reg &= ~(FM801_GPIO_GD(TEA_256PCPR_WRITE_ENABLE) | | ||
876 | FM801_GPIO_GD(TEA_256PCPR_BUS_CLOCK) | | ||
877 | FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK)); | ||
878 | |||
879 | for (i = 0; i < 24; i++) { | ||
880 | reg &= ~FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK); | ||
881 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
882 | udelay(1); | ||
883 | reg |= FM801_GPIO_GP(TEA_256PCPR_BUS_CLOCK); | ||
884 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
885 | udelay(1); | ||
886 | val <<= 1; | ||
887 | if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_256PCPR_DATA)) | ||
888 | val |= 1; | ||
889 | } | ||
890 | 754 | ||
891 | spin_unlock_irq(&chip->reg_lock); | 755 | return (reg & FM801_GPIO_GP(gpio.data)) ? TEA575X_DATA : 0 | |
892 | 756 | (reg & FM801_GPIO_GP(gpio.most)) ? TEA575X_MOST : 0; | |
893 | return val; | ||
894 | } | 757 | } |
895 | 758 | ||
896 | /* 64PCR GPIO numbers */ | 759 | static void snd_fm801_tea575x_set_direction(struct snd_tea575x *tea, bool output) |
897 | #define TEA_64PCR_BUS_CLOCK 0 | ||
898 | #define TEA_64PCR_WRITE_ENABLE 1 /* inverted */ | ||
899 | #define TEA_64PCR_DATA 2 | ||
900 | |||
901 | static void snd_fm801_tea575x_64pcr_write(struct snd_tea575x *tea, unsigned int val) | ||
902 | { | 760 | { |
903 | struct fm801 *chip = tea->private_data; | 761 | struct fm801 *chip = tea->private_data; |
904 | unsigned short reg; | 762 | unsigned short reg = inw(FM801_REG(chip, GPIO_CTRL)); |
905 | int i = 25; | 763 | struct snd_fm801_tea575x_gpio gpio = snd_fm801_tea575x_gpios[(chip->tea575x_tuner & TUNER_TYPE_MASK) - 1]; |
906 | 764 | ||
907 | spin_lock_irq(&chip->reg_lock); | ||
908 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
909 | /* use GPIO lines and set write enable bit */ | 765 | /* use GPIO lines and set write enable bit */ |
910 | reg |= FM801_GPIO_GS(TEA_64PCR_DATA) | | 766 | reg |= FM801_GPIO_GS(gpio.data) | |
911 | FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) | | 767 | FM801_GPIO_GS(gpio.wren) | |
912 | FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK); | 768 | FM801_GPIO_GS(gpio.clk) | |
913 | /* all of lines are in the write direction */ | 769 | FM801_GPIO_GS(gpio.most); |
914 | /* clear data and clock lines */ | 770 | if (output) { |
915 | reg &= ~(FM801_GPIO_GD(TEA_64PCR_DATA) | | 771 | /* all of lines are in the write direction */ |
916 | FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) | | 772 | /* clear data and clock lines */ |
917 | FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) | | 773 | reg &= ~(FM801_GPIO_GD(gpio.data) | |
918 | FM801_GPIO_GP(TEA_64PCR_DATA) | | 774 | FM801_GPIO_GD(gpio.wren) | |
919 | FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK) | | 775 | FM801_GPIO_GD(gpio.clk) | |
920 | FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE)); | 776 | FM801_GPIO_GP(gpio.data) | |
921 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 777 | FM801_GPIO_GP(gpio.clk) | |
922 | udelay(1); | 778 | FM801_GPIO_GP(gpio.wren)); |
923 | 779 | } else { | |
924 | while (i--) { | 780 | /* use GPIO lines, set data direction to input */ |
925 | if (val & (1 << i)) | 781 | reg |= FM801_GPIO_GD(gpio.data) | |
926 | reg |= FM801_GPIO_GP(TEA_64PCR_DATA); | 782 | FM801_GPIO_GD(gpio.most) | |
927 | else | 783 | FM801_GPIO_GP(gpio.data) | |
928 | reg &= ~FM801_GPIO_GP(TEA_64PCR_DATA); | 784 | FM801_GPIO_GP(gpio.most) | |
929 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 785 | FM801_GPIO_GP(gpio.wren); |
930 | udelay(1); | 786 | /* all of lines are in the write direction, except data */ |
931 | reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); | 787 | /* clear data, write enable and clock lines */ |
932 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 788 | reg &= ~(FM801_GPIO_GD(gpio.wren) | |
933 | reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); | 789 | FM801_GPIO_GD(gpio.clk) | |
934 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 790 | FM801_GPIO_GP(gpio.clk)); |
935 | udelay(1); | ||
936 | } | 791 | } |
937 | 792 | ||
938 | /* and reset the write enable bit */ | ||
939 | reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE) | | ||
940 | FM801_GPIO_GP(TEA_64PCR_DATA); | ||
941 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | 793 | outw(reg, FM801_REG(chip, GPIO_CTRL)); |
942 | spin_unlock_irq(&chip->reg_lock); | ||
943 | } | ||
944 | |||
945 | static unsigned int snd_fm801_tea575x_64pcr_read(struct snd_tea575x *tea) | ||
946 | { | ||
947 | struct fm801 *chip = tea->private_data; | ||
948 | unsigned short reg; | ||
949 | unsigned int val = 0; | ||
950 | int i; | ||
951 | |||
952 | spin_lock_irq(&chip->reg_lock); | ||
953 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
954 | /* use GPIO lines, set data direction to input */ | ||
955 | reg |= FM801_GPIO_GS(TEA_64PCR_DATA) | | ||
956 | FM801_GPIO_GS(TEA_64PCR_WRITE_ENABLE) | | ||
957 | FM801_GPIO_GS(TEA_64PCR_BUS_CLOCK) | | ||
958 | FM801_GPIO_GD(TEA_64PCR_DATA) | | ||
959 | FM801_GPIO_GP(TEA_64PCR_DATA) | | ||
960 | FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE); | ||
961 | /* all of lines are in the write direction, except data */ | ||
962 | /* clear data, write enable and clock lines */ | ||
963 | reg &= ~(FM801_GPIO_GD(TEA_64PCR_WRITE_ENABLE) | | ||
964 | FM801_GPIO_GD(TEA_64PCR_BUS_CLOCK) | | ||
965 | FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK)); | ||
966 | |||
967 | for (i = 0; i < 24; i++) { | ||
968 | reg &= ~FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); | ||
969 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
970 | udelay(1); | ||
971 | reg |= FM801_GPIO_GP(TEA_64PCR_BUS_CLOCK); | ||
972 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
973 | udelay(1); | ||
974 | val <<= 1; | ||
975 | if (inw(FM801_REG(chip, GPIO_CTRL)) & FM801_GPIO_GP(TEA_64PCR_DATA)) | ||
976 | val |= 1; | ||
977 | } | ||
978 | |||
979 | spin_unlock_irq(&chip->reg_lock); | ||
980 | |||
981 | return val; | ||
982 | } | 794 | } |
983 | 795 | ||
984 | static void snd_fm801_tea575x_64pcr_mute(struct snd_tea575x *tea, | 796 | static struct snd_tea575x_ops snd_fm801_tea_ops = { |
985 | unsigned int mute) | 797 | .set_pins = snd_fm801_tea575x_set_pins, |
986 | { | 798 | .get_pins = snd_fm801_tea575x_get_pins, |
987 | struct fm801 *chip = tea->private_data; | 799 | .set_direction = snd_fm801_tea575x_set_direction, |
988 | unsigned short reg; | ||
989 | |||
990 | spin_lock_irq(&chip->reg_lock); | ||
991 | |||
992 | reg = inw(FM801_REG(chip, GPIO_CTRL)); | ||
993 | if (mute) | ||
994 | /* 0xf800 (mute) */ | ||
995 | reg &= ~FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE); | ||
996 | else | ||
997 | /* 0xf802 (unmute) */ | ||
998 | reg |= FM801_GPIO_GP(TEA_64PCR_WRITE_ENABLE); | ||
999 | outw(reg, FM801_REG(chip, GPIO_CTRL)); | ||
1000 | udelay(1); | ||
1001 | |||
1002 | spin_unlock_irq(&chip->reg_lock); | ||
1003 | } | ||
1004 | |||
1005 | static struct snd_tea575x_ops snd_fm801_tea_ops[3] = { | ||
1006 | { | ||
1007 | /* 1 = MediaForte 256-PCS */ | ||
1008 | .write = snd_fm801_tea575x_256pcs_write, | ||
1009 | .read = snd_fm801_tea575x_256pcs_read, | ||
1010 | }, | ||
1011 | { | ||
1012 | /* 2 = MediaForte 256-PCPR */ | ||
1013 | .write = snd_fm801_tea575x_256pcpr_write, | ||
1014 | .read = snd_fm801_tea575x_256pcpr_read, | ||
1015 | }, | ||
1016 | { | ||
1017 | /* 3 = MediaForte 64-PCR */ | ||
1018 | .write = snd_fm801_tea575x_64pcr_write, | ||
1019 | .read = snd_fm801_tea575x_64pcr_read, | ||
1020 | .mute = snd_fm801_tea575x_64pcr_mute, | ||
1021 | } | ||
1022 | }; | 800 | }; |
1023 | #endif | 801 | #endif |
1024 | 802 | ||
@@ -1371,7 +1149,7 @@ static int snd_fm801_free(struct fm801 *chip) | |||
1371 | outw(cmdw, FM801_REG(chip, IRQ_MASK)); | 1149 | outw(cmdw, FM801_REG(chip, IRQ_MASK)); |
1372 | 1150 | ||
1373 | __end_hw: | 1151 | __end_hw: |
1374 | #ifdef TEA575X_RADIO | 1152 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
1375 | snd_tea575x_exit(&chip->tea); | 1153 | snd_tea575x_exit(&chip->tea); |
1376 | #endif | 1154 | #endif |
1377 | if (chip->irq >= 0) | 1155 | if (chip->irq >= 0) |
@@ -1450,16 +1228,25 @@ static int __devinit snd_fm801_create(struct snd_card *card, | |||
1450 | 1228 | ||
1451 | snd_card_set_dev(card, &pci->dev); | 1229 | snd_card_set_dev(card, &pci->dev); |
1452 | 1230 | ||
1453 | #ifdef TEA575X_RADIO | 1231 | #ifdef CONFIG_SND_FM801_TEA575X_BOOL |
1232 | chip->tea.private_data = chip; | ||
1233 | chip->tea.ops = &snd_fm801_tea_ops; | ||
1234 | sprintf(chip->tea.bus_info, "PCI:%s", pci_name(pci)); | ||
1454 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && | 1235 | if ((tea575x_tuner & TUNER_TYPE_MASK) > 0 && |
1455 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { | 1236 | (tea575x_tuner & TUNER_TYPE_MASK) < 4) { |
1456 | chip->tea.dev_nr = tea575x_tuner >> 16; | 1237 | if (snd_tea575x_init(&chip->tea)) |
1457 | chip->tea.card = card; | 1238 | snd_printk(KERN_ERR "TEA575x radio not found\n"); |
1458 | chip->tea.freq_fixup = 10700; | 1239 | } else if ((tea575x_tuner & TUNER_TYPE_MASK) == 0) |
1459 | chip->tea.private_data = chip; | 1240 | /* autodetect tuner connection */ |
1460 | chip->tea.ops = &snd_fm801_tea_ops[(tea575x_tuner & TUNER_TYPE_MASK) - 1]; | 1241 | for (tea575x_tuner = 1; tea575x_tuner <= 3; tea575x_tuner++) { |
1461 | snd_tea575x_init(&chip->tea); | 1242 | chip->tea575x_tuner = tea575x_tuner; |
1462 | } | 1243 | if (!snd_tea575x_init(&chip->tea)) { |
1244 | snd_printk(KERN_INFO "detected TEA575x radio type %s\n", | ||
1245 | snd_fm801_tea575x_gpios[tea575x_tuner - 1].name); | ||
1246 | break; | ||
1247 | } | ||
1248 | } | ||
1249 | strlcpy(chip->tea.card, snd_fm801_tea575x_gpios[(tea575x_tuner & TUNER_TYPE_MASK) - 1].name, sizeof(chip->tea.card)); | ||
1463 | #endif | 1250 | #endif |
1464 | 1251 | ||
1465 | *rchip = chip; | 1252 | *rchip = chip; |
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 430f41db6044..45b4a8d70e08 100644 --- a/sound/pci/hda/hda_codec.c +++ b/sound/pci/hda/hda_codec.c | |||
@@ -307,6 +307,12 @@ int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid, | |||
307 | } | 307 | } |
308 | EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); | 308 | EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); |
309 | 309 | ||
310 | static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | ||
311 | hda_nid_t *conn_list, int max_conns); | ||
312 | static bool add_conn_list(struct snd_array *array, hda_nid_t nid); | ||
313 | static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, | ||
314 | hda_nid_t *src, int len); | ||
315 | |||
310 | /** | 316 | /** |
311 | * snd_hda_get_connections - get connection list | 317 | * snd_hda_get_connections - get connection list |
312 | * @codec: the HDA codec | 318 | * @codec: the HDA codec |
@@ -320,7 +326,44 @@ EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); | |||
320 | * Returns the number of connections, or a negative error code. | 326 | * Returns the number of connections, or a negative error code. |
321 | */ | 327 | */ |
322 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | 328 | int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, |
323 | hda_nid_t *conn_list, int max_conns) | 329 | hda_nid_t *conn_list, int max_conns) |
330 | { | ||
331 | struct snd_array *array = &codec->conn_lists; | ||
332 | int i, len, old_used; | ||
333 | hda_nid_t list[HDA_MAX_CONNECTIONS]; | ||
334 | |||
335 | /* look up the cached results */ | ||
336 | for (i = 0; i < array->used; ) { | ||
337 | hda_nid_t *p = snd_array_elem(array, i); | ||
338 | len = p[1]; | ||
339 | if (nid == *p) | ||
340 | return copy_conn_list(nid, conn_list, max_conns, | ||
341 | p + 2, len); | ||
342 | i += len + 2; | ||
343 | } | ||
344 | |||
345 | len = _hda_get_connections(codec, nid, list, HDA_MAX_CONNECTIONS); | ||
346 | if (len < 0) | ||
347 | return len; | ||
348 | |||
349 | /* add to the cache */ | ||
350 | old_used = array->used; | ||
351 | if (!add_conn_list(array, nid) || !add_conn_list(array, len)) | ||
352 | goto error_add; | ||
353 | for (i = 0; i < len; i++) | ||
354 | if (!add_conn_list(array, list[i])) | ||
355 | goto error_add; | ||
356 | |||
357 | return copy_conn_list(nid, conn_list, max_conns, list, len); | ||
358 | |||
359 | error_add: | ||
360 | array->used = old_used; | ||
361 | return -ENOMEM; | ||
362 | } | ||
363 | EXPORT_SYMBOL_HDA(snd_hda_get_connections); | ||
364 | |||
365 | static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | ||
366 | hda_nid_t *conn_list, int max_conns) | ||
324 | { | 367 | { |
325 | unsigned int parm; | 368 | unsigned int parm; |
326 | int i, conn_len, conns; | 369 | int i, conn_len, conns; |
@@ -417,8 +460,28 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, | |||
417 | } | 460 | } |
418 | return conns; | 461 | return conns; |
419 | } | 462 | } |
420 | EXPORT_SYMBOL_HDA(snd_hda_get_connections); | ||
421 | 463 | ||
464 | static bool add_conn_list(struct snd_array *array, hda_nid_t nid) | ||
465 | { | ||
466 | hda_nid_t *p = snd_array_new(array); | ||
467 | if (!p) | ||
468 | return false; | ||
469 | *p = nid; | ||
470 | return true; | ||
471 | } | ||
472 | |||
473 | static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, | ||
474 | hda_nid_t *src, int len) | ||
475 | { | ||
476 | if (len > max_dst) { | ||
477 | snd_printk(KERN_ERR "hda_codec: " | ||
478 | "Too many connections %d for NID 0x%x\n", | ||
479 | len, nid); | ||
480 | return -EINVAL; | ||
481 | } | ||
482 | memcpy(dst, src, len * sizeof(hda_nid_t)); | ||
483 | return len; | ||
484 | } | ||
422 | 485 | ||
423 | /** | 486 | /** |
424 | * snd_hda_queue_unsol_event - add an unsolicited event to queue | 487 | * snd_hda_queue_unsol_event - add an unsolicited event to queue |
@@ -937,6 +1000,7 @@ void snd_hda_shutup_pins(struct hda_codec *codec) | |||
937 | } | 1000 | } |
938 | EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); | 1001 | EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); |
939 | 1002 | ||
1003 | #ifdef SND_HDA_NEEDS_RESUME | ||
940 | /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ | 1004 | /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ |
941 | static void restore_shutup_pins(struct hda_codec *codec) | 1005 | static void restore_shutup_pins(struct hda_codec *codec) |
942 | { | 1006 | { |
@@ -953,6 +1017,7 @@ static void restore_shutup_pins(struct hda_codec *codec) | |||
953 | } | 1017 | } |
954 | codec->pins_shutup = 0; | 1018 | codec->pins_shutup = 0; |
955 | } | 1019 | } |
1020 | #endif | ||
956 | 1021 | ||
957 | static void init_hda_cache(struct hda_cache_rec *cache, | 1022 | static void init_hda_cache(struct hda_cache_rec *cache, |
958 | unsigned int record_size); | 1023 | unsigned int record_size); |
@@ -1017,6 +1082,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) | |||
1017 | list_del(&codec->list); | 1082 | list_del(&codec->list); |
1018 | snd_array_free(&codec->mixers); | 1083 | snd_array_free(&codec->mixers); |
1019 | snd_array_free(&codec->nids); | 1084 | snd_array_free(&codec->nids); |
1085 | snd_array_free(&codec->conn_lists); | ||
1020 | codec->bus->caddr_tbl[codec->addr] = NULL; | 1086 | codec->bus->caddr_tbl[codec->addr] = NULL; |
1021 | if (codec->patch_ops.free) | 1087 | if (codec->patch_ops.free) |
1022 | codec->patch_ops.free(codec); | 1088 | codec->patch_ops.free(codec); |
@@ -1077,6 +1143,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, | |||
1077 | snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); | 1143 | snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); |
1078 | snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); | 1144 | snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); |
1079 | snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); | 1145 | snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); |
1146 | snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); | ||
1080 | if (codec->bus->modelname) { | 1147 | if (codec->bus->modelname) { |
1081 | codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); | 1148 | codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); |
1082 | if (!codec->modelname) { | 1149 | if (!codec->modelname) { |
@@ -1329,6 +1396,7 @@ static void purify_inactive_streams(struct hda_codec *codec) | |||
1329 | } | 1396 | } |
1330 | } | 1397 | } |
1331 | 1398 | ||
1399 | #ifdef SND_HDA_NEEDS_RESUME | ||
1332 | /* clean up all streams; called from suspend */ | 1400 | /* clean up all streams; called from suspend */ |
1333 | static void hda_cleanup_all_streams(struct hda_codec *codec) | 1401 | static void hda_cleanup_all_streams(struct hda_codec *codec) |
1334 | { | 1402 | { |
@@ -1340,6 +1408,7 @@ static void hda_cleanup_all_streams(struct hda_codec *codec) | |||
1340 | really_cleanup_stream(codec, p); | 1408 | really_cleanup_stream(codec, p); |
1341 | } | 1409 | } |
1342 | } | 1410 | } |
1411 | #endif | ||
1343 | 1412 | ||
1344 | /* | 1413 | /* |
1345 | * amp access functions | 1414 | * amp access functions |
@@ -2552,7 +2621,7 @@ static unsigned int convert_to_spdif_status(unsigned short val) | |||
2552 | static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, | 2621 | static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, |
2553 | int verb, int val) | 2622 | int verb, int val) |
2554 | { | 2623 | { |
2555 | hda_nid_t *d; | 2624 | const hda_nid_t *d; |
2556 | 2625 | ||
2557 | snd_hda_codec_write_cache(codec, nid, 0, verb, val); | 2626 | snd_hda_codec_write_cache(codec, nid, 0, verb, val); |
2558 | d = codec->slave_dig_outs; | 2627 | d = codec->slave_dig_outs; |
@@ -3803,7 +3872,8 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config); | |||
3803 | * | 3872 | * |
3804 | * Returns 0 if successful, or a negative error code. | 3873 | * Returns 0 if successful, or a negative error code. |
3805 | */ | 3874 | */ |
3806 | int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) | 3875 | int snd_hda_add_new_ctls(struct hda_codec *codec, |
3876 | const struct snd_kcontrol_new *knew) | ||
3807 | { | 3877 | { |
3808 | int err; | 3878 | int err; |
3809 | 3879 | ||
@@ -3946,7 +4016,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, | |||
3946 | struct hda_loopback_check *check, | 4016 | struct hda_loopback_check *check, |
3947 | hda_nid_t nid) | 4017 | hda_nid_t nid) |
3948 | { | 4018 | { |
3949 | struct hda_amp_list *p; | 4019 | const struct hda_amp_list *p; |
3950 | int ch, v; | 4020 | int ch, v; |
3951 | 4021 | ||
3952 | if (!check->amplist) | 4022 | if (!check->amplist) |
@@ -4114,7 +4184,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, | |||
4114 | -1); | 4184 | -1); |
4115 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); | 4185 | snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); |
4116 | if (codec->slave_dig_outs) { | 4186 | if (codec->slave_dig_outs) { |
4117 | hda_nid_t *d; | 4187 | const hda_nid_t *d; |
4118 | for (d = codec->slave_dig_outs; *d; d++) | 4188 | for (d = codec->slave_dig_outs; *d; d++) |
4119 | snd_hda_codec_setup_stream(codec, *d, stream_tag, 0, | 4189 | snd_hda_codec_setup_stream(codec, *d, stream_tag, 0, |
4120 | format); | 4190 | format); |
@@ -4129,7 +4199,7 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) | |||
4129 | { | 4199 | { |
4130 | snd_hda_codec_cleanup_stream(codec, nid); | 4200 | snd_hda_codec_cleanup_stream(codec, nid); |
4131 | if (codec->slave_dig_outs) { | 4201 | if (codec->slave_dig_outs) { |
4132 | hda_nid_t *d; | 4202 | const hda_nid_t *d; |
4133 | for (d = codec->slave_dig_outs; *d; d++) | 4203 | for (d = codec->slave_dig_outs; *d; d++) |
4134 | snd_hda_codec_cleanup_stream(codec, *d); | 4204 | snd_hda_codec_cleanup_stream(codec, *d); |
4135 | } | 4205 | } |
@@ -4276,7 +4346,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, | |||
4276 | unsigned int format, | 4346 | unsigned int format, |
4277 | struct snd_pcm_substream *substream) | 4347 | struct snd_pcm_substream *substream) |
4278 | { | 4348 | { |
4279 | hda_nid_t *nids = mout->dac_nids; | 4349 | const hda_nid_t *nids = mout->dac_nids; |
4280 | int chs = substream->runtime->channels; | 4350 | int chs = substream->runtime->channels; |
4281 | int i; | 4351 | int i; |
4282 | 4352 | ||
@@ -4331,7 +4401,7 @@ EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare); | |||
4331 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, | 4401 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, |
4332 | struct hda_multi_out *mout) | 4402 | struct hda_multi_out *mout) |
4333 | { | 4403 | { |
4334 | hda_nid_t *nids = mout->dac_nids; | 4404 | const hda_nid_t *nids = mout->dac_nids; |
4335 | int i; | 4405 | int i; |
4336 | 4406 | ||
4337 | for (i = 0; i < mout->num_dacs; i++) | 4407 | for (i = 0; i < mout->num_dacs; i++) |
@@ -4356,7 +4426,7 @@ EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); | |||
4356 | * Helper for automatic pin configuration | 4426 | * Helper for automatic pin configuration |
4357 | */ | 4427 | */ |
4358 | 4428 | ||
4359 | static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) | 4429 | static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list) |
4360 | { | 4430 | { |
4361 | for (; *list; list++) | 4431 | for (; *list; list++) |
4362 | if (*list == nid) | 4432 | if (*list == nid) |
@@ -4437,7 +4507,7 @@ static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg) | |||
4437 | */ | 4507 | */ |
4438 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, | 4508 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, |
4439 | struct auto_pin_cfg *cfg, | 4509 | struct auto_pin_cfg *cfg, |
4440 | hda_nid_t *ignore_nids) | 4510 | const hda_nid_t *ignore_nids) |
4441 | { | 4511 | { |
4442 | hda_nid_t nid, end_nid; | 4512 | hda_nid_t nid, end_nid; |
4443 | short seq, assoc_line_out, assoc_speaker; | 4513 | short seq, assoc_line_out, assoc_speaker; |
@@ -4628,10 +4698,13 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
4628 | /* | 4698 | /* |
4629 | * debug prints of the parsed results | 4699 | * debug prints of the parsed results |
4630 | */ | 4700 | */ |
4631 | snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | 4701 | snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n", |
4632 | cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], | 4702 | cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], |
4633 | cfg->line_out_pins[2], cfg->line_out_pins[3], | 4703 | cfg->line_out_pins[2], cfg->line_out_pins[3], |
4634 | cfg->line_out_pins[4]); | 4704 | cfg->line_out_pins[4], |
4705 | cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" : | ||
4706 | (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ? | ||
4707 | "speaker" : "line")); | ||
4635 | snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", | 4708 | snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", |
4636 | cfg->speaker_outs, cfg->speaker_pins[0], | 4709 | cfg->speaker_outs, cfg->speaker_pins[0], |
4637 | cfg->speaker_pins[1], cfg->speaker_pins[2], | 4710 | cfg->speaker_pins[1], cfg->speaker_pins[2], |
@@ -4646,7 +4719,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, | |||
4646 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); | 4719 | cfg->dig_out_pins[0], cfg->dig_out_pins[1]); |
4647 | snd_printd(" inputs:"); | 4720 | snd_printd(" inputs:"); |
4648 | for (i = 0; i < cfg->num_inputs; i++) { | 4721 | for (i = 0; i < cfg->num_inputs; i++) { |
4649 | snd_printdd(" %s=0x%x", | 4722 | snd_printd(" %s=0x%x", |
4650 | hda_get_autocfg_input_label(codec, cfg, i), | 4723 | hda_get_autocfg_input_label(codec, cfg, i), |
4651 | cfg->inputs[i].pin); | 4724 | cfg->inputs[i].pin); |
4652 | } | 4725 | } |
@@ -4982,6 +5055,8 @@ static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid, | |||
4982 | return "Line-out"; | 5055 | return "Line-out"; |
4983 | case SND_JACK_HEADSET: | 5056 | case SND_JACK_HEADSET: |
4984 | return "Headset"; | 5057 | return "Headset"; |
5058 | case SND_JACK_VIDEOOUT: | ||
5059 | return "HDMI/DP"; | ||
4985 | default: | 5060 | default: |
4986 | return "Misc"; | 5061 | return "Misc"; |
4987 | } | 5062 | } |
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h index e46d5420a9f2..59c97306c1de 100644 --- a/sound/pci/hda/hda_codec.h +++ b/sound/pci/hda/hda_codec.h | |||
@@ -825,12 +825,14 @@ struct hda_codec { | |||
825 | struct hda_cache_rec amp_cache; /* cache for amp access */ | 825 | struct hda_cache_rec amp_cache; /* cache for amp access */ |
826 | struct hda_cache_rec cmd_cache; /* cache for other commands */ | 826 | struct hda_cache_rec cmd_cache; /* cache for other commands */ |
827 | 827 | ||
828 | struct snd_array conn_lists; /* connection-list array */ | ||
829 | |||
828 | struct mutex spdif_mutex; | 830 | struct mutex spdif_mutex; |
829 | struct mutex control_mutex; | 831 | struct mutex control_mutex; |
830 | unsigned int spdif_status; /* IEC958 status bits */ | 832 | unsigned int spdif_status; /* IEC958 status bits */ |
831 | unsigned short spdif_ctls; /* SPDIF control bits */ | 833 | unsigned short spdif_ctls; /* SPDIF control bits */ |
832 | unsigned int spdif_in_enable; /* SPDIF input enable? */ | 834 | unsigned int spdif_in_enable; /* SPDIF input enable? */ |
833 | hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ | 835 | const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ |
834 | struct snd_array init_pins; /* initial (BIOS) pin configurations */ | 836 | struct snd_array init_pins; /* initial (BIOS) pin configurations */ |
835 | struct snd_array driver_pins; /* pin configs set by codec parser */ | 837 | struct snd_array driver_pins; /* pin configs set by codec parser */ |
836 | struct snd_array cvt_setups; /* audio convert setups */ | 838 | struct snd_array cvt_setups; /* audio convert setups */ |
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 70a9d32f0e96..486f6deb3eee 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -126,6 +126,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | |||
126 | "{Intel, ICH10}," | 126 | "{Intel, ICH10}," |
127 | "{Intel, PCH}," | 127 | "{Intel, PCH}," |
128 | "{Intel, CPT}," | 128 | "{Intel, CPT}," |
129 | "{Intel, PPT}," | ||
129 | "{Intel, PBG}," | 130 | "{Intel, PBG}," |
130 | "{Intel, SCH}," | 131 | "{Intel, SCH}," |
131 | "{ATI, SB450}," | 132 | "{ATI, SB450}," |
@@ -390,6 +391,7 @@ struct azx { | |||
390 | 391 | ||
391 | /* chip type specific */ | 392 | /* chip type specific */ |
392 | int driver_type; | 393 | int driver_type; |
394 | unsigned int driver_caps; | ||
393 | int playback_streams; | 395 | int playback_streams; |
394 | int playback_index_offset; | 396 | int playback_index_offset; |
395 | int capture_streams; | 397 | int capture_streams; |
@@ -463,6 +465,34 @@ enum { | |||
463 | AZX_NUM_DRIVERS, /* keep this as last entry */ | 465 | AZX_NUM_DRIVERS, /* keep this as last entry */ |
464 | }; | 466 | }; |
465 | 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 | |||
466 | static char *driver_short_names[] __devinitdata = { | 496 | static char *driver_short_names[] __devinitdata = { |
467 | [AZX_DRIVER_ICH] = "HDA Intel", | 497 | [AZX_DRIVER_ICH] = "HDA Intel", |
468 | [AZX_DRIVER_PCH] = "HDA Intel PCH", | 498 | [AZX_DRIVER_PCH] = "HDA Intel PCH", |
@@ -565,7 +595,7 @@ static void azx_init_cmd_io(struct azx *chip) | |||
565 | /* reset the rirb hw write pointer */ | 595 | /* reset the rirb hw write pointer */ |
566 | azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST); | 596 | azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST); |
567 | /* set N=1, get RIRB response interrupt for new entry */ | 597 | /* set N=1, get RIRB response interrupt for new entry */ |
568 | if (chip->driver_type == AZX_DRIVER_CTX) | 598 | if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) |
569 | azx_writew(chip, RINTCNT, 0xc0); | 599 | azx_writew(chip, RINTCNT, 0xc0); |
570 | else | 600 | else |
571 | azx_writew(chip, RINTCNT, 1); | 601 | azx_writew(chip, RINTCNT, 1); |
@@ -1055,19 +1085,24 @@ static void azx_init_pci(struct azx *chip) | |||
1055 | * codecs. | 1085 | * codecs. |
1056 | * The PCI register TCSEL is defined in the Intel manuals. | 1086 | * The PCI register TCSEL is defined in the Intel manuals. |
1057 | */ | 1087 | */ |
1058 | if (chip->driver_type != AZX_DRIVER_ATI && | 1088 | if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) { |
1059 | chip->driver_type != AZX_DRIVER_ATIHDMI) | 1089 | snd_printdd(SFX "Clearing TCSEL\n"); |
1060 | update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); | 1090 | update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); |
1091 | } | ||
1061 | 1092 | ||
1062 | switch (chip->driver_type) { | 1093 | /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio, |
1063 | case AZX_DRIVER_ATI: | 1094 | * we need to enable snoop. |
1064 | /* 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"); | ||
1065 | update_pci_byte(chip->pci, | 1098 | update_pci_byte(chip->pci, |
1066 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, | 1099 | ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, |
1067 | 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); | 1100 | 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); |
1068 | break; | 1101 | } |
1069 | case AZX_DRIVER_NVIDIA: | 1102 | |
1070 | /* 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"); | ||
1071 | update_pci_byte(chip->pci, | 1106 | update_pci_byte(chip->pci, |
1072 | NVIDIA_HDA_TRANSREG_ADDR, | 1107 | NVIDIA_HDA_TRANSREG_ADDR, |
1073 | 0x0f, NVIDIA_HDA_ENABLE_COHBITS); | 1108 | 0x0f, NVIDIA_HDA_ENABLE_COHBITS); |
@@ -1077,9 +1112,10 @@ static void azx_init_pci(struct azx *chip) | |||
1077 | update_pci_byte(chip->pci, | 1112 | update_pci_byte(chip->pci, |
1078 | NVIDIA_HDA_OSTRM_COH, | 1113 | NVIDIA_HDA_OSTRM_COH, |
1079 | 0x01, NVIDIA_HDA_ENABLE_COHBIT); | 1114 | 0x01, NVIDIA_HDA_ENABLE_COHBIT); |
1080 | break; | 1115 | } |
1081 | case AZX_DRIVER_SCH: | 1116 | |
1082 | case AZX_DRIVER_PCH: | 1117 | /* Enable SCH/PCH snoop if needed */ |
1118 | if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { | ||
1083 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); | 1119 | pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); |
1084 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { | 1120 | if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { |
1085 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, | 1121 | pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, |
@@ -1090,8 +1126,6 @@ static void azx_init_pci(struct azx *chip) | |||
1090 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) | 1126 | (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) |
1091 | ? "Failed" : "OK"); | 1127 | ? "Failed" : "OK"); |
1092 | } | 1128 | } |
1093 | break; | ||
1094 | |||
1095 | } | 1129 | } |
1096 | } | 1130 | } |
1097 | 1131 | ||
@@ -1145,7 +1179,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) | |||
1145 | status = azx_readb(chip, RIRBSTS); | 1179 | status = azx_readb(chip, RIRBSTS); |
1146 | if (status & RIRB_INT_MASK) { | 1180 | if (status & RIRB_INT_MASK) { |
1147 | if (status & RIRB_INT_RESPONSE) { | 1181 | if (status & RIRB_INT_RESPONSE) { |
1148 | if (chip->driver_type == AZX_DRIVER_CTX) | 1182 | if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY) |
1149 | udelay(80); | 1183 | udelay(80); |
1150 | azx_update_rirb(chip); | 1184 | azx_update_rirb(chip); |
1151 | } | 1185 | } |
@@ -1414,8 +1448,10 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) | |||
1414 | if (err < 0) | 1448 | if (err < 0) |
1415 | return err; | 1449 | return err; |
1416 | 1450 | ||
1417 | 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"); | ||
1418 | chip->bus->needs_damn_long_delay = 1; | 1453 | chip->bus->needs_damn_long_delay = 1; |
1454 | } | ||
1419 | 1455 | ||
1420 | codecs = 0; | 1456 | codecs = 0; |
1421 | max_slots = azx_max_codecs[chip->driver_type]; | 1457 | max_slots = azx_max_codecs[chip->driver_type]; |
@@ -1446,6 +1482,16 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) | |||
1446 | } | 1482 | } |
1447 | } | 1483 | } |
1448 | 1484 | ||
1485 | /* AMD chipsets often cause the communication stalls upon certain | ||
1486 | * sequence like the pin-detection. It seems that forcing the synced | ||
1487 | * access works around the stall. Grrr... | ||
1488 | */ | ||
1489 | if (chip->driver_caps & AZX_DCAPS_SYNC_WRITE) { | ||
1490 | snd_printd(SFX "Enable sync_write for stable communication\n"); | ||
1491 | chip->bus->sync_write = 1; | ||
1492 | chip->bus->allow_bus_reset = 1; | ||
1493 | } | ||
1494 | |||
1449 | /* Then create codec instances */ | 1495 | /* Then create codec instances */ |
1450 | for (c = 0; c < max_slots; c++) { | 1496 | for (c = 0; c < max_slots; c++) { |
1451 | if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { | 1497 | if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { |
@@ -1702,7 +1748,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) | |||
1702 | 1748 | ||
1703 | stream_tag = azx_dev->stream_tag; | 1749 | stream_tag = azx_dev->stream_tag; |
1704 | /* CA-IBG chips need the playback stream starting from 1 */ | 1750 | /* CA-IBG chips need the playback stream starting from 1 */ |
1705 | if (chip->driver_type == AZX_DRIVER_CTX && | 1751 | if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) && |
1706 | stream_tag > chip->capture_streams) | 1752 | stream_tag > chip->capture_streams) |
1707 | stream_tag -= chip->capture_streams; | 1753 | stream_tag -= chip->capture_streams; |
1708 | return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag, | 1754 | return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag, |
@@ -2347,13 +2393,14 @@ static int __devinit check_position_fix(struct azx *chip, int fix) | |||
2347 | } | 2393 | } |
2348 | 2394 | ||
2349 | /* Check VIA/ATI HD Audio Controller exist */ | 2395 | /* Check VIA/ATI HD Audio Controller exist */ |
2350 | switch (chip->driver_type) { | 2396 | if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) { |
2351 | case AZX_DRIVER_VIA: | 2397 | snd_printd(SFX "Using VIACOMBO position fix\n"); |
2352 | case AZX_DRIVER_ATI: | ||
2353 | /* Use link position directly, avoid any transfer problem. */ | ||
2354 | return POS_FIX_VIACOMBO; | 2398 | return POS_FIX_VIACOMBO; |
2355 | } | 2399 | } |
2356 | 2400 | if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) { | |
2401 | snd_printd(SFX "Using LPIB position fix\n"); | ||
2402 | return POS_FIX_LPIB; | ||
2403 | } | ||
2357 | return POS_FIX_AUTO; | 2404 | return POS_FIX_AUTO; |
2358 | } | 2405 | } |
2359 | 2406 | ||
@@ -2435,8 +2482,8 @@ static void __devinit check_msi(struct azx *chip) | |||
2435 | } | 2482 | } |
2436 | 2483 | ||
2437 | /* NVidia chipsets seem to cause troubles with MSI */ | 2484 | /* NVidia chipsets seem to cause troubles with MSI */ |
2438 | if (chip->driver_type == AZX_DRIVER_NVIDIA) { | 2485 | if (chip->driver_caps & AZX_DCAPS_NO_MSI) { |
2439 | printk(KERN_INFO "hda_intel: Disable MSI for Nvidia chipset\n"); | 2486 | printk(KERN_INFO "hda_intel: Disabling MSI\n"); |
2440 | chip->msi = 0; | 2487 | chip->msi = 0; |
2441 | } | 2488 | } |
2442 | } | 2489 | } |
@@ -2446,7 +2493,7 @@ static void __devinit check_msi(struct azx *chip) | |||
2446 | * constructor | 2493 | * constructor |
2447 | */ | 2494 | */ |
2448 | 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, |
2449 | int dev, int driver_type, | 2496 | int dev, unsigned int driver_caps, |
2450 | struct azx **rchip) | 2497 | struct azx **rchip) |
2451 | { | 2498 | { |
2452 | struct azx *chip; | 2499 | struct azx *chip; |
@@ -2474,7 +2521,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2474 | chip->card = card; | 2521 | chip->card = card; |
2475 | chip->pci = pci; | 2522 | chip->pci = pci; |
2476 | chip->irq = -1; | 2523 | chip->irq = -1; |
2477 | chip->driver_type = driver_type; | 2524 | chip->driver_caps = driver_caps; |
2525 | chip->driver_type = driver_caps & 0xff; | ||
2478 | check_msi(chip); | 2526 | check_msi(chip); |
2479 | chip->dev_index = dev; | 2527 | chip->dev_index = dev; |
2480 | INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); | 2528 | INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); |
@@ -2538,8 +2586,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2538 | snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); | 2586 | snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); |
2539 | 2587 | ||
2540 | /* disable SB600 64bit support for safety */ | 2588 | /* disable SB600 64bit support for safety */ |
2541 | if ((chip->driver_type == AZX_DRIVER_ATI) || | 2589 | if (chip->pci->vendor == PCI_VENDOR_ID_ATI) { |
2542 | (chip->driver_type == AZX_DRIVER_ATIHDMI)) { | ||
2543 | struct pci_dev *p_smbus; | 2590 | struct pci_dev *p_smbus; |
2544 | p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, | 2591 | p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, |
2545 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, | 2592 | PCI_DEVICE_ID_ATI_SBX00_SMBUS, |
@@ -2551,10 +2598,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
2551 | } | 2598 | } |
2552 | } | 2599 | } |
2553 | 2600 | ||
2554 | /* disable 64bit DMA address for Teradici */ | 2601 | /* disable 64bit DMA address on some devices */ |
2555 | /* it does not work with device 6549:1200 subsys e4a2:040b */ | 2602 | if (chip->driver_caps & AZX_DCAPS_NO_64BIT) { |
2556 | if (chip->driver_type == AZX_DRIVER_TERA) | 2603 | snd_printd(SFX "Disabling 64bit DMA\n"); |
2557 | gcap &= ~ICH6_GCAP_64OK; | 2604 | gcap &= ~ICH6_GCAP_64OK; |
2605 | } | ||
2558 | 2606 | ||
2559 | /* allow 64bit DMA address if supported by H/W */ | 2607 | /* allow 64bit DMA address if supported by H/W */ |
2560 | 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))) |
@@ -2756,36 +2804,62 @@ static void __devexit azx_remove(struct pci_dev *pci) | |||
2756 | /* PCI IDs */ | 2804 | /* PCI IDs */ |
2757 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | 2805 | static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { |
2758 | /* CPT */ | 2806 | /* CPT */ |
2759 | { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, | 2807 | { PCI_DEVICE(0x8086, 0x1c20), |
2808 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | ||
2760 | /* PBG */ | 2809 | /* PBG */ |
2761 | { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH }, | 2810 | { PCI_DEVICE(0x8086, 0x1d20), |
2811 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | ||
2812 | /* Panther Point */ | ||
2813 | { PCI_DEVICE(0x8086, 0x1e20), | ||
2814 | .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, | ||
2762 | /* SCH */ | 2815 | /* SCH */ |
2763 | { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, | 2816 | { PCI_DEVICE(0x8086, 0x811b), |
2817 | .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, | ||
2764 | /* Generic Intel */ | 2818 | /* Generic Intel */ |
2765 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), | 2819 | { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), |
2766 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2820 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
2767 | .class_mask = 0xffffff, | 2821 | .class_mask = 0xffffff, |
2768 | .driver_data = AZX_DRIVER_ICH }, | 2822 | .driver_data = AZX_DRIVER_ICH }, |
2769 | /* ATI SB 450/600 */ | 2823 | /* ATI SB 450/600/700/800/900 */ |
2770 | { PCI_DEVICE(0x1002, 0x437b), .driver_data = AZX_DRIVER_ATI }, | 2824 | { PCI_DEVICE(0x1002, 0x437b), |
2771 | { 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 }, | ||
2772 | /* ATI HDMI */ | 2831 | /* ATI HDMI */ |
2773 | { PCI_DEVICE(0x1002, 0x793b), .driver_data = AZX_DRIVER_ATIHDMI }, | 2832 | { PCI_DEVICE(0x1002, 0x793b), |
2774 | { PCI_DEVICE(0x1002, 0x7919), .driver_data = AZX_DRIVER_ATIHDMI }, | 2833 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
2775 | { PCI_DEVICE(0x1002, 0x960f), .driver_data = AZX_DRIVER_ATIHDMI }, | 2834 | { PCI_DEVICE(0x1002, 0x7919), |
2776 | { PCI_DEVICE(0x1002, 0x970f), .driver_data = AZX_DRIVER_ATIHDMI }, | 2835 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
2777 | { PCI_DEVICE(0x1002, 0xaa00), .driver_data = AZX_DRIVER_ATIHDMI }, | 2836 | { PCI_DEVICE(0x1002, 0x960f), |
2778 | { PCI_DEVICE(0x1002, 0xaa08), .driver_data = AZX_DRIVER_ATIHDMI }, | 2837 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
2779 | { PCI_DEVICE(0x1002, 0xaa10), .driver_data = AZX_DRIVER_ATIHDMI }, | 2838 | { PCI_DEVICE(0x1002, 0x970f), |
2780 | { PCI_DEVICE(0x1002, 0xaa18), .driver_data = AZX_DRIVER_ATIHDMI }, | 2839 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
2781 | { PCI_DEVICE(0x1002, 0xaa20), .driver_data = AZX_DRIVER_ATIHDMI }, | 2840 | { PCI_DEVICE(0x1002, 0xaa00), |
2782 | { PCI_DEVICE(0x1002, 0xaa28), .driver_data = AZX_DRIVER_ATIHDMI }, | 2841 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
2783 | { PCI_DEVICE(0x1002, 0xaa30), .driver_data = AZX_DRIVER_ATIHDMI }, | 2842 | { PCI_DEVICE(0x1002, 0xaa08), |
2784 | { PCI_DEVICE(0x1002, 0xaa38), .driver_data = AZX_DRIVER_ATIHDMI }, | 2843 | .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, |
2785 | { PCI_DEVICE(0x1002, 0xaa40), .driver_data = AZX_DRIVER_ATIHDMI }, | 2844 | { PCI_DEVICE(0x1002, 0xaa10), |
2786 | { 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 }, | ||
2787 | /* VIA VT8251/VT8237A */ | 2860 | /* VIA VT8251/VT8237A */ |
2788 | { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA }, | 2861 | { PCI_DEVICE(0x1106, 0x3288), |
2862 | .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, | ||
2789 | /* SIS966 */ | 2863 | /* SIS966 */ |
2790 | { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, | 2864 | { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, |
2791 | /* ULI M5461 */ | 2865 | /* ULI M5461 */ |
@@ -2794,9 +2868,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
2794 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), | 2868 | { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), |
2795 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2869 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
2796 | .class_mask = 0xffffff, | 2870 | .class_mask = 0xffffff, |
2797 | .driver_data = AZX_DRIVER_NVIDIA }, | 2871 | .driver_data = AZX_DRIVER_NVIDIA | AZX_DCAPS_PRESET_NVIDIA }, |
2798 | /* Teradici */ | 2872 | /* Teradici */ |
2799 | { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, | 2873 | { PCI_DEVICE(0x6549, 0x1200), |
2874 | .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, | ||
2800 | /* Creative X-Fi (CA0110-IBG) */ | 2875 | /* Creative X-Fi (CA0110-IBG) */ |
2801 | #if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) | 2876 | #if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) |
2802 | /* the following entry conflicts with snd-ctxfi driver, | 2877 | /* the following entry conflicts with snd-ctxfi driver, |
@@ -2806,10 +2881,13 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
2806 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), | 2881 | { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), |
2807 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2882 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
2808 | .class_mask = 0xffffff, | 2883 | .class_mask = 0xffffff, |
2809 | .driver_data = AZX_DRIVER_CTX }, | 2884 | .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | |
2885 | AZX_DCAPS_RIRB_PRE_DELAY }, | ||
2810 | #else | 2886 | #else |
2811 | /* this entry seems still valid -- i.e. without emu20kx chip */ | 2887 | /* this entry seems still valid -- i.e. without emu20kx chip */ |
2812 | { 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 }, | ||
2813 | #endif | 2891 | #endif |
2814 | /* Vortex86MX */ | 2892 | /* Vortex86MX */ |
2815 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, | 2893 | { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, |
@@ -2819,11 +2897,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { | |||
2819 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), | 2897 | { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), |
2820 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2898 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
2821 | .class_mask = 0xffffff, | 2899 | .class_mask = 0xffffff, |
2822 | .driver_data = AZX_DRIVER_GENERIC }, | 2900 | .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI }, |
2823 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID), | 2901 | { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID), |
2824 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, | 2902 | .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, |
2825 | .class_mask = 0xffffff, | 2903 | .class_mask = 0xffffff, |
2826 | .driver_data = AZX_DRIVER_GENERIC }, | 2904 | .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI }, |
2827 | { 0, } | 2905 | { 0, } |
2828 | }; | 2906 | }; |
2829 | MODULE_DEVICE_TABLE(pci, azx_ids); | 2907 | MODULE_DEVICE_TABLE(pci, azx_ids); |
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index ff5e2ac2239a..08ec073444e2 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -267,11 +267,11 @@ enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */ | |||
267 | 267 | ||
268 | struct hda_multi_out { | 268 | struct hda_multi_out { |
269 | int num_dacs; /* # of DACs, must be more than 1 */ | 269 | int num_dacs; /* # of DACs, must be more than 1 */ |
270 | hda_nid_t *dac_nids; /* DAC list */ | 270 | const hda_nid_t *dac_nids; /* DAC list */ |
271 | hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ | 271 | hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ |
272 | hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */ | 272 | hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */ |
273 | hda_nid_t dig_out_nid; /* digital out audio widget */ | 273 | hda_nid_t dig_out_nid; /* digital out audio widget */ |
274 | hda_nid_t *slave_dig_outs; | 274 | const hda_nid_t *slave_dig_outs; |
275 | int max_channels; /* currently supported analog channels */ | 275 | int max_channels; /* currently supported analog channels */ |
276 | int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ | 276 | int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ |
277 | int no_share_stream; /* don't share a stream with multiple pins */ | 277 | int no_share_stream; /* don't share a stream with multiple pins */ |
@@ -347,7 +347,7 @@ int snd_hda_check_board_codec_sid_config(struct hda_codec *codec, | |||
347 | int num_configs, const char * const *models, | 347 | int num_configs, const char * const *models, |
348 | const struct snd_pci_quirk *tbl); | 348 | const struct snd_pci_quirk *tbl); |
349 | int snd_hda_add_new_ctls(struct hda_codec *codec, | 349 | int snd_hda_add_new_ctls(struct hda_codec *codec, |
350 | struct snd_kcontrol_new *knew); | 350 | const struct snd_kcontrol_new *knew); |
351 | 351 | ||
352 | /* | 352 | /* |
353 | * unsolicited event handler | 353 | * unsolicited event handler |
@@ -443,7 +443,7 @@ struct auto_pin_cfg { | |||
443 | 443 | ||
444 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, | 444 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, |
445 | struct auto_pin_cfg *cfg, | 445 | struct auto_pin_cfg *cfg, |
446 | hda_nid_t *ignore_nids); | 446 | const hda_nid_t *ignore_nids); |
447 | 447 | ||
448 | /* amp values */ | 448 | /* amp values */ |
449 | #define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) | 449 | #define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8)) |
@@ -493,6 +493,12 @@ u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid); | |||
493 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); | 493 | u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); |
494 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); | 494 | int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); |
495 | 495 | ||
496 | static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) | ||
497 | { | ||
498 | return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && | ||
499 | (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); | ||
500 | } | ||
501 | |||
496 | /* flags for hda_nid_item */ | 502 | /* flags for hda_nid_item */ |
497 | #define HDA_NID_ITEM_AMP (1<<0) | 503 | #define HDA_NID_ITEM_AMP (1<<0) |
498 | 504 | ||
@@ -567,7 +573,7 @@ struct hda_amp_list { | |||
567 | }; | 573 | }; |
568 | 574 | ||
569 | struct hda_loopback_check { | 575 | struct hda_loopback_check { |
570 | struct hda_amp_list *amplist; | 576 | const struct hda_amp_list *amplist; |
571 | int power_on; | 577 | int power_on; |
572 | }; | 578 | }; |
573 | 579 | ||
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2942d2a9ea10..696ac2590307 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -30,7 +30,7 @@ | |||
30 | #include "hda_beep.h" | 30 | #include "hda_beep.h" |
31 | 31 | ||
32 | struct ad198x_spec { | 32 | struct ad198x_spec { |
33 | struct snd_kcontrol_new *mixers[6]; | 33 | const struct snd_kcontrol_new *mixers[6]; |
34 | int num_mixers; | 34 | int num_mixers; |
35 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | 35 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
36 | const struct hda_verb *init_verbs[6]; /* initialization verbs | 36 | const struct hda_verb *init_verbs[6]; /* initialization verbs |
@@ -46,17 +46,17 @@ struct ad198x_spec { | |||
46 | unsigned int cur_eapd; | 46 | unsigned int cur_eapd; |
47 | unsigned int need_dac_fix; | 47 | unsigned int need_dac_fix; |
48 | 48 | ||
49 | hda_nid_t *alt_dac_nid; | 49 | const hda_nid_t *alt_dac_nid; |
50 | struct hda_pcm_stream *stream_analog_alt_playback; | 50 | const struct hda_pcm_stream *stream_analog_alt_playback; |
51 | 51 | ||
52 | /* capture */ | 52 | /* capture */ |
53 | unsigned int num_adc_nids; | 53 | unsigned int num_adc_nids; |
54 | hda_nid_t *adc_nids; | 54 | const hda_nid_t *adc_nids; |
55 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | 55 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ |
56 | 56 | ||
57 | /* capture source */ | 57 | /* capture source */ |
58 | const struct hda_input_mux *input_mux; | 58 | const struct hda_input_mux *input_mux; |
59 | hda_nid_t *capsrc_nids; | 59 | const hda_nid_t *capsrc_nids; |
60 | unsigned int cur_mux[3]; | 60 | unsigned int cur_mux[3]; |
61 | 61 | ||
62 | /* channel model */ | 62 | /* channel model */ |
@@ -182,13 +182,13 @@ static void ad198x_free_kctls(struct hda_codec *codec); | |||
182 | 182 | ||
183 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 183 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
184 | /* additional beep mixers; the actual parameters are overwritten at build */ | 184 | /* additional beep mixers; the actual parameters are overwritten at build */ |
185 | static struct snd_kcontrol_new ad_beep_mixer[] = { | 185 | static const struct snd_kcontrol_new ad_beep_mixer[] = { |
186 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), | 186 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), |
187 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), | 187 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), |
188 | { } /* end */ | 188 | { } /* end */ |
189 | }; | 189 | }; |
190 | 190 | ||
191 | static struct snd_kcontrol_new ad_beep2_mixer[] = { | 191 | static const struct snd_kcontrol_new ad_beep2_mixer[] = { |
192 | HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT), | 192 | HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT), |
193 | HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT), | 193 | HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT), |
194 | { } /* end */ | 194 | { } /* end */ |
@@ -231,7 +231,7 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
231 | /* create beep controls if needed */ | 231 | /* create beep controls if needed */ |
232 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 232 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
233 | if (spec->beep_amp) { | 233 | if (spec->beep_amp) { |
234 | struct snd_kcontrol_new *knew; | 234 | const struct snd_kcontrol_new *knew; |
235 | knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; | 235 | knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; |
236 | for ( ; knew->name; knew++) { | 236 | for ( ; knew->name; knew++) { |
237 | struct snd_kcontrol *kctl; | 237 | struct snd_kcontrol *kctl; |
@@ -331,7 +331,7 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
331 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); | 331 | return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); |
332 | } | 332 | } |
333 | 333 | ||
334 | static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { | 334 | static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { |
335 | .substreams = 1, | 335 | .substreams = 1, |
336 | .channels_min = 2, | 336 | .channels_min = 2, |
337 | .channels_max = 2, | 337 | .channels_max = 2, |
@@ -403,7 +403,7 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
403 | 403 | ||
404 | /* | 404 | /* |
405 | */ | 405 | */ |
406 | static struct hda_pcm_stream ad198x_pcm_analog_playback = { | 406 | static const struct hda_pcm_stream ad198x_pcm_analog_playback = { |
407 | .substreams = 1, | 407 | .substreams = 1, |
408 | .channels_min = 2, | 408 | .channels_min = 2, |
409 | .channels_max = 6, /* changed later */ | 409 | .channels_max = 6, /* changed later */ |
@@ -415,7 +415,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_playback = { | |||
415 | }, | 415 | }, |
416 | }; | 416 | }; |
417 | 417 | ||
418 | static struct hda_pcm_stream ad198x_pcm_analog_capture = { | 418 | static const struct hda_pcm_stream ad198x_pcm_analog_capture = { |
419 | .substreams = 1, | 419 | .substreams = 1, |
420 | .channels_min = 2, | 420 | .channels_min = 2, |
421 | .channels_max = 2, | 421 | .channels_max = 2, |
@@ -426,7 +426,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_capture = { | |||
426 | }, | 426 | }, |
427 | }; | 427 | }; |
428 | 428 | ||
429 | static struct hda_pcm_stream ad198x_pcm_digital_playback = { | 429 | static const struct hda_pcm_stream ad198x_pcm_digital_playback = { |
430 | .substreams = 1, | 430 | .substreams = 1, |
431 | .channels_min = 2, | 431 | .channels_min = 2, |
432 | .channels_max = 2, | 432 | .channels_max = 2, |
@@ -439,7 +439,7 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { | |||
439 | }, | 439 | }, |
440 | }; | 440 | }; |
441 | 441 | ||
442 | static struct hda_pcm_stream ad198x_pcm_digital_capture = { | 442 | static const struct hda_pcm_stream ad198x_pcm_digital_capture = { |
443 | .substreams = 1, | 443 | .substreams = 1, |
444 | .channels_min = 2, | 444 | .channels_min = 2, |
445 | .channels_max = 2, | 445 | .channels_max = 2, |
@@ -489,11 +489,6 @@ static int ad198x_build_pcms(struct hda_codec *codec) | |||
489 | return 0; | 489 | return 0; |
490 | } | 490 | } |
491 | 491 | ||
492 | static inline void ad198x_shutup(struct hda_codec *codec) | ||
493 | { | ||
494 | snd_hda_shutup_pins(codec); | ||
495 | } | ||
496 | |||
497 | static void ad198x_free_kctls(struct hda_codec *codec) | 492 | static void ad198x_free_kctls(struct hda_codec *codec) |
498 | { | 493 | { |
499 | struct ad198x_spec *spec = codec->spec; | 494 | struct ad198x_spec *spec = codec->spec; |
@@ -547,6 +542,12 @@ static void ad198x_power_eapd(struct hda_codec *codec) | |||
547 | } | 542 | } |
548 | } | 543 | } |
549 | 544 | ||
545 | static void ad198x_shutup(struct hda_codec *codec) | ||
546 | { | ||
547 | snd_hda_shutup_pins(codec); | ||
548 | ad198x_power_eapd(codec); | ||
549 | } | ||
550 | |||
550 | static void ad198x_free(struct hda_codec *codec) | 551 | static void ad198x_free(struct hda_codec *codec) |
551 | { | 552 | { |
552 | struct ad198x_spec *spec = codec->spec; | 553 | struct ad198x_spec *spec = codec->spec; |
@@ -564,12 +565,11 @@ static void ad198x_free(struct hda_codec *codec) | |||
564 | static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) | 565 | static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) |
565 | { | 566 | { |
566 | ad198x_shutup(codec); | 567 | ad198x_shutup(codec); |
567 | ad198x_power_eapd(codec); | ||
568 | return 0; | 568 | return 0; |
569 | } | 569 | } |
570 | #endif | 570 | #endif |
571 | 571 | ||
572 | static struct hda_codec_ops ad198x_patch_ops = { | 572 | static const struct hda_codec_ops ad198x_patch_ops = { |
573 | .build_controls = ad198x_build_controls, | 573 | .build_controls = ad198x_build_controls, |
574 | .build_pcms = ad198x_build_pcms, | 574 | .build_pcms = ad198x_build_pcms, |
575 | .init = ad198x_init, | 575 | .init = ad198x_init, |
@@ -639,13 +639,13 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
639 | #define AD1986A_CLFE_DAC 0x05 | 639 | #define AD1986A_CLFE_DAC 0x05 |
640 | #define AD1986A_ADC 0x06 | 640 | #define AD1986A_ADC 0x06 |
641 | 641 | ||
642 | static hda_nid_t ad1986a_dac_nids[3] = { | 642 | static const hda_nid_t ad1986a_dac_nids[3] = { |
643 | AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC | 643 | AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC |
644 | }; | 644 | }; |
645 | static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; | 645 | static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; |
646 | static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 }; | 646 | static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 }; |
647 | 647 | ||
648 | static struct hda_input_mux ad1986a_capture_source = { | 648 | static const struct hda_input_mux ad1986a_capture_source = { |
649 | .num_items = 7, | 649 | .num_items = 7, |
650 | .items = { | 650 | .items = { |
651 | { "Mic", 0x0 }, | 651 | { "Mic", 0x0 }, |
@@ -659,7 +659,7 @@ static struct hda_input_mux ad1986a_capture_source = { | |||
659 | }; | 659 | }; |
660 | 660 | ||
661 | 661 | ||
662 | static struct hda_bind_ctls ad1986a_bind_pcm_vol = { | 662 | static const struct hda_bind_ctls ad1986a_bind_pcm_vol = { |
663 | .ops = &snd_hda_bind_vol, | 663 | .ops = &snd_hda_bind_vol, |
664 | .values = { | 664 | .values = { |
665 | HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), | 665 | HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), |
@@ -669,7 +669,7 @@ static struct hda_bind_ctls ad1986a_bind_pcm_vol = { | |||
669 | }, | 669 | }, |
670 | }; | 670 | }; |
671 | 671 | ||
672 | static struct hda_bind_ctls ad1986a_bind_pcm_sw = { | 672 | static const struct hda_bind_ctls ad1986a_bind_pcm_sw = { |
673 | .ops = &snd_hda_bind_sw, | 673 | .ops = &snd_hda_bind_sw, |
674 | .values = { | 674 | .values = { |
675 | HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), | 675 | HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), |
@@ -682,7 +682,7 @@ static struct hda_bind_ctls ad1986a_bind_pcm_sw = { | |||
682 | /* | 682 | /* |
683 | * mixers | 683 | * mixers |
684 | */ | 684 | */ |
685 | static struct snd_kcontrol_new ad1986a_mixers[] = { | 685 | static const struct snd_kcontrol_new ad1986a_mixers[] = { |
686 | /* | 686 | /* |
687 | * bind volumes/mutes of 3 DACs as a single PCM control for simplicity | 687 | * bind volumes/mutes of 3 DACs as a single PCM control for simplicity |
688 | */ | 688 | */ |
@@ -723,7 +723,7 @@ static struct snd_kcontrol_new ad1986a_mixers[] = { | |||
723 | }; | 723 | }; |
724 | 724 | ||
725 | /* additional mixers for 3stack mode */ | 725 | /* additional mixers for 3stack mode */ |
726 | static struct snd_kcontrol_new ad1986a_3st_mixers[] = { | 726 | static const struct snd_kcontrol_new ad1986a_3st_mixers[] = { |
727 | { | 727 | { |
728 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 728 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
729 | .name = "Channel Mode", | 729 | .name = "Channel Mode", |
@@ -735,10 +735,10 @@ static struct snd_kcontrol_new ad1986a_3st_mixers[] = { | |||
735 | }; | 735 | }; |
736 | 736 | ||
737 | /* laptop model - 2ch only */ | 737 | /* laptop model - 2ch only */ |
738 | static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; | 738 | static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; |
739 | 739 | ||
740 | /* master controls both pins 0x1a and 0x1b */ | 740 | /* master controls both pins 0x1a and 0x1b */ |
741 | static struct hda_bind_ctls ad1986a_laptop_master_vol = { | 741 | static const struct hda_bind_ctls ad1986a_laptop_master_vol = { |
742 | .ops = &snd_hda_bind_vol, | 742 | .ops = &snd_hda_bind_vol, |
743 | .values = { | 743 | .values = { |
744 | HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), | 744 | HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), |
@@ -747,7 +747,7 @@ static struct hda_bind_ctls ad1986a_laptop_master_vol = { | |||
747 | }, | 747 | }, |
748 | }; | 748 | }; |
749 | 749 | ||
750 | static struct hda_bind_ctls ad1986a_laptop_master_sw = { | 750 | static const struct hda_bind_ctls ad1986a_laptop_master_sw = { |
751 | .ops = &snd_hda_bind_sw, | 751 | .ops = &snd_hda_bind_sw, |
752 | .values = { | 752 | .values = { |
753 | HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), | 753 | HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), |
@@ -756,7 +756,7 @@ static struct hda_bind_ctls ad1986a_laptop_master_sw = { | |||
756 | }, | 756 | }, |
757 | }; | 757 | }; |
758 | 758 | ||
759 | static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { | 759 | static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = { |
760 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 760 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
761 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), | 761 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), |
762 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), | 762 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), |
@@ -787,7 +787,7 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { | |||
787 | 787 | ||
788 | /* laptop-eapd model - 2ch only */ | 788 | /* laptop-eapd model - 2ch only */ |
789 | 789 | ||
790 | static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { | 790 | static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = { |
791 | .num_items = 3, | 791 | .num_items = 3, |
792 | .items = { | 792 | .items = { |
793 | { "Mic", 0x0 }, | 793 | { "Mic", 0x0 }, |
@@ -796,7 +796,7 @@ static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { | |||
796 | }, | 796 | }, |
797 | }; | 797 | }; |
798 | 798 | ||
799 | static struct hda_input_mux ad1986a_automic_capture_source = { | 799 | static const struct hda_input_mux ad1986a_automic_capture_source = { |
800 | .num_items = 2, | 800 | .num_items = 2, |
801 | .items = { | 801 | .items = { |
802 | { "Mic", 0x0 }, | 802 | { "Mic", 0x0 }, |
@@ -804,13 +804,13 @@ static struct hda_input_mux ad1986a_automic_capture_source = { | |||
804 | }, | 804 | }, |
805 | }; | 805 | }; |
806 | 806 | ||
807 | static struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = { | 807 | static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = { |
808 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), | 808 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), |
809 | HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), | 809 | HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), |
810 | { } /* end */ | 810 | { } /* end */ |
811 | }; | 811 | }; |
812 | 812 | ||
813 | static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { | 813 | static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { |
814 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 814 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
815 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), | 815 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), |
816 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), | 816 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), |
@@ -837,7 +837,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { | |||
837 | { } /* end */ | 837 | { } /* end */ |
838 | }; | 838 | }; |
839 | 839 | ||
840 | static struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { | 840 | static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { |
841 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), | 841 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), |
842 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), | 842 | HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), |
843 | { } /* end */ | 843 | { } /* end */ |
@@ -931,7 +931,7 @@ static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
931 | return change; | 931 | return change; |
932 | } | 932 | } |
933 | 933 | ||
934 | static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { | 934 | static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { |
935 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), | 935 | HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), |
936 | { | 936 | { |
937 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 937 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -949,7 +949,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { | |||
949 | /* | 949 | /* |
950 | * initialization verbs | 950 | * initialization verbs |
951 | */ | 951 | */ |
952 | static struct hda_verb ad1986a_init_verbs[] = { | 952 | static const struct hda_verb ad1986a_init_verbs[] = { |
953 | /* Front, Surround, CLFE DAC; mute as default */ | 953 | /* Front, Surround, CLFE DAC; mute as default */ |
954 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 954 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, |
955 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 955 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, |
@@ -1004,7 +1004,7 @@ static struct hda_verb ad1986a_init_verbs[] = { | |||
1004 | { } /* end */ | 1004 | { } /* end */ |
1005 | }; | 1005 | }; |
1006 | 1006 | ||
1007 | static struct hda_verb ad1986a_ch2_init[] = { | 1007 | static const struct hda_verb ad1986a_ch2_init[] = { |
1008 | /* Surround out -> Line In */ | 1008 | /* Surround out -> Line In */ |
1009 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 1009 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
1010 | /* Line-in selectors */ | 1010 | /* Line-in selectors */ |
@@ -1016,7 +1016,7 @@ static struct hda_verb ad1986a_ch2_init[] = { | |||
1016 | { } /* end */ | 1016 | { } /* end */ |
1017 | }; | 1017 | }; |
1018 | 1018 | ||
1019 | static struct hda_verb ad1986a_ch4_init[] = { | 1019 | static const struct hda_verb ad1986a_ch4_init[] = { |
1020 | /* Surround out -> Surround */ | 1020 | /* Surround out -> Surround */ |
1021 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 1021 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
1022 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, | 1022 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
@@ -1026,7 +1026,7 @@ static struct hda_verb ad1986a_ch4_init[] = { | |||
1026 | { } /* end */ | 1026 | { } /* end */ |
1027 | }; | 1027 | }; |
1028 | 1028 | ||
1029 | static struct hda_verb ad1986a_ch6_init[] = { | 1029 | static const struct hda_verb ad1986a_ch6_init[] = { |
1030 | /* Surround out -> Surround out */ | 1030 | /* Surround out -> Surround out */ |
1031 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 1031 | { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
1032 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, | 1032 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
@@ -1036,19 +1036,19 @@ static struct hda_verb ad1986a_ch6_init[] = { | |||
1036 | { } /* end */ | 1036 | { } /* end */ |
1037 | }; | 1037 | }; |
1038 | 1038 | ||
1039 | static struct hda_channel_mode ad1986a_modes[3] = { | 1039 | static const struct hda_channel_mode ad1986a_modes[3] = { |
1040 | { 2, ad1986a_ch2_init }, | 1040 | { 2, ad1986a_ch2_init }, |
1041 | { 4, ad1986a_ch4_init }, | 1041 | { 4, ad1986a_ch4_init }, |
1042 | { 6, ad1986a_ch6_init }, | 1042 | { 6, ad1986a_ch6_init }, |
1043 | }; | 1043 | }; |
1044 | 1044 | ||
1045 | /* eapd initialization */ | 1045 | /* eapd initialization */ |
1046 | static struct hda_verb ad1986a_eapd_init_verbs[] = { | 1046 | static const struct hda_verb ad1986a_eapd_init_verbs[] = { |
1047 | {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, | 1047 | {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, |
1048 | {} | 1048 | {} |
1049 | }; | 1049 | }; |
1050 | 1050 | ||
1051 | static struct hda_verb ad1986a_automic_verbs[] = { | 1051 | static const struct hda_verb ad1986a_automic_verbs[] = { |
1052 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 1052 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
1053 | {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 1053 | {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
1054 | /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/ | 1054 | /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/ |
@@ -1058,7 +1058,7 @@ static struct hda_verb ad1986a_automic_verbs[] = { | |||
1058 | }; | 1058 | }; |
1059 | 1059 | ||
1060 | /* Ultra initialization */ | 1060 | /* Ultra initialization */ |
1061 | static struct hda_verb ad1986a_ultra_init[] = { | 1061 | static const struct hda_verb ad1986a_ultra_init[] = { |
1062 | /* eapd initialization */ | 1062 | /* eapd initialization */ |
1063 | { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, | 1063 | { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, |
1064 | /* CLFE -> Mic in */ | 1064 | /* CLFE -> Mic in */ |
@@ -1069,7 +1069,7 @@ static struct hda_verb ad1986a_ultra_init[] = { | |||
1069 | }; | 1069 | }; |
1070 | 1070 | ||
1071 | /* pin sensing on HP jack */ | 1071 | /* pin sensing on HP jack */ |
1072 | static struct hda_verb ad1986a_hp_init_verbs[] = { | 1072 | static const struct hda_verb ad1986a_hp_init_verbs[] = { |
1073 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT}, | 1073 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT}, |
1074 | {} | 1074 | {} |
1075 | }; | 1075 | }; |
@@ -1120,7 +1120,7 @@ static const char * const ad1986a_models[AD1986A_MODELS] = { | |||
1120 | [AD1986A_SAMSUNG_P50] = "samsung-p50", | 1120 | [AD1986A_SAMSUNG_P50] = "samsung-p50", |
1121 | }; | 1121 | }; |
1122 | 1122 | ||
1123 | static struct snd_pci_quirk ad1986a_cfg_tbl[] = { | 1123 | static const struct snd_pci_quirk ad1986a_cfg_tbl[] = { |
1124 | SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD), | 1124 | SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD), |
1125 | SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD), | 1125 | SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD), |
1126 | SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD), | 1126 | SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD), |
@@ -1152,7 +1152,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { | |||
1152 | }; | 1152 | }; |
1153 | 1153 | ||
1154 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1154 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1155 | static struct hda_amp_list ad1986a_loopbacks[] = { | 1155 | static const struct hda_amp_list ad1986a_loopbacks[] = { |
1156 | { 0x13, HDA_OUTPUT, 0 }, /* Mic */ | 1156 | { 0x13, HDA_OUTPUT, 0 }, /* Mic */ |
1157 | { 0x14, HDA_OUTPUT, 0 }, /* Phone */ | 1157 | { 0x14, HDA_OUTPUT, 0 }, /* Phone */ |
1158 | { 0x15, HDA_OUTPUT, 0 }, /* CD */ | 1158 | { 0x15, HDA_OUTPUT, 0 }, /* CD */ |
@@ -1329,11 +1329,11 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
1329 | #define AD1983_DAC 0x03 | 1329 | #define AD1983_DAC 0x03 |
1330 | #define AD1983_ADC 0x04 | 1330 | #define AD1983_ADC 0x04 |
1331 | 1331 | ||
1332 | static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; | 1332 | static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; |
1333 | static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; | 1333 | static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; |
1334 | static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; | 1334 | static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; |
1335 | 1335 | ||
1336 | static struct hda_input_mux ad1983_capture_source = { | 1336 | static const struct hda_input_mux ad1983_capture_source = { |
1337 | .num_items = 4, | 1337 | .num_items = 4, |
1338 | .items = { | 1338 | .items = { |
1339 | { "Mic", 0x0 }, | 1339 | { "Mic", 0x0 }, |
@@ -1348,7 +1348,7 @@ static struct hda_input_mux ad1983_capture_source = { | |||
1348 | */ | 1348 | */ |
1349 | static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) | 1349 | static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) |
1350 | { | 1350 | { |
1351 | static char *texts[] = { "PCM", "ADC" }; | 1351 | static const char * const texts[] = { "PCM", "ADC" }; |
1352 | 1352 | ||
1353 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 1353 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
1354 | uinfo->count = 1; | 1354 | uinfo->count = 1; |
@@ -1385,7 +1385,7 @@ static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ | |||
1385 | return 0; | 1385 | return 0; |
1386 | } | 1386 | } |
1387 | 1387 | ||
1388 | static struct snd_kcontrol_new ad1983_mixers[] = { | 1388 | static const struct snd_kcontrol_new ad1983_mixers[] = { |
1389 | HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), | 1389 | HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), |
1390 | HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), | 1390 | HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), |
1391 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), | 1391 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), |
@@ -1418,7 +1418,7 @@ static struct snd_kcontrol_new ad1983_mixers[] = { | |||
1418 | { } /* end */ | 1418 | { } /* end */ |
1419 | }; | 1419 | }; |
1420 | 1420 | ||
1421 | static struct hda_verb ad1983_init_verbs[] = { | 1421 | static const struct hda_verb ad1983_init_verbs[] = { |
1422 | /* Front, HP, Mono; mute as default */ | 1422 | /* Front, HP, Mono; mute as default */ |
1423 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 1423 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, |
1424 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 1424 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, |
@@ -1458,7 +1458,7 @@ static struct hda_verb ad1983_init_verbs[] = { | |||
1458 | }; | 1458 | }; |
1459 | 1459 | ||
1460 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1460 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1461 | static struct hda_amp_list ad1983_loopbacks[] = { | 1461 | static const struct hda_amp_list ad1983_loopbacks[] = { |
1462 | { 0x12, HDA_OUTPUT, 0 }, /* Mic */ | 1462 | { 0x12, HDA_OUTPUT, 0 }, /* Mic */ |
1463 | { 0x13, HDA_OUTPUT, 0 }, /* Line */ | 1463 | { 0x13, HDA_OUTPUT, 0 }, /* Line */ |
1464 | { } /* end */ | 1464 | { } /* end */ |
@@ -1518,12 +1518,12 @@ static int patch_ad1983(struct hda_codec *codec) | |||
1518 | #define AD1981_DAC 0x03 | 1518 | #define AD1981_DAC 0x03 |
1519 | #define AD1981_ADC 0x04 | 1519 | #define AD1981_ADC 0x04 |
1520 | 1520 | ||
1521 | static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; | 1521 | static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; |
1522 | static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; | 1522 | static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; |
1523 | static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; | 1523 | static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; |
1524 | 1524 | ||
1525 | /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ | 1525 | /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ |
1526 | static struct hda_input_mux ad1981_capture_source = { | 1526 | static const struct hda_input_mux ad1981_capture_source = { |
1527 | .num_items = 7, | 1527 | .num_items = 7, |
1528 | .items = { | 1528 | .items = { |
1529 | { "Front Mic", 0x0 }, | 1529 | { "Front Mic", 0x0 }, |
@@ -1536,7 +1536,7 @@ static struct hda_input_mux ad1981_capture_source = { | |||
1536 | }, | 1536 | }, |
1537 | }; | 1537 | }; |
1538 | 1538 | ||
1539 | static struct snd_kcontrol_new ad1981_mixers[] = { | 1539 | static const struct snd_kcontrol_new ad1981_mixers[] = { |
1540 | HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), | 1540 | HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), |
1541 | HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), | 1541 | HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), |
1542 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), | 1542 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), |
@@ -1577,7 +1577,7 @@ static struct snd_kcontrol_new ad1981_mixers[] = { | |||
1577 | { } /* end */ | 1577 | { } /* end */ |
1578 | }; | 1578 | }; |
1579 | 1579 | ||
1580 | static struct hda_verb ad1981_init_verbs[] = { | 1580 | static const struct hda_verb ad1981_init_verbs[] = { |
1581 | /* Front, HP, Mono; mute as default */ | 1581 | /* Front, HP, Mono; mute as default */ |
1582 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 1582 | {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, |
1583 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 1583 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, |
@@ -1625,7 +1625,7 @@ static struct hda_verb ad1981_init_verbs[] = { | |||
1625 | }; | 1625 | }; |
1626 | 1626 | ||
1627 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1627 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1628 | static struct hda_amp_list ad1981_loopbacks[] = { | 1628 | static const struct hda_amp_list ad1981_loopbacks[] = { |
1629 | { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */ | 1629 | { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */ |
1630 | { 0x13, HDA_OUTPUT, 0 }, /* Line */ | 1630 | { 0x13, HDA_OUTPUT, 0 }, /* Line */ |
1631 | { 0x1b, HDA_OUTPUT, 0 }, /* Aux */ | 1631 | { 0x1b, HDA_OUTPUT, 0 }, /* Aux */ |
@@ -1645,7 +1645,7 @@ static struct hda_amp_list ad1981_loopbacks[] = { | |||
1645 | #define AD1981_HP_EVENT 0x37 | 1645 | #define AD1981_HP_EVENT 0x37 |
1646 | #define AD1981_MIC_EVENT 0x38 | 1646 | #define AD1981_MIC_EVENT 0x38 |
1647 | 1647 | ||
1648 | static struct hda_verb ad1981_hp_init_verbs[] = { | 1648 | static const struct hda_verb ad1981_hp_init_verbs[] = { |
1649 | {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */ | 1649 | {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */ |
1650 | /* pin sensing on HP and Mic jacks */ | 1650 | /* pin sensing on HP and Mic jacks */ |
1651 | {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, | 1651 | {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, |
@@ -1674,7 +1674,7 @@ static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
1674 | } | 1674 | } |
1675 | 1675 | ||
1676 | /* bind volumes of both NID 0x05 and 0x06 */ | 1676 | /* bind volumes of both NID 0x05 and 0x06 */ |
1677 | static struct hda_bind_ctls ad1981_hp_bind_master_vol = { | 1677 | static const struct hda_bind_ctls ad1981_hp_bind_master_vol = { |
1678 | .ops = &snd_hda_bind_vol, | 1678 | .ops = &snd_hda_bind_vol, |
1679 | .values = { | 1679 | .values = { |
1680 | HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), | 1680 | HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), |
@@ -1696,12 +1696,12 @@ static void ad1981_hp_automute(struct hda_codec *codec) | |||
1696 | /* toggle input of built-in and mic jack appropriately */ | 1696 | /* toggle input of built-in and mic jack appropriately */ |
1697 | static void ad1981_hp_automic(struct hda_codec *codec) | 1697 | static void ad1981_hp_automic(struct hda_codec *codec) |
1698 | { | 1698 | { |
1699 | static struct hda_verb mic_jack_on[] = { | 1699 | static const struct hda_verb mic_jack_on[] = { |
1700 | {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 1700 | {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, |
1701 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 1701 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, |
1702 | {} | 1702 | {} |
1703 | }; | 1703 | }; |
1704 | static struct hda_verb mic_jack_off[] = { | 1704 | static const struct hda_verb mic_jack_off[] = { |
1705 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 1705 | {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, |
1706 | {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 1706 | {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, |
1707 | {} | 1707 | {} |
@@ -1730,7 +1730,7 @@ static void ad1981_hp_unsol_event(struct hda_codec *codec, | |||
1730 | } | 1730 | } |
1731 | } | 1731 | } |
1732 | 1732 | ||
1733 | static struct hda_input_mux ad1981_hp_capture_source = { | 1733 | static const struct hda_input_mux ad1981_hp_capture_source = { |
1734 | .num_items = 3, | 1734 | .num_items = 3, |
1735 | .items = { | 1735 | .items = { |
1736 | { "Mic", 0x0 }, | 1736 | { "Mic", 0x0 }, |
@@ -1739,7 +1739,7 @@ static struct hda_input_mux ad1981_hp_capture_source = { | |||
1739 | }, | 1739 | }, |
1740 | }; | 1740 | }; |
1741 | 1741 | ||
1742 | static struct snd_kcontrol_new ad1981_hp_mixers[] = { | 1742 | static const struct snd_kcontrol_new ad1981_hp_mixers[] = { |
1743 | HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), | 1743 | HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), |
1744 | { | 1744 | { |
1745 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1745 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -1790,7 +1790,7 @@ static int ad1981_hp_init(struct hda_codec *codec) | |||
1790 | } | 1790 | } |
1791 | 1791 | ||
1792 | /* configuration for Toshiba Laptops */ | 1792 | /* configuration for Toshiba Laptops */ |
1793 | static struct hda_verb ad1981_toshiba_init_verbs[] = { | 1793 | static const struct hda_verb ad1981_toshiba_init_verbs[] = { |
1794 | {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */ | 1794 | {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */ |
1795 | /* pin sensing on HP and Mic jacks */ | 1795 | /* pin sensing on HP and Mic jacks */ |
1796 | {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, | 1796 | {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, |
@@ -1798,14 +1798,14 @@ static struct hda_verb ad1981_toshiba_init_verbs[] = { | |||
1798 | {} | 1798 | {} |
1799 | }; | 1799 | }; |
1800 | 1800 | ||
1801 | static struct snd_kcontrol_new ad1981_toshiba_mixers[] = { | 1801 | static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = { |
1802 | HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT), | 1802 | HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT), |
1803 | HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT), | 1803 | HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT), |
1804 | { } | 1804 | { } |
1805 | }; | 1805 | }; |
1806 | 1806 | ||
1807 | /* configuration for Lenovo Thinkpad T60 */ | 1807 | /* configuration for Lenovo Thinkpad T60 */ |
1808 | static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { | 1808 | static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { |
1809 | HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT), | 1809 | HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT), |
1810 | HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT), | 1810 | HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT), |
1811 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), | 1811 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), |
@@ -1835,7 +1835,7 @@ static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { | |||
1835 | { } /* end */ | 1835 | { } /* end */ |
1836 | }; | 1836 | }; |
1837 | 1837 | ||
1838 | static struct hda_input_mux ad1981_thinkpad_capture_source = { | 1838 | static const struct hda_input_mux ad1981_thinkpad_capture_source = { |
1839 | .num_items = 3, | 1839 | .num_items = 3, |
1840 | .items = { | 1840 | .items = { |
1841 | { "Mic", 0x0 }, | 1841 | { "Mic", 0x0 }, |
@@ -1860,7 +1860,7 @@ static const char * const ad1981_models[AD1981_MODELS] = { | |||
1860 | [AD1981_TOSHIBA] = "toshiba" | 1860 | [AD1981_TOSHIBA] = "toshiba" |
1861 | }; | 1861 | }; |
1862 | 1862 | ||
1863 | static struct snd_pci_quirk ad1981_cfg_tbl[] = { | 1863 | static const struct snd_pci_quirk ad1981_cfg_tbl[] = { |
1864 | SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), | 1864 | SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), |
1865 | SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), | 1865 | SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), |
1866 | /* All HP models */ | 1866 | /* All HP models */ |
@@ -2075,32 +2075,32 @@ enum { | |||
2075 | * mixers | 2075 | * mixers |
2076 | */ | 2076 | */ |
2077 | 2077 | ||
2078 | static hda_nid_t ad1988_6stack_dac_nids[4] = { | 2078 | static const hda_nid_t ad1988_6stack_dac_nids[4] = { |
2079 | 0x04, 0x06, 0x05, 0x0a | 2079 | 0x04, 0x06, 0x05, 0x0a |
2080 | }; | 2080 | }; |
2081 | 2081 | ||
2082 | static hda_nid_t ad1988_3stack_dac_nids[3] = { | 2082 | static const hda_nid_t ad1988_3stack_dac_nids[3] = { |
2083 | 0x04, 0x05, 0x0a | 2083 | 0x04, 0x05, 0x0a |
2084 | }; | 2084 | }; |
2085 | 2085 | ||
2086 | /* for AD1988A revision-2, DAC2-4 are swapped */ | 2086 | /* for AD1988A revision-2, DAC2-4 are swapped */ |
2087 | static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { | 2087 | static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { |
2088 | 0x04, 0x05, 0x0a, 0x06 | 2088 | 0x04, 0x05, 0x0a, 0x06 |
2089 | }; | 2089 | }; |
2090 | 2090 | ||
2091 | static hda_nid_t ad1988_alt_dac_nid[1] = { | 2091 | static const hda_nid_t ad1988_alt_dac_nid[1] = { |
2092 | 0x03 | 2092 | 0x03 |
2093 | }; | 2093 | }; |
2094 | 2094 | ||
2095 | static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { | 2095 | static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { |
2096 | 0x04, 0x0a, 0x06 | 2096 | 0x04, 0x0a, 0x06 |
2097 | }; | 2097 | }; |
2098 | 2098 | ||
2099 | static hda_nid_t ad1988_adc_nids[3] = { | 2099 | static const hda_nid_t ad1988_adc_nids[3] = { |
2100 | 0x08, 0x09, 0x0f | 2100 | 0x08, 0x09, 0x0f |
2101 | }; | 2101 | }; |
2102 | 2102 | ||
2103 | static hda_nid_t ad1988_capsrc_nids[3] = { | 2103 | static const hda_nid_t ad1988_capsrc_nids[3] = { |
2104 | 0x0c, 0x0d, 0x0e | 2104 | 0x0c, 0x0d, 0x0e |
2105 | }; | 2105 | }; |
2106 | 2106 | ||
@@ -2108,11 +2108,11 @@ static hda_nid_t ad1988_capsrc_nids[3] = { | |||
2108 | #define AD1988_SPDIF_OUT_HDMI 0x0b | 2108 | #define AD1988_SPDIF_OUT_HDMI 0x0b |
2109 | #define AD1988_SPDIF_IN 0x07 | 2109 | #define AD1988_SPDIF_IN 0x07 |
2110 | 2110 | ||
2111 | static hda_nid_t ad1989b_slave_dig_outs[] = { | 2111 | static const hda_nid_t ad1989b_slave_dig_outs[] = { |
2112 | AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 | 2112 | AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 |
2113 | }; | 2113 | }; |
2114 | 2114 | ||
2115 | static struct hda_input_mux ad1988_6stack_capture_source = { | 2115 | static const struct hda_input_mux ad1988_6stack_capture_source = { |
2116 | .num_items = 5, | 2116 | .num_items = 5, |
2117 | .items = { | 2117 | .items = { |
2118 | { "Front Mic", 0x1 }, /* port-B */ | 2118 | { "Front Mic", 0x1 }, /* port-B */ |
@@ -2123,7 +2123,7 @@ static struct hda_input_mux ad1988_6stack_capture_source = { | |||
2123 | }, | 2123 | }, |
2124 | }; | 2124 | }; |
2125 | 2125 | ||
2126 | static struct hda_input_mux ad1988_laptop_capture_source = { | 2126 | static const struct hda_input_mux ad1988_laptop_capture_source = { |
2127 | .num_items = 3, | 2127 | .num_items = 3, |
2128 | .items = { | 2128 | .items = { |
2129 | { "Mic/Line", 0x1 }, /* port-B */ | 2129 | { "Mic/Line", 0x1 }, /* port-B */ |
@@ -2166,7 +2166,7 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
2166 | } | 2166 | } |
2167 | 2167 | ||
2168 | /* 6-stack mode */ | 2168 | /* 6-stack mode */ |
2169 | static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { | 2169 | static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = { |
2170 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 2170 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
2171 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), | 2171 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), |
2172 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), | 2172 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), |
@@ -2175,7 +2175,7 @@ static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { | |||
2175 | { } /* end */ | 2175 | { } /* end */ |
2176 | }; | 2176 | }; |
2177 | 2177 | ||
2178 | static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { | 2178 | static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { |
2179 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 2179 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
2180 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT), | 2180 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT), |
2181 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | 2181 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), |
@@ -2184,7 +2184,7 @@ static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { | |||
2184 | { } /* end */ | 2184 | { } /* end */ |
2185 | }; | 2185 | }; |
2186 | 2186 | ||
2187 | static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { | 2187 | static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = { |
2188 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), | 2188 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), |
2189 | HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), | 2189 | HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), |
2190 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), | 2190 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), |
@@ -2211,14 +2211,14 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { | |||
2211 | { } /* end */ | 2211 | { } /* end */ |
2212 | }; | 2212 | }; |
2213 | 2213 | ||
2214 | static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = { | 2214 | static const struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = { |
2215 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 2215 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
2216 | 2216 | ||
2217 | { } /* end */ | 2217 | { } /* end */ |
2218 | }; | 2218 | }; |
2219 | 2219 | ||
2220 | /* 3-stack mode */ | 2220 | /* 3-stack mode */ |
2221 | static struct snd_kcontrol_new ad1988_3stack_mixers1[] = { | 2221 | static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = { |
2222 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 2222 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
2223 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), | 2223 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), |
2224 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), | 2224 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), |
@@ -2226,7 +2226,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers1[] = { | |||
2226 | { } /* end */ | 2226 | { } /* end */ |
2227 | }; | 2227 | }; |
2228 | 2228 | ||
2229 | static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { | 2229 | static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { |
2230 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 2230 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
2231 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), | 2231 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), |
2232 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT), | 2232 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT), |
@@ -2234,7 +2234,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { | |||
2234 | { } /* end */ | 2234 | { } /* end */ |
2235 | }; | 2235 | }; |
2236 | 2236 | ||
2237 | static struct snd_kcontrol_new ad1988_3stack_mixers2[] = { | 2237 | static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = { |
2238 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), | 2238 | HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), |
2239 | HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), | 2239 | HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), |
2240 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), | 2240 | HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), |
@@ -2268,7 +2268,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers2[] = { | |||
2268 | }; | 2268 | }; |
2269 | 2269 | ||
2270 | /* laptop mode */ | 2270 | /* laptop mode */ |
2271 | static struct snd_kcontrol_new ad1988_laptop_mixers[] = { | 2271 | static const struct snd_kcontrol_new ad1988_laptop_mixers[] = { |
2272 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 2272 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
2273 | HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), | 2273 | HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), |
2274 | HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), | 2274 | HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), |
@@ -2299,7 +2299,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = { | |||
2299 | }; | 2299 | }; |
2300 | 2300 | ||
2301 | /* capture */ | 2301 | /* capture */ |
2302 | static struct snd_kcontrol_new ad1988_capture_mixers[] = { | 2302 | static const struct snd_kcontrol_new ad1988_capture_mixers[] = { |
2303 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), | 2303 | HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), |
2304 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), | 2304 | HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), |
2305 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), | 2305 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), |
@@ -2324,7 +2324,7 @@ static struct snd_kcontrol_new ad1988_capture_mixers[] = { | |||
2324 | static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol, | 2324 | static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol, |
2325 | struct snd_ctl_elem_info *uinfo) | 2325 | struct snd_ctl_elem_info *uinfo) |
2326 | { | 2326 | { |
2327 | static char *texts[] = { | 2327 | static const char * const texts[] = { |
2328 | "PCM", "ADC1", "ADC2", "ADC3" | 2328 | "PCM", "ADC1", "ADC2", "ADC3" |
2329 | }; | 2329 | }; |
2330 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 2330 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
@@ -2405,7 +2405,7 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, | |||
2405 | return change; | 2405 | return change; |
2406 | } | 2406 | } |
2407 | 2407 | ||
2408 | static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { | 2408 | static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { |
2409 | HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | 2409 | HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), |
2410 | { | 2410 | { |
2411 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2411 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -2418,12 +2418,12 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { | |||
2418 | { } /* end */ | 2418 | { } /* end */ |
2419 | }; | 2419 | }; |
2420 | 2420 | ||
2421 | static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { | 2421 | static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { |
2422 | HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT), | 2422 | HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT), |
2423 | { } /* end */ | 2423 | { } /* end */ |
2424 | }; | 2424 | }; |
2425 | 2425 | ||
2426 | static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { | 2426 | static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { |
2427 | HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), | 2427 | HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), |
2428 | HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT), | 2428 | HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT), |
2429 | { } /* end */ | 2429 | { } /* end */ |
@@ -2436,7 +2436,7 @@ static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { | |||
2436 | /* | 2436 | /* |
2437 | * for 6-stack (+dig) | 2437 | * for 6-stack (+dig) |
2438 | */ | 2438 | */ |
2439 | static struct hda_verb ad1988_6stack_init_verbs[] = { | 2439 | static const struct hda_verb ad1988_6stack_init_verbs[] = { |
2440 | /* Front, Surround, CLFE, side DAC; unmute as default */ | 2440 | /* Front, Surround, CLFE, side DAC; unmute as default */ |
2441 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2441 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2442 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2442 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -2496,7 +2496,7 @@ static struct hda_verb ad1988_6stack_init_verbs[] = { | |||
2496 | { } | 2496 | { } |
2497 | }; | 2497 | }; |
2498 | 2498 | ||
2499 | static struct hda_verb ad1988_6stack_fp_init_verbs[] = { | 2499 | static const struct hda_verb ad1988_6stack_fp_init_verbs[] = { |
2500 | /* Headphone; unmute as default */ | 2500 | /* Headphone; unmute as default */ |
2501 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2501 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2502 | /* Port-A front headphon path */ | 2502 | /* Port-A front headphon path */ |
@@ -2509,7 +2509,7 @@ static struct hda_verb ad1988_6stack_fp_init_verbs[] = { | |||
2509 | { } | 2509 | { } |
2510 | }; | 2510 | }; |
2511 | 2511 | ||
2512 | static struct hda_verb ad1988_capture_init_verbs[] = { | 2512 | static const struct hda_verb ad1988_capture_init_verbs[] = { |
2513 | /* mute analog mix */ | 2513 | /* mute analog mix */ |
2514 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 2514 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
2515 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 2515 | {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
@@ -2527,7 +2527,7 @@ static struct hda_verb ad1988_capture_init_verbs[] = { | |||
2527 | { } | 2527 | { } |
2528 | }; | 2528 | }; |
2529 | 2529 | ||
2530 | static struct hda_verb ad1988_spdif_init_verbs[] = { | 2530 | static const struct hda_verb ad1988_spdif_init_verbs[] = { |
2531 | /* SPDIF out sel */ | 2531 | /* SPDIF out sel */ |
2532 | {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ | 2532 | {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ |
2533 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ | 2533 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ |
@@ -2539,14 +2539,14 @@ static struct hda_verb ad1988_spdif_init_verbs[] = { | |||
2539 | { } | 2539 | { } |
2540 | }; | 2540 | }; |
2541 | 2541 | ||
2542 | static struct hda_verb ad1988_spdif_in_init_verbs[] = { | 2542 | static const struct hda_verb ad1988_spdif_in_init_verbs[] = { |
2543 | /* unmute SPDIF input pin */ | 2543 | /* unmute SPDIF input pin */ |
2544 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 2544 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
2545 | { } | 2545 | { } |
2546 | }; | 2546 | }; |
2547 | 2547 | ||
2548 | /* AD1989 has no ADC -> SPDIF route */ | 2548 | /* AD1989 has no ADC -> SPDIF route */ |
2549 | static struct hda_verb ad1989_spdif_init_verbs[] = { | 2549 | static const struct hda_verb ad1989_spdif_init_verbs[] = { |
2550 | /* SPDIF-1 out pin */ | 2550 | /* SPDIF-1 out pin */ |
2551 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 2551 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
2552 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ | 2552 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ |
@@ -2559,7 +2559,7 @@ static struct hda_verb ad1989_spdif_init_verbs[] = { | |||
2559 | /* | 2559 | /* |
2560 | * verbs for 3stack (+dig) | 2560 | * verbs for 3stack (+dig) |
2561 | */ | 2561 | */ |
2562 | static struct hda_verb ad1988_3stack_ch2_init[] = { | 2562 | static const struct hda_verb ad1988_3stack_ch2_init[] = { |
2563 | /* set port-C to line-in */ | 2563 | /* set port-C to line-in */ |
2564 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 2564 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
2565 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 2565 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
@@ -2569,7 +2569,7 @@ static struct hda_verb ad1988_3stack_ch2_init[] = { | |||
2569 | { } /* end */ | 2569 | { } /* end */ |
2570 | }; | 2570 | }; |
2571 | 2571 | ||
2572 | static struct hda_verb ad1988_3stack_ch6_init[] = { | 2572 | static const struct hda_verb ad1988_3stack_ch6_init[] = { |
2573 | /* set port-C to surround out */ | 2573 | /* set port-C to surround out */ |
2574 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 2574 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
2575 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 2575 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
@@ -2579,12 +2579,12 @@ static struct hda_verb ad1988_3stack_ch6_init[] = { | |||
2579 | { } /* end */ | 2579 | { } /* end */ |
2580 | }; | 2580 | }; |
2581 | 2581 | ||
2582 | static struct hda_channel_mode ad1988_3stack_modes[2] = { | 2582 | static const struct hda_channel_mode ad1988_3stack_modes[2] = { |
2583 | { 2, ad1988_3stack_ch2_init }, | 2583 | { 2, ad1988_3stack_ch2_init }, |
2584 | { 6, ad1988_3stack_ch6_init }, | 2584 | { 6, ad1988_3stack_ch6_init }, |
2585 | }; | 2585 | }; |
2586 | 2586 | ||
2587 | static struct hda_verb ad1988_3stack_init_verbs[] = { | 2587 | static const struct hda_verb ad1988_3stack_init_verbs[] = { |
2588 | /* Front, Surround, CLFE, side DAC; unmute as default */ | 2588 | /* Front, Surround, CLFE, side DAC; unmute as default */ |
2589 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2589 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2590 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2590 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -2644,13 +2644,13 @@ static struct hda_verb ad1988_3stack_init_verbs[] = { | |||
2644 | /* | 2644 | /* |
2645 | * verbs for laptop mode (+dig) | 2645 | * verbs for laptop mode (+dig) |
2646 | */ | 2646 | */ |
2647 | static struct hda_verb ad1988_laptop_hp_on[] = { | 2647 | static const struct hda_verb ad1988_laptop_hp_on[] = { |
2648 | /* unmute port-A and mute port-D */ | 2648 | /* unmute port-A and mute port-D */ |
2649 | { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 2649 | { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
2650 | { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 2650 | { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
2651 | { } /* end */ | 2651 | { } /* end */ |
2652 | }; | 2652 | }; |
2653 | static struct hda_verb ad1988_laptop_hp_off[] = { | 2653 | static const struct hda_verb ad1988_laptop_hp_off[] = { |
2654 | /* mute port-A and unmute port-D */ | 2654 | /* mute port-A and unmute port-D */ |
2655 | { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 2655 | { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
2656 | { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 2656 | { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
@@ -2659,7 +2659,7 @@ static struct hda_verb ad1988_laptop_hp_off[] = { | |||
2659 | 2659 | ||
2660 | #define AD1988_HP_EVENT 0x01 | 2660 | #define AD1988_HP_EVENT 0x01 |
2661 | 2661 | ||
2662 | static struct hda_verb ad1988_laptop_init_verbs[] = { | 2662 | static const struct hda_verb ad1988_laptop_init_verbs[] = { |
2663 | /* Front, Surround, CLFE, side DAC; unmute as default */ | 2663 | /* Front, Surround, CLFE, side DAC; unmute as default */ |
2664 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2664 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
2665 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 2665 | {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -2723,7 +2723,7 @@ static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res) | |||
2723 | } | 2723 | } |
2724 | 2724 | ||
2725 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2725 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2726 | static struct hda_amp_list ad1988_loopbacks[] = { | 2726 | static const struct hda_amp_list ad1988_loopbacks[] = { |
2727 | { 0x20, HDA_INPUT, 0 }, /* Front Mic */ | 2727 | { 0x20, HDA_INPUT, 0 }, /* Front Mic */ |
2728 | { 0x20, HDA_INPUT, 1 }, /* Line */ | 2728 | { 0x20, HDA_INPUT, 1 }, /* Line */ |
2729 | { 0x20, HDA_INPUT, 4 }, /* Mic */ | 2729 | { 0x20, HDA_INPUT, 4 }, /* Mic */ |
@@ -2741,7 +2741,7 @@ enum { | |||
2741 | AD_CTL_WIDGET_MUTE, | 2741 | AD_CTL_WIDGET_MUTE, |
2742 | AD_CTL_BIND_MUTE, | 2742 | AD_CTL_BIND_MUTE, |
2743 | }; | 2743 | }; |
2744 | static struct snd_kcontrol_new ad1988_control_templates[] = { | 2744 | static const struct snd_kcontrol_new ad1988_control_templates[] = { |
2745 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | 2745 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), |
2746 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | 2746 | HDA_CODEC_MUTE(NULL, 0, 0, 0), |
2747 | HDA_BIND_MUTE(NULL, 0, 0, 0), | 2747 | HDA_BIND_MUTE(NULL, 0, 0, 0), |
@@ -2770,18 +2770,18 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name, | |||
2770 | #define AD1988_PIN_CD_NID 0x18 | 2770 | #define AD1988_PIN_CD_NID 0x18 |
2771 | #define AD1988_PIN_BEEP_NID 0x10 | 2771 | #define AD1988_PIN_BEEP_NID 0x10 |
2772 | 2772 | ||
2773 | static hda_nid_t ad1988_mixer_nids[8] = { | 2773 | static const hda_nid_t ad1988_mixer_nids[8] = { |
2774 | /* A B C D E F G H */ | 2774 | /* A B C D E F G H */ |
2775 | 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28 | 2775 | 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28 |
2776 | }; | 2776 | }; |
2777 | 2777 | ||
2778 | static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) | 2778 | static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) |
2779 | { | 2779 | { |
2780 | static hda_nid_t idx_to_dac[8] = { | 2780 | static const hda_nid_t idx_to_dac[8] = { |
2781 | /* A B C D E F G H */ | 2781 | /* A B C D E F G H */ |
2782 | 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a | 2782 | 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a |
2783 | }; | 2783 | }; |
2784 | static hda_nid_t idx_to_dac_rev2[8] = { | 2784 | static const hda_nid_t idx_to_dac_rev2[8] = { |
2785 | /* A B C D E F G H */ | 2785 | /* A B C D E F G H */ |
2786 | 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 | 2786 | 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 |
2787 | }; | 2787 | }; |
@@ -2791,13 +2791,13 @@ static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) | |||
2791 | return idx_to_dac[idx]; | 2791 | return idx_to_dac[idx]; |
2792 | } | 2792 | } |
2793 | 2793 | ||
2794 | static hda_nid_t ad1988_boost_nids[8] = { | 2794 | static const hda_nid_t ad1988_boost_nids[8] = { |
2795 | 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0 | 2795 | 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0 |
2796 | }; | 2796 | }; |
2797 | 2797 | ||
2798 | static int ad1988_pin_idx(hda_nid_t nid) | 2798 | static int ad1988_pin_idx(hda_nid_t nid) |
2799 | { | 2799 | { |
2800 | static hda_nid_t ad1988_io_pins[8] = { | 2800 | static const hda_nid_t ad1988_io_pins[8] = { |
2801 | 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25 | 2801 | 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25 |
2802 | }; | 2802 | }; |
2803 | int i; | 2803 | int i; |
@@ -2809,7 +2809,7 @@ static int ad1988_pin_idx(hda_nid_t nid) | |||
2809 | 2809 | ||
2810 | static int ad1988_pin_to_loopback_idx(hda_nid_t nid) | 2810 | static int ad1988_pin_to_loopback_idx(hda_nid_t nid) |
2811 | { | 2811 | { |
2812 | static int loopback_idx[8] = { | 2812 | static const int loopback_idx[8] = { |
2813 | 2, 0, 1, 3, 4, 5, 1, 4 | 2813 | 2, 0, 1, 3, 4, 5, 1, 4 |
2814 | }; | 2814 | }; |
2815 | switch (nid) { | 2815 | switch (nid) { |
@@ -2822,7 +2822,7 @@ static int ad1988_pin_to_loopback_idx(hda_nid_t nid) | |||
2822 | 2822 | ||
2823 | static int ad1988_pin_to_adc_idx(hda_nid_t nid) | 2823 | static int ad1988_pin_to_adc_idx(hda_nid_t nid) |
2824 | { | 2824 | { |
2825 | static int adc_idx[8] = { | 2825 | static const int adc_idx[8] = { |
2826 | 0, 1, 2, 8, 4, 3, 6, 7 | 2826 | 0, 1, 2, 8, 4, 3, 6, 7 |
2827 | }; | 2827 | }; |
2828 | switch (nid) { | 2828 | switch (nid) { |
@@ -2845,7 +2845,7 @@ static int ad1988_auto_fill_dac_nids(struct hda_codec *codec, | |||
2845 | /* check the pins hardwired to audio widget */ | 2845 | /* check the pins hardwired to audio widget */ |
2846 | for (i = 0; i < cfg->line_outs; i++) { | 2846 | for (i = 0; i < cfg->line_outs; i++) { |
2847 | idx = ad1988_pin_idx(cfg->line_out_pins[i]); | 2847 | idx = ad1988_pin_idx(cfg->line_out_pins[i]); |
2848 | spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx); | 2848 | spec->private_dac_nids[i] = ad1988_idx_to_dac(codec, idx); |
2849 | } | 2849 | } |
2850 | spec->multiout.num_dacs = cfg->line_outs; | 2850 | spec->multiout.num_dacs = cfg->line_outs; |
2851 | return 0; | 2851 | return 0; |
@@ -3070,6 +3070,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec) | |||
3070 | 3070 | ||
3071 | for (i = 0; i < cfg->num_inputs; i++) { | 3071 | for (i = 0; i < cfg->num_inputs; i++) { |
3072 | hda_nid_t nid = cfg->inputs[i].pin; | 3072 | hda_nid_t nid = cfg->inputs[i].pin; |
3073 | int type = cfg->inputs[i].type; | ||
3073 | switch (nid) { | 3074 | switch (nid) { |
3074 | case 0x15: /* port-C */ | 3075 | case 0x15: /* port-C */ |
3075 | snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0); | 3076 | snd_hda_codec_write(codec, 0x33, 0, AC_VERB_SET_CONNECT_SEL, 0x0); |
@@ -3079,7 +3080,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec) | |||
3079 | break; | 3080 | break; |
3080 | } | 3081 | } |
3081 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 3082 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, |
3082 | i == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN); | 3083 | type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN); |
3083 | if (nid != AD1988_PIN_CD_NID) | 3084 | if (nid != AD1988_PIN_CD_NID) |
3084 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 3085 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, |
3085 | AMP_OUT_MUTE); | 3086 | AMP_OUT_MUTE); |
@@ -3154,10 +3155,11 @@ static const char * const ad1988_models[AD1988_MODEL_LAST] = { | |||
3154 | [AD1988_AUTO] = "auto", | 3155 | [AD1988_AUTO] = "auto", |
3155 | }; | 3156 | }; |
3156 | 3157 | ||
3157 | static struct snd_pci_quirk ad1988_cfg_tbl[] = { | 3158 | static const struct snd_pci_quirk ad1988_cfg_tbl[] = { |
3158 | SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), | 3159 | SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), |
3159 | SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), | 3160 | SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), |
3160 | 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), | ||
3161 | 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), |
3162 | {} | 3164 | {} |
3163 | }; | 3165 | }; |
@@ -3342,21 +3344,21 @@ static int patch_ad1988(struct hda_codec *codec) | |||
3342 | * but no build-up framework is given, so far. | 3344 | * but no build-up framework is given, so far. |
3343 | */ | 3345 | */ |
3344 | 3346 | ||
3345 | static hda_nid_t ad1884_dac_nids[1] = { | 3347 | static const hda_nid_t ad1884_dac_nids[1] = { |
3346 | 0x04, | 3348 | 0x04, |
3347 | }; | 3349 | }; |
3348 | 3350 | ||
3349 | static hda_nid_t ad1884_adc_nids[2] = { | 3351 | static const hda_nid_t ad1884_adc_nids[2] = { |
3350 | 0x08, 0x09, | 3352 | 0x08, 0x09, |
3351 | }; | 3353 | }; |
3352 | 3354 | ||
3353 | static hda_nid_t ad1884_capsrc_nids[2] = { | 3355 | static const hda_nid_t ad1884_capsrc_nids[2] = { |
3354 | 0x0c, 0x0d, | 3356 | 0x0c, 0x0d, |
3355 | }; | 3357 | }; |
3356 | 3358 | ||
3357 | #define AD1884_SPDIF_OUT 0x02 | 3359 | #define AD1884_SPDIF_OUT 0x02 |
3358 | 3360 | ||
3359 | static struct hda_input_mux ad1884_capture_source = { | 3361 | static const struct hda_input_mux ad1884_capture_source = { |
3360 | .num_items = 4, | 3362 | .num_items = 4, |
3361 | .items = { | 3363 | .items = { |
3362 | { "Front Mic", 0x0 }, | 3364 | { "Front Mic", 0x0 }, |
@@ -3366,7 +3368,7 @@ static struct hda_input_mux ad1884_capture_source = { | |||
3366 | }, | 3368 | }, |
3367 | }; | 3369 | }; |
3368 | 3370 | ||
3369 | static struct snd_kcontrol_new ad1884_base_mixers[] = { | 3371 | static const struct snd_kcontrol_new ad1884_base_mixers[] = { |
3370 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 3372 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
3371 | /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ | 3373 | /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ |
3372 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), | 3374 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), |
@@ -3410,7 +3412,7 @@ static struct snd_kcontrol_new ad1884_base_mixers[] = { | |||
3410 | { } /* end */ | 3412 | { } /* end */ |
3411 | }; | 3413 | }; |
3412 | 3414 | ||
3413 | static struct snd_kcontrol_new ad1984_dmic_mixers[] = { | 3415 | static const struct snd_kcontrol_new ad1984_dmic_mixers[] = { |
3414 | HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT), | 3416 | HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT), |
3415 | HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT), | 3417 | HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT), |
3416 | HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0, | 3418 | HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0, |
@@ -3423,7 +3425,7 @@ static struct snd_kcontrol_new ad1984_dmic_mixers[] = { | |||
3423 | /* | 3425 | /* |
3424 | * initialization verbs | 3426 | * initialization verbs |
3425 | */ | 3427 | */ |
3426 | static struct hda_verb ad1884_init_verbs[] = { | 3428 | static const struct hda_verb ad1884_init_verbs[] = { |
3427 | /* DACs; mute as default */ | 3429 | /* DACs; mute as default */ |
3428 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 3430 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
3429 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 3431 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
@@ -3469,7 +3471,7 @@ static struct hda_verb ad1884_init_verbs[] = { | |||
3469 | }; | 3471 | }; |
3470 | 3472 | ||
3471 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3473 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3472 | static struct hda_amp_list ad1884_loopbacks[] = { | 3474 | static const struct hda_amp_list ad1884_loopbacks[] = { |
3473 | { 0x20, HDA_INPUT, 0 }, /* Front Mic */ | 3475 | { 0x20, HDA_INPUT, 0 }, /* Front Mic */ |
3474 | { 0x20, HDA_INPUT, 1 }, /* Mic */ | 3476 | { 0x20, HDA_INPUT, 1 }, /* Mic */ |
3475 | { 0x20, HDA_INPUT, 2 }, /* CD */ | 3477 | { 0x20, HDA_INPUT, 2 }, /* CD */ |
@@ -3541,7 +3543,7 @@ static int patch_ad1884(struct hda_codec *codec) | |||
3541 | /* | 3543 | /* |
3542 | * Lenovo Thinkpad T61/X61 | 3544 | * Lenovo Thinkpad T61/X61 |
3543 | */ | 3545 | */ |
3544 | static struct hda_input_mux ad1984_thinkpad_capture_source = { | 3546 | static const struct hda_input_mux ad1984_thinkpad_capture_source = { |
3545 | .num_items = 4, | 3547 | .num_items = 4, |
3546 | .items = { | 3548 | .items = { |
3547 | { "Mic", 0x0 }, | 3549 | { "Mic", 0x0 }, |
@@ -3555,7 +3557,7 @@ static struct hda_input_mux ad1984_thinkpad_capture_source = { | |||
3555 | /* | 3557 | /* |
3556 | * Dell Precision T3400 | 3558 | * Dell Precision T3400 |
3557 | */ | 3559 | */ |
3558 | static struct hda_input_mux ad1984_dell_desktop_capture_source = { | 3560 | static const struct hda_input_mux ad1984_dell_desktop_capture_source = { |
3559 | .num_items = 3, | 3561 | .num_items = 3, |
3560 | .items = { | 3562 | .items = { |
3561 | { "Front Mic", 0x0 }, | 3563 | { "Front Mic", 0x0 }, |
@@ -3565,7 +3567,7 @@ static struct hda_input_mux ad1984_dell_desktop_capture_source = { | |||
3565 | }; | 3567 | }; |
3566 | 3568 | ||
3567 | 3569 | ||
3568 | static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { | 3570 | static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { |
3569 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 3571 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
3570 | /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ | 3572 | /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ |
3571 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), | 3573 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), |
@@ -3611,7 +3613,7 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { | |||
3611 | }; | 3613 | }; |
3612 | 3614 | ||
3613 | /* additional verbs */ | 3615 | /* additional verbs */ |
3614 | static struct hda_verb ad1984_thinkpad_init_verbs[] = { | 3616 | static const struct hda_verb ad1984_thinkpad_init_verbs[] = { |
3615 | /* Port-E (docking station mic) pin */ | 3617 | /* Port-E (docking station mic) pin */ |
3616 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 3618 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
3617 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 3619 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
@@ -3629,7 +3631,7 @@ static struct hda_verb ad1984_thinkpad_init_verbs[] = { | |||
3629 | /* | 3631 | /* |
3630 | * Dell Precision T3400 | 3632 | * Dell Precision T3400 |
3631 | */ | 3633 | */ |
3632 | static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = { | 3634 | static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = { |
3633 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 3635 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
3634 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), | 3636 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), |
3635 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), | 3637 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), |
@@ -3680,7 +3682,7 @@ static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo, | |||
3680 | return 0; | 3682 | return 0; |
3681 | } | 3683 | } |
3682 | 3684 | ||
3683 | static struct hda_pcm_stream ad1984_pcm_dmic_capture = { | 3685 | static const struct hda_pcm_stream ad1984_pcm_dmic_capture = { |
3684 | .substreams = 2, | 3686 | .substreams = 2, |
3685 | .channels_min = 2, | 3687 | .channels_min = 2, |
3686 | .channels_max = 2, | 3688 | .channels_max = 2, |
@@ -3722,7 +3724,7 @@ static const char * const ad1984_models[AD1984_MODELS] = { | |||
3722 | [AD1984_DELL_DESKTOP] = "dell_desktop", | 3724 | [AD1984_DELL_DESKTOP] = "dell_desktop", |
3723 | }; | 3725 | }; |
3724 | 3726 | ||
3725 | static struct snd_pci_quirk ad1984_cfg_tbl[] = { | 3727 | static const struct snd_pci_quirk ad1984_cfg_tbl[] = { |
3726 | /* Lenovo Thinkpad T61/X61 */ | 3728 | /* Lenovo Thinkpad T61/X61 */ |
3727 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), | 3729 | SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), |
3728 | SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), | 3730 | SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), |
@@ -3787,7 +3789,7 @@ static int patch_ad1984(struct hda_codec *codec) | |||
3787 | * We share the single DAC for both HP and line-outs (see AD1884/1984). | 3789 | * We share the single DAC for both HP and line-outs (see AD1884/1984). |
3788 | */ | 3790 | */ |
3789 | 3791 | ||
3790 | static hda_nid_t ad1884a_dac_nids[1] = { | 3792 | static const hda_nid_t ad1884a_dac_nids[1] = { |
3791 | 0x03, | 3793 | 0x03, |
3792 | }; | 3794 | }; |
3793 | 3795 | ||
@@ -3796,7 +3798,7 @@ static hda_nid_t ad1884a_dac_nids[1] = { | |||
3796 | 3798 | ||
3797 | #define AD1884A_SPDIF_OUT 0x02 | 3799 | #define AD1884A_SPDIF_OUT 0x02 |
3798 | 3800 | ||
3799 | static struct hda_input_mux ad1884a_capture_source = { | 3801 | static const struct hda_input_mux ad1884a_capture_source = { |
3800 | .num_items = 5, | 3802 | .num_items = 5, |
3801 | .items = { | 3803 | .items = { |
3802 | { "Front Mic", 0x0 }, | 3804 | { "Front Mic", 0x0 }, |
@@ -3807,7 +3809,7 @@ static struct hda_input_mux ad1884a_capture_source = { | |||
3807 | }, | 3809 | }, |
3808 | }; | 3810 | }; |
3809 | 3811 | ||
3810 | static struct snd_kcontrol_new ad1884a_base_mixers[] = { | 3812 | static const struct snd_kcontrol_new ad1884a_base_mixers[] = { |
3811 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | 3813 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), |
3812 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), | 3814 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), |
3813 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), | 3815 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), |
@@ -3859,7 +3861,7 @@ static struct snd_kcontrol_new ad1884a_base_mixers[] = { | |||
3859 | /* | 3861 | /* |
3860 | * initialization verbs | 3862 | * initialization verbs |
3861 | */ | 3863 | */ |
3862 | static struct hda_verb ad1884a_init_verbs[] = { | 3864 | static const struct hda_verb ad1884a_init_verbs[] = { |
3863 | /* DACs; unmute as default */ | 3865 | /* DACs; unmute as default */ |
3864 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | 3866 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ |
3865 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | 3867 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ |
@@ -3914,7 +3916,7 @@ static struct hda_verb ad1884a_init_verbs[] = { | |||
3914 | }; | 3916 | }; |
3915 | 3917 | ||
3916 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3918 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3917 | static struct hda_amp_list ad1884a_loopbacks[] = { | 3919 | static const struct hda_amp_list ad1884a_loopbacks[] = { |
3918 | { 0x20, HDA_INPUT, 0 }, /* Front Mic */ | 3920 | { 0x20, HDA_INPUT, 0 }, /* Front Mic */ |
3919 | { 0x20, HDA_INPUT, 1 }, /* Mic */ | 3921 | { 0x20, HDA_INPUT, 1 }, /* Mic */ |
3920 | { 0x20, HDA_INPUT, 2 }, /* CD */ | 3922 | { 0x20, HDA_INPUT, 2 }, /* CD */ |
@@ -3947,7 +3949,7 @@ static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol, | |||
3947 | return ret; | 3949 | return ret; |
3948 | } | 3950 | } |
3949 | 3951 | ||
3950 | static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { | 3952 | static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = { |
3951 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | 3953 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), |
3952 | { | 3954 | { |
3953 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 3955 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -3975,7 +3977,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { | |||
3975 | { } /* end */ | 3977 | { } /* end */ |
3976 | }; | 3978 | }; |
3977 | 3979 | ||
3978 | static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { | 3980 | static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = { |
3979 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | 3981 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), |
3980 | /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ | 3982 | /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ |
3981 | { | 3983 | { |
@@ -4095,7 +4097,7 @@ static int ad1884a_laptop_init(struct hda_codec *codec) | |||
4095 | } | 4097 | } |
4096 | 4098 | ||
4097 | /* additional verbs for laptop model */ | 4099 | /* additional verbs for laptop model */ |
4098 | static struct hda_verb ad1884a_laptop_verbs[] = { | 4100 | static const struct hda_verb ad1884a_laptop_verbs[] = { |
4099 | /* Port-A (HP) pin - always unmuted */ | 4101 | /* Port-A (HP) pin - always unmuted */ |
4100 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 4102 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
4101 | /* Port-F (int speaker) mixer - route only from analog mixer */ | 4103 | /* Port-F (int speaker) mixer - route only from analog mixer */ |
@@ -4126,7 +4128,7 @@ static struct hda_verb ad1884a_laptop_verbs[] = { | |||
4126 | { } /* end */ | 4128 | { } /* end */ |
4127 | }; | 4129 | }; |
4128 | 4130 | ||
4129 | static struct hda_verb ad1884a_mobile_verbs[] = { | 4131 | static const struct hda_verb ad1884a_mobile_verbs[] = { |
4130 | /* DACs; unmute as default */ | 4132 | /* DACs; unmute as default */ |
4131 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | 4133 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ |
4132 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | 4134 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ |
@@ -4181,7 +4183,7 @@ static struct hda_verb ad1884a_mobile_verbs[] = { | |||
4181 | * 0x17 - built-in mic | 4183 | * 0x17 - built-in mic |
4182 | */ | 4184 | */ |
4183 | 4185 | ||
4184 | static struct hda_verb ad1984a_thinkpad_verbs[] = { | 4186 | static const struct hda_verb ad1984a_thinkpad_verbs[] = { |
4185 | /* HP unmute */ | 4187 | /* HP unmute */ |
4186 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 4188 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
4187 | /* analog mix */ | 4189 | /* analog mix */ |
@@ -4198,7 +4200,7 @@ static struct hda_verb ad1984a_thinkpad_verbs[] = { | |||
4198 | { } /* end */ | 4200 | { } /* end */ |
4199 | }; | 4201 | }; |
4200 | 4202 | ||
4201 | static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { | 4203 | static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { |
4202 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | 4204 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), |
4203 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), | 4205 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), |
4204 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), | 4206 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), |
@@ -4219,7 +4221,7 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { | |||
4219 | { } /* end */ | 4221 | { } /* end */ |
4220 | }; | 4222 | }; |
4221 | 4223 | ||
4222 | static struct hda_input_mux ad1984a_thinkpad_capture_source = { | 4224 | static const struct hda_input_mux ad1984a_thinkpad_capture_source = { |
4223 | .num_items = 3, | 4225 | .num_items = 3, |
4224 | .items = { | 4226 | .items = { |
4225 | { "Mic", 0x0 }, | 4227 | { "Mic", 0x0 }, |
@@ -4262,7 +4264,7 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec) | |||
4262 | * 0x15 - mic-in | 4264 | * 0x15 - mic-in |
4263 | */ | 4265 | */ |
4264 | 4266 | ||
4265 | static struct hda_verb ad1984a_precision_verbs[] = { | 4267 | static const struct hda_verb ad1984a_precision_verbs[] = { |
4266 | /* Unmute main output path */ | 4268 | /* Unmute main output path */ |
4267 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | 4269 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ |
4268 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ | 4270 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ |
@@ -4288,7 +4290,7 @@ static struct hda_verb ad1984a_precision_verbs[] = { | |||
4288 | { } /* end */ | 4290 | { } /* end */ |
4289 | }; | 4291 | }; |
4290 | 4292 | ||
4291 | static struct snd_kcontrol_new ad1984a_precision_mixers[] = { | 4293 | static const struct snd_kcontrol_new ad1984a_precision_mixers[] = { |
4292 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | 4294 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), |
4293 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), | 4295 | HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), |
4294 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), | 4296 | HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), |
@@ -4344,7 +4346,7 @@ static int ad1984a_precision_init(struct hda_codec *codec) | |||
4344 | * digital-mic (0x17) - Internal mic | 4346 | * digital-mic (0x17) - Internal mic |
4345 | */ | 4347 | */ |
4346 | 4348 | ||
4347 | static struct hda_verb ad1984a_touchsmart_verbs[] = { | 4349 | static const struct hda_verb ad1984a_touchsmart_verbs[] = { |
4348 | /* DACs; unmute as default */ | 4350 | /* DACs; unmute as default */ |
4349 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | 4351 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ |
4350 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ | 4352 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ |
@@ -4396,7 +4398,7 @@ static struct hda_verb ad1984a_touchsmart_verbs[] = { | |||
4396 | { } /* end */ | 4398 | { } /* end */ |
4397 | }; | 4399 | }; |
4398 | 4400 | ||
4399 | static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { | 4401 | static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { |
4400 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), | 4402 | HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), |
4401 | /* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ | 4403 | /* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ |
4402 | { | 4404 | { |
@@ -4475,7 +4477,7 @@ static const char * const ad1884a_models[AD1884A_MODELS] = { | |||
4475 | [AD1984A_PRECISION] = "precision", | 4477 | [AD1984A_PRECISION] = "precision", |
4476 | }; | 4478 | }; |
4477 | 4479 | ||
4478 | static struct snd_pci_quirk ad1884a_cfg_tbl[] = { | 4480 | static const struct snd_pci_quirk ad1884a_cfg_tbl[] = { |
4479 | SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), | 4481 | SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), |
4480 | SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), | 4482 | SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), |
4481 | SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), | 4483 | SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), |
@@ -4614,22 +4616,22 @@ static int patch_ad1884a(struct hda_codec *codec) | |||
4614 | * port-G - rear clfe-out (6stack) | 4616 | * port-G - rear clfe-out (6stack) |
4615 | */ | 4617 | */ |
4616 | 4618 | ||
4617 | static hda_nid_t ad1882_dac_nids[3] = { | 4619 | static const hda_nid_t ad1882_dac_nids[3] = { |
4618 | 0x04, 0x03, 0x05 | 4620 | 0x04, 0x03, 0x05 |
4619 | }; | 4621 | }; |
4620 | 4622 | ||
4621 | static hda_nid_t ad1882_adc_nids[2] = { | 4623 | static const hda_nid_t ad1882_adc_nids[2] = { |
4622 | 0x08, 0x09, | 4624 | 0x08, 0x09, |
4623 | }; | 4625 | }; |
4624 | 4626 | ||
4625 | static hda_nid_t ad1882_capsrc_nids[2] = { | 4627 | static const hda_nid_t ad1882_capsrc_nids[2] = { |
4626 | 0x0c, 0x0d, | 4628 | 0x0c, 0x0d, |
4627 | }; | 4629 | }; |
4628 | 4630 | ||
4629 | #define AD1882_SPDIF_OUT 0x02 | 4631 | #define AD1882_SPDIF_OUT 0x02 |
4630 | 4632 | ||
4631 | /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ | 4633 | /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ |
4632 | static struct hda_input_mux ad1882_capture_source = { | 4634 | static const struct hda_input_mux ad1882_capture_source = { |
4633 | .num_items = 5, | 4635 | .num_items = 5, |
4634 | .items = { | 4636 | .items = { |
4635 | { "Front Mic", 0x1 }, | 4637 | { "Front Mic", 0x1 }, |
@@ -4641,7 +4643,7 @@ static struct hda_input_mux ad1882_capture_source = { | |||
4641 | }; | 4643 | }; |
4642 | 4644 | ||
4643 | /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */ | 4645 | /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */ |
4644 | static struct hda_input_mux ad1882a_capture_source = { | 4646 | static const struct hda_input_mux ad1882a_capture_source = { |
4645 | .num_items = 5, | 4647 | .num_items = 5, |
4646 | .items = { | 4648 | .items = { |
4647 | { "Front Mic", 0x1 }, | 4649 | { "Front Mic", 0x1 }, |
@@ -4652,7 +4654,7 @@ static struct hda_input_mux ad1882a_capture_source = { | |||
4652 | }, | 4654 | }, |
4653 | }; | 4655 | }; |
4654 | 4656 | ||
4655 | static struct snd_kcontrol_new ad1882_base_mixers[] = { | 4657 | static const struct snd_kcontrol_new ad1882_base_mixers[] = { |
4656 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), | 4658 | HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), |
4657 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 4659 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
4658 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), | 4660 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), |
@@ -4694,7 +4696,7 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = { | |||
4694 | { } /* end */ | 4696 | { } /* end */ |
4695 | }; | 4697 | }; |
4696 | 4698 | ||
4697 | static struct snd_kcontrol_new ad1882_loopback_mixers[] = { | 4699 | static const struct snd_kcontrol_new ad1882_loopback_mixers[] = { |
4698 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), | 4700 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), |
4699 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), | 4701 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), |
4700 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), | 4702 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), |
@@ -4706,7 +4708,7 @@ static struct snd_kcontrol_new ad1882_loopback_mixers[] = { | |||
4706 | { } /* end */ | 4708 | { } /* end */ |
4707 | }; | 4709 | }; |
4708 | 4710 | ||
4709 | static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { | 4711 | static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = { |
4710 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), | 4712 | HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), |
4711 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), | 4713 | HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), |
4712 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), | 4714 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), |
@@ -4719,7 +4721,7 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { | |||
4719 | { } /* end */ | 4721 | { } /* end */ |
4720 | }; | 4722 | }; |
4721 | 4723 | ||
4722 | static struct snd_kcontrol_new ad1882_3stack_mixers[] = { | 4724 | static const struct snd_kcontrol_new ad1882_3stack_mixers[] = { |
4723 | HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 4725 | HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
4724 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), | 4726 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), |
4725 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), | 4727 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), |
@@ -4733,14 +4735,14 @@ static struct snd_kcontrol_new ad1882_3stack_mixers[] = { | |||
4733 | { } /* end */ | 4735 | { } /* end */ |
4734 | }; | 4736 | }; |
4735 | 4737 | ||
4736 | static struct snd_kcontrol_new ad1882_6stack_mixers[] = { | 4738 | static const struct snd_kcontrol_new ad1882_6stack_mixers[] = { |
4737 | HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), | 4739 | HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), |
4738 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), | 4740 | HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), |
4739 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), | 4741 | HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), |
4740 | { } /* end */ | 4742 | { } /* end */ |
4741 | }; | 4743 | }; |
4742 | 4744 | ||
4743 | static struct hda_verb ad1882_ch2_init[] = { | 4745 | static const struct hda_verb ad1882_ch2_init[] = { |
4744 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 4746 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
4745 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 4747 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
4746 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 4748 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
@@ -4750,7 +4752,7 @@ static struct hda_verb ad1882_ch2_init[] = { | |||
4750 | { } /* end */ | 4752 | { } /* end */ |
4751 | }; | 4753 | }; |
4752 | 4754 | ||
4753 | static struct hda_verb ad1882_ch4_init[] = { | 4755 | static const struct hda_verb ad1882_ch4_init[] = { |
4754 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 4756 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
4755 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 4757 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
4756 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 4758 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -4760,7 +4762,7 @@ static struct hda_verb ad1882_ch4_init[] = { | |||
4760 | { } /* end */ | 4762 | { } /* end */ |
4761 | }; | 4763 | }; |
4762 | 4764 | ||
4763 | static struct hda_verb ad1882_ch6_init[] = { | 4765 | static const struct hda_verb ad1882_ch6_init[] = { |
4764 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 4766 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
4765 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 4767 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
4766 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 4768 | {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -4770,7 +4772,7 @@ static struct hda_verb ad1882_ch6_init[] = { | |||
4770 | { } /* end */ | 4772 | { } /* end */ |
4771 | }; | 4773 | }; |
4772 | 4774 | ||
4773 | static struct hda_channel_mode ad1882_modes[3] = { | 4775 | static const struct hda_channel_mode ad1882_modes[3] = { |
4774 | { 2, ad1882_ch2_init }, | 4776 | { 2, ad1882_ch2_init }, |
4775 | { 4, ad1882_ch4_init }, | 4777 | { 4, ad1882_ch4_init }, |
4776 | { 6, ad1882_ch6_init }, | 4778 | { 6, ad1882_ch6_init }, |
@@ -4779,7 +4781,7 @@ static struct hda_channel_mode ad1882_modes[3] = { | |||
4779 | /* | 4781 | /* |
4780 | * initialization verbs | 4782 | * initialization verbs |
4781 | */ | 4783 | */ |
4782 | static struct hda_verb ad1882_init_verbs[] = { | 4784 | static const struct hda_verb ad1882_init_verbs[] = { |
4783 | /* DACs; mute as default */ | 4785 | /* DACs; mute as default */ |
4784 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 4786 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
4785 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 4787 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
@@ -4848,7 +4850,7 @@ static struct hda_verb ad1882_init_verbs[] = { | |||
4848 | }; | 4850 | }; |
4849 | 4851 | ||
4850 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4852 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4851 | static struct hda_amp_list ad1882_loopbacks[] = { | 4853 | static const struct hda_amp_list ad1882_loopbacks[] = { |
4852 | { 0x20, HDA_INPUT, 0 }, /* Front Mic */ | 4854 | { 0x20, HDA_INPUT, 0 }, /* Front Mic */ |
4853 | { 0x20, HDA_INPUT, 1 }, /* Mic */ | 4855 | { 0x20, HDA_INPUT, 1 }, /* Mic */ |
4854 | { 0x20, HDA_INPUT, 4 }, /* Line */ | 4856 | { 0x20, HDA_INPUT, 4 }, /* Line */ |
@@ -4945,7 +4947,7 @@ static int patch_ad1882(struct hda_codec *codec) | |||
4945 | /* | 4947 | /* |
4946 | * patch entries | 4948 | * patch entries |
4947 | */ | 4949 | */ |
4948 | static struct hda_codec_preset snd_hda_preset_analog[] = { | 4950 | static const struct hda_codec_preset snd_hda_preset_analog[] = { |
4949 | { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, | 4951 | { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, |
4950 | { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, | 4952 | { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, |
4951 | { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, | 4953 | { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, |
diff --git a/sound/pci/hda/patch_ca0110.c b/sound/pci/hda/patch_ca0110.c index 46c8bf48c31f..61b92634b161 100644 --- a/sound/pci/hda/patch_ca0110.c +++ b/sound/pci/hda/patch_ca0110.c | |||
@@ -134,7 +134,7 @@ static int ca0110_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
134 | /* | 134 | /* |
135 | */ | 135 | */ |
136 | 136 | ||
137 | static char *dirstr[2] = { "Playback", "Capture" }; | 137 | static const char * const dirstr[2] = { "Playback", "Capture" }; |
138 | 138 | ||
139 | static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, | 139 | static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, |
140 | int chan, int dir) | 140 | int chan, int dir) |
@@ -171,7 +171,7 @@ static int ca0110_build_controls(struct hda_codec *codec) | |||
171 | { | 171 | { |
172 | struct ca0110_spec *spec = codec->spec; | 172 | struct ca0110_spec *spec = codec->spec; |
173 | struct auto_pin_cfg *cfg = &spec->autocfg; | 173 | struct auto_pin_cfg *cfg = &spec->autocfg; |
174 | static char *prefix[AUTO_CFG_MAX_OUTS] = { | 174 | static const char * const prefix[AUTO_CFG_MAX_OUTS] = { |
175 | "Front", "Surround", NULL, "Side", "Multi" | 175 | "Front", "Surround", NULL, "Side", "Multi" |
176 | }; | 176 | }; |
177 | hda_nid_t mutenid; | 177 | hda_nid_t mutenid; |
@@ -259,7 +259,7 @@ static int ca0110_build_controls(struct hda_codec *codec) | |||
259 | 259 | ||
260 | /* | 260 | /* |
261 | */ | 261 | */ |
262 | static struct hda_pcm_stream ca0110_pcm_analog_playback = { | 262 | static const struct hda_pcm_stream ca0110_pcm_analog_playback = { |
263 | .substreams = 1, | 263 | .substreams = 1, |
264 | .channels_min = 2, | 264 | .channels_min = 2, |
265 | .channels_max = 8, | 265 | .channels_max = 8, |
@@ -270,7 +270,7 @@ static struct hda_pcm_stream ca0110_pcm_analog_playback = { | |||
270 | }, | 270 | }, |
271 | }; | 271 | }; |
272 | 272 | ||
273 | static struct hda_pcm_stream ca0110_pcm_analog_capture = { | 273 | static const struct hda_pcm_stream ca0110_pcm_analog_capture = { |
274 | .substreams = 1, | 274 | .substreams = 1, |
275 | .channels_min = 2, | 275 | .channels_min = 2, |
276 | .channels_max = 2, | 276 | .channels_max = 2, |
@@ -280,7 +280,7 @@ static struct hda_pcm_stream ca0110_pcm_analog_capture = { | |||
280 | }, | 280 | }, |
281 | }; | 281 | }; |
282 | 282 | ||
283 | static struct hda_pcm_stream ca0110_pcm_digital_playback = { | 283 | static const struct hda_pcm_stream ca0110_pcm_digital_playback = { |
284 | .substreams = 1, | 284 | .substreams = 1, |
285 | .channels_min = 2, | 285 | .channels_min = 2, |
286 | .channels_max = 2, | 286 | .channels_max = 2, |
@@ -291,7 +291,7 @@ static struct hda_pcm_stream ca0110_pcm_digital_playback = { | |||
291 | }, | 291 | }, |
292 | }; | 292 | }; |
293 | 293 | ||
294 | static struct hda_pcm_stream ca0110_pcm_digital_capture = { | 294 | static const struct hda_pcm_stream ca0110_pcm_digital_capture = { |
295 | .substreams = 1, | 295 | .substreams = 1, |
296 | .channels_min = 2, | 296 | .channels_min = 2, |
297 | .channels_max = 2, | 297 | .channels_max = 2, |
@@ -389,7 +389,7 @@ static void ca0110_free(struct hda_codec *codec) | |||
389 | kfree(codec->spec); | 389 | kfree(codec->spec); |
390 | } | 390 | } |
391 | 391 | ||
392 | static struct hda_codec_ops ca0110_patch_ops = { | 392 | static const struct hda_codec_ops ca0110_patch_ops = { |
393 | .build_controls = ca0110_build_controls, | 393 | .build_controls = ca0110_build_controls, |
394 | .build_pcms = ca0110_build_pcms, | 394 | .build_pcms = ca0110_build_pcms, |
395 | .init = ca0110_init, | 395 | .init = ca0110_init, |
@@ -539,7 +539,7 @@ static int patch_ca0110(struct hda_codec *codec) | |||
539 | /* | 539 | /* |
540 | * patch entries | 540 | * patch entries |
541 | */ | 541 | */ |
542 | static struct hda_codec_preset snd_hda_preset_ca0110[] = { | 542 | static const struct hda_codec_preset snd_hda_preset_ca0110[] = { |
543 | { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, | 543 | { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, |
544 | { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, | 544 | { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, |
545 | { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 }, | 545 | { .id = 0x1102000d, .name = "SB0880 X-Fi", .patch = patch_ca0110 }, |
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 067982f4f182..26a1521045bb 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -51,7 +51,7 @@ struct cs_spec { | |||
51 | unsigned int cur_adc_format; | 51 | unsigned int cur_adc_format; |
52 | hda_nid_t dig_in; | 52 | hda_nid_t dig_in; |
53 | 53 | ||
54 | struct hda_bind_ctls *capture_bind[2]; | 54 | const struct hda_bind_ctls *capture_bind[2]; |
55 | 55 | ||
56 | unsigned int gpio_mask; | 56 | unsigned int gpio_mask; |
57 | unsigned int gpio_dir; | 57 | unsigned int gpio_dir; |
@@ -231,7 +231,7 @@ static int cs_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
231 | 231 | ||
232 | /* | 232 | /* |
233 | */ | 233 | */ |
234 | static struct hda_pcm_stream cs_pcm_analog_playback = { | 234 | static const struct hda_pcm_stream cs_pcm_analog_playback = { |
235 | .substreams = 1, | 235 | .substreams = 1, |
236 | .channels_min = 2, | 236 | .channels_min = 2, |
237 | .channels_max = 2, | 237 | .channels_max = 2, |
@@ -242,7 +242,7 @@ static struct hda_pcm_stream cs_pcm_analog_playback = { | |||
242 | }, | 242 | }, |
243 | }; | 243 | }; |
244 | 244 | ||
245 | static struct hda_pcm_stream cs_pcm_analog_capture = { | 245 | static const struct hda_pcm_stream cs_pcm_analog_capture = { |
246 | .substreams = 1, | 246 | .substreams = 1, |
247 | .channels_min = 2, | 247 | .channels_min = 2, |
248 | .channels_max = 2, | 248 | .channels_max = 2, |
@@ -252,7 +252,7 @@ static struct hda_pcm_stream cs_pcm_analog_capture = { | |||
252 | }, | 252 | }, |
253 | }; | 253 | }; |
254 | 254 | ||
255 | static struct hda_pcm_stream cs_pcm_digital_playback = { | 255 | static const struct hda_pcm_stream cs_pcm_digital_playback = { |
256 | .substreams = 1, | 256 | .substreams = 1, |
257 | .channels_min = 2, | 257 | .channels_min = 2, |
258 | .channels_max = 2, | 258 | .channels_max = 2, |
@@ -264,7 +264,7 @@ static struct hda_pcm_stream cs_pcm_digital_playback = { | |||
264 | }, | 264 | }, |
265 | }; | 265 | }; |
266 | 266 | ||
267 | static struct hda_pcm_stream cs_pcm_digital_capture = { | 267 | static const struct hda_pcm_stream cs_pcm_digital_capture = { |
268 | .substreams = 1, | 268 | .substreams = 1, |
269 | .channels_min = 2, | 269 | .channels_min = 2, |
270 | .channels_max = 2, | 270 | .channels_max = 2, |
@@ -331,8 +331,8 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx) | |||
331 | struct cs_spec *spec = codec->spec; | 331 | struct cs_spec *spec = codec->spec; |
332 | struct auto_pin_cfg *cfg = &spec->autocfg; | 332 | struct auto_pin_cfg *cfg = &spec->autocfg; |
333 | hda_nid_t pin = cfg->inputs[idx].pin; | 333 | hda_nid_t pin = cfg->inputs[idx].pin; |
334 | unsigned int val = snd_hda_query_pin_caps(codec, pin); | 334 | unsigned int val; |
335 | if (!(val & AC_PINCAP_PRES_DETECT)) | 335 | if (!is_jack_detectable(codec, pin)) |
336 | return 0; | 336 | return 0; |
337 | val = snd_hda_codec_get_pincfg(codec, pin); | 337 | val = snd_hda_codec_get_pincfg(codec, pin); |
338 | return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT); | 338 | return (snd_hda_get_input_pin_attr(val) != INPUT_PIN_ATTR_INT); |
@@ -349,8 +349,7 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, | |||
349 | hda_nid_t pins[2]; | 349 | hda_nid_t pins[2]; |
350 | unsigned int type; | 350 | unsigned int type; |
351 | int j, nums; | 351 | int j, nums; |
352 | type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) | 352 | type = get_wcaps_type(get_wcaps(codec, nid)); |
353 | >> AC_WCAP_TYPE_SHIFT; | ||
354 | if (type != AC_WID_AUD_IN) | 353 | if (type != AC_WID_AUD_IN) |
355 | continue; | 354 | continue; |
356 | nums = snd_hda_get_connections(codec, nid, pins, | 355 | nums = snd_hda_get_connections(codec, nid, pins, |
@@ -559,10 +558,10 @@ static int add_output(struct hda_codec *codec, hda_nid_t dac, int idx, | |||
559 | const char *name; | 558 | const char *name; |
560 | int err, index; | 559 | int err, index; |
561 | struct snd_kcontrol *kctl; | 560 | struct snd_kcontrol *kctl; |
562 | static char *speakers[] = { | 561 | static const char * const speakers[] = { |
563 | "Front Speaker", "Surround Speaker", "Bass Speaker" | 562 | "Front Speaker", "Surround Speaker", "Bass Speaker" |
564 | }; | 563 | }; |
565 | static char *line_outs[] = { | 564 | static const char * const line_outs[] = { |
566 | "Front Line-Out", "Surround Line-Out", "Bass Line-Out" | 565 | "Front Line-Out", "Surround Line-Out", "Bass Line-Out" |
567 | }; | 566 | }; |
568 | 567 | ||
@@ -642,7 +641,7 @@ static int build_output(struct hda_codec *codec) | |||
642 | /* | 641 | /* |
643 | */ | 642 | */ |
644 | 643 | ||
645 | static struct snd_kcontrol_new cs_capture_ctls[] = { | 644 | static const struct snd_kcontrol_new cs_capture_ctls[] = { |
646 | HDA_BIND_SW("Capture Switch", 0), | 645 | HDA_BIND_SW("Capture Switch", 0), |
647 | HDA_BIND_VOL("Capture Volume", 0), | 646 | HDA_BIND_VOL("Capture Volume", 0), |
648 | }; | 647 | }; |
@@ -710,7 +709,7 @@ static int cs_capture_source_put(struct snd_kcontrol *kcontrol, | |||
710 | return change_cur_input(codec, idx, 0); | 709 | return change_cur_input(codec, idx, 0); |
711 | } | 710 | } |
712 | 711 | ||
713 | static struct snd_kcontrol_new cs_capture_source = { | 712 | static const struct snd_kcontrol_new cs_capture_source = { |
714 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 713 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
715 | .name = "Capture Source", | 714 | .name = "Capture Source", |
716 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | 715 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, |
@@ -719,7 +718,7 @@ static struct snd_kcontrol_new cs_capture_source = { | |||
719 | .put = cs_capture_source_put, | 718 | .put = cs_capture_source_put, |
720 | }; | 719 | }; |
721 | 720 | ||
722 | static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec, | 721 | static const struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec, |
723 | struct hda_ctl_ops *ops) | 722 | struct hda_ctl_ops *ops) |
724 | { | 723 | { |
725 | struct cs_spec *spec = codec->spec; | 724 | struct cs_spec *spec = codec->spec; |
@@ -847,15 +846,14 @@ static void cs_automute(struct hda_codec *codec) | |||
847 | { | 846 | { |
848 | struct cs_spec *spec = codec->spec; | 847 | struct cs_spec *spec = codec->spec; |
849 | struct auto_pin_cfg *cfg = &spec->autocfg; | 848 | struct auto_pin_cfg *cfg = &spec->autocfg; |
850 | unsigned int caps, hp_present; | 849 | unsigned int hp_present; |
851 | hda_nid_t nid; | 850 | hda_nid_t nid; |
852 | int i; | 851 | int i; |
853 | 852 | ||
854 | hp_present = 0; | 853 | hp_present = 0; |
855 | for (i = 0; i < cfg->hp_outs; i++) { | 854 | for (i = 0; i < cfg->hp_outs; i++) { |
856 | nid = cfg->hp_pins[i]; | 855 | nid = cfg->hp_pins[i]; |
857 | caps = snd_hda_query_pin_caps(codec, nid); | 856 | if (!is_jack_detectable(codec, nid)) |
858 | if (!(caps & AC_PINCAP_PRES_DETECT)) | ||
859 | continue; | 857 | continue; |
860 | hp_present = snd_hda_jack_detect(codec, nid); | 858 | hp_present = snd_hda_jack_detect(codec, nid); |
861 | if (hp_present) | 859 | if (hp_present) |
@@ -924,7 +922,7 @@ static void init_output(struct hda_codec *codec) | |||
924 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); | 922 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); |
925 | if (!cfg->speaker_outs) | 923 | if (!cfg->speaker_outs) |
926 | continue; | 924 | continue; |
927 | if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { | 925 | if (is_jack_detectable(codec, nid)) { |
928 | snd_hda_codec_write(codec, nid, 0, | 926 | snd_hda_codec_write(codec, nid, 0, |
929 | AC_VERB_SET_UNSOLICITED_ENABLE, | 927 | AC_VERB_SET_UNSOLICITED_ENABLE, |
930 | AC_USRSP_EN | HP_EVENT); | 928 | AC_USRSP_EN | HP_EVENT); |
@@ -983,7 +981,7 @@ static void init_input(struct hda_codec *codec) | |||
983 | cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); | 981 | cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); |
984 | } | 982 | } |
985 | 983 | ||
986 | static struct hda_verb cs_coef_init_verbs[] = { | 984 | static const struct hda_verb cs_coef_init_verbs[] = { |
987 | {0x11, AC_VERB_SET_PROC_STATE, 1}, | 985 | {0x11, AC_VERB_SET_PROC_STATE, 1}, |
988 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, | 986 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, |
989 | {0x11, AC_VERB_SET_PROC_COEF, | 987 | {0x11, AC_VERB_SET_PROC_COEF, |
@@ -1017,7 +1015,7 @@ static struct hda_verb cs_coef_init_verbs[] = { | |||
1017 | * blocks, which will alleviate the issue. | 1015 | * blocks, which will alleviate the issue. |
1018 | */ | 1016 | */ |
1019 | 1017 | ||
1020 | static struct hda_verb cs_errata_init_verbs[] = { | 1018 | static const struct hda_verb cs_errata_init_verbs[] = { |
1021 | {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */ | 1019 | {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */ |
1022 | {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ | 1020 | {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ |
1023 | 1021 | ||
@@ -1126,7 +1124,7 @@ static void cs_unsol_event(struct hda_codec *codec, unsigned int res) | |||
1126 | } | 1124 | } |
1127 | } | 1125 | } |
1128 | 1126 | ||
1129 | static struct hda_codec_ops cs_patch_ops = { | 1127 | static const struct hda_codec_ops cs_patch_ops = { |
1130 | .build_controls = cs_build_controls, | 1128 | .build_controls = cs_build_controls, |
1131 | .build_pcms = cs_build_pcms, | 1129 | .build_pcms = cs_build_pcms, |
1132 | .init = cs_init, | 1130 | .init = cs_init, |
@@ -1166,7 +1164,7 @@ static const char * const cs420x_models[CS420X_MODELS] = { | |||
1166 | }; | 1164 | }; |
1167 | 1165 | ||
1168 | 1166 | ||
1169 | static struct snd_pci_quirk cs420x_cfg_tbl[] = { | 1167 | static const struct snd_pci_quirk cs420x_cfg_tbl[] = { |
1170 | SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53), | 1168 | SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53), |
1171 | SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), | 1169 | SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), |
1172 | SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), | 1170 | SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), |
@@ -1180,7 +1178,7 @@ struct cs_pincfg { | |||
1180 | u32 val; | 1178 | u32 val; |
1181 | }; | 1179 | }; |
1182 | 1180 | ||
1183 | static struct cs_pincfg mbp53_pincfgs[] = { | 1181 | static const struct cs_pincfg mbp53_pincfgs[] = { |
1184 | { 0x09, 0x012b4050 }, | 1182 | { 0x09, 0x012b4050 }, |
1185 | { 0x0a, 0x90100141 }, | 1183 | { 0x0a, 0x90100141 }, |
1186 | { 0x0b, 0x90100140 }, | 1184 | { 0x0b, 0x90100140 }, |
@@ -1194,7 +1192,7 @@ static struct cs_pincfg mbp53_pincfgs[] = { | |||
1194 | {} /* terminator */ | 1192 | {} /* terminator */ |
1195 | }; | 1193 | }; |
1196 | 1194 | ||
1197 | static struct cs_pincfg mbp55_pincfgs[] = { | 1195 | static const struct cs_pincfg mbp55_pincfgs[] = { |
1198 | { 0x09, 0x012b4030 }, | 1196 | { 0x09, 0x012b4030 }, |
1199 | { 0x0a, 0x90100121 }, | 1197 | { 0x0a, 0x90100121 }, |
1200 | { 0x0b, 0x90100120 }, | 1198 | { 0x0b, 0x90100120 }, |
@@ -1208,7 +1206,7 @@ static struct cs_pincfg mbp55_pincfgs[] = { | |||
1208 | {} /* terminator */ | 1206 | {} /* terminator */ |
1209 | }; | 1207 | }; |
1210 | 1208 | ||
1211 | static struct cs_pincfg imac27_pincfgs[] = { | 1209 | static const struct cs_pincfg imac27_pincfgs[] = { |
1212 | { 0x09, 0x012b4050 }, | 1210 | { 0x09, 0x012b4050 }, |
1213 | { 0x0a, 0x90100140 }, | 1211 | { 0x0a, 0x90100140 }, |
1214 | { 0x0b, 0x90100142 }, | 1212 | { 0x0b, 0x90100142 }, |
@@ -1222,7 +1220,7 @@ static struct cs_pincfg imac27_pincfgs[] = { | |||
1222 | {} /* terminator */ | 1220 | {} /* terminator */ |
1223 | }; | 1221 | }; |
1224 | 1222 | ||
1225 | static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = { | 1223 | static const struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = { |
1226 | [CS420X_MBP53] = mbp53_pincfgs, | 1224 | [CS420X_MBP53] = mbp53_pincfgs, |
1227 | [CS420X_MBP55] = mbp55_pincfgs, | 1225 | [CS420X_MBP55] = mbp55_pincfgs, |
1228 | [CS420X_IMAC27] = imac27_pincfgs, | 1226 | [CS420X_IMAC27] = imac27_pincfgs, |
@@ -1283,7 +1281,7 @@ static int patch_cs420x(struct hda_codec *codec) | |||
1283 | /* | 1281 | /* |
1284 | * patch entries | 1282 | * patch entries |
1285 | */ | 1283 | */ |
1286 | static struct hda_codec_preset snd_hda_preset_cirrus[] = { | 1284 | static const struct hda_codec_preset snd_hda_preset_cirrus[] = { |
1287 | { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, | 1285 | { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, |
1288 | { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, | 1286 | { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, |
1289 | {} /* terminator */ | 1287 | {} /* terminator */ |
diff --git a/sound/pci/hda/patch_cmedia.c b/sound/pci/hda/patch_cmedia.c index 1f8bbcd0f802..ab3308daa960 100644 --- a/sound/pci/hda/patch_cmedia.c +++ b/sound/pci/hda/patch_cmedia.c | |||
@@ -53,7 +53,7 @@ struct cmi_spec { | |||
53 | int num_dacs; | 53 | int num_dacs; |
54 | 54 | ||
55 | /* capture */ | 55 | /* capture */ |
56 | hda_nid_t *adc_nids; | 56 | const hda_nid_t *adc_nids; |
57 | hda_nid_t dig_in_nid; | 57 | hda_nid_t dig_in_nid; |
58 | 58 | ||
59 | /* capture source */ | 59 | /* capture source */ |
@@ -110,7 +110,7 @@ static int cmi_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v | |||
110 | */ | 110 | */ |
111 | 111 | ||
112 | /* 3-stack / 2 channel */ | 112 | /* 3-stack / 2 channel */ |
113 | static struct hda_verb cmi9880_ch2_init[] = { | 113 | static const struct hda_verb cmi9880_ch2_init[] = { |
114 | /* set line-in PIN for input */ | 114 | /* set line-in PIN for input */ |
115 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 115 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
116 | /* set mic PIN for input, also enable vref */ | 116 | /* set mic PIN for input, also enable vref */ |
@@ -121,7 +121,7 @@ static struct hda_verb cmi9880_ch2_init[] = { | |||
121 | }; | 121 | }; |
122 | 122 | ||
123 | /* 3-stack / 6 channel */ | 123 | /* 3-stack / 6 channel */ |
124 | static struct hda_verb cmi9880_ch6_init[] = { | 124 | static const struct hda_verb cmi9880_ch6_init[] = { |
125 | /* set line-in PIN for output */ | 125 | /* set line-in PIN for output */ |
126 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 126 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
127 | /* set mic PIN for output */ | 127 | /* set mic PIN for output */ |
@@ -132,7 +132,7 @@ static struct hda_verb cmi9880_ch6_init[] = { | |||
132 | }; | 132 | }; |
133 | 133 | ||
134 | /* 3-stack+front / 8 channel */ | 134 | /* 3-stack+front / 8 channel */ |
135 | static struct hda_verb cmi9880_ch8_init[] = { | 135 | static const struct hda_verb cmi9880_ch8_init[] = { |
136 | /* set line-in PIN for output */ | 136 | /* set line-in PIN for output */ |
137 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 137 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
138 | /* set mic PIN for output */ | 138 | /* set mic PIN for output */ |
@@ -142,7 +142,7 @@ static struct hda_verb cmi9880_ch8_init[] = { | |||
142 | {} | 142 | {} |
143 | }; | 143 | }; |
144 | 144 | ||
145 | static struct hda_channel_mode cmi9880_channel_modes[3] = { | 145 | static const struct hda_channel_mode cmi9880_channel_modes[3] = { |
146 | { 2, cmi9880_ch2_init }, | 146 | { 2, cmi9880_ch2_init }, |
147 | { 6, cmi9880_ch6_init }, | 147 | { 6, cmi9880_ch6_init }, |
148 | { 8, cmi9880_ch8_init }, | 148 | { 8, cmi9880_ch8_init }, |
@@ -174,7 +174,7 @@ static int cmi_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va | |||
174 | 174 | ||
175 | /* | 175 | /* |
176 | */ | 176 | */ |
177 | static struct snd_kcontrol_new cmi9880_basic_mixer[] = { | 177 | static const struct snd_kcontrol_new cmi9880_basic_mixer[] = { |
178 | /* CMI9880 has no playback volumes! */ | 178 | /* CMI9880 has no playback volumes! */ |
179 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */ | 179 | HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */ |
180 | HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT), | 180 | HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT), |
@@ -205,7 +205,7 @@ static struct snd_kcontrol_new cmi9880_basic_mixer[] = { | |||
205 | /* | 205 | /* |
206 | * shared I/O pins | 206 | * shared I/O pins |
207 | */ | 207 | */ |
208 | static struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = { | 208 | static const struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = { |
209 | { | 209 | { |
210 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 210 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
211 | .name = "Channel Mode", | 211 | .name = "Channel Mode", |
@@ -219,7 +219,7 @@ static struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = { | |||
219 | /* AUD-in selections: | 219 | /* AUD-in selections: |
220 | * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20 | 220 | * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20 |
221 | */ | 221 | */ |
222 | static struct hda_input_mux cmi9880_basic_mux = { | 222 | static const struct hda_input_mux cmi9880_basic_mux = { |
223 | .num_items = 4, | 223 | .num_items = 4, |
224 | .items = { | 224 | .items = { |
225 | { "Front Mic", 0x5 }, | 225 | { "Front Mic", 0x5 }, |
@@ -229,7 +229,7 @@ static struct hda_input_mux cmi9880_basic_mux = { | |||
229 | } | 229 | } |
230 | }; | 230 | }; |
231 | 231 | ||
232 | static struct hda_input_mux cmi9880_no_line_mux = { | 232 | static const struct hda_input_mux cmi9880_no_line_mux = { |
233 | .num_items = 3, | 233 | .num_items = 3, |
234 | .items = { | 234 | .items = { |
235 | { "Front Mic", 0x5 }, | 235 | { "Front Mic", 0x5 }, |
@@ -239,11 +239,11 @@ static struct hda_input_mux cmi9880_no_line_mux = { | |||
239 | }; | 239 | }; |
240 | 240 | ||
241 | /* front, rear, clfe, rear_surr */ | 241 | /* front, rear, clfe, rear_surr */ |
242 | static hda_nid_t cmi9880_dac_nids[4] = { | 242 | static const hda_nid_t cmi9880_dac_nids[4] = { |
243 | 0x03, 0x04, 0x05, 0x06 | 243 | 0x03, 0x04, 0x05, 0x06 |
244 | }; | 244 | }; |
245 | /* ADC0, ADC1 */ | 245 | /* ADC0, ADC1 */ |
246 | static hda_nid_t cmi9880_adc_nids[2] = { | 246 | static const hda_nid_t cmi9880_adc_nids[2] = { |
247 | 0x08, 0x09 | 247 | 0x08, 0x09 |
248 | }; | 248 | }; |
249 | 249 | ||
@@ -252,7 +252,7 @@ static hda_nid_t cmi9880_adc_nids[2] = { | |||
252 | 252 | ||
253 | /* | 253 | /* |
254 | */ | 254 | */ |
255 | static struct hda_verb cmi9880_basic_init[] = { | 255 | static const struct hda_verb cmi9880_basic_init[] = { |
256 | /* port-D for line out (rear panel) */ | 256 | /* port-D for line out (rear panel) */ |
257 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | 257 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
258 | /* port-E for HP out (front panel) */ | 258 | /* port-E for HP out (front panel) */ |
@@ -281,7 +281,7 @@ static struct hda_verb cmi9880_basic_init[] = { | |||
281 | {} /* terminator */ | 281 | {} /* terminator */ |
282 | }; | 282 | }; |
283 | 283 | ||
284 | static struct hda_verb cmi9880_allout_init[] = { | 284 | static const struct hda_verb cmi9880_allout_init[] = { |
285 | /* port-D for line out (rear panel) */ | 285 | /* port-D for line out (rear panel) */ |
286 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | 286 | { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
287 | /* port-E for HP out (front panel) */ | 287 | /* port-E for HP out (front panel) */ |
@@ -528,7 +528,7 @@ static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
528 | 528 | ||
529 | /* | 529 | /* |
530 | */ | 530 | */ |
531 | static struct hda_pcm_stream cmi9880_pcm_analog_playback = { | 531 | static const struct hda_pcm_stream cmi9880_pcm_analog_playback = { |
532 | .substreams = 1, | 532 | .substreams = 1, |
533 | .channels_min = 2, | 533 | .channels_min = 2, |
534 | .channels_max = 8, | 534 | .channels_max = 8, |
@@ -540,7 +540,7 @@ static struct hda_pcm_stream cmi9880_pcm_analog_playback = { | |||
540 | }, | 540 | }, |
541 | }; | 541 | }; |
542 | 542 | ||
543 | static struct hda_pcm_stream cmi9880_pcm_analog_capture = { | 543 | static const struct hda_pcm_stream cmi9880_pcm_analog_capture = { |
544 | .substreams = 2, | 544 | .substreams = 2, |
545 | .channels_min = 2, | 545 | .channels_min = 2, |
546 | .channels_max = 2, | 546 | .channels_max = 2, |
@@ -551,7 +551,7 @@ static struct hda_pcm_stream cmi9880_pcm_analog_capture = { | |||
551 | }, | 551 | }, |
552 | }; | 552 | }; |
553 | 553 | ||
554 | static struct hda_pcm_stream cmi9880_pcm_digital_playback = { | 554 | static const struct hda_pcm_stream cmi9880_pcm_digital_playback = { |
555 | .substreams = 1, | 555 | .substreams = 1, |
556 | .channels_min = 2, | 556 | .channels_min = 2, |
557 | .channels_max = 2, | 557 | .channels_max = 2, |
@@ -563,7 +563,7 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = { | |||
563 | }, | 563 | }, |
564 | }; | 564 | }; |
565 | 565 | ||
566 | static struct hda_pcm_stream cmi9880_pcm_digital_capture = { | 566 | static const struct hda_pcm_stream cmi9880_pcm_digital_capture = { |
567 | .substreams = 1, | 567 | .substreams = 1, |
568 | .channels_min = 2, | 568 | .channels_min = 2, |
569 | .channels_max = 2, | 569 | .channels_max = 2, |
@@ -617,14 +617,14 @@ static const char * const cmi9880_models[CMI_MODELS] = { | |||
617 | [CMI_AUTO] = "auto", | 617 | [CMI_AUTO] = "auto", |
618 | }; | 618 | }; |
619 | 619 | ||
620 | static struct snd_pci_quirk cmi9880_cfg_tbl[] = { | 620 | static const struct snd_pci_quirk cmi9880_cfg_tbl[] = { |
621 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG), | 621 | SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG), |
622 | SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL), | 622 | SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL), |
623 | SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG), | 623 | SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG), |
624 | {} /* terminator */ | 624 | {} /* terminator */ |
625 | }; | 625 | }; |
626 | 626 | ||
627 | static struct hda_codec_ops cmi9880_patch_ops = { | 627 | static const struct hda_codec_ops cmi9880_patch_ops = { |
628 | .build_controls = cmi9880_build_controls, | 628 | .build_controls = cmi9880_build_controls, |
629 | .build_pcms = cmi9880_build_pcms, | 629 | .build_pcms = cmi9880_build_pcms, |
630 | .init = cmi9880_init, | 630 | .init = cmi9880_init, |
@@ -745,7 +745,7 @@ static int patch_cmi9880(struct hda_codec *codec) | |||
745 | /* | 745 | /* |
746 | * patch entries | 746 | * patch entries |
747 | */ | 747 | */ |
748 | static struct hda_codec_preset snd_hda_preset_cmedia[] = { | 748 | static const struct hda_codec_preset snd_hda_preset_cmedia[] = { |
749 | { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, | 749 | { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, |
750 | { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, | 750 | { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, |
751 | {} /* terminator */ | 751 | {} /* terminator */ |
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index ad97d937d3a8..3e6b9a8539c2 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c | |||
@@ -39,6 +39,7 @@ | |||
39 | 39 | ||
40 | #define CONEXANT_HP_EVENT 0x37 | 40 | #define CONEXANT_HP_EVENT 0x37 |
41 | #define CONEXANT_MIC_EVENT 0x38 | 41 | #define CONEXANT_MIC_EVENT 0x38 |
42 | #define CONEXANT_LINE_EVENT 0x39 | ||
42 | 43 | ||
43 | /* Conexant 5051 specific */ | 44 | /* Conexant 5051 specific */ |
44 | 45 | ||
@@ -55,9 +56,16 @@ struct pin_dac_pair { | |||
55 | int type; | 56 | int type; |
56 | }; | 57 | }; |
57 | 58 | ||
59 | struct imux_info { | ||
60 | hda_nid_t pin; /* input pin NID */ | ||
61 | hda_nid_t adc; /* connected ADC NID */ | ||
62 | hda_nid_t boost; /* optional boost volume NID */ | ||
63 | int index; /* corresponding to autocfg.input */ | ||
64 | }; | ||
65 | |||
58 | struct conexant_spec { | 66 | struct conexant_spec { |
59 | 67 | ||
60 | struct snd_kcontrol_new *mixers[5]; | 68 | const struct snd_kcontrol_new *mixers[5]; |
61 | int num_mixers; | 69 | int num_mixers; |
62 | hda_nid_t vmaster_nid; | 70 | hda_nid_t vmaster_nid; |
63 | 71 | ||
@@ -74,14 +82,17 @@ struct conexant_spec { | |||
74 | */ | 82 | */ |
75 | unsigned int cur_eapd; | 83 | unsigned int cur_eapd; |
76 | unsigned int hp_present; | 84 | unsigned int hp_present; |
85 | unsigned int line_present; | ||
77 | unsigned int auto_mic; | 86 | unsigned int auto_mic; |
78 | int auto_mic_ext; /* autocfg.inputs[] index for ext mic */ | 87 | int auto_mic_ext; /* imux_pins[] index for ext mic */ |
88 | int auto_mic_dock; /* imux_pins[] index for dock mic */ | ||
89 | int auto_mic_int; /* imux_pins[] index for int mic */ | ||
79 | unsigned int need_dac_fix; | 90 | unsigned int need_dac_fix; |
80 | hda_nid_t slave_dig_outs[2]; | 91 | hda_nid_t slave_dig_outs[2]; |
81 | 92 | ||
82 | /* capture */ | 93 | /* capture */ |
83 | unsigned int num_adc_nids; | 94 | unsigned int num_adc_nids; |
84 | hda_nid_t *adc_nids; | 95 | const hda_nid_t *adc_nids; |
85 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | 96 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ |
86 | 97 | ||
87 | unsigned int cur_adc_idx; | 98 | unsigned int cur_adc_idx; |
@@ -89,9 +100,11 @@ struct conexant_spec { | |||
89 | unsigned int cur_adc_stream_tag; | 100 | unsigned int cur_adc_stream_tag; |
90 | unsigned int cur_adc_format; | 101 | unsigned int cur_adc_format; |
91 | 102 | ||
103 | const struct hda_pcm_stream *capture_stream; | ||
104 | |||
92 | /* capture source */ | 105 | /* capture source */ |
93 | const struct hda_input_mux *input_mux; | 106 | const struct hda_input_mux *input_mux; |
94 | hda_nid_t *capsrc_nids; | 107 | const hda_nid_t *capsrc_nids; |
95 | unsigned int cur_mux[3]; | 108 | unsigned int cur_mux[3]; |
96 | 109 | ||
97 | /* channel model */ | 110 | /* channel model */ |
@@ -106,12 +119,17 @@ struct conexant_spec { | |||
106 | /* dynamic controls, init_verbs and input_mux */ | 119 | /* dynamic controls, init_verbs and input_mux */ |
107 | struct auto_pin_cfg autocfg; | 120 | struct auto_pin_cfg autocfg; |
108 | struct hda_input_mux private_imux; | 121 | struct hda_input_mux private_imux; |
122 | struct imux_info imux_info[HDA_MAX_NUM_INPUTS]; | ||
123 | hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS]; | ||
109 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; | 124 | hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; |
110 | struct pin_dac_pair dac_info[8]; | 125 | struct pin_dac_pair dac_info[8]; |
111 | int dac_info_filled; | 126 | int dac_info_filled; |
112 | 127 | ||
113 | unsigned int port_d_mode; | 128 | unsigned int port_d_mode; |
114 | unsigned int auto_mute:1; /* used in auto-parser */ | 129 | unsigned int auto_mute:1; /* used in auto-parser */ |
130 | unsigned int detect_line:1; /* Line-out detection enabled */ | ||
131 | unsigned int automute_lines:1; /* automute line-out as well */ | ||
132 | unsigned int automute_hp_lo:1; /* both HP and LO available */ | ||
115 | unsigned int dell_automute:1; | 133 | unsigned int dell_automute:1; |
116 | unsigned int dell_vostro:1; | 134 | unsigned int dell_vostro:1; |
117 | unsigned int ideapad:1; | 135 | unsigned int ideapad:1; |
@@ -119,6 +137,8 @@ struct conexant_spec { | |||
119 | unsigned int hp_laptop:1; | 137 | unsigned int hp_laptop:1; |
120 | unsigned int asus:1; | 138 | unsigned int asus:1; |
121 | 139 | ||
140 | unsigned int adc_switching:1; | ||
141 | |||
122 | unsigned int ext_mic_present; | 142 | unsigned int ext_mic_present; |
123 | unsigned int recording; | 143 | unsigned int recording; |
124 | void (*capture_prepare)(struct hda_codec *codec); | 144 | void (*capture_prepare)(struct hda_codec *codec); |
@@ -227,7 +247,7 @@ static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
227 | 247 | ||
228 | 248 | ||
229 | 249 | ||
230 | static struct hda_pcm_stream conexant_pcm_analog_playback = { | 250 | static const struct hda_pcm_stream conexant_pcm_analog_playback = { |
231 | .substreams = 1, | 251 | .substreams = 1, |
232 | .channels_min = 2, | 252 | .channels_min = 2, |
233 | .channels_max = 2, | 253 | .channels_max = 2, |
@@ -239,7 +259,7 @@ static struct hda_pcm_stream conexant_pcm_analog_playback = { | |||
239 | }, | 259 | }, |
240 | }; | 260 | }; |
241 | 261 | ||
242 | static struct hda_pcm_stream conexant_pcm_analog_capture = { | 262 | static const struct hda_pcm_stream conexant_pcm_analog_capture = { |
243 | .substreams = 1, | 263 | .substreams = 1, |
244 | .channels_min = 2, | 264 | .channels_min = 2, |
245 | .channels_max = 2, | 265 | .channels_max = 2, |
@@ -251,7 +271,7 @@ static struct hda_pcm_stream conexant_pcm_analog_capture = { | |||
251 | }; | 271 | }; |
252 | 272 | ||
253 | 273 | ||
254 | static struct hda_pcm_stream conexant_pcm_digital_playback = { | 274 | static const struct hda_pcm_stream conexant_pcm_digital_playback = { |
255 | .substreams = 1, | 275 | .substreams = 1, |
256 | .channels_min = 2, | 276 | .channels_min = 2, |
257 | .channels_max = 2, | 277 | .channels_max = 2, |
@@ -263,7 +283,7 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = { | |||
263 | }, | 283 | }, |
264 | }; | 284 | }; |
265 | 285 | ||
266 | static struct hda_pcm_stream conexant_pcm_digital_capture = { | 286 | static const struct hda_pcm_stream conexant_pcm_digital_capture = { |
267 | .substreams = 1, | 287 | .substreams = 1, |
268 | .channels_min = 2, | 288 | .channels_min = 2, |
269 | .channels_max = 2, | 289 | .channels_max = 2, |
@@ -294,7 +314,7 @@ static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
294 | return 0; | 314 | return 0; |
295 | } | 315 | } |
296 | 316 | ||
297 | static struct hda_pcm_stream cx5051_pcm_analog_capture = { | 317 | static const struct hda_pcm_stream cx5051_pcm_analog_capture = { |
298 | .substreams = 1, | 318 | .substreams = 1, |
299 | .channels_min = 2, | 319 | .channels_min = 2, |
300 | .channels_max = 2, | 320 | .channels_max = 2, |
@@ -319,13 +339,19 @@ static int conexant_build_pcms(struct hda_codec *codec) | |||
319 | spec->multiout.max_channels; | 339 | spec->multiout.max_channels; |
320 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = | 340 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = |
321 | spec->multiout.dac_nids[0]; | 341 | spec->multiout.dac_nids[0]; |
322 | if (codec->vendor_id == 0x14f15051) | 342 | if (spec->capture_stream) |
323 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | 343 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream; |
324 | cx5051_pcm_analog_capture; | 344 | else { |
325 | else | 345 | if (codec->vendor_id == 0x14f15051) |
326 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | 346 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = |
327 | conexant_pcm_analog_capture; | 347 | cx5051_pcm_analog_capture; |
328 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; | 348 | else { |
349 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | ||
350 | conexant_pcm_analog_capture; | ||
351 | info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = | ||
352 | spec->num_adc_nids; | ||
353 | } | ||
354 | } | ||
329 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; | 355 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; |
330 | 356 | ||
331 | if (spec->multiout.dig_out_nid) { | 357 | if (spec->multiout.dig_out_nid) { |
@@ -433,7 +459,7 @@ static void conexant_free(struct hda_codec *codec) | |||
433 | kfree(codec->spec); | 459 | kfree(codec->spec); |
434 | } | 460 | } |
435 | 461 | ||
436 | static struct snd_kcontrol_new cxt_capture_mixers[] = { | 462 | static const struct snd_kcontrol_new cxt_capture_mixers[] = { |
437 | { | 463 | { |
438 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 464 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
439 | .name = "Capture Source", | 465 | .name = "Capture Source", |
@@ -446,7 +472,7 @@ static struct snd_kcontrol_new cxt_capture_mixers[] = { | |||
446 | 472 | ||
447 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 473 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
448 | /* additional beep mixers; the actual parameters are overwritten at build */ | 474 | /* additional beep mixers; the actual parameters are overwritten at build */ |
449 | static struct snd_kcontrol_new cxt_beep_mixer[] = { | 475 | static const struct snd_kcontrol_new cxt_beep_mixer[] = { |
450 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), | 476 | HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), |
451 | HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), | 477 | HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), |
452 | { } /* end */ | 478 | { } /* end */ |
@@ -456,12 +482,18 @@ static struct snd_kcontrol_new cxt_beep_mixer[] = { | |||
456 | static const char * const slave_vols[] = { | 482 | static const char * const slave_vols[] = { |
457 | "Headphone Playback Volume", | 483 | "Headphone Playback Volume", |
458 | "Speaker Playback Volume", | 484 | "Speaker Playback Volume", |
485 | "Front Playback Volume", | ||
486 | "Surround Playback Volume", | ||
487 | "CLFE Playback Volume", | ||
459 | NULL | 488 | NULL |
460 | }; | 489 | }; |
461 | 490 | ||
462 | static const char * const slave_sws[] = { | 491 | static const char * const slave_sws[] = { |
463 | "Headphone Playback Switch", | 492 | "Headphone Playback Switch", |
464 | "Speaker Playback Switch", | 493 | "Speaker Playback Switch", |
494 | "Front Playback Switch", | ||
495 | "Surround Playback Switch", | ||
496 | "CLFE Playback Switch", | ||
465 | NULL | 497 | NULL |
466 | }; | 498 | }; |
467 | 499 | ||
@@ -521,7 +553,7 @@ static int conexant_build_controls(struct hda_codec *codec) | |||
521 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 553 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
522 | /* create beep controls if needed */ | 554 | /* create beep controls if needed */ |
523 | if (spec->beep_amp) { | 555 | if (spec->beep_amp) { |
524 | struct snd_kcontrol_new *knew; | 556 | const struct snd_kcontrol_new *knew; |
525 | for (knew = cxt_beep_mixer; knew->name; knew++) { | 557 | for (knew = cxt_beep_mixer; knew->name; knew++) { |
526 | struct snd_kcontrol *kctl; | 558 | struct snd_kcontrol *kctl; |
527 | kctl = snd_ctl_new1(knew, codec); | 559 | kctl = snd_ctl_new1(knew, codec); |
@@ -546,7 +578,7 @@ static int conexant_suspend(struct hda_codec *codec, pm_message_t state) | |||
546 | } | 578 | } |
547 | #endif | 579 | #endif |
548 | 580 | ||
549 | static struct hda_codec_ops conexant_patch_ops = { | 581 | static const struct hda_codec_ops conexant_patch_ops = { |
550 | .build_controls = conexant_build_controls, | 582 | .build_controls = conexant_build_controls, |
551 | .build_pcms = conexant_build_pcms, | 583 | .build_pcms = conexant_build_pcms, |
552 | .init = conexant_init, | 584 | .init = conexant_init, |
@@ -564,6 +596,7 @@ static struct hda_codec_ops conexant_patch_ops = { | |||
564 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ | 596 | #define set_beep_amp(spec, nid, idx, dir) /* NOP */ |
565 | #endif | 597 | #endif |
566 | 598 | ||
599 | static int patch_conexant_auto(struct hda_codec *codec); | ||
567 | /* | 600 | /* |
568 | * EAPD control | 601 | * EAPD control |
569 | * the private value = nid | (invert << 8) | 602 | * the private value = nid | (invert << 8) |
@@ -662,16 +695,16 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
662 | 695 | ||
663 | /* Conexant 5045 specific */ | 696 | /* Conexant 5045 specific */ |
664 | 697 | ||
665 | static hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; | 698 | static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; |
666 | static hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; | 699 | static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; |
667 | static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; | 700 | static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; |
668 | #define CXT5045_SPDIF_OUT 0x18 | 701 | #define CXT5045_SPDIF_OUT 0x18 |
669 | 702 | ||
670 | static struct hda_channel_mode cxt5045_modes[1] = { | 703 | static const struct hda_channel_mode cxt5045_modes[1] = { |
671 | { 2, NULL }, | 704 | { 2, NULL }, |
672 | }; | 705 | }; |
673 | 706 | ||
674 | static struct hda_input_mux cxt5045_capture_source = { | 707 | static const struct hda_input_mux cxt5045_capture_source = { |
675 | .num_items = 2, | 708 | .num_items = 2, |
676 | .items = { | 709 | .items = { |
677 | { "IntMic", 0x1 }, | 710 | { "IntMic", 0x1 }, |
@@ -679,7 +712,7 @@ static struct hda_input_mux cxt5045_capture_source = { | |||
679 | } | 712 | } |
680 | }; | 713 | }; |
681 | 714 | ||
682 | static struct hda_input_mux cxt5045_capture_source_benq = { | 715 | static const struct hda_input_mux cxt5045_capture_source_benq = { |
683 | .num_items = 5, | 716 | .num_items = 5, |
684 | .items = { | 717 | .items = { |
685 | { "IntMic", 0x1 }, | 718 | { "IntMic", 0x1 }, |
@@ -690,7 +723,7 @@ static struct hda_input_mux cxt5045_capture_source_benq = { | |||
690 | } | 723 | } |
691 | }; | 724 | }; |
692 | 725 | ||
693 | static struct hda_input_mux cxt5045_capture_source_hp530 = { | 726 | static const struct hda_input_mux cxt5045_capture_source_hp530 = { |
694 | .num_items = 2, | 727 | .num_items = 2, |
695 | .items = { | 728 | .items = { |
696 | { "ExtMic", 0x1 }, | 729 | { "ExtMic", 0x1 }, |
@@ -723,7 +756,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
723 | } | 756 | } |
724 | 757 | ||
725 | /* bind volumes of both NID 0x10 and 0x11 */ | 758 | /* bind volumes of both NID 0x10 and 0x11 */ |
726 | static struct hda_bind_ctls cxt5045_hp_bind_master_vol = { | 759 | static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = { |
727 | .ops = &snd_hda_bind_vol, | 760 | .ops = &snd_hda_bind_vol, |
728 | .values = { | 761 | .values = { |
729 | HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT), | 762 | HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT), |
@@ -735,12 +768,12 @@ static struct hda_bind_ctls cxt5045_hp_bind_master_vol = { | |||
735 | /* toggle input of built-in and mic jack appropriately */ | 768 | /* toggle input of built-in and mic jack appropriately */ |
736 | static void cxt5045_hp_automic(struct hda_codec *codec) | 769 | static void cxt5045_hp_automic(struct hda_codec *codec) |
737 | { | 770 | { |
738 | static struct hda_verb mic_jack_on[] = { | 771 | static const struct hda_verb mic_jack_on[] = { |
739 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 772 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, |
740 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 773 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, |
741 | {} | 774 | {} |
742 | }; | 775 | }; |
743 | static struct hda_verb mic_jack_off[] = { | 776 | static const struct hda_verb mic_jack_off[] = { |
744 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, | 777 | {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, |
745 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, | 778 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, |
746 | {} | 779 | {} |
@@ -784,7 +817,7 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, | |||
784 | } | 817 | } |
785 | } | 818 | } |
786 | 819 | ||
787 | static struct snd_kcontrol_new cxt5045_mixers[] = { | 820 | static const struct snd_kcontrol_new cxt5045_mixers[] = { |
788 | HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), | 821 | HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), |
789 | HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), | 822 | HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), |
790 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), | 823 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), |
@@ -808,7 +841,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { | |||
808 | {} | 841 | {} |
809 | }; | 842 | }; |
810 | 843 | ||
811 | static struct snd_kcontrol_new cxt5045_benq_mixers[] = { | 844 | static const struct snd_kcontrol_new cxt5045_benq_mixers[] = { |
812 | HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT), | 845 | HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT), |
813 | HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT), | 846 | HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT), |
814 | HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT), | 847 | HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT), |
@@ -825,7 +858,7 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = { | |||
825 | {} | 858 | {} |
826 | }; | 859 | }; |
827 | 860 | ||
828 | static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { | 861 | static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = { |
829 | HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), | 862 | HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), |
830 | HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), | 863 | HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), |
831 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), | 864 | HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), |
@@ -849,7 +882,7 @@ static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { | |||
849 | {} | 882 | {} |
850 | }; | 883 | }; |
851 | 884 | ||
852 | static struct hda_verb cxt5045_init_verbs[] = { | 885 | static const struct hda_verb cxt5045_init_verbs[] = { |
853 | /* Line in, Mic */ | 886 | /* Line in, Mic */ |
854 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, | 887 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, |
855 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, | 888 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, |
@@ -875,7 +908,7 @@ static struct hda_verb cxt5045_init_verbs[] = { | |||
875 | { } /* end */ | 908 | { } /* end */ |
876 | }; | 909 | }; |
877 | 910 | ||
878 | static struct hda_verb cxt5045_benq_init_verbs[] = { | 911 | static const struct hda_verb cxt5045_benq_init_verbs[] = { |
879 | /* Internal Mic, Mic */ | 912 | /* Internal Mic, Mic */ |
880 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, | 913 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, |
881 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, | 914 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, |
@@ -901,13 +934,13 @@ static struct hda_verb cxt5045_benq_init_verbs[] = { | |||
901 | { } /* end */ | 934 | { } /* end */ |
902 | }; | 935 | }; |
903 | 936 | ||
904 | static struct hda_verb cxt5045_hp_sense_init_verbs[] = { | 937 | static const struct hda_verb cxt5045_hp_sense_init_verbs[] = { |
905 | /* pin sensing on HP jack */ | 938 | /* pin sensing on HP jack */ |
906 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | 939 | {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, |
907 | { } /* end */ | 940 | { } /* end */ |
908 | }; | 941 | }; |
909 | 942 | ||
910 | static struct hda_verb cxt5045_mic_sense_init_verbs[] = { | 943 | static const struct hda_verb cxt5045_mic_sense_init_verbs[] = { |
911 | /* pin sensing on HP jack */ | 944 | /* pin sensing on HP jack */ |
912 | {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | 945 | {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, |
913 | { } /* end */ | 946 | { } /* end */ |
@@ -917,7 +950,7 @@ static struct hda_verb cxt5045_mic_sense_init_verbs[] = { | |||
917 | /* Test configuration for debugging, modelled after the ALC260 test | 950 | /* Test configuration for debugging, modelled after the ALC260 test |
918 | * configuration. | 951 | * configuration. |
919 | */ | 952 | */ |
920 | static struct hda_input_mux cxt5045_test_capture_source = { | 953 | static const struct hda_input_mux cxt5045_test_capture_source = { |
921 | .num_items = 5, | 954 | .num_items = 5, |
922 | .items = { | 955 | .items = { |
923 | { "MIXER", 0x0 }, | 956 | { "MIXER", 0x0 }, |
@@ -928,7 +961,7 @@ static struct hda_input_mux cxt5045_test_capture_source = { | |||
928 | }, | 961 | }, |
929 | }; | 962 | }; |
930 | 963 | ||
931 | static struct snd_kcontrol_new cxt5045_test_mixer[] = { | 964 | static const struct snd_kcontrol_new cxt5045_test_mixer[] = { |
932 | 965 | ||
933 | /* Output controls */ | 966 | /* Output controls */ |
934 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), | 967 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), |
@@ -978,7 +1011,7 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { | |||
978 | { } /* end */ | 1011 | { } /* end */ |
979 | }; | 1012 | }; |
980 | 1013 | ||
981 | static struct hda_verb cxt5045_test_init_verbs[] = { | 1014 | static const struct hda_verb cxt5045_test_init_verbs[] = { |
982 | /* Set connections */ | 1015 | /* Set connections */ |
983 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, | 1016 | { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
984 | { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, | 1017 | { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, |
@@ -1047,6 +1080,7 @@ enum { | |||
1047 | #ifdef CONFIG_SND_DEBUG | 1080 | #ifdef CONFIG_SND_DEBUG |
1048 | CXT5045_TEST, | 1081 | CXT5045_TEST, |
1049 | #endif | 1082 | #endif |
1083 | CXT5045_AUTO, | ||
1050 | CXT5045_MODELS | 1084 | CXT5045_MODELS |
1051 | }; | 1085 | }; |
1052 | 1086 | ||
@@ -1059,9 +1093,10 @@ static const char * const cxt5045_models[CXT5045_MODELS] = { | |||
1059 | #ifdef CONFIG_SND_DEBUG | 1093 | #ifdef CONFIG_SND_DEBUG |
1060 | [CXT5045_TEST] = "test", | 1094 | [CXT5045_TEST] = "test", |
1061 | #endif | 1095 | #endif |
1096 | [CXT5045_AUTO] = "auto", | ||
1062 | }; | 1097 | }; |
1063 | 1098 | ||
1064 | static struct snd_pci_quirk cxt5045_cfg_tbl[] = { | 1099 | static const struct snd_pci_quirk cxt5045_cfg_tbl[] = { |
1065 | SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), | 1100 | SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), |
1066 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", | 1101 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", |
1067 | CXT5045_LAPTOP_HPSENSE), | 1102 | CXT5045_LAPTOP_HPSENSE), |
@@ -1085,6 +1120,16 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1085 | struct conexant_spec *spec; | 1120 | struct conexant_spec *spec; |
1086 | int board_config; | 1121 | int board_config; |
1087 | 1122 | ||
1123 | board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, | ||
1124 | cxt5045_models, | ||
1125 | cxt5045_cfg_tbl); | ||
1126 | #if 0 /* use the old method just for safety */ | ||
1127 | if (board_config < 0) | ||
1128 | board_config = CXT5045_AUTO; | ||
1129 | #endif | ||
1130 | if (board_config == CXT5045_AUTO) | ||
1131 | return patch_conexant_auto(codec); | ||
1132 | |||
1088 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 1133 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
1089 | if (!spec) | 1134 | if (!spec) |
1090 | return -ENOMEM; | 1135 | return -ENOMEM; |
@@ -1111,9 +1156,6 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1111 | 1156 | ||
1112 | codec->patch_ops = conexant_patch_ops; | 1157 | codec->patch_ops = conexant_patch_ops; |
1113 | 1158 | ||
1114 | board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, | ||
1115 | cxt5045_models, | ||
1116 | cxt5045_cfg_tbl); | ||
1117 | switch (board_config) { | 1159 | switch (board_config) { |
1118 | case CXT5045_LAPTOP_HPSENSE: | 1160 | case CXT5045_LAPTOP_HPSENSE: |
1119 | codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; | 1161 | codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; |
@@ -1196,15 +1238,15 @@ static int patch_cxt5045(struct hda_codec *codec) | |||
1196 | /* Conexant 5047 specific */ | 1238 | /* Conexant 5047 specific */ |
1197 | #define CXT5047_SPDIF_OUT 0x11 | 1239 | #define CXT5047_SPDIF_OUT 0x11 |
1198 | 1240 | ||
1199 | static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */ | 1241 | static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */ |
1200 | static hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; | 1242 | static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; |
1201 | static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; | 1243 | static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; |
1202 | 1244 | ||
1203 | static struct hda_channel_mode cxt5047_modes[1] = { | 1245 | static const struct hda_channel_mode cxt5047_modes[1] = { |
1204 | { 2, NULL }, | 1246 | { 2, NULL }, |
1205 | }; | 1247 | }; |
1206 | 1248 | ||
1207 | static struct hda_input_mux cxt5047_toshiba_capture_source = { | 1249 | static const struct hda_input_mux cxt5047_toshiba_capture_source = { |
1208 | .num_items = 2, | 1250 | .num_items = 2, |
1209 | .items = { | 1251 | .items = { |
1210 | { "ExtMic", 0x2 }, | 1252 | { "ExtMic", 0x2 }, |
@@ -1256,12 +1298,12 @@ static void cxt5047_hp_automute(struct hda_codec *codec) | |||
1256 | /* toggle input of built-in and mic jack appropriately */ | 1298 | /* toggle input of built-in and mic jack appropriately */ |
1257 | static void cxt5047_hp_automic(struct hda_codec *codec) | 1299 | static void cxt5047_hp_automic(struct hda_codec *codec) |
1258 | { | 1300 | { |
1259 | static struct hda_verb mic_jack_on[] = { | 1301 | static const struct hda_verb mic_jack_on[] = { |
1260 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 1302 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
1261 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 1303 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1262 | {} | 1304 | {} |
1263 | }; | 1305 | }; |
1264 | static struct hda_verb mic_jack_off[] = { | 1306 | static const struct hda_verb mic_jack_off[] = { |
1265 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 1307 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
1266 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 1308 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
1267 | {} | 1309 | {} |
@@ -1289,7 +1331,7 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec, | |||
1289 | } | 1331 | } |
1290 | } | 1332 | } |
1291 | 1333 | ||
1292 | static struct snd_kcontrol_new cxt5047_base_mixers[] = { | 1334 | static const struct snd_kcontrol_new cxt5047_base_mixers[] = { |
1293 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT), | 1335 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT), |
1294 | HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT), | 1336 | HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT), |
1295 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT), | 1337 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT), |
@@ -1309,19 +1351,19 @@ static struct snd_kcontrol_new cxt5047_base_mixers[] = { | |||
1309 | {} | 1351 | {} |
1310 | }; | 1352 | }; |
1311 | 1353 | ||
1312 | static struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = { | 1354 | static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = { |
1313 | /* See the note in cxt5047_hp_master_sw_put */ | 1355 | /* See the note in cxt5047_hp_master_sw_put */ |
1314 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT), | 1356 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT), |
1315 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), | 1357 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), |
1316 | {} | 1358 | {} |
1317 | }; | 1359 | }; |
1318 | 1360 | ||
1319 | static struct snd_kcontrol_new cxt5047_hp_only_mixers[] = { | 1361 | static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = { |
1320 | HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT), | 1362 | HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT), |
1321 | { } /* end */ | 1363 | { } /* end */ |
1322 | }; | 1364 | }; |
1323 | 1365 | ||
1324 | static struct hda_verb cxt5047_init_verbs[] = { | 1366 | static const struct hda_verb cxt5047_init_verbs[] = { |
1325 | /* Line in, Mic, Built-in Mic */ | 1367 | /* Line in, Mic, Built-in Mic */ |
1326 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 1368 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
1327 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, | 1369 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, |
@@ -1348,7 +1390,7 @@ static struct hda_verb cxt5047_init_verbs[] = { | |||
1348 | }; | 1390 | }; |
1349 | 1391 | ||
1350 | /* configuration for Toshiba Laptops */ | 1392 | /* configuration for Toshiba Laptops */ |
1351 | static struct hda_verb cxt5047_toshiba_init_verbs[] = { | 1393 | static const struct hda_verb cxt5047_toshiba_init_verbs[] = { |
1352 | {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */ | 1394 | {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */ |
1353 | {} | 1395 | {} |
1354 | }; | 1396 | }; |
@@ -1357,7 +1399,7 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = { | |||
1357 | * configuration. | 1399 | * configuration. |
1358 | */ | 1400 | */ |
1359 | #ifdef CONFIG_SND_DEBUG | 1401 | #ifdef CONFIG_SND_DEBUG |
1360 | static struct hda_input_mux cxt5047_test_capture_source = { | 1402 | static const struct hda_input_mux cxt5047_test_capture_source = { |
1361 | .num_items = 4, | 1403 | .num_items = 4, |
1362 | .items = { | 1404 | .items = { |
1363 | { "LINE1 pin", 0x0 }, | 1405 | { "LINE1 pin", 0x0 }, |
@@ -1367,7 +1409,7 @@ static struct hda_input_mux cxt5047_test_capture_source = { | |||
1367 | }, | 1409 | }, |
1368 | }; | 1410 | }; |
1369 | 1411 | ||
1370 | static struct snd_kcontrol_new cxt5047_test_mixer[] = { | 1412 | static const struct snd_kcontrol_new cxt5047_test_mixer[] = { |
1371 | 1413 | ||
1372 | /* Output only controls */ | 1414 | /* Output only controls */ |
1373 | HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT), | 1415 | HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT), |
@@ -1420,7 +1462,7 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = { | |||
1420 | { } /* end */ | 1462 | { } /* end */ |
1421 | }; | 1463 | }; |
1422 | 1464 | ||
1423 | static struct hda_verb cxt5047_test_init_verbs[] = { | 1465 | static const struct hda_verb cxt5047_test_init_verbs[] = { |
1424 | /* Enable retasking pins as output, initially without power amp */ | 1466 | /* Enable retasking pins as output, initially without power amp */ |
1425 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 1467 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1426 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 1468 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
@@ -1492,6 +1534,7 @@ enum { | |||
1492 | #ifdef CONFIG_SND_DEBUG | 1534 | #ifdef CONFIG_SND_DEBUG |
1493 | CXT5047_TEST, | 1535 | CXT5047_TEST, |
1494 | #endif | 1536 | #endif |
1537 | CXT5047_AUTO, | ||
1495 | CXT5047_MODELS | 1538 | CXT5047_MODELS |
1496 | }; | 1539 | }; |
1497 | 1540 | ||
@@ -1502,9 +1545,10 @@ static const char * const cxt5047_models[CXT5047_MODELS] = { | |||
1502 | #ifdef CONFIG_SND_DEBUG | 1545 | #ifdef CONFIG_SND_DEBUG |
1503 | [CXT5047_TEST] = "test", | 1546 | [CXT5047_TEST] = "test", |
1504 | #endif | 1547 | #endif |
1548 | [CXT5047_AUTO] = "auto", | ||
1505 | }; | 1549 | }; |
1506 | 1550 | ||
1507 | static struct snd_pci_quirk cxt5047_cfg_tbl[] = { | 1551 | static const struct snd_pci_quirk cxt5047_cfg_tbl[] = { |
1508 | SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), | 1552 | SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), |
1509 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", | 1553 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", |
1510 | CXT5047_LAPTOP), | 1554 | CXT5047_LAPTOP), |
@@ -1517,6 +1561,16 @@ static int patch_cxt5047(struct hda_codec *codec) | |||
1517 | struct conexant_spec *spec; | 1561 | struct conexant_spec *spec; |
1518 | int board_config; | 1562 | int board_config; |
1519 | 1563 | ||
1564 | board_config = snd_hda_check_board_config(codec, CXT5047_MODELS, | ||
1565 | cxt5047_models, | ||
1566 | cxt5047_cfg_tbl); | ||
1567 | #if 0 /* not enabled as default, as BIOS often broken for this codec */ | ||
1568 | if (board_config < 0) | ||
1569 | board_config = CXT5047_AUTO; | ||
1570 | #endif | ||
1571 | if (board_config == CXT5047_AUTO) | ||
1572 | return patch_conexant_auto(codec); | ||
1573 | |||
1520 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 1574 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
1521 | if (!spec) | 1575 | if (!spec) |
1522 | return -ENOMEM; | 1576 | return -ENOMEM; |
@@ -1540,9 +1594,6 @@ static int patch_cxt5047(struct hda_codec *codec) | |||
1540 | 1594 | ||
1541 | codec->patch_ops = conexant_patch_ops; | 1595 | codec->patch_ops = conexant_patch_ops; |
1542 | 1596 | ||
1543 | board_config = snd_hda_check_board_config(codec, CXT5047_MODELS, | ||
1544 | cxt5047_models, | ||
1545 | cxt5047_cfg_tbl); | ||
1546 | switch (board_config) { | 1597 | switch (board_config) { |
1547 | case CXT5047_LAPTOP: | 1598 | case CXT5047_LAPTOP: |
1548 | spec->num_mixers = 2; | 1599 | spec->num_mixers = 2; |
@@ -1591,10 +1642,10 @@ static int patch_cxt5047(struct hda_codec *codec) | |||
1591 | } | 1642 | } |
1592 | 1643 | ||
1593 | /* Conexant 5051 specific */ | 1644 | /* Conexant 5051 specific */ |
1594 | static hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; | 1645 | static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; |
1595 | static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; | 1646 | static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; |
1596 | 1647 | ||
1597 | static struct hda_channel_mode cxt5051_modes[1] = { | 1648 | static const struct hda_channel_mode cxt5051_modes[1] = { |
1598 | { 2, NULL }, | 1649 | { 2, NULL }, |
1599 | }; | 1650 | }; |
1600 | 1651 | ||
@@ -1696,7 +1747,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, | |||
1696 | snd_hda_input_jack_report(codec, nid); | 1747 | snd_hda_input_jack_report(codec, nid); |
1697 | } | 1748 | } |
1698 | 1749 | ||
1699 | static struct snd_kcontrol_new cxt5051_playback_mixers[] = { | 1750 | static const struct snd_kcontrol_new cxt5051_playback_mixers[] = { |
1700 | HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), | 1751 | HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), |
1701 | { | 1752 | { |
1702 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1753 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -1709,7 +1760,7 @@ static struct snd_kcontrol_new cxt5051_playback_mixers[] = { | |||
1709 | {} | 1760 | {} |
1710 | }; | 1761 | }; |
1711 | 1762 | ||
1712 | static struct snd_kcontrol_new cxt5051_capture_mixers[] = { | 1763 | static const struct snd_kcontrol_new cxt5051_capture_mixers[] = { |
1713 | HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), | 1764 | HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), |
1714 | HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), | 1765 | HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), |
1715 | HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), | 1766 | HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), |
@@ -1719,7 +1770,7 @@ static struct snd_kcontrol_new cxt5051_capture_mixers[] = { | |||
1719 | {} | 1770 | {} |
1720 | }; | 1771 | }; |
1721 | 1772 | ||
1722 | static struct snd_kcontrol_new cxt5051_hp_mixers[] = { | 1773 | static const struct snd_kcontrol_new cxt5051_hp_mixers[] = { |
1723 | HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), | 1774 | HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), |
1724 | HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), | 1775 | HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), |
1725 | HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT), | 1776 | HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT), |
@@ -1727,19 +1778,19 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = { | |||
1727 | {} | 1778 | {} |
1728 | }; | 1779 | }; |
1729 | 1780 | ||
1730 | static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { | 1781 | static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { |
1731 | HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT), | 1782 | HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT), |
1732 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT), | 1783 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT), |
1733 | {} | 1784 | {} |
1734 | }; | 1785 | }; |
1735 | 1786 | ||
1736 | static struct snd_kcontrol_new cxt5051_f700_mixers[] = { | 1787 | static const struct snd_kcontrol_new cxt5051_f700_mixers[] = { |
1737 | HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT), | 1788 | HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT), |
1738 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT), | 1789 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT), |
1739 | {} | 1790 | {} |
1740 | }; | 1791 | }; |
1741 | 1792 | ||
1742 | static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { | 1793 | static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { |
1743 | HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), | 1794 | HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), |
1744 | HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), | 1795 | HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), |
1745 | HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), | 1796 | HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), |
@@ -1747,7 +1798,7 @@ static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { | |||
1747 | {} | 1798 | {} |
1748 | }; | 1799 | }; |
1749 | 1800 | ||
1750 | static struct hda_verb cxt5051_init_verbs[] = { | 1801 | static const struct hda_verb cxt5051_init_verbs[] = { |
1751 | /* Line in, Mic */ | 1802 | /* Line in, Mic */ |
1752 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, | 1803 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, |
1753 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 1804 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
@@ -1776,7 +1827,7 @@ static struct hda_verb cxt5051_init_verbs[] = { | |||
1776 | { } /* end */ | 1827 | { } /* end */ |
1777 | }; | 1828 | }; |
1778 | 1829 | ||
1779 | static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { | 1830 | static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { |
1780 | /* Line in, Mic */ | 1831 | /* Line in, Mic */ |
1781 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, | 1832 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, |
1782 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 1833 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
@@ -1801,7 +1852,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { | |||
1801 | { } /* end */ | 1852 | { } /* end */ |
1802 | }; | 1853 | }; |
1803 | 1854 | ||
1804 | static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { | 1855 | static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { |
1805 | /* Line in, Mic */ | 1856 | /* Line in, Mic */ |
1806 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, | 1857 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, |
1807 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 1858 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
@@ -1834,7 +1885,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { | |||
1834 | { } /* end */ | 1885 | { } /* end */ |
1835 | }; | 1886 | }; |
1836 | 1887 | ||
1837 | static struct hda_verb cxt5051_f700_init_verbs[] = { | 1888 | static const struct hda_verb cxt5051_f700_init_verbs[] = { |
1838 | /* Line in, Mic */ | 1889 | /* Line in, Mic */ |
1839 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, | 1890 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, |
1840 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 1891 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
@@ -1869,7 +1920,7 @@ static void cxt5051_init_mic_port(struct hda_codec *codec, hda_nid_t nid, | |||
1869 | snd_hda_input_jack_report(codec, nid); | 1920 | snd_hda_input_jack_report(codec, nid); |
1870 | } | 1921 | } |
1871 | 1922 | ||
1872 | static struct hda_verb cxt5051_ideapad_init_verbs[] = { | 1923 | static const struct hda_verb cxt5051_ideapad_init_verbs[] = { |
1873 | /* Subwoofer */ | 1924 | /* Subwoofer */ |
1874 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 1925 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
1875 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | 1926 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -1906,6 +1957,7 @@ enum { | |||
1906 | CXT5051_F700, /* HP Compaq Presario F700 */ | 1957 | CXT5051_F700, /* HP Compaq Presario F700 */ |
1907 | CXT5051_TOSHIBA, /* Toshiba M300 & co */ | 1958 | CXT5051_TOSHIBA, /* Toshiba M300 & co */ |
1908 | CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ | 1959 | CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ |
1960 | CXT5051_AUTO, /* auto-parser */ | ||
1909 | CXT5051_MODELS | 1961 | CXT5051_MODELS |
1910 | }; | 1962 | }; |
1911 | 1963 | ||
@@ -1917,9 +1969,10 @@ static const char *const cxt5051_models[CXT5051_MODELS] = { | |||
1917 | [CXT5051_F700] = "hp-700", | 1969 | [CXT5051_F700] = "hp-700", |
1918 | [CXT5051_TOSHIBA] = "toshiba", | 1970 | [CXT5051_TOSHIBA] = "toshiba", |
1919 | [CXT5051_IDEAPAD] = "ideapad", | 1971 | [CXT5051_IDEAPAD] = "ideapad", |
1972 | [CXT5051_AUTO] = "auto", | ||
1920 | }; | 1973 | }; |
1921 | 1974 | ||
1922 | static struct snd_pci_quirk cxt5051_cfg_tbl[] = { | 1975 | static const struct snd_pci_quirk cxt5051_cfg_tbl[] = { |
1923 | SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), | 1976 | SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), |
1924 | SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), | 1977 | SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), |
1925 | SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700), | 1978 | SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700), |
@@ -1937,6 +1990,16 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1937 | struct conexant_spec *spec; | 1990 | struct conexant_spec *spec; |
1938 | int board_config; | 1991 | int board_config; |
1939 | 1992 | ||
1993 | board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, | ||
1994 | cxt5051_models, | ||
1995 | cxt5051_cfg_tbl); | ||
1996 | #if 0 /* use the old method just for safety */ | ||
1997 | if (board_config < 0) | ||
1998 | board_config = CXT5051_AUTO; | ||
1999 | #endif | ||
2000 | if (board_config == CXT5051_AUTO) | ||
2001 | return patch_conexant_auto(codec); | ||
2002 | |||
1940 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 2003 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
1941 | if (!spec) | 2004 | if (!spec) |
1942 | return -ENOMEM; | 2005 | return -ENOMEM; |
@@ -1967,9 +2030,6 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
1967 | 2030 | ||
1968 | codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; | 2031 | codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; |
1969 | 2032 | ||
1970 | board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, | ||
1971 | cxt5051_models, | ||
1972 | cxt5051_cfg_tbl); | ||
1973 | spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC; | 2033 | spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC; |
1974 | switch (board_config) { | 2034 | switch (board_config) { |
1975 | case CXT5051_HP: | 2035 | case CXT5051_HP: |
@@ -2011,17 +2071,17 @@ static int patch_cxt5051(struct hda_codec *codec) | |||
2011 | 2071 | ||
2012 | /* Conexant 5066 specific */ | 2072 | /* Conexant 5066 specific */ |
2013 | 2073 | ||
2014 | static hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; | 2074 | static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; |
2015 | static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; | 2075 | static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; |
2016 | static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; | 2076 | static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; |
2017 | static hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 }; | 2077 | static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 }; |
2018 | 2078 | ||
2019 | /* OLPC's microphone port is DC coupled for use with external sensors, | 2079 | /* OLPC's microphone port is DC coupled for use with external sensors, |
2020 | * therefore we use a 50% mic bias in order to center the input signal with | 2080 | * therefore we use a 50% mic bias in order to center the input signal with |
2021 | * the DC input range of the codec. */ | 2081 | * the DC input range of the codec. */ |
2022 | #define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50 | 2082 | #define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50 |
2023 | 2083 | ||
2024 | static struct hda_channel_mode cxt5066_modes[1] = { | 2084 | static const struct hda_channel_mode cxt5066_modes[1] = { |
2025 | { 2, NULL }, | 2085 | { 2, NULL }, |
2026 | }; | 2086 | }; |
2027 | 2087 | ||
@@ -2176,7 +2236,7 @@ static void cxt5066_vostro_automic(struct hda_codec *codec) | |||
2176 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2236 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2177 | {} | 2237 | {} |
2178 | }; | 2238 | }; |
2179 | static struct hda_verb ext_mic_absent[] = { | 2239 | static const struct hda_verb ext_mic_absent[] = { |
2180 | /* enable internal mic, port C */ | 2240 | /* enable internal mic, port C */ |
2181 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 2241 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
2182 | 2242 | ||
@@ -2209,7 +2269,7 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec) | |||
2209 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2269 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2210 | {} | 2270 | {} |
2211 | }; | 2271 | }; |
2212 | static struct hda_verb ext_mic_absent[] = { | 2272 | static const struct hda_verb ext_mic_absent[] = { |
2213 | {0x14, AC_VERB_SET_CONNECT_SEL, 2}, | 2273 | {0x14, AC_VERB_SET_CONNECT_SEL, 2}, |
2214 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 2274 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
2215 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2275 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
@@ -2257,7 +2317,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec) | |||
2257 | { | 2317 | { |
2258 | unsigned int ext_present, dock_present; | 2318 | unsigned int ext_present, dock_present; |
2259 | 2319 | ||
2260 | static struct hda_verb ext_mic_present[] = { | 2320 | static const struct hda_verb ext_mic_present[] = { |
2261 | {0x14, AC_VERB_SET_CONNECT_SEL, 0}, | 2321 | {0x14, AC_VERB_SET_CONNECT_SEL, 0}, |
2262 | {0x17, AC_VERB_SET_CONNECT_SEL, 1}, | 2322 | {0x17, AC_VERB_SET_CONNECT_SEL, 1}, |
2263 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 2323 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
@@ -2265,7 +2325,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec) | |||
2265 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2325 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2266 | {} | 2326 | {} |
2267 | }; | 2327 | }; |
2268 | static struct hda_verb dock_mic_present[] = { | 2328 | static const struct hda_verb dock_mic_present[] = { |
2269 | {0x14, AC_VERB_SET_CONNECT_SEL, 0}, | 2329 | {0x14, AC_VERB_SET_CONNECT_SEL, 0}, |
2270 | {0x17, AC_VERB_SET_CONNECT_SEL, 0}, | 2330 | {0x17, AC_VERB_SET_CONNECT_SEL, 0}, |
2271 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, | 2331 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, |
@@ -2273,7 +2333,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec) | |||
2273 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2333 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2274 | {} | 2334 | {} |
2275 | }; | 2335 | }; |
2276 | static struct hda_verb ext_mic_absent[] = { | 2336 | static const struct hda_verb ext_mic_absent[] = { |
2277 | {0x14, AC_VERB_SET_CONNECT_SEL, 2}, | 2337 | {0x14, AC_VERB_SET_CONNECT_SEL, 2}, |
2278 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 2338 | {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
2279 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2339 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
@@ -2537,7 +2597,7 @@ static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec) | |||
2537 | } | 2597 | } |
2538 | 2598 | ||
2539 | static void conexant_check_dig_outs(struct hda_codec *codec, | 2599 | static void conexant_check_dig_outs(struct hda_codec *codec, |
2540 | hda_nid_t *dig_pins, | 2600 | const hda_nid_t *dig_pins, |
2541 | int num_pins) | 2601 | int num_pins) |
2542 | { | 2602 | { |
2543 | struct conexant_spec *spec = codec->spec; | 2603 | struct conexant_spec *spec = codec->spec; |
@@ -2557,7 +2617,7 @@ static void conexant_check_dig_outs(struct hda_codec *codec, | |||
2557 | } | 2617 | } |
2558 | } | 2618 | } |
2559 | 2619 | ||
2560 | static struct hda_input_mux cxt5066_capture_source = { | 2620 | static const struct hda_input_mux cxt5066_capture_source = { |
2561 | .num_items = 4, | 2621 | .num_items = 4, |
2562 | .items = { | 2622 | .items = { |
2563 | { "Mic B", 0 }, | 2623 | { "Mic B", 0 }, |
@@ -2567,7 +2627,7 @@ static struct hda_input_mux cxt5066_capture_source = { | |||
2567 | }, | 2627 | }, |
2568 | }; | 2628 | }; |
2569 | 2629 | ||
2570 | static struct hda_bind_ctls cxt5066_bind_capture_vol_others = { | 2630 | static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = { |
2571 | .ops = &snd_hda_bind_vol, | 2631 | .ops = &snd_hda_bind_vol, |
2572 | .values = { | 2632 | .values = { |
2573 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), | 2633 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), |
@@ -2576,7 +2636,7 @@ static struct hda_bind_ctls cxt5066_bind_capture_vol_others = { | |||
2576 | }, | 2636 | }, |
2577 | }; | 2637 | }; |
2578 | 2638 | ||
2579 | static struct hda_bind_ctls cxt5066_bind_capture_sw_others = { | 2639 | static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = { |
2580 | .ops = &snd_hda_bind_sw, | 2640 | .ops = &snd_hda_bind_sw, |
2581 | .values = { | 2641 | .values = { |
2582 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), | 2642 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), |
@@ -2585,12 +2645,12 @@ static struct hda_bind_ctls cxt5066_bind_capture_sw_others = { | |||
2585 | }, | 2645 | }, |
2586 | }; | 2646 | }; |
2587 | 2647 | ||
2588 | static struct snd_kcontrol_new cxt5066_mixer_master[] = { | 2648 | static const struct snd_kcontrol_new cxt5066_mixer_master[] = { |
2589 | HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), | 2649 | HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), |
2590 | {} | 2650 | {} |
2591 | }; | 2651 | }; |
2592 | 2652 | ||
2593 | static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { | 2653 | static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { |
2594 | { | 2654 | { |
2595 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2655 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2596 | .name = "Master Playback Volume", | 2656 | .name = "Master Playback Volume", |
@@ -2609,7 +2669,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { | |||
2609 | {} | 2669 | {} |
2610 | }; | 2670 | }; |
2611 | 2671 | ||
2612 | static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { | 2672 | static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { |
2613 | { | 2673 | { |
2614 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2674 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2615 | .name = "DC Mode Enable Switch", | 2675 | .name = "DC Mode Enable Switch", |
@@ -2627,7 +2687,7 @@ static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { | |||
2627 | {} | 2687 | {} |
2628 | }; | 2688 | }; |
2629 | 2689 | ||
2630 | static struct snd_kcontrol_new cxt5066_mixers[] = { | 2690 | static const struct snd_kcontrol_new cxt5066_mixers[] = { |
2631 | { | 2691 | { |
2632 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2692 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2633 | .name = "Master Playback Switch", | 2693 | .name = "Master Playback Switch", |
@@ -2650,7 +2710,7 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { | |||
2650 | {} | 2710 | {} |
2651 | }; | 2711 | }; |
2652 | 2712 | ||
2653 | static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { | 2713 | static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = { |
2654 | { | 2714 | { |
2655 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2715 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2656 | .name = "Internal Mic Boost Capture Enum", | 2716 | .name = "Internal Mic Boost Capture Enum", |
@@ -2662,7 +2722,7 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { | |||
2662 | {} | 2722 | {} |
2663 | }; | 2723 | }; |
2664 | 2724 | ||
2665 | static struct hda_verb cxt5066_init_verbs[] = { | 2725 | static const struct hda_verb cxt5066_init_verbs[] = { |
2666 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ | 2726 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ |
2667 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ | 2727 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ |
2668 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ | 2728 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ |
@@ -2717,7 +2777,7 @@ static struct hda_verb cxt5066_init_verbs[] = { | |||
2717 | { } /* end */ | 2777 | { } /* end */ |
2718 | }; | 2778 | }; |
2719 | 2779 | ||
2720 | static struct hda_verb cxt5066_init_verbs_olpc[] = { | 2780 | static const struct hda_verb cxt5066_init_verbs_olpc[] = { |
2721 | /* Port A: headphones */ | 2781 | /* Port A: headphones */ |
2722 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 2782 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
2723 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | 2783 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ |
@@ -2778,7 +2838,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = { | |||
2778 | { } /* end */ | 2838 | { } /* end */ |
2779 | }; | 2839 | }; |
2780 | 2840 | ||
2781 | static struct hda_verb cxt5066_init_verbs_vostro[] = { | 2841 | static const struct hda_verb cxt5066_init_verbs_vostro[] = { |
2782 | /* Port A: headphones */ | 2842 | /* Port A: headphones */ |
2783 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, | 2843 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, |
2784 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ | 2844 | {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ |
@@ -2839,7 +2899,7 @@ static struct hda_verb cxt5066_init_verbs_vostro[] = { | |||
2839 | { } /* end */ | 2899 | { } /* end */ |
2840 | }; | 2900 | }; |
2841 | 2901 | ||
2842 | static struct hda_verb cxt5066_init_verbs_ideapad[] = { | 2902 | static const struct hda_verb cxt5066_init_verbs_ideapad[] = { |
2843 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ | 2903 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ |
2844 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ | 2904 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ |
2845 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ | 2905 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ |
@@ -2889,7 +2949,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = { | |||
2889 | { } /* end */ | 2949 | { } /* end */ |
2890 | }; | 2950 | }; |
2891 | 2951 | ||
2892 | static struct hda_verb cxt5066_init_verbs_thinkpad[] = { | 2952 | static const struct hda_verb cxt5066_init_verbs_thinkpad[] = { |
2893 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ | 2953 | {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ |
2894 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ | 2954 | {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ |
2895 | 2955 | ||
@@ -2947,13 +3007,13 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = { | |||
2947 | { } /* end */ | 3007 | { } /* end */ |
2948 | }; | 3008 | }; |
2949 | 3009 | ||
2950 | static struct hda_verb cxt5066_init_verbs_portd_lo[] = { | 3010 | static const struct hda_verb cxt5066_init_verbs_portd_lo[] = { |
2951 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 3011 | {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
2952 | { } /* end */ | 3012 | { } /* end */ |
2953 | }; | 3013 | }; |
2954 | 3014 | ||
2955 | 3015 | ||
2956 | static struct hda_verb cxt5066_init_verbs_hp_laptop[] = { | 3016 | static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = { |
2957 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x0}, | 3017 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x0}, |
2958 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, | 3018 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, |
2959 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, | 3019 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, |
@@ -2997,6 +3057,7 @@ enum { | |||
2997 | CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ | 3057 | CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ |
2998 | CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */ | 3058 | CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */ |
2999 | CXT5066_HP_LAPTOP, /* HP Laptop */ | 3059 | CXT5066_HP_LAPTOP, /* HP Laptop */ |
3060 | CXT5066_AUTO, /* BIOS auto-parser */ | ||
3000 | CXT5066_MODELS | 3061 | CXT5066_MODELS |
3001 | }; | 3062 | }; |
3002 | 3063 | ||
@@ -3009,9 +3070,10 @@ static const char * const cxt5066_models[CXT5066_MODELS] = { | |||
3009 | [CXT5066_THINKPAD] = "thinkpad", | 3070 | [CXT5066_THINKPAD] = "thinkpad", |
3010 | [CXT5066_ASUS] = "asus", | 3071 | [CXT5066_ASUS] = "asus", |
3011 | [CXT5066_HP_LAPTOP] = "hp-laptop", | 3072 | [CXT5066_HP_LAPTOP] = "hp-laptop", |
3073 | [CXT5066_AUTO] = "auto", | ||
3012 | }; | 3074 | }; |
3013 | 3075 | ||
3014 | static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | 3076 | static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { |
3015 | SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), | 3077 | SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), |
3016 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), | 3078 | SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), |
3017 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), | 3079 | SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), |
@@ -3036,7 +3098,9 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { | |||
3036 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), | 3098 | SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), |
3037 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), | 3099 | SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), |
3038 | 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), | ||
3039 | 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), | ||
3040 | 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 */ |
3041 | {} | 3105 | {} |
3042 | }; | 3106 | }; |
@@ -3046,6 +3110,15 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3046 | struct conexant_spec *spec; | 3110 | struct conexant_spec *spec; |
3047 | int board_config; | 3111 | int board_config; |
3048 | 3112 | ||
3113 | board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, | ||
3114 | cxt5066_models, cxt5066_cfg_tbl); | ||
3115 | #if 0 /* use the old method just for safety */ | ||
3116 | if (board_config < 0) | ||
3117 | board_config = CXT5066_AUTO; | ||
3118 | #endif | ||
3119 | if (board_config == CXT5066_AUTO) | ||
3120 | return patch_conexant_auto(codec); | ||
3121 | |||
3049 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 3122 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
3050 | if (!spec) | 3123 | if (!spec) |
3051 | return -ENOMEM; | 3124 | return -ENOMEM; |
@@ -3076,8 +3149,6 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3076 | 3149 | ||
3077 | set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); | 3150 | set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); |
3078 | 3151 | ||
3079 | board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, | ||
3080 | cxt5066_models, cxt5066_cfg_tbl); | ||
3081 | switch (board_config) { | 3152 | switch (board_config) { |
3082 | default: | 3153 | default: |
3083 | case CXT5066_LAPTOP: | 3154 | case CXT5066_LAPTOP: |
@@ -3195,7 +3266,45 @@ static int patch_cxt5066(struct hda_codec *codec) | |||
3195 | * Automatic parser for CX20641 & co | 3266 | * Automatic parser for CX20641 & co |
3196 | */ | 3267 | */ |
3197 | 3268 | ||
3198 | static hda_nid_t cx_auto_adc_nids[] = { 0x14 }; | 3269 | static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo, |
3270 | struct hda_codec *codec, | ||
3271 | unsigned int stream_tag, | ||
3272 | unsigned int format, | ||
3273 | struct snd_pcm_substream *substream) | ||
3274 | { | ||
3275 | struct conexant_spec *spec = codec->spec; | ||
3276 | hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc; | ||
3277 | if (spec->adc_switching) { | ||
3278 | spec->cur_adc = adc; | ||
3279 | spec->cur_adc_stream_tag = stream_tag; | ||
3280 | spec->cur_adc_format = format; | ||
3281 | } | ||
3282 | snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format); | ||
3283 | return 0; | ||
3284 | } | ||
3285 | |||
3286 | static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | ||
3287 | struct hda_codec *codec, | ||
3288 | struct snd_pcm_substream *substream) | ||
3289 | { | ||
3290 | struct conexant_spec *spec = codec->spec; | ||
3291 | snd_hda_codec_cleanup_stream(codec, spec->cur_adc); | ||
3292 | spec->cur_adc = 0; | ||
3293 | return 0; | ||
3294 | } | ||
3295 | |||
3296 | static const struct hda_pcm_stream cx_auto_pcm_analog_capture = { | ||
3297 | .substreams = 1, | ||
3298 | .channels_min = 2, | ||
3299 | .channels_max = 2, | ||
3300 | .nid = 0, /* fill later */ | ||
3301 | .ops = { | ||
3302 | .prepare = cx_auto_capture_pcm_prepare, | ||
3303 | .cleanup = cx_auto_capture_pcm_cleanup | ||
3304 | }, | ||
3305 | }; | ||
3306 | |||
3307 | static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; | ||
3199 | 3308 | ||
3200 | /* get the connection index of @nid in the widget @mux */ | 3309 | /* get the connection index of @nid in the widget @mux */ |
3201 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | 3310 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, |
@@ -3320,61 +3429,349 @@ static void cx_auto_parse_output(struct hda_codec *codec) | |||
3320 | spec->multiout.dac_nids = spec->private_dac_nids; | 3429 | spec->multiout.dac_nids = spec->private_dac_nids; |
3321 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; | 3430 | spec->multiout.max_channels = spec->multiout.num_dacs * 2; |
3322 | 3431 | ||
3323 | if (cfg->hp_outs > 0) | 3432 | for (i = 0; i < cfg->hp_outs; i++) { |
3324 | spec->auto_mute = 1; | 3433 | if (is_jack_detectable(codec, cfg->hp_pins[i])) { |
3434 | spec->auto_mute = 1; | ||
3435 | break; | ||
3436 | } | ||
3437 | } | ||
3438 | if (spec->auto_mute && | ||
3439 | cfg->line_out_pins[0] && | ||
3440 | cfg->line_out_type != AUTO_PIN_SPEAKER_OUT && | ||
3441 | cfg->line_out_pins[0] != cfg->hp_pins[0] && | ||
3442 | cfg->line_out_pins[0] != cfg->speaker_pins[0]) { | ||
3443 | for (i = 0; i < cfg->line_outs; i++) { | ||
3444 | if (is_jack_detectable(codec, cfg->line_out_pins[i])) { | ||
3445 | spec->detect_line = 1; | ||
3446 | break; | ||
3447 | } | ||
3448 | } | ||
3449 | spec->automute_lines = spec->detect_line; | ||
3450 | } | ||
3451 | |||
3325 | spec->vmaster_nid = spec->private_dac_nids[0]; | 3452 | spec->vmaster_nid = spec->private_dac_nids[0]; |
3326 | } | 3453 | } |
3327 | 3454 | ||
3455 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, | ||
3456 | hda_nid_t *pins, bool on); | ||
3457 | |||
3458 | static void do_automute(struct hda_codec *codec, int num_pins, | ||
3459 | hda_nid_t *pins, bool on) | ||
3460 | { | ||
3461 | int i; | ||
3462 | for (i = 0; i < num_pins; i++) | ||
3463 | snd_hda_codec_write(codec, pins[i], 0, | ||
3464 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
3465 | on ? PIN_OUT : 0); | ||
3466 | cx_auto_turn_eapd(codec, num_pins, pins, on); | ||
3467 | } | ||
3468 | |||
3469 | static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) | ||
3470 | { | ||
3471 | int i, present = 0; | ||
3472 | |||
3473 | for (i = 0; i < num_pins; i++) { | ||
3474 | hda_nid_t nid = pins[i]; | ||
3475 | if (!nid || !is_jack_detectable(codec, nid)) | ||
3476 | break; | ||
3477 | snd_hda_input_jack_report(codec, nid); | ||
3478 | present |= snd_hda_jack_detect(codec, nid); | ||
3479 | } | ||
3480 | return present; | ||
3481 | } | ||
3482 | |||
3328 | /* auto-mute/unmute speaker and line outs according to headphone jack */ | 3483 | /* auto-mute/unmute speaker and line outs according to headphone jack */ |
3484 | static void cx_auto_update_speakers(struct hda_codec *codec) | ||
3485 | { | ||
3486 | struct conexant_spec *spec = codec->spec; | ||
3487 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3488 | int on = 1; | ||
3489 | |||
3490 | /* turn on HP EAPD when HP jacks are present */ | ||
3491 | if (spec->auto_mute) | ||
3492 | on = spec->hp_present; | ||
3493 | cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_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); | ||
3499 | |||
3500 | /* toggle line-out mutes if needed, too */ | ||
3501 | /* if LO is a copy of either HP or Speaker, don't need to handle it */ | ||
3502 | if (cfg->line_out_pins[0] == cfg->hp_pins[0] || | ||
3503 | cfg->line_out_pins[0] == cfg->speaker_pins[0]) | ||
3504 | return; | ||
3505 | if (spec->auto_mute) { | ||
3506 | /* mute LO in auto-mode when HP jack is present */ | ||
3507 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT || | ||
3508 | spec->automute_lines) | ||
3509 | on = !spec->hp_present; | ||
3510 | else | ||
3511 | on = 1; | ||
3512 | } | ||
3513 | do_automute(codec, cfg->line_outs, cfg->line_out_pins, on); | ||
3514 | } | ||
3515 | |||
3329 | static void cx_auto_hp_automute(struct hda_codec *codec) | 3516 | static void cx_auto_hp_automute(struct hda_codec *codec) |
3330 | { | 3517 | { |
3331 | struct conexant_spec *spec = codec->spec; | 3518 | struct conexant_spec *spec = codec->spec; |
3332 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3519 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3333 | int i, present; | ||
3334 | 3520 | ||
3335 | if (!spec->auto_mute) | 3521 | if (!spec->auto_mute) |
3336 | return; | 3522 | return; |
3337 | present = 0; | 3523 | spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins); |
3338 | for (i = 0; i < cfg->hp_outs; i++) { | 3524 | cx_auto_update_speakers(codec); |
3339 | if (snd_hda_jack_detect(codec, cfg->hp_pins[i])) { | 3525 | } |
3340 | present = 1; | 3526 | |
3341 | break; | 3527 | static void cx_auto_line_automute(struct hda_codec *codec) |
3342 | } | 3528 | { |
3529 | struct conexant_spec *spec = codec->spec; | ||
3530 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3531 | |||
3532 | if (!spec->auto_mute || !spec->detect_line) | ||
3533 | return; | ||
3534 | spec->line_present = detect_jacks(codec, cfg->line_outs, | ||
3535 | cfg->line_out_pins); | ||
3536 | cx_auto_update_speakers(codec); | ||
3537 | } | ||
3538 | |||
3539 | static int cx_automute_mode_info(struct snd_kcontrol *kcontrol, | ||
3540 | struct snd_ctl_elem_info *uinfo) | ||
3541 | { | ||
3542 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3543 | struct conexant_spec *spec = codec->spec; | ||
3544 | static const char * const texts2[] = { | ||
3545 | "Disabled", "Enabled" | ||
3546 | }; | ||
3547 | static const char * const texts3[] = { | ||
3548 | "Disabled", "Speaker Only", "Line-Out+Speaker" | ||
3549 | }; | ||
3550 | const char * const *texts; | ||
3551 | |||
3552 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
3553 | uinfo->count = 1; | ||
3554 | if (spec->automute_hp_lo) { | ||
3555 | uinfo->value.enumerated.items = 3; | ||
3556 | texts = texts3; | ||
3557 | } else { | ||
3558 | uinfo->value.enumerated.items = 2; | ||
3559 | texts = texts2; | ||
3343 | } | 3560 | } |
3344 | for (i = 0; i < cfg->line_outs; i++) { | 3561 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) |
3345 | snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, | 3562 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; |
3346 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 3563 | strcpy(uinfo->value.enumerated.name, |
3347 | present ? 0 : PIN_OUT); | 3564 | texts[uinfo->value.enumerated.item]); |
3565 | return 0; | ||
3566 | } | ||
3567 | |||
3568 | static int cx_automute_mode_get(struct snd_kcontrol *kcontrol, | ||
3569 | struct snd_ctl_elem_value *ucontrol) | ||
3570 | { | ||
3571 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3572 | struct conexant_spec *spec = codec->spec; | ||
3573 | unsigned int val; | ||
3574 | if (!spec->auto_mute) | ||
3575 | val = 0; | ||
3576 | else if (!spec->automute_lines) | ||
3577 | val = 1; | ||
3578 | else | ||
3579 | val = 2; | ||
3580 | ucontrol->value.enumerated.item[0] = val; | ||
3581 | return 0; | ||
3582 | } | ||
3583 | |||
3584 | static int cx_automute_mode_put(struct snd_kcontrol *kcontrol, | ||
3585 | struct snd_ctl_elem_value *ucontrol) | ||
3586 | { | ||
3587 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3588 | struct conexant_spec *spec = codec->spec; | ||
3589 | |||
3590 | switch (ucontrol->value.enumerated.item[0]) { | ||
3591 | case 0: | ||
3592 | if (!spec->auto_mute) | ||
3593 | return 0; | ||
3594 | spec->auto_mute = 0; | ||
3595 | break; | ||
3596 | case 1: | ||
3597 | if (spec->auto_mute && !spec->automute_lines) | ||
3598 | return 0; | ||
3599 | spec->auto_mute = 1; | ||
3600 | spec->automute_lines = 0; | ||
3601 | break; | ||
3602 | case 2: | ||
3603 | if (!spec->automute_hp_lo) | ||
3604 | return -EINVAL; | ||
3605 | if (spec->auto_mute && spec->automute_lines) | ||
3606 | return 0; | ||
3607 | spec->auto_mute = 1; | ||
3608 | spec->automute_lines = 1; | ||
3609 | break; | ||
3610 | default: | ||
3611 | return -EINVAL; | ||
3348 | } | 3612 | } |
3349 | for (i = 0; !present && i < cfg->line_outs; i++) | 3613 | cx_auto_update_speakers(codec); |
3350 | if (snd_hda_jack_detect(codec, cfg->line_out_pins[i])) | 3614 | return 1; |
3351 | present = 1; | 3615 | } |
3352 | for (i = 0; i < cfg->speaker_outs; i++) { | 3616 | |
3353 | snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, | 3617 | static const struct snd_kcontrol_new cx_automute_mode_enum[] = { |
3354 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 3618 | { |
3355 | present ? 0 : PIN_OUT); | 3619 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
3620 | .name = "Auto-Mute Mode", | ||
3621 | .info = cx_automute_mode_info, | ||
3622 | .get = cx_automute_mode_get, | ||
3623 | .put = cx_automute_mode_put, | ||
3624 | }, | ||
3625 | { } | ||
3626 | }; | ||
3627 | |||
3628 | static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol, | ||
3629 | struct snd_ctl_elem_info *uinfo) | ||
3630 | { | ||
3631 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3632 | struct conexant_spec *spec = codec->spec; | ||
3633 | |||
3634 | return snd_hda_input_mux_info(&spec->private_imux, uinfo); | ||
3635 | } | ||
3636 | |||
3637 | static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol, | ||
3638 | struct snd_ctl_elem_value *ucontrol) | ||
3639 | { | ||
3640 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3641 | struct conexant_spec *spec = codec->spec; | ||
3642 | |||
3643 | ucontrol->value.enumerated.item[0] = spec->cur_mux[0]; | ||
3644 | return 0; | ||
3645 | } | ||
3646 | |||
3647 | /* look for the route the given pin from mux and return the index; | ||
3648 | * if do_select is set, actually select the route. | ||
3649 | */ | ||
3650 | static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux, | ||
3651 | hda_nid_t pin, hda_nid_t *srcp, | ||
3652 | bool do_select, int depth) | ||
3653 | { | ||
3654 | hda_nid_t conn[HDA_MAX_NUM_INPUTS]; | ||
3655 | int i, nums; | ||
3656 | |||
3657 | switch (get_wcaps_type(get_wcaps(codec, mux))) { | ||
3658 | case AC_WID_AUD_IN: | ||
3659 | case AC_WID_AUD_SEL: | ||
3660 | case AC_WID_AUD_MIX: | ||
3661 | break; | ||
3662 | default: | ||
3663 | return -1; | ||
3664 | } | ||
3665 | |||
3666 | nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); | ||
3667 | for (i = 0; i < nums; i++) | ||
3668 | if (conn[i] == pin) { | ||
3669 | if (do_select) | ||
3670 | snd_hda_codec_write(codec, mux, 0, | ||
3671 | AC_VERB_SET_CONNECT_SEL, i); | ||
3672 | if (srcp) | ||
3673 | *srcp = mux; | ||
3674 | return i; | ||
3675 | } | ||
3676 | depth++; | ||
3677 | if (depth == 2) | ||
3678 | return -1; | ||
3679 | for (i = 0; i < nums; i++) { | ||
3680 | int ret = __select_input_connection(codec, conn[i], pin, srcp, | ||
3681 | do_select, depth); | ||
3682 | if (ret >= 0) { | ||
3683 | if (do_select) | ||
3684 | snd_hda_codec_write(codec, mux, 0, | ||
3685 | AC_VERB_SET_CONNECT_SEL, i); | ||
3686 | return i; | ||
3687 | } | ||
3356 | } | 3688 | } |
3689 | return -1; | ||
3690 | } | ||
3691 | |||
3692 | static void select_input_connection(struct hda_codec *codec, hda_nid_t mux, | ||
3693 | hda_nid_t pin) | ||
3694 | { | ||
3695 | __select_input_connection(codec, mux, pin, NULL, true, 0); | ||
3696 | } | ||
3697 | |||
3698 | static int get_input_connection(struct hda_codec *codec, hda_nid_t mux, | ||
3699 | hda_nid_t pin) | ||
3700 | { | ||
3701 | return __select_input_connection(codec, mux, pin, NULL, false, 0); | ||
3702 | } | ||
3703 | |||
3704 | static int cx_auto_mux_enum_update(struct hda_codec *codec, | ||
3705 | const struct hda_input_mux *imux, | ||
3706 | unsigned int idx) | ||
3707 | { | ||
3708 | struct conexant_spec *spec = codec->spec; | ||
3709 | hda_nid_t adc; | ||
3710 | int changed = 1; | ||
3711 | |||
3712 | if (!imux->num_items) | ||
3713 | return 0; | ||
3714 | if (idx >= imux->num_items) | ||
3715 | idx = imux->num_items - 1; | ||
3716 | if (spec->cur_mux[0] == idx) | ||
3717 | changed = 0; | ||
3718 | adc = spec->imux_info[idx].adc; | ||
3719 | select_input_connection(codec, spec->imux_info[idx].adc, | ||
3720 | spec->imux_info[idx].pin); | ||
3721 | if (spec->cur_adc && spec->cur_adc != adc) { | ||
3722 | /* stream is running, let's swap the current ADC */ | ||
3723 | __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); | ||
3724 | spec->cur_adc = adc; | ||
3725 | snd_hda_codec_setup_stream(codec, adc, | ||
3726 | spec->cur_adc_stream_tag, 0, | ||
3727 | spec->cur_adc_format); | ||
3728 | } | ||
3729 | spec->cur_mux[0] = idx; | ||
3730 | return changed; | ||
3731 | } | ||
3732 | |||
3733 | static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol, | ||
3734 | struct snd_ctl_elem_value *ucontrol) | ||
3735 | { | ||
3736 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
3737 | struct conexant_spec *spec = codec->spec; | ||
3738 | |||
3739 | return cx_auto_mux_enum_update(codec, &spec->private_imux, | ||
3740 | ucontrol->value.enumerated.item[0]); | ||
3741 | } | ||
3742 | |||
3743 | static const struct snd_kcontrol_new cx_auto_capture_mixers[] = { | ||
3744 | { | ||
3745 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
3746 | .name = "Capture Source", | ||
3747 | .info = cx_auto_mux_enum_info, | ||
3748 | .get = cx_auto_mux_enum_get, | ||
3749 | .put = cx_auto_mux_enum_put | ||
3750 | }, | ||
3751 | {} | ||
3752 | }; | ||
3753 | |||
3754 | static bool select_automic(struct hda_codec *codec, int idx, bool detect) | ||
3755 | { | ||
3756 | struct conexant_spec *spec = codec->spec; | ||
3757 | if (idx < 0) | ||
3758 | return false; | ||
3759 | if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin)) | ||
3760 | return false; | ||
3761 | cx_auto_mux_enum_update(codec, &spec->private_imux, idx); | ||
3762 | return true; | ||
3357 | } | 3763 | } |
3358 | 3764 | ||
3359 | /* automatic switch internal and external mic */ | 3765 | /* automatic switch internal and external mic */ |
3360 | static void cx_auto_automic(struct hda_codec *codec) | 3766 | static void cx_auto_automic(struct hda_codec *codec) |
3361 | { | 3767 | { |
3362 | struct conexant_spec *spec = codec->spec; | 3768 | struct conexant_spec *spec = codec->spec; |
3363 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
3364 | struct hda_input_mux *imux = &spec->private_imux; | ||
3365 | int ext_idx = spec->auto_mic_ext; | ||
3366 | 3769 | ||
3367 | if (!spec->auto_mic) | 3770 | if (!spec->auto_mic) |
3368 | return; | 3771 | return; |
3369 | if (snd_hda_jack_detect(codec, cfg->inputs[ext_idx].pin)) { | 3772 | if (!select_automic(codec, spec->auto_mic_ext, true)) |
3370 | snd_hda_codec_write(codec, spec->adc_nids[0], 0, | 3773 | if (!select_automic(codec, spec->auto_mic_dock, true)) |
3371 | AC_VERB_SET_CONNECT_SEL, | 3774 | select_automic(codec, spec->auto_mic_int, false); |
3372 | imux->items[ext_idx].index); | ||
3373 | } else { | ||
3374 | snd_hda_codec_write(codec, spec->adc_nids[0], 0, | ||
3375 | AC_VERB_SET_CONNECT_SEL, | ||
3376 | imux->items[!ext_idx].index); | ||
3377 | } | ||
3378 | } | 3775 | } |
3379 | 3776 | ||
3380 | static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) | 3777 | static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -3383,7 +3780,9 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) | |||
3383 | switch (res >> 26) { | 3780 | switch (res >> 26) { |
3384 | case CONEXANT_HP_EVENT: | 3781 | case CONEXANT_HP_EVENT: |
3385 | cx_auto_hp_automute(codec); | 3782 | cx_auto_hp_automute(codec); |
3386 | snd_hda_input_jack_report(codec, nid); | 3783 | break; |
3784 | case CONEXANT_LINE_EVENT: | ||
3785 | cx_auto_line_automute(codec); | ||
3387 | break; | 3786 | break; |
3388 | case CONEXANT_MIC_EVENT: | 3787 | case CONEXANT_MIC_EVENT: |
3389 | cx_auto_automic(codec); | 3788 | cx_auto_automic(codec); |
@@ -3392,43 +3791,45 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) | |||
3392 | } | 3791 | } |
3393 | } | 3792 | } |
3394 | 3793 | ||
3395 | /* return true if it's an internal-mic pin */ | ||
3396 | static int is_int_mic(struct hda_codec *codec, hda_nid_t pin) | ||
3397 | { | ||
3398 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin); | ||
3399 | return get_defcfg_device(def_conf) == AC_JACK_MIC_IN && | ||
3400 | snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT; | ||
3401 | } | ||
3402 | |||
3403 | /* return true if it's an external-mic pin */ | ||
3404 | static int is_ext_mic(struct hda_codec *codec, hda_nid_t pin) | ||
3405 | { | ||
3406 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin); | ||
3407 | return get_defcfg_device(def_conf) == AC_JACK_MIC_IN && | ||
3408 | snd_hda_get_input_pin_attr(def_conf) >= INPUT_PIN_ATTR_NORMAL && | ||
3409 | (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_PRES_DETECT); | ||
3410 | } | ||
3411 | |||
3412 | /* check whether the pin config is suitable for auto-mic switching; | 3794 | /* check whether the pin config is suitable for auto-mic switching; |
3413 | * auto-mic is enabled only when one int-mic and one-ext mic exist | 3795 | * auto-mic is enabled only when one int-mic and one ext- and/or |
3796 | * one dock-mic exist | ||
3414 | */ | 3797 | */ |
3415 | static void cx_auto_check_auto_mic(struct hda_codec *codec) | 3798 | static void cx_auto_check_auto_mic(struct hda_codec *codec) |
3416 | { | 3799 | { |
3417 | struct conexant_spec *spec = codec->spec; | 3800 | struct conexant_spec *spec = codec->spec; |
3418 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3801 | int pset[INPUT_PIN_ATTR_NORMAL + 1]; |
3802 | int i; | ||
3419 | 3803 | ||
3420 | if (is_ext_mic(codec, cfg->inputs[0].pin) && | 3804 | for (i = 0; i < ARRAY_SIZE(pset); i++) |
3421 | is_int_mic(codec, cfg->inputs[1].pin)) { | 3805 | pset[i] = -1; |
3422 | spec->auto_mic = 1; | 3806 | for (i = 0; i < spec->private_imux.num_items; i++) { |
3423 | spec->auto_mic_ext = 1; | 3807 | hda_nid_t pin = spec->imux_info[i].pin; |
3424 | return; | 3808 | unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin); |
3425 | } | 3809 | int type, attr; |
3426 | if (is_int_mic(codec, cfg->inputs[1].pin) && | 3810 | attr = snd_hda_get_input_pin_attr(def_conf); |
3427 | is_ext_mic(codec, cfg->inputs[0].pin)) { | 3811 | if (attr == INPUT_PIN_ATTR_UNUSED) |
3428 | spec->auto_mic = 1; | 3812 | return; /* invalid entry */ |
3429 | spec->auto_mic_ext = 0; | 3813 | if (attr > INPUT_PIN_ATTR_NORMAL) |
3430 | return; | 3814 | attr = INPUT_PIN_ATTR_NORMAL; |
3815 | if (attr != INPUT_PIN_ATTR_INT && | ||
3816 | !is_jack_detectable(codec, pin)) | ||
3817 | return; /* non-detectable pin */ | ||
3818 | type = get_defcfg_device(def_conf); | ||
3819 | if (type != AC_JACK_MIC_IN && | ||
3820 | (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN)) | ||
3821 | return; /* no valid input type */ | ||
3822 | if (pset[attr] >= 0) | ||
3823 | return; /* already occupied */ | ||
3824 | pset[attr] = i; | ||
3431 | } | 3825 | } |
3826 | if (pset[INPUT_PIN_ATTR_INT] < 0 || | ||
3827 | (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK])) | ||
3828 | return; /* no input to switch*/ | ||
3829 | spec->auto_mic = 1; | ||
3830 | spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL]; | ||
3831 | spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK]; | ||
3832 | spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT]; | ||
3432 | } | 3833 | } |
3433 | 3834 | ||
3434 | static void cx_auto_parse_input(struct hda_codec *codec) | 3835 | static void cx_auto_parse_input(struct hda_codec *codec) |
@@ -3436,22 +3837,37 @@ static void cx_auto_parse_input(struct hda_codec *codec) | |||
3436 | struct conexant_spec *spec = codec->spec; | 3837 | struct conexant_spec *spec = codec->spec; |
3437 | struct auto_pin_cfg *cfg = &spec->autocfg; | 3838 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3438 | struct hda_input_mux *imux; | 3839 | struct hda_input_mux *imux; |
3439 | int i; | 3840 | int i, j; |
3440 | 3841 | ||
3441 | imux = &spec->private_imux; | 3842 | imux = &spec->private_imux; |
3442 | for (i = 0; i < cfg->num_inputs; i++) { | 3843 | for (i = 0; i < cfg->num_inputs; i++) { |
3443 | int idx = get_connection_index(codec, spec->adc_nids[0], | 3844 | for (j = 0; j < spec->num_adc_nids; j++) { |
3444 | cfg->inputs[i].pin); | 3845 | hda_nid_t adc = spec->adc_nids[j]; |
3445 | if (idx >= 0) { | 3846 | int idx = get_input_connection(codec, adc, |
3446 | const char *label; | 3847 | cfg->inputs[i].pin); |
3447 | label = hda_get_autocfg_input_label(codec, cfg, i); | 3848 | if (idx >= 0) { |
3448 | snd_hda_add_imux_item(imux, label, idx, NULL); | 3849 | const char *label; |
3850 | label = hda_get_autocfg_input_label(codec, cfg, i); | ||
3851 | spec->imux_info[imux->num_items].index = i; | ||
3852 | spec->imux_info[imux->num_items].boost = 0; | ||
3853 | spec->imux_info[imux->num_items].adc = adc; | ||
3854 | spec->imux_info[imux->num_items].pin = | ||
3855 | cfg->inputs[i].pin; | ||
3856 | snd_hda_add_imux_item(imux, label, idx, NULL); | ||
3857 | break; | ||
3858 | } | ||
3449 | } | 3859 | } |
3450 | } | 3860 | } |
3451 | if (imux->num_items == 2 && cfg->num_inputs == 2) | 3861 | if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items) |
3452 | cx_auto_check_auto_mic(codec); | 3862 | cx_auto_check_auto_mic(codec); |
3453 | if (imux->num_items > 1 && !spec->auto_mic) | 3863 | if (imux->num_items > 1 && !spec->auto_mic) { |
3454 | spec->input_mux = imux; | 3864 | for (i = 1; i < imux->num_items; i++) { |
3865 | if (spec->imux_info[i].adc != spec->imux_info[0].adc) { | ||
3866 | spec->adc_switching = 1; | ||
3867 | break; | ||
3868 | } | ||
3869 | } | ||
3870 | } | ||
3455 | } | 3871 | } |
3456 | 3872 | ||
3457 | /* get digital-input audio widget corresponding to the given pin */ | 3873 | /* get digital-input audio widget corresponding to the given pin */ |
@@ -3517,14 +3933,15 @@ static int cx_auto_parse_auto_config(struct hda_codec *codec) | |||
3517 | return 0; | 3933 | return 0; |
3518 | } | 3934 | } |
3519 | 3935 | ||
3520 | static void cx_auto_turn_on_eapd(struct hda_codec *codec, int num_pins, | 3936 | static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, |
3521 | hda_nid_t *pins) | 3937 | hda_nid_t *pins, bool on) |
3522 | { | 3938 | { |
3523 | int i; | 3939 | int i; |
3524 | for (i = 0; i < num_pins; i++) { | 3940 | for (i = 0; i < num_pins; i++) { |
3525 | if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD) | 3941 | if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD) |
3526 | snd_hda_codec_write(codec, pins[i], 0, | 3942 | snd_hda_codec_write(codec, pins[i], 0, |
3527 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | 3943 | AC_VERB_SET_EAPD_BTLENABLE, |
3944 | on ? 0x02 : 0); | ||
3528 | } | 3945 | } |
3529 | } | 3946 | } |
3530 | 3947 | ||
@@ -3537,6 +3954,34 @@ static void select_connection(struct hda_codec *codec, hda_nid_t pin, | |||
3537 | AC_VERB_SET_CONNECT_SEL, idx); | 3954 | AC_VERB_SET_CONNECT_SEL, idx); |
3538 | } | 3955 | } |
3539 | 3956 | ||
3957 | static void mute_outputs(struct hda_codec *codec, int num_nids, | ||
3958 | const hda_nid_t *nids) | ||
3959 | { | ||
3960 | int i, val; | ||
3961 | |||
3962 | for (i = 0; i < num_nids; i++) { | ||
3963 | hda_nid_t nid = nids[i]; | ||
3964 | if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) | ||
3965 | continue; | ||
3966 | if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE) | ||
3967 | val = AMP_OUT_MUTE; | ||
3968 | else | ||
3969 | val = AMP_OUT_ZERO; | ||
3970 | snd_hda_codec_write(codec, nid, 0, | ||
3971 | AC_VERB_SET_AMP_GAIN_MUTE, val); | ||
3972 | } | ||
3973 | } | ||
3974 | |||
3975 | static void enable_unsol_pins(struct hda_codec *codec, int num_pins, | ||
3976 | hda_nid_t *pins, unsigned int tag) | ||
3977 | { | ||
3978 | int i; | ||
3979 | for (i = 0; i < num_pins; i++) | ||
3980 | snd_hda_codec_write(codec, pins[i], 0, | ||
3981 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
3982 | AC_USRSP_EN | tag); | ||
3983 | } | ||
3984 | |||
3540 | static void cx_auto_init_output(struct hda_codec *codec) | 3985 | static void cx_auto_init_output(struct hda_codec *codec) |
3541 | { | 3986 | { |
3542 | struct conexant_spec *spec = codec->spec; | 3987 | struct conexant_spec *spec = codec->spec; |
@@ -3544,51 +3989,53 @@ static void cx_auto_init_output(struct hda_codec *codec) | |||
3544 | hda_nid_t nid; | 3989 | hda_nid_t nid; |
3545 | int i; | 3990 | int i; |
3546 | 3991 | ||
3547 | for (i = 0; i < spec->multiout.num_dacs; i++) | 3992 | mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids); |
3548 | snd_hda_codec_write(codec, spec->multiout.dac_nids[i], 0, | ||
3549 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); | ||
3550 | |||
3551 | for (i = 0; i < cfg->hp_outs; i++) | 3993 | for (i = 0; i < cfg->hp_outs; i++) |
3552 | snd_hda_codec_write(codec, cfg->hp_pins[i], 0, | 3994 | snd_hda_codec_write(codec, cfg->hp_pins[i], 0, |
3553 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); | 3995 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); |
3554 | if (spec->auto_mute) { | 3996 | mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); |
3555 | for (i = 0; i < cfg->hp_outs; i++) { | 3997 | mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); |
3556 | snd_hda_codec_write(codec, cfg->hp_pins[i], 0, | 3998 | mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins); |
3557 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
3558 | AC_USRSP_EN | CONEXANT_HP_EVENT); | ||
3559 | } | ||
3560 | cx_auto_hp_automute(codec); | ||
3561 | } else { | ||
3562 | for (i = 0; i < cfg->line_outs; i++) | ||
3563 | snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, | ||
3564 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
3565 | for (i = 0; i < cfg->speaker_outs; i++) | ||
3566 | snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, | ||
3567 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
3568 | } | ||
3569 | |||
3570 | for (i = 0; i < spec->dac_info_filled; i++) { | 3999 | for (i = 0; i < spec->dac_info_filled; i++) { |
3571 | nid = spec->dac_info[i].dac; | 4000 | nid = spec->dac_info[i].dac; |
3572 | if (!nid) | 4001 | if (!nid) |
3573 | nid = spec->multiout.dac_nids[0]; | 4002 | nid = spec->multiout.dac_nids[0]; |
3574 | select_connection(codec, spec->dac_info[i].pin, nid); | 4003 | select_connection(codec, spec->dac_info[i].pin, nid); |
3575 | } | 4004 | } |
3576 | 4005 | if (spec->auto_mute) { | |
3577 | /* turn on EAPD */ | 4006 | enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins, |
3578 | cx_auto_turn_on_eapd(codec, cfg->line_outs, cfg->line_out_pins); | 4007 | CONEXANT_HP_EVENT); |
3579 | cx_auto_turn_on_eapd(codec, cfg->hp_outs, cfg->hp_pins); | 4008 | spec->hp_present = detect_jacks(codec, cfg->hp_outs, |
3580 | cx_auto_turn_on_eapd(codec, cfg->speaker_outs, cfg->speaker_pins); | 4009 | cfg->hp_pins); |
4010 | if (spec->detect_line) { | ||
4011 | enable_unsol_pins(codec, cfg->line_outs, | ||
4012 | cfg->line_out_pins, | ||
4013 | CONEXANT_LINE_EVENT); | ||
4014 | spec->line_present = | ||
4015 | detect_jacks(codec, cfg->line_outs, | ||
4016 | cfg->line_out_pins); | ||
4017 | } | ||
4018 | } | ||
4019 | cx_auto_update_speakers(codec); | ||
3581 | } | 4020 | } |
3582 | 4021 | ||
3583 | static void cx_auto_init_input(struct hda_codec *codec) | 4022 | static void cx_auto_init_input(struct hda_codec *codec) |
3584 | { | 4023 | { |
3585 | struct conexant_spec *spec = codec->spec; | 4024 | struct conexant_spec *spec = codec->spec; |
3586 | struct auto_pin_cfg *cfg = &spec->autocfg; | 4025 | struct auto_pin_cfg *cfg = &spec->autocfg; |
3587 | int i; | 4026 | int i, val; |
3588 | 4027 | ||
3589 | for (i = 0; i < spec->num_adc_nids; i++) | 4028 | for (i = 0; i < spec->num_adc_nids; i++) { |
3590 | snd_hda_codec_write(codec, spec->adc_nids[i], 0, | 4029 | hda_nid_t nid = spec->adc_nids[i]; |
3591 | AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)); | 4030 | if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) |
4031 | continue; | ||
4032 | if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) | ||
4033 | val = AMP_IN_MUTE(0); | ||
4034 | else | ||
4035 | val = AMP_IN_UNMUTE(0); | ||
4036 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | ||
4037 | val); | ||
4038 | } | ||
3592 | 4039 | ||
3593 | for (i = 0; i < cfg->num_inputs; i++) { | 4040 | for (i = 0; i < cfg->num_inputs; i++) { |
3594 | unsigned int type; | 4041 | unsigned int type; |
@@ -3601,17 +4048,22 @@ static void cx_auto_init_input(struct hda_codec *codec) | |||
3601 | } | 4048 | } |
3602 | 4049 | ||
3603 | if (spec->auto_mic) { | 4050 | if (spec->auto_mic) { |
3604 | int ext_idx = spec->auto_mic_ext; | 4051 | if (spec->auto_mic_ext >= 0) { |
3605 | snd_hda_codec_write(codec, cfg->inputs[ext_idx].pin, 0, | 4052 | snd_hda_codec_write(codec, |
3606 | AC_VERB_SET_UNSOLICITED_ENABLE, | 4053 | cfg->inputs[spec->auto_mic_ext].pin, 0, |
3607 | AC_USRSP_EN | CONEXANT_MIC_EVENT); | 4054 | AC_VERB_SET_UNSOLICITED_ENABLE, |
4055 | AC_USRSP_EN | CONEXANT_MIC_EVENT); | ||
4056 | } | ||
4057 | if (spec->auto_mic_dock >= 0) { | ||
4058 | snd_hda_codec_write(codec, | ||
4059 | cfg->inputs[spec->auto_mic_dock].pin, 0, | ||
4060 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
4061 | AC_USRSP_EN | CONEXANT_MIC_EVENT); | ||
4062 | } | ||
3608 | cx_auto_automic(codec); | 4063 | cx_auto_automic(codec); |
3609 | } else { | 4064 | } else { |
3610 | for (i = 0; i < spec->num_adc_nids; i++) { | 4065 | select_input_connection(codec, spec->imux_info[0].adc, |
3611 | snd_hda_codec_write(codec, spec->adc_nids[i], 0, | 4066 | spec->imux_info[0].pin); |
3612 | AC_VERB_SET_CONNECT_SEL, | ||
3613 | spec->private_imux.items[0].index); | ||
3614 | } | ||
3615 | } | 4067 | } |
3616 | } | 4068 | } |
3617 | 4069 | ||
@@ -3646,7 +4098,7 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, | |||
3646 | HDA_CODEC_VOLUME(name, 0, 0, 0), | 4098 | HDA_CODEC_VOLUME(name, 0, 0, 0), |
3647 | HDA_CODEC_MUTE(name, 0, 0, 0), | 4099 | HDA_CODEC_MUTE(name, 0, 0, 0), |
3648 | }; | 4100 | }; |
3649 | static char *sfx[2] = { "Volume", "Switch" }; | 4101 | static const char * const sfx[2] = { "Volume", "Switch" }; |
3650 | int i, err; | 4102 | int i, err; |
3651 | 4103 | ||
3652 | for (i = 0; i < 2; i++) { | 4104 | for (i = 0; i < 2; i++) { |
@@ -3674,6 +4126,19 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, | |||
3674 | #define cx_auto_add_pb_volume(codec, nid, str, idx) \ | 4126 | #define cx_auto_add_pb_volume(codec, nid, str, idx) \ |
3675 | cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) | 4127 | cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) |
3676 | 4128 | ||
4129 | static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac, | ||
4130 | hda_nid_t pin, const char *name, int idx) | ||
4131 | { | ||
4132 | unsigned int caps; | ||
4133 | caps = query_amp_caps(codec, dac, HDA_OUTPUT); | ||
4134 | if (caps & AC_AMPCAP_NUM_STEPS) | ||
4135 | return cx_auto_add_pb_volume(codec, dac, name, idx); | ||
4136 | caps = query_amp_caps(codec, pin, HDA_OUTPUT); | ||
4137 | if (caps & AC_AMPCAP_NUM_STEPS) | ||
4138 | return cx_auto_add_pb_volume(codec, pin, name, idx); | ||
4139 | return 0; | ||
4140 | } | ||
4141 | |||
3677 | static int cx_auto_build_output_controls(struct hda_codec *codec) | 4142 | static int cx_auto_build_output_controls(struct hda_codec *codec) |
3678 | { | 4143 | { |
3679 | struct conexant_spec *spec = codec->spec; | 4144 | struct conexant_spec *spec = codec->spec; |
@@ -3682,8 +4147,10 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) | |||
3682 | static const char * const texts[3] = { "Front", "Surround", "CLFE" }; | 4147 | static const char * const texts[3] = { "Front", "Surround", "CLFE" }; |
3683 | 4148 | ||
3684 | if (spec->dac_info_filled == 1) | 4149 | if (spec->dac_info_filled == 1) |
3685 | return cx_auto_add_pb_volume(codec, spec->dac_info[0].dac, | 4150 | return try_add_pb_volume(codec, spec->dac_info[0].dac, |
3686 | "Master", 0); | 4151 | spec->dac_info[0].pin, |
4152 | "Master", 0); | ||
4153 | |||
3687 | for (i = 0; i < spec->dac_info_filled; i++) { | 4154 | for (i = 0; i < spec->dac_info_filled; i++) { |
3688 | const char *label; | 4155 | const char *label; |
3689 | int idx, type; | 4156 | int idx, type; |
@@ -3707,74 +4174,123 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) | |||
3707 | idx = num_spk++; | 4174 | idx = num_spk++; |
3708 | break; | 4175 | break; |
3709 | } | 4176 | } |
3710 | err = cx_auto_add_pb_volume(codec, spec->dac_info[i].dac, | 4177 | err = try_add_pb_volume(codec, spec->dac_info[i].dac, |
3711 | label, idx); | 4178 | spec->dac_info[i].pin, |
4179 | label, idx); | ||
3712 | if (err < 0) | 4180 | if (err < 0) |
3713 | return err; | 4181 | return err; |
3714 | } | 4182 | } |
4183 | |||
4184 | if (spec->auto_mute) { | ||
4185 | err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum); | ||
4186 | if (err < 0) | ||
4187 | return err; | ||
4188 | } | ||
4189 | |||
4190 | return 0; | ||
4191 | } | ||
4192 | |||
4193 | static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid, | ||
4194 | const char *label, const char *pfx, | ||
4195 | int cidx) | ||
4196 | { | ||
4197 | struct conexant_spec *spec = codec->spec; | ||
4198 | int i; | ||
4199 | |||
4200 | for (i = 0; i < spec->num_adc_nids; i++) { | ||
4201 | hda_nid_t adc_nid = spec->adc_nids[i]; | ||
4202 | int idx = get_input_connection(codec, adc_nid, nid); | ||
4203 | if (idx < 0) | ||
4204 | continue; | ||
4205 | return cx_auto_add_volume_idx(codec, label, pfx, | ||
4206 | cidx, adc_nid, HDA_INPUT, idx); | ||
4207 | } | ||
4208 | return 0; | ||
4209 | } | ||
4210 | |||
4211 | static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx, | ||
4212 | const char *label, int cidx) | ||
4213 | { | ||
4214 | struct conexant_spec *spec = codec->spec; | ||
4215 | hda_nid_t mux, nid; | ||
4216 | int i, con; | ||
4217 | |||
4218 | nid = spec->imux_info[idx].pin; | ||
4219 | if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) | ||
4220 | return cx_auto_add_volume(codec, label, " Boost", cidx, | ||
4221 | nid, HDA_INPUT); | ||
4222 | con = __select_input_connection(codec, spec->imux_info[idx].adc, nid, | ||
4223 | &mux, false, 0); | ||
4224 | if (con < 0) | ||
4225 | return 0; | ||
4226 | for (i = 0; i < idx; i++) { | ||
4227 | if (spec->imux_info[i].boost == mux) | ||
4228 | return 0; /* already present */ | ||
4229 | } | ||
4230 | |||
4231 | if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) { | ||
4232 | spec->imux_info[idx].boost = mux; | ||
4233 | return cx_auto_add_volume(codec, label, " Boost", 0, | ||
4234 | mux, HDA_OUTPUT); | ||
4235 | } | ||
3715 | return 0; | 4236 | return 0; |
3716 | } | 4237 | } |
3717 | 4238 | ||
3718 | static int cx_auto_build_input_controls(struct hda_codec *codec) | 4239 | static int cx_auto_build_input_controls(struct hda_codec *codec) |
3719 | { | 4240 | { |
3720 | struct conexant_spec *spec = codec->spec; | 4241 | struct conexant_spec *spec = codec->spec; |
3721 | struct auto_pin_cfg *cfg = &spec->autocfg; | 4242 | struct hda_input_mux *imux = &spec->private_imux; |
3722 | static const char *prev_label; | 4243 | const char *prev_label; |
3723 | int i, err, cidx, conn_len; | 4244 | int input_conn[HDA_MAX_NUM_INPUTS]; |
3724 | hda_nid_t conn[HDA_MAX_CONNECTIONS]; | 4245 | int i, err, cidx; |
3725 | 4246 | int multi_connection; | |
3726 | int multi_adc_volume = 0; /* If the ADC nid has several input volumes */ | 4247 | |
3727 | int adc_nid = spec->adc_nids[0]; | 4248 | multi_connection = 0; |
3728 | 4249 | for (i = 0; i < imux->num_items; i++) { | |
3729 | conn_len = snd_hda_get_connections(codec, adc_nid, conn, | 4250 | cidx = get_input_connection(codec, spec->imux_info[i].adc, |
3730 | HDA_MAX_CONNECTIONS); | 4251 | spec->imux_info[i].pin); |
3731 | if (conn_len < 0) | 4252 | input_conn[i] = (spec->imux_info[i].adc << 8) | cidx; |
3732 | return conn_len; | 4253 | if (i > 0 && input_conn[i] != input_conn[0]) |
3733 | 4254 | multi_connection = 1; | |
3734 | multi_adc_volume = cfg->num_inputs > 1 && conn_len > 1; | ||
3735 | if (!multi_adc_volume) { | ||
3736 | err = cx_auto_add_volume(codec, "Capture", "", 0, adc_nid, | ||
3737 | HDA_INPUT); | ||
3738 | if (err < 0) | ||
3739 | return err; | ||
3740 | } | 4255 | } |
3741 | 4256 | ||
3742 | prev_label = NULL; | 4257 | prev_label = NULL; |
3743 | cidx = 0; | 4258 | cidx = 0; |
3744 | for (i = 0; i < cfg->num_inputs; i++) { | 4259 | for (i = 0; i < imux->num_items; i++) { |
3745 | hda_nid_t nid = cfg->inputs[i].pin; | 4260 | hda_nid_t nid = spec->imux_info[i].pin; |
3746 | const char *label; | 4261 | const char *label; |
3747 | int j; | ||
3748 | int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP; | ||
3749 | if (!pin_amp && !multi_adc_volume) | ||
3750 | continue; | ||
3751 | 4262 | ||
3752 | label = hda_get_autocfg_input_label(codec, cfg, i); | 4263 | label = hda_get_autocfg_input_label(codec, &spec->autocfg, |
4264 | spec->imux_info[i].index); | ||
3753 | if (label == prev_label) | 4265 | if (label == prev_label) |
3754 | cidx++; | 4266 | cidx++; |
3755 | else | 4267 | else |
3756 | cidx = 0; | 4268 | cidx = 0; |
3757 | prev_label = label; | 4269 | prev_label = label; |
3758 | 4270 | ||
3759 | if (pin_amp) { | 4271 | err = cx_auto_add_boost_volume(codec, i, label, cidx); |
3760 | err = cx_auto_add_volume(codec, label, " Boost", cidx, | 4272 | if (err < 0) |
3761 | nid, HDA_INPUT); | 4273 | return err; |
3762 | if (err < 0) | ||
3763 | return err; | ||
3764 | } | ||
3765 | 4274 | ||
3766 | if (!multi_adc_volume) | 4275 | if (!multi_connection) { |
3767 | continue; | 4276 | if (i > 0) |
3768 | for (j = 0; j < conn_len; j++) { | 4277 | continue; |
3769 | if (conn[j] == nid) { | 4278 | err = cx_auto_add_capture_volume(codec, nid, |
3770 | err = cx_auto_add_volume_idx(codec, label, | 4279 | "Capture", "", cidx); |
3771 | " Capture", cidx, adc_nid, HDA_INPUT, j); | 4280 | } else { |
3772 | if (err < 0) | 4281 | err = cx_auto_add_capture_volume(codec, nid, |
3773 | return err; | 4282 | label, " Capture", cidx); |
3774 | break; | ||
3775 | } | ||
3776 | } | 4283 | } |
4284 | if (err < 0) | ||
4285 | return err; | ||
4286 | } | ||
4287 | |||
4288 | if (spec->private_imux.num_items > 1 && !spec->auto_mic) { | ||
4289 | err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers); | ||
4290 | if (err < 0) | ||
4291 | return err; | ||
3777 | } | 4292 | } |
4293 | |||
3778 | return 0; | 4294 | return 0; |
3779 | } | 4295 | } |
3780 | 4296 | ||
@@ -3791,7 +4307,29 @@ static int cx_auto_build_controls(struct hda_codec *codec) | |||
3791 | return conexant_build_controls(codec); | 4307 | return conexant_build_controls(codec); |
3792 | } | 4308 | } |
3793 | 4309 | ||
3794 | static struct hda_codec_ops cx_auto_patch_ops = { | 4310 | static int cx_auto_search_adcs(struct hda_codec *codec) |
4311 | { | ||
4312 | struct conexant_spec *spec = codec->spec; | ||
4313 | hda_nid_t nid, end_nid; | ||
4314 | |||
4315 | end_nid = codec->start_nid + codec->num_nodes; | ||
4316 | for (nid = codec->start_nid; nid < end_nid; nid++) { | ||
4317 | unsigned int caps = get_wcaps(codec, nid); | ||
4318 | if (get_wcaps_type(caps) != AC_WID_AUD_IN) | ||
4319 | continue; | ||
4320 | if (caps & AC_WCAP_DIGITAL) | ||
4321 | continue; | ||
4322 | if (snd_BUG_ON(spec->num_adc_nids >= | ||
4323 | ARRAY_SIZE(spec->private_adc_nids))) | ||
4324 | break; | ||
4325 | spec->private_adc_nids[spec->num_adc_nids++] = nid; | ||
4326 | } | ||
4327 | spec->adc_nids = spec->private_adc_nids; | ||
4328 | return 0; | ||
4329 | } | ||
4330 | |||
4331 | |||
4332 | static const struct hda_codec_ops cx_auto_patch_ops = { | ||
3795 | .build_controls = cx_auto_build_controls, | 4333 | .build_controls = cx_auto_build_controls, |
3796 | .build_pcms = conexant_build_pcms, | 4334 | .build_pcms = conexant_build_pcms, |
3797 | .init = cx_auto_init, | 4335 | .init = cx_auto_init, |
@@ -3808,19 +4346,24 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
3808 | struct conexant_spec *spec; | 4346 | struct conexant_spec *spec; |
3809 | int err; | 4347 | int err; |
3810 | 4348 | ||
4349 | printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", | ||
4350 | codec->chip_name); | ||
4351 | |||
3811 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); | 4352 | spec = kzalloc(sizeof(*spec), GFP_KERNEL); |
3812 | if (!spec) | 4353 | if (!spec) |
3813 | return -ENOMEM; | 4354 | return -ENOMEM; |
3814 | codec->spec = spec; | 4355 | codec->spec = spec; |
3815 | spec->adc_nids = cx_auto_adc_nids; | 4356 | codec->pin_amp_workaround = 1; |
3816 | spec->num_adc_nids = ARRAY_SIZE(cx_auto_adc_nids); | 4357 | err = cx_auto_search_adcs(codec); |
3817 | spec->capsrc_nids = spec->adc_nids; | 4358 | if (err < 0) |
4359 | return err; | ||
3818 | err = cx_auto_parse_auto_config(codec); | 4360 | err = cx_auto_parse_auto_config(codec); |
3819 | if (err < 0) { | 4361 | if (err < 0) { |
3820 | kfree(codec->spec); | 4362 | kfree(codec->spec); |
3821 | codec->spec = NULL; | 4363 | codec->spec = NULL; |
3822 | return err; | 4364 | return err; |
3823 | } | 4365 | } |
4366 | spec->capture_stream = &cx_auto_pcm_analog_capture; | ||
3824 | codec->patch_ops = cx_auto_patch_ops; | 4367 | codec->patch_ops = cx_auto_patch_ops; |
3825 | if (spec->beep_amp) | 4368 | if (spec->beep_amp) |
3826 | snd_hda_attach_beep_device(codec, spec->beep_amp); | 4369 | snd_hda_attach_beep_device(codec, spec->beep_amp); |
@@ -3830,7 +4373,7 @@ static int patch_conexant_auto(struct hda_codec *codec) | |||
3830 | /* | 4373 | /* |
3831 | */ | 4374 | */ |
3832 | 4375 | ||
3833 | static struct hda_codec_preset snd_hda_preset_conexant[] = { | 4376 | static const struct hda_codec_preset snd_hda_preset_conexant[] = { |
3834 | { .id = 0x14f15045, .name = "CX20549 (Venice)", | 4377 | { .id = 0x14f15045, .name = "CX20549 (Venice)", |
3835 | .patch = patch_cxt5045 }, | 4378 | .patch = patch_cxt5045 }, |
3836 | { .id = 0x14f15047, .name = "CX20551 (Waikiki)", | 4379 | { .id = 0x14f15047, .name = "CX20551 (Waikiki)", |
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 715615a88a8d..bd0ae697f9c4 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/moduleparam.h> | 34 | #include <linux/moduleparam.h> |
35 | #include <sound/core.h> | 35 | #include <sound/core.h> |
36 | #include <sound/jack.h> | ||
36 | #include "hda_codec.h" | 37 | #include "hda_codec.h" |
37 | #include "hda_local.h" | 38 | #include "hda_local.h" |
38 | 39 | ||
@@ -47,8 +48,8 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); | |||
47 | * | 48 | * |
48 | * The HDA correspondence of pipes/ports are converter/pin nodes. | 49 | * The HDA correspondence of pipes/ports are converter/pin nodes. |
49 | */ | 50 | */ |
50 | #define MAX_HDMI_CVTS 3 | 51 | #define MAX_HDMI_CVTS 4 |
51 | #define MAX_HDMI_PINS 3 | 52 | #define MAX_HDMI_PINS 4 |
52 | 53 | ||
53 | struct hdmi_spec { | 54 | struct hdmi_spec { |
54 | int num_cvts; | 55 | int num_cvts; |
@@ -76,11 +77,7 @@ struct hdmi_spec { | |||
76 | * ati/nvhdmi specific | 77 | * ati/nvhdmi specific |
77 | */ | 78 | */ |
78 | struct hda_multi_out multiout; | 79 | struct hda_multi_out multiout; |
79 | struct hda_pcm_stream *pcm_playback; | 80 | const struct hda_pcm_stream *pcm_playback; |
80 | |||
81 | /* misc flags */ | ||
82 | /* PD bit indicates only the update, not the current state */ | ||
83 | unsigned int old_pin_detect:1; | ||
84 | }; | 81 | }; |
85 | 82 | ||
86 | 83 | ||
@@ -299,13 +296,6 @@ static int hda_node_index(hda_nid_t *nids, hda_nid_t nid) | |||
299 | return -EINVAL; | 296 | return -EINVAL; |
300 | } | 297 | } |
301 | 298 | ||
302 | static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid, | ||
303 | struct hdmi_eld *eld) | ||
304 | { | ||
305 | if (!snd_hdmi_get_eld(eld, codec, pin_nid)) | ||
306 | snd_hdmi_show_eld(eld); | ||
307 | } | ||
308 | |||
309 | #ifdef BE_PARANOID | 299 | #ifdef BE_PARANOID |
310 | 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, |
311 | int *packet_index, int *byte_index) | 301 | int *packet_index, int *byte_index) |
@@ -693,33 +683,20 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, | |||
693 | 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) |
694 | { | 684 | { |
695 | struct hdmi_spec *spec = codec->spec; | 685 | struct hdmi_spec *spec = codec->spec; |
696 | int tag = res >> AC_UNSOL_RES_TAG_SHIFT; | 686 | int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT; |
697 | int pind = !!(res & AC_UNSOL_RES_PD); | 687 | int pd = !!(res & AC_UNSOL_RES_PD); |
698 | int eldv = !!(res & AC_UNSOL_RES_ELDV); | 688 | int eldv = !!(res & AC_UNSOL_RES_ELDV); |
699 | int index; | 689 | int index; |
700 | 690 | ||
701 | printk(KERN_INFO | 691 | printk(KERN_INFO |
702 | "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", |
703 | tag, pind, eldv); | 693 | pin_nid, pd, eldv); |
704 | 694 | ||
705 | index = hda_node_index(spec->pin, tag); | 695 | index = hda_node_index(spec->pin, pin_nid); |
706 | if (index < 0) | 696 | if (index < 0) |
707 | return; | 697 | return; |
708 | 698 | ||
709 | if (spec->old_pin_detect) { | 699 | hdmi_present_sense(codec, pin_nid, &spec->sink_eld[index]); |
710 | if (pind) | ||
711 | hdmi_present_sense(codec, tag, &spec->sink_eld[index]); | ||
712 | pind = spec->sink_eld[index].monitor_present; | ||
713 | } | ||
714 | |||
715 | spec->sink_eld[index].monitor_present = pind; | ||
716 | spec->sink_eld[index].eld_valid = eldv; | ||
717 | |||
718 | if (pind && eldv) { | ||
719 | hdmi_get_show_eld(codec, spec->pin[index], | ||
720 | &spec->sink_eld[index]); | ||
721 | /* TODO: do real things about ELD */ | ||
722 | } | ||
723 | } | 700 | } |
724 | 701 | ||
725 | 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) |
@@ -900,18 +877,39 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid) | |||
900 | 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, |
901 | struct hdmi_eld *eld) | 878 | struct hdmi_eld *eld) |
902 | { | 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 | */ | ||
903 | int present = snd_hda_pin_sense(codec, pin_nid); | 888 | int present = snd_hda_pin_sense(codec, pin_nid); |
904 | 889 | ||
890 | memset(eld, 0, sizeof(*eld)); | ||
891 | |||
905 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); | 892 | eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); |
906 | 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; | ||
897 | |||
898 | printk(KERN_INFO | ||
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); | ||
907 | 905 | ||
908 | if (present & AC_PINSENSE_ELDV) | 906 | snd_hda_input_jack_report(codec, pin_nid); |
909 | hdmi_get_show_eld(codec, pin_nid, eld); | ||
910 | } | 907 | } |
911 | 908 | ||
912 | 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) |
913 | { | 910 | { |
914 | struct hdmi_spec *spec = codec->spec; | 911 | struct hdmi_spec *spec = codec->spec; |
912 | int err; | ||
915 | 913 | ||
916 | if (spec->num_pins >= MAX_HDMI_PINS) { | 914 | if (spec->num_pins >= MAX_HDMI_PINS) { |
917 | snd_printk(KERN_WARNING | 915 | snd_printk(KERN_WARNING |
@@ -919,6 +917,11 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) | |||
919 | return -E2BIG; | 917 | return -E2BIG; |
920 | } | 918 | } |
921 | 919 | ||
920 | err = snd_hda_input_jack_add(codec, pin_nid, | ||
921 | SND_JACK_VIDEOOUT, NULL); | ||
922 | if (err < 0) | ||
923 | return err; | ||
924 | |||
922 | 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]); |
923 | 926 | ||
924 | spec->pin[spec->num_pins] = pin_nid; | 927 | spec->pin[spec->num_pins] = pin_nid; |
@@ -1024,6 +1027,7 @@ static char *generic_hdmi_pcm_names[MAX_HDMI_CVTS] = { | |||
1024 | "HDMI 0", | 1027 | "HDMI 0", |
1025 | "HDMI 1", | 1028 | "HDMI 1", |
1026 | "HDMI 2", | 1029 | "HDMI 2", |
1030 | "HDMI 3", | ||
1027 | }; | 1031 | }; |
1028 | 1032 | ||
1029 | /* | 1033 | /* |
@@ -1044,7 +1048,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1044 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); | 1048 | return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); |
1045 | } | 1049 | } |
1046 | 1050 | ||
1047 | static struct hda_pcm_stream generic_hdmi_pcm_playback = { | 1051 | static const struct hda_pcm_stream generic_hdmi_pcm_playback = { |
1048 | .substreams = 1, | 1052 | .substreams = 1, |
1049 | .channels_min = 2, | 1053 | .channels_min = 2, |
1050 | .ops = { | 1054 | .ops = { |
@@ -1120,11 +1124,12 @@ static void generic_hdmi_free(struct hda_codec *codec) | |||
1120 | 1124 | ||
1121 | for (i = 0; i < spec->num_pins; i++) | 1125 | for (i = 0; i < spec->num_pins; i++) |
1122 | snd_hda_eld_proc_free(codec, &spec->sink_eld[i]); | 1126 | snd_hda_eld_proc_free(codec, &spec->sink_eld[i]); |
1127 | snd_hda_input_jack_free(codec); | ||
1123 | 1128 | ||
1124 | kfree(spec); | 1129 | kfree(spec); |
1125 | } | 1130 | } |
1126 | 1131 | ||
1127 | static struct hda_codec_ops generic_hdmi_patch_ops = { | 1132 | static const struct hda_codec_ops generic_hdmi_patch_ops = { |
1128 | .init = generic_hdmi_init, | 1133 | .init = generic_hdmi_init, |
1129 | .free = generic_hdmi_free, | 1134 | .free = generic_hdmi_free, |
1130 | .build_pcms = generic_hdmi_build_pcms, | 1135 | .build_pcms = generic_hdmi_build_pcms, |
@@ -1169,12 +1174,12 @@ static int patch_generic_hdmi(struct hda_codec *codec) | |||
1169 | #define nvhdmi_master_con_nid_7x 0x04 | 1174 | #define nvhdmi_master_con_nid_7x 0x04 |
1170 | #define nvhdmi_master_pin_nid_7x 0x05 | 1175 | #define nvhdmi_master_pin_nid_7x 0x05 |
1171 | 1176 | ||
1172 | static hda_nid_t nvhdmi_con_nids_7x[4] = { | 1177 | static const hda_nid_t nvhdmi_con_nids_7x[4] = { |
1173 | /*front, rear, clfe, rear_surr */ | 1178 | /*front, rear, clfe, rear_surr */ |
1174 | 0x6, 0x8, 0xa, 0xc, | 1179 | 0x6, 0x8, 0xa, 0xc, |
1175 | }; | 1180 | }; |
1176 | 1181 | ||
1177 | static struct hda_verb nvhdmi_basic_init_7x[] = { | 1182 | static const struct hda_verb nvhdmi_basic_init_7x[] = { |
1178 | /* set audio protect on */ | 1183 | /* set audio protect on */ |
1179 | { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, | 1184 | { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, |
1180 | /* enable digital output on pin widget */ | 1185 | /* enable digital output on pin widget */ |
@@ -1435,7 +1440,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1435 | return 0; | 1440 | return 0; |
1436 | } | 1441 | } |
1437 | 1442 | ||
1438 | static struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { | 1443 | static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { |
1439 | .substreams = 1, | 1444 | .substreams = 1, |
1440 | .channels_min = 2, | 1445 | .channels_min = 2, |
1441 | .channels_max = 8, | 1446 | .channels_max = 8, |
@@ -1450,7 +1455,7 @@ static struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { | |||
1450 | }, | 1455 | }, |
1451 | }; | 1456 | }; |
1452 | 1457 | ||
1453 | static struct hda_pcm_stream nvhdmi_pcm_playback_2ch = { | 1458 | static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = { |
1454 | .substreams = 1, | 1459 | .substreams = 1, |
1455 | .channels_min = 2, | 1460 | .channels_min = 2, |
1456 | .channels_max = 2, | 1461 | .channels_max = 2, |
@@ -1465,32 +1470,20 @@ static struct hda_pcm_stream nvhdmi_pcm_playback_2ch = { | |||
1465 | }, | 1470 | }, |
1466 | }; | 1471 | }; |
1467 | 1472 | ||
1468 | static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { | 1473 | static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { |
1469 | .build_controls = generic_hdmi_build_controls, | 1474 | .build_controls = generic_hdmi_build_controls, |
1470 | .build_pcms = generic_hdmi_build_pcms, | 1475 | .build_pcms = generic_hdmi_build_pcms, |
1471 | .init = nvhdmi_7x_init, | 1476 | .init = nvhdmi_7x_init, |
1472 | .free = generic_hdmi_free, | 1477 | .free = generic_hdmi_free, |
1473 | }; | 1478 | }; |
1474 | 1479 | ||
1475 | static struct hda_codec_ops nvhdmi_patch_ops_2ch = { | 1480 | static const struct hda_codec_ops nvhdmi_patch_ops_2ch = { |
1476 | .build_controls = generic_hdmi_build_controls, | 1481 | .build_controls = generic_hdmi_build_controls, |
1477 | .build_pcms = generic_hdmi_build_pcms, | 1482 | .build_pcms = generic_hdmi_build_pcms, |
1478 | .init = nvhdmi_7x_init, | 1483 | .init = nvhdmi_7x_init, |
1479 | .free = generic_hdmi_free, | 1484 | .free = generic_hdmi_free, |
1480 | }; | 1485 | }; |
1481 | 1486 | ||
1482 | static int patch_nvhdmi_8ch_89(struct hda_codec *codec) | ||
1483 | { | ||
1484 | struct hdmi_spec *spec; | ||
1485 | int err = patch_generic_hdmi(codec); | ||
1486 | |||
1487 | if (err < 0) | ||
1488 | return err; | ||
1489 | spec = codec->spec; | ||
1490 | spec->old_pin_detect = 1; | ||
1491 | return 0; | ||
1492 | } | ||
1493 | |||
1494 | static int patch_nvhdmi_2ch(struct hda_codec *codec) | 1487 | static int patch_nvhdmi_2ch(struct hda_codec *codec) |
1495 | { | 1488 | { |
1496 | struct hdmi_spec *spec; | 1489 | struct hdmi_spec *spec; |
@@ -1504,7 +1497,6 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) | |||
1504 | spec->multiout.num_dacs = 0; /* no analog */ | 1497 | spec->multiout.num_dacs = 0; /* no analog */ |
1505 | spec->multiout.max_channels = 2; | 1498 | spec->multiout.max_channels = 2; |
1506 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; | 1499 | spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; |
1507 | spec->old_pin_detect = 1; | ||
1508 | spec->num_cvts = 1; | 1500 | spec->num_cvts = 1; |
1509 | spec->cvt[0] = nvhdmi_master_con_nid_7x; | 1501 | spec->cvt[0] = nvhdmi_master_con_nid_7x; |
1510 | spec->pcm_playback = &nvhdmi_pcm_playback_2ch; | 1502 | spec->pcm_playback = &nvhdmi_pcm_playback_2ch; |
@@ -1568,7 +1560,7 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1568 | return 0; | 1560 | return 0; |
1569 | } | 1561 | } |
1570 | 1562 | ||
1571 | static struct hda_pcm_stream atihdmi_pcm_digital_playback = { | 1563 | static const struct hda_pcm_stream atihdmi_pcm_digital_playback = { |
1572 | .substreams = 1, | 1564 | .substreams = 1, |
1573 | .channels_min = 2, | 1565 | .channels_min = 2, |
1574 | .channels_max = 2, | 1566 | .channels_max = 2, |
@@ -1580,7 +1572,7 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = { | |||
1580 | }, | 1572 | }, |
1581 | }; | 1573 | }; |
1582 | 1574 | ||
1583 | static struct hda_verb atihdmi_basic_init[] = { | 1575 | static const struct hda_verb atihdmi_basic_init[] = { |
1584 | /* enable digital output on pin widget */ | 1576 | /* enable digital output on pin widget */ |
1585 | { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 1577 | { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
1586 | {} /* terminator */ | 1578 | {} /* terminator */ |
@@ -1599,7 +1591,7 @@ static int atihdmi_init(struct hda_codec *codec) | |||
1599 | return 0; | 1591 | return 0; |
1600 | } | 1592 | } |
1601 | 1593 | ||
1602 | static struct hda_codec_ops atihdmi_patch_ops = { | 1594 | static const struct hda_codec_ops atihdmi_patch_ops = { |
1603 | .build_controls = generic_hdmi_build_controls, | 1595 | .build_controls = generic_hdmi_build_controls, |
1604 | .build_pcms = generic_hdmi_build_pcms, | 1596 | .build_pcms = generic_hdmi_build_pcms, |
1605 | .init = atihdmi_init, | 1597 | .init = atihdmi_init, |
@@ -1634,7 +1626,7 @@ static int patch_atihdmi(struct hda_codec *codec) | |||
1634 | /* | 1626 | /* |
1635 | * patch entries | 1627 | * patch entries |
1636 | */ | 1628 | */ |
1637 | static struct hda_codec_preset snd_hda_preset_hdmi[] = { | 1629 | static const struct hda_codec_preset snd_hda_preset_hdmi[] = { |
1638 | { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi }, | 1630 | { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi }, |
1639 | { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi }, | 1631 | { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi }, |
1640 | { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi }, | 1632 | { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi }, |
@@ -1647,28 +1639,28 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
1647 | { .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, | 1639 | { .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, |
1648 | { .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, | 1640 | { .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, |
1649 | { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x }, | 1641 | { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x }, |
1650 | { .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1642 | { .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_generic_hdmi }, |
1651 | { .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1643 | { .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_generic_hdmi }, |
1652 | { .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi_8ch_89 }, | 1644 | { .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_generic_hdmi }, |
1653 | { .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1645 | { .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_generic_hdmi }, |
1654 | { .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1646 | { .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_generic_hdmi }, |
1655 | { .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1647 | { .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_generic_hdmi }, |
1656 | { .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1648 | { .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_generic_hdmi }, |
1657 | { .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1649 | { .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_generic_hdmi }, |
1658 | { .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1650 | { .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_generic_hdmi }, |
1659 | { .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1651 | { .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_generic_hdmi }, |
1660 | { .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1652 | { .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_generic_hdmi }, |
1661 | /* 17 is known to be absent */ | 1653 | /* 17 is known to be absent */ |
1662 | { .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1654 | { .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_generic_hdmi }, |
1663 | { .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1655 | { .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_generic_hdmi }, |
1664 | { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1656 | { .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_generic_hdmi }, |
1665 | { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1657 | { .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_generic_hdmi }, |
1666 | { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1658 | { .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_generic_hdmi }, |
1667 | { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1659 | { .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_generic_hdmi }, |
1668 | { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1660 | { .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_generic_hdmi }, |
1669 | { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1661 | { .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, |
1670 | { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1662 | { .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, |
1671 | { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, | 1663 | { .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, |
1672 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, | 1664 | { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, |
1673 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, | 1665 | { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, |
1674 | { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, | 1666 | { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, |
@@ -1677,6 +1669,7 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = { | |||
1677 | { .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_generic_hdmi }, | 1669 | { .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_generic_hdmi }, |
1678 | { .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, | 1670 | { .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, |
1679 | { .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, | 1671 | { .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, |
1672 | { .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, | ||
1680 | { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, | 1673 | { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, |
1681 | {} /* terminator */ | 1674 | {} /* terminator */ |
1682 | }; | 1675 | }; |
@@ -1722,6 +1715,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862802"); | |||
1722 | MODULE_ALIAS("snd-hda-codec-id:80862803"); | 1715 | MODULE_ALIAS("snd-hda-codec-id:80862803"); |
1723 | MODULE_ALIAS("snd-hda-codec-id:80862804"); | 1716 | MODULE_ALIAS("snd-hda-codec-id:80862804"); |
1724 | MODULE_ALIAS("snd-hda-codec-id:80862805"); | 1717 | MODULE_ALIAS("snd-hda-codec-id:80862805"); |
1718 | MODULE_ALIAS("snd-hda-codec-id:80862806"); | ||
1725 | MODULE_ALIAS("snd-hda-codec-id:808629fb"); | 1719 | MODULE_ALIAS("snd-hda-codec-id:808629fb"); |
1726 | 1720 | ||
1727 | MODULE_LICENSE("GPL"); | 1721 | MODULE_LICENSE("GPL"); |
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index 52928d9a72da..7a4e10002f56 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c | |||
@@ -299,11 +299,23 @@ struct alc_customize_define { | |||
299 | 299 | ||
300 | struct alc_fixup; | 300 | struct alc_fixup; |
301 | 301 | ||
302 | struct alc_multi_io { | ||
303 | hda_nid_t pin; /* multi-io widget pin NID */ | ||
304 | hda_nid_t dac; /* DAC to be connected */ | ||
305 | unsigned int ctl_in; /* cached input-pin control value */ | ||
306 | }; | ||
307 | |||
308 | enum { | ||
309 | ALC_AUTOMUTE_PIN, /* change the pin control */ | ||
310 | ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */ | ||
311 | ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ | ||
312 | }; | ||
313 | |||
302 | struct alc_spec { | 314 | struct alc_spec { |
303 | /* codec parameterization */ | 315 | /* codec parameterization */ |
304 | struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ | 316 | const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ |
305 | unsigned int num_mixers; | 317 | unsigned int num_mixers; |
306 | struct snd_kcontrol_new *cap_mixer; /* capture mixer */ | 318 | const struct snd_kcontrol_new *cap_mixer; /* capture mixer */ |
307 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ | 319 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
308 | 320 | ||
309 | const struct hda_verb *init_verbs[10]; /* initialization verbs | 321 | const struct hda_verb *init_verbs[10]; /* initialization verbs |
@@ -313,14 +325,14 @@ struct alc_spec { | |||
313 | unsigned int num_init_verbs; | 325 | unsigned int num_init_verbs; |
314 | 326 | ||
315 | char stream_name_analog[32]; /* analog PCM stream */ | 327 | char stream_name_analog[32]; /* analog PCM stream */ |
316 | struct hda_pcm_stream *stream_analog_playback; | 328 | const struct hda_pcm_stream *stream_analog_playback; |
317 | struct hda_pcm_stream *stream_analog_capture; | 329 | const struct hda_pcm_stream *stream_analog_capture; |
318 | struct hda_pcm_stream *stream_analog_alt_playback; | 330 | const struct hda_pcm_stream *stream_analog_alt_playback; |
319 | struct hda_pcm_stream *stream_analog_alt_capture; | 331 | const struct hda_pcm_stream *stream_analog_alt_capture; |
320 | 332 | ||
321 | char stream_name_digital[32]; /* digital PCM stream */ | 333 | char stream_name_digital[32]; /* digital PCM stream */ |
322 | struct hda_pcm_stream *stream_digital_playback; | 334 | const struct hda_pcm_stream *stream_digital_playback; |
323 | struct hda_pcm_stream *stream_digital_capture; | 335 | const struct hda_pcm_stream *stream_digital_capture; |
324 | 336 | ||
325 | /* playback */ | 337 | /* playback */ |
326 | struct hda_multi_out multiout; /* playback set-up | 338 | struct hda_multi_out multiout; /* playback set-up |
@@ -333,8 +345,8 @@ struct alc_spec { | |||
333 | 345 | ||
334 | /* capture */ | 346 | /* capture */ |
335 | unsigned int num_adc_nids; | 347 | unsigned int num_adc_nids; |
336 | hda_nid_t *adc_nids; | 348 | const hda_nid_t *adc_nids; |
337 | hda_nid_t *capsrc_nids; | 349 | const hda_nid_t *capsrc_nids; |
338 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ | 350 | hda_nid_t dig_in_nid; /* digital-in NID; optional */ |
339 | 351 | ||
340 | /* capture setup for dynamic dual-adc switch */ | 352 | /* capture setup for dynamic dual-adc switch */ |
@@ -348,6 +360,7 @@ struct alc_spec { | |||
348 | const struct hda_input_mux *input_mux; | 360 | const struct hda_input_mux *input_mux; |
349 | unsigned int cur_mux[3]; | 361 | unsigned int cur_mux[3]; |
350 | struct alc_mic_route ext_mic; | 362 | struct alc_mic_route ext_mic; |
363 | struct alc_mic_route dock_mic; | ||
351 | struct alc_mic_route int_mic; | 364 | struct alc_mic_route int_mic; |
352 | 365 | ||
353 | /* channel model */ | 366 | /* channel model */ |
@@ -375,17 +388,27 @@ struct alc_spec { | |||
375 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 388 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
376 | void (*power_hook)(struct hda_codec *codec); | 389 | void (*power_hook)(struct hda_codec *codec); |
377 | #endif | 390 | #endif |
391 | void (*shutup)(struct hda_codec *codec); | ||
378 | 392 | ||
379 | /* for pin sensing */ | 393 | /* for pin sensing */ |
380 | unsigned int sense_updated: 1; | ||
381 | unsigned int jack_present: 1; | 394 | unsigned int jack_present: 1; |
382 | unsigned int master_sw: 1; | 395 | unsigned int line_jack_present:1; |
396 | unsigned int master_mute:1; | ||
383 | unsigned int auto_mic:1; | 397 | unsigned int auto_mic:1; |
398 | unsigned int automute:1; /* HP automute enabled */ | ||
399 | unsigned int detect_line:1; /* Line-out detection enabled */ | ||
400 | unsigned int automute_lines:1; /* automute line-out as well */ | ||
401 | unsigned int automute_hp_lo:1; /* both HP and LO available */ | ||
384 | 402 | ||
385 | /* other flags */ | 403 | /* other flags */ |
386 | unsigned int no_analog :1; /* digital I/O only */ | 404 | unsigned int no_analog :1; /* digital I/O only */ |
387 | unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ | 405 | unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ |
388 | unsigned int single_input_src:1; | 406 | unsigned int single_input_src:1; |
407 | |||
408 | /* auto-mute control */ | ||
409 | int automute_mode; | ||
410 | hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS]; | ||
411 | |||
389 | int init_amp; | 412 | int init_amp; |
390 | int codec_variant; /* flag for other variants */ | 413 | int codec_variant; /* flag for other variants */ |
391 | 414 | ||
@@ -403,25 +426,29 @@ struct alc_spec { | |||
403 | int fixup_id; | 426 | int fixup_id; |
404 | const struct alc_fixup *fixup_list; | 427 | const struct alc_fixup *fixup_list; |
405 | const char *fixup_name; | 428 | const char *fixup_name; |
429 | |||
430 | /* multi-io */ | ||
431 | int multi_ios; | ||
432 | struct alc_multi_io multi_io[4]; | ||
406 | }; | 433 | }; |
407 | 434 | ||
408 | /* | 435 | /* |
409 | * configuration template - to be copied to the spec instance | 436 | * configuration template - to be copied to the spec instance |
410 | */ | 437 | */ |
411 | struct alc_config_preset { | 438 | struct alc_config_preset { |
412 | struct snd_kcontrol_new *mixers[5]; /* should be identical size | 439 | const struct snd_kcontrol_new *mixers[5]; /* should be identical size |
413 | * with spec | 440 | * with spec |
414 | */ | 441 | */ |
415 | struct snd_kcontrol_new *cap_mixer; /* capture mixer */ | 442 | const struct snd_kcontrol_new *cap_mixer; /* capture mixer */ |
416 | const struct hda_verb *init_verbs[5]; | 443 | const struct hda_verb *init_verbs[5]; |
417 | unsigned int num_dacs; | 444 | unsigned int num_dacs; |
418 | hda_nid_t *dac_nids; | 445 | const hda_nid_t *dac_nids; |
419 | hda_nid_t dig_out_nid; /* optional */ | 446 | hda_nid_t dig_out_nid; /* optional */ |
420 | hda_nid_t hp_nid; /* optional */ | 447 | hda_nid_t hp_nid; /* optional */ |
421 | hda_nid_t *slave_dig_outs; | 448 | const hda_nid_t *slave_dig_outs; |
422 | unsigned int num_adc_nids; | 449 | unsigned int num_adc_nids; |
423 | hda_nid_t *adc_nids; | 450 | const hda_nid_t *adc_nids; |
424 | hda_nid_t *capsrc_nids; | 451 | const hda_nid_t *capsrc_nids; |
425 | hda_nid_t dig_in_nid; | 452 | hda_nid_t dig_in_nid; |
426 | unsigned int num_channel_mode; | 453 | unsigned int num_channel_mode; |
427 | const struct hda_channel_mode *channel_mode; | 454 | const struct hda_channel_mode *channel_mode; |
@@ -433,7 +460,7 @@ struct alc_config_preset { | |||
433 | void (*setup)(struct hda_codec *); | 460 | void (*setup)(struct hda_codec *); |
434 | void (*init_hook)(struct hda_codec *); | 461 | void (*init_hook)(struct hda_codec *); |
435 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 462 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
436 | struct hda_amp_list *loopbacks; | 463 | const struct hda_amp_list *loopbacks; |
437 | void (*power_hook)(struct hda_codec *codec); | 464 | void (*power_hook)(struct hda_codec *codec); |
438 | #endif | 465 | #endif |
439 | }; | 466 | }; |
@@ -560,11 +587,11 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, | |||
560 | * NIDs 0x0f and 0x10 have been observed to have this behaviour as of | 587 | * NIDs 0x0f and 0x10 have been observed to have this behaviour as of |
561 | * March 2006. | 588 | * March 2006. |
562 | */ | 589 | */ |
563 | static char *alc_pin_mode_names[] = { | 590 | static const char * const alc_pin_mode_names[] = { |
564 | "Mic 50pc bias", "Mic 80pc bias", | 591 | "Mic 50pc bias", "Mic 80pc bias", |
565 | "Line in", "Line out", "Headphone out", | 592 | "Line in", "Line out", "Headphone out", |
566 | }; | 593 | }; |
567 | static unsigned char alc_pin_mode_values[] = { | 594 | static const unsigned char alc_pin_mode_values[] = { |
568 | PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, | 595 | PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, |
569 | }; | 596 | }; |
570 | /* The control can present all 5 options, or it can limit the options based | 597 | /* The control can present all 5 options, or it can limit the options based |
@@ -583,7 +610,7 @@ static unsigned char alc_pin_mode_values[] = { | |||
583 | /* Info about the pin modes supported by the different pin direction modes. | 610 | /* Info about the pin modes supported by the different pin direction modes. |
584 | * For each direction the minimum and maximum values are given. | 611 | * For each direction the minimum and maximum values are given. |
585 | */ | 612 | */ |
586 | static signed char alc_pin_mode_dir_info[5][2] = { | 613 | static const signed char alc_pin_mode_dir_info[5][2] = { |
587 | { 0, 2 }, /* ALC_PIN_DIR_IN */ | 614 | { 0, 2 }, /* ALC_PIN_DIR_IN */ |
588 | { 3, 4 }, /* ALC_PIN_DIR_OUT */ | 615 | { 3, 4 }, /* ALC_PIN_DIR_OUT */ |
589 | { 0, 4 }, /* ALC_PIN_DIR_INOUT */ | 616 | { 0, 4 }, /* ALC_PIN_DIR_INOUT */ |
@@ -900,7 +927,7 @@ static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec) | |||
900 | 927 | ||
901 | /* | 928 | /* |
902 | */ | 929 | */ |
903 | static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) | 930 | static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) |
904 | { | 931 | { |
905 | if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) | 932 | if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) |
906 | return; | 933 | return; |
@@ -971,21 +998,21 @@ static void setup_preset(struct hda_codec *codec, | |||
971 | } | 998 | } |
972 | 999 | ||
973 | /* Enable GPIO mask and set output */ | 1000 | /* Enable GPIO mask and set output */ |
974 | static struct hda_verb alc_gpio1_init_verbs[] = { | 1001 | static const struct hda_verb alc_gpio1_init_verbs[] = { |
975 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, | 1002 | {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, |
976 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, | 1003 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, |
977 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, | 1004 | {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, |
978 | { } | 1005 | { } |
979 | }; | 1006 | }; |
980 | 1007 | ||
981 | static struct hda_verb alc_gpio2_init_verbs[] = { | 1008 | static const struct hda_verb alc_gpio2_init_verbs[] = { |
982 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, | 1009 | {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, |
983 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, | 1010 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, |
984 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, | 1011 | {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, |
985 | { } | 1012 | { } |
986 | }; | 1013 | }; |
987 | 1014 | ||
988 | static struct hda_verb alc_gpio3_init_verbs[] = { | 1015 | static const struct hda_verb alc_gpio3_init_verbs[] = { |
989 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, | 1016 | {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, |
990 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, | 1017 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, |
991 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, | 1018 | {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, |
@@ -1031,6 +1058,7 @@ static int alc_init_jacks(struct hda_codec *codec) | |||
1031 | int err; | 1058 | int err; |
1032 | unsigned int hp_nid = spec->autocfg.hp_pins[0]; | 1059 | unsigned int hp_nid = spec->autocfg.hp_pins[0]; |
1033 | unsigned int mic_nid = spec->ext_mic.pin; | 1060 | unsigned int mic_nid = spec->ext_mic.pin; |
1061 | unsigned int dock_nid = spec->dock_mic.pin; | ||
1034 | 1062 | ||
1035 | if (hp_nid) { | 1063 | if (hp_nid) { |
1036 | err = snd_hda_input_jack_add(codec, hp_nid, | 1064 | err = snd_hda_input_jack_add(codec, hp_nid, |
@@ -1047,46 +1075,116 @@ static int alc_init_jacks(struct hda_codec *codec) | |||
1047 | return err; | 1075 | return err; |
1048 | snd_hda_input_jack_report(codec, mic_nid); | 1076 | snd_hda_input_jack_report(codec, mic_nid); |
1049 | } | 1077 | } |
1078 | if (dock_nid) { | ||
1079 | err = snd_hda_input_jack_add(codec, dock_nid, | ||
1080 | SND_JACK_MICROPHONE, NULL); | ||
1081 | if (err < 0) | ||
1082 | return err; | ||
1083 | snd_hda_input_jack_report(codec, dock_nid); | ||
1084 | } | ||
1050 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ | 1085 | #endif /* CONFIG_SND_HDA_INPUT_JACK */ |
1051 | return 0; | 1086 | return 0; |
1052 | } | 1087 | } |
1053 | 1088 | ||
1054 | static void alc_automute_speaker(struct hda_codec *codec, int pinctl) | 1089 | static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) |
1055 | { | 1090 | { |
1056 | struct alc_spec *spec = codec->spec; | 1091 | int i, present = 0; |
1057 | unsigned int mute; | ||
1058 | hda_nid_t nid; | ||
1059 | int i; | ||
1060 | 1092 | ||
1061 | spec->jack_present = 0; | 1093 | for (i = 0; i < num_pins; i++) { |
1062 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { | 1094 | hda_nid_t nid = pins[i]; |
1063 | nid = spec->autocfg.hp_pins[i]; | ||
1064 | if (!nid) | 1095 | if (!nid) |
1065 | break; | 1096 | break; |
1066 | snd_hda_input_jack_report(codec, nid); | 1097 | snd_hda_input_jack_report(codec, nid); |
1067 | spec->jack_present |= snd_hda_jack_detect(codec, nid); | 1098 | present |= snd_hda_jack_detect(codec, nid); |
1068 | } | 1099 | } |
1100 | return present; | ||
1101 | } | ||
1069 | 1102 | ||
1070 | mute = spec->jack_present ? HDA_AMP_MUTE : 0; | 1103 | static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, |
1071 | /* Toggle internal speakers muting */ | 1104 | bool mute, bool hp_out) |
1072 | for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { | 1105 | { |
1073 | nid = spec->autocfg.speaker_pins[i]; | 1106 | struct alc_spec *spec = codec->spec; |
1107 | unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0; | ||
1108 | unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT); | ||
1109 | int i; | ||
1110 | |||
1111 | for (i = 0; i < num_pins; i++) { | ||
1112 | hda_nid_t nid = pins[i]; | ||
1074 | if (!nid) | 1113 | if (!nid) |
1075 | break; | 1114 | break; |
1076 | if (pinctl) { | 1115 | switch (spec->automute_mode) { |
1116 | case ALC_AUTOMUTE_PIN: | ||
1077 | snd_hda_codec_write(codec, nid, 0, | 1117 | snd_hda_codec_write(codec, nid, 0, |
1078 | AC_VERB_SET_PIN_WIDGET_CONTROL, | 1118 | AC_VERB_SET_PIN_WIDGET_CONTROL, |
1079 | spec->jack_present ? 0 : PIN_OUT); | 1119 | pin_bits); |
1080 | } else { | 1120 | break; |
1121 | case ALC_AUTOMUTE_AMP: | ||
1081 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | 1122 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, |
1082 | HDA_AMP_MUTE, mute); | 1123 | HDA_AMP_MUTE, mute_bits); |
1124 | break; | ||
1125 | case ALC_AUTOMUTE_MIXER: | ||
1126 | nid = spec->automute_mixer_nid[i]; | ||
1127 | if (!nid) | ||
1128 | break; | ||
1129 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, | ||
1130 | HDA_AMP_MUTE, mute_bits); | ||
1131 | snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1, | ||
1132 | HDA_AMP_MUTE, mute_bits); | ||
1133 | break; | ||
1083 | } | 1134 | } |
1084 | } | 1135 | } |
1085 | } | 1136 | } |
1086 | 1137 | ||
1087 | static void alc_automute_pin(struct hda_codec *codec) | 1138 | /* Toggle internal speakers muting */ |
1139 | static void update_speakers(struct hda_codec *codec) | ||
1088 | { | 1140 | { |
1089 | alc_automute_speaker(codec, 1); | 1141 | struct alc_spec *spec = codec->spec; |
1142 | int on; | ||
1143 | |||
1144 | if (!spec->automute) | ||
1145 | on = 0; | ||
1146 | else | ||
1147 | on = spec->jack_present | spec->line_jack_present; | ||
1148 | on |= spec->master_mute; | ||
1149 | do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), | ||
1150 | spec->autocfg.speaker_pins, on, false); | ||
1151 | |||
1152 | /* toggle line-out mutes if needed, too */ | ||
1153 | /* if LO is a copy of either HP or Speaker, don't need to handle it */ | ||
1154 | if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || | ||
1155 | spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) | ||
1156 | return; | ||
1157 | if (!spec->automute_lines || !spec->automute) | ||
1158 | on = 0; | ||
1159 | else | ||
1160 | on = spec->jack_present; | ||
1161 | on |= spec->master_mute; | ||
1162 | do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), | ||
1163 | spec->autocfg.line_out_pins, on, false); | ||
1164 | } | ||
1165 | |||
1166 | static void alc_hp_automute(struct hda_codec *codec) | ||
1167 | { | ||
1168 | struct alc_spec *spec = codec->spec; | ||
1169 | |||
1170 | if (!spec->automute) | ||
1171 | return; | ||
1172 | spec->jack_present = | ||
1173 | detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), | ||
1174 | spec->autocfg.hp_pins); | ||
1175 | update_speakers(codec); | ||
1176 | } | ||
1177 | |||
1178 | static void alc_line_automute(struct hda_codec *codec) | ||
1179 | { | ||
1180 | struct alc_spec *spec = codec->spec; | ||
1181 | |||
1182 | if (!spec->automute || !spec->detect_line) | ||
1183 | return; | ||
1184 | spec->line_jack_present = | ||
1185 | detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), | ||
1186 | spec->autocfg.line_out_pins); | ||
1187 | update_speakers(codec); | ||
1090 | } | 1188 | } |
1091 | 1189 | ||
1092 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, | 1190 | static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, |
@@ -1128,7 +1226,7 @@ static void alc_dual_mic_adc_auto_switch(struct hda_codec *codec) | |||
1128 | static void alc_mic_automute(struct hda_codec *codec) | 1226 | static void alc_mic_automute(struct hda_codec *codec) |
1129 | { | 1227 | { |
1130 | struct alc_spec *spec = codec->spec; | 1228 | struct alc_spec *spec = codec->spec; |
1131 | struct alc_mic_route *dead, *alive; | 1229 | struct alc_mic_route *dead1, *dead2, *alive; |
1132 | unsigned int present, type; | 1230 | unsigned int present, type; |
1133 | hda_nid_t cap_nid; | 1231 | hda_nid_t cap_nid; |
1134 | 1232 | ||
@@ -1146,13 +1244,24 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
1146 | 1244 | ||
1147 | cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; | 1245 | cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; |
1148 | 1246 | ||
1247 | alive = &spec->int_mic; | ||
1248 | dead1 = &spec->ext_mic; | ||
1249 | dead2 = &spec->dock_mic; | ||
1250 | |||
1149 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); | 1251 | present = snd_hda_jack_detect(codec, spec->ext_mic.pin); |
1150 | if (present) { | 1252 | if (present) { |
1151 | alive = &spec->ext_mic; | 1253 | alive = &spec->ext_mic; |
1152 | dead = &spec->int_mic; | 1254 | dead1 = &spec->int_mic; |
1153 | } else { | 1255 | dead2 = &spec->dock_mic; |
1154 | alive = &spec->int_mic; | 1256 | } |
1155 | dead = &spec->ext_mic; | 1257 | if (!present && spec->dock_mic.pin > 0) { |
1258 | present = snd_hda_jack_detect(codec, spec->dock_mic.pin); | ||
1259 | if (present) { | ||
1260 | alive = &spec->dock_mic; | ||
1261 | dead1 = &spec->int_mic; | ||
1262 | dead2 = &spec->ext_mic; | ||
1263 | } | ||
1264 | snd_hda_input_jack_report(codec, spec->dock_mic.pin); | ||
1156 | } | 1265 | } |
1157 | 1266 | ||
1158 | type = get_wcaps_type(get_wcaps(codec, cap_nid)); | 1267 | type = get_wcaps_type(get_wcaps(codec, cap_nid)); |
@@ -1161,9 +1270,14 @@ static void alc_mic_automute(struct hda_codec *codec) | |||
1161 | snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, | 1270 | snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, |
1162 | alive->mux_idx, | 1271 | alive->mux_idx, |
1163 | HDA_AMP_MUTE, 0); | 1272 | HDA_AMP_MUTE, 0); |
1164 | snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, | 1273 | if (dead1->pin > 0) |
1165 | dead->mux_idx, | 1274 | snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, |
1166 | HDA_AMP_MUTE, HDA_AMP_MUTE); | 1275 | dead1->mux_idx, |
1276 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
1277 | if (dead2->pin > 0) | ||
1278 | snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, | ||
1279 | dead2->mux_idx, | ||
1280 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
1167 | } else { | 1281 | } else { |
1168 | /* MUX style (e.g. ALC880) */ | 1282 | /* MUX style (e.g. ALC880) */ |
1169 | snd_hda_codec_write_cache(codec, cap_nid, 0, | 1283 | snd_hda_codec_write_cache(codec, cap_nid, 0, |
@@ -1184,7 +1298,10 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
1184 | res >>= 26; | 1298 | res >>= 26; |
1185 | switch (res) { | 1299 | switch (res) { |
1186 | case ALC880_HP_EVENT: | 1300 | case ALC880_HP_EVENT: |
1187 | alc_automute_pin(codec); | 1301 | alc_hp_automute(codec); |
1302 | break; | ||
1303 | case ALC880_FRONT_EVENT: | ||
1304 | alc_line_automute(codec); | ||
1188 | break; | 1305 | break; |
1189 | case ALC880_MIC_EVENT: | 1306 | case ALC880_MIC_EVENT: |
1190 | alc_mic_automute(codec); | 1307 | alc_mic_automute(codec); |
@@ -1194,7 +1311,8 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) | |||
1194 | 1311 | ||
1195 | static void alc_inithook(struct hda_codec *codec) | 1312 | static void alc_inithook(struct hda_codec *codec) |
1196 | { | 1313 | { |
1197 | alc_automute_pin(codec); | 1314 | alc_hp_automute(codec); |
1315 | alc_line_automute(codec); | ||
1198 | alc_mic_automute(codec); | 1316 | alc_mic_automute(codec); |
1199 | } | 1317 | } |
1200 | 1318 | ||
@@ -1236,6 +1354,43 @@ static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) | |||
1236 | on ? 2 : 0); | 1354 | on ? 2 : 0); |
1237 | } | 1355 | } |
1238 | 1356 | ||
1357 | /* turn on/off EAPD controls of the codec */ | ||
1358 | static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) | ||
1359 | { | ||
1360 | /* We currently only handle front, HP */ | ||
1361 | switch (codec->vendor_id) { | ||
1362 | case 0x10ec0260: | ||
1363 | set_eapd(codec, 0x0f, on); | ||
1364 | set_eapd(codec, 0x10, on); | ||
1365 | break; | ||
1366 | case 0x10ec0262: | ||
1367 | case 0x10ec0267: | ||
1368 | case 0x10ec0268: | ||
1369 | case 0x10ec0269: | ||
1370 | case 0x10ec0270: | ||
1371 | case 0x10ec0272: | ||
1372 | case 0x10ec0660: | ||
1373 | case 0x10ec0662: | ||
1374 | case 0x10ec0663: | ||
1375 | case 0x10ec0665: | ||
1376 | case 0x10ec0862: | ||
1377 | case 0x10ec0889: | ||
1378 | case 0x10ec0892: | ||
1379 | set_eapd(codec, 0x14, on); | ||
1380 | set_eapd(codec, 0x15, on); | ||
1381 | break; | ||
1382 | } | ||
1383 | } | ||
1384 | |||
1385 | /* generic shutup callback; | ||
1386 | * just turning off EPAD and a little pause for avoiding pop-noise | ||
1387 | */ | ||
1388 | static void alc_eapd_shutup(struct hda_codec *codec) | ||
1389 | { | ||
1390 | alc_auto_setup_eapd(codec, false); | ||
1391 | msleep(200); | ||
1392 | } | ||
1393 | |||
1239 | static void alc_auto_init_amp(struct hda_codec *codec, int type) | 1394 | static void alc_auto_init_amp(struct hda_codec *codec, int type) |
1240 | { | 1395 | { |
1241 | unsigned int tmp; | 1396 | unsigned int tmp; |
@@ -1251,27 +1406,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
1251 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); | 1406 | snd_hda_sequence_write(codec, alc_gpio3_init_verbs); |
1252 | break; | 1407 | break; |
1253 | case ALC_INIT_DEFAULT: | 1408 | case ALC_INIT_DEFAULT: |
1254 | switch (codec->vendor_id) { | 1409 | alc_auto_setup_eapd(codec, true); |
1255 | case 0x10ec0260: | ||
1256 | set_eapd(codec, 0x0f, 1); | ||
1257 | set_eapd(codec, 0x10, 1); | ||
1258 | break; | ||
1259 | case 0x10ec0262: | ||
1260 | case 0x10ec0267: | ||
1261 | case 0x10ec0268: | ||
1262 | case 0x10ec0269: | ||
1263 | case 0x10ec0270: | ||
1264 | case 0x10ec0272: | ||
1265 | case 0x10ec0660: | ||
1266 | case 0x10ec0662: | ||
1267 | case 0x10ec0663: | ||
1268 | case 0x10ec0665: | ||
1269 | case 0x10ec0862: | ||
1270 | case 0x10ec0889: | ||
1271 | set_eapd(codec, 0x14, 1); | ||
1272 | set_eapd(codec, 0x15, 1); | ||
1273 | break; | ||
1274 | } | ||
1275 | switch (codec->vendor_id) { | 1410 | switch (codec->vendor_id) { |
1276 | case 0x10ec0260: | 1411 | case 0x10ec0260: |
1277 | snd_hda_codec_write(codec, 0x1a, 0, | 1412 | snd_hda_codec_write(codec, 0x1a, 0, |
@@ -1315,20 +1450,128 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) | |||
1315 | } | 1450 | } |
1316 | } | 1451 | } |
1317 | 1452 | ||
1453 | static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, | ||
1454 | struct snd_ctl_elem_info *uinfo) | ||
1455 | { | ||
1456 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1457 | struct alc_spec *spec = codec->spec; | ||
1458 | static const char * const texts2[] = { | ||
1459 | "Disabled", "Enabled" | ||
1460 | }; | ||
1461 | static const char * const texts3[] = { | ||
1462 | "Disabled", "Speaker Only", "Line-Out+Speaker" | ||
1463 | }; | ||
1464 | const char * const *texts; | ||
1465 | |||
1466 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
1467 | uinfo->count = 1; | ||
1468 | if (spec->automute_hp_lo) { | ||
1469 | uinfo->value.enumerated.items = 3; | ||
1470 | texts = texts3; | ||
1471 | } else { | ||
1472 | uinfo->value.enumerated.items = 2; | ||
1473 | texts = texts2; | ||
1474 | } | ||
1475 | if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) | ||
1476 | uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; | ||
1477 | strcpy(uinfo->value.enumerated.name, | ||
1478 | texts[uinfo->value.enumerated.item]); | ||
1479 | return 0; | ||
1480 | } | ||
1481 | |||
1482 | static int alc_automute_mode_get(struct snd_kcontrol *kcontrol, | ||
1483 | struct snd_ctl_elem_value *ucontrol) | ||
1484 | { | ||
1485 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1486 | struct alc_spec *spec = codec->spec; | ||
1487 | unsigned int val; | ||
1488 | if (!spec->automute) | ||
1489 | val = 0; | ||
1490 | else if (!spec->automute_lines) | ||
1491 | val = 1; | ||
1492 | else | ||
1493 | val = 2; | ||
1494 | ucontrol->value.enumerated.item[0] = val; | ||
1495 | return 0; | ||
1496 | } | ||
1497 | |||
1498 | static int alc_automute_mode_put(struct snd_kcontrol *kcontrol, | ||
1499 | struct snd_ctl_elem_value *ucontrol) | ||
1500 | { | ||
1501 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
1502 | struct alc_spec *spec = codec->spec; | ||
1503 | |||
1504 | switch (ucontrol->value.enumerated.item[0]) { | ||
1505 | case 0: | ||
1506 | if (!spec->automute) | ||
1507 | return 0; | ||
1508 | spec->automute = 0; | ||
1509 | break; | ||
1510 | case 1: | ||
1511 | if (spec->automute && !spec->automute_lines) | ||
1512 | return 0; | ||
1513 | spec->automute = 1; | ||
1514 | spec->automute_lines = 0; | ||
1515 | break; | ||
1516 | case 2: | ||
1517 | if (!spec->automute_hp_lo) | ||
1518 | return -EINVAL; | ||
1519 | if (spec->automute && spec->automute_lines) | ||
1520 | return 0; | ||
1521 | spec->automute = 1; | ||
1522 | spec->automute_lines = 1; | ||
1523 | break; | ||
1524 | default: | ||
1525 | return -EINVAL; | ||
1526 | } | ||
1527 | update_speakers(codec); | ||
1528 | return 1; | ||
1529 | } | ||
1530 | |||
1531 | static const struct snd_kcontrol_new alc_automute_mode_enum = { | ||
1532 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
1533 | .name = "Auto-Mute Mode", | ||
1534 | .info = alc_automute_mode_info, | ||
1535 | .get = alc_automute_mode_get, | ||
1536 | .put = alc_automute_mode_put, | ||
1537 | }; | ||
1538 | |||
1539 | static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec); | ||
1540 | |||
1541 | static int alc_add_automute_mode_enum(struct hda_codec *codec) | ||
1542 | { | ||
1543 | struct alc_spec *spec = codec->spec; | ||
1544 | struct snd_kcontrol_new *knew; | ||
1545 | |||
1546 | knew = alc_kcontrol_new(spec); | ||
1547 | if (!knew) | ||
1548 | return -ENOMEM; | ||
1549 | *knew = alc_automute_mode_enum; | ||
1550 | knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL); | ||
1551 | if (!knew->name) | ||
1552 | return -ENOMEM; | ||
1553 | return 0; | ||
1554 | } | ||
1555 | |||
1318 | static void alc_init_auto_hp(struct hda_codec *codec) | 1556 | static void alc_init_auto_hp(struct hda_codec *codec) |
1319 | { | 1557 | { |
1320 | struct alc_spec *spec = codec->spec; | 1558 | struct alc_spec *spec = codec->spec; |
1321 | struct auto_pin_cfg *cfg = &spec->autocfg; | 1559 | struct auto_pin_cfg *cfg = &spec->autocfg; |
1560 | int present = 0; | ||
1322 | int i; | 1561 | int i; |
1323 | 1562 | ||
1324 | if (!cfg->hp_pins[0]) { | 1563 | if (cfg->hp_pins[0]) |
1325 | if (cfg->line_out_type != AUTO_PIN_HP_OUT) | 1564 | present++; |
1326 | return; | 1565 | if (cfg->line_out_pins[0]) |
1327 | } | 1566 | present++; |
1567 | if (cfg->speaker_pins[0]) | ||
1568 | present++; | ||
1569 | if (present < 2) /* need two different output types */ | ||
1570 | return; | ||
1571 | if (present == 3) | ||
1572 | spec->automute_hp_lo = 1; /* both HP and LO automute */ | ||
1328 | 1573 | ||
1329 | if (!cfg->speaker_pins[0]) { | 1574 | if (!cfg->speaker_pins[0]) { |
1330 | if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) | ||
1331 | return; | ||
1332 | memcpy(cfg->speaker_pins, cfg->line_out_pins, | 1575 | memcpy(cfg->speaker_pins, cfg->line_out_pins, |
1333 | sizeof(cfg->speaker_pins)); | 1576 | sizeof(cfg->speaker_pins)); |
1334 | cfg->speaker_outs = cfg->line_outs; | 1577 | cfg->speaker_outs = cfg->line_outs; |
@@ -1341,28 +1584,49 @@ static void alc_init_auto_hp(struct hda_codec *codec) | |||
1341 | } | 1584 | } |
1342 | 1585 | ||
1343 | for (i = 0; i < cfg->hp_outs; i++) { | 1586 | for (i = 0; i < cfg->hp_outs; i++) { |
1587 | hda_nid_t nid = cfg->hp_pins[i]; | ||
1588 | if (!is_jack_detectable(codec, nid)) | ||
1589 | continue; | ||
1344 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", | 1590 | snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", |
1345 | cfg->hp_pins[i]); | 1591 | nid); |
1346 | snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0, | 1592 | snd_hda_codec_write_cache(codec, nid, 0, |
1347 | AC_VERB_SET_UNSOLICITED_ENABLE, | 1593 | AC_VERB_SET_UNSOLICITED_ENABLE, |
1348 | AC_USRSP_EN | ALC880_HP_EVENT); | 1594 | AC_USRSP_EN | ALC880_HP_EVENT); |
1595 | spec->automute = 1; | ||
1596 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
1597 | } | ||
1598 | if (spec->automute && cfg->line_out_pins[0] && | ||
1599 | cfg->line_out_pins[0] != cfg->hp_pins[0] && | ||
1600 | cfg->line_out_pins[0] != cfg->speaker_pins[0]) { | ||
1601 | for (i = 0; i < cfg->line_outs; i++) { | ||
1602 | hda_nid_t nid = cfg->line_out_pins[i]; | ||
1603 | if (!is_jack_detectable(codec, nid)) | ||
1604 | continue; | ||
1605 | snd_printdd("realtek: Enable Line-Out auto-muting " | ||
1606 | "on NID 0x%x\n", nid); | ||
1607 | snd_hda_codec_write_cache(codec, nid, 0, | ||
1608 | AC_VERB_SET_UNSOLICITED_ENABLE, | ||
1609 | AC_USRSP_EN | ALC880_FRONT_EVENT); | ||
1610 | spec->detect_line = 1; | ||
1611 | } | ||
1612 | spec->automute_lines = spec->detect_line; | ||
1613 | } | ||
1614 | |||
1615 | if (spec->automute) { | ||
1616 | /* create a control for automute mode */ | ||
1617 | alc_add_automute_mode_enum(codec); | ||
1618 | spec->unsol_event = alc_sku_unsol_event; | ||
1349 | } | 1619 | } |
1350 | spec->unsol_event = alc_sku_unsol_event; | ||
1351 | } | 1620 | } |
1352 | 1621 | ||
1353 | static void alc_init_auto_mic(struct hda_codec *codec) | 1622 | static void alc_init_auto_mic(struct hda_codec *codec) |
1354 | { | 1623 | { |
1355 | struct alc_spec *spec = codec->spec; | 1624 | struct alc_spec *spec = codec->spec; |
1356 | struct auto_pin_cfg *cfg = &spec->autocfg; | 1625 | struct auto_pin_cfg *cfg = &spec->autocfg; |
1357 | hda_nid_t fixed, ext; | 1626 | hda_nid_t fixed, ext, dock; |
1358 | int i; | 1627 | int i; |
1359 | 1628 | ||
1360 | /* there must be only two mic inputs exclusively */ | 1629 | fixed = ext = dock = 0; |
1361 | for (i = 0; i < cfg->num_inputs; i++) | ||
1362 | if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) | ||
1363 | return; | ||
1364 | |||
1365 | fixed = ext = 0; | ||
1366 | for (i = 0; i < cfg->num_inputs; i++) { | 1630 | for (i = 0; i < cfg->num_inputs; i++) { |
1367 | hda_nid_t nid = cfg->inputs[i].pin; | 1631 | hda_nid_t nid = cfg->inputs[i].pin; |
1368 | unsigned int defcfg; | 1632 | unsigned int defcfg; |
@@ -1371,26 +1635,45 @@ static void alc_init_auto_mic(struct hda_codec *codec) | |||
1371 | case INPUT_PIN_ATTR_INT: | 1635 | case INPUT_PIN_ATTR_INT: |
1372 | if (fixed) | 1636 | if (fixed) |
1373 | return; /* already occupied */ | 1637 | return; /* already occupied */ |
1638 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | ||
1639 | return; /* invalid type */ | ||
1374 | fixed = nid; | 1640 | fixed = nid; |
1375 | break; | 1641 | break; |
1376 | case INPUT_PIN_ATTR_UNUSED: | 1642 | case INPUT_PIN_ATTR_UNUSED: |
1377 | return; /* invalid entry */ | 1643 | return; /* invalid entry */ |
1644 | case INPUT_PIN_ATTR_DOCK: | ||
1645 | if (dock) | ||
1646 | return; /* already occupied */ | ||
1647 | if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) | ||
1648 | return; /* invalid type */ | ||
1649 | dock = nid; | ||
1650 | break; | ||
1378 | default: | 1651 | default: |
1379 | if (ext) | 1652 | if (ext) |
1380 | return; /* already occupied */ | 1653 | return; /* already occupied */ |
1654 | if (cfg->inputs[i].type != AUTO_PIN_MIC) | ||
1655 | return; /* invalid type */ | ||
1381 | ext = nid; | 1656 | ext = nid; |
1382 | break; | 1657 | break; |
1383 | } | 1658 | } |
1384 | } | 1659 | } |
1660 | if (!ext && dock) { | ||
1661 | ext = dock; | ||
1662 | dock = 0; | ||
1663 | } | ||
1385 | if (!ext || !fixed) | 1664 | if (!ext || !fixed) |
1386 | return; | 1665 | return; |
1387 | if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) | 1666 | if (!is_jack_detectable(codec, ext)) |
1388 | return; /* no unsol support */ | 1667 | return; /* no unsol support */ |
1389 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", | 1668 | if (dock && !is_jack_detectable(codec, dock)) |
1390 | ext, fixed); | 1669 | return; /* no unsol support */ |
1670 | snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", | ||
1671 | ext, fixed, dock); | ||
1391 | spec->ext_mic.pin = ext; | 1672 | spec->ext_mic.pin = ext; |
1673 | spec->dock_mic.pin = dock; | ||
1392 | spec->int_mic.pin = fixed; | 1674 | spec->int_mic.pin = fixed; |
1393 | spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ | 1675 | spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ |
1676 | spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ | ||
1394 | spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ | 1677 | spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ |
1395 | spec->auto_mic = 1; | 1678 | spec->auto_mic = 1; |
1396 | snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, | 1679 | snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, |
@@ -1583,9 +1866,6 @@ do_sku: | |||
1583 | return 1; | 1866 | return 1; |
1584 | spec->autocfg.hp_pins[0] = nid; | 1867 | spec->autocfg.hp_pins[0] = nid; |
1585 | } | 1868 | } |
1586 | |||
1587 | alc_init_auto_hp(codec); | ||
1588 | alc_init_auto_mic(codec); | ||
1589 | return 1; | 1869 | return 1; |
1590 | } | 1870 | } |
1591 | 1871 | ||
@@ -1598,9 +1878,10 @@ static void alc_ssid_check(struct hda_codec *codec, | |||
1598 | snd_printd("realtek: " | 1878 | snd_printd("realtek: " |
1599 | "Enable default setup for auto mode as fallback\n"); | 1879 | "Enable default setup for auto mode as fallback\n"); |
1600 | spec->init_amp = ALC_INIT_DEFAULT; | 1880 | spec->init_amp = ALC_INIT_DEFAULT; |
1601 | alc_init_auto_hp(codec); | ||
1602 | alc_init_auto_mic(codec); | ||
1603 | } | 1881 | } |
1882 | |||
1883 | alc_init_auto_hp(codec); | ||
1884 | alc_init_auto_mic(codec); | ||
1604 | } | 1885 | } |
1605 | 1886 | ||
1606 | /* | 1887 | /* |
@@ -1704,11 +1985,11 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) | |||
1704 | codec->chip_name, fix->type); | 1985 | codec->chip_name, fix->type); |
1705 | break; | 1986 | break; |
1706 | } | 1987 | } |
1707 | if (!fix[id].chained) | 1988 | if (!fix->chained) |
1708 | break; | 1989 | break; |
1709 | if (++depth > 10) | 1990 | if (++depth > 10) |
1710 | break; | 1991 | break; |
1711 | id = fix[id].chain_id; | 1992 | id = fix->chain_id; |
1712 | } | 1993 | } |
1713 | } | 1994 | } |
1714 | 1995 | ||
@@ -1842,7 +2123,7 @@ static void alc_auto_parse_digital(struct hda_codec *codec) | |||
1842 | /* | 2123 | /* |
1843 | * 2ch mode | 2124 | * 2ch mode |
1844 | */ | 2125 | */ |
1845 | static struct hda_verb alc888_4ST_ch2_intel_init[] = { | 2126 | static const struct hda_verb alc888_4ST_ch2_intel_init[] = { |
1846 | /* Mic-in jack as mic in */ | 2127 | /* Mic-in jack as mic in */ |
1847 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 2128 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
1848 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 2129 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
@@ -1857,7 +2138,7 @@ static struct hda_verb alc888_4ST_ch2_intel_init[] = { | |||
1857 | /* | 2138 | /* |
1858 | * 4ch mode | 2139 | * 4ch mode |
1859 | */ | 2140 | */ |
1860 | static struct hda_verb alc888_4ST_ch4_intel_init[] = { | 2141 | static const struct hda_verb alc888_4ST_ch4_intel_init[] = { |
1861 | /* Mic-in jack as mic in */ | 2142 | /* Mic-in jack as mic in */ |
1862 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 2143 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
1863 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 2144 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
@@ -1872,7 +2153,7 @@ static struct hda_verb alc888_4ST_ch4_intel_init[] = { | |||
1872 | /* | 2153 | /* |
1873 | * 6ch mode | 2154 | * 6ch mode |
1874 | */ | 2155 | */ |
1875 | static struct hda_verb alc888_4ST_ch6_intel_init[] = { | 2156 | static const struct hda_verb alc888_4ST_ch6_intel_init[] = { |
1876 | /* Mic-in jack as CLFE */ | 2157 | /* Mic-in jack as CLFE */ |
1877 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 2158 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
1878 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 2159 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
@@ -1887,7 +2168,7 @@ static struct hda_verb alc888_4ST_ch6_intel_init[] = { | |||
1887 | /* | 2168 | /* |
1888 | * 8ch mode | 2169 | * 8ch mode |
1889 | */ | 2170 | */ |
1890 | static struct hda_verb alc888_4ST_ch8_intel_init[] = { | 2171 | static const struct hda_verb alc888_4ST_ch8_intel_init[] = { |
1891 | /* Mic-in jack as CLFE */ | 2172 | /* Mic-in jack as CLFE */ |
1892 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 2173 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
1893 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 2174 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
@@ -1899,7 +2180,7 @@ static struct hda_verb alc888_4ST_ch8_intel_init[] = { | |||
1899 | { } /* end */ | 2180 | { } /* end */ |
1900 | }; | 2181 | }; |
1901 | 2182 | ||
1902 | static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { | 2183 | static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { |
1903 | { 2, alc888_4ST_ch2_intel_init }, | 2184 | { 2, alc888_4ST_ch2_intel_init }, |
1904 | { 4, alc888_4ST_ch4_intel_init }, | 2185 | { 4, alc888_4ST_ch4_intel_init }, |
1905 | { 6, alc888_4ST_ch6_intel_init }, | 2186 | { 6, alc888_4ST_ch6_intel_init }, |
@@ -1910,7 +2191,7 @@ static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { | |||
1910 | * ALC888 Fujitsu Siemens Amillo xa3530 | 2191 | * ALC888 Fujitsu Siemens Amillo xa3530 |
1911 | */ | 2192 | */ |
1912 | 2193 | ||
1913 | static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { | 2194 | static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = { |
1914 | /* Front Mic: set to PIN_IN (empty by default) */ | 2195 | /* Front Mic: set to PIN_IN (empty by default) */ |
1915 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 2196 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
1916 | /* Connect Internal HP to Front */ | 2197 | /* Connect Internal HP to Front */ |
@@ -1943,22 +2224,6 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { | |||
1943 | {} | 2224 | {} |
1944 | }; | 2225 | }; |
1945 | 2226 | ||
1946 | static void alc_automute_amp(struct hda_codec *codec) | ||
1947 | { | ||
1948 | alc_automute_speaker(codec, 0); | ||
1949 | } | ||
1950 | |||
1951 | static void alc_automute_amp_unsol_event(struct hda_codec *codec, | ||
1952 | unsigned int res) | ||
1953 | { | ||
1954 | if (codec->vendor_id == 0x10ec0880) | ||
1955 | res >>= 28; | ||
1956 | else | ||
1957 | res >>= 26; | ||
1958 | if (res == ALC880_HP_EVENT) | ||
1959 | alc_automute_amp(codec); | ||
1960 | } | ||
1961 | |||
1962 | static void alc889_automute_setup(struct hda_codec *codec) | 2227 | static void alc889_automute_setup(struct hda_codec *codec) |
1963 | { | 2228 | { |
1964 | struct alc_spec *spec = codec->spec; | 2229 | struct alc_spec *spec = codec->spec; |
@@ -1969,12 +2234,14 @@ static void alc889_automute_setup(struct hda_codec *codec) | |||
1969 | spec->autocfg.speaker_pins[2] = 0x17; | 2234 | spec->autocfg.speaker_pins[2] = 0x17; |
1970 | spec->autocfg.speaker_pins[3] = 0x19; | 2235 | spec->autocfg.speaker_pins[3] = 0x19; |
1971 | spec->autocfg.speaker_pins[4] = 0x1a; | 2236 | spec->autocfg.speaker_pins[4] = 0x1a; |
2237 | spec->automute = 1; | ||
2238 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
1972 | } | 2239 | } |
1973 | 2240 | ||
1974 | static void alc889_intel_init_hook(struct hda_codec *codec) | 2241 | static void alc889_intel_init_hook(struct hda_codec *codec) |
1975 | { | 2242 | { |
1976 | alc889_coef_init(codec); | 2243 | alc889_coef_init(codec); |
1977 | alc_automute_amp(codec); | 2244 | alc_hp_automute(codec); |
1978 | } | 2245 | } |
1979 | 2246 | ||
1980 | static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) | 2247 | static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) |
@@ -1985,13 +2252,15 @@ static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) | |||
1985 | spec->autocfg.hp_pins[1] = 0x1b; /* hp */ | 2252 | spec->autocfg.hp_pins[1] = 0x1b; /* hp */ |
1986 | spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ | 2253 | spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ |
1987 | spec->autocfg.speaker_pins[1] = 0x15; /* bass */ | 2254 | spec->autocfg.speaker_pins[1] = 0x15; /* bass */ |
2255 | spec->automute = 1; | ||
2256 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
1988 | } | 2257 | } |
1989 | 2258 | ||
1990 | /* | 2259 | /* |
1991 | * ALC888 Acer Aspire 4930G model | 2260 | * ALC888 Acer Aspire 4930G model |
1992 | */ | 2261 | */ |
1993 | 2262 | ||
1994 | static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { | 2263 | static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = { |
1995 | /* Front Mic: set to PIN_IN (empty by default) */ | 2264 | /* Front Mic: set to PIN_IN (empty by default) */ |
1996 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 2265 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
1997 | /* Unselect Front Mic by default in input mixer 3 */ | 2266 | /* Unselect Front Mic by default in input mixer 3 */ |
@@ -2014,7 +2283,7 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { | |||
2014 | * ALC888 Acer Aspire 6530G model | 2283 | * ALC888 Acer Aspire 6530G model |
2015 | */ | 2284 | */ |
2016 | 2285 | ||
2017 | static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { | 2286 | static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = { |
2018 | /* Route to built-in subwoofer as well as speakers */ | 2287 | /* Route to built-in subwoofer as well as speakers */ |
2019 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 2288 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
2020 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 2289 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -2044,7 +2313,7 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { | |||
2044 | *ALC888 Acer Aspire 7730G model | 2313 | *ALC888 Acer Aspire 7730G model |
2045 | */ | 2314 | */ |
2046 | 2315 | ||
2047 | static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { | 2316 | static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = { |
2048 | /* Bias voltage on for external mic port */ | 2317 | /* Bias voltage on for external mic port */ |
2049 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, | 2318 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, |
2050 | /* Front Mic: set to PIN_IN (empty by default) */ | 2319 | /* Front Mic: set to PIN_IN (empty by default) */ |
@@ -2074,7 +2343,7 @@ static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { | |||
2074 | * ALC889 Acer Aspire 8930G model | 2343 | * ALC889 Acer Aspire 8930G model |
2075 | */ | 2344 | */ |
2076 | 2345 | ||
2077 | static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { | 2346 | static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = { |
2078 | /* Front Mic: set to PIN_IN (empty by default) */ | 2347 | /* Front Mic: set to PIN_IN (empty by default) */ |
2079 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 2348 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
2080 | /* Unselect Front Mic by default in input mixer 3 */ | 2349 | /* Unselect Front Mic by default in input mixer 3 */ |
@@ -2120,7 +2389,7 @@ static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { | |||
2120 | { } | 2389 | { } |
2121 | }; | 2390 | }; |
2122 | 2391 | ||
2123 | static struct hda_input_mux alc888_2_capture_sources[2] = { | 2392 | static const struct hda_input_mux alc888_2_capture_sources[2] = { |
2124 | /* Front mic only available on one ADC */ | 2393 | /* Front mic only available on one ADC */ |
2125 | { | 2394 | { |
2126 | .num_items = 4, | 2395 | .num_items = 4, |
@@ -2141,7 +2410,7 @@ static struct hda_input_mux alc888_2_capture_sources[2] = { | |||
2141 | } | 2410 | } |
2142 | }; | 2411 | }; |
2143 | 2412 | ||
2144 | static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { | 2413 | static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { |
2145 | /* Interal mic only available on one ADC */ | 2414 | /* Interal mic only available on one ADC */ |
2146 | { | 2415 | { |
2147 | .num_items = 5, | 2416 | .num_items = 5, |
@@ -2164,7 +2433,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { | |||
2164 | } | 2433 | } |
2165 | }; | 2434 | }; |
2166 | 2435 | ||
2167 | static struct hda_input_mux alc889_capture_sources[3] = { | 2436 | static const struct hda_input_mux alc889_capture_sources[3] = { |
2168 | /* Digital mic only available on first "ADC" */ | 2437 | /* Digital mic only available on first "ADC" */ |
2169 | { | 2438 | { |
2170 | .num_items = 5, | 2439 | .num_items = 5, |
@@ -2196,7 +2465,7 @@ static struct hda_input_mux alc889_capture_sources[3] = { | |||
2196 | } | 2465 | } |
2197 | }; | 2466 | }; |
2198 | 2467 | ||
2199 | static struct snd_kcontrol_new alc888_base_mixer[] = { | 2468 | static const struct snd_kcontrol_new alc888_base_mixer[] = { |
2200 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2469 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2201 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2470 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
2202 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 2471 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2218,7 +2487,7 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { | |||
2218 | { } /* end */ | 2487 | { } /* end */ |
2219 | }; | 2488 | }; |
2220 | 2489 | ||
2221 | static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { | 2490 | static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { |
2222 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2491 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2223 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2492 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
2224 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 2493 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2240,7 +2509,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { | |||
2240 | { } /* end */ | 2509 | { } /* end */ |
2241 | }; | 2510 | }; |
2242 | 2511 | ||
2243 | static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { | 2512 | static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { |
2244 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2513 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2245 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2514 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
2246 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 2515 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2267,6 +2536,8 @@ static void alc888_acer_aspire_4930g_setup(struct hda_codec *codec) | |||
2267 | spec->autocfg.speaker_pins[0] = 0x14; | 2536 | spec->autocfg.speaker_pins[0] = 0x14; |
2268 | spec->autocfg.speaker_pins[1] = 0x16; | 2537 | spec->autocfg.speaker_pins[1] = 0x16; |
2269 | spec->autocfg.speaker_pins[2] = 0x17; | 2538 | spec->autocfg.speaker_pins[2] = 0x17; |
2539 | spec->automute = 1; | ||
2540 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
2270 | } | 2541 | } |
2271 | 2542 | ||
2272 | static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) | 2543 | static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) |
@@ -2277,6 +2548,8 @@ static void alc888_acer_aspire_6530g_setup(struct hda_codec *codec) | |||
2277 | spec->autocfg.speaker_pins[0] = 0x14; | 2548 | spec->autocfg.speaker_pins[0] = 0x14; |
2278 | spec->autocfg.speaker_pins[1] = 0x16; | 2549 | spec->autocfg.speaker_pins[1] = 0x16; |
2279 | spec->autocfg.speaker_pins[2] = 0x17; | 2550 | spec->autocfg.speaker_pins[2] = 0x17; |
2551 | spec->automute = 1; | ||
2552 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
2280 | } | 2553 | } |
2281 | 2554 | ||
2282 | static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) | 2555 | static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) |
@@ -2287,6 +2560,8 @@ static void alc888_acer_aspire_7730g_setup(struct hda_codec *codec) | |||
2287 | spec->autocfg.speaker_pins[0] = 0x14; | 2560 | spec->autocfg.speaker_pins[0] = 0x14; |
2288 | spec->autocfg.speaker_pins[1] = 0x16; | 2561 | spec->autocfg.speaker_pins[1] = 0x16; |
2289 | spec->autocfg.speaker_pins[2] = 0x17; | 2562 | spec->autocfg.speaker_pins[2] = 0x17; |
2563 | spec->automute = 1; | ||
2564 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
2290 | } | 2565 | } |
2291 | 2566 | ||
2292 | static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) | 2567 | static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) |
@@ -2297,6 +2572,8 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) | |||
2297 | spec->autocfg.speaker_pins[0] = 0x14; | 2572 | spec->autocfg.speaker_pins[0] = 0x14; |
2298 | spec->autocfg.speaker_pins[1] = 0x16; | 2573 | spec->autocfg.speaker_pins[1] = 0x16; |
2299 | spec->autocfg.speaker_pins[2] = 0x1b; | 2574 | spec->autocfg.speaker_pins[2] = 0x1b; |
2575 | spec->automute = 1; | ||
2576 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
2300 | } | 2577 | } |
2301 | 2578 | ||
2302 | /* | 2579 | /* |
@@ -2307,12 +2584,12 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) | |||
2307 | * F-Mic = 0x1b, HP = 0x19 | 2584 | * F-Mic = 0x1b, HP = 0x19 |
2308 | */ | 2585 | */ |
2309 | 2586 | ||
2310 | static hda_nid_t alc880_dac_nids[4] = { | 2587 | static const hda_nid_t alc880_dac_nids[4] = { |
2311 | /* front, rear, clfe, rear_surr */ | 2588 | /* front, rear, clfe, rear_surr */ |
2312 | 0x02, 0x05, 0x04, 0x03 | 2589 | 0x02, 0x05, 0x04, 0x03 |
2313 | }; | 2590 | }; |
2314 | 2591 | ||
2315 | static hda_nid_t alc880_adc_nids[3] = { | 2592 | static const hda_nid_t alc880_adc_nids[3] = { |
2316 | /* ADC0-2 */ | 2593 | /* ADC0-2 */ |
2317 | 0x07, 0x08, 0x09, | 2594 | 0x07, 0x08, 0x09, |
2318 | }; | 2595 | }; |
@@ -2321,7 +2598,7 @@ static hda_nid_t alc880_adc_nids[3] = { | |||
2321 | * but it shows zero connection in the real implementation on some devices. | 2598 | * but it shows zero connection in the real implementation on some devices. |
2322 | * Note: this is a 915GAV bug, fixed on 915GLV | 2599 | * Note: this is a 915GAV bug, fixed on 915GLV |
2323 | */ | 2600 | */ |
2324 | static hda_nid_t alc880_adc_nids_alt[2] = { | 2601 | static const hda_nid_t alc880_adc_nids_alt[2] = { |
2325 | /* ADC1-2 */ | 2602 | /* ADC1-2 */ |
2326 | 0x08, 0x09, | 2603 | 0x08, 0x09, |
2327 | }; | 2604 | }; |
@@ -2329,7 +2606,7 @@ static hda_nid_t alc880_adc_nids_alt[2] = { | |||
2329 | #define ALC880_DIGOUT_NID 0x06 | 2606 | #define ALC880_DIGOUT_NID 0x06 |
2330 | #define ALC880_DIGIN_NID 0x0a | 2607 | #define ALC880_DIGIN_NID 0x0a |
2331 | 2608 | ||
2332 | static struct hda_input_mux alc880_capture_source = { | 2609 | static const struct hda_input_mux alc880_capture_source = { |
2333 | .num_items = 4, | 2610 | .num_items = 4, |
2334 | .items = { | 2611 | .items = { |
2335 | { "Mic", 0x0 }, | 2612 | { "Mic", 0x0 }, |
@@ -2341,7 +2618,7 @@ static struct hda_input_mux alc880_capture_source = { | |||
2341 | 2618 | ||
2342 | /* channel source setting (2/6 channel selection for 3-stack) */ | 2619 | /* channel source setting (2/6 channel selection for 3-stack) */ |
2343 | /* 2ch mode */ | 2620 | /* 2ch mode */ |
2344 | static struct hda_verb alc880_threestack_ch2_init[] = { | 2621 | static const struct hda_verb alc880_threestack_ch2_init[] = { |
2345 | /* set line-in to input, mute it */ | 2622 | /* set line-in to input, mute it */ |
2346 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 2623 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
2347 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 2624 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
@@ -2352,7 +2629,7 @@ static struct hda_verb alc880_threestack_ch2_init[] = { | |||
2352 | }; | 2629 | }; |
2353 | 2630 | ||
2354 | /* 6ch mode */ | 2631 | /* 6ch mode */ |
2355 | static struct hda_verb alc880_threestack_ch6_init[] = { | 2632 | static const struct hda_verb alc880_threestack_ch6_init[] = { |
2356 | /* set line-in to output, unmute it */ | 2633 | /* set line-in to output, unmute it */ |
2357 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 2634 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
2358 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 2635 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
@@ -2362,12 +2639,12 @@ static struct hda_verb alc880_threestack_ch6_init[] = { | |||
2362 | { } /* end */ | 2639 | { } /* end */ |
2363 | }; | 2640 | }; |
2364 | 2641 | ||
2365 | static struct hda_channel_mode alc880_threestack_modes[2] = { | 2642 | static const struct hda_channel_mode alc880_threestack_modes[2] = { |
2366 | { 2, alc880_threestack_ch2_init }, | 2643 | { 2, alc880_threestack_ch2_init }, |
2367 | { 6, alc880_threestack_ch6_init }, | 2644 | { 6, alc880_threestack_ch6_init }, |
2368 | }; | 2645 | }; |
2369 | 2646 | ||
2370 | static struct snd_kcontrol_new alc880_three_stack_mixer[] = { | 2647 | static const struct snd_kcontrol_new alc880_three_stack_mixer[] = { |
2371 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2648 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2372 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2649 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
2373 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 2650 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
@@ -2512,14 +2789,14 @@ static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, | |||
2512 | } | 2789 | } |
2513 | 2790 | ||
2514 | #define DEFINE_CAPMIX(num) \ | 2791 | #define DEFINE_CAPMIX(num) \ |
2515 | static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ | 2792 | static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ |
2516 | _DEFINE_CAPMIX(num), \ | 2793 | _DEFINE_CAPMIX(num), \ |
2517 | _DEFINE_CAPSRC(num), \ | 2794 | _DEFINE_CAPSRC(num), \ |
2518 | { } /* end */ \ | 2795 | { } /* end */ \ |
2519 | } | 2796 | } |
2520 | 2797 | ||
2521 | #define DEFINE_CAPMIX_NOSRC(num) \ | 2798 | #define DEFINE_CAPMIX_NOSRC(num) \ |
2522 | static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ | 2799 | static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ |
2523 | _DEFINE_CAPMIX(num), \ | 2800 | _DEFINE_CAPMIX(num), \ |
2524 | { } /* end */ \ | 2801 | { } /* end */ \ |
2525 | } | 2802 | } |
@@ -2542,7 +2819,7 @@ DEFINE_CAPMIX_NOSRC(3); | |||
2542 | */ | 2819 | */ |
2543 | 2820 | ||
2544 | /* additional mixers to alc880_three_stack_mixer */ | 2821 | /* additional mixers to alc880_three_stack_mixer */ |
2545 | static struct snd_kcontrol_new alc880_five_stack_mixer[] = { | 2822 | static const struct snd_kcontrol_new alc880_five_stack_mixer[] = { |
2546 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 2823 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
2547 | HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), | 2824 | HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), |
2548 | { } /* end */ | 2825 | { } /* end */ |
@@ -2550,7 +2827,7 @@ static struct snd_kcontrol_new alc880_five_stack_mixer[] = { | |||
2550 | 2827 | ||
2551 | /* channel source setting (6/8 channel selection for 5-stack) */ | 2828 | /* channel source setting (6/8 channel selection for 5-stack) */ |
2552 | /* 6ch mode */ | 2829 | /* 6ch mode */ |
2553 | static struct hda_verb alc880_fivestack_ch6_init[] = { | 2830 | static const struct hda_verb alc880_fivestack_ch6_init[] = { |
2554 | /* set line-in to input, mute it */ | 2831 | /* set line-in to input, mute it */ |
2555 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 2832 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
2556 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 2833 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
@@ -2558,14 +2835,14 @@ static struct hda_verb alc880_fivestack_ch6_init[] = { | |||
2558 | }; | 2835 | }; |
2559 | 2836 | ||
2560 | /* 8ch mode */ | 2837 | /* 8ch mode */ |
2561 | static struct hda_verb alc880_fivestack_ch8_init[] = { | 2838 | static const struct hda_verb alc880_fivestack_ch8_init[] = { |
2562 | /* set line-in to output, unmute it */ | 2839 | /* set line-in to output, unmute it */ |
2563 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 2840 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
2564 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 2841 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
2565 | { } /* end */ | 2842 | { } /* end */ |
2566 | }; | 2843 | }; |
2567 | 2844 | ||
2568 | static struct hda_channel_mode alc880_fivestack_modes[2] = { | 2845 | static const struct hda_channel_mode alc880_fivestack_modes[2] = { |
2569 | { 6, alc880_fivestack_ch6_init }, | 2846 | { 6, alc880_fivestack_ch6_init }, |
2570 | { 8, alc880_fivestack_ch8_init }, | 2847 | { 8, alc880_fivestack_ch8_init }, |
2571 | }; | 2848 | }; |
@@ -2580,12 +2857,12 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = { | |||
2580 | * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b | 2857 | * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b |
2581 | */ | 2858 | */ |
2582 | 2859 | ||
2583 | static hda_nid_t alc880_6st_dac_nids[4] = { | 2860 | static const hda_nid_t alc880_6st_dac_nids[4] = { |
2584 | /* front, rear, clfe, rear_surr */ | 2861 | /* front, rear, clfe, rear_surr */ |
2585 | 0x02, 0x03, 0x04, 0x05 | 2862 | 0x02, 0x03, 0x04, 0x05 |
2586 | }; | 2863 | }; |
2587 | 2864 | ||
2588 | static struct hda_input_mux alc880_6stack_capture_source = { | 2865 | static const struct hda_input_mux alc880_6stack_capture_source = { |
2589 | .num_items = 4, | 2866 | .num_items = 4, |
2590 | .items = { | 2867 | .items = { |
2591 | { "Mic", 0x0 }, | 2868 | { "Mic", 0x0 }, |
@@ -2596,11 +2873,11 @@ static struct hda_input_mux alc880_6stack_capture_source = { | |||
2596 | }; | 2873 | }; |
2597 | 2874 | ||
2598 | /* fixed 8-channels */ | 2875 | /* fixed 8-channels */ |
2599 | static struct hda_channel_mode alc880_sixstack_modes[1] = { | 2876 | static const struct hda_channel_mode alc880_sixstack_modes[1] = { |
2600 | { 8, NULL }, | 2877 | { 8, NULL }, |
2601 | }; | 2878 | }; |
2602 | 2879 | ||
2603 | static struct snd_kcontrol_new alc880_six_stack_mixer[] = { | 2880 | static const struct snd_kcontrol_new alc880_six_stack_mixer[] = { |
2604 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2881 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2605 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2882 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
2606 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 2883 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2655,18 +2932,18 @@ static struct snd_kcontrol_new alc880_six_stack_mixer[] = { | |||
2655 | * haven't setup any initialization verbs for these yet... | 2932 | * haven't setup any initialization verbs for these yet... |
2656 | */ | 2933 | */ |
2657 | 2934 | ||
2658 | static hda_nid_t alc880_w810_dac_nids[3] = { | 2935 | static const hda_nid_t alc880_w810_dac_nids[3] = { |
2659 | /* front, rear/surround, clfe */ | 2936 | /* front, rear/surround, clfe */ |
2660 | 0x02, 0x03, 0x04 | 2937 | 0x02, 0x03, 0x04 |
2661 | }; | 2938 | }; |
2662 | 2939 | ||
2663 | /* fixed 6 channels */ | 2940 | /* fixed 6 channels */ |
2664 | static struct hda_channel_mode alc880_w810_modes[1] = { | 2941 | static const struct hda_channel_mode alc880_w810_modes[1] = { |
2665 | { 6, NULL } | 2942 | { 6, NULL } |
2666 | }; | 2943 | }; |
2667 | 2944 | ||
2668 | /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ | 2945 | /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ |
2669 | static struct snd_kcontrol_new alc880_w810_base_mixer[] = { | 2946 | static const struct snd_kcontrol_new alc880_w810_base_mixer[] = { |
2670 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2947 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2671 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2948 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
2672 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 2949 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2688,17 +2965,17 @@ static struct snd_kcontrol_new alc880_w810_base_mixer[] = { | |||
2688 | * Line = 0x1a | 2965 | * Line = 0x1a |
2689 | */ | 2966 | */ |
2690 | 2967 | ||
2691 | static hda_nid_t alc880_z71v_dac_nids[1] = { | 2968 | static const hda_nid_t alc880_z71v_dac_nids[1] = { |
2692 | 0x02 | 2969 | 0x02 |
2693 | }; | 2970 | }; |
2694 | #define ALC880_Z71V_HP_DAC 0x03 | 2971 | #define ALC880_Z71V_HP_DAC 0x03 |
2695 | 2972 | ||
2696 | /* fixed 2 channels */ | 2973 | /* fixed 2 channels */ |
2697 | static struct hda_channel_mode alc880_2_jack_modes[1] = { | 2974 | static const struct hda_channel_mode alc880_2_jack_modes[1] = { |
2698 | { 2, NULL } | 2975 | { 2, NULL } |
2699 | }; | 2976 | }; |
2700 | 2977 | ||
2701 | static struct snd_kcontrol_new alc880_z71v_mixer[] = { | 2978 | static const struct snd_kcontrol_new alc880_z71v_mixer[] = { |
2702 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 2979 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2703 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 2980 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
2704 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 2981 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2718,12 +2995,12 @@ static struct snd_kcontrol_new alc880_z71v_mixer[] = { | |||
2718 | * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 | 2995 | * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 |
2719 | */ | 2996 | */ |
2720 | 2997 | ||
2721 | static hda_nid_t alc880_f1734_dac_nids[1] = { | 2998 | static const hda_nid_t alc880_f1734_dac_nids[1] = { |
2722 | 0x03 | 2999 | 0x03 |
2723 | }; | 3000 | }; |
2724 | #define ALC880_F1734_HP_DAC 0x02 | 3001 | #define ALC880_F1734_HP_DAC 0x02 |
2725 | 3002 | ||
2726 | static struct snd_kcontrol_new alc880_f1734_mixer[] = { | 3003 | static const struct snd_kcontrol_new alc880_f1734_mixer[] = { |
2727 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 3004 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2728 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | 3005 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
2729 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 3006 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2735,7 +3012,7 @@ static struct snd_kcontrol_new alc880_f1734_mixer[] = { | |||
2735 | { } /* end */ | 3012 | { } /* end */ |
2736 | }; | 3013 | }; |
2737 | 3014 | ||
2738 | static struct hda_input_mux alc880_f1734_capture_source = { | 3015 | static const struct hda_input_mux alc880_f1734_capture_source = { |
2739 | .num_items = 2, | 3016 | .num_items = 2, |
2740 | .items = { | 3017 | .items = { |
2741 | { "Mic", 0x1 }, | 3018 | { "Mic", 0x1 }, |
@@ -2755,7 +3032,7 @@ static struct hda_input_mux alc880_f1734_capture_source = { | |||
2755 | #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ | 3032 | #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ |
2756 | #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ | 3033 | #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ |
2757 | 3034 | ||
2758 | static struct snd_kcontrol_new alc880_asus_mixer[] = { | 3035 | static const struct snd_kcontrol_new alc880_asus_mixer[] = { |
2759 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 3036 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2760 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 3037 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
2761 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 3038 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2789,14 +3066,14 @@ static struct snd_kcontrol_new alc880_asus_mixer[] = { | |||
2789 | */ | 3066 | */ |
2790 | 3067 | ||
2791 | /* additional mixers to alc880_asus_mixer */ | 3068 | /* additional mixers to alc880_asus_mixer */ |
2792 | static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { | 3069 | static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { |
2793 | HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), | 3070 | HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), |
2794 | HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), | 3071 | HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), |
2795 | { } /* end */ | 3072 | { } /* end */ |
2796 | }; | 3073 | }; |
2797 | 3074 | ||
2798 | /* TCL S700 */ | 3075 | /* TCL S700 */ |
2799 | static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { | 3076 | static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { |
2800 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 3077 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2801 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 3078 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
2802 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 3079 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -2810,7 +3087,7 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { | |||
2810 | }; | 3087 | }; |
2811 | 3088 | ||
2812 | /* Uniwill */ | 3089 | /* Uniwill */ |
2813 | static struct snd_kcontrol_new alc880_uniwill_mixer[] = { | 3090 | static const struct snd_kcontrol_new alc880_uniwill_mixer[] = { |
2814 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 3091 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2815 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | 3092 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
2816 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 3093 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2837,7 +3114,7 @@ static struct snd_kcontrol_new alc880_uniwill_mixer[] = { | |||
2837 | { } /* end */ | 3114 | { } /* end */ |
2838 | }; | 3115 | }; |
2839 | 3116 | ||
2840 | static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { | 3117 | static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = { |
2841 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 3118 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2842 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | 3119 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
2843 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 3120 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2851,7 +3128,7 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { | |||
2851 | { } /* end */ | 3128 | { } /* end */ |
2852 | }; | 3129 | }; |
2853 | 3130 | ||
2854 | static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { | 3131 | static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { |
2855 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 3132 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
2856 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | 3133 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
2857 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 3134 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -2878,7 +3155,6 @@ static const char * const alc_slave_vols[] = { | |||
2878 | "Speaker Playback Volume", | 3155 | "Speaker Playback Volume", |
2879 | "Mono Playback Volume", | 3156 | "Mono Playback Volume", |
2880 | "Line-Out Playback Volume", | 3157 | "Line-Out Playback Volume", |
2881 | "PCM Playback Volume", | ||
2882 | NULL, | 3158 | NULL, |
2883 | }; | 3159 | }; |
2884 | 3160 | ||
@@ -2893,7 +3169,6 @@ static const char * const alc_slave_sws[] = { | |||
2893 | "Mono Playback Switch", | 3169 | "Mono Playback Switch", |
2894 | "IEC958 Playback Switch", | 3170 | "IEC958 Playback Switch", |
2895 | "Line-Out Playback Switch", | 3171 | "Line-Out Playback Switch", |
2896 | "PCM Playback Switch", | ||
2897 | NULL, | 3172 | NULL, |
2898 | }; | 3173 | }; |
2899 | 3174 | ||
@@ -2914,7 +3189,7 @@ static void alc_free_kctls(struct hda_codec *codec); | |||
2914 | 3189 | ||
2915 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 3190 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
2916 | /* additional beep mixers; the actual parameters are overwritten at build */ | 3191 | /* additional beep mixers; the actual parameters are overwritten at build */ |
2917 | static struct snd_kcontrol_new alc_beep_mixer[] = { | 3192 | static const struct snd_kcontrol_new alc_beep_mixer[] = { |
2918 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), | 3193 | HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), |
2919 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), | 3194 | HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), |
2920 | { } /* end */ | 3195 | { } /* end */ |
@@ -2925,7 +3200,7 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2925 | { | 3200 | { |
2926 | struct alc_spec *spec = codec->spec; | 3201 | struct alc_spec *spec = codec->spec; |
2927 | struct snd_kcontrol *kctl = NULL; | 3202 | struct snd_kcontrol *kctl = NULL; |
2928 | struct snd_kcontrol_new *knew; | 3203 | const struct snd_kcontrol_new *knew; |
2929 | int i, j, err; | 3204 | int i, j, err; |
2930 | unsigned int u; | 3205 | unsigned int u; |
2931 | hda_nid_t nid; | 3206 | hda_nid_t nid; |
@@ -2962,7 +3237,7 @@ static int alc_build_controls(struct hda_codec *codec) | |||
2962 | #ifdef CONFIG_SND_HDA_INPUT_BEEP | 3237 | #ifdef CONFIG_SND_HDA_INPUT_BEEP |
2963 | /* create beep controls if needed */ | 3238 | /* create beep controls if needed */ |
2964 | if (spec->beep_amp) { | 3239 | if (spec->beep_amp) { |
2965 | struct snd_kcontrol_new *knew; | 3240 | const struct snd_kcontrol_new *knew; |
2966 | for (knew = alc_beep_mixer; knew->name; knew++) { | 3241 | for (knew = alc_beep_mixer; knew->name; knew++) { |
2967 | struct snd_kcontrol *kctl; | 3242 | struct snd_kcontrol *kctl; |
2968 | kctl = snd_ctl_new1(knew, codec); | 3243 | kctl = snd_ctl_new1(knew, codec); |
@@ -3001,7 +3276,7 @@ static int alc_build_controls(struct hda_codec *codec) | |||
3001 | if (!kctl) | 3276 | if (!kctl) |
3002 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); | 3277 | kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); |
3003 | for (i = 0; kctl && i < kctl->count; i++) { | 3278 | for (i = 0; kctl && i < kctl->count; i++) { |
3004 | hda_nid_t *nids = spec->capsrc_nids; | 3279 | const hda_nid_t *nids = spec->capsrc_nids; |
3005 | if (!nids) | 3280 | if (!nids) |
3006 | nids = spec->adc_nids; | 3281 | nids = spec->adc_nids; |
3007 | err = snd_hda_add_nid(codec, kctl, i, nids[i]); | 3282 | err = snd_hda_add_nid(codec, kctl, i, nids[i]); |
@@ -3079,7 +3354,7 @@ static int alc_build_controls(struct hda_codec *codec) | |||
3079 | /* | 3354 | /* |
3080 | * generic initialization of ADC, input mixers and output mixers | 3355 | * generic initialization of ADC, input mixers and output mixers |
3081 | */ | 3356 | */ |
3082 | static struct hda_verb alc880_volume_init_verbs[] = { | 3357 | static const struct hda_verb alc880_volume_init_verbs[] = { |
3083 | /* | 3358 | /* |
3084 | * Unmute ADC0-2 and set the default input to mic-in | 3359 | * Unmute ADC0-2 and set the default input to mic-in |
3085 | */ | 3360 | */ |
@@ -3130,7 +3405,7 @@ static struct hda_verb alc880_volume_init_verbs[] = { | |||
3130 | * 3-stack pin configuration: | 3405 | * 3-stack pin configuration: |
3131 | * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b | 3406 | * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b |
3132 | */ | 3407 | */ |
3133 | static struct hda_verb alc880_pin_3stack_init_verbs[] = { | 3408 | static const struct hda_verb alc880_pin_3stack_init_verbs[] = { |
3134 | /* | 3409 | /* |
3135 | * preset connection lists of input pins | 3410 | * preset connection lists of input pins |
3136 | * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround | 3411 | * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround |
@@ -3168,7 +3443,7 @@ static struct hda_verb alc880_pin_3stack_init_verbs[] = { | |||
3168 | * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, | 3443 | * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, |
3169 | * line-in/side = 0x1a, f-mic = 0x1b | 3444 | * line-in/side = 0x1a, f-mic = 0x1b |
3170 | */ | 3445 | */ |
3171 | static struct hda_verb alc880_pin_5stack_init_verbs[] = { | 3446 | static const struct hda_verb alc880_pin_5stack_init_verbs[] = { |
3172 | /* | 3447 | /* |
3173 | * preset connection lists of input pins | 3448 | * preset connection lists of input pins |
3174 | * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround | 3449 | * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround |
@@ -3212,7 +3487,7 @@ static struct hda_verb alc880_pin_5stack_init_verbs[] = { | |||
3212 | * W810 pin configuration: | 3487 | * W810 pin configuration: |
3213 | * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b | 3488 | * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b |
3214 | */ | 3489 | */ |
3215 | static struct hda_verb alc880_pin_w810_init_verbs[] = { | 3490 | static const struct hda_verb alc880_pin_w810_init_verbs[] = { |
3216 | /* hphone/speaker input selector: front DAC */ | 3491 | /* hphone/speaker input selector: front DAC */ |
3217 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, | 3492 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, |
3218 | 3493 | ||
@@ -3233,7 +3508,7 @@ static struct hda_verb alc880_pin_w810_init_verbs[] = { | |||
3233 | * Z71V pin configuration: | 3508 | * Z71V pin configuration: |
3234 | * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) | 3509 | * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) |
3235 | */ | 3510 | */ |
3236 | static struct hda_verb alc880_pin_z71v_init_verbs[] = { | 3511 | static const struct hda_verb alc880_pin_z71v_init_verbs[] = { |
3237 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 3512 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
3238 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 3513 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
3239 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 3514 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -3252,7 +3527,7 @@ static struct hda_verb alc880_pin_z71v_init_verbs[] = { | |||
3252 | * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, | 3527 | * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, |
3253 | * f-mic = 0x19, line = 0x1a, HP = 0x1b | 3528 | * f-mic = 0x19, line = 0x1a, HP = 0x1b |
3254 | */ | 3529 | */ |
3255 | static struct hda_verb alc880_pin_6stack_init_verbs[] = { | 3530 | static const struct hda_verb alc880_pin_6stack_init_verbs[] = { |
3256 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 3531 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
3257 | 3532 | ||
3258 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 3533 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
@@ -3282,7 +3557,7 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = { | |||
3282 | * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, | 3557 | * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, |
3283 | * line = 0x1a | 3558 | * line = 0x1a |
3284 | */ | 3559 | */ |
3285 | static struct hda_verb alc880_uniwill_init_verbs[] = { | 3560 | static const struct hda_verb alc880_uniwill_init_verbs[] = { |
3286 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 3561 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
3287 | 3562 | ||
3288 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 3563 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -3320,7 +3595,7 @@ static struct hda_verb alc880_uniwill_init_verbs[] = { | |||
3320 | * Uniwill P53 | 3595 | * Uniwill P53 |
3321 | * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, | 3596 | * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, |
3322 | */ | 3597 | */ |
3323 | static struct hda_verb alc880_uniwill_p53_init_verbs[] = { | 3598 | static const struct hda_verb alc880_uniwill_p53_init_verbs[] = { |
3324 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 3599 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
3325 | 3600 | ||
3326 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 3601 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -3349,7 +3624,7 @@ static struct hda_verb alc880_uniwill_p53_init_verbs[] = { | |||
3349 | { } | 3624 | { } |
3350 | }; | 3625 | }; |
3351 | 3626 | ||
3352 | static struct hda_verb alc880_beep_init_verbs[] = { | 3627 | static const struct hda_verb alc880_beep_init_verbs[] = { |
3353 | { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, | 3628 | { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, |
3354 | { } | 3629 | { } |
3355 | }; | 3630 | }; |
@@ -3372,11 +3647,13 @@ static void alc880_uniwill_setup(struct hda_codec *codec) | |||
3372 | spec->autocfg.hp_pins[0] = 0x14; | 3647 | spec->autocfg.hp_pins[0] = 0x14; |
3373 | spec->autocfg.speaker_pins[0] = 0x15; | 3648 | spec->autocfg.speaker_pins[0] = 0x15; |
3374 | spec->autocfg.speaker_pins[0] = 0x16; | 3649 | spec->autocfg.speaker_pins[0] = 0x16; |
3650 | spec->automute = 1; | ||
3651 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
3375 | } | 3652 | } |
3376 | 3653 | ||
3377 | static void alc880_uniwill_init_hook(struct hda_codec *codec) | 3654 | static void alc880_uniwill_init_hook(struct hda_codec *codec) |
3378 | { | 3655 | { |
3379 | alc_automute_amp(codec); | 3656 | alc_hp_automute(codec); |
3380 | alc88x_simple_mic_automute(codec); | 3657 | alc88x_simple_mic_automute(codec); |
3381 | } | 3658 | } |
3382 | 3659 | ||
@@ -3391,7 +3668,7 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, | |||
3391 | alc88x_simple_mic_automute(codec); | 3668 | alc88x_simple_mic_automute(codec); |
3392 | break; | 3669 | break; |
3393 | default: | 3670 | default: |
3394 | alc_automute_amp_unsol_event(codec, res); | 3671 | alc_sku_unsol_event(codec, res); |
3395 | break; | 3672 | break; |
3396 | } | 3673 | } |
3397 | } | 3674 | } |
@@ -3402,6 +3679,8 @@ static void alc880_uniwill_p53_setup(struct hda_codec *codec) | |||
3402 | 3679 | ||
3403 | spec->autocfg.hp_pins[0] = 0x14; | 3680 | spec->autocfg.hp_pins[0] = 0x14; |
3404 | spec->autocfg.speaker_pins[0] = 0x15; | 3681 | spec->autocfg.speaker_pins[0] = 0x15; |
3682 | spec->automute = 1; | ||
3683 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
3405 | } | 3684 | } |
3406 | 3685 | ||
3407 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) | 3686 | static void alc880_uniwill_p53_dcvol_automute(struct hda_codec *codec) |
@@ -3426,14 +3705,14 @@ static void alc880_uniwill_p53_unsol_event(struct hda_codec *codec, | |||
3426 | if ((res >> 28) == ALC880_DCVOL_EVENT) | 3705 | if ((res >> 28) == ALC880_DCVOL_EVENT) |
3427 | alc880_uniwill_p53_dcvol_automute(codec); | 3706 | alc880_uniwill_p53_dcvol_automute(codec); |
3428 | else | 3707 | else |
3429 | alc_automute_amp_unsol_event(codec, res); | 3708 | alc_sku_unsol_event(codec, res); |
3430 | } | 3709 | } |
3431 | 3710 | ||
3432 | /* | 3711 | /* |
3433 | * F1734 pin configuration: | 3712 | * F1734 pin configuration: |
3434 | * HP = 0x14, speaker-out = 0x15, mic = 0x18 | 3713 | * HP = 0x14, speaker-out = 0x15, mic = 0x18 |
3435 | */ | 3714 | */ |
3436 | static struct hda_verb alc880_pin_f1734_init_verbs[] = { | 3715 | static const struct hda_verb alc880_pin_f1734_init_verbs[] = { |
3437 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, | 3716 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, |
3438 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, | 3717 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, |
3439 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, | 3718 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -3465,7 +3744,7 @@ static struct hda_verb alc880_pin_f1734_init_verbs[] = { | |||
3465 | * ASUS pin configuration: | 3744 | * ASUS pin configuration: |
3466 | * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a | 3745 | * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a |
3467 | */ | 3746 | */ |
3468 | static struct hda_verb alc880_pin_asus_init_verbs[] = { | 3747 | static const struct hda_verb alc880_pin_asus_init_verbs[] = { |
3469 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, | 3748 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, |
3470 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, | 3749 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, |
3471 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, | 3750 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, |
@@ -3499,7 +3778,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = { | |||
3499 | #define alc880_gpio3_init_verbs alc_gpio3_init_verbs | 3778 | #define alc880_gpio3_init_verbs alc_gpio3_init_verbs |
3500 | 3779 | ||
3501 | /* Clevo m520g init */ | 3780 | /* Clevo m520g init */ |
3502 | static struct hda_verb alc880_pin_clevo_init_verbs[] = { | 3781 | static const struct hda_verb alc880_pin_clevo_init_verbs[] = { |
3503 | /* headphone output */ | 3782 | /* headphone output */ |
3504 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, | 3783 | {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, |
3505 | /* line-out */ | 3784 | /* line-out */ |
@@ -3527,7 +3806,7 @@ static struct hda_verb alc880_pin_clevo_init_verbs[] = { | |||
3527 | { } | 3806 | { } |
3528 | }; | 3807 | }; |
3529 | 3808 | ||
3530 | static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { | 3809 | static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { |
3531 | /* change to EAPD mode */ | 3810 | /* change to EAPD mode */ |
3532 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 3811 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
3533 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, | 3812 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, |
@@ -3565,12 +3844,12 @@ static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { | |||
3565 | */ | 3844 | */ |
3566 | 3845 | ||
3567 | /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ | 3846 | /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ |
3568 | static hda_nid_t alc880_lg_dac_nids[3] = { | 3847 | static const hda_nid_t alc880_lg_dac_nids[3] = { |
3569 | 0x05, 0x02, 0x03 | 3848 | 0x05, 0x02, 0x03 |
3570 | }; | 3849 | }; |
3571 | 3850 | ||
3572 | /* seems analog CD is not working */ | 3851 | /* seems analog CD is not working */ |
3573 | static struct hda_input_mux alc880_lg_capture_source = { | 3852 | static const struct hda_input_mux alc880_lg_capture_source = { |
3574 | .num_items = 3, | 3853 | .num_items = 3, |
3575 | .items = { | 3854 | .items = { |
3576 | { "Mic", 0x1 }, | 3855 | { "Mic", 0x1 }, |
@@ -3580,34 +3859,34 @@ static struct hda_input_mux alc880_lg_capture_source = { | |||
3580 | }; | 3859 | }; |
3581 | 3860 | ||
3582 | /* 2,4,6 channel modes */ | 3861 | /* 2,4,6 channel modes */ |
3583 | static struct hda_verb alc880_lg_ch2_init[] = { | 3862 | static const struct hda_verb alc880_lg_ch2_init[] = { |
3584 | /* set line-in and mic-in to input */ | 3863 | /* set line-in and mic-in to input */ |
3585 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 3864 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
3586 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 3865 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
3587 | { } | 3866 | { } |
3588 | }; | 3867 | }; |
3589 | 3868 | ||
3590 | static struct hda_verb alc880_lg_ch4_init[] = { | 3869 | static const struct hda_verb alc880_lg_ch4_init[] = { |
3591 | /* set line-in to out and mic-in to input */ | 3870 | /* set line-in to out and mic-in to input */ |
3592 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | 3871 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
3593 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 3872 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
3594 | { } | 3873 | { } |
3595 | }; | 3874 | }; |
3596 | 3875 | ||
3597 | static struct hda_verb alc880_lg_ch6_init[] = { | 3876 | static const struct hda_verb alc880_lg_ch6_init[] = { |
3598 | /* set line-in and mic-in to output */ | 3877 | /* set line-in and mic-in to output */ |
3599 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | 3878 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
3600 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | 3879 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
3601 | { } | 3880 | { } |
3602 | }; | 3881 | }; |
3603 | 3882 | ||
3604 | static struct hda_channel_mode alc880_lg_ch_modes[3] = { | 3883 | static const struct hda_channel_mode alc880_lg_ch_modes[3] = { |
3605 | { 2, alc880_lg_ch2_init }, | 3884 | { 2, alc880_lg_ch2_init }, |
3606 | { 4, alc880_lg_ch4_init }, | 3885 | { 4, alc880_lg_ch4_init }, |
3607 | { 6, alc880_lg_ch6_init }, | 3886 | { 6, alc880_lg_ch6_init }, |
3608 | }; | 3887 | }; |
3609 | 3888 | ||
3610 | static struct snd_kcontrol_new alc880_lg_mixer[] = { | 3889 | static const struct snd_kcontrol_new alc880_lg_mixer[] = { |
3611 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 3890 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
3612 | HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), | 3891 | HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), |
3613 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 3892 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
@@ -3632,7 +3911,7 @@ static struct snd_kcontrol_new alc880_lg_mixer[] = { | |||
3632 | { } /* end */ | 3911 | { } /* end */ |
3633 | }; | 3912 | }; |
3634 | 3913 | ||
3635 | static struct hda_verb alc880_lg_init_verbs[] = { | 3914 | static const struct hda_verb alc880_lg_init_verbs[] = { |
3636 | /* set capture source to mic-in */ | 3915 | /* set capture source to mic-in */ |
3637 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 3916 | {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
3638 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 3917 | {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -3670,6 +3949,8 @@ static void alc880_lg_setup(struct hda_codec *codec) | |||
3670 | 3949 | ||
3671 | spec->autocfg.hp_pins[0] = 0x1b; | 3950 | spec->autocfg.hp_pins[0] = 0x1b; |
3672 | spec->autocfg.speaker_pins[0] = 0x17; | 3951 | spec->autocfg.speaker_pins[0] = 0x17; |
3952 | spec->automute = 1; | ||
3953 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
3673 | } | 3954 | } |
3674 | 3955 | ||
3675 | /* | 3956 | /* |
@@ -3684,7 +3965,7 @@ static void alc880_lg_setup(struct hda_codec *codec) | |||
3684 | * SPDIF-Out: 0x1e | 3965 | * SPDIF-Out: 0x1e |
3685 | */ | 3966 | */ |
3686 | 3967 | ||
3687 | static struct hda_input_mux alc880_lg_lw_capture_source = { | 3968 | static const struct hda_input_mux alc880_lg_lw_capture_source = { |
3688 | .num_items = 3, | 3969 | .num_items = 3, |
3689 | .items = { | 3970 | .items = { |
3690 | { "Mic", 0x0 }, | 3971 | { "Mic", 0x0 }, |
@@ -3695,7 +3976,7 @@ static struct hda_input_mux alc880_lg_lw_capture_source = { | |||
3695 | 3976 | ||
3696 | #define alc880_lg_lw_modes alc880_threestack_modes | 3977 | #define alc880_lg_lw_modes alc880_threestack_modes |
3697 | 3978 | ||
3698 | static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { | 3979 | static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = { |
3699 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 3980 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
3700 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 3981 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
3701 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 3982 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
@@ -3720,7 +4001,7 @@ static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { | |||
3720 | { } /* end */ | 4001 | { } /* end */ |
3721 | }; | 4002 | }; |
3722 | 4003 | ||
3723 | static struct hda_verb alc880_lg_lw_init_verbs[] = { | 4004 | static const struct hda_verb alc880_lg_lw_init_verbs[] = { |
3724 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 4005 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
3725 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ | 4006 | {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ |
3726 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ | 4007 | {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ |
@@ -3754,9 +4035,11 @@ static void alc880_lg_lw_setup(struct hda_codec *codec) | |||
3754 | 4035 | ||
3755 | spec->autocfg.hp_pins[0] = 0x1b; | 4036 | spec->autocfg.hp_pins[0] = 0x1b; |
3756 | spec->autocfg.speaker_pins[0] = 0x14; | 4037 | spec->autocfg.speaker_pins[0] = 0x14; |
4038 | spec->automute = 1; | ||
4039 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
3757 | } | 4040 | } |
3758 | 4041 | ||
3759 | static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { | 4042 | static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = { |
3760 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 4043 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
3761 | HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), | 4044 | HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), |
3762 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 4045 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -3766,7 +4049,7 @@ static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { | |||
3766 | { } /* end */ | 4049 | { } /* end */ |
3767 | }; | 4050 | }; |
3768 | 4051 | ||
3769 | static struct hda_input_mux alc880_medion_rim_capture_source = { | 4052 | static const struct hda_input_mux alc880_medion_rim_capture_source = { |
3770 | .num_items = 2, | 4053 | .num_items = 2, |
3771 | .items = { | 4054 | .items = { |
3772 | { "Mic", 0x0 }, | 4055 | { "Mic", 0x0 }, |
@@ -3774,7 +4057,7 @@ static struct hda_input_mux alc880_medion_rim_capture_source = { | |||
3774 | }, | 4057 | }, |
3775 | }; | 4058 | }; |
3776 | 4059 | ||
3777 | static struct hda_verb alc880_medion_rim_init_verbs[] = { | 4060 | static const struct hda_verb alc880_medion_rim_init_verbs[] = { |
3778 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ | 4061 | {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ |
3779 | 4062 | ||
3780 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 4063 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -3801,7 +4084,7 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = { | |||
3801 | static void alc880_medion_rim_automute(struct hda_codec *codec) | 4084 | static void alc880_medion_rim_automute(struct hda_codec *codec) |
3802 | { | 4085 | { |
3803 | struct alc_spec *spec = codec->spec; | 4086 | struct alc_spec *spec = codec->spec; |
3804 | alc_automute_amp(codec); | 4087 | alc_hp_automute(codec); |
3805 | /* toggle EAPD */ | 4088 | /* toggle EAPD */ |
3806 | if (spec->jack_present) | 4089 | if (spec->jack_present) |
3807 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); | 4090 | snd_hda_codec_write(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 0); |
@@ -3825,10 +4108,12 @@ static void alc880_medion_rim_setup(struct hda_codec *codec) | |||
3825 | 4108 | ||
3826 | spec->autocfg.hp_pins[0] = 0x14; | 4109 | spec->autocfg.hp_pins[0] = 0x14; |
3827 | spec->autocfg.speaker_pins[0] = 0x1b; | 4110 | spec->autocfg.speaker_pins[0] = 0x1b; |
4111 | spec->automute = 1; | ||
4112 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
3828 | } | 4113 | } |
3829 | 4114 | ||
3830 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4115 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3831 | static struct hda_amp_list alc880_loopbacks[] = { | 4116 | static const struct hda_amp_list alc880_loopbacks[] = { |
3832 | { 0x0b, HDA_INPUT, 0 }, | 4117 | { 0x0b, HDA_INPUT, 0 }, |
3833 | { 0x0b, HDA_INPUT, 1 }, | 4118 | { 0x0b, HDA_INPUT, 1 }, |
3834 | { 0x0b, HDA_INPUT, 2 }, | 4119 | { 0x0b, HDA_INPUT, 2 }, |
@@ -3837,7 +4122,7 @@ static struct hda_amp_list alc880_loopbacks[] = { | |||
3837 | { } /* end */ | 4122 | { } /* end */ |
3838 | }; | 4123 | }; |
3839 | 4124 | ||
3840 | static struct hda_amp_list alc880_lg_loopbacks[] = { | 4125 | static const struct hda_amp_list alc880_lg_loopbacks[] = { |
3841 | { 0x0b, HDA_INPUT, 1 }, | 4126 | { 0x0b, HDA_INPUT, 1 }, |
3842 | { 0x0b, HDA_INPUT, 6 }, | 4127 | { 0x0b, HDA_INPUT, 6 }, |
3843 | { 0x0b, HDA_INPUT, 7 }, | 4128 | { 0x0b, HDA_INPUT, 7 }, |
@@ -4009,7 +4294,7 @@ static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
4009 | return 0; | 4294 | return 0; |
4010 | } | 4295 | } |
4011 | 4296 | ||
4012 | static struct hda_pcm_stream dualmic_pcm_analog_capture = { | 4297 | static const struct hda_pcm_stream dualmic_pcm_analog_capture = { |
4013 | .substreams = 1, | 4298 | .substreams = 1, |
4014 | .channels_min = 2, | 4299 | .channels_min = 2, |
4015 | .channels_max = 2, | 4300 | .channels_max = 2, |
@@ -4022,7 +4307,7 @@ static struct hda_pcm_stream dualmic_pcm_analog_capture = { | |||
4022 | 4307 | ||
4023 | /* | 4308 | /* |
4024 | */ | 4309 | */ |
4025 | static struct hda_pcm_stream alc880_pcm_analog_playback = { | 4310 | static const struct hda_pcm_stream alc880_pcm_analog_playback = { |
4026 | .substreams = 1, | 4311 | .substreams = 1, |
4027 | .channels_min = 2, | 4312 | .channels_min = 2, |
4028 | .channels_max = 8, | 4313 | .channels_max = 8, |
@@ -4034,21 +4319,21 @@ static struct hda_pcm_stream alc880_pcm_analog_playback = { | |||
4034 | }, | 4319 | }, |
4035 | }; | 4320 | }; |
4036 | 4321 | ||
4037 | static struct hda_pcm_stream alc880_pcm_analog_capture = { | 4322 | static const struct hda_pcm_stream alc880_pcm_analog_capture = { |
4038 | .substreams = 1, | 4323 | .substreams = 1, |
4039 | .channels_min = 2, | 4324 | .channels_min = 2, |
4040 | .channels_max = 2, | 4325 | .channels_max = 2, |
4041 | /* NID is set in alc_build_pcms */ | 4326 | /* NID is set in alc_build_pcms */ |
4042 | }; | 4327 | }; |
4043 | 4328 | ||
4044 | static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { | 4329 | static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = { |
4045 | .substreams = 1, | 4330 | .substreams = 1, |
4046 | .channels_min = 2, | 4331 | .channels_min = 2, |
4047 | .channels_max = 2, | 4332 | .channels_max = 2, |
4048 | /* NID is set in alc_build_pcms */ | 4333 | /* NID is set in alc_build_pcms */ |
4049 | }; | 4334 | }; |
4050 | 4335 | ||
4051 | static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { | 4336 | static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = { |
4052 | .substreams = 2, /* can be overridden */ | 4337 | .substreams = 2, /* can be overridden */ |
4053 | .channels_min = 2, | 4338 | .channels_min = 2, |
4054 | .channels_max = 2, | 4339 | .channels_max = 2, |
@@ -4059,7 +4344,7 @@ static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { | |||
4059 | }, | 4344 | }, |
4060 | }; | 4345 | }; |
4061 | 4346 | ||
4062 | static struct hda_pcm_stream alc880_pcm_digital_playback = { | 4347 | static const struct hda_pcm_stream alc880_pcm_digital_playback = { |
4063 | .substreams = 1, | 4348 | .substreams = 1, |
4064 | .channels_min = 2, | 4349 | .channels_min = 2, |
4065 | .channels_max = 2, | 4350 | .channels_max = 2, |
@@ -4072,7 +4357,7 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = { | |||
4072 | }, | 4357 | }, |
4073 | }; | 4358 | }; |
4074 | 4359 | ||
4075 | static struct hda_pcm_stream alc880_pcm_digital_capture = { | 4360 | static const struct hda_pcm_stream alc880_pcm_digital_capture = { |
4076 | .substreams = 1, | 4361 | .substreams = 1, |
4077 | .channels_min = 2, | 4362 | .channels_min = 2, |
4078 | .channels_max = 2, | 4363 | .channels_max = 2, |
@@ -4080,7 +4365,7 @@ static struct hda_pcm_stream alc880_pcm_digital_capture = { | |||
4080 | }; | 4365 | }; |
4081 | 4366 | ||
4082 | /* Used by alc_build_pcms to flag that a PCM has no playback stream */ | 4367 | /* Used by alc_build_pcms to flag that a PCM has no playback stream */ |
4083 | static struct hda_pcm_stream alc_pcm_null_stream = { | 4368 | static const struct hda_pcm_stream alc_pcm_null_stream = { |
4084 | .substreams = 0, | 4369 | .substreams = 0, |
4085 | .channels_min = 0, | 4370 | .channels_min = 0, |
4086 | .channels_max = 0, | 4371 | .channels_max = 0, |
@@ -4174,7 +4459,7 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
4174 | alc_pcm_null_stream; | 4459 | alc_pcm_null_stream; |
4175 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; | 4460 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; |
4176 | } | 4461 | } |
4177 | if (spec->num_adc_nids > 1) { | 4462 | if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) { |
4178 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = | 4463 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = |
4179 | *spec->stream_analog_alt_capture; | 4464 | *spec->stream_analog_alt_capture; |
4180 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = | 4465 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = |
@@ -4193,6 +4478,10 @@ static int alc_build_pcms(struct hda_codec *codec) | |||
4193 | 4478 | ||
4194 | static inline void alc_shutup(struct hda_codec *codec) | 4479 | static inline void alc_shutup(struct hda_codec *codec) |
4195 | { | 4480 | { |
4481 | struct alc_spec *spec = codec->spec; | ||
4482 | |||
4483 | if (spec && spec->shutup) | ||
4484 | spec->shutup(codec); | ||
4196 | snd_hda_shutup_pins(codec); | 4485 | snd_hda_shutup_pins(codec); |
4197 | } | 4486 | } |
4198 | 4487 | ||
@@ -4226,28 +4515,7 @@ static void alc_free(struct hda_codec *codec) | |||
4226 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4515 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4227 | static void alc_power_eapd(struct hda_codec *codec) | 4516 | static void alc_power_eapd(struct hda_codec *codec) |
4228 | { | 4517 | { |
4229 | /* We currently only handle front, HP */ | 4518 | alc_auto_setup_eapd(codec, false); |
4230 | switch (codec->vendor_id) { | ||
4231 | case 0x10ec0260: | ||
4232 | set_eapd(codec, 0x0f, 0); | ||
4233 | set_eapd(codec, 0x10, 0); | ||
4234 | break; | ||
4235 | case 0x10ec0262: | ||
4236 | case 0x10ec0267: | ||
4237 | case 0x10ec0268: | ||
4238 | case 0x10ec0269: | ||
4239 | case 0x10ec0270: | ||
4240 | case 0x10ec0272: | ||
4241 | case 0x10ec0660: | ||
4242 | case 0x10ec0662: | ||
4243 | case 0x10ec0663: | ||
4244 | case 0x10ec0665: | ||
4245 | case 0x10ec0862: | ||
4246 | case 0x10ec0889: | ||
4247 | set_eapd(codec, 0x14, 0); | ||
4248 | set_eapd(codec, 0x15, 0); | ||
4249 | break; | ||
4250 | } | ||
4251 | } | 4519 | } |
4252 | 4520 | ||
4253 | static int alc_suspend(struct hda_codec *codec, pm_message_t state) | 4521 | static int alc_suspend(struct hda_codec *codec, pm_message_t state) |
@@ -4263,6 +4531,7 @@ static int alc_suspend(struct hda_codec *codec, pm_message_t state) | |||
4263 | #ifdef SND_HDA_NEEDS_RESUME | 4531 | #ifdef SND_HDA_NEEDS_RESUME |
4264 | static int alc_resume(struct hda_codec *codec) | 4532 | static int alc_resume(struct hda_codec *codec) |
4265 | { | 4533 | { |
4534 | msleep(150); /* to avoid pop noise */ | ||
4266 | codec->patch_ops.init(codec); | 4535 | codec->patch_ops.init(codec); |
4267 | snd_hda_codec_resume_amp(codec); | 4536 | snd_hda_codec_resume_amp(codec); |
4268 | snd_hda_codec_resume_cache(codec); | 4537 | snd_hda_codec_resume_cache(codec); |
@@ -4273,7 +4542,7 @@ static int alc_resume(struct hda_codec *codec) | |||
4273 | 4542 | ||
4274 | /* | 4543 | /* |
4275 | */ | 4544 | */ |
4276 | static struct hda_codec_ops alc_patch_ops = { | 4545 | static const struct hda_codec_ops alc_patch_ops = { |
4277 | .build_controls = alc_build_controls, | 4546 | .build_controls = alc_build_controls, |
4278 | .build_pcms = alc_build_pcms, | 4547 | .build_pcms = alc_build_pcms, |
4279 | .init = alc_init, | 4548 | .init = alc_init, |
@@ -4308,11 +4577,11 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name) | |||
4308 | * enum controls. | 4577 | * enum controls. |
4309 | */ | 4578 | */ |
4310 | #ifdef CONFIG_SND_DEBUG | 4579 | #ifdef CONFIG_SND_DEBUG |
4311 | static hda_nid_t alc880_test_dac_nids[4] = { | 4580 | static const hda_nid_t alc880_test_dac_nids[4] = { |
4312 | 0x02, 0x03, 0x04, 0x05 | 4581 | 0x02, 0x03, 0x04, 0x05 |
4313 | }; | 4582 | }; |
4314 | 4583 | ||
4315 | static struct hda_input_mux alc880_test_capture_source = { | 4584 | static const struct hda_input_mux alc880_test_capture_source = { |
4316 | .num_items = 7, | 4585 | .num_items = 7, |
4317 | .items = { | 4586 | .items = { |
4318 | { "In-1", 0x0 }, | 4587 | { "In-1", 0x0 }, |
@@ -4325,7 +4594,7 @@ static struct hda_input_mux alc880_test_capture_source = { | |||
4325 | }, | 4594 | }, |
4326 | }; | 4595 | }; |
4327 | 4596 | ||
4328 | static struct hda_channel_mode alc880_test_modes[4] = { | 4597 | static const struct hda_channel_mode alc880_test_modes[4] = { |
4329 | { 2, NULL }, | 4598 | { 2, NULL }, |
4330 | { 4, NULL }, | 4599 | { 4, NULL }, |
4331 | { 6, NULL }, | 4600 | { 6, NULL }, |
@@ -4335,7 +4604,7 @@ static struct hda_channel_mode alc880_test_modes[4] = { | |||
4335 | static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, | 4604 | static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, |
4336 | struct snd_ctl_elem_info *uinfo) | 4605 | struct snd_ctl_elem_info *uinfo) |
4337 | { | 4606 | { |
4338 | static char *texts[] = { | 4607 | static const char * const texts[] = { |
4339 | "N/A", "Line Out", "HP Out", | 4608 | "N/A", "Line Out", "HP Out", |
4340 | "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" | 4609 | "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" |
4341 | }; | 4610 | }; |
@@ -4380,7 +4649,7 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, | |||
4380 | { | 4649 | { |
4381 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 4650 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
4382 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; | 4651 | hda_nid_t nid = (hda_nid_t)kcontrol->private_value; |
4383 | static unsigned int ctls[] = { | 4652 | static const unsigned int ctls[] = { |
4384 | 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, | 4653 | 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, |
4385 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, | 4654 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, |
4386 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, | 4655 | AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, |
@@ -4410,7 +4679,7 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, | |||
4410 | static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, | 4679 | static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, |
4411 | struct snd_ctl_elem_info *uinfo) | 4680 | struct snd_ctl_elem_info *uinfo) |
4412 | { | 4681 | { |
4413 | static char *texts[] = { | 4682 | static const char * const texts[] = { |
4414 | "Front", "Surround", "CLFE", "Side" | 4683 | "Front", "Surround", "CLFE", "Side" |
4415 | }; | 4684 | }; |
4416 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | 4685 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; |
@@ -4471,7 +4740,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, | |||
4471 | .private_value = nid \ | 4740 | .private_value = nid \ |
4472 | } | 4741 | } |
4473 | 4742 | ||
4474 | static struct snd_kcontrol_new alc880_test_mixer[] = { | 4743 | static const struct snd_kcontrol_new alc880_test_mixer[] = { |
4475 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 4744 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
4476 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 4745 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
4477 | HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | 4746 | HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), |
@@ -4512,7 +4781,7 @@ static struct snd_kcontrol_new alc880_test_mixer[] = { | |||
4512 | { } /* end */ | 4781 | { } /* end */ |
4513 | }; | 4782 | }; |
4514 | 4783 | ||
4515 | static struct hda_verb alc880_test_init_verbs[] = { | 4784 | static const struct hda_verb alc880_test_init_verbs[] = { |
4516 | /* Unmute inputs of 0x0c - 0x0f */ | 4785 | /* Unmute inputs of 0x0c - 0x0f */ |
4517 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 4786 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
4518 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 4787 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -4596,7 +4865,7 @@ static const char * const alc880_models[ALC880_MODEL_LAST] = { | |||
4596 | [ALC880_AUTO] = "auto", | 4865 | [ALC880_AUTO] = "auto", |
4597 | }; | 4866 | }; |
4598 | 4867 | ||
4599 | static struct snd_pci_quirk alc880_cfg_tbl[] = { | 4868 | static const struct snd_pci_quirk alc880_cfg_tbl[] = { |
4600 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), | 4869 | SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), |
4601 | SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), | 4870 | SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), |
4602 | SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), | 4871 | SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), |
@@ -4676,7 +4945,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { | |||
4676 | /* | 4945 | /* |
4677 | * ALC880 codec presets | 4946 | * ALC880 codec presets |
4678 | */ | 4947 | */ |
4679 | static struct alc_config_preset alc880_presets[] = { | 4948 | static const struct alc_config_preset alc880_presets[] = { |
4680 | [ALC880_3ST] = { | 4949 | [ALC880_3ST] = { |
4681 | .mixers = { alc880_three_stack_mixer }, | 4950 | .mixers = { alc880_three_stack_mixer }, |
4682 | .init_verbs = { alc880_volume_init_verbs, | 4951 | .init_verbs = { alc880_volume_init_verbs, |
@@ -4794,7 +5063,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
4794 | .input_mux = &alc880_f1734_capture_source, | 5063 | .input_mux = &alc880_f1734_capture_source, |
4795 | .unsol_event = alc880_uniwill_p53_unsol_event, | 5064 | .unsol_event = alc880_uniwill_p53_unsol_event, |
4796 | .setup = alc880_uniwill_p53_setup, | 5065 | .setup = alc880_uniwill_p53_setup, |
4797 | .init_hook = alc_automute_amp, | 5066 | .init_hook = alc_hp_automute, |
4798 | }, | 5067 | }, |
4799 | [ALC880_ASUS] = { | 5068 | [ALC880_ASUS] = { |
4800 | .mixers = { alc880_asus_mixer }, | 5069 | .mixers = { alc880_asus_mixer }, |
@@ -4885,7 +5154,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
4885 | .input_mux = &alc880_capture_source, | 5154 | .input_mux = &alc880_capture_source, |
4886 | .unsol_event = alc880_uniwill_p53_unsol_event, | 5155 | .unsol_event = alc880_uniwill_p53_unsol_event, |
4887 | .setup = alc880_uniwill_p53_setup, | 5156 | .setup = alc880_uniwill_p53_setup, |
4888 | .init_hook = alc_automute_amp, | 5157 | .init_hook = alc_hp_automute, |
4889 | }, | 5158 | }, |
4890 | [ALC880_FUJITSU] = { | 5159 | [ALC880_FUJITSU] = { |
4891 | .mixers = { alc880_fujitsu_mixer }, | 5160 | .mixers = { alc880_fujitsu_mixer }, |
@@ -4900,7 +5169,7 @@ static struct alc_config_preset alc880_presets[] = { | |||
4900 | .input_mux = &alc880_capture_source, | 5169 | .input_mux = &alc880_capture_source, |
4901 | .unsol_event = alc880_uniwill_p53_unsol_event, | 5170 | .unsol_event = alc880_uniwill_p53_unsol_event, |
4902 | .setup = alc880_uniwill_p53_setup, | 5171 | .setup = alc880_uniwill_p53_setup, |
4903 | .init_hook = alc_automute_amp, | 5172 | .init_hook = alc_hp_automute, |
4904 | }, | 5173 | }, |
4905 | [ALC880_CLEVO] = { | 5174 | [ALC880_CLEVO] = { |
4906 | .mixers = { alc880_three_stack_mixer }, | 5175 | .mixers = { alc880_three_stack_mixer }, |
@@ -4925,9 +5194,9 @@ static struct alc_config_preset alc880_presets[] = { | |||
4925 | .channel_mode = alc880_lg_ch_modes, | 5194 | .channel_mode = alc880_lg_ch_modes, |
4926 | .need_dac_fix = 1, | 5195 | .need_dac_fix = 1, |
4927 | .input_mux = &alc880_lg_capture_source, | 5196 | .input_mux = &alc880_lg_capture_source, |
4928 | .unsol_event = alc_automute_amp_unsol_event, | 5197 | .unsol_event = alc_sku_unsol_event, |
4929 | .setup = alc880_lg_setup, | 5198 | .setup = alc880_lg_setup, |
4930 | .init_hook = alc_automute_amp, | 5199 | .init_hook = alc_hp_automute, |
4931 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5200 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4932 | .loopbacks = alc880_lg_loopbacks, | 5201 | .loopbacks = alc880_lg_loopbacks, |
4933 | #endif | 5202 | #endif |
@@ -4942,9 +5211,9 @@ static struct alc_config_preset alc880_presets[] = { | |||
4942 | .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), | 5211 | .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), |
4943 | .channel_mode = alc880_lg_lw_modes, | 5212 | .channel_mode = alc880_lg_lw_modes, |
4944 | .input_mux = &alc880_lg_lw_capture_source, | 5213 | .input_mux = &alc880_lg_lw_capture_source, |
4945 | .unsol_event = alc_automute_amp_unsol_event, | 5214 | .unsol_event = alc_sku_unsol_event, |
4946 | .setup = alc880_lg_lw_setup, | 5215 | .setup = alc880_lg_lw_setup, |
4947 | .init_hook = alc_automute_amp, | 5216 | .init_hook = alc_hp_automute, |
4948 | }, | 5217 | }, |
4949 | [ALC880_MEDION_RIM] = { | 5218 | [ALC880_MEDION_RIM] = { |
4950 | .mixers = { alc880_medion_rim_mixer }, | 5219 | .mixers = { alc880_medion_rim_mixer }, |
@@ -4984,20 +5253,25 @@ enum { | |||
4984 | ALC_CTL_WIDGET_MUTE, | 5253 | ALC_CTL_WIDGET_MUTE, |
4985 | ALC_CTL_BIND_MUTE, | 5254 | ALC_CTL_BIND_MUTE, |
4986 | }; | 5255 | }; |
4987 | static struct snd_kcontrol_new alc880_control_templates[] = { | 5256 | static const struct snd_kcontrol_new alc880_control_templates[] = { |
4988 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | 5257 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), |
4989 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | 5258 | HDA_CODEC_MUTE(NULL, 0, 0, 0), |
4990 | HDA_BIND_MUTE(NULL, 0, 0, 0), | 5259 | HDA_BIND_MUTE(NULL, 0, 0, 0), |
4991 | }; | 5260 | }; |
4992 | 5261 | ||
5262 | static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec) | ||
5263 | { | ||
5264 | snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); | ||
5265 | return snd_array_new(&spec->kctls); | ||
5266 | } | ||
5267 | |||
4993 | /* add dynamic controls */ | 5268 | /* add dynamic controls */ |
4994 | static int add_control(struct alc_spec *spec, int type, const char *name, | 5269 | static int add_control(struct alc_spec *spec, int type, const char *name, |
4995 | int cidx, unsigned long val) | 5270 | int cidx, unsigned long val) |
4996 | { | 5271 | { |
4997 | struct snd_kcontrol_new *knew; | 5272 | struct snd_kcontrol_new *knew; |
4998 | 5273 | ||
4999 | snd_array_init(&spec->kctls, sizeof(*knew), 32); | 5274 | knew = alc_kcontrol_new(spec); |
5000 | knew = snd_array_new(&spec->kctls); | ||
5001 | if (!knew) | 5275 | if (!knew) |
5002 | return -ENOMEM; | 5276 | return -ENOMEM; |
5003 | *knew = alc880_control_templates[type]; | 5277 | *knew = alc880_control_templates[type]; |
@@ -5055,7 +5329,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, | |||
5055 | nid = cfg->line_out_pins[i]; | 5329 | nid = cfg->line_out_pins[i]; |
5056 | if (alc880_is_fixed_pin(nid)) { | 5330 | if (alc880_is_fixed_pin(nid)) { |
5057 | int idx = alc880_fixed_pin_idx(nid); | 5331 | int idx = alc880_fixed_pin_idx(nid); |
5058 | spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); | 5332 | spec->private_dac_nids[i] = alc880_idx_to_dac(idx); |
5059 | assigned[idx] = 1; | 5333 | assigned[idx] = 1; |
5060 | } | 5334 | } |
5061 | } | 5335 | } |
@@ -5067,7 +5341,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, | |||
5067 | /* search for an empty channel */ | 5341 | /* search for an empty channel */ |
5068 | for (j = 0; j < cfg->line_outs; j++) { | 5342 | for (j = 0; j < cfg->line_outs; j++) { |
5069 | if (!assigned[j]) { | 5343 | if (!assigned[j]) { |
5070 | spec->multiout.dac_nids[i] = | 5344 | spec->private_dac_nids[i] = |
5071 | alc880_idx_to_dac(j); | 5345 | alc880_idx_to_dac(j); |
5072 | assigned[j] = 1; | 5346 | assigned[j] = 1; |
5073 | break; | 5347 | break; |
@@ -5078,10 +5352,13 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, | |||
5078 | return 0; | 5352 | return 0; |
5079 | } | 5353 | } |
5080 | 5354 | ||
5081 | static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, | 5355 | static const char *alc_get_line_out_pfx(struct alc_spec *spec, |
5082 | bool can_be_master) | 5356 | bool can_be_master) |
5083 | { | 5357 | { |
5084 | if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master) | 5358 | struct auto_pin_cfg *cfg = &spec->autocfg; |
5359 | |||
5360 | if (cfg->line_outs == 1 && !spec->multi_ios && | ||
5361 | !cfg->hp_outs && !cfg->speaker_outs && can_be_master) | ||
5085 | return "Master"; | 5362 | return "Master"; |
5086 | 5363 | ||
5087 | switch (cfg->line_out_type) { | 5364 | switch (cfg->line_out_type) { |
@@ -5092,7 +5369,7 @@ static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, | |||
5092 | case AUTO_PIN_HP_OUT: | 5369 | case AUTO_PIN_HP_OUT: |
5093 | return "Headphone"; | 5370 | return "Headphone"; |
5094 | default: | 5371 | default: |
5095 | if (cfg->line_outs == 1) | 5372 | if (cfg->line_outs == 1 && !spec->multi_ios) |
5096 | return "PCM"; | 5373 | return "PCM"; |
5097 | break; | 5374 | break; |
5098 | } | 5375 | } |
@@ -5106,11 +5383,15 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
5106 | static const char * const chname[4] = { | 5383 | static const char * const chname[4] = { |
5107 | "Front", "Surround", NULL /*CLFE*/, "Side" | 5384 | "Front", "Surround", NULL /*CLFE*/, "Side" |
5108 | }; | 5385 | }; |
5109 | const char *pfx = alc_get_line_out_pfx(cfg, false); | 5386 | const char *pfx = alc_get_line_out_pfx(spec, false); |
5110 | hda_nid_t nid; | 5387 | hda_nid_t nid; |
5111 | int i, err; | 5388 | int i, err, noutputs; |
5112 | 5389 | ||
5113 | for (i = 0; i < cfg->line_outs; i++) { | 5390 | noutputs = cfg->line_outs; |
5391 | if (spec->multi_ios > 0) | ||
5392 | noutputs += spec->multi_ios; | ||
5393 | |||
5394 | for (i = 0; i < noutputs; i++) { | ||
5114 | if (!spec->multiout.dac_nids[i]) | 5395 | if (!spec->multiout.dac_nids[i]) |
5115 | continue; | 5396 | continue; |
5116 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); | 5397 | nid = alc880_idx_to_mixer(alc880_dac_to_idx(spec->multiout.dac_nids[i])); |
@@ -5376,6 +5657,8 @@ static void alc880_auto_init_input_src(struct hda_codec *codec) | |||
5376 | } | 5657 | } |
5377 | } | 5658 | } |
5378 | 5659 | ||
5660 | static int alc_auto_add_multi_channel_mode(struct hda_codec *codec); | ||
5661 | |||
5379 | /* parse the BIOS configuration and set up the alc_spec */ | 5662 | /* parse the BIOS configuration and set up the alc_spec */ |
5380 | /* return 1 if successful, 0 if the proper config is not found, | 5663 | /* return 1 if successful, 0 if the proper config is not found, |
5381 | * or a negative error code | 5664 | * or a negative error code |
@@ -5384,7 +5667,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
5384 | { | 5667 | { |
5385 | struct alc_spec *spec = codec->spec; | 5668 | struct alc_spec *spec = codec->spec; |
5386 | int err; | 5669 | int err; |
5387 | static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; | 5670 | static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; |
5388 | 5671 | ||
5389 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 5672 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
5390 | alc880_ignore); | 5673 | alc880_ignore); |
@@ -5396,6 +5679,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec) | |||
5396 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); | 5679 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); |
5397 | if (err < 0) | 5680 | if (err < 0) |
5398 | return err; | 5681 | return err; |
5682 | err = alc_auto_add_multi_channel_mode(codec); | ||
5683 | if (err < 0) | ||
5684 | return err; | ||
5399 | err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); | 5685 | err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); |
5400 | if (err < 0) | 5686 | if (err < 0) |
5401 | return err; | 5687 | return err; |
@@ -5467,6 +5753,12 @@ static void fixup_automic_adc(struct hda_codec *codec) | |||
5467 | spec->capsrc_nids += i; | 5753 | spec->capsrc_nids += i; |
5468 | spec->adc_nids += i; | 5754 | spec->adc_nids += i; |
5469 | spec->num_adc_nids = 1; | 5755 | spec->num_adc_nids = 1; |
5756 | /* optional dock-mic */ | ||
5757 | eidx = get_connection_index(codec, cap, spec->dock_mic.pin); | ||
5758 | if (eidx < 0) | ||
5759 | spec->dock_mic.pin = 0; | ||
5760 | else | ||
5761 | spec->dock_mic.mux_idx = eidx; | ||
5470 | return; | 5762 | return; |
5471 | } | 5763 | } |
5472 | snd_printd(KERN_INFO "hda_codec: %s: " | 5764 | snd_printd(KERN_INFO "hda_codec: %s: " |
@@ -5494,6 +5786,8 @@ static int init_capsrc_for_pin(struct hda_codec *codec, hda_nid_t pin) | |||
5494 | struct alc_spec *spec = codec->spec; | 5786 | struct alc_spec *spec = codec->spec; |
5495 | int i; | 5787 | int i; |
5496 | 5788 | ||
5789 | if (!pin) | ||
5790 | return 0; | ||
5497 | for (i = 0; i < spec->num_adc_nids; i++) { | 5791 | for (i = 0; i < spec->num_adc_nids; i++) { |
5498 | hda_nid_t cap = spec->capsrc_nids ? | 5792 | hda_nid_t cap = spec->capsrc_nids ? |
5499 | spec->capsrc_nids[i] : spec->adc_nids[i]; | 5793 | spec->capsrc_nids[i] : spec->adc_nids[i]; |
@@ -5534,6 +5828,7 @@ static void fixup_dual_adc_switch(struct hda_codec *codec) | |||
5534 | { | 5828 | { |
5535 | struct alc_spec *spec = codec->spec; | 5829 | struct alc_spec *spec = codec->spec; |
5536 | init_capsrc_for_pin(codec, spec->ext_mic.pin); | 5830 | init_capsrc_for_pin(codec, spec->ext_mic.pin); |
5831 | init_capsrc_for_pin(codec, spec->dock_mic.pin); | ||
5537 | init_capsrc_for_pin(codec, spec->int_mic.pin); | 5832 | init_capsrc_for_pin(codec, spec->int_mic.pin); |
5538 | } | 5833 | } |
5539 | 5834 | ||
@@ -5550,7 +5845,7 @@ static void alc_init_special_input_src(struct hda_codec *codec) | |||
5550 | static void set_capture_mixer(struct hda_codec *codec) | 5845 | static void set_capture_mixer(struct hda_codec *codec) |
5551 | { | 5846 | { |
5552 | struct alc_spec *spec = codec->spec; | 5847 | struct alc_spec *spec = codec->spec; |
5553 | static struct snd_kcontrol_new *caps[2][3] = { | 5848 | static const struct snd_kcontrol_new *caps[2][3] = { |
5554 | { alc_capture_mixer_nosrc1, | 5849 | { alc_capture_mixer_nosrc1, |
5555 | alc_capture_mixer_nosrc2, | 5850 | alc_capture_mixer_nosrc2, |
5556 | alc_capture_mixer_nosrc3 }, | 5851 | alc_capture_mixer_nosrc3 }, |
@@ -5576,7 +5871,7 @@ static void set_capture_mixer(struct hda_codec *codec) | |||
5576 | } | 5871 | } |
5577 | 5872 | ||
5578 | /* fill adc_nids (and capsrc_nids) containing all active input pins */ | 5873 | /* fill adc_nids (and capsrc_nids) containing all active input pins */ |
5579 | static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | 5874 | static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids, |
5580 | int num_nids) | 5875 | int num_nids) |
5581 | { | 5876 | { |
5582 | struct alc_spec *spec = codec->spec; | 5877 | struct alc_spec *spec = codec->spec; |
@@ -5642,9 +5937,11 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, | |||
5642 | #define set_beep_amp(spec, nid, idx, dir) \ | 5937 | #define set_beep_amp(spec, nid, idx, dir) \ |
5643 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) | 5938 | ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) |
5644 | 5939 | ||
5645 | static struct snd_pci_quirk beep_white_list[] = { | 5940 | static const struct snd_pci_quirk beep_white_list[] = { |
5646 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), | 5941 | SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), |
5647 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), | 5942 | SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), |
5943 | SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), | ||
5944 | SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), | ||
5648 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), | 5945 | SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), |
5649 | {} | 5946 | {} |
5650 | }; | 5947 | }; |
@@ -5752,17 +6049,17 @@ static int patch_alc880(struct hda_codec *codec) | |||
5752 | * ALC260 support | 6049 | * ALC260 support |
5753 | */ | 6050 | */ |
5754 | 6051 | ||
5755 | static hda_nid_t alc260_dac_nids[1] = { | 6052 | static const hda_nid_t alc260_dac_nids[1] = { |
5756 | /* front */ | 6053 | /* front */ |
5757 | 0x02, | 6054 | 0x02, |
5758 | }; | 6055 | }; |
5759 | 6056 | ||
5760 | static hda_nid_t alc260_adc_nids[1] = { | 6057 | static const hda_nid_t alc260_adc_nids[1] = { |
5761 | /* ADC0 */ | 6058 | /* ADC0 */ |
5762 | 0x04, | 6059 | 0x04, |
5763 | }; | 6060 | }; |
5764 | 6061 | ||
5765 | static hda_nid_t alc260_adc_nids_alt[1] = { | 6062 | static const hda_nid_t alc260_adc_nids_alt[1] = { |
5766 | /* ADC1 */ | 6063 | /* ADC1 */ |
5767 | 0x05, | 6064 | 0x05, |
5768 | }; | 6065 | }; |
@@ -5770,7 +6067,7 @@ static hda_nid_t alc260_adc_nids_alt[1] = { | |||
5770 | /* NIDs used when simultaneous access to both ADCs makes sense. Note that | 6067 | /* NIDs used when simultaneous access to both ADCs makes sense. Note that |
5771 | * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. | 6068 | * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. |
5772 | */ | 6069 | */ |
5773 | static hda_nid_t alc260_dual_adc_nids[2] = { | 6070 | static const hda_nid_t alc260_dual_adc_nids[2] = { |
5774 | /* ADC0, ADC1 */ | 6071 | /* ADC0, ADC1 */ |
5775 | 0x04, 0x05 | 6072 | 0x04, 0x05 |
5776 | }; | 6073 | }; |
@@ -5778,7 +6075,7 @@ static hda_nid_t alc260_dual_adc_nids[2] = { | |||
5778 | #define ALC260_DIGOUT_NID 0x03 | 6075 | #define ALC260_DIGOUT_NID 0x03 |
5779 | #define ALC260_DIGIN_NID 0x06 | 6076 | #define ALC260_DIGIN_NID 0x06 |
5780 | 6077 | ||
5781 | static struct hda_input_mux alc260_capture_source = { | 6078 | static const struct hda_input_mux alc260_capture_source = { |
5782 | .num_items = 4, | 6079 | .num_items = 4, |
5783 | .items = { | 6080 | .items = { |
5784 | { "Mic", 0x0 }, | 6081 | { "Mic", 0x0 }, |
@@ -5794,7 +6091,7 @@ static struct hda_input_mux alc260_capture_source = { | |||
5794 | * recording the mixer output on the second ADC (ADC0 doesn't have a | 6091 | * recording the mixer output on the second ADC (ADC0 doesn't have a |
5795 | * connection to the mixer output). | 6092 | * connection to the mixer output). |
5796 | */ | 6093 | */ |
5797 | static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { | 6094 | static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = { |
5798 | { | 6095 | { |
5799 | .num_items = 3, | 6096 | .num_items = 3, |
5800 | .items = { | 6097 | .items = { |
@@ -5818,7 +6115,7 @@ static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { | |||
5818 | /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to | 6115 | /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to |
5819 | * the Fujitsu S702x, but jacks are marked differently. | 6116 | * the Fujitsu S702x, but jacks are marked differently. |
5820 | */ | 6117 | */ |
5821 | static struct hda_input_mux alc260_acer_capture_sources[2] = { | 6118 | static const struct hda_input_mux alc260_acer_capture_sources[2] = { |
5822 | { | 6119 | { |
5823 | .num_items = 4, | 6120 | .num_items = 4, |
5824 | .items = { | 6121 | .items = { |
@@ -5841,7 +6138,7 @@ static struct hda_input_mux alc260_acer_capture_sources[2] = { | |||
5841 | }; | 6138 | }; |
5842 | 6139 | ||
5843 | /* Maxdata Favorit 100XS */ | 6140 | /* Maxdata Favorit 100XS */ |
5844 | static struct hda_input_mux alc260_favorit100_capture_sources[2] = { | 6141 | static const struct hda_input_mux alc260_favorit100_capture_sources[2] = { |
5845 | { | 6142 | { |
5846 | .num_items = 2, | 6143 | .num_items = 2, |
5847 | .items = { | 6144 | .items = { |
@@ -5865,7 +6162,7 @@ static struct hda_input_mux alc260_favorit100_capture_sources[2] = { | |||
5865 | * element which allows changing the channel mode, so the verb list is | 6162 | * element which allows changing the channel mode, so the verb list is |
5866 | * never used. | 6163 | * never used. |
5867 | */ | 6164 | */ |
5868 | static struct hda_channel_mode alc260_modes[1] = { | 6165 | static const struct hda_channel_mode alc260_modes[1] = { |
5869 | { 2, NULL }, | 6166 | { 2, NULL }, |
5870 | }; | 6167 | }; |
5871 | 6168 | ||
@@ -5879,7 +6176,7 @@ static struct hda_channel_mode alc260_modes[1] = { | |||
5879 | * acer: acer + capture | 6176 | * acer: acer + capture |
5880 | */ | 6177 | */ |
5881 | 6178 | ||
5882 | static struct snd_kcontrol_new alc260_base_output_mixer[] = { | 6179 | static const struct snd_kcontrol_new alc260_base_output_mixer[] = { |
5883 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 6180 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
5884 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | 6181 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), |
5885 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), | 6182 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), |
@@ -5889,7 +6186,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = { | |||
5889 | { } /* end */ | 6186 | { } /* end */ |
5890 | }; | 6187 | }; |
5891 | 6188 | ||
5892 | static struct snd_kcontrol_new alc260_input_mixer[] = { | 6189 | static const struct snd_kcontrol_new alc260_input_mixer[] = { |
5893 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), | 6190 | HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), |
5894 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), | 6191 | HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), |
5895 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), | 6192 | HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), |
@@ -5902,21 +6199,14 @@ static struct snd_kcontrol_new alc260_input_mixer[] = { | |||
5902 | }; | 6199 | }; |
5903 | 6200 | ||
5904 | /* update HP, line and mono out pins according to the master switch */ | 6201 | /* update HP, line and mono out pins according to the master switch */ |
5905 | static void alc260_hp_master_update(struct hda_codec *codec, | 6202 | static void alc260_hp_master_update(struct hda_codec *codec) |
5906 | hda_nid_t hp, hda_nid_t line, | ||
5907 | hda_nid_t mono) | ||
5908 | { | 6203 | { |
5909 | struct alc_spec *spec = codec->spec; | 6204 | struct alc_spec *spec = codec->spec; |
5910 | unsigned int val = spec->master_sw ? PIN_HP : 0; | 6205 | |
5911 | /* change HP and line-out pins */ | 6206 | /* change HP pins */ |
5912 | snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 6207 | do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), |
5913 | val); | 6208 | spec->autocfg.hp_pins, spec->master_mute, true); |
5914 | snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | 6209 | update_speakers(codec); |
5915 | val); | ||
5916 | /* mono (speaker) depending on the HP jack sense */ | ||
5917 | val = (val && !spec->jack_present) ? PIN_OUT : 0; | ||
5918 | snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
5919 | val); | ||
5920 | } | 6210 | } |
5921 | 6211 | ||
5922 | static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, | 6212 | static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, |
@@ -5924,7 +6214,7 @@ static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, | |||
5924 | { | 6214 | { |
5925 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 6215 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
5926 | struct alc_spec *spec = codec->spec; | 6216 | struct alc_spec *spec = codec->spec; |
5927 | *ucontrol->value.integer.value = spec->master_sw; | 6217 | *ucontrol->value.integer.value = !spec->master_mute; |
5928 | return 0; | 6218 | return 0; |
5929 | } | 6219 | } |
5930 | 6220 | ||
@@ -5933,20 +6223,16 @@ static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
5933 | { | 6223 | { |
5934 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 6224 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
5935 | struct alc_spec *spec = codec->spec; | 6225 | struct alc_spec *spec = codec->spec; |
5936 | int val = !!*ucontrol->value.integer.value; | 6226 | int val = !*ucontrol->value.integer.value; |
5937 | hda_nid_t hp, line, mono; | ||
5938 | 6227 | ||
5939 | if (val == spec->master_sw) | 6228 | if (val == spec->master_mute) |
5940 | return 0; | 6229 | return 0; |
5941 | spec->master_sw = val; | 6230 | spec->master_mute = val; |
5942 | hp = (kcontrol->private_value >> 16) & 0xff; | 6231 | alc260_hp_master_update(codec); |
5943 | line = (kcontrol->private_value >> 8) & 0xff; | ||
5944 | mono = kcontrol->private_value & 0xff; | ||
5945 | alc260_hp_master_update(codec, hp, line, mono); | ||
5946 | return 1; | 6232 | return 1; |
5947 | } | 6233 | } |
5948 | 6234 | ||
5949 | static struct snd_kcontrol_new alc260_hp_output_mixer[] = { | 6235 | static const struct snd_kcontrol_new alc260_hp_output_mixer[] = { |
5950 | { | 6236 | { |
5951 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 6237 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
5952 | .name = "Master Playback Switch", | 6238 | .name = "Master Playback Switch", |
@@ -5954,7 +6240,6 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = { | |||
5954 | .info = snd_ctl_boolean_mono_info, | 6240 | .info = snd_ctl_boolean_mono_info, |
5955 | .get = alc260_hp_master_sw_get, | 6241 | .get = alc260_hp_master_sw_get, |
5956 | .put = alc260_hp_master_sw_put, | 6242 | .put = alc260_hp_master_sw_put, |
5957 | .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 | ||
5958 | }, | 6243 | }, |
5959 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 6244 | HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
5960 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), | 6245 | HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), |
@@ -5966,26 +6251,23 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = { | |||
5966 | { } /* end */ | 6251 | { } /* end */ |
5967 | }; | 6252 | }; |
5968 | 6253 | ||
5969 | static struct hda_verb alc260_hp_unsol_verbs[] = { | 6254 | static const struct hda_verb alc260_hp_unsol_verbs[] = { |
5970 | {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | 6255 | {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
5971 | {}, | 6256 | {}, |
5972 | }; | 6257 | }; |
5973 | 6258 | ||
5974 | static void alc260_hp_automute(struct hda_codec *codec) | 6259 | static void alc260_hp_setup(struct hda_codec *codec) |
5975 | { | 6260 | { |
5976 | struct alc_spec *spec = codec->spec; | 6261 | struct alc_spec *spec = codec->spec; |
5977 | 6262 | ||
5978 | spec->jack_present = snd_hda_jack_detect(codec, 0x10); | 6263 | spec->autocfg.hp_pins[0] = 0x0f; |
5979 | alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); | 6264 | spec->autocfg.speaker_pins[0] = 0x10; |
5980 | } | 6265 | spec->autocfg.speaker_pins[1] = 0x11; |
5981 | 6266 | spec->automute = 1; | |
5982 | static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) | 6267 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
5983 | { | ||
5984 | if ((res >> 26) == ALC880_HP_EVENT) | ||
5985 | alc260_hp_automute(codec); | ||
5986 | } | 6268 | } |
5987 | 6269 | ||
5988 | static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { | 6270 | static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = { |
5989 | { | 6271 | { |
5990 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 6272 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
5991 | .name = "Master Playback Switch", | 6273 | .name = "Master Playback Switch", |
@@ -5993,7 +6275,6 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { | |||
5993 | .info = snd_ctl_boolean_mono_info, | 6275 | .info = snd_ctl_boolean_mono_info, |
5994 | .get = alc260_hp_master_sw_get, | 6276 | .get = alc260_hp_master_sw_get, |
5995 | .put = alc260_hp_master_sw_put, | 6277 | .put = alc260_hp_master_sw_put, |
5996 | .private_value = (0x15 << 16) | (0x10 << 8) | 0x11 | ||
5997 | }, | 6278 | }, |
5998 | HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), | 6279 | HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), |
5999 | HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), | 6280 | HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), |
@@ -6006,7 +6287,18 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { | |||
6006 | { } /* end */ | 6287 | { } /* end */ |
6007 | }; | 6288 | }; |
6008 | 6289 | ||
6009 | static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { | 6290 | static void alc260_hp_3013_setup(struct hda_codec *codec) |
6291 | { | ||
6292 | struct alc_spec *spec = codec->spec; | ||
6293 | |||
6294 | spec->autocfg.hp_pins[0] = 0x15; | ||
6295 | spec->autocfg.speaker_pins[0] = 0x10; | ||
6296 | spec->autocfg.speaker_pins[1] = 0x11; | ||
6297 | spec->automute = 1; | ||
6298 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
6299 | } | ||
6300 | |||
6301 | static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = { | ||
6010 | .ops = &snd_hda_bind_vol, | 6302 | .ops = &snd_hda_bind_vol, |
6011 | .values = { | 6303 | .values = { |
6012 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), | 6304 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), |
@@ -6016,7 +6308,7 @@ static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { | |||
6016 | }, | 6308 | }, |
6017 | }; | 6309 | }; |
6018 | 6310 | ||
6019 | static struct hda_bind_ctls alc260_dc7600_bind_switch = { | 6311 | static const struct hda_bind_ctls alc260_dc7600_bind_switch = { |
6020 | .ops = &snd_hda_bind_sw, | 6312 | .ops = &snd_hda_bind_sw, |
6021 | .values = { | 6313 | .values = { |
6022 | HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), | 6314 | HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), |
@@ -6025,7 +6317,7 @@ static struct hda_bind_ctls alc260_dc7600_bind_switch = { | |||
6025 | }, | 6317 | }, |
6026 | }; | 6318 | }; |
6027 | 6319 | ||
6028 | static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { | 6320 | static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { |
6029 | HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), | 6321 | HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), |
6030 | HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), | 6322 | HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), |
6031 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), | 6323 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), |
@@ -6033,49 +6325,27 @@ static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { | |||
6033 | { } /* end */ | 6325 | { } /* end */ |
6034 | }; | 6326 | }; |
6035 | 6327 | ||
6036 | static struct hda_verb alc260_hp_3013_unsol_verbs[] = { | 6328 | static const struct hda_verb alc260_hp_3013_unsol_verbs[] = { |
6037 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | 6329 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
6038 | {}, | 6330 | {}, |
6039 | }; | 6331 | }; |
6040 | 6332 | ||
6041 | static void alc260_hp_3013_automute(struct hda_codec *codec) | 6333 | static void alc260_hp_3012_setup(struct hda_codec *codec) |
6042 | { | 6334 | { |
6043 | struct alc_spec *spec = codec->spec; | 6335 | struct alc_spec *spec = codec->spec; |
6044 | 6336 | ||
6045 | spec->jack_present = snd_hda_jack_detect(codec, 0x15); | 6337 | spec->autocfg.hp_pins[0] = 0x10; |
6046 | alc260_hp_master_update(codec, 0x15, 0x10, 0x11); | 6338 | spec->autocfg.speaker_pins[0] = 0x0f; |
6047 | } | 6339 | spec->autocfg.speaker_pins[1] = 0x11; |
6048 | 6340 | spec->autocfg.speaker_pins[2] = 0x15; | |
6049 | static void alc260_hp_3013_unsol_event(struct hda_codec *codec, | 6341 | spec->automute = 1; |
6050 | unsigned int res) | 6342 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
6051 | { | ||
6052 | if ((res >> 26) == ALC880_HP_EVENT) | ||
6053 | alc260_hp_3013_automute(codec); | ||
6054 | } | ||
6055 | |||
6056 | static void alc260_hp_3012_automute(struct hda_codec *codec) | ||
6057 | { | ||
6058 | unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; | ||
6059 | |||
6060 | snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
6061 | bits); | ||
6062 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
6063 | bits); | ||
6064 | snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
6065 | bits); | ||
6066 | } | ||
6067 | |||
6068 | static void alc260_hp_3012_unsol_event(struct hda_codec *codec, | ||
6069 | unsigned int res) | ||
6070 | { | ||
6071 | if ((res >> 26) == ALC880_HP_EVENT) | ||
6072 | alc260_hp_3012_automute(codec); | ||
6073 | } | 6343 | } |
6074 | 6344 | ||
6075 | /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, | 6345 | /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, |
6076 | * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. | 6346 | * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. |
6077 | */ | 6347 | */ |
6078 | static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { | 6348 | static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = { |
6079 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 6349 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
6080 | HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), | 6350 | HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), |
6081 | ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), | 6351 | ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), |
@@ -6112,7 +6382,7 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { | |||
6112 | * controls for such models. On models without a "mono speaker" the control | 6382 | * controls for such models. On models without a "mono speaker" the control |
6113 | * won't do anything. | 6383 | * won't do anything. |
6114 | */ | 6384 | */ |
6115 | static struct snd_kcontrol_new alc260_acer_mixer[] = { | 6385 | static const struct snd_kcontrol_new alc260_acer_mixer[] = { |
6116 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 6386 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
6117 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), | 6387 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), |
6118 | ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), | 6388 | ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), |
@@ -6133,7 +6403,7 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { | |||
6133 | 6403 | ||
6134 | /* Maxdata Favorit 100XS: one output and one input (0x12) jack | 6404 | /* Maxdata Favorit 100XS: one output and one input (0x12) jack |
6135 | */ | 6405 | */ |
6136 | static struct snd_kcontrol_new alc260_favorit100_mixer[] = { | 6406 | static const struct snd_kcontrol_new alc260_favorit100_mixer[] = { |
6137 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 6407 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
6138 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), | 6408 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), |
6139 | ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), | 6409 | ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), |
@@ -6146,7 +6416,7 @@ static struct snd_kcontrol_new alc260_favorit100_mixer[] = { | |||
6146 | /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, | 6416 | /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, |
6147 | * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. | 6417 | * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. |
6148 | */ | 6418 | */ |
6149 | static struct snd_kcontrol_new alc260_will_mixer[] = { | 6419 | static const struct snd_kcontrol_new alc260_will_mixer[] = { |
6150 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 6420 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
6151 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), | 6421 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), |
6152 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | 6422 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), |
@@ -6163,7 +6433,7 @@ static struct snd_kcontrol_new alc260_will_mixer[] = { | |||
6163 | /* Replacer 672V ALC260 pin usage: Mic jack = 0x12, | 6433 | /* Replacer 672V ALC260 pin usage: Mic jack = 0x12, |
6164 | * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. | 6434 | * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. |
6165 | */ | 6435 | */ |
6166 | static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { | 6436 | static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { |
6167 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), | 6437 | HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), |
6168 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), | 6438 | HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), |
6169 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), | 6439 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), |
@@ -6180,7 +6450,7 @@ static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { | |||
6180 | /* | 6450 | /* |
6181 | * initialization verbs | 6451 | * initialization verbs |
6182 | */ | 6452 | */ |
6183 | static struct hda_verb alc260_init_verbs[] = { | 6453 | static const struct hda_verb alc260_init_verbs[] = { |
6184 | /* Line In pin widget for input */ | 6454 | /* Line In pin widget for input */ |
6185 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 6455 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
6186 | /* CD pin widget for input */ | 6456 | /* CD pin widget for input */ |
@@ -6244,7 +6514,7 @@ static struct hda_verb alc260_init_verbs[] = { | |||
6244 | }; | 6514 | }; |
6245 | 6515 | ||
6246 | #if 0 /* should be identical with alc260_init_verbs? */ | 6516 | #if 0 /* should be identical with alc260_init_verbs? */ |
6247 | static struct hda_verb alc260_hp_init_verbs[] = { | 6517 | static const struct hda_verb alc260_hp_init_verbs[] = { |
6248 | /* Headphone and output */ | 6518 | /* Headphone and output */ |
6249 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | 6519 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, |
6250 | /* mono output */ | 6520 | /* mono output */ |
@@ -6294,7 +6564,7 @@ static struct hda_verb alc260_hp_init_verbs[] = { | |||
6294 | }; | 6564 | }; |
6295 | #endif | 6565 | #endif |
6296 | 6566 | ||
6297 | static struct hda_verb alc260_hp_3013_init_verbs[] = { | 6567 | static const struct hda_verb alc260_hp_3013_init_verbs[] = { |
6298 | /* Line out and output */ | 6568 | /* Line out and output */ |
6299 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | 6569 | {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, |
6300 | /* mono output */ | 6570 | /* mono output */ |
@@ -6347,7 +6617,7 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = { | |||
6347 | * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD | 6617 | * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD |
6348 | * audio = 0x16, internal speaker = 0x10. | 6618 | * audio = 0x16, internal speaker = 0x10. |
6349 | */ | 6619 | */ |
6350 | static struct hda_verb alc260_fujitsu_init_verbs[] = { | 6620 | static const struct hda_verb alc260_fujitsu_init_verbs[] = { |
6351 | /* Disable all GPIOs */ | 6621 | /* Disable all GPIOs */ |
6352 | {0x01, AC_VERB_SET_GPIO_MASK, 0}, | 6622 | {0x01, AC_VERB_SET_GPIO_MASK, 0}, |
6353 | /* Internal speaker is connected to headphone pin */ | 6623 | /* Internal speaker is connected to headphone pin */ |
@@ -6429,7 +6699,7 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = { | |||
6429 | /* Initialisation sequence for ALC260 as configured in Acer TravelMate and | 6699 | /* Initialisation sequence for ALC260 as configured in Acer TravelMate and |
6430 | * similar laptops (adapted from Fujitsu init verbs). | 6700 | * similar laptops (adapted from Fujitsu init verbs). |
6431 | */ | 6701 | */ |
6432 | static struct hda_verb alc260_acer_init_verbs[] = { | 6702 | static const struct hda_verb alc260_acer_init_verbs[] = { |
6433 | /* On TravelMate laptops, GPIO 0 enables the internal speaker and | 6703 | /* On TravelMate laptops, GPIO 0 enables the internal speaker and |
6434 | * the headphone jack. Turn this on and rely on the standard mute | 6704 | * the headphone jack. Turn this on and rely on the standard mute |
6435 | * methods whenever the user wants to turn these outputs off. | 6705 | * methods whenever the user wants to turn these outputs off. |
@@ -6517,7 +6787,7 @@ static struct hda_verb alc260_acer_init_verbs[] = { | |||
6517 | /* Initialisation sequence for Maxdata Favorit 100XS | 6787 | /* Initialisation sequence for Maxdata Favorit 100XS |
6518 | * (adapted from Acer init verbs). | 6788 | * (adapted from Acer init verbs). |
6519 | */ | 6789 | */ |
6520 | static struct hda_verb alc260_favorit100_init_verbs[] = { | 6790 | static const struct hda_verb alc260_favorit100_init_verbs[] = { |
6521 | /* GPIO 0 enables the output jack. | 6791 | /* GPIO 0 enables the output jack. |
6522 | * Turn this on and rely on the standard mute | 6792 | * Turn this on and rely on the standard mute |
6523 | * methods whenever the user wants to turn these outputs off. | 6793 | * methods whenever the user wants to turn these outputs off. |
@@ -6597,7 +6867,7 @@ static struct hda_verb alc260_favorit100_init_verbs[] = { | |||
6597 | { } | 6867 | { } |
6598 | }; | 6868 | }; |
6599 | 6869 | ||
6600 | static struct hda_verb alc260_will_verbs[] = { | 6870 | static const struct hda_verb alc260_will_verbs[] = { |
6601 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 6871 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
6602 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, | 6872 | {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, |
6603 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, | 6873 | {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -6607,7 +6877,7 @@ static struct hda_verb alc260_will_verbs[] = { | |||
6607 | {} | 6877 | {} |
6608 | }; | 6878 | }; |
6609 | 6879 | ||
6610 | static struct hda_verb alc260_replacer_672v_verbs[] = { | 6880 | static const struct hda_verb alc260_replacer_672v_verbs[] = { |
6611 | {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | 6881 | {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, |
6612 | {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, | 6882 | {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, |
6613 | {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, | 6883 | {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, |
@@ -6649,7 +6919,7 @@ static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, | |||
6649 | alc260_replacer_672v_automute(codec); | 6919 | alc260_replacer_672v_automute(codec); |
6650 | } | 6920 | } |
6651 | 6921 | ||
6652 | static struct hda_verb alc260_hp_dc7600_verbs[] = { | 6922 | static const struct hda_verb alc260_hp_dc7600_verbs[] = { |
6653 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, | 6923 | {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, |
6654 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | 6924 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, |
6655 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 6925 | {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
@@ -6667,17 +6937,17 @@ static struct hda_verb alc260_hp_dc7600_verbs[] = { | |||
6667 | * configuration. | 6937 | * configuration. |
6668 | */ | 6938 | */ |
6669 | #ifdef CONFIG_SND_DEBUG | 6939 | #ifdef CONFIG_SND_DEBUG |
6670 | static hda_nid_t alc260_test_dac_nids[1] = { | 6940 | static const hda_nid_t alc260_test_dac_nids[1] = { |
6671 | 0x02, | 6941 | 0x02, |
6672 | }; | 6942 | }; |
6673 | static hda_nid_t alc260_test_adc_nids[2] = { | 6943 | static const hda_nid_t alc260_test_adc_nids[2] = { |
6674 | 0x04, 0x05, | 6944 | 0x04, 0x05, |
6675 | }; | 6945 | }; |
6676 | /* For testing the ALC260, each input MUX needs its own definition since | 6946 | /* For testing the ALC260, each input MUX needs its own definition since |
6677 | * the signal assignments are different. This assumes that the first ADC | 6947 | * the signal assignments are different. This assumes that the first ADC |
6678 | * is NID 0x04. | 6948 | * is NID 0x04. |
6679 | */ | 6949 | */ |
6680 | static struct hda_input_mux alc260_test_capture_sources[2] = { | 6950 | static const struct hda_input_mux alc260_test_capture_sources[2] = { |
6681 | { | 6951 | { |
6682 | .num_items = 7, | 6952 | .num_items = 7, |
6683 | .items = { | 6953 | .items = { |
@@ -6704,7 +6974,7 @@ static struct hda_input_mux alc260_test_capture_sources[2] = { | |||
6704 | }, | 6974 | }, |
6705 | }, | 6975 | }, |
6706 | }; | 6976 | }; |
6707 | static struct snd_kcontrol_new alc260_test_mixer[] = { | 6977 | static const struct snd_kcontrol_new alc260_test_mixer[] = { |
6708 | /* Output driver widgets */ | 6978 | /* Output driver widgets */ |
6709 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), | 6979 | HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), |
6710 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), | 6980 | HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), |
@@ -6768,7 +7038,7 @@ static struct snd_kcontrol_new alc260_test_mixer[] = { | |||
6768 | 7038 | ||
6769 | { } /* end */ | 7039 | { } /* end */ |
6770 | }; | 7040 | }; |
6771 | static struct hda_verb alc260_test_init_verbs[] = { | 7041 | static const struct hda_verb alc260_test_init_verbs[] = { |
6772 | /* Enable all GPIOs as outputs with an initial value of 0 */ | 7042 | /* Enable all GPIOs as outputs with an initial value of 0 */ |
6773 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, | 7043 | {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, |
6774 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, | 7044 | {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, |
@@ -6906,7 +7176,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
6906 | 7176 | ||
6907 | spec->multiout.num_dacs = 1; | 7177 | spec->multiout.num_dacs = 1; |
6908 | spec->multiout.dac_nids = spec->private_dac_nids; | 7178 | spec->multiout.dac_nids = spec->private_dac_nids; |
6909 | spec->multiout.dac_nids[0] = 0x02; | 7179 | spec->private_dac_nids[0] = 0x02; |
6910 | 7180 | ||
6911 | nid = cfg->line_out_pins[0]; | 7181 | nid = cfg->line_out_pins[0]; |
6912 | if (nid) { | 7182 | if (nid) { |
@@ -7004,7 +7274,7 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) | |||
7004 | /* | 7274 | /* |
7005 | * generic initialization of ADC, input mixers and output mixers | 7275 | * generic initialization of ADC, input mixers and output mixers |
7006 | */ | 7276 | */ |
7007 | static struct hda_verb alc260_volume_init_verbs[] = { | 7277 | static const struct hda_verb alc260_volume_init_verbs[] = { |
7008 | /* | 7278 | /* |
7009 | * Unmute ADC0-1 and set the default input to mic-in | 7279 | * Unmute ADC0-1 and set the default input to mic-in |
7010 | */ | 7280 | */ |
@@ -7049,7 +7319,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec) | |||
7049 | { | 7319 | { |
7050 | struct alc_spec *spec = codec->spec; | 7320 | struct alc_spec *spec = codec->spec; |
7051 | int err; | 7321 | int err; |
7052 | static hda_nid_t alc260_ignore[] = { 0x17, 0 }; | 7322 | static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; |
7053 | 7323 | ||
7054 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 7324 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
7055 | alc260_ignore); | 7325 | alc260_ignore); |
@@ -7094,7 +7364,7 @@ static void alc260_auto_init(struct hda_codec *codec) | |||
7094 | } | 7364 | } |
7095 | 7365 | ||
7096 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 7366 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
7097 | static struct hda_amp_list alc260_loopbacks[] = { | 7367 | static const struct hda_amp_list alc260_loopbacks[] = { |
7098 | { 0x07, HDA_INPUT, 0 }, | 7368 | { 0x07, HDA_INPUT, 0 }, |
7099 | { 0x07, HDA_INPUT, 1 }, | 7369 | { 0x07, HDA_INPUT, 1 }, |
7100 | { 0x07, HDA_INPUT, 2 }, | 7370 | { 0x07, HDA_INPUT, 2 }, |
@@ -7121,7 +7391,7 @@ static const struct alc_fixup alc260_fixups[] = { | |||
7121 | }, | 7391 | }, |
7122 | }; | 7392 | }; |
7123 | 7393 | ||
7124 | static struct snd_pci_quirk alc260_fixup_tbl[] = { | 7394 | static const struct snd_pci_quirk alc260_fixup_tbl[] = { |
7125 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), | 7395 | SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), |
7126 | {} | 7396 | {} |
7127 | }; | 7397 | }; |
@@ -7145,7 +7415,7 @@ static const char * const alc260_models[ALC260_MODEL_LAST] = { | |||
7145 | [ALC260_AUTO] = "auto", | 7415 | [ALC260_AUTO] = "auto", |
7146 | }; | 7416 | }; |
7147 | 7417 | ||
7148 | static struct snd_pci_quirk alc260_cfg_tbl[] = { | 7418 | static const struct snd_pci_quirk alc260_cfg_tbl[] = { |
7149 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), | 7419 | SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), |
7150 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), | 7420 | SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), |
7151 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), | 7421 | SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), |
@@ -7169,7 +7439,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { | |||
7169 | {} | 7439 | {} |
7170 | }; | 7440 | }; |
7171 | 7441 | ||
7172 | static struct alc_config_preset alc260_presets[] = { | 7442 | static const struct alc_config_preset alc260_presets[] = { |
7173 | [ALC260_BASIC] = { | 7443 | [ALC260_BASIC] = { |
7174 | .mixers = { alc260_base_output_mixer, | 7444 | .mixers = { alc260_base_output_mixer, |
7175 | alc260_input_mixer }, | 7445 | alc260_input_mixer }, |
@@ -7194,8 +7464,9 @@ static struct alc_config_preset alc260_presets[] = { | |||
7194 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | 7464 | .num_channel_mode = ARRAY_SIZE(alc260_modes), |
7195 | .channel_mode = alc260_modes, | 7465 | .channel_mode = alc260_modes, |
7196 | .input_mux = &alc260_capture_source, | 7466 | .input_mux = &alc260_capture_source, |
7197 | .unsol_event = alc260_hp_unsol_event, | 7467 | .unsol_event = alc_sku_unsol_event, |
7198 | .init_hook = alc260_hp_automute, | 7468 | .setup = alc260_hp_setup, |
7469 | .init_hook = alc_inithook, | ||
7199 | }, | 7470 | }, |
7200 | [ALC260_HP_DC7600] = { | 7471 | [ALC260_HP_DC7600] = { |
7201 | .mixers = { alc260_hp_dc7600_mixer, | 7472 | .mixers = { alc260_hp_dc7600_mixer, |
@@ -7209,8 +7480,9 @@ static struct alc_config_preset alc260_presets[] = { | |||
7209 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | 7480 | .num_channel_mode = ARRAY_SIZE(alc260_modes), |
7210 | .channel_mode = alc260_modes, | 7481 | .channel_mode = alc260_modes, |
7211 | .input_mux = &alc260_capture_source, | 7482 | .input_mux = &alc260_capture_source, |
7212 | .unsol_event = alc260_hp_3012_unsol_event, | 7483 | .unsol_event = alc_sku_unsol_event, |
7213 | .init_hook = alc260_hp_3012_automute, | 7484 | .setup = alc260_hp_3012_setup, |
7485 | .init_hook = alc_inithook, | ||
7214 | }, | 7486 | }, |
7215 | [ALC260_HP_3013] = { | 7487 | [ALC260_HP_3013] = { |
7216 | .mixers = { alc260_hp_3013_mixer, | 7488 | .mixers = { alc260_hp_3013_mixer, |
@@ -7224,8 +7496,9 @@ static struct alc_config_preset alc260_presets[] = { | |||
7224 | .num_channel_mode = ARRAY_SIZE(alc260_modes), | 7496 | .num_channel_mode = ARRAY_SIZE(alc260_modes), |
7225 | .channel_mode = alc260_modes, | 7497 | .channel_mode = alc260_modes, |
7226 | .input_mux = &alc260_capture_source, | 7498 | .input_mux = &alc260_capture_source, |
7227 | .unsol_event = alc260_hp_3013_unsol_event, | 7499 | .unsol_event = alc_sku_unsol_event, |
7228 | .init_hook = alc260_hp_3013_automute, | 7500 | .setup = alc260_hp_3013_setup, |
7501 | .init_hook = alc_inithook, | ||
7229 | }, | 7502 | }, |
7230 | [ALC260_FUJITSU_S702X] = { | 7503 | [ALC260_FUJITSU_S702X] = { |
7231 | .mixers = { alc260_fujitsu_mixer }, | 7504 | .mixers = { alc260_fujitsu_mixer }, |
@@ -7383,6 +7656,7 @@ static int patch_alc260(struct hda_codec *codec) | |||
7383 | codec->patch_ops = alc_patch_ops; | 7656 | codec->patch_ops = alc_patch_ops; |
7384 | if (board_config == ALC260_AUTO) | 7657 | if (board_config == ALC260_AUTO) |
7385 | spec->init_hook = alc260_auto_init; | 7658 | spec->init_hook = alc260_auto_init; |
7659 | spec->shutup = alc_eapd_shutup; | ||
7386 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 7660 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
7387 | if (!spec->loopback.amplist) | 7661 | if (!spec->loopback.amplist) |
7388 | spec->loopback.amplist = alc260_loopbacks; | 7662 | spec->loopback.amplist = alc260_loopbacks; |
@@ -7410,12 +7684,12 @@ static int patch_alc260(struct hda_codec *codec) | |||
7410 | #define ALC1200_DIGOUT_NID 0x10 | 7684 | #define ALC1200_DIGOUT_NID 0x10 |
7411 | 7685 | ||
7412 | 7686 | ||
7413 | static struct hda_channel_mode alc882_ch_modes[1] = { | 7687 | static const struct hda_channel_mode alc882_ch_modes[1] = { |
7414 | { 8, NULL } | 7688 | { 8, NULL } |
7415 | }; | 7689 | }; |
7416 | 7690 | ||
7417 | /* DACs */ | 7691 | /* DACs */ |
7418 | static hda_nid_t alc882_dac_nids[4] = { | 7692 | static const hda_nid_t alc882_dac_nids[4] = { |
7419 | /* front, rear, clfe, rear_surr */ | 7693 | /* front, rear, clfe, rear_surr */ |
7420 | 0x02, 0x03, 0x04, 0x05 | 7694 | 0x02, 0x03, 0x04, 0x05 |
7421 | }; | 7695 | }; |
@@ -7425,20 +7699,20 @@ static hda_nid_t alc882_dac_nids[4] = { | |||
7425 | #define alc882_adc_nids alc880_adc_nids | 7699 | #define alc882_adc_nids alc880_adc_nids |
7426 | #define alc882_adc_nids_alt alc880_adc_nids_alt | 7700 | #define alc882_adc_nids_alt alc880_adc_nids_alt |
7427 | #define alc883_adc_nids alc882_adc_nids_alt | 7701 | #define alc883_adc_nids alc882_adc_nids_alt |
7428 | static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; | 7702 | static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; |
7429 | static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; | 7703 | static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; |
7430 | #define alc889_adc_nids alc880_adc_nids | 7704 | #define alc889_adc_nids alc880_adc_nids |
7431 | 7705 | ||
7432 | static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; | 7706 | static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; |
7433 | static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; | 7707 | static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; |
7434 | #define alc883_capsrc_nids alc882_capsrc_nids_alt | 7708 | #define alc883_capsrc_nids alc882_capsrc_nids_alt |
7435 | static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; | 7709 | static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; |
7436 | #define alc889_capsrc_nids alc882_capsrc_nids | 7710 | #define alc889_capsrc_nids alc882_capsrc_nids |
7437 | 7711 | ||
7438 | /* input MUX */ | 7712 | /* input MUX */ |
7439 | /* FIXME: should be a matrix-type input source selection */ | 7713 | /* FIXME: should be a matrix-type input source selection */ |
7440 | 7714 | ||
7441 | static struct hda_input_mux alc882_capture_source = { | 7715 | static const struct hda_input_mux alc882_capture_source = { |
7442 | .num_items = 4, | 7716 | .num_items = 4, |
7443 | .items = { | 7717 | .items = { |
7444 | { "Mic", 0x0 }, | 7718 | { "Mic", 0x0 }, |
@@ -7450,7 +7724,7 @@ static struct hda_input_mux alc882_capture_source = { | |||
7450 | 7724 | ||
7451 | #define alc883_capture_source alc882_capture_source | 7725 | #define alc883_capture_source alc882_capture_source |
7452 | 7726 | ||
7453 | static struct hda_input_mux alc889_capture_source = { | 7727 | static const struct hda_input_mux alc889_capture_source = { |
7454 | .num_items = 3, | 7728 | .num_items = 3, |
7455 | .items = { | 7729 | .items = { |
7456 | { "Front Mic", 0x0 }, | 7730 | { "Front Mic", 0x0 }, |
@@ -7459,7 +7733,7 @@ static struct hda_input_mux alc889_capture_source = { | |||
7459 | }, | 7733 | }, |
7460 | }; | 7734 | }; |
7461 | 7735 | ||
7462 | static struct hda_input_mux mb5_capture_source = { | 7736 | static const struct hda_input_mux mb5_capture_source = { |
7463 | .num_items = 3, | 7737 | .num_items = 3, |
7464 | .items = { | 7738 | .items = { |
7465 | { "Mic", 0x1 }, | 7739 | { "Mic", 0x1 }, |
@@ -7468,7 +7742,7 @@ static struct hda_input_mux mb5_capture_source = { | |||
7468 | }, | 7742 | }, |
7469 | }; | 7743 | }; |
7470 | 7744 | ||
7471 | static struct hda_input_mux macmini3_capture_source = { | 7745 | static const struct hda_input_mux macmini3_capture_source = { |
7472 | .num_items = 2, | 7746 | .num_items = 2, |
7473 | .items = { | 7747 | .items = { |
7474 | { "Line", 0x2 }, | 7748 | { "Line", 0x2 }, |
@@ -7476,7 +7750,7 @@ static struct hda_input_mux macmini3_capture_source = { | |||
7476 | }, | 7750 | }, |
7477 | }; | 7751 | }; |
7478 | 7752 | ||
7479 | static struct hda_input_mux alc883_3stack_6ch_intel = { | 7753 | static const struct hda_input_mux alc883_3stack_6ch_intel = { |
7480 | .num_items = 4, | 7754 | .num_items = 4, |
7481 | .items = { | 7755 | .items = { |
7482 | { "Mic", 0x1 }, | 7756 | { "Mic", 0x1 }, |
@@ -7486,7 +7760,7 @@ static struct hda_input_mux alc883_3stack_6ch_intel = { | |||
7486 | }, | 7760 | }, |
7487 | }; | 7761 | }; |
7488 | 7762 | ||
7489 | static struct hda_input_mux alc883_lenovo_101e_capture_source = { | 7763 | static const struct hda_input_mux alc883_lenovo_101e_capture_source = { |
7490 | .num_items = 2, | 7764 | .num_items = 2, |
7491 | .items = { | 7765 | .items = { |
7492 | { "Mic", 0x1 }, | 7766 | { "Mic", 0x1 }, |
@@ -7494,7 +7768,7 @@ static struct hda_input_mux alc883_lenovo_101e_capture_source = { | |||
7494 | }, | 7768 | }, |
7495 | }; | 7769 | }; |
7496 | 7770 | ||
7497 | static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { | 7771 | static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = { |
7498 | .num_items = 4, | 7772 | .num_items = 4, |
7499 | .items = { | 7773 | .items = { |
7500 | { "Mic", 0x0 }, | 7774 | { "Mic", 0x0 }, |
@@ -7504,7 +7778,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { | |||
7504 | }, | 7778 | }, |
7505 | }; | 7779 | }; |
7506 | 7780 | ||
7507 | static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { | 7781 | static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { |
7508 | .num_items = 2, | 7782 | .num_items = 2, |
7509 | .items = { | 7783 | .items = { |
7510 | { "Mic", 0x0 }, | 7784 | { "Mic", 0x0 }, |
@@ -7512,7 +7786,7 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { | |||
7512 | }, | 7786 | }, |
7513 | }; | 7787 | }; |
7514 | 7788 | ||
7515 | static struct hda_input_mux alc883_lenovo_sky_capture_source = { | 7789 | static const struct hda_input_mux alc883_lenovo_sky_capture_source = { |
7516 | .num_items = 3, | 7790 | .num_items = 3, |
7517 | .items = { | 7791 | .items = { |
7518 | { "Mic", 0x0 }, | 7792 | { "Mic", 0x0 }, |
@@ -7521,7 +7795,7 @@ static struct hda_input_mux alc883_lenovo_sky_capture_source = { | |||
7521 | }, | 7795 | }, |
7522 | }; | 7796 | }; |
7523 | 7797 | ||
7524 | static struct hda_input_mux alc883_asus_eee1601_capture_source = { | 7798 | static const struct hda_input_mux alc883_asus_eee1601_capture_source = { |
7525 | .num_items = 2, | 7799 | .num_items = 2, |
7526 | .items = { | 7800 | .items = { |
7527 | { "Mic", 0x0 }, | 7801 | { "Mic", 0x0 }, |
@@ -7529,7 +7803,7 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = { | |||
7529 | }, | 7803 | }, |
7530 | }; | 7804 | }; |
7531 | 7805 | ||
7532 | static struct hda_input_mux alc889A_mb31_capture_source = { | 7806 | static const struct hda_input_mux alc889A_mb31_capture_source = { |
7533 | .num_items = 2, | 7807 | .num_items = 2, |
7534 | .items = { | 7808 | .items = { |
7535 | { "Mic", 0x0 }, | 7809 | { "Mic", 0x0 }, |
@@ -7540,7 +7814,7 @@ static struct hda_input_mux alc889A_mb31_capture_source = { | |||
7540 | }, | 7814 | }, |
7541 | }; | 7815 | }; |
7542 | 7816 | ||
7543 | static struct hda_input_mux alc889A_imac91_capture_source = { | 7817 | static const struct hda_input_mux alc889A_imac91_capture_source = { |
7544 | .num_items = 2, | 7818 | .num_items = 2, |
7545 | .items = { | 7819 | .items = { |
7546 | { "Mic", 0x01 }, | 7820 | { "Mic", 0x01 }, |
@@ -7551,14 +7825,14 @@ static struct hda_input_mux alc889A_imac91_capture_source = { | |||
7551 | /* | 7825 | /* |
7552 | * 2ch mode | 7826 | * 2ch mode |
7553 | */ | 7827 | */ |
7554 | static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { | 7828 | static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = { |
7555 | { 2, NULL } | 7829 | { 2, NULL } |
7556 | }; | 7830 | }; |
7557 | 7831 | ||
7558 | /* | 7832 | /* |
7559 | * 2ch mode | 7833 | * 2ch mode |
7560 | */ | 7834 | */ |
7561 | static struct hda_verb alc882_3ST_ch2_init[] = { | 7835 | static const struct hda_verb alc882_3ST_ch2_init[] = { |
7562 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 7836 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
7563 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 7837 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
7564 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 7838 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
@@ -7569,7 +7843,7 @@ static struct hda_verb alc882_3ST_ch2_init[] = { | |||
7569 | /* | 7843 | /* |
7570 | * 4ch mode | 7844 | * 4ch mode |
7571 | */ | 7845 | */ |
7572 | static struct hda_verb alc882_3ST_ch4_init[] = { | 7846 | static const struct hda_verb alc882_3ST_ch4_init[] = { |
7573 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 7847 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
7574 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 7848 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
7575 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7849 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -7581,7 +7855,7 @@ static struct hda_verb alc882_3ST_ch4_init[] = { | |||
7581 | /* | 7855 | /* |
7582 | * 6ch mode | 7856 | * 6ch mode |
7583 | */ | 7857 | */ |
7584 | static struct hda_verb alc882_3ST_ch6_init[] = { | 7858 | static const struct hda_verb alc882_3ST_ch6_init[] = { |
7585 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7859 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7586 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 7860 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
7587 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | 7861 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, |
@@ -7591,7 +7865,7 @@ static struct hda_verb alc882_3ST_ch6_init[] = { | |||
7591 | { } /* end */ | 7865 | { } /* end */ |
7592 | }; | 7866 | }; |
7593 | 7867 | ||
7594 | static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { | 7868 | static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = { |
7595 | { 2, alc882_3ST_ch2_init }, | 7869 | { 2, alc882_3ST_ch2_init }, |
7596 | { 4, alc882_3ST_ch4_init }, | 7870 | { 4, alc882_3ST_ch4_init }, |
7597 | { 6, alc882_3ST_ch6_init }, | 7871 | { 6, alc882_3ST_ch6_init }, |
@@ -7602,7 +7876,7 @@ static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { | |||
7602 | /* | 7876 | /* |
7603 | * 2ch mode | 7877 | * 2ch mode |
7604 | */ | 7878 | */ |
7605 | static struct hda_verb alc883_3ST_ch2_clevo_init[] = { | 7879 | static const struct hda_verb alc883_3ST_ch2_clevo_init[] = { |
7606 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, | 7880 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, |
7607 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 7881 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
7608 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 7882 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
@@ -7614,7 +7888,7 @@ static struct hda_verb alc883_3ST_ch2_clevo_init[] = { | |||
7614 | /* | 7888 | /* |
7615 | * 4ch mode | 7889 | * 4ch mode |
7616 | */ | 7890 | */ |
7617 | static struct hda_verb alc883_3ST_ch4_clevo_init[] = { | 7891 | static const struct hda_verb alc883_3ST_ch4_clevo_init[] = { |
7618 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7892 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7619 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 7893 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
7620 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 7894 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
@@ -7627,7 +7901,7 @@ static struct hda_verb alc883_3ST_ch4_clevo_init[] = { | |||
7627 | /* | 7901 | /* |
7628 | * 6ch mode | 7902 | * 6ch mode |
7629 | */ | 7903 | */ |
7630 | static struct hda_verb alc883_3ST_ch6_clevo_init[] = { | 7904 | static const struct hda_verb alc883_3ST_ch6_clevo_init[] = { |
7631 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7905 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7632 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7906 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7633 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 7907 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
@@ -7638,7 +7912,7 @@ static struct hda_verb alc883_3ST_ch6_clevo_init[] = { | |||
7638 | { } /* end */ | 7912 | { } /* end */ |
7639 | }; | 7913 | }; |
7640 | 7914 | ||
7641 | static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { | 7915 | static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { |
7642 | { 2, alc883_3ST_ch2_clevo_init }, | 7916 | { 2, alc883_3ST_ch2_clevo_init }, |
7643 | { 4, alc883_3ST_ch4_clevo_init }, | 7917 | { 4, alc883_3ST_ch4_clevo_init }, |
7644 | { 6, alc883_3ST_ch6_clevo_init }, | 7918 | { 6, alc883_3ST_ch6_clevo_init }, |
@@ -7648,7 +7922,7 @@ static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { | |||
7648 | /* | 7922 | /* |
7649 | * 6ch mode | 7923 | * 6ch mode |
7650 | */ | 7924 | */ |
7651 | static struct hda_verb alc882_sixstack_ch6_init[] = { | 7925 | static const struct hda_verb alc882_sixstack_ch6_init[] = { |
7652 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | 7926 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, |
7653 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7927 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7654 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7928 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -7659,7 +7933,7 @@ static struct hda_verb alc882_sixstack_ch6_init[] = { | |||
7659 | /* | 7933 | /* |
7660 | * 8ch mode | 7934 | * 8ch mode |
7661 | */ | 7935 | */ |
7662 | static struct hda_verb alc882_sixstack_ch8_init[] = { | 7936 | static const struct hda_verb alc882_sixstack_ch8_init[] = { |
7663 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7937 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7664 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7938 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7665 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7939 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -7667,7 +7941,7 @@ static struct hda_verb alc882_sixstack_ch8_init[] = { | |||
7667 | { } /* end */ | 7941 | { } /* end */ |
7668 | }; | 7942 | }; |
7669 | 7943 | ||
7670 | static struct hda_channel_mode alc882_sixstack_modes[2] = { | 7944 | static const struct hda_channel_mode alc882_sixstack_modes[2] = { |
7671 | { 6, alc882_sixstack_ch6_init }, | 7945 | { 6, alc882_sixstack_ch6_init }, |
7672 | { 8, alc882_sixstack_ch8_init }, | 7946 | { 8, alc882_sixstack_ch8_init }, |
7673 | }; | 7947 | }; |
@@ -7675,7 +7949,7 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = { | |||
7675 | 7949 | ||
7676 | /* Macbook Air 2,1 */ | 7950 | /* Macbook Air 2,1 */ |
7677 | 7951 | ||
7678 | static struct hda_channel_mode alc885_mba21_ch_modes[1] = { | 7952 | static const struct hda_channel_mode alc885_mba21_ch_modes[1] = { |
7679 | { 2, NULL }, | 7953 | { 2, NULL }, |
7680 | }; | 7954 | }; |
7681 | 7955 | ||
@@ -7686,7 +7960,7 @@ static struct hda_channel_mode alc885_mba21_ch_modes[1] = { | |||
7686 | /* | 7960 | /* |
7687 | * 2ch mode | 7961 | * 2ch mode |
7688 | */ | 7962 | */ |
7689 | static struct hda_verb alc885_mbp_ch2_init[] = { | 7963 | static const struct hda_verb alc885_mbp_ch2_init[] = { |
7690 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 7964 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
7691 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 7965 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
7692 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 7966 | { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
@@ -7696,7 +7970,7 @@ static struct hda_verb alc885_mbp_ch2_init[] = { | |||
7696 | /* | 7970 | /* |
7697 | * 4ch mode | 7971 | * 4ch mode |
7698 | */ | 7972 | */ |
7699 | static struct hda_verb alc885_mbp_ch4_init[] = { | 7973 | static const struct hda_verb alc885_mbp_ch4_init[] = { |
7700 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 7974 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7701 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 7975 | { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
7702 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, | 7976 | { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, |
@@ -7705,7 +7979,7 @@ static struct hda_verb alc885_mbp_ch4_init[] = { | |||
7705 | { } /* end */ | 7979 | { } /* end */ |
7706 | }; | 7980 | }; |
7707 | 7981 | ||
7708 | static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { | 7982 | static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = { |
7709 | { 2, alc885_mbp_ch2_init }, | 7983 | { 2, alc885_mbp_ch2_init }, |
7710 | { 4, alc885_mbp_ch4_init }, | 7984 | { 4, alc885_mbp_ch4_init }, |
7711 | }; | 7985 | }; |
@@ -7715,7 +7989,7 @@ static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { | |||
7715 | * Speakers/Woofer/HP = Front | 7989 | * Speakers/Woofer/HP = Front |
7716 | * LineIn = Input | 7990 | * LineIn = Input |
7717 | */ | 7991 | */ |
7718 | static struct hda_verb alc885_mb5_ch2_init[] = { | 7992 | static const struct hda_verb alc885_mb5_ch2_init[] = { |
7719 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 7993 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
7720 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 7994 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
7721 | { } /* end */ | 7995 | { } /* end */ |
@@ -7727,14 +8001,14 @@ static struct hda_verb alc885_mb5_ch2_init[] = { | |||
7727 | * Woofer = LFE | 8001 | * Woofer = LFE |
7728 | * LineIn = Surround | 8002 | * LineIn = Surround |
7729 | */ | 8003 | */ |
7730 | static struct hda_verb alc885_mb5_ch6_init[] = { | 8004 | static const struct hda_verb alc885_mb5_ch6_init[] = { |
7731 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 8005 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
7732 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 8006 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
7733 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | 8007 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, |
7734 | { } /* end */ | 8008 | { } /* end */ |
7735 | }; | 8009 | }; |
7736 | 8010 | ||
7737 | static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { | 8011 | static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = { |
7738 | { 2, alc885_mb5_ch2_init }, | 8012 | { 2, alc885_mb5_ch2_init }, |
7739 | { 6, alc885_mb5_ch6_init }, | 8013 | { 6, alc885_mb5_ch6_init }, |
7740 | }; | 8014 | }; |
@@ -7744,7 +8018,7 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { | |||
7744 | /* | 8018 | /* |
7745 | * 2ch mode | 8019 | * 2ch mode |
7746 | */ | 8020 | */ |
7747 | static struct hda_verb alc883_4ST_ch2_init[] = { | 8021 | static const struct hda_verb alc883_4ST_ch2_init[] = { |
7748 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8022 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7749 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 8023 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
7750 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 8024 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
@@ -7757,7 +8031,7 @@ static struct hda_verb alc883_4ST_ch2_init[] = { | |||
7757 | /* | 8031 | /* |
7758 | * 4ch mode | 8032 | * 4ch mode |
7759 | */ | 8033 | */ |
7760 | static struct hda_verb alc883_4ST_ch4_init[] = { | 8034 | static const struct hda_verb alc883_4ST_ch4_init[] = { |
7761 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8035 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7762 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 8036 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
7763 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 8037 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
@@ -7771,7 +8045,7 @@ static struct hda_verb alc883_4ST_ch4_init[] = { | |||
7771 | /* | 8045 | /* |
7772 | * 6ch mode | 8046 | * 6ch mode |
7773 | */ | 8047 | */ |
7774 | static struct hda_verb alc883_4ST_ch6_init[] = { | 8048 | static const struct hda_verb alc883_4ST_ch6_init[] = { |
7775 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8049 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7776 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 8050 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
7777 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8051 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -7786,7 +8060,7 @@ static struct hda_verb alc883_4ST_ch6_init[] = { | |||
7786 | /* | 8060 | /* |
7787 | * 8ch mode | 8061 | * 8ch mode |
7788 | */ | 8062 | */ |
7789 | static struct hda_verb alc883_4ST_ch8_init[] = { | 8063 | static const struct hda_verb alc883_4ST_ch8_init[] = { |
7790 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8064 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7791 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 8065 | { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
7792 | { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, | 8066 | { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, |
@@ -7799,7 +8073,7 @@ static struct hda_verb alc883_4ST_ch8_init[] = { | |||
7799 | { } /* end */ | 8073 | { } /* end */ |
7800 | }; | 8074 | }; |
7801 | 8075 | ||
7802 | static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { | 8076 | static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = { |
7803 | { 2, alc883_4ST_ch2_init }, | 8077 | { 2, alc883_4ST_ch2_init }, |
7804 | { 4, alc883_4ST_ch4_init }, | 8078 | { 4, alc883_4ST_ch4_init }, |
7805 | { 6, alc883_4ST_ch6_init }, | 8079 | { 6, alc883_4ST_ch6_init }, |
@@ -7810,7 +8084,7 @@ static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { | |||
7810 | /* | 8084 | /* |
7811 | * 2ch mode | 8085 | * 2ch mode |
7812 | */ | 8086 | */ |
7813 | static struct hda_verb alc883_3ST_ch2_intel_init[] = { | 8087 | static const struct hda_verb alc883_3ST_ch2_intel_init[] = { |
7814 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 8088 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
7815 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 8089 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
7816 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 8090 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
@@ -7821,7 +8095,7 @@ static struct hda_verb alc883_3ST_ch2_intel_init[] = { | |||
7821 | /* | 8095 | /* |
7822 | * 4ch mode | 8096 | * 4ch mode |
7823 | */ | 8097 | */ |
7824 | static struct hda_verb alc883_3ST_ch4_intel_init[] = { | 8098 | static const struct hda_verb alc883_3ST_ch4_intel_init[] = { |
7825 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 8099 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
7826 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 8100 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
7827 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8101 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -7833,7 +8107,7 @@ static struct hda_verb alc883_3ST_ch4_intel_init[] = { | |||
7833 | /* | 8107 | /* |
7834 | * 6ch mode | 8108 | * 6ch mode |
7835 | */ | 8109 | */ |
7836 | static struct hda_verb alc883_3ST_ch6_intel_init[] = { | 8110 | static const struct hda_verb alc883_3ST_ch6_intel_init[] = { |
7837 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8111 | { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7838 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 8112 | { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
7839 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, | 8113 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, |
@@ -7843,7 +8117,7 @@ static struct hda_verb alc883_3ST_ch6_intel_init[] = { | |||
7843 | { } /* end */ | 8117 | { } /* end */ |
7844 | }; | 8118 | }; |
7845 | 8119 | ||
7846 | static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { | 8120 | static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { |
7847 | { 2, alc883_3ST_ch2_intel_init }, | 8121 | { 2, alc883_3ST_ch2_intel_init }, |
7848 | { 4, alc883_3ST_ch4_intel_init }, | 8122 | { 4, alc883_3ST_ch4_intel_init }, |
7849 | { 6, alc883_3ST_ch6_intel_init }, | 8123 | { 6, alc883_3ST_ch6_intel_init }, |
@@ -7852,7 +8126,7 @@ static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { | |||
7852 | /* | 8126 | /* |
7853 | * 2ch mode | 8127 | * 2ch mode |
7854 | */ | 8128 | */ |
7855 | static struct hda_verb alc889_ch2_intel_init[] = { | 8129 | static const struct hda_verb alc889_ch2_intel_init[] = { |
7856 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 8130 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7857 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 8131 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7858 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 8132 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
@@ -7865,7 +8139,7 @@ static struct hda_verb alc889_ch2_intel_init[] = { | |||
7865 | /* | 8139 | /* |
7866 | * 6ch mode | 8140 | * 6ch mode |
7867 | */ | 8141 | */ |
7868 | static struct hda_verb alc889_ch6_intel_init[] = { | 8142 | static const struct hda_verb alc889_ch6_intel_init[] = { |
7869 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 8143 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7870 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, | 8144 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, |
7871 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, | 8145 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, |
@@ -7878,7 +8152,7 @@ static struct hda_verb alc889_ch6_intel_init[] = { | |||
7878 | /* | 8152 | /* |
7879 | * 8ch mode | 8153 | * 8ch mode |
7880 | */ | 8154 | */ |
7881 | static struct hda_verb alc889_ch8_intel_init[] = { | 8155 | static const struct hda_verb alc889_ch8_intel_init[] = { |
7882 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, | 8156 | { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, |
7883 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, | 8157 | { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, |
7884 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, | 8158 | { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, |
@@ -7889,7 +8163,7 @@ static struct hda_verb alc889_ch8_intel_init[] = { | |||
7889 | { } /* end */ | 8163 | { } /* end */ |
7890 | }; | 8164 | }; |
7891 | 8165 | ||
7892 | static struct hda_channel_mode alc889_8ch_intel_modes[3] = { | 8166 | static const struct hda_channel_mode alc889_8ch_intel_modes[3] = { |
7893 | { 2, alc889_ch2_intel_init }, | 8167 | { 2, alc889_ch2_intel_init }, |
7894 | { 6, alc889_ch6_intel_init }, | 8168 | { 6, alc889_ch6_intel_init }, |
7895 | { 8, alc889_ch8_intel_init }, | 8169 | { 8, alc889_ch8_intel_init }, |
@@ -7898,7 +8172,7 @@ static struct hda_channel_mode alc889_8ch_intel_modes[3] = { | |||
7898 | /* | 8172 | /* |
7899 | * 6ch mode | 8173 | * 6ch mode |
7900 | */ | 8174 | */ |
7901 | static struct hda_verb alc883_sixstack_ch6_init[] = { | 8175 | static const struct hda_verb alc883_sixstack_ch6_init[] = { |
7902 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | 8176 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, |
7903 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8177 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7904 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8178 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -7909,7 +8183,7 @@ static struct hda_verb alc883_sixstack_ch6_init[] = { | |||
7909 | /* | 8183 | /* |
7910 | * 8ch mode | 8184 | * 8ch mode |
7911 | */ | 8185 | */ |
7912 | static struct hda_verb alc883_sixstack_ch8_init[] = { | 8186 | static const struct hda_verb alc883_sixstack_ch8_init[] = { |
7913 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8187 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7914 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8188 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
7915 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 8189 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -7917,7 +8191,7 @@ static struct hda_verb alc883_sixstack_ch8_init[] = { | |||
7917 | { } /* end */ | 8191 | { } /* end */ |
7918 | }; | 8192 | }; |
7919 | 8193 | ||
7920 | static struct hda_channel_mode alc883_sixstack_modes[2] = { | 8194 | static const struct hda_channel_mode alc883_sixstack_modes[2] = { |
7921 | { 6, alc883_sixstack_ch6_init }, | 8195 | { 6, alc883_sixstack_ch6_init }, |
7922 | { 8, alc883_sixstack_ch8_init }, | 8196 | { 8, alc883_sixstack_ch8_init }, |
7923 | }; | 8197 | }; |
@@ -7926,7 +8200,7 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = { | |||
7926 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | 8200 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 |
7927 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | 8201 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b |
7928 | */ | 8202 | */ |
7929 | static struct snd_kcontrol_new alc882_base_mixer[] = { | 8203 | static const struct snd_kcontrol_new alc882_base_mixer[] = { |
7930 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 8204 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
7931 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 8205 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
7932 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 8206 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -7953,14 +8227,14 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { | |||
7953 | 8227 | ||
7954 | /* Macbook Air 2,1 same control for HP and internal Speaker */ | 8228 | /* Macbook Air 2,1 same control for HP and internal Speaker */ |
7955 | 8229 | ||
7956 | static struct snd_kcontrol_new alc885_mba21_mixer[] = { | 8230 | static const struct snd_kcontrol_new alc885_mba21_mixer[] = { |
7957 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | 8231 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), |
7958 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), | 8232 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), |
7959 | { } | 8233 | { } |
7960 | }; | 8234 | }; |
7961 | 8235 | ||
7962 | 8236 | ||
7963 | static struct snd_kcontrol_new alc885_mbp3_mixer[] = { | 8237 | static const struct snd_kcontrol_new alc885_mbp3_mixer[] = { |
7964 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | 8238 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), |
7965 | HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), | 8239 | HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), |
7966 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), | 8240 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), |
@@ -7975,7 +8249,7 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = { | |||
7975 | { } /* end */ | 8249 | { } /* end */ |
7976 | }; | 8250 | }; |
7977 | 8251 | ||
7978 | static struct snd_kcontrol_new alc885_mb5_mixer[] = { | 8252 | static const struct snd_kcontrol_new alc885_mb5_mixer[] = { |
7979 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | 8253 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), |
7980 | HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), | 8254 | HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), |
7981 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | 8255 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), |
@@ -7993,7 +8267,7 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = { | |||
7993 | { } /* end */ | 8267 | { } /* end */ |
7994 | }; | 8268 | }; |
7995 | 8269 | ||
7996 | static struct snd_kcontrol_new alc885_macmini3_mixer[] = { | 8270 | static const struct snd_kcontrol_new alc885_macmini3_mixer[] = { |
7997 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | 8271 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), |
7998 | HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), | 8272 | HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), |
7999 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), | 8273 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), |
@@ -8008,14 +8282,14 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = { | |||
8008 | { } /* end */ | 8282 | { } /* end */ |
8009 | }; | 8283 | }; |
8010 | 8284 | ||
8011 | static struct snd_kcontrol_new alc885_imac91_mixer[] = { | 8285 | static const struct snd_kcontrol_new alc885_imac91_mixer[] = { |
8012 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | 8286 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), |
8013 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), | 8287 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), |
8014 | { } /* end */ | 8288 | { } /* end */ |
8015 | }; | 8289 | }; |
8016 | 8290 | ||
8017 | 8291 | ||
8018 | static struct snd_kcontrol_new alc882_w2jc_mixer[] = { | 8292 | static const struct snd_kcontrol_new alc882_w2jc_mixer[] = { |
8019 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 8293 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8020 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 8294 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8021 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 8295 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
@@ -8028,7 +8302,7 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = { | |||
8028 | { } /* end */ | 8302 | { } /* end */ |
8029 | }; | 8303 | }; |
8030 | 8304 | ||
8031 | static struct snd_kcontrol_new alc882_targa_mixer[] = { | 8305 | static const struct snd_kcontrol_new alc882_targa_mixer[] = { |
8032 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 8306 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8033 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 8307 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8034 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 8308 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
@@ -8048,7 +8322,7 @@ static struct snd_kcontrol_new alc882_targa_mixer[] = { | |||
8048 | /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? | 8322 | /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? |
8049 | * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c | 8323 | * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c |
8050 | */ | 8324 | */ |
8051 | static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { | 8325 | static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { |
8052 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 8326 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8053 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 8327 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
8054 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 8328 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
@@ -8065,7 +8339,7 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { | |||
8065 | { } /* end */ | 8339 | { } /* end */ |
8066 | }; | 8340 | }; |
8067 | 8341 | ||
8068 | static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { | 8342 | static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { |
8069 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 8343 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8070 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 8344 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8071 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 8345 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
@@ -8079,7 +8353,7 @@ static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { | |||
8079 | { } /* end */ | 8353 | { } /* end */ |
8080 | }; | 8354 | }; |
8081 | 8355 | ||
8082 | static struct snd_kcontrol_new alc882_chmode_mixer[] = { | 8356 | static const struct snd_kcontrol_new alc882_chmode_mixer[] = { |
8083 | { | 8357 | { |
8084 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 8358 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
8085 | .name = "Channel Mode", | 8359 | .name = "Channel Mode", |
@@ -8090,7 +8364,7 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = { | |||
8090 | { } /* end */ | 8364 | { } /* end */ |
8091 | }; | 8365 | }; |
8092 | 8366 | ||
8093 | static struct hda_verb alc882_base_init_verbs[] = { | 8367 | static const struct hda_verb alc882_base_init_verbs[] = { |
8094 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | 8368 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ |
8095 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8369 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
8096 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 8370 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
@@ -8152,7 +8426,7 @@ static struct hda_verb alc882_base_init_verbs[] = { | |||
8152 | { } | 8426 | { } |
8153 | }; | 8427 | }; |
8154 | 8428 | ||
8155 | static struct hda_verb alc882_adc1_init_verbs[] = { | 8429 | static const struct hda_verb alc882_adc1_init_verbs[] = { |
8156 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ | 8430 | /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ |
8157 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8431 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
8158 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 8432 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
@@ -8164,26 +8438,26 @@ static struct hda_verb alc882_adc1_init_verbs[] = { | |||
8164 | { } | 8438 | { } |
8165 | }; | 8439 | }; |
8166 | 8440 | ||
8167 | static struct hda_verb alc882_eapd_verbs[] = { | 8441 | static const struct hda_verb alc882_eapd_verbs[] = { |
8168 | /* change to EAPD mode */ | 8442 | /* change to EAPD mode */ |
8169 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 8443 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
8170 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, | 8444 | {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, |
8171 | { } | 8445 | { } |
8172 | }; | 8446 | }; |
8173 | 8447 | ||
8174 | static struct hda_verb alc889_eapd_verbs[] = { | 8448 | static const struct hda_verb alc889_eapd_verbs[] = { |
8175 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 8449 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
8176 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 8450 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
8177 | { } | 8451 | { } |
8178 | }; | 8452 | }; |
8179 | 8453 | ||
8180 | static struct hda_verb alc_hp15_unsol_verbs[] = { | 8454 | static const struct hda_verb alc_hp15_unsol_verbs[] = { |
8181 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | 8455 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
8182 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 8456 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
8183 | {} | 8457 | {} |
8184 | }; | 8458 | }; |
8185 | 8459 | ||
8186 | static struct hda_verb alc885_init_verbs[] = { | 8460 | static const struct hda_verb alc885_init_verbs[] = { |
8187 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | 8461 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ |
8188 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8462 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
8189 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 8463 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -8242,7 +8516,7 @@ static struct hda_verb alc885_init_verbs[] = { | |||
8242 | { } | 8516 | { } |
8243 | }; | 8517 | }; |
8244 | 8518 | ||
8245 | static struct hda_verb alc885_init_input_verbs[] = { | 8519 | static const struct hda_verb alc885_init_input_verbs[] = { |
8246 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8520 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
8247 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, | 8521 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, |
8248 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, | 8522 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, |
@@ -8251,7 +8525,7 @@ static struct hda_verb alc885_init_input_verbs[] = { | |||
8251 | 8525 | ||
8252 | 8526 | ||
8253 | /* Unmute Selector 24h and set the default input to front mic */ | 8527 | /* Unmute Selector 24h and set the default input to front mic */ |
8254 | static struct hda_verb alc889_init_input_verbs[] = { | 8528 | static const struct hda_verb alc889_init_input_verbs[] = { |
8255 | {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, | 8529 | {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, |
8256 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 8530 | {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
8257 | { } | 8531 | { } |
@@ -8261,7 +8535,7 @@ static struct hda_verb alc889_init_input_verbs[] = { | |||
8261 | #define alc883_init_verbs alc882_base_init_verbs | 8535 | #define alc883_init_verbs alc882_base_init_verbs |
8262 | 8536 | ||
8263 | /* Mac Pro test */ | 8537 | /* Mac Pro test */ |
8264 | static struct snd_kcontrol_new alc882_macpro_mixer[] = { | 8538 | static const struct snd_kcontrol_new alc882_macpro_mixer[] = { |
8265 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 8539 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8266 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 8540 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8267 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), | 8541 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), |
@@ -8274,7 +8548,7 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = { | |||
8274 | { } /* end */ | 8548 | { } /* end */ |
8275 | }; | 8549 | }; |
8276 | 8550 | ||
8277 | static struct hda_verb alc882_macpro_init_verbs[] = { | 8551 | static const struct hda_verb alc882_macpro_init_verbs[] = { |
8278 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | 8552 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ |
8279 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 8553 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
8280 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8554 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
@@ -8326,7 +8600,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = { | |||
8326 | }; | 8600 | }; |
8327 | 8601 | ||
8328 | /* Macbook 5,1 */ | 8602 | /* Macbook 5,1 */ |
8329 | static struct hda_verb alc885_mb5_init_verbs[] = { | 8603 | static const struct hda_verb alc885_mb5_init_verbs[] = { |
8330 | /* DACs */ | 8604 | /* DACs */ |
8331 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 8605 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
8332 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 8606 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -8375,7 +8649,7 @@ static struct hda_verb alc885_mb5_init_verbs[] = { | |||
8375 | }; | 8649 | }; |
8376 | 8650 | ||
8377 | /* Macmini 3,1 */ | 8651 | /* Macmini 3,1 */ |
8378 | static struct hda_verb alc885_macmini3_init_verbs[] = { | 8652 | static const struct hda_verb alc885_macmini3_init_verbs[] = { |
8379 | /* DACs */ | 8653 | /* DACs */ |
8380 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 8654 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
8381 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 8655 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -8422,7 +8696,7 @@ static struct hda_verb alc885_macmini3_init_verbs[] = { | |||
8422 | }; | 8696 | }; |
8423 | 8697 | ||
8424 | 8698 | ||
8425 | static struct hda_verb alc885_mba21_init_verbs[] = { | 8699 | static const struct hda_verb alc885_mba21_init_verbs[] = { |
8426 | /*Internal and HP Speaker Mixer*/ | 8700 | /*Internal and HP Speaker Mixer*/ |
8427 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 8701 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
8428 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8702 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -8445,7 +8719,7 @@ static struct hda_verb alc885_mba21_init_verbs[] = { | |||
8445 | 8719 | ||
8446 | 8720 | ||
8447 | /* Macbook Pro rev3 */ | 8721 | /* Macbook Pro rev3 */ |
8448 | static struct hda_verb alc885_mbp3_init_verbs[] = { | 8722 | static const struct hda_verb alc885_mbp3_init_verbs[] = { |
8449 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ | 8723 | /* Front mixer: unmute input/output amp left and right (volume = 0) */ |
8450 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 8724 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
8451 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 8725 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
@@ -8509,7 +8783,7 @@ static struct hda_verb alc885_mbp3_init_verbs[] = { | |||
8509 | }; | 8783 | }; |
8510 | 8784 | ||
8511 | /* iMac 9,1 */ | 8785 | /* iMac 9,1 */ |
8512 | static struct hda_verb alc885_imac91_init_verbs[] = { | 8786 | static const struct hda_verb alc885_imac91_init_verbs[] = { |
8513 | /* Internal Speaker Pin (0x0c) */ | 8787 | /* Internal Speaker Pin (0x0c) */ |
8514 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, | 8788 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, |
8515 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 8789 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -8564,14 +8838,14 @@ static struct hda_verb alc885_imac91_init_verbs[] = { | |||
8564 | }; | 8838 | }; |
8565 | 8839 | ||
8566 | /* iMac 24 mixer. */ | 8840 | /* iMac 24 mixer. */ |
8567 | static struct snd_kcontrol_new alc885_imac24_mixer[] = { | 8841 | static const struct snd_kcontrol_new alc885_imac24_mixer[] = { |
8568 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | 8842 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), |
8569 | HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), | 8843 | HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), |
8570 | { } /* end */ | 8844 | { } /* end */ |
8571 | }; | 8845 | }; |
8572 | 8846 | ||
8573 | /* iMac 24 init verbs. */ | 8847 | /* iMac 24 init verbs. */ |
8574 | static struct hda_verb alc885_imac24_init_verbs[] = { | 8848 | static const struct hda_verb alc885_imac24_init_verbs[] = { |
8575 | /* Internal speakers: output 0 (0x0c) */ | 8849 | /* Internal speakers: output 0 (0x0c) */ |
8576 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 8850 | {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
8577 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 8851 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -8599,6 +8873,8 @@ static void alc885_imac24_setup(struct hda_codec *codec) | |||
8599 | spec->autocfg.hp_pins[0] = 0x14; | 8873 | spec->autocfg.hp_pins[0] = 0x14; |
8600 | spec->autocfg.speaker_pins[0] = 0x18; | 8874 | spec->autocfg.speaker_pins[0] = 0x18; |
8601 | spec->autocfg.speaker_pins[1] = 0x1a; | 8875 | spec->autocfg.speaker_pins[1] = 0x1a; |
8876 | spec->automute = 1; | ||
8877 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
8602 | } | 8878 | } |
8603 | 8879 | ||
8604 | #define alc885_mb5_setup alc885_imac24_setup | 8880 | #define alc885_mb5_setup alc885_imac24_setup |
@@ -8611,6 +8887,8 @@ static void alc885_mba21_setup(struct hda_codec *codec) | |||
8611 | 8887 | ||
8612 | spec->autocfg.hp_pins[0] = 0x14; | 8888 | spec->autocfg.hp_pins[0] = 0x14; |
8613 | spec->autocfg.speaker_pins[0] = 0x18; | 8889 | spec->autocfg.speaker_pins[0] = 0x18; |
8890 | spec->automute = 1; | ||
8891 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
8614 | } | 8892 | } |
8615 | 8893 | ||
8616 | 8894 | ||
@@ -8621,6 +8899,8 @@ static void alc885_mbp3_setup(struct hda_codec *codec) | |||
8621 | 8899 | ||
8622 | spec->autocfg.hp_pins[0] = 0x15; | 8900 | spec->autocfg.hp_pins[0] = 0x15; |
8623 | spec->autocfg.speaker_pins[0] = 0x14; | 8901 | spec->autocfg.speaker_pins[0] = 0x14; |
8902 | spec->automute = 1; | ||
8903 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
8624 | } | 8904 | } |
8625 | 8905 | ||
8626 | static void alc885_imac91_setup(struct hda_codec *codec) | 8906 | static void alc885_imac91_setup(struct hda_codec *codec) |
@@ -8630,9 +8910,11 @@ static void alc885_imac91_setup(struct hda_codec *codec) | |||
8630 | spec->autocfg.hp_pins[0] = 0x14; | 8910 | spec->autocfg.hp_pins[0] = 0x14; |
8631 | spec->autocfg.speaker_pins[0] = 0x18; | 8911 | spec->autocfg.speaker_pins[0] = 0x18; |
8632 | spec->autocfg.speaker_pins[1] = 0x1a; | 8912 | spec->autocfg.speaker_pins[1] = 0x1a; |
8913 | spec->automute = 1; | ||
8914 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
8633 | } | 8915 | } |
8634 | 8916 | ||
8635 | static struct hda_verb alc882_targa_verbs[] = { | 8917 | static const struct hda_verb alc882_targa_verbs[] = { |
8636 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8918 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
8637 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 8919 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
8638 | 8920 | ||
@@ -8651,7 +8933,7 @@ static struct hda_verb alc882_targa_verbs[] = { | |||
8651 | static void alc882_targa_automute(struct hda_codec *codec) | 8933 | static void alc882_targa_automute(struct hda_codec *codec) |
8652 | { | 8934 | { |
8653 | struct alc_spec *spec = codec->spec; | 8935 | struct alc_spec *spec = codec->spec; |
8654 | alc_automute_amp(codec); | 8936 | alc_hp_automute(codec); |
8655 | snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, | 8937 | snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, |
8656 | spec->jack_present ? 1 : 3); | 8938 | spec->jack_present ? 1 : 3); |
8657 | } | 8939 | } |
@@ -8662,6 +8944,8 @@ static void alc882_targa_setup(struct hda_codec *codec) | |||
8662 | 8944 | ||
8663 | spec->autocfg.hp_pins[0] = 0x14; | 8945 | spec->autocfg.hp_pins[0] = 0x14; |
8664 | spec->autocfg.speaker_pins[0] = 0x1b; | 8946 | spec->autocfg.speaker_pins[0] = 0x1b; |
8947 | spec->automute = 1; | ||
8948 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
8665 | } | 8949 | } |
8666 | 8950 | ||
8667 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) | 8951 | static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) |
@@ -8670,7 +8954,7 @@ static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) | |||
8670 | alc882_targa_automute(codec); | 8954 | alc882_targa_automute(codec); |
8671 | } | 8955 | } |
8672 | 8956 | ||
8673 | static struct hda_verb alc882_asus_a7j_verbs[] = { | 8957 | static const struct hda_verb alc882_asus_a7j_verbs[] = { |
8674 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8958 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
8675 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 8959 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
8676 | 8960 | ||
@@ -8688,7 +8972,7 @@ static struct hda_verb alc882_asus_a7j_verbs[] = { | |||
8688 | { } /* end */ | 8972 | { } /* end */ |
8689 | }; | 8973 | }; |
8690 | 8974 | ||
8691 | static struct hda_verb alc882_asus_a7m_verbs[] = { | 8975 | static const struct hda_verb alc882_asus_a7m_verbs[] = { |
8692 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 8976 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
8693 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 8977 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
8694 | 8978 | ||
@@ -8749,13 +9033,13 @@ static void alc885_macpro_init_hook(struct hda_codec *codec) | |||
8749 | static void alc885_imac24_init_hook(struct hda_codec *codec) | 9033 | static void alc885_imac24_init_hook(struct hda_codec *codec) |
8750 | { | 9034 | { |
8751 | alc885_macpro_init_hook(codec); | 9035 | alc885_macpro_init_hook(codec); |
8752 | alc_automute_amp(codec); | 9036 | alc_hp_automute(codec); |
8753 | } | 9037 | } |
8754 | 9038 | ||
8755 | /* | 9039 | /* |
8756 | * generic initialization of ADC, input mixers and output mixers | 9040 | * generic initialization of ADC, input mixers and output mixers |
8757 | */ | 9041 | */ |
8758 | static struct hda_verb alc883_auto_init_verbs[] = { | 9042 | static const struct hda_verb alc883_auto_init_verbs[] = { |
8759 | /* | 9043 | /* |
8760 | * Unmute ADC0-2 and set the default input to mic-in | 9044 | * Unmute ADC0-2 and set the default input to mic-in |
8761 | */ | 9045 | */ |
@@ -8795,7 +9079,7 @@ static struct hda_verb alc883_auto_init_verbs[] = { | |||
8795 | }; | 9079 | }; |
8796 | 9080 | ||
8797 | /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ | 9081 | /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ |
8798 | static struct hda_verb alc889A_mb31_ch2_init[] = { | 9082 | static const struct hda_verb alc889A_mb31_ch2_init[] = { |
8799 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | 9083 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ |
8800 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | 9084 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ |
8801 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ | 9085 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ |
@@ -8804,7 +9088,7 @@ static struct hda_verb alc889A_mb31_ch2_init[] = { | |||
8804 | }; | 9088 | }; |
8805 | 9089 | ||
8806 | /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ | 9090 | /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ |
8807 | static struct hda_verb alc889A_mb31_ch4_init[] = { | 9091 | static const struct hda_verb alc889A_mb31_ch4_init[] = { |
8808 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ | 9092 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ |
8809 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | 9093 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ |
8810 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ | 9094 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ |
@@ -8813,7 +9097,7 @@ static struct hda_verb alc889A_mb31_ch4_init[] = { | |||
8813 | }; | 9097 | }; |
8814 | 9098 | ||
8815 | /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ | 9099 | /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ |
8816 | static struct hda_verb alc889A_mb31_ch5_init[] = { | 9100 | static const struct hda_verb alc889A_mb31_ch5_init[] = { |
8817 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ | 9101 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ |
8818 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ | 9102 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ |
8819 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ | 9103 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ |
@@ -8822,7 +9106,7 @@ static struct hda_verb alc889A_mb31_ch5_init[] = { | |||
8822 | }; | 9106 | }; |
8823 | 9107 | ||
8824 | /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ | 9108 | /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ |
8825 | static struct hda_verb alc889A_mb31_ch6_init[] = { | 9109 | static const struct hda_verb alc889A_mb31_ch6_init[] = { |
8826 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ | 9110 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ |
8827 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ | 9111 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ |
8828 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ | 9112 | {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ |
@@ -8830,14 +9114,14 @@ static struct hda_verb alc889A_mb31_ch6_init[] = { | |||
8830 | { } /* end */ | 9114 | { } /* end */ |
8831 | }; | 9115 | }; |
8832 | 9116 | ||
8833 | static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { | 9117 | static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { |
8834 | { 2, alc889A_mb31_ch2_init }, | 9118 | { 2, alc889A_mb31_ch2_init }, |
8835 | { 4, alc889A_mb31_ch4_init }, | 9119 | { 4, alc889A_mb31_ch4_init }, |
8836 | { 5, alc889A_mb31_ch5_init }, | 9120 | { 5, alc889A_mb31_ch5_init }, |
8837 | { 6, alc889A_mb31_ch6_init }, | 9121 | { 6, alc889A_mb31_ch6_init }, |
8838 | }; | 9122 | }; |
8839 | 9123 | ||
8840 | static struct hda_verb alc883_medion_eapd_verbs[] = { | 9124 | static const struct hda_verb alc883_medion_eapd_verbs[] = { |
8841 | /* eanable EAPD on medion laptop */ | 9125 | /* eanable EAPD on medion laptop */ |
8842 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 9126 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
8843 | {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, | 9127 | {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, |
@@ -8846,7 +9130,7 @@ static struct hda_verb alc883_medion_eapd_verbs[] = { | |||
8846 | 9130 | ||
8847 | #define alc883_base_mixer alc882_base_mixer | 9131 | #define alc883_base_mixer alc882_base_mixer |
8848 | 9132 | ||
8849 | static struct snd_kcontrol_new alc883_mitac_mixer[] = { | 9133 | static const struct snd_kcontrol_new alc883_mitac_mixer[] = { |
8850 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9134 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8851 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9135 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8852 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 9136 | HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
@@ -8863,7 +9147,7 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = { | |||
8863 | { } /* end */ | 9147 | { } /* end */ |
8864 | }; | 9148 | }; |
8865 | 9149 | ||
8866 | static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { | 9150 | static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { |
8867 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9151 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8868 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | 9152 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
8869 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 9153 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -8877,7 +9161,7 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { | |||
8877 | { } /* end */ | 9161 | { } /* end */ |
8878 | }; | 9162 | }; |
8879 | 9163 | ||
8880 | static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { | 9164 | static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { |
8881 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9165 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8882 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), | 9166 | HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), |
8883 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 9167 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -8891,7 +9175,7 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { | |||
8891 | { } /* end */ | 9175 | { } /* end */ |
8892 | }; | 9176 | }; |
8893 | 9177 | ||
8894 | static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { | 9178 | static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { |
8895 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9179 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8896 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9180 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8897 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 9181 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
@@ -8908,7 +9192,7 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { | |||
8908 | { } /* end */ | 9192 | { } /* end */ |
8909 | }; | 9193 | }; |
8910 | 9194 | ||
8911 | static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { | 9195 | static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { |
8912 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9196 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8913 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9197 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8914 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 9198 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -8931,7 +9215,7 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { | |||
8931 | { } /* end */ | 9215 | { } /* end */ |
8932 | }; | 9216 | }; |
8933 | 9217 | ||
8934 | static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { | 9218 | static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { |
8935 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9219 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8936 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9220 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8937 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 9221 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -8955,7 +9239,7 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { | |||
8955 | { } /* end */ | 9239 | { } /* end */ |
8956 | }; | 9240 | }; |
8957 | 9241 | ||
8958 | static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { | 9242 | static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { |
8959 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9243 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8960 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9244 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8961 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 9245 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -8979,7 +9263,7 @@ static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { | |||
8979 | { } /* end */ | 9263 | { } /* end */ |
8980 | }; | 9264 | }; |
8981 | 9265 | ||
8982 | static struct snd_kcontrol_new alc883_fivestack_mixer[] = { | 9266 | static const struct snd_kcontrol_new alc883_fivestack_mixer[] = { |
8983 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9267 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
8984 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9268 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
8985 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 9269 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -9002,7 +9286,7 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = { | |||
9002 | { } /* end */ | 9286 | { } /* end */ |
9003 | }; | 9287 | }; |
9004 | 9288 | ||
9005 | static struct snd_kcontrol_new alc883_targa_mixer[] = { | 9289 | static const struct snd_kcontrol_new alc883_targa_mixer[] = { |
9006 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9290 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9007 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9291 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
9008 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 9292 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -9023,7 +9307,7 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = { | |||
9023 | { } /* end */ | 9307 | { } /* end */ |
9024 | }; | 9308 | }; |
9025 | 9309 | ||
9026 | static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { | 9310 | static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { |
9027 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9311 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9028 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9312 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
9029 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 9313 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -9039,7 +9323,7 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { | |||
9039 | { } /* end */ | 9323 | { } /* end */ |
9040 | }; | 9324 | }; |
9041 | 9325 | ||
9042 | static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { | 9326 | static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { |
9043 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 9327 | HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
9044 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), | 9328 | HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), |
9045 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), | 9329 | HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), |
@@ -9048,7 +9332,7 @@ static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { | |||
9048 | { } /* end */ | 9332 | { } /* end */ |
9049 | }; | 9333 | }; |
9050 | 9334 | ||
9051 | static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { | 9335 | static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { |
9052 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9336 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9053 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9337 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
9054 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 9338 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -9060,7 +9344,7 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { | |||
9060 | { } /* end */ | 9344 | { } /* end */ |
9061 | }; | 9345 | }; |
9062 | 9346 | ||
9063 | static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { | 9347 | static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { |
9064 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9348 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9065 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), | 9349 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), |
9066 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 9350 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -9073,7 +9357,7 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { | |||
9073 | { } /* end */ | 9357 | { } /* end */ |
9074 | }; | 9358 | }; |
9075 | 9359 | ||
9076 | static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { | 9360 | static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { |
9077 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9361 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9078 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9362 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
9079 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 9363 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
@@ -9083,7 +9367,7 @@ static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { | |||
9083 | { } /* end */ | 9367 | { } /* end */ |
9084 | }; | 9368 | }; |
9085 | 9369 | ||
9086 | static struct hda_verb alc883_medion_wim2160_verbs[] = { | 9370 | static const struct hda_verb alc883_medion_wim2160_verbs[] = { |
9087 | /* Unmute front mixer */ | 9371 | /* Unmute front mixer */ |
9088 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 9372 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
9089 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 9373 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -9107,9 +9391,11 @@ static void alc883_medion_wim2160_setup(struct hda_codec *codec) | |||
9107 | 9391 | ||
9108 | spec->autocfg.hp_pins[0] = 0x1a; | 9392 | spec->autocfg.hp_pins[0] = 0x1a; |
9109 | spec->autocfg.speaker_pins[0] = 0x15; | 9393 | spec->autocfg.speaker_pins[0] = 0x15; |
9394 | spec->automute = 1; | ||
9395 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9110 | } | 9396 | } |
9111 | 9397 | ||
9112 | static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { | 9398 | static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { |
9113 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9399 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9114 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9400 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
9115 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 9401 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -9121,7 +9407,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { | |||
9121 | { } /* end */ | 9407 | { } /* end */ |
9122 | }; | 9408 | }; |
9123 | 9409 | ||
9124 | static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { | 9410 | static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { |
9125 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9411 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9126 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), | 9412 | HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), |
9127 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 9413 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -9134,7 +9420,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { | |||
9134 | { } /* end */ | 9420 | { } /* end */ |
9135 | }; | 9421 | }; |
9136 | 9422 | ||
9137 | static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { | 9423 | static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { |
9138 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9424 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9139 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9425 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
9140 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | 9426 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), |
@@ -9159,7 +9445,7 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { | |||
9159 | { } /* end */ | 9445 | { } /* end */ |
9160 | }; | 9446 | }; |
9161 | 9447 | ||
9162 | static struct snd_kcontrol_new alc889A_mb31_mixer[] = { | 9448 | static const struct snd_kcontrol_new alc889A_mb31_mixer[] = { |
9163 | /* Output mixers */ | 9449 | /* Output mixers */ |
9164 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), | 9450 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), |
9165 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), | 9451 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), |
@@ -9185,7 +9471,7 @@ static struct snd_kcontrol_new alc889A_mb31_mixer[] = { | |||
9185 | { } /* end */ | 9471 | { } /* end */ |
9186 | }; | 9472 | }; |
9187 | 9473 | ||
9188 | static struct snd_kcontrol_new alc883_vaiott_mixer[] = { | 9474 | static const struct snd_kcontrol_new alc883_vaiott_mixer[] = { |
9189 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9475 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9190 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9476 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
9191 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 9477 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
@@ -9195,7 +9481,7 @@ static struct snd_kcontrol_new alc883_vaiott_mixer[] = { | |||
9195 | { } /* end */ | 9481 | { } /* end */ |
9196 | }; | 9482 | }; |
9197 | 9483 | ||
9198 | static struct hda_bind_ctls alc883_bind_cap_vol = { | 9484 | static const struct hda_bind_ctls alc883_bind_cap_vol = { |
9199 | .ops = &snd_hda_bind_vol, | 9485 | .ops = &snd_hda_bind_vol, |
9200 | .values = { | 9486 | .values = { |
9201 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), | 9487 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), |
@@ -9204,7 +9490,7 @@ static struct hda_bind_ctls alc883_bind_cap_vol = { | |||
9204 | }, | 9490 | }, |
9205 | }; | 9491 | }; |
9206 | 9492 | ||
9207 | static struct hda_bind_ctls alc883_bind_cap_switch = { | 9493 | static const struct hda_bind_ctls alc883_bind_cap_switch = { |
9208 | .ops = &snd_hda_bind_sw, | 9494 | .ops = &snd_hda_bind_sw, |
9209 | .values = { | 9495 | .values = { |
9210 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), | 9496 | HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), |
@@ -9213,7 +9499,7 @@ static struct hda_bind_ctls alc883_bind_cap_switch = { | |||
9213 | }, | 9499 | }, |
9214 | }; | 9500 | }; |
9215 | 9501 | ||
9216 | static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { | 9502 | static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { |
9217 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 9503 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
9218 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 9504 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
9219 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 9505 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -9225,7 +9511,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { | |||
9225 | { } /* end */ | 9511 | { } /* end */ |
9226 | }; | 9512 | }; |
9227 | 9513 | ||
9228 | static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { | 9514 | static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { |
9229 | HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), | 9515 | HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), |
9230 | HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), | 9516 | HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), |
9231 | { | 9517 | { |
@@ -9240,7 +9526,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { | |||
9240 | { } /* end */ | 9526 | { } /* end */ |
9241 | }; | 9527 | }; |
9242 | 9528 | ||
9243 | static struct snd_kcontrol_new alc883_chmode_mixer[] = { | 9529 | static const struct snd_kcontrol_new alc883_chmode_mixer[] = { |
9244 | { | 9530 | { |
9245 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 9531 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
9246 | .name = "Channel Mode", | 9532 | .name = "Channel Mode", |
@@ -9259,9 +9545,11 @@ static void alc883_mitac_setup(struct hda_codec *codec) | |||
9259 | spec->autocfg.hp_pins[0] = 0x15; | 9545 | spec->autocfg.hp_pins[0] = 0x15; |
9260 | spec->autocfg.speaker_pins[0] = 0x14; | 9546 | spec->autocfg.speaker_pins[0] = 0x14; |
9261 | spec->autocfg.speaker_pins[1] = 0x17; | 9547 | spec->autocfg.speaker_pins[1] = 0x17; |
9548 | spec->automute = 1; | ||
9549 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9262 | } | 9550 | } |
9263 | 9551 | ||
9264 | static struct hda_verb alc883_mitac_verbs[] = { | 9552 | static const struct hda_verb alc883_mitac_verbs[] = { |
9265 | /* HP */ | 9553 | /* HP */ |
9266 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 9554 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
9267 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 9555 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -9276,7 +9564,7 @@ static struct hda_verb alc883_mitac_verbs[] = { | |||
9276 | { } /* end */ | 9564 | { } /* end */ |
9277 | }; | 9565 | }; |
9278 | 9566 | ||
9279 | static struct hda_verb alc883_clevo_m540r_verbs[] = { | 9567 | static const struct hda_verb alc883_clevo_m540r_verbs[] = { |
9280 | /* HP */ | 9568 | /* HP */ |
9281 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 9569 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
9282 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 9570 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -9292,7 +9580,7 @@ static struct hda_verb alc883_clevo_m540r_verbs[] = { | |||
9292 | { } /* end */ | 9580 | { } /* end */ |
9293 | }; | 9581 | }; |
9294 | 9582 | ||
9295 | static struct hda_verb alc883_clevo_m720_verbs[] = { | 9583 | static const struct hda_verb alc883_clevo_m720_verbs[] = { |
9296 | /* HP */ | 9584 | /* HP */ |
9297 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 9585 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
9298 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 9586 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -9307,7 +9595,7 @@ static struct hda_verb alc883_clevo_m720_verbs[] = { | |||
9307 | { } /* end */ | 9595 | { } /* end */ |
9308 | }; | 9596 | }; |
9309 | 9597 | ||
9310 | static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { | 9598 | static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { |
9311 | /* HP */ | 9599 | /* HP */ |
9312 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, | 9600 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, |
9313 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 9601 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -9321,7 +9609,7 @@ static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { | |||
9321 | { } /* end */ | 9609 | { } /* end */ |
9322 | }; | 9610 | }; |
9323 | 9611 | ||
9324 | static struct hda_verb alc883_targa_verbs[] = { | 9612 | static const struct hda_verb alc883_targa_verbs[] = { |
9325 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 9613 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
9326 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 9614 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
9327 | 9615 | ||
@@ -9350,14 +9638,14 @@ static struct hda_verb alc883_targa_verbs[] = { | |||
9350 | { } /* end */ | 9638 | { } /* end */ |
9351 | }; | 9639 | }; |
9352 | 9640 | ||
9353 | static struct hda_verb alc883_lenovo_101e_verbs[] = { | 9641 | static const struct hda_verb alc883_lenovo_101e_verbs[] = { |
9354 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 9642 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
9355 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, | 9643 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, |
9356 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, | 9644 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, |
9357 | { } /* end */ | 9645 | { } /* end */ |
9358 | }; | 9646 | }; |
9359 | 9647 | ||
9360 | static struct hda_verb alc883_lenovo_nb0763_verbs[] = { | 9648 | static const struct hda_verb alc883_lenovo_nb0763_verbs[] = { |
9361 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 9649 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
9362 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 9650 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
9363 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 9651 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
@@ -9365,7 +9653,7 @@ static struct hda_verb alc883_lenovo_nb0763_verbs[] = { | |||
9365 | { } /* end */ | 9653 | { } /* end */ |
9366 | }; | 9654 | }; |
9367 | 9655 | ||
9368 | static struct hda_verb alc888_lenovo_ms7195_verbs[] = { | 9656 | static const struct hda_verb alc888_lenovo_ms7195_verbs[] = { |
9369 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 9657 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
9370 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 9658 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
9371 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 9659 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -9374,7 +9662,7 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = { | |||
9374 | { } /* end */ | 9662 | { } /* end */ |
9375 | }; | 9663 | }; |
9376 | 9664 | ||
9377 | static struct hda_verb alc883_haier_w66_verbs[] = { | 9665 | static const struct hda_verb alc883_haier_w66_verbs[] = { |
9378 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 9666 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
9379 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 9667 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
9380 | 9668 | ||
@@ -9387,7 +9675,7 @@ static struct hda_verb alc883_haier_w66_verbs[] = { | |||
9387 | { } /* end */ | 9675 | { } /* end */ |
9388 | }; | 9676 | }; |
9389 | 9677 | ||
9390 | static struct hda_verb alc888_lenovo_sky_verbs[] = { | 9678 | static const struct hda_verb alc888_lenovo_sky_verbs[] = { |
9391 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 9679 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
9392 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 9680 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
9393 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 9681 | {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -9399,12 +9687,12 @@ static struct hda_verb alc888_lenovo_sky_verbs[] = { | |||
9399 | { } /* end */ | 9687 | { } /* end */ |
9400 | }; | 9688 | }; |
9401 | 9689 | ||
9402 | static struct hda_verb alc888_6st_dell_verbs[] = { | 9690 | static const struct hda_verb alc888_6st_dell_verbs[] = { |
9403 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 9691 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
9404 | { } | 9692 | { } |
9405 | }; | 9693 | }; |
9406 | 9694 | ||
9407 | static struct hda_verb alc883_vaiott_verbs[] = { | 9695 | static const struct hda_verb alc883_vaiott_verbs[] = { |
9408 | /* HP */ | 9696 | /* HP */ |
9409 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 9697 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
9410 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 9698 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -9423,9 +9711,11 @@ static void alc888_3st_hp_setup(struct hda_codec *codec) | |||
9423 | spec->autocfg.speaker_pins[0] = 0x14; | 9711 | spec->autocfg.speaker_pins[0] = 0x14; |
9424 | spec->autocfg.speaker_pins[1] = 0x16; | 9712 | spec->autocfg.speaker_pins[1] = 0x16; |
9425 | spec->autocfg.speaker_pins[2] = 0x18; | 9713 | spec->autocfg.speaker_pins[2] = 0x18; |
9714 | spec->automute = 1; | ||
9715 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9426 | } | 9716 | } |
9427 | 9717 | ||
9428 | static struct hda_verb alc888_3st_hp_verbs[] = { | 9718 | static const struct hda_verb alc888_3st_hp_verbs[] = { |
9429 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ | 9719 | {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ |
9430 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ | 9720 | {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ |
9431 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ | 9721 | {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ |
@@ -9436,7 +9726,7 @@ static struct hda_verb alc888_3st_hp_verbs[] = { | |||
9436 | /* | 9726 | /* |
9437 | * 2ch mode | 9727 | * 2ch mode |
9438 | */ | 9728 | */ |
9439 | static struct hda_verb alc888_3st_hp_2ch_init[] = { | 9729 | static const struct hda_verb alc888_3st_hp_2ch_init[] = { |
9440 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 9730 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
9441 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 9731 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
9442 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 9732 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
@@ -9447,7 +9737,7 @@ static struct hda_verb alc888_3st_hp_2ch_init[] = { | |||
9447 | /* | 9737 | /* |
9448 | * 4ch mode | 9738 | * 4ch mode |
9449 | */ | 9739 | */ |
9450 | static struct hda_verb alc888_3st_hp_4ch_init[] = { | 9740 | static const struct hda_verb alc888_3st_hp_4ch_init[] = { |
9451 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 9741 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
9452 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 9742 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
9453 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 9743 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -9459,7 +9749,7 @@ static struct hda_verb alc888_3st_hp_4ch_init[] = { | |||
9459 | /* | 9749 | /* |
9460 | * 6ch mode | 9750 | * 6ch mode |
9461 | */ | 9751 | */ |
9462 | static struct hda_verb alc888_3st_hp_6ch_init[] = { | 9752 | static const struct hda_verb alc888_3st_hp_6ch_init[] = { |
9463 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 9753 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
9464 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 9754 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
9465 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | 9755 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, |
@@ -9469,39 +9759,21 @@ static struct hda_verb alc888_3st_hp_6ch_init[] = { | |||
9469 | { } /* end */ | 9759 | { } /* end */ |
9470 | }; | 9760 | }; |
9471 | 9761 | ||
9472 | static struct hda_channel_mode alc888_3st_hp_modes[3] = { | 9762 | static const struct hda_channel_mode alc888_3st_hp_modes[3] = { |
9473 | { 2, alc888_3st_hp_2ch_init }, | 9763 | { 2, alc888_3st_hp_2ch_init }, |
9474 | { 4, alc888_3st_hp_4ch_init }, | 9764 | { 4, alc888_3st_hp_4ch_init }, |
9475 | { 6, alc888_3st_hp_6ch_init }, | 9765 | { 6, alc888_3st_hp_6ch_init }, |
9476 | }; | 9766 | }; |
9477 | 9767 | ||
9478 | /* toggle front-jack and RCA according to the hp-jack state */ | 9768 | static void alc888_lenovo_ms7195_setup(struct hda_codec *codec) |
9479 | static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) | ||
9480 | { | 9769 | { |
9481 | unsigned int present = snd_hda_jack_detect(codec, 0x1b); | 9770 | struct alc_spec *spec = codec->spec; |
9482 | |||
9483 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
9484 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
9485 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
9486 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
9487 | } | ||
9488 | |||
9489 | /* toggle RCA according to the front-jack state */ | ||
9490 | static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) | ||
9491 | { | ||
9492 | unsigned int present = snd_hda_jack_detect(codec, 0x14); | ||
9493 | |||
9494 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
9495 | HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); | ||
9496 | } | ||
9497 | 9771 | ||
9498 | static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, | 9772 | spec->autocfg.hp_pins[0] = 0x1b; |
9499 | unsigned int res) | 9773 | spec->autocfg.line_out_pins[0] = 0x14; |
9500 | { | 9774 | spec->autocfg.speaker_pins[0] = 0x15; |
9501 | if ((res >> 26) == ALC880_HP_EVENT) | 9775 | spec->automute = 1; |
9502 | alc888_lenovo_ms7195_front_automute(codec); | 9776 | spec->automute_mode = ALC_AUTOMUTE_AMP; |
9503 | if ((res >> 26) == ALC880_FRONT_EVENT) | ||
9504 | alc888_lenovo_ms7195_rca_automute(codec); | ||
9505 | } | 9777 | } |
9506 | 9778 | ||
9507 | /* toggle speaker-output according to the hp-jack state */ | 9779 | /* toggle speaker-output according to the hp-jack state */ |
@@ -9511,6 +9783,8 @@ static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) | |||
9511 | 9783 | ||
9512 | spec->autocfg.hp_pins[0] = 0x14; | 9784 | spec->autocfg.hp_pins[0] = 0x14; |
9513 | spec->autocfg.speaker_pins[0] = 0x15; | 9785 | spec->autocfg.speaker_pins[0] = 0x15; |
9786 | spec->automute = 1; | ||
9787 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9514 | } | 9788 | } |
9515 | 9789 | ||
9516 | /* toggle speaker-output according to the hp-jack state */ | 9790 | /* toggle speaker-output according to the hp-jack state */ |
@@ -9523,11 +9797,13 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec) | |||
9523 | 9797 | ||
9524 | spec->autocfg.hp_pins[0] = 0x15; | 9798 | spec->autocfg.hp_pins[0] = 0x15; |
9525 | spec->autocfg.speaker_pins[0] = 0x14; | 9799 | spec->autocfg.speaker_pins[0] = 0x14; |
9800 | spec->automute = 1; | ||
9801 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9526 | } | 9802 | } |
9527 | 9803 | ||
9528 | static void alc883_clevo_m720_init_hook(struct hda_codec *codec) | 9804 | static void alc883_clevo_m720_init_hook(struct hda_codec *codec) |
9529 | { | 9805 | { |
9530 | alc_automute_amp(codec); | 9806 | alc_hp_automute(codec); |
9531 | alc88x_simple_mic_automute(codec); | 9807 | alc88x_simple_mic_automute(codec); |
9532 | } | 9808 | } |
9533 | 9809 | ||
@@ -9539,7 +9815,7 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, | |||
9539 | alc88x_simple_mic_automute(codec); | 9815 | alc88x_simple_mic_automute(codec); |
9540 | break; | 9816 | break; |
9541 | default: | 9817 | default: |
9542 | alc_automute_amp_unsol_event(codec, res); | 9818 | alc_sku_unsol_event(codec, res); |
9543 | break; | 9819 | break; |
9544 | } | 9820 | } |
9545 | } | 9821 | } |
@@ -9551,6 +9827,8 @@ static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) | |||
9551 | 9827 | ||
9552 | spec->autocfg.hp_pins[0] = 0x14; | 9828 | spec->autocfg.hp_pins[0] = 0x14; |
9553 | spec->autocfg.speaker_pins[0] = 0x15; | 9829 | spec->autocfg.speaker_pins[0] = 0x15; |
9830 | spec->automute = 1; | ||
9831 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9554 | } | 9832 | } |
9555 | 9833 | ||
9556 | static void alc883_haier_w66_setup(struct hda_codec *codec) | 9834 | static void alc883_haier_w66_setup(struct hda_codec *codec) |
@@ -9559,33 +9837,21 @@ static void alc883_haier_w66_setup(struct hda_codec *codec) | |||
9559 | 9837 | ||
9560 | spec->autocfg.hp_pins[0] = 0x1b; | 9838 | spec->autocfg.hp_pins[0] = 0x1b; |
9561 | spec->autocfg.speaker_pins[0] = 0x14; | 9839 | spec->autocfg.speaker_pins[0] = 0x14; |
9840 | spec->automute = 1; | ||
9841 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9562 | } | 9842 | } |
9563 | 9843 | ||
9564 | static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | 9844 | static void alc883_lenovo_101e_setup(struct hda_codec *codec) |
9565 | { | ||
9566 | int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; | ||
9567 | |||
9568 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
9569 | HDA_AMP_MUTE, bits); | ||
9570 | } | ||
9571 | |||
9572 | static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) | ||
9573 | { | 9845 | { |
9574 | int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0; | 9846 | struct alc_spec *spec = codec->spec; |
9575 | |||
9576 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
9577 | HDA_AMP_MUTE, bits); | ||
9578 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
9579 | HDA_AMP_MUTE, bits); | ||
9580 | } | ||
9581 | 9847 | ||
9582 | static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, | 9848 | spec->autocfg.hp_pins[0] = 0x1b; |
9583 | unsigned int res) | 9849 | spec->autocfg.line_out_pins[0] = 0x14; |
9584 | { | 9850 | spec->autocfg.speaker_pins[0] = 0x15; |
9585 | if ((res >> 26) == ALC880_HP_EVENT) | 9851 | spec->automute = 1; |
9586 | alc883_lenovo_101e_all_automute(codec); | 9852 | spec->detect_line = 1; |
9587 | if ((res >> 26) == ALC880_FRONT_EVENT) | 9853 | spec->automute_lines = 1; |
9588 | alc883_lenovo_101e_ispeaker_automute(codec); | 9854 | spec->automute_mode = ALC_AUTOMUTE_AMP; |
9589 | } | 9855 | } |
9590 | 9856 | ||
9591 | /* toggle speaker-output according to the hp-jack state */ | 9857 | /* toggle speaker-output according to the hp-jack state */ |
@@ -9596,9 +9862,11 @@ static void alc883_acer_aspire_setup(struct hda_codec *codec) | |||
9596 | spec->autocfg.hp_pins[0] = 0x14; | 9862 | spec->autocfg.hp_pins[0] = 0x14; |
9597 | spec->autocfg.speaker_pins[0] = 0x15; | 9863 | spec->autocfg.speaker_pins[0] = 0x15; |
9598 | spec->autocfg.speaker_pins[1] = 0x16; | 9864 | spec->autocfg.speaker_pins[1] = 0x16; |
9865 | spec->automute = 1; | ||
9866 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9599 | } | 9867 | } |
9600 | 9868 | ||
9601 | static struct hda_verb alc883_acer_eapd_verbs[] = { | 9869 | static const struct hda_verb alc883_acer_eapd_verbs[] = { |
9602 | /* HP Pin: output 0 (0x0c) */ | 9870 | /* HP Pin: output 0 (0x0c) */ |
9603 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 9871 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
9604 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 9872 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -9625,6 +9893,8 @@ static void alc888_6st_dell_setup(struct hda_codec *codec) | |||
9625 | spec->autocfg.speaker_pins[1] = 0x15; | 9893 | spec->autocfg.speaker_pins[1] = 0x15; |
9626 | spec->autocfg.speaker_pins[2] = 0x16; | 9894 | spec->autocfg.speaker_pins[2] = 0x16; |
9627 | spec->autocfg.speaker_pins[3] = 0x17; | 9895 | spec->autocfg.speaker_pins[3] = 0x17; |
9896 | spec->automute = 1; | ||
9897 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9628 | } | 9898 | } |
9629 | 9899 | ||
9630 | static void alc888_lenovo_sky_setup(struct hda_codec *codec) | 9900 | static void alc888_lenovo_sky_setup(struct hda_codec *codec) |
@@ -9637,6 +9907,8 @@ static void alc888_lenovo_sky_setup(struct hda_codec *codec) | |||
9637 | spec->autocfg.speaker_pins[2] = 0x16; | 9907 | spec->autocfg.speaker_pins[2] = 0x16; |
9638 | spec->autocfg.speaker_pins[3] = 0x17; | 9908 | spec->autocfg.speaker_pins[3] = 0x17; |
9639 | spec->autocfg.speaker_pins[4] = 0x1a; | 9909 | spec->autocfg.speaker_pins[4] = 0x1a; |
9910 | spec->automute = 1; | ||
9911 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9640 | } | 9912 | } |
9641 | 9913 | ||
9642 | static void alc883_vaiott_setup(struct hda_codec *codec) | 9914 | static void alc883_vaiott_setup(struct hda_codec *codec) |
@@ -9646,9 +9918,11 @@ static void alc883_vaiott_setup(struct hda_codec *codec) | |||
9646 | spec->autocfg.hp_pins[0] = 0x15; | 9918 | spec->autocfg.hp_pins[0] = 0x15; |
9647 | spec->autocfg.speaker_pins[0] = 0x14; | 9919 | spec->autocfg.speaker_pins[0] = 0x14; |
9648 | spec->autocfg.speaker_pins[1] = 0x17; | 9920 | spec->autocfg.speaker_pins[1] = 0x17; |
9921 | spec->automute = 1; | ||
9922 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9649 | } | 9923 | } |
9650 | 9924 | ||
9651 | static struct hda_verb alc888_asus_m90v_verbs[] = { | 9925 | static const struct hda_verb alc888_asus_m90v_verbs[] = { |
9652 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 9926 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
9653 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 9927 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
9654 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 9928 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
@@ -9671,9 +9945,11 @@ static void alc883_mode2_setup(struct hda_codec *codec) | |||
9671 | spec->ext_mic.mux_idx = 0; | 9945 | spec->ext_mic.mux_idx = 0; |
9672 | spec->int_mic.mux_idx = 1; | 9946 | spec->int_mic.mux_idx = 1; |
9673 | spec->auto_mic = 1; | 9947 | spec->auto_mic = 1; |
9948 | spec->automute = 1; | ||
9949 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
9674 | } | 9950 | } |
9675 | 9951 | ||
9676 | static struct hda_verb alc888_asus_eee1601_verbs[] = { | 9952 | static const struct hda_verb alc888_asus_eee1601_verbs[] = { |
9677 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 9953 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
9678 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 9954 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
9679 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 9955 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
@@ -9692,10 +9968,10 @@ static void alc883_eee1601_inithook(struct hda_codec *codec) | |||
9692 | 9968 | ||
9693 | spec->autocfg.hp_pins[0] = 0x14; | 9969 | spec->autocfg.hp_pins[0] = 0x14; |
9694 | spec->autocfg.speaker_pins[0] = 0x1b; | 9970 | spec->autocfg.speaker_pins[0] = 0x1b; |
9695 | alc_automute_pin(codec); | 9971 | alc_hp_automute(codec); |
9696 | } | 9972 | } |
9697 | 9973 | ||
9698 | static struct hda_verb alc889A_mb31_verbs[] = { | 9974 | static const struct hda_verb alc889A_mb31_verbs[] = { |
9699 | /* Init rear pin (used as headphone output) */ | 9975 | /* Init rear pin (used as headphone output) */ |
9700 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ | 9976 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ |
9701 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ | 9977 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ |
@@ -9741,11 +10017,11 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) | |||
9741 | #define alc882_pcm_digital_playback alc880_pcm_digital_playback | 10017 | #define alc882_pcm_digital_playback alc880_pcm_digital_playback |
9742 | #define alc882_pcm_digital_capture alc880_pcm_digital_capture | 10018 | #define alc882_pcm_digital_capture alc880_pcm_digital_capture |
9743 | 10019 | ||
9744 | static hda_nid_t alc883_slave_dig_outs[] = { | 10020 | static const hda_nid_t alc883_slave_dig_outs[] = { |
9745 | ALC1200_DIGOUT_NID, 0, | 10021 | ALC1200_DIGOUT_NID, 0, |
9746 | }; | 10022 | }; |
9747 | 10023 | ||
9748 | static hda_nid_t alc1200_slave_dig_outs[] = { | 10024 | static const hda_nid_t alc1200_slave_dig_outs[] = { |
9749 | ALC883_DIGOUT_NID, 0, | 10025 | ALC883_DIGOUT_NID, 0, |
9750 | }; | 10026 | }; |
9751 | 10027 | ||
@@ -9804,7 +10080,7 @@ static const char * const alc882_models[ALC882_MODEL_LAST] = { | |||
9804 | [ALC882_AUTO] = "auto", | 10080 | [ALC882_AUTO] = "auto", |
9805 | }; | 10081 | }; |
9806 | 10082 | ||
9807 | static struct snd_pci_quirk alc882_cfg_tbl[] = { | 10083 | static const struct snd_pci_quirk alc882_cfg_tbl[] = { |
9808 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), | 10084 | SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), |
9809 | 10085 | ||
9810 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), | 10086 | SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), |
@@ -9863,6 +10139,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
9863 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), | 10139 | SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), |
9864 | SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), | 10140 | SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), |
9865 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), | 10141 | SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), |
10142 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), | ||
9866 | 10143 | ||
9867 | SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), | 10144 | SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), |
9868 | SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), | 10145 | SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), |
@@ -9930,7 +10207,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { | |||
9930 | }; | 10207 | }; |
9931 | 10208 | ||
9932 | /* codec SSID table for Intel Mac */ | 10209 | /* codec SSID table for Intel Mac */ |
9933 | static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { | 10210 | static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { |
9934 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), | 10211 | SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), |
9935 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), | 10212 | SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), |
9936 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), | 10213 | SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), |
@@ -9957,7 +10234,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { | |||
9957 | {} /* terminator */ | 10234 | {} /* terminator */ |
9958 | }; | 10235 | }; |
9959 | 10236 | ||
9960 | static struct alc_config_preset alc882_presets[] = { | 10237 | static const struct alc_config_preset alc882_presets[] = { |
9961 | [ALC882_3ST_DIG] = { | 10238 | [ALC882_3ST_DIG] = { |
9962 | .mixers = { alc882_base_mixer }, | 10239 | .mixers = { alc882_base_mixer }, |
9963 | .init_verbs = { alc882_base_init_verbs, | 10240 | .init_verbs = { alc882_base_init_verbs, |
@@ -10013,9 +10290,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10013 | .channel_mode = alc885_mba21_ch_modes, | 10290 | .channel_mode = alc885_mba21_ch_modes, |
10014 | .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), | 10291 | .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), |
10015 | .input_mux = &alc882_capture_source, | 10292 | .input_mux = &alc882_capture_source, |
10016 | .unsol_event = alc_automute_amp_unsol_event, | 10293 | .unsol_event = alc_sku_unsol_event, |
10017 | .setup = alc885_mba21_setup, | 10294 | .setup = alc885_mba21_setup, |
10018 | .init_hook = alc_automute_amp, | 10295 | .init_hook = alc_hp_automute, |
10019 | }, | 10296 | }, |
10020 | [ALC885_MBP3] = { | 10297 | [ALC885_MBP3] = { |
10021 | .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, | 10298 | .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, |
@@ -10029,9 +10306,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10029 | .input_mux = &alc882_capture_source, | 10306 | .input_mux = &alc882_capture_source, |
10030 | .dig_out_nid = ALC882_DIGOUT_NID, | 10307 | .dig_out_nid = ALC882_DIGOUT_NID, |
10031 | .dig_in_nid = ALC882_DIGIN_NID, | 10308 | .dig_in_nid = ALC882_DIGIN_NID, |
10032 | .unsol_event = alc_automute_amp_unsol_event, | 10309 | .unsol_event = alc_sku_unsol_event, |
10033 | .setup = alc885_mbp3_setup, | 10310 | .setup = alc885_mbp3_setup, |
10034 | .init_hook = alc_automute_amp, | 10311 | .init_hook = alc_hp_automute, |
10035 | }, | 10312 | }, |
10036 | [ALC885_MB5] = { | 10313 | [ALC885_MB5] = { |
10037 | .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, | 10314 | .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, |
@@ -10044,9 +10321,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10044 | .input_mux = &mb5_capture_source, | 10321 | .input_mux = &mb5_capture_source, |
10045 | .dig_out_nid = ALC882_DIGOUT_NID, | 10322 | .dig_out_nid = ALC882_DIGOUT_NID, |
10046 | .dig_in_nid = ALC882_DIGIN_NID, | 10323 | .dig_in_nid = ALC882_DIGIN_NID, |
10047 | .unsol_event = alc_automute_amp_unsol_event, | 10324 | .unsol_event = alc_sku_unsol_event, |
10048 | .setup = alc885_mb5_setup, | 10325 | .setup = alc885_mb5_setup, |
10049 | .init_hook = alc_automute_amp, | 10326 | .init_hook = alc_hp_automute, |
10050 | }, | 10327 | }, |
10051 | [ALC885_MACMINI3] = { | 10328 | [ALC885_MACMINI3] = { |
10052 | .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, | 10329 | .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, |
@@ -10059,9 +10336,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10059 | .input_mux = &macmini3_capture_source, | 10336 | .input_mux = &macmini3_capture_source, |
10060 | .dig_out_nid = ALC882_DIGOUT_NID, | 10337 | .dig_out_nid = ALC882_DIGOUT_NID, |
10061 | .dig_in_nid = ALC882_DIGIN_NID, | 10338 | .dig_in_nid = ALC882_DIGIN_NID, |
10062 | .unsol_event = alc_automute_amp_unsol_event, | 10339 | .unsol_event = alc_sku_unsol_event, |
10063 | .setup = alc885_macmini3_setup, | 10340 | .setup = alc885_macmini3_setup, |
10064 | .init_hook = alc_automute_amp, | 10341 | .init_hook = alc_hp_automute, |
10065 | }, | 10342 | }, |
10066 | [ALC885_MACPRO] = { | 10343 | [ALC885_MACPRO] = { |
10067 | .mixers = { alc882_macpro_mixer }, | 10344 | .mixers = { alc882_macpro_mixer }, |
@@ -10085,7 +10362,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
10085 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), | 10362 | .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), |
10086 | .channel_mode = alc882_ch_modes, | 10363 | .channel_mode = alc882_ch_modes, |
10087 | .input_mux = &alc882_capture_source, | 10364 | .input_mux = &alc882_capture_source, |
10088 | .unsol_event = alc_automute_amp_unsol_event, | 10365 | .unsol_event = alc_sku_unsol_event, |
10089 | .setup = alc885_imac24_setup, | 10366 | .setup = alc885_imac24_setup, |
10090 | .init_hook = alc885_imac24_init_hook, | 10367 | .init_hook = alc885_imac24_init_hook, |
10091 | }, | 10368 | }, |
@@ -10100,9 +10377,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10100 | .input_mux = &alc889A_imac91_capture_source, | 10377 | .input_mux = &alc889A_imac91_capture_source, |
10101 | .dig_out_nid = ALC882_DIGOUT_NID, | 10378 | .dig_out_nid = ALC882_DIGOUT_NID, |
10102 | .dig_in_nid = ALC882_DIGIN_NID, | 10379 | .dig_in_nid = ALC882_DIGIN_NID, |
10103 | .unsol_event = alc_automute_amp_unsol_event, | 10380 | .unsol_event = alc_sku_unsol_event, |
10104 | .setup = alc885_imac91_setup, | 10381 | .setup = alc885_imac91_setup, |
10105 | .init_hook = alc_automute_amp, | 10382 | .init_hook = alc_hp_automute, |
10106 | }, | 10383 | }, |
10107 | [ALC882_TARGA] = { | 10384 | [ALC882_TARGA] = { |
10108 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, | 10385 | .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, |
@@ -10118,7 +10395,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
10118 | .channel_mode = alc882_3ST_6ch_modes, | 10395 | .channel_mode = alc882_3ST_6ch_modes, |
10119 | .need_dac_fix = 1, | 10396 | .need_dac_fix = 1, |
10120 | .input_mux = &alc882_capture_source, | 10397 | .input_mux = &alc882_capture_source, |
10121 | .unsol_event = alc882_targa_unsol_event, | 10398 | .unsol_event = alc_sku_unsol_event, |
10122 | .setup = alc882_targa_setup, | 10399 | .setup = alc882_targa_setup, |
10123 | .init_hook = alc882_targa_automute, | 10400 | .init_hook = alc882_targa_automute, |
10124 | }, | 10401 | }, |
@@ -10212,8 +10489,8 @@ static struct alc_config_preset alc882_presets[] = { | |||
10212 | .capsrc_nids = alc889_capsrc_nids, | 10489 | .capsrc_nids = alc889_capsrc_nids, |
10213 | .input_mux = &alc889_capture_source, | 10490 | .input_mux = &alc889_capture_source, |
10214 | .setup = alc889_automute_setup, | 10491 | .setup = alc889_automute_setup, |
10215 | .init_hook = alc_automute_amp, | 10492 | .init_hook = alc_hp_automute, |
10216 | .unsol_event = alc_automute_amp_unsol_event, | 10493 | .unsol_event = alc_sku_unsol_event, |
10217 | .need_dac_fix = 1, | 10494 | .need_dac_fix = 1, |
10218 | }, | 10495 | }, |
10219 | [ALC889_INTEL] = { | 10496 | [ALC889_INTEL] = { |
@@ -10233,7 +10510,7 @@ static struct alc_config_preset alc882_presets[] = { | |||
10233 | .input_mux = &alc889_capture_source, | 10510 | .input_mux = &alc889_capture_source, |
10234 | .setup = alc889_automute_setup, | 10511 | .setup = alc889_automute_setup, |
10235 | .init_hook = alc889_intel_init_hook, | 10512 | .init_hook = alc889_intel_init_hook, |
10236 | .unsol_event = alc_automute_amp_unsol_event, | 10513 | .unsol_event = alc_sku_unsol_event, |
10237 | .need_dac_fix = 1, | 10514 | .need_dac_fix = 1, |
10238 | }, | 10515 | }, |
10239 | [ALC883_6ST_DIG] = { | 10516 | [ALC883_6ST_DIG] = { |
@@ -10322,9 +10599,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10322 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 10599 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
10323 | .channel_mode = alc883_3ST_2ch_modes, | 10600 | .channel_mode = alc883_3ST_2ch_modes, |
10324 | .input_mux = &alc883_capture_source, | 10601 | .input_mux = &alc883_capture_source, |
10325 | .unsol_event = alc_automute_amp_unsol_event, | 10602 | .unsol_event = alc_sku_unsol_event, |
10326 | .setup = alc883_acer_aspire_setup, | 10603 | .setup = alc883_acer_aspire_setup, |
10327 | .init_hook = alc_automute_amp, | 10604 | .init_hook = alc_hp_automute, |
10328 | }, | 10605 | }, |
10329 | [ALC888_ACER_ASPIRE_4930G] = { | 10606 | [ALC888_ACER_ASPIRE_4930G] = { |
10330 | .mixers = { alc888_acer_aspire_4930g_mixer, | 10607 | .mixers = { alc888_acer_aspire_4930g_mixer, |
@@ -10344,9 +10621,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10344 | .num_mux_defs = | 10621 | .num_mux_defs = |
10345 | ARRAY_SIZE(alc888_2_capture_sources), | 10622 | ARRAY_SIZE(alc888_2_capture_sources), |
10346 | .input_mux = alc888_2_capture_sources, | 10623 | .input_mux = alc888_2_capture_sources, |
10347 | .unsol_event = alc_automute_amp_unsol_event, | 10624 | .unsol_event = alc_sku_unsol_event, |
10348 | .setup = alc888_acer_aspire_4930g_setup, | 10625 | .setup = alc888_acer_aspire_4930g_setup, |
10349 | .init_hook = alc_automute_amp, | 10626 | .init_hook = alc_hp_automute, |
10350 | }, | 10627 | }, |
10351 | [ALC888_ACER_ASPIRE_6530G] = { | 10628 | [ALC888_ACER_ASPIRE_6530G] = { |
10352 | .mixers = { alc888_acer_aspire_6530_mixer }, | 10629 | .mixers = { alc888_acer_aspire_6530_mixer }, |
@@ -10363,9 +10640,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10363 | .num_mux_defs = | 10640 | .num_mux_defs = |
10364 | ARRAY_SIZE(alc888_2_capture_sources), | 10641 | ARRAY_SIZE(alc888_2_capture_sources), |
10365 | .input_mux = alc888_acer_aspire_6530_sources, | 10642 | .input_mux = alc888_acer_aspire_6530_sources, |
10366 | .unsol_event = alc_automute_amp_unsol_event, | 10643 | .unsol_event = alc_sku_unsol_event, |
10367 | .setup = alc888_acer_aspire_6530g_setup, | 10644 | .setup = alc888_acer_aspire_6530g_setup, |
10368 | .init_hook = alc_automute_amp, | 10645 | .init_hook = alc_hp_automute, |
10369 | }, | 10646 | }, |
10370 | [ALC888_ACER_ASPIRE_8930G] = { | 10647 | [ALC888_ACER_ASPIRE_8930G] = { |
10371 | .mixers = { alc889_acer_aspire_8930g_mixer, | 10648 | .mixers = { alc889_acer_aspire_8930g_mixer, |
@@ -10386,9 +10663,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10386 | .num_mux_defs = | 10663 | .num_mux_defs = |
10387 | ARRAY_SIZE(alc889_capture_sources), | 10664 | ARRAY_SIZE(alc889_capture_sources), |
10388 | .input_mux = alc889_capture_sources, | 10665 | .input_mux = alc889_capture_sources, |
10389 | .unsol_event = alc_automute_amp_unsol_event, | 10666 | .unsol_event = alc_sku_unsol_event, |
10390 | .setup = alc889_acer_aspire_8930g_setup, | 10667 | .setup = alc889_acer_aspire_8930g_setup, |
10391 | .init_hook = alc_automute_amp, | 10668 | .init_hook = alc_hp_automute, |
10392 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 10669 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
10393 | .power_hook = alc_power_eapd, | 10670 | .power_hook = alc_power_eapd, |
10394 | #endif | 10671 | #endif |
@@ -10409,9 +10686,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10409 | .need_dac_fix = 1, | 10686 | .need_dac_fix = 1, |
10410 | .const_channel_count = 6, | 10687 | .const_channel_count = 6, |
10411 | .input_mux = &alc883_capture_source, | 10688 | .input_mux = &alc883_capture_source, |
10412 | .unsol_event = alc_automute_amp_unsol_event, | 10689 | .unsol_event = alc_sku_unsol_event, |
10413 | .setup = alc888_acer_aspire_7730g_setup, | 10690 | .setup = alc888_acer_aspire_7730g_setup, |
10414 | .init_hook = alc_automute_amp, | 10691 | .init_hook = alc_hp_automute, |
10415 | }, | 10692 | }, |
10416 | [ALC883_MEDION] = { | 10693 | [ALC883_MEDION] = { |
10417 | .mixers = { alc883_fivestack_mixer, | 10694 | .mixers = { alc883_fivestack_mixer, |
@@ -10438,9 +10715,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10438 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 10715 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
10439 | .channel_mode = alc883_3ST_2ch_modes, | 10716 | .channel_mode = alc883_3ST_2ch_modes, |
10440 | .input_mux = &alc883_capture_source, | 10717 | .input_mux = &alc883_capture_source, |
10441 | .unsol_event = alc_automute_amp_unsol_event, | 10718 | .unsol_event = alc_sku_unsol_event, |
10442 | .setup = alc883_medion_wim2160_setup, | 10719 | .setup = alc883_medion_wim2160_setup, |
10443 | .init_hook = alc_automute_amp, | 10720 | .init_hook = alc_hp_automute, |
10444 | }, | 10721 | }, |
10445 | [ALC883_LAPTOP_EAPD] = { | 10722 | [ALC883_LAPTOP_EAPD] = { |
10446 | .mixers = { alc883_base_mixer }, | 10723 | .mixers = { alc883_base_mixer }, |
@@ -10490,8 +10767,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10490 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 10767 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
10491 | .channel_mode = alc883_3ST_2ch_modes, | 10768 | .channel_mode = alc883_3ST_2ch_modes, |
10492 | .input_mux = &alc883_lenovo_101e_capture_source, | 10769 | .input_mux = &alc883_lenovo_101e_capture_source, |
10493 | .unsol_event = alc883_lenovo_101e_unsol_event, | 10770 | .setup = alc883_lenovo_101e_setup, |
10494 | .init_hook = alc883_lenovo_101e_all_automute, | 10771 | .unsol_event = alc_sku_unsol_event, |
10772 | .init_hook = alc_inithook, | ||
10495 | }, | 10773 | }, |
10496 | [ALC883_LENOVO_NB0763] = { | 10774 | [ALC883_LENOVO_NB0763] = { |
10497 | .mixers = { alc883_lenovo_nb0763_mixer }, | 10775 | .mixers = { alc883_lenovo_nb0763_mixer }, |
@@ -10502,9 +10780,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10502 | .channel_mode = alc883_3ST_2ch_modes, | 10780 | .channel_mode = alc883_3ST_2ch_modes, |
10503 | .need_dac_fix = 1, | 10781 | .need_dac_fix = 1, |
10504 | .input_mux = &alc883_lenovo_nb0763_capture_source, | 10782 | .input_mux = &alc883_lenovo_nb0763_capture_source, |
10505 | .unsol_event = alc_automute_amp_unsol_event, | 10783 | .unsol_event = alc_sku_unsol_event, |
10506 | .setup = alc883_lenovo_nb0763_setup, | 10784 | .setup = alc883_lenovo_nb0763_setup, |
10507 | .init_hook = alc_automute_amp, | 10785 | .init_hook = alc_hp_automute, |
10508 | }, | 10786 | }, |
10509 | [ALC888_LENOVO_MS7195_DIG] = { | 10787 | [ALC888_LENOVO_MS7195_DIG] = { |
10510 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 10788 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -10516,8 +10794,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10516 | .channel_mode = alc883_3ST_6ch_modes, | 10794 | .channel_mode = alc883_3ST_6ch_modes, |
10517 | .need_dac_fix = 1, | 10795 | .need_dac_fix = 1, |
10518 | .input_mux = &alc883_capture_source, | 10796 | .input_mux = &alc883_capture_source, |
10519 | .unsol_event = alc883_lenovo_ms7195_unsol_event, | 10797 | .unsol_event = alc_sku_unsol_event, |
10520 | .init_hook = alc888_lenovo_ms7195_front_automute, | 10798 | .setup = alc888_lenovo_ms7195_setup, |
10799 | .init_hook = alc_inithook, | ||
10521 | }, | 10800 | }, |
10522 | [ALC883_HAIER_W66] = { | 10801 | [ALC883_HAIER_W66] = { |
10523 | .mixers = { alc883_targa_2ch_mixer}, | 10802 | .mixers = { alc883_targa_2ch_mixer}, |
@@ -10528,9 +10807,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10528 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 10807 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
10529 | .channel_mode = alc883_3ST_2ch_modes, | 10808 | .channel_mode = alc883_3ST_2ch_modes, |
10530 | .input_mux = &alc883_capture_source, | 10809 | .input_mux = &alc883_capture_source, |
10531 | .unsol_event = alc_automute_amp_unsol_event, | 10810 | .unsol_event = alc_sku_unsol_event, |
10532 | .setup = alc883_haier_w66_setup, | 10811 | .setup = alc883_haier_w66_setup, |
10533 | .init_hook = alc_automute_amp, | 10812 | .init_hook = alc_hp_automute, |
10534 | }, | 10813 | }, |
10535 | [ALC888_3ST_HP] = { | 10814 | [ALC888_3ST_HP] = { |
10536 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 10815 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -10541,9 +10820,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10541 | .channel_mode = alc888_3st_hp_modes, | 10820 | .channel_mode = alc888_3st_hp_modes, |
10542 | .need_dac_fix = 1, | 10821 | .need_dac_fix = 1, |
10543 | .input_mux = &alc883_capture_source, | 10822 | .input_mux = &alc883_capture_source, |
10544 | .unsol_event = alc_automute_amp_unsol_event, | 10823 | .unsol_event = alc_sku_unsol_event, |
10545 | .setup = alc888_3st_hp_setup, | 10824 | .setup = alc888_3st_hp_setup, |
10546 | .init_hook = alc_automute_amp, | 10825 | .init_hook = alc_hp_automute, |
10547 | }, | 10826 | }, |
10548 | [ALC888_6ST_DELL] = { | 10827 | [ALC888_6ST_DELL] = { |
10549 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, | 10828 | .mixers = { alc883_base_mixer, alc883_chmode_mixer }, |
@@ -10555,9 +10834,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10555 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), | 10834 | .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), |
10556 | .channel_mode = alc883_sixstack_modes, | 10835 | .channel_mode = alc883_sixstack_modes, |
10557 | .input_mux = &alc883_capture_source, | 10836 | .input_mux = &alc883_capture_source, |
10558 | .unsol_event = alc_automute_amp_unsol_event, | 10837 | .unsol_event = alc_sku_unsol_event, |
10559 | .setup = alc888_6st_dell_setup, | 10838 | .setup = alc888_6st_dell_setup, |
10560 | .init_hook = alc_automute_amp, | 10839 | .init_hook = alc_hp_automute, |
10561 | }, | 10840 | }, |
10562 | [ALC883_MITAC] = { | 10841 | [ALC883_MITAC] = { |
10563 | .mixers = { alc883_mitac_mixer }, | 10842 | .mixers = { alc883_mitac_mixer }, |
@@ -10567,9 +10846,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10567 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 10846 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
10568 | .channel_mode = alc883_3ST_2ch_modes, | 10847 | .channel_mode = alc883_3ST_2ch_modes, |
10569 | .input_mux = &alc883_capture_source, | 10848 | .input_mux = &alc883_capture_source, |
10570 | .unsol_event = alc_automute_amp_unsol_event, | 10849 | .unsol_event = alc_sku_unsol_event, |
10571 | .setup = alc883_mitac_setup, | 10850 | .setup = alc883_mitac_setup, |
10572 | .init_hook = alc_automute_amp, | 10851 | .init_hook = alc_hp_automute, |
10573 | }, | 10852 | }, |
10574 | [ALC883_FUJITSU_PI2515] = { | 10853 | [ALC883_FUJITSU_PI2515] = { |
10575 | .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, | 10854 | .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, |
@@ -10581,9 +10860,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10581 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 10860 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
10582 | .channel_mode = alc883_3ST_2ch_modes, | 10861 | .channel_mode = alc883_3ST_2ch_modes, |
10583 | .input_mux = &alc883_fujitsu_pi2515_capture_source, | 10862 | .input_mux = &alc883_fujitsu_pi2515_capture_source, |
10584 | .unsol_event = alc_automute_amp_unsol_event, | 10863 | .unsol_event = alc_sku_unsol_event, |
10585 | .setup = alc883_2ch_fujitsu_pi2515_setup, | 10864 | .setup = alc883_2ch_fujitsu_pi2515_setup, |
10586 | .init_hook = alc_automute_amp, | 10865 | .init_hook = alc_hp_automute, |
10587 | }, | 10866 | }, |
10588 | [ALC888_FUJITSU_XA3530] = { | 10867 | [ALC888_FUJITSU_XA3530] = { |
10589 | .mixers = { alc888_base_mixer, alc883_chmode_mixer }, | 10868 | .mixers = { alc888_base_mixer, alc883_chmode_mixer }, |
@@ -10600,9 +10879,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10600 | .num_mux_defs = | 10879 | .num_mux_defs = |
10601 | ARRAY_SIZE(alc888_2_capture_sources), | 10880 | ARRAY_SIZE(alc888_2_capture_sources), |
10602 | .input_mux = alc888_2_capture_sources, | 10881 | .input_mux = alc888_2_capture_sources, |
10603 | .unsol_event = alc_automute_amp_unsol_event, | 10882 | .unsol_event = alc_sku_unsol_event, |
10604 | .setup = alc888_fujitsu_xa3530_setup, | 10883 | .setup = alc888_fujitsu_xa3530_setup, |
10605 | .init_hook = alc_automute_amp, | 10884 | .init_hook = alc_hp_automute, |
10606 | }, | 10885 | }, |
10607 | [ALC888_LENOVO_SKY] = { | 10886 | [ALC888_LENOVO_SKY] = { |
10608 | .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, | 10887 | .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, |
@@ -10614,9 +10893,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10614 | .channel_mode = alc883_sixstack_modes, | 10893 | .channel_mode = alc883_sixstack_modes, |
10615 | .need_dac_fix = 1, | 10894 | .need_dac_fix = 1, |
10616 | .input_mux = &alc883_lenovo_sky_capture_source, | 10895 | .input_mux = &alc883_lenovo_sky_capture_source, |
10617 | .unsol_event = alc_automute_amp_unsol_event, | 10896 | .unsol_event = alc_sku_unsol_event, |
10618 | .setup = alc888_lenovo_sky_setup, | 10897 | .setup = alc888_lenovo_sky_setup, |
10619 | .init_hook = alc_automute_amp, | 10898 | .init_hook = alc_hp_automute, |
10620 | }, | 10899 | }, |
10621 | [ALC888_ASUS_M90V] = { | 10900 | [ALC888_ASUS_M90V] = { |
10622 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, | 10901 | .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, |
@@ -10684,9 +10963,9 @@ static struct alc_config_preset alc882_presets[] = { | |||
10684 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), | 10963 | .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), |
10685 | .channel_mode = alc883_3ST_2ch_modes, | 10964 | .channel_mode = alc883_3ST_2ch_modes, |
10686 | .input_mux = &alc883_capture_source, | 10965 | .input_mux = &alc883_capture_source, |
10687 | .unsol_event = alc_automute_amp_unsol_event, | 10966 | .unsol_event = alc_sku_unsol_event, |
10688 | .setup = alc883_vaiott_setup, | 10967 | .setup = alc883_vaiott_setup, |
10689 | .init_hook = alc_automute_amp, | 10968 | .init_hook = alc_hp_automute, |
10690 | }, | 10969 | }, |
10691 | }; | 10970 | }; |
10692 | 10971 | ||
@@ -10699,7 +10978,6 @@ enum { | |||
10699 | PINFIX_LENOVO_Y530, | 10978 | PINFIX_LENOVO_Y530, |
10700 | PINFIX_PB_M5210, | 10979 | PINFIX_PB_M5210, |
10701 | PINFIX_ACER_ASPIRE_7736, | 10980 | PINFIX_ACER_ASPIRE_7736, |
10702 | PINFIX_GIGABYTE_880GM, | ||
10703 | }; | 10981 | }; |
10704 | 10982 | ||
10705 | static const struct alc_fixup alc882_fixups[] = { | 10983 | static const struct alc_fixup alc882_fixups[] = { |
@@ -10731,21 +11009,13 @@ static const struct alc_fixup alc882_fixups[] = { | |||
10731 | .type = ALC_FIXUP_SKU, | 11009 | .type = ALC_FIXUP_SKU, |
10732 | .v.sku = ALC_FIXUP_SKU_IGNORE, | 11010 | .v.sku = ALC_FIXUP_SKU_IGNORE, |
10733 | }, | 11011 | }, |
10734 | [PINFIX_GIGABYTE_880GM] = { | ||
10735 | .type = ALC_FIXUP_PINS, | ||
10736 | .v.pins = (const struct alc_pincfg[]) { | ||
10737 | { 0x14, 0x1114410 }, /* set as speaker */ | ||
10738 | { } | ||
10739 | } | ||
10740 | }, | ||
10741 | }; | 11012 | }; |
10742 | 11013 | ||
10743 | static struct snd_pci_quirk alc882_fixup_tbl[] = { | 11014 | static const struct snd_pci_quirk alc882_fixup_tbl[] = { |
10744 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), | 11015 | SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), |
10745 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), | 11016 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), |
10746 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), | 11017 | SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), |
10747 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), | 11018 | SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), |
10748 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM), | ||
10749 | {} | 11019 | {} |
10750 | }; | 11020 | }; |
10751 | 11021 | ||
@@ -10849,6 +11119,11 @@ static void alc882_auto_init_input_src(struct hda_codec *codec) | |||
10849 | const struct hda_input_mux *imux; | 11119 | const struct hda_input_mux *imux; |
10850 | int conns, mute, idx, item; | 11120 | int conns, mute, idx, item; |
10851 | 11121 | ||
11122 | /* mute ADC */ | ||
11123 | snd_hda_codec_write(codec, spec->adc_nids[c], 0, | ||
11124 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
11125 | AMP_IN_MUTE(0)); | ||
11126 | |||
10852 | conns = snd_hda_get_connections(codec, nid, conn_list, | 11127 | conns = snd_hda_get_connections(codec, nid, conn_list, |
10853 | ARRAY_SIZE(conn_list)); | 11128 | ARRAY_SIZE(conn_list)); |
10854 | if (conns < 0) | 11129 | if (conns < 0) |
@@ -10928,7 +11203,7 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) | |||
10928 | static int alc882_parse_auto_config(struct hda_codec *codec) | 11203 | static int alc882_parse_auto_config(struct hda_codec *codec) |
10929 | { | 11204 | { |
10930 | struct alc_spec *spec = codec->spec; | 11205 | struct alc_spec *spec = codec->spec; |
10931 | static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; | 11206 | static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; |
10932 | int err; | 11207 | int err; |
10933 | 11208 | ||
10934 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 11209 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
@@ -10941,6 +11216,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec) | |||
10941 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); | 11216 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); |
10942 | if (err < 0) | 11217 | if (err < 0) |
10943 | return err; | 11218 | return err; |
11219 | err = alc_auto_add_multi_channel_mode(codec); | ||
11220 | if (err < 0) | ||
11221 | return err; | ||
10944 | err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); | 11222 | err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); |
10945 | if (err < 0) | 11223 | if (err < 0) |
10946 | return err; | 11224 | return err; |
@@ -11142,14 +11420,14 @@ static int patch_alc882(struct hda_codec *codec) | |||
11142 | #define alc262_modes alc260_modes | 11420 | #define alc262_modes alc260_modes |
11143 | #define alc262_capture_source alc882_capture_source | 11421 | #define alc262_capture_source alc882_capture_source |
11144 | 11422 | ||
11145 | static hda_nid_t alc262_dmic_adc_nids[1] = { | 11423 | static const hda_nid_t alc262_dmic_adc_nids[1] = { |
11146 | /* ADC0 */ | 11424 | /* ADC0 */ |
11147 | 0x09 | 11425 | 0x09 |
11148 | }; | 11426 | }; |
11149 | 11427 | ||
11150 | static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; | 11428 | static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; |
11151 | 11429 | ||
11152 | static struct snd_kcontrol_new alc262_base_mixer[] = { | 11430 | static const struct snd_kcontrol_new alc262_base_mixer[] = { |
11153 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11431 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11154 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 11432 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
11155 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 11433 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
@@ -11170,71 +11448,30 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { | |||
11170 | }; | 11448 | }; |
11171 | 11449 | ||
11172 | /* update HP, line and mono-out pins according to the master switch */ | 11450 | /* update HP, line and mono-out pins according to the master switch */ |
11173 | static void alc262_hp_master_update(struct hda_codec *codec) | 11451 | #define alc262_hp_master_update alc260_hp_master_update |
11174 | { | ||
11175 | struct alc_spec *spec = codec->spec; | ||
11176 | int val = spec->master_sw; | ||
11177 | |||
11178 | /* HP & line-out */ | ||
11179 | snd_hda_codec_write_cache(codec, 0x1b, 0, | ||
11180 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
11181 | val ? PIN_HP : 0); | ||
11182 | snd_hda_codec_write_cache(codec, 0x15, 0, | ||
11183 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
11184 | val ? PIN_HP : 0); | ||
11185 | /* mono (speaker) depending on the HP jack sense */ | ||
11186 | val = val && !spec->jack_present; | ||
11187 | snd_hda_codec_write_cache(codec, 0x16, 0, | ||
11188 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
11189 | val ? PIN_OUT : 0); | ||
11190 | } | ||
11191 | 11452 | ||
11192 | static void alc262_hp_bpc_automute(struct hda_codec *codec) | 11453 | static void alc262_hp_bpc_setup(struct hda_codec *codec) |
11193 | { | 11454 | { |
11194 | struct alc_spec *spec = codec->spec; | 11455 | struct alc_spec *spec = codec->spec; |
11195 | 11456 | ||
11196 | spec->jack_present = snd_hda_jack_detect(codec, 0x1b); | 11457 | spec->autocfg.hp_pins[0] = 0x1b; |
11197 | alc262_hp_master_update(codec); | 11458 | spec->autocfg.speaker_pins[0] = 0x16; |
11198 | } | 11459 | spec->automute = 1; |
11199 | 11460 | spec->automute_mode = ALC_AUTOMUTE_PIN; | |
11200 | static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) | ||
11201 | { | ||
11202 | if ((res >> 26) != ALC880_HP_EVENT) | ||
11203 | return; | ||
11204 | alc262_hp_bpc_automute(codec); | ||
11205 | } | 11461 | } |
11206 | 11462 | ||
11207 | static void alc262_hp_wildwest_automute(struct hda_codec *codec) | 11463 | static void alc262_hp_wildwest_setup(struct hda_codec *codec) |
11208 | { | 11464 | { |
11209 | struct alc_spec *spec = codec->spec; | 11465 | struct alc_spec *spec = codec->spec; |
11210 | 11466 | ||
11211 | spec->jack_present = snd_hda_jack_detect(codec, 0x15); | 11467 | spec->autocfg.hp_pins[0] = 0x15; |
11212 | alc262_hp_master_update(codec); | 11468 | spec->autocfg.speaker_pins[0] = 0x16; |
11213 | } | 11469 | spec->automute = 1; |
11214 | 11470 | spec->automute_mode = ALC_AUTOMUTE_PIN; | |
11215 | static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, | ||
11216 | unsigned int res) | ||
11217 | { | ||
11218 | if ((res >> 26) != ALC880_HP_EVENT) | ||
11219 | return; | ||
11220 | alc262_hp_wildwest_automute(codec); | ||
11221 | } | 11471 | } |
11222 | 11472 | ||
11223 | #define alc262_hp_master_sw_get alc260_hp_master_sw_get | 11473 | #define alc262_hp_master_sw_get alc260_hp_master_sw_get |
11224 | 11474 | #define alc262_hp_master_sw_put alc260_hp_master_sw_put | |
11225 | static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, | ||
11226 | struct snd_ctl_elem_value *ucontrol) | ||
11227 | { | ||
11228 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
11229 | struct alc_spec *spec = codec->spec; | ||
11230 | int val = !!*ucontrol->value.integer.value; | ||
11231 | |||
11232 | if (val == spec->master_sw) | ||
11233 | return 0; | ||
11234 | spec->master_sw = val; | ||
11235 | alc262_hp_master_update(codec); | ||
11236 | return 1; | ||
11237 | } | ||
11238 | 11475 | ||
11239 | #define ALC262_HP_MASTER_SWITCH \ | 11476 | #define ALC262_HP_MASTER_SWITCH \ |
11240 | { \ | 11477 | { \ |
@@ -11251,7 +11488,7 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, | |||
11251 | } | 11488 | } |
11252 | 11489 | ||
11253 | 11490 | ||
11254 | static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | 11491 | static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { |
11255 | ALC262_HP_MASTER_SWITCH, | 11492 | ALC262_HP_MASTER_SWITCH, |
11256 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11493 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11257 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 11494 | HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
@@ -11275,7 +11512,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { | |||
11275 | { } /* end */ | 11512 | { } /* end */ |
11276 | }; | 11513 | }; |
11277 | 11514 | ||
11278 | static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { | 11515 | static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { |
11279 | ALC262_HP_MASTER_SWITCH, | 11516 | ALC262_HP_MASTER_SWITCH, |
11280 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11517 | HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11281 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 11518 | HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
@@ -11295,7 +11532,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { | |||
11295 | { } /* end */ | 11532 | { } /* end */ |
11296 | }; | 11533 | }; |
11297 | 11534 | ||
11298 | static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { | 11535 | static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { |
11299 | HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 11536 | HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
11300 | HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), | 11537 | HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), |
11301 | HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT), | 11538 | HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT), |
@@ -11309,9 +11546,11 @@ static void alc262_hp_t5735_setup(struct hda_codec *codec) | |||
11309 | 11546 | ||
11310 | spec->autocfg.hp_pins[0] = 0x15; | 11547 | spec->autocfg.hp_pins[0] = 0x15; |
11311 | spec->autocfg.speaker_pins[0] = 0x14; | 11548 | spec->autocfg.speaker_pins[0] = 0x14; |
11549 | spec->automute = 1; | ||
11550 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
11312 | } | 11551 | } |
11313 | 11552 | ||
11314 | static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { | 11553 | static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { |
11315 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11554 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11316 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 11555 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
11317 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), | 11556 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), |
@@ -11322,7 +11561,7 @@ static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { | |||
11322 | { } /* end */ | 11561 | { } /* end */ |
11323 | }; | 11562 | }; |
11324 | 11563 | ||
11325 | static struct hda_verb alc262_hp_t5735_verbs[] = { | 11564 | static const struct hda_verb alc262_hp_t5735_verbs[] = { |
11326 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 11565 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
11327 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 11566 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
11328 | 11567 | ||
@@ -11330,7 +11569,7 @@ static struct hda_verb alc262_hp_t5735_verbs[] = { | |||
11330 | { } | 11569 | { } |
11331 | }; | 11570 | }; |
11332 | 11571 | ||
11333 | static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { | 11572 | static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { |
11334 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11573 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11335 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 11574 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
11336 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), | 11575 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), |
@@ -11340,7 +11579,7 @@ static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { | |||
11340 | { } /* end */ | 11579 | { } /* end */ |
11341 | }; | 11580 | }; |
11342 | 11581 | ||
11343 | static struct hda_verb alc262_hp_rp5700_verbs[] = { | 11582 | static const struct hda_verb alc262_hp_rp5700_verbs[] = { |
11344 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 11583 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
11345 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 11584 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
11346 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 11585 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
@@ -11354,7 +11593,7 @@ static struct hda_verb alc262_hp_rp5700_verbs[] = { | |||
11354 | {} | 11593 | {} |
11355 | }; | 11594 | }; |
11356 | 11595 | ||
11357 | static struct hda_input_mux alc262_hp_rp5700_capture_source = { | 11596 | static const struct hda_input_mux alc262_hp_rp5700_capture_source = { |
11358 | .num_items = 1, | 11597 | .num_items = 1, |
11359 | .items = { | 11598 | .items = { |
11360 | { "Line", 0x1 }, | 11599 | { "Line", 0x1 }, |
@@ -11362,44 +11601,9 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = { | |||
11362 | }; | 11601 | }; |
11363 | 11602 | ||
11364 | /* bind hp and internal speaker mute (with plug check) as master switch */ | 11603 | /* bind hp and internal speaker mute (with plug check) as master switch */ |
11365 | static void alc262_hippo_master_update(struct hda_codec *codec) | 11604 | #define alc262_hippo_master_update alc262_hp_master_update |
11366 | { | ||
11367 | struct alc_spec *spec = codec->spec; | ||
11368 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; | ||
11369 | hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; | ||
11370 | hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; | ||
11371 | unsigned int mute; | ||
11372 | |||
11373 | /* HP */ | ||
11374 | mute = spec->master_sw ? 0 : HDA_AMP_MUTE; | ||
11375 | snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, | ||
11376 | HDA_AMP_MUTE, mute); | ||
11377 | /* mute internal speaker per jack sense */ | ||
11378 | if (spec->jack_present) | ||
11379 | mute = HDA_AMP_MUTE; | ||
11380 | if (line_nid) | ||
11381 | snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, | ||
11382 | HDA_AMP_MUTE, mute); | ||
11383 | if (speaker_nid && speaker_nid != line_nid) | ||
11384 | snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, | ||
11385 | HDA_AMP_MUTE, mute); | ||
11386 | } | ||
11387 | |||
11388 | #define alc262_hippo_master_sw_get alc262_hp_master_sw_get | 11605 | #define alc262_hippo_master_sw_get alc262_hp_master_sw_get |
11389 | 11606 | #define alc262_hippo_master_sw_put alc262_hp_master_sw_put | |
11390 | static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, | ||
11391 | struct snd_ctl_elem_value *ucontrol) | ||
11392 | { | ||
11393 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
11394 | struct alc_spec *spec = codec->spec; | ||
11395 | int val = !!*ucontrol->value.integer.value; | ||
11396 | |||
11397 | if (val == spec->master_sw) | ||
11398 | return 0; | ||
11399 | spec->master_sw = val; | ||
11400 | alc262_hippo_master_update(codec); | ||
11401 | return 1; | ||
11402 | } | ||
11403 | 11607 | ||
11404 | #define ALC262_HIPPO_MASTER_SWITCH \ | 11608 | #define ALC262_HIPPO_MASTER_SWITCH \ |
11405 | { \ | 11609 | { \ |
@@ -11416,7 +11620,7 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, | |||
11416 | (SUBDEV_SPEAKER(0) << 16), \ | 11620 | (SUBDEV_SPEAKER(0) << 16), \ |
11417 | } | 11621 | } |
11418 | 11622 | ||
11419 | static struct snd_kcontrol_new alc262_hippo_mixer[] = { | 11623 | static const struct snd_kcontrol_new alc262_hippo_mixer[] = { |
11420 | ALC262_HIPPO_MASTER_SWITCH, | 11624 | ALC262_HIPPO_MASTER_SWITCH, |
11421 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11625 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11422 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 11626 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
@@ -11433,7 +11637,7 @@ static struct snd_kcontrol_new alc262_hippo_mixer[] = { | |||
11433 | { } /* end */ | 11637 | { } /* end */ |
11434 | }; | 11638 | }; |
11435 | 11639 | ||
11436 | static struct snd_kcontrol_new alc262_hippo1_mixer[] = { | 11640 | static const struct snd_kcontrol_new alc262_hippo1_mixer[] = { |
11437 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11641 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11438 | ALC262_HIPPO_MASTER_SWITCH, | 11642 | ALC262_HIPPO_MASTER_SWITCH, |
11439 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 11643 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
@@ -11450,28 +11654,14 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = { | |||
11450 | }; | 11654 | }; |
11451 | 11655 | ||
11452 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 11656 | /* mute/unmute internal speaker according to the hp jack and mute state */ |
11453 | static void alc262_hippo_automute(struct hda_codec *codec) | ||
11454 | { | ||
11455 | struct alc_spec *spec = codec->spec; | ||
11456 | hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; | ||
11457 | |||
11458 | spec->jack_present = snd_hda_jack_detect(codec, hp_nid); | ||
11459 | alc262_hippo_master_update(codec); | ||
11460 | } | ||
11461 | |||
11462 | static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) | ||
11463 | { | ||
11464 | if ((res >> 26) != ALC880_HP_EVENT) | ||
11465 | return; | ||
11466 | alc262_hippo_automute(codec); | ||
11467 | } | ||
11468 | |||
11469 | static void alc262_hippo_setup(struct hda_codec *codec) | 11657 | static void alc262_hippo_setup(struct hda_codec *codec) |
11470 | { | 11658 | { |
11471 | struct alc_spec *spec = codec->spec; | 11659 | struct alc_spec *spec = codec->spec; |
11472 | 11660 | ||
11473 | spec->autocfg.hp_pins[0] = 0x15; | 11661 | spec->autocfg.hp_pins[0] = 0x15; |
11474 | spec->autocfg.speaker_pins[0] = 0x14; | 11662 | spec->autocfg.speaker_pins[0] = 0x14; |
11663 | spec->automute = 1; | ||
11664 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
11475 | } | 11665 | } |
11476 | 11666 | ||
11477 | static void alc262_hippo1_setup(struct hda_codec *codec) | 11667 | static void alc262_hippo1_setup(struct hda_codec *codec) |
@@ -11480,10 +11670,12 @@ static void alc262_hippo1_setup(struct hda_codec *codec) | |||
11480 | 11670 | ||
11481 | spec->autocfg.hp_pins[0] = 0x1b; | 11671 | spec->autocfg.hp_pins[0] = 0x1b; |
11482 | spec->autocfg.speaker_pins[0] = 0x14; | 11672 | spec->autocfg.speaker_pins[0] = 0x14; |
11673 | spec->automute = 1; | ||
11674 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
11483 | } | 11675 | } |
11484 | 11676 | ||
11485 | 11677 | ||
11486 | static struct snd_kcontrol_new alc262_sony_mixer[] = { | 11678 | static const struct snd_kcontrol_new alc262_sony_mixer[] = { |
11487 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11679 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11488 | ALC262_HIPPO_MASTER_SWITCH, | 11680 | ALC262_HIPPO_MASTER_SWITCH, |
11489 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 11681 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -11493,7 +11685,7 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = { | |||
11493 | { } /* end */ | 11685 | { } /* end */ |
11494 | }; | 11686 | }; |
11495 | 11687 | ||
11496 | static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { | 11688 | static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = { |
11497 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11689 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11498 | ALC262_HIPPO_MASTER_SWITCH, | 11690 | ALC262_HIPPO_MASTER_SWITCH, |
11499 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 11691 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
@@ -11504,7 +11696,7 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { | |||
11504 | { } /* end */ | 11696 | { } /* end */ |
11505 | }; | 11697 | }; |
11506 | 11698 | ||
11507 | static struct snd_kcontrol_new alc262_tyan_mixer[] = { | 11699 | static const struct snd_kcontrol_new alc262_tyan_mixer[] = { |
11508 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11700 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11509 | HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), | 11701 | HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), |
11510 | HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), | 11702 | HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), |
@@ -11520,7 +11712,7 @@ static struct snd_kcontrol_new alc262_tyan_mixer[] = { | |||
11520 | { } /* end */ | 11712 | { } /* end */ |
11521 | }; | 11713 | }; |
11522 | 11714 | ||
11523 | static struct hda_verb alc262_tyan_verbs[] = { | 11715 | static const struct hda_verb alc262_tyan_verbs[] = { |
11524 | /* Headphone automute */ | 11716 | /* Headphone automute */ |
11525 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | 11717 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
11526 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 11718 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -11542,6 +11734,8 @@ static void alc262_tyan_setup(struct hda_codec *codec) | |||
11542 | 11734 | ||
11543 | spec->autocfg.hp_pins[0] = 0x1b; | 11735 | spec->autocfg.hp_pins[0] = 0x1b; |
11544 | spec->autocfg.speaker_pins[0] = 0x15; | 11736 | spec->autocfg.speaker_pins[0] = 0x15; |
11737 | spec->automute = 1; | ||
11738 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
11545 | } | 11739 | } |
11546 | 11740 | ||
11547 | 11741 | ||
@@ -11551,7 +11745,7 @@ static void alc262_tyan_setup(struct hda_codec *codec) | |||
11551 | /* | 11745 | /* |
11552 | * generic initialization of ADC, input mixers and output mixers | 11746 | * generic initialization of ADC, input mixers and output mixers |
11553 | */ | 11747 | */ |
11554 | static struct hda_verb alc262_init_verbs[] = { | 11748 | static const struct hda_verb alc262_init_verbs[] = { |
11555 | /* | 11749 | /* |
11556 | * Unmute ADC0-2 and set the default input to mic-in | 11750 | * Unmute ADC0-2 and set the default input to mic-in |
11557 | */ | 11751 | */ |
@@ -11627,13 +11821,13 @@ static struct hda_verb alc262_init_verbs[] = { | |||
11627 | { } | 11821 | { } |
11628 | }; | 11822 | }; |
11629 | 11823 | ||
11630 | static struct hda_verb alc262_eapd_verbs[] = { | 11824 | static const struct hda_verb alc262_eapd_verbs[] = { |
11631 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 11825 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
11632 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 11826 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
11633 | { } | 11827 | { } |
11634 | }; | 11828 | }; |
11635 | 11829 | ||
11636 | static struct hda_verb alc262_hippo1_unsol_verbs[] = { | 11830 | static const struct hda_verb alc262_hippo1_unsol_verbs[] = { |
11637 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | 11831 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, |
11638 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, | 11832 | {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, |
11639 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, | 11833 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, |
@@ -11643,7 +11837,7 @@ static struct hda_verb alc262_hippo1_unsol_verbs[] = { | |||
11643 | {} | 11837 | {} |
11644 | }; | 11838 | }; |
11645 | 11839 | ||
11646 | static struct hda_verb alc262_sony_unsol_verbs[] = { | 11840 | static const struct hda_verb alc262_sony_unsol_verbs[] = { |
11647 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, | 11841 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, |
11648 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 11842 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
11649 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic | 11843 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic |
@@ -11653,7 +11847,7 @@ static struct hda_verb alc262_sony_unsol_verbs[] = { | |||
11653 | {} | 11847 | {} |
11654 | }; | 11848 | }; |
11655 | 11849 | ||
11656 | static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { | 11850 | static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { |
11657 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 11851 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11658 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 11852 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
11659 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 11853 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
@@ -11662,7 +11856,7 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { | |||
11662 | { } /* end */ | 11856 | { } /* end */ |
11663 | }; | 11857 | }; |
11664 | 11858 | ||
11665 | static struct hda_verb alc262_toshiba_s06_verbs[] = { | 11859 | static const struct hda_verb alc262_toshiba_s06_verbs[] = { |
11666 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 11860 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
11667 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 11861 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
11668 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 11862 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -11685,6 +11879,8 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec) | |||
11685 | spec->int_mic.pin = 0x12; | 11879 | spec->int_mic.pin = 0x12; |
11686 | spec->int_mic.mux_idx = 9; | 11880 | spec->int_mic.mux_idx = 9; |
11687 | spec->auto_mic = 1; | 11881 | spec->auto_mic = 1; |
11882 | spec->automute = 1; | ||
11883 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
11688 | } | 11884 | } |
11689 | 11885 | ||
11690 | /* | 11886 | /* |
@@ -11694,7 +11890,7 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec) | |||
11694 | * 0x18 = external mic | 11890 | * 0x18 = external mic |
11695 | */ | 11891 | */ |
11696 | 11892 | ||
11697 | static struct snd_kcontrol_new alc262_nec_mixer[] = { | 11893 | static const struct snd_kcontrol_new alc262_nec_mixer[] = { |
11698 | HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), | 11894 | HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), |
11699 | HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), | 11895 | HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), |
11700 | 11896 | ||
@@ -11707,7 +11903,7 @@ static struct snd_kcontrol_new alc262_nec_mixer[] = { | |||
11707 | { } /* end */ | 11903 | { } /* end */ |
11708 | }; | 11904 | }; |
11709 | 11905 | ||
11710 | static struct hda_verb alc262_nec_verbs[] = { | 11906 | static const struct hda_verb alc262_nec_verbs[] = { |
11711 | /* Unmute Speaker */ | 11907 | /* Unmute Speaker */ |
11712 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 11908 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
11713 | 11909 | ||
@@ -11730,7 +11926,7 @@ static struct hda_verb alc262_nec_verbs[] = { | |||
11730 | 11926 | ||
11731 | #define ALC_HP_EVENT 0x37 | 11927 | #define ALC_HP_EVENT 0x37 |
11732 | 11928 | ||
11733 | static struct hda_verb alc262_fujitsu_unsol_verbs[] = { | 11929 | static const struct hda_verb alc262_fujitsu_unsol_verbs[] = { |
11734 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | 11930 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, |
11735 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 11931 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
11736 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | 11932 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, |
@@ -11738,20 +11934,20 @@ static struct hda_verb alc262_fujitsu_unsol_verbs[] = { | |||
11738 | {} | 11934 | {} |
11739 | }; | 11935 | }; |
11740 | 11936 | ||
11741 | static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { | 11937 | static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { |
11742 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, | 11938 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, |
11743 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 11939 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
11744 | {} | 11940 | {} |
11745 | }; | 11941 | }; |
11746 | 11942 | ||
11747 | static struct hda_verb alc262_lenovo_3000_init_verbs[] = { | 11943 | static const struct hda_verb alc262_lenovo_3000_init_verbs[] = { |
11748 | /* Front Mic pin: input vref at 50% */ | 11944 | /* Front Mic pin: input vref at 50% */ |
11749 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, | 11945 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, |
11750 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 11946 | {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, |
11751 | {} | 11947 | {} |
11752 | }; | 11948 | }; |
11753 | 11949 | ||
11754 | static struct hda_input_mux alc262_fujitsu_capture_source = { | 11950 | static const struct hda_input_mux alc262_fujitsu_capture_source = { |
11755 | .num_items = 3, | 11951 | .num_items = 3, |
11756 | .items = { | 11952 | .items = { |
11757 | { "Mic", 0x0 }, | 11953 | { "Mic", 0x0 }, |
@@ -11760,7 +11956,7 @@ static struct hda_input_mux alc262_fujitsu_capture_source = { | |||
11760 | }, | 11956 | }, |
11761 | }; | 11957 | }; |
11762 | 11958 | ||
11763 | static struct hda_input_mux alc262_HP_capture_source = { | 11959 | static const struct hda_input_mux alc262_HP_capture_source = { |
11764 | .num_items = 5, | 11960 | .num_items = 5, |
11765 | .items = { | 11961 | .items = { |
11766 | { "Mic", 0x0 }, | 11962 | { "Mic", 0x0 }, |
@@ -11771,7 +11967,7 @@ static struct hda_input_mux alc262_HP_capture_source = { | |||
11771 | }, | 11967 | }, |
11772 | }; | 11968 | }; |
11773 | 11969 | ||
11774 | static struct hda_input_mux alc262_HP_D7000_capture_source = { | 11970 | static const struct hda_input_mux alc262_HP_D7000_capture_source = { |
11775 | .num_items = 4, | 11971 | .num_items = 4, |
11776 | .items = { | 11972 | .items = { |
11777 | { "Mic", 0x0 }, | 11973 | { "Mic", 0x0 }, |
@@ -11781,44 +11977,19 @@ static struct hda_input_mux alc262_HP_D7000_capture_source = { | |||
11781 | }, | 11977 | }, |
11782 | }; | 11978 | }; |
11783 | 11979 | ||
11784 | /* mute/unmute internal speaker according to the hp jacks and mute state */ | 11980 | static void alc262_fujitsu_setup(struct hda_codec *codec) |
11785 | static void alc262_fujitsu_automute(struct hda_codec *codec, int force) | ||
11786 | { | 11981 | { |
11787 | struct alc_spec *spec = codec->spec; | 11982 | struct alc_spec *spec = codec->spec; |
11788 | unsigned int mute; | ||
11789 | 11983 | ||
11790 | if (force || !spec->sense_updated) { | 11984 | spec->autocfg.hp_pins[0] = 0x14; |
11791 | spec->jack_present = snd_hda_jack_detect(codec, 0x14) || | 11985 | spec->autocfg.hp_pins[1] = 0x1b; |
11792 | snd_hda_jack_detect(codec, 0x1b); | 11986 | spec->autocfg.speaker_pins[0] = 0x15; |
11793 | spec->sense_updated = 1; | 11987 | spec->automute = 1; |
11794 | } | 11988 | spec->automute_mode = ALC_AUTOMUTE_AMP; |
11795 | /* unmute internal speaker only if both HPs are unplugged and | ||
11796 | * master switch is on | ||
11797 | */ | ||
11798 | if (spec->jack_present) | ||
11799 | mute = HDA_AMP_MUTE; | ||
11800 | else | ||
11801 | mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); | ||
11802 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
11803 | HDA_AMP_MUTE, mute); | ||
11804 | } | ||
11805 | |||
11806 | /* unsolicited event for HP jack sensing */ | ||
11807 | static void alc262_fujitsu_unsol_event(struct hda_codec *codec, | ||
11808 | unsigned int res) | ||
11809 | { | ||
11810 | if ((res >> 26) != ALC_HP_EVENT) | ||
11811 | return; | ||
11812 | alc262_fujitsu_automute(codec, 1); | ||
11813 | } | ||
11814 | |||
11815 | static void alc262_fujitsu_init_hook(struct hda_codec *codec) | ||
11816 | { | ||
11817 | alc262_fujitsu_automute(codec, 1); | ||
11818 | } | 11989 | } |
11819 | 11990 | ||
11820 | /* bind volumes of both NID 0x0c and 0x0d */ | 11991 | /* bind volumes of both NID 0x0c and 0x0d */ |
11821 | static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { | 11992 | static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { |
11822 | .ops = &snd_hda_bind_vol, | 11993 | .ops = &snd_hda_bind_vol, |
11823 | .values = { | 11994 | .values = { |
11824 | HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), | 11995 | HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), |
@@ -11827,78 +11998,15 @@ static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { | |||
11827 | }, | 11998 | }, |
11828 | }; | 11999 | }; |
11829 | 12000 | ||
11830 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 12001 | static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = { |
11831 | static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) | ||
11832 | { | ||
11833 | struct alc_spec *spec = codec->spec; | ||
11834 | unsigned int mute; | ||
11835 | |||
11836 | if (force || !spec->sense_updated) { | ||
11837 | spec->jack_present = snd_hda_jack_detect(codec, 0x1b); | ||
11838 | spec->sense_updated = 1; | ||
11839 | } | ||
11840 | if (spec->jack_present) { | ||
11841 | /* mute internal speaker */ | ||
11842 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
11843 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
11844 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
11845 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
11846 | } else { | ||
11847 | /* unmute internal speaker if necessary */ | ||
11848 | mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); | ||
11849 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
11850 | HDA_AMP_MUTE, mute); | ||
11851 | snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, | ||
11852 | HDA_AMP_MUTE, mute); | ||
11853 | } | ||
11854 | } | ||
11855 | |||
11856 | /* unsolicited event for HP jack sensing */ | ||
11857 | static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, | ||
11858 | unsigned int res) | ||
11859 | { | ||
11860 | if ((res >> 26) != ALC_HP_EVENT) | ||
11861 | return; | ||
11862 | alc262_lenovo_3000_automute(codec, 1); | ||
11863 | } | ||
11864 | |||
11865 | static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid, | ||
11866 | int dir, int idx, long *valp) | ||
11867 | { | ||
11868 | int i, change = 0; | ||
11869 | |||
11870 | for (i = 0; i < 2; i++, valp++) | ||
11871 | change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx, | ||
11872 | HDA_AMP_MUTE, | ||
11873 | *valp ? 0 : HDA_AMP_MUTE); | ||
11874 | return change; | ||
11875 | } | ||
11876 | |||
11877 | /* bind hp and internal speaker mute (with plug check) */ | ||
11878 | static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, | ||
11879 | struct snd_ctl_elem_value *ucontrol) | ||
11880 | { | ||
11881 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
11882 | long *valp = ucontrol->value.integer.value; | ||
11883 | int change; | ||
11884 | |||
11885 | change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); | ||
11886 | change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); | ||
11887 | if (change) | ||
11888 | alc262_fujitsu_automute(codec, 0); | ||
11889 | return change; | ||
11890 | } | ||
11891 | |||
11892 | static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { | ||
11893 | HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), | 12002 | HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), |
11894 | { | 12003 | { |
11895 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 12004 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
11896 | .name = "Master Playback Switch", | 12005 | .name = "Master Playback Switch", |
11897 | .subdevice = HDA_SUBDEV_AMP_FLAG, | 12006 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, |
11898 | .info = snd_hda_mixer_amp_switch_info, | 12007 | .info = snd_ctl_boolean_mono_info, |
11899 | .get = snd_hda_mixer_amp_switch_get, | 12008 | .get = alc262_hp_master_sw_get, |
11900 | .put = alc262_fujitsu_master_sw_put, | 12009 | .put = alc262_hp_master_sw_put, |
11901 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
11902 | }, | 12010 | }, |
11903 | { | 12011 | { |
11904 | .iface = NID_MAPPING, | 12012 | .iface = NID_MAPPING, |
@@ -11916,30 +12024,26 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { | |||
11916 | { } /* end */ | 12024 | { } /* end */ |
11917 | }; | 12025 | }; |
11918 | 12026 | ||
11919 | /* bind hp and internal speaker mute (with plug check) */ | 12027 | static void alc262_lenovo_3000_setup(struct hda_codec *codec) |
11920 | static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, | ||
11921 | struct snd_ctl_elem_value *ucontrol) | ||
11922 | { | 12028 | { |
11923 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 12029 | struct alc_spec *spec = codec->spec; |
11924 | long *valp = ucontrol->value.integer.value; | ||
11925 | int change; | ||
11926 | 12030 | ||
11927 | change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); | 12031 | spec->autocfg.hp_pins[0] = 0x1b; |
11928 | if (change) | 12032 | spec->autocfg.speaker_pins[0] = 0x14; |
11929 | alc262_lenovo_3000_automute(codec, 0); | 12033 | spec->autocfg.speaker_pins[1] = 0x16; |
11930 | return change; | 12034 | spec->automute = 1; |
12035 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
11931 | } | 12036 | } |
11932 | 12037 | ||
11933 | static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { | 12038 | static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { |
11934 | HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), | 12039 | HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), |
11935 | { | 12040 | { |
11936 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 12041 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
11937 | .name = "Master Playback Switch", | 12042 | .name = "Master Playback Switch", |
11938 | .subdevice = HDA_SUBDEV_AMP_FLAG, | 12043 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, |
11939 | .info = snd_hda_mixer_amp_switch_info, | 12044 | .info = snd_ctl_boolean_mono_info, |
11940 | .get = snd_hda_mixer_amp_switch_get, | 12045 | .get = alc262_hp_master_sw_get, |
11941 | .put = alc262_lenovo_3000_master_sw_put, | 12046 | .put = alc262_hp_master_sw_put, |
11942 | .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), | ||
11943 | }, | 12047 | }, |
11944 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), | 12048 | HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), |
11945 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), | 12049 | HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), |
@@ -11952,7 +12056,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { | |||
11952 | { } /* end */ | 12056 | { } /* end */ |
11953 | }; | 12057 | }; |
11954 | 12058 | ||
11955 | static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { | 12059 | static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { |
11956 | HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), | 12060 | HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), |
11957 | ALC262_HIPPO_MASTER_SWITCH, | 12061 | ALC262_HIPPO_MASTER_SWITCH, |
11958 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 12062 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -11965,13 +12069,13 @@ static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { | |||
11965 | }; | 12069 | }; |
11966 | 12070 | ||
11967 | /* additional init verbs for Benq laptops */ | 12071 | /* additional init verbs for Benq laptops */ |
11968 | static struct hda_verb alc262_EAPD_verbs[] = { | 12072 | static const struct hda_verb alc262_EAPD_verbs[] = { |
11969 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, | 12073 | {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, |
11970 | {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, | 12074 | {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, |
11971 | {} | 12075 | {} |
11972 | }; | 12076 | }; |
11973 | 12077 | ||
11974 | static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { | 12078 | static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = { |
11975 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, | 12079 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, |
11976 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, | 12080 | {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, |
11977 | 12081 | ||
@@ -11981,7 +12085,7 @@ static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { | |||
11981 | }; | 12085 | }; |
11982 | 12086 | ||
11983 | /* Samsung Q1 Ultra Vista model setup */ | 12087 | /* Samsung Q1 Ultra Vista model setup */ |
11984 | static struct snd_kcontrol_new alc262_ultra_mixer[] = { | 12088 | static const struct snd_kcontrol_new alc262_ultra_mixer[] = { |
11985 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), | 12089 | HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), |
11986 | HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), | 12090 | HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), |
11987 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), | 12091 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), |
@@ -11991,7 +12095,7 @@ static struct snd_kcontrol_new alc262_ultra_mixer[] = { | |||
11991 | { } /* end */ | 12095 | { } /* end */ |
11992 | }; | 12096 | }; |
11993 | 12097 | ||
11994 | static struct hda_verb alc262_ultra_verbs[] = { | 12098 | static const struct hda_verb alc262_ultra_verbs[] = { |
11995 | /* output mixer */ | 12099 | /* output mixer */ |
11996 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 12100 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
11997 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 12101 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
@@ -12054,7 +12158,7 @@ static void alc262_ultra_unsol_event(struct hda_codec *codec, | |||
12054 | alc262_ultra_automute(codec); | 12158 | alc262_ultra_automute(codec); |
12055 | } | 12159 | } |
12056 | 12160 | ||
12057 | static struct hda_input_mux alc262_ultra_capture_source = { | 12161 | static const struct hda_input_mux alc262_ultra_capture_source = { |
12058 | .num_items = 2, | 12162 | .num_items = 2, |
12059 | .items = { | 12163 | .items = { |
12060 | { "Mic", 0x1 }, | 12164 | { "Mic", 0x1 }, |
@@ -12080,7 +12184,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
12080 | return ret; | 12184 | return ret; |
12081 | } | 12185 | } |
12082 | 12186 | ||
12083 | static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { | 12187 | static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { |
12084 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), | 12188 | HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), |
12085 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), | 12189 | HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), |
12086 | { | 12190 | { |
@@ -12155,9 +12259,9 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
12155 | 12259 | ||
12156 | spec->multiout.num_dacs = 1; /* only use one dac */ | 12260 | spec->multiout.num_dacs = 1; /* only use one dac */ |
12157 | spec->multiout.dac_nids = spec->private_dac_nids; | 12261 | spec->multiout.dac_nids = spec->private_dac_nids; |
12158 | spec->multiout.dac_nids[0] = 2; | 12262 | spec->private_dac_nids[0] = 2; |
12159 | 12263 | ||
12160 | pfx = alc_get_line_out_pfx(cfg, true); | 12264 | pfx = alc_get_line_out_pfx(spec, true); |
12161 | if (!pfx) | 12265 | if (!pfx) |
12162 | pfx = "Front"; | 12266 | pfx = "Front"; |
12163 | for (i = 0; i < 2; i++) { | 12267 | for (i = 0; i < 2; i++) { |
@@ -12211,7 +12315,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
12211 | /* | 12315 | /* |
12212 | * generic initialization of ADC, input mixers and output mixers | 12316 | * generic initialization of ADC, input mixers and output mixers |
12213 | */ | 12317 | */ |
12214 | static struct hda_verb alc262_volume_init_verbs[] = { | 12318 | static const struct hda_verb alc262_volume_init_verbs[] = { |
12215 | /* | 12319 | /* |
12216 | * Unmute ADC0-2 and set the default input to mic-in | 12320 | * Unmute ADC0-2 and set the default input to mic-in |
12217 | */ | 12321 | */ |
@@ -12272,7 +12376,7 @@ static struct hda_verb alc262_volume_init_verbs[] = { | |||
12272 | { } | 12376 | { } |
12273 | }; | 12377 | }; |
12274 | 12378 | ||
12275 | static struct hda_verb alc262_HP_BPC_init_verbs[] = { | 12379 | static const struct hda_verb alc262_HP_BPC_init_verbs[] = { |
12276 | /* | 12380 | /* |
12277 | * Unmute ADC0-2 and set the default input to mic-in | 12381 | * Unmute ADC0-2 and set the default input to mic-in |
12278 | */ | 12382 | */ |
@@ -12376,7 +12480,7 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { | |||
12376 | { } | 12480 | { } |
12377 | }; | 12481 | }; |
12378 | 12482 | ||
12379 | static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { | 12483 | static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { |
12380 | /* | 12484 | /* |
12381 | * Unmute ADC0-2 and set the default input to mic-in | 12485 | * Unmute ADC0-2 and set the default input to mic-in |
12382 | */ | 12486 | */ |
@@ -12472,7 +12576,7 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { | |||
12472 | { } | 12576 | { } |
12473 | }; | 12577 | }; |
12474 | 12578 | ||
12475 | static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { | 12579 | static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { |
12476 | 12580 | ||
12477 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ | 12581 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ |
12478 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 12582 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
@@ -12508,7 +12612,7 @@ static const struct alc_fixup alc262_fixups[] = { | |||
12508 | }, | 12612 | }, |
12509 | }; | 12613 | }; |
12510 | 12614 | ||
12511 | static struct snd_pci_quirk alc262_fixup_tbl[] = { | 12615 | static const struct snd_pci_quirk alc262_fixup_tbl[] = { |
12512 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), | 12616 | SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), |
12513 | {} | 12617 | {} |
12514 | }; | 12618 | }; |
@@ -12531,7 +12635,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) | |||
12531 | { | 12635 | { |
12532 | struct alc_spec *spec = codec->spec; | 12636 | struct alc_spec *spec = codec->spec; |
12533 | int err; | 12637 | int err; |
12534 | static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; | 12638 | static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; |
12535 | 12639 | ||
12536 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 12640 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
12537 | alc262_ignore); | 12641 | alc262_ignore); |
@@ -12616,7 +12720,7 @@ static const char * const alc262_models[ALC262_MODEL_LAST] = { | |||
12616 | [ALC262_AUTO] = "auto", | 12720 | [ALC262_AUTO] = "auto", |
12617 | }; | 12721 | }; |
12618 | 12722 | ||
12619 | static struct snd_pci_quirk alc262_cfg_tbl[] = { | 12723 | static const struct snd_pci_quirk alc262_cfg_tbl[] = { |
12620 | SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), | 12724 | SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), |
12621 | SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), | 12725 | SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), |
12622 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", | 12726 | SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", |
@@ -12668,7 +12772,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { | |||
12668 | {} | 12772 | {} |
12669 | }; | 12773 | }; |
12670 | 12774 | ||
12671 | static struct alc_config_preset alc262_presets[] = { | 12775 | static const struct alc_config_preset alc262_presets[] = { |
12672 | [ALC262_BASIC] = { | 12776 | [ALC262_BASIC] = { |
12673 | .mixers = { alc262_base_mixer }, | 12777 | .mixers = { alc262_base_mixer }, |
12674 | .init_verbs = { alc262_init_verbs }, | 12778 | .init_verbs = { alc262_init_verbs }, |
@@ -12689,9 +12793,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12689 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12793 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12690 | .channel_mode = alc262_modes, | 12794 | .channel_mode = alc262_modes, |
12691 | .input_mux = &alc262_capture_source, | 12795 | .input_mux = &alc262_capture_source, |
12692 | .unsol_event = alc262_hippo_unsol_event, | 12796 | .unsol_event = alc_sku_unsol_event, |
12693 | .setup = alc262_hippo_setup, | 12797 | .setup = alc262_hippo_setup, |
12694 | .init_hook = alc262_hippo_automute, | 12798 | .init_hook = alc_inithook, |
12695 | }, | 12799 | }, |
12696 | [ALC262_HIPPO_1] = { | 12800 | [ALC262_HIPPO_1] = { |
12697 | .mixers = { alc262_hippo1_mixer }, | 12801 | .mixers = { alc262_hippo1_mixer }, |
@@ -12703,9 +12807,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12703 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12807 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12704 | .channel_mode = alc262_modes, | 12808 | .channel_mode = alc262_modes, |
12705 | .input_mux = &alc262_capture_source, | 12809 | .input_mux = &alc262_capture_source, |
12706 | .unsol_event = alc262_hippo_unsol_event, | 12810 | .unsol_event = alc_sku_unsol_event, |
12707 | .setup = alc262_hippo1_setup, | 12811 | .setup = alc262_hippo1_setup, |
12708 | .init_hook = alc262_hippo_automute, | 12812 | .init_hook = alc_inithook, |
12709 | }, | 12813 | }, |
12710 | [ALC262_FUJITSU] = { | 12814 | [ALC262_FUJITSU] = { |
12711 | .mixers = { alc262_fujitsu_mixer }, | 12815 | .mixers = { alc262_fujitsu_mixer }, |
@@ -12718,8 +12822,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12718 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12822 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12719 | .channel_mode = alc262_modes, | 12823 | .channel_mode = alc262_modes, |
12720 | .input_mux = &alc262_fujitsu_capture_source, | 12824 | .input_mux = &alc262_fujitsu_capture_source, |
12721 | .unsol_event = alc262_fujitsu_unsol_event, | 12825 | .unsol_event = alc_sku_unsol_event, |
12722 | .init_hook = alc262_fujitsu_init_hook, | 12826 | .setup = alc262_fujitsu_setup, |
12827 | .init_hook = alc_inithook, | ||
12723 | }, | 12828 | }, |
12724 | [ALC262_HP_BPC] = { | 12829 | [ALC262_HP_BPC] = { |
12725 | .mixers = { alc262_HP_BPC_mixer }, | 12830 | .mixers = { alc262_HP_BPC_mixer }, |
@@ -12730,8 +12835,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12730 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12835 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12731 | .channel_mode = alc262_modes, | 12836 | .channel_mode = alc262_modes, |
12732 | .input_mux = &alc262_HP_capture_source, | 12837 | .input_mux = &alc262_HP_capture_source, |
12733 | .unsol_event = alc262_hp_bpc_unsol_event, | 12838 | .unsol_event = alc_sku_unsol_event, |
12734 | .init_hook = alc262_hp_bpc_automute, | 12839 | .setup = alc262_hp_bpc_setup, |
12840 | .init_hook = alc_inithook, | ||
12735 | }, | 12841 | }, |
12736 | [ALC262_HP_BPC_D7000_WF] = { | 12842 | [ALC262_HP_BPC_D7000_WF] = { |
12737 | .mixers = { alc262_HP_BPC_WildWest_mixer }, | 12843 | .mixers = { alc262_HP_BPC_WildWest_mixer }, |
@@ -12742,8 +12848,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12742 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12848 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12743 | .channel_mode = alc262_modes, | 12849 | .channel_mode = alc262_modes, |
12744 | .input_mux = &alc262_HP_D7000_capture_source, | 12850 | .input_mux = &alc262_HP_D7000_capture_source, |
12745 | .unsol_event = alc262_hp_wildwest_unsol_event, | 12851 | .unsol_event = alc_sku_unsol_event, |
12746 | .init_hook = alc262_hp_wildwest_automute, | 12852 | .setup = alc262_hp_wildwest_setup, |
12853 | .init_hook = alc_inithook, | ||
12747 | }, | 12854 | }, |
12748 | [ALC262_HP_BPC_D7000_WL] = { | 12855 | [ALC262_HP_BPC_D7000_WL] = { |
12749 | .mixers = { alc262_HP_BPC_WildWest_mixer, | 12856 | .mixers = { alc262_HP_BPC_WildWest_mixer, |
@@ -12755,8 +12862,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12755 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12862 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12756 | .channel_mode = alc262_modes, | 12863 | .channel_mode = alc262_modes, |
12757 | .input_mux = &alc262_HP_D7000_capture_source, | 12864 | .input_mux = &alc262_HP_D7000_capture_source, |
12758 | .unsol_event = alc262_hp_wildwest_unsol_event, | 12865 | .unsol_event = alc_sku_unsol_event, |
12759 | .init_hook = alc262_hp_wildwest_automute, | 12866 | .setup = alc262_hp_wildwest_setup, |
12867 | .init_hook = alc_inithook, | ||
12760 | }, | 12868 | }, |
12761 | [ALC262_HP_TC_T5735] = { | 12869 | [ALC262_HP_TC_T5735] = { |
12762 | .mixers = { alc262_hp_t5735_mixer }, | 12870 | .mixers = { alc262_hp_t5735_mixer }, |
@@ -12799,9 +12907,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12799 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12907 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12800 | .channel_mode = alc262_modes, | 12908 | .channel_mode = alc262_modes, |
12801 | .input_mux = &alc262_capture_source, | 12909 | .input_mux = &alc262_capture_source, |
12802 | .unsol_event = alc262_hippo_unsol_event, | 12910 | .unsol_event = alc_sku_unsol_event, |
12803 | .setup = alc262_hippo_setup, | 12911 | .setup = alc262_hippo_setup, |
12804 | .init_hook = alc262_hippo_automute, | 12912 | .init_hook = alc_inithook, |
12805 | }, | 12913 | }, |
12806 | [ALC262_BENQ_T31] = { | 12914 | [ALC262_BENQ_T31] = { |
12807 | .mixers = { alc262_benq_t31_mixer }, | 12915 | .mixers = { alc262_benq_t31_mixer }, |
@@ -12813,9 +12921,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12813 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12921 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12814 | .channel_mode = alc262_modes, | 12922 | .channel_mode = alc262_modes, |
12815 | .input_mux = &alc262_capture_source, | 12923 | .input_mux = &alc262_capture_source, |
12816 | .unsol_event = alc262_hippo_unsol_event, | 12924 | .unsol_event = alc_sku_unsol_event, |
12817 | .setup = alc262_hippo_setup, | 12925 | .setup = alc262_hippo_setup, |
12818 | .init_hook = alc262_hippo_automute, | 12926 | .init_hook = alc_inithook, |
12819 | }, | 12927 | }, |
12820 | [ALC262_ULTRA] = { | 12928 | [ALC262_ULTRA] = { |
12821 | .mixers = { alc262_ultra_mixer }, | 12929 | .mixers = { alc262_ultra_mixer }, |
@@ -12844,7 +12952,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12844 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12952 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12845 | .channel_mode = alc262_modes, | 12953 | .channel_mode = alc262_modes, |
12846 | .input_mux = &alc262_fujitsu_capture_source, | 12954 | .input_mux = &alc262_fujitsu_capture_source, |
12847 | .unsol_event = alc262_lenovo_3000_unsol_event, | 12955 | .unsol_event = alc_sku_unsol_event, |
12956 | .setup = alc262_lenovo_3000_setup, | ||
12957 | .init_hook = alc_inithook, | ||
12848 | }, | 12958 | }, |
12849 | [ALC262_NEC] = { | 12959 | [ALC262_NEC] = { |
12850 | .mixers = { alc262_nec_mixer }, | 12960 | .mixers = { alc262_nec_mixer }, |
@@ -12881,9 +12991,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12881 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 12991 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12882 | .channel_mode = alc262_modes, | 12992 | .channel_mode = alc262_modes, |
12883 | .input_mux = &alc262_capture_source, | 12993 | .input_mux = &alc262_capture_source, |
12884 | .unsol_event = alc262_hippo_unsol_event, | 12994 | .unsol_event = alc_sku_unsol_event, |
12885 | .setup = alc262_hippo_setup, | 12995 | .setup = alc262_hippo_setup, |
12886 | .init_hook = alc262_hippo_automute, | 12996 | .init_hook = alc_inithook, |
12887 | }, | 12997 | }, |
12888 | [ALC262_TYAN] = { | 12998 | [ALC262_TYAN] = { |
12889 | .mixers = { alc262_tyan_mixer }, | 12999 | .mixers = { alc262_tyan_mixer }, |
@@ -12895,9 +13005,9 @@ static struct alc_config_preset alc262_presets[] = { | |||
12895 | .num_channel_mode = ARRAY_SIZE(alc262_modes), | 13005 | .num_channel_mode = ARRAY_SIZE(alc262_modes), |
12896 | .channel_mode = alc262_modes, | 13006 | .channel_mode = alc262_modes, |
12897 | .input_mux = &alc262_capture_source, | 13007 | .input_mux = &alc262_capture_source, |
12898 | .unsol_event = alc_automute_amp_unsol_event, | 13008 | .unsol_event = alc_sku_unsol_event, |
12899 | .setup = alc262_tyan_setup, | 13009 | .setup = alc262_tyan_setup, |
12900 | .init_hook = alc_automute_amp, | 13010 | .init_hook = alc_hp_automute, |
12901 | }, | 13011 | }, |
12902 | }; | 13012 | }; |
12903 | 13013 | ||
@@ -13018,6 +13128,7 @@ static int patch_alc262(struct hda_codec *codec) | |||
13018 | codec->patch_ops = alc_patch_ops; | 13128 | codec->patch_ops = alc_patch_ops; |
13019 | if (board_config == ALC262_AUTO) | 13129 | if (board_config == ALC262_AUTO) |
13020 | spec->init_hook = alc262_auto_init; | 13130 | spec->init_hook = alc262_auto_init; |
13131 | spec->shutup = alc_eapd_shutup; | ||
13021 | 13132 | ||
13022 | alc_init_jacks(codec); | 13133 | alc_init_jacks(codec); |
13023 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 13134 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -13034,24 +13145,24 @@ static int patch_alc262(struct hda_codec *codec) | |||
13034 | #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID | 13145 | #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID |
13035 | #define alc268_modes alc260_modes | 13146 | #define alc268_modes alc260_modes |
13036 | 13147 | ||
13037 | static hda_nid_t alc268_dac_nids[2] = { | 13148 | static const hda_nid_t alc268_dac_nids[2] = { |
13038 | /* front, hp */ | 13149 | /* front, hp */ |
13039 | 0x02, 0x03 | 13150 | 0x02, 0x03 |
13040 | }; | 13151 | }; |
13041 | 13152 | ||
13042 | static hda_nid_t alc268_adc_nids[2] = { | 13153 | static const hda_nid_t alc268_adc_nids[2] = { |
13043 | /* ADC0-1 */ | 13154 | /* ADC0-1 */ |
13044 | 0x08, 0x07 | 13155 | 0x08, 0x07 |
13045 | }; | 13156 | }; |
13046 | 13157 | ||
13047 | static hda_nid_t alc268_adc_nids_alt[1] = { | 13158 | static const hda_nid_t alc268_adc_nids_alt[1] = { |
13048 | /* ADC0 */ | 13159 | /* ADC0 */ |
13049 | 0x08 | 13160 | 0x08 |
13050 | }; | 13161 | }; |
13051 | 13162 | ||
13052 | static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; | 13163 | static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; |
13053 | 13164 | ||
13054 | static struct snd_kcontrol_new alc268_base_mixer[] = { | 13165 | static const struct snd_kcontrol_new alc268_base_mixer[] = { |
13055 | /* output mixer control */ | 13166 | /* output mixer control */ |
13056 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | 13167 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), |
13057 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 13168 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -13063,7 +13174,7 @@ static struct snd_kcontrol_new alc268_base_mixer[] = { | |||
13063 | { } | 13174 | { } |
13064 | }; | 13175 | }; |
13065 | 13176 | ||
13066 | static struct snd_kcontrol_new alc268_toshiba_mixer[] = { | 13177 | static const struct snd_kcontrol_new alc268_toshiba_mixer[] = { |
13067 | /* output mixer control */ | 13178 | /* output mixer control */ |
13068 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | 13179 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), |
13069 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), | 13180 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), |
@@ -13075,7 +13186,7 @@ static struct snd_kcontrol_new alc268_toshiba_mixer[] = { | |||
13075 | }; | 13186 | }; |
13076 | 13187 | ||
13077 | /* bind Beep switches of both NID 0x0f and 0x10 */ | 13188 | /* bind Beep switches of both NID 0x0f and 0x10 */ |
13078 | static struct hda_bind_ctls alc268_bind_beep_sw = { | 13189 | static const struct hda_bind_ctls alc268_bind_beep_sw = { |
13079 | .ops = &snd_hda_bind_sw, | 13190 | .ops = &snd_hda_bind_sw, |
13080 | .values = { | 13191 | .values = { |
13081 | HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), | 13192 | HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), |
@@ -13084,27 +13195,27 @@ static struct hda_bind_ctls alc268_bind_beep_sw = { | |||
13084 | }, | 13195 | }, |
13085 | }; | 13196 | }; |
13086 | 13197 | ||
13087 | static struct snd_kcontrol_new alc268_beep_mixer[] = { | 13198 | static const struct snd_kcontrol_new alc268_beep_mixer[] = { |
13088 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), | 13199 | HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), |
13089 | HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), | 13200 | HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), |
13090 | { } | 13201 | { } |
13091 | }; | 13202 | }; |
13092 | 13203 | ||
13093 | static struct hda_verb alc268_eapd_verbs[] = { | 13204 | static const struct hda_verb alc268_eapd_verbs[] = { |
13094 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 13205 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
13095 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 13206 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
13096 | { } | 13207 | { } |
13097 | }; | 13208 | }; |
13098 | 13209 | ||
13099 | /* Toshiba specific */ | 13210 | /* Toshiba specific */ |
13100 | static struct hda_verb alc268_toshiba_verbs[] = { | 13211 | static const struct hda_verb alc268_toshiba_verbs[] = { |
13101 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 13212 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
13102 | { } /* end */ | 13213 | { } /* end */ |
13103 | }; | 13214 | }; |
13104 | 13215 | ||
13105 | /* Acer specific */ | 13216 | /* Acer specific */ |
13106 | /* bind volumes of both NID 0x02 and 0x03 */ | 13217 | /* bind volumes of both NID 0x02 and 0x03 */ |
13107 | static struct hda_bind_ctls alc268_acer_bind_master_vol = { | 13218 | static const struct hda_bind_ctls alc268_acer_bind_master_vol = { |
13108 | .ops = &snd_hda_bind_vol, | 13219 | .ops = &snd_hda_bind_vol, |
13109 | .values = { | 13220 | .values = { |
13110 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | 13221 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), |
@@ -13113,66 +13224,44 @@ static struct hda_bind_ctls alc268_acer_bind_master_vol = { | |||
13113 | }, | 13224 | }, |
13114 | }; | 13225 | }; |
13115 | 13226 | ||
13116 | /* mute/unmute internal speaker according to the hp jack and mute state */ | 13227 | static void alc268_acer_setup(struct hda_codec *codec) |
13117 | static void alc268_acer_automute(struct hda_codec *codec, int force) | ||
13118 | { | 13228 | { |
13119 | struct alc_spec *spec = codec->spec; | 13229 | struct alc_spec *spec = codec->spec; |
13120 | unsigned int mute; | ||
13121 | 13230 | ||
13122 | if (force || !spec->sense_updated) { | 13231 | spec->autocfg.hp_pins[0] = 0x14; |
13123 | spec->jack_present = snd_hda_jack_detect(codec, 0x14); | 13232 | spec->autocfg.speaker_pins[0] = 0x15; |
13124 | spec->sense_updated = 1; | 13233 | spec->automute = 1; |
13125 | } | 13234 | spec->automute_mode = ALC_AUTOMUTE_AMP; |
13126 | if (spec->jack_present) | ||
13127 | mute = HDA_AMP_MUTE; /* mute internal speaker */ | ||
13128 | else /* unmute internal speaker if necessary */ | ||
13129 | mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); | ||
13130 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
13131 | HDA_AMP_MUTE, mute); | ||
13132 | } | 13235 | } |
13133 | 13236 | ||
13237 | #define alc268_acer_master_sw_get alc262_hp_master_sw_get | ||
13238 | #define alc268_acer_master_sw_put alc262_hp_master_sw_put | ||
13134 | 13239 | ||
13135 | /* bind hp and internal speaker mute (with plug check) */ | 13240 | static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { |
13136 | static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, | ||
13137 | struct snd_ctl_elem_value *ucontrol) | ||
13138 | { | ||
13139 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
13140 | long *valp = ucontrol->value.integer.value; | ||
13141 | int change; | ||
13142 | |||
13143 | change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); | ||
13144 | if (change) | ||
13145 | alc268_acer_automute(codec, 0); | ||
13146 | return change; | ||
13147 | } | ||
13148 | |||
13149 | static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { | ||
13150 | /* output mixer control */ | 13241 | /* output mixer control */ |
13151 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | 13242 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), |
13152 | { | 13243 | { |
13153 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 13244 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
13154 | .name = "Master Playback Switch", | 13245 | .name = "Master Playback Switch", |
13155 | .subdevice = HDA_SUBDEV_AMP_FLAG, | 13246 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x15, |
13156 | .info = snd_hda_mixer_amp_switch_info, | 13247 | .info = snd_ctl_boolean_mono_info, |
13157 | .get = snd_hda_mixer_amp_switch_get, | 13248 | .get = alc268_acer_master_sw_get, |
13158 | .put = alc268_acer_master_sw_put, | 13249 | .put = alc268_acer_master_sw_put, |
13159 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
13160 | }, | 13250 | }, |
13161 | HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), | 13251 | HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), |
13162 | { } | 13252 | { } |
13163 | }; | 13253 | }; |
13164 | 13254 | ||
13165 | static struct snd_kcontrol_new alc268_acer_mixer[] = { | 13255 | static const struct snd_kcontrol_new alc268_acer_mixer[] = { |
13166 | /* output mixer control */ | 13256 | /* output mixer control */ |
13167 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | 13257 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), |
13168 | { | 13258 | { |
13169 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 13259 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
13170 | .name = "Master Playback Switch", | 13260 | .name = "Master Playback Switch", |
13171 | .subdevice = HDA_SUBDEV_AMP_FLAG, | 13261 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, |
13172 | .info = snd_hda_mixer_amp_switch_info, | 13262 | .info = snd_ctl_boolean_mono_info, |
13173 | .get = snd_hda_mixer_amp_switch_get, | 13263 | .get = alc268_acer_master_sw_get, |
13174 | .put = alc268_acer_master_sw_put, | 13264 | .put = alc268_acer_master_sw_put, |
13175 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
13176 | }, | 13265 | }, |
13177 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | 13266 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), |
13178 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), | 13267 | HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), |
@@ -13180,24 +13269,23 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = { | |||
13180 | { } | 13269 | { } |
13181 | }; | 13270 | }; |
13182 | 13271 | ||
13183 | static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { | 13272 | static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { |
13184 | /* output mixer control */ | 13273 | /* output mixer control */ |
13185 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | 13274 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), |
13186 | { | 13275 | { |
13187 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 13276 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
13188 | .name = "Master Playback Switch", | 13277 | .name = "Master Playback Switch", |
13189 | .subdevice = HDA_SUBDEV_AMP_FLAG, | 13278 | .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, |
13190 | .info = snd_hda_mixer_amp_switch_info, | 13279 | .info = snd_ctl_boolean_mono_info, |
13191 | .get = snd_hda_mixer_amp_switch_get, | 13280 | .get = alc268_acer_master_sw_get, |
13192 | .put = alc268_acer_master_sw_put, | 13281 | .put = alc268_acer_master_sw_put, |
13193 | .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | ||
13194 | }, | 13282 | }, |
13195 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | 13283 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), |
13196 | HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), | 13284 | HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), |
13197 | { } | 13285 | { } |
13198 | }; | 13286 | }; |
13199 | 13287 | ||
13200 | static struct hda_verb alc268_acer_aspire_one_verbs[] = { | 13288 | static const struct hda_verb alc268_acer_aspire_one_verbs[] = { |
13201 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 13289 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
13202 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 13290 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
13203 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 13291 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
@@ -13207,7 +13295,7 @@ static struct hda_verb alc268_acer_aspire_one_verbs[] = { | |||
13207 | { } | 13295 | { } |
13208 | }; | 13296 | }; |
13209 | 13297 | ||
13210 | static struct hda_verb alc268_acer_verbs[] = { | 13298 | static const struct hda_verb alc268_acer_verbs[] = { |
13211 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ | 13299 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ |
13212 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 13300 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
13213 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 13301 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -13219,53 +13307,16 @@ static struct hda_verb alc268_acer_verbs[] = { | |||
13219 | }; | 13307 | }; |
13220 | 13308 | ||
13221 | /* unsolicited event for HP jack sensing */ | 13309 | /* unsolicited event for HP jack sensing */ |
13222 | #define alc268_toshiba_unsol_event alc262_hippo_unsol_event | ||
13223 | #define alc268_toshiba_setup alc262_hippo_setup | 13310 | #define alc268_toshiba_setup alc262_hippo_setup |
13224 | #define alc268_toshiba_automute alc262_hippo_automute | ||
13225 | |||
13226 | static void alc268_acer_unsol_event(struct hda_codec *codec, | ||
13227 | unsigned int res) | ||
13228 | { | ||
13229 | if ((res >> 26) != ALC880_HP_EVENT) | ||
13230 | return; | ||
13231 | alc268_acer_automute(codec, 1); | ||
13232 | } | ||
13233 | |||
13234 | static void alc268_acer_init_hook(struct hda_codec *codec) | ||
13235 | { | ||
13236 | alc268_acer_automute(codec, 1); | ||
13237 | } | ||
13238 | |||
13239 | /* toggle speaker-output according to the hp-jack state */ | ||
13240 | static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) | ||
13241 | { | ||
13242 | unsigned int present; | ||
13243 | unsigned char bits; | ||
13244 | |||
13245 | present = snd_hda_jack_detect(codec, 0x15); | ||
13246 | bits = present ? HDA_AMP_MUTE : 0; | ||
13247 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, | ||
13248 | HDA_AMP_MUTE, bits); | ||
13249 | snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, | ||
13250 | HDA_AMP_MUTE, bits); | ||
13251 | } | ||
13252 | |||
13253 | static void alc268_acer_lc_unsol_event(struct hda_codec *codec, | ||
13254 | unsigned int res) | ||
13255 | { | ||
13256 | switch (res >> 26) { | ||
13257 | case ALC880_HP_EVENT: | ||
13258 | alc268_aspire_one_speaker_automute(codec); | ||
13259 | break; | ||
13260 | case ALC880_MIC_EVENT: | ||
13261 | alc_mic_automute(codec); | ||
13262 | break; | ||
13263 | } | ||
13264 | } | ||
13265 | 13311 | ||
13266 | static void alc268_acer_lc_setup(struct hda_codec *codec) | 13312 | static void alc268_acer_lc_setup(struct hda_codec *codec) |
13267 | { | 13313 | { |
13268 | struct alc_spec *spec = codec->spec; | 13314 | struct alc_spec *spec = codec->spec; |
13315 | spec->autocfg.hp_pins[0] = 0x15; | ||
13316 | spec->autocfg.speaker_pins[0] = 0x14; | ||
13317 | spec->automute_mixer_nid[0] = 0x0f; | ||
13318 | spec->automute = 1; | ||
13319 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
13269 | spec->ext_mic.pin = 0x18; | 13320 | spec->ext_mic.pin = 0x18; |
13270 | spec->ext_mic.mux_idx = 0; | 13321 | spec->ext_mic.mux_idx = 0; |
13271 | spec->int_mic.pin = 0x12; | 13322 | spec->int_mic.pin = 0x12; |
@@ -13273,13 +13324,7 @@ static void alc268_acer_lc_setup(struct hda_codec *codec) | |||
13273 | spec->auto_mic = 1; | 13324 | spec->auto_mic = 1; |
13274 | } | 13325 | } |
13275 | 13326 | ||
13276 | static void alc268_acer_lc_init_hook(struct hda_codec *codec) | 13327 | static const struct snd_kcontrol_new alc268_dell_mixer[] = { |
13277 | { | ||
13278 | alc268_aspire_one_speaker_automute(codec); | ||
13279 | alc_mic_automute(codec); | ||
13280 | } | ||
13281 | |||
13282 | static struct snd_kcontrol_new alc268_dell_mixer[] = { | ||
13283 | /* output mixer control */ | 13328 | /* output mixer control */ |
13284 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 13329 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
13285 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 13330 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -13290,7 +13335,7 @@ static struct snd_kcontrol_new alc268_dell_mixer[] = { | |||
13290 | { } | 13335 | { } |
13291 | }; | 13336 | }; |
13292 | 13337 | ||
13293 | static struct hda_verb alc268_dell_verbs[] = { | 13338 | static const struct hda_verb alc268_dell_verbs[] = { |
13294 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 13339 | {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
13295 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 13340 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
13296 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 13341 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
@@ -13310,9 +13355,11 @@ static void alc268_dell_setup(struct hda_codec *codec) | |||
13310 | spec->int_mic.pin = 0x19; | 13355 | spec->int_mic.pin = 0x19; |
13311 | spec->int_mic.mux_idx = 1; | 13356 | spec->int_mic.mux_idx = 1; |
13312 | spec->auto_mic = 1; | 13357 | spec->auto_mic = 1; |
13358 | spec->automute = 1; | ||
13359 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
13313 | } | 13360 | } |
13314 | 13361 | ||
13315 | static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { | 13362 | static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { |
13316 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), | 13363 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), |
13317 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 13364 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
13318 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), | 13365 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), |
@@ -13324,7 +13371,7 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { | |||
13324 | { } | 13371 | { } |
13325 | }; | 13372 | }; |
13326 | 13373 | ||
13327 | static struct hda_verb alc267_quanta_il1_verbs[] = { | 13374 | static const struct hda_verb alc267_quanta_il1_verbs[] = { |
13328 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, | 13375 | {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, |
13329 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, | 13376 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, |
13330 | { } | 13377 | { } |
@@ -13340,12 +13387,14 @@ static void alc267_quanta_il1_setup(struct hda_codec *codec) | |||
13340 | spec->int_mic.pin = 0x19; | 13387 | spec->int_mic.pin = 0x19; |
13341 | spec->int_mic.mux_idx = 1; | 13388 | spec->int_mic.mux_idx = 1; |
13342 | spec->auto_mic = 1; | 13389 | spec->auto_mic = 1; |
13390 | spec->automute = 1; | ||
13391 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
13343 | } | 13392 | } |
13344 | 13393 | ||
13345 | /* | 13394 | /* |
13346 | * generic initialization of ADC, input mixers and output mixers | 13395 | * generic initialization of ADC, input mixers and output mixers |
13347 | */ | 13396 | */ |
13348 | static struct hda_verb alc268_base_init_verbs[] = { | 13397 | static const struct hda_verb alc268_base_init_verbs[] = { |
13349 | /* Unmute DAC0-1 and set vol = 0 */ | 13398 | /* Unmute DAC0-1 and set vol = 0 */ |
13350 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 13399 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
13351 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 13400 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
@@ -13393,7 +13442,7 @@ static struct hda_verb alc268_base_init_verbs[] = { | |||
13393 | /* | 13442 | /* |
13394 | * generic initialization of ADC, input mixers and output mixers | 13443 | * generic initialization of ADC, input mixers and output mixers |
13395 | */ | 13444 | */ |
13396 | static struct hda_verb alc268_volume_init_verbs[] = { | 13445 | static const struct hda_verb alc268_volume_init_verbs[] = { |
13397 | /* set output DAC */ | 13446 | /* set output DAC */ |
13398 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 13447 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
13399 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 13448 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
@@ -13419,20 +13468,20 @@ static struct hda_verb alc268_volume_init_verbs[] = { | |||
13419 | { } | 13468 | { } |
13420 | }; | 13469 | }; |
13421 | 13470 | ||
13422 | static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { | 13471 | static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { |
13423 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), | 13472 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), |
13424 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | 13473 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), |
13425 | { } /* end */ | 13474 | { } /* end */ |
13426 | }; | 13475 | }; |
13427 | 13476 | ||
13428 | static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { | 13477 | static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = { |
13429 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), | 13478 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), |
13430 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | 13479 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), |
13431 | _DEFINE_CAPSRC(1), | 13480 | _DEFINE_CAPSRC(1), |
13432 | { } /* end */ | 13481 | { } /* end */ |
13433 | }; | 13482 | }; |
13434 | 13483 | ||
13435 | static struct snd_kcontrol_new alc268_capture_mixer[] = { | 13484 | static const struct snd_kcontrol_new alc268_capture_mixer[] = { |
13436 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), | 13485 | HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), |
13437 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), | 13486 | HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), |
13438 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), | 13487 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), |
@@ -13441,7 +13490,7 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = { | |||
13441 | { } /* end */ | 13490 | { } /* end */ |
13442 | }; | 13491 | }; |
13443 | 13492 | ||
13444 | static struct hda_input_mux alc268_capture_source = { | 13493 | static const struct hda_input_mux alc268_capture_source = { |
13445 | .num_items = 4, | 13494 | .num_items = 4, |
13446 | .items = { | 13495 | .items = { |
13447 | { "Mic", 0x0 }, | 13496 | { "Mic", 0x0 }, |
@@ -13451,7 +13500,7 @@ static struct hda_input_mux alc268_capture_source = { | |||
13451 | }, | 13500 | }, |
13452 | }; | 13501 | }; |
13453 | 13502 | ||
13454 | static struct hda_input_mux alc268_acer_capture_source = { | 13503 | static const struct hda_input_mux alc268_acer_capture_source = { |
13455 | .num_items = 3, | 13504 | .num_items = 3, |
13456 | .items = { | 13505 | .items = { |
13457 | { "Mic", 0x0 }, | 13506 | { "Mic", 0x0 }, |
@@ -13460,7 +13509,7 @@ static struct hda_input_mux alc268_acer_capture_source = { | |||
13460 | }, | 13509 | }, |
13461 | }; | 13510 | }; |
13462 | 13511 | ||
13463 | static struct hda_input_mux alc268_acer_dmic_capture_source = { | 13512 | static const struct hda_input_mux alc268_acer_dmic_capture_source = { |
13464 | .num_items = 3, | 13513 | .num_items = 3, |
13465 | .items = { | 13514 | .items = { |
13466 | { "Mic", 0x0 }, | 13515 | { "Mic", 0x0 }, |
@@ -13470,7 +13519,7 @@ static struct hda_input_mux alc268_acer_dmic_capture_source = { | |||
13470 | }; | 13519 | }; |
13471 | 13520 | ||
13472 | #ifdef CONFIG_SND_DEBUG | 13521 | #ifdef CONFIG_SND_DEBUG |
13473 | static struct snd_kcontrol_new alc268_test_mixer[] = { | 13522 | static const struct snd_kcontrol_new alc268_test_mixer[] = { |
13474 | /* Volume widgets */ | 13523 | /* Volume widgets */ |
13475 | HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 13524 | HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
13476 | HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 13525 | HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
@@ -13549,7 +13598,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
13549 | HDA_OUTPUT)); | 13598 | HDA_OUTPUT)); |
13550 | if (err < 0) | 13599 | if (err < 0) |
13551 | return err; | 13600 | return err; |
13552 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; | 13601 | spec->private_dac_nids[spec->multiout.num_dacs++] = dac; |
13553 | } | 13602 | } |
13554 | 13603 | ||
13555 | if (nid != 0x16) | 13604 | if (nid != 0x16) |
@@ -13722,7 +13771,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) | |||
13722 | { | 13771 | { |
13723 | struct alc_spec *spec = codec->spec; | 13772 | struct alc_spec *spec = codec->spec; |
13724 | int err; | 13773 | int err; |
13725 | static hda_nid_t alc268_ignore[] = { 0 }; | 13774 | static const hda_nid_t alc268_ignore[] = { 0 }; |
13726 | 13775 | ||
13727 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 13776 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
13728 | alc268_ignore); | 13777 | alc268_ignore); |
@@ -13802,7 +13851,7 @@ static const char * const alc268_models[ALC268_MODEL_LAST] = { | |||
13802 | [ALC268_AUTO] = "auto", | 13851 | [ALC268_AUTO] = "auto", |
13803 | }; | 13852 | }; |
13804 | 13853 | ||
13805 | static struct snd_pci_quirk alc268_cfg_tbl[] = { | 13854 | static const struct snd_pci_quirk alc268_cfg_tbl[] = { |
13806 | SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), | 13855 | SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), |
13807 | SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), | 13856 | SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), |
13808 | SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), | 13857 | SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), |
@@ -13827,7 +13876,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { | |||
13827 | }; | 13876 | }; |
13828 | 13877 | ||
13829 | /* Toshiba laptops have no unique PCI SSID but only codec SSID */ | 13878 | /* Toshiba laptops have no unique PCI SSID but only codec SSID */ |
13830 | static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { | 13879 | static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { |
13831 | SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), | 13880 | SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), |
13832 | SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), | 13881 | SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), |
13833 | SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", | 13882 | SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", |
@@ -13835,7 +13884,7 @@ static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { | |||
13835 | {} | 13884 | {} |
13836 | }; | 13885 | }; |
13837 | 13886 | ||
13838 | static struct alc_config_preset alc268_presets[] = { | 13887 | static const struct alc_config_preset alc268_presets[] = { |
13839 | [ALC267_QUANTA_IL1] = { | 13888 | [ALC267_QUANTA_IL1] = { |
13840 | .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, | 13889 | .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, |
13841 | alc268_capture_nosrc_mixer }, | 13890 | alc268_capture_nosrc_mixer }, |
@@ -13881,9 +13930,9 @@ static struct alc_config_preset alc268_presets[] = { | |||
13881 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 13930 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
13882 | .channel_mode = alc268_modes, | 13931 | .channel_mode = alc268_modes, |
13883 | .input_mux = &alc268_capture_source, | 13932 | .input_mux = &alc268_capture_source, |
13884 | .unsol_event = alc268_toshiba_unsol_event, | 13933 | .unsol_event = alc_sku_unsol_event, |
13885 | .setup = alc268_toshiba_setup, | 13934 | .setup = alc268_toshiba_setup, |
13886 | .init_hook = alc268_toshiba_automute, | 13935 | .init_hook = alc_inithook, |
13887 | }, | 13936 | }, |
13888 | [ALC268_ACER] = { | 13937 | [ALC268_ACER] = { |
13889 | .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, | 13938 | .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, |
@@ -13899,8 +13948,9 @@ static struct alc_config_preset alc268_presets[] = { | |||
13899 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 13948 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
13900 | .channel_mode = alc268_modes, | 13949 | .channel_mode = alc268_modes, |
13901 | .input_mux = &alc268_acer_capture_source, | 13950 | .input_mux = &alc268_acer_capture_source, |
13902 | .unsol_event = alc268_acer_unsol_event, | 13951 | .unsol_event = alc_sku_unsol_event, |
13903 | .init_hook = alc268_acer_init_hook, | 13952 | .setup = alc268_acer_setup, |
13953 | .init_hook = alc_inithook, | ||
13904 | }, | 13954 | }, |
13905 | [ALC268_ACER_DMIC] = { | 13955 | [ALC268_ACER_DMIC] = { |
13906 | .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, | 13956 | .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, |
@@ -13916,8 +13966,9 @@ static struct alc_config_preset alc268_presets[] = { | |||
13916 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 13966 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
13917 | .channel_mode = alc268_modes, | 13967 | .channel_mode = alc268_modes, |
13918 | .input_mux = &alc268_acer_dmic_capture_source, | 13968 | .input_mux = &alc268_acer_dmic_capture_source, |
13919 | .unsol_event = alc268_acer_unsol_event, | 13969 | .unsol_event = alc_sku_unsol_event, |
13920 | .init_hook = alc268_acer_init_hook, | 13970 | .setup = alc268_acer_setup, |
13971 | .init_hook = alc_inithook, | ||
13921 | }, | 13972 | }, |
13922 | [ALC268_ACER_ASPIRE_ONE] = { | 13973 | [ALC268_ACER_ASPIRE_ONE] = { |
13923 | .mixers = { alc268_acer_aspire_one_mixer, | 13974 | .mixers = { alc268_acer_aspire_one_mixer, |
@@ -13933,9 +13984,9 @@ static struct alc_config_preset alc268_presets[] = { | |||
13933 | .hp_nid = 0x03, | 13984 | .hp_nid = 0x03, |
13934 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 13985 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
13935 | .channel_mode = alc268_modes, | 13986 | .channel_mode = alc268_modes, |
13936 | .unsol_event = alc268_acer_lc_unsol_event, | 13987 | .unsol_event = alc_sku_unsol_event, |
13937 | .setup = alc268_acer_lc_setup, | 13988 | .setup = alc268_acer_lc_setup, |
13938 | .init_hook = alc268_acer_lc_init_hook, | 13989 | .init_hook = alc_inithook, |
13939 | }, | 13990 | }, |
13940 | [ALC268_DELL] = { | 13991 | [ALC268_DELL] = { |
13941 | .mixers = { alc268_dell_mixer, alc268_beep_mixer, | 13992 | .mixers = { alc268_dell_mixer, alc268_beep_mixer, |
@@ -13969,8 +14020,9 @@ static struct alc_config_preset alc268_presets[] = { | |||
13969 | .num_channel_mode = ARRAY_SIZE(alc268_modes), | 14020 | .num_channel_mode = ARRAY_SIZE(alc268_modes), |
13970 | .channel_mode = alc268_modes, | 14021 | .channel_mode = alc268_modes, |
13971 | .input_mux = &alc268_capture_source, | 14022 | .input_mux = &alc268_capture_source, |
14023 | .unsol_event = alc_sku_unsol_event, | ||
13972 | .setup = alc268_toshiba_setup, | 14024 | .setup = alc268_toshiba_setup, |
13973 | .init_hook = alc268_toshiba_automute, | 14025 | .init_hook = alc_inithook, |
13974 | }, | 14026 | }, |
13975 | #ifdef CONFIG_SND_DEBUG | 14027 | #ifdef CONFIG_SND_DEBUG |
13976 | [ALC268_TEST] = { | 14028 | [ALC268_TEST] = { |
@@ -14092,6 +14144,7 @@ static int patch_alc268(struct hda_codec *codec) | |||
14092 | codec->patch_ops = alc_patch_ops; | 14144 | codec->patch_ops = alc_patch_ops; |
14093 | if (board_config == ALC268_AUTO) | 14145 | if (board_config == ALC268_AUTO) |
14094 | spec->init_hook = alc268_auto_init; | 14146 | spec->init_hook = alc268_auto_init; |
14147 | spec->shutup = alc_eapd_shutup; | ||
14095 | 14148 | ||
14096 | alc_init_jacks(codec); | 14149 | alc_init_jacks(codec); |
14097 | 14150 | ||
@@ -14105,32 +14158,32 @@ static int patch_alc268(struct hda_codec *codec) | |||
14105 | 14158 | ||
14106 | #define alc269_dac_nids alc260_dac_nids | 14159 | #define alc269_dac_nids alc260_dac_nids |
14107 | 14160 | ||
14108 | static hda_nid_t alc269_adc_nids[1] = { | 14161 | static const hda_nid_t alc269_adc_nids[1] = { |
14109 | /* ADC1 */ | 14162 | /* ADC1 */ |
14110 | 0x08, | 14163 | 0x08, |
14111 | }; | 14164 | }; |
14112 | 14165 | ||
14113 | static hda_nid_t alc269_capsrc_nids[1] = { | 14166 | static const hda_nid_t alc269_capsrc_nids[1] = { |
14114 | 0x23, | 14167 | 0x23, |
14115 | }; | 14168 | }; |
14116 | 14169 | ||
14117 | static hda_nid_t alc269vb_adc_nids[1] = { | 14170 | static const hda_nid_t alc269vb_adc_nids[1] = { |
14118 | /* ADC1 */ | 14171 | /* ADC1 */ |
14119 | 0x09, | 14172 | 0x09, |
14120 | }; | 14173 | }; |
14121 | 14174 | ||
14122 | static hda_nid_t alc269vb_capsrc_nids[1] = { | 14175 | static const hda_nid_t alc269vb_capsrc_nids[1] = { |
14123 | 0x22, | 14176 | 0x22, |
14124 | }; | 14177 | }; |
14125 | 14178 | ||
14126 | static hda_nid_t alc269_adc_candidates[] = { | 14179 | static const hda_nid_t alc269_adc_candidates[] = { |
14127 | 0x08, 0x09, 0x07, 0x11, | 14180 | 0x08, 0x09, 0x07, 0x11, |
14128 | }; | 14181 | }; |
14129 | 14182 | ||
14130 | #define alc269_modes alc260_modes | 14183 | #define alc269_modes alc260_modes |
14131 | #define alc269_capture_source alc880_lg_lw_capture_source | 14184 | #define alc269_capture_source alc880_lg_lw_capture_source |
14132 | 14185 | ||
14133 | static struct snd_kcontrol_new alc269_base_mixer[] = { | 14186 | static const struct snd_kcontrol_new alc269_base_mixer[] = { |
14134 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 14187 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
14135 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 14188 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
14136 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), | 14189 | HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), |
@@ -14146,7 +14199,7 @@ static struct snd_kcontrol_new alc269_base_mixer[] = { | |||
14146 | { } /* end */ | 14199 | { } /* end */ |
14147 | }; | 14200 | }; |
14148 | 14201 | ||
14149 | static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { | 14202 | static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { |
14150 | /* output mixer control */ | 14203 | /* output mixer control */ |
14151 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | 14204 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), |
14152 | { | 14205 | { |
@@ -14167,7 +14220,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { | |||
14167 | { } | 14220 | { } |
14168 | }; | 14221 | }; |
14169 | 14222 | ||
14170 | static struct snd_kcontrol_new alc269_lifebook_mixer[] = { | 14223 | static const struct snd_kcontrol_new alc269_lifebook_mixer[] = { |
14171 | /* output mixer control */ | 14224 | /* output mixer control */ |
14172 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), | 14225 | HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), |
14173 | { | 14226 | { |
@@ -14191,7 +14244,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = { | |||
14191 | { } | 14244 | { } |
14192 | }; | 14245 | }; |
14193 | 14246 | ||
14194 | static struct snd_kcontrol_new alc269_laptop_mixer[] = { | 14247 | static const struct snd_kcontrol_new alc269_laptop_mixer[] = { |
14195 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 14248 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
14196 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 14249 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
14197 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), | 14250 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), |
@@ -14199,7 +14252,7 @@ static struct snd_kcontrol_new alc269_laptop_mixer[] = { | |||
14199 | { } /* end */ | 14252 | { } /* end */ |
14200 | }; | 14253 | }; |
14201 | 14254 | ||
14202 | static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { | 14255 | static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = { |
14203 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 14256 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
14204 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 14257 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
14205 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | 14258 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), |
@@ -14207,14 +14260,14 @@ static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { | |||
14207 | { } /* end */ | 14260 | { } /* end */ |
14208 | }; | 14261 | }; |
14209 | 14262 | ||
14210 | static struct snd_kcontrol_new alc269_asus_mixer[] = { | 14263 | static const struct snd_kcontrol_new alc269_asus_mixer[] = { |
14211 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 14264 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
14212 | HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), | 14265 | HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), |
14213 | { } /* end */ | 14266 | { } /* end */ |
14214 | }; | 14267 | }; |
14215 | 14268 | ||
14216 | /* capture mixer elements */ | 14269 | /* capture mixer elements */ |
14217 | static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { | 14270 | static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { |
14218 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 14271 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
14219 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 14272 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
14220 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | 14273 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), |
@@ -14222,14 +14275,14 @@ static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { | |||
14222 | { } /* end */ | 14275 | { } /* end */ |
14223 | }; | 14276 | }; |
14224 | 14277 | ||
14225 | static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { | 14278 | static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { |
14226 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 14279 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
14227 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 14280 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
14228 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | 14281 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), |
14229 | { } /* end */ | 14282 | { } /* end */ |
14230 | }; | 14283 | }; |
14231 | 14284 | ||
14232 | static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { | 14285 | static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { |
14233 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | 14286 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), |
14234 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | 14287 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), |
14235 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | 14288 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), |
@@ -14237,7 +14290,7 @@ static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { | |||
14237 | { } /* end */ | 14290 | { } /* end */ |
14238 | }; | 14291 | }; |
14239 | 14292 | ||
14240 | static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { | 14293 | static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { |
14241 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | 14294 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), |
14242 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | 14295 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), |
14243 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), | 14296 | HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), |
@@ -14247,7 +14300,7 @@ static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { | |||
14247 | /* FSC amilo */ | 14300 | /* FSC amilo */ |
14248 | #define alc269_fujitsu_mixer alc269_laptop_mixer | 14301 | #define alc269_fujitsu_mixer alc269_laptop_mixer |
14249 | 14302 | ||
14250 | static struct hda_verb alc269_quanta_fl1_verbs[] = { | 14303 | static const struct hda_verb alc269_quanta_fl1_verbs[] = { |
14251 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | 14304 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, |
14252 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 14305 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
14253 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 14306 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -14257,7 +14310,7 @@ static struct hda_verb alc269_quanta_fl1_verbs[] = { | |||
14257 | { } | 14310 | { } |
14258 | }; | 14311 | }; |
14259 | 14312 | ||
14260 | static struct hda_verb alc269_lifebook_verbs[] = { | 14313 | static const struct hda_verb alc269_lifebook_verbs[] = { |
14261 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | 14314 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, |
14262 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, | 14315 | {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, |
14263 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 14316 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
@@ -14274,15 +14327,7 @@ static struct hda_verb alc269_lifebook_verbs[] = { | |||
14274 | /* toggle speaker-output according to the hp-jack state */ | 14327 | /* toggle speaker-output according to the hp-jack state */ |
14275 | static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) | 14328 | static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) |
14276 | { | 14329 | { |
14277 | unsigned int present; | 14330 | alc_hp_automute(codec); |
14278 | unsigned char bits; | ||
14279 | |||
14280 | present = snd_hda_jack_detect(codec, 0x15); | ||
14281 | bits = present ? HDA_AMP_MUTE : 0; | ||
14282 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | ||
14283 | HDA_AMP_MUTE, bits); | ||
14284 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | ||
14285 | HDA_AMP_MUTE, bits); | ||
14286 | 14331 | ||
14287 | snd_hda_codec_write(codec, 0x20, 0, | 14332 | snd_hda_codec_write(codec, 0x20, 0, |
14288 | AC_VERB_SET_COEF_INDEX, 0x0c); | 14333 | AC_VERB_SET_COEF_INDEX, 0x0c); |
@@ -14295,34 +14340,8 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) | |||
14295 | AC_VERB_SET_PROC_COEF, 0x480); | 14340 | AC_VERB_SET_PROC_COEF, 0x480); |
14296 | } | 14341 | } |
14297 | 14342 | ||
14298 | /* toggle speaker-output according to the hp-jacks state */ | 14343 | #define alc269_lifebook_speaker_automute \ |
14299 | static void alc269_lifebook_speaker_automute(struct hda_codec *codec) | 14344 | alc269_quanta_fl1_speaker_automute |
14300 | { | ||
14301 | unsigned int present; | ||
14302 | unsigned char bits; | ||
14303 | |||
14304 | /* Check laptop headphone socket */ | ||
14305 | present = snd_hda_jack_detect(codec, 0x15); | ||
14306 | |||
14307 | /* Check port replicator headphone socket */ | ||
14308 | present |= snd_hda_jack_detect(codec, 0x1a); | ||
14309 | |||
14310 | bits = present ? HDA_AMP_MUTE : 0; | ||
14311 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | ||
14312 | HDA_AMP_MUTE, bits); | ||
14313 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | ||
14314 | HDA_AMP_MUTE, bits); | ||
14315 | |||
14316 | snd_hda_codec_write(codec, 0x20, 0, | ||
14317 | AC_VERB_SET_COEF_INDEX, 0x0c); | ||
14318 | snd_hda_codec_write(codec, 0x20, 0, | ||
14319 | AC_VERB_SET_PROC_COEF, 0x680); | ||
14320 | |||
14321 | snd_hda_codec_write(codec, 0x20, 0, | ||
14322 | AC_VERB_SET_COEF_INDEX, 0x0c); | ||
14323 | snd_hda_codec_write(codec, 0x20, 0, | ||
14324 | AC_VERB_SET_PROC_COEF, 0x480); | ||
14325 | } | ||
14326 | 14345 | ||
14327 | static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) | 14346 | static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) |
14328 | { | 14347 | { |
@@ -14371,6 +14390,9 @@ static void alc269_quanta_fl1_setup(struct hda_codec *codec) | |||
14371 | struct alc_spec *spec = codec->spec; | 14390 | struct alc_spec *spec = codec->spec; |
14372 | spec->autocfg.hp_pins[0] = 0x15; | 14391 | spec->autocfg.hp_pins[0] = 0x15; |
14373 | spec->autocfg.speaker_pins[0] = 0x14; | 14392 | spec->autocfg.speaker_pins[0] = 0x14; |
14393 | spec->automute_mixer_nid[0] = 0x0c; | ||
14394 | spec->automute = 1; | ||
14395 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
14374 | spec->ext_mic.pin = 0x18; | 14396 | spec->ext_mic.pin = 0x18; |
14375 | spec->ext_mic.mux_idx = 0; | 14397 | spec->ext_mic.mux_idx = 0; |
14376 | spec->int_mic.pin = 0x19; | 14398 | spec->int_mic.pin = 0x19; |
@@ -14384,13 +14406,24 @@ static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) | |||
14384 | alc_mic_automute(codec); | 14406 | alc_mic_automute(codec); |
14385 | } | 14407 | } |
14386 | 14408 | ||
14409 | static void alc269_lifebook_setup(struct hda_codec *codec) | ||
14410 | { | ||
14411 | struct alc_spec *spec = codec->spec; | ||
14412 | spec->autocfg.hp_pins[0] = 0x15; | ||
14413 | spec->autocfg.hp_pins[1] = 0x1a; | ||
14414 | spec->autocfg.speaker_pins[0] = 0x14; | ||
14415 | spec->automute_mixer_nid[0] = 0x0c; | ||
14416 | spec->automute = 1; | ||
14417 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
14418 | } | ||
14419 | |||
14387 | static void alc269_lifebook_init_hook(struct hda_codec *codec) | 14420 | static void alc269_lifebook_init_hook(struct hda_codec *codec) |
14388 | { | 14421 | { |
14389 | alc269_lifebook_speaker_automute(codec); | 14422 | alc269_lifebook_speaker_automute(codec); |
14390 | alc269_lifebook_mic_autoswitch(codec); | 14423 | alc269_lifebook_mic_autoswitch(codec); |
14391 | } | 14424 | } |
14392 | 14425 | ||
14393 | static struct hda_verb alc269_laptop_dmic_init_verbs[] = { | 14426 | static const struct hda_verb alc269_laptop_dmic_init_verbs[] = { |
14394 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | 14427 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, |
14395 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, | 14428 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, |
14396 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | 14429 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, |
@@ -14401,7 +14434,7 @@ static struct hda_verb alc269_laptop_dmic_init_verbs[] = { | |||
14401 | {} | 14434 | {} |
14402 | }; | 14435 | }; |
14403 | 14436 | ||
14404 | static struct hda_verb alc269_laptop_amic_init_verbs[] = { | 14437 | static const struct hda_verb alc269_laptop_amic_init_verbs[] = { |
14405 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, | 14438 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, |
14406 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, | 14439 | {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, |
14407 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | 14440 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, |
@@ -14411,7 +14444,7 @@ static struct hda_verb alc269_laptop_amic_init_verbs[] = { | |||
14411 | {} | 14444 | {} |
14412 | }; | 14445 | }; |
14413 | 14446 | ||
14414 | static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { | 14447 | static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { |
14415 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, | 14448 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, |
14416 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, | 14449 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, |
14417 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | 14450 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, |
@@ -14422,7 +14455,7 @@ static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { | |||
14422 | {} | 14455 | {} |
14423 | }; | 14456 | }; |
14424 | 14457 | ||
14425 | static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { | 14458 | static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = { |
14426 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, | 14459 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, |
14427 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, | 14460 | {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, |
14428 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, | 14461 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, |
@@ -14433,7 +14466,7 @@ static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { | |||
14433 | {} | 14466 | {} |
14434 | }; | 14467 | }; |
14435 | 14468 | ||
14436 | static struct hda_verb alc271_acer_dmic_verbs[] = { | 14469 | static const struct hda_verb alc271_acer_dmic_verbs[] = { |
14437 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, | 14470 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, |
14438 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, | 14471 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, |
14439 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 14472 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
@@ -14447,42 +14480,14 @@ static struct hda_verb alc271_acer_dmic_verbs[] = { | |||
14447 | { } | 14480 | { } |
14448 | }; | 14481 | }; |
14449 | 14482 | ||
14450 | /* toggle speaker-output according to the hp-jack state */ | ||
14451 | static void alc269_speaker_automute(struct hda_codec *codec) | ||
14452 | { | ||
14453 | struct alc_spec *spec = codec->spec; | ||
14454 | unsigned int nid = spec->autocfg.hp_pins[0]; | ||
14455 | unsigned int present; | ||
14456 | unsigned char bits; | ||
14457 | |||
14458 | present = snd_hda_jack_detect(codec, nid); | ||
14459 | bits = present ? HDA_AMP_MUTE : 0; | ||
14460 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | ||
14461 | HDA_AMP_MUTE, bits); | ||
14462 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | ||
14463 | HDA_AMP_MUTE, bits); | ||
14464 | snd_hda_input_jack_report(codec, nid); | ||
14465 | } | ||
14466 | |||
14467 | /* unsolicited event for HP jack sensing */ | ||
14468 | static void alc269_laptop_unsol_event(struct hda_codec *codec, | ||
14469 | unsigned int res) | ||
14470 | { | ||
14471 | switch (res >> 26) { | ||
14472 | case ALC880_HP_EVENT: | ||
14473 | alc269_speaker_automute(codec); | ||
14474 | break; | ||
14475 | case ALC880_MIC_EVENT: | ||
14476 | alc_mic_automute(codec); | ||
14477 | break; | ||
14478 | } | ||
14479 | } | ||
14480 | |||
14481 | static void alc269_laptop_amic_setup(struct hda_codec *codec) | 14483 | static void alc269_laptop_amic_setup(struct hda_codec *codec) |
14482 | { | 14484 | { |
14483 | struct alc_spec *spec = codec->spec; | 14485 | struct alc_spec *spec = codec->spec; |
14484 | spec->autocfg.hp_pins[0] = 0x15; | 14486 | spec->autocfg.hp_pins[0] = 0x15; |
14485 | spec->autocfg.speaker_pins[0] = 0x14; | 14487 | spec->autocfg.speaker_pins[0] = 0x14; |
14488 | spec->automute_mixer_nid[0] = 0x0c; | ||
14489 | spec->automute = 1; | ||
14490 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
14486 | spec->ext_mic.pin = 0x18; | 14491 | spec->ext_mic.pin = 0x18; |
14487 | spec->ext_mic.mux_idx = 0; | 14492 | spec->ext_mic.mux_idx = 0; |
14488 | spec->int_mic.pin = 0x19; | 14493 | spec->int_mic.pin = 0x19; |
@@ -14495,6 +14500,9 @@ static void alc269_laptop_dmic_setup(struct hda_codec *codec) | |||
14495 | struct alc_spec *spec = codec->spec; | 14500 | struct alc_spec *spec = codec->spec; |
14496 | spec->autocfg.hp_pins[0] = 0x15; | 14501 | spec->autocfg.hp_pins[0] = 0x15; |
14497 | spec->autocfg.speaker_pins[0] = 0x14; | 14502 | spec->autocfg.speaker_pins[0] = 0x14; |
14503 | spec->automute_mixer_nid[0] = 0x0c; | ||
14504 | spec->automute = 1; | ||
14505 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
14498 | spec->ext_mic.pin = 0x18; | 14506 | spec->ext_mic.pin = 0x18; |
14499 | spec->ext_mic.mux_idx = 0; | 14507 | spec->ext_mic.mux_idx = 0; |
14500 | spec->int_mic.pin = 0x12; | 14508 | spec->int_mic.pin = 0x12; |
@@ -14507,6 +14515,9 @@ static void alc269vb_laptop_amic_setup(struct hda_codec *codec) | |||
14507 | struct alc_spec *spec = codec->spec; | 14515 | struct alc_spec *spec = codec->spec; |
14508 | spec->autocfg.hp_pins[0] = 0x21; | 14516 | spec->autocfg.hp_pins[0] = 0x21; |
14509 | spec->autocfg.speaker_pins[0] = 0x14; | 14517 | spec->autocfg.speaker_pins[0] = 0x14; |
14518 | spec->automute_mixer_nid[0] = 0x0c; | ||
14519 | spec->automute = 1; | ||
14520 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
14510 | spec->ext_mic.pin = 0x18; | 14521 | spec->ext_mic.pin = 0x18; |
14511 | spec->ext_mic.mux_idx = 0; | 14522 | spec->ext_mic.mux_idx = 0; |
14512 | spec->int_mic.pin = 0x19; | 14523 | spec->int_mic.pin = 0x19; |
@@ -14519,6 +14530,9 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | |||
14519 | struct alc_spec *spec = codec->spec; | 14530 | struct alc_spec *spec = codec->spec; |
14520 | spec->autocfg.hp_pins[0] = 0x21; | 14531 | spec->autocfg.hp_pins[0] = 0x21; |
14521 | spec->autocfg.speaker_pins[0] = 0x14; | 14532 | spec->autocfg.speaker_pins[0] = 0x14; |
14533 | spec->automute_mixer_nid[0] = 0x0c; | ||
14534 | spec->automute = 1; | ||
14535 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
14522 | spec->ext_mic.pin = 0x18; | 14536 | spec->ext_mic.pin = 0x18; |
14523 | spec->ext_mic.mux_idx = 0; | 14537 | spec->ext_mic.mux_idx = 0; |
14524 | spec->int_mic.pin = 0x12; | 14538 | spec->int_mic.pin = 0x12; |
@@ -14526,16 +14540,10 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) | |||
14526 | spec->auto_mic = 1; | 14540 | spec->auto_mic = 1; |
14527 | } | 14541 | } |
14528 | 14542 | ||
14529 | static void alc269_laptop_inithook(struct hda_codec *codec) | ||
14530 | { | ||
14531 | alc269_speaker_automute(codec); | ||
14532 | alc_mic_automute(codec); | ||
14533 | } | ||
14534 | |||
14535 | /* | 14543 | /* |
14536 | * generic initialization of ADC, input mixers and output mixers | 14544 | * generic initialization of ADC, input mixers and output mixers |
14537 | */ | 14545 | */ |
14538 | static struct hda_verb alc269_init_verbs[] = { | 14546 | static const struct hda_verb alc269_init_verbs[] = { |
14539 | /* | 14547 | /* |
14540 | * Unmute ADC0 and set the default input to mic-in | 14548 | * Unmute ADC0 and set the default input to mic-in |
14541 | */ | 14549 | */ |
@@ -14578,7 +14586,7 @@ static struct hda_verb alc269_init_verbs[] = { | |||
14578 | { } | 14586 | { } |
14579 | }; | 14587 | }; |
14580 | 14588 | ||
14581 | static struct hda_verb alc269vb_init_verbs[] = { | 14589 | static const struct hda_verb alc269vb_init_verbs[] = { |
14582 | /* | 14590 | /* |
14583 | * Unmute ADC0 and set the default input to mic-in | 14591 | * Unmute ADC0 and set the default input to mic-in |
14584 | */ | 14592 | */ |
@@ -14636,7 +14644,7 @@ static struct hda_verb alc269vb_init_verbs[] = { | |||
14636 | #define alc269_pcm_digital_playback alc880_pcm_digital_playback | 14644 | #define alc269_pcm_digital_playback alc880_pcm_digital_playback |
14637 | #define alc269_pcm_digital_capture alc880_pcm_digital_capture | 14645 | #define alc269_pcm_digital_capture alc880_pcm_digital_capture |
14638 | 14646 | ||
14639 | static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { | 14647 | static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { |
14640 | .substreams = 1, | 14648 | .substreams = 1, |
14641 | .channels_min = 2, | 14649 | .channels_min = 2, |
14642 | .channels_max = 8, | 14650 | .channels_max = 8, |
@@ -14649,7 +14657,7 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { | |||
14649 | }, | 14657 | }, |
14650 | }; | 14658 | }; |
14651 | 14659 | ||
14652 | static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { | 14660 | static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { |
14653 | .substreams = 1, | 14661 | .substreams = 1, |
14654 | .channels_min = 2, | 14662 | .channels_min = 2, |
14655 | .channels_max = 2, | 14663 | .channels_max = 2, |
@@ -14733,7 +14741,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) | |||
14733 | { | 14741 | { |
14734 | struct alc_spec *spec = codec->spec; | 14742 | struct alc_spec *spec = codec->spec; |
14735 | int err; | 14743 | int err; |
14736 | static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; | 14744 | static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; |
14737 | 14745 | ||
14738 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 14746 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
14739 | alc269_ignore); | 14747 | alc269_ignore); |
@@ -14803,7 +14811,6 @@ static void alc269_auto_init(struct hda_codec *codec) | |||
14803 | alc_inithook(codec); | 14811 | alc_inithook(codec); |
14804 | } | 14812 | } |
14805 | 14813 | ||
14806 | #ifdef SND_HDA_NEEDS_RESUME | ||
14807 | static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) | 14814 | static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) |
14808 | { | 14815 | { |
14809 | int val = alc_read_coef_idx(codec, 0x04); | 14816 | int val = alc_read_coef_idx(codec, 0x04); |
@@ -14814,25 +14821,17 @@ static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) | |||
14814 | alc_write_coef_idx(codec, 0x04, val); | 14821 | alc_write_coef_idx(codec, 0x04, val); |
14815 | } | 14822 | } |
14816 | 14823 | ||
14817 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 14824 | static void alc269_shutup(struct hda_codec *codec) |
14818 | static int alc269_suspend(struct hda_codec *codec, pm_message_t state) | ||
14819 | { | 14825 | { |
14820 | struct alc_spec *spec = codec->spec; | ||
14821 | |||
14822 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) | 14826 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) |
14823 | alc269_toggle_power_output(codec, 0); | 14827 | alc269_toggle_power_output(codec, 0); |
14824 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | 14828 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { |
14825 | alc269_toggle_power_output(codec, 0); | 14829 | alc269_toggle_power_output(codec, 0); |
14826 | msleep(150); | 14830 | msleep(150); |
14827 | } | 14831 | } |
14828 | |||
14829 | alc_shutup(codec); | ||
14830 | if (spec && spec->power_hook) | ||
14831 | spec->power_hook(codec); | ||
14832 | return 0; | ||
14833 | } | 14832 | } |
14834 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | ||
14835 | 14833 | ||
14834 | #ifdef SND_HDA_NEEDS_RESUME | ||
14836 | static int alc269_resume(struct hda_codec *codec) | 14835 | static int alc269_resume(struct hda_codec *codec) |
14837 | { | 14836 | { |
14838 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { | 14837 | if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { |
@@ -14868,6 +14867,23 @@ static void alc269_fixup_hweq(struct hda_codec *codec, | |||
14868 | alc_write_coef_idx(codec, 0x1e, coef | 0x80); | 14867 | alc_write_coef_idx(codec, 0x1e, coef | 0x80); |
14869 | } | 14868 | } |
14870 | 14869 | ||
14870 | static void alc271_fixup_dmic(struct hda_codec *codec, | ||
14871 | const struct alc_fixup *fix, int action) | ||
14872 | { | ||
14873 | static const struct hda_verb verbs[] = { | ||
14874 | {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, | ||
14875 | {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, | ||
14876 | {} | ||
14877 | }; | ||
14878 | unsigned int cfg; | ||
14879 | |||
14880 | if (strcmp(codec->chip_name, "ALC271X")) | ||
14881 | return; | ||
14882 | cfg = snd_hda_codec_get_pincfg(codec, 0x12); | ||
14883 | if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) | ||
14884 | snd_hda_sequence_write(codec, verbs); | ||
14885 | } | ||
14886 | |||
14871 | enum { | 14887 | enum { |
14872 | ALC269_FIXUP_SONY_VAIO, | 14888 | ALC269_FIXUP_SONY_VAIO, |
14873 | ALC275_FIXUP_SONY_VAIO_GPIO2, | 14889 | ALC275_FIXUP_SONY_VAIO_GPIO2, |
@@ -14876,6 +14892,7 @@ enum { | |||
14876 | ALC269_FIXUP_ASUS_G73JW, | 14892 | ALC269_FIXUP_ASUS_G73JW, |
14877 | ALC269_FIXUP_LENOVO_EAPD, | 14893 | ALC269_FIXUP_LENOVO_EAPD, |
14878 | ALC275_FIXUP_SONY_HWEQ, | 14894 | ALC275_FIXUP_SONY_HWEQ, |
14895 | ALC271_FIXUP_DMIC, | ||
14879 | }; | 14896 | }; |
14880 | 14897 | ||
14881 | static const struct alc_fixup alc269_fixups[] = { | 14898 | static const struct alc_fixup alc269_fixups[] = { |
@@ -14929,15 +14946,20 @@ static const struct alc_fixup alc269_fixups[] = { | |||
14929 | .v.func = alc269_fixup_hweq, | 14946 | .v.func = alc269_fixup_hweq, |
14930 | .chained = true, | 14947 | .chained = true, |
14931 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 | 14948 | .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 |
14932 | } | 14949 | }, |
14950 | [ALC271_FIXUP_DMIC] = { | ||
14951 | .type = ALC_FIXUP_FUNC, | ||
14952 | .v.func = alc271_fixup_dmic, | ||
14953 | }, | ||
14933 | }; | 14954 | }; |
14934 | 14955 | ||
14935 | static struct snd_pci_quirk alc269_fixup_tbl[] = { | 14956 | static const struct snd_pci_quirk alc269_fixup_tbl[] = { |
14936 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), | 14957 | SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), |
14937 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 14958 | SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
14938 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), | 14959 | SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), |
14939 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), | 14960 | SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), |
14940 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), | 14961 | SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), |
14962 | SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), | ||
14941 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), | 14963 | SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), |
14942 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), | 14964 | SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), |
14943 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), | 14965 | SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), |
@@ -14962,7 +14984,7 @@ static const char * const alc269_models[ALC269_MODEL_LAST] = { | |||
14962 | [ALC269_AUTO] = "auto", | 14984 | [ALC269_AUTO] = "auto", |
14963 | }; | 14985 | }; |
14964 | 14986 | ||
14965 | static struct snd_pci_quirk alc269_cfg_tbl[] = { | 14987 | static const struct snd_pci_quirk alc269_cfg_tbl[] = { |
14966 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), | 14988 | SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), |
14967 | SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), | 14989 | SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), |
14968 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", | 14990 | SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", |
@@ -15020,7 +15042,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { | |||
15020 | {} | 15042 | {} |
15021 | }; | 15043 | }; |
15022 | 15044 | ||
15023 | static struct alc_config_preset alc269_presets[] = { | 15045 | static const struct alc_config_preset alc269_presets[] = { |
15024 | [ALC269_BASIC] = { | 15046 | [ALC269_BASIC] = { |
15025 | .mixers = { alc269_base_mixer }, | 15047 | .mixers = { alc269_base_mixer }, |
15026 | .init_verbs = { alc269_init_verbs }, | 15048 | .init_verbs = { alc269_init_verbs }, |
@@ -15054,9 +15076,9 @@ static struct alc_config_preset alc269_presets[] = { | |||
15054 | .hp_nid = 0x03, | 15076 | .hp_nid = 0x03, |
15055 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | 15077 | .num_channel_mode = ARRAY_SIZE(alc269_modes), |
15056 | .channel_mode = alc269_modes, | 15078 | .channel_mode = alc269_modes, |
15057 | .unsol_event = alc269_laptop_unsol_event, | 15079 | .unsol_event = alc_sku_unsol_event, |
15058 | .setup = alc269_laptop_amic_setup, | 15080 | .setup = alc269_laptop_amic_setup, |
15059 | .init_hook = alc269_laptop_inithook, | 15081 | .init_hook = alc_inithook, |
15060 | }, | 15082 | }, |
15061 | [ALC269_DMIC] = { | 15083 | [ALC269_DMIC] = { |
15062 | .mixers = { alc269_laptop_mixer }, | 15084 | .mixers = { alc269_laptop_mixer }, |
@@ -15068,9 +15090,9 @@ static struct alc_config_preset alc269_presets[] = { | |||
15068 | .hp_nid = 0x03, | 15090 | .hp_nid = 0x03, |
15069 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | 15091 | .num_channel_mode = ARRAY_SIZE(alc269_modes), |
15070 | .channel_mode = alc269_modes, | 15092 | .channel_mode = alc269_modes, |
15071 | .unsol_event = alc269_laptop_unsol_event, | 15093 | .unsol_event = alc_sku_unsol_event, |
15072 | .setup = alc269_laptop_dmic_setup, | 15094 | .setup = alc269_laptop_dmic_setup, |
15073 | .init_hook = alc269_laptop_inithook, | 15095 | .init_hook = alc_inithook, |
15074 | }, | 15096 | }, |
15075 | [ALC269VB_AMIC] = { | 15097 | [ALC269VB_AMIC] = { |
15076 | .mixers = { alc269vb_laptop_mixer }, | 15098 | .mixers = { alc269vb_laptop_mixer }, |
@@ -15082,9 +15104,9 @@ static struct alc_config_preset alc269_presets[] = { | |||
15082 | .hp_nid = 0x03, | 15104 | .hp_nid = 0x03, |
15083 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | 15105 | .num_channel_mode = ARRAY_SIZE(alc269_modes), |
15084 | .channel_mode = alc269_modes, | 15106 | .channel_mode = alc269_modes, |
15085 | .unsol_event = alc269_laptop_unsol_event, | 15107 | .unsol_event = alc_sku_unsol_event, |
15086 | .setup = alc269vb_laptop_amic_setup, | 15108 | .setup = alc269vb_laptop_amic_setup, |
15087 | .init_hook = alc269_laptop_inithook, | 15109 | .init_hook = alc_inithook, |
15088 | }, | 15110 | }, |
15089 | [ALC269VB_DMIC] = { | 15111 | [ALC269VB_DMIC] = { |
15090 | .mixers = { alc269vb_laptop_mixer }, | 15112 | .mixers = { alc269vb_laptop_mixer }, |
@@ -15096,9 +15118,9 @@ static struct alc_config_preset alc269_presets[] = { | |||
15096 | .hp_nid = 0x03, | 15118 | .hp_nid = 0x03, |
15097 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | 15119 | .num_channel_mode = ARRAY_SIZE(alc269_modes), |
15098 | .channel_mode = alc269_modes, | 15120 | .channel_mode = alc269_modes, |
15099 | .unsol_event = alc269_laptop_unsol_event, | 15121 | .unsol_event = alc_sku_unsol_event, |
15100 | .setup = alc269vb_laptop_dmic_setup, | 15122 | .setup = alc269vb_laptop_dmic_setup, |
15101 | .init_hook = alc269_laptop_inithook, | 15123 | .init_hook = alc_inithook, |
15102 | }, | 15124 | }, |
15103 | [ALC269_FUJITSU] = { | 15125 | [ALC269_FUJITSU] = { |
15104 | .mixers = { alc269_fujitsu_mixer }, | 15126 | .mixers = { alc269_fujitsu_mixer }, |
@@ -15110,9 +15132,9 @@ static struct alc_config_preset alc269_presets[] = { | |||
15110 | .hp_nid = 0x03, | 15132 | .hp_nid = 0x03, |
15111 | .num_channel_mode = ARRAY_SIZE(alc269_modes), | 15133 | .num_channel_mode = ARRAY_SIZE(alc269_modes), |
15112 | .channel_mode = alc269_modes, | 15134 | .channel_mode = alc269_modes, |
15113 | .unsol_event = alc269_laptop_unsol_event, | 15135 | .unsol_event = alc_sku_unsol_event, |
15114 | .setup = alc269_laptop_dmic_setup, | 15136 | .setup = alc269_laptop_dmic_setup, |
15115 | .init_hook = alc269_laptop_inithook, | 15137 | .init_hook = alc_inithook, |
15116 | }, | 15138 | }, |
15117 | [ALC269_LIFEBOOK] = { | 15139 | [ALC269_LIFEBOOK] = { |
15118 | .mixers = { alc269_lifebook_mixer }, | 15140 | .mixers = { alc269_lifebook_mixer }, |
@@ -15124,6 +15146,7 @@ static struct alc_config_preset alc269_presets[] = { | |||
15124 | .channel_mode = alc269_modes, | 15146 | .channel_mode = alc269_modes, |
15125 | .input_mux = &alc269_capture_source, | 15147 | .input_mux = &alc269_capture_source, |
15126 | .unsol_event = alc269_lifebook_unsol_event, | 15148 | .unsol_event = alc269_lifebook_unsol_event, |
15149 | .setup = alc269_lifebook_setup, | ||
15127 | .init_hook = alc269_lifebook_init_hook, | 15150 | .init_hook = alc269_lifebook_init_hook, |
15128 | }, | 15151 | }, |
15129 | [ALC271_ACER] = { | 15152 | [ALC271_ACER] = { |
@@ -15169,14 +15192,21 @@ static int alc269_fill_coef(struct hda_codec *codec) | |||
15169 | val = alc_read_coef_idx(codec, 0xd); | 15192 | val = alc_read_coef_idx(codec, 0xd); |
15170 | if ((val & 0x0c00) >> 10 != 0x1) { | 15193 | if ((val & 0x0c00) >> 10 != 0x1) { |
15171 | /* Capless ramp up clock control */ | 15194 | /* Capless ramp up clock control */ |
15172 | alc_write_coef_idx(codec, 0xd, val | 1<<10); | 15195 | alc_write_coef_idx(codec, 0xd, val | (1<<10)); |
15173 | } | 15196 | } |
15174 | val = alc_read_coef_idx(codec, 0x17); | 15197 | val = alc_read_coef_idx(codec, 0x17); |
15175 | if ((val & 0x01c0) >> 6 != 0x4) { | 15198 | if ((val & 0x01c0) >> 6 != 0x4) { |
15176 | /* Class D power on reset */ | 15199 | /* Class D power on reset */ |
15177 | alc_write_coef_idx(codec, 0x17, val | 1<<7); | 15200 | alc_write_coef_idx(codec, 0x17, val | (1<<7)); |
15178 | } | 15201 | } |
15179 | } | 15202 | } |
15203 | |||
15204 | val = alc_read_coef_idx(codec, 0xd); /* Class D */ | ||
15205 | alc_write_coef_idx(codec, 0xd, val | (1<<14)); | ||
15206 | |||
15207 | val = alc_read_coef_idx(codec, 0x4); /* HP */ | ||
15208 | alc_write_coef_idx(codec, 0x4, val | (1<<11)); | ||
15209 | |||
15180 | return 0; | 15210 | return 0; |
15181 | } | 15211 | } |
15182 | 15212 | ||
@@ -15297,14 +15327,12 @@ static int patch_alc269(struct hda_codec *codec) | |||
15297 | spec->vmaster_nid = 0x02; | 15327 | spec->vmaster_nid = 0x02; |
15298 | 15328 | ||
15299 | codec->patch_ops = alc_patch_ops; | 15329 | codec->patch_ops = alc_patch_ops; |
15300 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
15301 | codec->patch_ops.suspend = alc269_suspend; | ||
15302 | #endif | ||
15303 | #ifdef SND_HDA_NEEDS_RESUME | 15330 | #ifdef SND_HDA_NEEDS_RESUME |
15304 | codec->patch_ops.resume = alc269_resume; | 15331 | codec->patch_ops.resume = alc269_resume; |
15305 | #endif | 15332 | #endif |
15306 | if (board_config == ALC269_AUTO) | 15333 | if (board_config == ALC269_AUTO) |
15307 | spec->init_hook = alc269_auto_init; | 15334 | spec->init_hook = alc269_auto_init; |
15335 | spec->shutup = alc269_shutup; | ||
15308 | 15336 | ||
15309 | alc_init_jacks(codec); | 15337 | alc_init_jacks(codec); |
15310 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 15338 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -15325,7 +15353,7 @@ static int patch_alc269(struct hda_codec *codec) | |||
15325 | * set the path ways for 2 channel output | 15353 | * set the path ways for 2 channel output |
15326 | * need to set the codec line out and mic 1 pin widgets to inputs | 15354 | * need to set the codec line out and mic 1 pin widgets to inputs |
15327 | */ | 15355 | */ |
15328 | static struct hda_verb alc861_threestack_ch2_init[] = { | 15356 | static const struct hda_verb alc861_threestack_ch2_init[] = { |
15329 | /* set pin widget 1Ah (line in) for input */ | 15357 | /* set pin widget 1Ah (line in) for input */ |
15330 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | 15358 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, |
15331 | /* set pin widget 18h (mic1/2) for input, for mic also enable | 15359 | /* set pin widget 18h (mic1/2) for input, for mic also enable |
@@ -15344,7 +15372,7 @@ static struct hda_verb alc861_threestack_ch2_init[] = { | |||
15344 | * 6ch mode | 15372 | * 6ch mode |
15345 | * need to set the codec line out and mic 1 pin widgets to outputs | 15373 | * need to set the codec line out and mic 1 pin widgets to outputs |
15346 | */ | 15374 | */ |
15347 | static struct hda_verb alc861_threestack_ch6_init[] = { | 15375 | static const struct hda_verb alc861_threestack_ch6_init[] = { |
15348 | /* set pin widget 1Ah (line in) for output (Back Surround)*/ | 15376 | /* set pin widget 1Ah (line in) for output (Back Surround)*/ |
15349 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 15377 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, |
15350 | /* set pin widget 18h (mic1) for output (CLFE)*/ | 15378 | /* set pin widget 18h (mic1) for output (CLFE)*/ |
@@ -15361,30 +15389,30 @@ static struct hda_verb alc861_threestack_ch6_init[] = { | |||
15361 | { } /* end */ | 15389 | { } /* end */ |
15362 | }; | 15390 | }; |
15363 | 15391 | ||
15364 | static struct hda_channel_mode alc861_threestack_modes[2] = { | 15392 | static const struct hda_channel_mode alc861_threestack_modes[2] = { |
15365 | { 2, alc861_threestack_ch2_init }, | 15393 | { 2, alc861_threestack_ch2_init }, |
15366 | { 6, alc861_threestack_ch6_init }, | 15394 | { 6, alc861_threestack_ch6_init }, |
15367 | }; | 15395 | }; |
15368 | /* Set mic1 as input and unmute the mixer */ | 15396 | /* Set mic1 as input and unmute the mixer */ |
15369 | static struct hda_verb alc861_uniwill_m31_ch2_init[] = { | 15397 | static const struct hda_verb alc861_uniwill_m31_ch2_init[] = { |
15370 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, | 15398 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, |
15371 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ | 15399 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ |
15372 | { } /* end */ | 15400 | { } /* end */ |
15373 | }; | 15401 | }; |
15374 | /* Set mic1 as output and mute mixer */ | 15402 | /* Set mic1 as output and mute mixer */ |
15375 | static struct hda_verb alc861_uniwill_m31_ch4_init[] = { | 15403 | static const struct hda_verb alc861_uniwill_m31_ch4_init[] = { |
15376 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 15404 | { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, |
15377 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ | 15405 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ |
15378 | { } /* end */ | 15406 | { } /* end */ |
15379 | }; | 15407 | }; |
15380 | 15408 | ||
15381 | static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { | 15409 | static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = { |
15382 | { 2, alc861_uniwill_m31_ch2_init }, | 15410 | { 2, alc861_uniwill_m31_ch2_init }, |
15383 | { 4, alc861_uniwill_m31_ch4_init }, | 15411 | { 4, alc861_uniwill_m31_ch4_init }, |
15384 | }; | 15412 | }; |
15385 | 15413 | ||
15386 | /* Set mic1 and line-in as input and unmute the mixer */ | 15414 | /* Set mic1 and line-in as input and unmute the mixer */ |
15387 | static struct hda_verb alc861_asus_ch2_init[] = { | 15415 | static const struct hda_verb alc861_asus_ch2_init[] = { |
15388 | /* set pin widget 1Ah (line in) for input */ | 15416 | /* set pin widget 1Ah (line in) for input */ |
15389 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, | 15417 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, |
15390 | /* set pin widget 18h (mic1/2) for input, for mic also enable | 15418 | /* set pin widget 18h (mic1/2) for input, for mic also enable |
@@ -15400,7 +15428,7 @@ static struct hda_verb alc861_asus_ch2_init[] = { | |||
15400 | { } /* end */ | 15428 | { } /* end */ |
15401 | }; | 15429 | }; |
15402 | /* Set mic1 nad line-in as output and mute mixer */ | 15430 | /* Set mic1 nad line-in as output and mute mixer */ |
15403 | static struct hda_verb alc861_asus_ch6_init[] = { | 15431 | static const struct hda_verb alc861_asus_ch6_init[] = { |
15404 | /* set pin widget 1Ah (line in) for output (Back Surround)*/ | 15432 | /* set pin widget 1Ah (line in) for output (Back Surround)*/ |
15405 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, | 15433 | { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, |
15406 | /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ | 15434 | /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ |
@@ -15418,14 +15446,14 @@ static struct hda_verb alc861_asus_ch6_init[] = { | |||
15418 | { } /* end */ | 15446 | { } /* end */ |
15419 | }; | 15447 | }; |
15420 | 15448 | ||
15421 | static struct hda_channel_mode alc861_asus_modes[2] = { | 15449 | static const struct hda_channel_mode alc861_asus_modes[2] = { |
15422 | { 2, alc861_asus_ch2_init }, | 15450 | { 2, alc861_asus_ch2_init }, |
15423 | { 6, alc861_asus_ch6_init }, | 15451 | { 6, alc861_asus_ch6_init }, |
15424 | }; | 15452 | }; |
15425 | 15453 | ||
15426 | /* patch-ALC861 */ | 15454 | /* patch-ALC861 */ |
15427 | 15455 | ||
15428 | static struct snd_kcontrol_new alc861_base_mixer[] = { | 15456 | static const struct snd_kcontrol_new alc861_base_mixer[] = { |
15429 | /* output mixer control */ | 15457 | /* output mixer control */ |
15430 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), | 15458 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), |
15431 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), | 15459 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), |
@@ -15448,7 +15476,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = { | |||
15448 | { } /* end */ | 15476 | { } /* end */ |
15449 | }; | 15477 | }; |
15450 | 15478 | ||
15451 | static struct snd_kcontrol_new alc861_3ST_mixer[] = { | 15479 | static const struct snd_kcontrol_new alc861_3ST_mixer[] = { |
15452 | /* output mixer control */ | 15480 | /* output mixer control */ |
15453 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), | 15481 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), |
15454 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), | 15482 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), |
@@ -15479,7 +15507,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { | |||
15479 | { } /* end */ | 15507 | { } /* end */ |
15480 | }; | 15508 | }; |
15481 | 15509 | ||
15482 | static struct snd_kcontrol_new alc861_toshiba_mixer[] = { | 15510 | static const struct snd_kcontrol_new alc861_toshiba_mixer[] = { |
15483 | /* output mixer control */ | 15511 | /* output mixer control */ |
15484 | HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), | 15512 | HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), |
15485 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), | 15513 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), |
@@ -15488,7 +15516,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = { | |||
15488 | { } /* end */ | 15516 | { } /* end */ |
15489 | }; | 15517 | }; |
15490 | 15518 | ||
15491 | static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | 15519 | static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { |
15492 | /* output mixer control */ | 15520 | /* output mixer control */ |
15493 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), | 15521 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), |
15494 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), | 15522 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), |
@@ -15519,7 +15547,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { | |||
15519 | { } /* end */ | 15547 | { } /* end */ |
15520 | }; | 15548 | }; |
15521 | 15549 | ||
15522 | static struct snd_kcontrol_new alc861_asus_mixer[] = { | 15550 | static const struct snd_kcontrol_new alc861_asus_mixer[] = { |
15523 | /* output mixer control */ | 15551 | /* output mixer control */ |
15524 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), | 15552 | HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), |
15525 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), | 15553 | HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), |
@@ -15551,7 +15579,7 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { | |||
15551 | }; | 15579 | }; |
15552 | 15580 | ||
15553 | /* additional mixer */ | 15581 | /* additional mixer */ |
15554 | static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { | 15582 | static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { |
15555 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), | 15583 | HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), |
15556 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), | 15584 | HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), |
15557 | { } | 15585 | { } |
@@ -15560,7 +15588,7 @@ static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { | |||
15560 | /* | 15588 | /* |
15561 | * generic initialization of ADC, input mixers and output mixers | 15589 | * generic initialization of ADC, input mixers and output mixers |
15562 | */ | 15590 | */ |
15563 | static struct hda_verb alc861_base_init_verbs[] = { | 15591 | static const struct hda_verb alc861_base_init_verbs[] = { |
15564 | /* | 15592 | /* |
15565 | * Unmute ADC0 and set the default input to mic-in | 15593 | * Unmute ADC0 and set the default input to mic-in |
15566 | */ | 15594 | */ |
@@ -15626,7 +15654,7 @@ static struct hda_verb alc861_base_init_verbs[] = { | |||
15626 | { } | 15654 | { } |
15627 | }; | 15655 | }; |
15628 | 15656 | ||
15629 | static struct hda_verb alc861_threestack_init_verbs[] = { | 15657 | static const struct hda_verb alc861_threestack_init_verbs[] = { |
15630 | /* | 15658 | /* |
15631 | * Unmute ADC0 and set the default input to mic-in | 15659 | * Unmute ADC0 and set the default input to mic-in |
15632 | */ | 15660 | */ |
@@ -15687,7 +15715,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = { | |||
15687 | { } | 15715 | { } |
15688 | }; | 15716 | }; |
15689 | 15717 | ||
15690 | static struct hda_verb alc861_uniwill_m31_init_verbs[] = { | 15718 | static const struct hda_verb alc861_uniwill_m31_init_verbs[] = { |
15691 | /* | 15719 | /* |
15692 | * Unmute ADC0 and set the default input to mic-in | 15720 | * Unmute ADC0 and set the default input to mic-in |
15693 | */ | 15721 | */ |
@@ -15749,7 +15777,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { | |||
15749 | { } | 15777 | { } |
15750 | }; | 15778 | }; |
15751 | 15779 | ||
15752 | static struct hda_verb alc861_asus_init_verbs[] = { | 15780 | static const struct hda_verb alc861_asus_init_verbs[] = { |
15753 | /* | 15781 | /* |
15754 | * Unmute ADC0 and set the default input to mic-in | 15782 | * Unmute ADC0 and set the default input to mic-in |
15755 | */ | 15783 | */ |
@@ -15815,7 +15843,7 @@ static struct hda_verb alc861_asus_init_verbs[] = { | |||
15815 | }; | 15843 | }; |
15816 | 15844 | ||
15817 | /* additional init verbs for ASUS laptops */ | 15845 | /* additional init verbs for ASUS laptops */ |
15818 | static struct hda_verb alc861_asus_laptop_init_verbs[] = { | 15846 | static const struct hda_verb alc861_asus_laptop_init_verbs[] = { |
15819 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ | 15847 | { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ |
15820 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ | 15848 | { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ |
15821 | { } | 15849 | { } |
@@ -15824,7 +15852,7 @@ static struct hda_verb alc861_asus_laptop_init_verbs[] = { | |||
15824 | /* | 15852 | /* |
15825 | * generic initialization of ADC, input mixers and output mixers | 15853 | * generic initialization of ADC, input mixers and output mixers |
15826 | */ | 15854 | */ |
15827 | static struct hda_verb alc861_auto_init_verbs[] = { | 15855 | static const struct hda_verb alc861_auto_init_verbs[] = { |
15828 | /* | 15856 | /* |
15829 | * Unmute ADC0 and set the default input to mic-in | 15857 | * Unmute ADC0 and set the default input to mic-in |
15830 | */ | 15858 | */ |
@@ -15873,7 +15901,7 @@ static struct hda_verb alc861_auto_init_verbs[] = { | |||
15873 | { } | 15901 | { } |
15874 | }; | 15902 | }; |
15875 | 15903 | ||
15876 | static struct hda_verb alc861_toshiba_init_verbs[] = { | 15904 | static const struct hda_verb alc861_toshiba_init_verbs[] = { |
15877 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | 15905 | {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
15878 | 15906 | ||
15879 | { } | 15907 | { } |
@@ -15906,26 +15934,26 @@ static void alc861_toshiba_unsol_event(struct hda_codec *codec, | |||
15906 | 15934 | ||
15907 | #define ALC861_DIGOUT_NID 0x07 | 15935 | #define ALC861_DIGOUT_NID 0x07 |
15908 | 15936 | ||
15909 | static struct hda_channel_mode alc861_8ch_modes[1] = { | 15937 | static const struct hda_channel_mode alc861_8ch_modes[1] = { |
15910 | { 8, NULL } | 15938 | { 8, NULL } |
15911 | }; | 15939 | }; |
15912 | 15940 | ||
15913 | static hda_nid_t alc861_dac_nids[4] = { | 15941 | static const hda_nid_t alc861_dac_nids[4] = { |
15914 | /* front, surround, clfe, side */ | 15942 | /* front, surround, clfe, side */ |
15915 | 0x03, 0x06, 0x05, 0x04 | 15943 | 0x03, 0x06, 0x05, 0x04 |
15916 | }; | 15944 | }; |
15917 | 15945 | ||
15918 | static hda_nid_t alc660_dac_nids[3] = { | 15946 | static const hda_nid_t alc660_dac_nids[3] = { |
15919 | /* front, clfe, surround */ | 15947 | /* front, clfe, surround */ |
15920 | 0x03, 0x05, 0x06 | 15948 | 0x03, 0x05, 0x06 |
15921 | }; | 15949 | }; |
15922 | 15950 | ||
15923 | static hda_nid_t alc861_adc_nids[1] = { | 15951 | static const hda_nid_t alc861_adc_nids[1] = { |
15924 | /* ADC0-2 */ | 15952 | /* ADC0-2 */ |
15925 | 0x08, | 15953 | 0x08, |
15926 | }; | 15954 | }; |
15927 | 15955 | ||
15928 | static struct hda_input_mux alc861_capture_source = { | 15956 | static const struct hda_input_mux alc861_capture_source = { |
15929 | .num_items = 5, | 15957 | .num_items = 5, |
15930 | .items = { | 15958 | .items = { |
15931 | { "Mic", 0x0 }, | 15959 | { "Mic", 0x0 }, |
@@ -15975,7 +16003,7 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec, | |||
15975 | dac = alc861_look_for_dac(codec, nid); | 16003 | dac = alc861_look_for_dac(codec, nid); |
15976 | if (!dac) | 16004 | if (!dac) |
15977 | continue; | 16005 | continue; |
15978 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; | 16006 | spec->private_dac_nids[spec->multiout.num_dacs++] = dac; |
15979 | } | 16007 | } |
15980 | return 0; | 16008 | return 0; |
15981 | } | 16009 | } |
@@ -15998,11 +16026,15 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
15998 | static const char * const chname[4] = { | 16026 | static const char * const chname[4] = { |
15999 | "Front", "Surround", NULL /*CLFE*/, "Side" | 16027 | "Front", "Surround", NULL /*CLFE*/, "Side" |
16000 | }; | 16028 | }; |
16001 | const char *pfx = alc_get_line_out_pfx(cfg, true); | 16029 | const char *pfx = alc_get_line_out_pfx(spec, true); |
16002 | hda_nid_t nid; | 16030 | hda_nid_t nid; |
16003 | int i, err; | 16031 | int i, err, noutputs; |
16004 | 16032 | ||
16005 | for (i = 0; i < cfg->line_outs; i++) { | 16033 | noutputs = cfg->line_outs; |
16034 | if (spec->multi_ios > 0) | ||
16035 | noutputs += spec->multi_ios; | ||
16036 | |||
16037 | for (i = 0; i < noutputs; i++) { | ||
16006 | nid = spec->multiout.dac_nids[i]; | 16038 | nid = spec->multiout.dac_nids[i]; |
16007 | if (!nid) | 16039 | if (!nid) |
16008 | continue; | 16040 | continue; |
@@ -16135,7 +16167,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
16135 | { | 16167 | { |
16136 | struct alc_spec *spec = codec->spec; | 16168 | struct alc_spec *spec = codec->spec; |
16137 | int err; | 16169 | int err; |
16138 | static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; | 16170 | static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; |
16139 | 16171 | ||
16140 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 16172 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
16141 | alc861_ignore); | 16173 | alc861_ignore); |
@@ -16147,6 +16179,9 @@ static int alc861_parse_auto_config(struct hda_codec *codec) | |||
16147 | err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); | 16179 | err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); |
16148 | if (err < 0) | 16180 | if (err < 0) |
16149 | return err; | 16181 | return err; |
16182 | err = alc_auto_add_multi_channel_mode(codec); | ||
16183 | if (err < 0) | ||
16184 | return err; | ||
16150 | err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); | 16185 | err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); |
16151 | if (err < 0) | 16186 | if (err < 0) |
16152 | return err; | 16187 | return err; |
@@ -16191,7 +16226,7 @@ static void alc861_auto_init(struct hda_codec *codec) | |||
16191 | } | 16226 | } |
16192 | 16227 | ||
16193 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 16228 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
16194 | static struct hda_amp_list alc861_loopbacks[] = { | 16229 | static const struct hda_amp_list alc861_loopbacks[] = { |
16195 | { 0x15, HDA_INPUT, 0 }, | 16230 | { 0x15, HDA_INPUT, 0 }, |
16196 | { 0x15, HDA_INPUT, 1 }, | 16231 | { 0x15, HDA_INPUT, 1 }, |
16197 | { 0x15, HDA_INPUT, 2 }, | 16232 | { 0x15, HDA_INPUT, 2 }, |
@@ -16216,7 +16251,7 @@ static const char * const alc861_models[ALC861_MODEL_LAST] = { | |||
16216 | [ALC861_AUTO] = "auto", | 16251 | [ALC861_AUTO] = "auto", |
16217 | }; | 16252 | }; |
16218 | 16253 | ||
16219 | static struct snd_pci_quirk alc861_cfg_tbl[] = { | 16254 | static const struct snd_pci_quirk alc861_cfg_tbl[] = { |
16220 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), | 16255 | SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), |
16221 | SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), | 16256 | SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), |
16222 | SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), | 16257 | SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), |
@@ -16240,7 +16275,7 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { | |||
16240 | {} | 16275 | {} |
16241 | }; | 16276 | }; |
16242 | 16277 | ||
16243 | static struct alc_config_preset alc861_presets[] = { | 16278 | static const struct alc_config_preset alc861_presets[] = { |
16244 | [ALC861_3ST] = { | 16279 | [ALC861_3ST] = { |
16245 | .mixers = { alc861_3ST_mixer }, | 16280 | .mixers = { alc861_3ST_mixer }, |
16246 | .init_verbs = { alc861_threestack_init_verbs }, | 16281 | .init_verbs = { alc861_threestack_init_verbs }, |
@@ -16363,7 +16398,7 @@ static const struct alc_fixup alc861_fixups[] = { | |||
16363 | }, | 16398 | }, |
16364 | }; | 16399 | }; |
16365 | 16400 | ||
16366 | static struct snd_pci_quirk alc861_fixup_tbl[] = { | 16401 | static const struct snd_pci_quirk alc861_fixup_tbl[] = { |
16367 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), | 16402 | SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), |
16368 | {} | 16403 | {} |
16369 | }; | 16404 | }; |
@@ -16456,7 +16491,7 @@ static int patch_alc861(struct hda_codec *codec) | |||
16456 | */ | 16491 | */ |
16457 | #define ALC861VD_DIGOUT_NID 0x06 | 16492 | #define ALC861VD_DIGOUT_NID 0x06 |
16458 | 16493 | ||
16459 | static hda_nid_t alc861vd_dac_nids[4] = { | 16494 | static const hda_nid_t alc861vd_dac_nids[4] = { |
16460 | /* front, surr, clfe, side surr */ | 16495 | /* front, surr, clfe, side surr */ |
16461 | 0x02, 0x03, 0x04, 0x05 | 16496 | 0x02, 0x03, 0x04, 0x05 |
16462 | }; | 16497 | }; |
@@ -16468,21 +16503,21 @@ static hda_nid_t alc861vd_dac_nids[4] = { | |||
16468 | * - and it is the same as in 861vd. | 16503 | * - and it is the same as in 861vd. |
16469 | * adc_nids in ALC660vd are (is) the same as in 861vd | 16504 | * adc_nids in ALC660vd are (is) the same as in 861vd |
16470 | */ | 16505 | */ |
16471 | static hda_nid_t alc660vd_dac_nids[3] = { | 16506 | static const hda_nid_t alc660vd_dac_nids[3] = { |
16472 | /* front, rear, clfe, rear_surr */ | 16507 | /* front, rear, clfe, rear_surr */ |
16473 | 0x02, 0x04, 0x03 | 16508 | 0x02, 0x04, 0x03 |
16474 | }; | 16509 | }; |
16475 | 16510 | ||
16476 | static hda_nid_t alc861vd_adc_nids[1] = { | 16511 | static const hda_nid_t alc861vd_adc_nids[1] = { |
16477 | /* ADC0 */ | 16512 | /* ADC0 */ |
16478 | 0x09, | 16513 | 0x09, |
16479 | }; | 16514 | }; |
16480 | 16515 | ||
16481 | static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; | 16516 | static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; |
16482 | 16517 | ||
16483 | /* input MUX */ | 16518 | /* input MUX */ |
16484 | /* FIXME: should be a matrix-type input source selection */ | 16519 | /* FIXME: should be a matrix-type input source selection */ |
16485 | static struct hda_input_mux alc861vd_capture_source = { | 16520 | static const struct hda_input_mux alc861vd_capture_source = { |
16486 | .num_items = 4, | 16521 | .num_items = 4, |
16487 | .items = { | 16522 | .items = { |
16488 | { "Mic", 0x0 }, | 16523 | { "Mic", 0x0 }, |
@@ -16492,7 +16527,7 @@ static struct hda_input_mux alc861vd_capture_source = { | |||
16492 | }, | 16527 | }, |
16493 | }; | 16528 | }; |
16494 | 16529 | ||
16495 | static struct hda_input_mux alc861vd_dallas_capture_source = { | 16530 | static const struct hda_input_mux alc861vd_dallas_capture_source = { |
16496 | .num_items = 2, | 16531 | .num_items = 2, |
16497 | .items = { | 16532 | .items = { |
16498 | { "Mic", 0x0 }, | 16533 | { "Mic", 0x0 }, |
@@ -16500,7 +16535,7 @@ static struct hda_input_mux alc861vd_dallas_capture_source = { | |||
16500 | }, | 16535 | }, |
16501 | }; | 16536 | }; |
16502 | 16537 | ||
16503 | static struct hda_input_mux alc861vd_hp_capture_source = { | 16538 | static const struct hda_input_mux alc861vd_hp_capture_source = { |
16504 | .num_items = 2, | 16539 | .num_items = 2, |
16505 | .items = { | 16540 | .items = { |
16506 | { "Front Mic", 0x0 }, | 16541 | { "Front Mic", 0x0 }, |
@@ -16511,14 +16546,14 @@ static struct hda_input_mux alc861vd_hp_capture_source = { | |||
16511 | /* | 16546 | /* |
16512 | * 2ch mode | 16547 | * 2ch mode |
16513 | */ | 16548 | */ |
16514 | static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { | 16549 | static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { |
16515 | { 2, NULL } | 16550 | { 2, NULL } |
16516 | }; | 16551 | }; |
16517 | 16552 | ||
16518 | /* | 16553 | /* |
16519 | * 6ch mode | 16554 | * 6ch mode |
16520 | */ | 16555 | */ |
16521 | static struct hda_verb alc861vd_6stack_ch6_init[] = { | 16556 | static const struct hda_verb alc861vd_6stack_ch6_init[] = { |
16522 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | 16557 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, |
16523 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 16558 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
16524 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 16559 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -16529,7 +16564,7 @@ static struct hda_verb alc861vd_6stack_ch6_init[] = { | |||
16529 | /* | 16564 | /* |
16530 | * 8ch mode | 16565 | * 8ch mode |
16531 | */ | 16566 | */ |
16532 | static struct hda_verb alc861vd_6stack_ch8_init[] = { | 16567 | static const struct hda_verb alc861vd_6stack_ch8_init[] = { |
16533 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 16568 | { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
16534 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 16569 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
16535 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 16570 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -16537,12 +16572,12 @@ static struct hda_verb alc861vd_6stack_ch8_init[] = { | |||
16537 | { } /* end */ | 16572 | { } /* end */ |
16538 | }; | 16573 | }; |
16539 | 16574 | ||
16540 | static struct hda_channel_mode alc861vd_6stack_modes[2] = { | 16575 | static const struct hda_channel_mode alc861vd_6stack_modes[2] = { |
16541 | { 6, alc861vd_6stack_ch6_init }, | 16576 | { 6, alc861vd_6stack_ch6_init }, |
16542 | { 8, alc861vd_6stack_ch8_init }, | 16577 | { 8, alc861vd_6stack_ch8_init }, |
16543 | }; | 16578 | }; |
16544 | 16579 | ||
16545 | static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { | 16580 | static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = { |
16546 | { | 16581 | { |
16547 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 16582 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
16548 | .name = "Channel Mode", | 16583 | .name = "Channel Mode", |
@@ -16556,7 +16591,7 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { | |||
16556 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 | 16591 | /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 |
16557 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | 16592 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b |
16558 | */ | 16593 | */ |
16559 | static struct snd_kcontrol_new alc861vd_6st_mixer[] = { | 16594 | static const struct snd_kcontrol_new alc861vd_6st_mixer[] = { |
16560 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 16595 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
16561 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 16596 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
16562 | 16597 | ||
@@ -16592,7 +16627,7 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = { | |||
16592 | { } /* end */ | 16627 | { } /* end */ |
16593 | }; | 16628 | }; |
16594 | 16629 | ||
16595 | static struct snd_kcontrol_new alc861vd_3st_mixer[] = { | 16630 | static const struct snd_kcontrol_new alc861vd_3st_mixer[] = { |
16596 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 16631 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
16597 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 16632 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
16598 | 16633 | ||
@@ -16615,7 +16650,7 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { | |||
16615 | { } /* end */ | 16650 | { } /* end */ |
16616 | }; | 16651 | }; |
16617 | 16652 | ||
16618 | static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { | 16653 | static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { |
16619 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 16654 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
16620 | /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ | 16655 | /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ |
16621 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 16656 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -16639,7 +16674,7 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { | |||
16639 | /* Pin assignment: Speaker=0x14, HP = 0x15, | 16674 | /* Pin assignment: Speaker=0x14, HP = 0x15, |
16640 | * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d | 16675 | * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d |
16641 | */ | 16676 | */ |
16642 | static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { | 16677 | static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = { |
16643 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 16678 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
16644 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), | 16679 | HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), |
16645 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 16680 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
@@ -16656,7 +16691,7 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { | |||
16656 | /* Pin assignment: Speaker=0x14, Line-out = 0x15, | 16691 | /* Pin assignment: Speaker=0x14, Line-out = 0x15, |
16657 | * Front Mic=0x18, ATAPI Mic = 0x19, | 16692 | * Front Mic=0x18, ATAPI Mic = 0x19, |
16658 | */ | 16693 | */ |
16659 | static struct snd_kcontrol_new alc861vd_hp_mixer[] = { | 16694 | static const struct snd_kcontrol_new alc861vd_hp_mixer[] = { |
16660 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 16695 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
16661 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), | 16696 | HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), |
16662 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 16697 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
@@ -16672,7 +16707,7 @@ static struct snd_kcontrol_new alc861vd_hp_mixer[] = { | |||
16672 | /* | 16707 | /* |
16673 | * generic initialization of ADC, input mixers and output mixers | 16708 | * generic initialization of ADC, input mixers and output mixers |
16674 | */ | 16709 | */ |
16675 | static struct hda_verb alc861vd_volume_init_verbs[] = { | 16710 | static const struct hda_verb alc861vd_volume_init_verbs[] = { |
16676 | /* | 16711 | /* |
16677 | * Unmute ADC0 and set the default input to mic-in | 16712 | * Unmute ADC0 and set the default input to mic-in |
16678 | */ | 16713 | */ |
@@ -16722,7 +16757,7 @@ static struct hda_verb alc861vd_volume_init_verbs[] = { | |||
16722 | * 3-stack pin configuration: | 16757 | * 3-stack pin configuration: |
16723 | * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b | 16758 | * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b |
16724 | */ | 16759 | */ |
16725 | static struct hda_verb alc861vd_3stack_init_verbs[] = { | 16760 | static const struct hda_verb alc861vd_3stack_init_verbs[] = { |
16726 | /* | 16761 | /* |
16727 | * Set pin mode and muting | 16762 | * Set pin mode and muting |
16728 | */ | 16763 | */ |
@@ -16753,7 +16788,7 @@ static struct hda_verb alc861vd_3stack_init_verbs[] = { | |||
16753 | /* | 16788 | /* |
16754 | * 6-stack pin configuration: | 16789 | * 6-stack pin configuration: |
16755 | */ | 16790 | */ |
16756 | static struct hda_verb alc861vd_6stack_init_verbs[] = { | 16791 | static const struct hda_verb alc861vd_6stack_init_verbs[] = { |
16757 | /* | 16792 | /* |
16758 | * Set pin mode and muting | 16793 | * Set pin mode and muting |
16759 | */ | 16794 | */ |
@@ -16794,18 +16829,18 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = { | |||
16794 | { } | 16829 | { } |
16795 | }; | 16830 | }; |
16796 | 16831 | ||
16797 | static struct hda_verb alc861vd_eapd_verbs[] = { | 16832 | static const struct hda_verb alc861vd_eapd_verbs[] = { |
16798 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 16833 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
16799 | { } | 16834 | { } |
16800 | }; | 16835 | }; |
16801 | 16836 | ||
16802 | static struct hda_verb alc660vd_eapd_verbs[] = { | 16837 | static const struct hda_verb alc660vd_eapd_verbs[] = { |
16803 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 16838 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
16804 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | 16839 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
16805 | { } | 16840 | { } |
16806 | }; | 16841 | }; |
16807 | 16842 | ||
16808 | static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { | 16843 | static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = { |
16809 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 16844 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
16810 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | 16845 | {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, |
16811 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | 16846 | {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, |
@@ -16819,11 +16854,13 @@ static void alc861vd_lenovo_setup(struct hda_codec *codec) | |||
16819 | struct alc_spec *spec = codec->spec; | 16854 | struct alc_spec *spec = codec->spec; |
16820 | spec->autocfg.hp_pins[0] = 0x1b; | 16855 | spec->autocfg.hp_pins[0] = 0x1b; |
16821 | spec->autocfg.speaker_pins[0] = 0x14; | 16856 | spec->autocfg.speaker_pins[0] = 0x14; |
16857 | spec->automute = 1; | ||
16858 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
16822 | } | 16859 | } |
16823 | 16860 | ||
16824 | static void alc861vd_lenovo_init_hook(struct hda_codec *codec) | 16861 | static void alc861vd_lenovo_init_hook(struct hda_codec *codec) |
16825 | { | 16862 | { |
16826 | alc_automute_amp(codec); | 16863 | alc_hp_automute(codec); |
16827 | alc88x_simple_mic_automute(codec); | 16864 | alc88x_simple_mic_automute(codec); |
16828 | } | 16865 | } |
16829 | 16866 | ||
@@ -16835,12 +16872,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, | |||
16835 | alc88x_simple_mic_automute(codec); | 16872 | alc88x_simple_mic_automute(codec); |
16836 | break; | 16873 | break; |
16837 | default: | 16874 | default: |
16838 | alc_automute_amp_unsol_event(codec, res); | 16875 | alc_sku_unsol_event(codec, res); |
16839 | break; | 16876 | break; |
16840 | } | 16877 | } |
16841 | } | 16878 | } |
16842 | 16879 | ||
16843 | static struct hda_verb alc861vd_dallas_verbs[] = { | 16880 | static const struct hda_verb alc861vd_dallas_verbs[] = { |
16844 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 16881 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
16845 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 16882 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
16846 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, | 16883 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, |
@@ -16892,6 +16929,8 @@ static void alc861vd_dallas_setup(struct hda_codec *codec) | |||
16892 | 16929 | ||
16893 | spec->autocfg.hp_pins[0] = 0x15; | 16930 | spec->autocfg.hp_pins[0] = 0x15; |
16894 | spec->autocfg.speaker_pins[0] = 0x14; | 16931 | spec->autocfg.speaker_pins[0] = 0x14; |
16932 | spec->automute = 1; | ||
16933 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
16895 | } | 16934 | } |
16896 | 16935 | ||
16897 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 16936 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -16920,7 +16959,7 @@ static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = { | |||
16920 | [ALC861VD_AUTO] = "auto", | 16959 | [ALC861VD_AUTO] = "auto", |
16921 | }; | 16960 | }; |
16922 | 16961 | ||
16923 | static struct snd_pci_quirk alc861vd_cfg_tbl[] = { | 16962 | static const struct snd_pci_quirk alc861vd_cfg_tbl[] = { |
16924 | SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), | 16963 | SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), |
16925 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), | 16964 | SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), |
16926 | SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), | 16965 | SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), |
@@ -16939,7 +16978,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { | |||
16939 | {} | 16978 | {} |
16940 | }; | 16979 | }; |
16941 | 16980 | ||
16942 | static struct alc_config_preset alc861vd_presets[] = { | 16981 | static const struct alc_config_preset alc861vd_presets[] = { |
16943 | [ALC660VD_3ST] = { | 16982 | [ALC660VD_3ST] = { |
16944 | .mixers = { alc861vd_3st_mixer }, | 16983 | .mixers = { alc861vd_3st_mixer }, |
16945 | .init_verbs = { alc861vd_volume_init_verbs, | 16984 | .init_verbs = { alc861vd_volume_init_verbs, |
@@ -17016,9 +17055,9 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
17016 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | 17055 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), |
17017 | .channel_mode = alc861vd_3stack_2ch_modes, | 17056 | .channel_mode = alc861vd_3stack_2ch_modes, |
17018 | .input_mux = &alc861vd_dallas_capture_source, | 17057 | .input_mux = &alc861vd_dallas_capture_source, |
17019 | .unsol_event = alc_automute_amp_unsol_event, | 17058 | .unsol_event = alc_sku_unsol_event, |
17020 | .setup = alc861vd_dallas_setup, | 17059 | .setup = alc861vd_dallas_setup, |
17021 | .init_hook = alc_automute_amp, | 17060 | .init_hook = alc_hp_automute, |
17022 | }, | 17061 | }, |
17023 | [ALC861VD_HP] = { | 17062 | [ALC861VD_HP] = { |
17024 | .mixers = { alc861vd_hp_mixer }, | 17063 | .mixers = { alc861vd_hp_mixer }, |
@@ -17029,9 +17068,9 @@ static struct alc_config_preset alc861vd_presets[] = { | |||
17029 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), | 17068 | .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), |
17030 | .channel_mode = alc861vd_3stack_2ch_modes, | 17069 | .channel_mode = alc861vd_3stack_2ch_modes, |
17031 | .input_mux = &alc861vd_hp_capture_source, | 17070 | .input_mux = &alc861vd_hp_capture_source, |
17032 | .unsol_event = alc_automute_amp_unsol_event, | 17071 | .unsol_event = alc_sku_unsol_event, |
17033 | .setup = alc861vd_dallas_setup, | 17072 | .setup = alc861vd_dallas_setup, |
17034 | .init_hook = alc_automute_amp, | 17073 | .init_hook = alc_hp_automute, |
17035 | }, | 17074 | }, |
17036 | [ALC660VD_ASUS_V1S] = { | 17075 | [ALC660VD_ASUS_V1S] = { |
17037 | .mixers = { alc861vd_lenovo_mixer }, | 17076 | .mixers = { alc861vd_lenovo_mixer }, |
@@ -17130,11 +17169,15 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, | |||
17130 | static const char * const chname[4] = { | 17169 | static const char * const chname[4] = { |
17131 | "Front", "Surround", "CLFE", "Side" | 17170 | "Front", "Surround", "CLFE", "Side" |
17132 | }; | 17171 | }; |
17133 | const char *pfx = alc_get_line_out_pfx(cfg, true); | 17172 | const char *pfx = alc_get_line_out_pfx(spec, true); |
17134 | hda_nid_t nid_v, nid_s; | 17173 | hda_nid_t nid_v, nid_s; |
17135 | int i, err; | 17174 | int i, err, noutputs; |
17136 | 17175 | ||
17137 | for (i = 0; i < cfg->line_outs; i++) { | 17176 | noutputs = cfg->line_outs; |
17177 | if (spec->multi_ios > 0) | ||
17178 | noutputs += spec->multi_ios; | ||
17179 | |||
17180 | for (i = 0; i < noutputs; i++) { | ||
17138 | if (!spec->multiout.dac_nids[i]) | 17181 | if (!spec->multiout.dac_nids[i]) |
17139 | continue; | 17182 | continue; |
17140 | nid_v = alc861vd_idx_to_mixer_vol( | 17183 | nid_v = alc861vd_idx_to_mixer_vol( |
@@ -17247,7 +17290,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
17247 | { | 17290 | { |
17248 | struct alc_spec *spec = codec->spec; | 17291 | struct alc_spec *spec = codec->spec; |
17249 | int err; | 17292 | int err; |
17250 | static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; | 17293 | static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; |
17251 | 17294 | ||
17252 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 17295 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
17253 | alc861vd_ignore); | 17296 | alc861vd_ignore); |
@@ -17259,6 +17302,9 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) | |||
17259 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); | 17302 | err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); |
17260 | if (err < 0) | 17303 | if (err < 0) |
17261 | return err; | 17304 | return err; |
17305 | err = alc_auto_add_multi_channel_mode(codec); | ||
17306 | if (err < 0) | ||
17307 | return err; | ||
17262 | err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); | 17308 | err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); |
17263 | if (err < 0) | 17309 | if (err < 0) |
17264 | return err; | 17310 | return err; |
@@ -17327,7 +17373,7 @@ static const struct alc_fixup alc861vd_fixups[] = { | |||
17327 | }, | 17373 | }, |
17328 | }; | 17374 | }; |
17329 | 17375 | ||
17330 | static struct snd_pci_quirk alc861vd_fixup_tbl[] = { | 17376 | static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { |
17331 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), | 17377 | SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), |
17332 | {} | 17378 | {} |
17333 | }; | 17379 | }; |
@@ -17410,6 +17456,7 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
17410 | 17456 | ||
17411 | if (board_config == ALC861VD_AUTO) | 17457 | if (board_config == ALC861VD_AUTO) |
17412 | spec->init_hook = alc861vd_auto_init; | 17458 | spec->init_hook = alc861vd_auto_init; |
17459 | spec->shutup = alc_eapd_shutup; | ||
17413 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 17460 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
17414 | if (!spec->loopback.amplist) | 17461 | if (!spec->loopback.amplist) |
17415 | spec->loopback.amplist = alc861vd_loopbacks; | 17462 | spec->loopback.amplist = alc861vd_loopbacks; |
@@ -17432,32 +17479,32 @@ static int patch_alc861vd(struct hda_codec *codec) | |||
17432 | #define ALC662_DIGOUT_NID 0x06 | 17479 | #define ALC662_DIGOUT_NID 0x06 |
17433 | #define ALC662_DIGIN_NID 0x0a | 17480 | #define ALC662_DIGIN_NID 0x0a |
17434 | 17481 | ||
17435 | static hda_nid_t alc662_dac_nids[4] = { | 17482 | static const hda_nid_t alc662_dac_nids[3] = { |
17436 | /* front, rear, clfe, rear_surr */ | 17483 | /* front, rear, clfe */ |
17437 | 0x02, 0x03, 0x04 | 17484 | 0x02, 0x03, 0x04 |
17438 | }; | 17485 | }; |
17439 | 17486 | ||
17440 | static hda_nid_t alc272_dac_nids[2] = { | 17487 | static const hda_nid_t alc272_dac_nids[2] = { |
17441 | 0x02, 0x03 | 17488 | 0x02, 0x03 |
17442 | }; | 17489 | }; |
17443 | 17490 | ||
17444 | static hda_nid_t alc662_adc_nids[2] = { | 17491 | static const hda_nid_t alc662_adc_nids[2] = { |
17445 | /* ADC1-2 */ | 17492 | /* ADC1-2 */ |
17446 | 0x09, 0x08 | 17493 | 0x09, 0x08 |
17447 | }; | 17494 | }; |
17448 | 17495 | ||
17449 | static hda_nid_t alc272_adc_nids[1] = { | 17496 | static const hda_nid_t alc272_adc_nids[1] = { |
17450 | /* ADC1-2 */ | 17497 | /* ADC1-2 */ |
17451 | 0x08, | 17498 | 0x08, |
17452 | }; | 17499 | }; |
17453 | 17500 | ||
17454 | static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; | 17501 | static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; |
17455 | static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; | 17502 | static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; |
17456 | 17503 | ||
17457 | 17504 | ||
17458 | /* input MUX */ | 17505 | /* input MUX */ |
17459 | /* FIXME: should be a matrix-type input source selection */ | 17506 | /* FIXME: should be a matrix-type input source selection */ |
17460 | static struct hda_input_mux alc662_capture_source = { | 17507 | static const struct hda_input_mux alc662_capture_source = { |
17461 | .num_items = 4, | 17508 | .num_items = 4, |
17462 | .items = { | 17509 | .items = { |
17463 | { "Mic", 0x0 }, | 17510 | { "Mic", 0x0 }, |
@@ -17467,7 +17514,7 @@ static struct hda_input_mux alc662_capture_source = { | |||
17467 | }, | 17514 | }, |
17468 | }; | 17515 | }; |
17469 | 17516 | ||
17470 | static struct hda_input_mux alc662_lenovo_101e_capture_source = { | 17517 | static const struct hda_input_mux alc662_lenovo_101e_capture_source = { |
17471 | .num_items = 2, | 17518 | .num_items = 2, |
17472 | .items = { | 17519 | .items = { |
17473 | { "Mic", 0x1 }, | 17520 | { "Mic", 0x1 }, |
@@ -17475,7 +17522,7 @@ static struct hda_input_mux alc662_lenovo_101e_capture_source = { | |||
17475 | }, | 17522 | }, |
17476 | }; | 17523 | }; |
17477 | 17524 | ||
17478 | static struct hda_input_mux alc663_capture_source = { | 17525 | static const struct hda_input_mux alc663_capture_source = { |
17479 | .num_items = 3, | 17526 | .num_items = 3, |
17480 | .items = { | 17527 | .items = { |
17481 | { "Mic", 0x0 }, | 17528 | { "Mic", 0x0 }, |
@@ -17485,7 +17532,7 @@ static struct hda_input_mux alc663_capture_source = { | |||
17485 | }; | 17532 | }; |
17486 | 17533 | ||
17487 | #if 0 /* set to 1 for testing other input sources below */ | 17534 | #if 0 /* set to 1 for testing other input sources below */ |
17488 | static struct hda_input_mux alc272_nc10_capture_source = { | 17535 | static const struct hda_input_mux alc272_nc10_capture_source = { |
17489 | .num_items = 16, | 17536 | .num_items = 16, |
17490 | .items = { | 17537 | .items = { |
17491 | { "Autoselect Mic", 0x0 }, | 17538 | { "Autoselect Mic", 0x0 }, |
@@ -17511,14 +17558,14 @@ static struct hda_input_mux alc272_nc10_capture_source = { | |||
17511 | /* | 17558 | /* |
17512 | * 2ch mode | 17559 | * 2ch mode |
17513 | */ | 17560 | */ |
17514 | static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { | 17561 | static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = { |
17515 | { 2, NULL } | 17562 | { 2, NULL } |
17516 | }; | 17563 | }; |
17517 | 17564 | ||
17518 | /* | 17565 | /* |
17519 | * 2ch mode | 17566 | * 2ch mode |
17520 | */ | 17567 | */ |
17521 | static struct hda_verb alc662_3ST_ch2_init[] = { | 17568 | static const struct hda_verb alc662_3ST_ch2_init[] = { |
17522 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, | 17569 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, |
17523 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, | 17570 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, |
17524 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, | 17571 | { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, |
@@ -17529,7 +17576,7 @@ static struct hda_verb alc662_3ST_ch2_init[] = { | |||
17529 | /* | 17576 | /* |
17530 | * 6ch mode | 17577 | * 6ch mode |
17531 | */ | 17578 | */ |
17532 | static struct hda_verb alc662_3ST_ch6_init[] = { | 17579 | static const struct hda_verb alc662_3ST_ch6_init[] = { |
17533 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 17580 | { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
17534 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, | 17581 | { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, |
17535 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, | 17582 | { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, |
@@ -17539,7 +17586,7 @@ static struct hda_verb alc662_3ST_ch6_init[] = { | |||
17539 | { } /* end */ | 17586 | { } /* end */ |
17540 | }; | 17587 | }; |
17541 | 17588 | ||
17542 | static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { | 17589 | static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = { |
17543 | { 2, alc662_3ST_ch2_init }, | 17590 | { 2, alc662_3ST_ch2_init }, |
17544 | { 6, alc662_3ST_ch6_init }, | 17591 | { 6, alc662_3ST_ch6_init }, |
17545 | }; | 17592 | }; |
@@ -17547,7 +17594,7 @@ static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { | |||
17547 | /* | 17594 | /* |
17548 | * 2ch mode | 17595 | * 2ch mode |
17549 | */ | 17596 | */ |
17550 | static struct hda_verb alc662_sixstack_ch6_init[] = { | 17597 | static const struct hda_verb alc662_sixstack_ch6_init[] = { |
17551 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | 17598 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, |
17552 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, | 17599 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, |
17553 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 17600 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
@@ -17557,14 +17604,14 @@ static struct hda_verb alc662_sixstack_ch6_init[] = { | |||
17557 | /* | 17604 | /* |
17558 | * 6ch mode | 17605 | * 6ch mode |
17559 | */ | 17606 | */ |
17560 | static struct hda_verb alc662_sixstack_ch8_init[] = { | 17607 | static const struct hda_verb alc662_sixstack_ch8_init[] = { |
17561 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 17608 | { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
17562 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 17609 | { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
17563 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, | 17610 | { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, |
17564 | { } /* end */ | 17611 | { } /* end */ |
17565 | }; | 17612 | }; |
17566 | 17613 | ||
17567 | static struct hda_channel_mode alc662_5stack_modes[2] = { | 17614 | static const struct hda_channel_mode alc662_5stack_modes[2] = { |
17568 | { 2, alc662_sixstack_ch6_init }, | 17615 | { 2, alc662_sixstack_ch6_init }, |
17569 | { 6, alc662_sixstack_ch8_init }, | 17616 | { 6, alc662_sixstack_ch8_init }, |
17570 | }; | 17617 | }; |
@@ -17573,7 +17620,7 @@ static struct hda_channel_mode alc662_5stack_modes[2] = { | |||
17573 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b | 17620 | * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b |
17574 | */ | 17621 | */ |
17575 | 17622 | ||
17576 | static struct snd_kcontrol_new alc662_base_mixer[] = { | 17623 | static const struct snd_kcontrol_new alc662_base_mixer[] = { |
17577 | /* output mixer control */ | 17624 | /* output mixer control */ |
17578 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | 17625 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), |
17579 | HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), | 17626 | HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), |
@@ -17597,7 +17644,7 @@ static struct snd_kcontrol_new alc662_base_mixer[] = { | |||
17597 | { } /* end */ | 17644 | { } /* end */ |
17598 | }; | 17645 | }; |
17599 | 17646 | ||
17600 | static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { | 17647 | static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { |
17601 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 17648 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
17602 | HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), | 17649 | HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), |
17603 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 17650 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
@@ -17612,7 +17659,7 @@ static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { | |||
17612 | { } /* end */ | 17659 | { } /* end */ |
17613 | }; | 17660 | }; |
17614 | 17661 | ||
17615 | static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { | 17662 | static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { |
17616 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 17663 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
17617 | HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), | 17664 | HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), |
17618 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 17665 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
@@ -17633,7 +17680,7 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { | |||
17633 | { } /* end */ | 17680 | { } /* end */ |
17634 | }; | 17681 | }; |
17635 | 17682 | ||
17636 | static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { | 17683 | static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { |
17637 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 17684 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
17638 | HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), | 17685 | HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), |
17639 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 17686 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
@@ -17646,7 +17693,7 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { | |||
17646 | { } /* end */ | 17693 | { } /* end */ |
17647 | }; | 17694 | }; |
17648 | 17695 | ||
17649 | static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { | 17696 | static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { |
17650 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 17697 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
17651 | ALC262_HIPPO_MASTER_SWITCH, | 17698 | ALC262_HIPPO_MASTER_SWITCH, |
17652 | 17699 | ||
@@ -17660,7 +17707,7 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { | |||
17660 | { } /* end */ | 17707 | { } /* end */ |
17661 | }; | 17708 | }; |
17662 | 17709 | ||
17663 | static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { | 17710 | static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { |
17664 | ALC262_HIPPO_MASTER_SWITCH, | 17711 | ALC262_HIPPO_MASTER_SWITCH, |
17665 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 17712 | HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
17666 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 17713 | HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
@@ -17674,7 +17721,7 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { | |||
17674 | { } /* end */ | 17721 | { } /* end */ |
17675 | }; | 17722 | }; |
17676 | 17723 | ||
17677 | static struct hda_bind_ctls alc663_asus_bind_master_vol = { | 17724 | static const struct hda_bind_ctls alc663_asus_bind_master_vol = { |
17678 | .ops = &snd_hda_bind_vol, | 17725 | .ops = &snd_hda_bind_vol, |
17679 | .values = { | 17726 | .values = { |
17680 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | 17727 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), |
@@ -17683,7 +17730,7 @@ static struct hda_bind_ctls alc663_asus_bind_master_vol = { | |||
17683 | }, | 17730 | }, |
17684 | }; | 17731 | }; |
17685 | 17732 | ||
17686 | static struct hda_bind_ctls alc663_asus_one_bind_switch = { | 17733 | static const struct hda_bind_ctls alc663_asus_one_bind_switch = { |
17687 | .ops = &snd_hda_bind_sw, | 17734 | .ops = &snd_hda_bind_sw, |
17688 | .values = { | 17735 | .values = { |
17689 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | 17736 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), |
@@ -17692,7 +17739,7 @@ static struct hda_bind_ctls alc663_asus_one_bind_switch = { | |||
17692 | }, | 17739 | }, |
17693 | }; | 17740 | }; |
17694 | 17741 | ||
17695 | static struct snd_kcontrol_new alc663_m51va_mixer[] = { | 17742 | static const struct snd_kcontrol_new alc663_m51va_mixer[] = { |
17696 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), | 17743 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), |
17697 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), | 17744 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), |
17698 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 17745 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -17700,7 +17747,7 @@ static struct snd_kcontrol_new alc663_m51va_mixer[] = { | |||
17700 | { } /* end */ | 17747 | { } /* end */ |
17701 | }; | 17748 | }; |
17702 | 17749 | ||
17703 | static struct hda_bind_ctls alc663_asus_tree_bind_switch = { | 17750 | static const struct hda_bind_ctls alc663_asus_tree_bind_switch = { |
17704 | .ops = &snd_hda_bind_sw, | 17751 | .ops = &snd_hda_bind_sw, |
17705 | .values = { | 17752 | .values = { |
17706 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | 17753 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), |
@@ -17710,7 +17757,7 @@ static struct hda_bind_ctls alc663_asus_tree_bind_switch = { | |||
17710 | }, | 17757 | }, |
17711 | }; | 17758 | }; |
17712 | 17759 | ||
17713 | static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { | 17760 | static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { |
17714 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), | 17761 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), |
17715 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), | 17762 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), |
17716 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 17763 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -17721,7 +17768,7 @@ static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { | |||
17721 | { } /* end */ | 17768 | { } /* end */ |
17722 | }; | 17769 | }; |
17723 | 17770 | ||
17724 | static struct hda_bind_ctls alc663_asus_four_bind_switch = { | 17771 | static const struct hda_bind_ctls alc663_asus_four_bind_switch = { |
17725 | .ops = &snd_hda_bind_sw, | 17772 | .ops = &snd_hda_bind_sw, |
17726 | .values = { | 17773 | .values = { |
17727 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | 17774 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), |
@@ -17731,7 +17778,7 @@ static struct hda_bind_ctls alc663_asus_four_bind_switch = { | |||
17731 | }, | 17778 | }, |
17732 | }; | 17779 | }; |
17733 | 17780 | ||
17734 | static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { | 17781 | static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { |
17735 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), | 17782 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), |
17736 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), | 17783 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), |
17737 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), | 17784 | HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), |
@@ -17741,7 +17788,7 @@ static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { | |||
17741 | { } /* end */ | 17788 | { } /* end */ |
17742 | }; | 17789 | }; |
17743 | 17790 | ||
17744 | static struct snd_kcontrol_new alc662_1bjd_mixer[] = { | 17791 | static const struct snd_kcontrol_new alc662_1bjd_mixer[] = { |
17745 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 17792 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
17746 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 17793 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
17747 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), | 17794 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), |
@@ -17752,7 +17799,7 @@ static struct snd_kcontrol_new alc662_1bjd_mixer[] = { | |||
17752 | { } /* end */ | 17799 | { } /* end */ |
17753 | }; | 17800 | }; |
17754 | 17801 | ||
17755 | static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { | 17802 | static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = { |
17756 | .ops = &snd_hda_bind_vol, | 17803 | .ops = &snd_hda_bind_vol, |
17757 | .values = { | 17804 | .values = { |
17758 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), | 17805 | HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), |
@@ -17761,7 +17808,7 @@ static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { | |||
17761 | }, | 17808 | }, |
17762 | }; | 17809 | }; |
17763 | 17810 | ||
17764 | static struct hda_bind_ctls alc663_asus_two_bind_switch = { | 17811 | static const struct hda_bind_ctls alc663_asus_two_bind_switch = { |
17765 | .ops = &snd_hda_bind_sw, | 17812 | .ops = &snd_hda_bind_sw, |
17766 | .values = { | 17813 | .values = { |
17767 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | 17814 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), |
@@ -17770,7 +17817,7 @@ static struct hda_bind_ctls alc663_asus_two_bind_switch = { | |||
17770 | }, | 17817 | }, |
17771 | }; | 17818 | }; |
17772 | 17819 | ||
17773 | static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { | 17820 | static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { |
17774 | HDA_BIND_VOL("Master Playback Volume", | 17821 | HDA_BIND_VOL("Master Playback Volume", |
17775 | &alc663_asus_two_bind_master_vol), | 17822 | &alc663_asus_two_bind_master_vol), |
17776 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), | 17823 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), |
@@ -17781,7 +17828,7 @@ static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { | |||
17781 | { } /* end */ | 17828 | { } /* end */ |
17782 | }; | 17829 | }; |
17783 | 17830 | ||
17784 | static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { | 17831 | static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { |
17785 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), | 17832 | HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), |
17786 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), | 17833 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), |
17787 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 17834 | HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
@@ -17791,7 +17838,7 @@ static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { | |||
17791 | { } /* end */ | 17838 | { } /* end */ |
17792 | }; | 17839 | }; |
17793 | 17840 | ||
17794 | static struct snd_kcontrol_new alc663_g71v_mixer[] = { | 17841 | static const struct snd_kcontrol_new alc663_g71v_mixer[] = { |
17795 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 17842 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
17796 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 17843 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
17797 | HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), | 17844 | HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), |
@@ -17805,7 +17852,7 @@ static struct snd_kcontrol_new alc663_g71v_mixer[] = { | |||
17805 | { } /* end */ | 17852 | { } /* end */ |
17806 | }; | 17853 | }; |
17807 | 17854 | ||
17808 | static struct snd_kcontrol_new alc663_g50v_mixer[] = { | 17855 | static const struct snd_kcontrol_new alc663_g50v_mixer[] = { |
17809 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 17856 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
17810 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 17857 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
17811 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), | 17858 | HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), |
@@ -17819,7 +17866,7 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = { | |||
17819 | { } /* end */ | 17866 | { } /* end */ |
17820 | }; | 17867 | }; |
17821 | 17868 | ||
17822 | static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { | 17869 | static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { |
17823 | .ops = &snd_hda_bind_sw, | 17870 | .ops = &snd_hda_bind_sw, |
17824 | .values = { | 17871 | .values = { |
17825 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | 17872 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), |
@@ -17831,7 +17878,7 @@ static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { | |||
17831 | }, | 17878 | }, |
17832 | }; | 17879 | }; |
17833 | 17880 | ||
17834 | static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { | 17881 | static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { |
17835 | .ops = &snd_hda_bind_sw, | 17882 | .ops = &snd_hda_bind_sw, |
17836 | .values = { | 17883 | .values = { |
17837 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | 17884 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), |
@@ -17840,7 +17887,7 @@ static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { | |||
17840 | }, | 17887 | }, |
17841 | }; | 17888 | }; |
17842 | 17889 | ||
17843 | static struct snd_kcontrol_new alc663_mode7_mixer[] = { | 17890 | static const struct snd_kcontrol_new alc663_mode7_mixer[] = { |
17844 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), | 17891 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), |
17845 | HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), | 17892 | HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), |
17846 | HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), | 17893 | HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), |
@@ -17853,7 +17900,7 @@ static struct snd_kcontrol_new alc663_mode7_mixer[] = { | |||
17853 | { } /* end */ | 17900 | { } /* end */ |
17854 | }; | 17901 | }; |
17855 | 17902 | ||
17856 | static struct snd_kcontrol_new alc663_mode8_mixer[] = { | 17903 | static const struct snd_kcontrol_new alc663_mode8_mixer[] = { |
17857 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), | 17904 | HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), |
17858 | HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), | 17905 | HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), |
17859 | HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), | 17906 | HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), |
@@ -17865,7 +17912,7 @@ static struct snd_kcontrol_new alc663_mode8_mixer[] = { | |||
17865 | }; | 17912 | }; |
17866 | 17913 | ||
17867 | 17914 | ||
17868 | static struct snd_kcontrol_new alc662_chmode_mixer[] = { | 17915 | static const struct snd_kcontrol_new alc662_chmode_mixer[] = { |
17869 | { | 17916 | { |
17870 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 17917 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
17871 | .name = "Channel Mode", | 17918 | .name = "Channel Mode", |
@@ -17876,7 +17923,7 @@ static struct snd_kcontrol_new alc662_chmode_mixer[] = { | |||
17876 | { } /* end */ | 17923 | { } /* end */ |
17877 | }; | 17924 | }; |
17878 | 17925 | ||
17879 | static struct hda_verb alc662_init_verbs[] = { | 17926 | static const struct hda_verb alc662_init_verbs[] = { |
17880 | /* ADC: mute amp left and right */ | 17927 | /* ADC: mute amp left and right */ |
17881 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 17928 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
17882 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, | 17929 | {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, |
@@ -17922,55 +17969,36 @@ static struct hda_verb alc662_init_verbs[] = { | |||
17922 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 17969 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
17923 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 17970 | {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
17924 | 17971 | ||
17925 | /* always trun on EAPD */ | ||
17926 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
17927 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, | ||
17928 | |||
17929 | { } | ||
17930 | }; | ||
17931 | |||
17932 | static struct hda_verb alc663_init_verbs[] = { | ||
17933 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
17934 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
17935 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
17936 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
17937 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
17938 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
17939 | { } | 17972 | { } |
17940 | }; | 17973 | }; |
17941 | 17974 | ||
17942 | static struct hda_verb alc272_init_verbs[] = { | 17975 | static const struct hda_verb alc662_eapd_init_verbs[] = { |
17943 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 17976 | /* always trun on EAPD */ |
17944 | {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, | 17977 | {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
17945 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 17978 | {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, |
17946 | {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
17947 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | ||
17948 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | ||
17949 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
17950 | {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
17951 | { } | 17979 | { } |
17952 | }; | 17980 | }; |
17953 | 17981 | ||
17954 | static struct hda_verb alc662_sue_init_verbs[] = { | 17982 | static const struct hda_verb alc662_sue_init_verbs[] = { |
17955 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, | 17983 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, |
17956 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, | 17984 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, |
17957 | {} | 17985 | {} |
17958 | }; | 17986 | }; |
17959 | 17987 | ||
17960 | static struct hda_verb alc662_eeepc_sue_init_verbs[] = { | 17988 | static const struct hda_verb alc662_eeepc_sue_init_verbs[] = { |
17961 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | 17989 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, |
17962 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | 17990 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
17963 | {} | 17991 | {} |
17964 | }; | 17992 | }; |
17965 | 17993 | ||
17966 | /* Set Unsolicited Event*/ | 17994 | /* Set Unsolicited Event*/ |
17967 | static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { | 17995 | static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { |
17968 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 17996 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
17969 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, | 17997 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, |
17970 | {} | 17998 | {} |
17971 | }; | 17999 | }; |
17972 | 18000 | ||
17973 | static struct hda_verb alc663_m51va_init_verbs[] = { | 18001 | static const struct hda_verb alc663_m51va_init_verbs[] = { |
17974 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18002 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
17975 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18003 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
17976 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 18004 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
@@ -17983,7 +18011,7 @@ static struct hda_verb alc663_m51va_init_verbs[] = { | |||
17983 | {} | 18011 | {} |
17984 | }; | 18012 | }; |
17985 | 18013 | ||
17986 | static struct hda_verb alc663_21jd_amic_init_verbs[] = { | 18014 | static const struct hda_verb alc663_21jd_amic_init_verbs[] = { |
17987 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 18015 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
17988 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 18016 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
17989 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | 18017 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ |
@@ -17994,7 +18022,7 @@ static struct hda_verb alc663_21jd_amic_init_verbs[] = { | |||
17994 | {} | 18022 | {} |
17995 | }; | 18023 | }; |
17996 | 18024 | ||
17997 | static struct hda_verb alc662_1bjd_amic_init_verbs[] = { | 18025 | static const struct hda_verb alc662_1bjd_amic_init_verbs[] = { |
17998 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18026 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
17999 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 18027 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
18000 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 18028 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -18006,7 +18034,7 @@ static struct hda_verb alc662_1bjd_amic_init_verbs[] = { | |||
18006 | {} | 18034 | {} |
18007 | }; | 18035 | }; |
18008 | 18036 | ||
18009 | static struct hda_verb alc663_15jd_amic_init_verbs[] = { | 18037 | static const struct hda_verb alc663_15jd_amic_init_verbs[] = { |
18010 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 18038 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
18011 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 18039 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
18012 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ | 18040 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ |
@@ -18017,7 +18045,7 @@ static struct hda_verb alc663_15jd_amic_init_verbs[] = { | |||
18017 | {} | 18045 | {} |
18018 | }; | 18046 | }; |
18019 | 18047 | ||
18020 | static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { | 18048 | static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { |
18021 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18049 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
18022 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 18050 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
18023 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 18051 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -18033,7 +18061,7 @@ static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { | |||
18033 | {} | 18061 | {} |
18034 | }; | 18062 | }; |
18035 | 18063 | ||
18036 | static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { | 18064 | static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { |
18037 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18065 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
18038 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 18066 | {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
18039 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 18067 | {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -18049,7 +18077,7 @@ static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { | |||
18049 | {} | 18077 | {} |
18050 | }; | 18078 | }; |
18051 | 18079 | ||
18052 | static struct hda_verb alc663_g71v_init_verbs[] = { | 18080 | static const struct hda_verb alc663_g71v_init_verbs[] = { |
18053 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 18081 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
18054 | /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ | 18082 | /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ |
18055 | /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ | 18083 | /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ |
@@ -18064,7 +18092,7 @@ static struct hda_verb alc663_g71v_init_verbs[] = { | |||
18064 | {} | 18092 | {} |
18065 | }; | 18093 | }; |
18066 | 18094 | ||
18067 | static struct hda_verb alc663_g50v_init_verbs[] = { | 18095 | static const struct hda_verb alc663_g50v_init_verbs[] = { |
18068 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 18096 | {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
18069 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 18097 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
18070 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ | 18098 | {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ |
@@ -18074,7 +18102,7 @@ static struct hda_verb alc663_g50v_init_verbs[] = { | |||
18074 | {} | 18102 | {} |
18075 | }; | 18103 | }; |
18076 | 18104 | ||
18077 | static struct hda_verb alc662_ecs_init_verbs[] = { | 18105 | static const struct hda_verb alc662_ecs_init_verbs[] = { |
18078 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, | 18106 | {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, |
18079 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | 18107 | {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, |
18080 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, | 18108 | {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, |
@@ -18082,7 +18110,7 @@ static struct hda_verb alc662_ecs_init_verbs[] = { | |||
18082 | {} | 18110 | {} |
18083 | }; | 18111 | }; |
18084 | 18112 | ||
18085 | static struct hda_verb alc272_dell_zm1_init_verbs[] = { | 18113 | static const struct hda_verb alc272_dell_zm1_init_verbs[] = { |
18086 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18114 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
18087 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18115 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
18088 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18116 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
@@ -18097,7 +18125,7 @@ static struct hda_verb alc272_dell_zm1_init_verbs[] = { | |||
18097 | {} | 18125 | {} |
18098 | }; | 18126 | }; |
18099 | 18127 | ||
18100 | static struct hda_verb alc272_dell_init_verbs[] = { | 18128 | static const struct hda_verb alc272_dell_init_verbs[] = { |
18101 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18129 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
18102 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18130 | {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
18103 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18131 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
@@ -18112,7 +18140,7 @@ static struct hda_verb alc272_dell_init_verbs[] = { | |||
18112 | {} | 18140 | {} |
18113 | }; | 18141 | }; |
18114 | 18142 | ||
18115 | static struct hda_verb alc663_mode7_init_verbs[] = { | 18143 | static const struct hda_verb alc663_mode7_init_verbs[] = { |
18116 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18144 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
18117 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18145 | {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
18118 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, | 18146 | {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, |
@@ -18131,7 +18159,7 @@ static struct hda_verb alc663_mode7_init_verbs[] = { | |||
18131 | {} | 18159 | {} |
18132 | }; | 18160 | }; |
18133 | 18161 | ||
18134 | static struct hda_verb alc663_mode8_init_verbs[] = { | 18162 | static const struct hda_verb alc663_mode8_init_verbs[] = { |
18135 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, | 18163 | {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, |
18136 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, | 18164 | {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, |
18137 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 18165 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -18151,61 +18179,29 @@ static struct hda_verb alc663_mode8_init_verbs[] = { | |||
18151 | {} | 18179 | {} |
18152 | }; | 18180 | }; |
18153 | 18181 | ||
18154 | static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { | 18182 | static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = { |
18155 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), | 18183 | HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), |
18156 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), | 18184 | HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), |
18157 | { } /* end */ | 18185 | { } /* end */ |
18158 | }; | 18186 | }; |
18159 | 18187 | ||
18160 | static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { | 18188 | static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = { |
18161 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), | 18189 | HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), |
18162 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), | 18190 | HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), |
18163 | { } /* end */ | 18191 | { } /* end */ |
18164 | }; | 18192 | }; |
18165 | 18193 | ||
18166 | static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) | 18194 | static void alc662_lenovo_101e_setup(struct hda_codec *codec) |
18167 | { | 18195 | { |
18168 | unsigned int present; | 18196 | struct alc_spec *spec = codec->spec; |
18169 | unsigned char bits; | ||
18170 | |||
18171 | present = snd_hda_jack_detect(codec, 0x14); | ||
18172 | bits = present ? HDA_AMP_MUTE : 0; | ||
18173 | |||
18174 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
18175 | HDA_AMP_MUTE, bits); | ||
18176 | } | ||
18177 | |||
18178 | static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) | ||
18179 | { | ||
18180 | unsigned int present; | ||
18181 | unsigned char bits; | ||
18182 | |||
18183 | present = snd_hda_jack_detect(codec, 0x1b); | ||
18184 | bits = present ? HDA_AMP_MUTE : 0; | ||
18185 | |||
18186 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
18187 | HDA_AMP_MUTE, bits); | ||
18188 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
18189 | HDA_AMP_MUTE, bits); | ||
18190 | } | ||
18191 | |||
18192 | static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, | ||
18193 | unsigned int res) | ||
18194 | { | ||
18195 | if ((res >> 26) == ALC880_HP_EVENT) | ||
18196 | alc662_lenovo_101e_all_automute(codec); | ||
18197 | if ((res >> 26) == ALC880_FRONT_EVENT) | ||
18198 | alc662_lenovo_101e_ispeaker_automute(codec); | ||
18199 | } | ||
18200 | 18197 | ||
18201 | /* unsolicited event for HP jack sensing */ | 18198 | spec->autocfg.hp_pins[0] = 0x1b; |
18202 | static void alc662_eeepc_unsol_event(struct hda_codec *codec, | 18199 | spec->autocfg.line_out_pins[0] = 0x14; |
18203 | unsigned int res) | 18200 | spec->autocfg.speaker_pins[0] = 0x15; |
18204 | { | 18201 | spec->automute = 1; |
18205 | if ((res >> 26) == ALC880_MIC_EVENT) | 18202 | spec->detect_line = 1; |
18206 | alc_mic_automute(codec); | 18203 | spec->automute_lines = 1; |
18207 | else | 18204 | spec->automute_mode = ALC_AUTOMUTE_AMP; |
18208 | alc262_hippo_unsol_event(codec, res); | ||
18209 | } | 18205 | } |
18210 | 18206 | ||
18211 | static void alc662_eeepc_setup(struct hda_codec *codec) | 18207 | static void alc662_eeepc_setup(struct hda_codec *codec) |
@@ -18220,180 +18216,24 @@ static void alc662_eeepc_setup(struct hda_codec *codec) | |||
18220 | spec->auto_mic = 1; | 18216 | spec->auto_mic = 1; |
18221 | } | 18217 | } |
18222 | 18218 | ||
18223 | static void alc662_eeepc_inithook(struct hda_codec *codec) | ||
18224 | { | ||
18225 | alc262_hippo_automute(codec); | ||
18226 | alc_mic_automute(codec); | ||
18227 | } | ||
18228 | |||
18229 | static void alc662_eeepc_ep20_setup(struct hda_codec *codec) | 18219 | static void alc662_eeepc_ep20_setup(struct hda_codec *codec) |
18230 | { | 18220 | { |
18231 | struct alc_spec *spec = codec->spec; | 18221 | struct alc_spec *spec = codec->spec; |
18232 | 18222 | ||
18233 | spec->autocfg.hp_pins[0] = 0x14; | 18223 | spec->autocfg.hp_pins[0] = 0x14; |
18234 | spec->autocfg.speaker_pins[0] = 0x1b; | 18224 | spec->autocfg.speaker_pins[0] = 0x1b; |
18235 | } | 18225 | spec->automute = 1; |
18236 | 18226 | spec->automute_mode = ALC_AUTOMUTE_AMP; | |
18237 | #define alc662_eeepc_ep20_inithook alc262_hippo_master_update | ||
18238 | |||
18239 | static void alc663_m51va_speaker_automute(struct hda_codec *codec) | ||
18240 | { | ||
18241 | unsigned int present; | ||
18242 | unsigned char bits; | ||
18243 | |||
18244 | present = snd_hda_jack_detect(codec, 0x21); | ||
18245 | bits = present ? HDA_AMP_MUTE : 0; | ||
18246 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | ||
18247 | HDA_AMP_MUTE, bits); | ||
18248 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | ||
18249 | HDA_AMP_MUTE, bits); | ||
18250 | } | ||
18251 | |||
18252 | static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) | ||
18253 | { | ||
18254 | unsigned int present; | ||
18255 | unsigned char bits; | ||
18256 | |||
18257 | present = snd_hda_jack_detect(codec, 0x21); | ||
18258 | bits = present ? HDA_AMP_MUTE : 0; | ||
18259 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | ||
18260 | HDA_AMP_MUTE, bits); | ||
18261 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | ||
18262 | HDA_AMP_MUTE, bits); | ||
18263 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, | ||
18264 | HDA_AMP_MUTE, bits); | ||
18265 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, | ||
18266 | HDA_AMP_MUTE, bits); | ||
18267 | } | ||
18268 | |||
18269 | static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) | ||
18270 | { | ||
18271 | unsigned int present; | ||
18272 | unsigned char bits; | ||
18273 | |||
18274 | present = snd_hda_jack_detect(codec, 0x15); | ||
18275 | bits = present ? HDA_AMP_MUTE : 0; | ||
18276 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | ||
18277 | HDA_AMP_MUTE, bits); | ||
18278 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | ||
18279 | HDA_AMP_MUTE, bits); | ||
18280 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, | ||
18281 | HDA_AMP_MUTE, bits); | ||
18282 | snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, | ||
18283 | HDA_AMP_MUTE, bits); | ||
18284 | } | ||
18285 | |||
18286 | static void alc662_f5z_speaker_automute(struct hda_codec *codec) | ||
18287 | { | ||
18288 | unsigned int present; | ||
18289 | unsigned char bits; | ||
18290 | |||
18291 | present = snd_hda_jack_detect(codec, 0x1b); | ||
18292 | bits = present ? 0 : PIN_OUT; | ||
18293 | snd_hda_codec_write(codec, 0x14, 0, | ||
18294 | AC_VERB_SET_PIN_WIDGET_CONTROL, bits); | ||
18295 | } | ||
18296 | |||
18297 | static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) | ||
18298 | { | ||
18299 | unsigned int present1, present2; | ||
18300 | |||
18301 | present1 = snd_hda_jack_detect(codec, 0x21); | ||
18302 | present2 = snd_hda_jack_detect(codec, 0x15); | ||
18303 | |||
18304 | if (present1 || present2) { | ||
18305 | snd_hda_codec_write_cache(codec, 0x14, 0, | ||
18306 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
18307 | } else { | ||
18308 | snd_hda_codec_write_cache(codec, 0x14, 0, | ||
18309 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
18310 | } | ||
18311 | } | ||
18312 | |||
18313 | static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) | ||
18314 | { | ||
18315 | unsigned int present1, present2; | ||
18316 | |||
18317 | present1 = snd_hda_jack_detect(codec, 0x1b); | ||
18318 | present2 = snd_hda_jack_detect(codec, 0x15); | ||
18319 | |||
18320 | if (present1 || present2) { | ||
18321 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | ||
18322 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
18323 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | ||
18324 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
18325 | } else { | ||
18326 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, | ||
18327 | HDA_AMP_MUTE, 0); | ||
18328 | snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, | ||
18329 | HDA_AMP_MUTE, 0); | ||
18330 | } | ||
18331 | } | ||
18332 | |||
18333 | static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) | ||
18334 | { | ||
18335 | unsigned int present1, present2; | ||
18336 | |||
18337 | present1 = snd_hda_codec_read(codec, 0x1b, 0, | ||
18338 | AC_VERB_GET_PIN_SENSE, 0) | ||
18339 | & AC_PINSENSE_PRESENCE; | ||
18340 | present2 = snd_hda_codec_read(codec, 0x21, 0, | ||
18341 | AC_VERB_GET_PIN_SENSE, 0) | ||
18342 | & AC_PINSENSE_PRESENCE; | ||
18343 | |||
18344 | if (present1 || present2) { | ||
18345 | snd_hda_codec_write_cache(codec, 0x14, 0, | ||
18346 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
18347 | snd_hda_codec_write_cache(codec, 0x17, 0, | ||
18348 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
18349 | } else { | ||
18350 | snd_hda_codec_write_cache(codec, 0x14, 0, | ||
18351 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
18352 | snd_hda_codec_write_cache(codec, 0x17, 0, | ||
18353 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
18354 | } | ||
18355 | } | ||
18356 | |||
18357 | static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) | ||
18358 | { | ||
18359 | unsigned int present1, present2; | ||
18360 | |||
18361 | present1 = snd_hda_codec_read(codec, 0x21, 0, | ||
18362 | AC_VERB_GET_PIN_SENSE, 0) | ||
18363 | & AC_PINSENSE_PRESENCE; | ||
18364 | present2 = snd_hda_codec_read(codec, 0x15, 0, | ||
18365 | AC_VERB_GET_PIN_SENSE, 0) | ||
18366 | & AC_PINSENSE_PRESENCE; | ||
18367 | |||
18368 | if (present1 || present2) { | ||
18369 | snd_hda_codec_write_cache(codec, 0x14, 0, | ||
18370 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
18371 | snd_hda_codec_write_cache(codec, 0x17, 0, | ||
18372 | AC_VERB_SET_PIN_WIDGET_CONTROL, 0); | ||
18373 | } else { | ||
18374 | snd_hda_codec_write_cache(codec, 0x14, 0, | ||
18375 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
18376 | snd_hda_codec_write_cache(codec, 0x17, 0, | ||
18377 | AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); | ||
18378 | } | ||
18379 | } | ||
18380 | |||
18381 | static void alc663_m51va_unsol_event(struct hda_codec *codec, | ||
18382 | unsigned int res) | ||
18383 | { | ||
18384 | switch (res >> 26) { | ||
18385 | case ALC880_HP_EVENT: | ||
18386 | alc663_m51va_speaker_automute(codec); | ||
18387 | break; | ||
18388 | case ALC880_MIC_EVENT: | ||
18389 | alc_mic_automute(codec); | ||
18390 | break; | ||
18391 | } | ||
18392 | } | 18227 | } |
18393 | 18228 | ||
18394 | static void alc663_m51va_setup(struct hda_codec *codec) | 18229 | static void alc663_m51va_setup(struct hda_codec *codec) |
18395 | { | 18230 | { |
18396 | struct alc_spec *spec = codec->spec; | 18231 | struct alc_spec *spec = codec->spec; |
18232 | spec->autocfg.hp_pins[0] = 0x21; | ||
18233 | spec->autocfg.speaker_pins[0] = 0x14; | ||
18234 | spec->automute_mixer_nid[0] = 0x0c; | ||
18235 | spec->automute = 1; | ||
18236 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
18397 | spec->ext_mic.pin = 0x18; | 18237 | spec->ext_mic.pin = 0x18; |
18398 | spec->ext_mic.mux_idx = 0; | 18238 | spec->ext_mic.mux_idx = 0; |
18399 | spec->int_mic.pin = 0x12; | 18239 | spec->int_mic.pin = 0x12; |
@@ -18401,18 +18241,15 @@ static void alc663_m51va_setup(struct hda_codec *codec) | |||
18401 | spec->auto_mic = 1; | 18241 | spec->auto_mic = 1; |
18402 | } | 18242 | } |
18403 | 18243 | ||
18404 | static void alc663_m51va_inithook(struct hda_codec *codec) | ||
18405 | { | ||
18406 | alc663_m51va_speaker_automute(codec); | ||
18407 | alc_mic_automute(codec); | ||
18408 | } | ||
18409 | |||
18410 | /* ***************** Mode1 ******************************/ | 18244 | /* ***************** Mode1 ******************************/ |
18411 | #define alc663_mode1_unsol_event alc663_m51va_unsol_event | ||
18412 | |||
18413 | static void alc663_mode1_setup(struct hda_codec *codec) | 18245 | static void alc663_mode1_setup(struct hda_codec *codec) |
18414 | { | 18246 | { |
18415 | struct alc_spec *spec = codec->spec; | 18247 | struct alc_spec *spec = codec->spec; |
18248 | spec->autocfg.hp_pins[0] = 0x21; | ||
18249 | spec->autocfg.speaker_pins[0] = 0x14; | ||
18250 | spec->automute_mixer_nid[0] = 0x0c; | ||
18251 | spec->automute = 1; | ||
18252 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
18416 | spec->ext_mic.pin = 0x18; | 18253 | spec->ext_mic.pin = 0x18; |
18417 | spec->ext_mic.mux_idx = 0; | 18254 | spec->ext_mic.mux_idx = 0; |
18418 | spec->int_mic.pin = 0x19; | 18255 | spec->int_mic.pin = 0x19; |
@@ -18420,229 +18257,144 @@ static void alc663_mode1_setup(struct hda_codec *codec) | |||
18420 | spec->auto_mic = 1; | 18257 | spec->auto_mic = 1; |
18421 | } | 18258 | } |
18422 | 18259 | ||
18423 | #define alc663_mode1_inithook alc663_m51va_inithook | ||
18424 | |||
18425 | /* ***************** Mode2 ******************************/ | 18260 | /* ***************** Mode2 ******************************/ |
18426 | static void alc662_mode2_unsol_event(struct hda_codec *codec, | 18261 | static void alc662_mode2_setup(struct hda_codec *codec) |
18427 | unsigned int res) | ||
18428 | { | 18262 | { |
18429 | switch (res >> 26) { | 18263 | struct alc_spec *spec = codec->spec; |
18430 | case ALC880_HP_EVENT: | 18264 | spec->autocfg.hp_pins[0] = 0x1b; |
18431 | alc662_f5z_speaker_automute(codec); | 18265 | spec->autocfg.speaker_pins[0] = 0x14; |
18432 | break; | 18266 | spec->automute = 1; |
18433 | case ALC880_MIC_EVENT: | 18267 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
18434 | alc_mic_automute(codec); | 18268 | spec->ext_mic.pin = 0x18; |
18435 | break; | 18269 | spec->ext_mic.mux_idx = 0; |
18436 | } | 18270 | spec->int_mic.pin = 0x19; |
18271 | spec->int_mic.mux_idx = 1; | ||
18272 | spec->auto_mic = 1; | ||
18437 | } | 18273 | } |
18438 | 18274 | ||
18439 | #define alc662_mode2_setup alc663_mode1_setup | ||
18440 | |||
18441 | static void alc662_mode2_inithook(struct hda_codec *codec) | ||
18442 | { | ||
18443 | alc662_f5z_speaker_automute(codec); | ||
18444 | alc_mic_automute(codec); | ||
18445 | } | ||
18446 | /* ***************** Mode3 ******************************/ | 18275 | /* ***************** Mode3 ******************************/ |
18447 | static void alc663_mode3_unsol_event(struct hda_codec *codec, | 18276 | static void alc663_mode3_setup(struct hda_codec *codec) |
18448 | unsigned int res) | ||
18449 | { | 18277 | { |
18450 | switch (res >> 26) { | 18278 | struct alc_spec *spec = codec->spec; |
18451 | case ALC880_HP_EVENT: | 18279 | spec->autocfg.hp_pins[0] = 0x21; |
18452 | alc663_two_hp_m1_speaker_automute(codec); | 18280 | spec->autocfg.hp_pins[0] = 0x15; |
18453 | break; | 18281 | spec->autocfg.speaker_pins[0] = 0x14; |
18454 | case ALC880_MIC_EVENT: | 18282 | spec->automute = 1; |
18455 | alc_mic_automute(codec); | 18283 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
18456 | break; | 18284 | spec->ext_mic.pin = 0x18; |
18457 | } | 18285 | spec->ext_mic.mux_idx = 0; |
18286 | spec->int_mic.pin = 0x19; | ||
18287 | spec->int_mic.mux_idx = 1; | ||
18288 | spec->auto_mic = 1; | ||
18458 | } | 18289 | } |
18459 | 18290 | ||
18460 | #define alc663_mode3_setup alc663_mode1_setup | ||
18461 | |||
18462 | static void alc663_mode3_inithook(struct hda_codec *codec) | ||
18463 | { | ||
18464 | alc663_two_hp_m1_speaker_automute(codec); | ||
18465 | alc_mic_automute(codec); | ||
18466 | } | ||
18467 | /* ***************** Mode4 ******************************/ | 18291 | /* ***************** Mode4 ******************************/ |
18468 | static void alc663_mode4_unsol_event(struct hda_codec *codec, | 18292 | static void alc663_mode4_setup(struct hda_codec *codec) |
18469 | unsigned int res) | ||
18470 | { | 18293 | { |
18471 | switch (res >> 26) { | 18294 | struct alc_spec *spec = codec->spec; |
18472 | case ALC880_HP_EVENT: | 18295 | spec->autocfg.hp_pins[0] = 0x21; |
18473 | alc663_21jd_two_speaker_automute(codec); | 18296 | spec->autocfg.speaker_pins[0] = 0x14; |
18474 | break; | 18297 | spec->autocfg.speaker_pins[1] = 0x16; |
18475 | case ALC880_MIC_EVENT: | 18298 | spec->automute_mixer_nid[0] = 0x0c; |
18476 | alc_mic_automute(codec); | 18299 | spec->automute_mixer_nid[1] = 0x0e; |
18477 | break; | 18300 | spec->automute = 1; |
18478 | } | 18301 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
18302 | spec->ext_mic.pin = 0x18; | ||
18303 | spec->ext_mic.mux_idx = 0; | ||
18304 | spec->int_mic.pin = 0x19; | ||
18305 | spec->int_mic.mux_idx = 1; | ||
18306 | spec->auto_mic = 1; | ||
18479 | } | 18307 | } |
18480 | 18308 | ||
18481 | #define alc663_mode4_setup alc663_mode1_setup | ||
18482 | |||
18483 | static void alc663_mode4_inithook(struct hda_codec *codec) | ||
18484 | { | ||
18485 | alc663_21jd_two_speaker_automute(codec); | ||
18486 | alc_mic_automute(codec); | ||
18487 | } | ||
18488 | /* ***************** Mode5 ******************************/ | 18309 | /* ***************** Mode5 ******************************/ |
18489 | static void alc663_mode5_unsol_event(struct hda_codec *codec, | 18310 | static void alc663_mode5_setup(struct hda_codec *codec) |
18490 | unsigned int res) | ||
18491 | { | 18311 | { |
18492 | switch (res >> 26) { | 18312 | struct alc_spec *spec = codec->spec; |
18493 | case ALC880_HP_EVENT: | 18313 | spec->autocfg.hp_pins[0] = 0x15; |
18494 | alc663_15jd_two_speaker_automute(codec); | 18314 | spec->autocfg.speaker_pins[0] = 0x14; |
18495 | break; | 18315 | spec->autocfg.speaker_pins[1] = 0x16; |
18496 | case ALC880_MIC_EVENT: | 18316 | spec->automute_mixer_nid[0] = 0x0c; |
18497 | alc_mic_automute(codec); | 18317 | spec->automute_mixer_nid[1] = 0x0e; |
18498 | break; | 18318 | spec->automute = 1; |
18499 | } | 18319 | spec->automute_mode = ALC_AUTOMUTE_MIXER; |
18320 | spec->ext_mic.pin = 0x18; | ||
18321 | spec->ext_mic.mux_idx = 0; | ||
18322 | spec->int_mic.pin = 0x19; | ||
18323 | spec->int_mic.mux_idx = 1; | ||
18324 | spec->auto_mic = 1; | ||
18500 | } | 18325 | } |
18501 | 18326 | ||
18502 | #define alc663_mode5_setup alc663_mode1_setup | ||
18503 | |||
18504 | static void alc663_mode5_inithook(struct hda_codec *codec) | ||
18505 | { | ||
18506 | alc663_15jd_two_speaker_automute(codec); | ||
18507 | alc_mic_automute(codec); | ||
18508 | } | ||
18509 | /* ***************** Mode6 ******************************/ | 18327 | /* ***************** Mode6 ******************************/ |
18510 | static void alc663_mode6_unsol_event(struct hda_codec *codec, | 18328 | static void alc663_mode6_setup(struct hda_codec *codec) |
18511 | unsigned int res) | ||
18512 | { | ||
18513 | switch (res >> 26) { | ||
18514 | case ALC880_HP_EVENT: | ||
18515 | alc663_two_hp_m2_speaker_automute(codec); | ||
18516 | break; | ||
18517 | case ALC880_MIC_EVENT: | ||
18518 | alc_mic_automute(codec); | ||
18519 | break; | ||
18520 | } | ||
18521 | } | ||
18522 | |||
18523 | #define alc663_mode6_setup alc663_mode1_setup | ||
18524 | |||
18525 | static void alc663_mode6_inithook(struct hda_codec *codec) | ||
18526 | { | 18329 | { |
18527 | alc663_two_hp_m2_speaker_automute(codec); | 18330 | struct alc_spec *spec = codec->spec; |
18528 | alc_mic_automute(codec); | 18331 | spec->autocfg.hp_pins[0] = 0x1b; |
18332 | spec->autocfg.hp_pins[0] = 0x15; | ||
18333 | spec->autocfg.speaker_pins[0] = 0x14; | ||
18334 | spec->automute_mixer_nid[0] = 0x0c; | ||
18335 | spec->automute = 1; | ||
18336 | spec->automute_mode = ALC_AUTOMUTE_MIXER; | ||
18337 | spec->ext_mic.pin = 0x18; | ||
18338 | spec->ext_mic.mux_idx = 0; | ||
18339 | spec->int_mic.pin = 0x19; | ||
18340 | spec->int_mic.mux_idx = 1; | ||
18341 | spec->auto_mic = 1; | ||
18529 | } | 18342 | } |
18530 | 18343 | ||
18531 | /* ***************** Mode7 ******************************/ | 18344 | /* ***************** Mode7 ******************************/ |
18532 | static void alc663_mode7_unsol_event(struct hda_codec *codec, | 18345 | static void alc663_mode7_setup(struct hda_codec *codec) |
18533 | unsigned int res) | ||
18534 | { | 18346 | { |
18535 | switch (res >> 26) { | 18347 | struct alc_spec *spec = codec->spec; |
18536 | case ALC880_HP_EVENT: | 18348 | spec->autocfg.hp_pins[0] = 0x1b; |
18537 | alc663_two_hp_m7_speaker_automute(codec); | 18349 | spec->autocfg.hp_pins[0] = 0x21; |
18538 | break; | 18350 | spec->autocfg.speaker_pins[0] = 0x14; |
18539 | case ALC880_MIC_EVENT: | 18351 | spec->autocfg.speaker_pins[0] = 0x17; |
18540 | alc_mic_automute(codec); | 18352 | spec->automute = 1; |
18541 | break; | 18353 | spec->automute_mode = ALC_AUTOMUTE_PIN; |
18542 | } | 18354 | spec->ext_mic.pin = 0x18; |
18543 | } | 18355 | spec->ext_mic.mux_idx = 0; |
18544 | 18356 | spec->int_mic.pin = 0x19; | |
18545 | #define alc663_mode7_setup alc663_mode1_setup | 18357 | spec->int_mic.mux_idx = 1; |
18546 | 18358 | spec->auto_mic = 1; | |
18547 | static void alc663_mode7_inithook(struct hda_codec *codec) | ||
18548 | { | ||
18549 | alc663_two_hp_m7_speaker_automute(codec); | ||
18550 | alc_mic_automute(codec); | ||
18551 | } | 18359 | } |
18552 | 18360 | ||
18553 | /* ***************** Mode8 ******************************/ | 18361 | /* ***************** Mode8 ******************************/ |
18554 | static void alc663_mode8_unsol_event(struct hda_codec *codec, | 18362 | static void alc663_mode8_setup(struct hda_codec *codec) |
18555 | unsigned int res) | ||
18556 | { | ||
18557 | switch (res >> 26) { | ||
18558 | case ALC880_HP_EVENT: | ||
18559 | alc663_two_hp_m8_speaker_automute(codec); | ||
18560 | break; | ||
18561 | case ALC880_MIC_EVENT: | ||
18562 | alc_mic_automute(codec); | ||
18563 | break; | ||
18564 | } | ||
18565 | } | ||
18566 | |||
18567 | #define alc663_mode8_setup alc663_m51va_setup | ||
18568 | |||
18569 | static void alc663_mode8_inithook(struct hda_codec *codec) | ||
18570 | { | ||
18571 | alc663_two_hp_m8_speaker_automute(codec); | ||
18572 | alc_mic_automute(codec); | ||
18573 | } | ||
18574 | |||
18575 | static void alc663_g71v_hp_automute(struct hda_codec *codec) | ||
18576 | { | ||
18577 | unsigned int present; | ||
18578 | unsigned char bits; | ||
18579 | |||
18580 | present = snd_hda_jack_detect(codec, 0x21); | ||
18581 | bits = present ? HDA_AMP_MUTE : 0; | ||
18582 | snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, | ||
18583 | HDA_AMP_MUTE, bits); | ||
18584 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
18585 | HDA_AMP_MUTE, bits); | ||
18586 | } | ||
18587 | |||
18588 | static void alc663_g71v_front_automute(struct hda_codec *codec) | ||
18589 | { | ||
18590 | unsigned int present; | ||
18591 | unsigned char bits; | ||
18592 | |||
18593 | present = snd_hda_jack_detect(codec, 0x15); | ||
18594 | bits = present ? HDA_AMP_MUTE : 0; | ||
18595 | snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, | ||
18596 | HDA_AMP_MUTE, bits); | ||
18597 | } | ||
18598 | |||
18599 | static void alc663_g71v_unsol_event(struct hda_codec *codec, | ||
18600 | unsigned int res) | ||
18601 | { | ||
18602 | switch (res >> 26) { | ||
18603 | case ALC880_HP_EVENT: | ||
18604 | alc663_g71v_hp_automute(codec); | ||
18605 | break; | ||
18606 | case ALC880_FRONT_EVENT: | ||
18607 | alc663_g71v_front_automute(codec); | ||
18608 | break; | ||
18609 | case ALC880_MIC_EVENT: | ||
18610 | alc_mic_automute(codec); | ||
18611 | break; | ||
18612 | } | ||
18613 | } | ||
18614 | |||
18615 | #define alc663_g71v_setup alc663_m51va_setup | ||
18616 | |||
18617 | static void alc663_g71v_inithook(struct hda_codec *codec) | ||
18618 | { | 18363 | { |
18619 | alc663_g71v_front_automute(codec); | 18364 | struct alc_spec *spec = codec->spec; |
18620 | alc663_g71v_hp_automute(codec); | 18365 | spec->autocfg.hp_pins[0] = 0x21; |
18621 | alc_mic_automute(codec); | 18366 | spec->autocfg.hp_pins[1] = 0x15; |
18367 | spec->autocfg.speaker_pins[0] = 0x14; | ||
18368 | spec->autocfg.speaker_pins[0] = 0x17; | ||
18369 | spec->automute = 1; | ||
18370 | spec->automute_mode = ALC_AUTOMUTE_PIN; | ||
18371 | spec->ext_mic.pin = 0x18; | ||
18372 | spec->ext_mic.mux_idx = 0; | ||
18373 | spec->int_mic.pin = 0x12; | ||
18374 | spec->int_mic.mux_idx = 9; | ||
18375 | spec->auto_mic = 1; | ||
18622 | } | 18376 | } |
18623 | 18377 | ||
18624 | static void alc663_g50v_unsol_event(struct hda_codec *codec, | 18378 | static void alc663_g71v_setup(struct hda_codec *codec) |
18625 | unsigned int res) | ||
18626 | { | 18379 | { |
18627 | switch (res >> 26) { | 18380 | struct alc_spec *spec = codec->spec; |
18628 | case ALC880_HP_EVENT: | 18381 | spec->autocfg.hp_pins[0] = 0x21; |
18629 | alc663_m51va_speaker_automute(codec); | 18382 | spec->autocfg.line_out_pins[0] = 0x15; |
18630 | break; | 18383 | spec->autocfg.speaker_pins[0] = 0x14; |
18631 | case ALC880_MIC_EVENT: | 18384 | spec->automute = 1; |
18632 | alc_mic_automute(codec); | 18385 | spec->automute_mode = ALC_AUTOMUTE_AMP; |
18633 | break; | 18386 | spec->detect_line = 1; |
18634 | } | 18387 | spec->automute_lines = 1; |
18388 | spec->ext_mic.pin = 0x18; | ||
18389 | spec->ext_mic.mux_idx = 0; | ||
18390 | spec->int_mic.pin = 0x12; | ||
18391 | spec->int_mic.mux_idx = 9; | ||
18392 | spec->auto_mic = 1; | ||
18635 | } | 18393 | } |
18636 | 18394 | ||
18637 | #define alc663_g50v_setup alc663_m51va_setup | 18395 | #define alc663_g50v_setup alc663_m51va_setup |
18638 | 18396 | ||
18639 | static void alc663_g50v_inithook(struct hda_codec *codec) | 18397 | static const struct snd_kcontrol_new alc662_ecs_mixer[] = { |
18640 | { | ||
18641 | alc663_m51va_speaker_automute(codec); | ||
18642 | alc_mic_automute(codec); | ||
18643 | } | ||
18644 | |||
18645 | static struct snd_kcontrol_new alc662_ecs_mixer[] = { | ||
18646 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 18398 | HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
18647 | ALC262_HIPPO_MASTER_SWITCH, | 18399 | ALC262_HIPPO_MASTER_SWITCH, |
18648 | 18400 | ||
@@ -18656,7 +18408,7 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = { | |||
18656 | { } /* end */ | 18408 | { } /* end */ |
18657 | }; | 18409 | }; |
18658 | 18410 | ||
18659 | static struct snd_kcontrol_new alc272_nc10_mixer[] = { | 18411 | static const struct snd_kcontrol_new alc272_nc10_mixer[] = { |
18660 | /* Master Playback automatically created from Speaker and Headphone */ | 18412 | /* Master Playback automatically created from Speaker and Headphone */ |
18661 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), | 18413 | HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), |
18662 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 18414 | HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -18691,7 +18443,7 @@ static const char * const alc662_models[ALC662_MODEL_LAST] = { | |||
18691 | [ALC662_3ST_2ch_DIG] = "3stack-dig", | 18443 | [ALC662_3ST_2ch_DIG] = "3stack-dig", |
18692 | [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", | 18444 | [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", |
18693 | [ALC662_3ST_6ch] = "3stack-6ch", | 18445 | [ALC662_3ST_6ch] = "3stack-6ch", |
18694 | [ALC662_5ST_DIG] = "6stack-dig", | 18446 | [ALC662_5ST_DIG] = "5stack-dig", |
18695 | [ALC662_LENOVO_101E] = "lenovo-101e", | 18447 | [ALC662_LENOVO_101E] = "lenovo-101e", |
18696 | [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", | 18448 | [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", |
18697 | [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", | 18449 | [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", |
@@ -18714,7 +18466,7 @@ static const char * const alc662_models[ALC662_MODEL_LAST] = { | |||
18714 | [ALC662_AUTO] = "auto", | 18466 | [ALC662_AUTO] = "auto", |
18715 | }; | 18467 | }; |
18716 | 18468 | ||
18717 | static struct snd_pci_quirk alc662_cfg_tbl[] = { | 18469 | static const struct snd_pci_quirk alc662_cfg_tbl[] = { |
18718 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), | 18470 | SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), |
18719 | SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), | 18471 | SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), |
18720 | SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), | 18472 | SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), |
@@ -18782,6 +18534,8 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
18782 | ALC662_3ST_6ch_DIG), | 18534 | ALC662_3ST_6ch_DIG), |
18783 | SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), | 18535 | SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), |
18784 | SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), | 18536 | SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), |
18537 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", | ||
18538 | ALC662_3ST_6ch_DIG), | ||
18785 | SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), | 18539 | SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), |
18786 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), | 18540 | SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), |
18787 | SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), | 18541 | SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), |
@@ -18794,10 +18548,10 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { | |||
18794 | {} | 18548 | {} |
18795 | }; | 18549 | }; |
18796 | 18550 | ||
18797 | static struct alc_config_preset alc662_presets[] = { | 18551 | static const struct alc_config_preset alc662_presets[] = { |
18798 | [ALC662_3ST_2ch_DIG] = { | 18552 | [ALC662_3ST_2ch_DIG] = { |
18799 | .mixers = { alc662_3ST_2ch_mixer }, | 18553 | .mixers = { alc662_3ST_2ch_mixer }, |
18800 | .init_verbs = { alc662_init_verbs }, | 18554 | .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, |
18801 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18555 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18802 | .dac_nids = alc662_dac_nids, | 18556 | .dac_nids = alc662_dac_nids, |
18803 | .dig_out_nid = ALC662_DIGOUT_NID, | 18557 | .dig_out_nid = ALC662_DIGOUT_NID, |
@@ -18808,7 +18562,7 @@ static struct alc_config_preset alc662_presets[] = { | |||
18808 | }, | 18562 | }, |
18809 | [ALC662_3ST_6ch_DIG] = { | 18563 | [ALC662_3ST_6ch_DIG] = { |
18810 | .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, | 18564 | .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, |
18811 | .init_verbs = { alc662_init_verbs }, | 18565 | .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, |
18812 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18566 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18813 | .dac_nids = alc662_dac_nids, | 18567 | .dac_nids = alc662_dac_nids, |
18814 | .dig_out_nid = ALC662_DIGOUT_NID, | 18568 | .dig_out_nid = ALC662_DIGOUT_NID, |
@@ -18820,7 +18574,7 @@ static struct alc_config_preset alc662_presets[] = { | |||
18820 | }, | 18574 | }, |
18821 | [ALC662_3ST_6ch] = { | 18575 | [ALC662_3ST_6ch] = { |
18822 | .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, | 18576 | .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, |
18823 | .init_verbs = { alc662_init_verbs }, | 18577 | .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, |
18824 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18578 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18825 | .dac_nids = alc662_dac_nids, | 18579 | .dac_nids = alc662_dac_nids, |
18826 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | 18580 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), |
@@ -18830,7 +18584,7 @@ static struct alc_config_preset alc662_presets[] = { | |||
18830 | }, | 18584 | }, |
18831 | [ALC662_5ST_DIG] = { | 18585 | [ALC662_5ST_DIG] = { |
18832 | .mixers = { alc662_base_mixer, alc662_chmode_mixer }, | 18586 | .mixers = { alc662_base_mixer, alc662_chmode_mixer }, |
18833 | .init_verbs = { alc662_init_verbs }, | 18587 | .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, |
18834 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18588 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18835 | .dac_nids = alc662_dac_nids, | 18589 | .dac_nids = alc662_dac_nids, |
18836 | .dig_out_nid = ALC662_DIGOUT_NID, | 18590 | .dig_out_nid = ALC662_DIGOUT_NID, |
@@ -18841,104 +18595,120 @@ static struct alc_config_preset alc662_presets[] = { | |||
18841 | }, | 18595 | }, |
18842 | [ALC662_LENOVO_101E] = { | 18596 | [ALC662_LENOVO_101E] = { |
18843 | .mixers = { alc662_lenovo_101e_mixer }, | 18597 | .mixers = { alc662_lenovo_101e_mixer }, |
18844 | .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, | 18598 | .init_verbs = { alc662_init_verbs, |
18599 | alc662_eapd_init_verbs, | ||
18600 | alc662_sue_init_verbs }, | ||
18845 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18601 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18846 | .dac_nids = alc662_dac_nids, | 18602 | .dac_nids = alc662_dac_nids, |
18847 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18603 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18848 | .channel_mode = alc662_3ST_2ch_modes, | 18604 | .channel_mode = alc662_3ST_2ch_modes, |
18849 | .input_mux = &alc662_lenovo_101e_capture_source, | 18605 | .input_mux = &alc662_lenovo_101e_capture_source, |
18850 | .unsol_event = alc662_lenovo_101e_unsol_event, | 18606 | .unsol_event = alc_sku_unsol_event, |
18851 | .init_hook = alc662_lenovo_101e_all_automute, | 18607 | .setup = alc662_lenovo_101e_setup, |
18608 | .init_hook = alc_inithook, | ||
18852 | }, | 18609 | }, |
18853 | [ALC662_ASUS_EEEPC_P701] = { | 18610 | [ALC662_ASUS_EEEPC_P701] = { |
18854 | .mixers = { alc662_eeepc_p701_mixer }, | 18611 | .mixers = { alc662_eeepc_p701_mixer }, |
18855 | .init_verbs = { alc662_init_verbs, | 18612 | .init_verbs = { alc662_init_verbs, |
18613 | alc662_eapd_init_verbs, | ||
18856 | alc662_eeepc_sue_init_verbs }, | 18614 | alc662_eeepc_sue_init_verbs }, |
18857 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18615 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18858 | .dac_nids = alc662_dac_nids, | 18616 | .dac_nids = alc662_dac_nids, |
18859 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18617 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18860 | .channel_mode = alc662_3ST_2ch_modes, | 18618 | .channel_mode = alc662_3ST_2ch_modes, |
18861 | .unsol_event = alc662_eeepc_unsol_event, | 18619 | .unsol_event = alc_sku_unsol_event, |
18862 | .setup = alc662_eeepc_setup, | 18620 | .setup = alc662_eeepc_setup, |
18863 | .init_hook = alc662_eeepc_inithook, | 18621 | .init_hook = alc_inithook, |
18864 | }, | 18622 | }, |
18865 | [ALC662_ASUS_EEEPC_EP20] = { | 18623 | [ALC662_ASUS_EEEPC_EP20] = { |
18866 | .mixers = { alc662_eeepc_ep20_mixer, | 18624 | .mixers = { alc662_eeepc_ep20_mixer, |
18867 | alc662_chmode_mixer }, | 18625 | alc662_chmode_mixer }, |
18868 | .init_verbs = { alc662_init_verbs, | 18626 | .init_verbs = { alc662_init_verbs, |
18627 | alc662_eapd_init_verbs, | ||
18869 | alc662_eeepc_ep20_sue_init_verbs }, | 18628 | alc662_eeepc_ep20_sue_init_verbs }, |
18870 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18629 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18871 | .dac_nids = alc662_dac_nids, | 18630 | .dac_nids = alc662_dac_nids, |
18872 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | 18631 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), |
18873 | .channel_mode = alc662_3ST_6ch_modes, | 18632 | .channel_mode = alc662_3ST_6ch_modes, |
18874 | .input_mux = &alc662_lenovo_101e_capture_source, | 18633 | .input_mux = &alc662_lenovo_101e_capture_source, |
18875 | .unsol_event = alc662_eeepc_unsol_event, | 18634 | .unsol_event = alc_sku_unsol_event, |
18876 | .setup = alc662_eeepc_ep20_setup, | 18635 | .setup = alc662_eeepc_ep20_setup, |
18877 | .init_hook = alc662_eeepc_ep20_inithook, | 18636 | .init_hook = alc_inithook, |
18878 | }, | 18637 | }, |
18879 | [ALC662_ECS] = { | 18638 | [ALC662_ECS] = { |
18880 | .mixers = { alc662_ecs_mixer }, | 18639 | .mixers = { alc662_ecs_mixer }, |
18881 | .init_verbs = { alc662_init_verbs, | 18640 | .init_verbs = { alc662_init_verbs, |
18641 | alc662_eapd_init_verbs, | ||
18882 | alc662_ecs_init_verbs }, | 18642 | alc662_ecs_init_verbs }, |
18883 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18643 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18884 | .dac_nids = alc662_dac_nids, | 18644 | .dac_nids = alc662_dac_nids, |
18885 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18645 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18886 | .channel_mode = alc662_3ST_2ch_modes, | 18646 | .channel_mode = alc662_3ST_2ch_modes, |
18887 | .unsol_event = alc662_eeepc_unsol_event, | 18647 | .unsol_event = alc_sku_unsol_event, |
18888 | .setup = alc662_eeepc_setup, | 18648 | .setup = alc662_eeepc_setup, |
18889 | .init_hook = alc662_eeepc_inithook, | 18649 | .init_hook = alc_inithook, |
18890 | }, | 18650 | }, |
18891 | [ALC663_ASUS_M51VA] = { | 18651 | [ALC663_ASUS_M51VA] = { |
18892 | .mixers = { alc663_m51va_mixer }, | 18652 | .mixers = { alc663_m51va_mixer }, |
18893 | .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, | 18653 | .init_verbs = { alc662_init_verbs, |
18654 | alc662_eapd_init_verbs, | ||
18655 | alc663_m51va_init_verbs }, | ||
18894 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18656 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18895 | .dac_nids = alc662_dac_nids, | 18657 | .dac_nids = alc662_dac_nids, |
18896 | .dig_out_nid = ALC662_DIGOUT_NID, | 18658 | .dig_out_nid = ALC662_DIGOUT_NID, |
18897 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18659 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18898 | .channel_mode = alc662_3ST_2ch_modes, | 18660 | .channel_mode = alc662_3ST_2ch_modes, |
18899 | .unsol_event = alc663_m51va_unsol_event, | 18661 | .unsol_event = alc_sku_unsol_event, |
18900 | .setup = alc663_m51va_setup, | 18662 | .setup = alc663_m51va_setup, |
18901 | .init_hook = alc663_m51va_inithook, | 18663 | .init_hook = alc_inithook, |
18902 | }, | 18664 | }, |
18903 | [ALC663_ASUS_G71V] = { | 18665 | [ALC663_ASUS_G71V] = { |
18904 | .mixers = { alc663_g71v_mixer }, | 18666 | .mixers = { alc663_g71v_mixer }, |
18905 | .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, | 18667 | .init_verbs = { alc662_init_verbs, |
18668 | alc662_eapd_init_verbs, | ||
18669 | alc663_g71v_init_verbs }, | ||
18906 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18670 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18907 | .dac_nids = alc662_dac_nids, | 18671 | .dac_nids = alc662_dac_nids, |
18908 | .dig_out_nid = ALC662_DIGOUT_NID, | 18672 | .dig_out_nid = ALC662_DIGOUT_NID, |
18909 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18673 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18910 | .channel_mode = alc662_3ST_2ch_modes, | 18674 | .channel_mode = alc662_3ST_2ch_modes, |
18911 | .unsol_event = alc663_g71v_unsol_event, | 18675 | .unsol_event = alc_sku_unsol_event, |
18912 | .setup = alc663_g71v_setup, | 18676 | .setup = alc663_g71v_setup, |
18913 | .init_hook = alc663_g71v_inithook, | 18677 | .init_hook = alc_inithook, |
18914 | }, | 18678 | }, |
18915 | [ALC663_ASUS_H13] = { | 18679 | [ALC663_ASUS_H13] = { |
18916 | .mixers = { alc663_m51va_mixer }, | 18680 | .mixers = { alc663_m51va_mixer }, |
18917 | .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, | 18681 | .init_verbs = { alc662_init_verbs, |
18682 | alc662_eapd_init_verbs, | ||
18683 | alc663_m51va_init_verbs }, | ||
18918 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18684 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18919 | .dac_nids = alc662_dac_nids, | 18685 | .dac_nids = alc662_dac_nids, |
18920 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18686 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18921 | .channel_mode = alc662_3ST_2ch_modes, | 18687 | .channel_mode = alc662_3ST_2ch_modes, |
18922 | .unsol_event = alc663_m51va_unsol_event, | 18688 | .setup = alc663_m51va_setup, |
18923 | .init_hook = alc663_m51va_inithook, | 18689 | .unsol_event = alc_sku_unsol_event, |
18690 | .init_hook = alc_inithook, | ||
18924 | }, | 18691 | }, |
18925 | [ALC663_ASUS_G50V] = { | 18692 | [ALC663_ASUS_G50V] = { |
18926 | .mixers = { alc663_g50v_mixer }, | 18693 | .mixers = { alc663_g50v_mixer }, |
18927 | .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, | 18694 | .init_verbs = { alc662_init_verbs, |
18695 | alc662_eapd_init_verbs, | ||
18696 | alc663_g50v_init_verbs }, | ||
18928 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18697 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18929 | .dac_nids = alc662_dac_nids, | 18698 | .dac_nids = alc662_dac_nids, |
18930 | .dig_out_nid = ALC662_DIGOUT_NID, | 18699 | .dig_out_nid = ALC662_DIGOUT_NID, |
18931 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), | 18700 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), |
18932 | .channel_mode = alc662_3ST_6ch_modes, | 18701 | .channel_mode = alc662_3ST_6ch_modes, |
18933 | .input_mux = &alc663_capture_source, | 18702 | .input_mux = &alc663_capture_source, |
18934 | .unsol_event = alc663_g50v_unsol_event, | 18703 | .unsol_event = alc_sku_unsol_event, |
18935 | .setup = alc663_g50v_setup, | 18704 | .setup = alc663_g50v_setup, |
18936 | .init_hook = alc663_g50v_inithook, | 18705 | .init_hook = alc_inithook, |
18937 | }, | 18706 | }, |
18938 | [ALC663_ASUS_MODE1] = { | 18707 | [ALC663_ASUS_MODE1] = { |
18939 | .mixers = { alc663_m51va_mixer }, | 18708 | .mixers = { alc663_m51va_mixer }, |
18940 | .cap_mixer = alc662_auto_capture_mixer, | 18709 | .cap_mixer = alc662_auto_capture_mixer, |
18941 | .init_verbs = { alc662_init_verbs, | 18710 | .init_verbs = { alc662_init_verbs, |
18711 | alc662_eapd_init_verbs, | ||
18942 | alc663_21jd_amic_init_verbs }, | 18712 | alc663_21jd_amic_init_verbs }, |
18943 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18713 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18944 | .hp_nid = 0x03, | 18714 | .hp_nid = 0x03, |
@@ -18946,28 +18716,30 @@ static struct alc_config_preset alc662_presets[] = { | |||
18946 | .dig_out_nid = ALC662_DIGOUT_NID, | 18716 | .dig_out_nid = ALC662_DIGOUT_NID, |
18947 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18717 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18948 | .channel_mode = alc662_3ST_2ch_modes, | 18718 | .channel_mode = alc662_3ST_2ch_modes, |
18949 | .unsol_event = alc663_mode1_unsol_event, | 18719 | .unsol_event = alc_sku_unsol_event, |
18950 | .setup = alc663_mode1_setup, | 18720 | .setup = alc663_mode1_setup, |
18951 | .init_hook = alc663_mode1_inithook, | 18721 | .init_hook = alc_inithook, |
18952 | }, | 18722 | }, |
18953 | [ALC662_ASUS_MODE2] = { | 18723 | [ALC662_ASUS_MODE2] = { |
18954 | .mixers = { alc662_1bjd_mixer }, | 18724 | .mixers = { alc662_1bjd_mixer }, |
18955 | .cap_mixer = alc662_auto_capture_mixer, | 18725 | .cap_mixer = alc662_auto_capture_mixer, |
18956 | .init_verbs = { alc662_init_verbs, | 18726 | .init_verbs = { alc662_init_verbs, |
18727 | alc662_eapd_init_verbs, | ||
18957 | alc662_1bjd_amic_init_verbs }, | 18728 | alc662_1bjd_amic_init_verbs }, |
18958 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18729 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18959 | .dac_nids = alc662_dac_nids, | 18730 | .dac_nids = alc662_dac_nids, |
18960 | .dig_out_nid = ALC662_DIGOUT_NID, | 18731 | .dig_out_nid = ALC662_DIGOUT_NID, |
18961 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18732 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18962 | .channel_mode = alc662_3ST_2ch_modes, | 18733 | .channel_mode = alc662_3ST_2ch_modes, |
18963 | .unsol_event = alc662_mode2_unsol_event, | 18734 | .unsol_event = alc_sku_unsol_event, |
18964 | .setup = alc662_mode2_setup, | 18735 | .setup = alc662_mode2_setup, |
18965 | .init_hook = alc662_mode2_inithook, | 18736 | .init_hook = alc_inithook, |
18966 | }, | 18737 | }, |
18967 | [ALC663_ASUS_MODE3] = { | 18738 | [ALC663_ASUS_MODE3] = { |
18968 | .mixers = { alc663_two_hp_m1_mixer }, | 18739 | .mixers = { alc663_two_hp_m1_mixer }, |
18969 | .cap_mixer = alc662_auto_capture_mixer, | 18740 | .cap_mixer = alc662_auto_capture_mixer, |
18970 | .init_verbs = { alc662_init_verbs, | 18741 | .init_verbs = { alc662_init_verbs, |
18742 | alc662_eapd_init_verbs, | ||
18971 | alc663_two_hp_amic_m1_init_verbs }, | 18743 | alc663_two_hp_amic_m1_init_verbs }, |
18972 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18744 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18973 | .hp_nid = 0x03, | 18745 | .hp_nid = 0x03, |
@@ -18975,14 +18747,15 @@ static struct alc_config_preset alc662_presets[] = { | |||
18975 | .dig_out_nid = ALC662_DIGOUT_NID, | 18747 | .dig_out_nid = ALC662_DIGOUT_NID, |
18976 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18748 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18977 | .channel_mode = alc662_3ST_2ch_modes, | 18749 | .channel_mode = alc662_3ST_2ch_modes, |
18978 | .unsol_event = alc663_mode3_unsol_event, | 18750 | .unsol_event = alc_sku_unsol_event, |
18979 | .setup = alc663_mode3_setup, | 18751 | .setup = alc663_mode3_setup, |
18980 | .init_hook = alc663_mode3_inithook, | 18752 | .init_hook = alc_inithook, |
18981 | }, | 18753 | }, |
18982 | [ALC663_ASUS_MODE4] = { | 18754 | [ALC663_ASUS_MODE4] = { |
18983 | .mixers = { alc663_asus_21jd_clfe_mixer }, | 18755 | .mixers = { alc663_asus_21jd_clfe_mixer }, |
18984 | .cap_mixer = alc662_auto_capture_mixer, | 18756 | .cap_mixer = alc662_auto_capture_mixer, |
18985 | .init_verbs = { alc662_init_verbs, | 18757 | .init_verbs = { alc662_init_verbs, |
18758 | alc662_eapd_init_verbs, | ||
18986 | alc663_21jd_amic_init_verbs}, | 18759 | alc663_21jd_amic_init_verbs}, |
18987 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18760 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
18988 | .hp_nid = 0x03, | 18761 | .hp_nid = 0x03, |
@@ -18990,14 +18763,15 @@ static struct alc_config_preset alc662_presets[] = { | |||
18990 | .dig_out_nid = ALC662_DIGOUT_NID, | 18763 | .dig_out_nid = ALC662_DIGOUT_NID, |
18991 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18764 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
18992 | .channel_mode = alc662_3ST_2ch_modes, | 18765 | .channel_mode = alc662_3ST_2ch_modes, |
18993 | .unsol_event = alc663_mode4_unsol_event, | 18766 | .unsol_event = alc_sku_unsol_event, |
18994 | .setup = alc663_mode4_setup, | 18767 | .setup = alc663_mode4_setup, |
18995 | .init_hook = alc663_mode4_inithook, | 18768 | .init_hook = alc_inithook, |
18996 | }, | 18769 | }, |
18997 | [ALC663_ASUS_MODE5] = { | 18770 | [ALC663_ASUS_MODE5] = { |
18998 | .mixers = { alc663_asus_15jd_clfe_mixer }, | 18771 | .mixers = { alc663_asus_15jd_clfe_mixer }, |
18999 | .cap_mixer = alc662_auto_capture_mixer, | 18772 | .cap_mixer = alc662_auto_capture_mixer, |
19000 | .init_verbs = { alc662_init_verbs, | 18773 | .init_verbs = { alc662_init_verbs, |
18774 | alc662_eapd_init_verbs, | ||
19001 | alc663_15jd_amic_init_verbs }, | 18775 | alc663_15jd_amic_init_verbs }, |
19002 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18776 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
19003 | .hp_nid = 0x03, | 18777 | .hp_nid = 0x03, |
@@ -19005,14 +18779,15 @@ static struct alc_config_preset alc662_presets[] = { | |||
19005 | .dig_out_nid = ALC662_DIGOUT_NID, | 18779 | .dig_out_nid = ALC662_DIGOUT_NID, |
19006 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18780 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
19007 | .channel_mode = alc662_3ST_2ch_modes, | 18781 | .channel_mode = alc662_3ST_2ch_modes, |
19008 | .unsol_event = alc663_mode5_unsol_event, | 18782 | .unsol_event = alc_sku_unsol_event, |
19009 | .setup = alc663_mode5_setup, | 18783 | .setup = alc663_mode5_setup, |
19010 | .init_hook = alc663_mode5_inithook, | 18784 | .init_hook = alc_inithook, |
19011 | }, | 18785 | }, |
19012 | [ALC663_ASUS_MODE6] = { | 18786 | [ALC663_ASUS_MODE6] = { |
19013 | .mixers = { alc663_two_hp_m2_mixer }, | 18787 | .mixers = { alc663_two_hp_m2_mixer }, |
19014 | .cap_mixer = alc662_auto_capture_mixer, | 18788 | .cap_mixer = alc662_auto_capture_mixer, |
19015 | .init_verbs = { alc662_init_verbs, | 18789 | .init_verbs = { alc662_init_verbs, |
18790 | alc662_eapd_init_verbs, | ||
19016 | alc663_two_hp_amic_m2_init_verbs }, | 18791 | alc663_two_hp_amic_m2_init_verbs }, |
19017 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18792 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
19018 | .hp_nid = 0x03, | 18793 | .hp_nid = 0x03, |
@@ -19020,14 +18795,15 @@ static struct alc_config_preset alc662_presets[] = { | |||
19020 | .dig_out_nid = ALC662_DIGOUT_NID, | 18795 | .dig_out_nid = ALC662_DIGOUT_NID, |
19021 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18796 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
19022 | .channel_mode = alc662_3ST_2ch_modes, | 18797 | .channel_mode = alc662_3ST_2ch_modes, |
19023 | .unsol_event = alc663_mode6_unsol_event, | 18798 | .unsol_event = alc_sku_unsol_event, |
19024 | .setup = alc663_mode6_setup, | 18799 | .setup = alc663_mode6_setup, |
19025 | .init_hook = alc663_mode6_inithook, | 18800 | .init_hook = alc_inithook, |
19026 | }, | 18801 | }, |
19027 | [ALC663_ASUS_MODE7] = { | 18802 | [ALC663_ASUS_MODE7] = { |
19028 | .mixers = { alc663_mode7_mixer }, | 18803 | .mixers = { alc663_mode7_mixer }, |
19029 | .cap_mixer = alc662_auto_capture_mixer, | 18804 | .cap_mixer = alc662_auto_capture_mixer, |
19030 | .init_verbs = { alc662_init_verbs, | 18805 | .init_verbs = { alc662_init_verbs, |
18806 | alc662_eapd_init_verbs, | ||
19031 | alc663_mode7_init_verbs }, | 18807 | alc663_mode7_init_verbs }, |
19032 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18808 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
19033 | .hp_nid = 0x03, | 18809 | .hp_nid = 0x03, |
@@ -19035,14 +18811,15 @@ static struct alc_config_preset alc662_presets[] = { | |||
19035 | .dig_out_nid = ALC662_DIGOUT_NID, | 18811 | .dig_out_nid = ALC662_DIGOUT_NID, |
19036 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18812 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
19037 | .channel_mode = alc662_3ST_2ch_modes, | 18813 | .channel_mode = alc662_3ST_2ch_modes, |
19038 | .unsol_event = alc663_mode7_unsol_event, | 18814 | .unsol_event = alc_sku_unsol_event, |
19039 | .setup = alc663_mode7_setup, | 18815 | .setup = alc663_mode7_setup, |
19040 | .init_hook = alc663_mode7_inithook, | 18816 | .init_hook = alc_inithook, |
19041 | }, | 18817 | }, |
19042 | [ALC663_ASUS_MODE8] = { | 18818 | [ALC663_ASUS_MODE8] = { |
19043 | .mixers = { alc663_mode8_mixer }, | 18819 | .mixers = { alc663_mode8_mixer }, |
19044 | .cap_mixer = alc662_auto_capture_mixer, | 18820 | .cap_mixer = alc662_auto_capture_mixer, |
19045 | .init_verbs = { alc662_init_verbs, | 18821 | .init_verbs = { alc662_init_verbs, |
18822 | alc662_eapd_init_verbs, | ||
19046 | alc663_mode8_init_verbs }, | 18823 | alc663_mode8_init_verbs }, |
19047 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), | 18824 | .num_dacs = ARRAY_SIZE(alc662_dac_nids), |
19048 | .hp_nid = 0x03, | 18825 | .hp_nid = 0x03, |
@@ -19050,52 +18827,57 @@ static struct alc_config_preset alc662_presets[] = { | |||
19050 | .dig_out_nid = ALC662_DIGOUT_NID, | 18827 | .dig_out_nid = ALC662_DIGOUT_NID, |
19051 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18828 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
19052 | .channel_mode = alc662_3ST_2ch_modes, | 18829 | .channel_mode = alc662_3ST_2ch_modes, |
19053 | .unsol_event = alc663_mode8_unsol_event, | 18830 | .unsol_event = alc_sku_unsol_event, |
19054 | .setup = alc663_mode8_setup, | 18831 | .setup = alc663_mode8_setup, |
19055 | .init_hook = alc663_mode8_inithook, | 18832 | .init_hook = alc_inithook, |
19056 | }, | 18833 | }, |
19057 | [ALC272_DELL] = { | 18834 | [ALC272_DELL] = { |
19058 | .mixers = { alc663_m51va_mixer }, | 18835 | .mixers = { alc663_m51va_mixer }, |
19059 | .cap_mixer = alc272_auto_capture_mixer, | 18836 | .cap_mixer = alc272_auto_capture_mixer, |
19060 | .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, | 18837 | .init_verbs = { alc662_init_verbs, |
18838 | alc662_eapd_init_verbs, | ||
18839 | alc272_dell_init_verbs }, | ||
19061 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | 18840 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), |
19062 | .dac_nids = alc662_dac_nids, | 18841 | .dac_nids = alc272_dac_nids, |
19063 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18842 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
19064 | .adc_nids = alc272_adc_nids, | 18843 | .adc_nids = alc272_adc_nids, |
19065 | .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), | 18844 | .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), |
19066 | .capsrc_nids = alc272_capsrc_nids, | 18845 | .capsrc_nids = alc272_capsrc_nids, |
19067 | .channel_mode = alc662_3ST_2ch_modes, | 18846 | .channel_mode = alc662_3ST_2ch_modes, |
19068 | .unsol_event = alc663_m51va_unsol_event, | 18847 | .unsol_event = alc_sku_unsol_event, |
19069 | .setup = alc663_m51va_setup, | 18848 | .setup = alc663_m51va_setup, |
19070 | .init_hook = alc663_m51va_inithook, | 18849 | .init_hook = alc_inithook, |
19071 | }, | 18850 | }, |
19072 | [ALC272_DELL_ZM1] = { | 18851 | [ALC272_DELL_ZM1] = { |
19073 | .mixers = { alc663_m51va_mixer }, | 18852 | .mixers = { alc663_m51va_mixer }, |
19074 | .cap_mixer = alc662_auto_capture_mixer, | 18853 | .cap_mixer = alc662_auto_capture_mixer, |
19075 | .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, | 18854 | .init_verbs = { alc662_init_verbs, |
18855 | alc662_eapd_init_verbs, | ||
18856 | alc272_dell_zm1_init_verbs }, | ||
19076 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | 18857 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), |
19077 | .dac_nids = alc662_dac_nids, | 18858 | .dac_nids = alc272_dac_nids, |
19078 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18859 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
19079 | .adc_nids = alc662_adc_nids, | 18860 | .adc_nids = alc662_adc_nids, |
19080 | .num_adc_nids = 1, | 18861 | .num_adc_nids = 1, |
19081 | .capsrc_nids = alc662_capsrc_nids, | 18862 | .capsrc_nids = alc662_capsrc_nids, |
19082 | .channel_mode = alc662_3ST_2ch_modes, | 18863 | .channel_mode = alc662_3ST_2ch_modes, |
19083 | .unsol_event = alc663_m51va_unsol_event, | 18864 | .unsol_event = alc_sku_unsol_event, |
19084 | .setup = alc663_m51va_setup, | 18865 | .setup = alc663_m51va_setup, |
19085 | .init_hook = alc663_m51va_inithook, | 18866 | .init_hook = alc_inithook, |
19086 | }, | 18867 | }, |
19087 | [ALC272_SAMSUNG_NC10] = { | 18868 | [ALC272_SAMSUNG_NC10] = { |
19088 | .mixers = { alc272_nc10_mixer }, | 18869 | .mixers = { alc272_nc10_mixer }, |
19089 | .init_verbs = { alc662_init_verbs, | 18870 | .init_verbs = { alc662_init_verbs, |
18871 | alc662_eapd_init_verbs, | ||
19090 | alc663_21jd_amic_init_verbs }, | 18872 | alc663_21jd_amic_init_verbs }, |
19091 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), | 18873 | .num_dacs = ARRAY_SIZE(alc272_dac_nids), |
19092 | .dac_nids = alc272_dac_nids, | 18874 | .dac_nids = alc272_dac_nids, |
19093 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), | 18875 | .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), |
19094 | .channel_mode = alc662_3ST_2ch_modes, | 18876 | .channel_mode = alc662_3ST_2ch_modes, |
19095 | /*.input_mux = &alc272_nc10_capture_source,*/ | 18877 | /*.input_mux = &alc272_nc10_capture_source,*/ |
19096 | .unsol_event = alc663_mode4_unsol_event, | 18878 | .unsol_event = alc_sku_unsol_event, |
19097 | .setup = alc663_mode4_setup, | 18879 | .setup = alc663_mode4_setup, |
19098 | .init_hook = alc663_mode4_inithook, | 18880 | .init_hook = alc_inithook, |
19099 | }, | 18881 | }, |
19100 | }; | 18882 | }; |
19101 | 18883 | ||
@@ -19105,45 +18887,79 @@ static struct alc_config_preset alc662_presets[] = { | |||
19105 | */ | 18887 | */ |
19106 | 18888 | ||
19107 | /* convert from MIX nid to DAC */ | 18889 | /* convert from MIX nid to DAC */ |
19108 | static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) | 18890 | static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid) |
19109 | { | 18891 | { |
19110 | if (nid == 0x0f) | 18892 | hda_nid_t list[5]; |
19111 | return 0x02; | 18893 | int i, num; |
19112 | else if (nid >= 0x0c && nid <= 0x0e) | 18894 | |
19113 | return nid - 0x0c + 0x02; | 18895 | num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list)); |
19114 | else if (nid == 0x26) /* ALC887-VD has this DAC too */ | 18896 | for (i = 0; i < num; i++) { |
19115 | return 0x25; | 18897 | if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT) |
19116 | else | 18898 | return list[i]; |
19117 | return 0; | 18899 | } |
18900 | return 0; | ||
18901 | } | ||
18902 | |||
18903 | /* go down to the selector widget before the mixer */ | ||
18904 | static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin) | ||
18905 | { | ||
18906 | hda_nid_t srcs[5]; | ||
18907 | int num = snd_hda_get_connections(codec, pin, srcs, | ||
18908 | ARRAY_SIZE(srcs)); | ||
18909 | if (num != 1 || | ||
18910 | get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL) | ||
18911 | return pin; | ||
18912 | return srcs[0]; | ||
19118 | } | 18913 | } |
19119 | 18914 | ||
19120 | /* get MIX nid connected to the given pin targeted to DAC */ | 18915 | /* get MIX nid connected to the given pin targeted to DAC */ |
19121 | static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, | 18916 | static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, |
19122 | hda_nid_t dac) | 18917 | hda_nid_t dac) |
19123 | { | 18918 | { |
19124 | hda_nid_t mix[5]; | 18919 | hda_nid_t mix[5]; |
19125 | int i, num; | 18920 | int i, num; |
19126 | 18921 | ||
18922 | pin = alc_go_down_to_selector(codec, pin); | ||
19127 | num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); | 18923 | num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); |
19128 | for (i = 0; i < num; i++) { | 18924 | for (i = 0; i < num; i++) { |
19129 | if (alc662_mix_to_dac(mix[i]) == dac) | 18925 | if (alc_auto_mix_to_dac(codec, mix[i]) == dac) |
19130 | return mix[i]; | 18926 | return mix[i]; |
19131 | } | 18927 | } |
19132 | return 0; | 18928 | return 0; |
19133 | } | 18929 | } |
19134 | 18930 | ||
18931 | /* select the connection from pin to DAC if needed */ | ||
18932 | static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin, | ||
18933 | hda_nid_t dac) | ||
18934 | { | ||
18935 | hda_nid_t mix[5]; | ||
18936 | int i, num; | ||
18937 | |||
18938 | pin = alc_go_down_to_selector(codec, pin); | ||
18939 | num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); | ||
18940 | if (num < 2) | ||
18941 | return 0; | ||
18942 | for (i = 0; i < num; i++) { | ||
18943 | if (alc_auto_mix_to_dac(codec, mix[i]) == dac) { | ||
18944 | snd_hda_codec_update_cache(codec, pin, 0, | ||
18945 | AC_VERB_SET_CONNECT_SEL, i); | ||
18946 | return 0; | ||
18947 | } | ||
18948 | } | ||
18949 | return 0; | ||
18950 | } | ||
18951 | |||
19135 | /* look for an empty DAC slot */ | 18952 | /* look for an empty DAC slot */ |
19136 | static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) | 18953 | static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) |
19137 | { | 18954 | { |
19138 | struct alc_spec *spec = codec->spec; | 18955 | struct alc_spec *spec = codec->spec; |
19139 | hda_nid_t srcs[5]; | 18956 | hda_nid_t srcs[5]; |
19140 | int i, j, num; | 18957 | int i, j, num; |
19141 | 18958 | ||
18959 | pin = alc_go_down_to_selector(codec, pin); | ||
19142 | num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); | 18960 | num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); |
19143 | if (num < 0) | ||
19144 | return 0; | ||
19145 | for (i = 0; i < num; i++) { | 18961 | for (i = 0; i < num; i++) { |
19146 | hda_nid_t nid = alc662_mix_to_dac(srcs[i]); | 18962 | hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); |
19147 | if (!nid) | 18963 | if (!nid) |
19148 | continue; | 18964 | continue; |
19149 | for (j = 0; j < spec->multiout.num_dacs; j++) | 18965 | for (j = 0; j < spec->multiout.num_dacs; j++) |
@@ -19165,10 +18981,10 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec, | |||
19165 | 18981 | ||
19166 | spec->multiout.dac_nids = spec->private_dac_nids; | 18982 | spec->multiout.dac_nids = spec->private_dac_nids; |
19167 | for (i = 0; i < cfg->line_outs; i++) { | 18983 | for (i = 0; i < cfg->line_outs; i++) { |
19168 | dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); | 18984 | dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]); |
19169 | if (!dac) | 18985 | if (!dac) |
19170 | continue; | 18986 | continue; |
19171 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; | 18987 | spec->private_dac_nids[spec->multiout.num_dacs++] = dac; |
19172 | } | 18988 | } |
19173 | return 0; | 18989 | return 0; |
19174 | } | 18990 | } |
@@ -19204,15 +19020,23 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, | |||
19204 | static const char * const chname[4] = { | 19020 | static const char * const chname[4] = { |
19205 | "Front", "Surround", NULL /*CLFE*/, "Side" | 19021 | "Front", "Surround", NULL /*CLFE*/, "Side" |
19206 | }; | 19022 | }; |
19207 | const char *pfx = alc_get_line_out_pfx(cfg, true); | 19023 | const char *pfx = alc_get_line_out_pfx(spec, true); |
19208 | hda_nid_t nid, mix; | 19024 | hda_nid_t nid, mix, pin; |
19209 | int i, err; | 19025 | int i, err, noutputs; |
19210 | 19026 | ||
19211 | for (i = 0; i < cfg->line_outs; i++) { | 19027 | noutputs = cfg->line_outs; |
19028 | if (spec->multi_ios > 0) | ||
19029 | noutputs += spec->multi_ios; | ||
19030 | |||
19031 | for (i = 0; i < noutputs; i++) { | ||
19212 | nid = spec->multiout.dac_nids[i]; | 19032 | nid = spec->multiout.dac_nids[i]; |
19213 | if (!nid) | 19033 | if (!nid) |
19214 | continue; | 19034 | continue; |
19215 | mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); | 19035 | if (i >= cfg->line_outs) |
19036 | pin = spec->multi_io[i - 1].pin; | ||
19037 | else | ||
19038 | pin = cfg->line_out_pins[i]; | ||
19039 | mix = alc_auto_dac_to_mix(codec, pin, nid); | ||
19216 | if (!mix) | 19040 | if (!mix) |
19217 | continue; | 19041 | continue; |
19218 | if (!pfx && i == 2) { | 19042 | if (!pfx && i == 2) { |
@@ -19258,7 +19082,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
19258 | 19082 | ||
19259 | if (!pin) | 19083 | if (!pin) |
19260 | return 0; | 19084 | return 0; |
19261 | nid = alc662_look_for_dac(codec, pin); | 19085 | nid = alc_auto_look_for_dac(codec, pin); |
19262 | if (!nid) { | 19086 | if (!nid) { |
19263 | /* the corresponding DAC is already occupied */ | 19087 | /* the corresponding DAC is already occupied */ |
19264 | if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) | 19088 | if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) |
@@ -19268,7 +19092,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, | |||
19268 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); | 19092 | HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); |
19269 | } | 19093 | } |
19270 | 19094 | ||
19271 | mix = alc662_dac_to_mix(codec, pin, nid); | 19095 | mix = alc_auto_dac_to_mix(codec, pin, nid); |
19272 | if (!mix) | 19096 | if (!mix) |
19273 | return 0; | 19097 | return 0; |
19274 | err = alc662_add_vol_ctl(spec, pfx, nid, 3); | 19098 | err = alc662_add_vol_ctl(spec, pfx, nid, 3); |
@@ -19292,14 +19116,21 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, | |||
19292 | hda_nid_t srcs[HDA_MAX_CONNECTIONS]; | 19116 | hda_nid_t srcs[HDA_MAX_CONNECTIONS]; |
19293 | 19117 | ||
19294 | alc_set_pin_output(codec, nid, pin_type); | 19118 | alc_set_pin_output(codec, nid, pin_type); |
19295 | /* need the manual connection? */ | ||
19296 | num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); | 19119 | num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); |
19297 | if (num <= 1) | ||
19298 | return; | ||
19299 | for (i = 0; i < num; i++) { | 19120 | for (i = 0; i < num; i++) { |
19300 | if (alc662_mix_to_dac(srcs[i]) != dac) | 19121 | if (alc_auto_mix_to_dac(codec, srcs[i]) != dac) |
19301 | continue; | 19122 | continue; |
19302 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); | 19123 | /* need the manual connection? */ |
19124 | if (num > 1) | ||
19125 | snd_hda_codec_write(codec, nid, 0, | ||
19126 | AC_VERB_SET_CONNECT_SEL, i); | ||
19127 | /* unmute mixer widget inputs */ | ||
19128 | snd_hda_codec_write(codec, srcs[i], 0, | ||
19129 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
19130 | AMP_IN_UNMUTE(0)); | ||
19131 | snd_hda_codec_write(codec, srcs[i], 0, | ||
19132 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
19133 | AMP_IN_UNMUTE(1)); | ||
19303 | return; | 19134 | return; |
19304 | } | 19135 | } |
19305 | } | 19136 | } |
@@ -19356,11 +19187,164 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec) | |||
19356 | 19187 | ||
19357 | #define alc662_auto_init_input_src alc882_auto_init_input_src | 19188 | #define alc662_auto_init_input_src alc882_auto_init_input_src |
19358 | 19189 | ||
19190 | /* | ||
19191 | * multi-io helper | ||
19192 | */ | ||
19193 | static int alc_auto_fill_multi_ios(struct hda_codec *codec, | ||
19194 | unsigned int location) | ||
19195 | { | ||
19196 | struct alc_spec *spec = codec->spec; | ||
19197 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
19198 | int type, i, num_pins = 0; | ||
19199 | |||
19200 | for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { | ||
19201 | for (i = 0; i < cfg->num_inputs; i++) { | ||
19202 | hda_nid_t nid = cfg->inputs[i].pin; | ||
19203 | hda_nid_t dac; | ||
19204 | unsigned int defcfg, caps; | ||
19205 | if (cfg->inputs[i].type != type) | ||
19206 | continue; | ||
19207 | defcfg = snd_hda_codec_get_pincfg(codec, nid); | ||
19208 | if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX) | ||
19209 | continue; | ||
19210 | if (location && get_defcfg_location(defcfg) != location) | ||
19211 | continue; | ||
19212 | caps = snd_hda_query_pin_caps(codec, nid); | ||
19213 | if (!(caps & AC_PINCAP_OUT)) | ||
19214 | continue; | ||
19215 | dac = alc_auto_look_for_dac(codec, nid); | ||
19216 | if (!dac) | ||
19217 | continue; | ||
19218 | spec->multi_io[num_pins].pin = nid; | ||
19219 | spec->multi_io[num_pins].dac = dac; | ||
19220 | num_pins++; | ||
19221 | spec->private_dac_nids[spec->multiout.num_dacs++] = dac; | ||
19222 | } | ||
19223 | } | ||
19224 | spec->multiout.num_dacs = 1; | ||
19225 | if (num_pins < 2) | ||
19226 | return 0; | ||
19227 | return num_pins; | ||
19228 | } | ||
19229 | |||
19230 | static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, | ||
19231 | struct snd_ctl_elem_info *uinfo) | ||
19232 | { | ||
19233 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
19234 | struct alc_spec *spec = codec->spec; | ||
19235 | |||
19236 | uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; | ||
19237 | uinfo->count = 1; | ||
19238 | uinfo->value.enumerated.items = spec->multi_ios + 1; | ||
19239 | if (uinfo->value.enumerated.item > spec->multi_ios) | ||
19240 | uinfo->value.enumerated.item = spec->multi_ios; | ||
19241 | sprintf(uinfo->value.enumerated.name, "%dch", | ||
19242 | (uinfo->value.enumerated.item + 1) * 2); | ||
19243 | return 0; | ||
19244 | } | ||
19245 | |||
19246 | static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol, | ||
19247 | struct snd_ctl_elem_value *ucontrol) | ||
19248 | { | ||
19249 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
19250 | struct alc_spec *spec = codec->spec; | ||
19251 | ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2; | ||
19252 | return 0; | ||
19253 | } | ||
19254 | |||
19255 | static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output) | ||
19256 | { | ||
19257 | struct alc_spec *spec = codec->spec; | ||
19258 | hda_nid_t nid = spec->multi_io[idx].pin; | ||
19259 | |||
19260 | if (!spec->multi_io[idx].ctl_in) | ||
19261 | spec->multi_io[idx].ctl_in = | ||
19262 | snd_hda_codec_read(codec, nid, 0, | ||
19263 | AC_VERB_GET_PIN_WIDGET_CONTROL, 0); | ||
19264 | if (output) { | ||
19265 | snd_hda_codec_update_cache(codec, nid, 0, | ||
19266 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
19267 | PIN_OUT); | ||
19268 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) | ||
19269 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
19270 | HDA_AMP_MUTE, 0); | ||
19271 | alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac); | ||
19272 | } else { | ||
19273 | if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) | ||
19274 | snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, | ||
19275 | HDA_AMP_MUTE, HDA_AMP_MUTE); | ||
19276 | snd_hda_codec_update_cache(codec, nid, 0, | ||
19277 | AC_VERB_SET_PIN_WIDGET_CONTROL, | ||
19278 | spec->multi_io[idx].ctl_in); | ||
19279 | } | ||
19280 | return 0; | ||
19281 | } | ||
19282 | |||
19283 | static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol, | ||
19284 | struct snd_ctl_elem_value *ucontrol) | ||
19285 | { | ||
19286 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | ||
19287 | struct alc_spec *spec = codec->spec; | ||
19288 | int i, ch; | ||
19289 | |||
19290 | ch = ucontrol->value.enumerated.item[0]; | ||
19291 | if (ch < 0 || ch > spec->multi_ios) | ||
19292 | return -EINVAL; | ||
19293 | if (ch == (spec->ext_channel_count - 1) / 2) | ||
19294 | return 0; | ||
19295 | spec->ext_channel_count = (ch + 1) * 2; | ||
19296 | for (i = 0; i < spec->multi_ios; i++) | ||
19297 | alc_set_multi_io(codec, i, i < ch); | ||
19298 | spec->multiout.max_channels = spec->ext_channel_count; | ||
19299 | return 1; | ||
19300 | } | ||
19301 | |||
19302 | static const struct snd_kcontrol_new alc_auto_channel_mode_enum = { | ||
19303 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
19304 | .name = "Channel Mode", | ||
19305 | .info = alc_auto_ch_mode_info, | ||
19306 | .get = alc_auto_ch_mode_get, | ||
19307 | .put = alc_auto_ch_mode_put, | ||
19308 | }; | ||
19309 | |||
19310 | static int alc_auto_add_multi_channel_mode(struct hda_codec *codec) | ||
19311 | { | ||
19312 | struct alc_spec *spec = codec->spec; | ||
19313 | struct auto_pin_cfg *cfg = &spec->autocfg; | ||
19314 | unsigned int location, defcfg; | ||
19315 | int num_pins; | ||
19316 | |||
19317 | if (cfg->line_outs != 1 || | ||
19318 | cfg->line_out_type != AUTO_PIN_LINE_OUT) | ||
19319 | return 0; | ||
19320 | |||
19321 | defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); | ||
19322 | location = get_defcfg_location(defcfg); | ||
19323 | |||
19324 | num_pins = alc_auto_fill_multi_ios(codec, location); | ||
19325 | if (num_pins > 0) { | ||
19326 | struct snd_kcontrol_new *knew; | ||
19327 | |||
19328 | knew = alc_kcontrol_new(spec); | ||
19329 | if (!knew) | ||
19330 | return -ENOMEM; | ||
19331 | *knew = alc_auto_channel_mode_enum; | ||
19332 | knew->name = kstrdup("Channel Mode", GFP_KERNEL); | ||
19333 | if (!knew->name) | ||
19334 | return -ENOMEM; | ||
19335 | |||
19336 | spec->multi_ios = num_pins; | ||
19337 | spec->ext_channel_count = 2; | ||
19338 | spec->multiout.num_dacs = num_pins + 1; | ||
19339 | } | ||
19340 | return 0; | ||
19341 | } | ||
19342 | |||
19359 | static int alc662_parse_auto_config(struct hda_codec *codec) | 19343 | static int alc662_parse_auto_config(struct hda_codec *codec) |
19360 | { | 19344 | { |
19361 | struct alc_spec *spec = codec->spec; | 19345 | struct alc_spec *spec = codec->spec; |
19362 | int err; | 19346 | int err; |
19363 | static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; | 19347 | static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; |
19364 | 19348 | ||
19365 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 19349 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
19366 | alc662_ignore); | 19350 | alc662_ignore); |
@@ -19372,6 +19356,9 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
19372 | err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); | 19356 | err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); |
19373 | if (err < 0) | 19357 | if (err < 0) |
19374 | return err; | 19358 | return err; |
19359 | err = alc_auto_add_multi_channel_mode(codec); | ||
19360 | if (err < 0) | ||
19361 | return err; | ||
19375 | err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); | 19362 | err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); |
19376 | if (err < 0) | 19363 | if (err < 0) |
19377 | return err; | 19364 | return err; |
@@ -19402,14 +19389,6 @@ static int alc662_parse_auto_config(struct hda_codec *codec) | |||
19402 | spec->num_mux_defs = 1; | 19389 | spec->num_mux_defs = 1; |
19403 | spec->input_mux = &spec->private_imux[0]; | 19390 | spec->input_mux = &spec->private_imux[0]; |
19404 | 19391 | ||
19405 | add_verb(spec, alc662_init_verbs); | ||
19406 | if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || | ||
19407 | codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) | ||
19408 | add_verb(spec, alc663_init_verbs); | ||
19409 | |||
19410 | if (codec->vendor_id == 0x10ec0272) | ||
19411 | add_verb(spec, alc272_init_verbs); | ||
19412 | |||
19413 | err = alc_auto_add_mic_boost(codec); | 19392 | err = alc_auto_add_mic_boost(codec); |
19414 | if (err < 0) | 19393 | if (err < 0) |
19415 | return err; | 19394 | return err; |
@@ -19455,7 +19434,7 @@ enum { | |||
19455 | ALC662_FIXUP_IDEAPAD, | 19434 | ALC662_FIXUP_IDEAPAD, |
19456 | ALC272_FIXUP_MARIO, | 19435 | ALC272_FIXUP_MARIO, |
19457 | ALC662_FIXUP_CZC_P10T, | 19436 | ALC662_FIXUP_CZC_P10T, |
19458 | ALC662_FIXUP_GIGABYTE, | 19437 | ALC662_FIXUP_SKU_IGNORE, |
19459 | }; | 19438 | }; |
19460 | 19439 | ||
19461 | static const struct alc_fixup alc662_fixups[] = { | 19440 | static const struct alc_fixup alc662_fixups[] = { |
@@ -19484,20 +19463,17 @@ static const struct alc_fixup alc662_fixups[] = { | |||
19484 | {} | 19463 | {} |
19485 | } | 19464 | } |
19486 | }, | 19465 | }, |
19487 | [ALC662_FIXUP_GIGABYTE] = { | 19466 | [ALC662_FIXUP_SKU_IGNORE] = { |
19488 | .type = ALC_FIXUP_PINS, | 19467 | .type = ALC_FIXUP_SKU, |
19489 | .v.pins = (const struct alc_pincfg[]) { | 19468 | .v.sku = ALC_FIXUP_SKU_IGNORE, |
19490 | { 0x14, 0x1114410 }, /* set as speaker */ | ||
19491 | { } | ||
19492 | } | ||
19493 | }, | 19469 | }, |
19494 | }; | 19470 | }; |
19495 | 19471 | ||
19496 | static struct snd_pci_quirk alc662_fixup_tbl[] = { | 19472 | static const struct snd_pci_quirk alc662_fixup_tbl[] = { |
19497 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), | 19473 | SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), |
19474 | SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), | ||
19498 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), | 19475 | SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), |
19499 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), | 19476 | SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), |
19500 | SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE), | ||
19501 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), | 19477 | SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), |
19502 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), | 19478 | SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), |
19503 | SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), | 19479 | SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), |
@@ -19611,6 +19587,7 @@ static int patch_alc662(struct hda_codec *codec) | |||
19611 | codec->patch_ops = alc_patch_ops; | 19587 | codec->patch_ops = alc_patch_ops; |
19612 | if (board_config == ALC662_AUTO) | 19588 | if (board_config == ALC662_AUTO) |
19613 | spec->init_hook = alc662_auto_init; | 19589 | spec->init_hook = alc662_auto_init; |
19590 | spec->shutup = alc_eapd_shutup; | ||
19614 | 19591 | ||
19615 | alc_init_jacks(codec); | 19592 | alc_init_jacks(codec); |
19616 | 19593 | ||
@@ -19639,6 +19616,15 @@ static int patch_alc888(struct hda_codec *codec) | |||
19639 | return patch_alc882(codec); | 19616 | return patch_alc882(codec); |
19640 | } | 19617 | } |
19641 | 19618 | ||
19619 | static int patch_alc899(struct hda_codec *codec) | ||
19620 | { | ||
19621 | if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) { | ||
19622 | kfree(codec->chip_name); | ||
19623 | codec->chip_name = kstrdup("ALC898", GFP_KERNEL); | ||
19624 | } | ||
19625 | return patch_alc882(codec); | ||
19626 | } | ||
19627 | |||
19642 | /* | 19628 | /* |
19643 | * ALC680 support | 19629 | * ALC680 support |
19644 | */ | 19630 | */ |
@@ -19646,12 +19632,12 @@ static int patch_alc888(struct hda_codec *codec) | |||
19646 | #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID | 19632 | #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID |
19647 | #define alc680_modes alc260_modes | 19633 | #define alc680_modes alc260_modes |
19648 | 19634 | ||
19649 | static hda_nid_t alc680_dac_nids[3] = { | 19635 | static const hda_nid_t alc680_dac_nids[3] = { |
19650 | /* Lout1, Lout2, hp */ | 19636 | /* Lout1, Lout2, hp */ |
19651 | 0x02, 0x03, 0x04 | 19637 | 0x02, 0x03, 0x04 |
19652 | }; | 19638 | }; |
19653 | 19639 | ||
19654 | static hda_nid_t alc680_adc_nids[3] = { | 19640 | static const hda_nid_t alc680_adc_nids[3] = { |
19655 | /* ADC0-2 */ | 19641 | /* ADC0-2 */ |
19656 | /* DMIC, MIC, Line-in*/ | 19642 | /* DMIC, MIC, Line-in*/ |
19657 | 0x07, 0x08, 0x09 | 19643 | 0x07, 0x08, 0x09 |
@@ -19671,8 +19657,7 @@ static void alc680_rec_autoswitch(struct hda_codec *codec) | |||
19671 | 19657 | ||
19672 | for (i = 0; i < cfg->num_inputs; i++) { | 19658 | for (i = 0; i < cfg->num_inputs; i++) { |
19673 | nid = cfg->inputs[i].pin; | 19659 | nid = cfg->inputs[i].pin; |
19674 | if (!(snd_hda_query_pin_caps(codec, nid) & | 19660 | if (!is_jack_detectable(codec, nid)) |
19675 | AC_PINCAP_PRES_DETECT)) | ||
19676 | continue; | 19661 | continue; |
19677 | if (snd_hda_jack_detect(codec, nid)) { | 19662 | if (snd_hda_jack_detect(codec, nid)) { |
19678 | if (cfg->inputs[i].type < type_found) { | 19663 | if (cfg->inputs[i].type < type_found) { |
@@ -19719,7 +19704,7 @@ static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
19719 | return 0; | 19704 | return 0; |
19720 | } | 19705 | } |
19721 | 19706 | ||
19722 | static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { | 19707 | static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = { |
19723 | .substreams = 1, /* can be overridden */ | 19708 | .substreams = 1, /* can be overridden */ |
19724 | .channels_min = 2, | 19709 | .channels_min = 2, |
19725 | .channels_max = 2, | 19710 | .channels_max = 2, |
@@ -19730,7 +19715,7 @@ static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { | |||
19730 | }, | 19715 | }, |
19731 | }; | 19716 | }; |
19732 | 19717 | ||
19733 | static struct snd_kcontrol_new alc680_base_mixer[] = { | 19718 | static const struct snd_kcontrol_new alc680_base_mixer[] = { |
19734 | /* output mixer control */ | 19719 | /* output mixer control */ |
19735 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), | 19720 | HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), |
19736 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), | 19721 | HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), |
@@ -19742,7 +19727,7 @@ static struct snd_kcontrol_new alc680_base_mixer[] = { | |||
19742 | { } | 19727 | { } |
19743 | }; | 19728 | }; |
19744 | 19729 | ||
19745 | static struct hda_bind_ctls alc680_bind_cap_vol = { | 19730 | static const struct hda_bind_ctls alc680_bind_cap_vol = { |
19746 | .ops = &snd_hda_bind_vol, | 19731 | .ops = &snd_hda_bind_vol, |
19747 | .values = { | 19732 | .values = { |
19748 | HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), | 19733 | HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), |
@@ -19752,7 +19737,7 @@ static struct hda_bind_ctls alc680_bind_cap_vol = { | |||
19752 | }, | 19737 | }, |
19753 | }; | 19738 | }; |
19754 | 19739 | ||
19755 | static struct hda_bind_ctls alc680_bind_cap_switch = { | 19740 | static const struct hda_bind_ctls alc680_bind_cap_switch = { |
19756 | .ops = &snd_hda_bind_sw, | 19741 | .ops = &snd_hda_bind_sw, |
19757 | .values = { | 19742 | .values = { |
19758 | HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), | 19743 | HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), |
@@ -19762,7 +19747,7 @@ static struct hda_bind_ctls alc680_bind_cap_switch = { | |||
19762 | }, | 19747 | }, |
19763 | }; | 19748 | }; |
19764 | 19749 | ||
19765 | static struct snd_kcontrol_new alc680_master_capture_mixer[] = { | 19750 | static const struct snd_kcontrol_new alc680_master_capture_mixer[] = { |
19766 | HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), | 19751 | HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), |
19767 | HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), | 19752 | HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), |
19768 | { } /* end */ | 19753 | { } /* end */ |
@@ -19771,7 +19756,7 @@ static struct snd_kcontrol_new alc680_master_capture_mixer[] = { | |||
19771 | /* | 19756 | /* |
19772 | * generic initialization of ADC, input mixers and output mixers | 19757 | * generic initialization of ADC, input mixers and output mixers |
19773 | */ | 19758 | */ |
19774 | static struct hda_verb alc680_init_verbs[] = { | 19759 | static const struct hda_verb alc680_init_verbs[] = { |
19775 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 19760 | {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
19776 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 19761 | {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
19777 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, | 19762 | {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, |
@@ -19809,20 +19794,22 @@ static void alc680_base_setup(struct hda_codec *codec) | |||
19809 | spec->autocfg.inputs[0].type = AUTO_PIN_MIC; | 19794 | spec->autocfg.inputs[0].type = AUTO_PIN_MIC; |
19810 | spec->autocfg.inputs[1].pin = 0x19; | 19795 | spec->autocfg.inputs[1].pin = 0x19; |
19811 | spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; | 19796 | spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; |
19797 | spec->automute = 1; | ||
19798 | spec->automute_mode = ALC_AUTOMUTE_AMP; | ||
19812 | } | 19799 | } |
19813 | 19800 | ||
19814 | static void alc680_unsol_event(struct hda_codec *codec, | 19801 | static void alc680_unsol_event(struct hda_codec *codec, |
19815 | unsigned int res) | 19802 | unsigned int res) |
19816 | { | 19803 | { |
19817 | if ((res >> 26) == ALC880_HP_EVENT) | 19804 | if ((res >> 26) == ALC880_HP_EVENT) |
19818 | alc_automute_amp(codec); | 19805 | alc_hp_automute(codec); |
19819 | if ((res >> 26) == ALC880_MIC_EVENT) | 19806 | if ((res >> 26) == ALC880_MIC_EVENT) |
19820 | alc680_rec_autoswitch(codec); | 19807 | alc680_rec_autoswitch(codec); |
19821 | } | 19808 | } |
19822 | 19809 | ||
19823 | static void alc680_inithook(struct hda_codec *codec) | 19810 | static void alc680_inithook(struct hda_codec *codec) |
19824 | { | 19811 | { |
19825 | alc_automute_amp(codec); | 19812 | alc_hp_automute(codec); |
19826 | alc680_rec_autoswitch(codec); | 19813 | alc680_rec_autoswitch(codec); |
19827 | } | 19814 | } |
19828 | 19815 | ||
@@ -19859,7 +19846,7 @@ static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, | |||
19859 | 19846 | ||
19860 | if (err < 0) | 19847 | if (err < 0) |
19861 | return err; | 19848 | return err; |
19862 | spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; | 19849 | spec->private_dac_nids[spec->multiout.num_dacs++] = dac; |
19863 | } | 19850 | } |
19864 | 19851 | ||
19865 | return 0; | 19852 | return 0; |
@@ -19945,7 +19932,7 @@ static int alc680_parse_auto_config(struct hda_codec *codec) | |||
19945 | { | 19932 | { |
19946 | struct alc_spec *spec = codec->spec; | 19933 | struct alc_spec *spec = codec->spec; |
19947 | int err; | 19934 | int err; |
19948 | static hda_nid_t alc680_ignore[] = { 0 }; | 19935 | static const hda_nid_t alc680_ignore[] = { 0 }; |
19949 | 19936 | ||
19950 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, | 19937 | err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, |
19951 | alc680_ignore); | 19938 | alc680_ignore); |
@@ -20003,12 +19990,12 @@ static const char * const alc680_models[ALC680_MODEL_LAST] = { | |||
20003 | [ALC680_AUTO] = "auto", | 19990 | [ALC680_AUTO] = "auto", |
20004 | }; | 19991 | }; |
20005 | 19992 | ||
20006 | static struct snd_pci_quirk alc680_cfg_tbl[] = { | 19993 | static const struct snd_pci_quirk alc680_cfg_tbl[] = { |
20007 | SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), | 19994 | SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), |
20008 | {} | 19995 | {} |
20009 | }; | 19996 | }; |
20010 | 19997 | ||
20011 | static struct alc_config_preset alc680_presets[] = { | 19998 | static const struct alc_config_preset alc680_presets[] = { |
20012 | [ALC680_BASE] = { | 19999 | [ALC680_BASE] = { |
20013 | .mixers = { alc680_base_mixer }, | 20000 | .mixers = { alc680_base_mixer }, |
20014 | .cap_mixer = alc680_master_capture_mixer, | 20001 | .cap_mixer = alc680_master_capture_mixer, |
@@ -20089,7 +20076,8 @@ static int patch_alc680(struct hda_codec *codec) | |||
20089 | /* | 20076 | /* |
20090 | * patch entries | 20077 | * patch entries |
20091 | */ | 20078 | */ |
20092 | static struct hda_codec_preset snd_hda_preset_realtek[] = { | 20079 | static const struct hda_codec_preset snd_hda_preset_realtek[] = { |
20080 | { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, | ||
20093 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, | 20081 | { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, |
20094 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, | 20082 | { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, |
20095 | { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, | 20083 | { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, |
@@ -20098,6 +20086,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
20098 | { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, | 20086 | { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, |
20099 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, | 20087 | { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, |
20100 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, | 20088 | { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, |
20089 | { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, | ||
20101 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", | 20090 | { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", |
20102 | .patch = patch_alc861 }, | 20091 | .patch = patch_alc861 }, |
20103 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, | 20092 | { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, |
@@ -20125,6 +20114,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { | |||
20125 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, | 20114 | { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, |
20126 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, | 20115 | { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, |
20127 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, | 20116 | { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, |
20117 | { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 }, | ||
20128 | {} /* terminator */ | 20118 | {} /* terminator */ |
20129 | }; | 20119 | }; |
20130 | 20120 | ||
diff --git a/sound/pci/hda/patch_si3054.c b/sound/pci/hda/patch_si3054.c index f419ee8d75f0..2f55f32876fa 100644 --- a/sound/pci/hda/patch_si3054.c +++ b/sound/pci/hda/patch_si3054.c | |||
@@ -130,7 +130,7 @@ static int si3054_switch_put(struct snd_kcontrol *kcontrol, | |||
130 | } | 130 | } |
131 | 131 | ||
132 | 132 | ||
133 | static struct snd_kcontrol_new si3054_modem_mixer[] = { | 133 | static const struct snd_kcontrol_new si3054_modem_mixer[] = { |
134 | SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH), | 134 | SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH), |
135 | SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID), | 135 | SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID), |
136 | {} | 136 | {} |
@@ -181,7 +181,7 @@ static int si3054_pcm_open(struct hda_pcm_stream *hinfo, | |||
181 | } | 181 | } |
182 | 182 | ||
183 | 183 | ||
184 | static struct hda_pcm_stream si3054_pcm = { | 184 | static const struct hda_pcm_stream si3054_pcm = { |
185 | .substreams = 1, | 185 | .substreams = 1, |
186 | .channels_min = 1, | 186 | .channels_min = 1, |
187 | .channels_max = 1, | 187 | .channels_max = 1, |
@@ -200,12 +200,13 @@ static int si3054_build_pcms(struct hda_codec *codec) | |||
200 | { | 200 | { |
201 | struct si3054_spec *spec = codec->spec; | 201 | struct si3054_spec *spec = codec->spec; |
202 | struct hda_pcm *info = &spec->pcm; | 202 | struct hda_pcm *info = &spec->pcm; |
203 | si3054_pcm.nid = codec->mfg; | ||
204 | codec->num_pcms = 1; | 203 | codec->num_pcms = 1; |
205 | codec->pcm_info = info; | 204 | codec->pcm_info = info; |
206 | info->name = "Si3054 Modem"; | 205 | info->name = "Si3054 Modem"; |
207 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; | 206 | info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; |
208 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; | 207 | info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; |
208 | info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = codec->mfg; | ||
209 | info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = codec->mfg; | ||
209 | info->pcm_type = HDA_PCM_TYPE_MODEM; | 210 | info->pcm_type = HDA_PCM_TYPE_MODEM; |
210 | return 0; | 211 | return 0; |
211 | } | 212 | } |
@@ -263,7 +264,7 @@ static void si3054_free(struct hda_codec *codec) | |||
263 | /* | 264 | /* |
264 | */ | 265 | */ |
265 | 266 | ||
266 | static struct hda_codec_ops si3054_patch_ops = { | 267 | static const struct hda_codec_ops si3054_patch_ops = { |
267 | .build_controls = si3054_build_controls, | 268 | .build_controls = si3054_build_controls, |
268 | .build_pcms = si3054_build_pcms, | 269 | .build_pcms = si3054_build_pcms, |
269 | .init = si3054_init, | 270 | .init = si3054_init, |
@@ -283,7 +284,7 @@ static int patch_si3054(struct hda_codec *codec) | |||
283 | /* | 284 | /* |
284 | * patch entries | 285 | * patch entries |
285 | */ | 286 | */ |
286 | static struct hda_codec_preset snd_hda_preset_si3054[] = { | 287 | static const struct hda_codec_preset snd_hda_preset_si3054[] = { |
287 | { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, | 288 | { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, |
288 | { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, | 289 | { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, |
289 | { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, | 290 | { .id = 0x11c13026, .name = "Si3054", .patch = patch_si3054 }, |
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c index 94d19c03a7f4..7f81cc2274f3 100644 --- a/sound/pci/hda/patch_sigmatel.c +++ b/sound/pci/hda/patch_sigmatel.c | |||
@@ -217,15 +217,15 @@ struct sigmatel_spec { | |||
217 | unsigned int stream_delay; | 217 | unsigned int stream_delay; |
218 | 218 | ||
219 | /* analog loopback */ | 219 | /* analog loopback */ |
220 | struct snd_kcontrol_new *aloopback_ctl; | 220 | const struct snd_kcontrol_new *aloopback_ctl; |
221 | unsigned char aloopback_mask; | 221 | unsigned char aloopback_mask; |
222 | unsigned char aloopback_shift; | 222 | unsigned char aloopback_shift; |
223 | 223 | ||
224 | /* power management */ | 224 | /* power management */ |
225 | unsigned int num_pwrs; | 225 | unsigned int num_pwrs; |
226 | unsigned int *pwr_mapping; | 226 | const unsigned int *pwr_mapping; |
227 | hda_nid_t *pwr_nids; | 227 | const hda_nid_t *pwr_nids; |
228 | hda_nid_t *dac_list; | 228 | const hda_nid_t *dac_list; |
229 | 229 | ||
230 | /* events */ | 230 | /* events */ |
231 | struct snd_array events; | 231 | struct snd_array events; |
@@ -241,20 +241,20 @@ struct sigmatel_spec { | |||
241 | int volume_offset; | 241 | int volume_offset; |
242 | 242 | ||
243 | /* capture */ | 243 | /* capture */ |
244 | hda_nid_t *adc_nids; | 244 | const hda_nid_t *adc_nids; |
245 | unsigned int num_adcs; | 245 | unsigned int num_adcs; |
246 | hda_nid_t *mux_nids; | 246 | const hda_nid_t *mux_nids; |
247 | unsigned int num_muxes; | 247 | unsigned int num_muxes; |
248 | hda_nid_t *dmic_nids; | 248 | const hda_nid_t *dmic_nids; |
249 | unsigned int num_dmics; | 249 | unsigned int num_dmics; |
250 | hda_nid_t *dmux_nids; | 250 | const hda_nid_t *dmux_nids; |
251 | unsigned int num_dmuxes; | 251 | unsigned int num_dmuxes; |
252 | hda_nid_t *smux_nids; | 252 | const hda_nid_t *smux_nids; |
253 | unsigned int num_smuxes; | 253 | unsigned int num_smuxes; |
254 | unsigned int num_analog_muxes; | 254 | unsigned int num_analog_muxes; |
255 | 255 | ||
256 | unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ | 256 | const unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ |
257 | unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */ | 257 | const unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */ |
258 | unsigned int num_caps; /* number of capture volume/switch elements */ | 258 | unsigned int num_caps; /* number of capture volume/switch elements */ |
259 | 259 | ||
260 | struct sigmatel_mic_route ext_mic; | 260 | struct sigmatel_mic_route ext_mic; |
@@ -269,12 +269,12 @@ struct sigmatel_spec { | |||
269 | hda_nid_t digbeep_nid; | 269 | hda_nid_t digbeep_nid; |
270 | 270 | ||
271 | /* pin widgets */ | 271 | /* pin widgets */ |
272 | hda_nid_t *pin_nids; | 272 | const hda_nid_t *pin_nids; |
273 | unsigned int num_pins; | 273 | unsigned int num_pins; |
274 | 274 | ||
275 | /* codec specific stuff */ | 275 | /* codec specific stuff */ |
276 | struct hda_verb *init; | 276 | const struct hda_verb *init; |
277 | struct snd_kcontrol_new *mixer; | 277 | const struct snd_kcontrol_new *mixer; |
278 | 278 | ||
279 | /* capture source */ | 279 | /* capture source */ |
280 | struct hda_input_mux *dinput_mux; | 280 | struct hda_input_mux *dinput_mux; |
@@ -317,52 +317,52 @@ struct sigmatel_spec { | |||
317 | hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; | 317 | hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; |
318 | }; | 318 | }; |
319 | 319 | ||
320 | static hda_nid_t stac9200_adc_nids[1] = { | 320 | static const hda_nid_t stac9200_adc_nids[1] = { |
321 | 0x03, | 321 | 0x03, |
322 | }; | 322 | }; |
323 | 323 | ||
324 | static hda_nid_t stac9200_mux_nids[1] = { | 324 | static const hda_nid_t stac9200_mux_nids[1] = { |
325 | 0x0c, | 325 | 0x0c, |
326 | }; | 326 | }; |
327 | 327 | ||
328 | static hda_nid_t stac9200_dac_nids[1] = { | 328 | static const hda_nid_t stac9200_dac_nids[1] = { |
329 | 0x02, | 329 | 0x02, |
330 | }; | 330 | }; |
331 | 331 | ||
332 | static hda_nid_t stac92hd73xx_pwr_nids[8] = { | 332 | static const hda_nid_t stac92hd73xx_pwr_nids[8] = { |
333 | 0x0a, 0x0b, 0x0c, 0xd, 0x0e, | 333 | 0x0a, 0x0b, 0x0c, 0xd, 0x0e, |
334 | 0x0f, 0x10, 0x11 | 334 | 0x0f, 0x10, 0x11 |
335 | }; | 335 | }; |
336 | 336 | ||
337 | static hda_nid_t stac92hd73xx_slave_dig_outs[2] = { | 337 | static const hda_nid_t stac92hd73xx_slave_dig_outs[2] = { |
338 | 0x26, 0, | 338 | 0x26, 0, |
339 | }; | 339 | }; |
340 | 340 | ||
341 | static hda_nid_t stac92hd73xx_adc_nids[2] = { | 341 | static const hda_nid_t stac92hd73xx_adc_nids[2] = { |
342 | 0x1a, 0x1b | 342 | 0x1a, 0x1b |
343 | }; | 343 | }; |
344 | 344 | ||
345 | #define STAC92HD73XX_NUM_DMICS 2 | 345 | #define STAC92HD73XX_NUM_DMICS 2 |
346 | static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { | 346 | static const hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { |
347 | 0x13, 0x14, 0 | 347 | 0x13, 0x14, 0 |
348 | }; | 348 | }; |
349 | 349 | ||
350 | #define STAC92HD73_DAC_COUNT 5 | 350 | #define STAC92HD73_DAC_COUNT 5 |
351 | 351 | ||
352 | static hda_nid_t stac92hd73xx_mux_nids[2] = { | 352 | static const hda_nid_t stac92hd73xx_mux_nids[2] = { |
353 | 0x20, 0x21, | 353 | 0x20, 0x21, |
354 | }; | 354 | }; |
355 | 355 | ||
356 | static hda_nid_t stac92hd73xx_dmux_nids[2] = { | 356 | static const hda_nid_t stac92hd73xx_dmux_nids[2] = { |
357 | 0x20, 0x21, | 357 | 0x20, 0x21, |
358 | }; | 358 | }; |
359 | 359 | ||
360 | static hda_nid_t stac92hd73xx_smux_nids[2] = { | 360 | static const hda_nid_t stac92hd73xx_smux_nids[2] = { |
361 | 0x22, 0x23, | 361 | 0x22, 0x23, |
362 | }; | 362 | }; |
363 | 363 | ||
364 | #define STAC92HD73XX_NUM_CAPS 2 | 364 | #define STAC92HD73XX_NUM_CAPS 2 |
365 | static unsigned long stac92hd73xx_capvols[] = { | 365 | static const unsigned long stac92hd73xx_capvols[] = { |
366 | HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT), | 366 | HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT), |
367 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), | 367 | HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), |
368 | }; | 368 | }; |
@@ -370,137 +370,141 @@ static unsigned long stac92hd73xx_capvols[] = { | |||
370 | 370 | ||
371 | #define STAC92HD83_DAC_COUNT 3 | 371 | #define STAC92HD83_DAC_COUNT 3 |
372 | 372 | ||
373 | static hda_nid_t stac92hd83xxx_pwr_nids[4] = { | 373 | static const hda_nid_t stac92hd83xxx_pwr_nids[4] = { |
374 | 0xa, 0xb, 0xd, 0xe, | 374 | 0xa, 0xb, 0xd, 0xe, |
375 | }; | 375 | }; |
376 | 376 | ||
377 | static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { | 377 | static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { |
378 | 0x1e, 0, | 378 | 0x1e, 0, |
379 | }; | 379 | }; |
380 | 380 | ||
381 | static unsigned int stac92hd83xxx_pwr_mapping[4] = { | 381 | static const unsigned int stac92hd83xxx_pwr_mapping[4] = { |
382 | 0x03, 0x0c, 0x20, 0x40, | 382 | 0x03, 0x0c, 0x20, 0x40, |
383 | }; | 383 | }; |
384 | 384 | ||
385 | static hda_nid_t stac92hd83xxx_dmic_nids[] = { | 385 | static const hda_nid_t stac92hd83xxx_dmic_nids[] = { |
386 | 0x11, 0x20, | 386 | 0x11, 0x20, |
387 | }; | 387 | }; |
388 | 388 | ||
389 | static hda_nid_t stac92hd71bxx_pwr_nids[3] = { | 389 | static const hda_nid_t stac92hd71bxx_pwr_nids[3] = { |
390 | 0x0a, 0x0d, 0x0f | 390 | 0x0a, 0x0d, 0x0f |
391 | }; | 391 | }; |
392 | 392 | ||
393 | static hda_nid_t stac92hd71bxx_adc_nids[2] = { | 393 | static const hda_nid_t stac92hd71bxx_adc_nids[2] = { |
394 | 0x12, 0x13, | 394 | 0x12, 0x13, |
395 | }; | 395 | }; |
396 | 396 | ||
397 | static hda_nid_t stac92hd71bxx_mux_nids[2] = { | 397 | static const hda_nid_t stac92hd71bxx_mux_nids[2] = { |
398 | 0x1a, 0x1b | 398 | 0x1a, 0x1b |
399 | }; | 399 | }; |
400 | 400 | ||
401 | static hda_nid_t stac92hd71bxx_dmux_nids[2] = { | 401 | static const hda_nid_t stac92hd71bxx_dmux_nids[2] = { |
402 | 0x1c, 0x1d, | 402 | 0x1c, 0x1d, |
403 | }; | 403 | }; |
404 | 404 | ||
405 | static hda_nid_t stac92hd71bxx_smux_nids[2] = { | 405 | static const hda_nid_t stac92hd71bxx_smux_nids[2] = { |
406 | 0x24, 0x25, | 406 | 0x24, 0x25, |
407 | }; | 407 | }; |
408 | 408 | ||
409 | #define STAC92HD71BXX_NUM_DMICS 2 | 409 | #define STAC92HD71BXX_NUM_DMICS 2 |
410 | static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { | 410 | static const hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { |
411 | 0x18, 0x19, 0 | 411 | 0x18, 0x19, 0 |
412 | }; | 412 | }; |
413 | 413 | ||
414 | static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { | 414 | static const hda_nid_t stac92hd71bxx_dmic_5port_nids[STAC92HD71BXX_NUM_DMICS] = { |
415 | 0x18, 0 | ||
416 | }; | ||
417 | |||
418 | static const hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { | ||
415 | 0x22, 0 | 419 | 0x22, 0 |
416 | }; | 420 | }; |
417 | 421 | ||
418 | #define STAC92HD71BXX_NUM_CAPS 2 | 422 | #define STAC92HD71BXX_NUM_CAPS 2 |
419 | static unsigned long stac92hd71bxx_capvols[] = { | 423 | static const unsigned long stac92hd71bxx_capvols[] = { |
420 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), | 424 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), |
421 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | 425 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), |
422 | }; | 426 | }; |
423 | #define stac92hd71bxx_capsws stac92hd71bxx_capvols | 427 | #define stac92hd71bxx_capsws stac92hd71bxx_capvols |
424 | 428 | ||
425 | static hda_nid_t stac925x_adc_nids[1] = { | 429 | static const hda_nid_t stac925x_adc_nids[1] = { |
426 | 0x03, | 430 | 0x03, |
427 | }; | 431 | }; |
428 | 432 | ||
429 | static hda_nid_t stac925x_mux_nids[1] = { | 433 | static const hda_nid_t stac925x_mux_nids[1] = { |
430 | 0x0f, | 434 | 0x0f, |
431 | }; | 435 | }; |
432 | 436 | ||
433 | static hda_nid_t stac925x_dac_nids[1] = { | 437 | static const hda_nid_t stac925x_dac_nids[1] = { |
434 | 0x02, | 438 | 0x02, |
435 | }; | 439 | }; |
436 | 440 | ||
437 | #define STAC925X_NUM_DMICS 1 | 441 | #define STAC925X_NUM_DMICS 1 |
438 | static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = { | 442 | static const hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = { |
439 | 0x15, 0 | 443 | 0x15, 0 |
440 | }; | 444 | }; |
441 | 445 | ||
442 | static hda_nid_t stac925x_dmux_nids[1] = { | 446 | static const hda_nid_t stac925x_dmux_nids[1] = { |
443 | 0x14, | 447 | 0x14, |
444 | }; | 448 | }; |
445 | 449 | ||
446 | static unsigned long stac925x_capvols[] = { | 450 | static const unsigned long stac925x_capvols[] = { |
447 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), | 451 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), |
448 | }; | 452 | }; |
449 | static unsigned long stac925x_capsws[] = { | 453 | static const unsigned long stac925x_capsws[] = { |
450 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), | 454 | HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), |
451 | }; | 455 | }; |
452 | 456 | ||
453 | static hda_nid_t stac922x_adc_nids[2] = { | 457 | static const hda_nid_t stac922x_adc_nids[2] = { |
454 | 0x06, 0x07, | 458 | 0x06, 0x07, |
455 | }; | 459 | }; |
456 | 460 | ||
457 | static hda_nid_t stac922x_mux_nids[2] = { | 461 | static const hda_nid_t stac922x_mux_nids[2] = { |
458 | 0x12, 0x13, | 462 | 0x12, 0x13, |
459 | }; | 463 | }; |
460 | 464 | ||
461 | #define STAC922X_NUM_CAPS 2 | 465 | #define STAC922X_NUM_CAPS 2 |
462 | static unsigned long stac922x_capvols[] = { | 466 | static const unsigned long stac922x_capvols[] = { |
463 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT), | 467 | HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT), |
464 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), | 468 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), |
465 | }; | 469 | }; |
466 | #define stac922x_capsws stac922x_capvols | 470 | #define stac922x_capsws stac922x_capvols |
467 | 471 | ||
468 | static hda_nid_t stac927x_slave_dig_outs[2] = { | 472 | static const hda_nid_t stac927x_slave_dig_outs[2] = { |
469 | 0x1f, 0, | 473 | 0x1f, 0, |
470 | }; | 474 | }; |
471 | 475 | ||
472 | static hda_nid_t stac927x_adc_nids[3] = { | 476 | static const hda_nid_t stac927x_adc_nids[3] = { |
473 | 0x07, 0x08, 0x09 | 477 | 0x07, 0x08, 0x09 |
474 | }; | 478 | }; |
475 | 479 | ||
476 | static hda_nid_t stac927x_mux_nids[3] = { | 480 | static const hda_nid_t stac927x_mux_nids[3] = { |
477 | 0x15, 0x16, 0x17 | 481 | 0x15, 0x16, 0x17 |
478 | }; | 482 | }; |
479 | 483 | ||
480 | static hda_nid_t stac927x_smux_nids[1] = { | 484 | static const hda_nid_t stac927x_smux_nids[1] = { |
481 | 0x21, | 485 | 0x21, |
482 | }; | 486 | }; |
483 | 487 | ||
484 | static hda_nid_t stac927x_dac_nids[6] = { | 488 | static const hda_nid_t stac927x_dac_nids[6] = { |
485 | 0x02, 0x03, 0x04, 0x05, 0x06, 0 | 489 | 0x02, 0x03, 0x04, 0x05, 0x06, 0 |
486 | }; | 490 | }; |
487 | 491 | ||
488 | static hda_nid_t stac927x_dmux_nids[1] = { | 492 | static const hda_nid_t stac927x_dmux_nids[1] = { |
489 | 0x1b, | 493 | 0x1b, |
490 | }; | 494 | }; |
491 | 495 | ||
492 | #define STAC927X_NUM_DMICS 2 | 496 | #define STAC927X_NUM_DMICS 2 |
493 | static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { | 497 | static const hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { |
494 | 0x13, 0x14, 0 | 498 | 0x13, 0x14, 0 |
495 | }; | 499 | }; |
496 | 500 | ||
497 | #define STAC927X_NUM_CAPS 3 | 501 | #define STAC927X_NUM_CAPS 3 |
498 | static unsigned long stac927x_capvols[] = { | 502 | static const unsigned long stac927x_capvols[] = { |
499 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), | 503 | HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), |
500 | HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT), | 504 | HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT), |
501 | HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT), | 505 | HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT), |
502 | }; | 506 | }; |
503 | static unsigned long stac927x_capsws[] = { | 507 | static const unsigned long stac927x_capsws[] = { |
504 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), | 508 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), |
505 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), | 509 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), |
506 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | 510 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), |
@@ -511,77 +515,77 @@ static const char * const stac927x_spdif_labels[5] = { | |||
511 | "Analog Mux 2", "Analog Mux 3" | 515 | "Analog Mux 2", "Analog Mux 3" |
512 | }; | 516 | }; |
513 | 517 | ||
514 | static hda_nid_t stac9205_adc_nids[2] = { | 518 | static const hda_nid_t stac9205_adc_nids[2] = { |
515 | 0x12, 0x13 | 519 | 0x12, 0x13 |
516 | }; | 520 | }; |
517 | 521 | ||
518 | static hda_nid_t stac9205_mux_nids[2] = { | 522 | static const hda_nid_t stac9205_mux_nids[2] = { |
519 | 0x19, 0x1a | 523 | 0x19, 0x1a |
520 | }; | 524 | }; |
521 | 525 | ||
522 | static hda_nid_t stac9205_dmux_nids[1] = { | 526 | static const hda_nid_t stac9205_dmux_nids[1] = { |
523 | 0x1d, | 527 | 0x1d, |
524 | }; | 528 | }; |
525 | 529 | ||
526 | static hda_nid_t stac9205_smux_nids[1] = { | 530 | static const hda_nid_t stac9205_smux_nids[1] = { |
527 | 0x21, | 531 | 0x21, |
528 | }; | 532 | }; |
529 | 533 | ||
530 | #define STAC9205_NUM_DMICS 2 | 534 | #define STAC9205_NUM_DMICS 2 |
531 | static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { | 535 | static const hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { |
532 | 0x17, 0x18, 0 | 536 | 0x17, 0x18, 0 |
533 | }; | 537 | }; |
534 | 538 | ||
535 | #define STAC9205_NUM_CAPS 2 | 539 | #define STAC9205_NUM_CAPS 2 |
536 | static unsigned long stac9205_capvols[] = { | 540 | static const unsigned long stac9205_capvols[] = { |
537 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT), | 541 | HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT), |
538 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT), | 542 | HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT), |
539 | }; | 543 | }; |
540 | static unsigned long stac9205_capsws[] = { | 544 | static const unsigned long stac9205_capsws[] = { |
541 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), | 545 | HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), |
542 | HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT), | 546 | HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT), |
543 | }; | 547 | }; |
544 | 548 | ||
545 | static hda_nid_t stac9200_pin_nids[8] = { | 549 | static const hda_nid_t stac9200_pin_nids[8] = { |
546 | 0x08, 0x09, 0x0d, 0x0e, | 550 | 0x08, 0x09, 0x0d, 0x0e, |
547 | 0x0f, 0x10, 0x11, 0x12, | 551 | 0x0f, 0x10, 0x11, 0x12, |
548 | }; | 552 | }; |
549 | 553 | ||
550 | static hda_nid_t stac925x_pin_nids[8] = { | 554 | static const hda_nid_t stac925x_pin_nids[8] = { |
551 | 0x07, 0x08, 0x0a, 0x0b, | 555 | 0x07, 0x08, 0x0a, 0x0b, |
552 | 0x0c, 0x0d, 0x10, 0x11, | 556 | 0x0c, 0x0d, 0x10, 0x11, |
553 | }; | 557 | }; |
554 | 558 | ||
555 | static hda_nid_t stac922x_pin_nids[10] = { | 559 | static const hda_nid_t stac922x_pin_nids[10] = { |
556 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 560 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
557 | 0x0f, 0x10, 0x11, 0x15, 0x1b, | 561 | 0x0f, 0x10, 0x11, 0x15, 0x1b, |
558 | }; | 562 | }; |
559 | 563 | ||
560 | static hda_nid_t stac92hd73xx_pin_nids[13] = { | 564 | static const hda_nid_t stac92hd73xx_pin_nids[13] = { |
561 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 565 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
562 | 0x0f, 0x10, 0x11, 0x12, 0x13, | 566 | 0x0f, 0x10, 0x11, 0x12, 0x13, |
563 | 0x14, 0x22, 0x23 | 567 | 0x14, 0x22, 0x23 |
564 | }; | 568 | }; |
565 | 569 | ||
566 | #define STAC92HD71BXX_NUM_PINS 13 | 570 | #define STAC92HD71BXX_NUM_PINS 13 |
567 | static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { | 571 | static const hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { |
568 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, | 572 | 0x0a, 0x0b, 0x0c, 0x0d, 0x00, |
569 | 0x00, 0x14, 0x18, 0x19, 0x1e, | 573 | 0x00, 0x14, 0x18, 0x19, 0x1e, |
570 | 0x1f, 0x20, 0x27 | 574 | 0x1f, 0x20, 0x27 |
571 | }; | 575 | }; |
572 | static hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { | 576 | static const hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { |
573 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 577 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
574 | 0x0f, 0x14, 0x18, 0x19, 0x1e, | 578 | 0x0f, 0x14, 0x18, 0x19, 0x1e, |
575 | 0x1f, 0x20, 0x27 | 579 | 0x1f, 0x20, 0x27 |
576 | }; | 580 | }; |
577 | 581 | ||
578 | static hda_nid_t stac927x_pin_nids[14] = { | 582 | static const hda_nid_t stac927x_pin_nids[14] = { |
579 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 583 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
580 | 0x0f, 0x10, 0x11, 0x12, 0x13, | 584 | 0x0f, 0x10, 0x11, 0x12, 0x13, |
581 | 0x14, 0x21, 0x22, 0x23, | 585 | 0x14, 0x21, 0x22, 0x23, |
582 | }; | 586 | }; |
583 | 587 | ||
584 | static hda_nid_t stac9205_pin_nids[12] = { | 588 | static const hda_nid_t stac9205_pin_nids[12] = { |
585 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, | 589 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, |
586 | 0x0f, 0x14, 0x16, 0x17, 0x18, | 590 | 0x0f, 0x14, 0x16, 0x17, 0x18, |
587 | 0x21, 0x22, | 591 | 0x21, 0x22, |
@@ -841,45 +845,45 @@ static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol, | |||
841 | return 1; | 845 | return 1; |
842 | } | 846 | } |
843 | 847 | ||
844 | static struct hda_verb stac9200_core_init[] = { | 848 | static const struct hda_verb stac9200_core_init[] = { |
845 | /* set dac0mux for dac converter */ | 849 | /* set dac0mux for dac converter */ |
846 | { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | 850 | { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, |
847 | {} | 851 | {} |
848 | }; | 852 | }; |
849 | 853 | ||
850 | static struct hda_verb stac9200_eapd_init[] = { | 854 | static const struct hda_verb stac9200_eapd_init[] = { |
851 | /* set dac0mux for dac converter */ | 855 | /* set dac0mux for dac converter */ |
852 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, | 856 | {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, |
853 | {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, | 857 | {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, |
854 | {} | 858 | {} |
855 | }; | 859 | }; |
856 | 860 | ||
857 | static struct hda_verb dell_eq_core_init[] = { | 861 | static const struct hda_verb dell_eq_core_init[] = { |
858 | /* set master volume to max value without distortion | 862 | /* set master volume to max value without distortion |
859 | * and direct control */ | 863 | * and direct control */ |
860 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, | 864 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, |
861 | {} | 865 | {} |
862 | }; | 866 | }; |
863 | 867 | ||
864 | static struct hda_verb stac92hd73xx_core_init[] = { | 868 | static const struct hda_verb stac92hd73xx_core_init[] = { |
865 | /* set master volume and direct control */ | 869 | /* set master volume and direct control */ |
866 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 870 | { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
867 | {} | 871 | {} |
868 | }; | 872 | }; |
869 | 873 | ||
870 | static struct hda_verb stac92hd83xxx_core_init[] = { | 874 | static const struct hda_verb stac92hd83xxx_core_init[] = { |
871 | /* power state controls amps */ | 875 | /* power state controls amps */ |
872 | { 0x01, AC_VERB_SET_EAPD, 1 << 2}, | 876 | { 0x01, AC_VERB_SET_EAPD, 1 << 2}, |
873 | {} | 877 | {} |
874 | }; | 878 | }; |
875 | 879 | ||
876 | static struct hda_verb stac92hd71bxx_core_init[] = { | 880 | static const struct hda_verb stac92hd71bxx_core_init[] = { |
877 | /* set master volume and direct control */ | 881 | /* set master volume and direct control */ |
878 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 882 | { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
879 | {} | 883 | {} |
880 | }; | 884 | }; |
881 | 885 | ||
882 | static struct hda_verb stac92hd71bxx_unmute_core_init[] = { | 886 | static const struct hda_verb stac92hd71bxx_unmute_core_init[] = { |
883 | /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ | 887 | /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ |
884 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 888 | { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
885 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 889 | { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -887,7 +891,7 @@ static struct hda_verb stac92hd71bxx_unmute_core_init[] = { | |||
887 | {} | 891 | {} |
888 | }; | 892 | }; |
889 | 893 | ||
890 | static struct hda_verb stac925x_core_init[] = { | 894 | static const struct hda_verb stac925x_core_init[] = { |
891 | /* set dac0mux for dac converter */ | 895 | /* set dac0mux for dac converter */ |
892 | { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, | 896 | { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, |
893 | /* mute the master volume */ | 897 | /* mute the master volume */ |
@@ -895,13 +899,13 @@ static struct hda_verb stac925x_core_init[] = { | |||
895 | {} | 899 | {} |
896 | }; | 900 | }; |
897 | 901 | ||
898 | static struct hda_verb stac922x_core_init[] = { | 902 | static const struct hda_verb stac922x_core_init[] = { |
899 | /* set master volume and direct control */ | 903 | /* set master volume and direct control */ |
900 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 904 | { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
901 | {} | 905 | {} |
902 | }; | 906 | }; |
903 | 907 | ||
904 | static struct hda_verb d965_core_init[] = { | 908 | static const struct hda_verb d965_core_init[] = { |
905 | /* set master volume and direct control */ | 909 | /* set master volume and direct control */ |
906 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 910 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
907 | /* unmute node 0x1b */ | 911 | /* unmute node 0x1b */ |
@@ -911,7 +915,7 @@ static struct hda_verb d965_core_init[] = { | |||
911 | {} | 915 | {} |
912 | }; | 916 | }; |
913 | 917 | ||
914 | static struct hda_verb dell_3st_core_init[] = { | 918 | static const struct hda_verb dell_3st_core_init[] = { |
915 | /* don't set delta bit */ | 919 | /* don't set delta bit */ |
916 | {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, | 920 | {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, |
917 | /* unmute node 0x1b */ | 921 | /* unmute node 0x1b */ |
@@ -921,7 +925,7 @@ static struct hda_verb dell_3st_core_init[] = { | |||
921 | {} | 925 | {} |
922 | }; | 926 | }; |
923 | 927 | ||
924 | static struct hda_verb stac927x_core_init[] = { | 928 | static const struct hda_verb stac927x_core_init[] = { |
925 | /* set master volume and direct control */ | 929 | /* set master volume and direct control */ |
926 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 930 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
927 | /* enable analog pc beep path */ | 931 | /* enable analog pc beep path */ |
@@ -929,7 +933,7 @@ static struct hda_verb stac927x_core_init[] = { | |||
929 | {} | 933 | {} |
930 | }; | 934 | }; |
931 | 935 | ||
932 | static struct hda_verb stac927x_volknob_core_init[] = { | 936 | static const struct hda_verb stac927x_volknob_core_init[] = { |
933 | /* don't set delta bit */ | 937 | /* don't set delta bit */ |
934 | {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, | 938 | {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, |
935 | /* enable analog pc beep path */ | 939 | /* enable analog pc beep path */ |
@@ -937,7 +941,7 @@ static struct hda_verb stac927x_volknob_core_init[] = { | |||
937 | {} | 941 | {} |
938 | }; | 942 | }; |
939 | 943 | ||
940 | static struct hda_verb stac9205_core_init[] = { | 944 | static const struct hda_verb stac9205_core_init[] = { |
941 | /* set master volume and direct control */ | 945 | /* set master volume and direct control */ |
942 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, | 946 | { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, |
943 | /* enable analog pc beep path */ | 947 | /* enable analog pc beep path */ |
@@ -977,7 +981,7 @@ static struct hda_verb stac9205_core_init[] = { | |||
977 | .private_value = nid, \ | 981 | .private_value = nid, \ |
978 | } | 982 | } |
979 | 983 | ||
980 | static struct snd_kcontrol_new stac9200_mixer[] = { | 984 | static const struct snd_kcontrol_new stac9200_mixer[] = { |
981 | HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT), | 985 | HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT), |
982 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), | 986 | HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), |
983 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), | 987 | HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), |
@@ -985,38 +989,38 @@ static struct snd_kcontrol_new stac9200_mixer[] = { | |||
985 | { } /* end */ | 989 | { } /* end */ |
986 | }; | 990 | }; |
987 | 991 | ||
988 | static struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { | 992 | static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { |
989 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), | 993 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), |
990 | {} | 994 | {} |
991 | }; | 995 | }; |
992 | 996 | ||
993 | static struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = { | 997 | static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = { |
994 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), | 998 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), |
995 | {} | 999 | {} |
996 | }; | 1000 | }; |
997 | 1001 | ||
998 | static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { | 1002 | static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { |
999 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), | 1003 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), |
1000 | {} | 1004 | {} |
1001 | }; | 1005 | }; |
1002 | 1006 | ||
1003 | 1007 | ||
1004 | static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { | 1008 | static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = { |
1005 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) | 1009 | STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) |
1006 | }; | 1010 | }; |
1007 | 1011 | ||
1008 | static struct snd_kcontrol_new stac925x_mixer[] = { | 1012 | static const struct snd_kcontrol_new stac925x_mixer[] = { |
1009 | HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT), | 1013 | HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT), |
1010 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), | 1014 | HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), |
1011 | { } /* end */ | 1015 | { } /* end */ |
1012 | }; | 1016 | }; |
1013 | 1017 | ||
1014 | static struct snd_kcontrol_new stac9205_loopback[] = { | 1018 | static const struct snd_kcontrol_new stac9205_loopback[] = { |
1015 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), | 1019 | STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), |
1016 | {} | 1020 | {} |
1017 | }; | 1021 | }; |
1018 | 1022 | ||
1019 | static struct snd_kcontrol_new stac927x_loopback[] = { | 1023 | static const struct snd_kcontrol_new stac927x_loopback[] = { |
1020 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), | 1024 | STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), |
1021 | {} | 1025 | {} |
1022 | }; | 1026 | }; |
@@ -1182,16 +1186,16 @@ static int stac92xx_build_controls(struct hda_codec *codec) | |||
1182 | return 0; | 1186 | return 0; |
1183 | } | 1187 | } |
1184 | 1188 | ||
1185 | static unsigned int ref9200_pin_configs[8] = { | 1189 | static const unsigned int ref9200_pin_configs[8] = { |
1186 | 0x01c47010, 0x01447010, 0x0221401f, 0x01114010, | 1190 | 0x01c47010, 0x01447010, 0x0221401f, 0x01114010, |
1187 | 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, | 1191 | 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, |
1188 | }; | 1192 | }; |
1189 | 1193 | ||
1190 | static unsigned int gateway9200_m4_pin_configs[8] = { | 1194 | static const unsigned int gateway9200_m4_pin_configs[8] = { |
1191 | 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, | 1195 | 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, |
1192 | 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, | 1196 | 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, |
1193 | }; | 1197 | }; |
1194 | static unsigned int gateway9200_m4_2_pin_configs[8] = { | 1198 | static const unsigned int gateway9200_m4_2_pin_configs[8] = { |
1195 | 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, | 1199 | 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, |
1196 | 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, | 1200 | 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, |
1197 | }; | 1201 | }; |
@@ -1202,7 +1206,7 @@ static unsigned int gateway9200_m4_2_pin_configs[8] = { | |||
1202 | 102801DE | 1206 | 102801DE |
1203 | 102801E8 | 1207 | 102801E8 |
1204 | */ | 1208 | */ |
1205 | static unsigned int dell9200_d21_pin_configs[8] = { | 1209 | static const unsigned int dell9200_d21_pin_configs[8] = { |
1206 | 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, | 1210 | 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, |
1207 | 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, | 1211 | 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, |
1208 | }; | 1212 | }; |
@@ -1212,7 +1216,7 @@ static unsigned int dell9200_d21_pin_configs[8] = { | |||
1212 | 102801C0 | 1216 | 102801C0 |
1213 | 102801C1 | 1217 | 102801C1 |
1214 | */ | 1218 | */ |
1215 | static unsigned int dell9200_d22_pin_configs[8] = { | 1219 | static const unsigned int dell9200_d22_pin_configs[8] = { |
1216 | 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, | 1220 | 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, |
1217 | 0x01813020, 0x02a19021, 0x90100140, 0x400001f2, | 1221 | 0x01813020, 0x02a19021, 0x90100140, 0x400001f2, |
1218 | }; | 1222 | }; |
@@ -1226,7 +1230,7 @@ static unsigned int dell9200_d22_pin_configs[8] = { | |||
1226 | 102801DA | 1230 | 102801DA |
1227 | 102801E3 | 1231 | 102801E3 |
1228 | */ | 1232 | */ |
1229 | static unsigned int dell9200_d23_pin_configs[8] = { | 1233 | static const unsigned int dell9200_d23_pin_configs[8] = { |
1230 | 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, | 1234 | 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, |
1231 | 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, | 1235 | 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, |
1232 | }; | 1236 | }; |
@@ -1237,7 +1241,7 @@ static unsigned int dell9200_d23_pin_configs[8] = { | |||
1237 | 102801B5 (Dell Inspiron 630m) | 1241 | 102801B5 (Dell Inspiron 630m) |
1238 | 102801D8 (Dell Inspiron 640m) | 1242 | 102801D8 (Dell Inspiron 640m) |
1239 | */ | 1243 | */ |
1240 | static unsigned int dell9200_m21_pin_configs[8] = { | 1244 | static const unsigned int dell9200_m21_pin_configs[8] = { |
1241 | 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310, | 1245 | 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310, |
1242 | 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd, | 1246 | 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd, |
1243 | }; | 1247 | }; |
@@ -1250,7 +1254,7 @@ static unsigned int dell9200_m21_pin_configs[8] = { | |||
1250 | 102801D4 | 1254 | 102801D4 |
1251 | 102801D6 | 1255 | 102801D6 |
1252 | */ | 1256 | */ |
1253 | static unsigned int dell9200_m22_pin_configs[8] = { | 1257 | static const unsigned int dell9200_m22_pin_configs[8] = { |
1254 | 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, | 1258 | 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, |
1255 | 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc, | 1259 | 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc, |
1256 | }; | 1260 | }; |
@@ -1260,7 +1264,7 @@ static unsigned int dell9200_m22_pin_configs[8] = { | |||
1260 | 102801CE (Dell XPS M1710) | 1264 | 102801CE (Dell XPS M1710) |
1261 | 102801CF (Dell Precision M90) | 1265 | 102801CF (Dell Precision M90) |
1262 | */ | 1266 | */ |
1263 | static unsigned int dell9200_m23_pin_configs[8] = { | 1267 | static const unsigned int dell9200_m23_pin_configs[8] = { |
1264 | 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310, | 1268 | 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310, |
1265 | 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc, | 1269 | 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc, |
1266 | }; | 1270 | }; |
@@ -1272,7 +1276,7 @@ static unsigned int dell9200_m23_pin_configs[8] = { | |||
1272 | 102801CB (Dell Latitude 120L) | 1276 | 102801CB (Dell Latitude 120L) |
1273 | 102801D3 | 1277 | 102801D3 |
1274 | */ | 1278 | */ |
1275 | static unsigned int dell9200_m24_pin_configs[8] = { | 1279 | static const unsigned int dell9200_m24_pin_configs[8] = { |
1276 | 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, | 1280 | 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, |
1277 | 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, | 1281 | 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, |
1278 | }; | 1282 | }; |
@@ -1283,7 +1287,7 @@ static unsigned int dell9200_m24_pin_configs[8] = { | |||
1283 | 102801EE | 1287 | 102801EE |
1284 | 102801EF | 1288 | 102801EF |
1285 | */ | 1289 | */ |
1286 | static unsigned int dell9200_m25_pin_configs[8] = { | 1290 | static const unsigned int dell9200_m25_pin_configs[8] = { |
1287 | 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, | 1291 | 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, |
1288 | 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd, | 1292 | 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd, |
1289 | }; | 1293 | }; |
@@ -1293,7 +1297,7 @@ static unsigned int dell9200_m25_pin_configs[8] = { | |||
1293 | 102801F5 (Dell Inspiron 1501) | 1297 | 102801F5 (Dell Inspiron 1501) |
1294 | 102801F6 | 1298 | 102801F6 |
1295 | */ | 1299 | */ |
1296 | static unsigned int dell9200_m26_pin_configs[8] = { | 1300 | static const unsigned int dell9200_m26_pin_configs[8] = { |
1297 | 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, | 1301 | 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, |
1298 | 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe, | 1302 | 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe, |
1299 | }; | 1303 | }; |
@@ -1302,18 +1306,18 @@ static unsigned int dell9200_m26_pin_configs[8] = { | |||
1302 | STAC 9200-32 | 1306 | STAC 9200-32 |
1303 | 102801CD (Dell Inspiron E1705/9400) | 1307 | 102801CD (Dell Inspiron E1705/9400) |
1304 | */ | 1308 | */ |
1305 | static unsigned int dell9200_m27_pin_configs[8] = { | 1309 | static const unsigned int dell9200_m27_pin_configs[8] = { |
1306 | 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, | 1310 | 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, |
1307 | 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, | 1311 | 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, |
1308 | }; | 1312 | }; |
1309 | 1313 | ||
1310 | static unsigned int oqo9200_pin_configs[8] = { | 1314 | static const unsigned int oqo9200_pin_configs[8] = { |
1311 | 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210, | 1315 | 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210, |
1312 | 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3, | 1316 | 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3, |
1313 | }; | 1317 | }; |
1314 | 1318 | ||
1315 | 1319 | ||
1316 | static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { | 1320 | static const unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { |
1317 | [STAC_REF] = ref9200_pin_configs, | 1321 | [STAC_REF] = ref9200_pin_configs, |
1318 | [STAC_9200_OQO] = oqo9200_pin_configs, | 1322 | [STAC_9200_OQO] = oqo9200_pin_configs, |
1319 | [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, | 1323 | [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, |
@@ -1350,7 +1354,7 @@ static const char * const stac9200_models[STAC_9200_MODELS] = { | |||
1350 | [STAC_9200_PANASONIC] = "panasonic", | 1354 | [STAC_9200_PANASONIC] = "panasonic", |
1351 | }; | 1355 | }; |
1352 | 1356 | ||
1353 | static struct snd_pci_quirk stac9200_cfg_tbl[] = { | 1357 | static const struct snd_pci_quirk stac9200_cfg_tbl[] = { |
1354 | /* SigmaTel reference board */ | 1358 | /* SigmaTel reference board */ |
1355 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1359 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1356 | "DFI LanParty", STAC_REF), | 1360 | "DFI LanParty", STAC_REF), |
@@ -1426,47 +1430,47 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { | |||
1426 | {} /* terminator */ | 1430 | {} /* terminator */ |
1427 | }; | 1431 | }; |
1428 | 1432 | ||
1429 | static unsigned int ref925x_pin_configs[8] = { | 1433 | static const unsigned int ref925x_pin_configs[8] = { |
1430 | 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, | 1434 | 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, |
1431 | 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, | 1435 | 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, |
1432 | }; | 1436 | }; |
1433 | 1437 | ||
1434 | static unsigned int stac925xM1_pin_configs[8] = { | 1438 | static const unsigned int stac925xM1_pin_configs[8] = { |
1435 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1439 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, |
1436 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | 1440 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, |
1437 | }; | 1441 | }; |
1438 | 1442 | ||
1439 | static unsigned int stac925xM1_2_pin_configs[8] = { | 1443 | static const unsigned int stac925xM1_2_pin_configs[8] = { |
1440 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1444 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, |
1441 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | 1445 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, |
1442 | }; | 1446 | }; |
1443 | 1447 | ||
1444 | static unsigned int stac925xM2_pin_configs[8] = { | 1448 | static const unsigned int stac925xM2_pin_configs[8] = { |
1445 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1449 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, |
1446 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | 1450 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, |
1447 | }; | 1451 | }; |
1448 | 1452 | ||
1449 | static unsigned int stac925xM2_2_pin_configs[8] = { | 1453 | static const unsigned int stac925xM2_2_pin_configs[8] = { |
1450 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1454 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, |
1451 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | 1455 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, |
1452 | }; | 1456 | }; |
1453 | 1457 | ||
1454 | static unsigned int stac925xM3_pin_configs[8] = { | 1458 | static const unsigned int stac925xM3_pin_configs[8] = { |
1455 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1459 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, |
1456 | 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, | 1460 | 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, |
1457 | }; | 1461 | }; |
1458 | 1462 | ||
1459 | static unsigned int stac925xM5_pin_configs[8] = { | 1463 | static const unsigned int stac925xM5_pin_configs[8] = { |
1460 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1464 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, |
1461 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, | 1465 | 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, |
1462 | }; | 1466 | }; |
1463 | 1467 | ||
1464 | static unsigned int stac925xM6_pin_configs[8] = { | 1468 | static const unsigned int stac925xM6_pin_configs[8] = { |
1465 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, | 1469 | 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, |
1466 | 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, | 1470 | 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, |
1467 | }; | 1471 | }; |
1468 | 1472 | ||
1469 | static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { | 1473 | static const unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { |
1470 | [STAC_REF] = ref925x_pin_configs, | 1474 | [STAC_REF] = ref925x_pin_configs, |
1471 | [STAC_M1] = stac925xM1_pin_configs, | 1475 | [STAC_M1] = stac925xM1_pin_configs, |
1472 | [STAC_M1_2] = stac925xM1_2_pin_configs, | 1476 | [STAC_M1_2] = stac925xM1_2_pin_configs, |
@@ -1489,7 +1493,7 @@ static const char * const stac925x_models[STAC_925x_MODELS] = { | |||
1489 | [STAC_M6] = "m6", | 1493 | [STAC_M6] = "m6", |
1490 | }; | 1494 | }; |
1491 | 1495 | ||
1492 | static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { | 1496 | static const struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { |
1493 | SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), | 1497 | SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), |
1494 | SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), | 1498 | SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), |
1495 | SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), | 1499 | SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), |
@@ -1503,7 +1507,7 @@ static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { | |||
1503 | {} /* terminator */ | 1507 | {} /* terminator */ |
1504 | }; | 1508 | }; |
1505 | 1509 | ||
1506 | static struct snd_pci_quirk stac925x_cfg_tbl[] = { | 1510 | static const struct snd_pci_quirk stac925x_cfg_tbl[] = { |
1507 | /* SigmaTel reference board */ | 1511 | /* SigmaTel reference board */ |
1508 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), | 1512 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), |
1509 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), | 1513 | SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), |
@@ -1515,33 +1519,33 @@ static struct snd_pci_quirk stac925x_cfg_tbl[] = { | |||
1515 | {} /* terminator */ | 1519 | {} /* terminator */ |
1516 | }; | 1520 | }; |
1517 | 1521 | ||
1518 | static unsigned int ref92hd73xx_pin_configs[13] = { | 1522 | static const unsigned int ref92hd73xx_pin_configs[13] = { |
1519 | 0x02214030, 0x02a19040, 0x01a19020, 0x02214030, | 1523 | 0x02214030, 0x02a19040, 0x01a19020, 0x02214030, |
1520 | 0x0181302e, 0x01014010, 0x01014020, 0x01014030, | 1524 | 0x0181302e, 0x01014010, 0x01014020, 0x01014030, |
1521 | 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050, | 1525 | 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050, |
1522 | 0x01452050, | 1526 | 0x01452050, |
1523 | }; | 1527 | }; |
1524 | 1528 | ||
1525 | static unsigned int dell_m6_pin_configs[13] = { | 1529 | static const unsigned int dell_m6_pin_configs[13] = { |
1526 | 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110, | 1530 | 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110, |
1527 | 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0, | 1531 | 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0, |
1528 | 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, | 1532 | 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, |
1529 | 0x4f0000f0, | 1533 | 0x4f0000f0, |
1530 | }; | 1534 | }; |
1531 | 1535 | ||
1532 | static unsigned int alienware_m17x_pin_configs[13] = { | 1536 | static const unsigned int alienware_m17x_pin_configs[13] = { |
1533 | 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020, | 1537 | 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020, |
1534 | 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, | 1538 | 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, |
1535 | 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, | 1539 | 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, |
1536 | 0x904601b0, | 1540 | 0x904601b0, |
1537 | }; | 1541 | }; |
1538 | 1542 | ||
1539 | static unsigned int intel_dg45id_pin_configs[13] = { | 1543 | static const unsigned int intel_dg45id_pin_configs[13] = { |
1540 | 0x02214230, 0x02A19240, 0x01013214, 0x01014210, | 1544 | 0x02214230, 0x02A19240, 0x01013214, 0x01014210, |
1541 | 0x01A19250, 0x01011212, 0x01016211 | 1545 | 0x01A19250, 0x01011212, 0x01016211 |
1542 | }; | 1546 | }; |
1543 | 1547 | ||
1544 | static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { | 1548 | static const unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { |
1545 | [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, | 1549 | [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, |
1546 | [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, | 1550 | [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, |
1547 | [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, | 1551 | [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, |
@@ -1563,7 +1567,7 @@ static const char * const stac92hd73xx_models[STAC_92HD73XX_MODELS] = { | |||
1563 | [STAC_ALIENWARE_M17X] = "alienware", | 1567 | [STAC_ALIENWARE_M17X] = "alienware", |
1564 | }; | 1568 | }; |
1565 | 1569 | ||
1566 | static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | 1570 | static const struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { |
1567 | /* SigmaTel reference board */ | 1571 | /* SigmaTel reference board */ |
1568 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1572 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1569 | "DFI LanParty", STAC_92HD73XX_REF), | 1573 | "DFI LanParty", STAC_92HD73XX_REF), |
@@ -1600,11 +1604,11 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { | |||
1600 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe, | 1604 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe, |
1601 | "Dell Studio XPS 1645", STAC_DELL_M6_BOTH), | 1605 | "Dell Studio XPS 1645", STAC_DELL_M6_BOTH), |
1602 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, | 1606 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, |
1603 | "Dell Studio 1558", STAC_DELL_M6_BOTH), | 1607 | "Dell Studio 1558", STAC_DELL_M6_DMIC), |
1604 | {} /* terminator */ | 1608 | {} /* terminator */ |
1605 | }; | 1609 | }; |
1606 | 1610 | ||
1607 | static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { | 1611 | static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { |
1608 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, | 1612 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, |
1609 | "Alienware M17x", STAC_ALIENWARE_M17X), | 1613 | "Alienware M17x", STAC_ALIENWARE_M17X), |
1610 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, | 1614 | SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, |
@@ -1612,25 +1616,25 @@ static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { | |||
1612 | {} /* terminator */ | 1616 | {} /* terminator */ |
1613 | }; | 1617 | }; |
1614 | 1618 | ||
1615 | static unsigned int ref92hd83xxx_pin_configs[10] = { | 1619 | static const unsigned int ref92hd83xxx_pin_configs[10] = { |
1616 | 0x02214030, 0x02211010, 0x02a19020, 0x02170130, | 1620 | 0x02214030, 0x02211010, 0x02a19020, 0x02170130, |
1617 | 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, | 1621 | 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, |
1618 | 0x01451160, 0x98560170, | 1622 | 0x01451160, 0x98560170, |
1619 | }; | 1623 | }; |
1620 | 1624 | ||
1621 | static unsigned int dell_s14_pin_configs[10] = { | 1625 | static const unsigned int dell_s14_pin_configs[10] = { |
1622 | 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110, | 1626 | 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110, |
1623 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160, | 1627 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160, |
1624 | 0x40f000f0, 0x40f000f0, | 1628 | 0x40f000f0, 0x40f000f0, |
1625 | }; | 1629 | }; |
1626 | 1630 | ||
1627 | static unsigned int hp_dv7_4000_pin_configs[10] = { | 1631 | static const unsigned int hp_dv7_4000_pin_configs[10] = { |
1628 | 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, | 1632 | 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, |
1629 | 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, | 1633 | 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, |
1630 | 0x40f000f0, 0x40f000f0, | 1634 | 0x40f000f0, 0x40f000f0, |
1631 | }; | 1635 | }; |
1632 | 1636 | ||
1633 | static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { | 1637 | static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { |
1634 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, | 1638 | [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, |
1635 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, | 1639 | [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, |
1636 | [STAC_DELL_S14] = dell_s14_pin_configs, | 1640 | [STAC_DELL_S14] = dell_s14_pin_configs, |
@@ -1646,7 +1650,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { | |||
1646 | [STAC_HP_DV7_4000] = "hp-dv7-4000", | 1650 | [STAC_HP_DV7_4000] = "hp-dv7-4000", |
1647 | }; | 1651 | }; |
1648 | 1652 | ||
1649 | static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | 1653 | static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { |
1650 | /* SigmaTel reference board */ | 1654 | /* SigmaTel reference board */ |
1651 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1655 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1652 | "DFI LanParty", STAC_92HD83XXX_REF), | 1656 | "DFI LanParty", STAC_92HD83XXX_REF), |
@@ -1659,35 +1663,35 @@ static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { | |||
1659 | {} /* terminator */ | 1663 | {} /* terminator */ |
1660 | }; | 1664 | }; |
1661 | 1665 | ||
1662 | static unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { | 1666 | static const unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1663 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, | 1667 | 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, |
1664 | 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, | 1668 | 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, |
1665 | 0x90a000f0, 0x01452050, 0x01452050, 0x00000000, | 1669 | 0x90a000f0, 0x01452050, 0x01452050, 0x00000000, |
1666 | 0x00000000 | 1670 | 0x00000000 |
1667 | }; | 1671 | }; |
1668 | 1672 | ||
1669 | static unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { | 1673 | static const unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1670 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, | 1674 | 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, |
1671 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, | 1675 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, |
1672 | 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000, | 1676 | 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000, |
1673 | 0x00000000 | 1677 | 0x00000000 |
1674 | }; | 1678 | }; |
1675 | 1679 | ||
1676 | static unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { | 1680 | static const unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1677 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 1681 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, |
1678 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, | 1682 | 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, |
1679 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, | 1683 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, |
1680 | 0x00000000 | 1684 | 0x00000000 |
1681 | }; | 1685 | }; |
1682 | 1686 | ||
1683 | static unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { | 1687 | static const unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { |
1684 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, | 1688 | 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, |
1685 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, | 1689 | 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, |
1686 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, | 1690 | 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, |
1687 | 0x00000000 | 1691 | 0x00000000 |
1688 | }; | 1692 | }; |
1689 | 1693 | ||
1690 | static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { | 1694 | static const unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { |
1691 | [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, | 1695 | [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, |
1692 | [STAC_DELL_M4_1] = dell_m4_1_pin_configs, | 1696 | [STAC_DELL_M4_1] = dell_m4_1_pin_configs, |
1693 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, | 1697 | [STAC_DELL_M4_2] = dell_m4_2_pin_configs, |
@@ -1712,7 +1716,7 @@ static const char * const stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { | |||
1712 | [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", | 1716 | [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", |
1713 | }; | 1717 | }; |
1714 | 1718 | ||
1715 | static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | 1719 | static const struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { |
1716 | /* SigmaTel reference board */ | 1720 | /* SigmaTel reference board */ |
1717 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1721 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1718 | "DFI LanParty", STAC_92HD71BXX_REF), | 1722 | "DFI LanParty", STAC_92HD71BXX_REF), |
@@ -1769,7 +1773,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { | |||
1769 | {} /* terminator */ | 1773 | {} /* terminator */ |
1770 | }; | 1774 | }; |
1771 | 1775 | ||
1772 | static unsigned int ref922x_pin_configs[10] = { | 1776 | static const unsigned int ref922x_pin_configs[10] = { |
1773 | 0x01014010, 0x01016011, 0x01012012, 0x0221401f, | 1777 | 0x01014010, 0x01016011, 0x01012012, 0x0221401f, |
1774 | 0x01813122, 0x01011014, 0x01441030, 0x01c41030, | 1778 | 0x01813122, 0x01011014, 0x01441030, 0x01c41030, |
1775 | 0x40000100, 0x40000100, | 1779 | 0x40000100, 0x40000100, |
@@ -1783,7 +1787,7 @@ static unsigned int ref922x_pin_configs[10] = { | |||
1783 | 102801D1 | 1787 | 102801D1 |
1784 | 102801D2 | 1788 | 102801D2 |
1785 | */ | 1789 | */ |
1786 | static unsigned int dell_922x_d81_pin_configs[10] = { | 1790 | static const unsigned int dell_922x_d81_pin_configs[10] = { |
1787 | 0x02214030, 0x01a19021, 0x01111012, 0x01114010, | 1791 | 0x02214030, 0x01a19021, 0x01111012, 0x01114010, |
1788 | 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1, | 1792 | 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1, |
1789 | 0x01813122, 0x400001f2, | 1793 | 0x01813122, 0x400001f2, |
@@ -1794,7 +1798,7 @@ static unsigned int dell_922x_d81_pin_configs[10] = { | |||
1794 | 102801AC | 1798 | 102801AC |
1795 | 102801D0 | 1799 | 102801D0 |
1796 | */ | 1800 | */ |
1797 | static unsigned int dell_922x_d82_pin_configs[10] = { | 1801 | static const unsigned int dell_922x_d82_pin_configs[10] = { |
1798 | 0x02214030, 0x01a19021, 0x01111012, 0x01114010, | 1802 | 0x02214030, 0x01a19021, 0x01111012, 0x01114010, |
1799 | 0x02a19020, 0x01117011, 0x01451140, 0x400001f0, | 1803 | 0x02a19020, 0x01117011, 0x01451140, 0x400001f0, |
1800 | 0x01813122, 0x400001f1, | 1804 | 0x01813122, 0x400001f1, |
@@ -1804,7 +1808,7 @@ static unsigned int dell_922x_d82_pin_configs[10] = { | |||
1804 | STAC 922X pin configs for | 1808 | STAC 922X pin configs for |
1805 | 102801BF | 1809 | 102801BF |
1806 | */ | 1810 | */ |
1807 | static unsigned int dell_922x_m81_pin_configs[10] = { | 1811 | static const unsigned int dell_922x_m81_pin_configs[10] = { |
1808 | 0x0321101f, 0x01112024, 0x01111222, 0x91174220, | 1812 | 0x0321101f, 0x01112024, 0x01111222, 0x91174220, |
1809 | 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, | 1813 | 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, |
1810 | 0x40C003f1, 0x405003f0, | 1814 | 0x40C003f1, 0x405003f0, |
@@ -1814,61 +1818,61 @@ static unsigned int dell_922x_m81_pin_configs[10] = { | |||
1814 | STAC 9221 A1 pin configs for | 1818 | STAC 9221 A1 pin configs for |
1815 | 102801D7 (Dell XPS M1210) | 1819 | 102801D7 (Dell XPS M1210) |
1816 | */ | 1820 | */ |
1817 | static unsigned int dell_922x_m82_pin_configs[10] = { | 1821 | static const unsigned int dell_922x_m82_pin_configs[10] = { |
1818 | 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, | 1822 | 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, |
1819 | 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, | 1823 | 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, |
1820 | 0x508003f3, 0x405003f4, | 1824 | 0x508003f3, 0x405003f4, |
1821 | }; | 1825 | }; |
1822 | 1826 | ||
1823 | static unsigned int d945gtp3_pin_configs[10] = { | 1827 | static const unsigned int d945gtp3_pin_configs[10] = { |
1824 | 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, | 1828 | 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, |
1825 | 0x40000100, 0x40000100, 0x40000100, 0x40000100, | 1829 | 0x40000100, 0x40000100, 0x40000100, 0x40000100, |
1826 | 0x02a19120, 0x40000100, | 1830 | 0x02a19120, 0x40000100, |
1827 | }; | 1831 | }; |
1828 | 1832 | ||
1829 | static unsigned int d945gtp5_pin_configs[10] = { | 1833 | static const unsigned int d945gtp5_pin_configs[10] = { |
1830 | 0x0221401f, 0x01011012, 0x01813024, 0x01014010, | 1834 | 0x0221401f, 0x01011012, 0x01813024, 0x01014010, |
1831 | 0x01a19021, 0x01016011, 0x01452130, 0x40000100, | 1835 | 0x01a19021, 0x01016011, 0x01452130, 0x40000100, |
1832 | 0x02a19320, 0x40000100, | 1836 | 0x02a19320, 0x40000100, |
1833 | }; | 1837 | }; |
1834 | 1838 | ||
1835 | static unsigned int intel_mac_v1_pin_configs[10] = { | 1839 | static const unsigned int intel_mac_v1_pin_configs[10] = { |
1836 | 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, | 1840 | 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, |
1837 | 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, | 1841 | 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, |
1838 | 0x400000fc, 0x400000fb, | 1842 | 0x400000fc, 0x400000fb, |
1839 | }; | 1843 | }; |
1840 | 1844 | ||
1841 | static unsigned int intel_mac_v2_pin_configs[10] = { | 1845 | static const unsigned int intel_mac_v2_pin_configs[10] = { |
1842 | 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, | 1846 | 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, |
1843 | 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, | 1847 | 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, |
1844 | 0x400000fc, 0x400000fb, | 1848 | 0x400000fc, 0x400000fb, |
1845 | }; | 1849 | }; |
1846 | 1850 | ||
1847 | static unsigned int intel_mac_v3_pin_configs[10] = { | 1851 | static const unsigned int intel_mac_v3_pin_configs[10] = { |
1848 | 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, | 1852 | 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, |
1849 | 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, | 1853 | 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, |
1850 | 0x400000fc, 0x400000fb, | 1854 | 0x400000fc, 0x400000fb, |
1851 | }; | 1855 | }; |
1852 | 1856 | ||
1853 | static unsigned int intel_mac_v4_pin_configs[10] = { | 1857 | static const unsigned int intel_mac_v4_pin_configs[10] = { |
1854 | 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, | 1858 | 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, |
1855 | 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, | 1859 | 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, |
1856 | 0x400000fc, 0x400000fb, | 1860 | 0x400000fc, 0x400000fb, |
1857 | }; | 1861 | }; |
1858 | 1862 | ||
1859 | static unsigned int intel_mac_v5_pin_configs[10] = { | 1863 | static const unsigned int intel_mac_v5_pin_configs[10] = { |
1860 | 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, | 1864 | 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, |
1861 | 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, | 1865 | 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, |
1862 | 0x400000fc, 0x400000fb, | 1866 | 0x400000fc, 0x400000fb, |
1863 | }; | 1867 | }; |
1864 | 1868 | ||
1865 | static unsigned int ecs202_pin_configs[10] = { | 1869 | static const unsigned int ecs202_pin_configs[10] = { |
1866 | 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010, | 1870 | 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010, |
1867 | 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1, | 1871 | 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1, |
1868 | 0x9037012e, 0x40e000f2, | 1872 | 0x9037012e, 0x40e000f2, |
1869 | }; | 1873 | }; |
1870 | 1874 | ||
1871 | static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { | 1875 | static const unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { |
1872 | [STAC_D945_REF] = ref922x_pin_configs, | 1876 | [STAC_D945_REF] = ref922x_pin_configs, |
1873 | [STAC_D945GTP3] = d945gtp3_pin_configs, | 1877 | [STAC_D945GTP3] = d945gtp3_pin_configs, |
1874 | [STAC_D945GTP5] = d945gtp5_pin_configs, | 1878 | [STAC_D945GTP5] = d945gtp5_pin_configs, |
@@ -1917,7 +1921,7 @@ static const char * const stac922x_models[STAC_922X_MODELS] = { | |||
1917 | [STAC_922X_DELL_M82] = "dell-m82", | 1921 | [STAC_922X_DELL_M82] = "dell-m82", |
1918 | }; | 1922 | }; |
1919 | 1923 | ||
1920 | static struct snd_pci_quirk stac922x_cfg_tbl[] = { | 1924 | static const struct snd_pci_quirk stac922x_cfg_tbl[] = { |
1921 | /* SigmaTel reference board */ | 1925 | /* SigmaTel reference board */ |
1922 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 1926 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
1923 | "DFI LanParty", STAC_D945_REF), | 1927 | "DFI LanParty", STAC_D945_REF), |
@@ -2008,42 +2012,42 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { | |||
2008 | {} /* terminator */ | 2012 | {} /* terminator */ |
2009 | }; | 2013 | }; |
2010 | 2014 | ||
2011 | static unsigned int ref927x_pin_configs[14] = { | 2015 | static const unsigned int ref927x_pin_configs[14] = { |
2012 | 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, | 2016 | 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, |
2013 | 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, | 2017 | 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, |
2014 | 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, | 2018 | 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, |
2015 | 0x01c42190, 0x40000100, | 2019 | 0x01c42190, 0x40000100, |
2016 | }; | 2020 | }; |
2017 | 2021 | ||
2018 | static unsigned int d965_3st_pin_configs[14] = { | 2022 | static const unsigned int d965_3st_pin_configs[14] = { |
2019 | 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, | 2023 | 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, |
2020 | 0x01a19021, 0x01813024, 0x40000100, 0x40000100, | 2024 | 0x01a19021, 0x01813024, 0x40000100, 0x40000100, |
2021 | 0x40000100, 0x40000100, 0x40000100, 0x40000100, | 2025 | 0x40000100, 0x40000100, 0x40000100, 0x40000100, |
2022 | 0x40000100, 0x40000100 | 2026 | 0x40000100, 0x40000100 |
2023 | }; | 2027 | }; |
2024 | 2028 | ||
2025 | static unsigned int d965_5st_pin_configs[14] = { | 2029 | static const unsigned int d965_5st_pin_configs[14] = { |
2026 | 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, | 2030 | 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, |
2027 | 0x01a19040, 0x01011012, 0x01016011, 0x40000100, | 2031 | 0x01a19040, 0x01011012, 0x01016011, 0x40000100, |
2028 | 0x40000100, 0x40000100, 0x40000100, 0x01442070, | 2032 | 0x40000100, 0x40000100, 0x40000100, 0x01442070, |
2029 | 0x40000100, 0x40000100 | 2033 | 0x40000100, 0x40000100 |
2030 | }; | 2034 | }; |
2031 | 2035 | ||
2032 | static unsigned int d965_5st_no_fp_pin_configs[14] = { | 2036 | static const unsigned int d965_5st_no_fp_pin_configs[14] = { |
2033 | 0x40000100, 0x40000100, 0x0181304e, 0x01014010, | 2037 | 0x40000100, 0x40000100, 0x0181304e, 0x01014010, |
2034 | 0x01a19040, 0x01011012, 0x01016011, 0x40000100, | 2038 | 0x01a19040, 0x01011012, 0x01016011, 0x40000100, |
2035 | 0x40000100, 0x40000100, 0x40000100, 0x01442070, | 2039 | 0x40000100, 0x40000100, 0x40000100, 0x01442070, |
2036 | 0x40000100, 0x40000100 | 2040 | 0x40000100, 0x40000100 |
2037 | }; | 2041 | }; |
2038 | 2042 | ||
2039 | static unsigned int dell_3st_pin_configs[14] = { | 2043 | static const unsigned int dell_3st_pin_configs[14] = { |
2040 | 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, | 2044 | 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, |
2041 | 0x01111212, 0x01116211, 0x01813050, 0x01112214, | 2045 | 0x01111212, 0x01116211, 0x01813050, 0x01112214, |
2042 | 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb, | 2046 | 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb, |
2043 | 0x40c003fc, 0x40000100 | 2047 | 0x40c003fc, 0x40000100 |
2044 | }; | 2048 | }; |
2045 | 2049 | ||
2046 | static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { | 2050 | static const unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { |
2047 | [STAC_D965_REF_NO_JD] = ref927x_pin_configs, | 2051 | [STAC_D965_REF_NO_JD] = ref927x_pin_configs, |
2048 | [STAC_D965_REF] = ref927x_pin_configs, | 2052 | [STAC_D965_REF] = ref927x_pin_configs, |
2049 | [STAC_D965_3ST] = d965_3st_pin_configs, | 2053 | [STAC_D965_3ST] = d965_3st_pin_configs, |
@@ -2066,7 +2070,7 @@ static const char * const stac927x_models[STAC_927X_MODELS] = { | |||
2066 | [STAC_927X_VOLKNOB] = "volknob", | 2070 | [STAC_927X_VOLKNOB] = "volknob", |
2067 | }; | 2071 | }; |
2068 | 2072 | ||
2069 | static struct snd_pci_quirk stac927x_cfg_tbl[] = { | 2073 | static const struct snd_pci_quirk stac927x_cfg_tbl[] = { |
2070 | /* SigmaTel reference board */ | 2074 | /* SigmaTel reference board */ |
2071 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2075 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2072 | "DFI LanParty", STAC_D965_REF), | 2076 | "DFI LanParty", STAC_D965_REF), |
@@ -2104,7 +2108,7 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { | |||
2104 | {} /* terminator */ | 2108 | {} /* terminator */ |
2105 | }; | 2109 | }; |
2106 | 2110 | ||
2107 | static unsigned int ref9205_pin_configs[12] = { | 2111 | static const unsigned int ref9205_pin_configs[12] = { |
2108 | 0x40000100, 0x40000100, 0x01016011, 0x01014010, | 2112 | 0x40000100, 0x40000100, 0x01016011, 0x01014010, |
2109 | 0x01813122, 0x01a19021, 0x01019020, 0x40000100, | 2113 | 0x01813122, 0x01a19021, 0x01019020, 0x40000100, |
2110 | 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 | 2114 | 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 |
@@ -2121,7 +2125,7 @@ static unsigned int ref9205_pin_configs[12] = { | |||
2121 | 10280228 (Dell Vostro 1500) | 2125 | 10280228 (Dell Vostro 1500) |
2122 | 10280229 (Dell Vostro 1700) | 2126 | 10280229 (Dell Vostro 1700) |
2123 | */ | 2127 | */ |
2124 | static unsigned int dell_9205_m42_pin_configs[12] = { | 2128 | static const unsigned int dell_9205_m42_pin_configs[12] = { |
2125 | 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, | 2129 | 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, |
2126 | 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9, | 2130 | 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9, |
2127 | 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE, | 2131 | 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE, |
@@ -2137,19 +2141,19 @@ static unsigned int dell_9205_m42_pin_configs[12] = { | |||
2137 | 10280200 | 2141 | 10280200 |
2138 | 10280201 | 2142 | 10280201 |
2139 | */ | 2143 | */ |
2140 | static unsigned int dell_9205_m43_pin_configs[12] = { | 2144 | static const unsigned int dell_9205_m43_pin_configs[12] = { |
2141 | 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310, | 2145 | 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310, |
2142 | 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9, | 2146 | 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9, |
2143 | 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8, | 2147 | 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8, |
2144 | }; | 2148 | }; |
2145 | 2149 | ||
2146 | static unsigned int dell_9205_m44_pin_configs[12] = { | 2150 | static const unsigned int dell_9205_m44_pin_configs[12] = { |
2147 | 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310, | 2151 | 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310, |
2148 | 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9, | 2152 | 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9, |
2149 | 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe, | 2153 | 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe, |
2150 | }; | 2154 | }; |
2151 | 2155 | ||
2152 | static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { | 2156 | static const unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { |
2153 | [STAC_9205_REF] = ref9205_pin_configs, | 2157 | [STAC_9205_REF] = ref9205_pin_configs, |
2154 | [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, | 2158 | [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, |
2155 | [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, | 2159 | [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, |
@@ -2166,7 +2170,7 @@ static const char * const stac9205_models[STAC_9205_MODELS] = { | |||
2166 | [STAC_9205_EAPD] = "eapd", | 2170 | [STAC_9205_EAPD] = "eapd", |
2167 | }; | 2171 | }; |
2168 | 2172 | ||
2169 | static struct snd_pci_quirk stac9205_cfg_tbl[] = { | 2173 | static const struct snd_pci_quirk stac9205_cfg_tbl[] = { |
2170 | /* SigmaTel reference board */ | 2174 | /* SigmaTel reference board */ |
2171 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, | 2175 | SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, |
2172 | "DFI LanParty", STAC_9205_REF), | 2176 | "DFI LanParty", STAC_9205_REF), |
@@ -2214,7 +2218,7 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { | |||
2214 | }; | 2218 | }; |
2215 | 2219 | ||
2216 | static void stac92xx_set_config_regs(struct hda_codec *codec, | 2220 | static void stac92xx_set_config_regs(struct hda_codec *codec, |
2217 | unsigned int *pincfgs) | 2221 | const unsigned int *pincfgs) |
2218 | { | 2222 | { |
2219 | int i; | 2223 | int i; |
2220 | struct sigmatel_spec *spec = codec->spec; | 2224 | struct sigmatel_spec *spec = codec->spec; |
@@ -2334,7 +2338,7 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
2334 | return 0; | 2338 | return 0; |
2335 | } | 2339 | } |
2336 | 2340 | ||
2337 | static struct hda_pcm_stream stac92xx_pcm_digital_playback = { | 2341 | static const struct hda_pcm_stream stac92xx_pcm_digital_playback = { |
2338 | .substreams = 1, | 2342 | .substreams = 1, |
2339 | .channels_min = 2, | 2343 | .channels_min = 2, |
2340 | .channels_max = 2, | 2344 | .channels_max = 2, |
@@ -2347,14 +2351,14 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { | |||
2347 | }, | 2351 | }, |
2348 | }; | 2352 | }; |
2349 | 2353 | ||
2350 | static struct hda_pcm_stream stac92xx_pcm_digital_capture = { | 2354 | static const struct hda_pcm_stream stac92xx_pcm_digital_capture = { |
2351 | .substreams = 1, | 2355 | .substreams = 1, |
2352 | .channels_min = 2, | 2356 | .channels_min = 2, |
2353 | .channels_max = 2, | 2357 | .channels_max = 2, |
2354 | /* NID is set in stac92xx_build_pcms */ | 2358 | /* NID is set in stac92xx_build_pcms */ |
2355 | }; | 2359 | }; |
2356 | 2360 | ||
2357 | static struct hda_pcm_stream stac92xx_pcm_analog_playback = { | 2361 | static const struct hda_pcm_stream stac92xx_pcm_analog_playback = { |
2358 | .substreams = 1, | 2362 | .substreams = 1, |
2359 | .channels_min = 2, | 2363 | .channels_min = 2, |
2360 | .channels_max = 8, | 2364 | .channels_max = 8, |
@@ -2366,7 +2370,7 @@ static struct hda_pcm_stream stac92xx_pcm_analog_playback = { | |||
2366 | }, | 2370 | }, |
2367 | }; | 2371 | }; |
2368 | 2372 | ||
2369 | static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { | 2373 | static const struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { |
2370 | .substreams = 1, | 2374 | .substreams = 1, |
2371 | .channels_min = 2, | 2375 | .channels_min = 2, |
2372 | .channels_max = 2, | 2376 | .channels_max = 2, |
@@ -2378,7 +2382,7 @@ static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { | |||
2378 | }, | 2382 | }, |
2379 | }; | 2383 | }; |
2380 | 2384 | ||
2381 | static struct hda_pcm_stream stac92xx_pcm_analog_capture = { | 2385 | static const struct hda_pcm_stream stac92xx_pcm_analog_capture = { |
2382 | .channels_min = 2, | 2386 | .channels_min = 2, |
2383 | .channels_max = 2, | 2387 | .channels_max = 2, |
2384 | /* NID + .substreams is set in stac92xx_build_pcms */ | 2388 | /* NID + .substreams is set in stac92xx_build_pcms */ |
@@ -2487,7 +2491,7 @@ static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol, | |||
2487 | struct snd_ctl_elem_info *uinfo) | 2491 | struct snd_ctl_elem_info *uinfo) |
2488 | { | 2492 | { |
2489 | int i; | 2493 | int i; |
2490 | static char *texts[] = { | 2494 | static const char * const texts[] = { |
2491 | "Mic In", "Line In", "Line Out" | 2495 | "Mic In", "Line In", "Line Out" |
2492 | }; | 2496 | }; |
2493 | 2497 | ||
@@ -2556,7 +2560,7 @@ static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol, | |||
2556 | static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol, | 2560 | static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol, |
2557 | struct snd_ctl_elem_info *uinfo) | 2561 | struct snd_ctl_elem_info *uinfo) |
2558 | { | 2562 | { |
2559 | static char *texts[2]; | 2563 | char *texts[2]; |
2560 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 2564 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
2561 | struct sigmatel_spec *spec = codec->spec; | 2565 | struct sigmatel_spec *spec = codec->spec; |
2562 | 2566 | ||
@@ -2687,7 +2691,7 @@ enum { | |||
2687 | STAC_CTL_WIDGET_DC_BIAS | 2691 | STAC_CTL_WIDGET_DC_BIAS |
2688 | }; | 2692 | }; |
2689 | 2693 | ||
2690 | static struct snd_kcontrol_new stac92xx_control_templates[] = { | 2694 | static const struct snd_kcontrol_new stac92xx_control_templates[] = { |
2691 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | 2695 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), |
2692 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | 2696 | HDA_CODEC_MUTE(NULL, 0, 0, 0), |
2693 | HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0), | 2697 | HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0), |
@@ -2701,7 +2705,7 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { | |||
2701 | /* add dynamic controls */ | 2705 | /* add dynamic controls */ |
2702 | static struct snd_kcontrol_new * | 2706 | static struct snd_kcontrol_new * |
2703 | stac_control_new(struct sigmatel_spec *spec, | 2707 | stac_control_new(struct sigmatel_spec *spec, |
2704 | struct snd_kcontrol_new *ktemp, | 2708 | const struct snd_kcontrol_new *ktemp, |
2705 | const char *name, | 2709 | const char *name, |
2706 | unsigned int subdev) | 2710 | unsigned int subdev) |
2707 | { | 2711 | { |
@@ -2724,7 +2728,7 @@ stac_control_new(struct sigmatel_spec *spec, | |||
2724 | } | 2728 | } |
2725 | 2729 | ||
2726 | static int stac92xx_add_control_temp(struct sigmatel_spec *spec, | 2730 | static int stac92xx_add_control_temp(struct sigmatel_spec *spec, |
2727 | struct snd_kcontrol_new *ktemp, | 2731 | const struct snd_kcontrol_new *ktemp, |
2728 | int idx, const char *name, | 2732 | int idx, const char *name, |
2729 | unsigned long val) | 2733 | unsigned long val) |
2730 | { | 2734 | { |
@@ -2754,7 +2758,7 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, | |||
2754 | return stac92xx_add_control_idx(spec, type, 0, name, val); | 2758 | return stac92xx_add_control_idx(spec, type, 0, name, val); |
2755 | } | 2759 | } |
2756 | 2760 | ||
2757 | static struct snd_kcontrol_new stac_input_src_temp = { | 2761 | static const struct snd_kcontrol_new stac_input_src_temp = { |
2758 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2762 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2759 | .name = "Input Source", | 2763 | .name = "Input Source", |
2760 | .info = stac92xx_mux_enum_info, | 2764 | .info = stac92xx_mux_enum_info, |
@@ -3072,7 +3076,8 @@ static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) | |||
3072 | printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); | 3076 | printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); |
3073 | return 1; | 3077 | return 1; |
3074 | } else { | 3078 | } else { |
3075 | spec->multiout.dac_nids[spec->multiout.num_dacs] = nid; | 3079 | snd_BUG_ON(spec->multiout.dac_nids != spec->dac_nids); |
3080 | spec->dac_nids[spec->multiout.num_dacs] = nid; | ||
3076 | spec->multiout.num_dacs++; | 3081 | spec->multiout.num_dacs++; |
3077 | } | 3082 | } |
3078 | return 0; | 3083 | return 0; |
@@ -3109,8 +3114,7 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, | |||
3109 | 3114 | ||
3110 | for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { | 3115 | for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { |
3111 | if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { | 3116 | if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { |
3112 | wid_caps = get_wcaps(codec, pins[i]); | 3117 | if (is_jack_detectable(codec, pins[i])) |
3113 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
3114 | spec->hp_detect = 1; | 3118 | spec->hp_detect = 1; |
3115 | } | 3119 | } |
3116 | nid = dac_nids[i]; | 3120 | nid = dac_nids[i]; |
@@ -3309,7 +3313,7 @@ static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol, | |||
3309 | return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]); | 3313 | return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]); |
3310 | } | 3314 | } |
3311 | 3315 | ||
3312 | static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { | 3316 | static const struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { |
3313 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 3317 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
3314 | .info = stac92xx_dig_beep_switch_info, | 3318 | .info = stac92xx_dig_beep_switch_info, |
3315 | .get = stac92xx_dig_beep_switch_get, | 3319 | .get = stac92xx_dig_beep_switch_get, |
@@ -3516,14 +3520,18 @@ static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, | |||
3516 | hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock) | 3520 | hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock) |
3517 | { | 3521 | { |
3518 | unsigned int cfg; | 3522 | unsigned int cfg; |
3523 | unsigned int type; | ||
3519 | 3524 | ||
3520 | if (!nid) | 3525 | if (!nid) |
3521 | return 0; | 3526 | return 0; |
3522 | cfg = snd_hda_codec_get_pincfg(codec, nid); | 3527 | cfg = snd_hda_codec_get_pincfg(codec, nid); |
3528 | type = get_defcfg_device(cfg); | ||
3523 | switch (snd_hda_get_input_pin_attr(cfg)) { | 3529 | switch (snd_hda_get_input_pin_attr(cfg)) { |
3524 | case INPUT_PIN_ATTR_INT: | 3530 | case INPUT_PIN_ATTR_INT: |
3525 | if (*fixed) | 3531 | if (*fixed) |
3526 | return 1; /* already occupied */ | 3532 | return 1; /* already occupied */ |
3533 | if (type != AC_JACK_MIC_IN) | ||
3534 | return 1; /* invalid type */ | ||
3527 | *fixed = nid; | 3535 | *fixed = nid; |
3528 | break; | 3536 | break; |
3529 | case INPUT_PIN_ATTR_UNUSED: | 3537 | case INPUT_PIN_ATTR_UNUSED: |
@@ -3531,11 +3539,15 @@ static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, | |||
3531 | case INPUT_PIN_ATTR_DOCK: | 3539 | case INPUT_PIN_ATTR_DOCK: |
3532 | if (*dock) | 3540 | if (*dock) |
3533 | return 1; /* already occupied */ | 3541 | return 1; /* already occupied */ |
3542 | if (type != AC_JACK_MIC_IN && type != AC_JACK_LINE_IN) | ||
3543 | return 1; /* invalid type */ | ||
3534 | *dock = nid; | 3544 | *dock = nid; |
3535 | break; | 3545 | break; |
3536 | default: | 3546 | default: |
3537 | if (*ext) | 3547 | if (*ext) |
3538 | return 1; /* already occupied */ | 3548 | return 1; /* already occupied */ |
3549 | if (type != AC_JACK_MIC_IN) | ||
3550 | return 1; /* invalid type */ | ||
3539 | *ext = nid; | 3551 | *ext = nid; |
3540 | break; | 3552 | break; |
3541 | } | 3553 | } |
@@ -3591,10 +3603,6 @@ static int stac_check_auto_mic(struct hda_codec *codec) | |||
3591 | hda_nid_t fixed, ext, dock; | 3603 | hda_nid_t fixed, ext, dock; |
3592 | int i; | 3604 | int i; |
3593 | 3605 | ||
3594 | for (i = 0; i < cfg->num_inputs; i++) { | ||
3595 | if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) | ||
3596 | return 0; /* must be exclusively mics */ | ||
3597 | } | ||
3598 | fixed = ext = dock = 0; | 3606 | fixed = ext = dock = 0; |
3599 | for (i = 0; i < cfg->num_inputs; i++) | 3607 | for (i = 0; i < cfg->num_inputs; i++) |
3600 | if (check_mic_pin(codec, cfg->inputs[i].pin, | 3608 | if (check_mic_pin(codec, cfg->inputs[i].pin, |
@@ -3606,7 +3614,7 @@ static int stac_check_auto_mic(struct hda_codec *codec) | |||
3606 | return 0; | 3614 | return 0; |
3607 | if (!fixed || (!ext && !dock)) | 3615 | if (!fixed || (!ext && !dock)) |
3608 | return 0; /* no input to switch */ | 3616 | return 0; /* no input to switch */ |
3609 | if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) | 3617 | if (!is_jack_detectable(codec, ext)) |
3610 | return 0; /* no unsol support */ | 3618 | return 0; /* no unsol support */ |
3611 | if (set_mic_route(codec, &spec->ext_mic, ext) || | 3619 | if (set_mic_route(codec, &spec->ext_mic, ext) || |
3612 | set_mic_route(codec, &spec->int_mic, fixed) || | 3620 | set_mic_route(codec, &spec->int_mic, fixed) || |
@@ -3921,13 +3929,11 @@ static int stac9200_auto_create_hp_ctls(struct hda_codec *codec, | |||
3921 | { | 3929 | { |
3922 | struct sigmatel_spec *spec = codec->spec; | 3930 | struct sigmatel_spec *spec = codec->spec; |
3923 | hda_nid_t pin = cfg->hp_pins[0]; | 3931 | hda_nid_t pin = cfg->hp_pins[0]; |
3924 | unsigned int wid_caps; | ||
3925 | 3932 | ||
3926 | if (! pin) | 3933 | if (! pin) |
3927 | return 0; | 3934 | return 0; |
3928 | 3935 | ||
3929 | wid_caps = get_wcaps(codec, pin); | 3936 | if (is_jack_detectable(codec, pin)) |
3930 | if (wid_caps & AC_WCAP_UNSOL_CAP) | ||
3931 | spec->hp_detect = 1; | 3937 | spec->hp_detect = 1; |
3932 | 3938 | ||
3933 | return 0; | 3939 | return 0; |
@@ -4138,7 +4144,7 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, | |||
4138 | struct sigmatel_event *event; | 4144 | struct sigmatel_event *event; |
4139 | int tag; | 4145 | int tag; |
4140 | 4146 | ||
4141 | if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) | 4147 | if (!is_jack_detectable(codec, nid)) |
4142 | return 0; | 4148 | return 0; |
4143 | event = stac_get_event(codec, nid); | 4149 | event = stac_get_event(codec, nid); |
4144 | if (event) { | 4150 | if (event) { |
@@ -4171,7 +4177,7 @@ static void stac92xx_power_down(struct hda_codec *codec) | |||
4171 | struct sigmatel_spec *spec = codec->spec; | 4177 | struct sigmatel_spec *spec = codec->spec; |
4172 | 4178 | ||
4173 | /* power down inactive DACs */ | 4179 | /* power down inactive DACs */ |
4174 | hda_nid_t *dac; | 4180 | const hda_nid_t *dac; |
4175 | for (dac = spec->dac_list; *dac; dac++) | 4181 | for (dac = spec->dac_list; *dac; dac++) |
4176 | if (!check_all_dac_nids(spec, *dac)) | 4182 | if (!check_all_dac_nids(spec, *dac)) |
4177 | snd_hda_codec_write(codec, *dac, 0, | 4183 | snd_hda_codec_write(codec, *dac, 0, |
@@ -4644,7 +4650,7 @@ static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) | |||
4644 | } | 4650 | } |
4645 | 4651 | ||
4646 | static int stac92xx_connected_ports(struct hda_codec *codec, | 4652 | static int stac92xx_connected_ports(struct hda_codec *codec, |
4647 | hda_nid_t *nids, int num_nids) | 4653 | const hda_nid_t *nids, int num_nids) |
4648 | { | 4654 | { |
4649 | struct sigmatel_spec *spec = codec->spec; | 4655 | struct sigmatel_spec *spec = codec->spec; |
4650 | int idx, num; | 4656 | int idx, num; |
@@ -4968,7 +4974,7 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) | |||
4968 | } | 4974 | } |
4969 | #endif | 4975 | #endif |
4970 | 4976 | ||
4971 | static struct hda_codec_ops stac92xx_patch_ops = { | 4977 | static const struct hda_codec_ops stac92xx_patch_ops = { |
4972 | .build_controls = stac92xx_build_controls, | 4978 | .build_controls = stac92xx_build_controls, |
4973 | .build_pcms = stac92xx_build_pcms, | 4979 | .build_pcms = stac92xx_build_pcms, |
4974 | .init = stac92xx_init, | 4980 | .init = stac92xx_init, |
@@ -5588,7 +5594,7 @@ static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol, | |||
5588 | return 1; | 5594 | return 1; |
5589 | } | 5595 | } |
5590 | 5596 | ||
5591 | static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { | 5597 | static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { |
5592 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 5598 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
5593 | .info = stac_hp_bass_gpio_info, | 5599 | .info = stac_hp_bass_gpio_info, |
5594 | .get = stac_hp_bass_gpio_get, | 5600 | .get = stac_hp_bass_gpio_get, |
@@ -5612,7 +5618,7 @@ static int stac_add_hp_bass_switch(struct hda_codec *codec) | |||
5612 | static int patch_stac92hd71bxx(struct hda_codec *codec) | 5618 | static int patch_stac92hd71bxx(struct hda_codec *codec) |
5613 | { | 5619 | { |
5614 | struct sigmatel_spec *spec; | 5620 | struct sigmatel_spec *spec; |
5615 | struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; | 5621 | const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; |
5616 | unsigned int pin_cfg; | 5622 | unsigned int pin_cfg; |
5617 | int err = 0; | 5623 | int err = 0; |
5618 | 5624 | ||
@@ -5705,9 +5711,9 @@ again: | |||
5705 | unmute_init++; | 5711 | unmute_init++; |
5706 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); | 5712 | snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); |
5707 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); | 5713 | snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); |
5708 | stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0; | 5714 | spec->dmic_nids = stac92hd71bxx_dmic_5port_nids; |
5709 | spec->num_dmics = stac92xx_connected_ports(codec, | 5715 | spec->num_dmics = stac92xx_connected_ports(codec, |
5710 | stac92hd71bxx_dmic_nids, | 5716 | stac92hd71bxx_dmic_5port_nids, |
5711 | STAC92HD71BXX_NUM_DMICS - 1); | 5717 | STAC92HD71BXX_NUM_DMICS - 1); |
5712 | break; | 5718 | break; |
5713 | case 0x111d7603: /* 6 Port with Analog Mixer */ | 5719 | case 0x111d7603: /* 6 Port with Analog Mixer */ |
@@ -5729,15 +5735,6 @@ again: | |||
5729 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) | 5735 | if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) |
5730 | snd_hda_sequence_write_cache(codec, unmute_init); | 5736 | snd_hda_sequence_write_cache(codec, unmute_init); |
5731 | 5737 | ||
5732 | /* Some HP machines seem to have unstable codec communications | ||
5733 | * especially with ATI fglrx driver. For recovering from the | ||
5734 | * CORB/RIRB stall, allow the BUS reset and keep always sync | ||
5735 | */ | ||
5736 | if (spec->board_config == STAC_HP_DV5) { | ||
5737 | codec->bus->sync_write = 1; | ||
5738 | codec->bus->allow_bus_reset = 1; | ||
5739 | } | ||
5740 | |||
5741 | spec->aloopback_ctl = stac92hd71bxx_loopback; | 5738 | spec->aloopback_ctl = stac92hd71bxx_loopback; |
5742 | spec->aloopback_mask = 0x50; | 5739 | spec->aloopback_mask = 0x50; |
5743 | spec->aloopback_shift = 0; | 5740 | spec->aloopback_shift = 0; |
@@ -6223,31 +6220,31 @@ static int patch_stac9205(struct hda_codec *codec) | |||
6223 | * STAC9872 hack | 6220 | * STAC9872 hack |
6224 | */ | 6221 | */ |
6225 | 6222 | ||
6226 | static struct hda_verb stac9872_core_init[] = { | 6223 | static const struct hda_verb stac9872_core_init[] = { |
6227 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ | 6224 | {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ |
6228 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ | 6225 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ |
6229 | {} | 6226 | {} |
6230 | }; | 6227 | }; |
6231 | 6228 | ||
6232 | static hda_nid_t stac9872_pin_nids[] = { | 6229 | static const hda_nid_t stac9872_pin_nids[] = { |
6233 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, | 6230 | 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, |
6234 | 0x11, 0x13, 0x14, | 6231 | 0x11, 0x13, 0x14, |
6235 | }; | 6232 | }; |
6236 | 6233 | ||
6237 | static hda_nid_t stac9872_adc_nids[] = { | 6234 | static const hda_nid_t stac9872_adc_nids[] = { |
6238 | 0x8 /*,0x6*/ | 6235 | 0x8 /*,0x6*/ |
6239 | }; | 6236 | }; |
6240 | 6237 | ||
6241 | static hda_nid_t stac9872_mux_nids[] = { | 6238 | static const hda_nid_t stac9872_mux_nids[] = { |
6242 | 0x15 | 6239 | 0x15 |
6243 | }; | 6240 | }; |
6244 | 6241 | ||
6245 | static unsigned long stac9872_capvols[] = { | 6242 | static const unsigned long stac9872_capvols[] = { |
6246 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), | 6243 | HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), |
6247 | }; | 6244 | }; |
6248 | #define stac9872_capsws stac9872_capvols | 6245 | #define stac9872_capsws stac9872_capvols |
6249 | 6246 | ||
6250 | static unsigned int stac9872_vaio_pin_configs[9] = { | 6247 | static const unsigned int stac9872_vaio_pin_configs[9] = { |
6251 | 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, | 6248 | 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, |
6252 | 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, | 6249 | 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, |
6253 | 0x90a7013e | 6250 | 0x90a7013e |
@@ -6258,11 +6255,11 @@ static const char * const stac9872_models[STAC_9872_MODELS] = { | |||
6258 | [STAC_9872_VAIO] = "vaio", | 6255 | [STAC_9872_VAIO] = "vaio", |
6259 | }; | 6256 | }; |
6260 | 6257 | ||
6261 | static unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { | 6258 | static const unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { |
6262 | [STAC_9872_VAIO] = stac9872_vaio_pin_configs, | 6259 | [STAC_9872_VAIO] = stac9872_vaio_pin_configs, |
6263 | }; | 6260 | }; |
6264 | 6261 | ||
6265 | static struct snd_pci_quirk stac9872_cfg_tbl[] = { | 6262 | static const struct snd_pci_quirk stac9872_cfg_tbl[] = { |
6266 | SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0, | 6263 | SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0, |
6267 | "Sony VAIO F/S", STAC_9872_VAIO), | 6264 | "Sony VAIO F/S", STAC_9872_VAIO), |
6268 | {} /* terminator */ | 6265 | {} /* terminator */ |
@@ -6316,7 +6313,7 @@ static int patch_stac9872(struct hda_codec *codec) | |||
6316 | /* | 6313 | /* |
6317 | * patch entries | 6314 | * patch entries |
6318 | */ | 6315 | */ |
6319 | static struct hda_codec_preset snd_hda_preset_sigmatel[] = { | 6316 | static const struct hda_codec_preset snd_hda_preset_sigmatel[] = { |
6320 | { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, | 6317 | { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, |
6321 | { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, | 6318 | { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, |
6322 | { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, | 6319 | { .id = 0x83847680, .name = "STAC9221 A1", .patch = patch_stac922x }, |
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 1371b57c11e8..605c99e1e520 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -98,24 +98,30 @@ enum VIA_HDA_CODEC { | |||
98 | VT1716S, | 98 | VT1716S, |
99 | VT2002P, | 99 | VT2002P, |
100 | VT1812, | 100 | VT1812, |
101 | VT1802, | ||
101 | CODEC_TYPES, | 102 | CODEC_TYPES, |
102 | }; | 103 | }; |
103 | 104 | ||
105 | #define VT2002P_COMPATIBLE(spec) \ | ||
106 | ((spec)->codec_type == VT2002P ||\ | ||
107 | (spec)->codec_type == VT1812 ||\ | ||
108 | (spec)->codec_type == VT1802) | ||
109 | |||
104 | struct via_spec { | 110 | struct via_spec { |
105 | /* codec parameterization */ | 111 | /* codec parameterization */ |
106 | struct snd_kcontrol_new *mixers[6]; | 112 | const struct snd_kcontrol_new *mixers[6]; |
107 | unsigned int num_mixers; | 113 | unsigned int num_mixers; |
108 | 114 | ||
109 | struct hda_verb *init_verbs[5]; | 115 | const struct hda_verb *init_verbs[5]; |
110 | unsigned int num_iverbs; | 116 | unsigned int num_iverbs; |
111 | 117 | ||
112 | char *stream_name_analog; | 118 | char *stream_name_analog; |
113 | struct hda_pcm_stream *stream_analog_playback; | 119 | const struct hda_pcm_stream *stream_analog_playback; |
114 | struct hda_pcm_stream *stream_analog_capture; | 120 | const struct hda_pcm_stream *stream_analog_capture; |
115 | 121 | ||
116 | char *stream_name_digital; | 122 | char *stream_name_digital; |
117 | struct hda_pcm_stream *stream_digital_playback; | 123 | const struct hda_pcm_stream *stream_digital_playback; |
118 | struct hda_pcm_stream *stream_digital_capture; | 124 | const struct hda_pcm_stream *stream_digital_capture; |
119 | 125 | ||
120 | /* playback */ | 126 | /* playback */ |
121 | struct hda_multi_out multiout; | 127 | struct hda_multi_out multiout; |
@@ -123,7 +129,7 @@ struct via_spec { | |||
123 | 129 | ||
124 | /* capture */ | 130 | /* capture */ |
125 | unsigned int num_adc_nids; | 131 | unsigned int num_adc_nids; |
126 | hda_nid_t *adc_nids; | 132 | const hda_nid_t *adc_nids; |
127 | hda_nid_t mux_nids[3]; | 133 | hda_nid_t mux_nids[3]; |
128 | hda_nid_t dig_in_nid; | 134 | hda_nid_t dig_in_nid; |
129 | hda_nid_t dig_in_pin; | 135 | hda_nid_t dig_in_pin; |
@@ -154,6 +160,9 @@ struct via_spec { | |||
154 | struct delayed_work vt1708_hp_work; | 160 | struct delayed_work vt1708_hp_work; |
155 | int vt1708_jack_detectect; | 161 | int vt1708_jack_detectect; |
156 | int vt1708_hp_present; | 162 | int vt1708_hp_present; |
163 | |||
164 | void (*set_widgets_power_state)(struct hda_codec *codec); | ||
165 | |||
157 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 166 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
158 | struct hda_loopback_check loopback; | 167 | struct hda_loopback_check loopback; |
159 | #endif | 168 | #endif |
@@ -218,17 +227,19 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) | |||
218 | codec_type = VT1812; | 227 | codec_type = VT1812; |
219 | else if (dev_id == 0x0440) | 228 | else if (dev_id == 0x0440) |
220 | codec_type = VT1708S; | 229 | codec_type = VT1708S; |
230 | else if ((dev_id & 0xfff) == 0x446) | ||
231 | codec_type = VT1802; | ||
221 | else | 232 | else |
222 | codec_type = UNKNOWN; | 233 | codec_type = UNKNOWN; |
223 | return codec_type; | 234 | return codec_type; |
224 | }; | 235 | }; |
225 | 236 | ||
237 | #define VIA_JACK_EVENT 0x20 | ||
226 | #define VIA_HP_EVENT 0x01 | 238 | #define VIA_HP_EVENT 0x01 |
227 | #define VIA_GPIO_EVENT 0x02 | 239 | #define VIA_GPIO_EVENT 0x02 |
228 | #define VIA_JACK_EVENT 0x04 | 240 | #define VIA_MONO_EVENT 0x03 |
229 | #define VIA_MONO_EVENT 0x08 | 241 | #define VIA_SPEAKER_EVENT 0x04 |
230 | #define VIA_SPEAKER_EVENT 0x10 | 242 | #define VIA_BIND_HP_EVENT 0x05 |
231 | #define VIA_BIND_HP_EVENT 0x20 | ||
232 | 243 | ||
233 | enum { | 244 | enum { |
234 | VIA_CTL_WIDGET_VOL, | 245 | VIA_CTL_WIDGET_VOL, |
@@ -245,7 +256,6 @@ enum { | |||
245 | }; | 256 | }; |
246 | 257 | ||
247 | static void analog_low_current_mode(struct hda_codec *codec, int stream_idle); | 258 | static void analog_low_current_mode(struct hda_codec *codec, int stream_idle); |
248 | static void set_jack_power_state(struct hda_codec *codec); | ||
249 | static int is_aa_path_mute(struct hda_codec *codec); | 259 | static int is_aa_path_mute(struct hda_codec *codec); |
250 | 260 | ||
251 | static void vt1708_start_hp_work(struct via_spec *spec) | 261 | static void vt1708_start_hp_work(struct via_spec *spec) |
@@ -271,6 +281,12 @@ static void vt1708_stop_hp_work(struct via_spec *spec) | |||
271 | cancel_delayed_work_sync(&spec->vt1708_hp_work); | 281 | cancel_delayed_work_sync(&spec->vt1708_hp_work); |
272 | } | 282 | } |
273 | 283 | ||
284 | static void set_widgets_power_state(struct hda_codec *codec) | ||
285 | { | ||
286 | struct via_spec *spec = codec->spec; | ||
287 | if (spec->set_widgets_power_state) | ||
288 | spec->set_widgets_power_state(codec); | ||
289 | } | ||
274 | 290 | ||
275 | static int analog_input_switch_put(struct snd_kcontrol *kcontrol, | 291 | static int analog_input_switch_put(struct snd_kcontrol *kcontrol, |
276 | struct snd_ctl_elem_value *ucontrol) | 292 | struct snd_ctl_elem_value *ucontrol) |
@@ -278,7 +294,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol, | |||
278 | int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); | 294 | int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); |
279 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 295 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
280 | 296 | ||
281 | set_jack_power_state(codec); | 297 | set_widgets_power_state(codec); |
282 | analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); | 298 | analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); |
283 | if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { | 299 | if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { |
284 | if (is_aa_path_mute(codec)) | 300 | if (is_aa_path_mute(codec)) |
@@ -394,54 +410,54 @@ static int bind_pin_switch_put(struct snd_kcontrol *kcontrol, | |||
394 | .put = bind_pin_switch_put, \ | 410 | .put = bind_pin_switch_put, \ |
395 | .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } | 411 | .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } |
396 | 412 | ||
397 | static struct snd_kcontrol_new via_control_templates[] = { | 413 | static const struct snd_kcontrol_new via_control_templates[] = { |
398 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), | 414 | HDA_CODEC_VOLUME(NULL, 0, 0, 0), |
399 | HDA_CODEC_MUTE(NULL, 0, 0, 0), | 415 | HDA_CODEC_MUTE(NULL, 0, 0, 0), |
400 | ANALOG_INPUT_MUTE, | 416 | ANALOG_INPUT_MUTE, |
401 | BIND_PIN_MUTE, | 417 | BIND_PIN_MUTE, |
402 | }; | 418 | }; |
403 | 419 | ||
404 | static hda_nid_t vt1708_adc_nids[2] = { | 420 | static const hda_nid_t vt1708_adc_nids[2] = { |
405 | /* ADC1-2 */ | 421 | /* ADC1-2 */ |
406 | 0x15, 0x27 | 422 | 0x15, 0x27 |
407 | }; | 423 | }; |
408 | 424 | ||
409 | static hda_nid_t vt1709_adc_nids[3] = { | 425 | static const hda_nid_t vt1709_adc_nids[3] = { |
410 | /* ADC1-2 */ | 426 | /* ADC1-2 */ |
411 | 0x14, 0x15, 0x16 | 427 | 0x14, 0x15, 0x16 |
412 | }; | 428 | }; |
413 | 429 | ||
414 | static hda_nid_t vt1708B_adc_nids[2] = { | 430 | static const hda_nid_t vt1708B_adc_nids[2] = { |
415 | /* ADC1-2 */ | 431 | /* ADC1-2 */ |
416 | 0x13, 0x14 | 432 | 0x13, 0x14 |
417 | }; | 433 | }; |
418 | 434 | ||
419 | static hda_nid_t vt1708S_adc_nids[2] = { | 435 | static const hda_nid_t vt1708S_adc_nids[2] = { |
420 | /* ADC1-2 */ | 436 | /* ADC1-2 */ |
421 | 0x13, 0x14 | 437 | 0x13, 0x14 |
422 | }; | 438 | }; |
423 | 439 | ||
424 | static hda_nid_t vt1702_adc_nids[3] = { | 440 | static const hda_nid_t vt1702_adc_nids[3] = { |
425 | /* ADC1-2 */ | 441 | /* ADC1-2 */ |
426 | 0x12, 0x20, 0x1F | 442 | 0x12, 0x20, 0x1F |
427 | }; | 443 | }; |
428 | 444 | ||
429 | static hda_nid_t vt1718S_adc_nids[2] = { | 445 | static const hda_nid_t vt1718S_adc_nids[2] = { |
430 | /* ADC1-2 */ | 446 | /* ADC1-2 */ |
431 | 0x10, 0x11 | 447 | 0x10, 0x11 |
432 | }; | 448 | }; |
433 | 449 | ||
434 | static hda_nid_t vt1716S_adc_nids[2] = { | 450 | static const hda_nid_t vt1716S_adc_nids[2] = { |
435 | /* ADC1-2 */ | 451 | /* ADC1-2 */ |
436 | 0x13, 0x14 | 452 | 0x13, 0x14 |
437 | }; | 453 | }; |
438 | 454 | ||
439 | static hda_nid_t vt2002P_adc_nids[2] = { | 455 | static const hda_nid_t vt2002P_adc_nids[2] = { |
440 | /* ADC1-2 */ | 456 | /* ADC1-2 */ |
441 | 0x10, 0x11 | 457 | 0x10, 0x11 |
442 | }; | 458 | }; |
443 | 459 | ||
444 | static hda_nid_t vt1812_adc_nids[2] = { | 460 | static const hda_nid_t vt1812_adc_nids[2] = { |
445 | /* ADC1-2 */ | 461 | /* ADC1-2 */ |
446 | 0x10, 0x11 | 462 | 0x10, 0x11 |
447 | }; | 463 | }; |
@@ -471,7 +487,7 @@ static int __via_add_control(struct via_spec *spec, int type, const char *name, | |||
471 | __via_add_control(spec, type, name, 0, val) | 487 | __via_add_control(spec, type, name, 0, val) |
472 | 488 | ||
473 | static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, | 489 | static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, |
474 | struct snd_kcontrol_new *tmpl) | 490 | const struct snd_kcontrol_new *tmpl) |
475 | { | 491 | { |
476 | struct snd_kcontrol_new *knew; | 492 | struct snd_kcontrol_new *knew; |
477 | 493 | ||
@@ -602,482 +618,6 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, | |||
602 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); | 618 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); |
603 | } | 619 | } |
604 | 620 | ||
605 | static void set_jack_power_state(struct hda_codec *codec) | ||
606 | { | ||
607 | struct via_spec *spec = codec->spec; | ||
608 | int imux_is_smixer; | ||
609 | unsigned int parm; | ||
610 | |||
611 | if (spec->codec_type == VT1702) { | ||
612 | imux_is_smixer = snd_hda_codec_read( | ||
613 | codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; | ||
614 | /* inputs */ | ||
615 | /* PW 1/2/5 (14h/15h/18h) */ | ||
616 | parm = AC_PWRST_D3; | ||
617 | set_pin_power_state(codec, 0x14, &parm); | ||
618 | set_pin_power_state(codec, 0x15, &parm); | ||
619 | set_pin_power_state(codec, 0x18, &parm); | ||
620 | if (imux_is_smixer) | ||
621 | parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */ | ||
622 | /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ | ||
623 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, | ||
624 | parm); | ||
625 | snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, | ||
626 | parm); | ||
627 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, | ||
628 | parm); | ||
629 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, | ||
630 | parm); | ||
631 | |||
632 | /* outputs */ | ||
633 | /* PW 3/4 (16h/17h) */ | ||
634 | parm = AC_PWRST_D3; | ||
635 | set_pin_power_state(codec, 0x16, &parm); | ||
636 | set_pin_power_state(codec, 0x17, &parm); | ||
637 | /* MW0 (1ah), AOW 0/1 (10h/1dh) */ | ||
638 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, | ||
639 | imux_is_smixer ? AC_PWRST_D0 : parm); | ||
640 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, | ||
641 | parm); | ||
642 | snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, | ||
643 | parm); | ||
644 | } else if (spec->codec_type == VT1708B_8CH | ||
645 | || spec->codec_type == VT1708B_4CH | ||
646 | || spec->codec_type == VT1708S) { | ||
647 | /* SW0 (17h) = stereo mixer */ | ||
648 | int is_8ch = spec->codec_type != VT1708B_4CH; | ||
649 | imux_is_smixer = snd_hda_codec_read( | ||
650 | codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) | ||
651 | == ((spec->codec_type == VT1708S) ? 5 : 0); | ||
652 | /* inputs */ | ||
653 | /* PW 1/2/5 (1ah/1bh/1eh) */ | ||
654 | parm = AC_PWRST_D3; | ||
655 | set_pin_power_state(codec, 0x1a, &parm); | ||
656 | set_pin_power_state(codec, 0x1b, &parm); | ||
657 | set_pin_power_state(codec, 0x1e, &parm); | ||
658 | if (imux_is_smixer) | ||
659 | parm = AC_PWRST_D0; | ||
660 | /* SW0 (17h), AIW 0/1 (13h/14h) */ | ||
661 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, | ||
662 | parm); | ||
663 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, | ||
664 | parm); | ||
665 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, | ||
666 | parm); | ||
667 | |||
668 | /* outputs */ | ||
669 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | ||
670 | parm = AC_PWRST_D3; | ||
671 | set_pin_power_state(codec, 0x19, &parm); | ||
672 | if (spec->smart51_enabled) | ||
673 | parm = AC_PWRST_D0; | ||
674 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, | ||
675 | parm); | ||
676 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, | ||
677 | parm); | ||
678 | |||
679 | /* PW6 (22h), SW2 (26h), AOW2 (24h) */ | ||
680 | if (is_8ch) { | ||
681 | parm = AC_PWRST_D3; | ||
682 | set_pin_power_state(codec, 0x22, &parm); | ||
683 | if (spec->smart51_enabled) | ||
684 | parm = AC_PWRST_D0; | ||
685 | snd_hda_codec_write(codec, 0x26, 0, | ||
686 | AC_VERB_SET_POWER_STATE, parm); | ||
687 | snd_hda_codec_write(codec, 0x24, 0, | ||
688 | AC_VERB_SET_POWER_STATE, parm); | ||
689 | } | ||
690 | |||
691 | /* PW 3/4/7 (1ch/1dh/23h) */ | ||
692 | parm = AC_PWRST_D3; | ||
693 | /* force to D0 for internal Speaker */ | ||
694 | set_pin_power_state(codec, 0x1c, &parm); | ||
695 | set_pin_power_state(codec, 0x1d, &parm); | ||
696 | if (is_8ch) | ||
697 | set_pin_power_state(codec, 0x23, &parm); | ||
698 | /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ | ||
699 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, | ||
700 | imux_is_smixer ? AC_PWRST_D0 : parm); | ||
701 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, | ||
702 | parm); | ||
703 | if (is_8ch) { | ||
704 | snd_hda_codec_write(codec, 0x25, 0, | ||
705 | AC_VERB_SET_POWER_STATE, parm); | ||
706 | snd_hda_codec_write(codec, 0x27, 0, | ||
707 | AC_VERB_SET_POWER_STATE, parm); | ||
708 | } | ||
709 | } else if (spec->codec_type == VT1718S) { | ||
710 | /* MUX6 (1eh) = stereo mixer */ | ||
711 | imux_is_smixer = snd_hda_codec_read( | ||
712 | codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; | ||
713 | /* inputs */ | ||
714 | /* PW 5/6/7 (29h/2ah/2bh) */ | ||
715 | parm = AC_PWRST_D3; | ||
716 | set_pin_power_state(codec, 0x29, &parm); | ||
717 | set_pin_power_state(codec, 0x2a, &parm); | ||
718 | set_pin_power_state(codec, 0x2b, &parm); | ||
719 | if (imux_is_smixer) | ||
720 | parm = AC_PWRST_D0; | ||
721 | /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ | ||
722 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, | ||
723 | parm); | ||
724 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, | ||
725 | parm); | ||
726 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, | ||
727 | parm); | ||
728 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, | ||
729 | parm); | ||
730 | |||
731 | /* outputs */ | ||
732 | /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ | ||
733 | parm = AC_PWRST_D3; | ||
734 | set_pin_power_state(codec, 0x27, &parm); | ||
735 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, | ||
736 | parm); | ||
737 | snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, | ||
738 | parm); | ||
739 | |||
740 | /* PW2 (26h), AOW2 (ah) */ | ||
741 | parm = AC_PWRST_D3; | ||
742 | set_pin_power_state(codec, 0x26, &parm); | ||
743 | snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, | ||
744 | parm); | ||
745 | |||
746 | /* PW0/1 (24h/25h) */ | ||
747 | parm = AC_PWRST_D3; | ||
748 | set_pin_power_state(codec, 0x24, &parm); | ||
749 | set_pin_power_state(codec, 0x25, &parm); | ||
750 | if (!spec->hp_independent_mode) /* check for redirected HP */ | ||
751 | set_pin_power_state(codec, 0x28, &parm); | ||
752 | snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, | ||
753 | parm); | ||
754 | snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, | ||
755 | parm); | ||
756 | /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ | ||
757 | snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, | ||
758 | imux_is_smixer ? AC_PWRST_D0 : parm); | ||
759 | if (spec->hp_independent_mode) { | ||
760 | /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ | ||
761 | parm = AC_PWRST_D3; | ||
762 | set_pin_power_state(codec, 0x28, &parm); | ||
763 | snd_hda_codec_write(codec, 0x1b, 0, | ||
764 | AC_VERB_SET_POWER_STATE, parm); | ||
765 | snd_hda_codec_write(codec, 0x34, 0, | ||
766 | AC_VERB_SET_POWER_STATE, parm); | ||
767 | snd_hda_codec_write(codec, 0xc, 0, | ||
768 | AC_VERB_SET_POWER_STATE, parm); | ||
769 | } | ||
770 | } else if (spec->codec_type == VT1716S) { | ||
771 | unsigned int mono_out, present; | ||
772 | /* SW0 (17h) = stereo mixer */ | ||
773 | imux_is_smixer = snd_hda_codec_read( | ||
774 | codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; | ||
775 | /* inputs */ | ||
776 | /* PW 1/2/5 (1ah/1bh/1eh) */ | ||
777 | parm = AC_PWRST_D3; | ||
778 | set_pin_power_state(codec, 0x1a, &parm); | ||
779 | set_pin_power_state(codec, 0x1b, &parm); | ||
780 | set_pin_power_state(codec, 0x1e, &parm); | ||
781 | if (imux_is_smixer) | ||
782 | parm = AC_PWRST_D0; | ||
783 | /* SW0 (17h), AIW0(13h) */ | ||
784 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, | ||
785 | parm); | ||
786 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, | ||
787 | parm); | ||
788 | |||
789 | parm = AC_PWRST_D3; | ||
790 | set_pin_power_state(codec, 0x1e, &parm); | ||
791 | /* PW11 (22h) */ | ||
792 | if (spec->dmic_enabled) | ||
793 | set_pin_power_state(codec, 0x22, &parm); | ||
794 | else | ||
795 | snd_hda_codec_write( | ||
796 | codec, 0x22, 0, | ||
797 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
798 | |||
799 | /* SW2(26h), AIW1(14h) */ | ||
800 | snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, | ||
801 | parm); | ||
802 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, | ||
803 | parm); | ||
804 | |||
805 | /* outputs */ | ||
806 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | ||
807 | parm = AC_PWRST_D3; | ||
808 | set_pin_power_state(codec, 0x19, &parm); | ||
809 | /* Smart 5.1 PW2(1bh) */ | ||
810 | if (spec->smart51_enabled) | ||
811 | set_pin_power_state(codec, 0x1b, &parm); | ||
812 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, | ||
813 | parm); | ||
814 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, | ||
815 | parm); | ||
816 | |||
817 | /* PW7 (23h), SW3 (27h), AOW3 (25h) */ | ||
818 | parm = AC_PWRST_D3; | ||
819 | set_pin_power_state(codec, 0x23, &parm); | ||
820 | /* Smart 5.1 PW1(1ah) */ | ||
821 | if (spec->smart51_enabled) | ||
822 | set_pin_power_state(codec, 0x1a, &parm); | ||
823 | snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, | ||
824 | parm); | ||
825 | |||
826 | /* Smart 5.1 PW5(1eh) */ | ||
827 | if (spec->smart51_enabled) | ||
828 | set_pin_power_state(codec, 0x1e, &parm); | ||
829 | snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, | ||
830 | parm); | ||
831 | |||
832 | /* Mono out */ | ||
833 | /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ | ||
834 | present = snd_hda_jack_detect(codec, 0x1c); | ||
835 | if (present) | ||
836 | mono_out = 0; | ||
837 | else { | ||
838 | present = snd_hda_jack_detect(codec, 0x1d); | ||
839 | if (!spec->hp_independent_mode && present) | ||
840 | mono_out = 0; | ||
841 | else | ||
842 | mono_out = 1; | ||
843 | } | ||
844 | parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; | ||
845 | snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, | ||
846 | parm); | ||
847 | snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, | ||
848 | parm); | ||
849 | snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, | ||
850 | parm); | ||
851 | |||
852 | /* PW 3/4 (1ch/1dh) */ | ||
853 | parm = AC_PWRST_D3; | ||
854 | set_pin_power_state(codec, 0x1c, &parm); | ||
855 | set_pin_power_state(codec, 0x1d, &parm); | ||
856 | /* HP Independent Mode, power on AOW3 */ | ||
857 | if (spec->hp_independent_mode) | ||
858 | snd_hda_codec_write(codec, 0x25, 0, | ||
859 | AC_VERB_SET_POWER_STATE, parm); | ||
860 | |||
861 | /* force to D0 for internal Speaker */ | ||
862 | /* MW0 (16h), AOW0 (10h) */ | ||
863 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, | ||
864 | imux_is_smixer ? AC_PWRST_D0 : parm); | ||
865 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, | ||
866 | mono_out ? AC_PWRST_D0 : parm); | ||
867 | } else if (spec->codec_type == VT2002P) { | ||
868 | unsigned int present; | ||
869 | /* MUX9 (1eh) = stereo mixer */ | ||
870 | imux_is_smixer = snd_hda_codec_read( | ||
871 | codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; | ||
872 | /* inputs */ | ||
873 | /* PW 5/6/7 (29h/2ah/2bh) */ | ||
874 | parm = AC_PWRST_D3; | ||
875 | set_pin_power_state(codec, 0x29, &parm); | ||
876 | set_pin_power_state(codec, 0x2a, &parm); | ||
877 | set_pin_power_state(codec, 0x2b, &parm); | ||
878 | if (imux_is_smixer) | ||
879 | parm = AC_PWRST_D0; | ||
880 | /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ | ||
881 | snd_hda_codec_write(codec, 0x1e, 0, | ||
882 | AC_VERB_SET_POWER_STATE, parm); | ||
883 | snd_hda_codec_write(codec, 0x1f, 0, | ||
884 | AC_VERB_SET_POWER_STATE, parm); | ||
885 | snd_hda_codec_write(codec, 0x10, 0, | ||
886 | AC_VERB_SET_POWER_STATE, parm); | ||
887 | snd_hda_codec_write(codec, 0x11, 0, | ||
888 | AC_VERB_SET_POWER_STATE, parm); | ||
889 | |||
890 | /* outputs */ | ||
891 | /* AOW0 (8h)*/ | ||
892 | snd_hda_codec_write(codec, 0x8, 0, | ||
893 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
894 | |||
895 | /* PW4 (26h), MW4 (1ch), MUX4(37h) */ | ||
896 | parm = AC_PWRST_D3; | ||
897 | set_pin_power_state(codec, 0x26, &parm); | ||
898 | snd_hda_codec_write(codec, 0x1c, 0, | ||
899 | AC_VERB_SET_POWER_STATE, parm); | ||
900 | snd_hda_codec_write(codec, 0x37, | ||
901 | 0, AC_VERB_SET_POWER_STATE, parm); | ||
902 | |||
903 | /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ | ||
904 | parm = AC_PWRST_D3; | ||
905 | set_pin_power_state(codec, 0x25, &parm); | ||
906 | snd_hda_codec_write(codec, 0x19, 0, | ||
907 | AC_VERB_SET_POWER_STATE, parm); | ||
908 | snd_hda_codec_write(codec, 0x35, 0, | ||
909 | AC_VERB_SET_POWER_STATE, parm); | ||
910 | if (spec->hp_independent_mode) { | ||
911 | snd_hda_codec_write(codec, 0x9, 0, | ||
912 | AC_VERB_SET_POWER_STATE, parm); | ||
913 | } | ||
914 | |||
915 | /* Class-D */ | ||
916 | /* PW0 (24h), MW0(18h), MUX0(34h) */ | ||
917 | present = snd_hda_jack_detect(codec, 0x25); | ||
918 | parm = AC_PWRST_D3; | ||
919 | set_pin_power_state(codec, 0x24, &parm); | ||
920 | if (present) { | ||
921 | snd_hda_codec_write( | ||
922 | codec, 0x18, 0, | ||
923 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
924 | snd_hda_codec_write( | ||
925 | codec, 0x34, 0, | ||
926 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
927 | } else { | ||
928 | snd_hda_codec_write( | ||
929 | codec, 0x18, 0, | ||
930 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
931 | snd_hda_codec_write( | ||
932 | codec, 0x34, 0, | ||
933 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
934 | } | ||
935 | |||
936 | /* Mono Out */ | ||
937 | /* PW15 (31h), MW8(17h), MUX8(3bh) */ | ||
938 | present = snd_hda_jack_detect(codec, 0x26); | ||
939 | parm = AC_PWRST_D3; | ||
940 | set_pin_power_state(codec, 0x31, &parm); | ||
941 | if (present) { | ||
942 | snd_hda_codec_write( | ||
943 | codec, 0x17, 0, | ||
944 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
945 | snd_hda_codec_write( | ||
946 | codec, 0x3b, 0, | ||
947 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
948 | } else { | ||
949 | snd_hda_codec_write( | ||
950 | codec, 0x17, 0, | ||
951 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
952 | snd_hda_codec_write( | ||
953 | codec, 0x3b, 0, | ||
954 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
955 | } | ||
956 | |||
957 | /* MW9 (21h) */ | ||
958 | if (imux_is_smixer || !is_aa_path_mute(codec)) | ||
959 | snd_hda_codec_write( | ||
960 | codec, 0x21, 0, | ||
961 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
962 | else | ||
963 | snd_hda_codec_write( | ||
964 | codec, 0x21, 0, | ||
965 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
966 | } else if (spec->codec_type == VT1812) { | ||
967 | unsigned int present; | ||
968 | /* MUX10 (1eh) = stereo mixer */ | ||
969 | imux_is_smixer = snd_hda_codec_read( | ||
970 | codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; | ||
971 | /* inputs */ | ||
972 | /* PW 5/6/7 (29h/2ah/2bh) */ | ||
973 | parm = AC_PWRST_D3; | ||
974 | set_pin_power_state(codec, 0x29, &parm); | ||
975 | set_pin_power_state(codec, 0x2a, &parm); | ||
976 | set_pin_power_state(codec, 0x2b, &parm); | ||
977 | if (imux_is_smixer) | ||
978 | parm = AC_PWRST_D0; | ||
979 | /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ | ||
980 | snd_hda_codec_write(codec, 0x1e, 0, | ||
981 | AC_VERB_SET_POWER_STATE, parm); | ||
982 | snd_hda_codec_write(codec, 0x1f, 0, | ||
983 | AC_VERB_SET_POWER_STATE, parm); | ||
984 | snd_hda_codec_write(codec, 0x10, 0, | ||
985 | AC_VERB_SET_POWER_STATE, parm); | ||
986 | snd_hda_codec_write(codec, 0x11, 0, | ||
987 | AC_VERB_SET_POWER_STATE, parm); | ||
988 | |||
989 | /* outputs */ | ||
990 | /* AOW0 (8h)*/ | ||
991 | snd_hda_codec_write(codec, 0x8, 0, | ||
992 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
993 | |||
994 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ | ||
995 | parm = AC_PWRST_D3; | ||
996 | set_pin_power_state(codec, 0x28, &parm); | ||
997 | snd_hda_codec_write(codec, 0x18, 0, | ||
998 | AC_VERB_SET_POWER_STATE, parm); | ||
999 | snd_hda_codec_write(codec, 0x38, 0, | ||
1000 | AC_VERB_SET_POWER_STATE, parm); | ||
1001 | |||
1002 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ | ||
1003 | parm = AC_PWRST_D3; | ||
1004 | set_pin_power_state(codec, 0x25, &parm); | ||
1005 | snd_hda_codec_write(codec, 0x15, 0, | ||
1006 | AC_VERB_SET_POWER_STATE, parm); | ||
1007 | snd_hda_codec_write(codec, 0x35, 0, | ||
1008 | AC_VERB_SET_POWER_STATE, parm); | ||
1009 | if (spec->hp_independent_mode) { | ||
1010 | snd_hda_codec_write(codec, 0x9, 0, | ||
1011 | AC_VERB_SET_POWER_STATE, parm); | ||
1012 | } | ||
1013 | |||
1014 | /* Internal Speaker */ | ||
1015 | /* PW0 (24h), MW0(14h), MUX0(34h) */ | ||
1016 | present = snd_hda_jack_detect(codec, 0x25); | ||
1017 | parm = AC_PWRST_D3; | ||
1018 | set_pin_power_state(codec, 0x24, &parm); | ||
1019 | if (present) { | ||
1020 | snd_hda_codec_write(codec, 0x14, 0, | ||
1021 | AC_VERB_SET_POWER_STATE, | ||
1022 | AC_PWRST_D3); | ||
1023 | snd_hda_codec_write(codec, 0x34, 0, | ||
1024 | AC_VERB_SET_POWER_STATE, | ||
1025 | AC_PWRST_D3); | ||
1026 | } else { | ||
1027 | snd_hda_codec_write(codec, 0x14, 0, | ||
1028 | AC_VERB_SET_POWER_STATE, | ||
1029 | AC_PWRST_D0); | ||
1030 | snd_hda_codec_write(codec, 0x34, 0, | ||
1031 | AC_VERB_SET_POWER_STATE, | ||
1032 | AC_PWRST_D0); | ||
1033 | } | ||
1034 | /* Mono Out */ | ||
1035 | /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */ | ||
1036 | present = snd_hda_jack_detect(codec, 0x28); | ||
1037 | parm = AC_PWRST_D3; | ||
1038 | set_pin_power_state(codec, 0x31, &parm); | ||
1039 | if (present) { | ||
1040 | snd_hda_codec_write(codec, 0x1c, 0, | ||
1041 | AC_VERB_SET_POWER_STATE, | ||
1042 | AC_PWRST_D3); | ||
1043 | snd_hda_codec_write(codec, 0x3c, 0, | ||
1044 | AC_VERB_SET_POWER_STATE, | ||
1045 | AC_PWRST_D3); | ||
1046 | snd_hda_codec_write(codec, 0x3e, 0, | ||
1047 | AC_VERB_SET_POWER_STATE, | ||
1048 | AC_PWRST_D3); | ||
1049 | } else { | ||
1050 | snd_hda_codec_write(codec, 0x1c, 0, | ||
1051 | AC_VERB_SET_POWER_STATE, | ||
1052 | AC_PWRST_D0); | ||
1053 | snd_hda_codec_write(codec, 0x3c, 0, | ||
1054 | AC_VERB_SET_POWER_STATE, | ||
1055 | AC_PWRST_D0); | ||
1056 | snd_hda_codec_write(codec, 0x3e, 0, | ||
1057 | AC_VERB_SET_POWER_STATE, | ||
1058 | AC_PWRST_D0); | ||
1059 | } | ||
1060 | |||
1061 | /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ | ||
1062 | parm = AC_PWRST_D3; | ||
1063 | set_pin_power_state(codec, 0x33, &parm); | ||
1064 | snd_hda_codec_write(codec, 0x1d, 0, | ||
1065 | AC_VERB_SET_POWER_STATE, parm); | ||
1066 | snd_hda_codec_write(codec, 0x3d, 0, | ||
1067 | AC_VERB_SET_POWER_STATE, parm); | ||
1068 | |||
1069 | /* MW9 (21h) */ | ||
1070 | if (imux_is_smixer || !is_aa_path_mute(codec)) | ||
1071 | snd_hda_codec_write( | ||
1072 | codec, 0x21, 0, | ||
1073 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
1074 | else | ||
1075 | snd_hda_codec_write( | ||
1076 | codec, 0x21, 0, | ||
1077 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
1078 | } | ||
1079 | } | ||
1080 | |||
1081 | /* | 621 | /* |
1082 | * input MUX handling | 622 | * input MUX handling |
1083 | */ | 623 | */ |
@@ -1120,7 +660,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, | |||
1120 | spec->mux_nids[adc_idx], | 660 | spec->mux_nids[adc_idx], |
1121 | &spec->cur_mux[adc_idx]); | 661 | &spec->cur_mux[adc_idx]); |
1122 | /* update jack power state */ | 662 | /* update jack power state */ |
1123 | set_jack_power_state(codec); | 663 | set_widgets_power_state(codec); |
1124 | 664 | ||
1125 | return ret; | 665 | return ret; |
1126 | } | 666 | } |
@@ -1168,6 +708,9 @@ static hda_nid_t side_mute_channel(struct via_spec *spec) | |||
1168 | case VT1709_10CH: return 0x29; | 708 | case VT1709_10CH: return 0x29; |
1169 | case VT1708B_8CH: /* fall thru */ | 709 | case VT1708B_8CH: /* fall thru */ |
1170 | case VT1708S: return 0x27; | 710 | case VT1708S: return 0x27; |
711 | case VT2002P: return 0x19; | ||
712 | case VT1802: return 0x15; | ||
713 | case VT1812: return 0x15; | ||
1171 | default: return 0; | 714 | default: return 0; |
1172 | } | 715 | } |
1173 | } | 716 | } |
@@ -1176,13 +719,22 @@ static int update_side_mute_status(struct hda_codec *codec) | |||
1176 | { | 719 | { |
1177 | /* mute side channel */ | 720 | /* mute side channel */ |
1178 | struct via_spec *spec = codec->spec; | 721 | struct via_spec *spec = codec->spec; |
1179 | unsigned int parm = spec->hp_independent_mode | 722 | unsigned int parm; |
1180 | ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; | ||
1181 | hda_nid_t sw3 = side_mute_channel(spec); | 723 | hda_nid_t sw3 = side_mute_channel(spec); |
1182 | 724 | ||
1183 | if (sw3) | 725 | if (sw3) { |
1184 | snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 726 | if (VT2002P_COMPATIBLE(spec)) |
1185 | parm); | 727 | parm = spec->hp_independent_mode ? |
728 | AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1); | ||
729 | else | ||
730 | parm = spec->hp_independent_mode ? | ||
731 | AMP_OUT_MUTE : AMP_OUT_UNMUTE; | ||
732 | snd_hda_codec_write(codec, sw3, 0, | ||
733 | AC_VERB_SET_AMP_GAIN_MUTE, parm); | ||
734 | if (spec->codec_type == VT1812) | ||
735 | snd_hda_codec_write(codec, 0x1d, 0, | ||
736 | AC_VERB_SET_AMP_GAIN_MUTE, parm); | ||
737 | } | ||
1186 | return 0; | 738 | return 0; |
1187 | } | 739 | } |
1188 | 740 | ||
@@ -1217,19 +769,18 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, | |||
1217 | || spec->codec_type == VT1702 | 769 | || spec->codec_type == VT1702 |
1218 | || spec->codec_type == VT1718S | 770 | || spec->codec_type == VT1718S |
1219 | || spec->codec_type == VT1716S | 771 | || spec->codec_type == VT1716S |
1220 | || spec->codec_type == VT2002P | 772 | || VT2002P_COMPATIBLE(spec)) { |
1221 | || spec->codec_type == VT1812) { | ||
1222 | activate_ctl(codec, "Headphone Playback Volume", | 773 | activate_ctl(codec, "Headphone Playback Volume", |
1223 | spec->hp_independent_mode); | 774 | spec->hp_independent_mode); |
1224 | activate_ctl(codec, "Headphone Playback Switch", | 775 | activate_ctl(codec, "Headphone Playback Switch", |
1225 | spec->hp_independent_mode); | 776 | spec->hp_independent_mode); |
1226 | } | 777 | } |
1227 | /* update jack power state */ | 778 | /* update jack power state */ |
1228 | set_jack_power_state(codec); | 779 | set_widgets_power_state(codec); |
1229 | return 0; | 780 | return 0; |
1230 | } | 781 | } |
1231 | 782 | ||
1232 | static struct snd_kcontrol_new via_hp_mixer[2] = { | 783 | static const struct snd_kcontrol_new via_hp_mixer[2] = { |
1233 | { | 784 | { |
1234 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 785 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1235 | .name = "Independent HP", | 786 | .name = "Independent HP", |
@@ -1256,6 +807,7 @@ static int via_hp_build(struct hda_codec *codec) | |||
1256 | nid = 0x34; | 807 | nid = 0x34; |
1257 | break; | 808 | break; |
1258 | case VT2002P: | 809 | case VT2002P: |
810 | case VT1802: | ||
1259 | nid = 0x35; | 811 | nid = 0x35; |
1260 | break; | 812 | break; |
1261 | case VT1812: | 813 | case VT1812: |
@@ -1292,14 +844,18 @@ static void notify_aa_path_ctls(struct hda_codec *codec) | |||
1292 | { | 844 | { |
1293 | int i; | 845 | int i; |
1294 | struct snd_ctl_elem_id id; | 846 | struct snd_ctl_elem_id id; |
1295 | const char *labels[] = {"Mic", "Front Mic", "Line"}; | 847 | const char *labels[] = {"Mic", "Front Mic", "Line", "Rear Mic"}; |
848 | struct snd_kcontrol *ctl; | ||
1296 | 849 | ||
1297 | memset(&id, 0, sizeof(id)); | 850 | memset(&id, 0, sizeof(id)); |
1298 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; | 851 | id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; |
1299 | for (i = 0; i < ARRAY_SIZE(labels); i++) { | 852 | for (i = 0; i < ARRAY_SIZE(labels); i++) { |
1300 | sprintf(id.name, "%s Playback Volume", labels[i]); | 853 | sprintf(id.name, "%s Playback Volume", labels[i]); |
1301 | snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE, | 854 | ctl = snd_hda_find_mixer_ctl(codec, id.name); |
1302 | &id); | 855 | if (ctl) |
856 | snd_ctl_notify(codec->bus->card, | ||
857 | SNDRV_CTL_EVENT_MASK_VALUE, | ||
858 | &ctl->id); | ||
1303 | } | 859 | } |
1304 | } | 860 | } |
1305 | 861 | ||
@@ -1443,11 +999,11 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol, | |||
1443 | } | 999 | } |
1444 | } | 1000 | } |
1445 | spec->smart51_enabled = *ucontrol->value.integer.value; | 1001 | spec->smart51_enabled = *ucontrol->value.integer.value; |
1446 | set_jack_power_state(codec); | 1002 | set_widgets_power_state(codec); |
1447 | return 1; | 1003 | return 1; |
1448 | } | 1004 | } |
1449 | 1005 | ||
1450 | static struct snd_kcontrol_new via_smart51_mixer[2] = { | 1006 | static const struct snd_kcontrol_new via_smart51_mixer[2] = { |
1451 | { | 1007 | { |
1452 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 1008 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
1453 | .name = "Smart 5.1", | 1009 | .name = "Smart 5.1", |
@@ -1469,6 +1025,11 @@ static int via_smart51_build(struct via_spec *spec) | |||
1469 | hda_nid_t nid; | 1025 | hda_nid_t nid; |
1470 | int i; | 1026 | int i; |
1471 | 1027 | ||
1028 | if (!cfg) | ||
1029 | return 0; | ||
1030 | if (cfg->line_outs > 2) | ||
1031 | return 0; | ||
1032 | |||
1472 | knew = via_clone_control(spec, &via_smart51_mixer[0]); | 1033 | knew = via_clone_control(spec, &via_smart51_mixer[0]); |
1473 | if (knew == NULL) | 1034 | if (knew == NULL) |
1474 | return -ENOMEM; | 1035 | return -ENOMEM; |
@@ -1488,7 +1049,7 @@ static int via_smart51_build(struct via_spec *spec) | |||
1488 | } | 1049 | } |
1489 | 1050 | ||
1490 | /* capture mixer elements */ | 1051 | /* capture mixer elements */ |
1491 | static struct snd_kcontrol_new vt1708_capture_mixer[] = { | 1052 | static const struct snd_kcontrol_new vt1708_capture_mixer[] = { |
1492 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), | 1053 | HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), |
1493 | HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT), | 1054 | HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT), |
1494 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT), | 1055 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT), |
@@ -1539,6 +1100,7 @@ static int is_aa_path_mute(struct hda_codec *codec) | |||
1539 | break; | 1100 | break; |
1540 | case VT2002P: | 1101 | case VT2002P: |
1541 | case VT1812: | 1102 | case VT1812: |
1103 | case VT1802: | ||
1542 | nid_mixer = 0x21; | 1104 | nid_mixer = 0x21; |
1543 | start_idx = 0; | 1105 | start_idx = 0; |
1544 | end_idx = 2; | 1106 | end_idx = 2; |
@@ -1603,6 +1165,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle) | |||
1603 | break; | 1165 | break; |
1604 | case VT2002P: | 1166 | case VT2002P: |
1605 | case VT1812: | 1167 | case VT1812: |
1168 | case VT1802: | ||
1606 | verb = 0xf93; | 1169 | verb = 0xf93; |
1607 | parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */ | 1170 | parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */ |
1608 | break; | 1171 | break; |
@@ -1616,7 +1179,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle) | |||
1616 | /* | 1179 | /* |
1617 | * generic initialization of ADC, input mixers and output mixers | 1180 | * generic initialization of ADC, input mixers and output mixers |
1618 | */ | 1181 | */ |
1619 | static struct hda_verb vt1708_volume_init_verbs[] = { | 1182 | static const struct hda_verb vt1708_volume_init_verbs[] = { |
1620 | /* | 1183 | /* |
1621 | * Unmute ADC0-1 and set the default input to mic-in | 1184 | * Unmute ADC0-1 and set the default input to mic-in |
1622 | */ | 1185 | */ |
@@ -1646,6 +1209,8 @@ static struct hda_verb vt1708_volume_init_verbs[] = { | |||
1646 | {0x20, AC_VERB_SET_CONNECT_SEL, 0}, | 1209 | {0x20, AC_VERB_SET_CONNECT_SEL, 0}, |
1647 | /* PW9 Output enable */ | 1210 | /* PW9 Output enable */ |
1648 | {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, | 1211 | {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, |
1212 | /* power down jack detect function */ | ||
1213 | {0x1, 0xf81, 0x1}, | ||
1649 | { } | 1214 | { } |
1650 | }; | 1215 | }; |
1651 | 1216 | ||
@@ -1668,7 +1233,7 @@ static void playback_multi_pcm_prep_0(struct hda_codec *codec, | |||
1668 | { | 1233 | { |
1669 | struct via_spec *spec = codec->spec; | 1234 | struct via_spec *spec = codec->spec; |
1670 | struct hda_multi_out *mout = &spec->multiout; | 1235 | struct hda_multi_out *mout = &spec->multiout; |
1671 | hda_nid_t *nids = mout->dac_nids; | 1236 | const hda_nid_t *nids = mout->dac_nids; |
1672 | int chs = substream->runtime->channels; | 1237 | int chs = substream->runtime->channels; |
1673 | int i; | 1238 | int i; |
1674 | 1239 | ||
@@ -1737,7 +1302,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, | |||
1737 | { | 1302 | { |
1738 | struct via_spec *spec = codec->spec; | 1303 | struct via_spec *spec = codec->spec; |
1739 | struct hda_multi_out *mout = &spec->multiout; | 1304 | struct hda_multi_out *mout = &spec->multiout; |
1740 | hda_nid_t *nids = mout->dac_nids; | 1305 | const hda_nid_t *nids = mout->dac_nids; |
1741 | 1306 | ||
1742 | if (substream->number == 0) | 1307 | if (substream->number == 0) |
1743 | playback_multi_pcm_prep_0(codec, stream_tag, format, | 1308 | playback_multi_pcm_prep_0(codec, stream_tag, format, |
@@ -1758,7 +1323,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
1758 | { | 1323 | { |
1759 | struct via_spec *spec = codec->spec; | 1324 | struct via_spec *spec = codec->spec; |
1760 | struct hda_multi_out *mout = &spec->multiout; | 1325 | struct hda_multi_out *mout = &spec->multiout; |
1761 | hda_nid_t *nids = mout->dac_nids; | 1326 | const hda_nid_t *nids = mout->dac_nids; |
1762 | int i; | 1327 | int i; |
1763 | 1328 | ||
1764 | if (substream->number == 0) { | 1329 | if (substream->number == 0) { |
@@ -1856,7 +1421,7 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, | |||
1856 | return 0; | 1421 | return 0; |
1857 | } | 1422 | } |
1858 | 1423 | ||
1859 | static struct hda_pcm_stream vt1708_pcm_analog_playback = { | 1424 | static const struct hda_pcm_stream vt1708_pcm_analog_playback = { |
1860 | .substreams = 2, | 1425 | .substreams = 2, |
1861 | .channels_min = 2, | 1426 | .channels_min = 2, |
1862 | .channels_max = 8, | 1427 | .channels_max = 8, |
@@ -1868,7 +1433,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_playback = { | |||
1868 | }, | 1433 | }, |
1869 | }; | 1434 | }; |
1870 | 1435 | ||
1871 | static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { | 1436 | static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { |
1872 | .substreams = 2, | 1437 | .substreams = 2, |
1873 | .channels_min = 2, | 1438 | .channels_min = 2, |
1874 | .channels_max = 8, | 1439 | .channels_max = 8, |
@@ -1885,7 +1450,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { | |||
1885 | }, | 1450 | }, |
1886 | }; | 1451 | }; |
1887 | 1452 | ||
1888 | static struct hda_pcm_stream vt1708_pcm_analog_capture = { | 1453 | static const struct hda_pcm_stream vt1708_pcm_analog_capture = { |
1889 | .substreams = 2, | 1454 | .substreams = 2, |
1890 | .channels_min = 2, | 1455 | .channels_min = 2, |
1891 | .channels_max = 2, | 1456 | .channels_max = 2, |
@@ -1896,7 +1461,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_capture = { | |||
1896 | }, | 1461 | }, |
1897 | }; | 1462 | }; |
1898 | 1463 | ||
1899 | static struct hda_pcm_stream vt1708_pcm_digital_playback = { | 1464 | static const struct hda_pcm_stream vt1708_pcm_digital_playback = { |
1900 | .substreams = 1, | 1465 | .substreams = 1, |
1901 | .channels_min = 2, | 1466 | .channels_min = 2, |
1902 | .channels_max = 2, | 1467 | .channels_max = 2, |
@@ -1909,7 +1474,7 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = { | |||
1909 | }, | 1474 | }, |
1910 | }; | 1475 | }; |
1911 | 1476 | ||
1912 | static struct hda_pcm_stream vt1708_pcm_digital_capture = { | 1477 | static const struct hda_pcm_stream vt1708_pcm_digital_capture = { |
1913 | .substreams = 1, | 1478 | .substreams = 1, |
1914 | .channels_min = 2, | 1479 | .channels_min = 2, |
1915 | .channels_max = 2, | 1480 | .channels_max = 2, |
@@ -1919,7 +1484,7 @@ static int via_build_controls(struct hda_codec *codec) | |||
1919 | { | 1484 | { |
1920 | struct via_spec *spec = codec->spec; | 1485 | struct via_spec *spec = codec->spec; |
1921 | struct snd_kcontrol *kctl; | 1486 | struct snd_kcontrol *kctl; |
1922 | struct snd_kcontrol_new *knew; | 1487 | const struct snd_kcontrol_new *knew; |
1923 | int err, i; | 1488 | int err, i; |
1924 | 1489 | ||
1925 | for (i = 0; i < spec->num_mixers; i++) { | 1490 | for (i = 0; i < spec->num_mixers; i++) { |
@@ -1967,7 +1532,7 @@ static int via_build_controls(struct hda_codec *codec) | |||
1967 | } | 1532 | } |
1968 | 1533 | ||
1969 | /* init power states */ | 1534 | /* init power states */ |
1970 | set_jack_power_state(codec); | 1535 | set_widgets_power_state(codec); |
1971 | analog_low_current_mode(codec, 1); | 1536 | analog_low_current_mode(codec, 1); |
1972 | 1537 | ||
1973 | via_free_kctls(codec); /* no longer needed */ | 1538 | via_free_kctls(codec); /* no longer needed */ |
@@ -2131,7 +1696,7 @@ static void via_speaker_automute(struct hda_codec *codec) | |||
2131 | unsigned int hp_present; | 1696 | unsigned int hp_present; |
2132 | struct via_spec *spec = codec->spec; | 1697 | struct via_spec *spec = codec->spec; |
2133 | 1698 | ||
2134 | if (spec->codec_type != VT2002P && spec->codec_type != VT1812) | 1699 | if (!VT2002P_COMPATIBLE(spec)) |
2135 | return; | 1700 | return; |
2136 | 1701 | ||
2137 | hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); | 1702 | hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); |
@@ -2190,17 +1755,21 @@ static void via_unsol_event(struct hda_codec *codec, | |||
2190 | unsigned int res) | 1755 | unsigned int res) |
2191 | { | 1756 | { |
2192 | res >>= 26; | 1757 | res >>= 26; |
2193 | if (res & VIA_HP_EVENT) | 1758 | |
1759 | if (res & VIA_JACK_EVENT) | ||
1760 | set_widgets_power_state(codec); | ||
1761 | |||
1762 | res &= ~VIA_JACK_EVENT; | ||
1763 | |||
1764 | if (res == VIA_HP_EVENT) | ||
2194 | via_hp_automute(codec); | 1765 | via_hp_automute(codec); |
2195 | if (res & VIA_GPIO_EVENT) | 1766 | else if (res == VIA_GPIO_EVENT) |
2196 | via_gpio_control(codec); | 1767 | via_gpio_control(codec); |
2197 | if (res & VIA_JACK_EVENT) | 1768 | else if (res == VIA_MONO_EVENT) |
2198 | set_jack_power_state(codec); | ||
2199 | if (res & VIA_MONO_EVENT) | ||
2200 | via_mono_automute(codec); | 1769 | via_mono_automute(codec); |
2201 | if (res & VIA_SPEAKER_EVENT) | 1770 | else if (res == VIA_SPEAKER_EVENT) |
2202 | via_speaker_automute(codec); | 1771 | via_speaker_automute(codec); |
2203 | if (res & VIA_BIND_HP_EVENT) | 1772 | else if (res == VIA_BIND_HP_EVENT) |
2204 | via_hp_bind_automute(codec); | 1773 | via_hp_bind_automute(codec); |
2205 | } | 1774 | } |
2206 | 1775 | ||
@@ -2250,7 +1819,7 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) | |||
2250 | 1819 | ||
2251 | /* | 1820 | /* |
2252 | */ | 1821 | */ |
2253 | static struct hda_codec_ops via_patch_ops = { | 1822 | static const struct hda_codec_ops via_patch_ops = { |
2254 | .build_controls = via_build_controls, | 1823 | .build_controls = via_build_controls, |
2255 | .build_pcms = via_build_pcms, | 1824 | .build_pcms = via_build_pcms, |
2256 | .init = via_init, | 1825 | .init = via_init, |
@@ -2280,16 +1849,16 @@ static int vt1708_auto_fill_dac_nids(struct via_spec *spec, | |||
2280 | /* config dac list */ | 1849 | /* config dac list */ |
2281 | switch (i) { | 1850 | switch (i) { |
2282 | case AUTO_SEQ_FRONT: | 1851 | case AUTO_SEQ_FRONT: |
2283 | spec->multiout.dac_nids[i] = 0x10; | 1852 | spec->private_dac_nids[i] = 0x10; |
2284 | break; | 1853 | break; |
2285 | case AUTO_SEQ_CENLFE: | 1854 | case AUTO_SEQ_CENLFE: |
2286 | spec->multiout.dac_nids[i] = 0x12; | 1855 | spec->private_dac_nids[i] = 0x12; |
2287 | break; | 1856 | break; |
2288 | case AUTO_SEQ_SURROUND: | 1857 | case AUTO_SEQ_SURROUND: |
2289 | spec->multiout.dac_nids[i] = 0x11; | 1858 | spec->private_dac_nids[i] = 0x11; |
2290 | break; | 1859 | break; |
2291 | case AUTO_SEQ_SIDE: | 1860 | case AUTO_SEQ_SIDE: |
2292 | spec->multiout.dac_nids[i] = 0x13; | 1861 | spec->private_dac_nids[i] = 0x13; |
2293 | break; | 1862 | break; |
2294 | } | 1863 | } |
2295 | } | 1864 | } |
@@ -2433,7 +2002,8 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
2433 | static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, | 2002 | static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, |
2434 | const struct auto_pin_cfg *cfg, | 2003 | const struct auto_pin_cfg *cfg, |
2435 | hda_nid_t cap_nid, | 2004 | hda_nid_t cap_nid, |
2436 | hda_nid_t pin_idxs[], int num_idxs) | 2005 | const hda_nid_t pin_idxs[], |
2006 | int num_idxs) | ||
2437 | { | 2007 | { |
2438 | struct via_spec *spec = codec->spec; | 2008 | struct via_spec *spec = codec->spec; |
2439 | struct hda_input_mux *imux = &spec->private_imux[0]; | 2009 | struct hda_input_mux *imux = &spec->private_imux[0]; |
@@ -2479,13 +2049,13 @@ static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, | |||
2479 | static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec, | 2049 | static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec, |
2480 | const struct auto_pin_cfg *cfg) | 2050 | const struct auto_pin_cfg *cfg) |
2481 | { | 2051 | { |
2482 | static hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 }; | 2052 | static const hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 }; |
2483 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs, | 2053 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs, |
2484 | ARRAY_SIZE(pin_idxs)); | 2054 | ARRAY_SIZE(pin_idxs)); |
2485 | } | 2055 | } |
2486 | 2056 | ||
2487 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2057 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2488 | static struct hda_amp_list vt1708_loopbacks[] = { | 2058 | static const struct hda_amp_list vt1708_loopbacks[] = { |
2489 | { 0x17, HDA_INPUT, 1 }, | 2059 | { 0x17, HDA_INPUT, 1 }, |
2490 | { 0x17, HDA_INPUT, 2 }, | 2060 | { 0x17, HDA_INPUT, 2 }, |
2491 | { 0x17, HDA_INPUT, 3 }, | 2061 | { 0x17, HDA_INPUT, 3 }, |
@@ -2544,7 +2114,7 @@ static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol, | |||
2544 | return change; | 2114 | return change; |
2545 | } | 2115 | } |
2546 | 2116 | ||
2547 | static struct snd_kcontrol_new vt1708_jack_detectect[] = { | 2117 | static const struct snd_kcontrol_new vt1708_jack_detectect[] = { |
2548 | { | 2118 | { |
2549 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 2119 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
2550 | .name = "Jack Detect", | 2120 | .name = "Jack Detect", |
@@ -2619,7 +2189,8 @@ static int via_auto_init(struct hda_codec *codec) | |||
2619 | via_auto_init_multi_out(codec); | 2189 | via_auto_init_multi_out(codec); |
2620 | via_auto_init_hp_out(codec); | 2190 | via_auto_init_hp_out(codec); |
2621 | via_auto_init_analog_input(codec); | 2191 | via_auto_init_analog_input(codec); |
2622 | if (spec->codec_type == VT2002P || spec->codec_type == VT1812) { | 2192 | |
2193 | if (VT2002P_COMPATIBLE(spec)) { | ||
2623 | via_hp_bind_automute(codec); | 2194 | via_hp_bind_automute(codec); |
2624 | } else { | 2195 | } else { |
2625 | via_hp_automute(codec); | 2196 | via_hp_automute(codec); |
@@ -2723,7 +2294,7 @@ static int patch_vt1708(struct hda_codec *codec) | |||
2723 | } | 2294 | } |
2724 | 2295 | ||
2725 | /* capture mixer elements */ | 2296 | /* capture mixer elements */ |
2726 | static struct snd_kcontrol_new vt1709_capture_mixer[] = { | 2297 | static const struct snd_kcontrol_new vt1709_capture_mixer[] = { |
2727 | HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT), | 2298 | HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT), |
2728 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT), | 2299 | HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT), |
2729 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT), | 2300 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT), |
@@ -2745,7 +2316,7 @@ static struct snd_kcontrol_new vt1709_capture_mixer[] = { | |||
2745 | { } /* end */ | 2316 | { } /* end */ |
2746 | }; | 2317 | }; |
2747 | 2318 | ||
2748 | static struct hda_verb vt1709_uniwill_init_verbs[] = { | 2319 | static const struct hda_verb vt1709_uniwill_init_verbs[] = { |
2749 | {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, | 2320 | {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, |
2750 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, | 2321 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, |
2751 | { } | 2322 | { } |
@@ -2754,7 +2325,7 @@ static struct hda_verb vt1709_uniwill_init_verbs[] = { | |||
2754 | /* | 2325 | /* |
2755 | * generic initialization of ADC, input mixers and output mixers | 2326 | * generic initialization of ADC, input mixers and output mixers |
2756 | */ | 2327 | */ |
2757 | static struct hda_verb vt1709_10ch_volume_init_verbs[] = { | 2328 | static const struct hda_verb vt1709_10ch_volume_init_verbs[] = { |
2758 | /* | 2329 | /* |
2759 | * Unmute ADC0-2 and set the default input to mic-in | 2330 | * Unmute ADC0-2 and set the default input to mic-in |
2760 | */ | 2331 | */ |
@@ -2794,7 +2365,7 @@ static struct hda_verb vt1709_10ch_volume_init_verbs[] = { | |||
2794 | { } | 2365 | { } |
2795 | }; | 2366 | }; |
2796 | 2367 | ||
2797 | static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { | 2368 | static const struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { |
2798 | .substreams = 1, | 2369 | .substreams = 1, |
2799 | .channels_min = 2, | 2370 | .channels_min = 2, |
2800 | .channels_max = 10, | 2371 | .channels_max = 10, |
@@ -2806,7 +2377,7 @@ static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { | |||
2806 | }, | 2377 | }, |
2807 | }; | 2378 | }; |
2808 | 2379 | ||
2809 | static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { | 2380 | static const struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { |
2810 | .substreams = 1, | 2381 | .substreams = 1, |
2811 | .channels_min = 2, | 2382 | .channels_min = 2, |
2812 | .channels_max = 6, | 2383 | .channels_max = 6, |
@@ -2818,7 +2389,7 @@ static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { | |||
2818 | }, | 2389 | }, |
2819 | }; | 2390 | }; |
2820 | 2391 | ||
2821 | static struct hda_pcm_stream vt1709_pcm_analog_capture = { | 2392 | static const struct hda_pcm_stream vt1709_pcm_analog_capture = { |
2822 | .substreams = 2, | 2393 | .substreams = 2, |
2823 | .channels_min = 2, | 2394 | .channels_min = 2, |
2824 | .channels_max = 2, | 2395 | .channels_max = 2, |
@@ -2829,7 +2400,7 @@ static struct hda_pcm_stream vt1709_pcm_analog_capture = { | |||
2829 | }, | 2400 | }, |
2830 | }; | 2401 | }; |
2831 | 2402 | ||
2832 | static struct hda_pcm_stream vt1709_pcm_digital_playback = { | 2403 | static const struct hda_pcm_stream vt1709_pcm_digital_playback = { |
2833 | .substreams = 1, | 2404 | .substreams = 1, |
2834 | .channels_min = 2, | 2405 | .channels_min = 2, |
2835 | .channels_max = 2, | 2406 | .channels_max = 2, |
@@ -2840,7 +2411,7 @@ static struct hda_pcm_stream vt1709_pcm_digital_playback = { | |||
2840 | }, | 2411 | }, |
2841 | }; | 2412 | }; |
2842 | 2413 | ||
2843 | static struct hda_pcm_stream vt1709_pcm_digital_capture = { | 2414 | static const struct hda_pcm_stream vt1709_pcm_digital_capture = { |
2844 | .substreams = 1, | 2415 | .substreams = 1, |
2845 | .channels_min = 2, | 2416 | .channels_min = 2, |
2846 | .channels_max = 2, | 2417 | .channels_max = 2, |
@@ -2867,26 +2438,26 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec, | |||
2867 | switch (i) { | 2438 | switch (i) { |
2868 | case AUTO_SEQ_FRONT: | 2439 | case AUTO_SEQ_FRONT: |
2869 | /* AOW0 */ | 2440 | /* AOW0 */ |
2870 | spec->multiout.dac_nids[i] = 0x10; | 2441 | spec->private_dac_nids[i] = 0x10; |
2871 | break; | 2442 | break; |
2872 | case AUTO_SEQ_CENLFE: | 2443 | case AUTO_SEQ_CENLFE: |
2873 | /* AOW2 */ | 2444 | /* AOW2 */ |
2874 | spec->multiout.dac_nids[i] = 0x12; | 2445 | spec->private_dac_nids[i] = 0x12; |
2875 | break; | 2446 | break; |
2876 | case AUTO_SEQ_SURROUND: | 2447 | case AUTO_SEQ_SURROUND: |
2877 | /* AOW3 */ | 2448 | /* AOW3 */ |
2878 | spec->multiout.dac_nids[i] = 0x11; | 2449 | spec->private_dac_nids[i] = 0x11; |
2879 | break; | 2450 | break; |
2880 | case AUTO_SEQ_SIDE: | 2451 | case AUTO_SEQ_SIDE: |
2881 | /* AOW1 */ | 2452 | /* AOW1 */ |
2882 | spec->multiout.dac_nids[i] = 0x27; | 2453 | spec->private_dac_nids[i] = 0x27; |
2883 | break; | 2454 | break; |
2884 | default: | 2455 | default: |
2885 | break; | 2456 | break; |
2886 | } | 2457 | } |
2887 | } | 2458 | } |
2888 | } | 2459 | } |
2889 | spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ | 2460 | spec->private_dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ |
2890 | 2461 | ||
2891 | } else if (cfg->line_outs == 3) { /* 6 channels */ | 2462 | } else if (cfg->line_outs == 3) { /* 6 channels */ |
2892 | for (i = 0; i < cfg->line_outs; i++) { | 2463 | for (i = 0; i < cfg->line_outs; i++) { |
@@ -2896,15 +2467,15 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec, | |||
2896 | switch (i) { | 2467 | switch (i) { |
2897 | case AUTO_SEQ_FRONT: | 2468 | case AUTO_SEQ_FRONT: |
2898 | /* AOW0 */ | 2469 | /* AOW0 */ |
2899 | spec->multiout.dac_nids[i] = 0x10; | 2470 | spec->private_dac_nids[i] = 0x10; |
2900 | break; | 2471 | break; |
2901 | case AUTO_SEQ_CENLFE: | 2472 | case AUTO_SEQ_CENLFE: |
2902 | /* AOW2 */ | 2473 | /* AOW2 */ |
2903 | spec->multiout.dac_nids[i] = 0x12; | 2474 | spec->private_dac_nids[i] = 0x12; |
2904 | break; | 2475 | break; |
2905 | case AUTO_SEQ_SURROUND: | 2476 | case AUTO_SEQ_SURROUND: |
2906 | /* AOW1 */ | 2477 | /* AOW1 */ |
2907 | spec->multiout.dac_nids[i] = 0x11; | 2478 | spec->private_dac_nids[i] = 0x11; |
2908 | break; | 2479 | break; |
2909 | default: | 2480 | default: |
2910 | break; | 2481 | break; |
@@ -3052,7 +2623,7 @@ static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
3052 | static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec, | 2623 | static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec, |
3053 | const struct auto_pin_cfg *cfg) | 2624 | const struct auto_pin_cfg *cfg) |
3054 | { | 2625 | { |
3055 | static hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 }; | 2626 | static const hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 }; |
3056 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs, | 2627 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs, |
3057 | ARRAY_SIZE(pin_idxs)); | 2628 | ARRAY_SIZE(pin_idxs)); |
3058 | } | 2629 | } |
@@ -3102,7 +2673,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) | |||
3102 | } | 2673 | } |
3103 | 2674 | ||
3104 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2675 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3105 | static struct hda_amp_list vt1709_loopbacks[] = { | 2676 | static const struct hda_amp_list vt1709_loopbacks[] = { |
3106 | { 0x18, HDA_INPUT, 1 }, | 2677 | { 0x18, HDA_INPUT, 1 }, |
3107 | { 0x18, HDA_INPUT, 2 }, | 2678 | { 0x18, HDA_INPUT, 2 }, |
3108 | { 0x18, HDA_INPUT, 3 }, | 2679 | { 0x18, HDA_INPUT, 3 }, |
@@ -3163,7 +2734,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec) | |||
3163 | /* | 2734 | /* |
3164 | * generic initialization of ADC, input mixers and output mixers | 2735 | * generic initialization of ADC, input mixers and output mixers |
3165 | */ | 2736 | */ |
3166 | static struct hda_verb vt1709_6ch_volume_init_verbs[] = { | 2737 | static const struct hda_verb vt1709_6ch_volume_init_verbs[] = { |
3167 | /* | 2738 | /* |
3168 | * Unmute ADC0-2 and set the default input to mic-in | 2739 | * Unmute ADC0-2 and set the default input to mic-in |
3169 | */ | 2740 | */ |
@@ -3253,7 +2824,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec) | |||
3253 | } | 2824 | } |
3254 | 2825 | ||
3255 | /* capture mixer elements */ | 2826 | /* capture mixer elements */ |
3256 | static struct snd_kcontrol_new vt1708B_capture_mixer[] = { | 2827 | static const struct snd_kcontrol_new vt1708B_capture_mixer[] = { |
3257 | HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), | 2828 | HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), |
3258 | HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), | 2829 | HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), |
3259 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), | 2830 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), |
@@ -3275,7 +2846,7 @@ static struct snd_kcontrol_new vt1708B_capture_mixer[] = { | |||
3275 | /* | 2846 | /* |
3276 | * generic initialization of ADC, input mixers and output mixers | 2847 | * generic initialization of ADC, input mixers and output mixers |
3277 | */ | 2848 | */ |
3278 | static struct hda_verb vt1708B_8ch_volume_init_verbs[] = { | 2849 | static const struct hda_verb vt1708B_8ch_volume_init_verbs[] = { |
3279 | /* | 2850 | /* |
3280 | * Unmute ADC0-1 and set the default input to mic-in | 2851 | * Unmute ADC0-1 and set the default input to mic-in |
3281 | */ | 2852 | */ |
@@ -3310,7 +2881,7 @@ static struct hda_verb vt1708B_8ch_volume_init_verbs[] = { | |||
3310 | { } | 2881 | { } |
3311 | }; | 2882 | }; |
3312 | 2883 | ||
3313 | static struct hda_verb vt1708B_4ch_volume_init_verbs[] = { | 2884 | static const struct hda_verb vt1708B_4ch_volume_init_verbs[] = { |
3314 | /* | 2885 | /* |
3315 | * Unmute ADC0-1 and set the default input to mic-in | 2886 | * Unmute ADC0-1 and set the default input to mic-in |
3316 | */ | 2887 | */ |
@@ -3345,7 +2916,7 @@ static struct hda_verb vt1708B_4ch_volume_init_verbs[] = { | |||
3345 | { } | 2916 | { } |
3346 | }; | 2917 | }; |
3347 | 2918 | ||
3348 | static struct hda_verb vt1708B_uniwill_init_verbs[] = { | 2919 | static const struct hda_verb vt1708B_uniwill_init_verbs[] = { |
3349 | {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, | 2920 | {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, |
3350 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, | 2921 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, |
3351 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | 2922 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, |
@@ -3369,7 +2940,7 @@ static int via_pcm_open_close(struct hda_pcm_stream *hinfo, | |||
3369 | return 0; | 2940 | return 0; |
3370 | } | 2941 | } |
3371 | 2942 | ||
3372 | static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { | 2943 | static const struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { |
3373 | .substreams = 2, | 2944 | .substreams = 2, |
3374 | .channels_min = 2, | 2945 | .channels_min = 2, |
3375 | .channels_max = 8, | 2946 | .channels_max = 8, |
@@ -3382,7 +2953,7 @@ static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { | |||
3382 | }, | 2953 | }, |
3383 | }; | 2954 | }; |
3384 | 2955 | ||
3385 | static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { | 2956 | static const struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { |
3386 | .substreams = 2, | 2957 | .substreams = 2, |
3387 | .channels_min = 2, | 2958 | .channels_min = 2, |
3388 | .channels_max = 4, | 2959 | .channels_max = 4, |
@@ -3394,7 +2965,7 @@ static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { | |||
3394 | }, | 2965 | }, |
3395 | }; | 2966 | }; |
3396 | 2967 | ||
3397 | static struct hda_pcm_stream vt1708B_pcm_analog_capture = { | 2968 | static const struct hda_pcm_stream vt1708B_pcm_analog_capture = { |
3398 | .substreams = 2, | 2969 | .substreams = 2, |
3399 | .channels_min = 2, | 2970 | .channels_min = 2, |
3400 | .channels_max = 2, | 2971 | .channels_max = 2, |
@@ -3407,7 +2978,7 @@ static struct hda_pcm_stream vt1708B_pcm_analog_capture = { | |||
3407 | }, | 2978 | }, |
3408 | }; | 2979 | }; |
3409 | 2980 | ||
3410 | static struct hda_pcm_stream vt1708B_pcm_digital_playback = { | 2981 | static const struct hda_pcm_stream vt1708B_pcm_digital_playback = { |
3411 | .substreams = 1, | 2982 | .substreams = 1, |
3412 | .channels_min = 2, | 2983 | .channels_min = 2, |
3413 | .channels_max = 2, | 2984 | .channels_max = 2, |
@@ -3420,7 +2991,7 @@ static struct hda_pcm_stream vt1708B_pcm_digital_playback = { | |||
3420 | }, | 2991 | }, |
3421 | }; | 2992 | }; |
3422 | 2993 | ||
3423 | static struct hda_pcm_stream vt1708B_pcm_digital_capture = { | 2994 | static const struct hda_pcm_stream vt1708B_pcm_digital_capture = { |
3424 | .substreams = 1, | 2995 | .substreams = 1, |
3425 | .channels_min = 2, | 2996 | .channels_min = 2, |
3426 | .channels_max = 2, | 2997 | .channels_max = 2, |
@@ -3443,16 +3014,16 @@ static int vt1708B_auto_fill_dac_nids(struct via_spec *spec, | |||
3443 | /* config dac list */ | 3014 | /* config dac list */ |
3444 | switch (i) { | 3015 | switch (i) { |
3445 | case AUTO_SEQ_FRONT: | 3016 | case AUTO_SEQ_FRONT: |
3446 | spec->multiout.dac_nids[i] = 0x10; | 3017 | spec->private_dac_nids[i] = 0x10; |
3447 | break; | 3018 | break; |
3448 | case AUTO_SEQ_CENLFE: | 3019 | case AUTO_SEQ_CENLFE: |
3449 | spec->multiout.dac_nids[i] = 0x24; | 3020 | spec->private_dac_nids[i] = 0x24; |
3450 | break; | 3021 | break; |
3451 | case AUTO_SEQ_SURROUND: | 3022 | case AUTO_SEQ_SURROUND: |
3452 | spec->multiout.dac_nids[i] = 0x11; | 3023 | spec->private_dac_nids[i] = 0x11; |
3453 | break; | 3024 | break; |
3454 | case AUTO_SEQ_SIDE: | 3025 | case AUTO_SEQ_SIDE: |
3455 | spec->multiout.dac_nids[i] = 0x25; | 3026 | spec->private_dac_nids[i] = 0x25; |
3456 | break; | 3027 | break; |
3457 | } | 3028 | } |
3458 | } | 3029 | } |
@@ -3584,7 +3155,7 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
3584 | static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec, | 3155 | static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec, |
3585 | const struct auto_pin_cfg *cfg) | 3156 | const struct auto_pin_cfg *cfg) |
3586 | { | 3157 | { |
3587 | static hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e }; | 3158 | static const hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e }; |
3588 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, | 3159 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, |
3589 | ARRAY_SIZE(pin_idxs)); | 3160 | ARRAY_SIZE(pin_idxs)); |
3590 | } | 3161 | } |
@@ -3634,7 +3205,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) | |||
3634 | } | 3205 | } |
3635 | 3206 | ||
3636 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3207 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3637 | static struct hda_amp_list vt1708B_loopbacks[] = { | 3208 | static const struct hda_amp_list vt1708B_loopbacks[] = { |
3638 | { 0x16, HDA_INPUT, 1 }, | 3209 | { 0x16, HDA_INPUT, 1 }, |
3639 | { 0x16, HDA_INPUT, 2 }, | 3210 | { 0x16, HDA_INPUT, 2 }, |
3640 | { 0x16, HDA_INPUT, 3 }, | 3211 | { 0x16, HDA_INPUT, 3 }, |
@@ -3642,6 +3213,87 @@ static struct hda_amp_list vt1708B_loopbacks[] = { | |||
3642 | { } /* end */ | 3213 | { } /* end */ |
3643 | }; | 3214 | }; |
3644 | #endif | 3215 | #endif |
3216 | |||
3217 | static void set_widgets_power_state_vt1708B(struct hda_codec *codec) | ||
3218 | { | ||
3219 | struct via_spec *spec = codec->spec; | ||
3220 | int imux_is_smixer; | ||
3221 | unsigned int parm; | ||
3222 | int is_8ch = 0; | ||
3223 | if ((spec->codec_type != VT1708B_4CH) && | ||
3224 | (codec->vendor_id != 0x11064397)) | ||
3225 | is_8ch = 1; | ||
3226 | |||
3227 | /* SW0 (17h) = stereo mixer */ | ||
3228 | imux_is_smixer = | ||
3229 | (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) | ||
3230 | == ((spec->codec_type == VT1708S) ? 5 : 0)); | ||
3231 | /* inputs */ | ||
3232 | /* PW 1/2/5 (1ah/1bh/1eh) */ | ||
3233 | parm = AC_PWRST_D3; | ||
3234 | set_pin_power_state(codec, 0x1a, &parm); | ||
3235 | set_pin_power_state(codec, 0x1b, &parm); | ||
3236 | set_pin_power_state(codec, 0x1e, &parm); | ||
3237 | if (imux_is_smixer) | ||
3238 | parm = AC_PWRST_D0; | ||
3239 | /* SW0 (17h), AIW 0/1 (13h/14h) */ | ||
3240 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); | ||
3241 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); | ||
3242 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); | ||
3243 | |||
3244 | /* outputs */ | ||
3245 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | ||
3246 | parm = AC_PWRST_D3; | ||
3247 | set_pin_power_state(codec, 0x19, &parm); | ||
3248 | if (spec->smart51_enabled) | ||
3249 | set_pin_power_state(codec, 0x1b, &parm); | ||
3250 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); | ||
3251 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | ||
3252 | |||
3253 | /* PW6 (22h), SW2 (26h), AOW2 (24h) */ | ||
3254 | if (is_8ch) { | ||
3255 | parm = AC_PWRST_D3; | ||
3256 | set_pin_power_state(codec, 0x22, &parm); | ||
3257 | if (spec->smart51_enabled) | ||
3258 | set_pin_power_state(codec, 0x1a, &parm); | ||
3259 | snd_hda_codec_write(codec, 0x26, 0, | ||
3260 | AC_VERB_SET_POWER_STATE, parm); | ||
3261 | snd_hda_codec_write(codec, 0x24, 0, | ||
3262 | AC_VERB_SET_POWER_STATE, parm); | ||
3263 | } else if (codec->vendor_id == 0x11064397) { | ||
3264 | /* PW7(23h), SW2(27h), AOW2(25h) */ | ||
3265 | parm = AC_PWRST_D3; | ||
3266 | set_pin_power_state(codec, 0x23, &parm); | ||
3267 | if (spec->smart51_enabled) | ||
3268 | set_pin_power_state(codec, 0x1a, &parm); | ||
3269 | snd_hda_codec_write(codec, 0x27, 0, | ||
3270 | AC_VERB_SET_POWER_STATE, parm); | ||
3271 | snd_hda_codec_write(codec, 0x25, 0, | ||
3272 | AC_VERB_SET_POWER_STATE, parm); | ||
3273 | } | ||
3274 | |||
3275 | /* PW 3/4/7 (1ch/1dh/23h) */ | ||
3276 | parm = AC_PWRST_D3; | ||
3277 | /* force to D0 for internal Speaker */ | ||
3278 | set_pin_power_state(codec, 0x1c, &parm); | ||
3279 | set_pin_power_state(codec, 0x1d, &parm); | ||
3280 | if (is_8ch) | ||
3281 | set_pin_power_state(codec, 0x23, &parm); | ||
3282 | |||
3283 | /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ | ||
3284 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, | ||
3285 | imux_is_smixer ? AC_PWRST_D0 : parm); | ||
3286 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | ||
3287 | if (is_8ch) { | ||
3288 | snd_hda_codec_write(codec, 0x25, 0, | ||
3289 | AC_VERB_SET_POWER_STATE, parm); | ||
3290 | snd_hda_codec_write(codec, 0x27, 0, | ||
3291 | AC_VERB_SET_POWER_STATE, parm); | ||
3292 | } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode) | ||
3293 | snd_hda_codec_write(codec, 0x25, 0, | ||
3294 | AC_VERB_SET_POWER_STATE, parm); | ||
3295 | } | ||
3296 | |||
3645 | static int patch_vt1708S(struct hda_codec *codec); | 3297 | static int patch_vt1708S(struct hda_codec *codec); |
3646 | static int patch_vt1708B_8ch(struct hda_codec *codec) | 3298 | static int patch_vt1708B_8ch(struct hda_codec *codec) |
3647 | { | 3299 | { |
@@ -3692,6 +3344,8 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) | |||
3692 | spec->loopback.amplist = vt1708B_loopbacks; | 3344 | spec->loopback.amplist = vt1708B_loopbacks; |
3693 | #endif | 3345 | #endif |
3694 | 3346 | ||
3347 | spec->set_widgets_power_state = set_widgets_power_state_vt1708B; | ||
3348 | |||
3695 | return 0; | 3349 | return 0; |
3696 | } | 3350 | } |
3697 | 3351 | ||
@@ -3742,13 +3396,15 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) | |||
3742 | spec->loopback.amplist = vt1708B_loopbacks; | 3396 | spec->loopback.amplist = vt1708B_loopbacks; |
3743 | #endif | 3397 | #endif |
3744 | 3398 | ||
3399 | spec->set_widgets_power_state = set_widgets_power_state_vt1708B; | ||
3400 | |||
3745 | return 0; | 3401 | return 0; |
3746 | } | 3402 | } |
3747 | 3403 | ||
3748 | /* Patch for VT1708S */ | 3404 | /* Patch for VT1708S */ |
3749 | 3405 | ||
3750 | /* capture mixer elements */ | 3406 | /* capture mixer elements */ |
3751 | static struct snd_kcontrol_new vt1708S_capture_mixer[] = { | 3407 | static const struct snd_kcontrol_new vt1708S_capture_mixer[] = { |
3752 | HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), | 3408 | HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), |
3753 | HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), | 3409 | HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), |
3754 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), | 3410 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), |
@@ -3771,7 +3427,7 @@ static struct snd_kcontrol_new vt1708S_capture_mixer[] = { | |||
3771 | { } /* end */ | 3427 | { } /* end */ |
3772 | }; | 3428 | }; |
3773 | 3429 | ||
3774 | static struct hda_verb vt1708S_volume_init_verbs[] = { | 3430 | static const struct hda_verb vt1708S_volume_init_verbs[] = { |
3775 | /* Unmute ADC0-1 and set the default input to mic-in */ | 3431 | /* Unmute ADC0-1 and set the default input to mic-in */ |
3776 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 3432 | {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
3777 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 3433 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
@@ -3797,7 +3453,7 @@ static struct hda_verb vt1708S_volume_init_verbs[] = { | |||
3797 | { } | 3453 | { } |
3798 | }; | 3454 | }; |
3799 | 3455 | ||
3800 | static struct hda_verb vt1708S_uniwill_init_verbs[] = { | 3456 | static const struct hda_verb vt1708S_uniwill_init_verbs[] = { |
3801 | {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, | 3457 | {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, |
3802 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, | 3458 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, |
3803 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | 3459 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, |
@@ -3810,7 +3466,19 @@ static struct hda_verb vt1708S_uniwill_init_verbs[] = { | |||
3810 | { } | 3466 | { } |
3811 | }; | 3467 | }; |
3812 | 3468 | ||
3813 | static struct hda_pcm_stream vt1708S_pcm_analog_playback = { | 3469 | static const struct hda_verb vt1705_uniwill_init_verbs[] = { |
3470 | {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, | ||
3471 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, | ||
3472 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | ||
3473 | {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | ||
3474 | {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | ||
3475 | {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | ||
3476 | {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | ||
3477 | {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | ||
3478 | { } | ||
3479 | }; | ||
3480 | |||
3481 | static const struct hda_pcm_stream vt1708S_pcm_analog_playback = { | ||
3814 | .substreams = 2, | 3482 | .substreams = 2, |
3815 | .channels_min = 2, | 3483 | .channels_min = 2, |
3816 | .channels_max = 8, | 3484 | .channels_max = 8, |
@@ -3823,7 +3491,20 @@ static struct hda_pcm_stream vt1708S_pcm_analog_playback = { | |||
3823 | }, | 3491 | }, |
3824 | }; | 3492 | }; |
3825 | 3493 | ||
3826 | static struct hda_pcm_stream vt1708S_pcm_analog_capture = { | 3494 | static const struct hda_pcm_stream vt1705_pcm_analog_playback = { |
3495 | .substreams = 2, | ||
3496 | .channels_min = 2, | ||
3497 | .channels_max = 6, | ||
3498 | .nid = 0x10, /* NID to query formats and rates */ | ||
3499 | .ops = { | ||
3500 | .open = via_playback_pcm_open, | ||
3501 | .prepare = via_playback_multi_pcm_prepare, | ||
3502 | .cleanup = via_playback_multi_pcm_cleanup, | ||
3503 | .close = via_pcm_open_close | ||
3504 | }, | ||
3505 | }; | ||
3506 | |||
3507 | static const struct hda_pcm_stream vt1708S_pcm_analog_capture = { | ||
3827 | .substreams = 2, | 3508 | .substreams = 2, |
3828 | .channels_min = 2, | 3509 | .channels_min = 2, |
3829 | .channels_max = 2, | 3510 | .channels_max = 2, |
@@ -3836,7 +3517,7 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = { | |||
3836 | }, | 3517 | }, |
3837 | }; | 3518 | }; |
3838 | 3519 | ||
3839 | static struct hda_pcm_stream vt1708S_pcm_digital_playback = { | 3520 | static const struct hda_pcm_stream vt1708S_pcm_digital_playback = { |
3840 | .substreams = 1, | 3521 | .substreams = 1, |
3841 | .channels_min = 2, | 3522 | .channels_min = 2, |
3842 | .channels_max = 2, | 3523 | .channels_max = 2, |
@@ -3866,16 +3547,19 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, | |||
3866 | /* config dac list */ | 3547 | /* config dac list */ |
3867 | switch (i) { | 3548 | switch (i) { |
3868 | case AUTO_SEQ_FRONT: | 3549 | case AUTO_SEQ_FRONT: |
3869 | spec->multiout.dac_nids[i] = 0x10; | 3550 | spec->private_dac_nids[i] = 0x10; |
3870 | break; | 3551 | break; |
3871 | case AUTO_SEQ_CENLFE: | 3552 | case AUTO_SEQ_CENLFE: |
3872 | spec->multiout.dac_nids[i] = 0x24; | 3553 | if (spec->codec->vendor_id == 0x11064397) |
3554 | spec->private_dac_nids[i] = 0x25; | ||
3555 | else | ||
3556 | spec->private_dac_nids[i] = 0x24; | ||
3873 | break; | 3557 | break; |
3874 | case AUTO_SEQ_SURROUND: | 3558 | case AUTO_SEQ_SURROUND: |
3875 | spec->multiout.dac_nids[i] = 0x11; | 3559 | spec->private_dac_nids[i] = 0x11; |
3876 | break; | 3560 | break; |
3877 | case AUTO_SEQ_SIDE: | 3561 | case AUTO_SEQ_SIDE: |
3878 | spec->multiout.dac_nids[i] = 0x25; | 3562 | spec->private_dac_nids[i] = 0x25; |
3879 | break; | 3563 | break; |
3880 | } | 3564 | } |
3881 | } | 3565 | } |
@@ -3884,23 +3568,29 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, | |||
3884 | /* for Smart 5.1, line/mic inputs double as output pins */ | 3568 | /* for Smart 5.1, line/mic inputs double as output pins */ |
3885 | if (cfg->line_outs == 1) { | 3569 | if (cfg->line_outs == 1) { |
3886 | spec->multiout.num_dacs = 3; | 3570 | spec->multiout.num_dacs = 3; |
3887 | spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11; | 3571 | spec->private_dac_nids[AUTO_SEQ_SURROUND] = 0x11; |
3888 | spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24; | 3572 | if (spec->codec->vendor_id == 0x11064397) |
3573 | spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x25; | ||
3574 | else | ||
3575 | spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x24; | ||
3889 | } | 3576 | } |
3890 | 3577 | ||
3891 | return 0; | 3578 | return 0; |
3892 | } | 3579 | } |
3893 | 3580 | ||
3894 | /* add playback controls from the parsed DAC table */ | 3581 | /* add playback controls from the parsed DAC table */ |
3895 | static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, | 3582 | static int vt1708S_auto_create_multi_out_ctls(struct hda_codec *codec, |
3896 | const struct auto_pin_cfg *cfg) | 3583 | const struct auto_pin_cfg *cfg) |
3897 | { | 3584 | { |
3585 | struct via_spec *spec = codec->spec; | ||
3898 | char name[32]; | 3586 | char name[32]; |
3899 | static const char * const chname[4] = { | 3587 | static const char * const chname[4] = { |
3900 | "Front", "Surround", "C/LFE", "Side" | 3588 | "Front", "Surround", "C/LFE", "Side" |
3901 | }; | 3589 | }; |
3902 | hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25}; | 3590 | hda_nid_t nid_vols[2][4] = { {0x10, 0x11, 0x24, 0x25}, |
3903 | hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27}; | 3591 | {0x10, 0x11, 0x25, 0} }; |
3592 | hda_nid_t nid_mutes[2][4] = { {0x1C, 0x18, 0x26, 0x27}, | ||
3593 | {0x1C, 0x18, 0x27, 0} }; | ||
3904 | hda_nid_t nid, nid_vol, nid_mute; | 3594 | hda_nid_t nid, nid_vol, nid_mute; |
3905 | int i, err; | 3595 | int i, err; |
3906 | 3596 | ||
@@ -3911,8 +3601,15 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, | |||
3911 | if (!nid && i > AUTO_SEQ_CENLFE) | 3601 | if (!nid && i > AUTO_SEQ_CENLFE) |
3912 | continue; | 3602 | continue; |
3913 | 3603 | ||
3914 | nid_vol = nid_vols[i]; | 3604 | if (codec->vendor_id == 0x11064397) { |
3915 | nid_mute = nid_mutes[i]; | 3605 | nid_vol = nid_vols[1][i]; |
3606 | nid_mute = nid_mutes[1][i]; | ||
3607 | } else { | ||
3608 | nid_vol = nid_vols[0][i]; | ||
3609 | nid_mute = nid_mutes[0][i]; | ||
3610 | } | ||
3611 | if (!nid_vol && !nid_mute) | ||
3612 | continue; | ||
3916 | 3613 | ||
3917 | if (i == AUTO_SEQ_CENLFE) { | 3614 | if (i == AUTO_SEQ_CENLFE) { |
3918 | /* Center/LFE */ | 3615 | /* Center/LFE */ |
@@ -4022,7 +3719,7 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
4022 | static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec, | 3719 | static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec, |
4023 | const struct auto_pin_cfg *cfg) | 3720 | const struct auto_pin_cfg *cfg) |
4024 | { | 3721 | { |
4025 | static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff }; | 3722 | static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff }; |
4026 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, | 3723 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, |
4027 | ARRAY_SIZE(pin_idxs)); | 3724 | ARRAY_SIZE(pin_idxs)); |
4028 | } | 3725 | } |
@@ -4066,7 +3763,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) | |||
4066 | if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) | 3763 | if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) |
4067 | return 0; /* can't find valid BIOS pin config */ | 3764 | return 0; /* can't find valid BIOS pin config */ |
4068 | 3765 | ||
4069 | err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg); | 3766 | err = vt1708S_auto_create_multi_out_ctls(codec, &spec->autocfg); |
4070 | if (err < 0) | 3767 | if (err < 0) |
4071 | return err; | 3768 | return err; |
4072 | err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); | 3769 | err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); |
@@ -4093,7 +3790,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) | |||
4093 | } | 3790 | } |
4094 | 3791 | ||
4095 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3792 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4096 | static struct hda_amp_list vt1708S_loopbacks[] = { | 3793 | static const struct hda_amp_list vt1708S_loopbacks[] = { |
4097 | { 0x16, HDA_INPUT, 1 }, | 3794 | { 0x16, HDA_INPUT, 1 }, |
4098 | { 0x16, HDA_INPUT, 2 }, | 3795 | { 0x16, HDA_INPUT, 2 }, |
4099 | { 0x16, HDA_INPUT, 3 }, | 3796 | { 0x16, HDA_INPUT, 3 }, |
@@ -4133,17 +3830,29 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
4133 | } | 3830 | } |
4134 | 3831 | ||
4135 | spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; | 3832 | spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; |
4136 | spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs; | 3833 | if (codec->vendor_id == 0x11064397) |
3834 | spec->init_verbs[spec->num_iverbs++] = | ||
3835 | vt1705_uniwill_init_verbs; | ||
3836 | else | ||
3837 | spec->init_verbs[spec->num_iverbs++] = | ||
3838 | vt1708S_uniwill_init_verbs; | ||
4137 | 3839 | ||
4138 | if (codec->vendor_id == 0x11060440) | 3840 | if (codec->vendor_id == 0x11060440) |
4139 | spec->stream_name_analog = "VT1818S Analog"; | 3841 | spec->stream_name_analog = "VT1818S Analog"; |
3842 | else if (codec->vendor_id == 0x11064397) | ||
3843 | spec->stream_name_analog = "VT1705 Analog"; | ||
4140 | else | 3844 | else |
4141 | spec->stream_name_analog = "VT1708S Analog"; | 3845 | spec->stream_name_analog = "VT1708S Analog"; |
4142 | spec->stream_analog_playback = &vt1708S_pcm_analog_playback; | 3846 | if (codec->vendor_id == 0x11064397) |
3847 | spec->stream_analog_playback = &vt1705_pcm_analog_playback; | ||
3848 | else | ||
3849 | spec->stream_analog_playback = &vt1708S_pcm_analog_playback; | ||
4143 | spec->stream_analog_capture = &vt1708S_pcm_analog_capture; | 3850 | spec->stream_analog_capture = &vt1708S_pcm_analog_capture; |
4144 | 3851 | ||
4145 | if (codec->vendor_id == 0x11060440) | 3852 | if (codec->vendor_id == 0x11060440) |
4146 | spec->stream_name_digital = "VT1818S Digital"; | 3853 | spec->stream_name_digital = "VT1818S Digital"; |
3854 | else if (codec->vendor_id == 0x11064397) | ||
3855 | spec->stream_name_digital = "VT1705 Digital"; | ||
4147 | else | 3856 | else |
4148 | spec->stream_name_digital = "VT1708S Digital"; | 3857 | spec->stream_name_digital = "VT1708S Digital"; |
4149 | spec->stream_digital_playback = &vt1708S_pcm_digital_playback; | 3858 | spec->stream_digital_playback = &vt1708S_pcm_digital_playback; |
@@ -4181,13 +3890,22 @@ static int patch_vt1708S(struct hda_codec *codec) | |||
4181 | spec->stream_name_analog = "VT1818S Analog"; | 3890 | spec->stream_name_analog = "VT1818S Analog"; |
4182 | spec->stream_name_digital = "VT1818S Digital"; | 3891 | spec->stream_name_digital = "VT1818S Digital"; |
4183 | } | 3892 | } |
3893 | /* correct names for VT1705 */ | ||
3894 | if (codec->vendor_id == 0x11064397) { | ||
3895 | kfree(codec->chip_name); | ||
3896 | codec->chip_name = kstrdup("VT1705", GFP_KERNEL); | ||
3897 | snprintf(codec->bus->card->mixername, | ||
3898 | sizeof(codec->bus->card->mixername), | ||
3899 | "%s %s", codec->vendor_name, codec->chip_name); | ||
3900 | } | ||
3901 | spec->set_widgets_power_state = set_widgets_power_state_vt1708B; | ||
4184 | return 0; | 3902 | return 0; |
4185 | } | 3903 | } |
4186 | 3904 | ||
4187 | /* Patch for VT1702 */ | 3905 | /* Patch for VT1702 */ |
4188 | 3906 | ||
4189 | /* capture mixer elements */ | 3907 | /* capture mixer elements */ |
4190 | static struct snd_kcontrol_new vt1702_capture_mixer[] = { | 3908 | static const struct snd_kcontrol_new vt1702_capture_mixer[] = { |
4191 | HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT), | 3909 | HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT), |
4192 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT), | 3910 | HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT), |
4193 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT), | 3911 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT), |
@@ -4211,7 +3929,7 @@ static struct snd_kcontrol_new vt1702_capture_mixer[] = { | |||
4211 | { } /* end */ | 3929 | { } /* end */ |
4212 | }; | 3930 | }; |
4213 | 3931 | ||
4214 | static struct hda_verb vt1702_volume_init_verbs[] = { | 3932 | static const struct hda_verb vt1702_volume_init_verbs[] = { |
4215 | /* | 3933 | /* |
4216 | * Unmute ADC0-1 and set the default input to mic-in | 3934 | * Unmute ADC0-1 and set the default input to mic-in |
4217 | */ | 3935 | */ |
@@ -4242,7 +3960,7 @@ static struct hda_verb vt1702_volume_init_verbs[] = { | |||
4242 | { } | 3960 | { } |
4243 | }; | 3961 | }; |
4244 | 3962 | ||
4245 | static struct hda_verb vt1702_uniwill_init_verbs[] = { | 3963 | static const struct hda_verb vt1702_uniwill_init_verbs[] = { |
4246 | {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, | 3964 | {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, |
4247 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, | 3965 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, |
4248 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | 3966 | {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, |
@@ -4252,7 +3970,7 @@ static struct hda_verb vt1702_uniwill_init_verbs[] = { | |||
4252 | { } | 3970 | { } |
4253 | }; | 3971 | }; |
4254 | 3972 | ||
4255 | static struct hda_pcm_stream vt1702_pcm_analog_playback = { | 3973 | static const struct hda_pcm_stream vt1702_pcm_analog_playback = { |
4256 | .substreams = 2, | 3974 | .substreams = 2, |
4257 | .channels_min = 2, | 3975 | .channels_min = 2, |
4258 | .channels_max = 2, | 3976 | .channels_max = 2, |
@@ -4265,7 +3983,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_playback = { | |||
4265 | }, | 3983 | }, |
4266 | }; | 3984 | }; |
4267 | 3985 | ||
4268 | static struct hda_pcm_stream vt1702_pcm_analog_capture = { | 3986 | static const struct hda_pcm_stream vt1702_pcm_analog_capture = { |
4269 | .substreams = 3, | 3987 | .substreams = 3, |
4270 | .channels_min = 2, | 3988 | .channels_min = 2, |
4271 | .channels_max = 2, | 3989 | .channels_max = 2, |
@@ -4278,7 +3996,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_capture = { | |||
4278 | }, | 3996 | }, |
4279 | }; | 3997 | }; |
4280 | 3998 | ||
4281 | static struct hda_pcm_stream vt1702_pcm_digital_playback = { | 3999 | static const struct hda_pcm_stream vt1702_pcm_digital_playback = { |
4282 | .substreams = 2, | 4000 | .substreams = 2, |
4283 | .channels_min = 2, | 4001 | .channels_min = 2, |
4284 | .channels_max = 2, | 4002 | .channels_max = 2, |
@@ -4300,7 +4018,7 @@ static int vt1702_auto_fill_dac_nids(struct via_spec *spec, | |||
4300 | 4018 | ||
4301 | if (cfg->line_out_pins[0]) { | 4019 | if (cfg->line_out_pins[0]) { |
4302 | /* config dac list */ | 4020 | /* config dac list */ |
4303 | spec->multiout.dac_nids[0] = 0x10; | 4021 | spec->private_dac_nids[0] = 0x10; |
4304 | } | 4022 | } |
4305 | 4023 | ||
4306 | return 0; | 4024 | return 0; |
@@ -4378,7 +4096,7 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
4378 | static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec, | 4096 | static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec, |
4379 | const struct auto_pin_cfg *cfg) | 4097 | const struct auto_pin_cfg *cfg) |
4380 | { | 4098 | { |
4381 | static hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff }; | 4099 | static const hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff }; |
4382 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs, | 4100 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs, |
4383 | ARRAY_SIZE(pin_idxs)); | 4101 | ARRAY_SIZE(pin_idxs)); |
4384 | } | 4102 | } |
@@ -4429,7 +4147,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) | |||
4429 | } | 4147 | } |
4430 | 4148 | ||
4431 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4149 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4432 | static struct hda_amp_list vt1702_loopbacks[] = { | 4150 | static const struct hda_amp_list vt1702_loopbacks[] = { |
4433 | { 0x1A, HDA_INPUT, 1 }, | 4151 | { 0x1A, HDA_INPUT, 1 }, |
4434 | { 0x1A, HDA_INPUT, 2 }, | 4152 | { 0x1A, HDA_INPUT, 2 }, |
4435 | { 0x1A, HDA_INPUT, 3 }, | 4153 | { 0x1A, HDA_INPUT, 3 }, |
@@ -4438,6 +4156,37 @@ static struct hda_amp_list vt1702_loopbacks[] = { | |||
4438 | }; | 4156 | }; |
4439 | #endif | 4157 | #endif |
4440 | 4158 | ||
4159 | static void set_widgets_power_state_vt1702(struct hda_codec *codec) | ||
4160 | { | ||
4161 | int imux_is_smixer = | ||
4162 | snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; | ||
4163 | unsigned int parm; | ||
4164 | /* inputs */ | ||
4165 | /* PW 1/2/5 (14h/15h/18h) */ | ||
4166 | parm = AC_PWRST_D3; | ||
4167 | set_pin_power_state(codec, 0x14, &parm); | ||
4168 | set_pin_power_state(codec, 0x15, &parm); | ||
4169 | set_pin_power_state(codec, 0x18, &parm); | ||
4170 | if (imux_is_smixer) | ||
4171 | parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */ | ||
4172 | /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ | ||
4173 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4174 | snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4175 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4176 | snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4177 | |||
4178 | /* outputs */ | ||
4179 | /* PW 3/4 (16h/17h) */ | ||
4180 | parm = AC_PWRST_D3; | ||
4181 | set_pin_power_state(codec, 0x17, &parm); | ||
4182 | set_pin_power_state(codec, 0x16, &parm); | ||
4183 | /* MW0 (1ah), AOW 0/1 (10h/1dh) */ | ||
4184 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, | ||
4185 | imux_is_smixer ? AC_PWRST_D0 : parm); | ||
4186 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4187 | snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4188 | } | ||
4189 | |||
4441 | static int patch_vt1702(struct hda_codec *codec) | 4190 | static int patch_vt1702(struct hda_codec *codec) |
4442 | { | 4191 | { |
4443 | struct via_spec *spec; | 4192 | struct via_spec *spec; |
@@ -4484,13 +4233,14 @@ static int patch_vt1702(struct hda_codec *codec) | |||
4484 | spec->loopback.amplist = vt1702_loopbacks; | 4233 | spec->loopback.amplist = vt1702_loopbacks; |
4485 | #endif | 4234 | #endif |
4486 | 4235 | ||
4236 | spec->set_widgets_power_state = set_widgets_power_state_vt1702; | ||
4487 | return 0; | 4237 | return 0; |
4488 | } | 4238 | } |
4489 | 4239 | ||
4490 | /* Patch for VT1718S */ | 4240 | /* Patch for VT1718S */ |
4491 | 4241 | ||
4492 | /* capture mixer elements */ | 4242 | /* capture mixer elements */ |
4493 | static struct snd_kcontrol_new vt1718S_capture_mixer[] = { | 4243 | static const struct snd_kcontrol_new vt1718S_capture_mixer[] = { |
4494 | HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), | 4244 | HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), |
4495 | HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), | 4245 | HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), |
4496 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), | 4246 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), |
@@ -4512,14 +4262,15 @@ static struct snd_kcontrol_new vt1718S_capture_mixer[] = { | |||
4512 | { } /* end */ | 4262 | { } /* end */ |
4513 | }; | 4263 | }; |
4514 | 4264 | ||
4515 | static struct hda_verb vt1718S_volume_init_verbs[] = { | 4265 | static const struct hda_verb vt1718S_volume_init_verbs[] = { |
4516 | /* | 4266 | /* |
4517 | * Unmute ADC0-1 and set the default input to mic-in | 4267 | * Unmute ADC0-1 and set the default input to mic-in |
4518 | */ | 4268 | */ |
4519 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 4269 | {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
4520 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | 4270 | {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, |
4521 | 4271 | ||
4522 | 4272 | /* Enable MW0 adjust Gain 5 */ | |
4273 | {0x1, 0xfb2, 0x10}, | ||
4523 | /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | 4274 | /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback |
4524 | * mixer widget | 4275 | * mixer widget |
4525 | */ | 4276 | */ |
@@ -4528,7 +4279,7 @@ static struct hda_verb vt1718S_volume_init_verbs[] = { | |||
4528 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | 4279 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, |
4529 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | 4280 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, |
4530 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | 4281 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, |
4531 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, | 4282 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, |
4532 | 4283 | ||
4533 | /* Setup default input of Front HP to MW9 */ | 4284 | /* Setup default input of Front HP to MW9 */ |
4534 | {0x28, AC_VERB_SET_CONNECT_SEL, 0x1}, | 4285 | {0x28, AC_VERB_SET_CONNECT_SEL, 0x1}, |
@@ -4559,7 +4310,7 @@ static struct hda_verb vt1718S_volume_init_verbs[] = { | |||
4559 | }; | 4310 | }; |
4560 | 4311 | ||
4561 | 4312 | ||
4562 | static struct hda_verb vt1718S_uniwill_init_verbs[] = { | 4313 | static const struct hda_verb vt1718S_uniwill_init_verbs[] = { |
4563 | {0x28, AC_VERB_SET_UNSOLICITED_ENABLE, | 4314 | {0x28, AC_VERB_SET_UNSOLICITED_ENABLE, |
4564 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, | 4315 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, |
4565 | {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | 4316 | {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, |
@@ -4572,7 +4323,7 @@ static struct hda_verb vt1718S_uniwill_init_verbs[] = { | |||
4572 | { } | 4323 | { } |
4573 | }; | 4324 | }; |
4574 | 4325 | ||
4575 | static struct hda_pcm_stream vt1718S_pcm_analog_playback = { | 4326 | static const struct hda_pcm_stream vt1718S_pcm_analog_playback = { |
4576 | .substreams = 2, | 4327 | .substreams = 2, |
4577 | .channels_min = 2, | 4328 | .channels_min = 2, |
4578 | .channels_max = 10, | 4329 | .channels_max = 10, |
@@ -4585,7 +4336,7 @@ static struct hda_pcm_stream vt1718S_pcm_analog_playback = { | |||
4585 | }, | 4336 | }, |
4586 | }; | 4337 | }; |
4587 | 4338 | ||
4588 | static struct hda_pcm_stream vt1718S_pcm_analog_capture = { | 4339 | static const struct hda_pcm_stream vt1718S_pcm_analog_capture = { |
4589 | .substreams = 2, | 4340 | .substreams = 2, |
4590 | .channels_min = 2, | 4341 | .channels_min = 2, |
4591 | .channels_max = 2, | 4342 | .channels_max = 2, |
@@ -4598,7 +4349,7 @@ static struct hda_pcm_stream vt1718S_pcm_analog_capture = { | |||
4598 | }, | 4349 | }, |
4599 | }; | 4350 | }; |
4600 | 4351 | ||
4601 | static struct hda_pcm_stream vt1718S_pcm_digital_playback = { | 4352 | static const struct hda_pcm_stream vt1718S_pcm_digital_playback = { |
4602 | .substreams = 2, | 4353 | .substreams = 2, |
4603 | .channels_min = 2, | 4354 | .channels_min = 2, |
4604 | .channels_max = 2, | 4355 | .channels_max = 2, |
@@ -4611,7 +4362,7 @@ static struct hda_pcm_stream vt1718S_pcm_digital_playback = { | |||
4611 | }, | 4362 | }, |
4612 | }; | 4363 | }; |
4613 | 4364 | ||
4614 | static struct hda_pcm_stream vt1718S_pcm_digital_capture = { | 4365 | static const struct hda_pcm_stream vt1718S_pcm_digital_capture = { |
4615 | .substreams = 1, | 4366 | .substreams = 1, |
4616 | .channels_min = 2, | 4367 | .channels_min = 2, |
4617 | .channels_max = 2, | 4368 | .channels_max = 2, |
@@ -4634,16 +4385,16 @@ static int vt1718S_auto_fill_dac_nids(struct via_spec *spec, | |||
4634 | /* config dac list */ | 4385 | /* config dac list */ |
4635 | switch (i) { | 4386 | switch (i) { |
4636 | case AUTO_SEQ_FRONT: | 4387 | case AUTO_SEQ_FRONT: |
4637 | spec->multiout.dac_nids[i] = 0x8; | 4388 | spec->private_dac_nids[i] = 0x8; |
4638 | break; | 4389 | break; |
4639 | case AUTO_SEQ_CENLFE: | 4390 | case AUTO_SEQ_CENLFE: |
4640 | spec->multiout.dac_nids[i] = 0xa; | 4391 | spec->private_dac_nids[i] = 0xa; |
4641 | break; | 4392 | break; |
4642 | case AUTO_SEQ_SURROUND: | 4393 | case AUTO_SEQ_SURROUND: |
4643 | spec->multiout.dac_nids[i] = 0x9; | 4394 | spec->private_dac_nids[i] = 0x9; |
4644 | break; | 4395 | break; |
4645 | case AUTO_SEQ_SIDE: | 4396 | case AUTO_SEQ_SIDE: |
4646 | spec->multiout.dac_nids[i] = 0xb; | 4397 | spec->private_dac_nids[i] = 0xb; |
4647 | break; | 4398 | break; |
4648 | } | 4399 | } |
4649 | } | 4400 | } |
@@ -4765,7 +4516,7 @@ static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
4765 | static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec, | 4516 | static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec, |
4766 | const struct auto_pin_cfg *cfg) | 4517 | const struct auto_pin_cfg *cfg) |
4767 | { | 4518 | { |
4768 | static hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff }; | 4519 | static const hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff }; |
4769 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, | 4520 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, |
4770 | ARRAY_SIZE(pin_idxs)); | 4521 | ARRAY_SIZE(pin_idxs)); |
4771 | } | 4522 | } |
@@ -4816,7 +4567,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec) | |||
4816 | } | 4567 | } |
4817 | 4568 | ||
4818 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 4569 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
4819 | static struct hda_amp_list vt1718S_loopbacks[] = { | 4570 | static const struct hda_amp_list vt1718S_loopbacks[] = { |
4820 | { 0x21, HDA_INPUT, 1 }, | 4571 | { 0x21, HDA_INPUT, 1 }, |
4821 | { 0x21, HDA_INPUT, 2 }, | 4572 | { 0x21, HDA_INPUT, 2 }, |
4822 | { 0x21, HDA_INPUT, 3 }, | 4573 | { 0x21, HDA_INPUT, 3 }, |
@@ -4825,6 +4576,72 @@ static struct hda_amp_list vt1718S_loopbacks[] = { | |||
4825 | }; | 4576 | }; |
4826 | #endif | 4577 | #endif |
4827 | 4578 | ||
4579 | static void set_widgets_power_state_vt1718S(struct hda_codec *codec) | ||
4580 | { | ||
4581 | struct via_spec *spec = codec->spec; | ||
4582 | int imux_is_smixer; | ||
4583 | unsigned int parm; | ||
4584 | /* MUX6 (1eh) = stereo mixer */ | ||
4585 | imux_is_smixer = | ||
4586 | snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; | ||
4587 | /* inputs */ | ||
4588 | /* PW 5/6/7 (29h/2ah/2bh) */ | ||
4589 | parm = AC_PWRST_D3; | ||
4590 | set_pin_power_state(codec, 0x29, &parm); | ||
4591 | set_pin_power_state(codec, 0x2a, &parm); | ||
4592 | set_pin_power_state(codec, 0x2b, &parm); | ||
4593 | if (imux_is_smixer) | ||
4594 | parm = AC_PWRST_D0; | ||
4595 | /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ | ||
4596 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4597 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4598 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4599 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4600 | |||
4601 | /* outputs */ | ||
4602 | /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ | ||
4603 | parm = AC_PWRST_D3; | ||
4604 | set_pin_power_state(codec, 0x27, &parm); | ||
4605 | snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4606 | snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4607 | |||
4608 | /* PW2 (26h), AOW2 (ah) */ | ||
4609 | parm = AC_PWRST_D3; | ||
4610 | set_pin_power_state(codec, 0x26, &parm); | ||
4611 | if (spec->smart51_enabled) | ||
4612 | set_pin_power_state(codec, 0x2b, &parm); | ||
4613 | snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4614 | |||
4615 | /* PW0 (24h), AOW0 (8h) */ | ||
4616 | parm = AC_PWRST_D3; | ||
4617 | set_pin_power_state(codec, 0x24, &parm); | ||
4618 | if (!spec->hp_independent_mode) /* check for redirected HP */ | ||
4619 | set_pin_power_state(codec, 0x28, &parm); | ||
4620 | snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4621 | /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ | ||
4622 | snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, | ||
4623 | imux_is_smixer ? AC_PWRST_D0 : parm); | ||
4624 | |||
4625 | /* PW1 (25h), AOW1 (9h) */ | ||
4626 | parm = AC_PWRST_D3; | ||
4627 | set_pin_power_state(codec, 0x25, &parm); | ||
4628 | if (spec->smart51_enabled) | ||
4629 | set_pin_power_state(codec, 0x2a, &parm); | ||
4630 | snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm); | ||
4631 | |||
4632 | if (spec->hp_independent_mode) { | ||
4633 | /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ | ||
4634 | parm = AC_PWRST_D3; | ||
4635 | set_pin_power_state(codec, 0x28, &parm); | ||
4636 | snd_hda_codec_write(codec, 0x1b, 0, | ||
4637 | AC_VERB_SET_POWER_STATE, parm); | ||
4638 | snd_hda_codec_write(codec, 0x34, 0, | ||
4639 | AC_VERB_SET_POWER_STATE, parm); | ||
4640 | snd_hda_codec_write(codec, 0xc, 0, | ||
4641 | AC_VERB_SET_POWER_STATE, parm); | ||
4642 | } | ||
4643 | } | ||
4644 | |||
4828 | static int patch_vt1718S(struct hda_codec *codec) | 4645 | static int patch_vt1718S(struct hda_codec *codec) |
4829 | { | 4646 | { |
4830 | struct via_spec *spec; | 4647 | struct via_spec *spec; |
@@ -4886,6 +4703,8 @@ static int patch_vt1718S(struct hda_codec *codec) | |||
4886 | spec->loopback.amplist = vt1718S_loopbacks; | 4703 | spec->loopback.amplist = vt1718S_loopbacks; |
4887 | #endif | 4704 | #endif |
4888 | 4705 | ||
4706 | spec->set_widgets_power_state = set_widgets_power_state_vt1718S; | ||
4707 | |||
4889 | return 0; | 4708 | return 0; |
4890 | } | 4709 | } |
4891 | 4710 | ||
@@ -4925,13 +4744,12 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol, | |||
4925 | snd_hda_codec_write(codec, 0x26, 0, | 4744 | snd_hda_codec_write(codec, 0x26, 0, |
4926 | AC_VERB_SET_CONNECT_SEL, index); | 4745 | AC_VERB_SET_CONNECT_SEL, index); |
4927 | spec->dmic_enabled = index; | 4746 | spec->dmic_enabled = index; |
4928 | set_jack_power_state(codec); | 4747 | set_widgets_power_state(codec); |
4929 | |||
4930 | return 1; | 4748 | return 1; |
4931 | } | 4749 | } |
4932 | 4750 | ||
4933 | /* capture mixer elements */ | 4751 | /* capture mixer elements */ |
4934 | static struct snd_kcontrol_new vt1716S_capture_mixer[] = { | 4752 | static const struct snd_kcontrol_new vt1716S_capture_mixer[] = { |
4935 | HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), | 4753 | HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), |
4936 | HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), | 4754 | HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), |
4937 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), | 4755 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), |
@@ -4950,7 +4768,7 @@ static struct snd_kcontrol_new vt1716S_capture_mixer[] = { | |||
4950 | { } /* end */ | 4768 | { } /* end */ |
4951 | }; | 4769 | }; |
4952 | 4770 | ||
4953 | static struct snd_kcontrol_new vt1716s_dmic_mixer[] = { | 4771 | static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = { |
4954 | HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT), | 4772 | HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT), |
4955 | { | 4773 | { |
4956 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 4774 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -4966,12 +4784,12 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = { | |||
4966 | 4784 | ||
4967 | 4785 | ||
4968 | /* mono-out mixer elements */ | 4786 | /* mono-out mixer elements */ |
4969 | static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = { | 4787 | static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = { |
4970 | HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT), | 4788 | HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT), |
4971 | { } /* end */ | 4789 | { } /* end */ |
4972 | }; | 4790 | }; |
4973 | 4791 | ||
4974 | static struct hda_verb vt1716S_volume_init_verbs[] = { | 4792 | static const struct hda_verb vt1716S_volume_init_verbs[] = { |
4975 | /* | 4793 | /* |
4976 | * Unmute ADC0-1 and set the default input to mic-in | 4794 | * Unmute ADC0-1 and set the default input to mic-in |
4977 | */ | 4795 | */ |
@@ -5020,7 +4838,7 @@ static struct hda_verb vt1716S_volume_init_verbs[] = { | |||
5020 | }; | 4838 | }; |
5021 | 4839 | ||
5022 | 4840 | ||
5023 | static struct hda_verb vt1716S_uniwill_init_verbs[] = { | 4841 | static const struct hda_verb vt1716S_uniwill_init_verbs[] = { |
5024 | {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, | 4842 | {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, |
5025 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, | 4843 | AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, |
5026 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | 4844 | {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, |
@@ -5033,7 +4851,7 @@ static struct hda_verb vt1716S_uniwill_init_verbs[] = { | |||
5033 | { } | 4851 | { } |
5034 | }; | 4852 | }; |
5035 | 4853 | ||
5036 | static struct hda_pcm_stream vt1716S_pcm_analog_playback = { | 4854 | static const struct hda_pcm_stream vt1716S_pcm_analog_playback = { |
5037 | .substreams = 2, | 4855 | .substreams = 2, |
5038 | .channels_min = 2, | 4856 | .channels_min = 2, |
5039 | .channels_max = 6, | 4857 | .channels_max = 6, |
@@ -5046,7 +4864,7 @@ static struct hda_pcm_stream vt1716S_pcm_analog_playback = { | |||
5046 | }, | 4864 | }, |
5047 | }; | 4865 | }; |
5048 | 4866 | ||
5049 | static struct hda_pcm_stream vt1716S_pcm_analog_capture = { | 4867 | static const struct hda_pcm_stream vt1716S_pcm_analog_capture = { |
5050 | .substreams = 2, | 4868 | .substreams = 2, |
5051 | .channels_min = 2, | 4869 | .channels_min = 2, |
5052 | .channels_max = 2, | 4870 | .channels_max = 2, |
@@ -5059,7 +4877,7 @@ static struct hda_pcm_stream vt1716S_pcm_analog_capture = { | |||
5059 | }, | 4877 | }, |
5060 | }; | 4878 | }; |
5061 | 4879 | ||
5062 | static struct hda_pcm_stream vt1716S_pcm_digital_playback = { | 4880 | static const struct hda_pcm_stream vt1716S_pcm_digital_playback = { |
5063 | .substreams = 2, | 4881 | .substreams = 2, |
5064 | .channels_min = 2, | 4882 | .channels_min = 2, |
5065 | .channels_max = 2, | 4883 | .channels_max = 2, |
@@ -5088,13 +4906,13 @@ static int vt1716S_auto_fill_dac_nids(struct via_spec *spec, | |||
5088 | /* config dac list */ | 4906 | /* config dac list */ |
5089 | switch (i) { | 4907 | switch (i) { |
5090 | case AUTO_SEQ_FRONT: | 4908 | case AUTO_SEQ_FRONT: |
5091 | spec->multiout.dac_nids[i] = 0x10; | 4909 | spec->private_dac_nids[i] = 0x10; |
5092 | break; | 4910 | break; |
5093 | case AUTO_SEQ_CENLFE: | 4911 | case AUTO_SEQ_CENLFE: |
5094 | spec->multiout.dac_nids[i] = 0x25; | 4912 | spec->private_dac_nids[i] = 0x25; |
5095 | break; | 4913 | break; |
5096 | case AUTO_SEQ_SURROUND: | 4914 | case AUTO_SEQ_SURROUND: |
5097 | spec->multiout.dac_nids[i] = 0x11; | 4915 | spec->private_dac_nids[i] = 0x11; |
5098 | break; | 4916 | break; |
5099 | } | 4917 | } |
5100 | } | 4918 | } |
@@ -5229,7 +5047,7 @@ static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) | |||
5229 | static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec, | 5047 | static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec, |
5230 | const struct auto_pin_cfg *cfg) | 5048 | const struct auto_pin_cfg *cfg) |
5231 | { | 5049 | { |
5232 | static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff }; | 5050 | static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff }; |
5233 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, | 5051 | return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, |
5234 | ARRAY_SIZE(pin_idxs)); | 5052 | ARRAY_SIZE(pin_idxs)); |
5235 | } | 5053 | } |
@@ -5276,7 +5094,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec) | |||
5276 | } | 5094 | } |
5277 | 5095 | ||
5278 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5096 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5279 | static struct hda_amp_list vt1716S_loopbacks[] = { | 5097 | static const struct hda_amp_list vt1716S_loopbacks[] = { |
5280 | { 0x16, HDA_INPUT, 1 }, | 5098 | { 0x16, HDA_INPUT, 1 }, |
5281 | { 0x16, HDA_INPUT, 2 }, | 5099 | { 0x16, HDA_INPUT, 2 }, |
5282 | { 0x16, HDA_INPUT, 3 }, | 5100 | { 0x16, HDA_INPUT, 3 }, |
@@ -5285,6 +5103,99 @@ static struct hda_amp_list vt1716S_loopbacks[] = { | |||
5285 | }; | 5103 | }; |
5286 | #endif | 5104 | #endif |
5287 | 5105 | ||
5106 | static void set_widgets_power_state_vt1716S(struct hda_codec *codec) | ||
5107 | { | ||
5108 | struct via_spec *spec = codec->spec; | ||
5109 | int imux_is_smixer; | ||
5110 | unsigned int parm; | ||
5111 | unsigned int mono_out, present; | ||
5112 | /* SW0 (17h) = stereo mixer */ | ||
5113 | imux_is_smixer = | ||
5114 | (snd_hda_codec_read(codec, 0x17, 0, | ||
5115 | AC_VERB_GET_CONNECT_SEL, 0x00) == 5); | ||
5116 | /* inputs */ | ||
5117 | /* PW 1/2/5 (1ah/1bh/1eh) */ | ||
5118 | parm = AC_PWRST_D3; | ||
5119 | set_pin_power_state(codec, 0x1a, &parm); | ||
5120 | set_pin_power_state(codec, 0x1b, &parm); | ||
5121 | set_pin_power_state(codec, 0x1e, &parm); | ||
5122 | if (imux_is_smixer) | ||
5123 | parm = AC_PWRST_D0; | ||
5124 | /* SW0 (17h), AIW0(13h) */ | ||
5125 | snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5126 | snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5127 | |||
5128 | parm = AC_PWRST_D3; | ||
5129 | set_pin_power_state(codec, 0x1e, &parm); | ||
5130 | /* PW11 (22h) */ | ||
5131 | if (spec->dmic_enabled) | ||
5132 | set_pin_power_state(codec, 0x22, &parm); | ||
5133 | else | ||
5134 | snd_hda_codec_write(codec, 0x22, 0, | ||
5135 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
5136 | |||
5137 | /* SW2(26h), AIW1(14h) */ | ||
5138 | snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5139 | snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5140 | |||
5141 | /* outputs */ | ||
5142 | /* PW0 (19h), SW1 (18h), AOW1 (11h) */ | ||
5143 | parm = AC_PWRST_D3; | ||
5144 | set_pin_power_state(codec, 0x19, &parm); | ||
5145 | /* Smart 5.1 PW2(1bh) */ | ||
5146 | if (spec->smart51_enabled) | ||
5147 | set_pin_power_state(codec, 0x1b, &parm); | ||
5148 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5149 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5150 | |||
5151 | /* PW7 (23h), SW3 (27h), AOW3 (25h) */ | ||
5152 | parm = AC_PWRST_D3; | ||
5153 | set_pin_power_state(codec, 0x23, &parm); | ||
5154 | /* Smart 5.1 PW1(1ah) */ | ||
5155 | if (spec->smart51_enabled) | ||
5156 | set_pin_power_state(codec, 0x1a, &parm); | ||
5157 | snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5158 | |||
5159 | /* Smart 5.1 PW5(1eh) */ | ||
5160 | if (spec->smart51_enabled) | ||
5161 | set_pin_power_state(codec, 0x1e, &parm); | ||
5162 | snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5163 | |||
5164 | /* Mono out */ | ||
5165 | /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ | ||
5166 | present = snd_hda_jack_detect(codec, 0x1c); | ||
5167 | |||
5168 | if (present) | ||
5169 | mono_out = 0; | ||
5170 | else { | ||
5171 | present = snd_hda_jack_detect(codec, 0x1d); | ||
5172 | if (!spec->hp_independent_mode && present) | ||
5173 | mono_out = 0; | ||
5174 | else | ||
5175 | mono_out = 1; | ||
5176 | } | ||
5177 | parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; | ||
5178 | snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5179 | snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5180 | snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5181 | |||
5182 | /* PW 3/4 (1ch/1dh) */ | ||
5183 | parm = AC_PWRST_D3; | ||
5184 | set_pin_power_state(codec, 0x1c, &parm); | ||
5185 | set_pin_power_state(codec, 0x1d, &parm); | ||
5186 | /* HP Independent Mode, power on AOW3 */ | ||
5187 | if (spec->hp_independent_mode) | ||
5188 | snd_hda_codec_write(codec, 0x25, 0, | ||
5189 | AC_VERB_SET_POWER_STATE, parm); | ||
5190 | |||
5191 | /* force to D0 for internal Speaker */ | ||
5192 | /* MW0 (16h), AOW0 (10h) */ | ||
5193 | snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, | ||
5194 | imux_is_smixer ? AC_PWRST_D0 : parm); | ||
5195 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, | ||
5196 | mono_out ? AC_PWRST_D0 : parm); | ||
5197 | } | ||
5198 | |||
5288 | static int patch_vt1716S(struct hda_codec *codec) | 5199 | static int patch_vt1716S(struct hda_codec *codec) |
5289 | { | 5200 | { |
5290 | struct via_spec *spec; | 5201 | struct via_spec *spec; |
@@ -5339,13 +5250,14 @@ static int patch_vt1716S(struct hda_codec *codec) | |||
5339 | spec->loopback.amplist = vt1716S_loopbacks; | 5250 | spec->loopback.amplist = vt1716S_loopbacks; |
5340 | #endif | 5251 | #endif |
5341 | 5252 | ||
5253 | spec->set_widgets_power_state = set_widgets_power_state_vt1716S; | ||
5342 | return 0; | 5254 | return 0; |
5343 | } | 5255 | } |
5344 | 5256 | ||
5345 | /* for vt2002P */ | 5257 | /* for vt2002P */ |
5346 | 5258 | ||
5347 | /* capture mixer elements */ | 5259 | /* capture mixer elements */ |
5348 | static struct snd_kcontrol_new vt2002P_capture_mixer[] = { | 5260 | static const struct snd_kcontrol_new vt2002P_capture_mixer[] = { |
5349 | HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), | 5261 | HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), |
5350 | HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), | 5262 | HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), |
5351 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), | 5263 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), |
@@ -5368,7 +5280,11 @@ static struct snd_kcontrol_new vt2002P_capture_mixer[] = { | |||
5368 | { } /* end */ | 5280 | { } /* end */ |
5369 | }; | 5281 | }; |
5370 | 5282 | ||
5371 | static struct hda_verb vt2002P_volume_init_verbs[] = { | 5283 | static const struct hda_verb vt2002P_volume_init_verbs[] = { |
5284 | /* Class-D speaker related verbs */ | ||
5285 | {0x1, 0xfe0, 0x4}, | ||
5286 | {0x1, 0xfe9, 0x80}, | ||
5287 | {0x1, 0xfe2, 0x22}, | ||
5372 | /* | 5288 | /* |
5373 | * Unmute ADC0-1 and set the default input to mic-in | 5289 | * Unmute ADC0-1 and set the default input to mic-in |
5374 | */ | 5290 | */ |
@@ -5419,9 +5335,60 @@ static struct hda_verb vt2002P_volume_init_verbs[] = { | |||
5419 | {0x1, 0xfb8, 0x88}, | 5335 | {0x1, 0xfb8, 0x88}, |
5420 | { } | 5336 | { } |
5421 | }; | 5337 | }; |
5338 | static const struct hda_verb vt1802_volume_init_verbs[] = { | ||
5339 | /* | ||
5340 | * Unmute ADC0-1 and set the default input to mic-in | ||
5341 | */ | ||
5342 | {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5343 | {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5344 | |||
5345 | |||
5346 | /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback | ||
5347 | * mixer widget | ||
5348 | */ | ||
5349 | /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ | ||
5350 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, | ||
5351 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, | ||
5352 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, | ||
5353 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, | ||
5354 | {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, | ||
5355 | |||
5356 | /* MUX Indices: Mic = 0 */ | ||
5357 | {0x1e, AC_VERB_SET_CONNECT_SEL, 0}, | ||
5358 | {0x1f, AC_VERB_SET_CONNECT_SEL, 0}, | ||
5359 | |||
5360 | /* PW9 Output enable */ | ||
5361 | {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, | ||
5422 | 5362 | ||
5363 | /* Enable Boost Volume backdoor */ | ||
5364 | {0x1, 0xfb9, 0x24}, | ||
5365 | |||
5366 | /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */ | ||
5367 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5368 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5369 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5370 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, | ||
5371 | {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5372 | {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5373 | {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5374 | {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, | ||
5423 | 5375 | ||
5424 | static struct hda_verb vt2002P_uniwill_init_verbs[] = { | 5376 | /* set MUX0/1/4/8 = 0 (AOW0) */ |
5377 | {0x34, AC_VERB_SET_CONNECT_SEL, 0}, | ||
5378 | {0x35, AC_VERB_SET_CONNECT_SEL, 0}, | ||
5379 | {0x38, AC_VERB_SET_CONNECT_SEL, 0}, | ||
5380 | {0x3c, AC_VERB_SET_CONNECT_SEL, 0}, | ||
5381 | |||
5382 | /* set PW0 index=0 (MW0) */ | ||
5383 | {0x24, AC_VERB_SET_CONNECT_SEL, 0}, | ||
5384 | |||
5385 | /* Enable AOW0 to MW9 */ | ||
5386 | {0x1, 0xfb8, 0x88}, | ||
5387 | { } | ||
5388 | }; | ||
5389 | |||
5390 | |||
5391 | static const struct hda_verb vt2002P_uniwill_init_verbs[] = { | ||
5425 | {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, | 5392 | {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, |
5426 | AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, | 5393 | AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, |
5427 | {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, | 5394 | {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, |
@@ -5431,8 +5398,18 @@ static struct hda_verb vt2002P_uniwill_init_verbs[] = { | |||
5431 | {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | 5398 | {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, |
5432 | { } | 5399 | { } |
5433 | }; | 5400 | }; |
5401 | static const struct hda_verb vt1802_uniwill_init_verbs[] = { | ||
5402 | {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, | ||
5403 | AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, | ||
5404 | {0x28, AC_VERB_SET_UNSOLICITED_ENABLE, | ||
5405 | AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, | ||
5406 | {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | ||
5407 | {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | ||
5408 | {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, | ||
5409 | { } | ||
5410 | }; | ||
5434 | 5411 | ||
5435 | static struct hda_pcm_stream vt2002P_pcm_analog_playback = { | 5412 | static const struct hda_pcm_stream vt2002P_pcm_analog_playback = { |
5436 | .substreams = 2, | 5413 | .substreams = 2, |
5437 | .channels_min = 2, | 5414 | .channels_min = 2, |
5438 | .channels_max = 2, | 5415 | .channels_max = 2, |
@@ -5445,7 +5422,7 @@ static struct hda_pcm_stream vt2002P_pcm_analog_playback = { | |||
5445 | }, | 5422 | }, |
5446 | }; | 5423 | }; |
5447 | 5424 | ||
5448 | static struct hda_pcm_stream vt2002P_pcm_analog_capture = { | 5425 | static const struct hda_pcm_stream vt2002P_pcm_analog_capture = { |
5449 | .substreams = 2, | 5426 | .substreams = 2, |
5450 | .channels_min = 2, | 5427 | .channels_min = 2, |
5451 | .channels_max = 2, | 5428 | .channels_max = 2, |
@@ -5458,7 +5435,7 @@ static struct hda_pcm_stream vt2002P_pcm_analog_capture = { | |||
5458 | }, | 5435 | }, |
5459 | }; | 5436 | }; |
5460 | 5437 | ||
5461 | static struct hda_pcm_stream vt2002P_pcm_digital_playback = { | 5438 | static const struct hda_pcm_stream vt2002P_pcm_digital_playback = { |
5462 | .substreams = 1, | 5439 | .substreams = 1, |
5463 | .channels_min = 2, | 5440 | .channels_min = 2, |
5464 | .channels_max = 2, | 5441 | .channels_max = 2, |
@@ -5478,7 +5455,7 @@ static int vt2002P_auto_fill_dac_nids(struct via_spec *spec, | |||
5478 | spec->multiout.num_dacs = 1; | 5455 | spec->multiout.num_dacs = 1; |
5479 | spec->multiout.dac_nids = spec->private_dac_nids; | 5456 | spec->multiout.dac_nids = spec->private_dac_nids; |
5480 | if (cfg->line_out_pins[0]) | 5457 | if (cfg->line_out_pins[0]) |
5481 | spec->multiout.dac_nids[0] = 0x8; | 5458 | spec->private_dac_nids[0] = 0x8; |
5482 | return 0; | 5459 | return 0; |
5483 | } | 5460 | } |
5484 | 5461 | ||
@@ -5487,10 +5464,15 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec, | |||
5487 | const struct auto_pin_cfg *cfg) | 5464 | const struct auto_pin_cfg *cfg) |
5488 | { | 5465 | { |
5489 | int err; | 5466 | int err; |
5467 | hda_nid_t sw_nid; | ||
5490 | 5468 | ||
5491 | if (!cfg->line_out_pins[0]) | 5469 | if (!cfg->line_out_pins[0]) |
5492 | return -1; | 5470 | return -1; |
5493 | 5471 | ||
5472 | if (spec->codec_type == VT1802) | ||
5473 | sw_nid = 0x28; | ||
5474 | else | ||
5475 | sw_nid = 0x26; | ||
5494 | 5476 | ||
5495 | /* Line-Out: PortE */ | 5477 | /* Line-Out: PortE */ |
5496 | err = via_add_control(spec, VIA_CTL_WIDGET_VOL, | 5478 | err = via_add_control(spec, VIA_CTL_WIDGET_VOL, |
@@ -5500,7 +5482,7 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec, | |||
5500 | return err; | 5482 | return err; |
5501 | err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, | 5483 | err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, |
5502 | "Master Front Playback Switch", | 5484 | "Master Front Playback Switch", |
5503 | HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT)); | 5485 | HDA_COMPOSE_AMP_VAL(sw_nid, 3, 0, HDA_OUTPUT)); |
5504 | if (err < 0) | 5486 | if (err < 0) |
5505 | return err; | 5487 | return err; |
5506 | 5488 | ||
@@ -5540,7 +5522,7 @@ static int vt2002P_auto_create_analog_input_ctls(struct hda_codec *codec, | |||
5540 | { | 5522 | { |
5541 | struct via_spec *spec = codec->spec; | 5523 | struct via_spec *spec = codec->spec; |
5542 | struct hda_input_mux *imux = &spec->private_imux[0]; | 5524 | struct hda_input_mux *imux = &spec->private_imux[0]; |
5543 | static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff }; | 5525 | static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff }; |
5544 | int err; | 5526 | int err; |
5545 | 5527 | ||
5546 | err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, | 5528 | err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, |
@@ -5601,7 +5583,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec) | |||
5601 | } | 5583 | } |
5602 | 5584 | ||
5603 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 5585 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5604 | static struct hda_amp_list vt2002P_loopbacks[] = { | 5586 | static const struct hda_amp_list vt2002P_loopbacks[] = { |
5605 | { 0x21, HDA_INPUT, 0 }, | 5587 | { 0x21, HDA_INPUT, 0 }, |
5606 | { 0x21, HDA_INPUT, 1 }, | 5588 | { 0x21, HDA_INPUT, 1 }, |
5607 | { 0x21, HDA_INPUT, 2 }, | 5589 | { 0x21, HDA_INPUT, 2 }, |
@@ -5609,6 +5591,116 @@ static struct hda_amp_list vt2002P_loopbacks[] = { | |||
5609 | }; | 5591 | }; |
5610 | #endif | 5592 | #endif |
5611 | 5593 | ||
5594 | static void set_widgets_power_state_vt2002P(struct hda_codec *codec) | ||
5595 | { | ||
5596 | struct via_spec *spec = codec->spec; | ||
5597 | int imux_is_smixer; | ||
5598 | unsigned int parm; | ||
5599 | unsigned int present; | ||
5600 | /* MUX9 (1eh) = stereo mixer */ | ||
5601 | imux_is_smixer = | ||
5602 | snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; | ||
5603 | /* inputs */ | ||
5604 | /* PW 5/6/7 (29h/2ah/2bh) */ | ||
5605 | parm = AC_PWRST_D3; | ||
5606 | set_pin_power_state(codec, 0x29, &parm); | ||
5607 | set_pin_power_state(codec, 0x2a, &parm); | ||
5608 | set_pin_power_state(codec, 0x2b, &parm); | ||
5609 | parm = AC_PWRST_D0; | ||
5610 | /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ | ||
5611 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5612 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5613 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5614 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5615 | |||
5616 | /* outputs */ | ||
5617 | /* AOW0 (8h)*/ | ||
5618 | snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5619 | |||
5620 | if (spec->codec_type == VT1802) { | ||
5621 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ | ||
5622 | parm = AC_PWRST_D3; | ||
5623 | set_pin_power_state(codec, 0x28, &parm); | ||
5624 | snd_hda_codec_write(codec, 0x18, 0, | ||
5625 | AC_VERB_SET_POWER_STATE, parm); | ||
5626 | snd_hda_codec_write(codec, 0x38, 0, | ||
5627 | AC_VERB_SET_POWER_STATE, parm); | ||
5628 | } else { | ||
5629 | /* PW4 (26h), MW4 (1ch), MUX4(37h) */ | ||
5630 | parm = AC_PWRST_D3; | ||
5631 | set_pin_power_state(codec, 0x26, &parm); | ||
5632 | snd_hda_codec_write(codec, 0x1c, 0, | ||
5633 | AC_VERB_SET_POWER_STATE, parm); | ||
5634 | snd_hda_codec_write(codec, 0x37, 0, | ||
5635 | AC_VERB_SET_POWER_STATE, parm); | ||
5636 | } | ||
5637 | |||
5638 | if (spec->codec_type == VT1802) { | ||
5639 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ | ||
5640 | parm = AC_PWRST_D3; | ||
5641 | set_pin_power_state(codec, 0x25, &parm); | ||
5642 | snd_hda_codec_write(codec, 0x15, 0, | ||
5643 | AC_VERB_SET_POWER_STATE, parm); | ||
5644 | snd_hda_codec_write(codec, 0x35, 0, | ||
5645 | AC_VERB_SET_POWER_STATE, parm); | ||
5646 | } else { | ||
5647 | /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ | ||
5648 | parm = AC_PWRST_D3; | ||
5649 | set_pin_power_state(codec, 0x25, &parm); | ||
5650 | snd_hda_codec_write(codec, 0x19, 0, | ||
5651 | AC_VERB_SET_POWER_STATE, parm); | ||
5652 | snd_hda_codec_write(codec, 0x35, 0, | ||
5653 | AC_VERB_SET_POWER_STATE, parm); | ||
5654 | } | ||
5655 | |||
5656 | if (spec->hp_independent_mode) | ||
5657 | snd_hda_codec_write(codec, 0x9, 0, | ||
5658 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
5659 | |||
5660 | /* Class-D */ | ||
5661 | /* PW0 (24h), MW0(18h/14h), MUX0(34h) */ | ||
5662 | present = snd_hda_jack_detect(codec, 0x25); | ||
5663 | |||
5664 | parm = AC_PWRST_D3; | ||
5665 | set_pin_power_state(codec, 0x24, &parm); | ||
5666 | parm = present ? AC_PWRST_D3 : AC_PWRST_D0; | ||
5667 | if (spec->codec_type == VT1802) | ||
5668 | snd_hda_codec_write(codec, 0x14, 0, | ||
5669 | AC_VERB_SET_POWER_STATE, parm); | ||
5670 | else | ||
5671 | snd_hda_codec_write(codec, 0x18, 0, | ||
5672 | AC_VERB_SET_POWER_STATE, parm); | ||
5673 | snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm); | ||
5674 | |||
5675 | /* Mono Out */ | ||
5676 | present = snd_hda_jack_detect(codec, 0x26); | ||
5677 | |||
5678 | parm = present ? AC_PWRST_D3 : AC_PWRST_D0; | ||
5679 | if (spec->codec_type == VT1802) { | ||
5680 | /* PW15 (33h), MW8(1ch), MUX8(3ch) */ | ||
5681 | snd_hda_codec_write(codec, 0x33, 0, | ||
5682 | AC_VERB_SET_POWER_STATE, parm); | ||
5683 | snd_hda_codec_write(codec, 0x1c, 0, | ||
5684 | AC_VERB_SET_POWER_STATE, parm); | ||
5685 | snd_hda_codec_write(codec, 0x3c, 0, | ||
5686 | AC_VERB_SET_POWER_STATE, parm); | ||
5687 | } else { | ||
5688 | /* PW15 (31h), MW8(17h), MUX8(3bh) */ | ||
5689 | snd_hda_codec_write(codec, 0x31, 0, | ||
5690 | AC_VERB_SET_POWER_STATE, parm); | ||
5691 | snd_hda_codec_write(codec, 0x17, 0, | ||
5692 | AC_VERB_SET_POWER_STATE, parm); | ||
5693 | snd_hda_codec_write(codec, 0x3b, 0, | ||
5694 | AC_VERB_SET_POWER_STATE, parm); | ||
5695 | } | ||
5696 | /* MW9 (21h) */ | ||
5697 | if (imux_is_smixer || !is_aa_path_mute(codec)) | ||
5698 | snd_hda_codec_write(codec, 0x21, 0, | ||
5699 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
5700 | else | ||
5701 | snd_hda_codec_write(codec, 0x21, 0, | ||
5702 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
5703 | } | ||
5612 | 5704 | ||
5613 | /* patch for vt2002P */ | 5705 | /* patch for vt2002P */ |
5614 | static int patch_vt2002P(struct hda_codec *codec) | 5706 | static int patch_vt2002P(struct hda_codec *codec) |
@@ -5631,14 +5723,31 @@ static int patch_vt2002P(struct hda_codec *codec) | |||
5631 | "from BIOS. Using genenic mode...\n"); | 5723 | "from BIOS. Using genenic mode...\n"); |
5632 | } | 5724 | } |
5633 | 5725 | ||
5634 | spec->init_verbs[spec->num_iverbs++] = vt2002P_volume_init_verbs; | 5726 | if (spec->codec_type == VT1802) |
5635 | spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs; | 5727 | spec->init_verbs[spec->num_iverbs++] = |
5728 | vt1802_volume_init_verbs; | ||
5729 | else | ||
5730 | spec->init_verbs[spec->num_iverbs++] = | ||
5731 | vt2002P_volume_init_verbs; | ||
5732 | |||
5733 | if (spec->codec_type == VT1802) | ||
5734 | spec->init_verbs[spec->num_iverbs++] = | ||
5735 | vt1802_uniwill_init_verbs; | ||
5736 | else | ||
5737 | spec->init_verbs[spec->num_iverbs++] = | ||
5738 | vt2002P_uniwill_init_verbs; | ||
5636 | 5739 | ||
5637 | spec->stream_name_analog = "VT2002P Analog"; | 5740 | if (spec->codec_type == VT1802) |
5741 | spec->stream_name_analog = "VT1802 Analog"; | ||
5742 | else | ||
5743 | spec->stream_name_analog = "VT2002P Analog"; | ||
5638 | spec->stream_analog_playback = &vt2002P_pcm_analog_playback; | 5744 | spec->stream_analog_playback = &vt2002P_pcm_analog_playback; |
5639 | spec->stream_analog_capture = &vt2002P_pcm_analog_capture; | 5745 | spec->stream_analog_capture = &vt2002P_pcm_analog_capture; |
5640 | 5746 | ||
5641 | spec->stream_name_digital = "VT2002P Digital"; | 5747 | if (spec->codec_type == VT1802) |
5748 | spec->stream_name_digital = "VT1802 Digital"; | ||
5749 | else | ||
5750 | spec->stream_name_digital = "VT2002P Digital"; | ||
5642 | spec->stream_digital_playback = &vt2002P_pcm_digital_playback; | 5751 | spec->stream_digital_playback = &vt2002P_pcm_digital_playback; |
5643 | 5752 | ||
5644 | if (!spec->adc_nids && spec->input_mux) { | 5753 | if (!spec->adc_nids && spec->input_mux) { |
@@ -5660,13 +5769,14 @@ static int patch_vt2002P(struct hda_codec *codec) | |||
5660 | spec->loopback.amplist = vt2002P_loopbacks; | 5769 | spec->loopback.amplist = vt2002P_loopbacks; |
5661 | #endif | 5770 | #endif |
5662 | 5771 | ||
5772 | spec->set_widgets_power_state = set_widgets_power_state_vt2002P; | ||
5663 | return 0; | 5773 | return 0; |
5664 | } | 5774 | } |
5665 | 5775 | ||
5666 | /* for vt1812 */ | 5776 | /* for vt1812 */ |
5667 | 5777 | ||
5668 | /* capture mixer elements */ | 5778 | /* capture mixer elements */ |
5669 | static struct snd_kcontrol_new vt1812_capture_mixer[] = { | 5779 | static const struct snd_kcontrol_new vt1812_capture_mixer[] = { |
5670 | HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), | 5780 | HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), |
5671 | HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), | 5781 | HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), |
5672 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), | 5782 | HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), |
@@ -5688,7 +5798,7 @@ static struct snd_kcontrol_new vt1812_capture_mixer[] = { | |||
5688 | { } /* end */ | 5798 | { } /* end */ |
5689 | }; | 5799 | }; |
5690 | 5800 | ||
5691 | static struct hda_verb vt1812_volume_init_verbs[] = { | 5801 | static const struct hda_verb vt1812_volume_init_verbs[] = { |
5692 | /* | 5802 | /* |
5693 | * Unmute ADC0-1 and set the default input to mic-in | 5803 | * Unmute ADC0-1 and set the default input to mic-in |
5694 | */ | 5804 | */ |
@@ -5741,7 +5851,7 @@ static struct hda_verb vt1812_volume_init_verbs[] = { | |||
5741 | }; | 5851 | }; |
5742 | 5852 | ||
5743 | 5853 | ||
5744 | static struct hda_verb vt1812_uniwill_init_verbs[] = { | 5854 | static const struct hda_verb vt1812_uniwill_init_verbs[] = { |
5745 | {0x33, AC_VERB_SET_UNSOLICITED_ENABLE, | 5855 | {0x33, AC_VERB_SET_UNSOLICITED_ENABLE, |
5746 | AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, | 5856 | AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, |
5747 | {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT }, | 5857 | {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT }, |
@@ -5753,7 +5863,7 @@ static struct hda_verb vt1812_uniwill_init_verbs[] = { | |||
5753 | { } | 5863 | { } |
5754 | }; | 5864 | }; |
5755 | 5865 | ||
5756 | static struct hda_pcm_stream vt1812_pcm_analog_playback = { | 5866 | static const struct hda_pcm_stream vt1812_pcm_analog_playback = { |
5757 | .substreams = 2, | 5867 | .substreams = 2, |
5758 | .channels_min = 2, | 5868 | .channels_min = 2, |
5759 | .channels_max = 2, | 5869 | .channels_max = 2, |
@@ -5766,7 +5876,7 @@ static struct hda_pcm_stream vt1812_pcm_analog_playback = { | |||
5766 | }, | 5876 | }, |
5767 | }; | 5877 | }; |
5768 | 5878 | ||
5769 | static struct hda_pcm_stream vt1812_pcm_analog_capture = { | 5879 | static const struct hda_pcm_stream vt1812_pcm_analog_capture = { |
5770 | .substreams = 2, | 5880 | .substreams = 2, |
5771 | .channels_min = 2, | 5881 | .channels_min = 2, |
5772 | .channels_max = 2, | 5882 | .channels_max = 2, |
@@ -5779,7 +5889,7 @@ static struct hda_pcm_stream vt1812_pcm_analog_capture = { | |||
5779 | }, | 5889 | }, |
5780 | }; | 5890 | }; |
5781 | 5891 | ||
5782 | static struct hda_pcm_stream vt1812_pcm_digital_playback = { | 5892 | static const struct hda_pcm_stream vt1812_pcm_digital_playback = { |
5783 | .substreams = 1, | 5893 | .substreams = 1, |
5784 | .channels_min = 2, | 5894 | .channels_min = 2, |
5785 | .channels_max = 2, | 5895 | .channels_max = 2, |
@@ -5798,7 +5908,7 @@ static int vt1812_auto_fill_dac_nids(struct via_spec *spec, | |||
5798 | spec->multiout.num_dacs = 1; | 5908 | spec->multiout.num_dacs = 1; |
5799 | spec->multiout.dac_nids = spec->private_dac_nids; | 5909 | spec->multiout.dac_nids = spec->private_dac_nids; |
5800 | if (cfg->line_out_pins[0]) | 5910 | if (cfg->line_out_pins[0]) |
5801 | spec->multiout.dac_nids[0] = 0x8; | 5911 | spec->private_dac_nids[0] = 0x8; |
5802 | return 0; | 5912 | return 0; |
5803 | } | 5913 | } |
5804 | 5914 | ||
@@ -5861,7 +5971,7 @@ static int vt1812_auto_create_analog_input_ctls(struct hda_codec *codec, | |||
5861 | { | 5971 | { |
5862 | struct via_spec *spec = codec->spec; | 5972 | struct via_spec *spec = codec->spec; |
5863 | struct hda_input_mux *imux = &spec->private_imux[0]; | 5973 | struct hda_input_mux *imux = &spec->private_imux[0]; |
5864 | static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff }; | 5974 | static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff }; |
5865 | int err; | 5975 | int err; |
5866 | 5976 | ||
5867 | err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, | 5977 | err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, |
@@ -5923,7 +6033,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec) | |||
5923 | } | 6033 | } |
5924 | 6034 | ||
5925 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 6035 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
5926 | static struct hda_amp_list vt1812_loopbacks[] = { | 6036 | static const struct hda_amp_list vt1812_loopbacks[] = { |
5927 | { 0x21, HDA_INPUT, 0 }, | 6037 | { 0x21, HDA_INPUT, 0 }, |
5928 | { 0x21, HDA_INPUT, 1 }, | 6038 | { 0x21, HDA_INPUT, 1 }, |
5929 | { 0x21, HDA_INPUT, 2 }, | 6039 | { 0x21, HDA_INPUT, 2 }, |
@@ -5931,6 +6041,97 @@ static struct hda_amp_list vt1812_loopbacks[] = { | |||
5931 | }; | 6041 | }; |
5932 | #endif | 6042 | #endif |
5933 | 6043 | ||
6044 | static void set_widgets_power_state_vt1812(struct hda_codec *codec) | ||
6045 | { | ||
6046 | struct via_spec *spec = codec->spec; | ||
6047 | int imux_is_smixer = | ||
6048 | snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; | ||
6049 | unsigned int parm; | ||
6050 | unsigned int present; | ||
6051 | /* MUX10 (1eh) = stereo mixer */ | ||
6052 | imux_is_smixer = | ||
6053 | snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; | ||
6054 | /* inputs */ | ||
6055 | /* PW 5/6/7 (29h/2ah/2bh) */ | ||
6056 | parm = AC_PWRST_D3; | ||
6057 | set_pin_power_state(codec, 0x29, &parm); | ||
6058 | set_pin_power_state(codec, 0x2a, &parm); | ||
6059 | set_pin_power_state(codec, 0x2b, &parm); | ||
6060 | parm = AC_PWRST_D0; | ||
6061 | /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ | ||
6062 | snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); | ||
6063 | snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); | ||
6064 | snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); | ||
6065 | snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); | ||
6066 | |||
6067 | /* outputs */ | ||
6068 | /* AOW0 (8h)*/ | ||
6069 | snd_hda_codec_write(codec, 0x8, 0, | ||
6070 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
6071 | |||
6072 | /* PW4 (28h), MW4 (18h), MUX4(38h) */ | ||
6073 | parm = AC_PWRST_D3; | ||
6074 | set_pin_power_state(codec, 0x28, &parm); | ||
6075 | snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); | ||
6076 | snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm); | ||
6077 | |||
6078 | /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ | ||
6079 | parm = AC_PWRST_D3; | ||
6080 | set_pin_power_state(codec, 0x25, &parm); | ||
6081 | snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm); | ||
6082 | snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm); | ||
6083 | if (spec->hp_independent_mode) | ||
6084 | snd_hda_codec_write(codec, 0x9, 0, | ||
6085 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
6086 | |||
6087 | /* Internal Speaker */ | ||
6088 | /* PW0 (24h), MW0(14h), MUX0(34h) */ | ||
6089 | present = snd_hda_jack_detect(codec, 0x25); | ||
6090 | |||
6091 | parm = AC_PWRST_D3; | ||
6092 | set_pin_power_state(codec, 0x24, &parm); | ||
6093 | if (present) { | ||
6094 | snd_hda_codec_write(codec, 0x14, 0, | ||
6095 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
6096 | snd_hda_codec_write(codec, 0x34, 0, | ||
6097 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
6098 | } else { | ||
6099 | snd_hda_codec_write(codec, 0x14, 0, | ||
6100 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
6101 | snd_hda_codec_write(codec, 0x34, 0, | ||
6102 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
6103 | } | ||
6104 | |||
6105 | |||
6106 | /* Mono Out */ | ||
6107 | /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */ | ||
6108 | present = snd_hda_jack_detect(codec, 0x28); | ||
6109 | |||
6110 | parm = AC_PWRST_D3; | ||
6111 | set_pin_power_state(codec, 0x31, &parm); | ||
6112 | if (present) { | ||
6113 | snd_hda_codec_write(codec, 0x1c, 0, | ||
6114 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
6115 | snd_hda_codec_write(codec, 0x3c, 0, | ||
6116 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
6117 | snd_hda_codec_write(codec, 0x3e, 0, | ||
6118 | AC_VERB_SET_POWER_STATE, AC_PWRST_D3); | ||
6119 | } else { | ||
6120 | snd_hda_codec_write(codec, 0x1c, 0, | ||
6121 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
6122 | snd_hda_codec_write(codec, 0x3c, 0, | ||
6123 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
6124 | snd_hda_codec_write(codec, 0x3e, 0, | ||
6125 | AC_VERB_SET_POWER_STATE, AC_PWRST_D0); | ||
6126 | } | ||
6127 | |||
6128 | /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ | ||
6129 | parm = AC_PWRST_D3; | ||
6130 | set_pin_power_state(codec, 0x33, &parm); | ||
6131 | snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); | ||
6132 | snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm); | ||
6133 | |||
6134 | } | ||
5934 | 6135 | ||
5935 | /* patch for vt1812 */ | 6136 | /* patch for vt1812 */ |
5936 | static int patch_vt1812(struct hda_codec *codec) | 6137 | static int patch_vt1812(struct hda_codec *codec) |
@@ -5984,13 +6185,14 @@ static int patch_vt1812(struct hda_codec *codec) | |||
5984 | spec->loopback.amplist = vt1812_loopbacks; | 6185 | spec->loopback.amplist = vt1812_loopbacks; |
5985 | #endif | 6186 | #endif |
5986 | 6187 | ||
6188 | spec->set_widgets_power_state = set_widgets_power_state_vt1812; | ||
5987 | return 0; | 6189 | return 0; |
5988 | } | 6190 | } |
5989 | 6191 | ||
5990 | /* | 6192 | /* |
5991 | * patch entries | 6193 | * patch entries |
5992 | */ | 6194 | */ |
5993 | static struct hda_codec_preset snd_hda_preset_via[] = { | 6195 | static const struct hda_codec_preset snd_hda_preset_via[] = { |
5994 | { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708}, | 6196 | { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708}, |
5995 | { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708}, | 6197 | { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708}, |
5996 | { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708}, | 6198 | { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708}, |
@@ -6035,7 +6237,7 @@ static struct hda_codec_preset snd_hda_preset_via[] = { | |||
6035 | .patch = patch_vt1708S}, | 6237 | .patch = patch_vt1708S}, |
6036 | { .id = 0x11063397, .name = "VT1708S", | 6238 | { .id = 0x11063397, .name = "VT1708S", |
6037 | .patch = patch_vt1708S}, | 6239 | .patch = patch_vt1708S}, |
6038 | { .id = 0x11064397, .name = "VT1708S", | 6240 | { .id = 0x11064397, .name = "VT1705", |
6039 | .patch = patch_vt1708S}, | 6241 | .patch = patch_vt1708S}, |
6040 | { .id = 0x11065397, .name = "VT1708S", | 6242 | { .id = 0x11065397, .name = "VT1708S", |
6041 | .patch = patch_vt1708S}, | 6243 | .patch = patch_vt1708S}, |
@@ -6076,6 +6278,10 @@ static struct hda_codec_preset snd_hda_preset_via[] = { | |||
6076 | { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812}, | 6278 | { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812}, |
6077 | { .id = 0x11060440, .name = "VT1818S", | 6279 | { .id = 0x11060440, .name = "VT1818S", |
6078 | .patch = patch_vt1708S}, | 6280 | .patch = patch_vt1708S}, |
6281 | { .id = 0x11060446, .name = "VT1802", | ||
6282 | .patch = patch_vt2002P}, | ||
6283 | { .id = 0x11068446, .name = "VT1802", | ||
6284 | .patch = patch_vt2002P}, | ||
6079 | {} /* terminator */ | 6285 | {} /* terminator */ |
6080 | }; | 6286 | }; |
6081 | 6287 | ||
diff --git a/sound/pci/intel8x0m.c b/sound/pci/intel8x0m.c index 27709f0cd2a6..f3353b49c785 100644 --- a/sound/pci/intel8x0m.c +++ b/sound/pci/intel8x0m.c | |||
@@ -235,8 +235,8 @@ static DEFINE_PCI_DEVICE_TABLE(snd_intel8x0m_ids) = { | |||
235 | { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */ | 235 | { PCI_VDEVICE(NVIDIA, 0x0069), DEVICE_NFORCE }, /* NFORCE2 */ |
236 | { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */ | 236 | { PCI_VDEVICE(NVIDIA, 0x0089), DEVICE_NFORCE }, /* NFORCE2s */ |
237 | { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */ | 237 | { PCI_VDEVICE(NVIDIA, 0x00d9), DEVICE_NFORCE }, /* NFORCE3 */ |
238 | { PCI_VDEVICE(AMD, 0x746e), DEVICE_INTEL }, /* AMD8111 */ | ||
238 | #if 0 | 239 | #if 0 |
239 | { PCI_VDEVICE(AMD, 0x746d), DEVICE_INTEL }, /* AMD8111 */ | ||
240 | { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */ | 240 | { PCI_VDEVICE(AL, 0x5455), DEVICE_ALI }, /* Ali5455 */ |
241 | #endif | 241 | #endif |
242 | { 0, } | 242 | { 0, } |
@@ -1261,9 +1261,9 @@ static struct shortname_table { | |||
1261 | { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" }, | 1261 | { PCI_DEVICE_ID_NVIDIA_MCP2_MODEM, "NVidia nForce2" }, |
1262 | { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" }, | 1262 | { PCI_DEVICE_ID_NVIDIA_MCP2S_MODEM, "NVidia nForce2s" }, |
1263 | { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" }, | 1263 | { PCI_DEVICE_ID_NVIDIA_MCP3_MODEM, "NVidia nForce3" }, |
1264 | { 0x746e, "AMD AMD8111" }, | ||
1264 | #if 0 | 1265 | #if 0 |
1265 | { 0x5455, "ALi M5455" }, | 1266 | { 0x5455, "ALi M5455" }, |
1266 | { 0x746d, "AMD AMD8111" }, | ||
1267 | #endif | 1267 | #endif |
1268 | { 0 }, | 1268 | { 0 }, |
1269 | }; | 1269 | }; |
diff --git a/sound/pci/lola/Makefile b/sound/pci/lola/Makefile new file mode 100644 index 000000000000..8178a2a59d00 --- /dev/null +++ b/sound/pci/lola/Makefile | |||
@@ -0,0 +1,4 @@ | |||
1 | snd-lola-y := lola.o lola_pcm.o lola_clock.o lola_mixer.o | ||
2 | snd-lola-$(CONFIG_SND_DEBUG) += lola_proc.o | ||
3 | |||
4 | obj-$(CONFIG_SND_LOLA) += snd-lola.o | ||
diff --git a/sound/pci/lola/lola.c b/sound/pci/lola/lola.c new file mode 100644 index 000000000000..34b24286d279 --- /dev/null +++ b/sound/pci/lola/lola.c | |||
@@ -0,0 +1,791 @@ | |||
1 | /* | ||
2 | * Support for Digigram Lola PCI-e boards | ||
3 | * | ||
4 | * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation; either version 2 of the License, or (at your option) | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
18 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/moduleparam.h> | ||
24 | #include <linux/dma-mapping.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/interrupt.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/pci.h> | ||
29 | #include <sound/core.h> | ||
30 | #include <sound/control.h> | ||
31 | #include <sound/pcm.h> | ||
32 | #include <sound/initval.h> | ||
33 | #include "lola.h" | ||
34 | |||
35 | /* Standard options */ | ||
36 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; | ||
37 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; | ||
38 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; | ||
39 | |||
40 | module_param_array(index, int, NULL, 0444); | ||
41 | MODULE_PARM_DESC(index, "Index value for Digigram Lola driver."); | ||
42 | module_param_array(id, charp, NULL, 0444); | ||
43 | MODULE_PARM_DESC(id, "ID string for Digigram Lola driver."); | ||
44 | module_param_array(enable, bool, NULL, 0444); | ||
45 | MODULE_PARM_DESC(enable, "Enable Digigram Lola driver."); | ||
46 | |||
47 | /* Lola-specific options */ | ||
48 | |||
49 | /* for instance use always max granularity which is compatible | ||
50 | * with all sample rates | ||
51 | */ | ||
52 | static int granularity[SNDRV_CARDS] = { | ||
53 | [0 ... (SNDRV_CARDS - 1)] = LOLA_GRANULARITY_MAX | ||
54 | }; | ||
55 | |||
56 | /* below a sample_rate of 16kHz the analogue audio quality is NOT excellent */ | ||
57 | static int sample_rate_min[SNDRV_CARDS] = { | ||
58 | [0 ... (SNDRV_CARDS - 1) ] = 16000 | ||
59 | }; | ||
60 | |||
61 | module_param_array(granularity, int, NULL, 0444); | ||
62 | MODULE_PARM_DESC(granularity, "Granularity value"); | ||
63 | module_param_array(sample_rate_min, int, NULL, 0444); | ||
64 | MODULE_PARM_DESC(sample_rate_min, "Minimal sample rate"); | ||
65 | |||
66 | /* | ||
67 | */ | ||
68 | |||
69 | MODULE_LICENSE("GPL"); | ||
70 | MODULE_SUPPORTED_DEVICE("{{Digigram, Lola}}"); | ||
71 | MODULE_DESCRIPTION("Digigram Lola driver"); | ||
72 | MODULE_AUTHOR("Takashi Iwai <tiwai@suse.de>"); | ||
73 | |||
74 | #ifdef CONFIG_SND_DEBUG_VERBOSE | ||
75 | static int debug; | ||
76 | module_param(debug, int, 0644); | ||
77 | #define verbose_debug(fmt, args...) \ | ||
78 | do { if (debug > 1) printk(KERN_DEBUG SFX fmt, ##args); } while (0) | ||
79 | #else | ||
80 | #define verbose_debug(fmt, args...) | ||
81 | #endif | ||
82 | |||
83 | /* | ||
84 | * pseudo-codec read/write via CORB/RIRB | ||
85 | */ | ||
86 | |||
87 | static int corb_send_verb(struct lola *chip, unsigned int nid, | ||
88 | unsigned int verb, unsigned int data, | ||
89 | unsigned int extdata) | ||
90 | { | ||
91 | unsigned long flags; | ||
92 | int ret = -EIO; | ||
93 | |||
94 | chip->last_cmd_nid = nid; | ||
95 | chip->last_verb = verb; | ||
96 | chip->last_data = data; | ||
97 | chip->last_extdata = extdata; | ||
98 | data |= (nid << 20) | (verb << 8); | ||
99 | |||
100 | spin_lock_irqsave(&chip->reg_lock, flags); | ||
101 | if (chip->rirb.cmds < LOLA_CORB_ENTRIES - 1) { | ||
102 | unsigned int wp = chip->corb.wp + 1; | ||
103 | wp %= LOLA_CORB_ENTRIES; | ||
104 | chip->corb.wp = wp; | ||
105 | chip->corb.buf[wp * 2] = cpu_to_le32(data); | ||
106 | chip->corb.buf[wp * 2 + 1] = cpu_to_le32(extdata); | ||
107 | lola_writew(chip, BAR0, CORBWP, wp); | ||
108 | chip->rirb.cmds++; | ||
109 | smp_wmb(); | ||
110 | ret = 0; | ||
111 | } | ||
112 | spin_unlock_irqrestore(&chip->reg_lock, flags); | ||
113 | return ret; | ||
114 | } | ||
115 | |||
116 | static void lola_queue_unsol_event(struct lola *chip, unsigned int res, | ||
117 | unsigned int res_ex) | ||
118 | { | ||
119 | lola_update_ext_clock_freq(chip, res); | ||
120 | } | ||
121 | |||
122 | /* retrieve RIRB entry - called from interrupt handler */ | ||
123 | static void lola_update_rirb(struct lola *chip) | ||
124 | { | ||
125 | unsigned int rp, wp; | ||
126 | u32 res, res_ex; | ||
127 | |||
128 | wp = lola_readw(chip, BAR0, RIRBWP); | ||
129 | if (wp == chip->rirb.wp) | ||
130 | return; | ||
131 | chip->rirb.wp = wp; | ||
132 | |||
133 | while (chip->rirb.rp != wp) { | ||
134 | chip->rirb.rp++; | ||
135 | chip->rirb.rp %= LOLA_CORB_ENTRIES; | ||
136 | |||
137 | rp = chip->rirb.rp << 1; /* an RIRB entry is 8-bytes */ | ||
138 | res_ex = le32_to_cpu(chip->rirb.buf[rp + 1]); | ||
139 | res = le32_to_cpu(chip->rirb.buf[rp]); | ||
140 | if (res_ex & LOLA_RIRB_EX_UNSOL_EV) | ||
141 | lola_queue_unsol_event(chip, res, res_ex); | ||
142 | else if (chip->rirb.cmds) { | ||
143 | chip->res = res; | ||
144 | chip->res_ex = res_ex; | ||
145 | smp_wmb(); | ||
146 | chip->rirb.cmds--; | ||
147 | } | ||
148 | } | ||
149 | } | ||
150 | |||
151 | static int rirb_get_response(struct lola *chip, unsigned int *val, | ||
152 | unsigned int *extval) | ||
153 | { | ||
154 | unsigned long timeout; | ||
155 | |||
156 | again: | ||
157 | timeout = jiffies + msecs_to_jiffies(1000); | ||
158 | for (;;) { | ||
159 | if (chip->polling_mode) { | ||
160 | spin_lock_irq(&chip->reg_lock); | ||
161 | lola_update_rirb(chip); | ||
162 | spin_unlock_irq(&chip->reg_lock); | ||
163 | } | ||
164 | if (!chip->rirb.cmds) { | ||
165 | *val = chip->res; | ||
166 | if (extval) | ||
167 | *extval = chip->res_ex; | ||
168 | verbose_debug("get_response: %x, %x\n", | ||
169 | chip->res, chip->res_ex); | ||
170 | if (chip->res_ex & LOLA_RIRB_EX_ERROR) { | ||
171 | printk(KERN_WARNING SFX "RIRB ERROR: " | ||
172 | "NID=%x, verb=%x, data=%x, ext=%x\n", | ||
173 | chip->last_cmd_nid, | ||
174 | chip->last_verb, chip->last_data, | ||
175 | chip->last_extdata); | ||
176 | return -EIO; | ||
177 | } | ||
178 | return 0; | ||
179 | } | ||
180 | if (time_after(jiffies, timeout)) | ||
181 | break; | ||
182 | udelay(20); | ||
183 | cond_resched(); | ||
184 | } | ||
185 | printk(KERN_WARNING SFX "RIRB response error\n"); | ||
186 | if (!chip->polling_mode) { | ||
187 | printk(KERN_WARNING SFX "switching to polling mode\n"); | ||
188 | chip->polling_mode = 1; | ||
189 | goto again; | ||
190 | } | ||
191 | return -EIO; | ||
192 | } | ||
193 | |||
194 | /* aynchronous write of a codec verb with data */ | ||
195 | int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb, | ||
196 | unsigned int data, unsigned int extdata) | ||
197 | { | ||
198 | verbose_debug("codec_write NID=%x, verb=%x, data=%x, ext=%x\n", | ||
199 | nid, verb, data, extdata); | ||
200 | return corb_send_verb(chip, nid, verb, data, extdata); | ||
201 | } | ||
202 | |||
203 | /* write a codec verb with data and read the returned status */ | ||
204 | int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb, | ||
205 | unsigned int data, unsigned int extdata, | ||
206 | unsigned int *val, unsigned int *extval) | ||
207 | { | ||
208 | int err; | ||
209 | |||
210 | verbose_debug("codec_read NID=%x, verb=%x, data=%x, ext=%x\n", | ||
211 | nid, verb, data, extdata); | ||
212 | err = corb_send_verb(chip, nid, verb, data, extdata); | ||
213 | if (err < 0) | ||
214 | return err; | ||
215 | err = rirb_get_response(chip, val, extval); | ||
216 | return err; | ||
217 | } | ||
218 | |||
219 | /* flush all pending codec writes */ | ||
220 | int lola_codec_flush(struct lola *chip) | ||
221 | { | ||
222 | unsigned int tmp; | ||
223 | return rirb_get_response(chip, &tmp, NULL); | ||
224 | } | ||
225 | |||
226 | /* | ||
227 | * interrupt handler | ||
228 | */ | ||
229 | static irqreturn_t lola_interrupt(int irq, void *dev_id) | ||
230 | { | ||
231 | struct lola *chip = dev_id; | ||
232 | unsigned int notify_ins, notify_outs, error_ins, error_outs; | ||
233 | int handled = 0; | ||
234 | int i; | ||
235 | |||
236 | notify_ins = notify_outs = error_ins = error_outs = 0; | ||
237 | spin_lock(&chip->reg_lock); | ||
238 | for (;;) { | ||
239 | unsigned int status, in_sts, out_sts; | ||
240 | unsigned int reg; | ||
241 | |||
242 | status = lola_readl(chip, BAR1, DINTSTS); | ||
243 | if (!status || status == -1) | ||
244 | break; | ||
245 | |||
246 | in_sts = lola_readl(chip, BAR1, DIINTSTS); | ||
247 | out_sts = lola_readl(chip, BAR1, DOINTSTS); | ||
248 | |||
249 | /* clear Input Interrupts */ | ||
250 | for (i = 0; in_sts && i < chip->pcm[CAPT].num_streams; i++) { | ||
251 | if (!(in_sts & (1 << i))) | ||
252 | continue; | ||
253 | in_sts &= ~(1 << i); | ||
254 | reg = lola_dsd_read(chip, i, STS); | ||
255 | if (reg & LOLA_DSD_STS_DESE) /* error */ | ||
256 | error_ins |= (1 << i); | ||
257 | if (reg & LOLA_DSD_STS_BCIS) /* notify */ | ||
258 | notify_ins |= (1 << i); | ||
259 | /* clear */ | ||
260 | lola_dsd_write(chip, i, STS, reg); | ||
261 | } | ||
262 | |||
263 | /* clear Output Interrupts */ | ||
264 | for (i = 0; out_sts && i < chip->pcm[PLAY].num_streams; i++) { | ||
265 | if (!(out_sts & (1 << i))) | ||
266 | continue; | ||
267 | out_sts &= ~(1 << i); | ||
268 | reg = lola_dsd_read(chip, i + MAX_STREAM_IN_COUNT, STS); | ||
269 | if (reg & LOLA_DSD_STS_DESE) /* error */ | ||
270 | error_outs |= (1 << i); | ||
271 | if (reg & LOLA_DSD_STS_BCIS) /* notify */ | ||
272 | notify_outs |= (1 << i); | ||
273 | lola_dsd_write(chip, i + MAX_STREAM_IN_COUNT, STS, reg); | ||
274 | } | ||
275 | |||
276 | if (status & LOLA_DINT_CTRL) { | ||
277 | unsigned char rbsts; /* ring status is byte access */ | ||
278 | rbsts = lola_readb(chip, BAR0, RIRBSTS); | ||
279 | rbsts &= LOLA_RIRB_INT_MASK; | ||
280 | if (rbsts) | ||
281 | lola_writeb(chip, BAR0, RIRBSTS, rbsts); | ||
282 | rbsts = lola_readb(chip, BAR0, CORBSTS); | ||
283 | rbsts &= LOLA_CORB_INT_MASK; | ||
284 | if (rbsts) | ||
285 | lola_writeb(chip, BAR0, CORBSTS, rbsts); | ||
286 | |||
287 | lola_update_rirb(chip); | ||
288 | } | ||
289 | |||
290 | if (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR)) { | ||
291 | /* clear global fifo error interrupt */ | ||
292 | lola_writel(chip, BAR1, DINTSTS, | ||
293 | (status & (LOLA_DINT_FIFOERR | LOLA_DINT_MUERR))); | ||
294 | } | ||
295 | handled = 1; | ||
296 | } | ||
297 | spin_unlock(&chip->reg_lock); | ||
298 | |||
299 | lola_pcm_update(chip, &chip->pcm[CAPT], notify_ins); | ||
300 | lola_pcm_update(chip, &chip->pcm[PLAY], notify_outs); | ||
301 | |||
302 | return IRQ_RETVAL(handled); | ||
303 | } | ||
304 | |||
305 | |||
306 | /* | ||
307 | * controller | ||
308 | */ | ||
309 | static int reset_controller(struct lola *chip) | ||
310 | { | ||
311 | unsigned int gctl = lola_readl(chip, BAR0, GCTL); | ||
312 | unsigned long end_time; | ||
313 | |||
314 | if (gctl) { | ||
315 | /* to be sure */ | ||
316 | lola_writel(chip, BAR1, BOARD_MODE, 0); | ||
317 | return 0; | ||
318 | } | ||
319 | |||
320 | chip->cold_reset = 1; | ||
321 | lola_writel(chip, BAR0, GCTL, LOLA_GCTL_RESET); | ||
322 | end_time = jiffies + msecs_to_jiffies(200); | ||
323 | do { | ||
324 | msleep(1); | ||
325 | gctl = lola_readl(chip, BAR0, GCTL); | ||
326 | if (gctl) | ||
327 | break; | ||
328 | } while (time_before(jiffies, end_time)); | ||
329 | if (!gctl) { | ||
330 | printk(KERN_ERR SFX "cannot reset controller\n"); | ||
331 | return -EIO; | ||
332 | } | ||
333 | return 0; | ||
334 | } | ||
335 | |||
336 | static void lola_irq_enable(struct lola *chip) | ||
337 | { | ||
338 | unsigned int val; | ||
339 | |||
340 | /* enalbe all I/O streams */ | ||
341 | val = (1 << chip->pcm[PLAY].num_streams) - 1; | ||
342 | lola_writel(chip, BAR1, DOINTCTL, val); | ||
343 | val = (1 << chip->pcm[CAPT].num_streams) - 1; | ||
344 | lola_writel(chip, BAR1, DIINTCTL, val); | ||
345 | |||
346 | /* enable global irqs */ | ||
347 | val = LOLA_DINT_GLOBAL | LOLA_DINT_CTRL | LOLA_DINT_FIFOERR | | ||
348 | LOLA_DINT_MUERR; | ||
349 | lola_writel(chip, BAR1, DINTCTL, val); | ||
350 | } | ||
351 | |||
352 | static void lola_irq_disable(struct lola *chip) | ||
353 | { | ||
354 | lola_writel(chip, BAR1, DINTCTL, 0); | ||
355 | lola_writel(chip, BAR1, DIINTCTL, 0); | ||
356 | lola_writel(chip, BAR1, DOINTCTL, 0); | ||
357 | } | ||
358 | |||
359 | static int setup_corb_rirb(struct lola *chip) | ||
360 | { | ||
361 | int err; | ||
362 | unsigned char tmp; | ||
363 | unsigned long end_time; | ||
364 | |||
365 | err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, | ||
366 | snd_dma_pci_data(chip->pci), | ||
367 | PAGE_SIZE, &chip->rb); | ||
368 | if (err < 0) | ||
369 | return err; | ||
370 | |||
371 | chip->corb.addr = chip->rb.addr; | ||
372 | chip->corb.buf = (u32 *)chip->rb.area; | ||
373 | chip->rirb.addr = chip->rb.addr + 2048; | ||
374 | chip->rirb.buf = (u32 *)(chip->rb.area + 2048); | ||
375 | |||
376 | /* disable ringbuffer DMAs */ | ||
377 | lola_writeb(chip, BAR0, RIRBCTL, 0); | ||
378 | lola_writeb(chip, BAR0, CORBCTL, 0); | ||
379 | |||
380 | end_time = jiffies + msecs_to_jiffies(200); | ||
381 | do { | ||
382 | if (!lola_readb(chip, BAR0, RIRBCTL) && | ||
383 | !lola_readb(chip, BAR0, CORBCTL)) | ||
384 | break; | ||
385 | msleep(1); | ||
386 | } while (time_before(jiffies, end_time)); | ||
387 | |||
388 | /* CORB set up */ | ||
389 | lola_writel(chip, BAR0, CORBLBASE, (u32)chip->corb.addr); | ||
390 | lola_writel(chip, BAR0, CORBUBASE, upper_32_bits(chip->corb.addr)); | ||
391 | /* set the corb size to 256 entries */ | ||
392 | lola_writeb(chip, BAR0, CORBSIZE, 0x02); | ||
393 | /* set the corb write pointer to 0 */ | ||
394 | lola_writew(chip, BAR0, CORBWP, 0); | ||
395 | /* reset the corb hw read pointer */ | ||
396 | lola_writew(chip, BAR0, CORBRP, LOLA_RBRWP_CLR); | ||
397 | /* enable corb dma */ | ||
398 | lola_writeb(chip, BAR0, CORBCTL, LOLA_RBCTL_DMA_EN); | ||
399 | /* clear flags if set */ | ||
400 | tmp = lola_readb(chip, BAR0, CORBSTS) & LOLA_CORB_INT_MASK; | ||
401 | if (tmp) | ||
402 | lola_writeb(chip, BAR0, CORBSTS, tmp); | ||
403 | chip->corb.wp = 0; | ||
404 | |||
405 | /* RIRB set up */ | ||
406 | lola_writel(chip, BAR0, RIRBLBASE, (u32)chip->rirb.addr); | ||
407 | lola_writel(chip, BAR0, RIRBUBASE, upper_32_bits(chip->rirb.addr)); | ||
408 | /* set the rirb size to 256 entries */ | ||
409 | lola_writeb(chip, BAR0, RIRBSIZE, 0x02); | ||
410 | /* reset the rirb hw write pointer */ | ||
411 | lola_writew(chip, BAR0, RIRBWP, LOLA_RBRWP_CLR); | ||
412 | /* set N=1, get RIRB response interrupt for new entry */ | ||
413 | lola_writew(chip, BAR0, RINTCNT, 1); | ||
414 | /* enable rirb dma and response irq */ | ||
415 | lola_writeb(chip, BAR0, RIRBCTL, LOLA_RBCTL_DMA_EN | LOLA_RBCTL_IRQ_EN); | ||
416 | /* clear flags if set */ | ||
417 | tmp = lola_readb(chip, BAR0, RIRBSTS) & LOLA_RIRB_INT_MASK; | ||
418 | if (tmp) | ||
419 | lola_writeb(chip, BAR0, RIRBSTS, tmp); | ||
420 | chip->rirb.rp = chip->rirb.cmds = 0; | ||
421 | |||
422 | return 0; | ||
423 | } | ||
424 | |||
425 | static void stop_corb_rirb(struct lola *chip) | ||
426 | { | ||
427 | /* disable ringbuffer DMAs */ | ||
428 | lola_writeb(chip, BAR0, RIRBCTL, 0); | ||
429 | lola_writeb(chip, BAR0, CORBCTL, 0); | ||
430 | } | ||
431 | |||
432 | static void lola_reset_setups(struct lola *chip) | ||
433 | { | ||
434 | /* update the granularity */ | ||
435 | lola_set_granularity(chip, chip->granularity, true); | ||
436 | /* update the sample clock */ | ||
437 | lola_set_clock_index(chip, chip->clock.cur_index); | ||
438 | /* enable unsolicited events of the clock widget */ | ||
439 | lola_enable_clock_events(chip); | ||
440 | /* update the analog gains */ | ||
441 | lola_setup_all_analog_gains(chip, CAPT, false); /* input, update */ | ||
442 | /* update SRC configuration if applicable */ | ||
443 | lola_set_src_config(chip, chip->input_src_mask, false); | ||
444 | /* update the analog outputs */ | ||
445 | lola_setup_all_analog_gains(chip, PLAY, false); /* output, update */ | ||
446 | } | ||
447 | |||
448 | static int lola_parse_tree(struct lola *chip) | ||
449 | { | ||
450 | unsigned int val; | ||
451 | int nid, err; | ||
452 | |||
453 | err = lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val); | ||
454 | if (err < 0) { | ||
455 | printk(KERN_ERR SFX "Can't read VENDOR_ID\n"); | ||
456 | return err; | ||
457 | } | ||
458 | val >>= 16; | ||
459 | if (val != 0x1369) { | ||
460 | printk(KERN_ERR SFX "Unknown codec vendor 0x%x\n", val); | ||
461 | return -EINVAL; | ||
462 | } | ||
463 | |||
464 | err = lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val); | ||
465 | if (err < 0) { | ||
466 | printk(KERN_ERR SFX "Can't read FUNCTION_TYPE for 0x%x\n", nid); | ||
467 | return err; | ||
468 | } | ||
469 | if (val != 1) { | ||
470 | printk(KERN_ERR SFX "Unknown function type %d\n", val); | ||
471 | return -EINVAL; | ||
472 | } | ||
473 | |||
474 | err = lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val); | ||
475 | if (err < 0) { | ||
476 | printk(KERN_ERR SFX "Can't read SPECCAPS\n"); | ||
477 | return err; | ||
478 | } | ||
479 | chip->lola_caps = val; | ||
480 | chip->pin[CAPT].num_pins = LOLA_AFG_INPUT_PIN_COUNT(chip->lola_caps); | ||
481 | chip->pin[PLAY].num_pins = LOLA_AFG_OUTPUT_PIN_COUNT(chip->lola_caps); | ||
482 | snd_printdd(SFX "speccaps=0x%x, pins in=%d, out=%d\n", | ||
483 | chip->lola_caps, | ||
484 | chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins); | ||
485 | |||
486 | if (chip->pin[CAPT].num_pins > MAX_AUDIO_INOUT_COUNT || | ||
487 | chip->pin[PLAY].num_pins > MAX_AUDIO_INOUT_COUNT) { | ||
488 | printk(KERN_ERR SFX "Invalid Lola-spec caps 0x%x\n", val); | ||
489 | return -EINVAL; | ||
490 | } | ||
491 | |||
492 | nid = 0x02; | ||
493 | err = lola_init_pcm(chip, CAPT, &nid); | ||
494 | if (err < 0) | ||
495 | return err; | ||
496 | err = lola_init_pcm(chip, PLAY, &nid); | ||
497 | if (err < 0) | ||
498 | return err; | ||
499 | |||
500 | err = lola_init_pins(chip, CAPT, &nid); | ||
501 | if (err < 0) | ||
502 | return err; | ||
503 | err = lola_init_pins(chip, PLAY, &nid); | ||
504 | if (err < 0) | ||
505 | return err; | ||
506 | |||
507 | if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) { | ||
508 | err = lola_init_clock_widget(chip, nid); | ||
509 | if (err < 0) | ||
510 | return err; | ||
511 | nid++; | ||
512 | } | ||
513 | if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) { | ||
514 | err = lola_init_mixer_widget(chip, nid); | ||
515 | if (err < 0) | ||
516 | return err; | ||
517 | nid++; | ||
518 | } | ||
519 | |||
520 | /* enable unsolicited events of the clock widget */ | ||
521 | err = lola_enable_clock_events(chip); | ||
522 | if (err < 0) | ||
523 | return err; | ||
524 | |||
525 | /* if last ResetController was not a ColdReset, we don't know | ||
526 | * the state of the card; initialize here again | ||
527 | */ | ||
528 | if (!chip->cold_reset) { | ||
529 | lola_reset_setups(chip); | ||
530 | chip->cold_reset = 1; | ||
531 | } else { | ||
532 | /* set the granularity if it is not the default */ | ||
533 | if (chip->granularity != LOLA_GRANULARITY_MIN) | ||
534 | lola_set_granularity(chip, chip->granularity, true); | ||
535 | } | ||
536 | |||
537 | return 0; | ||
538 | } | ||
539 | |||
540 | static void lola_stop_hw(struct lola *chip) | ||
541 | { | ||
542 | stop_corb_rirb(chip); | ||
543 | lola_irq_disable(chip); | ||
544 | } | ||
545 | |||
546 | static void lola_free(struct lola *chip) | ||
547 | { | ||
548 | if (chip->initialized) | ||
549 | lola_stop_hw(chip); | ||
550 | lola_free_pcm(chip); | ||
551 | lola_free_mixer(chip); | ||
552 | if (chip->irq >= 0) | ||
553 | free_irq(chip->irq, (void *)chip); | ||
554 | if (chip->bar[0].remap_addr) | ||
555 | iounmap(chip->bar[0].remap_addr); | ||
556 | if (chip->bar[1].remap_addr) | ||
557 | iounmap(chip->bar[1].remap_addr); | ||
558 | if (chip->rb.area) | ||
559 | snd_dma_free_pages(&chip->rb); | ||
560 | pci_release_regions(chip->pci); | ||
561 | pci_disable_device(chip->pci); | ||
562 | kfree(chip); | ||
563 | } | ||
564 | |||
565 | static int lola_dev_free(struct snd_device *device) | ||
566 | { | ||
567 | lola_free(device->device_data); | ||
568 | return 0; | ||
569 | } | ||
570 | |||
571 | static int __devinit lola_create(struct snd_card *card, struct pci_dev *pci, | ||
572 | int dev, struct lola **rchip) | ||
573 | { | ||
574 | struct lola *chip; | ||
575 | int err; | ||
576 | unsigned int dever; | ||
577 | static struct snd_device_ops ops = { | ||
578 | .dev_free = lola_dev_free, | ||
579 | }; | ||
580 | |||
581 | *rchip = NULL; | ||
582 | |||
583 | err = pci_enable_device(pci); | ||
584 | if (err < 0) | ||
585 | return err; | ||
586 | |||
587 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
588 | if (!chip) { | ||
589 | snd_printk(KERN_ERR SFX "cannot allocate chip\n"); | ||
590 | pci_disable_device(pci); | ||
591 | return -ENOMEM; | ||
592 | } | ||
593 | |||
594 | spin_lock_init(&chip->reg_lock); | ||
595 | mutex_init(&chip->open_mutex); | ||
596 | chip->card = card; | ||
597 | chip->pci = pci; | ||
598 | chip->irq = -1; | ||
599 | |||
600 | chip->granularity = granularity[dev]; | ||
601 | switch (chip->granularity) { | ||
602 | case 8: | ||
603 | chip->sample_rate_max = 48000; | ||
604 | break; | ||
605 | case 16: | ||
606 | chip->sample_rate_max = 96000; | ||
607 | break; | ||
608 | case 32: | ||
609 | chip->sample_rate_max = 192000; | ||
610 | break; | ||
611 | default: | ||
612 | snd_printk(KERN_WARNING SFX | ||
613 | "Invalid granularity %d, reset to %d\n", | ||
614 | chip->granularity, LOLA_GRANULARITY_MAX); | ||
615 | chip->granularity = LOLA_GRANULARITY_MAX; | ||
616 | chip->sample_rate_max = 192000; | ||
617 | break; | ||
618 | } | ||
619 | chip->sample_rate_min = sample_rate_min[dev]; | ||
620 | if (chip->sample_rate_min > chip->sample_rate_max) { | ||
621 | snd_printk(KERN_WARNING SFX | ||
622 | "Invalid sample_rate_min %d, reset to 16000\n", | ||
623 | chip->sample_rate_min); | ||
624 | chip->sample_rate_min = 16000; | ||
625 | } | ||
626 | |||
627 | err = pci_request_regions(pci, DRVNAME); | ||
628 | if (err < 0) { | ||
629 | kfree(chip); | ||
630 | pci_disable_device(pci); | ||
631 | return err; | ||
632 | } | ||
633 | |||
634 | chip->bar[0].addr = pci_resource_start(pci, 0); | ||
635 | chip->bar[0].remap_addr = pci_ioremap_bar(pci, 0); | ||
636 | chip->bar[1].addr = pci_resource_start(pci, 2); | ||
637 | chip->bar[1].remap_addr = pci_ioremap_bar(pci, 2); | ||
638 | if (!chip->bar[0].remap_addr || !chip->bar[1].remap_addr) { | ||
639 | snd_printk(KERN_ERR SFX "ioremap error\n"); | ||
640 | err = -ENXIO; | ||
641 | goto errout; | ||
642 | } | ||
643 | |||
644 | pci_set_master(pci); | ||
645 | |||
646 | err = reset_controller(chip); | ||
647 | if (err < 0) | ||
648 | goto errout; | ||
649 | |||
650 | if (request_irq(pci->irq, lola_interrupt, IRQF_SHARED, | ||
651 | DRVNAME, chip)) { | ||
652 | printk(KERN_ERR SFX "unable to grab IRQ %d\n", pci->irq); | ||
653 | err = -EBUSY; | ||
654 | goto errout; | ||
655 | } | ||
656 | chip->irq = pci->irq; | ||
657 | synchronize_irq(chip->irq); | ||
658 | |||
659 | dever = lola_readl(chip, BAR1, DEVER); | ||
660 | chip->pcm[CAPT].num_streams = (dever >> 0) & 0x3ff; | ||
661 | chip->pcm[PLAY].num_streams = (dever >> 10) & 0x3ff; | ||
662 | chip->version = (dever >> 24) & 0xff; | ||
663 | snd_printdd(SFX "streams in=%d, out=%d, version=0x%x\n", | ||
664 | chip->pcm[CAPT].num_streams, chip->pcm[PLAY].num_streams, | ||
665 | chip->version); | ||
666 | |||
667 | /* Test LOLA_BAR1_DEVER */ | ||
668 | if (chip->pcm[CAPT].num_streams > MAX_STREAM_IN_COUNT || | ||
669 | chip->pcm[PLAY].num_streams > MAX_STREAM_OUT_COUNT || | ||
670 | (!chip->pcm[CAPT].num_streams && | ||
671 | !chip->pcm[PLAY].num_streams)) { | ||
672 | printk(KERN_ERR SFX "invalid DEVER = %x\n", dever); | ||
673 | err = -EINVAL; | ||
674 | goto errout; | ||
675 | } | ||
676 | |||
677 | err = setup_corb_rirb(chip); | ||
678 | if (err < 0) | ||
679 | goto errout; | ||
680 | |||
681 | err = snd_device_new(card, SNDRV_DEV_LOWLEVEL, chip, &ops); | ||
682 | if (err < 0) { | ||
683 | snd_printk(KERN_ERR SFX "Error creating device [card]!\n"); | ||
684 | goto errout; | ||
685 | } | ||
686 | |||
687 | strcpy(card->driver, "Lola"); | ||
688 | strlcpy(card->shortname, "Digigram Lola", sizeof(card->shortname)); | ||
689 | snprintf(card->longname, sizeof(card->longname), | ||
690 | "%s at 0x%lx irq %i", | ||
691 | card->shortname, chip->bar[0].addr, chip->irq); | ||
692 | strcpy(card->mixername, card->shortname); | ||
693 | |||
694 | lola_irq_enable(chip); | ||
695 | |||
696 | chip->initialized = 1; | ||
697 | *rchip = chip; | ||
698 | return 0; | ||
699 | |||
700 | errout: | ||
701 | lola_free(chip); | ||
702 | return err; | ||
703 | } | ||
704 | |||
705 | static int __devinit lola_probe(struct pci_dev *pci, | ||
706 | const struct pci_device_id *pci_id) | ||
707 | { | ||
708 | static int dev; | ||
709 | struct snd_card *card; | ||
710 | struct lola *chip; | ||
711 | int err; | ||
712 | |||
713 | if (dev >= SNDRV_CARDS) | ||
714 | return -ENODEV; | ||
715 | if (!enable[dev]) { | ||
716 | dev++; | ||
717 | return -ENOENT; | ||
718 | } | ||
719 | |||
720 | err = snd_card_create(index[dev], id[dev], THIS_MODULE, 0, &card); | ||
721 | if (err < 0) { | ||
722 | snd_printk(KERN_ERR SFX "Error creating card!\n"); | ||
723 | return err; | ||
724 | } | ||
725 | |||
726 | snd_card_set_dev(card, &pci->dev); | ||
727 | |||
728 | err = lola_create(card, pci, dev, &chip); | ||
729 | if (err < 0) | ||
730 | goto out_free; | ||
731 | card->private_data = chip; | ||
732 | |||
733 | err = lola_parse_tree(chip); | ||
734 | if (err < 0) | ||
735 | goto out_free; | ||
736 | |||
737 | err = lola_create_pcm(chip); | ||
738 | if (err < 0) | ||
739 | goto out_free; | ||
740 | |||
741 | err = lola_create_mixer(chip); | ||
742 | if (err < 0) | ||
743 | goto out_free; | ||
744 | |||
745 | lola_proc_debug_new(chip); | ||
746 | |||
747 | err = snd_card_register(card); | ||
748 | if (err < 0) | ||
749 | goto out_free; | ||
750 | |||
751 | pci_set_drvdata(pci, card); | ||
752 | dev++; | ||
753 | return err; | ||
754 | out_free: | ||
755 | snd_card_free(card); | ||
756 | return err; | ||
757 | } | ||
758 | |||
759 | static void __devexit lola_remove(struct pci_dev *pci) | ||
760 | { | ||
761 | snd_card_free(pci_get_drvdata(pci)); | ||
762 | pci_set_drvdata(pci, NULL); | ||
763 | } | ||
764 | |||
765 | /* PCI IDs */ | ||
766 | static DEFINE_PCI_DEVICE_TABLE(lola_ids) = { | ||
767 | { PCI_VDEVICE(DIGIGRAM, 0x0001) }, | ||
768 | { 0, } | ||
769 | }; | ||
770 | MODULE_DEVICE_TABLE(pci, lola_ids); | ||
771 | |||
772 | /* pci_driver definition */ | ||
773 | static struct pci_driver driver = { | ||
774 | .name = DRVNAME, | ||
775 | .id_table = lola_ids, | ||
776 | .probe = lola_probe, | ||
777 | .remove = __devexit_p(lola_remove), | ||
778 | }; | ||
779 | |||
780 | static int __init alsa_card_lola_init(void) | ||
781 | { | ||
782 | return pci_register_driver(&driver); | ||
783 | } | ||
784 | |||
785 | static void __exit alsa_card_lola_exit(void) | ||
786 | { | ||
787 | pci_unregister_driver(&driver); | ||
788 | } | ||
789 | |||
790 | module_init(alsa_card_lola_init) | ||
791 | module_exit(alsa_card_lola_exit) | ||
diff --git a/sound/pci/lola/lola.h b/sound/pci/lola/lola.h new file mode 100644 index 000000000000..d5708e29b16d --- /dev/null +++ b/sound/pci/lola/lola.h | |||
@@ -0,0 +1,527 @@ | |||
1 | /* | ||
2 | * Support for Digigram Lola PCI-e boards | ||
3 | * | ||
4 | * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation; either version 2 of the License, or (at your option) | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
18 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #ifndef _LOLA_H | ||
22 | #define _LOLA_H | ||
23 | |||
24 | #define DRVNAME "snd-lola" | ||
25 | #define SFX DRVNAME ": " | ||
26 | |||
27 | /* | ||
28 | * Lola HD Audio Registers BAR0 | ||
29 | */ | ||
30 | #define LOLA_BAR0_GCAP 0x00 | ||
31 | #define LOLA_BAR0_VMIN 0x02 | ||
32 | #define LOLA_BAR0_VMAJ 0x03 | ||
33 | #define LOLA_BAR0_OUTPAY 0x04 | ||
34 | #define LOLA_BAR0_INPAY 0x06 | ||
35 | #define LOLA_BAR0_GCTL 0x08 | ||
36 | #define LOLA_BAR0_WAKEEN 0x0c | ||
37 | #define LOLA_BAR0_STATESTS 0x0e | ||
38 | #define LOLA_BAR0_GSTS 0x10 | ||
39 | #define LOLA_BAR0_OUTSTRMPAY 0x18 | ||
40 | #define LOLA_BAR0_INSTRMPAY 0x1a | ||
41 | #define LOLA_BAR0_INTCTL 0x20 | ||
42 | #define LOLA_BAR0_INTSTS 0x24 | ||
43 | #define LOLA_BAR0_WALCLK 0x30 | ||
44 | #define LOLA_BAR0_SSYNC 0x38 | ||
45 | |||
46 | #define LOLA_BAR0_CORBLBASE 0x40 | ||
47 | #define LOLA_BAR0_CORBUBASE 0x44 | ||
48 | #define LOLA_BAR0_CORBWP 0x48 /* no ULONG access */ | ||
49 | #define LOLA_BAR0_CORBRP 0x4a /* no ULONG access */ | ||
50 | #define LOLA_BAR0_CORBCTL 0x4c /* no ULONG access */ | ||
51 | #define LOLA_BAR0_CORBSTS 0x4d /* UCHAR access only */ | ||
52 | #define LOLA_BAR0_CORBSIZE 0x4e /* no ULONG access */ | ||
53 | |||
54 | #define LOLA_BAR0_RIRBLBASE 0x50 | ||
55 | #define LOLA_BAR0_RIRBUBASE 0x54 | ||
56 | #define LOLA_BAR0_RIRBWP 0x58 | ||
57 | #define LOLA_BAR0_RINTCNT 0x5a /* no ULONG access */ | ||
58 | #define LOLA_BAR0_RIRBCTL 0x5c | ||
59 | #define LOLA_BAR0_RIRBSTS 0x5d /* UCHAR access only */ | ||
60 | #define LOLA_BAR0_RIRBSIZE 0x5e /* no ULONG access */ | ||
61 | |||
62 | #define LOLA_BAR0_ICW 0x60 | ||
63 | #define LOLA_BAR0_IRR 0x64 | ||
64 | #define LOLA_BAR0_ICS 0x68 | ||
65 | #define LOLA_BAR0_DPLBASE 0x70 | ||
66 | #define LOLA_BAR0_DPUBASE 0x74 | ||
67 | |||
68 | /* stream register offsets from stream base 0x80 */ | ||
69 | #define LOLA_BAR0_SD0_OFFSET 0x80 | ||
70 | #define LOLA_REG0_SD_CTL 0x00 | ||
71 | #define LOLA_REG0_SD_STS 0x03 | ||
72 | #define LOLA_REG0_SD_LPIB 0x04 | ||
73 | #define LOLA_REG0_SD_CBL 0x08 | ||
74 | #define LOLA_REG0_SD_LVI 0x0c | ||
75 | #define LOLA_REG0_SD_FIFOW 0x0e | ||
76 | #define LOLA_REG0_SD_FIFOSIZE 0x10 | ||
77 | #define LOLA_REG0_SD_FORMAT 0x12 | ||
78 | #define LOLA_REG0_SD_BDLPL 0x18 | ||
79 | #define LOLA_REG0_SD_BDLPU 0x1c | ||
80 | |||
81 | /* | ||
82 | * Lola Digigram Registers BAR1 | ||
83 | */ | ||
84 | #define LOLA_BAR1_FPGAVER 0x00 | ||
85 | #define LOLA_BAR1_DEVER 0x04 | ||
86 | #define LOLA_BAR1_UCBMV 0x08 | ||
87 | #define LOLA_BAR1_JTAG 0x0c | ||
88 | #define LOLA_BAR1_UARTRX 0x10 | ||
89 | #define LOLA_BAR1_UARTTX 0x14 | ||
90 | #define LOLA_BAR1_UARTCR 0x18 | ||
91 | #define LOLA_BAR1_NVRAMVER 0x1c | ||
92 | #define LOLA_BAR1_CTRLSPI 0x20 | ||
93 | #define LOLA_BAR1_DSPI 0x24 | ||
94 | #define LOLA_BAR1_AISPI 0x28 | ||
95 | #define LOLA_BAR1_GRAN 0x2c | ||
96 | |||
97 | #define LOLA_BAR1_DINTCTL 0x80 | ||
98 | #define LOLA_BAR1_DIINTCTL 0x84 | ||
99 | #define LOLA_BAR1_DOINTCTL 0x88 | ||
100 | #define LOLA_BAR1_LRC 0x90 | ||
101 | #define LOLA_BAR1_DINTSTS 0x94 | ||
102 | #define LOLA_BAR1_DIINTSTS 0x98 | ||
103 | #define LOLA_BAR1_DOINTSTS 0x9c | ||
104 | |||
105 | #define LOLA_BAR1_DSD0_OFFSET 0xa0 | ||
106 | #define LOLA_BAR1_DSD_SIZE 0x18 | ||
107 | |||
108 | #define LOLA_BAR1_DSDnSTS 0x00 | ||
109 | #define LOLA_BAR1_DSDnLPIB 0x04 | ||
110 | #define LOLA_BAR1_DSDnCTL 0x08 | ||
111 | #define LOLA_BAR1_DSDnLVI 0x0c | ||
112 | #define LOLA_BAR1_DSDnBDPL 0x10 | ||
113 | #define LOLA_BAR1_DSDnBDPU 0x14 | ||
114 | |||
115 | #define LOLA_BAR1_SSYNC 0x03e8 | ||
116 | |||
117 | #define LOLA_BAR1_BOARD_CTRL 0x0f00 | ||
118 | #define LOLA_BAR1_BOARD_MODE 0x0f02 | ||
119 | |||
120 | #define LOLA_BAR1_SOURCE_GAIN_ENABLE 0x1000 | ||
121 | #define LOLA_BAR1_DEST00_MIX_GAIN_ENABLE 0x1004 | ||
122 | #define LOLA_BAR1_DEST31_MIX_GAIN_ENABLE 0x1080 | ||
123 | #define LOLA_BAR1_SOURCE00_01_GAIN 0x1084 | ||
124 | #define LOLA_BAR1_SOURCE30_31_GAIN 0x10c0 | ||
125 | #define LOLA_BAR1_SOURCE_GAIN(src) \ | ||
126 | (LOLA_BAR1_SOURCE00_01_GAIN + (src) * 2) | ||
127 | #define LOLA_BAR1_DEST00_MIX00_01_GAIN 0x10c4 | ||
128 | #define LOLA_BAR1_DEST00_MIX30_31_GAIN 0x1100 | ||
129 | #define LOLA_BAR1_DEST01_MIX00_01_GAIN 0x1104 | ||
130 | #define LOLA_BAR1_DEST01_MIX30_31_GAIN 0x1140 | ||
131 | #define LOLA_BAR1_DEST31_MIX00_01_GAIN 0x1884 | ||
132 | #define LOLA_BAR1_DEST31_MIX30_31_GAIN 0x18c0 | ||
133 | #define LOLA_BAR1_MIX_GAIN(dest, mix) \ | ||
134 | (LOLA_BAR1_DEST00_MIX00_01_GAIN + (dest) * 0x40 + (mix) * 2) | ||
135 | #define LOLA_BAR1_ANALOG_CLIP_IN 0x18c4 | ||
136 | #define LOLA_BAR1_PEAKMETERS_SOURCE00_01 0x18c8 | ||
137 | #define LOLA_BAR1_PEAKMETERS_SOURCE30_31 0x1904 | ||
138 | #define LOLA_BAR1_PEAKMETERS_SOURCE(src) \ | ||
139 | (LOLA_BAR1_PEAKMETERS_SOURCE00_01 + (src) * 2) | ||
140 | #define LOLA_BAR1_PEAKMETERS_DEST00_01 0x1908 | ||
141 | #define LOLA_BAR1_PEAKMETERS_DEST30_31 0x1944 | ||
142 | #define LOLA_BAR1_PEAKMETERS_DEST(dest) \ | ||
143 | (LOLA_BAR1_PEAKMETERS_DEST00_01 + (dest) * 2) | ||
144 | #define LOLA_BAR1_PEAKMETERS_AGC00_01 0x1948 | ||
145 | #define LOLA_BAR1_PEAKMETERS_AGC14_15 0x1964 | ||
146 | #define LOLA_BAR1_PEAKMETERS_AGC(x) \ | ||
147 | (LOLA_BAR1_PEAKMETERS_AGC00_01 + (x) * 2) | ||
148 | |||
149 | /* GCTL reset bit */ | ||
150 | #define LOLA_GCTL_RESET (1 << 0) | ||
151 | /* GCTL unsolicited response enable bit */ | ||
152 | #define LOLA_GCTL_UREN (1 << 8) | ||
153 | |||
154 | /* CORB/RIRB control, read/write pointer */ | ||
155 | #define LOLA_RBCTL_DMA_EN 0x02 /* enable DMA */ | ||
156 | #define LOLA_RBCTL_IRQ_EN 0x01 /* enable IRQ */ | ||
157 | #define LOLA_RBRWP_CLR 0x8000 /* read/write pointer clear */ | ||
158 | |||
159 | #define LOLA_RIRB_EX_UNSOL_EV 0x40000000 | ||
160 | #define LOLA_RIRB_EX_ERROR 0x80000000 | ||
161 | |||
162 | /* CORB int mask: CMEI[0] */ | ||
163 | #define LOLA_CORB_INT_CMEI 0x01 | ||
164 | #define LOLA_CORB_INT_MASK LOLA_CORB_INT_CMEI | ||
165 | |||
166 | /* RIRB int mask: overrun[2], response[0] */ | ||
167 | #define LOLA_RIRB_INT_RESPONSE 0x01 | ||
168 | #define LOLA_RIRB_INT_OVERRUN 0x04 | ||
169 | #define LOLA_RIRB_INT_MASK (LOLA_RIRB_INT_RESPONSE | LOLA_RIRB_INT_OVERRUN) | ||
170 | |||
171 | /* DINTCTL and DINTSTS */ | ||
172 | #define LOLA_DINT_GLOBAL 0x80000000 /* global interrupt enable bit */ | ||
173 | #define LOLA_DINT_CTRL 0x40000000 /* controller interrupt enable bit */ | ||
174 | #define LOLA_DINT_FIFOERR 0x20000000 /* global fifo error enable bit */ | ||
175 | #define LOLA_DINT_MUERR 0x10000000 /* global microcontroller underrun error */ | ||
176 | |||
177 | /* DSDnCTL bits */ | ||
178 | #define LOLA_DSD_CTL_SRST 0x01 /* stream reset bit */ | ||
179 | #define LOLA_DSD_CTL_SRUN 0x02 /* stream DMA start bit */ | ||
180 | #define LOLA_DSD_CTL_IOCE 0x04 /* interrupt on completion enable */ | ||
181 | #define LOLA_DSD_CTL_DEIE 0x10 /* descriptor error interrupt enable */ | ||
182 | #define LOLA_DSD_CTL_VLRCV 0x20 /* valid LRCountValue information in bits 8..31 */ | ||
183 | #define LOLA_LRC_MASK 0xffffff00 | ||
184 | |||
185 | /* DSDnSTS */ | ||
186 | #define LOLA_DSD_STS_BCIS 0x04 /* buffer completion interrupt status */ | ||
187 | #define LOLA_DSD_STS_DESE 0x10 /* descriptor error interrupt */ | ||
188 | #define LOLA_DSD_STS_FIFORDY 0x20 /* fifo ready */ | ||
189 | |||
190 | #define LOLA_CORB_ENTRIES 256 | ||
191 | |||
192 | #define MAX_STREAM_IN_COUNT 16 | ||
193 | #define MAX_STREAM_OUT_COUNT 16 | ||
194 | #define MAX_STREAM_COUNT 16 | ||
195 | #define MAX_PINS MAX_STREAM_COUNT | ||
196 | #define MAX_STREAM_BUFFER_COUNT 16 | ||
197 | #define MAX_AUDIO_INOUT_COUNT 16 | ||
198 | |||
199 | #define LOLA_CLOCK_TYPE_INTERNAL 0 | ||
200 | #define LOLA_CLOCK_TYPE_AES 1 | ||
201 | #define LOLA_CLOCK_TYPE_AES_SYNC 2 | ||
202 | #define LOLA_CLOCK_TYPE_WORDCLOCK 3 | ||
203 | #define LOLA_CLOCK_TYPE_ETHERSOUND 4 | ||
204 | #define LOLA_CLOCK_TYPE_VIDEO 5 | ||
205 | |||
206 | #define LOLA_CLOCK_FORMAT_NONE 0 | ||
207 | #define LOLA_CLOCK_FORMAT_NTSC 1 | ||
208 | #define LOLA_CLOCK_FORMAT_PAL 2 | ||
209 | |||
210 | #define MAX_SAMPLE_CLOCK_COUNT 48 | ||
211 | |||
212 | /* parameters used with mixer widget's mixer capabilities */ | ||
213 | #define LOLA_PEAK_METER_CAN_AGC_MASK 1 | ||
214 | #define LOLA_PEAK_METER_CAN_ANALOG_CLIP_MASK 2 | ||
215 | |||
216 | struct lola_bar { | ||
217 | unsigned long addr; | ||
218 | void __iomem *remap_addr; | ||
219 | }; | ||
220 | |||
221 | /* CORB/RIRB */ | ||
222 | struct lola_rb { | ||
223 | u32 *buf; /* CORB/RIRB buffer, 8 byte per each entry */ | ||
224 | dma_addr_t addr; /* physical address of CORB/RIRB buffer */ | ||
225 | unsigned short rp, wp; /* read/write pointers */ | ||
226 | int cmds; /* number of pending requests */ | ||
227 | }; | ||
228 | |||
229 | /* Pin widget setup */ | ||
230 | struct lola_pin { | ||
231 | unsigned int nid; | ||
232 | bool is_analog; | ||
233 | unsigned int amp_mute; | ||
234 | unsigned int amp_step_size; | ||
235 | unsigned int amp_num_steps; | ||
236 | unsigned int amp_offset; | ||
237 | unsigned int max_level; | ||
238 | unsigned int config_default_reg; | ||
239 | unsigned int fixed_gain_list_len; | ||
240 | unsigned int cur_gain_step; | ||
241 | }; | ||
242 | |||
243 | struct lola_pin_array { | ||
244 | unsigned int num_pins; | ||
245 | unsigned int num_analog_pins; | ||
246 | struct lola_pin pins[MAX_PINS]; | ||
247 | }; | ||
248 | |||
249 | /* Clock widget setup */ | ||
250 | struct lola_sample_clock { | ||
251 | unsigned int type; | ||
252 | unsigned int format; | ||
253 | unsigned int freq; | ||
254 | }; | ||
255 | |||
256 | struct lola_clock_widget { | ||
257 | unsigned int nid; | ||
258 | unsigned int items; | ||
259 | unsigned int cur_index; | ||
260 | unsigned int cur_freq; | ||
261 | bool cur_valid; | ||
262 | struct lola_sample_clock sample_clock[MAX_SAMPLE_CLOCK_COUNT]; | ||
263 | unsigned int idx_lookup[MAX_SAMPLE_CLOCK_COUNT]; | ||
264 | }; | ||
265 | |||
266 | #define LOLA_MIXER_DIM 32 | ||
267 | struct lola_mixer_array { | ||
268 | u32 src_gain_enable; | ||
269 | u32 dest_mix_gain_enable[LOLA_MIXER_DIM]; | ||
270 | u16 src_gain[LOLA_MIXER_DIM]; | ||
271 | u16 dest_mix_gain[LOLA_MIXER_DIM][LOLA_MIXER_DIM]; | ||
272 | }; | ||
273 | |||
274 | /* Mixer widget setup */ | ||
275 | struct lola_mixer_widget { | ||
276 | unsigned int nid; | ||
277 | unsigned int caps; | ||
278 | struct lola_mixer_array __user *array; | ||
279 | struct lola_mixer_array *array_saved; | ||
280 | unsigned int src_stream_outs; | ||
281 | unsigned int src_phys_ins; | ||
282 | unsigned int dest_stream_ins; | ||
283 | unsigned int dest_phys_outs; | ||
284 | unsigned int src_stream_out_ofs; | ||
285 | unsigned int dest_phys_out_ofs; | ||
286 | unsigned int src_mask; | ||
287 | unsigned int dest_mask; | ||
288 | }; | ||
289 | |||
290 | /* Audio stream */ | ||
291 | struct lola_stream { | ||
292 | unsigned int nid; /* audio widget NID */ | ||
293 | unsigned int index; /* array index */ | ||
294 | unsigned int dsd; /* DSD index */ | ||
295 | bool can_float; | ||
296 | struct snd_pcm_substream *substream; /* assigned PCM substream */ | ||
297 | struct lola_stream *master; /* master stream (for multi-channel) */ | ||
298 | |||
299 | /* buffer setup */ | ||
300 | unsigned int bufsize; | ||
301 | unsigned int period_bytes; | ||
302 | unsigned int frags; | ||
303 | |||
304 | /* format + channel setup */ | ||
305 | unsigned int format_verb; | ||
306 | |||
307 | /* flags */ | ||
308 | unsigned int opened:1; | ||
309 | unsigned int prepared:1; | ||
310 | unsigned int paused:1; | ||
311 | unsigned int running:1; | ||
312 | }; | ||
313 | |||
314 | #define PLAY SNDRV_PCM_STREAM_PLAYBACK | ||
315 | #define CAPT SNDRV_PCM_STREAM_CAPTURE | ||
316 | |||
317 | struct lola_pcm { | ||
318 | unsigned int num_streams; | ||
319 | struct snd_dma_buffer bdl; /* BDL buffer */ | ||
320 | struct lola_stream streams[MAX_STREAM_COUNT]; | ||
321 | }; | ||
322 | |||
323 | /* card instance */ | ||
324 | struct lola { | ||
325 | struct snd_card *card; | ||
326 | struct pci_dev *pci; | ||
327 | |||
328 | /* pci resources */ | ||
329 | struct lola_bar bar[2]; | ||
330 | int irq; | ||
331 | |||
332 | /* locks */ | ||
333 | spinlock_t reg_lock; | ||
334 | struct mutex open_mutex; | ||
335 | |||
336 | /* CORB/RIRB */ | ||
337 | struct lola_rb corb; | ||
338 | struct lola_rb rirb; | ||
339 | unsigned int res, res_ex; /* last read values */ | ||
340 | /* last command (for debugging) */ | ||
341 | unsigned int last_cmd_nid, last_verb, last_data, last_extdata; | ||
342 | |||
343 | /* CORB/RIRB buffers */ | ||
344 | struct snd_dma_buffer rb; | ||
345 | |||
346 | /* unsolicited events */ | ||
347 | unsigned int last_unsol_res; | ||
348 | |||
349 | /* streams */ | ||
350 | struct lola_pcm pcm[2]; | ||
351 | |||
352 | /* input src */ | ||
353 | unsigned int input_src_caps_mask; | ||
354 | unsigned int input_src_mask; | ||
355 | |||
356 | /* pins */ | ||
357 | struct lola_pin_array pin[2]; | ||
358 | |||
359 | /* clock */ | ||
360 | struct lola_clock_widget clock; | ||
361 | int ref_count_rate; | ||
362 | unsigned int sample_rate; | ||
363 | |||
364 | /* mixer */ | ||
365 | struct lola_mixer_widget mixer; | ||
366 | |||
367 | /* hw info */ | ||
368 | unsigned int version; | ||
369 | unsigned int lola_caps; | ||
370 | |||
371 | /* parameters */ | ||
372 | unsigned int granularity; | ||
373 | unsigned int sample_rate_min; | ||
374 | unsigned int sample_rate_max; | ||
375 | |||
376 | /* flags */ | ||
377 | unsigned int initialized:1; | ||
378 | unsigned int cold_reset:1; | ||
379 | unsigned int polling_mode:1; | ||
380 | |||
381 | /* for debugging */ | ||
382 | unsigned int debug_res; | ||
383 | unsigned int debug_res_ex; | ||
384 | }; | ||
385 | |||
386 | #define BAR0 0 | ||
387 | #define BAR1 1 | ||
388 | |||
389 | /* Helper macros */ | ||
390 | #define lola_readl(chip, idx, name) \ | ||
391 | readl((chip)->bar[idx].remap_addr + LOLA_##idx##_##name) | ||
392 | #define lola_readw(chip, idx, name) \ | ||
393 | readw((chip)->bar[idx].remap_addr + LOLA_##idx##_##name) | ||
394 | #define lola_readb(chip, idx, name) \ | ||
395 | readb((chip)->bar[idx].remap_addr + LOLA_##idx##_##name) | ||
396 | #define lola_writel(chip, idx, name, val) \ | ||
397 | writel((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name) | ||
398 | #define lola_writew(chip, idx, name, val) \ | ||
399 | writew((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name) | ||
400 | #define lola_writeb(chip, idx, name, val) \ | ||
401 | writeb((val), (chip)->bar[idx].remap_addr + LOLA_##idx##_##name) | ||
402 | |||
403 | #define lola_dsd_read(chip, dsd, name) \ | ||
404 | readl((chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \ | ||
405 | (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name) | ||
406 | #define lola_dsd_write(chip, dsd, name, val) \ | ||
407 | writel((val), (chip)->bar[BAR1].remap_addr + LOLA_BAR1_DSD0_OFFSET + \ | ||
408 | (LOLA_BAR1_DSD_SIZE * (dsd)) + LOLA_BAR1_DSDn##name) | ||
409 | |||
410 | /* GET verbs HDAudio */ | ||
411 | #define LOLA_VERB_GET_STREAM_FORMAT 0xa00 | ||
412 | #define LOLA_VERB_GET_AMP_GAIN_MUTE 0xb00 | ||
413 | #define LOLA_VERB_PARAMETERS 0xf00 | ||
414 | #define LOLA_VERB_GET_POWER_STATE 0xf05 | ||
415 | #define LOLA_VERB_GET_CONV 0xf06 | ||
416 | #define LOLA_VERB_GET_UNSOLICITED_RESPONSE 0xf08 | ||
417 | #define LOLA_VERB_GET_DIGI_CONVERT_1 0xf0d | ||
418 | #define LOLA_VERB_GET_CONFIG_DEFAULT 0xf1c | ||
419 | #define LOLA_VERB_GET_SUBSYSTEM_ID 0xf20 | ||
420 | /* GET verbs Digigram */ | ||
421 | #define LOLA_VERB_GET_FIXED_GAIN 0xfc0 | ||
422 | #define LOLA_VERB_GET_GAIN_SELECT 0xfc1 | ||
423 | #define LOLA_VERB_GET_MAX_LEVEL 0xfc2 | ||
424 | #define LOLA_VERB_GET_CLOCK_LIST 0xfc3 | ||
425 | #define LOLA_VERB_GET_CLOCK_SELECT 0xfc4 | ||
426 | #define LOLA_VERB_GET_CLOCK_STATUS 0xfc5 | ||
427 | |||
428 | /* SET verbs HDAudio */ | ||
429 | #define LOLA_VERB_SET_STREAM_FORMAT 0x200 | ||
430 | #define LOLA_VERB_SET_AMP_GAIN_MUTE 0x300 | ||
431 | #define LOLA_VERB_SET_POWER_STATE 0x705 | ||
432 | #define LOLA_VERB_SET_CHANNEL_STREAMID 0x706 | ||
433 | #define LOLA_VERB_SET_UNSOLICITED_ENABLE 0x708 | ||
434 | #define LOLA_VERB_SET_DIGI_CONVERT_1 0x70d | ||
435 | /* SET verbs Digigram */ | ||
436 | #define LOLA_VERB_SET_GAIN_SELECT 0xf81 | ||
437 | #define LOLA_VERB_SET_CLOCK_SELECT 0xf84 | ||
438 | #define LOLA_VERB_SET_GRANULARITY_STEPS 0xf86 | ||
439 | #define LOLA_VERB_SET_SOURCE_GAIN 0xf87 | ||
440 | #define LOLA_VERB_SET_MIX_GAIN 0xf88 | ||
441 | #define LOLA_VERB_SET_DESTINATION_GAIN 0xf89 | ||
442 | #define LOLA_VERB_SET_SRC 0xf8a | ||
443 | |||
444 | /* Parameter IDs used with LOLA_VERB_PARAMETERS */ | ||
445 | #define LOLA_PAR_VENDOR_ID 0x00 | ||
446 | #define LOLA_PAR_FUNCTION_TYPE 0x05 | ||
447 | #define LOLA_PAR_AUDIO_WIDGET_CAP 0x09 | ||
448 | #define LOLA_PAR_PCM 0x0a | ||
449 | #define LOLA_PAR_STREAM_FORMATS 0x0b | ||
450 | #define LOLA_PAR_PIN_CAP 0x0c | ||
451 | #define LOLA_PAR_AMP_IN_CAP 0x0d | ||
452 | #define LOLA_PAR_CONNLIST_LEN 0x0e | ||
453 | #define LOLA_PAR_POWER_STATE 0x0f | ||
454 | #define LOLA_PAR_GPIO_CAP 0x11 | ||
455 | #define LOLA_PAR_AMP_OUT_CAP 0x12 | ||
456 | #define LOLA_PAR_SPECIFIC_CAPS 0x80 | ||
457 | #define LOLA_PAR_FIXED_GAIN_LIST 0x81 | ||
458 | |||
459 | /* extract results of LOLA_PAR_SPECIFIC_CAPS */ | ||
460 | #define LOLA_AFG_MIXER_WIDGET_PRESENT(res) ((res & (1 << 21)) != 0) | ||
461 | #define LOLA_AFG_CLOCK_WIDGET_PRESENT(res) ((res & (1 << 20)) != 0) | ||
462 | #define LOLA_AFG_INPUT_PIN_COUNT(res) ((res >> 10) & 0x2ff) | ||
463 | #define LOLA_AFG_OUTPUT_PIN_COUNT(res) ((res) & 0x2ff) | ||
464 | |||
465 | /* extract results of LOLA_PAR_AMP_IN_CAP / LOLA_PAR_AMP_OUT_CAP */ | ||
466 | #define LOLA_AMP_MUTE_CAPABLE(res) ((res & (1 << 31)) != 0) | ||
467 | #define LOLA_AMP_STEP_SIZE(res) ((res >> 24) & 0x7f) | ||
468 | #define LOLA_AMP_NUM_STEPS(res) ((res >> 12) & 0x3ff) | ||
469 | #define LOLA_AMP_OFFSET(res) ((res) & 0x3ff) | ||
470 | |||
471 | #define LOLA_GRANULARITY_MIN 8 | ||
472 | #define LOLA_GRANULARITY_MAX 32 | ||
473 | #define LOLA_GRANULARITY_STEP 8 | ||
474 | |||
475 | /* parameters used with unsolicited command/response */ | ||
476 | #define LOLA_UNSOLICITED_TAG_MASK 0x3f | ||
477 | #define LOLA_UNSOLICITED_TAG 0x1a | ||
478 | #define LOLA_UNSOLICITED_ENABLE 0x80 | ||
479 | #define LOLA_UNSOL_RESP_TAG_OFFSET 26 | ||
480 | |||
481 | /* count values in the Vendor Specific Mixer Widget's Audio Widget Capabilities */ | ||
482 | #define LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(res) ((res >> 2) & 0x1f) | ||
483 | #define LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(res) ((res >> 7) & 0x1f) | ||
484 | |||
485 | int lola_codec_write(struct lola *chip, unsigned int nid, unsigned int verb, | ||
486 | unsigned int data, unsigned int extdata); | ||
487 | int lola_codec_read(struct lola *chip, unsigned int nid, unsigned int verb, | ||
488 | unsigned int data, unsigned int extdata, | ||
489 | unsigned int *val, unsigned int *extval); | ||
490 | int lola_codec_flush(struct lola *chip); | ||
491 | #define lola_read_param(chip, nid, param, val) \ | ||
492 | lola_codec_read(chip, nid, LOLA_VERB_PARAMETERS, param, 0, val, NULL) | ||
493 | |||
494 | /* PCM */ | ||
495 | int lola_create_pcm(struct lola *chip); | ||
496 | void lola_free_pcm(struct lola *chip); | ||
497 | int lola_init_pcm(struct lola *chip, int dir, int *nidp); | ||
498 | void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits); | ||
499 | |||
500 | /* clock */ | ||
501 | int lola_init_clock_widget(struct lola *chip, int nid); | ||
502 | int lola_set_granularity(struct lola *chip, unsigned int val, bool force); | ||
503 | int lola_enable_clock_events(struct lola *chip); | ||
504 | int lola_set_clock_index(struct lola *chip, unsigned int idx); | ||
505 | int lola_set_clock(struct lola *chip, int idx); | ||
506 | int lola_set_sample_rate(struct lola *chip, int rate); | ||
507 | bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val); | ||
508 | unsigned int lola_sample_rate_convert(unsigned int coded); | ||
509 | |||
510 | /* mixer */ | ||
511 | int lola_init_pins(struct lola *chip, int dir, int *nidp); | ||
512 | int lola_init_mixer_widget(struct lola *chip, int nid); | ||
513 | void lola_free_mixer(struct lola *chip); | ||
514 | int lola_create_mixer(struct lola *chip); | ||
515 | int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute); | ||
516 | void lola_save_mixer(struct lola *chip); | ||
517 | void lola_restore_mixer(struct lola *chip); | ||
518 | int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update); | ||
519 | |||
520 | /* proc */ | ||
521 | #ifdef CONFIG_SND_DEBUG | ||
522 | void lola_proc_debug_new(struct lola *chip); | ||
523 | #else | ||
524 | #define lola_proc_debug_new(chip) | ||
525 | #endif | ||
526 | |||
527 | #endif /* _LOLA_H */ | ||
diff --git a/sound/pci/lola/lola_clock.c b/sound/pci/lola/lola_clock.c new file mode 100644 index 000000000000..72f8ef0ac865 --- /dev/null +++ b/sound/pci/lola/lola_clock.c | |||
@@ -0,0 +1,323 @@ | |||
1 | /* | ||
2 | * Support for Digigram Lola PCI-e boards | ||
3 | * | ||
4 | * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation; either version 2 of the License, or (at your option) | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
18 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/delay.h> | ||
24 | #include <sound/core.h> | ||
25 | #include <sound/pcm.h> | ||
26 | #include "lola.h" | ||
27 | |||
28 | unsigned int lola_sample_rate_convert(unsigned int coded) | ||
29 | { | ||
30 | unsigned int freq; | ||
31 | |||
32 | /* base frequency */ | ||
33 | switch (coded & 0x3) { | ||
34 | case 0: freq = 48000; break; | ||
35 | case 1: freq = 44100; break; | ||
36 | case 2: freq = 32000; break; | ||
37 | default: return 0; /* error */ | ||
38 | } | ||
39 | |||
40 | /* multiplier / devisor */ | ||
41 | switch (coded & 0x1c) { | ||
42 | case (0 << 2): break; | ||
43 | case (4 << 2): break; | ||
44 | case (1 << 2): freq *= 2; break; | ||
45 | case (2 << 2): freq *= 4; break; | ||
46 | case (5 << 2): freq /= 2; break; | ||
47 | case (6 << 2): freq /= 4; break; | ||
48 | default: return 0; /* error */ | ||
49 | } | ||
50 | |||
51 | /* ajustement */ | ||
52 | switch (coded & 0x60) { | ||
53 | case (0 << 5): break; | ||
54 | case (1 << 5): freq = (freq * 999) / 1000; break; | ||
55 | case (2 << 5): freq = (freq * 1001) / 1000; break; | ||
56 | default: return 0; /* error */ | ||
57 | } | ||
58 | return freq; | ||
59 | } | ||
60 | |||
61 | /* | ||
62 | * Granualrity | ||
63 | */ | ||
64 | |||
65 | #define LOLA_MAXFREQ_AT_GRANULARITY_MIN 48000 | ||
66 | #define LOLA_MAXFREQ_AT_GRANULARITY_BELOW_MAX 96000 | ||
67 | |||
68 | static bool check_gran_clock_compatibility(struct lola *chip, | ||
69 | unsigned int val, | ||
70 | unsigned int freq) | ||
71 | { | ||
72 | if (!chip->granularity) | ||
73 | return true; | ||
74 | |||
75 | if (val < LOLA_GRANULARITY_MIN || val > LOLA_GRANULARITY_MAX || | ||
76 | (val % LOLA_GRANULARITY_STEP) != 0) | ||
77 | return false; | ||
78 | |||
79 | if (val == LOLA_GRANULARITY_MIN) { | ||
80 | if (freq > LOLA_MAXFREQ_AT_GRANULARITY_MIN) | ||
81 | return false; | ||
82 | } else if (val < LOLA_GRANULARITY_MAX) { | ||
83 | if (freq > LOLA_MAXFREQ_AT_GRANULARITY_BELOW_MAX) | ||
84 | return false; | ||
85 | } | ||
86 | return true; | ||
87 | } | ||
88 | |||
89 | int lola_set_granularity(struct lola *chip, unsigned int val, bool force) | ||
90 | { | ||
91 | int err; | ||
92 | |||
93 | if (!force) { | ||
94 | if (val == chip->granularity) | ||
95 | return 0; | ||
96 | #if 0 | ||
97 | /* change Gran only if there are no streams allocated ! */ | ||
98 | if (chip->audio_in_alloc_mask || chip->audio_out_alloc_mask) | ||
99 | return -EBUSY; | ||
100 | #endif | ||
101 | if (!check_gran_clock_compatibility(chip, val, | ||
102 | chip->clock.cur_freq)) | ||
103 | return -EINVAL; | ||
104 | } | ||
105 | |||
106 | chip->granularity = val; | ||
107 | val /= LOLA_GRANULARITY_STEP; | ||
108 | |||
109 | /* audio function group */ | ||
110 | err = lola_codec_write(chip, 1, LOLA_VERB_SET_GRANULARITY_STEPS, | ||
111 | val, 0); | ||
112 | if (err < 0) | ||
113 | return err; | ||
114 | /* this can be a very slow function !!! */ | ||
115 | usleep_range(400 * val, 20000); | ||
116 | return lola_codec_flush(chip); | ||
117 | } | ||
118 | |||
119 | /* | ||
120 | * Clock widget handling | ||
121 | */ | ||
122 | |||
123 | int __devinit lola_init_clock_widget(struct lola *chip, int nid) | ||
124 | { | ||
125 | unsigned int val; | ||
126 | int i, j, nitems, nb_verbs, idx, idx_list; | ||
127 | int err; | ||
128 | |||
129 | err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); | ||
130 | if (err < 0) { | ||
131 | printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid); | ||
132 | return err; | ||
133 | } | ||
134 | |||
135 | if ((val & 0xfff00000) != 0x01f00000) { /* test SubType and Type */ | ||
136 | snd_printdd("No valid clock widget\n"); | ||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | chip->clock.nid = nid; | ||
141 | chip->clock.items = val & 0xff; | ||
142 | snd_printdd("clock_list nid=%x, entries=%d\n", nid, | ||
143 | chip->clock.items); | ||
144 | if (chip->clock.items > MAX_SAMPLE_CLOCK_COUNT) { | ||
145 | printk(KERN_ERR SFX "CLOCK_LIST too big: %d\n", | ||
146 | chip->clock.items); | ||
147 | return -EINVAL; | ||
148 | } | ||
149 | |||
150 | nitems = chip->clock.items; | ||
151 | nb_verbs = (nitems + 3) / 4; | ||
152 | idx = 0; | ||
153 | idx_list = 0; | ||
154 | for (i = 0; i < nb_verbs; i++) { | ||
155 | unsigned int res_ex; | ||
156 | unsigned short items[4]; | ||
157 | |||
158 | err = lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST, | ||
159 | idx, 0, &val, &res_ex); | ||
160 | if (err < 0) { | ||
161 | printk(KERN_ERR SFX "Can't read CLOCK_LIST\n"); | ||
162 | return -EINVAL; | ||
163 | } | ||
164 | |||
165 | items[0] = val & 0xfff; | ||
166 | items[1] = (val >> 16) & 0xfff; | ||
167 | items[2] = res_ex & 0xfff; | ||
168 | items[3] = (res_ex >> 16) & 0xfff; | ||
169 | |||
170 | for (j = 0; j < 4; j++) { | ||
171 | unsigned char type = items[j] >> 8; | ||
172 | unsigned int freq = items[j] & 0xff; | ||
173 | int format = LOLA_CLOCK_FORMAT_NONE; | ||
174 | bool add_clock = true; | ||
175 | if (type == LOLA_CLOCK_TYPE_INTERNAL) { | ||
176 | freq = lola_sample_rate_convert(freq); | ||
177 | if (freq < chip->sample_rate_min) | ||
178 | add_clock = false; | ||
179 | else if (freq == 48000) { | ||
180 | chip->clock.cur_index = idx_list; | ||
181 | chip->clock.cur_freq = 48000; | ||
182 | chip->clock.cur_valid = true; | ||
183 | } | ||
184 | } else if (type == LOLA_CLOCK_TYPE_VIDEO) { | ||
185 | freq = lola_sample_rate_convert(freq); | ||
186 | if (freq < chip->sample_rate_min) | ||
187 | add_clock = false; | ||
188 | /* video clock has a format (0:NTSC, 1:PAL)*/ | ||
189 | if (items[j] & 0x80) | ||
190 | format = LOLA_CLOCK_FORMAT_NTSC; | ||
191 | else | ||
192 | format = LOLA_CLOCK_FORMAT_PAL; | ||
193 | } | ||
194 | if (add_clock) { | ||
195 | struct lola_sample_clock *sc; | ||
196 | sc = &chip->clock.sample_clock[idx_list]; | ||
197 | sc->type = type; | ||
198 | sc->format = format; | ||
199 | sc->freq = freq; | ||
200 | /* keep the index used with the board */ | ||
201 | chip->clock.idx_lookup[idx_list] = idx; | ||
202 | idx_list++; | ||
203 | } else { | ||
204 | chip->clock.items--; | ||
205 | } | ||
206 | if (++idx >= nitems) | ||
207 | break; | ||
208 | } | ||
209 | } | ||
210 | return 0; | ||
211 | } | ||
212 | |||
213 | /* enable unsolicited events of the clock widget */ | ||
214 | int lola_enable_clock_events(struct lola *chip) | ||
215 | { | ||
216 | unsigned int res; | ||
217 | int err; | ||
218 | |||
219 | err = lola_codec_read(chip, chip->clock.nid, | ||
220 | LOLA_VERB_SET_UNSOLICITED_ENABLE, | ||
221 | LOLA_UNSOLICITED_ENABLE | LOLA_UNSOLICITED_TAG, | ||
222 | 0, &res, NULL); | ||
223 | if (err < 0) | ||
224 | return err; | ||
225 | if (res) { | ||
226 | printk(KERN_WARNING SFX "error in enable_clock_events %d\n", | ||
227 | res); | ||
228 | return -EINVAL; | ||
229 | } | ||
230 | return 0; | ||
231 | } | ||
232 | |||
233 | int lola_set_clock_index(struct lola *chip, unsigned int idx) | ||
234 | { | ||
235 | unsigned int res; | ||
236 | int err; | ||
237 | |||
238 | err = lola_codec_read(chip, chip->clock.nid, | ||
239 | LOLA_VERB_SET_CLOCK_SELECT, | ||
240 | chip->clock.idx_lookup[idx], | ||
241 | 0, &res, NULL); | ||
242 | if (err < 0) | ||
243 | return err; | ||
244 | if (res) { | ||
245 | printk(KERN_WARNING SFX "error in set_clock %d\n", res); | ||
246 | return -EINVAL; | ||
247 | } | ||
248 | return 0; | ||
249 | } | ||
250 | |||
251 | bool lola_update_ext_clock_freq(struct lola *chip, unsigned int val) | ||
252 | { | ||
253 | unsigned int tag; | ||
254 | |||
255 | /* the current EXTERNAL clock information gets updated by interrupt | ||
256 | * with an unsolicited response | ||
257 | */ | ||
258 | if (!val) | ||
259 | return false; | ||
260 | tag = (val >> LOLA_UNSOL_RESP_TAG_OFFSET) & LOLA_UNSOLICITED_TAG_MASK; | ||
261 | if (tag != LOLA_UNSOLICITED_TAG) | ||
262 | return false; | ||
263 | |||
264 | /* only for current = external clocks */ | ||
265 | if (chip->clock.sample_clock[chip->clock.cur_index].type != | ||
266 | LOLA_CLOCK_TYPE_INTERNAL) { | ||
267 | chip->clock.cur_freq = lola_sample_rate_convert(val & 0x7f); | ||
268 | chip->clock.cur_valid = (val & 0x100) != 0; | ||
269 | } | ||
270 | return true; | ||
271 | } | ||
272 | |||
273 | int lola_set_clock(struct lola *chip, int idx) | ||
274 | { | ||
275 | int freq = 0; | ||
276 | bool valid = false; | ||
277 | |||
278 | if (idx == chip->clock.cur_index) { | ||
279 | /* current clock is allowed */ | ||
280 | freq = chip->clock.cur_freq; | ||
281 | valid = chip->clock.cur_valid; | ||
282 | } else if (chip->clock.sample_clock[idx].type == | ||
283 | LOLA_CLOCK_TYPE_INTERNAL) { | ||
284 | /* internal clocks allowed */ | ||
285 | freq = chip->clock.sample_clock[idx].freq; | ||
286 | valid = true; | ||
287 | } | ||
288 | |||
289 | if (!freq || !valid) | ||
290 | return -EINVAL; | ||
291 | |||
292 | if (!check_gran_clock_compatibility(chip, chip->granularity, freq)) | ||
293 | return -EINVAL; | ||
294 | |||
295 | if (idx != chip->clock.cur_index) { | ||
296 | int err = lola_set_clock_index(chip, idx); | ||
297 | if (err < 0) | ||
298 | return err; | ||
299 | /* update new settings */ | ||
300 | chip->clock.cur_index = idx; | ||
301 | chip->clock.cur_freq = freq; | ||
302 | chip->clock.cur_valid = true; | ||
303 | } | ||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | int lola_set_sample_rate(struct lola *chip, int rate) | ||
308 | { | ||
309 | int i; | ||
310 | |||
311 | if (chip->clock.cur_freq == rate && chip->clock.cur_valid) | ||
312 | return 0; | ||
313 | /* search for new dwClockIndex */ | ||
314 | for (i = 0; i < chip->clock.items; i++) { | ||
315 | if (chip->clock.sample_clock[i].type == LOLA_CLOCK_TYPE_INTERNAL && | ||
316 | chip->clock.sample_clock[i].freq == rate) | ||
317 | break; | ||
318 | } | ||
319 | if (i >= chip->clock.items) | ||
320 | return -EINVAL; | ||
321 | return lola_set_clock(chip, i); | ||
322 | } | ||
323 | |||
diff --git a/sound/pci/lola/lola_mixer.c b/sound/pci/lola/lola_mixer.c new file mode 100644 index 000000000000..5d518f1a712c --- /dev/null +++ b/sound/pci/lola/lola_mixer.c | |||
@@ -0,0 +1,839 @@ | |||
1 | /* | ||
2 | * Support for Digigram Lola PCI-e boards | ||
3 | * | ||
4 | * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation; either version 2 of the License, or (at your option) | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
18 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/vmalloc.h> | ||
24 | #include <linux/io.h> | ||
25 | #include <sound/core.h> | ||
26 | #include <sound/control.h> | ||
27 | #include <sound/pcm.h> | ||
28 | #include <sound/tlv.h> | ||
29 | #include "lola.h" | ||
30 | |||
31 | static int __devinit lola_init_pin(struct lola *chip, struct lola_pin *pin, | ||
32 | int dir, int nid) | ||
33 | { | ||
34 | unsigned int val; | ||
35 | int err; | ||
36 | |||
37 | pin->nid = nid; | ||
38 | err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); | ||
39 | if (err < 0) { | ||
40 | printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid); | ||
41 | return err; | ||
42 | } | ||
43 | val &= 0x00f00fff; /* test TYPE and bits 0..11 */ | ||
44 | if (val == 0x00400200) /* Type = 4, Digital = 1 */ | ||
45 | pin->is_analog = false; | ||
46 | else if (val == 0x0040000a && dir == CAPT) /* Dig=0, InAmp/ovrd */ | ||
47 | pin->is_analog = true; | ||
48 | else if (val == 0x0040000c && dir == PLAY) /* Dig=0, OutAmp/ovrd */ | ||
49 | pin->is_analog = true; | ||
50 | else { | ||
51 | printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n", val, nid); | ||
52 | return -EINVAL; | ||
53 | } | ||
54 | |||
55 | /* analog parameters only following, so continue in case of Digital pin | ||
56 | */ | ||
57 | if (!pin->is_analog) | ||
58 | return 0; | ||
59 | |||
60 | if (dir == PLAY) | ||
61 | err = lola_read_param(chip, nid, LOLA_PAR_AMP_OUT_CAP, &val); | ||
62 | else | ||
63 | err = lola_read_param(chip, nid, LOLA_PAR_AMP_IN_CAP, &val); | ||
64 | if (err < 0) { | ||
65 | printk(KERN_ERR SFX "Can't read AMP-caps for 0x%x\n", nid); | ||
66 | return err; | ||
67 | } | ||
68 | |||
69 | pin->amp_mute = LOLA_AMP_MUTE_CAPABLE(val); | ||
70 | pin->amp_step_size = LOLA_AMP_STEP_SIZE(val); | ||
71 | pin->amp_num_steps = LOLA_AMP_NUM_STEPS(val); | ||
72 | if (pin->amp_num_steps) { | ||
73 | /* zero as mute state */ | ||
74 | pin->amp_num_steps++; | ||
75 | pin->amp_step_size++; | ||
76 | } | ||
77 | pin->amp_offset = LOLA_AMP_OFFSET(val); | ||
78 | |||
79 | err = lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val, | ||
80 | NULL); | ||
81 | if (err < 0) { | ||
82 | printk(KERN_ERR SFX "Can't get MAX_LEVEL 0x%x\n", nid); | ||
83 | return err; | ||
84 | } | ||
85 | pin->max_level = val & 0x3ff; /* 10 bits */ | ||
86 | |||
87 | pin->config_default_reg = 0; | ||
88 | pin->fixed_gain_list_len = 0; | ||
89 | pin->cur_gain_step = 0; | ||
90 | |||
91 | return 0; | ||
92 | } | ||
93 | |||
94 | int __devinit lola_init_pins(struct lola *chip, int dir, int *nidp) | ||
95 | { | ||
96 | int i, err, nid; | ||
97 | nid = *nidp; | ||
98 | for (i = 0; i < chip->pin[dir].num_pins; i++, nid++) { | ||
99 | err = lola_init_pin(chip, &chip->pin[dir].pins[i], dir, nid); | ||
100 | if (err < 0) | ||
101 | return err; | ||
102 | if (chip->pin[dir].pins[i].is_analog) | ||
103 | chip->pin[dir].num_analog_pins++; | ||
104 | } | ||
105 | *nidp = nid; | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | void lola_free_mixer(struct lola *chip) | ||
110 | { | ||
111 | if (chip->mixer.array_saved) | ||
112 | vfree(chip->mixer.array_saved); | ||
113 | } | ||
114 | |||
115 | int __devinit lola_init_mixer_widget(struct lola *chip, int nid) | ||
116 | { | ||
117 | unsigned int val; | ||
118 | int err; | ||
119 | |||
120 | err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); | ||
121 | if (err < 0) { | ||
122 | printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid); | ||
123 | return err; | ||
124 | } | ||
125 | |||
126 | if ((val & 0xfff00000) != 0x02f00000) { /* test SubType and Type */ | ||
127 | snd_printdd("No valid mixer widget\n"); | ||
128 | return 0; | ||
129 | } | ||
130 | |||
131 | chip->mixer.nid = nid; | ||
132 | chip->mixer.caps = val; | ||
133 | chip->mixer.array = (struct lola_mixer_array __iomem *) | ||
134 | (chip->bar[BAR1].remap_addr + LOLA_BAR1_SOURCE_GAIN_ENABLE); | ||
135 | |||
136 | /* reserve memory to copy mixer data for sleep mode transitions */ | ||
137 | chip->mixer.array_saved = vmalloc(sizeof(struct lola_mixer_array)); | ||
138 | |||
139 | /* mixer matrix sources are physical input data and play streams */ | ||
140 | chip->mixer.src_stream_outs = chip->pcm[PLAY].num_streams; | ||
141 | chip->mixer.src_phys_ins = chip->pin[CAPT].num_pins; | ||
142 | |||
143 | /* mixer matrix destinations are record streams and physical output */ | ||
144 | chip->mixer.dest_stream_ins = chip->pcm[CAPT].num_streams; | ||
145 | chip->mixer.dest_phys_outs = chip->pin[PLAY].num_pins; | ||
146 | |||
147 | /* mixer matrix can have unused areas between PhysIn and | ||
148 | * Play or Record and PhysOut zones | ||
149 | */ | ||
150 | chip->mixer.src_stream_out_ofs = chip->mixer.src_phys_ins + | ||
151 | LOLA_MIXER_SRC_INPUT_PLAY_SEPARATION(val); | ||
152 | chip->mixer.dest_phys_out_ofs = chip->mixer.dest_stream_ins + | ||
153 | LOLA_MIXER_DEST_REC_OUTPUT_SEPATATION(val); | ||
154 | |||
155 | /* example : MixerMatrix of LoLa881 | ||
156 | * 0-------8------16-------8------16 | ||
157 | * | | | | | | ||
158 | * | INPUT | | INPUT | | | ||
159 | * | -> |unused | -> |unused | | ||
160 | * | RECORD| | OUTPUT| | | ||
161 | * | | | | | | ||
162 | * 8-------------------------------- | ||
163 | * | | | | | | ||
164 | * | | | | | | ||
165 | * |unused |unused |unused |unused | | ||
166 | * | | | | | | ||
167 | * | | | | | | ||
168 | * 16------------------------------- | ||
169 | * | | | | | | ||
170 | * | PLAY | | PLAY | | | ||
171 | * | -> |unused | -> |unused | | ||
172 | * | RECORD| | OUTPUT| | | ||
173 | * | | | | | | ||
174 | * 8-------------------------------- | ||
175 | * | | | | | | ||
176 | * | | | | | | ||
177 | * |unused |unused |unused |unused | | ||
178 | * | | | | | | ||
179 | * | | | | | | ||
180 | * 16------------------------------- | ||
181 | */ | ||
182 | if (chip->mixer.src_stream_out_ofs > MAX_AUDIO_INOUT_COUNT || | ||
183 | chip->mixer.dest_phys_out_ofs > MAX_STREAM_IN_COUNT) { | ||
184 | printk(KERN_ERR SFX "Invalid mixer widget size\n"); | ||
185 | return -EINVAL; | ||
186 | } | ||
187 | |||
188 | chip->mixer.src_mask = ((1U << chip->mixer.src_phys_ins) - 1) | | ||
189 | (((1U << chip->mixer.src_stream_outs) - 1) | ||
190 | << chip->mixer.src_stream_out_ofs); | ||
191 | chip->mixer.dest_mask = ((1U << chip->mixer.dest_stream_ins) - 1) | | ||
192 | (((1U << chip->mixer.dest_phys_outs) - 1) | ||
193 | << chip->mixer.dest_phys_out_ofs); | ||
194 | |||
195 | return 0; | ||
196 | } | ||
197 | |||
198 | static int lola_mixer_set_src_gain(struct lola *chip, unsigned int id, | ||
199 | unsigned short gain, bool on) | ||
200 | { | ||
201 | unsigned int oldval, val; | ||
202 | |||
203 | if (!(chip->mixer.src_mask & (1 << id))) | ||
204 | return -EINVAL; | ||
205 | writew(gain, &chip->mixer.array->src_gain[id]); | ||
206 | oldval = val = readl(&chip->mixer.array->src_gain_enable); | ||
207 | if (on) | ||
208 | val |= (1 << id); | ||
209 | else | ||
210 | val &= ~(1 << id); | ||
211 | writel(val, &chip->mixer.array->src_gain_enable); | ||
212 | lola_codec_flush(chip); | ||
213 | /* inform micro-controller about the new source gain */ | ||
214 | return lola_codec_write(chip, chip->mixer.nid, | ||
215 | LOLA_VERB_SET_SOURCE_GAIN, id, 0); | ||
216 | } | ||
217 | |||
218 | #if 0 /* not used */ | ||
219 | static int lola_mixer_set_src_gains(struct lola *chip, unsigned int mask, | ||
220 | unsigned short *gains) | ||
221 | { | ||
222 | int i; | ||
223 | |||
224 | if ((chip->mixer.src_mask & mask) != mask) | ||
225 | return -EINVAL; | ||
226 | for (i = 0; i < LOLA_MIXER_DIM; i++) { | ||
227 | if (mask & (1 << i)) { | ||
228 | writew(*gains, &chip->mixer.array->src_gain[i]); | ||
229 | gains++; | ||
230 | } | ||
231 | } | ||
232 | writel(mask, &chip->mixer.array->src_gain_enable); | ||
233 | lola_codec_flush(chip); | ||
234 | if (chip->mixer.caps & LOLA_PEAK_METER_CAN_AGC_MASK) { | ||
235 | /* update for all srcs at once */ | ||
236 | return lola_codec_write(chip, chip->mixer.nid, | ||
237 | LOLA_VERB_SET_SOURCE_GAIN, 0x80, 0); | ||
238 | } | ||
239 | /* update manually */ | ||
240 | for (i = 0; i < LOLA_MIXER_DIM; i++) { | ||
241 | if (mask & (1 << i)) { | ||
242 | lola_codec_write(chip, chip->mixer.nid, | ||
243 | LOLA_VERB_SET_SOURCE_GAIN, i, 0); | ||
244 | } | ||
245 | } | ||
246 | return 0; | ||
247 | } | ||
248 | #endif /* not used */ | ||
249 | |||
250 | static int lola_mixer_set_mapping_gain(struct lola *chip, | ||
251 | unsigned int src, unsigned int dest, | ||
252 | unsigned short gain, bool on) | ||
253 | { | ||
254 | unsigned int val; | ||
255 | |||
256 | if (!(chip->mixer.src_mask & (1 << src)) || | ||
257 | !(chip->mixer.dest_mask & (1 << dest))) | ||
258 | return -EINVAL; | ||
259 | if (on) | ||
260 | writew(gain, &chip->mixer.array->dest_mix_gain[dest][src]); | ||
261 | val = readl(&chip->mixer.array->dest_mix_gain_enable[dest]); | ||
262 | if (on) | ||
263 | val |= (1 << src); | ||
264 | else | ||
265 | val &= ~(1 << src); | ||
266 | writel(val, &chip->mixer.array->dest_mix_gain_enable[dest]); | ||
267 | lola_codec_flush(chip); | ||
268 | return lola_codec_write(chip, chip->mixer.nid, LOLA_VERB_SET_MIX_GAIN, | ||
269 | src, dest); | ||
270 | } | ||
271 | |||
272 | static int lola_mixer_set_dest_gains(struct lola *chip, unsigned int id, | ||
273 | unsigned int mask, unsigned short *gains) | ||
274 | { | ||
275 | int i; | ||
276 | |||
277 | if (!(chip->mixer.dest_mask & (1 << id)) || | ||
278 | (chip->mixer.src_mask & mask) != mask) | ||
279 | return -EINVAL; | ||
280 | for (i = 0; i < LOLA_MIXER_DIM; i++) { | ||
281 | if (mask & (1 << i)) { | ||
282 | writew(*gains, &chip->mixer.array->dest_mix_gain[id][i]); | ||
283 | gains++; | ||
284 | } | ||
285 | } | ||
286 | writel(mask, &chip->mixer.array->dest_mix_gain_enable[id]); | ||
287 | lola_codec_flush(chip); | ||
288 | /* update for all dests at once */ | ||
289 | return lola_codec_write(chip, chip->mixer.nid, | ||
290 | LOLA_VERB_SET_DESTINATION_GAIN, id, 0); | ||
291 | } | ||
292 | |||
293 | /* | ||
294 | */ | ||
295 | |||
296 | static int set_analog_volume(struct lola *chip, int dir, | ||
297 | unsigned int idx, unsigned int val, | ||
298 | bool external_call); | ||
299 | |||
300 | int lola_setup_all_analog_gains(struct lola *chip, int dir, bool mute) | ||
301 | { | ||
302 | struct lola_pin *pin; | ||
303 | int idx, max_idx; | ||
304 | |||
305 | pin = chip->pin[dir].pins; | ||
306 | max_idx = chip->pin[dir].num_pins; | ||
307 | for (idx = 0; idx < max_idx; idx++) { | ||
308 | if (pin[idx].is_analog) { | ||
309 | unsigned int val = mute ? 0 : pin[idx].cur_gain_step; | ||
310 | /* set volume and do not save the value */ | ||
311 | set_analog_volume(chip, dir, idx, val, false); | ||
312 | } | ||
313 | } | ||
314 | return lola_codec_flush(chip); | ||
315 | } | ||
316 | |||
317 | void lola_save_mixer(struct lola *chip) | ||
318 | { | ||
319 | /* mute analog output */ | ||
320 | if (chip->mixer.array_saved) { | ||
321 | /* store contents of mixer array */ | ||
322 | memcpy_fromio(chip->mixer.array_saved, chip->mixer.array, | ||
323 | sizeof(*chip->mixer.array)); | ||
324 | } | ||
325 | lola_setup_all_analog_gains(chip, PLAY, true); /* output mute */ | ||
326 | } | ||
327 | |||
328 | void lola_restore_mixer(struct lola *chip) | ||
329 | { | ||
330 | int i; | ||
331 | |||
332 | /*lola_reset_setups(chip);*/ | ||
333 | if (chip->mixer.array_saved) { | ||
334 | /* restore contents of mixer array */ | ||
335 | memcpy_toio(chip->mixer.array, chip->mixer.array_saved, | ||
336 | sizeof(*chip->mixer.array)); | ||
337 | /* inform micro-controller about all restored values | ||
338 | * and ignore return values | ||
339 | */ | ||
340 | for (i = 0; i < chip->mixer.src_phys_ins; i++) | ||
341 | lola_codec_write(chip, chip->mixer.nid, | ||
342 | LOLA_VERB_SET_SOURCE_GAIN, | ||
343 | i, 0); | ||
344 | for (i = 0; i < chip->mixer.src_stream_outs; i++) | ||
345 | lola_codec_write(chip, chip->mixer.nid, | ||
346 | LOLA_VERB_SET_SOURCE_GAIN, | ||
347 | chip->mixer.src_stream_out_ofs + i, 0); | ||
348 | for (i = 0; i < chip->mixer.dest_stream_ins; i++) | ||
349 | lola_codec_write(chip, chip->mixer.nid, | ||
350 | LOLA_VERB_SET_DESTINATION_GAIN, | ||
351 | i, 0); | ||
352 | for (i = 0; i < chip->mixer.dest_phys_outs; i++) | ||
353 | lola_codec_write(chip, chip->mixer.nid, | ||
354 | LOLA_VERB_SET_DESTINATION_GAIN, | ||
355 | chip->mixer.dest_phys_out_ofs + i, 0); | ||
356 | lola_codec_flush(chip); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | /* | ||
361 | */ | ||
362 | |||
363 | static int set_analog_volume(struct lola *chip, int dir, | ||
364 | unsigned int idx, unsigned int val, | ||
365 | bool external_call) | ||
366 | { | ||
367 | struct lola_pin *pin; | ||
368 | int err; | ||
369 | |||
370 | if (idx >= chip->pin[dir].num_pins) | ||
371 | return -EINVAL; | ||
372 | pin = &chip->pin[dir].pins[idx]; | ||
373 | if (!pin->is_analog || pin->amp_num_steps <= val) | ||
374 | return -EINVAL; | ||
375 | if (external_call && pin->cur_gain_step == val) | ||
376 | return 0; | ||
377 | if (external_call) | ||
378 | lola_codec_flush(chip); | ||
379 | err = lola_codec_write(chip, pin->nid, | ||
380 | LOLA_VERB_SET_AMP_GAIN_MUTE, val, 0); | ||
381 | if (err < 0) | ||
382 | return err; | ||
383 | if (external_call) | ||
384 | pin->cur_gain_step = val; | ||
385 | return 0; | ||
386 | } | ||
387 | |||
388 | int lola_set_src_config(struct lola *chip, unsigned int src_mask, bool update) | ||
389 | { | ||
390 | int ret = 0; | ||
391 | int success = 0; | ||
392 | int n, err; | ||
393 | |||
394 | /* SRC can be activated and the dwInputSRCMask is valid? */ | ||
395 | if ((chip->input_src_caps_mask & src_mask) != src_mask) | ||
396 | return -EINVAL; | ||
397 | /* handle all even Inputs - SRC is a stereo setting !!! */ | ||
398 | for (n = 0; n < chip->pin[CAPT].num_pins; n += 2) { | ||
399 | unsigned int mask = 3U << n; /* handle the stereo case */ | ||
400 | unsigned int new_src, src_state; | ||
401 | if (!(chip->input_src_caps_mask & mask)) | ||
402 | continue; | ||
403 | /* if one IO needs SRC, both stereo IO will get SRC */ | ||
404 | new_src = (src_mask & mask) != 0; | ||
405 | if (update) { | ||
406 | src_state = (chip->input_src_mask & mask) != 0; | ||
407 | if (src_state == new_src) | ||
408 | continue; /* nothing to change for this IO */ | ||
409 | } | ||
410 | err = lola_codec_write(chip, chip->pcm[CAPT].streams[n].nid, | ||
411 | LOLA_VERB_SET_SRC, new_src, 0); | ||
412 | if (!err) | ||
413 | success++; | ||
414 | else | ||
415 | ret = err; | ||
416 | } | ||
417 | if (success) | ||
418 | ret = lola_codec_flush(chip); | ||
419 | if (!ret) | ||
420 | chip->input_src_mask = src_mask; | ||
421 | return ret; | ||
422 | } | ||
423 | |||
424 | /* | ||
425 | */ | ||
426 | static int init_mixer_values(struct lola *chip) | ||
427 | { | ||
428 | int i; | ||
429 | |||
430 | /* all src on */ | ||
431 | lola_set_src_config(chip, (1 << chip->pin[CAPT].num_pins) - 1, false); | ||
432 | |||
433 | /* clear all matrix */ | ||
434 | memset_io(chip->mixer.array, 0, sizeof(*chip->mixer.array)); | ||
435 | /* set src gain to 0dB */ | ||
436 | for (i = 0; i < chip->mixer.src_phys_ins; i++) | ||
437 | lola_mixer_set_src_gain(chip, i, 336, true); /* 0dB */ | ||
438 | for (i = 0; i < chip->mixer.src_stream_outs; i++) | ||
439 | lola_mixer_set_src_gain(chip, | ||
440 | i + chip->mixer.src_stream_out_ofs, | ||
441 | 336, true); /* 0dB */ | ||
442 | /* set 1:1 dest gain */ | ||
443 | for (i = 0; i < chip->mixer.dest_stream_ins; i++) { | ||
444 | int src = i % chip->mixer.src_phys_ins; | ||
445 | lola_mixer_set_mapping_gain(chip, src, i, 336, true); | ||
446 | } | ||
447 | for (i = 0; i < chip->mixer.src_stream_outs; i++) { | ||
448 | int src = chip->mixer.src_stream_out_ofs + i; | ||
449 | int dst = chip->mixer.dest_phys_out_ofs + | ||
450 | i % chip->mixer.dest_phys_outs; | ||
451 | lola_mixer_set_mapping_gain(chip, src, dst, 336, true); | ||
452 | } | ||
453 | return 0; | ||
454 | } | ||
455 | |||
456 | /* | ||
457 | * analog mixer control element | ||
458 | */ | ||
459 | static int lola_analog_vol_info(struct snd_kcontrol *kcontrol, | ||
460 | struct snd_ctl_elem_info *uinfo) | ||
461 | { | ||
462 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
463 | int dir = kcontrol->private_value; | ||
464 | |||
465 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
466 | uinfo->count = chip->pin[dir].num_pins; | ||
467 | uinfo->value.integer.min = 0; | ||
468 | uinfo->value.integer.max = chip->pin[dir].pins[0].amp_num_steps; | ||
469 | return 0; | ||
470 | } | ||
471 | |||
472 | static int lola_analog_vol_get(struct snd_kcontrol *kcontrol, | ||
473 | struct snd_ctl_elem_value *ucontrol) | ||
474 | { | ||
475 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
476 | int dir = kcontrol->private_value; | ||
477 | int i; | ||
478 | |||
479 | for (i = 0; i < chip->pin[dir].num_pins; i++) | ||
480 | ucontrol->value.integer.value[i] = | ||
481 | chip->pin[dir].pins[i].cur_gain_step; | ||
482 | return 0; | ||
483 | } | ||
484 | |||
485 | static int lola_analog_vol_put(struct snd_kcontrol *kcontrol, | ||
486 | struct snd_ctl_elem_value *ucontrol) | ||
487 | { | ||
488 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
489 | int dir = kcontrol->private_value; | ||
490 | int i, err; | ||
491 | |||
492 | for (i = 0; i < chip->pin[dir].num_pins; i++) { | ||
493 | err = set_analog_volume(chip, dir, i, | ||
494 | ucontrol->value.integer.value[i], | ||
495 | true); | ||
496 | if (err < 0) | ||
497 | return err; | ||
498 | } | ||
499 | return 0; | ||
500 | } | ||
501 | |||
502 | static int lola_analog_vol_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
503 | unsigned int size, unsigned int __user *tlv) | ||
504 | { | ||
505 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
506 | int dir = kcontrol->private_value; | ||
507 | unsigned int val1, val2; | ||
508 | struct lola_pin *pin; | ||
509 | |||
510 | if (size < 4 * sizeof(unsigned int)) | ||
511 | return -ENOMEM; | ||
512 | pin = &chip->pin[dir].pins[0]; | ||
513 | |||
514 | val2 = pin->amp_step_size * 25; | ||
515 | val1 = -1 * (int)pin->amp_offset * (int)val2; | ||
516 | #ifdef TLV_DB_SCALE_MUTE | ||
517 | val2 |= TLV_DB_SCALE_MUTE; | ||
518 | #endif | ||
519 | if (put_user(SNDRV_CTL_TLVT_DB_SCALE, tlv)) | ||
520 | return -EFAULT; | ||
521 | if (put_user(2 * sizeof(unsigned int), tlv + 1)) | ||
522 | return -EFAULT; | ||
523 | if (put_user(val1, tlv + 2)) | ||
524 | return -EFAULT; | ||
525 | if (put_user(val2, tlv + 3)) | ||
526 | return -EFAULT; | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | static struct snd_kcontrol_new lola_analog_mixer __devinitdata = { | ||
531 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
532 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
533 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
534 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK), | ||
535 | .info = lola_analog_vol_info, | ||
536 | .get = lola_analog_vol_get, | ||
537 | .put = lola_analog_vol_put, | ||
538 | .tlv.c = lola_analog_vol_tlv, | ||
539 | }; | ||
540 | |||
541 | static int __devinit create_analog_mixer(struct lola *chip, int dir, char *name) | ||
542 | { | ||
543 | if (!chip->pin[dir].num_pins) | ||
544 | return 0; | ||
545 | /* no analog volumes on digital only adapters */ | ||
546 | if (chip->pin[dir].num_pins != chip->pin[dir].num_analog_pins) | ||
547 | return 0; | ||
548 | lola_analog_mixer.name = name; | ||
549 | lola_analog_mixer.private_value = dir; | ||
550 | return snd_ctl_add(chip->card, | ||
551 | snd_ctl_new1(&lola_analog_mixer, chip)); | ||
552 | } | ||
553 | |||
554 | /* | ||
555 | * Hardware sample rate converter on digital input | ||
556 | */ | ||
557 | static int lola_input_src_info(struct snd_kcontrol *kcontrol, | ||
558 | struct snd_ctl_elem_info *uinfo) | ||
559 | { | ||
560 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
561 | |||
562 | uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN; | ||
563 | uinfo->count = chip->pin[CAPT].num_pins; | ||
564 | uinfo->value.integer.min = 0; | ||
565 | uinfo->value.integer.max = 1; | ||
566 | return 0; | ||
567 | } | ||
568 | |||
569 | static int lola_input_src_get(struct snd_kcontrol *kcontrol, | ||
570 | struct snd_ctl_elem_value *ucontrol) | ||
571 | { | ||
572 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
573 | int i; | ||
574 | |||
575 | for (i = 0; i < chip->pin[CAPT].num_pins; i++) | ||
576 | ucontrol->value.integer.value[i] = | ||
577 | !!(chip->input_src_mask & (1 << i)); | ||
578 | return 0; | ||
579 | } | ||
580 | |||
581 | static int lola_input_src_put(struct snd_kcontrol *kcontrol, | ||
582 | struct snd_ctl_elem_value *ucontrol) | ||
583 | { | ||
584 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
585 | int i; | ||
586 | unsigned int mask; | ||
587 | |||
588 | mask = 0; | ||
589 | for (i = 0; i < chip->pin[CAPT].num_pins; i++) | ||
590 | if (ucontrol->value.integer.value[i]) | ||
591 | mask |= 1 << i; | ||
592 | return lola_set_src_config(chip, mask, true); | ||
593 | } | ||
594 | |||
595 | static struct snd_kcontrol_new lola_input_src_mixer __devinitdata = { | ||
596 | .name = "Digital SRC Capture Switch", | ||
597 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
598 | .info = lola_input_src_info, | ||
599 | .get = lola_input_src_get, | ||
600 | .put = lola_input_src_put, | ||
601 | }; | ||
602 | |||
603 | /* | ||
604 | * Lola16161 or Lola881 can have Hardware sample rate converters | ||
605 | * on its digital input pins | ||
606 | */ | ||
607 | static int __devinit create_input_src_mixer(struct lola *chip) | ||
608 | { | ||
609 | if (!chip->input_src_caps_mask) | ||
610 | return 0; | ||
611 | |||
612 | return snd_ctl_add(chip->card, | ||
613 | snd_ctl_new1(&lola_input_src_mixer, chip)); | ||
614 | } | ||
615 | |||
616 | /* | ||
617 | * src gain mixer | ||
618 | */ | ||
619 | static int lola_src_gain_info(struct snd_kcontrol *kcontrol, | ||
620 | struct snd_ctl_elem_info *uinfo) | ||
621 | { | ||
622 | unsigned int count = (kcontrol->private_value >> 8) & 0xff; | ||
623 | |||
624 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
625 | uinfo->count = count; | ||
626 | uinfo->value.integer.min = 0; | ||
627 | uinfo->value.integer.max = 409; | ||
628 | return 0; | ||
629 | } | ||
630 | |||
631 | static int lola_src_gain_get(struct snd_kcontrol *kcontrol, | ||
632 | struct snd_ctl_elem_value *ucontrol) | ||
633 | { | ||
634 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
635 | unsigned int ofs = kcontrol->private_value & 0xff; | ||
636 | unsigned int count = (kcontrol->private_value >> 8) & 0xff; | ||
637 | unsigned int mask, i; | ||
638 | |||
639 | mask = readl(&chip->mixer.array->src_gain_enable); | ||
640 | for (i = 0; i < count; i++) { | ||
641 | unsigned int idx = ofs + i; | ||
642 | unsigned short val; | ||
643 | if (!(chip->mixer.src_mask & (1 << idx))) | ||
644 | return -EINVAL; | ||
645 | if (mask & (1 << idx)) | ||
646 | val = readw(&chip->mixer.array->src_gain[idx]) + 1; | ||
647 | else | ||
648 | val = 0; | ||
649 | ucontrol->value.integer.value[i] = val; | ||
650 | } | ||
651 | return 0; | ||
652 | } | ||
653 | |||
654 | static int lola_src_gain_put(struct snd_kcontrol *kcontrol, | ||
655 | struct snd_ctl_elem_value *ucontrol) | ||
656 | { | ||
657 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
658 | unsigned int ofs = kcontrol->private_value & 0xff; | ||
659 | unsigned int count = (kcontrol->private_value >> 8) & 0xff; | ||
660 | int i, err; | ||
661 | |||
662 | for (i = 0; i < count; i++) { | ||
663 | unsigned int idx = ofs + i; | ||
664 | unsigned short val = ucontrol->value.integer.value[i]; | ||
665 | if (val) | ||
666 | val--; | ||
667 | err = lola_mixer_set_src_gain(chip, idx, val, !!val); | ||
668 | if (err < 0) | ||
669 | return err; | ||
670 | } | ||
671 | return 0; | ||
672 | } | ||
673 | |||
674 | /* raw value: 0 = -84dB, 336 = 0dB, 408=18dB, incremented 1 for mute */ | ||
675 | static const DECLARE_TLV_DB_SCALE(lola_src_gain_tlv, -8425, 25, 1); | ||
676 | |||
677 | static struct snd_kcontrol_new lola_src_gain_mixer __devinitdata = { | ||
678 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
679 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
680 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), | ||
681 | .info = lola_src_gain_info, | ||
682 | .get = lola_src_gain_get, | ||
683 | .put = lola_src_gain_put, | ||
684 | .tlv.p = lola_src_gain_tlv, | ||
685 | }; | ||
686 | |||
687 | static int __devinit create_src_gain_mixer(struct lola *chip, | ||
688 | int num, int ofs, char *name) | ||
689 | { | ||
690 | lola_src_gain_mixer.name = name; | ||
691 | lola_src_gain_mixer.private_value = ofs + (num << 8); | ||
692 | return snd_ctl_add(chip->card, | ||
693 | snd_ctl_new1(&lola_src_gain_mixer, chip)); | ||
694 | } | ||
695 | |||
696 | /* | ||
697 | * destination gain (matrix-like) mixer | ||
698 | */ | ||
699 | static int lola_dest_gain_info(struct snd_kcontrol *kcontrol, | ||
700 | struct snd_ctl_elem_info *uinfo) | ||
701 | { | ||
702 | unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; | ||
703 | |||
704 | uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER; | ||
705 | uinfo->count = src_num; | ||
706 | uinfo->value.integer.min = 0; | ||
707 | uinfo->value.integer.max = 433; | ||
708 | return 0; | ||
709 | } | ||
710 | |||
711 | static int lola_dest_gain_get(struct snd_kcontrol *kcontrol, | ||
712 | struct snd_ctl_elem_value *ucontrol) | ||
713 | { | ||
714 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
715 | unsigned int src_ofs = kcontrol->private_value & 0xff; | ||
716 | unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; | ||
717 | unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff; | ||
718 | unsigned int dst, mask, i; | ||
719 | |||
720 | dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs; | ||
721 | mask = readl(&chip->mixer.array->dest_mix_gain_enable[dst]); | ||
722 | for (i = 0; i < src_num; i++) { | ||
723 | unsigned int src = src_ofs + i; | ||
724 | unsigned short val; | ||
725 | if (!(chip->mixer.src_mask & (1 << src))) | ||
726 | return -EINVAL; | ||
727 | if (mask & (1 << dst)) | ||
728 | val = readw(&chip->mixer.array->dest_mix_gain[dst][src]) + 1; | ||
729 | else | ||
730 | val = 0; | ||
731 | ucontrol->value.integer.value[i] = val; | ||
732 | } | ||
733 | return 0; | ||
734 | } | ||
735 | |||
736 | static int lola_dest_gain_put(struct snd_kcontrol *kcontrol, | ||
737 | struct snd_ctl_elem_value *ucontrol) | ||
738 | { | ||
739 | struct lola *chip = snd_kcontrol_chip(kcontrol); | ||
740 | unsigned int src_ofs = kcontrol->private_value & 0xff; | ||
741 | unsigned int src_num = (kcontrol->private_value >> 8) & 0xff; | ||
742 | unsigned int dst_ofs = (kcontrol->private_value >> 16) & 0xff; | ||
743 | unsigned int dst, mask; | ||
744 | unsigned short gains[MAX_STREAM_COUNT]; | ||
745 | int i, num; | ||
746 | |||
747 | mask = 0; | ||
748 | num = 0; | ||
749 | for (i = 0; i < src_num; i++) { | ||
750 | unsigned short val = ucontrol->value.integer.value[i]; | ||
751 | if (val) { | ||
752 | gains[num++] = val - 1; | ||
753 | mask |= 1 << i; | ||
754 | } | ||
755 | } | ||
756 | mask <<= src_ofs; | ||
757 | dst = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id) + dst_ofs; | ||
758 | return lola_mixer_set_dest_gains(chip, dst, mask, gains); | ||
759 | } | ||
760 | |||
761 | static const DECLARE_TLV_DB_SCALE(lola_dest_gain_tlv, -8425, 25, 1); | ||
762 | |||
763 | static struct snd_kcontrol_new lola_dest_gain_mixer __devinitdata = { | ||
764 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
765 | .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE | | ||
766 | SNDRV_CTL_ELEM_ACCESS_TLV_READ), | ||
767 | .info = lola_dest_gain_info, | ||
768 | .get = lola_dest_gain_get, | ||
769 | .put = lola_dest_gain_put, | ||
770 | .tlv.p = lola_dest_gain_tlv, | ||
771 | }; | ||
772 | |||
773 | static int __devinit create_dest_gain_mixer(struct lola *chip, | ||
774 | int src_num, int src_ofs, | ||
775 | int num, int ofs, char *name) | ||
776 | { | ||
777 | lola_dest_gain_mixer.count = num; | ||
778 | lola_dest_gain_mixer.name = name; | ||
779 | lola_dest_gain_mixer.private_value = | ||
780 | src_ofs + (src_num << 8) + (ofs << 16) + (num << 24); | ||
781 | return snd_ctl_add(chip->card, | ||
782 | snd_ctl_new1(&lola_dest_gain_mixer, chip)); | ||
783 | } | ||
784 | |||
785 | /* | ||
786 | */ | ||
787 | int __devinit lola_create_mixer(struct lola *chip) | ||
788 | { | ||
789 | int err; | ||
790 | |||
791 | err = create_analog_mixer(chip, PLAY, "Analog Playback Volume"); | ||
792 | if (err < 0) | ||
793 | return err; | ||
794 | err = create_analog_mixer(chip, CAPT, "Analog Capture Volume"); | ||
795 | if (err < 0) | ||
796 | return err; | ||
797 | err = create_input_src_mixer(chip); | ||
798 | if (err < 0) | ||
799 | return err; | ||
800 | err = create_src_gain_mixer(chip, chip->mixer.src_phys_ins, 0, | ||
801 | "Line Source Gain Volume"); | ||
802 | if (err < 0) | ||
803 | return err; | ||
804 | err = create_src_gain_mixer(chip, chip->mixer.src_stream_outs, | ||
805 | chip->mixer.src_stream_out_ofs, | ||
806 | "Stream Source Gain Volume"); | ||
807 | if (err < 0) | ||
808 | return err; | ||
809 | err = create_dest_gain_mixer(chip, | ||
810 | chip->mixer.src_phys_ins, 0, | ||
811 | chip->mixer.dest_stream_ins, 0, | ||
812 | "Line Capture Volume"); | ||
813 | if (err < 0) | ||
814 | return err; | ||
815 | err = create_dest_gain_mixer(chip, | ||
816 | chip->mixer.src_stream_outs, | ||
817 | chip->mixer.src_stream_out_ofs, | ||
818 | chip->mixer.dest_stream_ins, 0, | ||
819 | "Stream-Loopback Capture Volume"); | ||
820 | if (err < 0) | ||
821 | return err; | ||
822 | err = create_dest_gain_mixer(chip, | ||
823 | chip->mixer.src_phys_ins, 0, | ||
824 | chip->mixer.dest_phys_outs, | ||
825 | chip->mixer.dest_phys_out_ofs, | ||
826 | "Line-Loopback Playback Volume"); | ||
827 | if (err < 0) | ||
828 | return err; | ||
829 | err = create_dest_gain_mixer(chip, | ||
830 | chip->mixer.src_stream_outs, | ||
831 | chip->mixer.src_stream_out_ofs, | ||
832 | chip->mixer.dest_phys_outs, | ||
833 | chip->mixer.dest_phys_out_ofs, | ||
834 | "Stream Playback Volume"); | ||
835 | if (err < 0) | ||
836 | return err; | ||
837 | |||
838 | return init_mixer_values(chip); | ||
839 | } | ||
diff --git a/sound/pci/lola/lola_pcm.c b/sound/pci/lola/lola_pcm.c new file mode 100644 index 000000000000..c44db68eecb5 --- /dev/null +++ b/sound/pci/lola/lola_pcm.c | |||
@@ -0,0 +1,706 @@ | |||
1 | /* | ||
2 | * Support for Digigram Lola PCI-e boards | ||
3 | * | ||
4 | * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation; either version 2 of the License, or (at your option) | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
18 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/dma-mapping.h> | ||
24 | #include <linux/pci.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <sound/core.h> | ||
27 | #include <sound/pcm.h> | ||
28 | #include "lola.h" | ||
29 | |||
30 | #define LOLA_MAX_BDL_ENTRIES 8 | ||
31 | #define LOLA_MAX_BUF_SIZE (1024*1024*1024) | ||
32 | #define LOLA_BDL_ENTRY_SIZE (16 * 16) | ||
33 | |||
34 | static struct lola_pcm *lola_get_pcm(struct snd_pcm_substream *substream) | ||
35 | { | ||
36 | struct lola *chip = snd_pcm_substream_chip(substream); | ||
37 | return &chip->pcm[substream->stream]; | ||
38 | } | ||
39 | |||
40 | static struct lola_stream *lola_get_stream(struct snd_pcm_substream *substream) | ||
41 | { | ||
42 | struct lola_pcm *pcm = lola_get_pcm(substream); | ||
43 | unsigned int idx = substream->number; | ||
44 | return &pcm->streams[idx]; | ||
45 | } | ||
46 | |||
47 | static unsigned int lola_get_lrc(struct lola *chip) | ||
48 | { | ||
49 | return lola_readl(chip, BAR1, LRC); | ||
50 | } | ||
51 | |||
52 | static unsigned int lola_get_tstamp(struct lola *chip, bool quick_no_sync) | ||
53 | { | ||
54 | unsigned int tstamp = lola_get_lrc(chip) >> 8; | ||
55 | if (chip->granularity) { | ||
56 | unsigned int wait_banks = quick_no_sync ? 0 : 8; | ||
57 | tstamp += (wait_banks + 1) * chip->granularity - 1; | ||
58 | tstamp -= tstamp % chip->granularity; | ||
59 | } | ||
60 | return tstamp << 8; | ||
61 | } | ||
62 | |||
63 | /* clear any pending interrupt status */ | ||
64 | static void lola_stream_clear_pending_irq(struct lola *chip, | ||
65 | struct lola_stream *str) | ||
66 | { | ||
67 | unsigned int val = lola_dsd_read(chip, str->dsd, STS); | ||
68 | val &= LOLA_DSD_STS_DESE | LOLA_DSD_STS_BCIS; | ||
69 | if (val) | ||
70 | lola_dsd_write(chip, str->dsd, STS, val); | ||
71 | } | ||
72 | |||
73 | static void lola_stream_start(struct lola *chip, struct lola_stream *str, | ||
74 | unsigned int tstamp) | ||
75 | { | ||
76 | lola_stream_clear_pending_irq(chip, str); | ||
77 | lola_dsd_write(chip, str->dsd, CTL, | ||
78 | LOLA_DSD_CTL_SRUN | | ||
79 | LOLA_DSD_CTL_IOCE | | ||
80 | LOLA_DSD_CTL_DEIE | | ||
81 | LOLA_DSD_CTL_VLRCV | | ||
82 | tstamp); | ||
83 | } | ||
84 | |||
85 | static void lola_stream_stop(struct lola *chip, struct lola_stream *str, | ||
86 | unsigned int tstamp) | ||
87 | { | ||
88 | lola_dsd_write(chip, str->dsd, CTL, | ||
89 | LOLA_DSD_CTL_IOCE | | ||
90 | LOLA_DSD_CTL_DEIE | | ||
91 | LOLA_DSD_CTL_VLRCV | | ||
92 | tstamp); | ||
93 | lola_stream_clear_pending_irq(chip, str); | ||
94 | } | ||
95 | |||
96 | static void wait_for_srst_clear(struct lola *chip, struct lola_stream *str) | ||
97 | { | ||
98 | unsigned long end_time = jiffies + msecs_to_jiffies(200); | ||
99 | while (time_before(jiffies, end_time)) { | ||
100 | unsigned int val; | ||
101 | val = lola_dsd_read(chip, str->dsd, CTL); | ||
102 | if (!(val & LOLA_DSD_CTL_SRST)) | ||
103 | return; | ||
104 | msleep(1); | ||
105 | } | ||
106 | printk(KERN_WARNING SFX "SRST not clear (stream %d)\n", str->dsd); | ||
107 | } | ||
108 | |||
109 | static int lola_stream_wait_for_fifo(struct lola *chip, | ||
110 | struct lola_stream *str, | ||
111 | bool ready) | ||
112 | { | ||
113 | unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0; | ||
114 | unsigned long end_time = jiffies + msecs_to_jiffies(200); | ||
115 | while (time_before(jiffies, end_time)) { | ||
116 | unsigned int reg = lola_dsd_read(chip, str->dsd, STS); | ||
117 | if ((reg & LOLA_DSD_STS_FIFORDY) == val) | ||
118 | return 0; | ||
119 | msleep(1); | ||
120 | } | ||
121 | printk(KERN_WARNING SFX "FIFO not ready (stream %d)\n", str->dsd); | ||
122 | return -EIO; | ||
123 | } | ||
124 | |||
125 | /* sync for FIFO ready/empty for all linked streams; | ||
126 | * clear paused flag when FIFO gets ready again | ||
127 | */ | ||
128 | static int lola_sync_wait_for_fifo(struct lola *chip, | ||
129 | struct snd_pcm_substream *substream, | ||
130 | bool ready) | ||
131 | { | ||
132 | unsigned int val = ready ? LOLA_DSD_STS_FIFORDY : 0; | ||
133 | unsigned long end_time = jiffies + msecs_to_jiffies(200); | ||
134 | struct snd_pcm_substream *s; | ||
135 | int pending = 0; | ||
136 | |||
137 | while (time_before(jiffies, end_time)) { | ||
138 | pending = 0; | ||
139 | snd_pcm_group_for_each_entry(s, substream) { | ||
140 | struct lola_stream *str; | ||
141 | if (s->pcm->card != substream->pcm->card) | ||
142 | continue; | ||
143 | str = lola_get_stream(s); | ||
144 | if (str->prepared && str->paused) { | ||
145 | unsigned int reg; | ||
146 | reg = lola_dsd_read(chip, str->dsd, STS); | ||
147 | if ((reg & LOLA_DSD_STS_FIFORDY) != val) { | ||
148 | pending = str->dsd + 1; | ||
149 | break; | ||
150 | } | ||
151 | if (ready) | ||
152 | str->paused = 0; | ||
153 | } | ||
154 | } | ||
155 | if (!pending) | ||
156 | return 0; | ||
157 | msleep(1); | ||
158 | } | ||
159 | printk(KERN_WARNING SFX "FIFO not ready (pending %d)\n", pending - 1); | ||
160 | return -EIO; | ||
161 | } | ||
162 | |||
163 | /* finish pause - prepare for a new resume */ | ||
164 | static void lola_sync_pause(struct lola *chip, | ||
165 | struct snd_pcm_substream *substream) | ||
166 | { | ||
167 | struct snd_pcm_substream *s; | ||
168 | |||
169 | lola_sync_wait_for_fifo(chip, substream, false); | ||
170 | snd_pcm_group_for_each_entry(s, substream) { | ||
171 | struct lola_stream *str; | ||
172 | if (s->pcm->card != substream->pcm->card) | ||
173 | continue; | ||
174 | str = lola_get_stream(s); | ||
175 | if (str->paused && str->prepared) | ||
176 | lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRUN | | ||
177 | LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE); | ||
178 | } | ||
179 | lola_sync_wait_for_fifo(chip, substream, true); | ||
180 | } | ||
181 | |||
182 | static void lola_stream_reset(struct lola *chip, struct lola_stream *str) | ||
183 | { | ||
184 | if (str->prepared) { | ||
185 | if (str->paused) | ||
186 | lola_sync_pause(chip, str->substream); | ||
187 | str->prepared = 0; | ||
188 | lola_dsd_write(chip, str->dsd, CTL, | ||
189 | LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE); | ||
190 | lola_stream_wait_for_fifo(chip, str, false); | ||
191 | lola_stream_clear_pending_irq(chip, str); | ||
192 | lola_dsd_write(chip, str->dsd, CTL, LOLA_DSD_CTL_SRST); | ||
193 | lola_dsd_write(chip, str->dsd, LVI, 0); | ||
194 | lola_dsd_write(chip, str->dsd, BDPU, 0); | ||
195 | lola_dsd_write(chip, str->dsd, BDPL, 0); | ||
196 | wait_for_srst_clear(chip, str); | ||
197 | } | ||
198 | } | ||
199 | |||
200 | static struct snd_pcm_hardware lola_pcm_hw = { | ||
201 | .info = (SNDRV_PCM_INFO_MMAP | | ||
202 | SNDRV_PCM_INFO_INTERLEAVED | | ||
203 | SNDRV_PCM_INFO_BLOCK_TRANSFER | | ||
204 | SNDRV_PCM_INFO_MMAP_VALID | | ||
205 | SNDRV_PCM_INFO_PAUSE), | ||
206 | .formats = (SNDRV_PCM_FMTBIT_S16_LE | | ||
207 | SNDRV_PCM_FMTBIT_S24_LE | | ||
208 | SNDRV_PCM_FMTBIT_S32_LE | | ||
209 | SNDRV_PCM_FMTBIT_FLOAT_LE), | ||
210 | .rates = SNDRV_PCM_RATE_8000_192000, | ||
211 | .rate_min = 8000, | ||
212 | .rate_max = 192000, | ||
213 | .channels_min = 1, | ||
214 | .channels_max = 2, | ||
215 | .buffer_bytes_max = LOLA_MAX_BUF_SIZE, | ||
216 | .period_bytes_min = 128, | ||
217 | .period_bytes_max = LOLA_MAX_BUF_SIZE / 2, | ||
218 | .periods_min = 2, | ||
219 | .periods_max = LOLA_MAX_BDL_ENTRIES, | ||
220 | .fifo_size = 0, | ||
221 | }; | ||
222 | |||
223 | static int lola_pcm_open(struct snd_pcm_substream *substream) | ||
224 | { | ||
225 | struct lola *chip = snd_pcm_substream_chip(substream); | ||
226 | struct lola_pcm *pcm = lola_get_pcm(substream); | ||
227 | struct lola_stream *str = lola_get_stream(substream); | ||
228 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
229 | |||
230 | mutex_lock(&chip->open_mutex); | ||
231 | if (str->opened) { | ||
232 | mutex_unlock(&chip->open_mutex); | ||
233 | return -EBUSY; | ||
234 | } | ||
235 | str->substream = substream; | ||
236 | str->master = NULL; | ||
237 | str->opened = 1; | ||
238 | runtime->hw = lola_pcm_hw; | ||
239 | runtime->hw.channels_max = pcm->num_streams - str->index; | ||
240 | if (chip->sample_rate) { | ||
241 | /* sample rate is locked */ | ||
242 | runtime->hw.rate_min = chip->sample_rate; | ||
243 | runtime->hw.rate_max = chip->sample_rate; | ||
244 | } else { | ||
245 | runtime->hw.rate_min = chip->sample_rate_min; | ||
246 | runtime->hw.rate_max = chip->sample_rate_max; | ||
247 | } | ||
248 | chip->ref_count_rate++; | ||
249 | snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); | ||
250 | /* period size = multiple of chip->granularity (8, 16 or 32 frames)*/ | ||
251 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_BUFFER_SIZE, | ||
252 | chip->granularity); | ||
253 | snd_pcm_hw_constraint_step(runtime, 0, SNDRV_PCM_HW_PARAM_PERIOD_SIZE, | ||
254 | chip->granularity); | ||
255 | mutex_unlock(&chip->open_mutex); | ||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | static void lola_cleanup_slave_streams(struct lola_pcm *pcm, | ||
260 | struct lola_stream *str) | ||
261 | { | ||
262 | int i; | ||
263 | for (i = str->index + 1; i < pcm->num_streams; i++) { | ||
264 | struct lola_stream *s = &pcm->streams[i]; | ||
265 | if (s->master != str) | ||
266 | break; | ||
267 | s->master = NULL; | ||
268 | s->opened = 0; | ||
269 | } | ||
270 | } | ||
271 | |||
272 | static int lola_pcm_close(struct snd_pcm_substream *substream) | ||
273 | { | ||
274 | struct lola *chip = snd_pcm_substream_chip(substream); | ||
275 | struct lola_stream *str = lola_get_stream(substream); | ||
276 | |||
277 | mutex_lock(&chip->open_mutex); | ||
278 | if (str->substream == substream) { | ||
279 | str->substream = NULL; | ||
280 | str->opened = 0; | ||
281 | } | ||
282 | if (--chip->ref_count_rate == 0) { | ||
283 | /* release sample rate */ | ||
284 | chip->sample_rate = 0; | ||
285 | } | ||
286 | mutex_unlock(&chip->open_mutex); | ||
287 | return 0; | ||
288 | } | ||
289 | |||
290 | static int lola_pcm_hw_params(struct snd_pcm_substream *substream, | ||
291 | struct snd_pcm_hw_params *hw_params) | ||
292 | { | ||
293 | struct lola_stream *str = lola_get_stream(substream); | ||
294 | |||
295 | str->bufsize = 0; | ||
296 | str->period_bytes = 0; | ||
297 | str->format_verb = 0; | ||
298 | return snd_pcm_lib_malloc_pages(substream, | ||
299 | params_buffer_bytes(hw_params)); | ||
300 | } | ||
301 | |||
302 | static int lola_pcm_hw_free(struct snd_pcm_substream *substream) | ||
303 | { | ||
304 | struct lola *chip = snd_pcm_substream_chip(substream); | ||
305 | struct lola_pcm *pcm = lola_get_pcm(substream); | ||
306 | struct lola_stream *str = lola_get_stream(substream); | ||
307 | |||
308 | mutex_lock(&chip->open_mutex); | ||
309 | lola_stream_reset(chip, str); | ||
310 | lola_cleanup_slave_streams(pcm, str); | ||
311 | mutex_unlock(&chip->open_mutex); | ||
312 | return snd_pcm_lib_free_pages(substream); | ||
313 | } | ||
314 | |||
315 | /* | ||
316 | * set up a BDL entry | ||
317 | */ | ||
318 | static int setup_bdle(struct snd_pcm_substream *substream, | ||
319 | struct lola_stream *str, u32 **bdlp, | ||
320 | int ofs, int size) | ||
321 | { | ||
322 | u32 *bdl = *bdlp; | ||
323 | |||
324 | while (size > 0) { | ||
325 | dma_addr_t addr; | ||
326 | int chunk; | ||
327 | |||
328 | if (str->frags >= LOLA_MAX_BDL_ENTRIES) | ||
329 | return -EINVAL; | ||
330 | |||
331 | addr = snd_pcm_sgbuf_get_addr(substream, ofs); | ||
332 | /* program the address field of the BDL entry */ | ||
333 | bdl[0] = cpu_to_le32((u32)addr); | ||
334 | bdl[1] = cpu_to_le32(upper_32_bits(addr)); | ||
335 | /* program the size field of the BDL entry */ | ||
336 | chunk = snd_pcm_sgbuf_get_chunk_size(substream, ofs, size); | ||
337 | bdl[2] = cpu_to_le32(chunk); | ||
338 | /* program the IOC to enable interrupt | ||
339 | * only when the whole fragment is processed | ||
340 | */ | ||
341 | size -= chunk; | ||
342 | bdl[3] = size ? 0 : cpu_to_le32(0x01); | ||
343 | bdl += 4; | ||
344 | str->frags++; | ||
345 | ofs += chunk; | ||
346 | } | ||
347 | *bdlp = bdl; | ||
348 | return ofs; | ||
349 | } | ||
350 | |||
351 | /* | ||
352 | * set up BDL entries | ||
353 | */ | ||
354 | static int lola_setup_periods(struct lola *chip, struct lola_pcm *pcm, | ||
355 | struct snd_pcm_substream *substream, | ||
356 | struct lola_stream *str) | ||
357 | { | ||
358 | u32 *bdl; | ||
359 | int i, ofs, periods, period_bytes; | ||
360 | |||
361 | period_bytes = str->period_bytes; | ||
362 | periods = str->bufsize / period_bytes; | ||
363 | |||
364 | /* program the initial BDL entries */ | ||
365 | bdl = (u32 *)(pcm->bdl.area + LOLA_BDL_ENTRY_SIZE * str->index); | ||
366 | ofs = 0; | ||
367 | str->frags = 0; | ||
368 | for (i = 0; i < periods; i++) { | ||
369 | ofs = setup_bdle(substream, str, &bdl, ofs, period_bytes); | ||
370 | if (ofs < 0) | ||
371 | goto error; | ||
372 | } | ||
373 | return 0; | ||
374 | |||
375 | error: | ||
376 | snd_printk(KERN_ERR SFX "Too many BDL entries: buffer=%d, period=%d\n", | ||
377 | str->bufsize, period_bytes); | ||
378 | return -EINVAL; | ||
379 | } | ||
380 | |||
381 | static unsigned int lola_get_format_verb(struct snd_pcm_substream *substream) | ||
382 | { | ||
383 | unsigned int verb; | ||
384 | |||
385 | switch (substream->runtime->format) { | ||
386 | case SNDRV_PCM_FORMAT_S16_LE: | ||
387 | verb = 0x00000000; | ||
388 | break; | ||
389 | case SNDRV_PCM_FORMAT_S24_LE: | ||
390 | verb = 0x00000200; | ||
391 | break; | ||
392 | case SNDRV_PCM_FORMAT_S32_LE: | ||
393 | verb = 0x00000300; | ||
394 | break; | ||
395 | case SNDRV_PCM_FORMAT_FLOAT_LE: | ||
396 | verb = 0x00001300; | ||
397 | break; | ||
398 | default: | ||
399 | return 0; | ||
400 | } | ||
401 | verb |= substream->runtime->channels; | ||
402 | return verb; | ||
403 | } | ||
404 | |||
405 | static int lola_set_stream_config(struct lola *chip, | ||
406 | struct lola_stream *str, | ||
407 | int channels) | ||
408 | { | ||
409 | int i, err; | ||
410 | unsigned int verb, val; | ||
411 | |||
412 | /* set format info for all channels | ||
413 | * (with only one command for the first channel) | ||
414 | */ | ||
415 | err = lola_codec_read(chip, str->nid, LOLA_VERB_SET_STREAM_FORMAT, | ||
416 | str->format_verb, 0, &val, NULL); | ||
417 | if (err < 0) { | ||
418 | printk(KERN_ERR SFX "Cannot set stream format 0x%x\n", | ||
419 | str->format_verb); | ||
420 | return err; | ||
421 | } | ||
422 | |||
423 | /* update stream - channel config */ | ||
424 | for (i = 0; i < channels; i++) { | ||
425 | verb = (str->index << 6) | i; | ||
426 | err = lola_codec_read(chip, str[i].nid, | ||
427 | LOLA_VERB_SET_CHANNEL_STREAMID, 0, verb, | ||
428 | &val, NULL); | ||
429 | if (err < 0) { | ||
430 | printk(KERN_ERR SFX "Cannot set stream channel %d\n", i); | ||
431 | return err; | ||
432 | } | ||
433 | } | ||
434 | return 0; | ||
435 | } | ||
436 | |||
437 | /* | ||
438 | * set up the SD for streaming | ||
439 | */ | ||
440 | static int lola_setup_controller(struct lola *chip, struct lola_pcm *pcm, | ||
441 | struct lola_stream *str) | ||
442 | { | ||
443 | dma_addr_t bdl; | ||
444 | |||
445 | if (str->prepared) | ||
446 | return -EINVAL; | ||
447 | |||
448 | /* set up BDL */ | ||
449 | bdl = pcm->bdl.addr + LOLA_BDL_ENTRY_SIZE * str->index; | ||
450 | lola_dsd_write(chip, str->dsd, BDPL, (u32)bdl); | ||
451 | lola_dsd_write(chip, str->dsd, BDPU, upper_32_bits(bdl)); | ||
452 | /* program the stream LVI (last valid index) of the BDL */ | ||
453 | lola_dsd_write(chip, str->dsd, LVI, str->frags - 1); | ||
454 | lola_stream_clear_pending_irq(chip, str); | ||
455 | |||
456 | lola_dsd_write(chip, str->dsd, CTL, | ||
457 | LOLA_DSD_CTL_IOCE | LOLA_DSD_CTL_DEIE | LOLA_DSD_CTL_SRUN); | ||
458 | |||
459 | str->prepared = 1; | ||
460 | |||
461 | return lola_stream_wait_for_fifo(chip, str, true); | ||
462 | } | ||
463 | |||
464 | static int lola_pcm_prepare(struct snd_pcm_substream *substream) | ||
465 | { | ||
466 | struct lola *chip = snd_pcm_substream_chip(substream); | ||
467 | struct lola_pcm *pcm = lola_get_pcm(substream); | ||
468 | struct lola_stream *str = lola_get_stream(substream); | ||
469 | struct snd_pcm_runtime *runtime = substream->runtime; | ||
470 | unsigned int bufsize, period_bytes, format_verb; | ||
471 | int i, err; | ||
472 | |||
473 | mutex_lock(&chip->open_mutex); | ||
474 | lola_stream_reset(chip, str); | ||
475 | lola_cleanup_slave_streams(pcm, str); | ||
476 | if (str->index + runtime->channels > pcm->num_streams) { | ||
477 | mutex_unlock(&chip->open_mutex); | ||
478 | return -EINVAL; | ||
479 | } | ||
480 | for (i = 1; i < runtime->channels; i++) { | ||
481 | str[i].master = str; | ||
482 | str[i].opened = 1; | ||
483 | } | ||
484 | mutex_unlock(&chip->open_mutex); | ||
485 | |||
486 | bufsize = snd_pcm_lib_buffer_bytes(substream); | ||
487 | period_bytes = snd_pcm_lib_period_bytes(substream); | ||
488 | format_verb = lola_get_format_verb(substream); | ||
489 | |||
490 | str->bufsize = bufsize; | ||
491 | str->period_bytes = period_bytes; | ||
492 | str->format_verb = format_verb; | ||
493 | |||
494 | err = lola_setup_periods(chip, pcm, substream, str); | ||
495 | if (err < 0) | ||
496 | return err; | ||
497 | |||
498 | err = lola_set_sample_rate(chip, runtime->rate); | ||
499 | if (err < 0) | ||
500 | return err; | ||
501 | chip->sample_rate = runtime->rate; /* sample rate gets locked */ | ||
502 | |||
503 | err = lola_set_stream_config(chip, str, runtime->channels); | ||
504 | if (err < 0) | ||
505 | return err; | ||
506 | |||
507 | err = lola_setup_controller(chip, pcm, str); | ||
508 | if (err < 0) { | ||
509 | lola_stream_reset(chip, str); | ||
510 | return err; | ||
511 | } | ||
512 | |||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | static int lola_pcm_trigger(struct snd_pcm_substream *substream, int cmd) | ||
517 | { | ||
518 | struct lola *chip = snd_pcm_substream_chip(substream); | ||
519 | struct lola_stream *str; | ||
520 | struct snd_pcm_substream *s; | ||
521 | unsigned int start; | ||
522 | unsigned int tstamp; | ||
523 | bool sync_streams; | ||
524 | |||
525 | switch (cmd) { | ||
526 | case SNDRV_PCM_TRIGGER_START: | ||
527 | case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: | ||
528 | case SNDRV_PCM_TRIGGER_RESUME: | ||
529 | start = 1; | ||
530 | break; | ||
531 | case SNDRV_PCM_TRIGGER_PAUSE_PUSH: | ||
532 | case SNDRV_PCM_TRIGGER_SUSPEND: | ||
533 | case SNDRV_PCM_TRIGGER_STOP: | ||
534 | start = 0; | ||
535 | break; | ||
536 | default: | ||
537 | return -EINVAL; | ||
538 | } | ||
539 | |||
540 | /* | ||
541 | * sample correct synchronization is only needed starting several | ||
542 | * streams. On stop or if only one stream do as quick as possible | ||
543 | */ | ||
544 | sync_streams = (start && snd_pcm_stream_linked(substream)); | ||
545 | tstamp = lola_get_tstamp(chip, !sync_streams); | ||
546 | spin_lock(&chip->reg_lock); | ||
547 | snd_pcm_group_for_each_entry(s, substream) { | ||
548 | if (s->pcm->card != substream->pcm->card) | ||
549 | continue; | ||
550 | str = lola_get_stream(s); | ||
551 | if (start) | ||
552 | lola_stream_start(chip, str, tstamp); | ||
553 | else | ||
554 | lola_stream_stop(chip, str, tstamp); | ||
555 | str->running = start; | ||
556 | str->paused = !start; | ||
557 | snd_pcm_trigger_done(s, substream); | ||
558 | } | ||
559 | spin_unlock(&chip->reg_lock); | ||
560 | return 0; | ||
561 | } | ||
562 | |||
563 | static snd_pcm_uframes_t lola_pcm_pointer(struct snd_pcm_substream *substream) | ||
564 | { | ||
565 | struct lola *chip = snd_pcm_substream_chip(substream); | ||
566 | struct lola_stream *str = lola_get_stream(substream); | ||
567 | unsigned int pos = lola_dsd_read(chip, str->dsd, LPIB); | ||
568 | |||
569 | if (pos >= str->bufsize) | ||
570 | pos = 0; | ||
571 | return bytes_to_frames(substream->runtime, pos); | ||
572 | } | ||
573 | |||
574 | void lola_pcm_update(struct lola *chip, struct lola_pcm *pcm, unsigned int bits) | ||
575 | { | ||
576 | int i; | ||
577 | |||
578 | for (i = 0; bits && i < pcm->num_streams; i++) { | ||
579 | if (bits & (1 << i)) { | ||
580 | struct lola_stream *str = &pcm->streams[i]; | ||
581 | if (str->substream && str->running) | ||
582 | snd_pcm_period_elapsed(str->substream); | ||
583 | bits &= ~(1 << i); | ||
584 | } | ||
585 | } | ||
586 | } | ||
587 | |||
588 | static struct snd_pcm_ops lola_pcm_ops = { | ||
589 | .open = lola_pcm_open, | ||
590 | .close = lola_pcm_close, | ||
591 | .ioctl = snd_pcm_lib_ioctl, | ||
592 | .hw_params = lola_pcm_hw_params, | ||
593 | .hw_free = lola_pcm_hw_free, | ||
594 | .prepare = lola_pcm_prepare, | ||
595 | .trigger = lola_pcm_trigger, | ||
596 | .pointer = lola_pcm_pointer, | ||
597 | .page = snd_pcm_sgbuf_ops_page, | ||
598 | }; | ||
599 | |||
600 | int __devinit lola_create_pcm(struct lola *chip) | ||
601 | { | ||
602 | struct snd_pcm *pcm; | ||
603 | int i, err; | ||
604 | |||
605 | for (i = 0; i < 2; i++) { | ||
606 | err = snd_dma_alloc_pages(SNDRV_DMA_TYPE_DEV, | ||
607 | snd_dma_pci_data(chip->pci), | ||
608 | PAGE_SIZE, &chip->pcm[i].bdl); | ||
609 | if (err < 0) | ||
610 | return err; | ||
611 | } | ||
612 | |||
613 | err = snd_pcm_new(chip->card, "Digigram Lola", 0, | ||
614 | chip->pcm[SNDRV_PCM_STREAM_PLAYBACK].num_streams, | ||
615 | chip->pcm[SNDRV_PCM_STREAM_CAPTURE].num_streams, | ||
616 | &pcm); | ||
617 | if (err < 0) | ||
618 | return err; | ||
619 | strlcpy(pcm->name, "Digigram Lola", sizeof(pcm->name)); | ||
620 | pcm->private_data = chip; | ||
621 | for (i = 0; i < 2; i++) { | ||
622 | if (chip->pcm[i].num_streams) | ||
623 | snd_pcm_set_ops(pcm, i, &lola_pcm_ops); | ||
624 | } | ||
625 | /* buffer pre-allocation */ | ||
626 | snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV_SG, | ||
627 | snd_dma_pci_data(chip->pci), | ||
628 | 1024 * 64, 32 * 1024 * 1024); | ||
629 | return 0; | ||
630 | } | ||
631 | |||
632 | void lola_free_pcm(struct lola *chip) | ||
633 | { | ||
634 | snd_dma_free_pages(&chip->pcm[0].bdl); | ||
635 | snd_dma_free_pages(&chip->pcm[1].bdl); | ||
636 | } | ||
637 | |||
638 | /* | ||
639 | */ | ||
640 | |||
641 | static int lola_init_stream(struct lola *chip, struct lola_stream *str, | ||
642 | int idx, int nid, int dir) | ||
643 | { | ||
644 | unsigned int val; | ||
645 | int err; | ||
646 | |||
647 | str->nid = nid; | ||
648 | str->index = idx; | ||
649 | str->dsd = idx; | ||
650 | if (dir == PLAY) | ||
651 | str->dsd += MAX_STREAM_IN_COUNT; | ||
652 | err = lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); | ||
653 | if (err < 0) { | ||
654 | printk(KERN_ERR SFX "Can't read wcaps for 0x%x\n", nid); | ||
655 | return err; | ||
656 | } | ||
657 | if (dir == PLAY) { | ||
658 | /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1) */ | ||
659 | if ((val & 0x00f00dff) != 0x00000010) { | ||
660 | printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n", | ||
661 | val, nid); | ||
662 | return -EINVAL; | ||
663 | } | ||
664 | } else { | ||
665 | /* test TYPE and bits 0..11 (no test bit9 : Digital = 0/1) | ||
666 | * (bug : ignore bit8: Conn list = 0/1) | ||
667 | */ | ||
668 | if ((val & 0x00f00cff) != 0x00100010) { | ||
669 | printk(KERN_ERR SFX "Invalid wcaps 0x%x for 0x%x\n", | ||
670 | val, nid); | ||
671 | return -EINVAL; | ||
672 | } | ||
673 | /* test bit9:DIGITAL and bit12:SRC_PRESENT*/ | ||
674 | if ((val & 0x00001200) == 0x00001200) | ||
675 | chip->input_src_caps_mask |= (1 << idx); | ||
676 | } | ||
677 | |||
678 | err = lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val); | ||
679 | if (err < 0) { | ||
680 | printk(KERN_ERR SFX "Can't read FORMATS 0x%x\n", nid); | ||
681 | return err; | ||
682 | } | ||
683 | val &= 3; | ||
684 | if (val == 3) | ||
685 | str->can_float = true; | ||
686 | if (!(val & 1)) { | ||
687 | printk(KERN_ERR SFX "Invalid formats 0x%x for 0x%x", val, nid); | ||
688 | return -EINVAL; | ||
689 | } | ||
690 | return 0; | ||
691 | } | ||
692 | |||
693 | int __devinit lola_init_pcm(struct lola *chip, int dir, int *nidp) | ||
694 | { | ||
695 | struct lola_pcm *pcm = &chip->pcm[dir]; | ||
696 | int i, nid, err; | ||
697 | |||
698 | nid = *nidp; | ||
699 | for (i = 0; i < pcm->num_streams; i++, nid++) { | ||
700 | err = lola_init_stream(chip, &pcm->streams[i], i, nid, dir); | ||
701 | if (err < 0) | ||
702 | return err; | ||
703 | } | ||
704 | *nidp = nid; | ||
705 | return 0; | ||
706 | } | ||
diff --git a/sound/pci/lola/lola_proc.c b/sound/pci/lola/lola_proc.c new file mode 100644 index 000000000000..9d7daf897c9d --- /dev/null +++ b/sound/pci/lola/lola_proc.c | |||
@@ -0,0 +1,222 @@ | |||
1 | /* | ||
2 | * Support for Digigram Lola PCI-e boards | ||
3 | * | ||
4 | * Copyright (c) 2011 Takashi Iwai <tiwai@suse.de> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the Free | ||
8 | * Software Foundation; either version 2 of the License, or (at your option) | ||
9 | * any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but WITHOUT | ||
12 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | ||
13 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | ||
14 | * more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License along with | ||
17 | * this program; if not, write to the Free Software Foundation, Inc., 59 | ||
18 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | */ | ||
20 | |||
21 | #include <linux/kernel.h> | ||
22 | #include <linux/init.h> | ||
23 | #include <linux/io.h> | ||
24 | #include <sound/core.h> | ||
25 | #include <sound/info.h> | ||
26 | #include <sound/pcm.h> | ||
27 | #include "lola.h" | ||
28 | |||
29 | static void print_audio_widget(struct snd_info_buffer *buffer, | ||
30 | struct lola *chip, int nid, const char *name) | ||
31 | { | ||
32 | unsigned int val; | ||
33 | |||
34 | lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); | ||
35 | snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val); | ||
36 | lola_read_param(chip, nid, LOLA_PAR_STREAM_FORMATS, &val); | ||
37 | snd_iprintf(buffer, " Formats: 0x%x\n", val); | ||
38 | } | ||
39 | |||
40 | static void print_pin_widget(struct snd_info_buffer *buffer, | ||
41 | struct lola *chip, int nid, unsigned int ampcap, | ||
42 | const char *name) | ||
43 | { | ||
44 | unsigned int val; | ||
45 | |||
46 | lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); | ||
47 | snd_iprintf(buffer, "Node 0x%02x %s wcaps 0x%x\n", nid, name, val); | ||
48 | if (val == 0x00400200) | ||
49 | return; | ||
50 | lola_read_param(chip, nid, ampcap, &val); | ||
51 | snd_iprintf(buffer, " Amp-Caps: 0x%x\n", val); | ||
52 | snd_iprintf(buffer, " mute=%d, step-size=%d, steps=%d, ofs=%d\n", | ||
53 | LOLA_AMP_MUTE_CAPABLE(val), | ||
54 | LOLA_AMP_STEP_SIZE(val), | ||
55 | LOLA_AMP_NUM_STEPS(val), | ||
56 | LOLA_AMP_OFFSET(val)); | ||
57 | lola_codec_read(chip, nid, LOLA_VERB_GET_MAX_LEVEL, 0, 0, &val, NULL); | ||
58 | snd_iprintf(buffer, " Max-level: 0x%x\n", val); | ||
59 | } | ||
60 | |||
61 | static void print_clock_widget(struct snd_info_buffer *buffer, | ||
62 | struct lola *chip, int nid) | ||
63 | { | ||
64 | int i, j, num_clocks; | ||
65 | unsigned int val; | ||
66 | |||
67 | lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); | ||
68 | snd_iprintf(buffer, "Node 0x%02x [Clock] wcaps 0x%x\n", nid, val); | ||
69 | num_clocks = val & 0xff; | ||
70 | for (i = 0; i < num_clocks; i += 4) { | ||
71 | unsigned int res_ex; | ||
72 | unsigned short items[4]; | ||
73 | const char *name; | ||
74 | |||
75 | lola_codec_read(chip, nid, LOLA_VERB_GET_CLOCK_LIST, | ||
76 | i, 0, &val, &res_ex); | ||
77 | items[0] = val & 0xfff; | ||
78 | items[1] = (val >> 16) & 0xfff; | ||
79 | items[2] = res_ex & 0xfff; | ||
80 | items[3] = (res_ex >> 16) & 0xfff; | ||
81 | for (j = 0; j < 4; j++) { | ||
82 | unsigned char type = items[j] >> 8; | ||
83 | unsigned int freq = items[j] & 0xff; | ||
84 | if (i + j >= num_clocks) | ||
85 | break; | ||
86 | if (type == LOLA_CLOCK_TYPE_INTERNAL) { | ||
87 | name = "Internal"; | ||
88 | freq = lola_sample_rate_convert(freq); | ||
89 | } else if (type == LOLA_CLOCK_TYPE_VIDEO) { | ||
90 | name = "Video"; | ||
91 | freq = lola_sample_rate_convert(freq); | ||
92 | } else { | ||
93 | name = "Other"; | ||
94 | } | ||
95 | snd_iprintf(buffer, " Clock %d: Type %d:%s, freq=%d\n", | ||
96 | i + j, type, name, freq); | ||
97 | } | ||
98 | } | ||
99 | } | ||
100 | |||
101 | static void print_mixer_widget(struct snd_info_buffer *buffer, | ||
102 | struct lola *chip, int nid) | ||
103 | { | ||
104 | unsigned int val; | ||
105 | |||
106 | lola_read_param(chip, nid, LOLA_PAR_AUDIO_WIDGET_CAP, &val); | ||
107 | snd_iprintf(buffer, "Node 0x%02x [Mixer] wcaps 0x%x\n", nid, val); | ||
108 | } | ||
109 | |||
110 | static void lola_proc_codec_read(struct snd_info_entry *entry, | ||
111 | struct snd_info_buffer *buffer) | ||
112 | { | ||
113 | struct lola *chip = entry->private_data; | ||
114 | unsigned int val; | ||
115 | int i, nid; | ||
116 | |||
117 | lola_read_param(chip, 0, LOLA_PAR_VENDOR_ID, &val); | ||
118 | snd_iprintf(buffer, "Vendor: 0x%08x\n", val); | ||
119 | lola_read_param(chip, 1, LOLA_PAR_FUNCTION_TYPE, &val); | ||
120 | snd_iprintf(buffer, "Function Type: %d\n", val); | ||
121 | lola_read_param(chip, 1, LOLA_PAR_SPECIFIC_CAPS, &val); | ||
122 | snd_iprintf(buffer, "Specific-Caps: 0x%08x\n", val); | ||
123 | snd_iprintf(buffer, " Pins-In %d, Pins-Out %d\n", | ||
124 | chip->pin[CAPT].num_pins, chip->pin[PLAY].num_pins); | ||
125 | nid = 2; | ||
126 | for (i = 0; i < chip->pcm[CAPT].num_streams; i++, nid++) | ||
127 | print_audio_widget(buffer, chip, nid, "[Audio-In]"); | ||
128 | for (i = 0; i < chip->pcm[PLAY].num_streams; i++, nid++) | ||
129 | print_audio_widget(buffer, chip, nid, "[Audio-Out]"); | ||
130 | for (i = 0; i < chip->pin[CAPT].num_pins; i++, nid++) | ||
131 | print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_IN_CAP, | ||
132 | "[Pin-In]"); | ||
133 | for (i = 0; i < chip->pin[PLAY].num_pins; i++, nid++) | ||
134 | print_pin_widget(buffer, chip, nid, LOLA_PAR_AMP_OUT_CAP, | ||
135 | "[Pin-Out]"); | ||
136 | if (LOLA_AFG_CLOCK_WIDGET_PRESENT(chip->lola_caps)) { | ||
137 | print_clock_widget(buffer, chip, nid); | ||
138 | nid++; | ||
139 | } | ||
140 | if (LOLA_AFG_MIXER_WIDGET_PRESENT(chip->lola_caps)) { | ||
141 | print_mixer_widget(buffer, chip, nid); | ||
142 | nid++; | ||
143 | } | ||
144 | } | ||
145 | |||
146 | /* direct codec access for debugging */ | ||
147 | static void lola_proc_codec_rw_write(struct snd_info_entry *entry, | ||
148 | struct snd_info_buffer *buffer) | ||
149 | { | ||
150 | struct lola *chip = entry->private_data; | ||
151 | char line[64]; | ||
152 | unsigned int id, verb, data, extdata; | ||
153 | while (!snd_info_get_line(buffer, line, sizeof(line))) { | ||
154 | if (sscanf(line, "%i %i %i %i", &id, &verb, &data, &extdata) != 4) | ||
155 | continue; | ||
156 | lola_codec_read(chip, id, verb, data, extdata, | ||
157 | &chip->debug_res, | ||
158 | &chip->debug_res_ex); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | static void lola_proc_codec_rw_read(struct snd_info_entry *entry, | ||
163 | struct snd_info_buffer *buffer) | ||
164 | { | ||
165 | struct lola *chip = entry->private_data; | ||
166 | snd_iprintf(buffer, "0x%x 0x%x\n", chip->debug_res, chip->debug_res_ex); | ||
167 | } | ||
168 | |||
169 | /* | ||
170 | * dump some registers | ||
171 | */ | ||
172 | static void lola_proc_regs_read(struct snd_info_entry *entry, | ||
173 | struct snd_info_buffer *buffer) | ||
174 | { | ||
175 | struct lola *chip = entry->private_data; | ||
176 | int i; | ||
177 | |||
178 | for (i = 0; i < 0x40; i += 4) { | ||
179 | snd_iprintf(buffer, "BAR0 %02x: %08x\n", i, | ||
180 | readl(chip->bar[BAR0].remap_addr + i)); | ||
181 | } | ||
182 | snd_iprintf(buffer, "\n"); | ||
183 | for (i = 0; i < 0x30; i += 4) { | ||
184 | snd_iprintf(buffer, "BAR1 %02x: %08x\n", i, | ||
185 | readl(chip->bar[BAR1].remap_addr + i)); | ||
186 | } | ||
187 | snd_iprintf(buffer, "\n"); | ||
188 | for (i = 0x80; i < 0xa0; i += 4) { | ||
189 | snd_iprintf(buffer, "BAR1 %02x: %08x\n", i, | ||
190 | readl(chip->bar[BAR1].remap_addr + i)); | ||
191 | } | ||
192 | snd_iprintf(buffer, "\n"); | ||
193 | for (i = 0; i < 32; i++) { | ||
194 | snd_iprintf(buffer, "DSD %02x STS %08x\n", i, | ||
195 | lola_dsd_read(chip, i, STS)); | ||
196 | snd_iprintf(buffer, "DSD %02x LPIB %08x\n", i, | ||
197 | lola_dsd_read(chip, i, LPIB)); | ||
198 | snd_iprintf(buffer, "DSD %02x CTL %08x\n", i, | ||
199 | lola_dsd_read(chip, i, CTL)); | ||
200 | snd_iprintf(buffer, "DSD %02x LVIL %08x\n", i, | ||
201 | lola_dsd_read(chip, i, LVI)); | ||
202 | snd_iprintf(buffer, "DSD %02x BDPL %08x\n", i, | ||
203 | lola_dsd_read(chip, i, BDPL)); | ||
204 | snd_iprintf(buffer, "DSD %02x BDPU %08x\n", i, | ||
205 | lola_dsd_read(chip, i, BDPU)); | ||
206 | } | ||
207 | } | ||
208 | |||
209 | void __devinit lola_proc_debug_new(struct lola *chip) | ||
210 | { | ||
211 | struct snd_info_entry *entry; | ||
212 | |||
213 | if (!snd_card_proc_new(chip->card, "codec", &entry)) | ||
214 | snd_info_set_text_ops(entry, chip, lola_proc_codec_read); | ||
215 | if (!snd_card_proc_new(chip->card, "codec_rw", &entry)) { | ||
216 | snd_info_set_text_ops(entry, chip, lola_proc_codec_rw_read); | ||
217 | entry->mode |= S_IWUSR; | ||
218 | entry->c.text.write = lola_proc_codec_rw_write; | ||
219 | } | ||
220 | if (!snd_card_proc_new(chip->card, "regs", &entry)) | ||
221 | snd_info_set_text_ops(entry, chip, lola_proc_regs_read); | ||
222 | } | ||
diff --git a/sound/pcmcia/pdaudiocf/pdaudiocf.c b/sound/pcmcia/pdaudiocf/pdaudiocf.c index 8cc4733698a0..ce33be0e4e98 100644 --- a/sound/pcmcia/pdaudiocf/pdaudiocf.c +++ b/sound/pcmcia/pdaudiocf/pdaudiocf.c | |||
@@ -278,7 +278,7 @@ static int pdacf_resume(struct pcmcia_device *link) | |||
278 | /* | 278 | /* |
279 | * Module entry points | 279 | * Module entry points |
280 | */ | 280 | */ |
281 | static struct pcmcia_device_id snd_pdacf_ids[] = { | 281 | static const struct pcmcia_device_id snd_pdacf_ids[] = { |
282 | /* this is too general PCMCIA_DEVICE_MANF_CARD(0x015d, 0x4c45), */ | 282 | /* this is too general PCMCIA_DEVICE_MANF_CARD(0x015d, 0x4c45), */ |
283 | PCMCIA_DEVICE_PROD_ID12("Core Sound","PDAudio-CF",0x396d19d2,0x71717b49), | 283 | PCMCIA_DEVICE_PROD_ID12("Core Sound","PDAudio-CF",0x396d19d2,0x71717b49), |
284 | PCMCIA_DEVICE_NULL | 284 | PCMCIA_DEVICE_NULL |
diff --git a/sound/pcmcia/vx/vxpocket.c b/sound/pcmcia/vx/vxpocket.c index 80000d631f88..d9ef21d8fa73 100644 --- a/sound/pcmcia/vx/vxpocket.c +++ b/sound/pcmcia/vx/vxpocket.c | |||
@@ -350,7 +350,7 @@ static void vxpocket_detach(struct pcmcia_device *link) | |||
350 | * Module entry points | 350 | * Module entry points |
351 | */ | 351 | */ |
352 | 352 | ||
353 | static struct pcmcia_device_id vxp_ids[] = { | 353 | static const struct pcmcia_device_id vxp_ids[] = { |
354 | PCMCIA_DEVICE_MANF_CARD(0x01f1, 0x0100), | 354 | PCMCIA_DEVICE_MANF_CARD(0x01f1, 0x0100), |
355 | PCMCIA_DEVICE_NULL | 355 | PCMCIA_DEVICE_NULL |
356 | }; | 356 | }; |
diff --git a/sound/ppc/tumbler.c b/sound/ppc/tumbler.c index 961d98297695..9cea84c3e0c6 100644 --- a/sound/ppc/tumbler.c +++ b/sound/ppc/tumbler.c | |||
@@ -1000,7 +1000,7 @@ static void device_change_handler(struct work_struct *work) | |||
1000 | chip->lineout_sw_ctl); | 1000 | chip->lineout_sw_ctl); |
1001 | if (mix->anded_reset) | 1001 | if (mix->anded_reset) |
1002 | msleep(10); | 1002 | msleep(10); |
1003 | check_mute(chip, &mix->amp_mute, 1, mix->auto_mute_notify, | 1003 | check_mute(chip, &mix->amp_mute, !IS_G4DA, mix->auto_mute_notify, |
1004 | chip->speaker_sw_ctl); | 1004 | chip->speaker_sw_ctl); |
1005 | } else { | 1005 | } else { |
1006 | /* unmute speaker, mute others */ | 1006 | /* unmute speaker, mute others */ |
diff --git a/sound/soc/atmel/atmel_ssc_dai.c b/sound/soc/atmel/atmel_ssc_dai.c index a7a7bbc07627..f53dc09c48f3 100644 --- a/sound/soc/atmel/atmel_ssc_dai.c +++ b/sound/soc/atmel/atmel_ssc_dai.c | |||
@@ -846,9 +846,10 @@ int atmel_ssc_set_audio(int ssc_id) | |||
846 | if (IS_ERR(ssc)) | 846 | if (IS_ERR(ssc)) |
847 | pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n", | 847 | pr_warn("Unable to parent ASoC SSC DAI on SSC: %ld\n", |
848 | PTR_ERR(ssc)); | 848 | PTR_ERR(ssc)); |
849 | else | 849 | else { |
850 | ssc_pdev->dev.parent = &(ssc->pdev->dev); | 850 | ssc_pdev->dev.parent = &(ssc->pdev->dev); |
851 | ssc_free(ssc); | 851 | ssc_free(ssc); |
852 | } | ||
852 | 853 | ||
853 | ret = platform_device_add(ssc_pdev); | 854 | ret = platform_device_add(ssc_pdev); |
854 | if (ret < 0) | 855 | if (ret < 0) |
diff --git a/sound/soc/codecs/cq93vc.c b/sound/soc/codecs/cq93vc.c index b8066ef10bb0..46dbfd067f79 100644 --- a/sound/soc/codecs/cq93vc.c +++ b/sound/soc/codecs/cq93vc.c | |||
@@ -153,8 +153,7 @@ static int cq93vc_resume(struct snd_soc_codec *codec) | |||
153 | 153 | ||
154 | static int cq93vc_probe(struct snd_soc_codec *codec) | 154 | static int cq93vc_probe(struct snd_soc_codec *codec) |
155 | { | 155 | { |
156 | struct davinci_vc *davinci_vc = | 156 | struct davinci_vc *davinci_vc = codec->dev->platform_data; |
157 | mfd_get_data(to_platform_device(codec->dev)); | ||
158 | 157 | ||
159 | davinci_vc->cq93vc.codec = codec; | 158 | davinci_vc->cq93vc.codec = codec; |
160 | codec->control_data = davinci_vc; | 159 | codec->control_data = davinci_vc; |
diff --git a/sound/soc/codecs/cx20442.c b/sound/soc/codecs/cx20442.c index d68ea532cc7f..f8c663dcff02 100644 --- a/sound/soc/codecs/cx20442.c +++ b/sound/soc/codecs/cx20442.c | |||
@@ -262,14 +262,14 @@ static int v253_hangup(struct tty_struct *tty) | |||
262 | } | 262 | } |
263 | 263 | ||
264 | /* Line discipline .receive_buf() */ | 264 | /* Line discipline .receive_buf() */ |
265 | static void v253_receive(struct tty_struct *tty, | 265 | static unsigned int v253_receive(struct tty_struct *tty, |
266 | const unsigned char *cp, char *fp, int count) | 266 | const unsigned char *cp, char *fp, int count) |
267 | { | 267 | { |
268 | struct snd_soc_codec *codec = tty->disc_data; | 268 | struct snd_soc_codec *codec = tty->disc_data; |
269 | struct cx20442_priv *cx20442; | 269 | struct cx20442_priv *cx20442; |
270 | 270 | ||
271 | if (!codec) | 271 | if (!codec) |
272 | return; | 272 | return count; |
273 | 273 | ||
274 | cx20442 = snd_soc_codec_get_drvdata(codec); | 274 | cx20442 = snd_soc_codec_get_drvdata(codec); |
275 | 275 | ||
@@ -281,6 +281,8 @@ static void v253_receive(struct tty_struct *tty, | |||
281 | codec->hw_write = (hw_write_t)tty->ops->write; | 281 | codec->hw_write = (hw_write_t)tty->ops->write; |
282 | codec->card->pop_time = 1; | 282 | codec->card->pop_time = 1; |
283 | } | 283 | } |
284 | |||
285 | return count; | ||
284 | } | 286 | } |
285 | 287 | ||
286 | /* Line discipline .write_wakeup() */ | 288 | /* Line discipline .write_wakeup() */ |
diff --git a/sound/soc/codecs/twl4030.c b/sound/soc/codecs/twl4030.c index 575238d68e5e..bec788b12613 100644 --- a/sound/soc/codecs/twl4030.c +++ b/sound/soc/codecs/twl4030.c | |||
@@ -26,7 +26,6 @@ | |||
26 | #include <linux/pm.h> | 26 | #include <linux/pm.h> |
27 | #include <linux/i2c.h> | 27 | #include <linux/i2c.h> |
28 | #include <linux/platform_device.h> | 28 | #include <linux/platform_device.h> |
29 | #include <linux/mfd/core.h> | ||
30 | #include <linux/i2c/twl.h> | 29 | #include <linux/i2c/twl.h> |
31 | #include <linux/slab.h> | 30 | #include <linux/slab.h> |
32 | #include <sound/core.h> | 31 | #include <sound/core.h> |
@@ -733,8 +732,7 @@ static int aif_event(struct snd_soc_dapm_widget *w, | |||
733 | 732 | ||
734 | static void headset_ramp(struct snd_soc_codec *codec, int ramp) | 733 | static void headset_ramp(struct snd_soc_codec *codec, int ramp) |
735 | { | 734 | { |
736 | struct twl4030_codec_audio_data *pdata = | 735 | struct twl4030_codec_audio_data *pdata = codec->dev->platform_data; |
737 | mfd_get_data(to_platform_device(codec->dev)); | ||
738 | unsigned char hs_gain, hs_pop; | 736 | unsigned char hs_gain, hs_pop; |
739 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); | 737 | struct twl4030_priv *twl4030 = snd_soc_codec_get_drvdata(codec); |
740 | /* Base values for ramp delay calculation: 2^19 - 2^26 */ | 738 | /* Base values for ramp delay calculation: 2^19 - 2^26 */ |
@@ -2299,7 +2297,7 @@ static struct snd_soc_codec_driver soc_codec_dev_twl4030 = { | |||
2299 | 2297 | ||
2300 | static int __devinit twl4030_codec_probe(struct platform_device *pdev) | 2298 | static int __devinit twl4030_codec_probe(struct platform_device *pdev) |
2301 | { | 2299 | { |
2302 | struct twl4030_codec_audio_data *pdata = mfd_get_data(pdev); | 2300 | struct twl4030_codec_audio_data *pdata = pdev->dev.platform_data; |
2303 | 2301 | ||
2304 | if (!pdata) { | 2302 | if (!pdata) { |
2305 | dev_err(&pdev->dev, "platform_data is missing\n"); | 2303 | dev_err(&pdev->dev, "platform_data is missing\n"); |
diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c index c8a874d0d4ca..5836201834d9 100644 --- a/sound/soc/codecs/wl1273.c +++ b/sound/soc/codecs/wl1273.c | |||
@@ -441,8 +441,7 @@ EXPORT_SYMBOL_GPL(wl1273_get_format); | |||
441 | 441 | ||
442 | static int wl1273_probe(struct snd_soc_codec *codec) | 442 | static int wl1273_probe(struct snd_soc_codec *codec) |
443 | { | 443 | { |
444 | struct wl1273_core **core = | 444 | struct wl1273_core **core = codec->dev->platform_data; |
445 | mfd_get_data(to_platform_device(codec->dev)); | ||
446 | struct wl1273_priv *wl1273; | 445 | struct wl1273_priv *wl1273; |
447 | int r; | 446 | int r; |
448 | 447 | ||
diff --git a/sound/soc/codecs/wm8400.c b/sound/soc/codecs/wm8400.c index 736b785e3756..fbee556cbf35 100644 --- a/sound/soc/codecs/wm8400.c +++ b/sound/soc/codecs/wm8400.c | |||
@@ -1378,7 +1378,7 @@ static void wm8400_probe_deferred(struct work_struct *work) | |||
1378 | 1378 | ||
1379 | static int wm8400_codec_probe(struct snd_soc_codec *codec) | 1379 | static int wm8400_codec_probe(struct snd_soc_codec *codec) |
1380 | { | 1380 | { |
1381 | struct wm8400 *wm8400 = mfd_get_data(to_platform_device(codec->dev)); | 1381 | struct wm8400 *wm8400 = dev_get_platdata(codec->dev); |
1382 | struct wm8400_priv *priv; | 1382 | struct wm8400_priv *priv; |
1383 | int ret; | 1383 | int ret; |
1384 | u16 reg; | 1384 | u16 reg; |
diff --git a/sound/soc/davinci/davinci-vcif.c b/sound/soc/davinci/davinci-vcif.c index 13e05a302a92..9259f1f34899 100644 --- a/sound/soc/davinci/davinci-vcif.c +++ b/sound/soc/davinci/davinci-vcif.c | |||
@@ -205,7 +205,7 @@ static struct snd_soc_dai_driver davinci_vcif_dai = { | |||
205 | 205 | ||
206 | static int davinci_vcif_probe(struct platform_device *pdev) | 206 | static int davinci_vcif_probe(struct platform_device *pdev) |
207 | { | 207 | { |
208 | struct davinci_vc *davinci_vc = mfd_get_data(pdev); | 208 | struct davinci_vc *davinci_vc = pdev->dev.platform_data; |
209 | struct davinci_vcif_dev *davinci_vcif_dev; | 209 | struct davinci_vcif_dev *davinci_vcif_dev; |
210 | int ret; | 210 | int ret; |
211 | 211 | ||
diff --git a/sound/soc/omap/Kconfig b/sound/soc/omap/Kconfig index b5922984eac6..99054cf1f68f 100644 --- a/sound/soc/omap/Kconfig +++ b/sound/soc/omap/Kconfig | |||
@@ -65,14 +65,6 @@ config SND_OMAP_SOC_OVERO | |||
65 | Say Y if you want to add support for SoC audio on the | 65 | Say Y if you want to add support for SoC audio on the |
66 | Gumstix Overo or CompuLab CM-T35 | 66 | Gumstix Overo or CompuLab CM-T35 |
67 | 67 | ||
68 | config SND_OMAP_SOC_OMAP2EVM | ||
69 | tristate "SoC Audio support for OMAP2EVM board" | ||
70 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP2EVM | ||
71 | select SND_OMAP_SOC_MCBSP | ||
72 | select SND_SOC_TWL4030 | ||
73 | help | ||
74 | Say Y if you want to add support for SoC audio on the omap2evm board. | ||
75 | |||
76 | config SND_OMAP_SOC_OMAP3EVM | 68 | config SND_OMAP_SOC_OMAP3EVM |
77 | tristate "SoC Audio support for OMAP3EVM board" | 69 | tristate "SoC Audio support for OMAP3EVM board" |
78 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3EVM | 70 | depends on TWL4030_CORE && SND_OMAP_SOC && MACH_OMAP3EVM |
diff --git a/sound/soc/omap/Makefile b/sound/soc/omap/Makefile index ba9fc650db28..6c2c87eed5bb 100644 --- a/sound/soc/omap/Makefile +++ b/sound/soc/omap/Makefile | |||
@@ -13,7 +13,6 @@ snd-soc-rx51-objs := rx51.o | |||
13 | snd-soc-ams-delta-objs := ams-delta.o | 13 | snd-soc-ams-delta-objs := ams-delta.o |
14 | snd-soc-osk5912-objs := osk5912.o | 14 | snd-soc-osk5912-objs := osk5912.o |
15 | snd-soc-overo-objs := overo.o | 15 | snd-soc-overo-objs := overo.o |
16 | snd-soc-omap2evm-objs := omap2evm.o | ||
17 | snd-soc-omap3evm-objs := omap3evm.o | 16 | snd-soc-omap3evm-objs := omap3evm.o |
18 | snd-soc-am3517evm-objs := am3517evm.o | 17 | snd-soc-am3517evm-objs := am3517evm.o |
19 | snd-soc-sdp3430-objs := sdp3430.o | 18 | snd-soc-sdp3430-objs := sdp3430.o |
diff --git a/sound/soc/omap/omap2evm.c b/sound/soc/omap/omap2evm.c deleted file mode 100644 index 29b60d6796e7..000000000000 --- a/sound/soc/omap/omap2evm.c +++ /dev/null | |||
@@ -1,139 +0,0 @@ | |||
1 | /* | ||
2 | * omap2evm.c -- SoC audio machine driver for omap2evm board | ||
3 | * | ||
4 | * Author: Arun KS <arunks@mistralsolutions.com> | ||
5 | * | ||
6 | * Based on sound/soc/omap/overo.c by Steve Sakoman | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * version 2 as published by the Free Software Foundation. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, but | ||
13 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the Free Software | ||
19 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
20 | * 02110-1301 USA | ||
21 | * | ||
22 | */ | ||
23 | |||
24 | #include <linux/clk.h> | ||
25 | #include <linux/platform_device.h> | ||
26 | #include <sound/core.h> | ||
27 | #include <sound/pcm.h> | ||
28 | #include <sound/soc.h> | ||
29 | |||
30 | #include <asm/mach-types.h> | ||
31 | #include <mach/hardware.h> | ||
32 | #include <mach/gpio.h> | ||
33 | #include <plat/mcbsp.h> | ||
34 | |||
35 | #include "omap-mcbsp.h" | ||
36 | #include "omap-pcm.h" | ||
37 | |||
38 | static int omap2evm_hw_params(struct snd_pcm_substream *substream, | ||
39 | struct snd_pcm_hw_params *params) | ||
40 | { | ||
41 | struct snd_soc_pcm_runtime *rtd = substream->private_data; | ||
42 | struct snd_soc_dai *codec_dai = rtd->codec_dai; | ||
43 | struct snd_soc_dai *cpu_dai = rtd->cpu_dai; | ||
44 | int ret; | ||
45 | |||
46 | /* Set codec DAI configuration */ | ||
47 | ret = snd_soc_dai_set_fmt(codec_dai, | ||
48 | SND_SOC_DAIFMT_I2S | | ||
49 | SND_SOC_DAIFMT_NB_NF | | ||
50 | SND_SOC_DAIFMT_CBM_CFM); | ||
51 | if (ret < 0) { | ||
52 | printk(KERN_ERR "can't set codec DAI configuration\n"); | ||
53 | return ret; | ||
54 | } | ||
55 | |||
56 | /* Set cpu DAI configuration */ | ||
57 | ret = snd_soc_dai_set_fmt(cpu_dai, | ||
58 | SND_SOC_DAIFMT_I2S | | ||
59 | SND_SOC_DAIFMT_NB_NF | | ||
60 | SND_SOC_DAIFMT_CBM_CFM); | ||
61 | if (ret < 0) { | ||
62 | printk(KERN_ERR "can't set cpu DAI configuration\n"); | ||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | /* Set the codec system clock for DAC and ADC */ | ||
67 | ret = snd_soc_dai_set_sysclk(codec_dai, 0, 26000000, | ||
68 | SND_SOC_CLOCK_IN); | ||
69 | if (ret < 0) { | ||
70 | printk(KERN_ERR "can't set codec system clock\n"); | ||
71 | return ret; | ||
72 | } | ||
73 | |||
74 | return 0; | ||
75 | } | ||
76 | |||
77 | static struct snd_soc_ops omap2evm_ops = { | ||
78 | .hw_params = omap2evm_hw_params, | ||
79 | }; | ||
80 | |||
81 | /* Digital audio interface glue - connects codec <--> CPU */ | ||
82 | static struct snd_soc_dai_link omap2evm_dai = { | ||
83 | .name = "TWL4030", | ||
84 | .stream_name = "TWL4030", | ||
85 | .cpu_dai_name = "omap-mcbsp-dai.1", | ||
86 | .codec_dai_name = "twl4030-hifi", | ||
87 | .platform_name = "omap-pcm-audio", | ||
88 | .codec_name = "twl4030-codec", | ||
89 | .ops = &omap2evm_ops, | ||
90 | }; | ||
91 | |||
92 | /* Audio machine driver */ | ||
93 | static struct snd_soc_card snd_soc_omap2evm = { | ||
94 | .name = "omap2evm", | ||
95 | .dai_link = &omap2evm_dai, | ||
96 | .num_links = 1, | ||
97 | }; | ||
98 | |||
99 | static struct platform_device *omap2evm_snd_device; | ||
100 | |||
101 | static int __init omap2evm_soc_init(void) | ||
102 | { | ||
103 | int ret; | ||
104 | |||
105 | if (!machine_is_omap2evm()) | ||
106 | return -ENODEV; | ||
107 | printk(KERN_INFO "omap2evm SoC init\n"); | ||
108 | |||
109 | omap2evm_snd_device = platform_device_alloc("soc-audio", -1); | ||
110 | if (!omap2evm_snd_device) { | ||
111 | printk(KERN_ERR "Platform device allocation failed\n"); | ||
112 | return -ENOMEM; | ||
113 | } | ||
114 | |||
115 | platform_set_drvdata(omap2evm_snd_device, &snd_soc_omap2evm); | ||
116 | |||
117 | ret = platform_device_add(omap2evm_snd_device); | ||
118 | if (ret) | ||
119 | goto err1; | ||
120 | |||
121 | return 0; | ||
122 | |||
123 | err1: | ||
124 | printk(KERN_ERR "Unable to add platform device\n"); | ||
125 | platform_device_put(omap2evm_snd_device); | ||
126 | |||
127 | return ret; | ||
128 | } | ||
129 | module_init(omap2evm_soc_init); | ||
130 | |||
131 | static void __exit omap2evm_soc_exit(void) | ||
132 | { | ||
133 | platform_device_unregister(omap2evm_snd_device); | ||
134 | } | ||
135 | module_exit(omap2evm_soc_exit); | ||
136 | |||
137 | MODULE_AUTHOR("Arun KS <arunks@mistralsolutions.com>"); | ||
138 | MODULE_DESCRIPTION("ALSA SoC omap2evm"); | ||
139 | MODULE_LICENSE("GPL"); | ||
diff --git a/sound/soc/samsung/Kconfig b/sound/soc/samsung/Kconfig index 459566bfcd35..d155cbb58e1c 100644 --- a/sound/soc/samsung/Kconfig +++ b/sound/soc/samsung/Kconfig | |||
@@ -1,6 +1,6 @@ | |||
1 | config SND_SOC_SAMSUNG | 1 | config SND_SOC_SAMSUNG |
2 | tristate "ASoC support for Samsung" | 2 | tristate "ASoC support for Samsung" |
3 | depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_S5P6442 || ARCH_EXYNOS4 | 3 | depends on ARCH_S3C2410 || ARCH_S3C64XX || ARCH_S5PC100 || ARCH_S5PV210 || ARCH_S5P64X0 || ARCH_EXYNOS4 |
4 | select S3C64XX_DMA if ARCH_S3C64XX | 4 | select S3C64XX_DMA if ARCH_S3C64XX |
5 | select S3C2410_DMA if ARCH_S3C2410 | 5 | select S3C2410_DMA if ARCH_S3C2410 |
6 | help | 6 | help |
@@ -55,7 +55,7 @@ config SND_SOC_SAMSUNG_JIVE_WM8750 | |||
55 | 55 | ||
56 | config SND_SOC_SAMSUNG_SMDK_WM8580 | 56 | config SND_SOC_SAMSUNG_SMDK_WM8580 |
57 | tristate "SoC I2S Audio support for WM8580 on SMDK" | 57 | tristate "SoC I2S Audio support for WM8580 on SMDK" |
58 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDK6442 || MACH_SMDKV210 || MACH_SMDKC110) | 58 | depends on SND_SOC_SAMSUNG && (MACH_SMDK6410 || MACH_SMDKC100 || MACH_SMDK6440 || MACH_SMDK6450 || MACH_SMDKV210 || MACH_SMDKC110) |
59 | select SND_SOC_WM8580 | 59 | select SND_SOC_WM8580 |
60 | select SND_SAMSUNG_I2S | 60 | select SND_SAMSUNG_I2S |
61 | help | 61 | help |
diff --git a/sound/soc/samsung/smdk_wm8580.c b/sound/soc/samsung/smdk_wm8580.c index 8aacf23d6f3a..3d26f6607aa4 100644 --- a/sound/soc/samsung/smdk_wm8580.c +++ b/sound/soc/samsung/smdk_wm8580.c | |||
@@ -249,7 +249,7 @@ static int __init smdk_audio_init(void) | |||
249 | int ret; | 249 | int ret; |
250 | char *str; | 250 | char *str; |
251 | 251 | ||
252 | if (machine_is_smdkc100() || machine_is_smdk6442() | 252 | if (machine_is_smdkc100() |
253 | || machine_is_smdkv210() || machine_is_smdkc110()) { | 253 | || machine_is_smdkv210() || machine_is_smdkc110()) { |
254 | smdk.num_links = 3; | 254 | smdk.num_links = 3; |
255 | /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ | 255 | /* Secondary is at offset SAMSUNG_I2S_SECOFF from Primary */ |
diff --git a/sound/usb/6fire/control.c b/sound/usb/6fire/control.c index 248463511186..ac828eff1a63 100644 --- a/sound/usb/6fire/control.c +++ b/sound/usb/6fire/control.c | |||
@@ -65,6 +65,15 @@ init_data[] = { | |||
65 | { 0 } /* TERMINATING ENTRY */ | 65 | { 0 } /* TERMINATING ENTRY */ |
66 | }; | 66 | }; |
67 | 67 | ||
68 | static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 }; | ||
69 | /* values to write to soundcard register for all samplerates */ | ||
70 | static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; | ||
71 | static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; | ||
72 | |||
73 | enum { | ||
74 | DIGITAL_THRU_ONLY_SAMPLERATE = 3 | ||
75 | }; | ||
76 | |||
68 | static void usb6fire_control_master_vol_update(struct control_runtime *rt) | 77 | static void usb6fire_control_master_vol_update(struct control_runtime *rt) |
69 | { | 78 | { |
70 | struct comm_runtime *comm_rt = rt->chip->comm; | 79 | struct comm_runtime *comm_rt = rt->chip->comm; |
@@ -95,6 +104,67 @@ static void usb6fire_control_opt_coax_update(struct control_runtime *rt) | |||
95 | } | 104 | } |
96 | } | 105 | } |
97 | 106 | ||
107 | static int usb6fire_control_set_rate(struct control_runtime *rt, int rate) | ||
108 | { | ||
109 | int ret; | ||
110 | struct usb_device *device = rt->chip->dev; | ||
111 | struct comm_runtime *comm_rt = rt->chip->comm; | ||
112 | |||
113 | if (rate < 0 || rate >= CONTROL_N_RATES) | ||
114 | return -EINVAL; | ||
115 | |||
116 | ret = usb_set_interface(device, 1, rates_altsetting[rate]); | ||
117 | if (ret < 0) | ||
118 | return ret; | ||
119 | |||
120 | /* set soundcard clock */ | ||
121 | ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rate], | ||
122 | rates_6fire_vh[rate]); | ||
123 | if (ret < 0) | ||
124 | return ret; | ||
125 | |||
126 | return 0; | ||
127 | } | ||
128 | |||
129 | static int usb6fire_control_set_channels( | ||
130 | struct control_runtime *rt, int n_analog_out, | ||
131 | int n_analog_in, bool spdif_out, bool spdif_in) | ||
132 | { | ||
133 | int ret; | ||
134 | struct comm_runtime *comm_rt = rt->chip->comm; | ||
135 | |||
136 | /* enable analog inputs and outputs | ||
137 | * (one bit per stereo-channel) */ | ||
138 | ret = comm_rt->write16(comm_rt, 0x02, 0x02, | ||
139 | (1 << (n_analog_out / 2)) - 1, | ||
140 | (1 << (n_analog_in / 2)) - 1); | ||
141 | if (ret < 0) | ||
142 | return ret; | ||
143 | |||
144 | /* disable digital inputs and outputs */ | ||
145 | /* TODO: use spdif_x to enable/disable digital channels */ | ||
146 | ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00); | ||
147 | if (ret < 0) | ||
148 | return ret; | ||
149 | |||
150 | return 0; | ||
151 | } | ||
152 | |||
153 | static int usb6fire_control_streaming_update(struct control_runtime *rt) | ||
154 | { | ||
155 | struct comm_runtime *comm_rt = rt->chip->comm; | ||
156 | |||
157 | if (comm_rt) { | ||
158 | if (!rt->usb_streaming && rt->digital_thru_switch) | ||
159 | usb6fire_control_set_rate(rt, | ||
160 | DIGITAL_THRU_ONLY_SAMPLERATE); | ||
161 | return comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, | ||
162 | (rt->usb_streaming ? 0x01 : 0x00) | | ||
163 | (rt->digital_thru_switch ? 0x08 : 0x00)); | ||
164 | } | ||
165 | return -EINVAL; | ||
166 | } | ||
167 | |||
98 | static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, | 168 | static int usb6fire_control_master_vol_info(struct snd_kcontrol *kcontrol, |
99 | struct snd_ctl_elem_info *uinfo) | 169 | struct snd_ctl_elem_info *uinfo) |
100 | { | 170 | { |
@@ -195,6 +265,28 @@ static int usb6fire_control_opt_coax_get(struct snd_kcontrol *kcontrol, | |||
195 | return 0; | 265 | return 0; |
196 | } | 266 | } |
197 | 267 | ||
268 | static int usb6fire_control_digital_thru_put(struct snd_kcontrol *kcontrol, | ||
269 | struct snd_ctl_elem_value *ucontrol) | ||
270 | { | ||
271 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | ||
272 | int changed = 0; | ||
273 | |||
274 | if (rt->digital_thru_switch != ucontrol->value.integer.value[0]) { | ||
275 | rt->digital_thru_switch = ucontrol->value.integer.value[0]; | ||
276 | usb6fire_control_streaming_update(rt); | ||
277 | changed = 1; | ||
278 | } | ||
279 | return changed; | ||
280 | } | ||
281 | |||
282 | static int usb6fire_control_digital_thru_get(struct snd_kcontrol *kcontrol, | ||
283 | struct snd_ctl_elem_value *ucontrol) | ||
284 | { | ||
285 | struct control_runtime *rt = snd_kcontrol_chip(kcontrol); | ||
286 | ucontrol->value.integer.value[0] = rt->digital_thru_switch; | ||
287 | return 0; | ||
288 | } | ||
289 | |||
198 | static struct __devinitdata snd_kcontrol_new elements[] = { | 290 | static struct __devinitdata snd_kcontrol_new elements[] = { |
199 | { | 291 | { |
200 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | 292 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, |
@@ -223,6 +315,15 @@ static struct __devinitdata snd_kcontrol_new elements[] = { | |||
223 | .get = usb6fire_control_opt_coax_get, | 315 | .get = usb6fire_control_opt_coax_get, |
224 | .put = usb6fire_control_opt_coax_put | 316 | .put = usb6fire_control_opt_coax_put |
225 | }, | 317 | }, |
318 | { | ||
319 | .iface = SNDRV_CTL_ELEM_IFACE_MIXER, | ||
320 | .name = "Digital Thru Playback Route", | ||
321 | .index = 0, | ||
322 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, | ||
323 | .info = snd_ctl_boolean_mono_info, | ||
324 | .get = usb6fire_control_digital_thru_get, | ||
325 | .put = usb6fire_control_digital_thru_put | ||
326 | }, | ||
226 | {} | 327 | {} |
227 | }; | 328 | }; |
228 | 329 | ||
@@ -238,6 +339,9 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip) | |||
238 | return -ENOMEM; | 339 | return -ENOMEM; |
239 | 340 | ||
240 | rt->chip = chip; | 341 | rt->chip = chip; |
342 | rt->update_streaming = usb6fire_control_streaming_update; | ||
343 | rt->set_rate = usb6fire_control_set_rate; | ||
344 | rt->set_channels = usb6fire_control_set_channels; | ||
241 | 345 | ||
242 | i = 0; | 346 | i = 0; |
243 | while (init_data[i].type) { | 347 | while (init_data[i].type) { |
@@ -249,6 +353,7 @@ int __devinit usb6fire_control_init(struct sfire_chip *chip) | |||
249 | usb6fire_control_opt_coax_update(rt); | 353 | usb6fire_control_opt_coax_update(rt); |
250 | usb6fire_control_line_phono_update(rt); | 354 | usb6fire_control_line_phono_update(rt); |
251 | usb6fire_control_master_vol_update(rt); | 355 | usb6fire_control_master_vol_update(rt); |
356 | usb6fire_control_streaming_update(rt); | ||
252 | 357 | ||
253 | i = 0; | 358 | i = 0; |
254 | while (elements[i].name) { | 359 | while (elements[i].name) { |
diff --git a/sound/usb/6fire/control.h b/sound/usb/6fire/control.h index b534c777ab02..8f5aeead2e3d 100644 --- a/sound/usb/6fire/control.h +++ b/sound/usb/6fire/control.h | |||
@@ -21,12 +21,29 @@ enum { | |||
21 | CONTROL_MAX_ELEMENTS = 32 | 21 | CONTROL_MAX_ELEMENTS = 32 |
22 | }; | 22 | }; |
23 | 23 | ||
24 | enum { | ||
25 | CONTROL_RATE_44KHZ, | ||
26 | CONTROL_RATE_48KHZ, | ||
27 | CONTROL_RATE_88KHZ, | ||
28 | CONTROL_RATE_96KHZ, | ||
29 | CONTROL_RATE_176KHZ, | ||
30 | CONTROL_RATE_192KHZ, | ||
31 | CONTROL_N_RATES | ||
32 | }; | ||
33 | |||
24 | struct control_runtime { | 34 | struct control_runtime { |
35 | int (*update_streaming)(struct control_runtime *rt); | ||
36 | int (*set_rate)(struct control_runtime *rt, int rate); | ||
37 | int (*set_channels)(struct control_runtime *rt, int n_analog_out, | ||
38 | int n_analog_in, bool spdif_out, bool spdif_in); | ||
39 | |||
25 | struct sfire_chip *chip; | 40 | struct sfire_chip *chip; |
26 | 41 | ||
27 | struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS]; | 42 | struct snd_kcontrol *element[CONTROL_MAX_ELEMENTS]; |
28 | bool opt_coax_switch; | 43 | bool opt_coax_switch; |
29 | bool line_phono_switch; | 44 | bool line_phono_switch; |
45 | bool digital_thru_switch; | ||
46 | bool usb_streaming; | ||
30 | u8 master_vol; | 47 | u8 master_vol; |
31 | }; | 48 | }; |
32 | 49 | ||
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c index 86c1a3103760..d47beffedb0f 100644 --- a/sound/usb/6fire/firmware.c +++ b/sound/usb/6fire/firmware.c | |||
@@ -3,12 +3,6 @@ | |||
3 | * | 3 | * |
4 | * Firmware loader | 4 | * Firmware loader |
5 | * | 5 | * |
6 | * Currently not working for all devices. To be able to use the device | ||
7 | * in linux, it is also possible to let the windows driver upload the firmware. | ||
8 | * For that, start the computer in windows and reboot. | ||
9 | * As long as the device is connected to the power supply, no firmware reload | ||
10 | * needs to be performed. | ||
11 | * | ||
12 | * Author: Torsten Schenk <torsten.schenk@zoho.com> | 6 | * Author: Torsten Schenk <torsten.schenk@zoho.com> |
13 | * Created: Jan 01, 2011 | 7 | * Created: Jan 01, 2011 |
14 | * Version: 0.3.0 | 8 | * Version: 0.3.0 |
@@ -21,6 +15,7 @@ | |||
21 | */ | 15 | */ |
22 | 16 | ||
23 | #include <linux/firmware.h> | 17 | #include <linux/firmware.h> |
18 | #include <linux/bitrev.h> | ||
24 | 19 | ||
25 | #include "firmware.h" | 20 | #include "firmware.h" |
26 | #include "chip.h" | 21 | #include "chip.h" |
@@ -33,32 +28,6 @@ enum { | |||
33 | FPGA_BUFSIZE = 512, FPGA_EP = 2 | 28 | FPGA_BUFSIZE = 512, FPGA_EP = 2 |
34 | }; | 29 | }; |
35 | 30 | ||
36 | static const u8 BIT_REVERSE_TABLE[256] = { | ||
37 | 0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0, 0x10, 0x90, 0x50, | ||
38 | 0xd0, 0x30, 0xb0, 0x70, 0xf0, 0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, | ||
39 | 0x68, 0xe8, 0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8, 0x04, | ||
40 | 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4, 0x14, 0x94, 0x54, 0xd4, | ||
41 | 0x34, 0xb4, 0x74, 0xf4, 0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, | ||
42 | 0xec, 0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc, 0x02, 0x82, | ||
43 | 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2, 0x12, 0x92, 0x52, 0xd2, 0x32, | ||
44 | 0xb2, 0x72, 0xf2, 0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea, | ||
45 | 0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa, 0x06, 0x86, 0x46, | ||
46 | 0xc6, 0x26, 0xa6, 0x66, 0xe6, 0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, | ||
47 | 0x76, 0xf6, 0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee, 0x1e, | ||
48 | 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe, 0x01, 0x81, 0x41, 0xc1, | ||
49 | 0x21, 0xa1, 0x61, 0xe1, 0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, | ||
50 | 0xf1, 0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9, 0x19, 0x99, | ||
51 | 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9, 0x05, 0x85, 0x45, 0xc5, 0x25, | ||
52 | 0xa5, 0x65, 0xe5, 0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5, | ||
53 | 0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed, 0x1d, 0x9d, 0x5d, | ||
54 | 0xdd, 0x3d, 0xbd, 0x7d, 0xfd, 0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, | ||
55 | 0x63, 0xe3, 0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3, 0x0b, | ||
56 | 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb, 0x1b, 0x9b, 0x5b, 0xdb, | ||
57 | 0x3b, 0xbb, 0x7b, 0xfb, 0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, | ||
58 | 0xe7, 0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7, 0x0f, 0x8f, | ||
59 | 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef, 0x1f, 0x9f, 0x5f, 0xdf, 0x3f, | ||
60 | 0xbf, 0x7f, 0xff }; | ||
61 | |||
62 | /* | 31 | /* |
63 | * wMaxPacketSize of pcm endpoints. | 32 | * wMaxPacketSize of pcm endpoints. |
64 | * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c | 33 | * keep synced with rates_in_packet_size and rates_out_packet_size in pcm.c |
@@ -72,6 +41,10 @@ static const u8 ep_w_max_packet_size[] = { | |||
72 | 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */ | 41 | 0x94, 0x01, 0x5c, 0x02 /* alt 3: 404 EP2 and 604 EP6 (25 fpp) */ |
73 | }; | 42 | }; |
74 | 43 | ||
44 | static const u8 known_fw_versions[][4] = { | ||
45 | { 0x03, 0x01, 0x0b, 0x00 } | ||
46 | }; | ||
47 | |||
75 | struct ihex_record { | 48 | struct ihex_record { |
76 | u16 address; | 49 | u16 address; |
77 | u8 len; | 50 | u8 len; |
@@ -340,7 +313,7 @@ static int usb6fire_fw_fpga_upload( | |||
340 | 313 | ||
341 | while (c != end) { | 314 | while (c != end) { |
342 | for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++) | 315 | for (i = 0; c != end && i < FPGA_BUFSIZE; i++, c++) |
343 | buffer[i] = BIT_REVERSE_TABLE[(u8) *c]; | 316 | buffer[i] = byte_rev_table[(u8) *c]; |
344 | 317 | ||
345 | ret = usb6fire_fw_fpga_write(device, buffer, i); | 318 | ret = usb6fire_fw_fpga_write(device, buffer, i); |
346 | if (ret < 0) { | 319 | if (ret < 0) { |
@@ -363,6 +336,25 @@ static int usb6fire_fw_fpga_upload( | |||
363 | return 0; | 336 | return 0; |
364 | } | 337 | } |
365 | 338 | ||
339 | /* check, if the firmware version the devices has currently loaded | ||
340 | * is known by this driver. 'version' needs to have 4 bytes version | ||
341 | * info data. */ | ||
342 | static int usb6fire_fw_check(u8 *version) | ||
343 | { | ||
344 | int i; | ||
345 | |||
346 | for (i = 0; i < ARRAY_SIZE(known_fw_versions); i++) | ||
347 | if (!memcmp(version, known_fw_versions + i, 4)) | ||
348 | return 0; | ||
349 | |||
350 | snd_printk(KERN_ERR PREFIX "invalid fimware version in device: " | ||
351 | "%02x %02x %02x %02x. " | ||
352 | "please reconnect to power. if this failure " | ||
353 | "still happens, check your firmware installation.", | ||
354 | version[0], version[1], version[2], version[3]); | ||
355 | return -EINVAL; | ||
356 | } | ||
357 | |||
366 | int usb6fire_fw_init(struct usb_interface *intf) | 358 | int usb6fire_fw_init(struct usb_interface *intf) |
367 | { | 359 | { |
368 | int i; | 360 | int i; |
@@ -378,9 +370,7 @@ int usb6fire_fw_init(struct usb_interface *intf) | |||
378 | "firmware state.\n"); | 370 | "firmware state.\n"); |
379 | return ret; | 371 | return ret; |
380 | } | 372 | } |
381 | if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55 | 373 | if (buffer[0] != 0xeb || buffer[1] != 0xaa || buffer[2] != 0x55) { |
382 | || buffer[4] != 0x03 || buffer[5] != 0x01 || buffer[7] | ||
383 | != 0x00) { | ||
384 | snd_printk(KERN_ERR PREFIX "unknown device firmware state " | 374 | snd_printk(KERN_ERR PREFIX "unknown device firmware state " |
385 | "received from device: "); | 375 | "received from device: "); |
386 | for (i = 0; i < 8; i++) | 376 | for (i = 0; i < 8; i++) |
@@ -389,7 +379,7 @@ int usb6fire_fw_init(struct usb_interface *intf) | |||
389 | return -EIO; | 379 | return -EIO; |
390 | } | 380 | } |
391 | /* do we need fpga loader ezusb firmware? */ | 381 | /* do we need fpga loader ezusb firmware? */ |
392 | if (buffer[3] == 0x01 && buffer[6] == 0x19) { | 382 | if (buffer[3] == 0x01) { |
393 | ret = usb6fire_fw_ezusb_upload(intf, | 383 | ret = usb6fire_fw_ezusb_upload(intf, |
394 | "6fire/dmx6firel2.ihx", 0, NULL, 0); | 384 | "6fire/dmx6firel2.ihx", 0, NULL, 0); |
395 | if (ret < 0) | 385 | if (ret < 0) |
@@ -397,7 +387,10 @@ int usb6fire_fw_init(struct usb_interface *intf) | |||
397 | return FW_NOT_READY; | 387 | return FW_NOT_READY; |
398 | } | 388 | } |
399 | /* do we need fpga firmware and application ezusb firmware? */ | 389 | /* do we need fpga firmware and application ezusb firmware? */ |
400 | else if (buffer[3] == 0x02 && buffer[6] == 0x0b) { | 390 | else if (buffer[3] == 0x02) { |
391 | ret = usb6fire_fw_check(buffer + 4); | ||
392 | if (ret < 0) | ||
393 | return ret; | ||
401 | ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); | 394 | ret = usb6fire_fw_fpga_upload(intf, "6fire/dmx6firecf.bin"); |
402 | if (ret < 0) | 395 | if (ret < 0) |
403 | return ret; | 396 | return ret; |
@@ -410,8 +403,8 @@ int usb6fire_fw_init(struct usb_interface *intf) | |||
410 | return FW_NOT_READY; | 403 | return FW_NOT_READY; |
411 | } | 404 | } |
412 | /* all fw loaded? */ | 405 | /* all fw loaded? */ |
413 | else if (buffer[3] == 0x03 && buffer[6] == 0x0b) | 406 | else if (buffer[3] == 0x03) |
414 | return 0; | 407 | return usb6fire_fw_check(buffer + 4); |
415 | /* unknown data? */ | 408 | /* unknown data? */ |
416 | else { | 409 | else { |
417 | snd_printk(KERN_ERR PREFIX "unknown device firmware state " | 410 | snd_printk(KERN_ERR PREFIX "unknown device firmware state " |
diff --git a/sound/usb/6fire/pcm.c b/sound/usb/6fire/pcm.c index ba62c7468ba8..b137b25865cc 100644 --- a/sound/usb/6fire/pcm.c +++ b/sound/usb/6fire/pcm.c | |||
@@ -17,26 +17,23 @@ | |||
17 | #include "pcm.h" | 17 | #include "pcm.h" |
18 | #include "chip.h" | 18 | #include "chip.h" |
19 | #include "comm.h" | 19 | #include "comm.h" |
20 | #include "control.h" | ||
20 | 21 | ||
21 | enum { | 22 | enum { |
22 | OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4 | 23 | OUT_N_CHANNELS = 6, IN_N_CHANNELS = 4 |
23 | }; | 24 | }; |
24 | 25 | ||
25 | /* keep next two synced with | 26 | /* keep next two synced with |
26 | * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE */ | 27 | * FW_EP_W_MAX_PACKET_SIZE[] and RATES_MAX_PACKET_SIZE |
28 | * and CONTROL_RATE_XXX in control.h */ | ||
27 | static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 }; | 29 | static const int rates_in_packet_size[] = { 228, 228, 420, 420, 404, 404 }; |
28 | static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 }; | 30 | static const int rates_out_packet_size[] = { 228, 228, 420, 420, 604, 604 }; |
29 | static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 }; | 31 | static const int rates[] = { 44100, 48000, 88200, 96000, 176400, 192000 }; |
30 | static const int rates_altsetting[] = { 1, 1, 2, 2, 3, 3 }; | ||
31 | static const int rates_alsaid[] = { | 32 | static const int rates_alsaid[] = { |
32 | SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000, | 33 | SNDRV_PCM_RATE_44100, SNDRV_PCM_RATE_48000, |
33 | SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000, | 34 | SNDRV_PCM_RATE_88200, SNDRV_PCM_RATE_96000, |
34 | SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 }; | 35 | SNDRV_PCM_RATE_176400, SNDRV_PCM_RATE_192000 }; |
35 | 36 | ||
36 | /* values to write to soundcard register for all samplerates */ | ||
37 | static const u16 rates_6fire_vl[] = {0x00, 0x01, 0x00, 0x01, 0x00, 0x01}; | ||
38 | static const u16 rates_6fire_vh[] = {0x11, 0x11, 0x10, 0x10, 0x00, 0x00}; | ||
39 | |||
40 | enum { /* settings for pcm */ | 37 | enum { /* settings for pcm */ |
41 | OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024 | 38 | OUT_EP = 6, IN_EP = 2, MAX_BUFSIZE = 128 * 1024 |
42 | }; | 39 | }; |
@@ -48,15 +45,6 @@ enum { /* pcm streaming states */ | |||
48 | STREAM_STOPPING | 45 | STREAM_STOPPING |
49 | }; | 46 | }; |
50 | 47 | ||
51 | enum { /* pcm sample rates (also index into RATES_XXX[]) */ | ||
52 | RATE_44KHZ, | ||
53 | RATE_48KHZ, | ||
54 | RATE_88KHZ, | ||
55 | RATE_96KHZ, | ||
56 | RATE_176KHZ, | ||
57 | RATE_192KHZ | ||
58 | }; | ||
59 | |||
60 | static const struct snd_pcm_hardware pcm_hw = { | 48 | static const struct snd_pcm_hardware pcm_hw = { |
61 | .info = SNDRV_PCM_INFO_MMAP | | 49 | .info = SNDRV_PCM_INFO_MMAP | |
62 | SNDRV_PCM_INFO_INTERLEAVED | | 50 | SNDRV_PCM_INFO_INTERLEAVED | |
@@ -64,7 +52,7 @@ static const struct snd_pcm_hardware pcm_hw = { | |||
64 | SNDRV_PCM_INFO_MMAP_VALID | | 52 | SNDRV_PCM_INFO_MMAP_VALID | |
65 | SNDRV_PCM_INFO_BATCH, | 53 | SNDRV_PCM_INFO_BATCH, |
66 | 54 | ||
67 | .formats = SNDRV_PCM_FMTBIT_S24_LE, | 55 | .formats = SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE, |
68 | 56 | ||
69 | .rates = SNDRV_PCM_RATE_44100 | | 57 | .rates = SNDRV_PCM_RATE_44100 | |
70 | SNDRV_PCM_RATE_48000 | | 58 | SNDRV_PCM_RATE_48000 | |
@@ -87,57 +75,34 @@ static const struct snd_pcm_hardware pcm_hw = { | |||
87 | static int usb6fire_pcm_set_rate(struct pcm_runtime *rt) | 75 | static int usb6fire_pcm_set_rate(struct pcm_runtime *rt) |
88 | { | 76 | { |
89 | int ret; | 77 | int ret; |
90 | struct usb_device *device = rt->chip->dev; | 78 | struct control_runtime *ctrl_rt = rt->chip->control; |
91 | struct comm_runtime *comm_rt = rt->chip->comm; | ||
92 | 79 | ||
93 | if (rt->rate >= ARRAY_SIZE(rates)) | 80 | ctrl_rt->usb_streaming = false; |
94 | return -EINVAL; | 81 | ret = ctrl_rt->update_streaming(ctrl_rt); |
95 | /* disable streaming */ | ||
96 | ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x00); | ||
97 | if (ret < 0) { | 82 | if (ret < 0) { |
98 | snd_printk(KERN_ERR PREFIX "error stopping streaming while " | 83 | snd_printk(KERN_ERR PREFIX "error stopping streaming while " |
99 | "setting samplerate %d.\n", rates[rt->rate]); | 84 | "setting samplerate %d.\n", rates[rt->rate]); |
100 | return ret; | 85 | return ret; |
101 | } | 86 | } |
102 | 87 | ||
103 | ret = usb_set_interface(device, 1, rates_altsetting[rt->rate]); | 88 | ret = ctrl_rt->set_rate(ctrl_rt, rt->rate); |
104 | if (ret < 0) { | ||
105 | snd_printk(KERN_ERR PREFIX "error setting interface " | ||
106 | "altsetting %d for samplerate %d.\n", | ||
107 | rates_altsetting[rt->rate], rates[rt->rate]); | ||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | /* set soundcard clock */ | ||
112 | ret = comm_rt->write16(comm_rt, 0x02, 0x01, rates_6fire_vl[rt->rate], | ||
113 | rates_6fire_vh[rt->rate]); | ||
114 | if (ret < 0) { | 89 | if (ret < 0) { |
115 | snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n", | 90 | snd_printk(KERN_ERR PREFIX "error setting samplerate %d.\n", |
116 | rates[rt->rate]); | 91 | rates[rt->rate]); |
117 | return ret; | 92 | return ret; |
118 | } | 93 | } |
119 | 94 | ||
120 | /* enable analog inputs and outputs | 95 | ret = ctrl_rt->set_channels(ctrl_rt, OUT_N_CHANNELS, IN_N_CHANNELS, |
121 | * (one bit per stereo-channel) */ | 96 | false, false); |
122 | ret = comm_rt->write16(comm_rt, 0x02, 0x02, | ||
123 | (1 << (OUT_N_CHANNELS / 2)) - 1, | ||
124 | (1 << (IN_N_CHANNELS / 2)) - 1); | ||
125 | if (ret < 0) { | 97 | if (ret < 0) { |
126 | snd_printk(KERN_ERR PREFIX "error initializing analog channels " | 98 | snd_printk(KERN_ERR PREFIX "error initializing channels " |
127 | "while setting samplerate %d.\n", | 99 | "while setting samplerate %d.\n", |
128 | rates[rt->rate]); | 100 | rates[rt->rate]); |
129 | return ret; | 101 | return ret; |
130 | } | 102 | } |
131 | /* disable digital inputs and outputs */ | ||
132 | ret = comm_rt->write16(comm_rt, 0x02, 0x03, 0x00, 0x00); | ||
133 | if (ret < 0) { | ||
134 | snd_printk(KERN_ERR PREFIX "error initializing digital " | ||
135 | "channels while setting samplerate %d.\n", | ||
136 | rates[rt->rate]); | ||
137 | return ret; | ||
138 | } | ||
139 | 103 | ||
140 | ret = comm_rt->write16(comm_rt, 0x02, 0x00, 0x00, 0x01); | 104 | ctrl_rt->usb_streaming = true; |
105 | ret = ctrl_rt->update_streaming(ctrl_rt); | ||
141 | if (ret < 0) { | 106 | if (ret < 0) { |
142 | snd_printk(KERN_ERR PREFIX "error starting streaming while " | 107 | snd_printk(KERN_ERR PREFIX "error starting streaming while " |
143 | "setting samplerate %d.\n", rates[rt->rate]); | 108 | "setting samplerate %d.\n", rates[rt->rate]); |
@@ -168,12 +133,15 @@ static struct pcm_substream *usb6fire_pcm_get_substream( | |||
168 | static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt) | 133 | static void usb6fire_pcm_stream_stop(struct pcm_runtime *rt) |
169 | { | 134 | { |
170 | int i; | 135 | int i; |
136 | struct control_runtime *ctrl_rt = rt->chip->control; | ||
171 | 137 | ||
172 | if (rt->stream_state != STREAM_DISABLED) { | 138 | if (rt->stream_state != STREAM_DISABLED) { |
173 | for (i = 0; i < PCM_N_URBS; i++) { | 139 | for (i = 0; i < PCM_N_URBS; i++) { |
174 | usb_kill_urb(&rt->in_urbs[i].instance); | 140 | usb_kill_urb(&rt->in_urbs[i].instance); |
175 | usb_kill_urb(&rt->out_urbs[i].instance); | 141 | usb_kill_urb(&rt->out_urbs[i].instance); |
176 | } | 142 | } |
143 | ctrl_rt->usb_streaming = false; | ||
144 | ctrl_rt->update_streaming(ctrl_rt); | ||
177 | rt->stream_state = STREAM_DISABLED; | 145 | rt->stream_state = STREAM_DISABLED; |
178 | } | 146 | } |
179 | } | 147 | } |
@@ -228,7 +196,7 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb) | |||
228 | unsigned int total_length = 0; | 196 | unsigned int total_length = 0; |
229 | struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); | 197 | struct pcm_runtime *rt = snd_pcm_substream_chip(sub->instance); |
230 | struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; | 198 | struct snd_pcm_runtime *alsa_rt = sub->instance->runtime; |
231 | u32 *src = (u32 *) urb->buffer; | 199 | u32 *src = NULL; |
232 | u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off | 200 | u32 *dest = (u32 *) (alsa_rt->dma_area + sub->dma_off |
233 | * (alsa_rt->frame_bits >> 3)); | 201 | * (alsa_rt->frame_bits >> 3)); |
234 | u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size | 202 | u32 *dest_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size |
@@ -244,7 +212,12 @@ static void usb6fire_pcm_capture(struct pcm_substream *sub, struct pcm_urb *urb) | |||
244 | else | 212 | else |
245 | frame_count = 0; | 213 | frame_count = 0; |
246 | 214 | ||
247 | src = (u32 *) (urb->buffer + total_length); | 215 | if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) |
216 | src = (u32 *) (urb->buffer + total_length); | ||
217 | else if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE) | ||
218 | src = (u32 *) (urb->buffer - 1 + total_length); | ||
219 | else | ||
220 | return; | ||
248 | src++; /* skip leading 4 bytes of every packet */ | 221 | src++; /* skip leading 4 bytes of every packet */ |
249 | total_length += urb->packets[i].length; | 222 | total_length += urb->packets[i].length; |
250 | for (frame = 0; frame < frame_count; frame++) { | 223 | for (frame = 0; frame < frame_count; frame++) { |
@@ -274,9 +247,18 @@ static void usb6fire_pcm_playback(struct pcm_substream *sub, | |||
274 | * (alsa_rt->frame_bits >> 3)); | 247 | * (alsa_rt->frame_bits >> 3)); |
275 | u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size | 248 | u32 *src_end = (u32 *) (alsa_rt->dma_area + alsa_rt->buffer_size |
276 | * (alsa_rt->frame_bits >> 3)); | 249 | * (alsa_rt->frame_bits >> 3)); |
277 | u32 *dest = (u32 *) urb->buffer; | 250 | u32 *dest; |
278 | int bytes_per_frame = alsa_rt->channels << 2; | 251 | int bytes_per_frame = alsa_rt->channels << 2; |
279 | 252 | ||
253 | if (alsa_rt->format == SNDRV_PCM_FORMAT_S32_LE) | ||
254 | dest = (u32 *) (urb->buffer - 1); | ||
255 | else if (alsa_rt->format == SNDRV_PCM_FORMAT_S24_LE) | ||
256 | dest = (u32 *) (urb->buffer); | ||
257 | else { | ||
258 | snd_printk(KERN_ERR PREFIX "Unknown sample format."); | ||
259 | return; | ||
260 | } | ||
261 | |||
280 | for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { | 262 | for (i = 0; i < PCM_N_PACKETS_PER_URB; i++) { |
281 | /* at least 4 header bytes for valid packet. | 263 | /* at least 4 header bytes for valid packet. |
282 | * after that: 32 bits per sample for analog channels */ | 264 | * after that: 32 bits per sample for analog channels */ |
@@ -456,7 +438,7 @@ static int usb6fire_pcm_close(struct snd_pcm_substream *alsa_sub) | |||
456 | /* all substreams closed? if so, stop streaming */ | 438 | /* all substreams closed? if so, stop streaming */ |
457 | if (!rt->playback.instance && !rt->capture.instance) { | 439 | if (!rt->playback.instance && !rt->capture.instance) { |
458 | usb6fire_pcm_stream_stop(rt); | 440 | usb6fire_pcm_stream_stop(rt); |
459 | rt->rate = -1; | 441 | rt->rate = ARRAY_SIZE(rates); |
460 | } | 442 | } |
461 | } | 443 | } |
462 | mutex_unlock(&rt->stream_mutex); | 444 | mutex_unlock(&rt->stream_mutex); |
@@ -480,7 +462,6 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub) | |||
480 | struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); | 462 | struct pcm_runtime *rt = snd_pcm_substream_chip(alsa_sub); |
481 | struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); | 463 | struct pcm_substream *sub = usb6fire_pcm_get_substream(alsa_sub); |
482 | struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; | 464 | struct snd_pcm_runtime *alsa_rt = alsa_sub->runtime; |
483 | int i; | ||
484 | int ret; | 465 | int ret; |
485 | 466 | ||
486 | if (rt->panic) | 467 | if (rt->panic) |
@@ -493,12 +474,10 @@ static int usb6fire_pcm_prepare(struct snd_pcm_substream *alsa_sub) | |||
493 | sub->period_off = 0; | 474 | sub->period_off = 0; |
494 | 475 | ||
495 | if (rt->stream_state == STREAM_DISABLED) { | 476 | if (rt->stream_state == STREAM_DISABLED) { |
496 | for (i = 0; i < ARRAY_SIZE(rates); i++) | 477 | for (rt->rate = 0; rt->rate < ARRAY_SIZE(rates); rt->rate++) |
497 | if (alsa_rt->rate == rates[i]) { | 478 | if (alsa_rt->rate == rates[rt->rate]) |
498 | rt->rate = i; | ||
499 | break; | 479 | break; |
500 | } | 480 | if (rt->rate == ARRAY_SIZE(rates)) { |
501 | if (i == ARRAY_SIZE(rates)) { | ||
502 | mutex_unlock(&rt->stream_mutex); | 481 | mutex_unlock(&rt->stream_mutex); |
503 | snd_printk("invalid rate %d in prepare.\n", | 482 | snd_printk("invalid rate %d in prepare.\n", |
504 | alsa_rt->rate); | 483 | alsa_rt->rate); |
@@ -613,7 +592,7 @@ int __devinit usb6fire_pcm_init(struct sfire_chip *chip) | |||
613 | 592 | ||
614 | rt->chip = chip; | 593 | rt->chip = chip; |
615 | rt->stream_state = STREAM_DISABLED; | 594 | rt->stream_state = STREAM_DISABLED; |
616 | rt->rate = -1; | 595 | rt->rate = ARRAY_SIZE(rates); |
617 | init_waitqueue_head(&rt->stream_wait_queue); | 596 | init_waitqueue_head(&rt->stream_wait_queue); |
618 | mutex_init(&rt->stream_mutex); | 597 | mutex_init(&rt->stream_mutex); |
619 | 598 | ||
diff --git a/sound/usb/Kconfig b/sound/usb/Kconfig index 97724d8fa9f6..8beb77563da2 100644 --- a/sound/usb/Kconfig +++ b/sound/usb/Kconfig | |||
@@ -100,19 +100,17 @@ config SND_USB_US122L | |||
100 | 100 | ||
101 | config SND_USB_6FIRE | 101 | config SND_USB_6FIRE |
102 | tristate "TerraTec DMX 6Fire USB" | 102 | tristate "TerraTec DMX 6Fire USB" |
103 | depends on EXPERIMENTAL | ||
104 | select FW_LOADER | 103 | select FW_LOADER |
104 | select BITREVERSE | ||
105 | select SND_RAWMIDI | 105 | select SND_RAWMIDI |
106 | select SND_PCM | 106 | select SND_PCM |
107 | help | 107 | help |
108 | Say Y here to include support for TerraTec 6fire DMX USB interface. | 108 | Say Y here to include support for TerraTec 6fire DMX USB interface. |
109 | 109 | ||
110 | You will need firmware files in order to be able to use the device | 110 | You will need firmware files in order to be able to use the device |
111 | after it has been coldstarted. This driver currently does not support | 111 | after it has been coldstarted. An install script for the firmware |
112 | firmware loading for all devices. If you own such a device, | 112 | and further help can be found at |
113 | you could start windows and let the windows driver upload | 113 | http://sixfireusb.sourceforge.net |
114 | the firmware. As long as you do not unplug your device from power, | ||
115 | it should be usable. | ||
116 | 114 | ||
117 | endif # SND_USB | 115 | endif # SND_USB |
118 | 116 | ||
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/clock.c b/sound/usb/clock.c index 7754a1034545..075195e8661a 100644 --- a/sound/usb/clock.c +++ b/sound/usb/clock.c | |||
@@ -104,6 +104,15 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) | |||
104 | int err; | 104 | int err; |
105 | unsigned char data; | 105 | unsigned char data; |
106 | struct usb_device *dev = chip->dev; | 106 | struct usb_device *dev = chip->dev; |
107 | struct uac_clock_source_descriptor *cs_desc = | ||
108 | snd_usb_find_clock_source(chip->ctrl_intf, source_id); | ||
109 | |||
110 | if (!cs_desc) | ||
111 | return 0; | ||
112 | |||
113 | /* If a clock source can't tell us whether it's valid, we assume it is */ | ||
114 | if (!uac2_control_is_readable(cs_desc->bmControls, UAC2_CS_CONTROL_CLOCK_VALID)) | ||
115 | return 1; | ||
107 | 116 | ||
108 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, | 117 | err = snd_usb_ctl_msg(dev, usb_rcvctrlpipe(dev, 0), UAC2_CS_CUR, |
109 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, | 118 | USB_TYPE_CLASS | USB_RECIP_INTERFACE | USB_DIR_IN, |
@@ -114,7 +123,7 @@ static bool uac_clock_source_is_valid(struct snd_usb_audio *chip, int source_id) | |||
114 | if (err < 0) { | 123 | if (err < 0) { |
115 | snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", | 124 | snd_printk(KERN_WARNING "%s(): cannot get clock validity for id %d\n", |
116 | __func__, source_id); | 125 | __func__, source_id); |
117 | return err; | 126 | return 0; |
118 | } | 127 | } |
119 | 128 | ||
120 | return !!data; | 129 | return !!data; |
diff --git a/sound/usb/debug.h b/sound/usb/debug.h index 343ec2d9ee66..58030176f008 100644 --- a/sound/usb/debug.h +++ b/sound/usb/debug.h | |||
@@ -8,7 +8,7 @@ | |||
8 | #ifdef HW_CONST_DEBUG | 8 | #ifdef HW_CONST_DEBUG |
9 | #define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args) | 9 | #define hwc_debug(fmt, args...) printk(KERN_DEBUG fmt, ##args) |
10 | #else | 10 | #else |
11 | #define hwc_debug(fmt, args...) /**/ | 11 | #define hwc_debug(fmt, args...) do { } while(0) |
12 | #endif | 12 | #endif |
13 | 13 | ||
14 | #endif /* __USBAUDIO_DEBUG_H */ | 14 | #endif /* __USBAUDIO_DEBUG_H */ |
diff --git a/sound/usb/format.c b/sound/usb/format.c index 5b792d2c8061..8d042dce0d16 100644 --- a/sound/usb/format.c +++ b/sound/usb/format.c | |||
@@ -30,6 +30,7 @@ | |||
30 | #include "helper.h" | 30 | #include "helper.h" |
31 | #include "debug.h" | 31 | #include "debug.h" |
32 | #include "clock.h" | 32 | #include "clock.h" |
33 | #include "format.h" | ||
33 | 34 | ||
34 | /* | 35 | /* |
35 | * parse the audio format type I descriptor | 36 | * parse the audio format type I descriptor |
@@ -176,9 +177,11 @@ static int parse_audio_format_rates_v1(struct snd_usb_audio *chip, struct audiof | |||
176 | if (!rate) | 177 | if (!rate) |
177 | continue; | 178 | continue; |
178 | /* C-Media CM6501 mislabels its 96 kHz altsetting */ | 179 | /* C-Media CM6501 mislabels its 96 kHz altsetting */ |
180 | /* Terratec Aureon 7.1 USB C-Media 6206, too */ | ||
179 | if (rate == 48000 && nr_rates == 1 && | 181 | if (rate == 48000 && nr_rates == 1 && |
180 | (chip->usb_id == USB_ID(0x0d8c, 0x0201) || | 182 | (chip->usb_id == USB_ID(0x0d8c, 0x0201) || |
181 | chip->usb_id == USB_ID(0x0d8c, 0x0102)) && | 183 | chip->usb_id == USB_ID(0x0d8c, 0x0102) || |
184 | chip->usb_id == USB_ID(0x0ccd, 0x00b1)) && | ||
182 | fp->altsetting == 5 && fp->maxpacksize == 392) | 185 | fp->altsetting == 5 && fp->maxpacksize == 392) |
183 | rate = 96000; | 186 | rate = 96000; |
184 | /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */ | 187 | /* Creative VF0470 Live Cam reports 16 kHz instead of 8kHz */ |
diff --git a/sound/usb/mixer.c b/sound/usb/mixer.c index 6ec33b62e6cf..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 |
@@ -1097,11 +1091,13 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1097 | append_ctl_name(kctl, control == UAC_FU_MUTE ? | 1091 | append_ctl_name(kctl, control == UAC_FU_MUTE ? |
1098 | " Switch" : " Volume"); | 1092 | " Switch" : " Volume"); |
1099 | if (control == UAC_FU_VOLUME) { | 1093 | if (control == UAC_FU_VOLUME) { |
1100 | kctl->tlv.c = mixer_vol_tlv; | ||
1101 | kctl->vd[0].access |= | ||
1102 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
1103 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | ||
1104 | check_mapped_dB(map, cval); | 1094 | check_mapped_dB(map, cval); |
1095 | if (cval->dBmin < cval->dBmax) { | ||
1096 | kctl->tlv.c = mixer_vol_tlv; | ||
1097 | kctl->vd[0].access |= | ||
1098 | SNDRV_CTL_ELEM_ACCESS_TLV_READ | | ||
1099 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK; | ||
1100 | } | ||
1105 | } | 1101 | } |
1106 | break; | 1102 | break; |
1107 | 1103 | ||
@@ -1174,7 +1170,7 @@ static void build_feature_ctl(struct mixer_build *state, void *raw_desc, | |||
1174 | 1170 | ||
1175 | 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", |
1176 | 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); |
1177 | add_control_to_empty(state, kctl); | 1173 | snd_usb_mixer_add_control(state->mixer, kctl); |
1178 | } | 1174 | } |
1179 | 1175 | ||
1180 | 1176 | ||
@@ -1338,7 +1334,7 @@ static void build_mixer_unit_ctl(struct mixer_build *state, | |||
1338 | 1334 | ||
1339 | 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", |
1340 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max); | 1336 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max); |
1341 | add_control_to_empty(state, kctl); | 1337 | snd_usb_mixer_add_control(state->mixer, kctl); |
1342 | } | 1338 | } |
1343 | 1339 | ||
1344 | 1340 | ||
@@ -1639,7 +1635,7 @@ static int build_audio_procunit(struct mixer_build *state, int unitid, void *raw | |||
1639 | 1635 | ||
1640 | 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", |
1641 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max); | 1637 | cval->id, kctl->id.name, cval->channels, cval->min, cval->max); |
1642 | if ((err = add_control_to_empty(state, kctl)) < 0) | 1638 | if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0) |
1643 | return err; | 1639 | return err; |
1644 | } | 1640 | } |
1645 | return 0; | 1641 | return 0; |
@@ -1856,7 +1852,7 @@ static int parse_audio_selector_unit(struct mixer_build *state, int unitid, void | |||
1856 | 1852 | ||
1857 | snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", | 1853 | snd_printdd(KERN_INFO "[%d] SU [%s] items = %d\n", |
1858 | cval->id, kctl->id.name, desc->bNrInPins); | 1854 | cval->id, kctl->id.name, desc->bNrInPins); |
1859 | if ((err = add_control_to_empty(state, kctl)) < 0) | 1855 | if ((err = snd_usb_mixer_add_control(state->mixer, kctl)) < 0) |
1860 | return err; | 1856 | return err; |
1861 | 1857 | ||
1862 | 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 73dcc8256bc0..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 | * |
@@ -61,6 +63,7 @@ static const struct rc_config { | |||
61 | { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ | 63 | { USB_ID(0x041e, 0x3020), 2, 1, 6, 6, 18, 0x0013 }, /* Audigy 2 NX */ |
62 | { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ | 64 | { USB_ID(0x041e, 0x3040), 2, 2, 6, 6, 2, 0x6e91 }, /* Live! 24-bit */ |
63 | { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */ | 65 | { USB_ID(0x041e, 0x3042), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 */ |
66 | { USB_ID(0x041e, 0x30df), 0, 1, 1, 1, 1, 0x000d }, /* Usb X-Fi S51 Pro */ | ||
64 | { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ | 67 | { USB_ID(0x041e, 0x3048), 2, 2, 6, 6, 2, 0x6e91 }, /* Toshiba SB0500 */ |
65 | }; | 68 | }; |
66 | 69 | ||
@@ -188,6 +191,12 @@ static int snd_audigy2nx_led_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e | |||
188 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 191 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, |
189 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | 192 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, |
190 | !value, 0, NULL, 0, 100); | 193 | !value, 0, NULL, 0, 100); |
194 | /* USB X-Fi S51 Pro */ | ||
195 | if (mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) | ||
196 | err = snd_usb_ctl_msg(mixer->chip->dev, | ||
197 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | ||
198 | USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_OTHER, | ||
199 | !value, 0, NULL, 0, 100); | ||
191 | else | 200 | else |
192 | err = snd_usb_ctl_msg(mixer->chip->dev, | 201 | err = snd_usb_ctl_msg(mixer->chip->dev, |
193 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, | 202 | usb_sndctrlpipe(mixer->chip->dev, 0), 0x24, |
@@ -234,9 +243,13 @@ static int snd_audigy2nx_controls_create(struct usb_mixer_interface *mixer) | |||
234 | /* USB X-Fi S51 doesn't have a CMSS LED */ | 243 | /* USB X-Fi S51 doesn't have a CMSS LED */ |
235 | if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) | 244 | if ((mixer->chip->usb_id == USB_ID(0x041e, 0x3042)) && i == 0) |
236 | continue; | 245 | continue; |
246 | /* USB X-Fi S51 Pro doesn't have one either */ | ||
247 | if ((mixer->chip->usb_id == USB_ID(0x041e, 0x30df)) && i == 0) | ||
248 | continue; | ||
237 | if (i > 1 && /* Live24ext has 2 LEDs only */ | 249 | if (i > 1 && /* Live24ext has 2 LEDs only */ |
238 | (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || | 250 | (mixer->chip->usb_id == USB_ID(0x041e, 0x3040) || |
239 | mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || | 251 | mixer->chip->usb_id == USB_ID(0x041e, 0x3042) || |
252 | mixer->chip->usb_id == USB_ID(0x041e, 0x30df) || | ||
240 | mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) | 253 | mixer->chip->usb_id == USB_ID(0x041e, 0x3048))) |
241 | break; | 254 | break; |
242 | err = snd_ctl_add(mixer->chip->card, | 255 | err = snd_ctl_add(mixer->chip->card, |
@@ -481,6 +494,69 @@ static int snd_nativeinstruments_create_mixer(struct usb_mixer_interface *mixer, | |||
481 | return err; | 494 | return err; |
482 | } | 495 | } |
483 | 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 | |||
484 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, | 560 | void snd_emuusb_set_samplerate(struct snd_usb_audio *chip, |
485 | unsigned char samplerate_id) | 561 | unsigned char samplerate_id) |
486 | { | 562 | { |
@@ -512,6 +588,7 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
512 | case USB_ID(0x041e, 0x3020): | 588 | case USB_ID(0x041e, 0x3020): |
513 | case USB_ID(0x041e, 0x3040): | 589 | case USB_ID(0x041e, 0x3040): |
514 | case USB_ID(0x041e, 0x3042): | 590 | case USB_ID(0x041e, 0x3042): |
591 | case USB_ID(0x041e, 0x30df): | ||
515 | case USB_ID(0x041e, 0x3048): | 592 | case USB_ID(0x041e, 0x3048): |
516 | err = snd_audigy2nx_controls_create(mixer); | 593 | err = snd_audigy2nx_controls_create(mixer); |
517 | if (err < 0) | 594 | if (err < 0) |
@@ -521,6 +598,11 @@ int snd_usb_mixer_apply_create_quirk(struct usb_mixer_interface *mixer) | |||
521 | snd_audigy2nx_proc_read); | 598 | snd_audigy2nx_proc_read); |
522 | break; | 599 | break; |
523 | 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 | |||
524 | case USB_ID(0x0b05, 0x1739): | 606 | case USB_ID(0x0b05, 0x1739): |
525 | case USB_ID(0x0b05, 0x1743): | 607 | case USB_ID(0x0b05, 0x1743): |
526 | 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 c66d3f64dcf8..0b2ae8e1c02d 100644 --- a/sound/usb/quirks-table.h +++ b/sound/usb/quirks-table.h | |||
@@ -1651,6 +1651,32 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1651 | } | 1651 | } |
1652 | } | 1652 | } |
1653 | }, | 1653 | }, |
1654 | { | ||
1655 | USB_DEVICE(0x0582, 0x0127), | ||
1656 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
1657 | /* .vendor_name = "Roland", */ | ||
1658 | /* .product_name = "GR-55", */ | ||
1659 | .ifnum = QUIRK_ANY_INTERFACE, | ||
1660 | .type = QUIRK_COMPOSITE, | ||
1661 | .data = (const struct snd_usb_audio_quirk[]) { | ||
1662 | { | ||
1663 | .ifnum = 0, | ||
1664 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1665 | }, | ||
1666 | { | ||
1667 | .ifnum = 1, | ||
1668 | .type = QUIRK_AUDIO_STANDARD_INTERFACE | ||
1669 | }, | ||
1670 | { | ||
1671 | .ifnum = 2, | ||
1672 | .type = QUIRK_MIDI_STANDARD_INTERFACE | ||
1673 | }, | ||
1674 | { | ||
1675 | .ifnum = -1 | ||
1676 | } | ||
1677 | } | ||
1678 | } | ||
1679 | }, | ||
1654 | 1680 | ||
1655 | /* Guillemot devices */ | 1681 | /* Guillemot devices */ |
1656 | { | 1682 | { |
@@ -1953,7 +1979,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1953 | } | 1979 | } |
1954 | }, | 1980 | }, |
1955 | { | 1981 | { |
1956 | USB_DEVICE(0x0763, 0x2080), | 1982 | USB_DEVICE_VENDOR_SPEC(0x0763, 0x2080), |
1957 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 1983 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
1958 | /* .vendor_name = "M-Audio", */ | 1984 | /* .vendor_name = "M-Audio", */ |
1959 | /* .product_name = "Fast Track Ultra", */ | 1985 | /* .product_name = "Fast Track Ultra", */ |
@@ -1962,7 +1988,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
1962 | .data = & (const struct snd_usb_audio_quirk[]) { | 1988 | .data = & (const struct snd_usb_audio_quirk[]) { |
1963 | { | 1989 | { |
1964 | .ifnum = 0, | 1990 | .ifnum = 0, |
1965 | .type = QUIRK_IGNORE_INTERFACE | 1991 | .type = QUIRK_AUDIO_STANDARD_MIXER, |
1966 | }, | 1992 | }, |
1967 | { | 1993 | { |
1968 | .ifnum = 1, | 1994 | .ifnum = 1, |
@@ -2020,7 +2046,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2020 | } | 2046 | } |
2021 | }, | 2047 | }, |
2022 | { | 2048 | { |
2023 | USB_DEVICE(0x0763, 0x2081), | 2049 | USB_DEVICE_VENDOR_SPEC(0x0763, 0x2081), |
2024 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | 2050 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { |
2025 | /* .vendor_name = "M-Audio", */ | 2051 | /* .vendor_name = "M-Audio", */ |
2026 | /* .product_name = "Fast Track Ultra 8R", */ | 2052 | /* .product_name = "Fast Track Ultra 8R", */ |
@@ -2029,7 +2055,7 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2029 | .data = & (const struct snd_usb_audio_quirk[]) { | 2055 | .data = & (const struct snd_usb_audio_quirk[]) { |
2030 | { | 2056 | { |
2031 | .ifnum = 0, | 2057 | .ifnum = 0, |
2032 | .type = QUIRK_IGNORE_INTERFACE | 2058 | .type = QUIRK_AUDIO_STANDARD_MIXER, |
2033 | }, | 2059 | }, |
2034 | { | 2060 | { |
2035 | .ifnum = 1, | 2061 | .ifnum = 1, |
@@ -2179,6 +2205,17 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2179 | } | 2205 | } |
2180 | }, | 2206 | }, |
2181 | 2207 | ||
2208 | /* KORG devices */ | ||
2209 | { | ||
2210 | USB_DEVICE_VENDOR_SPEC(0x0944, 0x0200), | ||
2211 | .driver_info = (unsigned long) & (const struct snd_usb_audio_quirk) { | ||
2212 | .vendor_name = "KORG, Inc.", | ||
2213 | /* .product_name = "PANDORA PX5D", */ | ||
2214 | .ifnum = 3, | ||
2215 | .type = QUIRK_MIDI_STANDARD_INTERFACE, | ||
2216 | } | ||
2217 | }, | ||
2218 | |||
2182 | /* AKAI devices */ | 2219 | /* AKAI devices */ |
2183 | { | 2220 | { |
2184 | USB_DEVICE(0x09e8, 0x0062), | 2221 | USB_DEVICE(0x09e8, 0x0062), |
@@ -2332,6 +2369,12 @@ YAMAHA_DEVICE(0x7010, "UB99"), | |||
2332 | 2369 | ||
2333 | /* Native Instruments MK2 series */ | 2370 | /* Native Instruments MK2 series */ |
2334 | { | 2371 | { |
2372 | /* Komplete Audio 6 */ | ||
2373 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | ||
2374 | .idVendor = 0x17cc, | ||
2375 | .idProduct = 0x1000, | ||
2376 | }, | ||
2377 | { | ||
2335 | /* Traktor Audio 6 */ | 2378 | /* Traktor Audio 6 */ |
2336 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, | 2379 | .match_flags = USB_DEVICE_ID_MATCH_DEVICE, |
2337 | .idVendor = 0x17cc, | 2380 | .idVendor = 0x17cc, |
diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c index ec07e62e53f3..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) { |
@@ -533,12 +549,14 @@ int snd_usb_apply_boot_quirk(struct usb_device *dev, | |||
533 | 549 | ||
534 | case USB_ID(0x0d8c, 0x0102): | 550 | case USB_ID(0x0d8c, 0x0102): |
535 | /* C-Media CM6206 / CM106-Like Sound Device */ | 551 | /* C-Media CM6206 / CM106-Like Sound Device */ |
552 | case USB_ID(0x0ccd, 0x00b1): /* Terratec Aureon 7.1 USB */ | ||
536 | return snd_usb_cm6206_boot_quirk(dev); | 553 | return snd_usb_cm6206_boot_quirk(dev); |
537 | 554 | ||
538 | case USB_ID(0x133e, 0x0815): | 555 | case USB_ID(0x133e, 0x0815): |
539 | /* Access Music VirusTI Desktop */ | 556 | /* Access Music VirusTI Desktop */ |
540 | return snd_usb_accessmusic_boot_quirk(dev); | 557 | return snd_usb_accessmusic_boot_quirk(dev); |
541 | 558 | ||
559 | case USB_ID(0x17cc, 0x1000): /* Komplete Audio 6 */ | ||
542 | case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ | 560 | case USB_ID(0x17cc, 0x1010): /* Traktor Audio 6 */ |
543 | case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ | 561 | case USB_ID(0x17cc, 0x1020): /* Traktor Audio 10 */ |
544 | return snd_usb_nativeinstruments_boot_quirk(dev); | 562 | return snd_usb_nativeinstruments_boot_quirk(dev); |
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 | }; |