diff options
author | Takashi Iwai <tiwai@suse.de> | 2011-06-21 09:57:44 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2011-06-21 10:02:32 -0400 |
commit | 09a9ad69a5467fbda3fd358d2be155c22aa416e4 (patch) | |
tree | 336c02b4a218897b40413a92cc09c26ac2599de7 /sound/pci | |
parent | a934d5a983528543850c90b29bedbdfd71f7097b (diff) |
ALSA: hda - VT1708 independent HP routing fix
The codecs like VT1708 needs more complicated routing using the mixer
widget rather than the simple selector widgets.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci')
-rw-r--r-- | sound/pci/hda/patch_via.c | 222 |
1 files changed, 122 insertions, 100 deletions
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c index 5b907b356951..bceb6b2364fe 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c | |||
@@ -83,10 +83,20 @@ enum VIA_HDA_CODEC { | |||
83 | 83 | ||
84 | #define MAX_NID_PATH_DEPTH 5 | 84 | #define MAX_NID_PATH_DEPTH 5 |
85 | 85 | ||
86 | /* output-path: DAC -> ... -> pin | ||
87 | * idx[] contains the source index number of the next widget; | ||
88 | * e.g. idx[0] is the index of the DAC selected by path[1] widget | ||
89 | * multi[] indicates whether it's a selector widget with multi-connectors | ||
90 | * (i.e. the connection selection is mandatory) | ||
91 | * vol_ctl and mute_ctl contains the NIDs for the assigned mixers | ||
92 | */ | ||
86 | struct nid_path { | 93 | struct nid_path { |
87 | int depth; | 94 | int depth; |
88 | hda_nid_t path[MAX_NID_PATH_DEPTH]; | 95 | hda_nid_t path[MAX_NID_PATH_DEPTH]; |
89 | short idx[MAX_NID_PATH_DEPTH]; | 96 | unsigned char idx[MAX_NID_PATH_DEPTH]; |
97 | unsigned char multi[MAX_NID_PATH_DEPTH]; | ||
98 | unsigned int vol_ctl; | ||
99 | unsigned int mute_ctl; | ||
90 | }; | 100 | }; |
91 | 101 | ||
92 | struct via_spec { | 102 | struct via_spec { |
@@ -422,43 +432,39 @@ static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | |||
422 | return false; | 432 | return false; |
423 | } | 433 | } |
424 | 434 | ||
425 | #define have_vol_or_mute(codec, nid, dir) \ | 435 | #define have_mute(codec, nid, dir) \ |
426 | check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS | AC_AMPCAP_MUTE) | 436 | check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE) |
427 | 437 | ||
428 | /* unmute input amp and select the specificed source */ | 438 | /* enable/disable the output-route */ |
429 | static void unmute_and_select(struct hda_codec *codec, hda_nid_t nid, | 439 | static void activate_output_path(struct hda_codec *codec, struct nid_path *path, |
430 | hda_nid_t src, hda_nid_t mix) | 440 | bool enable, bool force) |
431 | { | 441 | { |
432 | int idx, num_conns; | 442 | int i; |
433 | 443 | for (i = 0; i < path->depth; i++) { | |
434 | idx = __get_connection_index(codec, nid, src, &num_conns); | 444 | hda_nid_t src, dst; |
435 | if (idx < 0) | 445 | int idx = path->idx[i]; |
436 | return; | 446 | src = path->path[i]; |
437 | 447 | if (i < path->depth - 1) | |
438 | /* select the route explicitly when multiple connections exist */ | 448 | dst = path->path[i + 1]; |
439 | if (num_conns > 1 && | 449 | else |
440 | get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX) | 450 | dst = 0; |
441 | snd_hda_codec_write(codec, nid, 0, | 451 | if (enable && path->multi[i]) |
442 | AC_VERB_SET_CONNECT_SEL, idx); | 452 | snd_hda_codec_write(codec, dst, 0, |
443 | 453 | AC_VERB_SET_CONNECT_SEL, idx); | |
444 | /* unmute if the input amp is present */ | 454 | if (have_mute(codec, dst, HDA_INPUT)) { |
445 | if (have_vol_or_mute(codec, nid, HDA_INPUT)) | 455 | int val = enable ? AMP_IN_UNMUTE(idx) : |
446 | snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 456 | AMP_IN_MUTE(idx); |
447 | AMP_IN_UNMUTE(idx)); | 457 | snd_hda_codec_write(codec, dst, 0, |
448 | 458 | AC_VERB_SET_AMP_GAIN_MUTE, val); | |
449 | /* unmute the src output */ | 459 | } |
450 | if (have_vol_or_mute(codec, src, HDA_OUTPUT)) | 460 | if (!force && (src == path->vol_ctl || src == path->mute_ctl)) |
451 | snd_hda_codec_write(codec, src, 0, AC_VERB_SET_AMP_GAIN_MUTE, | 461 | continue; |
452 | AMP_OUT_UNMUTE); | 462 | if (have_mute(codec, src, HDA_OUTPUT)) { |
453 | 463 | int val = enable ? AMP_OUT_UNMUTE : AMP_OUT_MUTE; | |
454 | /* unmute AA-path if present */ | 464 | snd_hda_codec_write(codec, src, 0, |
455 | if (!mix || mix == src) | 465 | AC_VERB_SET_AMP_GAIN_MUTE, val); |
456 | return; | 466 | } |
457 | idx = __get_connection_index(codec, nid, mix, NULL); | 467 | } |
458 | if (idx >= 0 && have_vol_or_mute(codec, nid, HDA_INPUT)) | ||
459 | snd_hda_codec_write(codec, nid, 0, | ||
460 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
461 | AMP_IN_UNMUTE(idx)); | ||
462 | } | 468 | } |
463 | 469 | ||
464 | /* set the given pin as output */ | 470 | /* set the given pin as output */ |
@@ -474,16 +480,18 @@ static void init_output_pin(struct hda_codec *codec, hda_nid_t pin, | |||
474 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); | 480 | AC_VERB_SET_EAPD_BTLENABLE, 0x02); |
475 | } | 481 | } |
476 | 482 | ||
477 | static void via_auto_init_output(struct hda_codec *codec, hda_nid_t pin, | 483 | static void via_auto_init_output(struct hda_codec *codec, |
478 | int pin_type, struct nid_path *path) | 484 | struct nid_path *path, int pin_type, |
485 | bool force) | ||
479 | { | 486 | { |
480 | struct via_spec *spec = codec->spec; | 487 | struct via_spec *spec = codec->spec; |
481 | unsigned int caps; | 488 | unsigned int caps; |
482 | hda_nid_t nid; | 489 | hda_nid_t pin, nid; |
483 | int i; | 490 | int i, idx; |
484 | 491 | ||
485 | if (!pin) | 492 | if (!path->depth) |
486 | return; | 493 | return; |
494 | pin = path->path[path->depth - 1]; | ||
487 | 495 | ||
488 | init_output_pin(codec, pin, pin_type); | 496 | init_output_pin(codec, pin, pin_type); |
489 | caps = query_amp_caps(codec, pin, HDA_OUTPUT); | 497 | caps = query_amp_caps(codec, pin, HDA_OUTPUT); |
@@ -494,34 +502,48 @@ static void via_auto_init_output(struct hda_codec *codec, hda_nid_t pin, | |||
494 | AMP_OUT_MUTE | val); | 502 | AMP_OUT_MUTE | val); |
495 | } | 503 | } |
496 | 504 | ||
497 | /* initialize the output path */ | 505 | activate_output_path(codec, path, true, force); |
506 | |||
507 | /* initialize the AA-path */ | ||
508 | if (!spec->aa_mix_nid) | ||
509 | return; | ||
498 | for (i = path->depth - 1; i > 0; i--) { | 510 | for (i = path->depth - 1; i > 0; i--) { |
499 | nid = path->path[i - 1]; | 511 | nid = path->path[i]; |
500 | unmute_and_select(codec, path->path[i], nid, spec->aa_mix_nid); | 512 | idx = get_connection_index(codec, nid, spec->aa_mix_nid); |
513 | if (idx >= 0) { | ||
514 | if (have_mute(codec, nid, HDA_INPUT)) | ||
515 | snd_hda_codec_write(codec, nid, 0, | ||
516 | AC_VERB_SET_AMP_GAIN_MUTE, | ||
517 | AMP_IN_UNMUTE(idx)); | ||
518 | break; | ||
519 | } | ||
501 | } | 520 | } |
502 | } | 521 | } |
503 | 522 | ||
504 | |||
505 | static void via_auto_init_multi_out(struct hda_codec *codec) | 523 | static void via_auto_init_multi_out(struct hda_codec *codec) |
506 | { | 524 | { |
507 | struct via_spec *spec = codec->spec; | 525 | struct via_spec *spec = codec->spec; |
508 | int i; | 526 | int i; |
509 | 527 | ||
510 | for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++) | 528 | for (i = 0; i < spec->autocfg.line_outs + spec->smart51_nums; i++) |
511 | via_auto_init_output(codec, spec->autocfg.line_out_pins[i], | 529 | via_auto_init_output(codec, &spec->out_path[i], PIN_OUT, true); |
512 | PIN_OUT, &spec->out_path[i]); | ||
513 | } | 530 | } |
514 | 531 | ||
515 | static void via_auto_init_hp_out(struct hda_codec *codec) | 532 | static void via_auto_init_hp_out(struct hda_codec *codec) |
516 | { | 533 | { |
517 | struct via_spec *spec = codec->spec; | 534 | struct via_spec *spec = codec->spec; |
518 | 535 | ||
519 | if (spec->hp_dac_nid) | 536 | if (!spec->hp_dac_nid) { |
520 | via_auto_init_output(codec, spec->autocfg.hp_pins[0], PIN_HP, | 537 | via_auto_init_output(codec, &spec->hp_dep_path, PIN_HP, true); |
521 | &spec->hp_path); | 538 | return; |
522 | else | 539 | } |
523 | via_auto_init_output(codec, spec->autocfg.hp_pins[0], PIN_HP, | 540 | if (spec->hp_independent_mode) { |
524 | &spec->hp_dep_path); | 541 | activate_output_path(codec, &spec->hp_dep_path, false, false); |
542 | via_auto_init_output(codec, &spec->hp_path, PIN_HP, true); | ||
543 | } else { | ||
544 | activate_output_path(codec, &spec->hp_path, false, false); | ||
545 | via_auto_init_output(codec, &spec->hp_dep_path, PIN_HP, true); | ||
546 | } | ||
525 | } | 547 | } |
526 | 548 | ||
527 | static void via_auto_init_speaker_out(struct hda_codec *codec) | 549 | static void via_auto_init_speaker_out(struct hda_codec *codec) |
@@ -529,8 +551,7 @@ static void via_auto_init_speaker_out(struct hda_codec *codec) | |||
529 | struct via_spec *spec = codec->spec; | 551 | struct via_spec *spec = codec->spec; |
530 | 552 | ||
531 | if (spec->autocfg.speaker_outs) | 553 | if (spec->autocfg.speaker_outs) |
532 | via_auto_init_output(codec, spec->autocfg.speaker_pins[0], | 554 | via_auto_init_output(codec, &spec->speaker_path, PIN_OUT, true); |
533 | PIN_OUT, &spec->speaker_path); | ||
534 | } | 555 | } |
535 | 556 | ||
536 | static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin); | 557 | static bool is_smart51_pins(struct hda_codec *codec, hda_nid_t pin); |
@@ -738,27 +759,14 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, | |||
738 | { | 759 | { |
739 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); | 760 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
740 | struct via_spec *spec = codec->spec; | 761 | struct via_spec *spec = codec->spec; |
741 | hda_nid_t nid, src; | ||
742 | int i, idx, num_conns; | ||
743 | struct nid_path *path; | ||
744 | 762 | ||
745 | spec->hp_independent_mode = !!ucontrol->value.enumerated.item[0]; | 763 | spec->hp_independent_mode = !!ucontrol->value.enumerated.item[0]; |
746 | if (spec->hp_independent_mode) | 764 | if (spec->hp_independent_mode) { |
747 | path = &spec->hp_path; | 765 | activate_output_path(codec, &spec->hp_dep_path, false, false); |
748 | else | 766 | activate_output_path(codec, &spec->hp_path, true, false); |
749 | path = &spec->hp_dep_path; | 767 | } else { |
750 | 768 | activate_output_path(codec, &spec->hp_path, false, false); | |
751 | /* re-route the output path */ | 769 | activate_output_path(codec, &spec->hp_dep_path, true, false); |
752 | for (i = path->depth - 1; i > 0; i--) { | ||
753 | nid = path->path[i]; | ||
754 | src = path->path[i - 1]; | ||
755 | idx = __get_connection_index(codec, nid, src, &num_conns); | ||
756 | if (idx < 0) | ||
757 | continue; | ||
758 | if (num_conns > 1 && | ||
759 | get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX) | ||
760 | snd_hda_codec_write(codec, nid, 0, | ||
761 | AC_VERB_SET_CONNECT_SEL, idx); | ||
762 | } | 770 | } |
763 | 771 | ||
764 | /* update jack power state */ | 772 | /* update jack power state */ |
@@ -1577,12 +1585,8 @@ static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid, | |||
1577 | for (i = 0; i < nums; i++) { | 1585 | for (i = 0; i < nums; i++) { |
1578 | if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT) | 1586 | if (get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT) |
1579 | continue; | 1587 | continue; |
1580 | if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) { | 1588 | if (conn[i] == target_dac || is_empty_dac(codec, conn[i])) |
1581 | path->path[0] = conn[i]; | 1589 | goto found; |
1582 | path->idx[0] = i; | ||
1583 | path->depth = 1; | ||
1584 | return true; | ||
1585 | } | ||
1586 | } | 1590 | } |
1587 | if (depth >= MAX_NID_PATH_DEPTH) | 1591 | if (depth >= MAX_NID_PATH_DEPTH) |
1588 | return false; | 1592 | return false; |
@@ -1593,14 +1597,18 @@ static bool __parse_output_path(struct hda_codec *codec, hda_nid_t nid, | |||
1593 | (wid_type != -1 && type != wid_type)) | 1597 | (wid_type != -1 && type != wid_type)) |
1594 | continue; | 1598 | continue; |
1595 | if (__parse_output_path(codec, conn[i], target_dac, | 1599 | if (__parse_output_path(codec, conn[i], target_dac, |
1596 | path, depth + 1, AC_WID_AUD_SEL)) { | 1600 | path, depth + 1, AC_WID_AUD_SEL)) |
1597 | path->path[path->depth] = conn[i]; | 1601 | goto found; |
1598 | path->idx[path->depth] = i; | ||
1599 | path->depth++; | ||
1600 | return true; | ||
1601 | } | ||
1602 | } | 1602 | } |
1603 | return false; | 1603 | return false; |
1604 | |||
1605 | found: | ||
1606 | path->path[path->depth] = conn[i]; | ||
1607 | path->idx[path->depth] = i; | ||
1608 | if (nums > 1 && get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_MIX) | ||
1609 | path->multi[path->depth] = 1; | ||
1610 | path->depth++; | ||
1611 | return true; | ||
1604 | } | 1612 | } |
1605 | 1613 | ||
1606 | static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid, | 1614 | static bool parse_output_path(struct hda_codec *codec, hda_nid_t nid, |
@@ -1634,18 +1642,16 @@ static int via_auto_fill_dac_nids(struct hda_codec *codec) | |||
1634 | } | 1642 | } |
1635 | 1643 | ||
1636 | static int create_ch_ctls(struct hda_codec *codec, const char *pfx, | 1644 | static int create_ch_ctls(struct hda_codec *codec, const char *pfx, |
1637 | hda_nid_t pin, hda_nid_t dac, int chs) | 1645 | int chs, bool check_dac, struct nid_path *path) |
1638 | { | 1646 | { |
1639 | struct via_spec *spec = codec->spec; | 1647 | struct via_spec *spec = codec->spec; |
1640 | char name[32]; | 1648 | char name[32]; |
1641 | hda_nid_t nid, sel, conn[8]; | 1649 | hda_nid_t dac, pin, sel, nid; |
1642 | int nums, err; | 1650 | int err; |
1643 | 1651 | ||
1644 | /* check selector widget connected to the pin */ | 1652 | dac = check_dac ? path->path[0] : 0; |
1645 | sel = 0; | 1653 | pin = path->path[path->depth - 1]; |
1646 | nums = snd_hda_get_connections(codec, pin, conn, ARRAY_SIZE(conn)); | 1654 | sel = path->depth > 1 ? path->path[1] : 0; |
1647 | if (nums == 1 && conn[0] != pin) | ||
1648 | sel = conn[0]; | ||
1649 | 1655 | ||
1650 | if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS)) | 1656 | if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_NUM_STEPS)) |
1651 | nid = dac; | 1657 | nid = dac; |
@@ -1661,6 +1667,7 @@ static int create_ch_ctls(struct hda_codec *codec, const char *pfx, | |||
1661 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 1667 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); |
1662 | if (err < 0) | 1668 | if (err < 0) |
1663 | return err; | 1669 | return err; |
1670 | path->vol_ctl = nid; | ||
1664 | } | 1671 | } |
1665 | 1672 | ||
1666 | if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_MUTE)) | 1673 | if (dac && check_amp_caps(codec, dac, HDA_OUTPUT, AC_AMPCAP_MUTE)) |
@@ -1677,6 +1684,7 @@ static int create_ch_ctls(struct hda_codec *codec, const char *pfx, | |||
1677 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); | 1684 | HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); |
1678 | if (err < 0) | 1685 | if (err < 0) |
1679 | return err; | 1686 | return err; |
1687 | path->mute_ctl = nid; | ||
1680 | } | 1688 | } |
1681 | return 0; | 1689 | return 0; |
1682 | } | 1690 | } |
@@ -1747,10 +1755,12 @@ static int via_auto_create_multi_out_ctls(struct hda_codec *codec) | |||
1747 | if (!pin || !dac) | 1755 | if (!pin || !dac) |
1748 | continue; | 1756 | continue; |
1749 | if (i == HDA_CLFE) { | 1757 | if (i == HDA_CLFE) { |
1750 | err = create_ch_ctls(codec, "Center", pin, dac, 1); | 1758 | err = create_ch_ctls(codec, "Center", 1, true, |
1759 | &spec->out_path[i]); | ||
1751 | if (err < 0) | 1760 | if (err < 0) |
1752 | return err; | 1761 | return err; |
1753 | err = create_ch_ctls(codec, "LFE", pin, dac, 2); | 1762 | err = create_ch_ctls(codec, "LFE", 2, true, |
1763 | &spec->out_path[i]); | ||
1754 | if (err < 0) | 1764 | if (err < 0) |
1755 | return err; | 1765 | return err; |
1756 | } else { | 1766 | } else { |
@@ -1758,7 +1768,8 @@ static int via_auto_create_multi_out_ctls(struct hda_codec *codec) | |||
1758 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && | 1768 | if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT && |
1759 | cfg->line_outs == 1) | 1769 | cfg->line_outs == 1) |
1760 | pfx = "Speaker"; | 1770 | pfx = "Speaker"; |
1761 | err = create_ch_ctls(codec, pfx, pin, dac, 3); | 1771 | err = create_ch_ctls(codec, pfx, 3, true, |
1772 | &spec->out_path[i]); | ||
1762 | if (err < 0) | 1773 | if (err < 0) |
1763 | return err; | 1774 | return err; |
1764 | } | 1775 | } |
@@ -1790,6 +1801,7 @@ static int via_auto_create_multi_out_ctls(struct hda_codec *codec) | |||
1790 | static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) | 1801 | static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) |
1791 | { | 1802 | { |
1792 | struct via_spec *spec = codec->spec; | 1803 | struct via_spec *spec = codec->spec; |
1804 | struct nid_path *path; | ||
1793 | int err; | 1805 | int err; |
1794 | 1806 | ||
1795 | if (!pin) | 1807 | if (!pin) |
@@ -1803,9 +1815,17 @@ static int via_auto_create_hp_ctls(struct hda_codec *codec, hda_nid_t pin) | |||
1803 | !spec->hp_dac_nid) | 1815 | !spec->hp_dac_nid) |
1804 | return 0; | 1816 | return 0; |
1805 | 1817 | ||
1806 | err = create_ch_ctls(codec, "Headphone", pin, spec->hp_dac_nid, 3); | 1818 | if (spec->hp_dac_nid) |
1819 | path = &spec->hp_path; | ||
1820 | else | ||
1821 | path = &spec->hp_dep_path; | ||
1822 | err = create_ch_ctls(codec, "Headphone", 3, false, path); | ||
1807 | if (err < 0) | 1823 | if (err < 0) |
1808 | return err; | 1824 | return err; |
1825 | if (spec->hp_dac_nid) { | ||
1826 | spec->hp_dep_path.vol_ctl = spec->hp_path.vol_ctl; | ||
1827 | spec->hp_dep_path.mute_ctl = spec->hp_path.mute_ctl; | ||
1828 | } | ||
1809 | 1829 | ||
1810 | return 0; | 1830 | return 0; |
1811 | } | 1831 | } |
@@ -1822,11 +1842,13 @@ static int via_auto_create_speaker_ctls(struct hda_codec *codec) | |||
1822 | if (parse_output_path(codec, pin, 0, &spec->speaker_path)) { | 1842 | if (parse_output_path(codec, pin, 0, &spec->speaker_path)) { |
1823 | dac = spec->speaker_path.path[0]; | 1843 | dac = spec->speaker_path.path[0]; |
1824 | spec->multiout.extra_out_nid[0] = dac; | 1844 | spec->multiout.extra_out_nid[0] = dac; |
1825 | return create_ch_ctls(codec, "Speaker", pin, dac, 3); | 1845 | return create_ch_ctls(codec, "Speaker", 3, true, |
1846 | &spec->speaker_path); | ||
1826 | } | 1847 | } |
1827 | if (parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT], | 1848 | if (parse_output_path(codec, pin, spec->multiout.dac_nids[HDA_FRONT], |
1828 | &spec->speaker_path)) | 1849 | &spec->speaker_path)) |
1829 | return create_ch_ctls(codec, "Speaker", pin, 0, 3); | 1850 | return create_ch_ctls(codec, "Speaker", 3, false, |
1851 | &spec->speaker_path); | ||
1830 | 1852 | ||
1831 | return 0; | 1853 | return 0; |
1832 | } | 1854 | } |