diff --git a/Documentation/sound/alsa/HD-Audio-Models.txt b/Documentation/sound/alsa/HD-Audio-Models.txt index 0caf77e59be4..d70c93bdcadf 100644 --- a/Documentation/sound/alsa/HD-Audio-Models.txt +++ b/Documentation/sound/alsa/HD-Audio-Models.txt @@ -94,7 +94,7 @@ ALC662/663/272 3stack-dig 3-stack (2-channel) with SPDIF 3stack-6ch 3-stack (6-channel) 3stack-6ch-dig 3-stack (6-channel) with SPDIF - 6stack-dig 6-stack with SPDIF + 5stack-dig 5-stack with SPDIF lenovo-101e Lenovo laptop eeepc-p701 ASUS Eeepc P701 eeepc-ep20 ASUS Eeepc EP20 diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 759ade12e758..8edd998509f7 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, } EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); +static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, + hda_nid_t *conn_list, int max_conns); +static bool add_conn_list(struct snd_array *array, hda_nid_t nid); +static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, + hda_nid_t *src, int len); + /** * snd_hda_get_connections - get connection list * @codec: the HDA codec @@ -320,7 +326,44 @@ EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes); * Returns the number of connections, or a negative error code. */ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, - hda_nid_t *conn_list, int max_conns) + hda_nid_t *conn_list, int max_conns) +{ + struct snd_array *array = &codec->conn_lists; + int i, len, old_used; + hda_nid_t list[HDA_MAX_CONNECTIONS]; + + /* look up the cached results */ + for (i = 0; i < array->used; ) { + hda_nid_t *p = snd_array_elem(array, i); + len = p[1]; + if (nid == *p) + return copy_conn_list(nid, conn_list, max_conns, + p + 2, len); + i += len + 2; + } + + len = _hda_get_connections(codec, nid, list, HDA_MAX_CONNECTIONS); + if (len < 0) + return len; + + /* add to the cache */ + old_used = array->used; + if (!add_conn_list(array, nid) || !add_conn_list(array, len)) + goto error_add; + for (i = 0; i < len; i++) + if (!add_conn_list(array, list[i])) + goto error_add; + + return copy_conn_list(nid, conn_list, max_conns, list, len); + + error_add: + array->used = old_used; + return -ENOMEM; +} +EXPORT_SYMBOL_HDA(snd_hda_get_connections); + +static int _hda_get_connections(struct hda_codec *codec, hda_nid_t nid, + hda_nid_t *conn_list, int max_conns) { unsigned int parm; int i, conn_len, conns; @@ -417,8 +460,28 @@ int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid, } return conns; } -EXPORT_SYMBOL_HDA(snd_hda_get_connections); +static bool add_conn_list(struct snd_array *array, hda_nid_t nid) +{ + hda_nid_t *p = snd_array_new(array); + if (!p) + return false; + *p = nid; + return true; +} + +static int copy_conn_list(hda_nid_t nid, hda_nid_t *dst, int max_dst, + hda_nid_t *src, int len) +{ + if (len > max_dst) { + snd_printk(KERN_ERR "hda_codec: " + "Too many connections %d for NID 0x%x\n", + len, nid); + return -EINVAL; + } + memcpy(dst, src, len * sizeof(hda_nid_t)); + return len; +} /** * snd_hda_queue_unsol_event - add an unsolicited event to queue @@ -1019,6 +1082,7 @@ static void snd_hda_codec_free(struct hda_codec *codec) list_del(&codec->list); snd_array_free(&codec->mixers); snd_array_free(&codec->nids); + snd_array_free(&codec->conn_lists); codec->bus->caddr_tbl[codec->addr] = NULL; if (codec->patch_ops.free) codec->patch_ops.free(codec); @@ -1079,6 +1143,7 @@ int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16); snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16); snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8); + snd_array_init(&codec->conn_lists, sizeof(hda_nid_t), 64); if (codec->bus->modelname) { codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL); if (!codec->modelname) { @@ -2556,7 +2621,7 @@ static unsigned int convert_to_spdif_status(unsigned short val) static void set_dig_out(struct hda_codec *codec, hda_nid_t nid, int verb, int val) { - hda_nid_t *d; + const hda_nid_t *d; snd_hda_codec_write_cache(codec, nid, 0, verb, val); d = codec->slave_dig_outs; @@ -3807,7 +3872,8 @@ EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config); * * Returns 0 if successful, or a negative error code. */ -int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew) +int snd_hda_add_new_ctls(struct hda_codec *codec, + const struct snd_kcontrol_new *knew) { int err; @@ -3950,7 +4016,7 @@ int snd_hda_check_amp_list_power(struct hda_codec *codec, struct hda_loopback_check *check, hda_nid_t nid) { - struct hda_amp_list *p; + const struct hda_amp_list *p; int ch, v; if (!check->amplist) @@ -4118,7 +4184,7 @@ static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid, -1); snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format); if (codec->slave_dig_outs) { - hda_nid_t *d; + const hda_nid_t *d; for (d = codec->slave_dig_outs; *d; d++) snd_hda_codec_setup_stream(codec, *d, stream_tag, 0, format); @@ -4133,7 +4199,7 @@ static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid) { snd_hda_codec_cleanup_stream(codec, nid); if (codec->slave_dig_outs) { - hda_nid_t *d; + const hda_nid_t *d; for (d = codec->slave_dig_outs; *d; d++) snd_hda_codec_cleanup_stream(codec, *d); } @@ -4280,7 +4346,7 @@ int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, unsigned int format, struct snd_pcm_substream *substream) { - hda_nid_t *nids = mout->dac_nids; + const hda_nid_t *nids = mout->dac_nids; int chs = substream->runtime->channels; int i; @@ -4335,7 +4401,7 @@ EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare); int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout) { - hda_nid_t *nids = mout->dac_nids; + const hda_nid_t *nids = mout->dac_nids; int i; for (i = 0; i < mout->num_dacs; i++) @@ -4360,7 +4426,7 @@ EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup); * Helper for automatic pin configuration */ -static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list) +static int is_in_nid_list(hda_nid_t nid, const hda_nid_t *list) { for (; *list; list++) if (*list == nid) @@ -4441,7 +4507,7 @@ static void sort_autocfg_input_pins(struct auto_pin_cfg *cfg) */ int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, - hda_nid_t *ignore_nids) + const hda_nid_t *ignore_nids) { hda_nid_t nid, end_nid; short seq, assoc_line_out, assoc_speaker; @@ -4632,10 +4698,13 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, /* * debug prints of the parsed results */ - snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", + snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x) type:%s\n", cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1], cfg->line_out_pins[2], cfg->line_out_pins[3], - cfg->line_out_pins[4]); + cfg->line_out_pins[4], + cfg->line_out_type == AUTO_PIN_HP_OUT ? "hp" : + (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT ? + "speaker" : "line")); snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n", cfg->speaker_outs, cfg->speaker_pins[0], cfg->speaker_pins[1], cfg->speaker_pins[2], @@ -4986,6 +5055,8 @@ static const char *get_jack_default_name(struct hda_codec *codec, hda_nid_t nid, return "Line-out"; case SND_JACK_HEADSET: return "Headset"; + case SND_JACK_VIDEOOUT: + return "HDMI/DP"; default: return "Misc"; } 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 { struct hda_cache_rec amp_cache; /* cache for amp access */ struct hda_cache_rec cmd_cache; /* cache for other commands */ + struct snd_array conn_lists; /* connection-list array */ + struct mutex spdif_mutex; struct mutex control_mutex; unsigned int spdif_status; /* IEC958 status bits */ unsigned short spdif_ctls; /* SPDIF control bits */ unsigned int spdif_in_enable; /* SPDIF input enable? */ - hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ + const hda_nid_t *slave_dig_outs; /* optional digital out slave widgets */ struct snd_array init_pins; /* initial (BIOS) pin configurations */ struct snd_array driver_pins; /* pin configs set by codec parser */ struct snd_array cvt_setups; /* audio convert setups */ diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 70a9d32f0e96..43a036716d25 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -126,6 +126,7 @@ MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," "{Intel, ICH10}," "{Intel, PCH}," "{Intel, CPT}," + "{Intel, PPT}," "{Intel, PBG}," "{Intel, SCH}," "{ATI, SB450}," @@ -1091,7 +1092,13 @@ static void azx_init_pci(struct azx *chip) ? "Failed" : "OK"); } break; - + default: + /* AMD Hudson needs the similar snoop, as it seems... */ + if (chip->pci->vendor == PCI_VENDOR_ID_AMD) + update_pci_byte(chip->pci, + ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, + 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); + break; } } @@ -1446,6 +1453,17 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) } } + /* AMD chipsets often cause the communication stalls upon certain + * sequence like the pin-detection. It seems that forcing the synced + * access works around the stall. Grrr... + */ + if (chip->pci->vendor == PCI_VENDOR_ID_AMD || + chip->pci->vendor == PCI_VENDOR_ID_ATI) { + snd_printk(KERN_INFO SFX "Enable sync_write for AMD chipset\n"); + chip->bus->sync_write = 1; + chip->bus->allow_bus_reset = 1; + } + /* Then create codec instances */ for (c = 0; c < max_slots; c++) { if ((chip->codec_mask & (1 << c)) & chip->codec_probe_mask) { @@ -2349,9 +2367,16 @@ static int __devinit check_position_fix(struct azx *chip, int fix) /* Check VIA/ATI HD Audio Controller exist */ switch (chip->driver_type) { case AZX_DRIVER_VIA: - case AZX_DRIVER_ATI: /* Use link position directly, avoid any transfer problem. */ return POS_FIX_VIACOMBO; + case AZX_DRIVER_ATI: + /* ATI chipsets don't work well with position-buffer */ + return POS_FIX_LPIB; + case AZX_DRIVER_GENERIC: + /* AMD chipsets also don't work with position-buffer */ + if (chip->pci->vendor == PCI_VENDOR_ID_AMD) + return POS_FIX_LPIB; + break; } return POS_FIX_AUTO; @@ -2549,6 +2574,13 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, gcap &= ~ICH6_GCAP_64OK; pci_dev_put(p_smbus); } + } else { + /* FIXME: not sure whether this is really needed, but + * Hudson isn't stable enough for allowing everything... + * let's check later again. + */ + if (chip->pci->vendor == PCI_VENDOR_ID_AMD) + gcap &= ~ICH6_GCAP_64OK; } /* disable 64bit DMA address for Teradici */ @@ -2759,6 +2791,8 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, /* PBG */ { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH }, + /* Panther Point */ + { PCI_DEVICE(0x8086, 0x1e20), .driver_data = AZX_DRIVER_PCH }, /* SCH */ { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, /* Generic Intel */ 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 */ struct hda_multi_out { int num_dacs; /* # of DACs, must be more than 1 */ - hda_nid_t *dac_nids; /* DAC list */ + const hda_nid_t *dac_nids; /* DAC list */ hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */ hda_nid_t dig_out_nid; /* digital out audio widget */ - hda_nid_t *slave_dig_outs; + const hda_nid_t *slave_dig_outs; int max_channels; /* currently supported analog channels */ int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ 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, int num_configs, const char * const *models, const struct snd_pci_quirk *tbl); int snd_hda_add_new_ctls(struct hda_codec *codec, - struct snd_kcontrol_new *knew); + const struct snd_kcontrol_new *knew); /* * unsolicited event handler @@ -443,7 +443,7 @@ struct auto_pin_cfg { int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, - hda_nid_t *ignore_nids); + const hda_nid_t *ignore_nids); /* amp values */ #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); u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); +static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) +{ + return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && + (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); +} + /* flags for hda_nid_item */ #define HDA_NID_ITEM_AMP (1<<0) @@ -567,7 +573,7 @@ struct hda_amp_list { }; struct hda_loopback_check { - struct hda_amp_list *amplist; + const struct hda_amp_list *amplist; int power_on; }; diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 2942d2a9ea10..f1b3875c57df 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c @@ -30,7 +30,7 @@ #include "hda_beep.h" struct ad198x_spec { - struct snd_kcontrol_new *mixers[6]; + const struct snd_kcontrol_new *mixers[6]; int num_mixers; unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ const struct hda_verb *init_verbs[6]; /* initialization verbs @@ -46,17 +46,17 @@ struct ad198x_spec { unsigned int cur_eapd; unsigned int need_dac_fix; - hda_nid_t *alt_dac_nid; - struct hda_pcm_stream *stream_analog_alt_playback; + const hda_nid_t *alt_dac_nid; + const struct hda_pcm_stream *stream_analog_alt_playback; /* capture */ unsigned int num_adc_nids; - hda_nid_t *adc_nids; + const hda_nid_t *adc_nids; hda_nid_t dig_in_nid; /* digital-in NID; optional */ /* capture source */ const struct hda_input_mux *input_mux; - hda_nid_t *capsrc_nids; + const hda_nid_t *capsrc_nids; unsigned int cur_mux[3]; /* channel model */ @@ -182,13 +182,13 @@ static void ad198x_free_kctls(struct hda_codec *codec); #ifdef CONFIG_SND_HDA_INPUT_BEEP /* additional beep mixers; the actual parameters are overwritten at build */ -static struct snd_kcontrol_new ad_beep_mixer[] = { +static const struct snd_kcontrol_new ad_beep_mixer[] = { HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), { } /* end */ }; -static struct snd_kcontrol_new ad_beep2_mixer[] = { +static const struct snd_kcontrol_new ad_beep2_mixer[] = { HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT), HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT), { } /* end */ @@ -231,7 +231,7 @@ static int ad198x_build_controls(struct hda_codec *codec) /* create beep controls if needed */ #ifdef CONFIG_SND_HDA_INPUT_BEEP if (spec->beep_amp) { - struct snd_kcontrol_new *knew; + const struct snd_kcontrol_new *knew; knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; for ( ; knew->name; knew++) { struct snd_kcontrol *kctl; @@ -331,7 +331,7 @@ static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); } -static struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { +static const struct hda_pcm_stream ad198x_pcm_analog_alt_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -403,7 +403,7 @@ static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, /* */ -static struct hda_pcm_stream ad198x_pcm_analog_playback = { +static const struct hda_pcm_stream ad198x_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 6, /* changed later */ @@ -415,7 +415,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_playback = { }, }; -static struct hda_pcm_stream ad198x_pcm_analog_capture = { +static const struct hda_pcm_stream ad198x_pcm_analog_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -426,7 +426,7 @@ static struct hda_pcm_stream ad198x_pcm_analog_capture = { }, }; -static struct hda_pcm_stream ad198x_pcm_digital_playback = { +static const struct hda_pcm_stream ad198x_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -439,7 +439,7 @@ static struct hda_pcm_stream ad198x_pcm_digital_playback = { }, }; -static struct hda_pcm_stream ad198x_pcm_digital_capture = { +static const struct hda_pcm_stream ad198x_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -489,11 +489,6 @@ static int ad198x_build_pcms(struct hda_codec *codec) return 0; } -static inline void ad198x_shutup(struct hda_codec *codec) -{ - snd_hda_shutup_pins(codec); -} - static void ad198x_free_kctls(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; @@ -547,6 +542,12 @@ static void ad198x_power_eapd(struct hda_codec *codec) } } +static void ad198x_shutup(struct hda_codec *codec) +{ + snd_hda_shutup_pins(codec); + ad198x_power_eapd(codec); +} + static void ad198x_free(struct hda_codec *codec) { struct ad198x_spec *spec = codec->spec; @@ -564,12 +565,11 @@ static void ad198x_free(struct hda_codec *codec) static int ad198x_suspend(struct hda_codec *codec, pm_message_t state) { ad198x_shutup(codec); - ad198x_power_eapd(codec); return 0; } #endif -static struct hda_codec_ops ad198x_patch_ops = { +static const struct hda_codec_ops ad198x_patch_ops = { .build_controls = ad198x_build_controls, .build_pcms = ad198x_build_pcms, .init = ad198x_init, @@ -639,13 +639,13 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, #define AD1986A_CLFE_DAC 0x05 #define AD1986A_ADC 0x06 -static hda_nid_t ad1986a_dac_nids[3] = { +static const hda_nid_t ad1986a_dac_nids[3] = { AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC }; -static hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; -static hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 }; +static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; +static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 }; -static struct hda_input_mux ad1986a_capture_source = { +static const struct hda_input_mux ad1986a_capture_source = { .num_items = 7, .items = { { "Mic", 0x0 }, @@ -659,7 +659,7 @@ static struct hda_input_mux ad1986a_capture_source = { }; -static struct hda_bind_ctls ad1986a_bind_pcm_vol = { +static const struct hda_bind_ctls ad1986a_bind_pcm_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), @@ -669,7 +669,7 @@ static struct hda_bind_ctls ad1986a_bind_pcm_vol = { }, }; -static struct hda_bind_ctls ad1986a_bind_pcm_sw = { +static const struct hda_bind_ctls ad1986a_bind_pcm_sw = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), @@ -682,7 +682,7 @@ static struct hda_bind_ctls ad1986a_bind_pcm_sw = { /* * mixers */ -static struct snd_kcontrol_new ad1986a_mixers[] = { +static const struct snd_kcontrol_new ad1986a_mixers[] = { /* * bind volumes/mutes of 3 DACs as a single PCM control for simplicity */ @@ -723,7 +723,7 @@ static struct snd_kcontrol_new ad1986a_mixers[] = { }; /* additional mixers for 3stack mode */ -static struct snd_kcontrol_new ad1986a_3st_mixers[] = { +static const struct snd_kcontrol_new ad1986a_3st_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", @@ -735,10 +735,10 @@ static struct snd_kcontrol_new ad1986a_3st_mixers[] = { }; /* laptop model - 2ch only */ -static hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; +static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; /* master controls both pins 0x1a and 0x1b */ -static struct hda_bind_ctls ad1986a_laptop_master_vol = { +static const struct hda_bind_ctls ad1986a_laptop_master_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), @@ -747,7 +747,7 @@ static struct hda_bind_ctls ad1986a_laptop_master_vol = { }, }; -static struct hda_bind_ctls ad1986a_laptop_master_sw = { +static const struct hda_bind_ctls ad1986a_laptop_master_sw = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), @@ -756,7 +756,7 @@ static struct hda_bind_ctls ad1986a_laptop_master_sw = { }, }; -static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { +static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = { HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), @@ -787,7 +787,7 @@ static struct snd_kcontrol_new ad1986a_laptop_mixers[] = { /* laptop-eapd model - 2ch only */ -static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { +static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, @@ -796,7 +796,7 @@ static struct hda_input_mux ad1986a_laptop_eapd_capture_source = { }, }; -static struct hda_input_mux ad1986a_automic_capture_source = { +static const struct hda_input_mux ad1986a_automic_capture_source = { .num_items = 2, .items = { { "Mic", 0x0 }, @@ -804,13 +804,13 @@ static struct hda_input_mux ad1986a_automic_capture_source = { }, }; -static struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = { +static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = { HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), { } /* end */ }; -static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { +static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), @@ -837,7 +837,7 @@ static struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { +static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), { } /* end */ @@ -931,7 +931,7 @@ static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { +static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -949,7 +949,7 @@ static struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { /* * initialization verbs */ -static struct hda_verb ad1986a_init_verbs[] = { +static const struct hda_verb ad1986a_init_verbs[] = { /* Front, Surround, CLFE DAC; mute as default */ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, @@ -1004,7 +1004,7 @@ static struct hda_verb ad1986a_init_verbs[] = { { } /* end */ }; -static struct hda_verb ad1986a_ch2_init[] = { +static const struct hda_verb ad1986a_ch2_init[] = { /* Surround out -> Line In */ { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* Line-in selectors */ @@ -1016,7 +1016,7 @@ static struct hda_verb ad1986a_ch2_init[] = { { } /* end */ }; -static struct hda_verb ad1986a_ch4_init[] = { +static const struct hda_verb ad1986a_ch4_init[] = { /* Surround out -> Surround */ { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, @@ -1026,7 +1026,7 @@ static struct hda_verb ad1986a_ch4_init[] = { { } /* end */ }; -static struct hda_verb ad1986a_ch6_init[] = { +static const struct hda_verb ad1986a_ch6_init[] = { /* Surround out -> Surround out */ { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, @@ -1036,19 +1036,19 @@ static struct hda_verb ad1986a_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode ad1986a_modes[3] = { +static const struct hda_channel_mode ad1986a_modes[3] = { { 2, ad1986a_ch2_init }, { 4, ad1986a_ch4_init }, { 6, ad1986a_ch6_init }, }; /* eapd initialization */ -static struct hda_verb ad1986a_eapd_init_verbs[] = { +static const struct hda_verb ad1986a_eapd_init_verbs[] = { {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, {} }; -static struct hda_verb ad1986a_automic_verbs[] = { +static const struct hda_verb ad1986a_automic_verbs[] = { {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/ @@ -1058,7 +1058,7 @@ static struct hda_verb ad1986a_automic_verbs[] = { }; /* Ultra initialization */ -static struct hda_verb ad1986a_ultra_init[] = { +static const struct hda_verb ad1986a_ultra_init[] = { /* eapd initialization */ { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* CLFE -> Mic in */ @@ -1069,7 +1069,7 @@ static struct hda_verb ad1986a_ultra_init[] = { }; /* pin sensing on HP jack */ -static struct hda_verb ad1986a_hp_init_verbs[] = { +static const struct hda_verb ad1986a_hp_init_verbs[] = { {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT}, {} }; @@ -1120,7 +1120,7 @@ static const char * const ad1986a_models[AD1986A_MODELS] = { [AD1986A_SAMSUNG_P50] = "samsung-p50", }; -static struct snd_pci_quirk ad1986a_cfg_tbl[] = { +static const struct snd_pci_quirk ad1986a_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD), SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD), @@ -1152,7 +1152,7 @@ static struct snd_pci_quirk ad1986a_cfg_tbl[] = { }; #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list ad1986a_loopbacks[] = { +static const struct hda_amp_list ad1986a_loopbacks[] = { { 0x13, HDA_OUTPUT, 0 }, /* Mic */ { 0x14, HDA_OUTPUT, 0 }, /* Phone */ { 0x15, HDA_OUTPUT, 0 }, /* CD */ @@ -1329,11 +1329,11 @@ static int patch_ad1986a(struct hda_codec *codec) #define AD1983_DAC 0x03 #define AD1983_ADC 0x04 -static hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; -static hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; -static hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; +static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; +static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; +static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; -static struct hda_input_mux ad1983_capture_source = { +static const struct hda_input_mux ad1983_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -1348,7 +1348,7 @@ static struct hda_input_mux ad1983_capture_source = { */ static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = { "PCM", "ADC" }; + static const char * const texts[] = { "PCM", "ADC" }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; uinfo->count = 1; @@ -1385,7 +1385,7 @@ static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_ return 0; } -static struct snd_kcontrol_new ad1983_mixers[] = { +static const struct snd_kcontrol_new ad1983_mixers[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), @@ -1418,7 +1418,7 @@ static struct snd_kcontrol_new ad1983_mixers[] = { { } /* end */ }; -static struct hda_verb ad1983_init_verbs[] = { +static const struct hda_verb ad1983_init_verbs[] = { /* Front, HP, Mono; mute as default */ {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, @@ -1458,7 +1458,7 @@ static struct hda_verb ad1983_init_verbs[] = { }; #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list ad1983_loopbacks[] = { +static const struct hda_amp_list ad1983_loopbacks[] = { { 0x12, HDA_OUTPUT, 0 }, /* Mic */ { 0x13, HDA_OUTPUT, 0 }, /* Line */ { } /* end */ @@ -1518,12 +1518,12 @@ static int patch_ad1983(struct hda_codec *codec) #define AD1981_DAC 0x03 #define AD1981_ADC 0x04 -static hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; -static hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; -static hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; +static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; +static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; +static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ -static struct hda_input_mux ad1981_capture_source = { +static const struct hda_input_mux ad1981_capture_source = { .num_items = 7, .items = { { "Front Mic", 0x0 }, @@ -1536,7 +1536,7 @@ static struct hda_input_mux ad1981_capture_source = { }, }; -static struct snd_kcontrol_new ad1981_mixers[] = { +static const struct snd_kcontrol_new ad1981_mixers[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), @@ -1577,7 +1577,7 @@ static struct snd_kcontrol_new ad1981_mixers[] = { { } /* end */ }; -static struct hda_verb ad1981_init_verbs[] = { +static const struct hda_verb ad1981_init_verbs[] = { /* Front, HP, Mono; mute as default */ {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, @@ -1625,7 +1625,7 @@ static struct hda_verb ad1981_init_verbs[] = { }; #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list ad1981_loopbacks[] = { +static const struct hda_amp_list ad1981_loopbacks[] = { { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */ { 0x13, HDA_OUTPUT, 0 }, /* Line */ { 0x1b, HDA_OUTPUT, 0 }, /* Aux */ @@ -1645,7 +1645,7 @@ static struct hda_amp_list ad1981_loopbacks[] = { #define AD1981_HP_EVENT 0x37 #define AD1981_MIC_EVENT 0x38 -static struct hda_verb ad1981_hp_init_verbs[] = { +static const struct hda_verb ad1981_hp_init_verbs[] = { {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */ /* pin sensing on HP and Mic jacks */ {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, } /* bind volumes of both NID 0x05 and 0x06 */ -static struct hda_bind_ctls ad1981_hp_bind_master_vol = { +static const struct hda_bind_ctls ad1981_hp_bind_master_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), @@ -1696,12 +1696,12 @@ static void ad1981_hp_automute(struct hda_codec *codec) /* toggle input of built-in and mic jack appropriately */ static void ad1981_hp_automic(struct hda_codec *codec) { - static struct hda_verb mic_jack_on[] = { + static const struct hda_verb mic_jack_on[] = { {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, {} }; - static struct hda_verb mic_jack_off[] = { + static const struct hda_verb mic_jack_off[] = { {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, {} @@ -1730,7 +1730,7 @@ static void ad1981_hp_unsol_event(struct hda_codec *codec, } } -static struct hda_input_mux ad1981_hp_capture_source = { +static const struct hda_input_mux ad1981_hp_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, @@ -1739,7 +1739,7 @@ static struct hda_input_mux ad1981_hp_capture_source = { }, }; -static struct snd_kcontrol_new ad1981_hp_mixers[] = { +static const struct snd_kcontrol_new ad1981_hp_mixers[] = { HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1790,7 +1790,7 @@ static int ad1981_hp_init(struct hda_codec *codec) } /* configuration for Toshiba Laptops */ -static struct hda_verb ad1981_toshiba_init_verbs[] = { +static const struct hda_verb ad1981_toshiba_init_verbs[] = { {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */ /* pin sensing on HP and Mic jacks */ {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, @@ -1798,14 +1798,14 @@ static struct hda_verb ad1981_toshiba_init_verbs[] = { {} }; -static struct snd_kcontrol_new ad1981_toshiba_mixers[] = { +static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = { HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT), { } }; /* configuration for Lenovo Thinkpad T60 */ -static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { +static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), @@ -1835,7 +1835,7 @@ static struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { { } /* end */ }; -static struct hda_input_mux ad1981_thinkpad_capture_source = { +static const struct hda_input_mux ad1981_thinkpad_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, @@ -1860,7 +1860,7 @@ static const char * const ad1981_models[AD1981_MODELS] = { [AD1981_TOSHIBA] = "toshiba" }; -static struct snd_pci_quirk ad1981_cfg_tbl[] = { +static const struct snd_pci_quirk ad1981_cfg_tbl[] = { SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), /* All HP models */ @@ -2075,32 +2075,32 @@ enum { * mixers */ -static hda_nid_t ad1988_6stack_dac_nids[4] = { +static const hda_nid_t ad1988_6stack_dac_nids[4] = { 0x04, 0x06, 0x05, 0x0a }; -static hda_nid_t ad1988_3stack_dac_nids[3] = { +static const hda_nid_t ad1988_3stack_dac_nids[3] = { 0x04, 0x05, 0x0a }; /* for AD1988A revision-2, DAC2-4 are swapped */ -static hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { +static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { 0x04, 0x05, 0x0a, 0x06 }; -static hda_nid_t ad1988_alt_dac_nid[1] = { +static const hda_nid_t ad1988_alt_dac_nid[1] = { 0x03 }; -static hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { +static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { 0x04, 0x0a, 0x06 }; -static hda_nid_t ad1988_adc_nids[3] = { +static const hda_nid_t ad1988_adc_nids[3] = { 0x08, 0x09, 0x0f }; -static hda_nid_t ad1988_capsrc_nids[3] = { +static const hda_nid_t ad1988_capsrc_nids[3] = { 0x0c, 0x0d, 0x0e }; @@ -2108,11 +2108,11 @@ static hda_nid_t ad1988_capsrc_nids[3] = { #define AD1988_SPDIF_OUT_HDMI 0x0b #define AD1988_SPDIF_IN 0x07 -static hda_nid_t ad1989b_slave_dig_outs[] = { +static const hda_nid_t ad1989b_slave_dig_outs[] = { AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 }; -static struct hda_input_mux ad1988_6stack_capture_source = { +static const struct hda_input_mux ad1988_6stack_capture_source = { .num_items = 5, .items = { { "Front Mic", 0x1 }, /* port-B */ @@ -2123,7 +2123,7 @@ static struct hda_input_mux ad1988_6stack_capture_source = { }, }; -static struct hda_input_mux ad1988_laptop_capture_source = { +static const struct hda_input_mux ad1988_laptop_capture_source = { .num_items = 3, .items = { { "Mic/Line", 0x1 }, /* port-B */ @@ -2166,7 +2166,7 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, } /* 6-stack mode */ -static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { +static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), @@ -2175,7 +2175,7 @@ static struct snd_kcontrol_new ad1988_6stack_mixers1[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { +static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT), 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[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { +static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = { HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), @@ -2211,14 +2211,14 @@ static struct snd_kcontrol_new ad1988_6stack_mixers2[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = { +static const struct snd_kcontrol_new ad1988_6stack_fp_mixers[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), { } /* end */ }; /* 3-stack mode */ -static struct snd_kcontrol_new ad1988_3stack_mixers1[] = { +static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), @@ -2226,7 +2226,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers1[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { +static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 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[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1988_3stack_mixers2[] = { +static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = { HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), @@ -2268,7 +2268,7 @@ static struct snd_kcontrol_new ad1988_3stack_mixers2[] = { }; /* laptop mode */ -static struct snd_kcontrol_new ad1988_laptop_mixers[] = { +static const struct snd_kcontrol_new ad1988_laptop_mixers[] = { HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), @@ -2299,7 +2299,7 @@ static struct snd_kcontrol_new ad1988_laptop_mixers[] = { }; /* capture */ -static struct snd_kcontrol_new ad1988_capture_mixers[] = { +static const struct snd_kcontrol_new ad1988_capture_mixers[] = { HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), @@ -2324,7 +2324,7 @@ static struct snd_kcontrol_new ad1988_capture_mixers[] = { static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = { + static const char * const texts[] = { "PCM", "ADC1", "ADC2", "ADC3" }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; @@ -2405,7 +2405,7 @@ static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { +static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -2418,12 +2418,12 @@ static struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { +static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT), { } /* end */ }; -static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { +static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT), { } /* end */ @@ -2436,7 +2436,7 @@ static struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { /* * for 6-stack (+dig) */ -static struct hda_verb ad1988_6stack_init_verbs[] = { +static const struct hda_verb ad1988_6stack_init_verbs[] = { /* Front, Surround, CLFE, side DAC; unmute as default */ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -2496,7 +2496,7 @@ static struct hda_verb ad1988_6stack_init_verbs[] = { { } }; -static struct hda_verb ad1988_6stack_fp_init_verbs[] = { +static const struct hda_verb ad1988_6stack_fp_init_verbs[] = { /* Headphone; unmute as default */ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Port-A front headphon path */ @@ -2509,7 +2509,7 @@ static struct hda_verb ad1988_6stack_fp_init_verbs[] = { { } }; -static struct hda_verb ad1988_capture_init_verbs[] = { +static const struct hda_verb ad1988_capture_init_verbs[] = { /* mute analog mix */ {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, @@ -2527,7 +2527,7 @@ static struct hda_verb ad1988_capture_init_verbs[] = { { } }; -static struct hda_verb ad1988_spdif_init_verbs[] = { +static const struct hda_verb ad1988_spdif_init_verbs[] = { /* SPDIF out sel */ {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ @@ -2539,14 +2539,14 @@ static struct hda_verb ad1988_spdif_init_verbs[] = { { } }; -static struct hda_verb ad1988_spdif_in_init_verbs[] = { +static const struct hda_verb ad1988_spdif_in_init_verbs[] = { /* unmute SPDIF input pin */ {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, { } }; /* AD1989 has no ADC -> SPDIF route */ -static struct hda_verb ad1989_spdif_init_verbs[] = { +static const struct hda_verb ad1989_spdif_init_verbs[] = { /* SPDIF-1 out pin */ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ @@ -2559,7 +2559,7 @@ static struct hda_verb ad1989_spdif_init_verbs[] = { /* * verbs for 3stack (+dig) */ -static struct hda_verb ad1988_3stack_ch2_init[] = { +static const struct hda_verb ad1988_3stack_ch2_init[] = { /* set port-C to line-in */ { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, @@ -2569,7 +2569,7 @@ static struct hda_verb ad1988_3stack_ch2_init[] = { { } /* end */ }; -static struct hda_verb ad1988_3stack_ch6_init[] = { +static const struct hda_verb ad1988_3stack_ch6_init[] = { /* set port-C to surround out */ { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -2579,12 +2579,12 @@ static struct hda_verb ad1988_3stack_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode ad1988_3stack_modes[2] = { +static const struct hda_channel_mode ad1988_3stack_modes[2] = { { 2, ad1988_3stack_ch2_init }, { 6, ad1988_3stack_ch6_init }, }; -static struct hda_verb ad1988_3stack_init_verbs[] = { +static const struct hda_verb ad1988_3stack_init_verbs[] = { /* Front, Surround, CLFE, side DAC; unmute as default */ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -2644,13 +2644,13 @@ static struct hda_verb ad1988_3stack_init_verbs[] = { /* * verbs for laptop mode (+dig) */ -static struct hda_verb ad1988_laptop_hp_on[] = { +static const struct hda_verb ad1988_laptop_hp_on[] = { /* unmute port-A and mute port-D */ { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, { } /* end */ }; -static struct hda_verb ad1988_laptop_hp_off[] = { +static const struct hda_verb ad1988_laptop_hp_off[] = { /* mute port-A and unmute port-D */ { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -2659,7 +2659,7 @@ static struct hda_verb ad1988_laptop_hp_off[] = { #define AD1988_HP_EVENT 0x01 -static struct hda_verb ad1988_laptop_init_verbs[] = { +static const struct hda_verb ad1988_laptop_init_verbs[] = { /* Front, Surround, CLFE, side DAC; unmute as default */ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {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) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list ad1988_loopbacks[] = { +static const struct hda_amp_list ad1988_loopbacks[] = { { 0x20, HDA_INPUT, 0 }, /* Front Mic */ { 0x20, HDA_INPUT, 1 }, /* Line */ { 0x20, HDA_INPUT, 4 }, /* Mic */ @@ -2741,7 +2741,7 @@ enum { AD_CTL_WIDGET_MUTE, AD_CTL_BIND_MUTE, }; -static struct snd_kcontrol_new ad1988_control_templates[] = { +static const struct snd_kcontrol_new ad1988_control_templates[] = { HDA_CODEC_VOLUME(NULL, 0, 0, 0), HDA_CODEC_MUTE(NULL, 0, 0, 0), HDA_BIND_MUTE(NULL, 0, 0, 0), @@ -2770,18 +2770,18 @@ static int add_control(struct ad198x_spec *spec, int type, const char *name, #define AD1988_PIN_CD_NID 0x18 #define AD1988_PIN_BEEP_NID 0x10 -static hda_nid_t ad1988_mixer_nids[8] = { +static const hda_nid_t ad1988_mixer_nids[8] = { /* A B C D E F G H */ 0x22, 0x2b, 0x2c, 0x29, 0x26, 0x2a, 0x27, 0x28 }; static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) { - static hda_nid_t idx_to_dac[8] = { + static const hda_nid_t idx_to_dac[8] = { /* A B C D E F G H */ 0x04, 0x06, 0x05, 0x04, 0x0a, 0x06, 0x05, 0x0a }; - static hda_nid_t idx_to_dac_rev2[8] = { + static const hda_nid_t idx_to_dac_rev2[8] = { /* A B C D E F G H */ 0x04, 0x05, 0x0a, 0x04, 0x06, 0x05, 0x0a, 0x06 }; @@ -2791,13 +2791,13 @@ static inline hda_nid_t ad1988_idx_to_dac(struct hda_codec *codec, int idx) return idx_to_dac[idx]; } -static hda_nid_t ad1988_boost_nids[8] = { +static const hda_nid_t ad1988_boost_nids[8] = { 0x38, 0x39, 0x3a, 0x3d, 0x3c, 0x3b, 0, 0 }; static int ad1988_pin_idx(hda_nid_t nid) { - static hda_nid_t ad1988_io_pins[8] = { + static const hda_nid_t ad1988_io_pins[8] = { 0x11, 0x14, 0x15, 0x12, 0x17, 0x16, 0x24, 0x25 }; int i; @@ -2809,7 +2809,7 @@ static int ad1988_pin_idx(hda_nid_t nid) static int ad1988_pin_to_loopback_idx(hda_nid_t nid) { - static int loopback_idx[8] = { + static const int loopback_idx[8] = { 2, 0, 1, 3, 4, 5, 1, 4 }; switch (nid) { @@ -2822,7 +2822,7 @@ static int ad1988_pin_to_loopback_idx(hda_nid_t nid) static int ad1988_pin_to_adc_idx(hda_nid_t nid) { - static int adc_idx[8] = { + static const int adc_idx[8] = { 0, 1, 2, 8, 4, 3, 6, 7 }; switch (nid) { @@ -2845,7 +2845,7 @@ static int ad1988_auto_fill_dac_nids(struct hda_codec *codec, /* check the pins hardwired to audio widget */ for (i = 0; i < cfg->line_outs; i++) { idx = ad1988_pin_idx(cfg->line_out_pins[i]); - spec->multiout.dac_nids[i] = ad1988_idx_to_dac(codec, idx); + spec->private_dac_nids[i] = ad1988_idx_to_dac(codec, idx); } spec->multiout.num_dacs = cfg->line_outs; return 0; @@ -3070,6 +3070,7 @@ static void ad1988_auto_init_analog_input(struct hda_codec *codec) for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; + int type = cfg->inputs[i].type; switch (nid) { case 0x15: /* port-C */ 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) break; } snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - i == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN); + type == AUTO_PIN_MIC ? PIN_VREF80 : PIN_IN); if (nid != AD1988_PIN_CD_NID) snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); @@ -3154,7 +3155,7 @@ static const char * const ad1988_models[AD1988_MODEL_LAST] = { [AD1988_AUTO] = "auto", }; -static struct snd_pci_quirk ad1988_cfg_tbl[] = { +static const struct snd_pci_quirk ad1988_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), @@ -3342,21 +3343,21 @@ static int patch_ad1988(struct hda_codec *codec) * but no build-up framework is given, so far. */ -static hda_nid_t ad1884_dac_nids[1] = { +static const hda_nid_t ad1884_dac_nids[1] = { 0x04, }; -static hda_nid_t ad1884_adc_nids[2] = { +static const hda_nid_t ad1884_adc_nids[2] = { 0x08, 0x09, }; -static hda_nid_t ad1884_capsrc_nids[2] = { +static const hda_nid_t ad1884_capsrc_nids[2] = { 0x0c, 0x0d, }; #define AD1884_SPDIF_OUT 0x02 -static struct hda_input_mux ad1884_capture_source = { +static const struct hda_input_mux ad1884_capture_source = { .num_items = 4, .items = { { "Front Mic", 0x0 }, @@ -3366,7 +3367,7 @@ static struct hda_input_mux ad1884_capture_source = { }, }; -static struct snd_kcontrol_new ad1884_base_mixers[] = { +static const struct snd_kcontrol_new ad1884_base_mixers[] = { HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), @@ -3410,7 +3411,7 @@ static struct snd_kcontrol_new ad1884_base_mixers[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1984_dmic_mixers[] = { +static const struct snd_kcontrol_new ad1984_dmic_mixers[] = { HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0, @@ -3423,7 +3424,7 @@ static struct snd_kcontrol_new ad1984_dmic_mixers[] = { /* * initialization verbs */ -static struct hda_verb ad1884_init_verbs[] = { +static const struct hda_verb ad1884_init_verbs[] = { /* DACs; mute as default */ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, @@ -3469,7 +3470,7 @@ static struct hda_verb ad1884_init_verbs[] = { }; #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list ad1884_loopbacks[] = { +static const struct hda_amp_list ad1884_loopbacks[] = { { 0x20, HDA_INPUT, 0 }, /* Front Mic */ { 0x20, HDA_INPUT, 1 }, /* Mic */ { 0x20, HDA_INPUT, 2 }, /* CD */ @@ -3541,7 +3542,7 @@ static int patch_ad1884(struct hda_codec *codec) /* * Lenovo Thinkpad T61/X61 */ -static struct hda_input_mux ad1984_thinkpad_capture_source = { +static const struct hda_input_mux ad1984_thinkpad_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -3555,7 +3556,7 @@ static struct hda_input_mux ad1984_thinkpad_capture_source = { /* * Dell Precision T3400 */ -static struct hda_input_mux ad1984_dell_desktop_capture_source = { +static const struct hda_input_mux ad1984_dell_desktop_capture_source = { .num_items = 3, .items = { { "Front Mic", 0x0 }, @@ -3565,7 +3566,7 @@ static struct hda_input_mux ad1984_dell_desktop_capture_source = { }; -static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { +static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), @@ -3611,7 +3612,7 @@ static struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { }; /* additional verbs */ -static struct hda_verb ad1984_thinkpad_init_verbs[] = { +static const struct hda_verb ad1984_thinkpad_init_verbs[] = { /* Port-E (docking station mic) pin */ {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, @@ -3629,7 +3630,7 @@ static struct hda_verb ad1984_thinkpad_init_verbs[] = { /* * Dell Precision T3400 */ -static struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = { +static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = { HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), @@ -3680,7 +3681,7 @@ static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo, return 0; } -static struct hda_pcm_stream ad1984_pcm_dmic_capture = { +static const struct hda_pcm_stream ad1984_pcm_dmic_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -3722,7 +3723,7 @@ static const char * const ad1984_models[AD1984_MODELS] = { [AD1984_DELL_DESKTOP] = "dell_desktop", }; -static struct snd_pci_quirk ad1984_cfg_tbl[] = { +static const struct snd_pci_quirk ad1984_cfg_tbl[] = { /* Lenovo Thinkpad T61/X61 */ SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), @@ -3787,7 +3788,7 @@ static int patch_ad1984(struct hda_codec *codec) * We share the single DAC for both HP and line-outs (see AD1884/1984). */ -static hda_nid_t ad1884a_dac_nids[1] = { +static const hda_nid_t ad1884a_dac_nids[1] = { 0x03, }; @@ -3796,7 +3797,7 @@ static hda_nid_t ad1884a_dac_nids[1] = { #define AD1884A_SPDIF_OUT 0x02 -static struct hda_input_mux ad1884a_capture_source = { +static const struct hda_input_mux ad1884a_capture_source = { .num_items = 5, .items = { { "Front Mic", 0x0 }, @@ -3807,7 +3808,7 @@ static struct hda_input_mux ad1884a_capture_source = { }, }; -static struct snd_kcontrol_new ad1884a_base_mixers[] = { +static const struct snd_kcontrol_new ad1884a_base_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), @@ -3859,7 +3860,7 @@ static struct snd_kcontrol_new ad1884a_base_mixers[] = { /* * initialization verbs */ -static struct hda_verb ad1884a_init_verbs[] = { +static const struct hda_verb ad1884a_init_verbs[] = { /* DACs; unmute as default */ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ @@ -3914,7 +3915,7 @@ static struct hda_verb ad1884a_init_verbs[] = { }; #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list ad1884a_loopbacks[] = { +static const struct hda_amp_list ad1884a_loopbacks[] = { { 0x20, HDA_INPUT, 0 }, /* Front Mic */ { 0x20, HDA_INPUT, 1 }, /* Mic */ { 0x20, HDA_INPUT, 2 }, /* CD */ @@ -3947,7 +3948,7 @@ static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol, return ret; } -static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { +static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -3975,7 +3976,7 @@ static struct snd_kcontrol_new ad1884a_laptop_mixers[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1884a_mobile_mixers[] = { +static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ { @@ -4095,7 +4096,7 @@ static int ad1884a_laptop_init(struct hda_codec *codec) } /* additional verbs for laptop model */ -static struct hda_verb ad1884a_laptop_verbs[] = { +static const struct hda_verb ad1884a_laptop_verbs[] = { /* Port-A (HP) pin - always unmuted */ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Port-F (int speaker) mixer - route only from analog mixer */ @@ -4126,7 +4127,7 @@ static struct hda_verb ad1884a_laptop_verbs[] = { { } /* end */ }; -static struct hda_verb ad1884a_mobile_verbs[] = { +static const struct hda_verb ad1884a_mobile_verbs[] = { /* DACs; unmute as default */ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ @@ -4181,7 +4182,7 @@ static struct hda_verb ad1884a_mobile_verbs[] = { * 0x17 - built-in mic */ -static struct hda_verb ad1984a_thinkpad_verbs[] = { +static const struct hda_verb ad1984a_thinkpad_verbs[] = { /* HP unmute */ {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* analog mix */ @@ -4198,7 +4199,7 @@ static struct hda_verb ad1984a_thinkpad_verbs[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { +static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), @@ -4219,7 +4220,7 @@ static struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { { } /* end */ }; -static struct hda_input_mux ad1984a_thinkpad_capture_source = { +static const struct hda_input_mux ad1984a_thinkpad_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, @@ -4262,7 +4263,7 @@ static int ad1984a_thinkpad_init(struct hda_codec *codec) * 0x15 - mic-in */ -static struct hda_verb ad1984a_precision_verbs[] = { +static const struct hda_verb ad1984a_precision_verbs[] = { /* Unmute main output path */ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ @@ -4288,7 +4289,7 @@ static struct hda_verb ad1984a_precision_verbs[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1984a_precision_mixers[] = { +static const struct snd_kcontrol_new ad1984a_precision_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), @@ -4344,7 +4345,7 @@ static int ad1984a_precision_init(struct hda_codec *codec) * digital-mic (0x17) - Internal mic */ -static struct hda_verb ad1984a_touchsmart_verbs[] = { +static const struct hda_verb ad1984a_touchsmart_verbs[] = { /* DACs; unmute as default */ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ @@ -4396,7 +4397,7 @@ static struct hda_verb ad1984a_touchsmart_verbs[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { +static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), /* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ { @@ -4475,7 +4476,7 @@ static const char * const ad1884a_models[AD1884A_MODELS] = { [AD1984A_PRECISION] = "precision", }; -static struct snd_pci_quirk ad1884a_cfg_tbl[] = { +static const struct snd_pci_quirk ad1884a_cfg_tbl[] = { SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), @@ -4614,22 +4615,22 @@ static int patch_ad1884a(struct hda_codec *codec) * port-G - rear clfe-out (6stack) */ -static hda_nid_t ad1882_dac_nids[3] = { +static const hda_nid_t ad1882_dac_nids[3] = { 0x04, 0x03, 0x05 }; -static hda_nid_t ad1882_adc_nids[2] = { +static const hda_nid_t ad1882_adc_nids[2] = { 0x08, 0x09, }; -static hda_nid_t ad1882_capsrc_nids[2] = { +static const hda_nid_t ad1882_capsrc_nids[2] = { 0x0c, 0x0d, }; #define AD1882_SPDIF_OUT 0x02 /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ -static struct hda_input_mux ad1882_capture_source = { +static const struct hda_input_mux ad1882_capture_source = { .num_items = 5, .items = { { "Front Mic", 0x1 }, @@ -4641,7 +4642,7 @@ static struct hda_input_mux ad1882_capture_source = { }; /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */ -static struct hda_input_mux ad1882a_capture_source = { +static const struct hda_input_mux ad1882a_capture_source = { .num_items = 5, .items = { { "Front Mic", 0x1 }, @@ -4652,7 +4653,7 @@ static struct hda_input_mux ad1882a_capture_source = { }, }; -static struct snd_kcontrol_new ad1882_base_mixers[] = { +static const struct snd_kcontrol_new ad1882_base_mixers[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), @@ -4694,7 +4695,7 @@ static struct snd_kcontrol_new ad1882_base_mixers[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1882_loopback_mixers[] = { +static const struct snd_kcontrol_new ad1882_loopback_mixers[] = { HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), @@ -4706,7 +4707,7 @@ static struct snd_kcontrol_new ad1882_loopback_mixers[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { +static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = { HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), @@ -4719,7 +4720,7 @@ static struct snd_kcontrol_new ad1882a_loopback_mixers[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1882_3stack_mixers[] = { +static const struct snd_kcontrol_new ad1882_3stack_mixers[] = { HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), @@ -4733,14 +4734,14 @@ static struct snd_kcontrol_new ad1882_3stack_mixers[] = { { } /* end */ }; -static struct snd_kcontrol_new ad1882_6stack_mixers[] = { +static const struct snd_kcontrol_new ad1882_6stack_mixers[] = { HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), { } /* end */ }; -static struct hda_verb ad1882_ch2_init[] = { +static const struct hda_verb ad1882_ch2_init[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, @@ -4750,7 +4751,7 @@ static struct hda_verb ad1882_ch2_init[] = { { } /* end */ }; -static struct hda_verb ad1882_ch4_init[] = { +static const struct hda_verb ad1882_ch4_init[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -4760,7 +4761,7 @@ static struct hda_verb ad1882_ch4_init[] = { { } /* end */ }; -static struct hda_verb ad1882_ch6_init[] = { +static const struct hda_verb ad1882_ch6_init[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -4770,7 +4771,7 @@ static struct hda_verb ad1882_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode ad1882_modes[3] = { +static const struct hda_channel_mode ad1882_modes[3] = { { 2, ad1882_ch2_init }, { 4, ad1882_ch4_init }, { 6, ad1882_ch6_init }, @@ -4779,7 +4780,7 @@ static struct hda_channel_mode ad1882_modes[3] = { /* * initialization verbs */ -static struct hda_verb ad1882_init_verbs[] = { +static const struct hda_verb ad1882_init_verbs[] = { /* DACs; mute as default */ {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, @@ -4848,7 +4849,7 @@ static struct hda_verb ad1882_init_verbs[] = { }; #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list ad1882_loopbacks[] = { +static const struct hda_amp_list ad1882_loopbacks[] = { { 0x20, HDA_INPUT, 0 }, /* Front Mic */ { 0x20, HDA_INPUT, 1 }, /* Mic */ { 0x20, HDA_INPUT, 4 }, /* Line */ @@ -4945,7 +4946,7 @@ static int patch_ad1882(struct hda_codec *codec) /* * patch entries */ -static struct hda_codec_preset snd_hda_preset_analog[] = { +static const struct hda_codec_preset snd_hda_preset_analog[] = { { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, { .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, /* */ -static char *dirstr[2] = { "Playback", "Capture" }; +static const char * const dirstr[2] = { "Playback", "Capture" }; static int _add_switch(struct hda_codec *codec, hda_nid_t nid, const char *pfx, int chan, int dir) @@ -171,7 +171,7 @@ static int ca0110_build_controls(struct hda_codec *codec) { struct ca0110_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; - static char *prefix[AUTO_CFG_MAX_OUTS] = { + static const char * const prefix[AUTO_CFG_MAX_OUTS] = { "Front", "Surround", NULL, "Side", "Multi" }; hda_nid_t mutenid; @@ -259,7 +259,7 @@ static int ca0110_build_controls(struct hda_codec *codec) /* */ -static struct hda_pcm_stream ca0110_pcm_analog_playback = { +static const struct hda_pcm_stream ca0110_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 8, @@ -270,7 +270,7 @@ static struct hda_pcm_stream ca0110_pcm_analog_playback = { }, }; -static struct hda_pcm_stream ca0110_pcm_analog_capture = { +static const struct hda_pcm_stream ca0110_pcm_analog_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -280,7 +280,7 @@ static struct hda_pcm_stream ca0110_pcm_analog_capture = { }, }; -static struct hda_pcm_stream ca0110_pcm_digital_playback = { +static const struct hda_pcm_stream ca0110_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -291,7 +291,7 @@ static struct hda_pcm_stream ca0110_pcm_digital_playback = { }, }; -static struct hda_pcm_stream ca0110_pcm_digital_capture = { +static const struct hda_pcm_stream ca0110_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -389,7 +389,7 @@ static void ca0110_free(struct hda_codec *codec) kfree(codec->spec); } -static struct hda_codec_ops ca0110_patch_ops = { +static const struct hda_codec_ops ca0110_patch_ops = { .build_controls = ca0110_build_controls, .build_pcms = ca0110_build_pcms, .init = ca0110_init, @@ -539,7 +539,7 @@ static int patch_ca0110(struct hda_codec *codec) /* * patch entries */ -static struct hda_codec_preset snd_hda_preset_ca0110[] = { +static const struct hda_codec_preset snd_hda_preset_ca0110[] = { { .id = 0x1102000a, .name = "CA0110-IBG", .patch = patch_ca0110 }, { .id = 0x1102000b, .name = "CA0110-IBG", .patch = patch_ca0110 }, { .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 { unsigned int cur_adc_format; hda_nid_t dig_in; - struct hda_bind_ctls *capture_bind[2]; + const struct hda_bind_ctls *capture_bind[2]; unsigned int gpio_mask; unsigned int gpio_dir; @@ -231,7 +231,7 @@ static int cs_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, /* */ -static struct hda_pcm_stream cs_pcm_analog_playback = { +static const struct hda_pcm_stream cs_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -242,7 +242,7 @@ static struct hda_pcm_stream cs_pcm_analog_playback = { }, }; -static struct hda_pcm_stream cs_pcm_analog_capture = { +static const struct hda_pcm_stream cs_pcm_analog_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -252,7 +252,7 @@ static struct hda_pcm_stream cs_pcm_analog_capture = { }, }; -static struct hda_pcm_stream cs_pcm_digital_playback = { +static const struct hda_pcm_stream cs_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -264,7 +264,7 @@ static struct hda_pcm_stream cs_pcm_digital_playback = { }, }; -static struct hda_pcm_stream cs_pcm_digital_capture = { +static const struct hda_pcm_stream cs_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -331,8 +331,8 @@ static int is_ext_mic(struct hda_codec *codec, unsigned int idx) struct cs_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; hda_nid_t pin = cfg->inputs[idx].pin; - unsigned int val = snd_hda_query_pin_caps(codec, pin); - if (!(val & AC_PINCAP_PRES_DETECT)) + unsigned int val; + if (!is_jack_detectable(codec, pin)) return 0; val = snd_hda_codec_get_pincfg(codec, pin); 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, hda_nid_t pins[2]; unsigned int type; int j, nums; - type = (get_wcaps(codec, nid) & AC_WCAP_TYPE) - >> AC_WCAP_TYPE_SHIFT; + type = get_wcaps_type(get_wcaps(codec, nid)); if (type != AC_WID_AUD_IN) continue; 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, const char *name; int err, index; struct snd_kcontrol *kctl; - static char *speakers[] = { + static const char * const speakers[] = { "Front Speaker", "Surround Speaker", "Bass Speaker" }; - static char *line_outs[] = { + static const char * const line_outs[] = { "Front Line-Out", "Surround Line-Out", "Bass Line-Out" }; @@ -642,7 +641,7 @@ static int build_output(struct hda_codec *codec) /* */ -static struct snd_kcontrol_new cs_capture_ctls[] = { +static const struct snd_kcontrol_new cs_capture_ctls[] = { HDA_BIND_SW("Capture Switch", 0), HDA_BIND_VOL("Capture Volume", 0), }; @@ -710,7 +709,7 @@ static int cs_capture_source_put(struct snd_kcontrol *kcontrol, return change_cur_input(codec, idx, 0); } -static struct snd_kcontrol_new cs_capture_source = { +static const struct snd_kcontrol_new cs_capture_source = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, @@ -719,7 +718,7 @@ static struct snd_kcontrol_new cs_capture_source = { .put = cs_capture_source_put, }; -static struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec, +static const struct hda_bind_ctls *make_bind_capture(struct hda_codec *codec, struct hda_ctl_ops *ops) { struct cs_spec *spec = codec->spec; @@ -847,15 +846,14 @@ static void cs_automute(struct hda_codec *codec) { struct cs_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; - unsigned int caps, hp_present; + unsigned int hp_present; hda_nid_t nid; int i; hp_present = 0; for (i = 0; i < cfg->hp_outs; i++) { nid = cfg->hp_pins[i]; - caps = snd_hda_query_pin_caps(codec, nid); - if (!(caps & AC_PINCAP_PRES_DETECT)) + if (!is_jack_detectable(codec, nid)) continue; hp_present = snd_hda_jack_detect(codec, nid); if (hp_present) @@ -924,7 +922,7 @@ static void init_output(struct hda_codec *codec) AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); if (!cfg->speaker_outs) continue; - if (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP) { + if (is_jack_detectable(codec, nid)) { snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | HP_EVENT); @@ -983,7 +981,7 @@ static void init_input(struct hda_codec *codec) cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); } -static struct hda_verb cs_coef_init_verbs[] = { +static const struct hda_verb cs_coef_init_verbs[] = { {0x11, AC_VERB_SET_PROC_STATE, 1}, {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, {0x11, AC_VERB_SET_PROC_COEF, @@ -1017,7 +1015,7 @@ static struct hda_verb cs_coef_init_verbs[] = { * blocks, which will alleviate the issue. */ -static struct hda_verb cs_errata_init_verbs[] = { +static const struct hda_verb cs_errata_init_verbs[] = { {0x01, AC_VERB_SET_POWER_STATE, 0x00}, /* AFG: D0 */ {0x11, AC_VERB_SET_PROC_STATE, 0x01}, /* VPW: processing on */ @@ -1126,7 +1124,7 @@ static void cs_unsol_event(struct hda_codec *codec, unsigned int res) } } -static struct hda_codec_ops cs_patch_ops = { +static const struct hda_codec_ops cs_patch_ops = { .build_controls = cs_build_controls, .build_pcms = cs_build_pcms, .init = cs_init, @@ -1166,7 +1164,7 @@ static const char * const cs420x_models[CS420X_MODELS] = { }; -static struct snd_pci_quirk cs420x_cfg_tbl[] = { +static const struct snd_pci_quirk cs420x_cfg_tbl[] = { SND_PCI_QUIRK(0x10de, 0x0ac0, "MacBookPro 5,3", CS420X_MBP53), SND_PCI_QUIRK(0x10de, 0x0d94, "MacBookAir 3,1(2)", CS420X_MBP55), SND_PCI_QUIRK(0x10de, 0xcb79, "MacBookPro 5,5", CS420X_MBP55), @@ -1180,7 +1178,7 @@ struct cs_pincfg { u32 val; }; -static struct cs_pincfg mbp53_pincfgs[] = { +static const struct cs_pincfg mbp53_pincfgs[] = { { 0x09, 0x012b4050 }, { 0x0a, 0x90100141 }, { 0x0b, 0x90100140 }, @@ -1194,7 +1192,7 @@ static struct cs_pincfg mbp53_pincfgs[] = { {} /* terminator */ }; -static struct cs_pincfg mbp55_pincfgs[] = { +static const struct cs_pincfg mbp55_pincfgs[] = { { 0x09, 0x012b4030 }, { 0x0a, 0x90100121 }, { 0x0b, 0x90100120 }, @@ -1208,7 +1206,7 @@ static struct cs_pincfg mbp55_pincfgs[] = { {} /* terminator */ }; -static struct cs_pincfg imac27_pincfgs[] = { +static const struct cs_pincfg imac27_pincfgs[] = { { 0x09, 0x012b4050 }, { 0x0a, 0x90100140 }, { 0x0b, 0x90100142 }, @@ -1222,7 +1220,7 @@ static struct cs_pincfg imac27_pincfgs[] = { {} /* terminator */ }; -static struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = { +static const struct cs_pincfg *cs_pincfgs[CS420X_MODELS] = { [CS420X_MBP53] = mbp53_pincfgs, [CS420X_MBP55] = mbp55_pincfgs, [CS420X_IMAC27] = imac27_pincfgs, @@ -1283,7 +1281,7 @@ static int patch_cs420x(struct hda_codec *codec) /* * patch entries */ -static struct hda_codec_preset snd_hda_preset_cirrus[] = { +static const struct hda_codec_preset snd_hda_preset_cirrus[] = { { .id = 0x10134206, .name = "CS4206", .patch = patch_cs420x }, { .id = 0x10134207, .name = "CS4207", .patch = patch_cs420x }, {} /* 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 { int num_dacs; /* capture */ - hda_nid_t *adc_nids; + const hda_nid_t *adc_nids; hda_nid_t dig_in_nid; /* capture source */ @@ -110,7 +110,7 @@ static int cmi_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_v */ /* 3-stack / 2 channel */ -static struct hda_verb cmi9880_ch2_init[] = { +static const struct hda_verb cmi9880_ch2_init[] = { /* set line-in PIN for input */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, /* set mic PIN for input, also enable vref */ @@ -121,7 +121,7 @@ static struct hda_verb cmi9880_ch2_init[] = { }; /* 3-stack / 6 channel */ -static struct hda_verb cmi9880_ch6_init[] = { +static const struct hda_verb cmi9880_ch6_init[] = { /* set line-in PIN for output */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* set mic PIN for output */ @@ -132,7 +132,7 @@ static struct hda_verb cmi9880_ch6_init[] = { }; /* 3-stack+front / 8 channel */ -static struct hda_verb cmi9880_ch8_init[] = { +static const struct hda_verb cmi9880_ch8_init[] = { /* set line-in PIN for output */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* set mic PIN for output */ @@ -142,7 +142,7 @@ static struct hda_verb cmi9880_ch8_init[] = { {} }; -static struct hda_channel_mode cmi9880_channel_modes[3] = { +static const struct hda_channel_mode cmi9880_channel_modes[3] = { { 2, cmi9880_ch2_init }, { 6, cmi9880_ch6_init }, { 8, cmi9880_ch8_init }, @@ -174,7 +174,7 @@ static int cmi_ch_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_va /* */ -static struct snd_kcontrol_new cmi9880_basic_mixer[] = { +static const struct snd_kcontrol_new cmi9880_basic_mixer[] = { /* CMI9880 has no playback volumes! */ HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), /* front */ HDA_CODEC_MUTE("Surround Playback Switch", 0x04, 0x0, HDA_OUTPUT), @@ -205,7 +205,7 @@ static struct snd_kcontrol_new cmi9880_basic_mixer[] = { /* * shared I/O pins */ -static struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = { +static const struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", @@ -219,7 +219,7 @@ static struct snd_kcontrol_new cmi9880_ch_mode_mixer[] = { /* AUD-in selections: * 0x0b 0x0c 0x0d 0x0e 0x0f 0x10 0x11 0x1f 0x20 */ -static struct hda_input_mux cmi9880_basic_mux = { +static const struct hda_input_mux cmi9880_basic_mux = { .num_items = 4, .items = { { "Front Mic", 0x5 }, @@ -229,7 +229,7 @@ static struct hda_input_mux cmi9880_basic_mux = { } }; -static struct hda_input_mux cmi9880_no_line_mux = { +static const struct hda_input_mux cmi9880_no_line_mux = { .num_items = 3, .items = { { "Front Mic", 0x5 }, @@ -239,11 +239,11 @@ static struct hda_input_mux cmi9880_no_line_mux = { }; /* front, rear, clfe, rear_surr */ -static hda_nid_t cmi9880_dac_nids[4] = { +static const hda_nid_t cmi9880_dac_nids[4] = { 0x03, 0x04, 0x05, 0x06 }; /* ADC0, ADC1 */ -static hda_nid_t cmi9880_adc_nids[2] = { +static const hda_nid_t cmi9880_adc_nids[2] = { 0x08, 0x09 }; @@ -252,7 +252,7 @@ static hda_nid_t cmi9880_adc_nids[2] = { /* */ -static struct hda_verb cmi9880_basic_init[] = { +static const struct hda_verb cmi9880_basic_init[] = { /* port-D for line out (rear panel) */ { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* port-E for HP out (front panel) */ @@ -281,7 +281,7 @@ static struct hda_verb cmi9880_basic_init[] = { {} /* terminator */ }; -static struct hda_verb cmi9880_allout_init[] = { +static const struct hda_verb cmi9880_allout_init[] = { /* port-D for line out (rear panel) */ { 0x0b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, /* port-E for HP out (front panel) */ @@ -528,7 +528,7 @@ static int cmi9880_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, /* */ -static struct hda_pcm_stream cmi9880_pcm_analog_playback = { +static const struct hda_pcm_stream cmi9880_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 8, @@ -540,7 +540,7 @@ static struct hda_pcm_stream cmi9880_pcm_analog_playback = { }, }; -static struct hda_pcm_stream cmi9880_pcm_analog_capture = { +static const struct hda_pcm_stream cmi9880_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -551,7 +551,7 @@ static struct hda_pcm_stream cmi9880_pcm_analog_capture = { }, }; -static struct hda_pcm_stream cmi9880_pcm_digital_playback = { +static const struct hda_pcm_stream cmi9880_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -563,7 +563,7 @@ static struct hda_pcm_stream cmi9880_pcm_digital_playback = { }, }; -static struct hda_pcm_stream cmi9880_pcm_digital_capture = { +static const struct hda_pcm_stream cmi9880_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -617,14 +617,14 @@ static const char * const cmi9880_models[CMI_MODELS] = { [CMI_AUTO] = "auto", }; -static struct snd_pci_quirk cmi9880_cfg_tbl[] = { +static const struct snd_pci_quirk cmi9880_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x813d, "ASUS P5AD2", CMI_FULL_DIG), SND_PCI_QUIRK(0x1854, 0x002b, "LG LS75", CMI_MINIMAL), SND_PCI_QUIRK(0x1854, 0x0032, "LG", CMI_FULL_DIG), {} /* terminator */ }; -static struct hda_codec_ops cmi9880_patch_ops = { +static const struct hda_codec_ops cmi9880_patch_ops = { .build_controls = cmi9880_build_controls, .build_pcms = cmi9880_build_pcms, .init = cmi9880_init, @@ -745,7 +745,7 @@ static int patch_cmi9880(struct hda_codec *codec) /* * patch entries */ -static struct hda_codec_preset snd_hda_preset_cmedia[] = { +static const struct hda_codec_preset snd_hda_preset_cmedia[] = { { .id = 0x13f69880, .name = "CMI9880", .patch = patch_cmi9880 }, { .id = 0x434d4980, .name = "CMI9880", .patch = patch_cmi9880 }, {} /* terminator */ diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c index ad97d937d3a8..4f37477d3c71 100644 --- a/sound/pci/hda/patch_conexant.c +++ b/sound/pci/hda/patch_conexant.c @@ -39,6 +39,7 @@ #define CONEXANT_HP_EVENT 0x37 #define CONEXANT_MIC_EVENT 0x38 +#define CONEXANT_LINE_EVENT 0x39 /* Conexant 5051 specific */ @@ -55,9 +56,16 @@ struct pin_dac_pair { int type; }; +struct imux_info { + hda_nid_t pin; /* input pin NID */ + hda_nid_t adc; /* connected ADC NID */ + hda_nid_t boost; /* optional boost volume NID */ + int index; /* corresponding to autocfg.input */ +}; + struct conexant_spec { - struct snd_kcontrol_new *mixers[5]; + const struct snd_kcontrol_new *mixers[5]; int num_mixers; hda_nid_t vmaster_nid; @@ -74,14 +82,17 @@ struct conexant_spec { */ unsigned int cur_eapd; unsigned int hp_present; + unsigned int line_present; unsigned int auto_mic; - int auto_mic_ext; /* autocfg.inputs[] index for ext mic */ + int auto_mic_ext; /* imux_pins[] index for ext mic */ + int auto_mic_dock; /* imux_pins[] index for dock mic */ + int auto_mic_int; /* imux_pins[] index for int mic */ unsigned int need_dac_fix; hda_nid_t slave_dig_outs[2]; /* capture */ unsigned int num_adc_nids; - hda_nid_t *adc_nids; + const hda_nid_t *adc_nids; hda_nid_t dig_in_nid; /* digital-in NID; optional */ unsigned int cur_adc_idx; @@ -89,9 +100,11 @@ struct conexant_spec { unsigned int cur_adc_stream_tag; unsigned int cur_adc_format; + const struct hda_pcm_stream *capture_stream; + /* capture source */ const struct hda_input_mux *input_mux; - hda_nid_t *capsrc_nids; + const hda_nid_t *capsrc_nids; unsigned int cur_mux[3]; /* channel model */ @@ -106,12 +119,17 @@ struct conexant_spec { /* dynamic controls, init_verbs and input_mux */ struct auto_pin_cfg autocfg; struct hda_input_mux private_imux; + struct imux_info imux_info[HDA_MAX_NUM_INPUTS]; + hda_nid_t private_adc_nids[HDA_MAX_NUM_INPUTS]; hda_nid_t private_dac_nids[AUTO_CFG_MAX_OUTS]; struct pin_dac_pair dac_info[8]; int dac_info_filled; unsigned int port_d_mode; unsigned int auto_mute:1; /* used in auto-parser */ + unsigned int detect_line:1; /* Line-out detection enabled */ + unsigned int automute_lines:1; /* automute line-out as well */ + unsigned int automute_hp_lo:1; /* both HP and LO available */ unsigned int dell_automute:1; unsigned int dell_vostro:1; unsigned int ideapad:1; @@ -119,6 +137,8 @@ struct conexant_spec { unsigned int hp_laptop:1; unsigned int asus:1; + unsigned int adc_switching:1; + unsigned int ext_mic_present; unsigned int recording; void (*capture_prepare)(struct hda_codec *codec); @@ -227,7 +247,7 @@ static int conexant_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, -static struct hda_pcm_stream conexant_pcm_analog_playback = { +static const struct hda_pcm_stream conexant_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -239,7 +259,7 @@ static struct hda_pcm_stream conexant_pcm_analog_playback = { }, }; -static struct hda_pcm_stream conexant_pcm_analog_capture = { +static const struct hda_pcm_stream conexant_pcm_analog_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -251,7 +271,7 @@ static struct hda_pcm_stream conexant_pcm_analog_capture = { }; -static struct hda_pcm_stream conexant_pcm_digital_playback = { +static const struct hda_pcm_stream conexant_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -263,7 +283,7 @@ static struct hda_pcm_stream conexant_pcm_digital_playback = { }, }; -static struct hda_pcm_stream conexant_pcm_digital_capture = { +static const struct hda_pcm_stream conexant_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -294,7 +314,7 @@ static int cx5051_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, return 0; } -static struct hda_pcm_stream cx5051_pcm_analog_capture = { +static const struct hda_pcm_stream cx5051_pcm_analog_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -319,13 +339,19 @@ static int conexant_build_pcms(struct hda_codec *codec) spec->multiout.max_channels; info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; - if (codec->vendor_id == 0x14f15051) - info->stream[SNDRV_PCM_STREAM_CAPTURE] = - cx5051_pcm_analog_capture; - else - info->stream[SNDRV_PCM_STREAM_CAPTURE] = - conexant_pcm_analog_capture; - info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; + if (spec->capture_stream) + info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->capture_stream; + else { + if (codec->vendor_id == 0x14f15051) + info->stream[SNDRV_PCM_STREAM_CAPTURE] = + cx5051_pcm_analog_capture; + else { + info->stream[SNDRV_PCM_STREAM_CAPTURE] = + conexant_pcm_analog_capture; + info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = + spec->num_adc_nids; + } + } info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; if (spec->multiout.dig_out_nid) { @@ -433,7 +459,7 @@ static void conexant_free(struct hda_codec *codec) kfree(codec->spec); } -static struct snd_kcontrol_new cxt_capture_mixers[] = { +static const struct snd_kcontrol_new cxt_capture_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Capture Source", @@ -446,7 +472,7 @@ static struct snd_kcontrol_new cxt_capture_mixers[] = { #ifdef CONFIG_SND_HDA_INPUT_BEEP /* additional beep mixers; the actual parameters are overwritten at build */ -static struct snd_kcontrol_new cxt_beep_mixer[] = { +static const struct snd_kcontrol_new cxt_beep_mixer[] = { HDA_CODEC_VOLUME_MONO("Beep Playback Volume", 0, 1, 0, HDA_OUTPUT), HDA_CODEC_MUTE_BEEP_MONO("Beep Playback Switch", 0, 1, 0, HDA_OUTPUT), { } /* end */ @@ -456,12 +482,18 @@ static struct snd_kcontrol_new cxt_beep_mixer[] = { static const char * const slave_vols[] = { "Headphone Playback Volume", "Speaker Playback Volume", + "Front Playback Volume", + "Surround Playback Volume", + "CLFE Playback Volume", NULL }; static const char * const slave_sws[] = { "Headphone Playback Switch", "Speaker Playback Switch", + "Front Playback Switch", + "Surround Playback Switch", + "CLFE Playback Switch", NULL }; @@ -521,7 +553,7 @@ static int conexant_build_controls(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_INPUT_BEEP /* create beep controls if needed */ if (spec->beep_amp) { - struct snd_kcontrol_new *knew; + const struct snd_kcontrol_new *knew; for (knew = cxt_beep_mixer; knew->name; knew++) { struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); @@ -546,7 +578,7 @@ static int conexant_suspend(struct hda_codec *codec, pm_message_t state) } #endif -static struct hda_codec_ops conexant_patch_ops = { +static const struct hda_codec_ops conexant_patch_ops = { .build_controls = conexant_build_controls, .build_pcms = conexant_build_pcms, .init = conexant_init, @@ -564,6 +596,7 @@ static struct hda_codec_ops conexant_patch_ops = { #define set_beep_amp(spec, nid, idx, dir) /* NOP */ #endif +static int patch_conexant_auto(struct hda_codec *codec); /* * EAPD control * the private value = nid | (invert << 8) @@ -662,16 +695,16 @@ static int conexant_ch_mode_put(struct snd_kcontrol *kcontrol, /* Conexant 5045 specific */ -static hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; -static hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; -static hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; +static const hda_nid_t cxt5045_dac_nids[1] = { 0x19 }; +static const hda_nid_t cxt5045_adc_nids[1] = { 0x1a }; +static const hda_nid_t cxt5045_capsrc_nids[1] = { 0x1a }; #define CXT5045_SPDIF_OUT 0x18 -static struct hda_channel_mode cxt5045_modes[1] = { +static const struct hda_channel_mode cxt5045_modes[1] = { { 2, NULL }, }; -static struct hda_input_mux cxt5045_capture_source = { +static const struct hda_input_mux cxt5045_capture_source = { .num_items = 2, .items = { { "IntMic", 0x1 }, @@ -679,7 +712,7 @@ static struct hda_input_mux cxt5045_capture_source = { } }; -static struct hda_input_mux cxt5045_capture_source_benq = { +static const struct hda_input_mux cxt5045_capture_source_benq = { .num_items = 5, .items = { { "IntMic", 0x1 }, @@ -690,7 +723,7 @@ static struct hda_input_mux cxt5045_capture_source_benq = { } }; -static struct hda_input_mux cxt5045_capture_source_hp530 = { +static const struct hda_input_mux cxt5045_capture_source_hp530 = { .num_items = 2, .items = { { "ExtMic", 0x1 }, @@ -723,7 +756,7 @@ static int cxt5045_hp_master_sw_put(struct snd_kcontrol *kcontrol, } /* bind volumes of both NID 0x10 and 0x11 */ -static struct hda_bind_ctls cxt5045_hp_bind_master_vol = { +static const struct hda_bind_ctls cxt5045_hp_bind_master_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x10, 3, 0, HDA_OUTPUT), @@ -735,12 +768,12 @@ static struct hda_bind_ctls cxt5045_hp_bind_master_vol = { /* toggle input of built-in and mic jack appropriately */ static void cxt5045_hp_automic(struct hda_codec *codec) { - static struct hda_verb mic_jack_on[] = { + static const struct hda_verb mic_jack_on[] = { {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, {} }; - static struct hda_verb mic_jack_off[] = { + static const struct hda_verb mic_jack_off[] = { {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, {} @@ -784,7 +817,7 @@ static void cxt5045_hp_unsol_event(struct hda_codec *codec, } } -static struct snd_kcontrol_new cxt5045_mixers[] = { +static const struct snd_kcontrol_new cxt5045_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x01, HDA_INPUT), HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), @@ -808,7 +841,7 @@ static struct snd_kcontrol_new cxt5045_mixers[] = { {} }; -static struct snd_kcontrol_new cxt5045_benq_mixers[] = { +static const struct snd_kcontrol_new cxt5045_benq_mixers[] = { HDA_CODEC_VOLUME("CD Capture Volume", 0x1a, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Capture Switch", 0x1a, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x17, 0x4, HDA_INPUT), @@ -825,7 +858,7 @@ static struct snd_kcontrol_new cxt5045_benq_mixers[] = { {} }; -static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { +static const struct snd_kcontrol_new cxt5045_mixers_hp530[] = { HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Capture Switch", 0x1a, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Capture Volume", 0x1a, 0x01, HDA_INPUT), @@ -849,7 +882,7 @@ static struct snd_kcontrol_new cxt5045_mixers_hp530[] = { {} }; -static struct hda_verb cxt5045_init_verbs[] = { +static const struct hda_verb cxt5045_init_verbs[] = { /* Line in, Mic */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, @@ -875,7 +908,7 @@ static struct hda_verb cxt5045_init_verbs[] = { { } /* end */ }; -static struct hda_verb cxt5045_benq_init_verbs[] = { +static const struct hda_verb cxt5045_benq_init_verbs[] = { /* Internal Mic, Mic */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_80 }, {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[] = { { } /* end */ }; -static struct hda_verb cxt5045_hp_sense_init_verbs[] = { +static const struct hda_verb cxt5045_hp_sense_init_verbs[] = { /* pin sensing on HP jack */ {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, { } /* end */ }; -static struct hda_verb cxt5045_mic_sense_init_verbs[] = { +static const struct hda_verb cxt5045_mic_sense_init_verbs[] = { /* pin sensing on HP jack */ {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, { } /* end */ @@ -917,7 +950,7 @@ static struct hda_verb cxt5045_mic_sense_init_verbs[] = { /* Test configuration for debugging, modelled after the ALC260 test * configuration. */ -static struct hda_input_mux cxt5045_test_capture_source = { +static const struct hda_input_mux cxt5045_test_capture_source = { .num_items = 5, .items = { { "MIXER", 0x0 }, @@ -928,7 +961,7 @@ static struct hda_input_mux cxt5045_test_capture_source = { }, }; -static struct snd_kcontrol_new cxt5045_test_mixer[] = { +static const struct snd_kcontrol_new cxt5045_test_mixer[] = { /* Output controls */ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x10, 0x0, HDA_OUTPUT), @@ -978,7 +1011,7 @@ static struct snd_kcontrol_new cxt5045_test_mixer[] = { { } /* end */ }; -static struct hda_verb cxt5045_test_init_verbs[] = { +static const struct hda_verb cxt5045_test_init_verbs[] = { /* Set connections */ { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, { 0x11, AC_VERB_SET_CONNECT_SEL, 0x0 }, @@ -1047,6 +1080,7 @@ enum { #ifdef CONFIG_SND_DEBUG CXT5045_TEST, #endif + CXT5045_AUTO, CXT5045_MODELS }; @@ -1059,9 +1093,10 @@ static const char * const cxt5045_models[CXT5045_MODELS] = { #ifdef CONFIG_SND_DEBUG [CXT5045_TEST] = "test", #endif + [CXT5045_AUTO] = "auto", }; -static struct snd_pci_quirk cxt5045_cfg_tbl[] = { +static const struct snd_pci_quirk cxt5045_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30d5, "HP 530", CXT5045_LAPTOP_HP530), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", CXT5045_LAPTOP_HPSENSE), @@ -1085,6 +1120,16 @@ static int patch_cxt5045(struct hda_codec *codec) struct conexant_spec *spec; int board_config; + board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, + cxt5045_models, + cxt5045_cfg_tbl); +#if 0 /* use the old method just for safety */ + if (board_config < 0) + board_config = CXT5045_AUTO; +#endif + if (board_config == CXT5045_AUTO) + return patch_conexant_auto(codec); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (!spec) return -ENOMEM; @@ -1111,9 +1156,6 @@ static int patch_cxt5045(struct hda_codec *codec) codec->patch_ops = conexant_patch_ops; - board_config = snd_hda_check_board_config(codec, CXT5045_MODELS, - cxt5045_models, - cxt5045_cfg_tbl); switch (board_config) { case CXT5045_LAPTOP_HPSENSE: codec->patch_ops.unsol_event = cxt5045_hp_unsol_event; @@ -1196,15 +1238,15 @@ static int patch_cxt5045(struct hda_codec *codec) /* Conexant 5047 specific */ #define CXT5047_SPDIF_OUT 0x11 -static hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */ -static hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; -static hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; +static const hda_nid_t cxt5047_dac_nids[1] = { 0x10 }; /* 0x1c */ +static const hda_nid_t cxt5047_adc_nids[1] = { 0x12 }; +static const hda_nid_t cxt5047_capsrc_nids[1] = { 0x1a }; -static struct hda_channel_mode cxt5047_modes[1] = { +static const struct hda_channel_mode cxt5047_modes[1] = { { 2, NULL }, }; -static struct hda_input_mux cxt5047_toshiba_capture_source = { +static const struct hda_input_mux cxt5047_toshiba_capture_source = { .num_items = 2, .items = { { "ExtMic", 0x2 }, @@ -1256,12 +1298,12 @@ static void cxt5047_hp_automute(struct hda_codec *codec) /* toggle input of built-in and mic jack appropriately */ static void cxt5047_hp_automic(struct hda_codec *codec) { - static struct hda_verb mic_jack_on[] = { + static const struct hda_verb mic_jack_on[] = { {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {} }; - static struct hda_verb mic_jack_off[] = { + static const struct hda_verb mic_jack_off[] = { {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {} @@ -1289,7 +1331,7 @@ static void cxt5047_hp_unsol_event(struct hda_codec *codec, } } -static struct snd_kcontrol_new cxt5047_base_mixers[] = { +static const struct snd_kcontrol_new cxt5047_base_mixers[] = { HDA_CODEC_VOLUME("Mic Playback Volume", 0x19, 0x02, HDA_INPUT), HDA_CODEC_MUTE("Mic Playback Switch", 0x19, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost Volume", 0x1a, 0x0, HDA_OUTPUT), @@ -1309,19 +1351,19 @@ static struct snd_kcontrol_new cxt5047_base_mixers[] = { {} }; -static struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = { +static const struct snd_kcontrol_new cxt5047_hp_spk_mixers[] = { /* See the note in cxt5047_hp_master_sw_put */ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x1d, 0x01, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x13, 0x00, HDA_OUTPUT), {} }; -static struct snd_kcontrol_new cxt5047_hp_only_mixers[] = { +static const struct snd_kcontrol_new cxt5047_hp_only_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x13, 0x00, HDA_OUTPUT), { } /* end */ }; -static struct hda_verb cxt5047_init_verbs[] = { +static const struct hda_verb cxt5047_init_verbs[] = { /* Line in, Mic, Built-in Mic */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN|AC_PINCTL_VREF_50 }, @@ -1348,7 +1390,7 @@ static struct hda_verb cxt5047_init_verbs[] = { }; /* configuration for Toshiba Laptops */ -static struct hda_verb cxt5047_toshiba_init_verbs[] = { +static const struct hda_verb cxt5047_toshiba_init_verbs[] = { {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x0}, /* default off */ {} }; @@ -1357,7 +1399,7 @@ static struct hda_verb cxt5047_toshiba_init_verbs[] = { * configuration. */ #ifdef CONFIG_SND_DEBUG -static struct hda_input_mux cxt5047_test_capture_source = { +static const struct hda_input_mux cxt5047_test_capture_source = { .num_items = 4, .items = { { "LINE1 pin", 0x0 }, @@ -1367,7 +1409,7 @@ static struct hda_input_mux cxt5047_test_capture_source = { }, }; -static struct snd_kcontrol_new cxt5047_test_mixer[] = { +static const struct snd_kcontrol_new cxt5047_test_mixer[] = { /* Output only controls */ HDA_CODEC_VOLUME("OutAmp-1 Volume", 0x10, 0x0, HDA_OUTPUT), @@ -1420,7 +1462,7 @@ static struct snd_kcontrol_new cxt5047_test_mixer[] = { { } /* end */ }; -static struct hda_verb cxt5047_test_init_verbs[] = { +static const struct hda_verb cxt5047_test_init_verbs[] = { /* Enable retasking pins as output, initially without power amp */ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -1492,6 +1534,7 @@ enum { #ifdef CONFIG_SND_DEBUG CXT5047_TEST, #endif + CXT5047_AUTO, CXT5047_MODELS }; @@ -1502,9 +1545,10 @@ static const char * const cxt5047_models[CXT5047_MODELS] = { #ifdef CONFIG_SND_DEBUG [CXT5047_TEST] = "test", #endif + [CXT5047_AUTO] = "auto", }; -static struct snd_pci_quirk cxt5047_cfg_tbl[] = { +static const struct snd_pci_quirk cxt5047_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30a5, "HP DV5200T/DV8000T", CXT5047_LAPTOP_HP), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3000, "HP DV Series", CXT5047_LAPTOP), @@ -1517,6 +1561,16 @@ static int patch_cxt5047(struct hda_codec *codec) struct conexant_spec *spec; int board_config; + board_config = snd_hda_check_board_config(codec, CXT5047_MODELS, + cxt5047_models, + cxt5047_cfg_tbl); +#if 0 /* not enabled as default, as BIOS often broken for this codec */ + if (board_config < 0) + board_config = CXT5047_AUTO; +#endif + if (board_config == CXT5047_AUTO) + return patch_conexant_auto(codec); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (!spec) return -ENOMEM; @@ -1540,9 +1594,6 @@ static int patch_cxt5047(struct hda_codec *codec) codec->patch_ops = conexant_patch_ops; - board_config = snd_hda_check_board_config(codec, CXT5047_MODELS, - cxt5047_models, - cxt5047_cfg_tbl); switch (board_config) { case CXT5047_LAPTOP: spec->num_mixers = 2; @@ -1591,10 +1642,10 @@ static int patch_cxt5047(struct hda_codec *codec) } /* Conexant 5051 specific */ -static hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; -static hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; +static const hda_nid_t cxt5051_dac_nids[1] = { 0x10 }; +static const hda_nid_t cxt5051_adc_nids[2] = { 0x14, 0x15 }; -static struct hda_channel_mode cxt5051_modes[1] = { +static const struct hda_channel_mode cxt5051_modes[1] = { { 2, NULL }, }; @@ -1696,7 +1747,7 @@ static void cxt5051_hp_unsol_event(struct hda_codec *codec, snd_hda_input_jack_report(codec, nid); } -static struct snd_kcontrol_new cxt5051_playback_mixers[] = { +static const struct snd_kcontrol_new cxt5051_playback_mixers[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -1709,7 +1760,7 @@ static struct snd_kcontrol_new cxt5051_playback_mixers[] = { {} }; -static struct snd_kcontrol_new cxt5051_capture_mixers[] = { +static const struct snd_kcontrol_new cxt5051_capture_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), @@ -1719,7 +1770,7 @@ static struct snd_kcontrol_new cxt5051_capture_mixers[] = { {} }; -static struct snd_kcontrol_new cxt5051_hp_mixers[] = { +static const struct snd_kcontrol_new cxt5051_hp_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), HDA_CODEC_VOLUME("Mic Volume", 0x15, 0x00, HDA_INPUT), @@ -1727,19 +1778,19 @@ static struct snd_kcontrol_new cxt5051_hp_mixers[] = { {} }; -static struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { +static const struct snd_kcontrol_new cxt5051_hp_dv6736_mixers[] = { HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x14, 0x00, HDA_INPUT), {} }; -static struct snd_kcontrol_new cxt5051_f700_mixers[] = { +static const struct snd_kcontrol_new cxt5051_f700_mixers[] = { HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x01, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x14, 0x01, HDA_INPUT), {} }; -static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { +static const struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { HDA_CODEC_VOLUME("Internal Mic Volume", 0x14, 0x00, HDA_INPUT), HDA_CODEC_MUTE("Internal Mic Switch", 0x14, 0x00, HDA_INPUT), HDA_CODEC_VOLUME("Mic Volume", 0x14, 0x01, HDA_INPUT), @@ -1747,7 +1798,7 @@ static struct snd_kcontrol_new cxt5051_toshiba_mixers[] = { {} }; -static struct hda_verb cxt5051_init_verbs[] = { +static const struct hda_verb cxt5051_init_verbs[] = { /* Line in, Mic */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, @@ -1776,7 +1827,7 @@ static struct hda_verb cxt5051_init_verbs[] = { { } /* end */ }; -static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { +static const struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { /* Line in, Mic */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, @@ -1801,7 +1852,7 @@ static struct hda_verb cxt5051_hp_dv6736_init_verbs[] = { { } /* end */ }; -static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { +static const struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { /* Line in, Mic */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, @@ -1834,7 +1885,7 @@ static struct hda_verb cxt5051_lenovo_x200_init_verbs[] = { { } /* end */ }; -static struct hda_verb cxt5051_f700_init_verbs[] = { +static const struct hda_verb cxt5051_f700_init_verbs[] = { /* Line in, Mic */ {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0) | 0x03}, {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, snd_hda_input_jack_report(codec, nid); } -static struct hda_verb cxt5051_ideapad_init_verbs[] = { +static const struct hda_verb cxt5051_ideapad_init_verbs[] = { /* Subwoofer */ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -1906,6 +1957,7 @@ enum { CXT5051_F700, /* HP Compaq Presario F700 */ CXT5051_TOSHIBA, /* Toshiba M300 & co */ CXT5051_IDEAPAD, /* Lenovo IdeaPad Y430 */ + CXT5051_AUTO, /* auto-parser */ CXT5051_MODELS }; @@ -1917,9 +1969,10 @@ static const char *const cxt5051_models[CXT5051_MODELS] = { [CXT5051_F700] = "hp-700", [CXT5051_TOSHIBA] = "toshiba", [CXT5051_IDEAPAD] = "ideapad", + [CXT5051_AUTO] = "auto", }; -static struct snd_pci_quirk cxt5051_cfg_tbl[] = { +static const struct snd_pci_quirk cxt5051_cfg_tbl[] = { SND_PCI_QUIRK(0x103c, 0x30cf, "HP DV6736", CXT5051_HP_DV6736), SND_PCI_QUIRK(0x103c, 0x360b, "Compaq Presario CQ60", CXT5051_HP), SND_PCI_QUIRK(0x103c, 0x30ea, "Compaq Presario F700", CXT5051_F700), @@ -1937,6 +1990,16 @@ static int patch_cxt5051(struct hda_codec *codec) struct conexant_spec *spec; int board_config; + board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, + cxt5051_models, + cxt5051_cfg_tbl); +#if 0 /* use the old method just for safety */ + if (board_config < 0) + board_config = CXT5051_AUTO; +#endif + if (board_config == CXT5051_AUTO) + return patch_conexant_auto(codec); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (!spec) return -ENOMEM; @@ -1967,9 +2030,6 @@ static int patch_cxt5051(struct hda_codec *codec) codec->patch_ops.unsol_event = cxt5051_hp_unsol_event; - board_config = snd_hda_check_board_config(codec, CXT5051_MODELS, - cxt5051_models, - cxt5051_cfg_tbl); spec->auto_mic = AUTO_MIC_PORTB | AUTO_MIC_PORTC; switch (board_config) { case CXT5051_HP: @@ -2011,17 +2071,17 @@ static int patch_cxt5051(struct hda_codec *codec) /* Conexant 5066 specific */ -static hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; -static hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; -static hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; -static hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 }; +static const hda_nid_t cxt5066_dac_nids[1] = { 0x10 }; +static const hda_nid_t cxt5066_adc_nids[3] = { 0x14, 0x15, 0x16 }; +static const hda_nid_t cxt5066_capsrc_nids[1] = { 0x17 }; +static const hda_nid_t cxt5066_digout_pin_nids[2] = { 0x20, 0x22 }; /* OLPC's microphone port is DC coupled for use with external sensors, * therefore we use a 50% mic bias in order to center the input signal with * the DC input range of the codec. */ #define CXT5066_OLPC_EXT_MIC_BIAS PIN_VREF50 -static struct hda_channel_mode cxt5066_modes[1] = { +static const struct hda_channel_mode cxt5066_modes[1] = { { 2, NULL }, }; @@ -2176,7 +2236,7 @@ static void cxt5066_vostro_automic(struct hda_codec *codec) {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, {} }; - static struct hda_verb ext_mic_absent[] = { + static const struct hda_verb ext_mic_absent[] = { /* enable internal mic, port C */ {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, @@ -2209,7 +2269,7 @@ static void cxt5066_ideapad_automic(struct hda_codec *codec) {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, {} }; - static struct hda_verb ext_mic_absent[] = { + static const struct hda_verb ext_mic_absent[] = { {0x14, AC_VERB_SET_CONNECT_SEL, 2}, {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, @@ -2257,7 +2317,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec) { unsigned int ext_present, dock_present; - static struct hda_verb ext_mic_present[] = { + static const struct hda_verb ext_mic_present[] = { {0x14, AC_VERB_SET_CONNECT_SEL, 0}, {0x17, AC_VERB_SET_CONNECT_SEL, 1}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, @@ -2265,7 +2325,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec) {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, {} }; - static struct hda_verb dock_mic_present[] = { + static const struct hda_verb dock_mic_present[] = { {0x14, AC_VERB_SET_CONNECT_SEL, 0}, {0x17, AC_VERB_SET_CONNECT_SEL, 0}, {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, @@ -2273,7 +2333,7 @@ static void cxt5066_thinkpad_automic(struct hda_codec *codec) {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, {} }; - static struct hda_verb ext_mic_absent[] = { + static const struct hda_verb ext_mic_absent[] = { {0x14, AC_VERB_SET_CONNECT_SEL, 2}, {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, @@ -2537,7 +2597,7 @@ static void cxt5066_olpc_capture_cleanup(struct hda_codec *codec) } static void conexant_check_dig_outs(struct hda_codec *codec, - hda_nid_t *dig_pins, + const hda_nid_t *dig_pins, int num_pins) { struct conexant_spec *spec = codec->spec; @@ -2557,7 +2617,7 @@ static void conexant_check_dig_outs(struct hda_codec *codec, } } -static struct hda_input_mux cxt5066_capture_source = { +static const struct hda_input_mux cxt5066_capture_source = { .num_items = 4, .items = { { "Mic B", 0 }, @@ -2567,7 +2627,7 @@ static struct hda_input_mux cxt5066_capture_source = { }, }; -static struct hda_bind_ctls cxt5066_bind_capture_vol_others = { +static const struct hda_bind_ctls cxt5066_bind_capture_vol_others = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), @@ -2576,7 +2636,7 @@ static struct hda_bind_ctls cxt5066_bind_capture_vol_others = { }, }; -static struct hda_bind_ctls cxt5066_bind_capture_sw_others = { +static const struct hda_bind_ctls cxt5066_bind_capture_sw_others = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_INPUT), @@ -2585,12 +2645,12 @@ static struct hda_bind_ctls cxt5066_bind_capture_sw_others = { }, }; -static struct snd_kcontrol_new cxt5066_mixer_master[] = { +static const struct snd_kcontrol_new cxt5066_mixer_master[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x10, 0x00, HDA_OUTPUT), {} }; -static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { +static const struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Volume", @@ -2609,7 +2669,7 @@ static struct snd_kcontrol_new cxt5066_mixer_master_olpc[] = { {} }; -static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { +static const struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "DC Mode Enable Switch", @@ -2627,7 +2687,7 @@ static struct snd_kcontrol_new cxt5066_mixer_olpc_dc[] = { {} }; -static struct snd_kcontrol_new cxt5066_mixers[] = { +static const struct snd_kcontrol_new cxt5066_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -2650,7 +2710,7 @@ static struct snd_kcontrol_new cxt5066_mixers[] = { {} }; -static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { +static const struct snd_kcontrol_new cxt5066_vostro_mixers[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Internal Mic Boost Capture Enum", @@ -2662,7 +2722,7 @@ static struct snd_kcontrol_new cxt5066_vostro_mixers[] = { {} }; -static struct hda_verb cxt5066_init_verbs[] = { +static const struct hda_verb cxt5066_init_verbs[] = { {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ @@ -2717,7 +2777,7 @@ static struct hda_verb cxt5066_init_verbs[] = { { } /* end */ }; -static struct hda_verb cxt5066_init_verbs_olpc[] = { +static const struct hda_verb cxt5066_init_verbs_olpc[] = { /* Port A: headphones */ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ @@ -2778,7 +2838,7 @@ static struct hda_verb cxt5066_init_verbs_olpc[] = { { } /* end */ }; -static struct hda_verb cxt5066_init_verbs_vostro[] = { +static const struct hda_verb cxt5066_init_verbs_vostro[] = { /* Port A: headphones */ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0}, {0x19, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC1 */ @@ -2839,7 +2899,7 @@ static struct hda_verb cxt5066_init_verbs_vostro[] = { { } /* end */ }; -static struct hda_verb cxt5066_init_verbs_ideapad[] = { +static const struct hda_verb cxt5066_init_verbs_ideapad[] = { {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port B */ {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, /* Port C */ {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ @@ -2889,7 +2949,7 @@ static struct hda_verb cxt5066_init_verbs_ideapad[] = { { } /* end */ }; -static struct hda_verb cxt5066_init_verbs_thinkpad[] = { +static const struct hda_verb cxt5066_init_verbs_thinkpad[] = { {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port F */ {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Port E */ @@ -2947,13 +3007,13 @@ static struct hda_verb cxt5066_init_verbs_thinkpad[] = { { } /* end */ }; -static struct hda_verb cxt5066_init_verbs_portd_lo[] = { +static const struct hda_verb cxt5066_init_verbs_portd_lo[] = { {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, { } /* end */ }; -static struct hda_verb cxt5066_init_verbs_hp_laptop[] = { +static const struct hda_verb cxt5066_init_verbs_hp_laptop[] = { {0x14, AC_VERB_SET_CONNECT_SEL, 0x0}, {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_HP_EVENT}, {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | CONEXANT_MIC_EVENT}, @@ -2997,6 +3057,7 @@ enum { CXT5066_THINKPAD, /* Lenovo ThinkPad T410s, others? */ CXT5066_ASUS, /* Asus K52JU, Lenovo G560 - Int mic at 0x1a and Ext mic at 0x1b */ CXT5066_HP_LAPTOP, /* HP Laptop */ + CXT5066_AUTO, /* BIOS auto-parser */ CXT5066_MODELS }; @@ -3009,9 +3070,10 @@ static const char * const cxt5066_models[CXT5066_MODELS] = { [CXT5066_THINKPAD] = "thinkpad", [CXT5066_ASUS] = "asus", [CXT5066_HP_LAPTOP] = "hp-laptop", + [CXT5066_AUTO] = "auto", }; -static struct snd_pci_quirk cxt5066_cfg_tbl[] = { +static const struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK_MASK(0x1025, 0xff00, 0x0400, "Acer", CXT5066_IDEAPAD), SND_PCI_QUIRK(0x1028, 0x02d8, "Dell Vostro", CXT5066_DELL_VOSTRO), SND_PCI_QUIRK(0x1028, 0x02f5, "Dell Vostro 320", CXT5066_IDEAPAD), @@ -3046,6 +3108,15 @@ static int patch_cxt5066(struct hda_codec *codec) struct conexant_spec *spec; int board_config; + board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, + cxt5066_models, cxt5066_cfg_tbl); +#if 0 /* use the old method just for safety */ + if (board_config < 0) + board_config = CXT5066_AUTO; +#endif + if (board_config == CXT5066_AUTO) + return patch_conexant_auto(codec); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (!spec) return -ENOMEM; @@ -3076,8 +3147,6 @@ static int patch_cxt5066(struct hda_codec *codec) set_beep_amp(spec, 0x13, 0, HDA_OUTPUT); - board_config = snd_hda_check_board_config(codec, CXT5066_MODELS, - cxt5066_models, cxt5066_cfg_tbl); switch (board_config) { default: case CXT5066_LAPTOP: @@ -3195,7 +3264,45 @@ static int patch_cxt5066(struct hda_codec *codec) * Automatic parser for CX20641 & co */ -static hda_nid_t cx_auto_adc_nids[] = { 0x14 }; +static int cx_auto_capture_pcm_prepare(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + unsigned int stream_tag, + unsigned int format, + struct snd_pcm_substream *substream) +{ + struct conexant_spec *spec = codec->spec; + hda_nid_t adc = spec->imux_info[spec->cur_mux[0]].adc; + if (spec->adc_switching) { + spec->cur_adc = adc; + spec->cur_adc_stream_tag = stream_tag; + spec->cur_adc_format = format; + } + snd_hda_codec_setup_stream(codec, adc, stream_tag, 0, format); + return 0; +} + +static int cx_auto_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, + struct hda_codec *codec, + struct snd_pcm_substream *substream) +{ + struct conexant_spec *spec = codec->spec; + snd_hda_codec_cleanup_stream(codec, spec->cur_adc); + spec->cur_adc = 0; + return 0; +} + +static const struct hda_pcm_stream cx_auto_pcm_analog_capture = { + .substreams = 1, + .channels_min = 2, + .channels_max = 2, + .nid = 0, /* fill later */ + .ops = { + .prepare = cx_auto_capture_pcm_prepare, + .cleanup = cx_auto_capture_pcm_cleanup + }, +}; + +static const hda_nid_t cx_auto_adc_nids[] = { 0x14 }; /* get the connection index of @nid in the widget @mux */ static int get_connection_index(struct hda_codec *codec, hda_nid_t mux, @@ -3320,61 +3427,339 @@ static void cx_auto_parse_output(struct hda_codec *codec) spec->multiout.dac_nids = spec->private_dac_nids; spec->multiout.max_channels = spec->multiout.num_dacs * 2; - if (cfg->hp_outs > 0) - spec->auto_mute = 1; + for (i = 0; i < cfg->hp_outs; i++) { + if (is_jack_detectable(codec, cfg->hp_pins[i])) { + spec->auto_mute = 1; + break; + } + } + if (spec->auto_mute && cfg->line_out_pins[0] && + cfg->line_out_pins[0] != cfg->hp_pins[0] && + cfg->line_out_pins[0] != cfg->speaker_pins[0]) { + for (i = 0; i < cfg->line_outs; i++) { + if (is_jack_detectable(codec, cfg->line_out_pins[i])) { + spec->detect_line = 1; + break; + } + } + spec->automute_lines = spec->detect_line; + } + spec->vmaster_nid = spec->private_dac_nids[0]; } +static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, + hda_nid_t *pins, bool on); + +static void do_automute(struct hda_codec *codec, int num_pins, + hda_nid_t *pins, bool on) +{ + int i; + for (i = 0; i < num_pins; i++) + snd_hda_codec_write(codec, pins[i], 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + on ? PIN_OUT : 0); + cx_auto_turn_eapd(codec, num_pins, pins, on); +} + +static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) +{ + int i, present = 0; + + for (i = 0; i < num_pins; i++) { + hda_nid_t nid = pins[i]; + if (!nid || !is_jack_detectable(codec, nid)) + break; + snd_hda_input_jack_report(codec, nid); + present |= snd_hda_jack_detect(codec, nid); + } + return present; +} + /* auto-mute/unmute speaker and line outs according to headphone jack */ +static void cx_auto_update_speakers(struct hda_codec *codec) +{ + struct conexant_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + int on; + + if (!spec->auto_mute) + on = 0; + else + on = spec->hp_present | spec->line_present; + cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); + do_automute(codec, cfg->speaker_outs, cfg->speaker_pins, !on); + + /* toggle line-out mutes if needed, too */ + /* if LO is a copy of either HP or Speaker, don't need to handle it */ + if (cfg->line_out_pins[0] == cfg->hp_pins[0] || + cfg->line_out_pins[0] == cfg->speaker_pins[0]) + return; + if (!spec->automute_lines || !spec->auto_mute) + on = 0; + else + on = spec->hp_present; + do_automute(codec, cfg->line_outs, cfg->line_out_pins, !on); +} + static void cx_auto_hp_automute(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; - int i, present; if (!spec->auto_mute) return; - present = 0; - for (i = 0; i < cfg->hp_outs; i++) { - if (snd_hda_jack_detect(codec, cfg->hp_pins[i])) { - present = 1; - break; + spec->hp_present = detect_jacks(codec, cfg->hp_outs, cfg->hp_pins); + cx_auto_update_speakers(codec); +} + +static void cx_auto_line_automute(struct hda_codec *codec) +{ + struct conexant_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + + if (!spec->auto_mute || !spec->detect_line) + return; + spec->line_present = detect_jacks(codec, cfg->line_outs, + cfg->line_out_pins); + cx_auto_update_speakers(codec); +} + +static int cx_automute_mode_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct conexant_spec *spec = codec->spec; + static const char * const texts2[] = { + "Disabled", "Enabled" + }; + static const char * const texts3[] = { + "Disabled", "Speaker Only", "Line-Out+Speaker" + }; + const char * const *texts; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + if (spec->automute_hp_lo) { + uinfo->value.enumerated.items = 3; + texts = texts3; + } else { + uinfo->value.enumerated.items = 2; + texts = texts2; + } + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + return 0; +} + +static int cx_automute_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct conexant_spec *spec = codec->spec; + unsigned int val; + if (!spec->auto_mute) + val = 0; + else if (!spec->automute_lines) + val = 1; + else + val = 2; + ucontrol->value.enumerated.item[0] = val; + return 0; +} + +static int cx_automute_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct conexant_spec *spec = codec->spec; + + switch (ucontrol->value.enumerated.item[0]) { + case 0: + if (!spec->auto_mute) + return 0; + spec->auto_mute = 0; + break; + case 1: + if (spec->auto_mute && !spec->automute_lines) + return 0; + spec->auto_mute = 1; + spec->automute_lines = 0; + break; + case 2: + if (!spec->automute_hp_lo) + return -EINVAL; + if (spec->auto_mute && spec->automute_lines) + return 0; + spec->auto_mute = 1; + spec->automute_lines = 1; + break; + default: + return -EINVAL; + } + cx_auto_update_speakers(codec); + return 1; +} + +static const struct snd_kcontrol_new cx_automute_mode_enum[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Auto-Mute Mode", + .info = cx_automute_mode_info, + .get = cx_automute_mode_get, + .put = cx_automute_mode_put, + }, + { } +}; + +static int cx_auto_mux_enum_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct conexant_spec *spec = codec->spec; + + return snd_hda_input_mux_info(&spec->private_imux, uinfo); +} + +static int cx_auto_mux_enum_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct conexant_spec *spec = codec->spec; + + ucontrol->value.enumerated.item[0] = spec->cur_mux[0]; + return 0; +} + +/* look for the route the given pin from mux and return the index; + * if do_select is set, actually select the route. + */ +static int __select_input_connection(struct hda_codec *codec, hda_nid_t mux, + hda_nid_t pin, hda_nid_t *srcp, + bool do_select, int depth) +{ + hda_nid_t conn[HDA_MAX_NUM_INPUTS]; + int i, nums; + + switch (get_wcaps_type(get_wcaps(codec, mux))) { + case AC_WID_AUD_IN: + case AC_WID_AUD_SEL: + case AC_WID_AUD_MIX: + break; + default: + return -1; + } + + nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn)); + for (i = 0; i < nums; i++) + if (conn[i] == pin) { + if (do_select) + snd_hda_codec_write(codec, mux, 0, + AC_VERB_SET_CONNECT_SEL, i); + if (srcp) + *srcp = mux; + return i; + } + depth++; + if (depth == 2) + return -1; + for (i = 0; i < nums; i++) { + int ret = __select_input_connection(codec, conn[i], pin, srcp, + do_select, depth); + if (ret >= 0) { + if (do_select) + snd_hda_codec_write(codec, mux, 0, + AC_VERB_SET_CONNECT_SEL, i); + return i; } } - for (i = 0; i < cfg->line_outs; i++) { - snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - present ? 0 : PIN_OUT); - } - for (i = 0; !present && i < cfg->line_outs; i++) - if (snd_hda_jack_detect(codec, cfg->line_out_pins[i])) - present = 1; - for (i = 0; i < cfg->speaker_outs; i++) { - snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - present ? 0 : PIN_OUT); + return -1; +} + +static void select_input_connection(struct hda_codec *codec, hda_nid_t mux, + hda_nid_t pin) +{ + __select_input_connection(codec, mux, pin, NULL, true, 0); +} + +static int get_input_connection(struct hda_codec *codec, hda_nid_t mux, + hda_nid_t pin) +{ + return __select_input_connection(codec, mux, pin, NULL, false, 0); +} + +static int cx_auto_mux_enum_update(struct hda_codec *codec, + const struct hda_input_mux *imux, + unsigned int idx) +{ + struct conexant_spec *spec = codec->spec; + hda_nid_t adc; + + if (!imux->num_items) + return 0; + if (idx >= imux->num_items) + idx = imux->num_items - 1; + if (spec->cur_mux[0] == idx) + return 0; + adc = spec->imux_info[idx].adc; + select_input_connection(codec, spec->imux_info[idx].adc, + spec->imux_info[idx].pin); + if (spec->cur_adc && spec->cur_adc != adc) { + /* stream is running, let's swap the current ADC */ + __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1); + spec->cur_adc = adc; + snd_hda_codec_setup_stream(codec, adc, + spec->cur_adc_stream_tag, 0, + spec->cur_adc_format); } + spec->cur_mux[0] = idx; + return 1; +} + +static int cx_auto_mux_enum_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct conexant_spec *spec = codec->spec; + + return cx_auto_mux_enum_update(codec, &spec->private_imux, + ucontrol->value.enumerated.item[0]); +} + +static const struct snd_kcontrol_new cx_auto_capture_mixers[] = { + { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Capture Source", + .info = cx_auto_mux_enum_info, + .get = cx_auto_mux_enum_get, + .put = cx_auto_mux_enum_put + }, + {} +}; + +static bool select_automic(struct hda_codec *codec, int idx, bool detect) +{ + struct conexant_spec *spec = codec->spec; + if (idx < 0) + return false; + if (detect && !snd_hda_jack_detect(codec, spec->imux_info[idx].pin)) + return false; + cx_auto_mux_enum_update(codec, &spec->private_imux, idx); + return true; } /* automatic switch internal and external mic */ static void cx_auto_automic(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; - struct hda_input_mux *imux = &spec->private_imux; - int ext_idx = spec->auto_mic_ext; if (!spec->auto_mic) return; - if (snd_hda_jack_detect(codec, cfg->inputs[ext_idx].pin)) { - snd_hda_codec_write(codec, spec->adc_nids[0], 0, - AC_VERB_SET_CONNECT_SEL, - imux->items[ext_idx].index); - } else { - snd_hda_codec_write(codec, spec->adc_nids[0], 0, - AC_VERB_SET_CONNECT_SEL, - imux->items[!ext_idx].index); - } + if (!select_automic(codec, spec->auto_mic_ext, true)) + if (!select_automic(codec, spec->auto_mic_dock, true)) + select_automic(codec, spec->auto_mic_int, false); } static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) @@ -3383,7 +3768,9 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) switch (res >> 26) { case CONEXANT_HP_EVENT: cx_auto_hp_automute(codec); - snd_hda_input_jack_report(codec, nid); + break; + case CONEXANT_LINE_EVENT: + cx_auto_line_automute(codec); break; case CONEXANT_MIC_EVENT: cx_auto_automic(codec); @@ -3392,43 +3779,45 @@ static void cx_auto_unsol_event(struct hda_codec *codec, unsigned int res) } } -/* return true if it's an internal-mic pin */ -static int is_int_mic(struct hda_codec *codec, hda_nid_t pin) -{ - unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin); - return get_defcfg_device(def_conf) == AC_JACK_MIC_IN && - snd_hda_get_input_pin_attr(def_conf) == INPUT_PIN_ATTR_INT; -} - -/* return true if it's an external-mic pin */ -static int is_ext_mic(struct hda_codec *codec, hda_nid_t pin) -{ - unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin); - return get_defcfg_device(def_conf) == AC_JACK_MIC_IN && - snd_hda_get_input_pin_attr(def_conf) >= INPUT_PIN_ATTR_NORMAL && - (snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_PRES_DETECT); -} - /* check whether the pin config is suitable for auto-mic switching; - * auto-mic is enabled only when one int-mic and one-ext mic exist + * auto-mic is enabled only when one int-mic and one ext- and/or + * one dock-mic exist */ static void cx_auto_check_auto_mic(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; + int pset[INPUT_PIN_ATTR_NORMAL + 1]; + int i; - if (is_ext_mic(codec, cfg->inputs[0].pin) && - is_int_mic(codec, cfg->inputs[1].pin)) { - spec->auto_mic = 1; - spec->auto_mic_ext = 1; - return; - } - if (is_int_mic(codec, cfg->inputs[1].pin) && - is_ext_mic(codec, cfg->inputs[0].pin)) { - spec->auto_mic = 1; - spec->auto_mic_ext = 0; - return; + for (i = 0; i < INPUT_PIN_ATTR_NORMAL; i++) + pset[i] = -1; + for (i = 0; i < spec->private_imux.num_items; i++) { + hda_nid_t pin = spec->imux_info[i].pin; + unsigned int def_conf = snd_hda_codec_get_pincfg(codec, pin); + int type, attr; + attr = snd_hda_get_input_pin_attr(def_conf); + if (attr == INPUT_PIN_ATTR_UNUSED) + return; /* invalid entry */ + if (attr > INPUT_PIN_ATTR_NORMAL) + attr = INPUT_PIN_ATTR_NORMAL; + if (attr != INPUT_PIN_ATTR_INT && + !is_jack_detectable(codec, pin)) + return; /* non-detectable pin */ + type = get_defcfg_device(def_conf); + if (type != AC_JACK_MIC_IN && + (attr != INPUT_PIN_ATTR_DOCK || type != AC_JACK_LINE_IN)) + return; /* no valid input type */ + if (pset[attr] >= 0) + return; /* already occupied */ + pset[attr] = i; } + if (pset[INPUT_PIN_ATTR_INT] < 0 || + (pset[INPUT_PIN_ATTR_NORMAL] < 0 && pset[INPUT_PIN_ATTR_DOCK])) + return; /* no input to switch*/ + spec->auto_mic = 1; + spec->auto_mic_ext = pset[INPUT_PIN_ATTR_NORMAL]; + spec->auto_mic_dock = pset[INPUT_PIN_ATTR_DOCK]; + spec->auto_mic_int = pset[INPUT_PIN_ATTR_INT]; } static void cx_auto_parse_input(struct hda_codec *codec) @@ -3436,22 +3825,37 @@ static void cx_auto_parse_input(struct hda_codec *codec) struct conexant_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; struct hda_input_mux *imux; - int i; + int i, j; imux = &spec->private_imux; for (i = 0; i < cfg->num_inputs; i++) { - int idx = get_connection_index(codec, spec->adc_nids[0], - cfg->inputs[i].pin); - if (idx >= 0) { - const char *label; - label = hda_get_autocfg_input_label(codec, cfg, i); - snd_hda_add_imux_item(imux, label, idx, NULL); + for (j = 0; j < spec->num_adc_nids; j++) { + hda_nid_t adc = spec->adc_nids[j]; + int idx = get_input_connection(codec, adc, + cfg->inputs[i].pin); + if (idx >= 0) { + const char *label; + label = hda_get_autocfg_input_label(codec, cfg, i); + spec->imux_info[imux->num_items].index = i; + spec->imux_info[imux->num_items].boost = 0; + spec->imux_info[imux->num_items].adc = adc; + spec->imux_info[imux->num_items].pin = + cfg->inputs[i].pin; + snd_hda_add_imux_item(imux, label, idx, NULL); + break; + } } } - if (imux->num_items == 2 && cfg->num_inputs == 2) + if (imux->num_items >= 2 && cfg->num_inputs == imux->num_items) cx_auto_check_auto_mic(codec); - if (imux->num_items > 1 && !spec->auto_mic) - spec->input_mux = imux; + if (imux->num_items > 1 && !spec->auto_mic) { + for (i = 1; i < imux->num_items; i++) { + if (spec->imux_info[i].adc != spec->imux_info[0].adc) { + spec->adc_switching = 1; + break; + } + } + } } /* get digital-input audio widget corresponding to the given pin */ @@ -3517,14 +3921,15 @@ static int cx_auto_parse_auto_config(struct hda_codec *codec) return 0; } -static void cx_auto_turn_on_eapd(struct hda_codec *codec, int num_pins, - hda_nid_t *pins) +static void cx_auto_turn_eapd(struct hda_codec *codec, int num_pins, + hda_nid_t *pins, bool on) { int i; for (i = 0; i < num_pins; i++) { if (snd_hda_query_pin_caps(codec, pins[i]) & AC_PINCAP_EAPD) snd_hda_codec_write(codec, pins[i], 0, - AC_VERB_SET_EAPD_BTLENABLE, 0x02); + AC_VERB_SET_EAPD_BTLENABLE, + on ? 0x02 : 0); } } @@ -3537,6 +3942,34 @@ static void select_connection(struct hda_codec *codec, hda_nid_t pin, AC_VERB_SET_CONNECT_SEL, idx); } +static void mute_outputs(struct hda_codec *codec, int num_nids, + const hda_nid_t *nids) +{ + int i, val; + + for (i = 0; i < num_nids; i++) { + hda_nid_t nid = nids[i]; + if (!(get_wcaps(codec, nid) & AC_WCAP_OUT_AMP)) + continue; + if (query_amp_caps(codec, nid, HDA_OUTPUT) & AC_AMPCAP_MUTE) + val = AMP_OUT_MUTE; + else + val = AMP_OUT_ZERO; + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_AMP_GAIN_MUTE, val); + } +} + +static void enable_unsol_pins(struct hda_codec *codec, int num_pins, + hda_nid_t *pins, unsigned int tag) +{ + int i; + for (i = 0; i < num_pins; i++) + snd_hda_codec_write(codec, pins[i], 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | tag); +} + static void cx_auto_init_output(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; @@ -3544,51 +3977,53 @@ static void cx_auto_init_output(struct hda_codec *codec) hda_nid_t nid; int i; - for (i = 0; i < spec->multiout.num_dacs; i++) - snd_hda_codec_write(codec, spec->multiout.dac_nids[i], 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); - + mute_outputs(codec, spec->multiout.num_dacs, spec->multiout.dac_nids); for (i = 0; i < cfg->hp_outs; i++) snd_hda_codec_write(codec, cfg->hp_pins[i], 0, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP); - if (spec->auto_mute) { - for (i = 0; i < cfg->hp_outs; i++) { - snd_hda_codec_write(codec, cfg->hp_pins[i], 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | CONEXANT_HP_EVENT); - } - cx_auto_hp_automute(codec); - } else { - for (i = 0; i < cfg->line_outs; i++) - snd_hda_codec_write(codec, cfg->line_out_pins[i], 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - for (i = 0; i < cfg->speaker_outs; i++) - snd_hda_codec_write(codec, cfg->speaker_pins[i], 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - } - + mute_outputs(codec, cfg->hp_outs, cfg->hp_pins); + mute_outputs(codec, cfg->line_outs, cfg->line_out_pins); + mute_outputs(codec, cfg->speaker_outs, cfg->speaker_pins); for (i = 0; i < spec->dac_info_filled; i++) { nid = spec->dac_info[i].dac; if (!nid) nid = spec->multiout.dac_nids[0]; select_connection(codec, spec->dac_info[i].pin, nid); } - - /* turn on EAPD */ - cx_auto_turn_on_eapd(codec, cfg->line_outs, cfg->line_out_pins); - cx_auto_turn_on_eapd(codec, cfg->hp_outs, cfg->hp_pins); - cx_auto_turn_on_eapd(codec, cfg->speaker_outs, cfg->speaker_pins); + if (spec->auto_mute) { + enable_unsol_pins(codec, cfg->hp_outs, cfg->hp_pins, + CONEXANT_HP_EVENT); + spec->hp_present = detect_jacks(codec, cfg->hp_outs, + cfg->hp_pins); + if (spec->detect_line) { + enable_unsol_pins(codec, cfg->line_outs, + cfg->line_out_pins, + CONEXANT_LINE_EVENT); + spec->line_present = + detect_jacks(codec, cfg->line_outs, + cfg->line_out_pins); + } + } + cx_auto_update_speakers(codec); } static void cx_auto_init_input(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; - int i; + int i, val; - for (i = 0; i < spec->num_adc_nids; i++) - snd_hda_codec_write(codec, spec->adc_nids[i], 0, - AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)); + for (i = 0; i < spec->num_adc_nids; i++) { + hda_nid_t nid = spec->adc_nids[i]; + if (!(get_wcaps(codec, nid) & AC_WCAP_IN_AMP)) + continue; + if (query_amp_caps(codec, nid, HDA_INPUT) & AC_AMPCAP_MUTE) + val = AMP_IN_MUTE(0); + else + val = AMP_IN_UNMUTE(0); + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, + val); + } for (i = 0; i < cfg->num_inputs; i++) { unsigned int type; @@ -3601,17 +4036,22 @@ static void cx_auto_init_input(struct hda_codec *codec) } if (spec->auto_mic) { - int ext_idx = spec->auto_mic_ext; - snd_hda_codec_write(codec, cfg->inputs[ext_idx].pin, 0, - AC_VERB_SET_UNSOLICITED_ENABLE, - AC_USRSP_EN | CONEXANT_MIC_EVENT); + if (spec->auto_mic_ext >= 0) { + snd_hda_codec_write(codec, + cfg->inputs[spec->auto_mic_ext].pin, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | CONEXANT_MIC_EVENT); + } + if (spec->auto_mic_dock >= 0) { + snd_hda_codec_write(codec, + cfg->inputs[spec->auto_mic_dock].pin, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | CONEXANT_MIC_EVENT); + } cx_auto_automic(codec); } else { - for (i = 0; i < spec->num_adc_nids; i++) { - snd_hda_codec_write(codec, spec->adc_nids[i], 0, - AC_VERB_SET_CONNECT_SEL, - spec->private_imux.items[0].index); - } + select_input_connection(codec, spec->imux_info[0].adc, + spec->imux_info[0].pin); } } @@ -3646,7 +4086,7 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, HDA_CODEC_VOLUME(name, 0, 0, 0), HDA_CODEC_MUTE(name, 0, 0, 0), }; - static char *sfx[2] = { "Volume", "Switch" }; + static const char * const sfx[2] = { "Volume", "Switch" }; int i, err; for (i = 0; i < 2; i++) { @@ -3674,6 +4114,19 @@ static int cx_auto_add_volume_idx(struct hda_codec *codec, const char *basename, #define cx_auto_add_pb_volume(codec, nid, str, idx) \ cx_auto_add_volume(codec, str, " Playback", idx, nid, HDA_OUTPUT) +static int try_add_pb_volume(struct hda_codec *codec, hda_nid_t dac, + hda_nid_t pin, const char *name, int idx) +{ + unsigned int caps; + caps = query_amp_caps(codec, dac, HDA_OUTPUT); + if (caps & AC_AMPCAP_NUM_STEPS) + return cx_auto_add_pb_volume(codec, dac, name, idx); + caps = query_amp_caps(codec, pin, HDA_OUTPUT); + if (caps & AC_AMPCAP_NUM_STEPS) + return cx_auto_add_pb_volume(codec, pin, name, idx); + return 0; +} + static int cx_auto_build_output_controls(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; @@ -3682,8 +4135,10 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) static const char * const texts[3] = { "Front", "Surround", "CLFE" }; if (spec->dac_info_filled == 1) - return cx_auto_add_pb_volume(codec, spec->dac_info[0].dac, - "Master", 0); + return try_add_pb_volume(codec, spec->dac_info[0].dac, + spec->dac_info[0].pin, + "Master", 0); + for (i = 0; i < spec->dac_info_filled; i++) { const char *label; int idx, type; @@ -3707,74 +4162,123 @@ static int cx_auto_build_output_controls(struct hda_codec *codec) idx = num_spk++; break; } - err = cx_auto_add_pb_volume(codec, spec->dac_info[i].dac, - label, idx); + err = try_add_pb_volume(codec, spec->dac_info[i].dac, + spec->dac_info[i].pin, + label, idx); if (err < 0) return err; } + + if (spec->auto_mute) { + err = snd_hda_add_new_ctls(codec, cx_automute_mode_enum); + if (err < 0) + return err; + } + + return 0; +} + +static int cx_auto_add_capture_volume(struct hda_codec *codec, hda_nid_t nid, + const char *label, const char *pfx, + int cidx) +{ + struct conexant_spec *spec = codec->spec; + int i; + + for (i = 0; i < spec->num_adc_nids; i++) { + hda_nid_t adc_nid = spec->adc_nids[i]; + int idx = get_input_connection(codec, adc_nid, nid); + if (idx < 0) + continue; + return cx_auto_add_volume_idx(codec, label, pfx, + cidx, adc_nid, HDA_INPUT, idx); + } + return 0; +} + +static int cx_auto_add_boost_volume(struct hda_codec *codec, int idx, + const char *label, int cidx) +{ + struct conexant_spec *spec = codec->spec; + hda_nid_t mux, nid; + int i, con; + + nid = spec->imux_info[idx].pin; + if (get_wcaps(codec, nid) & AC_WCAP_IN_AMP) + return cx_auto_add_volume(codec, label, " Boost", cidx, + nid, HDA_INPUT); + con = __select_input_connection(codec, spec->imux_info[idx].adc, nid, + &mux, false, 0); + if (con < 0) + return 0; + for (i = 0; i < idx; i++) { + if (spec->imux_info[i].boost == mux) + return 0; /* already present */ + } + + if (get_wcaps(codec, mux) & AC_WCAP_OUT_AMP) { + spec->imux_info[idx].boost = mux; + return cx_auto_add_volume(codec, label, " Boost", 0, + mux, HDA_OUTPUT); + } return 0; } static int cx_auto_build_input_controls(struct hda_codec *codec) { struct conexant_spec *spec = codec->spec; - struct auto_pin_cfg *cfg = &spec->autocfg; - static const char *prev_label; - int i, err, cidx, conn_len; - hda_nid_t conn[HDA_MAX_CONNECTIONS]; + struct hda_input_mux *imux = &spec->private_imux; + const char *prev_label; + int input_conn[HDA_MAX_NUM_INPUTS]; + int i, err, cidx; + int multi_connection; - int multi_adc_volume = 0; /* If the ADC nid has several input volumes */ - int adc_nid = spec->adc_nids[0]; - - conn_len = snd_hda_get_connections(codec, adc_nid, conn, - HDA_MAX_CONNECTIONS); - if (conn_len < 0) - return conn_len; - - multi_adc_volume = cfg->num_inputs > 1 && conn_len > 1; - if (!multi_adc_volume) { - err = cx_auto_add_volume(codec, "Capture", "", 0, adc_nid, - HDA_INPUT); - if (err < 0) - return err; + multi_connection = 0; + for (i = 0; i < imux->num_items; i++) { + cidx = get_input_connection(codec, spec->imux_info[i].adc, + spec->imux_info[i].pin); + input_conn[i] = (spec->imux_info[i].adc << 8) | cidx; + if (i > 0 && input_conn[i] != input_conn[0]) + multi_connection = 1; } prev_label = NULL; cidx = 0; - for (i = 0; i < cfg->num_inputs; i++) { - hda_nid_t nid = cfg->inputs[i].pin; + for (i = 0; i < imux->num_items; i++) { + hda_nid_t nid = spec->imux_info[i].pin; const char *label; - int j; - int pin_amp = get_wcaps(codec, nid) & AC_WCAP_IN_AMP; - if (!pin_amp && !multi_adc_volume) - continue; - label = hda_get_autocfg_input_label(codec, cfg, i); + label = hda_get_autocfg_input_label(codec, &spec->autocfg, + spec->imux_info[i].index); if (label == prev_label) cidx++; else cidx = 0; prev_label = label; - if (pin_amp) { - err = cx_auto_add_volume(codec, label, " Boost", cidx, - nid, HDA_INPUT); - if (err < 0) - return err; - } + err = cx_auto_add_boost_volume(codec, i, label, cidx); + if (err < 0) + return err; - if (!multi_adc_volume) - continue; - for (j = 0; j < conn_len; j++) { - if (conn[j] == nid) { - err = cx_auto_add_volume_idx(codec, label, - " Capture", cidx, adc_nid, HDA_INPUT, j); - if (err < 0) - return err; - break; - } + if (!multi_connection) { + if (i > 0) + continue; + err = cx_auto_add_capture_volume(codec, nid, + "Capture", "", cidx); + } else { + err = cx_auto_add_capture_volume(codec, nid, + label, " Capture", cidx); } + if (err < 0) + return err; } + + if (spec->private_imux.num_items > 1 && !spec->auto_mic) { + err = snd_hda_add_new_ctls(codec, cx_auto_capture_mixers); + if (err < 0) + return err; + } + return 0; } @@ -3791,7 +4295,29 @@ static int cx_auto_build_controls(struct hda_codec *codec) return conexant_build_controls(codec); } -static struct hda_codec_ops cx_auto_patch_ops = { +static int cx_auto_search_adcs(struct hda_codec *codec) +{ + struct conexant_spec *spec = codec->spec; + hda_nid_t nid, end_nid; + + end_nid = codec->start_nid + codec->num_nodes; + for (nid = codec->start_nid; nid < end_nid; nid++) { + unsigned int caps = get_wcaps(codec, nid); + if (get_wcaps_type(caps) != AC_WID_AUD_IN) + continue; + if (caps & AC_WCAP_DIGITAL) + continue; + if (snd_BUG_ON(spec->num_adc_nids >= + ARRAY_SIZE(spec->private_adc_nids))) + break; + spec->private_adc_nids[spec->num_adc_nids++] = nid; + } + spec->adc_nids = spec->private_adc_nids; + return 0; +} + + +static const struct hda_codec_ops cx_auto_patch_ops = { .build_controls = cx_auto_build_controls, .build_pcms = conexant_build_pcms, .init = cx_auto_init, @@ -3808,19 +4334,24 @@ static int patch_conexant_auto(struct hda_codec *codec) struct conexant_spec *spec; int err; + printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", + codec->chip_name); + spec = kzalloc(sizeof(*spec), GFP_KERNEL); if (!spec) return -ENOMEM; codec->spec = spec; - spec->adc_nids = cx_auto_adc_nids; - spec->num_adc_nids = ARRAY_SIZE(cx_auto_adc_nids); - spec->capsrc_nids = spec->adc_nids; + codec->pin_amp_workaround = 1; + err = cx_auto_search_adcs(codec); + if (err < 0) + return err; err = cx_auto_parse_auto_config(codec); if (err < 0) { kfree(codec->spec); codec->spec = NULL; return err; } + spec->capture_stream = &cx_auto_pcm_analog_capture; codec->patch_ops = cx_auto_patch_ops; if (spec->beep_amp) snd_hda_attach_beep_device(codec, spec->beep_amp); @@ -3830,7 +4361,7 @@ static int patch_conexant_auto(struct hda_codec *codec) /* */ -static struct hda_codec_preset snd_hda_preset_conexant[] = { +static const struct hda_codec_preset snd_hda_preset_conexant[] = { { .id = 0x14f15045, .name = "CX20549 (Venice)", .patch = patch_cxt5045 }, { .id = 0x14f15047, .name = "CX20551 (Waikiki)", diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c index 715615a88a8d..322901873222 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "hda_codec.h" #include "hda_local.h" @@ -76,7 +77,7 @@ struct hdmi_spec { * ati/nvhdmi specific */ struct hda_multi_out multiout; - struct hda_pcm_stream *pcm_playback; + const struct hda_pcm_stream *pcm_playback; /* misc flags */ /* PD bit indicates only the update, not the current state */ @@ -720,6 +721,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) &spec->sink_eld[index]); /* TODO: do real things about ELD */ } + + snd_hda_input_jack_report(codec, tag); } static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) @@ -912,6 +915,7 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) { struct hdmi_spec *spec = codec->spec; + int err; if (spec->num_pins >= MAX_HDMI_PINS) { snd_printk(KERN_WARNING @@ -919,6 +923,12 @@ static int hdmi_add_pin(struct hda_codec *codec, hda_nid_t pin_nid) return -E2BIG; } + err = snd_hda_input_jack_add(codec, pin_nid, + SND_JACK_VIDEOOUT, NULL); + if (err < 0) + return err; + snd_hda_input_jack_report(codec, pin_nid); + hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); spec->pin[spec->num_pins] = pin_nid; @@ -1044,7 +1054,7 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, return hdmi_setup_stream(codec, hinfo->nid, stream_tag, format); } -static struct hda_pcm_stream generic_hdmi_pcm_playback = { +static const struct hda_pcm_stream generic_hdmi_pcm_playback = { .substreams = 1, .channels_min = 2, .ops = { @@ -1120,11 +1130,12 @@ static void generic_hdmi_free(struct hda_codec *codec) for (i = 0; i < spec->num_pins; i++) snd_hda_eld_proc_free(codec, &spec->sink_eld[i]); + snd_hda_input_jack_free(codec); kfree(spec); } -static struct hda_codec_ops generic_hdmi_patch_ops = { +static const struct hda_codec_ops generic_hdmi_patch_ops = { .init = generic_hdmi_init, .free = generic_hdmi_free, .build_pcms = generic_hdmi_build_pcms, @@ -1169,12 +1180,12 @@ static int patch_generic_hdmi(struct hda_codec *codec) #define nvhdmi_master_con_nid_7x 0x04 #define nvhdmi_master_pin_nid_7x 0x05 -static hda_nid_t nvhdmi_con_nids_7x[4] = { +static const hda_nid_t nvhdmi_con_nids_7x[4] = { /*front, rear, clfe, rear_surr */ 0x6, 0x8, 0xa, 0xc, }; -static struct hda_verb nvhdmi_basic_init_7x[] = { +static const struct hda_verb nvhdmi_basic_init_7x[] = { /* set audio protect on */ { 0x1, Nv_VERB_SET_Audio_Protection_On, 0x1}, /* enable digital output on pin widget */ @@ -1435,7 +1446,7 @@ static int nvhdmi_8ch_7x_pcm_prepare(struct hda_pcm_stream *hinfo, return 0; } -static struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { +static const struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { .substreams = 1, .channels_min = 2, .channels_max = 8, @@ -1450,7 +1461,7 @@ static struct hda_pcm_stream nvhdmi_pcm_playback_8ch_7x = { }, }; -static struct hda_pcm_stream nvhdmi_pcm_playback_2ch = { +static const struct hda_pcm_stream nvhdmi_pcm_playback_2ch = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -1465,14 +1476,14 @@ static struct hda_pcm_stream nvhdmi_pcm_playback_2ch = { }, }; -static struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { +static const struct hda_codec_ops nvhdmi_patch_ops_8ch_7x = { .build_controls = generic_hdmi_build_controls, .build_pcms = generic_hdmi_build_pcms, .init = nvhdmi_7x_init, .free = generic_hdmi_free, }; -static struct hda_codec_ops nvhdmi_patch_ops_2ch = { +static const struct hda_codec_ops nvhdmi_patch_ops_2ch = { .build_controls = generic_hdmi_build_controls, .build_pcms = generic_hdmi_build_pcms, .init = nvhdmi_7x_init, @@ -1568,7 +1579,7 @@ static int atihdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo, return 0; } -static struct hda_pcm_stream atihdmi_pcm_digital_playback = { +static const struct hda_pcm_stream atihdmi_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -1580,7 +1591,7 @@ static struct hda_pcm_stream atihdmi_pcm_digital_playback = { }, }; -static struct hda_verb atihdmi_basic_init[] = { +static const struct hda_verb atihdmi_basic_init[] = { /* enable digital output on pin widget */ { 0x03, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, {} /* terminator */ @@ -1599,7 +1610,7 @@ static int atihdmi_init(struct hda_codec *codec) return 0; } -static struct hda_codec_ops atihdmi_patch_ops = { +static const struct hda_codec_ops atihdmi_patch_ops = { .build_controls = generic_hdmi_build_controls, .build_pcms = generic_hdmi_build_pcms, .init = atihdmi_init, @@ -1634,7 +1645,7 @@ static int patch_atihdmi(struct hda_codec *codec) /* * patch entries */ -static struct hda_codec_preset snd_hda_preset_hdmi[] = { +static const struct hda_codec_preset snd_hda_preset_hdmi[] = { { .id = 0x1002793c, .name = "RS600 HDMI", .patch = patch_atihdmi }, { .id = 0x10027919, .name = "RS600 HDMI", .patch = patch_atihdmi }, { .id = 0x1002791a, .name = "RS690/780 HDMI", .patch = patch_atihdmi }, @@ -1677,6 +1688,7 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = { { .id = 0x80862803, .name = "Eaglelake HDMI", .patch = patch_generic_hdmi }, { .id = 0x80862804, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, { .id = 0x80862805, .name = "CougarPoint HDMI", .patch = patch_generic_hdmi }, +{ .id = 0x80862806, .name = "PantherPoint HDMI", .patch = patch_generic_hdmi }, { .id = 0x808629fb, .name = "Crestline HDMI", .patch = patch_generic_hdmi }, {} /* terminator */ }; @@ -1722,6 +1734,7 @@ MODULE_ALIAS("snd-hda-codec-id:80862802"); MODULE_ALIAS("snd-hda-codec-id:80862803"); MODULE_ALIAS("snd-hda-codec-id:80862804"); MODULE_ALIAS("snd-hda-codec-id:80862805"); +MODULE_ALIAS("snd-hda-codec-id:80862806"); MODULE_ALIAS("snd-hda-codec-id:808629fb"); MODULE_LICENSE("GPL"); diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c index c82979a8cd09..7a4e10002f56 100644 --- a/sound/pci/hda/patch_realtek.c +++ b/sound/pci/hda/patch_realtek.c @@ -299,11 +299,23 @@ struct alc_customize_define { struct alc_fixup; +struct alc_multi_io { + hda_nid_t pin; /* multi-io widget pin NID */ + hda_nid_t dac; /* DAC to be connected */ + unsigned int ctl_in; /* cached input-pin control value */ +}; + +enum { + ALC_AUTOMUTE_PIN, /* change the pin control */ + ALC_AUTOMUTE_AMP, /* mute/unmute the pin AMP */ + ALC_AUTOMUTE_MIXER, /* mute/unmute mixer widget AMP */ +}; + struct alc_spec { /* codec parameterization */ - struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ + const struct snd_kcontrol_new *mixers[5]; /* mixer arrays */ unsigned int num_mixers; - struct snd_kcontrol_new *cap_mixer; /* capture mixer */ + const struct snd_kcontrol_new *cap_mixer; /* capture mixer */ unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ const struct hda_verb *init_verbs[10]; /* initialization verbs @@ -313,14 +325,14 @@ struct alc_spec { unsigned int num_init_verbs; char stream_name_analog[32]; /* analog PCM stream */ - struct hda_pcm_stream *stream_analog_playback; - struct hda_pcm_stream *stream_analog_capture; - struct hda_pcm_stream *stream_analog_alt_playback; - struct hda_pcm_stream *stream_analog_alt_capture; + const struct hda_pcm_stream *stream_analog_playback; + const struct hda_pcm_stream *stream_analog_capture; + const struct hda_pcm_stream *stream_analog_alt_playback; + const struct hda_pcm_stream *stream_analog_alt_capture; char stream_name_digital[32]; /* digital PCM stream */ - struct hda_pcm_stream *stream_digital_playback; - struct hda_pcm_stream *stream_digital_capture; + const struct hda_pcm_stream *stream_digital_playback; + const struct hda_pcm_stream *stream_digital_capture; /* playback */ struct hda_multi_out multiout; /* playback set-up @@ -333,8 +345,8 @@ struct alc_spec { /* capture */ unsigned int num_adc_nids; - hda_nid_t *adc_nids; - hda_nid_t *capsrc_nids; + const hda_nid_t *adc_nids; + const hda_nid_t *capsrc_nids; hda_nid_t dig_in_nid; /* digital-in NID; optional */ /* capture setup for dynamic dual-adc switch */ @@ -348,6 +360,7 @@ struct alc_spec { const struct hda_input_mux *input_mux; unsigned int cur_mux[3]; struct alc_mic_route ext_mic; + struct alc_mic_route dock_mic; struct alc_mic_route int_mic; /* channel model */ @@ -375,17 +388,27 @@ struct alc_spec { #ifdef CONFIG_SND_HDA_POWER_SAVE void (*power_hook)(struct hda_codec *codec); #endif + void (*shutup)(struct hda_codec *codec); /* for pin sensing */ - unsigned int sense_updated: 1; unsigned int jack_present: 1; - unsigned int master_sw: 1; + unsigned int line_jack_present:1; + unsigned int master_mute:1; unsigned int auto_mic:1; + unsigned int automute:1; /* HP automute enabled */ + unsigned int detect_line:1; /* Line-out detection enabled */ + unsigned int automute_lines:1; /* automute line-out as well */ + unsigned int automute_hp_lo:1; /* both HP and LO available */ /* other flags */ unsigned int no_analog :1; /* digital I/O only */ unsigned int dual_adc_switch:1; /* switch ADCs (for ALC275) */ unsigned int single_input_src:1; + + /* auto-mute control */ + int automute_mode; + hda_nid_t automute_mixer_nid[AUTO_CFG_MAX_OUTS]; + int init_amp; int codec_variant; /* flag for other variants */ @@ -403,25 +426,29 @@ struct alc_spec { int fixup_id; const struct alc_fixup *fixup_list; const char *fixup_name; + + /* multi-io */ + int multi_ios; + struct alc_multi_io multi_io[4]; }; /* * configuration template - to be copied to the spec instance */ struct alc_config_preset { - struct snd_kcontrol_new *mixers[5]; /* should be identical size + const struct snd_kcontrol_new *mixers[5]; /* should be identical size * with spec */ - struct snd_kcontrol_new *cap_mixer; /* capture mixer */ + const struct snd_kcontrol_new *cap_mixer; /* capture mixer */ const struct hda_verb *init_verbs[5]; unsigned int num_dacs; - hda_nid_t *dac_nids; + const hda_nid_t *dac_nids; hda_nid_t dig_out_nid; /* optional */ hda_nid_t hp_nid; /* optional */ - hda_nid_t *slave_dig_outs; + const hda_nid_t *slave_dig_outs; unsigned int num_adc_nids; - hda_nid_t *adc_nids; - hda_nid_t *capsrc_nids; + const hda_nid_t *adc_nids; + const hda_nid_t *capsrc_nids; hda_nid_t dig_in_nid; unsigned int num_channel_mode; const struct hda_channel_mode *channel_mode; @@ -433,7 +460,7 @@ struct alc_config_preset { void (*setup)(struct hda_codec *); void (*init_hook)(struct hda_codec *); #ifdef CONFIG_SND_HDA_POWER_SAVE - struct hda_amp_list *loopbacks; + const struct hda_amp_list *loopbacks; void (*power_hook)(struct hda_codec *codec); #endif }; @@ -560,11 +587,11 @@ static int alc_ch_mode_put(struct snd_kcontrol *kcontrol, * NIDs 0x0f and 0x10 have been observed to have this behaviour as of * March 2006. */ -static char *alc_pin_mode_names[] = { +static const char * const alc_pin_mode_names[] = { "Mic 50pc bias", "Mic 80pc bias", "Line in", "Line out", "Headphone out", }; -static unsigned char alc_pin_mode_values[] = { +static const unsigned char alc_pin_mode_values[] = { PIN_VREF50, PIN_VREF80, PIN_IN, PIN_OUT, PIN_HP, }; /* 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[] = { /* Info about the pin modes supported by the different pin direction modes. * For each direction the minimum and maximum values are given. */ -static signed char alc_pin_mode_dir_info[5][2] = { +static const signed char alc_pin_mode_dir_info[5][2] = { { 0, 2 }, /* ALC_PIN_DIR_IN */ { 3, 4 }, /* ALC_PIN_DIR_OUT */ { 0, 4 }, /* ALC_PIN_DIR_INOUT */ @@ -900,7 +927,7 @@ static void alc_fixup_autocfg_pin_nums(struct hda_codec *codec) /* */ -static void add_mixer(struct alc_spec *spec, struct snd_kcontrol_new *mix) +static void add_mixer(struct alc_spec *spec, const struct snd_kcontrol_new *mix) { if (snd_BUG_ON(spec->num_mixers >= ARRAY_SIZE(spec->mixers))) return; @@ -971,21 +998,21 @@ static void setup_preset(struct hda_codec *codec, } /* Enable GPIO mask and set output */ -static struct hda_verb alc_gpio1_init_verbs[] = { +static const struct hda_verb alc_gpio1_init_verbs[] = { {0x01, AC_VERB_SET_GPIO_MASK, 0x01}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x01}, {0x01, AC_VERB_SET_GPIO_DATA, 0x01}, { } }; -static struct hda_verb alc_gpio2_init_verbs[] = { +static const struct hda_verb alc_gpio2_init_verbs[] = { {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, { } }; -static struct hda_verb alc_gpio3_init_verbs[] = { +static const struct hda_verb alc_gpio3_init_verbs[] = { {0x01, AC_VERB_SET_GPIO_MASK, 0x03}, {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x03}, {0x01, AC_VERB_SET_GPIO_DATA, 0x03}, @@ -1031,6 +1058,7 @@ static int alc_init_jacks(struct hda_codec *codec) int err; unsigned int hp_nid = spec->autocfg.hp_pins[0]; unsigned int mic_nid = spec->ext_mic.pin; + unsigned int dock_nid = spec->dock_mic.pin; if (hp_nid) { err = snd_hda_input_jack_add(codec, hp_nid, @@ -1047,46 +1075,116 @@ static int alc_init_jacks(struct hda_codec *codec) return err; snd_hda_input_jack_report(codec, mic_nid); } + if (dock_nid) { + err = snd_hda_input_jack_add(codec, dock_nid, + SND_JACK_MICROPHONE, NULL); + if (err < 0) + return err; + snd_hda_input_jack_report(codec, dock_nid); + } #endif /* CONFIG_SND_HDA_INPUT_JACK */ return 0; } -static void alc_automute_speaker(struct hda_codec *codec, int pinctl) +static int detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) { - struct alc_spec *spec = codec->spec; - unsigned int mute; - hda_nid_t nid; - int i; + int i, present = 0; - spec->jack_present = 0; - for (i = 0; i < ARRAY_SIZE(spec->autocfg.hp_pins); i++) { - nid = spec->autocfg.hp_pins[i]; + for (i = 0; i < num_pins; i++) { + hda_nid_t nid = pins[i]; if (!nid) break; snd_hda_input_jack_report(codec, nid); - spec->jack_present |= snd_hda_jack_detect(codec, nid); + present |= snd_hda_jack_detect(codec, nid); } + return present; +} - mute = spec->jack_present ? HDA_AMP_MUTE : 0; - /* Toggle internal speakers muting */ - for (i = 0; i < ARRAY_SIZE(spec->autocfg.speaker_pins); i++) { - nid = spec->autocfg.speaker_pins[i]; +static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, + bool mute, bool hp_out) +{ + struct alc_spec *spec = codec->spec; + unsigned int mute_bits = mute ? HDA_AMP_MUTE : 0; + unsigned int pin_bits = mute ? 0 : (hp_out ? PIN_HP : PIN_OUT); + int i; + + for (i = 0; i < num_pins; i++) { + hda_nid_t nid = pins[i]; if (!nid) break; - if (pinctl) { + switch (spec->automute_mode) { + case ALC_AUTOMUTE_PIN: snd_hda_codec_write(codec, nid, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - spec->jack_present ? 0 : PIN_OUT); - } else { + AC_VERB_SET_PIN_WIDGET_CONTROL, + pin_bits); + break; + case ALC_AUTOMUTE_AMP: snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); + HDA_AMP_MUTE, mute_bits); + break; + case ALC_AUTOMUTE_MIXER: + nid = spec->automute_mixer_nid[i]; + if (!nid) + break; + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 0, + HDA_AMP_MUTE, mute_bits); + snd_hda_codec_amp_stereo(codec, nid, HDA_INPUT, 1, + HDA_AMP_MUTE, mute_bits); + break; } } } -static void alc_automute_pin(struct hda_codec *codec) +/* Toggle internal speakers muting */ +static void update_speakers(struct hda_codec *codec) { - alc_automute_speaker(codec, 1); + struct alc_spec *spec = codec->spec; + int on; + + if (!spec->automute) + on = 0; + else + on = spec->jack_present | spec->line_jack_present; + on |= spec->master_mute; + do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), + spec->autocfg.speaker_pins, on, false); + + /* toggle line-out mutes if needed, too */ + /* if LO is a copy of either HP or Speaker, don't need to handle it */ + if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] || + spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0]) + return; + if (!spec->automute_lines || !spec->automute) + on = 0; + else + on = spec->jack_present; + on |= spec->master_mute; + do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), + spec->autocfg.line_out_pins, on, false); +} + +static void alc_hp_automute(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + + if (!spec->automute) + return; + spec->jack_present = + detect_jacks(codec, ARRAY_SIZE(spec->autocfg.hp_pins), + spec->autocfg.hp_pins); + update_speakers(codec); +} + +static void alc_line_automute(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + + if (!spec->automute || !spec->detect_line) + return; + spec->line_jack_present = + detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), + spec->autocfg.line_out_pins); + update_speakers(codec); } 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) static void alc_mic_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - struct alc_mic_route *dead, *alive; + struct alc_mic_route *dead1, *dead2, *alive; unsigned int present, type; hda_nid_t cap_nid; @@ -1146,13 +1244,24 @@ static void alc_mic_automute(struct hda_codec *codec) cap_nid = spec->capsrc_nids ? spec->capsrc_nids[0] : spec->adc_nids[0]; + alive = &spec->int_mic; + dead1 = &spec->ext_mic; + dead2 = &spec->dock_mic; + present = snd_hda_jack_detect(codec, spec->ext_mic.pin); if (present) { alive = &spec->ext_mic; - dead = &spec->int_mic; - } else { - alive = &spec->int_mic; - dead = &spec->ext_mic; + dead1 = &spec->int_mic; + dead2 = &spec->dock_mic; + } + if (!present && spec->dock_mic.pin > 0) { + present = snd_hda_jack_detect(codec, spec->dock_mic.pin); + if (present) { + alive = &spec->dock_mic; + dead1 = &spec->int_mic; + dead2 = &spec->ext_mic; + } + snd_hda_input_jack_report(codec, spec->dock_mic.pin); } type = get_wcaps_type(get_wcaps(codec, cap_nid)); @@ -1161,9 +1270,14 @@ static void alc_mic_automute(struct hda_codec *codec) snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, alive->mux_idx, HDA_AMP_MUTE, 0); - snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, - dead->mux_idx, - HDA_AMP_MUTE, HDA_AMP_MUTE); + if (dead1->pin > 0) + snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, + dead1->mux_idx, + HDA_AMP_MUTE, HDA_AMP_MUTE); + if (dead2->pin > 0) + snd_hda_codec_amp_stereo(codec, cap_nid, HDA_INPUT, + dead2->mux_idx, + HDA_AMP_MUTE, HDA_AMP_MUTE); } else { /* MUX style (e.g. ALC880) */ 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) res >>= 26; switch (res) { case ALC880_HP_EVENT: - alc_automute_pin(codec); + alc_hp_automute(codec); + break; + case ALC880_FRONT_EVENT: + alc_line_automute(codec); break; case ALC880_MIC_EVENT: alc_mic_automute(codec); @@ -1194,7 +1311,8 @@ static void alc_sku_unsol_event(struct hda_codec *codec, unsigned int res) static void alc_inithook(struct hda_codec *codec) { - alc_automute_pin(codec); + alc_hp_automute(codec); + alc_line_automute(codec); alc_mic_automute(codec); } @@ -1236,6 +1354,43 @@ static void set_eapd(struct hda_codec *codec, hda_nid_t nid, int on) on ? 2 : 0); } +/* turn on/off EAPD controls of the codec */ +static void alc_auto_setup_eapd(struct hda_codec *codec, bool on) +{ + /* We currently only handle front, HP */ + switch (codec->vendor_id) { + case 0x10ec0260: + set_eapd(codec, 0x0f, on); + set_eapd(codec, 0x10, on); + break; + case 0x10ec0262: + case 0x10ec0267: + case 0x10ec0268: + case 0x10ec0269: + case 0x10ec0270: + case 0x10ec0272: + case 0x10ec0660: + case 0x10ec0662: + case 0x10ec0663: + case 0x10ec0665: + case 0x10ec0862: + case 0x10ec0889: + case 0x10ec0892: + set_eapd(codec, 0x14, on); + set_eapd(codec, 0x15, on); + break; + } +} + +/* generic shutup callback; + * just turning off EPAD and a little pause for avoiding pop-noise + */ +static void alc_eapd_shutup(struct hda_codec *codec) +{ + alc_auto_setup_eapd(codec, false); + msleep(200); +} + static void alc_auto_init_amp(struct hda_codec *codec, int type) { unsigned int tmp; @@ -1251,27 +1406,7 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) snd_hda_sequence_write(codec, alc_gpio3_init_verbs); break; case ALC_INIT_DEFAULT: - switch (codec->vendor_id) { - case 0x10ec0260: - set_eapd(codec, 0x0f, 1); - set_eapd(codec, 0x10, 1); - break; - case 0x10ec0262: - case 0x10ec0267: - case 0x10ec0268: - case 0x10ec0269: - case 0x10ec0270: - case 0x10ec0272: - case 0x10ec0660: - case 0x10ec0662: - case 0x10ec0663: - case 0x10ec0665: - case 0x10ec0862: - case 0x10ec0889: - set_eapd(codec, 0x14, 1); - set_eapd(codec, 0x15, 1); - break; - } + alc_auto_setup_eapd(codec, true); switch (codec->vendor_id) { case 0x10ec0260: snd_hda_codec_write(codec, 0x1a, 0, @@ -1315,20 +1450,128 @@ static void alc_auto_init_amp(struct hda_codec *codec, int type) } } +static int alc_automute_mode_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + static const char * const texts2[] = { + "Disabled", "Enabled" + }; + static const char * const texts3[] = { + "Disabled", "Speaker Only", "Line-Out+Speaker" + }; + const char * const *texts; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + if (spec->automute_hp_lo) { + uinfo->value.enumerated.items = 3; + texts = texts3; + } else { + uinfo->value.enumerated.items = 2; + texts = texts2; + } + if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) + uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; + strcpy(uinfo->value.enumerated.name, + texts[uinfo->value.enumerated.item]); + return 0; +} + +static int alc_automute_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + unsigned int val; + if (!spec->automute) + val = 0; + else if (!spec->automute_lines) + val = 1; + else + val = 2; + ucontrol->value.enumerated.item[0] = val; + return 0; +} + +static int alc_automute_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + + switch (ucontrol->value.enumerated.item[0]) { + case 0: + if (!spec->automute) + return 0; + spec->automute = 0; + break; + case 1: + if (spec->automute && !spec->automute_lines) + return 0; + spec->automute = 1; + spec->automute_lines = 0; + break; + case 2: + if (!spec->automute_hp_lo) + return -EINVAL; + if (spec->automute && spec->automute_lines) + return 0; + spec->automute = 1; + spec->automute_lines = 1; + break; + default: + return -EINVAL; + } + update_speakers(codec); + return 1; +} + +static const struct snd_kcontrol_new alc_automute_mode_enum = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Auto-Mute Mode", + .info = alc_automute_mode_info, + .get = alc_automute_mode_get, + .put = alc_automute_mode_put, +}; + +static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec); + +static int alc_add_automute_mode_enum(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + struct snd_kcontrol_new *knew; + + knew = alc_kcontrol_new(spec); + if (!knew) + return -ENOMEM; + *knew = alc_automute_mode_enum; + knew->name = kstrdup("Auto-Mute Mode", GFP_KERNEL); + if (!knew->name) + return -ENOMEM; + return 0; +} + static void alc_init_auto_hp(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; + int present = 0; int i; - if (!cfg->hp_pins[0]) { - if (cfg->line_out_type != AUTO_PIN_HP_OUT) - return; - } + if (cfg->hp_pins[0]) + present++; + if (cfg->line_out_pins[0]) + present++; + if (cfg->speaker_pins[0]) + present++; + if (present < 2) /* need two different output types */ + return; + if (present == 3) + spec->automute_hp_lo = 1; /* both HP and LO automute */ if (!cfg->speaker_pins[0]) { - if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) - return; memcpy(cfg->speaker_pins, cfg->line_out_pins, sizeof(cfg->speaker_pins)); cfg->speaker_outs = cfg->line_outs; @@ -1341,28 +1584,49 @@ static void alc_init_auto_hp(struct hda_codec *codec) } for (i = 0; i < cfg->hp_outs; i++) { + hda_nid_t nid = cfg->hp_pins[i]; + if (!is_jack_detectable(codec, nid)) + continue; snd_printdd("realtek: Enable HP auto-muting on NID 0x%x\n", - cfg->hp_pins[i]); - snd_hda_codec_write_cache(codec, cfg->hp_pins[i], 0, + nid); + snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT); + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; + } + if (spec->automute && cfg->line_out_pins[0] && + cfg->line_out_pins[0] != cfg->hp_pins[0] && + cfg->line_out_pins[0] != cfg->speaker_pins[0]) { + for (i = 0; i < cfg->line_outs; i++) { + hda_nid_t nid = cfg->line_out_pins[i]; + if (!is_jack_detectable(codec, nid)) + continue; + snd_printdd("realtek: Enable Line-Out auto-muting " + "on NID 0x%x\n", nid); + snd_hda_codec_write_cache(codec, nid, 0, + AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | ALC880_FRONT_EVENT); + spec->detect_line = 1; + } + spec->automute_lines = spec->detect_line; + } + + if (spec->automute) { + /* create a control for automute mode */ + alc_add_automute_mode_enum(codec); + spec->unsol_event = alc_sku_unsol_event; } - spec->unsol_event = alc_sku_unsol_event; } static void alc_init_auto_mic(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct auto_pin_cfg *cfg = &spec->autocfg; - hda_nid_t fixed, ext; + hda_nid_t fixed, ext, dock; int i; - /* there must be only two mic inputs exclusively */ - for (i = 0; i < cfg->num_inputs; i++) - if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) - return; - - fixed = ext = 0; + fixed = ext = dock = 0; for (i = 0; i < cfg->num_inputs; i++) { hda_nid_t nid = cfg->inputs[i].pin; unsigned int defcfg; @@ -1371,26 +1635,45 @@ static void alc_init_auto_mic(struct hda_codec *codec) case INPUT_PIN_ATTR_INT: if (fixed) return; /* already occupied */ + if (cfg->inputs[i].type != AUTO_PIN_MIC) + return; /* invalid type */ fixed = nid; break; case INPUT_PIN_ATTR_UNUSED: return; /* invalid entry */ + case INPUT_PIN_ATTR_DOCK: + if (dock) + return; /* already occupied */ + if (cfg->inputs[i].type > AUTO_PIN_LINE_IN) + return; /* invalid type */ + dock = nid; + break; default: if (ext) return; /* already occupied */ + if (cfg->inputs[i].type != AUTO_PIN_MIC) + return; /* invalid type */ ext = nid; break; } } + if (!ext && dock) { + ext = dock; + dock = 0; + } if (!ext || !fixed) return; - if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) + if (!is_jack_detectable(codec, ext)) return; /* no unsol support */ - snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", - ext, fixed); + if (dock && !is_jack_detectable(codec, dock)) + return; /* no unsol support */ + snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n", + ext, fixed, dock); spec->ext_mic.pin = ext; + spec->dock_mic.pin = dock; spec->int_mic.pin = fixed; spec->ext_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ + spec->dock_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ spec->int_mic.mux_idx = MUX_IDX_UNDEF; /* set later */ spec->auto_mic = 1; snd_hda_codec_write_cache(codec, spec->ext_mic.pin, 0, @@ -1583,9 +1866,6 @@ static int alc_subsystem_id(struct hda_codec *codec, return 1; spec->autocfg.hp_pins[0] = nid; } - - alc_init_auto_hp(codec); - alc_init_auto_mic(codec); return 1; } @@ -1598,9 +1878,10 @@ static void alc_ssid_check(struct hda_codec *codec, snd_printd("realtek: " "Enable default setup for auto mode as fallback\n"); spec->init_amp = ALC_INIT_DEFAULT; - alc_init_auto_hp(codec); - alc_init_auto_mic(codec); } + + alc_init_auto_hp(codec); + alc_init_auto_mic(codec); } /* @@ -1842,7 +2123,7 @@ static void alc_auto_parse_digital(struct hda_codec *codec) /* * 2ch mode */ -static struct hda_verb alc888_4ST_ch2_intel_init[] = { +static const struct hda_verb alc888_4ST_ch2_intel_init[] = { /* Mic-in jack as mic in */ { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -1857,7 +2138,7 @@ static struct hda_verb alc888_4ST_ch2_intel_init[] = { /* * 4ch mode */ -static struct hda_verb alc888_4ST_ch4_intel_init[] = { +static const struct hda_verb alc888_4ST_ch4_intel_init[] = { /* Mic-in jack as mic in */ { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -1872,7 +2153,7 @@ static struct hda_verb alc888_4ST_ch4_intel_init[] = { /* * 6ch mode */ -static struct hda_verb alc888_4ST_ch6_intel_init[] = { +static const struct hda_verb alc888_4ST_ch6_intel_init[] = { /* Mic-in jack as CLFE */ { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -1887,7 +2168,7 @@ static struct hda_verb alc888_4ST_ch6_intel_init[] = { /* * 8ch mode */ -static struct hda_verb alc888_4ST_ch8_intel_init[] = { +static const struct hda_verb alc888_4ST_ch8_intel_init[] = { /* Mic-in jack as CLFE */ { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -1899,7 +2180,7 @@ static struct hda_verb alc888_4ST_ch8_intel_init[] = { { } /* end */ }; -static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { +static const struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { { 2, alc888_4ST_ch2_intel_init }, { 4, alc888_4ST_ch4_intel_init }, { 6, alc888_4ST_ch6_intel_init }, @@ -1910,7 +2191,7 @@ static struct hda_channel_mode alc888_4ST_8ch_intel_modes[4] = { * ALC888 Fujitsu Siemens Amillo xa3530 */ -static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { +static const struct hda_verb alc888_fujitsu_xa3530_verbs[] = { /* Front Mic: set to PIN_IN (empty by default) */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Connect Internal HP to Front */ @@ -1943,22 +2224,6 @@ static struct hda_verb alc888_fujitsu_xa3530_verbs[] = { {} }; -static void alc_automute_amp(struct hda_codec *codec) -{ - alc_automute_speaker(codec, 0); -} - -static void alc_automute_amp_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if (codec->vendor_id == 0x10ec0880) - res >>= 28; - else - res >>= 26; - if (res == ALC880_HP_EVENT) - alc_automute_amp(codec); -} - static void alc889_automute_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; @@ -1969,12 +2234,14 @@ static void alc889_automute_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[2] = 0x17; spec->autocfg.speaker_pins[3] = 0x19; spec->autocfg.speaker_pins[4] = 0x1a; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc889_intel_init_hook(struct hda_codec *codec) { alc889_coef_init(codec); - alc_automute_amp(codec); + alc_hp_automute(codec); } static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) @@ -1985,13 +2252,15 @@ static void alc888_fujitsu_xa3530_setup(struct hda_codec *codec) spec->autocfg.hp_pins[1] = 0x1b; /* hp */ spec->autocfg.speaker_pins[0] = 0x14; /* speaker */ spec->autocfg.speaker_pins[1] = 0x15; /* bass */ + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } /* * ALC888 Acer Aspire 4930G model */ -static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { +static const struct hda_verb alc888_acer_aspire_4930g_verbs[] = { /* Front Mic: set to PIN_IN (empty by default) */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Unselect Front Mic by default in input mixer 3 */ @@ -2014,7 +2283,7 @@ static struct hda_verb alc888_acer_aspire_4930g_verbs[] = { * ALC888 Acer Aspire 6530G model */ -static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { +static const struct hda_verb alc888_acer_aspire_6530g_verbs[] = { /* Route to built-in subwoofer as well as speakers */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -2044,7 +2313,7 @@ static struct hda_verb alc888_acer_aspire_6530g_verbs[] = { *ALC888 Acer Aspire 7730G model */ -static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { +static const struct hda_verb alc888_acer_aspire_7730G_verbs[] = { /* Bias voltage on for external mic port */ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN | PIN_VREF80}, /* Front Mic: set to PIN_IN (empty by default) */ @@ -2074,7 +2343,7 @@ static struct hda_verb alc888_acer_aspire_7730G_verbs[] = { * ALC889 Acer Aspire 8930G model */ -static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { +static const struct hda_verb alc889_acer_aspire_8930g_verbs[] = { /* Front Mic: set to PIN_IN (empty by default) */ {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Unselect Front Mic by default in input mixer 3 */ @@ -2120,7 +2389,7 @@ static struct hda_verb alc889_acer_aspire_8930g_verbs[] = { { } }; -static struct hda_input_mux alc888_2_capture_sources[2] = { +static const struct hda_input_mux alc888_2_capture_sources[2] = { /* Front mic only available on one ADC */ { .num_items = 4, @@ -2141,7 +2410,7 @@ static struct hda_input_mux alc888_2_capture_sources[2] = { } }; -static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { +static const struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { /* Interal mic only available on one ADC */ { .num_items = 5, @@ -2164,7 +2433,7 @@ static struct hda_input_mux alc888_acer_aspire_6530_sources[2] = { } }; -static struct hda_input_mux alc889_capture_sources[3] = { +static const struct hda_input_mux alc889_capture_sources[3] = { /* Digital mic only available on first "ADC" */ { .num_items = 5, @@ -2196,7 +2465,7 @@ static struct hda_input_mux alc889_capture_sources[3] = { } }; -static struct snd_kcontrol_new alc888_base_mixer[] = { +static const struct snd_kcontrol_new alc888_base_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2218,7 +2487,7 @@ static struct snd_kcontrol_new alc888_base_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { +static const struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2240,7 +2509,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_4930g_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { +static const struct snd_kcontrol_new alc889_acer_aspire_8930g_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), 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) spec->autocfg.speaker_pins[0] = 0x14; spec->autocfg.speaker_pins[1] = 0x16; spec->autocfg.speaker_pins[2] = 0x17; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } 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) spec->autocfg.speaker_pins[0] = 0x14; spec->autocfg.speaker_pins[1] = 0x16; spec->autocfg.speaker_pins[2] = 0x17; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } 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) spec->autocfg.speaker_pins[0] = 0x14; spec->autocfg.speaker_pins[1] = 0x16; spec->autocfg.speaker_pins[2] = 0x17; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } 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) spec->autocfg.speaker_pins[0] = 0x14; spec->autocfg.speaker_pins[1] = 0x16; spec->autocfg.speaker_pins[2] = 0x1b; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } /* @@ -2307,12 +2584,12 @@ static void alc889_acer_aspire_8930g_setup(struct hda_codec *codec) * F-Mic = 0x1b, HP = 0x19 */ -static hda_nid_t alc880_dac_nids[4] = { +static const hda_nid_t alc880_dac_nids[4] = { /* front, rear, clfe, rear_surr */ 0x02, 0x05, 0x04, 0x03 }; -static hda_nid_t alc880_adc_nids[3] = { +static const hda_nid_t alc880_adc_nids[3] = { /* ADC0-2 */ 0x07, 0x08, 0x09, }; @@ -2321,7 +2598,7 @@ static hda_nid_t alc880_adc_nids[3] = { * but it shows zero connection in the real implementation on some devices. * Note: this is a 915GAV bug, fixed on 915GLV */ -static hda_nid_t alc880_adc_nids_alt[2] = { +static const hda_nid_t alc880_adc_nids_alt[2] = { /* ADC1-2 */ 0x08, 0x09, }; @@ -2329,7 +2606,7 @@ static hda_nid_t alc880_adc_nids_alt[2] = { #define ALC880_DIGOUT_NID 0x06 #define ALC880_DIGIN_NID 0x0a -static struct hda_input_mux alc880_capture_source = { +static const struct hda_input_mux alc880_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -2341,7 +2618,7 @@ static struct hda_input_mux alc880_capture_source = { /* channel source setting (2/6 channel selection for 3-stack) */ /* 2ch mode */ -static struct hda_verb alc880_threestack_ch2_init[] = { +static const struct hda_verb alc880_threestack_ch2_init[] = { /* set line-in to input, mute it */ { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -2352,7 +2629,7 @@ static struct hda_verb alc880_threestack_ch2_init[] = { }; /* 6ch mode */ -static struct hda_verb alc880_threestack_ch6_init[] = { +static const struct hda_verb alc880_threestack_ch6_init[] = { /* set line-in to output, unmute it */ { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -2362,12 +2639,12 @@ static struct hda_verb alc880_threestack_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode alc880_threestack_modes[2] = { +static const struct hda_channel_mode alc880_threestack_modes[2] = { { 2, alc880_threestack_ch2_init }, { 6, alc880_threestack_ch6_init }, }; -static struct snd_kcontrol_new alc880_three_stack_mixer[] = { +static const struct snd_kcontrol_new alc880_three_stack_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), @@ -2512,14 +2789,14 @@ static int alc_cap_sw_put(struct snd_kcontrol *kcontrol, } #define DEFINE_CAPMIX(num) \ -static struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ +static const struct snd_kcontrol_new alc_capture_mixer ## num[] = { \ _DEFINE_CAPMIX(num), \ _DEFINE_CAPSRC(num), \ { } /* end */ \ } #define DEFINE_CAPMIX_NOSRC(num) \ -static struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ +static const struct snd_kcontrol_new alc_capture_mixer_nosrc ## num[] = { \ _DEFINE_CAPMIX(num), \ { } /* end */ \ } @@ -2542,7 +2819,7 @@ DEFINE_CAPMIX_NOSRC(3); */ /* additional mixers to alc880_three_stack_mixer */ -static struct snd_kcontrol_new alc880_five_stack_mixer[] = { +static const struct snd_kcontrol_new alc880_five_stack_mixer[] = { HDA_CODEC_VOLUME("Side Playback Volume", 0x0d, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Side Playback Switch", 0x0d, 2, HDA_INPUT), { } /* end */ @@ -2550,7 +2827,7 @@ static struct snd_kcontrol_new alc880_five_stack_mixer[] = { /* channel source setting (6/8 channel selection for 5-stack) */ /* 6ch mode */ -static struct hda_verb alc880_fivestack_ch6_init[] = { +static const struct hda_verb alc880_fivestack_ch6_init[] = { /* set line-in to input, mute it */ { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -2558,14 +2835,14 @@ static struct hda_verb alc880_fivestack_ch6_init[] = { }; /* 8ch mode */ -static struct hda_verb alc880_fivestack_ch8_init[] = { +static const struct hda_verb alc880_fivestack_ch8_init[] = { /* set line-in to output, unmute it */ { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, { } /* end */ }; -static struct hda_channel_mode alc880_fivestack_modes[2] = { +static const struct hda_channel_mode alc880_fivestack_modes[2] = { { 6, alc880_fivestack_ch6_init }, { 8, alc880_fivestack_ch8_init }, }; @@ -2580,12 +2857,12 @@ static struct hda_channel_mode alc880_fivestack_modes[2] = { * Mic = 0x18, F-Mic = 0x19, Line = 0x1a, HP = 0x1b */ -static hda_nid_t alc880_6st_dac_nids[4] = { +static const hda_nid_t alc880_6st_dac_nids[4] = { /* front, rear, clfe, rear_surr */ 0x02, 0x03, 0x04, 0x05 }; -static struct hda_input_mux alc880_6stack_capture_source = { +static const struct hda_input_mux alc880_6stack_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -2596,11 +2873,11 @@ static struct hda_input_mux alc880_6stack_capture_source = { }; /* fixed 8-channels */ -static struct hda_channel_mode alc880_sixstack_modes[1] = { +static const struct hda_channel_mode alc880_sixstack_modes[1] = { { 8, NULL }, }; -static struct snd_kcontrol_new alc880_six_stack_mixer[] = { +static const struct snd_kcontrol_new alc880_six_stack_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2655,18 +2932,18 @@ static struct snd_kcontrol_new alc880_six_stack_mixer[] = { * haven't setup any initialization verbs for these yet... */ -static hda_nid_t alc880_w810_dac_nids[3] = { +static const hda_nid_t alc880_w810_dac_nids[3] = { /* front, rear/surround, clfe */ 0x02, 0x03, 0x04 }; /* fixed 6 channels */ -static struct hda_channel_mode alc880_w810_modes[1] = { +static const struct hda_channel_mode alc880_w810_modes[1] = { { 6, NULL } }; /* Pin assignment: Front = 0x14, Surr = 0x15, CLFE = 0x16, HP = 0x1b */ -static struct snd_kcontrol_new alc880_w810_base_mixer[] = { +static const struct snd_kcontrol_new alc880_w810_base_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2688,17 +2965,17 @@ static struct snd_kcontrol_new alc880_w810_base_mixer[] = { * Line = 0x1a */ -static hda_nid_t alc880_z71v_dac_nids[1] = { +static const hda_nid_t alc880_z71v_dac_nids[1] = { 0x02 }; #define ALC880_Z71V_HP_DAC 0x03 /* fixed 2 channels */ -static struct hda_channel_mode alc880_2_jack_modes[1] = { +static const struct hda_channel_mode alc880_2_jack_modes[1] = { { 2, NULL } }; -static struct snd_kcontrol_new alc880_z71v_mixer[] = { +static const struct snd_kcontrol_new alc880_z71v_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2718,12 +2995,12 @@ static struct snd_kcontrol_new alc880_z71v_mixer[] = { * Pin assignment: HP = 0x14, Front = 0x15, Mic = 0x18 */ -static hda_nid_t alc880_f1734_dac_nids[1] = { +static const hda_nid_t alc880_f1734_dac_nids[1] = { 0x03 }; #define ALC880_F1734_HP_DAC 0x02 -static struct snd_kcontrol_new alc880_f1734_mixer[] = { +static const struct snd_kcontrol_new alc880_f1734_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2735,7 +3012,7 @@ static struct snd_kcontrol_new alc880_f1734_mixer[] = { { } /* end */ }; -static struct hda_input_mux alc880_f1734_capture_source = { +static const struct hda_input_mux alc880_f1734_capture_source = { .num_items = 2, .items = { { "Mic", 0x1 }, @@ -2755,7 +3032,7 @@ static struct hda_input_mux alc880_f1734_capture_source = { #define alc880_asus_dac_nids alc880_w810_dac_nids /* identical with w810 */ #define alc880_asus_modes alc880_threestack_modes /* 2/6 channel mode */ -static struct snd_kcontrol_new alc880_asus_mixer[] = { +static const struct snd_kcontrol_new alc880_asus_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2789,14 +3066,14 @@ static struct snd_kcontrol_new alc880_asus_mixer[] = { */ /* additional mixers to alc880_asus_mixer */ -static struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { +static const struct snd_kcontrol_new alc880_asus_w1v_mixer[] = { HDA_CODEC_VOLUME("Line2 Playback Volume", 0x0b, 0x03, HDA_INPUT), HDA_CODEC_MUTE("Line2 Playback Switch", 0x0b, 0x03, HDA_INPUT), { } /* end */ }; /* TCL S700 */ -static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { +static const struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -2810,7 +3087,7 @@ static struct snd_kcontrol_new alc880_tcl_s700_mixer[] = { }; /* Uniwill */ -static struct snd_kcontrol_new alc880_uniwill_mixer[] = { +static const struct snd_kcontrol_new alc880_uniwill_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2837,7 +3114,7 @@ static struct snd_kcontrol_new alc880_uniwill_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { +static const struct snd_kcontrol_new alc880_fujitsu_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2851,7 +3128,7 @@ static struct snd_kcontrol_new alc880_fujitsu_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { +static const struct snd_kcontrol_new alc880_uniwill_p53_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -2878,7 +3155,6 @@ static const char * const alc_slave_vols[] = { "Speaker Playback Volume", "Mono Playback Volume", "Line-Out Playback Volume", - "PCM Playback Volume", NULL, }; @@ -2893,7 +3169,6 @@ static const char * const alc_slave_sws[] = { "Mono Playback Switch", "IEC958 Playback Switch", "Line-Out Playback Switch", - "PCM Playback Switch", NULL, }; @@ -2914,7 +3189,7 @@ static void alc_free_kctls(struct hda_codec *codec); #ifdef CONFIG_SND_HDA_INPUT_BEEP /* additional beep mixers; the actual parameters are overwritten at build */ -static struct snd_kcontrol_new alc_beep_mixer[] = { +static const struct snd_kcontrol_new alc_beep_mixer[] = { HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_INPUT), HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_INPUT), { } /* end */ @@ -2925,7 +3200,7 @@ static int alc_build_controls(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; struct snd_kcontrol *kctl = NULL; - struct snd_kcontrol_new *knew; + const struct snd_kcontrol_new *knew; int i, j, err; unsigned int u; hda_nid_t nid; @@ -2962,7 +3237,7 @@ static int alc_build_controls(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_INPUT_BEEP /* create beep controls if needed */ if (spec->beep_amp) { - struct snd_kcontrol_new *knew; + const struct snd_kcontrol_new *knew; for (knew = alc_beep_mixer; knew->name; knew++) { struct snd_kcontrol *kctl; kctl = snd_ctl_new1(knew, codec); @@ -3001,7 +3276,7 @@ static int alc_build_controls(struct hda_codec *codec) if (!kctl) kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); for (i = 0; kctl && i < kctl->count; i++) { - hda_nid_t *nids = spec->capsrc_nids; + const hda_nid_t *nids = spec->capsrc_nids; if (!nids) nids = spec->adc_nids; err = snd_hda_add_nid(codec, kctl, i, nids[i]); @@ -3079,7 +3354,7 @@ static int alc_build_controls(struct hda_codec *codec) /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc880_volume_init_verbs[] = { +static const struct hda_verb alc880_volume_init_verbs[] = { /* * Unmute ADC0-2 and set the default input to mic-in */ @@ -3130,7 +3405,7 @@ static struct hda_verb alc880_volume_init_verbs[] = { * 3-stack pin configuration: * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b */ -static struct hda_verb alc880_pin_3stack_init_verbs[] = { +static const struct hda_verb alc880_pin_3stack_init_verbs[] = { /* * preset connection lists of input pins * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround @@ -3168,7 +3443,7 @@ static struct hda_verb alc880_pin_3stack_init_verbs[] = { * front = 0x14, surround = 0x17, clfe = 0x16, mic = 0x18, HP = 0x19, * line-in/side = 0x1a, f-mic = 0x1b */ -static struct hda_verb alc880_pin_5stack_init_verbs[] = { +static const struct hda_verb alc880_pin_5stack_init_verbs[] = { /* * preset connection lists of input pins * 0 = front, 1 = rear_surr, 2 = CLFE, 3 = surround @@ -3212,7 +3487,7 @@ static struct hda_verb alc880_pin_5stack_init_verbs[] = { * W810 pin configuration: * front = 0x14, surround = 0x15, clfe = 0x16, HP = 0x1b */ -static struct hda_verb alc880_pin_w810_init_verbs[] = { +static const struct hda_verb alc880_pin_w810_init_verbs[] = { /* hphone/speaker input selector: front DAC */ {0x13, AC_VERB_SET_CONNECT_SEL, 0x0}, @@ -3233,7 +3508,7 @@ static struct hda_verb alc880_pin_w810_init_verbs[] = { * Z71V pin configuration: * Speaker-out = 0x14, HP = 0x15, Mic = 0x18, Line-in = 0x1a, Mic2 = 0x1b (?) */ -static struct hda_verb alc880_pin_z71v_init_verbs[] = { +static const struct hda_verb alc880_pin_z71v_init_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -3252,7 +3527,7 @@ static struct hda_verb alc880_pin_z71v_init_verbs[] = { * front = 0x14, surr = 0x15, clfe = 0x16, side = 0x17, mic = 0x18, * f-mic = 0x19, line = 0x1a, HP = 0x1b */ -static struct hda_verb alc880_pin_6stack_init_verbs[] = { +static const struct hda_verb alc880_pin_6stack_init_verbs[] = { {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -3282,7 +3557,7 @@ static struct hda_verb alc880_pin_6stack_init_verbs[] = { * HP = 0x14, InternalSpeaker = 0x15, mic = 0x18, internal mic = 0x19, * line = 0x1a */ -static struct hda_verb alc880_uniwill_init_verbs[] = { +static const struct hda_verb alc880_uniwill_init_verbs[] = { {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -3320,7 +3595,7 @@ static struct hda_verb alc880_uniwill_init_verbs[] = { * Uniwill P53 * HP = 0x14, InternalSpeaker = 0x15, mic = 0x19, */ -static struct hda_verb alc880_uniwill_p53_init_verbs[] = { +static const struct hda_verb alc880_uniwill_p53_init_verbs[] = { {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -3349,7 +3624,7 @@ static struct hda_verb alc880_uniwill_p53_init_verbs[] = { { } }; -static struct hda_verb alc880_beep_init_verbs[] = { +static const struct hda_verb alc880_beep_init_verbs[] = { { 0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) }, { } }; @@ -3372,11 +3647,13 @@ static void alc880_uniwill_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x16; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc880_uniwill_init_hook(struct hda_codec *codec) { - alc_automute_amp(codec); + alc_hp_automute(codec); alc88x_simple_mic_automute(codec); } @@ -3391,7 +3668,7 @@ static void alc880_uniwill_unsol_event(struct hda_codec *codec, alc88x_simple_mic_automute(codec); break; default: - alc_automute_amp_unsol_event(codec, res); + alc_sku_unsol_event(codec, res); break; } } @@ -3402,6 +3679,8 @@ static void alc880_uniwill_p53_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x15; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } 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, if ((res >> 28) == ALC880_DCVOL_EVENT) alc880_uniwill_p53_dcvol_automute(codec); else - alc_automute_amp_unsol_event(codec, res); + alc_sku_unsol_event(codec, res); } /* * F1734 pin configuration: * HP = 0x14, speaker-out = 0x15, mic = 0x18 */ -static struct hda_verb alc880_pin_f1734_init_verbs[] = { +static const struct hda_verb alc880_pin_f1734_init_verbs[] = { {0x07, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -3465,7 +3744,7 @@ static struct hda_verb alc880_pin_f1734_init_verbs[] = { * ASUS pin configuration: * HP/front = 0x14, surr = 0x15, clfe = 0x16, mic = 0x18, line = 0x1a */ -static struct hda_verb alc880_pin_asus_init_verbs[] = { +static const struct hda_verb alc880_pin_asus_init_verbs[] = { {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, {0x11, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x12, AC_VERB_SET_CONNECT_SEL, 0x01}, @@ -3499,7 +3778,7 @@ static struct hda_verb alc880_pin_asus_init_verbs[] = { #define alc880_gpio3_init_verbs alc_gpio3_init_verbs /* Clevo m520g init */ -static struct hda_verb alc880_pin_clevo_init_verbs[] = { +static const struct hda_verb alc880_pin_clevo_init_verbs[] = { /* headphone output */ {0x11, AC_VERB_SET_CONNECT_SEL, 0x01}, /* line-out */ @@ -3527,7 +3806,7 @@ static struct hda_verb alc880_pin_clevo_init_verbs[] = { { } }; -static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { +static const struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { /* change to EAPD mode */ {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, @@ -3565,12 +3844,12 @@ static struct hda_verb alc880_pin_tcl_S700_init_verbs[] = { */ /* To make 5.1 output working (green=Front, blue=Surr, red=CLFE) */ -static hda_nid_t alc880_lg_dac_nids[3] = { +static const hda_nid_t alc880_lg_dac_nids[3] = { 0x05, 0x02, 0x03 }; /* seems analog CD is not working */ -static struct hda_input_mux alc880_lg_capture_source = { +static const struct hda_input_mux alc880_lg_capture_source = { .num_items = 3, .items = { { "Mic", 0x1 }, @@ -3580,34 +3859,34 @@ static struct hda_input_mux alc880_lg_capture_source = { }; /* 2,4,6 channel modes */ -static struct hda_verb alc880_lg_ch2_init[] = { +static const struct hda_verb alc880_lg_ch2_init[] = { /* set line-in and mic-in to input */ { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { } }; -static struct hda_verb alc880_lg_ch4_init[] = { +static const struct hda_verb alc880_lg_ch4_init[] = { /* set line-in to out and mic-in to input */ { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { } }; -static struct hda_verb alc880_lg_ch6_init[] = { +static const struct hda_verb alc880_lg_ch6_init[] = { /* set line-in and mic-in to output */ { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, { } }; -static struct hda_channel_mode alc880_lg_ch_modes[3] = { +static const struct hda_channel_mode alc880_lg_ch_modes[3] = { { 2, alc880_lg_ch2_init }, { 4, alc880_lg_ch4_init }, { 6, alc880_lg_ch6_init }, }; -static struct snd_kcontrol_new alc880_lg_mixer[] = { +static const struct snd_kcontrol_new alc880_lg_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0f, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0f, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0c, 0x0, HDA_OUTPUT), @@ -3632,7 +3911,7 @@ static struct snd_kcontrol_new alc880_lg_mixer[] = { { } /* end */ }; -static struct hda_verb alc880_lg_init_verbs[] = { +static const struct hda_verb alc880_lg_init_verbs[] = { /* set capture source to mic-in */ {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -3670,6 +3949,8 @@ static void alc880_lg_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x1b; spec->autocfg.speaker_pins[0] = 0x17; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } /* @@ -3684,7 +3965,7 @@ static void alc880_lg_setup(struct hda_codec *codec) * SPDIF-Out: 0x1e */ -static struct hda_input_mux alc880_lg_lw_capture_source = { +static const struct hda_input_mux alc880_lg_lw_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, @@ -3695,7 +3976,7 @@ static struct hda_input_mux alc880_lg_lw_capture_source = { #define alc880_lg_lw_modes alc880_threestack_modes -static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { +static const struct snd_kcontrol_new alc880_lg_lw_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0f, 0x0, HDA_OUTPUT), @@ -3720,7 +4001,7 @@ static struct snd_kcontrol_new alc880_lg_lw_mixer[] = { { } /* end */ }; -static struct hda_verb alc880_lg_lw_init_verbs[] = { +static const struct hda_verb alc880_lg_lw_init_verbs[] = { {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ {0x10, AC_VERB_SET_CONNECT_SEL, 0x02}, /* mic/clfe */ {0x12, AC_VERB_SET_CONNECT_SEL, 0x03}, /* line/surround */ @@ -3754,9 +4035,11 @@ static void alc880_lg_lw_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x1b; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { +static const struct snd_kcontrol_new alc880_medion_rim_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -3766,7 +4049,7 @@ static struct snd_kcontrol_new alc880_medion_rim_mixer[] = { { } /* end */ }; -static struct hda_input_mux alc880_medion_rim_capture_source = { +static const struct hda_input_mux alc880_medion_rim_capture_source = { .num_items = 2, .items = { { "Mic", 0x0 }, @@ -3774,7 +4057,7 @@ static struct hda_input_mux alc880_medion_rim_capture_source = { }, }; -static struct hda_verb alc880_medion_rim_init_verbs[] = { +static const struct hda_verb alc880_medion_rim_init_verbs[] = { {0x13, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -3801,7 +4084,7 @@ static struct hda_verb alc880_medion_rim_init_verbs[] = { static void alc880_medion_rim_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - alc_automute_amp(codec); + alc_hp_automute(codec); /* toggle EAPD */ if (spec->jack_present) 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) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x1b; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list alc880_loopbacks[] = { +static const struct hda_amp_list alc880_loopbacks[] = { { 0x0b, HDA_INPUT, 0 }, { 0x0b, HDA_INPUT, 1 }, { 0x0b, HDA_INPUT, 2 }, @@ -3837,7 +4122,7 @@ static struct hda_amp_list alc880_loopbacks[] = { { } /* end */ }; -static struct hda_amp_list alc880_lg_loopbacks[] = { +static const struct hda_amp_list alc880_lg_loopbacks[] = { { 0x0b, HDA_INPUT, 1 }, { 0x0b, HDA_INPUT, 6 }, { 0x0b, HDA_INPUT, 7 }, @@ -4009,7 +4294,7 @@ static int dualmic_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, return 0; } -static struct hda_pcm_stream dualmic_pcm_analog_capture = { +static const struct hda_pcm_stream dualmic_pcm_analog_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -4022,7 +4307,7 @@ static struct hda_pcm_stream dualmic_pcm_analog_capture = { /* */ -static struct hda_pcm_stream alc880_pcm_analog_playback = { +static const struct hda_pcm_stream alc880_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 8, @@ -4034,21 +4319,21 @@ static struct hda_pcm_stream alc880_pcm_analog_playback = { }, }; -static struct hda_pcm_stream alc880_pcm_analog_capture = { +static const struct hda_pcm_stream alc880_pcm_analog_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, /* NID is set in alc_build_pcms */ }; -static struct hda_pcm_stream alc880_pcm_analog_alt_playback = { +static const struct hda_pcm_stream alc880_pcm_analog_alt_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, /* NID is set in alc_build_pcms */ }; -static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { +static const struct hda_pcm_stream alc880_pcm_analog_alt_capture = { .substreams = 2, /* can be overridden */ .channels_min = 2, .channels_max = 2, @@ -4059,7 +4344,7 @@ static struct hda_pcm_stream alc880_pcm_analog_alt_capture = { }, }; -static struct hda_pcm_stream alc880_pcm_digital_playback = { +static const struct hda_pcm_stream alc880_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -4072,7 +4357,7 @@ static struct hda_pcm_stream alc880_pcm_digital_playback = { }, }; -static struct hda_pcm_stream alc880_pcm_digital_capture = { +static const struct hda_pcm_stream alc880_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -4080,7 +4365,7 @@ static struct hda_pcm_stream alc880_pcm_digital_capture = { }; /* Used by alc_build_pcms to flag that a PCM has no playback stream */ -static struct hda_pcm_stream alc_pcm_null_stream = { +static const struct hda_pcm_stream alc_pcm_null_stream = { .substreams = 0, .channels_min = 0, .channels_max = 0, @@ -4174,7 +4459,7 @@ static int alc_build_pcms(struct hda_codec *codec) alc_pcm_null_stream; info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0; } - if (spec->num_adc_nids > 1) { + if (spec->num_adc_nids > 1 && spec->stream_analog_alt_capture) { info->stream[SNDRV_PCM_STREAM_CAPTURE] = *spec->stream_analog_alt_capture; info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = @@ -4193,6 +4478,10 @@ static int alc_build_pcms(struct hda_codec *codec) static inline void alc_shutup(struct hda_codec *codec) { + struct alc_spec *spec = codec->spec; + + if (spec && spec->shutup) + spec->shutup(codec); snd_hda_shutup_pins(codec); } @@ -4226,28 +4515,7 @@ static void alc_free(struct hda_codec *codec) #ifdef CONFIG_SND_HDA_POWER_SAVE static void alc_power_eapd(struct hda_codec *codec) { - /* We currently only handle front, HP */ - switch (codec->vendor_id) { - case 0x10ec0260: - set_eapd(codec, 0x0f, 0); - set_eapd(codec, 0x10, 0); - break; - case 0x10ec0262: - case 0x10ec0267: - case 0x10ec0268: - case 0x10ec0269: - case 0x10ec0270: - case 0x10ec0272: - case 0x10ec0660: - case 0x10ec0662: - case 0x10ec0663: - case 0x10ec0665: - case 0x10ec0862: - case 0x10ec0889: - set_eapd(codec, 0x14, 0); - set_eapd(codec, 0x15, 0); - break; - } + alc_auto_setup_eapd(codec, false); } 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) #ifdef SND_HDA_NEEDS_RESUME static int alc_resume(struct hda_codec *codec) { + msleep(150); /* to avoid pop noise */ codec->patch_ops.init(codec); snd_hda_codec_resume_amp(codec); snd_hda_codec_resume_cache(codec); @@ -4273,7 +4542,7 @@ static int alc_resume(struct hda_codec *codec) /* */ -static struct hda_codec_ops alc_patch_ops = { +static const struct hda_codec_ops alc_patch_ops = { .build_controls = alc_build_controls, .build_pcms = alc_build_pcms, .init = alc_init, @@ -4308,11 +4577,11 @@ static int alc_codec_rename(struct hda_codec *codec, const char *name) * enum controls. */ #ifdef CONFIG_SND_DEBUG -static hda_nid_t alc880_test_dac_nids[4] = { +static const hda_nid_t alc880_test_dac_nids[4] = { 0x02, 0x03, 0x04, 0x05 }; -static struct hda_input_mux alc880_test_capture_source = { +static const struct hda_input_mux alc880_test_capture_source = { .num_items = 7, .items = { { "In-1", 0x0 }, @@ -4325,7 +4594,7 @@ static struct hda_input_mux alc880_test_capture_source = { }, }; -static struct hda_channel_mode alc880_test_modes[4] = { +static const struct hda_channel_mode alc880_test_modes[4] = { { 2, NULL }, { 4, NULL }, { 6, NULL }, @@ -4335,7 +4604,7 @@ static struct hda_channel_mode alc880_test_modes[4] = { static int alc_test_pin_ctl_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = { + static const char * const texts[] = { "N/A", "Line Out", "HP Out", "In Hi-Z", "In 50%", "In Grd", "In 80%", "In 100%" }; @@ -4380,7 +4649,7 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); hda_nid_t nid = (hda_nid_t)kcontrol->private_value; - static unsigned int ctls[] = { + static const unsigned int ctls[] = { 0, AC_PINCTL_OUT_EN, AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN, AC_PINCTL_IN_EN | AC_PINCTL_VREF_HIZ, AC_PINCTL_IN_EN | AC_PINCTL_VREF_50, @@ -4410,7 +4679,7 @@ static int alc_test_pin_ctl_put(struct snd_kcontrol *kcontrol, static int alc_test_pin_src_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[] = { + static const char * const texts[] = { "Front", "Surround", "CLFE", "Side" }; uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; @@ -4471,7 +4740,7 @@ static int alc_test_pin_src_put(struct snd_kcontrol *kcontrol, .private_value = nid \ } -static struct snd_kcontrol_new alc880_test_mixer[] = { +static const struct snd_kcontrol_new alc880_test_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("CLFE Playback Volume", 0x0e, 0x0, HDA_OUTPUT), @@ -4512,7 +4781,7 @@ static struct snd_kcontrol_new alc880_test_mixer[] = { { } /* end */ }; -static struct hda_verb alc880_test_init_verbs[] = { +static const struct hda_verb alc880_test_init_verbs[] = { /* Unmute inputs of 0x0c - 0x0f */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -4596,7 +4865,7 @@ static const char * const alc880_models[ALC880_MODEL_LAST] = { [ALC880_AUTO] = "auto", }; -static struct snd_pci_quirk alc880_cfg_tbl[] = { +static const struct snd_pci_quirk alc880_cfg_tbl[] = { SND_PCI_QUIRK(0x1019, 0x0f69, "Coeus G610P", ALC880_W810), SND_PCI_QUIRK(0x1019, 0xa880, "ECS", ALC880_5ST_DIG), SND_PCI_QUIRK(0x1019, 0xa884, "Acer APFV", ALC880_6ST), @@ -4676,7 +4945,7 @@ static struct snd_pci_quirk alc880_cfg_tbl[] = { /* * ALC880 codec presets */ -static struct alc_config_preset alc880_presets[] = { +static const struct alc_config_preset alc880_presets[] = { [ALC880_3ST] = { .mixers = { alc880_three_stack_mixer }, .init_verbs = { alc880_volume_init_verbs, @@ -4794,7 +5063,7 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_f1734_capture_source, .unsol_event = alc880_uniwill_p53_unsol_event, .setup = alc880_uniwill_p53_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC880_ASUS] = { .mixers = { alc880_asus_mixer }, @@ -4885,7 +5154,7 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_capture_source, .unsol_event = alc880_uniwill_p53_unsol_event, .setup = alc880_uniwill_p53_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC880_FUJITSU] = { .mixers = { alc880_fujitsu_mixer }, @@ -4900,7 +5169,7 @@ static struct alc_config_preset alc880_presets[] = { .input_mux = &alc880_capture_source, .unsol_event = alc880_uniwill_p53_unsol_event, .setup = alc880_uniwill_p53_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC880_CLEVO] = { .mixers = { alc880_three_stack_mixer }, @@ -4925,9 +5194,9 @@ static struct alc_config_preset alc880_presets[] = { .channel_mode = alc880_lg_ch_modes, .need_dac_fix = 1, .input_mux = &alc880_lg_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc880_lg_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, #ifdef CONFIG_SND_HDA_POWER_SAVE .loopbacks = alc880_lg_loopbacks, #endif @@ -4942,9 +5211,9 @@ static struct alc_config_preset alc880_presets[] = { .num_channel_mode = ARRAY_SIZE(alc880_lg_lw_modes), .channel_mode = alc880_lg_lw_modes, .input_mux = &alc880_lg_lw_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc880_lg_lw_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC880_MEDION_RIM] = { .mixers = { alc880_medion_rim_mixer }, @@ -4984,20 +5253,25 @@ enum { ALC_CTL_WIDGET_MUTE, ALC_CTL_BIND_MUTE, }; -static struct snd_kcontrol_new alc880_control_templates[] = { +static const struct snd_kcontrol_new alc880_control_templates[] = { HDA_CODEC_VOLUME(NULL, 0, 0, 0), HDA_CODEC_MUTE(NULL, 0, 0, 0), HDA_BIND_MUTE(NULL, 0, 0, 0), }; +static struct snd_kcontrol_new *alc_kcontrol_new(struct alc_spec *spec) +{ + snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); + return snd_array_new(&spec->kctls); +} + /* add dynamic controls */ static int add_control(struct alc_spec *spec, int type, const char *name, int cidx, unsigned long val) { struct snd_kcontrol_new *knew; - snd_array_init(&spec->kctls, sizeof(*knew), 32); - knew = snd_array_new(&spec->kctls); + knew = alc_kcontrol_new(spec); if (!knew) return -ENOMEM; *knew = alc880_control_templates[type]; @@ -5055,7 +5329,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, nid = cfg->line_out_pins[i]; if (alc880_is_fixed_pin(nid)) { int idx = alc880_fixed_pin_idx(nid); - spec->multiout.dac_nids[i] = alc880_idx_to_dac(idx); + spec->private_dac_nids[i] = alc880_idx_to_dac(idx); assigned[idx] = 1; } } @@ -5067,7 +5341,7 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, /* search for an empty channel */ for (j = 0; j < cfg->line_outs; j++) { if (!assigned[j]) { - spec->multiout.dac_nids[i] = + spec->private_dac_nids[i] = alc880_idx_to_dac(j); assigned[j] = 1; break; @@ -5078,10 +5352,13 @@ static int alc880_auto_fill_dac_nids(struct alc_spec *spec, return 0; } -static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, +static const char *alc_get_line_out_pfx(struct alc_spec *spec, bool can_be_master) { - if (!cfg->hp_outs && !cfg->speaker_outs && can_be_master) + struct auto_pin_cfg *cfg = &spec->autocfg; + + if (cfg->line_outs == 1 && !spec->multi_ios && + !cfg->hp_outs && !cfg->speaker_outs && can_be_master) return "Master"; switch (cfg->line_out_type) { @@ -5092,7 +5369,7 @@ static const char *alc_get_line_out_pfx(const struct auto_pin_cfg *cfg, case AUTO_PIN_HP_OUT: return "Headphone"; default: - if (cfg->line_outs == 1) + if (cfg->line_outs == 1 && !spec->multi_ios) return "PCM"; break; } @@ -5106,11 +5383,15 @@ static int alc880_auto_create_multi_out_ctls(struct alc_spec *spec, static const char * const chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; - const char *pfx = alc_get_line_out_pfx(cfg, false); + const char *pfx = alc_get_line_out_pfx(spec, false); hda_nid_t nid; - int i, err; + int i, err, noutputs; - for (i = 0; i < cfg->line_outs; i++) { + noutputs = cfg->line_outs; + if (spec->multi_ios > 0) + noutputs += spec->multi_ios; + + for (i = 0; i < noutputs; i++) { if (!spec->multiout.dac_nids[i]) continue; 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) } } +static int alc_auto_add_multi_channel_mode(struct hda_codec *codec); + /* parse the BIOS configuration and set up the alc_spec */ /* return 1 if successful, 0 if the proper config is not found, * or a negative error code @@ -5384,7 +5667,7 @@ static int alc880_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; - static hda_nid_t alc880_ignore[] = { 0x1d, 0 }; + static const hda_nid_t alc880_ignore[] = { 0x1d, 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc880_ignore); @@ -5394,6 +5677,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec) return 0; /* can't find valid BIOS pin config */ err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc_auto_add_multi_channel_mode(codec); if (err < 0) return err; err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); @@ -5467,6 +5753,12 @@ static void fixup_automic_adc(struct hda_codec *codec) spec->capsrc_nids += i; spec->adc_nids += i; spec->num_adc_nids = 1; + /* optional dock-mic */ + eidx = get_connection_index(codec, cap, spec->dock_mic.pin); + if (eidx < 0) + spec->dock_mic.pin = 0; + else + spec->dock_mic.mux_idx = eidx; return; } 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) struct alc_spec *spec = codec->spec; int i; + if (!pin) + return 0; for (i = 0; i < spec->num_adc_nids; i++) { hda_nid_t cap = spec->capsrc_nids ? spec->capsrc_nids[i] : spec->adc_nids[i]; @@ -5534,6 +5828,7 @@ static void fixup_dual_adc_switch(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; init_capsrc_for_pin(codec, spec->ext_mic.pin); + init_capsrc_for_pin(codec, spec->dock_mic.pin); init_capsrc_for_pin(codec, spec->int_mic.pin); } @@ -5550,7 +5845,7 @@ static void alc_init_special_input_src(struct hda_codec *codec) static void set_capture_mixer(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - static struct snd_kcontrol_new *caps[2][3] = { + static const struct snd_kcontrol_new *caps[2][3] = { { alc_capture_mixer_nosrc1, alc_capture_mixer_nosrc2, alc_capture_mixer_nosrc3 }, @@ -5576,7 +5871,7 @@ static void set_capture_mixer(struct hda_codec *codec) } /* fill adc_nids (and capsrc_nids) containing all active input pins */ -static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, +static void fillup_priv_adc_nids(struct hda_codec *codec, const hda_nid_t *nids, int num_nids) { struct alc_spec *spec = codec->spec; @@ -5642,10 +5937,11 @@ static void fillup_priv_adc_nids(struct hda_codec *codec, hda_nid_t *nids, #define set_beep_amp(spec, nid, idx, dir) \ ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir)) -static struct snd_pci_quirk beep_white_list[] = { +static const struct snd_pci_quirk beep_white_list[] = { SND_PCI_QUIRK(0x1043, 0x829f, "ASUS", 1), SND_PCI_QUIRK(0x1043, 0x83ce, "EeePC", 1), SND_PCI_QUIRK(0x1043, 0x831a, "EeePC", 1), + SND_PCI_QUIRK(0x1043, 0x834a, "EeePC", 1), SND_PCI_QUIRK(0x8086, 0xd613, "Intel", 1), {} }; @@ -5753,17 +6049,17 @@ static int patch_alc880(struct hda_codec *codec) * ALC260 support */ -static hda_nid_t alc260_dac_nids[1] = { +static const hda_nid_t alc260_dac_nids[1] = { /* front */ 0x02, }; -static hda_nid_t alc260_adc_nids[1] = { +static const hda_nid_t alc260_adc_nids[1] = { /* ADC0 */ 0x04, }; -static hda_nid_t alc260_adc_nids_alt[1] = { +static const hda_nid_t alc260_adc_nids_alt[1] = { /* ADC1 */ 0x05, }; @@ -5771,7 +6067,7 @@ static hda_nid_t alc260_adc_nids_alt[1] = { /* NIDs used when simultaneous access to both ADCs makes sense. Note that * alc260_capture_mixer assumes ADC0 (nid 0x04) is the first ADC. */ -static hda_nid_t alc260_dual_adc_nids[2] = { +static const hda_nid_t alc260_dual_adc_nids[2] = { /* ADC0, ADC1 */ 0x04, 0x05 }; @@ -5779,7 +6075,7 @@ static hda_nid_t alc260_dual_adc_nids[2] = { #define ALC260_DIGOUT_NID 0x03 #define ALC260_DIGIN_NID 0x06 -static struct hda_input_mux alc260_capture_source = { +static const struct hda_input_mux alc260_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -5795,7 +6091,7 @@ static struct hda_input_mux alc260_capture_source = { * recording the mixer output on the second ADC (ADC0 doesn't have a * connection to the mixer output). */ -static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { +static const struct hda_input_mux alc260_fujitsu_capture_sources[2] = { { .num_items = 3, .items = { @@ -5819,7 +6115,7 @@ static struct hda_input_mux alc260_fujitsu_capture_sources[2] = { /* Acer TravelMate(/Extensa/Aspire) notebooks have similar configuration to * the Fujitsu S702x, but jacks are marked differently. */ -static struct hda_input_mux alc260_acer_capture_sources[2] = { +static const struct hda_input_mux alc260_acer_capture_sources[2] = { { .num_items = 4, .items = { @@ -5842,7 +6138,7 @@ static struct hda_input_mux alc260_acer_capture_sources[2] = { }; /* Maxdata Favorit 100XS */ -static struct hda_input_mux alc260_favorit100_capture_sources[2] = { +static const struct hda_input_mux alc260_favorit100_capture_sources[2] = { { .num_items = 2, .items = { @@ -5866,7 +6162,7 @@ static struct hda_input_mux alc260_favorit100_capture_sources[2] = { * element which allows changing the channel mode, so the verb list is * never used. */ -static struct hda_channel_mode alc260_modes[1] = { +static const struct hda_channel_mode alc260_modes[1] = { { 2, NULL }, }; @@ -5880,7 +6176,7 @@ static struct hda_channel_mode alc260_modes[1] = { * acer: acer + capture */ -static struct snd_kcontrol_new alc260_base_output_mixer[] = { +static const struct snd_kcontrol_new alc260_base_output_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x09, 0x0, HDA_OUTPUT), @@ -5890,7 +6186,7 @@ static struct snd_kcontrol_new alc260_base_output_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc260_input_mixer[] = { +static const struct snd_kcontrol_new alc260_input_mixer[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x07, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x07, 0x04, HDA_INPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x07, 0x02, HDA_INPUT), @@ -5903,21 +6199,14 @@ static struct snd_kcontrol_new alc260_input_mixer[] = { }; /* update HP, line and mono out pins according to the master switch */ -static void alc260_hp_master_update(struct hda_codec *codec, - hda_nid_t hp, hda_nid_t line, - hda_nid_t mono) +static void alc260_hp_master_update(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int val = spec->master_sw ? PIN_HP : 0; - /* change HP and line-out pins */ - snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - val); - snd_hda_codec_write(codec, line, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - val); - /* mono (speaker) depending on the HP jack sense */ - val = (val && !spec->jack_present) ? PIN_OUT : 0; - snd_hda_codec_write(codec, mono, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - val); + + /* change HP pins */ + do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), + spec->autocfg.hp_pins, spec->master_mute, true); + update_speakers(codec); } static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, @@ -5925,7 +6214,7 @@ static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; - *ucontrol->value.integer.value = spec->master_sw; + *ucontrol->value.integer.value = !spec->master_mute; return 0; } @@ -5934,20 +6223,16 @@ static int alc260_hp_master_sw_put(struct snd_kcontrol *kcontrol, { struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct alc_spec *spec = codec->spec; - int val = !!*ucontrol->value.integer.value; - hda_nid_t hp, line, mono; + int val = !*ucontrol->value.integer.value; - if (val == spec->master_sw) + if (val == spec->master_mute) return 0; - spec->master_sw = val; - hp = (kcontrol->private_value >> 16) & 0xff; - line = (kcontrol->private_value >> 8) & 0xff; - mono = kcontrol->private_value & 0xff; - alc260_hp_master_update(codec, hp, line, mono); + spec->master_mute = val; + alc260_hp_master_update(codec); return 1; } -static struct snd_kcontrol_new alc260_hp_output_mixer[] = { +static const struct snd_kcontrol_new alc260_hp_output_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -5955,7 +6240,6 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = { .info = snd_ctl_boolean_mono_info, .get = alc260_hp_master_sw_get, .put = alc260_hp_master_sw_put, - .private_value = (0x0f << 16) | (0x10 << 8) | 0x11 }, HDA_CODEC_VOLUME("Front Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x08, 2, HDA_INPUT), @@ -5967,26 +6251,23 @@ static struct snd_kcontrol_new alc260_hp_output_mixer[] = { { } /* end */ }; -static struct hda_verb alc260_hp_unsol_verbs[] = { +static const struct hda_verb alc260_hp_unsol_verbs[] = { {0x10, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {}, }; -static void alc260_hp_automute(struct hda_codec *codec) +static void alc260_hp_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - spec->jack_present = snd_hda_jack_detect(codec, 0x10); - alc260_hp_master_update(codec, 0x0f, 0x10, 0x11); + spec->autocfg.hp_pins[0] = 0x0f; + spec->autocfg.speaker_pins[0] = 0x10; + spec->autocfg.speaker_pins[1] = 0x11; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; } -static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) -{ - if ((res >> 26) == ALC880_HP_EVENT) - alc260_hp_automute(codec); -} - -static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { +static const struct snd_kcontrol_new alc260_hp_3013_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", @@ -5994,7 +6275,6 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { .info = snd_ctl_boolean_mono_info, .get = alc260_hp_master_sw_get, .put = alc260_hp_master_sw_put, - .private_value = (0x15 << 16) | (0x10 << 8) | 0x11 }, HDA_CODEC_VOLUME("Front Playback Volume", 0x09, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x10, 0x0, HDA_OUTPUT), @@ -6007,7 +6287,18 @@ static struct snd_kcontrol_new alc260_hp_3013_mixer[] = { { } /* end */ }; -static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { +static void alc260_hp_3013_setup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + + spec->autocfg.hp_pins[0] = 0x15; + spec->autocfg.speaker_pins[0] = 0x10; + spec->autocfg.speaker_pins[1] = 0x11; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; +} + +static const struct hda_bind_ctls alc260_dc7600_bind_master_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_OUTPUT), @@ -6017,7 +6308,7 @@ static struct hda_bind_ctls alc260_dc7600_bind_master_vol = { }, }; -static struct hda_bind_ctls alc260_dc7600_bind_switch = { +static const struct hda_bind_ctls alc260_dc7600_bind_switch = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x11, 3, 0, HDA_OUTPUT), @@ -6026,7 +6317,7 @@ static struct hda_bind_ctls alc260_dc7600_bind_switch = { }, }; -static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { +static const struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { HDA_BIND_VOL("Master Playback Volume", &alc260_dc7600_bind_master_vol), HDA_BIND_SW("LineOut Playback Switch", &alc260_dc7600_bind_switch), HDA_CODEC_MUTE("Speaker Playback Switch", 0x0f, 0x0, HDA_OUTPUT), @@ -6034,49 +6325,27 @@ static struct snd_kcontrol_new alc260_hp_dc7600_mixer[] = { { } /* end */ }; -static struct hda_verb alc260_hp_3013_unsol_verbs[] = { +static const struct hda_verb alc260_hp_3013_unsol_verbs[] = { {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {}, }; -static void alc260_hp_3013_automute(struct hda_codec *codec) +static void alc260_hp_3012_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - spec->jack_present = snd_hda_jack_detect(codec, 0x15); - alc260_hp_master_update(codec, 0x15, 0x10, 0x11); -} - -static void alc260_hp_3013_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) == ALC880_HP_EVENT) - alc260_hp_3013_automute(codec); -} - -static void alc260_hp_3012_automute(struct hda_codec *codec) -{ - unsigned int bits = snd_hda_jack_detect(codec, 0x10) ? 0 : PIN_OUT; - - snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - bits); - snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - bits); - snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, - bits); -} - -static void alc260_hp_3012_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) == ALC880_HP_EVENT) - alc260_hp_3012_automute(codec); + spec->autocfg.hp_pins[0] = 0x10; + spec->autocfg.speaker_pins[0] = 0x0f; + spec->autocfg.speaker_pins[1] = 0x11; + spec->autocfg.speaker_pins[2] = 0x15; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; } /* Fujitsu S702x series laptops. ALC260 pin usage: Mic/Line jack = 0x12, * HP jack = 0x14, CD audio = 0x16, internal speaker = 0x10. */ -static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { +static const struct snd_kcontrol_new alc260_fujitsu_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x08, 2, HDA_INPUT), ALC_PIN_MODE("Headphone Jack Mode", 0x14, ALC_PIN_DIR_INOUT), @@ -6113,7 +6382,7 @@ static struct snd_kcontrol_new alc260_fujitsu_mixer[] = { * controls for such models. On models without a "mono speaker" the control * won't do anything. */ -static struct snd_kcontrol_new alc260_acer_mixer[] = { +static const struct snd_kcontrol_new alc260_acer_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), ALC_PIN_MODE("Headphone Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), @@ -6134,7 +6403,7 @@ static struct snd_kcontrol_new alc260_acer_mixer[] = { /* Maxdata Favorit 100XS: one output and one input (0x12) jack */ -static struct snd_kcontrol_new alc260_favorit100_mixer[] = { +static const struct snd_kcontrol_new alc260_favorit100_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x08, 2, HDA_INPUT), ALC_PIN_MODE("Output Jack Mode", 0x0f, ALC_PIN_DIR_INOUT), @@ -6147,7 +6416,7 @@ static struct snd_kcontrol_new alc260_favorit100_mixer[] = { /* Packard bell V7900 ALC260 pin usage: HP = 0x0f, Mic jack = 0x12, * Line In jack = 0x14, CD audio = 0x16, pc beep = 0x17. */ -static struct snd_kcontrol_new alc260_will_mixer[] = { +static const struct snd_kcontrol_new alc260_will_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), @@ -6164,7 +6433,7 @@ static struct snd_kcontrol_new alc260_will_mixer[] = { /* Replacer 672V ALC260 pin usage: Mic jack = 0x12, * Line In jack = 0x14, ATAPI Mic = 0x13, speaker = 0x0f. */ -static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { +static const struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x08, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x08, 0x2, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x07, 0x0, HDA_INPUT), @@ -6181,7 +6450,7 @@ static struct snd_kcontrol_new alc260_replacer_672v_mixer[] = { /* * initialization verbs */ -static struct hda_verb alc260_init_verbs[] = { +static const struct hda_verb alc260_init_verbs[] = { /* Line In pin widget for input */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* CD pin widget for input */ @@ -6245,7 +6514,7 @@ static struct hda_verb alc260_init_verbs[] = { }; #if 0 /* should be identical with alc260_init_verbs? */ -static struct hda_verb alc260_hp_init_verbs[] = { +static const struct hda_verb alc260_hp_init_verbs[] = { /* Headphone and output */ {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, /* mono output */ @@ -6295,7 +6564,7 @@ static struct hda_verb alc260_hp_init_verbs[] = { }; #endif -static struct hda_verb alc260_hp_3013_init_verbs[] = { +static const struct hda_verb alc260_hp_3013_init_verbs[] = { /* Line out and output */ {0x10, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, /* mono output */ @@ -6348,7 +6617,7 @@ static struct hda_verb alc260_hp_3013_init_verbs[] = { * laptops. ALC260 pin usage: Mic/Line jack = 0x12, HP jack = 0x14, CD * audio = 0x16, internal speaker = 0x10. */ -static struct hda_verb alc260_fujitsu_init_verbs[] = { +static const struct hda_verb alc260_fujitsu_init_verbs[] = { /* Disable all GPIOs */ {0x01, AC_VERB_SET_GPIO_MASK, 0}, /* Internal speaker is connected to headphone pin */ @@ -6430,7 +6699,7 @@ static struct hda_verb alc260_fujitsu_init_verbs[] = { /* Initialisation sequence for ALC260 as configured in Acer TravelMate and * similar laptops (adapted from Fujitsu init verbs). */ -static struct hda_verb alc260_acer_init_verbs[] = { +static const struct hda_verb alc260_acer_init_verbs[] = { /* On TravelMate laptops, GPIO 0 enables the internal speaker and * the headphone jack. Turn this on and rely on the standard mute * methods whenever the user wants to turn these outputs off. @@ -6518,7 +6787,7 @@ static struct hda_verb alc260_acer_init_verbs[] = { /* Initialisation sequence for Maxdata Favorit 100XS * (adapted from Acer init verbs). */ -static struct hda_verb alc260_favorit100_init_verbs[] = { +static const struct hda_verb alc260_favorit100_init_verbs[] = { /* GPIO 0 enables the output jack. * Turn this on and rely on the standard mute * methods whenever the user wants to turn these outputs off. @@ -6598,7 +6867,7 @@ static struct hda_verb alc260_favorit100_init_verbs[] = { { } }; -static struct hda_verb alc260_will_verbs[] = { +static const struct hda_verb alc260_will_verbs[] = { {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x0b, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -6608,7 +6877,7 @@ static struct hda_verb alc260_will_verbs[] = { {} }; -static struct hda_verb alc260_replacer_672v_verbs[] = { +static const struct hda_verb alc260_replacer_672v_verbs[] = { {0x0f, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, {0x1a, AC_VERB_SET_COEF_INDEX, 0x07}, {0x1a, AC_VERB_SET_PROC_COEF, 0x3050}, @@ -6650,7 +6919,7 @@ static void alc260_replacer_672v_unsol_event(struct hda_codec *codec, alc260_replacer_672v_automute(codec); } -static struct hda_verb alc260_hp_dc7600_verbs[] = { +static const struct hda_verb alc260_hp_dc7600_verbs[] = { {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -6668,17 +6937,17 @@ static struct hda_verb alc260_hp_dc7600_verbs[] = { * configuration. */ #ifdef CONFIG_SND_DEBUG -static hda_nid_t alc260_test_dac_nids[1] = { +static const hda_nid_t alc260_test_dac_nids[1] = { 0x02, }; -static hda_nid_t alc260_test_adc_nids[2] = { +static const hda_nid_t alc260_test_adc_nids[2] = { 0x04, 0x05, }; /* For testing the ALC260, each input MUX needs its own definition since * the signal assignments are different. This assumes that the first ADC * is NID 0x04. */ -static struct hda_input_mux alc260_test_capture_sources[2] = { +static const struct hda_input_mux alc260_test_capture_sources[2] = { { .num_items = 7, .items = { @@ -6705,7 +6974,7 @@ static struct hda_input_mux alc260_test_capture_sources[2] = { }, }, }; -static struct snd_kcontrol_new alc260_test_mixer[] = { +static const struct snd_kcontrol_new alc260_test_mixer[] = { /* Output driver widgets */ HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), HDA_BIND_MUTE_MONO("Mono Playback Switch", 0x0a, 1, 2, HDA_INPUT), @@ -6769,7 +7038,7 @@ static struct snd_kcontrol_new alc260_test_mixer[] = { { } /* end */ }; -static struct hda_verb alc260_test_init_verbs[] = { +static const struct hda_verb alc260_test_init_verbs[] = { /* Enable all GPIOs as outputs with an initial value of 0 */ {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x0f}, {0x01, AC_VERB_SET_GPIO_DATA, 0x00}, @@ -6907,7 +7176,7 @@ static int alc260_auto_create_multi_out_ctls(struct alc_spec *spec, spec->multiout.num_dacs = 1; spec->multiout.dac_nids = spec->private_dac_nids; - spec->multiout.dac_nids[0] = 0x02; + spec->private_dac_nids[0] = 0x02; nid = cfg->line_out_pins[0]; if (nid) { @@ -7005,7 +7274,7 @@ static void alc260_auto_init_analog_input(struct hda_codec *codec) /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc260_volume_init_verbs[] = { +static const struct hda_verb alc260_volume_init_verbs[] = { /* * Unmute ADC0-1 and set the default input to mic-in */ @@ -7050,7 +7319,7 @@ static int alc260_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; - static hda_nid_t alc260_ignore[] = { 0x17, 0 }; + static const hda_nid_t alc260_ignore[] = { 0x17, 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc260_ignore); @@ -7095,7 +7364,7 @@ static void alc260_auto_init(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list alc260_loopbacks[] = { +static const struct hda_amp_list alc260_loopbacks[] = { { 0x07, HDA_INPUT, 0 }, { 0x07, HDA_INPUT, 1 }, { 0x07, HDA_INPUT, 2 }, @@ -7122,7 +7391,7 @@ static const struct alc_fixup alc260_fixups[] = { }, }; -static struct snd_pci_quirk alc260_fixup_tbl[] = { +static const struct snd_pci_quirk alc260_fixup_tbl[] = { SND_PCI_QUIRK(0x103c, 0x280a, "HP dc5750", PINFIX_HP_DC5750), {} }; @@ -7146,7 +7415,7 @@ static const char * const alc260_models[ALC260_MODEL_LAST] = { [ALC260_AUTO] = "auto", }; -static struct snd_pci_quirk alc260_cfg_tbl[] = { +static const struct snd_pci_quirk alc260_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x007b, "Acer C20x", ALC260_ACER), SND_PCI_QUIRK(0x1025, 0x007f, "Acer", ALC260_WILL), SND_PCI_QUIRK(0x1025, 0x008f, "Acer", ALC260_ACER), @@ -7170,7 +7439,7 @@ static struct snd_pci_quirk alc260_cfg_tbl[] = { {} }; -static struct alc_config_preset alc260_presets[] = { +static const struct alc_config_preset alc260_presets[] = { [ALC260_BASIC] = { .mixers = { alc260_base_output_mixer, alc260_input_mixer }, @@ -7195,8 +7464,9 @@ static struct alc_config_preset alc260_presets[] = { .num_channel_mode = ARRAY_SIZE(alc260_modes), .channel_mode = alc260_modes, .input_mux = &alc260_capture_source, - .unsol_event = alc260_hp_unsol_event, - .init_hook = alc260_hp_automute, + .unsol_event = alc_sku_unsol_event, + .setup = alc260_hp_setup, + .init_hook = alc_inithook, }, [ALC260_HP_DC7600] = { .mixers = { alc260_hp_dc7600_mixer, @@ -7210,8 +7480,9 @@ static struct alc_config_preset alc260_presets[] = { .num_channel_mode = ARRAY_SIZE(alc260_modes), .channel_mode = alc260_modes, .input_mux = &alc260_capture_source, - .unsol_event = alc260_hp_3012_unsol_event, - .init_hook = alc260_hp_3012_automute, + .unsol_event = alc_sku_unsol_event, + .setup = alc260_hp_3012_setup, + .init_hook = alc_inithook, }, [ALC260_HP_3013] = { .mixers = { alc260_hp_3013_mixer, @@ -7225,8 +7496,9 @@ static struct alc_config_preset alc260_presets[] = { .num_channel_mode = ARRAY_SIZE(alc260_modes), .channel_mode = alc260_modes, .input_mux = &alc260_capture_source, - .unsol_event = alc260_hp_3013_unsol_event, - .init_hook = alc260_hp_3013_automute, + .unsol_event = alc_sku_unsol_event, + .setup = alc260_hp_3013_setup, + .init_hook = alc_inithook, }, [ALC260_FUJITSU_S702X] = { .mixers = { alc260_fujitsu_mixer }, @@ -7384,6 +7656,7 @@ static int patch_alc260(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC260_AUTO) spec->init_hook = alc260_auto_init; + spec->shutup = alc_eapd_shutup; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc260_loopbacks; @@ -7411,12 +7684,12 @@ static int patch_alc260(struct hda_codec *codec) #define ALC1200_DIGOUT_NID 0x10 -static struct hda_channel_mode alc882_ch_modes[1] = { +static const struct hda_channel_mode alc882_ch_modes[1] = { { 8, NULL } }; /* DACs */ -static hda_nid_t alc882_dac_nids[4] = { +static const hda_nid_t alc882_dac_nids[4] = { /* front, rear, clfe, rear_surr */ 0x02, 0x03, 0x04, 0x05 }; @@ -7426,20 +7699,20 @@ static hda_nid_t alc882_dac_nids[4] = { #define alc882_adc_nids alc880_adc_nids #define alc882_adc_nids_alt alc880_adc_nids_alt #define alc883_adc_nids alc882_adc_nids_alt -static hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; -static hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; +static const hda_nid_t alc883_adc_nids_alt[1] = { 0x08 }; +static const hda_nid_t alc883_adc_nids_rev[2] = { 0x09, 0x08 }; #define alc889_adc_nids alc880_adc_nids -static hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; -static hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; +static const hda_nid_t alc882_capsrc_nids[3] = { 0x24, 0x23, 0x22 }; +static const hda_nid_t alc882_capsrc_nids_alt[2] = { 0x23, 0x22 }; #define alc883_capsrc_nids alc882_capsrc_nids_alt -static hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; +static const hda_nid_t alc883_capsrc_nids_rev[2] = { 0x22, 0x23 }; #define alc889_capsrc_nids alc882_capsrc_nids /* input MUX */ /* FIXME: should be a matrix-type input source selection */ -static struct hda_input_mux alc882_capture_source = { +static const struct hda_input_mux alc882_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -7451,7 +7724,7 @@ static struct hda_input_mux alc882_capture_source = { #define alc883_capture_source alc882_capture_source -static struct hda_input_mux alc889_capture_source = { +static const struct hda_input_mux alc889_capture_source = { .num_items = 3, .items = { { "Front Mic", 0x0 }, @@ -7460,7 +7733,7 @@ static struct hda_input_mux alc889_capture_source = { }, }; -static struct hda_input_mux mb5_capture_source = { +static const struct hda_input_mux mb5_capture_source = { .num_items = 3, .items = { { "Mic", 0x1 }, @@ -7469,7 +7742,7 @@ static struct hda_input_mux mb5_capture_source = { }, }; -static struct hda_input_mux macmini3_capture_source = { +static const struct hda_input_mux macmini3_capture_source = { .num_items = 2, .items = { { "Line", 0x2 }, @@ -7477,7 +7750,7 @@ static struct hda_input_mux macmini3_capture_source = { }, }; -static struct hda_input_mux alc883_3stack_6ch_intel = { +static const struct hda_input_mux alc883_3stack_6ch_intel = { .num_items = 4, .items = { { "Mic", 0x1 }, @@ -7487,7 +7760,7 @@ static struct hda_input_mux alc883_3stack_6ch_intel = { }, }; -static struct hda_input_mux alc883_lenovo_101e_capture_source = { +static const struct hda_input_mux alc883_lenovo_101e_capture_source = { .num_items = 2, .items = { { "Mic", 0x1 }, @@ -7495,7 +7768,7 @@ static struct hda_input_mux alc883_lenovo_101e_capture_source = { }, }; -static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { +static const struct hda_input_mux alc883_lenovo_nb0763_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -7505,7 +7778,7 @@ static struct hda_input_mux alc883_lenovo_nb0763_capture_source = { }, }; -static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { +static const struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { .num_items = 2, .items = { { "Mic", 0x0 }, @@ -7513,7 +7786,7 @@ static struct hda_input_mux alc883_fujitsu_pi2515_capture_source = { }, }; -static struct hda_input_mux alc883_lenovo_sky_capture_source = { +static const struct hda_input_mux alc883_lenovo_sky_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, @@ -7522,7 +7795,7 @@ static struct hda_input_mux alc883_lenovo_sky_capture_source = { }, }; -static struct hda_input_mux alc883_asus_eee1601_capture_source = { +static const struct hda_input_mux alc883_asus_eee1601_capture_source = { .num_items = 2, .items = { { "Mic", 0x0 }, @@ -7530,7 +7803,7 @@ static struct hda_input_mux alc883_asus_eee1601_capture_source = { }, }; -static struct hda_input_mux alc889A_mb31_capture_source = { +static const struct hda_input_mux alc889A_mb31_capture_source = { .num_items = 2, .items = { { "Mic", 0x0 }, @@ -7541,7 +7814,7 @@ static struct hda_input_mux alc889A_mb31_capture_source = { }, }; -static struct hda_input_mux alc889A_imac91_capture_source = { +static const struct hda_input_mux alc889A_imac91_capture_source = { .num_items = 2, .items = { { "Mic", 0x01 }, @@ -7552,14 +7825,14 @@ static struct hda_input_mux alc889A_imac91_capture_source = { /* * 2ch mode */ -static struct hda_channel_mode alc883_3ST_2ch_modes[1] = { +static const struct hda_channel_mode alc883_3ST_2ch_modes[1] = { { 2, NULL } }; /* * 2ch mode */ -static struct hda_verb alc882_3ST_ch2_init[] = { +static const struct hda_verb alc882_3ST_ch2_init[] = { { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, @@ -7570,7 +7843,7 @@ static struct hda_verb alc882_3ST_ch2_init[] = { /* * 4ch mode */ -static struct hda_verb alc882_3ST_ch4_init[] = { +static const struct hda_verb alc882_3ST_ch4_init[] = { { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7582,7 +7855,7 @@ static struct hda_verb alc882_3ST_ch4_init[] = { /* * 6ch mode */ -static struct hda_verb alc882_3ST_ch6_init[] = { +static const struct hda_verb alc882_3ST_ch6_init[] = { { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -7592,7 +7865,7 @@ static struct hda_verb alc882_3ST_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { +static const struct hda_channel_mode alc882_3ST_6ch_modes[3] = { { 2, alc882_3ST_ch2_init }, { 4, alc882_3ST_ch4_init }, { 6, alc882_3ST_ch6_init }, @@ -7603,7 +7876,7 @@ static struct hda_channel_mode alc882_3ST_6ch_modes[3] = { /* * 2ch mode */ -static struct hda_verb alc883_3ST_ch2_clevo_init[] = { +static const struct hda_verb alc883_3ST_ch2_clevo_init[] = { { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP }, { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -7615,7 +7888,7 @@ static struct hda_verb alc883_3ST_ch2_clevo_init[] = { /* * 4ch mode */ -static struct hda_verb alc883_3ST_ch4_clevo_init[] = { +static const struct hda_verb alc883_3ST_ch4_clevo_init[] = { { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, @@ -7628,7 +7901,7 @@ static struct hda_verb alc883_3ST_ch4_clevo_init[] = { /* * 6ch mode */ -static struct hda_verb alc883_3ST_ch6_clevo_init[] = { +static const struct hda_verb alc883_3ST_ch6_clevo_init[] = { { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -7639,7 +7912,7 @@ static struct hda_verb alc883_3ST_ch6_clevo_init[] = { { } /* end */ }; -static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { +static const struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { { 2, alc883_3ST_ch2_clevo_init }, { 4, alc883_3ST_ch4_clevo_init }, { 6, alc883_3ST_ch6_clevo_init }, @@ -7649,7 +7922,7 @@ static struct hda_channel_mode alc883_3ST_6ch_clevo_modes[3] = { /* * 6ch mode */ -static struct hda_verb alc882_sixstack_ch6_init[] = { +static const struct hda_verb alc882_sixstack_ch6_init[] = { { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7660,7 +7933,7 @@ static struct hda_verb alc882_sixstack_ch6_init[] = { /* * 8ch mode */ -static struct hda_verb alc882_sixstack_ch8_init[] = { +static const struct hda_verb alc882_sixstack_ch8_init[] = { { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7668,7 +7941,7 @@ static struct hda_verb alc882_sixstack_ch8_init[] = { { } /* end */ }; -static struct hda_channel_mode alc882_sixstack_modes[2] = { +static const struct hda_channel_mode alc882_sixstack_modes[2] = { { 6, alc882_sixstack_ch6_init }, { 8, alc882_sixstack_ch8_init }, }; @@ -7676,7 +7949,7 @@ static struct hda_channel_mode alc882_sixstack_modes[2] = { /* Macbook Air 2,1 */ -static struct hda_channel_mode alc885_mba21_ch_modes[1] = { +static const struct hda_channel_mode alc885_mba21_ch_modes[1] = { { 2, NULL }, }; @@ -7687,7 +7960,7 @@ static struct hda_channel_mode alc885_mba21_ch_modes[1] = { /* * 2ch mode */ -static struct hda_verb alc885_mbp_ch2_init[] = { +static const struct hda_verb alc885_mbp_ch2_init[] = { { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, { 0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, @@ -7697,7 +7970,7 @@ static struct hda_verb alc885_mbp_ch2_init[] = { /* * 4ch mode */ -static struct hda_verb alc885_mbp_ch4_init[] = { +static const struct hda_verb alc885_mbp_ch4_init[] = { { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x1a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, { 0x1a, AC_VERB_SET_CONNECT_SEL, 0x01 }, @@ -7706,7 +7979,7 @@ static struct hda_verb alc885_mbp_ch4_init[] = { { } /* end */ }; -static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { +static const struct hda_channel_mode alc885_mbp_4ch_modes[2] = { { 2, alc885_mbp_ch2_init }, { 4, alc885_mbp_ch4_init }, }; @@ -7716,7 +7989,7 @@ static struct hda_channel_mode alc885_mbp_4ch_modes[2] = { * Speakers/Woofer/HP = Front * LineIn = Input */ -static struct hda_verb alc885_mb5_ch2_init[] = { +static const struct hda_verb alc885_mb5_ch2_init[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, { } /* end */ @@ -7728,14 +8001,14 @@ static struct hda_verb alc885_mb5_ch2_init[] = { * Woofer = LFE * LineIn = Surround */ -static struct hda_verb alc885_mb5_ch6_init[] = { +static const struct hda_verb alc885_mb5_ch6_init[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, { } /* end */ }; -static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { +static const struct hda_channel_mode alc885_mb5_6ch_modes[2] = { { 2, alc885_mb5_ch2_init }, { 6, alc885_mb5_ch6_init }, }; @@ -7745,7 +8018,7 @@ static struct hda_channel_mode alc885_mb5_6ch_modes[2] = { /* * 2ch mode */ -static struct hda_verb alc883_4ST_ch2_init[] = { +static const struct hda_verb alc883_4ST_ch2_init[] = { { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, @@ -7758,7 +8031,7 @@ static struct hda_verb alc883_4ST_ch2_init[] = { /* * 4ch mode */ -static struct hda_verb alc883_4ST_ch4_init[] = { +static const struct hda_verb alc883_4ST_ch4_init[] = { { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, @@ -7772,7 +8045,7 @@ static struct hda_verb alc883_4ST_ch4_init[] = { /* * 6ch mode */ -static struct hda_verb alc883_4ST_ch6_init[] = { +static const struct hda_verb alc883_4ST_ch6_init[] = { { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7787,7 +8060,7 @@ static struct hda_verb alc883_4ST_ch6_init[] = { /* * 8ch mode */ -static struct hda_verb alc883_4ST_ch8_init[] = { +static const struct hda_verb alc883_4ST_ch8_init[] = { { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, { 0x17, AC_VERB_SET_CONNECT_SEL, 0x03 }, @@ -7800,7 +8073,7 @@ static struct hda_verb alc883_4ST_ch8_init[] = { { } /* end */ }; -static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { +static const struct hda_channel_mode alc883_4ST_8ch_modes[4] = { { 2, alc883_4ST_ch2_init }, { 4, alc883_4ST_ch4_init }, { 6, alc883_4ST_ch6_init }, @@ -7811,7 +8084,7 @@ static struct hda_channel_mode alc883_4ST_8ch_modes[4] = { /* * 2ch mode */ -static struct hda_verb alc883_3ST_ch2_intel_init[] = { +static const struct hda_verb alc883_3ST_ch2_intel_init[] = { { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, @@ -7822,7 +8095,7 @@ static struct hda_verb alc883_3ST_ch2_intel_init[] = { /* * 4ch mode */ -static struct hda_verb alc883_3ST_ch4_intel_init[] = { +static const struct hda_verb alc883_3ST_ch4_intel_init[] = { { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7834,7 +8107,7 @@ static struct hda_verb alc883_3ST_ch4_intel_init[] = { /* * 6ch mode */ -static struct hda_verb alc883_3ST_ch6_intel_init[] = { +static const struct hda_verb alc883_3ST_ch6_intel_init[] = { { 0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, { 0x19, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -7844,7 +8117,7 @@ static struct hda_verb alc883_3ST_ch6_intel_init[] = { { } /* end */ }; -static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { +static const struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { { 2, alc883_3ST_ch2_intel_init }, { 4, alc883_3ST_ch4_intel_init }, { 6, alc883_3ST_ch6_intel_init }, @@ -7853,7 +8126,7 @@ static struct hda_channel_mode alc883_3ST_6ch_intel_modes[3] = { /* * 2ch mode */ -static struct hda_verb alc889_ch2_intel_init[] = { +static const struct hda_verb alc889_ch2_intel_init[] = { { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, { 0x19, AC_VERB_SET_CONNECT_SEL, 0x00 }, { 0x16, AC_VERB_SET_CONNECT_SEL, 0x00 }, @@ -7866,7 +8139,7 @@ static struct hda_verb alc889_ch2_intel_init[] = { /* * 6ch mode */ -static struct hda_verb alc889_ch6_intel_init[] = { +static const struct hda_verb alc889_ch6_intel_init[] = { { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -7879,7 +8152,7 @@ static struct hda_verb alc889_ch6_intel_init[] = { /* * 8ch mode */ -static struct hda_verb alc889_ch8_intel_init[] = { +static const struct hda_verb alc889_ch8_intel_init[] = { { 0x14, AC_VERB_SET_CONNECT_SEL, 0x00 }, { 0x19, AC_VERB_SET_CONNECT_SEL, 0x01 }, { 0x16, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -7890,7 +8163,7 @@ static struct hda_verb alc889_ch8_intel_init[] = { { } /* end */ }; -static struct hda_channel_mode alc889_8ch_intel_modes[3] = { +static const struct hda_channel_mode alc889_8ch_intel_modes[3] = { { 2, alc889_ch2_intel_init }, { 6, alc889_ch6_intel_init }, { 8, alc889_ch8_intel_init }, @@ -7899,7 +8172,7 @@ static struct hda_channel_mode alc889_8ch_intel_modes[3] = { /* * 6ch mode */ -static struct hda_verb alc883_sixstack_ch6_init[] = { +static const struct hda_verb alc883_sixstack_ch6_init[] = { { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7910,7 +8183,7 @@ static struct hda_verb alc883_sixstack_ch6_init[] = { /* * 8ch mode */ -static struct hda_verb alc883_sixstack_ch8_init[] = { +static const struct hda_verb alc883_sixstack_ch8_init[] = { { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -7918,7 +8191,7 @@ static struct hda_verb alc883_sixstack_ch8_init[] = { { } /* end */ }; -static struct hda_channel_mode alc883_sixstack_modes[2] = { +static const struct hda_channel_mode alc883_sixstack_modes[2] = { { 6, alc883_sixstack_ch6_init }, { 8, alc883_sixstack_ch8_init }, }; @@ -7927,7 +8200,7 @@ static struct hda_channel_mode alc883_sixstack_modes[2] = { /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b */ -static struct snd_kcontrol_new alc882_base_mixer[] = { +static const struct snd_kcontrol_new alc882_base_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -7954,14 +8227,14 @@ static struct snd_kcontrol_new alc882_base_mixer[] = { /* Macbook Air 2,1 same control for HP and internal Speaker */ -static struct snd_kcontrol_new alc885_mba21_mixer[] = { +static const struct snd_kcontrol_new alc885_mba21_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_OUTPUT), { } }; -static struct snd_kcontrol_new alc885_mbp3_mixer[] = { +static const struct snd_kcontrol_new alc885_mbp3_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), HDA_BIND_MUTE ("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0e, 0x00, HDA_OUTPUT), @@ -7976,7 +8249,7 @@ static struct snd_kcontrol_new alc885_mbp3_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc885_mb5_mixer[] = { +static const struct snd_kcontrol_new alc885_mb5_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), @@ -7994,7 +8267,7 @@ static struct snd_kcontrol_new alc885_mb5_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc885_macmini3_mixer[] = { +static const struct snd_kcontrol_new alc885_macmini3_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), HDA_BIND_MUTE ("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x00, HDA_OUTPUT), @@ -8009,14 +8282,14 @@ static struct snd_kcontrol_new alc885_macmini3_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc885_imac91_mixer[] = { +static const struct snd_kcontrol_new alc885_imac91_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x00, HDA_OUTPUT), HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 0x02, HDA_INPUT), { } /* end */ }; -static struct snd_kcontrol_new alc882_w2jc_mixer[] = { +static const struct snd_kcontrol_new alc882_w2jc_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -8029,7 +8302,7 @@ static struct snd_kcontrol_new alc882_w2jc_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc882_targa_mixer[] = { +static const struct snd_kcontrol_new alc882_targa_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -8049,7 +8322,7 @@ static struct snd_kcontrol_new alc882_targa_mixer[] = { /* Pin assignment: Front=0x14, HP = 0x15, Front = 0x16, ??? * Front Mic=0x18, Line In = 0x1a, Line In = 0x1b, CD = 0x1c */ -static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { +static const struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -8066,7 +8339,7 @@ static struct snd_kcontrol_new alc882_asus_a7j_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { +static const struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -8080,7 +8353,7 @@ static struct snd_kcontrol_new alc882_asus_a7m_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc882_chmode_mixer[] = { +static const struct snd_kcontrol_new alc882_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", @@ -8091,7 +8364,7 @@ static struct snd_kcontrol_new alc882_chmode_mixer[] = { { } /* end */ }; -static struct hda_verb alc882_base_init_verbs[] = { +static const struct hda_verb alc882_base_init_verbs[] = { /* Front mixer: unmute input/output amp left and right (volume = 0) */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, @@ -8153,7 +8426,7 @@ static struct hda_verb alc882_base_init_verbs[] = { { } }; -static struct hda_verb alc882_adc1_init_verbs[] = { +static const struct hda_verb alc882_adc1_init_verbs[] = { /* Input mixer1: unmute Mic, F-Mic, Line, CD inputs */ {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, @@ -8165,26 +8438,26 @@ static struct hda_verb alc882_adc1_init_verbs[] = { { } }; -static struct hda_verb alc882_eapd_verbs[] = { +static const struct hda_verb alc882_eapd_verbs[] = { /* change to EAPD mode */ {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, {0x20, AC_VERB_SET_PROC_COEF, 0x3060}, { } }; -static struct hda_verb alc889_eapd_verbs[] = { +static const struct hda_verb alc889_eapd_verbs[] = { {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, { } }; -static struct hda_verb alc_hp15_unsol_verbs[] = { +static const struct hda_verb alc_hp15_unsol_verbs[] = { {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {} }; -static struct hda_verb alc885_init_verbs[] = { +static const struct hda_verb alc885_init_verbs[] = { /* Front mixer: unmute input/output amp left and right (volume = 0) */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -8243,7 +8516,7 @@ static struct hda_verb alc885_init_verbs[] = { { } }; -static struct hda_verb alc885_init_input_verbs[] = { +static const struct hda_verb alc885_init_input_verbs[] = { {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(2)}, {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3)}, @@ -8252,7 +8525,7 @@ static struct hda_verb alc885_init_input_verbs[] = { /* Unmute Selector 24h and set the default input to front mic */ -static struct hda_verb alc889_init_input_verbs[] = { +static const struct hda_verb alc889_init_input_verbs[] = { {0x24, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, { } @@ -8262,7 +8535,7 @@ static struct hda_verb alc889_init_input_verbs[] = { #define alc883_init_verbs alc882_base_init_verbs /* Mac Pro test */ -static struct snd_kcontrol_new alc882_macpro_mixer[] = { +static const struct snd_kcontrol_new alc882_macpro_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x18, 0x0, HDA_OUTPUT), @@ -8275,7 +8548,7 @@ static struct snd_kcontrol_new alc882_macpro_mixer[] = { { } /* end */ }; -static struct hda_verb alc882_macpro_init_verbs[] = { +static const struct hda_verb alc882_macpro_init_verbs[] = { /* Front mixer: unmute input/output amp left and right (volume = 0) */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, @@ -8327,7 +8600,7 @@ static struct hda_verb alc882_macpro_init_verbs[] = { }; /* Macbook 5,1 */ -static struct hda_verb alc885_mb5_init_verbs[] = { +static const struct hda_verb alc885_mb5_init_verbs[] = { /* DACs */ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -8376,7 +8649,7 @@ static struct hda_verb alc885_mb5_init_verbs[] = { }; /* Macmini 3,1 */ -static struct hda_verb alc885_macmini3_init_verbs[] = { +static const struct hda_verb alc885_macmini3_init_verbs[] = { /* DACs */ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -8423,7 +8696,7 @@ static struct hda_verb alc885_macmini3_init_verbs[] = { }; -static struct hda_verb alc885_mba21_init_verbs[] = { +static const struct hda_verb alc885_mba21_init_verbs[] = { /*Internal and HP Speaker Mixer*/ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -8446,7 +8719,7 @@ static struct hda_verb alc885_mba21_init_verbs[] = { /* Macbook Pro rev3 */ -static struct hda_verb alc885_mbp3_init_verbs[] = { +static const struct hda_verb alc885_mbp3_init_verbs[] = { /* Front mixer: unmute input/output amp left and right (volume = 0) */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, @@ -8510,7 +8783,7 @@ static struct hda_verb alc885_mbp3_init_verbs[] = { }; /* iMac 9,1 */ -static struct hda_verb alc885_imac91_init_verbs[] = { +static const struct hda_verb alc885_imac91_init_verbs[] = { /* Internal Speaker Pin (0x0c) */ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, (PIN_OUT | AC_PINCTL_VREF_50) }, {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -8565,14 +8838,14 @@ static struct hda_verb alc885_imac91_init_verbs[] = { }; /* iMac 24 mixer. */ -static struct snd_kcontrol_new alc885_imac24_mixer[] = { +static const struct snd_kcontrol_new alc885_imac24_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x00, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x00, HDA_INPUT), { } /* end */ }; /* iMac 24 init verbs. */ -static struct hda_verb alc885_imac24_init_verbs[] = { +static const struct hda_verb alc885_imac24_init_verbs[] = { /* Internal speakers: output 0 (0x0c) */ {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -8600,6 +8873,8 @@ static void alc885_imac24_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x18; spec->autocfg.speaker_pins[1] = 0x1a; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } #define alc885_mb5_setup alc885_imac24_setup @@ -8612,6 +8887,8 @@ static void alc885_mba21_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x18; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } @@ -8622,6 +8899,8 @@ static void alc885_mbp3_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc885_imac91_setup(struct hda_codec *codec) @@ -8631,9 +8910,11 @@ static void alc885_imac91_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x18; spec->autocfg.speaker_pins[1] = 0x1a; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static struct hda_verb alc882_targa_verbs[] = { +static const struct hda_verb alc882_targa_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -8652,7 +8933,7 @@ static struct hda_verb alc882_targa_verbs[] = { static void alc882_targa_automute(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - alc_automute_amp(codec); + alc_hp_automute(codec); snd_hda_codec_write_cache(codec, 1, 0, AC_VERB_SET_GPIO_DATA, spec->jack_present ? 1 : 3); } @@ -8663,6 +8944,8 @@ static void alc882_targa_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x1b; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) @@ -8671,7 +8954,7 @@ static void alc882_targa_unsol_event(struct hda_codec *codec, unsigned int res) alc882_targa_automute(codec); } -static struct hda_verb alc882_asus_a7j_verbs[] = { +static const struct hda_verb alc882_asus_a7j_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -8689,7 +8972,7 @@ static struct hda_verb alc882_asus_a7j_verbs[] = { { } /* end */ }; -static struct hda_verb alc882_asus_a7m_verbs[] = { +static const struct hda_verb alc882_asus_a7m_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -8750,13 +9033,13 @@ static void alc885_macpro_init_hook(struct hda_codec *codec) static void alc885_imac24_init_hook(struct hda_codec *codec) { alc885_macpro_init_hook(codec); - alc_automute_amp(codec); + alc_hp_automute(codec); } /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc883_auto_init_verbs[] = { +static const struct hda_verb alc883_auto_init_verbs[] = { /* * Unmute ADC0-2 and set the default input to mic-in */ @@ -8796,7 +9079,7 @@ static struct hda_verb alc883_auto_init_verbs[] = { }; /* 2ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:front) */ -static struct hda_verb alc889A_mb31_ch2_init[] = { +static const struct hda_verb alc889A_mb31_ch2_init[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ @@ -8805,7 +9088,7 @@ static struct hda_verb alc889A_mb31_ch2_init[] = { }; /* 4ch mode (Speaker:front, Subwoofer:CLFE, Line:CLFE, Headphones:front) */ -static struct hda_verb alc889A_mb31_ch4_init[] = { +static const struct hda_verb alc889A_mb31_ch4_init[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* HP as front */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ @@ -8814,7 +9097,7 @@ static struct hda_verb alc889A_mb31_ch4_init[] = { }; /* 5ch mode (Speaker:front, Subwoofer:CLFE, Line:input, Headphones:rear) */ -static struct hda_verb alc889A_mb31_ch5_init[] = { +static const struct hda_verb alc889A_mb31_ch5_init[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as rear */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Subwoofer on */ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* Line as input */ @@ -8823,7 +9106,7 @@ static struct hda_verb alc889A_mb31_ch5_init[] = { }; /* 6ch mode (Speaker:front, Subwoofer:off, Line:CLFE, Headphones:Rear) */ -static struct hda_verb alc889A_mb31_ch6_init[] = { +static const struct hda_verb alc889A_mb31_ch6_init[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* HP as front */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, /* Subwoofer off */ {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, /* Line as output */ @@ -8831,14 +9114,14 @@ static struct hda_verb alc889A_mb31_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { +static const struct hda_channel_mode alc889A_mb31_6ch_modes[4] = { { 2, alc889A_mb31_ch2_init }, { 4, alc889A_mb31_ch4_init }, { 5, alc889A_mb31_ch5_init }, { 6, alc889A_mb31_ch6_init }, }; -static struct hda_verb alc883_medion_eapd_verbs[] = { +static const struct hda_verb alc883_medion_eapd_verbs[] = { /* eanable EAPD on medion laptop */ {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, @@ -8847,7 +9130,7 @@ static struct hda_verb alc883_medion_eapd_verbs[] = { #define alc883_base_mixer alc882_base_mixer -static struct snd_kcontrol_new alc883_mitac_mixer[] = { +static const struct snd_kcontrol_new alc883_mitac_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), @@ -8864,7 +9147,7 @@ static struct snd_kcontrol_new alc883_mitac_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { +static const struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -8878,7 +9161,7 @@ static struct snd_kcontrol_new alc883_clevo_m720_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { +static const struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Headphone Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -8892,7 +9175,7 @@ static struct snd_kcontrol_new alc883_2ch_fujitsu_pi2515_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { +static const struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -8909,7 +9192,7 @@ static struct snd_kcontrol_new alc883_3ST_2ch_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { +static const struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -8932,7 +9215,7 @@ static struct snd_kcontrol_new alc883_3ST_6ch_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { +static const struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -8956,7 +9239,7 @@ static struct snd_kcontrol_new alc883_3ST_6ch_intel_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { +static const struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -8980,7 +9263,7 @@ static struct snd_kcontrol_new alc885_8ch_intel_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_fivestack_mixer[] = { +static const struct snd_kcontrol_new alc883_fivestack_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -9003,7 +9286,7 @@ static struct snd_kcontrol_new alc883_fivestack_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_targa_mixer[] = { +static const struct snd_kcontrol_new alc883_targa_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -9024,7 +9307,7 @@ static struct snd_kcontrol_new alc883_targa_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { +static const struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -9040,7 +9323,7 @@ static struct snd_kcontrol_new alc883_targa_2ch_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { +static const struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { HDA_CODEC_VOLUME("Side Playback Volume", 0x0f, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Side Playback Switch", 0x0f, 2, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x0b, 0x1, HDA_INPUT), @@ -9049,7 +9332,7 @@ static struct snd_kcontrol_new alc883_targa_8ch_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { +static const struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -9061,7 +9344,7 @@ static struct snd_kcontrol_new alc883_lenovo_101e_2ch_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { +static const struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -9074,7 +9357,7 @@ static struct snd_kcontrol_new alc883_lenovo_nb0763_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { +static const struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -9084,7 +9367,7 @@ static struct snd_kcontrol_new alc883_medion_wim2160_mixer[] = { { } /* end */ }; -static struct hda_verb alc883_medion_wim2160_verbs[] = { +static const struct hda_verb alc883_medion_wim2160_verbs[] = { /* Unmute front mixer */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -9108,9 +9391,11 @@ static void alc883_medion_wim2160_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x1a; spec->autocfg.speaker_pins[0] = 0x15; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { +static const struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -9122,7 +9407,7 @@ static struct snd_kcontrol_new alc883_acer_aspire_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { +static const struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("LFE Playback Volume", 0x0f, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), @@ -9135,7 +9420,7 @@ static struct snd_kcontrol_new alc888_acer_aspire_6530_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { +static const struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x0e, 0x0, HDA_OUTPUT), @@ -9160,7 +9445,7 @@ static struct snd_kcontrol_new alc888_lenovo_sky_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc889A_mb31_mixer[] = { +static const struct snd_kcontrol_new alc889A_mb31_mixer[] = { /* Output mixers */ HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x00, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 0x02, HDA_INPUT), @@ -9186,7 +9471,7 @@ static struct snd_kcontrol_new alc889A_mb31_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_vaiott_mixer[] = { +static const struct snd_kcontrol_new alc883_vaiott_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -9196,7 +9481,7 @@ static struct snd_kcontrol_new alc883_vaiott_mixer[] = { { } /* end */ }; -static struct hda_bind_ctls alc883_bind_cap_vol = { +static const struct hda_bind_ctls alc883_bind_cap_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), @@ -9205,7 +9490,7 @@ static struct hda_bind_ctls alc883_bind_cap_vol = { }, }; -static struct hda_bind_ctls alc883_bind_cap_switch = { +static const struct hda_bind_ctls alc883_bind_cap_switch = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x08, 3, 0, HDA_INPUT), @@ -9214,7 +9499,7 @@ static struct hda_bind_ctls alc883_bind_cap_switch = { }, }; -static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { +static const struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -9226,7 +9511,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { +static const struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { HDA_BIND_VOL("Capture Volume", &alc883_bind_cap_vol), HDA_BIND_SW("Capture Switch", &alc883_bind_cap_switch), { @@ -9241,7 +9526,7 @@ static struct snd_kcontrol_new alc883_asus_eee1601_cap_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc883_chmode_mixer[] = { +static const struct snd_kcontrol_new alc883_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", @@ -9260,9 +9545,11 @@ static void alc883_mitac_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; spec->autocfg.speaker_pins[1] = 0x17; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static struct hda_verb alc883_mitac_verbs[] = { +static const struct hda_verb alc883_mitac_verbs[] = { /* HP */ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -9277,7 +9564,7 @@ static struct hda_verb alc883_mitac_verbs[] = { { } /* end */ }; -static struct hda_verb alc883_clevo_m540r_verbs[] = { +static const struct hda_verb alc883_clevo_m540r_verbs[] = { /* HP */ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -9293,7 +9580,7 @@ static struct hda_verb alc883_clevo_m540r_verbs[] = { { } /* end */ }; -static struct hda_verb alc883_clevo_m720_verbs[] = { +static const struct hda_verb alc883_clevo_m720_verbs[] = { /* HP */ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -9308,7 +9595,7 @@ static struct hda_verb alc883_clevo_m720_verbs[] = { { } /* end */ }; -static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { +static const struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { /* HP */ {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -9322,7 +9609,7 @@ static struct hda_verb alc883_2ch_fujitsu_pi2515_verbs[] = { { } /* end */ }; -static struct hda_verb alc883_targa_verbs[] = { +static const struct hda_verb alc883_targa_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -9351,14 +9638,14 @@ static struct hda_verb alc883_targa_verbs[] = { { } /* end */ }; -static struct hda_verb alc883_lenovo_101e_verbs[] = { +static const struct hda_verb alc883_lenovo_101e_verbs[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_FRONT_EVENT|AC_USRSP_EN}, {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT|AC_USRSP_EN}, { } /* end */ }; -static struct hda_verb alc883_lenovo_nb0763_verbs[] = { +static const struct hda_verb alc883_lenovo_nb0763_verbs[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, @@ -9366,7 +9653,7 @@ static struct hda_verb alc883_lenovo_nb0763_verbs[] = { { } /* end */ }; -static struct hda_verb alc888_lenovo_ms7195_verbs[] = { +static const struct hda_verb alc888_lenovo_ms7195_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -9375,7 +9662,7 @@ static struct hda_verb alc888_lenovo_ms7195_verbs[] = { { } /* end */ }; -static struct hda_verb alc883_haier_w66_verbs[] = { +static const struct hda_verb alc883_haier_w66_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -9388,7 +9675,7 @@ static struct hda_verb alc883_haier_w66_verbs[] = { { } /* end */ }; -static struct hda_verb alc888_lenovo_sky_verbs[] = { +static const struct hda_verb alc888_lenovo_sky_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -9400,12 +9687,12 @@ static struct hda_verb alc888_lenovo_sky_verbs[] = { { } /* end */ }; -static struct hda_verb alc888_6st_dell_verbs[] = { +static const struct hda_verb alc888_6st_dell_verbs[] = { {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, { } }; -static struct hda_verb alc883_vaiott_verbs[] = { +static const struct hda_verb alc883_vaiott_verbs[] = { /* HP */ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -9424,9 +9711,11 @@ static void alc888_3st_hp_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[0] = 0x14; spec->autocfg.speaker_pins[1] = 0x16; spec->autocfg.speaker_pins[2] = 0x18; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static struct hda_verb alc888_3st_hp_verbs[] = { +static const struct hda_verb alc888_3st_hp_verbs[] = { {0x14, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Front: output 0 (0x0c) */ {0x16, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Rear : output 1 (0x0d) */ {0x18, AC_VERB_SET_CONNECT_SEL, 0x02}, /* CLFE : output 2 (0x0e) */ @@ -9437,7 +9726,7 @@ static struct hda_verb alc888_3st_hp_verbs[] = { /* * 2ch mode */ -static struct hda_verb alc888_3st_hp_2ch_init[] = { +static const struct hda_verb alc888_3st_hp_2ch_init[] = { { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, @@ -9448,7 +9737,7 @@ static struct hda_verb alc888_3st_hp_2ch_init[] = { /* * 4ch mode */ -static struct hda_verb alc888_3st_hp_4ch_init[] = { +static const struct hda_verb alc888_3st_hp_4ch_init[] = { { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -9460,7 +9749,7 @@ static struct hda_verb alc888_3st_hp_4ch_init[] = { /* * 6ch mode */ -static struct hda_verb alc888_3st_hp_6ch_init[] = { +static const struct hda_verb alc888_3st_hp_6ch_init[] = { { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -9470,39 +9759,21 @@ static struct hda_verb alc888_3st_hp_6ch_init[] = { { } /* end */ }; -static struct hda_channel_mode alc888_3st_hp_modes[3] = { +static const struct hda_channel_mode alc888_3st_hp_modes[3] = { { 2, alc888_3st_hp_2ch_init }, { 4, alc888_3st_hp_4ch_init }, { 6, alc888_3st_hp_6ch_init }, }; -/* toggle front-jack and RCA according to the hp-jack state */ -static void alc888_lenovo_ms7195_front_automute(struct hda_codec *codec) +static void alc888_lenovo_ms7195_setup(struct hda_codec *codec) { - unsigned int present = snd_hda_jack_detect(codec, 0x1b); + struct alc_spec *spec = codec->spec; - snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); -} - -/* toggle RCA according to the front-jack state */ -static void alc888_lenovo_ms7195_rca_automute(struct hda_codec *codec) -{ - unsigned int present = snd_hda_jack_detect(codec, 0x14); - - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); -} - -static void alc883_lenovo_ms7195_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) == ALC880_HP_EVENT) - alc888_lenovo_ms7195_front_automute(codec); - if ((res >> 26) == ALC880_FRONT_EVENT) - alc888_lenovo_ms7195_rca_automute(codec); + spec->autocfg.hp_pins[0] = 0x1b; + spec->autocfg.line_out_pins[0] = 0x14; + spec->autocfg.speaker_pins[0] = 0x15; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } /* toggle speaker-output according to the hp-jack state */ @@ -9512,6 +9783,8 @@ static void alc883_lenovo_nb0763_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x15; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } /* toggle speaker-output according to the hp-jack state */ @@ -9524,11 +9797,13 @@ static void alc883_clevo_m720_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc883_clevo_m720_init_hook(struct hda_codec *codec) { - alc_automute_amp(codec); + alc_hp_automute(codec); alc88x_simple_mic_automute(codec); } @@ -9540,7 +9815,7 @@ static void alc883_clevo_m720_unsol_event(struct hda_codec *codec, alc88x_simple_mic_automute(codec); break; default: - alc_automute_amp_unsol_event(codec, res); + alc_sku_unsol_event(codec, res); break; } } @@ -9552,6 +9827,8 @@ static void alc883_2ch_fujitsu_pi2515_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x15; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc883_haier_w66_setup(struct hda_codec *codec) @@ -9560,33 +9837,21 @@ static void alc883_haier_w66_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x1b; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static void alc883_lenovo_101e_ispeaker_automute(struct hda_codec *codec) +static void alc883_lenovo_101e_setup(struct hda_codec *codec) { - int bits = snd_hda_jack_detect(codec, 0x14) ? HDA_AMP_MUTE : 0; + struct alc_spec *spec = codec->spec; - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, bits); -} - -static void alc883_lenovo_101e_all_automute(struct hda_codec *codec) -{ - int bits = snd_hda_jack_detect(codec, 0x1b) ? HDA_AMP_MUTE : 0; - - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, - HDA_AMP_MUTE, bits); -} - -static void alc883_lenovo_101e_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) == ALC880_HP_EVENT) - alc883_lenovo_101e_all_automute(codec); - if ((res >> 26) == ALC880_FRONT_EVENT) - alc883_lenovo_101e_ispeaker_automute(codec); + spec->autocfg.hp_pins[0] = 0x1b; + spec->autocfg.line_out_pins[0] = 0x14; + spec->autocfg.speaker_pins[0] = 0x15; + spec->automute = 1; + spec->detect_line = 1; + spec->automute_lines = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } /* toggle speaker-output according to the hp-jack state */ @@ -9597,9 +9862,11 @@ static void alc883_acer_aspire_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x15; spec->autocfg.speaker_pins[1] = 0x16; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static struct hda_verb alc883_acer_eapd_verbs[] = { +static const struct hda_verb alc883_acer_eapd_verbs[] = { /* HP Pin: output 0 (0x0c) */ {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -9626,6 +9893,8 @@ static void alc888_6st_dell_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[1] = 0x15; spec->autocfg.speaker_pins[2] = 0x16; spec->autocfg.speaker_pins[3] = 0x17; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc888_lenovo_sky_setup(struct hda_codec *codec) @@ -9638,6 +9907,8 @@ static void alc888_lenovo_sky_setup(struct hda_codec *codec) spec->autocfg.speaker_pins[2] = 0x16; spec->autocfg.speaker_pins[3] = 0x17; spec->autocfg.speaker_pins[4] = 0x1a; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc883_vaiott_setup(struct hda_codec *codec) @@ -9647,9 +9918,11 @@ static void alc883_vaiott_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; spec->autocfg.speaker_pins[1] = 0x17; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static struct hda_verb alc888_asus_m90v_verbs[] = { +static const struct hda_verb alc888_asus_m90v_verbs[] = { {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, @@ -9672,9 +9945,11 @@ static void alc883_mode2_setup(struct hda_codec *codec) spec->ext_mic.mux_idx = 0; spec->int_mic.mux_idx = 1; spec->auto_mic = 1; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static struct hda_verb alc888_asus_eee1601_verbs[] = { +static const struct hda_verb alc888_asus_eee1601_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, @@ -9693,10 +9968,10 @@ static void alc883_eee1601_inithook(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x1b; - alc_automute_pin(codec); + alc_hp_automute(codec); } -static struct hda_verb alc889A_mb31_verbs[] = { +static const struct hda_verb alc889A_mb31_verbs[] = { /* Init rear pin (used as headphone output) */ {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc4}, /* Apple Headphones */ {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Connect to front */ @@ -9742,11 +10017,11 @@ static void alc889A_mb31_unsol_event(struct hda_codec *codec, unsigned int res) #define alc882_pcm_digital_playback alc880_pcm_digital_playback #define alc882_pcm_digital_capture alc880_pcm_digital_capture -static hda_nid_t alc883_slave_dig_outs[] = { +static const hda_nid_t alc883_slave_dig_outs[] = { ALC1200_DIGOUT_NID, 0, }; -static hda_nid_t alc1200_slave_dig_outs[] = { +static const hda_nid_t alc1200_slave_dig_outs[] = { ALC883_DIGOUT_NID, 0, }; @@ -9805,7 +10080,7 @@ static const char * const alc882_models[ALC882_MODEL_LAST] = { [ALC882_AUTO] = "auto", }; -static struct snd_pci_quirk alc882_cfg_tbl[] = { +static const struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1019, 0x6668, "ECS", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1025, 0x006c, "Acer Aspire 9810", ALC883_ACER_ASPIRE), @@ -9932,7 +10207,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { }; /* codec SSID table for Intel Mac */ -static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { +static const struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { SND_PCI_QUIRK(0x106b, 0x00a0, "MacBookPro 3,1", ALC885_MBP3), SND_PCI_QUIRK(0x106b, 0x00a1, "Macbook", ALC885_MBP3), SND_PCI_QUIRK(0x106b, 0x00a4, "MacbookPro 4,1", ALC885_MBP3), @@ -9959,7 +10234,7 @@ static struct snd_pci_quirk alc882_ssid_cfg_tbl[] = { {} /* terminator */ }; -static struct alc_config_preset alc882_presets[] = { +static const struct alc_config_preset alc882_presets[] = { [ALC882_3ST_DIG] = { .mixers = { alc882_base_mixer }, .init_verbs = { alc882_base_init_verbs, @@ -10015,9 +10290,9 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc885_mba21_ch_modes, .num_channel_mode = ARRAY_SIZE(alc885_mba21_ch_modes), .input_mux = &alc882_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_mba21_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC885_MBP3] = { .mixers = { alc885_mbp3_mixer, alc882_chmode_mixer }, @@ -10031,9 +10306,9 @@ static struct alc_config_preset alc882_presets[] = { .input_mux = &alc882_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, .dig_in_nid = ALC882_DIGIN_NID, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_mbp3_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC885_MB5] = { .mixers = { alc885_mb5_mixer, alc882_chmode_mixer }, @@ -10046,9 +10321,9 @@ static struct alc_config_preset alc882_presets[] = { .input_mux = &mb5_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, .dig_in_nid = ALC882_DIGIN_NID, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_mb5_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC885_MACMINI3] = { .mixers = { alc885_macmini3_mixer, alc882_chmode_mixer }, @@ -10061,9 +10336,9 @@ static struct alc_config_preset alc882_presets[] = { .input_mux = &macmini3_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, .dig_in_nid = ALC882_DIGIN_NID, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_macmini3_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC885_MACPRO] = { .mixers = { alc882_macpro_mixer }, @@ -10087,7 +10362,7 @@ static struct alc_config_preset alc882_presets[] = { .num_channel_mode = ARRAY_SIZE(alc882_ch_modes), .channel_mode = alc882_ch_modes, .input_mux = &alc882_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_imac24_setup, .init_hook = alc885_imac24_init_hook, }, @@ -10102,9 +10377,9 @@ static struct alc_config_preset alc882_presets[] = { .input_mux = &alc889A_imac91_capture_source, .dig_out_nid = ALC882_DIGOUT_NID, .dig_in_nid = ALC882_DIGIN_NID, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc885_imac91_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC882_TARGA] = { .mixers = { alc882_targa_mixer, alc882_chmode_mixer }, @@ -10120,7 +10395,7 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc882_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc882_capture_source, - .unsol_event = alc882_targa_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc882_targa_setup, .init_hook = alc882_targa_automute, }, @@ -10214,8 +10489,8 @@ static struct alc_config_preset alc882_presets[] = { .capsrc_nids = alc889_capsrc_nids, .input_mux = &alc889_capture_source, .setup = alc889_automute_setup, - .init_hook = alc_automute_amp, - .unsol_event = alc_automute_amp_unsol_event, + .init_hook = alc_hp_automute, + .unsol_event = alc_sku_unsol_event, .need_dac_fix = 1, }, [ALC889_INTEL] = { @@ -10235,7 +10510,7 @@ static struct alc_config_preset alc882_presets[] = { .input_mux = &alc889_capture_source, .setup = alc889_automute_setup, .init_hook = alc889_intel_init_hook, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .need_dac_fix = 1, }, [ALC883_6ST_DIG] = { @@ -10324,9 +10599,9 @@ static struct alc_config_preset alc882_presets[] = { .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc883_acer_aspire_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC888_ACER_ASPIRE_4930G] = { .mixers = { alc888_acer_aspire_4930g_mixer, @@ -10346,9 +10621,9 @@ static struct alc_config_preset alc882_presets[] = { .num_mux_defs = ARRAY_SIZE(alc888_2_capture_sources), .input_mux = alc888_2_capture_sources, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc888_acer_aspire_4930g_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC888_ACER_ASPIRE_6530G] = { .mixers = { alc888_acer_aspire_6530_mixer }, @@ -10365,9 +10640,9 @@ static struct alc_config_preset alc882_presets[] = { .num_mux_defs = ARRAY_SIZE(alc888_2_capture_sources), .input_mux = alc888_acer_aspire_6530_sources, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc888_acer_aspire_6530g_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC888_ACER_ASPIRE_8930G] = { .mixers = { alc889_acer_aspire_8930g_mixer, @@ -10388,9 +10663,9 @@ static struct alc_config_preset alc882_presets[] = { .num_mux_defs = ARRAY_SIZE(alc889_capture_sources), .input_mux = alc889_capture_sources, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc889_acer_aspire_8930g_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, #ifdef CONFIG_SND_HDA_POWER_SAVE .power_hook = alc_power_eapd, #endif @@ -10411,9 +10686,9 @@ static struct alc_config_preset alc882_presets[] = { .need_dac_fix = 1, .const_channel_count = 6, .input_mux = &alc883_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc888_acer_aspire_7730g_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC883_MEDION] = { .mixers = { alc883_fivestack_mixer, @@ -10440,9 +10715,9 @@ static struct alc_config_preset alc882_presets[] = { .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc883_medion_wim2160_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC883_LAPTOP_EAPD] = { .mixers = { alc883_base_mixer }, @@ -10492,8 +10767,9 @@ static struct alc_config_preset alc882_presets[] = { .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_lenovo_101e_capture_source, - .unsol_event = alc883_lenovo_101e_unsol_event, - .init_hook = alc883_lenovo_101e_all_automute, + .setup = alc883_lenovo_101e_setup, + .unsol_event = alc_sku_unsol_event, + .init_hook = alc_inithook, }, [ALC883_LENOVO_NB0763] = { .mixers = { alc883_lenovo_nb0763_mixer }, @@ -10504,9 +10780,9 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc883_3ST_2ch_modes, .need_dac_fix = 1, .input_mux = &alc883_lenovo_nb0763_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc883_lenovo_nb0763_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC888_LENOVO_MS7195_DIG] = { .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, @@ -10518,8 +10794,9 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc883_3ST_6ch_modes, .need_dac_fix = 1, .input_mux = &alc883_capture_source, - .unsol_event = alc883_lenovo_ms7195_unsol_event, - .init_hook = alc888_lenovo_ms7195_front_automute, + .unsol_event = alc_sku_unsol_event, + .setup = alc888_lenovo_ms7195_setup, + .init_hook = alc_inithook, }, [ALC883_HAIER_W66] = { .mixers = { alc883_targa_2ch_mixer}, @@ -10530,9 +10807,9 @@ static struct alc_config_preset alc882_presets[] = { .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc883_haier_w66_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC888_3ST_HP] = { .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, @@ -10543,9 +10820,9 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc888_3st_hp_modes, .need_dac_fix = 1, .input_mux = &alc883_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc888_3st_hp_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC888_6ST_DELL] = { .mixers = { alc883_base_mixer, alc883_chmode_mixer }, @@ -10557,9 +10834,9 @@ static struct alc_config_preset alc882_presets[] = { .num_channel_mode = ARRAY_SIZE(alc883_sixstack_modes), .channel_mode = alc883_sixstack_modes, .input_mux = &alc883_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc888_6st_dell_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC883_MITAC] = { .mixers = { alc883_mitac_mixer }, @@ -10569,9 +10846,9 @@ static struct alc_config_preset alc882_presets[] = { .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc883_mitac_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC883_FUJITSU_PI2515] = { .mixers = { alc883_2ch_fujitsu_pi2515_mixer }, @@ -10583,9 +10860,9 @@ static struct alc_config_preset alc882_presets[] = { .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_fujitsu_pi2515_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc883_2ch_fujitsu_pi2515_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC888_FUJITSU_XA3530] = { .mixers = { alc888_base_mixer, alc883_chmode_mixer }, @@ -10602,9 +10879,9 @@ static struct alc_config_preset alc882_presets[] = { .num_mux_defs = ARRAY_SIZE(alc888_2_capture_sources), .input_mux = alc888_2_capture_sources, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc888_fujitsu_xa3530_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC888_LENOVO_SKY] = { .mixers = { alc888_lenovo_sky_mixer, alc883_chmode_mixer }, @@ -10616,9 +10893,9 @@ static struct alc_config_preset alc882_presets[] = { .channel_mode = alc883_sixstack_modes, .need_dac_fix = 1, .input_mux = &alc883_lenovo_sky_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc888_lenovo_sky_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC888_ASUS_M90V] = { .mixers = { alc883_3ST_6ch_mixer, alc883_chmode_mixer }, @@ -10686,9 +10963,9 @@ static struct alc_config_preset alc882_presets[] = { .num_channel_mode = ARRAY_SIZE(alc883_3ST_2ch_modes), .channel_mode = alc883_3ST_2ch_modes, .input_mux = &alc883_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc883_vaiott_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, }; @@ -10734,7 +11011,7 @@ static const struct alc_fixup alc882_fixups[] = { }, }; -static struct snd_pci_quirk alc882_fixup_tbl[] = { +static const struct snd_pci_quirk alc882_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0155, "Packard-Bell M5120", PINFIX_PB_M5210), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Y530", PINFIX_LENOVO_Y530), SND_PCI_QUIRK(0x147b, 0x107a, "Abit AW9D-MAX", PINFIX_ABIT_AW9D_MAX), @@ -10842,6 +11119,11 @@ static void alc882_auto_init_input_src(struct hda_codec *codec) const struct hda_input_mux *imux; int conns, mute, idx, item; + /* mute ADC */ + snd_hda_codec_write(codec, spec->adc_nids[c], 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_MUTE(0)); + conns = snd_hda_get_connections(codec, nid, conn_list, ARRAY_SIZE(conn_list)); if (conns < 0) @@ -10921,7 +11203,7 @@ static int alc_auto_add_mic_boost(struct hda_codec *codec) static int alc882_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - static hda_nid_t alc882_ignore[] = { 0x1d, 0 }; + static const hda_nid_t alc882_ignore[] = { 0x1d, 0 }; int err; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, @@ -10932,6 +11214,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec) return 0; /* can't find valid BIOS pin config */ err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc_auto_add_multi_channel_mode(codec); if (err < 0) return err; err = alc880_auto_create_multi_out_ctls(spec, &spec->autocfg); @@ -11135,14 +11420,14 @@ static int patch_alc882(struct hda_codec *codec) #define alc262_modes alc260_modes #define alc262_capture_source alc882_capture_source -static hda_nid_t alc262_dmic_adc_nids[1] = { +static const hda_nid_t alc262_dmic_adc_nids[1] = { /* ADC0 */ 0x09 }; -static hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; +static const hda_nid_t alc262_dmic_capsrc_nids[1] = { 0x22 }; -static struct snd_kcontrol_new alc262_base_mixer[] = { +static const struct snd_kcontrol_new alc262_base_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -11163,71 +11448,30 @@ static struct snd_kcontrol_new alc262_base_mixer[] = { }; /* update HP, line and mono-out pins according to the master switch */ -static void alc262_hp_master_update(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - int val = spec->master_sw; +#define alc262_hp_master_update alc260_hp_master_update - /* HP & line-out */ - snd_hda_codec_write_cache(codec, 0x1b, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - val ? PIN_HP : 0); - snd_hda_codec_write_cache(codec, 0x15, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - val ? PIN_HP : 0); - /* mono (speaker) depending on the HP jack sense */ - val = val && !spec->jack_present; - snd_hda_codec_write_cache(codec, 0x16, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, - val ? PIN_OUT : 0); -} - -static void alc262_hp_bpc_automute(struct hda_codec *codec) +static void alc262_hp_bpc_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - spec->jack_present = snd_hda_jack_detect(codec, 0x1b); - alc262_hp_master_update(codec); + spec->autocfg.hp_pins[0] = 0x1b; + spec->autocfg.speaker_pins[0] = 0x16; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; } -static void alc262_hp_bpc_unsol_event(struct hda_codec *codec, unsigned int res) -{ - if ((res >> 26) != ALC880_HP_EVENT) - return; - alc262_hp_bpc_automute(codec); -} - -static void alc262_hp_wildwest_automute(struct hda_codec *codec) +static void alc262_hp_wildwest_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - spec->jack_present = snd_hda_jack_detect(codec, 0x15); - alc262_hp_master_update(codec); -} - -static void alc262_hp_wildwest_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) != ALC880_HP_EVENT) - return; - alc262_hp_wildwest_automute(codec); + spec->autocfg.hp_pins[0] = 0x15; + spec->autocfg.speaker_pins[0] = 0x16; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; } #define alc262_hp_master_sw_get alc260_hp_master_sw_get - -static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct alc_spec *spec = codec->spec; - int val = !!*ucontrol->value.integer.value; - - if (val == spec->master_sw) - return 0; - spec->master_sw = val; - alc262_hp_master_update(codec); - return 1; -} +#define alc262_hp_master_sw_put alc260_hp_master_sw_put #define ALC262_HP_MASTER_SWITCH \ { \ @@ -11244,7 +11488,7 @@ static int alc262_hp_master_sw_put(struct snd_kcontrol *kcontrol, } -static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { +static const struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { ALC262_HP_MASTER_SWITCH, HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -11268,7 +11512,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { +static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { ALC262_HP_MASTER_SWITCH, HDA_CODEC_VOLUME("Front Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -11288,7 +11532,7 @@ static struct snd_kcontrol_new alc262_HP_BPC_WildWest_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { +static const struct snd_kcontrol_new alc262_HP_BPC_WildWest_option_mixer[] = { HDA_CODEC_VOLUME("Rear Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Rear Mic Playback Switch", 0x0b, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Rear Mic Boost Volume", 0x18, 0, HDA_INPUT), @@ -11302,9 +11546,11 @@ static void alc262_hp_t5735_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; } -static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { +static const struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0d, 0x0, HDA_OUTPUT), @@ -11315,7 +11561,7 @@ static struct snd_kcontrol_new alc262_hp_t5735_mixer[] = { { } /* end */ }; -static struct hda_verb alc262_hp_t5735_verbs[] = { +static const struct hda_verb alc262_hp_t5735_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -11323,7 +11569,7 @@ static struct hda_verb alc262_hp_t5735_verbs[] = { { } }; -static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { +static const struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { HDA_CODEC_VOLUME("Headphone Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0e, 0x0, HDA_OUTPUT), @@ -11333,7 +11579,7 @@ static struct snd_kcontrol_new alc262_hp_rp5700_mixer[] = { { } /* end */ }; -static struct hda_verb alc262_hp_rp5700_verbs[] = { +static const struct hda_verb alc262_hp_rp5700_verbs[] = { {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -11347,7 +11593,7 @@ static struct hda_verb alc262_hp_rp5700_verbs[] = { {} }; -static struct hda_input_mux alc262_hp_rp5700_capture_source = { +static const struct hda_input_mux alc262_hp_rp5700_capture_source = { .num_items = 1, .items = { { "Line", 0x1 }, @@ -11355,44 +11601,9 @@ static struct hda_input_mux alc262_hp_rp5700_capture_source = { }; /* bind hp and internal speaker mute (with plug check) as master switch */ -static void alc262_hippo_master_update(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; - hda_nid_t line_nid = spec->autocfg.line_out_pins[0]; - hda_nid_t speaker_nid = spec->autocfg.speaker_pins[0]; - unsigned int mute; - - /* HP */ - mute = spec->master_sw ? 0 : HDA_AMP_MUTE; - snd_hda_codec_amp_stereo(codec, hp_nid, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); - /* mute internal speaker per jack sense */ - if (spec->jack_present) - mute = HDA_AMP_MUTE; - if (line_nid) - snd_hda_codec_amp_stereo(codec, line_nid, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); - if (speaker_nid && speaker_nid != line_nid) - snd_hda_codec_amp_stereo(codec, speaker_nid, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); -} - +#define alc262_hippo_master_update alc262_hp_master_update #define alc262_hippo_master_sw_get alc262_hp_master_sw_get - -static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - struct alc_spec *spec = codec->spec; - int val = !!*ucontrol->value.integer.value; - - if (val == spec->master_sw) - return 0; - spec->master_sw = val; - alc262_hippo_master_update(codec); - return 1; -} +#define alc262_hippo_master_sw_put alc262_hp_master_sw_put #define ALC262_HIPPO_MASTER_SWITCH \ { \ @@ -11409,7 +11620,7 @@ static int alc262_hippo_master_sw_put(struct snd_kcontrol *kcontrol, (SUBDEV_SPEAKER(0) << 16), \ } -static struct snd_kcontrol_new alc262_hippo_mixer[] = { +static const struct snd_kcontrol_new alc262_hippo_mixer[] = { ALC262_HIPPO_MASTER_SWITCH, HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -11426,7 +11637,7 @@ static struct snd_kcontrol_new alc262_hippo_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc262_hippo1_mixer[] = { +static const struct snd_kcontrol_new alc262_hippo1_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), @@ -11443,28 +11654,14 @@ static struct snd_kcontrol_new alc262_hippo1_mixer[] = { }; /* mute/unmute internal speaker according to the hp jack and mute state */ -static void alc262_hippo_automute(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - hda_nid_t hp_nid = spec->autocfg.hp_pins[0]; - - spec->jack_present = snd_hda_jack_detect(codec, hp_nid); - alc262_hippo_master_update(codec); -} - -static void alc262_hippo_unsol_event(struct hda_codec *codec, unsigned int res) -{ - if ((res >> 26) != ALC880_HP_EVENT) - return; - alc262_hippo_automute(codec); -} - static void alc262_hippo_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc262_hippo1_setup(struct hda_codec *codec) @@ -11473,10 +11670,12 @@ static void alc262_hippo1_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x1b; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static struct snd_kcontrol_new alc262_sony_mixer[] = { +static const struct snd_kcontrol_new alc262_sony_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -11486,7 +11685,7 @@ static struct snd_kcontrol_new alc262_sony_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { +static const struct snd_kcontrol_new alc262_benq_t31_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -11497,7 +11696,7 @@ static struct snd_kcontrol_new alc262_benq_t31_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc262_tyan_mixer[] = { +static const struct snd_kcontrol_new alc262_tyan_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Aux Playback Volume", 0x0b, 0x06, HDA_INPUT), @@ -11513,7 +11712,7 @@ static struct snd_kcontrol_new alc262_tyan_mixer[] = { { } /* end */ }; -static struct hda_verb alc262_tyan_verbs[] = { +static const struct hda_verb alc262_tyan_verbs[] = { /* Headphone automute */ {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -11535,6 +11734,8 @@ static void alc262_tyan_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x1b; spec->autocfg.speaker_pins[0] = 0x15; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } @@ -11544,7 +11745,7 @@ static void alc262_tyan_setup(struct hda_codec *codec) /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc262_init_verbs[] = { +static const struct hda_verb alc262_init_verbs[] = { /* * Unmute ADC0-2 and set the default input to mic-in */ @@ -11620,13 +11821,13 @@ static struct hda_verb alc262_init_verbs[] = { { } }; -static struct hda_verb alc262_eapd_verbs[] = { +static const struct hda_verb alc262_eapd_verbs[] = { {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, { } }; -static struct hda_verb alc262_hippo1_unsol_verbs[] = { +static const struct hda_verb alc262_hippo1_unsol_verbs[] = { {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, {0x1b, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0x0000}, @@ -11636,7 +11837,7 @@ static struct hda_verb alc262_hippo1_unsol_verbs[] = { {} }; -static struct hda_verb alc262_sony_unsol_verbs[] = { +static const struct hda_verb alc262_sony_unsol_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0}, {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, // Front Mic @@ -11646,7 +11847,7 @@ static struct hda_verb alc262_sony_unsol_verbs[] = { {} }; -static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { +static const struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -11655,7 +11856,7 @@ static struct snd_kcontrol_new alc262_toshiba_s06_mixer[] = { { } /* end */ }; -static struct hda_verb alc262_toshiba_s06_verbs[] = { +static const struct hda_verb alc262_toshiba_s06_verbs[] = { {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -11678,6 +11879,8 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec) spec->int_mic.pin = 0x12; spec->int_mic.mux_idx = 9; spec->auto_mic = 1; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; } /* @@ -11687,7 +11890,7 @@ static void alc262_toshiba_s06_setup(struct hda_codec *codec) * 0x18 = external mic */ -static struct snd_kcontrol_new alc262_nec_mixer[] = { +static const struct snd_kcontrol_new alc262_nec_mixer[] = { HDA_CODEC_VOLUME_MONO("Speaker Playback Volume", 0x0e, 1, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE_MONO("Speaker Playback Switch", 0x16, 0, 0x0, HDA_OUTPUT), @@ -11700,7 +11903,7 @@ static struct snd_kcontrol_new alc262_nec_mixer[] = { { } /* end */ }; -static struct hda_verb alc262_nec_verbs[] = { +static const struct hda_verb alc262_nec_verbs[] = { /* Unmute Speaker */ {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -11723,7 +11926,7 @@ static struct hda_verb alc262_nec_verbs[] = { #define ALC_HP_EVENT 0x37 -static struct hda_verb alc262_fujitsu_unsol_verbs[] = { +static const struct hda_verb alc262_fujitsu_unsol_verbs[] = { {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, @@ -11731,20 +11934,20 @@ static struct hda_verb alc262_fujitsu_unsol_verbs[] = { {} }; -static struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { +static const struct hda_verb alc262_lenovo_3000_unsol_verbs[] = { {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC_HP_EVENT}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {} }; -static struct hda_verb alc262_lenovo_3000_init_verbs[] = { +static const struct hda_verb alc262_lenovo_3000_init_verbs[] = { /* Front Mic pin: input vref at 50% */ {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF50}, {0x19, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, {} }; -static struct hda_input_mux alc262_fujitsu_capture_source = { +static const struct hda_input_mux alc262_fujitsu_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, @@ -11753,7 +11956,7 @@ static struct hda_input_mux alc262_fujitsu_capture_source = { }, }; -static struct hda_input_mux alc262_HP_capture_source = { +static const struct hda_input_mux alc262_HP_capture_source = { .num_items = 5, .items = { { "Mic", 0x0 }, @@ -11764,7 +11967,7 @@ static struct hda_input_mux alc262_HP_capture_source = { }, }; -static struct hda_input_mux alc262_HP_D7000_capture_source = { +static const struct hda_input_mux alc262_HP_D7000_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -11774,44 +11977,19 @@ static struct hda_input_mux alc262_HP_D7000_capture_source = { }, }; -/* mute/unmute internal speaker according to the hp jacks and mute state */ -static void alc262_fujitsu_automute(struct hda_codec *codec, int force) +static void alc262_fujitsu_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int mute; - if (force || !spec->sense_updated) { - spec->jack_present = snd_hda_jack_detect(codec, 0x14) || - snd_hda_jack_detect(codec, 0x1b); - spec->sense_updated = 1; - } - /* unmute internal speaker only if both HPs are unplugged and - * master switch is on - */ - if (spec->jack_present) - mute = HDA_AMP_MUTE; - else - mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); -} - -/* unsolicited event for HP jack sensing */ -static void alc262_fujitsu_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) != ALC_HP_EVENT) - return; - alc262_fujitsu_automute(codec, 1); -} - -static void alc262_fujitsu_init_hook(struct hda_codec *codec) -{ - alc262_fujitsu_automute(codec, 1); + spec->autocfg.hp_pins[0] = 0x14; + spec->autocfg.hp_pins[1] = 0x1b; + spec->autocfg.speaker_pins[0] = 0x15; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } /* bind volumes of both NID 0x0c and 0x0d */ -static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { +static const struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x0c, 3, 0, HDA_OUTPUT), @@ -11820,78 +11998,15 @@ static struct hda_bind_ctls alc262_fujitsu_bind_master_vol = { }, }; -/* mute/unmute internal speaker according to the hp jack and mute state */ -static void alc262_lenovo_3000_automute(struct hda_codec *codec, int force) -{ - struct alc_spec *spec = codec->spec; - unsigned int mute; - - if (force || !spec->sense_updated) { - spec->jack_present = snd_hda_jack_detect(codec, 0x1b); - spec->sense_updated = 1; - } - if (spec->jack_present) { - /* mute internal speaker */ - snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, - HDA_AMP_MUTE, HDA_AMP_MUTE); - snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, - HDA_AMP_MUTE, HDA_AMP_MUTE); - } else { - /* unmute internal speaker if necessary */ - mute = snd_hda_codec_amp_read(codec, 0x1b, 0, HDA_OUTPUT, 0); - snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); - snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); - } -} - -/* unsolicited event for HP jack sensing */ -static void alc262_lenovo_3000_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) != ALC_HP_EVENT) - return; - alc262_lenovo_3000_automute(codec, 1); -} - -static int amp_stereo_mute_update(struct hda_codec *codec, hda_nid_t nid, - int dir, int idx, long *valp) -{ - int i, change = 0; - - for (i = 0; i < 2; i++, valp++) - change |= snd_hda_codec_amp_update(codec, nid, i, dir, idx, - HDA_AMP_MUTE, - *valp ? 0 : HDA_AMP_MUTE); - return change; -} - -/* bind hp and internal speaker mute (with plug check) */ -static int alc262_fujitsu_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); - change |= amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); - if (change) - alc262_fujitsu_automute(codec, 0); - return change; -} - -static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { +static const struct snd_kcontrol_new alc262_fujitsu_mixer[] = { HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_AMP_FLAG, - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, - .put = alc262_fujitsu_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), + .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, + .info = snd_ctl_boolean_mono_info, + .get = alc262_hp_master_sw_get, + .put = alc262_hp_master_sw_put, }, { .iface = NID_MAPPING, @@ -11909,30 +12024,26 @@ static struct snd_kcontrol_new alc262_fujitsu_mixer[] = { { } /* end */ }; -/* bind hp and internal speaker mute (with plug check) */ -static int alc262_lenovo_3000_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) +static void alc262_lenovo_3000_setup(struct hda_codec *codec) { - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; + struct alc_spec *spec = codec->spec; - change = amp_stereo_mute_update(codec, 0x1b, HDA_OUTPUT, 0, valp); - if (change) - alc262_lenovo_3000_automute(codec, 0); - return change; + spec->autocfg.hp_pins[0] = 0x1b; + spec->autocfg.speaker_pins[0] = 0x14; + spec->autocfg.speaker_pins[1] = 0x16; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } -static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { +static const struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_AMP_FLAG, - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, - .put = alc262_lenovo_3000_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), + .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, + .info = snd_ctl_boolean_mono_info, + .get = alc262_hp_master_sw_get, + .put = alc262_hp_master_sw_put, }, HDA_CODEC_VOLUME("CD Playback Volume", 0x0b, 0x04, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x0b, 0x04, HDA_INPUT), @@ -11945,7 +12056,7 @@ static struct snd_kcontrol_new alc262_lenovo_3000_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { +static const struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { HDA_BIND_VOL("Master Playback Volume", &alc262_fujitsu_bind_master_vol), ALC262_HIPPO_MASTER_SWITCH, HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -11958,13 +12069,13 @@ static struct snd_kcontrol_new alc262_toshiba_rx1_mixer[] = { }; /* additional init verbs for Benq laptops */ -static struct hda_verb alc262_EAPD_verbs[] = { +static const struct hda_verb alc262_EAPD_verbs[] = { {0x20, AC_VERB_SET_COEF_INDEX, 0x07}, {0x20, AC_VERB_SET_PROC_COEF, 0x3070}, {} }; -static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { +static const struct hda_verb alc262_benq_t31_EAPD_verbs[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x19, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24}, @@ -11974,7 +12085,7 @@ static struct hda_verb alc262_benq_t31_EAPD_verbs[] = { }; /* Samsung Q1 Ultra Vista model setup */ -static struct snd_kcontrol_new alc262_ultra_mixer[] = { +static const struct snd_kcontrol_new alc262_ultra_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x0c, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Master Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x01, HDA_INPUT), @@ -11984,7 +12095,7 @@ static struct snd_kcontrol_new alc262_ultra_mixer[] = { { } /* end */ }; -static struct hda_verb alc262_ultra_verbs[] = { +static const struct hda_verb alc262_ultra_verbs[] = { /* output mixer */ {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, @@ -12047,7 +12158,7 @@ static void alc262_ultra_unsol_event(struct hda_codec *codec, alc262_ultra_automute(codec); } -static struct hda_input_mux alc262_ultra_capture_source = { +static const struct hda_input_mux alc262_ultra_capture_source = { .num_items = 2, .items = { { "Mic", 0x1 }, @@ -12073,7 +12184,7 @@ static int alc262_ultra_mux_enum_put(struct snd_kcontrol *kcontrol, return ret; } -static struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { +static const struct snd_kcontrol_new alc262_ultra_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x07, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x07, 0x0, HDA_INPUT), { @@ -12148,9 +12259,9 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, spec->multiout.num_dacs = 1; /* only use one dac */ spec->multiout.dac_nids = spec->private_dac_nids; - spec->multiout.dac_nids[0] = 2; + spec->private_dac_nids[0] = 2; - pfx = alc_get_line_out_pfx(cfg, true); + pfx = alc_get_line_out_pfx(spec, true); if (!pfx) pfx = "Front"; for (i = 0; i < 2; i++) { @@ -12204,7 +12315,7 @@ static int alc262_auto_create_multi_out_ctls(struct alc_spec *spec, /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc262_volume_init_verbs[] = { +static const struct hda_verb alc262_volume_init_verbs[] = { /* * Unmute ADC0-2 and set the default input to mic-in */ @@ -12265,7 +12376,7 @@ static struct hda_verb alc262_volume_init_verbs[] = { { } }; -static struct hda_verb alc262_HP_BPC_init_verbs[] = { +static const struct hda_verb alc262_HP_BPC_init_verbs[] = { /* * Unmute ADC0-2 and set the default input to mic-in */ @@ -12369,7 +12480,7 @@ static struct hda_verb alc262_HP_BPC_init_verbs[] = { { } }; -static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { +static const struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { /* * Unmute ADC0-2 and set the default input to mic-in */ @@ -12465,7 +12576,7 @@ static struct hda_verb alc262_HP_BPC_WildWest_init_verbs[] = { { } }; -static struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { +static const struct hda_verb alc262_toshiba_rx1_unsol_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, /* Front Speaker */ {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, @@ -12501,7 +12612,7 @@ static const struct alc_fixup alc262_fixups[] = { }, }; -static struct snd_pci_quirk alc262_fixup_tbl[] = { +static const struct snd_pci_quirk alc262_fixup_tbl[] = { SND_PCI_QUIRK(0x1734, 0x1147, "FSC Celsius H270", PINFIX_FSC_H270), {} }; @@ -12524,7 +12635,7 @@ static int alc262_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; - static hda_nid_t alc262_ignore[] = { 0x1d, 0 }; + static const hda_nid_t alc262_ignore[] = { 0x1d, 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc262_ignore); @@ -12609,7 +12720,7 @@ static const char * const alc262_models[ALC262_MODEL_LAST] = { [ALC262_AUTO] = "auto", }; -static struct snd_pci_quirk alc262_cfg_tbl[] = { +static const struct snd_pci_quirk alc262_cfg_tbl[] = { SND_PCI_QUIRK(0x1002, 0x437b, "Hippo", ALC262_HIPPO), SND_PCI_QUIRK(0x1033, 0x8895, "NEC Versa S9100", ALC262_NEC), SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x1200, "HP xw series", @@ -12661,7 +12772,7 @@ static struct snd_pci_quirk alc262_cfg_tbl[] = { {} }; -static struct alc_config_preset alc262_presets[] = { +static const struct alc_config_preset alc262_presets[] = { [ALC262_BASIC] = { .mixers = { alc262_base_mixer }, .init_verbs = { alc262_init_verbs }, @@ -12682,9 +12793,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, - .unsol_event = alc262_hippo_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc262_hippo_setup, - .init_hook = alc262_hippo_automute, + .init_hook = alc_inithook, }, [ALC262_HIPPO_1] = { .mixers = { alc262_hippo1_mixer }, @@ -12696,9 +12807,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, - .unsol_event = alc262_hippo_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc262_hippo1_setup, - .init_hook = alc262_hippo_automute, + .init_hook = alc_inithook, }, [ALC262_FUJITSU] = { .mixers = { alc262_fujitsu_mixer }, @@ -12711,8 +12822,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_fujitsu_capture_source, - .unsol_event = alc262_fujitsu_unsol_event, - .init_hook = alc262_fujitsu_init_hook, + .unsol_event = alc_sku_unsol_event, + .setup = alc262_fujitsu_setup, + .init_hook = alc_inithook, }, [ALC262_HP_BPC] = { .mixers = { alc262_HP_BPC_mixer }, @@ -12723,8 +12835,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_capture_source, - .unsol_event = alc262_hp_bpc_unsol_event, - .init_hook = alc262_hp_bpc_automute, + .unsol_event = alc_sku_unsol_event, + .setup = alc262_hp_bpc_setup, + .init_hook = alc_inithook, }, [ALC262_HP_BPC_D7000_WF] = { .mixers = { alc262_HP_BPC_WildWest_mixer }, @@ -12735,8 +12848,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_D7000_capture_source, - .unsol_event = alc262_hp_wildwest_unsol_event, - .init_hook = alc262_hp_wildwest_automute, + .unsol_event = alc_sku_unsol_event, + .setup = alc262_hp_wildwest_setup, + .init_hook = alc_inithook, }, [ALC262_HP_BPC_D7000_WL] = { .mixers = { alc262_HP_BPC_WildWest_mixer, @@ -12748,8 +12862,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_HP_D7000_capture_source, - .unsol_event = alc262_hp_wildwest_unsol_event, - .init_hook = alc262_hp_wildwest_automute, + .unsol_event = alc_sku_unsol_event, + .setup = alc262_hp_wildwest_setup, + .init_hook = alc_inithook, }, [ALC262_HP_TC_T5735] = { .mixers = { alc262_hp_t5735_mixer }, @@ -12792,9 +12907,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, - .unsol_event = alc262_hippo_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc262_hippo_setup, - .init_hook = alc262_hippo_automute, + .init_hook = alc_inithook, }, [ALC262_BENQ_T31] = { .mixers = { alc262_benq_t31_mixer }, @@ -12806,9 +12921,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, - .unsol_event = alc262_hippo_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc262_hippo_setup, - .init_hook = alc262_hippo_automute, + .init_hook = alc_inithook, }, [ALC262_ULTRA] = { .mixers = { alc262_ultra_mixer }, @@ -12837,7 +12952,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_fujitsu_capture_source, - .unsol_event = alc262_lenovo_3000_unsol_event, + .unsol_event = alc_sku_unsol_event, + .setup = alc262_lenovo_3000_setup, + .init_hook = alc_inithook, }, [ALC262_NEC] = { .mixers = { alc262_nec_mixer }, @@ -12874,9 +12991,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, - .unsol_event = alc262_hippo_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc262_hippo_setup, - .init_hook = alc262_hippo_automute, + .init_hook = alc_inithook, }, [ALC262_TYAN] = { .mixers = { alc262_tyan_mixer }, @@ -12888,9 +13005,9 @@ static struct alc_config_preset alc262_presets[] = { .num_channel_mode = ARRAY_SIZE(alc262_modes), .channel_mode = alc262_modes, .input_mux = &alc262_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc262_tyan_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, }; @@ -13011,6 +13128,7 @@ static int patch_alc262(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC262_AUTO) spec->init_hook = alc262_auto_init; + spec->shutup = alc_eapd_shutup; alc_init_jacks(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE @@ -13027,24 +13145,24 @@ static int patch_alc262(struct hda_codec *codec) #define ALC268_DIGOUT_NID ALC880_DIGOUT_NID #define alc268_modes alc260_modes -static hda_nid_t alc268_dac_nids[2] = { +static const hda_nid_t alc268_dac_nids[2] = { /* front, hp */ 0x02, 0x03 }; -static hda_nid_t alc268_adc_nids[2] = { +static const hda_nid_t alc268_adc_nids[2] = { /* ADC0-1 */ 0x08, 0x07 }; -static hda_nid_t alc268_adc_nids_alt[1] = { +static const hda_nid_t alc268_adc_nids_alt[1] = { /* ADC0 */ 0x08 }; -static hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; +static const hda_nid_t alc268_capsrc_nids[2] = { 0x23, 0x24 }; -static struct snd_kcontrol_new alc268_base_mixer[] = { +static const struct snd_kcontrol_new alc268_base_mixer[] = { /* output mixer control */ HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -13056,7 +13174,7 @@ static struct snd_kcontrol_new alc268_base_mixer[] = { { } }; -static struct snd_kcontrol_new alc268_toshiba_mixer[] = { +static const struct snd_kcontrol_new alc268_toshiba_mixer[] = { /* output mixer control */ HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), @@ -13068,7 +13186,7 @@ static struct snd_kcontrol_new alc268_toshiba_mixer[] = { }; /* bind Beep switches of both NID 0x0f and 0x10 */ -static struct hda_bind_ctls alc268_bind_beep_sw = { +static const struct hda_bind_ctls alc268_bind_beep_sw = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x0f, 3, 1, HDA_INPUT), @@ -13077,27 +13195,27 @@ static struct hda_bind_ctls alc268_bind_beep_sw = { }, }; -static struct snd_kcontrol_new alc268_beep_mixer[] = { +static const struct snd_kcontrol_new alc268_beep_mixer[] = { HDA_CODEC_VOLUME("Beep Playback Volume", 0x1d, 0x0, HDA_INPUT), HDA_BIND_SW("Beep Playback Switch", &alc268_bind_beep_sw), { } }; -static struct hda_verb alc268_eapd_verbs[] = { +static const struct hda_verb alc268_eapd_verbs[] = { {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, { } }; /* Toshiba specific */ -static struct hda_verb alc268_toshiba_verbs[] = { +static const struct hda_verb alc268_toshiba_verbs[] = { {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, { } /* end */ }; /* Acer specific */ /* bind volumes of both NID 0x02 and 0x03 */ -static struct hda_bind_ctls alc268_acer_bind_master_vol = { +static const struct hda_bind_ctls alc268_acer_bind_master_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), @@ -13106,66 +13224,44 @@ static struct hda_bind_ctls alc268_acer_bind_master_vol = { }, }; -/* mute/unmute internal speaker according to the hp jack and mute state */ -static void alc268_acer_automute(struct hda_codec *codec, int force) +static void alc268_acer_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; - unsigned int mute; - if (force || !spec->sense_updated) { - spec->jack_present = snd_hda_jack_detect(codec, 0x14); - spec->sense_updated = 1; - } - if (spec->jack_present) - mute = HDA_AMP_MUTE; /* mute internal speaker */ - else /* unmute internal speaker if necessary */ - mute = snd_hda_codec_amp_read(codec, 0x14, 0, HDA_OUTPUT, 0); - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, mute); + spec->autocfg.hp_pins[0] = 0x14; + spec->autocfg.speaker_pins[0] = 0x15; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } +#define alc268_acer_master_sw_get alc262_hp_master_sw_get +#define alc268_acer_master_sw_put alc262_hp_master_sw_put -/* bind hp and internal speaker mute (with plug check) */ -static int alc268_acer_master_sw_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - long *valp = ucontrol->value.integer.value; - int change; - - change = amp_stereo_mute_update(codec, 0x14, HDA_OUTPUT, 0, valp); - if (change) - alc268_acer_automute(codec, 0); - return change; -} - -static struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { +static const struct snd_kcontrol_new alc268_acer_aspire_one_mixer[] = { /* output mixer control */ HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_AMP_FLAG, - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, + .subdevice = HDA_SUBDEV_NID_FLAG | 0x15, + .info = snd_ctl_boolean_mono_info, + .get = alc268_acer_master_sw_get, .put = alc268_acer_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), }, HDA_CODEC_VOLUME("Mic Boost Capture Volume", 0x18, 0, HDA_INPUT), { } }; -static struct snd_kcontrol_new alc268_acer_mixer[] = { +static const struct snd_kcontrol_new alc268_acer_mixer[] = { /* output mixer control */ HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_AMP_FLAG, - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, + .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, + .info = snd_ctl_boolean_mono_info, + .get = alc268_acer_master_sw_get, .put = alc268_acer_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), }, HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x19, 0, HDA_INPUT), @@ -13173,24 +13269,23 @@ static struct snd_kcontrol_new alc268_acer_mixer[] = { { } }; -static struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { +static const struct snd_kcontrol_new alc268_acer_dmic_mixer[] = { /* output mixer control */ HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Master Playback Switch", - .subdevice = HDA_SUBDEV_AMP_FLAG, - .info = snd_hda_mixer_amp_switch_info, - .get = snd_hda_mixer_amp_switch_get, + .subdevice = HDA_SUBDEV_NID_FLAG | 0x14, + .info = snd_ctl_boolean_mono_info, + .get = alc268_acer_master_sw_get, .put = alc268_acer_master_sw_put, - .private_value = HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), }, HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), HDA_CODEC_VOLUME("Line In Boost Volume", 0x1a, 0, HDA_INPUT), { } }; -static struct hda_verb alc268_acer_aspire_one_verbs[] = { +static const struct hda_verb alc268_acer_aspire_one_verbs[] = { {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, @@ -13200,7 +13295,7 @@ static struct hda_verb alc268_acer_aspire_one_verbs[] = { { } }; -static struct hda_verb alc268_acer_verbs[] = { +static const struct hda_verb alc268_acer_verbs[] = { {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, /* internal dmic? */ {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -13212,53 +13307,16 @@ static struct hda_verb alc268_acer_verbs[] = { }; /* unsolicited event for HP jack sensing */ -#define alc268_toshiba_unsol_event alc262_hippo_unsol_event #define alc268_toshiba_setup alc262_hippo_setup -#define alc268_toshiba_automute alc262_hippo_automute - -static void alc268_acer_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) != ALC880_HP_EVENT) - return; - alc268_acer_automute(codec, 1); -} - -static void alc268_acer_init_hook(struct hda_codec *codec) -{ - alc268_acer_automute(codec, 1); -} - -/* toggle speaker-output according to the hp-jack state */ -static void alc268_aspire_one_speaker_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x15); - bits = present ? HDA_AMP_MUTE : 0; - snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0f, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); -} - -static void alc268_acer_lc_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - switch (res >> 26) { - case ALC880_HP_EVENT: - alc268_aspire_one_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } -} static void alc268_acer_lc_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x15; + spec->autocfg.speaker_pins[0] = 0x14; + spec->automute_mixer_nid[0] = 0x0f; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x12; @@ -13266,13 +13324,7 @@ static void alc268_acer_lc_setup(struct hda_codec *codec) spec->auto_mic = 1; } -static void alc268_acer_lc_init_hook(struct hda_codec *codec) -{ - alc268_aspire_one_speaker_automute(codec); - alc_mic_automute(codec); -} - -static struct snd_kcontrol_new alc268_dell_mixer[] = { +static const struct snd_kcontrol_new alc268_dell_mixer[] = { /* output mixer control */ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -13283,7 +13335,7 @@ static struct snd_kcontrol_new alc268_dell_mixer[] = { { } }; -static struct hda_verb alc268_dell_verbs[] = { +static const struct hda_verb alc268_dell_verbs[] = { {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, @@ -13303,9 +13355,11 @@ static void alc268_dell_setup(struct hda_codec *codec) spec->int_mic.pin = 0x19; spec->int_mic.mux_idx = 1; spec->auto_mic = 1; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; } -static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { +static const struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x2, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x3, 0x0, HDA_OUTPUT), @@ -13317,7 +13371,7 @@ static struct snd_kcontrol_new alc267_quanta_il1_mixer[] = { { } }; -static struct hda_verb alc267_quanta_il1_verbs[] = { +static const struct hda_verb alc267_quanta_il1_verbs[] = { {0x15, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_HP_EVENT | AC_USRSP_EN}, {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, ALC880_MIC_EVENT | AC_USRSP_EN}, { } @@ -13333,12 +13387,14 @@ static void alc267_quanta_il1_setup(struct hda_codec *codec) spec->int_mic.pin = 0x19; spec->int_mic.mux_idx = 1; spec->auto_mic = 1; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; } /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc268_base_init_verbs[] = { +static const struct hda_verb alc268_base_init_verbs[] = { /* Unmute DAC0-1 and set vol = 0 */ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, @@ -13386,7 +13442,7 @@ static struct hda_verb alc268_base_init_verbs[] = { /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc268_volume_init_verbs[] = { +static const struct hda_verb alc268_volume_init_verbs[] = { /* set output DAC */ {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, @@ -13412,20 +13468,20 @@ static struct hda_verb alc268_volume_init_verbs[] = { { } }; -static struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { +static const struct snd_kcontrol_new alc268_capture_nosrc_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), { } /* end */ }; -static struct snd_kcontrol_new alc268_capture_alt_mixer[] = { +static const struct snd_kcontrol_new alc268_capture_alt_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), _DEFINE_CAPSRC(1), { } /* end */ }; -static struct snd_kcontrol_new alc268_capture_mixer[] = { +static const struct snd_kcontrol_new alc268_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x23, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Capture Switch", 0x23, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x24, 0x0, HDA_OUTPUT), @@ -13434,7 +13490,7 @@ static struct snd_kcontrol_new alc268_capture_mixer[] = { { } /* end */ }; -static struct hda_input_mux alc268_capture_source = { +static const struct hda_input_mux alc268_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -13444,7 +13500,7 @@ static struct hda_input_mux alc268_capture_source = { }, }; -static struct hda_input_mux alc268_acer_capture_source = { +static const struct hda_input_mux alc268_acer_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, @@ -13453,7 +13509,7 @@ static struct hda_input_mux alc268_acer_capture_source = { }, }; -static struct hda_input_mux alc268_acer_dmic_capture_source = { +static const struct hda_input_mux alc268_acer_dmic_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, @@ -13463,7 +13519,7 @@ static struct hda_input_mux alc268_acer_dmic_capture_source = { }; #ifdef CONFIG_SND_DEBUG -static struct snd_kcontrol_new alc268_test_mixer[] = { +static const struct snd_kcontrol_new alc268_test_mixer[] = { /* Volume widgets */ HDA_CODEC_VOLUME("LOUT1 Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("LOUT2 Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -13542,7 +13598,7 @@ static int alc268_new_analog_output(struct alc_spec *spec, hda_nid_t nid, HDA_OUTPUT)); if (err < 0) return err; - spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; + spec->private_dac_nids[spec->multiout.num_dacs++] = dac; } if (nid != 0x16) @@ -13715,7 +13771,7 @@ static int alc268_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; - static hda_nid_t alc268_ignore[] = { 0 }; + static const hda_nid_t alc268_ignore[] = { 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc268_ignore); @@ -13795,7 +13851,7 @@ static const char * const alc268_models[ALC268_MODEL_LAST] = { [ALC268_AUTO] = "auto", }; -static struct snd_pci_quirk alc268_cfg_tbl[] = { +static const struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x011e, "Acer Aspire 5720z", ALC268_ACER), SND_PCI_QUIRK(0x1025, 0x0126, "Acer", ALC268_ACER), SND_PCI_QUIRK(0x1025, 0x012e, "Acer Aspire 5310", ALC268_ACER), @@ -13820,7 +13876,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { }; /* Toshiba laptops have no unique PCI SSID but only codec SSID */ -static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { +static const struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { SND_PCI_QUIRK(0x1179, 0xff0a, "TOSHIBA X-200", ALC268_AUTO), SND_PCI_QUIRK(0x1179, 0xff0e, "TOSHIBA X-200 HDMI", ALC268_AUTO), SND_PCI_QUIRK_MASK(0x1179, 0xff00, 0xff00, "TOSHIBA A/Lx05", @@ -13828,7 +13884,7 @@ static struct snd_pci_quirk alc268_ssid_cfg_tbl[] = { {} }; -static struct alc_config_preset alc268_presets[] = { +static const struct alc_config_preset alc268_presets[] = { [ALC267_QUANTA_IL1] = { .mixers = { alc267_quanta_il1_mixer, alc268_beep_mixer, alc268_capture_nosrc_mixer }, @@ -13874,9 +13930,9 @@ static struct alc_config_preset alc268_presets[] = { .num_channel_mode = ARRAY_SIZE(alc268_modes), .channel_mode = alc268_modes, .input_mux = &alc268_capture_source, - .unsol_event = alc268_toshiba_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc268_toshiba_setup, - .init_hook = alc268_toshiba_automute, + .init_hook = alc_inithook, }, [ALC268_ACER] = { .mixers = { alc268_acer_mixer, alc268_capture_alt_mixer, @@ -13892,8 +13948,9 @@ static struct alc_config_preset alc268_presets[] = { .num_channel_mode = ARRAY_SIZE(alc268_modes), .channel_mode = alc268_modes, .input_mux = &alc268_acer_capture_source, - .unsol_event = alc268_acer_unsol_event, - .init_hook = alc268_acer_init_hook, + .unsol_event = alc_sku_unsol_event, + .setup = alc268_acer_setup, + .init_hook = alc_inithook, }, [ALC268_ACER_DMIC] = { .mixers = { alc268_acer_dmic_mixer, alc268_capture_alt_mixer, @@ -13909,8 +13966,9 @@ static struct alc_config_preset alc268_presets[] = { .num_channel_mode = ARRAY_SIZE(alc268_modes), .channel_mode = alc268_modes, .input_mux = &alc268_acer_dmic_capture_source, - .unsol_event = alc268_acer_unsol_event, - .init_hook = alc268_acer_init_hook, + .unsol_event = alc_sku_unsol_event, + .setup = alc268_acer_setup, + .init_hook = alc_inithook, }, [ALC268_ACER_ASPIRE_ONE] = { .mixers = { alc268_acer_aspire_one_mixer, @@ -13926,9 +13984,9 @@ static struct alc_config_preset alc268_presets[] = { .hp_nid = 0x03, .num_channel_mode = ARRAY_SIZE(alc268_modes), .channel_mode = alc268_modes, - .unsol_event = alc268_acer_lc_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc268_acer_lc_setup, - .init_hook = alc268_acer_lc_init_hook, + .init_hook = alc_inithook, }, [ALC268_DELL] = { .mixers = { alc268_dell_mixer, alc268_beep_mixer, @@ -13962,8 +14020,9 @@ static struct alc_config_preset alc268_presets[] = { .num_channel_mode = ARRAY_SIZE(alc268_modes), .channel_mode = alc268_modes, .input_mux = &alc268_capture_source, + .unsol_event = alc_sku_unsol_event, .setup = alc268_toshiba_setup, - .init_hook = alc268_toshiba_automute, + .init_hook = alc_inithook, }, #ifdef CONFIG_SND_DEBUG [ALC268_TEST] = { @@ -14085,6 +14144,7 @@ static int patch_alc268(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC268_AUTO) spec->init_hook = alc268_auto_init; + spec->shutup = alc_eapd_shutup; alc_init_jacks(codec); @@ -14098,32 +14158,32 @@ static int patch_alc268(struct hda_codec *codec) #define alc269_dac_nids alc260_dac_nids -static hda_nid_t alc269_adc_nids[1] = { +static const hda_nid_t alc269_adc_nids[1] = { /* ADC1 */ 0x08, }; -static hda_nid_t alc269_capsrc_nids[1] = { +static const hda_nid_t alc269_capsrc_nids[1] = { 0x23, }; -static hda_nid_t alc269vb_adc_nids[1] = { +static const hda_nid_t alc269vb_adc_nids[1] = { /* ADC1 */ 0x09, }; -static hda_nid_t alc269vb_capsrc_nids[1] = { +static const hda_nid_t alc269vb_capsrc_nids[1] = { 0x22, }; -static hda_nid_t alc269_adc_candidates[] = { +static const hda_nid_t alc269_adc_candidates[] = { 0x08, 0x09, 0x07, 0x11, }; #define alc269_modes alc260_modes #define alc269_capture_source alc880_lg_lw_capture_source -static struct snd_kcontrol_new alc269_base_mixer[] = { +static const struct snd_kcontrol_new alc269_base_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Line Playback Volume", 0x0b, 0x02, HDA_INPUT), @@ -14139,7 +14199,7 @@ static struct snd_kcontrol_new alc269_base_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { +static const struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { /* output mixer control */ HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), { @@ -14160,7 +14220,7 @@ static struct snd_kcontrol_new alc269_quanta_fl1_mixer[] = { { } }; -static struct snd_kcontrol_new alc269_lifebook_mixer[] = { +static const struct snd_kcontrol_new alc269_lifebook_mixer[] = { /* output mixer control */ HDA_BIND_VOL("Master Playback Volume", &alc268_acer_bind_master_vol), { @@ -14184,7 +14244,7 @@ static struct snd_kcontrol_new alc269_lifebook_mixer[] = { { } }; -static struct snd_kcontrol_new alc269_laptop_mixer[] = { +static const struct snd_kcontrol_new alc269_laptop_mixer[] = { HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x15, 0x0, HDA_OUTPUT), @@ -14192,7 +14252,7 @@ static struct snd_kcontrol_new alc269_laptop_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { +static const struct snd_kcontrol_new alc269vb_laptop_mixer[] = { HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), @@ -14200,14 +14260,14 @@ static struct snd_kcontrol_new alc269vb_laptop_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc269_asus_mixer[] = { +static const struct snd_kcontrol_new alc269_asus_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0x0c, 0x0, HDA_INPUT), { } /* end */ }; /* capture mixer elements */ -static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { +static const struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), @@ -14215,14 +14275,14 @@ static struct snd_kcontrol_new alc269_laptop_analog_capture_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { +static const struct snd_kcontrol_new alc269_laptop_digital_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), { } /* end */ }; -static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { +static const struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), @@ -14230,7 +14290,7 @@ static struct snd_kcontrol_new alc269vb_laptop_analog_capture_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { +static const struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0, HDA_INPUT), @@ -14240,7 +14300,7 @@ static struct snd_kcontrol_new alc269vb_laptop_digital_capture_mixer[] = { /* FSC amilo */ #define alc269_fujitsu_mixer alc269_laptop_mixer -static struct hda_verb alc269_quanta_fl1_verbs[] = { +static const struct hda_verb alc269_quanta_fl1_verbs[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -14250,7 +14310,7 @@ static struct hda_verb alc269_quanta_fl1_verbs[] = { { } }; -static struct hda_verb alc269_lifebook_verbs[] = { +static const struct hda_verb alc269_lifebook_verbs[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x1a, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, @@ -14267,15 +14327,7 @@ static struct hda_verb alc269_lifebook_verbs[] = { /* toggle speaker-output according to the hp-jack state */ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) { - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x15); - bits = present ? HDA_AMP_MUTE : 0; - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); + alc_hp_automute(codec); snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_COEF_INDEX, 0x0c); @@ -14288,34 +14340,8 @@ static void alc269_quanta_fl1_speaker_automute(struct hda_codec *codec) AC_VERB_SET_PROC_COEF, 0x480); } -/* toggle speaker-output according to the hp-jacks state */ -static void alc269_lifebook_speaker_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - /* Check laptop headphone socket */ - present = snd_hda_jack_detect(codec, 0x15); - - /* Check port replicator headphone socket */ - present |= snd_hda_jack_detect(codec, 0x1a); - - bits = present ? HDA_AMP_MUTE : 0; - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); - - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_COEF_INDEX, 0x0c); - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_PROC_COEF, 0x680); - - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_COEF_INDEX, 0x0c); - snd_hda_codec_write(codec, 0x20, 0, - AC_VERB_SET_PROC_COEF, 0x480); -} +#define alc269_lifebook_speaker_automute \ + alc269_quanta_fl1_speaker_automute static void alc269_lifebook_mic_autoswitch(struct hda_codec *codec) { @@ -14364,6 +14390,9 @@ static void alc269_quanta_fl1_setup(struct hda_codec *codec) struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x19; @@ -14377,13 +14406,24 @@ static void alc269_quanta_fl1_init_hook(struct hda_codec *codec) alc_mic_automute(codec); } +static void alc269_lifebook_setup(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x15; + spec->autocfg.hp_pins[1] = 0x1a; + spec->autocfg.speaker_pins[0] = 0x14; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; +} + static void alc269_lifebook_init_hook(struct hda_codec *codec) { alc269_lifebook_speaker_automute(codec); alc269_lifebook_mic_autoswitch(codec); } -static struct hda_verb alc269_laptop_dmic_init_verbs[] = { +static const struct hda_verb alc269_laptop_dmic_init_verbs[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x23, AC_VERB_SET_CONNECT_SEL, 0x05}, {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, @@ -14394,7 +14434,7 @@ static struct hda_verb alc269_laptop_dmic_init_verbs[] = { {} }; -static struct hda_verb alc269_laptop_amic_init_verbs[] = { +static const struct hda_verb alc269_laptop_amic_init_verbs[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x23, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, @@ -14404,7 +14444,7 @@ static struct hda_verb alc269_laptop_amic_init_verbs[] = { {} }; -static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { +static const struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x22, AC_VERB_SET_CONNECT_SEL, 0x06}, {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, @@ -14415,7 +14455,7 @@ static struct hda_verb alc269vb_laptop_dmic_init_verbs[] = { {} }; -static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { +static const struct hda_verb alc269vb_laptop_amic_init_verbs[] = { {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x22, AC_VERB_SET_CONNECT_SEL, 0x01}, {0x02, AC_VERB_SET_AMP_GAIN_MUTE, 0xb026 }, @@ -14426,7 +14466,7 @@ static struct hda_verb alc269vb_laptop_amic_init_verbs[] = { {} }; -static struct hda_verb alc271_acer_dmic_verbs[] = { +static const struct hda_verb alc271_acer_dmic_verbs[] = { {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, @@ -14440,42 +14480,14 @@ static struct hda_verb alc271_acer_dmic_verbs[] = { { } }; -/* toggle speaker-output according to the hp-jack state */ -static void alc269_speaker_automute(struct hda_codec *codec) -{ - struct alc_spec *spec = codec->spec; - unsigned int nid = spec->autocfg.hp_pins[0]; - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, nid); - bits = present ? HDA_AMP_MUTE : 0; - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); - snd_hda_input_jack_report(codec, nid); -} - -/* unsolicited event for HP jack sensing */ -static void alc269_laptop_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - switch (res >> 26) { - case ALC880_HP_EVENT: - alc269_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } -} - static void alc269_laptop_amic_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x19; @@ -14488,6 +14500,9 @@ static void alc269_laptop_dmic_setup(struct hda_codec *codec) struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x12; @@ -14500,6 +14515,9 @@ static void alc269vb_laptop_amic_setup(struct hda_codec *codec) struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x21; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x19; @@ -14512,6 +14530,9 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x21; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x12; @@ -14519,16 +14540,10 @@ static void alc269vb_laptop_dmic_setup(struct hda_codec *codec) spec->auto_mic = 1; } -static void alc269_laptop_inithook(struct hda_codec *codec) -{ - alc269_speaker_automute(codec); - alc_mic_automute(codec); -} - /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc269_init_verbs[] = { +static const struct hda_verb alc269_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ @@ -14571,7 +14586,7 @@ static struct hda_verb alc269_init_verbs[] = { { } }; -static struct hda_verb alc269vb_init_verbs[] = { +static const struct hda_verb alc269vb_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ @@ -14629,7 +14644,7 @@ static struct hda_verb alc269vb_init_verbs[] = { #define alc269_pcm_digital_playback alc880_pcm_digital_playback #define alc269_pcm_digital_capture alc880_pcm_digital_capture -static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { +static const struct hda_pcm_stream alc269_44k_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 8, @@ -14642,7 +14657,7 @@ static struct hda_pcm_stream alc269_44k_pcm_analog_playback = { }, }; -static struct hda_pcm_stream alc269_44k_pcm_analog_capture = { +static const struct hda_pcm_stream alc269_44k_pcm_analog_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -14726,7 +14741,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; - static hda_nid_t alc269_ignore[] = { 0x1d, 0 }; + static const hda_nid_t alc269_ignore[] = { 0x1d, 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc269_ignore); @@ -14796,7 +14811,6 @@ static void alc269_auto_init(struct hda_codec *codec) alc_inithook(codec); } -#ifdef SND_HDA_NEEDS_RESUME static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) { int val = alc_read_coef_idx(codec, 0x04); @@ -14807,25 +14821,17 @@ static void alc269_toggle_power_output(struct hda_codec *codec, int power_up) alc_write_coef_idx(codec, 0x04, val); } -#ifdef CONFIG_SND_HDA_POWER_SAVE -static int alc269_suspend(struct hda_codec *codec, pm_message_t state) +static void alc269_shutup(struct hda_codec *codec) { - struct alc_spec *spec = codec->spec; - if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x017) alc269_toggle_power_output(codec, 0); if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { alc269_toggle_power_output(codec, 0); msleep(150); } - - alc_shutup(codec); - if (spec && spec->power_hook) - spec->power_hook(codec); - return 0; } -#endif /* CONFIG_SND_HDA_POWER_SAVE */ +#ifdef SND_HDA_NEEDS_RESUME static int alc269_resume(struct hda_codec *codec) { if ((alc_read_coef_idx(codec, 0) & 0x00ff) == 0x018) { @@ -14864,7 +14870,7 @@ static void alc269_fixup_hweq(struct hda_codec *codec, static void alc271_fixup_dmic(struct hda_codec *codec, const struct alc_fixup *fix, int action) { - static struct hda_verb verbs[] = { + static const struct hda_verb verbs[] = { {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, {} @@ -14947,7 +14953,7 @@ static const struct alc_fixup alc269_fixups[] = { }, }; -static struct snd_pci_quirk alc269_fixup_tbl[] = { +static const struct snd_pci_quirk alc269_fixup_tbl[] = { SND_PCI_QUIRK(0x104d, 0x9073, "Sony VAIO", ALC275_FIXUP_SONY_VAIO_GPIO2), SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), @@ -14978,7 +14984,7 @@ static const char * const alc269_models[ALC269_MODEL_LAST] = { [ALC269_AUTO] = "auto", }; -static struct snd_pci_quirk alc269_cfg_tbl[] = { +static const struct snd_pci_quirk alc269_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_QUANTA_FL1), SND_PCI_QUIRK(0x1025, 0x047c, "ACER ZGA", ALC271_ACER), SND_PCI_QUIRK(0x1043, 0x8330, "ASUS Eeepc P703 P900A", @@ -15036,7 +15042,7 @@ static struct snd_pci_quirk alc269_cfg_tbl[] = { {} }; -static struct alc_config_preset alc269_presets[] = { +static const struct alc_config_preset alc269_presets[] = { [ALC269_BASIC] = { .mixers = { alc269_base_mixer }, .init_verbs = { alc269_init_verbs }, @@ -15070,9 +15076,9 @@ static struct alc_config_preset alc269_presets[] = { .hp_nid = 0x03, .num_channel_mode = ARRAY_SIZE(alc269_modes), .channel_mode = alc269_modes, - .unsol_event = alc269_laptop_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc269_laptop_amic_setup, - .init_hook = alc269_laptop_inithook, + .init_hook = alc_inithook, }, [ALC269_DMIC] = { .mixers = { alc269_laptop_mixer }, @@ -15084,9 +15090,9 @@ static struct alc_config_preset alc269_presets[] = { .hp_nid = 0x03, .num_channel_mode = ARRAY_SIZE(alc269_modes), .channel_mode = alc269_modes, - .unsol_event = alc269_laptop_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc269_laptop_dmic_setup, - .init_hook = alc269_laptop_inithook, + .init_hook = alc_inithook, }, [ALC269VB_AMIC] = { .mixers = { alc269vb_laptop_mixer }, @@ -15098,9 +15104,9 @@ static struct alc_config_preset alc269_presets[] = { .hp_nid = 0x03, .num_channel_mode = ARRAY_SIZE(alc269_modes), .channel_mode = alc269_modes, - .unsol_event = alc269_laptop_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc269vb_laptop_amic_setup, - .init_hook = alc269_laptop_inithook, + .init_hook = alc_inithook, }, [ALC269VB_DMIC] = { .mixers = { alc269vb_laptop_mixer }, @@ -15112,9 +15118,9 @@ static struct alc_config_preset alc269_presets[] = { .hp_nid = 0x03, .num_channel_mode = ARRAY_SIZE(alc269_modes), .channel_mode = alc269_modes, - .unsol_event = alc269_laptop_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc269vb_laptop_dmic_setup, - .init_hook = alc269_laptop_inithook, + .init_hook = alc_inithook, }, [ALC269_FUJITSU] = { .mixers = { alc269_fujitsu_mixer }, @@ -15126,9 +15132,9 @@ static struct alc_config_preset alc269_presets[] = { .hp_nid = 0x03, .num_channel_mode = ARRAY_SIZE(alc269_modes), .channel_mode = alc269_modes, - .unsol_event = alc269_laptop_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc269_laptop_dmic_setup, - .init_hook = alc269_laptop_inithook, + .init_hook = alc_inithook, }, [ALC269_LIFEBOOK] = { .mixers = { alc269_lifebook_mixer }, @@ -15140,6 +15146,7 @@ static struct alc_config_preset alc269_presets[] = { .channel_mode = alc269_modes, .input_mux = &alc269_capture_source, .unsol_event = alc269_lifebook_unsol_event, + .setup = alc269_lifebook_setup, .init_hook = alc269_lifebook_init_hook, }, [ALC271_ACER] = { @@ -15185,14 +15192,21 @@ static int alc269_fill_coef(struct hda_codec *codec) val = alc_read_coef_idx(codec, 0xd); if ((val & 0x0c00) >> 10 != 0x1) { /* Capless ramp up clock control */ - alc_write_coef_idx(codec, 0xd, val | 1<<10); + alc_write_coef_idx(codec, 0xd, val | (1<<10)); } val = alc_read_coef_idx(codec, 0x17); if ((val & 0x01c0) >> 6 != 0x4) { /* Class D power on reset */ - alc_write_coef_idx(codec, 0x17, val | 1<<7); + alc_write_coef_idx(codec, 0x17, val | (1<<7)); } } + + val = alc_read_coef_idx(codec, 0xd); /* Class D */ + alc_write_coef_idx(codec, 0xd, val | (1<<14)); + + val = alc_read_coef_idx(codec, 0x4); /* HP */ + alc_write_coef_idx(codec, 0x4, val | (1<<11)); + return 0; } @@ -15313,14 +15327,12 @@ static int patch_alc269(struct hda_codec *codec) spec->vmaster_nid = 0x02; codec->patch_ops = alc_patch_ops; -#ifdef CONFIG_SND_HDA_POWER_SAVE - codec->patch_ops.suspend = alc269_suspend; -#endif #ifdef SND_HDA_NEEDS_RESUME codec->patch_ops.resume = alc269_resume; #endif if (board_config == ALC269_AUTO) spec->init_hook = alc269_auto_init; + spec->shutup = alc269_shutup; alc_init_jacks(codec); #ifdef CONFIG_SND_HDA_POWER_SAVE @@ -15341,7 +15353,7 @@ static int patch_alc269(struct hda_codec *codec) * set the path ways for 2 channel output * need to set the codec line out and mic 1 pin widgets to inputs */ -static struct hda_verb alc861_threestack_ch2_init[] = { +static const struct hda_verb alc861_threestack_ch2_init[] = { /* set pin widget 1Ah (line in) for input */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, /* set pin widget 18h (mic1/2) for input, for mic also enable @@ -15360,7 +15372,7 @@ static struct hda_verb alc861_threestack_ch2_init[] = { * 6ch mode * need to set the codec line out and mic 1 pin widgets to outputs */ -static struct hda_verb alc861_threestack_ch6_init[] = { +static const struct hda_verb alc861_threestack_ch6_init[] = { /* set pin widget 1Ah (line in) for output (Back Surround)*/ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, /* set pin widget 18h (mic1) for output (CLFE)*/ @@ -15377,30 +15389,30 @@ static struct hda_verb alc861_threestack_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode alc861_threestack_modes[2] = { +static const struct hda_channel_mode alc861_threestack_modes[2] = { { 2, alc861_threestack_ch2_init }, { 6, alc861_threestack_ch6_init }, }; /* Set mic1 as input and unmute the mixer */ -static struct hda_verb alc861_uniwill_m31_ch2_init[] = { +static const struct hda_verb alc861_uniwill_m31_ch2_init[] = { { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7080 | (0x01 << 8)) }, /*mic*/ { } /* end */ }; /* Set mic1 as output and mute mixer */ -static struct hda_verb alc861_uniwill_m31_ch4_init[] = { +static const struct hda_verb alc861_uniwill_m31_ch4_init[] = { { 0x0d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, (0x7000 | (0x01 << 8)) }, /*mic*/ { } /* end */ }; -static struct hda_channel_mode alc861_uniwill_m31_modes[2] = { +static const struct hda_channel_mode alc861_uniwill_m31_modes[2] = { { 2, alc861_uniwill_m31_ch2_init }, { 4, alc861_uniwill_m31_ch4_init }, }; /* Set mic1 and line-in as input and unmute the mixer */ -static struct hda_verb alc861_asus_ch2_init[] = { +static const struct hda_verb alc861_asus_ch2_init[] = { /* set pin widget 1Ah (line in) for input */ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, /* set pin widget 18h (mic1/2) for input, for mic also enable @@ -15416,7 +15428,7 @@ static struct hda_verb alc861_asus_ch2_init[] = { { } /* end */ }; /* Set mic1 nad line-in as output and mute mixer */ -static struct hda_verb alc861_asus_ch6_init[] = { +static const struct hda_verb alc861_asus_ch6_init[] = { /* set pin widget 1Ah (line in) for output (Back Surround)*/ { 0x0c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, /* { 0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, */ @@ -15434,14 +15446,14 @@ static struct hda_verb alc861_asus_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode alc861_asus_modes[2] = { +static const struct hda_channel_mode alc861_asus_modes[2] = { { 2, alc861_asus_ch2_init }, { 6, alc861_asus_ch6_init }, }; /* patch-ALC861 */ -static struct snd_kcontrol_new alc861_base_mixer[] = { +static const struct snd_kcontrol_new alc861_base_mixer[] = { /* output mixer control */ HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), @@ -15464,7 +15476,7 @@ static struct snd_kcontrol_new alc861_base_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc861_3ST_mixer[] = { +static const struct snd_kcontrol_new alc861_3ST_mixer[] = { /* output mixer control */ HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), @@ -15495,7 +15507,7 @@ static struct snd_kcontrol_new alc861_3ST_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc861_toshiba_mixer[] = { +static const struct snd_kcontrol_new alc861_toshiba_mixer[] = { /* output mixer control */ HDA_CODEC_MUTE("Master Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Mic Playback Volume", 0x15, 0x01, HDA_INPUT), @@ -15504,7 +15516,7 @@ static struct snd_kcontrol_new alc861_toshiba_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { +static const struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { /* output mixer control */ HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), @@ -15535,7 +15547,7 @@ static struct snd_kcontrol_new alc861_uniwill_m31_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc861_asus_mixer[] = { +static const struct snd_kcontrol_new alc861_asus_mixer[] = { /* output mixer control */ HDA_CODEC_MUTE("Front Playback Switch", 0x03, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Surround Playback Switch", 0x06, 0x0, HDA_OUTPUT), @@ -15567,7 +15579,7 @@ static struct snd_kcontrol_new alc861_asus_mixer[] = { }; /* additional mixer */ -static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { +static const struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_INPUT), HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_INPUT), { } @@ -15576,7 +15588,7 @@ static struct snd_kcontrol_new alc861_asus_laptop_mixer[] = { /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc861_base_init_verbs[] = { +static const struct hda_verb alc861_base_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ @@ -15642,7 +15654,7 @@ static struct hda_verb alc861_base_init_verbs[] = { { } }; -static struct hda_verb alc861_threestack_init_verbs[] = { +static const struct hda_verb alc861_threestack_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ @@ -15703,7 +15715,7 @@ static struct hda_verb alc861_threestack_init_verbs[] = { { } }; -static struct hda_verb alc861_uniwill_m31_init_verbs[] = { +static const struct hda_verb alc861_uniwill_m31_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ @@ -15765,7 +15777,7 @@ static struct hda_verb alc861_uniwill_m31_init_verbs[] = { { } }; -static struct hda_verb alc861_asus_init_verbs[] = { +static const struct hda_verb alc861_asus_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ @@ -15831,7 +15843,7 @@ static struct hda_verb alc861_asus_init_verbs[] = { }; /* additional init verbs for ASUS laptops */ -static struct hda_verb alc861_asus_laptop_init_verbs[] = { +static const struct hda_verb alc861_asus_laptop_init_verbs[] = { { 0x0f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x45 }, /* HP-out */ { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2) }, /* mute line-in */ { } @@ -15840,7 +15852,7 @@ static struct hda_verb alc861_asus_laptop_init_verbs[] = { /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc861_auto_init_verbs[] = { +static const struct hda_verb alc861_auto_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ @@ -15889,7 +15901,7 @@ static struct hda_verb alc861_auto_init_verbs[] = { { } }; -static struct hda_verb alc861_toshiba_init_verbs[] = { +static const struct hda_verb alc861_toshiba_init_verbs[] = { {0x0f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, { } @@ -15922,26 +15934,26 @@ static void alc861_toshiba_unsol_event(struct hda_codec *codec, #define ALC861_DIGOUT_NID 0x07 -static struct hda_channel_mode alc861_8ch_modes[1] = { +static const struct hda_channel_mode alc861_8ch_modes[1] = { { 8, NULL } }; -static hda_nid_t alc861_dac_nids[4] = { +static const hda_nid_t alc861_dac_nids[4] = { /* front, surround, clfe, side */ 0x03, 0x06, 0x05, 0x04 }; -static hda_nid_t alc660_dac_nids[3] = { +static const hda_nid_t alc660_dac_nids[3] = { /* front, clfe, surround */ 0x03, 0x05, 0x06 }; -static hda_nid_t alc861_adc_nids[1] = { +static const hda_nid_t alc861_adc_nids[1] = { /* ADC0-2 */ 0x08, }; -static struct hda_input_mux alc861_capture_source = { +static const struct hda_input_mux alc861_capture_source = { .num_items = 5, .items = { { "Mic", 0x0 }, @@ -15991,7 +16003,7 @@ static int alc861_auto_fill_dac_nids(struct hda_codec *codec, dac = alc861_look_for_dac(codec, nid); if (!dac) continue; - spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; + spec->private_dac_nids[spec->multiout.num_dacs++] = dac; } return 0; } @@ -16014,11 +16026,15 @@ static int alc861_auto_create_multi_out_ctls(struct hda_codec *codec, static const char * const chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; - const char *pfx = alc_get_line_out_pfx(cfg, true); + const char *pfx = alc_get_line_out_pfx(spec, true); hda_nid_t nid; - int i, err; + int i, err, noutputs; - for (i = 0; i < cfg->line_outs; i++) { + noutputs = cfg->line_outs; + if (spec->multi_ios > 0) + noutputs += spec->multi_ios; + + for (i = 0; i < noutputs; i++) { nid = spec->multiout.dac_nids[i]; if (!nid) continue; @@ -16151,7 +16167,7 @@ static int alc861_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; - static hda_nid_t alc861_ignore[] = { 0x1d, 0 }; + static const hda_nid_t alc861_ignore[] = { 0x1d, 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc861_ignore); @@ -16161,6 +16177,9 @@ static int alc861_parse_auto_config(struct hda_codec *codec) return 0; /* can't find valid BIOS pin config */ err = alc861_auto_fill_dac_nids(codec, &spec->autocfg); + if (err < 0) + return err; + err = alc_auto_add_multi_channel_mode(codec); if (err < 0) return err; err = alc861_auto_create_multi_out_ctls(codec, &spec->autocfg); @@ -16207,7 +16226,7 @@ static void alc861_auto_init(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list alc861_loopbacks[] = { +static const struct hda_amp_list alc861_loopbacks[] = { { 0x15, HDA_INPUT, 0 }, { 0x15, HDA_INPUT, 1 }, { 0x15, HDA_INPUT, 2 }, @@ -16232,7 +16251,7 @@ static const char * const alc861_models[ALC861_MODEL_LAST] = { [ALC861_AUTO] = "auto", }; -static struct snd_pci_quirk alc861_cfg_tbl[] = { +static const struct snd_pci_quirk alc861_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1205, "ASUS W7J", ALC861_3ST), SND_PCI_QUIRK(0x1043, 0x1335, "ASUS F2/3", ALC861_ASUS_LAPTOP), SND_PCI_QUIRK(0x1043, 0x1338, "ASUS F2/3", ALC861_ASUS_LAPTOP), @@ -16256,7 +16275,7 @@ static struct snd_pci_quirk alc861_cfg_tbl[] = { {} }; -static struct alc_config_preset alc861_presets[] = { +static const struct alc_config_preset alc861_presets[] = { [ALC861_3ST] = { .mixers = { alc861_3ST_mixer }, .init_verbs = { alc861_threestack_init_verbs }, @@ -16379,7 +16398,7 @@ static const struct alc_fixup alc861_fixups[] = { }, }; -static struct snd_pci_quirk alc861_fixup_tbl[] = { +static const struct snd_pci_quirk alc861_fixup_tbl[] = { SND_PCI_QUIRK(0x1734, 0x10c7, "FSC Amilo Pi1505", PINFIX_FSC_AMILO_PI1505), {} }; @@ -16472,7 +16491,7 @@ static int patch_alc861(struct hda_codec *codec) */ #define ALC861VD_DIGOUT_NID 0x06 -static hda_nid_t alc861vd_dac_nids[4] = { +static const hda_nid_t alc861vd_dac_nids[4] = { /* front, surr, clfe, side surr */ 0x02, 0x03, 0x04, 0x05 }; @@ -16484,21 +16503,21 @@ static hda_nid_t alc861vd_dac_nids[4] = { * - and it is the same as in 861vd. * adc_nids in ALC660vd are (is) the same as in 861vd */ -static hda_nid_t alc660vd_dac_nids[3] = { +static const hda_nid_t alc660vd_dac_nids[3] = { /* front, rear, clfe, rear_surr */ 0x02, 0x04, 0x03 }; -static hda_nid_t alc861vd_adc_nids[1] = { +static const hda_nid_t alc861vd_adc_nids[1] = { /* ADC0 */ 0x09, }; -static hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; +static const hda_nid_t alc861vd_capsrc_nids[1] = { 0x22 }; /* input MUX */ /* FIXME: should be a matrix-type input source selection */ -static struct hda_input_mux alc861vd_capture_source = { +static const struct hda_input_mux alc861vd_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -16508,7 +16527,7 @@ static struct hda_input_mux alc861vd_capture_source = { }, }; -static struct hda_input_mux alc861vd_dallas_capture_source = { +static const struct hda_input_mux alc861vd_dallas_capture_source = { .num_items = 2, .items = { { "Mic", 0x0 }, @@ -16516,7 +16535,7 @@ static struct hda_input_mux alc861vd_dallas_capture_source = { }, }; -static struct hda_input_mux alc861vd_hp_capture_source = { +static const struct hda_input_mux alc861vd_hp_capture_source = { .num_items = 2, .items = { { "Front Mic", 0x0 }, @@ -16527,14 +16546,14 @@ static struct hda_input_mux alc861vd_hp_capture_source = { /* * 2ch mode */ -static struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { +static const struct hda_channel_mode alc861vd_3stack_2ch_modes[1] = { { 2, NULL } }; /* * 6ch mode */ -static struct hda_verb alc861vd_6stack_ch6_init[] = { +static const struct hda_verb alc861vd_6stack_ch6_init[] = { { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -16545,7 +16564,7 @@ static struct hda_verb alc861vd_6stack_ch6_init[] = { /* * 8ch mode */ -static struct hda_verb alc861vd_6stack_ch8_init[] = { +static const struct hda_verb alc861vd_6stack_ch8_init[] = { { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -16553,12 +16572,12 @@ static struct hda_verb alc861vd_6stack_ch8_init[] = { { } /* end */ }; -static struct hda_channel_mode alc861vd_6stack_modes[2] = { +static const struct hda_channel_mode alc861vd_6stack_modes[2] = { { 6, alc861vd_6stack_ch6_init }, { 8, alc861vd_6stack_ch8_init }, }; -static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { +static const struct snd_kcontrol_new alc861vd_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", @@ -16572,7 +16591,7 @@ static struct snd_kcontrol_new alc861vd_chmode_mixer[] = { /* Pin assignment: Front=0x14, Rear=0x15, CLFE=0x16, Side=0x17 * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b */ -static struct snd_kcontrol_new alc861vd_6st_mixer[] = { +static const struct snd_kcontrol_new alc861vd_6st_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -16608,7 +16627,7 @@ static struct snd_kcontrol_new alc861vd_6st_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc861vd_3st_mixer[] = { +static const struct snd_kcontrol_new alc861vd_3st_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), @@ -16631,7 +16650,7 @@ static struct snd_kcontrol_new alc861vd_3st_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { +static const struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), /*HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT),*/ HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -16655,7 +16674,7 @@ static struct snd_kcontrol_new alc861vd_lenovo_mixer[] = { /* Pin assignment: Speaker=0x14, HP = 0x15, * Mic=0x18, Internal Mic = 0x19, CD = 0x1c, PC Beep = 0x1d */ -static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { +static const struct snd_kcontrol_new alc861vd_dallas_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Speaker Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -16672,7 +16691,7 @@ static struct snd_kcontrol_new alc861vd_dallas_mixer[] = { /* Pin assignment: Speaker=0x14, Line-out = 0x15, * Front Mic=0x18, ATAPI Mic = 0x19, */ -static struct snd_kcontrol_new alc861vd_hp_mixer[] = { +static const struct snd_kcontrol_new alc861vd_hp_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x0c, 2, HDA_INPUT), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -16688,7 +16707,7 @@ static struct snd_kcontrol_new alc861vd_hp_mixer[] = { /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc861vd_volume_init_verbs[] = { +static const struct hda_verb alc861vd_volume_init_verbs[] = { /* * Unmute ADC0 and set the default input to mic-in */ @@ -16738,7 +16757,7 @@ static struct hda_verb alc861vd_volume_init_verbs[] = { * 3-stack pin configuration: * front = 0x14, mic/clfe = 0x18, HP = 0x19, line/surr = 0x1a, f-mic = 0x1b */ -static struct hda_verb alc861vd_3stack_init_verbs[] = { +static const struct hda_verb alc861vd_3stack_init_verbs[] = { /* * Set pin mode and muting */ @@ -16769,7 +16788,7 @@ static struct hda_verb alc861vd_3stack_init_verbs[] = { /* * 6-stack pin configuration: */ -static struct hda_verb alc861vd_6stack_init_verbs[] = { +static const struct hda_verb alc861vd_6stack_init_verbs[] = { /* * Set pin mode and muting */ @@ -16810,18 +16829,18 @@ static struct hda_verb alc861vd_6stack_init_verbs[] = { { } }; -static struct hda_verb alc861vd_eapd_verbs[] = { +static const struct hda_verb alc861vd_eapd_verbs[] = { {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, { } }; -static struct hda_verb alc660vd_eapd_verbs[] = { +static const struct hda_verb alc660vd_eapd_verbs[] = { {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, { } }; -static struct hda_verb alc861vd_lenovo_unsol_verbs[] = { +static const struct hda_verb alc861vd_lenovo_unsol_verbs[] = { {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, @@ -16835,11 +16854,13 @@ static void alc861vd_lenovo_setup(struct hda_codec *codec) struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x1b; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc861vd_lenovo_init_hook(struct hda_codec *codec) { - alc_automute_amp(codec); + alc_hp_automute(codec); alc88x_simple_mic_automute(codec); } @@ -16851,12 +16872,12 @@ static void alc861vd_lenovo_unsol_event(struct hda_codec *codec, alc88x_simple_mic_automute(codec); break; default: - alc_automute_amp_unsol_event(codec, res); + alc_sku_unsol_event(codec, res); break; } } -static struct hda_verb alc861vd_dallas_verbs[] = { +static const struct hda_verb alc861vd_dallas_verbs[] = { {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, @@ -16908,6 +16929,8 @@ static void alc861vd_dallas_setup(struct hda_codec *codec) spec->autocfg.hp_pins[0] = 0x15; spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } #ifdef CONFIG_SND_HDA_POWER_SAVE @@ -16936,7 +16959,7 @@ static const char * const alc861vd_models[ALC861VD_MODEL_LAST] = { [ALC861VD_AUTO] = "auto", }; -static struct snd_pci_quirk alc861vd_cfg_tbl[] = { +static const struct snd_pci_quirk alc861vd_cfg_tbl[] = { SND_PCI_QUIRK(0x1019, 0xa88d, "Realtek ALC660 demo", ALC660VD_3ST), SND_PCI_QUIRK(0x103c, 0x30bf, "HP TX1000", ALC861VD_HP), SND_PCI_QUIRK(0x1043, 0x12e2, "Asus z35m", ALC660VD_3ST), @@ -16955,7 +16978,7 @@ static struct snd_pci_quirk alc861vd_cfg_tbl[] = { {} }; -static struct alc_config_preset alc861vd_presets[] = { +static const struct alc_config_preset alc861vd_presets[] = { [ALC660VD_3ST] = { .mixers = { alc861vd_3st_mixer }, .init_verbs = { alc861vd_volume_init_verbs, @@ -17032,9 +17055,9 @@ static struct alc_config_preset alc861vd_presets[] = { .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), .channel_mode = alc861vd_3stack_2ch_modes, .input_mux = &alc861vd_dallas_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc861vd_dallas_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC861VD_HP] = { .mixers = { alc861vd_hp_mixer }, @@ -17045,9 +17068,9 @@ static struct alc_config_preset alc861vd_presets[] = { .num_channel_mode = ARRAY_SIZE(alc861vd_3stack_2ch_modes), .channel_mode = alc861vd_3stack_2ch_modes, .input_mux = &alc861vd_hp_capture_source, - .unsol_event = alc_automute_amp_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc861vd_dallas_setup, - .init_hook = alc_automute_amp, + .init_hook = alc_hp_automute, }, [ALC660VD_ASUS_V1S] = { .mixers = { alc861vd_lenovo_mixer }, @@ -17146,11 +17169,15 @@ static int alc861vd_auto_create_multi_out_ctls(struct alc_spec *spec, static const char * const chname[4] = { "Front", "Surround", "CLFE", "Side" }; - const char *pfx = alc_get_line_out_pfx(cfg, true); + const char *pfx = alc_get_line_out_pfx(spec, true); hda_nid_t nid_v, nid_s; - int i, err; + int i, err, noutputs; - for (i = 0; i < cfg->line_outs; i++) { + noutputs = cfg->line_outs; + if (spec->multi_ios > 0) + noutputs += spec->multi_ios; + + for (i = 0; i < noutputs; i++) { if (!spec->multiout.dac_nids[i]) continue; nid_v = alc861vd_idx_to_mixer_vol( @@ -17263,7 +17290,7 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; - static hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; + static const hda_nid_t alc861vd_ignore[] = { 0x1d, 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc861vd_ignore); @@ -17273,6 +17300,9 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) return 0; /* can't find valid BIOS pin config */ err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); + if (err < 0) + return err; + err = alc_auto_add_multi_channel_mode(codec); if (err < 0) return err; err = alc861vd_auto_create_multi_out_ctls(spec, &spec->autocfg); @@ -17343,7 +17373,7 @@ static const struct alc_fixup alc861vd_fixups[] = { }, }; -static struct snd_pci_quirk alc861vd_fixup_tbl[] = { +static const struct snd_pci_quirk alc861vd_fixup_tbl[] = { SND_PCI_QUIRK(0x1043, 0x1339, "ASUS A7-K", ALC660VD_FIX_ASUS_GPIO1), {} }; @@ -17426,6 +17456,7 @@ static int patch_alc861vd(struct hda_codec *codec) if (board_config == ALC861VD_AUTO) spec->init_hook = alc861vd_auto_init; + spec->shutup = alc_eapd_shutup; #ifdef CONFIG_SND_HDA_POWER_SAVE if (!spec->loopback.amplist) spec->loopback.amplist = alc861vd_loopbacks; @@ -17448,32 +17479,32 @@ static int patch_alc861vd(struct hda_codec *codec) #define ALC662_DIGOUT_NID 0x06 #define ALC662_DIGIN_NID 0x0a -static hda_nid_t alc662_dac_nids[4] = { - /* front, rear, clfe, rear_surr */ +static const hda_nid_t alc662_dac_nids[3] = { + /* front, rear, clfe */ 0x02, 0x03, 0x04 }; -static hda_nid_t alc272_dac_nids[2] = { +static const hda_nid_t alc272_dac_nids[2] = { 0x02, 0x03 }; -static hda_nid_t alc662_adc_nids[2] = { +static const hda_nid_t alc662_adc_nids[2] = { /* ADC1-2 */ 0x09, 0x08 }; -static hda_nid_t alc272_adc_nids[1] = { +static const hda_nid_t alc272_adc_nids[1] = { /* ADC1-2 */ 0x08, }; -static hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; -static hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; +static const hda_nid_t alc662_capsrc_nids[2] = { 0x22, 0x23 }; +static const hda_nid_t alc272_capsrc_nids[1] = { 0x23 }; /* input MUX */ /* FIXME: should be a matrix-type input source selection */ -static struct hda_input_mux alc662_capture_source = { +static const struct hda_input_mux alc662_capture_source = { .num_items = 4, .items = { { "Mic", 0x0 }, @@ -17483,7 +17514,7 @@ static struct hda_input_mux alc662_capture_source = { }, }; -static struct hda_input_mux alc662_lenovo_101e_capture_source = { +static const struct hda_input_mux alc662_lenovo_101e_capture_source = { .num_items = 2, .items = { { "Mic", 0x1 }, @@ -17491,7 +17522,7 @@ static struct hda_input_mux alc662_lenovo_101e_capture_source = { }, }; -static struct hda_input_mux alc663_capture_source = { +static const struct hda_input_mux alc663_capture_source = { .num_items = 3, .items = { { "Mic", 0x0 }, @@ -17501,7 +17532,7 @@ static struct hda_input_mux alc663_capture_source = { }; #if 0 /* set to 1 for testing other input sources below */ -static struct hda_input_mux alc272_nc10_capture_source = { +static const struct hda_input_mux alc272_nc10_capture_source = { .num_items = 16, .items = { { "Autoselect Mic", 0x0 }, @@ -17527,14 +17558,14 @@ static struct hda_input_mux alc272_nc10_capture_source = { /* * 2ch mode */ -static struct hda_channel_mode alc662_3ST_2ch_modes[1] = { +static const struct hda_channel_mode alc662_3ST_2ch_modes[1] = { { 2, NULL } }; /* * 2ch mode */ -static struct hda_verb alc662_3ST_ch2_init[] = { +static const struct hda_verb alc662_3ST_ch2_init[] = { { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, { 0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, @@ -17545,7 +17576,7 @@ static struct hda_verb alc662_3ST_ch2_init[] = { /* * 6ch mode */ -static struct hda_verb alc662_3ST_ch6_init[] = { +static const struct hda_verb alc662_3ST_ch6_init[] = { { 0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, { 0x18, AC_VERB_SET_CONNECT_SEL, 0x02 }, @@ -17555,7 +17586,7 @@ static struct hda_verb alc662_3ST_ch6_init[] = { { } /* end */ }; -static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { +static const struct hda_channel_mode alc662_3ST_6ch_modes[2] = { { 2, alc662_3ST_ch2_init }, { 6, alc662_3ST_ch6_init }, }; @@ -17563,7 +17594,7 @@ static struct hda_channel_mode alc662_3ST_6ch_modes[2] = { /* * 2ch mode */ -static struct hda_verb alc662_sixstack_ch6_init[] = { +static const struct hda_verb alc662_sixstack_ch6_init[] = { { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x00 }, { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, @@ -17573,14 +17604,14 @@ static struct hda_verb alc662_sixstack_ch6_init[] = { /* * 6ch mode */ -static struct hda_verb alc662_sixstack_ch8_init[] = { +static const struct hda_verb alc662_sixstack_ch8_init[] = { { 0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { 0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, { } /* end */ }; -static struct hda_channel_mode alc662_5stack_modes[2] = { +static const struct hda_channel_mode alc662_5stack_modes[2] = { { 2, alc662_sixstack_ch6_init }, { 6, alc662_sixstack_ch8_init }, }; @@ -17589,7 +17620,7 @@ static struct hda_channel_mode alc662_5stack_modes[2] = { * Mic=0x18, Front Mic=0x19, Line-In=0x1a, HP=0x1b */ -static struct snd_kcontrol_new alc662_base_mixer[] = { +static const struct snd_kcontrol_new alc662_base_mixer[] = { /* output mixer control */ HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), @@ -17613,7 +17644,7 @@ static struct snd_kcontrol_new alc662_base_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { +static const struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -17628,7 +17659,7 @@ static struct snd_kcontrol_new alc662_3ST_2ch_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { +static const struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x0c, 0x0, HDA_INPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -17649,7 +17680,7 @@ static struct snd_kcontrol_new alc662_3ST_6ch_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { +static const struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_BIND_MUTE("Front Playback Switch", 0x02, 2, HDA_INPUT), HDA_CODEC_VOLUME("Speaker Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -17662,7 +17693,7 @@ static struct snd_kcontrol_new alc662_lenovo_101e_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { +static const struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, @@ -17676,7 +17707,7 @@ static struct snd_kcontrol_new alc662_eeepc_p701_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { +static const struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { ALC262_HIPPO_MASTER_SWITCH, HDA_CODEC_VOLUME("Front Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -17690,7 +17721,7 @@ static struct snd_kcontrol_new alc662_eeepc_ep20_mixer[] = { { } /* end */ }; -static struct hda_bind_ctls alc663_asus_bind_master_vol = { +static const struct hda_bind_ctls alc663_asus_bind_master_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), @@ -17699,7 +17730,7 @@ static struct hda_bind_ctls alc663_asus_bind_master_vol = { }, }; -static struct hda_bind_ctls alc663_asus_one_bind_switch = { +static const struct hda_bind_ctls alc663_asus_one_bind_switch = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17708,7 +17739,7 @@ static struct hda_bind_ctls alc663_asus_one_bind_switch = { }, }; -static struct snd_kcontrol_new alc663_m51va_mixer[] = { +static const struct snd_kcontrol_new alc663_m51va_mixer[] = { HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), HDA_BIND_SW("Master Playback Switch", &alc663_asus_one_bind_switch), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -17716,7 +17747,7 @@ static struct snd_kcontrol_new alc663_m51va_mixer[] = { { } /* end */ }; -static struct hda_bind_ctls alc663_asus_tree_bind_switch = { +static const struct hda_bind_ctls alc663_asus_tree_bind_switch = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17726,7 +17757,7 @@ static struct hda_bind_ctls alc663_asus_tree_bind_switch = { }, }; -static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { +static const struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), HDA_BIND_SW("Master Playback Switch", &alc663_asus_tree_bind_switch), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -17737,7 +17768,7 @@ static struct snd_kcontrol_new alc663_two_hp_m1_mixer[] = { { } /* end */ }; -static struct hda_bind_ctls alc663_asus_four_bind_switch = { +static const struct hda_bind_ctls alc663_asus_four_bind_switch = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17747,7 +17778,7 @@ static struct hda_bind_ctls alc663_asus_four_bind_switch = { }, }; -static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { +static const struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), HDA_BIND_SW("Master Playback Switch", &alc663_asus_four_bind_switch), HDA_CODEC_VOLUME("Mic Playback Volume", 0x0b, 0x0, HDA_INPUT), @@ -17757,7 +17788,7 @@ static struct snd_kcontrol_new alc663_two_hp_m2_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc662_1bjd_mixer[] = { +static const struct snd_kcontrol_new alc662_1bjd_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x1b, 0x0, HDA_OUTPUT), @@ -17768,7 +17799,7 @@ static struct snd_kcontrol_new alc662_1bjd_mixer[] = { { } /* end */ }; -static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { +static const struct hda_bind_ctls alc663_asus_two_bind_master_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x02, 3, 0, HDA_OUTPUT), @@ -17777,7 +17808,7 @@ static struct hda_bind_ctls alc663_asus_two_bind_master_vol = { }, }; -static struct hda_bind_ctls alc663_asus_two_bind_switch = { +static const struct hda_bind_ctls alc663_asus_two_bind_switch = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17786,7 +17817,7 @@ static struct hda_bind_ctls alc663_asus_two_bind_switch = { }, }; -static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { +static const struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { HDA_BIND_VOL("Master Playback Volume", &alc663_asus_two_bind_master_vol), HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), @@ -17797,7 +17828,7 @@ static struct snd_kcontrol_new alc663_asus_21jd_clfe_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { +static const struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { HDA_BIND_VOL("Master Playback Volume", &alc663_asus_bind_master_vol), HDA_BIND_SW("Master Playback Switch", &alc663_asus_two_bind_switch), HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -17807,7 +17838,7 @@ static struct snd_kcontrol_new alc663_asus_15jd_clfe_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc663_g71v_mixer[] = { +static const struct snd_kcontrol_new alc663_g71v_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_VOLUME("Front Playback Volume", 0x03, 0x0, HDA_OUTPUT), @@ -17821,7 +17852,7 @@ static struct snd_kcontrol_new alc663_g71v_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc663_g50v_mixer[] = { +static const struct snd_kcontrol_new alc663_g50v_mixer[] = { HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Headphone Playback Switch", 0x21, 0x0, HDA_OUTPUT), @@ -17835,7 +17866,7 @@ static struct snd_kcontrol_new alc663_g50v_mixer[] = { { } /* end */ }; -static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { +static const struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17847,7 +17878,7 @@ static struct hda_bind_ctls alc663_asus_mode7_8_all_bind_switch = { }, }; -static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { +static const struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), @@ -17856,7 +17887,7 @@ static struct hda_bind_ctls alc663_asus_mode7_8_sp_bind_switch = { }, }; -static struct snd_kcontrol_new alc663_mode7_mixer[] = { +static const struct snd_kcontrol_new alc663_mode7_mixer[] = { HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), @@ -17869,7 +17900,7 @@ static struct snd_kcontrol_new alc663_mode7_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc663_mode8_mixer[] = { +static const struct snd_kcontrol_new alc663_mode8_mixer[] = { HDA_BIND_SW("Master Playback Switch", &alc663_asus_mode7_8_all_bind_switch), HDA_BIND_VOL("Speaker Playback Volume", &alc663_asus_bind_master_vol), HDA_BIND_SW("Speaker Playback Switch", &alc663_asus_mode7_8_sp_bind_switch), @@ -17881,7 +17912,7 @@ static struct snd_kcontrol_new alc663_mode8_mixer[] = { }; -static struct snd_kcontrol_new alc662_chmode_mixer[] = { +static const struct snd_kcontrol_new alc662_chmode_mixer[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Channel Mode", @@ -17892,7 +17923,7 @@ static struct snd_kcontrol_new alc662_chmode_mixer[] = { { } /* end */ }; -static struct hda_verb alc662_init_verbs[] = { +static const struct hda_verb alc662_init_verbs[] = { /* ADC: mute amp left and right */ {0x09, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x09, AC_VERB_SET_CONNECT_SEL, 0x00}, @@ -17938,55 +17969,36 @@ static struct hda_verb alc662_init_verbs[] = { {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x23, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + { } +}; + +static const struct hda_verb alc662_eapd_init_verbs[] = { /* always trun on EAPD */ {0x14, AC_VERB_SET_EAPD_BTLENABLE, 2}, {0x15, AC_VERB_SET_EAPD_BTLENABLE, 2}, - { } }; -static struct hda_verb alc663_init_verbs[] = { - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - { } -}; - -static struct hda_verb alc272_init_verbs[] = { - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - {0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, - { } -}; - -static struct hda_verb alc662_sue_init_verbs[] = { +static const struct hda_verb alc662_sue_init_verbs[] = { {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_FRONT_EVENT}, {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN|ALC880_HP_EVENT}, {} }; -static struct hda_verb alc662_eeepc_sue_init_verbs[] = { +static const struct hda_verb alc662_eeepc_sue_init_verbs[] = { {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {} }; /* Set Unsolicited Event*/ -static struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { +static const struct hda_verb alc662_eeepc_ep20_sue_init_verbs[] = { {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_HP_EVENT}, {} }; -static struct hda_verb alc663_m51va_init_verbs[] = { +static const struct hda_verb alc663_m51va_init_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, @@ -17999,7 +18011,7 @@ static struct hda_verb alc663_m51va_init_verbs[] = { {} }; -static struct hda_verb alc663_21jd_amic_init_verbs[] = { +static const struct hda_verb alc663_21jd_amic_init_verbs[] = { {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x21, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ @@ -18010,7 +18022,7 @@ static struct hda_verb alc663_21jd_amic_init_verbs[] = { {} }; -static struct hda_verb alc662_1bjd_amic_init_verbs[] = { +static const struct hda_verb alc662_1bjd_amic_init_verbs[] = { {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -18022,7 +18034,7 @@ static struct hda_verb alc662_1bjd_amic_init_verbs[] = { {} }; -static struct hda_verb alc663_15jd_amic_init_verbs[] = { +static const struct hda_verb alc663_15jd_amic_init_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, /* Headphone */ @@ -18033,7 +18045,7 @@ static struct hda_verb alc663_15jd_amic_init_verbs[] = { {} }; -static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { +static const struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -18049,7 +18061,7 @@ static struct hda_verb alc663_two_hp_amic_m1_init_verbs[] = { {} }; -static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { +static const struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -18065,7 +18077,7 @@ static struct hda_verb alc663_two_hp_amic_m2_init_verbs[] = { {} }; -static struct hda_verb alc663_g71v_init_verbs[] = { +static const struct hda_verb alc663_g71v_init_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, /* {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, */ /* {0x15, AC_VERB_SET_CONNECT_SEL, 0x01}, */ /* Headphone */ @@ -18080,7 +18092,7 @@ static struct hda_verb alc663_g71v_init_verbs[] = { {} }; -static struct hda_verb alc663_g50v_init_verbs[] = { +static const struct hda_verb alc663_g50v_init_verbs[] = { {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x21, AC_VERB_SET_CONNECT_SEL, 0x00}, /* Headphone */ @@ -18090,7 +18102,7 @@ static struct hda_verb alc663_g50v_init_verbs[] = { {} }; -static struct hda_verb alc662_ecs_init_verbs[] = { +static const struct hda_verb alc662_ecs_init_verbs[] = { {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0x701f}, {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, {0x18, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | ALC880_MIC_EVENT}, @@ -18098,7 +18110,7 @@ static struct hda_verb alc662_ecs_init_verbs[] = { {} }; -static struct hda_verb alc272_dell_zm1_init_verbs[] = { +static const struct hda_verb alc272_dell_zm1_init_verbs[] = { {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, @@ -18113,7 +18125,7 @@ static struct hda_verb alc272_dell_zm1_init_verbs[] = { {} }; -static struct hda_verb alc272_dell_init_verbs[] = { +static const struct hda_verb alc272_dell_init_verbs[] = { {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, @@ -18128,7 +18140,7 @@ static struct hda_verb alc272_dell_init_verbs[] = { {} }; -static struct hda_verb alc663_mode7_init_verbs[] = { +static const struct hda_verb alc663_mode7_init_verbs[] = { {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, @@ -18147,7 +18159,7 @@ static struct hda_verb alc663_mode7_init_verbs[] = { {} }; -static struct hda_verb alc663_mode8_init_verbs[] = { +static const struct hda_verb alc663_mode8_init_verbs[] = { {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -18167,61 +18179,29 @@ static struct hda_verb alc663_mode8_init_verbs[] = { {} }; -static struct snd_kcontrol_new alc662_auto_capture_mixer[] = { +static const struct snd_kcontrol_new alc662_auto_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x09, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x09, 0x0, HDA_INPUT), { } /* end */ }; -static struct snd_kcontrol_new alc272_auto_capture_mixer[] = { +static const struct snd_kcontrol_new alc272_auto_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x08, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x08, 0x0, HDA_INPUT), { } /* end */ }; -static void alc662_lenovo_101e_ispeaker_automute(struct hda_codec *codec) +static void alc662_lenovo_101e_setup(struct hda_codec *codec) { - unsigned int present; - unsigned char bits; + struct alc_spec *spec = codec->spec; - present = snd_hda_jack_detect(codec, 0x14); - bits = present ? HDA_AMP_MUTE : 0; - - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, bits); -} - -static void alc662_lenovo_101e_all_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x1b); - bits = present ? HDA_AMP_MUTE : 0; - - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, - HDA_AMP_MUTE, bits); -} - -static void alc662_lenovo_101e_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) == ALC880_HP_EVENT) - alc662_lenovo_101e_all_automute(codec); - if ((res >> 26) == ALC880_FRONT_EVENT) - alc662_lenovo_101e_ispeaker_automute(codec); -} - -/* unsolicited event for HP jack sensing */ -static void alc662_eeepc_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - if ((res >> 26) == ALC880_MIC_EVENT) - alc_mic_automute(codec); - else - alc262_hippo_unsol_event(codec, res); + spec->autocfg.hp_pins[0] = 0x1b; + spec->autocfg.line_out_pins[0] = 0x14; + spec->autocfg.speaker_pins[0] = 0x15; + spec->automute = 1; + spec->detect_line = 1; + spec->automute_lines = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc662_eeepc_setup(struct hda_codec *codec) @@ -18236,180 +18216,24 @@ static void alc662_eeepc_setup(struct hda_codec *codec) spec->auto_mic = 1; } -static void alc662_eeepc_inithook(struct hda_codec *codec) -{ - alc262_hippo_automute(codec); - alc_mic_automute(codec); -} - static void alc662_eeepc_ep20_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; spec->autocfg.hp_pins[0] = 0x14; spec->autocfg.speaker_pins[0] = 0x1b; -} - -#define alc662_eeepc_ep20_inithook alc262_hippo_master_update - -static void alc663_m51va_speaker_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x21); - bits = present ? HDA_AMP_MUTE : 0; - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); -} - -static void alc663_21jd_two_speaker_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x21); - bits = present ? HDA_AMP_MUTE : 0; - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); -} - -static void alc663_15jd_two_speaker_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x15); - bits = present ? HDA_AMP_MUTE : 0; - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x0e, HDA_INPUT, 1, - HDA_AMP_MUTE, bits); -} - -static void alc662_f5z_speaker_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x1b); - bits = present ? 0 : PIN_OUT; - snd_hda_codec_write(codec, 0x14, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, bits); -} - -static void alc663_two_hp_m1_speaker_automute(struct hda_codec *codec) -{ - unsigned int present1, present2; - - present1 = snd_hda_jack_detect(codec, 0x21); - present2 = snd_hda_jack_detect(codec, 0x15); - - if (present1 || present2) { - snd_hda_codec_write_cache(codec, 0x14, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, 0); - } else { - snd_hda_codec_write_cache(codec, 0x14, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - } -} - -static void alc663_two_hp_m2_speaker_automute(struct hda_codec *codec) -{ - unsigned int present1, present2; - - present1 = snd_hda_jack_detect(codec, 0x1b); - present2 = snd_hda_jack_detect(codec, 0x15); - - if (present1 || present2) { - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - HDA_AMP_MUTE, HDA_AMP_MUTE); - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - HDA_AMP_MUTE, HDA_AMP_MUTE); - } else { - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 0, - HDA_AMP_MUTE, 0); - snd_hda_codec_amp_stereo(codec, 0x0c, HDA_INPUT, 1, - HDA_AMP_MUTE, 0); - } -} - -static void alc663_two_hp_m7_speaker_automute(struct hda_codec *codec) -{ - unsigned int present1, present2; - - present1 = snd_hda_codec_read(codec, 0x1b, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; - present2 = snd_hda_codec_read(codec, 0x21, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; - - if (present1 || present2) { - snd_hda_codec_write_cache(codec, 0x14, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, 0); - snd_hda_codec_write_cache(codec, 0x17, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, 0); - } else { - snd_hda_codec_write_cache(codec, 0x14, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - snd_hda_codec_write_cache(codec, 0x17, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - } -} - -static void alc663_two_hp_m8_speaker_automute(struct hda_codec *codec) -{ - unsigned int present1, present2; - - present1 = snd_hda_codec_read(codec, 0x21, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; - present2 = snd_hda_codec_read(codec, 0x15, 0, - AC_VERB_GET_PIN_SENSE, 0) - & AC_PINSENSE_PRESENCE; - - if (present1 || present2) { - snd_hda_codec_write_cache(codec, 0x14, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, 0); - snd_hda_codec_write_cache(codec, 0x17, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, 0); - } else { - snd_hda_codec_write_cache(codec, 0x14, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - snd_hda_codec_write_cache(codec, 0x17, 0, - AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); - } -} - -static void alc663_m51va_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - switch (res >> 26) { - case ALC880_HP_EVENT: - alc663_m51va_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc663_m51va_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x21; + spec->autocfg.speaker_pins[0] = 0x14; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x12; @@ -18417,18 +18241,15 @@ static void alc663_m51va_setup(struct hda_codec *codec) spec->auto_mic = 1; } -static void alc663_m51va_inithook(struct hda_codec *codec) -{ - alc663_m51va_speaker_automute(codec); - alc_mic_automute(codec); -} - /* ***************** Mode1 ******************************/ -#define alc663_mode1_unsol_event alc663_m51va_unsol_event - static void alc663_mode1_setup(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x21; + spec->autocfg.speaker_pins[0] = 0x14; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x19; @@ -18436,229 +18257,144 @@ static void alc663_mode1_setup(struct hda_codec *codec) spec->auto_mic = 1; } -#define alc663_mode1_inithook alc663_m51va_inithook - /* ***************** Mode2 ******************************/ -static void alc662_mode2_unsol_event(struct hda_codec *codec, - unsigned int res) +static void alc662_mode2_setup(struct hda_codec *codec) { - switch (res >> 26) { - case ALC880_HP_EVENT: - alc662_f5z_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x1b; + spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x19; + spec->int_mic.mux_idx = 1; + spec->auto_mic = 1; } -#define alc662_mode2_setup alc663_mode1_setup - -static void alc662_mode2_inithook(struct hda_codec *codec) -{ - alc662_f5z_speaker_automute(codec); - alc_mic_automute(codec); -} /* ***************** Mode3 ******************************/ -static void alc663_mode3_unsol_event(struct hda_codec *codec, - unsigned int res) +static void alc663_mode3_setup(struct hda_codec *codec) { - switch (res >> 26) { - case ALC880_HP_EVENT: - alc663_two_hp_m1_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x21; + spec->autocfg.hp_pins[0] = 0x15; + spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x19; + spec->int_mic.mux_idx = 1; + spec->auto_mic = 1; } -#define alc663_mode3_setup alc663_mode1_setup - -static void alc663_mode3_inithook(struct hda_codec *codec) -{ - alc663_two_hp_m1_speaker_automute(codec); - alc_mic_automute(codec); -} /* ***************** Mode4 ******************************/ -static void alc663_mode4_unsol_event(struct hda_codec *codec, - unsigned int res) +static void alc663_mode4_setup(struct hda_codec *codec) { - switch (res >> 26) { - case ALC880_HP_EVENT: - alc663_21jd_two_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x21; + spec->autocfg.speaker_pins[0] = 0x14; + spec->autocfg.speaker_pins[1] = 0x16; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute_mixer_nid[1] = 0x0e; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x19; + spec->int_mic.mux_idx = 1; + spec->auto_mic = 1; } -#define alc663_mode4_setup alc663_mode1_setup - -static void alc663_mode4_inithook(struct hda_codec *codec) -{ - alc663_21jd_two_speaker_automute(codec); - alc_mic_automute(codec); -} /* ***************** Mode5 ******************************/ -static void alc663_mode5_unsol_event(struct hda_codec *codec, - unsigned int res) +static void alc663_mode5_setup(struct hda_codec *codec) { - switch (res >> 26) { - case ALC880_HP_EVENT: - alc663_15jd_two_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x15; + spec->autocfg.speaker_pins[0] = 0x14; + spec->autocfg.speaker_pins[1] = 0x16; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute_mixer_nid[1] = 0x0e; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x19; + spec->int_mic.mux_idx = 1; + spec->auto_mic = 1; } -#define alc663_mode5_setup alc663_mode1_setup - -static void alc663_mode5_inithook(struct hda_codec *codec) -{ - alc663_15jd_two_speaker_automute(codec); - alc_mic_automute(codec); -} /* ***************** Mode6 ******************************/ -static void alc663_mode6_unsol_event(struct hda_codec *codec, - unsigned int res) +static void alc663_mode6_setup(struct hda_codec *codec) { - switch (res >> 26) { - case ALC880_HP_EVENT: - alc663_two_hp_m2_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } -} - -#define alc663_mode6_setup alc663_mode1_setup - -static void alc663_mode6_inithook(struct hda_codec *codec) -{ - alc663_two_hp_m2_speaker_automute(codec); - alc_mic_automute(codec); + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x1b; + spec->autocfg.hp_pins[0] = 0x15; + spec->autocfg.speaker_pins[0] = 0x14; + spec->automute_mixer_nid[0] = 0x0c; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_MIXER; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x19; + spec->int_mic.mux_idx = 1; + spec->auto_mic = 1; } /* ***************** Mode7 ******************************/ -static void alc663_mode7_unsol_event(struct hda_codec *codec, - unsigned int res) +static void alc663_mode7_setup(struct hda_codec *codec) { - switch (res >> 26) { - case ALC880_HP_EVENT: - alc663_two_hp_m7_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } -} - -#define alc663_mode7_setup alc663_mode1_setup - -static void alc663_mode7_inithook(struct hda_codec *codec) -{ - alc663_two_hp_m7_speaker_automute(codec); - alc_mic_automute(codec); + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x1b; + spec->autocfg.hp_pins[0] = 0x21; + spec->autocfg.speaker_pins[0] = 0x14; + spec->autocfg.speaker_pins[0] = 0x17; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x19; + spec->int_mic.mux_idx = 1; + spec->auto_mic = 1; } /* ***************** Mode8 ******************************/ -static void alc663_mode8_unsol_event(struct hda_codec *codec, - unsigned int res) +static void alc663_mode8_setup(struct hda_codec *codec) { - switch (res >> 26) { - case ALC880_HP_EVENT: - alc663_two_hp_m8_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x21; + spec->autocfg.hp_pins[1] = 0x15; + spec->autocfg.speaker_pins[0] = 0x14; + spec->autocfg.speaker_pins[0] = 0x17; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_PIN; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x12; + spec->int_mic.mux_idx = 9; + spec->auto_mic = 1; } -#define alc663_mode8_setup alc663_m51va_setup - -static void alc663_mode8_inithook(struct hda_codec *codec) +static void alc663_g71v_setup(struct hda_codec *codec) { - alc663_two_hp_m8_speaker_automute(codec); - alc_mic_automute(codec); -} - -static void alc663_g71v_hp_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x21); - bits = present ? HDA_AMP_MUTE : 0; - snd_hda_codec_amp_stereo(codec, 0x15, HDA_OUTPUT, 0, - HDA_AMP_MUTE, bits); - snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, - HDA_AMP_MUTE, bits); -} - -static void alc663_g71v_front_automute(struct hda_codec *codec) -{ - unsigned int present; - unsigned char bits; - - present = snd_hda_jack_detect(codec, 0x15); - bits = present ? HDA_AMP_MUTE : 0; - snd_hda_codec_amp_stereo(codec, 0x14, HDA_OUTPUT, 0, - HDA_AMP_MUTE, bits); -} - -static void alc663_g71v_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - switch (res >> 26) { - case ALC880_HP_EVENT: - alc663_g71v_hp_automute(codec); - break; - case ALC880_FRONT_EVENT: - alc663_g71v_front_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } -} - -#define alc663_g71v_setup alc663_m51va_setup - -static void alc663_g71v_inithook(struct hda_codec *codec) -{ - alc663_g71v_front_automute(codec); - alc663_g71v_hp_automute(codec); - alc_mic_automute(codec); -} - -static void alc663_g50v_unsol_event(struct hda_codec *codec, - unsigned int res) -{ - switch (res >> 26) { - case ALC880_HP_EVENT: - alc663_m51va_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } + struct alc_spec *spec = codec->spec; + spec->autocfg.hp_pins[0] = 0x21; + spec->autocfg.line_out_pins[0] = 0x15; + spec->autocfg.speaker_pins[0] = 0x14; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; + spec->detect_line = 1; + spec->automute_lines = 1; + spec->ext_mic.pin = 0x18; + spec->ext_mic.mux_idx = 0; + spec->int_mic.pin = 0x12; + spec->int_mic.mux_idx = 9; + spec->auto_mic = 1; } #define alc663_g50v_setup alc663_m51va_setup -static void alc663_g50v_inithook(struct hda_codec *codec) -{ - alc663_m51va_speaker_automute(codec); - alc_mic_automute(codec); -} - -static struct snd_kcontrol_new alc662_ecs_mixer[] = { +static const struct snd_kcontrol_new alc662_ecs_mixer[] = { HDA_CODEC_VOLUME("Master Playback Volume", 0x02, 0x0, HDA_OUTPUT), ALC262_HIPPO_MASTER_SWITCH, @@ -18672,7 +18408,7 @@ static struct snd_kcontrol_new alc662_ecs_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new alc272_nc10_mixer[] = { +static const struct snd_kcontrol_new alc272_nc10_mixer[] = { /* Master Playback automatically created from Speaker and Headphone */ HDA_CODEC_VOLUME("Speaker Playback Volume", 0x02, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Speaker Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -18707,7 +18443,7 @@ static const char * const alc662_models[ALC662_MODEL_LAST] = { [ALC662_3ST_2ch_DIG] = "3stack-dig", [ALC662_3ST_6ch_DIG] = "3stack-6ch-dig", [ALC662_3ST_6ch] = "3stack-6ch", - [ALC662_5ST_DIG] = "6stack-dig", + [ALC662_5ST_DIG] = "5stack-dig", [ALC662_LENOVO_101E] = "lenovo-101e", [ALC662_ASUS_EEEPC_P701] = "eeepc-p701", [ALC662_ASUS_EEEPC_EP20] = "eeepc-ep20", @@ -18730,7 +18466,7 @@ static const char * const alc662_models[ALC662_MODEL_LAST] = { [ALC662_AUTO] = "auto", }; -static struct snd_pci_quirk alc662_cfg_tbl[] = { +static const struct snd_pci_quirk alc662_cfg_tbl[] = { SND_PCI_QUIRK(0x1019, 0x9087, "ECS", ALC662_ECS), SND_PCI_QUIRK(0x1028, 0x02d6, "DELL", ALC272_DELL), SND_PCI_QUIRK(0x1028, 0x02f4, "DELL ZM1", ALC272_DELL_ZM1), @@ -18812,10 +18548,10 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { {} }; -static struct alc_config_preset alc662_presets[] = { +static const struct alc_config_preset alc662_presets[] = { [ALC662_3ST_2ch_DIG] = { .mixers = { alc662_3ST_2ch_mixer }, - .init_verbs = { alc662_init_verbs }, + .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, @@ -18826,7 +18562,7 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC662_3ST_6ch_DIG] = { .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, - .init_verbs = { alc662_init_verbs }, + .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, @@ -18838,7 +18574,7 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC662_3ST_6ch] = { .mixers = { alc662_3ST_6ch_mixer, alc662_chmode_mixer }, - .init_verbs = { alc662_init_verbs }, + .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), @@ -18848,7 +18584,7 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC662_5ST_DIG] = { .mixers = { alc662_base_mixer, alc662_chmode_mixer }, - .init_verbs = { alc662_init_verbs }, + .init_verbs = { alc662_init_verbs, alc662_eapd_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, @@ -18859,104 +18595,120 @@ static struct alc_config_preset alc662_presets[] = { }, [ALC662_LENOVO_101E] = { .mixers = { alc662_lenovo_101e_mixer }, - .init_verbs = { alc662_init_verbs, alc662_sue_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc662_sue_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, .input_mux = &alc662_lenovo_101e_capture_source, - .unsol_event = alc662_lenovo_101e_unsol_event, - .init_hook = alc662_lenovo_101e_all_automute, + .unsol_event = alc_sku_unsol_event, + .setup = alc662_lenovo_101e_setup, + .init_hook = alc_inithook, }, [ALC662_ASUS_EEEPC_P701] = { .mixers = { alc662_eeepc_p701_mixer }, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc662_eeepc_sue_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc662_eeepc_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc662_eeepc_setup, - .init_hook = alc662_eeepc_inithook, + .init_hook = alc_inithook, }, [ALC662_ASUS_EEEPC_EP20] = { .mixers = { alc662_eeepc_ep20_mixer, alc662_chmode_mixer }, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc662_eeepc_ep20_sue_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), .channel_mode = alc662_3ST_6ch_modes, .input_mux = &alc662_lenovo_101e_capture_source, - .unsol_event = alc662_eeepc_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc662_eeepc_ep20_setup, - .init_hook = alc662_eeepc_ep20_inithook, + .init_hook = alc_inithook, }, [ALC662_ECS] = { .mixers = { alc662_ecs_mixer }, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc662_ecs_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc662_eeepc_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc662_eeepc_setup, - .init_hook = alc662_eeepc_inithook, + .init_hook = alc_inithook, }, [ALC663_ASUS_M51VA] = { .mixers = { alc663_m51va_mixer }, - .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc663_m51va_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_m51va_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_m51va_setup, - .init_hook = alc663_m51va_inithook, + .init_hook = alc_inithook, }, [ALC663_ASUS_G71V] = { .mixers = { alc663_g71v_mixer }, - .init_verbs = { alc662_init_verbs, alc663_g71v_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc663_g71v_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_g71v_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_g71v_setup, - .init_hook = alc663_g71v_inithook, + .init_hook = alc_inithook, }, [ALC663_ASUS_H13] = { .mixers = { alc663_m51va_mixer }, - .init_verbs = { alc662_init_verbs, alc663_m51va_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc663_m51va_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_m51va_unsol_event, - .init_hook = alc663_m51va_inithook, + .setup = alc663_m51va_setup, + .unsol_event = alc_sku_unsol_event, + .init_hook = alc_inithook, }, [ALC663_ASUS_G50V] = { .mixers = { alc663_g50v_mixer }, - .init_verbs = { alc662_init_verbs, alc663_g50v_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc663_g50v_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_6ch_modes), .channel_mode = alc662_3ST_6ch_modes, .input_mux = &alc663_capture_source, - .unsol_event = alc663_g50v_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_g50v_setup, - .init_hook = alc663_g50v_inithook, + .init_hook = alc_inithook, }, [ALC663_ASUS_MODE1] = { .mixers = { alc663_m51va_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_21jd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -18964,28 +18716,30 @@ static struct alc_config_preset alc662_presets[] = { .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_mode1_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_mode1_setup, - .init_hook = alc663_mode1_inithook, + .init_hook = alc_inithook, }, [ALC662_ASUS_MODE2] = { .mixers = { alc662_1bjd_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc662_1bjd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .dac_nids = alc662_dac_nids, .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc662_mode2_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc662_mode2_setup, - .init_hook = alc662_mode2_inithook, + .init_hook = alc_inithook, }, [ALC663_ASUS_MODE3] = { .mixers = { alc663_two_hp_m1_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_two_hp_amic_m1_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -18993,14 +18747,15 @@ static struct alc_config_preset alc662_presets[] = { .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_mode3_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_mode3_setup, - .init_hook = alc663_mode3_inithook, + .init_hook = alc_inithook, }, [ALC663_ASUS_MODE4] = { .mixers = { alc663_asus_21jd_clfe_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_21jd_amic_init_verbs}, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -19008,14 +18763,15 @@ static struct alc_config_preset alc662_presets[] = { .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_mode4_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_mode4_setup, - .init_hook = alc663_mode4_inithook, + .init_hook = alc_inithook, }, [ALC663_ASUS_MODE5] = { .mixers = { alc663_asus_15jd_clfe_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_15jd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -19023,14 +18779,15 @@ static struct alc_config_preset alc662_presets[] = { .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_mode5_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_mode5_setup, - .init_hook = alc663_mode5_inithook, + .init_hook = alc_inithook, }, [ALC663_ASUS_MODE6] = { .mixers = { alc663_two_hp_m2_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_two_hp_amic_m2_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -19038,14 +18795,15 @@ static struct alc_config_preset alc662_presets[] = { .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_mode6_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_mode6_setup, - .init_hook = alc663_mode6_inithook, + .init_hook = alc_inithook, }, [ALC663_ASUS_MODE7] = { .mixers = { alc663_mode7_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_mode7_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -19053,14 +18811,15 @@ static struct alc_config_preset alc662_presets[] = { .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_mode7_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_mode7_setup, - .init_hook = alc663_mode7_inithook, + .init_hook = alc_inithook, }, [ALC663_ASUS_MODE8] = { .mixers = { alc663_mode8_mixer }, .cap_mixer = alc662_auto_capture_mixer, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_mode8_init_verbs }, .num_dacs = ARRAY_SIZE(alc662_dac_nids), .hp_nid = 0x03, @@ -19068,52 +18827,57 @@ static struct alc_config_preset alc662_presets[] = { .dig_out_nid = ALC662_DIGOUT_NID, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_mode8_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_mode8_setup, - .init_hook = alc663_mode8_inithook, + .init_hook = alc_inithook, }, [ALC272_DELL] = { .mixers = { alc663_m51va_mixer }, .cap_mixer = alc272_auto_capture_mixer, - .init_verbs = { alc662_init_verbs, alc272_dell_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc272_dell_init_verbs }, .num_dacs = ARRAY_SIZE(alc272_dac_nids), - .dac_nids = alc662_dac_nids, + .dac_nids = alc272_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .adc_nids = alc272_adc_nids, .num_adc_nids = ARRAY_SIZE(alc272_adc_nids), .capsrc_nids = alc272_capsrc_nids, .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_m51va_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_m51va_setup, - .init_hook = alc663_m51va_inithook, + .init_hook = alc_inithook, }, [ALC272_DELL_ZM1] = { .mixers = { alc663_m51va_mixer }, .cap_mixer = alc662_auto_capture_mixer, - .init_verbs = { alc662_init_verbs, alc272_dell_zm1_init_verbs }, + .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, + alc272_dell_zm1_init_verbs }, .num_dacs = ARRAY_SIZE(alc272_dac_nids), - .dac_nids = alc662_dac_nids, + .dac_nids = alc272_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .adc_nids = alc662_adc_nids, .num_adc_nids = 1, .capsrc_nids = alc662_capsrc_nids, .channel_mode = alc662_3ST_2ch_modes, - .unsol_event = alc663_m51va_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_m51va_setup, - .init_hook = alc663_m51va_inithook, + .init_hook = alc_inithook, }, [ALC272_SAMSUNG_NC10] = { .mixers = { alc272_nc10_mixer }, .init_verbs = { alc662_init_verbs, + alc662_eapd_init_verbs, alc663_21jd_amic_init_verbs }, .num_dacs = ARRAY_SIZE(alc272_dac_nids), .dac_nids = alc272_dac_nids, .num_channel_mode = ARRAY_SIZE(alc662_3ST_2ch_modes), .channel_mode = alc662_3ST_2ch_modes, /*.input_mux = &alc272_nc10_capture_source,*/ - .unsol_event = alc663_mode4_unsol_event, + .unsol_event = alc_sku_unsol_event, .setup = alc663_mode4_setup, - .init_hook = alc663_mode4_inithook, + .init_hook = alc_inithook, }, }; @@ -19123,45 +18887,79 @@ static struct alc_config_preset alc662_presets[] = { */ /* convert from MIX nid to DAC */ -static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) +static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid) { - if (nid == 0x0f) - return 0x02; - else if (nid >= 0x0c && nid <= 0x0e) - return nid - 0x0c + 0x02; - else if (nid == 0x26) /* ALC887-VD has this DAC too */ - return 0x25; - else - return 0; + hda_nid_t list[5]; + int i, num; + + num = snd_hda_get_connections(codec, nid, list, ARRAY_SIZE(list)); + for (i = 0; i < num; i++) { + if (get_wcaps_type(get_wcaps(codec, list[i])) == AC_WID_AUD_OUT) + return list[i]; + } + return 0; +} + +/* go down to the selector widget before the mixer */ +static hda_nid_t alc_go_down_to_selector(struct hda_codec *codec, hda_nid_t pin) +{ + hda_nid_t srcs[5]; + int num = snd_hda_get_connections(codec, pin, srcs, + ARRAY_SIZE(srcs)); + if (num != 1 || + get_wcaps_type(get_wcaps(codec, srcs[0])) != AC_WID_AUD_SEL) + return pin; + return srcs[0]; } /* get MIX nid connected to the given pin targeted to DAC */ -static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, +static hda_nid_t alc_auto_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, hda_nid_t dac) { hda_nid_t mix[5]; int i, num; + pin = alc_go_down_to_selector(codec, pin); num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); for (i = 0; i < num; i++) { - if (alc662_mix_to_dac(mix[i]) == dac) + if (alc_auto_mix_to_dac(codec, mix[i]) == dac) return mix[i]; } return 0; } +/* select the connection from pin to DAC if needed */ +static int alc_auto_select_dac(struct hda_codec *codec, hda_nid_t pin, + hda_nid_t dac) +{ + hda_nid_t mix[5]; + int i, num; + + pin = alc_go_down_to_selector(codec, pin); + num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); + if (num < 2) + return 0; + for (i = 0; i < num; i++) { + if (alc_auto_mix_to_dac(codec, mix[i]) == dac) { + snd_hda_codec_update_cache(codec, pin, 0, + AC_VERB_SET_CONNECT_SEL, i); + return 0; + } + } + return 0; +} + /* look for an empty DAC slot */ -static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) +static hda_nid_t alc_auto_look_for_dac(struct hda_codec *codec, hda_nid_t pin) { struct alc_spec *spec = codec->spec; hda_nid_t srcs[5]; int i, j, num; + pin = alc_go_down_to_selector(codec, pin); num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); - if (num < 0) - return 0; for (i = 0; i < num; i++) { - hda_nid_t nid = alc662_mix_to_dac(srcs[i]); + hda_nid_t nid = alc_auto_mix_to_dac(codec, srcs[i]); if (!nid) continue; for (j = 0; j < spec->multiout.num_dacs; j++) @@ -19183,10 +18981,10 @@ static int alc662_auto_fill_dac_nids(struct hda_codec *codec, spec->multiout.dac_nids = spec->private_dac_nids; for (i = 0; i < cfg->line_outs; i++) { - dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); + dac = alc_auto_look_for_dac(codec, cfg->line_out_pins[i]); if (!dac) continue; - spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; + spec->private_dac_nids[spec->multiout.num_dacs++] = dac; } return 0; } @@ -19222,15 +19020,23 @@ static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, static const char * const chname[4] = { "Front", "Surround", NULL /*CLFE*/, "Side" }; - const char *pfx = alc_get_line_out_pfx(cfg, true); - hda_nid_t nid, mix; - int i, err; + const char *pfx = alc_get_line_out_pfx(spec, true); + hda_nid_t nid, mix, pin; + int i, err, noutputs; - for (i = 0; i < cfg->line_outs; i++) { + noutputs = cfg->line_outs; + if (spec->multi_ios > 0) + noutputs += spec->multi_ios; + + for (i = 0; i < noutputs; i++) { nid = spec->multiout.dac_nids[i]; if (!nid) continue; - mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); + if (i >= cfg->line_outs) + pin = spec->multi_io[i - 1].pin; + else + pin = cfg->line_out_pins[i]; + mix = alc_auto_dac_to_mix(codec, pin, nid); if (!mix) continue; if (!pfx && i == 2) { @@ -19276,7 +19082,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, if (!pin) return 0; - nid = alc662_look_for_dac(codec, pin); + nid = alc_auto_look_for_dac(codec, pin); if (!nid) { /* the corresponding DAC is already occupied */ if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) @@ -19286,7 +19092,7 @@ static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); } - mix = alc662_dac_to_mix(codec, pin, nid); + mix = alc_auto_dac_to_mix(codec, pin, nid); if (!mix) return 0; err = alc662_add_vol_ctl(spec, pfx, nid, 3); @@ -19310,14 +19116,21 @@ static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, hda_nid_t srcs[HDA_MAX_CONNECTIONS]; alc_set_pin_output(codec, nid, pin_type); - /* need the manual connection? */ num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); - if (num <= 1) - return; for (i = 0; i < num; i++) { - if (alc662_mix_to_dac(srcs[i]) != dac) + if (alc_auto_mix_to_dac(codec, srcs[i]) != dac) continue; - snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); + /* need the manual connection? */ + if (num > 1) + snd_hda_codec_write(codec, nid, 0, + AC_VERB_SET_CONNECT_SEL, i); + /* unmute mixer widget inputs */ + snd_hda_codec_write(codec, srcs[i], 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_UNMUTE(0)); + snd_hda_codec_write(codec, srcs[i], 0, + AC_VERB_SET_AMP_GAIN_MUTE, + AMP_IN_UNMUTE(1)); return; } } @@ -19374,11 +19187,164 @@ static void alc662_auto_init_analog_input(struct hda_codec *codec) #define alc662_auto_init_input_src alc882_auto_init_input_src +/* + * multi-io helper + */ +static int alc_auto_fill_multi_ios(struct hda_codec *codec, + unsigned int location) +{ + struct alc_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + int type, i, num_pins = 0; + + for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) { + for (i = 0; i < cfg->num_inputs; i++) { + hda_nid_t nid = cfg->inputs[i].pin; + hda_nid_t dac; + unsigned int defcfg, caps; + if (cfg->inputs[i].type != type) + continue; + defcfg = snd_hda_codec_get_pincfg(codec, nid); + if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX) + continue; + if (location && get_defcfg_location(defcfg) != location) + continue; + caps = snd_hda_query_pin_caps(codec, nid); + if (!(caps & AC_PINCAP_OUT)) + continue; + dac = alc_auto_look_for_dac(codec, nid); + if (!dac) + continue; + spec->multi_io[num_pins].pin = nid; + spec->multi_io[num_pins].dac = dac; + num_pins++; + spec->private_dac_nids[spec->multiout.num_dacs++] = dac; + } + } + spec->multiout.num_dacs = 1; + if (num_pins < 2) + return 0; + return num_pins; +} + +static int alc_auto_ch_mode_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = spec->multi_ios + 1; + if (uinfo->value.enumerated.item > spec->multi_ios) + uinfo->value.enumerated.item = spec->multi_ios; + sprintf(uinfo->value.enumerated.name, "%dch", + (uinfo->value.enumerated.item + 1) * 2); + return 0; +} + +static int alc_auto_ch_mode_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + ucontrol->value.enumerated.item[0] = (spec->ext_channel_count - 1) / 2; + return 0; +} + +static int alc_set_multi_io(struct hda_codec *codec, int idx, bool output) +{ + struct alc_spec *spec = codec->spec; + hda_nid_t nid = spec->multi_io[idx].pin; + + if (!spec->multi_io[idx].ctl_in) + spec->multi_io[idx].ctl_in = + snd_hda_codec_read(codec, nid, 0, + AC_VERB_GET_PIN_WIDGET_CONTROL, 0); + if (output) { + snd_hda_codec_update_cache(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + PIN_OUT); + if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) + snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, + HDA_AMP_MUTE, 0); + alc_auto_select_dac(codec, nid, spec->multi_io[idx].dac); + } else { + if (get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) + snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0, + HDA_AMP_MUTE, HDA_AMP_MUTE); + snd_hda_codec_update_cache(codec, nid, 0, + AC_VERB_SET_PIN_WIDGET_CONTROL, + spec->multi_io[idx].ctl_in); + } + return 0; +} + +static int alc_auto_ch_mode_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + struct hda_codec *codec = snd_kcontrol_chip(kcontrol); + struct alc_spec *spec = codec->spec; + int i, ch; + + ch = ucontrol->value.enumerated.item[0]; + if (ch < 0 || ch > spec->multi_ios) + return -EINVAL; + if (ch == (spec->ext_channel_count - 1) / 2) + return 0; + spec->ext_channel_count = (ch + 1) * 2; + for (i = 0; i < spec->multi_ios; i++) + alc_set_multi_io(codec, i, i < ch); + spec->multiout.max_channels = spec->ext_channel_count; + return 1; +} + +static const struct snd_kcontrol_new alc_auto_channel_mode_enum = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Channel Mode", + .info = alc_auto_ch_mode_info, + .get = alc_auto_ch_mode_get, + .put = alc_auto_ch_mode_put, +}; + +static int alc_auto_add_multi_channel_mode(struct hda_codec *codec) +{ + struct alc_spec *spec = codec->spec; + struct auto_pin_cfg *cfg = &spec->autocfg; + unsigned int location, defcfg; + int num_pins; + + if (cfg->line_outs != 1 || + cfg->line_out_type != AUTO_PIN_LINE_OUT) + return 0; + + defcfg = snd_hda_codec_get_pincfg(codec, cfg->line_out_pins[0]); + location = get_defcfg_location(defcfg); + + num_pins = alc_auto_fill_multi_ios(codec, location); + if (num_pins > 0) { + struct snd_kcontrol_new *knew; + + knew = alc_kcontrol_new(spec); + if (!knew) + return -ENOMEM; + *knew = alc_auto_channel_mode_enum; + knew->name = kstrdup("Channel Mode", GFP_KERNEL); + if (!knew->name) + return -ENOMEM; + + spec->multi_ios = num_pins; + spec->ext_channel_count = 2; + spec->multiout.num_dacs = num_pins + 1; + } + return 0; +} + static int alc662_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; - static hda_nid_t alc662_ignore[] = { 0x1d, 0 }; + static const hda_nid_t alc662_ignore[] = { 0x1d, 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc662_ignore); @@ -19388,6 +19354,9 @@ static int alc662_parse_auto_config(struct hda_codec *codec) return 0; /* can't find valid BIOS pin config */ err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); + if (err < 0) + return err; + err = alc_auto_add_multi_channel_mode(codec); if (err < 0) return err; err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); @@ -19420,14 +19389,6 @@ static int alc662_parse_auto_config(struct hda_codec *codec) spec->num_mux_defs = 1; spec->input_mux = &spec->private_imux[0]; - add_verb(spec, alc662_init_verbs); - if (codec->vendor_id == 0x10ec0272 || codec->vendor_id == 0x10ec0663 || - codec->vendor_id == 0x10ec0665 || codec->vendor_id == 0x10ec0670) - add_verb(spec, alc663_init_verbs); - - if (codec->vendor_id == 0x10ec0272) - add_verb(spec, alc272_init_verbs); - err = alc_auto_add_mic_boost(codec); if (err < 0) return err; @@ -19508,7 +19469,7 @@ static const struct alc_fixup alc662_fixups[] = { }, }; -static struct snd_pci_quirk alc662_fixup_tbl[] = { +static const struct snd_pci_quirk alc662_fixup_tbl[] = { SND_PCI_QUIRK(0x1025, 0x0308, "Acer Aspire 8942G", ALC662_FIXUP_ASPIRE), SND_PCI_QUIRK(0x1025, 0x031c, "Gateway NV79", ALC662_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x1025, 0x038b, "Acer Aspire 8943G", ALC662_FIXUP_ASPIRE), @@ -19626,6 +19587,7 @@ static int patch_alc662(struct hda_codec *codec) codec->patch_ops = alc_patch_ops; if (board_config == ALC662_AUTO) spec->init_hook = alc662_auto_init; + spec->shutup = alc_eapd_shutup; alc_init_jacks(codec); @@ -19654,6 +19616,15 @@ static int patch_alc888(struct hda_codec *codec) return patch_alc882(codec); } +static int patch_alc899(struct hda_codec *codec) +{ + if ((alc_read_coef_idx(codec, 0) & 0x2000) != 0x2000) { + kfree(codec->chip_name); + codec->chip_name = kstrdup("ALC898", GFP_KERNEL); + } + return patch_alc882(codec); +} + /* * ALC680 support */ @@ -19661,12 +19632,12 @@ static int patch_alc888(struct hda_codec *codec) #define ALC680_DIGOUT_NID ALC880_DIGOUT_NID #define alc680_modes alc260_modes -static hda_nid_t alc680_dac_nids[3] = { +static const hda_nid_t alc680_dac_nids[3] = { /* Lout1, Lout2, hp */ 0x02, 0x03, 0x04 }; -static hda_nid_t alc680_adc_nids[3] = { +static const hda_nid_t alc680_adc_nids[3] = { /* ADC0-2 */ /* DMIC, MIC, Line-in*/ 0x07, 0x08, 0x09 @@ -19686,8 +19657,7 @@ static void alc680_rec_autoswitch(struct hda_codec *codec) for (i = 0; i < cfg->num_inputs; i++) { nid = cfg->inputs[i].pin; - if (!(snd_hda_query_pin_caps(codec, nid) & - AC_PINCAP_PRES_DETECT)) + if (!is_jack_detectable(codec, nid)) continue; if (snd_hda_jack_detect(codec, nid)) { if (cfg->inputs[i].type < type_found) { @@ -19734,7 +19704,7 @@ static int alc680_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, return 0; } -static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { +static const struct hda_pcm_stream alc680_pcm_analog_auto_capture = { .substreams = 1, /* can be overridden */ .channels_min = 2, .channels_max = 2, @@ -19745,7 +19715,7 @@ static struct hda_pcm_stream alc680_pcm_analog_auto_capture = { }, }; -static struct snd_kcontrol_new alc680_base_mixer[] = { +static const struct snd_kcontrol_new alc680_base_mixer[] = { /* output mixer control */ HDA_CODEC_VOLUME("Front Playback Volume", 0x2, 0x0, HDA_OUTPUT), HDA_CODEC_MUTE("Front Playback Switch", 0x14, 0x0, HDA_OUTPUT), @@ -19757,7 +19727,7 @@ static struct snd_kcontrol_new alc680_base_mixer[] = { { } }; -static struct hda_bind_ctls alc680_bind_cap_vol = { +static const struct hda_bind_ctls alc680_bind_cap_vol = { .ops = &snd_hda_bind_vol, .values = { HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), @@ -19767,7 +19737,7 @@ static struct hda_bind_ctls alc680_bind_cap_vol = { }, }; -static struct hda_bind_ctls alc680_bind_cap_switch = { +static const struct hda_bind_ctls alc680_bind_cap_switch = { .ops = &snd_hda_bind_sw, .values = { HDA_COMPOSE_AMP_VAL(0x07, 3, 0, HDA_INPUT), @@ -19777,7 +19747,7 @@ static struct hda_bind_ctls alc680_bind_cap_switch = { }, }; -static struct snd_kcontrol_new alc680_master_capture_mixer[] = { +static const struct snd_kcontrol_new alc680_master_capture_mixer[] = { HDA_BIND_VOL("Capture Volume", &alc680_bind_cap_vol), HDA_BIND_SW("Capture Switch", &alc680_bind_cap_switch), { } /* end */ @@ -19786,7 +19756,7 @@ static struct snd_kcontrol_new alc680_master_capture_mixer[] = { /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb alc680_init_verbs[] = { +static const struct hda_verb alc680_init_verbs[] = { {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, @@ -19824,20 +19794,22 @@ static void alc680_base_setup(struct hda_codec *codec) spec->autocfg.inputs[0].type = AUTO_PIN_MIC; spec->autocfg.inputs[1].pin = 0x19; spec->autocfg.inputs[1].type = AUTO_PIN_LINE_IN; + spec->automute = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; } static void alc680_unsol_event(struct hda_codec *codec, unsigned int res) { if ((res >> 26) == ALC880_HP_EVENT) - alc_automute_amp(codec); + alc_hp_automute(codec); if ((res >> 26) == ALC880_MIC_EVENT) alc680_rec_autoswitch(codec); } static void alc680_inithook(struct hda_codec *codec) { - alc_automute_amp(codec); + alc_hp_automute(codec); alc680_rec_autoswitch(codec); } @@ -19874,7 +19846,7 @@ static int alc680_new_analog_output(struct alc_spec *spec, hda_nid_t nid, if (err < 0) return err; - spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; + spec->private_dac_nids[spec->multiout.num_dacs++] = dac; } return 0; @@ -19960,7 +19932,7 @@ static int alc680_parse_auto_config(struct hda_codec *codec) { struct alc_spec *spec = codec->spec; int err; - static hda_nid_t alc680_ignore[] = { 0 }; + static const hda_nid_t alc680_ignore[] = { 0 }; err = snd_hda_parse_pin_def_config(codec, &spec->autocfg, alc680_ignore); @@ -20018,12 +19990,12 @@ static const char * const alc680_models[ALC680_MODEL_LAST] = { [ALC680_AUTO] = "auto", }; -static struct snd_pci_quirk alc680_cfg_tbl[] = { +static const struct snd_pci_quirk alc680_cfg_tbl[] = { SND_PCI_QUIRK(0x1043, 0x12f3, "ASUS NX90", ALC680_BASE), {} }; -static struct alc_config_preset alc680_presets[] = { +static const struct alc_config_preset alc680_presets[] = { [ALC680_BASE] = { .mixers = { alc680_base_mixer }, .cap_mixer = alc680_master_capture_mixer, @@ -20104,7 +20076,8 @@ static int patch_alc680(struct hda_codec *codec) /* * patch entries */ -static struct hda_codec_preset snd_hda_preset_realtek[] = { +static const struct hda_codec_preset snd_hda_preset_realtek[] = { + { .id = 0x10ec0221, .name = "ALC221", .patch = patch_alc269 }, { .id = 0x10ec0260, .name = "ALC260", .patch = patch_alc260 }, { .id = 0x10ec0262, .name = "ALC262", .patch = patch_alc262 }, { .id = 0x10ec0267, .name = "ALC267", .patch = patch_alc268 }, @@ -20113,6 +20086,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0270, .name = "ALC270", .patch = patch_alc269 }, { .id = 0x10ec0272, .name = "ALC272", .patch = patch_alc662 }, { .id = 0x10ec0275, .name = "ALC275", .patch = patch_alc269 }, + { .id = 0x10ec0276, .name = "ALC276", .patch = patch_alc269 }, { .id = 0x10ec0861, .rev = 0x100340, .name = "ALC660", .patch = patch_alc861 }, { .id = 0x10ec0660, .name = "ALC660-VD", .patch = patch_alc861vd }, @@ -20140,6 +20114,7 @@ static struct hda_codec_preset snd_hda_preset_realtek[] = { { .id = 0x10ec0888, .name = "ALC888", .patch = patch_alc888 }, { .id = 0x10ec0889, .name = "ALC889", .patch = patch_alc882 }, { .id = 0x10ec0892, .name = "ALC892", .patch = patch_alc662 }, + { .id = 0x10ec0899, .name = "ALC899", .patch = patch_alc899 }, {} /* terminator */ }; 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, } -static struct snd_kcontrol_new si3054_modem_mixer[] = { +static const struct snd_kcontrol_new si3054_modem_mixer[] = { SI3054_KCONTROL("Off-hook Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_OH), SI3054_KCONTROL("Caller ID Switch", SI3054_GPIO_CONTROL, SI3054_GPIO_CID), {} @@ -181,7 +181,7 @@ static int si3054_pcm_open(struct hda_pcm_stream *hinfo, } -static struct hda_pcm_stream si3054_pcm = { +static const struct hda_pcm_stream si3054_pcm = { .substreams = 1, .channels_min = 1, .channels_max = 1, @@ -200,12 +200,13 @@ static int si3054_build_pcms(struct hda_codec *codec) { struct si3054_spec *spec = codec->spec; struct hda_pcm *info = &spec->pcm; - si3054_pcm.nid = codec->mfg; codec->num_pcms = 1; codec->pcm_info = info; info->name = "Si3054 Modem"; info->stream[SNDRV_PCM_STREAM_PLAYBACK] = si3054_pcm; info->stream[SNDRV_PCM_STREAM_CAPTURE] = si3054_pcm; + info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = codec->mfg; + info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = codec->mfg; info->pcm_type = HDA_PCM_TYPE_MODEM; return 0; } @@ -263,7 +264,7 @@ static void si3054_free(struct hda_codec *codec) /* */ -static struct hda_codec_ops si3054_patch_ops = { +static const struct hda_codec_ops si3054_patch_ops = { .build_controls = si3054_build_controls, .build_pcms = si3054_build_pcms, .init = si3054_init, @@ -283,7 +284,7 @@ static int patch_si3054(struct hda_codec *codec) /* * patch entries */ -static struct hda_codec_preset snd_hda_preset_si3054[] = { +static const struct hda_codec_preset snd_hda_preset_si3054[] = { { .id = 0x163c3055, .name = "Si3054", .patch = patch_si3054 }, { .id = 0x163c3155, .name = "Si3054", .patch = patch_si3054 }, { .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 { unsigned int stream_delay; /* analog loopback */ - struct snd_kcontrol_new *aloopback_ctl; + const struct snd_kcontrol_new *aloopback_ctl; unsigned char aloopback_mask; unsigned char aloopback_shift; /* power management */ unsigned int num_pwrs; - unsigned int *pwr_mapping; - hda_nid_t *pwr_nids; - hda_nid_t *dac_list; + const unsigned int *pwr_mapping; + const hda_nid_t *pwr_nids; + const hda_nid_t *dac_list; /* events */ struct snd_array events; @@ -241,20 +241,20 @@ struct sigmatel_spec { int volume_offset; /* capture */ - hda_nid_t *adc_nids; + const hda_nid_t *adc_nids; unsigned int num_adcs; - hda_nid_t *mux_nids; + const hda_nid_t *mux_nids; unsigned int num_muxes; - hda_nid_t *dmic_nids; + const hda_nid_t *dmic_nids; unsigned int num_dmics; - hda_nid_t *dmux_nids; + const hda_nid_t *dmux_nids; unsigned int num_dmuxes; - hda_nid_t *smux_nids; + const hda_nid_t *smux_nids; unsigned int num_smuxes; unsigned int num_analog_muxes; - unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ - unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */ + const unsigned long *capvols; /* amp-volume attr: HDA_COMPOSE_AMP_VAL() */ + const unsigned long *capsws; /* amp-mute attr: HDA_COMPOSE_AMP_VAL() */ unsigned int num_caps; /* number of capture volume/switch elements */ struct sigmatel_mic_route ext_mic; @@ -269,12 +269,12 @@ struct sigmatel_spec { hda_nid_t digbeep_nid; /* pin widgets */ - hda_nid_t *pin_nids; + const hda_nid_t *pin_nids; unsigned int num_pins; /* codec specific stuff */ - struct hda_verb *init; - struct snd_kcontrol_new *mixer; + const struct hda_verb *init; + const struct snd_kcontrol_new *mixer; /* capture source */ struct hda_input_mux *dinput_mux; @@ -317,52 +317,52 @@ struct sigmatel_spec { hda_nid_t auto_dmic_nids[MAX_DMICS_NUM]; }; -static hda_nid_t stac9200_adc_nids[1] = { +static const hda_nid_t stac9200_adc_nids[1] = { 0x03, }; -static hda_nid_t stac9200_mux_nids[1] = { +static const hda_nid_t stac9200_mux_nids[1] = { 0x0c, }; -static hda_nid_t stac9200_dac_nids[1] = { +static const hda_nid_t stac9200_dac_nids[1] = { 0x02, }; -static hda_nid_t stac92hd73xx_pwr_nids[8] = { +static const hda_nid_t stac92hd73xx_pwr_nids[8] = { 0x0a, 0x0b, 0x0c, 0xd, 0x0e, 0x0f, 0x10, 0x11 }; -static hda_nid_t stac92hd73xx_slave_dig_outs[2] = { +static const hda_nid_t stac92hd73xx_slave_dig_outs[2] = { 0x26, 0, }; -static hda_nid_t stac92hd73xx_adc_nids[2] = { +static const hda_nid_t stac92hd73xx_adc_nids[2] = { 0x1a, 0x1b }; #define STAC92HD73XX_NUM_DMICS 2 -static hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { +static const hda_nid_t stac92hd73xx_dmic_nids[STAC92HD73XX_NUM_DMICS + 1] = { 0x13, 0x14, 0 }; #define STAC92HD73_DAC_COUNT 5 -static hda_nid_t stac92hd73xx_mux_nids[2] = { +static const hda_nid_t stac92hd73xx_mux_nids[2] = { 0x20, 0x21, }; -static hda_nid_t stac92hd73xx_dmux_nids[2] = { +static const hda_nid_t stac92hd73xx_dmux_nids[2] = { 0x20, 0x21, }; -static hda_nid_t stac92hd73xx_smux_nids[2] = { +static const hda_nid_t stac92hd73xx_smux_nids[2] = { 0x22, 0x23, }; #define STAC92HD73XX_NUM_CAPS 2 -static unsigned long stac92hd73xx_capvols[] = { +static const unsigned long stac92hd73xx_capvols[] = { HDA_COMPOSE_AMP_VAL(0x20, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), }; @@ -370,137 +370,141 @@ static unsigned long stac92hd73xx_capvols[] = { #define STAC92HD83_DAC_COUNT 3 -static hda_nid_t stac92hd83xxx_pwr_nids[4] = { +static const hda_nid_t stac92hd83xxx_pwr_nids[4] = { 0xa, 0xb, 0xd, 0xe, }; -static hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { +static const hda_nid_t stac92hd83xxx_slave_dig_outs[2] = { 0x1e, 0, }; -static unsigned int stac92hd83xxx_pwr_mapping[4] = { +static const unsigned int stac92hd83xxx_pwr_mapping[4] = { 0x03, 0x0c, 0x20, 0x40, }; -static hda_nid_t stac92hd83xxx_dmic_nids[] = { +static const hda_nid_t stac92hd83xxx_dmic_nids[] = { 0x11, 0x20, }; -static hda_nid_t stac92hd71bxx_pwr_nids[3] = { +static const hda_nid_t stac92hd71bxx_pwr_nids[3] = { 0x0a, 0x0d, 0x0f }; -static hda_nid_t stac92hd71bxx_adc_nids[2] = { +static const hda_nid_t stac92hd71bxx_adc_nids[2] = { 0x12, 0x13, }; -static hda_nid_t stac92hd71bxx_mux_nids[2] = { +static const hda_nid_t stac92hd71bxx_mux_nids[2] = { 0x1a, 0x1b }; -static hda_nid_t stac92hd71bxx_dmux_nids[2] = { +static const hda_nid_t stac92hd71bxx_dmux_nids[2] = { 0x1c, 0x1d, }; -static hda_nid_t stac92hd71bxx_smux_nids[2] = { +static const hda_nid_t stac92hd71bxx_smux_nids[2] = { 0x24, 0x25, }; #define STAC92HD71BXX_NUM_DMICS 2 -static hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { +static const hda_nid_t stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS + 1] = { 0x18, 0x19, 0 }; -static hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { +static const hda_nid_t stac92hd71bxx_dmic_5port_nids[STAC92HD71BXX_NUM_DMICS] = { + 0x18, 0 +}; + +static const hda_nid_t stac92hd71bxx_slave_dig_outs[2] = { 0x22, 0 }; #define STAC92HD71BXX_NUM_CAPS 2 -static unsigned long stac92hd71bxx_capvols[] = { +static const unsigned long stac92hd71bxx_capvols[] = { HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), }; #define stac92hd71bxx_capsws stac92hd71bxx_capvols -static hda_nid_t stac925x_adc_nids[1] = { +static const hda_nid_t stac925x_adc_nids[1] = { 0x03, }; -static hda_nid_t stac925x_mux_nids[1] = { +static const hda_nid_t stac925x_mux_nids[1] = { 0x0f, }; -static hda_nid_t stac925x_dac_nids[1] = { +static const hda_nid_t stac925x_dac_nids[1] = { 0x02, }; #define STAC925X_NUM_DMICS 1 -static hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = { +static const hda_nid_t stac925x_dmic_nids[STAC925X_NUM_DMICS + 1] = { 0x15, 0 }; -static hda_nid_t stac925x_dmux_nids[1] = { +static const hda_nid_t stac925x_dmux_nids[1] = { 0x14, }; -static unsigned long stac925x_capvols[] = { +static const unsigned long stac925x_capvols[] = { HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_OUTPUT), }; -static unsigned long stac925x_capsws[] = { +static const unsigned long stac925x_capsws[] = { HDA_COMPOSE_AMP_VAL(0x14, 3, 0, HDA_OUTPUT), }; -static hda_nid_t stac922x_adc_nids[2] = { +static const hda_nid_t stac922x_adc_nids[2] = { 0x06, 0x07, }; -static hda_nid_t stac922x_mux_nids[2] = { +static const hda_nid_t stac922x_mux_nids[2] = { 0x12, 0x13, }; #define STAC922X_NUM_CAPS 2 -static unsigned long stac922x_capvols[] = { +static const unsigned long stac922x_capvols[] = { HDA_COMPOSE_AMP_VAL(0x17, 3, 0, HDA_INPUT), HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), }; #define stac922x_capsws stac922x_capvols -static hda_nid_t stac927x_slave_dig_outs[2] = { +static const hda_nid_t stac927x_slave_dig_outs[2] = { 0x1f, 0, }; -static hda_nid_t stac927x_adc_nids[3] = { +static const hda_nid_t stac927x_adc_nids[3] = { 0x07, 0x08, 0x09 }; -static hda_nid_t stac927x_mux_nids[3] = { +static const hda_nid_t stac927x_mux_nids[3] = { 0x15, 0x16, 0x17 }; -static hda_nid_t stac927x_smux_nids[1] = { +static const hda_nid_t stac927x_smux_nids[1] = { 0x21, }; -static hda_nid_t stac927x_dac_nids[6] = { +static const hda_nid_t stac927x_dac_nids[6] = { 0x02, 0x03, 0x04, 0x05, 0x06, 0 }; -static hda_nid_t stac927x_dmux_nids[1] = { +static const hda_nid_t stac927x_dmux_nids[1] = { 0x1b, }; #define STAC927X_NUM_DMICS 2 -static hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { +static const hda_nid_t stac927x_dmic_nids[STAC927X_NUM_DMICS + 1] = { 0x13, 0x14, 0 }; #define STAC927X_NUM_CAPS 3 -static unsigned long stac927x_capvols[] = { +static const unsigned long stac927x_capvols[] = { HDA_COMPOSE_AMP_VAL(0x18, 3, 0, HDA_INPUT), HDA_COMPOSE_AMP_VAL(0x19, 3, 0, HDA_INPUT), HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_INPUT), }; -static unsigned long stac927x_capsws[] = { +static const unsigned long stac927x_capsws[] = { HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), @@ -511,77 +515,77 @@ static const char * const stac927x_spdif_labels[5] = { "Analog Mux 2", "Analog Mux 3" }; -static hda_nid_t stac9205_adc_nids[2] = { +static const hda_nid_t stac9205_adc_nids[2] = { 0x12, 0x13 }; -static hda_nid_t stac9205_mux_nids[2] = { +static const hda_nid_t stac9205_mux_nids[2] = { 0x19, 0x1a }; -static hda_nid_t stac9205_dmux_nids[1] = { +static const hda_nid_t stac9205_dmux_nids[1] = { 0x1d, }; -static hda_nid_t stac9205_smux_nids[1] = { +static const hda_nid_t stac9205_smux_nids[1] = { 0x21, }; #define STAC9205_NUM_DMICS 2 -static hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { +static const hda_nid_t stac9205_dmic_nids[STAC9205_NUM_DMICS + 1] = { 0x17, 0x18, 0 }; #define STAC9205_NUM_CAPS 2 -static unsigned long stac9205_capvols[] = { +static const unsigned long stac9205_capvols[] = { HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_INPUT), HDA_COMPOSE_AMP_VAL(0x1c, 3, 0, HDA_INPUT), }; -static unsigned long stac9205_capsws[] = { +static const unsigned long stac9205_capsws[] = { HDA_COMPOSE_AMP_VAL(0x1d, 3, 0, HDA_OUTPUT), HDA_COMPOSE_AMP_VAL(0x1e, 3, 0, HDA_OUTPUT), }; -static hda_nid_t stac9200_pin_nids[8] = { +static const hda_nid_t stac9200_pin_nids[8] = { 0x08, 0x09, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, }; -static hda_nid_t stac925x_pin_nids[8] = { +static const hda_nid_t stac925x_pin_nids[8] = { 0x07, 0x08, 0x0a, 0x0b, 0x0c, 0x0d, 0x10, 0x11, }; -static hda_nid_t stac922x_pin_nids[10] = { +static const hda_nid_t stac922x_pin_nids[10] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x15, 0x1b, }; -static hda_nid_t stac92hd73xx_pin_nids[13] = { +static const hda_nid_t stac92hd73xx_pin_nids[13] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x22, 0x23 }; #define STAC92HD71BXX_NUM_PINS 13 -static hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { +static const hda_nid_t stac92hd71bxx_pin_nids_4port[STAC92HD71BXX_NUM_PINS] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x00, 0x00, 0x14, 0x18, 0x19, 0x1e, 0x1f, 0x20, 0x27 }; -static hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { +static const hda_nid_t stac92hd71bxx_pin_nids_6port[STAC92HD71BXX_NUM_PINS] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x14, 0x18, 0x19, 0x1e, 0x1f, 0x20, 0x27 }; -static hda_nid_t stac927x_pin_nids[14] = { +static const hda_nid_t stac927x_pin_nids[14] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x14, 0x21, 0x22, 0x23, }; -static hda_nid_t stac9205_pin_nids[12] = { +static const hda_nid_t stac9205_pin_nids[12] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x14, 0x16, 0x17, 0x18, 0x21, 0x22, @@ -841,45 +845,45 @@ static int stac92xx_aloopback_put(struct snd_kcontrol *kcontrol, return 1; } -static struct hda_verb stac9200_core_init[] = { +static const struct hda_verb stac9200_core_init[] = { /* set dac0mux for dac converter */ { 0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, {} }; -static struct hda_verb stac9200_eapd_init[] = { +static const struct hda_verb stac9200_eapd_init[] = { /* set dac0mux for dac converter */ {0x07, AC_VERB_SET_CONNECT_SEL, 0x00}, {0x08, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, {} }; -static struct hda_verb dell_eq_core_init[] = { +static const struct hda_verb dell_eq_core_init[] = { /* set master volume to max value without distortion * and direct control */ { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xec}, {} }; -static struct hda_verb stac92hd73xx_core_init[] = { +static const struct hda_verb stac92hd73xx_core_init[] = { /* set master volume and direct control */ { 0x1f, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, {} }; -static struct hda_verb stac92hd83xxx_core_init[] = { +static const struct hda_verb stac92hd83xxx_core_init[] = { /* power state controls amps */ { 0x01, AC_VERB_SET_EAPD, 1 << 2}, {} }; -static struct hda_verb stac92hd71bxx_core_init[] = { +static const struct hda_verb stac92hd71bxx_core_init[] = { /* set master volume and direct control */ { 0x28, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, {} }; -static struct hda_verb stac92hd71bxx_unmute_core_init[] = { +static const struct hda_verb stac92hd71bxx_unmute_core_init[] = { /* unmute right and left channels for nodes 0x0f, 0xa, 0x0d */ { 0x0f, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, { 0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -887,7 +891,7 @@ static struct hda_verb stac92hd71bxx_unmute_core_init[] = { {} }; -static struct hda_verb stac925x_core_init[] = { +static const struct hda_verb stac925x_core_init[] = { /* set dac0mux for dac converter */ { 0x06, AC_VERB_SET_CONNECT_SEL, 0x00}, /* mute the master volume */ @@ -895,13 +899,13 @@ static struct hda_verb stac925x_core_init[] = { {} }; -static struct hda_verb stac922x_core_init[] = { +static const struct hda_verb stac922x_core_init[] = { /* set master volume and direct control */ { 0x16, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, {} }; -static struct hda_verb d965_core_init[] = { +static const struct hda_verb d965_core_init[] = { /* set master volume and direct control */ { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, /* unmute node 0x1b */ @@ -911,7 +915,7 @@ static struct hda_verb d965_core_init[] = { {} }; -static struct hda_verb dell_3st_core_init[] = { +static const struct hda_verb dell_3st_core_init[] = { /* don't set delta bit */ {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, /* unmute node 0x1b */ @@ -921,7 +925,7 @@ static struct hda_verb dell_3st_core_init[] = { {} }; -static struct hda_verb stac927x_core_init[] = { +static const struct hda_verb stac927x_core_init[] = { /* set master volume and direct control */ { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, /* enable analog pc beep path */ @@ -929,7 +933,7 @@ static struct hda_verb stac927x_core_init[] = { {} }; -static struct hda_verb stac927x_volknob_core_init[] = { +static const struct hda_verb stac927x_volknob_core_init[] = { /* don't set delta bit */ {0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0x7f}, /* enable analog pc beep path */ @@ -937,7 +941,7 @@ static struct hda_verb stac927x_volknob_core_init[] = { {} }; -static struct hda_verb stac9205_core_init[] = { +static const struct hda_verb stac9205_core_init[] = { /* set master volume and direct control */ { 0x24, AC_VERB_SET_VOLUME_KNOB_CONTROL, 0xff}, /* enable analog pc beep path */ @@ -977,7 +981,7 @@ static struct hda_verb stac9205_core_init[] = { .private_value = nid, \ } -static struct snd_kcontrol_new stac9200_mixer[] = { +static const struct snd_kcontrol_new stac9200_mixer[] = { HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xb, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0xb, 0, HDA_OUTPUT), HDA_CODEC_VOLUME("Capture Volume", 0x0a, 0, HDA_OUTPUT), @@ -985,38 +989,38 @@ static struct snd_kcontrol_new stac9200_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { +static const struct snd_kcontrol_new stac92hd73xx_6ch_loopback[] = { STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 3), {} }; -static struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = { +static const struct snd_kcontrol_new stac92hd73xx_8ch_loopback[] = { STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 4), {} }; -static struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { +static const struct snd_kcontrol_new stac92hd73xx_10ch_loopback[] = { STAC_ANALOG_LOOPBACK(0xFA0, 0x7A1, 5), {} }; -static struct snd_kcontrol_new stac92hd71bxx_loopback[] = { +static const struct snd_kcontrol_new stac92hd71bxx_loopback[] = { STAC_ANALOG_LOOPBACK(0xFA0, 0x7A0, 2) }; -static struct snd_kcontrol_new stac925x_mixer[] = { +static const struct snd_kcontrol_new stac925x_mixer[] = { HDA_CODEC_VOLUME_MIN_MUTE("Master Playback Volume", 0xe, 0, HDA_OUTPUT), HDA_CODEC_MUTE("Master Playback Switch", 0x0e, 0, HDA_OUTPUT), { } /* end */ }; -static struct snd_kcontrol_new stac9205_loopback[] = { +static const struct snd_kcontrol_new stac9205_loopback[] = { STAC_ANALOG_LOOPBACK(0xFE0, 0x7E0, 1), {} }; -static struct snd_kcontrol_new stac927x_loopback[] = { +static const struct snd_kcontrol_new stac927x_loopback[] = { STAC_ANALOG_LOOPBACK(0xFEB, 0x7EB, 1), {} }; @@ -1182,16 +1186,16 @@ static int stac92xx_build_controls(struct hda_codec *codec) return 0; } -static unsigned int ref9200_pin_configs[8] = { +static const unsigned int ref9200_pin_configs[8] = { 0x01c47010, 0x01447010, 0x0221401f, 0x01114010, 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; -static unsigned int gateway9200_m4_pin_configs[8] = { +static const unsigned int gateway9200_m4_pin_configs[8] = { 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, }; -static unsigned int gateway9200_m4_2_pin_configs[8] = { +static const unsigned int gateway9200_m4_2_pin_configs[8] = { 0x400000fe, 0x404500f4, 0x400100f0, 0x90110010, 0x400100f1, 0x02a1902e, 0x500000f2, 0x500000f3, }; @@ -1202,7 +1206,7 @@ static unsigned int gateway9200_m4_2_pin_configs[8] = { 102801DE 102801E8 */ -static unsigned int dell9200_d21_pin_configs[8] = { +static const unsigned int dell9200_d21_pin_configs[8] = { 0x400001f0, 0x400001f1, 0x02214030, 0x01014010, 0x02a19020, 0x01a19021, 0x90100140, 0x01813122, }; @@ -1212,7 +1216,7 @@ static unsigned int dell9200_d21_pin_configs[8] = { 102801C0 102801C1 */ -static unsigned int dell9200_d22_pin_configs[8] = { +static const unsigned int dell9200_d22_pin_configs[8] = { 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 0x01813020, 0x02a19021, 0x90100140, 0x400001f2, }; @@ -1226,7 +1230,7 @@ static unsigned int dell9200_d22_pin_configs[8] = { 102801DA 102801E3 */ -static unsigned int dell9200_d23_pin_configs[8] = { +static const unsigned int dell9200_d23_pin_configs[8] = { 0x400001f0, 0x400001f1, 0x0221401f, 0x01014010, 0x01813020, 0x01a19021, 0x90100140, 0x400001f2, }; @@ -1237,7 +1241,7 @@ static unsigned int dell9200_d23_pin_configs[8] = { 102801B5 (Dell Inspiron 630m) 102801D8 (Dell Inspiron 640m) */ -static unsigned int dell9200_m21_pin_configs[8] = { +static const unsigned int dell9200_m21_pin_configs[8] = { 0x40c003fa, 0x03441340, 0x0321121f, 0x90170310, 0x408003fb, 0x03a11020, 0x401003fc, 0x403003fd, }; @@ -1250,7 +1254,7 @@ static unsigned int dell9200_m21_pin_configs[8] = { 102801D4 102801D6 */ -static unsigned int dell9200_m22_pin_configs[8] = { +static const unsigned int dell9200_m22_pin_configs[8] = { 0x40c003fa, 0x0144131f, 0x0321121f, 0x90170310, 0x90a70321, 0x03a11020, 0x401003fb, 0x40f000fc, }; @@ -1260,7 +1264,7 @@ static unsigned int dell9200_m22_pin_configs[8] = { 102801CE (Dell XPS M1710) 102801CF (Dell Precision M90) */ -static unsigned int dell9200_m23_pin_configs[8] = { +static const unsigned int dell9200_m23_pin_configs[8] = { 0x40c003fa, 0x01441340, 0x0421421f, 0x90170310, 0x408003fb, 0x04a1102e, 0x90170311, 0x403003fc, }; @@ -1272,7 +1276,7 @@ static unsigned int dell9200_m23_pin_configs[8] = { 102801CB (Dell Latitude 120L) 102801D3 */ -static unsigned int dell9200_m24_pin_configs[8] = { +static const unsigned int dell9200_m24_pin_configs[8] = { 0x40c003fa, 0x404003fb, 0x0321121f, 0x90170310, 0x408003fc, 0x03a11020, 0x401003fd, 0x403003fe, }; @@ -1283,7 +1287,7 @@ static unsigned int dell9200_m24_pin_configs[8] = { 102801EE 102801EF */ -static unsigned int dell9200_m25_pin_configs[8] = { +static const unsigned int dell9200_m25_pin_configs[8] = { 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, 0x408003fb, 0x04a11020, 0x401003fc, 0x403003fd, }; @@ -1293,7 +1297,7 @@ static unsigned int dell9200_m25_pin_configs[8] = { 102801F5 (Dell Inspiron 1501) 102801F6 */ -static unsigned int dell9200_m26_pin_configs[8] = { +static const unsigned int dell9200_m26_pin_configs[8] = { 0x40c003fa, 0x404003fb, 0x0421121f, 0x90170310, 0x408003fc, 0x04a11020, 0x401003fd, 0x403003fe, }; @@ -1302,18 +1306,18 @@ static unsigned int dell9200_m26_pin_configs[8] = { STAC 9200-32 102801CD (Dell Inspiron E1705/9400) */ -static unsigned int dell9200_m27_pin_configs[8] = { +static const unsigned int dell9200_m27_pin_configs[8] = { 0x40c003fa, 0x01441340, 0x0421121f, 0x90170310, 0x90170310, 0x04a11020, 0x90170310, 0x40f003fc, }; -static unsigned int oqo9200_pin_configs[8] = { +static const unsigned int oqo9200_pin_configs[8] = { 0x40c000f0, 0x404000f1, 0x0221121f, 0x02211210, 0x90170111, 0x90a70120, 0x400000f2, 0x400000f3, }; -static unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { +static const unsigned int *stac9200_brd_tbl[STAC_9200_MODELS] = { [STAC_REF] = ref9200_pin_configs, [STAC_9200_OQO] = oqo9200_pin_configs, [STAC_9200_DELL_D21] = dell9200_d21_pin_configs, @@ -1350,7 +1354,7 @@ static const char * const stac9200_models[STAC_9200_MODELS] = { [STAC_9200_PANASONIC] = "panasonic", }; -static struct snd_pci_quirk stac9200_cfg_tbl[] = { +static const struct snd_pci_quirk stac9200_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), @@ -1426,47 +1430,47 @@ static struct snd_pci_quirk stac9200_cfg_tbl[] = { {} /* terminator */ }; -static unsigned int ref925x_pin_configs[8] = { +static const unsigned int ref925x_pin_configs[8] = { 0x40c003f0, 0x424503f2, 0x01813022, 0x02a19021, 0x90a70320, 0x02214210, 0x01019020, 0x9033032e, }; -static unsigned int stac925xM1_pin_configs[8] = { +static const unsigned int stac925xM1_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; -static unsigned int stac925xM1_2_pin_configs[8] = { +static const unsigned int stac925xM1_2_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; -static unsigned int stac925xM2_pin_configs[8] = { +static const unsigned int stac925xM2_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; -static unsigned int stac925xM2_2_pin_configs[8] = { +static const unsigned int stac925xM2_2_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; -static unsigned int stac925xM3_pin_configs[8] = { +static const unsigned int stac925xM3_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x503303f3, }; -static unsigned int stac925xM5_pin_configs[8] = { +static const unsigned int stac925xM5_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x9033032e, }; -static unsigned int stac925xM6_pin_configs[8] = { +static const unsigned int stac925xM6_pin_configs[8] = { 0x40c003f4, 0x424503f2, 0x400000f3, 0x02a19020, 0x40a000f0, 0x90100210, 0x400003f1, 0x90330320, }; -static unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { +static const unsigned int *stac925x_brd_tbl[STAC_925x_MODELS] = { [STAC_REF] = ref925x_pin_configs, [STAC_M1] = stac925xM1_pin_configs, [STAC_M1_2] = stac925xM1_2_pin_configs, @@ -1489,7 +1493,7 @@ static const char * const stac925x_models[STAC_925x_MODELS] = { [STAC_M6] = "m6", }; -static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { +static const struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { SND_PCI_QUIRK(0x107b, 0x0316, "Gateway M255", STAC_M2), SND_PCI_QUIRK(0x107b, 0x0366, "Gateway MP6954", STAC_M5), SND_PCI_QUIRK(0x107b, 0x0461, "Gateway NX560XL", STAC_M1), @@ -1503,7 +1507,7 @@ static struct snd_pci_quirk stac925x_codec_id_cfg_tbl[] = { {} /* terminator */ }; -static struct snd_pci_quirk stac925x_cfg_tbl[] = { +static const struct snd_pci_quirk stac925x_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_REF), SND_PCI_QUIRK(PCI_VENDOR_ID_DFI, 0x3101, "DFI LanParty", STAC_REF), @@ -1515,33 +1519,33 @@ static struct snd_pci_quirk stac925x_cfg_tbl[] = { {} /* terminator */ }; -static unsigned int ref92hd73xx_pin_configs[13] = { +static const unsigned int ref92hd73xx_pin_configs[13] = { 0x02214030, 0x02a19040, 0x01a19020, 0x02214030, 0x0181302e, 0x01014010, 0x01014020, 0x01014030, 0x02319040, 0x90a000f0, 0x90a000f0, 0x01452050, 0x01452050, }; -static unsigned int dell_m6_pin_configs[13] = { +static const unsigned int dell_m6_pin_configs[13] = { 0x0321101f, 0x4f00000f, 0x4f0000f0, 0x90170110, 0x03a11020, 0x0321101f, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, }; -static unsigned int alienware_m17x_pin_configs[13] = { +static const unsigned int alienware_m17x_pin_configs[13] = { 0x0321101f, 0x0321101f, 0x03a11020, 0x03014020, 0x90170110, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, 0x4f0000f0, 0x90a60160, 0x4f0000f0, 0x4f0000f0, 0x904601b0, }; -static unsigned int intel_dg45id_pin_configs[13] = { +static const unsigned int intel_dg45id_pin_configs[13] = { 0x02214230, 0x02A19240, 0x01013214, 0x01014210, 0x01A19250, 0x01011212, 0x01016211 }; -static unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { +static const unsigned int *stac92hd73xx_brd_tbl[STAC_92HD73XX_MODELS] = { [STAC_92HD73XX_REF] = ref92hd73xx_pin_configs, [STAC_DELL_M6_AMIC] = dell_m6_pin_configs, [STAC_DELL_M6_DMIC] = dell_m6_pin_configs, @@ -1563,7 +1567,7 @@ static const char * const stac92hd73xx_models[STAC_92HD73XX_MODELS] = { [STAC_ALIENWARE_M17X] = "alienware", }; -static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { +static const struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD73XX_REF), @@ -1600,11 +1604,11 @@ static struct snd_pci_quirk stac92hd73xx_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02fe, "Dell Studio XPS 1645", STAC_DELL_M6_BOTH), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x0413, - "Dell Studio 1558", STAC_DELL_M6_BOTH), + "Dell Studio 1558", STAC_DELL_M6_DMIC), {} /* terminator */ }; -static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { +static const struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x02a1, "Alienware M17x", STAC_ALIENWARE_M17X), SND_PCI_QUIRK(PCI_VENDOR_ID_DELL, 0x043a, @@ -1612,25 +1616,25 @@ static struct snd_pci_quirk stac92hd73xx_codec_id_cfg_tbl[] = { {} /* terminator */ }; -static unsigned int ref92hd83xxx_pin_configs[10] = { +static const unsigned int ref92hd83xxx_pin_configs[10] = { 0x02214030, 0x02211010, 0x02a19020, 0x02170130, 0x01014050, 0x01819040, 0x01014020, 0x90a3014e, 0x01451160, 0x98560170, }; -static unsigned int dell_s14_pin_configs[10] = { +static const unsigned int dell_s14_pin_configs[10] = { 0x0221403f, 0x0221101f, 0x02a19020, 0x90170110, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a60160, 0x40f000f0, 0x40f000f0, }; -static unsigned int hp_dv7_4000_pin_configs[10] = { +static const unsigned int hp_dv7_4000_pin_configs[10] = { 0x03a12050, 0x0321201f, 0x40f000f0, 0x90170110, 0x40f000f0, 0x40f000f0, 0x90170110, 0xd5a30140, 0x40f000f0, 0x40f000f0, }; -static unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { +static const unsigned int *stac92hd83xxx_brd_tbl[STAC_92HD83XXX_MODELS] = { [STAC_92HD83XXX_REF] = ref92hd83xxx_pin_configs, [STAC_92HD83XXX_PWR_REF] = ref92hd83xxx_pin_configs, [STAC_DELL_S14] = dell_s14_pin_configs, @@ -1646,7 +1650,7 @@ static const char * const stac92hd83xxx_models[STAC_92HD83XXX_MODELS] = { [STAC_HP_DV7_4000] = "hp-dv7-4000", }; -static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { +static const struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD83XXX_REF), @@ -1659,35 +1663,35 @@ static struct snd_pci_quirk stac92hd83xxx_cfg_tbl[] = { {} /* terminator */ }; -static unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { +static const unsigned int ref92hd71bxx_pin_configs[STAC92HD71BXX_NUM_PINS] = { 0x02214030, 0x02a19040, 0x01a19020, 0x01014010, 0x0181302e, 0x01014010, 0x01019020, 0x90a000f0, 0x90a000f0, 0x01452050, 0x01452050, 0x00000000, 0x00000000 }; -static unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { +static const unsigned int dell_m4_1_pin_configs[STAC92HD71BXX_NUM_PINS] = { 0x0421101f, 0x04a11221, 0x40f000f0, 0x90170110, 0x23a1902e, 0x23014250, 0x40f000f0, 0x90a000f0, 0x40f000f0, 0x4f0000f0, 0x4f0000f0, 0x00000000, 0x00000000 }; -static unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { +static const unsigned int dell_m4_2_pin_configs[STAC92HD71BXX_NUM_PINS] = { 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 0x23a1902e, 0x23014250, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, 0x00000000 }; -static unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { +static const unsigned int dell_m4_3_pin_configs[STAC92HD71BXX_NUM_PINS] = { 0x0421101f, 0x04a11221, 0x90a70330, 0x90170110, 0x40f000f0, 0x40f000f0, 0x40f000f0, 0x90a000f0, 0x40f000f0, 0x044413b0, 0x044413b0, 0x00000000, 0x00000000 }; -static unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { +static const unsigned int *stac92hd71bxx_brd_tbl[STAC_92HD71BXX_MODELS] = { [STAC_92HD71BXX_REF] = ref92hd71bxx_pin_configs, [STAC_DELL_M4_1] = dell_m4_1_pin_configs, [STAC_DELL_M4_2] = dell_m4_2_pin_configs, @@ -1712,7 +1716,7 @@ static const char * const stac92hd71bxx_models[STAC_92HD71BXX_MODELS] = { [STAC_HP_DV4_1222NR] = "hp-dv4-1222nr", }; -static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { +static const struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_92HD71BXX_REF), @@ -1769,7 +1773,7 @@ static struct snd_pci_quirk stac92hd71bxx_cfg_tbl[] = { {} /* terminator */ }; -static unsigned int ref922x_pin_configs[10] = { +static const unsigned int ref922x_pin_configs[10] = { 0x01014010, 0x01016011, 0x01012012, 0x0221401f, 0x01813122, 0x01011014, 0x01441030, 0x01c41030, 0x40000100, 0x40000100, @@ -1783,7 +1787,7 @@ static unsigned int ref922x_pin_configs[10] = { 102801D1 102801D2 */ -static unsigned int dell_922x_d81_pin_configs[10] = { +static const unsigned int dell_922x_d81_pin_configs[10] = { 0x02214030, 0x01a19021, 0x01111012, 0x01114010, 0x02a19020, 0x01117011, 0x400001f0, 0x400001f1, 0x01813122, 0x400001f2, @@ -1794,7 +1798,7 @@ static unsigned int dell_922x_d81_pin_configs[10] = { 102801AC 102801D0 */ -static unsigned int dell_922x_d82_pin_configs[10] = { +static const unsigned int dell_922x_d82_pin_configs[10] = { 0x02214030, 0x01a19021, 0x01111012, 0x01114010, 0x02a19020, 0x01117011, 0x01451140, 0x400001f0, 0x01813122, 0x400001f1, @@ -1804,7 +1808,7 @@ static unsigned int dell_922x_d82_pin_configs[10] = { STAC 922X pin configs for 102801BF */ -static unsigned int dell_922x_m81_pin_configs[10] = { +static const unsigned int dell_922x_m81_pin_configs[10] = { 0x0321101f, 0x01112024, 0x01111222, 0x91174220, 0x03a11050, 0x01116221, 0x90a70330, 0x01452340, 0x40C003f1, 0x405003f0, @@ -1814,61 +1818,61 @@ static unsigned int dell_922x_m81_pin_configs[10] = { STAC 9221 A1 pin configs for 102801D7 (Dell XPS M1210) */ -static unsigned int dell_922x_m82_pin_configs[10] = { +static const unsigned int dell_922x_m82_pin_configs[10] = { 0x02211211, 0x408103ff, 0x02a1123e, 0x90100310, 0x408003f1, 0x0221121f, 0x03451340, 0x40c003f2, 0x508003f3, 0x405003f4, }; -static unsigned int d945gtp3_pin_configs[10] = { +static const unsigned int d945gtp3_pin_configs[10] = { 0x0221401f, 0x01a19022, 0x01813021, 0x01014010, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x02a19120, 0x40000100, }; -static unsigned int d945gtp5_pin_configs[10] = { +static const unsigned int d945gtp5_pin_configs[10] = { 0x0221401f, 0x01011012, 0x01813024, 0x01014010, 0x01a19021, 0x01016011, 0x01452130, 0x40000100, 0x02a19320, 0x40000100, }; -static unsigned int intel_mac_v1_pin_configs[10] = { +static const unsigned int intel_mac_v1_pin_configs[10] = { 0x0121e21f, 0x400000ff, 0x9017e110, 0x400000fd, 0x400000fe, 0x0181e020, 0x1145e030, 0x11c5e240, 0x400000fc, 0x400000fb, }; -static unsigned int intel_mac_v2_pin_configs[10] = { +static const unsigned int intel_mac_v2_pin_configs[10] = { 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, 0x400000fe, 0x0181e020, 0x1145e230, 0x500000fa, 0x400000fc, 0x400000fb, }; -static unsigned int intel_mac_v3_pin_configs[10] = { +static const unsigned int intel_mac_v3_pin_configs[10] = { 0x0121e21f, 0x90a7012e, 0x9017e110, 0x400000fd, 0x400000fe, 0x0181e020, 0x1145e230, 0x11c5e240, 0x400000fc, 0x400000fb, }; -static unsigned int intel_mac_v4_pin_configs[10] = { +static const unsigned int intel_mac_v4_pin_configs[10] = { 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, 0x400000fc, 0x400000fb, }; -static unsigned int intel_mac_v5_pin_configs[10] = { +static const unsigned int intel_mac_v5_pin_configs[10] = { 0x0321e21f, 0x03a1e02e, 0x9017e110, 0x9017e11f, 0x400000fe, 0x0381e020, 0x1345e230, 0x13c5e240, 0x400000fc, 0x400000fb, }; -static unsigned int ecs202_pin_configs[10] = { +static const unsigned int ecs202_pin_configs[10] = { 0x0221401f, 0x02a19020, 0x01a19020, 0x01114010, 0x408000f0, 0x01813022, 0x074510a0, 0x40c400f1, 0x9037012e, 0x40e000f2, }; -static unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { +static const unsigned int *stac922x_brd_tbl[STAC_922X_MODELS] = { [STAC_D945_REF] = ref922x_pin_configs, [STAC_D945GTP3] = d945gtp3_pin_configs, [STAC_D945GTP5] = d945gtp5_pin_configs, @@ -1917,7 +1921,7 @@ static const char * const stac922x_models[STAC_922X_MODELS] = { [STAC_922X_DELL_M82] = "dell-m82", }; -static struct snd_pci_quirk stac922x_cfg_tbl[] = { +static const struct snd_pci_quirk stac922x_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_D945_REF), @@ -2008,42 +2012,42 @@ static struct snd_pci_quirk stac922x_cfg_tbl[] = { {} /* terminator */ }; -static unsigned int ref927x_pin_configs[14] = { +static const unsigned int ref927x_pin_configs[14] = { 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, 0x01a19040, 0x01011012, 0x01016011, 0x0101201f, 0x183301f0, 0x18a001f0, 0x18a001f0, 0x01442070, 0x01c42190, 0x40000100, }; -static unsigned int d965_3st_pin_configs[14] = { +static const unsigned int d965_3st_pin_configs[14] = { 0x0221401f, 0x02a19120, 0x40000100, 0x01014011, 0x01a19021, 0x01813024, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x40000100 }; -static unsigned int d965_5st_pin_configs[14] = { +static const unsigned int d965_5st_pin_configs[14] = { 0x02214020, 0x02a19080, 0x0181304e, 0x01014010, 0x01a19040, 0x01011012, 0x01016011, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x01442070, 0x40000100, 0x40000100 }; -static unsigned int d965_5st_no_fp_pin_configs[14] = { +static const unsigned int d965_5st_no_fp_pin_configs[14] = { 0x40000100, 0x40000100, 0x0181304e, 0x01014010, 0x01a19040, 0x01011012, 0x01016011, 0x40000100, 0x40000100, 0x40000100, 0x40000100, 0x01442070, 0x40000100, 0x40000100 }; -static unsigned int dell_3st_pin_configs[14] = { +static const unsigned int dell_3st_pin_configs[14] = { 0x02211230, 0x02a11220, 0x01a19040, 0x01114210, 0x01111212, 0x01116211, 0x01813050, 0x01112214, 0x403003fa, 0x90a60040, 0x90a60040, 0x404003fb, 0x40c003fc, 0x40000100 }; -static unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { +static const unsigned int *stac927x_brd_tbl[STAC_927X_MODELS] = { [STAC_D965_REF_NO_JD] = ref927x_pin_configs, [STAC_D965_REF] = ref927x_pin_configs, [STAC_D965_3ST] = d965_3st_pin_configs, @@ -2066,7 +2070,7 @@ static const char * const stac927x_models[STAC_927X_MODELS] = { [STAC_927X_VOLKNOB] = "volknob", }; -static struct snd_pci_quirk stac927x_cfg_tbl[] = { +static const struct snd_pci_quirk stac927x_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_D965_REF), @@ -2104,7 +2108,7 @@ static struct snd_pci_quirk stac927x_cfg_tbl[] = { {} /* terminator */ }; -static unsigned int ref9205_pin_configs[12] = { +static const unsigned int ref9205_pin_configs[12] = { 0x40000100, 0x40000100, 0x01016011, 0x01014010, 0x01813122, 0x01a19021, 0x01019020, 0x40000100, 0x90a000f0, 0x90a000f0, 0x01441030, 0x01c41030 @@ -2121,7 +2125,7 @@ static unsigned int ref9205_pin_configs[12] = { 10280228 (Dell Vostro 1500) 10280229 (Dell Vostro 1700) */ -static unsigned int dell_9205_m42_pin_configs[12] = { +static const unsigned int dell_9205_m42_pin_configs[12] = { 0x0321101F, 0x03A11020, 0x400003FA, 0x90170310, 0x400003FB, 0x400003FC, 0x400003FD, 0x40F000F9, 0x90A60330, 0x400003FF, 0x0144131F, 0x40C003FE, @@ -2137,19 +2141,19 @@ static unsigned int dell_9205_m42_pin_configs[12] = { 10280200 10280201 */ -static unsigned int dell_9205_m43_pin_configs[12] = { +static const unsigned int dell_9205_m43_pin_configs[12] = { 0x0321101f, 0x03a11020, 0x90a70330, 0x90170310, 0x400000fe, 0x400000ff, 0x400000fd, 0x40f000f9, 0x400000fa, 0x400000fc, 0x0144131f, 0x40c003f8, }; -static unsigned int dell_9205_m44_pin_configs[12] = { +static const unsigned int dell_9205_m44_pin_configs[12] = { 0x0421101f, 0x04a11020, 0x400003fa, 0x90170310, 0x400003fb, 0x400003fc, 0x400003fd, 0x400003f9, 0x90a60330, 0x400003ff, 0x01441340, 0x40c003fe, }; -static unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { +static const unsigned int *stac9205_brd_tbl[STAC_9205_MODELS] = { [STAC_9205_REF] = ref9205_pin_configs, [STAC_9205_DELL_M42] = dell_9205_m42_pin_configs, [STAC_9205_DELL_M43] = dell_9205_m43_pin_configs, @@ -2166,7 +2170,7 @@ static const char * const stac9205_models[STAC_9205_MODELS] = { [STAC_9205_EAPD] = "eapd", }; -static struct snd_pci_quirk stac9205_cfg_tbl[] = { +static const struct snd_pci_quirk stac9205_cfg_tbl[] = { /* SigmaTel reference board */ SND_PCI_QUIRK(PCI_VENDOR_ID_INTEL, 0x2668, "DFI LanParty", STAC_9205_REF), @@ -2214,7 +2218,7 @@ static struct snd_pci_quirk stac9205_cfg_tbl[] = { }; static void stac92xx_set_config_regs(struct hda_codec *codec, - unsigned int *pincfgs) + const unsigned int *pincfgs) { int i; struct sigmatel_spec *spec = codec->spec; @@ -2334,7 +2338,7 @@ static int stac92xx_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, return 0; } -static struct hda_pcm_stream stac92xx_pcm_digital_playback = { +static const struct hda_pcm_stream stac92xx_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -2347,14 +2351,14 @@ static struct hda_pcm_stream stac92xx_pcm_digital_playback = { }, }; -static struct hda_pcm_stream stac92xx_pcm_digital_capture = { +static const struct hda_pcm_stream stac92xx_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, /* NID is set in stac92xx_build_pcms */ }; -static struct hda_pcm_stream stac92xx_pcm_analog_playback = { +static const struct hda_pcm_stream stac92xx_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 8, @@ -2366,7 +2370,7 @@ static struct hda_pcm_stream stac92xx_pcm_analog_playback = { }, }; -static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { +static const struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -2378,7 +2382,7 @@ static struct hda_pcm_stream stac92xx_pcm_analog_alt_playback = { }, }; -static struct hda_pcm_stream stac92xx_pcm_analog_capture = { +static const struct hda_pcm_stream stac92xx_pcm_analog_capture = { .channels_min = 2, .channels_max = 2, /* NID + .substreams is set in stac92xx_build_pcms */ @@ -2487,7 +2491,7 @@ static int stac92xx_dc_bias_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { int i; - static char *texts[] = { + static const char * const texts[] = { "Mic In", "Line In", "Line Out" }; @@ -2556,7 +2560,7 @@ static int stac92xx_dc_bias_put(struct snd_kcontrol *kcontrol, static int stac92xx_io_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) { - static char *texts[2]; + char *texts[2]; struct hda_codec *codec = snd_kcontrol_chip(kcontrol); struct sigmatel_spec *spec = codec->spec; @@ -2687,7 +2691,7 @@ enum { STAC_CTL_WIDGET_DC_BIAS }; -static struct snd_kcontrol_new stac92xx_control_templates[] = { +static const struct snd_kcontrol_new stac92xx_control_templates[] = { HDA_CODEC_VOLUME(NULL, 0, 0, 0), HDA_CODEC_MUTE(NULL, 0, 0, 0), HDA_CODEC_MUTE_BEEP(NULL, 0, 0, 0), @@ -2701,7 +2705,7 @@ static struct snd_kcontrol_new stac92xx_control_templates[] = { /* add dynamic controls */ static struct snd_kcontrol_new * stac_control_new(struct sigmatel_spec *spec, - struct snd_kcontrol_new *ktemp, + const struct snd_kcontrol_new *ktemp, const char *name, unsigned int subdev) { @@ -2724,7 +2728,7 @@ stac_control_new(struct sigmatel_spec *spec, } static int stac92xx_add_control_temp(struct sigmatel_spec *spec, - struct snd_kcontrol_new *ktemp, + const struct snd_kcontrol_new *ktemp, int idx, const char *name, unsigned long val) { @@ -2754,7 +2758,7 @@ static inline int stac92xx_add_control(struct sigmatel_spec *spec, int type, return stac92xx_add_control_idx(spec, type, 0, name, val); } -static struct snd_kcontrol_new stac_input_src_temp = { +static const struct snd_kcontrol_new stac_input_src_temp = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Input Source", .info = stac92xx_mux_enum_info, @@ -3072,7 +3076,8 @@ static int add_spec_dacs(struct sigmatel_spec *spec, hda_nid_t nid) printk(KERN_WARNING "stac92xx: No space for DAC 0x%x\n", nid); return 1; } else { - spec->multiout.dac_nids[spec->multiout.num_dacs] = nid; + snd_BUG_ON(spec->multiout.dac_nids != spec->dac_nids); + spec->dac_nids[spec->multiout.num_dacs] = nid; spec->multiout.num_dacs++; } return 0; @@ -3109,8 +3114,7 @@ static int create_multi_out_ctls(struct hda_codec *codec, int num_outs, for (i = 0; i < num_outs && i < ARRAY_SIZE(chname); i++) { if (type == AUTO_PIN_HP_OUT && !spec->hp_detect) { - wid_caps = get_wcaps(codec, pins[i]); - if (wid_caps & AC_WCAP_UNSOL_CAP) + if (is_jack_detectable(codec, pins[i])) spec->hp_detect = 1; } nid = dac_nids[i]; @@ -3309,7 +3313,7 @@ static int stac92xx_dig_beep_switch_put(struct snd_kcontrol *kcontrol, return snd_hda_enable_beep_device(codec, ucontrol->value.integer.value[0]); } -static struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { +static const struct snd_kcontrol_new stac92xx_dig_beep_ctrl = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .info = stac92xx_dig_beep_switch_info, .get = stac92xx_dig_beep_switch_get, @@ -3516,14 +3520,18 @@ static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, hda_nid_t *fixed, hda_nid_t *ext, hda_nid_t *dock) { unsigned int cfg; + unsigned int type; if (!nid) return 0; cfg = snd_hda_codec_get_pincfg(codec, nid); + type = get_defcfg_device(cfg); switch (snd_hda_get_input_pin_attr(cfg)) { case INPUT_PIN_ATTR_INT: if (*fixed) return 1; /* already occupied */ + if (type != AC_JACK_MIC_IN) + return 1; /* invalid type */ *fixed = nid; break; case INPUT_PIN_ATTR_UNUSED: @@ -3531,11 +3539,15 @@ static int check_mic_pin(struct hda_codec *codec, hda_nid_t nid, case INPUT_PIN_ATTR_DOCK: if (*dock) return 1; /* already occupied */ + if (type != AC_JACK_MIC_IN && type != AC_JACK_LINE_IN) + return 1; /* invalid type */ *dock = nid; break; default: if (*ext) return 1; /* already occupied */ + if (type != AC_JACK_MIC_IN) + return 1; /* invalid type */ *ext = nid; break; } @@ -3591,10 +3603,6 @@ static int stac_check_auto_mic(struct hda_codec *codec) hda_nid_t fixed, ext, dock; int i; - for (i = 0; i < cfg->num_inputs; i++) { - if (cfg->inputs[i].type >= AUTO_PIN_LINE_IN) - return 0; /* must be exclusively mics */ - } fixed = ext = dock = 0; for (i = 0; i < cfg->num_inputs; i++) if (check_mic_pin(codec, cfg->inputs[i].pin, @@ -3606,7 +3614,7 @@ static int stac_check_auto_mic(struct hda_codec *codec) return 0; if (!fixed || (!ext && !dock)) return 0; /* no input to switch */ - if (!(get_wcaps(codec, ext) & AC_WCAP_UNSOL_CAP)) + if (!is_jack_detectable(codec, ext)) return 0; /* no unsol support */ if (set_mic_route(codec, &spec->ext_mic, ext) || set_mic_route(codec, &spec->int_mic, fixed) || @@ -3921,13 +3929,11 @@ static int stac9200_auto_create_hp_ctls(struct hda_codec *codec, { struct sigmatel_spec *spec = codec->spec; hda_nid_t pin = cfg->hp_pins[0]; - unsigned int wid_caps; if (! pin) return 0; - wid_caps = get_wcaps(codec, pin); - if (wid_caps & AC_WCAP_UNSOL_CAP) + if (is_jack_detectable(codec, pin)) spec->hp_detect = 1; return 0; @@ -4138,7 +4144,7 @@ static int enable_pin_detect(struct hda_codec *codec, hda_nid_t nid, struct sigmatel_event *event; int tag; - if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) + if (!is_jack_detectable(codec, nid)) return 0; event = stac_get_event(codec, nid); if (event) { @@ -4171,7 +4177,7 @@ static void stac92xx_power_down(struct hda_codec *codec) struct sigmatel_spec *spec = codec->spec; /* power down inactive DACs */ - hda_nid_t *dac; + const hda_nid_t *dac; for (dac = spec->dac_list; *dac; dac++) if (!check_all_dac_nids(spec, *dac)) snd_hda_codec_write(codec, *dac, 0, @@ -4644,7 +4650,7 @@ static unsigned int stac_get_defcfg_connect(struct hda_codec *codec, int idx) } static int stac92xx_connected_ports(struct hda_codec *codec, - hda_nid_t *nids, int num_nids) + const hda_nid_t *nids, int num_nids) { struct sigmatel_spec *spec = codec->spec; int idx, num; @@ -4968,7 +4974,7 @@ static int stac92xx_suspend(struct hda_codec *codec, pm_message_t state) } #endif -static struct hda_codec_ops stac92xx_patch_ops = { +static const struct hda_codec_ops stac92xx_patch_ops = { .build_controls = stac92xx_build_controls, .build_pcms = stac92xx_build_pcms, .init = stac92xx_init, @@ -5588,7 +5594,7 @@ static int stac_hp_bass_gpio_put(struct snd_kcontrol *kcontrol, return 1; } -static struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { +static const struct snd_kcontrol_new stac_hp_bass_sw_ctrl = { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .info = stac_hp_bass_gpio_info, .get = stac_hp_bass_gpio_get, @@ -5612,7 +5618,7 @@ static int stac_add_hp_bass_switch(struct hda_codec *codec) static int patch_stac92hd71bxx(struct hda_codec *codec) { struct sigmatel_spec *spec; - struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; + const struct hda_verb *unmute_init = stac92hd71bxx_unmute_core_init; unsigned int pin_cfg; int err = 0; @@ -5705,9 +5711,9 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) unmute_init++; snd_hda_codec_set_pincfg(codec, 0x0f, 0x40f000f0); snd_hda_codec_set_pincfg(codec, 0x19, 0x40f000f3); - stac92hd71bxx_dmic_nids[STAC92HD71BXX_NUM_DMICS - 1] = 0; + spec->dmic_nids = stac92hd71bxx_dmic_5port_nids; spec->num_dmics = stac92xx_connected_ports(codec, - stac92hd71bxx_dmic_nids, + stac92hd71bxx_dmic_5port_nids, STAC92HD71BXX_NUM_DMICS - 1); break; case 0x111d7603: /* 6 Port with Analog Mixer */ @@ -5729,15 +5735,6 @@ static int patch_stac92hd71bxx(struct hda_codec *codec) if (get_wcaps(codec, 0xa) & AC_WCAP_IN_AMP) snd_hda_sequence_write_cache(codec, unmute_init); - /* Some HP machines seem to have unstable codec communications - * especially with ATI fglrx driver. For recovering from the - * CORB/RIRB stall, allow the BUS reset and keep always sync - */ - if (spec->board_config == STAC_HP_DV5) { - codec->bus->sync_write = 1; - codec->bus->allow_bus_reset = 1; - } - spec->aloopback_ctl = stac92hd71bxx_loopback; spec->aloopback_mask = 0x50; spec->aloopback_shift = 0; @@ -6223,31 +6220,31 @@ static int patch_stac9205(struct hda_codec *codec) * STAC9872 hack */ -static struct hda_verb stac9872_core_init[] = { +static const struct hda_verb stac9872_core_init[] = { {0x15, AC_VERB_SET_CONNECT_SEL, 0x1}, /* mic-sel: 0a,0d,14,02 */ {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, /* Mic-in -> 0x9 */ {} }; -static hda_nid_t stac9872_pin_nids[] = { +static const hda_nid_t stac9872_pin_nids[] = { 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x11, 0x13, 0x14, }; -static hda_nid_t stac9872_adc_nids[] = { +static const hda_nid_t stac9872_adc_nids[] = { 0x8 /*,0x6*/ }; -static hda_nid_t stac9872_mux_nids[] = { +static const hda_nid_t stac9872_mux_nids[] = { 0x15 }; -static unsigned long stac9872_capvols[] = { +static const unsigned long stac9872_capvols[] = { HDA_COMPOSE_AMP_VAL(0x09, 3, 0, HDA_INPUT), }; #define stac9872_capsws stac9872_capvols -static unsigned int stac9872_vaio_pin_configs[9] = { +static const unsigned int stac9872_vaio_pin_configs[9] = { 0x03211020, 0x411111f0, 0x411111f0, 0x03a15030, 0x411111f0, 0x90170110, 0x411111f0, 0x411111f0, 0x90a7013e @@ -6258,11 +6255,11 @@ static const char * const stac9872_models[STAC_9872_MODELS] = { [STAC_9872_VAIO] = "vaio", }; -static unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { +static const unsigned int *stac9872_brd_tbl[STAC_9872_MODELS] = { [STAC_9872_VAIO] = stac9872_vaio_pin_configs, }; -static struct snd_pci_quirk stac9872_cfg_tbl[] = { +static const struct snd_pci_quirk stac9872_cfg_tbl[] = { SND_PCI_QUIRK_MASK(0x104d, 0xfff0, 0x81e0, "Sony VAIO F/S", STAC_9872_VAIO), {} /* terminator */ @@ -6316,7 +6313,7 @@ static int patch_stac9872(struct hda_codec *codec) /* * patch entries */ -static struct hda_codec_preset snd_hda_preset_sigmatel[] = { +static const struct hda_codec_preset snd_hda_preset_sigmatel[] = { { .id = 0x83847690, .name = "STAC9200", .patch = patch_stac9200 }, { .id = 0x83847882, .name = "STAC9220 A1", .patch = patch_stac922x }, { .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 0997031c48d2..605c99e1e520 100644 --- a/sound/pci/hda/patch_via.c +++ b/sound/pci/hda/patch_via.c @@ -98,24 +98,30 @@ enum VIA_HDA_CODEC { VT1716S, VT2002P, VT1812, + VT1802, CODEC_TYPES, }; +#define VT2002P_COMPATIBLE(spec) \ + ((spec)->codec_type == VT2002P ||\ + (spec)->codec_type == VT1812 ||\ + (spec)->codec_type == VT1802) + struct via_spec { /* codec parameterization */ - struct snd_kcontrol_new *mixers[6]; + const struct snd_kcontrol_new *mixers[6]; unsigned int num_mixers; - struct hda_verb *init_verbs[5]; + const struct hda_verb *init_verbs[5]; unsigned int num_iverbs; char *stream_name_analog; - struct hda_pcm_stream *stream_analog_playback; - struct hda_pcm_stream *stream_analog_capture; + const struct hda_pcm_stream *stream_analog_playback; + const struct hda_pcm_stream *stream_analog_capture; char *stream_name_digital; - struct hda_pcm_stream *stream_digital_playback; - struct hda_pcm_stream *stream_digital_capture; + const struct hda_pcm_stream *stream_digital_playback; + const struct hda_pcm_stream *stream_digital_capture; /* playback */ struct hda_multi_out multiout; @@ -123,7 +129,7 @@ struct via_spec { /* capture */ unsigned int num_adc_nids; - hda_nid_t *adc_nids; + const hda_nid_t *adc_nids; hda_nid_t mux_nids[3]; hda_nid_t dig_in_nid; hda_nid_t dig_in_pin; @@ -154,6 +160,9 @@ struct via_spec { struct delayed_work vt1708_hp_work; int vt1708_jack_detectect; int vt1708_hp_present; + + void (*set_widgets_power_state)(struct hda_codec *codec); + #ifdef CONFIG_SND_HDA_POWER_SAVE struct hda_loopback_check loopback; #endif @@ -218,17 +227,19 @@ static enum VIA_HDA_CODEC get_codec_type(struct hda_codec *codec) codec_type = VT1812; else if (dev_id == 0x0440) codec_type = VT1708S; + else if ((dev_id & 0xfff) == 0x446) + codec_type = VT1802; else codec_type = UNKNOWN; return codec_type; }; +#define VIA_JACK_EVENT 0x20 #define VIA_HP_EVENT 0x01 #define VIA_GPIO_EVENT 0x02 -#define VIA_JACK_EVENT 0x04 -#define VIA_MONO_EVENT 0x08 -#define VIA_SPEAKER_EVENT 0x10 -#define VIA_BIND_HP_EVENT 0x20 +#define VIA_MONO_EVENT 0x03 +#define VIA_SPEAKER_EVENT 0x04 +#define VIA_BIND_HP_EVENT 0x05 enum { VIA_CTL_WIDGET_VOL, @@ -245,7 +256,6 @@ enum { }; static void analog_low_current_mode(struct hda_codec *codec, int stream_idle); -static void set_jack_power_state(struct hda_codec *codec); static int is_aa_path_mute(struct hda_codec *codec); static void vt1708_start_hp_work(struct via_spec *spec) @@ -271,6 +281,12 @@ static void vt1708_stop_hp_work(struct via_spec *spec) cancel_delayed_work_sync(&spec->vt1708_hp_work); } +static void set_widgets_power_state(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + if (spec->set_widgets_power_state) + spec->set_widgets_power_state(codec); +} static int analog_input_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) @@ -278,7 +294,7 @@ static int analog_input_switch_put(struct snd_kcontrol *kcontrol, int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); struct hda_codec *codec = snd_kcontrol_chip(kcontrol); - set_jack_power_state(codec); + set_widgets_power_state(codec); analog_low_current_mode(snd_kcontrol_chip(kcontrol), -1); if (snd_hda_get_bool_hint(codec, "analog_loopback_hp_detect") == 1) { if (is_aa_path_mute(codec)) @@ -394,54 +410,54 @@ static int bind_pin_switch_put(struct snd_kcontrol *kcontrol, .put = bind_pin_switch_put, \ .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0) } -static struct snd_kcontrol_new via_control_templates[] = { +static const struct snd_kcontrol_new via_control_templates[] = { HDA_CODEC_VOLUME(NULL, 0, 0, 0), HDA_CODEC_MUTE(NULL, 0, 0, 0), ANALOG_INPUT_MUTE, BIND_PIN_MUTE, }; -static hda_nid_t vt1708_adc_nids[2] = { +static const hda_nid_t vt1708_adc_nids[2] = { /* ADC1-2 */ 0x15, 0x27 }; -static hda_nid_t vt1709_adc_nids[3] = { +static const hda_nid_t vt1709_adc_nids[3] = { /* ADC1-2 */ 0x14, 0x15, 0x16 }; -static hda_nid_t vt1708B_adc_nids[2] = { +static const hda_nid_t vt1708B_adc_nids[2] = { /* ADC1-2 */ 0x13, 0x14 }; -static hda_nid_t vt1708S_adc_nids[2] = { +static const hda_nid_t vt1708S_adc_nids[2] = { /* ADC1-2 */ 0x13, 0x14 }; -static hda_nid_t vt1702_adc_nids[3] = { +static const hda_nid_t vt1702_adc_nids[3] = { /* ADC1-2 */ 0x12, 0x20, 0x1F }; -static hda_nid_t vt1718S_adc_nids[2] = { +static const hda_nid_t vt1718S_adc_nids[2] = { /* ADC1-2 */ 0x10, 0x11 }; -static hda_nid_t vt1716S_adc_nids[2] = { +static const hda_nid_t vt1716S_adc_nids[2] = { /* ADC1-2 */ 0x13, 0x14 }; -static hda_nid_t vt2002P_adc_nids[2] = { +static const hda_nid_t vt2002P_adc_nids[2] = { /* ADC1-2 */ 0x10, 0x11 }; -static hda_nid_t vt1812_adc_nids[2] = { +static const hda_nid_t vt1812_adc_nids[2] = { /* ADC1-2 */ 0x10, 0x11 }; @@ -471,7 +487,7 @@ static int __via_add_control(struct via_spec *spec, int type, const char *name, __via_add_control(spec, type, name, 0, val) static struct snd_kcontrol_new *via_clone_control(struct via_spec *spec, - struct snd_kcontrol_new *tmpl) + const struct snd_kcontrol_new *tmpl) { struct snd_kcontrol_new *knew; @@ -602,482 +618,6 @@ static void set_pin_power_state(struct hda_codec *codec, hda_nid_t nid, snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE, parm); } -static void set_jack_power_state(struct hda_codec *codec) -{ - struct via_spec *spec = codec->spec; - int imux_is_smixer; - unsigned int parm; - - if (spec->codec_type == VT1702) { - imux_is_smixer = snd_hda_codec_read( - codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; - /* inputs */ - /* PW 1/2/5 (14h/15h/18h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x14, &parm); - set_pin_power_state(codec, 0x15, &parm); - set_pin_power_state(codec, 0x18, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; /* SW0 = stereo mixer (idx 3) */ - /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ - snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* outputs */ - /* PW 3/4 (16h/17h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x16, &parm); - set_pin_power_state(codec, 0x17, &parm); - /* MW0 (1ah), AOW 0/1 (10h/1dh) */ - snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, - imux_is_smixer ? AC_PWRST_D0 : parm); - snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, - parm); - } else if (spec->codec_type == VT1708B_8CH - || spec->codec_type == VT1708B_4CH - || spec->codec_type == VT1708S) { - /* SW0 (17h) = stereo mixer */ - int is_8ch = spec->codec_type != VT1708B_4CH; - imux_is_smixer = snd_hda_codec_read( - codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) - == ((spec->codec_type == VT1708S) ? 5 : 0); - /* inputs */ - /* PW 1/2/5 (1ah/1bh/1eh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x1a, &parm); - set_pin_power_state(codec, 0x1b, &parm); - set_pin_power_state(codec, 0x1e, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; - /* SW0 (17h), AIW 0/1 (13h/14h) */ - snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* outputs */ - /* PW0 (19h), SW1 (18h), AOW1 (11h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x19, &parm); - if (spec->smart51_enabled) - parm = AC_PWRST_D0; - snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* PW6 (22h), SW2 (26h), AOW2 (24h) */ - if (is_8ch) { - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x22, &parm); - if (spec->smart51_enabled) - parm = AC_PWRST_D0; - snd_hda_codec_write(codec, 0x26, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x24, 0, - AC_VERB_SET_POWER_STATE, parm); - } - - /* PW 3/4/7 (1ch/1dh/23h) */ - parm = AC_PWRST_D3; - /* force to D0 for internal Speaker */ - set_pin_power_state(codec, 0x1c, &parm); - set_pin_power_state(codec, 0x1d, &parm); - if (is_8ch) - set_pin_power_state(codec, 0x23, &parm); - /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ - snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, - imux_is_smixer ? AC_PWRST_D0 : parm); - snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, - parm); - if (is_8ch) { - snd_hda_codec_write(codec, 0x25, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x27, 0, - AC_VERB_SET_POWER_STATE, parm); - } - } else if (spec->codec_type == VT1718S) { - /* MUX6 (1eh) = stereo mixer */ - imux_is_smixer = snd_hda_codec_read( - codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; - /* inputs */ - /* PW 5/6/7 (29h/2ah/2bh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x29, &parm); - set_pin_power_state(codec, 0x2a, &parm); - set_pin_power_state(codec, 0x2b, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; - /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ - snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* outputs */ - /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x27, &parm); - snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* PW2 (26h), AOW2 (ah) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x26, &parm); - snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* PW0/1 (24h/25h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x24, &parm); - set_pin_power_state(codec, 0x25, &parm); - if (!spec->hp_independent_mode) /* check for redirected HP */ - set_pin_power_state(codec, 0x28, &parm); - snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, - parm); - /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ - snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, - imux_is_smixer ? AC_PWRST_D0 : parm); - if (spec->hp_independent_mode) { - /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x28, &parm); - snd_hda_codec_write(codec, 0x1b, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x34, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0xc, 0, - AC_VERB_SET_POWER_STATE, parm); - } - } else if (spec->codec_type == VT1716S) { - unsigned int mono_out, present; - /* SW0 (17h) = stereo mixer */ - imux_is_smixer = snd_hda_codec_read( - codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; - /* inputs */ - /* PW 1/2/5 (1ah/1bh/1eh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x1a, &parm); - set_pin_power_state(codec, 0x1b, &parm); - set_pin_power_state(codec, 0x1e, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; - /* SW0 (17h), AIW0(13h) */ - snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, - parm); - - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x1e, &parm); - /* PW11 (22h) */ - if (spec->dmic_enabled) - set_pin_power_state(codec, 0x22, &parm); - else - snd_hda_codec_write( - codec, 0x22, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - - /* SW2(26h), AIW1(14h) */ - snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* outputs */ - /* PW0 (19h), SW1 (18h), AOW1 (11h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x19, &parm); - /* Smart 5.1 PW2(1bh) */ - if (spec->smart51_enabled) - set_pin_power_state(codec, 0x1b, &parm); - snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* PW7 (23h), SW3 (27h), AOW3 (25h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x23, &parm); - /* Smart 5.1 PW1(1ah) */ - if (spec->smart51_enabled) - set_pin_power_state(codec, 0x1a, &parm); - snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* Smart 5.1 PW5(1eh) */ - if (spec->smart51_enabled) - set_pin_power_state(codec, 0x1e, &parm); - snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* Mono out */ - /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ - present = snd_hda_jack_detect(codec, 0x1c); - if (present) - mono_out = 0; - else { - present = snd_hda_jack_detect(codec, 0x1d); - if (!spec->hp_independent_mode && present) - mono_out = 0; - else - mono_out = 1; - } - parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; - snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, - parm); - snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, - parm); - - /* PW 3/4 (1ch/1dh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x1c, &parm); - set_pin_power_state(codec, 0x1d, &parm); - /* HP Independent Mode, power on AOW3 */ - if (spec->hp_independent_mode) - snd_hda_codec_write(codec, 0x25, 0, - AC_VERB_SET_POWER_STATE, parm); - - /* force to D0 for internal Speaker */ - /* MW0 (16h), AOW0 (10h) */ - snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, - imux_is_smixer ? AC_PWRST_D0 : parm); - snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, - mono_out ? AC_PWRST_D0 : parm); - } else if (spec->codec_type == VT2002P) { - unsigned int present; - /* MUX9 (1eh) = stereo mixer */ - imux_is_smixer = snd_hda_codec_read( - codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; - /* inputs */ - /* PW 5/6/7 (29h/2ah/2bh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x29, &parm); - set_pin_power_state(codec, 0x2a, &parm); - set_pin_power_state(codec, 0x2b, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; - /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ - snd_hda_codec_write(codec, 0x1e, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x1f, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x10, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x11, 0, - AC_VERB_SET_POWER_STATE, parm); - - /* outputs */ - /* AOW0 (8h)*/ - snd_hda_codec_write(codec, 0x8, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - - /* PW4 (26h), MW4 (1ch), MUX4(37h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x26, &parm); - snd_hda_codec_write(codec, 0x1c, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x37, - 0, AC_VERB_SET_POWER_STATE, parm); - - /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x25, &parm); - snd_hda_codec_write(codec, 0x19, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x35, 0, - AC_VERB_SET_POWER_STATE, parm); - if (spec->hp_independent_mode) { - snd_hda_codec_write(codec, 0x9, 0, - AC_VERB_SET_POWER_STATE, parm); - } - - /* Class-D */ - /* PW0 (24h), MW0(18h), MUX0(34h) */ - present = snd_hda_jack_detect(codec, 0x25); - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x24, &parm); - if (present) { - snd_hda_codec_write( - codec, 0x18, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - snd_hda_codec_write( - codec, 0x34, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - } else { - snd_hda_codec_write( - codec, 0x18, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - snd_hda_codec_write( - codec, 0x34, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - } - - /* Mono Out */ - /* PW15 (31h), MW8(17h), MUX8(3bh) */ - present = snd_hda_jack_detect(codec, 0x26); - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x31, &parm); - if (present) { - snd_hda_codec_write( - codec, 0x17, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - snd_hda_codec_write( - codec, 0x3b, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - } else { - snd_hda_codec_write( - codec, 0x17, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - snd_hda_codec_write( - codec, 0x3b, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - } - - /* MW9 (21h) */ - if (imux_is_smixer || !is_aa_path_mute(codec)) - snd_hda_codec_write( - codec, 0x21, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - else - snd_hda_codec_write( - codec, 0x21, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - } else if (spec->codec_type == VT1812) { - unsigned int present; - /* MUX10 (1eh) = stereo mixer */ - imux_is_smixer = snd_hda_codec_read( - codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; - /* inputs */ - /* PW 5/6/7 (29h/2ah/2bh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x29, &parm); - set_pin_power_state(codec, 0x2a, &parm); - set_pin_power_state(codec, 0x2b, &parm); - if (imux_is_smixer) - parm = AC_PWRST_D0; - /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ - snd_hda_codec_write(codec, 0x1e, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x1f, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x10, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x11, 0, - AC_VERB_SET_POWER_STATE, parm); - - /* outputs */ - /* AOW0 (8h)*/ - snd_hda_codec_write(codec, 0x8, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - - /* PW4 (28h), MW4 (18h), MUX4(38h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x28, &parm); - snd_hda_codec_write(codec, 0x18, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x38, 0, - AC_VERB_SET_POWER_STATE, parm); - - /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x25, &parm); - snd_hda_codec_write(codec, 0x15, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x35, 0, - AC_VERB_SET_POWER_STATE, parm); - if (spec->hp_independent_mode) { - snd_hda_codec_write(codec, 0x9, 0, - AC_VERB_SET_POWER_STATE, parm); - } - - /* Internal Speaker */ - /* PW0 (24h), MW0(14h), MUX0(34h) */ - present = snd_hda_jack_detect(codec, 0x25); - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x24, &parm); - if (present) { - snd_hda_codec_write(codec, 0x14, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D3); - snd_hda_codec_write(codec, 0x34, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D3); - } else { - snd_hda_codec_write(codec, 0x14, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D0); - snd_hda_codec_write(codec, 0x34, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D0); - } - /* Mono Out */ - /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */ - present = snd_hda_jack_detect(codec, 0x28); - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x31, &parm); - if (present) { - snd_hda_codec_write(codec, 0x1c, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D3); - snd_hda_codec_write(codec, 0x3c, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D3); - snd_hda_codec_write(codec, 0x3e, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D3); - } else { - snd_hda_codec_write(codec, 0x1c, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D0); - snd_hda_codec_write(codec, 0x3c, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D0); - snd_hda_codec_write(codec, 0x3e, 0, - AC_VERB_SET_POWER_STATE, - AC_PWRST_D0); - } - - /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ - parm = AC_PWRST_D3; - set_pin_power_state(codec, 0x33, &parm); - snd_hda_codec_write(codec, 0x1d, 0, - AC_VERB_SET_POWER_STATE, parm); - snd_hda_codec_write(codec, 0x3d, 0, - AC_VERB_SET_POWER_STATE, parm); - - /* MW9 (21h) */ - if (imux_is_smixer || !is_aa_path_mute(codec)) - snd_hda_codec_write( - codec, 0x21, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D0); - else - snd_hda_codec_write( - codec, 0x21, 0, - AC_VERB_SET_POWER_STATE, AC_PWRST_D3); - } -} - /* * input MUX handling */ @@ -1120,7 +660,7 @@ static int via_mux_enum_put(struct snd_kcontrol *kcontrol, spec->mux_nids[adc_idx], &spec->cur_mux[adc_idx]); /* update jack power state */ - set_jack_power_state(codec); + set_widgets_power_state(codec); return ret; } @@ -1168,6 +708,9 @@ static hda_nid_t side_mute_channel(struct via_spec *spec) case VT1709_10CH: return 0x29; case VT1708B_8CH: /* fall thru */ case VT1708S: return 0x27; + case VT2002P: return 0x19; + case VT1802: return 0x15; + case VT1812: return 0x15; default: return 0; } } @@ -1176,13 +719,22 @@ static int update_side_mute_status(struct hda_codec *codec) { /* mute side channel */ struct via_spec *spec = codec->spec; - unsigned int parm = spec->hp_independent_mode - ? AMP_OUT_MUTE : AMP_OUT_UNMUTE; + unsigned int parm; hda_nid_t sw3 = side_mute_channel(spec); - if (sw3) - snd_hda_codec_write(codec, sw3, 0, AC_VERB_SET_AMP_GAIN_MUTE, - parm); + if (sw3) { + if (VT2002P_COMPATIBLE(spec)) + parm = spec->hp_independent_mode ? + AMP_IN_MUTE(1) : AMP_IN_UNMUTE(1); + else + parm = spec->hp_independent_mode ? + AMP_OUT_MUTE : AMP_OUT_UNMUTE; + snd_hda_codec_write(codec, sw3, 0, + AC_VERB_SET_AMP_GAIN_MUTE, parm); + if (spec->codec_type == VT1812) + snd_hda_codec_write(codec, 0x1d, 0, + AC_VERB_SET_AMP_GAIN_MUTE, parm); + } return 0; } @@ -1217,19 +769,18 @@ static int via_independent_hp_put(struct snd_kcontrol *kcontrol, || spec->codec_type == VT1702 || spec->codec_type == VT1718S || spec->codec_type == VT1716S - || spec->codec_type == VT2002P - || spec->codec_type == VT1812) { + || VT2002P_COMPATIBLE(spec)) { activate_ctl(codec, "Headphone Playback Volume", spec->hp_independent_mode); activate_ctl(codec, "Headphone Playback Switch", spec->hp_independent_mode); } /* update jack power state */ - set_jack_power_state(codec); + set_widgets_power_state(codec); return 0; } -static struct snd_kcontrol_new via_hp_mixer[2] = { +static const struct snd_kcontrol_new via_hp_mixer[2] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Independent HP", @@ -1256,6 +807,7 @@ static int via_hp_build(struct hda_codec *codec) nid = 0x34; break; case VT2002P: + case VT1802: nid = 0x35; break; case VT1812: @@ -1447,11 +999,11 @@ static int via_smart51_put(struct snd_kcontrol *kcontrol, } } spec->smart51_enabled = *ucontrol->value.integer.value; - set_jack_power_state(codec); + set_widgets_power_state(codec); return 1; } -static struct snd_kcontrol_new via_smart51_mixer[2] = { +static const struct snd_kcontrol_new via_smart51_mixer[2] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Smart 5.1", @@ -1473,6 +1025,11 @@ static int via_smart51_build(struct via_spec *spec) hda_nid_t nid; int i; + if (!cfg) + return 0; + if (cfg->line_outs > 2) + return 0; + knew = via_clone_control(spec, &via_smart51_mixer[0]); if (knew == NULL) return -ENOMEM; @@ -1492,7 +1049,7 @@ static int via_smart51_build(struct via_spec *spec) } /* capture mixer elements */ -static struct snd_kcontrol_new vt1708_capture_mixer[] = { +static const struct snd_kcontrol_new vt1708_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x27, 0x0, HDA_INPUT), @@ -1543,6 +1100,7 @@ static int is_aa_path_mute(struct hda_codec *codec) break; case VT2002P: case VT1812: + case VT1802: nid_mixer = 0x21; start_idx = 0; end_idx = 2; @@ -1607,6 +1165,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle) break; case VT2002P: case VT1812: + case VT1802: verb = 0xf93; parm = enable ? 0x00 : 0xe0; /* 0x00: 4/40x, 0xe0: 1x */ break; @@ -1620,7 +1179,7 @@ static void analog_low_current_mode(struct hda_codec *codec, int stream_idle) /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb vt1708_volume_init_verbs[] = { +static const struct hda_verb vt1708_volume_init_verbs[] = { /* * Unmute ADC0-1 and set the default input to mic-in */ @@ -1650,6 +1209,8 @@ static struct hda_verb vt1708_volume_init_verbs[] = { {0x20, AC_VERB_SET_CONNECT_SEL, 0}, /* PW9 Output enable */ {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40}, + /* power down jack detect function */ + {0x1, 0xf81, 0x1}, { } }; @@ -1672,7 +1233,7 @@ static void playback_multi_pcm_prep_0(struct hda_codec *codec, { struct via_spec *spec = codec->spec; struct hda_multi_out *mout = &spec->multiout; - hda_nid_t *nids = mout->dac_nids; + const hda_nid_t *nids = mout->dac_nids; int chs = substream->runtime->channels; int i; @@ -1741,7 +1302,7 @@ static int via_playback_multi_pcm_prepare(struct hda_pcm_stream *hinfo, { struct via_spec *spec = codec->spec; struct hda_multi_out *mout = &spec->multiout; - hda_nid_t *nids = mout->dac_nids; + const hda_nid_t *nids = mout->dac_nids; if (substream->number == 0) playback_multi_pcm_prep_0(codec, stream_tag, format, @@ -1762,7 +1323,7 @@ static int via_playback_multi_pcm_cleanup(struct hda_pcm_stream *hinfo, { struct via_spec *spec = codec->spec; struct hda_multi_out *mout = &spec->multiout; - hda_nid_t *nids = mout->dac_nids; + const hda_nid_t *nids = mout->dac_nids; int i; if (substream->number == 0) { @@ -1860,7 +1421,7 @@ static int via_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, return 0; } -static struct hda_pcm_stream vt1708_pcm_analog_playback = { +static const struct hda_pcm_stream vt1708_pcm_analog_playback = { .substreams = 2, .channels_min = 2, .channels_max = 8, @@ -1872,7 +1433,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { +static const struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { .substreams = 2, .channels_min = 2, .channels_max = 8, @@ -1889,7 +1450,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_s16_playback = { }, }; -static struct hda_pcm_stream vt1708_pcm_analog_capture = { +static const struct hda_pcm_stream vt1708_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -1900,7 +1461,7 @@ static struct hda_pcm_stream vt1708_pcm_analog_capture = { }, }; -static struct hda_pcm_stream vt1708_pcm_digital_playback = { +static const struct hda_pcm_stream vt1708_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -1913,7 +1474,7 @@ static struct hda_pcm_stream vt1708_pcm_digital_playback = { }, }; -static struct hda_pcm_stream vt1708_pcm_digital_capture = { +static const struct hda_pcm_stream vt1708_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -1923,7 +1484,7 @@ static int via_build_controls(struct hda_codec *codec) { struct via_spec *spec = codec->spec; struct snd_kcontrol *kctl; - struct snd_kcontrol_new *knew; + const struct snd_kcontrol_new *knew; int err, i; for (i = 0; i < spec->num_mixers; i++) { @@ -1971,7 +1532,7 @@ static int via_build_controls(struct hda_codec *codec) } /* init power states */ - set_jack_power_state(codec); + set_widgets_power_state(codec); analog_low_current_mode(codec, 1); via_free_kctls(codec); /* no longer needed */ @@ -2135,7 +1696,7 @@ static void via_speaker_automute(struct hda_codec *codec) unsigned int hp_present; struct via_spec *spec = codec->spec; - if (spec->codec_type != VT2002P && spec->codec_type != VT1812) + if (!VT2002P_COMPATIBLE(spec)) return; hp_present = snd_hda_jack_detect(codec, spec->autocfg.hp_pins[0]); @@ -2194,17 +1755,21 @@ static void via_unsol_event(struct hda_codec *codec, unsigned int res) { res >>= 26; - if (res & VIA_HP_EVENT) - via_hp_automute(codec); - if (res & VIA_GPIO_EVENT) - via_gpio_control(codec); + if (res & VIA_JACK_EVENT) - set_jack_power_state(codec); - if (res & VIA_MONO_EVENT) + set_widgets_power_state(codec); + + res &= ~VIA_JACK_EVENT; + + if (res == VIA_HP_EVENT) + via_hp_automute(codec); + else if (res == VIA_GPIO_EVENT) + via_gpio_control(codec); + else if (res == VIA_MONO_EVENT) via_mono_automute(codec); - if (res & VIA_SPEAKER_EVENT) + else if (res == VIA_SPEAKER_EVENT) via_speaker_automute(codec); - if (res & VIA_BIND_HP_EVENT) + else if (res == VIA_BIND_HP_EVENT) via_hp_bind_automute(codec); } @@ -2254,7 +1819,7 @@ static int via_check_power_status(struct hda_codec *codec, hda_nid_t nid) /* */ -static struct hda_codec_ops via_patch_ops = { +static const struct hda_codec_ops via_patch_ops = { .build_controls = via_build_controls, .build_pcms = via_build_pcms, .init = via_init, @@ -2284,16 +1849,16 @@ static int vt1708_auto_fill_dac_nids(struct via_spec *spec, /* config dac list */ switch (i) { case AUTO_SEQ_FRONT: - spec->multiout.dac_nids[i] = 0x10; + spec->private_dac_nids[i] = 0x10; break; case AUTO_SEQ_CENLFE: - spec->multiout.dac_nids[i] = 0x12; + spec->private_dac_nids[i] = 0x12; break; case AUTO_SEQ_SURROUND: - spec->multiout.dac_nids[i] = 0x11; + spec->private_dac_nids[i] = 0x11; break; case AUTO_SEQ_SIDE: - spec->multiout.dac_nids[i] = 0x13; + spec->private_dac_nids[i] = 0x13; break; } } @@ -2437,7 +2002,8 @@ static int vt1708_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg, hda_nid_t cap_nid, - hda_nid_t pin_idxs[], int num_idxs) + const hda_nid_t pin_idxs[], + int num_idxs) { struct via_spec *spec = codec->spec; struct hda_input_mux *imux = &spec->private_imux[0]; @@ -2483,13 +2049,13 @@ static int vt_auto_create_analog_input_ctls(struct hda_codec *codec, static int vt1708_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { - static hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 }; + static const hda_nid_t pin_idxs[] = { 0xff, 0x24, 0x1d, 0x1e, 0x21 }; return vt_auto_create_analog_input_ctls(codec, cfg, 0x17, pin_idxs, ARRAY_SIZE(pin_idxs)); } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list vt1708_loopbacks[] = { +static const struct hda_amp_list vt1708_loopbacks[] = { { 0x17, HDA_INPUT, 1 }, { 0x17, HDA_INPUT, 2 }, { 0x17, HDA_INPUT, 3 }, @@ -2548,7 +2114,7 @@ static int vt1708_jack_detectect_put(struct snd_kcontrol *kcontrol, return change; } -static struct snd_kcontrol_new vt1708_jack_detectect[] = { +static const struct snd_kcontrol_new vt1708_jack_detectect[] = { { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = "Jack Detect", @@ -2623,7 +2189,8 @@ static int via_auto_init(struct hda_codec *codec) via_auto_init_multi_out(codec); via_auto_init_hp_out(codec); via_auto_init_analog_input(codec); - if (spec->codec_type == VT2002P || spec->codec_type == VT1812) { + + if (VT2002P_COMPATIBLE(spec)) { via_hp_bind_automute(codec); } else { via_hp_automute(codec); @@ -2727,7 +2294,7 @@ static int patch_vt1708(struct hda_codec *codec) } /* capture mixer elements */ -static struct snd_kcontrol_new vt1709_capture_mixer[] = { +static const struct snd_kcontrol_new vt1709_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x14, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x14, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x15, 0x0, HDA_INPUT), @@ -2749,7 +2316,7 @@ static struct snd_kcontrol_new vt1709_capture_mixer[] = { { } /* end */ }; -static struct hda_verb vt1709_uniwill_init_verbs[] = { +static const struct hda_verb vt1709_uniwill_init_verbs[] = { {0x20, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, { } @@ -2758,7 +2325,7 @@ static struct hda_verb vt1709_uniwill_init_verbs[] = { /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb vt1709_10ch_volume_init_verbs[] = { +static const struct hda_verb vt1709_10ch_volume_init_verbs[] = { /* * Unmute ADC0-2 and set the default input to mic-in */ @@ -2798,7 +2365,7 @@ static struct hda_verb vt1709_10ch_volume_init_verbs[] = { { } }; -static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { +static const struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 10, @@ -2810,7 +2377,7 @@ static struct hda_pcm_stream vt1709_10ch_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { +static const struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { .substreams = 1, .channels_min = 2, .channels_max = 6, @@ -2822,7 +2389,7 @@ static struct hda_pcm_stream vt1709_6ch_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt1709_pcm_analog_capture = { +static const struct hda_pcm_stream vt1709_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -2833,7 +2400,7 @@ static struct hda_pcm_stream vt1709_pcm_analog_capture = { }, }; -static struct hda_pcm_stream vt1709_pcm_digital_playback = { +static const struct hda_pcm_stream vt1709_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -2844,7 +2411,7 @@ static struct hda_pcm_stream vt1709_pcm_digital_playback = { }, }; -static struct hda_pcm_stream vt1709_pcm_digital_capture = { +static const struct hda_pcm_stream vt1709_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -2871,26 +2438,26 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec, switch (i) { case AUTO_SEQ_FRONT: /* AOW0 */ - spec->multiout.dac_nids[i] = 0x10; + spec->private_dac_nids[i] = 0x10; break; case AUTO_SEQ_CENLFE: /* AOW2 */ - spec->multiout.dac_nids[i] = 0x12; + spec->private_dac_nids[i] = 0x12; break; case AUTO_SEQ_SURROUND: /* AOW3 */ - spec->multiout.dac_nids[i] = 0x11; + spec->private_dac_nids[i] = 0x11; break; case AUTO_SEQ_SIDE: /* AOW1 */ - spec->multiout.dac_nids[i] = 0x27; + spec->private_dac_nids[i] = 0x27; break; default: break; } } } - spec->multiout.dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ + spec->private_dac_nids[cfg->line_outs] = 0x28; /* AOW4 */ } else if (cfg->line_outs == 3) { /* 6 channels */ for (i = 0; i < cfg->line_outs; i++) { @@ -2900,15 +2467,15 @@ static int vt1709_auto_fill_dac_nids(struct via_spec *spec, switch (i) { case AUTO_SEQ_FRONT: /* AOW0 */ - spec->multiout.dac_nids[i] = 0x10; + spec->private_dac_nids[i] = 0x10; break; case AUTO_SEQ_CENLFE: /* AOW2 */ - spec->multiout.dac_nids[i] = 0x12; + spec->private_dac_nids[i] = 0x12; break; case AUTO_SEQ_SURROUND: /* AOW1 */ - spec->multiout.dac_nids[i] = 0x11; + spec->private_dac_nids[i] = 0x11; break; default: break; @@ -3056,7 +2623,7 @@ static int vt1709_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) static int vt1709_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { - static hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 }; + static const hda_nid_t pin_idxs[] = { 0xff, 0x23, 0x1d, 0x1e, 0x21 }; return vt_auto_create_analog_input_ctls(codec, cfg, 0x18, pin_idxs, ARRAY_SIZE(pin_idxs)); } @@ -3106,7 +2673,7 @@ static int vt1709_parse_auto_config(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list vt1709_loopbacks[] = { +static const struct hda_amp_list vt1709_loopbacks[] = { { 0x18, HDA_INPUT, 1 }, { 0x18, HDA_INPUT, 2 }, { 0x18, HDA_INPUT, 3 }, @@ -3167,7 +2734,7 @@ static int patch_vt1709_10ch(struct hda_codec *codec) /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb vt1709_6ch_volume_init_verbs[] = { +static const struct hda_verb vt1709_6ch_volume_init_verbs[] = { /* * Unmute ADC0-2 and set the default input to mic-in */ @@ -3257,7 +2824,7 @@ static int patch_vt1709_6ch(struct hda_codec *codec) } /* capture mixer elements */ -static struct snd_kcontrol_new vt1708B_capture_mixer[] = { +static const struct snd_kcontrol_new vt1708B_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), @@ -3279,7 +2846,7 @@ static struct snd_kcontrol_new vt1708B_capture_mixer[] = { /* * generic initialization of ADC, input mixers and output mixers */ -static struct hda_verb vt1708B_8ch_volume_init_verbs[] = { +static const struct hda_verb vt1708B_8ch_volume_init_verbs[] = { /* * Unmute ADC0-1 and set the default input to mic-in */ @@ -3314,7 +2881,7 @@ static struct hda_verb vt1708B_8ch_volume_init_verbs[] = { { } }; -static struct hda_verb vt1708B_4ch_volume_init_verbs[] = { +static const struct hda_verb vt1708B_4ch_volume_init_verbs[] = { /* * Unmute ADC0-1 and set the default input to mic-in */ @@ -3349,7 +2916,7 @@ static struct hda_verb vt1708B_4ch_volume_init_verbs[] = { { } }; -static struct hda_verb vt1708B_uniwill_init_verbs[] = { +static const struct hda_verb vt1708B_uniwill_init_verbs[] = { {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, @@ -3373,7 +2940,7 @@ static int via_pcm_open_close(struct hda_pcm_stream *hinfo, return 0; } -static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { +static const struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { .substreams = 2, .channels_min = 2, .channels_max = 8, @@ -3386,7 +2953,7 @@ static struct hda_pcm_stream vt1708B_8ch_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { +static const struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { .substreams = 2, .channels_min = 2, .channels_max = 4, @@ -3398,7 +2965,7 @@ static struct hda_pcm_stream vt1708B_4ch_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt1708B_pcm_analog_capture = { +static const struct hda_pcm_stream vt1708B_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -3411,7 +2978,7 @@ static struct hda_pcm_stream vt1708B_pcm_analog_capture = { }, }; -static struct hda_pcm_stream vt1708B_pcm_digital_playback = { +static const struct hda_pcm_stream vt1708B_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -3424,7 +2991,7 @@ static struct hda_pcm_stream vt1708B_pcm_digital_playback = { }, }; -static struct hda_pcm_stream vt1708B_pcm_digital_capture = { +static const struct hda_pcm_stream vt1708B_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -3447,16 +3014,16 @@ static int vt1708B_auto_fill_dac_nids(struct via_spec *spec, /* config dac list */ switch (i) { case AUTO_SEQ_FRONT: - spec->multiout.dac_nids[i] = 0x10; + spec->private_dac_nids[i] = 0x10; break; case AUTO_SEQ_CENLFE: - spec->multiout.dac_nids[i] = 0x24; + spec->private_dac_nids[i] = 0x24; break; case AUTO_SEQ_SURROUND: - spec->multiout.dac_nids[i] = 0x11; + spec->private_dac_nids[i] = 0x11; break; case AUTO_SEQ_SIDE: - spec->multiout.dac_nids[i] = 0x25; + spec->private_dac_nids[i] = 0x25; break; } } @@ -3588,7 +3155,7 @@ static int vt1708B_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) static int vt1708B_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { - static hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e }; + static const hda_nid_t pin_idxs[] = { 0xff, 0x1f, 0x1a, 0x1b, 0x1e }; return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, ARRAY_SIZE(pin_idxs)); } @@ -3638,7 +3205,7 @@ static int vt1708B_parse_auto_config(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list vt1708B_loopbacks[] = { +static const struct hda_amp_list vt1708B_loopbacks[] = { { 0x16, HDA_INPUT, 1 }, { 0x16, HDA_INPUT, 2 }, { 0x16, HDA_INPUT, 3 }, @@ -3646,6 +3213,87 @@ static struct hda_amp_list vt1708B_loopbacks[] = { { } /* end */ }; #endif + +static void set_widgets_power_state_vt1708B(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int imux_is_smixer; + unsigned int parm; + int is_8ch = 0; + if ((spec->codec_type != VT1708B_4CH) && + (codec->vendor_id != 0x11064397)) + is_8ch = 1; + + /* SW0 (17h) = stereo mixer */ + imux_is_smixer = + (snd_hda_codec_read(codec, 0x17, 0, AC_VERB_GET_CONNECT_SEL, 0x00) + == ((spec->codec_type == VT1708S) ? 5 : 0)); + /* inputs */ + /* PW 1/2/5 (1ah/1bh/1eh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x1a, &parm); + set_pin_power_state(codec, 0x1b, &parm); + set_pin_power_state(codec, 0x1e, &parm); + if (imux_is_smixer) + parm = AC_PWRST_D0; + /* SW0 (17h), AIW 0/1 (13h/14h) */ + snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* PW0 (19h), SW1 (18h), AOW1 (11h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x19, &parm); + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1b, &parm); + snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW6 (22h), SW2 (26h), AOW2 (24h) */ + if (is_8ch) { + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x22, &parm); + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1a, &parm); + snd_hda_codec_write(codec, 0x26, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x24, 0, + AC_VERB_SET_POWER_STATE, parm); + } else if (codec->vendor_id == 0x11064397) { + /* PW7(23h), SW2(27h), AOW2(25h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x23, &parm); + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1a, &parm); + snd_hda_codec_write(codec, 0x27, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); + } + + /* PW 3/4/7 (1ch/1dh/23h) */ + parm = AC_PWRST_D3; + /* force to D0 for internal Speaker */ + set_pin_power_state(codec, 0x1c, &parm); + set_pin_power_state(codec, 0x1d, &parm); + if (is_8ch) + set_pin_power_state(codec, 0x23, &parm); + + /* MW0 (16h), Sw3 (27h), AOW 0/3 (10h/25h) */ + snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + if (is_8ch) { + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x27, 0, + AC_VERB_SET_POWER_STATE, parm); + } else if (codec->vendor_id == 0x11064397 && spec->hp_independent_mode) + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); +} + static int patch_vt1708S(struct hda_codec *codec); static int patch_vt1708B_8ch(struct hda_codec *codec) { @@ -3696,6 +3344,8 @@ static int patch_vt1708B_8ch(struct hda_codec *codec) spec->loopback.amplist = vt1708B_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1708B; + return 0; } @@ -3746,13 +3396,15 @@ static int patch_vt1708B_4ch(struct hda_codec *codec) spec->loopback.amplist = vt1708B_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1708B; + return 0; } /* Patch for VT1708S */ /* capture mixer elements */ -static struct snd_kcontrol_new vt1708S_capture_mixer[] = { +static const struct snd_kcontrol_new vt1708S_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), @@ -3775,7 +3427,7 @@ static struct snd_kcontrol_new vt1708S_capture_mixer[] = { { } /* end */ }; -static struct hda_verb vt1708S_volume_init_verbs[] = { +static const struct hda_verb vt1708S_volume_init_verbs[] = { /* Unmute ADC0-1 and set the default input to mic-in */ {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, @@ -3801,7 +3453,7 @@ static struct hda_verb vt1708S_volume_init_verbs[] = { { } }; -static struct hda_verb vt1708S_uniwill_init_verbs[] = { +static const struct hda_verb vt1708S_uniwill_init_verbs[] = { {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, @@ -3814,7 +3466,19 @@ static struct hda_verb vt1708S_uniwill_init_verbs[] = { { } }; -static struct hda_pcm_stream vt1708S_pcm_analog_playback = { +static const struct hda_verb vt1705_uniwill_init_verbs[] = { + {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, + {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x1b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x1e, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x23, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + { } +}; + +static const struct hda_pcm_stream vt1708S_pcm_analog_playback = { .substreams = 2, .channels_min = 2, .channels_max = 8, @@ -3827,7 +3491,20 @@ static struct hda_pcm_stream vt1708S_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt1708S_pcm_analog_capture = { +static const struct hda_pcm_stream vt1705_pcm_analog_playback = { + .substreams = 2, + .channels_min = 2, + .channels_max = 6, + .nid = 0x10, /* NID to query formats and rates */ + .ops = { + .open = via_playback_pcm_open, + .prepare = via_playback_multi_pcm_prepare, + .cleanup = via_playback_multi_pcm_cleanup, + .close = via_pcm_open_close + }, +}; + +static const struct hda_pcm_stream vt1708S_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -3840,7 +3517,7 @@ static struct hda_pcm_stream vt1708S_pcm_analog_capture = { }, }; -static struct hda_pcm_stream vt1708S_pcm_digital_playback = { +static const struct hda_pcm_stream vt1708S_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -3870,16 +3547,19 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, /* config dac list */ switch (i) { case AUTO_SEQ_FRONT: - spec->multiout.dac_nids[i] = 0x10; + spec->private_dac_nids[i] = 0x10; break; case AUTO_SEQ_CENLFE: - spec->multiout.dac_nids[i] = 0x24; + if (spec->codec->vendor_id == 0x11064397) + spec->private_dac_nids[i] = 0x25; + else + spec->private_dac_nids[i] = 0x24; break; case AUTO_SEQ_SURROUND: - spec->multiout.dac_nids[i] = 0x11; + spec->private_dac_nids[i] = 0x11; break; case AUTO_SEQ_SIDE: - spec->multiout.dac_nids[i] = 0x25; + spec->private_dac_nids[i] = 0x25; break; } } @@ -3888,23 +3568,29 @@ static int vt1708S_auto_fill_dac_nids(struct via_spec *spec, /* for Smart 5.1, line/mic inputs double as output pins */ if (cfg->line_outs == 1) { spec->multiout.num_dacs = 3; - spec->multiout.dac_nids[AUTO_SEQ_SURROUND] = 0x11; - spec->multiout.dac_nids[AUTO_SEQ_CENLFE] = 0x24; + spec->private_dac_nids[AUTO_SEQ_SURROUND] = 0x11; + if (spec->codec->vendor_id == 0x11064397) + spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x25; + else + spec->private_dac_nids[AUTO_SEQ_CENLFE] = 0x24; } return 0; } /* add playback controls from the parsed DAC table */ -static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, +static int vt1708S_auto_create_multi_out_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { + struct via_spec *spec = codec->spec; char name[32]; static const char * const chname[4] = { "Front", "Surround", "C/LFE", "Side" }; - hda_nid_t nid_vols[] = {0x10, 0x11, 0x24, 0x25}; - hda_nid_t nid_mutes[] = {0x1C, 0x18, 0x26, 0x27}; + hda_nid_t nid_vols[2][4] = { {0x10, 0x11, 0x24, 0x25}, + {0x10, 0x11, 0x25, 0} }; + hda_nid_t nid_mutes[2][4] = { {0x1C, 0x18, 0x26, 0x27}, + {0x1C, 0x18, 0x27, 0} }; hda_nid_t nid, nid_vol, nid_mute; int i, err; @@ -3915,8 +3601,15 @@ static int vt1708S_auto_create_multi_out_ctls(struct via_spec *spec, if (!nid && i > AUTO_SEQ_CENLFE) continue; - nid_vol = nid_vols[i]; - nid_mute = nid_mutes[i]; + if (codec->vendor_id == 0x11064397) { + nid_vol = nid_vols[1][i]; + nid_mute = nid_mutes[1][i]; + } else { + nid_vol = nid_vols[0][i]; + nid_mute = nid_mutes[0][i]; + } + if (!nid_vol && !nid_mute) + continue; if (i == AUTO_SEQ_CENLFE) { /* Center/LFE */ @@ -4026,7 +3719,7 @@ static int vt1708S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) static int vt1708S_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { - static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff }; + static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff }; return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, ARRAY_SIZE(pin_idxs)); } @@ -4070,7 +3763,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) if (!spec->autocfg.line_outs && !spec->autocfg.hp_pins[0]) return 0; /* can't find valid BIOS pin config */ - err = vt1708S_auto_create_multi_out_ctls(spec, &spec->autocfg); + err = vt1708S_auto_create_multi_out_ctls(codec, &spec->autocfg); if (err < 0) return err; err = vt1708S_auto_create_hp_ctls(spec, spec->autocfg.hp_pins[0]); @@ -4097,7 +3790,7 @@ static int vt1708S_parse_auto_config(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list vt1708S_loopbacks[] = { +static const struct hda_amp_list vt1708S_loopbacks[] = { { 0x16, HDA_INPUT, 1 }, { 0x16, HDA_INPUT, 2 }, { 0x16, HDA_INPUT, 3 }, @@ -4137,17 +3830,29 @@ static int patch_vt1708S(struct hda_codec *codec) } spec->init_verbs[spec->num_iverbs++] = vt1708S_volume_init_verbs; - spec->init_verbs[spec->num_iverbs++] = vt1708S_uniwill_init_verbs; + if (codec->vendor_id == 0x11064397) + spec->init_verbs[spec->num_iverbs++] = + vt1705_uniwill_init_verbs; + else + spec->init_verbs[spec->num_iverbs++] = + vt1708S_uniwill_init_verbs; if (codec->vendor_id == 0x11060440) spec->stream_name_analog = "VT1818S Analog"; + else if (codec->vendor_id == 0x11064397) + spec->stream_name_analog = "VT1705 Analog"; else spec->stream_name_analog = "VT1708S Analog"; - spec->stream_analog_playback = &vt1708S_pcm_analog_playback; + if (codec->vendor_id == 0x11064397) + spec->stream_analog_playback = &vt1705_pcm_analog_playback; + else + spec->stream_analog_playback = &vt1708S_pcm_analog_playback; spec->stream_analog_capture = &vt1708S_pcm_analog_capture; if (codec->vendor_id == 0x11060440) spec->stream_name_digital = "VT1818S Digital"; + else if (codec->vendor_id == 0x11064397) + spec->stream_name_digital = "VT1705 Digital"; else spec->stream_name_digital = "VT1708S Digital"; spec->stream_digital_playback = &vt1708S_pcm_digital_playback; @@ -4185,13 +3890,22 @@ static int patch_vt1708S(struct hda_codec *codec) spec->stream_name_analog = "VT1818S Analog"; spec->stream_name_digital = "VT1818S Digital"; } + /* correct names for VT1705 */ + if (codec->vendor_id == 0x11064397) { + kfree(codec->chip_name); + codec->chip_name = kstrdup("VT1705", GFP_KERNEL); + snprintf(codec->bus->card->mixername, + sizeof(codec->bus->card->mixername), + "%s %s", codec->vendor_name, codec->chip_name); + } + spec->set_widgets_power_state = set_widgets_power_state_vt1708B; return 0; } /* Patch for VT1702 */ /* capture mixer elements */ -static struct snd_kcontrol_new vt1702_capture_mixer[] = { +static const struct snd_kcontrol_new vt1702_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x20, 0x0, HDA_INPUT), @@ -4215,7 +3929,7 @@ static struct snd_kcontrol_new vt1702_capture_mixer[] = { { } /* end */ }; -static struct hda_verb vt1702_volume_init_verbs[] = { +static const struct hda_verb vt1702_volume_init_verbs[] = { /* * Unmute ADC0-1 and set the default input to mic-in */ @@ -4246,7 +3960,7 @@ static struct hda_verb vt1702_volume_init_verbs[] = { { } }; -static struct hda_verb vt1702_uniwill_init_verbs[] = { +static const struct hda_verb vt1702_uniwill_init_verbs[] = { {0x17, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, @@ -4256,7 +3970,7 @@ static struct hda_verb vt1702_uniwill_init_verbs[] = { { } }; -static struct hda_pcm_stream vt1702_pcm_analog_playback = { +static const struct hda_pcm_stream vt1702_pcm_analog_playback = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -4269,7 +3983,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt1702_pcm_analog_capture = { +static const struct hda_pcm_stream vt1702_pcm_analog_capture = { .substreams = 3, .channels_min = 2, .channels_max = 2, @@ -4282,7 +3996,7 @@ static struct hda_pcm_stream vt1702_pcm_analog_capture = { }, }; -static struct hda_pcm_stream vt1702_pcm_digital_playback = { +static const struct hda_pcm_stream vt1702_pcm_digital_playback = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -4304,7 +4018,7 @@ static int vt1702_auto_fill_dac_nids(struct via_spec *spec, if (cfg->line_out_pins[0]) { /* config dac list */ - spec->multiout.dac_nids[0] = 0x10; + spec->private_dac_nids[0] = 0x10; } return 0; @@ -4382,7 +4096,7 @@ static int vt1702_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) static int vt1702_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { - static hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff }; + static const hda_nid_t pin_idxs[] = { 0x14, 0x15, 0x18, 0xff }; return vt_auto_create_analog_input_ctls(codec, cfg, 0x1a, pin_idxs, ARRAY_SIZE(pin_idxs)); } @@ -4433,7 +4147,7 @@ static int vt1702_parse_auto_config(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list vt1702_loopbacks[] = { +static const struct hda_amp_list vt1702_loopbacks[] = { { 0x1A, HDA_INPUT, 1 }, { 0x1A, HDA_INPUT, 2 }, { 0x1A, HDA_INPUT, 3 }, @@ -4442,6 +4156,37 @@ static struct hda_amp_list vt1702_loopbacks[] = { }; #endif +static void set_widgets_power_state_vt1702(struct hda_codec *codec) +{ + int imux_is_smixer = + snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; + unsigned int parm; + /* inputs */ + /* PW 1/2/5 (14h/15h/18h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x14, &parm); + set_pin_power_state(codec, 0x15, &parm); + set_pin_power_state(codec, 0x18, &parm); + if (imux_is_smixer) + parm = AC_PWRST_D0; /* SW0 (13h) = stereo mixer (idx 3) */ + /* SW0 (13h), AIW 0/1/2 (12h/1fh/20h) */ + snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x20, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* PW 3/4 (16h/17h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x17, &parm); + set_pin_power_state(codec, 0x16, &parm); + /* MW0 (1ah), AOW 0/1 (10h/1dh) */ + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); +} + static int patch_vt1702(struct hda_codec *codec) { struct via_spec *spec; @@ -4488,13 +4233,14 @@ static int patch_vt1702(struct hda_codec *codec) spec->loopback.amplist = vt1702_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1702; return 0; } /* Patch for VT1718S */ /* capture mixer elements */ -static struct snd_kcontrol_new vt1718S_capture_mixer[] = { +static const struct snd_kcontrol_new vt1718S_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), @@ -4516,14 +4262,15 @@ static struct snd_kcontrol_new vt1718S_capture_mixer[] = { { } /* end */ }; -static struct hda_verb vt1718S_volume_init_verbs[] = { +static const struct hda_verb vt1718S_volume_init_verbs[] = { /* * Unmute ADC0-1 and set the default input to mic-in */ {0x10, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, - + /* Enable MW0 adjust Gain 5 */ + {0x1, 0xfb2, 0x10}, /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback * mixer widget */ @@ -4532,7 +4279,7 @@ static struct hda_verb vt1718S_volume_init_verbs[] = { {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5)}, /* Setup default input of Front HP to MW9 */ {0x28, AC_VERB_SET_CONNECT_SEL, 0x1}, @@ -4563,7 +4310,7 @@ static struct hda_verb vt1718S_volume_init_verbs[] = { }; -static struct hda_verb vt1718S_uniwill_init_verbs[] = { +static const struct hda_verb vt1718S_uniwill_init_verbs[] = { {0x28, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, {0x24, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, @@ -4576,7 +4323,7 @@ static struct hda_verb vt1718S_uniwill_init_verbs[] = { { } }; -static struct hda_pcm_stream vt1718S_pcm_analog_playback = { +static const struct hda_pcm_stream vt1718S_pcm_analog_playback = { .substreams = 2, .channels_min = 2, .channels_max = 10, @@ -4589,7 +4336,7 @@ static struct hda_pcm_stream vt1718S_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt1718S_pcm_analog_capture = { +static const struct hda_pcm_stream vt1718S_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -4602,7 +4349,7 @@ static struct hda_pcm_stream vt1718S_pcm_analog_capture = { }, }; -static struct hda_pcm_stream vt1718S_pcm_digital_playback = { +static const struct hda_pcm_stream vt1718S_pcm_digital_playback = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -4615,7 +4362,7 @@ static struct hda_pcm_stream vt1718S_pcm_digital_playback = { }, }; -static struct hda_pcm_stream vt1718S_pcm_digital_capture = { +static const struct hda_pcm_stream vt1718S_pcm_digital_capture = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -4638,16 +4385,16 @@ static int vt1718S_auto_fill_dac_nids(struct via_spec *spec, /* config dac list */ switch (i) { case AUTO_SEQ_FRONT: - spec->multiout.dac_nids[i] = 0x8; + spec->private_dac_nids[i] = 0x8; break; case AUTO_SEQ_CENLFE: - spec->multiout.dac_nids[i] = 0xa; + spec->private_dac_nids[i] = 0xa; break; case AUTO_SEQ_SURROUND: - spec->multiout.dac_nids[i] = 0x9; + spec->private_dac_nids[i] = 0x9; break; case AUTO_SEQ_SIDE: - spec->multiout.dac_nids[i] = 0xb; + spec->private_dac_nids[i] = 0xb; break; } } @@ -4769,7 +4516,7 @@ static int vt1718S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) static int vt1718S_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { - static hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff }; + static const hda_nid_t pin_idxs[] = { 0x2c, 0x2b, 0x2a, 0x29, 0, 0xff }; return vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, ARRAY_SIZE(pin_idxs)); } @@ -4820,7 +4567,7 @@ static int vt1718S_parse_auto_config(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list vt1718S_loopbacks[] = { +static const struct hda_amp_list vt1718S_loopbacks[] = { { 0x21, HDA_INPUT, 1 }, { 0x21, HDA_INPUT, 2 }, { 0x21, HDA_INPUT, 3 }, @@ -4829,6 +4576,72 @@ static struct hda_amp_list vt1718S_loopbacks[] = { }; #endif +static void set_widgets_power_state_vt1718S(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int imux_is_smixer; + unsigned int parm; + /* MUX6 (1eh) = stereo mixer */ + imux_is_smixer = + snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; + /* inputs */ + /* PW 5/6/7 (29h/2ah/2bh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x29, &parm); + set_pin_power_state(codec, 0x2a, &parm); + set_pin_power_state(codec, 0x2b, &parm); + if (imux_is_smixer) + parm = AC_PWRST_D0; + /* MUX6/7 (1eh/1fh), AIW 0/1 (10h/11h) */ + snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* PW3 (27h), MW2 (1ah), AOW3 (bh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x27, &parm); + snd_hda_codec_write(codec, 0x1a, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0xb, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW2 (26h), AOW2 (ah) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x26, &parm); + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x2b, &parm); + snd_hda_codec_write(codec, 0xa, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW0 (24h), AOW0 (8h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x24, &parm); + if (!spec->hp_independent_mode) /* check for redirected HP */ + set_pin_power_state(codec, 0x28, &parm); + snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); + /* MW9 (21h), Mw2 (1ah), AOW0 (8h) */ + snd_hda_codec_write(codec, 0x21, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + + /* PW1 (25h), AOW1 (9h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x25, &parm); + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x2a, &parm); + snd_hda_codec_write(codec, 0x9, 0, AC_VERB_SET_POWER_STATE, parm); + + if (spec->hp_independent_mode) { + /* PW4 (28h), MW3 (1bh), MUX1(34h), AOW4 (ch) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x28, &parm); + snd_hda_codec_write(codec, 0x1b, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x34, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0xc, 0, + AC_VERB_SET_POWER_STATE, parm); + } +} + static int patch_vt1718S(struct hda_codec *codec) { struct via_spec *spec; @@ -4890,6 +4703,8 @@ static int patch_vt1718S(struct hda_codec *codec) spec->loopback.amplist = vt1718S_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1718S; + return 0; } @@ -4929,13 +4744,12 @@ static int vt1716s_dmic_put(struct snd_kcontrol *kcontrol, snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_CONNECT_SEL, index); spec->dmic_enabled = index; - set_jack_power_state(codec); - + set_widgets_power_state(codec); return 1; } /* capture mixer elements */ -static struct snd_kcontrol_new vt1716S_capture_mixer[] = { +static const struct snd_kcontrol_new vt1716S_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x13, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x13, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x14, 0x0, HDA_INPUT), @@ -4954,7 +4768,7 @@ static struct snd_kcontrol_new vt1716S_capture_mixer[] = { { } /* end */ }; -static struct snd_kcontrol_new vt1716s_dmic_mixer[] = { +static const struct snd_kcontrol_new vt1716s_dmic_mixer[] = { HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x22, 0x0, HDA_INPUT), { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, @@ -4970,12 +4784,12 @@ static struct snd_kcontrol_new vt1716s_dmic_mixer[] = { /* mono-out mixer elements */ -static struct snd_kcontrol_new vt1716S_mono_out_mixer[] = { +static const struct snd_kcontrol_new vt1716S_mono_out_mixer[] = { HDA_CODEC_MUTE("Mono Playback Switch", 0x2a, 0x0, HDA_OUTPUT), { } /* end */ }; -static struct hda_verb vt1716S_volume_init_verbs[] = { +static const struct hda_verb vt1716S_volume_init_verbs[] = { /* * Unmute ADC0-1 and set the default input to mic-in */ @@ -5024,7 +4838,7 @@ static struct hda_verb vt1716S_volume_init_verbs[] = { }; -static struct hda_verb vt1716S_uniwill_init_verbs[] = { +static const struct hda_verb vt1716S_uniwill_init_verbs[] = { {0x1d, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_HP_EVENT | VIA_JACK_EVENT}, {0x19, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, @@ -5037,7 +4851,7 @@ static struct hda_verb vt1716S_uniwill_init_verbs[] = { { } }; -static struct hda_pcm_stream vt1716S_pcm_analog_playback = { +static const struct hda_pcm_stream vt1716S_pcm_analog_playback = { .substreams = 2, .channels_min = 2, .channels_max = 6, @@ -5050,7 +4864,7 @@ static struct hda_pcm_stream vt1716S_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt1716S_pcm_analog_capture = { +static const struct hda_pcm_stream vt1716S_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -5063,7 +4877,7 @@ static struct hda_pcm_stream vt1716S_pcm_analog_capture = { }, }; -static struct hda_pcm_stream vt1716S_pcm_digital_playback = { +static const struct hda_pcm_stream vt1716S_pcm_digital_playback = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -5092,13 +4906,13 @@ static int vt1716S_auto_fill_dac_nids(struct via_spec *spec, /* config dac list */ switch (i) { case AUTO_SEQ_FRONT: - spec->multiout.dac_nids[i] = 0x10; + spec->private_dac_nids[i] = 0x10; break; case AUTO_SEQ_CENLFE: - spec->multiout.dac_nids[i] = 0x25; + spec->private_dac_nids[i] = 0x25; break; case AUTO_SEQ_SURROUND: - spec->multiout.dac_nids[i] = 0x11; + spec->private_dac_nids[i] = 0x11; break; } } @@ -5233,7 +5047,7 @@ static int vt1716S_auto_create_hp_ctls(struct via_spec *spec, hda_nid_t pin) static int vt1716S_auto_create_analog_input_ctls(struct hda_codec *codec, const struct auto_pin_cfg *cfg) { - static hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff }; + static const hda_nid_t pin_idxs[] = { 0x1f, 0x1a, 0x1b, 0x1e, 0, 0xff }; return vt_auto_create_analog_input_ctls(codec, cfg, 0x16, pin_idxs, ARRAY_SIZE(pin_idxs)); } @@ -5280,7 +5094,7 @@ static int vt1716S_parse_auto_config(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list vt1716S_loopbacks[] = { +static const struct hda_amp_list vt1716S_loopbacks[] = { { 0x16, HDA_INPUT, 1 }, { 0x16, HDA_INPUT, 2 }, { 0x16, HDA_INPUT, 3 }, @@ -5289,6 +5103,99 @@ static struct hda_amp_list vt1716S_loopbacks[] = { }; #endif +static void set_widgets_power_state_vt1716S(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int imux_is_smixer; + unsigned int parm; + unsigned int mono_out, present; + /* SW0 (17h) = stereo mixer */ + imux_is_smixer = + (snd_hda_codec_read(codec, 0x17, 0, + AC_VERB_GET_CONNECT_SEL, 0x00) == 5); + /* inputs */ + /* PW 1/2/5 (1ah/1bh/1eh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x1a, &parm); + set_pin_power_state(codec, 0x1b, &parm); + set_pin_power_state(codec, 0x1e, &parm); + if (imux_is_smixer) + parm = AC_PWRST_D0; + /* SW0 (17h), AIW0(13h) */ + snd_hda_codec_write(codec, 0x17, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x13, 0, AC_VERB_SET_POWER_STATE, parm); + + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x1e, &parm); + /* PW11 (22h) */ + if (spec->dmic_enabled) + set_pin_power_state(codec, 0x22, &parm); + else + snd_hda_codec_write(codec, 0x22, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + + /* SW2(26h), AIW1(14h) */ + snd_hda_codec_write(codec, 0x26, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x14, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* PW0 (19h), SW1 (18h), AOW1 (11h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x19, &parm); + /* Smart 5.1 PW2(1bh) */ + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1b, &parm); + snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW7 (23h), SW3 (27h), AOW3 (25h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x23, &parm); + /* Smart 5.1 PW1(1ah) */ + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1a, &parm); + snd_hda_codec_write(codec, 0x27, 0, AC_VERB_SET_POWER_STATE, parm); + + /* Smart 5.1 PW5(1eh) */ + if (spec->smart51_enabled) + set_pin_power_state(codec, 0x1e, &parm); + snd_hda_codec_write(codec, 0x25, 0, AC_VERB_SET_POWER_STATE, parm); + + /* Mono out */ + /* SW4(28h)->MW1(29h)-> PW12 (2ah)*/ + present = snd_hda_jack_detect(codec, 0x1c); + + if (present) + mono_out = 0; + else { + present = snd_hda_jack_detect(codec, 0x1d); + if (!spec->hp_independent_mode && present) + mono_out = 0; + else + mono_out = 1; + } + parm = mono_out ? AC_PWRST_D0 : AC_PWRST_D3; + snd_hda_codec_write(codec, 0x28, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x29, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x2a, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW 3/4 (1ch/1dh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x1c, &parm); + set_pin_power_state(codec, 0x1d, &parm); + /* HP Independent Mode, power on AOW3 */ + if (spec->hp_independent_mode) + snd_hda_codec_write(codec, 0x25, 0, + AC_VERB_SET_POWER_STATE, parm); + + /* force to D0 for internal Speaker */ + /* MW0 (16h), AOW0 (10h) */ + snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_POWER_STATE, + imux_is_smixer ? AC_PWRST_D0 : parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, + mono_out ? AC_PWRST_D0 : parm); +} + static int patch_vt1716S(struct hda_codec *codec) { struct via_spec *spec; @@ -5343,13 +5250,14 @@ static int patch_vt1716S(struct hda_codec *codec) spec->loopback.amplist = vt1716S_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1716S; return 0; } /* for vt2002P */ /* capture mixer elements */ -static struct snd_kcontrol_new vt2002P_capture_mixer[] = { +static const struct snd_kcontrol_new vt2002P_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), @@ -5372,7 +5280,11 @@ static struct snd_kcontrol_new vt2002P_capture_mixer[] = { { } /* end */ }; -static struct hda_verb vt2002P_volume_init_verbs[] = { +static const struct hda_verb vt2002P_volume_init_verbs[] = { + /* Class-D speaker related verbs */ + {0x1, 0xfe0, 0x4}, + {0x1, 0xfe9, 0x80}, + {0x1, 0xfe2, 0x22}, /* * Unmute ADC0-1 and set the default input to mic-in */ @@ -5423,9 +5335,60 @@ static struct hda_verb vt2002P_volume_init_verbs[] = { {0x1, 0xfb8, 0x88}, { } }; +static const struct hda_verb vt1802_volume_init_verbs[] = { + /* + * Unmute ADC0-1 and set the default input to mic-in + */ + {0x8, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x9, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, -static struct hda_verb vt2002P_uniwill_init_verbs[] = { + /* Mute input amps (CD, Line In, Mic 1 & Mic 2) of the analog-loopback + * mixer widget + */ + /* Amp Indices: CD = 1, Mic1 = 2, Line = 3, Mic2 = 4 */ + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, + {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, + + /* MUX Indices: Mic = 0 */ + {0x1e, AC_VERB_SET_CONNECT_SEL, 0}, + {0x1f, AC_VERB_SET_CONNECT_SEL, 0}, + + /* PW9 Output enable */ + {0x2d, AC_VERB_SET_PIN_WIDGET_CONTROL, AC_PINCTL_OUT_EN}, + + /* Enable Boost Volume backdoor */ + {0x1, 0xfb9, 0x24}, + + /* MW0/1/4/8: un-mute index 0 (MUXx), un-mute index 1 (MW9) */ + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, + {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, + + /* set MUX0/1/4/8 = 0 (AOW0) */ + {0x34, AC_VERB_SET_CONNECT_SEL, 0}, + {0x35, AC_VERB_SET_CONNECT_SEL, 0}, + {0x38, AC_VERB_SET_CONNECT_SEL, 0}, + {0x3c, AC_VERB_SET_CONNECT_SEL, 0}, + + /* set PW0 index=0 (MW0) */ + {0x24, AC_VERB_SET_CONNECT_SEL, 0}, + + /* Enable AOW0 to MW9 */ + {0x1, 0xfb8, 0x88}, + { } +}; + + +static const struct hda_verb vt2002P_uniwill_init_verbs[] = { {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, {0x26, AC_VERB_SET_UNSOLICITED_ENABLE, @@ -5435,8 +5398,18 @@ static struct hda_verb vt2002P_uniwill_init_verbs[] = { {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, { } }; +static const struct hda_verb vt1802_uniwill_init_verbs[] = { + {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, + {0x28, AC_VERB_SET_UNSOLICITED_ENABLE, + AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, + {0x29, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x2a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + {0x2b, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT}, + { } +}; -static struct hda_pcm_stream vt2002P_pcm_analog_playback = { +static const struct hda_pcm_stream vt2002P_pcm_analog_playback = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -5449,7 +5422,7 @@ static struct hda_pcm_stream vt2002P_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt2002P_pcm_analog_capture = { +static const struct hda_pcm_stream vt2002P_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -5462,7 +5435,7 @@ static struct hda_pcm_stream vt2002P_pcm_analog_capture = { }, }; -static struct hda_pcm_stream vt2002P_pcm_digital_playback = { +static const struct hda_pcm_stream vt2002P_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -5482,7 +5455,7 @@ static int vt2002P_auto_fill_dac_nids(struct via_spec *spec, spec->multiout.num_dacs = 1; spec->multiout.dac_nids = spec->private_dac_nids; if (cfg->line_out_pins[0]) - spec->multiout.dac_nids[0] = 0x8; + spec->private_dac_nids[0] = 0x8; return 0; } @@ -5491,10 +5464,15 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec, const struct auto_pin_cfg *cfg) { int err; + hda_nid_t sw_nid; if (!cfg->line_out_pins[0]) return -1; + if (spec->codec_type == VT1802) + sw_nid = 0x28; + else + sw_nid = 0x26; /* Line-Out: PortE */ err = via_add_control(spec, VIA_CTL_WIDGET_VOL, @@ -5504,7 +5482,7 @@ static int vt2002P_auto_create_multi_out_ctls(struct via_spec *spec, return err; err = via_add_control(spec, VIA_CTL_WIDGET_BIND_PIN_MUTE, "Master Front Playback Switch", - HDA_COMPOSE_AMP_VAL(0x26, 3, 0, HDA_OUTPUT)); + HDA_COMPOSE_AMP_VAL(sw_nid, 3, 0, HDA_OUTPUT)); if (err < 0) return err; @@ -5544,7 +5522,7 @@ static int vt2002P_auto_create_analog_input_ctls(struct hda_codec *codec, { struct via_spec *spec = codec->spec; struct hda_input_mux *imux = &spec->private_imux[0]; - static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff }; + static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0xff }; int err; err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, @@ -5605,7 +5583,7 @@ static int vt2002P_parse_auto_config(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list vt2002P_loopbacks[] = { +static const struct hda_amp_list vt2002P_loopbacks[] = { { 0x21, HDA_INPUT, 0 }, { 0x21, HDA_INPUT, 1 }, { 0x21, HDA_INPUT, 2 }, @@ -5613,6 +5591,116 @@ static struct hda_amp_list vt2002P_loopbacks[] = { }; #endif +static void set_widgets_power_state_vt2002P(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int imux_is_smixer; + unsigned int parm; + unsigned int present; + /* MUX9 (1eh) = stereo mixer */ + imux_is_smixer = + snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; + /* inputs */ + /* PW 5/6/7 (29h/2ah/2bh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x29, &parm); + set_pin_power_state(codec, 0x2a, &parm); + set_pin_power_state(codec, 0x2b, &parm); + parm = AC_PWRST_D0; + /* MUX9/10 (1eh/1fh), AIW 0/1 (10h/11h) */ + snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* AOW0 (8h)*/ + snd_hda_codec_write(codec, 0x8, 0, AC_VERB_SET_POWER_STATE, parm); + + if (spec->codec_type == VT1802) { + /* PW4 (28h), MW4 (18h), MUX4(38h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x28, &parm); + snd_hda_codec_write(codec, 0x18, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x38, 0, + AC_VERB_SET_POWER_STATE, parm); + } else { + /* PW4 (26h), MW4 (1ch), MUX4(37h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x26, &parm); + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x37, 0, + AC_VERB_SET_POWER_STATE, parm); + } + + if (spec->codec_type == VT1802) { + /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x25, &parm); + snd_hda_codec_write(codec, 0x15, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x35, 0, + AC_VERB_SET_POWER_STATE, parm); + } else { + /* PW1 (25h), MW1 (19h), MUX1(35h), AOW1 (9h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x25, &parm); + snd_hda_codec_write(codec, 0x19, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x35, 0, + AC_VERB_SET_POWER_STATE, parm); + } + + if (spec->hp_independent_mode) + snd_hda_codec_write(codec, 0x9, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + + /* Class-D */ + /* PW0 (24h), MW0(18h/14h), MUX0(34h) */ + present = snd_hda_jack_detect(codec, 0x25); + + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x24, &parm); + parm = present ? AC_PWRST_D3 : AC_PWRST_D0; + if (spec->codec_type == VT1802) + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_POWER_STATE, parm); + else + snd_hda_codec_write(codec, 0x18, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x34, 0, AC_VERB_SET_POWER_STATE, parm); + + /* Mono Out */ + present = snd_hda_jack_detect(codec, 0x26); + + parm = present ? AC_PWRST_D3 : AC_PWRST_D0; + if (spec->codec_type == VT1802) { + /* PW15 (33h), MW8(1ch), MUX8(3ch) */ + snd_hda_codec_write(codec, 0x33, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x3c, 0, + AC_VERB_SET_POWER_STATE, parm); + } else { + /* PW15 (31h), MW8(17h), MUX8(3bh) */ + snd_hda_codec_write(codec, 0x31, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x17, 0, + AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x3b, 0, + AC_VERB_SET_POWER_STATE, parm); + } + /* MW9 (21h) */ + if (imux_is_smixer || !is_aa_path_mute(codec)) + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + else + snd_hda_codec_write(codec, 0x21, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); +} /* patch for vt2002P */ static int patch_vt2002P(struct hda_codec *codec) @@ -5635,14 +5723,31 @@ static int patch_vt2002P(struct hda_codec *codec) "from BIOS. Using genenic mode...\n"); } - spec->init_verbs[spec->num_iverbs++] = vt2002P_volume_init_verbs; - spec->init_verbs[spec->num_iverbs++] = vt2002P_uniwill_init_verbs; + if (spec->codec_type == VT1802) + spec->init_verbs[spec->num_iverbs++] = + vt1802_volume_init_verbs; + else + spec->init_verbs[spec->num_iverbs++] = + vt2002P_volume_init_verbs; - spec->stream_name_analog = "VT2002P Analog"; + if (spec->codec_type == VT1802) + spec->init_verbs[spec->num_iverbs++] = + vt1802_uniwill_init_verbs; + else + spec->init_verbs[spec->num_iverbs++] = + vt2002P_uniwill_init_verbs; + + if (spec->codec_type == VT1802) + spec->stream_name_analog = "VT1802 Analog"; + else + spec->stream_name_analog = "VT2002P Analog"; spec->stream_analog_playback = &vt2002P_pcm_analog_playback; spec->stream_analog_capture = &vt2002P_pcm_analog_capture; - spec->stream_name_digital = "VT2002P Digital"; + if (spec->codec_type == VT1802) + spec->stream_name_digital = "VT1802 Digital"; + else + spec->stream_name_digital = "VT2002P Digital"; spec->stream_digital_playback = &vt2002P_pcm_digital_playback; if (!spec->adc_nids && spec->input_mux) { @@ -5664,13 +5769,14 @@ static int patch_vt2002P(struct hda_codec *codec) spec->loopback.amplist = vt2002P_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt2002P; return 0; } /* for vt1812 */ /* capture mixer elements */ -static struct snd_kcontrol_new vt1812_capture_mixer[] = { +static const struct snd_kcontrol_new vt1812_capture_mixer[] = { HDA_CODEC_VOLUME("Capture Volume", 0x10, 0x0, HDA_INPUT), HDA_CODEC_MUTE("Capture Switch", 0x10, 0x0, HDA_INPUT), HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x11, 0x0, HDA_INPUT), @@ -5692,7 +5798,7 @@ static struct snd_kcontrol_new vt1812_capture_mixer[] = { { } /* end */ }; -static struct hda_verb vt1812_volume_init_verbs[] = { +static const struct hda_verb vt1812_volume_init_verbs[] = { /* * Unmute ADC0-1 and set the default input to mic-in */ @@ -5745,7 +5851,7 @@ static struct hda_verb vt1812_volume_init_verbs[] = { }; -static struct hda_verb vt1812_uniwill_init_verbs[] = { +static const struct hda_verb vt1812_uniwill_init_verbs[] = { {0x33, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT | VIA_BIND_HP_EVENT}, {0x25, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | VIA_JACK_EVENT }, @@ -5757,7 +5863,7 @@ static struct hda_verb vt1812_uniwill_init_verbs[] = { { } }; -static struct hda_pcm_stream vt1812_pcm_analog_playback = { +static const struct hda_pcm_stream vt1812_pcm_analog_playback = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -5770,7 +5876,7 @@ static struct hda_pcm_stream vt1812_pcm_analog_playback = { }, }; -static struct hda_pcm_stream vt1812_pcm_analog_capture = { +static const struct hda_pcm_stream vt1812_pcm_analog_capture = { .substreams = 2, .channels_min = 2, .channels_max = 2, @@ -5783,7 +5889,7 @@ static struct hda_pcm_stream vt1812_pcm_analog_capture = { }, }; -static struct hda_pcm_stream vt1812_pcm_digital_playback = { +static const struct hda_pcm_stream vt1812_pcm_digital_playback = { .substreams = 1, .channels_min = 2, .channels_max = 2, @@ -5802,7 +5908,7 @@ static int vt1812_auto_fill_dac_nids(struct via_spec *spec, spec->multiout.num_dacs = 1; spec->multiout.dac_nids = spec->private_dac_nids; if (cfg->line_out_pins[0]) - spec->multiout.dac_nids[0] = 0x8; + spec->private_dac_nids[0] = 0x8; return 0; } @@ -5865,7 +5971,7 @@ static int vt1812_auto_create_analog_input_ctls(struct hda_codec *codec, { struct via_spec *spec = codec->spec; struct hda_input_mux *imux = &spec->private_imux[0]; - static hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff }; + static const hda_nid_t pin_idxs[] = { 0x2b, 0x2a, 0x29, 0, 0, 0xff }; int err; err = vt_auto_create_analog_input_ctls(codec, cfg, 0x21, pin_idxs, @@ -5927,7 +6033,7 @@ static int vt1812_parse_auto_config(struct hda_codec *codec) } #ifdef CONFIG_SND_HDA_POWER_SAVE -static struct hda_amp_list vt1812_loopbacks[] = { +static const struct hda_amp_list vt1812_loopbacks[] = { { 0x21, HDA_INPUT, 0 }, { 0x21, HDA_INPUT, 1 }, { 0x21, HDA_INPUT, 2 }, @@ -5935,6 +6041,97 @@ static struct hda_amp_list vt1812_loopbacks[] = { }; #endif +static void set_widgets_power_state_vt1812(struct hda_codec *codec) +{ + struct via_spec *spec = codec->spec; + int imux_is_smixer = + snd_hda_codec_read(codec, 0x13, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 3; + unsigned int parm; + unsigned int present; + /* MUX10 (1eh) = stereo mixer */ + imux_is_smixer = + snd_hda_codec_read(codec, 0x1e, 0, AC_VERB_GET_CONNECT_SEL, 0x00) == 5; + /* inputs */ + /* PW 5/6/7 (29h/2ah/2bh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x29, &parm); + set_pin_power_state(codec, 0x2a, &parm); + set_pin_power_state(codec, 0x2b, &parm); + parm = AC_PWRST_D0; + /* MUX10/11 (1eh/1fh), AIW 0/1 (10h/11h) */ + snd_hda_codec_write(codec, 0x1e, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x1f, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x10, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x11, 0, AC_VERB_SET_POWER_STATE, parm); + + /* outputs */ + /* AOW0 (8h)*/ + snd_hda_codec_write(codec, 0x8, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + + /* PW4 (28h), MW4 (18h), MUX4(38h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x28, &parm); + snd_hda_codec_write(codec, 0x18, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x38, 0, AC_VERB_SET_POWER_STATE, parm); + + /* PW1 (25h), MW1 (15h), MUX1(35h), AOW1 (9h) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x25, &parm); + snd_hda_codec_write(codec, 0x15, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x35, 0, AC_VERB_SET_POWER_STATE, parm); + if (spec->hp_independent_mode) + snd_hda_codec_write(codec, 0x9, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + + /* Internal Speaker */ + /* PW0 (24h), MW0(14h), MUX0(34h) */ + present = snd_hda_jack_detect(codec, 0x25); + + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x24, &parm); + if (present) { + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x34, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + } else { + snd_hda_codec_write(codec, 0x14, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x34, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + } + + + /* Mono Out */ + /* PW13 (31h), MW13(1ch), MUX13(3ch), MW14(3eh) */ + present = snd_hda_jack_detect(codec, 0x28); + + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x31, &parm); + if (present) { + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x3c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + snd_hda_codec_write(codec, 0x3e, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D3); + } else { + snd_hda_codec_write(codec, 0x1c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x3c, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + snd_hda_codec_write(codec, 0x3e, 0, + AC_VERB_SET_POWER_STATE, AC_PWRST_D0); + } + + /* PW15 (33h), MW15 (1dh), MUX15(3dh) */ + parm = AC_PWRST_D3; + set_pin_power_state(codec, 0x33, &parm); + snd_hda_codec_write(codec, 0x1d, 0, AC_VERB_SET_POWER_STATE, parm); + snd_hda_codec_write(codec, 0x3d, 0, AC_VERB_SET_POWER_STATE, parm); + +} /* patch for vt1812 */ static int patch_vt1812(struct hda_codec *codec) @@ -5988,13 +6185,14 @@ static int patch_vt1812(struct hda_codec *codec) spec->loopback.amplist = vt1812_loopbacks; #endif + spec->set_widgets_power_state = set_widgets_power_state_vt1812; return 0; } /* * patch entries */ -static struct hda_codec_preset snd_hda_preset_via[] = { +static const struct hda_codec_preset snd_hda_preset_via[] = { { .id = 0x11061708, .name = "VT1708", .patch = patch_vt1708}, { .id = 0x11061709, .name = "VT1708", .patch = patch_vt1708}, { .id = 0x1106170a, .name = "VT1708", .patch = patch_vt1708}, @@ -6039,7 +6237,7 @@ static struct hda_codec_preset snd_hda_preset_via[] = { .patch = patch_vt1708S}, { .id = 0x11063397, .name = "VT1708S", .patch = patch_vt1708S}, - { .id = 0x11064397, .name = "VT1708S", + { .id = 0x11064397, .name = "VT1705", .patch = patch_vt1708S}, { .id = 0x11065397, .name = "VT1708S", .patch = patch_vt1708S}, @@ -6080,6 +6278,10 @@ static struct hda_codec_preset snd_hda_preset_via[] = { { .id = 0x11060448, .name = "VT1812", .patch = patch_vt1812}, { .id = 0x11060440, .name = "VT1818S", .patch = patch_vt1708S}, + { .id = 0x11060446, .name = "VT1802", + .patch = patch_vt2002P}, + { .id = 0x11068446, .name = "VT1802", + .patch = patch_vt2002P}, {} /* terminator */ };