diff options
author | Takashi Iwai <tiwai@suse.de> | 2009-07-06 07:00:57 -0400 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2009-07-06 07:02:44 -0400 |
commit | 40c20fa05a29766565f56ede17d0ffa539e1c9a9 (patch) | |
tree | e990bb08e0671f7e49eb2e0cf55a56ee4b992dfe /sound | |
parent | ea35929b886975a240660b3ba6c61826761731ad (diff) |
ALSA: hda - Add CS420x-specific coef setup
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound')
-rw-r--r-- | sound/pci/hda/patch_cirrus.c | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_cirrus.c b/sound/pci/hda/patch_cirrus.c index 8e33214abeb4..2187383cdfd6 100644 --- a/sound/pci/hda/patch_cirrus.c +++ b/sound/pci/hda/patch_cirrus.c | |||
@@ -58,6 +58,64 @@ struct cs_spec { | |||
58 | unsigned int mic_detect:1; | 58 | unsigned int mic_detect:1; |
59 | }; | 59 | }; |
60 | 60 | ||
61 | /* Vendor-specific processing widget */ | ||
62 | #define CS420X_VENDOR_NID 0x11 | ||
63 | #define CS_DIG_OUT1_PIN_NID 0x10 | ||
64 | #define CS_DIG_OUT2_PIN_NID 0x15 | ||
65 | #define CS_DMIC1_PIN_NID 0x12 | ||
66 | #define CS_DMIC2_PIN_NID 0x0e | ||
67 | |||
68 | /* coef indices */ | ||
69 | #define IDX_SPDIF_STAT 0x0000 | ||
70 | #define IDX_SPDIF_CTL 0x0001 | ||
71 | #define IDX_ADC_CFG 0x0002 | ||
72 | /* SZC bitmask, 4 modes below: | ||
73 | * 0 = immediate, | ||
74 | * 1 = digital immediate, analog zero-cross | ||
75 | * 2 = digtail & analog soft-ramp | ||
76 | * 3 = digital soft-ramp, analog zero-cross | ||
77 | */ | ||
78 | #define CS_COEF_ADC_SZC_MASK (3 << 0) | ||
79 | #define CS_COEF_ADC_MIC_SZC_MODE (3 << 0) /* SZC setup for mic */ | ||
80 | #define CS_COEF_ADC_LI_SZC_MODE (3 << 0) /* SZC setup for line-in */ | ||
81 | /* PGA mode: 0 = differential, 1 = signle-ended */ | ||
82 | #define CS_COEF_ADC_MIC_PGA_MODE (1 << 5) /* PGA setup for mic */ | ||
83 | #define CS_COEF_ADC_LI_PGA_MODE (1 << 6) /* PGA setup for line-in */ | ||
84 | #define IDX_DAC_CFG 0x0003 | ||
85 | /* SZC bitmask, 4 modes below: | ||
86 | * 0 = Immediate | ||
87 | * 1 = zero-cross | ||
88 | * 2 = soft-ramp | ||
89 | * 3 = soft-ramp on zero-cross | ||
90 | */ | ||
91 | #define CS_COEF_DAC_HP_SZC_MODE (3 << 0) /* nid 0x02 */ | ||
92 | #define CS_COEF_DAC_LO_SZC_MODE (3 << 2) /* nid 0x03 */ | ||
93 | #define CS_COEF_DAC_SPK_SZC_MODE (3 << 4) /* nid 0x04 */ | ||
94 | |||
95 | #define IDX_BEEP_CFG 0x0004 | ||
96 | /* 0x0008 - test reg key */ | ||
97 | /* 0x0009 - 0x0014 -> 12 test regs */ | ||
98 | /* 0x0015 - visibility reg */ | ||
99 | |||
100 | |||
101 | static int cs_vendor_coef_get(struct hda_codec *codec, unsigned int idx) | ||
102 | { | ||
103 | snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, | ||
104 | AC_VERB_SET_COEF_INDEX, idx); | ||
105 | return snd_hda_codec_read(codec, CS420X_VENDOR_NID, 0, | ||
106 | AC_VERB_GET_PROC_COEF, 0); | ||
107 | } | ||
108 | |||
109 | static void cs_vendor_coef_set(struct hda_codec *codec, unsigned int idx, | ||
110 | unsigned int coef) | ||
111 | { | ||
112 | snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, | ||
113 | AC_VERB_SET_COEF_INDEX, idx); | ||
114 | snd_hda_codec_write(codec, CS420X_VENDOR_NID, 0, | ||
115 | AC_VERB_SET_PROC_COEF, coef); | ||
116 | } | ||
117 | |||
118 | |||
61 | #define HP_EVENT 1 | 119 | #define HP_EVENT 1 |
62 | #define MIC_EVENT 2 | 120 | #define MIC_EVENT 2 |
63 | 121 | ||
@@ -295,6 +353,14 @@ static hda_nid_t get_adc(struct hda_codec *codec, hda_nid_t pin, | |||
295 | return 0; | 353 | return 0; |
296 | } | 354 | } |
297 | 355 | ||
356 | static int is_active_pin(struct hda_codec *codec, hda_nid_t nid) | ||
357 | { | ||
358 | struct cs_spec *spec = codec->spec; | ||
359 | unsigned int val; | ||
360 | val = snd_hda_codec_get_pincfg(codec, nid); | ||
361 | return (get_defcfg_connect(val) != AC_JACK_PORT_NONE); | ||
362 | } | ||
363 | |||
298 | static int parse_output(struct hda_codec *codec) | 364 | static int parse_output(struct hda_codec *codec) |
299 | { | 365 | { |
300 | struct cs_spec *spec = codec->spec; | 366 | struct cs_spec *spec = codec->spec; |
@@ -833,6 +899,7 @@ static void init_input(struct hda_codec *codec) | |||
833 | { | 899 | { |
834 | struct cs_spec *spec = codec->spec; | 900 | struct cs_spec *spec = codec->spec; |
835 | struct auto_pin_cfg *cfg = &spec->autocfg; | 901 | struct auto_pin_cfg *cfg = &spec->autocfg; |
902 | unsigned int coef; | ||
836 | int i; | 903 | int i; |
837 | 904 | ||
838 | for (i = 0; i < AUTO_PIN_LAST; i++) { | 905 | for (i = 0; i < AUTO_PIN_LAST; i++) { |
@@ -861,14 +928,57 @@ static void init_input(struct hda_codec *codec) | |||
861 | change_cur_input(codec, spec->cur_input, 1); | 928 | change_cur_input(codec, spec->cur_input, 1); |
862 | if (spec->mic_detect) | 929 | if (spec->mic_detect) |
863 | cs_automic(codec); | 930 | cs_automic(codec); |
931 | |||
932 | coef = 0x000a; /* ADC1/2 - Digital and Analog Soft Ramp */ | ||
933 | if (is_active_pin(codec, CS_DMIC2_PIN_NID)) | ||
934 | coef |= 0x0500; /* DMIC2 enable 2 channels, disable GPIO1 */ | ||
935 | if (is_active_pin(codec, CS_DMIC1_PIN_NID)) | ||
936 | coef |= 0x1800; /* DMIC1 enable 2 channels, disable GPIO0 | ||
937 | * No effect if SPDIF_OUT2 is slected in | ||
938 | * IDX_SPDIF_CTL. | ||
939 | */ | ||
940 | cs_vendor_coef_set(codec, IDX_ADC_CFG, coef); | ||
941 | } | ||
942 | |||
943 | static struct hda_verb cs_coef_init_verbs[] = { | ||
944 | {0x11, AC_VERB_SET_PROC_STATE, 1}, | ||
945 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, | ||
946 | {0x11, AC_VERB_SET_PROC_COEF, | ||
947 | (0x002a /* DAC1/2/3 SZCMode Soft Ramp */ | ||
948 | | 0x0040 /* Mute DACs on FIFO error */ | ||
949 | | 0x1000 /* Enable DACs High Pass Filter */ | ||
950 | | 0x0400 /* Disable Coefficient Auto increment */ | ||
951 | )}, | ||
952 | /* Beep */ | ||
953 | {0x11, AC_VERB_SET_COEF_INDEX, IDX_DAC_CFG}, | ||
954 | {0x11, AC_VERB_SET_PROC_COEF, 0x0007}, /* Enable Beep thru DAC1/2/3 */ | ||
955 | |||
956 | {} /* terminator */ | ||
957 | }; | ||
958 | |||
959 | /* SPDIF setup */ | ||
960 | static void init_digital(struct hda_codec *codec) | ||
961 | { | ||
962 | unsigned int coef; | ||
963 | |||
964 | coef = 0x0002; /* SRC_MUTE soft-mute on SPDIF (if no lock) */ | ||
965 | coef |= 0x0008; /* Replace with mute on error */ | ||
966 | if (is_active_pin(codec, CS_DIG_OUT2_PIN_NID)) | ||
967 | coef |= 0x4000; /* RX to TX1 or TX2 Loopthru / SPDIF2 | ||
968 | * SPDIF_OUT2 is shared with GPIO1 and | ||
969 | * DMIC_SDA2. | ||
970 | */ | ||
971 | cs_vendor_coef_set(codec, IDX_SPDIF_CTL, coef); | ||
864 | } | 972 | } |
865 | 973 | ||
866 | static int cs_init(struct hda_codec *codec) | 974 | static int cs_init(struct hda_codec *codec) |
867 | { | 975 | { |
868 | struct cs_spec *spec = codec->spec; | 976 | struct cs_spec *spec = codec->spec; |
869 | 977 | ||
978 | snd_hda_sequence_write(codec, cs_coef_init_verbs); | ||
870 | init_output(codec); | 979 | init_output(codec); |
871 | init_input(codec); | 980 | init_input(codec); |
981 | init_digital(codec); | ||
872 | return 0; | 982 | return 0; |
873 | } | 983 | } |
874 | 984 | ||