aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-09-04 19:26:56 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2013-09-04 19:26:56 -0400
commit977dbfcf8e9ff1783355b260d93101af315de18a (patch)
treeb586ca678499d1ccc2d199a97d65996c630b25d8 /sound/pci
parentaa7054f5a5a9ff728ce291cb103afa19f4f849eb (diff)
parentb054087dbacee30a9dddaef2c9a96312146be04e (diff)
Merge tag 'sound-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound
Pull sound updates from Takashi Iwai: "Changes are seen in a wide range of codes, mainly due to ASoC DAPM requirements; HD-audio shows a high peak in diffstat, it's just a removal of bunch of old static quirks. Some highlights: - HDPM: Updates for AIO/RayDAT support, TCO/sync support - RME96: Add PCM sync support - HD-audio: * A few HDMI/DP audio updates (CA assignment fix, stream switching fix, Intel DP device list support) * Device specific fixes (ASUS/CXT HP mic support, Thinkpad mic improvements, Chromebook fixes, STAC9228 Dell fixes) * Replace the all static quirks for AD codecs with the generic parser * WAKEEN support for handling irqs in the power saving mode - USB-audio: Clean up implicit fb handling and related codes - DAPM is now mandatory for ASoC CODEC drivers; all existing drivers have had some level of DAPM support added. In addition, a lot of cleanups and improvements in DAPM. - Support for ASoC cross-platform compile test - New drivers and support for Analog Devices ADAU1702 and ADAU1401(a), Asahi Kasei Microdevices AK4554, Atmel AT91ASM9x5 and WM8904 based machines, Freescale S/PDIF and SSI AC'97, Renesas R-Car SoCs, Samsung Exynos5420 SoCs, Texas Instruments PCM1681 and PCM1792A and Wolfson Microelectronics WM8997 - DT bindings for kirkwood and i.MX S/PDIF - Clean up and bug fixes: ssm2602, rt5640 and sgtl5000. - Core helpers for bitbanged AC'97 reset" * tag 'sound-3.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound: (375 commits) ALSA: hda - Re-setup HDMI pin and audio infoframe on stream switches ALSA: hda - hdmi: Fallback to ALSA allocation when selecting CA ASoC: mxs-sgtl5000: Configure the dai_links as unidirectional ASoC: soc-pcm: Allow to specify unidirectional dai_link ASoC: fsl_spdif: Staticse non-exported symbols ASoC: ssm2602: Fix cache sync ASoC: Remove unused sysfs_registered field from snd_soc_codec struct ASoC: Remove unused debugfs_dapm field from snd_soc_{platform,codec} struct ASoC: Remove unused control_type field from snd_soc_codec struct ASoC: fsl: Add one blank space after ':=' in Makefile ASoC: fsl: Add wrapping for dev_dbg() in fsl_spdif.c ASoC: rt5640: change widget sequence for depop ASoC: dapm: Fix auto-disable for inverted controls ASoC: fsl: Drop SND_SOC_FSL_UTILS from SND_SOC_IMX_SPDIF ASoC: Samsung: Do not queue cyclic buffers multiple times ASoC: ep93xx-i2s: Remove unnecessary dev_set_drvdata() ASoC: designware_i2s: Remove unnecessary dev_set_drvdata() ASoC: fsl_spdif: remove redundant dev_err call in fsl_spdif_probe() ASoC: fsl: Add S/PDIF machine driver ASoc: kirkwood: Use the Kirkwood audio driver in Dove boards ...
Diffstat (limited to 'sound/pci')
-rw-r--r--sound/pci/hda/Kconfig9
-rw-r--r--sound/pci/hda/hda_codec.c64
-rw-r--r--sound/pci/hda/hda_codec.h21
-rw-r--r--sound/pci/hda/hda_generic.c79
-rw-r--r--sound/pci/hda/hda_generic.h1
-rw-r--r--sound/pci/hda/hda_hwdep.c6
-rw-r--r--sound/pci/hda/hda_intel.c34
-rw-r--r--sound/pci/hda/hda_jack.c22
-rw-r--r--sound/pci/hda/hda_jack.h13
-rw-r--r--sound/pci/hda/hda_proc.c33
-rw-r--r--sound/pci/hda/patch_analog.c4528
-rw-r--r--sound/pci/hda/patch_conexant.c79
-rw-r--r--sound/pci/hda/patch_hdmi.c61
-rw-r--r--sound/pci/hda/patch_realtek.c190
-rw-r--r--sound/pci/hda/patch_sigmatel.c14
-rw-r--r--sound/pci/hda/patch_via.c2
-rw-r--r--sound/pci/rme96.c307
-rw-r--r--sound/pci/rme9652/hdspm.c779
18 files changed, 1506 insertions, 4736 deletions
diff --git a/sound/pci/hda/Kconfig b/sound/pci/hda/Kconfig
index 59c5e9c03d53..8de66ccd7279 100644
--- a/sound/pci/hda/Kconfig
+++ b/sound/pci/hda/Kconfig
@@ -152,14 +152,9 @@ config SND_HDA_CODEC_HDMI
152 This module is automatically loaded at probing. 152 This module is automatically loaded at probing.
153 153
154config SND_HDA_I915 154config SND_HDA_I915
155 bool "Build Display HD-audio controller/codec power well support for i915 cards" 155 bool
156 default y
156 depends on DRM_I915 157 depends on DRM_I915
157 help
158 Say Y here to include full HDMI and DisplayPort HD-audio controller/codec
159 power-well support for Intel Haswell graphics cards based on the i915 driver.
160
161 Note that this option must be enabled for Intel Haswell C+ stepping machines, otherwise
162 the GPU audio controller/codecs will not be initialized or damaged when exit from S3 mode.
163 158
164config SND_HDA_CODEC_CIRRUS 159config SND_HDA_CODEC_CIRRUS
165 bool "Build Cirrus Logic codec support" 160 bool "Build Cirrus Logic codec support"
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 8a005f0e5ca4..5b6c4e3c92ca 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -666,6 +666,64 @@ int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
666} 666}
667EXPORT_SYMBOL_HDA(snd_hda_get_conn_index); 667EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
668 668
669
670/* return DEVLIST_LEN parameter of the given widget */
671static unsigned int get_num_devices(struct hda_codec *codec, hda_nid_t nid)
672{
673 unsigned int wcaps = get_wcaps(codec, nid);
674 unsigned int parm;
675
676 if (!codec->dp_mst || !(wcaps & AC_WCAP_DIGITAL) ||
677 get_wcaps_type(wcaps) != AC_WID_PIN)
678 return 0;
679
680 parm = snd_hda_param_read(codec, nid, AC_PAR_DEVLIST_LEN);
681 if (parm == -1 && codec->bus->rirb_error)
682 parm = 0;
683 return parm & AC_DEV_LIST_LEN_MASK;
684}
685
686/**
687 * snd_hda_get_devices - copy device list without cache
688 * @codec: the HDA codec
689 * @nid: NID of the pin to parse
690 * @dev_list: device list array
691 * @max_devices: max. number of devices to store
692 *
693 * Copy the device list. This info is dynamic and so not cached.
694 * Currently called only from hda_proc.c, so not exported.
695 */
696int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
697 u8 *dev_list, int max_devices)
698{
699 unsigned int parm;
700 int i, dev_len, devices;
701
702 parm = get_num_devices(codec, nid);
703 if (!parm) /* not multi-stream capable */
704 return 0;
705
706 dev_len = parm + 1;
707 dev_len = dev_len < max_devices ? dev_len : max_devices;
708
709 devices = 0;
710 while (devices < dev_len) {
711 parm = snd_hda_codec_read(codec, nid, 0,
712 AC_VERB_GET_DEVICE_LIST, devices);
713 if (parm == -1 && codec->bus->rirb_error)
714 break;
715
716 for (i = 0; i < 8; i++) {
717 dev_list[devices] = (u8)parm;
718 parm >>= 4;
719 devices++;
720 if (devices >= dev_len)
721 break;
722 }
723 }
724 return devices;
725}
726
669/** 727/**
670 * snd_hda_queue_unsol_event - add an unsolicited event to queue 728 * snd_hda_queue_unsol_event - add an unsolicited event to queue
671 * @bus: the BUS 729 * @bus: the BUS
@@ -1216,11 +1274,13 @@ static void hda_jackpoll_work(struct work_struct *work)
1216{ 1274{
1217 struct hda_codec *codec = 1275 struct hda_codec *codec =
1218 container_of(work, struct hda_codec, jackpoll_work.work); 1276 container_of(work, struct hda_codec, jackpoll_work.work);
1219 if (!codec->jackpoll_interval)
1220 return;
1221 1277
1222 snd_hda_jack_set_dirty_all(codec); 1278 snd_hda_jack_set_dirty_all(codec);
1223 snd_hda_jack_poll_all(codec); 1279 snd_hda_jack_poll_all(codec);
1280
1281 if (!codec->jackpoll_interval)
1282 return;
1283
1224 queue_delayed_work(codec->bus->workq, &codec->jackpoll_work, 1284 queue_delayed_work(codec->bus->workq, &codec->jackpoll_work,
1225 codec->jackpoll_interval); 1285 codec->jackpoll_interval);
1226} 1286}
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 701c2e069b10..7aa9870040c1 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -94,6 +94,8 @@ enum {
94#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32 94#define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32
95#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33 95#define AC_VERB_GET_HDMI_CP_CTRL 0x0f33
96#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34 96#define AC_VERB_GET_HDMI_CHAN_SLOT 0x0f34
97#define AC_VERB_GET_DEVICE_SEL 0xf35
98#define AC_VERB_GET_DEVICE_LIST 0xf36
97 99
98/* 100/*
99 * SET verbs 101 * SET verbs
@@ -133,6 +135,7 @@ enum {
133#define AC_VERB_SET_HDMI_DIP_XMIT 0x732 135#define AC_VERB_SET_HDMI_DIP_XMIT 0x732
134#define AC_VERB_SET_HDMI_CP_CTRL 0x733 136#define AC_VERB_SET_HDMI_CP_CTRL 0x733
135#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734 137#define AC_VERB_SET_HDMI_CHAN_SLOT 0x734
138#define AC_VERB_SET_DEVICE_SEL 0x735
136 139
137/* 140/*
138 * Parameter IDs 141 * Parameter IDs
@@ -154,6 +157,7 @@ enum {
154#define AC_PAR_GPIO_CAP 0x11 157#define AC_PAR_GPIO_CAP 0x11
155#define AC_PAR_AMP_OUT_CAP 0x12 158#define AC_PAR_AMP_OUT_CAP 0x12
156#define AC_PAR_VOL_KNB_CAP 0x13 159#define AC_PAR_VOL_KNB_CAP 0x13
160#define AC_PAR_DEVLIST_LEN 0x15
157#define AC_PAR_HDMI_LPCM_CAP 0x20 161#define AC_PAR_HDMI_LPCM_CAP 0x20
158 162
159/* 163/*
@@ -251,6 +255,11 @@ enum {
251#define AC_UNSOL_RES_TAG_SHIFT 26 255#define AC_UNSOL_RES_TAG_SHIFT 26
252#define AC_UNSOL_RES_SUBTAG (0x1f<<21) 256#define AC_UNSOL_RES_SUBTAG (0x1f<<21)
253#define AC_UNSOL_RES_SUBTAG_SHIFT 21 257#define AC_UNSOL_RES_SUBTAG_SHIFT 21
258#define AC_UNSOL_RES_DE (0x3f<<15) /* Device Entry
259 * (for DP1.2 MST)
260 */
261#define AC_UNSOL_RES_DE_SHIFT 15
262#define AC_UNSOL_RES_IA (1<<2) /* Inactive (for DP1.2 MST) */
254#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */ 263#define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */
255#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */ 264#define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */
256#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */ 265#define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */
@@ -352,6 +361,10 @@ enum {
352#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */ 361#define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */
353#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */ 362#define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */
354 363
364/* Display pin's device list length */
365#define AC_DEV_LIST_LEN_MASK 0x3f
366#define AC_MAX_DEV_LIST_LEN 64
367
355/* 368/*
356 * Control Parameters 369 * Control Parameters
357 */ 370 */
@@ -460,6 +473,11 @@ enum {
460#define AC_DEFCFG_PORT_CONN (0x3<<30) 473#define AC_DEFCFG_PORT_CONN (0x3<<30)
461#define AC_DEFCFG_PORT_CONN_SHIFT 30 474#define AC_DEFCFG_PORT_CONN_SHIFT 30
462 475
476/* Display pin's device list entry */
477#define AC_DE_PD (1<<0)
478#define AC_DE_ELDV (1<<1)
479#define AC_DE_IA (1<<2)
480
463/* device device types (0x0-0xf) */ 481/* device device types (0x0-0xf) */
464enum { 482enum {
465 AC_JACK_LINE_OUT, 483 AC_JACK_LINE_OUT,
@@ -885,6 +903,7 @@ struct hda_codec {
885 unsigned int pcm_format_first:1; /* PCM format must be set first */ 903 unsigned int pcm_format_first:1; /* PCM format must be set first */
886 unsigned int epss:1; /* supporting EPSS? */ 904 unsigned int epss:1; /* supporting EPSS? */
887 unsigned int cached_write:1; /* write only to caches */ 905 unsigned int cached_write:1; /* write only to caches */
906 unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */
888#ifdef CONFIG_PM 907#ifdef CONFIG_PM
889 unsigned int power_on :1; /* current (global) power-state */ 908 unsigned int power_on :1; /* current (global) power-state */
890 unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ 909 unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */
@@ -972,6 +991,8 @@ int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int nums,
972 const hda_nid_t *list); 991 const hda_nid_t *list);
973int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, 992int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
974 hda_nid_t nid, int recursive); 993 hda_nid_t nid, int recursive);
994int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
995 u8 *dev_list, int max_devices);
975int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 996int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
976 u32 *ratesp, u64 *formatsp, unsigned int *bpsp); 997 u32 *ratesp, u64 *formatsp, unsigned int *bpsp);
977 998
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index e3c7ba8d7582..ac41e9cdc976 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -142,6 +142,9 @@ static void parse_user_hints(struct hda_codec *codec)
142 val = snd_hda_get_bool_hint(codec, "primary_hp"); 142 val = snd_hda_get_bool_hint(codec, "primary_hp");
143 if (val >= 0) 143 if (val >= 0)
144 spec->no_primary_hp = !val; 144 spec->no_primary_hp = !val;
145 val = snd_hda_get_bool_hint(codec, "multi_io");
146 if (val >= 0)
147 spec->no_multi_io = !val;
145 val = snd_hda_get_bool_hint(codec, "multi_cap_vol"); 148 val = snd_hda_get_bool_hint(codec, "multi_cap_vol");
146 if (val >= 0) 149 if (val >= 0)
147 spec->multi_cap_vol = !!val; 150 spec->multi_cap_vol = !!val;
@@ -813,6 +816,8 @@ static void resume_path_from_idx(struct hda_codec *codec, int path_idx)
813 816
814static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol, 817static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
815 struct snd_ctl_elem_value *ucontrol); 818 struct snd_ctl_elem_value *ucontrol);
819static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol,
820 struct snd_ctl_elem_value *ucontrol);
816 821
817enum { 822enum {
818 HDA_CTL_WIDGET_VOL, 823 HDA_CTL_WIDGET_VOL,
@@ -830,7 +835,13 @@ static const struct snd_kcontrol_new control_templates[] = {
830 .put = hda_gen_mixer_mute_put, /* replaced */ 835 .put = hda_gen_mixer_mute_put, /* replaced */
831 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0), 836 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0),
832 }, 837 },
833 HDA_BIND_MUTE(NULL, 0, 0, 0), 838 {
839 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
840 .info = snd_hda_mixer_amp_switch_info,
841 .get = snd_hda_mixer_bind_switch_get,
842 .put = hda_gen_bind_mute_put, /* replaced */
843 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0),
844 },
834}; 845};
835 846
836/* add dynamic controls from template */ 847/* add dynamic controls from template */
@@ -937,8 +948,8 @@ static int add_stereo_sw(struct hda_codec *codec, const char *pfx,
937} 948}
938 949
939/* playback mute control with the software mute bit check */ 950/* playback mute control with the software mute bit check */
940static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol, 951static void sync_auto_mute_bits(struct snd_kcontrol *kcontrol,
941 struct snd_ctl_elem_value *ucontrol) 952 struct snd_ctl_elem_value *ucontrol)
942{ 953{
943 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 954 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
944 struct hda_gen_spec *spec = codec->spec; 955 struct hda_gen_spec *spec = codec->spec;
@@ -949,10 +960,22 @@ static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
949 ucontrol->value.integer.value[0] &= enabled; 960 ucontrol->value.integer.value[0] &= enabled;
950 ucontrol->value.integer.value[1] &= enabled; 961 ucontrol->value.integer.value[1] &= enabled;
951 } 962 }
963}
952 964
965static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
966 struct snd_ctl_elem_value *ucontrol)
967{
968 sync_auto_mute_bits(kcontrol, ucontrol);
953 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 969 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
954} 970}
955 971
972static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol,
973 struct snd_ctl_elem_value *ucontrol)
974{
975 sync_auto_mute_bits(kcontrol, ucontrol);
976 return snd_hda_mixer_bind_switch_put(kcontrol, ucontrol);
977}
978
956/* any ctl assigned to the path with the given index? */ 979/* any ctl assigned to the path with the given index? */
957static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type) 980static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type)
958{ 981{
@@ -1541,7 +1564,8 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1541 cfg->speaker_pins, 1564 cfg->speaker_pins,
1542 spec->multiout.extra_out_nid, 1565 spec->multiout.extra_out_nid,
1543 spec->speaker_paths); 1566 spec->speaker_paths);
1544 if (fill_mio_first && cfg->line_outs == 1 && 1567 if (!spec->no_multi_io &&
1568 fill_mio_first && cfg->line_outs == 1 &&
1545 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1569 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1546 err = fill_multi_ios(codec, cfg->line_out_pins[0], true); 1570 err = fill_multi_ios(codec, cfg->line_out_pins[0], true);
1547 if (!err) 1571 if (!err)
@@ -1554,7 +1578,7 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1554 spec->private_dac_nids, spec->out_paths, 1578 spec->private_dac_nids, spec->out_paths,
1555 spec->main_out_badness); 1579 spec->main_out_badness);
1556 1580
1557 if (fill_mio_first && 1581 if (!spec->no_multi_io && fill_mio_first &&
1558 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1582 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1559 /* try to fill multi-io first */ 1583 /* try to fill multi-io first */
1560 err = fill_multi_ios(codec, cfg->line_out_pins[0], false); 1584 err = fill_multi_ios(codec, cfg->line_out_pins[0], false);
@@ -1582,7 +1606,8 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1582 return err; 1606 return err;
1583 badness += err; 1607 badness += err;
1584 } 1608 }
1585 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1609 if (!spec->no_multi_io &&
1610 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1586 err = fill_multi_ios(codec, cfg->line_out_pins[0], false); 1611 err = fill_multi_ios(codec, cfg->line_out_pins[0], false);
1587 if (err < 0) 1612 if (err < 0)
1588 return err; 1613 return err;
@@ -1600,7 +1625,8 @@ static int fill_and_eval_dacs(struct hda_codec *codec,
1600 check_aamix_out_path(codec, spec->speaker_paths[0]); 1625 check_aamix_out_path(codec, spec->speaker_paths[0]);
1601 } 1626 }
1602 1627
1603 if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 1628 if (!spec->no_multi_io &&
1629 cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
1604 if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2) 1630 if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2)
1605 spec->multi_ios = 1; /* give badness */ 1631 spec->multi_ios = 1; /* give badness */
1606 1632
@@ -3724,7 +3750,8 @@ static int mux_select(struct hda_codec *codec, unsigned int adc_idx,
3724/* check each pin in the given array; returns true if any of them is plugged */ 3750/* check each pin in the given array; returns true if any of them is plugged */
3725static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 3751static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3726{ 3752{
3727 int i, present = 0; 3753 int i;
3754 bool present = false;
3728 3755
3729 for (i = 0; i < num_pins; i++) { 3756 for (i = 0; i < num_pins; i++) {
3730 hda_nid_t nid = pins[i]; 3757 hda_nid_t nid = pins[i];
@@ -3733,14 +3760,15 @@ static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3733 /* don't detect pins retasked as inputs */ 3760 /* don't detect pins retasked as inputs */
3734 if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN) 3761 if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN)
3735 continue; 3762 continue;
3736 present |= snd_hda_jack_detect(codec, nid); 3763 if (snd_hda_jack_detect_state(codec, nid) == HDA_JACK_PRESENT)
3764 present = true;
3737 } 3765 }
3738 return present; 3766 return present;
3739} 3767}
3740 3768
3741/* standard HP/line-out auto-mute helper */ 3769/* standard HP/line-out auto-mute helper */
3742static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, 3770static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
3743 bool mute) 3771 int *paths, bool mute)
3744{ 3772{
3745 struct hda_gen_spec *spec = codec->spec; 3773 struct hda_gen_spec *spec = codec->spec;
3746 int i; 3774 int i;
@@ -3752,10 +3780,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
3752 break; 3780 break;
3753 3781
3754 if (spec->auto_mute_via_amp) { 3782 if (spec->auto_mute_via_amp) {
3783 struct nid_path *path;
3784 hda_nid_t mute_nid;
3785
3786 path = snd_hda_get_path_from_idx(codec, paths[i]);
3787 if (!path)
3788 continue;
3789 mute_nid = get_amp_nid_(path->ctls[NID_PATH_MUTE_CTL]);
3790 if (!mute_nid)
3791 continue;
3755 if (mute) 3792 if (mute)
3756 spec->mute_bits |= (1ULL << nid); 3793 spec->mute_bits |= (1ULL << mute_nid);
3757 else 3794 else
3758 spec->mute_bits &= ~(1ULL << nid); 3795 spec->mute_bits &= ~(1ULL << mute_nid);
3759 set_pin_eapd(codec, nid, !mute); 3796 set_pin_eapd(codec, nid, !mute);
3760 continue; 3797 continue;
3761 } 3798 }
@@ -3786,14 +3823,19 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
3786void snd_hda_gen_update_outputs(struct hda_codec *codec) 3823void snd_hda_gen_update_outputs(struct hda_codec *codec)
3787{ 3824{
3788 struct hda_gen_spec *spec = codec->spec; 3825 struct hda_gen_spec *spec = codec->spec;
3826 int *paths;
3789 int on; 3827 int on;
3790 3828
3791 /* Control HP pins/amps depending on master_mute state; 3829 /* Control HP pins/amps depending on master_mute state;
3792 * in general, HP pins/amps control should be enabled in all cases, 3830 * in general, HP pins/amps control should be enabled in all cases,
3793 * but currently set only for master_mute, just to be safe 3831 * but currently set only for master_mute, just to be safe
3794 */ 3832 */
3833 if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
3834 paths = spec->out_paths;
3835 else
3836 paths = spec->hp_paths;
3795 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), 3837 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
3796 spec->autocfg.hp_pins, spec->master_mute); 3838 spec->autocfg.hp_pins, paths, spec->master_mute);
3797 3839
3798 if (!spec->automute_speaker) 3840 if (!spec->automute_speaker)
3799 on = 0; 3841 on = 0;
@@ -3801,8 +3843,12 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec)
3801 on = spec->hp_jack_present | spec->line_jack_present; 3843 on = spec->hp_jack_present | spec->line_jack_present;
3802 on |= spec->master_mute; 3844 on |= spec->master_mute;
3803 spec->speaker_muted = on; 3845 spec->speaker_muted = on;
3846 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
3847 paths = spec->out_paths;
3848 else
3849 paths = spec->speaker_paths;
3804 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), 3850 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
3805 spec->autocfg.speaker_pins, on); 3851 spec->autocfg.speaker_pins, paths, on);
3806 3852
3807 /* toggle line-out mutes if needed, too */ 3853 /* toggle line-out mutes if needed, too */
3808 /* if LO is a copy of either HP or Speaker, don't need to handle it */ 3854 /* if LO is a copy of either HP or Speaker, don't need to handle it */
@@ -3815,8 +3861,9 @@ void snd_hda_gen_update_outputs(struct hda_codec *codec)
3815 on = spec->hp_jack_present; 3861 on = spec->hp_jack_present;
3816 on |= spec->master_mute; 3862 on |= spec->master_mute;
3817 spec->line_out_muted = on; 3863 spec->line_out_muted = on;
3864 paths = spec->out_paths;
3818 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), 3865 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
3819 spec->autocfg.line_out_pins, on); 3866 spec->autocfg.line_out_pins, paths, on);
3820} 3867}
3821EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs); 3868EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs);
3822 3869
@@ -3887,7 +3934,7 @@ void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *ja
3887 /* don't detect pins retasked as outputs */ 3934 /* don't detect pins retasked as outputs */
3888 if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN) 3935 if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN)
3889 continue; 3936 continue;
3890 if (snd_hda_jack_detect(codec, pin)) { 3937 if (snd_hda_jack_detect_state(codec, pin) == HDA_JACK_PRESENT) {
3891 mux_select(codec, 0, spec->am_entry[i].idx); 3938 mux_select(codec, 0, spec->am_entry[i].idx);
3892 return; 3939 return;
3893 } 3940 }
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index e199a852388b..48d44026705b 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -220,6 +220,7 @@ struct hda_gen_spec {
220 unsigned int hp_mic:1; /* Allow HP as a mic-in */ 220 unsigned int hp_mic:1; /* Allow HP as a mic-in */
221 unsigned int suppress_hp_mic_detect:1; /* Don't detect HP/mic */ 221 unsigned int suppress_hp_mic_detect:1; /* Don't detect HP/mic */
222 unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */ 222 unsigned int no_primary_hp:1; /* Don't prefer HP pins to speaker pins */
223 unsigned int no_multi_io:1; /* Don't try multi I/O config */
223 unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */ 224 unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */
224 unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */ 225 unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */
225 unsigned int own_eapd_ctl:1; /* set EAPD by own function */ 226 unsigned int own_eapd_ctl:1; /* set EAPD by own function */
diff --git a/sound/pci/hda/hda_hwdep.c b/sound/pci/hda/hda_hwdep.c
index ce67608734b5..fe0bda19de15 100644
--- a/sound/pci/hda/hda_hwdep.c
+++ b/sound/pci/hda/hda_hwdep.c
@@ -295,7 +295,7 @@ static ssize_t type##_store(struct device *dev, \
295 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 295 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \
296 struct hda_codec *codec = hwdep->private_data; \ 296 struct hda_codec *codec = hwdep->private_data; \
297 unsigned long val; \ 297 unsigned long val; \
298 int err = strict_strtoul(buf, 0, &val); \ 298 int err = kstrtoul(buf, 0, &val); \
299 if (err < 0) \ 299 if (err < 0) \
300 return err; \ 300 return err; \
301 codec->type = val; \ 301 codec->type = val; \
@@ -654,7 +654,7 @@ int snd_hda_get_int_hint(struct hda_codec *codec, const char *key, int *valp)
654 p = snd_hda_get_hint(codec, key); 654 p = snd_hda_get_hint(codec, key);
655 if (!p) 655 if (!p)
656 ret = -ENOENT; 656 ret = -ENOENT;
657 else if (strict_strtoul(p, 0, &val)) 657 else if (kstrtoul(p, 0, &val))
658 ret = -EINVAL; 658 ret = -EINVAL;
659 else { 659 else {
660 *valp = val; 660 *valp = val;
@@ -751,7 +751,7 @@ static void parse_##name##_mode(char *buf, struct hda_bus *bus, \
751 struct hda_codec **codecp) \ 751 struct hda_codec **codecp) \
752{ \ 752{ \
753 unsigned long val; \ 753 unsigned long val; \
754 if (!strict_strtoul(buf, 0, &val)) \ 754 if (!kstrtoul(buf, 0, &val)) \
755 (*codecp)->name = val; \ 755 (*codecp)->name = val; \
756} 756}
757 757
diff --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c
index 8860dd529520..c6c98298ac39 100644
--- a/sound/pci/hda/hda_intel.c
+++ b/sound/pci/hda/hda_intel.c
@@ -1160,7 +1160,7 @@ static int azx_reset(struct azx *chip, int full_reset)
1160 goto __skip; 1160 goto __skip;
1161 1161
1162 /* clear STATESTS */ 1162 /* clear STATESTS */
1163 azx_writeb(chip, STATESTS, STATESTS_INT_MASK); 1163 azx_writew(chip, STATESTS, STATESTS_INT_MASK);
1164 1164
1165 /* reset controller */ 1165 /* reset controller */
1166 azx_enter_link_reset(chip); 1166 azx_enter_link_reset(chip);
@@ -1242,7 +1242,7 @@ static void azx_int_clear(struct azx *chip)
1242 } 1242 }
1243 1243
1244 /* clear STATESTS */ 1244 /* clear STATESTS */
1245 azx_writeb(chip, STATESTS, STATESTS_INT_MASK); 1245 azx_writew(chip, STATESTS, STATESTS_INT_MASK);
1246 1246
1247 /* clear rirb status */ 1247 /* clear rirb status */
1248 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); 1248 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK);
@@ -1451,8 +1451,8 @@ static irqreturn_t azx_interrupt(int irq, void *dev_id)
1451 1451
1452#if 0 1452#if 0
1453 /* clear state status int */ 1453 /* clear state status int */
1454 if (azx_readb(chip, STATESTS) & 0x04) 1454 if (azx_readw(chip, STATESTS) & 0x04)
1455 azx_writeb(chip, STATESTS, 0x04); 1455 azx_writew(chip, STATESTS, 0x04);
1456#endif 1456#endif
1457 spin_unlock(&chip->reg_lock); 1457 spin_unlock(&chip->reg_lock);
1458 1458
@@ -2971,6 +2971,10 @@ static int azx_runtime_suspend(struct device *dev)
2971 struct snd_card *card = dev_get_drvdata(dev); 2971 struct snd_card *card = dev_get_drvdata(dev);
2972 struct azx *chip = card->private_data; 2972 struct azx *chip = card->private_data;
2973 2973
2974 /* enable controller wake up event */
2975 azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) |
2976 STATESTS_INT_MASK);
2977
2974 azx_stop_chip(chip); 2978 azx_stop_chip(chip);
2975 azx_enter_link_reset(chip); 2979 azx_enter_link_reset(chip);
2976 azx_clear_irq_pending(chip); 2980 azx_clear_irq_pending(chip);
@@ -2983,11 +2987,31 @@ static int azx_runtime_resume(struct device *dev)
2983{ 2987{
2984 struct snd_card *card = dev_get_drvdata(dev); 2988 struct snd_card *card = dev_get_drvdata(dev);
2985 struct azx *chip = card->private_data; 2989 struct azx *chip = card->private_data;
2990 struct hda_bus *bus;
2991 struct hda_codec *codec;
2992 int status;
2986 2993
2987 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) 2994 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL)
2988 hda_display_power(true); 2995 hda_display_power(true);
2996
2997 /* Read STATESTS before controller reset */
2998 status = azx_readw(chip, STATESTS);
2999
2989 azx_init_pci(chip); 3000 azx_init_pci(chip);
2990 azx_init_chip(chip, 1); 3001 azx_init_chip(chip, 1);
3002
3003 bus = chip->bus;
3004 if (status && bus) {
3005 list_for_each_entry(codec, &bus->codec_list, list)
3006 if (status & (1 << codec->addr))
3007 queue_delayed_work(codec->bus->workq,
3008 &codec->jackpoll_work, codec->jackpoll_interval);
3009 }
3010
3011 /* disable controller Wake Up event*/
3012 azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) &
3013 ~STATESTS_INT_MASK);
3014
2991 return 0; 3015 return 0;
2992} 3016}
2993 3017
@@ -3831,11 +3855,13 @@ static int azx_probe_continue(struct azx *chip)
3831 3855
3832 /* Request power well for Haswell HDA controller and codec */ 3856 /* Request power well for Haswell HDA controller and codec */
3833 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { 3857 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) {
3858#ifdef CONFIG_SND_HDA_I915
3834 err = hda_i915_init(); 3859 err = hda_i915_init();
3835 if (err < 0) { 3860 if (err < 0) {
3836 snd_printk(KERN_ERR SFX "Error request power-well from i915\n"); 3861 snd_printk(KERN_ERR SFX "Error request power-well from i915\n");
3837 goto out_free; 3862 goto out_free;
3838 } 3863 }
3864#endif
3839 hda_display_power(true); 3865 hda_display_power(true);
3840 } 3866 }
3841 3867
diff --git a/sound/pci/hda/hda_jack.c b/sound/pci/hda/hda_jack.c
index 3fd2973183e2..05b3e3e9108f 100644
--- a/sound/pci/hda/hda_jack.c
+++ b/sound/pci/hda/hda_jack.c
@@ -194,18 +194,24 @@ u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
194EXPORT_SYMBOL_HDA(snd_hda_pin_sense); 194EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
195 195
196/** 196/**
197 * snd_hda_jack_detect - query pin Presence Detect status 197 * snd_hda_jack_detect_state - query pin Presence Detect status
198 * @codec: the CODEC to sense 198 * @codec: the CODEC to sense
199 * @nid: the pin NID to sense 199 * @nid: the pin NID to sense
200 * 200 *
201 * Query and return the pin's Presence Detect status. 201 * Query and return the pin's Presence Detect status, as either
202 * HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT or HDA_JACK_PHANTOM.
202 */ 203 */
203int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 204int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid)
204{ 205{
205 u32 sense = snd_hda_pin_sense(codec, nid); 206 struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid);
206 return get_jack_plug_state(sense); 207 if (jack && jack->phantom_jack)
208 return HDA_JACK_PHANTOM;
209 else if (snd_hda_pin_sense(codec, nid) & AC_PINSENSE_PRESENCE)
210 return HDA_JACK_PRESENT;
211 else
212 return HDA_JACK_NOT_PRESENT;
207} 213}
208EXPORT_SYMBOL_HDA(snd_hda_jack_detect); 214EXPORT_SYMBOL_HDA(snd_hda_jack_detect_state);
209 215
210/** 216/**
211 * snd_hda_jack_detect_enable - enable the jack-detection 217 * snd_hda_jack_detect_enable - enable the jack-detection
@@ -247,8 +253,8 @@ EXPORT_SYMBOL_HDA(snd_hda_jack_detect_enable);
247int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, 253int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
248 hda_nid_t gating_nid) 254 hda_nid_t gating_nid)
249{ 255{
250 struct hda_jack_tbl *gated = snd_hda_jack_tbl_get(codec, gated_nid); 256 struct hda_jack_tbl *gated = snd_hda_jack_tbl_new(codec, gated_nid);
251 struct hda_jack_tbl *gating = snd_hda_jack_tbl_get(codec, gating_nid); 257 struct hda_jack_tbl *gating = snd_hda_jack_tbl_new(codec, gating_nid);
252 258
253 if (!gated || !gating) 259 if (!gated || !gating)
254 return -EINVAL; 260 return -EINVAL;
diff --git a/sound/pci/hda/hda_jack.h b/sound/pci/hda/hda_jack.h
index ec12abd45263..379420c44eef 100644
--- a/sound/pci/hda/hda_jack.h
+++ b/sound/pci/hda/hda_jack.h
@@ -75,7 +75,18 @@ int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid,
75 hda_nid_t gating_nid); 75 hda_nid_t gating_nid);
76 76
77u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 77u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid);
78int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 78
79/* the jack state returned from snd_hda_jack_detect_state() */
80enum {
81 HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT, HDA_JACK_PHANTOM,
82};
83
84int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid);
85
86static inline bool snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
87{
88 return snd_hda_jack_detect_state(codec, nid) != HDA_JACK_NOT_PRESENT;
89}
79 90
80bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid); 91bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid);
81 92
diff --git a/sound/pci/hda/hda_proc.c b/sound/pci/hda/hda_proc.c
index 9760f001916d..a8cb22eec89e 100644
--- a/sound/pci/hda/hda_proc.c
+++ b/sound/pci/hda/hda_proc.c
@@ -582,6 +582,36 @@ static void print_gpio(struct snd_info_buffer *buffer,
582 print_nid_array(buffer, codec, nid, &codec->nids); 582 print_nid_array(buffer, codec, nid, &codec->nids);
583} 583}
584 584
585static void print_device_list(struct snd_info_buffer *buffer,
586 struct hda_codec *codec, hda_nid_t nid)
587{
588 int i, curr = -1;
589 u8 dev_list[AC_MAX_DEV_LIST_LEN];
590 int devlist_len;
591
592 devlist_len = snd_hda_get_devices(codec, nid, dev_list,
593 AC_MAX_DEV_LIST_LEN);
594 snd_iprintf(buffer, " Devices: %d\n", devlist_len);
595 if (devlist_len <= 0)
596 return;
597
598 curr = snd_hda_codec_read(codec, nid, 0,
599 AC_VERB_GET_DEVICE_SEL, 0);
600
601 for (i = 0; i < devlist_len; i++) {
602 if (i == curr)
603 snd_iprintf(buffer, " *");
604 else
605 snd_iprintf(buffer, " ");
606
607 snd_iprintf(buffer,
608 "Dev %02d: PD = %d, ELDV = %d, IA = %d\n", i,
609 !!(dev_list[i] & AC_DE_PD),
610 !!(dev_list[i] & AC_DE_ELDV),
611 !!(dev_list[i] & AC_DE_IA));
612 }
613}
614
585static void print_codec_info(struct snd_info_entry *entry, 615static void print_codec_info(struct snd_info_entry *entry,
586 struct snd_info_buffer *buffer) 616 struct snd_info_buffer *buffer)
587{ 617{
@@ -751,6 +781,9 @@ static void print_codec_info(struct snd_info_entry *entry,
751 (wid_caps & AC_WCAP_DELAY) >> 781 (wid_caps & AC_WCAP_DELAY) >>
752 AC_WCAP_DELAY_SHIFT); 782 AC_WCAP_DELAY_SHIFT);
753 783
784 if (wid_type == AC_WID_PIN && codec->dp_mst)
785 print_device_list(buffer, codec, nid);
786
754 if (wid_caps & AC_WCAP_CONN_LIST) 787 if (wid_caps & AC_WCAP_CONN_LIST)
755 print_conn_list(buffer, codec, nid, wid_type, 788 print_conn_list(buffer, codec, nid, wid_type,
756 conn, conn_len); 789 conn, conn_len);
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c
index d97f0d61a15b..0cbdd87dde6d 100644
--- a/sound/pci/hda/patch_analog.c
+++ b/sound/pci/hda/patch_analog.c
@@ -32,7 +32,6 @@
32#include "hda_jack.h" 32#include "hda_jack.h"
33#include "hda_generic.h" 33#include "hda_generic.h"
34 34
35#define ENABLE_AD_STATIC_QUIRKS
36 35
37struct ad198x_spec { 36struct ad198x_spec {
38 struct hda_gen_spec gen; 37 struct hda_gen_spec gen;
@@ -43,114 +42,8 @@ struct ad198x_spec {
43 hda_nid_t eapd_nid; 42 hda_nid_t eapd_nid;
44 43
45 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 44 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */
46
47#ifdef ENABLE_AD_STATIC_QUIRKS
48 const struct snd_kcontrol_new *mixers[6];
49 int num_mixers;
50 const struct hda_verb *init_verbs[6]; /* initialization verbs
51 * don't forget NULL termination!
52 */
53 unsigned int num_init_verbs;
54
55 /* playback */
56 struct hda_multi_out multiout; /* playback set-up
57 * max_channels, dacs must be set
58 * dig_out_nid and hp_nid are optional
59 */
60 unsigned int cur_eapd;
61 unsigned int need_dac_fix;
62
63 /* capture */
64 unsigned int num_adc_nids;
65 const hda_nid_t *adc_nids;
66 hda_nid_t dig_in_nid; /* digital-in NID; optional */
67
68 /* capture source */
69 const struct hda_input_mux *input_mux;
70 const hda_nid_t *capsrc_nids;
71 unsigned int cur_mux[3];
72
73 /* channel model */
74 const struct hda_channel_mode *channel_mode;
75 int num_channel_mode;
76
77 /* PCM information */
78 struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */
79
80 unsigned int spdif_route;
81
82 unsigned int jack_present: 1;
83 unsigned int inv_jack_detect: 1;/* inverted jack-detection */
84 unsigned int analog_beep: 1; /* analog beep input present */
85 unsigned int avoid_init_slave_vol:1;
86
87#ifdef CONFIG_PM
88 struct hda_loopback_check loopback;
89#endif
90 /* for virtual master */
91 hda_nid_t vmaster_nid;
92 const char * const *slave_vols;
93 const char * const *slave_sws;
94#endif /* ENABLE_AD_STATIC_QUIRKS */
95};
96
97#ifdef ENABLE_AD_STATIC_QUIRKS
98/*
99 * input MUX handling (common part)
100 */
101static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
102{
103 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
104 struct ad198x_spec *spec = codec->spec;
105
106 return snd_hda_input_mux_info(spec->input_mux, uinfo);
107}
108
109static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
110{
111 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
112 struct ad198x_spec *spec = codec->spec;
113 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
114
115 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
116 return 0;
117}
118
119static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
120{
121 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
122 struct ad198x_spec *spec = codec->spec;
123 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
124
125 return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol,
126 spec->capsrc_nids[adc_idx],
127 &spec->cur_mux[adc_idx]);
128}
129
130/*
131 * initialization (common callbacks)
132 */
133static int ad198x_init(struct hda_codec *codec)
134{
135 struct ad198x_spec *spec = codec->spec;
136 int i;
137
138 for (i = 0; i < spec->num_init_verbs; i++)
139 snd_hda_sequence_write(codec, spec->init_verbs[i]);
140 return 0;
141}
142
143static const char * const ad_slave_pfxs[] = {
144 "Front", "Surround", "Center", "LFE", "Side",
145 "Headphone", "Mono", "Speaker", "IEC958",
146 NULL
147}; 45};
148 46
149static const char * const ad1988_6stack_fp_slave_pfxs[] = {
150 "Front", "Surround", "Center", "LFE", "Side", "IEC958",
151 NULL
152};
153#endif /* ENABLE_AD_STATIC_QUIRKS */
154 47
155#ifdef CONFIG_SND_HDA_INPUT_BEEP 48#ifdef CONFIG_SND_HDA_INPUT_BEEP
156/* additional beep mixers; the actual parameters are overwritten at build */ 49/* additional beep mixers; the actual parameters are overwritten at build */
@@ -160,12 +53,6 @@ static const struct snd_kcontrol_new ad_beep_mixer[] = {
160 { } /* end */ 53 { } /* end */
161}; 54};
162 55
163static const struct snd_kcontrol_new ad_beep2_mixer[] = {
164 HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT),
165 HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT),
166 { } /* end */
167};
168
169#define set_beep_amp(spec, nid, idx, dir) \ 56#define set_beep_amp(spec, nid, idx, dir) \
170 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */ 57 ((spec)->beep_amp = HDA_COMPOSE_AMP_VAL(nid, 1, idx, dir)) /* mono */
171#else 58#else
@@ -181,8 +68,7 @@ static int create_beep_ctls(struct hda_codec *codec)
181 if (!spec->beep_amp) 68 if (!spec->beep_amp)
182 return 0; 69 return 0;
183 70
184 knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; 71 for (knew = ad_beep_mixer ; knew->name; knew++) {
185 for ( ; knew->name; knew++) {
186 int err; 72 int err;
187 struct snd_kcontrol *kctl; 73 struct snd_kcontrol *kctl;
188 kctl = snd_ctl_new1(knew, codec); 74 kctl = snd_ctl_new1(knew, codec);
@@ -199,268 +85,6 @@ static int create_beep_ctls(struct hda_codec *codec)
199#define create_beep_ctls(codec) 0 85#define create_beep_ctls(codec) 0
200#endif 86#endif
201 87
202#ifdef ENABLE_AD_STATIC_QUIRKS
203static int ad198x_build_controls(struct hda_codec *codec)
204{
205 struct ad198x_spec *spec = codec->spec;
206 struct snd_kcontrol *kctl;
207 unsigned int i;
208 int err;
209
210 for (i = 0; i < spec->num_mixers; i++) {
211 err = snd_hda_add_new_ctls(codec, spec->mixers[i]);
212 if (err < 0)
213 return err;
214 }
215 if (spec->multiout.dig_out_nid) {
216 err = snd_hda_create_spdif_out_ctls(codec,
217 spec->multiout.dig_out_nid,
218 spec->multiout.dig_out_nid);
219 if (err < 0)
220 return err;
221 err = snd_hda_create_spdif_share_sw(codec,
222 &spec->multiout);
223 if (err < 0)
224 return err;
225 spec->multiout.share_spdif = 1;
226 }
227 if (spec->dig_in_nid) {
228 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
229 if (err < 0)
230 return err;
231 }
232
233 /* create beep controls if needed */
234 err = create_beep_ctls(codec);
235 if (err < 0)
236 return err;
237
238 /* if we have no master control, let's create it */
239 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
240 unsigned int vmaster_tlv[4];
241 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
242 HDA_OUTPUT, vmaster_tlv);
243 err = __snd_hda_add_vmaster(codec, "Master Playback Volume",
244 vmaster_tlv,
245 (spec->slave_vols ?
246 spec->slave_vols : ad_slave_pfxs),
247 "Playback Volume",
248 !spec->avoid_init_slave_vol, NULL);
249 if (err < 0)
250 return err;
251 }
252 if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
253 err = snd_hda_add_vmaster(codec, "Master Playback Switch",
254 NULL,
255 (spec->slave_sws ?
256 spec->slave_sws : ad_slave_pfxs),
257 "Playback Switch");
258 if (err < 0)
259 return err;
260 }
261
262 /* assign Capture Source enums to NID */
263 kctl = snd_hda_find_mixer_ctl(codec, "Capture Source");
264 if (!kctl)
265 kctl = snd_hda_find_mixer_ctl(codec, "Input Source");
266 for (i = 0; kctl && i < kctl->count; i++) {
267 err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]);
268 if (err < 0)
269 return err;
270 }
271
272 /* assign IEC958 enums to NID */
273 kctl = snd_hda_find_mixer_ctl(codec,
274 SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source");
275 if (kctl) {
276 err = snd_hda_add_nid(codec, kctl, 0,
277 spec->multiout.dig_out_nid);
278 if (err < 0)
279 return err;
280 }
281
282 return 0;
283}
284
285#ifdef CONFIG_PM
286static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid)
287{
288 struct ad198x_spec *spec = codec->spec;
289 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
290}
291#endif
292
293/*
294 * Analog playback callbacks
295 */
296static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo,
297 struct hda_codec *codec,
298 struct snd_pcm_substream *substream)
299{
300 struct ad198x_spec *spec = codec->spec;
301 return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream,
302 hinfo);
303}
304
305static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
306 struct hda_codec *codec,
307 unsigned int stream_tag,
308 unsigned int format,
309 struct snd_pcm_substream *substream)
310{
311 struct ad198x_spec *spec = codec->spec;
312 return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag,
313 format, substream);
314}
315
316static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
317 struct hda_codec *codec,
318 struct snd_pcm_substream *substream)
319{
320 struct ad198x_spec *spec = codec->spec;
321 return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
322}
323
324/*
325 * Digital out
326 */
327static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
328 struct hda_codec *codec,
329 struct snd_pcm_substream *substream)
330{
331 struct ad198x_spec *spec = codec->spec;
332 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
333}
334
335static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
336 struct hda_codec *codec,
337 struct snd_pcm_substream *substream)
338{
339 struct ad198x_spec *spec = codec->spec;
340 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
341}
342
343static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
344 struct hda_codec *codec,
345 unsigned int stream_tag,
346 unsigned int format,
347 struct snd_pcm_substream *substream)
348{
349 struct ad198x_spec *spec = codec->spec;
350 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag,
351 format, substream);
352}
353
354static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
355 struct hda_codec *codec,
356 struct snd_pcm_substream *substream)
357{
358 struct ad198x_spec *spec = codec->spec;
359 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
360}
361
362/*
363 * Analog capture
364 */
365static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
366 struct hda_codec *codec,
367 unsigned int stream_tag,
368 unsigned int format,
369 struct snd_pcm_substream *substream)
370{
371 struct ad198x_spec *spec = codec->spec;
372 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number],
373 stream_tag, 0, format);
374 return 0;
375}
376
377static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
378 struct hda_codec *codec,
379 struct snd_pcm_substream *substream)
380{
381 struct ad198x_spec *spec = codec->spec;
382 snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]);
383 return 0;
384}
385
386/*
387 */
388static const struct hda_pcm_stream ad198x_pcm_analog_playback = {
389 .substreams = 1,
390 .channels_min = 2,
391 .channels_max = 6, /* changed later */
392 .nid = 0, /* fill later */
393 .ops = {
394 .open = ad198x_playback_pcm_open,
395 .prepare = ad198x_playback_pcm_prepare,
396 .cleanup = ad198x_playback_pcm_cleanup,
397 },
398};
399
400static const struct hda_pcm_stream ad198x_pcm_analog_capture = {
401 .substreams = 1,
402 .channels_min = 2,
403 .channels_max = 2,
404 .nid = 0, /* fill later */
405 .ops = {
406 .prepare = ad198x_capture_pcm_prepare,
407 .cleanup = ad198x_capture_pcm_cleanup
408 },
409};
410
411static const struct hda_pcm_stream ad198x_pcm_digital_playback = {
412 .substreams = 1,
413 .channels_min = 2,
414 .channels_max = 2,
415 .nid = 0, /* fill later */
416 .ops = {
417 .open = ad198x_dig_playback_pcm_open,
418 .close = ad198x_dig_playback_pcm_close,
419 .prepare = ad198x_dig_playback_pcm_prepare,
420 .cleanup = ad198x_dig_playback_pcm_cleanup
421 },
422};
423
424static const struct hda_pcm_stream ad198x_pcm_digital_capture = {
425 .substreams = 1,
426 .channels_min = 2,
427 .channels_max = 2,
428 /* NID is set in alc_build_pcms */
429};
430
431static int ad198x_build_pcms(struct hda_codec *codec)
432{
433 struct ad198x_spec *spec = codec->spec;
434 struct hda_pcm *info = spec->pcm_rec;
435
436 codec->num_pcms = 1;
437 codec->pcm_info = info;
438
439 info->name = "AD198x Analog";
440 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback;
441 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels;
442 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
443 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture;
444 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids;
445 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
446
447 if (spec->multiout.dig_out_nid) {
448 info++;
449 codec->num_pcms++;
450 codec->spdif_status_reset = 1;
451 info->name = "AD198x Digital";
452 info->pcm_type = HDA_PCM_TYPE_SPDIF;
453 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback;
454 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
455 if (spec->dig_in_nid) {
456 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture;
457 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
458 }
459 }
460
461 return 0;
462}
463#endif /* ENABLE_AD_STATIC_QUIRKS */
464 88
465static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, 89static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front,
466 hda_nid_t hp) 90 hda_nid_t hp)
@@ -507,18 +131,6 @@ static void ad198x_shutup(struct hda_codec *codec)
507 ad198x_power_eapd(codec); 131 ad198x_power_eapd(codec);
508} 132}
509 133
510static void ad198x_free(struct hda_codec *codec)
511{
512 struct ad198x_spec *spec = codec->spec;
513
514 if (!spec)
515 return;
516
517 snd_hda_gen_spec_free(&spec->gen);
518 kfree(spec);
519 snd_hda_detach_beep_device(codec);
520}
521
522#ifdef CONFIG_PM 134#ifdef CONFIG_PM
523static int ad198x_suspend(struct hda_codec *codec) 135static int ad198x_suspend(struct hda_codec *codec)
524{ 136{
@@ -527,65 +139,6 @@ static int ad198x_suspend(struct hda_codec *codec)
527} 139}
528#endif 140#endif
529 141
530#ifdef ENABLE_AD_STATIC_QUIRKS
531static const struct hda_codec_ops ad198x_patch_ops = {
532 .build_controls = ad198x_build_controls,
533 .build_pcms = ad198x_build_pcms,
534 .init = ad198x_init,
535 .free = ad198x_free,
536#ifdef CONFIG_PM
537 .check_power_status = ad198x_check_power_status,
538 .suspend = ad198x_suspend,
539#endif
540 .reboot_notify = ad198x_shutup,
541};
542
543
544/*
545 * EAPD control
546 * the private value = nid
547 */
548#define ad198x_eapd_info snd_ctl_boolean_mono_info
549
550static int ad198x_eapd_get(struct snd_kcontrol *kcontrol,
551 struct snd_ctl_elem_value *ucontrol)
552{
553 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
554 struct ad198x_spec *spec = codec->spec;
555 if (codec->inv_eapd)
556 ucontrol->value.integer.value[0] = ! spec->cur_eapd;
557 else
558 ucontrol->value.integer.value[0] = spec->cur_eapd;
559 return 0;
560}
561
562static int ad198x_eapd_put(struct snd_kcontrol *kcontrol,
563 struct snd_ctl_elem_value *ucontrol)
564{
565 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
566 struct ad198x_spec *spec = codec->spec;
567 hda_nid_t nid = kcontrol->private_value & 0xff;
568 unsigned int eapd;
569 eapd = !!ucontrol->value.integer.value[0];
570 if (codec->inv_eapd)
571 eapd = !eapd;
572 if (eapd == spec->cur_eapd)
573 return 0;
574 spec->cur_eapd = eapd;
575 snd_hda_codec_write_cache(codec, nid,
576 0, AC_VERB_SET_EAPD_BTLENABLE,
577 eapd ? 0x02 : 0x00);
578 return 1;
579}
580
581static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
582 struct snd_ctl_elem_info *uinfo);
583static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol,
584 struct snd_ctl_elem_value *ucontrol);
585static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
586 struct snd_ctl_elem_value *ucontrol);
587#endif /* ENABLE_AD_STATIC_QUIRKS */
588
589 142
590/* 143/*
591 * Automatic parse of I/O pins from the BIOS configuration 144 * Automatic parse of I/O pins from the BIOS configuration
@@ -646,537 +199,6 @@ static int ad198x_parse_auto_config(struct hda_codec *codec)
646 * AD1986A specific 199 * AD1986A specific
647 */ 200 */
648 201
649#ifdef ENABLE_AD_STATIC_QUIRKS
650#define AD1986A_SPDIF_OUT 0x02
651#define AD1986A_FRONT_DAC 0x03
652#define AD1986A_SURR_DAC 0x04
653#define AD1986A_CLFE_DAC 0x05
654#define AD1986A_ADC 0x06
655
656static const hda_nid_t ad1986a_dac_nids[3] = {
657 AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC
658};
659static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC };
660static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 };
661
662static const struct hda_input_mux ad1986a_capture_source = {
663 .num_items = 7,
664 .items = {
665 { "Mic", 0x0 },
666 { "CD", 0x1 },
667 { "Aux", 0x3 },
668 { "Line", 0x4 },
669 { "Mix", 0x5 },
670 { "Mono", 0x6 },
671 { "Phone", 0x7 },
672 },
673};
674
675
676static const struct hda_bind_ctls ad1986a_bind_pcm_vol = {
677 .ops = &snd_hda_bind_vol,
678 .values = {
679 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
680 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
681 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
682 0
683 },
684};
685
686static const struct hda_bind_ctls ad1986a_bind_pcm_sw = {
687 .ops = &snd_hda_bind_sw,
688 .values = {
689 HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT),
690 HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT),
691 HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT),
692 0
693 },
694};
695
696/*
697 * mixers
698 */
699static const struct snd_kcontrol_new ad1986a_mixers[] = {
700 /*
701 * bind volumes/mutes of 3 DACs as a single PCM control for simplicity
702 */
703 HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol),
704 HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw),
705 HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
706 HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
707 HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
708 HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
709 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT),
710 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT),
711 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT),
712 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT),
713 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT),
714 HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT),
715 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
716 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
717 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
718 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
719 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
720 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
721 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
722 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
723 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
724 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
725 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT),
726 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
727 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
728 {
729 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
730 .name = "Capture Source",
731 .info = ad198x_mux_enum_info,
732 .get = ad198x_mux_enum_get,
733 .put = ad198x_mux_enum_put,
734 },
735 HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT),
736 { } /* end */
737};
738
739/* additional mixers for 3stack mode */
740static const struct snd_kcontrol_new ad1986a_3st_mixers[] = {
741 {
742 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
743 .name = "Channel Mode",
744 .info = ad198x_ch_mode_info,
745 .get = ad198x_ch_mode_get,
746 .put = ad198x_ch_mode_put,
747 },
748 { } /* end */
749};
750
751/* laptop model - 2ch only */
752static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC };
753
754/* master controls both pins 0x1a and 0x1b */
755static const struct hda_bind_ctls ad1986a_laptop_master_vol = {
756 .ops = &snd_hda_bind_vol,
757 .values = {
758 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
759 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
760 0,
761 },
762};
763
764static const struct hda_bind_ctls ad1986a_laptop_master_sw = {
765 .ops = &snd_hda_bind_sw,
766 .values = {
767 HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
768 HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT),
769 0,
770 },
771};
772
773static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = {
774 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
775 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
776 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
777 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
778 HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT),
779 HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT),
780 HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT),
781 HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT),
782 HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT),
783 HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT),
784 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
785 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
786 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
787 /*
788 HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT),
789 HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */
790 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
791 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
792 {
793 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
794 .name = "Capture Source",
795 .info = ad198x_mux_enum_info,
796 .get = ad198x_mux_enum_get,
797 .put = ad198x_mux_enum_put,
798 },
799 { } /* end */
800};
801
802/* laptop-eapd model - 2ch only */
803
804static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = {
805 .num_items = 3,
806 .items = {
807 { "Mic", 0x0 },
808 { "Internal Mic", 0x4 },
809 { "Mix", 0x5 },
810 },
811};
812
813static const struct hda_input_mux ad1986a_automic_capture_source = {
814 .num_items = 2,
815 .items = {
816 { "Mic", 0x0 },
817 { "Mix", 0x5 },
818 },
819};
820
821static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = {
822 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
823 HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw),
824 { } /* end */
825};
826
827static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = {
828 HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT),
829 HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT),
830 HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
831 HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
832 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT),
833 HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT),
834 HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT),
835 {
836 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
837 .name = "Capture Source",
838 .info = ad198x_mux_enum_info,
839 .get = ad198x_mux_enum_get,
840 .put = ad198x_mux_enum_put,
841 },
842 {
843 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
844 .name = "External Amplifier",
845 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
846 .info = ad198x_eapd_info,
847 .get = ad198x_eapd_get,
848 .put = ad198x_eapd_put,
849 .private_value = 0x1b, /* port-D */
850 },
851 { } /* end */
852};
853
854static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = {
855 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT),
856 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT),
857 { } /* end */
858};
859
860/* re-connect the mic boost input according to the jack sensing */
861static void ad1986a_automic(struct hda_codec *codec)
862{
863 unsigned int present;
864 present = snd_hda_jack_detect(codec, 0x1f);
865 /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */
866 snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL,
867 present ? 0 : 2);
868}
869
870#define AD1986A_MIC_EVENT 0x36
871
872static void ad1986a_automic_unsol_event(struct hda_codec *codec,
873 unsigned int res)
874{
875 if ((res >> 26) != AD1986A_MIC_EVENT)
876 return;
877 ad1986a_automic(codec);
878}
879
880static int ad1986a_automic_init(struct hda_codec *codec)
881{
882 ad198x_init(codec);
883 ad1986a_automic(codec);
884 return 0;
885}
886
887/* laptop-automute - 2ch only */
888
889static void ad1986a_update_hp(struct hda_codec *codec)
890{
891 struct ad198x_spec *spec = codec->spec;
892 unsigned int mute;
893
894 if (spec->jack_present)
895 mute = HDA_AMP_MUTE; /* mute internal speaker */
896 else
897 /* unmute internal speaker if necessary */
898 mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0);
899 snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0,
900 HDA_AMP_MUTE, mute);
901}
902
903static void ad1986a_hp_automute(struct hda_codec *codec)
904{
905 struct ad198x_spec *spec = codec->spec;
906
907 spec->jack_present = snd_hda_jack_detect(codec, 0x1a);
908 if (spec->inv_jack_detect)
909 spec->jack_present = !spec->jack_present;
910 ad1986a_update_hp(codec);
911}
912
913#define AD1986A_HP_EVENT 0x37
914
915static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
916{
917 if ((res >> 26) != AD1986A_HP_EVENT)
918 return;
919 ad1986a_hp_automute(codec);
920}
921
922static int ad1986a_hp_init(struct hda_codec *codec)
923{
924 ad198x_init(codec);
925 ad1986a_hp_automute(codec);
926 return 0;
927}
928
929/* bind hp and internal speaker mute (with plug check) */
930static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol,
931 struct snd_ctl_elem_value *ucontrol)
932{
933 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
934 int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
935 if (change)
936 ad1986a_update_hp(codec);
937 return change;
938}
939
940static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = {
941 HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol),
942 {
943 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
944 .name = "Master Playback Switch",
945 .subdevice = HDA_SUBDEV_AMP_FLAG,
946 .info = snd_hda_mixer_amp_switch_info,
947 .get = snd_hda_mixer_amp_switch_get,
948 .put = ad1986a_hp_master_sw_put,
949 .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT),
950 },
951 { } /* end */
952};
953
954
955/*
956 * initialization verbs
957 */
958static const struct hda_verb ad1986a_init_verbs[] = {
959 /* Front, Surround, CLFE DAC; mute as default */
960 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
961 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
962 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
963 /* Downmix - off */
964 {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
965 /* HP, Line-Out, Surround, CLFE selectors */
966 {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0},
967 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0},
968 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
969 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
970 /* Mono selector */
971 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0},
972 /* Mic selector: Mic 1/2 pin */
973 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
974 /* Line-in selector: Line-in */
975 {0x10, AC_VERB_SET_CONNECT_SEL, 0x0},
976 /* Mic 1/2 swap */
977 {0x11, AC_VERB_SET_CONNECT_SEL, 0x0},
978 /* Record selector: mic */
979 {0x12, AC_VERB_SET_CONNECT_SEL, 0x0},
980 /* Mic, Phone, CD, Aux, Line-In amp; mute as default */
981 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
982 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
983 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
984 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
985 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
986 /* PC beep */
987 {0x18, AC_VERB_SET_CONNECT_SEL, 0x0},
988 /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */
989 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
990 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
991 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
992 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
993 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
994 /* HP Pin */
995 {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
996 /* Front, Surround, CLFE Pins */
997 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
998 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
999 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1000 /* Mono Pin */
1001 {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1002 /* Mic Pin */
1003 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1004 /* Line, Aux, CD, Beep-In Pin */
1005 {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1006 {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1007 {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1008 {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1009 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1010 { } /* end */
1011};
1012
1013static const struct hda_verb ad1986a_ch2_init[] = {
1014 /* Surround out -> Line In */
1015 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
1016 /* Line-in selectors */
1017 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 },
1018 /* CLFE -> Mic in */
1019 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1020 /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */
1021 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
1022 { } /* end */
1023};
1024
1025static const struct hda_verb ad1986a_ch4_init[] = {
1026 /* Surround out -> Surround */
1027 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1028 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1029 /* CLFE -> Mic in */
1030 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
1031 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 },
1032 { } /* end */
1033};
1034
1035static const struct hda_verb ad1986a_ch6_init[] = {
1036 /* Surround out -> Surround out */
1037 { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1038 { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 },
1039 /* CLFE -> CLFE */
1040 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
1041 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 },
1042 { } /* end */
1043};
1044
1045static const struct hda_channel_mode ad1986a_modes[3] = {
1046 { 2, ad1986a_ch2_init },
1047 { 4, ad1986a_ch4_init },
1048 { 6, ad1986a_ch6_init },
1049};
1050
1051/* eapd initialization */
1052static const struct hda_verb ad1986a_eapd_init_verbs[] = {
1053 {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1054 {}
1055};
1056
1057static const struct hda_verb ad1986a_automic_verbs[] = {
1058 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1059 {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
1060 /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/
1061 {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0},
1062 {0x1f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_MIC_EVENT},
1063 {}
1064};
1065
1066/* Ultra initialization */
1067static const struct hda_verb ad1986a_ultra_init[] = {
1068 /* eapd initialization */
1069 { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 },
1070 /* CLFE -> Mic in */
1071 { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 },
1072 { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1073 { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 },
1074 { } /* end */
1075};
1076
1077/* pin sensing on HP jack */
1078static const struct hda_verb ad1986a_hp_init_verbs[] = {
1079 {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT},
1080 {}
1081};
1082
1083static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec,
1084 unsigned int res)
1085{
1086 switch (res >> 26) {
1087 case AD1986A_HP_EVENT:
1088 ad1986a_hp_automute(codec);
1089 break;
1090 case AD1986A_MIC_EVENT:
1091 ad1986a_automic(codec);
1092 break;
1093 }
1094}
1095
1096static int ad1986a_samsung_p50_init(struct hda_codec *codec)
1097{
1098 ad198x_init(codec);
1099 ad1986a_hp_automute(codec);
1100 ad1986a_automic(codec);
1101 return 0;
1102}
1103
1104
1105/* models */
1106enum {
1107 AD1986A_AUTO,
1108 AD1986A_6STACK,
1109 AD1986A_3STACK,
1110 AD1986A_LAPTOP,
1111 AD1986A_LAPTOP_EAPD,
1112 AD1986A_LAPTOP_AUTOMUTE,
1113 AD1986A_ULTRA,
1114 AD1986A_SAMSUNG,
1115 AD1986A_SAMSUNG_P50,
1116 AD1986A_MODELS
1117};
1118
1119static const char * const ad1986a_models[AD1986A_MODELS] = {
1120 [AD1986A_AUTO] = "auto",
1121 [AD1986A_6STACK] = "6stack",
1122 [AD1986A_3STACK] = "3stack",
1123 [AD1986A_LAPTOP] = "laptop",
1124 [AD1986A_LAPTOP_EAPD] = "laptop-eapd",
1125 [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute",
1126 [AD1986A_ULTRA] = "ultra",
1127 [AD1986A_SAMSUNG] = "samsung",
1128 [AD1986A_SAMSUNG_P50] = "samsung-p50",
1129};
1130
1131static const struct snd_pci_quirk ad1986a_cfg_tbl[] = {
1132 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD),
1133 SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD),
1134 SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD),
1135 SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD),
1136 SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD),
1137 SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD),
1138 SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD),
1139 SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD),
1140 SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP),
1141 SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK),
1142 SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK),
1143 SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP),
1144 SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK),
1145 SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK),
1146 SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK),
1147 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK),
1148 SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK),
1149 SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK),
1150 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP),
1151 SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50),
1152 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA),
1153 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG),
1154 SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK),
1155 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP),
1156 SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK),
1157 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE),
1158 SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP),
1159 {}
1160};
1161
1162#ifdef CONFIG_PM
1163static const struct hda_amp_list ad1986a_loopbacks[] = {
1164 { 0x13, HDA_OUTPUT, 0 }, /* Mic */
1165 { 0x14, HDA_OUTPUT, 0 }, /* Phone */
1166 { 0x15, HDA_OUTPUT, 0 }, /* CD */
1167 { 0x16, HDA_OUTPUT, 0 }, /* Aux */
1168 { 0x17, HDA_OUTPUT, 0 }, /* Line */
1169 { } /* end */
1170};
1171#endif
1172
1173static int is_jack_available(struct hda_codec *codec, hda_nid_t nid)
1174{
1175 unsigned int conf = snd_hda_codec_get_pincfg(codec, nid);
1176 return get_defcfg_connect(conf) != AC_JACK_PORT_NONE;
1177}
1178#endif /* ENABLE_AD_STATIC_QUIRKS */
1179
1180static int alloc_ad_spec(struct hda_codec *codec) 202static int alloc_ad_spec(struct hda_codec *codec)
1181{ 203{
1182 struct ad198x_spec *spec; 204 struct ad198x_spec *spec;
@@ -1203,6 +225,11 @@ static void ad_fixup_inv_jack_detect(struct hda_codec *codec,
1203 225
1204enum { 226enum {
1205 AD1986A_FIXUP_INV_JACK_DETECT, 227 AD1986A_FIXUP_INV_JACK_DETECT,
228 AD1986A_FIXUP_ULTRA,
229 AD1986A_FIXUP_SAMSUNG,
230 AD1986A_FIXUP_3STACK,
231 AD1986A_FIXUP_LAPTOP,
232 AD1986A_FIXUP_LAPTOP_IMIC,
1206}; 233};
1207 234
1208static const struct hda_fixup ad1986a_fixups[] = { 235static const struct hda_fixup ad1986a_fixups[] = {
@@ -1210,16 +237,86 @@ static const struct hda_fixup ad1986a_fixups[] = {
1210 .type = HDA_FIXUP_FUNC, 237 .type = HDA_FIXUP_FUNC,
1211 .v.func = ad_fixup_inv_jack_detect, 238 .v.func = ad_fixup_inv_jack_detect,
1212 }, 239 },
240 [AD1986A_FIXUP_ULTRA] = {
241 .type = HDA_FIXUP_PINS,
242 .v.pins = (const struct hda_pintbl[]) {
243 { 0x1b, 0x90170110 }, /* speaker */
244 { 0x1d, 0x90a7013e }, /* int mic */
245 {}
246 },
247 },
248 [AD1986A_FIXUP_SAMSUNG] = {
249 .type = HDA_FIXUP_PINS,
250 .v.pins = (const struct hda_pintbl[]) {
251 { 0x1b, 0x90170110 }, /* speaker */
252 { 0x1d, 0x90a7013e }, /* int mic */
253 { 0x20, 0x411111f0 }, /* N/A */
254 { 0x24, 0x411111f0 }, /* N/A */
255 {}
256 },
257 },
258 [AD1986A_FIXUP_3STACK] = {
259 .type = HDA_FIXUP_PINS,
260 .v.pins = (const struct hda_pintbl[]) {
261 { 0x1a, 0x02214021 }, /* headphone */
262 { 0x1b, 0x01014011 }, /* front */
263 { 0x1c, 0x01013012 }, /* surround */
264 { 0x1d, 0x01019015 }, /* clfe */
265 { 0x1e, 0x411111f0 }, /* N/A */
266 { 0x1f, 0x02a190f0 }, /* mic */
267 { 0x20, 0x018130f0 }, /* line-in */
268 {}
269 },
270 },
271 [AD1986A_FIXUP_LAPTOP] = {
272 .type = HDA_FIXUP_PINS,
273 .v.pins = (const struct hda_pintbl[]) {
274 { 0x1a, 0x02214021 }, /* headphone */
275 { 0x1b, 0x90170110 }, /* speaker */
276 { 0x1c, 0x411111f0 }, /* N/A */
277 { 0x1d, 0x411111f0 }, /* N/A */
278 { 0x1e, 0x411111f0 }, /* N/A */
279 { 0x1f, 0x02a191f0 }, /* mic */
280 { 0x20, 0x411111f0 }, /* N/A */
281 {}
282 },
283 },
284 [AD1986A_FIXUP_LAPTOP_IMIC] = {
285 .type = HDA_FIXUP_PINS,
286 .v.pins = (const struct hda_pintbl[]) {
287 { 0x1d, 0x90a7013e }, /* int mic */
288 {}
289 },
290 .chained_before = 1,
291 .chain_id = AD1986A_FIXUP_LAPTOP,
292 },
1213}; 293};
1214 294
1215static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { 295static const struct snd_pci_quirk ad1986a_fixup_tbl[] = {
296 SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_FIXUP_LAPTOP_IMIC),
297 SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK),
298 SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK),
299 SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK),
300 SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP),
301 SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG),
302 SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA),
1216 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT), 303 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT),
304 SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_FIXUP_3STACK),
305 SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_FIXUP_3STACK),
306 {}
307};
308
309static const struct hda_model_fixup ad1986a_fixup_models[] = {
310 { .id = AD1986A_FIXUP_3STACK, .name = "3stack" },
311 { .id = AD1986A_FIXUP_LAPTOP, .name = "laptop" },
312 { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-imic" },
313 { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-eapd" }, /* alias */
1217 {} 314 {}
1218}; 315};
1219 316
1220/* 317/*
1221 */ 318 */
1222static int ad1986a_parse_auto_config(struct hda_codec *codec) 319static int patch_ad1986a(struct hda_codec *codec)
1223{ 320{
1224 int err; 321 int err;
1225 struct ad198x_spec *spec; 322 struct ad198x_spec *spec;
@@ -1244,7 +341,8 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec)
1244 */ 341 */
1245 spec->gen.multiout.no_share_stream = 1; 342 spec->gen.multiout.no_share_stream = 1;
1246 343
1247 snd_hda_pick_fixup(codec, NULL, ad1986a_fixup_tbl, ad1986a_fixups); 344 snd_hda_pick_fixup(codec, ad1986a_fixup_models, ad1986a_fixup_tbl,
345 ad1986a_fixups);
1248 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 346 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
1249 347
1250 err = ad198x_parse_auto_config(codec); 348 err = ad198x_parse_auto_config(codec);
@@ -1258,330 +356,11 @@ static int ad1986a_parse_auto_config(struct hda_codec *codec)
1258 return 0; 356 return 0;
1259} 357}
1260 358
1261#ifdef ENABLE_AD_STATIC_QUIRKS
1262static int patch_ad1986a(struct hda_codec *codec)
1263{
1264 struct ad198x_spec *spec;
1265 int err, board_config;
1266
1267 board_config = snd_hda_check_board_config(codec, AD1986A_MODELS,
1268 ad1986a_models,
1269 ad1986a_cfg_tbl);
1270 if (board_config < 0) {
1271 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
1272 codec->chip_name);
1273 board_config = AD1986A_AUTO;
1274 }
1275
1276 if (board_config == AD1986A_AUTO)
1277 return ad1986a_parse_auto_config(codec);
1278
1279 err = alloc_ad_spec(codec);
1280 if (err < 0)
1281 return err;
1282 spec = codec->spec;
1283
1284 err = snd_hda_attach_beep_device(codec, 0x19);
1285 if (err < 0) {
1286 ad198x_free(codec);
1287 return err;
1288 }
1289 set_beep_amp(spec, 0x18, 0, HDA_OUTPUT);
1290
1291 spec->multiout.max_channels = 6;
1292 spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids);
1293 spec->multiout.dac_nids = ad1986a_dac_nids;
1294 spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT;
1295 spec->num_adc_nids = 1;
1296 spec->adc_nids = ad1986a_adc_nids;
1297 spec->capsrc_nids = ad1986a_capsrc_nids;
1298 spec->input_mux = &ad1986a_capture_source;
1299 spec->num_mixers = 1;
1300 spec->mixers[0] = ad1986a_mixers;
1301 spec->num_init_verbs = 1;
1302 spec->init_verbs[0] = ad1986a_init_verbs;
1303#ifdef CONFIG_PM
1304 spec->loopback.amplist = ad1986a_loopbacks;
1305#endif
1306 spec->vmaster_nid = 0x1b;
1307 codec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */
1308
1309 codec->patch_ops = ad198x_patch_ops;
1310
1311 /* override some parameters */
1312 switch (board_config) {
1313 case AD1986A_3STACK:
1314 spec->num_mixers = 2;
1315 spec->mixers[1] = ad1986a_3st_mixers;
1316 spec->num_init_verbs = 2;
1317 spec->init_verbs[1] = ad1986a_ch2_init;
1318 spec->channel_mode = ad1986a_modes;
1319 spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes);
1320 spec->need_dac_fix = 1;
1321 spec->multiout.max_channels = 2;
1322 spec->multiout.num_dacs = 1;
1323 break;
1324 case AD1986A_LAPTOP:
1325 spec->mixers[0] = ad1986a_laptop_mixers;
1326 spec->multiout.max_channels = 2;
1327 spec->multiout.num_dacs = 1;
1328 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1329 break;
1330 case AD1986A_LAPTOP_EAPD:
1331 spec->num_mixers = 3;
1332 spec->mixers[0] = ad1986a_laptop_master_mixers;
1333 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1334 spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1335 spec->num_init_verbs = 2;
1336 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1337 spec->multiout.max_channels = 2;
1338 spec->multiout.num_dacs = 1;
1339 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1340 if (!is_jack_available(codec, 0x25))
1341 spec->multiout.dig_out_nid = 0;
1342 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1343 break;
1344 case AD1986A_SAMSUNG:
1345 spec->num_mixers = 2;
1346 spec->mixers[0] = ad1986a_laptop_master_mixers;
1347 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1348 spec->num_init_verbs = 3;
1349 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1350 spec->init_verbs[2] = ad1986a_automic_verbs;
1351 spec->multiout.max_channels = 2;
1352 spec->multiout.num_dacs = 1;
1353 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1354 if (!is_jack_available(codec, 0x25))
1355 spec->multiout.dig_out_nid = 0;
1356 spec->input_mux = &ad1986a_automic_capture_source;
1357 codec->patch_ops.unsol_event = ad1986a_automic_unsol_event;
1358 codec->patch_ops.init = ad1986a_automic_init;
1359 break;
1360 case AD1986A_SAMSUNG_P50:
1361 spec->num_mixers = 2;
1362 spec->mixers[0] = ad1986a_automute_master_mixers;
1363 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1364 spec->num_init_verbs = 4;
1365 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1366 spec->init_verbs[2] = ad1986a_automic_verbs;
1367 spec->init_verbs[3] = ad1986a_hp_init_verbs;
1368 spec->multiout.max_channels = 2;
1369 spec->multiout.num_dacs = 1;
1370 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1371 if (!is_jack_available(codec, 0x25))
1372 spec->multiout.dig_out_nid = 0;
1373 spec->input_mux = &ad1986a_automic_capture_source;
1374 codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event;
1375 codec->patch_ops.init = ad1986a_samsung_p50_init;
1376 break;
1377 case AD1986A_LAPTOP_AUTOMUTE:
1378 spec->num_mixers = 3;
1379 spec->mixers[0] = ad1986a_automute_master_mixers;
1380 spec->mixers[1] = ad1986a_laptop_eapd_mixers;
1381 spec->mixers[2] = ad1986a_laptop_intmic_mixers;
1382 spec->num_init_verbs = 3;
1383 spec->init_verbs[1] = ad1986a_eapd_init_verbs;
1384 spec->init_verbs[2] = ad1986a_hp_init_verbs;
1385 spec->multiout.max_channels = 2;
1386 spec->multiout.num_dacs = 1;
1387 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1388 if (!is_jack_available(codec, 0x25))
1389 spec->multiout.dig_out_nid = 0;
1390 spec->input_mux = &ad1986a_laptop_eapd_capture_source;
1391 codec->patch_ops.unsol_event = ad1986a_hp_unsol_event;
1392 codec->patch_ops.init = ad1986a_hp_init;
1393 /* Lenovo N100 seems to report the reversed bit
1394 * for HP jack-sensing
1395 */
1396 spec->inv_jack_detect = 1;
1397 break;
1398 case AD1986A_ULTRA:
1399 spec->mixers[0] = ad1986a_laptop_eapd_mixers;
1400 spec->num_init_verbs = 2;
1401 spec->init_verbs[1] = ad1986a_ultra_init;
1402 spec->multiout.max_channels = 2;
1403 spec->multiout.num_dacs = 1;
1404 spec->multiout.dac_nids = ad1986a_laptop_dac_nids;
1405 spec->multiout.dig_out_nid = 0;
1406 break;
1407 }
1408
1409 /* AD1986A has a hardware problem that it can't share a stream
1410 * with multiple output pins. The copy of front to surrounds
1411 * causes noisy or silent outputs at a certain timing, e.g.
1412 * changing the volume.
1413 * So, let's disable the shared stream.
1414 */
1415 spec->multiout.no_share_stream = 1;
1416
1417 codec->no_trigger_sense = 1;
1418 codec->no_sticky_stream = 1;
1419
1420 return 0;
1421}
1422#else /* ENABLE_AD_STATIC_QUIRKS */
1423#define patch_ad1986a ad1986a_parse_auto_config
1424#endif /* ENABLE_AD_STATIC_QUIRKS */
1425 359
1426/* 360/*
1427 * AD1983 specific 361 * AD1983 specific
1428 */ 362 */
1429 363
1430#ifdef ENABLE_AD_STATIC_QUIRKS
1431#define AD1983_SPDIF_OUT 0x02
1432#define AD1983_DAC 0x03
1433#define AD1983_ADC 0x04
1434
1435static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC };
1436static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC };
1437static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 };
1438
1439static const struct hda_input_mux ad1983_capture_source = {
1440 .num_items = 4,
1441 .items = {
1442 { "Mic", 0x0 },
1443 { "Line", 0x1 },
1444 { "Mix", 0x2 },
1445 { "Mix Mono", 0x3 },
1446 },
1447};
1448
1449/*
1450 * SPDIF playback route
1451 */
1452static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
1453{
1454 static const char * const texts[] = { "PCM", "ADC" };
1455
1456 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
1457 uinfo->count = 1;
1458 uinfo->value.enumerated.items = 2;
1459 if (uinfo->value.enumerated.item > 1)
1460 uinfo->value.enumerated.item = 1;
1461 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
1462 return 0;
1463}
1464
1465static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1466{
1467 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1468 struct ad198x_spec *spec = codec->spec;
1469
1470 ucontrol->value.enumerated.item[0] = spec->spdif_route;
1471 return 0;
1472}
1473
1474static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
1475{
1476 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1477 struct ad198x_spec *spec = codec->spec;
1478
1479 if (ucontrol->value.enumerated.item[0] > 1)
1480 return -EINVAL;
1481 if (spec->spdif_route != ucontrol->value.enumerated.item[0]) {
1482 spec->spdif_route = ucontrol->value.enumerated.item[0];
1483 snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0,
1484 AC_VERB_SET_CONNECT_SEL,
1485 spec->spdif_route);
1486 return 1;
1487 }
1488 return 0;
1489}
1490
1491static const struct snd_kcontrol_new ad1983_mixers[] = {
1492 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1493 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1494 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1495 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1496 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1497 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1498 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1499 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1500 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1501 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1502 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1503 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1504 HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT),
1505 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1506 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1507 {
1508 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1509 .name = "Capture Source",
1510 .info = ad198x_mux_enum_info,
1511 .get = ad198x_mux_enum_get,
1512 .put = ad198x_mux_enum_put,
1513 },
1514 {
1515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1516 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1517 .info = ad1983_spdif_route_info,
1518 .get = ad1983_spdif_route_get,
1519 .put = ad1983_spdif_route_put,
1520 },
1521 { } /* end */
1522};
1523
1524static const struct hda_verb ad1983_init_verbs[] = {
1525 /* Front, HP, Mono; mute as default */
1526 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1527 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1528 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1529 /* Beep, PCM, Mic, Line-In: mute */
1530 {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1531 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1532 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1533 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1534 /* Front, HP selectors; from Mix */
1535 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1536 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1537 /* Mono selector; from Mix */
1538 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1539 /* Mic selector; Mic */
1540 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
1541 /* Line-in selector: Line-in */
1542 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
1543 /* Mic boost: 0dB */
1544 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1545 /* Record selector: mic */
1546 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1547 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1548 /* SPDIF route: PCM */
1549 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1550 /* Front Pin */
1551 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1552 /* HP Pin */
1553 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1554 /* Mono Pin */
1555 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1556 /* Mic Pin */
1557 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1558 /* Line Pin */
1559 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1560 { } /* end */
1561};
1562
1563#ifdef CONFIG_PM
1564static const struct hda_amp_list ad1983_loopbacks[] = {
1565 { 0x12, HDA_OUTPUT, 0 }, /* Mic */
1566 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1567 { } /* end */
1568};
1569#endif
1570
1571/* models */
1572enum {
1573 AD1983_AUTO,
1574 AD1983_BASIC,
1575 AD1983_MODELS
1576};
1577
1578static const char * const ad1983_models[AD1983_MODELS] = {
1579 [AD1983_AUTO] = "auto",
1580 [AD1983_BASIC] = "basic",
1581};
1582#endif /* ENABLE_AD_STATIC_QUIRKS */
1583
1584
1585/* 364/*
1586 * SPDIF mux control for AD1983 auto-parser 365 * SPDIF mux control for AD1983 auto-parser
1587 */ 366 */
@@ -1656,7 +435,7 @@ static int ad1983_add_spdif_mux_ctl(struct hda_codec *codec)
1656 return 0; 435 return 0;
1657} 436}
1658 437
1659static int ad1983_parse_auto_config(struct hda_codec *codec) 438static int patch_ad1983(struct hda_codec *codec)
1660{ 439{
1661 struct ad198x_spec *spec; 440 struct ad198x_spec *spec;
1662 int err; 441 int err;
@@ -1681,432 +460,11 @@ static int ad1983_parse_auto_config(struct hda_codec *codec)
1681 return err; 460 return err;
1682} 461}
1683 462
1684#ifdef ENABLE_AD_STATIC_QUIRKS
1685static int patch_ad1983(struct hda_codec *codec)
1686{
1687 struct ad198x_spec *spec;
1688 int board_config;
1689 int err;
1690
1691 board_config = snd_hda_check_board_config(codec, AD1983_MODELS,
1692 ad1983_models, NULL);
1693 if (board_config < 0) {
1694 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
1695 codec->chip_name);
1696 board_config = AD1983_AUTO;
1697 }
1698
1699 if (board_config == AD1983_AUTO)
1700 return ad1983_parse_auto_config(codec);
1701
1702 err = alloc_ad_spec(codec);
1703 if (err < 0)
1704 return err;
1705 spec = codec->spec;
1706
1707 err = snd_hda_attach_beep_device(codec, 0x10);
1708 if (err < 0) {
1709 ad198x_free(codec);
1710 return err;
1711 }
1712 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
1713
1714 spec->multiout.max_channels = 2;
1715 spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids);
1716 spec->multiout.dac_nids = ad1983_dac_nids;
1717 spec->multiout.dig_out_nid = AD1983_SPDIF_OUT;
1718 spec->num_adc_nids = 1;
1719 spec->adc_nids = ad1983_adc_nids;
1720 spec->capsrc_nids = ad1983_capsrc_nids;
1721 spec->input_mux = &ad1983_capture_source;
1722 spec->num_mixers = 1;
1723 spec->mixers[0] = ad1983_mixers;
1724 spec->num_init_verbs = 1;
1725 spec->init_verbs[0] = ad1983_init_verbs;
1726 spec->spdif_route = 0;
1727#ifdef CONFIG_PM
1728 spec->loopback.amplist = ad1983_loopbacks;
1729#endif
1730 spec->vmaster_nid = 0x05;
1731
1732 codec->patch_ops = ad198x_patch_ops;
1733
1734 codec->no_trigger_sense = 1;
1735 codec->no_sticky_stream = 1;
1736
1737 return 0;
1738}
1739#else /* ENABLE_AD_STATIC_QUIRKS */
1740#define patch_ad1983 ad1983_parse_auto_config
1741#endif /* ENABLE_AD_STATIC_QUIRKS */
1742
1743 463
1744/* 464/*
1745 * AD1981 HD specific 465 * AD1981 HD specific
1746 */ 466 */
1747 467
1748#ifdef ENABLE_AD_STATIC_QUIRKS
1749#define AD1981_SPDIF_OUT 0x02
1750#define AD1981_DAC 0x03
1751#define AD1981_ADC 0x04
1752
1753static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC };
1754static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC };
1755static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 };
1756
1757/* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */
1758static const struct hda_input_mux ad1981_capture_source = {
1759 .num_items = 7,
1760 .items = {
1761 { "Front Mic", 0x0 },
1762 { "Line", 0x1 },
1763 { "Mix", 0x2 },
1764 { "Mix Mono", 0x3 },
1765 { "CD", 0x4 },
1766 { "Mic", 0x6 },
1767 { "Aux", 0x7 },
1768 },
1769};
1770
1771static const struct snd_kcontrol_new ad1981_mixers[] = {
1772 HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT),
1773 HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT),
1774 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT),
1775 HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT),
1776 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT),
1777 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT),
1778 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1779 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1780 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1781 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1782 HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1783 HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1784 HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
1785 HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT),
1786 HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1787 HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1788 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1789 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1790 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
1791 HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
1792 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
1793 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
1794 {
1795 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1796 .name = "Capture Source",
1797 .info = ad198x_mux_enum_info,
1798 .get = ad198x_mux_enum_get,
1799 .put = ad198x_mux_enum_put,
1800 },
1801 /* identical with AD1983 */
1802 {
1803 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1804 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
1805 .info = ad1983_spdif_route_info,
1806 .get = ad1983_spdif_route_get,
1807 .put = ad1983_spdif_route_put,
1808 },
1809 { } /* end */
1810};
1811
1812static const struct hda_verb ad1981_init_verbs[] = {
1813 /* Front, HP, Mono; mute as default */
1814 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1815 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1816 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1817 /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */
1818 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1819 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1820 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1821 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1822 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1823 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1824 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1825 /* Front, HP selectors; from Mix */
1826 {0x05, AC_VERB_SET_CONNECT_SEL, 0x01},
1827 {0x06, AC_VERB_SET_CONNECT_SEL, 0x01},
1828 /* Mono selector; from Mix */
1829 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03},
1830 /* Mic Mixer; select Front Mic */
1831 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1832 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1833 /* Mic boost: 0dB */
1834 {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1835 {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
1836 /* Record selector: Front mic */
1837 {0x15, AC_VERB_SET_CONNECT_SEL, 0x0},
1838 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1839 /* SPDIF route: PCM */
1840 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0},
1841 /* Front Pin */
1842 {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1843 /* HP Pin */
1844 {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 },
1845 /* Mono Pin */
1846 {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 },
1847 /* Front & Rear Mic Pins */
1848 {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1849 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 },
1850 /* Line Pin */
1851 {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 },
1852 /* Digital Beep */
1853 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00},
1854 /* Line-Out as Input: disabled */
1855 {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1856 { } /* end */
1857};
1858
1859#ifdef CONFIG_PM
1860static const struct hda_amp_list ad1981_loopbacks[] = {
1861 { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */
1862 { 0x13, HDA_OUTPUT, 0 }, /* Line */
1863 { 0x1b, HDA_OUTPUT, 0 }, /* Aux */
1864 { 0x1c, HDA_OUTPUT, 0 }, /* Mic */
1865 { 0x1d, HDA_OUTPUT, 0 }, /* CD */
1866 { } /* end */
1867};
1868#endif
1869
1870/*
1871 * Patch for HP nx6320
1872 *
1873 * nx6320 uses EAPD in the reverse way - EAPD-on means the internal
1874 * speaker output enabled _and_ mute-LED off.
1875 */
1876
1877#define AD1981_HP_EVENT 0x37
1878#define AD1981_MIC_EVENT 0x38
1879
1880static const struct hda_verb ad1981_hp_init_verbs[] = {
1881 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */
1882 /* pin sensing on HP and Mic jacks */
1883 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
1884 {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
1885 {}
1886};
1887
1888/* turn on/off EAPD (+ mute HP) as a master switch */
1889static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol,
1890 struct snd_ctl_elem_value *ucontrol)
1891{
1892 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1893 struct ad198x_spec *spec = codec->spec;
1894
1895 if (! ad198x_eapd_put(kcontrol, ucontrol))
1896 return 0;
1897 /* change speaker pin appropriately */
1898 snd_hda_set_pin_ctl(codec, 0x05, spec->cur_eapd ? PIN_OUT : 0);
1899 /* toggle HP mute appropriately */
1900 snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0,
1901 HDA_AMP_MUTE,
1902 spec->cur_eapd ? 0 : HDA_AMP_MUTE);
1903 return 1;
1904}
1905
1906/* bind volumes of both NID 0x05 and 0x06 */
1907static const struct hda_bind_ctls ad1981_hp_bind_master_vol = {
1908 .ops = &snd_hda_bind_vol,
1909 .values = {
1910 HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT),
1911 HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT),
1912 0
1913 },
1914};
1915
1916/* mute internal speaker if HP is plugged */
1917static void ad1981_hp_automute(struct hda_codec *codec)
1918{
1919 unsigned int present;
1920
1921 present = snd_hda_jack_detect(codec, 0x06);
1922 snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0,
1923 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
1924}
1925
1926/* toggle input of built-in and mic jack appropriately */
1927static void ad1981_hp_automic(struct hda_codec *codec)
1928{
1929 static const struct hda_verb mic_jack_on[] = {
1930 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1931 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1932 {}
1933 };
1934 static const struct hda_verb mic_jack_off[] = {
1935 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080},
1936 {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000},
1937 {}
1938 };
1939 unsigned int present;
1940
1941 present = snd_hda_jack_detect(codec, 0x08);
1942 if (present)
1943 snd_hda_sequence_write(codec, mic_jack_on);
1944 else
1945 snd_hda_sequence_write(codec, mic_jack_off);
1946}
1947
1948/* unsolicited event for HP jack sensing */
1949static void ad1981_hp_unsol_event(struct hda_codec *codec,
1950 unsigned int res)
1951{
1952 res >>= 26;
1953 switch (res) {
1954 case AD1981_HP_EVENT:
1955 ad1981_hp_automute(codec);
1956 break;
1957 case AD1981_MIC_EVENT:
1958 ad1981_hp_automic(codec);
1959 break;
1960 }
1961}
1962
1963static const struct hda_input_mux ad1981_hp_capture_source = {
1964 .num_items = 3,
1965 .items = {
1966 { "Mic", 0x0 },
1967 { "Dock Mic", 0x1 },
1968 { "Mix", 0x2 },
1969 },
1970};
1971
1972static const struct snd_kcontrol_new ad1981_hp_mixers[] = {
1973 HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol),
1974 {
1975 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
1976 .subdevice = HDA_SUBDEV_NID_FLAG | 0x05,
1977 .name = "Master Playback Switch",
1978 .info = ad198x_eapd_info,
1979 .get = ad198x_eapd_get,
1980 .put = ad1981_hp_master_sw_put,
1981 .private_value = 0x05,
1982 },
1983 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
1984 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
1985#if 0
1986 /* FIXME: analog mic/line loopback doesn't work with my tests...
1987 * (although recording is OK)
1988 */
1989 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
1990 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
1991 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT),
1992 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT),
1993 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT),
1994 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT),
1995 /* FIXME: does this laptop have analog CD connection? */
1996 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
1997 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
1998#endif
1999 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
2000 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT),
2001 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
2002 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
2003 {
2004 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2005 .name = "Capture Source",
2006 .info = ad198x_mux_enum_info,
2007 .get = ad198x_mux_enum_get,
2008 .put = ad198x_mux_enum_put,
2009 },
2010 { } /* end */
2011};
2012
2013/* initialize jack-sensing, too */
2014static int ad1981_hp_init(struct hda_codec *codec)
2015{
2016 ad198x_init(codec);
2017 ad1981_hp_automute(codec);
2018 ad1981_hp_automic(codec);
2019 return 0;
2020}
2021
2022/* configuration for Toshiba Laptops */
2023static const struct hda_verb ad1981_toshiba_init_verbs[] = {
2024 {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */
2025 /* pin sensing on HP and Mic jacks */
2026 {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT},
2027 {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT},
2028 {}
2029};
2030
2031static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = {
2032 HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT),
2033 HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT),
2034 { }
2035};
2036
2037/* configuration for Lenovo Thinkpad T60 */
2038static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = {
2039 HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2040 HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT),
2041 HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT),
2042 HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT),
2043 HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT),
2044 HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT),
2045 HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2046 HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT),
2047 HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT),
2048 HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT),
2049 HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT),
2050 {
2051 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2052 .name = "Capture Source",
2053 .info = ad198x_mux_enum_info,
2054 .get = ad198x_mux_enum_get,
2055 .put = ad198x_mux_enum_put,
2056 },
2057 /* identical with AD1983 */
2058 {
2059 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2060 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
2061 .info = ad1983_spdif_route_info,
2062 .get = ad1983_spdif_route_get,
2063 .put = ad1983_spdif_route_put,
2064 },
2065 { } /* end */
2066};
2067
2068static const struct hda_input_mux ad1981_thinkpad_capture_source = {
2069 .num_items = 3,
2070 .items = {
2071 { "Mic", 0x0 },
2072 { "Mix", 0x2 },
2073 { "CD", 0x4 },
2074 },
2075};
2076
2077/* models */
2078enum {
2079 AD1981_AUTO,
2080 AD1981_BASIC,
2081 AD1981_HP,
2082 AD1981_THINKPAD,
2083 AD1981_TOSHIBA,
2084 AD1981_MODELS
2085};
2086
2087static const char * const ad1981_models[AD1981_MODELS] = {
2088 [AD1981_AUTO] = "auto",
2089 [AD1981_HP] = "hp",
2090 [AD1981_THINKPAD] = "thinkpad",
2091 [AD1981_BASIC] = "basic",
2092 [AD1981_TOSHIBA] = "toshiba"
2093};
2094
2095static const struct snd_pci_quirk ad1981_cfg_tbl[] = {
2096 SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD),
2097 SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD),
2098 /* All HP models */
2099 SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP),
2100 SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA),
2101 /* Lenovo Thinkpad T60/X60/Z6xx */
2102 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD),
2103 /* HP nx6320 (reversed SSID, H/W bug) */
2104 SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP),
2105 {}
2106};
2107#endif /* ENABLE_AD_STATIC_QUIRKS */
2108
2109
2110/* follow EAPD via vmaster hook */ 468/* follow EAPD via vmaster hook */
2111static void ad_vmaster_eapd_hook(void *private_data, int enabled) 469static void ad_vmaster_eapd_hook(void *private_data, int enabled)
2112{ 470{
@@ -2172,7 +530,7 @@ static const struct snd_pci_quirk ad1981_fixup_tbl[] = {
2172 {} 530 {}
2173}; 531};
2174 532
2175static int ad1981_parse_auto_config(struct hda_codec *codec) 533static int patch_ad1981(struct hda_codec *codec)
2176{ 534{
2177 struct ad198x_spec *spec; 535 struct ad198x_spec *spec;
2178 int err; 536 int err;
@@ -2205,110 +563,6 @@ static int ad1981_parse_auto_config(struct hda_codec *codec)
2205 return err; 563 return err;
2206} 564}
2207 565
2208#ifdef ENABLE_AD_STATIC_QUIRKS
2209static int patch_ad1981(struct hda_codec *codec)
2210{
2211 struct ad198x_spec *spec;
2212 int err, board_config;
2213
2214 board_config = snd_hda_check_board_config(codec, AD1981_MODELS,
2215 ad1981_models,
2216 ad1981_cfg_tbl);
2217 if (board_config < 0) {
2218 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
2219 codec->chip_name);
2220 board_config = AD1981_AUTO;
2221 }
2222
2223 if (board_config == AD1981_AUTO)
2224 return ad1981_parse_auto_config(codec);
2225
2226 err = alloc_ad_spec(codec);
2227 if (err < 0)
2228 return -ENOMEM;
2229 spec = codec->spec;
2230
2231 err = snd_hda_attach_beep_device(codec, 0x10);
2232 if (err < 0) {
2233 ad198x_free(codec);
2234 return err;
2235 }
2236 set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT);
2237
2238 spec->multiout.max_channels = 2;
2239 spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids);
2240 spec->multiout.dac_nids = ad1981_dac_nids;
2241 spec->multiout.dig_out_nid = AD1981_SPDIF_OUT;
2242 spec->num_adc_nids = 1;
2243 spec->adc_nids = ad1981_adc_nids;
2244 spec->capsrc_nids = ad1981_capsrc_nids;
2245 spec->input_mux = &ad1981_capture_source;
2246 spec->num_mixers = 1;
2247 spec->mixers[0] = ad1981_mixers;
2248 spec->num_init_verbs = 1;
2249 spec->init_verbs[0] = ad1981_init_verbs;
2250 spec->spdif_route = 0;
2251#ifdef CONFIG_PM
2252 spec->loopback.amplist = ad1981_loopbacks;
2253#endif
2254 spec->vmaster_nid = 0x05;
2255
2256 codec->patch_ops = ad198x_patch_ops;
2257
2258 /* override some parameters */
2259 switch (board_config) {
2260 case AD1981_HP:
2261 spec->mixers[0] = ad1981_hp_mixers;
2262 spec->num_init_verbs = 2;
2263 spec->init_verbs[1] = ad1981_hp_init_verbs;
2264 if (!is_jack_available(codec, 0x0a))
2265 spec->multiout.dig_out_nid = 0;
2266 spec->input_mux = &ad1981_hp_capture_source;
2267
2268 codec->patch_ops.init = ad1981_hp_init;
2269 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
2270 /* set the upper-limit for mixer amp to 0dB for avoiding the
2271 * possible damage by overloading
2272 */
2273 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2274 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2275 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2276 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2277 (1 << AC_AMPCAP_MUTE_SHIFT));
2278 break;
2279 case AD1981_THINKPAD:
2280 spec->mixers[0] = ad1981_thinkpad_mixers;
2281 spec->input_mux = &ad1981_thinkpad_capture_source;
2282 /* set the upper-limit for mixer amp to 0dB for avoiding the
2283 * possible damage by overloading
2284 */
2285 snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT,
2286 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
2287 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
2288 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
2289 (1 << AC_AMPCAP_MUTE_SHIFT));
2290 break;
2291 case AD1981_TOSHIBA:
2292 spec->mixers[0] = ad1981_hp_mixers;
2293 spec->mixers[1] = ad1981_toshiba_mixers;
2294 spec->num_init_verbs = 2;
2295 spec->init_verbs[1] = ad1981_toshiba_init_verbs;
2296 spec->multiout.dig_out_nid = 0;
2297 spec->input_mux = &ad1981_hp_capture_source;
2298 codec->patch_ops.init = ad1981_hp_init;
2299 codec->patch_ops.unsol_event = ad1981_hp_unsol_event;
2300 break;
2301 }
2302
2303 codec->no_trigger_sense = 1;
2304 codec->no_sticky_stream = 1;
2305
2306 return 0;
2307}
2308#else /* ENABLE_AD_STATIC_QUIRKS */
2309#define patch_ad1981 ad1981_parse_auto_config
2310#endif /* ENABLE_AD_STATIC_QUIRKS */
2311
2312 566
2313/* 567/*
2314 * AD1988 568 * AD1988
@@ -2395,90 +649,7 @@ static int patch_ad1981(struct hda_codec *codec)
2395 * E/F quad mic array 649 * E/F quad mic array
2396 */ 650 */
2397 651
2398
2399#ifdef ENABLE_AD_STATIC_QUIRKS 652#ifdef ENABLE_AD_STATIC_QUIRKS
2400/* models */
2401enum {
2402 AD1988_AUTO,
2403 AD1988_6STACK,
2404 AD1988_6STACK_DIG,
2405 AD1988_3STACK,
2406 AD1988_3STACK_DIG,
2407 AD1988_LAPTOP,
2408 AD1988_LAPTOP_DIG,
2409 AD1988_MODEL_LAST,
2410};
2411
2412/* reivision id to check workarounds */
2413#define AD1988A_REV2 0x100200
2414
2415#define is_rev2(codec) \
2416 ((codec)->vendor_id == 0x11d41988 && \
2417 (codec)->revision_id == AD1988A_REV2)
2418
2419/*
2420 * mixers
2421 */
2422
2423static const hda_nid_t ad1988_6stack_dac_nids[4] = {
2424 0x04, 0x06, 0x05, 0x0a
2425};
2426
2427static const hda_nid_t ad1988_3stack_dac_nids[3] = {
2428 0x04, 0x05, 0x0a
2429};
2430
2431/* for AD1988A revision-2, DAC2-4 are swapped */
2432static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = {
2433 0x04, 0x05, 0x0a, 0x06
2434};
2435
2436static const hda_nid_t ad1988_alt_dac_nid[1] = {
2437 0x03
2438};
2439
2440static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = {
2441 0x04, 0x0a, 0x06
2442};
2443
2444static const hda_nid_t ad1988_adc_nids[3] = {
2445 0x08, 0x09, 0x0f
2446};
2447
2448static const hda_nid_t ad1988_capsrc_nids[3] = {
2449 0x0c, 0x0d, 0x0e
2450};
2451
2452#define AD1988_SPDIF_OUT 0x02
2453#define AD1988_SPDIF_OUT_HDMI 0x0b
2454#define AD1988_SPDIF_IN 0x07
2455
2456static const hda_nid_t ad1989b_slave_dig_outs[] = {
2457 AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0
2458};
2459
2460static const struct hda_input_mux ad1988_6stack_capture_source = {
2461 .num_items = 5,
2462 .items = {
2463 { "Front Mic", 0x1 }, /* port-B */
2464 { "Line", 0x2 }, /* port-C */
2465 { "Mic", 0x4 }, /* port-E */
2466 { "CD", 0x5 },
2467 { "Mix", 0x9 },
2468 },
2469};
2470
2471static const struct hda_input_mux ad1988_laptop_capture_source = {
2472 .num_items = 3,
2473 .items = {
2474 { "Mic/Line", 0x1 }, /* port-B */
2475 { "CD", 0x5 },
2476 { "Mix", 0x9 },
2477 },
2478};
2479
2480/*
2481 */
2482static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, 653static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol,
2483 struct snd_ctl_elem_info *uinfo) 654 struct snd_ctl_elem_info *uinfo)
2484{ 655{
@@ -2509,569 +680,6 @@ static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol,
2509 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 680 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
2510 return err; 681 return err;
2511} 682}
2512
2513/* 6-stack mode */
2514static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = {
2515 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2516 HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2517 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2518 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2519 HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2520 { } /* end */
2521};
2522
2523static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = {
2524 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2525 HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT),
2526 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT),
2527 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT),
2528 HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT),
2529 { } /* end */
2530};
2531
2532static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = {
2533 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2534 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2535 HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT),
2536 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT),
2537 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT),
2538 HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT),
2539 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2540 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2541
2542 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2543 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2544 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2545 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2546 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2547 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2548 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2549 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2550
2551 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2552 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2553
2554 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2555 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2556 { } /* end */
2557};
2558
2559/* 3-stack mode */
2560static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = {
2561 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2562 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2563 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
2564 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
2565 { } /* end */
2566};
2567
2568static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = {
2569 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2570 HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT),
2571 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT),
2572 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT),
2573 { } /* end */
2574};
2575
2576static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = {
2577 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2578 HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT),
2579 HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT),
2580 HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT),
2581 HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT),
2582 HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT),
2583 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2584
2585 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2586 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2587 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2588 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2589 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2590 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2591 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT),
2592 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT),
2593
2594 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2595 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2596
2597 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2598 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
2599 {
2600 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2601 .name = "Channel Mode",
2602 .info = ad198x_ch_mode_info,
2603 .get = ad198x_ch_mode_get,
2604 .put = ad198x_ch_mode_put,
2605 },
2606
2607 { } /* end */
2608};
2609
2610/* laptop mode */
2611static const struct snd_kcontrol_new ad1988_laptop_mixers[] = {
2612 HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT),
2613 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
2614 HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT),
2615 HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT),
2616
2617 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT),
2618 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT),
2619 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT),
2620 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT),
2621 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT),
2622 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT),
2623
2624 HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT),
2625 HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT),
2626
2627 HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
2628
2629 {
2630 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2631 .name = "External Amplifier",
2632 .subdevice = HDA_SUBDEV_NID_FLAG | 0x12,
2633 .info = ad198x_eapd_info,
2634 .get = ad198x_eapd_get,
2635 .put = ad198x_eapd_put,
2636 .private_value = 0x12, /* port-D */
2637 },
2638
2639 { } /* end */
2640};
2641
2642/* capture */
2643static const struct snd_kcontrol_new ad1988_capture_mixers[] = {
2644 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
2645 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
2646 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
2647 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
2648 HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT),
2649 HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT),
2650 {
2651 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2652 /* The multiple "Capture Source" controls confuse alsamixer
2653 * So call somewhat different..
2654 */
2655 /* .name = "Capture Source", */
2656 .name = "Input Source",
2657 .count = 3,
2658 .info = ad198x_mux_enum_info,
2659 .get = ad198x_mux_enum_get,
2660 .put = ad198x_mux_enum_put,
2661 },
2662 { } /* end */
2663};
2664
2665static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol,
2666 struct snd_ctl_elem_info *uinfo)
2667{
2668 static const char * const texts[] = {
2669 "PCM", "ADC1", "ADC2", "ADC3"
2670 };
2671 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2672 uinfo->count = 1;
2673 uinfo->value.enumerated.items = 4;
2674 if (uinfo->value.enumerated.item >= 4)
2675 uinfo->value.enumerated.item = 3;
2676 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]);
2677 return 0;
2678}
2679
2680static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol,
2681 struct snd_ctl_elem_value *ucontrol)
2682{
2683 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2684 unsigned int sel;
2685
2686 sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE,
2687 AC_AMP_GET_INPUT);
2688 if (!(sel & 0x80))
2689 ucontrol->value.enumerated.item[0] = 0;
2690 else {
2691 sel = snd_hda_codec_read(codec, 0x0b, 0,
2692 AC_VERB_GET_CONNECT_SEL, 0);
2693 if (sel < 3)
2694 sel++;
2695 else
2696 sel = 0;
2697 ucontrol->value.enumerated.item[0] = sel;
2698 }
2699 return 0;
2700}
2701
2702static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol,
2703 struct snd_ctl_elem_value *ucontrol)
2704{
2705 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2706 unsigned int val, sel;
2707 int change;
2708
2709 val = ucontrol->value.enumerated.item[0];
2710 if (val > 3)
2711 return -EINVAL;
2712 if (!val) {
2713 sel = snd_hda_codec_read(codec, 0x1d, 0,
2714 AC_VERB_GET_AMP_GAIN_MUTE,
2715 AC_AMP_GET_INPUT);
2716 change = sel & 0x80;
2717 if (change) {
2718 snd_hda_codec_write_cache(codec, 0x1d, 0,
2719 AC_VERB_SET_AMP_GAIN_MUTE,
2720 AMP_IN_UNMUTE(0));
2721 snd_hda_codec_write_cache(codec, 0x1d, 0,
2722 AC_VERB_SET_AMP_GAIN_MUTE,
2723 AMP_IN_MUTE(1));
2724 }
2725 } else {
2726 sel = snd_hda_codec_read(codec, 0x1d, 0,
2727 AC_VERB_GET_AMP_GAIN_MUTE,
2728 AC_AMP_GET_INPUT | 0x01);
2729 change = sel & 0x80;
2730 if (change) {
2731 snd_hda_codec_write_cache(codec, 0x1d, 0,
2732 AC_VERB_SET_AMP_GAIN_MUTE,
2733 AMP_IN_MUTE(0));
2734 snd_hda_codec_write_cache(codec, 0x1d, 0,
2735 AC_VERB_SET_AMP_GAIN_MUTE,
2736 AMP_IN_UNMUTE(1));
2737 }
2738 sel = snd_hda_codec_read(codec, 0x0b, 0,
2739 AC_VERB_GET_CONNECT_SEL, 0) + 1;
2740 change |= sel != val;
2741 if (change)
2742 snd_hda_codec_write_cache(codec, 0x0b, 0,
2743 AC_VERB_SET_CONNECT_SEL,
2744 val - 1);
2745 }
2746 return change;
2747}
2748
2749static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = {
2750 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2751 {
2752 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2753 .name = "IEC958 Playback Source",
2754 .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b,
2755 .info = ad1988_spdif_playback_source_info,
2756 .get = ad1988_spdif_playback_source_get,
2757 .put = ad1988_spdif_playback_source_put,
2758 },
2759 { } /* end */
2760};
2761
2762static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = {
2763 HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT),
2764 { } /* end */
2765};
2766
2767static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = {
2768 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
2769 HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT),
2770 { } /* end */
2771};
2772
2773/*
2774 * initialization verbs
2775 */
2776
2777/*
2778 * for 6-stack (+dig)
2779 */
2780static const struct hda_verb ad1988_6stack_init_verbs[] = {
2781 /* Front, Surround, CLFE, side DAC; unmute as default */
2782 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2783 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2784 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2785 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2786 /* Port-A front headphon path */
2787 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2788 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2789 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2790 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2791 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2792 /* Port-D line-out path */
2793 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2794 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2795 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2796 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2797 /* Port-F surround path */
2798 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2799 {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2800 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2801 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2802 /* Port-G CLFE path */
2803 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2804 {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2805 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2806 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2807 /* Port-H side path */
2808 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2809 {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2810 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2811 {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2812 /* Mono out path */
2813 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2814 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2815 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2816 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2817 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2818 /* Port-B front mic-in path */
2819 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2820 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2821 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2822 /* Port-C line-in path */
2823 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2824 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2825 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2826 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2827 /* Port-E mic-in path */
2828 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2829 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2830 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2831 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2832 /* Analog CD Input */
2833 {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
2834 /* Analog Mix output amp */
2835 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2836
2837 { }
2838};
2839
2840static const struct hda_verb ad1988_6stack_fp_init_verbs[] = {
2841 /* Headphone; unmute as default */
2842 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2843 /* Port-A front headphon path */
2844 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2845 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2846 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2847 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2848 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2849
2850 { }
2851};
2852
2853static const struct hda_verb ad1988_capture_init_verbs[] = {
2854 /* mute analog mix */
2855 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2856 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2857 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2858 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2859 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2860 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2861 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2862 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2863 /* select ADCs - front-mic */
2864 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2865 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2866 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2867
2868 { }
2869};
2870
2871static const struct hda_verb ad1988_spdif_init_verbs[] = {
2872 /* SPDIF out sel */
2873 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
2874 {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */
2875 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2876 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2877 /* SPDIF out pin */
2878 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2879
2880 { }
2881};
2882
2883static const struct hda_verb ad1988_spdif_in_init_verbs[] = {
2884 /* unmute SPDIF input pin */
2885 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
2886 { }
2887};
2888
2889/* AD1989 has no ADC -> SPDIF route */
2890static const struct hda_verb ad1989_spdif_init_verbs[] = {
2891 /* SPDIF-1 out pin */
2892 {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2893 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2894 /* SPDIF-2/HDMI out pin */
2895 {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2896 {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
2897 { }
2898};
2899
2900/*
2901 * verbs for 3stack (+dig)
2902 */
2903static const struct hda_verb ad1988_3stack_ch2_init[] = {
2904 /* set port-C to line-in */
2905 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2906 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN },
2907 /* set port-E to mic-in */
2908 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2909 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 },
2910 { } /* end */
2911};
2912
2913static const struct hda_verb ad1988_3stack_ch6_init[] = {
2914 /* set port-C to surround out */
2915 { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2916 { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2917 /* set port-E to CLFE out */
2918 { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT },
2919 { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2920 { } /* end */
2921};
2922
2923static const struct hda_channel_mode ad1988_3stack_modes[2] = {
2924 { 2, ad1988_3stack_ch2_init },
2925 { 6, ad1988_3stack_ch6_init },
2926};
2927
2928static const struct hda_verb ad1988_3stack_init_verbs[] = {
2929 /* Front, Surround, CLFE, side DAC; unmute as default */
2930 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2931 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2932 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2933 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2934 /* Port-A front headphon path */
2935 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
2936 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2937 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2938 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2939 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
2940 /* Port-D line-out path */
2941 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2942 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2943 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2944 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2945 /* Mono out path */
2946 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
2947 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2948 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2949 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2950 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
2951 /* Port-B front mic-in path */
2952 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
2953 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
2954 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2955 /* Port-C line-in/surround path - 6ch mode as default */
2956 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2957 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2958 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2959 {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */
2960 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
2961 /* Port-E mic-in/CLFE path - 6ch mode as default */
2962 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
2963 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
2964 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
2965 {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */
2966 {0x34, AC_VERB_SET_CONNECT_SEL, 0x0},
2967 /* mute analog mix */
2968 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
2969 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
2970 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
2971 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
2972 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
2973 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
2974 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
2975 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
2976 /* select ADCs - front-mic */
2977 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
2978 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
2979 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
2980 /* Analog Mix output amp */
2981 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
2982 { }
2983};
2984
2985/*
2986 * verbs for laptop mode (+dig)
2987 */
2988static const struct hda_verb ad1988_laptop_hp_on[] = {
2989 /* unmute port-A and mute port-D */
2990 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2991 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2992 { } /* end */
2993};
2994static const struct hda_verb ad1988_laptop_hp_off[] = {
2995 /* mute port-A and unmute port-D */
2996 { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE },
2997 { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE },
2998 { } /* end */
2999};
3000
3001#define AD1988_HP_EVENT 0x01
3002
3003static const struct hda_verb ad1988_laptop_init_verbs[] = {
3004 /* Front, Surround, CLFE, side DAC; unmute as default */
3005 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3006 {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3007 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3008 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3009 /* Port-A front headphon path */
3010 {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */
3011 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3012 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3013 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3014 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3015 /* unsolicited event for pin-sense */
3016 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT },
3017 /* Port-D line-out path + EAPD */
3018 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3019 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3020 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3021 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3022 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */
3023 /* Mono out path */
3024 {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */
3025 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3026 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3027 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3028 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */
3029 /* Port-B mic-in path */
3030 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3031 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3032 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3033 /* Port-C docking station - try to output */
3034 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
3035 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
3036 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3037 {0x33, AC_VERB_SET_CONNECT_SEL, 0x0},
3038 /* mute analog mix */
3039 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3040 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3041 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3042 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3043 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3044 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
3045 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
3046 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
3047 /* select ADCs - mic */
3048 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
3049 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1},
3050 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3051 /* Analog Mix output amp */
3052 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3053 { }
3054};
3055
3056static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res)
3057{
3058 if ((res >> 26) != AD1988_HP_EVENT)
3059 return;
3060 if (snd_hda_jack_detect(codec, 0x11))
3061 snd_hda_sequence_write(codec, ad1988_laptop_hp_on);
3062 else
3063 snd_hda_sequence_write(codec, ad1988_laptop_hp_off);
3064}
3065
3066#ifdef CONFIG_PM
3067static const struct hda_amp_list ad1988_loopbacks[] = {
3068 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3069 { 0x20, HDA_INPUT, 1 }, /* Line */
3070 { 0x20, HDA_INPUT, 4 }, /* Mic */
3071 { 0x20, HDA_INPUT, 6 }, /* CD */
3072 { } /* end */
3073};
3074#endif
3075#endif /* ENABLE_AD_STATIC_QUIRKS */ 683#endif /* ENABLE_AD_STATIC_QUIRKS */
3076 684
3077static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, 685static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol,
@@ -3220,7 +828,34 @@ static int ad1988_add_spdif_mux_ctl(struct hda_codec *codec)
3220/* 828/*
3221 */ 829 */
3222 830
3223static int ad1988_parse_auto_config(struct hda_codec *codec) 831enum {
832 AD1988_FIXUP_6STACK_DIG,
833};
834
835static const struct hda_fixup ad1988_fixups[] = {
836 [AD1988_FIXUP_6STACK_DIG] = {
837 .type = HDA_FIXUP_PINS,
838 .v.pins = (const struct hda_pintbl[]) {
839 { 0x11, 0x02214130 }, /* front-hp */
840 { 0x12, 0x01014010 }, /* line-out */
841 { 0x14, 0x02a19122 }, /* front-mic */
842 { 0x15, 0x01813021 }, /* line-in */
843 { 0x16, 0x01011012 }, /* line-out */
844 { 0x17, 0x01a19020 }, /* mic */
845 { 0x1b, 0x0145f1f0 }, /* SPDIF */
846 { 0x24, 0x01016011 }, /* line-out */
847 { 0x25, 0x01012013 }, /* line-out */
848 { }
849 }
850 },
851};
852
853static const struct hda_model_fixup ad1988_fixup_models[] = {
854 { .id = AD1988_FIXUP_6STACK_DIG, .name = "6stack-dig" },
855 {}
856};
857
858static int patch_ad1988(struct hda_codec *codec)
3224{ 859{
3225 struct ad198x_spec *spec; 860 struct ad198x_spec *spec;
3226 int err; 861 int err;
@@ -3234,12 +869,19 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
3234 spec->gen.mixer_merge_nid = 0x21; 869 spec->gen.mixer_merge_nid = 0x21;
3235 spec->gen.beep_nid = 0x10; 870 spec->gen.beep_nid = 0x10;
3236 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 871 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
872
873 snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups);
874 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
875
3237 err = ad198x_parse_auto_config(codec); 876 err = ad198x_parse_auto_config(codec);
3238 if (err < 0) 877 if (err < 0)
3239 goto error; 878 goto error;
3240 err = ad1988_add_spdif_mux_ctl(codec); 879 err = ad1988_add_spdif_mux_ctl(codec);
3241 if (err < 0) 880 if (err < 0)
3242 goto error; 881 goto error;
882
883 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
884
3243 return 0; 885 return 0;
3244 886
3245 error: 887 error:
@@ -3247,169 +889,6 @@ static int ad1988_parse_auto_config(struct hda_codec *codec)
3247 return err; 889 return err;
3248} 890}
3249 891
3250/*
3251 */
3252
3253#ifdef ENABLE_AD_STATIC_QUIRKS
3254static const char * const ad1988_models[AD1988_MODEL_LAST] = {
3255 [AD1988_6STACK] = "6stack",
3256 [AD1988_6STACK_DIG] = "6stack-dig",
3257 [AD1988_3STACK] = "3stack",
3258 [AD1988_3STACK_DIG] = "3stack-dig",
3259 [AD1988_LAPTOP] = "laptop",
3260 [AD1988_LAPTOP_DIG] = "laptop-dig",
3261 [AD1988_AUTO] = "auto",
3262};
3263
3264static const struct snd_pci_quirk ad1988_cfg_tbl[] = {
3265 SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG),
3266 SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG),
3267 SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG),
3268 SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG),
3269 SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG),
3270 {}
3271};
3272
3273static int patch_ad1988(struct hda_codec *codec)
3274{
3275 struct ad198x_spec *spec;
3276 int err, board_config;
3277
3278 board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST,
3279 ad1988_models, ad1988_cfg_tbl);
3280 if (board_config < 0) {
3281 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3282 codec->chip_name);
3283 board_config = AD1988_AUTO;
3284 }
3285
3286 if (board_config == AD1988_AUTO)
3287 return ad1988_parse_auto_config(codec);
3288
3289 err = alloc_ad_spec(codec);
3290 if (err < 0)
3291 return err;
3292 spec = codec->spec;
3293
3294 if (is_rev2(codec))
3295 snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n");
3296
3297 err = snd_hda_attach_beep_device(codec, 0x10);
3298 if (err < 0) {
3299 ad198x_free(codec);
3300 return err;
3301 }
3302 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3303
3304 if (!spec->multiout.hp_nid)
3305 spec->multiout.hp_nid = ad1988_alt_dac_nid[0];
3306 switch (board_config) {
3307 case AD1988_6STACK:
3308 case AD1988_6STACK_DIG:
3309 spec->multiout.max_channels = 8;
3310 spec->multiout.num_dacs = 4;
3311 if (is_rev2(codec))
3312 spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2;
3313 else
3314 spec->multiout.dac_nids = ad1988_6stack_dac_nids;
3315 spec->input_mux = &ad1988_6stack_capture_source;
3316 spec->num_mixers = 2;
3317 if (is_rev2(codec))
3318 spec->mixers[0] = ad1988_6stack_mixers1_rev2;
3319 else
3320 spec->mixers[0] = ad1988_6stack_mixers1;
3321 spec->mixers[1] = ad1988_6stack_mixers2;
3322 spec->num_init_verbs = 1;
3323 spec->init_verbs[0] = ad1988_6stack_init_verbs;
3324 if (board_config == AD1988_6STACK_DIG) {
3325 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3326 spec->dig_in_nid = AD1988_SPDIF_IN;
3327 }
3328 break;
3329 case AD1988_3STACK:
3330 case AD1988_3STACK_DIG:
3331 spec->multiout.max_channels = 6;
3332 spec->multiout.num_dacs = 3;
3333 if (is_rev2(codec))
3334 spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2;
3335 else
3336 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3337 spec->input_mux = &ad1988_6stack_capture_source;
3338 spec->channel_mode = ad1988_3stack_modes;
3339 spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes);
3340 spec->num_mixers = 2;
3341 if (is_rev2(codec))
3342 spec->mixers[0] = ad1988_3stack_mixers1_rev2;
3343 else
3344 spec->mixers[0] = ad1988_3stack_mixers1;
3345 spec->mixers[1] = ad1988_3stack_mixers2;
3346 spec->num_init_verbs = 1;
3347 spec->init_verbs[0] = ad1988_3stack_init_verbs;
3348 if (board_config == AD1988_3STACK_DIG)
3349 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3350 break;
3351 case AD1988_LAPTOP:
3352 case AD1988_LAPTOP_DIG:
3353 spec->multiout.max_channels = 2;
3354 spec->multiout.num_dacs = 1;
3355 spec->multiout.dac_nids = ad1988_3stack_dac_nids;
3356 spec->input_mux = &ad1988_laptop_capture_source;
3357 spec->num_mixers = 1;
3358 spec->mixers[0] = ad1988_laptop_mixers;
3359 codec->inv_eapd = 1; /* inverted EAPD */
3360 spec->num_init_verbs = 1;
3361 spec->init_verbs[0] = ad1988_laptop_init_verbs;
3362 if (board_config == AD1988_LAPTOP_DIG)
3363 spec->multiout.dig_out_nid = AD1988_SPDIF_OUT;
3364 break;
3365 }
3366
3367 spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids);
3368 spec->adc_nids = ad1988_adc_nids;
3369 spec->capsrc_nids = ad1988_capsrc_nids;
3370 spec->mixers[spec->num_mixers++] = ad1988_capture_mixers;
3371 spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs;
3372 if (spec->multiout.dig_out_nid) {
3373 if (codec->vendor_id >= 0x11d4989a) {
3374 spec->mixers[spec->num_mixers++] =
3375 ad1989_spdif_out_mixers;
3376 spec->init_verbs[spec->num_init_verbs++] =
3377 ad1989_spdif_init_verbs;
3378 codec->slave_dig_outs = ad1989b_slave_dig_outs;
3379 } else {
3380 spec->mixers[spec->num_mixers++] =
3381 ad1988_spdif_out_mixers;
3382 spec->init_verbs[spec->num_init_verbs++] =
3383 ad1988_spdif_init_verbs;
3384 }
3385 }
3386 if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) {
3387 spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers;
3388 spec->init_verbs[spec->num_init_verbs++] =
3389 ad1988_spdif_in_init_verbs;
3390 }
3391
3392 codec->patch_ops = ad198x_patch_ops;
3393 switch (board_config) {
3394 case AD1988_LAPTOP:
3395 case AD1988_LAPTOP_DIG:
3396 codec->patch_ops.unsol_event = ad1988_laptop_unsol_event;
3397 break;
3398 }
3399#ifdef CONFIG_PM
3400 spec->loopback.amplist = ad1988_loopbacks;
3401#endif
3402 spec->vmaster_nid = 0x04;
3403
3404 codec->no_trigger_sense = 1;
3405 codec->no_sticky_stream = 1;
3406
3407 return 0;
3408}
3409#else /* ENABLE_AD_STATIC_QUIRKS */
3410#define patch_ad1988 ad1988_parse_auto_config
3411#endif /* ENABLE_AD_STATIC_QUIRKS */
3412
3413 892
3414/* 893/*
3415 * AD1884 / AD1984 894 * AD1884 / AD1984
@@ -3423,167 +902,19 @@ static int patch_ad1988(struct hda_codec *codec)
3423 * 902 *
3424 * AD1984 = AD1884 + two digital mic-ins 903 * AD1984 = AD1884 + two digital mic-ins
3425 * 904 *
3426 * FIXME: 905 * AD1883 / AD1884A / AD1984A / AD1984B
3427 * For simplicity, we share the single DAC for both HP and line-outs 906 *
3428 * right now. The inidividual playbacks could be easily implemented, 907 * port-B (0x14) - front mic-in
3429 * but no build-up framework is given, so far. 908 * port-E (0x1c) - rear mic-in
3430 */ 909 * port-F (0x16) - CD / ext out
3431 910 * port-C (0x15) - rear line-in
3432#ifdef ENABLE_AD_STATIC_QUIRKS 911 * port-D (0x12) - rear line-out
3433static const hda_nid_t ad1884_dac_nids[1] = { 912 * port-A (0x11) - front hp-out
3434 0x04, 913 *
3435}; 914 * AD1984A = AD1884A + digital-mic
3436 915 * AD1883 = equivalent with AD1984A
3437static const hda_nid_t ad1884_adc_nids[2] = { 916 * AD1984B = AD1984A + extra SPDIF-out
3438 0x08, 0x09,
3439};
3440
3441static const hda_nid_t ad1884_capsrc_nids[2] = {
3442 0x0c, 0x0d,
3443};
3444
3445#define AD1884_SPDIF_OUT 0x02
3446
3447static const struct hda_input_mux ad1884_capture_source = {
3448 .num_items = 4,
3449 .items = {
3450 { "Front Mic", 0x0 },
3451 { "Mic", 0x1 },
3452 { "CD", 0x2 },
3453 { "Mix", 0x3 },
3454 },
3455};
3456
3457static const struct snd_kcontrol_new ad1884_base_mixers[] = {
3458 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3459 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3460 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3461 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3462 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3463 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3464 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3465 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3466 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3467 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3468 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
3469 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
3470 HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3471 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3472 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3473 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3474 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3475 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3476 {
3477 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3478 /* The multiple "Capture Source" controls confuse alsamixer
3479 * So call somewhat different..
3480 */
3481 /* .name = "Capture Source", */
3482 .name = "Input Source",
3483 .count = 2,
3484 .info = ad198x_mux_enum_info,
3485 .get = ad198x_mux_enum_get,
3486 .put = ad198x_mux_enum_put,
3487 },
3488 /* SPDIF controls */
3489 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3490 {
3491 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3492 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3493 /* identical with ad1983 */
3494 .info = ad1983_spdif_route_info,
3495 .get = ad1983_spdif_route_get,
3496 .put = ad1983_spdif_route_put,
3497 },
3498 { } /* end */
3499};
3500
3501static const struct snd_kcontrol_new ad1984_dmic_mixers[] = {
3502 HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT),
3503 HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT),
3504 HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0,
3505 HDA_INPUT),
3506 HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0,
3507 HDA_INPUT),
3508 { } /* end */
3509};
3510
3511/*
3512 * initialization verbs
3513 */ 917 */
3514static const struct hda_verb ad1884_init_verbs[] = {
3515 /* DACs; mute as default */
3516 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3517 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3518 /* Port-A (HP) mixer */
3519 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3520 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3521 /* Port-A pin */
3522 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3523 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3524 /* HP selector - select DAC2 */
3525 {0x22, AC_VERB_SET_CONNECT_SEL, 0x1},
3526 /* Port-D (Line-out) mixer */
3527 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3528 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3529 /* Port-D pin */
3530 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3531 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3532 /* Mono-out mixer */
3533 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3534 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
3535 /* Mono-out pin */
3536 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
3537 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3538 /* Mono selector */
3539 {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1},
3540 /* Port-B (front mic) pin */
3541 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3542 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3543 /* Port-C (rear mic) pin */
3544 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3545 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
3546 /* Analog mixer; mute as default */
3547 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
3548 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
3549 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
3550 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
3551 /* Analog Mix output amp */
3552 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
3553 /* SPDIF output selector */
3554 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
3555 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
3556 { } /* end */
3557};
3558
3559#ifdef CONFIG_PM
3560static const struct hda_amp_list ad1884_loopbacks[] = {
3561 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
3562 { 0x20, HDA_INPUT, 1 }, /* Mic */
3563 { 0x20, HDA_INPUT, 2 }, /* CD */
3564 { 0x20, HDA_INPUT, 4 }, /* Docking */
3565 { } /* end */
3566};
3567#endif
3568
3569static const char * const ad1884_slave_vols[] = {
3570 "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD",
3571 "Internal Mic", "Dock Mic", /* "Beep", */ "IEC958",
3572 NULL
3573};
3574
3575enum {
3576 AD1884_AUTO,
3577 AD1884_BASIC,
3578 AD1884_MODELS
3579};
3580
3581static const char * const ad1884_models[AD1884_MODELS] = {
3582 [AD1884_AUTO] = "auto",
3583 [AD1884_BASIC] = "basic",
3584};
3585#endif /* ENABLE_AD_STATIC_QUIRKS */
3586
3587 918
3588/* set the upper-limit for mixer amp to 0dB for avoiding the possible 919/* set the upper-limit for mixer amp to 0dB for avoiding the possible
3589 * damage by overloading 920 * damage by overloading
@@ -3599,14 +930,34 @@ static void ad1884_fixup_amp_override(struct hda_codec *codec,
3599 (1 << AC_AMPCAP_MUTE_SHIFT)); 930 (1 << AC_AMPCAP_MUTE_SHIFT));
3600} 931}
3601 932
933/* toggle GPIO1 according to the mute state */
934static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled)
935{
936 struct hda_codec *codec = private_data;
937 struct ad198x_spec *spec = codec->spec;
938
939 if (spec->eapd_nid)
940 ad_vmaster_eapd_hook(private_data, enabled);
941 snd_hda_codec_update_cache(codec, 0x01, 0,
942 AC_VERB_SET_GPIO_DATA,
943 enabled ? 0x00 : 0x02);
944}
945
3602static void ad1884_fixup_hp_eapd(struct hda_codec *codec, 946static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
3603 const struct hda_fixup *fix, int action) 947 const struct hda_fixup *fix, int action)
3604{ 948{
3605 struct ad198x_spec *spec = codec->spec; 949 struct ad198x_spec *spec = codec->spec;
950 static const struct hda_verb gpio_init_verbs[] = {
951 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
952 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
953 {0x01, AC_VERB_SET_GPIO_DATA, 0x02},
954 {},
955 };
3606 956
3607 switch (action) { 957 switch (action) {
3608 case HDA_FIXUP_ACT_PRE_PROBE: 958 case HDA_FIXUP_ACT_PRE_PROBE:
3609 spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; 959 spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook;
960 snd_hda_sequence_write_cache(codec, gpio_init_verbs);
3610 break; 961 break;
3611 case HDA_FIXUP_ACT_PROBE: 962 case HDA_FIXUP_ACT_PROBE:
3612 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) 963 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
@@ -3617,9 +968,18 @@ static void ad1884_fixup_hp_eapd(struct hda_codec *codec,
3617 } 968 }
3618} 969}
3619 970
971/* set magic COEFs for dmic */
972static const struct hda_verb ad1884_dmic_init_verbs[] = {
973 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
974 {0x01, AC_VERB_SET_PROC_COEF, 0x08},
975 {}
976};
977
3620enum { 978enum {
3621 AD1884_FIXUP_AMP_OVERRIDE, 979 AD1884_FIXUP_AMP_OVERRIDE,
3622 AD1884_FIXUP_HP_EAPD, 980 AD1884_FIXUP_HP_EAPD,
981 AD1884_FIXUP_DMIC_COEF,
982 AD1884_FIXUP_HP_TOUCHSMART,
3623}; 983};
3624 984
3625static const struct hda_fixup ad1884_fixups[] = { 985static const struct hda_fixup ad1884_fixups[] = {
@@ -3633,15 +993,27 @@ static const struct hda_fixup ad1884_fixups[] = {
3633 .chained = true, 993 .chained = true,
3634 .chain_id = AD1884_FIXUP_AMP_OVERRIDE, 994 .chain_id = AD1884_FIXUP_AMP_OVERRIDE,
3635 }, 995 },
996 [AD1884_FIXUP_DMIC_COEF] = {
997 .type = HDA_FIXUP_VERBS,
998 .v.verbs = ad1884_dmic_init_verbs,
999 },
1000 [AD1884_FIXUP_HP_TOUCHSMART] = {
1001 .type = HDA_FIXUP_VERBS,
1002 .v.verbs = ad1884_dmic_init_verbs,
1003 .chained = true,
1004 .chain_id = AD1884_FIXUP_HP_EAPD,
1005 },
3636}; 1006};
3637 1007
3638static const struct snd_pci_quirk ad1884_fixup_tbl[] = { 1008static const struct snd_pci_quirk ad1884_fixup_tbl[] = {
1009 SND_PCI_QUIRK(0x103c, 0x2a82, "HP Touchsmart", AD1884_FIXUP_HP_TOUCHSMART),
3639 SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD), 1010 SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD),
1011 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1884_FIXUP_DMIC_COEF),
3640 {} 1012 {}
3641}; 1013};
3642 1014
3643 1015
3644static int ad1884_parse_auto_config(struct hda_codec *codec) 1016static int patch_ad1884(struct hda_codec *codec)
3645{ 1017{
3646 struct ad198x_spec *spec; 1018 struct ad198x_spec *spec;
3647 int err; 1019 int err;
@@ -3674,1170 +1046,6 @@ static int ad1884_parse_auto_config(struct hda_codec *codec)
3674 return err; 1046 return err;
3675} 1047}
3676 1048
3677#ifdef ENABLE_AD_STATIC_QUIRKS
3678static int patch_ad1884_basic(struct hda_codec *codec)
3679{
3680 struct ad198x_spec *spec;
3681 int err;
3682
3683 err = alloc_ad_spec(codec);
3684 if (err < 0)
3685 return err;
3686 spec = codec->spec;
3687
3688 err = snd_hda_attach_beep_device(codec, 0x10);
3689 if (err < 0) {
3690 ad198x_free(codec);
3691 return err;
3692 }
3693 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
3694
3695 spec->multiout.max_channels = 2;
3696 spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids);
3697 spec->multiout.dac_nids = ad1884_dac_nids;
3698 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3699 spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids);
3700 spec->adc_nids = ad1884_adc_nids;
3701 spec->capsrc_nids = ad1884_capsrc_nids;
3702 spec->input_mux = &ad1884_capture_source;
3703 spec->num_mixers = 1;
3704 spec->mixers[0] = ad1884_base_mixers;
3705 spec->num_init_verbs = 1;
3706 spec->init_verbs[0] = ad1884_init_verbs;
3707 spec->spdif_route = 0;
3708#ifdef CONFIG_PM
3709 spec->loopback.amplist = ad1884_loopbacks;
3710#endif
3711 spec->vmaster_nid = 0x04;
3712 /* we need to cover all playback volumes */
3713 spec->slave_vols = ad1884_slave_vols;
3714 /* slaves may contain input volumes, so we can't raise to 0dB blindly */
3715 spec->avoid_init_slave_vol = 1;
3716
3717 codec->patch_ops = ad198x_patch_ops;
3718
3719 codec->no_trigger_sense = 1;
3720 codec->no_sticky_stream = 1;
3721
3722 return 0;
3723}
3724
3725static int patch_ad1884(struct hda_codec *codec)
3726{
3727 int board_config;
3728
3729 board_config = snd_hda_check_board_config(codec, AD1884_MODELS,
3730 ad1884_models, NULL);
3731 if (board_config < 0) {
3732 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3733 codec->chip_name);
3734 board_config = AD1884_AUTO;
3735 }
3736
3737 if (board_config == AD1884_AUTO)
3738 return ad1884_parse_auto_config(codec);
3739 else
3740 return patch_ad1884_basic(codec);
3741}
3742#else /* ENABLE_AD_STATIC_QUIRKS */
3743#define patch_ad1884 ad1884_parse_auto_config
3744#endif /* ENABLE_AD_STATIC_QUIRKS */
3745
3746
3747#ifdef ENABLE_AD_STATIC_QUIRKS
3748/*
3749 * Lenovo Thinkpad T61/X61
3750 */
3751static const struct hda_input_mux ad1984_thinkpad_capture_source = {
3752 .num_items = 4,
3753 .items = {
3754 { "Mic", 0x0 },
3755 { "Internal Mic", 0x1 },
3756 { "Mix", 0x3 },
3757 { "Dock Mic", 0x4 },
3758 },
3759};
3760
3761
3762/*
3763 * Dell Precision T3400
3764 */
3765static const struct hda_input_mux ad1984_dell_desktop_capture_source = {
3766 .num_items = 3,
3767 .items = {
3768 { "Front Mic", 0x0 },
3769 { "Line-In", 0x1 },
3770 { "Mix", 0x3 },
3771 },
3772};
3773
3774
3775static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = {
3776 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3777 /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */
3778 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3779 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3780 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3781 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3782 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
3783 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
3784 HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT),
3785 HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT),
3786 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
3787 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
3788 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3789 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
3790 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
3791 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3792 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3793 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3794 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3795 {
3796 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3797 /* The multiple "Capture Source" controls confuse alsamixer
3798 * So call somewhat different..
3799 */
3800 /* .name = "Capture Source", */
3801 .name = "Input Source",
3802 .count = 2,
3803 .info = ad198x_mux_enum_info,
3804 .get = ad198x_mux_enum_get,
3805 .put = ad198x_mux_enum_put,
3806 },
3807 /* SPDIF controls */
3808 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
3809 {
3810 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3811 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
3812 /* identical with ad1983 */
3813 .info = ad1983_spdif_route_info,
3814 .get = ad1983_spdif_route_get,
3815 .put = ad1983_spdif_route_put,
3816 },
3817 { } /* end */
3818};
3819
3820/* additional verbs */
3821static const struct hda_verb ad1984_thinkpad_init_verbs[] = {
3822 /* Port-E (docking station mic) pin */
3823 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
3824 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
3825 /* docking mic boost */
3826 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
3827 /* Analog PC Beeper - allow firmware/ACPI beeps */
3828 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a},
3829 /* Analog mixer - docking mic; mute as default */
3830 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
3831 /* enable EAPD bit */
3832 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
3833 { } /* end */
3834};
3835
3836/*
3837 * Dell Precision T3400
3838 */
3839static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = {
3840 HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT),
3841 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
3842 HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT),
3843 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
3844 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
3845 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
3846 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
3847 HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT),
3848 HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT),
3849 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT),
3850 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
3851 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
3852 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
3853 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
3854 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
3855 {
3856 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3857 /* The multiple "Capture Source" controls confuse alsamixer
3858 * So call somewhat different..
3859 */
3860 /* .name = "Capture Source", */
3861 .name = "Input Source",
3862 .count = 2,
3863 .info = ad198x_mux_enum_info,
3864 .get = ad198x_mux_enum_get,
3865 .put = ad198x_mux_enum_put,
3866 },
3867 { } /* end */
3868};
3869
3870/* Digial MIC ADC NID 0x05 + 0x06 */
3871static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo,
3872 struct hda_codec *codec,
3873 unsigned int stream_tag,
3874 unsigned int format,
3875 struct snd_pcm_substream *substream)
3876{
3877 snd_hda_codec_setup_stream(codec, 0x05 + substream->number,
3878 stream_tag, 0, format);
3879 return 0;
3880}
3881
3882static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo,
3883 struct hda_codec *codec,
3884 struct snd_pcm_substream *substream)
3885{
3886 snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number);
3887 return 0;
3888}
3889
3890static const struct hda_pcm_stream ad1984_pcm_dmic_capture = {
3891 .substreams = 2,
3892 .channels_min = 2,
3893 .channels_max = 2,
3894 .nid = 0x05,
3895 .ops = {
3896 .prepare = ad1984_pcm_dmic_prepare,
3897 .cleanup = ad1984_pcm_dmic_cleanup
3898 },
3899};
3900
3901static int ad1984_build_pcms(struct hda_codec *codec)
3902{
3903 struct ad198x_spec *spec = codec->spec;
3904 struct hda_pcm *info;
3905 int err;
3906
3907 err = ad198x_build_pcms(codec);
3908 if (err < 0)
3909 return err;
3910
3911 info = spec->pcm_rec + codec->num_pcms;
3912 codec->num_pcms++;
3913 info->name = "AD1984 Digital Mic";
3914 info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture;
3915 return 0;
3916}
3917
3918/* models */
3919enum {
3920 AD1984_AUTO,
3921 AD1984_BASIC,
3922 AD1984_THINKPAD,
3923 AD1984_DELL_DESKTOP,
3924 AD1984_MODELS
3925};
3926
3927static const char * const ad1984_models[AD1984_MODELS] = {
3928 [AD1984_AUTO] = "auto",
3929 [AD1984_BASIC] = "basic",
3930 [AD1984_THINKPAD] = "thinkpad",
3931 [AD1984_DELL_DESKTOP] = "dell_desktop",
3932};
3933
3934static const struct snd_pci_quirk ad1984_cfg_tbl[] = {
3935 /* Lenovo Thinkpad T61/X61 */
3936 SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD),
3937 SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP),
3938 SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP),
3939 {}
3940};
3941
3942static int patch_ad1984(struct hda_codec *codec)
3943{
3944 struct ad198x_spec *spec;
3945 int board_config, err;
3946
3947 board_config = snd_hda_check_board_config(codec, AD1984_MODELS,
3948 ad1984_models, ad1984_cfg_tbl);
3949 if (board_config < 0) {
3950 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
3951 codec->chip_name);
3952 board_config = AD1984_AUTO;
3953 }
3954
3955 if (board_config == AD1984_AUTO)
3956 return ad1884_parse_auto_config(codec);
3957
3958 err = patch_ad1884_basic(codec);
3959 if (err < 0)
3960 return err;
3961 spec = codec->spec;
3962
3963 switch (board_config) {
3964 case AD1984_BASIC:
3965 /* additional digital mics */
3966 spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers;
3967 codec->patch_ops.build_pcms = ad1984_build_pcms;
3968 break;
3969 case AD1984_THINKPAD:
3970 if (codec->subsystem_id == 0x17aa20fb) {
3971 /* Thinpad X300 does not have the ability to do SPDIF,
3972 or attach to docking station to use SPDIF */
3973 spec->multiout.dig_out_nid = 0;
3974 } else
3975 spec->multiout.dig_out_nid = AD1884_SPDIF_OUT;
3976 spec->input_mux = &ad1984_thinkpad_capture_source;
3977 spec->mixers[0] = ad1984_thinkpad_mixers;
3978 spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs;
3979 spec->analog_beep = 1;
3980 break;
3981 case AD1984_DELL_DESKTOP:
3982 spec->multiout.dig_out_nid = 0;
3983 spec->input_mux = &ad1984_dell_desktop_capture_source;
3984 spec->mixers[0] = ad1984_dell_desktop_mixers;
3985 break;
3986 }
3987 return 0;
3988}
3989#else /* ENABLE_AD_STATIC_QUIRKS */
3990#define patch_ad1984 ad1884_parse_auto_config
3991#endif /* ENABLE_AD_STATIC_QUIRKS */
3992
3993
3994/*
3995 * AD1883 / AD1884A / AD1984A / AD1984B
3996 *
3997 * port-B (0x14) - front mic-in
3998 * port-E (0x1c) - rear mic-in
3999 * port-F (0x16) - CD / ext out
4000 * port-C (0x15) - rear line-in
4001 * port-D (0x12) - rear line-out
4002 * port-A (0x11) - front hp-out
4003 *
4004 * AD1984A = AD1884A + digital-mic
4005 * AD1883 = equivalent with AD1984A
4006 * AD1984B = AD1984A + extra SPDIF-out
4007 *
4008 * FIXME:
4009 * We share the single DAC for both HP and line-outs (see AD1884/1984).
4010 */
4011
4012#ifdef ENABLE_AD_STATIC_QUIRKS
4013static const hda_nid_t ad1884a_dac_nids[1] = {
4014 0x03,
4015};
4016
4017#define ad1884a_adc_nids ad1884_adc_nids
4018#define ad1884a_capsrc_nids ad1884_capsrc_nids
4019
4020#define AD1884A_SPDIF_OUT 0x02
4021
4022static const struct hda_input_mux ad1884a_capture_source = {
4023 .num_items = 5,
4024 .items = {
4025 { "Front Mic", 0x0 },
4026 { "Mic", 0x4 },
4027 { "Line", 0x1 },
4028 { "CD", 0x2 },
4029 { "Mix", 0x3 },
4030 },
4031};
4032
4033static const struct snd_kcontrol_new ad1884a_base_mixers[] = {
4034 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4035 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4036 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4037 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4038 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4039 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4040 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4041 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4042 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4043 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4044 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4045 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4046 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4047 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4048 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT),
4049 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT),
4050 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4051 HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT),
4052 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4053 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4054 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4055 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4056 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4057 {
4058 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4059 /* The multiple "Capture Source" controls confuse alsamixer
4060 * So call somewhat different..
4061 */
4062 /* .name = "Capture Source", */
4063 .name = "Input Source",
4064 .count = 2,
4065 .info = ad198x_mux_enum_info,
4066 .get = ad198x_mux_enum_get,
4067 .put = ad198x_mux_enum_put,
4068 },
4069 /* SPDIF controls */
4070 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4071 {
4072 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4073 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4074 /* identical with ad1983 */
4075 .info = ad1983_spdif_route_info,
4076 .get = ad1983_spdif_route_get,
4077 .put = ad1983_spdif_route_put,
4078 },
4079 { } /* end */
4080};
4081
4082/*
4083 * initialization verbs
4084 */
4085static const struct hda_verb ad1884a_init_verbs[] = {
4086 /* DACs; unmute as default */
4087 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4088 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4089 /* Port-A (HP) mixer - route only from analog mixer */
4090 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4091 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4092 /* Port-A pin */
4093 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4094 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4095 /* Port-D (Line-out) mixer - route only from analog mixer */
4096 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4097 {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4098 /* Port-D pin */
4099 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4100 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4101 /* Mono-out mixer - route only from analog mixer */
4102 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4103 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4104 /* Mono-out pin */
4105 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4106 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4107 /* Port-B (front mic) pin */
4108 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4109 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4110 /* Port-C (rear line-in) pin */
4111 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4112 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
4113 /* Port-E (rear mic) pin */
4114 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4115 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4116 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */
4117 /* Port-F (CD) pin */
4118 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4119 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4120 /* Analog mixer; mute as default */
4121 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4122 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4123 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4124 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4125 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */
4126 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4127 /* Analog Mix output amp */
4128 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4129 /* capture sources */
4130 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0},
4131 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4132 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4133 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4134 /* SPDIF output amp */
4135 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
4136 { } /* end */
4137};
4138
4139#ifdef CONFIG_PM
4140static const struct hda_amp_list ad1884a_loopbacks[] = {
4141 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
4142 { 0x20, HDA_INPUT, 1 }, /* Mic */
4143 { 0x20, HDA_INPUT, 2 }, /* CD */
4144 { 0x20, HDA_INPUT, 4 }, /* Docking */
4145 { } /* end */
4146};
4147#endif
4148
4149/*
4150 * Laptop model
4151 *
4152 * Port A: Headphone jack
4153 * Port B: MIC jack
4154 * Port C: Internal MIC
4155 * Port D: Dock Line Out (if enabled)
4156 * Port E: Dock Line In (if enabled)
4157 * Port F: Internal speakers
4158 */
4159
4160static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol,
4161 struct snd_ctl_elem_value *ucontrol)
4162{
4163 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
4164 int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
4165 int mute = (!ucontrol->value.integer.value[0] &&
4166 !ucontrol->value.integer.value[1]);
4167 /* toggle GPIO1 according to the mute state */
4168 snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA,
4169 mute ? 0x02 : 0x0);
4170 return ret;
4171}
4172
4173static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = {
4174 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4175 {
4176 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4177 .name = "Master Playback Switch",
4178 .subdevice = HDA_SUBDEV_AMP_FLAG,
4179 .info = snd_hda_mixer_amp_switch_info,
4180 .get = snd_hda_mixer_amp_switch_get,
4181 .put = ad1884a_mobile_master_sw_put,
4182 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4183 },
4184 HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4185 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4186 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4187 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4188 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4189 HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4190 HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4191 HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4192 HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4193 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4194 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4195 HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4196 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4197 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4198 { } /* end */
4199};
4200
4201static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = {
4202 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4203 /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4204 {
4205 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4206 .name = "Master Playback Switch",
4207 .subdevice = HDA_SUBDEV_AMP_FLAG,
4208 .info = snd_hda_mixer_amp_switch_info,
4209 .get = snd_hda_mixer_amp_switch_get,
4210 .put = ad1884a_mobile_master_sw_put,
4211 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4212 },
4213 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4214 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4215 HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT),
4216 HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT),
4217 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4218 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4219 { } /* end */
4220};
4221
4222/* mute internal speaker if HP is plugged */
4223static void ad1884a_hp_automute(struct hda_codec *codec)
4224{
4225 unsigned int present;
4226
4227 present = snd_hda_jack_detect(codec, 0x11);
4228 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4229 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4230 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4231 present ? 0x00 : 0x02);
4232}
4233
4234/* switch to external mic if plugged */
4235static void ad1884a_hp_automic(struct hda_codec *codec)
4236{
4237 unsigned int present;
4238
4239 present = snd_hda_jack_detect(codec, 0x14);
4240 snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL,
4241 present ? 0 : 1);
4242}
4243
4244#define AD1884A_HP_EVENT 0x37
4245#define AD1884A_MIC_EVENT 0x36
4246
4247/* unsolicited event for HP jack sensing */
4248static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res)
4249{
4250 switch (res >> 26) {
4251 case AD1884A_HP_EVENT:
4252 ad1884a_hp_automute(codec);
4253 break;
4254 case AD1884A_MIC_EVENT:
4255 ad1884a_hp_automic(codec);
4256 break;
4257 }
4258}
4259
4260/* initialize jack-sensing, too */
4261static int ad1884a_hp_init(struct hda_codec *codec)
4262{
4263 ad198x_init(codec);
4264 ad1884a_hp_automute(codec);
4265 ad1884a_hp_automic(codec);
4266 return 0;
4267}
4268
4269/* mute internal speaker if HP or docking HP is plugged */
4270static void ad1884a_laptop_automute(struct hda_codec *codec)
4271{
4272 unsigned int present;
4273
4274 present = snd_hda_jack_detect(codec, 0x11);
4275 if (!present)
4276 present = snd_hda_jack_detect(codec, 0x12);
4277 snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0,
4278 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4279 snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE,
4280 present ? 0x00 : 0x02);
4281}
4282
4283/* switch to external mic if plugged */
4284static void ad1884a_laptop_automic(struct hda_codec *codec)
4285{
4286 unsigned int idx;
4287
4288 if (snd_hda_jack_detect(codec, 0x14))
4289 idx = 0;
4290 else if (snd_hda_jack_detect(codec, 0x1c))
4291 idx = 4;
4292 else
4293 idx = 1;
4294 snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx);
4295}
4296
4297/* unsolicited event for HP jack sensing */
4298static void ad1884a_laptop_unsol_event(struct hda_codec *codec,
4299 unsigned int res)
4300{
4301 switch (res >> 26) {
4302 case AD1884A_HP_EVENT:
4303 ad1884a_laptop_automute(codec);
4304 break;
4305 case AD1884A_MIC_EVENT:
4306 ad1884a_laptop_automic(codec);
4307 break;
4308 }
4309}
4310
4311/* initialize jack-sensing, too */
4312static int ad1884a_laptop_init(struct hda_codec *codec)
4313{
4314 ad198x_init(codec);
4315 ad1884a_laptop_automute(codec);
4316 ad1884a_laptop_automic(codec);
4317 return 0;
4318}
4319
4320/* additional verbs for laptop model */
4321static const struct hda_verb ad1884a_laptop_verbs[] = {
4322 /* Port-A (HP) pin - always unmuted */
4323 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4324 /* Port-F (int speaker) mixer - route only from analog mixer */
4325 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4326 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4327 /* Port-F (int speaker) pin */
4328 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4329 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4330 /* required for compaq 6530s/6531s speaker output */
4331 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
4332 /* Port-C pin - internal mic-in */
4333 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4334 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4335 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4336 /* Port-D (docking line-out) pin - default unmuted */
4337 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4338 /* analog mix */
4339 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4340 /* unsolicited event for pin-sense */
4341 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4342 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4343 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4344 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4345 /* allow to touch GPIO1 (for mute control) */
4346 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4347 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4348 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4349 { } /* end */
4350};
4351
4352static const struct hda_verb ad1884a_mobile_verbs[] = {
4353 /* DACs; unmute as default */
4354 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4355 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4356 /* Port-A (HP) mixer - route only from analog mixer */
4357 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4358 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4359 /* Port-A pin */
4360 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4361 /* Port-A (HP) pin - always unmuted */
4362 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4363 /* Port-B (mic jack) pin */
4364 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4365 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4366 /* Port-C (int mic) pin */
4367 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4368 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4369 /* Port-F (int speaker) mixer - route only from analog mixer */
4370 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4371 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4372 /* Port-F pin */
4373 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4374 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4375 /* Analog mixer; mute as default */
4376 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4377 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4378 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4379 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4380 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4381 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4382 /* Analog Mix output amp */
4383 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4384 /* capture sources */
4385 /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4386 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4387 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4388 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4389 /* unsolicited event for pin-sense */
4390 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4391 {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4392 /* allow to touch GPIO1 (for mute control) */
4393 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4394 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4395 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4396 { } /* end */
4397};
4398
4399/*
4400 * Thinkpad X300
4401 * 0x11 - HP
4402 * 0x12 - speaker
4403 * 0x14 - mic-in
4404 * 0x17 - built-in mic
4405 */
4406
4407static const struct hda_verb ad1984a_thinkpad_verbs[] = {
4408 /* HP unmute */
4409 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4410 /* analog mix */
4411 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4412 /* turn on EAPD */
4413 {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4414 /* unsolicited event for pin-sense */
4415 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4416 /* internal mic - dmic */
4417 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4418 /* set magic COEFs for dmic */
4419 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4420 {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4421 { } /* end */
4422};
4423
4424static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = {
4425 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4426 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4427 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4428 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4429 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4430 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4431 HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT),
4432 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4433 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4434 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4435 {
4436 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4437 .name = "Capture Source",
4438 .info = ad198x_mux_enum_info,
4439 .get = ad198x_mux_enum_get,
4440 .put = ad198x_mux_enum_put,
4441 },
4442 { } /* end */
4443};
4444
4445static const struct hda_input_mux ad1984a_thinkpad_capture_source = {
4446 .num_items = 3,
4447 .items = {
4448 { "Mic", 0x0 },
4449 { "Internal Mic", 0x5 },
4450 { "Mix", 0x3 },
4451 },
4452};
4453
4454/* mute internal speaker if HP is plugged */
4455static void ad1984a_thinkpad_automute(struct hda_codec *codec)
4456{
4457 unsigned int present;
4458
4459 present = snd_hda_jack_detect(codec, 0x11);
4460 snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0,
4461 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4462}
4463
4464/* unsolicited event for HP jack sensing */
4465static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec,
4466 unsigned int res)
4467{
4468 if ((res >> 26) != AD1884A_HP_EVENT)
4469 return;
4470 ad1984a_thinkpad_automute(codec);
4471}
4472
4473/* initialize jack-sensing, too */
4474static int ad1984a_thinkpad_init(struct hda_codec *codec)
4475{
4476 ad198x_init(codec);
4477 ad1984a_thinkpad_automute(codec);
4478 return 0;
4479}
4480
4481/*
4482 * Precision R5500
4483 * 0x12 - HP/line-out
4484 * 0x13 - speaker (mono)
4485 * 0x15 - mic-in
4486 */
4487
4488static const struct hda_verb ad1984a_precision_verbs[] = {
4489 /* Unmute main output path */
4490 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4491 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */
4492 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */
4493 /* Analog mixer; mute as default */
4494 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4495 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4496 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4497 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4498 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4499 /* Select mic as input */
4500 {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1},
4501 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */
4502 /* Configure as mic */
4503 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4504 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */
4505 /* HP unmute */
4506 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4507 /* turn on EAPD */
4508 {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02},
4509 /* unsolicited event for pin-sense */
4510 {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4511 { } /* end */
4512};
4513
4514static const struct snd_kcontrol_new ad1984a_precision_mixers[] = {
4515 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4516 HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),
4517 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4518 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4519 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4520 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4521 HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT),
4522 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4523 HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT),
4524 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4525 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4526 { } /* end */
4527};
4528
4529
4530/* mute internal speaker if HP is plugged */
4531static void ad1984a_precision_automute(struct hda_codec *codec)
4532{
4533 unsigned int present;
4534
4535 present = snd_hda_jack_detect(codec, 0x12);
4536 snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0,
4537 HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0);
4538}
4539
4540
4541/* unsolicited event for HP jack sensing */
4542static void ad1984a_precision_unsol_event(struct hda_codec *codec,
4543 unsigned int res)
4544{
4545 if ((res >> 26) != AD1884A_HP_EVENT)
4546 return;
4547 ad1984a_precision_automute(codec);
4548}
4549
4550/* initialize jack-sensing, too */
4551static int ad1984a_precision_init(struct hda_codec *codec)
4552{
4553 ad198x_init(codec);
4554 ad1984a_precision_automute(codec);
4555 return 0;
4556}
4557
4558
4559/*
4560 * HP Touchsmart
4561 * port-A (0x11) - front hp-out
4562 * port-B (0x14) - unused
4563 * port-C (0x15) - unused
4564 * port-D (0x12) - rear line out
4565 * port-E (0x1c) - front mic-in
4566 * port-F (0x16) - Internal speakers
4567 * digital-mic (0x17) - Internal mic
4568 */
4569
4570static const struct hda_verb ad1984a_touchsmart_verbs[] = {
4571 /* DACs; unmute as default */
4572 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4573 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */
4574 /* Port-A (HP) mixer - route only from analog mixer */
4575 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4576 {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4577 /* Port-A pin */
4578 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4579 /* Port-A (HP) pin - always unmuted */
4580 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4581 /* Port-E (int speaker) mixer - route only from analog mixer */
4582 {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03},
4583 /* Port-E pin */
4584 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4585 {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE},
4586 {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
4587 /* Port-F (int speaker) mixer - route only from analog mixer */
4588 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4589 {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
4590 /* Port-F pin */
4591 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
4592 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4593 /* Analog mixer; mute as default */
4594 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
4595 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
4596 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
4597 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
4598 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
4599 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
4600 /* Analog Mix output amp */
4601 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4602 /* capture sources */
4603 /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */
4604 {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4605 {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0},
4606 {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
4607 /* unsolicited event for pin-sense */
4608 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT},
4609 {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT},
4610 /* allow to touch GPIO1 (for mute control) */
4611 {0x01, AC_VERB_SET_GPIO_MASK, 0x02},
4612 {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02},
4613 {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */
4614 /* internal mic - dmic */
4615 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
4616 /* set magic COEFs for dmic */
4617 {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7},
4618 {0x01, AC_VERB_SET_PROC_COEF, 0x08},
4619 { } /* end */
4620};
4621
4622static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = {
4623 HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT),
4624/* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/
4625 {
4626 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4627 .subdevice = HDA_SUBDEV_AMP_FLAG,
4628 .name = "Master Playback Switch",
4629 .info = snd_hda_mixer_amp_switch_info,
4630 .get = snd_hda_mixer_amp_switch_get,
4631 .put = ad1884a_mobile_master_sw_put,
4632 .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT),
4633 },
4634 HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT),
4635 HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT),
4636 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4637 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4638 HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT),
4639 HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT),
4640 { } /* end */
4641};
4642
4643/* switch to external mic if plugged */
4644static void ad1984a_touchsmart_automic(struct hda_codec *codec)
4645{
4646 if (snd_hda_jack_detect(codec, 0x1c))
4647 snd_hda_codec_write(codec, 0x0c, 0,
4648 AC_VERB_SET_CONNECT_SEL, 0x4);
4649 else
4650 snd_hda_codec_write(codec, 0x0c, 0,
4651 AC_VERB_SET_CONNECT_SEL, 0x5);
4652}
4653
4654
4655/* unsolicited event for HP jack sensing */
4656static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec,
4657 unsigned int res)
4658{
4659 switch (res >> 26) {
4660 case AD1884A_HP_EVENT:
4661 ad1884a_hp_automute(codec);
4662 break;
4663 case AD1884A_MIC_EVENT:
4664 ad1984a_touchsmart_automic(codec);
4665 break;
4666 }
4667}
4668
4669/* initialize jack-sensing, too */
4670static int ad1984a_touchsmart_init(struct hda_codec *codec)
4671{
4672 ad198x_init(codec);
4673 ad1884a_hp_automute(codec);
4674 ad1984a_touchsmart_automic(codec);
4675 return 0;
4676}
4677
4678
4679/*
4680 */
4681
4682enum {
4683 AD1884A_AUTO,
4684 AD1884A_DESKTOP,
4685 AD1884A_LAPTOP,
4686 AD1884A_MOBILE,
4687 AD1884A_THINKPAD,
4688 AD1984A_TOUCHSMART,
4689 AD1984A_PRECISION,
4690 AD1884A_MODELS
4691};
4692
4693static const char * const ad1884a_models[AD1884A_MODELS] = {
4694 [AD1884A_AUTO] = "auto",
4695 [AD1884A_DESKTOP] = "desktop",
4696 [AD1884A_LAPTOP] = "laptop",
4697 [AD1884A_MOBILE] = "mobile",
4698 [AD1884A_THINKPAD] = "thinkpad",
4699 [AD1984A_TOUCHSMART] = "touchsmart",
4700 [AD1984A_PRECISION] = "precision",
4701};
4702
4703static const struct snd_pci_quirk ad1884a_cfg_tbl[] = {
4704 SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION),
4705 SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE),
4706 SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP),
4707 SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE),
4708 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE),
4709 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP),
4710 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP),
4711 SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP),
4712 SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE),
4713 SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD),
4714 SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART),
4715 {}
4716};
4717
4718static int patch_ad1884a(struct hda_codec *codec)
4719{
4720 struct ad198x_spec *spec;
4721 int err, board_config;
4722
4723 board_config = snd_hda_check_board_config(codec, AD1884A_MODELS,
4724 ad1884a_models,
4725 ad1884a_cfg_tbl);
4726 if (board_config < 0) {
4727 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
4728 codec->chip_name);
4729 board_config = AD1884A_AUTO;
4730 }
4731
4732 if (board_config == AD1884A_AUTO)
4733 return ad1884_parse_auto_config(codec);
4734
4735 err = alloc_ad_spec(codec);
4736 if (err < 0)
4737 return err;
4738 spec = codec->spec;
4739
4740 err = snd_hda_attach_beep_device(codec, 0x10);
4741 if (err < 0) {
4742 ad198x_free(codec);
4743 return err;
4744 }
4745 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
4746
4747 spec->multiout.max_channels = 2;
4748 spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids);
4749 spec->multiout.dac_nids = ad1884a_dac_nids;
4750 spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT;
4751 spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids);
4752 spec->adc_nids = ad1884a_adc_nids;
4753 spec->capsrc_nids = ad1884a_capsrc_nids;
4754 spec->input_mux = &ad1884a_capture_source;
4755 spec->num_mixers = 1;
4756 spec->mixers[0] = ad1884a_base_mixers;
4757 spec->num_init_verbs = 1;
4758 spec->init_verbs[0] = ad1884a_init_verbs;
4759 spec->spdif_route = 0;
4760#ifdef CONFIG_PM
4761 spec->loopback.amplist = ad1884a_loopbacks;
4762#endif
4763 codec->patch_ops = ad198x_patch_ops;
4764
4765 /* override some parameters */
4766 switch (board_config) {
4767 case AD1884A_LAPTOP:
4768 spec->mixers[0] = ad1884a_laptop_mixers;
4769 spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs;
4770 spec->multiout.dig_out_nid = 0;
4771 codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event;
4772 codec->patch_ops.init = ad1884a_laptop_init;
4773 /* set the upper-limit for mixer amp to 0dB for avoiding the
4774 * possible damage by overloading
4775 */
4776 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4777 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4778 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4779 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4780 (1 << AC_AMPCAP_MUTE_SHIFT));
4781 break;
4782 case AD1884A_MOBILE:
4783 spec->mixers[0] = ad1884a_mobile_mixers;
4784 spec->init_verbs[0] = ad1884a_mobile_verbs;
4785 spec->multiout.dig_out_nid = 0;
4786 codec->patch_ops.unsol_event = ad1884a_hp_unsol_event;
4787 codec->patch_ops.init = ad1884a_hp_init;
4788 /* set the upper-limit for mixer amp to 0dB for avoiding the
4789 * possible damage by overloading
4790 */
4791 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4792 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4793 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4794 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4795 (1 << AC_AMPCAP_MUTE_SHIFT));
4796 break;
4797 case AD1884A_THINKPAD:
4798 spec->mixers[0] = ad1984a_thinkpad_mixers;
4799 spec->init_verbs[spec->num_init_verbs++] =
4800 ad1984a_thinkpad_verbs;
4801 spec->multiout.dig_out_nid = 0;
4802 spec->input_mux = &ad1984a_thinkpad_capture_source;
4803 codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event;
4804 codec->patch_ops.init = ad1984a_thinkpad_init;
4805 break;
4806 case AD1984A_PRECISION:
4807 spec->mixers[0] = ad1984a_precision_mixers;
4808 spec->init_verbs[spec->num_init_verbs++] =
4809 ad1984a_precision_verbs;
4810 spec->multiout.dig_out_nid = 0;
4811 codec->patch_ops.unsol_event = ad1984a_precision_unsol_event;
4812 codec->patch_ops.init = ad1984a_precision_init;
4813 break;
4814 case AD1984A_TOUCHSMART:
4815 spec->mixers[0] = ad1984a_touchsmart_mixers;
4816 spec->init_verbs[0] = ad1984a_touchsmart_verbs;
4817 spec->multiout.dig_out_nid = 0;
4818 codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event;
4819 codec->patch_ops.init = ad1984a_touchsmart_init;
4820 /* set the upper-limit for mixer amp to 0dB for avoiding the
4821 * possible damage by overloading
4822 */
4823 snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT,
4824 (0x17 << AC_AMPCAP_OFFSET_SHIFT) |
4825 (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) |
4826 (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) |
4827 (1 << AC_AMPCAP_MUTE_SHIFT));
4828 break;
4829 }
4830
4831 codec->no_trigger_sense = 1;
4832 codec->no_sticky_stream = 1;
4833
4834 return 0;
4835}
4836#else /* ENABLE_AD_STATIC_QUIRKS */
4837#define patch_ad1884a ad1884_parse_auto_config
4838#endif /* ENABLE_AD_STATIC_QUIRKS */
4839
4840
4841/* 1049/*
4842 * AD1882 / AD1882A 1050 * AD1882 / AD1882A
4843 * 1051 *
@@ -4850,299 +1058,7 @@ static int patch_ad1884a(struct hda_codec *codec)
4850 * port-G - rear clfe-out (6stack) 1058 * port-G - rear clfe-out (6stack)
4851 */ 1059 */
4852 1060
4853#ifdef ENABLE_AD_STATIC_QUIRKS 1061static int patch_ad1882(struct hda_codec *codec)
4854static const hda_nid_t ad1882_dac_nids[3] = {
4855 0x04, 0x03, 0x05
4856};
4857
4858static const hda_nid_t ad1882_adc_nids[2] = {
4859 0x08, 0x09,
4860};
4861
4862static const hda_nid_t ad1882_capsrc_nids[2] = {
4863 0x0c, 0x0d,
4864};
4865
4866#define AD1882_SPDIF_OUT 0x02
4867
4868/* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */
4869static const struct hda_input_mux ad1882_capture_source = {
4870 .num_items = 5,
4871 .items = {
4872 { "Front Mic", 0x1 },
4873 { "Mic", 0x4 },
4874 { "Line", 0x2 },
4875 { "CD", 0x3 },
4876 { "Mix", 0x7 },
4877 },
4878};
4879
4880/* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */
4881static const struct hda_input_mux ad1882a_capture_source = {
4882 .num_items = 5,
4883 .items = {
4884 { "Front Mic", 0x1 },
4885 { "Mic", 0x4},
4886 { "Line", 0x2 },
4887 { "Digital Mic", 0x06 },
4888 { "Mix", 0x7 },
4889 },
4890};
4891
4892static const struct snd_kcontrol_new ad1882_base_mixers[] = {
4893 HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT),
4894 HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT),
4895 HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT),
4896 HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT),
4897 HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT),
4898 HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT),
4899 HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT),
4900 HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT),
4901
4902 HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT),
4903 HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT),
4904 HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT),
4905 HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT),
4906 HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT),
4907 HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT),
4908 HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT),
4909 {
4910 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4911 /* The multiple "Capture Source" controls confuse alsamixer
4912 * So call somewhat different..
4913 */
4914 /* .name = "Capture Source", */
4915 .name = "Input Source",
4916 .count = 2,
4917 .info = ad198x_mux_enum_info,
4918 .get = ad198x_mux_enum_get,
4919 .put = ad198x_mux_enum_put,
4920 },
4921 /* SPDIF controls */
4922 HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT),
4923 {
4924 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4925 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source",
4926 /* identical with ad1983 */
4927 .info = ad1983_spdif_route_info,
4928 .get = ad1983_spdif_route_get,
4929 .put = ad1983_spdif_route_put,
4930 },
4931 { } /* end */
4932};
4933
4934static const struct snd_kcontrol_new ad1882_loopback_mixers[] = {
4935 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4936 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4937 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT),
4938 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT),
4939 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT),
4940 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT),
4941 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4942 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4943 { } /* end */
4944};
4945
4946static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = {
4947 HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT),
4948 HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT),
4949 HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT),
4950 HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT),
4951 HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT),
4952 HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT),
4953 HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT),
4954 HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT),
4955 HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT),
4956 { } /* end */
4957};
4958
4959static const struct snd_kcontrol_new ad1882_3stack_mixers[] = {
4960 HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT),
4961 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT),
4962 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT),
4963 {
4964 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4965 .name = "Channel Mode",
4966 .info = ad198x_ch_mode_info,
4967 .get = ad198x_ch_mode_get,
4968 .put = ad198x_ch_mode_put,
4969 },
4970 { } /* end */
4971};
4972
4973/* simple auto-mute control for AD1882 3-stack board */
4974#define AD1882_HP_EVENT 0x01
4975
4976static void ad1882_3stack_automute(struct hda_codec *codec)
4977{
4978 bool mute = snd_hda_jack_detect(codec, 0x11);
4979 snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
4980 mute ? 0 : PIN_OUT);
4981}
4982
4983static int ad1882_3stack_automute_init(struct hda_codec *codec)
4984{
4985 ad198x_init(codec);
4986 ad1882_3stack_automute(codec);
4987 return 0;
4988}
4989
4990static void ad1882_3stack_unsol_event(struct hda_codec *codec, unsigned int res)
4991{
4992 switch (res >> 26) {
4993 case AD1882_HP_EVENT:
4994 ad1882_3stack_automute(codec);
4995 break;
4996 }
4997}
4998
4999static const struct snd_kcontrol_new ad1882_6stack_mixers[] = {
5000 HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT),
5001 HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT),
5002 HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT),
5003 { } /* end */
5004};
5005
5006static const struct hda_verb ad1882_ch2_init[] = {
5007 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5008 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5009 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5010 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5011 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5012 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5013 { } /* end */
5014};
5015
5016static const struct hda_verb ad1882_ch4_init[] = {
5017 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5018 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5019 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5020 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5021 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5022 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5023 { } /* end */
5024};
5025
5026static const struct hda_verb ad1882_ch6_init[] = {
5027 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5028 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5029 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5030 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5031 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5032 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5033 { } /* end */
5034};
5035
5036static const struct hda_channel_mode ad1882_modes[3] = {
5037 { 2, ad1882_ch2_init },
5038 { 4, ad1882_ch4_init },
5039 { 6, ad1882_ch6_init },
5040};
5041
5042/*
5043 * initialization verbs
5044 */
5045static const struct hda_verb ad1882_init_verbs[] = {
5046 /* DACs; mute as default */
5047 {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5048 {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5049 {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO},
5050 /* Port-A (HP) mixer */
5051 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5052 {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5053 /* Port-A pin */
5054 {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5055 {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5056 /* HP selector - select DAC2 */
5057 {0x37, AC_VERB_SET_CONNECT_SEL, 0x1},
5058 /* Port-D (Line-out) mixer */
5059 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5060 {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5061 /* Port-D pin */
5062 {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5063 {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5064 /* Mono-out mixer */
5065 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)},
5066 {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)},
5067 /* Mono-out pin */
5068 {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP},
5069 {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5070 /* Port-B (front mic) pin */
5071 {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5072 {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5073 {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5074 /* Port-C (line-in) pin */
5075 {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN},
5076 {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5077 {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5078 /* Port-C mixer - mute as input */
5079 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5080 {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5081 /* Port-E (mic-in) pin */
5082 {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},
5083 {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5084 {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */
5085 /* Port-E mixer - mute as input */
5086 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5087 {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5088 /* Port-F (surround) */
5089 {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5090 {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5091 /* Port-G (CLFE) */
5092 {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT},
5093 {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE},
5094 /* Analog mixer; mute as default */
5095 /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */
5096 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)},
5097 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)},
5098 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)},
5099 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)},
5100 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)},
5101 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)},
5102 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)},
5103 {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)},
5104 /* Analog Mix output amp */
5105 {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */
5106 /* SPDIF output selector */
5107 {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
5108 {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */
5109 {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */
5110 { } /* end */
5111};
5112
5113static const struct hda_verb ad1882_3stack_automute_verbs[] = {
5114 {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1882_HP_EVENT},
5115 { } /* end */
5116};
5117
5118#ifdef CONFIG_PM
5119static const struct hda_amp_list ad1882_loopbacks[] = {
5120 { 0x20, HDA_INPUT, 0 }, /* Front Mic */
5121 { 0x20, HDA_INPUT, 1 }, /* Mic */
5122 { 0x20, HDA_INPUT, 4 }, /* Line */
5123 { 0x20, HDA_INPUT, 6 }, /* CD */
5124 { } /* end */
5125};
5126#endif
5127
5128/* models */
5129enum {
5130 AD1882_AUTO,
5131 AD1882_3STACK,
5132 AD1882_6STACK,
5133 AD1882_3STACK_AUTOMUTE,
5134 AD1882_MODELS
5135};
5136
5137static const char * const ad1882_models[AD1986A_MODELS] = {
5138 [AD1882_AUTO] = "auto",
5139 [AD1882_3STACK] = "3stack",
5140 [AD1882_6STACK] = "6stack",
5141 [AD1882_3STACK_AUTOMUTE] = "3stack-automute",
5142};
5143#endif /* ENABLE_AD_STATIC_QUIRKS */
5144
5145static int ad1882_parse_auto_config(struct hda_codec *codec)
5146{ 1062{
5147 struct ad198x_spec *spec; 1063 struct ad198x_spec *spec;
5148 int err; 1064 int err;
@@ -5169,110 +1085,20 @@ static int ad1882_parse_auto_config(struct hda_codec *codec)
5169 return err; 1085 return err;
5170} 1086}
5171 1087
5172#ifdef ENABLE_AD_STATIC_QUIRKS
5173static int patch_ad1882(struct hda_codec *codec)
5174{
5175 struct ad198x_spec *spec;
5176 int err, board_config;
5177
5178 board_config = snd_hda_check_board_config(codec, AD1882_MODELS,
5179 ad1882_models, NULL);
5180 if (board_config < 0) {
5181 printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n",
5182 codec->chip_name);
5183 board_config = AD1882_AUTO;
5184 }
5185
5186 if (board_config == AD1882_AUTO)
5187 return ad1882_parse_auto_config(codec);
5188
5189 err = alloc_ad_spec(codec);
5190 if (err < 0)
5191 return err;
5192 spec = codec->spec;
5193
5194 err = snd_hda_attach_beep_device(codec, 0x10);
5195 if (err < 0) {
5196 ad198x_free(codec);
5197 return err;
5198 }
5199 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT);
5200
5201 spec->multiout.max_channels = 6;
5202 spec->multiout.num_dacs = 3;
5203 spec->multiout.dac_nids = ad1882_dac_nids;
5204 spec->multiout.dig_out_nid = AD1882_SPDIF_OUT;
5205 spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids);
5206 spec->adc_nids = ad1882_adc_nids;
5207 spec->capsrc_nids = ad1882_capsrc_nids;
5208 if (codec->vendor_id == 0x11d41882)
5209 spec->input_mux = &ad1882_capture_source;
5210 else
5211 spec->input_mux = &ad1882a_capture_source;
5212 spec->num_mixers = 2;
5213 spec->mixers[0] = ad1882_base_mixers;
5214 if (codec->vendor_id == 0x11d41882)
5215 spec->mixers[1] = ad1882_loopback_mixers;
5216 else
5217 spec->mixers[1] = ad1882a_loopback_mixers;
5218 spec->num_init_verbs = 1;
5219 spec->init_verbs[0] = ad1882_init_verbs;
5220 spec->spdif_route = 0;
5221#ifdef CONFIG_PM
5222 spec->loopback.amplist = ad1882_loopbacks;
5223#endif
5224 spec->vmaster_nid = 0x04;
5225
5226 codec->patch_ops = ad198x_patch_ops;
5227
5228 /* override some parameters */
5229 switch (board_config) {
5230 default:
5231 case AD1882_3STACK:
5232 case AD1882_3STACK_AUTOMUTE:
5233 spec->num_mixers = 3;
5234 spec->mixers[2] = ad1882_3stack_mixers;
5235 spec->channel_mode = ad1882_modes;
5236 spec->num_channel_mode = ARRAY_SIZE(ad1882_modes);
5237 spec->need_dac_fix = 1;
5238 spec->multiout.max_channels = 2;
5239 spec->multiout.num_dacs = 1;
5240 if (board_config != AD1882_3STACK) {
5241 spec->init_verbs[spec->num_init_verbs++] =
5242 ad1882_3stack_automute_verbs;
5243 codec->patch_ops.unsol_event = ad1882_3stack_unsol_event;
5244 codec->patch_ops.init = ad1882_3stack_automute_init;
5245 }
5246 break;
5247 case AD1882_6STACK:
5248 spec->num_mixers = 3;
5249 spec->mixers[2] = ad1882_6stack_mixers;
5250 break;
5251 }
5252
5253 codec->no_trigger_sense = 1;
5254 codec->no_sticky_stream = 1;
5255
5256 return 0;
5257}
5258#else /* ENABLE_AD_STATIC_QUIRKS */
5259#define patch_ad1882 ad1882_parse_auto_config
5260#endif /* ENABLE_AD_STATIC_QUIRKS */
5261
5262 1088
5263/* 1089/*
5264 * patch entries 1090 * patch entries
5265 */ 1091 */
5266static const struct hda_codec_preset snd_hda_preset_analog[] = { 1092static const struct hda_codec_preset snd_hda_preset_analog[] = {
5267 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, 1093 { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884 },
5268 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, 1094 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 },
5269 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, 1095 { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884 },
5270 { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, 1096 { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 },
5271 { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a }, 1097 { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884 },
5272 { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a }, 1098 { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884 },
5273 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, 1099 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 },
5274 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, 1100 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 },
5275 { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 }, 1101 { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1884 },
5276 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, 1102 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a },
5277 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, 1103 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 },
5278 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 }, 1104 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index de00ce166470..4edd2d0f9a3c 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -66,6 +66,8 @@ struct conexant_spec {
66 hda_nid_t eapds[4]; 66 hda_nid_t eapds[4];
67 bool dynamic_eapd; 67 bool dynamic_eapd;
68 68
69 unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */
70
69#ifdef ENABLE_CXT_STATIC_QUIRKS 71#ifdef ENABLE_CXT_STATIC_QUIRKS
70 const struct snd_kcontrol_new *mixers[5]; 72 const struct snd_kcontrol_new *mixers[5];
71 int num_mixers; 73 int num_mixers;
@@ -3200,6 +3202,9 @@ static int cx_auto_init(struct hda_codec *codec)
3200 snd_hda_gen_init(codec); 3202 snd_hda_gen_init(codec);
3201 if (!spec->dynamic_eapd) 3203 if (!spec->dynamic_eapd)
3202 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 3204 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true);
3205
3206 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT);
3207
3203 return 0; 3208 return 0;
3204} 3209}
3205 3210
@@ -3224,6 +3229,8 @@ enum {
3224 CXT_PINCFG_LEMOTE_A1205, 3229 CXT_PINCFG_LEMOTE_A1205,
3225 CXT_FIXUP_STEREO_DMIC, 3230 CXT_FIXUP_STEREO_DMIC,
3226 CXT_FIXUP_INC_MIC_BOOST, 3231 CXT_FIXUP_INC_MIC_BOOST,
3232 CXT_FIXUP_HEADPHONE_MIC_PIN,
3233 CXT_FIXUP_HEADPHONE_MIC,
3227}; 3234};
3228 3235
3229static void cxt_fixup_stereo_dmic(struct hda_codec *codec, 3236static void cxt_fixup_stereo_dmic(struct hda_codec *codec,
@@ -3246,6 +3253,59 @@ static void cxt5066_increase_mic_boost(struct hda_codec *codec,
3246 (0 << AC_AMPCAP_MUTE_SHIFT)); 3253 (0 << AC_AMPCAP_MUTE_SHIFT));
3247} 3254}
3248 3255
3256static void cxt_update_headset_mode(struct hda_codec *codec)
3257{
3258 /* The verbs used in this function were tested on a Conexant CX20751/2 codec. */
3259 int i;
3260 bool mic_mode = false;
3261 struct conexant_spec *spec = codec->spec;
3262 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3263
3264 hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]];
3265
3266 for (i = 0; i < cfg->num_inputs; i++)
3267 if (cfg->inputs[i].pin == mux_pin) {
3268 mic_mode = !!cfg->inputs[i].is_headphone_mic;
3269 break;
3270 }
3271
3272 if (mic_mode) {
3273 snd_hda_codec_write_cache(codec, 0x1c, 0, 0x410, 0x7c); /* enable merged mode for analog int-mic */
3274 spec->gen.hp_jack_present = false;
3275 } else {
3276 snd_hda_codec_write_cache(codec, 0x1c, 0, 0x410, 0x54); /* disable merged mode for analog int-mic */
3277 spec->gen.hp_jack_present = snd_hda_jack_detect(codec, spec->gen.autocfg.hp_pins[0]);
3278 }
3279
3280 snd_hda_gen_update_outputs(codec);
3281}
3282
3283static void cxt_update_headset_mode_hook(struct hda_codec *codec,
3284 struct snd_ctl_elem_value *ucontrol)
3285{
3286 cxt_update_headset_mode(codec);
3287}
3288
3289static void cxt_fixup_headphone_mic(struct hda_codec *codec,
3290 const struct hda_fixup *fix, int action)
3291{
3292 struct conexant_spec *spec = codec->spec;
3293
3294 switch (action) {
3295 case HDA_FIXUP_ACT_PRE_PROBE:
3296 spec->parse_flags |= HDA_PINCFG_HEADPHONE_MIC;
3297 break;
3298 case HDA_FIXUP_ACT_PROBE:
3299 spec->gen.cap_sync_hook = cxt_update_headset_mode_hook;
3300 spec->gen.automute_hook = cxt_update_headset_mode;
3301 break;
3302 case HDA_FIXUP_ACT_INIT:
3303 cxt_update_headset_mode(codec);
3304 break;
3305 }
3306}
3307
3308
3249/* ThinkPad X200 & co with cxt5051 */ 3309/* ThinkPad X200 & co with cxt5051 */
3250static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { 3310static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = {
3251 { 0x16, 0x042140ff }, /* HP (seq# overridden) */ 3311 { 0x16, 0x042140ff }, /* HP (seq# overridden) */
@@ -3302,6 +3362,19 @@ static const struct hda_fixup cxt_fixups[] = {
3302 .type = HDA_FIXUP_FUNC, 3362 .type = HDA_FIXUP_FUNC,
3303 .v.func = cxt5066_increase_mic_boost, 3363 .v.func = cxt5066_increase_mic_boost,
3304 }, 3364 },
3365 [CXT_FIXUP_HEADPHONE_MIC_PIN] = {
3366 .type = HDA_FIXUP_PINS,
3367 .chained = true,
3368 .chain_id = CXT_FIXUP_HEADPHONE_MIC,
3369 .v.pins = (const struct hda_pintbl[]) {
3370 { 0x18, 0x03a1913d }, /* use as headphone mic, without its own jack detect */
3371 { }
3372 }
3373 },
3374 [CXT_FIXUP_HEADPHONE_MIC] = {
3375 .type = HDA_FIXUP_FUNC,
3376 .v.func = cxt_fixup_headphone_mic,
3377 },
3305}; 3378};
3306 3379
3307static const struct snd_pci_quirk cxt5051_fixups[] = { 3380static const struct snd_pci_quirk cxt5051_fixups[] = {
@@ -3311,6 +3384,7 @@ static const struct snd_pci_quirk cxt5051_fixups[] = {
3311 3384
3312static const struct snd_pci_quirk cxt5066_fixups[] = { 3385static const struct snd_pci_quirk cxt5066_fixups[] = {
3313 SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), 3386 SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC),
3387 SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN),
3314 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), 3388 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410),
3315 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), 3389 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410),
3316 SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), 3390 SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410),
@@ -3395,7 +3469,8 @@ static int patch_conexant_auto(struct hda_codec *codec)
3395 3469
3396 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 3470 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE);
3397 3471
3398 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); 3472 err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL,
3473 spec->parse_flags);
3399 if (err < 0) 3474 if (err < 0)
3400 goto error; 3475 goto error;
3401 3476
@@ -3416,6 +3491,8 @@ static int patch_conexant_auto(struct hda_codec *codec)
3416 codec->bus->allow_bus_reset = 1; 3491 codec->bus->allow_bus_reset = 1;
3417 } 3492 }
3418 3493
3494 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3495
3419 return 0; 3496 return 0;
3420 3497
3421 error: 3498 error:
diff --git a/sound/pci/hda/patch_hdmi.c b/sound/pci/hda/patch_hdmi.c
index 9f3586276871..9a58893d52a7 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -67,6 +67,8 @@ struct hdmi_spec_per_pin {
67 struct delayed_work work; 67 struct delayed_work work;
68 struct snd_kcontrol *eld_ctl; 68 struct snd_kcontrol *eld_ctl;
69 int repoll_count; 69 int repoll_count;
70 bool setup; /* the stream has been set up by prepare callback */
71 int channels; /* current number of channels */
70 bool non_pcm; 72 bool non_pcm;
71 bool chmap_set; /* channel-map override by ALSA API? */ 73 bool chmap_set; /* channel-map override by ALSA API? */
72 unsigned char chmap[8]; /* ALSA API channel-map */ 74 unsigned char chmap[8]; /* ALSA API channel-map */
@@ -551,6 +553,17 @@ static int hdmi_channel_allocation(struct hdmi_eld *eld, int channels)
551 } 553 }
552 } 554 }
553 555
556 if (!ca) {
557 /* if there was no match, select the regular ALSA channel
558 * allocation with the matching number of channels */
559 for (i = 0; i < ARRAY_SIZE(channel_allocations); i++) {
560 if (channels == channel_allocations[i].channels) {
561 ca = channel_allocations[i].ca_index;
562 break;
563 }
564 }
565 }
566
554 snd_print_channel_allocation(eld->info.spk_alloc, buf, sizeof(buf)); 567 snd_print_channel_allocation(eld->info.spk_alloc, buf, sizeof(buf));
555 snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n", 568 snd_printdd("HDMI: select CA 0x%x for %d-channel allocation: %s\n",
556 ca, channels, buf); 569 ca, channels, buf);
@@ -868,18 +881,19 @@ static bool hdmi_infoframe_uptodate(struct hda_codec *codec, hda_nid_t pin_nid,
868 return true; 881 return true;
869} 882}
870 883
871static void hdmi_setup_audio_infoframe(struct hda_codec *codec, int pin_idx, 884static void hdmi_setup_audio_infoframe(struct hda_codec *codec,
872 bool non_pcm, 885 struct hdmi_spec_per_pin *per_pin,
873 struct snd_pcm_substream *substream) 886 bool non_pcm)
874{ 887{
875 struct hdmi_spec *spec = codec->spec;
876 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
877 hda_nid_t pin_nid = per_pin->pin_nid; 888 hda_nid_t pin_nid = per_pin->pin_nid;
878 int channels = substream->runtime->channels; 889 int channels = per_pin->channels;
879 struct hdmi_eld *eld; 890 struct hdmi_eld *eld;
880 int ca; 891 int ca;
881 union audio_infoframe ai; 892 union audio_infoframe ai;
882 893
894 if (!channels)
895 return;
896
883 eld = &per_pin->sink_eld; 897 eld = &per_pin->sink_eld;
884 if (!eld->monitor_present) 898 if (!eld->monitor_present)
885 return; 899 return;
@@ -959,6 +973,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
959 int pin_nid; 973 int pin_nid;
960 int pin_idx; 974 int pin_idx;
961 struct hda_jack_tbl *jack; 975 struct hda_jack_tbl *jack;
976 int dev_entry = (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT;
962 977
963 jack = snd_hda_jack_tbl_get_from_tag(codec, tag); 978 jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
964 if (!jack) 979 if (!jack)
@@ -967,8 +982,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
967 jack->jack_dirty = 1; 982 jack->jack_dirty = 1;
968 983
969 _snd_printd(SND_PR_VERBOSE, 984 _snd_printd(SND_PR_VERBOSE,
970 "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 985 "HDMI hot plug event: Codec=%d Pin=%d Device=%d Inactive=%d Presence_Detect=%d ELD_Valid=%d\n",
971 codec->addr, pin_nid, 986 codec->addr, pin_nid, dev_entry, !!(res & AC_UNSOL_RES_IA),
972 !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV)); 987 !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV));
973 988
974 pin_idx = pin_nid_to_pin_index(spec, pin_nid); 989 pin_idx = pin_nid_to_pin_index(spec, pin_nid);
@@ -1329,6 +1344,7 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1329 eld_changed = true; 1344 eld_changed = true;
1330 } 1345 }
1331 if (update_eld) { 1346 if (update_eld) {
1347 bool old_eld_valid = pin_eld->eld_valid;
1332 pin_eld->eld_valid = eld->eld_valid; 1348 pin_eld->eld_valid = eld->eld_valid;
1333 eld_changed = pin_eld->eld_size != eld->eld_size || 1349 eld_changed = pin_eld->eld_size != eld->eld_size ||
1334 memcmp(pin_eld->eld_buffer, eld->eld_buffer, 1350 memcmp(pin_eld->eld_buffer, eld->eld_buffer,
@@ -1338,6 +1354,18 @@ static void hdmi_present_sense(struct hdmi_spec_per_pin *per_pin, int repoll)
1338 eld->eld_size); 1354 eld->eld_size);
1339 pin_eld->eld_size = eld->eld_size; 1355 pin_eld->eld_size = eld->eld_size;
1340 pin_eld->info = eld->info; 1356 pin_eld->info = eld->info;
1357
1358 /* Haswell-specific workaround: re-setup when the transcoder is
1359 * changed during the stream playback
1360 */
1361 if (codec->vendor_id == 0x80862807 &&
1362 eld->eld_valid && !old_eld_valid && per_pin->setup) {
1363 snd_hda_codec_write(codec, pin_nid, 0,
1364 AC_VERB_SET_AMP_GAIN_MUTE,
1365 AMP_OUT_UNMUTE);
1366 hdmi_setup_audio_infoframe(codec, per_pin,
1367 per_pin->non_pcm);
1368 }
1341 } 1369 }
1342 mutex_unlock(&pin_eld->lock); 1370 mutex_unlock(&pin_eld->lock);
1343 1371
@@ -1510,14 +1538,17 @@ static int generic_hdmi_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
1510 hda_nid_t cvt_nid = hinfo->nid; 1538 hda_nid_t cvt_nid = hinfo->nid;
1511 struct hdmi_spec *spec = codec->spec; 1539 struct hdmi_spec *spec = codec->spec;
1512 int pin_idx = hinfo_to_pin_index(spec, hinfo); 1540 int pin_idx = hinfo_to_pin_index(spec, hinfo);
1513 hda_nid_t pin_nid = get_pin(spec, pin_idx)->pin_nid; 1541 struct hdmi_spec_per_pin *per_pin = get_pin(spec, pin_idx);
1542 hda_nid_t pin_nid = per_pin->pin_nid;
1514 bool non_pcm; 1543 bool non_pcm;
1515 1544
1516 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid); 1545 non_pcm = check_non_pcm_per_cvt(codec, cvt_nid);
1546 per_pin->channels = substream->runtime->channels;
1547 per_pin->setup = true;
1517 1548
1518 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels); 1549 hdmi_set_channel_count(codec, cvt_nid, substream->runtime->channels);
1519 1550
1520 hdmi_setup_audio_infoframe(codec, pin_idx, non_pcm, substream); 1551 hdmi_setup_audio_infoframe(codec, per_pin, non_pcm);
1521 1552
1522 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format); 1553 return hdmi_setup_stream(codec, cvt_nid, pin_nid, stream_tag, format);
1523} 1554}
@@ -1557,6 +1588,9 @@ static int hdmi_pcm_close(struct hda_pcm_stream *hinfo,
1557 snd_hda_spdif_ctls_unassign(codec, pin_idx); 1588 snd_hda_spdif_ctls_unassign(codec, pin_idx);
1558 per_pin->chmap_set = false; 1589 per_pin->chmap_set = false;
1559 memset(per_pin->chmap, 0, sizeof(per_pin->chmap)); 1590 memset(per_pin->chmap, 0, sizeof(per_pin->chmap));
1591
1592 per_pin->setup = false;
1593 per_pin->channels = 0;
1560 } 1594 }
1561 1595
1562 return 0; 1596 return 0;
@@ -1692,8 +1726,7 @@ static int hdmi_chmap_ctl_put(struct snd_kcontrol *kcontrol,
1692 per_pin->chmap_set = true; 1726 per_pin->chmap_set = true;
1693 memcpy(per_pin->chmap, chmap, sizeof(chmap)); 1727 memcpy(per_pin->chmap, chmap, sizeof(chmap));
1694 if (prepared) 1728 if (prepared)
1695 hdmi_setup_audio_infoframe(codec, pin_idx, per_pin->non_pcm, 1729 hdmi_setup_audio_infoframe(codec, per_pin, per_pin->non_pcm);
1696 substream);
1697 1730
1698 return 0; 1731 return 0;
1699} 1732}
@@ -1992,8 +2025,10 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1992 return -EINVAL; 2025 return -EINVAL;
1993 } 2026 }
1994 codec->patch_ops = generic_hdmi_patch_ops; 2027 codec->patch_ops = generic_hdmi_patch_ops;
1995 if (codec->vendor_id == 0x80862807) 2028 if (codec->vendor_id == 0x80862807) {
1996 codec->patch_ops.set_power_state = haswell_set_power_state; 2029 codec->patch_ops.set_power_state = haswell_set_power_state;
2030 codec->dp_mst = true;
2031 }
1997 2032
1998 generic_hdmi_init_per_pins(codec); 2033 generic_hdmi_init_per_pins(codec);
1999 2034
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 389db4c2801b..9e9378cde8fa 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -282,6 +282,7 @@ static void alc_eapd_shutup(struct hda_codec *codec)
282{ 282{
283 alc_auto_setup_eapd(codec, false); 283 alc_auto_setup_eapd(codec, false);
284 msleep(200); 284 msleep(200);
285 snd_hda_shutup_pins(codec);
285} 286}
286 287
287/* generic EAPD initialization */ 288/* generic EAPD initialization */
@@ -826,7 +827,8 @@ static inline void alc_shutup(struct hda_codec *codec)
826 827
827 if (spec && spec->shutup) 828 if (spec && spec->shutup)
828 spec->shutup(codec); 829 spec->shutup(codec);
829 snd_hda_shutup_pins(codec); 830 else
831 snd_hda_shutup_pins(codec);
830} 832}
831 833
832#define alc_free snd_hda_gen_free 834#define alc_free snd_hda_gen_free
@@ -1853,8 +1855,10 @@ static void alc882_fixup_no_primary_hp(struct hda_codec *codec,
1853 const struct hda_fixup *fix, int action) 1855 const struct hda_fixup *fix, int action)
1854{ 1856{
1855 struct alc_spec *spec = codec->spec; 1857 struct alc_spec *spec = codec->spec;
1856 if (action == HDA_FIXUP_ACT_PRE_PROBE) 1858 if (action == HDA_FIXUP_ACT_PRE_PROBE) {
1857 spec->gen.no_primary_hp = 1; 1859 spec->gen.no_primary_hp = 1;
1860 spec->gen.no_multi_io = 1;
1861 }
1858} 1862}
1859 1863
1860static const struct hda_fixup alc882_fixups[] = { 1864static const struct hda_fixup alc882_fixups[] = {
@@ -2533,6 +2537,7 @@ enum {
2533 ALC269_TYPE_ALC269VD, 2537 ALC269_TYPE_ALC269VD,
2534 ALC269_TYPE_ALC280, 2538 ALC269_TYPE_ALC280,
2535 ALC269_TYPE_ALC282, 2539 ALC269_TYPE_ALC282,
2540 ALC269_TYPE_ALC283,
2536 ALC269_TYPE_ALC284, 2541 ALC269_TYPE_ALC284,
2537 ALC269_TYPE_ALC286, 2542 ALC269_TYPE_ALC286,
2538}; 2543};
@@ -2558,6 +2563,7 @@ static int alc269_parse_auto_config(struct hda_codec *codec)
2558 case ALC269_TYPE_ALC269VB: 2563 case ALC269_TYPE_ALC269VB:
2559 case ALC269_TYPE_ALC269VD: 2564 case ALC269_TYPE_ALC269VD:
2560 case ALC269_TYPE_ALC282: 2565 case ALC269_TYPE_ALC282:
2566 case ALC269_TYPE_ALC283:
2561 case ALC269_TYPE_ALC286: 2567 case ALC269_TYPE_ALC286:
2562 ssids = alc269_ssids; 2568 ssids = alc269_ssids;
2563 break; 2569 break;
@@ -2583,15 +2589,81 @@ static void alc269_shutup(struct hda_codec *codec)
2583{ 2589{
2584 struct alc_spec *spec = codec->spec; 2590 struct alc_spec *spec = codec->spec;
2585 2591
2586 if (spec->codec_variant != ALC269_TYPE_ALC269VB)
2587 return;
2588
2589 if (spec->codec_variant == ALC269_TYPE_ALC269VB) 2592 if (spec->codec_variant == ALC269_TYPE_ALC269VB)
2590 alc269vb_toggle_power_output(codec, 0); 2593 alc269vb_toggle_power_output(codec, 0);
2591 if (spec->codec_variant == ALC269_TYPE_ALC269VB && 2594 if (spec->codec_variant == ALC269_TYPE_ALC269VB &&
2592 (alc_get_coef0(codec) & 0x00ff) == 0x018) { 2595 (alc_get_coef0(codec) & 0x00ff) == 0x018) {
2593 msleep(150); 2596 msleep(150);
2594 } 2597 }
2598 snd_hda_shutup_pins(codec);
2599}
2600
2601static void alc283_init(struct hda_codec *codec)
2602{
2603 struct alc_spec *spec = codec->spec;
2604 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2605 bool hp_pin_sense;
2606 int val;
2607
2608 if (!hp_pin)
2609 return;
2610 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2611
2612 /* Index 0x43 Direct Drive HP AMP LPM Control 1 */
2613 /* Headphone capless set to high power mode */
2614 alc_write_coef_idx(codec, 0x43, 0x9004);
2615
2616 snd_hda_codec_write(codec, hp_pin, 0,
2617 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2618
2619 if (hp_pin_sense)
2620 msleep(85);
2621
2622 snd_hda_codec_write(codec, hp_pin, 0,
2623 AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT);
2624
2625 if (hp_pin_sense)
2626 msleep(85);
2627 /* Index 0x46 Combo jack auto switch control 2 */
2628 /* 3k pull low control for Headset jack. */
2629 val = alc_read_coef_idx(codec, 0x46);
2630 alc_write_coef_idx(codec, 0x46, val & ~(3 << 12));
2631 /* Headphone capless set to normal mode */
2632 alc_write_coef_idx(codec, 0x43, 0x9614);
2633}
2634
2635static void alc283_shutup(struct hda_codec *codec)
2636{
2637 struct alc_spec *spec = codec->spec;
2638 hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0];
2639 bool hp_pin_sense;
2640 int val;
2641
2642 if (!hp_pin) {
2643 alc269_shutup(codec);
2644 return;
2645 }
2646
2647 hp_pin_sense = snd_hda_jack_detect(codec, hp_pin);
2648
2649 alc_write_coef_idx(codec, 0x43, 0x9004);
2650
2651 snd_hda_codec_write(codec, hp_pin, 0,
2652 AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE);
2653
2654 if (hp_pin_sense)
2655 msleep(85);
2656
2657 snd_hda_codec_write(codec, hp_pin, 0,
2658 AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0);
2659
2660 val = alc_read_coef_idx(codec, 0x46);
2661 alc_write_coef_idx(codec, 0x46, val | (3 << 12));
2662
2663 if (hp_pin_sense)
2664 msleep(85);
2665 snd_hda_shutup_pins(codec);
2666 alc_write_coef_idx(codec, 0x43, 0x9614);
2595} 2667}
2596 2668
2597static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, 2669static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg,
@@ -2722,6 +2794,7 @@ static int alc269_resume(struct hda_codec *codec)
2722 hda_call_check_power_status(codec, 0x01); 2794 hda_call_check_power_status(codec, 0x01);
2723 if (spec->has_alc5505_dsp) 2795 if (spec->has_alc5505_dsp)
2724 alc5505_dsp_resume(codec); 2796 alc5505_dsp_resume(codec);
2797
2725 return 0; 2798 return 0;
2726} 2799}
2727#endif /* CONFIG_PM */ 2800#endif /* CONFIG_PM */
@@ -3261,6 +3334,28 @@ static void alc_fixup_headset_mode_alc668(struct hda_codec *codec,
3261 alc_fixup_headset_mode(codec, fix, action); 3334 alc_fixup_headset_mode(codec, fix, action);
3262} 3335}
3263 3336
3337/* Returns the nid of the external mic input pin, or 0 if it cannot be found. */
3338static int find_ext_mic_pin(struct hda_codec *codec)
3339{
3340 struct alc_spec *spec = codec->spec;
3341 struct auto_pin_cfg *cfg = &spec->gen.autocfg;
3342 hda_nid_t nid;
3343 unsigned int defcfg;
3344 int i;
3345
3346 for (i = 0; i < cfg->num_inputs; i++) {
3347 if (cfg->inputs[i].type != AUTO_PIN_MIC)
3348 continue;
3349 nid = cfg->inputs[i].pin;
3350 defcfg = snd_hda_codec_get_pincfg(codec, nid);
3351 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
3352 continue;
3353 return nid;
3354 }
3355
3356 return 0;
3357}
3358
3264static void alc271_hp_gate_mic_jack(struct hda_codec *codec, 3359static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
3265 const struct hda_fixup *fix, 3360 const struct hda_fixup *fix,
3266 int action) 3361 int action)
@@ -3268,11 +3363,12 @@ static void alc271_hp_gate_mic_jack(struct hda_codec *codec,
3268 struct alc_spec *spec = codec->spec; 3363 struct alc_spec *spec = codec->spec;
3269 3364
3270 if (action == HDA_FIXUP_ACT_PROBE) { 3365 if (action == HDA_FIXUP_ACT_PROBE) {
3271 if (snd_BUG_ON(!spec->gen.am_entry[1].pin || 3366 int mic_pin = find_ext_mic_pin(codec);
3272 !spec->gen.autocfg.hp_pins[0])) 3367 int hp_pin = spec->gen.autocfg.hp_pins[0];
3368
3369 if (snd_BUG_ON(!mic_pin || !hp_pin))
3273 return; 3370 return;
3274 snd_hda_jack_set_gating_jack(codec, spec->gen.am_entry[1].pin, 3371 snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin);
3275 spec->gen.autocfg.hp_pins[0]);
3276 } 3372 }
3277} 3373}
3278 3374
@@ -3308,6 +3404,45 @@ static void alc269_fixup_limit_int_mic_boost(struct hda_codec *codec,
3308 } 3404 }
3309} 3405}
3310 3406
3407static void alc283_hp_automute_hook(struct hda_codec *codec,
3408 struct hda_jack_tbl *jack)
3409{
3410 struct alc_spec *spec = codec->spec;
3411 int vref;
3412
3413 msleep(200);
3414 snd_hda_gen_hp_automute(codec, jack);
3415
3416 vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0;
3417
3418 msleep(600);
3419 snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL,
3420 vref);
3421}
3422
3423static void alc283_chromebook_caps(struct hda_codec *codec)
3424{
3425 snd_hda_override_wcaps(codec, 0x03, 0);
3426}
3427
3428static void alc283_fixup_chromebook(struct hda_codec *codec,
3429 const struct hda_fixup *fix, int action)
3430{
3431 struct alc_spec *spec = codec->spec;
3432 int val;
3433
3434 switch (action) {
3435 case HDA_FIXUP_ACT_PRE_PROBE:
3436 alc283_chromebook_caps(codec);
3437 spec->gen.hp_automute_hook = alc283_hp_automute_hook;
3438 /* MIC2-VREF control */
3439 /* Set to manual mode */
3440 val = alc_read_coef_idx(codec, 0x06);
3441 alc_write_coef_idx(codec, 0x06, val & ~0x000c);
3442 break;
3443 }
3444}
3445
3311enum { 3446enum {
3312 ALC269_FIXUP_SONY_VAIO, 3447 ALC269_FIXUP_SONY_VAIO,
3313 ALC275_FIXUP_SONY_VAIO_GPIO2, 3448 ALC275_FIXUP_SONY_VAIO_GPIO2,
@@ -3344,6 +3479,7 @@ enum {
3344 ALC269_FIXUP_ACER_AC700, 3479 ALC269_FIXUP_ACER_AC700,
3345 ALC269_FIXUP_LIMIT_INT_MIC_BOOST, 3480 ALC269_FIXUP_LIMIT_INT_MIC_BOOST,
3346 ALC269VB_FIXUP_ORDISSIMO_EVE2, 3481 ALC269VB_FIXUP_ORDISSIMO_EVE2,
3482 ALC283_FIXUP_CHROME_BOOK,
3347}; 3483};
3348 3484
3349static const struct hda_fixup alc269_fixups[] = { 3485static const struct hda_fixup alc269_fixups[] = {
@@ -3595,11 +3731,20 @@ static const struct hda_fixup alc269_fixups[] = {
3595 { } 3731 { }
3596 }, 3732 },
3597 }, 3733 },
3734 [ALC283_FIXUP_CHROME_BOOK] = {
3735 .type = HDA_FIXUP_FUNC,
3736 .v.func = alc283_fixup_chromebook,
3737 },
3598}; 3738};
3599 3739
3600static const struct snd_pci_quirk alc269_fixup_tbl[] = { 3740static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3601 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), 3741 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC),
3602 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), 3742 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC),
3743 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
3744 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
3745 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
3746 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
3747 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
3603 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3748 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3604 SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3749 SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
3605 SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), 3750 SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
@@ -3637,6 +3782,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3637 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), 3782 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED),
3638 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3783 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
3639 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3784 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1),
3785 SND_PCI_QUIRK(0x103c, 0x21ed, "HP Falco Chromebook", ALC283_FIXUP_CHROME_BOOK),
3640 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), 3786 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED),
3641 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3787 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3642 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3788 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
@@ -3655,11 +3801,6 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3655 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 3801 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
3656 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 3802 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ),
3657 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 3803 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO),
3658 SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z),
3659 SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700),
3660 SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK),
3661 SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK),
3662 SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC),
3663 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), 3804 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK),
3664 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 3805 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE),
3665 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), 3806 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE),
@@ -3670,8 +3811,16 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
3670 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), 3811 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK),
3671 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), 3812 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK),
3672 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), 3813 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK),
3673 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
3674 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), 3814 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK),
3815 SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK),
3816 SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3817 SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3818 SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3819 SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3820 SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3821 SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3822 SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3823 SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST),
3675 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), 3824 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K),
3676 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 3825 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD),
3677 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ 3826 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */
@@ -3840,11 +3989,15 @@ static int patch_alc269(struct hda_codec *codec)
3840 case 0x10ec0290: 3989 case 0x10ec0290:
3841 spec->codec_variant = ALC269_TYPE_ALC280; 3990 spec->codec_variant = ALC269_TYPE_ALC280;
3842 break; 3991 break;
3843 case 0x10ec0233:
3844 case 0x10ec0282: 3992 case 0x10ec0282:
3845 case 0x10ec0283:
3846 spec->codec_variant = ALC269_TYPE_ALC282; 3993 spec->codec_variant = ALC269_TYPE_ALC282;
3847 break; 3994 break;
3995 case 0x10ec0233:
3996 case 0x10ec0283:
3997 spec->codec_variant = ALC269_TYPE_ALC283;
3998 spec->shutup = alc283_shutup;
3999 spec->init_hook = alc283_init;
4000 break;
3848 case 0x10ec0284: 4001 case 0x10ec0284:
3849 case 0x10ec0292: 4002 case 0x10ec0292:
3850 spec->codec_variant = ALC269_TYPE_ALC284; 4003 spec->codec_variant = ALC269_TYPE_ALC284;
@@ -3872,7 +4025,8 @@ static int patch_alc269(struct hda_codec *codec)
3872 codec->patch_ops.suspend = alc269_suspend; 4025 codec->patch_ops.suspend = alc269_suspend;
3873 codec->patch_ops.resume = alc269_resume; 4026 codec->patch_ops.resume = alc269_resume;
3874#endif 4027#endif
3875 spec->shutup = alc269_shutup; 4028 if (!spec->shutup)
4029 spec->shutup = alc269_shutup;
3876 4030
3877 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4031 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE);
3878 4032
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index 6d1924c19abf..fba0cef1c47f 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -158,6 +158,7 @@ enum {
158 STAC_D965_VERBS, 158 STAC_D965_VERBS,
159 STAC_DELL_3ST, 159 STAC_DELL_3ST,
160 STAC_DELL_BIOS, 160 STAC_DELL_BIOS,
161 STAC_DELL_BIOS_AMIC,
161 STAC_DELL_BIOS_SPDIF, 162 STAC_DELL_BIOS_SPDIF,
162 STAC_927X_DELL_DMIC, 163 STAC_927X_DELL_DMIC,
163 STAC_927X_VOLKNOB, 164 STAC_927X_VOLKNOB,
@@ -3231,8 +3232,6 @@ static const struct hda_fixup stac927x_fixups[] = {
3231 [STAC_DELL_BIOS] = { 3232 [STAC_DELL_BIOS] = {
3232 .type = HDA_FIXUP_PINS, 3233 .type = HDA_FIXUP_PINS,
3233 .v.pins = (const struct hda_pintbl[]) { 3234 .v.pins = (const struct hda_pintbl[]) {
3234 /* configure the analog microphone on some laptops */
3235 { 0x0c, 0x90a79130 },
3236 /* correct the front output jack as a hp out */ 3235 /* correct the front output jack as a hp out */
3237 { 0x0f, 0x0221101f }, 3236 { 0x0f, 0x0221101f },
3238 /* correct the front input jack as a mic */ 3237 /* correct the front input jack as a mic */
@@ -3242,6 +3241,16 @@ static const struct hda_fixup stac927x_fixups[] = {
3242 .chained = true, 3241 .chained = true,
3243 .chain_id = STAC_927X_DELL_DMIC, 3242 .chain_id = STAC_927X_DELL_DMIC,
3244 }, 3243 },
3244 [STAC_DELL_BIOS_AMIC] = {
3245 .type = HDA_FIXUP_PINS,
3246 .v.pins = (const struct hda_pintbl[]) {
3247 /* configure the analog microphone on some laptops */
3248 { 0x0c, 0x90a79130 },
3249 {}
3250 },
3251 .chained = true,
3252 .chain_id = STAC_DELL_BIOS,
3253 },
3245 [STAC_DELL_BIOS_SPDIF] = { 3254 [STAC_DELL_BIOS_SPDIF] = {
3246 .type = HDA_FIXUP_PINS, 3255 .type = HDA_FIXUP_PINS,
3247 .v.pins = (const struct hda_pintbl[]) { 3256 .v.pins = (const struct hda_pintbl[]) {
@@ -3270,6 +3279,7 @@ static const struct hda_model_fixup stac927x_models[] = {
3270 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" }, 3279 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" },
3271 { .id = STAC_DELL_3ST, .name = "dell-3stack" }, 3280 { .id = STAC_DELL_3ST, .name = "dell-3stack" },
3272 { .id = STAC_DELL_BIOS, .name = "dell-bios" }, 3281 { .id = STAC_DELL_BIOS, .name = "dell-bios" },
3282 { .id = STAC_DELL_BIOS_AMIC, .name = "dell-bios-amic" },
3273 { .id = STAC_927X_VOLKNOB, .name = "volknob" }, 3283 { .id = STAC_927X_VOLKNOB, .name = "volknob" },
3274 {} 3284 {}
3275}; 3285};
diff --git a/sound/pci/hda/patch_via.c b/sound/pci/hda/patch_via.c
index e2481baddc70..0bc20ef5687a 100644
--- a/sound/pci/hda/patch_via.c
+++ b/sound/pci/hda/patch_via.c
@@ -207,9 +207,9 @@ static void vt1708_stop_hp_work(struct hda_codec *codec)
207 return; 207 return;
208 if (spec->hp_work_active) { 208 if (spec->hp_work_active) {
209 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 1); 209 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 1);
210 codec->jackpoll_interval = 0;
210 cancel_delayed_work_sync(&codec->jackpoll_work); 211 cancel_delayed_work_sync(&codec->jackpoll_work);
211 spec->hp_work_active = false; 212 spec->hp_work_active = false;
212 codec->jackpoll_interval = 0;
213 } 213 }
214} 214}
215 215
diff --git a/sound/pci/rme96.c b/sound/pci/rme96.c
index 2a8ad9d1a2ae..bb9ebc5543d7 100644
--- a/sound/pci/rme96.c
+++ b/sound/pci/rme96.c
@@ -28,6 +28,7 @@
28#include <linux/interrupt.h> 28#include <linux/interrupt.h>
29#include <linux/pci.h> 29#include <linux/pci.h>
30#include <linux/module.h> 30#include <linux/module.h>
31#include <linux/vmalloc.h>
31 32
32#include <sound/core.h> 33#include <sound/core.h>
33#include <sound/info.h> 34#include <sound/info.h>
@@ -198,6 +199,31 @@ MODULE_PARM_DESC(enable, "Enable RME Digi96 soundcard.");
198#define RME96_AD1852_VOL_BITS 14 199#define RME96_AD1852_VOL_BITS 14
199#define RME96_AD1855_VOL_BITS 10 200#define RME96_AD1855_VOL_BITS 10
200 201
202/* Defines for snd_rme96_trigger */
203#define RME96_TB_START_PLAYBACK 1
204#define RME96_TB_START_CAPTURE 2
205#define RME96_TB_STOP_PLAYBACK 4
206#define RME96_TB_STOP_CAPTURE 8
207#define RME96_TB_RESET_PLAYPOS 16
208#define RME96_TB_RESET_CAPTUREPOS 32
209#define RME96_TB_CLEAR_PLAYBACK_IRQ 64
210#define RME96_TB_CLEAR_CAPTURE_IRQ 128
211#define RME96_RESUME_PLAYBACK (RME96_TB_START_PLAYBACK)
212#define RME96_RESUME_CAPTURE (RME96_TB_START_CAPTURE)
213#define RME96_RESUME_BOTH (RME96_RESUME_PLAYBACK \
214 | RME96_RESUME_CAPTURE)
215#define RME96_START_PLAYBACK (RME96_TB_START_PLAYBACK \
216 | RME96_TB_RESET_PLAYPOS)
217#define RME96_START_CAPTURE (RME96_TB_START_CAPTURE \
218 | RME96_TB_RESET_CAPTUREPOS)
219#define RME96_START_BOTH (RME96_START_PLAYBACK \
220 | RME96_START_CAPTURE)
221#define RME96_STOP_PLAYBACK (RME96_TB_STOP_PLAYBACK \
222 | RME96_TB_CLEAR_PLAYBACK_IRQ)
223#define RME96_STOP_CAPTURE (RME96_TB_STOP_CAPTURE \
224 | RME96_TB_CLEAR_CAPTURE_IRQ)
225#define RME96_STOP_BOTH (RME96_STOP_PLAYBACK \
226 | RME96_STOP_CAPTURE)
201 227
202struct rme96 { 228struct rme96 {
203 spinlock_t lock; 229 spinlock_t lock;
@@ -214,6 +240,13 @@ struct rme96 {
214 240
215 u8 rev; /* card revision number */ 241 u8 rev; /* card revision number */
216 242
243#ifdef CONFIG_PM
244 u32 playback_pointer;
245 u32 capture_pointer;
246 void *playback_suspend_buffer;
247 void *capture_suspend_buffer;
248#endif
249
217 struct snd_pcm_substream *playback_substream; 250 struct snd_pcm_substream *playback_substream;
218 struct snd_pcm_substream *capture_substream; 251 struct snd_pcm_substream *capture_substream;
219 252
@@ -344,6 +377,8 @@ static struct snd_pcm_hardware snd_rme96_playback_spdif_info =
344{ 377{
345 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 378 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
346 SNDRV_PCM_INFO_MMAP_VALID | 379 SNDRV_PCM_INFO_MMAP_VALID |
380 SNDRV_PCM_INFO_SYNC_START |
381 SNDRV_PCM_INFO_RESUME |
347 SNDRV_PCM_INFO_INTERLEAVED | 382 SNDRV_PCM_INFO_INTERLEAVED |
348 SNDRV_PCM_INFO_PAUSE), 383 SNDRV_PCM_INFO_PAUSE),
349 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 384 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -373,6 +408,8 @@ static struct snd_pcm_hardware snd_rme96_capture_spdif_info =
373{ 408{
374 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 409 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
375 SNDRV_PCM_INFO_MMAP_VALID | 410 SNDRV_PCM_INFO_MMAP_VALID |
411 SNDRV_PCM_INFO_SYNC_START |
412 SNDRV_PCM_INFO_RESUME |
376 SNDRV_PCM_INFO_INTERLEAVED | 413 SNDRV_PCM_INFO_INTERLEAVED |
377 SNDRV_PCM_INFO_PAUSE), 414 SNDRV_PCM_INFO_PAUSE),
378 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 415 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -402,6 +439,8 @@ static struct snd_pcm_hardware snd_rme96_playback_adat_info =
402{ 439{
403 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 440 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
404 SNDRV_PCM_INFO_MMAP_VALID | 441 SNDRV_PCM_INFO_MMAP_VALID |
442 SNDRV_PCM_INFO_SYNC_START |
443 SNDRV_PCM_INFO_RESUME |
405 SNDRV_PCM_INFO_INTERLEAVED | 444 SNDRV_PCM_INFO_INTERLEAVED |
406 SNDRV_PCM_INFO_PAUSE), 445 SNDRV_PCM_INFO_PAUSE),
407 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 446 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -427,6 +466,8 @@ static struct snd_pcm_hardware snd_rme96_capture_adat_info =
427{ 466{
428 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 467 .info = (SNDRV_PCM_INFO_MMAP_IOMEM |
429 SNDRV_PCM_INFO_MMAP_VALID | 468 SNDRV_PCM_INFO_MMAP_VALID |
469 SNDRV_PCM_INFO_SYNC_START |
470 SNDRV_PCM_INFO_RESUME |
430 SNDRV_PCM_INFO_INTERLEAVED | 471 SNDRV_PCM_INFO_INTERLEAVED |
431 SNDRV_PCM_INFO_PAUSE), 472 SNDRV_PCM_INFO_PAUSE),
432 .formats = (SNDRV_PCM_FMTBIT_S16_LE | 473 .formats = (SNDRV_PCM_FMTBIT_S16_LE |
@@ -1045,54 +1086,35 @@ snd_rme96_capture_hw_params(struct snd_pcm_substream *substream,
1045} 1086}
1046 1087
1047static void 1088static void
1048snd_rme96_playback_start(struct rme96 *rme96, 1089snd_rme96_trigger(struct rme96 *rme96,
1049 int from_pause) 1090 int op)
1050{ 1091{
1051 if (!from_pause) { 1092 if (op & RME96_TB_RESET_PLAYPOS)
1052 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS); 1093 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
1053 } 1094 if (op & RME96_TB_RESET_CAPTUREPOS)
1054
1055 rme96->wcreg |= RME96_WCR_START;
1056 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1057}
1058
1059static void
1060snd_rme96_capture_start(struct rme96 *rme96,
1061 int from_pause)
1062{
1063 if (!from_pause) {
1064 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS); 1095 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
1065 } 1096 if (op & RME96_TB_CLEAR_PLAYBACK_IRQ) {
1066 1097 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1067 rme96->wcreg |= RME96_WCR_START_2; 1098 if (rme96->rcreg & RME96_RCR_IRQ)
1099 writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ);
1100 }
1101 if (op & RME96_TB_CLEAR_CAPTURE_IRQ) {
1102 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1103 if (rme96->rcreg & RME96_RCR_IRQ_2)
1104 writel(0, rme96->iobase + RME96_IO_CONFIRM_REC_IRQ);
1105 }
1106 if (op & RME96_TB_START_PLAYBACK)
1107 rme96->wcreg |= RME96_WCR_START;
1108 if (op & RME96_TB_STOP_PLAYBACK)
1109 rme96->wcreg &= ~RME96_WCR_START;
1110 if (op & RME96_TB_START_CAPTURE)
1111 rme96->wcreg |= RME96_WCR_START_2;
1112 if (op & RME96_TB_STOP_CAPTURE)
1113 rme96->wcreg &= ~RME96_WCR_START_2;
1068 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); 1114 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1069} 1115}
1070 1116
1071static void
1072snd_rme96_playback_stop(struct rme96 *rme96)
1073{
1074 /*
1075 * Check if there is an unconfirmed IRQ, if so confirm it, or else
1076 * the hardware will not stop generating interrupts
1077 */
1078 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1079 if (rme96->rcreg & RME96_RCR_IRQ) {
1080 writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ);
1081 }
1082 rme96->wcreg &= ~RME96_WCR_START;
1083 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1084}
1085 1117
1086static void
1087snd_rme96_capture_stop(struct rme96 *rme96)
1088{
1089 rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER);
1090 if (rme96->rcreg & RME96_RCR_IRQ_2) {
1091 writel(0, rme96->iobase + RME96_IO_CONFIRM_REC_IRQ);
1092 }
1093 rme96->wcreg &= ~RME96_WCR_START_2;
1094 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER);
1095}
1096 1118
1097static irqreturn_t 1119static irqreturn_t
1098snd_rme96_interrupt(int irq, 1120snd_rme96_interrupt(int irq,
@@ -1155,6 +1177,7 @@ snd_rme96_playback_spdif_open(struct snd_pcm_substream *substream)
1155 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1177 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1156 struct snd_pcm_runtime *runtime = substream->runtime; 1178 struct snd_pcm_runtime *runtime = substream->runtime;
1157 1179
1180 snd_pcm_set_sync(substream);
1158 spin_lock_irq(&rme96->lock); 1181 spin_lock_irq(&rme96->lock);
1159 if (rme96->playback_substream != NULL) { 1182 if (rme96->playback_substream != NULL) {
1160 spin_unlock_irq(&rme96->lock); 1183 spin_unlock_irq(&rme96->lock);
@@ -1191,6 +1214,7 @@ snd_rme96_capture_spdif_open(struct snd_pcm_substream *substream)
1191 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1214 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1192 struct snd_pcm_runtime *runtime = substream->runtime; 1215 struct snd_pcm_runtime *runtime = substream->runtime;
1193 1216
1217 snd_pcm_set_sync(substream);
1194 runtime->hw = snd_rme96_capture_spdif_info; 1218 runtime->hw = snd_rme96_capture_spdif_info;
1195 if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && 1219 if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG &&
1196 (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) 1220 (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0)
@@ -1222,6 +1246,7 @@ snd_rme96_playback_adat_open(struct snd_pcm_substream *substream)
1222 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1246 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1223 struct snd_pcm_runtime *runtime = substream->runtime; 1247 struct snd_pcm_runtime *runtime = substream->runtime;
1224 1248
1249 snd_pcm_set_sync(substream);
1225 spin_lock_irq(&rme96->lock); 1250 spin_lock_irq(&rme96->lock);
1226 if (rme96->playback_substream != NULL) { 1251 if (rme96->playback_substream != NULL) {
1227 spin_unlock_irq(&rme96->lock); 1252 spin_unlock_irq(&rme96->lock);
@@ -1253,6 +1278,7 @@ snd_rme96_capture_adat_open(struct snd_pcm_substream *substream)
1253 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1278 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1254 struct snd_pcm_runtime *runtime = substream->runtime; 1279 struct snd_pcm_runtime *runtime = substream->runtime;
1255 1280
1281 snd_pcm_set_sync(substream);
1256 runtime->hw = snd_rme96_capture_adat_info; 1282 runtime->hw = snd_rme96_capture_adat_info;
1257 if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) { 1283 if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) {
1258 /* makes no sense to use analog input. Note that analog 1284 /* makes no sense to use analog input. Note that analog
@@ -1288,7 +1314,7 @@ snd_rme96_playback_close(struct snd_pcm_substream *substream)
1288 1314
1289 spin_lock_irq(&rme96->lock); 1315 spin_lock_irq(&rme96->lock);
1290 if (RME96_ISPLAYING(rme96)) { 1316 if (RME96_ISPLAYING(rme96)) {
1291 snd_rme96_playback_stop(rme96); 1317 snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK);
1292 } 1318 }
1293 rme96->playback_substream = NULL; 1319 rme96->playback_substream = NULL;
1294 rme96->playback_periodsize = 0; 1320 rme96->playback_periodsize = 0;
@@ -1309,7 +1335,7 @@ snd_rme96_capture_close(struct snd_pcm_substream *substream)
1309 1335
1310 spin_lock_irq(&rme96->lock); 1336 spin_lock_irq(&rme96->lock);
1311 if (RME96_ISRECORDING(rme96)) { 1337 if (RME96_ISRECORDING(rme96)) {
1312 snd_rme96_capture_stop(rme96); 1338 snd_rme96_trigger(rme96, RME96_STOP_CAPTURE);
1313 } 1339 }
1314 rme96->capture_substream = NULL; 1340 rme96->capture_substream = NULL;
1315 rme96->capture_periodsize = 0; 1341 rme96->capture_periodsize = 0;
@@ -1324,7 +1350,7 @@ snd_rme96_playback_prepare(struct snd_pcm_substream *substream)
1324 1350
1325 spin_lock_irq(&rme96->lock); 1351 spin_lock_irq(&rme96->lock);
1326 if (RME96_ISPLAYING(rme96)) { 1352 if (RME96_ISPLAYING(rme96)) {
1327 snd_rme96_playback_stop(rme96); 1353 snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK);
1328 } 1354 }
1329 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS); 1355 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS);
1330 spin_unlock_irq(&rme96->lock); 1356 spin_unlock_irq(&rme96->lock);
@@ -1338,7 +1364,7 @@ snd_rme96_capture_prepare(struct snd_pcm_substream *substream)
1338 1364
1339 spin_lock_irq(&rme96->lock); 1365 spin_lock_irq(&rme96->lock);
1340 if (RME96_ISRECORDING(rme96)) { 1366 if (RME96_ISRECORDING(rme96)) {
1341 snd_rme96_capture_stop(rme96); 1367 snd_rme96_trigger(rme96, RME96_STOP_CAPTURE);
1342 } 1368 }
1343 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS); 1369 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS);
1344 spin_unlock_irq(&rme96->lock); 1370 spin_unlock_irq(&rme96->lock);
@@ -1350,41 +1376,55 @@ snd_rme96_playback_trigger(struct snd_pcm_substream *substream,
1350 int cmd) 1376 int cmd)
1351{ 1377{
1352 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1378 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1379 struct snd_pcm_substream *s;
1380 bool sync;
1381
1382 snd_pcm_group_for_each_entry(s, substream) {
1383 if (snd_pcm_substream_chip(s) == rme96)
1384 snd_pcm_trigger_done(s, substream);
1385 }
1386
1387 sync = (rme96->playback_substream && rme96->capture_substream) &&
1388 (rme96->playback_substream->group ==
1389 rme96->capture_substream->group);
1353 1390
1354 switch (cmd) { 1391 switch (cmd) {
1355 case SNDRV_PCM_TRIGGER_START: 1392 case SNDRV_PCM_TRIGGER_START:
1356 if (!RME96_ISPLAYING(rme96)) { 1393 if (!RME96_ISPLAYING(rme96)) {
1357 if (substream != rme96->playback_substream) { 1394 if (substream != rme96->playback_substream)
1358 return -EBUSY; 1395 return -EBUSY;
1359 } 1396 snd_rme96_trigger(rme96, sync ? RME96_START_BOTH
1360 snd_rme96_playback_start(rme96, 0); 1397 : RME96_START_PLAYBACK);
1361 } 1398 }
1362 break; 1399 break;
1363 1400
1401 case SNDRV_PCM_TRIGGER_SUSPEND:
1364 case SNDRV_PCM_TRIGGER_STOP: 1402 case SNDRV_PCM_TRIGGER_STOP:
1365 if (RME96_ISPLAYING(rme96)) { 1403 if (RME96_ISPLAYING(rme96)) {
1366 if (substream != rme96->playback_substream) { 1404 if (substream != rme96->playback_substream)
1367 return -EBUSY; 1405 return -EBUSY;
1368 } 1406 snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH
1369 snd_rme96_playback_stop(rme96); 1407 : RME96_STOP_PLAYBACK);
1370 } 1408 }
1371 break; 1409 break;
1372 1410
1373 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1411 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1374 if (RME96_ISPLAYING(rme96)) { 1412 if (RME96_ISPLAYING(rme96))
1375 snd_rme96_playback_stop(rme96); 1413 snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH
1376 } 1414 : RME96_STOP_PLAYBACK);
1377 break; 1415 break;
1378 1416
1417 case SNDRV_PCM_TRIGGER_RESUME:
1379 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1418 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1380 if (!RME96_ISPLAYING(rme96)) { 1419 if (!RME96_ISPLAYING(rme96))
1381 snd_rme96_playback_start(rme96, 1); 1420 snd_rme96_trigger(rme96, sync ? RME96_RESUME_BOTH
1382 } 1421 : RME96_RESUME_PLAYBACK);
1383 break; 1422 break;
1384 1423
1385 default: 1424 default:
1386 return -EINVAL; 1425 return -EINVAL;
1387 } 1426 }
1427
1388 return 0; 1428 return 0;
1389} 1429}
1390 1430
@@ -1393,38 +1433,51 @@ snd_rme96_capture_trigger(struct snd_pcm_substream *substream,
1393 int cmd) 1433 int cmd)
1394{ 1434{
1395 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1435 struct rme96 *rme96 = snd_pcm_substream_chip(substream);
1436 struct snd_pcm_substream *s;
1437 bool sync;
1438
1439 snd_pcm_group_for_each_entry(s, substream) {
1440 if (snd_pcm_substream_chip(s) == rme96)
1441 snd_pcm_trigger_done(s, substream);
1442 }
1443
1444 sync = (rme96->playback_substream && rme96->capture_substream) &&
1445 (rme96->playback_substream->group ==
1446 rme96->capture_substream->group);
1396 1447
1397 switch (cmd) { 1448 switch (cmd) {
1398 case SNDRV_PCM_TRIGGER_START: 1449 case SNDRV_PCM_TRIGGER_START:
1399 if (!RME96_ISRECORDING(rme96)) { 1450 if (!RME96_ISRECORDING(rme96)) {
1400 if (substream != rme96->capture_substream) { 1451 if (substream != rme96->capture_substream)
1401 return -EBUSY; 1452 return -EBUSY;
1402 } 1453 snd_rme96_trigger(rme96, sync ? RME96_START_BOTH
1403 snd_rme96_capture_start(rme96, 0); 1454 : RME96_START_CAPTURE);
1404 } 1455 }
1405 break; 1456 break;
1406 1457
1458 case SNDRV_PCM_TRIGGER_SUSPEND:
1407 case SNDRV_PCM_TRIGGER_STOP: 1459 case SNDRV_PCM_TRIGGER_STOP:
1408 if (RME96_ISRECORDING(rme96)) { 1460 if (RME96_ISRECORDING(rme96)) {
1409 if (substream != rme96->capture_substream) { 1461 if (substream != rme96->capture_substream)
1410 return -EBUSY; 1462 return -EBUSY;
1411 } 1463 snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH
1412 snd_rme96_capture_stop(rme96); 1464 : RME96_STOP_CAPTURE);
1413 } 1465 }
1414 break; 1466 break;
1415 1467
1416 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1468 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
1417 if (RME96_ISRECORDING(rme96)) { 1469 if (RME96_ISRECORDING(rme96))
1418 snd_rme96_capture_stop(rme96); 1470 snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH
1419 } 1471 : RME96_STOP_CAPTURE);
1420 break; 1472 break;
1421 1473
1474 case SNDRV_PCM_TRIGGER_RESUME:
1422 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1475 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
1423 if (!RME96_ISRECORDING(rme96)) { 1476 if (!RME96_ISRECORDING(rme96))
1424 snd_rme96_capture_start(rme96, 1); 1477 snd_rme96_trigger(rme96, sync ? RME96_RESUME_BOTH
1425 } 1478 : RME96_RESUME_CAPTURE);
1426 break; 1479 break;
1427 1480
1428 default: 1481 default:
1429 return -EINVAL; 1482 return -EINVAL;
1430 } 1483 }
@@ -1505,8 +1558,7 @@ snd_rme96_free(void *private_data)
1505 return; 1558 return;
1506 } 1559 }
1507 if (rme96->irq >= 0) { 1560 if (rme96->irq >= 0) {
1508 snd_rme96_playback_stop(rme96); 1561 snd_rme96_trigger(rme96, RME96_STOP_BOTH);
1509 snd_rme96_capture_stop(rme96);
1510 rme96->areg &= ~RME96_AR_DAC_EN; 1562 rme96->areg &= ~RME96_AR_DAC_EN;
1511 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); 1563 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
1512 free_irq(rme96->irq, (void *)rme96); 1564 free_irq(rme96->irq, (void *)rme96);
@@ -1520,6 +1572,10 @@ snd_rme96_free(void *private_data)
1520 pci_release_regions(rme96->pci); 1572 pci_release_regions(rme96->pci);
1521 rme96->port = 0; 1573 rme96->port = 0;
1522 } 1574 }
1575#ifdef CONFIG_PM
1576 vfree(rme96->playback_suspend_buffer);
1577 vfree(rme96->capture_suspend_buffer);
1578#endif
1523 pci_disable_device(rme96->pci); 1579 pci_disable_device(rme96->pci);
1524} 1580}
1525 1581
@@ -1606,8 +1662,7 @@ snd_rme96_create(struct rme96 *rme96)
1606 rme96->capture_periodsize = 0; 1662 rme96->capture_periodsize = 0;
1607 1663
1608 /* make sure playback/capture is stopped, if by some reason active */ 1664 /* make sure playback/capture is stopped, if by some reason active */
1609 snd_rme96_playback_stop(rme96); 1665 snd_rme96_trigger(rme96, RME96_STOP_BOTH);
1610 snd_rme96_capture_stop(rme96);
1611 1666
1612 /* set default values in registers */ 1667 /* set default values in registers */
1613 rme96->wcreg = 1668 rme96->wcreg =
@@ -2319,6 +2374,87 @@ snd_rme96_create_switches(struct snd_card *card,
2319 * Card initialisation 2374 * Card initialisation
2320 */ 2375 */
2321 2376
2377#ifdef CONFIG_PM
2378
2379static int
2380snd_rme96_suspend(struct pci_dev *pci,
2381 pm_message_t state)
2382{
2383 struct snd_card *card = pci_get_drvdata(pci);
2384 struct rme96 *rme96 = card->private_data;
2385
2386 snd_power_change_state(card, SNDRV_CTL_POWER_D3hot);
2387 snd_pcm_suspend(rme96->playback_substream);
2388 snd_pcm_suspend(rme96->capture_substream);
2389
2390 /* save capture & playback pointers */
2391 rme96->playback_pointer = readl(rme96->iobase + RME96_IO_GET_PLAY_POS)
2392 & RME96_RCR_AUDIO_ADDR_MASK;
2393 rme96->capture_pointer = readl(rme96->iobase + RME96_IO_GET_REC_POS)
2394 & RME96_RCR_AUDIO_ADDR_MASK;
2395
2396 /* save playback and capture buffers */
2397 memcpy_fromio(rme96->playback_suspend_buffer,
2398 rme96->iobase + RME96_IO_PLAY_BUFFER, RME96_BUFFER_SIZE);
2399 memcpy_fromio(rme96->capture_suspend_buffer,
2400 rme96->iobase + RME96_IO_REC_BUFFER, RME96_BUFFER_SIZE);
2401
2402 /* disable the DAC */
2403 rme96->areg &= ~RME96_AR_DAC_EN;
2404 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
2405
2406 pci_disable_device(pci);
2407 pci_save_state(pci);
2408
2409 return 0;
2410}
2411
2412static int
2413snd_rme96_resume(struct pci_dev *pci)
2414{
2415 struct snd_card *card = pci_get_drvdata(pci);
2416 struct rme96 *rme96 = card->private_data;
2417
2418 pci_restore_state(pci);
2419 if (pci_enable_device(pci) < 0) {
2420 printk(KERN_ERR "rme96: pci_enable_device failed, disabling device\n");
2421 snd_card_disconnect(card);
2422 return -EIO;
2423 }
2424
2425 /* reset playback and record buffer pointers */
2426 writel(0, rme96->iobase + RME96_IO_SET_PLAY_POS
2427 + rme96->playback_pointer);
2428 writel(0, rme96->iobase + RME96_IO_SET_REC_POS
2429 + rme96->capture_pointer);
2430
2431 /* restore playback and capture buffers */
2432 memcpy_toio(rme96->iobase + RME96_IO_PLAY_BUFFER,
2433 rme96->playback_suspend_buffer, RME96_BUFFER_SIZE);
2434 memcpy_toio(rme96->iobase + RME96_IO_REC_BUFFER,
2435 rme96->capture_suspend_buffer, RME96_BUFFER_SIZE);
2436
2437 /* reset the ADC */
2438 writel(rme96->areg | RME96_AR_PD2,
2439 rme96->iobase + RME96_IO_ADDITIONAL_REG);
2440 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
2441
2442 /* reset and enable DAC, restore analog volume */
2443 snd_rme96_reset_dac(rme96);
2444 rme96->areg |= RME96_AR_DAC_EN;
2445 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG);
2446 if (RME96_HAS_ANALOG_OUT(rme96)) {
2447 usleep_range(3000, 10000);
2448 snd_rme96_apply_dac_volume(rme96);
2449 }
2450
2451 snd_power_change_state(card, SNDRV_CTL_POWER_D0);
2452
2453 return 0;
2454}
2455
2456#endif
2457
2322static void snd_rme96_card_free(struct snd_card *card) 2458static void snd_rme96_card_free(struct snd_card *card)
2323{ 2459{
2324 snd_rme96_free(card->private_data); 2460 snd_rme96_free(card->private_data);
@@ -2355,6 +2491,23 @@ snd_rme96_probe(struct pci_dev *pci,
2355 return err; 2491 return err;
2356 } 2492 }
2357 2493
2494#ifdef CONFIG_PM
2495 rme96->playback_suspend_buffer = vmalloc(RME96_BUFFER_SIZE);
2496 if (!rme96->playback_suspend_buffer) {
2497 snd_printk(KERN_ERR
2498 "Failed to allocate playback suspend buffer!\n");
2499 snd_card_free(card);
2500 return -ENOMEM;
2501 }
2502 rme96->capture_suspend_buffer = vmalloc(RME96_BUFFER_SIZE);
2503 if (!rme96->capture_suspend_buffer) {
2504 snd_printk(KERN_ERR
2505 "Failed to allocate capture suspend buffer!\n");
2506 snd_card_free(card);
2507 return -ENOMEM;
2508 }
2509#endif
2510
2358 strcpy(card->driver, "Digi96"); 2511 strcpy(card->driver, "Digi96");
2359 switch (rme96->pci->device) { 2512 switch (rme96->pci->device) {
2360 case PCI_DEVICE_ID_RME_DIGI96: 2513 case PCI_DEVICE_ID_RME_DIGI96:
@@ -2397,6 +2550,10 @@ static struct pci_driver rme96_driver = {
2397 .id_table = snd_rme96_ids, 2550 .id_table = snd_rme96_ids,
2398 .probe = snd_rme96_probe, 2551 .probe = snd_rme96_probe,
2399 .remove = snd_rme96_remove, 2552 .remove = snd_rme96_remove,
2553#ifdef CONFIG_PM
2554 .suspend = snd_rme96_suspend,
2555 .resume = snd_rme96_resume,
2556#endif
2400}; 2557};
2401 2558
2402module_pci_driver(rme96_driver); 2559module_pci_driver(rme96_driver);
diff --git a/sound/pci/rme9652/hdspm.c b/sound/pci/rme9652/hdspm.c
index bd501931ee23..3cde55b753e2 100644
--- a/sound/pci/rme9652/hdspm.c
+++ b/sound/pci/rme9652/hdspm.c
@@ -38,6 +38,97 @@
38 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 38 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
39 * 39 *
40 */ 40 */
41
42/* ************* Register Documentation *******************************************************
43 *
44 * Work in progress! Documentation is based on the code in this file.
45 *
46 * --------- HDSPM_controlRegister ---------
47 * :7654.3210:7654.3210:7654.3210:7654.3210: bit number per byte
48 * :||||.||||:||||.||||:||||.||||:||||.||||:
49 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number
50 * :1098.7654:3210.9876:5432.1098:7654.3210: 0..31
51 * :||||.||||:||||.||||:||||.||||:||||.||||:
52 * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
53 * : . : . : . : x . : HDSPM_AudioInterruptEnable \_ setting both bits
54 * : . : . : . : . x: HDSPM_Start / enables audio IO
55 * : . : . : . : x. : HDSPM_ClockModeMaster - 1: Master, 0: Slave
56 * : . : . : . : .210 : HDSPM_LatencyMask - 3 Bit value for latency
57 * : . : . : . : . : 0:64, 1:128, 2:256, 3:512,
58 * : . : . : . : . : 4:1024, 5:2048, 6:4096, 7:8192
59 * :x . : . : . x:xx . : HDSPM_FrequencyMask
60 * : . : . : . :10 . : HDSPM_Frequency1|HDSPM_Frequency0: 1=32K,2=44.1K,3=48K,0=??
61 * : . : . : . x: . : <MADI> HDSPM_DoubleSpeed
62 * :x . : . : . : . : <MADI> HDSPM_QuadSpeed
63 * : . 3 : . 10: 2 . : . : HDSPM_SyncRefMask :
64 * : . : . x: . : . : HDSPM_SyncRef0
65 * : . : . x : . : . : HDSPM_SyncRef1
66 * : . : . : x . : . : <AES32> HDSPM_SyncRef2
67 * : . x : . : . : . : <AES32> HDSPM_SyncRef3
68 * : . : . 10: . : . : <MADI> sync ref: 0:WC, 1:Madi, 2:TCO, 3:SyncIn
69 * : . 3 : . 10: 2 . : . : <AES32> 0:WC, 1:AES1 ... 8:AES8, 9: TCO, 10:SyncIn?
70 * : . x : . : . : . : <MADIe> HDSPe_FLOAT_FORMAT
71 * : . : . : x . : . : <MADI> HDSPM_InputSelect0 : 0=optical,1=coax
72 * : . : . :x . : . : <MADI> HDSPM_InputSelect1
73 * : . : .x : . : . : <MADI> HDSPM_clr_tms
74 * : . : . : . x : . : <MADI> HDSPM_TX_64ch
75 * : . : . : . x : . : <AES32> HDSPM_Emphasis
76 * : . : . : .x : . : <MADI> HDSPM_AutoInp
77 * : . : . x : . : . : <MADI> HDSPM_SMUX
78 * : . : .x : . : . : <MADI> HDSPM_clr_tms
79 * : . : x. : . : . : <MADI> HDSPM_taxi_reset
80 * : . x: . : . : . : <MADI> HDSPM_LineOut
81 * : . x: . : . : . : <AES32> ??????????????????
82 * : . : x. : . : . : <AES32> HDSPM_WCK48
83 * : . : . : .x : . : <AES32> HDSPM_Dolby
84 * : . : x . : . : . : HDSPM_Midi0InterruptEnable
85 * : . :x . : . : . : HDSPM_Midi1InterruptEnable
86 * : . : x . : . : . : HDSPM_Midi2InterruptEnable
87 * : . x : . : . : . : <MADI> HDSPM_Midi3InterruptEnable
88 * : . x : . : . : . : <AES32> HDSPM_DS_DoubleWire
89 * : .x : . : . : . : <AES32> HDSPM_QS_DoubleWire
90 * : x. : . : . : . : <AES32> HDSPM_QS_QuadWire
91 * : . : . : . x : . : <AES32> HDSPM_Professional
92 * : x . : . : . : . : HDSPM_wclk_sel
93 * : . : . : . : . :
94 * :7654.3210:7654.3210:7654.3210:7654.3210: bit number per byte
95 * :||||.||||:||||.||||:||||.||||:||||.||||:
96 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number
97 * :1098.7654:3210.9876:5432.1098:7654.3210: 0..31
98 * :||||.||||:||||.||||:||||.||||:||||.||||:
99 * :8421.8421:8421.8421:8421.8421:8421.8421:hex digit
100 *
101 *
102 *
103 * AIO / RayDAT only
104 *
105 * ------------ HDSPM_WR_SETTINGS ----------
106 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number per byte
107 * :1098.7654:3210.9876:5432.1098:7654.3210:
108 * :||||.||||:||||.||||:||||.||||:||||.||||: bit number
109 * :7654.3210:7654.3210:7654.3210:7654.3210: 0..31
110 * :||||.||||:||||.||||:||||.||||:||||.||||:
111 * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
112 * : . : . : . : . x: HDSPM_c0Master 1: Master, 0: Slave
113 * : . : . : . : . x : HDSPM_c0_SyncRef0
114 * : . : . : . : . x : HDSPM_c0_SyncRef1
115 * : . : . : . : .x : HDSPM_c0_SyncRef2
116 * : . : . : . : x. : HDSPM_c0_SyncRef3
117 * : . : . : . : 3.210 : HDSPM_c0_SyncRefMask:
118 * : . : . : . : . : RayDat: 0:WC, 1:AES, 2:SPDIF, 3..6: ADAT1..4,
119 * : . : . : . : . : 9:TCO, 10:SyncIn
120 * : . : . : . : . : AIO: 0:WC, 1:AES, 2: SPDIF, 3: ATAT,
121 * : . : . : . : . : 9:TCO, 10:SyncIn
122 * : . : . : . : . :
123 * : . : . : . : . :
124 * :3322.2222:2222.1111:1111.1100:0000.0000: bit number per byte
125 * :1098.7654:3210.9876:5432.1098:7654.3210:
126 * :||||.||||:||||.||||:||||.||||:||||.||||: bit number
127 * :7654.3210:7654.3210:7654.3210:7654.3210: 0..31
128 * :||||.||||:||||.||||:||||.||||:||||.||||:
129 * :8421.8421:8421.8421:8421.8421:8421.8421: hex digit
130 *
131 */
41#include <linux/init.h> 132#include <linux/init.h>
42#include <linux/delay.h> 133#include <linux/delay.h>
43#include <linux/interrupt.h> 134#include <linux/interrupt.h>
@@ -95,7 +186,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
95#define HDSPM_controlRegister 64 186#define HDSPM_controlRegister 64
96#define HDSPM_interruptConfirmation 96 187#define HDSPM_interruptConfirmation 96
97#define HDSPM_control2Reg 256 /* not in specs ???????? */ 188#define HDSPM_control2Reg 256 /* not in specs ???????? */
98#define HDSPM_freqReg 256 /* for AES32 */ 189#define HDSPM_freqReg 256 /* for setting arbitrary clock values (DDS feature) */
99#define HDSPM_midiDataOut0 352 /* just believe in old code */ 190#define HDSPM_midiDataOut0 352 /* just believe in old code */
100#define HDSPM_midiDataOut1 356 191#define HDSPM_midiDataOut1 356
101#define HDSPM_eeprom_wr 384 /* for AES32 */ 192#define HDSPM_eeprom_wr 384 /* for AES32 */
@@ -258,6 +349,25 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
258 349
259#define HDSPM_wclk_sel (1<<30) 350#define HDSPM_wclk_sel (1<<30)
260 351
352/* additional control register bits for AIO*/
353#define HDSPM_c0_Wck48 0x20 /* also RayDAT */
354#define HDSPM_c0_Input0 0x1000
355#define HDSPM_c0_Input1 0x2000
356#define HDSPM_c0_Spdif_Opt 0x4000
357#define HDSPM_c0_Pro 0x8000
358#define HDSPM_c0_clr_tms 0x10000
359#define HDSPM_c0_AEB1 0x20000
360#define HDSPM_c0_AEB2 0x40000
361#define HDSPM_c0_LineOut 0x80000
362#define HDSPM_c0_AD_GAIN0 0x100000
363#define HDSPM_c0_AD_GAIN1 0x200000
364#define HDSPM_c0_DA_GAIN0 0x400000
365#define HDSPM_c0_DA_GAIN1 0x800000
366#define HDSPM_c0_PH_GAIN0 0x1000000
367#define HDSPM_c0_PH_GAIN1 0x2000000
368#define HDSPM_c0_Sym6db 0x4000000
369
370
261/* --- bit helper defines */ 371/* --- bit helper defines */
262#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2) 372#define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2)
263#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|\ 373#define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|\
@@ -341,11 +451,11 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
341#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */ 451#define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */
342#define HDSPM_madiSync (1<<18) /* MADI is in sync */ 452#define HDSPM_madiSync (1<<18) /* MADI is in sync */
343 453
344#define HDSPM_tcoLock 0x00000020 /* Optional TCO locked status FOR HDSPe MADI! */ 454#define HDSPM_tcoLockMadi 0x00000020 /* Optional TCO locked status for HDSPe MADI*/
345#define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status */ 455#define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status for HDSPe MADI and AES32!*/
346 456
347#define HDSPM_syncInLock 0x00010000 /* Sync In lock status FOR HDSPe MADI! */ 457#define HDSPM_syncInLock 0x00010000 /* Sync In lock status for HDSPe MADI! */
348#define HDSPM_syncInSync 0x00020000 /* Sync In sync status FOR HDSPe MADI! */ 458#define HDSPM_syncInSync 0x00020000 /* Sync In sync status for HDSPe MADI! */
349 459
350#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */ 460#define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */
351 /* since 64byte accurate, last 6 bits are not used */ 461 /* since 64byte accurate, last 6 bits are not used */
@@ -363,7 +473,7 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
363 * Interrupt 473 * Interrupt
364 */ 474 */
365#define HDSPM_tco_detect 0x08000000 475#define HDSPM_tco_detect 0x08000000
366#define HDSPM_tco_lock 0x20000000 476#define HDSPM_tcoLockAes 0x20000000 /* Optional TCO locked status for HDSPe AES */
367 477
368#define HDSPM_s2_tco_detect 0x00000040 478#define HDSPM_s2_tco_detect 0x00000040
369#define HDSPM_s2_AEBO_D 0x00000080 479#define HDSPM_s2_AEBO_D 0x00000080
@@ -461,7 +571,9 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
461#define HDSPM_AES32_AUTOSYNC_FROM_AES6 6 571#define HDSPM_AES32_AUTOSYNC_FROM_AES6 6
462#define HDSPM_AES32_AUTOSYNC_FROM_AES7 7 572#define HDSPM_AES32_AUTOSYNC_FROM_AES7 7
463#define HDSPM_AES32_AUTOSYNC_FROM_AES8 8 573#define HDSPM_AES32_AUTOSYNC_FROM_AES8 8
464#define HDSPM_AES32_AUTOSYNC_FROM_NONE 9 574#define HDSPM_AES32_AUTOSYNC_FROM_TCO 9
575#define HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN 10
576#define HDSPM_AES32_AUTOSYNC_FROM_NONE 11
465 577
466/* status2 */ 578/* status2 */
467/* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */ 579/* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */
@@ -537,36 +649,39 @@ MODULE_SUPPORTED_DEVICE("{{RME HDSPM-MADI}}");
537/* names for speed modes */ 649/* names for speed modes */
538static char *hdspm_speed_names[] = { "single", "double", "quad" }; 650static char *hdspm_speed_names[] = { "single", "double", "quad" };
539 651
540static char *texts_autosync_aes_tco[] = { "Word Clock", 652static const char *const texts_autosync_aes_tco[] = { "Word Clock",
541 "AES1", "AES2", "AES3", "AES4", 653 "AES1", "AES2", "AES3", "AES4",
542 "AES5", "AES6", "AES7", "AES8", 654 "AES5", "AES6", "AES7", "AES8",
543 "TCO" }; 655 "TCO", "Sync In"
544static char *texts_autosync_aes[] = { "Word Clock", 656};
657static const char *const texts_autosync_aes[] = { "Word Clock",
545 "AES1", "AES2", "AES3", "AES4", 658 "AES1", "AES2", "AES3", "AES4",
546 "AES5", "AES6", "AES7", "AES8" }; 659 "AES5", "AES6", "AES7", "AES8",
547static char *texts_autosync_madi_tco[] = { "Word Clock", 660 "Sync In"
661};
662static const char *const texts_autosync_madi_tco[] = { "Word Clock",
548 "MADI", "TCO", "Sync In" }; 663 "MADI", "TCO", "Sync In" };
549static char *texts_autosync_madi[] = { "Word Clock", 664static const char *const texts_autosync_madi[] = { "Word Clock",
550 "MADI", "Sync In" }; 665 "MADI", "Sync In" };
551 666
552static char *texts_autosync_raydat_tco[] = { 667static const char *const texts_autosync_raydat_tco[] = {
553 "Word Clock", 668 "Word Clock",
554 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4", 669 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
555 "AES", "SPDIF", "TCO", "Sync In" 670 "AES", "SPDIF", "TCO", "Sync In"
556}; 671};
557static char *texts_autosync_raydat[] = { 672static const char *const texts_autosync_raydat[] = {
558 "Word Clock", 673 "Word Clock",
559 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4", 674 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4",
560 "AES", "SPDIF", "Sync In" 675 "AES", "SPDIF", "Sync In"
561}; 676};
562static char *texts_autosync_aio_tco[] = { 677static const char *const texts_autosync_aio_tco[] = {
563 "Word Clock", 678 "Word Clock",
564 "ADAT", "AES", "SPDIF", "TCO", "Sync In" 679 "ADAT", "AES", "SPDIF", "TCO", "Sync In"
565}; 680};
566static char *texts_autosync_aio[] = { "Word Clock", 681static const char *const texts_autosync_aio[] = { "Word Clock",
567 "ADAT", "AES", "SPDIF", "Sync In" }; 682 "ADAT", "AES", "SPDIF", "Sync In" };
568 683
569static char *texts_freq[] = { 684static const char *const texts_freq[] = {
570 "No Lock", 685 "No Lock",
571 "32 kHz", 686 "32 kHz",
572 "44.1 kHz", 687 "44.1 kHz",
@@ -629,7 +744,8 @@ static char *texts_ports_aio_in_ss[] = {
629 "AES.L", "AES.R", 744 "AES.L", "AES.R",
630 "SPDIF.L", "SPDIF.R", 745 "SPDIF.L", "SPDIF.R",
631 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6", 746 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
632 "ADAT.7", "ADAT.8" 747 "ADAT.7", "ADAT.8",
748 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
633}; 749};
634 750
635static char *texts_ports_aio_out_ss[] = { 751static char *texts_ports_aio_out_ss[] = {
@@ -638,14 +754,16 @@ static char *texts_ports_aio_out_ss[] = {
638 "SPDIF.L", "SPDIF.R", 754 "SPDIF.L", "SPDIF.R",
639 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6", 755 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6",
640 "ADAT.7", "ADAT.8", 756 "ADAT.7", "ADAT.8",
641 "Phone.L", "Phone.R" 757 "Phone.L", "Phone.R",
758 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
642}; 759};
643 760
644static char *texts_ports_aio_in_ds[] = { 761static char *texts_ports_aio_in_ds[] = {
645 "Analogue.L", "Analogue.R", 762 "Analogue.L", "Analogue.R",
646 "AES.L", "AES.R", 763 "AES.L", "AES.R",
647 "SPDIF.L", "SPDIF.R", 764 "SPDIF.L", "SPDIF.R",
648 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4" 765 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
766 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
649}; 767};
650 768
651static char *texts_ports_aio_out_ds[] = { 769static char *texts_ports_aio_out_ds[] = {
@@ -653,14 +771,16 @@ static char *texts_ports_aio_out_ds[] = {
653 "AES.L", "AES.R", 771 "AES.L", "AES.R",
654 "SPDIF.L", "SPDIF.R", 772 "SPDIF.L", "SPDIF.R",
655 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", 773 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
656 "Phone.L", "Phone.R" 774 "Phone.L", "Phone.R",
775 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
657}; 776};
658 777
659static char *texts_ports_aio_in_qs[] = { 778static char *texts_ports_aio_in_qs[] = {
660 "Analogue.L", "Analogue.R", 779 "Analogue.L", "Analogue.R",
661 "AES.L", "AES.R", 780 "AES.L", "AES.R",
662 "SPDIF.L", "SPDIF.R", 781 "SPDIF.L", "SPDIF.R",
663 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4" 782 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
783 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
664}; 784};
665 785
666static char *texts_ports_aio_out_qs[] = { 786static char *texts_ports_aio_out_qs[] = {
@@ -668,7 +788,8 @@ static char *texts_ports_aio_out_qs[] = {
668 "AES.L", "AES.R", 788 "AES.L", "AES.R",
669 "SPDIF.L", "SPDIF.R", 789 "SPDIF.L", "SPDIF.R",
670 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", 790 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4",
671 "Phone.L", "Phone.R" 791 "Phone.L", "Phone.R",
792 "AEB.1", "AEB.2", "AEB.3", "AEB.4"
672}; 793};
673 794
674static char *texts_ports_aes32[] = { 795static char *texts_ports_aes32[] = {
@@ -745,8 +866,8 @@ static char channel_map_aio_in_ss[HDSPM_MAX_CHANNELS] = {
745 8, 9, /* aes in, */ 866 8, 9, /* aes in, */
746 10, 11, /* spdif in */ 867 10, 11, /* spdif in */
747 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT in */ 868 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT in */
748 -1, -1, 869 2, 3, 4, 5, /* AEB */
749 -1, -1, -1, -1, -1, -1, -1, -1, 870 -1, -1, -1, -1, -1, -1,
750 -1, -1, -1, -1, -1, -1, -1, -1, 871 -1, -1, -1, -1, -1, -1, -1, -1,
751 -1, -1, -1, -1, -1, -1, -1, -1, 872 -1, -1, -1, -1, -1, -1, -1, -1,
752 -1, -1, -1, -1, -1, -1, -1, -1, 873 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -760,7 +881,8 @@ static char channel_map_aio_out_ss[HDSPM_MAX_CHANNELS] = {
760 10, 11, /* spdif out */ 881 10, 11, /* spdif out */
761 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT out */ 882 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT out */
762 6, 7, /* phone out */ 883 6, 7, /* phone out */
763 -1, -1, -1, -1, -1, -1, -1, -1, 884 2, 3, 4, 5, /* AEB */
885 -1, -1, -1, -1,
764 -1, -1, -1, -1, -1, -1, -1, -1, 886 -1, -1, -1, -1, -1, -1, -1, -1,
765 -1, -1, -1, -1, -1, -1, -1, -1, 887 -1, -1, -1, -1, -1, -1, -1, -1,
766 -1, -1, -1, -1, -1, -1, -1, -1, 888 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -773,7 +895,8 @@ static char channel_map_aio_in_ds[HDSPM_MAX_CHANNELS] = {
773 8, 9, /* aes in */ 895 8, 9, /* aes in */
774 10, 11, /* spdif in */ 896 10, 11, /* spdif in */
775 12, 14, 16, 18, /* adat in */ 897 12, 14, 16, 18, /* adat in */
776 -1, -1, -1, -1, -1, -1, 898 2, 3, 4, 5, /* AEB */
899 -1, -1,
777 -1, -1, -1, -1, -1, -1, -1, -1, 900 -1, -1, -1, -1, -1, -1, -1, -1,
778 -1, -1, -1, -1, -1, -1, -1, -1, 901 -1, -1, -1, -1, -1, -1, -1, -1,
779 -1, -1, -1, -1, -1, -1, -1, -1, 902 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -788,7 +911,7 @@ static char channel_map_aio_out_ds[HDSPM_MAX_CHANNELS] = {
788 10, 11, /* spdif out */ 911 10, 11, /* spdif out */
789 12, 14, 16, 18, /* adat out */ 912 12, 14, 16, 18, /* adat out */
790 6, 7, /* phone out */ 913 6, 7, /* phone out */
791 -1, -1, -1, -1, 914 2, 3, 4, 5, /* AEB */
792 -1, -1, -1, -1, -1, -1, -1, -1, 915 -1, -1, -1, -1, -1, -1, -1, -1,
793 -1, -1, -1, -1, -1, -1, -1, -1, 916 -1, -1, -1, -1, -1, -1, -1, -1,
794 -1, -1, -1, -1, -1, -1, -1, -1, 917 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -802,7 +925,8 @@ static char channel_map_aio_in_qs[HDSPM_MAX_CHANNELS] = {
802 8, 9, /* aes in */ 925 8, 9, /* aes in */
803 10, 11, /* spdif in */ 926 10, 11, /* spdif in */
804 12, 16, /* adat in */ 927 12, 16, /* adat in */
805 -1, -1, -1, -1, -1, -1, -1, -1, 928 2, 3, 4, 5, /* AEB */
929 -1, -1, -1, -1,
806 -1, -1, -1, -1, -1, -1, -1, -1, 930 -1, -1, -1, -1, -1, -1, -1, -1,
807 -1, -1, -1, -1, -1, -1, -1, -1, 931 -1, -1, -1, -1, -1, -1, -1, -1,
808 -1, -1, -1, -1, -1, -1, -1, -1, 932 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -817,7 +941,8 @@ static char channel_map_aio_out_qs[HDSPM_MAX_CHANNELS] = {
817 10, 11, /* spdif out */ 941 10, 11, /* spdif out */
818 12, 16, /* adat out */ 942 12, 16, /* adat out */
819 6, 7, /* phone out */ 943 6, 7, /* phone out */
820 -1, -1, -1, -1, -1, -1, 944 2, 3, 4, 5, /* AEB */
945 -1, -1,
821 -1, -1, -1, -1, -1, -1, -1, -1, 946 -1, -1, -1, -1, -1, -1, -1, -1,
822 -1, -1, -1, -1, -1, -1, -1, -1, 947 -1, -1, -1, -1, -1, -1, -1, -1,
823 -1, -1, -1, -1, -1, -1, -1, -1, 948 -1, -1, -1, -1, -1, -1, -1, -1,
@@ -856,11 +981,11 @@ struct hdspm_midi {
856}; 981};
857 982
858struct hdspm_tco { 983struct hdspm_tco {
859 int input; 984 int input; /* 0: LTC, 1:Video, 2: WC*/
860 int framerate; 985 int framerate; /* 0=24, 1=25, 2=29.97, 3=29.97d, 4=30, 5=30d */
861 int wordclock; 986 int wordclock; /* 0=1:1, 1=44.1->48, 2=48->44.1 */
862 int samplerate; 987 int samplerate; /* 0=44.1, 1=48, 2= freq from app */
863 int pull; 988 int pull; /* 0=0, 1=+0.1%, 2=-0.1%, 3=+4%, 4=-4%*/
864 int term; /* 0 = off, 1 = on */ 989 int term; /* 0 = off, 1 = on */
865}; 990};
866 991
@@ -879,7 +1004,7 @@ struct hdspm {
879 1004
880 u32 control_register; /* cached value */ 1005 u32 control_register; /* cached value */
881 u32 control2_register; /* cached value */ 1006 u32 control2_register; /* cached value */
882 u32 settings_register; 1007 u32 settings_register; /* cached value for AIO / RayDat (sync reference, master/slave) */
883 1008
884 struct hdspm_midi midi[4]; 1009 struct hdspm_midi midi[4];
885 struct tasklet_struct midi_tasklet; 1010 struct tasklet_struct midi_tasklet;
@@ -941,7 +1066,7 @@ struct hdspm {
941 1066
942 struct hdspm_tco *tco; /* NULL if no TCO detected */ 1067 struct hdspm_tco *tco; /* NULL if no TCO detected */
943 1068
944 char **texts_autosync; 1069 const char *const *texts_autosync;
945 int texts_autosync_items; 1070 int texts_autosync_items;
946 1071
947 cycles_t last_interrupt; 1072 cycles_t last_interrupt;
@@ -976,12 +1101,24 @@ static inline void snd_hdspm_initialize_midi_flush(struct hdspm *hdspm);
976static inline int hdspm_get_pll_freq(struct hdspm *hdspm); 1101static inline int hdspm_get_pll_freq(struct hdspm *hdspm);
977static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm); 1102static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm);
978static int hdspm_autosync_ref(struct hdspm *hdspm); 1103static int hdspm_autosync_ref(struct hdspm *hdspm);
1104static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out);
979static int snd_hdspm_set_defaults(struct hdspm *hdspm); 1105static int snd_hdspm_set_defaults(struct hdspm *hdspm);
980static int hdspm_system_clock_mode(struct hdspm *hdspm); 1106static int hdspm_system_clock_mode(struct hdspm *hdspm);
981static void hdspm_set_sgbuf(struct hdspm *hdspm, 1107static void hdspm_set_sgbuf(struct hdspm *hdspm,
982 struct snd_pcm_substream *substream, 1108 struct snd_pcm_substream *substream,
983 unsigned int reg, int channels); 1109 unsigned int reg, int channels);
984 1110
1111static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx);
1112static int hdspm_wc_sync_check(struct hdspm *hdspm);
1113static int hdspm_tco_sync_check(struct hdspm *hdspm);
1114static int hdspm_sync_in_sync_check(struct hdspm *hdspm);
1115
1116static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index);
1117static int hdspm_get_tco_sample_rate(struct hdspm *hdspm);
1118static int hdspm_get_wc_sample_rate(struct hdspm *hdspm);
1119
1120
1121
985static inline int HDSPM_bit2freq(int n) 1122static inline int HDSPM_bit2freq(int n)
986{ 1123{
987 static const int bit2freq_tab[] = { 1124 static const int bit2freq_tab[] = {
@@ -992,6 +1129,12 @@ static inline int HDSPM_bit2freq(int n)
992 return bit2freq_tab[n]; 1129 return bit2freq_tab[n];
993} 1130}
994 1131
1132static bool hdspm_is_raydat_or_aio(struct hdspm *hdspm)
1133{
1134 return ((AIO == hdspm->io_type) || (RayDAT == hdspm->io_type));
1135}
1136
1137
995/* Write/read to/from HDSPM with Adresses in Bytes 1138/* Write/read to/from HDSPM with Adresses in Bytes
996 not words but only 32Bit writes are allowed */ 1139 not words but only 32Bit writes are allowed */
997 1140
@@ -1107,14 +1250,11 @@ static int hdspm_rate_multiplier(struct hdspm *hdspm, int rate)
1107 else if (hdspm->control_register & 1250 else if (hdspm->control_register &
1108 HDSPM_DoubleSpeed) 1251 HDSPM_DoubleSpeed)
1109 return rate * 2; 1252 return rate * 2;
1110 }; 1253 }
1111 return rate; 1254 return rate;
1112} 1255}
1113 1256
1114static int hdspm_tco_sync_check(struct hdspm *hdspm); 1257/* check for external sample rate, returns the sample rate in Hz*/
1115static int hdspm_sync_in_sync_check(struct hdspm *hdspm);
1116
1117/* check for external sample rate */
1118static int hdspm_external_sample_rate(struct hdspm *hdspm) 1258static int hdspm_external_sample_rate(struct hdspm *hdspm)
1119{ 1259{
1120 unsigned int status, status2, timecode; 1260 unsigned int status, status2, timecode;
@@ -1127,17 +1267,36 @@ static int hdspm_external_sample_rate(struct hdspm *hdspm)
1127 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister); 1267 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
1128 1268
1129 syncref = hdspm_autosync_ref(hdspm); 1269 syncref = hdspm_autosync_ref(hdspm);
1270 switch (syncref) {
1271 case HDSPM_AES32_AUTOSYNC_FROM_WORD:
1272 /* Check WC sync and get sample rate */
1273 if (hdspm_wc_sync_check(hdspm))
1274 return HDSPM_bit2freq(hdspm_get_wc_sample_rate(hdspm));
1275 break;
1130 1276
1131 if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD && 1277 case HDSPM_AES32_AUTOSYNC_FROM_AES1:
1132 status & HDSPM_AES32_wcLock) 1278 case HDSPM_AES32_AUTOSYNC_FROM_AES2:
1133 return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF); 1279 case HDSPM_AES32_AUTOSYNC_FROM_AES3:
1280 case HDSPM_AES32_AUTOSYNC_FROM_AES4:
1281 case HDSPM_AES32_AUTOSYNC_FROM_AES5:
1282 case HDSPM_AES32_AUTOSYNC_FROM_AES6:
1283 case HDSPM_AES32_AUTOSYNC_FROM_AES7:
1284 case HDSPM_AES32_AUTOSYNC_FROM_AES8:
1285 /* Check AES sync and get sample rate */
1286 if (hdspm_aes_sync_check(hdspm, syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))
1287 return HDSPM_bit2freq(hdspm_get_aes_sample_rate(hdspm,
1288 syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1));
1289 break;
1134 1290
1135 if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 && 1291
1136 syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 && 1292 case HDSPM_AES32_AUTOSYNC_FROM_TCO:
1137 status2 & (HDSPM_LockAES >> 1293 /* Check TCO sync and get sample rate */
1138 (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))) 1294 if (hdspm_tco_sync_check(hdspm))
1139 return HDSPM_bit2freq((timecode >> (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF); 1295 return HDSPM_bit2freq(hdspm_get_tco_sample_rate(hdspm));
1140 return 0; 1296 break;
1297 default:
1298 return 0;
1299 } /* end switch(syncref) */
1141 break; 1300 break;
1142 1301
1143 case MADIface: 1302 case MADIface:
@@ -2129,6 +2288,9 @@ static int hdspm_get_wc_sample_rate(struct hdspm *hdspm)
2129 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); 2288 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
2130 return (status >> 16) & 0xF; 2289 return (status >> 16) & 0xF;
2131 break; 2290 break;
2291 case AES32:
2292 status = hdspm_read(hdspm, HDSPM_statusRegister);
2293 return (status >> HDSPM_AES32_wcFreq_bit) & 0xF;
2132 default: 2294 default:
2133 break; 2295 break;
2134 } 2296 }
@@ -2152,6 +2314,9 @@ static int hdspm_get_tco_sample_rate(struct hdspm *hdspm)
2152 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); 2314 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1);
2153 return (status >> 20) & 0xF; 2315 return (status >> 20) & 0xF;
2154 break; 2316 break;
2317 case AES32:
2318 status = hdspm_read(hdspm, HDSPM_statusRegister);
2319 return (status >> 1) & 0xF;
2155 default: 2320 default:
2156 break; 2321 break;
2157 } 2322 }
@@ -2183,6 +2348,23 @@ static int hdspm_get_sync_in_sample_rate(struct hdspm *hdspm)
2183 return 0; 2348 return 0;
2184} 2349}
2185 2350
2351/**
2352 * Returns the AES sample rate class for the given card.
2353 **/
2354static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index)
2355{
2356 int timecode;
2357
2358 switch (hdspm->io_type) {
2359 case AES32:
2360 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister);
2361 return (timecode >> (4*index)) & 0xF;
2362 break;
2363 default:
2364 break;
2365 }
2366 return 0;
2367}
2186 2368
2187/** 2369/**
2188 * Returns the sample rate class for input source <idx> for 2370 * Returns the sample rate class for input source <idx> for
@@ -2196,15 +2378,23 @@ static int hdspm_get_s1_sample_rate(struct hdspm *hdspm, unsigned int idx)
2196} 2378}
2197 2379
2198#define ENUMERATED_CTL_INFO(info, texts) \ 2380#define ENUMERATED_CTL_INFO(info, texts) \
2199{ \ 2381 snd_ctl_enum_info(info, 1, ARRAY_SIZE(texts), texts)
2200 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; \ 2382
2201 uinfo->count = 1; \
2202 uinfo->value.enumerated.items = ARRAY_SIZE(texts); \
2203 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) \
2204 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; \
2205 strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); \
2206}
2207 2383
2384/* Helper function to query the external sample rate and return the
2385 * corresponding enum to be returned to userspace.
2386 */
2387static int hdspm_external_rate_to_enum(struct hdspm *hdspm)
2388{
2389 int rate = hdspm_external_sample_rate(hdspm);
2390 int i, selected_rate = 0;
2391 for (i = 1; i < 10; i++)
2392 if (HDSPM_bit2freq(i) == rate) {
2393 selected_rate = i;
2394 break;
2395 }
2396 return selected_rate;
2397}
2208 2398
2209 2399
2210#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ 2400#define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \
@@ -2270,7 +2460,7 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
2270 default: 2460 default:
2271 ucontrol->value.enumerated.item[0] = 2461 ucontrol->value.enumerated.item[0] =
2272 hdspm_get_s1_sample_rate(hdspm, 2462 hdspm_get_s1_sample_rate(hdspm,
2273 ucontrol->id.index-1); 2463 kcontrol->private_value-1);
2274 } 2464 }
2275 break; 2465 break;
2276 2466
@@ -2289,28 +2479,24 @@ static int snd_hdspm_get_autosync_sample_rate(struct snd_kcontrol *kcontrol,
2289 ucontrol->value.enumerated.item[0] = 2479 ucontrol->value.enumerated.item[0] =
2290 hdspm_get_sync_in_sample_rate(hdspm); 2480 hdspm_get_sync_in_sample_rate(hdspm);
2291 break; 2481 break;
2482 case 11: /* External Rate */
2483 ucontrol->value.enumerated.item[0] =
2484 hdspm_external_rate_to_enum(hdspm);
2485 break;
2292 default: /* AES1 to AES8 */ 2486 default: /* AES1 to AES8 */
2293 ucontrol->value.enumerated.item[0] = 2487 ucontrol->value.enumerated.item[0] =
2294 hdspm_get_s1_sample_rate(hdspm, 2488 hdspm_get_aes_sample_rate(hdspm,
2295 kcontrol->private_value-1); 2489 kcontrol->private_value -
2490 HDSPM_AES32_AUTOSYNC_FROM_AES1);
2296 break; 2491 break;
2297 } 2492 }
2298 break; 2493 break;
2299 2494
2300 case MADI: 2495 case MADI:
2301 case MADIface: 2496 case MADIface:
2302 { 2497 ucontrol->value.enumerated.item[0] =
2303 int rate = hdspm_external_sample_rate(hdspm); 2498 hdspm_external_rate_to_enum(hdspm);
2304 int i, selected_rate = 0;
2305 for (i = 1; i < 10; i++)
2306 if (HDSPM_bit2freq(i) == rate) {
2307 selected_rate = i;
2308 break;
2309 }
2310 ucontrol->value.enumerated.item[0] = selected_rate;
2311 }
2312 break; 2499 break;
2313
2314 default: 2500 default:
2315 break; 2501 break;
2316 } 2502 }
@@ -2359,33 +2545,17 @@ static int hdspm_system_clock_mode(struct hdspm *hdspm)
2359 **/ 2545 **/
2360static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode) 2546static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode)
2361{ 2547{
2362 switch (hdspm->io_type) { 2548 hdspm_set_toggle_setting(hdspm,
2363 case AIO: 2549 (hdspm_is_raydat_or_aio(hdspm)) ?
2364 case RayDAT: 2550 HDSPM_c0Master : HDSPM_ClockModeMaster,
2365 if (0 == mode) 2551 (0 == mode));
2366 hdspm->settings_register |= HDSPM_c0Master;
2367 else
2368 hdspm->settings_register &= ~HDSPM_c0Master;
2369
2370 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
2371 break;
2372
2373 default:
2374 if (0 == mode)
2375 hdspm->control_register |= HDSPM_ClockModeMaster;
2376 else
2377 hdspm->control_register &= ~HDSPM_ClockModeMaster;
2378
2379 hdspm_write(hdspm, HDSPM_controlRegister,
2380 hdspm->control_register);
2381 }
2382} 2552}
2383 2553
2384 2554
2385static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol, 2555static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol,
2386 struct snd_ctl_elem_info *uinfo) 2556 struct snd_ctl_elem_info *uinfo)
2387{ 2557{
2388 static char *texts[] = { "Master", "AutoSync" }; 2558 static const char *const texts[] = { "Master", "AutoSync" };
2389 ENUMERATED_CTL_INFO(uinfo, texts); 2559 ENUMERATED_CTL_INFO(uinfo, texts);
2390 return 0; 2560 return 0;
2391} 2561}
@@ -2809,16 +2979,7 @@ static int snd_hdspm_info_pref_sync_ref(struct snd_kcontrol *kcontrol,
2809{ 2979{
2810 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2980 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2811 2981
2812 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2982 snd_ctl_enum_info(uinfo, 1, hdspm->texts_autosync_items, hdspm->texts_autosync);
2813 uinfo->count = 1;
2814 uinfo->value.enumerated.items = hdspm->texts_autosync_items;
2815
2816 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2817 uinfo->value.enumerated.item =
2818 uinfo->value.enumerated.items - 1;
2819
2820 strcpy(uinfo->value.enumerated.name,
2821 hdspm->texts_autosync[uinfo->value.enumerated.item]);
2822 2983
2823 return 0; 2984 return 0;
2824} 2985}
@@ -2873,19 +3034,20 @@ static int snd_hdspm_put_pref_sync_ref(struct snd_kcontrol *kcontrol,
2873 3034
2874static int hdspm_autosync_ref(struct hdspm *hdspm) 3035static int hdspm_autosync_ref(struct hdspm *hdspm)
2875{ 3036{
3037 /* This looks at the autosync selected sync reference */
2876 if (AES32 == hdspm->io_type) { 3038 if (AES32 == hdspm->io_type) {
3039
2877 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); 3040 unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister);
2878 unsigned int syncref = 3041 unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF;
2879 (status >> HDSPM_AES32_syncref_bit) & 0xF; 3042 if ((syncref >= HDSPM_AES32_AUTOSYNC_FROM_WORD) &&
2880 if (syncref == 0) 3043 (syncref <= HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN)) {
2881 return HDSPM_AES32_AUTOSYNC_FROM_WORD;
2882 if (syncref <= 8)
2883 return syncref; 3044 return syncref;
3045 }
2884 return HDSPM_AES32_AUTOSYNC_FROM_NONE; 3046 return HDSPM_AES32_AUTOSYNC_FROM_NONE;
3047
2885 } else if (MADI == hdspm->io_type) { 3048 } else if (MADI == hdspm->io_type) {
2886 /* This looks at the autosync selected sync reference */
2887 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2888 3049
3050 unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
2889 switch (status2 & HDSPM_SelSyncRefMask) { 3051 switch (status2 & HDSPM_SelSyncRefMask) {
2890 case HDSPM_SelSyncRef_WORD: 3052 case HDSPM_SelSyncRef_WORD:
2891 return HDSPM_AUTOSYNC_FROM_WORD; 3053 return HDSPM_AUTOSYNC_FROM_WORD;
@@ -2898,7 +3060,7 @@ static int hdspm_autosync_ref(struct hdspm *hdspm)
2898 case HDSPM_SelSyncRef_NVALID: 3060 case HDSPM_SelSyncRef_NVALID:
2899 return HDSPM_AUTOSYNC_FROM_NONE; 3061 return HDSPM_AUTOSYNC_FROM_NONE;
2900 default: 3062 default:
2901 return 0; 3063 return HDSPM_AUTOSYNC_FROM_NONE;
2902 } 3064 }
2903 3065
2904 } 3066 }
@@ -2912,31 +3074,15 @@ static int snd_hdspm_info_autosync_ref(struct snd_kcontrol *kcontrol,
2912 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3074 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
2913 3075
2914 if (AES32 == hdspm->io_type) { 3076 if (AES32 == hdspm->io_type) {
2915 static char *texts[] = { "WordClock", "AES1", "AES2", "AES3", 3077 static const char *const texts[] = { "WordClock", "AES1", "AES2", "AES3",
2916 "AES4", "AES5", "AES6", "AES7", "AES8", "None"}; 3078 "AES4", "AES5", "AES6", "AES7", "AES8", "TCO", "Sync In", "None"};
2917 3079
2918 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3080 ENUMERATED_CTL_INFO(uinfo, texts);
2919 uinfo->count = 1;
2920 uinfo->value.enumerated.items = 10;
2921 if (uinfo->value.enumerated.item >=
2922 uinfo->value.enumerated.items)
2923 uinfo->value.enumerated.item =
2924 uinfo->value.enumerated.items - 1;
2925 strcpy(uinfo->value.enumerated.name,
2926 texts[uinfo->value.enumerated.item]);
2927 } else if (MADI == hdspm->io_type) { 3081 } else if (MADI == hdspm->io_type) {
2928 static char *texts[] = {"Word Clock", "MADI", "TCO", 3082 static const char *const texts[] = {"Word Clock", "MADI", "TCO",
2929 "Sync In", "None" }; 3083 "Sync In", "None" };
2930 3084
2931 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3085 ENUMERATED_CTL_INFO(uinfo, texts);
2932 uinfo->count = 1;
2933 uinfo->value.enumerated.items = 5;
2934 if (uinfo->value.enumerated.item >=
2935 uinfo->value.enumerated.items)
2936 uinfo->value.enumerated.item =
2937 uinfo->value.enumerated.items - 1;
2938 strcpy(uinfo->value.enumerated.name,
2939 texts[uinfo->value.enumerated.item]);
2940 } 3086 }
2941 return 0; 3087 return 0;
2942} 3088}
@@ -2964,7 +3110,7 @@ static int snd_hdspm_get_autosync_ref(struct snd_kcontrol *kcontrol,
2964static int snd_hdspm_info_tco_video_input_format(struct snd_kcontrol *kcontrol, 3110static int snd_hdspm_info_tco_video_input_format(struct snd_kcontrol *kcontrol,
2965 struct snd_ctl_elem_info *uinfo) 3111 struct snd_ctl_elem_info *uinfo)
2966{ 3112{
2967 static char *texts[] = {"No video", "NTSC", "PAL"}; 3113 static const char *const texts[] = {"No video", "NTSC", "PAL"};
2968 ENUMERATED_CTL_INFO(uinfo, texts); 3114 ENUMERATED_CTL_INFO(uinfo, texts);
2969 return 0; 3115 return 0;
2970} 3116}
@@ -3010,7 +3156,7 @@ static int snd_hdspm_get_tco_video_input_format(struct snd_kcontrol *kcontrol,
3010static int snd_hdspm_info_tco_ltc_frames(struct snd_kcontrol *kcontrol, 3156static int snd_hdspm_info_tco_ltc_frames(struct snd_kcontrol *kcontrol,
3011 struct snd_ctl_elem_info *uinfo) 3157 struct snd_ctl_elem_info *uinfo)
3012{ 3158{
3013 static char *texts[] = {"No lock", "24 fps", "25 fps", "29.97 fps", 3159 static const char *const texts[] = {"No lock", "24 fps", "25 fps", "29.97 fps",
3014 "30 fps"}; 3160 "30 fps"};
3015 ENUMERATED_CTL_INFO(uinfo, texts); 3161 ENUMERATED_CTL_INFO(uinfo, texts);
3016 return 0; 3162 return 0;
@@ -3027,19 +3173,19 @@ static int hdspm_tco_ltc_frames(struct hdspm *hdspm)
3027 HDSPM_TCO1_LTC_Format_MSB)) { 3173 HDSPM_TCO1_LTC_Format_MSB)) {
3028 case 0: 3174 case 0:
3029 /* 24 fps */ 3175 /* 24 fps */
3030 ret = 1; 3176 ret = fps_24;
3031 break; 3177 break;
3032 case HDSPM_TCO1_LTC_Format_LSB: 3178 case HDSPM_TCO1_LTC_Format_LSB:
3033 /* 25 fps */ 3179 /* 25 fps */
3034 ret = 2; 3180 ret = fps_25;
3035 break; 3181 break;
3036 case HDSPM_TCO1_LTC_Format_MSB: 3182 case HDSPM_TCO1_LTC_Format_MSB:
3037 /* 25 fps */ 3183 /* 29.97 fps */
3038 ret = 3; 3184 ret = fps_2997;
3039 break; 3185 break;
3040 default: 3186 default:
3041 /* 30 fps */ 3187 /* 30 fps */
3042 ret = 4; 3188 ret = fps_30;
3043 break; 3189 break;
3044 } 3190 }
3045 } 3191 }
@@ -3067,16 +3213,35 @@ static int snd_hdspm_get_tco_ltc_frames(struct snd_kcontrol *kcontrol,
3067 3213
3068static int hdspm_toggle_setting(struct hdspm *hdspm, u32 regmask) 3214static int hdspm_toggle_setting(struct hdspm *hdspm, u32 regmask)
3069{ 3215{
3070 return (hdspm->control_register & regmask) ? 1 : 0; 3216 u32 reg;
3217
3218 if (hdspm_is_raydat_or_aio(hdspm))
3219 reg = hdspm->settings_register;
3220 else
3221 reg = hdspm->control_register;
3222
3223 return (reg & regmask) ? 1 : 0;
3071} 3224}
3072 3225
3073static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out) 3226static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out)
3074{ 3227{
3228 u32 *reg;
3229 u32 target_reg;
3230
3231 if (hdspm_is_raydat_or_aio(hdspm)) {
3232 reg = &(hdspm->settings_register);
3233 target_reg = HDSPM_WR_SETTINGS;
3234 } else {
3235 reg = &(hdspm->control_register);
3236 target_reg = HDSPM_controlRegister;
3237 }
3238
3075 if (out) 3239 if (out)
3076 hdspm->control_register |= regmask; 3240 *reg |= regmask;
3077 else 3241 else
3078 hdspm->control_register &= ~regmask; 3242 *reg &= ~regmask;
3079 hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 3243
3244 hdspm_write(hdspm, target_reg, *reg);
3080 3245
3081 return 0; 3246 return 0;
3082} 3247}
@@ -3141,7 +3306,7 @@ static int hdspm_set_input_select(struct hdspm * hdspm, int out)
3141static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol, 3306static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol,
3142 struct snd_ctl_elem_info *uinfo) 3307 struct snd_ctl_elem_info *uinfo)
3143{ 3308{
3144 static char *texts[] = { "optical", "coaxial" }; 3309 static const char *const texts[] = { "optical", "coaxial" };
3145 ENUMERATED_CTL_INFO(uinfo, texts); 3310 ENUMERATED_CTL_INFO(uinfo, texts);
3146 return 0; 3311 return 0;
3147} 3312}
@@ -3203,7 +3368,7 @@ static int hdspm_set_ds_wire(struct hdspm * hdspm, int ds)
3203static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol, 3368static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol,
3204 struct snd_ctl_elem_info *uinfo) 3369 struct snd_ctl_elem_info *uinfo)
3205{ 3370{
3206 static char *texts[] = { "Single", "Double" }; 3371 static const char *const texts[] = { "Single", "Double" };
3207 ENUMERATED_CTL_INFO(uinfo, texts); 3372 ENUMERATED_CTL_INFO(uinfo, texts);
3208 return 0; 3373 return 0;
3209} 3374}
@@ -3276,7 +3441,7 @@ static int hdspm_set_qs_wire(struct hdspm * hdspm, int mode)
3276static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol, 3441static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol,
3277 struct snd_ctl_elem_info *uinfo) 3442 struct snd_ctl_elem_info *uinfo)
3278{ 3443{
3279 static char *texts[] = { "Single", "Double", "Quad" }; 3444 static const char *const texts[] = { "Single", "Double", "Quad" };
3280 ENUMERATED_CTL_INFO(uinfo, texts); 3445 ENUMERATED_CTL_INFO(uinfo, texts);
3281 return 0; 3446 return 0;
3282} 3447}
@@ -3313,6 +3478,84 @@ static int snd_hdspm_put_qs_wire(struct snd_kcontrol *kcontrol,
3313 return change; 3478 return change;
3314} 3479}
3315 3480
3481#define HDSPM_CONTROL_TRISTATE(xname, xindex) \
3482{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3483 .name = xname, \
3484 .private_value = xindex, \
3485 .info = snd_hdspm_info_tristate, \
3486 .get = snd_hdspm_get_tristate, \
3487 .put = snd_hdspm_put_tristate \
3488}
3489
3490static int hdspm_tristate(struct hdspm *hdspm, u32 regmask)
3491{
3492 u32 reg = hdspm->settings_register & (regmask * 3);
3493 return reg / regmask;
3494}
3495
3496static int hdspm_set_tristate(struct hdspm *hdspm, int mode, u32 regmask)
3497{
3498 hdspm->settings_register &= ~(regmask * 3);
3499 hdspm->settings_register |= (regmask * mode);
3500 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
3501
3502 return 0;
3503}
3504
3505static int snd_hdspm_info_tristate(struct snd_kcontrol *kcontrol,
3506 struct snd_ctl_elem_info *uinfo)
3507{
3508 u32 regmask = kcontrol->private_value;
3509
3510 static const char *const texts_spdif[] = { "Optical", "Coaxial", "Internal" };
3511 static const char *const texts_levels[] = { "Hi Gain", "+4 dBu", "-10 dBV" };
3512
3513 switch (regmask) {
3514 case HDSPM_c0_Input0:
3515 ENUMERATED_CTL_INFO(uinfo, texts_spdif);
3516 break;
3517 default:
3518 ENUMERATED_CTL_INFO(uinfo, texts_levels);
3519 break;
3520 }
3521 return 0;
3522}
3523
3524static int snd_hdspm_get_tristate(struct snd_kcontrol *kcontrol,
3525 struct snd_ctl_elem_value *ucontrol)
3526{
3527 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3528 u32 regmask = kcontrol->private_value;
3529
3530 spin_lock_irq(&hdspm->lock);
3531 ucontrol->value.enumerated.item[0] = hdspm_tristate(hdspm, regmask);
3532 spin_unlock_irq(&hdspm->lock);
3533 return 0;
3534}
3535
3536static int snd_hdspm_put_tristate(struct snd_kcontrol *kcontrol,
3537 struct snd_ctl_elem_value *ucontrol)
3538{
3539 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol);
3540 u32 regmask = kcontrol->private_value;
3541 int change;
3542 int val;
3543
3544 if (!snd_hdspm_use_is_exclusive(hdspm))
3545 return -EBUSY;
3546 val = ucontrol->value.integer.value[0];
3547 if (val < 0)
3548 val = 0;
3549 if (val > 2)
3550 val = 2;
3551
3552 spin_lock_irq(&hdspm->lock);
3553 change = val != hdspm_tristate(hdspm, regmask);
3554 hdspm_set_tristate(hdspm, val, regmask);
3555 spin_unlock_irq(&hdspm->lock);
3556 return change;
3557}
3558
3316#define HDSPM_MADI_SPEEDMODE(xname, xindex) \ 3559#define HDSPM_MADI_SPEEDMODE(xname, xindex) \
3317{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3560{ .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
3318 .name = xname, \ 3561 .name = xname, \
@@ -3352,7 +3595,7 @@ static int hdspm_set_madi_speedmode(struct hdspm *hdspm, int mode)
3352static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol, 3595static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol,
3353 struct snd_ctl_elem_info *uinfo) 3596 struct snd_ctl_elem_info *uinfo)
3354{ 3597{
3355 static char *texts[] = { "Single", "Double", "Quad" }; 3598 static const char *const texts[] = { "Single", "Double", "Quad" };
3356 ENUMERATED_CTL_INFO(uinfo, texts); 3599 ENUMERATED_CTL_INFO(uinfo, texts);
3357 return 0; 3600 return 0;
3358} 3601}
@@ -3587,7 +3830,7 @@ static int snd_hdspm_put_playback_mixer(struct snd_kcontrol *kcontrol,
3587static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, 3830static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
3588 struct snd_ctl_elem_info *uinfo) 3831 struct snd_ctl_elem_info *uinfo)
3589{ 3832{
3590 static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" }; 3833 static const char *const texts[] = { "No Lock", "Lock", "Sync", "N/A" };
3591 ENUMERATED_CTL_INFO(uinfo, texts); 3834 ENUMERATED_CTL_INFO(uinfo, texts);
3592 return 0; 3835 return 0;
3593} 3836}
@@ -3595,7 +3838,7 @@ static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol,
3595static int snd_hdspm_tco_info_lock_check(struct snd_kcontrol *kcontrol, 3838static int snd_hdspm_tco_info_lock_check(struct snd_kcontrol *kcontrol,
3596 struct snd_ctl_elem_info *uinfo) 3839 struct snd_ctl_elem_info *uinfo)
3597{ 3840{
3598 static char *texts[] = { "No Lock", "Lock" }; 3841 static const char *const texts[] = { "No Lock", "Lock" };
3599 ENUMERATED_CTL_INFO(uinfo, texts); 3842 ENUMERATED_CTL_INFO(uinfo, texts);
3600 return 0; 3843 return 0;
3601} 3844}
@@ -3745,9 +3988,18 @@ static int hdspm_tco_sync_check(struct hdspm *hdspm)
3745 if (hdspm->tco) { 3988 if (hdspm->tco) {
3746 switch (hdspm->io_type) { 3989 switch (hdspm->io_type) {
3747 case MADI: 3990 case MADI:
3991 status = hdspm_read(hdspm, HDSPM_statusRegister);
3992 if (status & HDSPM_tcoLockMadi) {
3993 if (status & HDSPM_tcoSync)
3994 return 2;
3995 else
3996 return 1;
3997 }
3998 return 0;
3999 break;
3748 case AES32: 4000 case AES32:
3749 status = hdspm_read(hdspm, HDSPM_statusRegister); 4001 status = hdspm_read(hdspm, HDSPM_statusRegister);
3750 if (status & HDSPM_tcoLock) { 4002 if (status & HDSPM_tcoLockAes) {
3751 if (status & HDSPM_tcoSync) 4003 if (status & HDSPM_tcoSync)
3752 return 2; 4004 return 2;
3753 else 4005 else
@@ -3807,7 +4059,8 @@ static int snd_hdspm_get_sync_check(struct snd_kcontrol *kcontrol,
3807 case 5: /* SYNC IN */ 4059 case 5: /* SYNC IN */
3808 val = hdspm_sync_in_sync_check(hdspm); break; 4060 val = hdspm_sync_in_sync_check(hdspm); break;
3809 default: 4061 default:
3810 val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); 4062 val = hdspm_s1_sync_check(hdspm,
4063 kcontrol->private_value-1);
3811 } 4064 }
3812 break; 4065 break;
3813 4066
@@ -3975,7 +4228,8 @@ static void hdspm_tco_write(struct hdspm *hdspm)
3975static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol, 4228static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol,
3976 struct snd_ctl_elem_info *uinfo) 4229 struct snd_ctl_elem_info *uinfo)
3977{ 4230{
3978 static char *texts[] = { "44.1 kHz", "48 kHz" }; 4231 /* TODO freq from app could be supported here, see tco->samplerate */
4232 static const char *const texts[] = { "44.1 kHz", "48 kHz" };
3979 ENUMERATED_CTL_INFO(uinfo, texts); 4233 ENUMERATED_CTL_INFO(uinfo, texts);
3980 return 0; 4234 return 0;
3981} 4235}
@@ -4021,7 +4275,8 @@ static int snd_hdspm_put_tco_sample_rate(struct snd_kcontrol *kcontrol,
4021static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol, 4275static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol,
4022 struct snd_ctl_elem_info *uinfo) 4276 struct snd_ctl_elem_info *uinfo)
4023{ 4277{
4024 static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" }; 4278 static const char *const texts[] = { "0", "+ 0.1 %", "- 0.1 %",
4279 "+ 4 %", "- 4 %" };
4025 ENUMERATED_CTL_INFO(uinfo, texts); 4280 ENUMERATED_CTL_INFO(uinfo, texts);
4026 return 0; 4281 return 0;
4027} 4282}
@@ -4066,7 +4321,7 @@ static int snd_hdspm_put_tco_pull(struct snd_kcontrol *kcontrol,
4066static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol, 4321static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol,
4067 struct snd_ctl_elem_info *uinfo) 4322 struct snd_ctl_elem_info *uinfo)
4068{ 4323{
4069 static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" }; 4324 static const char *const texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" };
4070 ENUMERATED_CTL_INFO(uinfo, texts); 4325 ENUMERATED_CTL_INFO(uinfo, texts);
4071 return 0; 4326 return 0;
4072} 4327}
@@ -4112,7 +4367,7 @@ static int snd_hdspm_put_tco_wck_conversion(struct snd_kcontrol *kcontrol,
4112static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol, 4367static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol,
4113 struct snd_ctl_elem_info *uinfo) 4368 struct snd_ctl_elem_info *uinfo)
4114{ 4369{
4115 static char *texts[] = { "24 fps", "25 fps", "29.97fps", 4370 static const char *const texts[] = { "24 fps", "25 fps", "29.97fps",
4116 "29.97 dfps", "30 fps", "30 dfps" }; 4371 "29.97 dfps", "30 fps", "30 dfps" };
4117 ENUMERATED_CTL_INFO(uinfo, texts); 4372 ENUMERATED_CTL_INFO(uinfo, texts);
4118 return 0; 4373 return 0;
@@ -4159,7 +4414,7 @@ static int snd_hdspm_put_tco_frame_rate(struct snd_kcontrol *kcontrol,
4159static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol, 4414static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol,
4160 struct snd_ctl_elem_info *uinfo) 4415 struct snd_ctl_elem_info *uinfo)
4161{ 4416{
4162 static char *texts[] = { "LTC", "Video", "WCK" }; 4417 static const char *const texts[] = { "LTC", "Video", "WCK" };
4163 ENUMERATED_CTL_INFO(uinfo, texts); 4418 ENUMERATED_CTL_INFO(uinfo, texts);
4164 return 0; 4419 return 0;
4165} 4420}
@@ -4284,7 +4539,6 @@ static struct snd_kcontrol_new snd_hdspm_controls_aio[] = {
4284 HDSPM_INTERNAL_CLOCK("Internal Clock", 0), 4539 HDSPM_INTERNAL_CLOCK("Internal Clock", 0),
4285 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), 4540 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0),
4286 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), 4541 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
4287 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
4288 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 4542 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
4289 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), 4543 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0),
4290 HDSPM_SYNC_CHECK("WC SyncCheck", 0), 4544 HDSPM_SYNC_CHECK("WC SyncCheck", 0),
@@ -4298,7 +4552,16 @@ static struct snd_kcontrol_new snd_hdspm_controls_aio[] = {
4298 HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2), 4552 HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2),
4299 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT Frequency", 3), 4553 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT Frequency", 3),
4300 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 4), 4554 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 4),
4301 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5) 4555 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5),
4556 HDSPM_CONTROL_TRISTATE("S/PDIF Input", HDSPM_c0_Input0),
4557 HDSPM_TOGGLE_SETTING("S/PDIF Out Optical", HDSPM_c0_Spdif_Opt),
4558 HDSPM_TOGGLE_SETTING("S/PDIF Out Professional", HDSPM_c0_Pro),
4559 HDSPM_TOGGLE_SETTING("ADAT internal (AEB/TEB)", HDSPM_c0_AEB1),
4560 HDSPM_TOGGLE_SETTING("XLR Breakout Cable", HDSPM_c0_Sym6db),
4561 HDSPM_TOGGLE_SETTING("Single Speed WordClock Out", HDSPM_c0_Wck48),
4562 HDSPM_CONTROL_TRISTATE("Input Level", HDSPM_c0_AD_GAIN0),
4563 HDSPM_CONTROL_TRISTATE("Output Level", HDSPM_c0_DA_GAIN0),
4564 HDSPM_CONTROL_TRISTATE("Phones Level", HDSPM_c0_PH_GAIN0)
4302 4565
4303 /* 4566 /*
4304 HDSPM_INPUT_SELECT("Input Select", 0), 4567 HDSPM_INPUT_SELECT("Input Select", 0),
@@ -4335,7 +4598,9 @@ static struct snd_kcontrol_new snd_hdspm_controls_raydat[] = {
4335 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT3 Frequency", 5), 4598 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT3 Frequency", 5),
4336 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT4 Frequency", 6), 4599 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT4 Frequency", 6),
4337 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 7), 4600 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 7),
4338 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8) 4601 HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8),
4602 HDSPM_TOGGLE_SETTING("S/PDIF Out Professional", HDSPM_c0_Pro),
4603 HDSPM_TOGGLE_SETTING("Single Speed WordClock Out", HDSPM_c0_Wck48)
4339}; 4604};
4340 4605
4341static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = { 4606static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
@@ -4345,7 +4610,7 @@ static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = {
4345 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), 4610 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0),
4346 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), 4611 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0),
4347 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 4612 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0),
4348 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), 4613 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 11),
4349 HDSPM_SYNC_CHECK("WC Sync Check", 0), 4614 HDSPM_SYNC_CHECK("WC Sync Check", 0),
4350 HDSPM_SYNC_CHECK("AES1 Sync Check", 1), 4615 HDSPM_SYNC_CHECK("AES1 Sync Check", 1),
4351 HDSPM_SYNC_CHECK("AES2 Sync Check", 2), 4616 HDSPM_SYNC_CHECK("AES2 Sync Check", 2),
@@ -4501,77 +4766,22 @@ static int snd_hdspm_create_controls(struct snd_card *card,
4501 ------------------------------------------------------------*/ 4766 ------------------------------------------------------------*/
4502 4767
4503static void 4768static void
4504snd_hdspm_proc_read_madi(struct snd_info_entry * entry, 4769snd_hdspm_proc_read_tco(struct snd_info_entry *entry,
4505 struct snd_info_buffer *buffer) 4770 struct snd_info_buffer *buffer)
4506{ 4771{
4507 struct hdspm *hdspm = entry->private_data; 4772 struct hdspm *hdspm = entry->private_data;
4508 unsigned int status, status2, control, freq; 4773 unsigned int status, control;
4509
4510 char *pref_sync_ref;
4511 char *autosync_ref;
4512 char *system_clock_mode;
4513 char *insel;
4514 int x, x2;
4515
4516 /* TCO stuff */
4517 int a, ltc, frames, seconds, minutes, hours; 4774 int a, ltc, frames, seconds, minutes, hours;
4518 unsigned int period; 4775 unsigned int period;
4519 u64 freq_const = 0; 4776 u64 freq_const = 0;
4520 u32 rate; 4777 u32 rate;
4521 4778
4779 snd_iprintf(buffer, "--- TCO ---\n");
4780
4522 status = hdspm_read(hdspm, HDSPM_statusRegister); 4781 status = hdspm_read(hdspm, HDSPM_statusRegister);
4523 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
4524 control = hdspm->control_register; 4782 control = hdspm->control_register;
4525 freq = hdspm_read(hdspm, HDSPM_timecodeRegister);
4526 4783
4527 snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n",
4528 hdspm->card_name, hdspm->card->number + 1,
4529 hdspm->firmware_rev,
4530 (status2 & HDSPM_version0) |
4531 (status2 & HDSPM_version1) | (status2 &
4532 HDSPM_version2));
4533 4784
4534 snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n",
4535 (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF,
4536 hdspm->serial);
4537
4538 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
4539 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
4540
4541 snd_iprintf(buffer, "--- System ---\n");
4542
4543 snd_iprintf(buffer,
4544 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
4545 status & HDSPM_audioIRQPending,
4546 (status & HDSPM_midi0IRQPending) ? 1 : 0,
4547 (status & HDSPM_midi1IRQPending) ? 1 : 0,
4548 hdspm->irq_count);
4549 snd_iprintf(buffer,
4550 "HW pointer: id = %d, rawptr = %d (%d->%d) "
4551 "estimated= %ld (bytes)\n",
4552 ((status & HDSPM_BufferID) ? 1 : 0),
4553 (status & HDSPM_BufferPositionMask),
4554 (status & HDSPM_BufferPositionMask) %
4555 (2 * (int)hdspm->period_bytes),
4556 ((status & HDSPM_BufferPositionMask) - 64) %
4557 (2 * (int)hdspm->period_bytes),
4558 (long) hdspm_hw_pointer(hdspm) * 4);
4559
4560 snd_iprintf(buffer,
4561 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
4562 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
4563 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
4564 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
4565 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
4566 snd_iprintf(buffer,
4567 "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
4568 hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
4569 hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
4570 snd_iprintf(buffer,
4571 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
4572 "status2=0x%x\n",
4573 hdspm->control_register, hdspm->control2_register,
4574 status, status2);
4575 if (status & HDSPM_tco_detect) { 4785 if (status & HDSPM_tco_detect) {
4576 snd_iprintf(buffer, "TCO module detected.\n"); 4786 snd_iprintf(buffer, "TCO module detected.\n");
4577 a = hdspm_read(hdspm, HDSPM_RD_TCO+4); 4787 a = hdspm_read(hdspm, HDSPM_RD_TCO+4);
@@ -4665,6 +4875,75 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
4665 } else { 4875 } else {
4666 snd_iprintf(buffer, "No TCO module detected.\n"); 4876 snd_iprintf(buffer, "No TCO module detected.\n");
4667 } 4877 }
4878}
4879
4880static void
4881snd_hdspm_proc_read_madi(struct snd_info_entry *entry,
4882 struct snd_info_buffer *buffer)
4883{
4884 struct hdspm *hdspm = entry->private_data;
4885 unsigned int status, status2, control, freq;
4886
4887 char *pref_sync_ref;
4888 char *autosync_ref;
4889 char *system_clock_mode;
4890 char *insel;
4891 int x, x2;
4892
4893 status = hdspm_read(hdspm, HDSPM_statusRegister);
4894 status2 = hdspm_read(hdspm, HDSPM_statusRegister2);
4895 control = hdspm->control_register;
4896 freq = hdspm_read(hdspm, HDSPM_timecodeRegister);
4897
4898 snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n",
4899 hdspm->card_name, hdspm->card->number + 1,
4900 hdspm->firmware_rev,
4901 (status2 & HDSPM_version0) |
4902 (status2 & HDSPM_version1) | (status2 &
4903 HDSPM_version2));
4904
4905 snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n",
4906 (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF,
4907 hdspm->serial);
4908
4909 snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n",
4910 hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase);
4911
4912 snd_iprintf(buffer, "--- System ---\n");
4913
4914 snd_iprintf(buffer,
4915 "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n",
4916 status & HDSPM_audioIRQPending,
4917 (status & HDSPM_midi0IRQPending) ? 1 : 0,
4918 (status & HDSPM_midi1IRQPending) ? 1 : 0,
4919 hdspm->irq_count);
4920 snd_iprintf(buffer,
4921 "HW pointer: id = %d, rawptr = %d (%d->%d) "
4922 "estimated= %ld (bytes)\n",
4923 ((status & HDSPM_BufferID) ? 1 : 0),
4924 (status & HDSPM_BufferPositionMask),
4925 (status & HDSPM_BufferPositionMask) %
4926 (2 * (int)hdspm->period_bytes),
4927 ((status & HDSPM_BufferPositionMask) - 64) %
4928 (2 * (int)hdspm->period_bytes),
4929 (long) hdspm_hw_pointer(hdspm) * 4);
4930
4931 snd_iprintf(buffer,
4932 "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n",
4933 hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF,
4934 hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF,
4935 hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF,
4936 hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF);
4937 snd_iprintf(buffer,
4938 "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n",
4939 hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF,
4940 hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF);
4941 snd_iprintf(buffer,
4942 "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, "
4943 "status2=0x%x\n",
4944 hdspm->control_register, hdspm->control2_register,
4945 status, status2);
4946
4668 4947
4669 snd_iprintf(buffer, "--- Settings ---\n"); 4948 snd_iprintf(buffer, "--- Settings ---\n");
4670 4949
@@ -4768,6 +5047,9 @@ snd_hdspm_proc_read_madi(struct snd_info_entry * entry,
4768 (status & HDSPM_RX_64ch) ? "64 channels" : 5047 (status & HDSPM_RX_64ch) ? "64 channels" :
4769 "56 channels"); 5048 "56 channels");
4770 5049
5050 /* call readout function for TCO specific status */
5051 snd_hdspm_proc_read_tco(entry, buffer);
5052
4771 snd_iprintf(buffer, "\n"); 5053 snd_iprintf(buffer, "\n");
4772} 5054}
4773 5055
@@ -4909,11 +5191,18 @@ snd_hdspm_proc_read_aes32(struct snd_info_entry * entry,
4909 autosync_ref = "AES7"; break; 5191 autosync_ref = "AES7"; break;
4910 case HDSPM_AES32_AUTOSYNC_FROM_AES8: 5192 case HDSPM_AES32_AUTOSYNC_FROM_AES8:
4911 autosync_ref = "AES8"; break; 5193 autosync_ref = "AES8"; break;
5194 case HDSPM_AES32_AUTOSYNC_FROM_TCO:
5195 autosync_ref = "TCO"; break;
5196 case HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN:
5197 autosync_ref = "Sync In"; break;
4912 default: 5198 default:
4913 autosync_ref = "---"; break; 5199 autosync_ref = "---"; break;
4914 } 5200 }
4915 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref); 5201 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref);
4916 5202
5203 /* call readout function for TCO specific status */
5204 snd_hdspm_proc_read_tco(entry, buffer);
5205
4917 snd_iprintf(buffer, "\n"); 5206 snd_iprintf(buffer, "\n");
4918} 5207}
4919 5208
@@ -5097,7 +5386,7 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
5097 5386
5098 case AES32: 5387 case AES32:
5099 hdspm->control_register = 5388 hdspm->control_register =
5100 HDSPM_ClockModeMaster | /* Master Cloack Mode on */ 5389 HDSPM_ClockModeMaster | /* Master Clock Mode on */
5101 hdspm_encode_latency(7) | /* latency max=8192samples */ 5390 hdspm_encode_latency(7) | /* latency max=8192samples */
5102 HDSPM_SyncRef0 | /* AES1 is syncclock */ 5391 HDSPM_SyncRef0 | /* AES1 is syncclock */
5103 HDSPM_LineOut | /* Analog output in */ 5392 HDSPM_LineOut | /* Analog output in */
@@ -5123,9 +5412,8 @@ static int snd_hdspm_set_defaults(struct hdspm * hdspm)
5123 5412
5124 all_in_all_mixer(hdspm, 0 * UNITY_GAIN); 5413 all_in_all_mixer(hdspm, 0 * UNITY_GAIN);
5125 5414
5126 if (hdspm->io_type == AIO || hdspm->io_type == RayDAT) { 5415 if (hdspm_is_raydat_or_aio(hdspm))
5127 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register); 5416 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register);
5128 }
5129 5417
5130 /* set a default rate so that the channel map is set up. */ 5418 /* set a default rate so that the channel map is set up. */
5131 hdspm_set_rate(hdspm, 48000, 1); 5419 hdspm_set_rate(hdspm, 48000, 1);
@@ -5371,6 +5659,16 @@ static int snd_hdspm_hw_params(struct snd_pcm_substream *substream,
5371 */ 5659 */
5372 5660
5373 5661
5662 /* For AES cards, the float format bit is the same as the
5663 * preferred sync reference. Since we don't want to break
5664 * sync settings, we have to skip the remaining part of this
5665 * function.
5666 */
5667 if (hdspm->io_type == AES32) {
5668 return 0;
5669 }
5670
5671
5374 /* Switch to native float format if requested */ 5672 /* Switch to native float format if requested */
5375 if (SNDRV_PCM_FORMAT_FLOAT_LE == params_format(params)) { 5673 if (SNDRV_PCM_FORMAT_FLOAT_LE == params_format(params)) {
5376 if (!(hdspm->control_register & HDSPe_FLOAT_FORMAT)) 5674 if (!(hdspm->control_register & HDSPe_FLOAT_FORMAT))
@@ -6013,7 +6311,7 @@ static int snd_hdspm_hwdep_ioctl(struct snd_hwdep *hw, struct file *file,
6013 ltc.format = fps_2997; 6311 ltc.format = fps_2997;
6014 break; 6312 break;
6015 default: 6313 default:
6016 ltc.format = 30; 6314 ltc.format = fps_30;
6017 break; 6315 break;
6018 } 6316 }
6019 if (i & HDSPM_TCO1_set_drop_frame_flag) { 6317 if (i & HDSPM_TCO1_set_drop_frame_flag) {
@@ -6479,10 +6777,6 @@ static int snd_hdspm_create(struct snd_card *card,
6479 break; 6777 break;
6480 6778
6481 case AIO: 6779 case AIO:
6482 if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) {
6483 snd_printk(KERN_INFO "HDSPM: AEB input board found, but not supported\n");
6484 }
6485
6486 hdspm->ss_in_channels = AIO_IN_SS_CHANNELS; 6780 hdspm->ss_in_channels = AIO_IN_SS_CHANNELS;
6487 hdspm->ds_in_channels = AIO_IN_DS_CHANNELS; 6781 hdspm->ds_in_channels = AIO_IN_DS_CHANNELS;
6488 hdspm->qs_in_channels = AIO_IN_QS_CHANNELS; 6782 hdspm->qs_in_channels = AIO_IN_QS_CHANNELS;
@@ -6490,6 +6784,20 @@ static int snd_hdspm_create(struct snd_card *card,
6490 hdspm->ds_out_channels = AIO_OUT_DS_CHANNELS; 6784 hdspm->ds_out_channels = AIO_OUT_DS_CHANNELS;
6491 hdspm->qs_out_channels = AIO_OUT_QS_CHANNELS; 6785 hdspm->qs_out_channels = AIO_OUT_QS_CHANNELS;
6492 6786
6787 if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) {
6788 snd_printk(KERN_INFO "HDSPM: AEB input board found\n");
6789 hdspm->ss_in_channels += 4;
6790 hdspm->ds_in_channels += 4;
6791 hdspm->qs_in_channels += 4;
6792 }
6793
6794 if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBO_D)) {
6795 snd_printk(KERN_INFO "HDSPM: AEB output board found\n");
6796 hdspm->ss_out_channels += 4;
6797 hdspm->ds_out_channels += 4;
6798 hdspm->qs_out_channels += 4;
6799 }
6800
6493 hdspm->channel_map_out_ss = channel_map_aio_out_ss; 6801 hdspm->channel_map_out_ss = channel_map_aio_out_ss;
6494 hdspm->channel_map_out_ds = channel_map_aio_out_ds; 6802 hdspm->channel_map_out_ds = channel_map_aio_out_ds;
6495 hdspm->channel_map_out_qs = channel_map_aio_out_qs; 6803 hdspm->channel_map_out_qs = channel_map_aio_out_qs;
@@ -6558,6 +6866,7 @@ static int snd_hdspm_create(struct snd_card *card,
6558 break; 6866 break;
6559 6867
6560 case MADI: 6868 case MADI:
6869 case AES32:
6561 if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) { 6870 if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) {
6562 hdspm->midiPorts++; 6871 hdspm->midiPorts++;
6563 hdspm->tco = kzalloc(sizeof(struct hdspm_tco), 6872 hdspm->tco = kzalloc(sizeof(struct hdspm_tco),
@@ -6565,7 +6874,7 @@ static int snd_hdspm_create(struct snd_card *card,
6565 if (NULL != hdspm->tco) { 6874 if (NULL != hdspm->tco) {
6566 hdspm_tco_write(hdspm); 6875 hdspm_tco_write(hdspm);
6567 } 6876 }
6568 snd_printk(KERN_INFO "HDSPM: MADI TCO module found\n"); 6877 snd_printk(KERN_INFO "HDSPM: MADI/AES TCO module found\n");
6569 } else { 6878 } else {
6570 hdspm->tco = NULL; 6879 hdspm->tco = NULL;
6571 } 6880 }
@@ -6580,10 +6889,12 @@ static int snd_hdspm_create(struct snd_card *card,
6580 case AES32: 6889 case AES32:
6581 if (hdspm->tco) { 6890 if (hdspm->tco) {
6582 hdspm->texts_autosync = texts_autosync_aes_tco; 6891 hdspm->texts_autosync = texts_autosync_aes_tco;
6583 hdspm->texts_autosync_items = 10; 6892 hdspm->texts_autosync_items =
6893 ARRAY_SIZE(texts_autosync_aes_tco);
6584 } else { 6894 } else {
6585 hdspm->texts_autosync = texts_autosync_aes; 6895 hdspm->texts_autosync = texts_autosync_aes;
6586 hdspm->texts_autosync_items = 9; 6896 hdspm->texts_autosync_items =
6897 ARRAY_SIZE(texts_autosync_aes);
6587 } 6898 }
6588 break; 6899 break;
6589 6900