diff options
author | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-07-27 09:54:47 +0200 |
---|---|---|
committer | Dmitry Torokhov <dmitry.torokhov@gmail.com> | 2011-07-27 09:54:47 +0200 |
commit | aa7eb8e78d8ecd6cd0475d86ea8385ff9cb47ece (patch) | |
tree | 3f9e98fadd5124fb05e8f6f9b06aa23698d4f215 /sound/pci/hda | |
parent | Input: sh_keysc - fix compile warning (diff) | |
parent | Input: synaptics - fix reporting of min coordinates (diff) | |
download | linux-aa7eb8e78d8ecd6cd0475d86ea8385ff9cb47ece.tar.xz linux-aa7eb8e78d8ecd6cd0475d86ea8385ff9cb47ece.zip |
Merge branch 'next' into for-linus
Diffstat (limited to 'sound/pci/hda')
-rw-r--r-- | sound/pci/hda/hda_beep.h | 9 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.c | 103 | ||||
-rw-r--r-- | sound/pci/hda/hda_codec.h | 4 | ||||
-rw-r--r-- | sound/pci/hda/hda_eld.c | 21 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 194 | ||||
-rw-r--r-- | sound/pci/hda/hda_local.h | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_analog.c | 362 | ||||
-rw-r--r-- | sound/pci/hda/patch_ca0110.c | 16 | ||||
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 52 | ||||
-rw-r--r-- | sound/pci/hda/patch_cmedia.c | 40 | ||||
-rw-r--r-- | sound/pci/hda/patch_conexant.c | 1098 | ||||
-rw-r--r-- | sound/pci/hda/patch_hdmi.c | 156 | ||||
-rw-r--r-- | sound/pci/hda/patch_realtek.c | 3740 | ||||
-rw-r--r-- | sound/pci/hda/patch_si3054.c | 11 | ||||
-rw-r--r-- | sound/pci/hda/patch_sigmatel.c | 431 | ||||
-rw-r--r-- | sound/pci/hda/patch_via.c | 1547 |
16 files changed, 4344 insertions, 3456 deletions
diff --git a/sound/pci/hda/hda_beep.h b/sound/pci/hda/hda_beep.h index f1de1bac042c..55f0647458c7 100644 --- a/sound/pci/hda/hda_beep.h +++ b/sound/pci/hda/hda_beep.h @@ -50,7 +50,12 @@ int snd_hda_enable_beep_device(struct hda_codec *codec, int enable); int snd_hda_attach_beep_device(struct hda_codec *codec, int nid); void snd_hda_detach_beep_device(struct hda_codec *codec); #else -#define snd_hda_attach_beep_device(...) 0 -#define snd_hda_detach_beep_device(...) +static inline int snd_hda_attach_beep_device(struct hda_codec *codec, int nid) +{ + return 0; +} +static inline void snd_hda_detach_beep_device(struct hda_codec *codec) +{ +} #endif #endif diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c index 430f41db6044..45b4a8d70e08 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 @@ -937,6 +1000,7 @@ void snd_hda_shutup_pins(struct hda_codec *codec) } EXPORT_SYMBOL_HDA(snd_hda_shutup_pins); +#ifdef SND_HDA_NEEDS_RESUME /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */ static void restore_shutup_pins(struct hda_codec *codec) { @@ -953,6 +1017,7 @@ static void restore_shutup_pins(struct hda_codec *codec) } codec->pins_shutup = 0; } +#endif static void init_hda_cache(struct hda_cache_rec *cache, unsigned int record_size); @@ -1017,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); @@ -1077,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) { @@ -1329,6 +1396,7 @@ static void purify_inactive_streams(struct hda_codec *codec) } } +#ifdef SND_HDA_NEEDS_RESUME /* clean up all streams; called from suspend */ static void hda_cleanup_all_streams(struct hda_codec *codec) { @@ -1340,6 +1408,7 @@ static void hda_cleanup_all_streams(struct hda_codec *codec) really_cleanup_stream(codec, p); } } +#endif /* * amp access functions @@ -2552,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; @@ -3803,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; @@ -3946,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) @@ -4114,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); @@ -4129,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); } @@ -4276,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; @@ -4331,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++) @@ -4356,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) @@ -4437,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; @@ -4628,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], @@ -4646,7 +4719,7 @@ int snd_hda_parse_pin_def_config(struct hda_codec *codec, cfg->dig_out_pins[0], cfg->dig_out_pins[1]); snd_printd(" inputs:"); for (i = 0; i < cfg->num_inputs; i++) { - snd_printdd(" %s=0x%x", + snd_printd(" %s=0x%x", hda_get_autocfg_input_label(codec, cfg, i), cfg->inputs[i].pin); } @@ -4982,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_eld.c b/sound/pci/hda/hda_eld.c index 74b0560289c0..b05f7be9dc1b 100644 --- a/sound/pci/hda/hda_eld.c +++ b/sound/pci/hda/hda_eld.c @@ -312,23 +312,6 @@ out_fail: return -EINVAL; } -static int hdmi_eld_valid(struct hda_codec *codec, hda_nid_t nid) -{ - int eldv; - int present; - - present = snd_hda_pin_sense(codec, nid); - eldv = (present & AC_PINSENSE_ELDV); - present = (present & AC_PINSENSE_PRESENCE); - -#ifdef CONFIG_SND_DEBUG_VERBOSE - printk(KERN_INFO "HDMI: sink_present = %d, eld_valid = %d\n", - !!present, !!eldv); -#endif - - return eldv && present; -} - int snd_hdmi_get_eld_size(struct hda_codec *codec, hda_nid_t nid) { return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_HDMI_DIP_SIZE, @@ -343,7 +326,7 @@ int snd_hdmi_get_eld(struct hdmi_eld *eld, int size; unsigned char *buf; - if (!hdmi_eld_valid(codec, nid)) + if (!eld->eld_valid) return -ENOENT; size = snd_hdmi_get_eld_size(codec, nid); @@ -477,6 +460,8 @@ static void hdmi_print_eld_info(struct snd_info_entry *entry, snd_iprintf(buffer, "monitor_present\t\t%d\n", e->monitor_present); snd_iprintf(buffer, "eld_valid\t\t%d\n", e->eld_valid); + if (!e->eld_valid) + return; snd_iprintf(buffer, "monitor_name\t\t%s\n", e->monitor_name); snd_iprintf(buffer, "connection_type\t\t%s\n", eld_connection_type_names[e->conn_type]); diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 70a9d32f0e96..486f6deb3eee 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}," @@ -390,6 +391,7 @@ struct azx { /* chip type specific */ int driver_type; + unsigned int driver_caps; int playback_streams; int playback_index_offset; int capture_streams; @@ -463,6 +465,34 @@ enum { AZX_NUM_DRIVERS, /* keep this as last entry */ }; +/* driver quirks (capabilities) */ +/* bits 0-7 are used for indicating driver type */ +#define AZX_DCAPS_NO_TCSEL (1 << 8) /* No Intel TCSEL bit */ +#define AZX_DCAPS_NO_MSI (1 << 9) /* No MSI support */ +#define AZX_DCAPS_ATI_SNOOP (1 << 10) /* ATI snoop enable */ +#define AZX_DCAPS_NVIDIA_SNOOP (1 << 11) /* Nvidia snoop enable */ +#define AZX_DCAPS_SCH_SNOOP (1 << 12) /* SCH/PCH snoop enable */ +#define AZX_DCAPS_RIRB_DELAY (1 << 13) /* Long delay in read loop */ +#define AZX_DCAPS_RIRB_PRE_DELAY (1 << 14) /* Put a delay before read */ +#define AZX_DCAPS_CTX_WORKAROUND (1 << 15) /* X-Fi workaround */ +#define AZX_DCAPS_POSFIX_LPIB (1 << 16) /* Use LPIB as default */ +#define AZX_DCAPS_POSFIX_VIA (1 << 17) /* Use VIACOMBO as default */ +#define AZX_DCAPS_NO_64BIT (1 << 18) /* No 64bit address */ +#define AZX_DCAPS_SYNC_WRITE (1 << 19) /* sync each cmd write */ + +/* quirks for ATI SB / AMD Hudson */ +#define AZX_DCAPS_PRESET_ATI_SB \ + (AZX_DCAPS_ATI_SNOOP | AZX_DCAPS_NO_TCSEL | \ + AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB) + +/* quirks for ATI/AMD HDMI */ +#define AZX_DCAPS_PRESET_ATI_HDMI \ + (AZX_DCAPS_NO_TCSEL | AZX_DCAPS_SYNC_WRITE | AZX_DCAPS_POSFIX_LPIB) + +/* quirks for Nvidia */ +#define AZX_DCAPS_PRESET_NVIDIA \ + (AZX_DCAPS_NVIDIA_SNOOP | AZX_DCAPS_RIRB_DELAY | AZX_DCAPS_NO_MSI) + static char *driver_short_names[] __devinitdata = { [AZX_DRIVER_ICH] = "HDA Intel", [AZX_DRIVER_PCH] = "HDA Intel PCH", @@ -565,7 +595,7 @@ static void azx_init_cmd_io(struct azx *chip) /* reset the rirb hw write pointer */ azx_writew(chip, RIRBWP, ICH6_RIRBWP_RST); /* set N=1, get RIRB response interrupt for new entry */ - if (chip->driver_type == AZX_DRIVER_CTX) + if (chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) azx_writew(chip, RINTCNT, 0xc0); else azx_writew(chip, RINTCNT, 1); @@ -1055,19 +1085,24 @@ static void azx_init_pci(struct azx *chip) * codecs. * The PCI register TCSEL is defined in the Intel manuals. */ - if (chip->driver_type != AZX_DRIVER_ATI && - chip->driver_type != AZX_DRIVER_ATIHDMI) + if (!(chip->driver_caps & AZX_DCAPS_NO_TCSEL)) { + snd_printdd(SFX "Clearing TCSEL\n"); update_pci_byte(chip->pci, ICH6_PCIREG_TCSEL, 0x07, 0); + } - switch (chip->driver_type) { - case AZX_DRIVER_ATI: - /* For ATI SB450 azalia HD audio, we need to enable snoop */ + /* For ATI SB450/600/700/800/900 and AMD Hudson azalia HD audio, + * we need to enable snoop. + */ + if (chip->driver_caps & AZX_DCAPS_ATI_SNOOP) { + snd_printdd(SFX "Enabling ATI snoop\n"); update_pci_byte(chip->pci, ATI_SB450_HDAUDIO_MISC_CNTR2_ADDR, 0x07, ATI_SB450_HDAUDIO_ENABLE_SNOOP); - break; - case AZX_DRIVER_NVIDIA: - /* For NVIDIA HDA, enable snoop */ + } + + /* For NVIDIA HDA, enable snoop */ + if (chip->driver_caps & AZX_DCAPS_NVIDIA_SNOOP) { + snd_printdd(SFX "Enabling Nvidia snoop\n"); update_pci_byte(chip->pci, NVIDIA_HDA_TRANSREG_ADDR, 0x0f, NVIDIA_HDA_ENABLE_COHBITS); @@ -1077,9 +1112,10 @@ static void azx_init_pci(struct azx *chip) update_pci_byte(chip->pci, NVIDIA_HDA_OSTRM_COH, 0x01, NVIDIA_HDA_ENABLE_COHBIT); - break; - case AZX_DRIVER_SCH: - case AZX_DRIVER_PCH: + } + + /* Enable SCH/PCH snoop if needed */ + if (chip->driver_caps & AZX_DCAPS_SCH_SNOOP) { pci_read_config_word(chip->pci, INTEL_SCH_HDA_DEVC, &snoop); if (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) { pci_write_config_word(chip->pci, INTEL_SCH_HDA_DEVC, @@ -1090,8 +1126,6 @@ static void azx_init_pci(struct azx *chip) (snoop & INTEL_SCH_HDA_DEVC_NOSNOOP) ? "Failed" : "OK"); } - break; - } } @@ -1145,7 +1179,7 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id) status = azx_readb(chip, RIRBSTS); if (status & RIRB_INT_MASK) { if (status & RIRB_INT_RESPONSE) { - if (chip->driver_type == AZX_DRIVER_CTX) + if (chip->driver_caps & AZX_DCAPS_RIRB_PRE_DELAY) udelay(80); azx_update_rirb(chip); } @@ -1414,8 +1448,10 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) if (err < 0) return err; - if (chip->driver_type == AZX_DRIVER_NVIDIA) + if (chip->driver_caps & AZX_DCAPS_RIRB_DELAY) { + snd_printd(SFX "Enable delay in RIRB handling\n"); chip->bus->needs_damn_long_delay = 1; + } codecs = 0; max_slots = azx_max_codecs[chip->driver_type]; @@ -1446,6 +1482,16 @@ 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->driver_caps & AZX_DCAPS_SYNC_WRITE) { + snd_printd(SFX "Enable sync_write for stable communication\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) { @@ -1702,7 +1748,7 @@ static int azx_pcm_prepare(struct snd_pcm_substream *substream) stream_tag = azx_dev->stream_tag; /* CA-IBG chips need the playback stream starting from 1 */ - if (chip->driver_type == AZX_DRIVER_CTX && + if ((chip->driver_caps & AZX_DCAPS_CTX_WORKAROUND) && stream_tag > chip->capture_streams) stream_tag -= chip->capture_streams; return snd_hda_codec_prepare(apcm->codec, hinfo, stream_tag, @@ -2347,13 +2393,14 @@ 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. */ + if (chip->driver_caps & AZX_DCAPS_POSFIX_VIA) { + snd_printd(SFX "Using VIACOMBO position fix\n"); return POS_FIX_VIACOMBO; } - + if (chip->driver_caps & AZX_DCAPS_POSFIX_LPIB) { + snd_printd(SFX "Using LPIB position fix\n"); + return POS_FIX_LPIB; + } return POS_FIX_AUTO; } @@ -2435,8 +2482,8 @@ static void __devinit check_msi(struct azx *chip) } /* NVidia chipsets seem to cause troubles with MSI */ - if (chip->driver_type == AZX_DRIVER_NVIDIA) { - printk(KERN_INFO "hda_intel: Disable MSI for Nvidia chipset\n"); + if (chip->driver_caps & AZX_DCAPS_NO_MSI) { + printk(KERN_INFO "hda_intel: Disabling MSI\n"); chip->msi = 0; } } @@ -2446,7 +2493,7 @@ static void __devinit check_msi(struct azx *chip) * constructor */ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, - int dev, int driver_type, + int dev, unsigned int driver_caps, struct azx **rchip) { struct azx *chip; @@ -2474,7 +2521,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, chip->card = card; chip->pci = pci; chip->irq = -1; - chip->driver_type = driver_type; + chip->driver_caps = driver_caps; + chip->driver_type = driver_caps & 0xff; check_msi(chip); chip->dev_index = dev; INIT_WORK(&chip->irq_pending_work, azx_irq_pending_work); @@ -2538,8 +2586,7 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, snd_printdd(SFX "chipset global capabilities = 0x%x\n", gcap); /* disable SB600 64bit support for safety */ - if ((chip->driver_type == AZX_DRIVER_ATI) || - (chip->driver_type == AZX_DRIVER_ATIHDMI)) { + if (chip->pci->vendor == PCI_VENDOR_ID_ATI) { struct pci_dev *p_smbus; p_smbus = pci_get_device(PCI_VENDOR_ID_ATI, PCI_DEVICE_ID_ATI_SBX00_SMBUS, @@ -2551,10 +2598,11 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, } } - /* disable 64bit DMA address for Teradici */ - /* it does not work with device 6549:1200 subsys e4a2:040b */ - if (chip->driver_type == AZX_DRIVER_TERA) + /* disable 64bit DMA address on some devices */ + if (chip->driver_caps & AZX_DCAPS_NO_64BIT) { + snd_printd(SFX "Disabling 64bit DMA\n"); gcap &= ~ICH6_GCAP_64OK; + } /* allow 64bit DMA address if supported by H/W */ if ((gcap & ICH6_GCAP_64OK) && !pci_set_dma_mask(pci, DMA_BIT_MASK(64))) @@ -2756,36 +2804,62 @@ static void __devexit azx_remove(struct pci_dev *pci) /* PCI IDs */ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { /* CPT */ - { PCI_DEVICE(0x8086, 0x1c20), .driver_data = AZX_DRIVER_PCH }, + { PCI_DEVICE(0x8086, 0x1c20), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, /* PBG */ - { PCI_DEVICE(0x8086, 0x1d20), .driver_data = AZX_DRIVER_PCH }, + { PCI_DEVICE(0x8086, 0x1d20), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, + /* Panther Point */ + { PCI_DEVICE(0x8086, 0x1e20), + .driver_data = AZX_DRIVER_PCH | AZX_DCAPS_SCH_SNOOP }, /* SCH */ - { PCI_DEVICE(0x8086, 0x811b), .driver_data = AZX_DRIVER_SCH }, + { PCI_DEVICE(0x8086, 0x811b), + .driver_data = AZX_DRIVER_SCH | AZX_DCAPS_SCH_SNOOP }, /* Generic Intel */ { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_ANY_ID), .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff, .driver_data = AZX_DRIVER_ICH }, - /* ATI SB 450/600 */ - { PCI_DEVICE(0x1002, 0x437b), .driver_data = AZX_DRIVER_ATI }, - { PCI_DEVICE(0x1002, 0x4383), .driver_data = AZX_DRIVER_ATI }, + /* ATI SB 450/600/700/800/900 */ + { PCI_DEVICE(0x1002, 0x437b), + .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, + { PCI_DEVICE(0x1002, 0x4383), + .driver_data = AZX_DRIVER_ATI | AZX_DCAPS_PRESET_ATI_SB }, + /* AMD Hudson */ + { PCI_DEVICE(0x1022, 0x780d), + .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_SB }, /* ATI HDMI */ - { PCI_DEVICE(0x1002, 0x793b), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0x7919), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0x960f), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0x970f), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0xaa00), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0xaa08), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0xaa10), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0xaa18), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0xaa20), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0xaa28), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0xaa30), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0xaa38), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0xaa40), .driver_data = AZX_DRIVER_ATIHDMI }, - { PCI_DEVICE(0x1002, 0xaa48), .driver_data = AZX_DRIVER_ATIHDMI }, + { PCI_DEVICE(0x1002, 0x793b), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0x7919), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0x960f), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0x970f), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaa00), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaa08), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaa10), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaa18), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaa20), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaa28), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaa30), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaa38), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaa40), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, + { PCI_DEVICE(0x1002, 0xaa48), + .driver_data = AZX_DRIVER_ATIHDMI | AZX_DCAPS_PRESET_ATI_HDMI }, /* VIA VT8251/VT8237A */ - { PCI_DEVICE(0x1106, 0x3288), .driver_data = AZX_DRIVER_VIA }, + { PCI_DEVICE(0x1106, 0x3288), + .driver_data = AZX_DRIVER_VIA | AZX_DCAPS_POSFIX_VIA }, /* SIS966 */ { PCI_DEVICE(0x1039, 0x7502), .driver_data = AZX_DRIVER_SIS }, /* ULI M5461 */ @@ -2794,9 +2868,10 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_ANY_ID), .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff, - .driver_data = AZX_DRIVER_NVIDIA }, + .driver_data = AZX_DRIVER_NVIDIA | AZX_DCAPS_PRESET_NVIDIA }, /* Teradici */ - { PCI_DEVICE(0x6549, 0x1200), .driver_data = AZX_DRIVER_TERA }, + { PCI_DEVICE(0x6549, 0x1200), + .driver_data = AZX_DRIVER_TERA | AZX_DCAPS_NO_64BIT }, /* Creative X-Fi (CA0110-IBG) */ #if !defined(CONFIG_SND_CTXFI) && !defined(CONFIG_SND_CTXFI_MODULE) /* the following entry conflicts with snd-ctxfi driver, @@ -2806,10 +2881,13 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_CREATIVE, PCI_ANY_ID), .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff, - .driver_data = AZX_DRIVER_CTX }, + .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | + AZX_DCAPS_RIRB_PRE_DELAY }, #else /* this entry seems still valid -- i.e. without emu20kx chip */ - { PCI_DEVICE(0x1102, 0x0009), .driver_data = AZX_DRIVER_CTX }, + { PCI_DEVICE(0x1102, 0x0009), + .driver_data = AZX_DRIVER_CTX | AZX_DCAPS_CTX_WORKAROUND | + AZX_DCAPS_RIRB_PRE_DELAY }, #endif /* Vortex86MX */ { PCI_DEVICE(0x17f3, 0x3010), .driver_data = AZX_DRIVER_GENERIC }, @@ -2819,11 +2897,11 @@ static DEFINE_PCI_DEVICE_TABLE(azx_ids) = { { PCI_DEVICE(PCI_VENDOR_ID_ATI, PCI_ANY_ID), .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff, - .driver_data = AZX_DRIVER_GENERIC }, + .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI }, { PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_ANY_ID), .class = PCI_CLASS_MULTIMEDIA_HD_AUDIO << 8, .class_mask = 0xffffff, - .driver_data = AZX_DRIVER_GENERIC }, + .driver_data = AZX_DRIVER_GENERIC | AZX_DCAPS_PRESET_ATI_HDMI }, { 0, } }; MODULE_DEVICE_TABLE(pci, azx_ids); 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..d694e9d4921d 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; @@ -511,9 +506,11 @@ static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, hda_nid_t hp) { struct ad198x_spec *spec = codec->spec; - snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, + if (snd_hda_query_pin_caps(codec, front) & AC_PINCAP_EAPD) + snd_hda_codec_write(codec, front, 0, AC_VERB_SET_EAPD_BTLENABLE, !spec->inv_eapd ? 0x00 : 0x02); - snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, + if (snd_hda_query_pin_caps(codec, hp) & AC_PINCAP_EAPD) + snd_hda_codec_write(codec, hp, 0, AC_VERB_SET_EAPD_BTLENABLE, !spec->inv_eapd ? 0x00 : 0x02); } @@ -529,6 +526,10 @@ static void ad198x_power_eapd(struct hda_codec *codec) case 0x11d4184a: case 0x11d4194a: case 0x11d4194b: + case 0x11d41988: + case 0x11d4198b: + case 0x11d4989a: + case 0x11d4989b: ad198x_power_eapd_write(codec, 0x12, 0x11); break; case 0x11d41981: @@ -538,15 +539,15 @@ static void ad198x_power_eapd(struct hda_codec *codec) case 0x11d41986: ad198x_power_eapd_write(codec, 0x1b, 0x1a); break; - case 0x11d41988: - case 0x11d4198b: - case 0x11d4989a: - case 0x11d4989b: - ad198x_power_eapd_write(codec, 0x29, 0x22); - break; } } +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,10 +3155,11 @@ 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), + SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG), SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG), {} }; @@ -3342,21 +3344,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 +3368,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 +3412,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 +3425,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 +3471,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 +3543,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 +3557,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 +3567,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 +3613,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 +3631,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 +3682,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 +3724,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 +3789,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 +3798,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 +3809,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 +3861,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 +3916,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 +3949,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 +3977,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 +4097,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 +4128,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 +4183,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 +4200,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 +4221,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 +4264,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 +4290,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 +4346,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 +4398,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 +4477,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 +4616,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 +4643,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 +4654,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 +4696,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 +4708,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 +4721,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 +4735,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 +4752,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 +4762,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 +4772,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 +4781,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 +4850,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 +4947,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..694b9daf691f 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), @@ -3036,8 +3098,11 @@ static struct snd_pci_quirk cxt5066_cfg_tbl[] = { SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo Thinkpad", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21da, "Lenovo X220", CXT5066_THINKPAD), SND_PCI_QUIRK(0x17aa, 0x21db, "Lenovo X220-tablet", CXT5066_THINKPAD), + SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo U350", CXT5066_ASUS), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo G560", CXT5066_ASUS), + SND_PCI_QUIRK(0x17aa, 0x3938, "Lenovo G565", CXT5066_AUTO), SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo", CXT5066_IDEAPAD), /* Fallback for Lenovos without dock mic */ + SND_PCI_QUIRK(0x1b0a, 0x2092, "CyberpowerPC Gamer Xplorer N57001", CXT5066_AUTO), {} }; @@ -3046,6 +3111,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 +3150,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 +3267,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 +3430,349 @@ 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_type != AUTO_PIN_SPEAKER_OUT && + 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 = 1; + + /* turn on HP EAPD when HP jacks are present */ + if (spec->auto_mute) + on = spec->hp_present; + cx_auto_turn_eapd(codec, cfg->hp_outs, cfg->hp_pins, on); + /* mute speakers in auto-mode if HP or LO jacks are plugged */ + if (spec->auto_mute) + on = !(spec->hp_present || + (spec->detect_line && spec->line_present)); + 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->auto_mute) { + /* mute LO in auto-mode when HP jack is present */ + if (cfg->line_out_type == AUTO_PIN_SPEAKER_OUT || + spec->automute_lines) + on = !spec->hp_present; + else + on = 1; + } + 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; } - 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); + 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; } - 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); + 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; + } } + 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; + int changed = 1; + + if (!imux->num_items) + return 0; + if (idx >= imux->num_items) + idx = imux->num_items - 1; + if (spec->cur_mux[0] == idx) + changed = 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 changed; +} + +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 +3781,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 +3792,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 < ARRAY_SIZE(pset); 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 +3838,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 +3934,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 +3955,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 +3990,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 +4049,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 +4099,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 +4127,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 +4148,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 +4175,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]; - - 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; + 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; + + 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 +4308,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 +4347,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 +4374,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..bd0ae697f9c4 100644 --- a/sound/pci/hda/patch_hdmi.c +++ b/sound/pci/hda/patch_hdmi.c @@ -33,6 +33,7 @@ #include <linux/slab.h> #include <linux/moduleparam.h> #include <sound/core.h> +#include <sound/jack.h> #include "hda_codec.h" #include "hda_local.h" @@ -47,8 +48,8 @@ MODULE_PARM_DESC(static_hdmi_pcm, "Don't restrict PCM parameters per ELD info"); * * The HDA correspondence of pipes/ports are converter/pin nodes. */ -#define MAX_HDMI_CVTS 3 -#define MAX_HDMI_PINS 3 +#define MAX_HDMI_CVTS 4 +#define MAX_HDMI_PINS 4 struct hdmi_spec { int num_cvts; @@ -76,11 +77,7 @@ struct hdmi_spec { * ati/nvhdmi specific */ struct hda_multi_out multiout; - struct hda_pcm_stream *pcm_playback; - - /* misc flags */ - /* PD bit indicates only the update, not the current state */ - unsigned int old_pin_detect:1; + const struct hda_pcm_stream *pcm_playback; }; @@ -299,13 +296,6 @@ static int hda_node_index(hda_nid_t *nids, hda_nid_t nid) return -EINVAL; } -static void hdmi_get_show_eld(struct hda_codec *codec, hda_nid_t pin_nid, - struct hdmi_eld *eld) -{ - if (!snd_hdmi_get_eld(eld, codec, pin_nid)) - snd_hdmi_show_eld(eld); -} - #ifdef BE_PARANOID static void hdmi_get_dip_index(struct hda_codec *codec, hda_nid_t pin_nid, int *packet_index, int *byte_index) @@ -693,33 +683,20 @@ static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res) { struct hdmi_spec *spec = codec->spec; - int tag = res >> AC_UNSOL_RES_TAG_SHIFT; - int pind = !!(res & AC_UNSOL_RES_PD); + int pin_nid = res >> AC_UNSOL_RES_TAG_SHIFT; + int pd = !!(res & AC_UNSOL_RES_PD); int eldv = !!(res & AC_UNSOL_RES_ELDV); int index; printk(KERN_INFO "HDMI hot plug event: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", - tag, pind, eldv); + pin_nid, pd, eldv); - index = hda_node_index(spec->pin, tag); + index = hda_node_index(spec->pin, pin_nid); if (index < 0) return; - if (spec->old_pin_detect) { - if (pind) - hdmi_present_sense(codec, tag, &spec->sink_eld[index]); - pind = spec->sink_eld[index].monitor_present; - } - - spec->sink_eld[index].monitor_present = pind; - spec->sink_eld[index].eld_valid = eldv; - - if (pind && eldv) { - hdmi_get_show_eld(codec, spec->pin[index], - &spec->sink_eld[index]); - /* TODO: do real things about ELD */ - } + hdmi_present_sense(codec, pin_nid, &spec->sink_eld[index]); } static void hdmi_non_intrinsic_event(struct hda_codec *codec, unsigned int res) @@ -900,18 +877,39 @@ static int hdmi_read_pin_conn(struct hda_codec *codec, hda_nid_t pin_nid) static void hdmi_present_sense(struct hda_codec *codec, hda_nid_t pin_nid, struct hdmi_eld *eld) { + /* + * Always execute a GetPinSense verb here, even when called from + * hdmi_intrinsic_event; for some NVIDIA HW, the unsolicited + * response's PD bit is not the real PD value, but indicates that + * the real PD value changed. An older version of the HD-audio + * specification worked this way. Hence, we just ignore the data in + * the unsolicited response to avoid custom WARs. + */ int present = snd_hda_pin_sense(codec, pin_nid); + memset(eld, 0, sizeof(*eld)); + eld->monitor_present = !!(present & AC_PINSENSE_PRESENCE); - eld->eld_valid = !!(present & AC_PINSENSE_ELDV); + if (eld->monitor_present) + eld->eld_valid = !!(present & AC_PINSENSE_ELDV); + else + eld->eld_valid = 0; + + printk(KERN_INFO + "HDMI status: Pin=%d Presence_Detect=%d ELD_Valid=%d\n", + pin_nid, eld->monitor_present, eld->eld_valid); + + if (eld->eld_valid) + if (!snd_hdmi_get_eld(eld, codec, pin_nid)) + snd_hdmi_show_eld(eld); - if (present & AC_PINSENSE_ELDV) - hdmi_get_show_eld(codec, pin_nid, eld); + snd_hda_input_jack_report(codec, 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 +917,11 @@ 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; + hdmi_present_sense(codec, pin_nid, &spec->sink_eld[spec->num_pins]); spec->pin[spec->num_pins] = pin_nid; @@ -1024,6 +1027,7 @@ static char *generic_hdmi_pcm_names[MAX_HDMI_CVTS] = { "HDMI 0", "HDMI 1", "HDMI 2", + "HDMI 3", }; /* @@ -1044,7 +1048,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 +1124,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 +1174,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 +1440,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 +1455,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,32 +1470,20 @@ 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, .free = generic_hdmi_free, }; -static int patch_nvhdmi_8ch_89(struct hda_codec *codec) -{ - struct hdmi_spec *spec; - int err = patch_generic_hdmi(codec); - - if (err < 0) - return err; - spec = codec->spec; - spec->old_pin_detect = 1; - return 0; -} - static int patch_nvhdmi_2ch(struct hda_codec *codec) { struct hdmi_spec *spec; @@ -1504,7 +1497,6 @@ static int patch_nvhdmi_2ch(struct hda_codec *codec) spec->multiout.num_dacs = 0; /* no analog */ spec->multiout.max_channels = 2; spec->multiout.dig_out_nid = nvhdmi_master_con_nid_7x; - spec->old_pin_detect = 1; spec->num_cvts = 1; spec->cvt[0] = nvhdmi_master_con_nid_7x; spec->pcm_playback = &nvhdmi_pcm_playback_2ch; @@ -1568,7 +1560,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 +1572,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 +1591,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 +1626,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 }, @@ -1647,28 +1639,28 @@ static struct hda_codec_preset snd_hda_preset_hdmi[] = { { .id = 0x10de0005, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, { .id = 0x10de0006, .name = "MCP77/78 HDMI", .patch = patch_nvhdmi_8ch_7x }, { .id = 0x10de0007, .name = "MCP79/7A HDMI", .patch = patch_nvhdmi_8ch_7x }, -{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, +{ .id = 0x10de000a, .name = "GPU 0a HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de000b, .name = "GPU 0b HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de000c, .name = "MCP89 HDMI", .patch = patch_generic_hdmi }, +{ .id = 0x10de000d, .name = "GPU 0d HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0010, .name = "GPU 10 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0011, .name = "GPU 11 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0012, .name = "GPU 12 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0013, .name = "GPU 13 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0014, .name = "GPU 14 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0015, .name = "GPU 15 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0016, .name = "GPU 16 HDMI/DP", .patch = patch_generic_hdmi }, /* 17 is known to be absent */ -{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, -{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_nvhdmi_8ch_89 }, +{ .id = 0x10de0018, .name = "GPU 18 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0019, .name = "GPU 19 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de001a, .name = "GPU 1a HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de001b, .name = "GPU 1b HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de001c, .name = "GPU 1c HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0040, .name = "GPU 40 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0041, .name = "GPU 41 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0042, .name = "GPU 42 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0043, .name = "GPU 43 HDMI/DP", .patch = patch_generic_hdmi }, +{ .id = 0x10de0044, .name = "GPU 44 HDMI/DP", .patch = patch_generic_hdmi }, { .id = 0x10de0067, .name = "MCP67 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x10de8001, .name = "MCP73 HDMI", .patch = patch_nvhdmi_2ch }, { .id = 0x80860054, .name = "IbexPeak HDMI", .patch = patch_generic_hdmi }, @@ -1677,6 +1669,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 +1715,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 52928d9a72da..61a774b3d3cb 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,123 @@ 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) +{ + struct alc_spec *spec = codec->spec; + int on; + + /* Control HP pins/amps depending on master_mute state; + * in general, HP pins/amps control should be enabled in all cases, + * but currently set only for master_mute, just to be safe + */ + do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), + spec->autocfg.hp_pins, spec->master_mute, true); + + 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) { - alc_automute_speaker(codec, 1); + 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 +1233,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 +1251,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 +1277,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 +1305,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 +1318,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 +1361,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 +1413,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 +1457,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 +1591,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 +1642,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 */ + if (dock && !is_jack_detectable(codec, dock)) return; /* no unsol support */ - snd_printdd("realtek: Enable auto-mic switch on NID 0x%x/0x%x\n", - ext, fixed); + 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 +1873,6 @@ do_sku: return 1; spec->autocfg.hp_pins[0] = nid; } - - alc_init_auto_hp(codec); - alc_init_auto_mic(codec); return 1; } @@ -1598,9 +1885,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); } /* @@ -1704,11 +1992,11 @@ static void alc_apply_fixup(struct hda_codec *codec, int action) codec->chip_name, fix->type); break; } - if (!fix[id].chained) + if (!fix->chained) break; if (++depth > 10) break; - id = fix[id].chain_id; + id = fix->chain_id; } } @@ -1842,7 +2130,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 +2145,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 +2160,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 +2175,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 +2187,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 +2198,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 +2231,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 +2241,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 +2259,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 +2290,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 +2320,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 +2350,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 +2396,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 +2417,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 +2440,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 +2472,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 +2494,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 +2516,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 +2543,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 +2555,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 +2567,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 +2579,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 +2591,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 +2605,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 +2613,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 +2625,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 +2636,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 +2646,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 +2796,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 +2826,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 +2834,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 +2842,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 +2864,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 +2880,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 +2939,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 +2972,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 +3002,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 +3019,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 +3039,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 +3073,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 +3094,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 +3121,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 +3135,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 +3162,6 @@ static const char * const alc_slave_vols[] = { "Speaker Playback Volume", "Mono Playback Volume", "Line-Out Playback Volume", - "PCM Playback Volume", NULL, }; @@ -2893,7 +3176,6 @@ static const char * const alc_slave_sws[] = { "Mono Playback Switch", "IEC958 Playback Switch", "Line-Out Playback Switch", - "PCM Playback Switch", NULL, }; @@ -2914,7 +3196,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 +3207,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 +3244,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 +3283,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 +3361,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 +3412,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 +3450,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 +3494,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 +3515,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 +3534,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 +3564,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 +3602,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 +3631,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 +3654,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 +3675,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 +3686,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 +3712,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 +3751,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 +3785,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 +3813,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 +3851,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 +3866,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 +3918,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 +3956,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 +3972,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 +3983,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 +4008,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 +4042,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 +4056,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 +4064,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 +4091,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 +4115,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 +4129,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 +4301,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 +4314,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 +4326,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 +4351,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 +4364,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 +4372,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 +4466,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 +4485,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 +4522,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 +4538,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 +4549,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 +4584,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 +4601,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 +4611,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 +4656,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 +4686,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 +4747,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 +4788,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 +4872,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 +4952,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 +5070,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 +5161,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 +5176,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 +5201,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 +5218,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 +5260,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 +5336,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 +5348,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 +5359,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 +5376,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 +5390,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 +5664,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 +5674,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); @@ -5396,6 +5686,9 @@ static int alc880_parse_auto_config(struct hda_codec *codec) 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); if (err < 0) return err; @@ -5467,6 +5760,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 +5793,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 +5835,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 +5852,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 +5878,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,9 +5944,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), {} }; @@ -5752,17 +6056,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, }; @@ -5770,7 +6074,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 }; @@ -5778,7 +6082,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 }, @@ -5794,7 +6098,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 = { @@ -5818,7 +6122,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 = { @@ -5841,7 +6145,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 = { @@ -5865,7 +6169,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 }, }; @@ -5879,7 +6183,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), @@ -5889,7 +6193,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), @@ -5902,21 +6206,9 @@ 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); + update_speakers(codec); } static int alc260_hp_master_sw_get(struct snd_kcontrol *kcontrol, @@ -5924,7 +6216,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; } @@ -5933,20 +6225,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", @@ -5954,7 +6242,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), @@ -5966,26 +6253,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); -} - -static void alc260_hp_unsol_event(struct hda_codec *codec, unsigned int res) -{ - if ((res >> 26) == ALC880_HP_EVENT) - alc260_hp_automute(codec); + 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 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", @@ -5993,7 +6277,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), @@ -6006,7 +6289,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), @@ -6016,7 +6310,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), @@ -6025,7 +6319,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), @@ -6033,49 +6327,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), @@ -6112,7 +6384,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), @@ -6133,7 +6405,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), @@ -6146,7 +6418,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), @@ -6163,7 +6435,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), @@ -6180,7 +6452,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 */ @@ -6244,7 +6516,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 */ @@ -6294,7 +6566,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 */ @@ -6347,7 +6619,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 */ @@ -6429,7 +6701,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. @@ -6517,7 +6789,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. @@ -6597,7 +6869,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}, @@ -6607,7 +6879,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}, @@ -6649,7 +6921,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}, @@ -6667,17 +6939,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 = { @@ -6704,7 +6976,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), @@ -6768,7 +7040,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}, @@ -6906,7 +7178,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) { @@ -7004,7 +7276,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 */ @@ -7049,7 +7321,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); @@ -7094,7 +7366,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 }, @@ -7121,7 +7393,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), {} }; @@ -7145,7 +7417,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), @@ -7169,7 +7441,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 }, @@ -7194,8 +7466,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, @@ -7209,8 +7482,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, @@ -7224,8 +7498,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 }, @@ -7383,6 +7658,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; @@ -7410,12 +7686,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 }; @@ -7425,20 +7701,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 }, @@ -7450,7 +7726,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 }, @@ -7459,7 +7735,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 }, @@ -7468,7 +7744,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 }, @@ -7476,7 +7752,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 }, @@ -7486,7 +7762,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 }, @@ -7494,7 +7770,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 }, @@ -7504,7 +7780,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 }, @@ -7512,7 +7788,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 }, @@ -7521,7 +7797,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 }, @@ -7529,7 +7805,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 }, @@ -7540,7 +7816,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 }, @@ -7551,14 +7827,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 }, @@ -7569,7 +7845,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 }, @@ -7581,7 +7857,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 }, @@ -7591,7 +7867,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 }, @@ -7602,7 +7878,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 }, @@ -7614,7 +7890,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 }, @@ -7627,7 +7903,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 }, @@ -7638,7 +7914,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 }, @@ -7648,7 +7924,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 }, @@ -7659,7 +7935,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 }, @@ -7667,7 +7943,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 }, }; @@ -7675,7 +7951,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 }, }; @@ -7686,7 +7962,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)}, @@ -7696,7 +7972,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 }, @@ -7705,7 +7981,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 }, }; @@ -7715,7 +7991,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 */ @@ -7727,14 +8003,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 }, }; @@ -7744,7 +8020,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 }, @@ -7757,7 +8033,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 }, @@ -7771,7 +8047,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 }, @@ -7786,7 +8062,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 }, @@ -7799,7 +8075,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 }, @@ -7810,7 +8086,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 }, @@ -7821,7 +8097,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 }, @@ -7833,7 +8109,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 }, @@ -7843,7 +8119,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 }, @@ -7852,7 +8128,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 }, @@ -7865,7 +8141,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 }, @@ -7878,7 +8154,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 }, @@ -7889,7 +8165,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 }, @@ -7898,7 +8174,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 }, @@ -7909,7 +8185,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 }, @@ -7917,7 +8193,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 }, }; @@ -7926,7 +8202,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), @@ -7953,14 +8229,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), @@ -7975,7 +8251,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), @@ -7993,7 +8269,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), @@ -8008,14 +8284,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), @@ -8028,7 +8304,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), @@ -8048,7 +8324,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), @@ -8065,7 +8341,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), @@ -8079,7 +8355,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", @@ -8090,7 +8366,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)}, @@ -8152,7 +8428,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)}, @@ -8164,26 +8440,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)}, @@ -8242,7 +8518,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)}, @@ -8251,7 +8527,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}, { } @@ -8261,7 +8537,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), @@ -8274,7 +8550,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)}, @@ -8326,7 +8602,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}, @@ -8375,7 +8651,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}, @@ -8422,7 +8698,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)}, @@ -8445,7 +8721,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)}, @@ -8509,7 +8785,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}, @@ -8564,14 +8840,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}, @@ -8599,6 +8875,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 @@ -8611,6 +8889,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; } @@ -8621,6 +8901,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) @@ -8630,9 +8912,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)}, @@ -8651,7 +8935,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); } @@ -8662,6 +8946,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) @@ -8670,7 +8956,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)}, @@ -8688,7 +8974,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)}, @@ -8749,13 +9035,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 */ @@ -8795,7 +9081,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 */ @@ -8804,7 +9090,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 */ @@ -8813,7 +9099,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 */ @@ -8822,7 +9108,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 */ @@ -8830,14 +9116,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}, @@ -8846,7 +9132,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), @@ -8863,7 +9149,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), @@ -8877,7 +9163,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), @@ -8891,7 +9177,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), @@ -8908,7 +9194,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), @@ -8931,7 +9217,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), @@ -8955,7 +9241,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), @@ -8979,7 +9265,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), @@ -9002,7 +9288,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), @@ -9023,7 +9309,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), @@ -9039,7 +9325,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), @@ -9048,7 +9334,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), @@ -9060,7 +9346,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), @@ -9073,7 +9359,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), @@ -9083,7 +9369,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)}, @@ -9107,9 +9393,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), @@ -9121,7 +9409,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), @@ -9134,7 +9422,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), @@ -9159,7 +9447,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), @@ -9185,7 +9473,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), @@ -9195,7 +9483,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), @@ -9204,7 +9492,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), @@ -9213,7 +9501,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), @@ -9225,7 +9513,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), { @@ -9240,7 +9528,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", @@ -9259,9 +9547,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}, @@ -9276,7 +9566,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}, @@ -9292,7 +9582,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}, @@ -9307,7 +9597,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}, @@ -9321,7 +9611,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)}, @@ -9350,14 +9640,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}, @@ -9365,7 +9655,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}, @@ -9374,7 +9664,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)}, @@ -9387,7 +9677,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)}, @@ -9399,12 +9689,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}, @@ -9423,9 +9713,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) */ @@ -9436,7 +9728,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 }, @@ -9447,7 +9739,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 }, @@ -9459,7 +9751,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 }, @@ -9469,39 +9761,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) -{ - unsigned int present = snd_hda_jack_detect(codec, 0x1b); - - 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) +static void alc888_lenovo_ms7195_setup(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); -} + struct alc_spec *spec = codec->spec; -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 */ @@ -9511,6 +9785,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 */ @@ -9523,11 +9799,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); } @@ -9539,7 +9817,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; } } @@ -9551,6 +9829,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) @@ -9559,33 +9839,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; - - 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); -} + struct alc_spec *spec = codec->spec; -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 */ @@ -9596,9 +9864,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}, @@ -9625,6 +9895,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) @@ -9637,6 +9909,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) @@ -9646,9 +9920,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)}, @@ -9671,9 +9947,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)}, @@ -9692,10 +9970,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 */ @@ -9741,11 +10019,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, }; @@ -9804,7 +10082,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), @@ -9863,6 +10141,7 @@ static struct snd_pci_quirk alc882_cfg_tbl[] = { SND_PCI_QUIRK(0x1071, 0x8258, "Evesham Voyaeger", ALC883_LAPTOP_EAPD), SND_PCI_QUIRK(0x10f1, 0x2350, "TYAN-S2350", ALC888_6ST_DELL), SND_PCI_QUIRK(0x108e, 0x534d, NULL, ALC883_3ST_6ch), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte P35 DS3R", ALC882_6ST_DIG), SND_PCI_QUIRK(0x1462, 0x0349, "MSI", ALC883_TARGA_2ch_DIG), SND_PCI_QUIRK(0x1462, 0x040d, "MSI", ALC883_TARGA_2ch_DIG), @@ -9930,7 +10209,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), @@ -9957,7 +10236,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, @@ -10013,9 +10292,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 }, @@ -10029,9 +10308,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 }, @@ -10044,9 +10323,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 }, @@ -10059,9 +10338,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 }, @@ -10085,7 +10364,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, }, @@ -10100,9 +10379,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 }, @@ -10118,7 +10397,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, }, @@ -10212,8 +10491,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] = { @@ -10233,7 +10512,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] = { @@ -10322,9 +10601,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, @@ -10344,9 +10623,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 }, @@ -10363,9 +10642,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, @@ -10386,9 +10665,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 @@ -10409,9 +10688,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, @@ -10438,9 +10717,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 }, @@ -10490,8 +10769,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 }, @@ -10502,9 +10782,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 }, @@ -10516,8 +10796,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}, @@ -10528,9 +10809,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 }, @@ -10541,9 +10822,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 }, @@ -10555,9 +10836,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 }, @@ -10567,9 +10848,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 }, @@ -10581,9 +10862,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 }, @@ -10600,9 +10881,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 }, @@ -10614,9 +10895,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 }, @@ -10684,9 +10965,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, }, }; @@ -10699,7 +10980,6 @@ enum { PINFIX_LENOVO_Y530, PINFIX_PB_M5210, PINFIX_ACER_ASPIRE_7736, - PINFIX_GIGABYTE_880GM, }; static const struct alc_fixup alc882_fixups[] = { @@ -10731,21 +11011,13 @@ static const struct alc_fixup alc882_fixups[] = { .type = ALC_FIXUP_SKU, .v.sku = ALC_FIXUP_SKU_IGNORE, }, - [PINFIX_GIGABYTE_880GM] = { - .type = ALC_FIXUP_PINS, - .v.pins = (const struct alc_pincfg[]) { - { 0x14, 0x1114410 }, /* set as speaker */ - { } - } - }, }; -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), SND_PCI_QUIRK(0x1025, 0x0296, "Acer Aspire 7736z", PINFIX_ACER_ASPIRE_7736), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", PINFIX_GIGABYTE_880GM), {} }; @@ -10849,6 +11121,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) @@ -10928,7 +11205,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, @@ -10941,6 +11218,9 @@ static int alc882_parse_auto_config(struct hda_codec *codec) 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); if (err < 0) return err; @@ -11142,14 +11422,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), @@ -11170,71 +11450,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; - - /* 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); -} +#define alc262_hp_master_update alc260_hp_master_update -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); -} - -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); + 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_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 \ { \ @@ -11251,7 +11490,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), @@ -11275,7 +11514,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), @@ -11295,7 +11534,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), @@ -11309,9 +11548,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), @@ -11322,7 +11563,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}, @@ -11330,7 +11571,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), @@ -11340,7 +11581,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}, @@ -11354,7 +11595,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 }, @@ -11362,44 +11603,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 \ { \ @@ -11416,7 +11622,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), @@ -11433,7 +11639,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), @@ -11450,28 +11656,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) @@ -11480,10 +11672,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), @@ -11493,7 +11687,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), @@ -11504,7 +11698,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), @@ -11520,7 +11714,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}, @@ -11542,6 +11736,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; } @@ -11551,7 +11747,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 */ @@ -11627,13 +11823,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}, @@ -11643,7 +11839,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 @@ -11653,7 +11849,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), @@ -11662,7 +11858,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}, @@ -11685,6 +11881,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; } /* @@ -11694,7 +11892,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), @@ -11707,7 +11905,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}, @@ -11728,9 +11926,9 @@ static struct hda_verb alc262_nec_verbs[] = { * 0x1b = port replicator headphone out */ -#define ALC_HP_EVENT 0x37 +#define ALC_HP_EVENT ALC880_HP_EVENT -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}, @@ -11738,20 +11936,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 }, @@ -11760,7 +11958,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 }, @@ -11771,7 +11969,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 }, @@ -11781,44 +11979,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), @@ -11827,78 +12000,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, @@ -11916,30 +12026,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), @@ -11952,7 +12058,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), @@ -11965,13 +12071,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}, @@ -11981,7 +12087,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), @@ -11991,7 +12097,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)}, @@ -12054,7 +12160,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 }, @@ -12080,7 +12186,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), { @@ -12155,9 +12261,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++) { @@ -12211,7 +12317,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 */ @@ -12272,7 +12378,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 */ @@ -12376,7 +12482,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 */ @@ -12472,7 +12578,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 }, @@ -12508,7 +12614,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), {} }; @@ -12531,7 +12637,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); @@ -12616,7 +12722,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", @@ -12668,7 +12774,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 }, @@ -12689,9 +12795,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 }, @@ -12703,9 +12809,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 }, @@ -12718,8 +12824,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 }, @@ -12730,8 +12837,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 }, @@ -12742,8 +12850,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, @@ -12755,8 +12864,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 }, @@ -12799,9 +12909,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 }, @@ -12813,9 +12923,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 }, @@ -12844,7 +12954,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 }, @@ -12881,9 +12993,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 }, @@ -12895,9 +13007,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, }, }; @@ -13018,6 +13130,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 @@ -13034,24 +13147,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), @@ -13063,7 +13176,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), @@ -13075,7 +13188,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), @@ -13084,27 +13197,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), @@ -13113,66 +13226,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), @@ -13180,24 +13271,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}, @@ -13207,7 +13297,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}, @@ -13219,53 +13309,15 @@ 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 = 1; + spec->automute_mode = ALC_AUTOMUTE_AMP; spec->ext_mic.pin = 0x18; spec->ext_mic.mux_idx = 0; spec->int_mic.pin = 0x12; @@ -13273,13 +13325,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), @@ -13290,7 +13336,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}, @@ -13310,9 +13356,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), @@ -13324,7 +13372,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}, { } @@ -13340,12 +13388,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}, @@ -13393,7 +13443,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}, @@ -13419,20 +13469,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), @@ -13441,7 +13491,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 }, @@ -13451,7 +13501,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 }, @@ -13460,7 +13510,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 }, @@ -13470,7 +13520,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), @@ -13549,7 +13599,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) @@ -13722,7 +13772,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); @@ -13802,7 +13852,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), @@ -13811,6 +13861,7 @@ static struct snd_pci_quirk alc268_cfg_tbl[] = { SND_PCI_QUIRK(0x1025, 0x015b, "Acer Aspire One", ALC268_ACER_ASPIRE_ONE), SND_PCI_QUIRK(0x1028, 0x0253, "Dell OEM", ALC268_DELL), + SND_PCI_QUIRK(0x1028, 0x02b0, "Dell Inspiron 910", ALC268_AUTO), SND_PCI_QUIRK_MASK(0x1028, 0xfff0, 0x02b0, "Dell Inspiron Mini9/Vostro A90", ALC268_DELL), /* almost compatible with toshiba but with optional digital outs; @@ -13827,7 +13878,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", @@ -13835,7 +13886,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 }, @@ -13881,9 +13932,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, @@ -13899,8 +13950,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, @@ -13916,8 +13968,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, @@ -13933,9 +13986,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, @@ -13969,8 +14022,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] = { @@ -14092,6 +14146,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); @@ -14105,32 +14160,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), @@ -14146,7 +14201,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), { @@ -14167,7 +14222,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), { @@ -14191,7 +14246,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), @@ -14199,7 +14254,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), @@ -14207,14 +14262,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), @@ -14222,14 +14277,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), @@ -14237,7 +14292,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), @@ -14247,7 +14302,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}, @@ -14257,7 +14312,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}, @@ -14274,15 +14329,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); @@ -14295,34 +14342,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) { @@ -14371,6 +14392,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; @@ -14384,13 +14408,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 }, @@ -14401,7 +14436,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 }, @@ -14411,7 +14446,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 }, @@ -14422,7 +14457,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 }, @@ -14433,7 +14468,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}, @@ -14447,42 +14482,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; @@ -14495,6 +14502,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; @@ -14507,6 +14517,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; @@ -14519,6 +14532,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; @@ -14526,16 +14542,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 */ @@ -14578,7 +14588,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 */ @@ -14636,7 +14646,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, @@ -14649,7 +14659,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, @@ -14733,7 +14743,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); @@ -14803,7 +14813,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); @@ -14814,25 +14823,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) { @@ -14868,6 +14869,23 @@ static void alc269_fixup_hweq(struct hda_codec *codec, alc_write_coef_idx(codec, 0x1e, coef | 0x80); } +static void alc271_fixup_dmic(struct hda_codec *codec, + const struct alc_fixup *fix, int action) +{ + static const struct hda_verb verbs[] = { + {0x20, AC_VERB_SET_COEF_INDEX, 0x0d}, + {0x20, AC_VERB_SET_PROC_COEF, 0x4000}, + {} + }; + unsigned int cfg; + + if (strcmp(codec->chip_name, "ALC271X")) + return; + cfg = snd_hda_codec_get_pincfg(codec, 0x12); + if (get_defcfg_connect(cfg) == AC_JACK_PORT_FIXED) + snd_hda_sequence_write(codec, verbs); +} + enum { ALC269_FIXUP_SONY_VAIO, ALC275_FIXUP_SONY_VAIO_GPIO2, @@ -14876,6 +14894,7 @@ enum { ALC269_FIXUP_ASUS_G73JW, ALC269_FIXUP_LENOVO_EAPD, ALC275_FIXUP_SONY_HWEQ, + ALC271_FIXUP_DMIC, }; static const struct alc_fixup alc269_fixups[] = { @@ -14929,15 +14948,20 @@ static const struct alc_fixup alc269_fixups[] = { .v.func = alc269_fixup_hweq, .chained = true, .chain_id = ALC275_FIXUP_SONY_VAIO_GPIO2 - } + }, + [ALC271_FIXUP_DMIC] = { + .type = ALC_FIXUP_FUNC, + .v.func = alc271_fixup_dmic, + }, }; -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), SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), + SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), SND_PCI_QUIRK(0x17aa, 0x21b8, "Thinkpad Edge 14", ALC269_FIXUP_SKU_IGNORE), @@ -14962,7 +14986,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", @@ -15020,7 +15044,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 }, @@ -15054,9 +15078,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 }, @@ -15068,9 +15092,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 }, @@ -15082,9 +15106,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 }, @@ -15096,9 +15120,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 }, @@ -15110,9 +15134,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 }, @@ -15124,6 +15148,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] = { @@ -15169,14 +15194,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; } @@ -15297,14 +15329,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 @@ -15325,7 +15355,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 @@ -15344,7 +15374,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)*/ @@ -15361,30 +15391,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 @@ -15400,7 +15430,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 }, */ @@ -15418,14 +15448,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), @@ -15448,7 +15478,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), @@ -15479,7 +15509,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), @@ -15488,7 +15518,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), @@ -15519,7 +15549,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), @@ -15551,7 +15581,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), { } @@ -15560,7 +15590,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 */ @@ -15626,7 +15656,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 */ @@ -15687,7 +15717,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 */ @@ -15749,7 +15779,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 */ @@ -15815,7 +15845,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 */ { } @@ -15824,7 +15854,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 */ @@ -15873,7 +15903,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}, { } @@ -15906,26 +15936,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 }, @@ -15975,7 +16005,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; } @@ -15998,11 +16028,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; @@ -16135,7 +16169,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); @@ -16147,6 +16181,9 @@ static int alc861_parse_auto_config(struct hda_codec *codec) 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); if (err < 0) return err; @@ -16191,7 +16228,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 }, @@ -16216,7 +16253,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), @@ -16240,7 +16277,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 }, @@ -16363,7 +16400,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), {} }; @@ -16456,7 +16493,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 }; @@ -16468,21 +16505,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 }, @@ -16492,7 +16529,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 }, @@ -16500,7 +16537,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 }, @@ -16511,14 +16548,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 }, @@ -16529,7 +16566,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 }, @@ -16537,12 +16574,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", @@ -16556,7 +16593,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), @@ -16592,7 +16629,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), @@ -16615,7 +16652,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), @@ -16639,7 +16676,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), @@ -16656,7 +16693,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), @@ -16672,7 +16709,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 */ @@ -16722,7 +16759,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 */ @@ -16753,7 +16790,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 */ @@ -16794,18 +16831,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)}, @@ -16819,11 +16856,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); } @@ -16835,12 +16874,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}, @@ -16892,6 +16931,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 @@ -16920,7 +16961,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), @@ -16939,7 +16980,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, @@ -17016,9 +17057,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 }, @@ -17029,9 +17070,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 }, @@ -17130,11 +17171,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( @@ -17247,7 +17292,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); @@ -17259,6 +17304,9 @@ static int alc861vd_parse_auto_config(struct hda_codec *codec) 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); if (err < 0) return err; @@ -17327,7 +17375,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), {} }; @@ -17410,6 +17458,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; @@ -17432,32 +17481,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 }, @@ -17467,7 +17516,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 }, @@ -17475,7 +17524,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 }, @@ -17485,7 +17534,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 }, @@ -17511,14 +17560,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 }, @@ -17529,7 +17578,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 }, @@ -17539,7 +17588,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 }, }; @@ -17547,7 +17596,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 }, @@ -17557,14 +17606,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 }, }; @@ -17573,7 +17622,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), @@ -17597,7 +17646,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), @@ -17612,7 +17661,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), @@ -17633,7 +17682,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), @@ -17646,7 +17695,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, @@ -17660,7 +17709,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), @@ -17674,7 +17723,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), @@ -17683,7 +17732,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), @@ -17692,7 +17741,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), @@ -17700,7 +17749,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), @@ -17710,7 +17759,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), @@ -17721,7 +17770,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), @@ -17731,7 +17780,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), @@ -17741,7 +17790,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), @@ -17752,7 +17801,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), @@ -17761,7 +17810,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), @@ -17770,7 +17819,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), @@ -17781,7 +17830,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), @@ -17791,7 +17840,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), @@ -17805,7 +17854,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), @@ -17819,7 +17868,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), @@ -17831,7 +17880,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), @@ -17840,7 +17889,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), @@ -17853,7 +17902,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), @@ -17865,7 +17914,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", @@ -17876,7 +17925,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}, @@ -17922,55 +17971,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)}, - /* 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 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 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}, @@ -17983,7 +18013,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 */ @@ -17994,7 +18024,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}, @@ -18006,7 +18036,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 */ @@ -18017,7 +18047,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}, @@ -18033,7 +18063,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}, @@ -18049,7 +18079,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 */ @@ -18064,7 +18094,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 */ @@ -18074,7 +18104,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}, @@ -18082,7 +18112,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}, @@ -18097,7 +18127,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}, @@ -18112,7 +18142,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}, @@ -18131,7 +18161,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}, @@ -18151,61 +18181,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; - - 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); -} + struct alc_spec *spec = codec->spec; -/* 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) @@ -18220,180 +18218,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; @@ -18401,18 +18243,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; @@ -18420,229 +18259,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) -{ - 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) +static void alc663_mode6_setup(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) -{ - switch (res >> 26) { - case ALC880_HP_EVENT: - alc663_two_hp_m8_speaker_automute(codec); - break; - case ALC880_MIC_EVENT: - alc_mic_automute(codec); - break; - } -} - -#define alc663_mode8_setup alc663_m51va_setup - -static void alc663_mode8_inithook(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) +static void alc663_mode8_setup(struct hda_codec *codec) { - alc663_g71v_front_automute(codec); - alc663_g71v_hp_automute(codec); - alc_mic_automute(codec); + 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; } -static void alc663_g50v_unsol_event(struct hda_codec *codec, - unsigned int res) +static void alc663_g71v_setup(struct hda_codec *codec) { - 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, @@ -18656,7 +18410,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), @@ -18691,7 +18445,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", @@ -18714,7 +18468,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), @@ -18782,6 +18536,8 @@ static struct snd_pci_quirk alc662_cfg_tbl[] = { ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1179, 0xff6e, "Toshiba NB20x", ALC662_AUTO), SND_PCI_QUIRK(0x144d, 0xca00, "Samsung NC10", ALC272_SAMSUNG_NC10), + SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte 945GCM-S2L", + ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x152d, 0x2304, "Quanta WH1", ALC663_ASUS_H13), SND_PCI_QUIRK(0x1565, 0x820f, "Biostar TA780G M2+", ALC662_3ST_6ch_DIG), SND_PCI_QUIRK(0x1631, 0xc10c, "PB RS65", ALC663_ASUS_M51VA), @@ -18794,10 +18550,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, @@ -18808,7 +18564,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, @@ -18820,7 +18576,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), @@ -18830,7 +18586,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, @@ -18841,104 +18597,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, @@ -18946,28 +18718,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, @@ -18975,14 +18749,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, @@ -18990,14 +18765,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, @@ -19005,14 +18781,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, @@ -19020,14 +18797,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, @@ -19035,14 +18813,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, @@ -19050,52 +18829,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, }, }; @@ -19105,45 +18889,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) -{ - 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; +static hda_nid_t alc_auto_mix_to_dac(struct hda_codec *codec, hda_nid_t nid) +{ + 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++) @@ -19165,10 +18983,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; } @@ -19204,15 +19022,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) { @@ -19258,7 +19084,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)) @@ -19268,7 +19094,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); @@ -19292,14 +19118,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; } } @@ -19356,11 +19189,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); @@ -19372,6 +19358,9 @@ static int alc662_parse_auto_config(struct hda_codec *codec) 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); if (err < 0) return err; @@ -19402,14 +19391,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; @@ -19455,7 +19436,7 @@ enum { ALC662_FIXUP_IDEAPAD, ALC272_FIXUP_MARIO, ALC662_FIXUP_CZC_P10T, - ALC662_FIXUP_GIGABYTE, + ALC662_FIXUP_SKU_IGNORE, }; static const struct alc_fixup alc662_fixups[] = { @@ -19484,20 +19465,17 @@ static const struct alc_fixup alc662_fixups[] = { {} } }, - [ALC662_FIXUP_GIGABYTE] = { - .type = ALC_FIXUP_PINS, - .v.pins = (const struct alc_pincfg[]) { - { 0x14, 0x1114410 }, /* set as speaker */ - { } - } + [ALC662_FIXUP_SKU_IGNORE] = { + .type = ALC_FIXUP_SKU, + .v.sku = ALC_FIXUP_SKU_IGNORE, }, }; -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), SND_PCI_QUIRK(0x144d, 0xc051, "Samsung R720", ALC662_FIXUP_IDEAPAD), - SND_PCI_QUIRK(0x1458, 0xa002, "Gigabyte", ALC662_FIXUP_GIGABYTE), SND_PCI_QUIRK(0x17aa, 0x38af, "Lenovo Ideapad Y550P", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x17aa, 0x3a0d, "Lenovo Ideapad Y550", ALC662_FIXUP_IDEAPAD), SND_PCI_QUIRK(0x1b35, 0x2206, "CZC P10T", ALC662_FIXUP_CZC_P10T), @@ -19611,6 +19589,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); @@ -19639,6 +19618,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 */ @@ -19646,12 +19634,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 @@ -19671,8 +19659,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) { @@ -19719,7 +19706,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, @@ -19730,7 +19717,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), @@ -19742,7 +19729,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), @@ -19752,7 +19739,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), @@ -19762,7 +19749,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 */ @@ -19771,7 +19758,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}, @@ -19809,20 +19796,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); } @@ -19859,7 +19848,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; @@ -19945,7 +19934,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); @@ -20003,12 +19992,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, @@ -20089,7 +20078,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 }, @@ -20098,6 +20088,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 }, @@ -20125,6 +20116,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 @@ again: 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 @@ again: 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 1371b57c11e8..c952582fb218 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: @@ -1280,10 +832,13 @@ static int via_hp_build(struct hda_codec *codec) knew->subdevice = HDA_SUBDEV_NID_FLAG | nid; knew->private_value = nid; - knew = via_clone_control(spec, &via_hp_mixer[1]); - if (knew == NULL) - return -ENOMEM; - knew->subdevice = side_mute_channel(spec); + nid = side_mute_channel(spec); + if (nid) { + knew = via_clone_control(spec, &via_hp_mixer[1]); + if (knew == NULL) + return -ENOMEM; + knew->subdevice = nid; + } return 0; } @@ -1292,14 +847,18 @@ static void notify_aa_path_ctls(struct hda_codec *codec) { int i; struct snd_ctl_elem_id id; - const char *labels[] = {"Mic", "Front Mic", "Line"}; + const char *labels[] = {"Mic", "Front Mic", "Line", "Rear Mic"}; + struct snd_kcontrol *ctl; memset(&id, 0, sizeof(id)); id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; for (i = 0; i < ARRAY_SIZE(labels); i++) { sprintf(id.name, "%s Playback Volume", labels[i]); - snd_ctl_notify(codec->bus->card, SNDRV_CTL_EVENT_MASK_VALUE, - &id); + ctl = snd_hda_find_mixer_ctl(codec, id.name); + if (ctl) + snd_ctl_notify(codec->bus->card, + SNDRV_CTL_EVENT_MASK_VALUE, + &ctl->id); } } @@ -1443,11 +1002,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", @@ -1469,6 +1028,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; @@ -1488,7 +1052,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), @@ -1539,6 +1103,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; @@ -1603,6 +1168,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; @@ -1616,7 +1182,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 */ @@ -1646,6 +1212,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}, { } }; @@ -1668,7 +1236,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; @@ -1737,7 +1305,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, @@ -1758,7 +1326,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) { @@ -1856,7 +1424,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, @@ -1868,7 +1436,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, @@ -1885,7 +1453,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, @@ -1896,7 +1464,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, @@ -1909,7 +1477,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, @@ -1919,7 +1487,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++) { @@ -1967,7 +1535,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 */ @@ -2131,7 +1699,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]); @@ -2190,17 +1758,21 @@ static void via_unsol_event(struct hda_codec *codec, unsigned int res) { res >>= 26; - if (res & VIA_HP_EVENT) + + if (res & VIA_JACK_EVENT) + set_widgets_power_state(codec); + + res &= ~VIA_JACK_EVENT; + + if (res == VIA_HP_EVENT) via_hp_automute(codec); - if (res & VIA_GPIO_EVENT) + else if (res == VIA_GPIO_EVENT) via_gpio_control(codec); - if (res & VIA_JACK_EVENT) - set_jack_power_state(codec); - if (res & VIA_MONO_EVENT) + 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); } @@ -2250,7 +1822,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, @@ -2280,16 +1852,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; } } @@ -2433,7 +2005,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]; @@ -2479,13 +2052,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 }, @@ -2544,7 +2117,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", @@ -2619,7 +2192,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); @@ -2723,7 +2297,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), @@ -2745,7 +2319,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}, { } @@ -2754,7 +2328,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 */ @@ -2794,7 +2368,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, @@ -2806,7 +2380,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, @@ -2818,7 +2392,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, @@ -2829,7 +2403,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, @@ -2840,7 +2414,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, @@ -2867,26 +2441,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++) { @@ -2896,15 +2470,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; @@ -3052,7 +2626,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)); } @@ -3102,7 +2676,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 }, @@ -3163,7 +2737,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 */ @@ -3253,7 +2827,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), @@ -3275,7 +2849,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 */ @@ -3310,7 +2884,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 */ @@ -3345,7 +2919,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}, @@ -3369,7 +2943,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, @@ -3382,7 +2956,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, @@ -3394,7 +2968,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, @@ -3407,7 +2981,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, @@ -3420,7 +2994,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, @@ -3443,16 +3017,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; } } @@ -3584,7 +3158,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)); } @@ -3634,7 +3208,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 }, @@ -3642,6 +3216,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) { @@ -3692,6 +3347,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; } @@ -3742,13 +3399,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), @@ -3771,7 +3430,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)}, @@ -3797,7 +3456,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}, @@ -3810,7 +3469,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, @@ -3823,7 +3494,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, @@ -3836,7 +3520,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, @@ -3866,16 +3550,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; } } @@ -3884,23 +3571,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; @@ -3911,8 +3604,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 */ @@ -4022,7 +3722,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)); } @@ -4066,7 +3766,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]); @@ -4093,7 +3793,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 }, @@ -4133,17 +3833,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; @@ -4181,13 +3893,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), @@ -4211,7 +3932,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 */ @@ -4242,7 +3963,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}, @@ -4252,7 +3973,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, @@ -4265,7 +3986,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, @@ -4278,7 +3999,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, @@ -4300,7 +4021,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; @@ -4378,7 +4099,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)); } @@ -4429,7 +4150,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 }, @@ -4438,6 +4159,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; @@ -4484,13 +4236,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), @@ -4512,14 +4265,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 */ @@ -4528,7 +4282,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}, @@ -4559,7 +4313,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}, @@ -4572,7 +4326,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, @@ -4585,7 +4339,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, @@ -4598,7 +4352,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, @@ -4611,7 +4365,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, @@ -4634,16 +4388,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; } } @@ -4765,7 +4519,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)); } @@ -4816,7 +4570,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 }, @@ -4825,6 +4579,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; @@ -4886,6 +4706,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; } @@ -4925,13 +4747,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), @@ -4950,7 +4771,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, @@ -4966,12 +4787,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 */ @@ -5020,7 +4841,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}, @@ -5033,7 +4854,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, @@ -5046,7 +4867,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, @@ -5059,7 +4880,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, @@ -5088,13 +4909,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; } } @@ -5229,7 +5050,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)); } @@ -5276,7 +5097,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 }, @@ -5285,6 +5106,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; @@ -5339,13 +5253,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), @@ -5368,7 +5283,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 */ @@ -5419,9 +5338,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)}, + + + /* 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 struct hda_verb vt2002P_uniwill_init_verbs[] = { +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, @@ -5431,8 +5401,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, @@ -5445,7 +5425,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, @@ -5458,7 +5438,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, @@ -5478,7 +5458,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; } @@ -5487,10 +5467,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, @@ -5500,7 +5485,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; @@ -5540,7 +5525,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, @@ -5601,7 +5586,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 }, @@ -5609,6 +5594,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) @@ -5631,14 +5726,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; + + 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; - spec->stream_name_analog = "VT2002P Analog"; + 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) { @@ -5660,13 +5772,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), @@ -5688,7 +5801,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 */ @@ -5741,7 +5854,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 }, @@ -5753,7 +5866,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, @@ -5766,7 +5879,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, @@ -5779,7 +5892,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, @@ -5798,7 +5911,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; } @@ -5861,7 +5974,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, @@ -5923,7 +6036,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 }, @@ -5931,6 +6044,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) @@ -5984,13 +6188,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}, @@ -6035,7 +6240,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}, @@ -6076,6 +6281,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 */ }; |