| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * HD audio interface patch for AD1882, AD1884, AD1981HD, AD1983, AD1984, |
|---|
| 3 | 4 | * AD1986A, AD1988 |
|---|
| 4 | 5 | * |
|---|
| 5 | 6 | * Copyright (c) 2005-2007 Takashi Iwai <tiwai@suse.de> |
|---|
| 6 | | - * |
|---|
| 7 | | - * This driver is free software; you can redistribute it and/or modify |
|---|
| 8 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 9 | | - * the Free Software Foundation; either version 2 of the License, or |
|---|
| 10 | | - * (at your option) any later version. |
|---|
| 11 | | - * |
|---|
| 12 | | - * This driver is distributed in the hope that it will be useful, |
|---|
| 13 | | - * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 14 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|---|
| 15 | | - * GNU 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|---|
| 20 | 7 | */ |
|---|
| 21 | 8 | |
|---|
| 22 | 9 | #include <linux/init.h> |
|---|
| .. | .. |
|---|
| 24 | 11 | #include <linux/module.h> |
|---|
| 25 | 12 | |
|---|
| 26 | 13 | #include <sound/core.h> |
|---|
| 27 | | -#include "hda_codec.h" |
|---|
| 14 | +#include <sound/hda_codec.h> |
|---|
| 28 | 15 | #include "hda_local.h" |
|---|
| 29 | 16 | #include "hda_auto_parser.h" |
|---|
| 30 | 17 | #include "hda_beep.h" |
|---|
| .. | .. |
|---|
| 41 | 28 | hda_nid_t eapd_nid; |
|---|
| 42 | 29 | |
|---|
| 43 | 30 | unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ |
|---|
| 31 | + int num_smux_conns; |
|---|
| 44 | 32 | }; |
|---|
| 45 | 33 | |
|---|
| 46 | 34 | |
|---|
| .. | .. |
|---|
| 402 | 390 | { |
|---|
| 403 | 391 | int err; |
|---|
| 404 | 392 | struct ad198x_spec *spec; |
|---|
| 405 | | - static hda_nid_t preferred_pairs[] = { |
|---|
| 393 | + static const hda_nid_t preferred_pairs[] = { |
|---|
| 406 | 394 | 0x1a, 0x03, |
|---|
| 407 | 395 | 0x1b, 0x03, |
|---|
| 408 | 396 | 0x1c, 0x04, |
|---|
| .. | .. |
|---|
| 466 | 454 | struct ad198x_spec *spec = codec->spec; |
|---|
| 467 | 455 | static const char * const texts2[] = { "PCM", "ADC" }; |
|---|
| 468 | 456 | static const char * const texts3[] = { "PCM", "ADC1", "ADC2" }; |
|---|
| 469 | | - hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; |
|---|
| 470 | | - int num_conns = snd_hda_get_num_conns(codec, dig_out); |
|---|
| 457 | + int num_conns = spec->num_smux_conns; |
|---|
| 471 | 458 | |
|---|
| 472 | 459 | if (num_conns == 2) |
|---|
| 473 | 460 | return snd_hda_enum_helper_info(kcontrol, uinfo, 2, texts2); |
|---|
| .. | .. |
|---|
| 494 | 481 | struct ad198x_spec *spec = codec->spec; |
|---|
| 495 | 482 | unsigned int val = ucontrol->value.enumerated.item[0]; |
|---|
| 496 | 483 | hda_nid_t dig_out = spec->gen.multiout.dig_out_nid; |
|---|
| 497 | | - int num_conns = snd_hda_get_num_conns(codec, dig_out); |
|---|
| 484 | + int num_conns = spec->num_smux_conns; |
|---|
| 498 | 485 | |
|---|
| 499 | 486 | if (val >= num_conns) |
|---|
| 500 | 487 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 525 | 512 | num_conns = snd_hda_get_num_conns(codec, dig_out); |
|---|
| 526 | 513 | if (num_conns != 2 && num_conns != 3) |
|---|
| 527 | 514 | return 0; |
|---|
| 515 | + spec->num_smux_conns = num_conns; |
|---|
| 528 | 516 | if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &ad1983_auto_smux_mixer)) |
|---|
| 529 | 517 | return -ENOMEM; |
|---|
| 530 | 518 | return 0; |
|---|
| .. | .. |
|---|
| 532 | 520 | |
|---|
| 533 | 521 | static int patch_ad1983(struct hda_codec *codec) |
|---|
| 534 | 522 | { |
|---|
| 523 | + static const hda_nid_t conn_0c[] = { 0x08 }; |
|---|
| 524 | + static const hda_nid_t conn_0d[] = { 0x09 }; |
|---|
| 535 | 525 | struct ad198x_spec *spec; |
|---|
| 536 | | - static hda_nid_t conn_0c[] = { 0x08 }; |
|---|
| 537 | | - static hda_nid_t conn_0d[] = { 0x09 }; |
|---|
| 538 | 526 | int err; |
|---|
| 539 | 527 | |
|---|
| 540 | 528 | err = alloc_ad_spec(codec); |
|---|
| .. | .. |
|---|
| 743 | 731 | struct snd_ctl_elem_info *uinfo) |
|---|
| 744 | 732 | { |
|---|
| 745 | 733 | struct hda_codec *codec = snd_kcontrol_chip(kcontrol); |
|---|
| 734 | + struct ad198x_spec *spec = codec->spec; |
|---|
| 746 | 735 | static const char * const texts[] = { |
|---|
| 747 | 736 | "PCM", "ADC1", "ADC2", "ADC3", |
|---|
| 748 | 737 | }; |
|---|
| 749 | | - int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; |
|---|
| 738 | + int num_conns = spec->num_smux_conns; |
|---|
| 739 | + |
|---|
| 750 | 740 | if (num_conns > 4) |
|---|
| 751 | 741 | num_conns = 4; |
|---|
| 752 | 742 | return snd_hda_enum_helper_info(kcontrol, uinfo, num_conns, texts); |
|---|
| .. | .. |
|---|
| 769 | 759 | struct ad198x_spec *spec = codec->spec; |
|---|
| 770 | 760 | unsigned int val = ucontrol->value.enumerated.item[0]; |
|---|
| 771 | 761 | struct nid_path *path; |
|---|
| 772 | | - int num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; |
|---|
| 762 | + int num_conns = spec->num_smux_conns; |
|---|
| 773 | 763 | |
|---|
| 774 | 764 | if (val >= num_conns) |
|---|
| 775 | 765 | return -EINVAL; |
|---|
| .. | .. |
|---|
| 825 | 815 | /* we create four static faked paths, since AD codecs have odd |
|---|
| 826 | 816 | * widget connections regarding the SPDIF out source |
|---|
| 827 | 817 | */ |
|---|
| 828 | | - static struct nid_path fake_paths[4] = { |
|---|
| 818 | + static const struct nid_path fake_paths[4] = { |
|---|
| 829 | 819 | { |
|---|
| 830 | 820 | .depth = 3, |
|---|
| 831 | 821 | .path = { 0x02, 0x1d, 0x1b }, |
|---|
| .. | .. |
|---|
| 860 | 850 | num_conns = snd_hda_get_num_conns(codec, 0x0b) + 1; |
|---|
| 861 | 851 | if (num_conns != 3 && num_conns != 4) |
|---|
| 862 | 852 | return 0; |
|---|
| 853 | + spec->num_smux_conns = num_conns; |
|---|
| 863 | 854 | |
|---|
| 864 | 855 | for (i = 0; i < num_conns; i++) { |
|---|
| 865 | 856 | struct nid_path *path = snd_array_new(&spec->gen.paths); |
|---|