static int cs_parse_auto_config(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; int err; int i; err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); if (err < 0) return err; err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); if (err < 0) return err; /* keep the ADCs powered up when it's dynamically switchable */ if (spec->gen.dyn_adc_switch) { unsigned int done = 0; for (i = 0; i < spec->gen.input_mux.num_items; i++) { int idx = spec->gen.dyn_adc_idx[i]; if (done & (1 << idx)) continue; snd_hda_gen_fix_pin_power(codec, spec->gen.adc_nids[idx]); done |= 1 << idx; } } return 0; }
static int cs421x_parse_auto_config(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; hda_nid_t dac = CS4210_DAC_NID; int err; fix_volume_caps(codec, dac); err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); if (err < 0) return err; err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); if (err < 0) return err; parse_cs421x_digital(codec); if (spec->gen.autocfg.speaker_outs && spec->vendor_nid == CS4210_VENDOR_NID) { if (!snd_hda_gen_add_kctl(&spec->gen, NULL, &cs421x_speaker_boost_ctl)) return -ENOMEM; } return 0; }
static int ad198x_parse_auto_config(struct hda_codec *codec, bool indep_hp) { struct ad198x_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->gen.autocfg; int err; codec->spdif_status_reset = 1; codec->no_trigger_sense = 1; codec->no_sticky_stream = 1; spec->gen.indep_hp = indep_hp; if (!spec->gen.add_stereo_mix_input) spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO; err = snd_hda_parse_pin_defcfg(codec, cfg, NULL, 0); if (err < 0) return err; err = snd_hda_gen_parse_auto_config(codec, cfg); if (err < 0) return err; codec->patch_ops = ad198x_auto_patch_ops; return 0; }
static int ca0110_parse_auto_config(struct hda_codec *codec) { struct hda_gen_spec *spec = codec->spec; int err; err = snd_hda_parse_pin_defcfg(codec, &spec->autocfg, NULL, 0); if (err < 0) return err; err = snd_hda_gen_parse_auto_config(codec, &spec->autocfg); if (err < 0) return err; return 0; }
static int cs421x_parse_auto_config(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; hda_nid_t dac = CS4210_DAC_NID; int err; fix_volume_caps(codec, dac); err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); if (err < 0) return err; err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); if (err < 0) return err; parse_cs421x_digital(codec); return 0; }
static int patch_conexant_auto(struct hda_codec *codec) { struct conexant_spec *spec; int err; codec_info(codec, "%s: BIOS auto-probing.\n", codec->core.chip_name); spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (!spec) return -ENOMEM; snd_hda_gen_spec_init(&spec->gen); codec->spec = spec; codec->patch_ops = cx_auto_patch_ops; cx_auto_parse_beep(codec); cx_auto_parse_eapd(codec); spec->gen.own_eapd_ctl = 1; if (spec->dynamic_eapd) spec->gen.vmaster_mute.hook = cx_auto_vmaster_hook; switch (codec->core.vendor_id) { case 0x14f15045: codec->single_adc_amp = 1; spec->gen.mixer_nid = 0x17; spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO; snd_hda_pick_fixup(codec, cxt5045_fixup_models, cxt5045_fixups, cxt_fixups); break; case 0x14f15047: codec->pin_amp_workaround = 1; spec->gen.mixer_nid = 0x19; spec->gen.add_stereo_mix_input = HDA_HINT_STEREO_MIX_AUTO; snd_hda_pick_fixup(codec, cxt5047_fixup_models, cxt5047_fixups, cxt_fixups); break; case 0x14f15051: add_cx5051_fake_mutes(codec); codec->pin_amp_workaround = 1; snd_hda_pick_fixup(codec, cxt5051_fixup_models, cxt5051_fixups, cxt_fixups); break; default: codec->pin_amp_workaround = 1; snd_hda_pick_fixup(codec, cxt5066_fixup_models, cxt5066_fixups, cxt_fixups); break; } /* Show mute-led control only on HP laptops * This is a sort of white-list: on HP laptops, EAPD corresponds * only to the mute-LED without actualy amp function. Meanwhile, * others may use EAPD really as an amp switch, so it might be * not good to expose it blindly. */ switch (codec->core.subsystem_id >> 16) { case 0x103c: spec->gen.vmaster_mute_enum = 1; break; } snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, spec->parse_flags); if (err < 0) goto error; err = snd_hda_gen_parse_auto_config(codec, &spec->gen.autocfg); if (err < 0) goto error; /* Some laptops with Conexant chips show stalls in S3 resume, * which falls into the single-cmd mode. * Better to make reset, then. */ if (!codec->bus->core.sync_write) { codec_info(codec, "Enable sync_write for stable communication\n"); codec->bus->core.sync_write = 1; codec->bus->allow_bus_reset = 1; } snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); return 0; error: cx_auto_free(codec); return err; }