Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge remote-tracking branch 'asoc/fix/fsl' into asoc-linus

+2174 -5017
+34
Documentation/devicetree/bindings/sound/imx-audio-spdif.txt
··· 1 + Freescale i.MX audio complex with S/PDIF transceiver 2 + 3 + Required properties: 4 + 5 + - compatible : "fsl,imx-audio-spdif" 6 + 7 + - model : The user-visible name of this sound complex 8 + 9 + - spdif-controller : The phandle of the i.MX S/PDIF controller 10 + 11 + 12 + Optional properties: 13 + 14 + - spdif-out : This is a boolean property. If present, the transmitting 15 + function of S/PDIF will be enabled, indicating there's a physical 16 + S/PDIF out connector/jack on the board or it's connecting to some 17 + other IP block, such as an HDMI encoder/display-controller. 18 + 19 + - spdif-in : This is a boolean property. If present, the receiving 20 + function of S/PDIF will be enabled, indicating there's a physical 21 + S/PDIF in connector/jack on the board. 22 + 23 + * Note: At least one of these two properties should be set in the DT binding. 24 + 25 + 26 + Example: 27 + 28 + sound-spdif { 29 + compatible = "fsl,imx-audio-spdif"; 30 + model = "imx-spdif"; 31 + spdif-controller = <&spdif>; 32 + spdif-out; 33 + spdif-in; 34 + };
+29
Documentation/devicetree/bindings/sound/mvebu-audio.txt
··· 1 + * mvebu (Kirkwood, Dove, Armada 370) audio controller 2 + 3 + Required properties: 4 + 5 + - compatible: "marvell,mvebu-audio" 6 + 7 + - reg: physical base address of the controller and length of memory mapped 8 + region. 9 + 10 + - interrupts: list of two irq numbers. 11 + The first irq is used for data flow and the second one is used for errors. 12 + 13 + - clocks: one or two phandles. 14 + The first one is mandatory and defines the internal clock. 15 + The second one is optional and defines an external clock. 16 + 17 + - clock-names: names associated to the clocks: 18 + "internal" for the internal clock 19 + "extclk" for the external clock 20 + 21 + Example: 22 + 23 + i2s1: audio-controller@b4000 { 24 + compatible = "marvell,mvebu-audio"; 25 + reg = <0xb4000 0x2210>; 26 + interrupts = <21>, <22>; 27 + clocks = <&gate_clk 13>; 28 + clock-names = "internal"; 29 + };
+1
Documentation/sound/alsa/HD-Audio-Models.txt
··· 244 244 5stack-no-fp D965 5stack without front panel 245 245 dell-3stack Dell Dimension E520 246 246 dell-bios Fixes with Dell BIOS setup 247 + dell-bios-amic Fixes with Dell BIOS setup including analog mic 247 248 volknob Fixes with volume-knob widget 0x24 248 249 auto BIOS setup (default) 249 250
+2
Documentation/sound/alsa/HD-Audio.txt
··· 454 454 - need_dac_fix (bool): limits the DACs depending on the channel count 455 455 - primary_hp (bool): probe headphone jacks as the primary outputs; 456 456 default true 457 + - multi_io (bool): try probing multi-I/O config (e.g. shared 458 + line-in/surround, mic/clfe jacks) 457 459 - multi_cap_vol (bool): provide multiple capture volumes 458 460 - inv_dmic_split (bool): provide split internal mic volume/switch for 459 461 phase-inverted digital mics
+11
MAINTAINERS
··· 7676 7676 F: include/uapi/sound/ 7677 7677 F: sound/ 7678 7678 7679 + SOUND - COMPRESSED AUDIO 7680 + M: Vinod Koul <vinod.koul@intel.com> 7681 + L: alsa-devel@alsa-project.org (moderated for non-subscribers) 7682 + T: git git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound.git 7683 + S: Supported 7684 + F: Documentation/sound/alsa/compress_offload.txt 7685 + F: include/sound/compress_driver.h 7686 + F: include/uapi/sound/compress_* 7687 + F: sound/core/compress_offload.c 7688 + F: sound/soc/soc-compress.c 7689 + 7679 7690 SOUND - SOC LAYER / DYNAMIC AUDIO POWER MANAGEMENT (ASoC) 7680 7691 M: Liam Girdwood <lgirdwood@gmail.com> 7681 7692 M: Mark Brown <broonie@kernel.org>
+11 -2
arch/arm/plat-samsung/s3c-dma-ops.c
··· 82 82 static int s3c_dma_prepare(unsigned ch, struct samsung_dma_prep *param) 83 83 { 84 84 struct cb_data *data; 85 - int len = (param->cap == DMA_CYCLIC) ? param->period : param->len; 85 + dma_addr_t pos = param->buf; 86 + dma_addr_t end = param->buf + param->len; 86 87 87 88 list_for_each_entry(data, &dma_list, node) 88 89 if (data->ch == ch) ··· 95 94 data->fp_param = param->fp_param; 96 95 } 97 96 98 - s3c2410_dma_enqueue(ch, (void *)data, param->buf, len); 97 + if (param->cap != DMA_CYCLIC) { 98 + s3c2410_dma_enqueue(ch, (void *)data, param->buf, param->len); 99 + return 0; 100 + } 101 + 102 + while (pos < end) { 103 + s3c2410_dma_enqueue(ch, (void *)data, pos, param->period); 104 + pos += param->period; 105 + } 99 106 100 107 return 0; 101 108 }
+8
include/sound/core.h
··· 27 27 #include <linux/rwsem.h> /* struct rw_semaphore */ 28 28 #include <linux/pm.h> /* pm_message_t */ 29 29 #include <linux/stringify.h> 30 + #include <linux/printk.h> 30 31 31 32 /* number of supported soundcards */ 32 33 #ifdef CONFIG_SND_DYNAMIC_MINORS ··· 377 376 #define snd_BUG() WARN(1, "BUG?\n") 378 377 379 378 /** 379 + * Suppress high rates of output when CONFIG_SND_DEBUG is enabled. 380 + */ 381 + #define snd_printd_ratelimit() printk_ratelimit() 382 + 383 + /** 380 384 * snd_BUG_ON - debugging check macro 381 385 * @cond: condition to evaluate 382 386 * ··· 403 397 int __ret_warn_on = !!(condition); \ 404 398 unlikely(__ret_warn_on); \ 405 399 }) 400 + 401 + static inline bool snd_printd_ratelimit(void) { return false; } 406 402 407 403 #endif /* CONFIG_SND_DEBUG */ 408 404
+1 -1
include/sound/soc-dapm.h
··· 413 413 struct snd_soc_dapm_widget *sink); 414 414 415 415 /* dapm path setup */ 416 - int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm); 416 + int snd_soc_dapm_new_widgets(struct snd_soc_card *card); 417 417 void snd_soc_dapm_free(struct snd_soc_dapm_context *dapm); 418 418 int snd_soc_dapm_add_routes(struct snd_soc_dapm_context *dapm, 419 419 const struct snd_soc_dapm_route *route, int num);
+4 -4
include/sound/soc.h
··· 697 697 unsigned int probed:1; /* Codec has been probed */ 698 698 unsigned int ac97_registered:1; /* Codec has been AC97 registered */ 699 699 unsigned int ac97_created:1; /* Codec has been created by SoC */ 700 - unsigned int sysfs_registered:1; /* codec has been sysfs registered */ 701 700 unsigned int cache_init:1; /* codec cache has been initialized */ 702 701 unsigned int using_regmap:1; /* using regmap access */ 703 702 u32 cache_only; /* Suppress writes to hardware */ ··· 704 705 705 706 /* codec IO */ 706 707 void *control_data; /* codec control (i2c/3wire) data */ 707 - enum snd_soc_control_type control_type; 708 708 hw_write_t hw_write; 709 709 unsigned int (*hw_read)(struct snd_soc_codec *, unsigned int); 710 710 unsigned int (*read)(struct snd_soc_codec *, unsigned int); ··· 722 724 #ifdef CONFIG_DEBUG_FS 723 725 struct dentry *debugfs_codec_root; 724 726 struct dentry *debugfs_reg; 725 - struct dentry *debugfs_dapm; 726 727 #endif 727 728 }; 728 729 ··· 846 849 847 850 #ifdef CONFIG_DEBUG_FS 848 851 struct dentry *debugfs_platform_root; 849 - struct dentry *debugfs_dapm; 850 852 #endif 851 853 }; 852 854 ··· 930 934 /* machine stream operations */ 931 935 const struct snd_soc_ops *ops; 932 936 const struct snd_soc_compr_ops *compr_ops; 937 + 938 + /* For unidirectional dai links */ 939 + bool playback_only; 940 + bool capture_only; 933 941 }; 934 942 935 943 struct snd_soc_codec_conf {
+1 -1
include/uapi/sound/hdspm.h
··· 111 111 enum hdspm_ltc_input_format input_format; 112 112 }; 113 113 114 - #define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_mixer_ioctl) 114 + #define SNDRV_HDSPM_IOCTL_GET_LTC _IOR('H', 0x46, struct hdspm_ltc) 115 115 116 116 /** 117 117 * The status data reflects the device's current state
+2 -2
sound/core/pcm_lib.c
··· 184 184 do { \ 185 185 if (xrun_debug(substream, XRUN_DEBUG_BASIC)) { \ 186 186 xrun_log_show(substream); \ 187 - if (printk_ratelimit()) { \ 187 + if (snd_printd_ratelimit()) { \ 188 188 snd_printd("PCM: " fmt, ##args); \ 189 189 } \ 190 190 dump_stack_on_xrun(substream); \ ··· 342 342 return -EPIPE; 343 343 } 344 344 if (pos >= runtime->buffer_size) { 345 - if (printk_ratelimit()) { 345 + if (snd_printd_ratelimit()) { 346 346 char name[16]; 347 347 snd_pcm_debug_name(substream, name, sizeof(name)); 348 348 xrun_log_show(substream);
+1 -1
sound/drivers/dummy.c
··· 1022 1022 if (i >= ARRAY_SIZE(fields)) 1023 1023 continue; 1024 1024 snd_info_get_str(item, ptr, sizeof(item)); 1025 - if (strict_strtoull(item, 0, &val)) 1025 + if (kstrtoull(item, 0, &val)) 1026 1026 continue; 1027 1027 if (fields[i].size == sizeof(int)) 1028 1028 *get_dummy_int_ptr(dummy, fields[i].offset) = val;
+1 -3
sound/firewire/speakers.c
··· 49 49 struct snd_card *card; 50 50 struct fw_unit *unit; 51 51 const struct device_info *device_info; 52 - struct snd_pcm_substream *pcm; 53 52 struct mutex mutex; 54 53 struct cmp_connection connection; 55 54 struct amdtp_out_stream stream; ··· 362 363 return err; 363 364 pcm->private_data = fwspk; 364 365 strcpy(pcm->name, fwspk->device_info->short_name); 365 - fwspk->pcm = pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; 366 - fwspk->pcm->ops = &ops; 366 + snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &ops); 367 367 return 0; 368 368 } 369 369
+1 -2
sound/isa/gus/interwave.c
··· 443 443 for (i = 0; i < 8; ++i) 444 444 iwave[i] = snd_gf1_peek(gus, bank_pos + i); 445 445 #ifdef CONFIG_SND_DEBUG_ROM 446 - printk(KERN_DEBUG "ROM at 0x%06x = %*phC\n", bank_pos, 447 - 8, iwave); 446 + printk(KERN_DEBUG "ROM at 0x%06x = %8phC\n", bank_pos, iwave); 448 447 #endif 449 448 if (strncmp(iwave, "INTRWAVE", 8)) 450 449 continue; /* first check */
+1 -2
sound/oss/dmabuf.c
··· 557 557 unsigned long flags; 558 558 int err = 0, n = 0; 559 559 struct dma_buffparms *dmap = adev->dmap_in; 560 - int go; 561 560 562 561 if (!(adev->open_mode & OPEN_READ)) 563 562 return -EIO; ··· 583 584 spin_unlock_irqrestore(&dmap->lock,flags); 584 585 return -EAGAIN; 585 586 } 586 - if ((go = adev->go)) 587 + if (adev->go) 587 588 timeout = dmabuf_timeout(dmap); 588 589 589 590 spin_unlock_irqrestore(&dmap->lock,flags);
+2 -7
sound/pci/hda/Kconfig
··· 152 152 This module is automatically loaded at probing. 153 153 154 154 config SND_HDA_I915 155 - bool "Build Display HD-audio controller/codec power well support for i915 cards" 155 + bool 156 + default y 156 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 164 159 config SND_HDA_CODEC_CIRRUS 165 160 bool "Build Cirrus Logic codec support"
+62 -2
sound/pci/hda/hda_codec.c
··· 666 666 } 667 667 EXPORT_SYMBOL_HDA(snd_hda_get_conn_index); 668 668 669 + 670 + /* return DEVLIST_LEN parameter of the given widget */ 671 + static 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 + */ 696 + int 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 728 * snd_hda_queue_unsol_event - add an unsolicited event to queue 671 729 * @bus: the BUS ··· 1274 1216 { 1275 1217 struct hda_codec *codec = 1276 1218 container_of(work, struct hda_codec, jackpoll_work.work); 1277 - if (!codec->jackpoll_interval) 1278 - return; 1279 1219 1280 1220 snd_hda_jack_set_dirty_all(codec); 1281 1221 snd_hda_jack_poll_all(codec); 1222 + 1223 + if (!codec->jackpoll_interval) 1224 + return; 1225 + 1282 1226 queue_delayed_work(codec->bus->workq, &codec->jackpoll_work, 1283 1227 codec->jackpoll_interval); 1284 1228 }
+21
sound/pci/hda/hda_codec.h
··· 94 94 #define AC_VERB_GET_HDMI_DIP_XMIT 0x0f32 95 95 #define AC_VERB_GET_HDMI_CP_CTRL 0x0f33 96 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 101 * SET verbs ··· 135 133 #define AC_VERB_SET_HDMI_DIP_XMIT 0x732 136 134 #define AC_VERB_SET_HDMI_CP_CTRL 0x733 137 135 #define AC_VERB_SET_HDMI_CHAN_SLOT 0x734 136 + #define AC_VERB_SET_DEVICE_SEL 0x735 138 137 139 138 /* 140 139 * Parameter IDs ··· 157 154 #define AC_PAR_GPIO_CAP 0x11 158 155 #define AC_PAR_AMP_OUT_CAP 0x12 159 156 #define AC_PAR_VOL_KNB_CAP 0x13 157 + #define AC_PAR_DEVLIST_LEN 0x15 160 158 #define AC_PAR_HDMI_LPCM_CAP 0x20 161 159 162 160 /* ··· 255 251 #define AC_UNSOL_RES_TAG_SHIFT 26 256 252 #define AC_UNSOL_RES_SUBTAG (0x1f<<21) 257 253 #define AC_UNSOL_RES_SUBTAG_SHIFT 21 254 + #define AC_UNSOL_RES_DE (0x3f<<15) /* Device Entry 255 + * (for DP1.2 MST) 256 + */ 257 + #define AC_UNSOL_RES_DE_SHIFT 15 258 + #define AC_UNSOL_RES_IA (1<<2) /* Inactive (for DP1.2 MST) */ 258 259 #define AC_UNSOL_RES_ELDV (1<<1) /* ELD Data valid (for HDMI) */ 259 260 #define AC_UNSOL_RES_PD (1<<0) /* pinsense detect */ 260 261 #define AC_UNSOL_RES_CP_STATE (1<<1) /* content protection */ ··· 360 351 #define AC_LPCMCAP_192K_24BIT (1<<29) /* 24b bitrate supported */ 361 352 #define AC_LPCMCAP_44K (1<<30) /* 44.1kHz support */ 362 353 #define AC_LPCMCAP_44K_MS (1<<31) /* 44.1kHz-multiplies support */ 354 + 355 + /* Display pin's device list length */ 356 + #define AC_DEV_LIST_LEN_MASK 0x3f 357 + #define AC_MAX_DEV_LIST_LEN 64 363 358 364 359 /* 365 360 * Control Parameters ··· 472 459 #define AC_DEFCFG_LOCATION_SHIFT 24 473 460 #define AC_DEFCFG_PORT_CONN (0x3<<30) 474 461 #define AC_DEFCFG_PORT_CONN_SHIFT 30 462 + 463 + /* Display pin's device list entry */ 464 + #define AC_DE_PD (1<<0) 465 + #define AC_DE_ELDV (1<<1) 466 + #define AC_DE_IA (1<<2) 475 467 476 468 /* device device types (0x0-0xf) */ 477 469 enum { ··· 903 885 unsigned int pcm_format_first:1; /* PCM format must be set first */ 904 886 unsigned int epss:1; /* supporting EPSS? */ 905 887 unsigned int cached_write:1; /* write only to caches */ 888 + unsigned int dp_mst:1; /* support DP1.2 Multi-stream transport */ 906 889 #ifdef CONFIG_PM 907 890 unsigned int power_on :1; /* current (global) power-state */ 908 891 unsigned int d3_stop_clk:1; /* support D3 operation without BCLK */ ··· 991 972 const hda_nid_t *list); 992 973 int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux, 993 974 hda_nid_t nid, int recursive); 975 + int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid, 976 + u8 *dev_list, int max_devices); 994 977 int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid, 995 978 u32 *ratesp, u64 *formatsp, unsigned int *bpsp); 996 979
+63 -16
sound/pci/hda/hda_generic.c
··· 142 142 val = snd_hda_get_bool_hint(codec, "primary_hp"); 143 143 if (val >= 0) 144 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 148 val = snd_hda_get_bool_hint(codec, "multi_cap_vol"); 146 149 if (val >= 0) 147 150 spec->multi_cap_vol = !!val; ··· 816 813 817 814 static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol, 818 815 struct snd_ctl_elem_value *ucontrol); 816 + static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol, 817 + struct snd_ctl_elem_value *ucontrol); 819 818 820 819 enum { 821 820 HDA_CTL_WIDGET_VOL, ··· 835 830 .put = hda_gen_mixer_mute_put, /* replaced */ 836 831 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0), 837 832 }, 838 - HDA_BIND_MUTE(NULL, 0, 0, 0), 833 + { 834 + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 835 + .info = snd_hda_mixer_amp_switch_info, 836 + .get = snd_hda_mixer_bind_switch_get, 837 + .put = hda_gen_bind_mute_put, /* replaced */ 838 + .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0), 839 + }, 839 840 }; 840 841 841 842 /* add dynamic controls from template */ ··· 948 937 } 949 938 950 939 /* playback mute control with the software mute bit check */ 951 - static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol, 952 - struct snd_ctl_elem_value *ucontrol) 940 + static void sync_auto_mute_bits(struct snd_kcontrol *kcontrol, 941 + struct snd_ctl_elem_value *ucontrol) 953 942 { 954 943 struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 955 944 struct hda_gen_spec *spec = codec->spec; ··· 960 949 ucontrol->value.integer.value[0] &= enabled; 961 950 ucontrol->value.integer.value[1] &= enabled; 962 951 } 952 + } 963 953 954 + static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol, 955 + struct snd_ctl_elem_value *ucontrol) 956 + { 957 + sync_auto_mute_bits(kcontrol, ucontrol); 964 958 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 959 + } 960 + 961 + static int hda_gen_bind_mute_put(struct snd_kcontrol *kcontrol, 962 + struct snd_ctl_elem_value *ucontrol) 963 + { 964 + sync_auto_mute_bits(kcontrol, ucontrol); 965 + return snd_hda_mixer_bind_switch_put(kcontrol, ucontrol); 965 966 } 966 967 967 968 /* any ctl assigned to the path with the given index? */ ··· 1564 1541 cfg->speaker_pins, 1565 1542 spec->multiout.extra_out_nid, 1566 1543 spec->speaker_paths); 1567 - if (fill_mio_first && cfg->line_outs == 1 && 1544 + if (!spec->no_multi_io && 1545 + fill_mio_first && cfg->line_outs == 1 && 1568 1546 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1569 1547 err = fill_multi_ios(codec, cfg->line_out_pins[0], true); 1570 1548 if (!err) ··· 1578 1554 spec->private_dac_nids, spec->out_paths, 1579 1555 spec->main_out_badness); 1580 1556 1581 - if (fill_mio_first && 1557 + if (!spec->no_multi_io && fill_mio_first && 1582 1558 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1583 1559 /* try to fill multi-io first */ 1584 1560 err = fill_multi_ios(codec, cfg->line_out_pins[0], false); ··· 1606 1582 return err; 1607 1583 badness += err; 1608 1584 } 1609 - if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1585 + if (!spec->no_multi_io && 1586 + cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) { 1610 1587 err = fill_multi_ios(codec, cfg->line_out_pins[0], false); 1611 1588 if (err < 0) 1612 1589 return err; ··· 1625 1600 check_aamix_out_path(codec, spec->speaker_paths[0]); 1626 1601 } 1627 1602 1628 - if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 1603 + if (!spec->no_multi_io && 1604 + cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) 1629 1605 if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2) 1630 1606 spec->multi_ios = 1; /* give badness */ 1631 1607 ··· 3750 3724 /* check each pin in the given array; returns true if any of them is plugged */ 3751 3725 static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins) 3752 3726 { 3753 - int i, present = 0; 3727 + int i; 3728 + bool present = false; 3754 3729 3755 3730 for (i = 0; i < num_pins; i++) { 3756 3731 hda_nid_t nid = pins[i]; ··· 3760 3733 /* don't detect pins retasked as inputs */ 3761 3734 if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN) 3762 3735 continue; 3763 - present |= snd_hda_jack_detect(codec, nid); 3736 + if (snd_hda_jack_detect_state(codec, nid) == HDA_JACK_PRESENT) 3737 + present = true; 3764 3738 } 3765 3739 return present; 3766 3740 } 3767 3741 3768 3742 /* standard HP/line-out auto-mute helper */ 3769 3743 static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, 3770 - bool mute) 3744 + int *paths, bool mute) 3771 3745 { 3772 3746 struct hda_gen_spec *spec = codec->spec; 3773 3747 int i; ··· 3780 3752 break; 3781 3753 3782 3754 if (spec->auto_mute_via_amp) { 3755 + struct nid_path *path; 3756 + hda_nid_t mute_nid; 3757 + 3758 + path = snd_hda_get_path_from_idx(codec, paths[i]); 3759 + if (!path) 3760 + continue; 3761 + mute_nid = get_amp_nid_(path->ctls[NID_PATH_MUTE_CTL]); 3762 + if (!mute_nid) 3763 + continue; 3783 3764 if (mute) 3784 - spec->mute_bits |= (1ULL << nid); 3765 + spec->mute_bits |= (1ULL << mute_nid); 3785 3766 else 3786 - spec->mute_bits &= ~(1ULL << nid); 3767 + spec->mute_bits &= ~(1ULL << mute_nid); 3787 3768 set_pin_eapd(codec, nid, !mute); 3788 3769 continue; 3789 3770 } ··· 3823 3786 void snd_hda_gen_update_outputs(struct hda_codec *codec) 3824 3787 { 3825 3788 struct hda_gen_spec *spec = codec->spec; 3789 + int *paths; 3826 3790 int on; 3827 3791 3828 3792 /* Control HP pins/amps depending on master_mute state; 3829 3793 * in general, HP pins/amps control should be enabled in all cases, 3830 3794 * but currently set only for master_mute, just to be safe 3831 3795 */ 3796 + if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT) 3797 + paths = spec->out_paths; 3798 + else 3799 + paths = spec->hp_paths; 3832 3800 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins), 3833 - spec->autocfg.hp_pins, spec->master_mute); 3801 + spec->autocfg.hp_pins, paths, spec->master_mute); 3834 3802 3835 3803 if (!spec->automute_speaker) 3836 3804 on = 0; ··· 3843 3801 on = spec->hp_jack_present | spec->line_jack_present; 3844 3802 on |= spec->master_mute; 3845 3803 spec->speaker_muted = on; 3804 + if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) 3805 + paths = spec->out_paths; 3806 + else 3807 + paths = spec->speaker_paths; 3846 3808 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins), 3847 - spec->autocfg.speaker_pins, on); 3809 + spec->autocfg.speaker_pins, paths, on); 3848 3810 3849 3811 /* toggle line-out mutes if needed, too */ 3850 3812 /* if LO is a copy of either HP or Speaker, don't need to handle it */ ··· 3861 3815 on = spec->hp_jack_present; 3862 3816 on |= spec->master_mute; 3863 3817 spec->line_out_muted = on; 3818 + paths = spec->out_paths; 3864 3819 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins), 3865 - spec->autocfg.line_out_pins, on); 3820 + spec->autocfg.line_out_pins, paths, on); 3866 3821 } 3867 3822 EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs); 3868 3823 ··· 3934 3887 /* don't detect pins retasked as outputs */ 3935 3888 if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN) 3936 3889 continue; 3937 - if (snd_hda_jack_detect(codec, pin)) { 3890 + if (snd_hda_jack_detect_state(codec, pin) == HDA_JACK_PRESENT) { 3938 3891 mux_select(codec, 0, spec->am_entry[i].idx); 3939 3892 return; 3940 3893 }
+1
sound/pci/hda/hda_generic.h
··· 220 220 unsigned int hp_mic:1; /* Allow HP as a mic-in */ 221 221 unsigned int suppress_hp_mic_detect:1; /* Don't detect HP/mic */ 222 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 224 unsigned int multi_cap_vol:1; /* allow multiple capture xxx volumes */ 224 225 unsigned int inv_dmic_split:1; /* inverted dmic w/a for conexant */ 225 226 unsigned int own_eapd_ctl:1; /* set EAPD by own function */
+3 -3
sound/pci/hda/hda_hwdep.c
··· 295 295 struct snd_hwdep *hwdep = dev_get_drvdata(dev); \ 296 296 struct hda_codec *codec = hwdep->private_data; \ 297 297 unsigned long val; \ 298 - int err = strict_strtoul(buf, 0, &val); \ 298 + int err = kstrtoul(buf, 0, &val); \ 299 299 if (err < 0) \ 300 300 return err; \ 301 301 codec->type = val; \ ··· 654 654 p = snd_hda_get_hint(codec, key); 655 655 if (!p) 656 656 ret = -ENOENT; 657 - else if (strict_strtoul(p, 0, &val)) 657 + else if (kstrtoul(p, 0, &val)) 658 658 ret = -EINVAL; 659 659 else { 660 660 *valp = val; ··· 751 751 struct hda_codec **codecp) \ 752 752 { \ 753 753 unsigned long val; \ 754 - if (!strict_strtoul(buf, 0, &val)) \ 754 + if (!kstrtoul(buf, 0, &val)) \ 755 755 (*codecp)->name = val; \ 756 756 } 757 757
+30 -4
sound/pci/hda/hda_intel.c
··· 1160 1160 goto __skip; 1161 1161 1162 1162 /* clear STATESTS */ 1163 - azx_writeb(chip, STATESTS, STATESTS_INT_MASK); 1163 + azx_writew(chip, STATESTS, STATESTS_INT_MASK); 1164 1164 1165 1165 /* reset controller */ 1166 1166 azx_enter_link_reset(chip); ··· 1242 1242 } 1243 1243 1244 1244 /* clear STATESTS */ 1245 - azx_writeb(chip, STATESTS, STATESTS_INT_MASK); 1245 + azx_writew(chip, STATESTS, STATESTS_INT_MASK); 1246 1246 1247 1247 /* clear rirb status */ 1248 1248 azx_writeb(chip, RIRBSTS, RIRB_INT_MASK); ··· 1451 1451 1452 1452 #if 0 1453 1453 /* clear state status int */ 1454 - if (azx_readb(chip, STATESTS) & 0x04) 1455 - azx_writeb(chip, STATESTS, 0x04); 1454 + if (azx_readw(chip, STATESTS) & 0x04) 1455 + azx_writew(chip, STATESTS, 0x04); 1456 1456 #endif 1457 1457 spin_unlock(&chip->reg_lock); 1458 1458 ··· 2971 2971 struct snd_card *card = dev_get_drvdata(dev); 2972 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 2978 azx_stop_chip(chip); 2975 2979 azx_enter_link_reset(chip); 2976 2980 azx_clear_irq_pending(chip); ··· 2987 2983 { 2988 2984 struct snd_card *card = dev_get_drvdata(dev); 2989 2985 struct azx *chip = card->private_data; 2986 + struct hda_bus *bus; 2987 + struct hda_codec *codec; 2988 + int status; 2990 2989 2991 2990 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) 2992 2991 hda_display_power(true); 2992 + 2993 + /* Read STATESTS before controller reset */ 2994 + status = azx_readw(chip, STATESTS); 2995 + 2993 2996 azx_init_pci(chip); 2994 2997 azx_init_chip(chip, 1); 2998 + 2999 + bus = chip->bus; 3000 + if (status && bus) { 3001 + list_for_each_entry(codec, &bus->codec_list, list) 3002 + if (status & (1 << codec->addr)) 3003 + queue_delayed_work(codec->bus->workq, 3004 + &codec->jackpoll_work, codec->jackpoll_interval); 3005 + } 3006 + 3007 + /* disable controller Wake Up event*/ 3008 + azx_writew(chip, WAKEEN, azx_readw(chip, WAKEEN) & 3009 + ~STATESTS_INT_MASK); 3010 + 2995 3011 return 0; 2996 3012 } 2997 3013 ··· 3855 3831 3856 3832 /* Request power well for Haswell HDA controller and codec */ 3857 3833 if (chip->driver_caps & AZX_DCAPS_I915_POWERWELL) { 3834 + #ifdef CONFIG_SND_HDA_I915 3858 3835 err = hda_i915_init(); 3859 3836 if (err < 0) { 3860 3837 snd_printk(KERN_ERR SFX "Error request power-well from i915\n"); 3861 3838 goto out_free; 3862 3839 } 3840 + #endif 3863 3841 hda_display_power(true); 3864 3842 } 3865 3843
+14 -8
sound/pci/hda/hda_jack.c
··· 194 194 EXPORT_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 198 * @codec: the CODEC to sense 199 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 */ 203 - int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid) 204 + int 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 - return get_jack_plug_state(sense); 206 + struct hda_jack_tbl *jack = snd_hda_jack_tbl_get(codec, nid); 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 } 208 - EXPORT_SYMBOL_HDA(snd_hda_jack_detect); 214 + EXPORT_SYMBOL_HDA(snd_hda_jack_detect_state); 209 215 210 216 /** 211 217 * snd_hda_jack_detect_enable - enable the jack-detection ··· 253 247 int snd_hda_jack_set_gating_jack(struct hda_codec *codec, hda_nid_t gated_nid, 254 248 hda_nid_t gating_nid) 255 249 { 256 - struct hda_jack_tbl *gated = snd_hda_jack_tbl_get(codec, gated_nid); 257 - struct hda_jack_tbl *gating = snd_hda_jack_tbl_get(codec, gating_nid); 250 + struct hda_jack_tbl *gated = snd_hda_jack_tbl_new(codec, gated_nid); 251 + struct hda_jack_tbl *gating = snd_hda_jack_tbl_new(codec, gating_nid); 258 252 259 253 if (!gated || !gating) 260 254 return -EINVAL;
+12 -1
sound/pci/hda/hda_jack.h
··· 75 75 hda_nid_t gating_nid); 76 76 77 77 u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid); 78 - int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); 78 + 79 + /* the jack state returned from snd_hda_jack_detect_state() */ 80 + enum { 81 + HDA_JACK_NOT_PRESENT, HDA_JACK_PRESENT, HDA_JACK_PHANTOM, 82 + }; 83 + 84 + int snd_hda_jack_detect_state(struct hda_codec *codec, hda_nid_t nid); 85 + 86 + static 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 80 91 bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid); 81 92
+33
sound/pci/hda/hda_proc.c
··· 582 582 print_nid_array(buffer, codec, nid, &codec->nids); 583 583 } 584 584 585 + static 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 + 585 615 static void print_codec_info(struct snd_info_entry *entry, 586 616 struct snd_info_buffer *buffer) 587 617 { ··· 780 750 snd_iprintf(buffer, " Delay: %d samples\n", 781 751 (wid_caps & AC_WCAP_DELAY) >> 782 752 AC_WCAP_DELAY_SHIFT); 753 + 754 + if (wid_type == AC_WID_PIN && codec->dp_mst) 755 + print_device_list(buffer, codec, nid); 783 756 784 757 if (wid_caps & AC_WCAP_CONN_LIST) 785 758 print_conn_list(buffer, codec, nid, wid_type,
+177 -4351
sound/pci/hda/patch_analog.c
··· 32 32 #include "hda_jack.h" 33 33 #include "hda_generic.h" 34 34 35 - #define ENABLE_AD_STATIC_QUIRKS 36 35 37 36 struct ad198x_spec { 38 37 struct hda_gen_spec gen; ··· 42 43 hda_nid_t eapd_nid; 43 44 44 45 unsigned int beep_amp; /* beep amp value, set via set_beep_amp() */ 45 - 46 - #ifdef ENABLE_AD_STATIC_QUIRKS 47 - const struct snd_kcontrol_new *mixers[6]; 48 - int num_mixers; 49 - const struct hda_verb *init_verbs[6]; /* initialization verbs 50 - * don't forget NULL termination! 51 - */ 52 - unsigned int num_init_verbs; 53 - 54 - /* playback */ 55 - struct hda_multi_out multiout; /* playback set-up 56 - * max_channels, dacs must be set 57 - * dig_out_nid and hp_nid are optional 58 - */ 59 - unsigned int cur_eapd; 60 - unsigned int need_dac_fix; 61 - 62 - /* capture */ 63 - unsigned int num_adc_nids; 64 - const hda_nid_t *adc_nids; 65 - hda_nid_t dig_in_nid; /* digital-in NID; optional */ 66 - 67 - /* capture source */ 68 - const struct hda_input_mux *input_mux; 69 - const hda_nid_t *capsrc_nids; 70 - unsigned int cur_mux[3]; 71 - 72 - /* channel model */ 73 - const struct hda_channel_mode *channel_mode; 74 - int num_channel_mode; 75 - 76 - /* PCM information */ 77 - struct hda_pcm pcm_rec[3]; /* used in alc_build_pcms() */ 78 - 79 - unsigned int spdif_route; 80 - 81 - unsigned int jack_present: 1; 82 - unsigned int inv_jack_detect: 1;/* inverted jack-detection */ 83 - unsigned int analog_beep: 1; /* analog beep input present */ 84 - unsigned int avoid_init_slave_vol:1; 85 - 86 - #ifdef CONFIG_PM 87 - struct hda_loopback_check loopback; 88 - #endif 89 - /* for virtual master */ 90 - hda_nid_t vmaster_nid; 91 - const char * const *slave_vols; 92 - const char * const *slave_sws; 93 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 94 46 }; 95 47 96 - #ifdef ENABLE_AD_STATIC_QUIRKS 97 - /* 98 - * input MUX handling (common part) 99 - */ 100 - static int ad198x_mux_enum_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 101 - { 102 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 103 - struct ad198x_spec *spec = codec->spec; 104 - 105 - return snd_hda_input_mux_info(spec->input_mux, uinfo); 106 - } 107 - 108 - static int ad198x_mux_enum_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 109 - { 110 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 111 - struct ad198x_spec *spec = codec->spec; 112 - unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 113 - 114 - ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx]; 115 - return 0; 116 - } 117 - 118 - static int ad198x_mux_enum_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 119 - { 120 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 121 - struct ad198x_spec *spec = codec->spec; 122 - unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id); 123 - 124 - return snd_hda_input_mux_put(codec, spec->input_mux, ucontrol, 125 - spec->capsrc_nids[adc_idx], 126 - &spec->cur_mux[adc_idx]); 127 - } 128 - 129 - /* 130 - * initialization (common callbacks) 131 - */ 132 - static int ad198x_init(struct hda_codec *codec) 133 - { 134 - struct ad198x_spec *spec = codec->spec; 135 - int i; 136 - 137 - for (i = 0; i < spec->num_init_verbs; i++) 138 - snd_hda_sequence_write(codec, spec->init_verbs[i]); 139 - return 0; 140 - } 141 - 142 - static const char * const ad_slave_pfxs[] = { 143 - "Front", "Surround", "Center", "LFE", "Side", 144 - "Headphone", "Mono", "Speaker", "IEC958", 145 - NULL 146 - }; 147 - 148 - static const char * const ad1988_6stack_fp_slave_pfxs[] = { 149 - "Front", "Surround", "Center", "LFE", "Side", "IEC958", 150 - NULL 151 - }; 152 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 153 48 154 49 #ifdef CONFIG_SND_HDA_INPUT_BEEP 155 50 /* additional beep mixers; the actual parameters are overwritten at build */ 156 51 static const struct snd_kcontrol_new ad_beep_mixer[] = { 157 52 HDA_CODEC_VOLUME("Beep Playback Volume", 0, 0, HDA_OUTPUT), 158 53 HDA_CODEC_MUTE_BEEP("Beep Playback Switch", 0, 0, HDA_OUTPUT), 159 - { } /* end */ 160 - }; 161 - 162 - static const struct snd_kcontrol_new ad_beep2_mixer[] = { 163 - HDA_CODEC_VOLUME("Digital Beep Playback Volume", 0, 0, HDA_OUTPUT), 164 - HDA_CODEC_MUTE_BEEP("Digital Beep Playback Switch", 0, 0, HDA_OUTPUT), 165 54 { } /* end */ 166 55 }; 167 56 ··· 68 181 if (!spec->beep_amp) 69 182 return 0; 70 183 71 - knew = spec->analog_beep ? ad_beep2_mixer : ad_beep_mixer; 72 - for ( ; knew->name; knew++) { 184 + for (knew = ad_beep_mixer ; knew->name; knew++) { 73 185 int err; 74 186 struct snd_kcontrol *kctl; 75 187 kctl = snd_ctl_new1(knew, codec); ··· 85 199 #define create_beep_ctls(codec) 0 86 200 #endif 87 201 88 - #ifdef ENABLE_AD_STATIC_QUIRKS 89 - static int ad198x_build_controls(struct hda_codec *codec) 90 - { 91 - struct ad198x_spec *spec = codec->spec; 92 - struct snd_kcontrol *kctl; 93 - unsigned int i; 94 - int err; 95 - 96 - for (i = 0; i < spec->num_mixers; i++) { 97 - err = snd_hda_add_new_ctls(codec, spec->mixers[i]); 98 - if (err < 0) 99 - return err; 100 - } 101 - if (spec->multiout.dig_out_nid) { 102 - err = snd_hda_create_spdif_out_ctls(codec, 103 - spec->multiout.dig_out_nid, 104 - spec->multiout.dig_out_nid); 105 - if (err < 0) 106 - return err; 107 - err = snd_hda_create_spdif_share_sw(codec, 108 - &spec->multiout); 109 - if (err < 0) 110 - return err; 111 - spec->multiout.share_spdif = 1; 112 - } 113 - if (spec->dig_in_nid) { 114 - err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid); 115 - if (err < 0) 116 - return err; 117 - } 118 - 119 - /* create beep controls if needed */ 120 - err = create_beep_ctls(codec); 121 - if (err < 0) 122 - return err; 123 - 124 - /* if we have no master control, let's create it */ 125 - if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { 126 - unsigned int vmaster_tlv[4]; 127 - snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 128 - HDA_OUTPUT, vmaster_tlv); 129 - err = __snd_hda_add_vmaster(codec, "Master Playback Volume", 130 - vmaster_tlv, 131 - (spec->slave_vols ? 132 - spec->slave_vols : ad_slave_pfxs), 133 - "Playback Volume", 134 - !spec->avoid_init_slave_vol, NULL); 135 - if (err < 0) 136 - return err; 137 - } 138 - if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { 139 - err = snd_hda_add_vmaster(codec, "Master Playback Switch", 140 - NULL, 141 - (spec->slave_sws ? 142 - spec->slave_sws : ad_slave_pfxs), 143 - "Playback Switch"); 144 - if (err < 0) 145 - return err; 146 - } 147 - 148 - /* assign Capture Source enums to NID */ 149 - kctl = snd_hda_find_mixer_ctl(codec, "Capture Source"); 150 - if (!kctl) 151 - kctl = snd_hda_find_mixer_ctl(codec, "Input Source"); 152 - for (i = 0; kctl && i < kctl->count; i++) { 153 - err = snd_hda_add_nid(codec, kctl, i, spec->capsrc_nids[i]); 154 - if (err < 0) 155 - return err; 156 - } 157 - 158 - /* assign IEC958 enums to NID */ 159 - kctl = snd_hda_find_mixer_ctl(codec, 160 - SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source"); 161 - if (kctl) { 162 - err = snd_hda_add_nid(codec, kctl, 0, 163 - spec->multiout.dig_out_nid); 164 - if (err < 0) 165 - return err; 166 - } 167 - 168 - return 0; 169 - } 170 - 171 - #ifdef CONFIG_PM 172 - static int ad198x_check_power_status(struct hda_codec *codec, hda_nid_t nid) 173 - { 174 - struct ad198x_spec *spec = codec->spec; 175 - return snd_hda_check_amp_list_power(codec, &spec->loopback, nid); 176 - } 177 - #endif 178 - 179 - /* 180 - * Analog playback callbacks 181 - */ 182 - static int ad198x_playback_pcm_open(struct hda_pcm_stream *hinfo, 183 - struct hda_codec *codec, 184 - struct snd_pcm_substream *substream) 185 - { 186 - struct ad198x_spec *spec = codec->spec; 187 - return snd_hda_multi_out_analog_open(codec, &spec->multiout, substream, 188 - hinfo); 189 - } 190 - 191 - static int ad198x_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 192 - struct hda_codec *codec, 193 - unsigned int stream_tag, 194 - unsigned int format, 195 - struct snd_pcm_substream *substream) 196 - { 197 - struct ad198x_spec *spec = codec->spec; 198 - return snd_hda_multi_out_analog_prepare(codec, &spec->multiout, stream_tag, 199 - format, substream); 200 - } 201 - 202 - static int ad198x_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 203 - struct hda_codec *codec, 204 - struct snd_pcm_substream *substream) 205 - { 206 - struct ad198x_spec *spec = codec->spec; 207 - return snd_hda_multi_out_analog_cleanup(codec, &spec->multiout); 208 - } 209 - 210 - /* 211 - * Digital out 212 - */ 213 - static int ad198x_dig_playback_pcm_open(struct hda_pcm_stream *hinfo, 214 - struct hda_codec *codec, 215 - struct snd_pcm_substream *substream) 216 - { 217 - struct ad198x_spec *spec = codec->spec; 218 - return snd_hda_multi_out_dig_open(codec, &spec->multiout); 219 - } 220 - 221 - static int ad198x_dig_playback_pcm_close(struct hda_pcm_stream *hinfo, 222 - struct hda_codec *codec, 223 - struct snd_pcm_substream *substream) 224 - { 225 - struct ad198x_spec *spec = codec->spec; 226 - return snd_hda_multi_out_dig_close(codec, &spec->multiout); 227 - } 228 - 229 - static int ad198x_dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo, 230 - struct hda_codec *codec, 231 - unsigned int stream_tag, 232 - unsigned int format, 233 - struct snd_pcm_substream *substream) 234 - { 235 - struct ad198x_spec *spec = codec->spec; 236 - return snd_hda_multi_out_dig_prepare(codec, &spec->multiout, stream_tag, 237 - format, substream); 238 - } 239 - 240 - static int ad198x_dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo, 241 - struct hda_codec *codec, 242 - struct snd_pcm_substream *substream) 243 - { 244 - struct ad198x_spec *spec = codec->spec; 245 - return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout); 246 - } 247 - 248 - /* 249 - * Analog capture 250 - */ 251 - static int ad198x_capture_pcm_prepare(struct hda_pcm_stream *hinfo, 252 - struct hda_codec *codec, 253 - unsigned int stream_tag, 254 - unsigned int format, 255 - struct snd_pcm_substream *substream) 256 - { 257 - struct ad198x_spec *spec = codec->spec; 258 - snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number], 259 - stream_tag, 0, format); 260 - return 0; 261 - } 262 - 263 - static int ad198x_capture_pcm_cleanup(struct hda_pcm_stream *hinfo, 264 - struct hda_codec *codec, 265 - struct snd_pcm_substream *substream) 266 - { 267 - struct ad198x_spec *spec = codec->spec; 268 - snd_hda_codec_cleanup_stream(codec, spec->adc_nids[substream->number]); 269 - return 0; 270 - } 271 - 272 - /* 273 - */ 274 - static const struct hda_pcm_stream ad198x_pcm_analog_playback = { 275 - .substreams = 1, 276 - .channels_min = 2, 277 - .channels_max = 6, /* changed later */ 278 - .nid = 0, /* fill later */ 279 - .ops = { 280 - .open = ad198x_playback_pcm_open, 281 - .prepare = ad198x_playback_pcm_prepare, 282 - .cleanup = ad198x_playback_pcm_cleanup, 283 - }, 284 - }; 285 - 286 - static const struct hda_pcm_stream ad198x_pcm_analog_capture = { 287 - .substreams = 1, 288 - .channels_min = 2, 289 - .channels_max = 2, 290 - .nid = 0, /* fill later */ 291 - .ops = { 292 - .prepare = ad198x_capture_pcm_prepare, 293 - .cleanup = ad198x_capture_pcm_cleanup 294 - }, 295 - }; 296 - 297 - static const struct hda_pcm_stream ad198x_pcm_digital_playback = { 298 - .substreams = 1, 299 - .channels_min = 2, 300 - .channels_max = 2, 301 - .nid = 0, /* fill later */ 302 - .ops = { 303 - .open = ad198x_dig_playback_pcm_open, 304 - .close = ad198x_dig_playback_pcm_close, 305 - .prepare = ad198x_dig_playback_pcm_prepare, 306 - .cleanup = ad198x_dig_playback_pcm_cleanup 307 - }, 308 - }; 309 - 310 - static const struct hda_pcm_stream ad198x_pcm_digital_capture = { 311 - .substreams = 1, 312 - .channels_min = 2, 313 - .channels_max = 2, 314 - /* NID is set in alc_build_pcms */ 315 - }; 316 - 317 - static int ad198x_build_pcms(struct hda_codec *codec) 318 - { 319 - struct ad198x_spec *spec = codec->spec; 320 - struct hda_pcm *info = spec->pcm_rec; 321 - 322 - codec->num_pcms = 1; 323 - codec->pcm_info = info; 324 - 325 - info->name = "AD198x Analog"; 326 - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_analog_playback; 327 - info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max = spec->multiout.max_channels; 328 - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0]; 329 - info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_analog_capture; 330 - info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams = spec->num_adc_nids; 331 - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0]; 332 - 333 - if (spec->multiout.dig_out_nid) { 334 - info++; 335 - codec->num_pcms++; 336 - codec->spdif_status_reset = 1; 337 - info->name = "AD198x Digital"; 338 - info->pcm_type = HDA_PCM_TYPE_SPDIF; 339 - info->stream[SNDRV_PCM_STREAM_PLAYBACK] = ad198x_pcm_digital_playback; 340 - info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid; 341 - if (spec->dig_in_nid) { 342 - info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad198x_pcm_digital_capture; 343 - info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid; 344 - } 345 - } 346 - 347 - return 0; 348 - } 349 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 350 202 351 203 static void ad198x_power_eapd_write(struct hda_codec *codec, hda_nid_t front, 352 204 hda_nid_t hp) ··· 131 507 ad198x_power_eapd(codec); 132 508 } 133 509 134 - static void ad198x_free(struct hda_codec *codec) 135 - { 136 - struct ad198x_spec *spec = codec->spec; 137 - 138 - if (!spec) 139 - return; 140 - 141 - snd_hda_gen_spec_free(&spec->gen); 142 - kfree(spec); 143 - snd_hda_detach_beep_device(codec); 144 - } 145 - 146 510 #ifdef CONFIG_PM 147 511 static int ad198x_suspend(struct hda_codec *codec) 148 512 { ··· 138 526 return 0; 139 527 } 140 528 #endif 141 - 142 - #ifdef ENABLE_AD_STATIC_QUIRKS 143 - static const struct hda_codec_ops ad198x_patch_ops = { 144 - .build_controls = ad198x_build_controls, 145 - .build_pcms = ad198x_build_pcms, 146 - .init = ad198x_init, 147 - .free = ad198x_free, 148 - #ifdef CONFIG_PM 149 - .check_power_status = ad198x_check_power_status, 150 - .suspend = ad198x_suspend, 151 - #endif 152 - .reboot_notify = ad198x_shutup, 153 - }; 154 - 155 - 156 - /* 157 - * EAPD control 158 - * the private value = nid 159 - */ 160 - #define ad198x_eapd_info snd_ctl_boolean_mono_info 161 - 162 - static int ad198x_eapd_get(struct snd_kcontrol *kcontrol, 163 - struct snd_ctl_elem_value *ucontrol) 164 - { 165 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 166 - struct ad198x_spec *spec = codec->spec; 167 - if (codec->inv_eapd) 168 - ucontrol->value.integer.value[0] = ! spec->cur_eapd; 169 - else 170 - ucontrol->value.integer.value[0] = spec->cur_eapd; 171 - return 0; 172 - } 173 - 174 - static int ad198x_eapd_put(struct snd_kcontrol *kcontrol, 175 - struct snd_ctl_elem_value *ucontrol) 176 - { 177 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 178 - struct ad198x_spec *spec = codec->spec; 179 - hda_nid_t nid = kcontrol->private_value & 0xff; 180 - unsigned int eapd; 181 - eapd = !!ucontrol->value.integer.value[0]; 182 - if (codec->inv_eapd) 183 - eapd = !eapd; 184 - if (eapd == spec->cur_eapd) 185 - return 0; 186 - spec->cur_eapd = eapd; 187 - snd_hda_codec_write_cache(codec, nid, 188 - 0, AC_VERB_SET_EAPD_BTLENABLE, 189 - eapd ? 0x02 : 0x00); 190 - return 1; 191 - } 192 - 193 - static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, 194 - struct snd_ctl_elem_info *uinfo); 195 - static int ad198x_ch_mode_get(struct snd_kcontrol *kcontrol, 196 - struct snd_ctl_elem_value *ucontrol); 197 - static int ad198x_ch_mode_put(struct snd_kcontrol *kcontrol, 198 - struct snd_ctl_elem_value *ucontrol); 199 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 200 529 201 530 202 531 /* ··· 199 646 * AD1986A specific 200 647 */ 201 648 202 - #ifdef ENABLE_AD_STATIC_QUIRKS 203 - #define AD1986A_SPDIF_OUT 0x02 204 - #define AD1986A_FRONT_DAC 0x03 205 - #define AD1986A_SURR_DAC 0x04 206 - #define AD1986A_CLFE_DAC 0x05 207 - #define AD1986A_ADC 0x06 208 - 209 - static const hda_nid_t ad1986a_dac_nids[3] = { 210 - AD1986A_FRONT_DAC, AD1986A_SURR_DAC, AD1986A_CLFE_DAC 211 - }; 212 - static const hda_nid_t ad1986a_adc_nids[1] = { AD1986A_ADC }; 213 - static const hda_nid_t ad1986a_capsrc_nids[1] = { 0x12 }; 214 - 215 - static const struct hda_input_mux ad1986a_capture_source = { 216 - .num_items = 7, 217 - .items = { 218 - { "Mic", 0x0 }, 219 - { "CD", 0x1 }, 220 - { "Aux", 0x3 }, 221 - { "Line", 0x4 }, 222 - { "Mix", 0x5 }, 223 - { "Mono", 0x6 }, 224 - { "Phone", 0x7 }, 225 - }, 226 - }; 227 - 228 - 229 - static const struct hda_bind_ctls ad1986a_bind_pcm_vol = { 230 - .ops = &snd_hda_bind_vol, 231 - .values = { 232 - HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), 233 - HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT), 234 - HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT), 235 - 0 236 - }, 237 - }; 238 - 239 - static const struct hda_bind_ctls ad1986a_bind_pcm_sw = { 240 - .ops = &snd_hda_bind_sw, 241 - .values = { 242 - HDA_COMPOSE_AMP_VAL(AD1986A_FRONT_DAC, 3, 0, HDA_OUTPUT), 243 - HDA_COMPOSE_AMP_VAL(AD1986A_SURR_DAC, 3, 0, HDA_OUTPUT), 244 - HDA_COMPOSE_AMP_VAL(AD1986A_CLFE_DAC, 3, 0, HDA_OUTPUT), 245 - 0 246 - }, 247 - }; 248 - 249 - /* 250 - * mixers 251 - */ 252 - static const struct snd_kcontrol_new ad1986a_mixers[] = { 253 - /* 254 - * bind volumes/mutes of 3 DACs as a single PCM control for simplicity 255 - */ 256 - HDA_BIND_VOL("PCM Playback Volume", &ad1986a_bind_pcm_vol), 257 - HDA_BIND_SW("PCM Playback Switch", &ad1986a_bind_pcm_sw), 258 - HDA_CODEC_VOLUME("Front Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 259 - HDA_CODEC_MUTE("Front Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 260 - HDA_CODEC_VOLUME("Surround Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 261 - HDA_CODEC_MUTE("Surround Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 262 - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x1d, 1, 0x0, HDA_OUTPUT), 263 - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x1d, 2, 0x0, HDA_OUTPUT), 264 - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x1d, 1, 0x0, HDA_OUTPUT), 265 - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x1d, 2, 0x0, HDA_OUTPUT), 266 - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x1a, 0x0, HDA_OUTPUT), 267 - HDA_CODEC_MUTE("Headphone Playback Switch", 0x1a, 0x0, HDA_OUTPUT), 268 - HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), 269 - HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), 270 - HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), 271 - HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), 272 - HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), 273 - HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 274 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 275 - HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 276 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT), 277 - HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 278 - HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), 279 - HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 280 - HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 281 - { 282 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 283 - .name = "Capture Source", 284 - .info = ad198x_mux_enum_info, 285 - .get = ad198x_mux_enum_get, 286 - .put = ad198x_mux_enum_put, 287 - }, 288 - HDA_CODEC_MUTE("Stereo Downmix Switch", 0x09, 0x0, HDA_OUTPUT), 289 - { } /* end */ 290 - }; 291 - 292 - /* additional mixers for 3stack mode */ 293 - static const struct snd_kcontrol_new ad1986a_3st_mixers[] = { 294 - { 295 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 296 - .name = "Channel Mode", 297 - .info = ad198x_ch_mode_info, 298 - .get = ad198x_ch_mode_get, 299 - .put = ad198x_ch_mode_put, 300 - }, 301 - { } /* end */ 302 - }; 303 - 304 - /* laptop model - 2ch only */ 305 - static const hda_nid_t ad1986a_laptop_dac_nids[1] = { AD1986A_FRONT_DAC }; 306 - 307 - /* master controls both pins 0x1a and 0x1b */ 308 - static const struct hda_bind_ctls ad1986a_laptop_master_vol = { 309 - .ops = &snd_hda_bind_vol, 310 - .values = { 311 - HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 312 - HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 313 - 0, 314 - }, 315 - }; 316 - 317 - static const struct hda_bind_ctls ad1986a_laptop_master_sw = { 318 - .ops = &snd_hda_bind_sw, 319 - .values = { 320 - HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 321 - HDA_COMPOSE_AMP_VAL(0x1b, 3, 0, HDA_OUTPUT), 322 - 0, 323 - }, 324 - }; 325 - 326 - static const struct snd_kcontrol_new ad1986a_laptop_mixers[] = { 327 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 328 - HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 329 - HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 330 - HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), 331 - HDA_CODEC_VOLUME("CD Playback Volume", 0x15, 0x0, HDA_OUTPUT), 332 - HDA_CODEC_MUTE("CD Playback Switch", 0x15, 0x0, HDA_OUTPUT), 333 - HDA_CODEC_VOLUME("Line Playback Volume", 0x17, 0x0, HDA_OUTPUT), 334 - HDA_CODEC_MUTE("Line Playback Switch", 0x17, 0x0, HDA_OUTPUT), 335 - HDA_CODEC_VOLUME("Aux Playback Volume", 0x16, 0x0, HDA_OUTPUT), 336 - HDA_CODEC_MUTE("Aux Playback Switch", 0x16, 0x0, HDA_OUTPUT), 337 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 338 - HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 339 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT), 340 - /* 341 - HDA_CODEC_VOLUME("Mono Playback Volume", 0x1e, 0x0, HDA_OUTPUT), 342 - HDA_CODEC_MUTE("Mono Playback Switch", 0x1e, 0x0, HDA_OUTPUT), */ 343 - HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 344 - HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 345 - { 346 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 347 - .name = "Capture Source", 348 - .info = ad198x_mux_enum_info, 349 - .get = ad198x_mux_enum_get, 350 - .put = ad198x_mux_enum_put, 351 - }, 352 - { } /* end */ 353 - }; 354 - 355 - /* laptop-eapd model - 2ch only */ 356 - 357 - static const struct hda_input_mux ad1986a_laptop_eapd_capture_source = { 358 - .num_items = 3, 359 - .items = { 360 - { "Mic", 0x0 }, 361 - { "Internal Mic", 0x4 }, 362 - { "Mix", 0x5 }, 363 - }, 364 - }; 365 - 366 - static const struct hda_input_mux ad1986a_automic_capture_source = { 367 - .num_items = 2, 368 - .items = { 369 - { "Mic", 0x0 }, 370 - { "Mix", 0x5 }, 371 - }, 372 - }; 373 - 374 - static const struct snd_kcontrol_new ad1986a_laptop_master_mixers[] = { 375 - HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 376 - HDA_BIND_SW("Master Playback Switch", &ad1986a_laptop_master_sw), 377 - { } /* end */ 378 - }; 379 - 380 - static const struct snd_kcontrol_new ad1986a_laptop_eapd_mixers[] = { 381 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x03, 0x0, HDA_OUTPUT), 382 - HDA_CODEC_MUTE("PCM Playback Switch", 0x03, 0x0, HDA_OUTPUT), 383 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 384 - HDA_CODEC_MUTE("Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 385 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x0f, 0x0, HDA_OUTPUT), 386 - HDA_CODEC_VOLUME("Capture Volume", 0x12, 0x0, HDA_OUTPUT), 387 - HDA_CODEC_MUTE("Capture Switch", 0x12, 0x0, HDA_OUTPUT), 388 - { 389 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 390 - .name = "Capture Source", 391 - .info = ad198x_mux_enum_info, 392 - .get = ad198x_mux_enum_get, 393 - .put = ad198x_mux_enum_put, 394 - }, 395 - { 396 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 397 - .name = "External Amplifier", 398 - .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, 399 - .info = ad198x_eapd_info, 400 - .get = ad198x_eapd_get, 401 - .put = ad198x_eapd_put, 402 - .private_value = 0x1b, /* port-D */ 403 - }, 404 - { } /* end */ 405 - }; 406 - 407 - static const struct snd_kcontrol_new ad1986a_laptop_intmic_mixers[] = { 408 - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x17, 0, HDA_OUTPUT), 409 - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x17, 0, HDA_OUTPUT), 410 - { } /* end */ 411 - }; 412 - 413 - /* re-connect the mic boost input according to the jack sensing */ 414 - static void ad1986a_automic(struct hda_codec *codec) 415 - { 416 - unsigned int present; 417 - present = snd_hda_jack_detect(codec, 0x1f); 418 - /* 0 = 0x1f, 2 = 0x1d, 4 = mixed */ 419 - snd_hda_codec_write(codec, 0x0f, 0, AC_VERB_SET_CONNECT_SEL, 420 - present ? 0 : 2); 421 - } 422 - 423 - #define AD1986A_MIC_EVENT 0x36 424 - 425 - static void ad1986a_automic_unsol_event(struct hda_codec *codec, 426 - unsigned int res) 427 - { 428 - if ((res >> 26) != AD1986A_MIC_EVENT) 429 - return; 430 - ad1986a_automic(codec); 431 - } 432 - 433 - static int ad1986a_automic_init(struct hda_codec *codec) 434 - { 435 - ad198x_init(codec); 436 - ad1986a_automic(codec); 437 - return 0; 438 - } 439 - 440 - /* laptop-automute - 2ch only */ 441 - 442 - static void ad1986a_update_hp(struct hda_codec *codec) 443 - { 444 - struct ad198x_spec *spec = codec->spec; 445 - unsigned int mute; 446 - 447 - if (spec->jack_present) 448 - mute = HDA_AMP_MUTE; /* mute internal speaker */ 449 - else 450 - /* unmute internal speaker if necessary */ 451 - mute = snd_hda_codec_amp_read(codec, 0x1a, 0, HDA_OUTPUT, 0); 452 - snd_hda_codec_amp_stereo(codec, 0x1b, HDA_OUTPUT, 0, 453 - HDA_AMP_MUTE, mute); 454 - } 455 - 456 - static void ad1986a_hp_automute(struct hda_codec *codec) 457 - { 458 - struct ad198x_spec *spec = codec->spec; 459 - 460 - spec->jack_present = snd_hda_jack_detect(codec, 0x1a); 461 - if (spec->inv_jack_detect) 462 - spec->jack_present = !spec->jack_present; 463 - ad1986a_update_hp(codec); 464 - } 465 - 466 - #define AD1986A_HP_EVENT 0x37 467 - 468 - static void ad1986a_hp_unsol_event(struct hda_codec *codec, unsigned int res) 469 - { 470 - if ((res >> 26) != AD1986A_HP_EVENT) 471 - return; 472 - ad1986a_hp_automute(codec); 473 - } 474 - 475 - static int ad1986a_hp_init(struct hda_codec *codec) 476 - { 477 - ad198x_init(codec); 478 - ad1986a_hp_automute(codec); 479 - return 0; 480 - } 481 - 482 - /* bind hp and internal speaker mute (with plug check) */ 483 - static int ad1986a_hp_master_sw_put(struct snd_kcontrol *kcontrol, 484 - struct snd_ctl_elem_value *ucontrol) 485 - { 486 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 487 - int change = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 488 - if (change) 489 - ad1986a_update_hp(codec); 490 - return change; 491 - } 492 - 493 - static const struct snd_kcontrol_new ad1986a_automute_master_mixers[] = { 494 - HDA_BIND_VOL("Master Playback Volume", &ad1986a_laptop_master_vol), 495 - { 496 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 497 - .name = "Master Playback Switch", 498 - .subdevice = HDA_SUBDEV_AMP_FLAG, 499 - .info = snd_hda_mixer_amp_switch_info, 500 - .get = snd_hda_mixer_amp_switch_get, 501 - .put = ad1986a_hp_master_sw_put, 502 - .private_value = HDA_COMPOSE_AMP_VAL(0x1a, 3, 0, HDA_OUTPUT), 503 - }, 504 - { } /* end */ 505 - }; 506 - 507 - 508 - /* 509 - * initialization verbs 510 - */ 511 - static const struct hda_verb ad1986a_init_verbs[] = { 512 - /* Front, Surround, CLFE DAC; mute as default */ 513 - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 514 - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 515 - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 516 - /* Downmix - off */ 517 - {0x09, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 518 - /* HP, Line-Out, Surround, CLFE selectors */ 519 - {0x0a, AC_VERB_SET_CONNECT_SEL, 0x0}, 520 - {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, 521 - {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, 522 - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 523 - /* Mono selector */ 524 - {0x0e, AC_VERB_SET_CONNECT_SEL, 0x0}, 525 - /* Mic selector: Mic 1/2 pin */ 526 - {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0}, 527 - /* Line-in selector: Line-in */ 528 - {0x10, AC_VERB_SET_CONNECT_SEL, 0x0}, 529 - /* Mic 1/2 swap */ 530 - {0x11, AC_VERB_SET_CONNECT_SEL, 0x0}, 531 - /* Record selector: mic */ 532 - {0x12, AC_VERB_SET_CONNECT_SEL, 0x0}, 533 - /* Mic, Phone, CD, Aux, Line-In amp; mute as default */ 534 - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 535 - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 536 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 537 - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 538 - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 539 - /* PC beep */ 540 - {0x18, AC_VERB_SET_CONNECT_SEL, 0x0}, 541 - /* HP, Line-Out, Surround, CLFE, Mono pins; mute as default */ 542 - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 543 - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 544 - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 545 - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 546 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 547 - /* HP Pin */ 548 - {0x1a, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 549 - /* Front, Surround, CLFE Pins */ 550 - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 551 - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 552 - {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 553 - /* Mono Pin */ 554 - {0x1e, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 555 - /* Mic Pin */ 556 - {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 557 - /* Line, Aux, CD, Beep-In Pin */ 558 - {0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 559 - {0x21, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 560 - {0x22, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 561 - {0x23, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 562 - {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 563 - { } /* end */ 564 - }; 565 - 566 - static const struct hda_verb ad1986a_ch2_init[] = { 567 - /* Surround out -> Line In */ 568 - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 569 - /* Line-in selectors */ 570 - { 0x10, AC_VERB_SET_CONNECT_SEL, 0x1 }, 571 - /* CLFE -> Mic in */ 572 - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 573 - /* Mic selector, mix C/LFE (backmic) and Mic (frontmic) */ 574 - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, 575 - { } /* end */ 576 - }; 577 - 578 - static const struct hda_verb ad1986a_ch4_init[] = { 579 - /* Surround out -> Surround */ 580 - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 581 - { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 582 - /* CLFE -> Mic in */ 583 - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 584 - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x4 }, 585 - { } /* end */ 586 - }; 587 - 588 - static const struct hda_verb ad1986a_ch6_init[] = { 589 - /* Surround out -> Surround out */ 590 - { 0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 591 - { 0x10, AC_VERB_SET_CONNECT_SEL, 0x0 }, 592 - /* CLFE -> CLFE */ 593 - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 594 - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x0 }, 595 - { } /* end */ 596 - }; 597 - 598 - static const struct hda_channel_mode ad1986a_modes[3] = { 599 - { 2, ad1986a_ch2_init }, 600 - { 4, ad1986a_ch4_init }, 601 - { 6, ad1986a_ch6_init }, 602 - }; 603 - 604 - /* eapd initialization */ 605 - static const struct hda_verb ad1986a_eapd_init_verbs[] = { 606 - {0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, 607 - {} 608 - }; 609 - 610 - static const struct hda_verb ad1986a_automic_verbs[] = { 611 - {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 612 - {0x1f, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 613 - /*{0x20, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80},*/ 614 - {0x0f, AC_VERB_SET_CONNECT_SEL, 0x0}, 615 - {0x1f, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_MIC_EVENT}, 616 - {} 617 - }; 618 - 619 - /* Ultra initialization */ 620 - static const struct hda_verb ad1986a_ultra_init[] = { 621 - /* eapd initialization */ 622 - { 0x1b, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, 623 - /* CLFE -> Mic in */ 624 - { 0x0f, AC_VERB_SET_CONNECT_SEL, 0x2 }, 625 - { 0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 626 - { 0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080 }, 627 - { } /* end */ 628 - }; 629 - 630 - /* pin sensing on HP jack */ 631 - static const struct hda_verb ad1986a_hp_init_verbs[] = { 632 - {0x1a, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1986A_HP_EVENT}, 633 - {} 634 - }; 635 - 636 - static void ad1986a_samsung_p50_unsol_event(struct hda_codec *codec, 637 - unsigned int res) 638 - { 639 - switch (res >> 26) { 640 - case AD1986A_HP_EVENT: 641 - ad1986a_hp_automute(codec); 642 - break; 643 - case AD1986A_MIC_EVENT: 644 - ad1986a_automic(codec); 645 - break; 646 - } 647 - } 648 - 649 - static int ad1986a_samsung_p50_init(struct hda_codec *codec) 650 - { 651 - ad198x_init(codec); 652 - ad1986a_hp_automute(codec); 653 - ad1986a_automic(codec); 654 - return 0; 655 - } 656 - 657 - 658 - /* models */ 659 - enum { 660 - AD1986A_AUTO, 661 - AD1986A_6STACK, 662 - AD1986A_3STACK, 663 - AD1986A_LAPTOP, 664 - AD1986A_LAPTOP_EAPD, 665 - AD1986A_LAPTOP_AUTOMUTE, 666 - AD1986A_ULTRA, 667 - AD1986A_SAMSUNG, 668 - AD1986A_SAMSUNG_P50, 669 - AD1986A_MODELS 670 - }; 671 - 672 - static const char * const ad1986a_models[AD1986A_MODELS] = { 673 - [AD1986A_AUTO] = "auto", 674 - [AD1986A_6STACK] = "6stack", 675 - [AD1986A_3STACK] = "3stack", 676 - [AD1986A_LAPTOP] = "laptop", 677 - [AD1986A_LAPTOP_EAPD] = "laptop-eapd", 678 - [AD1986A_LAPTOP_AUTOMUTE] = "laptop-automute", 679 - [AD1986A_ULTRA] = "ultra", 680 - [AD1986A_SAMSUNG] = "samsung", 681 - [AD1986A_SAMSUNG_P50] = "samsung-p50", 682 - }; 683 - 684 - static const struct snd_pci_quirk ad1986a_cfg_tbl[] = { 685 - SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_LAPTOP_EAPD), 686 - SND_PCI_QUIRK(0x1043, 0x1153, "ASUS M9", AD1986A_LAPTOP_EAPD), 687 - SND_PCI_QUIRK(0x1043, 0x11f7, "ASUS U5A", AD1986A_LAPTOP_EAPD), 688 - SND_PCI_QUIRK(0x1043, 0x1213, "ASUS A6J", AD1986A_LAPTOP_EAPD), 689 - SND_PCI_QUIRK(0x1043, 0x1263, "ASUS U5F", AD1986A_LAPTOP_EAPD), 690 - SND_PCI_QUIRK(0x1043, 0x1297, "ASUS Z62F", AD1986A_LAPTOP_EAPD), 691 - SND_PCI_QUIRK(0x1043, 0x12b3, "ASUS V1j", AD1986A_LAPTOP_EAPD), 692 - SND_PCI_QUIRK(0x1043, 0x1302, "ASUS W3j", AD1986A_LAPTOP_EAPD), 693 - SND_PCI_QUIRK(0x1043, 0x1443, "ASUS VX1", AD1986A_LAPTOP), 694 - SND_PCI_QUIRK(0x1043, 0x1447, "ASUS A8J", AD1986A_3STACK), 695 - SND_PCI_QUIRK(0x1043, 0x817f, "ASUS P5", AD1986A_3STACK), 696 - SND_PCI_QUIRK(0x1043, 0x818f, "ASUS P5", AD1986A_LAPTOP), 697 - SND_PCI_QUIRK(0x1043, 0x81b3, "ASUS P5", AD1986A_3STACK), 698 - SND_PCI_QUIRK(0x1043, 0x81cb, "ASUS M2N", AD1986A_3STACK), 699 - SND_PCI_QUIRK(0x1043, 0x8234, "ASUS M2N", AD1986A_3STACK), 700 - SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_3STACK), 701 - SND_PCI_QUIRK(0x1179, 0xff40, "Toshiba Satellite L40-10Q", AD1986A_3STACK), 702 - SND_PCI_QUIRK(0x144d, 0xb03c, "Samsung R55", AD1986A_3STACK), 703 - SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_LAPTOP), 704 - SND_PCI_QUIRK(0x144d, 0xc024, "Samsung P50", AD1986A_SAMSUNG_P50), 705 - SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_ULTRA), 706 - SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_SAMSUNG), 707 - SND_PCI_QUIRK(0x144d, 0xc504, "Samsung Q35", AD1986A_3STACK), 708 - SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_LAPTOP), 709 - SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_3STACK), 710 - SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_LAPTOP_AUTOMUTE), 711 - SND_PCI_QUIRK(0x17c0, 0x2017, "Samsung M50", AD1986A_LAPTOP), 712 - {} 713 - }; 714 - 715 - #ifdef CONFIG_PM 716 - static const struct hda_amp_list ad1986a_loopbacks[] = { 717 - { 0x13, HDA_OUTPUT, 0 }, /* Mic */ 718 - { 0x14, HDA_OUTPUT, 0 }, /* Phone */ 719 - { 0x15, HDA_OUTPUT, 0 }, /* CD */ 720 - { 0x16, HDA_OUTPUT, 0 }, /* Aux */ 721 - { 0x17, HDA_OUTPUT, 0 }, /* Line */ 722 - { } /* end */ 723 - }; 724 - #endif 725 - 726 - static int is_jack_available(struct hda_codec *codec, hda_nid_t nid) 727 - { 728 - unsigned int conf = snd_hda_codec_get_pincfg(codec, nid); 729 - return get_defcfg_connect(conf) != AC_JACK_PORT_NONE; 730 - } 731 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 732 - 733 649 static int alloc_ad_spec(struct hda_codec *codec) 734 650 { 735 651 struct ad198x_spec *spec; ··· 225 1203 226 1204 enum { 227 1205 AD1986A_FIXUP_INV_JACK_DETECT, 1206 + AD1986A_FIXUP_ULTRA, 1207 + AD1986A_FIXUP_SAMSUNG, 1208 + AD1986A_FIXUP_3STACK, 1209 + AD1986A_FIXUP_LAPTOP, 1210 + AD1986A_FIXUP_LAPTOP_IMIC, 228 1211 }; 229 1212 230 1213 static const struct hda_fixup ad1986a_fixups[] = { ··· 237 1210 .type = HDA_FIXUP_FUNC, 238 1211 .v.func = ad_fixup_inv_jack_detect, 239 1212 }, 1213 + [AD1986A_FIXUP_ULTRA] = { 1214 + .type = HDA_FIXUP_PINS, 1215 + .v.pins = (const struct hda_pintbl[]) { 1216 + { 0x1b, 0x90170110 }, /* speaker */ 1217 + { 0x1d, 0x90a7013e }, /* int mic */ 1218 + {} 1219 + }, 1220 + }, 1221 + [AD1986A_FIXUP_SAMSUNG] = { 1222 + .type = HDA_FIXUP_PINS, 1223 + .v.pins = (const struct hda_pintbl[]) { 1224 + { 0x1b, 0x90170110 }, /* speaker */ 1225 + { 0x1d, 0x90a7013e }, /* int mic */ 1226 + { 0x20, 0x411111f0 }, /* N/A */ 1227 + { 0x24, 0x411111f0 }, /* N/A */ 1228 + {} 1229 + }, 1230 + }, 1231 + [AD1986A_FIXUP_3STACK] = { 1232 + .type = HDA_FIXUP_PINS, 1233 + .v.pins = (const struct hda_pintbl[]) { 1234 + { 0x1a, 0x02214021 }, /* headphone */ 1235 + { 0x1b, 0x01014011 }, /* front */ 1236 + { 0x1c, 0x01013012 }, /* surround */ 1237 + { 0x1d, 0x01019015 }, /* clfe */ 1238 + { 0x1e, 0x411111f0 }, /* N/A */ 1239 + { 0x1f, 0x02a190f0 }, /* mic */ 1240 + { 0x20, 0x018130f0 }, /* line-in */ 1241 + {} 1242 + }, 1243 + }, 1244 + [AD1986A_FIXUP_LAPTOP] = { 1245 + .type = HDA_FIXUP_PINS, 1246 + .v.pins = (const struct hda_pintbl[]) { 1247 + { 0x1a, 0x02214021 }, /* headphone */ 1248 + { 0x1b, 0x90170110 }, /* speaker */ 1249 + { 0x1c, 0x411111f0 }, /* N/A */ 1250 + { 0x1d, 0x411111f0 }, /* N/A */ 1251 + { 0x1e, 0x411111f0 }, /* N/A */ 1252 + { 0x1f, 0x02a191f0 }, /* mic */ 1253 + { 0x20, 0x411111f0 }, /* N/A */ 1254 + {} 1255 + }, 1256 + }, 1257 + [AD1986A_FIXUP_LAPTOP_IMIC] = { 1258 + .type = HDA_FIXUP_PINS, 1259 + .v.pins = (const struct hda_pintbl[]) { 1260 + { 0x1d, 0x90a7013e }, /* int mic */ 1261 + {} 1262 + }, 1263 + .chained_before = 1, 1264 + .chain_id = AD1986A_FIXUP_LAPTOP, 1265 + }, 240 1266 }; 241 1267 242 1268 static const struct snd_pci_quirk ad1986a_fixup_tbl[] = { 1269 + SND_PCI_QUIRK(0x103c, 0x30af, "HP B2800", AD1986A_FIXUP_LAPTOP_IMIC), 1270 + SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8100, "ASUS P5", AD1986A_FIXUP_3STACK), 1271 + SND_PCI_QUIRK_MASK(0x1043, 0xff00, 0x8200, "ASUS M2", AD1986A_FIXUP_3STACK), 1272 + SND_PCI_QUIRK(0x10de, 0xcb84, "ASUS A8N-VM", AD1986A_FIXUP_3STACK), 1273 + SND_PCI_QUIRK(0x144d, 0xc01e, "FSC V2060", AD1986A_FIXUP_LAPTOP), 1274 + SND_PCI_QUIRK_MASK(0x144d, 0xff00, 0xc000, "Samsung", AD1986A_FIXUP_SAMSUNG), 1275 + SND_PCI_QUIRK(0x144d, 0xc027, "Samsung Q1", AD1986A_FIXUP_ULTRA), 243 1276 SND_PCI_QUIRK(0x17aa, 0x2066, "Lenovo N100", AD1986A_FIXUP_INV_JACK_DETECT), 1277 + SND_PCI_QUIRK(0x17aa, 0x1011, "Lenovo M55", AD1986A_FIXUP_3STACK), 1278 + SND_PCI_QUIRK(0x17aa, 0x1017, "Lenovo A60", AD1986A_FIXUP_3STACK), 1279 + {} 1280 + }; 1281 + 1282 + static const struct hda_model_fixup ad1986a_fixup_models[] = { 1283 + { .id = AD1986A_FIXUP_3STACK, .name = "3stack" }, 1284 + { .id = AD1986A_FIXUP_LAPTOP, .name = "laptop" }, 1285 + { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-imic" }, 1286 + { .id = AD1986A_FIXUP_LAPTOP_IMIC, .name = "laptop-eapd" }, /* alias */ 244 1287 {} 245 1288 }; 246 1289 247 1290 /* 248 1291 */ 249 - static int ad1986a_parse_auto_config(struct hda_codec *codec) 1292 + static int patch_ad1986a(struct hda_codec *codec) 250 1293 { 251 1294 int err; 252 1295 struct ad198x_spec *spec; ··· 341 1244 */ 342 1245 spec->gen.multiout.no_share_stream = 1; 343 1246 344 - snd_hda_pick_fixup(codec, NULL, ad1986a_fixup_tbl, ad1986a_fixups); 1247 + snd_hda_pick_fixup(codec, ad1986a_fixup_models, ad1986a_fixup_tbl, 1248 + ad1986a_fixups); 345 1249 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 346 1250 347 1251 err = ad198x_parse_auto_config(codec); ··· 356 1258 return 0; 357 1259 } 358 1260 359 - #ifdef ENABLE_AD_STATIC_QUIRKS 360 - static int patch_ad1986a(struct hda_codec *codec) 361 - { 362 - struct ad198x_spec *spec; 363 - int err, board_config; 364 - 365 - board_config = snd_hda_check_board_config(codec, AD1986A_MODELS, 366 - ad1986a_models, 367 - ad1986a_cfg_tbl); 368 - if (board_config < 0) { 369 - printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 370 - codec->chip_name); 371 - board_config = AD1986A_AUTO; 372 - } 373 - 374 - if (board_config == AD1986A_AUTO) 375 - return ad1986a_parse_auto_config(codec); 376 - 377 - err = alloc_ad_spec(codec); 378 - if (err < 0) 379 - return err; 380 - spec = codec->spec; 381 - 382 - err = snd_hda_attach_beep_device(codec, 0x19); 383 - if (err < 0) { 384 - ad198x_free(codec); 385 - return err; 386 - } 387 - set_beep_amp(spec, 0x18, 0, HDA_OUTPUT); 388 - 389 - spec->multiout.max_channels = 6; 390 - spec->multiout.num_dacs = ARRAY_SIZE(ad1986a_dac_nids); 391 - spec->multiout.dac_nids = ad1986a_dac_nids; 392 - spec->multiout.dig_out_nid = AD1986A_SPDIF_OUT; 393 - spec->num_adc_nids = 1; 394 - spec->adc_nids = ad1986a_adc_nids; 395 - spec->capsrc_nids = ad1986a_capsrc_nids; 396 - spec->input_mux = &ad1986a_capture_source; 397 - spec->num_mixers = 1; 398 - spec->mixers[0] = ad1986a_mixers; 399 - spec->num_init_verbs = 1; 400 - spec->init_verbs[0] = ad1986a_init_verbs; 401 - #ifdef CONFIG_PM 402 - spec->loopback.amplist = ad1986a_loopbacks; 403 - #endif 404 - spec->vmaster_nid = 0x1b; 405 - codec->inv_eapd = 1; /* AD1986A has the inverted EAPD implementation */ 406 - 407 - codec->patch_ops = ad198x_patch_ops; 408 - 409 - /* override some parameters */ 410 - switch (board_config) { 411 - case AD1986A_3STACK: 412 - spec->num_mixers = 2; 413 - spec->mixers[1] = ad1986a_3st_mixers; 414 - spec->num_init_verbs = 2; 415 - spec->init_verbs[1] = ad1986a_ch2_init; 416 - spec->channel_mode = ad1986a_modes; 417 - spec->num_channel_mode = ARRAY_SIZE(ad1986a_modes); 418 - spec->need_dac_fix = 1; 419 - spec->multiout.max_channels = 2; 420 - spec->multiout.num_dacs = 1; 421 - break; 422 - case AD1986A_LAPTOP: 423 - spec->mixers[0] = ad1986a_laptop_mixers; 424 - spec->multiout.max_channels = 2; 425 - spec->multiout.num_dacs = 1; 426 - spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 427 - break; 428 - case AD1986A_LAPTOP_EAPD: 429 - spec->num_mixers = 3; 430 - spec->mixers[0] = ad1986a_laptop_master_mixers; 431 - spec->mixers[1] = ad1986a_laptop_eapd_mixers; 432 - spec->mixers[2] = ad1986a_laptop_intmic_mixers; 433 - spec->num_init_verbs = 2; 434 - spec->init_verbs[1] = ad1986a_eapd_init_verbs; 435 - spec->multiout.max_channels = 2; 436 - spec->multiout.num_dacs = 1; 437 - spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 438 - if (!is_jack_available(codec, 0x25)) 439 - spec->multiout.dig_out_nid = 0; 440 - spec->input_mux = &ad1986a_laptop_eapd_capture_source; 441 - break; 442 - case AD1986A_SAMSUNG: 443 - spec->num_mixers = 2; 444 - spec->mixers[0] = ad1986a_laptop_master_mixers; 445 - spec->mixers[1] = ad1986a_laptop_eapd_mixers; 446 - spec->num_init_verbs = 3; 447 - spec->init_verbs[1] = ad1986a_eapd_init_verbs; 448 - spec->init_verbs[2] = ad1986a_automic_verbs; 449 - spec->multiout.max_channels = 2; 450 - spec->multiout.num_dacs = 1; 451 - spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 452 - if (!is_jack_available(codec, 0x25)) 453 - spec->multiout.dig_out_nid = 0; 454 - spec->input_mux = &ad1986a_automic_capture_source; 455 - codec->patch_ops.unsol_event = ad1986a_automic_unsol_event; 456 - codec->patch_ops.init = ad1986a_automic_init; 457 - break; 458 - case AD1986A_SAMSUNG_P50: 459 - spec->num_mixers = 2; 460 - spec->mixers[0] = ad1986a_automute_master_mixers; 461 - spec->mixers[1] = ad1986a_laptop_eapd_mixers; 462 - spec->num_init_verbs = 4; 463 - spec->init_verbs[1] = ad1986a_eapd_init_verbs; 464 - spec->init_verbs[2] = ad1986a_automic_verbs; 465 - spec->init_verbs[3] = ad1986a_hp_init_verbs; 466 - spec->multiout.max_channels = 2; 467 - spec->multiout.num_dacs = 1; 468 - spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 469 - if (!is_jack_available(codec, 0x25)) 470 - spec->multiout.dig_out_nid = 0; 471 - spec->input_mux = &ad1986a_automic_capture_source; 472 - codec->patch_ops.unsol_event = ad1986a_samsung_p50_unsol_event; 473 - codec->patch_ops.init = ad1986a_samsung_p50_init; 474 - break; 475 - case AD1986A_LAPTOP_AUTOMUTE: 476 - spec->num_mixers = 3; 477 - spec->mixers[0] = ad1986a_automute_master_mixers; 478 - spec->mixers[1] = ad1986a_laptop_eapd_mixers; 479 - spec->mixers[2] = ad1986a_laptop_intmic_mixers; 480 - spec->num_init_verbs = 3; 481 - spec->init_verbs[1] = ad1986a_eapd_init_verbs; 482 - spec->init_verbs[2] = ad1986a_hp_init_verbs; 483 - spec->multiout.max_channels = 2; 484 - spec->multiout.num_dacs = 1; 485 - spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 486 - if (!is_jack_available(codec, 0x25)) 487 - spec->multiout.dig_out_nid = 0; 488 - spec->input_mux = &ad1986a_laptop_eapd_capture_source; 489 - codec->patch_ops.unsol_event = ad1986a_hp_unsol_event; 490 - codec->patch_ops.init = ad1986a_hp_init; 491 - /* Lenovo N100 seems to report the reversed bit 492 - * for HP jack-sensing 493 - */ 494 - spec->inv_jack_detect = 1; 495 - break; 496 - case AD1986A_ULTRA: 497 - spec->mixers[0] = ad1986a_laptop_eapd_mixers; 498 - spec->num_init_verbs = 2; 499 - spec->init_verbs[1] = ad1986a_ultra_init; 500 - spec->multiout.max_channels = 2; 501 - spec->multiout.num_dacs = 1; 502 - spec->multiout.dac_nids = ad1986a_laptop_dac_nids; 503 - spec->multiout.dig_out_nid = 0; 504 - break; 505 - } 506 - 507 - /* AD1986A has a hardware problem that it can't share a stream 508 - * with multiple output pins. The copy of front to surrounds 509 - * causes noisy or silent outputs at a certain timing, e.g. 510 - * changing the volume. 511 - * So, let's disable the shared stream. 512 - */ 513 - spec->multiout.no_share_stream = 1; 514 - 515 - codec->no_trigger_sense = 1; 516 - codec->no_sticky_stream = 1; 517 - 518 - return 0; 519 - } 520 - #else /* ENABLE_AD_STATIC_QUIRKS */ 521 - #define patch_ad1986a ad1986a_parse_auto_config 522 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 523 1261 524 1262 /* 525 1263 * AD1983 specific 526 1264 */ 527 - 528 - #ifdef ENABLE_AD_STATIC_QUIRKS 529 - #define AD1983_SPDIF_OUT 0x02 530 - #define AD1983_DAC 0x03 531 - #define AD1983_ADC 0x04 532 - 533 - static const hda_nid_t ad1983_dac_nids[1] = { AD1983_DAC }; 534 - static const hda_nid_t ad1983_adc_nids[1] = { AD1983_ADC }; 535 - static const hda_nid_t ad1983_capsrc_nids[1] = { 0x15 }; 536 - 537 - static const struct hda_input_mux ad1983_capture_source = { 538 - .num_items = 4, 539 - .items = { 540 - { "Mic", 0x0 }, 541 - { "Line", 0x1 }, 542 - { "Mix", 0x2 }, 543 - { "Mix Mono", 0x3 }, 544 - }, 545 - }; 546 - 547 - /* 548 - * SPDIF playback route 549 - */ 550 - static int ad1983_spdif_route_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 551 - { 552 - static const char * const texts[] = { "PCM", "ADC" }; 553 - 554 - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 555 - uinfo->count = 1; 556 - uinfo->value.enumerated.items = 2; 557 - if (uinfo->value.enumerated.item > 1) 558 - uinfo->value.enumerated.item = 1; 559 - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 560 - return 0; 561 - } 562 - 563 - static int ad1983_spdif_route_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 564 - { 565 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 566 - struct ad198x_spec *spec = codec->spec; 567 - 568 - ucontrol->value.enumerated.item[0] = spec->spdif_route; 569 - return 0; 570 - } 571 - 572 - static int ad1983_spdif_route_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 573 - { 574 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 575 - struct ad198x_spec *spec = codec->spec; 576 - 577 - if (ucontrol->value.enumerated.item[0] > 1) 578 - return -EINVAL; 579 - if (spec->spdif_route != ucontrol->value.enumerated.item[0]) { 580 - spec->spdif_route = ucontrol->value.enumerated.item[0]; 581 - snd_hda_codec_write_cache(codec, spec->multiout.dig_out_nid, 0, 582 - AC_VERB_SET_CONNECT_SEL, 583 - spec->spdif_route); 584 - return 1; 585 - } 586 - return 0; 587 - } 588 - 589 - static const struct snd_kcontrol_new ad1983_mixers[] = { 590 - HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), 591 - HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), 592 - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), 593 - HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT), 594 - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT), 595 - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT), 596 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 597 - HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 598 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 599 - HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 600 - HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), 601 - HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), 602 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x0c, 0x0, HDA_OUTPUT), 603 - HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 604 - HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 605 - { 606 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 607 - .name = "Capture Source", 608 - .info = ad198x_mux_enum_info, 609 - .get = ad198x_mux_enum_get, 610 - .put = ad198x_mux_enum_put, 611 - }, 612 - { 613 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 614 - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 615 - .info = ad1983_spdif_route_info, 616 - .get = ad1983_spdif_route_get, 617 - .put = ad1983_spdif_route_put, 618 - }, 619 - { } /* end */ 620 - }; 621 - 622 - static const struct hda_verb ad1983_init_verbs[] = { 623 - /* Front, HP, Mono; mute as default */ 624 - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 625 - {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 626 - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 627 - /* Beep, PCM, Mic, Line-In: mute */ 628 - {0x10, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 629 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 630 - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 631 - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 632 - /* Front, HP selectors; from Mix */ 633 - {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 634 - {0x06, AC_VERB_SET_CONNECT_SEL, 0x01}, 635 - /* Mono selector; from Mix */ 636 - {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03}, 637 - /* Mic selector; Mic */ 638 - {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, 639 - /* Line-in selector: Line-in */ 640 - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 641 - /* Mic boost: 0dB */ 642 - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 643 - /* Record selector: mic */ 644 - {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, 645 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 646 - /* SPDIF route: PCM */ 647 - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, 648 - /* Front Pin */ 649 - {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 650 - /* HP Pin */ 651 - {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 652 - /* Mono Pin */ 653 - {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 654 - /* Mic Pin */ 655 - {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 656 - /* Line Pin */ 657 - {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 658 - { } /* end */ 659 - }; 660 - 661 - #ifdef CONFIG_PM 662 - static const struct hda_amp_list ad1983_loopbacks[] = { 663 - { 0x12, HDA_OUTPUT, 0 }, /* Mic */ 664 - { 0x13, HDA_OUTPUT, 0 }, /* Line */ 665 - { } /* end */ 666 - }; 667 - #endif 668 - 669 - /* models */ 670 - enum { 671 - AD1983_AUTO, 672 - AD1983_BASIC, 673 - AD1983_MODELS 674 - }; 675 - 676 - static const char * const ad1983_models[AD1983_MODELS] = { 677 - [AD1983_AUTO] = "auto", 678 - [AD1983_BASIC] = "basic", 679 - }; 680 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 681 - 682 1265 683 1266 /* 684 1267 * SPDIF mux control for AD1983 auto-parser ··· 435 1656 return 0; 436 1657 } 437 1658 438 - static int ad1983_parse_auto_config(struct hda_codec *codec) 1659 + static int patch_ad1983(struct hda_codec *codec) 439 1660 { 440 1661 struct ad198x_spec *spec; 441 1662 int err; ··· 460 1681 return err; 461 1682 } 462 1683 463 - #ifdef ENABLE_AD_STATIC_QUIRKS 464 - static int patch_ad1983(struct hda_codec *codec) 465 - { 466 - struct ad198x_spec *spec; 467 - int board_config; 468 - int err; 469 - 470 - board_config = snd_hda_check_board_config(codec, AD1983_MODELS, 471 - ad1983_models, NULL); 472 - if (board_config < 0) { 473 - printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 474 - codec->chip_name); 475 - board_config = AD1983_AUTO; 476 - } 477 - 478 - if (board_config == AD1983_AUTO) 479 - return ad1983_parse_auto_config(codec); 480 - 481 - err = alloc_ad_spec(codec); 482 - if (err < 0) 483 - return err; 484 - spec = codec->spec; 485 - 486 - err = snd_hda_attach_beep_device(codec, 0x10); 487 - if (err < 0) { 488 - ad198x_free(codec); 489 - return err; 490 - } 491 - set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 492 - 493 - spec->multiout.max_channels = 2; 494 - spec->multiout.num_dacs = ARRAY_SIZE(ad1983_dac_nids); 495 - spec->multiout.dac_nids = ad1983_dac_nids; 496 - spec->multiout.dig_out_nid = AD1983_SPDIF_OUT; 497 - spec->num_adc_nids = 1; 498 - spec->adc_nids = ad1983_adc_nids; 499 - spec->capsrc_nids = ad1983_capsrc_nids; 500 - spec->input_mux = &ad1983_capture_source; 501 - spec->num_mixers = 1; 502 - spec->mixers[0] = ad1983_mixers; 503 - spec->num_init_verbs = 1; 504 - spec->init_verbs[0] = ad1983_init_verbs; 505 - spec->spdif_route = 0; 506 - #ifdef CONFIG_PM 507 - spec->loopback.amplist = ad1983_loopbacks; 508 - #endif 509 - spec->vmaster_nid = 0x05; 510 - 511 - codec->patch_ops = ad198x_patch_ops; 512 - 513 - codec->no_trigger_sense = 1; 514 - codec->no_sticky_stream = 1; 515 - 516 - return 0; 517 - } 518 - #else /* ENABLE_AD_STATIC_QUIRKS */ 519 - #define patch_ad1983 ad1983_parse_auto_config 520 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 521 - 522 1684 523 1685 /* 524 1686 * AD1981 HD specific 525 1687 */ 526 - 527 - #ifdef ENABLE_AD_STATIC_QUIRKS 528 - #define AD1981_SPDIF_OUT 0x02 529 - #define AD1981_DAC 0x03 530 - #define AD1981_ADC 0x04 531 - 532 - static const hda_nid_t ad1981_dac_nids[1] = { AD1981_DAC }; 533 - static const hda_nid_t ad1981_adc_nids[1] = { AD1981_ADC }; 534 - static const hda_nid_t ad1981_capsrc_nids[1] = { 0x15 }; 535 - 536 - /* 0x0c, 0x09, 0x0e, 0x0f, 0x19, 0x05, 0x18, 0x17 */ 537 - static const struct hda_input_mux ad1981_capture_source = { 538 - .num_items = 7, 539 - .items = { 540 - { "Front Mic", 0x0 }, 541 - { "Line", 0x1 }, 542 - { "Mix", 0x2 }, 543 - { "Mix Mono", 0x3 }, 544 - { "CD", 0x4 }, 545 - { "Mic", 0x6 }, 546 - { "Aux", 0x7 }, 547 - }, 548 - }; 549 - 550 - static const struct snd_kcontrol_new ad1981_mixers[] = { 551 - HDA_CODEC_VOLUME("Front Playback Volume", 0x05, 0x0, HDA_OUTPUT), 552 - HDA_CODEC_MUTE("Front Playback Switch", 0x05, 0x0, HDA_OUTPUT), 553 - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x06, 0x0, HDA_OUTPUT), 554 - HDA_CODEC_MUTE("Headphone Playback Switch", 0x06, 0x0, HDA_OUTPUT), 555 - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x07, 1, 0x0, HDA_OUTPUT), 556 - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x07, 1, 0x0, HDA_OUTPUT), 557 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 558 - HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 559 - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 560 - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 561 - HDA_CODEC_VOLUME("Line Playback Volume", 0x13, 0x0, HDA_OUTPUT), 562 - HDA_CODEC_MUTE("Line Playback Switch", 0x13, 0x0, HDA_OUTPUT), 563 - HDA_CODEC_VOLUME("Aux Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 564 - HDA_CODEC_MUTE("Aux Playback Switch", 0x1b, 0x0, HDA_OUTPUT), 565 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 566 - HDA_CODEC_MUTE("Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 567 - HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 568 - HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 569 - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x08, 0x0, HDA_INPUT), 570 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x18, 0x0, HDA_INPUT), 571 - HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 572 - HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 573 - { 574 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 575 - .name = "Capture Source", 576 - .info = ad198x_mux_enum_info, 577 - .get = ad198x_mux_enum_get, 578 - .put = ad198x_mux_enum_put, 579 - }, 580 - /* identical with AD1983 */ 581 - { 582 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 583 - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 584 - .info = ad1983_spdif_route_info, 585 - .get = ad1983_spdif_route_get, 586 - .put = ad1983_spdif_route_put, 587 - }, 588 - { } /* end */ 589 - }; 590 - 591 - static const struct hda_verb ad1981_init_verbs[] = { 592 - /* Front, HP, Mono; mute as default */ 593 - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 594 - {0x06, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 595 - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 596 - /* Beep, PCM, Front Mic, Line, Rear Mic, Aux, CD-In: mute */ 597 - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 598 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 599 - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 600 - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 601 - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 602 - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 603 - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 604 - /* Front, HP selectors; from Mix */ 605 - {0x05, AC_VERB_SET_CONNECT_SEL, 0x01}, 606 - {0x06, AC_VERB_SET_CONNECT_SEL, 0x01}, 607 - /* Mono selector; from Mix */ 608 - {0x0b, AC_VERB_SET_CONNECT_SEL, 0x03}, 609 - /* Mic Mixer; select Front Mic */ 610 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 611 - {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 612 - /* Mic boost: 0dB */ 613 - {0x08, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 614 - {0x18, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 615 - /* Record selector: Front mic */ 616 - {0x15, AC_VERB_SET_CONNECT_SEL, 0x0}, 617 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 618 - /* SPDIF route: PCM */ 619 - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, 620 - /* Front Pin */ 621 - {0x05, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 622 - /* HP Pin */ 623 - {0x06, AC_VERB_SET_PIN_WIDGET_CONTROL, 0xc0 }, 624 - /* Mono Pin */ 625 - {0x07, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x40 }, 626 - /* Front & Rear Mic Pins */ 627 - {0x08, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 628 - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x24 }, 629 - /* Line Pin */ 630 - {0x09, AC_VERB_SET_PIN_WIDGET_CONTROL, 0x20 }, 631 - /* Digital Beep */ 632 - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x00}, 633 - /* Line-Out as Input: disabled */ 634 - {0x1a, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 635 - { } /* end */ 636 - }; 637 - 638 - #ifdef CONFIG_PM 639 - static const struct hda_amp_list ad1981_loopbacks[] = { 640 - { 0x12, HDA_OUTPUT, 0 }, /* Front Mic */ 641 - { 0x13, HDA_OUTPUT, 0 }, /* Line */ 642 - { 0x1b, HDA_OUTPUT, 0 }, /* Aux */ 643 - { 0x1c, HDA_OUTPUT, 0 }, /* Mic */ 644 - { 0x1d, HDA_OUTPUT, 0 }, /* CD */ 645 - { } /* end */ 646 - }; 647 - #endif 648 - 649 - /* 650 - * Patch for HP nx6320 651 - * 652 - * nx6320 uses EAPD in the reverse way - EAPD-on means the internal 653 - * speaker output enabled _and_ mute-LED off. 654 - */ 655 - 656 - #define AD1981_HP_EVENT 0x37 657 - #define AD1981_MIC_EVENT 0x38 658 - 659 - static const struct hda_verb ad1981_hp_init_verbs[] = { 660 - {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x00 }, /* default off */ 661 - /* pin sensing on HP and Mic jacks */ 662 - {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, 663 - {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT}, 664 - {} 665 - }; 666 - 667 - /* turn on/off EAPD (+ mute HP) as a master switch */ 668 - static int ad1981_hp_master_sw_put(struct snd_kcontrol *kcontrol, 669 - struct snd_ctl_elem_value *ucontrol) 670 - { 671 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 672 - struct ad198x_spec *spec = codec->spec; 673 - 674 - if (! ad198x_eapd_put(kcontrol, ucontrol)) 675 - return 0; 676 - /* change speaker pin appropriately */ 677 - snd_hda_set_pin_ctl(codec, 0x05, spec->cur_eapd ? PIN_OUT : 0); 678 - /* toggle HP mute appropriately */ 679 - snd_hda_codec_amp_stereo(codec, 0x06, HDA_OUTPUT, 0, 680 - HDA_AMP_MUTE, 681 - spec->cur_eapd ? 0 : HDA_AMP_MUTE); 682 - return 1; 683 - } 684 - 685 - /* bind volumes of both NID 0x05 and 0x06 */ 686 - static const struct hda_bind_ctls ad1981_hp_bind_master_vol = { 687 - .ops = &snd_hda_bind_vol, 688 - .values = { 689 - HDA_COMPOSE_AMP_VAL(0x05, 3, 0, HDA_OUTPUT), 690 - HDA_COMPOSE_AMP_VAL(0x06, 3, 0, HDA_OUTPUT), 691 - 0 692 - }, 693 - }; 694 - 695 - /* mute internal speaker if HP is plugged */ 696 - static void ad1981_hp_automute(struct hda_codec *codec) 697 - { 698 - unsigned int present; 699 - 700 - present = snd_hda_jack_detect(codec, 0x06); 701 - snd_hda_codec_amp_stereo(codec, 0x05, HDA_OUTPUT, 0, 702 - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 703 - } 704 - 705 - /* toggle input of built-in and mic jack appropriately */ 706 - static void ad1981_hp_automic(struct hda_codec *codec) 707 - { 708 - static const struct hda_verb mic_jack_on[] = { 709 - {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 710 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 711 - {} 712 - }; 713 - static const struct hda_verb mic_jack_off[] = { 714 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, 0xb080}, 715 - {0x1f, AC_VERB_SET_AMP_GAIN_MUTE, 0xb000}, 716 - {} 717 - }; 718 - unsigned int present; 719 - 720 - present = snd_hda_jack_detect(codec, 0x08); 721 - if (present) 722 - snd_hda_sequence_write(codec, mic_jack_on); 723 - else 724 - snd_hda_sequence_write(codec, mic_jack_off); 725 - } 726 - 727 - /* unsolicited event for HP jack sensing */ 728 - static void ad1981_hp_unsol_event(struct hda_codec *codec, 729 - unsigned int res) 730 - { 731 - res >>= 26; 732 - switch (res) { 733 - case AD1981_HP_EVENT: 734 - ad1981_hp_automute(codec); 735 - break; 736 - case AD1981_MIC_EVENT: 737 - ad1981_hp_automic(codec); 738 - break; 739 - } 740 - } 741 - 742 - static const struct hda_input_mux ad1981_hp_capture_source = { 743 - .num_items = 3, 744 - .items = { 745 - { "Mic", 0x0 }, 746 - { "Dock Mic", 0x1 }, 747 - { "Mix", 0x2 }, 748 - }, 749 - }; 750 - 751 - static const struct snd_kcontrol_new ad1981_hp_mixers[] = { 752 - HDA_BIND_VOL("Master Playback Volume", &ad1981_hp_bind_master_vol), 753 - { 754 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 755 - .subdevice = HDA_SUBDEV_NID_FLAG | 0x05, 756 - .name = "Master Playback Switch", 757 - .info = ad198x_eapd_info, 758 - .get = ad198x_eapd_get, 759 - .put = ad1981_hp_master_sw_put, 760 - .private_value = 0x05, 761 - }, 762 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 763 - HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 764 - #if 0 765 - /* FIXME: analog mic/line loopback doesn't work with my tests... 766 - * (although recording is OK) 767 - */ 768 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 769 - HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 770 - HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x13, 0x0, HDA_OUTPUT), 771 - HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x13, 0x0, HDA_OUTPUT), 772 - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x1c, 0x0, HDA_OUTPUT), 773 - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x1c, 0x0, HDA_OUTPUT), 774 - /* FIXME: does this laptop have analog CD connection? */ 775 - HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 776 - HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 777 - #endif 778 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT), 779 - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x18, 0x0, HDA_INPUT), 780 - HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 781 - HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 782 - { 783 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 784 - .name = "Capture Source", 785 - .info = ad198x_mux_enum_info, 786 - .get = ad198x_mux_enum_get, 787 - .put = ad198x_mux_enum_put, 788 - }, 789 - { } /* end */ 790 - }; 791 - 792 - /* initialize jack-sensing, too */ 793 - static int ad1981_hp_init(struct hda_codec *codec) 794 - { 795 - ad198x_init(codec); 796 - ad1981_hp_automute(codec); 797 - ad1981_hp_automic(codec); 798 - return 0; 799 - } 800 - 801 - /* configuration for Toshiba Laptops */ 802 - static const struct hda_verb ad1981_toshiba_init_verbs[] = { 803 - {0x05, AC_VERB_SET_EAPD_BTLENABLE, 0x01 }, /* default on */ 804 - /* pin sensing on HP and Mic jacks */ 805 - {0x06, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_HP_EVENT}, 806 - {0x08, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1981_MIC_EVENT}, 807 - {} 808 - }; 809 - 810 - static const struct snd_kcontrol_new ad1981_toshiba_mixers[] = { 811 - HDA_CODEC_VOLUME("Amp Volume", 0x1a, 0x0, HDA_OUTPUT), 812 - HDA_CODEC_MUTE("Amp Switch", 0x1a, 0x0, HDA_OUTPUT), 813 - { } 814 - }; 815 - 816 - /* configuration for Lenovo Thinkpad T60 */ 817 - static const struct snd_kcontrol_new ad1981_thinkpad_mixers[] = { 818 - HDA_CODEC_VOLUME("Master Playback Volume", 0x05, 0x0, HDA_OUTPUT), 819 - HDA_CODEC_MUTE("Master Playback Switch", 0x05, 0x0, HDA_OUTPUT), 820 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x11, 0x0, HDA_OUTPUT), 821 - HDA_CODEC_MUTE("PCM Playback Switch", 0x11, 0x0, HDA_OUTPUT), 822 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x12, 0x0, HDA_OUTPUT), 823 - HDA_CODEC_MUTE("Mic Playback Switch", 0x12, 0x0, HDA_OUTPUT), 824 - HDA_CODEC_VOLUME("CD Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 825 - HDA_CODEC_MUTE("CD Playback Switch", 0x1d, 0x0, HDA_OUTPUT), 826 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x08, 0x0, HDA_INPUT), 827 - HDA_CODEC_VOLUME("Capture Volume", 0x15, 0x0, HDA_OUTPUT), 828 - HDA_CODEC_MUTE("Capture Switch", 0x15, 0x0, HDA_OUTPUT), 829 - { 830 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 831 - .name = "Capture Source", 832 - .info = ad198x_mux_enum_info, 833 - .get = ad198x_mux_enum_get, 834 - .put = ad198x_mux_enum_put, 835 - }, 836 - /* identical with AD1983 */ 837 - { 838 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 839 - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 840 - .info = ad1983_spdif_route_info, 841 - .get = ad1983_spdif_route_get, 842 - .put = ad1983_spdif_route_put, 843 - }, 844 - { } /* end */ 845 - }; 846 - 847 - static const struct hda_input_mux ad1981_thinkpad_capture_source = { 848 - .num_items = 3, 849 - .items = { 850 - { "Mic", 0x0 }, 851 - { "Mix", 0x2 }, 852 - { "CD", 0x4 }, 853 - }, 854 - }; 855 - 856 - /* models */ 857 - enum { 858 - AD1981_AUTO, 859 - AD1981_BASIC, 860 - AD1981_HP, 861 - AD1981_THINKPAD, 862 - AD1981_TOSHIBA, 863 - AD1981_MODELS 864 - }; 865 - 866 - static const char * const ad1981_models[AD1981_MODELS] = { 867 - [AD1981_AUTO] = "auto", 868 - [AD1981_HP] = "hp", 869 - [AD1981_THINKPAD] = "thinkpad", 870 - [AD1981_BASIC] = "basic", 871 - [AD1981_TOSHIBA] = "toshiba" 872 - }; 873 - 874 - static const struct snd_pci_quirk ad1981_cfg_tbl[] = { 875 - SND_PCI_QUIRK(0x1014, 0x0597, "Lenovo Z60", AD1981_THINKPAD), 876 - SND_PCI_QUIRK(0x1014, 0x05b7, "Lenovo Z60m", AD1981_THINKPAD), 877 - /* All HP models */ 878 - SND_PCI_QUIRK_VENDOR(0x103c, "HP nx", AD1981_HP), 879 - SND_PCI_QUIRK(0x1179, 0x0001, "Toshiba U205", AD1981_TOSHIBA), 880 - /* Lenovo Thinkpad T60/X60/Z6xx */ 881 - SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1981_THINKPAD), 882 - /* HP nx6320 (reversed SSID, H/W bug) */ 883 - SND_PCI_QUIRK(0x30b0, 0x103c, "HP nx6320", AD1981_HP), 884 - {} 885 - }; 886 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 887 - 888 1688 889 1689 /* follow EAPD via vmaster hook */ 890 1690 static void ad_vmaster_eapd_hook(void *private_data, int enabled) ··· 530 2172 {} 531 2173 }; 532 2174 533 - static int ad1981_parse_auto_config(struct hda_codec *codec) 2175 + static int patch_ad1981(struct hda_codec *codec) 534 2176 { 535 2177 struct ad198x_spec *spec; 536 2178 int err; ··· 562 2204 snd_hda_gen_free(codec); 563 2205 return err; 564 2206 } 565 - 566 - #ifdef ENABLE_AD_STATIC_QUIRKS 567 - static int patch_ad1981(struct hda_codec *codec) 568 - { 569 - struct ad198x_spec *spec; 570 - int err, board_config; 571 - 572 - board_config = snd_hda_check_board_config(codec, AD1981_MODELS, 573 - ad1981_models, 574 - ad1981_cfg_tbl); 575 - if (board_config < 0) { 576 - printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 577 - codec->chip_name); 578 - board_config = AD1981_AUTO; 579 - } 580 - 581 - if (board_config == AD1981_AUTO) 582 - return ad1981_parse_auto_config(codec); 583 - 584 - err = alloc_ad_spec(codec); 585 - if (err < 0) 586 - return -ENOMEM; 587 - spec = codec->spec; 588 - 589 - err = snd_hda_attach_beep_device(codec, 0x10); 590 - if (err < 0) { 591 - ad198x_free(codec); 592 - return err; 593 - } 594 - set_beep_amp(spec, 0x0d, 0, HDA_OUTPUT); 595 - 596 - spec->multiout.max_channels = 2; 597 - spec->multiout.num_dacs = ARRAY_SIZE(ad1981_dac_nids); 598 - spec->multiout.dac_nids = ad1981_dac_nids; 599 - spec->multiout.dig_out_nid = AD1981_SPDIF_OUT; 600 - spec->num_adc_nids = 1; 601 - spec->adc_nids = ad1981_adc_nids; 602 - spec->capsrc_nids = ad1981_capsrc_nids; 603 - spec->input_mux = &ad1981_capture_source; 604 - spec->num_mixers = 1; 605 - spec->mixers[0] = ad1981_mixers; 606 - spec->num_init_verbs = 1; 607 - spec->init_verbs[0] = ad1981_init_verbs; 608 - spec->spdif_route = 0; 609 - #ifdef CONFIG_PM 610 - spec->loopback.amplist = ad1981_loopbacks; 611 - #endif 612 - spec->vmaster_nid = 0x05; 613 - 614 - codec->patch_ops = ad198x_patch_ops; 615 - 616 - /* override some parameters */ 617 - switch (board_config) { 618 - case AD1981_HP: 619 - spec->mixers[0] = ad1981_hp_mixers; 620 - spec->num_init_verbs = 2; 621 - spec->init_verbs[1] = ad1981_hp_init_verbs; 622 - if (!is_jack_available(codec, 0x0a)) 623 - spec->multiout.dig_out_nid = 0; 624 - spec->input_mux = &ad1981_hp_capture_source; 625 - 626 - codec->patch_ops.init = ad1981_hp_init; 627 - codec->patch_ops.unsol_event = ad1981_hp_unsol_event; 628 - /* set the upper-limit for mixer amp to 0dB for avoiding the 629 - * possible damage by overloading 630 - */ 631 - snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, 632 - (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 633 - (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 634 - (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 635 - (1 << AC_AMPCAP_MUTE_SHIFT)); 636 - break; 637 - case AD1981_THINKPAD: 638 - spec->mixers[0] = ad1981_thinkpad_mixers; 639 - spec->input_mux = &ad1981_thinkpad_capture_source; 640 - /* set the upper-limit for mixer amp to 0dB for avoiding the 641 - * possible damage by overloading 642 - */ 643 - snd_hda_override_amp_caps(codec, 0x11, HDA_INPUT, 644 - (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 645 - (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 646 - (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 647 - (1 << AC_AMPCAP_MUTE_SHIFT)); 648 - break; 649 - case AD1981_TOSHIBA: 650 - spec->mixers[0] = ad1981_hp_mixers; 651 - spec->mixers[1] = ad1981_toshiba_mixers; 652 - spec->num_init_verbs = 2; 653 - spec->init_verbs[1] = ad1981_toshiba_init_verbs; 654 - spec->multiout.dig_out_nid = 0; 655 - spec->input_mux = &ad1981_hp_capture_source; 656 - codec->patch_ops.init = ad1981_hp_init; 657 - codec->patch_ops.unsol_event = ad1981_hp_unsol_event; 658 - break; 659 - } 660 - 661 - codec->no_trigger_sense = 1; 662 - codec->no_sticky_stream = 1; 663 - 664 - return 0; 665 - } 666 - #else /* ENABLE_AD_STATIC_QUIRKS */ 667 - #define patch_ad1981 ad1981_parse_auto_config 668 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 669 2207 670 2208 671 2209 /* ··· 649 2395 * E/F quad mic array 650 2396 */ 651 2397 652 - 653 2398 #ifdef ENABLE_AD_STATIC_QUIRKS 654 - /* models */ 655 - enum { 656 - AD1988_AUTO, 657 - AD1988_6STACK, 658 - AD1988_6STACK_DIG, 659 - AD1988_3STACK, 660 - AD1988_3STACK_DIG, 661 - AD1988_LAPTOP, 662 - AD1988_LAPTOP_DIG, 663 - AD1988_MODEL_LAST, 664 - }; 665 - 666 - /* reivision id to check workarounds */ 667 - #define AD1988A_REV2 0x100200 668 - 669 - #define is_rev2(codec) \ 670 - ((codec)->vendor_id == 0x11d41988 && \ 671 - (codec)->revision_id == AD1988A_REV2) 672 - 673 - /* 674 - * mixers 675 - */ 676 - 677 - static const hda_nid_t ad1988_6stack_dac_nids[4] = { 678 - 0x04, 0x06, 0x05, 0x0a 679 - }; 680 - 681 - static const hda_nid_t ad1988_3stack_dac_nids[3] = { 682 - 0x04, 0x05, 0x0a 683 - }; 684 - 685 - /* for AD1988A revision-2, DAC2-4 are swapped */ 686 - static const hda_nid_t ad1988_6stack_dac_nids_rev2[4] = { 687 - 0x04, 0x05, 0x0a, 0x06 688 - }; 689 - 690 - static const hda_nid_t ad1988_alt_dac_nid[1] = { 691 - 0x03 692 - }; 693 - 694 - static const hda_nid_t ad1988_3stack_dac_nids_rev2[3] = { 695 - 0x04, 0x0a, 0x06 696 - }; 697 - 698 - static const hda_nid_t ad1988_adc_nids[3] = { 699 - 0x08, 0x09, 0x0f 700 - }; 701 - 702 - static const hda_nid_t ad1988_capsrc_nids[3] = { 703 - 0x0c, 0x0d, 0x0e 704 - }; 705 - 706 - #define AD1988_SPDIF_OUT 0x02 707 - #define AD1988_SPDIF_OUT_HDMI 0x0b 708 - #define AD1988_SPDIF_IN 0x07 709 - 710 - static const hda_nid_t ad1989b_slave_dig_outs[] = { 711 - AD1988_SPDIF_OUT, AD1988_SPDIF_OUT_HDMI, 0 712 - }; 713 - 714 - static const struct hda_input_mux ad1988_6stack_capture_source = { 715 - .num_items = 5, 716 - .items = { 717 - { "Front Mic", 0x1 }, /* port-B */ 718 - { "Line", 0x2 }, /* port-C */ 719 - { "Mic", 0x4 }, /* port-E */ 720 - { "CD", 0x5 }, 721 - { "Mix", 0x9 }, 722 - }, 723 - }; 724 - 725 - static const struct hda_input_mux ad1988_laptop_capture_source = { 726 - .num_items = 3, 727 - .items = { 728 - { "Mic/Line", 0x1 }, /* port-B */ 729 - { "CD", 0x5 }, 730 - { "Mix", 0x9 }, 731 - }, 732 - }; 733 - 734 - /* 735 - */ 736 2399 static int ad198x_ch_mode_info(struct snd_kcontrol *kcontrol, 737 2400 struct snd_ctl_elem_info *uinfo) 738 2401 { ··· 680 2509 spec->multiout.num_dacs = spec->multiout.max_channels / 2; 681 2510 return err; 682 2511 } 683 - 684 - /* 6-stack mode */ 685 - static const struct snd_kcontrol_new ad1988_6stack_mixers1[] = { 686 - HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 687 - HDA_CODEC_VOLUME("Surround Playback Volume", 0x06, 0x0, HDA_OUTPUT), 688 - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 689 - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), 690 - HDA_CODEC_VOLUME("Side Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 691 - { } /* end */ 692 - }; 693 - 694 - static const struct snd_kcontrol_new ad1988_6stack_mixers1_rev2[] = { 695 - HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 696 - HDA_CODEC_VOLUME("Surround Playback Volume", 0x05, 0x0, HDA_OUTPUT), 697 - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x0a, 1, 0x0, HDA_OUTPUT), 698 - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x0a, 2, 0x0, HDA_OUTPUT), 699 - HDA_CODEC_VOLUME("Side Playback Volume", 0x06, 0x0, HDA_OUTPUT), 700 - { } /* end */ 701 - }; 702 - 703 - static const struct snd_kcontrol_new ad1988_6stack_mixers2[] = { 704 - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 705 - HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 706 - HDA_BIND_MUTE("Surround Playback Switch", 0x2a, 2, HDA_INPUT), 707 - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x27, 1, 2, HDA_INPUT), 708 - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x27, 2, 2, HDA_INPUT), 709 - HDA_BIND_MUTE("Side Playback Switch", 0x28, 2, HDA_INPUT), 710 - HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), 711 - HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 712 - 713 - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), 714 - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), 715 - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT), 716 - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT), 717 - HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), 718 - HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), 719 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT), 720 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT), 721 - 722 - HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 723 - HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 724 - 725 - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), 726 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), 727 - { } /* end */ 728 - }; 729 - 730 - /* 3-stack mode */ 731 - static const struct snd_kcontrol_new ad1988_3stack_mixers1[] = { 732 - HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 733 - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 734 - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 735 - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), 736 - { } /* end */ 737 - }; 738 - 739 - static const struct snd_kcontrol_new ad1988_3stack_mixers1_rev2[] = { 740 - HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 741 - HDA_CODEC_VOLUME("Surround Playback Volume", 0x0a, 0x0, HDA_OUTPUT), 742 - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x06, 1, 0x0, HDA_OUTPUT), 743 - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x06, 2, 0x0, HDA_OUTPUT), 744 - { } /* end */ 745 - }; 746 - 747 - static const struct snd_kcontrol_new ad1988_3stack_mixers2[] = { 748 - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 749 - HDA_BIND_MUTE("Front Playback Switch", 0x29, 2, HDA_INPUT), 750 - HDA_BIND_MUTE("Surround Playback Switch", 0x2c, 2, HDA_INPUT), 751 - HDA_BIND_MUTE_MONO("Center Playback Switch", 0x26, 1, 2, HDA_INPUT), 752 - HDA_BIND_MUTE_MONO("LFE Playback Switch", 0x26, 2, 2, HDA_INPUT), 753 - HDA_BIND_MUTE("Headphone Playback Switch", 0x22, 2, HDA_INPUT), 754 - HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 755 - 756 - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), 757 - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), 758 - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x0, HDA_INPUT), 759 - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x0, HDA_INPUT), 760 - HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), 761 - HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), 762 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x4, HDA_INPUT), 763 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x4, HDA_INPUT), 764 - 765 - HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 766 - HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 767 - 768 - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), 769 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), 770 - { 771 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 772 - .name = "Channel Mode", 773 - .info = ad198x_ch_mode_info, 774 - .get = ad198x_ch_mode_get, 775 - .put = ad198x_ch_mode_put, 776 - }, 777 - 778 - { } /* end */ 779 - }; 780 - 781 - /* laptop mode */ 782 - static const struct snd_kcontrol_new ad1988_laptop_mixers[] = { 783 - HDA_CODEC_VOLUME("Headphone Playback Volume", 0x03, 0x0, HDA_OUTPUT), 784 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 785 - HDA_CODEC_MUTE("PCM Playback Switch", 0x29, 0x0, HDA_INPUT), 786 - HDA_BIND_MUTE("Mono Playback Switch", 0x1e, 2, HDA_INPUT), 787 - 788 - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x6, HDA_INPUT), 789 - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x6, HDA_INPUT), 790 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x0, HDA_INPUT), 791 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x0, HDA_INPUT), 792 - HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x1, HDA_INPUT), 793 - HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x1, HDA_INPUT), 794 - 795 - HDA_CODEC_VOLUME("Analog Mix Playback Volume", 0x21, 0x0, HDA_OUTPUT), 796 - HDA_CODEC_MUTE("Analog Mix Playback Switch", 0x21, 0x0, HDA_OUTPUT), 797 - 798 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), 799 - 800 - { 801 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 802 - .name = "External Amplifier", 803 - .subdevice = HDA_SUBDEV_NID_FLAG | 0x12, 804 - .info = ad198x_eapd_info, 805 - .get = ad198x_eapd_get, 806 - .put = ad198x_eapd_put, 807 - .private_value = 0x12, /* port-D */ 808 - }, 809 - 810 - { } /* end */ 811 - }; 812 - 813 - /* capture */ 814 - static const struct snd_kcontrol_new ad1988_capture_mixers[] = { 815 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 816 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 817 - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 818 - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 819 - HDA_CODEC_VOLUME_IDX("Capture Volume", 2, 0x0e, 0x0, HDA_OUTPUT), 820 - HDA_CODEC_MUTE_IDX("Capture Switch", 2, 0x0e, 0x0, HDA_OUTPUT), 821 - { 822 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 823 - /* The multiple "Capture Source" controls confuse alsamixer 824 - * So call somewhat different.. 825 - */ 826 - /* .name = "Capture Source", */ 827 - .name = "Input Source", 828 - .count = 3, 829 - .info = ad198x_mux_enum_info, 830 - .get = ad198x_mux_enum_get, 831 - .put = ad198x_mux_enum_put, 832 - }, 833 - { } /* end */ 834 - }; 835 - 836 - static int ad1988_spdif_playback_source_info(struct snd_kcontrol *kcontrol, 837 - struct snd_ctl_elem_info *uinfo) 838 - { 839 - static const char * const texts[] = { 840 - "PCM", "ADC1", "ADC2", "ADC3" 841 - }; 842 - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 843 - uinfo->count = 1; 844 - uinfo->value.enumerated.items = 4; 845 - if (uinfo->value.enumerated.item >= 4) 846 - uinfo->value.enumerated.item = 3; 847 - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); 848 - return 0; 849 - } 850 - 851 - static int ad1988_spdif_playback_source_get(struct snd_kcontrol *kcontrol, 852 - struct snd_ctl_elem_value *ucontrol) 853 - { 854 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 855 - unsigned int sel; 856 - 857 - sel = snd_hda_codec_read(codec, 0x1d, 0, AC_VERB_GET_AMP_GAIN_MUTE, 858 - AC_AMP_GET_INPUT); 859 - if (!(sel & 0x80)) 860 - ucontrol->value.enumerated.item[0] = 0; 861 - else { 862 - sel = snd_hda_codec_read(codec, 0x0b, 0, 863 - AC_VERB_GET_CONNECT_SEL, 0); 864 - if (sel < 3) 865 - sel++; 866 - else 867 - sel = 0; 868 - ucontrol->value.enumerated.item[0] = sel; 869 - } 870 - return 0; 871 - } 872 - 873 - static int ad1988_spdif_playback_source_put(struct snd_kcontrol *kcontrol, 874 - struct snd_ctl_elem_value *ucontrol) 875 - { 876 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 877 - unsigned int val, sel; 878 - int change; 879 - 880 - val = ucontrol->value.enumerated.item[0]; 881 - if (val > 3) 882 - return -EINVAL; 883 - if (!val) { 884 - sel = snd_hda_codec_read(codec, 0x1d, 0, 885 - AC_VERB_GET_AMP_GAIN_MUTE, 886 - AC_AMP_GET_INPUT); 887 - change = sel & 0x80; 888 - if (change) { 889 - snd_hda_codec_write_cache(codec, 0x1d, 0, 890 - AC_VERB_SET_AMP_GAIN_MUTE, 891 - AMP_IN_UNMUTE(0)); 892 - snd_hda_codec_write_cache(codec, 0x1d, 0, 893 - AC_VERB_SET_AMP_GAIN_MUTE, 894 - AMP_IN_MUTE(1)); 895 - } 896 - } else { 897 - sel = snd_hda_codec_read(codec, 0x1d, 0, 898 - AC_VERB_GET_AMP_GAIN_MUTE, 899 - AC_AMP_GET_INPUT | 0x01); 900 - change = sel & 0x80; 901 - if (change) { 902 - snd_hda_codec_write_cache(codec, 0x1d, 0, 903 - AC_VERB_SET_AMP_GAIN_MUTE, 904 - AMP_IN_MUTE(0)); 905 - snd_hda_codec_write_cache(codec, 0x1d, 0, 906 - AC_VERB_SET_AMP_GAIN_MUTE, 907 - AMP_IN_UNMUTE(1)); 908 - } 909 - sel = snd_hda_codec_read(codec, 0x0b, 0, 910 - AC_VERB_GET_CONNECT_SEL, 0) + 1; 911 - change |= sel != val; 912 - if (change) 913 - snd_hda_codec_write_cache(codec, 0x0b, 0, 914 - AC_VERB_SET_CONNECT_SEL, 915 - val - 1); 916 - } 917 - return change; 918 - } 919 - 920 - static const struct snd_kcontrol_new ad1988_spdif_out_mixers[] = { 921 - HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 922 - { 923 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 924 - .name = "IEC958 Playback Source", 925 - .subdevice = HDA_SUBDEV_NID_FLAG | 0x1b, 926 - .info = ad1988_spdif_playback_source_info, 927 - .get = ad1988_spdif_playback_source_get, 928 - .put = ad1988_spdif_playback_source_put, 929 - }, 930 - { } /* end */ 931 - }; 932 - 933 - static const struct snd_kcontrol_new ad1988_spdif_in_mixers[] = { 934 - HDA_CODEC_VOLUME("IEC958 Capture Volume", 0x1c, 0x0, HDA_INPUT), 935 - { } /* end */ 936 - }; 937 - 938 - static const struct snd_kcontrol_new ad1989_spdif_out_mixers[] = { 939 - HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 940 - HDA_CODEC_VOLUME("HDMI Playback Volume", 0x1d, 0x0, HDA_OUTPUT), 941 - { } /* end */ 942 - }; 943 - 944 - /* 945 - * initialization verbs 946 - */ 947 - 948 - /* 949 - * for 6-stack (+dig) 950 - */ 951 - static const struct hda_verb ad1988_6stack_init_verbs[] = { 952 - /* Front, Surround, CLFE, side DAC; unmute as default */ 953 - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 954 - {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 955 - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 956 - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 957 - /* Port-A front headphon path */ 958 - {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ 959 - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 960 - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 961 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 962 - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 963 - /* Port-D line-out path */ 964 - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 965 - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 966 - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 967 - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 968 - /* Port-F surround path */ 969 - {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 970 - {0x2a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 971 - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 972 - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 973 - /* Port-G CLFE path */ 974 - {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 975 - {0x27, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 976 - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 977 - {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 978 - /* Port-H side path */ 979 - {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 980 - {0x28, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 981 - {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 982 - {0x25, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 983 - /* Mono out path */ 984 - {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ 985 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 986 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 987 - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 988 - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ 989 - /* Port-B front mic-in path */ 990 - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 991 - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 992 - {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 993 - /* Port-C line-in path */ 994 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 995 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 996 - {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 997 - {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, 998 - /* Port-E mic-in path */ 999 - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1000 - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1001 - {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1002 - {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, 1003 - /* Analog CD Input */ 1004 - {0x18, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1005 - /* Analog Mix output amp */ 1006 - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ 1007 - 1008 - { } 1009 - }; 1010 - 1011 - static const struct hda_verb ad1988_6stack_fp_init_verbs[] = { 1012 - /* Headphone; unmute as default */ 1013 - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1014 - /* Port-A front headphon path */ 1015 - {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ 1016 - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1017 - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1018 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1019 - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1020 - 1021 - { } 1022 - }; 1023 - 1024 - static const struct hda_verb ad1988_capture_init_verbs[] = { 1025 - /* mute analog mix */ 1026 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1027 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1028 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1029 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1030 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1031 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 1032 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1033 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1034 - /* select ADCs - front-mic */ 1035 - {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 1036 - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, 1037 - {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 1038 - 1039 - { } 1040 - }; 1041 - 1042 - static const struct hda_verb ad1988_spdif_init_verbs[] = { 1043 - /* SPDIF out sel */ 1044 - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ 1045 - {0x0b, AC_VERB_SET_CONNECT_SEL, 0x0}, /* ADC1 */ 1046 - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1047 - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1048 - /* SPDIF out pin */ 1049 - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 1050 - 1051 - { } 1052 - }; 1053 - 1054 - static const struct hda_verb ad1988_spdif_in_init_verbs[] = { 1055 - /* unmute SPDIF input pin */ 1056 - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1057 - { } 1058 - }; 1059 - 1060 - /* AD1989 has no ADC -> SPDIF route */ 1061 - static const struct hda_verb ad1989_spdif_init_verbs[] = { 1062 - /* SPDIF-1 out pin */ 1063 - {0x1b, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1064 - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 1065 - /* SPDIF-2/HDMI out pin */ 1066 - {0x1d, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1067 - {0x1d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 1068 - { } 1069 - }; 1070 - 1071 - /* 1072 - * verbs for 3stack (+dig) 1073 - */ 1074 - static const struct hda_verb ad1988_3stack_ch2_init[] = { 1075 - /* set port-C to line-in */ 1076 - { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1077 - { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN }, 1078 - /* set port-E to mic-in */ 1079 - { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1080 - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80 }, 1081 - { } /* end */ 1082 - }; 1083 - 1084 - static const struct hda_verb ad1988_3stack_ch6_init[] = { 1085 - /* set port-C to surround out */ 1086 - { 0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1087 - { 0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1088 - /* set port-E to CLFE out */ 1089 - { 0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT }, 1090 - { 0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1091 - { } /* end */ 1092 - }; 1093 - 1094 - static const struct hda_channel_mode ad1988_3stack_modes[2] = { 1095 - { 2, ad1988_3stack_ch2_init }, 1096 - { 6, ad1988_3stack_ch6_init }, 1097 - }; 1098 - 1099 - static const struct hda_verb ad1988_3stack_init_verbs[] = { 1100 - /* Front, Surround, CLFE, side DAC; unmute as default */ 1101 - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1102 - {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1103 - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1104 - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1105 - /* Port-A front headphon path */ 1106 - {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ 1107 - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1108 - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1109 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1110 - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1111 - /* Port-D line-out path */ 1112 - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1113 - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1114 - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1115 - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1116 - /* Mono out path */ 1117 - {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ 1118 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1119 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1120 - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1121 - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ 1122 - /* Port-B front mic-in path */ 1123 - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1124 - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1125 - {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1126 - /* Port-C line-in/surround path - 6ch mode as default */ 1127 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1128 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1129 - {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1130 - {0x31, AC_VERB_SET_CONNECT_SEL, 0x0}, /* output sel: DAC 0x05 */ 1131 - {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, 1132 - /* Port-E mic-in/CLFE path - 6ch mode as default */ 1133 - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1134 - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1135 - {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1136 - {0x32, AC_VERB_SET_CONNECT_SEL, 0x1}, /* output sel: DAC 0x0a */ 1137 - {0x34, AC_VERB_SET_CONNECT_SEL, 0x0}, 1138 - /* mute analog mix */ 1139 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1140 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1141 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1142 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1143 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1144 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 1145 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1146 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1147 - /* select ADCs - front-mic */ 1148 - {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 1149 - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, 1150 - {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 1151 - /* Analog Mix output amp */ 1152 - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ 1153 - { } 1154 - }; 1155 - 1156 - /* 1157 - * verbs for laptop mode (+dig) 1158 - */ 1159 - static const struct hda_verb ad1988_laptop_hp_on[] = { 1160 - /* unmute port-A and mute port-D */ 1161 - { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1162 - { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1163 - { } /* end */ 1164 - }; 1165 - static const struct hda_verb ad1988_laptop_hp_off[] = { 1166 - /* mute port-A and unmute port-D */ 1167 - { 0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE }, 1168 - { 0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE }, 1169 - { } /* end */ 1170 - }; 1171 - 1172 - #define AD1988_HP_EVENT 0x01 1173 - 1174 - static const struct hda_verb ad1988_laptop_init_verbs[] = { 1175 - /* Front, Surround, CLFE, side DAC; unmute as default */ 1176 - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1177 - {0x06, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1178 - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1179 - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1180 - /* Port-A front headphon path */ 1181 - {0x37, AC_VERB_SET_CONNECT_SEL, 0x00}, /* DAC0:03h */ 1182 - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1183 - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1184 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1185 - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1186 - /* unsolicited event for pin-sense */ 1187 - {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1988_HP_EVENT }, 1188 - /* Port-D line-out path + EAPD */ 1189 - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1190 - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1191 - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1192 - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1193 - {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x00}, /* EAPD-off */ 1194 - /* Mono out path */ 1195 - {0x36, AC_VERB_SET_CONNECT_SEL, 0x1}, /* DAC1:04h */ 1196 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1197 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1198 - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1199 - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, 0xb01f}, /* unmute, 0dB */ 1200 - /* Port-B mic-in path */ 1201 - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1202 - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1203 - {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1204 - /* Port-C docking station - try to output */ 1205 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1206 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1207 - {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1208 - {0x33, AC_VERB_SET_CONNECT_SEL, 0x0}, 1209 - /* mute analog mix */ 1210 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1211 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1212 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1213 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1214 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1215 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 1216 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1217 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1218 - /* select ADCs - mic */ 1219 - {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 1220 - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x1}, 1221 - {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 1222 - /* Analog Mix output amp */ 1223 - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ 1224 - { } 1225 - }; 1226 - 1227 - static void ad1988_laptop_unsol_event(struct hda_codec *codec, unsigned int res) 1228 - { 1229 - if ((res >> 26) != AD1988_HP_EVENT) 1230 - return; 1231 - if (snd_hda_jack_detect(codec, 0x11)) 1232 - snd_hda_sequence_write(codec, ad1988_laptop_hp_on); 1233 - else 1234 - snd_hda_sequence_write(codec, ad1988_laptop_hp_off); 1235 - } 1236 - 1237 - #ifdef CONFIG_PM 1238 - static const struct hda_amp_list ad1988_loopbacks[] = { 1239 - { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 1240 - { 0x20, HDA_INPUT, 1 }, /* Line */ 1241 - { 0x20, HDA_INPUT, 4 }, /* Mic */ 1242 - { 0x20, HDA_INPUT, 6 }, /* CD */ 1243 - { } /* end */ 1244 - }; 1245 - #endif 1246 2512 #endif /* ENABLE_AD_STATIC_QUIRKS */ 1247 2513 1248 2514 static int ad1988_auto_smux_enum_info(struct snd_kcontrol *kcontrol, ··· 828 3220 /* 829 3221 */ 830 3222 831 - static int ad1988_parse_auto_config(struct hda_codec *codec) 3223 + enum { 3224 + AD1988_FIXUP_6STACK_DIG, 3225 + }; 3226 + 3227 + static const struct hda_fixup ad1988_fixups[] = { 3228 + [AD1988_FIXUP_6STACK_DIG] = { 3229 + .type = HDA_FIXUP_PINS, 3230 + .v.pins = (const struct hda_pintbl[]) { 3231 + { 0x11, 0x02214130 }, /* front-hp */ 3232 + { 0x12, 0x01014010 }, /* line-out */ 3233 + { 0x14, 0x02a19122 }, /* front-mic */ 3234 + { 0x15, 0x01813021 }, /* line-in */ 3235 + { 0x16, 0x01011012 }, /* line-out */ 3236 + { 0x17, 0x01a19020 }, /* mic */ 3237 + { 0x1b, 0x0145f1f0 }, /* SPDIF */ 3238 + { 0x24, 0x01016011 }, /* line-out */ 3239 + { 0x25, 0x01012013 }, /* line-out */ 3240 + { } 3241 + } 3242 + }, 3243 + }; 3244 + 3245 + static const struct hda_model_fixup ad1988_fixup_models[] = { 3246 + { .id = AD1988_FIXUP_6STACK_DIG, .name = "6stack-dig" }, 3247 + {} 3248 + }; 3249 + 3250 + static int patch_ad1988(struct hda_codec *codec) 832 3251 { 833 3252 struct ad198x_spec *spec; 834 3253 int err; ··· 869 3234 spec->gen.mixer_merge_nid = 0x21; 870 3235 spec->gen.beep_nid = 0x10; 871 3236 set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 3237 + 3238 + snd_hda_pick_fixup(codec, ad1988_fixup_models, NULL, ad1988_fixups); 3239 + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 3240 + 872 3241 err = ad198x_parse_auto_config(codec); 873 3242 if (err < 0) 874 3243 goto error; 875 3244 err = ad1988_add_spdif_mux_ctl(codec); 876 3245 if (err < 0) 877 3246 goto error; 3247 + 3248 + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 3249 + 878 3250 return 0; 879 3251 880 3252 error: 881 3253 snd_hda_gen_free(codec); 882 3254 return err; 883 3255 } 884 - 885 - /* 886 - */ 887 - 888 - #ifdef ENABLE_AD_STATIC_QUIRKS 889 - static const char * const ad1988_models[AD1988_MODEL_LAST] = { 890 - [AD1988_6STACK] = "6stack", 891 - [AD1988_6STACK_DIG] = "6stack-dig", 892 - [AD1988_3STACK] = "3stack", 893 - [AD1988_3STACK_DIG] = "3stack-dig", 894 - [AD1988_LAPTOP] = "laptop", 895 - [AD1988_LAPTOP_DIG] = "laptop-dig", 896 - [AD1988_AUTO] = "auto", 897 - }; 898 - 899 - static const struct snd_pci_quirk ad1988_cfg_tbl[] = { 900 - SND_PCI_QUIRK(0x1043, 0x81ec, "Asus P5B-DLX", AD1988_6STACK_DIG), 901 - SND_PCI_QUIRK(0x1043, 0x81f6, "Asus M2N-SLI", AD1988_6STACK_DIG), 902 - SND_PCI_QUIRK(0x1043, 0x8277, "Asus P5K-E/WIFI-AP", AD1988_6STACK_DIG), 903 - SND_PCI_QUIRK(0x1043, 0x82c0, "Asus M3N-HT Deluxe", AD1988_6STACK_DIG), 904 - SND_PCI_QUIRK(0x1043, 0x8311, "Asus P5Q-Premium/Pro", AD1988_6STACK_DIG), 905 - {} 906 - }; 907 - 908 - static int patch_ad1988(struct hda_codec *codec) 909 - { 910 - struct ad198x_spec *spec; 911 - int err, board_config; 912 - 913 - board_config = snd_hda_check_board_config(codec, AD1988_MODEL_LAST, 914 - ad1988_models, ad1988_cfg_tbl); 915 - if (board_config < 0) { 916 - printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 917 - codec->chip_name); 918 - board_config = AD1988_AUTO; 919 - } 920 - 921 - if (board_config == AD1988_AUTO) 922 - return ad1988_parse_auto_config(codec); 923 - 924 - err = alloc_ad_spec(codec); 925 - if (err < 0) 926 - return err; 927 - spec = codec->spec; 928 - 929 - if (is_rev2(codec)) 930 - snd_printk(KERN_INFO "patch_analog: AD1988A rev.2 is detected, enable workarounds\n"); 931 - 932 - err = snd_hda_attach_beep_device(codec, 0x10); 933 - if (err < 0) { 934 - ad198x_free(codec); 935 - return err; 936 - } 937 - set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 938 - 939 - if (!spec->multiout.hp_nid) 940 - spec->multiout.hp_nid = ad1988_alt_dac_nid[0]; 941 - switch (board_config) { 942 - case AD1988_6STACK: 943 - case AD1988_6STACK_DIG: 944 - spec->multiout.max_channels = 8; 945 - spec->multiout.num_dacs = 4; 946 - if (is_rev2(codec)) 947 - spec->multiout.dac_nids = ad1988_6stack_dac_nids_rev2; 948 - else 949 - spec->multiout.dac_nids = ad1988_6stack_dac_nids; 950 - spec->input_mux = &ad1988_6stack_capture_source; 951 - spec->num_mixers = 2; 952 - if (is_rev2(codec)) 953 - spec->mixers[0] = ad1988_6stack_mixers1_rev2; 954 - else 955 - spec->mixers[0] = ad1988_6stack_mixers1; 956 - spec->mixers[1] = ad1988_6stack_mixers2; 957 - spec->num_init_verbs = 1; 958 - spec->init_verbs[0] = ad1988_6stack_init_verbs; 959 - if (board_config == AD1988_6STACK_DIG) { 960 - spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 961 - spec->dig_in_nid = AD1988_SPDIF_IN; 962 - } 963 - break; 964 - case AD1988_3STACK: 965 - case AD1988_3STACK_DIG: 966 - spec->multiout.max_channels = 6; 967 - spec->multiout.num_dacs = 3; 968 - if (is_rev2(codec)) 969 - spec->multiout.dac_nids = ad1988_3stack_dac_nids_rev2; 970 - else 971 - spec->multiout.dac_nids = ad1988_3stack_dac_nids; 972 - spec->input_mux = &ad1988_6stack_capture_source; 973 - spec->channel_mode = ad1988_3stack_modes; 974 - spec->num_channel_mode = ARRAY_SIZE(ad1988_3stack_modes); 975 - spec->num_mixers = 2; 976 - if (is_rev2(codec)) 977 - spec->mixers[0] = ad1988_3stack_mixers1_rev2; 978 - else 979 - spec->mixers[0] = ad1988_3stack_mixers1; 980 - spec->mixers[1] = ad1988_3stack_mixers2; 981 - spec->num_init_verbs = 1; 982 - spec->init_verbs[0] = ad1988_3stack_init_verbs; 983 - if (board_config == AD1988_3STACK_DIG) 984 - spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 985 - break; 986 - case AD1988_LAPTOP: 987 - case AD1988_LAPTOP_DIG: 988 - spec->multiout.max_channels = 2; 989 - spec->multiout.num_dacs = 1; 990 - spec->multiout.dac_nids = ad1988_3stack_dac_nids; 991 - spec->input_mux = &ad1988_laptop_capture_source; 992 - spec->num_mixers = 1; 993 - spec->mixers[0] = ad1988_laptop_mixers; 994 - codec->inv_eapd = 1; /* inverted EAPD */ 995 - spec->num_init_verbs = 1; 996 - spec->init_verbs[0] = ad1988_laptop_init_verbs; 997 - if (board_config == AD1988_LAPTOP_DIG) 998 - spec->multiout.dig_out_nid = AD1988_SPDIF_OUT; 999 - break; 1000 - } 1001 - 1002 - spec->num_adc_nids = ARRAY_SIZE(ad1988_adc_nids); 1003 - spec->adc_nids = ad1988_adc_nids; 1004 - spec->capsrc_nids = ad1988_capsrc_nids; 1005 - spec->mixers[spec->num_mixers++] = ad1988_capture_mixers; 1006 - spec->init_verbs[spec->num_init_verbs++] = ad1988_capture_init_verbs; 1007 - if (spec->multiout.dig_out_nid) { 1008 - if (codec->vendor_id >= 0x11d4989a) { 1009 - spec->mixers[spec->num_mixers++] = 1010 - ad1989_spdif_out_mixers; 1011 - spec->init_verbs[spec->num_init_verbs++] = 1012 - ad1989_spdif_init_verbs; 1013 - codec->slave_dig_outs = ad1989b_slave_dig_outs; 1014 - } else { 1015 - spec->mixers[spec->num_mixers++] = 1016 - ad1988_spdif_out_mixers; 1017 - spec->init_verbs[spec->num_init_verbs++] = 1018 - ad1988_spdif_init_verbs; 1019 - } 1020 - } 1021 - if (spec->dig_in_nid && codec->vendor_id < 0x11d4989a) { 1022 - spec->mixers[spec->num_mixers++] = ad1988_spdif_in_mixers; 1023 - spec->init_verbs[spec->num_init_verbs++] = 1024 - ad1988_spdif_in_init_verbs; 1025 - } 1026 - 1027 - codec->patch_ops = ad198x_patch_ops; 1028 - switch (board_config) { 1029 - case AD1988_LAPTOP: 1030 - case AD1988_LAPTOP_DIG: 1031 - codec->patch_ops.unsol_event = ad1988_laptop_unsol_event; 1032 - break; 1033 - } 1034 - #ifdef CONFIG_PM 1035 - spec->loopback.amplist = ad1988_loopbacks; 1036 - #endif 1037 - spec->vmaster_nid = 0x04; 1038 - 1039 - codec->no_trigger_sense = 1; 1040 - codec->no_sticky_stream = 1; 1041 - 1042 - return 0; 1043 - } 1044 - #else /* ENABLE_AD_STATIC_QUIRKS */ 1045 - #define patch_ad1988 ad1988_parse_auto_config 1046 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 1047 3256 1048 3257 1049 3258 /* ··· 902 3423 * 903 3424 * AD1984 = AD1884 + two digital mic-ins 904 3425 * 905 - * FIXME: 906 - * For simplicity, we share the single DAC for both HP and line-outs 907 - * right now. The inidividual playbacks could be easily implemented, 908 - * but no build-up framework is given, so far. 3426 + * AD1883 / AD1884A / AD1984A / AD1984B 3427 + * 3428 + * port-B (0x14) - front mic-in 3429 + * port-E (0x1c) - rear mic-in 3430 + * port-F (0x16) - CD / ext out 3431 + * port-C (0x15) - rear line-in 3432 + * port-D (0x12) - rear line-out 3433 + * port-A (0x11) - front hp-out 3434 + * 3435 + * AD1984A = AD1884A + digital-mic 3436 + * AD1883 = equivalent with AD1984A 3437 + * AD1984B = AD1984A + extra SPDIF-out 909 3438 */ 910 - 911 - #ifdef ENABLE_AD_STATIC_QUIRKS 912 - static const hda_nid_t ad1884_dac_nids[1] = { 913 - 0x04, 914 - }; 915 - 916 - static const hda_nid_t ad1884_adc_nids[2] = { 917 - 0x08, 0x09, 918 - }; 919 - 920 - static const hda_nid_t ad1884_capsrc_nids[2] = { 921 - 0x0c, 0x0d, 922 - }; 923 - 924 - #define AD1884_SPDIF_OUT 0x02 925 - 926 - static const struct hda_input_mux ad1884_capture_source = { 927 - .num_items = 4, 928 - .items = { 929 - { "Front Mic", 0x0 }, 930 - { "Mic", 0x1 }, 931 - { "CD", 0x2 }, 932 - { "Mix", 0x3 }, 933 - }, 934 - }; 935 - 936 - static const struct snd_kcontrol_new ad1884_base_mixers[] = { 937 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 938 - /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ 939 - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 940 - HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), 941 - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 942 - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 943 - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 944 - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 945 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 946 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 947 - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), 948 - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), 949 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT), 950 - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 951 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 952 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 953 - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 954 - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 955 - { 956 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 957 - /* The multiple "Capture Source" controls confuse alsamixer 958 - * So call somewhat different.. 959 - */ 960 - /* .name = "Capture Source", */ 961 - .name = "Input Source", 962 - .count = 2, 963 - .info = ad198x_mux_enum_info, 964 - .get = ad198x_mux_enum_get, 965 - .put = ad198x_mux_enum_put, 966 - }, 967 - /* SPDIF controls */ 968 - HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 969 - { 970 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 971 - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 972 - /* identical with ad1983 */ 973 - .info = ad1983_spdif_route_info, 974 - .get = ad1983_spdif_route_get, 975 - .put = ad1983_spdif_route_put, 976 - }, 977 - { } /* end */ 978 - }; 979 - 980 - static const struct snd_kcontrol_new ad1984_dmic_mixers[] = { 981 - HDA_CODEC_VOLUME("Digital Mic Capture Volume", 0x05, 0x0, HDA_INPUT), 982 - HDA_CODEC_MUTE("Digital Mic Capture Switch", 0x05, 0x0, HDA_INPUT), 983 - HDA_CODEC_VOLUME_IDX("Digital Mic Capture Volume", 1, 0x06, 0x0, 984 - HDA_INPUT), 985 - HDA_CODEC_MUTE_IDX("Digital Mic Capture Switch", 1, 0x06, 0x0, 986 - HDA_INPUT), 987 - { } /* end */ 988 - }; 989 - 990 - /* 991 - * initialization verbs 992 - */ 993 - static const struct hda_verb ad1884_init_verbs[] = { 994 - /* DACs; mute as default */ 995 - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 996 - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 997 - /* Port-A (HP) mixer */ 998 - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 999 - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1000 - /* Port-A pin */ 1001 - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1002 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1003 - /* HP selector - select DAC2 */ 1004 - {0x22, AC_VERB_SET_CONNECT_SEL, 0x1}, 1005 - /* Port-D (Line-out) mixer */ 1006 - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1007 - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1008 - /* Port-D pin */ 1009 - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1010 - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1011 - /* Mono-out mixer */ 1012 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1013 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1014 - /* Mono-out pin */ 1015 - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1016 - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1017 - /* Mono selector */ 1018 - {0x0e, AC_VERB_SET_CONNECT_SEL, 0x1}, 1019 - /* Port-B (front mic) pin */ 1020 - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1021 - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1022 - /* Port-C (rear mic) pin */ 1023 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1024 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1025 - /* Analog mixer; mute as default */ 1026 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1027 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1028 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1029 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1030 - /* Analog Mix output amp */ 1031 - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ 1032 - /* SPDIF output selector */ 1033 - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ 1034 - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 1035 - { } /* end */ 1036 - }; 1037 - 1038 - #ifdef CONFIG_PM 1039 - static const struct hda_amp_list ad1884_loopbacks[] = { 1040 - { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 1041 - { 0x20, HDA_INPUT, 1 }, /* Mic */ 1042 - { 0x20, HDA_INPUT, 2 }, /* CD */ 1043 - { 0x20, HDA_INPUT, 4 }, /* Docking */ 1044 - { } /* end */ 1045 - }; 1046 - #endif 1047 - 1048 - static const char * const ad1884_slave_vols[] = { 1049 - "PCM", "Mic", "Mono", "Front Mic", "Mic", "CD", 1050 - "Internal Mic", "Dock Mic", /* "Beep", */ "IEC958", 1051 - NULL 1052 - }; 1053 - 1054 - enum { 1055 - AD1884_AUTO, 1056 - AD1884_BASIC, 1057 - AD1884_MODELS 1058 - }; 1059 - 1060 - static const char * const ad1884_models[AD1884_MODELS] = { 1061 - [AD1884_AUTO] = "auto", 1062 - [AD1884_BASIC] = "basic", 1063 - }; 1064 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 1065 - 1066 3439 1067 3440 /* set the upper-limit for mixer amp to 0dB for avoiding the possible 1068 3441 * damage by overloading ··· 930 3599 (1 << AC_AMPCAP_MUTE_SHIFT)); 931 3600 } 932 3601 3602 + /* toggle GPIO1 according to the mute state */ 3603 + static void ad1884_vmaster_hp_gpio_hook(void *private_data, int enabled) 3604 + { 3605 + struct hda_codec *codec = private_data; 3606 + struct ad198x_spec *spec = codec->spec; 3607 + 3608 + if (spec->eapd_nid) 3609 + ad_vmaster_eapd_hook(private_data, enabled); 3610 + snd_hda_codec_update_cache(codec, 0x01, 0, 3611 + AC_VERB_SET_GPIO_DATA, 3612 + enabled ? 0x00 : 0x02); 3613 + } 3614 + 933 3615 static void ad1884_fixup_hp_eapd(struct hda_codec *codec, 934 3616 const struct hda_fixup *fix, int action) 935 3617 { 936 3618 struct ad198x_spec *spec = codec->spec; 3619 + static const struct hda_verb gpio_init_verbs[] = { 3620 + {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 3621 + {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 3622 + {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, 3623 + {}, 3624 + }; 937 3625 938 3626 switch (action) { 939 3627 case HDA_FIXUP_ACT_PRE_PROBE: 940 - spec->gen.vmaster_mute.hook = ad_vmaster_eapd_hook; 3628 + spec->gen.vmaster_mute.hook = ad1884_vmaster_hp_gpio_hook; 3629 + snd_hda_sequence_write_cache(codec, gpio_init_verbs); 941 3630 break; 942 3631 case HDA_FIXUP_ACT_PROBE: 943 3632 if (spec->gen.autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT) ··· 968 3617 } 969 3618 } 970 3619 3620 + /* set magic COEFs for dmic */ 3621 + static const struct hda_verb ad1884_dmic_init_verbs[] = { 3622 + {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7}, 3623 + {0x01, AC_VERB_SET_PROC_COEF, 0x08}, 3624 + {} 3625 + }; 3626 + 971 3627 enum { 972 3628 AD1884_FIXUP_AMP_OVERRIDE, 973 3629 AD1884_FIXUP_HP_EAPD, 3630 + AD1884_FIXUP_DMIC_COEF, 3631 + AD1884_FIXUP_HP_TOUCHSMART, 974 3632 }; 975 3633 976 3634 static const struct hda_fixup ad1884_fixups[] = { ··· 993 3633 .chained = true, 994 3634 .chain_id = AD1884_FIXUP_AMP_OVERRIDE, 995 3635 }, 3636 + [AD1884_FIXUP_DMIC_COEF] = { 3637 + .type = HDA_FIXUP_VERBS, 3638 + .v.verbs = ad1884_dmic_init_verbs, 3639 + }, 3640 + [AD1884_FIXUP_HP_TOUCHSMART] = { 3641 + .type = HDA_FIXUP_VERBS, 3642 + .v.verbs = ad1884_dmic_init_verbs, 3643 + .chained = true, 3644 + .chain_id = AD1884_FIXUP_HP_EAPD, 3645 + }, 996 3646 }; 997 3647 998 3648 static const struct snd_pci_quirk ad1884_fixup_tbl[] = { 3649 + SND_PCI_QUIRK(0x103c, 0x2a82, "HP Touchsmart", AD1884_FIXUP_HP_TOUCHSMART), 999 3650 SND_PCI_QUIRK_VENDOR(0x103c, "HP", AD1884_FIXUP_HP_EAPD), 3651 + SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1884_FIXUP_DMIC_COEF), 1000 3652 {} 1001 3653 }; 1002 3654 1003 3655 1004 - static int ad1884_parse_auto_config(struct hda_codec *codec) 3656 + static int patch_ad1884(struct hda_codec *codec) 1005 3657 { 1006 3658 struct ad198x_spec *spec; 1007 3659 int err; ··· 1046 3674 return err; 1047 3675 } 1048 3676 1049 - #ifdef ENABLE_AD_STATIC_QUIRKS 1050 - static int patch_ad1884_basic(struct hda_codec *codec) 1051 - { 1052 - struct ad198x_spec *spec; 1053 - int err; 1054 - 1055 - err = alloc_ad_spec(codec); 1056 - if (err < 0) 1057 - return err; 1058 - spec = codec->spec; 1059 - 1060 - err = snd_hda_attach_beep_device(codec, 0x10); 1061 - if (err < 0) { 1062 - ad198x_free(codec); 1063 - return err; 1064 - } 1065 - set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 1066 - 1067 - spec->multiout.max_channels = 2; 1068 - spec->multiout.num_dacs = ARRAY_SIZE(ad1884_dac_nids); 1069 - spec->multiout.dac_nids = ad1884_dac_nids; 1070 - spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; 1071 - spec->num_adc_nids = ARRAY_SIZE(ad1884_adc_nids); 1072 - spec->adc_nids = ad1884_adc_nids; 1073 - spec->capsrc_nids = ad1884_capsrc_nids; 1074 - spec->input_mux = &ad1884_capture_source; 1075 - spec->num_mixers = 1; 1076 - spec->mixers[0] = ad1884_base_mixers; 1077 - spec->num_init_verbs = 1; 1078 - spec->init_verbs[0] = ad1884_init_verbs; 1079 - spec->spdif_route = 0; 1080 - #ifdef CONFIG_PM 1081 - spec->loopback.amplist = ad1884_loopbacks; 1082 - #endif 1083 - spec->vmaster_nid = 0x04; 1084 - /* we need to cover all playback volumes */ 1085 - spec->slave_vols = ad1884_slave_vols; 1086 - /* slaves may contain input volumes, so we can't raise to 0dB blindly */ 1087 - spec->avoid_init_slave_vol = 1; 1088 - 1089 - codec->patch_ops = ad198x_patch_ops; 1090 - 1091 - codec->no_trigger_sense = 1; 1092 - codec->no_sticky_stream = 1; 1093 - 1094 - return 0; 1095 - } 1096 - 1097 - static int patch_ad1884(struct hda_codec *codec) 1098 - { 1099 - int board_config; 1100 - 1101 - board_config = snd_hda_check_board_config(codec, AD1884_MODELS, 1102 - ad1884_models, NULL); 1103 - if (board_config < 0) { 1104 - printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 1105 - codec->chip_name); 1106 - board_config = AD1884_AUTO; 1107 - } 1108 - 1109 - if (board_config == AD1884_AUTO) 1110 - return ad1884_parse_auto_config(codec); 1111 - else 1112 - return patch_ad1884_basic(codec); 1113 - } 1114 - #else /* ENABLE_AD_STATIC_QUIRKS */ 1115 - #define patch_ad1884 ad1884_parse_auto_config 1116 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 1117 - 1118 - 1119 - #ifdef ENABLE_AD_STATIC_QUIRKS 1120 - /* 1121 - * Lenovo Thinkpad T61/X61 1122 - */ 1123 - static const struct hda_input_mux ad1984_thinkpad_capture_source = { 1124 - .num_items = 4, 1125 - .items = { 1126 - { "Mic", 0x0 }, 1127 - { "Internal Mic", 0x1 }, 1128 - { "Mix", 0x3 }, 1129 - { "Dock Mic", 0x4 }, 1130 - }, 1131 - }; 1132 - 1133 - 1134 - /* 1135 - * Dell Precision T3400 1136 - */ 1137 - static const struct hda_input_mux ad1984_dell_desktop_capture_source = { 1138 - .num_items = 3, 1139 - .items = { 1140 - { "Front Mic", 0x0 }, 1141 - { "Line-In", 0x1 }, 1142 - { "Mix", 0x3 }, 1143 - }, 1144 - }; 1145 - 1146 - 1147 - static const struct snd_kcontrol_new ad1984_thinkpad_mixers[] = { 1148 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 1149 - /* HDA_CODEC_VOLUME_IDX("PCM Playback Volume", 1, 0x03, 0x0, HDA_OUTPUT), */ 1150 - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 1151 - HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1152 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 1153 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 1154 - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 1155 - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 1156 - HDA_CODEC_VOLUME("Beep Playback Volume", 0x20, 0x03, HDA_INPUT), 1157 - HDA_CODEC_MUTE("Beep Playback Switch", 0x20, 0x03, HDA_INPUT), 1158 - HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 1159 - HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 1160 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 1161 - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT), 1162 - HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), 1163 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 1164 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 1165 - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 1166 - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 1167 - { 1168 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1169 - /* The multiple "Capture Source" controls confuse alsamixer 1170 - * So call somewhat different.. 1171 - */ 1172 - /* .name = "Capture Source", */ 1173 - .name = "Input Source", 1174 - .count = 2, 1175 - .info = ad198x_mux_enum_info, 1176 - .get = ad198x_mux_enum_get, 1177 - .put = ad198x_mux_enum_put, 1178 - }, 1179 - /* SPDIF controls */ 1180 - HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 1181 - { 1182 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1183 - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1184 - /* identical with ad1983 */ 1185 - .info = ad1983_spdif_route_info, 1186 - .get = ad1983_spdif_route_get, 1187 - .put = ad1983_spdif_route_put, 1188 - }, 1189 - { } /* end */ 1190 - }; 1191 - 1192 - /* additional verbs */ 1193 - static const struct hda_verb ad1984_thinkpad_init_verbs[] = { 1194 - /* Port-E (docking station mic) pin */ 1195 - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1196 - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1197 - /* docking mic boost */ 1198 - {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1199 - /* Analog PC Beeper - allow firmware/ACPI beeps */ 1200 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(3) | 0x1a}, 1201 - /* Analog mixer - docking mic; mute as default */ 1202 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1203 - /* enable EAPD bit */ 1204 - {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 1205 - { } /* end */ 1206 - }; 1207 - 1208 - /* 1209 - * Dell Precision T3400 1210 - */ 1211 - static const struct snd_kcontrol_new ad1984_dell_desktop_mixers[] = { 1212 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x04, 0x0, HDA_OUTPUT), 1213 - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 1214 - HDA_CODEC_MUTE("Speaker Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1215 - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 1216 - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 1217 - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 1218 - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 1219 - HDA_CODEC_VOLUME("Line-In Playback Volume", 0x20, 0x01, HDA_INPUT), 1220 - HDA_CODEC_MUTE("Line-In Playback Switch", 0x20, 0x01, HDA_INPUT), 1221 - HDA_CODEC_VOLUME("Line-In Boost Volume", 0x15, 0x0, HDA_INPUT), 1222 - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 1223 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 1224 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 1225 - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 1226 - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 1227 - { 1228 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1229 - /* The multiple "Capture Source" controls confuse alsamixer 1230 - * So call somewhat different.. 1231 - */ 1232 - /* .name = "Capture Source", */ 1233 - .name = "Input Source", 1234 - .count = 2, 1235 - .info = ad198x_mux_enum_info, 1236 - .get = ad198x_mux_enum_get, 1237 - .put = ad198x_mux_enum_put, 1238 - }, 1239 - { } /* end */ 1240 - }; 1241 - 1242 - /* Digial MIC ADC NID 0x05 + 0x06 */ 1243 - static int ad1984_pcm_dmic_prepare(struct hda_pcm_stream *hinfo, 1244 - struct hda_codec *codec, 1245 - unsigned int stream_tag, 1246 - unsigned int format, 1247 - struct snd_pcm_substream *substream) 1248 - { 1249 - snd_hda_codec_setup_stream(codec, 0x05 + substream->number, 1250 - stream_tag, 0, format); 1251 - return 0; 1252 - } 1253 - 1254 - static int ad1984_pcm_dmic_cleanup(struct hda_pcm_stream *hinfo, 1255 - struct hda_codec *codec, 1256 - struct snd_pcm_substream *substream) 1257 - { 1258 - snd_hda_codec_cleanup_stream(codec, 0x05 + substream->number); 1259 - return 0; 1260 - } 1261 - 1262 - static const struct hda_pcm_stream ad1984_pcm_dmic_capture = { 1263 - .substreams = 2, 1264 - .channels_min = 2, 1265 - .channels_max = 2, 1266 - .nid = 0x05, 1267 - .ops = { 1268 - .prepare = ad1984_pcm_dmic_prepare, 1269 - .cleanup = ad1984_pcm_dmic_cleanup 1270 - }, 1271 - }; 1272 - 1273 - static int ad1984_build_pcms(struct hda_codec *codec) 1274 - { 1275 - struct ad198x_spec *spec = codec->spec; 1276 - struct hda_pcm *info; 1277 - int err; 1278 - 1279 - err = ad198x_build_pcms(codec); 1280 - if (err < 0) 1281 - return err; 1282 - 1283 - info = spec->pcm_rec + codec->num_pcms; 1284 - codec->num_pcms++; 1285 - info->name = "AD1984 Digital Mic"; 1286 - info->stream[SNDRV_PCM_STREAM_CAPTURE] = ad1984_pcm_dmic_capture; 1287 - return 0; 1288 - } 1289 - 1290 - /* models */ 1291 - enum { 1292 - AD1984_AUTO, 1293 - AD1984_BASIC, 1294 - AD1984_THINKPAD, 1295 - AD1984_DELL_DESKTOP, 1296 - AD1984_MODELS 1297 - }; 1298 - 1299 - static const char * const ad1984_models[AD1984_MODELS] = { 1300 - [AD1984_AUTO] = "auto", 1301 - [AD1984_BASIC] = "basic", 1302 - [AD1984_THINKPAD] = "thinkpad", 1303 - [AD1984_DELL_DESKTOP] = "dell_desktop", 1304 - }; 1305 - 1306 - static const struct snd_pci_quirk ad1984_cfg_tbl[] = { 1307 - /* Lenovo Thinkpad T61/X61 */ 1308 - SND_PCI_QUIRK_VENDOR(0x17aa, "Lenovo Thinkpad", AD1984_THINKPAD), 1309 - SND_PCI_QUIRK(0x1028, 0x0214, "Dell T3400", AD1984_DELL_DESKTOP), 1310 - SND_PCI_QUIRK(0x1028, 0x0233, "Dell Latitude E6400", AD1984_DELL_DESKTOP), 1311 - {} 1312 - }; 1313 - 1314 - static int patch_ad1984(struct hda_codec *codec) 1315 - { 1316 - struct ad198x_spec *spec; 1317 - int board_config, err; 1318 - 1319 - board_config = snd_hda_check_board_config(codec, AD1984_MODELS, 1320 - ad1984_models, ad1984_cfg_tbl); 1321 - if (board_config < 0) { 1322 - printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 1323 - codec->chip_name); 1324 - board_config = AD1984_AUTO; 1325 - } 1326 - 1327 - if (board_config == AD1984_AUTO) 1328 - return ad1884_parse_auto_config(codec); 1329 - 1330 - err = patch_ad1884_basic(codec); 1331 - if (err < 0) 1332 - return err; 1333 - spec = codec->spec; 1334 - 1335 - switch (board_config) { 1336 - case AD1984_BASIC: 1337 - /* additional digital mics */ 1338 - spec->mixers[spec->num_mixers++] = ad1984_dmic_mixers; 1339 - codec->patch_ops.build_pcms = ad1984_build_pcms; 1340 - break; 1341 - case AD1984_THINKPAD: 1342 - if (codec->subsystem_id == 0x17aa20fb) { 1343 - /* Thinpad X300 does not have the ability to do SPDIF, 1344 - or attach to docking station to use SPDIF */ 1345 - spec->multiout.dig_out_nid = 0; 1346 - } else 1347 - spec->multiout.dig_out_nid = AD1884_SPDIF_OUT; 1348 - spec->input_mux = &ad1984_thinkpad_capture_source; 1349 - spec->mixers[0] = ad1984_thinkpad_mixers; 1350 - spec->init_verbs[spec->num_init_verbs++] = ad1984_thinkpad_init_verbs; 1351 - spec->analog_beep = 1; 1352 - break; 1353 - case AD1984_DELL_DESKTOP: 1354 - spec->multiout.dig_out_nid = 0; 1355 - spec->input_mux = &ad1984_dell_desktop_capture_source; 1356 - spec->mixers[0] = ad1984_dell_desktop_mixers; 1357 - break; 1358 - } 1359 - return 0; 1360 - } 1361 - #else /* ENABLE_AD_STATIC_QUIRKS */ 1362 - #define patch_ad1984 ad1884_parse_auto_config 1363 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 1364 - 1365 - 1366 - /* 1367 - * AD1883 / AD1884A / AD1984A / AD1984B 1368 - * 1369 - * port-B (0x14) - front mic-in 1370 - * port-E (0x1c) - rear mic-in 1371 - * port-F (0x16) - CD / ext out 1372 - * port-C (0x15) - rear line-in 1373 - * port-D (0x12) - rear line-out 1374 - * port-A (0x11) - front hp-out 1375 - * 1376 - * AD1984A = AD1884A + digital-mic 1377 - * AD1883 = equivalent with AD1984A 1378 - * AD1984B = AD1984A + extra SPDIF-out 1379 - * 1380 - * FIXME: 1381 - * We share the single DAC for both HP and line-outs (see AD1884/1984). 1382 - */ 1383 - 1384 - #ifdef ENABLE_AD_STATIC_QUIRKS 1385 - static const hda_nid_t ad1884a_dac_nids[1] = { 1386 - 0x03, 1387 - }; 1388 - 1389 - #define ad1884a_adc_nids ad1884_adc_nids 1390 - #define ad1884a_capsrc_nids ad1884_capsrc_nids 1391 - 1392 - #define AD1884A_SPDIF_OUT 0x02 1393 - 1394 - static const struct hda_input_mux ad1884a_capture_source = { 1395 - .num_items = 5, 1396 - .items = { 1397 - { "Front Mic", 0x0 }, 1398 - { "Mic", 0x4 }, 1399 - { "Line", 0x1 }, 1400 - { "CD", 0x2 }, 1401 - { "Mix", 0x3 }, 1402 - }, 1403 - }; 1404 - 1405 - static const struct snd_kcontrol_new ad1884a_base_mixers[] = { 1406 - HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 1407 - HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 1408 - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 1409 - HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1410 - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 1411 - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 1412 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 1413 - HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 1414 - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 1415 - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 1416 - HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT), 1417 - HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT), 1418 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 1419 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 1420 - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x02, HDA_INPUT), 1421 - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x02, HDA_INPUT), 1422 - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 1423 - HDA_CODEC_VOLUME("Line Boost Volume", 0x15, 0x0, HDA_INPUT), 1424 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), 1425 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 1426 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 1427 - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 1428 - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 1429 - { 1430 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1431 - /* The multiple "Capture Source" controls confuse alsamixer 1432 - * So call somewhat different.. 1433 - */ 1434 - /* .name = "Capture Source", */ 1435 - .name = "Input Source", 1436 - .count = 2, 1437 - .info = ad198x_mux_enum_info, 1438 - .get = ad198x_mux_enum_get, 1439 - .put = ad198x_mux_enum_put, 1440 - }, 1441 - /* SPDIF controls */ 1442 - HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 1443 - { 1444 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1445 - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1446 - /* identical with ad1983 */ 1447 - .info = ad1983_spdif_route_info, 1448 - .get = ad1983_spdif_route_get, 1449 - .put = ad1983_spdif_route_put, 1450 - }, 1451 - { } /* end */ 1452 - }; 1453 - 1454 - /* 1455 - * initialization verbs 1456 - */ 1457 - static const struct hda_verb ad1884a_init_verbs[] = { 1458 - /* DACs; unmute as default */ 1459 - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 1460 - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 1461 - /* Port-A (HP) mixer - route only from analog mixer */ 1462 - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1463 - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1464 - /* Port-A pin */ 1465 - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1466 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1467 - /* Port-D (Line-out) mixer - route only from analog mixer */ 1468 - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1469 - {0x0a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1470 - /* Port-D pin */ 1471 - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1472 - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1473 - /* Mono-out mixer - route only from analog mixer */ 1474 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1475 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1476 - /* Mono-out pin */ 1477 - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1478 - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1479 - /* Port-B (front mic) pin */ 1480 - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1481 - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1482 - /* Port-C (rear line-in) pin */ 1483 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1484 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1485 - /* Port-E (rear mic) pin */ 1486 - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1487 - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1488 - {0x25, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* no boost */ 1489 - /* Port-F (CD) pin */ 1490 - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1491 - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1492 - /* Analog mixer; mute as default */ 1493 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1494 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1495 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1496 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1497 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(4)}, /* aux */ 1498 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 1499 - /* Analog Mix output amp */ 1500 - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1501 - /* capture sources */ 1502 - {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, 1503 - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1504 - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 1505 - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1506 - /* SPDIF output amp */ 1507 - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 1508 - { } /* end */ 1509 - }; 1510 - 1511 - #ifdef CONFIG_PM 1512 - static const struct hda_amp_list ad1884a_loopbacks[] = { 1513 - { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 1514 - { 0x20, HDA_INPUT, 1 }, /* Mic */ 1515 - { 0x20, HDA_INPUT, 2 }, /* CD */ 1516 - { 0x20, HDA_INPUT, 4 }, /* Docking */ 1517 - { } /* end */ 1518 - }; 1519 - #endif 1520 - 1521 - /* 1522 - * Laptop model 1523 - * 1524 - * Port A: Headphone jack 1525 - * Port B: MIC jack 1526 - * Port C: Internal MIC 1527 - * Port D: Dock Line Out (if enabled) 1528 - * Port E: Dock Line In (if enabled) 1529 - * Port F: Internal speakers 1530 - */ 1531 - 1532 - static int ad1884a_mobile_master_sw_put(struct snd_kcontrol *kcontrol, 1533 - struct snd_ctl_elem_value *ucontrol) 1534 - { 1535 - struct hda_codec *codec = snd_kcontrol_chip(kcontrol); 1536 - int ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol); 1537 - int mute = (!ucontrol->value.integer.value[0] && 1538 - !ucontrol->value.integer.value[1]); 1539 - /* toggle GPIO1 according to the mute state */ 1540 - snd_hda_codec_write_cache(codec, 0x01, 0, AC_VERB_SET_GPIO_DATA, 1541 - mute ? 0x02 : 0x0); 1542 - return ret; 1543 - } 1544 - 1545 - static const struct snd_kcontrol_new ad1884a_laptop_mixers[] = { 1546 - HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 1547 - { 1548 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1549 - .name = "Master Playback Switch", 1550 - .subdevice = HDA_SUBDEV_AMP_FLAG, 1551 - .info = snd_hda_mixer_amp_switch_info, 1552 - .get = snd_hda_mixer_amp_switch_get, 1553 - .put = ad1884a_mobile_master_sw_put, 1554 - .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 1555 - }, 1556 - HDA_CODEC_MUTE("Dock Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1557 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 1558 - HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 1559 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 1560 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 1561 - HDA_CODEC_VOLUME("Internal Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 1562 - HDA_CODEC_MUTE("Internal Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 1563 - HDA_CODEC_VOLUME("Dock Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 1564 - HDA_CODEC_MUTE("Dock Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 1565 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 1566 - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x15, 0x0, HDA_INPUT), 1567 - HDA_CODEC_VOLUME("Dock Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), 1568 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 1569 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 1570 - { } /* end */ 1571 - }; 1572 - 1573 - static const struct snd_kcontrol_new ad1884a_mobile_mixers[] = { 1574 - HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 1575 - /*HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 1576 - { 1577 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1578 - .name = "Master Playback Switch", 1579 - .subdevice = HDA_SUBDEV_AMP_FLAG, 1580 - .info = snd_hda_mixer_amp_switch_info, 1581 - .get = snd_hda_mixer_amp_switch_get, 1582 - .put = ad1884a_mobile_master_sw_put, 1583 - .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 1584 - }, 1585 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 1586 - HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 1587 - HDA_CODEC_VOLUME("Mic Capture Volume", 0x14, 0x0, HDA_INPUT), 1588 - HDA_CODEC_VOLUME("Internal Mic Capture Volume", 0x15, 0x0, HDA_INPUT), 1589 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 1590 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 1591 - { } /* end */ 1592 - }; 1593 - 1594 - /* mute internal speaker if HP is plugged */ 1595 - static void ad1884a_hp_automute(struct hda_codec *codec) 1596 - { 1597 - unsigned int present; 1598 - 1599 - present = snd_hda_jack_detect(codec, 0x11); 1600 - snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 1601 - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 1602 - snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE, 1603 - present ? 0x00 : 0x02); 1604 - } 1605 - 1606 - /* switch to external mic if plugged */ 1607 - static void ad1884a_hp_automic(struct hda_codec *codec) 1608 - { 1609 - unsigned int present; 1610 - 1611 - present = snd_hda_jack_detect(codec, 0x14); 1612 - snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, 1613 - present ? 0 : 1); 1614 - } 1615 - 1616 - #define AD1884A_HP_EVENT 0x37 1617 - #define AD1884A_MIC_EVENT 0x36 1618 - 1619 - /* unsolicited event for HP jack sensing */ 1620 - static void ad1884a_hp_unsol_event(struct hda_codec *codec, unsigned int res) 1621 - { 1622 - switch (res >> 26) { 1623 - case AD1884A_HP_EVENT: 1624 - ad1884a_hp_automute(codec); 1625 - break; 1626 - case AD1884A_MIC_EVENT: 1627 - ad1884a_hp_automic(codec); 1628 - break; 1629 - } 1630 - } 1631 - 1632 - /* initialize jack-sensing, too */ 1633 - static int ad1884a_hp_init(struct hda_codec *codec) 1634 - { 1635 - ad198x_init(codec); 1636 - ad1884a_hp_automute(codec); 1637 - ad1884a_hp_automic(codec); 1638 - return 0; 1639 - } 1640 - 1641 - /* mute internal speaker if HP or docking HP is plugged */ 1642 - static void ad1884a_laptop_automute(struct hda_codec *codec) 1643 - { 1644 - unsigned int present; 1645 - 1646 - present = snd_hda_jack_detect(codec, 0x11); 1647 - if (!present) 1648 - present = snd_hda_jack_detect(codec, 0x12); 1649 - snd_hda_codec_amp_stereo(codec, 0x16, HDA_OUTPUT, 0, 1650 - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 1651 - snd_hda_codec_write(codec, 0x16, 0, AC_VERB_SET_EAPD_BTLENABLE, 1652 - present ? 0x00 : 0x02); 1653 - } 1654 - 1655 - /* switch to external mic if plugged */ 1656 - static void ad1884a_laptop_automic(struct hda_codec *codec) 1657 - { 1658 - unsigned int idx; 1659 - 1660 - if (snd_hda_jack_detect(codec, 0x14)) 1661 - idx = 0; 1662 - else if (snd_hda_jack_detect(codec, 0x1c)) 1663 - idx = 4; 1664 - else 1665 - idx = 1; 1666 - snd_hda_codec_write(codec, 0x0c, 0, AC_VERB_SET_CONNECT_SEL, idx); 1667 - } 1668 - 1669 - /* unsolicited event for HP jack sensing */ 1670 - static void ad1884a_laptop_unsol_event(struct hda_codec *codec, 1671 - unsigned int res) 1672 - { 1673 - switch (res >> 26) { 1674 - case AD1884A_HP_EVENT: 1675 - ad1884a_laptop_automute(codec); 1676 - break; 1677 - case AD1884A_MIC_EVENT: 1678 - ad1884a_laptop_automic(codec); 1679 - break; 1680 - } 1681 - } 1682 - 1683 - /* initialize jack-sensing, too */ 1684 - static int ad1884a_laptop_init(struct hda_codec *codec) 1685 - { 1686 - ad198x_init(codec); 1687 - ad1884a_laptop_automute(codec); 1688 - ad1884a_laptop_automic(codec); 1689 - return 0; 1690 - } 1691 - 1692 - /* additional verbs for laptop model */ 1693 - static const struct hda_verb ad1884a_laptop_verbs[] = { 1694 - /* Port-A (HP) pin - always unmuted */ 1695 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1696 - /* Port-F (int speaker) mixer - route only from analog mixer */ 1697 - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1698 - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1699 - /* Port-F (int speaker) pin */ 1700 - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1701 - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1702 - /* required for compaq 6530s/6531s speaker output */ 1703 - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1704 - /* Port-C pin - internal mic-in */ 1705 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1706 - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 1707 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 1708 - /* Port-D (docking line-out) pin - default unmuted */ 1709 - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1710 - /* analog mix */ 1711 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1712 - /* unsolicited event for pin-sense */ 1713 - {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 1714 - {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 1715 - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 1716 - {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 1717 - /* allow to touch GPIO1 (for mute control) */ 1718 - {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 1719 - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 1720 - {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */ 1721 - { } /* end */ 1722 - }; 1723 - 1724 - static const struct hda_verb ad1884a_mobile_verbs[] = { 1725 - /* DACs; unmute as default */ 1726 - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 1727 - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 1728 - /* Port-A (HP) mixer - route only from analog mixer */ 1729 - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1730 - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1731 - /* Port-A pin */ 1732 - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1733 - /* Port-A (HP) pin - always unmuted */ 1734 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1735 - /* Port-B (mic jack) pin */ 1736 - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1737 - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 1738 - /* Port-C (int mic) pin */ 1739 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1740 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 1741 - /* Port-F (int speaker) mixer - route only from analog mixer */ 1742 - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1743 - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1744 - /* Port-F pin */ 1745 - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1746 - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1747 - /* Analog mixer; mute as default */ 1748 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1749 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1750 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1751 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1752 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1753 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 1754 - /* Analog Mix output amp */ 1755 - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1756 - /* capture sources */ 1757 - /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */ 1758 - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1759 - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 1760 - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1761 - /* unsolicited event for pin-sense */ 1762 - {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 1763 - {0x14, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 1764 - /* allow to touch GPIO1 (for mute control) */ 1765 - {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 1766 - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 1767 - {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */ 1768 - { } /* end */ 1769 - }; 1770 - 1771 - /* 1772 - * Thinkpad X300 1773 - * 0x11 - HP 1774 - * 0x12 - speaker 1775 - * 0x14 - mic-in 1776 - * 0x17 - built-in mic 1777 - */ 1778 - 1779 - static const struct hda_verb ad1984a_thinkpad_verbs[] = { 1780 - /* HP unmute */ 1781 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1782 - /* analog mix */ 1783 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1784 - /* turn on EAPD */ 1785 - {0x12, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 1786 - /* unsolicited event for pin-sense */ 1787 - {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 1788 - /* internal mic - dmic */ 1789 - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1790 - /* set magic COEFs for dmic */ 1791 - {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7}, 1792 - {0x01, AC_VERB_SET_PROC_COEF, 0x08}, 1793 - { } /* end */ 1794 - }; 1795 - 1796 - static const struct snd_kcontrol_new ad1984a_thinkpad_mixers[] = { 1797 - HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 1798 - HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 1799 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 1800 - HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 1801 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 1802 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 1803 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x14, 0x0, HDA_INPUT), 1804 - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT), 1805 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 1806 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 1807 - { 1808 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1809 - .name = "Capture Source", 1810 - .info = ad198x_mux_enum_info, 1811 - .get = ad198x_mux_enum_get, 1812 - .put = ad198x_mux_enum_put, 1813 - }, 1814 - { } /* end */ 1815 - }; 1816 - 1817 - static const struct hda_input_mux ad1984a_thinkpad_capture_source = { 1818 - .num_items = 3, 1819 - .items = { 1820 - { "Mic", 0x0 }, 1821 - { "Internal Mic", 0x5 }, 1822 - { "Mix", 0x3 }, 1823 - }, 1824 - }; 1825 - 1826 - /* mute internal speaker if HP is plugged */ 1827 - static void ad1984a_thinkpad_automute(struct hda_codec *codec) 1828 - { 1829 - unsigned int present; 1830 - 1831 - present = snd_hda_jack_detect(codec, 0x11); 1832 - snd_hda_codec_amp_stereo(codec, 0x12, HDA_OUTPUT, 0, 1833 - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 1834 - } 1835 - 1836 - /* unsolicited event for HP jack sensing */ 1837 - static void ad1984a_thinkpad_unsol_event(struct hda_codec *codec, 1838 - unsigned int res) 1839 - { 1840 - if ((res >> 26) != AD1884A_HP_EVENT) 1841 - return; 1842 - ad1984a_thinkpad_automute(codec); 1843 - } 1844 - 1845 - /* initialize jack-sensing, too */ 1846 - static int ad1984a_thinkpad_init(struct hda_codec *codec) 1847 - { 1848 - ad198x_init(codec); 1849 - ad1984a_thinkpad_automute(codec); 1850 - return 0; 1851 - } 1852 - 1853 - /* 1854 - * Precision R5500 1855 - * 0x12 - HP/line-out 1856 - * 0x13 - speaker (mono) 1857 - * 0x15 - mic-in 1858 - */ 1859 - 1860 - static const struct hda_verb ad1984a_precision_verbs[] = { 1861 - /* Unmute main output path */ 1862 - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 1863 - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x1f}, /* 0dB */ 1864 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(5) + 0x17}, /* 0dB */ 1865 - /* Analog mixer; mute as default */ 1866 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1867 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1868 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1869 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1870 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1871 - /* Select mic as input */ 1872 - {0x0c, AC_VERB_SET_CONNECT_SEL, 0x1}, 1873 - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE + 0x27}, /* 0dB */ 1874 - /* Configure as mic */ 1875 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1876 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, 0x7002}, /* raise mic as default */ 1877 - /* HP unmute */ 1878 - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1879 - /* turn on EAPD */ 1880 - {0x13, AC_VERB_SET_EAPD_BTLENABLE, 0x02}, 1881 - /* unsolicited event for pin-sense */ 1882 - {0x12, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 1883 - { } /* end */ 1884 - }; 1885 - 1886 - static const struct snd_kcontrol_new ad1984a_precision_mixers[] = { 1887 - HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 1888 - HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT), 1889 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 1890 - HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 1891 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 1892 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 1893 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x15, 0x0, HDA_INPUT), 1894 - HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1895 - HDA_CODEC_VOLUME("Speaker Playback Volume", 0x13, 0x0, HDA_OUTPUT), 1896 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 1897 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 1898 - { } /* end */ 1899 - }; 1900 - 1901 - 1902 - /* mute internal speaker if HP is plugged */ 1903 - static void ad1984a_precision_automute(struct hda_codec *codec) 1904 - { 1905 - unsigned int present; 1906 - 1907 - present = snd_hda_jack_detect(codec, 0x12); 1908 - snd_hda_codec_amp_stereo(codec, 0x13, HDA_OUTPUT, 0, 1909 - HDA_AMP_MUTE, present ? HDA_AMP_MUTE : 0); 1910 - } 1911 - 1912 - 1913 - /* unsolicited event for HP jack sensing */ 1914 - static void ad1984a_precision_unsol_event(struct hda_codec *codec, 1915 - unsigned int res) 1916 - { 1917 - if ((res >> 26) != AD1884A_HP_EVENT) 1918 - return; 1919 - ad1984a_precision_automute(codec); 1920 - } 1921 - 1922 - /* initialize jack-sensing, too */ 1923 - static int ad1984a_precision_init(struct hda_codec *codec) 1924 - { 1925 - ad198x_init(codec); 1926 - ad1984a_precision_automute(codec); 1927 - return 0; 1928 - } 1929 - 1930 - 1931 - /* 1932 - * HP Touchsmart 1933 - * port-A (0x11) - front hp-out 1934 - * port-B (0x14) - unused 1935 - * port-C (0x15) - unused 1936 - * port-D (0x12) - rear line out 1937 - * port-E (0x1c) - front mic-in 1938 - * port-F (0x16) - Internal speakers 1939 - * digital-mic (0x17) - Internal mic 1940 - */ 1941 - 1942 - static const struct hda_verb ad1984a_touchsmart_verbs[] = { 1943 - /* DACs; unmute as default */ 1944 - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 1945 - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, 0x27}, /* 0dB */ 1946 - /* Port-A (HP) mixer - route only from analog mixer */ 1947 - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1948 - {0x07, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1949 - /* Port-A pin */ 1950 - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1951 - /* Port-A (HP) pin - always unmuted */ 1952 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1953 - /* Port-E (int speaker) mixer - route only from analog mixer */ 1954 - {0x25, AC_VERB_SET_AMP_GAIN_MUTE, 0x03}, 1955 - /* Port-E pin */ 1956 - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1957 - {0x1c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE}, 1958 - {0x1c, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1959 - /* Port-F (int speaker) mixer - route only from analog mixer */ 1960 - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1961 - {0x0b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1962 - /* Port-F pin */ 1963 - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1964 - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1965 - /* Analog mixer; mute as default */ 1966 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1967 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1968 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1969 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1970 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1971 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 1972 - /* Analog Mix output amp */ 1973 - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1974 - /* capture sources */ 1975 - /* {0x0c, AC_VERB_SET_CONNECT_SEL, 0x0}, */ /* set via unsol */ 1976 - {0x0c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1977 - {0x0d, AC_VERB_SET_CONNECT_SEL, 0x0}, 1978 - {0x0d, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1979 - /* unsolicited event for pin-sense */ 1980 - {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_HP_EVENT}, 1981 - {0x1c, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1884A_MIC_EVENT}, 1982 - /* allow to touch GPIO1 (for mute control) */ 1983 - {0x01, AC_VERB_SET_GPIO_MASK, 0x02}, 1984 - {0x01, AC_VERB_SET_GPIO_DIRECTION, 0x02}, 1985 - {0x01, AC_VERB_SET_GPIO_DATA, 0x02}, /* first muted */ 1986 - /* internal mic - dmic */ 1987 - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1988 - /* set magic COEFs for dmic */ 1989 - {0x01, AC_VERB_SET_COEF_INDEX, 0x13f7}, 1990 - {0x01, AC_VERB_SET_PROC_COEF, 0x08}, 1991 - { } /* end */ 1992 - }; 1993 - 1994 - static const struct snd_kcontrol_new ad1984a_touchsmart_mixers[] = { 1995 - HDA_CODEC_VOLUME("Master Playback Volume", 0x21, 0x0, HDA_OUTPUT), 1996 - /* HDA_CODEC_MUTE("Master Playback Switch", 0x21, 0x0, HDA_OUTPUT),*/ 1997 - { 1998 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1999 - .subdevice = HDA_SUBDEV_AMP_FLAG, 2000 - .name = "Master Playback Switch", 2001 - .info = snd_hda_mixer_amp_switch_info, 2002 - .get = snd_hda_mixer_amp_switch_get, 2003 - .put = ad1884a_mobile_master_sw_put, 2004 - .private_value = HDA_COMPOSE_AMP_VAL(0x21, 3, 0, HDA_OUTPUT), 2005 - }, 2006 - HDA_CODEC_VOLUME("PCM Playback Volume", 0x20, 0x5, HDA_INPUT), 2007 - HDA_CODEC_MUTE("PCM Playback Switch", 0x20, 0x5, HDA_INPUT), 2008 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 2009 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 2010 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x25, 0x0, HDA_OUTPUT), 2011 - HDA_CODEC_VOLUME("Internal Mic Boost Volume", 0x17, 0x0, HDA_INPUT), 2012 - { } /* end */ 2013 - }; 2014 - 2015 - /* switch to external mic if plugged */ 2016 - static void ad1984a_touchsmart_automic(struct hda_codec *codec) 2017 - { 2018 - if (snd_hda_jack_detect(codec, 0x1c)) 2019 - snd_hda_codec_write(codec, 0x0c, 0, 2020 - AC_VERB_SET_CONNECT_SEL, 0x4); 2021 - else 2022 - snd_hda_codec_write(codec, 0x0c, 0, 2023 - AC_VERB_SET_CONNECT_SEL, 0x5); 2024 - } 2025 - 2026 - 2027 - /* unsolicited event for HP jack sensing */ 2028 - static void ad1984a_touchsmart_unsol_event(struct hda_codec *codec, 2029 - unsigned int res) 2030 - { 2031 - switch (res >> 26) { 2032 - case AD1884A_HP_EVENT: 2033 - ad1884a_hp_automute(codec); 2034 - break; 2035 - case AD1884A_MIC_EVENT: 2036 - ad1984a_touchsmart_automic(codec); 2037 - break; 2038 - } 2039 - } 2040 - 2041 - /* initialize jack-sensing, too */ 2042 - static int ad1984a_touchsmart_init(struct hda_codec *codec) 2043 - { 2044 - ad198x_init(codec); 2045 - ad1884a_hp_automute(codec); 2046 - ad1984a_touchsmart_automic(codec); 2047 - return 0; 2048 - } 2049 - 2050 - 2051 - /* 2052 - */ 2053 - 2054 - enum { 2055 - AD1884A_AUTO, 2056 - AD1884A_DESKTOP, 2057 - AD1884A_LAPTOP, 2058 - AD1884A_MOBILE, 2059 - AD1884A_THINKPAD, 2060 - AD1984A_TOUCHSMART, 2061 - AD1984A_PRECISION, 2062 - AD1884A_MODELS 2063 - }; 2064 - 2065 - static const char * const ad1884a_models[AD1884A_MODELS] = { 2066 - [AD1884A_AUTO] = "auto", 2067 - [AD1884A_DESKTOP] = "desktop", 2068 - [AD1884A_LAPTOP] = "laptop", 2069 - [AD1884A_MOBILE] = "mobile", 2070 - [AD1884A_THINKPAD] = "thinkpad", 2071 - [AD1984A_TOUCHSMART] = "touchsmart", 2072 - [AD1984A_PRECISION] = "precision", 2073 - }; 2074 - 2075 - static const struct snd_pci_quirk ad1884a_cfg_tbl[] = { 2076 - SND_PCI_QUIRK(0x1028, 0x04ac, "Precision R5500", AD1984A_PRECISION), 2077 - SND_PCI_QUIRK(0x103c, 0x3030, "HP", AD1884A_MOBILE), 2078 - SND_PCI_QUIRK(0x103c, 0x3037, "HP 2230s", AD1884A_LAPTOP), 2079 - SND_PCI_QUIRK(0x103c, 0x3056, "HP", AD1884A_MOBILE), 2080 - SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x3070, "HP", AD1884A_MOBILE), 2081 - SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30d0, "HP laptop", AD1884A_LAPTOP), 2082 - SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x30e0, "HP laptop", AD1884A_LAPTOP), 2083 - SND_PCI_QUIRK_MASK(0x103c, 0xff00, 0x3600, "HP laptop", AD1884A_LAPTOP), 2084 - SND_PCI_QUIRK_MASK(0x103c, 0xfff0, 0x7010, "HP laptop", AD1884A_MOBILE), 2085 - SND_PCI_QUIRK(0x17aa, 0x20ac, "Thinkpad X300", AD1884A_THINKPAD), 2086 - SND_PCI_QUIRK(0x103c, 0x2a82, "Touchsmart", AD1984A_TOUCHSMART), 2087 - {} 2088 - }; 2089 - 2090 - static int patch_ad1884a(struct hda_codec *codec) 2091 - { 2092 - struct ad198x_spec *spec; 2093 - int err, board_config; 2094 - 2095 - board_config = snd_hda_check_board_config(codec, AD1884A_MODELS, 2096 - ad1884a_models, 2097 - ad1884a_cfg_tbl); 2098 - if (board_config < 0) { 2099 - printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 2100 - codec->chip_name); 2101 - board_config = AD1884A_AUTO; 2102 - } 2103 - 2104 - if (board_config == AD1884A_AUTO) 2105 - return ad1884_parse_auto_config(codec); 2106 - 2107 - err = alloc_ad_spec(codec); 2108 - if (err < 0) 2109 - return err; 2110 - spec = codec->spec; 2111 - 2112 - err = snd_hda_attach_beep_device(codec, 0x10); 2113 - if (err < 0) { 2114 - ad198x_free(codec); 2115 - return err; 2116 - } 2117 - set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 2118 - 2119 - spec->multiout.max_channels = 2; 2120 - spec->multiout.num_dacs = ARRAY_SIZE(ad1884a_dac_nids); 2121 - spec->multiout.dac_nids = ad1884a_dac_nids; 2122 - spec->multiout.dig_out_nid = AD1884A_SPDIF_OUT; 2123 - spec->num_adc_nids = ARRAY_SIZE(ad1884a_adc_nids); 2124 - spec->adc_nids = ad1884a_adc_nids; 2125 - spec->capsrc_nids = ad1884a_capsrc_nids; 2126 - spec->input_mux = &ad1884a_capture_source; 2127 - spec->num_mixers = 1; 2128 - spec->mixers[0] = ad1884a_base_mixers; 2129 - spec->num_init_verbs = 1; 2130 - spec->init_verbs[0] = ad1884a_init_verbs; 2131 - spec->spdif_route = 0; 2132 - #ifdef CONFIG_PM 2133 - spec->loopback.amplist = ad1884a_loopbacks; 2134 - #endif 2135 - codec->patch_ops = ad198x_patch_ops; 2136 - 2137 - /* override some parameters */ 2138 - switch (board_config) { 2139 - case AD1884A_LAPTOP: 2140 - spec->mixers[0] = ad1884a_laptop_mixers; 2141 - spec->init_verbs[spec->num_init_verbs++] = ad1884a_laptop_verbs; 2142 - spec->multiout.dig_out_nid = 0; 2143 - codec->patch_ops.unsol_event = ad1884a_laptop_unsol_event; 2144 - codec->patch_ops.init = ad1884a_laptop_init; 2145 - /* set the upper-limit for mixer amp to 0dB for avoiding the 2146 - * possible damage by overloading 2147 - */ 2148 - snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, 2149 - (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 2150 - (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 2151 - (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 2152 - (1 << AC_AMPCAP_MUTE_SHIFT)); 2153 - break; 2154 - case AD1884A_MOBILE: 2155 - spec->mixers[0] = ad1884a_mobile_mixers; 2156 - spec->init_verbs[0] = ad1884a_mobile_verbs; 2157 - spec->multiout.dig_out_nid = 0; 2158 - codec->patch_ops.unsol_event = ad1884a_hp_unsol_event; 2159 - codec->patch_ops.init = ad1884a_hp_init; 2160 - /* set the upper-limit for mixer amp to 0dB for avoiding the 2161 - * possible damage by overloading 2162 - */ 2163 - snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, 2164 - (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 2165 - (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 2166 - (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 2167 - (1 << AC_AMPCAP_MUTE_SHIFT)); 2168 - break; 2169 - case AD1884A_THINKPAD: 2170 - spec->mixers[0] = ad1984a_thinkpad_mixers; 2171 - spec->init_verbs[spec->num_init_verbs++] = 2172 - ad1984a_thinkpad_verbs; 2173 - spec->multiout.dig_out_nid = 0; 2174 - spec->input_mux = &ad1984a_thinkpad_capture_source; 2175 - codec->patch_ops.unsol_event = ad1984a_thinkpad_unsol_event; 2176 - codec->patch_ops.init = ad1984a_thinkpad_init; 2177 - break; 2178 - case AD1984A_PRECISION: 2179 - spec->mixers[0] = ad1984a_precision_mixers; 2180 - spec->init_verbs[spec->num_init_verbs++] = 2181 - ad1984a_precision_verbs; 2182 - spec->multiout.dig_out_nid = 0; 2183 - codec->patch_ops.unsol_event = ad1984a_precision_unsol_event; 2184 - codec->patch_ops.init = ad1984a_precision_init; 2185 - break; 2186 - case AD1984A_TOUCHSMART: 2187 - spec->mixers[0] = ad1984a_touchsmart_mixers; 2188 - spec->init_verbs[0] = ad1984a_touchsmart_verbs; 2189 - spec->multiout.dig_out_nid = 0; 2190 - codec->patch_ops.unsol_event = ad1984a_touchsmart_unsol_event; 2191 - codec->patch_ops.init = ad1984a_touchsmart_init; 2192 - /* set the upper-limit for mixer amp to 0dB for avoiding the 2193 - * possible damage by overloading 2194 - */ 2195 - snd_hda_override_amp_caps(codec, 0x20, HDA_INPUT, 2196 - (0x17 << AC_AMPCAP_OFFSET_SHIFT) | 2197 - (0x17 << AC_AMPCAP_NUM_STEPS_SHIFT) | 2198 - (0x05 << AC_AMPCAP_STEP_SIZE_SHIFT) | 2199 - (1 << AC_AMPCAP_MUTE_SHIFT)); 2200 - break; 2201 - } 2202 - 2203 - codec->no_trigger_sense = 1; 2204 - codec->no_sticky_stream = 1; 2205 - 2206 - return 0; 2207 - } 2208 - #else /* ENABLE_AD_STATIC_QUIRKS */ 2209 - #define patch_ad1884a ad1884_parse_auto_config 2210 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 2211 - 2212 - 2213 3677 /* 2214 3678 * AD1882 / AD1882A 2215 3679 * ··· 1058 4850 * port-G - rear clfe-out (6stack) 1059 4851 */ 1060 4852 1061 - #ifdef ENABLE_AD_STATIC_QUIRKS 1062 - static const hda_nid_t ad1882_dac_nids[3] = { 1063 - 0x04, 0x03, 0x05 1064 - }; 1065 - 1066 - static const hda_nid_t ad1882_adc_nids[2] = { 1067 - 0x08, 0x09, 1068 - }; 1069 - 1070 - static const hda_nid_t ad1882_capsrc_nids[2] = { 1071 - 0x0c, 0x0d, 1072 - }; 1073 - 1074 - #define AD1882_SPDIF_OUT 0x02 1075 - 1076 - /* list: 0x11, 0x39, 0x3a, 0x18, 0x3c, 0x3b, 0x12, 0x20 */ 1077 - static const struct hda_input_mux ad1882_capture_source = { 1078 - .num_items = 5, 1079 - .items = { 1080 - { "Front Mic", 0x1 }, 1081 - { "Mic", 0x4 }, 1082 - { "Line", 0x2 }, 1083 - { "CD", 0x3 }, 1084 - { "Mix", 0x7 }, 1085 - }, 1086 - }; 1087 - 1088 - /* list: 0x11, 0x39, 0x3a, 0x3c, 0x18, 0x1f, 0x12, 0x20 */ 1089 - static const struct hda_input_mux ad1882a_capture_source = { 1090 - .num_items = 5, 1091 - .items = { 1092 - { "Front Mic", 0x1 }, 1093 - { "Mic", 0x4}, 1094 - { "Line", 0x2 }, 1095 - { "Digital Mic", 0x06 }, 1096 - { "Mix", 0x7 }, 1097 - }, 1098 - }; 1099 - 1100 - static const struct snd_kcontrol_new ad1882_base_mixers[] = { 1101 - HDA_CODEC_VOLUME("Front Playback Volume", 0x04, 0x0, HDA_OUTPUT), 1102 - HDA_CODEC_VOLUME("Surround Playback Volume", 0x03, 0x0, HDA_OUTPUT), 1103 - HDA_CODEC_VOLUME_MONO("Center Playback Volume", 0x05, 1, 0x0, HDA_OUTPUT), 1104 - HDA_CODEC_VOLUME_MONO("LFE Playback Volume", 0x05, 2, 0x0, HDA_OUTPUT), 1105 - HDA_CODEC_MUTE("Headphone Playback Switch", 0x11, 0x0, HDA_OUTPUT), 1106 - HDA_CODEC_MUTE("Front Playback Switch", 0x12, 0x0, HDA_OUTPUT), 1107 - HDA_CODEC_VOLUME_MONO("Mono Playback Volume", 0x13, 1, 0x0, HDA_OUTPUT), 1108 - HDA_CODEC_MUTE_MONO("Mono Playback Switch", 0x13, 1, 0x0, HDA_OUTPUT), 1109 - 1110 - HDA_CODEC_VOLUME("Mic Boost Volume", 0x3c, 0x0, HDA_OUTPUT), 1111 - HDA_CODEC_VOLUME("Front Mic Boost Volume", 0x39, 0x0, HDA_OUTPUT), 1112 - HDA_CODEC_VOLUME("Line-In Boost Volume", 0x3a, 0x0, HDA_OUTPUT), 1113 - HDA_CODEC_VOLUME("Capture Volume", 0x0c, 0x0, HDA_OUTPUT), 1114 - HDA_CODEC_MUTE("Capture Switch", 0x0c, 0x0, HDA_OUTPUT), 1115 - HDA_CODEC_VOLUME_IDX("Capture Volume", 1, 0x0d, 0x0, HDA_OUTPUT), 1116 - HDA_CODEC_MUTE_IDX("Capture Switch", 1, 0x0d, 0x0, HDA_OUTPUT), 1117 - { 1118 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1119 - /* The multiple "Capture Source" controls confuse alsamixer 1120 - * So call somewhat different.. 1121 - */ 1122 - /* .name = "Capture Source", */ 1123 - .name = "Input Source", 1124 - .count = 2, 1125 - .info = ad198x_mux_enum_info, 1126 - .get = ad198x_mux_enum_get, 1127 - .put = ad198x_mux_enum_put, 1128 - }, 1129 - /* SPDIF controls */ 1130 - HDA_CODEC_VOLUME("IEC958 Playback Volume", 0x1b, 0x0, HDA_OUTPUT), 1131 - { 1132 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1133 - .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,NONE) "Source", 1134 - /* identical with ad1983 */ 1135 - .info = ad1983_spdif_route_info, 1136 - .get = ad1983_spdif_route_get, 1137 - .put = ad1983_spdif_route_put, 1138 - }, 1139 - { } /* end */ 1140 - }; 1141 - 1142 - static const struct snd_kcontrol_new ad1882_loopback_mixers[] = { 1143 - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 1144 - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 1145 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x01, HDA_INPUT), 1146 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x01, HDA_INPUT), 1147 - HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x04, HDA_INPUT), 1148 - HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x04, HDA_INPUT), 1149 - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), 1150 - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), 1151 - { } /* end */ 1152 - }; 1153 - 1154 - static const struct snd_kcontrol_new ad1882a_loopback_mixers[] = { 1155 - HDA_CODEC_VOLUME("Front Mic Playback Volume", 0x20, 0x00, HDA_INPUT), 1156 - HDA_CODEC_MUTE("Front Mic Playback Switch", 0x20, 0x00, HDA_INPUT), 1157 - HDA_CODEC_VOLUME("Mic Playback Volume", 0x20, 0x04, HDA_INPUT), 1158 - HDA_CODEC_MUTE("Mic Playback Switch", 0x20, 0x04, HDA_INPUT), 1159 - HDA_CODEC_VOLUME("Line Playback Volume", 0x20, 0x01, HDA_INPUT), 1160 - HDA_CODEC_MUTE("Line Playback Switch", 0x20, 0x01, HDA_INPUT), 1161 - HDA_CODEC_VOLUME("CD Playback Volume", 0x20, 0x06, HDA_INPUT), 1162 - HDA_CODEC_MUTE("CD Playback Switch", 0x20, 0x06, HDA_INPUT), 1163 - HDA_CODEC_VOLUME("Digital Mic Boost Volume", 0x1f, 0x0, HDA_INPUT), 1164 - { } /* end */ 1165 - }; 1166 - 1167 - static const struct snd_kcontrol_new ad1882_3stack_mixers[] = { 1168 - HDA_CODEC_MUTE("Surround Playback Switch", 0x15, 0x0, HDA_OUTPUT), 1169 - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x17, 1, 0x0, HDA_OUTPUT), 1170 - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x17, 2, 0x0, HDA_OUTPUT), 1171 - { 1172 - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 1173 - .name = "Channel Mode", 1174 - .info = ad198x_ch_mode_info, 1175 - .get = ad198x_ch_mode_get, 1176 - .put = ad198x_ch_mode_put, 1177 - }, 1178 - { } /* end */ 1179 - }; 1180 - 1181 - /* simple auto-mute control for AD1882 3-stack board */ 1182 - #define AD1882_HP_EVENT 0x01 1183 - 1184 - static void ad1882_3stack_automute(struct hda_codec *codec) 1185 - { 1186 - bool mute = snd_hda_jack_detect(codec, 0x11); 1187 - snd_hda_codec_write(codec, 0x12, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 1188 - mute ? 0 : PIN_OUT); 1189 - } 1190 - 1191 - static int ad1882_3stack_automute_init(struct hda_codec *codec) 1192 - { 1193 - ad198x_init(codec); 1194 - ad1882_3stack_automute(codec); 1195 - return 0; 1196 - } 1197 - 1198 - static void ad1882_3stack_unsol_event(struct hda_codec *codec, unsigned int res) 1199 - { 1200 - switch (res >> 26) { 1201 - case AD1882_HP_EVENT: 1202 - ad1882_3stack_automute(codec); 1203 - break; 1204 - } 1205 - } 1206 - 1207 - static const struct snd_kcontrol_new ad1882_6stack_mixers[] = { 1208 - HDA_CODEC_MUTE("Surround Playback Switch", 0x16, 0x0, HDA_OUTPUT), 1209 - HDA_CODEC_MUTE_MONO("Center Playback Switch", 0x24, 1, 0x0, HDA_OUTPUT), 1210 - HDA_CODEC_MUTE_MONO("LFE Playback Switch", 0x24, 2, 0x0, HDA_OUTPUT), 1211 - { } /* end */ 1212 - }; 1213 - 1214 - static const struct hda_verb ad1882_ch2_init[] = { 1215 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1216 - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1217 - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1218 - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1219 - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1220 - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1221 - { } /* end */ 1222 - }; 1223 - 1224 - static const struct hda_verb ad1882_ch4_init[] = { 1225 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1226 - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1227 - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1228 - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1229 - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1230 - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1231 - { } /* end */ 1232 - }; 1233 - 1234 - static const struct hda_verb ad1882_ch6_init[] = { 1235 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1236 - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1237 - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1238 - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1239 - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1240 - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1241 - { } /* end */ 1242 - }; 1243 - 1244 - static const struct hda_channel_mode ad1882_modes[3] = { 1245 - { 2, ad1882_ch2_init }, 1246 - { 4, ad1882_ch4_init }, 1247 - { 6, ad1882_ch6_init }, 1248 - }; 1249 - 1250 - /* 1251 - * initialization verbs 1252 - */ 1253 - static const struct hda_verb ad1882_init_verbs[] = { 1254 - /* DACs; mute as default */ 1255 - {0x03, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1256 - {0x04, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1257 - {0x05, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, 1258 - /* Port-A (HP) mixer */ 1259 - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1260 - {0x22, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1261 - /* Port-A pin */ 1262 - {0x11, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1263 - {0x11, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1264 - /* HP selector - select DAC2 */ 1265 - {0x37, AC_VERB_SET_CONNECT_SEL, 0x1}, 1266 - /* Port-D (Line-out) mixer */ 1267 - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1268 - {0x29, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1269 - /* Port-D pin */ 1270 - {0x12, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1271 - {0x12, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1272 - /* Mono-out mixer */ 1273 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(0)}, 1274 - {0x1e, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_UNMUTE(1)}, 1275 - /* Mono-out pin */ 1276 - {0x13, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_HP}, 1277 - {0x13, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1278 - /* Port-B (front mic) pin */ 1279 - {0x14, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1280 - {0x14, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1281 - {0x39, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ 1282 - /* Port-C (line-in) pin */ 1283 - {0x15, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_IN}, 1284 - {0x15, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1285 - {0x3a, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ 1286 - /* Port-C mixer - mute as input */ 1287 - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1288 - {0x2c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1289 - /* Port-E (mic-in) pin */ 1290 - {0x17, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_VREF80}, 1291 - {0x17, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1292 - {0x3c, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_ZERO}, /* boost */ 1293 - /* Port-E mixer - mute as input */ 1294 - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1295 - {0x26, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1296 - /* Port-F (surround) */ 1297 - {0x16, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1298 - {0x16, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1299 - /* Port-G (CLFE) */ 1300 - {0x24, AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT}, 1301 - {0x24, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE}, 1302 - /* Analog mixer; mute as default */ 1303 - /* list: 0x39, 0x3a, 0x11, 0x12, 0x3c, 0x3b, 0x18, 0x1a */ 1304 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(0)}, 1305 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(1)}, 1306 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(2)}, 1307 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(3)}, 1308 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(4)}, 1309 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(5)}, 1310 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(6)}, 1311 - {0x20, AC_VERB_SET_AMP_GAIN_MUTE, AMP_IN_MUTE(7)}, 1312 - /* Analog Mix output amp */ 1313 - {0x21, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x1f}, /* 0dB */ 1314 - /* SPDIF output selector */ 1315 - {0x02, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 1316 - {0x02, AC_VERB_SET_CONNECT_SEL, 0x0}, /* PCM */ 1317 - {0x1b, AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_UNMUTE | 0x27}, /* 0dB */ 1318 - { } /* end */ 1319 - }; 1320 - 1321 - static const struct hda_verb ad1882_3stack_automute_verbs[] = { 1322 - {0x11, AC_VERB_SET_UNSOLICITED_ENABLE, AC_USRSP_EN | AD1882_HP_EVENT}, 1323 - { } /* end */ 1324 - }; 1325 - 1326 - #ifdef CONFIG_PM 1327 - static const struct hda_amp_list ad1882_loopbacks[] = { 1328 - { 0x20, HDA_INPUT, 0 }, /* Front Mic */ 1329 - { 0x20, HDA_INPUT, 1 }, /* Mic */ 1330 - { 0x20, HDA_INPUT, 4 }, /* Line */ 1331 - { 0x20, HDA_INPUT, 6 }, /* CD */ 1332 - { } /* end */ 1333 - }; 1334 - #endif 1335 - 1336 - /* models */ 1337 - enum { 1338 - AD1882_AUTO, 1339 - AD1882_3STACK, 1340 - AD1882_6STACK, 1341 - AD1882_3STACK_AUTOMUTE, 1342 - AD1882_MODELS 1343 - }; 1344 - 1345 - static const char * const ad1882_models[AD1986A_MODELS] = { 1346 - [AD1882_AUTO] = "auto", 1347 - [AD1882_3STACK] = "3stack", 1348 - [AD1882_6STACK] = "6stack", 1349 - [AD1882_3STACK_AUTOMUTE] = "3stack-automute", 1350 - }; 1351 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 1352 - 1353 - static int ad1882_parse_auto_config(struct hda_codec *codec) 4853 + static int patch_ad1882(struct hda_codec *codec) 1354 4854 { 1355 4855 struct ad198x_spec *spec; 1356 4856 int err; ··· 1085 5169 return err; 1086 5170 } 1087 5171 1088 - #ifdef ENABLE_AD_STATIC_QUIRKS 1089 - static int patch_ad1882(struct hda_codec *codec) 1090 - { 1091 - struct ad198x_spec *spec; 1092 - int err, board_config; 1093 - 1094 - board_config = snd_hda_check_board_config(codec, AD1882_MODELS, 1095 - ad1882_models, NULL); 1096 - if (board_config < 0) { 1097 - printk(KERN_INFO "hda_codec: %s: BIOS auto-probing.\n", 1098 - codec->chip_name); 1099 - board_config = AD1882_AUTO; 1100 - } 1101 - 1102 - if (board_config == AD1882_AUTO) 1103 - return ad1882_parse_auto_config(codec); 1104 - 1105 - err = alloc_ad_spec(codec); 1106 - if (err < 0) 1107 - return err; 1108 - spec = codec->spec; 1109 - 1110 - err = snd_hda_attach_beep_device(codec, 0x10); 1111 - if (err < 0) { 1112 - ad198x_free(codec); 1113 - return err; 1114 - } 1115 - set_beep_amp(spec, 0x10, 0, HDA_OUTPUT); 1116 - 1117 - spec->multiout.max_channels = 6; 1118 - spec->multiout.num_dacs = 3; 1119 - spec->multiout.dac_nids = ad1882_dac_nids; 1120 - spec->multiout.dig_out_nid = AD1882_SPDIF_OUT; 1121 - spec->num_adc_nids = ARRAY_SIZE(ad1882_adc_nids); 1122 - spec->adc_nids = ad1882_adc_nids; 1123 - spec->capsrc_nids = ad1882_capsrc_nids; 1124 - if (codec->vendor_id == 0x11d41882) 1125 - spec->input_mux = &ad1882_capture_source; 1126 - else 1127 - spec->input_mux = &ad1882a_capture_source; 1128 - spec->num_mixers = 2; 1129 - spec->mixers[0] = ad1882_base_mixers; 1130 - if (codec->vendor_id == 0x11d41882) 1131 - spec->mixers[1] = ad1882_loopback_mixers; 1132 - else 1133 - spec->mixers[1] = ad1882a_loopback_mixers; 1134 - spec->num_init_verbs = 1; 1135 - spec->init_verbs[0] = ad1882_init_verbs; 1136 - spec->spdif_route = 0; 1137 - #ifdef CONFIG_PM 1138 - spec->loopback.amplist = ad1882_loopbacks; 1139 - #endif 1140 - spec->vmaster_nid = 0x04; 1141 - 1142 - codec->patch_ops = ad198x_patch_ops; 1143 - 1144 - /* override some parameters */ 1145 - switch (board_config) { 1146 - default: 1147 - case AD1882_3STACK: 1148 - case AD1882_3STACK_AUTOMUTE: 1149 - spec->num_mixers = 3; 1150 - spec->mixers[2] = ad1882_3stack_mixers; 1151 - spec->channel_mode = ad1882_modes; 1152 - spec->num_channel_mode = ARRAY_SIZE(ad1882_modes); 1153 - spec->need_dac_fix = 1; 1154 - spec->multiout.max_channels = 2; 1155 - spec->multiout.num_dacs = 1; 1156 - if (board_config != AD1882_3STACK) { 1157 - spec->init_verbs[spec->num_init_verbs++] = 1158 - ad1882_3stack_automute_verbs; 1159 - codec->patch_ops.unsol_event = ad1882_3stack_unsol_event; 1160 - codec->patch_ops.init = ad1882_3stack_automute_init; 1161 - } 1162 - break; 1163 - case AD1882_6STACK: 1164 - spec->num_mixers = 3; 1165 - spec->mixers[2] = ad1882_6stack_mixers; 1166 - break; 1167 - } 1168 - 1169 - codec->no_trigger_sense = 1; 1170 - codec->no_sticky_stream = 1; 1171 - 1172 - return 0; 1173 - } 1174 - #else /* ENABLE_AD_STATIC_QUIRKS */ 1175 - #define patch_ad1882 ad1882_parse_auto_config 1176 - #endif /* ENABLE_AD_STATIC_QUIRKS */ 1177 - 1178 5172 1179 5173 /* 1180 5174 * patch entries 1181 5175 */ 1182 5176 static const struct hda_codec_preset snd_hda_preset_analog[] = { 1183 - { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884a }, 5177 + { .id = 0x11d4184a, .name = "AD1884A", .patch = patch_ad1884 }, 1184 5178 { .id = 0x11d41882, .name = "AD1882", .patch = patch_ad1882 }, 1185 - { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884a }, 5179 + { .id = 0x11d41883, .name = "AD1883", .patch = patch_ad1884 }, 1186 5180 { .id = 0x11d41884, .name = "AD1884", .patch = patch_ad1884 }, 1187 - { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884a }, 1188 - { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884a }, 5181 + { .id = 0x11d4194a, .name = "AD1984A", .patch = patch_ad1884 }, 5182 + { .id = 0x11d4194b, .name = "AD1984B", .patch = patch_ad1884 }, 1189 5183 { .id = 0x11d41981, .name = "AD1981", .patch = patch_ad1981 }, 1190 5184 { .id = 0x11d41983, .name = "AD1983", .patch = patch_ad1983 }, 1191 - { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1984 }, 5185 + { .id = 0x11d41984, .name = "AD1984", .patch = patch_ad1884 }, 1192 5186 { .id = 0x11d41986, .name = "AD1986A", .patch = patch_ad1986a }, 1193 5187 { .id = 0x11d41988, .name = "AD1988", .patch = patch_ad1988 }, 1194 5188 { .id = 0x11d4198b, .name = "AD1988B", .patch = patch_ad1988 },
+78 -1
sound/pci/hda/patch_conexant.c
··· 66 66 hda_nid_t eapds[4]; 67 67 bool dynamic_eapd; 68 68 69 + unsigned int parse_flags; /* flag for snd_hda_parse_pin_defcfg() */ 70 + 69 71 #ifdef ENABLE_CXT_STATIC_QUIRKS 70 72 const struct snd_kcontrol_new *mixers[5]; 71 73 int num_mixers; ··· 3202 3200 snd_hda_gen_init(codec); 3203 3201 if (!spec->dynamic_eapd) 3204 3202 cx_auto_turn_eapd(codec, spec->num_eapds, spec->eapds, true); 3203 + 3204 + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_INIT); 3205 + 3205 3206 return 0; 3206 3207 } 3207 3208 ··· 3229 3224 CXT_PINCFG_LEMOTE_A1205, 3230 3225 CXT_FIXUP_STEREO_DMIC, 3231 3226 CXT_FIXUP_INC_MIC_BOOST, 3227 + CXT_FIXUP_HEADPHONE_MIC_PIN, 3228 + CXT_FIXUP_HEADPHONE_MIC, 3232 3229 }; 3233 3230 3234 3231 static void cxt_fixup_stereo_dmic(struct hda_codec *codec, ··· 3252 3245 (0x27 << AC_AMPCAP_STEP_SIZE_SHIFT) | 3253 3246 (0 << AC_AMPCAP_MUTE_SHIFT)); 3254 3247 } 3248 + 3249 + static void cxt_update_headset_mode(struct hda_codec *codec) 3250 + { 3251 + /* The verbs used in this function were tested on a Conexant CX20751/2 codec. */ 3252 + int i; 3253 + bool mic_mode = false; 3254 + struct conexant_spec *spec = codec->spec; 3255 + struct auto_pin_cfg *cfg = &spec->gen.autocfg; 3256 + 3257 + hda_nid_t mux_pin = spec->gen.imux_pins[spec->gen.cur_mux[0]]; 3258 + 3259 + for (i = 0; i < cfg->num_inputs; i++) 3260 + if (cfg->inputs[i].pin == mux_pin) { 3261 + mic_mode = !!cfg->inputs[i].is_headphone_mic; 3262 + break; 3263 + } 3264 + 3265 + if (mic_mode) { 3266 + snd_hda_codec_write_cache(codec, 0x1c, 0, 0x410, 0x7c); /* enable merged mode for analog int-mic */ 3267 + spec->gen.hp_jack_present = false; 3268 + } else { 3269 + snd_hda_codec_write_cache(codec, 0x1c, 0, 0x410, 0x54); /* disable merged mode for analog int-mic */ 3270 + spec->gen.hp_jack_present = snd_hda_jack_detect(codec, spec->gen.autocfg.hp_pins[0]); 3271 + } 3272 + 3273 + snd_hda_gen_update_outputs(codec); 3274 + } 3275 + 3276 + static void cxt_update_headset_mode_hook(struct hda_codec *codec, 3277 + struct snd_ctl_elem_value *ucontrol) 3278 + { 3279 + cxt_update_headset_mode(codec); 3280 + } 3281 + 3282 + static void cxt_fixup_headphone_mic(struct hda_codec *codec, 3283 + const struct hda_fixup *fix, int action) 3284 + { 3285 + struct conexant_spec *spec = codec->spec; 3286 + 3287 + switch (action) { 3288 + case HDA_FIXUP_ACT_PRE_PROBE: 3289 + spec->parse_flags |= HDA_PINCFG_HEADPHONE_MIC; 3290 + break; 3291 + case HDA_FIXUP_ACT_PROBE: 3292 + spec->gen.cap_sync_hook = cxt_update_headset_mode_hook; 3293 + spec->gen.automute_hook = cxt_update_headset_mode; 3294 + break; 3295 + case HDA_FIXUP_ACT_INIT: 3296 + cxt_update_headset_mode(codec); 3297 + break; 3298 + } 3299 + } 3300 + 3255 3301 3256 3302 /* ThinkPad X200 & co with cxt5051 */ 3257 3303 static const struct hda_pintbl cxt_pincfg_lenovo_x200[] = { ··· 3362 3302 .type = HDA_FIXUP_FUNC, 3363 3303 .v.func = cxt5066_increase_mic_boost, 3364 3304 }, 3305 + [CXT_FIXUP_HEADPHONE_MIC_PIN] = { 3306 + .type = HDA_FIXUP_PINS, 3307 + .chained = true, 3308 + .chain_id = CXT_FIXUP_HEADPHONE_MIC, 3309 + .v.pins = (const struct hda_pintbl[]) { 3310 + { 0x18, 0x03a1913d }, /* use as headphone mic, without its own jack detect */ 3311 + { } 3312 + } 3313 + }, 3314 + [CXT_FIXUP_HEADPHONE_MIC] = { 3315 + .type = HDA_FIXUP_FUNC, 3316 + .v.func = cxt_fixup_headphone_mic, 3317 + }, 3365 3318 }; 3366 3319 3367 3320 static const struct snd_pci_quirk cxt5051_fixups[] = { ··· 3384 3311 3385 3312 static const struct snd_pci_quirk cxt5066_fixups[] = { 3386 3313 SND_PCI_QUIRK(0x1025, 0x0543, "Acer Aspire One 522", CXT_FIXUP_STEREO_DMIC), 3314 + SND_PCI_QUIRK(0x1043, 0x138d, "Asus", CXT_FIXUP_HEADPHONE_MIC_PIN), 3387 3315 SND_PCI_QUIRK(0x17aa, 0x20f2, "Lenovo T400", CXT_PINCFG_LENOVO_TP410), 3388 3316 SND_PCI_QUIRK(0x17aa, 0x215e, "Lenovo T410", CXT_PINCFG_LENOVO_TP410), 3389 3317 SND_PCI_QUIRK(0x17aa, 0x215f, "Lenovo T510", CXT_PINCFG_LENOVO_TP410), ··· 3469 3395 3470 3396 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PRE_PROBE); 3471 3397 3472 - err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 0); 3398 + err = snd_hda_parse_pin_defcfg(codec, &spec->gen.autocfg, NULL, 3399 + spec->parse_flags); 3473 3400 if (err < 0) 3474 3401 goto error; 3475 3402 ··· 3490 3415 codec->bus->sync_write = 1; 3491 3416 codec->bus->allow_bus_reset = 1; 3492 3417 } 3418 + 3419 + snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 3493 3420 3494 3421 return 0; 3495 3422
+6 -3
sound/pci/hda/patch_hdmi.c
··· 959 959 int pin_nid; 960 960 int pin_idx; 961 961 struct hda_jack_tbl *jack; 962 + int dev_entry = (res & AC_UNSOL_RES_DE) >> AC_UNSOL_RES_DE_SHIFT; 962 963 963 964 jack = snd_hda_jack_tbl_get_from_tag(codec, tag); 964 965 if (!jack) ··· 968 967 jack->jack_dirty = 1; 969 968 970 969 _snd_printd(SND_PR_VERBOSE, 971 - "HDMI hot plug event: Codec=%d Pin=%d Presence_Detect=%d ELD_Valid=%d\n", 972 - codec->addr, pin_nid, 970 + "HDMI hot plug event: Codec=%d Pin=%d Device=%d Inactive=%d Presence_Detect=%d ELD_Valid=%d\n", 971 + codec->addr, pin_nid, dev_entry, !!(res & AC_UNSOL_RES_IA), 973 972 !!(res & AC_UNSOL_RES_PD), !!(res & AC_UNSOL_RES_ELDV)); 974 973 975 974 pin_idx = pin_nid_to_pin_index(spec, pin_nid); ··· 1993 1992 return -EINVAL; 1994 1993 } 1995 1994 codec->patch_ops = generic_hdmi_patch_ops; 1996 - if (codec->vendor_id == 0x80862807) 1995 + if (codec->vendor_id == 0x80862807) { 1997 1996 codec->patch_ops.set_power_state = haswell_set_power_state; 1997 + codec->dp_mst = true; 1998 + } 1998 1999 1999 2000 generic_hdmi_init_per_pins(codec); 2000 2001
+172 -18
sound/pci/hda/patch_realtek.c
··· 282 282 { 283 283 alc_auto_setup_eapd(codec, false); 284 284 msleep(200); 285 + snd_hda_shutup_pins(codec); 285 286 } 286 287 287 288 /* generic EAPD initialization */ ··· 827 826 828 827 if (spec && spec->shutup) 829 828 spec->shutup(codec); 830 - snd_hda_shutup_pins(codec); 829 + else 830 + snd_hda_shutup_pins(codec); 831 831 } 832 832 833 833 #define alc_free snd_hda_gen_free ··· 1855 1853 const struct hda_fixup *fix, int action) 1856 1854 { 1857 1855 struct alc_spec *spec = codec->spec; 1858 - if (action == HDA_FIXUP_ACT_PRE_PROBE) 1856 + if (action == HDA_FIXUP_ACT_PRE_PROBE) { 1859 1857 spec->gen.no_primary_hp = 1; 1858 + spec->gen.no_multi_io = 1; 1859 + } 1860 1860 } 1861 1861 1862 1862 static const struct hda_fixup alc882_fixups[] = { ··· 2537 2533 ALC269_TYPE_ALC269VD, 2538 2534 ALC269_TYPE_ALC280, 2539 2535 ALC269_TYPE_ALC282, 2536 + ALC269_TYPE_ALC283, 2540 2537 ALC269_TYPE_ALC284, 2541 2538 ALC269_TYPE_ALC286, 2542 2539 }; ··· 2563 2558 case ALC269_TYPE_ALC269VB: 2564 2559 case ALC269_TYPE_ALC269VD: 2565 2560 case ALC269_TYPE_ALC282: 2561 + case ALC269_TYPE_ALC283: 2566 2562 case ALC269_TYPE_ALC286: 2567 2563 ssids = alc269_ssids; 2568 2564 break; ··· 2589 2583 { 2590 2584 struct alc_spec *spec = codec->spec; 2591 2585 2592 - if (spec->codec_variant != ALC269_TYPE_ALC269VB) 2593 - return; 2594 - 2595 2586 if (spec->codec_variant == ALC269_TYPE_ALC269VB) 2596 2587 alc269vb_toggle_power_output(codec, 0); 2597 2588 if (spec->codec_variant == ALC269_TYPE_ALC269VB && 2598 2589 (alc_get_coef0(codec) & 0x00ff) == 0x018) { 2599 2590 msleep(150); 2600 2591 } 2592 + snd_hda_shutup_pins(codec); 2593 + } 2594 + 2595 + static void alc283_init(struct hda_codec *codec) 2596 + { 2597 + struct alc_spec *spec = codec->spec; 2598 + hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; 2599 + bool hp_pin_sense; 2600 + int val; 2601 + 2602 + if (!hp_pin) 2603 + return; 2604 + hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); 2605 + 2606 + /* Index 0x43 Direct Drive HP AMP LPM Control 1 */ 2607 + /* Headphone capless set to high power mode */ 2608 + alc_write_coef_idx(codec, 0x43, 0x9004); 2609 + 2610 + snd_hda_codec_write(codec, hp_pin, 0, 2611 + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 2612 + 2613 + if (hp_pin_sense) 2614 + msleep(85); 2615 + 2616 + snd_hda_codec_write(codec, hp_pin, 0, 2617 + AC_VERB_SET_PIN_WIDGET_CONTROL, PIN_OUT); 2618 + 2619 + if (hp_pin_sense) 2620 + msleep(85); 2621 + /* Index 0x46 Combo jack auto switch control 2 */ 2622 + /* 3k pull low control for Headset jack. */ 2623 + val = alc_read_coef_idx(codec, 0x46); 2624 + alc_write_coef_idx(codec, 0x46, val & ~(3 << 12)); 2625 + /* Headphone capless set to normal mode */ 2626 + alc_write_coef_idx(codec, 0x43, 0x9614); 2627 + } 2628 + 2629 + static void alc283_shutup(struct hda_codec *codec) 2630 + { 2631 + struct alc_spec *spec = codec->spec; 2632 + hda_nid_t hp_pin = spec->gen.autocfg.hp_pins[0]; 2633 + bool hp_pin_sense; 2634 + int val; 2635 + 2636 + if (!hp_pin) { 2637 + alc269_shutup(codec); 2638 + return; 2639 + } 2640 + 2641 + hp_pin_sense = snd_hda_jack_detect(codec, hp_pin); 2642 + 2643 + alc_write_coef_idx(codec, 0x43, 0x9004); 2644 + 2645 + snd_hda_codec_write(codec, hp_pin, 0, 2646 + AC_VERB_SET_AMP_GAIN_MUTE, AMP_OUT_MUTE); 2647 + 2648 + if (hp_pin_sense) 2649 + msleep(85); 2650 + 2651 + snd_hda_codec_write(codec, hp_pin, 0, 2652 + AC_VERB_SET_PIN_WIDGET_CONTROL, 0x0); 2653 + 2654 + val = alc_read_coef_idx(codec, 0x46); 2655 + alc_write_coef_idx(codec, 0x46, val | (3 << 12)); 2656 + 2657 + if (hp_pin_sense) 2658 + msleep(85); 2659 + snd_hda_shutup_pins(codec); 2660 + alc_write_coef_idx(codec, 0x43, 0x9614); 2601 2661 } 2602 2662 2603 2663 static void alc5505_coef_set(struct hda_codec *codec, unsigned int index_reg, ··· 2794 2722 hda_call_check_power_status(codec, 0x01); 2795 2723 if (spec->has_alc5505_dsp) 2796 2724 alc5505_dsp_resume(codec); 2725 + 2797 2726 return 0; 2798 2727 } 2799 2728 #endif /* CONFIG_PM */ ··· 3334 3261 alc_fixup_headset_mode(codec, fix, action); 3335 3262 } 3336 3263 3264 + /* Returns the nid of the external mic input pin, or 0 if it cannot be found. */ 3265 + static int find_ext_mic_pin(struct hda_codec *codec) 3266 + { 3267 + struct alc_spec *spec = codec->spec; 3268 + struct auto_pin_cfg *cfg = &spec->gen.autocfg; 3269 + hda_nid_t nid; 3270 + unsigned int defcfg; 3271 + int i; 3272 + 3273 + for (i = 0; i < cfg->num_inputs; i++) { 3274 + if (cfg->inputs[i].type != AUTO_PIN_MIC) 3275 + continue; 3276 + nid = cfg->inputs[i].pin; 3277 + defcfg = snd_hda_codec_get_pincfg(codec, nid); 3278 + if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT) 3279 + continue; 3280 + return nid; 3281 + } 3282 + 3283 + return 0; 3284 + } 3285 + 3337 3286 static void alc271_hp_gate_mic_jack(struct hda_codec *codec, 3338 3287 const struct hda_fixup *fix, 3339 3288 int action) ··· 3363 3268 struct alc_spec *spec = codec->spec; 3364 3269 3365 3270 if (action == HDA_FIXUP_ACT_PROBE) { 3366 - if (snd_BUG_ON(!spec->gen.am_entry[1].pin || 3367 - !spec->gen.autocfg.hp_pins[0])) 3271 + int mic_pin = find_ext_mic_pin(codec); 3272 + int hp_pin = spec->gen.autocfg.hp_pins[0]; 3273 + 3274 + if (snd_BUG_ON(!mic_pin || !hp_pin)) 3368 3275 return; 3369 - snd_hda_jack_set_gating_jack(codec, spec->gen.am_entry[1].pin, 3370 - spec->gen.autocfg.hp_pins[0]); 3276 + snd_hda_jack_set_gating_jack(codec, mic_pin, hp_pin); 3371 3277 } 3372 3278 } 3373 3279 ··· 3401 3305 (0x01 << AC_AMPCAP_NUM_STEPS_SHIFT) | 3402 3306 (0x2f << AC_AMPCAP_STEP_SIZE_SHIFT) | 3403 3307 (0 << AC_AMPCAP_MUTE_SHIFT)); 3308 + } 3309 + } 3310 + 3311 + static void alc283_hp_automute_hook(struct hda_codec *codec, 3312 + struct hda_jack_tbl *jack) 3313 + { 3314 + struct alc_spec *spec = codec->spec; 3315 + int vref; 3316 + 3317 + msleep(200); 3318 + snd_hda_gen_hp_automute(codec, jack); 3319 + 3320 + vref = spec->gen.hp_jack_present ? PIN_VREF80 : 0; 3321 + 3322 + msleep(600); 3323 + snd_hda_codec_write(codec, 0x19, 0, AC_VERB_SET_PIN_WIDGET_CONTROL, 3324 + vref); 3325 + } 3326 + 3327 + static void alc283_chromebook_caps(struct hda_codec *codec) 3328 + { 3329 + snd_hda_override_wcaps(codec, 0x03, 0); 3330 + } 3331 + 3332 + static void alc283_fixup_chromebook(struct hda_codec *codec, 3333 + const struct hda_fixup *fix, int action) 3334 + { 3335 + struct alc_spec *spec = codec->spec; 3336 + int val; 3337 + 3338 + switch (action) { 3339 + case HDA_FIXUP_ACT_PRE_PROBE: 3340 + alc283_chromebook_caps(codec); 3341 + spec->gen.hp_automute_hook = alc283_hp_automute_hook; 3342 + /* MIC2-VREF control */ 3343 + /* Set to manual mode */ 3344 + val = alc_read_coef_idx(codec, 0x06); 3345 + alc_write_coef_idx(codec, 0x06, val & ~0x000c); 3346 + break; 3404 3347 } 3405 3348 } 3406 3349 ··· 3479 3344 ALC269_FIXUP_ACER_AC700, 3480 3345 ALC269_FIXUP_LIMIT_INT_MIC_BOOST, 3481 3346 ALC269VB_FIXUP_ORDISSIMO_EVE2, 3347 + ALC283_FIXUP_CHROME_BOOK, 3482 3348 }; 3483 3349 3484 3350 static const struct hda_fixup alc269_fixups[] = { ··· 3731 3595 { } 3732 3596 }, 3733 3597 }, 3598 + [ALC283_FIXUP_CHROME_BOOK] = { 3599 + .type = HDA_FIXUP_FUNC, 3600 + .v.func = alc283_fixup_chromebook, 3601 + }, 3734 3602 }; 3735 3603 3736 3604 static const struct snd_pci_quirk alc269_fixup_tbl[] = { 3737 3605 SND_PCI_QUIRK(0x1025, 0x029b, "Acer 1810TZ", ALC269_FIXUP_INV_DMIC), 3738 3606 SND_PCI_QUIRK(0x1025, 0x0349, "Acer AOD260", ALC269_FIXUP_INV_DMIC), 3607 + SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), 3608 + SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), 3609 + SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), 3610 + SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), 3611 + SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 3739 3612 SND_PCI_QUIRK(0x1028, 0x05bd, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3740 3613 SND_PCI_QUIRK(0x1028, 0x05be, "Dell", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE), 3741 3614 SND_PCI_QUIRK(0x1028, 0x05c4, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE), ··· 3782 3637 SND_PCI_QUIRK(0x103c, 0x18e6, "HP", ALC269_FIXUP_HP_GPIO_LED), 3783 3638 SND_PCI_QUIRK(0x103c, 0x1973, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3784 3639 SND_PCI_QUIRK(0x103c, 0x1983, "HP Pavilion", ALC269_FIXUP_HP_MUTE_LED_MIC1), 3640 + SND_PCI_QUIRK(0x103c, 0x21ed, "HP Falco Chromebook", ALC283_FIXUP_CHROME_BOOK), 3785 3641 SND_PCI_QUIRK_VENDOR(0x103c, "HP", ALC269_FIXUP_HP_MUTE_LED), 3786 3642 SND_PCI_QUIRK(0x1043, 0x106d, "Asus K53BE", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3787 3643 SND_PCI_QUIRK(0x1043, 0x115d, "Asus 1015E", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), ··· 3801 3655 SND_PCI_QUIRK(0x104d, 0x907b, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 3802 3656 SND_PCI_QUIRK(0x104d, 0x9084, "Sony VAIO", ALC275_FIXUP_SONY_HWEQ), 3803 3657 SND_PCI_QUIRK_VENDOR(0x104d, "Sony VAIO", ALC269_FIXUP_SONY_VAIO), 3804 - SND_PCI_QUIRK(0x1028, 0x0470, "Dell M101z", ALC269_FIXUP_DELL_M101Z), 3805 - SND_PCI_QUIRK(0x1025, 0x047c, "Acer AC700", ALC269_FIXUP_ACER_AC700), 3806 - SND_PCI_QUIRK(0x1025, 0x0740, "Acer AO725", ALC271_FIXUP_HP_GATE_MIC_JACK), 3807 - SND_PCI_QUIRK(0x1025, 0x0742, "Acer AO756", ALC271_FIXUP_HP_GATE_MIC_JACK), 3808 - SND_PCI_QUIRK_VENDOR(0x1025, "Acer Aspire", ALC271_FIXUP_DMIC), 3809 3658 SND_PCI_QUIRK(0x10cf, 0x1475, "Lifebook", ALC269_FIXUP_LIFEBOOK), 3810 3659 SND_PCI_QUIRK(0x17aa, 0x20f2, "Thinkpad SL410/510", ALC269_FIXUP_SKU_IGNORE), 3811 3660 SND_PCI_QUIRK(0x17aa, 0x215e, "Thinkpad L512", ALC269_FIXUP_SKU_IGNORE), ··· 3811 3670 SND_PCI_QUIRK(0x17aa, 0x21fa, "Thinkpad X230", ALC269_FIXUP_LENOVO_DOCK), 3812 3671 SND_PCI_QUIRK(0x17aa, 0x21f3, "Thinkpad T430", ALC269_FIXUP_LENOVO_DOCK), 3813 3672 SND_PCI_QUIRK(0x17aa, 0x21fb, "Thinkpad T430s", ALC269_FIXUP_LENOVO_DOCK), 3814 - SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), 3815 3673 SND_PCI_QUIRK(0x17aa, 0x2203, "Thinkpad X230 Tablet", ALC269_FIXUP_LENOVO_DOCK), 3674 + SND_PCI_QUIRK(0x17aa, 0x2208, "Thinkpad T431s", ALC269_FIXUP_LENOVO_DOCK), 3675 + SND_PCI_QUIRK(0x17aa, 0x220c, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3676 + SND_PCI_QUIRK(0x17aa, 0x2212, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3677 + SND_PCI_QUIRK(0x17aa, 0x2214, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3678 + SND_PCI_QUIRK(0x17aa, 0x2215, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3679 + SND_PCI_QUIRK(0x17aa, 0x5013, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3680 + SND_PCI_QUIRK(0x17aa, 0x501a, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3681 + SND_PCI_QUIRK(0x17aa, 0x5026, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3682 + SND_PCI_QUIRK(0x17aa, 0x5109, "Thinkpad", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), 3816 3683 SND_PCI_QUIRK(0x17aa, 0x3bf8, "Quanta FL1", ALC269_FIXUP_PCM_44K), 3817 3684 SND_PCI_QUIRK(0x17aa, 0x9e54, "LENOVO NB", ALC269_FIXUP_LENOVO_EAPD), 3818 3685 SND_PCI_QUIRK(0x1b7d, 0xa831, "Ordissimo EVE2 ", ALC269VB_FIXUP_ORDISSIMO_EVE2), /* Also known as Malata PC-B1303 */ ··· 3989 3840 case 0x10ec0290: 3990 3841 spec->codec_variant = ALC269_TYPE_ALC280; 3991 3842 break; 3992 - case 0x10ec0233: 3993 3843 case 0x10ec0282: 3994 - case 0x10ec0283: 3995 3844 spec->codec_variant = ALC269_TYPE_ALC282; 3845 + break; 3846 + case 0x10ec0233: 3847 + case 0x10ec0283: 3848 + spec->codec_variant = ALC269_TYPE_ALC283; 3849 + spec->shutup = alc283_shutup; 3850 + spec->init_hook = alc283_init; 3996 3851 break; 3997 3852 case 0x10ec0284: 3998 3853 case 0x10ec0292: ··· 4025 3872 codec->patch_ops.suspend = alc269_suspend; 4026 3873 codec->patch_ops.resume = alc269_resume; 4027 3874 #endif 4028 - spec->shutup = alc269_shutup; 3875 + if (!spec->shutup) 3876 + spec->shutup = alc269_shutup; 4029 3877 4030 3878 snd_hda_apply_fixup(codec, HDA_FIXUP_ACT_PROBE); 4031 3879
+12 -2
sound/pci/hda/patch_sigmatel.c
··· 158 158 STAC_D965_VERBS, 159 159 STAC_DELL_3ST, 160 160 STAC_DELL_BIOS, 161 + STAC_DELL_BIOS_AMIC, 161 162 STAC_DELL_BIOS_SPDIF, 162 163 STAC_927X_DELL_DMIC, 163 164 STAC_927X_VOLKNOB, ··· 3232 3231 [STAC_DELL_BIOS] = { 3233 3232 .type = HDA_FIXUP_PINS, 3234 3233 .v.pins = (const struct hda_pintbl[]) { 3235 - /* configure the analog microphone on some laptops */ 3236 - { 0x0c, 0x90a79130 }, 3237 3234 /* correct the front output jack as a hp out */ 3238 3235 { 0x0f, 0x0221101f }, 3239 3236 /* correct the front input jack as a mic */ ··· 3240 3241 }, 3241 3242 .chained = true, 3242 3243 .chain_id = STAC_927X_DELL_DMIC, 3244 + }, 3245 + [STAC_DELL_BIOS_AMIC] = { 3246 + .type = HDA_FIXUP_PINS, 3247 + .v.pins = (const struct hda_pintbl[]) { 3248 + /* configure the analog microphone on some laptops */ 3249 + { 0x0c, 0x90a79130 }, 3250 + {} 3251 + }, 3252 + .chained = true, 3253 + .chain_id = STAC_DELL_BIOS, 3243 3254 }, 3244 3255 [STAC_DELL_BIOS_SPDIF] = { 3245 3256 .type = HDA_FIXUP_PINS, ··· 3279 3270 { .id = STAC_D965_5ST_NO_FP, .name = "5stack-no-fp" }, 3280 3271 { .id = STAC_DELL_3ST, .name = "dell-3stack" }, 3281 3272 { .id = STAC_DELL_BIOS, .name = "dell-bios" }, 3273 + { .id = STAC_DELL_BIOS_AMIC, .name = "dell-bios-amic" }, 3282 3274 { .id = STAC_927X_VOLKNOB, .name = "volknob" }, 3283 3275 {} 3284 3276 };
+1 -1
sound/pci/hda/patch_via.c
··· 207 207 return; 208 208 if (spec->hp_work_active) { 209 209 snd_hda_codec_write(codec, 0x1, 0, 0xf81, 1); 210 + codec->jackpoll_interval = 0; 210 211 cancel_delayed_work_sync(&codec->jackpoll_work); 211 212 spec->hp_work_active = false; 212 - codec->jackpoll_interval = 0; 213 213 } 214 214 } 215 215
+231 -74
sound/pci/rme96.c
··· 28 28 #include <linux/interrupt.h> 29 29 #include <linux/pci.h> 30 30 #include <linux/module.h> 31 + #include <linux/vmalloc.h> 31 32 32 33 #include <sound/core.h> 33 34 #include <sound/info.h> ··· 199 198 #define RME96_AD1852_VOL_BITS 14 200 199 #define RME96_AD1855_VOL_BITS 10 201 200 201 + /* Defines for snd_rme96_trigger */ 202 + #define RME96_TB_START_PLAYBACK 1 203 + #define RME96_TB_START_CAPTURE 2 204 + #define RME96_TB_STOP_PLAYBACK 4 205 + #define RME96_TB_STOP_CAPTURE 8 206 + #define RME96_TB_RESET_PLAYPOS 16 207 + #define RME96_TB_RESET_CAPTUREPOS 32 208 + #define RME96_TB_CLEAR_PLAYBACK_IRQ 64 209 + #define RME96_TB_CLEAR_CAPTURE_IRQ 128 210 + #define RME96_RESUME_PLAYBACK (RME96_TB_START_PLAYBACK) 211 + #define RME96_RESUME_CAPTURE (RME96_TB_START_CAPTURE) 212 + #define RME96_RESUME_BOTH (RME96_RESUME_PLAYBACK \ 213 + | RME96_RESUME_CAPTURE) 214 + #define RME96_START_PLAYBACK (RME96_TB_START_PLAYBACK \ 215 + | RME96_TB_RESET_PLAYPOS) 216 + #define RME96_START_CAPTURE (RME96_TB_START_CAPTURE \ 217 + | RME96_TB_RESET_CAPTUREPOS) 218 + #define RME96_START_BOTH (RME96_START_PLAYBACK \ 219 + | RME96_START_CAPTURE) 220 + #define RME96_STOP_PLAYBACK (RME96_TB_STOP_PLAYBACK \ 221 + | RME96_TB_CLEAR_PLAYBACK_IRQ) 222 + #define RME96_STOP_CAPTURE (RME96_TB_STOP_CAPTURE \ 223 + | RME96_TB_CLEAR_CAPTURE_IRQ) 224 + #define RME96_STOP_BOTH (RME96_STOP_PLAYBACK \ 225 + | RME96_STOP_CAPTURE) 202 226 203 227 struct rme96 { 204 228 spinlock_t lock; ··· 239 213 u16 vol[2]; /* cached volume of analog output */ 240 214 241 215 u8 rev; /* card revision number */ 216 + 217 + #ifdef CONFIG_PM 218 + u32 playback_pointer; 219 + u32 capture_pointer; 220 + void *playback_suspend_buffer; 221 + void *capture_suspend_buffer; 222 + #endif 242 223 243 224 struct snd_pcm_substream *playback_substream; 244 225 struct snd_pcm_substream *capture_substream; ··· 377 344 { 378 345 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 379 346 SNDRV_PCM_INFO_MMAP_VALID | 347 + SNDRV_PCM_INFO_SYNC_START | 348 + SNDRV_PCM_INFO_RESUME | 380 349 SNDRV_PCM_INFO_INTERLEAVED | 381 350 SNDRV_PCM_INFO_PAUSE), 382 351 .formats = (SNDRV_PCM_FMTBIT_S16_LE | ··· 408 373 { 409 374 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 410 375 SNDRV_PCM_INFO_MMAP_VALID | 376 + SNDRV_PCM_INFO_SYNC_START | 377 + SNDRV_PCM_INFO_RESUME | 411 378 SNDRV_PCM_INFO_INTERLEAVED | 412 379 SNDRV_PCM_INFO_PAUSE), 413 380 .formats = (SNDRV_PCM_FMTBIT_S16_LE | ··· 439 402 { 440 403 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 441 404 SNDRV_PCM_INFO_MMAP_VALID | 405 + SNDRV_PCM_INFO_SYNC_START | 406 + SNDRV_PCM_INFO_RESUME | 442 407 SNDRV_PCM_INFO_INTERLEAVED | 443 408 SNDRV_PCM_INFO_PAUSE), 444 409 .formats = (SNDRV_PCM_FMTBIT_S16_LE | ··· 466 427 { 467 428 .info = (SNDRV_PCM_INFO_MMAP_IOMEM | 468 429 SNDRV_PCM_INFO_MMAP_VALID | 430 + SNDRV_PCM_INFO_SYNC_START | 431 + SNDRV_PCM_INFO_RESUME | 469 432 SNDRV_PCM_INFO_INTERLEAVED | 470 433 SNDRV_PCM_INFO_PAUSE), 471 434 .formats = (SNDRV_PCM_FMTBIT_S16_LE | ··· 1086 1045 } 1087 1046 1088 1047 static void 1089 - snd_rme96_playback_start(struct rme96 *rme96, 1090 - int from_pause) 1048 + snd_rme96_trigger(struct rme96 *rme96, 1049 + int op) 1091 1050 { 1092 - if (!from_pause) { 1051 + if (op & RME96_TB_RESET_PLAYPOS) 1093 1052 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS); 1094 - } 1095 - 1096 - rme96->wcreg |= RME96_WCR_START; 1097 - writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); 1098 - } 1099 - 1100 - static void 1101 - snd_rme96_capture_start(struct rme96 *rme96, 1102 - int from_pause) 1103 - { 1104 - if (!from_pause) { 1053 + if (op & RME96_TB_RESET_CAPTUREPOS) 1105 1054 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS); 1055 + if (op & RME96_TB_CLEAR_PLAYBACK_IRQ) { 1056 + rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); 1057 + if (rme96->rcreg & RME96_RCR_IRQ) 1058 + writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ); 1106 1059 } 1107 - 1108 - rme96->wcreg |= RME96_WCR_START_2; 1060 + if (op & RME96_TB_CLEAR_CAPTURE_IRQ) { 1061 + rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); 1062 + if (rme96->rcreg & RME96_RCR_IRQ_2) 1063 + writel(0, rme96->iobase + RME96_IO_CONFIRM_REC_IRQ); 1064 + } 1065 + if (op & RME96_TB_START_PLAYBACK) 1066 + rme96->wcreg |= RME96_WCR_START; 1067 + if (op & RME96_TB_STOP_PLAYBACK) 1068 + rme96->wcreg &= ~RME96_WCR_START; 1069 + if (op & RME96_TB_START_CAPTURE) 1070 + rme96->wcreg |= RME96_WCR_START_2; 1071 + if (op & RME96_TB_STOP_CAPTURE) 1072 + rme96->wcreg &= ~RME96_WCR_START_2; 1109 1073 writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); 1110 1074 } 1111 1075 1112 - static void 1113 - snd_rme96_playback_stop(struct rme96 *rme96) 1114 - { 1115 - /* 1116 - * Check if there is an unconfirmed IRQ, if so confirm it, or else 1117 - * the hardware will not stop generating interrupts 1118 - */ 1119 - rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); 1120 - if (rme96->rcreg & RME96_RCR_IRQ) { 1121 - writel(0, rme96->iobase + RME96_IO_CONFIRM_PLAY_IRQ); 1122 - } 1123 - rme96->wcreg &= ~RME96_WCR_START; 1124 - writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); 1125 - } 1126 1076 1127 - static void 1128 - snd_rme96_capture_stop(struct rme96 *rme96) 1129 - { 1130 - rme96->rcreg = readl(rme96->iobase + RME96_IO_CONTROL_REGISTER); 1131 - if (rme96->rcreg & RME96_RCR_IRQ_2) { 1132 - writel(0, rme96->iobase + RME96_IO_CONFIRM_REC_IRQ); 1133 - } 1134 - rme96->wcreg &= ~RME96_WCR_START_2; 1135 - writel(rme96->wcreg, rme96->iobase + RME96_IO_CONTROL_REGISTER); 1136 - } 1137 1077 1138 1078 static irqreturn_t 1139 1079 snd_rme96_interrupt(int irq, ··· 1177 1155 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1178 1156 struct snd_pcm_runtime *runtime = substream->runtime; 1179 1157 1158 + snd_pcm_set_sync(substream); 1180 1159 spin_lock_irq(&rme96->lock); 1181 1160 if (rme96->playback_substream != NULL) { 1182 1161 spin_unlock_irq(&rme96->lock); ··· 1214 1191 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1215 1192 struct snd_pcm_runtime *runtime = substream->runtime; 1216 1193 1194 + snd_pcm_set_sync(substream); 1217 1195 runtime->hw = snd_rme96_capture_spdif_info; 1218 1196 if (snd_rme96_getinputtype(rme96) != RME96_INPUT_ANALOG && 1219 1197 (rate = snd_rme96_capture_getrate(rme96, &isadat)) > 0) ··· 1246 1222 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1247 1223 struct snd_pcm_runtime *runtime = substream->runtime; 1248 1224 1225 + snd_pcm_set_sync(substream); 1249 1226 spin_lock_irq(&rme96->lock); 1250 1227 if (rme96->playback_substream != NULL) { 1251 1228 spin_unlock_irq(&rme96->lock); ··· 1278 1253 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1279 1254 struct snd_pcm_runtime *runtime = substream->runtime; 1280 1255 1256 + snd_pcm_set_sync(substream); 1281 1257 runtime->hw = snd_rme96_capture_adat_info; 1282 1258 if (snd_rme96_getinputtype(rme96) == RME96_INPUT_ANALOG) { 1283 1259 /* makes no sense to use analog input. Note that analog ··· 1314 1288 1315 1289 spin_lock_irq(&rme96->lock); 1316 1290 if (RME96_ISPLAYING(rme96)) { 1317 - snd_rme96_playback_stop(rme96); 1291 + snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK); 1318 1292 } 1319 1293 rme96->playback_substream = NULL; 1320 1294 rme96->playback_periodsize = 0; ··· 1335 1309 1336 1310 spin_lock_irq(&rme96->lock); 1337 1311 if (RME96_ISRECORDING(rme96)) { 1338 - snd_rme96_capture_stop(rme96); 1312 + snd_rme96_trigger(rme96, RME96_STOP_CAPTURE); 1339 1313 } 1340 1314 rme96->capture_substream = NULL; 1341 1315 rme96->capture_periodsize = 0; ··· 1350 1324 1351 1325 spin_lock_irq(&rme96->lock); 1352 1326 if (RME96_ISPLAYING(rme96)) { 1353 - snd_rme96_playback_stop(rme96); 1327 + snd_rme96_trigger(rme96, RME96_STOP_PLAYBACK); 1354 1328 } 1355 1329 writel(0, rme96->iobase + RME96_IO_RESET_PLAY_POS); 1356 1330 spin_unlock_irq(&rme96->lock); ··· 1364 1338 1365 1339 spin_lock_irq(&rme96->lock); 1366 1340 if (RME96_ISRECORDING(rme96)) { 1367 - snd_rme96_capture_stop(rme96); 1341 + snd_rme96_trigger(rme96, RME96_STOP_CAPTURE); 1368 1342 } 1369 1343 writel(0, rme96->iobase + RME96_IO_RESET_REC_POS); 1370 1344 spin_unlock_irq(&rme96->lock); ··· 1376 1350 int cmd) 1377 1351 { 1378 1352 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1353 + struct snd_pcm_substream *s; 1354 + bool sync; 1355 + 1356 + snd_pcm_group_for_each_entry(s, substream) { 1357 + if (snd_pcm_substream_chip(s) == rme96) 1358 + snd_pcm_trigger_done(s, substream); 1359 + } 1360 + 1361 + sync = (rme96->playback_substream && rme96->capture_substream) && 1362 + (rme96->playback_substream->group == 1363 + rme96->capture_substream->group); 1379 1364 1380 1365 switch (cmd) { 1381 1366 case SNDRV_PCM_TRIGGER_START: 1382 1367 if (!RME96_ISPLAYING(rme96)) { 1383 - if (substream != rme96->playback_substream) { 1368 + if (substream != rme96->playback_substream) 1384 1369 return -EBUSY; 1385 - } 1386 - snd_rme96_playback_start(rme96, 0); 1370 + snd_rme96_trigger(rme96, sync ? RME96_START_BOTH 1371 + : RME96_START_PLAYBACK); 1387 1372 } 1388 1373 break; 1389 1374 1375 + case SNDRV_PCM_TRIGGER_SUSPEND: 1390 1376 case SNDRV_PCM_TRIGGER_STOP: 1391 1377 if (RME96_ISPLAYING(rme96)) { 1392 - if (substream != rme96->playback_substream) { 1378 + if (substream != rme96->playback_substream) 1393 1379 return -EBUSY; 1394 - } 1395 - snd_rme96_playback_stop(rme96); 1380 + snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH 1381 + : RME96_STOP_PLAYBACK); 1396 1382 } 1397 1383 break; 1398 1384 1399 1385 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1400 - if (RME96_ISPLAYING(rme96)) { 1401 - snd_rme96_playback_stop(rme96); 1402 - } 1386 + if (RME96_ISPLAYING(rme96)) 1387 + snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH 1388 + : RME96_STOP_PLAYBACK); 1403 1389 break; 1404 1390 1391 + case SNDRV_PCM_TRIGGER_RESUME: 1405 1392 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1406 - if (!RME96_ISPLAYING(rme96)) { 1407 - snd_rme96_playback_start(rme96, 1); 1408 - } 1393 + if (!RME96_ISPLAYING(rme96)) 1394 + snd_rme96_trigger(rme96, sync ? RME96_RESUME_BOTH 1395 + : RME96_RESUME_PLAYBACK); 1409 1396 break; 1410 - 1397 + 1411 1398 default: 1412 1399 return -EINVAL; 1413 1400 } 1401 + 1414 1402 return 0; 1415 1403 } 1416 1404 ··· 1433 1393 int cmd) 1434 1394 { 1435 1395 struct rme96 *rme96 = snd_pcm_substream_chip(substream); 1396 + struct snd_pcm_substream *s; 1397 + bool sync; 1398 + 1399 + snd_pcm_group_for_each_entry(s, substream) { 1400 + if (snd_pcm_substream_chip(s) == rme96) 1401 + snd_pcm_trigger_done(s, substream); 1402 + } 1403 + 1404 + sync = (rme96->playback_substream && rme96->capture_substream) && 1405 + (rme96->playback_substream->group == 1406 + rme96->capture_substream->group); 1436 1407 1437 1408 switch (cmd) { 1438 1409 case SNDRV_PCM_TRIGGER_START: 1439 1410 if (!RME96_ISRECORDING(rme96)) { 1440 - if (substream != rme96->capture_substream) { 1411 + if (substream != rme96->capture_substream) 1441 1412 return -EBUSY; 1442 - } 1443 - snd_rme96_capture_start(rme96, 0); 1413 + snd_rme96_trigger(rme96, sync ? RME96_START_BOTH 1414 + : RME96_START_CAPTURE); 1444 1415 } 1445 1416 break; 1446 1417 1418 + case SNDRV_PCM_TRIGGER_SUSPEND: 1447 1419 case SNDRV_PCM_TRIGGER_STOP: 1448 1420 if (RME96_ISRECORDING(rme96)) { 1449 - if (substream != rme96->capture_substream) { 1421 + if (substream != rme96->capture_substream) 1450 1422 return -EBUSY; 1451 - } 1452 - snd_rme96_capture_stop(rme96); 1423 + snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH 1424 + : RME96_STOP_CAPTURE); 1453 1425 } 1454 1426 break; 1455 1427 1456 1428 case SNDRV_PCM_TRIGGER_PAUSE_PUSH: 1457 - if (RME96_ISRECORDING(rme96)) { 1458 - snd_rme96_capture_stop(rme96); 1459 - } 1429 + if (RME96_ISRECORDING(rme96)) 1430 + snd_rme96_trigger(rme96, sync ? RME96_STOP_BOTH 1431 + : RME96_STOP_CAPTURE); 1460 1432 break; 1461 1433 1434 + case SNDRV_PCM_TRIGGER_RESUME: 1462 1435 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: 1463 - if (!RME96_ISRECORDING(rme96)) { 1464 - snd_rme96_capture_start(rme96, 1); 1465 - } 1436 + if (!RME96_ISRECORDING(rme96)) 1437 + snd_rme96_trigger(rme96, sync ? RME96_RESUME_BOTH 1438 + : RME96_RESUME_CAPTURE); 1466 1439 break; 1467 - 1440 + 1468 1441 default: 1469 1442 return -EINVAL; 1470 1443 } ··· 1558 1505 return; 1559 1506 } 1560 1507 if (rme96->irq >= 0) { 1561 - snd_rme96_playback_stop(rme96); 1562 - snd_rme96_capture_stop(rme96); 1508 + snd_rme96_trigger(rme96, RME96_STOP_BOTH); 1563 1509 rme96->areg &= ~RME96_AR_DAC_EN; 1564 1510 writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); 1565 1511 free_irq(rme96->irq, (void *)rme96); ··· 1572 1520 pci_release_regions(rme96->pci); 1573 1521 rme96->port = 0; 1574 1522 } 1523 + #ifdef CONFIG_PM 1524 + vfree(rme96->playback_suspend_buffer); 1525 + vfree(rme96->capture_suspend_buffer); 1526 + #endif 1575 1527 pci_disable_device(rme96->pci); 1576 1528 } 1577 1529 ··· 1662 1606 rme96->capture_periodsize = 0; 1663 1607 1664 1608 /* make sure playback/capture is stopped, if by some reason active */ 1665 - snd_rme96_playback_stop(rme96); 1666 - snd_rme96_capture_stop(rme96); 1609 + snd_rme96_trigger(rme96, RME96_STOP_BOTH); 1667 1610 1668 1611 /* set default values in registers */ 1669 1612 rme96->wcreg = ··· 2374 2319 * Card initialisation 2375 2320 */ 2376 2321 2322 + #ifdef CONFIG_PM 2323 + 2324 + static int 2325 + snd_rme96_suspend(struct pci_dev *pci, 2326 + pm_message_t state) 2327 + { 2328 + struct snd_card *card = pci_get_drvdata(pci); 2329 + struct rme96 *rme96 = card->private_data; 2330 + 2331 + snd_power_change_state(card, SNDRV_CTL_POWER_D3hot); 2332 + snd_pcm_suspend(rme96->playback_substream); 2333 + snd_pcm_suspend(rme96->capture_substream); 2334 + 2335 + /* save capture & playback pointers */ 2336 + rme96->playback_pointer = readl(rme96->iobase + RME96_IO_GET_PLAY_POS) 2337 + & RME96_RCR_AUDIO_ADDR_MASK; 2338 + rme96->capture_pointer = readl(rme96->iobase + RME96_IO_GET_REC_POS) 2339 + & RME96_RCR_AUDIO_ADDR_MASK; 2340 + 2341 + /* save playback and capture buffers */ 2342 + memcpy_fromio(rme96->playback_suspend_buffer, 2343 + rme96->iobase + RME96_IO_PLAY_BUFFER, RME96_BUFFER_SIZE); 2344 + memcpy_fromio(rme96->capture_suspend_buffer, 2345 + rme96->iobase + RME96_IO_REC_BUFFER, RME96_BUFFER_SIZE); 2346 + 2347 + /* disable the DAC */ 2348 + rme96->areg &= ~RME96_AR_DAC_EN; 2349 + writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); 2350 + 2351 + pci_disable_device(pci); 2352 + pci_save_state(pci); 2353 + 2354 + return 0; 2355 + } 2356 + 2357 + static int 2358 + snd_rme96_resume(struct pci_dev *pci) 2359 + { 2360 + struct snd_card *card = pci_get_drvdata(pci); 2361 + struct rme96 *rme96 = card->private_data; 2362 + 2363 + pci_restore_state(pci); 2364 + if (pci_enable_device(pci) < 0) { 2365 + printk(KERN_ERR "rme96: pci_enable_device failed, disabling device\n"); 2366 + snd_card_disconnect(card); 2367 + return -EIO; 2368 + } 2369 + 2370 + /* reset playback and record buffer pointers */ 2371 + writel(0, rme96->iobase + RME96_IO_SET_PLAY_POS 2372 + + rme96->playback_pointer); 2373 + writel(0, rme96->iobase + RME96_IO_SET_REC_POS 2374 + + rme96->capture_pointer); 2375 + 2376 + /* restore playback and capture buffers */ 2377 + memcpy_toio(rme96->iobase + RME96_IO_PLAY_BUFFER, 2378 + rme96->playback_suspend_buffer, RME96_BUFFER_SIZE); 2379 + memcpy_toio(rme96->iobase + RME96_IO_REC_BUFFER, 2380 + rme96->capture_suspend_buffer, RME96_BUFFER_SIZE); 2381 + 2382 + /* reset the ADC */ 2383 + writel(rme96->areg | RME96_AR_PD2, 2384 + rme96->iobase + RME96_IO_ADDITIONAL_REG); 2385 + writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); 2386 + 2387 + /* reset and enable DAC, restore analog volume */ 2388 + snd_rme96_reset_dac(rme96); 2389 + rme96->areg |= RME96_AR_DAC_EN; 2390 + writel(rme96->areg, rme96->iobase + RME96_IO_ADDITIONAL_REG); 2391 + if (RME96_HAS_ANALOG_OUT(rme96)) { 2392 + usleep_range(3000, 10000); 2393 + snd_rme96_apply_dac_volume(rme96); 2394 + } 2395 + 2396 + snd_power_change_state(card, SNDRV_CTL_POWER_D0); 2397 + 2398 + return 0; 2399 + } 2400 + 2401 + #endif 2402 + 2377 2403 static void snd_rme96_card_free(struct snd_card *card) 2378 2404 { 2379 2405 snd_rme96_free(card->private_data); ··· 2491 2355 return err; 2492 2356 } 2493 2357 2358 + #ifdef CONFIG_PM 2359 + rme96->playback_suspend_buffer = vmalloc(RME96_BUFFER_SIZE); 2360 + if (!rme96->playback_suspend_buffer) { 2361 + snd_printk(KERN_ERR 2362 + "Failed to allocate playback suspend buffer!\n"); 2363 + snd_card_free(card); 2364 + return -ENOMEM; 2365 + } 2366 + rme96->capture_suspend_buffer = vmalloc(RME96_BUFFER_SIZE); 2367 + if (!rme96->capture_suspend_buffer) { 2368 + snd_printk(KERN_ERR 2369 + "Failed to allocate capture suspend buffer!\n"); 2370 + snd_card_free(card); 2371 + return -ENOMEM; 2372 + } 2373 + #endif 2374 + 2494 2375 strcpy(card->driver, "Digi96"); 2495 2376 switch (rme96->pci->device) { 2496 2377 case PCI_DEVICE_ID_RME_DIGI96: ··· 2550 2397 .id_table = snd_rme96_ids, 2551 2398 .probe = snd_rme96_probe, 2552 2399 .remove = snd_rme96_remove, 2400 + #ifdef CONFIG_PM 2401 + .suspend = snd_rme96_suspend, 2402 + .resume = snd_rme96_resume, 2403 + #endif 2553 2404 }; 2554 2405 2555 2406 module_pci_driver(rme96_driver);
+548 -237
sound/pci/rme9652/hdspm.c
··· 38 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 132 #include <linux/init.h> 42 133 #include <linux/delay.h> 43 134 #include <linux/interrupt.h> ··· 186 95 #define HDSPM_controlRegister 64 187 96 #define HDSPM_interruptConfirmation 96 188 97 #define HDSPM_control2Reg 256 /* not in specs ???????? */ 189 - #define HDSPM_freqReg 256 /* for AES32 */ 98 + #define HDSPM_freqReg 256 /* for setting arbitrary clock values (DDS feature) */ 190 99 #define HDSPM_midiDataOut0 352 /* just believe in old code */ 191 100 #define HDSPM_midiDataOut1 356 192 101 #define HDSPM_eeprom_wr 384 /* for AES32 */ ··· 349 258 350 259 #define HDSPM_wclk_sel (1<<30) 351 260 261 + /* additional control register bits for AIO*/ 262 + #define HDSPM_c0_Wck48 0x20 /* also RayDAT */ 263 + #define HDSPM_c0_Input0 0x1000 264 + #define HDSPM_c0_Input1 0x2000 265 + #define HDSPM_c0_Spdif_Opt 0x4000 266 + #define HDSPM_c0_Pro 0x8000 267 + #define HDSPM_c0_clr_tms 0x10000 268 + #define HDSPM_c0_AEB1 0x20000 269 + #define HDSPM_c0_AEB2 0x40000 270 + #define HDSPM_c0_LineOut 0x80000 271 + #define HDSPM_c0_AD_GAIN0 0x100000 272 + #define HDSPM_c0_AD_GAIN1 0x200000 273 + #define HDSPM_c0_DA_GAIN0 0x400000 274 + #define HDSPM_c0_DA_GAIN1 0x800000 275 + #define HDSPM_c0_PH_GAIN0 0x1000000 276 + #define HDSPM_c0_PH_GAIN1 0x2000000 277 + #define HDSPM_c0_Sym6db 0x4000000 278 + 279 + 352 280 /* --- bit helper defines */ 353 281 #define HDSPM_LatencyMask (HDSPM_Latency0|HDSPM_Latency1|HDSPM_Latency2) 354 282 #define HDSPM_FrequencyMask (HDSPM_Frequency0|HDSPM_Frequency1|\ ··· 451 341 #define HDSPM_madiLock (1<<3) /* MADI Locked =1, no=0 */ 452 342 #define HDSPM_madiSync (1<<18) /* MADI is in sync */ 453 343 454 - #define HDSPM_tcoLock 0x00000020 /* Optional TCO locked status FOR HDSPe MADI! */ 455 - #define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status */ 344 + #define HDSPM_tcoLockMadi 0x00000020 /* Optional TCO locked status for HDSPe MADI*/ 345 + #define HDSPM_tcoSync 0x10000000 /* Optional TCO sync status for HDSPe MADI and AES32!*/ 456 346 457 - #define HDSPM_syncInLock 0x00010000 /* Sync In lock status FOR HDSPe MADI! */ 458 - #define HDSPM_syncInSync 0x00020000 /* Sync In sync status FOR HDSPe MADI! */ 347 + #define HDSPM_syncInLock 0x00010000 /* Sync In lock status for HDSPe MADI! */ 348 + #define HDSPM_syncInSync 0x00020000 /* Sync In sync status for HDSPe MADI! */ 459 349 460 350 #define HDSPM_BufferPositionMask 0x000FFC0 /* Bit 6..15 : h/w buffer pointer */ 461 351 /* since 64byte accurate, last 6 bits are not used */ ··· 473 363 * Interrupt 474 364 */ 475 365 #define HDSPM_tco_detect 0x08000000 476 - #define HDSPM_tco_lock 0x20000000 366 + #define HDSPM_tcoLockAes 0x20000000 /* Optional TCO locked status for HDSPe AES */ 477 367 478 368 #define HDSPM_s2_tco_detect 0x00000040 479 369 #define HDSPM_s2_AEBO_D 0x00000080 ··· 571 461 #define HDSPM_AES32_AUTOSYNC_FROM_AES6 6 572 462 #define HDSPM_AES32_AUTOSYNC_FROM_AES7 7 573 463 #define HDSPM_AES32_AUTOSYNC_FROM_AES8 8 574 - #define HDSPM_AES32_AUTOSYNC_FROM_NONE 9 464 + #define HDSPM_AES32_AUTOSYNC_FROM_TCO 9 465 + #define HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN 10 466 + #define HDSPM_AES32_AUTOSYNC_FROM_NONE 11 575 467 576 468 /* status2 */ 577 469 /* HDSPM_LockAES_bit is given by HDSPM_LockAES >> (AES# - 1) */ ··· 649 537 /* names for speed modes */ 650 538 static char *hdspm_speed_names[] = { "single", "double", "quad" }; 651 539 652 - static char *texts_autosync_aes_tco[] = { "Word Clock", 540 + static const char *const texts_autosync_aes_tco[] = { "Word Clock", 653 541 "AES1", "AES2", "AES3", "AES4", 654 542 "AES5", "AES6", "AES7", "AES8", 655 - "TCO" }; 656 - static char *texts_autosync_aes[] = { "Word Clock", 543 + "TCO", "Sync In" 544 + }; 545 + static const char *const texts_autosync_aes[] = { "Word Clock", 657 546 "AES1", "AES2", "AES3", "AES4", 658 - "AES5", "AES6", "AES7", "AES8" }; 659 - static char *texts_autosync_madi_tco[] = { "Word Clock", 547 + "AES5", "AES6", "AES7", "AES8", 548 + "Sync In" 549 + }; 550 + static const char *const texts_autosync_madi_tco[] = { "Word Clock", 660 551 "MADI", "TCO", "Sync In" }; 661 - static char *texts_autosync_madi[] = { "Word Clock", 552 + static const char *const texts_autosync_madi[] = { "Word Clock", 662 553 "MADI", "Sync In" }; 663 554 664 - static char *texts_autosync_raydat_tco[] = { 555 + static const char *const texts_autosync_raydat_tco[] = { 665 556 "Word Clock", 666 557 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4", 667 558 "AES", "SPDIF", "TCO", "Sync In" 668 559 }; 669 - static char *texts_autosync_raydat[] = { 560 + static const char *const texts_autosync_raydat[] = { 670 561 "Word Clock", 671 562 "ADAT 1", "ADAT 2", "ADAT 3", "ADAT 4", 672 563 "AES", "SPDIF", "Sync In" 673 564 }; 674 - static char *texts_autosync_aio_tco[] = { 565 + static const char *const texts_autosync_aio_tco[] = { 675 566 "Word Clock", 676 567 "ADAT", "AES", "SPDIF", "TCO", "Sync In" 677 568 }; 678 - static char *texts_autosync_aio[] = { "Word Clock", 569 + static const char *const texts_autosync_aio[] = { "Word Clock", 679 570 "ADAT", "AES", "SPDIF", "Sync In" }; 680 571 681 - static char *texts_freq[] = { 572 + static const char *const texts_freq[] = { 682 573 "No Lock", 683 574 "32 kHz", 684 575 "44.1 kHz", ··· 744 629 "AES.L", "AES.R", 745 630 "SPDIF.L", "SPDIF.R", 746 631 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6", 747 - "ADAT.7", "ADAT.8" 632 + "ADAT.7", "ADAT.8", 633 + "AEB.1", "AEB.2", "AEB.3", "AEB.4" 748 634 }; 749 635 750 636 static char *texts_ports_aio_out_ss[] = { ··· 754 638 "SPDIF.L", "SPDIF.R", 755 639 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", "ADAT.5", "ADAT.6", 756 640 "ADAT.7", "ADAT.8", 757 - "Phone.L", "Phone.R" 641 + "Phone.L", "Phone.R", 642 + "AEB.1", "AEB.2", "AEB.3", "AEB.4" 758 643 }; 759 644 760 645 static char *texts_ports_aio_in_ds[] = { 761 646 "Analogue.L", "Analogue.R", 762 647 "AES.L", "AES.R", 763 648 "SPDIF.L", "SPDIF.R", 764 - "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4" 649 + "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", 650 + "AEB.1", "AEB.2", "AEB.3", "AEB.4" 765 651 }; 766 652 767 653 static char *texts_ports_aio_out_ds[] = { ··· 771 653 "AES.L", "AES.R", 772 654 "SPDIF.L", "SPDIF.R", 773 655 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", 774 - "Phone.L", "Phone.R" 656 + "Phone.L", "Phone.R", 657 + "AEB.1", "AEB.2", "AEB.3", "AEB.4" 775 658 }; 776 659 777 660 static char *texts_ports_aio_in_qs[] = { 778 661 "Analogue.L", "Analogue.R", 779 662 "AES.L", "AES.R", 780 663 "SPDIF.L", "SPDIF.R", 781 - "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4" 664 + "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", 665 + "AEB.1", "AEB.2", "AEB.3", "AEB.4" 782 666 }; 783 667 784 668 static char *texts_ports_aio_out_qs[] = { ··· 788 668 "AES.L", "AES.R", 789 669 "SPDIF.L", "SPDIF.R", 790 670 "ADAT.1", "ADAT.2", "ADAT.3", "ADAT.4", 791 - "Phone.L", "Phone.R" 671 + "Phone.L", "Phone.R", 672 + "AEB.1", "AEB.2", "AEB.3", "AEB.4" 792 673 }; 793 674 794 675 static char *texts_ports_aes32[] = { ··· 866 745 8, 9, /* aes in, */ 867 746 10, 11, /* spdif in */ 868 747 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT in */ 869 - -1, -1, 870 - -1, -1, -1, -1, -1, -1, -1, -1, 748 + 2, 3, 4, 5, /* AEB */ 749 + -1, -1, -1, -1, -1, -1, 871 750 -1, -1, -1, -1, -1, -1, -1, -1, 872 751 -1, -1, -1, -1, -1, -1, -1, -1, 873 752 -1, -1, -1, -1, -1, -1, -1, -1, ··· 881 760 10, 11, /* spdif out */ 882 761 12, 13, 14, 15, 16, 17, 18, 19, /* ADAT out */ 883 762 6, 7, /* phone out */ 884 - -1, -1, -1, -1, -1, -1, -1, -1, 763 + 2, 3, 4, 5, /* AEB */ 764 + -1, -1, -1, -1, 885 765 -1, -1, -1, -1, -1, -1, -1, -1, 886 766 -1, -1, -1, -1, -1, -1, -1, -1, 887 767 -1, -1, -1, -1, -1, -1, -1, -1, ··· 895 773 8, 9, /* aes in */ 896 774 10, 11, /* spdif in */ 897 775 12, 14, 16, 18, /* adat in */ 898 - -1, -1, -1, -1, -1, -1, 776 + 2, 3, 4, 5, /* AEB */ 777 + -1, -1, 899 778 -1, -1, -1, -1, -1, -1, -1, -1, 900 779 -1, -1, -1, -1, -1, -1, -1, -1, 901 780 -1, -1, -1, -1, -1, -1, -1, -1, ··· 911 788 10, 11, /* spdif out */ 912 789 12, 14, 16, 18, /* adat out */ 913 790 6, 7, /* phone out */ 914 - -1, -1, -1, -1, 791 + 2, 3, 4, 5, /* AEB */ 915 792 -1, -1, -1, -1, -1, -1, -1, -1, 916 793 -1, -1, -1, -1, -1, -1, -1, -1, 917 794 -1, -1, -1, -1, -1, -1, -1, -1, ··· 925 802 8, 9, /* aes in */ 926 803 10, 11, /* spdif in */ 927 804 12, 16, /* adat in */ 928 - -1, -1, -1, -1, -1, -1, -1, -1, 805 + 2, 3, 4, 5, /* AEB */ 806 + -1, -1, -1, -1, 929 807 -1, -1, -1, -1, -1, -1, -1, -1, 930 808 -1, -1, -1, -1, -1, -1, -1, -1, 931 809 -1, -1, -1, -1, -1, -1, -1, -1, ··· 941 817 10, 11, /* spdif out */ 942 818 12, 16, /* adat out */ 943 819 6, 7, /* phone out */ 944 - -1, -1, -1, -1, -1, -1, 820 + 2, 3, 4, 5, /* AEB */ 821 + -1, -1, 945 822 -1, -1, -1, -1, -1, -1, -1, -1, 946 823 -1, -1, -1, -1, -1, -1, -1, -1, 947 824 -1, -1, -1, -1, -1, -1, -1, -1, ··· 981 856 }; 982 857 983 858 struct hdspm_tco { 984 - int input; 985 - int framerate; 986 - int wordclock; 987 - int samplerate; 988 - int pull; 859 + int input; /* 0: LTC, 1:Video, 2: WC*/ 860 + int framerate; /* 0=24, 1=25, 2=29.97, 3=29.97d, 4=30, 5=30d */ 861 + int wordclock; /* 0=1:1, 1=44.1->48, 2=48->44.1 */ 862 + int samplerate; /* 0=44.1, 1=48, 2= freq from app */ 863 + int pull; /* 0=0, 1=+0.1%, 2=-0.1%, 3=+4%, 4=-4%*/ 989 864 int term; /* 0 = off, 1 = on */ 990 865 }; 991 866 ··· 1004 879 1005 880 u32 control_register; /* cached value */ 1006 881 u32 control2_register; /* cached value */ 1007 - u32 settings_register; 882 + u32 settings_register; /* cached value for AIO / RayDat (sync reference, master/slave) */ 1008 883 1009 884 struct hdspm_midi midi[4]; 1010 885 struct tasklet_struct midi_tasklet; ··· 1066 941 1067 942 struct hdspm_tco *tco; /* NULL if no TCO detected */ 1068 943 1069 - char **texts_autosync; 944 + const char *const *texts_autosync; 1070 945 int texts_autosync_items; 1071 946 1072 947 cycles_t last_interrupt; ··· 1101 976 static inline int hdspm_get_pll_freq(struct hdspm *hdspm); 1102 977 static int hdspm_update_simple_mixer_controls(struct hdspm *hdspm); 1103 978 static int hdspm_autosync_ref(struct hdspm *hdspm); 979 + static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out); 1104 980 static int snd_hdspm_set_defaults(struct hdspm *hdspm); 1105 981 static int hdspm_system_clock_mode(struct hdspm *hdspm); 1106 982 static void hdspm_set_sgbuf(struct hdspm *hdspm, 1107 983 struct snd_pcm_substream *substream, 1108 984 unsigned int reg, int channels); 985 + 986 + static int hdspm_aes_sync_check(struct hdspm *hdspm, int idx); 987 + static int hdspm_wc_sync_check(struct hdspm *hdspm); 988 + static int hdspm_tco_sync_check(struct hdspm *hdspm); 989 + static int hdspm_sync_in_sync_check(struct hdspm *hdspm); 990 + 991 + static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index); 992 + static int hdspm_get_tco_sample_rate(struct hdspm *hdspm); 993 + static int hdspm_get_wc_sample_rate(struct hdspm *hdspm); 994 + 995 + 1109 996 1110 997 static inline int HDSPM_bit2freq(int n) 1111 998 { ··· 1128 991 return 0; 1129 992 return bit2freq_tab[n]; 1130 993 } 994 + 995 + static bool hdspm_is_raydat_or_aio(struct hdspm *hdspm) 996 + { 997 + return ((AIO == hdspm->io_type) || (RayDAT == hdspm->io_type)); 998 + } 999 + 1131 1000 1132 1001 /* Write/read to/from HDSPM with Adresses in Bytes 1133 1002 not words but only 32Bit writes are allowed */ ··· 1250 1107 else if (hdspm->control_register & 1251 1108 HDSPM_DoubleSpeed) 1252 1109 return rate * 2; 1253 - }; 1110 + } 1254 1111 return rate; 1255 1112 } 1256 1113 1257 - static int hdspm_tco_sync_check(struct hdspm *hdspm); 1258 - static int hdspm_sync_in_sync_check(struct hdspm *hdspm); 1259 - 1260 - /* check for external sample rate */ 1114 + /* check for external sample rate, returns the sample rate in Hz*/ 1261 1115 static int hdspm_external_sample_rate(struct hdspm *hdspm) 1262 1116 { 1263 1117 unsigned int status, status2, timecode; ··· 1267 1127 timecode = hdspm_read(hdspm, HDSPM_timecodeRegister); 1268 1128 1269 1129 syncref = hdspm_autosync_ref(hdspm); 1130 + switch (syncref) { 1131 + case HDSPM_AES32_AUTOSYNC_FROM_WORD: 1132 + /* Check WC sync and get sample rate */ 1133 + if (hdspm_wc_sync_check(hdspm)) 1134 + return HDSPM_bit2freq(hdspm_get_wc_sample_rate(hdspm)); 1135 + break; 1270 1136 1271 - if (syncref == HDSPM_AES32_AUTOSYNC_FROM_WORD && 1272 - status & HDSPM_AES32_wcLock) 1273 - return HDSPM_bit2freq((status >> HDSPM_AES32_wcFreq_bit) & 0xF); 1137 + case HDSPM_AES32_AUTOSYNC_FROM_AES1: 1138 + case HDSPM_AES32_AUTOSYNC_FROM_AES2: 1139 + case HDSPM_AES32_AUTOSYNC_FROM_AES3: 1140 + case HDSPM_AES32_AUTOSYNC_FROM_AES4: 1141 + case HDSPM_AES32_AUTOSYNC_FROM_AES5: 1142 + case HDSPM_AES32_AUTOSYNC_FROM_AES6: 1143 + case HDSPM_AES32_AUTOSYNC_FROM_AES7: 1144 + case HDSPM_AES32_AUTOSYNC_FROM_AES8: 1145 + /* Check AES sync and get sample rate */ 1146 + if (hdspm_aes_sync_check(hdspm, syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1)) 1147 + return HDSPM_bit2freq(hdspm_get_aes_sample_rate(hdspm, 1148 + syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1)); 1149 + break; 1274 1150 1275 - if (syncref >= HDSPM_AES32_AUTOSYNC_FROM_AES1 && 1276 - syncref <= HDSPM_AES32_AUTOSYNC_FROM_AES8 && 1277 - status2 & (HDSPM_LockAES >> 1278 - (syncref - HDSPM_AES32_AUTOSYNC_FROM_AES1))) 1279 - return HDSPM_bit2freq((timecode >> (4*(syncref-HDSPM_AES32_AUTOSYNC_FROM_AES1))) & 0xF); 1280 - return 0; 1151 + 1152 + case HDSPM_AES32_AUTOSYNC_FROM_TCO: 1153 + /* Check TCO sync and get sample rate */ 1154 + if (hdspm_tco_sync_check(hdspm)) 1155 + return HDSPM_bit2freq(hdspm_get_tco_sample_rate(hdspm)); 1156 + break; 1157 + default: 1158 + return 0; 1159 + } /* end switch(syncref) */ 1281 1160 break; 1282 1161 1283 1162 case MADIface: ··· 2288 2129 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); 2289 2130 return (status >> 16) & 0xF; 2290 2131 break; 2132 + case AES32: 2133 + status = hdspm_read(hdspm, HDSPM_statusRegister); 2134 + return (status >> HDSPM_AES32_wcFreq_bit) & 0xF; 2291 2135 default: 2292 2136 break; 2293 2137 } ··· 2314 2152 status = hdspm_read(hdspm, HDSPM_RD_STATUS_1); 2315 2153 return (status >> 20) & 0xF; 2316 2154 break; 2155 + case AES32: 2156 + status = hdspm_read(hdspm, HDSPM_statusRegister); 2157 + return (status >> 1) & 0xF; 2317 2158 default: 2318 2159 break; 2319 2160 } ··· 2348 2183 return 0; 2349 2184 } 2350 2185 2186 + /** 2187 + * Returns the AES sample rate class for the given card. 2188 + **/ 2189 + static int hdspm_get_aes_sample_rate(struct hdspm *hdspm, int index) 2190 + { 2191 + int timecode; 2192 + 2193 + switch (hdspm->io_type) { 2194 + case AES32: 2195 + timecode = hdspm_read(hdspm, HDSPM_timecodeRegister); 2196 + return (timecode >> (4*index)) & 0xF; 2197 + break; 2198 + default: 2199 + break; 2200 + } 2201 + return 0; 2202 + } 2351 2203 2352 2204 /** 2353 2205 * Returns the sample rate class for input source <idx> for ··· 2378 2196 } 2379 2197 2380 2198 #define ENUMERATED_CTL_INFO(info, texts) \ 2381 - { \ 2382 - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; \ 2383 - uinfo->count = 1; \ 2384 - uinfo->value.enumerated.items = ARRAY_SIZE(texts); \ 2385 - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) \ 2386 - uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1; \ 2387 - strcpy(uinfo->value.enumerated.name, texts[uinfo->value.enumerated.item]); \ 2388 - } 2199 + snd_ctl_enum_info(info, 1, ARRAY_SIZE(texts), texts) 2389 2200 2201 + 2202 + /* Helper function to query the external sample rate and return the 2203 + * corresponding enum to be returned to userspace. 2204 + */ 2205 + static int hdspm_external_rate_to_enum(struct hdspm *hdspm) 2206 + { 2207 + int rate = hdspm_external_sample_rate(hdspm); 2208 + int i, selected_rate = 0; 2209 + for (i = 1; i < 10; i++) 2210 + if (HDSPM_bit2freq(i) == rate) { 2211 + selected_rate = i; 2212 + break; 2213 + } 2214 + return selected_rate; 2215 + } 2390 2216 2391 2217 2392 2218 #define HDSPM_AUTOSYNC_SAMPLE_RATE(xname, xindex) \ ··· 2460 2270 default: 2461 2271 ucontrol->value.enumerated.item[0] = 2462 2272 hdspm_get_s1_sample_rate(hdspm, 2463 - ucontrol->id.index-1); 2273 + kcontrol->private_value-1); 2464 2274 } 2465 2275 break; 2466 2276 ··· 2479 2289 ucontrol->value.enumerated.item[0] = 2480 2290 hdspm_get_sync_in_sample_rate(hdspm); 2481 2291 break; 2292 + case 11: /* External Rate */ 2293 + ucontrol->value.enumerated.item[0] = 2294 + hdspm_external_rate_to_enum(hdspm); 2295 + break; 2482 2296 default: /* AES1 to AES8 */ 2483 2297 ucontrol->value.enumerated.item[0] = 2484 - hdspm_get_s1_sample_rate(hdspm, 2485 - kcontrol->private_value-1); 2298 + hdspm_get_aes_sample_rate(hdspm, 2299 + kcontrol->private_value - 2300 + HDSPM_AES32_AUTOSYNC_FROM_AES1); 2486 2301 break; 2487 2302 } 2488 2303 break; 2489 2304 2490 2305 case MADI: 2491 2306 case MADIface: 2492 - { 2493 - int rate = hdspm_external_sample_rate(hdspm); 2494 - int i, selected_rate = 0; 2495 - for (i = 1; i < 10; i++) 2496 - if (HDSPM_bit2freq(i) == rate) { 2497 - selected_rate = i; 2498 - break; 2499 - } 2500 - ucontrol->value.enumerated.item[0] = selected_rate; 2501 - } 2307 + ucontrol->value.enumerated.item[0] = 2308 + hdspm_external_rate_to_enum(hdspm); 2502 2309 break; 2503 - 2504 2310 default: 2505 2311 break; 2506 2312 } ··· 2545 2359 **/ 2546 2360 static void hdspm_set_system_clock_mode(struct hdspm *hdspm, int mode) 2547 2361 { 2548 - switch (hdspm->io_type) { 2549 - case AIO: 2550 - case RayDAT: 2551 - if (0 == mode) 2552 - hdspm->settings_register |= HDSPM_c0Master; 2553 - else 2554 - hdspm->settings_register &= ~HDSPM_c0Master; 2555 - 2556 - hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register); 2557 - break; 2558 - 2559 - default: 2560 - if (0 == mode) 2561 - hdspm->control_register |= HDSPM_ClockModeMaster; 2562 - else 2563 - hdspm->control_register &= ~HDSPM_ClockModeMaster; 2564 - 2565 - hdspm_write(hdspm, HDSPM_controlRegister, 2566 - hdspm->control_register); 2567 - } 2362 + hdspm_set_toggle_setting(hdspm, 2363 + (hdspm_is_raydat_or_aio(hdspm)) ? 2364 + HDSPM_c0Master : HDSPM_ClockModeMaster, 2365 + (0 == mode)); 2568 2366 } 2569 2367 2570 2368 2571 2369 static int snd_hdspm_info_system_clock_mode(struct snd_kcontrol *kcontrol, 2572 2370 struct snd_ctl_elem_info *uinfo) 2573 2371 { 2574 - static char *texts[] = { "Master", "AutoSync" }; 2372 + static const char *const texts[] = { "Master", "AutoSync" }; 2575 2373 ENUMERATED_CTL_INFO(uinfo, texts); 2576 2374 return 0; 2577 2375 } ··· 2979 2809 { 2980 2810 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 2981 2811 2982 - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 2983 - uinfo->count = 1; 2984 - uinfo->value.enumerated.items = hdspm->texts_autosync_items; 2985 - 2986 - if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items) 2987 - uinfo->value.enumerated.item = 2988 - uinfo->value.enumerated.items - 1; 2989 - 2990 - strcpy(uinfo->value.enumerated.name, 2991 - hdspm->texts_autosync[uinfo->value.enumerated.item]); 2812 + snd_ctl_enum_info(uinfo, 1, hdspm->texts_autosync_items, hdspm->texts_autosync); 2992 2813 2993 2814 return 0; 2994 2815 } ··· 3034 2873 3035 2874 static int hdspm_autosync_ref(struct hdspm *hdspm) 3036 2875 { 2876 + /* This looks at the autosync selected sync reference */ 3037 2877 if (AES32 == hdspm->io_type) { 3038 - unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); 3039 - unsigned int syncref = 3040 - (status >> HDSPM_AES32_syncref_bit) & 0xF; 3041 - if (syncref == 0) 3042 - return HDSPM_AES32_AUTOSYNC_FROM_WORD; 3043 - if (syncref <= 8) 3044 - return syncref; 3045 - return HDSPM_AES32_AUTOSYNC_FROM_NONE; 3046 - } else if (MADI == hdspm->io_type) { 3047 - /* This looks at the autosync selected sync reference */ 3048 - unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 3049 2878 2879 + unsigned int status = hdspm_read(hdspm, HDSPM_statusRegister); 2880 + unsigned int syncref = (status >> HDSPM_AES32_syncref_bit) & 0xF; 2881 + if ((syncref >= HDSPM_AES32_AUTOSYNC_FROM_WORD) && 2882 + (syncref <= HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN)) { 2883 + return syncref; 2884 + } 2885 + return HDSPM_AES32_AUTOSYNC_FROM_NONE; 2886 + 2887 + } else if (MADI == hdspm->io_type) { 2888 + 2889 + unsigned int status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 3050 2890 switch (status2 & HDSPM_SelSyncRefMask) { 3051 2891 case HDSPM_SelSyncRef_WORD: 3052 2892 return HDSPM_AUTOSYNC_FROM_WORD; ··· 3060 2898 case HDSPM_SelSyncRef_NVALID: 3061 2899 return HDSPM_AUTOSYNC_FROM_NONE; 3062 2900 default: 3063 - return 0; 2901 + return HDSPM_AUTOSYNC_FROM_NONE; 3064 2902 } 3065 2903 3066 2904 } ··· 3074 2912 struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3075 2913 3076 2914 if (AES32 == hdspm->io_type) { 3077 - static char *texts[] = { "WordClock", "AES1", "AES2", "AES3", 3078 - "AES4", "AES5", "AES6", "AES7", "AES8", "None"}; 2915 + static const char *const texts[] = { "WordClock", "AES1", "AES2", "AES3", 2916 + "AES4", "AES5", "AES6", "AES7", "AES8", "TCO", "Sync In", "None"}; 3079 2917 3080 - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3081 - uinfo->count = 1; 3082 - uinfo->value.enumerated.items = 10; 3083 - if (uinfo->value.enumerated.item >= 3084 - uinfo->value.enumerated.items) 3085 - uinfo->value.enumerated.item = 3086 - uinfo->value.enumerated.items - 1; 3087 - strcpy(uinfo->value.enumerated.name, 3088 - texts[uinfo->value.enumerated.item]); 2918 + ENUMERATED_CTL_INFO(uinfo, texts); 3089 2919 } else if (MADI == hdspm->io_type) { 3090 - static char *texts[] = {"Word Clock", "MADI", "TCO", 2920 + static const char *const texts[] = {"Word Clock", "MADI", "TCO", 3091 2921 "Sync In", "None" }; 3092 2922 3093 - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; 3094 - uinfo->count = 1; 3095 - uinfo->value.enumerated.items = 5; 3096 - if (uinfo->value.enumerated.item >= 3097 - uinfo->value.enumerated.items) 3098 - uinfo->value.enumerated.item = 3099 - uinfo->value.enumerated.items - 1; 3100 - strcpy(uinfo->value.enumerated.name, 3101 - texts[uinfo->value.enumerated.item]); 2923 + ENUMERATED_CTL_INFO(uinfo, texts); 3102 2924 } 3103 2925 return 0; 3104 2926 } ··· 3110 2964 static int snd_hdspm_info_tco_video_input_format(struct snd_kcontrol *kcontrol, 3111 2965 struct snd_ctl_elem_info *uinfo) 3112 2966 { 3113 - static char *texts[] = {"No video", "NTSC", "PAL"}; 2967 + static const char *const texts[] = {"No video", "NTSC", "PAL"}; 3114 2968 ENUMERATED_CTL_INFO(uinfo, texts); 3115 2969 return 0; 3116 2970 } ··· 3156 3010 static int snd_hdspm_info_tco_ltc_frames(struct snd_kcontrol *kcontrol, 3157 3011 struct snd_ctl_elem_info *uinfo) 3158 3012 { 3159 - static char *texts[] = {"No lock", "24 fps", "25 fps", "29.97 fps", 3013 + static const char *const texts[] = {"No lock", "24 fps", "25 fps", "29.97 fps", 3160 3014 "30 fps"}; 3161 3015 ENUMERATED_CTL_INFO(uinfo, texts); 3162 3016 return 0; ··· 3173 3027 HDSPM_TCO1_LTC_Format_MSB)) { 3174 3028 case 0: 3175 3029 /* 24 fps */ 3176 - ret = 1; 3030 + ret = fps_24; 3177 3031 break; 3178 3032 case HDSPM_TCO1_LTC_Format_LSB: 3179 3033 /* 25 fps */ 3180 - ret = 2; 3034 + ret = fps_25; 3181 3035 break; 3182 3036 case HDSPM_TCO1_LTC_Format_MSB: 3183 - /* 25 fps */ 3184 - ret = 3; 3037 + /* 29.97 fps */ 3038 + ret = fps_2997; 3185 3039 break; 3186 3040 default: 3187 3041 /* 30 fps */ 3188 - ret = 4; 3042 + ret = fps_30; 3189 3043 break; 3190 3044 } 3191 3045 } ··· 3213 3067 3214 3068 static int hdspm_toggle_setting(struct hdspm *hdspm, u32 regmask) 3215 3069 { 3216 - return (hdspm->control_register & regmask) ? 1 : 0; 3070 + u32 reg; 3071 + 3072 + if (hdspm_is_raydat_or_aio(hdspm)) 3073 + reg = hdspm->settings_register; 3074 + else 3075 + reg = hdspm->control_register; 3076 + 3077 + return (reg & regmask) ? 1 : 0; 3217 3078 } 3218 3079 3219 3080 static int hdspm_set_toggle_setting(struct hdspm *hdspm, u32 regmask, int out) 3220 3081 { 3082 + u32 *reg; 3083 + u32 target_reg; 3084 + 3085 + if (hdspm_is_raydat_or_aio(hdspm)) { 3086 + reg = &(hdspm->settings_register); 3087 + target_reg = HDSPM_WR_SETTINGS; 3088 + } else { 3089 + reg = &(hdspm->control_register); 3090 + target_reg = HDSPM_controlRegister; 3091 + } 3092 + 3221 3093 if (out) 3222 - hdspm->control_register |= regmask; 3094 + *reg |= regmask; 3223 3095 else 3224 - hdspm->control_register &= ~regmask; 3225 - hdspm_write(hdspm, HDSPM_controlRegister, hdspm->control_register); 3096 + *reg &= ~regmask; 3097 + 3098 + hdspm_write(hdspm, target_reg, *reg); 3226 3099 3227 3100 return 0; 3228 3101 } ··· 3306 3141 static int snd_hdspm_info_input_select(struct snd_kcontrol *kcontrol, 3307 3142 struct snd_ctl_elem_info *uinfo) 3308 3143 { 3309 - static char *texts[] = { "optical", "coaxial" }; 3144 + static const char *const texts[] = { "optical", "coaxial" }; 3310 3145 ENUMERATED_CTL_INFO(uinfo, texts); 3311 3146 return 0; 3312 3147 } ··· 3368 3203 static int snd_hdspm_info_ds_wire(struct snd_kcontrol *kcontrol, 3369 3204 struct snd_ctl_elem_info *uinfo) 3370 3205 { 3371 - static char *texts[] = { "Single", "Double" }; 3206 + static const char *const texts[] = { "Single", "Double" }; 3372 3207 ENUMERATED_CTL_INFO(uinfo, texts); 3373 3208 return 0; 3374 3209 } ··· 3441 3276 static int snd_hdspm_info_qs_wire(struct snd_kcontrol *kcontrol, 3442 3277 struct snd_ctl_elem_info *uinfo) 3443 3278 { 3444 - static char *texts[] = { "Single", "Double", "Quad" }; 3279 + static const char *const texts[] = { "Single", "Double", "Quad" }; 3445 3280 ENUMERATED_CTL_INFO(uinfo, texts); 3446 3281 return 0; 3447 3282 } ··· 3474 3309 spin_lock_irq(&hdspm->lock); 3475 3310 change = val != hdspm_qs_wire(hdspm); 3476 3311 hdspm_set_qs_wire(hdspm, val); 3312 + spin_unlock_irq(&hdspm->lock); 3313 + return change; 3314 + } 3315 + 3316 + #define HDSPM_CONTROL_TRISTATE(xname, xindex) \ 3317 + { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 3318 + .name = xname, \ 3319 + .private_value = xindex, \ 3320 + .info = snd_hdspm_info_tristate, \ 3321 + .get = snd_hdspm_get_tristate, \ 3322 + .put = snd_hdspm_put_tristate \ 3323 + } 3324 + 3325 + static int hdspm_tristate(struct hdspm *hdspm, u32 regmask) 3326 + { 3327 + u32 reg = hdspm->settings_register & (regmask * 3); 3328 + return reg / regmask; 3329 + } 3330 + 3331 + static int hdspm_set_tristate(struct hdspm *hdspm, int mode, u32 regmask) 3332 + { 3333 + hdspm->settings_register &= ~(regmask * 3); 3334 + hdspm->settings_register |= (regmask * mode); 3335 + hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register); 3336 + 3337 + return 0; 3338 + } 3339 + 3340 + static int snd_hdspm_info_tristate(struct snd_kcontrol *kcontrol, 3341 + struct snd_ctl_elem_info *uinfo) 3342 + { 3343 + u32 regmask = kcontrol->private_value; 3344 + 3345 + static const char *const texts_spdif[] = { "Optical", "Coaxial", "Internal" }; 3346 + static const char *const texts_levels[] = { "Hi Gain", "+4 dBu", "-10 dBV" }; 3347 + 3348 + switch (regmask) { 3349 + case HDSPM_c0_Input0: 3350 + ENUMERATED_CTL_INFO(uinfo, texts_spdif); 3351 + break; 3352 + default: 3353 + ENUMERATED_CTL_INFO(uinfo, texts_levels); 3354 + break; 3355 + } 3356 + return 0; 3357 + } 3358 + 3359 + static int snd_hdspm_get_tristate(struct snd_kcontrol *kcontrol, 3360 + struct snd_ctl_elem_value *ucontrol) 3361 + { 3362 + struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3363 + u32 regmask = kcontrol->private_value; 3364 + 3365 + spin_lock_irq(&hdspm->lock); 3366 + ucontrol->value.enumerated.item[0] = hdspm_tristate(hdspm, regmask); 3367 + spin_unlock_irq(&hdspm->lock); 3368 + return 0; 3369 + } 3370 + 3371 + static int snd_hdspm_put_tristate(struct snd_kcontrol *kcontrol, 3372 + struct snd_ctl_elem_value *ucontrol) 3373 + { 3374 + struct hdspm *hdspm = snd_kcontrol_chip(kcontrol); 3375 + u32 regmask = kcontrol->private_value; 3376 + int change; 3377 + int val; 3378 + 3379 + if (!snd_hdspm_use_is_exclusive(hdspm)) 3380 + return -EBUSY; 3381 + val = ucontrol->value.integer.value[0]; 3382 + if (val < 0) 3383 + val = 0; 3384 + if (val > 2) 3385 + val = 2; 3386 + 3387 + spin_lock_irq(&hdspm->lock); 3388 + change = val != hdspm_tristate(hdspm, regmask); 3389 + hdspm_set_tristate(hdspm, val, regmask); 3477 3390 spin_unlock_irq(&hdspm->lock); 3478 3391 return change; 3479 3392 } ··· 3595 3352 static int snd_hdspm_info_madi_speedmode(struct snd_kcontrol *kcontrol, 3596 3353 struct snd_ctl_elem_info *uinfo) 3597 3354 { 3598 - static char *texts[] = { "Single", "Double", "Quad" }; 3355 + static const char *const texts[] = { "Single", "Double", "Quad" }; 3599 3356 ENUMERATED_CTL_INFO(uinfo, texts); 3600 3357 return 0; 3601 3358 } ··· 3830 3587 static int snd_hdspm_info_sync_check(struct snd_kcontrol *kcontrol, 3831 3588 struct snd_ctl_elem_info *uinfo) 3832 3589 { 3833 - static char *texts[] = { "No Lock", "Lock", "Sync", "N/A" }; 3590 + static const char *const texts[] = { "No Lock", "Lock", "Sync", "N/A" }; 3834 3591 ENUMERATED_CTL_INFO(uinfo, texts); 3835 3592 return 0; 3836 3593 } ··· 3838 3595 static int snd_hdspm_tco_info_lock_check(struct snd_kcontrol *kcontrol, 3839 3596 struct snd_ctl_elem_info *uinfo) 3840 3597 { 3841 - static char *texts[] = { "No Lock", "Lock" }; 3598 + static const char *const texts[] = { "No Lock", "Lock" }; 3842 3599 ENUMERATED_CTL_INFO(uinfo, texts); 3843 3600 return 0; 3844 3601 } ··· 3988 3745 if (hdspm->tco) { 3989 3746 switch (hdspm->io_type) { 3990 3747 case MADI: 3748 + status = hdspm_read(hdspm, HDSPM_statusRegister); 3749 + if (status & HDSPM_tcoLockMadi) { 3750 + if (status & HDSPM_tcoSync) 3751 + return 2; 3752 + else 3753 + return 1; 3754 + } 3755 + return 0; 3756 + break; 3991 3757 case AES32: 3992 3758 status = hdspm_read(hdspm, HDSPM_statusRegister); 3993 - if (status & HDSPM_tcoLock) { 3759 + if (status & HDSPM_tcoLockAes) { 3994 3760 if (status & HDSPM_tcoSync) 3995 3761 return 2; 3996 3762 else ··· 4059 3807 case 5: /* SYNC IN */ 4060 3808 val = hdspm_sync_in_sync_check(hdspm); break; 4061 3809 default: 4062 - val = hdspm_s1_sync_check(hdspm, ucontrol->id.index-1); 3810 + val = hdspm_s1_sync_check(hdspm, 3811 + kcontrol->private_value-1); 4063 3812 } 4064 3813 break; 4065 3814 ··· 4228 3975 static int snd_hdspm_info_tco_sample_rate(struct snd_kcontrol *kcontrol, 4229 3976 struct snd_ctl_elem_info *uinfo) 4230 3977 { 4231 - static char *texts[] = { "44.1 kHz", "48 kHz" }; 3978 + /* TODO freq from app could be supported here, see tco->samplerate */ 3979 + static const char *const texts[] = { "44.1 kHz", "48 kHz" }; 4232 3980 ENUMERATED_CTL_INFO(uinfo, texts); 4233 3981 return 0; 4234 3982 } ··· 4275 4021 static int snd_hdspm_info_tco_pull(struct snd_kcontrol *kcontrol, 4276 4022 struct snd_ctl_elem_info *uinfo) 4277 4023 { 4278 - static char *texts[] = { "0", "+ 0.1 %", "- 0.1 %", "+ 4 %", "- 4 %" }; 4024 + static const char *const texts[] = { "0", "+ 0.1 %", "- 0.1 %", 4025 + "+ 4 %", "- 4 %" }; 4279 4026 ENUMERATED_CTL_INFO(uinfo, texts); 4280 4027 return 0; 4281 4028 } ··· 4321 4066 static int snd_hdspm_info_tco_wck_conversion(struct snd_kcontrol *kcontrol, 4322 4067 struct snd_ctl_elem_info *uinfo) 4323 4068 { 4324 - static char *texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" }; 4069 + static const char *const texts[] = { "1:1", "44.1 -> 48", "48 -> 44.1" }; 4325 4070 ENUMERATED_CTL_INFO(uinfo, texts); 4326 4071 return 0; 4327 4072 } ··· 4367 4112 static int snd_hdspm_info_tco_frame_rate(struct snd_kcontrol *kcontrol, 4368 4113 struct snd_ctl_elem_info *uinfo) 4369 4114 { 4370 - static char *texts[] = { "24 fps", "25 fps", "29.97fps", 4115 + static const char *const texts[] = { "24 fps", "25 fps", "29.97fps", 4371 4116 "29.97 dfps", "30 fps", "30 dfps" }; 4372 4117 ENUMERATED_CTL_INFO(uinfo, texts); 4373 4118 return 0; ··· 4414 4159 static int snd_hdspm_info_tco_sync_source(struct snd_kcontrol *kcontrol, 4415 4160 struct snd_ctl_elem_info *uinfo) 4416 4161 { 4417 - static char *texts[] = { "LTC", "Video", "WCK" }; 4162 + static const char *const texts[] = { "LTC", "Video", "WCK" }; 4418 4163 ENUMERATED_CTL_INFO(uinfo, texts); 4419 4164 return 0; 4420 4165 } ··· 4539 4284 HDSPM_INTERNAL_CLOCK("Internal Clock", 0), 4540 4285 HDSPM_SYSTEM_CLOCK_MODE("System Clock Mode", 0), 4541 4286 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), 4542 - HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), 4543 4287 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 4544 4288 HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), 4545 4289 HDSPM_SYNC_CHECK("WC SyncCheck", 0), ··· 4552 4298 HDSPM_AUTOSYNC_SAMPLE_RATE("SPDIF Frequency", 2), 4553 4299 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT Frequency", 3), 4554 4300 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 4), 4555 - HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5) 4301 + HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 5), 4302 + HDSPM_CONTROL_TRISTATE("S/PDIF Input", HDSPM_c0_Input0), 4303 + HDSPM_TOGGLE_SETTING("S/PDIF Out Optical", HDSPM_c0_Spdif_Opt), 4304 + HDSPM_TOGGLE_SETTING("S/PDIF Out Professional", HDSPM_c0_Pro), 4305 + HDSPM_TOGGLE_SETTING("ADAT internal (AEB/TEB)", HDSPM_c0_AEB1), 4306 + HDSPM_TOGGLE_SETTING("XLR Breakout Cable", HDSPM_c0_Sym6db), 4307 + HDSPM_TOGGLE_SETTING("Single Speed WordClock Out", HDSPM_c0_Wck48), 4308 + HDSPM_CONTROL_TRISTATE("Input Level", HDSPM_c0_AD_GAIN0), 4309 + HDSPM_CONTROL_TRISTATE("Output Level", HDSPM_c0_DA_GAIN0), 4310 + HDSPM_CONTROL_TRISTATE("Phones Level", HDSPM_c0_PH_GAIN0) 4556 4311 4557 4312 /* 4558 4313 HDSPM_INPUT_SELECT("Input Select", 0), ··· 4598 4335 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT3 Frequency", 5), 4599 4336 HDSPM_AUTOSYNC_SAMPLE_RATE("ADAT4 Frequency", 6), 4600 4337 HDSPM_AUTOSYNC_SAMPLE_RATE("TCO Frequency", 7), 4601 - HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8) 4338 + HDSPM_AUTOSYNC_SAMPLE_RATE("SYNC IN Frequency", 8), 4339 + HDSPM_TOGGLE_SETTING("S/PDIF Out Professional", HDSPM_c0_Pro), 4340 + HDSPM_TOGGLE_SETTING("Single Speed WordClock Out", HDSPM_c0_Wck48) 4602 4341 }; 4603 4342 4604 4343 static struct snd_kcontrol_new snd_hdspm_controls_aes32[] = { ··· 4610 4345 HDSPM_PREF_SYNC_REF("Preferred Sync Reference", 0), 4611 4346 HDSPM_AUTOSYNC_REF("AutoSync Reference", 0), 4612 4347 HDSPM_SYSTEM_SAMPLE_RATE("System Sample Rate", 0), 4613 - HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 0), 4348 + HDSPM_AUTOSYNC_SAMPLE_RATE("External Rate", 11), 4614 4349 HDSPM_SYNC_CHECK("WC Sync Check", 0), 4615 4350 HDSPM_SYNC_CHECK("AES1 Sync Check", 1), 4616 4351 HDSPM_SYNC_CHECK("AES2 Sync Check", 2), ··· 4766 4501 ------------------------------------------------------------*/ 4767 4502 4768 4503 static void 4769 - snd_hdspm_proc_read_madi(struct snd_info_entry * entry, 4770 - struct snd_info_buffer *buffer) 4504 + snd_hdspm_proc_read_tco(struct snd_info_entry *entry, 4505 + struct snd_info_buffer *buffer) 4771 4506 { 4772 4507 struct hdspm *hdspm = entry->private_data; 4773 - unsigned int status, status2, control, freq; 4774 - 4775 - char *pref_sync_ref; 4776 - char *autosync_ref; 4777 - char *system_clock_mode; 4778 - char *insel; 4779 - int x, x2; 4780 - 4781 - /* TCO stuff */ 4508 + unsigned int status, control; 4782 4509 int a, ltc, frames, seconds, minutes, hours; 4783 4510 unsigned int period; 4784 4511 u64 freq_const = 0; 4785 4512 u32 rate; 4786 4513 4514 + snd_iprintf(buffer, "--- TCO ---\n"); 4515 + 4787 4516 status = hdspm_read(hdspm, HDSPM_statusRegister); 4788 - status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 4789 4517 control = hdspm->control_register; 4790 - freq = hdspm_read(hdspm, HDSPM_timecodeRegister); 4791 4518 4792 - snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n", 4793 - hdspm->card_name, hdspm->card->number + 1, 4794 - hdspm->firmware_rev, 4795 - (status2 & HDSPM_version0) | 4796 - (status2 & HDSPM_version1) | (status2 & 4797 - HDSPM_version2)); 4798 4519 4799 - snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n", 4800 - (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF, 4801 - hdspm->serial); 4802 - 4803 - snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n", 4804 - hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase); 4805 - 4806 - snd_iprintf(buffer, "--- System ---\n"); 4807 - 4808 - snd_iprintf(buffer, 4809 - "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n", 4810 - status & HDSPM_audioIRQPending, 4811 - (status & HDSPM_midi0IRQPending) ? 1 : 0, 4812 - (status & HDSPM_midi1IRQPending) ? 1 : 0, 4813 - hdspm->irq_count); 4814 - snd_iprintf(buffer, 4815 - "HW pointer: id = %d, rawptr = %d (%d->%d) " 4816 - "estimated= %ld (bytes)\n", 4817 - ((status & HDSPM_BufferID) ? 1 : 0), 4818 - (status & HDSPM_BufferPositionMask), 4819 - (status & HDSPM_BufferPositionMask) % 4820 - (2 * (int)hdspm->period_bytes), 4821 - ((status & HDSPM_BufferPositionMask) - 64) % 4822 - (2 * (int)hdspm->period_bytes), 4823 - (long) hdspm_hw_pointer(hdspm) * 4); 4824 - 4825 - snd_iprintf(buffer, 4826 - "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n", 4827 - hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF, 4828 - hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF, 4829 - hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, 4830 - hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); 4831 - snd_iprintf(buffer, 4832 - "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n", 4833 - hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF, 4834 - hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF); 4835 - snd_iprintf(buffer, 4836 - "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, " 4837 - "status2=0x%x\n", 4838 - hdspm->control_register, hdspm->control2_register, 4839 - status, status2); 4840 4520 if (status & HDSPM_tco_detect) { 4841 4521 snd_iprintf(buffer, "TCO module detected.\n"); 4842 4522 a = hdspm_read(hdspm, HDSPM_RD_TCO+4); ··· 4875 4665 } else { 4876 4666 snd_iprintf(buffer, "No TCO module detected.\n"); 4877 4667 } 4668 + } 4669 + 4670 + static void 4671 + snd_hdspm_proc_read_madi(struct snd_info_entry *entry, 4672 + struct snd_info_buffer *buffer) 4673 + { 4674 + struct hdspm *hdspm = entry->private_data; 4675 + unsigned int status, status2, control, freq; 4676 + 4677 + char *pref_sync_ref; 4678 + char *autosync_ref; 4679 + char *system_clock_mode; 4680 + char *insel; 4681 + int x, x2; 4682 + 4683 + status = hdspm_read(hdspm, HDSPM_statusRegister); 4684 + status2 = hdspm_read(hdspm, HDSPM_statusRegister2); 4685 + control = hdspm->control_register; 4686 + freq = hdspm_read(hdspm, HDSPM_timecodeRegister); 4687 + 4688 + snd_iprintf(buffer, "%s (Card #%d) Rev.%x Status2first3bits: %x\n", 4689 + hdspm->card_name, hdspm->card->number + 1, 4690 + hdspm->firmware_rev, 4691 + (status2 & HDSPM_version0) | 4692 + (status2 & HDSPM_version1) | (status2 & 4693 + HDSPM_version2)); 4694 + 4695 + snd_iprintf(buffer, "HW Serial: 0x%06x%06x\n", 4696 + (hdspm_read(hdspm, HDSPM_midiStatusIn1)>>8) & 0xFFFFFF, 4697 + hdspm->serial); 4698 + 4699 + snd_iprintf(buffer, "IRQ: %d Registers bus: 0x%lx VM: 0x%lx\n", 4700 + hdspm->irq, hdspm->port, (unsigned long)hdspm->iobase); 4701 + 4702 + snd_iprintf(buffer, "--- System ---\n"); 4703 + 4704 + snd_iprintf(buffer, 4705 + "IRQ Pending: Audio=%d, MIDI0=%d, MIDI1=%d, IRQcount=%d\n", 4706 + status & HDSPM_audioIRQPending, 4707 + (status & HDSPM_midi0IRQPending) ? 1 : 0, 4708 + (status & HDSPM_midi1IRQPending) ? 1 : 0, 4709 + hdspm->irq_count); 4710 + snd_iprintf(buffer, 4711 + "HW pointer: id = %d, rawptr = %d (%d->%d) " 4712 + "estimated= %ld (bytes)\n", 4713 + ((status & HDSPM_BufferID) ? 1 : 0), 4714 + (status & HDSPM_BufferPositionMask), 4715 + (status & HDSPM_BufferPositionMask) % 4716 + (2 * (int)hdspm->period_bytes), 4717 + ((status & HDSPM_BufferPositionMask) - 64) % 4718 + (2 * (int)hdspm->period_bytes), 4719 + (long) hdspm_hw_pointer(hdspm) * 4); 4720 + 4721 + snd_iprintf(buffer, 4722 + "MIDI FIFO: Out1=0x%x, Out2=0x%x, In1=0x%x, In2=0x%x \n", 4723 + hdspm_read(hdspm, HDSPM_midiStatusOut0) & 0xFF, 4724 + hdspm_read(hdspm, HDSPM_midiStatusOut1) & 0xFF, 4725 + hdspm_read(hdspm, HDSPM_midiStatusIn0) & 0xFF, 4726 + hdspm_read(hdspm, HDSPM_midiStatusIn1) & 0xFF); 4727 + snd_iprintf(buffer, 4728 + "MIDIoverMADI FIFO: In=0x%x, Out=0x%x \n", 4729 + hdspm_read(hdspm, HDSPM_midiStatusIn2) & 0xFF, 4730 + hdspm_read(hdspm, HDSPM_midiStatusOut2) & 0xFF); 4731 + snd_iprintf(buffer, 4732 + "Register: ctrl1=0x%x, ctrl2=0x%x, status1=0x%x, " 4733 + "status2=0x%x\n", 4734 + hdspm->control_register, hdspm->control2_register, 4735 + status, status2); 4736 + 4878 4737 4879 4738 snd_iprintf(buffer, "--- Settings ---\n"); 4880 4739 ··· 5046 4767 (status & HDSPM_AB_int) ? "Coax" : "Optical", 5047 4768 (status & HDSPM_RX_64ch) ? "64 channels" : 5048 4769 "56 channels"); 4770 + 4771 + /* call readout function for TCO specific status */ 4772 + snd_hdspm_proc_read_tco(entry, buffer); 5049 4773 5050 4774 snd_iprintf(buffer, "\n"); 5051 4775 } ··· 5191 4909 autosync_ref = "AES7"; break; 5192 4910 case HDSPM_AES32_AUTOSYNC_FROM_AES8: 5193 4911 autosync_ref = "AES8"; break; 4912 + case HDSPM_AES32_AUTOSYNC_FROM_TCO: 4913 + autosync_ref = "TCO"; break; 4914 + case HDSPM_AES32_AUTOSYNC_FROM_SYNC_IN: 4915 + autosync_ref = "Sync In"; break; 5194 4916 default: 5195 4917 autosync_ref = "---"; break; 5196 4918 } 5197 4919 snd_iprintf(buffer, "AutoSync ref = %s\n", autosync_ref); 4920 + 4921 + /* call readout function for TCO specific status */ 4922 + snd_hdspm_proc_read_tco(entry, buffer); 5198 4923 5199 4924 snd_iprintf(buffer, "\n"); 5200 4925 } ··· 5386 5097 5387 5098 case AES32: 5388 5099 hdspm->control_register = 5389 - HDSPM_ClockModeMaster | /* Master Cloack Mode on */ 5100 + HDSPM_ClockModeMaster | /* Master Clock Mode on */ 5390 5101 hdspm_encode_latency(7) | /* latency max=8192samples */ 5391 5102 HDSPM_SyncRef0 | /* AES1 is syncclock */ 5392 5103 HDSPM_LineOut | /* Analog output in */ ··· 5412 5123 5413 5124 all_in_all_mixer(hdspm, 0 * UNITY_GAIN); 5414 5125 5415 - if (hdspm->io_type == AIO || hdspm->io_type == RayDAT) { 5126 + if (hdspm_is_raydat_or_aio(hdspm)) 5416 5127 hdspm_write(hdspm, HDSPM_WR_SETTINGS, hdspm->settings_register); 5417 - } 5418 5128 5419 5129 /* set a default rate so that the channel map is set up. */ 5420 5130 hdspm_set_rate(hdspm, 48000, 1); ··· 5657 5369 params_rate(params), params_channels(params), 5658 5370 params_buffer_size(params)); 5659 5371 */ 5372 + 5373 + 5374 + /* For AES cards, the float format bit is the same as the 5375 + * preferred sync reference. Since we don't want to break 5376 + * sync settings, we have to skip the remaining part of this 5377 + * function. 5378 + */ 5379 + if (hdspm->io_type == AES32) { 5380 + return 0; 5381 + } 5660 5382 5661 5383 5662 5384 /* Switch to native float format if requested */ ··· 6311 6013 ltc.format = fps_2997; 6312 6014 break; 6313 6015 default: 6314 - ltc.format = 30; 6016 + ltc.format = fps_30; 6315 6017 break; 6316 6018 } 6317 6019 if (i & HDSPM_TCO1_set_drop_frame_flag) { ··· 6777 6479 break; 6778 6480 6779 6481 case AIO: 6780 - if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) { 6781 - snd_printk(KERN_INFO "HDSPM: AEB input board found, but not supported\n"); 6782 - } 6783 - 6784 6482 hdspm->ss_in_channels = AIO_IN_SS_CHANNELS; 6785 6483 hdspm->ds_in_channels = AIO_IN_DS_CHANNELS; 6786 6484 hdspm->qs_in_channels = AIO_IN_QS_CHANNELS; 6787 6485 hdspm->ss_out_channels = AIO_OUT_SS_CHANNELS; 6788 6486 hdspm->ds_out_channels = AIO_OUT_DS_CHANNELS; 6789 6487 hdspm->qs_out_channels = AIO_OUT_QS_CHANNELS; 6488 + 6489 + if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBI_D)) { 6490 + snd_printk(KERN_INFO "HDSPM: AEB input board found\n"); 6491 + hdspm->ss_in_channels += 4; 6492 + hdspm->ds_in_channels += 4; 6493 + hdspm->qs_in_channels += 4; 6494 + } 6495 + 6496 + if (0 == (hdspm_read(hdspm, HDSPM_statusRegister2) & HDSPM_s2_AEBO_D)) { 6497 + snd_printk(KERN_INFO "HDSPM: AEB output board found\n"); 6498 + hdspm->ss_out_channels += 4; 6499 + hdspm->ds_out_channels += 4; 6500 + hdspm->qs_out_channels += 4; 6501 + } 6790 6502 6791 6503 hdspm->channel_map_out_ss = channel_map_aio_out_ss; 6792 6504 hdspm->channel_map_out_ds = channel_map_aio_out_ds; ··· 6866 6558 break; 6867 6559 6868 6560 case MADI: 6561 + case AES32: 6869 6562 if (hdspm_read(hdspm, HDSPM_statusRegister) & HDSPM_tco_detect) { 6870 6563 hdspm->midiPorts++; 6871 6564 hdspm->tco = kzalloc(sizeof(struct hdspm_tco), ··· 6874 6565 if (NULL != hdspm->tco) { 6875 6566 hdspm_tco_write(hdspm); 6876 6567 } 6877 - snd_printk(KERN_INFO "HDSPM: MADI TCO module found\n"); 6568 + snd_printk(KERN_INFO "HDSPM: MADI/AES TCO module found\n"); 6878 6569 } else { 6879 6570 hdspm->tco = NULL; 6880 6571 } ··· 6889 6580 case AES32: 6890 6581 if (hdspm->tco) { 6891 6582 hdspm->texts_autosync = texts_autosync_aes_tco; 6892 - hdspm->texts_autosync_items = 10; 6583 + hdspm->texts_autosync_items = 6584 + ARRAY_SIZE(texts_autosync_aes_tco); 6893 6585 } else { 6894 6586 hdspm->texts_autosync = texts_autosync_aes; 6895 - hdspm->texts_autosync_items = 9; 6587 + hdspm->texts_autosync_items = 6588 + ARRAY_SIZE(texts_autosync_aes); 6896 6589 } 6897 6590 break; 6898 6591
-2
sound/soc/cirrus/ep93xx-i2s.c
··· 408 408 return 0; 409 409 410 410 fail_put_lrclk: 411 - dev_set_drvdata(&pdev->dev, NULL); 412 411 clk_put(info->lrclk); 413 412 fail_put_sclk: 414 413 clk_put(info->sclk); ··· 422 423 struct ep93xx_i2s_info *info = dev_get_drvdata(&pdev->dev); 423 424 424 425 snd_soc_unregister_component(&pdev->dev); 425 - dev_set_drvdata(&pdev->dev, NULL); 426 426 clk_put(info->lrclk); 427 427 clk_put(info->sclk); 428 428 clk_put(info->mclk);
+4 -13
sound/soc/codecs/dmic.c
··· 50 50 {"DMIC AIF", NULL, "DMic"}, 51 51 }; 52 52 53 - static 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 - 65 53 static 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 69 60 static int dmic_dev_probe(struct platform_device *pdev)
+163 -54
sound/soc/codecs/rt5640.c
··· 50 50 51 51 static struct reg_default init_list[] = { 52 52 {RT5640_PR_BASE + 0x3d, 0x3600}, 53 - {RT5640_PR_BASE + 0x1c, 0x0D21}, 54 - {RT5640_PR_BASE + 0x1b, 0x0000}, 55 53 {RT5640_PR_BASE + 0x12, 0x0aa8}, 56 54 {RT5640_PR_BASE + 0x14, 0x0aaa}, 57 55 {RT5640_PR_BASE + 0x20, 0x6110}, ··· 382 384 383 385 static const struct snd_kcontrol_new rt5640_snd_controls[] = { 384 386 /* Speaker Output Volume */ 385 - SOC_DOUBLE("Speaker Playback Switch", RT5640_SPK_VOL, 386 - RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1), 387 387 SOC_DOUBLE("Speaker Channel Switch", RT5640_SPK_VOL, 388 388 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), 389 389 SOC_DOUBLE_TLV("Speaker Playback Volume", RT5640_SPK_VOL, 390 390 RT5640_L_VOL_SFT, RT5640_R_VOL_SFT, 39, 1, out_vol_tlv), 391 391 /* Headphone Output Volume */ 392 - SOC_DOUBLE("HP Playback Switch", RT5640_HP_VOL, 393 - RT5640_L_MUTE_SFT, RT5640_R_MUTE_SFT, 1, 1), 394 392 SOC_DOUBLE("HP Channel Switch", RT5640_HP_VOL, 395 393 RT5640_VOL_L_SFT, RT5640_VOL_R_SFT, 1, 1), 396 394 SOC_DOUBLE_TLV("HP Playback Volume", RT5640_HP_VOL, ··· 731 737 RT5640_M_BST1_MM_SFT, 1, 1), 732 738 }; 733 739 740 + static const struct snd_kcontrol_new spk_l_enable_control = 741 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_SPK_VOL, 742 + RT5640_L_MUTE_SFT, 1, 1); 743 + 744 + static const struct snd_kcontrol_new spk_r_enable_control = 745 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_SPK_VOL, 746 + RT5640_R_MUTE_SFT, 1, 1); 747 + 748 + static const struct snd_kcontrol_new hp_l_enable_control = 749 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_HP_VOL, 750 + RT5640_L_MUTE_SFT, 1, 1); 751 + 752 + static const struct snd_kcontrol_new hp_r_enable_control = 753 + SOC_DAPM_SINGLE_AUTODISABLE("Switch", RT5640_HP_VOL, 754 + RT5640_R_MUTE_SFT, 1, 1); 755 + 734 756 /* Stereo ADC source */ 735 757 static const char * const rt5640_stereo_adc1_src[] = { 736 758 "DIG MIX", "ADC" ··· 878 868 static const struct snd_kcontrol_new rt5640_sdi_mux = 879 869 SOC_DAPM_ENUM("SDI select", rt5640_sdi_sel_enum); 880 870 881 - static int spk_event(struct snd_soc_dapm_widget *w, 882 - struct snd_kcontrol *kcontrol, int event) 883 - { 884 - struct snd_soc_codec *codec = w->codec; 885 - struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); 886 - 887 - switch (event) { 888 - case SND_SOC_DAPM_POST_PMU: 889 - regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1, 890 - 0x0001, 0x0001); 891 - regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c, 892 - 0xf000, 0xf000); 893 - break; 894 - 895 - case SND_SOC_DAPM_PRE_PMD: 896 - regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 0x1c, 897 - 0xf000, 0x0000); 898 - regmap_update_bits(rt5640->regmap, RT5640_PWR_DIG1, 899 - 0x0001, 0x0000); 900 - break; 901 - 902 - default: 903 - return 0; 904 - } 905 - return 0; 906 - } 907 - 908 871 static int rt5640_set_dmic1_event(struct snd_soc_dapm_widget *w, 909 872 struct snd_kcontrol *kcontrol, int event) 910 873 { ··· 917 934 RT5640_DMIC_2_DP_MASK, 918 935 RT5640_DMIC_2L_LH_FALLING | RT5640_DMIC_2R_LH_RISING | 919 936 RT5640_DMIC_2_DP_IN1N); 937 + break; 938 + 939 + default: 940 + return 0; 941 + } 942 + 943 + return 0; 944 + } 945 + 946 + void hp_amp_power_on(struct snd_soc_codec *codec) 947 + { 948 + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); 949 + 950 + /* depop parameters */ 951 + regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 952 + RT5640_CHPUMP_INT_REG1, 0x0700, 0x0200); 953 + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2, 954 + RT5640_DEPOP_MASK, RT5640_DEPOP_MAN); 955 + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1, 956 + RT5640_HP_CP_MASK | RT5640_HP_SG_MASK | RT5640_HP_CB_MASK, 957 + RT5640_HP_CP_PU | RT5640_HP_SG_DIS | RT5640_HP_CB_PU); 958 + regmap_write(rt5640->regmap, RT5640_PR_BASE + RT5640_HP_DCC_INT1, 959 + 0x9f00); 960 + /* headphone amp power on */ 961 + regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1, 962 + RT5640_PWR_FV1 | RT5640_PWR_FV2, 0); 963 + regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1, 964 + RT5640_PWR_HA, 965 + RT5640_PWR_HA); 966 + usleep_range(10000, 15000); 967 + regmap_update_bits(rt5640->regmap, RT5640_PWR_ANLG1, 968 + RT5640_PWR_FV1 | RT5640_PWR_FV2 , 969 + RT5640_PWR_FV1 | RT5640_PWR_FV2); 970 + } 971 + 972 + static void rt5640_pmu_depop(struct snd_soc_codec *codec) 973 + { 974 + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); 975 + 976 + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M2, 977 + RT5640_DEPOP_MASK | RT5640_DIG_DP_MASK, 978 + RT5640_DEPOP_AUTO | RT5640_DIG_DP_EN); 979 + regmap_update_bits(rt5640->regmap, RT5640_CHARGE_PUMP, 980 + RT5640_PM_HP_MASK, RT5640_PM_HP_HV); 981 + 982 + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M3, 983 + RT5640_CP_FQ1_MASK | RT5640_CP_FQ2_MASK | RT5640_CP_FQ3_MASK, 984 + (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ1_SFT) | 985 + (RT5640_CP_FQ_12_KHZ << RT5640_CP_FQ2_SFT) | 986 + (RT5640_CP_FQ_192_KHZ << RT5640_CP_FQ3_SFT)); 987 + 988 + regmap_write(rt5640->regmap, RT5640_PR_BASE + 989 + RT5640_MAMP_INT_REG2, 0x1c00); 990 + regmap_update_bits(rt5640->regmap, RT5640_DEPOP_M1, 991 + RT5640_HP_CP_MASK | RT5640_HP_SG_MASK, 992 + RT5640_HP_CP_PD | RT5640_HP_SG_EN); 993 + regmap_update_bits(rt5640->regmap, RT5640_PR_BASE + 994 + RT5640_CHPUMP_INT_REG1, 0x0700, 0x0400); 995 + } 996 + 997 + static int rt5640_hp_event(struct snd_soc_dapm_widget *w, 998 + struct snd_kcontrol *kcontrol, int event) 999 + { 1000 + struct snd_soc_codec *codec = w->codec; 1001 + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); 1002 + 1003 + switch (event) { 1004 + case SND_SOC_DAPM_POST_PMU: 1005 + rt5640_pmu_depop(codec); 1006 + rt5640->hp_mute = 0; 1007 + break; 1008 + 1009 + case SND_SOC_DAPM_PRE_PMD: 1010 + rt5640->hp_mute = 1; 1011 + usleep_range(70000, 75000); 1012 + break; 1013 + 1014 + default: 1015 + return 0; 1016 + } 1017 + 1018 + return 0; 1019 + } 1020 + 1021 + static int rt5640_hp_power_event(struct snd_soc_dapm_widget *w, 1022 + struct snd_kcontrol *kcontrol, int event) 1023 + { 1024 + struct snd_soc_codec *codec = w->codec; 1025 + 1026 + switch (event) { 1027 + case SND_SOC_DAPM_POST_PMU: 1028 + hp_amp_power_on(codec); 1029 + break; 1030 + default: 1031 + return 0; 1032 + } 1033 + 1034 + return 0; 1035 + } 1036 + 1037 + static int rt5640_hp_post_event(struct snd_soc_dapm_widget *w, 1038 + struct snd_kcontrol *kcontrol, int event) 1039 + { 1040 + struct snd_soc_codec *codec = w->codec; 1041 + struct rt5640_priv *rt5640 = snd_soc_codec_get_drvdata(codec); 1042 + 1043 + switch (event) { 1044 + case SND_SOC_DAPM_POST_PMU: 1045 + if (!rt5640->hp_mute) 1046 + usleep_range(80000, 85000); 1047 + 920 1048 break; 921 1049 922 1050 default: ··· 1226 1132 rt5640_mono_mix, ARRAY_SIZE(rt5640_mono_mix)), 1227 1133 SND_SOC_DAPM_SUPPLY("Improve MONO Amp Drv", RT5640_PWR_ANLG1, 1228 1134 RT5640_PWR_MA_BIT, 0, NULL, 0), 1229 - SND_SOC_DAPM_SUPPLY("Improve HP Amp Drv", RT5640_PWR_ANLG1, 1230 - SND_SOC_NOPM, 0, NULL, 0), 1231 - SND_SOC_DAPM_PGA("HP L Amp", RT5640_PWR_ANLG1, 1135 + SND_SOC_DAPM_SUPPLY_S("Improve HP Amp Drv", 1, SND_SOC_NOPM, 1136 + 0, 0, rt5640_hp_power_event, SND_SOC_DAPM_POST_PMU), 1137 + SND_SOC_DAPM_PGA_S("HP Amp", 1, SND_SOC_NOPM, 0, 0, 1138 + rt5640_hp_event, 1139 + SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1140 + SND_SOC_DAPM_SUPPLY("HP L Amp", RT5640_PWR_ANLG1, 1232 1141 RT5640_PWR_HP_L_BIT, 0, NULL, 0), 1233 - SND_SOC_DAPM_PGA("HP R Amp", RT5640_PWR_ANLG1, 1142 + SND_SOC_DAPM_SUPPLY("HP R Amp", RT5640_PWR_ANLG1, 1234 1143 RT5640_PWR_HP_R_BIT, 0, NULL, 0), 1235 1144 SND_SOC_DAPM_SUPPLY("Improve SPK Amp Drv", RT5640_PWR_DIG1, 1236 - SND_SOC_NOPM, 0, spk_event, 1237 - SND_SOC_DAPM_PRE_PMD | SND_SOC_DAPM_POST_PMU), 1145 + RT5640_PWR_CLS_D_BIT, 0, NULL, 0), 1146 + 1147 + /* Output Switch */ 1148 + SND_SOC_DAPM_SWITCH("Speaker L Playback", SND_SOC_NOPM, 0, 0, 1149 + &spk_l_enable_control), 1150 + SND_SOC_DAPM_SWITCH("Speaker R Playback", SND_SOC_NOPM, 0, 0, 1151 + &spk_r_enable_control), 1152 + SND_SOC_DAPM_SWITCH("HP L Playback", SND_SOC_NOPM, 0, 0, 1153 + &hp_l_enable_control), 1154 + SND_SOC_DAPM_SWITCH("HP R Playback", SND_SOC_NOPM, 0, 0, 1155 + &hp_r_enable_control), 1156 + SND_SOC_DAPM_POST("HP Post", rt5640_hp_post_event), 1238 1157 /* Output Lines */ 1239 1158 SND_SOC_DAPM_OUTPUT("SPOLP"), 1240 1159 SND_SOC_DAPM_OUTPUT("SPOLN"), ··· 1488 1381 {"HPO MIX L", "HPO MIX DAC2 Switch", "DAC L2"}, 1489 1382 {"HPO MIX L", "HPO MIX DAC1 Switch", "DAC L1"}, 1490 1383 {"HPO MIX L", "HPO MIX HPVOL Switch", "HPOVOL L"}, 1384 + {"HPO MIX L", NULL, "HP L Amp"}, 1491 1385 {"HPO MIX R", "HPO MIX DAC2 Switch", "DAC R2"}, 1492 1386 {"HPO MIX R", "HPO MIX DAC1 Switch", "DAC R1"}, 1493 1387 {"HPO MIX R", "HPO MIX HPVOL Switch", "HPOVOL R"}, 1388 + {"HPO MIX R", NULL, "HP R Amp"}, 1494 1389 1495 1390 {"LOUT MIX", "DAC L1 Switch", "DAC L1"}, 1496 1391 {"LOUT MIX", "DAC R1 Switch", "DAC R1"}, ··· 1505 1396 {"Mono MIX", "OUTVOL L Switch", "OUTVOL L"}, 1506 1397 {"Mono MIX", "BST1 Switch", "BST1"}, 1507 1398 1508 - {"HP L Amp", NULL, "HPO MIX L"}, 1509 - {"HP R Amp", NULL, "HPO MIX R"}, 1399 + {"HP Amp", NULL, "HPO MIX L"}, 1400 + {"HP Amp", NULL, "HPO MIX R"}, 1510 1401 1511 - {"SPOLP", NULL, "SPOL MIX"}, 1512 - {"SPOLN", NULL, "SPOL MIX"}, 1513 - {"SPORP", NULL, "SPOR MIX"}, 1514 - {"SPORN", NULL, "SPOR MIX"}, 1402 + {"Speaker L Playback", "Switch", "SPOL MIX"}, 1403 + {"Speaker R Playback", "Switch", "SPOR MIX"}, 1404 + {"SPOLP", NULL, "Speaker L Playback"}, 1405 + {"SPOLN", NULL, "Speaker L Playback"}, 1406 + {"SPORP", NULL, "Speaker R Playback"}, 1407 + {"SPORN", NULL, "Speaker R Playback"}, 1515 1408 1516 1409 {"SPOLP", NULL, "Improve SPK Amp Drv"}, 1517 1410 {"SPOLN", NULL, "Improve SPK Amp Drv"}, ··· 1523 1412 {"HPOL", NULL, "Improve HP Amp Drv"}, 1524 1413 {"HPOR", NULL, "Improve HP Amp Drv"}, 1525 1414 1526 - {"HPOL", NULL, "HP L Amp"}, 1527 - {"HPOR", NULL, "HP R Amp"}, 1415 + {"HP L Playback", "Switch", "HP Amp"}, 1416 + {"HP R Playback", "Switch", "HP Amp"}, 1417 + {"HPOL", NULL, "HP L Playback"}, 1418 + {"HPOR", NULL, "HP R Playback"}, 1528 1419 {"LOUTL", NULL, "LOUT MIX"}, 1529 1420 {"LOUTR", NULL, "LOUT MIX"}, 1530 1421 {"MONOP", NULL, "Mono MIX"}, ··· 1905 1792 RT5640_PWR_BG | RT5640_PWR_VREF2, 1906 1793 RT5640_PWR_VREF1 | RT5640_PWR_MB | 1907 1794 RT5640_PWR_BG | RT5640_PWR_VREF2); 1908 - mdelay(10); 1795 + usleep_range(10000, 15000); 1909 1796 snd_soc_update_bits(codec, RT5640_PWR_ANLG1, 1910 1797 RT5640_PWR_FV1 | RT5640_PWR_FV2, 1911 1798 RT5640_PWR_FV1 | RT5640_PWR_FV2); 1912 1799 regcache_sync(rt5640->regmap); 1913 1800 snd_soc_update_bits(codec, RT5640_DUMMY1, 1914 1801 0x0301, 0x0301); 1915 - snd_soc_update_bits(codec, RT5640_DEPOP_M1, 1916 - 0x001d, 0x0019); 1917 - snd_soc_update_bits(codec, RT5640_DEPOP_M2, 1918 - 0x2000, 0x2000); 1919 1802 snd_soc_update_bits(codec, RT5640_MICBIAS, 1920 1803 0x0030, 0x0030); 1921 1804 } ··· 1955 1846 rt5640_set_bias_level(codec, SND_SOC_BIAS_OFF); 1956 1847 1957 1848 snd_soc_update_bits(codec, RT5640_DUMMY1, 0x0301, 0x0301); 1958 - snd_soc_update_bits(codec, RT5640_DEPOP_M1, 0x001d, 0x0019); 1959 - snd_soc_update_bits(codec, RT5640_DEPOP_M2, 0x2000, 0x2000); 1960 1849 snd_soc_update_bits(codec, RT5640_MICBIAS, 0x0030, 0x0030); 1961 1850 snd_soc_update_bits(codec, RT5640_DSP_PATH2, 0xfc00, 0x0c00); 1962 1851 ··· 2175 2068 if (rt5640->pdata.in2_diff) 2176 2069 regmap_update_bits(rt5640->regmap, RT5640_IN3_IN4, 2177 2070 RT5640_IN_DF2, RT5640_IN_DF2); 2071 + 2072 + rt5640->hp_mute = 1; 2178 2073 2179 2074 ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_rt5640, 2180 2075 rt5640_dai, ARRAY_SIZE(rt5640_dai));
+12
sound/soc/codecs/rt5640.h
··· 145 145 146 146 147 147 /* Index of Codec Private Register definition */ 148 + #define RT5640_CHPUMP_INT_REG1 0x24 149 + #define RT5640_MAMP_INT_REG2 0x37 148 150 #define RT5640_3D_SPK 0x63 149 151 #define RT5640_WND_1 0x6c 150 152 #define RT5640_WND_2 0x6d ··· 155 153 #define RT5640_WND_5 0x70 156 154 #define RT5640_WND_8 0x73 157 155 #define RT5640_DIP_SPK_INF 0x75 156 + #define RT5640_HP_DCC_INT1 0x77 158 157 #define RT5640_EQ_BW_LOP 0xa0 159 158 #define RT5640_EQ_GN_LOP 0xa1 160 159 #define RT5640_EQ_FC_BP1 0xa2 ··· 1204 1201 #define RT5640_CP_FQ2_SFT 4 1205 1202 #define RT5640_CP_FQ3_MASK (0x7) 1206 1203 #define RT5640_CP_FQ3_SFT 0 1204 + #define RT5640_CP_FQ_1_5_KHZ 0 1205 + #define RT5640_CP_FQ_3_KHZ 1 1206 + #define RT5640_CP_FQ_6_KHZ 2 1207 + #define RT5640_CP_FQ_12_KHZ 3 1208 + #define RT5640_CP_FQ_24_KHZ 4 1209 + #define RT5640_CP_FQ_48_KHZ 5 1210 + #define RT5640_CP_FQ_96_KHZ 6 1211 + #define RT5640_CP_FQ_192_KHZ 7 1207 1212 1208 1213 /* HPOUT charge pump (0x91) */ 1209 1214 #define RT5640_OSW_L_MASK (0x1 << 11) ··· 2098 2087 int pll_out; 2099 2088 2100 2089 int dmic_en; 2090 + bool hp_mute; 2101 2091 }; 2102 2092 2103 2093 #endif
+2 -1
sound/soc/codecs/ssm2602.c
··· 561 561 562 562 static 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 567 ssm2602_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 567 568 568 569 return 0;
+7 -15
sound/soc/codecs/tlv320aic32x4.c
··· 338 338 return -EINVAL; 339 339 } 340 340 341 - static 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 - 353 341 static int aic32x4_set_dai_sysclk(struct snd_soc_dai *codec_dai, 354 342 int clk_id, unsigned int freq, int dir) 355 343 { ··· 671 683 } 672 684 673 685 aic32x4_set_bias_level(codec, SND_SOC_BIAS_STANDBY); 674 - snd_soc_add_codec_controls(codec, aic32x4_snd_controls, 675 - ARRAY_SIZE(aic32x4_snd_controls)); 676 - aic32x4_add_widgets(codec); 677 686 678 687 /* 679 688 * Workaround: for an unknown reason, the ADC needs to be powered up ··· 699 714 .suspend = aic32x4_suspend, 700 715 .resume = aic32x4_resume, 701 716 .set_bias_level = aic32x4_set_bias_level, 717 + 718 + .controls = aic32x4_snd_controls, 719 + .num_controls = ARRAY_SIZE(aic32x4_snd_controls), 720 + .dapm_widgets = aic32x4_dapm_widgets, 721 + .num_dapm_widgets = ARRAY_SIZE(aic32x4_dapm_widgets), 722 + .dapm_routes = aic32x4_dapm_routes, 723 + .num_dapm_routes = ARRAY_SIZE(aic32x4_dapm_routes), 702 724 }; 703 725 704 726 static int aic32x4_i2c_probe(struct i2c_client *i2c,
-1
sound/soc/codecs/wm8904.c
··· 1202 1202 break; 1203 1203 } 1204 1204 1205 - snd_soc_dapm_new_widgets(dapm); 1206 1205 return 0; 1207 1206 } 1208 1207
+1 -1
sound/soc/codecs/wm8962.c
··· 3174 3174 long int time; 3175 3175 int ret; 3176 3176 3177 - ret = strict_strtol(buf, 10, &time); 3177 + ret = kstrtol(buf, 10, &time); 3178 3178 if (ret != 0) 3179 3179 return ret; 3180 3180
+1 -4
sound/soc/dwc/designware_i2s.c
··· 421 421 dw_i2s_dai, 1); 422 422 if (ret != 0) { 423 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 427 return 0; 428 428 429 - err_set_drvdata: 430 - dev_set_drvdata(&pdev->dev, NULL); 431 429 err_clk_disable: 432 430 clk_disable(dev->clk); 433 431 err_clk_put: ··· 438 440 struct dw_i2s_dev *dev = dev_get_drvdata(&pdev->dev); 439 441 440 442 snd_soc_unregister_component(&pdev->dev); 441 - dev_set_drvdata(&pdev->dev, NULL); 442 443 443 444 clk_put(dev->clk); 444 445
+11
sound/soc/fsl/Kconfig
··· 193 193 Say Y if you want to add support for SoC audio on an i.MX board with 194 194 a sgtl5000 codec. 195 195 196 + config 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 + 196 207 config SND_SOC_IMX_MC13783 197 208 tristate "SoC Audio support for I.MX boards with mc13783" 198 209 depends on MFD_MC13783 && ARM
+2
sound/soc/fsl/Makefile
··· 45 45 snd-soc-wm1133-ev1-objs := wm1133-ev1.o 46 46 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o 47 47 snd-soc-imx-wm8962-objs := imx-wm8962.o 48 + snd-soc-imx-spdif-objs := imx-spdif.o 48 49 snd-soc-imx-mc13783-objs := imx-mc13783.o 49 50 50 51 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o ··· 54 53 obj-$(CONFIG_SND_MXC_SOC_WM1133_EV1) += snd-soc-wm1133-ev1.o 55 54 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o 56 55 obj-$(CONFIG_SND_SOC_IMX_WM8962) += snd-soc-imx-wm8962.o 56 + obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o 57 57 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
+9 -20
sound/soc/fsl/fsl_spdif.c
··· 411 411 return 0; 412 412 } 413 413 414 - int fsl_spdif_startup(struct snd_pcm_substream *substream, 415 - struct snd_soc_dai *cpu_dai) 414 + static int fsl_spdif_startup(struct snd_pcm_substream *substream, 415 + struct snd_soc_dai *cpu_dai) 416 416 { 417 417 struct snd_soc_pcm_runtime *rtd = substream->private_data; 418 418 struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(rtd->cpu_dai); ··· 546 546 return 0; 547 547 } 548 548 549 - struct snd_soc_dai_ops fsl_spdif_dai_ops = { 549 + static struct snd_soc_dai_ops fsl_spdif_dai_ops = { 550 550 .startup = fsl_spdif_startup, 551 551 .hw_params = fsl_spdif_hw_params, 552 552 .trigger = fsl_spdif_trigger, ··· 555 555 556 556 557 557 /* 558 - * ============================================ 559 558 * FSL SPDIF IEC958 controller(mixer) functions 560 559 * 561 560 * Channel status get/put control ··· 562 563 * Valid bit value get control 563 564 * DPLL lock status get control 564 565 * User bit sync mode selection control 565 - * ============================================ 566 566 */ 567 567 568 568 static int fsl_spdif_info(struct snd_kcontrol *kcontrol, ··· 919 921 return 0; 920 922 } 921 923 922 - struct snd_soc_dai_driver fsl_spdif_dai = { 924 + static struct snd_soc_dai_driver fsl_spdif_dai = { 923 925 .probe = &fsl_spdif_dai_probe, 924 926 .playback = { 925 927 .channels_min = 2, ··· 940 942 .name = "fsl-spdif", 941 943 }; 942 944 943 - /* 944 - * ================ 945 - * FSL SPDIF REGMAP 946 - * ================ 947 - */ 945 + /* FSL SPDIF REGMAP */ 948 946 949 947 static bool fsl_spdif_readable_reg(struct device *dev, unsigned int reg) 950 948 { ··· 1071 1077 break; 1072 1078 } 1073 1079 1074 - dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate", 1080 + dev_dbg(&pdev->dev, "use rxtx%d as tx clock source for %dHz sample rate\n", 1075 1081 spdif_priv->txclk_src[index], rate[index]); 1076 - dev_dbg(&pdev->dev, "use divisor %d for %dHz sample rate", 1082 + dev_dbg(&pdev->dev, "use divisor %d for %dHz sample rate\n", 1077 1083 spdif_priv->txclk_div[index], rate[index]); 1078 1084 1079 1085 return 0; ··· 1113 1119 } 1114 1120 1115 1121 regs = devm_ioremap_resource(&pdev->dev, res); 1116 - if (IS_ERR(regs)) { 1117 - dev_err(&pdev->dev, "could not map device resources\n"); 1122 + if (IS_ERR(regs)) 1118 1123 return PTR_ERR(regs); 1119 - } 1120 1124 1121 1125 spdif_priv->regmap = devm_regmap_init_mmio_clk(&pdev->dev, 1122 1126 "core", regs, &fsl_spdif_regmap_config); ··· 1176 1184 &spdif_priv->cpu_dai_drv, 1); 1177 1185 if (ret) { 1178 1186 dev_err(&pdev->dev, "failed to register DAI: %d\n", ret); 1179 - goto error_dev; 1187 + return ret; 1180 1188 } 1181 1189 1182 1190 ret = imx_pcm_dma_init(pdev); ··· 1189 1197 1190 1198 error_component: 1191 1199 snd_soc_unregister_component(&pdev->dev); 1192 - error_dev: 1193 - dev_set_drvdata(&pdev->dev, NULL); 1194 1200 1195 1201 return ret; 1196 1202 } ··· 1197 1207 { 1198 1208 imx_pcm_dma_exit(pdev); 1199 1209 snd_soc_unregister_component(&pdev->dev); 1200 - dev_set_drvdata(&pdev->dev, NULL); 1201 1210 1202 1211 return 0; 1203 1212 }
-1
sound/soc/fsl/fsl_ssi.c
··· 1114 1114 snd_soc_unregister_component(&pdev->dev); 1115 1115 1116 1116 error_dev: 1117 - dev_set_drvdata(&pdev->dev, NULL); 1118 1117 device_remove_file(&pdev->dev, dev_attr); 1119 1118 1120 1119 error_clk:
+2 -1
sound/soc/fsl/imx-audmux.c
··· 335 335 if (audmux_type == IMX31_AUDMUX) 336 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 341 return 0; 341 342 }
+148
sound/soc/fsl/imx-spdif.c
··· 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 + 16 + struct 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 + 23 + static 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 + 100 + error_dir: 101 + if (data->rxdev) 102 + platform_device_unregister(data->rxdev); 103 + error_dit: 104 + if (data->txdev) 105 + platform_device_unregister(data->txdev); 106 + end: 107 + if (spdif_np) 108 + of_node_put(spdif_np); 109 + 110 + return ret; 111 + } 112 + 113 + static 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 + 127 + static const struct of_device_id imx_spdif_dt_ids[] = { 128 + { .compatible = "fsl,imx-audio-spdif", }, 129 + { /* sentinel */ } 130 + }; 131 + MODULE_DEVICE_TABLE(of, imx_spdif_dt_ids); 132 + 133 + static 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 + 143 + module_platform_driver(imx_spdif_driver); 144 + 145 + MODULE_AUTHOR("Freescale Semiconductor, Inc."); 146 + MODULE_DESCRIPTION("Freescale i.MX S/PDIF machine driver"); 147 + MODULE_LICENSE("GPL v2"); 148 + MODULE_ALIAS("platform:imx-spdif");
+2
sound/soc/generic/simple-card.c
··· 105 105 static struct platform_driver asoc_simple_card = { 106 106 .driver = { 107 107 .name = "asoc-simple-card", 108 + .owner = THIS_MODULE, 108 109 }, 109 110 .probe = asoc_simple_card_probe, 110 111 .remove = asoc_simple_card_remove, ··· 113 112 114 113 module_platform_driver(asoc_simple_card); 115 114 115 + MODULE_ALIAS("platform:asoc-simple-card"); 116 116 MODULE_LICENSE("GPL"); 117 117 MODULE_DESCRIPTION("ASoC Simple Sound Card"); 118 118 MODULE_AUTHOR("Kuninori Morimoto <kuninori.morimoto.gx@renesas.com>");
+2 -2
sound/soc/kirkwood/Kconfig
··· 1 1 config SND_KIRKWOOD_SOC 2 - tristate "SoC Audio for the Marvell Kirkwood chip" 3 - depends on ARCH_KIRKWOOD || COMPILE_TEST 2 + tristate "SoC Audio for the Marvell Kirkwood and Dove chips" 3 + depends on ARCH_KIRKWOOD || ARCH_DOVE || COMPILE_TEST 4 4 help 5 5 Say Y or M if you want to add support for codecs attached to 6 6 the Kirkwood I2S interface. You will also need to select the
+20 -6
sound/soc/kirkwood/kirkwood-i2s.c
··· 22 22 #include <sound/pcm_params.h> 23 23 #include <sound/soc.h> 24 24 #include <linux/platform_data/asoc-kirkwood.h> 25 + #include <linux/of.h> 26 + 25 27 #include "kirkwood.h" 26 28 27 29 #define DRV_NAME "mvebu-audio" ··· 455 453 struct snd_soc_dai_driver *soc_dai = &kirkwood_i2s_dai; 456 454 struct kirkwood_dma_data *priv; 457 455 struct resource *mem; 456 + struct device_node *np = pdev->dev.of_node; 458 457 int err; 459 458 460 459 priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); ··· 476 473 return -ENXIO; 477 474 } 478 475 479 - if (!data) { 480 - dev_err(&pdev->dev, "no platform data ?!\n"); 476 + if (np) { 477 + priv->burst = 128; /* might be 32 or 128 */ 478 + } else if (data) { 479 + priv->burst = data->burst; 480 + } else { 481 + dev_err(&pdev->dev, "no DT nor platform data ?!\n"); 481 482 return -EINVAL; 482 483 } 483 484 484 - priv->burst = data->burst; 485 - 486 - priv->clk = devm_clk_get(&pdev->dev, NULL); 485 + priv->clk = devm_clk_get(&pdev->dev, np ? "internal" : NULL); 487 486 if (IS_ERR(priv->clk)) { 488 487 dev_err(&pdev->dev, "no clock\n"); 489 488 return PTR_ERR(priv->clk); ··· 512 507 priv->ctl_rec = KIRKWOOD_RECCTL_SIZE_24; 513 508 514 509 /* Select the burst size */ 515 - if (data->burst == 32) { 510 + if (priv->burst == 32) { 516 511 priv->ctl_play |= KIRKWOOD_PLAYCTL_BURST_32; 517 512 priv->ctl_rec |= KIRKWOOD_RECCTL_BURST_32; 518 513 } else { ··· 557 552 return 0; 558 553 } 559 554 555 + #ifdef CONFIG_OF 556 + static struct of_device_id mvebu_audio_of_match[] = { 557 + { .compatible = "marvell,mvebu-audio" }, 558 + { } 559 + }; 560 + MODULE_DEVICE_TABLE(of, mvebu_audio_of_match); 561 + #endif 562 + 560 563 static struct platform_driver kirkwood_i2s_driver = { 561 564 .probe = kirkwood_i2s_dev_probe, 562 565 .remove = kirkwood_i2s_dev_remove, 563 566 .driver = { 564 567 .name = DRV_NAME, 565 568 .owner = THIS_MODULE, 569 + .of_match_table = of_match_ptr(mvebu_audio_of_match), 566 570 }, 567 571 }; 568 572
+2
sound/soc/mxs/mxs-sgtl5000.c
··· 105 105 .stream_name = "HiFi Playback", 106 106 .codec_dai_name = "sgtl5000", 107 107 .ops = &mxs_sgtl5000_hifi_ops, 108 + .playback_only = true, 108 109 }, { 109 110 .name = "HiFi Rx", 110 111 .stream_name = "HiFi Capture", 111 112 .codec_dai_name = "sgtl5000", 112 113 .ops = &mxs_sgtl5000_hifi_ops, 114 + .capture_only = true, 113 115 }, 114 116 }; 115 117
+1 -1
sound/soc/omap/mcbsp.c
··· 781 781 unsigned long val; \ 782 782 int status; \ 783 783 \ 784 - status = strict_strtoul(buf, 0, &val); \ 784 + status = kstrtoul(buf, 0, &val); \ 785 785 if (status) \ 786 786 return status; \ 787 787 \
+7
sound/soc/samsung/dma.c
··· 90 90 dma_info.period = prtd->dma_period; 91 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 100 while (prtd->dma_loaded < limit) { 94 101 pr_debug("dma_loaded: %d\n", prtd->dma_loaded); 95 102
+35 -20
sound/soc/sh/fsi.c
··· 235 235 struct sh_dmae_slave slave; /* see fsi_handler_init() */ 236 236 struct work_struct work; 237 237 dma_addr_t dma; 238 + int loop_cnt; 239 + int additional_pos; 238 240 }; 239 241 240 242 struct fsi_clk { ··· 1291 1289 io->bus_option = BUSOP_SET(24, PACKAGE_24BITBUS_BACK) | 1292 1290 BUSOP_SET(16, PACKAGE_16BITBUS_STREAM); 1293 1291 1292 + io->loop_cnt = 2; /* push 1st, 2nd period first, then 3rd, 4th... */ 1293 + io->additional_pos = 0; 1294 1294 io->dma = dma_map_single(dai->dev, runtime->dma_area, 1295 1295 snd_pcm_lib_buffer_bytes(io->substream), dir); 1296 1296 return 0; ··· 1309 1305 return 0; 1310 1306 } 1311 1307 1312 - static dma_addr_t fsi_dma_get_area(struct fsi_stream *io) 1308 + static dma_addr_t fsi_dma_get_area(struct fsi_stream *io, int additional) 1313 1309 { 1314 1310 struct snd_pcm_runtime *runtime = io->substream->runtime; 1311 + int period = io->period_pos + additional; 1315 1312 1316 - return io->dma + samples_to_bytes(runtime, io->buff_sample_pos); 1313 + if (period >= runtime->periods) 1314 + period = 0; 1315 + 1316 + return io->dma + samples_to_bytes(runtime, period * io->period_samples); 1317 1317 } 1318 1318 1319 1319 static void fsi_dma_complete(void *data) ··· 1329 1321 enum dma_data_direction dir = fsi_stream_is_play(fsi, io) ? 1330 1322 DMA_TO_DEVICE : DMA_FROM_DEVICE; 1331 1323 1332 - dma_sync_single_for_cpu(dai->dev, fsi_dma_get_area(io), 1324 + dma_sync_single_for_cpu(dai->dev, fsi_dma_get_area(io, 0), 1333 1325 samples_to_bytes(runtime, io->period_samples), dir); 1334 1326 1335 1327 io->buff_sample_pos += io->period_samples; ··· 1355 1347 struct snd_pcm_runtime *runtime; 1356 1348 enum dma_data_direction dir; 1357 1349 int is_play = fsi_stream_is_play(fsi, io); 1358 - int len; 1350 + int len, i; 1359 1351 dma_addr_t buf; 1360 1352 1361 1353 if (!fsi_stream_is_working(fsi, io)) ··· 1365 1357 runtime = io->substream->runtime; 1366 1358 dir = is_play ? DMA_TO_DEVICE : DMA_FROM_DEVICE; 1367 1359 len = samples_to_bytes(runtime, io->period_samples); 1368 - buf = fsi_dma_get_area(io); 1369 1360 1370 - dma_sync_single_for_device(dai->dev, buf, len, dir); 1361 + for (i = 0; i < io->loop_cnt; i++) { 1362 + buf = fsi_dma_get_area(io, io->additional_pos); 1371 1363 1372 - desc = dmaengine_prep_slave_single(io->chan, buf, len, dir, 1373 - DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 1374 - if (!desc) { 1375 - dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); 1376 - return; 1364 + dma_sync_single_for_device(dai->dev, buf, len, dir); 1365 + 1366 + desc = dmaengine_prep_slave_single(io->chan, buf, len, dir, 1367 + DMA_PREP_INTERRUPT | DMA_CTRL_ACK); 1368 + if (!desc) { 1369 + dev_err(dai->dev, "dmaengine_prep_slave_sg() fail\n"); 1370 + return; 1371 + } 1372 + 1373 + desc->callback = fsi_dma_complete; 1374 + desc->callback_param = io; 1375 + 1376 + if (dmaengine_submit(desc) < 0) { 1377 + dev_err(dai->dev, "tx_submit() fail\n"); 1378 + return; 1379 + } 1380 + 1381 + dma_async_issue_pending(io->chan); 1382 + 1383 + io->additional_pos = 1; 1377 1384 } 1378 1385 1379 - desc->callback = fsi_dma_complete; 1380 - desc->callback_param = io; 1381 - 1382 - if (dmaengine_submit(desc) < 0) { 1383 - dev_err(dai->dev, "tx_submit() fail\n"); 1384 - return; 1385 - } 1386 - 1387 - dma_async_issue_pending(io->chan); 1386 + io->loop_cnt = 1; 1388 1387 1389 1388 /* 1390 1389 * FIXME
+7 -10
sound/soc/soc-core.c
··· 203 203 struct snd_soc_pcm_runtime *rtd = dev_get_drvdata(dev); 204 204 int ret; 205 205 206 - ret = strict_strtol(buf, 10, &rtd->pmdown_time); 206 + ret = kstrtol(buf, 10, &rtd->pmdown_time); 207 207 if (ret) 208 208 return ret; 209 209 ··· 248 248 char *start = buf; 249 249 unsigned long reg, value; 250 250 struct snd_soc_codec *codec = file->private_data; 251 + int ret; 251 252 252 253 buf_size = min(count, (sizeof(buf)-1)); 253 254 if (copy_from_user(buf, user_buf, buf_size)) ··· 260 259 reg = simple_strtoul(start, &start, 16); 261 260 while (*start == ' ') 262 261 start++; 263 - if (strict_strtoul(start, 16, &value)) 264 - return -EINVAL; 262 + ret = kstrtoul(start, 16, &value); 263 + if (ret) 264 + return ret; 265 265 266 266 /* Userspace has been fiddling around behind the kernel's back */ 267 267 add_taint(TAINT_USER, LOCKDEP_NOW_UNRELIABLE); ··· 1245 1243 } 1246 1244 rtd->card = card; 1247 1245 1248 - /* Make sure all DAPM widgets are instantiated */ 1249 - snd_soc_dapm_new_widgets(&codec->dapm); 1250 - 1251 1246 /* machine controls, routes and widgets are not prefixed */ 1252 1247 temp = codec->name_prefix; 1253 1248 codec->name_prefix = NULL; ··· 1740 1741 snd_soc_dapm_add_routes(&card->dapm, card->dapm_routes, 1741 1742 card->num_dapm_routes); 1742 1743 1743 - snd_soc_dapm_new_widgets(&card->dapm); 1744 - 1745 1744 for (i = 0; i < card->num_links; i++) { 1746 1745 dai_link = &card->dai_link[i]; 1747 1746 dai_fmt = dai_link->dai_fmt; ··· 1818 1821 } 1819 1822 } 1820 1823 1821 - snd_soc_dapm_new_widgets(&card->dapm); 1822 - 1823 1824 if (card->fully_routed) 1824 1825 list_for_each_entry(codec, &card->codec_dev_list, card_list) 1825 1826 snd_soc_dapm_auto_nc_codec_pins(codec); 1827 + 1828 + snd_soc_dapm_new_widgets(card); 1826 1829 1827 1830 ret = snd_card_register(card->snd_card); 1828 1831 if (ret < 0) {
+6 -5
sound/soc/soc-dapm.c
··· 229 229 template.id = snd_soc_dapm_kcontrol; 230 230 template.name = kcontrol->id.name; 231 231 232 + data->value = template.on_val; 233 + 232 234 data->widget = snd_soc_dapm_new_control(widget->dapm, 233 235 &template); 234 236 if (!data->widget) { ··· 2376 2374 wsource->ext = 1; 2377 2375 } 2378 2376 2377 + dapm_mark_dirty(wsource, "Route added"); 2378 + dapm_mark_dirty(wsink, "Route added"); 2379 + 2379 2380 /* connect static paths */ 2380 2381 if (control == NULL) { 2381 2382 list_add(&path->list, &dapm->card->paths); ··· 2440 2435 path->connect = 0; 2441 2436 return 0; 2442 2437 } 2443 - 2444 - dapm_mark_dirty(wsource, "Route added"); 2445 - dapm_mark_dirty(wsink, "Route added"); 2446 2438 2447 2439 return 0; 2448 2440 err: ··· 2714 2712 * 2715 2713 * Returns 0 for success. 2716 2714 */ 2717 - int snd_soc_dapm_new_widgets(struct snd_soc_dapm_context *dapm) 2715 + int snd_soc_dapm_new_widgets(struct snd_soc_card *card) 2718 2716 { 2719 - struct snd_soc_card *card = dapm->card; 2720 2717 struct snd_soc_dapm_widget *w; 2721 2718 unsigned int val; 2722 2719
-2
sound/soc/soc-jack.c
··· 183 183 list_add(&(pins[i].list), &jack->pins); 184 184 } 185 185 186 - snd_soc_dapm_new_widgets(&jack->codec->card->dapm); 187 - 188 186 /* Update to reflect the last reported status; canned jack 189 187 * implementations are likely to set their state before the 190 188 * card has an opportunity to associate pins.
+10
sound/soc/soc-pcm.c
··· 2020 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 2033 /* create the PCM */ 2024 2034 if (rtd->dai_link->no_pcm) { 2025 2035 snprintf(new_name, sizeof(new_name), "(%s)",
+2 -2
sound/usb/6fire/firmware.c
··· 346 346 if (!memcmp(version, known_fw_versions + i, 2)) 347 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 350 "please reconnect to power. if this failure " 351 351 "still happens, check your firmware installation.", 352 - 4, version); 352 + version); 353 353 return -EINVAL; 354 354 } 355 355
+3
sound/usb/endpoint.c
··· 418 418 struct snd_usb_endpoint *ep; 419 419 int is_playback = direction == SNDRV_PCM_STREAM_PLAYBACK; 420 420 421 + if (WARN_ON(!alts)) 422 + return NULL; 423 + 421 424 mutex_lock(&chip->mutex); 422 425 423 426 list_for_each_entry(ep, &chip->ep_list, list) {
+138 -105
sound/usb/pcm.c
··· 327 327 return 0; 328 328 } 329 329 330 + static 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 + 380 + add_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 + 392 + static 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 462 * find a matching format and set up the interface 332 463 */ ··· 467 336 struct usb_host_interface *alts; 468 337 struct usb_interface_descriptor *altsd; 469 338 struct usb_interface *iface; 470 - unsigned int ep, attr; 471 - int is_playback = subs->direction == SNDRV_PCM_STREAM_PLAYBACK; 472 - int err, implicit_fb = 0; 339 + int err; 473 340 474 341 iface = usb_ifnum_to_if(dev, fmt->iface); 475 342 if (WARN_ON(!iface)) ··· 512 383 subs->data_endpoint = snd_usb_add_endpoint(subs->stream->chip, 513 384 alts, fmt->endpoint, subs->direction, 514 385 SND_USB_ENDPOINT_TYPE_DATA); 386 + 515 387 if (!subs->data_endpoint) 516 388 return -EINVAL; 517 389 518 - /* we need a sync pipe in async OUT or adaptive IN mode */ 519 - /* check the number of EP, since some devices have broken 520 - * descriptors which fool us. if it has only one EP, 521 - * assume it as adaptive-out or sync-in. 522 - */ 523 - attr = fmt->ep_attr & USB_ENDPOINT_SYNCTYPE; 390 + err = set_sync_endpoint(subs, fmt, dev, alts, altsd); 391 + if (err < 0) 392 + return err; 524 393 525 - switch (subs->stream->chip->usb_id) { 526 - case USB_ID(0x0763, 0x2030): /* M-Audio Fast Track C400 */ 527 - case USB_ID(0x0763, 0x2031): /* M-Audio Fast Track C600 */ 528 - if (is_playback) { 529 - implicit_fb = 1; 530 - ep = 0x81; 531 - iface = usb_ifnum_to_if(dev, 3); 532 - 533 - if (!iface || iface->num_altsetting == 0) 534 - return -EINVAL; 535 - 536 - alts = &iface->altsetting[1]; 537 - goto add_sync_ep; 538 - } 539 - break; 540 - case USB_ID(0x0763, 0x2080): /* M-Audio FastTrack Ultra */ 541 - case USB_ID(0x0763, 0x2081): 542 - if (is_playback) { 543 - implicit_fb = 1; 544 - ep = 0x81; 545 - iface = usb_ifnum_to_if(dev, 2); 546 - 547 - if (!iface || iface->num_altsetting == 0) 548 - return -EINVAL; 549 - 550 - alts = &iface->altsetting[1]; 551 - goto add_sync_ep; 552 - } 553 - } 554 - if (is_playback && 555 - attr == USB_ENDPOINT_SYNC_ASYNC && 556 - altsd->bInterfaceClass == USB_CLASS_VENDOR_SPEC && 557 - altsd->bInterfaceProtocol == 2 && 558 - altsd->bNumEndpoints == 1 && 559 - USB_ID_VENDOR(subs->stream->chip->usb_id) == 0x0582 /* Roland */ && 560 - search_roland_implicit_fb(dev, altsd->bInterfaceNumber + 1, 561 - altsd->bAlternateSetting, 562 - &alts, &ep) >= 0) { 563 - implicit_fb = 1; 564 - goto add_sync_ep; 565 - } 566 - 567 - if (((is_playback && attr == USB_ENDPOINT_SYNC_ASYNC) || 568 - (!is_playback && attr == USB_ENDPOINT_SYNC_ADAPTIVE)) && 569 - altsd->bNumEndpoints >= 2) { 570 - /* check sync-pipe endpoint */ 571 - /* ... and check descriptor size before accessing bSynchAddress 572 - because there is a version of the SB Audigy 2 NX firmware lacking 573 - the audio fields in the endpoint descriptors */ 574 - if ((get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK) != USB_ENDPOINT_XFER_ISOC || 575 - (get_endpoint(alts, 1)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && 576 - get_endpoint(alts, 1)->bSynchAddress != 0 && 577 - !implicit_fb)) { 578 - snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. bmAttributes %02x, bLength %d, bSynchAddress %02x\n", 579 - dev->devnum, fmt->iface, fmt->altsetting, 580 - get_endpoint(alts, 1)->bmAttributes, 581 - get_endpoint(alts, 1)->bLength, 582 - get_endpoint(alts, 1)->bSynchAddress); 583 - return -EINVAL; 584 - } 585 - ep = get_endpoint(alts, 1)->bEndpointAddress; 586 - if (!implicit_fb && 587 - get_endpoint(alts, 0)->bLength >= USB_DT_ENDPOINT_AUDIO_SIZE && 588 - (( is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress | USB_DIR_IN)) || 589 - (!is_playback && ep != (unsigned int)(get_endpoint(alts, 0)->bSynchAddress & ~USB_DIR_IN)))) { 590 - snd_printk(KERN_ERR "%d:%d:%d : invalid sync pipe. is_playback %d, ep %02x, bSynchAddress %02x\n", 591 - dev->devnum, fmt->iface, fmt->altsetting, 592 - is_playback, ep, get_endpoint(alts, 0)->bSynchAddress); 593 - return -EINVAL; 594 - } 595 - 596 - implicit_fb = (get_endpoint(alts, 1)->bmAttributes & USB_ENDPOINT_USAGE_MASK) 597 - == USB_ENDPOINT_USAGE_IMPLICIT_FB; 598 - 599 - add_sync_ep: 600 - subs->sync_endpoint = snd_usb_add_endpoint(subs->stream->chip, 601 - alts, ep, !subs->direction, 602 - implicit_fb ? 603 - SND_USB_ENDPOINT_TYPE_DATA : 604 - SND_USB_ENDPOINT_TYPE_SYNC); 605 - if (!subs->sync_endpoint) 606 - return -EINVAL; 607 - 608 - subs->data_endpoint->sync_master = subs->sync_endpoint; 609 - } 610 - 611 - if ((err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt)) < 0) 394 + err = snd_usb_init_pitch(subs->stream->chip, fmt->iface, alts, fmt); 395 + if (err < 0) 612 396 return err; 613 397 614 398 subs->cur_audiofmt = fmt; 615 399 616 400 snd_usb_set_format_quirk(subs, fmt); 617 - 618 - #if 0 619 - printk(KERN_DEBUG 620 - "setting done: format = %d, rate = %d..%d, channels = %d\n", 621 - fmt->format, fmt->rate_min, fmt->rate_max, fmt->channels); 622 - printk(KERN_DEBUG 623 - " datapipe = 0x%0x, syncpipe = 0x%0x\n", 624 - subs->datapipe, subs->syncpipe); 625 - #endif 626 401 627 402 return 0; 628 403 }
+3 -5
sound/usb/usx2y/usbusx2y.c
··· 305 305 { 306 306 int i; 307 307 for (i = 0; i < URBS_AsyncSeq; ++i) { 308 - if (S[i].urb) { 309 - usb_kill_urb(S->urb[i]); 310 - usb_free_urb(S->urb[i]); 311 - S->urb[i] = NULL; 312 - } 308 + usb_kill_urb(S->urb[i]); 309 + usb_free_urb(S->urb[i]); 310 + S->urb[i] = NULL; 313 311 } 314 312 kfree(S->buffer); 315 313 }