changelog shortlog tags changeset manifest revisions annotate raw

pci/hda/hda_local.h

changeset 5086: 6ee58da0b892
parent:a456a2256e31
child:d522c2501301
author: tiwai
date: Tue May 29 19:01:37 2007 +0200 (4 years ago)
permissions: -rw-r--r--
description: hda-codec - Fix STAC922x capture boost level

STAC922x provides the capture boost level up to 4, but actually it
works only up to 2. Since the range of the mixer is automatically
defined from amp-capability bits, we need to override the value
beforehand. snd_hda_override_amp_caps() is introduced for this
purpose.

The function patch_stac922x() calls this for NID 0x12 (Mux Capture
Volume). This should fix another recording problem on Intel Macs.

Patch-level: ASAP
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))
30/* mono volume with index (index=0,1,...) (channel=1,2) */
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 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE | \
34 SNDRV_CTL_ELEM_ACCESS_TLV_READ | \
35 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK, \
36 .info = snd_hda_mixer_amp_volume_info, \
37 .get = snd_hda_mixer_amp_volume_get, \
38 .put = snd_hda_mixer_amp_volume_put, \
39 .tlv = { .c = snd_hda_mixer_amp_tlv }, \
40 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
41/* stereo volume with index */
42#define HDA_CODEC_VOLUME_IDX(xname, xcidx, nid, xindex, direction) \
43 HDA_CODEC_VOLUME_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
44/* mono volume */
45#define HDA_CODEC_VOLUME_MONO(xname, nid, channel, xindex, direction) \
46 HDA_CODEC_VOLUME_MONO_IDX(xname, 0, nid, channel, xindex, direction)
47/* stereo volume */
48#define HDA_CODEC_VOLUME(xname, nid, xindex, direction) \
49 HDA_CODEC_VOLUME_MONO(xname, nid, 3, xindex, direction)
50/* mono mute switch with index (index=0,1,...) (channel=1,2) */
51#define HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, channel, xindex, direction) \
52 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = xcidx, \
53 .info = snd_hda_mixer_amp_switch_info, \
54 .get = snd_hda_mixer_amp_switch_get, \
55 .put = snd_hda_mixer_amp_switch_put, \
56 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, xindex, direction) }
57/* stereo mute switch with index */
58#define HDA_CODEC_MUTE_IDX(xname, xcidx, nid, xindex, direction) \
59 HDA_CODEC_MUTE_MONO_IDX(xname, xcidx, nid, 3, xindex, direction)
60/* mono mute switch */
61#define HDA_CODEC_MUTE_MONO(xname, nid, channel, xindex, direction) \
62 HDA_CODEC_MUTE_MONO_IDX(xname, 0, nid, channel, xindex, direction)
63/* stereo mute switch */
64#define HDA_CODEC_MUTE(xname, nid, xindex, direction) \
65 HDA_CODEC_MUTE_MONO(xname, nid, 3, xindex, direction)
66
67int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
68int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
69int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
70int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag, unsigned int size, unsigned int __user *tlv);
71int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo);
72int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
73int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
74/* lowlevel accessor with caching; use carefully */
75int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
76 int direction, int index);
77int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
78 int direction, int idx, int mask, int val);
79
80/* mono switch binding multiple inputs */
81#define HDA_BIND_MUTE_MONO(xname, nid, channel, indices, direction) \
82 { .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, .index = 0, \
83 .info = snd_hda_mixer_amp_switch_info, \
84 .get = snd_hda_mixer_bind_switch_get, \
85 .put = snd_hda_mixer_bind_switch_put, \
86 .private_value = HDA_COMPOSE_AMP_VAL(nid, channel, indices, direction) }
87
88/* stereo switch binding multiple inputs */
89#define HDA_BIND_MUTE(xname,nid,indices,dir) HDA_BIND_MUTE_MONO(xname,nid,3,indices,dir)
90
91int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
92int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol);
93
94int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid);
95int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid);
96
97/*
98 * input MUX helper
99 */
100#define HDA_MAX_NUM_INPUTS 16
101struct hda_input_mux_item {
102 const char *label;
103 unsigned int index;
104};
105struct hda_input_mux {
106 unsigned int num_items;
107 struct hda_input_mux_item items[HDA_MAX_NUM_INPUTS];
108};
109
110int snd_hda_input_mux_info(const struct hda_input_mux *imux, struct snd_ctl_elem_info *uinfo);
111int snd_hda_input_mux_put(struct hda_codec *codec, const struct hda_input_mux *imux,
112 struct snd_ctl_elem_value *ucontrol, hda_nid_t nid,
113 unsigned int *cur_val);
114
115/*
116 * Channel mode helper
117 */
118struct hda_channel_mode {
119 int channels;
120 const struct hda_verb *sequence;
121};
122
123int snd_hda_ch_mode_info(struct hda_codec *codec, struct snd_ctl_elem_info *uinfo,
124 const struct hda_channel_mode *chmode, int num_chmodes);
125int snd_hda_ch_mode_get(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
126 const struct hda_channel_mode *chmode, int num_chmodes,
127 int max_channels);
128int snd_hda_ch_mode_put(struct hda_codec *codec, struct snd_ctl_elem_value *ucontrol,
129 const struct hda_channel_mode *chmode, int num_chmodes,
130 int *max_channelsp);
131
132/*
133 * Multi-channel / digital-out PCM helper
134 */
135
136enum { HDA_FRONT, HDA_REAR, HDA_CLFE, HDA_SIDE }; /* index for dac_nidx */
137enum { HDA_DIG_NONE, HDA_DIG_EXCLUSIVE, HDA_DIG_ANALOG_DUP }; /* dig_out_used */
138
139struct hda_multi_out {
140 int num_dacs; /* # of DACs, must be more than 1 */
141 hda_nid_t *dac_nids; /* DAC list */
142 hda_nid_t hp_nid; /* optional DAC for HP, 0 when not exists */
143 hda_nid_t extra_out_nid[3]; /* optional DACs, 0 when not exists */
144 hda_nid_t dig_out_nid; /* digital out audio widget */
145 int max_channels; /* currently supported analog channels */
146 int dig_out_used; /* current usage of digital out (HDA_DIG_XXX) */
147};
148
149int snd_hda_multi_out_dig_open(struct hda_codec *codec, struct hda_multi_out *mout);
150int snd_hda_multi_out_dig_close(struct hda_codec *codec, struct hda_multi_out *mout);
151int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
152 struct hda_multi_out *mout,
153 unsigned int stream_tag,
154 unsigned int format,
155 struct snd_pcm_substream *substream);
156int snd_hda_multi_out_analog_open(struct hda_codec *codec, struct hda_multi_out *mout,
157 struct snd_pcm_substream *substream);
158int snd_hda_multi_out_analog_prepare(struct hda_codec *codec, struct hda_multi_out *mout,
159 unsigned int stream_tag,
160 unsigned int format,
161 struct snd_pcm_substream *substream);
162int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec, struct hda_multi_out *mout);
163
164/*
165 * generic codec parser
166 */
167int snd_hda_parse_generic_codec(struct hda_codec *codec);
168
169/*
170 * generic proc interface
171 */
172#ifdef CONFIG_PROC_FS
173int snd_hda_codec_proc_new(struct hda_codec *codec);
174#else
175static inline int snd_hda_codec_proc_new(struct hda_codec *codec) { return 0; }
176#endif
177
178/*
179 * Misc
180 */
181int snd_hda_check_board_config(struct hda_codec *codec, int num_configs,
182 const char **modelnames,
183 const struct snd_pci_quirk *pci_list);
184int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew);
185
186/*
187 * power management
188 */
189#ifdef CONFIG_PM
190int snd_hda_resume_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew);
191int snd_hda_resume_spdif_out(struct hda_codec *codec);
192int snd_hda_resume_spdif_in(struct hda_codec *codec);
193#endif
194
195/*
196 * unsolicited event handler
197 */
198
199#define HDA_UNSOL_QUEUE_SIZE 64
200
201struct hda_bus_unsolicited {
202 /* ring buffer */
203 u32 queue[HDA_UNSOL_QUEUE_SIZE * 2];
204 unsigned int rp, wp;
205
206 /* workqueue */
207 struct work_struct work;
208 struct hda_bus *bus;
209};
210
211/*
212 * Helper for automatic ping configuration
213 */
214
215enum {
216 AUTO_PIN_MIC,
217 AUTO_PIN_FRONT_MIC,
218 AUTO_PIN_LINE,
219 AUTO_PIN_FRONT_LINE,
220 AUTO_PIN_CD,
221 AUTO_PIN_AUX,
222 AUTO_PIN_LAST
223};
224
225enum {
226 AUTO_PIN_LINE_OUT,
227 AUTO_PIN_SPEAKER_OUT,
228 AUTO_PIN_HP_OUT
229};
230
231extern const char *auto_pin_cfg_labels[AUTO_PIN_LAST];
232
233struct auto_pin_cfg {
234 int line_outs;
235 hda_nid_t line_out_pins[5]; /* sorted in the order of Front/Surr/CLFE/Side */
236 int speaker_outs;
237 hda_nid_t speaker_pins[5];
238 int hp_outs;
239 int line_out_type; /* AUTO_PIN_XXX_OUT */
240 hda_nid_t hp_pins[5];
241 hda_nid_t input_pins[AUTO_PIN_LAST];
242 hda_nid_t dig_out_pin;
243 hda_nid_t dig_in_pin;
244};
245
246#define get_defcfg_connect(cfg) ((cfg & AC_DEFCFG_PORT_CONN) >> AC_DEFCFG_PORT_CONN_SHIFT)
247#define get_defcfg_association(cfg) ((cfg & AC_DEFCFG_DEF_ASSOC) >> AC_DEFCFG_ASSOC_SHIFT)
248#define get_defcfg_location(cfg) ((cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT)
249#define get_defcfg_sequence(cfg) (cfg & AC_DEFCFG_SEQUENCE)
250#define get_defcfg_device(cfg) ((cfg & AC_DEFCFG_DEVICE) >> AC_DEFCFG_DEVICE_SHIFT)
251
252int snd_hda_parse_pin_def_config(struct hda_codec *codec, struct auto_pin_cfg *cfg,
253 hda_nid_t *ignore_nids);
254
255/* amp values */
256#define AMP_IN_MUTE(idx) (0x7080 | ((idx)<<8))
257#define AMP_IN_UNMUTE(idx) (0x7000 | ((idx)<<8))
258#define AMP_OUT_MUTE 0xb080
259#define AMP_OUT_UNMUTE 0xb000
260#define AMP_OUT_ZERO 0xb000
261/* pinctl values */
262#define PIN_IN 0x20
263#define PIN_VREF80 0x24
264#define PIN_VREF50 0x21
265#define PIN_OUT 0x40
266#define PIN_HP 0xc0
267#define PIN_HP_AMP 0x80
268
269/*
270 * get widget capabilities
271 */
272static inline u32 get_wcaps(struct hda_codec *codec, hda_nid_t nid)
273{
274 if (nid < codec->start_nid ||
275 nid >= codec->start_nid + codec->num_nodes)
276 return snd_hda_param_read(codec, nid, AC_PAR_AUDIO_WIDGET_CAP);
277 return codec->wcaps[nid - codec->start_nid];
278}
279
280int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
281 unsigned int caps);
282
283#endif /* __SOUND_HDA_LOCAL_H */