aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorMark Brown <broonie@linaro.org>2013-09-11 06:17:15 -0400
committerMark Brown <broonie@linaro.org>2013-09-11 06:17:15 -0400
commitc34c0d7684b8b79666da6b1bc37fc330cd0dd216 (patch)
treec2bc72d67862df770af45a88814759baa0744d2c /sound
parent29dc5dd229dc3130b51df0932e59946fc09d3bd4 (diff)
parent4345adf92db760ca1a54061ce284aaa2e7d0791e (diff)
Merge remote-tracking branch 'asoc/fix/fsl' into asoc-linus
Diffstat (limited to 'sound')
-rw-r--r--sound/core/pcm_lib.c4
-rw-r--r--sound/drivers/dummy.c2
-rw-r--r--sound/firewire/speakers.c4
-rw-r--r--sound/isa/gus/interwave.c3
-rw-r--r--sound/oss/dmabuf.c3
-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.c9
-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
-rw-r--r--sound/soc/cirrus/ep93xx-i2s.c2
-rw-r--r--sound/soc/codecs/dmic.c17
-rw-r--r--sound/soc/codecs/rt5640.c217
-rw-r--r--sound/soc/codecs/rt5640.h12
-rw-r--r--sound/soc/codecs/ssm2602.c3
-rw-r--r--sound/soc/codecs/tlv320aic32x4.c22
-rw-r--r--sound/soc/codecs/wm8904.c1
-rw-r--r--sound/soc/codecs/wm8962.c2
-rw-r--r--sound/soc/dwc/designware_i2s.c5
-rw-r--r--sound/soc/fsl/Kconfig11
-rw-r--r--sound/soc/fsl/Makefile2
-rw-r--r--sound/soc/fsl/fsl_spdif.c29
-rw-r--r--sound/soc/fsl/fsl_ssi.c1
-rw-r--r--sound/soc/fsl/imx-audmux.c3
-rw-r--r--sound/soc/fsl/imx-spdif.c148
-rw-r--r--sound/soc/generic/simple-card.c2
-rw-r--r--sound/soc/kirkwood/Kconfig4
-rw-r--r--sound/soc/kirkwood/kirkwood-i2s.c26
-rw-r--r--sound/soc/mxs/mxs-sgtl5000.c2
-rw-r--r--sound/soc/omap/mcbsp.c2
-rw-r--r--sound/soc/samsung/dma.c7
-rw-r--r--sound/soc/sh/fsi.c51
-rw-r--r--sound/soc/soc-core.c17
-rw-r--r--sound/soc/soc-dapm.c11
-rw-r--r--sound/soc/soc-jack.c2
-rw-r--r--sound/soc/soc-pcm.c10
-rw-r--r--sound/usb/6fire/firmware.c4
-rw-r--r--sound/usb/endpoint.c3
-rw-r--r--sound/usb/pcm.c243
-rw-r--r--sound/usb/usx2y/usbusx2y.c8
53 files changed, 2068 insertions, 5005 deletions
diff --git a/sound/core/pcm_lib.c b/sound/core/pcm_lib.c
index 82bb029d4414..6e03b465e44e 100644
--- a/sound/core/pcm_lib.c
+++ b/sound/core/pcm_lib.c
@@ -184,7 +184,7 @@ static void xrun(struct snd_pcm_substream *substream)
184 do { \ 184 do { \
185 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ 185 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \
186 xrun_log_show(substream); \ 186 xrun_log_show(substream); \
187 if (printk_ratelimit()) { \ 187 if (snd_printd_ratelimit()) { \
188 snd_printd("PCM: " fmt, ##args); \ 188 snd_printd("PCM: " fmt, ##args); \
189 } \ 189 } \
190 dump_stack_on_xrun(substream); \ 190 dump_stack_on_xrun(substream); \
@@ -342,7 +342,7 @@ static int snd_pcm_update_hw_ptr0(struct snd_pcm_substream *substream,
342 return -EPIPE; 342 return -EPIPE;
343 } 343 }
344 if (pos >= runtime->buffer_size) { 344 if (pos >= runtime->buffer_size) {
345 if (printk_ratelimit()) { 345 if (snd_printd_ratelimit()) {
346 char name[16]; 346 char name[16];
347 snd_pcm_debug_name(substream, name, sizeof(name)); 347 snd_pcm_debug_name(substream, name, sizeof(name));
348 xrun_log_show(substream); 348 xrun_log_show(substream);
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 11048cc744d0..915b4d7fbb23 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -1022,7 +1022,7 @@ static void dummy_proc_write(struct snd_info_entry *entry,
1022 if (i >= ARRAY_SIZE(fields)) 1022 if (i >= ARRAY_SIZE(fields))
1023 continue; 1023 continue;
1024 snd_info_get_str(item, ptr, sizeof(item)); 1024 snd_info_get_str(item, ptr, sizeof(item));
1025 if (strict_strtoull(item, 0, &val)) 1025 if (kstrtoull(item, 0, &val))
1026 continue; 1026 continue;
1027 if (fields[i].size == sizeof(int)) 1027 if (fields[i].size == sizeof(int))
1028 *get_dummy_int_ptr(dummy, fields[i].offset) = val; 1028 *get_dummy_int_ptr(dummy, fields[i].offset) = val;
diff --git a/sound/firewire/speakers.c b/sound/firewire/speakers.c
index 2c6386503940..fe9e6e2f2c5b 100644
--- a/sound/firewire/speakers.c
+++ b/sound/firewire/speakers.c
@@ -49,7 +49,6 @@ struct fwspk {
49 struct snd_card *card; 49 struct snd_card *card;
50 struct fw_unit *unit; 50 struct fw_unit *unit;
51 const struct device_info *device_info; 51 const struct device_info *device_info;
52 struct snd_pcm_substream *pcm;
53 struct mutex mutex; 52 struct mutex mutex;
54 struct cmp_connection connection; 53 struct cmp_connection connection;
55 struct amdtp_out_stream stream; 54 struct amdtp_out_stream stream;
@@ -363,8 +362,7 @@ static int fwspk_create_pcm(struct fwspk *fwspk)
363 return err; 362 return err;
364 pcm->private_data = fwspk; 363 pcm->private_data = fwspk;
365 strcpy(pcm->name, fwspk->device_info->short_name); 364 strcpy(pcm->name, fwspk->device_info->short_name);
366 fwspk->pcm = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 365 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ops);
367 fwspk->pcm->ops = &ops;
368 return 0; 366 return 0;
369} 367}
370 368
diff --git a/sound/isa/gus/interwave.c b/sound/isa/gus/interwave.c
index 9942691cc0ca..afef0d738078 100644
--- a/sound/isa/gus/interwave.c
+++ b/sound/isa/gus/interwave.c
@@ -443,8 +443,7 @@ static void snd_interwave_detect_memory(struct snd_gus_card *gus)
443 for (i = 0; i < 8; ++i) 443 for (i = 0; i < 8; ++i)
444 iwave[i] = snd_gf1_peek(gus, bank_pos + i); 444 iwave[i] = snd_gf1_peek(gus, bank_pos + i);
445#ifdef CONFIG_SND_DEBUG_ROM 445#ifdef CONFIG_SND_DEBUG_ROM
446 printk(KERN_DEBUG "ROM at 0x%06x = %*phC\n", bank_pos, 446 printk(KERN_DEBUG "ROM at 0x%06x = %8phC\n", bank_pos, iwave);
447 8, iwave);
448#endif 447#endif
449 if (strncmp(iwave, "INTRWAVE", 8)) 448 if (strncmp(iwave, "INTRWAVE", 8))
450 continue; /* first check */ 449 continue; /* first check */
diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c
index a59c88818f48..461d94cfecbe 100644
--- a/sound/oss/dmabuf.c
+++ b/sound/oss/dmabuf.c
@@ -557,7 +557,6 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
557 unsigned long flags; 557 unsigned long flags;
558 int err = 0, n = 0; 558 int err = 0, n = 0;
559 struct dma_buffparms *dmap = adev->dmap_in; 559 struct dma_buffparms *dmap = adev->dmap_in;
560 int go;
561 560
562 if (!(adev->open_mode & OPEN_READ)) 561 if (!(adev->open_mode & OPEN_READ))
563 return -EIO; 562 return -EIO;
@@ -584,7 +583,7 @@ int DMAbuf_getrdbuffer(int dev, char **buf, int *len, int dontblock)
584 spin_unlock_irqrestore(&dmap->lock,flags); 583 spin_unlock_irqrestore(&dmap->lock,flags);
585 return -EAGAIN; 584 return -EAGAIN;
586 } 585 }
587 if ((go = adev->go)) 586 if (adev->go)
588 timeout = dmabuf_timeout(dmap); 587 timeout = dmabuf_timeout(dmap);
589 588
590 spin_unlock_irqrestore(&dmap->lock,flags); 589 spin_unlock_irqrestore(&dmap->lock,flags);
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..24d82d6c3464 100644
--- a/sound/pci/hda/patch_hdmi.c
+++ b/sound/pci/hda/patch_hdmi.c
@@ -959,6 +959,7 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
959 int pin_nid; 959 int pin_nid;
960 int pin_idx; 960 int pin_idx;
961 struct hda_jack_tbl *jack; 961 struct hda_jack_tbl *jack;
962 int dev_entry = (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT;
962 963
963 jack = snd_hda_jack_tbl_get_from_tag(codec, tag); 964 jack = snd_hda_jack_tbl_get_from_tag(codec, tag);
964 if (!jack) 965 if (!jack)
@@ -967,8 +968,8 @@ static void hdmi_intrinsic_event(struct hda_codec *codec, unsigned int res)
967 jack->jack_dirty = 1; 968 jack->jack_dirty = 1;
968 969
969 _snd_printd(SND_PR_VERBOSE, 970 _snd_printd(SND_PR_VERBOSE,
970 "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 971 "HDMI hot plug event: Codec=%d Pin=%d Device=%d Inactive=%d Presence_Detect=%d ELD_Valid=%d\n",
971 codec->addr, pin_nid, 972 codec->addr, pin_nid, dev_entry, !!(res & AC_UNSOL_RES_IA),
972 !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV)); 973 !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV));
973 974
974 pin_idx = pin_nid_to_pin_index(spec, pin_nid); 975 pin_idx = pin_nid_to_pin_index(spec, pin_nid);
@@ -1992,8 +1993,10 @@ static int patch_generic_hdmi(struct hda_codec *codec)
1992 return -EINVAL; 1993 return -EINVAL;
1993 } 1994 }
1994 codec->patch_ops = generic_hdmi_patch_ops; 1995 codec->patch_ops = generic_hdmi_patch_ops;
1995 if (codec->vendor_id == 0x80862807) 1996 if (codec->vendor_id == 0x80862807) {
1996 codec->patch_ops.set_power_state = haswell_set_power_state; 1997 codec->patch_ops.set_power_state = haswell_set_power_state;
1998 codec->dp_mst = true;
1999 }
1997 2000
1998 generic_hdmi_init_per_pins(codec); 2001 generic_hdmi_init_per_pins(codec);
1999 2002
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
diff --git a/sound/soc/cirrus/ep93xx-i2s.c b/sound/soc/cirrus/ep93xx-i2s.c
index f23f331e9a97..a57643d6402f 100644
--- a/sound/soc/cirrus/ep93xx-i2s.c
+++ b/sound/soc/cirrus/ep93xx-i2s.c
@@ -408,7 +408,6 @@ static int ep93xx_i2s_probe(struct platform_device *pdev)
408 return 0; 408 return 0;
409 409
410fail_put_lrclk: 410fail_put_lrclk:
411 dev_set_drvdata(&pdev->dev, NULL);
412 clk_put(info->lrclk); 411 clk_put(info->lrclk);
413fail_put_sclk: 412fail_put_sclk:
414 clk_put(info->sclk); 413 clk_put(info->sclk);
@@ -423,7 +422,6 @@ static int ep93xx_i2s_remove(struct platform_device *pdev)
423 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); 422 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev);
424 423
425 snd_soc_unregister_component(&pdev->dev); 424 snd_soc_unregister_component(&pdev->dev);
426 dev_set_drvdata(&pdev->dev, NULL);
427 clk_put(info->lrclk); 425 clk_put(info->lrclk);
428 clk_put(info->sclk); 426 clk_put(info->sclk);
429 clk_put(info->mclk); 427 clk_put(info->mclk);
diff --git a/sound/soc/codecs/dmic.c b/sound/soc/codecs/dmic.c
index 66967ba6f757..b2090b2a5e2d 100644
--- a/sound/soc/codecs/dmic.c
+++ b/sound/soc/codecs/dmic.c
@@ -50,20 +50,11 @@ static const struct snd_soc_dapm_route intercon[] = {
50 {"DMIC AIF", NULL, "DMic"}, 50 {"DMIC AIF", NULL, "DMic"},
51}; 51};
52 52
53static int dmic_probe(struct snd_soc_codec *codec)
54{
55 struct snd_soc_dapm_context *dapm = &codec->dapm;
56
57 snd_soc_dapm_new_controls(dapm, dmic_dapm_widgets,
58 ARRAY_SIZE(dmic_dapm_widgets));
59 snd_soc_dapm_add_routes(dapm, intercon, ARRAY_SIZE(intercon));
60 snd_soc_dapm_new_widgets(dapm);
61
62 return 0;
63}
64
65static struct snd_soc_codec_driver soc_dmic = { 53static struct snd_soc_codec_driver soc_dmic = {
66 .probe = dmic_probe, 54 .dapm_widgets = dmic_dapm_widgets,
55 .num_dapm_widgets = ARRAY_SIZE(dmic_dapm_widgets),
56 .dapm_routes = intercon,
57 .num_dapm_routes = ARRAY_SIZE(intercon),
67}; 58};
68 59
69static int dmic_dev_probe(struct platform_device *pdev) 60static int dmic_dev_probe(struct platform_device *pdev)
diff --git a/sound/soc/codecs/rt5640.c b/sound/soc/codecs/rt5640.c
index 4db7314baabc..c26a8f814b18 100644
--- a/sound/soc/codecs/rt5640.c
+++ b/sound/soc/codecs/rt5640.c
@@ -50,8 +50,6 @@ static const struct regmap_range_cfg rt5640_ranges[] = {
50 50
51static struct reg_default init_list[] = { 51static struct reg_default init_list[] = {
52 {RT5640_PR_BASE + 0x3d, 0x3600}, 52 {RT5640_PR_BASE + 0x3d, 0x3600},
53 {RT5640_PR_BASE + 0x1c, 0x0D21},
54 {RT5640_PR_BASE + 0x1b, 0x0000},
55 {RT5640_PR_BASE + 0x12, 0x0aa8}, 53 {RT5640_PR_BASE + 0x12, 0x0aa8},
56 {RT5640_PR_BASE + 0x14, 0x0aaa}, 54 {RT5640_PR_BASE + 0x14, 0x0aaa},
57 {RT5640_PR_BASE + 0x20, 0x6110}, 55 {RT5640_PR_BASE + 0x20, 0x6110},
@@ -384,15 +382,11 @@ static const SOC_ENUM_SINGLE_DECL(
384 382
385static const struct snd_kcontrol_new rt5640_snd_controls[] = { 383static const struct snd_kcontrol_new rt5640_snd_controls[] = {
386 /* Speaker Output Volume */ 384 /* Speaker Output Volume */
387 SOC_DOUBLE("Speaker Playback Switch", RT5640_SPK_VOL,
388 RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
389 SOC_DOUBLE("Speaker Channel Switch", RT5640_SPK_VOL, 385 SOC_DOUBLE("Speaker Channel Switch", RT5640_SPK_VOL,
390 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), 386 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
391 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5640_SPK_VOL, 387 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5640_SPK_VOL,
392 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv), 388 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv),
393 /* Headphone Output Volume */ 389 /* Headphone Output Volume */
394 SOC_DOUBLE("HP Playback Switch", RT5640_HP_VOL,
395 RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1),
396 SOC_DOUBLE("HP Channel Switch", RT5640_HP_VOL, 390 SOC_DOUBLE("HP Channel Switch", RT5640_HP_VOL,
397 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), 391 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1),
398 SOC_DOUBLE_TLV("HP Playback Volume", RT5640_HP_VOL, 392 SOC_DOUBLE_TLV("HP Playback Volume", RT5640_HP_VOL,
@@ -737,6 +731,22 @@ static const struct snd_kcontrol_new rt5640_mono_mix[] = {
737 RT5640_M_BST1_MM_SFT, 1, 1), 731 RT5640_M_BST1_MM_SFT, 1, 1),
738}; 732};
739 733
734static const struct snd_kcontrol_new spk_l_enable_control =
735 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_SPK_VOL,
736 RT5640_L_MUTE_SFT, 1, 1);
737
738static const struct snd_kcontrol_new spk_r_enable_control =
739 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_SPK_VOL,
740 RT5640_R_MUTE_SFT, 1, 1);
741
742static const struct snd_kcontrol_new hp_l_enable_control =
743 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_HP_VOL,
744 RT5640_L_MUTE_SFT, 1, 1);
745
746static const struct snd_kcontrol_new hp_r_enable_control =
747 SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_HP_VOL,
748 RT5640_R_MUTE_SFT, 1, 1);
749
740/* Stereo ADC source */ 750/* Stereo ADC source */
741static const char * const rt5640_stereo_adc1_src[] = { 751static const char * const rt5640_stereo_adc1_src[] = {
742 "DIG MIX", "ADC" 752 "DIG MIX", "ADC"
@@ -868,33 +878,6 @@ static const SOC_ENUM_SINGLE_DECL(
868static const struct snd_kcontrol_new rt5640_sdi_mux = 878static const struct snd_kcontrol_new rt5640_sdi_mux =
869 SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); 879 SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum);
870 880
871static int spk_event(struct snd_soc_dapm_widget *w,
872 struct snd_kcontrol *kcontrol, int event)
873{
874 struct snd_soc_codec *codec = w->codec;
875 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
876
877 switch (event) {
878 case SND_SOC_DAPM_POST_PMU:
879 regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1,
880 0x0001, 0x0001);
881 regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c,
882 0xf000, 0xf000);
883 break;
884
885 case SND_SOC_DAPM_PRE_PMD:
886 regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c,
887 0xf000, 0x0000);
888 regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1,
889 0x0001, 0x0000);
890 break;
891
892 default:
893 return 0;
894 }
895 return 0;
896}
897
898static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w, 881static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w,
899 struct snd_kcontrol *kcontrol, int event) 882 struct snd_kcontrol *kcontrol, int event)
900{ 883{
@@ -943,6 +926,117 @@ static int rt5640_set_dmic2_event(struct snd_soc_dapm_widget *w,
943 return 0; 926 return 0;
944} 927}
945 928
929void hp_amp_power_on(struct snd_soc_codec *codec)
930{
931 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
932
933 /* depop parameters */
934 regmap_update_bits(rt5640->regmap, RT5640_PR_BASE +
935 RT5640_CHPUMP_INT_REG1, 0x0700, 0x0200);
936 regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2,
937 RT5640_DEPOP_MASK, RT5640_DEPOP_MAN);
938 regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1,
939 RT5640_HP_CP_MASK | RT5640_HP_SG_MASK | RT5640_HP_CB_MASK,
940 RT5640_HP_CP_PU | RT5640_HP_SG_DIS | RT5640_HP_CB_PU);
941 regmap_write(rt5640->regmap, RT5640_PR_BASE + RT5640_HP_DCC_INT1,
942 0x9f00);
943 /* headphone amp power on */
944 regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1,
945 RT5640_PWR_FV1 | RT5640_PWR_FV2, 0);
946 regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1,
947 RT5640_PWR_HA,
948 RT5640_PWR_HA);
949 usleep_range(10000, 15000);
950 regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1,
951 RT5640_PWR_FV1 | RT5640_PWR_FV2 ,
952 RT5640_PWR_FV1 | RT5640_PWR_FV2);
953}
954
955static void rt5640_pmu_depop(struct snd_soc_codec *codec)
956{
957 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
958
959 regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2,
960 RT5640_DEPOP_MASK | RT5640_DIG_DP_MASK,
961 RT5640_DEPOP_AUTO | RT5640_DIG_DP_EN);
962 regmap_update_bits(rt5640->regmap, RT5640_CHARGE_PUMP,
963 RT5640_PM_HP_MASK, RT5640_PM_HP_HV);
964
965 regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M3,
966 RT5640_CP_FQ1_MASK | RT5640_CP_FQ2_MASK | RT5640_CP_FQ3_MASK,
967 (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ1_SFT) |
968 (RT5640_CP_FQ_12_KHZ << RT5640_CP_FQ2_SFT) |
969 (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ3_SFT));
970
971 regmap_write(rt5640->regmap, RT5640_PR_BASE +
972 RT5640_MAMP_INT_REG2, 0x1c00);
973 regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1,
974 RT5640_HP_CP_MASK | RT5640_HP_SG_MASK,
975 RT5640_HP_CP_PD | RT5640_HP_SG_EN);
976 regmap_update_bits(rt5640->regmap, RT5640_PR_BASE +
977 RT5640_CHPUMP_INT_REG1, 0x0700, 0x0400);
978}
979
980static int rt5640_hp_event(struct snd_soc_dapm_widget *w,
981 struct snd_kcontrol *kcontrol, int event)
982{
983 struct snd_soc_codec *codec = w->codec;
984 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
985
986 switch (event) {
987 case SND_SOC_DAPM_POST_PMU:
988 rt5640_pmu_depop(codec);
989 rt5640->hp_mute = 0;
990 break;
991
992 case SND_SOC_DAPM_PRE_PMD:
993 rt5640->hp_mute = 1;
994 usleep_range(70000, 75000);
995 break;
996
997 default:
998 return 0;
999 }
1000
1001 return 0;
1002}
1003
1004static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w,
1005 struct snd_kcontrol *kcontrol, int event)
1006{
1007 struct snd_soc_codec *codec = w->codec;
1008
1009 switch (event) {
1010 case SND_SOC_DAPM_POST_PMU:
1011 hp_amp_power_on(codec);
1012 break;
1013 default:
1014 return 0;
1015 }
1016
1017 return 0;
1018}
1019
1020static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w,
1021 struct snd_kcontrol *kcontrol, int event)
1022{
1023 struct snd_soc_codec *codec = w->codec;
1024 struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec);
1025
1026 switch (event) {
1027 case SND_SOC_DAPM_POST_PMU:
1028 if (!rt5640->hp_mute)
1029 usleep_range(80000, 85000);
1030
1031 break;
1032
1033 default:
1034 return 0;
1035 }
1036
1037 return 0;
1038}
1039
946static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = { 1040static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
947 SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2, 1041 SND_SOC_DAPM_SUPPLY("PLL1", RT5640_PWR_ANLG2,
948 RT5640_PWR_PLL_BIT, 0, NULL, 0), 1042 RT5640_PWR_PLL_BIT, 0, NULL, 0),
@@ -1132,15 +1226,28 @@ static const struct snd_soc_dapm_widget rt5640_dapm_widgets[] = {
1132 rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), 1226 rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)),
1133 SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, 1227 SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1,
1134 RT5640_PWR_MA_BIT, 0, NULL, 0), 1228 RT5640_PWR_MA_BIT, 0, NULL, 0),
1135 SND_SOC_DAPM_SUPPLY("Improve HP Amp Drv", RT5640_PWR_ANLG1, 1229 SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM,
1136 SND_SOC_NOPM, 0, NULL, 0), 1230 0, 0, rt5640_hp_power_event, SND_SOC_DAPM_POST_PMU),
1137 SND_SOC_DAPM_PGA("HP L Amp", RT5640_PWR_ANLG1, 1231 SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0,
1232 rt5640_hp_event,
1233 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU),
1234 SND_SOC_DAPM_SUPPLY("HP L Amp", RT5640_PWR_ANLG1,
1138 RT5640_PWR_HP_L_BIT, 0, NULL, 0), 1235 RT5640_PWR_HP_L_BIT, 0, NULL, 0),
1139 SND_SOC_DAPM_PGA("HP R Amp", RT5640_PWR_ANLG1, 1236 SND_SOC_DAPM_SUPPLY("HP R Amp", RT5640_PWR_ANLG1,
1140 RT5640_PWR_HP_R_BIT, 0, NULL, 0), 1237 RT5640_PWR_HP_R_BIT, 0, NULL, 0),
1141 SND_SOC_DAPM_SUPPLY("Improve SPK Amp Drv", RT5640_PWR_DIG1, 1238 SND_SOC_DAPM_SUPPLY("Improve SPK Amp Drv", RT5640_PWR_DIG1,
1142 SND_SOC_NOPM, 0, spk_event, 1239 RT5640_PWR_CLS_D_BIT, 0, NULL, 0),
1143 SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1240
1241 /* Output Switch */
1242 SND_SOC_DAPM_SWITCH("Speaker L Playback", SND_SOC_NOPM, 0, 0,
1243 &spk_l_enable_control),
1244 SND_SOC_DAPM_SWITCH("Speaker R Playback", SND_SOC_NOPM, 0, 0,
1245 &spk_r_enable_control),
1246 SND_SOC_DAPM_SWITCH("HP L Playback", SND_SOC_NOPM, 0, 0,
1247 &hp_l_enable_control),
1248 SND_SOC_DAPM_SWITCH("HP R Playback", SND_SOC_NOPM, 0, 0,
1249 &hp_r_enable_control),
1250 SND_SOC_DAPM_POST("HP Post", rt5640_hp_post_event),
1144 /* Output Lines */ 1251 /* Output Lines */
1145 SND_SOC_DAPM_OUTPUT("SPOLP"), 1252 SND_SOC_DAPM_OUTPUT("SPOLP"),
1146 SND_SOC_DAPM_OUTPUT("SPOLN"), 1253 SND_SOC_DAPM_OUTPUT("SPOLN"),
@@ -1381,9 +1488,11 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1381 {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"}, 1488 {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"},
1382 {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"}, 1489 {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"},
1383 {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"}, 1490 {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"},
1491 {"HPO MIX L", NULL, "HP L Amp"},
1384 {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"}, 1492 {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"},
1385 {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"}, 1493 {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"},
1386 {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"}, 1494 {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"},
1495 {"HPO MIX R", NULL, "HP R Amp"},
1387 1496
1388 {"LOUT MIX", "DAC L1 Switch", "DAC L1"}, 1497 {"LOUT MIX", "DAC L1 Switch", "DAC L1"},
1389 {"LOUT MIX", "DAC R1 Switch", "DAC R1"}, 1498 {"LOUT MIX", "DAC R1 Switch", "DAC R1"},
@@ -1396,13 +1505,15 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1396 {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, 1505 {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"},
1397 {"Mono MIX", "BST1 Switch", "BST1"}, 1506 {"Mono MIX", "BST1 Switch", "BST1"},
1398 1507
1399 {"HP L Amp", NULL, "HPO MIX L"}, 1508 {"HP Amp", NULL, "HPO MIX L"},
1400 {"HP R Amp", NULL, "HPO MIX R"}, 1509 {"HP Amp", NULL, "HPO MIX R"},
1401 1510
1402 {"SPOLP", NULL, "SPOL MIX"}, 1511 {"Speaker L Playback", "Switch", "SPOL MIX"},
1403 {"SPOLN", NULL, "SPOL MIX"}, 1512 {"Speaker R Playback", "Switch", "SPOR MIX"},
1404 {"SPORP", NULL, "SPOR MIX"}, 1513 {"SPOLP", NULL, "Speaker L Playback"},
1405 {"SPORN", NULL, "SPOR MIX"}, 1514 {"SPOLN", NULL, "Speaker L Playback"},
1515 {"SPORP", NULL, "Speaker R Playback"},
1516 {"SPORN", NULL, "Speaker R Playback"},
1406 1517
1407 {"SPOLP", NULL, "Improve SPK Amp Drv"}, 1518 {"SPOLP", NULL, "Improve SPK Amp Drv"},
1408 {"SPOLN", NULL, "Improve SPK Amp Drv"}, 1519 {"SPOLN", NULL, "Improve SPK Amp Drv"},
@@ -1412,8 +1523,10 @@ static const struct snd_soc_dapm_route rt5640_dapm_routes[] = {
1412 {"HPOL", NULL, "Improve HP Amp Drv"}, 1523 {"HPOL", NULL, "Improve HP Amp Drv"},
1413 {"HPOR", NULL, "Improve HP Amp Drv"}, 1524 {"HPOR", NULL, "Improve HP Amp Drv"},
1414 1525
1415 {"HPOL", NULL, "HP L Amp"}, 1526 {"HP L Playback", "Switch", "HP Amp"},
1416 {"HPOR", NULL, "HP R Amp"}, 1527 {"HP R Playback", "Switch", "HP Amp"},
1528 {"HPOL", NULL, "HP L Playback"},
1529 {"HPOR", NULL, "HP R Playback"},
1417 {"LOUTL", NULL, "LOUT MIX"}, 1530 {"LOUTL", NULL, "LOUT MIX"},
1418 {"LOUTR", NULL, "LOUT MIX"}, 1531 {"LOUTR", NULL, "LOUT MIX"},
1419 {"MONOP", NULL, "Mono MIX"}, 1532 {"MONOP", NULL, "Mono MIX"},
@@ -1792,17 +1905,13 @@ static int rt5640_set_bias_level(struct snd_soc_codec *codec,
1792 RT5640_PWR_BG | RT5640_PWR_VREF2, 1905 RT5640_PWR_BG | RT5640_PWR_VREF2,
1793 RT5640_PWR_VREF1 | RT5640_PWR_MB | 1906 RT5640_PWR_VREF1 | RT5640_PWR_MB |
1794 RT5640_PWR_BG | RT5640_PWR_VREF2); 1907 RT5640_PWR_BG | RT5640_PWR_VREF2);
1795 mdelay(10); 1908 usleep_range(10000, 15000);
1796 snd_soc_update_bits(codec, RT5640_PWR_ANLG1, 1909 snd_soc_update_bits(codec, RT5640_PWR_ANLG1,
1797 RT5640_PWR_FV1 | RT5640_PWR_FV2, 1910 RT5640_PWR_FV1 | RT5640_PWR_FV2,
1798 RT5640_PWR_FV1 | RT5640_PWR_FV2); 1911 RT5640_PWR_FV1 | RT5640_PWR_FV2);
1799 regcache_sync(rt5640->regmap); 1912 regcache_sync(rt5640->regmap);
1800 snd_soc_update_bits(codec, RT5640_DUMMY1, 1913 snd_soc_update_bits(codec, RT5640_DUMMY1,
1801 0x0301, 0x0301); 1914 0x0301, 0x0301);
1802 snd_soc_update_bits(codec, RT5640_DEPOP_M1,
1803 0x001d, 0x0019);
1804 snd_soc_update_bits(codec, RT5640_DEPOP_M2,
1805 0x2000, 0x2000);
1806 snd_soc_update_bits(codec, RT5640_MICBIAS, 1915 snd_soc_update_bits(codec, RT5640_MICBIAS,
1807 0x0030, 0x0030); 1916 0x0030, 0x0030);
1808 } 1917 }
@@ -1846,8 +1955,6 @@ static int rt5640_probe(struct snd_soc_codec *codec)
1846 rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); 1955 rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF);
1847 1956
1848 snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); 1957 snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301);
1849 snd_soc_update_bits(codec, RT5640_DEPOP_M1, 0x001d, 0x0019);
1850 snd_soc_update_bits(codec, RT5640_DEPOP_M2, 0x2000, 0x2000);
1851 snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030); 1958 snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030);
1852 snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00); 1959 snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00);
1853 1960
@@ -2069,6 +2176,8 @@ static int rt5640_i2c_probe(struct i2c_client *i2c,
2069 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, 2176 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4,
2070 RT5640_IN_DF2, RT5640_IN_DF2); 2177 RT5640_IN_DF2, RT5640_IN_DF2);
2071 2178
2179 rt5640->hp_mute = 1;
2180
2072 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, 2181 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640,
2073 rt5640_dai, ARRAY_SIZE(rt5640_dai)); 2182 rt5640_dai, ARRAY_SIZE(rt5640_dai));
2074 if (ret < 0) 2183 if (ret < 0)
diff --git a/sound/soc/codecs/rt5640.h b/sound/soc/codecs/rt5640.h
index c48286d7118f..5e8df25a13f3 100644
--- a/sound/soc/codecs/rt5640.h
+++ b/sound/soc/codecs/rt5640.h
@@ -145,6 +145,8 @@
145 145
146 146
147/* Index of Codec Private Register definition */ 147/* Index of Codec Private Register definition */
148#define RT5640_CHPUMP_INT_REG1 0x24
149#define RT5640_MAMP_INT_REG2 0x37
148#define RT5640_3D_SPK 0x63 150#define RT5640_3D_SPK 0x63
149#define RT5640_WND_1 0x6c 151#define RT5640_WND_1 0x6c
150#define RT5640_WND_2 0x6d 152#define RT5640_WND_2 0x6d
@@ -153,6 +155,7 @@
153#define RT5640_WND_5 0x70 155#define RT5640_WND_5 0x70
154#define RT5640_WND_8 0x73 156#define RT5640_WND_8 0x73
155#define RT5640_DIP_SPK_INF 0x75 157#define RT5640_DIP_SPK_INF 0x75
158#define RT5640_HP_DCC_INT1 0x77
156#define RT5640_EQ_BW_LOP 0xa0 159#define RT5640_EQ_BW_LOP 0xa0
157#define RT5640_EQ_GN_LOP 0xa1 160#define RT5640_EQ_GN_LOP 0xa1
158#define RT5640_EQ_FC_BP1 0xa2 161#define RT5640_EQ_FC_BP1 0xa2
@@ -1201,6 +1204,14 @@
1201#define RT5640_CP_FQ2_SFT 4 1204#define RT5640_CP_FQ2_SFT 4
1202#define RT5640_CP_FQ3_MASK (0x7) 1205#define RT5640_CP_FQ3_MASK (0x7)
1203#define RT5640_CP_FQ3_SFT 0 1206#define RT5640_CP_FQ3_SFT 0
1207#define RT5640_CP_FQ_1_5_KHZ 0
1208#define RT5640_CP_FQ_3_KHZ 1
1209#define RT5640_CP_FQ_6_KHZ 2
1210#define RT5640_CP_FQ_12_KHZ 3
1211#define RT5640_CP_FQ_24_KHZ 4
1212#define RT5640_CP_FQ_48_KHZ 5
1213#define RT5640_CP_FQ_96_KHZ 6
1214#define RT5640_CP_FQ_192_KHZ 7
1204 1215
1205/* HPOUT charge pump (0x91) */ 1216/* HPOUT charge pump (0x91) */
1206#define RT5640_OSW_L_MASK (0x1 << 11) 1217#define RT5640_OSW_L_MASK (0x1 << 11)
@@ -2087,6 +2098,7 @@ struct rt5640_priv {
2087 int pll_out; 2098 int pll_out;
2088 2099
2089 int dmic_en; 2100 int dmic_en;
2101 bool hp_mute;
2090}; 2102};
2091 2103
2092#endif 2104#endif
diff --git a/sound/soc/codecs/ssm2602.c b/sound/soc/codecs/ssm2602.c
index f8d30e5f6371..492644e67ace 100644
--- a/sound/soc/codecs/ssm2602.c
+++ b/sound/soc/codecs/ssm2602.c
@@ -561,8 +561,9 @@ static int ssm2602_suspend(struct snd_soc_codec *codec)
561 561
562static int ssm2602_resume(struct snd_soc_codec *codec) 562static int ssm2602_resume(struct snd_soc_codec *codec)
563{ 563{
564 snd_soc_cache_sync(codec); 564 struct ssm2602_priv *ssm2602 = snd_soc_codec_get_drvdata(codec);
565 565
566 regcache_sync(ssm2602->regmap);
566 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 567 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
567 568
568 return 0; 569 return 0;
diff --git a/sound/soc/codecs/tlv320aic32x4.c b/sound/soc/codecs/tlv320aic32x4.c
index 17df4e32feac..2ed57d4aa445 100644
--- a/sound/soc/codecs/tlv320aic32x4.c
+++ b/sound/soc/codecs/tlv320aic32x4.c
@@ -338,18 +338,6 @@ static inline int aic32x4_get_divs(int mclk, int rate)
338 return -EINVAL; 338 return -EINVAL;
339} 339}
340 340
341static int aic32x4_add_widgets(struct snd_soc_codec *codec)
342{
343 snd_soc_dapm_new_controls(&codec->dapm, aic32x4_dapm_widgets,
344 ARRAY_SIZE(aic32x4_dapm_widgets));
345
346 snd_soc_dapm_add_routes(&codec->dapm, aic32x4_dapm_routes,
347 ARRAY_SIZE(aic32x4_dapm_routes));
348
349 snd_soc_dapm_new_widgets(&codec->dapm);
350 return 0;
351}
352
353static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, 341static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai,
354 int clk_id, unsigned int freq, int dir) 342 int clk_id, unsigned int freq, int dir)
355{ 343{
@@ -683,9 +671,6 @@ static int aic32x4_probe(struct snd_soc_codec *codec)
683 } 671 }
684 672
685 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 673 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY);
686 snd_soc_add_codec_controls(codec, aic32x4_snd_controls,
687 ARRAY_SIZE(aic32x4_snd_controls));
688 aic32x4_add_widgets(codec);
689 674
690 /* 675 /*
691 * Workaround: for an unknown reason, the ADC needs to be powered up 676 * Workaround: for an unknown reason, the ADC needs to be powered up
@@ -714,6 +699,13 @@ static struct snd_soc_codec_driver soc_codec_dev_aic32x4 = {
714 .suspend = aic32x4_suspend, 699 .suspend = aic32x4_suspend,
715 .resume = aic32x4_resume, 700 .resume = aic32x4_resume,
716 .set_bias_level = aic32x4_set_bias_level, 701 .set_bias_level = aic32x4_set_bias_level,
702
703 .controls = aic32x4_snd_controls,
704 .num_controls = ARRAY_SIZE(aic32x4_snd_controls),
705 .dapm_widgets = aic32x4_dapm_widgets,
706 .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets),
707 .dapm_routes = aic32x4_dapm_routes,
708 .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes),
717}; 709};
718 710
719static int aic32x4_i2c_probe(struct i2c_client *i2c, 711static int aic32x4_i2c_probe(struct i2c_client *i2c,
diff --git a/sound/soc/codecs/wm8904.c b/sound/soc/codecs/wm8904.c
index 91dfbfeda6f8..4dfa8dceeabf 100644
--- a/sound/soc/codecs/wm8904.c
+++ b/sound/soc/codecs/wm8904.c
@@ -1202,7 +1202,6 @@ static int wm8904_add_widgets(struct snd_soc_codec *codec)
1202 break; 1202 break;
1203 } 1203 }
1204 1204
1205 snd_soc_dapm_new_widgets(dapm);
1206 return 0; 1205 return 0;
1207} 1206}
1208 1207
diff --git a/sound/soc/codecs/wm8962.c b/sound/soc/codecs/wm8962.c
index 36782f067cc5..11d80f3b6137 100644
--- a/sound/soc/codecs/wm8962.c
+++ b/sound/soc/codecs/wm8962.c
@@ -3174,7 +3174,7 @@ static ssize_t wm8962_beep_set(struct device *dev,
3174 long int time; 3174 long int time;
3175 int ret; 3175 int ret;
3176 3176
3177 ret = strict_strtol(buf, 10, &time); 3177 ret = kstrtol(buf, 10, &time);
3178 if (ret != 0) 3178 if (ret != 0)
3179 return ret; 3179 return ret;
3180 3180
diff --git a/sound/soc/dwc/designware_i2s.c b/sound/soc/dwc/designware_i2s.c
index 70eb37a5dd16..25c31f1655f6 100644
--- a/sound/soc/dwc/designware_i2s.c
+++ b/sound/soc/dwc/designware_i2s.c
@@ -421,13 +421,11 @@ static int dw_i2s_probe(struct platform_device *pdev)
421 dw_i2s_dai, 1); 421 dw_i2s_dai, 1);
422 if (ret != 0) { 422 if (ret != 0) {
423 dev_err(&pdev->dev, "not able to register dai\n"); 423 dev_err(&pdev->dev, "not able to register dai\n");
424 goto err_set_drvdata; 424 goto err_clk_disable;
425 } 425 }
426 426
427 return 0; 427 return 0;
428 428
429err_set_drvdata:
430 dev_set_drvdata(&pdev->dev, NULL);
431err_clk_disable: 429err_clk_disable:
432 clk_disable(dev->clk); 430 clk_disable(dev->clk);
433err_clk_put: 431err_clk_put:
@@ -440,7 +438,6 @@ static int dw_i2s_remove(struct platform_device *pdev)
440 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); 438 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev);
441 439
442 snd_soc_unregister_component(&pdev->dev); 440 snd_soc_unregister_component(&pdev->dev);
443 dev_set_drvdata(&pdev->dev, NULL);
444 441
445 clk_put(dev->clk); 442 clk_put(dev->clk);
446 443
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index cd088cc8c866..b7ab71f2ccc1 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -193,6 +193,17 @@ config SND_SOC_IMX_SGTL5000
193 Say Y if you want to add support for SoC audio on an i.MX board with 193 Say Y if you want to add support for SoC audio on an i.MX board with
194 a sgtl5000 codec. 194 a sgtl5000 codec.
195 195
196config SND_SOC_IMX_SPDIF
197 tristate "SoC Audio support for i.MX boards with S/PDIF"
198 select SND_SOC_IMX_PCM_DMA
199 select SND_SOC_FSL_SPDIF
200 select SND_SOC_SPDIF
201 select REGMAP_MMIO
202 help
203 SoC Audio support for i.MX boards with S/PDIF
204 Say Y if you want to add support for SoC audio on an i.MX board with
205 a S/DPDIF.
206
196config SND_SOC_IMX_MC13783 207config SND_SOC_IMX_MC13783
197 tristate "SoC Audio support for I.MX boards with mc13783" 208 tristate "SoC Audio support for I.MX boards with mc13783"
198 depends on MFD_MC13783 && ARM 209 depends on MFD_MC13783 && ARM
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 4b5970e014dd..8db705b0fdf9 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -45,6 +45,7 @@ snd-soc-mx27vis-aic32x4-objs := mx27vis-aic32x4.o
45snd-soc-wm1133-ev1-objs := wm1133-ev1.o 45snd-soc-wm1133-ev1-objs := wm1133-ev1.o
46snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o 46snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
47snd-soc-imx-wm8962-objs := imx-wm8962.o 47snd-soc-imx-wm8962-objs := imx-wm8962.o
48snd-soc-imx-spdif-objs := imx-spdif.o
48snd-soc-imx-mc13783-objs := imx-mc13783.o 49snd-soc-imx-mc13783-objs := imx-mc13783.o
49 50
50obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o 51obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
@@ -53,4 +54,5 @@ obj-$(CONFIG_SND_SOC_MX27VIS_AIC32X4) += snd-soc-mx27vis-aic32x4.o
53obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o 54obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o
54obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o 55obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
55obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o 56obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o
57obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
56obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o 58obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 42a43820d993..3920c3e849ce 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -411,8 +411,8 @@ static int spdif_set_sample_rate(struct snd_pcm_substream *substream,
411 return 0; 411 return 0;
412} 412}
413 413
414int fsl_spdif_startup(struct snd_pcm_substream *substream, 414static int fsl_spdif_startup(struct snd_pcm_substream *substream,
415 struct snd_soc_dai *cpu_dai) 415 struct snd_soc_dai *cpu_dai)
416{ 416{
417 struct snd_soc_pcm_runtime *rtd = substream->private_data; 417 struct snd_soc_pcm_runtime *rtd = substream->private_data;
418 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); 418 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai);
@@ -546,7 +546,7 @@ static int fsl_spdif_trigger(struct snd_pcm_substream *substream,
546 return 0; 546 return 0;
547} 547}
548 548
549struct snd_soc_dai_ops fsl_spdif_dai_ops = { 549static struct snd_soc_dai_ops fsl_spdif_dai_ops = {
550 .startup = fsl_spdif_startup, 550 .startup = fsl_spdif_startup,
551 .hw_params = fsl_spdif_hw_params, 551 .hw_params = fsl_spdif_hw_params,
552 .trigger = fsl_spdif_trigger, 552 .trigger = fsl_spdif_trigger,
@@ -555,7 +555,6 @@ struct snd_soc_dai_ops fsl_spdif_dai_ops = {
555 555
556 556
557/* 557/*
558 * ============================================
559 * FSL SPDIF IEC958 controller(mixer) functions 558 * FSL SPDIF IEC958 controller(mixer) functions
560 * 559 *
561 * Channel status get/put control 560 * Channel status get/put control
@@ -563,7 +562,6 @@ struct snd_soc_dai_ops fsl_spdif_dai_ops = {
563 * Valid bit value get control 562 * Valid bit value get control
564 * DPLL lock status get control 563 * DPLL lock status get control
565 * User bit sync mode selection control 564 * User bit sync mode selection control
566 * ============================================
567 */ 565 */
568 566
569static int fsl_spdif_info(struct snd_kcontrol *kcontrol, 567static int fsl_spdif_info(struct snd_kcontrol *kcontrol,
@@ -921,7 +919,7 @@ static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
921 return 0; 919 return 0;
922} 920}
923 921
924struct snd_soc_dai_driver fsl_spdif_dai = { 922static struct snd_soc_dai_driver fsl_spdif_dai = {
925 .probe = &fsl_spdif_dai_probe, 923 .probe = &fsl_spdif_dai_probe,
926 .playback = { 924 .playback = {
927 .channels_min = 2, 925 .channels_min = 2,
@@ -942,11 +940,7 @@ static const struct snd_soc_component_driver fsl_spdif_component = {
942 .name = "fsl-spdif", 940 .name = "fsl-spdif",
943}; 941};
944 942
945/* 943/* FSL SPDIF REGMAP */
946 * ================
947 * FSL SPDIF REGMAP
948 * ================
949 */
950 944
951static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) 945static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg)
952{ 946{
@@ -1077,9 +1071,9 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv *spdif_priv,
1077 break; 1071 break;
1078 } 1072 }
1079 1073
1080 dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate", 1074 dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n",
1081 spdif_priv->txclk_src[index], rate[index]); 1075 spdif_priv->txclk_src[index], rate[index]);
1082 dev_dbg(&pdev->dev, "use divisor %d for %dHz sample rate", 1076 dev_dbg(&pdev->dev, "use divisor %d for %dHz sample rate\n",
1083 spdif_priv->txclk_div[index], rate[index]); 1077 spdif_priv->txclk_div[index], rate[index]);
1084 1078
1085 return 0; 1079 return 0;
@@ -1119,10 +1113,8 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1119 } 1113 }
1120 1114
1121 regs = devm_ioremap_resource(&pdev->dev, res); 1115 regs = devm_ioremap_resource(&pdev->dev, res);
1122 if (IS_ERR(regs)) { 1116 if (IS_ERR(regs))
1123 dev_err(&pdev->dev, "could not map device resources\n");
1124 return PTR_ERR(regs); 1117 return PTR_ERR(regs);
1125 }
1126 1118
1127 spdif_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, 1119 spdif_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev,
1128 "core", regs, &fsl_spdif_regmap_config); 1120 "core", regs, &fsl_spdif_regmap_config);
@@ -1184,7 +1176,7 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1184 &spdif_priv->cpu_dai_drv, 1); 1176 &spdif_priv->cpu_dai_drv, 1);
1185 if (ret) { 1177 if (ret) {
1186 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); 1178 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret);
1187 goto error_dev; 1179 return ret;
1188 } 1180 }
1189 1181
1190 ret = imx_pcm_dma_init(pdev); 1182 ret = imx_pcm_dma_init(pdev);
@@ -1197,8 +1189,6 @@ static int fsl_spdif_probe(struct platform_device *pdev)
1197 1189
1198error_component: 1190error_component:
1199 snd_soc_unregister_component(&pdev->dev); 1191 snd_soc_unregister_component(&pdev->dev);
1200error_dev:
1201 dev_set_drvdata(&pdev->dev, NULL);
1202 1192
1203 return ret; 1193 return ret;
1204} 1194}
@@ -1207,7 +1197,6 @@ static int fsl_spdif_remove(struct platform_device *pdev)
1207{ 1197{
1208 imx_pcm_dma_exit(pdev); 1198 imx_pcm_dma_exit(pdev);
1209 snd_soc_unregister_component(&pdev->dev); 1199 snd_soc_unregister_component(&pdev->dev);
1210 dev_set_drvdata(&pdev->dev, NULL);
1211 1200
1212 return 0; 1201 return 0;
1213} 1202}
diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index 5cf626c4dc96..c6b743978d5e 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -1114,7 +1114,6 @@ error_dai:
1114 snd_soc_unregister_component(&pdev->dev); 1114 snd_soc_unregister_component(&pdev->dev);
1115 1115
1116error_dev: 1116error_dev:
1117 dev_set_drvdata(&pdev->dev, NULL);
1118 device_remove_file(&pdev->dev, dev_attr); 1117 device_remove_file(&pdev->dev, dev_attr);
1119 1118
1120error_clk: 1119error_clk:
diff --git a/sound/soc/fsl/imx-audmux.c b/sound/soc/fsl/imx-audmux.c
index ab17381cc981..d3bf71a0ec56 100644
--- a/sound/soc/fsl/imx-audmux.c
+++ b/sound/soc/fsl/imx-audmux.c
@@ -335,7 +335,8 @@ static int imx_audmux_probe(struct platform_device *pdev)
335 if (audmux_type == IMX31_AUDMUX) 335 if (audmux_type == IMX31_AUDMUX)
336 audmux_debugfs_init(); 336 audmux_debugfs_init();
337 337
338 imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node); 338 if (of_id)
339 imx_audmux_parse_dt_defaults(pdev, pdev->dev.of_node);
339 340
340 return 0; 341 return 0;
341} 342}
diff --git a/sound/soc/fsl/imx-spdif.c b/sound/soc/fsl/imx-spdif.c
new file mode 100644
index 000000000000..816013b0ebba
--- /dev/null
+++ b/sound/soc/fsl/imx-spdif.c
@@ -0,0 +1,148 @@
1/*
2 * Copyright (C) 2013 Freescale Semiconductor, Inc.
3 *
4 * The code contained herein is licensed under the GNU General Public
5 * License. You may obtain a copy of the GNU General Public License
6 * Version 2 or later at the following locations:
7 *
8 * http://www.opensource.org/licenses/gpl-license.html
9 * http://www.gnu.org/copyleft/gpl.html
10 */
11
12#include <linux/module.h>
13#include <linux/of_platform.h>
14#include <sound/soc.h>
15
16struct imx_spdif_data {
17 struct snd_soc_dai_link dai[2];
18 struct snd_soc_card card;
19 struct platform_device *txdev;
20 struct platform_device *rxdev;
21};
22
23static int imx_spdif_audio_probe(struct platform_device *pdev)
24{
25 struct device_node *spdif_np, *np = pdev->dev.of_node;
26 struct imx_spdif_data *data;
27 int ret = 0, num_links = 0;
28
29 spdif_np = of_parse_phandle(np, "spdif-controller", 0);
30 if (!spdif_np) {
31 dev_err(&pdev->dev, "failed to find spdif-controller\n");
32 ret = -EINVAL;
33 goto end;
34 }
35
36 data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
37 if (!data) {
38 dev_err(&pdev->dev, "failed to allocate memory\n");
39 ret = -ENOMEM;
40 goto end;
41 }
42
43 if (of_property_read_bool(np, "spdif-out")) {
44 data->dai[num_links].name = "S/PDIF TX";
45 data->dai[num_links].stream_name = "S/PDIF PCM Playback";
46 data->dai[num_links].codec_dai_name = "dit-hifi";
47 data->dai[num_links].codec_name = "spdif-dit";
48 data->dai[num_links].cpu_of_node = spdif_np;
49 data->dai[num_links].platform_of_node = spdif_np;
50 num_links++;
51
52 data->txdev = platform_device_register_simple("spdif-dit", -1, NULL, 0);
53 if (IS_ERR(data->txdev)) {
54 ret = PTR_ERR(data->txdev);
55 dev_err(&pdev->dev, "register dit failed: %d\n", ret);
56 goto end;
57 }
58 }
59
60 if (of_property_read_bool(np, "spdif-in")) {
61 data->dai[num_links].name = "S/PDIF RX";
62 data->dai[num_links].stream_name = "S/PDIF PCM Capture";
63 data->dai[num_links].codec_dai_name = "dir-hifi";
64 data->dai[num_links].codec_name = "spdif-dir";
65 data->dai[num_links].cpu_of_node = spdif_np;
66 data->dai[num_links].platform_of_node = spdif_np;
67 num_links++;
68
69 data->rxdev = platform_device_register_simple("spdif-dir", -1, NULL, 0);
70 if (IS_ERR(data->rxdev)) {
71 ret = PTR_ERR(data->rxdev);
72 dev_err(&pdev->dev, "register dir failed: %d\n", ret);
73 goto error_dit;
74 }
75 }
76
77 if (!num_links) {
78 dev_err(&pdev->dev, "no enabled S/PDIF DAI link\n");
79 goto error_dir;
80 }
81
82 data->card.dev = &pdev->dev;
83 data->card.num_links = num_links;
84 data->card.dai_link = data->dai;
85
86 ret = snd_soc_of_parse_card_name(&data->card, "model");
87 if (ret)
88 goto error_dir;
89
90 ret = snd_soc_register_card(&data->card);
91 if (ret) {
92 dev_err(&pdev->dev, "snd_soc_register_card failed: %d\n", ret);
93 goto error_dir;
94 }
95
96 platform_set_drvdata(pdev, data);
97
98 goto end;
99
100error_dir:
101 if (data->rxdev)
102 platform_device_unregister(data->rxdev);
103error_dit:
104 if (data->txdev)
105 platform_device_unregister(data->txdev);
106end:
107 if (spdif_np)
108 of_node_put(spdif_np);
109
110 return ret;
111}
112
113static int imx_spdif_audio_remove(struct platform_device *pdev)
114{
115 struct imx_spdif_data *data = platform_get_drvdata(pdev);
116
117 if (data->rxdev)
118 platform_device_unregister(data->rxdev);
119 if (data->txdev)
120 platform_device_unregister(data->txdev);
121
122 snd_soc_unregister_card(&data->card);
123
124 return 0;
125}
126
127static const struct of_device_id imx_spdif_dt_ids[] = {
128 { .compatible = "fsl,imx-audio-spdif", },
129 { /* sentinel */ }
130};
131MODULE_DEVICE_TABLE(of, imx_spdif_dt_ids);
132
133static struct platform_driver imx_spdif_driver = {
134 .driver = {
135 .name = "imx-spdif",
136 .owner = THIS_MODULE,
137 .of_match_table = imx_spdif_dt_ids,
138 },
139 .probe = imx_spdif_audio_probe,
140 .remove = imx_spdif_audio_remove,
141};
142
143module_platform_driver(imx_spdif_driver);
144
145MODULE_AUTHOR("Freescale Semiconductor, Inc.");
146MODULE_DESCRIPTION("Freescale i.MX S/PDIF machine driver");
147MODULE_LICENSE("GPL v2");
148MODULE_ALIAS("platform:imx-spdif");
diff --git a/sound/soc/generic/simple-card.c b/sound/soc/generic/simple-card.c
index 6cf8355a8542..8c49147db84c 100644
--- a/sound/soc/generic/simple-card.c
+++ b/sound/soc/generic/simple-card.c
@@ -105,6 +105,7 @@ static int asoc_simple_card_remove(struct platform_device *pdev)
105static struct platform_driver asoc_simple_card = { 105static struct platform_driver asoc_simple_card = {
106 .driver = { 106 .driver = {
107 .name = "asoc-simple-card", 107 .name = "asoc-simple-card",
108 .owner = THIS_MODULE,
108 }, 109 },
109 .probe = asoc_simple_card_probe, 110 .probe = asoc_simple_card_probe,
110 .remove = asoc_simple_card_remove, 111 .remove = asoc_simple_card_remove,
@@ -112,6 +113,7 @@ static struct platform_driver asoc_simple_card = {
112 113
113module_platform_driver(asoc_simple_card); 114module_platform_driver(asoc_simple_card);
114 115
116MODULE_ALIAS("platform:asoc-simple-card");
115MODULE_LICENSE("GPL"); 117MODULE_LICENSE("GPL");
116MODULE_DESCRIPTION("ASoC Simple Sound Card"); 118MODULE_DESCRIPTION("ASoC Simple Sound Card");
117MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>"); 119MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
diff --git a/sound/soc/kirkwood/Kconfig b/sound/soc/kirkwood/Kconfig
index 9e1970c44e86..78ed4a42ad21 100644
--- a/sound/soc/kirkwood/Kconfig
+++ b/sound/soc/kirkwood/Kconfig
@@ -1,6 +1,6 @@
1config SND_KIRKWOOD_SOC 1config SND_KIRKWOOD_SOC
2 tristate "SoC Audio for the Marvell Kirkwood chip" 2 tristate "SoC Audio for the Marvell Kirkwood and Dove chips"
3 depends on ARCH_KIRKWOOD || COMPILE_TEST 3 depends on ARCH_KIRKWOOD || ARCH_DOVE || COMPILE_TEST
4 help 4 help
5 Say Y or M if you want to add support for codecs attached to 5 Say Y or M if you want to add support for codecs attached to
6 the Kirkwood I2S interface. You will also need to select the 6 the Kirkwood I2S interface. You will also need to select the
diff --git a/sound/soc/kirkwood/kirkwood-i2s.c b/sound/soc/kirkwood/kirkwood-i2s.c
index e5f3f7a9ea26..7fce340ab3ef 100644
--- a/sound/soc/kirkwood/kirkwood-i2s.c
+++ b/sound/soc/kirkwood/kirkwood-i2s.c
@@ -22,6 +22,8 @@
22#include <sound/pcm_params.h> 22#include <sound/pcm_params.h>
23#include <sound/soc.h> 23#include <sound/soc.h>
24#include <linux/platform_data/asoc-kirkwood.h> 24#include <linux/platform_data/asoc-kirkwood.h>
25#include <linux/of.h>
26
25#include "kirkwood.h" 27#include "kirkwood.h"
26 28
27#define DRV_NAME "mvebu-audio" 29#define DRV_NAME "mvebu-audio"
@@ -453,6 +455,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
453 struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai; 455 struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai;
454 struct kirkwood_dma_data *priv; 456 struct kirkwood_dma_data *priv;
455 struct resource *mem; 457 struct resource *mem;
458 struct device_node *np = pdev->dev.of_node;
456 int err; 459 int err;
457 460
458 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); 461 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
@@ -473,14 +476,16 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
473 return -ENXIO; 476 return -ENXIO;
474 } 477 }
475 478
476 if (!data) { 479 if (np) {
477 dev_err(&pdev->dev, "no platform data ?!\n"); 480 priv->burst = 128; /* might be 32 or 128 */
481 } else if (data) {
482 priv->burst = data->burst;
483 } else {
484 dev_err(&pdev->dev, "no DT nor platform data ?!\n");
478 return -EINVAL; 485 return -EINVAL;
479 } 486 }
480 487
481 priv->burst = data->burst; 488 priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL);
482
483 priv->clk = devm_clk_get(&pdev->dev, NULL);
484 if (IS_ERR(priv->clk)) { 489 if (IS_ERR(priv->clk)) {
485 dev_err(&pdev->dev, "no clock\n"); 490 dev_err(&pdev->dev, "no clock\n");
486 return PTR_ERR(priv->clk); 491 return PTR_ERR(priv->clk);
@@ -507,7 +512,7 @@ static int kirkwood_i2s_dev_probe(struct platform_device *pdev)
507 priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; 512 priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24;
508 513
509 /* Select the burst size */ 514 /* Select the burst size */
510 if (data->burst == 32) { 515 if (priv->burst == 32) {
511 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; 516 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32;
512 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; 517 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32;
513 } else { 518 } else {
@@ -552,12 +557,21 @@ static int kirkwood_i2s_dev_remove(struct platform_device *pdev)
552 return 0; 557 return 0;
553} 558}
554 559
560#ifdef CONFIG_OF
561static struct of_device_id mvebu_audio_of_match[] = {
562 { .compatible = "marvell,mvebu-audio" },
563 { }
564};
565MODULE_DEVICE_TABLE(of, mvebu_audio_of_match);
566#endif
567
555static struct platform_driver kirkwood_i2s_driver = { 568static struct platform_driver kirkwood_i2s_driver = {
556 .probe = kirkwood_i2s_dev_probe, 569 .probe = kirkwood_i2s_dev_probe,
557 .remove = kirkwood_i2s_dev_remove, 570 .remove = kirkwood_i2s_dev_remove,
558 .driver = { 571 .driver = {
559 .name = DRV_NAME, 572 .name = DRV_NAME,
560 .owner = THIS_MODULE, 573 .owner = THIS_MODULE,
574 .of_match_table = of_match_ptr(mvebu_audio_of_match),
561 }, 575 },
562}; 576};
563 577
diff --git a/sound/soc/mxs/mxs-sgtl5000.c b/sound/soc/mxs/mxs-sgtl5000.c
index ce084eb10c49..4bb273786ff3 100644
--- a/sound/soc/mxs/mxs-sgtl5000.c
+++ b/sound/soc/mxs/mxs-sgtl5000.c
@@ -105,11 +105,13 @@ static struct snd_soc_dai_link mxs_sgtl5000_dai[] = {
105 .stream_name = "HiFi Playback", 105 .stream_name = "HiFi Playback",
106 .codec_dai_name = "sgtl5000", 106 .codec_dai_name = "sgtl5000",
107 .ops = &mxs_sgtl5000_hifi_ops, 107 .ops = &mxs_sgtl5000_hifi_ops,
108 .playback_only = true,
108 }, { 109 }, {
109 .name = "HiFi Rx", 110 .name = "HiFi Rx",
110 .stream_name = "HiFi Capture", 111 .stream_name = "HiFi Capture",
111 .codec_dai_name = "sgtl5000", 112 .codec_dai_name = "sgtl5000",
112 .ops = &mxs_sgtl5000_hifi_ops, 113 .ops = &mxs_sgtl5000_hifi_ops,
114 .capture_only = true,
113 }, 115 },
114}; 116};
115 117
diff --git a/sound/soc/omap/mcbsp.c b/sound/soc/omap/mcbsp.c
index 361e4c03646e..83433fdea32a 100644
--- a/sound/soc/omap/mcbsp.c
+++ b/sound/soc/omap/mcbsp.c
@@ -781,7 +781,7 @@ static ssize_t prop##_store(struct device *dev, \
781 unsigned long val; \ 781 unsigned long val; \
782 int status; \ 782 int status; \
783 \ 783 \
784 status = strict_strtoul(buf, 0, &val); \ 784 status = kstrtoul(buf, 0, &val); \
785 if (status) \ 785 if (status) \
786 return status; \ 786 return status; \
787 \ 787 \
diff --git a/sound/soc/samsung/dma.c b/sound/soc/samsung/dma.c
index a0c67f60f594..9338d11e9216 100644
--- a/sound/soc/samsung/dma.c
+++ b/sound/soc/samsung/dma.c
@@ -90,6 +90,13 @@ static void dma_enqueue(struct snd_pcm_substream *substream)
90 dma_info.period = prtd->dma_period; 90 dma_info.period = prtd->dma_period;
91 dma_info.len = prtd->dma_period*limit; 91 dma_info.len = prtd->dma_period*limit;
92 92
93 if (dma_info.cap == DMA_CYCLIC) {
94 dma_info.buf = pos;
95 prtd->params->ops->prepare(prtd->params->ch, &dma_info);
96 prtd->dma_loaded += limit;
97 return;
98 }
99
93 while (prtd->dma_loaded < limit) { 100 while (prtd->dma_loaded < limit) {
94 pr_debug("dma_loaded: %d\n", prtd->dma_loaded); 101 pr_debug("dma_loaded: %d\n", prtd->dma_loaded);
95 102
diff --git a/sound/soc/sh/fsi.c b/sound/soc/sh/fsi.c
index 30390260bb67..b33ca7cd085b 100644
--- a/sound/soc/sh/fsi.c
+++ b/sound/soc/sh/fsi.c
@@ -235,6 +235,8 @@ struct fsi_stream {
235 struct sh_dmae_slave slave; /* see fsi_handler_init() */ 235 struct sh_dmae_slave slave; /* see fsi_handler_init() */
236 struct work_struct work; 236 struct work_struct work;
237 dma_addr_t dma; 237 dma_addr_t dma;
238 int loop_cnt;
239 int additional_pos;
238}; 240};
239 241
240struct fsi_clk { 242struct fsi_clk {
@@ -1289,6 +1291,8 @@ static int fsi_dma_init(struct fsi_priv *fsi, struct fsi_stream *io)
1289 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | 1291 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) |
1290 BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); 1292 BUSOP_SET(16, PACKAGE_16BITBUS_STREAM);
1291 1293
1294 io->loop_cnt = 2; /* push 1st, 2nd period first, then 3rd, 4th... */
1295 io->additional_pos = 0;
1292 io->dma = dma_map_single(dai->dev, runtime->dma_area, 1296 io->dma = dma_map_single(dai->dev, runtime->dma_area,
1293 snd_pcm_lib_buffer_bytes(io->substream), dir); 1297 snd_pcm_lib_buffer_bytes(io->substream), dir);
1294 return 0; 1298 return 0;
@@ -1305,11 +1309,15 @@ static int fsi_dma_quit(struct fsi_priv *fsi, struct fsi_stream *io)
1305 return 0; 1309 return 0;
1306} 1310}
1307 1311
1308static dma_addr_t fsi_dma_get_area(struct fsi_stream *io) 1312static dma_addr_t fsi_dma_get_area(struct fsi_stream *io, int additional)
1309{ 1313{
1310 struct snd_pcm_runtime *runtime = io->substream->runtime; 1314 struct snd_pcm_runtime *runtime = io->substream->runtime;
1315 int period = io->period_pos + additional;
1311 1316
1312 return io->dma + samples_to_bytes(runtime, io->buff_sample_pos); 1317 if (period >= runtime->periods)
1318 period = 0;
1319
1320 return io->dma + samples_to_bytes(runtime, period * io->period_samples);
1313} 1321}
1314 1322
1315static void fsi_dma_complete(void *data) 1323static void fsi_dma_complete(void *data)
@@ -1321,7 +1329,7 @@ static void fsi_dma_complete(void *data)
1321 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? 1329 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ?
1322 DMA_TO_DEVICE : DMA_FROM_DEVICE; 1330 DMA_TO_DEVICE : DMA_FROM_DEVICE;
1323 1331
1324 dma_sync_single_for_cpu(dai->dev, fsi_dma_get_area(io), 1332 dma_sync_single_for_cpu(dai->dev, fsi_dma_get_area(io, 0),
1325 samples_to_bytes(runtime, io->period_samples), dir); 1333 samples_to_bytes(runtime, io->period_samples), dir);
1326 1334
1327 io->buff_sample_pos += io->period_samples; 1335 io->buff_sample_pos += io->period_samples;
@@ -1347,7 +1355,7 @@ static void fsi_dma_do_work(struct work_struct *work)
1347 struct snd_pcm_runtime *runtime; 1355 struct snd_pcm_runtime *runtime;
1348 enum dma_data_direction dir; 1356 enum dma_data_direction dir;
1349 int is_play = fsi_stream_is_play(fsi, io); 1357 int is_play = fsi_stream_is_play(fsi, io);
1350 int len; 1358 int len, i;
1351 dma_addr_t buf; 1359 dma_addr_t buf;
1352 1360
1353 if (!fsi_stream_is_working(fsi, io)) 1361 if (!fsi_stream_is_working(fsi, io))
@@ -1357,26 +1365,33 @@ static void fsi_dma_do_work(struct work_struct *work)
1357 runtime = io->substream->runtime; 1365 runtime = io->substream->runtime;
1358 dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; 1366 dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE;
1359 len = samples_to_bytes(runtime, io->period_samples); 1367 len = samples_to_bytes(runtime, io->period_samples);
1360 buf = fsi_dma_get_area(io);
1361 1368
1362 dma_sync_single_for_device(dai->dev, buf, len, dir); 1369 for (i = 0; i < io->loop_cnt; i++) {
1370 buf = fsi_dma_get_area(io, io->additional_pos);
1363 1371
1364 desc = dmaengine_prep_slave_single(io->chan, buf, len, dir, 1372 dma_sync_single_for_device(dai->dev, buf, len, dir);
1365 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1366 if (!desc) {
1367 dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n");
1368 return;
1369 }
1370 1373
1371 desc->callback = fsi_dma_complete; 1374 desc = dmaengine_prep_slave_single(io->chan, buf, len, dir,
1372 desc->callback_param = io; 1375 DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
1376 if (!desc) {
1377 dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n");
1378 return;
1379 }
1373 1380
1374 if (dmaengine_submit(desc) < 0) { 1381 desc->callback = fsi_dma_complete;
1375 dev_err(dai->dev, "tx_submit() fail\n"); 1382 desc->callback_param = io;
1376 return; 1383
1384 if (dmaengine_submit(desc) < 0) {
1385 dev_err(dai->dev, "tx_submit() fail\n");
1386 return;
1387 }
1388
1389 dma_async_issue_pending(io->chan);
1390
1391 io->additional_pos = 1;
1377 } 1392 }
1378 1393
1379 dma_async_issue_pending(io->chan); 1394 io->loop_cnt = 1;
1380 1395
1381 /* 1396 /*
1382 * FIXME 1397 * FIXME
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index 528f8708221d..4d0561312f3b 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -203,7 +203,7 @@ static ssize_t pmdown_time_set(struct device *dev,
203 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); 203 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev);
204 int ret; 204 int ret;
205 205
206 ret = strict_strtol(buf, 10, &rtd->pmdown_time); 206 ret = kstrtol(buf, 10, &rtd->pmdown_time);
207 if (ret) 207 if (ret)
208 return ret; 208 return ret;
209 209
@@ -248,6 +248,7 @@ static ssize_t codec_reg_write_file(struct file *file,
248 char *start = buf; 248 char *start = buf;
249 unsigned long reg, value; 249 unsigned long reg, value;
250 struct snd_soc_codec *codec = file->private_data; 250 struct snd_soc_codec *codec = file->private_data;
251 int ret;
251 252
252 buf_size = min(count, (sizeof(buf)-1)); 253 buf_size = min(count, (sizeof(buf)-1));
253 if (copy_from_user(buf, user_buf, buf_size)) 254 if (copy_from_user(buf, user_buf, buf_size))
@@ -259,8 +260,9 @@ static ssize_t codec_reg_write_file(struct file *file,
259 reg = simple_strtoul(start, &start, 16); 260 reg = simple_strtoul(start, &start, 16);
260 while (*start == ' ') 261 while (*start == ' ')
261 start++; 262 start++;
262 if (strict_strtoul(start, 16, &value)) 263 ret = kstrtoul(start, 16, &value);
263 return -EINVAL; 264 if (ret)
265 return ret;
264 266
265 /* Userspace has been fiddling around behind the kernel's back */ 267 /* Userspace has been fiddling around behind the kernel's back */
266 add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE); 268 add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE);
@@ -1243,9 +1245,6 @@ static int soc_post_component_init(struct snd_soc_card *card,
1243 } 1245 }
1244 rtd->card = card; 1246 rtd->card = card;
1245 1247
1246 /* Make sure all DAPM widgets are instantiated */
1247 snd_soc_dapm_new_widgets(&codec->dapm);
1248
1249 /* machine controls, routes and widgets are not prefixed */ 1248 /* machine controls, routes and widgets are not prefixed */
1250 temp = codec->name_prefix; 1249 temp = codec->name_prefix;
1251 codec->name_prefix = NULL; 1250 codec->name_prefix = NULL;
@@ -1741,8 +1740,6 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1741 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1740 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes,
1742 card->num_dapm_routes); 1741 card->num_dapm_routes);
1743 1742
1744 snd_soc_dapm_new_widgets(&card->dapm);
1745
1746 for (i = 0; i < card->num_links; i++) { 1743 for (i = 0; i < card->num_links; i++) {
1747 dai_link = &card->dai_link[i]; 1744 dai_link = &card->dai_link[i];
1748 dai_fmt = dai_link->dai_fmt; 1745 dai_fmt = dai_link->dai_fmt;
@@ -1821,12 +1818,12 @@ static int snd_soc_instantiate_card(struct snd_soc_card *card)
1821 } 1818 }
1822 } 1819 }
1823 1820
1824 snd_soc_dapm_new_widgets(&card->dapm);
1825
1826 if (card->fully_routed) 1821 if (card->fully_routed)
1827 list_for_each_entry(codec, &card->codec_dev_list, card_list) 1822 list_for_each_entry(codec, &card->codec_dev_list, card_list)
1828 snd_soc_dapm_auto_nc_codec_pins(codec); 1823 snd_soc_dapm_auto_nc_codec_pins(codec);
1829 1824
1825 snd_soc_dapm_new_widgets(card);
1826
1830 ret = snd_card_register(card->snd_card); 1827 ret = snd_card_register(card->snd_card);
1831 if (ret < 0) { 1828 if (ret < 0) {
1832 dev_err(card->dev, "ASoC: failed to register soundcard %d\n", 1829 dev_err(card->dev, "ASoC: failed to register soundcard %d\n",
diff --git a/sound/soc/soc-dapm.c b/sound/soc/soc-dapm.c
index d84bd0f167b6..c17c14c394df 100644
--- a/sound/soc/soc-dapm.c
+++ b/sound/soc/soc-dapm.c
@@ -229,6 +229,8 @@ static int dapm_kcontrol_data_alloc(struct snd_soc_dapm_widget *widget,
229 template.id = snd_soc_dapm_kcontrol; 229 template.id = snd_soc_dapm_kcontrol;
230 template.name = kcontrol->id.name; 230 template.name = kcontrol->id.name;
231 231
232 data->value = template.on_val;
233
232 data->widget = snd_soc_dapm_new_control(widget->dapm, 234 data->widget = snd_soc_dapm_new_control(widget->dapm,
233 &template); 235 &template);
234 if (!data->widget) { 236 if (!data->widget) {
@@ -2374,6 +2376,9 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
2374 wsource->ext = 1; 2376 wsource->ext = 1;
2375 } 2377 }
2376 2378
2379 dapm_mark_dirty(wsource, "Route added");
2380 dapm_mark_dirty(wsink, "Route added");
2381
2377 /* connect static paths */ 2382 /* connect static paths */
2378 if (control == NULL) { 2383 if (control == NULL) {
2379 list_add(&path->list, &dapm->card->paths); 2384 list_add(&path->list, &dapm->card->paths);
@@ -2436,9 +2441,6 @@ static int snd_soc_dapm_add_path(struct snd_soc_dapm_context *dapm,
2436 return 0; 2441 return 0;
2437 } 2442 }
2438 2443
2439 dapm_mark_dirty(wsource, "Route added");
2440 dapm_mark_dirty(wsink, "Route added");
2441
2442 return 0; 2444 return 0;
2443err: 2445err:
2444 kfree(path); 2446 kfree(path);
@@ -2712,9 +2714,8 @@ EXPORT_SYMBOL_GPL(snd_soc_dapm_weak_routes);
2712 * 2714 *
2713 * Returns 0 for success. 2715 * Returns 0 for success.
2714 */ 2716 */
2715int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) 2717int snd_soc_dapm_new_widgets(struct snd_soc_card *card)
2716{ 2718{
2717 struct snd_soc_card *card = dapm->card;
2718 struct snd_soc_dapm_widget *w; 2719 struct snd_soc_dapm_widget *w;
2719 unsigned int val; 2720 unsigned int val;
2720 2721
diff --git a/sound/soc/soc-jack.c b/sound/soc/soc-jack.c
index 7aa26b5178aa..71358e3b54d9 100644
--- a/sound/soc/soc-jack.c
+++ b/sound/soc/soc-jack.c
@@ -183,8 +183,6 @@ int snd_soc_jack_add_pins(struct snd_soc_jack *jack, int count,
183 list_add(&(pins[i].list), &jack->pins); 183 list_add(&(pins[i].list), &jack->pins);
184 } 184 }
185 185
186 snd_soc_dapm_new_widgets(&jack->codec->card->dapm);
187
188 /* Update to reflect the last reported status; canned jack 186 /* Update to reflect the last reported status; canned jack
189 * implementations are likely to set their state before the 187 * implementations are likely to set their state before the
190 * card has an opportunity to associate pins. 188 * card has an opportunity to associate pins.
diff --git a/sound/soc/soc-pcm.c b/sound/soc/soc-pcm.c
index fb70fbe26862..330c9a6b5cb5 100644
--- a/sound/soc/soc-pcm.c
+++ b/sound/soc/soc-pcm.c
@@ -2020,6 +2020,16 @@ int soc_new_pcm(struct snd_soc_pcm_runtime *rtd, int num)
2020 capture = 1; 2020 capture = 1;
2021 } 2021 }
2022 2022
2023 if (rtd->dai_link->playback_only) {
2024 playback = 1;
2025 capture = 0;
2026 }
2027
2028 if (rtd->dai_link->capture_only) {
2029 playback = 0;
2030 capture = 1;
2031 }
2032
2023 /* create the PCM */ 2033 /* create the PCM */
2024 if (rtd->dai_link->no_pcm) { 2034 if (rtd->dai_link->no_pcm) {
2025 snprintf(new_name, sizeof(new_name), "(%s)", 2035 snprintf(new_name, sizeof(new_name), "(%s)",
diff --git a/sound/usb/6fire/firmware.c b/sound/usb/6fire/firmware.c
index b9defcdeb7ef..780bf3f62d28 100644
--- a/sound/usb/6fire/firmware.c
+++ b/sound/usb/6fire/firmware.c
@@ -346,10 +346,10 @@ static int usb6fire_fw_check(u8 *version)
346 if (!memcmp(version, known_fw_versions + i, 2)) 346 if (!memcmp(version, known_fw_versions + i, 2))
347 return 0; 347 return 0;
348 348
349 snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %*ph. " 349 snd_printk(KERN_ERR PREFIX "invalid fimware version in device: %4ph. "
350 "please reconnect to power. if this failure " 350 "please reconnect to power. if this failure "
351 "still happens, check your firmware installation.", 351 "still happens, check your firmware installation.",
352 4, version); 352 version);
353 return -EINVAL; 353 return -EINVAL;
354} 354}
355 355
diff --git a/sound/usb/endpoint.c b/sound/usb/endpoint.c
index 659950e5b94f..93e970f2b3c0 100644
--- a/sound/usb/endpoint.c
+++ b/sound/usb/endpoint.c
@@ -418,6 +418,9 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
418 struct snd_usb_endpoint *ep; 418 struct snd_usb_endpoint *ep;
419 int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; 419 int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK;
420 420
421 if (WARN_ON(!alts))
422 return NULL;
423
421 mutex_lock(&chip->mutex); 424 mutex_lock(&chip->mutex);
422 425
423 list_for_each_entry(ep, &chip->ep_list, list) { 426 list_for_each_entry(ep, &chip->ep_list, list) {
diff --git a/sound/usb/pcm.c b/sound/usb/pcm.c
index 15b151ed4899..b375d58871e7 100644
--- a/sound/usb/pcm.c
+++ b/sound/usb/pcm.c
@@ -327,6 +327,137 @@ static int search_roland_implicit_fb(struct usb_device *dev, int ifnum,
327 return 0; 327 return 0;
328} 328}
329 329
330static int set_sync_ep_implicit_fb_quirk(struct snd_usb_substream *subs,
331 struct usb_device *dev,
332 struct usb_interface_descriptor *altsd,
333 unsigned int attr)
334{
335 struct usb_host_interface *alts;
336 struct usb_interface *iface;
337 unsigned int ep;
338
339 /* Implicit feedback sync EPs consumers are always playback EPs */
340 if (subs->direction != SNDRV_PCM_STREAM_PLAYBACK)
341 return 0;
342
343 switch (subs->stream->chip->usb_id) {
344 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
345 case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
346 ep = 0x81;
347 iface = usb_ifnum_to_if(dev, 3);
348
349 if (!iface || iface->num_altsetting == 0)
350 return -EINVAL;
351
352 alts = &iface->altsetting[1];
353 goto add_sync_ep;
354 break;
355 case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */
356 case USB_ID(0x0763, 0x2081):
357 ep = 0x81;
358 iface = usb_ifnum_to_if(dev, 2);
359
360 if (!iface || iface->num_altsetting == 0)
361 return -EINVAL;
362
363 alts = &iface->altsetting[1];
364 goto add_sync_ep;
365 }
366 if (attr == USB_ENDPOINT_SYNC_ASYNC &&
367 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
368 altsd->bInterfaceProtocol == 2 &&
369 altsd->bNumEndpoints == 1 &&
370 USB_ID_VENDOR(subs->stream->chip->usb_id) == 0x0582 /* Roland */ &&
371 search_roland_implicit_fb(dev, altsd->bInterfaceNumber + 1,
372 altsd->bAlternateSetting,
373 &alts, &ep) >= 0) {
374 goto add_sync_ep;
375 }
376
377 /* No quirk */
378 return 0;
379
380add_sync_ep:
381 subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip,
382 alts, ep, !subs->direction,
383 SND_USB_ENDPOINT_TYPE_DATA);
384 if (!subs->sync_endpoint)
385 return -EINVAL;
386
387 subs->data_endpoint->sync_master = subs->sync_endpoint;
388
389 return 0;
390}
391
392static int set_sync_endpoint(struct snd_usb_substream *subs,
393 struct audioformat *fmt,
394 struct usb_device *dev,
395 struct usb_host_interface *alts,
396 struct usb_interface_descriptor *altsd)
397{
398 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
399 unsigned int ep, attr;
400 bool implicit_fb;
401 int err;
402
403 /* we need a sync pipe in async OUT or adaptive IN mode */
404 /* check the number of EP, since some devices have broken
405 * descriptors which fool us. if it has only one EP,
406 * assume it as adaptive-out or sync-in.
407 */
408 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
409
410 err = set_sync_ep_implicit_fb_quirk(subs, dev, altsd, attr);
411 if (err < 0)
412 return err;
413
414 if (altsd->bNumEndpoints < 2)
415 return 0;
416
417 if ((is_playback && attr != USB_ENDPOINT_SYNC_ASYNC) ||
418 (!is_playback && attr != USB_ENDPOINT_SYNC_ADAPTIVE))
419 return 0;
420
421 /* check sync-pipe endpoint */
422 /* ... and check descriptor size before accessing bSynchAddress
423 because there is a version of the SB Audigy 2 NX firmware lacking
424 the audio fields in the endpoint descriptors */
425 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC ||
426 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
427 get_endpoint(alts, 1)->bSynchAddress != 0)) {
428 snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n",
429 dev->devnum, fmt->iface, fmt->altsetting,
430 get_endpoint(alts, 1)->bmAttributes,
431 get_endpoint(alts, 1)->bLength,
432 get_endpoint(alts, 1)->bSynchAddress);
433 return -EINVAL;
434 }
435 ep = get_endpoint(alts, 1)->bEndpointAddress;
436 if (get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
437 ((is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
438 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
439 snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n",
440 dev->devnum, fmt->iface, fmt->altsetting,
441 is_playback, ep, get_endpoint(alts, 0)->bSynchAddress);
442 return -EINVAL;
443 }
444
445 implicit_fb = (get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_USAGE_MASK)
446 == USB_ENDPOINT_USAGE_IMPLICIT_FB;
447
448 subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip,
449 alts, ep, !subs->direction,
450 implicit_fb ?
451 SND_USB_ENDPOINT_TYPE_DATA :
452 SND_USB_ENDPOINT_TYPE_SYNC);
453 if (!subs->sync_endpoint)
454 return -EINVAL;
455
456 subs->data_endpoint->sync_master = subs->sync_endpoint;
457
458 return 0;
459}
460
330/* 461/*
331 * find a matching format and set up the interface 462 * find a matching format and set up the interface
332 */ 463 */
@@ -336,9 +467,7 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
336 struct usb_host_interface *alts; 467 struct usb_host_interface *alts;
337 struct usb_interface_descriptor *altsd; 468 struct usb_interface_descriptor *altsd;
338 struct usb_interface *iface; 469 struct usb_interface *iface;
339 unsigned int ep, attr; 470 int err;
340 int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK;
341 int err, implicit_fb = 0;
342 471
343 iface = usb_ifnum_to_if(dev, fmt->iface); 472 iface = usb_ifnum_to_if(dev, fmt->iface);
344 if (WARN_ON(!iface)) 473 if (WARN_ON(!iface))
@@ -383,118 +512,22 @@ static int set_format(struct snd_usb_substream *subs, struct audioformat *fmt)
383 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, 512 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip,
384 alts, fmt->endpoint, subs->direction, 513 alts, fmt->endpoint, subs->direction,
385 SND_USB_ENDPOINT_TYPE_DATA); 514 SND_USB_ENDPOINT_TYPE_DATA);
515
386 if (!subs->data_endpoint) 516 if (!subs->data_endpoint)
387 return -EINVAL; 517 return -EINVAL;
388 518
389 /* we need a sync pipe in async OUT or adaptive IN mode */ 519 err = set_sync_endpoint(subs, fmt, dev, alts, altsd);
390 /* check the number of EP, since some devices have broken 520 if (err < 0)
391 * descriptors which fool us. if it has only one EP, 521 return err;
392 * assume it as adaptive-out or sync-in.
393 */
394 attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE;
395
396 switch (subs->stream->chip->usb_id) {
397 case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */
398 case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */
399 if (is_playback) {
400 implicit_fb = 1;
401 ep = 0x81;
402 iface = usb_ifnum_to_if(dev, 3);
403
404 if (!iface || iface->num_altsetting == 0)
405 return -EINVAL;
406
407 alts = &iface->altsetting[1];
408 goto add_sync_ep;
409 }
410 break;
411 case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */
412 case USB_ID(0x0763, 0x2081):
413 if (is_playback) {
414 implicit_fb = 1;
415 ep = 0x81;
416 iface = usb_ifnum_to_if(dev, 2);
417
418 if (!iface || iface->num_altsetting == 0)
419 return -EINVAL;
420
421 alts = &iface->altsetting[1];
422 goto add_sync_ep;
423 }
424 }
425 if (is_playback &&
426 attr == USB_ENDPOINT_SYNC_ASYNC &&
427 altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC &&
428 altsd->bInterfaceProtocol == 2 &&
429 altsd->bNumEndpoints == 1 &&
430 USB_ID_VENDOR(subs->stream->chip->usb_id) == 0x0582 /* Roland */ &&
431 search_roland_implicit_fb(dev, altsd->bInterfaceNumber + 1,
432 altsd->bAlternateSetting,
433 &alts, &ep) >= 0) {
434 implicit_fb = 1;
435 goto add_sync_ep;
436 }
437
438 if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) ||
439 (!is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) &&
440 altsd->bNumEndpoints >= 2) {
441 /* check sync-pipe endpoint */
442 /* ... and check descriptor size before accessing bSynchAddress
443 because there is a version of the SB Audigy 2 NX firmware lacking
444 the audio fields in the endpoint descriptors */
445 if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC ||
446 (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
447 get_endpoint(alts, 1)->bSynchAddress != 0 &&
448 !implicit_fb)) {
449 snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n",
450 dev->devnum, fmt->iface, fmt->altsetting,
451 get_endpoint(alts, 1)->bmAttributes,
452 get_endpoint(alts, 1)->bLength,
453 get_endpoint(alts, 1)->bSynchAddress);
454 return -EINVAL;
455 }
456 ep = get_endpoint(alts, 1)->bEndpointAddress;
457 if (!implicit_fb &&
458 get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE &&
459 (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) ||
460 (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) {
461 snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n",
462 dev->devnum, fmt->iface, fmt->altsetting,
463 is_playback, ep, get_endpoint(alts, 0)->bSynchAddress);
464 return -EINVAL;
465 }
466
467 implicit_fb = (get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_USAGE_MASK)
468 == USB_ENDPOINT_USAGE_IMPLICIT_FB;
469
470add_sync_ep:
471 subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip,
472 alts, ep, !subs->direction,
473 implicit_fb ?
474 SND_USB_ENDPOINT_TYPE_DATA :
475 SND_USB_ENDPOINT_TYPE_SYNC);
476 if (!subs->sync_endpoint)
477 return -EINVAL;
478
479 subs->data_endpoint->sync_master = subs->sync_endpoint;
480 }
481 522
482 if ((err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt)) < 0) 523 err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt);
524 if (err < 0)
483 return err; 525 return err;
484 526
485 subs->cur_audiofmt = fmt; 527 subs->cur_audiofmt = fmt;
486 528
487 snd_usb_set_format_quirk(subs, fmt); 529 snd_usb_set_format_quirk(subs, fmt);
488 530
489#if 0
490 printk(KERN_DEBUG
491 "setting done: format = %d, rate = %d..%d, channels = %d\n",
492 fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels);
493 printk(KERN_DEBUG
494 " datapipe = 0x%0x, syncpipe = 0x%0x\n",
495 subs->datapipe, subs->syncpipe);
496#endif
497
498 return 0; 531 return 0;
499} 532}
500 533
diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 1f9bbd55553f..5a51b18c50fe 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -305,11 +305,9 @@ static void usX2Y_unlinkSeq(struct snd_usX2Y_AsyncSeq *S)
305{ 305{
306 int i; 306 int i;
307 for (i = 0; i < URBS_AsyncSeq; ++i) { 307 for (i = 0; i < URBS_AsyncSeq; ++i) {
308 if (S[i].urb) { 308 usb_kill_urb(S->urb[i]);
309 usb_kill_urb(S->urb[i]); 309 usb_free_urb(S->urb[i]);
310 usb_free_urb(S->urb[i]); 310 S->urb[i] = NULL;
311 S->urb[i] = NULL;
312 }
313 } 311 }
314 kfree(S->buffer); 312 kfree(S->buffer);
315} 313}