aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2009-01-20 12:32:55 -0500
committerTakashi Iwai <tiwai@suse.de>2009-01-20 12:32:55 -0500
commite64f14f4e570d6ec5bc88abac92a3a27150756d7 (patch)
tree36e254757e4277a047c26c724b48dec18061a4bc /sound/pci/hda
parent8c441982fdc00f77b7aa609061c6411f47bcceda (diff)
ALSA: hda - Allow digital-only I/O on ALC262 codec
Some laptops like VAIO have multiple codecs and uses ALC262 only for the SPIDF output without analog I/O. So far, the codec-parser assumes the presence of analog I/O and returned an error for such a case. This patch adds some hacks to allow the digital-only configuration for ALC262. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda')
-rw-r--r--sound/pci/hda/patch_realtek.c43
1 files changed, 33 insertions, 10 deletions
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 4fdae06162ed..4cfa78c54398 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -306,6 +306,9 @@ struct alc_spec {
306 unsigned int jack_present: 1; 306 unsigned int jack_present: 1;
307 unsigned int master_sw: 1; 307 unsigned int master_sw: 1;
308 308
309 /* other flags */
310 unsigned int no_analog :1; /* digital I/O only */
311
309 /* for virtual master */ 312 /* for virtual master */
310 hda_nid_t vmaster_nid; 313 hda_nid_t vmaster_nid;
311#ifdef CONFIG_SND_HDA_POWER_SAVE 314#ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -2019,11 +2022,13 @@ static int alc_build_controls(struct hda_codec *codec)
2019 spec->multiout.dig_out_nid); 2022 spec->multiout.dig_out_nid);
2020 if (err < 0) 2023 if (err < 0)
2021 return err; 2024 return err;
2022 err = snd_hda_create_spdif_share_sw(codec, 2025 if (!spec->no_analog) {
2023 &spec->multiout); 2026 err = snd_hda_create_spdif_share_sw(codec,
2024 if (err < 0) 2027 &spec->multiout);
2025 return err; 2028 if (err < 0)
2026 spec->multiout.share_spdif = 1; 2029 return err;
2030 spec->multiout.share_spdif = 1;
2031 }
2027 } 2032 }
2028 if (spec->dig_in_nid) { 2033 if (spec->dig_in_nid) {
2029 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 2034 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
@@ -2032,7 +2037,8 @@ static int alc_build_controls(struct hda_codec *codec)
2032 } 2037 }
2033 2038
2034 /* if we have no master control, let's create it */ 2039 /* if we have no master control, let's create it */
2035 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 2040 if (!spec->no_analog &&
2041 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
2036 unsigned int vmaster_tlv[4]; 2042 unsigned int vmaster_tlv[4];
2037 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 2043 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
2038 HDA_OUTPUT, vmaster_tlv); 2044 HDA_OUTPUT, vmaster_tlv);
@@ -2041,7 +2047,8 @@ static int alc_build_controls(struct hda_codec *codec)
2041 if (err < 0) 2047 if (err < 0)
2042 return err; 2048 return err;
2043 } 2049 }
2044 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 2050 if (!spec->no_analog &&
2051 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
2045 err = snd_hda_add_vmaster(codec, "Master Playback Switch", 2052 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
2046 NULL, alc_slave_sws); 2053 NULL, alc_slave_sws);
2047 if (err < 0) 2054 if (err < 0)
@@ -3060,6 +3067,9 @@ static int alc_build_pcms(struct hda_codec *codec)
3060 codec->num_pcms = 1; 3067 codec->num_pcms = 1;
3061 codec->pcm_info = info; 3068 codec->pcm_info = info;
3062 3069
3070 if (spec->no_analog)
3071 goto skip_analog;
3072
3063 info->name = spec->stream_name_analog; 3073 info->name = spec->stream_name_analog;
3064 if (spec->stream_analog_playback) { 3074 if (spec->stream_analog_playback) {
3065 if (snd_BUG_ON(!spec->multiout.dac_nids)) 3075 if (snd_BUG_ON(!spec->multiout.dac_nids))
@@ -3083,6 +3093,7 @@ static int alc_build_pcms(struct hda_codec *codec)
3083 } 3093 }
3084 } 3094 }
3085 3095
3096 skip_analog:
3086 /* SPDIF for stream index #1 */ 3097 /* SPDIF for stream index #1 */
3087 if (spec->multiout.dig_out_nid || spec->dig_in_nid) { 3098 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
3088 codec->num_pcms = 2; 3099 codec->num_pcms = 2;
@@ -3106,6 +3117,9 @@ static int alc_build_pcms(struct hda_codec *codec)
3106 codec->spdif_status_reset = 1; 3117 codec->spdif_status_reset = 1;
3107 } 3118 }
3108 3119
3120 if (spec->no_analog)
3121 return 0;
3122
3109 /* If the use of more than one ADC is requested for the current 3123 /* If the use of more than one ADC is requested for the current
3110 * model, configure a second analog capture-only PCM. 3124 * model, configure a second analog capture-only PCM.
3111 */ 3125 */
@@ -10468,8 +10482,14 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
10468 alc262_ignore); 10482 alc262_ignore);
10469 if (err < 0) 10483 if (err < 0)
10470 return err; 10484 return err;
10471 if (!spec->autocfg.line_outs) 10485 if (!spec->autocfg.line_outs) {
10486 if (spec->autocfg.dig_out_pin || spec->autocfg.dig_in_pin) {
10487 spec->multiout.max_channels = 2;
10488 spec->no_analog = 1;
10489 goto dig_only;
10490 }
10472 return 0; /* can't find valid BIOS pin config */ 10491 return 0; /* can't find valid BIOS pin config */
10492 }
10473 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg); 10493 err = alc262_auto_create_multi_out_ctls(spec, &spec->autocfg);
10474 if (err < 0) 10494 if (err < 0)
10475 return err; 10495 return err;
@@ -10479,8 +10499,11 @@ static int alc262_parse_auto_config(struct hda_codec *codec)
10479 10499
10480 spec->multiout.max_channels = spec->multiout.num_dacs * 2; 10500 spec->multiout.max_channels = spec->multiout.num_dacs * 2;
10481 10501
10482 if (spec->autocfg.dig_out_pin) 10502 dig_only:
10503 if (spec->autocfg.dig_out_pin) {
10483 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID; 10504 spec->multiout.dig_out_nid = ALC262_DIGOUT_NID;
10505 spec->dig_out_type = spec->autocfg.dig_out_type;
10506 }
10484 if (spec->autocfg.dig_in_pin) 10507 if (spec->autocfg.dig_in_pin)
10485 spec->dig_in_nid = ALC262_DIGIN_NID; 10508 spec->dig_in_nid = ALC262_DIGIN_NID;
10486 10509
@@ -10875,7 +10898,7 @@ static int patch_alc262(struct hda_codec *codec)
10875 spec->capsrc_nids = alc262_capsrc_nids; 10898 spec->capsrc_nids = alc262_capsrc_nids;
10876 } 10899 }
10877 } 10900 }
10878 if (!spec->cap_mixer) 10901 if (!spec->cap_mixer && !spec->no_analog)
10879 set_capture_mixer(spec); 10902 set_capture_mixer(spec);
10880 10903
10881 spec->vmaster_nid = 0x0c; 10904 spec->vmaster_nid = 0x0c;