diff options
Diffstat (limited to 'sound/pci/hda/hda_local.h')
-rw-r--r-- | sound/pci/hda/hda_local.h | 193 |
1 files changed, 151 insertions, 42 deletions
diff --git a/sound/pci/hda/hda_local.h b/sound/pci/hda/hda_local.h index f91ea5ec9f6d..a79d0ed5469c 100644 --- a/sound/pci/hda/hda_local.h +++ b/sound/pci/hda/hda_local.h | |||
@@ -26,7 +26,8 @@ | |||
26 | /* | 26 | /* |
27 | * for mixer controls | 27 | * for mixer controls |
28 | */ | 28 | */ |
29 | #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) | 29 | #define HDA_COMPOSE_AMP_VAL(nid,chs,idx,dir) \ |
30 | ((nid) | ((chs)<<16) | ((dir)<<18) | ((idx)<<19)) | ||
30 | /* mono volume with index (index=0,1,...) (channel=1,2) */ | 31 | /* mono volume with index (index=0,1,...) (channel=1,2) */ |
31 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ | 32 | #define HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \ |
32 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ | 33 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \ |
@@ -64,18 +65,35 @@ | |||
64 | #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ | 65 | #define HDA_CODEC_MUTE(xname, nid, xindex, direction) \ |
65 | HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) | 66 | HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction) |
66 | 67 | ||
67 | int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); | 68 | int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, |
68 | int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | 69 | struct snd_ctl_elem_info *uinfo); |
69 | int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | 70 | int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, |
70 | int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv); | 71 | struct snd_ctl_elem_value *ucontrol); |
71 | int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo); | 72 | int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, |
72 | int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | 73 | struct snd_ctl_elem_value *ucontrol); |
73 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | 74 | int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, |
75 | unsigned int size, unsigned int __user *tlv); | ||
76 | int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, | ||
77 | struct snd_ctl_elem_info *uinfo); | ||
78 | int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, | ||
79 | struct snd_ctl_elem_value *ucontrol); | ||
80 | int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, | ||
81 | struct snd_ctl_elem_value *ucontrol); | ||
74 | /* lowlevel accessor with caching; use carefully */ | 82 | /* lowlevel accessor with caching; use carefully */ |
75 | int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, | 83 | int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch, |
76 | int direction, int index); | 84 | int direction, int index); |
77 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | 85 | int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, |
78 | int direction, int idx, int mask, int val); | 86 | int direction, int idx, int mask, int val); |
87 | int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid, | ||
88 | int dir, int idx, int mask, int val); | ||
89 | #ifdef SND_HDA_NEEDS_RESUME | ||
90 | void snd_hda_codec_resume_amp(struct hda_codec *codec); | ||
91 | #endif | ||
92 | |||
93 | /* amp value bits */ | ||
94 | #define HDA_AMP_MUTE 0x80 | ||
95 | #define HDA_AMP_UNMUTE 0x00 | ||
96 | #define HDA_AMP_VOLMASK 0x7f | ||
79 | 97 | ||
80 | /* mono switch binding multiple inputs */ | 98 | /* mono switch binding multiple inputs */ |
81 | #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ | 99 | #define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \ |
@@ -86,11 +104,61 @@ int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch, | |||
86 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } | 104 | .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) } |
87 | 105 | ||
88 | /* stereo switch binding multiple inputs */ | 106 | /* stereo switch binding multiple inputs */ |
89 | #define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) | 107 | #define HDA_BIND_MUTE(xname,nid,indices,dir) \ |
108 | HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir) | ||
109 | |||
110 | int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, | ||
111 | struct snd_ctl_elem_value *ucontrol); | ||
112 | int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, | ||
113 | struct snd_ctl_elem_value *ucontrol); | ||
114 | |||
115 | /* more generic bound controls */ | ||
116 | struct hda_ctl_ops { | ||
117 | snd_kcontrol_info_t *info; | ||
118 | snd_kcontrol_get_t *get; | ||
119 | snd_kcontrol_put_t *put; | ||
120 | snd_kcontrol_tlv_rw_t *tlv; | ||
121 | }; | ||
90 | 122 | ||
91 | int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | 123 | extern struct hda_ctl_ops snd_hda_bind_vol; /* for bind-volume with TLV */ |
92 | int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol); | 124 | extern struct hda_ctl_ops snd_hda_bind_sw; /* for bind-switch */ |
93 | 125 | ||
126 | struct hda_bind_ctls { | ||
127 | struct hda_ctl_ops *ops; | ||
128 | long values[]; | ||
129 | }; | ||
130 | |||
131 | int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol, | ||
132 | struct snd_ctl_elem_info *uinfo); | ||
133 | int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol, | ||
134 | struct snd_ctl_elem_value *ucontrol); | ||
135 | int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol, | ||
136 | struct snd_ctl_elem_value *ucontrol); | ||
137 | int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag, | ||
138 | unsigned int size, unsigned int __user *tlv); | ||
139 | |||
140 | #define HDA_BIND_VOL(xname, bindrec) \ | ||
141 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ | ||
142 | .name = xname, \ | ||
143 | .access = SNDRV_CTL_ELEM_ACCESS_READWRITE |\ | ||
144 | SNDRV_CTL_ELEM_ACCESS_TLV_READ |\ | ||
145 | SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK,\ | ||
146 | .info = snd_hda_mixer_bind_ctls_info,\ | ||
147 | .get = snd_hda_mixer_bind_ctls_get,\ | ||
148 | .put = snd_hda_mixer_bind_ctls_put,\ | ||
149 | .tlv = { .c = snd_hda_mixer_bind_tlv },\ | ||
150 | .private_value = (long) (bindrec) } | ||
151 | #define HDA_BIND_SW(xname, bindrec) \ | ||
152 | { .iface = SNDRV_CTL_ELEM_IFACE_MIXER,\ | ||
153 | .name = xname, \ | ||
154 | .info = snd_hda_mixer_bind_ctls_info,\ | ||
155 | .get = snd_hda_mixer_bind_ctls_get,\ | ||
156 | .put = snd_hda_mixer_bind_ctls_put,\ | ||
157 | .private_value = (long) (bindrec) } | ||
158 | |||
159 | /* | ||
160 | * SPDIF I/O | ||
161 | */ | ||
94 | int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); | 162 | int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid); |
95 | int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); | 163 | int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid); |
96 | 164 | ||
@@ -107,8 +175,10 @@ struct hda_input_mux { | |||
107 | struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS]; | 175 | struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS]; |
108 | }; | 176 | }; |
109 | 177 | ||
110 | int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo); | 178 | int snd_hda_input_mux_info(const struct hda_input_mux *imux, |
111 | int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux, | 179 | struct snd_ctl_elem_info *uinfo); |
180 | int snd_hda_input_mux_put(struct hda_codec *codec, | ||
181 | const struct hda_input_mux *imux, | ||
112 | struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, | 182 | struct snd_ctl_elem_value *ucontrol, hda_nid_t nid, |
113 | unsigned int *cur_val); | 183 | unsigned int *cur_val); |
114 | 184 | ||
@@ -120,13 +190,19 @@ struct hda_channel_mode { | |||
120 | const struct hda_verb *sequence; | 190 | const struct hda_verb *sequence; |
121 | }; | 191 | }; |
122 | 192 | ||
123 | int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo, | 193 | int snd_hda_ch_mode_info(struct hda_codec *codec, |
124 | const struct hda_channel_mode *chmode, int num_chmodes); | 194 | struct snd_ctl_elem_info *uinfo, |
125 | int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, | 195 | const struct hda_channel_mode *chmode, |
126 | const struct hda_channel_mode *chmode, int num_chmodes, | 196 | int num_chmodes); |
197 | int snd_hda_ch_mode_get(struct hda_codec *codec, | ||
198 | struct snd_ctl_elem_value *ucontrol, | ||
199 | const struct hda_channel_mode *chmode, | ||
200 | int num_chmodes, | ||
127 | int max_channels); | 201 | int max_channels); |
128 | int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol, | 202 | int snd_hda_ch_mode_put(struct hda_codec *codec, |
129 | const struct hda_channel_mode *chmode, int num_chmodes, | 203 | struct snd_ctl_elem_value *ucontrol, |
204 | const struct hda_channel_mode *chmode, | ||
205 | int num_chmodes, | ||
130 | int *max_channelsp); | 206 | int *max_channelsp); |
131 | 207 | ||
132 | /* | 208 | /* |
@@ -146,20 +222,25 @@ struct hda_multi_out { | |||
146 | int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ | 222 | int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */ |
147 | }; | 223 | }; |
148 | 224 | ||
149 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout); | 225 | int snd_hda_multi_out_dig_open(struct hda_codec *codec, |
150 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout); | 226 | struct hda_multi_out *mout); |
227 | int snd_hda_multi_out_dig_close(struct hda_codec *codec, | ||
228 | struct hda_multi_out *mout); | ||
151 | int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, | 229 | int snd_hda_multi_out_dig_prepare(struct hda_codec *codec, |
152 | struct hda_multi_out *mout, | 230 | struct hda_multi_out *mout, |
153 | unsigned int stream_tag, | 231 | unsigned int stream_tag, |
154 | unsigned int format, | 232 | unsigned int format, |
155 | struct snd_pcm_substream *substream); | 233 | struct snd_pcm_substream *substream); |
156 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout, | 234 | int snd_hda_multi_out_analog_open(struct hda_codec *codec, |
235 | struct hda_multi_out *mout, | ||
157 | struct snd_pcm_substream *substream); | 236 | struct snd_pcm_substream *substream); |
158 | int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout, | 237 | int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, |
238 | struct hda_multi_out *mout, | ||
159 | unsigned int stream_tag, | 239 | unsigned int stream_tag, |
160 | unsigned int format, | 240 | unsigned int format, |
161 | struct snd_pcm_substream *substream); | 241 | struct snd_pcm_substream *substream); |
162 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout); | 242 | int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, |
243 | struct hda_multi_out *mout); | ||
163 | 244 | ||
164 | /* | 245 | /* |
165 | * generic codec parser | 246 | * generic codec parser |
@@ -181,16 +262,8 @@ static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; } | |||
181 | int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, | 262 | int snd_hda_check_board_config(struct hda_codec *codec, int num_configs, |
182 | const char **modelnames, | 263 | const char **modelnames, |
183 | const struct snd_pci_quirk *pci_list); | 264 | const struct snd_pci_quirk *pci_list); |
184 | int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); | 265 | int snd_hda_add_new_ctls(struct hda_codec *codec, |
185 | 266 | struct snd_kcontrol_new *knew); | |
186 | /* | ||
187 | * power management | ||
188 | */ | ||
189 | #ifdef CONFIG_PM | ||
190 | int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew); | ||
191 | int snd_hda_resume_spdif_out(struct hda_codec *codec); | ||
192 | int snd_hda_resume_spdif_in(struct hda_codec *codec); | ||
193 | #endif | ||
194 | 267 | ||
195 | /* | 268 | /* |
196 | * unsolicited event handler | 269 | * unsolicited event handler |
@@ -232,7 +305,9 @@ extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST]; | |||
232 | 305 | ||
233 | struct auto_pin_cfg { | 306 | struct auto_pin_cfg { |
234 | int line_outs; | 307 | int line_outs; |
235 | hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */ | 308 | hda_nid_t line_out_pins[5]; /* sorted in the order of |
309 | * Front/Surr/CLFE/Side | ||
310 | */ | ||
236 | int speaker_outs; | 311 | int speaker_outs; |
237 | hda_nid_t speaker_pins[5]; | 312 | hda_nid_t speaker_pins[5]; |
238 | int hp_outs; | 313 | int hp_outs; |
@@ -243,13 +318,19 @@ struct auto_pin_cfg { | |||
243 | hda_nid_t dig_in_pin; | 318 | hda_nid_t dig_in_pin; |
244 | }; | 319 | }; |
245 | 320 | ||
246 | #define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) | 321 | #define get_defcfg_connect(cfg) \ |
247 | #define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) | 322 | ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT) |
248 | #define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) | 323 | #define get_defcfg_association(cfg) \ |
249 | #define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE) | 324 | ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT) |
250 | #define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) | 325 | #define get_defcfg_location(cfg) \ |
251 | 326 | ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT) | |
252 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg, | 327 | #define get_defcfg_sequence(cfg) \ |
328 | (cfg & AC_DEFCFG_SEQUENCE) | ||
329 | #define get_defcfg_device(cfg) \ | ||
330 | ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT) | ||
331 | |||
332 | int snd_hda_parse_pin_def_config(struct hda_codec *codec, | ||
333 | struct auto_pin_cfg *cfg, | ||
253 | hda_nid_t *ignore_nids); | 334 | hda_nid_t *ignore_nids); |
254 | 335 | ||
255 | /* amp values */ | 336 | /* amp values */ |
@@ -280,4 +361,32 @@ static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid) | |||
280 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, | 361 | int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir, |
281 | unsigned int caps); | 362 | unsigned int caps); |
282 | 363 | ||
364 | /* | ||
365 | * hwdep interface | ||
366 | */ | ||
367 | int snd_hda_create_hwdep(struct hda_codec *codec); | ||
368 | |||
369 | /* | ||
370 | * power-management | ||
371 | */ | ||
372 | |||
373 | #ifdef CONFIG_SND_HDA_POWER_SAVE | ||
374 | void snd_hda_schedule_power_save(struct hda_codec *codec); | ||
375 | |||
376 | struct hda_amp_list { | ||
377 | hda_nid_t nid; | ||
378 | unsigned char dir; | ||
379 | unsigned char idx; | ||
380 | }; | ||
381 | |||
382 | struct hda_loopback_check { | ||
383 | struct hda_amp_list *amplist; | ||
384 | int power_on; | ||
385 | }; | ||
386 | |||
387 | int snd_hda_check_amp_list_power(struct hda_codec *codec, | ||
388 | struct hda_loopback_check *check, | ||
389 | hda_nid_t nid); | ||
390 | #endif /* CONFIG_SND_HDA_POWER_SAVE */ | ||
391 | |||
283 | #endif /* __SOUND_HDA_LOCAL_H */ | 392 | #endif /* __SOUND_HDA_LOCAL_H */ |