Commit | Line | Data |
---|---|---|
1da177e4 LT |
1 | /* |
2 | * Universal Interface for Intel High Definition Audio Codec | |
3 | * | |
4 | * Local helper functions | |
5 | * | |
6 | * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de> | |
7 | * | |
8 | * This program is free software; you can redistribute it and/or modify it | |
9 | * under the terms of the GNU General Public License as published by the Free | |
10 | * Software Foundation; either version 2 of the License, or (at your option) | |
11 | * any later version. | |
12 | * | |
13 | * This program is distributed in the hope that it will be useful, but WITHOUT | |
14 | * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for | |
16 | * more details. | |
17 | * | |
18 | * You should have received a copy of the GNU General Public License along with | |
19 | * this program; if not, write to the Free Software Foundation, Inc., 59 | |
20 | * Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |
21 | */ | |
22 | ||
23 | #ifndef __SOUND_HDA_LOCAL_H | |
24 | #define __SOUND_HDA_LOCAL_H | |
25 | ||
26 | /* | |
27 | * for mixer controls | |
28 | */ | |
29 | #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) | |
985be54b | 30 | /* mono volume with index (index=0,1,...) (channel=1,2) */ |
1da177e4 LT |
31 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
32 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | |
33 | .info = snd_hda_mixer_amp_volume_info, \ | |
34 | .get = snd_hda_mixer_amp_volume_get, \ | |
35 | .put = snd_hda_mixer_amp_volume_put, \ | |
36 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } | |
985be54b | 37 | /* stereo volume with index */ |
1da177e4 LT |
38 | #define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \ |
39 | HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) | |
985be54b | 40 | /* mono volume */ |
1da177e4 LT |
41 | #define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \ |
42 | HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction) | |
985be54b | 43 | /* stereo volume */ |
1da177e4 LT |
44 | #define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \ |
45 | HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction) | |
985be54b | 46 | /* mono mute switch with index (index=0,1,...) (channel=1,2) */ |
1da177e4 LT |
47 | #define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
48 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | |
49 | .info = snd_hda_mixer_amp_switch_info, \ | |
50 | .get = snd_hda_mixer_amp_switch_get, \ | |
51 | .put = snd_hda_mixer_amp_switch_put, \ | |
52 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) } | |
985be54b | 53 | /* stereo mute switch with index */ |
1da177e4 LT |
54 | #define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \ |
55 | HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction) | |
985be54b | 56 | /* mono mute switch */ |
1da177e4 LT |
57 | #define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \ |
58 | HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction) | |
985be54b | 59 | /* stereo mute switch */ |
1da177e4 LT |
60 | #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ |
61 | HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) | |
62 | ||
63 | int snd_hda_mixer_amp_volume_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo); | |
64 | int snd_hda_mixer_amp_volume_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | |
65 | int snd_hda_mixer_amp_volume_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | |
66 | int snd_hda_mixer_amp_switch_info(snd_kcontrol_t *kcontrol, snd_ctl_elem_info_t *uinfo); | |
67 | int snd_hda_mixer_amp_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | |
68 | int snd_hda_mixer_amp_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | |
69 | ||
985be54b TI |
70 | /* mono switch binding multiple inputs */ |
71 | #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ | |
72 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \ | |
73 | .info = snd_hda_mixer_amp_switch_info, \ | |
74 | .get = snd_hda_mixer_bind_switch_get, \ | |
75 | .put = snd_hda_mixer_bind_switch_put, \ | |
76 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } | |
77 | ||
78 | /* stereo switch binding multiple inputs */ | |
79 | #define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) | |
80 | ||
81 | int snd_hda_mixer_bind_switch_get(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | |
82 | int snd_hda_mixer_bind_switch_put(snd_kcontrol_t *kcontrol, snd_ctl_elem_value_t *ucontrol); | |
83 | ||
1da177e4 LT |
84 | int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); |
85 | int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); | |
86 | ||
87 | /* | |
88 | * input MUX helper | |
89 | */ | |
90 | #define HDA_MAX_NUM_INPUTS 8 | |
91 | struct hda_input_mux_item { | |
92 | const char *label; | |
93 | unsigned int index; | |
94 | }; | |
95 | struct hda_input_mux { | |
96 | unsigned int num_items; | |
97 | struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS]; | |
98 | }; | |
99 | ||
100 | int snd_hda_input_mux_info(const struct hda_input_mux *imux, snd_ctl_elem_info_t *uinfo); | |
101 | int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, | |
102 | snd_ctl_elem_value_t *ucontrol, hda_nid_t nid, | |
103 | unsigned int *cur_val); | |
104 | ||
d2a6d7dc TI |
105 | /* |
106 | * Channel mode helper | |
107 | */ | |
108 | struct hda_channel_mode { | |
109 | int channels; | |
110 | const struct hda_verb *sequence; | |
111 | }; | |
112 | ||
113 | int snd_hda_ch_mode_info(struct hda_codec *codec, snd_ctl_elem_info_t *uinfo, | |
114 | const struct hda_channel_mode *chmode, int num_chmodes); | |
115 | int snd_hda_ch_mode_get(struct hda_codec *codec, snd_ctl_elem_value_t *ucontrol, | |
116 | const struct hda_channel_mode *chmode, int num_chmodes, | |
117 | int max_channels); | |
118 | int snd_hda_ch_mode_put(struct hda_codec *codec, snd_ctl_elem_value_t *ucontrol, | |
119 | const struct hda_channel_mode *chmode, int num_chmodes, | |
120 | int *max_channelsp); | |
121 | ||
1da177e4 LT |
122 | /* |
123 | * Multi-channel / digital-out PCM helper | |
124 | */ | |
125 | ||
126 | enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */ | |
127 | enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */ | |
128 | ||
129 | struct hda_multi_out { | |
130 | int num_dacs; /* # of DACs, must be more than 1 */ | |
131 | hda_nid_t *dac_nids; /* DAC list */ | |
132 | hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */ | |
133 | hda_nid_t dig_out_nid; /* digital out audio widget */ | |
134 | int max_channels; /* currently supported analog channels */ | |
135 | int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ | |
136 | }; | |
137 | ||
138 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); | |
139 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); | |
140 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, | |
141 | snd_pcm_substream_t *substream); | |
142 | int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, | |
143 | unsigned int stream_tag, | |
144 | unsigned int format, | |
145 | snd_pcm_substream_t *substream); | |
146 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout); | |
147 | ||
148 | /* | |
149 | * generic codec parser | |
150 | */ | |
151 | int snd_hda_parse_generic_codec(struct hda_codec *codec); | |
152 | ||
153 | /* | |
154 | * generic proc interface | |
155 | */ | |
156 | #ifdef CONFIG_PROC_FS | |
157 | int snd_hda_codec_proc_new(struct hda_codec *codec); | |
158 | #else | |
159 | static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } | |
160 | #endif | |
161 | ||
162 | /* | |
163 | * Misc | |
164 | */ | |
165 | struct hda_board_config { | |
166 | const char *modelname; | |
167 | int config; | |
7291548d TI |
168 | unsigned short pci_subvendor; |
169 | unsigned short pci_subdevice; | |
1da177e4 LT |
170 | }; |
171 | ||
e9edcee0 | 172 | int snd_hda_check_board_config(struct hda_codec *codec, const struct hda_board_config *tbl); |
1da177e4 LT |
173 | int snd_hda_add_new_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew); |
174 | ||
175 | /* | |
176 | * power management | |
177 | */ | |
178 | #ifdef CONFIG_PM | |
179 | int snd_hda_resume_ctls(struct hda_codec *codec, snd_kcontrol_new_t *knew); | |
180 | int snd_hda_resume_spdif_out(struct hda_codec *codec); | |
181 | int snd_hda_resume_spdif_in(struct hda_codec *codec); | |
182 | #endif | |
183 | ||
184 | /* | |
185 | * unsolicited event handler | |
186 | */ | |
187 | ||
188 | #define HDA_UNSOL_QUEUE_SIZE 64 | |
189 | ||
190 | struct hda_bus_unsolicited { | |
191 | /* ring buffer */ | |
192 | u32 queue[HDA_UNSOL_QUEUE_SIZE * 2]; | |
193 | unsigned int rp, wp; | |
194 | ||
195 | /* workqueue */ | |
196 | struct workqueue_struct *workq; | |
197 | struct work_struct work; | |
198 | }; | |
199 | ||
e9edcee0 TI |
200 | /* |
201 | * Helper for automatic ping configuration | |
202 | */ | |
203 | ||
204 | enum { | |
205 | AUTO_PIN_MIC, | |
206 | AUTO_PIN_FRONT_MIC, | |
207 | AUTO_PIN_LINE, | |
208 | AUTO_PIN_FRONT_LINE, | |
209 | AUTO_PIN_CD, | |
210 | AUTO_PIN_AUX, | |
211 | AUTO_PIN_LAST | |
212 | }; | |
213 | ||
214 | struct auto_pin_cfg { | |
215 | int line_outs; | |
216 | hda_nid_t line_out_pins[4]; /* sorted in the order of Front/Surr/CLFE/Side */ | |
217 | hda_nid_t hp_pin; | |
218 | hda_nid_t input_pins[AUTO_PIN_LAST]; | |
219 | hda_nid_t dig_out_pin; | |
220 | hda_nid_t dig_in_pin; | |
221 | }; | |
222 | ||
223 | #define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) | |
224 | #define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) | |
225 | #define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) | |
226 | #define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE) | |
227 | #define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) | |
228 | ||
229 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg); | |
230 | ||
1da177e4 | 231 | #endif /* __SOUND_HDA_LOCAL_H */ |