blob: f5c2d1ff1a0904756a6a444eee7faf3406279d8d [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * Generic widget tree parser
5 *
6 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
7 *
8 * This driver is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This driver is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
Linus Torvalds1da177e2005-04-16 15:20:36 -070023#include <linux/init.h>
24#include <linux/slab.h>
Paul Gortmakerd81a6d72011-09-22 09:34:58 -040025#include <linux/export.h>
Takashi Iwai352f7f92012-12-19 12:52:06 +010026#include <linux/sort.h>
Takashi Iwai55196ff2013-01-24 17:32:56 +010027#include <linux/delay.h>
Takashi Iwaif873e532012-12-20 16:58:39 +010028#include <linux/ctype.h>
29#include <linux/string.h>
Takashi Iwai294765582013-01-17 09:52:11 +010030#include <linux/bitops.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <sound/core.h>
Takashi Iwai352f7f92012-12-19 12:52:06 +010032#include <sound/jack.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070033#include "hda_codec.h"
34#include "hda_local.h"
Takashi Iwai352f7f92012-12-19 12:52:06 +010035#include "hda_auto_parser.h"
36#include "hda_jack.h"
Takashi Iwai7504b6c2013-03-18 11:25:51 +010037#include "hda_beep.h"
Takashi Iwai352f7f92012-12-19 12:52:06 +010038#include "hda_generic.h"
Linus Torvalds1da177e2005-04-16 15:20:36 -070039
Linus Torvalds1da177e2005-04-16 15:20:36 -070040
Takashi Iwai352f7f92012-12-19 12:52:06 +010041/* initialize hda_gen_spec struct */
42int snd_hda_gen_spec_init(struct hda_gen_spec *spec)
Linus Torvalds1da177e2005-04-16 15:20:36 -070043{
Takashi Iwai352f7f92012-12-19 12:52:06 +010044 snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
Takashi Iwai352f7f92012-12-19 12:52:06 +010045 snd_array_init(&spec->paths, sizeof(struct nid_path), 8);
Takashi Iwai0186f4f2013-02-07 10:45:11 +010046 snd_array_init(&spec->loopback_list, sizeof(struct hda_amp_list), 8);
Takashi Iwai38cf6f12012-12-21 14:09:42 +010047 mutex_init(&spec->pcm_mutex);
Takashi Iwai352f7f92012-12-19 12:52:06 +010048 return 0;
49}
50EXPORT_SYMBOL_HDA(snd_hda_gen_spec_init);
Linus Torvalds1da177e2005-04-16 15:20:36 -070051
Takashi Iwai12c93df2012-12-19 14:38:33 +010052struct snd_kcontrol_new *
53snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name,
54 const struct snd_kcontrol_new *temp)
Takashi Iwai352f7f92012-12-19 12:52:06 +010055{
56 struct snd_kcontrol_new *knew = snd_array_new(&spec->kctls);
57 if (!knew)
58 return NULL;
59 *knew = *temp;
60 if (name)
61 knew->name = kstrdup(name, GFP_KERNEL);
62 else if (knew->name)
63 knew->name = kstrdup(knew->name, GFP_KERNEL);
64 if (!knew->name)
65 return NULL;
66 return knew;
67}
Takashi Iwai12c93df2012-12-19 14:38:33 +010068EXPORT_SYMBOL_HDA(snd_hda_gen_add_kctl);
Takashi Iwai352f7f92012-12-19 12:52:06 +010069
70static void free_kctls(struct hda_gen_spec *spec)
71{
72 if (spec->kctls.list) {
73 struct snd_kcontrol_new *kctl = spec->kctls.list;
74 int i;
75 for (i = 0; i < spec->kctls.used; i++)
76 kfree(kctl[i].name);
77 }
78 snd_array_free(&spec->kctls);
79}
80
Takashi Iwai352f7f92012-12-19 12:52:06 +010081void snd_hda_gen_spec_free(struct hda_gen_spec *spec)
82{
83 if (!spec)
Linus Torvalds1da177e2005-04-16 15:20:36 -070084 return;
Takashi Iwai352f7f92012-12-19 12:52:06 +010085 free_kctls(spec);
Takashi Iwai352f7f92012-12-19 12:52:06 +010086 snd_array_free(&spec->paths);
Takashi Iwai0186f4f2013-02-07 10:45:11 +010087 snd_array_free(&spec->loopback_list);
Linus Torvalds1da177e2005-04-16 15:20:36 -070088}
Takashi Iwai352f7f92012-12-19 12:52:06 +010089EXPORT_SYMBOL_HDA(snd_hda_gen_spec_free);
Linus Torvalds1da177e2005-04-16 15:20:36 -070090
91/*
Takashi Iwai1c70a582013-01-11 17:48:22 +010092 * store user hints
93 */
94static void parse_user_hints(struct hda_codec *codec)
95{
96 struct hda_gen_spec *spec = codec->spec;
97 int val;
98
99 val = snd_hda_get_bool_hint(codec, "jack_detect");
100 if (val >= 0)
101 codec->no_jack_detect = !val;
102 val = snd_hda_get_bool_hint(codec, "inv_jack_detect");
103 if (val >= 0)
104 codec->inv_jack_detect = !!val;
105 val = snd_hda_get_bool_hint(codec, "trigger_sense");
106 if (val >= 0)
107 codec->no_trigger_sense = !val;
108 val = snd_hda_get_bool_hint(codec, "inv_eapd");
109 if (val >= 0)
110 codec->inv_eapd = !!val;
111 val = snd_hda_get_bool_hint(codec, "pcm_format_first");
112 if (val >= 0)
113 codec->pcm_format_first = !!val;
114 val = snd_hda_get_bool_hint(codec, "sticky_stream");
115 if (val >= 0)
116 codec->no_sticky_stream = !val;
117 val = snd_hda_get_bool_hint(codec, "spdif_status_reset");
118 if (val >= 0)
119 codec->spdif_status_reset = !!val;
120 val = snd_hda_get_bool_hint(codec, "pin_amp_workaround");
121 if (val >= 0)
122 codec->pin_amp_workaround = !!val;
123 val = snd_hda_get_bool_hint(codec, "single_adc_amp");
124 if (val >= 0)
125 codec->single_adc_amp = !!val;
126
Takashi Iwaif72706b2013-01-16 18:20:07 +0100127 val = snd_hda_get_bool_hint(codec, "auto_mute");
128 if (val >= 0)
129 spec->suppress_auto_mute = !val;
Takashi Iwai1c70a582013-01-11 17:48:22 +0100130 val = snd_hda_get_bool_hint(codec, "auto_mic");
131 if (val >= 0)
132 spec->suppress_auto_mic = !val;
133 val = snd_hda_get_bool_hint(codec, "line_in_auto_switch");
134 if (val >= 0)
135 spec->line_in_auto_switch = !!val;
Takashi Iwai7eebffd2013-06-24 16:00:21 +0200136 val = snd_hda_get_bool_hint(codec, "auto_mute_via_amp");
137 if (val >= 0)
138 spec->auto_mute_via_amp = !!val;
Takashi Iwai1c70a582013-01-11 17:48:22 +0100139 val = snd_hda_get_bool_hint(codec, "need_dac_fix");
140 if (val >= 0)
141 spec->need_dac_fix = !!val;
142 val = snd_hda_get_bool_hint(codec, "primary_hp");
143 if (val >= 0)
144 spec->no_primary_hp = !val;
145 val = snd_hda_get_bool_hint(codec, "multi_cap_vol");
146 if (val >= 0)
147 spec->multi_cap_vol = !!val;
148 val = snd_hda_get_bool_hint(codec, "inv_dmic_split");
149 if (val >= 0)
150 spec->inv_dmic_split = !!val;
151 val = snd_hda_get_bool_hint(codec, "indep_hp");
152 if (val >= 0)
153 spec->indep_hp = !!val;
154 val = snd_hda_get_bool_hint(codec, "add_stereo_mix_input");
155 if (val >= 0)
156 spec->add_stereo_mix_input = !!val;
Takashi Iwaif811c3c2013-03-07 18:32:59 +0100157 /* the following two are just for compatibility */
Takashi Iwai1c70a582013-01-11 17:48:22 +0100158 val = snd_hda_get_bool_hint(codec, "add_out_jack_modes");
159 if (val >= 0)
Takashi Iwaif811c3c2013-03-07 18:32:59 +0100160 spec->add_jack_modes = !!val;
Takashi Iwai294765582013-01-17 09:52:11 +0100161 val = snd_hda_get_bool_hint(codec, "add_in_jack_modes");
162 if (val >= 0)
Takashi Iwaif811c3c2013-03-07 18:32:59 +0100163 spec->add_jack_modes = !!val;
164 val = snd_hda_get_bool_hint(codec, "add_jack_modes");
165 if (val >= 0)
166 spec->add_jack_modes = !!val;
Takashi Iwai55196ff2013-01-24 17:32:56 +0100167 val = snd_hda_get_bool_hint(codec, "power_down_unused");
168 if (val >= 0)
169 spec->power_down_unused = !!val;
Takashi Iwai967303d2013-02-19 17:12:42 +0100170 val = snd_hda_get_bool_hint(codec, "add_hp_mic");
171 if (val >= 0)
172 spec->hp_mic = !!val;
173 val = snd_hda_get_bool_hint(codec, "hp_mic_detect");
174 if (val >= 0)
175 spec->suppress_hp_mic_detect = !val;
Takashi Iwai1c70a582013-01-11 17:48:22 +0100176
177 if (!snd_hda_get_int_hint(codec, "mixer_nid", &val))
178 spec->mixer_nid = val;
179}
180
181/*
Takashi Iwai2c12c302013-01-10 09:33:29 +0100182 * pin control value accesses
183 */
184
185#define update_pin_ctl(codec, pin, val) \
186 snd_hda_codec_update_cache(codec, pin, 0, \
187 AC_VERB_SET_PIN_WIDGET_CONTROL, val)
188
189/* restore the pinctl based on the cached value */
190static inline void restore_pin_ctl(struct hda_codec *codec, hda_nid_t pin)
191{
192 update_pin_ctl(codec, pin, snd_hda_codec_get_pin_target(codec, pin));
193}
194
195/* set the pinctl target value and write it if requested */
196static void set_pin_target(struct hda_codec *codec, hda_nid_t pin,
197 unsigned int val, bool do_write)
198{
199 if (!pin)
200 return;
201 val = snd_hda_correct_pin_ctl(codec, pin, val);
202 snd_hda_codec_set_pin_target(codec, pin, val);
203 if (do_write)
204 update_pin_ctl(codec, pin, val);
205}
206
207/* set pinctl target values for all given pins */
208static void set_pin_targets(struct hda_codec *codec, int num_pins,
209 hda_nid_t *pins, unsigned int val)
210{
211 int i;
212 for (i = 0; i < num_pins; i++)
213 set_pin_target(codec, pins[i], val, false);
214}
215
216/*
Takashi Iwai352f7f92012-12-19 12:52:06 +0100217 * parsing paths
Linus Torvalds1da177e2005-04-16 15:20:36 -0700218 */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700219
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100220/* return the position of NID in the list, or -1 if not found */
221static int find_idx_in_nid_list(hda_nid_t nid, const hda_nid_t *list, int nums)
222{
223 int i;
224 for (i = 0; i < nums; i++)
225 if (list[i] == nid)
226 return i;
227 return -1;
228}
229
230/* return true if the given NID is contained in the path */
231static bool is_nid_contained(struct nid_path *path, hda_nid_t nid)
232{
233 return find_idx_in_nid_list(nid, path->path, path->depth) >= 0;
234}
235
Takashi Iwaif5172a72013-01-04 13:19:55 +0100236static struct nid_path *get_nid_path(struct hda_codec *codec,
237 hda_nid_t from_nid, hda_nid_t to_nid,
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100238 int anchor_nid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700239{
Takashi Iwai352f7f92012-12-19 12:52:06 +0100240 struct hda_gen_spec *spec = codec->spec;
241 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700242
Takashi Iwai352f7f92012-12-19 12:52:06 +0100243 for (i = 0; i < spec->paths.used; i++) {
244 struct nid_path *path = snd_array_elem(&spec->paths, i);
245 if (path->depth <= 0)
246 continue;
247 if ((!from_nid || path->path[0] == from_nid) &&
Takashi Iwaif5172a72013-01-04 13:19:55 +0100248 (!to_nid || path->path[path->depth - 1] == to_nid)) {
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100249 if (!anchor_nid ||
250 (anchor_nid > 0 && is_nid_contained(path, anchor_nid)) ||
251 (anchor_nid < 0 && !is_nid_contained(path, anchor_nid)))
Takashi Iwaif5172a72013-01-04 13:19:55 +0100252 return path;
253 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254 }
255 return NULL;
256}
Takashi Iwaif5172a72013-01-04 13:19:55 +0100257
258/* get the path between the given NIDs;
259 * passing 0 to either @pin or @dac behaves as a wildcard
260 */
261struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec,
262 hda_nid_t from_nid, hda_nid_t to_nid)
263{
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100264 return get_nid_path(codec, from_nid, to_nid, 0);
Takashi Iwaif5172a72013-01-04 13:19:55 +0100265}
Takashi Iwai352f7f92012-12-19 12:52:06 +0100266EXPORT_SYMBOL_HDA(snd_hda_get_nid_path);
267
Takashi Iwai196c17662013-01-04 15:01:40 +0100268/* get the index number corresponding to the path instance;
269 * the index starts from 1, for easier checking the invalid value
270 */
271int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path)
272{
273 struct hda_gen_spec *spec = codec->spec;
274 struct nid_path *array = spec->paths.list;
275 ssize_t idx;
276
277 if (!spec->paths.used)
278 return 0;
279 idx = path - array;
280 if (idx < 0 || idx >= spec->paths.used)
281 return 0;
282 return idx + 1;
283}
Takashi Iwai4bd01e92013-01-22 15:17:20 +0100284EXPORT_SYMBOL_HDA(snd_hda_get_path_idx);
Takashi Iwai196c17662013-01-04 15:01:40 +0100285
286/* get the path instance corresponding to the given index number */
287struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx)
288{
289 struct hda_gen_spec *spec = codec->spec;
290
291 if (idx <= 0 || idx > spec->paths.used)
292 return NULL;
293 return snd_array_elem(&spec->paths, idx - 1);
294}
Takashi Iwai4bd01e92013-01-22 15:17:20 +0100295EXPORT_SYMBOL_HDA(snd_hda_get_path_from_idx);
Takashi Iwai196c17662013-01-04 15:01:40 +0100296
Takashi Iwai352f7f92012-12-19 12:52:06 +0100297/* check whether the given DAC is already found in any existing paths */
298static bool is_dac_already_used(struct hda_codec *codec, hda_nid_t nid)
299{
300 struct hda_gen_spec *spec = codec->spec;
301 int i;
302
303 for (i = 0; i < spec->paths.used; i++) {
304 struct nid_path *path = snd_array_elem(&spec->paths, i);
305 if (path->path[0] == nid)
306 return true;
307 }
308 return false;
309}
310
311/* check whether the given two widgets can be connected */
312static bool is_reachable_path(struct hda_codec *codec,
313 hda_nid_t from_nid, hda_nid_t to_nid)
314{
315 if (!from_nid || !to_nid)
316 return false;
317 return snd_hda_get_conn_index(codec, to_nid, from_nid, true) >= 0;
318}
319
320/* nid, dir and idx */
321#define AMP_VAL_COMPARE_MASK (0xffff | (1U << 18) | (0x0f << 19))
322
323/* check whether the given ctl is already assigned in any path elements */
324static bool is_ctl_used(struct hda_codec *codec, unsigned int val, int type)
325{
326 struct hda_gen_spec *spec = codec->spec;
327 int i;
328
329 val &= AMP_VAL_COMPARE_MASK;
330 for (i = 0; i < spec->paths.used; i++) {
331 struct nid_path *path = snd_array_elem(&spec->paths, i);
332 if ((path->ctls[type] & AMP_VAL_COMPARE_MASK) == val)
333 return true;
334 }
335 return false;
336}
337
338/* check whether a control with the given (nid, dir, idx) was assigned */
339static bool is_ctl_associated(struct hda_codec *codec, hda_nid_t nid,
Takashi Iwai8999bf02013-01-18 11:01:33 +0100340 int dir, int idx, int type)
Takashi Iwai352f7f92012-12-19 12:52:06 +0100341{
342 unsigned int val = HDA_COMPOSE_AMP_VAL(nid, 3, idx, dir);
Takashi Iwai8999bf02013-01-18 11:01:33 +0100343 return is_ctl_used(codec, val, type);
Takashi Iwai352f7f92012-12-19 12:52:06 +0100344}
345
Takashi Iwai0c8c0f52012-12-20 17:54:22 +0100346static void print_nid_path(const char *pfx, struct nid_path *path)
347{
348 char buf[40];
349 int i;
350
351
352 buf[0] = 0;
353 for (i = 0; i < path->depth; i++) {
354 char tmp[4];
355 sprintf(tmp, ":%02x", path->path[i]);
356 strlcat(buf, tmp, sizeof(buf));
357 }
358 snd_printdd("%s path: depth=%d %s\n", pfx, path->depth, buf);
359}
360
Takashi Iwai352f7f92012-12-19 12:52:06 +0100361/* called recursively */
362static bool __parse_nid_path(struct hda_codec *codec,
363 hda_nid_t from_nid, hda_nid_t to_nid,
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100364 int anchor_nid, struct nid_path *path,
365 int depth)
Takashi Iwai352f7f92012-12-19 12:52:06 +0100366{
Takashi Iwaiee8e7652013-01-03 15:25:11 +0100367 const hda_nid_t *conn;
Takashi Iwai352f7f92012-12-19 12:52:06 +0100368 int i, nums;
369
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100370 if (to_nid == anchor_nid)
371 anchor_nid = 0; /* anchor passed */
372 else if (to_nid == (hda_nid_t)(-anchor_nid))
373 return false; /* hit the exclusive nid */
Takashi Iwai352f7f92012-12-19 12:52:06 +0100374
Takashi Iwaiee8e7652013-01-03 15:25:11 +0100375 nums = snd_hda_get_conn_list(codec, to_nid, &conn);
Takashi Iwai352f7f92012-12-19 12:52:06 +0100376 for (i = 0; i < nums; i++) {
377 if (conn[i] != from_nid) {
378 /* special case: when from_nid is 0,
379 * try to find an empty DAC
380 */
381 if (from_nid ||
382 get_wcaps_type(get_wcaps(codec, conn[i])) != AC_WID_AUD_OUT ||
383 is_dac_already_used(codec, conn[i]))
384 continue;
385 }
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100386 /* anchor is not requested or already passed? */
387 if (anchor_nid <= 0)
Takashi Iwai352f7f92012-12-19 12:52:06 +0100388 goto found;
389 }
390 if (depth >= MAX_NID_PATH_DEPTH)
391 return false;
392 for (i = 0; i < nums; i++) {
393 unsigned int type;
394 type = get_wcaps_type(get_wcaps(codec, conn[i]));
395 if (type == AC_WID_AUD_OUT || type == AC_WID_AUD_IN ||
396 type == AC_WID_PIN)
397 continue;
398 if (__parse_nid_path(codec, from_nid, conn[i],
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100399 anchor_nid, path, depth + 1))
Takashi Iwai352f7f92012-12-19 12:52:06 +0100400 goto found;
401 }
402 return false;
403
404 found:
405 path->path[path->depth] = conn[i];
406 path->idx[path->depth + 1] = i;
407 if (nums > 1 && get_wcaps_type(get_wcaps(codec, to_nid)) != AC_WID_AUD_MIX)
408 path->multi[path->depth + 1] = 1;
409 path->depth++;
410 return true;
411}
412
413/* parse the widget path from the given nid to the target nid;
414 * when @from_nid is 0, try to find an empty DAC;
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100415 * when @anchor_nid is set to a positive value, only paths through the widget
416 * with the given value are evaluated.
417 * when @anchor_nid is set to a negative value, paths through the widget
418 * with the negative of given value are excluded, only other paths are chosen.
419 * when @anchor_nid is zero, no special handling about path selection.
Takashi Iwai352f7f92012-12-19 12:52:06 +0100420 */
421bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid,
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100422 hda_nid_t to_nid, int anchor_nid,
Takashi Iwai352f7f92012-12-19 12:52:06 +0100423 struct nid_path *path)
424{
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100425 if (__parse_nid_path(codec, from_nid, to_nid, anchor_nid, path, 1)) {
Takashi Iwai352f7f92012-12-19 12:52:06 +0100426 path->path[path->depth] = to_nid;
427 path->depth++;
Takashi Iwai352f7f92012-12-19 12:52:06 +0100428 return true;
429 }
430 return false;
431}
432EXPORT_SYMBOL_HDA(snd_hda_parse_nid_path);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433
434/*
Takashi Iwai352f7f92012-12-19 12:52:06 +0100435 * parse the path between the given NIDs and add to the path list.
436 * if no valid path is found, return NULL
Linus Torvalds1da177e2005-04-16 15:20:36 -0700437 */
Takashi Iwai352f7f92012-12-19 12:52:06 +0100438struct nid_path *
439snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid,
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100440 hda_nid_t to_nid, int anchor_nid)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441{
Takashi Iwai352f7f92012-12-19 12:52:06 +0100442 struct hda_gen_spec *spec = codec->spec;
443 struct nid_path *path;
444
445 if (from_nid && to_nid && !is_reachable_path(codec, from_nid, to_nid))
446 return NULL;
447
Takashi Iwaif5172a72013-01-04 13:19:55 +0100448 /* check whether the path has been already added */
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100449 path = get_nid_path(codec, from_nid, to_nid, anchor_nid);
Takashi Iwaif5172a72013-01-04 13:19:55 +0100450 if (path)
451 return path;
452
Takashi Iwai352f7f92012-12-19 12:52:06 +0100453 path = snd_array_new(&spec->paths);
454 if (!path)
455 return NULL;
456 memset(path, 0, sizeof(*path));
Takashi Iwai3ca529d2013-01-07 17:25:08 +0100457 if (snd_hda_parse_nid_path(codec, from_nid, to_nid, anchor_nid, path))
Takashi Iwai352f7f92012-12-19 12:52:06 +0100458 return path;
459 /* push back */
460 spec->paths.used--;
461 return NULL;
462}
463EXPORT_SYMBOL_HDA(snd_hda_add_new_path);
464
Takashi Iwai980428c2013-01-09 09:28:20 +0100465/* clear the given path as invalid so that it won't be picked up later */
466static void invalidate_nid_path(struct hda_codec *codec, int idx)
467{
468 struct nid_path *path = snd_hda_get_path_from_idx(codec, idx);
469 if (!path)
470 return;
471 memset(path, 0, sizeof(*path));
472}
473
Takashi Iwai352f7f92012-12-19 12:52:06 +0100474/* look for an empty DAC slot */
475static hda_nid_t look_for_dac(struct hda_codec *codec, hda_nid_t pin,
476 bool is_digital)
477{
478 struct hda_gen_spec *spec = codec->spec;
479 bool cap_digital;
480 int i;
481
482 for (i = 0; i < spec->num_all_dacs; i++) {
483 hda_nid_t nid = spec->all_dacs[i];
484 if (!nid || is_dac_already_used(codec, nid))
485 continue;
486 cap_digital = !!(get_wcaps(codec, nid) & AC_WCAP_DIGITAL);
487 if (is_digital != cap_digital)
488 continue;
489 if (is_reachable_path(codec, nid, pin))
490 return nid;
491 }
492 return 0;
493}
494
495/* replace the channels in the composed amp value with the given number */
496static unsigned int amp_val_replace_channels(unsigned int val, unsigned int chs)
497{
498 val &= ~(0x3U << 16);
499 val |= chs << 16;
500 return val;
501}
502
503/* check whether the widget has the given amp capability for the direction */
504static bool check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
505 int dir, unsigned int bits)
506{
507 if (!nid)
508 return false;
509 if (get_wcaps(codec, nid) & (1 << (dir + 1)))
510 if (query_amp_caps(codec, nid, dir) & bits)
511 return true;
512 return false;
513}
514
David Henningsson99a55922013-01-16 15:58:44 +0100515static bool same_amp_caps(struct hda_codec *codec, hda_nid_t nid1,
516 hda_nid_t nid2, int dir)
517{
518 if (!(get_wcaps(codec, nid1) & (1 << (dir + 1))))
519 return !(get_wcaps(codec, nid2) & (1 << (dir + 1)));
520 return (query_amp_caps(codec, nid1, dir) ==
521 query_amp_caps(codec, nid2, dir));
522}
523
Takashi Iwai352f7f92012-12-19 12:52:06 +0100524#define nid_has_mute(codec, nid, dir) \
525 check_amp_caps(codec, nid, dir, AC_AMPCAP_MUTE)
526#define nid_has_volume(codec, nid, dir) \
527 check_amp_caps(codec, nid, dir, AC_AMPCAP_NUM_STEPS)
528
529/* look for a widget suitable for assigning a mute switch in the path */
530static hda_nid_t look_for_out_mute_nid(struct hda_codec *codec,
531 struct nid_path *path)
532{
533 int i;
534
535 for (i = path->depth - 1; i >= 0; i--) {
536 if (nid_has_mute(codec, path->path[i], HDA_OUTPUT))
537 return path->path[i];
538 if (i != path->depth - 1 && i != 0 &&
539 nid_has_mute(codec, path->path[i], HDA_INPUT))
540 return path->path[i];
541 }
542 return 0;
543}
544
545/* look for a widget suitable for assigning a volume ctl in the path */
546static hda_nid_t look_for_out_vol_nid(struct hda_codec *codec,
547 struct nid_path *path)
548{
549 int i;
550
551 for (i = path->depth - 1; i >= 0; i--) {
552 if (nid_has_volume(codec, path->path[i], HDA_OUTPUT))
553 return path->path[i];
554 }
Takashi Iwai82beb8f2007-08-10 17:09:26 +0200555 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700556}
557
558/*
Takashi Iwai352f7f92012-12-19 12:52:06 +0100559 * path activation / deactivation
Linus Torvalds1da177e2005-04-16 15:20:36 -0700560 */
Takashi Iwai352f7f92012-12-19 12:52:06 +0100561
562/* can have the amp-in capability? */
563static bool has_amp_in(struct hda_codec *codec, struct nid_path *path, int idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564{
Takashi Iwai352f7f92012-12-19 12:52:06 +0100565 hda_nid_t nid = path->path[idx];
566 unsigned int caps = get_wcaps(codec, nid);
567 unsigned int type = get_wcaps_type(caps);
568
569 if (!(caps & AC_WCAP_IN_AMP))
570 return false;
571 if (type == AC_WID_PIN && idx > 0) /* only for input pins */
572 return false;
573 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700574}
575
Takashi Iwai352f7f92012-12-19 12:52:06 +0100576/* can have the amp-out capability? */
577static bool has_amp_out(struct hda_codec *codec, struct nid_path *path, int idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700578{
Takashi Iwai352f7f92012-12-19 12:52:06 +0100579 hda_nid_t nid = path->path[idx];
580 unsigned int caps = get_wcaps(codec, nid);
581 unsigned int type = get_wcaps_type(caps);
582
583 if (!(caps & AC_WCAP_OUT_AMP))
584 return false;
585 if (type == AC_WID_PIN && !idx) /* only for output pins */
586 return false;
587 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700588}
589
Takashi Iwai352f7f92012-12-19 12:52:06 +0100590/* check whether the given (nid,dir,idx) is active */
591static bool is_active_nid(struct hda_codec *codec, hda_nid_t nid,
Takashi Iwai7dddf2ae2013-01-24 16:31:35 +0100592 unsigned int dir, unsigned int idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593{
Takashi Iwai352f7f92012-12-19 12:52:06 +0100594 struct hda_gen_spec *spec = codec->spec;
595 int i, n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700596
Takashi Iwai352f7f92012-12-19 12:52:06 +0100597 for (n = 0; n < spec->paths.used; n++) {
598 struct nid_path *path = snd_array_elem(&spec->paths, n);
599 if (!path->active)
600 continue;
601 for (i = 0; i < path->depth; i++) {
602 if (path->path[i] == nid) {
603 if (dir == HDA_OUTPUT || path->idx[i] == idx)
604 return true;
605 break;
606 }
607 }
608 }
609 return false;
610}
611
Takashi Iwaib1b9fbd2013-05-14 12:58:47 +0200612/* check whether the NID is referred by any active paths */
613#define is_active_nid_for_any(codec, nid) \
614 is_active_nid(codec, nid, HDA_OUTPUT, 0)
615
Takashi Iwai352f7f92012-12-19 12:52:06 +0100616/* get the default amp value for the target state */
617static int get_amp_val_to_activate(struct hda_codec *codec, hda_nid_t nid,
Takashi Iwai8999bf02013-01-18 11:01:33 +0100618 int dir, unsigned int caps, bool enable)
Takashi Iwai352f7f92012-12-19 12:52:06 +0100619{
Takashi Iwai352f7f92012-12-19 12:52:06 +0100620 unsigned int val = 0;
621
Takashi Iwai352f7f92012-12-19 12:52:06 +0100622 if (caps & AC_AMPCAP_NUM_STEPS) {
623 /* set to 0dB */
624 if (enable)
625 val = (caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT;
626 }
627 if (caps & AC_AMPCAP_MUTE) {
628 if (!enable)
629 val |= HDA_AMP_MUTE;
630 }
631 return val;
632}
633
634/* initialize the amp value (only at the first time) */
635static void init_amp(struct hda_codec *codec, hda_nid_t nid, int dir, int idx)
636{
Takashi Iwai8999bf02013-01-18 11:01:33 +0100637 unsigned int caps = query_amp_caps(codec, nid, dir);
638 int val = get_amp_val_to_activate(codec, nid, dir, caps, false);
Takashi Iwai352f7f92012-12-19 12:52:06 +0100639 snd_hda_codec_amp_init_stereo(codec, nid, dir, idx, 0xff, val);
640}
641
Takashi Iwai8999bf02013-01-18 11:01:33 +0100642/* calculate amp value mask we can modify;
643 * if the given amp is controlled by mixers, don't touch it
644 */
645static unsigned int get_amp_mask_to_modify(struct hda_codec *codec,
646 hda_nid_t nid, int dir, int idx,
647 unsigned int caps)
Takashi Iwai352f7f92012-12-19 12:52:06 +0100648{
Takashi Iwai8999bf02013-01-18 11:01:33 +0100649 unsigned int mask = 0xff;
650
651 if (caps & AC_AMPCAP_MUTE) {
652 if (is_ctl_associated(codec, nid, dir, idx, NID_PATH_MUTE_CTL))
653 mask &= ~0x80;
654 }
655 if (caps & AC_AMPCAP_NUM_STEPS) {
656 if (is_ctl_associated(codec, nid, dir, idx, NID_PATH_VOL_CTL) ||
657 is_ctl_associated(codec, nid, dir, idx, NID_PATH_BOOST_CTL))
658 mask &= ~0x7f;
659 }
660 return mask;
661}
662
663static void activate_amp(struct hda_codec *codec, hda_nid_t nid, int dir,
664 int idx, int idx_to_check, bool enable)
665{
666 unsigned int caps;
667 unsigned int mask, val;
668
Takashi Iwai7dddf2ae2013-01-24 16:31:35 +0100669 if (!enable && is_active_nid(codec, nid, dir, idx_to_check))
Takashi Iwai352f7f92012-12-19 12:52:06 +0100670 return;
Takashi Iwai8999bf02013-01-18 11:01:33 +0100671
672 caps = query_amp_caps(codec, nid, dir);
673 val = get_amp_val_to_activate(codec, nid, dir, caps, enable);
674 mask = get_amp_mask_to_modify(codec, nid, dir, idx_to_check, caps);
675 if (!mask)
676 return;
677
678 val &= mask;
679 snd_hda_codec_amp_stereo(codec, nid, dir, idx, mask, val);
Takashi Iwai352f7f92012-12-19 12:52:06 +0100680}
681
682static void activate_amp_out(struct hda_codec *codec, struct nid_path *path,
683 int i, bool enable)
684{
685 hda_nid_t nid = path->path[i];
686 init_amp(codec, nid, HDA_OUTPUT, 0);
Takashi Iwai8999bf02013-01-18 11:01:33 +0100687 activate_amp(codec, nid, HDA_OUTPUT, 0, 0, enable);
Takashi Iwai352f7f92012-12-19 12:52:06 +0100688}
689
690static void activate_amp_in(struct hda_codec *codec, struct nid_path *path,
691 int i, bool enable, bool add_aamix)
692{
693 struct hda_gen_spec *spec = codec->spec;
Takashi Iwaiee8e7652013-01-03 15:25:11 +0100694 const hda_nid_t *conn;
Takashi Iwai352f7f92012-12-19 12:52:06 +0100695 int n, nums, idx;
696 int type;
697 hda_nid_t nid = path->path[i];
698
Takashi Iwaiee8e7652013-01-03 15:25:11 +0100699 nums = snd_hda_get_conn_list(codec, nid, &conn);
Takashi Iwai352f7f92012-12-19 12:52:06 +0100700 type = get_wcaps_type(get_wcaps(codec, nid));
701 if (type == AC_WID_PIN ||
702 (type == AC_WID_AUD_IN && codec->single_adc_amp)) {
703 nums = 1;
704 idx = 0;
705 } else
706 idx = path->idx[i];
707
708 for (n = 0; n < nums; n++)
709 init_amp(codec, nid, HDA_INPUT, n);
710
Takashi Iwai352f7f92012-12-19 12:52:06 +0100711 /* here is a little bit tricky in comparison with activate_amp_out();
712 * when aa-mixer is available, we need to enable the path as well
713 */
714 for (n = 0; n < nums; n++) {
Takashi Iwaie4a395e2013-01-23 17:00:31 +0100715 if (n != idx && (!add_aamix || conn[n] != spec->mixer_merge_nid))
Takashi Iwai352f7f92012-12-19 12:52:06 +0100716 continue;
Takashi Iwai8999bf02013-01-18 11:01:33 +0100717 activate_amp(codec, nid, HDA_INPUT, n, idx, enable);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700718 }
719}
720
Takashi Iwai352f7f92012-12-19 12:52:06 +0100721/* activate or deactivate the given path
722 * if @add_aamix is set, enable the input from aa-mix NID as well (if any)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700723 */
Takashi Iwai352f7f92012-12-19 12:52:06 +0100724void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path,
725 bool enable, bool add_aamix)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726{
Takashi Iwai55196ff2013-01-24 17:32:56 +0100727 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai352f7f92012-12-19 12:52:06 +0100728 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729
Takashi Iwai352f7f92012-12-19 12:52:06 +0100730 if (!enable)
731 path->active = false;
732
733 for (i = path->depth - 1; i >= 0; i--) {
Takashi Iwai55196ff2013-01-24 17:32:56 +0100734 hda_nid_t nid = path->path[i];
735 if (enable && spec->power_down_unused) {
736 /* make sure the widget is powered up */
737 if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D0))
738 snd_hda_codec_write(codec, nid, 0,
739 AC_VERB_SET_POWER_STATE,
740 AC_PWRST_D0);
741 }
Takashi Iwai352f7f92012-12-19 12:52:06 +0100742 if (enable && path->multi[i])
Takashi Iwai55196ff2013-01-24 17:32:56 +0100743 snd_hda_codec_write_cache(codec, nid, 0,
Takashi Iwai352f7f92012-12-19 12:52:06 +0100744 AC_VERB_SET_CONNECT_SEL,
745 path->idx[i]);
746 if (has_amp_in(codec, path, i))
747 activate_amp_in(codec, path, i, enable, add_aamix);
748 if (has_amp_out(codec, path, i))
749 activate_amp_out(codec, path, i, enable);
750 }
751
752 if (enable)
753 path->active = true;
754}
755EXPORT_SYMBOL_HDA(snd_hda_activate_path);
756
Takashi Iwai55196ff2013-01-24 17:32:56 +0100757/* if the given path is inactive, put widgets into D3 (only if suitable) */
758static void path_power_down_sync(struct hda_codec *codec, struct nid_path *path)
759{
760 struct hda_gen_spec *spec = codec->spec;
Jiri Slaby868211d2013-04-04 22:32:10 +0200761 bool changed = false;
Takashi Iwai55196ff2013-01-24 17:32:56 +0100762 int i;
763
764 if (!spec->power_down_unused || path->active)
765 return;
766
767 for (i = 0; i < path->depth; i++) {
768 hda_nid_t nid = path->path[i];
Takashi Iwaib1b9fbd2013-05-14 12:58:47 +0200769 if (!snd_hda_check_power_state(codec, nid, AC_PWRST_D3) &&
770 !is_active_nid_for_any(codec, nid)) {
Takashi Iwai55196ff2013-01-24 17:32:56 +0100771 snd_hda_codec_write(codec, nid, 0,
772 AC_VERB_SET_POWER_STATE,
773 AC_PWRST_D3);
774 changed = true;
775 }
776 }
777
778 if (changed) {
779 msleep(10);
780 snd_hda_codec_read(codec, path->path[0], 0,
781 AC_VERB_GET_POWER_STATE, 0);
782 }
783}
784
Takashi Iwaid5a9f1b2012-12-20 15:36:30 +0100785/* turn on/off EAPD on the given pin */
786static void set_pin_eapd(struct hda_codec *codec, hda_nid_t pin, bool enable)
787{
788 struct hda_gen_spec *spec = codec->spec;
789 if (spec->own_eapd_ctl ||
790 !(snd_hda_query_pin_caps(codec, pin) & AC_PINCAP_EAPD))
791 return;
Takashi Iwaiecac3ed2012-12-21 15:23:01 +0100792 if (codec->inv_eapd)
793 enable = !enable;
Takashi Iwai05909d5c2013-05-31 19:55:54 +0200794 if (spec->keep_eapd_on && !enable)
795 return;
Takashi Iwaid5a9f1b2012-12-20 15:36:30 +0100796 snd_hda_codec_update_cache(codec, pin, 0,
797 AC_VERB_SET_EAPD_BTLENABLE,
798 enable ? 0x02 : 0x00);
799}
800
Takashi Iwai3e367f12013-01-23 17:07:23 +0100801/* re-initialize the path specified by the given path index */
802static void resume_path_from_idx(struct hda_codec *codec, int path_idx)
803{
804 struct nid_path *path = snd_hda_get_path_from_idx(codec, path_idx);
805 if (path)
806 snd_hda_activate_path(codec, path, path->active, false);
807}
808
Takashi Iwai352f7f92012-12-19 12:52:06 +0100809
810/*
811 * Helper functions for creating mixer ctl elements
812 */
813
Takashi Iwai7eebffd2013-06-24 16:00:21 +0200814static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
815 struct snd_ctl_elem_value *ucontrol);
816
Takashi Iwai352f7f92012-12-19 12:52:06 +0100817enum {
818 HDA_CTL_WIDGET_VOL,
819 HDA_CTL_WIDGET_MUTE,
820 HDA_CTL_BIND_MUTE,
Takashi Iwai352f7f92012-12-19 12:52:06 +0100821};
822static const struct snd_kcontrol_new control_templates[] = {
823 HDA_CODEC_VOLUME(NULL, 0, 0, 0),
Takashi Iwai7eebffd2013-06-24 16:00:21 +0200824 /* only the put callback is replaced for handling the special mute */
825 {
826 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
827 .subdevice = HDA_SUBDEV_AMP_FLAG,
828 .info = snd_hda_mixer_amp_switch_info,
829 .get = snd_hda_mixer_amp_switch_get,
830 .put = hda_gen_mixer_mute_put, /* replaced */
831 .private_value = HDA_COMPOSE_AMP_VAL(0, 3, 0, 0),
832 },
Takashi Iwai352f7f92012-12-19 12:52:06 +0100833 HDA_BIND_MUTE(NULL, 0, 0, 0),
Takashi Iwai352f7f92012-12-19 12:52:06 +0100834};
835
836/* add dynamic controls from template */
Takashi Iwaia35bd1e2013-01-18 14:01:14 +0100837static struct snd_kcontrol_new *
838add_control(struct hda_gen_spec *spec, int type, const char *name,
Takashi Iwai352f7f92012-12-19 12:52:06 +0100839 int cidx, unsigned long val)
840{
841 struct snd_kcontrol_new *knew;
842
Takashi Iwai12c93df2012-12-19 14:38:33 +0100843 knew = snd_hda_gen_add_kctl(spec, name, &control_templates[type]);
Takashi Iwai352f7f92012-12-19 12:52:06 +0100844 if (!knew)
Takashi Iwaia35bd1e2013-01-18 14:01:14 +0100845 return NULL;
Takashi Iwai352f7f92012-12-19 12:52:06 +0100846 knew->index = cidx;
847 if (get_amp_nid_(val))
848 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
849 knew->private_value = val;
Takashi Iwaia35bd1e2013-01-18 14:01:14 +0100850 return knew;
Takashi Iwai352f7f92012-12-19 12:52:06 +0100851}
852
853static int add_control_with_pfx(struct hda_gen_spec *spec, int type,
854 const char *pfx, const char *dir,
855 const char *sfx, int cidx, unsigned long val)
856{
Takashi Iwai975cc022013-06-28 11:56:49 +0200857 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
Takashi Iwai352f7f92012-12-19 12:52:06 +0100858 snprintf(name, sizeof(name), "%s %s %s", pfx, dir, sfx);
Takashi Iwaia35bd1e2013-01-18 14:01:14 +0100859 if (!add_control(spec, type, name, cidx, val))
860 return -ENOMEM;
861 return 0;
Takashi Iwai352f7f92012-12-19 12:52:06 +0100862}
863
864#define add_pb_vol_ctrl(spec, type, pfx, val) \
865 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", 0, val)
866#define add_pb_sw_ctrl(spec, type, pfx, val) \
867 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", 0, val)
868#define __add_pb_vol_ctrl(spec, type, pfx, cidx, val) \
869 add_control_with_pfx(spec, type, pfx, "Playback", "Volume", cidx, val)
870#define __add_pb_sw_ctrl(spec, type, pfx, cidx, val) \
871 add_control_with_pfx(spec, type, pfx, "Playback", "Switch", cidx, val)
872
873static int add_vol_ctl(struct hda_codec *codec, const char *pfx, int cidx,
874 unsigned int chs, struct nid_path *path)
875{
876 unsigned int val;
877 if (!path)
878 return 0;
879 val = path->ctls[NID_PATH_VOL_CTL];
880 if (!val)
881 return 0;
882 val = amp_val_replace_channels(val, chs);
883 return __add_pb_vol_ctrl(codec->spec, HDA_CTL_WIDGET_VOL, pfx, cidx, val);
884}
885
886/* return the channel bits suitable for the given path->ctls[] */
887static int get_default_ch_nums(struct hda_codec *codec, struct nid_path *path,
888 int type)
889{
890 int chs = 1; /* mono (left only) */
891 if (path) {
892 hda_nid_t nid = get_amp_nid_(path->ctls[type]);
893 if (nid && (get_wcaps(codec, nid) & AC_WCAP_STEREO))
894 chs = 3; /* stereo */
895 }
896 return chs;
897}
898
899static int add_stereo_vol(struct hda_codec *codec, const char *pfx, int cidx,
900 struct nid_path *path)
901{
902 int chs = get_default_ch_nums(codec, path, NID_PATH_VOL_CTL);
903 return add_vol_ctl(codec, pfx, cidx, chs, path);
904}
905
906/* create a mute-switch for the given mixer widget;
907 * if it has multiple sources (e.g. DAC and loopback), create a bind-mute
908 */
909static int add_sw_ctl(struct hda_codec *codec, const char *pfx, int cidx,
910 unsigned int chs, struct nid_path *path)
911{
912 unsigned int val;
913 int type = HDA_CTL_WIDGET_MUTE;
914
915 if (!path)
916 return 0;
917 val = path->ctls[NID_PATH_MUTE_CTL];
918 if (!val)
919 return 0;
920 val = amp_val_replace_channels(val, chs);
921 if (get_amp_direction_(val) == HDA_INPUT) {
922 hda_nid_t nid = get_amp_nid_(val);
923 int nums = snd_hda_get_num_conns(codec, nid);
924 if (nums > 1) {
925 type = HDA_CTL_BIND_MUTE;
926 val |= nums << 19;
927 }
928 }
929 return __add_pb_sw_ctrl(codec->spec, type, pfx, cidx, val);
930}
931
932static int add_stereo_sw(struct hda_codec *codec, const char *pfx,
933 int cidx, struct nid_path *path)
934{
935 int chs = get_default_ch_nums(codec, path, NID_PATH_MUTE_CTL);
936 return add_sw_ctl(codec, pfx, cidx, chs, path);
937}
938
Takashi Iwai7eebffd2013-06-24 16:00:21 +0200939/* playback mute control with the software mute bit check */
940static int hda_gen_mixer_mute_put(struct snd_kcontrol *kcontrol,
941 struct snd_ctl_elem_value *ucontrol)
942{
943 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
944 struct hda_gen_spec *spec = codec->spec;
945
946 if (spec->auto_mute_via_amp) {
947 hda_nid_t nid = get_amp_nid(kcontrol);
948 bool enabled = !((spec->mute_bits >> nid) & 1);
949 ucontrol->value.integer.value[0] &= enabled;
950 ucontrol->value.integer.value[1] &= enabled;
951 }
952
953 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
954}
955
Takashi Iwai247d85e2013-01-17 16:18:11 +0100956/* any ctl assigned to the path with the given index? */
957static bool path_has_mixer(struct hda_codec *codec, int path_idx, int ctl_type)
958{
959 struct nid_path *path = snd_hda_get_path_from_idx(codec, path_idx);
960 return path && path->ctls[ctl_type];
961}
962
Takashi Iwai352f7f92012-12-19 12:52:06 +0100963static const char * const channel_name[4] = {
964 "Front", "Surround", "CLFE", "Side"
965};
966
967/* give some appropriate ctl name prefix for the given line out channel */
Takashi Iwai247d85e2013-01-17 16:18:11 +0100968static const char *get_line_out_pfx(struct hda_codec *codec, int ch,
969 int *index, int ctl_type)
Takashi Iwai352f7f92012-12-19 12:52:06 +0100970{
Takashi Iwai247d85e2013-01-17 16:18:11 +0100971 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai352f7f92012-12-19 12:52:06 +0100972 struct auto_pin_cfg *cfg = &spec->autocfg;
973
974 *index = 0;
975 if (cfg->line_outs == 1 && !spec->multi_ios &&
Takashi Iwai247d85e2013-01-17 16:18:11 +0100976 !cfg->hp_outs && !cfg->speaker_outs)
Takashi Iwai352f7f92012-12-19 12:52:06 +0100977 return spec->vmaster_mute.hook ? "PCM" : "Master";
978
979 /* if there is really a single DAC used in the whole output paths,
980 * use it master (or "PCM" if a vmaster hook is present)
981 */
982 if (spec->multiout.num_dacs == 1 && !spec->mixer_nid &&
983 !spec->multiout.hp_out_nid[0] && !spec->multiout.extra_out_nid[0])
984 return spec->vmaster_mute.hook ? "PCM" : "Master";
985
Takashi Iwai247d85e2013-01-17 16:18:11 +0100986 /* multi-io channels */
987 if (ch >= cfg->line_outs)
988 return channel_name[ch];
989
Takashi Iwai352f7f92012-12-19 12:52:06 +0100990 switch (cfg->line_out_type) {
991 case AUTO_PIN_SPEAKER_OUT:
Takashi Iwai247d85e2013-01-17 16:18:11 +0100992 /* if the primary channel vol/mute is shared with HP volume,
993 * don't name it as Speaker
994 */
995 if (!ch && cfg->hp_outs &&
996 !path_has_mixer(codec, spec->hp_paths[0], ctl_type))
997 break;
Takashi Iwai352f7f92012-12-19 12:52:06 +0100998 if (cfg->line_outs == 1)
999 return "Speaker";
1000 if (cfg->line_outs == 2)
1001 return ch ? "Bass Speaker" : "Speaker";
1002 break;
1003 case AUTO_PIN_HP_OUT:
Takashi Iwai247d85e2013-01-17 16:18:11 +01001004 /* if the primary channel vol/mute is shared with spk volume,
1005 * don't name it as Headphone
1006 */
1007 if (!ch && cfg->speaker_outs &&
1008 !path_has_mixer(codec, spec->speaker_paths[0], ctl_type))
1009 break;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001010 /* for multi-io case, only the primary out */
1011 if (ch && spec->multi_ios)
1012 break;
1013 *index = ch;
1014 return "Headphone";
Takashi Iwai352f7f92012-12-19 12:52:06 +01001015 }
Takashi Iwai247d85e2013-01-17 16:18:11 +01001016
1017 /* for a single channel output, we don't have to name the channel */
1018 if (cfg->line_outs == 1 && !spec->multi_ios)
1019 return "PCM";
1020
Takashi Iwai352f7f92012-12-19 12:52:06 +01001021 if (ch >= ARRAY_SIZE(channel_name)) {
1022 snd_BUG();
1023 return "PCM";
1024 }
1025
1026 return channel_name[ch];
1027}
1028
1029/*
1030 * Parse output paths
1031 */
1032
1033/* badness definition */
1034enum {
1035 /* No primary DAC is found for the main output */
1036 BAD_NO_PRIMARY_DAC = 0x10000,
1037 /* No DAC is found for the extra output */
1038 BAD_NO_DAC = 0x4000,
1039 /* No possible multi-ios */
Takashi Iwai1d739062013-02-13 14:17:32 +01001040 BAD_MULTI_IO = 0x120,
Takashi Iwai352f7f92012-12-19 12:52:06 +01001041 /* No individual DAC for extra output */
1042 BAD_NO_EXTRA_DAC = 0x102,
1043 /* No individual DAC for extra surrounds */
1044 BAD_NO_EXTRA_SURR_DAC = 0x101,
1045 /* Primary DAC shared with main surrounds */
1046 BAD_SHARED_SURROUND = 0x100,
Takashi Iwai55a63d42013-03-21 17:20:12 +01001047 /* No independent HP possible */
Takashi Iwaibec8e682013-03-22 15:10:08 +01001048 BAD_NO_INDEP_HP = 0x10,
Takashi Iwai352f7f92012-12-19 12:52:06 +01001049 /* Primary DAC shared with main CLFE */
1050 BAD_SHARED_CLFE = 0x10,
1051 /* Primary DAC shared with extra surrounds */
1052 BAD_SHARED_EXTRA_SURROUND = 0x10,
1053 /* Volume widget is shared */
1054 BAD_SHARED_VOL = 0x10,
1055};
1056
Takashi Iwai0e614dd2013-01-07 15:11:44 +01001057/* look for widgets in the given path which are appropriate for
Takashi Iwai352f7f92012-12-19 12:52:06 +01001058 * volume and mute controls, and assign the values to ctls[].
1059 *
1060 * When no appropriate widget is found in the path, the badness value
1061 * is incremented depending on the situation. The function returns the
1062 * total badness for both volume and mute controls.
1063 */
Takashi Iwai0e614dd2013-01-07 15:11:44 +01001064static int assign_out_path_ctls(struct hda_codec *codec, struct nid_path *path)
Takashi Iwai352f7f92012-12-19 12:52:06 +01001065{
Takashi Iwai352f7f92012-12-19 12:52:06 +01001066 hda_nid_t nid;
1067 unsigned int val;
1068 int badness = 0;
1069
1070 if (!path)
1071 return BAD_SHARED_VOL * 2;
Takashi Iwai0e614dd2013-01-07 15:11:44 +01001072
1073 if (path->ctls[NID_PATH_VOL_CTL] ||
1074 path->ctls[NID_PATH_MUTE_CTL])
1075 return 0; /* already evaluated */
1076
Takashi Iwai352f7f92012-12-19 12:52:06 +01001077 nid = look_for_out_vol_nid(codec, path);
1078 if (nid) {
1079 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
1080 if (is_ctl_used(codec, val, NID_PATH_VOL_CTL))
1081 badness += BAD_SHARED_VOL;
1082 else
1083 path->ctls[NID_PATH_VOL_CTL] = val;
1084 } else
1085 badness += BAD_SHARED_VOL;
1086 nid = look_for_out_mute_nid(codec, path);
1087 if (nid) {
1088 unsigned int wid_type = get_wcaps_type(get_wcaps(codec, nid));
1089 if (wid_type == AC_WID_PIN || wid_type == AC_WID_AUD_OUT ||
1090 nid_has_mute(codec, nid, HDA_OUTPUT))
1091 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
1092 else
1093 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_INPUT);
1094 if (is_ctl_used(codec, val, NID_PATH_MUTE_CTL))
1095 badness += BAD_SHARED_VOL;
1096 else
1097 path->ctls[NID_PATH_MUTE_CTL] = val;
1098 } else
1099 badness += BAD_SHARED_VOL;
1100 return badness;
1101}
1102
Takashi Iwai98bd1112013-03-22 14:53:50 +01001103const struct badness_table hda_main_out_badness = {
Takashi Iwai352f7f92012-12-19 12:52:06 +01001104 .no_primary_dac = BAD_NO_PRIMARY_DAC,
1105 .no_dac = BAD_NO_DAC,
1106 .shared_primary = BAD_NO_PRIMARY_DAC,
1107 .shared_surr = BAD_SHARED_SURROUND,
1108 .shared_clfe = BAD_SHARED_CLFE,
1109 .shared_surr_main = BAD_SHARED_SURROUND,
1110};
Takashi Iwai98bd1112013-03-22 14:53:50 +01001111EXPORT_SYMBOL_HDA(hda_main_out_badness);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001112
Takashi Iwai98bd1112013-03-22 14:53:50 +01001113const struct badness_table hda_extra_out_badness = {
Takashi Iwai352f7f92012-12-19 12:52:06 +01001114 .no_primary_dac = BAD_NO_DAC,
1115 .no_dac = BAD_NO_DAC,
1116 .shared_primary = BAD_NO_EXTRA_DAC,
1117 .shared_surr = BAD_SHARED_EXTRA_SURROUND,
1118 .shared_clfe = BAD_SHARED_EXTRA_SURROUND,
1119 .shared_surr_main = BAD_NO_EXTRA_SURR_DAC,
1120};
Takashi Iwai98bd1112013-03-22 14:53:50 +01001121EXPORT_SYMBOL_HDA(hda_extra_out_badness);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001122
Takashi Iwai7385df62013-01-07 09:50:52 +01001123/* get the DAC of the primary output corresponding to the given array index */
1124static hda_nid_t get_primary_out(struct hda_codec *codec, int idx)
1125{
1126 struct hda_gen_spec *spec = codec->spec;
1127 struct auto_pin_cfg *cfg = &spec->autocfg;
1128
1129 if (cfg->line_outs > idx)
1130 return spec->private_dac_nids[idx];
1131 idx -= cfg->line_outs;
1132 if (spec->multi_ios > idx)
1133 return spec->multi_io[idx].dac;
1134 return 0;
1135}
1136
1137/* return the DAC if it's reachable, otherwise zero */
1138static inline hda_nid_t try_dac(struct hda_codec *codec,
1139 hda_nid_t dac, hda_nid_t pin)
1140{
1141 return is_reachable_path(codec, dac, pin) ? dac : 0;
1142}
1143
Takashi Iwai352f7f92012-12-19 12:52:06 +01001144/* try to assign DACs to pins and return the resultant badness */
1145static int try_assign_dacs(struct hda_codec *codec, int num_outs,
1146 const hda_nid_t *pins, hda_nid_t *dacs,
Takashi Iwai196c17662013-01-04 15:01:40 +01001147 int *path_idx,
Takashi Iwai352f7f92012-12-19 12:52:06 +01001148 const struct badness_table *bad)
1149{
1150 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001151 int i, j;
1152 int badness = 0;
1153 hda_nid_t dac;
1154
1155 if (!num_outs)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001156 return 0;
1157
Takashi Iwai352f7f92012-12-19 12:52:06 +01001158 for (i = 0; i < num_outs; i++) {
Takashi Iwai0c8c0f52012-12-20 17:54:22 +01001159 struct nid_path *path;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001160 hda_nid_t pin = pins[i];
Takashi Iwai1e0b5282013-01-04 12:56:52 +01001161
Takashi Iwai0e614dd2013-01-07 15:11:44 +01001162 path = snd_hda_get_path_from_idx(codec, path_idx[i]);
1163 if (path) {
1164 badness += assign_out_path_ctls(codec, path);
Takashi Iwai1e0b5282013-01-04 12:56:52 +01001165 continue;
1166 }
1167
1168 dacs[i] = look_for_dac(codec, pin, false);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001169 if (!dacs[i] && !i) {
Takashi Iwai980428c2013-01-09 09:28:20 +01001170 /* try to steal the DAC of surrounds for the front */
Takashi Iwai352f7f92012-12-19 12:52:06 +01001171 for (j = 1; j < num_outs; j++) {
1172 if (is_reachable_path(codec, dacs[j], pin)) {
1173 dacs[0] = dacs[j];
1174 dacs[j] = 0;
Takashi Iwai980428c2013-01-09 09:28:20 +01001175 invalidate_nid_path(codec, path_idx[j]);
Takashi Iwai196c17662013-01-04 15:01:40 +01001176 path_idx[j] = 0;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001177 break;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001178 }
1179 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01001180 }
1181 dac = dacs[i];
1182 if (!dac) {
Takashi Iwai7385df62013-01-07 09:50:52 +01001183 if (num_outs > 2)
1184 dac = try_dac(codec, get_primary_out(codec, i), pin);
1185 if (!dac)
1186 dac = try_dac(codec, dacs[0], pin);
1187 if (!dac)
1188 dac = try_dac(codec, get_primary_out(codec, i), pin);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001189 if (dac) {
1190 if (!i)
1191 badness += bad->shared_primary;
1192 else if (i == 1)
1193 badness += bad->shared_surr;
1194 else
1195 badness += bad->shared_clfe;
1196 } else if (is_reachable_path(codec, spec->private_dac_nids[0], pin)) {
1197 dac = spec->private_dac_nids[0];
1198 badness += bad->shared_surr_main;
1199 } else if (!i)
1200 badness += bad->no_primary_dac;
1201 else
1202 badness += bad->no_dac;
1203 }
Takashi Iwai1fa335b2013-01-21 11:43:19 +01001204 if (!dac)
1205 continue;
Takashi Iwai3ca529d2013-01-07 17:25:08 +01001206 path = snd_hda_add_new_path(codec, dac, pin, -spec->mixer_nid);
Takashi Iwai117688a2013-01-04 15:41:41 +01001207 if (!path && !i && spec->mixer_nid) {
Takashi Iwaib3a8c742012-12-20 18:29:16 +01001208 /* try with aamix */
Takashi Iwai3ca529d2013-01-07 17:25:08 +01001209 path = snd_hda_add_new_path(codec, dac, pin, 0);
Takashi Iwaib3a8c742012-12-20 18:29:16 +01001210 }
Takashi Iwai1fa335b2013-01-21 11:43:19 +01001211 if (!path) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01001212 dac = dacs[i] = 0;
Takashi Iwai1fa335b2013-01-21 11:43:19 +01001213 badness += bad->no_dac;
1214 } else {
Takashi Iwaia7694092013-01-21 10:43:18 +01001215 /* print_nid_path("output", path); */
Takashi Iwaie1284af2013-01-03 16:33:02 +01001216 path->active = true;
Takashi Iwai196c17662013-01-04 15:01:40 +01001217 path_idx[i] = snd_hda_get_path_idx(codec, path);
Takashi Iwai0e614dd2013-01-07 15:11:44 +01001218 badness += assign_out_path_ctls(codec, path);
Takashi Iwaie1284af2013-01-03 16:33:02 +01001219 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01001220 }
1221
1222 return badness;
1223}
1224
1225/* return NID if the given pin has only a single connection to a certain DAC */
1226static hda_nid_t get_dac_if_single(struct hda_codec *codec, hda_nid_t pin)
1227{
1228 struct hda_gen_spec *spec = codec->spec;
1229 int i;
1230 hda_nid_t nid_found = 0;
1231
1232 for (i = 0; i < spec->num_all_dacs; i++) {
1233 hda_nid_t nid = spec->all_dacs[i];
1234 if (!nid || is_dac_already_used(codec, nid))
1235 continue;
1236 if (is_reachable_path(codec, nid, pin)) {
1237 if (nid_found)
1238 return 0;
1239 nid_found = nid;
1240 }
1241 }
1242 return nid_found;
1243}
1244
1245/* check whether the given pin can be a multi-io pin */
1246static bool can_be_multiio_pin(struct hda_codec *codec,
1247 unsigned int location, hda_nid_t nid)
1248{
1249 unsigned int defcfg, caps;
1250
1251 defcfg = snd_hda_codec_get_pincfg(codec, nid);
1252 if (get_defcfg_connect(defcfg) != AC_JACK_PORT_COMPLEX)
1253 return false;
1254 if (location && get_defcfg_location(defcfg) != location)
1255 return false;
1256 caps = snd_hda_query_pin_caps(codec, nid);
1257 if (!(caps & AC_PINCAP_OUT))
1258 return false;
1259 return true;
1260}
1261
Takashi Iwaie22aab72013-01-04 14:50:04 +01001262/* count the number of input pins that are capable to be multi-io */
1263static int count_multiio_pins(struct hda_codec *codec, hda_nid_t reference_pin)
1264{
1265 struct hda_gen_spec *spec = codec->spec;
1266 struct auto_pin_cfg *cfg = &spec->autocfg;
1267 unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin);
1268 unsigned int location = get_defcfg_location(defcfg);
1269 int type, i;
1270 int num_pins = 0;
1271
1272 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
1273 for (i = 0; i < cfg->num_inputs; i++) {
1274 if (cfg->inputs[i].type != type)
1275 continue;
1276 if (can_be_multiio_pin(codec, location,
1277 cfg->inputs[i].pin))
1278 num_pins++;
1279 }
1280 }
1281 return num_pins;
1282}
1283
Takashi Iwai352f7f92012-12-19 12:52:06 +01001284/*
1285 * multi-io helper
1286 *
1287 * When hardwired is set, try to fill ony hardwired pins, and returns
1288 * zero if any pins are filled, non-zero if nothing found.
1289 * When hardwired is off, try to fill possible input pins, and returns
1290 * the badness value.
1291 */
1292static int fill_multi_ios(struct hda_codec *codec,
1293 hda_nid_t reference_pin,
Takashi Iwaie22aab72013-01-04 14:50:04 +01001294 bool hardwired)
Takashi Iwai352f7f92012-12-19 12:52:06 +01001295{
1296 struct hda_gen_spec *spec = codec->spec;
1297 struct auto_pin_cfg *cfg = &spec->autocfg;
Takashi Iwaie22aab72013-01-04 14:50:04 +01001298 int type, i, j, num_pins, old_pins;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001299 unsigned int defcfg = snd_hda_codec_get_pincfg(codec, reference_pin);
1300 unsigned int location = get_defcfg_location(defcfg);
1301 int badness = 0;
Takashi Iwai0e614dd2013-01-07 15:11:44 +01001302 struct nid_path *path;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001303
1304 old_pins = spec->multi_ios;
1305 if (old_pins >= 2)
1306 goto end_fill;
1307
Takashi Iwaie22aab72013-01-04 14:50:04 +01001308 num_pins = count_multiio_pins(codec, reference_pin);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001309 if (num_pins < 2)
1310 goto end_fill;
1311
Takashi Iwai352f7f92012-12-19 12:52:06 +01001312 for (type = AUTO_PIN_LINE_IN; type >= AUTO_PIN_MIC; type--) {
1313 for (i = 0; i < cfg->num_inputs; i++) {
1314 hda_nid_t nid = cfg->inputs[i].pin;
1315 hda_nid_t dac = 0;
1316
1317 if (cfg->inputs[i].type != type)
1318 continue;
1319 if (!can_be_multiio_pin(codec, location, nid))
1320 continue;
1321 for (j = 0; j < spec->multi_ios; j++) {
1322 if (nid == spec->multi_io[j].pin)
1323 break;
1324 }
1325 if (j < spec->multi_ios)
1326 continue;
1327
Takashi Iwai352f7f92012-12-19 12:52:06 +01001328 if (hardwired)
1329 dac = get_dac_if_single(codec, nid);
1330 else if (!dac)
1331 dac = look_for_dac(codec, nid, false);
1332 if (!dac) {
1333 badness++;
1334 continue;
1335 }
Takashi Iwai3ca529d2013-01-07 17:25:08 +01001336 path = snd_hda_add_new_path(codec, dac, nid,
1337 -spec->mixer_nid);
Takashi Iwai0c8c0f52012-12-20 17:54:22 +01001338 if (!path) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01001339 badness++;
1340 continue;
1341 }
Takashi Iwaia7694092013-01-21 10:43:18 +01001342 /* print_nid_path("multiio", path); */
Takashi Iwai352f7f92012-12-19 12:52:06 +01001343 spec->multi_io[spec->multi_ios].pin = nid;
1344 spec->multi_io[spec->multi_ios].dac = dac;
Takashi Iwai196c17662013-01-04 15:01:40 +01001345 spec->out_paths[cfg->line_outs + spec->multi_ios] =
1346 snd_hda_get_path_idx(codec, path);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001347 spec->multi_ios++;
1348 if (spec->multi_ios >= 2)
1349 break;
1350 }
1351 }
1352 end_fill:
1353 if (badness)
1354 badness = BAD_MULTI_IO;
1355 if (old_pins == spec->multi_ios) {
1356 if (hardwired)
1357 return 1; /* nothing found */
1358 else
1359 return badness; /* no badness if nothing found */
1360 }
1361 if (!hardwired && spec->multi_ios < 2) {
1362 /* cancel newly assigned paths */
1363 spec->paths.used -= spec->multi_ios - old_pins;
1364 spec->multi_ios = old_pins;
1365 return badness;
1366 }
1367
1368 /* assign volume and mute controls */
Takashi Iwai0e614dd2013-01-07 15:11:44 +01001369 for (i = old_pins; i < spec->multi_ios; i++) {
1370 path = snd_hda_get_path_from_idx(codec, spec->out_paths[cfg->line_outs + i]);
1371 badness += assign_out_path_ctls(codec, path);
1372 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01001373
1374 return badness;
1375}
1376
1377/* map DACs for all pins in the list if they are single connections */
1378static bool map_singles(struct hda_codec *codec, int outs,
Takashi Iwai196c17662013-01-04 15:01:40 +01001379 const hda_nid_t *pins, hda_nid_t *dacs, int *path_idx)
Takashi Iwai352f7f92012-12-19 12:52:06 +01001380{
Takashi Iwaib3a8c742012-12-20 18:29:16 +01001381 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001382 int i;
1383 bool found = false;
1384 for (i = 0; i < outs; i++) {
Takashi Iwai0c8c0f52012-12-20 17:54:22 +01001385 struct nid_path *path;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001386 hda_nid_t dac;
1387 if (dacs[i])
1388 continue;
1389 dac = get_dac_if_single(codec, pins[i]);
1390 if (!dac)
1391 continue;
Takashi Iwai3ca529d2013-01-07 17:25:08 +01001392 path = snd_hda_add_new_path(codec, dac, pins[i],
1393 -spec->mixer_nid);
Takashi Iwai117688a2013-01-04 15:41:41 +01001394 if (!path && !i && spec->mixer_nid)
Takashi Iwai3ca529d2013-01-07 17:25:08 +01001395 path = snd_hda_add_new_path(codec, dac, pins[i], 0);
Takashi Iwai0c8c0f52012-12-20 17:54:22 +01001396 if (path) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01001397 dacs[i] = dac;
1398 found = true;
Takashi Iwaia7694092013-01-21 10:43:18 +01001399 /* print_nid_path("output", path); */
Takashi Iwaie1284af2013-01-03 16:33:02 +01001400 path->active = true;
Takashi Iwai196c17662013-01-04 15:01:40 +01001401 path_idx[i] = snd_hda_get_path_idx(codec, path);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001402 }
1403 }
1404 return found;
1405}
1406
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01001407/* create a new path including aamix if available, and return its index */
1408static int check_aamix_out_path(struct hda_codec *codec, int path_idx)
1409{
Takashi Iwai3ca529d2013-01-07 17:25:08 +01001410 struct hda_gen_spec *spec = codec->spec;
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01001411 struct nid_path *path;
Takashi Iwai5ead56f2013-04-16 14:16:54 +02001412 hda_nid_t path_dac, dac, pin;
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01001413
1414 path = snd_hda_get_path_from_idx(codec, path_idx);
Takashi Iwai3ca529d2013-01-07 17:25:08 +01001415 if (!path || !path->depth ||
1416 is_nid_contained(path, spec->mixer_nid))
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01001417 return 0;
Takashi Iwai5ead56f2013-04-16 14:16:54 +02001418 path_dac = path->path[0];
1419 dac = spec->private_dac_nids[0];
Takashi Iwaif87498b2013-01-21 14:24:31 +01001420 pin = path->path[path->depth - 1];
1421 path = snd_hda_add_new_path(codec, dac, pin, spec->mixer_nid);
1422 if (!path) {
Takashi Iwai5ead56f2013-04-16 14:16:54 +02001423 if (dac != path_dac)
1424 dac = path_dac;
Takashi Iwaif87498b2013-01-21 14:24:31 +01001425 else if (spec->multiout.hp_out_nid[0])
1426 dac = spec->multiout.hp_out_nid[0];
1427 else if (spec->multiout.extra_out_nid[0])
1428 dac = spec->multiout.extra_out_nid[0];
Takashi Iwai5ead56f2013-04-16 14:16:54 +02001429 else
1430 dac = 0;
Takashi Iwaif87498b2013-01-21 14:24:31 +01001431 if (dac)
1432 path = snd_hda_add_new_path(codec, dac, pin,
1433 spec->mixer_nid);
1434 }
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01001435 if (!path)
1436 return 0;
Takashi Iwaia7694092013-01-21 10:43:18 +01001437 /* print_nid_path("output-aamix", path); */
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01001438 path->active = false; /* unused as default */
1439 return snd_hda_get_path_idx(codec, path);
1440}
1441
Takashi Iwai55a63d42013-03-21 17:20:12 +01001442/* check whether the independent HP is available with the current config */
1443static bool indep_hp_possible(struct hda_codec *codec)
1444{
1445 struct hda_gen_spec *spec = codec->spec;
1446 struct auto_pin_cfg *cfg = &spec->autocfg;
1447 struct nid_path *path;
1448 int i, idx;
1449
1450 if (cfg->line_out_type == AUTO_PIN_HP_OUT)
1451 idx = spec->out_paths[0];
1452 else
1453 idx = spec->hp_paths[0];
1454 path = snd_hda_get_path_from_idx(codec, idx);
1455 if (!path)
1456 return false;
1457
1458 /* assume no path conflicts unless aamix is involved */
1459 if (!spec->mixer_nid || !is_nid_contained(path, spec->mixer_nid))
1460 return true;
1461
1462 /* check whether output paths contain aamix */
1463 for (i = 0; i < cfg->line_outs; i++) {
1464 if (spec->out_paths[i] == idx)
1465 break;
1466 path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]);
1467 if (path && is_nid_contained(path, spec->mixer_nid))
1468 return false;
1469 }
1470 for (i = 0; i < cfg->speaker_outs; i++) {
1471 path = snd_hda_get_path_from_idx(codec, spec->speaker_paths[i]);
1472 if (path && is_nid_contained(path, spec->mixer_nid))
1473 return false;
1474 }
1475
1476 return true;
1477}
1478
Takashi Iwaia07a9492013-01-07 16:44:06 +01001479/* fill the empty entries in the dac array for speaker/hp with the
1480 * shared dac pointed by the paths
1481 */
1482static void refill_shared_dacs(struct hda_codec *codec, int num_outs,
1483 hda_nid_t *dacs, int *path_idx)
1484{
1485 struct nid_path *path;
1486 int i;
1487
1488 for (i = 0; i < num_outs; i++) {
1489 if (dacs[i])
1490 continue;
1491 path = snd_hda_get_path_from_idx(codec, path_idx[i]);
1492 if (!path)
1493 continue;
1494 dacs[i] = path->path[0];
1495 }
1496}
1497
Takashi Iwai352f7f92012-12-19 12:52:06 +01001498/* fill in the dac_nids table from the parsed pin configuration */
1499static int fill_and_eval_dacs(struct hda_codec *codec,
1500 bool fill_hardwired,
1501 bool fill_mio_first)
1502{
1503 struct hda_gen_spec *spec = codec->spec;
1504 struct auto_pin_cfg *cfg = &spec->autocfg;
1505 int i, err, badness;
1506
1507 /* set num_dacs once to full for look_for_dac() */
1508 spec->multiout.num_dacs = cfg->line_outs;
1509 spec->multiout.dac_nids = spec->private_dac_nids;
1510 memset(spec->private_dac_nids, 0, sizeof(spec->private_dac_nids));
1511 memset(spec->multiout.hp_out_nid, 0, sizeof(spec->multiout.hp_out_nid));
1512 memset(spec->multiout.extra_out_nid, 0, sizeof(spec->multiout.extra_out_nid));
1513 spec->multi_ios = 0;
1514 snd_array_free(&spec->paths);
Takashi Iwaicd5be3f2013-01-07 15:07:00 +01001515
1516 /* clear path indices */
1517 memset(spec->out_paths, 0, sizeof(spec->out_paths));
1518 memset(spec->hp_paths, 0, sizeof(spec->hp_paths));
1519 memset(spec->speaker_paths, 0, sizeof(spec->speaker_paths));
1520 memset(spec->aamix_out_paths, 0, sizeof(spec->aamix_out_paths));
1521 memset(spec->digout_paths, 0, sizeof(spec->digout_paths));
Takashi Iwaic697b712013-01-07 17:09:26 +01001522 memset(spec->input_paths, 0, sizeof(spec->input_paths));
Takashi Iwaicd5be3f2013-01-07 15:07:00 +01001523 memset(spec->loopback_paths, 0, sizeof(spec->loopback_paths));
1524 memset(&spec->digin_path, 0, sizeof(spec->digin_path));
1525
Takashi Iwai352f7f92012-12-19 12:52:06 +01001526 badness = 0;
1527
1528 /* fill hard-wired DACs first */
1529 if (fill_hardwired) {
1530 bool mapped;
1531 do {
1532 mapped = map_singles(codec, cfg->line_outs,
1533 cfg->line_out_pins,
Takashi Iwai196c17662013-01-04 15:01:40 +01001534 spec->private_dac_nids,
1535 spec->out_paths);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001536 mapped |= map_singles(codec, cfg->hp_outs,
1537 cfg->hp_pins,
Takashi Iwai196c17662013-01-04 15:01:40 +01001538 spec->multiout.hp_out_nid,
1539 spec->hp_paths);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001540 mapped |= map_singles(codec, cfg->speaker_outs,
1541 cfg->speaker_pins,
Takashi Iwai196c17662013-01-04 15:01:40 +01001542 spec->multiout.extra_out_nid,
1543 spec->speaker_paths);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001544 if (fill_mio_first && cfg->line_outs == 1 &&
1545 cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
Takashi Iwaie22aab72013-01-04 14:50:04 +01001546 err = fill_multi_ios(codec, cfg->line_out_pins[0], true);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001547 if (!err)
1548 mapped = true;
1549 }
1550 } while (mapped);
1551 }
1552
1553 badness += try_assign_dacs(codec, cfg->line_outs, cfg->line_out_pins,
Takashi Iwai196c17662013-01-04 15:01:40 +01001554 spec->private_dac_nids, spec->out_paths,
Takashi Iwai98bd1112013-03-22 14:53:50 +01001555 spec->main_out_badness);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001556
Takashi Iwai352f7f92012-12-19 12:52:06 +01001557 if (fill_mio_first &&
1558 cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1559 /* try to fill multi-io first */
Takashi Iwaie22aab72013-01-04 14:50:04 +01001560 err = fill_multi_ios(codec, cfg->line_out_pins[0], false);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001561 if (err < 0)
1562 return err;
1563 /* we don't count badness at this stage yet */
1564 }
1565
1566 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
1567 err = try_assign_dacs(codec, cfg->hp_outs, cfg->hp_pins,
1568 spec->multiout.hp_out_nid,
Takashi Iwai196c17662013-01-04 15:01:40 +01001569 spec->hp_paths,
Takashi Iwai98bd1112013-03-22 14:53:50 +01001570 spec->extra_out_badness);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001571 if (err < 0)
1572 return err;
1573 badness += err;
1574 }
1575 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1576 err = try_assign_dacs(codec, cfg->speaker_outs,
1577 cfg->speaker_pins,
1578 spec->multiout.extra_out_nid,
Takashi Iwai196c17662013-01-04 15:01:40 +01001579 spec->speaker_paths,
Takashi Iwai98bd1112013-03-22 14:53:50 +01001580 spec->extra_out_badness);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001581 if (err < 0)
1582 return err;
1583 badness += err;
1584 }
1585 if (cfg->line_outs == 1 && cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
Takashi Iwaie22aab72013-01-04 14:50:04 +01001586 err = fill_multi_ios(codec, cfg->line_out_pins[0], false);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001587 if (err < 0)
1588 return err;
1589 badness += err;
1590 }
Takashi Iwaie22aab72013-01-04 14:50:04 +01001591
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01001592 if (spec->mixer_nid) {
1593 spec->aamix_out_paths[0] =
1594 check_aamix_out_path(codec, spec->out_paths[0]);
1595 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1596 spec->aamix_out_paths[1] =
1597 check_aamix_out_path(codec, spec->hp_paths[0]);
1598 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
1599 spec->aamix_out_paths[2] =
1600 check_aamix_out_path(codec, spec->speaker_paths[0]);
1601 }
1602
Takashi Iwaie22aab72013-01-04 14:50:04 +01001603 if (cfg->hp_outs && cfg->line_out_type == AUTO_PIN_SPEAKER_OUT)
1604 if (count_multiio_pins(codec, cfg->hp_pins[0]) >= 2)
1605 spec->multi_ios = 1; /* give badness */
Takashi Iwai352f7f92012-12-19 12:52:06 +01001606
Takashi Iwaia07a9492013-01-07 16:44:06 +01001607 /* re-count num_dacs and squash invalid entries */
1608 spec->multiout.num_dacs = 0;
1609 for (i = 0; i < cfg->line_outs; i++) {
1610 if (spec->private_dac_nids[i])
1611 spec->multiout.num_dacs++;
1612 else {
1613 memmove(spec->private_dac_nids + i,
1614 spec->private_dac_nids + i + 1,
1615 sizeof(hda_nid_t) * (cfg->line_outs - i - 1));
1616 spec->private_dac_nids[cfg->line_outs - 1] = 0;
1617 }
1618 }
1619
1620 spec->ext_channel_count = spec->min_channel_count =
David Henningssonc0f3b212013-01-16 11:45:37 +01001621 spec->multiout.num_dacs * 2;
Takashi Iwaia07a9492013-01-07 16:44:06 +01001622
Takashi Iwai352f7f92012-12-19 12:52:06 +01001623 if (spec->multi_ios == 2) {
1624 for (i = 0; i < 2; i++)
1625 spec->private_dac_nids[spec->multiout.num_dacs++] =
1626 spec->multi_io[i].dac;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001627 } else if (spec->multi_ios) {
1628 spec->multi_ios = 0;
1629 badness += BAD_MULTI_IO;
1630 }
1631
Takashi Iwai55a63d42013-03-21 17:20:12 +01001632 if (spec->indep_hp && !indep_hp_possible(codec))
1633 badness += BAD_NO_INDEP_HP;
1634
Takashi Iwaia07a9492013-01-07 16:44:06 +01001635 /* re-fill the shared DAC for speaker / headphone */
1636 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1637 refill_shared_dacs(codec, cfg->hp_outs,
1638 spec->multiout.hp_out_nid,
1639 spec->hp_paths);
1640 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
1641 refill_shared_dacs(codec, cfg->speaker_outs,
1642 spec->multiout.extra_out_nid,
1643 spec->speaker_paths);
1644
Takashi Iwai352f7f92012-12-19 12:52:06 +01001645 return badness;
1646}
1647
1648#define DEBUG_BADNESS
1649
1650#ifdef DEBUG_BADNESS
1651#define debug_badness snd_printdd
1652#else
1653#define debug_badness(...)
1654#endif
1655
Takashi Iwaia7694092013-01-21 10:43:18 +01001656#ifdef DEBUG_BADNESS
1657static inline void print_nid_path_idx(struct hda_codec *codec,
1658 const char *pfx, int idx)
Takashi Iwai352f7f92012-12-19 12:52:06 +01001659{
Takashi Iwaia7694092013-01-21 10:43:18 +01001660 struct nid_path *path;
1661
1662 path = snd_hda_get_path_from_idx(codec, idx);
1663 if (path)
1664 print_nid_path(pfx, path);
1665}
1666
1667static void debug_show_configs(struct hda_codec *codec,
1668 struct auto_pin_cfg *cfg)
1669{
1670 struct hda_gen_spec *spec = codec->spec;
Takashi Iwaia7694092013-01-21 10:43:18 +01001671 static const char * const lo_type[3] = { "LO", "SP", "HP" };
Takashi Iwaia7694092013-01-21 10:43:18 +01001672 int i;
1673
1674 debug_badness("multi_outs = %x/%x/%x/%x : %x/%x/%x/%x (type %s)\n",
Takashi Iwai352f7f92012-12-19 12:52:06 +01001675 cfg->line_out_pins[0], cfg->line_out_pins[1],
Takashi Iwai708122e2012-12-20 17:56:57 +01001676 cfg->line_out_pins[2], cfg->line_out_pins[3],
Takashi Iwai352f7f92012-12-19 12:52:06 +01001677 spec->multiout.dac_nids[0],
1678 spec->multiout.dac_nids[1],
1679 spec->multiout.dac_nids[2],
Takashi Iwaia7694092013-01-21 10:43:18 +01001680 spec->multiout.dac_nids[3],
1681 lo_type[cfg->line_out_type]);
1682 for (i = 0; i < cfg->line_outs; i++)
1683 print_nid_path_idx(codec, " out", spec->out_paths[i]);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001684 if (spec->multi_ios > 0)
1685 debug_badness("multi_ios(%d) = %x/%x : %x/%x\n",
1686 spec->multi_ios,
1687 spec->multi_io[0].pin, spec->multi_io[1].pin,
1688 spec->multi_io[0].dac, spec->multi_io[1].dac);
Takashi Iwaia7694092013-01-21 10:43:18 +01001689 for (i = 0; i < spec->multi_ios; i++)
1690 print_nid_path_idx(codec, " mio",
1691 spec->out_paths[cfg->line_outs + i]);
1692 if (cfg->hp_outs)
1693 debug_badness("hp_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
Takashi Iwai352f7f92012-12-19 12:52:06 +01001694 cfg->hp_pins[0], cfg->hp_pins[1],
Takashi Iwai708122e2012-12-20 17:56:57 +01001695 cfg->hp_pins[2], cfg->hp_pins[3],
Takashi Iwai352f7f92012-12-19 12:52:06 +01001696 spec->multiout.hp_out_nid[0],
1697 spec->multiout.hp_out_nid[1],
1698 spec->multiout.hp_out_nid[2],
1699 spec->multiout.hp_out_nid[3]);
Takashi Iwaia7694092013-01-21 10:43:18 +01001700 for (i = 0; i < cfg->hp_outs; i++)
1701 print_nid_path_idx(codec, " hp ", spec->hp_paths[i]);
1702 if (cfg->speaker_outs)
1703 debug_badness("spk_outs = %x/%x/%x/%x : %x/%x/%x/%x\n",
Takashi Iwai352f7f92012-12-19 12:52:06 +01001704 cfg->speaker_pins[0], cfg->speaker_pins[1],
1705 cfg->speaker_pins[2], cfg->speaker_pins[3],
1706 spec->multiout.extra_out_nid[0],
1707 spec->multiout.extra_out_nid[1],
1708 spec->multiout.extra_out_nid[2],
1709 spec->multiout.extra_out_nid[3]);
Takashi Iwaia7694092013-01-21 10:43:18 +01001710 for (i = 0; i < cfg->speaker_outs; i++)
1711 print_nid_path_idx(codec, " spk", spec->speaker_paths[i]);
1712 for (i = 0; i < 3; i++)
1713 print_nid_path_idx(codec, " mix", spec->aamix_out_paths[i]);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001714}
Takashi Iwaia7694092013-01-21 10:43:18 +01001715#else
1716#define debug_show_configs(codec, cfg) /* NOP */
1717#endif
Takashi Iwai352f7f92012-12-19 12:52:06 +01001718
1719/* find all available DACs of the codec */
1720static void fill_all_dac_nids(struct hda_codec *codec)
1721{
1722 struct hda_gen_spec *spec = codec->spec;
1723 int i;
1724 hda_nid_t nid = codec->start_nid;
1725
1726 spec->num_all_dacs = 0;
1727 memset(spec->all_dacs, 0, sizeof(spec->all_dacs));
1728 for (i = 0; i < codec->num_nodes; i++, nid++) {
1729 if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_AUD_OUT)
1730 continue;
1731 if (spec->num_all_dacs >= ARRAY_SIZE(spec->all_dacs)) {
1732 snd_printk(KERN_ERR "hda: Too many DACs!\n");
1733 break;
1734 }
1735 spec->all_dacs[spec->num_all_dacs++] = nid;
1736 }
1737}
1738
1739static int parse_output_paths(struct hda_codec *codec)
1740{
1741 struct hda_gen_spec *spec = codec->spec;
1742 struct auto_pin_cfg *cfg = &spec->autocfg;
1743 struct auto_pin_cfg *best_cfg;
Takashi Iwai9314a582013-01-21 10:49:05 +01001744 unsigned int val;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001745 int best_badness = INT_MAX;
1746 int badness;
1747 bool fill_hardwired = true, fill_mio_first = true;
1748 bool best_wired = true, best_mio = true;
1749 bool hp_spk_swapped = false;
1750
Takashi Iwai352f7f92012-12-19 12:52:06 +01001751 best_cfg = kmalloc(sizeof(*best_cfg), GFP_KERNEL);
1752 if (!best_cfg)
1753 return -ENOMEM;
1754 *best_cfg = *cfg;
1755
1756 for (;;) {
1757 badness = fill_and_eval_dacs(codec, fill_hardwired,
1758 fill_mio_first);
1759 if (badness < 0) {
1760 kfree(best_cfg);
1761 return badness;
1762 }
1763 debug_badness("==> lo_type=%d, wired=%d, mio=%d, badness=0x%x\n",
1764 cfg->line_out_type, fill_hardwired, fill_mio_first,
1765 badness);
Takashi Iwaia7694092013-01-21 10:43:18 +01001766 debug_show_configs(codec, cfg);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001767 if (badness < best_badness) {
1768 best_badness = badness;
1769 *best_cfg = *cfg;
1770 best_wired = fill_hardwired;
1771 best_mio = fill_mio_first;
1772 }
1773 if (!badness)
1774 break;
1775 fill_mio_first = !fill_mio_first;
1776 if (!fill_mio_first)
1777 continue;
1778 fill_hardwired = !fill_hardwired;
1779 if (!fill_hardwired)
1780 continue;
1781 if (hp_spk_swapped)
1782 break;
1783 hp_spk_swapped = true;
1784 if (cfg->speaker_outs > 0 &&
1785 cfg->line_out_type == AUTO_PIN_HP_OUT) {
1786 cfg->hp_outs = cfg->line_outs;
1787 memcpy(cfg->hp_pins, cfg->line_out_pins,
1788 sizeof(cfg->hp_pins));
1789 cfg->line_outs = cfg->speaker_outs;
1790 memcpy(cfg->line_out_pins, cfg->speaker_pins,
1791 sizeof(cfg->speaker_pins));
1792 cfg->speaker_outs = 0;
1793 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
1794 cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
1795 fill_hardwired = true;
1796 continue;
1797 }
1798 if (cfg->hp_outs > 0 &&
1799 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
1800 cfg->speaker_outs = cfg->line_outs;
1801 memcpy(cfg->speaker_pins, cfg->line_out_pins,
1802 sizeof(cfg->speaker_pins));
1803 cfg->line_outs = cfg->hp_outs;
1804 memcpy(cfg->line_out_pins, cfg->hp_pins,
1805 sizeof(cfg->hp_pins));
1806 cfg->hp_outs = 0;
1807 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
1808 cfg->line_out_type = AUTO_PIN_HP_OUT;
1809 fill_hardwired = true;
1810 continue;
1811 }
1812 break;
1813 }
1814
1815 if (badness) {
Takashi Iwai0c8c0f52012-12-20 17:54:22 +01001816 debug_badness("==> restoring best_cfg\n");
Takashi Iwai352f7f92012-12-19 12:52:06 +01001817 *cfg = *best_cfg;
1818 fill_and_eval_dacs(codec, best_wired, best_mio);
1819 }
1820 debug_badness("==> Best config: lo_type=%d, wired=%d, mio=%d\n",
1821 cfg->line_out_type, best_wired, best_mio);
Takashi Iwaia7694092013-01-21 10:43:18 +01001822 debug_show_configs(codec, cfg);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001823
1824 if (cfg->line_out_pins[0]) {
1825 struct nid_path *path;
Takashi Iwai196c17662013-01-04 15:01:40 +01001826 path = snd_hda_get_path_from_idx(codec, spec->out_paths[0]);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001827 if (path)
1828 spec->vmaster_nid = look_for_out_vol_nid(codec, path);
Takashi Iwai7a71bbf2013-01-17 10:25:15 +01001829 if (spec->vmaster_nid)
1830 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1831 HDA_OUTPUT, spec->vmaster_tlv);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001832 }
1833
Takashi Iwai9314a582013-01-21 10:49:05 +01001834 /* set initial pinctl targets */
1835 if (spec->prefer_hp_amp || cfg->line_out_type == AUTO_PIN_HP_OUT)
1836 val = PIN_HP;
1837 else
1838 val = PIN_OUT;
1839 set_pin_targets(codec, cfg->line_outs, cfg->line_out_pins, val);
1840 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
1841 set_pin_targets(codec, cfg->hp_outs, cfg->hp_pins, PIN_HP);
1842 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
1843 val = spec->prefer_hp_amp ? PIN_HP : PIN_OUT;
1844 set_pin_targets(codec, cfg->speaker_outs,
1845 cfg->speaker_pins, val);
1846 }
1847
Takashi Iwai55a63d42013-03-21 17:20:12 +01001848 /* clear indep_hp flag if not available */
1849 if (spec->indep_hp && !indep_hp_possible(codec))
1850 spec->indep_hp = 0;
1851
Takashi Iwai352f7f92012-12-19 12:52:06 +01001852 kfree(best_cfg);
1853 return 0;
1854}
1855
1856/* add playback controls from the parsed DAC table */
1857static int create_multi_out_ctls(struct hda_codec *codec,
1858 const struct auto_pin_cfg *cfg)
1859{
1860 struct hda_gen_spec *spec = codec->spec;
1861 int i, err, noutputs;
1862
1863 noutputs = cfg->line_outs;
1864 if (spec->multi_ios > 0 && cfg->line_outs < 3)
1865 noutputs += spec->multi_ios;
1866
1867 for (i = 0; i < noutputs; i++) {
1868 const char *name;
1869 int index;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001870 struct nid_path *path;
1871
Takashi Iwai196c17662013-01-04 15:01:40 +01001872 path = snd_hda_get_path_from_idx(codec, spec->out_paths[i]);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001873 if (!path)
1874 continue;
Takashi Iwai247d85e2013-01-17 16:18:11 +01001875
1876 name = get_line_out_pfx(codec, i, &index, NID_PATH_VOL_CTL);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001877 if (!name || !strcmp(name, "CLFE")) {
1878 /* Center/LFE */
1879 err = add_vol_ctl(codec, "Center", 0, 1, path);
1880 if (err < 0)
1881 return err;
1882 err = add_vol_ctl(codec, "LFE", 0, 2, path);
1883 if (err < 0)
1884 return err;
Takashi Iwai247d85e2013-01-17 16:18:11 +01001885 } else {
1886 err = add_stereo_vol(codec, name, index, path);
1887 if (err < 0)
1888 return err;
1889 }
1890
1891 name = get_line_out_pfx(codec, i, &index, NID_PATH_MUTE_CTL);
1892 if (!name || !strcmp(name, "CLFE")) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01001893 err = add_sw_ctl(codec, "Center", 0, 1, path);
1894 if (err < 0)
1895 return err;
1896 err = add_sw_ctl(codec, "LFE", 0, 2, path);
1897 if (err < 0)
1898 return err;
1899 } else {
Takashi Iwai352f7f92012-12-19 12:52:06 +01001900 err = add_stereo_sw(codec, name, index, path);
1901 if (err < 0)
1902 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001903 }
1904 }
1905 return 0;
1906}
1907
Takashi Iwaic2c80382013-01-07 10:33:57 +01001908static int create_extra_out(struct hda_codec *codec, int path_idx,
Takashi Iwai196c17662013-01-04 15:01:40 +01001909 const char *pfx, int cidx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001910{
Takashi Iwai352f7f92012-12-19 12:52:06 +01001911 struct nid_path *path;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001912 int err;
1913
Takashi Iwai196c17662013-01-04 15:01:40 +01001914 path = snd_hda_get_path_from_idx(codec, path_idx);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001915 if (!path)
1916 return 0;
Takashi Iwaic2c80382013-01-07 10:33:57 +01001917 err = add_stereo_vol(codec, pfx, cidx, path);
1918 if (err < 0)
1919 return err;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001920 err = add_stereo_sw(codec, pfx, cidx, path);
1921 if (err < 0)
1922 return err;
1923 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924}
1925
Takashi Iwai352f7f92012-12-19 12:52:06 +01001926/* add playback controls for speaker and HP outputs */
1927static int create_extra_outs(struct hda_codec *codec, int num_pins,
Takashi Iwai196c17662013-01-04 15:01:40 +01001928 const int *paths, const char *pfx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001929{
Takashi Iwaic2c80382013-01-07 10:33:57 +01001930 int i;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001931
1932 for (i = 0; i < num_pins; i++) {
Takashi Iwaic2c80382013-01-07 10:33:57 +01001933 const char *name;
Takashi Iwai975cc022013-06-28 11:56:49 +02001934 char tmp[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
Takashi Iwaic2c80382013-01-07 10:33:57 +01001935 int err, idx = 0;
1936
1937 if (num_pins == 2 && i == 1 && !strcmp(pfx, "Speaker"))
1938 name = "Bass Speaker";
1939 else if (num_pins >= 3) {
1940 snprintf(tmp, sizeof(tmp), "%s %s",
Takashi Iwai352f7f92012-12-19 12:52:06 +01001941 pfx, channel_name[i]);
Takashi Iwaic2c80382013-01-07 10:33:57 +01001942 name = tmp;
Takashi Iwai352f7f92012-12-19 12:52:06 +01001943 } else {
Takashi Iwaic2c80382013-01-07 10:33:57 +01001944 name = pfx;
1945 idx = i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001946 }
Takashi Iwaic2c80382013-01-07 10:33:57 +01001947 err = create_extra_out(codec, paths[i], name, idx);
Takashi Iwai352f7f92012-12-19 12:52:06 +01001948 if (err < 0)
1949 return err;
1950 }
1951 return 0;
1952}
Takashi Iwai97ec5582006-03-21 11:29:07 +01001953
Takashi Iwai352f7f92012-12-19 12:52:06 +01001954static int create_hp_out_ctls(struct hda_codec *codec)
1955{
1956 struct hda_gen_spec *spec = codec->spec;
1957 return create_extra_outs(codec, spec->autocfg.hp_outs,
Takashi Iwai196c17662013-01-04 15:01:40 +01001958 spec->hp_paths,
Takashi Iwai352f7f92012-12-19 12:52:06 +01001959 "Headphone");
1960}
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961
Takashi Iwai352f7f92012-12-19 12:52:06 +01001962static int create_speaker_out_ctls(struct hda_codec *codec)
1963{
1964 struct hda_gen_spec *spec = codec->spec;
1965 return create_extra_outs(codec, spec->autocfg.speaker_outs,
Takashi Iwai196c17662013-01-04 15:01:40 +01001966 spec->speaker_paths,
Takashi Iwai352f7f92012-12-19 12:52:06 +01001967 "Speaker");
1968}
1969
1970/*
Takashi Iwai38cf6f12012-12-21 14:09:42 +01001971 * independent HP controls
1972 */
1973
Takashi Iwai963afde2013-05-31 15:20:31 +02001974static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack);
Takashi Iwai38cf6f12012-12-21 14:09:42 +01001975static int indep_hp_info(struct snd_kcontrol *kcontrol,
1976 struct snd_ctl_elem_info *uinfo)
1977{
1978 return snd_hda_enum_bool_helper_info(kcontrol, uinfo);
1979}
1980
1981static int indep_hp_get(struct snd_kcontrol *kcontrol,
1982 struct snd_ctl_elem_value *ucontrol)
1983{
1984 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1985 struct hda_gen_spec *spec = codec->spec;
1986 ucontrol->value.enumerated.item[0] = spec->indep_hp_enabled;
1987 return 0;
1988}
1989
Takashi Iwaia1e908e2013-01-21 15:11:25 +01001990static void update_aamix_paths(struct hda_codec *codec, bool do_mix,
1991 int nomix_path_idx, int mix_path_idx,
1992 int out_type);
1993
Takashi Iwai38cf6f12012-12-21 14:09:42 +01001994static int indep_hp_put(struct snd_kcontrol *kcontrol,
1995 struct snd_ctl_elem_value *ucontrol)
1996{
1997 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1998 struct hda_gen_spec *spec = codec->spec;
1999 unsigned int select = ucontrol->value.enumerated.item[0];
2000 int ret = 0;
2001
2002 mutex_lock(&spec->pcm_mutex);
2003 if (spec->active_streams) {
2004 ret = -EBUSY;
2005 goto unlock;
2006 }
2007
2008 if (spec->indep_hp_enabled != select) {
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002009 hda_nid_t *dacp;
2010 if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
2011 dacp = &spec->private_dac_nids[0];
2012 else
2013 dacp = &spec->multiout.hp_out_nid[0];
2014
2015 /* update HP aamix paths in case it conflicts with indep HP */
2016 if (spec->have_aamix_ctl) {
2017 if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
2018 update_aamix_paths(codec, spec->aamix_mode,
2019 spec->out_paths[0],
2020 spec->aamix_out_paths[0],
2021 spec->autocfg.line_out_type);
2022 else
2023 update_aamix_paths(codec, spec->aamix_mode,
2024 spec->hp_paths[0],
2025 spec->aamix_out_paths[1],
2026 AUTO_PIN_HP_OUT);
2027 }
2028
Takashi Iwai38cf6f12012-12-21 14:09:42 +01002029 spec->indep_hp_enabled = select;
2030 if (spec->indep_hp_enabled)
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002031 *dacp = 0;
Takashi Iwai38cf6f12012-12-21 14:09:42 +01002032 else
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002033 *dacp = spec->alt_dac_nid;
Takashi Iwai92603c52013-01-22 07:46:31 +01002034
Takashi Iwai963afde2013-05-31 15:20:31 +02002035 call_hp_automute(codec, NULL);
Takashi Iwai38cf6f12012-12-21 14:09:42 +01002036 ret = 1;
2037 }
2038 unlock:
2039 mutex_unlock(&spec->pcm_mutex);
2040 return ret;
2041}
2042
2043static const struct snd_kcontrol_new indep_hp_ctl = {
2044 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2045 .name = "Independent HP",
2046 .info = indep_hp_info,
2047 .get = indep_hp_get,
2048 .put = indep_hp_put,
2049};
2050
2051
2052static int create_indep_hp_ctls(struct hda_codec *codec)
2053{
2054 struct hda_gen_spec *spec = codec->spec;
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002055 hda_nid_t dac;
Takashi Iwai38cf6f12012-12-21 14:09:42 +01002056
2057 if (!spec->indep_hp)
2058 return 0;
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002059 if (spec->autocfg.line_out_type == AUTO_PIN_HP_OUT)
2060 dac = spec->multiout.dac_nids[0];
2061 else
2062 dac = spec->multiout.hp_out_nid[0];
2063 if (!dac) {
Takashi Iwai38cf6f12012-12-21 14:09:42 +01002064 spec->indep_hp = 0;
2065 return 0;
2066 }
2067
2068 spec->indep_hp_enabled = false;
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002069 spec->alt_dac_nid = dac;
Takashi Iwai38cf6f12012-12-21 14:09:42 +01002070 if (!snd_hda_gen_add_kctl(spec, NULL, &indep_hp_ctl))
2071 return -ENOMEM;
2072 return 0;
2073}
2074
2075/*
Takashi Iwai352f7f92012-12-19 12:52:06 +01002076 * channel mode enum control
2077 */
2078
2079static int ch_mode_info(struct snd_kcontrol *kcontrol,
2080 struct snd_ctl_elem_info *uinfo)
2081{
2082 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2083 struct hda_gen_spec *spec = codec->spec;
Takashi Iwaia07a9492013-01-07 16:44:06 +01002084 int chs;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002085
2086 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2087 uinfo->count = 1;
2088 uinfo->value.enumerated.items = spec->multi_ios + 1;
2089 if (uinfo->value.enumerated.item > spec->multi_ios)
2090 uinfo->value.enumerated.item = spec->multi_ios;
Takashi Iwaia07a9492013-01-07 16:44:06 +01002091 chs = uinfo->value.enumerated.item * 2 + spec->min_channel_count;
2092 sprintf(uinfo->value.enumerated.name, "%dch", chs);
Takashi Iwai352f7f92012-12-19 12:52:06 +01002093 return 0;
2094}
2095
2096static int ch_mode_get(struct snd_kcontrol *kcontrol,
2097 struct snd_ctl_elem_value *ucontrol)
2098{
2099 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2100 struct hda_gen_spec *spec = codec->spec;
Takashi Iwaia07a9492013-01-07 16:44:06 +01002101 ucontrol->value.enumerated.item[0] =
2102 (spec->ext_channel_count - spec->min_channel_count) / 2;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002103 return 0;
2104}
2105
Takashi Iwai196c17662013-01-04 15:01:40 +01002106static inline struct nid_path *
2107get_multiio_path(struct hda_codec *codec, int idx)
2108{
2109 struct hda_gen_spec *spec = codec->spec;
2110 return snd_hda_get_path_from_idx(codec,
2111 spec->out_paths[spec->autocfg.line_outs + idx]);
2112}
2113
Takashi Iwaia5cc2502013-01-16 18:08:55 +01002114static void update_automute_all(struct hda_codec *codec);
2115
Takashi Iwai65033cc2013-04-16 12:31:05 +02002116/* Default value to be passed as aamix argument for snd_hda_activate_path();
2117 * used for output paths
2118 */
2119static bool aamix_default(struct hda_gen_spec *spec)
2120{
2121 return !spec->have_aamix_ctl || spec->aamix_mode;
2122}
2123
Takashi Iwai352f7f92012-12-19 12:52:06 +01002124static int set_multi_io(struct hda_codec *codec, int idx, bool output)
2125{
2126 struct hda_gen_spec *spec = codec->spec;
2127 hda_nid_t nid = spec->multi_io[idx].pin;
2128 struct nid_path *path;
2129
Takashi Iwai196c17662013-01-04 15:01:40 +01002130 path = get_multiio_path(codec, idx);
Takashi Iwai352f7f92012-12-19 12:52:06 +01002131 if (!path)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002132 return -EINVAL;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002133
2134 if (path->active == output)
2135 return 0;
2136
2137 if (output) {
Takashi Iwai2c12c302013-01-10 09:33:29 +01002138 set_pin_target(codec, nid, PIN_OUT, true);
Takashi Iwai65033cc2013-04-16 12:31:05 +02002139 snd_hda_activate_path(codec, path, true, aamix_default(spec));
Takashi Iwaid5a9f1b2012-12-20 15:36:30 +01002140 set_pin_eapd(codec, nid, true);
Takashi Iwai352f7f92012-12-19 12:52:06 +01002141 } else {
Takashi Iwaid5a9f1b2012-12-20 15:36:30 +01002142 set_pin_eapd(codec, nid, false);
Takashi Iwai65033cc2013-04-16 12:31:05 +02002143 snd_hda_activate_path(codec, path, false, aamix_default(spec));
Takashi Iwai2c12c302013-01-10 09:33:29 +01002144 set_pin_target(codec, nid, spec->multi_io[idx].ctl_in, true);
Takashi Iwai55196ff2013-01-24 17:32:56 +01002145 path_power_down_sync(codec, path);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146 }
Takashi Iwaia365fed2013-01-10 16:10:06 +01002147
2148 /* update jack retasking in case it modifies any of them */
Takashi Iwaia5cc2502013-01-16 18:08:55 +01002149 update_automute_all(codec);
Takashi Iwaia365fed2013-01-10 16:10:06 +01002150
Takashi Iwai352f7f92012-12-19 12:52:06 +01002151 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002152}
2153
Takashi Iwai352f7f92012-12-19 12:52:06 +01002154static int ch_mode_put(struct snd_kcontrol *kcontrol,
2155 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156{
Takashi Iwai352f7f92012-12-19 12:52:06 +01002157 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2158 struct hda_gen_spec *spec = codec->spec;
2159 int i, ch;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002160
Takashi Iwai352f7f92012-12-19 12:52:06 +01002161 ch = ucontrol->value.enumerated.item[0];
2162 if (ch < 0 || ch > spec->multi_ios)
2163 return -EINVAL;
Takashi Iwaia07a9492013-01-07 16:44:06 +01002164 if (ch == (spec->ext_channel_count - spec->min_channel_count) / 2)
Takashi Iwai352f7f92012-12-19 12:52:06 +01002165 return 0;
Takashi Iwaia07a9492013-01-07 16:44:06 +01002166 spec->ext_channel_count = ch * 2 + spec->min_channel_count;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002167 for (i = 0; i < spec->multi_ios; i++)
2168 set_multi_io(codec, i, i < ch);
2169 spec->multiout.max_channels = max(spec->ext_channel_count,
2170 spec->const_channel_count);
2171 if (spec->need_dac_fix)
2172 spec->multiout.num_dacs = spec->multiout.max_channels / 2;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002173 return 1;
2174}
2175
Takashi Iwai352f7f92012-12-19 12:52:06 +01002176static const struct snd_kcontrol_new channel_mode_enum = {
2177 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2178 .name = "Channel Mode",
2179 .info = ch_mode_info,
2180 .get = ch_mode_get,
2181 .put = ch_mode_put,
2182};
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183
Takashi Iwai352f7f92012-12-19 12:52:06 +01002184static int create_multi_channel_mode(struct hda_codec *codec)
2185{
2186 struct hda_gen_spec *spec = codec->spec;
2187
2188 if (spec->multi_ios > 0) {
Takashi Iwai12c93df2012-12-19 14:38:33 +01002189 if (!snd_hda_gen_add_kctl(spec, NULL, &channel_mode_enum))
Takashi Iwai352f7f92012-12-19 12:52:06 +01002190 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002191 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192 return 0;
2193}
2194
Takashi Iwai352f7f92012-12-19 12:52:06 +01002195/*
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01002196 * aamix loopback enable/disable switch
2197 */
2198
2199#define loopback_mixing_info indep_hp_info
2200
2201static int loopback_mixing_get(struct snd_kcontrol *kcontrol,
2202 struct snd_ctl_elem_value *ucontrol)
2203{
2204 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2205 struct hda_gen_spec *spec = codec->spec;
2206 ucontrol->value.enumerated.item[0] = spec->aamix_mode;
2207 return 0;
2208}
2209
2210static void update_aamix_paths(struct hda_codec *codec, bool do_mix,
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002211 int nomix_path_idx, int mix_path_idx,
2212 int out_type)
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01002213{
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002214 struct hda_gen_spec *spec = codec->spec;
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01002215 struct nid_path *nomix_path, *mix_path;
2216
2217 nomix_path = snd_hda_get_path_from_idx(codec, nomix_path_idx);
2218 mix_path = snd_hda_get_path_from_idx(codec, mix_path_idx);
2219 if (!nomix_path || !mix_path)
2220 return;
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002221
2222 /* if HP aamix path is driven from a different DAC and the
2223 * independent HP mode is ON, can't turn on aamix path
2224 */
2225 if (out_type == AUTO_PIN_HP_OUT && spec->indep_hp_enabled &&
2226 mix_path->path[0] != spec->alt_dac_nid)
2227 do_mix = false;
2228
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01002229 if (do_mix) {
2230 snd_hda_activate_path(codec, nomix_path, false, true);
2231 snd_hda_activate_path(codec, mix_path, true, true);
Takashi Iwai55196ff2013-01-24 17:32:56 +01002232 path_power_down_sync(codec, nomix_path);
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01002233 } else {
Takashi Iwai65033cc2013-04-16 12:31:05 +02002234 snd_hda_activate_path(codec, mix_path, false, false);
2235 snd_hda_activate_path(codec, nomix_path, true, false);
Takashi Iwai55196ff2013-01-24 17:32:56 +01002236 path_power_down_sync(codec, mix_path);
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01002237 }
2238}
2239
2240static int loopback_mixing_put(struct snd_kcontrol *kcontrol,
2241 struct snd_ctl_elem_value *ucontrol)
2242{
2243 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2244 struct hda_gen_spec *spec = codec->spec;
2245 unsigned int val = ucontrol->value.enumerated.item[0];
2246
2247 if (val == spec->aamix_mode)
2248 return 0;
2249 spec->aamix_mode = val;
2250 update_aamix_paths(codec, val, spec->out_paths[0],
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002251 spec->aamix_out_paths[0],
2252 spec->autocfg.line_out_type);
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01002253 update_aamix_paths(codec, val, spec->hp_paths[0],
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002254 spec->aamix_out_paths[1],
2255 AUTO_PIN_HP_OUT);
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01002256 update_aamix_paths(codec, val, spec->speaker_paths[0],
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002257 spec->aamix_out_paths[2],
2258 AUTO_PIN_SPEAKER_OUT);
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01002259 return 1;
2260}
2261
2262static const struct snd_kcontrol_new loopback_mixing_enum = {
2263 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2264 .name = "Loopback Mixing",
2265 .info = loopback_mixing_info,
2266 .get = loopback_mixing_get,
2267 .put = loopback_mixing_put,
2268};
2269
2270static int create_loopback_mixing_ctl(struct hda_codec *codec)
2271{
2272 struct hda_gen_spec *spec = codec->spec;
2273
2274 if (!spec->mixer_nid)
2275 return 0;
2276 if (!(spec->aamix_out_paths[0] || spec->aamix_out_paths[1] ||
2277 spec->aamix_out_paths[2]))
2278 return 0;
2279 if (!snd_hda_gen_add_kctl(spec, NULL, &loopback_mixing_enum))
2280 return -ENOMEM;
Takashi Iwaia1e908e2013-01-21 15:11:25 +01002281 spec->have_aamix_ctl = 1;
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01002282 return 0;
2283}
2284
2285/*
Takashi Iwai352f7f92012-12-19 12:52:06 +01002286 * shared headphone/mic handling
2287 */
Takashi Iwaicb53c622007-08-10 17:21:45 +02002288
Takashi Iwai352f7f92012-12-19 12:52:06 +01002289static void call_update_outputs(struct hda_codec *codec);
2290
2291/* for shared I/O, change the pin-control accordingly */
Takashi Iwai967303d2013-02-19 17:12:42 +01002292static void update_hp_mic(struct hda_codec *codec, int adc_mux, bool force)
Takashi Iwai352f7f92012-12-19 12:52:06 +01002293{
2294 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai967303d2013-02-19 17:12:42 +01002295 bool as_mic;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002296 unsigned int val;
Takashi Iwai967303d2013-02-19 17:12:42 +01002297 hda_nid_t pin;
2298
2299 pin = spec->hp_mic_pin;
2300 as_mic = spec->cur_mux[adc_mux] == spec->hp_mic_mux_idx;
2301
2302 if (!force) {
2303 val = snd_hda_codec_get_pin_target(codec, pin);
2304 if (as_mic) {
2305 if (val & PIN_IN)
2306 return;
2307 } else {
2308 if (val & PIN_OUT)
2309 return;
2310 }
2311 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01002312
2313 val = snd_hda_get_default_vref(codec, pin);
Takashi Iwai967303d2013-02-19 17:12:42 +01002314 /* if the HP pin doesn't support VREF and the codec driver gives an
2315 * alternative pin, set up the VREF on that pin instead
2316 */
Takashi Iwai352f7f92012-12-19 12:52:06 +01002317 if (val == AC_PINCTL_VREF_HIZ && spec->shared_mic_vref_pin) {
2318 const hda_nid_t vref_pin = spec->shared_mic_vref_pin;
2319 unsigned int vref_val = snd_hda_get_default_vref(codec, vref_pin);
2320 if (vref_val != AC_PINCTL_VREF_HIZ)
Takashi Iwai7594aa32012-12-20 15:38:40 +01002321 snd_hda_set_pin_ctl_cache(codec, vref_pin,
Takashi Iwai967303d2013-02-19 17:12:42 +01002322 PIN_IN | (as_mic ? vref_val : 0));
Takashi Iwaicb53c622007-08-10 17:21:45 +02002323 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01002324
Takashi Iwai8ba955c2013-03-07 18:40:58 +01002325 if (!spec->hp_mic_jack_modes) {
2326 if (as_mic)
2327 val |= PIN_IN;
2328 else
2329 val = PIN_HP;
2330 set_pin_target(codec, pin, val, true);
Takashi Iwai963afde2013-05-31 15:20:31 +02002331 call_hp_automute(codec, NULL);
Takashi Iwai8ba955c2013-03-07 18:40:58 +01002332 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01002333}
2334
2335/* create a shared input with the headphone out */
Takashi Iwai967303d2013-02-19 17:12:42 +01002336static int create_hp_mic(struct hda_codec *codec)
Takashi Iwai352f7f92012-12-19 12:52:06 +01002337{
2338 struct hda_gen_spec *spec = codec->spec;
2339 struct auto_pin_cfg *cfg = &spec->autocfg;
2340 unsigned int defcfg;
2341 hda_nid_t nid;
2342
Takashi Iwai967303d2013-02-19 17:12:42 +01002343 if (!spec->hp_mic) {
2344 if (spec->suppress_hp_mic_detect)
2345 return 0;
2346 /* automatic detection: only if no input or a single internal
2347 * input pin is found, try to detect the shared hp/mic
2348 */
2349 if (cfg->num_inputs > 1)
2350 return 0;
2351 else if (cfg->num_inputs == 1) {
2352 defcfg = snd_hda_codec_get_pincfg(codec, cfg->inputs[0].pin);
2353 if (snd_hda_get_input_pin_attr(defcfg) != INPUT_PIN_ATTR_INT)
2354 return 0;
2355 }
2356 }
2357
2358 spec->hp_mic = 0; /* clear once */
2359 if (cfg->num_inputs >= AUTO_CFG_MAX_INS)
Takashi Iwai352f7f92012-12-19 12:52:06 +01002360 return 0;
2361
Takashi Iwai967303d2013-02-19 17:12:42 +01002362 nid = 0;
2363 if (cfg->line_out_type == AUTO_PIN_HP_OUT && cfg->line_outs > 0)
2364 nid = cfg->line_out_pins[0];
2365 else if (cfg->hp_outs > 0)
2366 nid = cfg->hp_pins[0];
2367 if (!nid)
2368 return 0;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002369
2370 if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_IN))
2371 return 0; /* no input */
2372
Takashi Iwai967303d2013-02-19 17:12:42 +01002373 cfg->inputs[cfg->num_inputs].pin = nid;
2374 cfg->inputs[cfg->num_inputs].type = AUTO_PIN_MIC;
David Henningssoncb420b12013-04-11 11:30:28 +02002375 cfg->inputs[cfg->num_inputs].is_headphone_mic = 1;
Takashi Iwai967303d2013-02-19 17:12:42 +01002376 cfg->num_inputs++;
2377 spec->hp_mic = 1;
2378 spec->hp_mic_pin = nid;
2379 /* we can't handle auto-mic together with HP-mic */
2380 spec->suppress_auto_mic = 1;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002381 snd_printdd("hda-codec: Enable shared I/O jack on NID 0x%x\n", nid);
2382 return 0;
2383}
2384
Takashi Iwai978e77e2013-01-10 16:57:58 +01002385/*
2386 * output jack mode
2387 */
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002388
2389static int create_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t pin);
2390
2391static const char * const out_jack_texts[] = {
2392 "Line Out", "Headphone Out",
2393};
2394
Takashi Iwai978e77e2013-01-10 16:57:58 +01002395static int out_jack_mode_info(struct snd_kcontrol *kcontrol,
2396 struct snd_ctl_elem_info *uinfo)
2397{
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002398 return snd_hda_enum_helper_info(kcontrol, uinfo, 2, out_jack_texts);
Takashi Iwai978e77e2013-01-10 16:57:58 +01002399}
2400
2401static int out_jack_mode_get(struct snd_kcontrol *kcontrol,
2402 struct snd_ctl_elem_value *ucontrol)
2403{
2404 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2405 hda_nid_t nid = kcontrol->private_value;
2406 if (snd_hda_codec_get_pin_target(codec, nid) == PIN_HP)
2407 ucontrol->value.enumerated.item[0] = 1;
2408 else
2409 ucontrol->value.enumerated.item[0] = 0;
2410 return 0;
2411}
2412
2413static int out_jack_mode_put(struct snd_kcontrol *kcontrol,
2414 struct snd_ctl_elem_value *ucontrol)
2415{
2416 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2417 hda_nid_t nid = kcontrol->private_value;
2418 unsigned int val;
2419
2420 val = ucontrol->value.enumerated.item[0] ? PIN_HP : PIN_OUT;
2421 if (snd_hda_codec_get_pin_target(codec, nid) == val)
2422 return 0;
2423 snd_hda_set_pin_ctl_cache(codec, nid, val);
2424 return 1;
2425}
2426
2427static const struct snd_kcontrol_new out_jack_mode_enum = {
2428 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2429 .info = out_jack_mode_info,
2430 .get = out_jack_mode_get,
2431 .put = out_jack_mode_put,
2432};
2433
2434static bool find_kctl_name(struct hda_codec *codec, const char *name, int idx)
2435{
2436 struct hda_gen_spec *spec = codec->spec;
2437 int i;
2438
2439 for (i = 0; i < spec->kctls.used; i++) {
2440 struct snd_kcontrol_new *kctl = snd_array_elem(&spec->kctls, i);
2441 if (!strcmp(kctl->name, name) && kctl->index == idx)
2442 return true;
2443 }
2444 return false;
2445}
2446
2447static void get_jack_mode_name(struct hda_codec *codec, hda_nid_t pin,
2448 char *name, size_t name_len)
2449{
2450 struct hda_gen_spec *spec = codec->spec;
2451 int idx = 0;
2452
2453 snd_hda_get_pin_label(codec, pin, &spec->autocfg, name, name_len, &idx);
2454 strlcat(name, " Jack Mode", name_len);
2455
2456 for (; find_kctl_name(codec, name, idx); idx++)
2457 ;
2458}
2459
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002460static int get_out_jack_num_items(struct hda_codec *codec, hda_nid_t pin)
2461{
2462 struct hda_gen_spec *spec = codec->spec;
Takashi Iwaif811c3c2013-03-07 18:32:59 +01002463 if (spec->add_jack_modes) {
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002464 unsigned int pincap = snd_hda_query_pin_caps(codec, pin);
2465 if ((pincap & AC_PINCAP_OUT) && (pincap & AC_PINCAP_HP_DRV))
2466 return 2;
2467 }
2468 return 1;
2469}
2470
Takashi Iwai978e77e2013-01-10 16:57:58 +01002471static int create_out_jack_modes(struct hda_codec *codec, int num_pins,
2472 hda_nid_t *pins)
2473{
2474 struct hda_gen_spec *spec = codec->spec;
2475 int i;
2476
2477 for (i = 0; i < num_pins; i++) {
2478 hda_nid_t pin = pins[i];
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002479 if (pin == spec->hp_mic_pin) {
2480 int ret = create_hp_mic_jack_mode(codec, pin);
2481 if (ret < 0)
2482 return ret;
2483 continue;
2484 }
2485 if (get_out_jack_num_items(codec, pin) > 1) {
Takashi Iwai978e77e2013-01-10 16:57:58 +01002486 struct snd_kcontrol_new *knew;
Takashi Iwai975cc022013-06-28 11:56:49 +02002487 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
Takashi Iwai978e77e2013-01-10 16:57:58 +01002488 get_jack_mode_name(codec, pin, name, sizeof(name));
2489 knew = snd_hda_gen_add_kctl(spec, name,
2490 &out_jack_mode_enum);
2491 if (!knew)
2492 return -ENOMEM;
2493 knew->private_value = pin;
2494 }
2495 }
2496
2497 return 0;
2498}
2499
Takashi Iwai294765582013-01-17 09:52:11 +01002500/*
2501 * input jack mode
2502 */
2503
2504/* from AC_PINCTL_VREF_HIZ to AC_PINCTL_VREF_100 */
2505#define NUM_VREFS 6
2506
2507static const char * const vref_texts[NUM_VREFS] = {
2508 "Line In", "Mic 50pc Bias", "Mic 0V Bias",
2509 "", "Mic 80pc Bias", "Mic 100pc Bias"
2510};
2511
2512static unsigned int get_vref_caps(struct hda_codec *codec, hda_nid_t pin)
2513{
2514 unsigned int pincap;
2515
2516 pincap = snd_hda_query_pin_caps(codec, pin);
2517 pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
2518 /* filter out unusual vrefs */
2519 pincap &= ~(AC_PINCAP_VREF_GRD | AC_PINCAP_VREF_100);
2520 return pincap;
2521}
2522
2523/* convert from the enum item index to the vref ctl index (0=HIZ, 1=50%...) */
2524static int get_vref_idx(unsigned int vref_caps, unsigned int item_idx)
2525{
2526 unsigned int i, n = 0;
2527
2528 for (i = 0; i < NUM_VREFS; i++) {
2529 if (vref_caps & (1 << i)) {
2530 if (n == item_idx)
2531 return i;
2532 n++;
2533 }
2534 }
2535 return 0;
2536}
2537
2538/* convert back from the vref ctl index to the enum item index */
2539static int cvt_from_vref_idx(unsigned int vref_caps, unsigned int idx)
2540{
2541 unsigned int i, n = 0;
2542
2543 for (i = 0; i < NUM_VREFS; i++) {
2544 if (i == idx)
2545 return n;
2546 if (vref_caps & (1 << i))
2547 n++;
2548 }
2549 return 0;
2550}
2551
2552static int in_jack_mode_info(struct snd_kcontrol *kcontrol,
2553 struct snd_ctl_elem_info *uinfo)
2554{
2555 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2556 hda_nid_t nid = kcontrol->private_value;
2557 unsigned int vref_caps = get_vref_caps(codec, nid);
2558
2559 snd_hda_enum_helper_info(kcontrol, uinfo, hweight32(vref_caps),
2560 vref_texts);
2561 /* set the right text */
2562 strcpy(uinfo->value.enumerated.name,
2563 vref_texts[get_vref_idx(vref_caps, uinfo->value.enumerated.item)]);
2564 return 0;
2565}
2566
2567static int in_jack_mode_get(struct snd_kcontrol *kcontrol,
2568 struct snd_ctl_elem_value *ucontrol)
2569{
2570 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2571 hda_nid_t nid = kcontrol->private_value;
2572 unsigned int vref_caps = get_vref_caps(codec, nid);
2573 unsigned int idx;
2574
2575 idx = snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_VREFEN;
2576 ucontrol->value.enumerated.item[0] = cvt_from_vref_idx(vref_caps, idx);
2577 return 0;
2578}
2579
2580static int in_jack_mode_put(struct snd_kcontrol *kcontrol,
2581 struct snd_ctl_elem_value *ucontrol)
2582{
2583 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2584 hda_nid_t nid = kcontrol->private_value;
2585 unsigned int vref_caps = get_vref_caps(codec, nid);
2586 unsigned int val, idx;
2587
2588 val = snd_hda_codec_get_pin_target(codec, nid);
2589 idx = cvt_from_vref_idx(vref_caps, val & AC_PINCTL_VREFEN);
2590 if (idx == ucontrol->value.enumerated.item[0])
2591 return 0;
2592
2593 val &= ~AC_PINCTL_VREFEN;
2594 val |= get_vref_idx(vref_caps, ucontrol->value.enumerated.item[0]);
2595 snd_hda_set_pin_ctl_cache(codec, nid, val);
2596 return 1;
2597}
2598
2599static const struct snd_kcontrol_new in_jack_mode_enum = {
2600 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2601 .info = in_jack_mode_info,
2602 .get = in_jack_mode_get,
2603 .put = in_jack_mode_put,
2604};
2605
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002606static int get_in_jack_num_items(struct hda_codec *codec, hda_nid_t pin)
2607{
2608 struct hda_gen_spec *spec = codec->spec;
2609 int nitems = 0;
Takashi Iwaif811c3c2013-03-07 18:32:59 +01002610 if (spec->add_jack_modes)
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002611 nitems = hweight32(get_vref_caps(codec, pin));
2612 return nitems ? nitems : 1;
2613}
2614
Takashi Iwai294765582013-01-17 09:52:11 +01002615static int create_in_jack_mode(struct hda_codec *codec, hda_nid_t pin)
2616{
2617 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai294765582013-01-17 09:52:11 +01002618 struct snd_kcontrol_new *knew;
Takashi Iwai975cc022013-06-28 11:56:49 +02002619 char name[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002620 unsigned int defcfg;
2621
Takashi Iwaif811c3c2013-03-07 18:32:59 +01002622 if (pin == spec->hp_mic_pin)
2623 return 0; /* already done in create_out_jack_mode() */
Takashi Iwai294765582013-01-17 09:52:11 +01002624
2625 /* no jack mode for fixed pins */
2626 defcfg = snd_hda_codec_get_pincfg(codec, pin);
2627 if (snd_hda_get_input_pin_attr(defcfg) == INPUT_PIN_ATTR_INT)
2628 return 0;
2629
2630 /* no multiple vref caps? */
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002631 if (get_in_jack_num_items(codec, pin) <= 1)
Takashi Iwai294765582013-01-17 09:52:11 +01002632 return 0;
2633
2634 get_jack_mode_name(codec, pin, name, sizeof(name));
2635 knew = snd_hda_gen_add_kctl(spec, name, &in_jack_mode_enum);
2636 if (!knew)
2637 return -ENOMEM;
2638 knew->private_value = pin;
2639 return 0;
2640}
2641
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002642/*
2643 * HP/mic shared jack mode
2644 */
2645static int hp_mic_jack_mode_info(struct snd_kcontrol *kcontrol,
2646 struct snd_ctl_elem_info *uinfo)
2647{
2648 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2649 hda_nid_t nid = kcontrol->private_value;
2650 int out_jacks = get_out_jack_num_items(codec, nid);
2651 int in_jacks = get_in_jack_num_items(codec, nid);
2652 const char *text = NULL;
2653 int idx;
2654
2655 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
2656 uinfo->count = 1;
2657 uinfo->value.enumerated.items = out_jacks + in_jacks;
2658 if (uinfo->value.enumerated.item >= uinfo->value.enumerated.items)
2659 uinfo->value.enumerated.item = uinfo->value.enumerated.items - 1;
2660 idx = uinfo->value.enumerated.item;
2661 if (idx < out_jacks) {
2662 if (out_jacks > 1)
2663 text = out_jack_texts[idx];
2664 else
2665 text = "Headphone Out";
2666 } else {
2667 idx -= out_jacks;
2668 if (in_jacks > 1) {
2669 unsigned int vref_caps = get_vref_caps(codec, nid);
2670 text = vref_texts[get_vref_idx(vref_caps, idx)];
2671 } else
2672 text = "Mic In";
2673 }
2674
2675 strcpy(uinfo->value.enumerated.name, text);
2676 return 0;
2677}
2678
2679static int get_cur_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t nid)
2680{
2681 int out_jacks = get_out_jack_num_items(codec, nid);
2682 int in_jacks = get_in_jack_num_items(codec, nid);
2683 unsigned int val = snd_hda_codec_get_pin_target(codec, nid);
2684 int idx = 0;
2685
2686 if (val & PIN_OUT) {
2687 if (out_jacks > 1 && val == PIN_HP)
2688 idx = 1;
2689 } else if (val & PIN_IN) {
2690 idx = out_jacks;
2691 if (in_jacks > 1) {
2692 unsigned int vref_caps = get_vref_caps(codec, nid);
2693 val &= AC_PINCTL_VREFEN;
2694 idx += cvt_from_vref_idx(vref_caps, val);
2695 }
2696 }
2697 return idx;
2698}
2699
2700static int hp_mic_jack_mode_get(struct snd_kcontrol *kcontrol,
2701 struct snd_ctl_elem_value *ucontrol)
2702{
2703 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2704 hda_nid_t nid = kcontrol->private_value;
2705 ucontrol->value.enumerated.item[0] =
2706 get_cur_hp_mic_jack_mode(codec, nid);
2707 return 0;
2708}
2709
2710static int hp_mic_jack_mode_put(struct snd_kcontrol *kcontrol,
2711 struct snd_ctl_elem_value *ucontrol)
2712{
2713 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2714 hda_nid_t nid = kcontrol->private_value;
2715 int out_jacks = get_out_jack_num_items(codec, nid);
2716 int in_jacks = get_in_jack_num_items(codec, nid);
2717 unsigned int val, oldval, idx;
2718
2719 oldval = get_cur_hp_mic_jack_mode(codec, nid);
2720 idx = ucontrol->value.enumerated.item[0];
2721 if (oldval == idx)
2722 return 0;
2723
2724 if (idx < out_jacks) {
2725 if (out_jacks > 1)
2726 val = idx ? PIN_HP : PIN_OUT;
2727 else
2728 val = PIN_HP;
2729 } else {
2730 idx -= out_jacks;
2731 if (in_jacks > 1) {
2732 unsigned int vref_caps = get_vref_caps(codec, nid);
2733 val = snd_hda_codec_get_pin_target(codec, nid);
Takashi Iwai3f550e32013-03-07 18:30:27 +01002734 val &= ~(AC_PINCTL_VREFEN | PIN_HP);
2735 val |= get_vref_idx(vref_caps, idx) | PIN_IN;
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002736 } else
2737 val = snd_hda_get_default_vref(codec, nid);
2738 }
2739 snd_hda_set_pin_ctl_cache(codec, nid, val);
Takashi Iwai963afde2013-05-31 15:20:31 +02002740 call_hp_automute(codec, NULL);
Takashi Iwai8ba955c2013-03-07 18:40:58 +01002741
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002742 return 1;
2743}
2744
2745static const struct snd_kcontrol_new hp_mic_jack_mode_enum = {
2746 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2747 .info = hp_mic_jack_mode_info,
2748 .get = hp_mic_jack_mode_get,
2749 .put = hp_mic_jack_mode_put,
2750};
2751
2752static int create_hp_mic_jack_mode(struct hda_codec *codec, hda_nid_t pin)
2753{
2754 struct hda_gen_spec *spec = codec->spec;
2755 struct snd_kcontrol_new *knew;
2756
2757 if (get_out_jack_num_items(codec, pin) <= 1 &&
2758 get_in_jack_num_items(codec, pin) <= 1)
2759 return 0; /* no need */
2760 knew = snd_hda_gen_add_kctl(spec, "Headphone Mic Jack Mode",
2761 &hp_mic_jack_mode_enum);
2762 if (!knew)
2763 return -ENOMEM;
2764 knew->private_value = pin;
Takashi Iwai8ba955c2013-03-07 18:40:58 +01002765 spec->hp_mic_jack_modes = 1;
Takashi Iwai5f171ba2013-02-19 18:14:54 +01002766 return 0;
2767}
Takashi Iwai352f7f92012-12-19 12:52:06 +01002768
2769/*
2770 * Parse input paths
2771 */
2772
Takashi Iwai352f7f92012-12-19 12:52:06 +01002773/* add the powersave loopback-list entry */
Takashi Iwai0186f4f2013-02-07 10:45:11 +01002774static int add_loopback_list(struct hda_gen_spec *spec, hda_nid_t mix, int idx)
Takashi Iwai352f7f92012-12-19 12:52:06 +01002775{
2776 struct hda_amp_list *list;
2777
Takashi Iwai0186f4f2013-02-07 10:45:11 +01002778 list = snd_array_new(&spec->loopback_list);
2779 if (!list)
2780 return -ENOMEM;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002781 list->nid = mix;
2782 list->dir = HDA_INPUT;
2783 list->idx = idx;
Takashi Iwai0186f4f2013-02-07 10:45:11 +01002784 spec->loopback.amplist = spec->loopback_list.list;
2785 return 0;
Takashi Iwaicb53c622007-08-10 17:21:45 +02002786}
Takashi Iwaicb53c622007-08-10 17:21:45 +02002787
Takashi Iwai352f7f92012-12-19 12:52:06 +01002788/* create input playback/capture controls for the given pin */
Takashi Iwai196c17662013-01-04 15:01:40 +01002789static int new_analog_input(struct hda_codec *codec, int input_idx,
2790 hda_nid_t pin, const char *ctlname, int ctlidx,
Takashi Iwai352f7f92012-12-19 12:52:06 +01002791 hda_nid_t mix_nid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002792{
Takashi Iwai352f7f92012-12-19 12:52:06 +01002793 struct hda_gen_spec *spec = codec->spec;
2794 struct nid_path *path;
2795 unsigned int val;
2796 int err, idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797
Takashi Iwai352f7f92012-12-19 12:52:06 +01002798 if (!nid_has_volume(codec, mix_nid, HDA_INPUT) &&
2799 !nid_has_mute(codec, mix_nid, HDA_INPUT))
2800 return 0; /* no need for analog loopback */
2801
Takashi Iwai3ca529d2013-01-07 17:25:08 +01002802 path = snd_hda_add_new_path(codec, pin, mix_nid, 0);
Takashi Iwai352f7f92012-12-19 12:52:06 +01002803 if (!path)
2804 return -EINVAL;
Takashi Iwai0c8c0f52012-12-20 17:54:22 +01002805 print_nid_path("loopback", path);
Takashi Iwai196c17662013-01-04 15:01:40 +01002806 spec->loopback_paths[input_idx] = snd_hda_get_path_idx(codec, path);
Takashi Iwai352f7f92012-12-19 12:52:06 +01002807
2808 idx = path->idx[path->depth - 1];
2809 if (nid_has_volume(codec, mix_nid, HDA_INPUT)) {
2810 val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
2811 err = __add_pb_vol_ctrl(spec, HDA_CTL_WIDGET_VOL, ctlname, ctlidx, val);
Takashi Iwaid13bd412008-07-30 15:01:45 +02002812 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813 return err;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002814 path->ctls[NID_PATH_VOL_CTL] = val;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002815 }
2816
Takashi Iwai352f7f92012-12-19 12:52:06 +01002817 if (nid_has_mute(codec, mix_nid, HDA_INPUT)) {
2818 val = HDA_COMPOSE_AMP_VAL(mix_nid, 3, idx, HDA_INPUT);
2819 err = __add_pb_sw_ctrl(spec, HDA_CTL_WIDGET_MUTE, ctlname, ctlidx, val);
Takashi Iwaid13bd412008-07-30 15:01:45 +02002820 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002821 return err;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002822 path->ctls[NID_PATH_MUTE_CTL] = val;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002823 }
2824
Takashi Iwai352f7f92012-12-19 12:52:06 +01002825 path->active = true;
Takashi Iwai0186f4f2013-02-07 10:45:11 +01002826 err = add_loopback_list(spec, mix_nid, idx);
2827 if (err < 0)
2828 return err;
Takashi Iwaie4a395e2013-01-23 17:00:31 +01002829
2830 if (spec->mixer_nid != spec->mixer_merge_nid &&
2831 !spec->loopback_merge_path) {
2832 path = snd_hda_add_new_path(codec, spec->mixer_nid,
2833 spec->mixer_merge_nid, 0);
2834 if (path) {
2835 print_nid_path("loopback-merge", path);
2836 path->active = true;
2837 spec->loopback_merge_path =
2838 snd_hda_get_path_idx(codec, path);
2839 }
2840 }
2841
Takashi Iwai352f7f92012-12-19 12:52:06 +01002842 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002843}
2844
Takashi Iwai352f7f92012-12-19 12:52:06 +01002845static int is_input_pin(struct hda_codec *codec, hda_nid_t nid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002846{
Takashi Iwai352f7f92012-12-19 12:52:06 +01002847 unsigned int pincap = snd_hda_query_pin_caps(codec, nid);
2848 return (pincap & AC_PINCAP_IN) != 0;
2849}
2850
2851/* Parse the codec tree and retrieve ADCs */
2852static int fill_adc_nids(struct hda_codec *codec)
2853{
2854 struct hda_gen_spec *spec = codec->spec;
2855 hda_nid_t nid;
2856 hda_nid_t *adc_nids = spec->adc_nids;
2857 int max_nums = ARRAY_SIZE(spec->adc_nids);
2858 int i, nums = 0;
2859
2860 nid = codec->start_nid;
2861 for (i = 0; i < codec->num_nodes; i++, nid++) {
2862 unsigned int caps = get_wcaps(codec, nid);
2863 int type = get_wcaps_type(caps);
2864
2865 if (type != AC_WID_AUD_IN || (caps & AC_WCAP_DIGITAL))
2866 continue;
2867 adc_nids[nums] = nid;
2868 if (++nums >= max_nums)
2869 break;
2870 }
2871 spec->num_adc_nids = nums;
Takashi Iwai0ffd5342013-01-17 15:53:29 +01002872
2873 /* copy the detected ADCs to all_adcs[] */
2874 spec->num_all_adcs = nums;
2875 memcpy(spec->all_adcs, spec->adc_nids, nums * sizeof(hda_nid_t));
2876
Takashi Iwai352f7f92012-12-19 12:52:06 +01002877 return nums;
2878}
2879
2880/* filter out invalid adc_nids that don't give all active input pins;
2881 * if needed, check whether dynamic ADC-switching is available
2882 */
2883static int check_dyn_adc_switch(struct hda_codec *codec)
2884{
2885 struct hda_gen_spec *spec = codec->spec;
2886 struct hda_input_mux *imux = &spec->input_mux;
Takashi Iwai3a65bcd2013-01-09 09:06:18 +01002887 unsigned int ok_bits;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002888 int i, n, nums;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002889
Takashi Iwai352f7f92012-12-19 12:52:06 +01002890 nums = 0;
Takashi Iwai3a65bcd2013-01-09 09:06:18 +01002891 ok_bits = 0;
Takashi Iwai352f7f92012-12-19 12:52:06 +01002892 for (n = 0; n < spec->num_adc_nids; n++) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01002893 for (i = 0; i < imux->num_items; i++) {
Takashi Iwai3a65bcd2013-01-09 09:06:18 +01002894 if (!spec->input_paths[i][n])
Takashi Iwai352f7f92012-12-19 12:52:06 +01002895 break;
2896 }
Takashi Iwai3a65bcd2013-01-09 09:06:18 +01002897 if (i >= imux->num_items) {
2898 ok_bits |= (1 << n);
2899 nums++;
2900 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01002901 }
2902
Takashi Iwai3a65bcd2013-01-09 09:06:18 +01002903 if (!ok_bits) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01002904 /* check whether ADC-switch is possible */
2905 for (i = 0; i < imux->num_items; i++) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01002906 for (n = 0; n < spec->num_adc_nids; n++) {
Takashi Iwai3a65bcd2013-01-09 09:06:18 +01002907 if (spec->input_paths[i][n]) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01002908 spec->dyn_adc_idx[i] = n;
2909 break;
2910 }
2911 }
2912 }
2913
2914 snd_printdd("hda-codec: enabling ADC switching\n");
2915 spec->dyn_adc_switch = 1;
2916 } else if (nums != spec->num_adc_nids) {
Takashi Iwai3a65bcd2013-01-09 09:06:18 +01002917 /* shrink the invalid adcs and input paths */
2918 nums = 0;
2919 for (n = 0; n < spec->num_adc_nids; n++) {
2920 if (!(ok_bits & (1 << n)))
2921 continue;
2922 if (n != nums) {
2923 spec->adc_nids[nums] = spec->adc_nids[n];
Takashi Iwai980428c2013-01-09 09:28:20 +01002924 for (i = 0; i < imux->num_items; i++) {
2925 invalidate_nid_path(codec,
2926 spec->input_paths[i][nums]);
Takashi Iwai3a65bcd2013-01-09 09:06:18 +01002927 spec->input_paths[i][nums] =
2928 spec->input_paths[i][n];
Takashi Iwai980428c2013-01-09 09:28:20 +01002929 }
Takashi Iwai3a65bcd2013-01-09 09:06:18 +01002930 }
2931 nums++;
2932 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01002933 spec->num_adc_nids = nums;
2934 }
2935
Takashi Iwai967303d2013-02-19 17:12:42 +01002936 if (imux->num_items == 1 ||
2937 (imux->num_items == 2 && spec->hp_mic)) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01002938 snd_printdd("hda-codec: reducing to a single ADC\n");
2939 spec->num_adc_nids = 1; /* reduce to a single ADC */
2940 }
2941
2942 /* single index for individual volumes ctls */
2943 if (!spec->dyn_adc_switch && spec->multi_cap_vol)
2944 spec->num_adc_nids = 1;
2945
Linus Torvalds1da177e2005-04-16 15:20:36 -07002946 return 0;
2947}
2948
Takashi Iwaif3fc0b02013-01-09 09:14:23 +01002949/* parse capture source paths from the given pin and create imux items */
2950static int parse_capture_source(struct hda_codec *codec, hda_nid_t pin,
Takashi Iwai9dba2052013-01-18 10:01:15 +01002951 int cfg_idx, int num_adcs,
2952 const char *label, int anchor)
Takashi Iwaif3fc0b02013-01-09 09:14:23 +01002953{
2954 struct hda_gen_spec *spec = codec->spec;
2955 struct hda_input_mux *imux = &spec->input_mux;
2956 int imux_idx = imux->num_items;
2957 bool imux_added = false;
2958 int c;
2959
2960 for (c = 0; c < num_adcs; c++) {
2961 struct nid_path *path;
2962 hda_nid_t adc = spec->adc_nids[c];
2963
2964 if (!is_reachable_path(codec, pin, adc))
2965 continue;
2966 path = snd_hda_add_new_path(codec, pin, adc, anchor);
2967 if (!path)
2968 continue;
2969 print_nid_path("input", path);
2970 spec->input_paths[imux_idx][c] =
2971 snd_hda_get_path_idx(codec, path);
2972
2973 if (!imux_added) {
Takashi Iwai967303d2013-02-19 17:12:42 +01002974 if (spec->hp_mic_pin == pin)
2975 spec->hp_mic_mux_idx = imux->num_items;
Takashi Iwaif3fc0b02013-01-09 09:14:23 +01002976 spec->imux_pins[imux->num_items] = pin;
Takashi Iwai9dba2052013-01-18 10:01:15 +01002977 snd_hda_add_imux_item(imux, label, cfg_idx, NULL);
Takashi Iwaif3fc0b02013-01-09 09:14:23 +01002978 imux_added = true;
2979 }
2980 }
2981
2982 return 0;
2983}
2984
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985/*
Takashi Iwai352f7f92012-12-19 12:52:06 +01002986 * create playback/capture controls for input pins
Linus Torvalds1da177e2005-04-16 15:20:36 -07002987 */
Takashi Iwai9dba2052013-01-18 10:01:15 +01002988
Takashi Iwaic9700422013-01-18 10:17:30 +01002989/* fill the label for each input at first */
2990static int fill_input_pin_labels(struct hda_codec *codec)
2991{
2992 struct hda_gen_spec *spec = codec->spec;
2993 const struct auto_pin_cfg *cfg = &spec->autocfg;
2994 int i;
2995
2996 for (i = 0; i < cfg->num_inputs; i++) {
2997 hda_nid_t pin = cfg->inputs[i].pin;
2998 const char *label;
2999 int j, idx;
3000
3001 if (!is_input_pin(codec, pin))
3002 continue;
3003
3004 label = hda_get_autocfg_input_label(codec, cfg, i);
3005 idx = 0;
David Henningsson8e8db7f2013-01-18 15:43:02 +01003006 for (j = i - 1; j >= 0; j--) {
Takashi Iwaic9700422013-01-18 10:17:30 +01003007 if (spec->input_labels[j] &&
3008 !strcmp(spec->input_labels[j], label)) {
3009 idx = spec->input_label_idxs[j] + 1;
3010 break;
3011 }
3012 }
3013
3014 spec->input_labels[i] = label;
3015 spec->input_label_idxs[i] = idx;
3016 }
3017
3018 return 0;
3019}
3020
Takashi Iwai9dba2052013-01-18 10:01:15 +01003021#define CFG_IDX_MIX 99 /* a dummy cfg->input idx for stereo mix */
3022
Takashi Iwai352f7f92012-12-19 12:52:06 +01003023static int create_input_ctls(struct hda_codec *codec)
Takashi Iwaia7da6ce2006-09-06 14:03:14 +02003024{
Takashi Iwai352f7f92012-12-19 12:52:06 +01003025 struct hda_gen_spec *spec = codec->spec;
3026 const struct auto_pin_cfg *cfg = &spec->autocfg;
3027 hda_nid_t mixer = spec->mixer_nid;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003028 int num_adcs;
Takashi Iwaic9700422013-01-18 10:17:30 +01003029 int i, err;
Takashi Iwai2c12c302013-01-10 09:33:29 +01003030 unsigned int val;
Takashi Iwaia7da6ce2006-09-06 14:03:14 +02003031
Takashi Iwai352f7f92012-12-19 12:52:06 +01003032 num_adcs = fill_adc_nids(codec);
3033 if (num_adcs < 0)
3034 return 0;
Takashi Iwaia7da6ce2006-09-06 14:03:14 +02003035
Takashi Iwaic9700422013-01-18 10:17:30 +01003036 err = fill_input_pin_labels(codec);
3037 if (err < 0)
3038 return err;
3039
Takashi Iwai352f7f92012-12-19 12:52:06 +01003040 for (i = 0; i < cfg->num_inputs; i++) {
3041 hda_nid_t pin;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003042
Takashi Iwai352f7f92012-12-19 12:52:06 +01003043 pin = cfg->inputs[i].pin;
3044 if (!is_input_pin(codec, pin))
3045 continue;
3046
Takashi Iwai2c12c302013-01-10 09:33:29 +01003047 val = PIN_IN;
3048 if (cfg->inputs[i].type == AUTO_PIN_MIC)
3049 val |= snd_hda_get_default_vref(codec, pin);
Takashi Iwai93c9d8a2013-03-11 09:48:43 +01003050 if (pin != spec->hp_mic_pin)
3051 set_pin_target(codec, pin, val, false);
Takashi Iwai2c12c302013-01-10 09:33:29 +01003052
Takashi Iwai352f7f92012-12-19 12:52:06 +01003053 if (mixer) {
3054 if (is_reachable_path(codec, pin, mixer)) {
Takashi Iwai196c17662013-01-04 15:01:40 +01003055 err = new_analog_input(codec, i, pin,
Takashi Iwaic9700422013-01-18 10:17:30 +01003056 spec->input_labels[i],
3057 spec->input_label_idxs[i],
3058 mixer);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003059 if (err < 0)
3060 return err;
3061 }
3062 }
3063
Takashi Iwaic9700422013-01-18 10:17:30 +01003064 err = parse_capture_source(codec, pin, i, num_adcs,
3065 spec->input_labels[i], -mixer);
Takashi Iwaif3fc0b02013-01-09 09:14:23 +01003066 if (err < 0)
3067 return err;
Takashi Iwai294765582013-01-17 09:52:11 +01003068
Takashi Iwaif811c3c2013-03-07 18:32:59 +01003069 if (spec->add_jack_modes) {
Takashi Iwai294765582013-01-17 09:52:11 +01003070 err = create_in_jack_mode(codec, pin);
3071 if (err < 0)
3072 return err;
3073 }
Takashi Iwaif3fc0b02013-01-09 09:14:23 +01003074 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01003075
Takashi Iwaif3fc0b02013-01-09 09:14:23 +01003076 if (mixer && spec->add_stereo_mix_input) {
Takashi Iwai9dba2052013-01-18 10:01:15 +01003077 err = parse_capture_source(codec, mixer, CFG_IDX_MIX, num_adcs,
Takashi Iwaif3fc0b02013-01-09 09:14:23 +01003078 "Stereo Mix", 0);
3079 if (err < 0)
3080 return err;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003081 }
3082
3083 return 0;
3084}
3085
3086
3087/*
3088 * input source mux
3089 */
3090
Takashi Iwaic697b712013-01-07 17:09:26 +01003091/* get the input path specified by the given adc and imux indices */
3092static struct nid_path *get_input_path(struct hda_codec *codec, int adc_idx, int imux_idx)
Takashi Iwai352f7f92012-12-19 12:52:06 +01003093{
3094 struct hda_gen_spec *spec = codec->spec;
David Henningssonb56fa1e2013-01-16 11:45:35 +01003095 if (imux_idx < 0 || imux_idx >= HDA_MAX_NUM_INPUTS) {
3096 snd_BUG();
3097 return NULL;
3098 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01003099 if (spec->dyn_adc_switch)
3100 adc_idx = spec->dyn_adc_idx[imux_idx];
David Henningssond3d982f2013-01-18 15:43:01 +01003101 if (adc_idx < 0 || adc_idx >= AUTO_CFG_MAX_INS) {
David Henningssonb56fa1e2013-01-16 11:45:35 +01003102 snd_BUG();
3103 return NULL;
3104 }
Takashi Iwaic697b712013-01-07 17:09:26 +01003105 return snd_hda_get_path_from_idx(codec, spec->input_paths[imux_idx][adc_idx]);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003106}
3107
3108static int mux_select(struct hda_codec *codec, unsigned int adc_idx,
3109 unsigned int idx);
3110
3111static int mux_enum_info(struct snd_kcontrol *kcontrol,
3112 struct snd_ctl_elem_info *uinfo)
3113{
3114 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3115 struct hda_gen_spec *spec = codec->spec;
3116 return snd_hda_input_mux_info(&spec->input_mux, uinfo);
3117}
3118
3119static int mux_enum_get(struct snd_kcontrol *kcontrol,
3120 struct snd_ctl_elem_value *ucontrol)
3121{
3122 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3123 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai2a8d5392013-01-18 16:23:25 +01003124 /* the ctls are created at once with multiple counts */
3125 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003126
3127 ucontrol->value.enumerated.item[0] = spec->cur_mux[adc_idx];
3128 return 0;
3129}
3130
3131static int mux_enum_put(struct snd_kcontrol *kcontrol,
3132 struct snd_ctl_elem_value *ucontrol)
3133{
3134 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
Takashi Iwai2a8d5392013-01-18 16:23:25 +01003135 unsigned int adc_idx = snd_ctl_get_ioffidx(kcontrol, &ucontrol->id);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003136 return mux_select(codec, adc_idx,
3137 ucontrol->value.enumerated.item[0]);
3138}
3139
Takashi Iwai352f7f92012-12-19 12:52:06 +01003140static const struct snd_kcontrol_new cap_src_temp = {
3141 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3142 .name = "Input Source",
3143 .info = mux_enum_info,
3144 .get = mux_enum_get,
3145 .put = mux_enum_put,
3146};
3147
Takashi Iwai47d46ab2012-12-20 11:48:54 +01003148/*
3149 * capture volume and capture switch ctls
3150 */
3151
Takashi Iwai352f7f92012-12-19 12:52:06 +01003152typedef int (*put_call_t)(struct snd_kcontrol *kcontrol,
3153 struct snd_ctl_elem_value *ucontrol);
3154
Takashi Iwai47d46ab2012-12-20 11:48:54 +01003155/* call the given amp update function for all amps in the imux list at once */
Takashi Iwai352f7f92012-12-19 12:52:06 +01003156static int cap_put_caller(struct snd_kcontrol *kcontrol,
3157 struct snd_ctl_elem_value *ucontrol,
3158 put_call_t func, int type)
3159{
3160 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3161 struct hda_gen_spec *spec = codec->spec;
3162 const struct hda_input_mux *imux;
3163 struct nid_path *path;
3164 int i, adc_idx, err = 0;
3165
3166 imux = &spec->input_mux;
David Henningssona053d1e2013-01-16 11:45:36 +01003167 adc_idx = kcontrol->id.index;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003168 mutex_lock(&codec->control_mutex);
Takashi Iwai47d46ab2012-12-20 11:48:54 +01003169 /* we use the cache-only update at first since multiple input paths
3170 * may shared the same amp; by updating only caches, the redundant
3171 * writes to hardware can be reduced.
3172 */
Takashi Iwai352f7f92012-12-19 12:52:06 +01003173 codec->cached_write = 1;
3174 for (i = 0; i < imux->num_items; i++) {
Takashi Iwaic697b712013-01-07 17:09:26 +01003175 path = get_input_path(codec, adc_idx, i);
3176 if (!path || !path->ctls[type])
Takashi Iwai352f7f92012-12-19 12:52:06 +01003177 continue;
3178 kcontrol->private_value = path->ctls[type];
3179 err = func(kcontrol, ucontrol);
3180 if (err < 0)
3181 goto error;
3182 }
3183 error:
3184 codec->cached_write = 0;
3185 mutex_unlock(&codec->control_mutex);
Takashi Iwaidc870f32013-01-22 15:24:30 +01003186 snd_hda_codec_flush_cache(codec); /* flush the updates */
Takashi Iwai352f7f92012-12-19 12:52:06 +01003187 if (err >= 0 && spec->cap_sync_hook)
Takashi Iwaia90229e2013-01-18 14:10:00 +01003188 spec->cap_sync_hook(codec, ucontrol);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003189 return err;
3190}
3191
3192/* capture volume ctl callbacks */
3193#define cap_vol_info snd_hda_mixer_amp_volume_info
3194#define cap_vol_get snd_hda_mixer_amp_volume_get
3195#define cap_vol_tlv snd_hda_mixer_amp_tlv
3196
3197static int cap_vol_put(struct snd_kcontrol *kcontrol,
3198 struct snd_ctl_elem_value *ucontrol)
3199{
3200 return cap_put_caller(kcontrol, ucontrol,
3201 snd_hda_mixer_amp_volume_put,
3202 NID_PATH_VOL_CTL);
3203}
3204
3205static const struct snd_kcontrol_new cap_vol_temp = {
3206 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3207 .name = "Capture Volume",
3208 .access = (SNDRV_CTL_ELEM_ACCESS_READWRITE |
3209 SNDRV_CTL_ELEM_ACCESS_TLV_READ |
3210 SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK),
3211 .info = cap_vol_info,
3212 .get = cap_vol_get,
3213 .put = cap_vol_put,
3214 .tlv = { .c = cap_vol_tlv },
3215};
3216
3217/* capture switch ctl callbacks */
3218#define cap_sw_info snd_ctl_boolean_stereo_info
3219#define cap_sw_get snd_hda_mixer_amp_switch_get
3220
3221static int cap_sw_put(struct snd_kcontrol *kcontrol,
3222 struct snd_ctl_elem_value *ucontrol)
3223{
Takashi Iwaia90229e2013-01-18 14:10:00 +01003224 return cap_put_caller(kcontrol, ucontrol,
Takashi Iwai352f7f92012-12-19 12:52:06 +01003225 snd_hda_mixer_amp_switch_put,
3226 NID_PATH_MUTE_CTL);
3227}
3228
3229static const struct snd_kcontrol_new cap_sw_temp = {
3230 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
3231 .name = "Capture Switch",
3232 .info = cap_sw_info,
3233 .get = cap_sw_get,
3234 .put = cap_sw_put,
3235};
3236
3237static int parse_capvol_in_path(struct hda_codec *codec, struct nid_path *path)
3238{
3239 hda_nid_t nid;
3240 int i, depth;
3241
3242 path->ctls[NID_PATH_VOL_CTL] = path->ctls[NID_PATH_MUTE_CTL] = 0;
3243 for (depth = 0; depth < 3; depth++) {
3244 if (depth >= path->depth)
3245 return -EINVAL;
3246 i = path->depth - depth - 1;
3247 nid = path->path[i];
3248 if (!path->ctls[NID_PATH_VOL_CTL]) {
3249 if (nid_has_volume(codec, nid, HDA_OUTPUT))
3250 path->ctls[NID_PATH_VOL_CTL] =
3251 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3252 else if (nid_has_volume(codec, nid, HDA_INPUT)) {
3253 int idx = path->idx[i];
3254 if (!depth && codec->single_adc_amp)
3255 idx = 0;
3256 path->ctls[NID_PATH_VOL_CTL] =
3257 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_INPUT);
3258 }
3259 }
3260 if (!path->ctls[NID_PATH_MUTE_CTL]) {
3261 if (nid_has_mute(codec, nid, HDA_OUTPUT))
3262 path->ctls[NID_PATH_MUTE_CTL] =
3263 HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3264 else if (nid_has_mute(codec, nid, HDA_INPUT)) {
3265 int idx = path->idx[i];
3266 if (!depth && codec->single_adc_amp)
3267 idx = 0;
3268 path->ctls[NID_PATH_MUTE_CTL] =
3269 HDA_COMPOSE_AMP_VAL(nid, 3, idx, HDA_INPUT);
3270 }
3271 }
Takashi Iwai97ec5582006-03-21 11:29:07 +01003272 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273 return 0;
3274}
3275
Takashi Iwai352f7f92012-12-19 12:52:06 +01003276static bool is_inv_dmic_pin(struct hda_codec *codec, hda_nid_t nid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003277{
Takashi Iwai352f7f92012-12-19 12:52:06 +01003278 struct hda_gen_spec *spec = codec->spec;
3279 struct auto_pin_cfg *cfg = &spec->autocfg;
3280 unsigned int val;
3281 int i;
3282
3283 if (!spec->inv_dmic_split)
3284 return false;
3285 for (i = 0; i < cfg->num_inputs; i++) {
3286 if (cfg->inputs[i].pin != nid)
3287 continue;
3288 if (cfg->inputs[i].type != AUTO_PIN_MIC)
3289 return false;
3290 val = snd_hda_codec_get_pincfg(codec, nid);
3291 return snd_hda_get_input_pin_attr(val) == INPUT_PIN_ATTR_INT;
3292 }
3293 return false;
3294}
3295
Takashi Iwaia90229e2013-01-18 14:10:00 +01003296/* capture switch put callback for a single control with hook call */
Takashi Iwaia35bd1e2013-01-18 14:01:14 +01003297static int cap_single_sw_put(struct snd_kcontrol *kcontrol,
3298 struct snd_ctl_elem_value *ucontrol)
3299{
3300 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3301 struct hda_gen_spec *spec = codec->spec;
3302 int ret;
3303
3304 ret = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
3305 if (ret < 0)
3306 return ret;
3307
Takashi Iwaia90229e2013-01-18 14:10:00 +01003308 if (spec->cap_sync_hook)
3309 spec->cap_sync_hook(codec, ucontrol);
Takashi Iwaia35bd1e2013-01-18 14:01:14 +01003310
3311 return ret;
3312}
3313
Takashi Iwai352f7f92012-12-19 12:52:06 +01003314static int add_single_cap_ctl(struct hda_codec *codec, const char *label,
3315 int idx, bool is_switch, unsigned int ctl,
3316 bool inv_dmic)
3317{
3318 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai975cc022013-06-28 11:56:49 +02003319 char tmpname[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
Takashi Iwai352f7f92012-12-19 12:52:06 +01003320 int type = is_switch ? HDA_CTL_WIDGET_MUTE : HDA_CTL_WIDGET_VOL;
3321 const char *sfx = is_switch ? "Switch" : "Volume";
3322 unsigned int chs = inv_dmic ? 1 : 3;
Takashi Iwaia35bd1e2013-01-18 14:01:14 +01003323 struct snd_kcontrol_new *knew;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003324
3325 if (!ctl)
3326 return 0;
3327
3328 if (label)
3329 snprintf(tmpname, sizeof(tmpname),
3330 "%s Capture %s", label, sfx);
3331 else
3332 snprintf(tmpname, sizeof(tmpname),
3333 "Capture %s", sfx);
Takashi Iwaia35bd1e2013-01-18 14:01:14 +01003334 knew = add_control(spec, type, tmpname, idx,
3335 amp_val_replace_channels(ctl, chs));
3336 if (!knew)
3337 return -ENOMEM;
Takashi Iwaia90229e2013-01-18 14:10:00 +01003338 if (is_switch)
Takashi Iwaia35bd1e2013-01-18 14:01:14 +01003339 knew->put = cap_single_sw_put;
3340 if (!inv_dmic)
3341 return 0;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003342
3343 /* Make independent right kcontrol */
3344 if (label)
3345 snprintf(tmpname, sizeof(tmpname),
3346 "Inverted %s Capture %s", label, sfx);
3347 else
3348 snprintf(tmpname, sizeof(tmpname),
3349 "Inverted Capture %s", sfx);
Takashi Iwaia35bd1e2013-01-18 14:01:14 +01003350 knew = add_control(spec, type, tmpname, idx,
Takashi Iwai352f7f92012-12-19 12:52:06 +01003351 amp_val_replace_channels(ctl, 2));
Takashi Iwaia35bd1e2013-01-18 14:01:14 +01003352 if (!knew)
3353 return -ENOMEM;
Takashi Iwaia90229e2013-01-18 14:10:00 +01003354 if (is_switch)
Takashi Iwaia35bd1e2013-01-18 14:01:14 +01003355 knew->put = cap_single_sw_put;
3356 return 0;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003357}
3358
3359/* create single (and simple) capture volume and switch controls */
3360static int create_single_cap_vol_ctl(struct hda_codec *codec, int idx,
3361 unsigned int vol_ctl, unsigned int sw_ctl,
3362 bool inv_dmic)
3363{
3364 int err;
3365 err = add_single_cap_ctl(codec, NULL, idx, false, vol_ctl, inv_dmic);
3366 if (err < 0)
3367 return err;
3368 err = add_single_cap_ctl(codec, NULL, idx, true, sw_ctl, inv_dmic);
3369 if (err < 0)
3370 return err;
3371 return 0;
3372}
3373
3374/* create bound capture volume and switch controls */
3375static int create_bind_cap_vol_ctl(struct hda_codec *codec, int idx,
3376 unsigned int vol_ctl, unsigned int sw_ctl)
3377{
3378 struct hda_gen_spec *spec = codec->spec;
3379 struct snd_kcontrol_new *knew;
3380
3381 if (vol_ctl) {
Takashi Iwai12c93df2012-12-19 14:38:33 +01003382 knew = snd_hda_gen_add_kctl(spec, NULL, &cap_vol_temp);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003383 if (!knew)
3384 return -ENOMEM;
3385 knew->index = idx;
3386 knew->private_value = vol_ctl;
3387 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
3388 }
3389 if (sw_ctl) {
Takashi Iwai12c93df2012-12-19 14:38:33 +01003390 knew = snd_hda_gen_add_kctl(spec, NULL, &cap_sw_temp);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003391 if (!knew)
3392 return -ENOMEM;
3393 knew->index = idx;
3394 knew->private_value = sw_ctl;
3395 knew->subdevice = HDA_SUBDEV_AMP_FLAG;
3396 }
3397 return 0;
3398}
3399
3400/* return the vol ctl when used first in the imux list */
3401static unsigned int get_first_cap_ctl(struct hda_codec *codec, int idx, int type)
3402{
Takashi Iwai352f7f92012-12-19 12:52:06 +01003403 struct nid_path *path;
3404 unsigned int ctl;
3405 int i;
3406
Takashi Iwaic697b712013-01-07 17:09:26 +01003407 path = get_input_path(codec, 0, idx);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003408 if (!path)
3409 return 0;
3410 ctl = path->ctls[type];
3411 if (!ctl)
3412 return 0;
3413 for (i = 0; i < idx - 1; i++) {
Takashi Iwaic697b712013-01-07 17:09:26 +01003414 path = get_input_path(codec, 0, i);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003415 if (path && path->ctls[type] == ctl)
3416 return 0;
3417 }
3418 return ctl;
3419}
3420
3421/* create individual capture volume and switch controls per input */
3422static int create_multi_cap_vol_ctl(struct hda_codec *codec)
3423{
3424 struct hda_gen_spec *spec = codec->spec;
3425 struct hda_input_mux *imux = &spec->input_mux;
Takashi Iwaic9700422013-01-18 10:17:30 +01003426 int i, err, type;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003427
3428 for (i = 0; i < imux->num_items; i++) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01003429 bool inv_dmic;
Takashi Iwaic9700422013-01-18 10:17:30 +01003430 int idx;
Takashi Iwai9dba2052013-01-18 10:01:15 +01003431
Takashi Iwaic9700422013-01-18 10:17:30 +01003432 idx = imux->items[i].index;
3433 if (idx >= spec->autocfg.num_inputs)
Takashi Iwai9dba2052013-01-18 10:01:15 +01003434 continue;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003435 inv_dmic = is_inv_dmic_pin(codec, spec->imux_pins[i]);
3436
3437 for (type = 0; type < 2; type++) {
Takashi Iwaic9700422013-01-18 10:17:30 +01003438 err = add_single_cap_ctl(codec,
3439 spec->input_labels[idx],
3440 spec->input_label_idxs[idx],
3441 type,
Takashi Iwai352f7f92012-12-19 12:52:06 +01003442 get_first_cap_ctl(codec, i, type),
3443 inv_dmic);
3444 if (err < 0)
3445 return err;
3446 }
3447 }
3448 return 0;
3449}
3450
3451static int create_capture_mixers(struct hda_codec *codec)
3452{
3453 struct hda_gen_spec *spec = codec->spec;
3454 struct hda_input_mux *imux = &spec->input_mux;
3455 int i, n, nums, err;
3456
3457 if (spec->dyn_adc_switch)
3458 nums = 1;
3459 else
3460 nums = spec->num_adc_nids;
3461
3462 if (!spec->auto_mic && imux->num_items > 1) {
3463 struct snd_kcontrol_new *knew;
Takashi Iwai624d9142012-12-19 17:41:52 +01003464 const char *name;
3465 name = nums > 1 ? "Input Source" : "Capture Source";
3466 knew = snd_hda_gen_add_kctl(spec, name, &cap_src_temp);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003467 if (!knew)
3468 return -ENOMEM;
3469 knew->count = nums;
3470 }
3471
3472 for (n = 0; n < nums; n++) {
3473 bool multi = false;
David Henningsson99a55922013-01-16 15:58:44 +01003474 bool multi_cap_vol = spec->multi_cap_vol;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003475 bool inv_dmic = false;
3476 int vol, sw;
3477
3478 vol = sw = 0;
3479 for (i = 0; i < imux->num_items; i++) {
3480 struct nid_path *path;
Takashi Iwaic697b712013-01-07 17:09:26 +01003481 path = get_input_path(codec, n, i);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003482 if (!path)
3483 continue;
3484 parse_capvol_in_path(codec, path);
3485 if (!vol)
3486 vol = path->ctls[NID_PATH_VOL_CTL];
David Henningsson99a55922013-01-16 15:58:44 +01003487 else if (vol != path->ctls[NID_PATH_VOL_CTL]) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01003488 multi = true;
David Henningsson99a55922013-01-16 15:58:44 +01003489 if (!same_amp_caps(codec, vol,
3490 path->ctls[NID_PATH_VOL_CTL], HDA_INPUT))
3491 multi_cap_vol = true;
3492 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01003493 if (!sw)
3494 sw = path->ctls[NID_PATH_MUTE_CTL];
David Henningsson99a55922013-01-16 15:58:44 +01003495 else if (sw != path->ctls[NID_PATH_MUTE_CTL]) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01003496 multi = true;
David Henningsson99a55922013-01-16 15:58:44 +01003497 if (!same_amp_caps(codec, sw,
3498 path->ctls[NID_PATH_MUTE_CTL], HDA_INPUT))
3499 multi_cap_vol = true;
3500 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01003501 if (is_inv_dmic_pin(codec, spec->imux_pins[i]))
3502 inv_dmic = true;
3503 }
3504
3505 if (!multi)
3506 err = create_single_cap_vol_ctl(codec, n, vol, sw,
3507 inv_dmic);
David Henningsson99a55922013-01-16 15:58:44 +01003508 else if (!multi_cap_vol)
Takashi Iwai352f7f92012-12-19 12:52:06 +01003509 err = create_bind_cap_vol_ctl(codec, n, vol, sw);
3510 else
3511 err = create_multi_cap_vol_ctl(codec);
3512 if (err < 0)
3513 return err;
3514 }
3515
3516 return 0;
3517}
3518
3519/*
3520 * add mic boosts if needed
3521 */
Takashi Iwai6f7c83a2013-01-18 11:07:15 +01003522
3523/* check whether the given amp is feasible as a boost volume */
3524static bool check_boost_vol(struct hda_codec *codec, hda_nid_t nid,
3525 int dir, int idx)
3526{
3527 unsigned int step;
3528
3529 if (!nid_has_volume(codec, nid, dir) ||
3530 is_ctl_associated(codec, nid, dir, idx, NID_PATH_VOL_CTL) ||
3531 is_ctl_associated(codec, nid, dir, idx, NID_PATH_BOOST_CTL))
3532 return false;
3533
3534 step = (query_amp_caps(codec, nid, dir) & AC_AMPCAP_STEP_SIZE)
3535 >> AC_AMPCAP_STEP_SIZE_SHIFT;
3536 if (step < 0x20)
3537 return false;
3538 return true;
3539}
3540
3541/* look for a boost amp in a widget close to the pin */
3542static unsigned int look_for_boost_amp(struct hda_codec *codec,
3543 struct nid_path *path)
3544{
3545 unsigned int val = 0;
3546 hda_nid_t nid;
3547 int depth;
3548
3549 for (depth = 0; depth < 3; depth++) {
3550 if (depth >= path->depth - 1)
3551 break;
3552 nid = path->path[depth];
3553 if (depth && check_boost_vol(codec, nid, HDA_OUTPUT, 0)) {
3554 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
3555 break;
3556 } else if (check_boost_vol(codec, nid, HDA_INPUT,
3557 path->idx[depth])) {
3558 val = HDA_COMPOSE_AMP_VAL(nid, 3, path->idx[depth],
3559 HDA_INPUT);
3560 break;
3561 }
3562 }
3563
3564 return val;
3565}
3566
Takashi Iwai352f7f92012-12-19 12:52:06 +01003567static int parse_mic_boost(struct hda_codec *codec)
3568{
3569 struct hda_gen_spec *spec = codec->spec;
3570 struct auto_pin_cfg *cfg = &spec->autocfg;
Takashi Iwai6f7c83a2013-01-18 11:07:15 +01003571 struct hda_input_mux *imux = &spec->input_mux;
Takashi Iwaia35bd1e2013-01-18 14:01:14 +01003572 int i;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003573
Takashi Iwai6f7c83a2013-01-18 11:07:15 +01003574 if (!spec->num_adc_nids)
3575 return 0;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003576
Takashi Iwai6f7c83a2013-01-18 11:07:15 +01003577 for (i = 0; i < imux->num_items; i++) {
3578 struct nid_path *path;
3579 unsigned int val;
3580 int idx;
Takashi Iwai975cc022013-06-28 11:56:49 +02003581 char boost_label[SNDRV_CTL_ELEM_ID_NAME_MAXLEN];
David Henningsson02aba552013-01-16 15:58:43 +01003582
Takashi Iwai6f7c83a2013-01-18 11:07:15 +01003583 idx = imux->items[i].index;
3584 if (idx >= imux->num_items)
3585 continue;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003586
Takashi Iwai6f7c83a2013-01-18 11:07:15 +01003587 /* check only line-in and mic pins */
Takashi Iwai1799cdd52013-01-18 14:37:16 +01003588 if (cfg->inputs[idx].type > AUTO_PIN_LINE_IN)
Takashi Iwai6f7c83a2013-01-18 11:07:15 +01003589 continue;
3590
3591 path = get_input_path(codec, 0, i);
3592 if (!path)
3593 continue;
3594
3595 val = look_for_boost_amp(codec, path);
3596 if (!val)
3597 continue;
3598
3599 /* create a boost control */
3600 snprintf(boost_label, sizeof(boost_label),
3601 "%s Boost Volume", spec->input_labels[idx]);
Takashi Iwaia35bd1e2013-01-18 14:01:14 +01003602 if (!add_control(spec, HDA_CTL_WIDGET_VOL, boost_label,
3603 spec->input_label_idxs[idx], val))
3604 return -ENOMEM;
Takashi Iwai6f7c83a2013-01-18 11:07:15 +01003605
3606 path->ctls[NID_PATH_BOOST_CTL] = val;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003607 }
3608 return 0;
3609}
3610
3611/*
3612 * parse digital I/Os and set up NIDs in BIOS auto-parse mode
3613 */
3614static void parse_digital(struct hda_codec *codec)
3615{
3616 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai0c8c0f52012-12-20 17:54:22 +01003617 struct nid_path *path;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003618 int i, nums;
Takashi Iwai2c12c302013-01-10 09:33:29 +01003619 hda_nid_t dig_nid, pin;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003620
3621 /* support multiple SPDIFs; the secondary is set up as a slave */
3622 nums = 0;
3623 for (i = 0; i < spec->autocfg.dig_outs; i++) {
Takashi Iwai2c12c302013-01-10 09:33:29 +01003624 pin = spec->autocfg.dig_out_pins[i];
Takashi Iwai352f7f92012-12-19 12:52:06 +01003625 dig_nid = look_for_dac(codec, pin, true);
3626 if (!dig_nid)
3627 continue;
Takashi Iwai3ca529d2013-01-07 17:25:08 +01003628 path = snd_hda_add_new_path(codec, dig_nid, pin, 0);
Takashi Iwai0c8c0f52012-12-20 17:54:22 +01003629 if (!path)
Takashi Iwai352f7f92012-12-19 12:52:06 +01003630 continue;
Takashi Iwai0c8c0f52012-12-20 17:54:22 +01003631 print_nid_path("digout", path);
Takashi Iwaie1284af2013-01-03 16:33:02 +01003632 path->active = true;
Takashi Iwai196c17662013-01-04 15:01:40 +01003633 spec->digout_paths[i] = snd_hda_get_path_idx(codec, path);
Takashi Iwai2c12c302013-01-10 09:33:29 +01003634 set_pin_target(codec, pin, PIN_OUT, false);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003635 if (!nums) {
3636 spec->multiout.dig_out_nid = dig_nid;
3637 spec->dig_out_type = spec->autocfg.dig_out_type[0];
3638 } else {
3639 spec->multiout.slave_dig_outs = spec->slave_dig_outs;
3640 if (nums >= ARRAY_SIZE(spec->slave_dig_outs) - 1)
3641 break;
3642 spec->slave_dig_outs[nums - 1] = dig_nid;
3643 }
3644 nums++;
3645 }
3646
3647 if (spec->autocfg.dig_in_pin) {
Takashi Iwai2c12c302013-01-10 09:33:29 +01003648 pin = spec->autocfg.dig_in_pin;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003649 dig_nid = codec->start_nid;
3650 for (i = 0; i < codec->num_nodes; i++, dig_nid++) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01003651 unsigned int wcaps = get_wcaps(codec, dig_nid);
3652 if (get_wcaps_type(wcaps) != AC_WID_AUD_IN)
3653 continue;
3654 if (!(wcaps & AC_WCAP_DIGITAL))
3655 continue;
Takashi Iwai2c12c302013-01-10 09:33:29 +01003656 path = snd_hda_add_new_path(codec, pin, dig_nid, 0);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003657 if (path) {
Takashi Iwai0c8c0f52012-12-20 17:54:22 +01003658 print_nid_path("digin", path);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003659 path->active = true;
3660 spec->dig_in_nid = dig_nid;
Takashi Iwai2430d7b2013-01-04 15:09:42 +01003661 spec->digin_path = snd_hda_get_path_idx(codec, path);
Takashi Iwai2c12c302013-01-10 09:33:29 +01003662 set_pin_target(codec, pin, PIN_IN, false);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003663 break;
3664 }
3665 }
3666 }
3667}
3668
3669
3670/*
3671 * input MUX handling
3672 */
3673
3674static bool dyn_adc_pcm_resetup(struct hda_codec *codec, int cur);
3675
3676/* select the given imux item; either unmute exclusively or select the route */
3677static int mux_select(struct hda_codec *codec, unsigned int adc_idx,
3678 unsigned int idx)
3679{
3680 struct hda_gen_spec *spec = codec->spec;
3681 const struct hda_input_mux *imux;
Takashi Iwai55196ff2013-01-24 17:32:56 +01003682 struct nid_path *old_path, *path;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003683
3684 imux = &spec->input_mux;
3685 if (!imux->num_items)
3686 return 0;
3687
3688 if (idx >= imux->num_items)
3689 idx = imux->num_items - 1;
3690 if (spec->cur_mux[adc_idx] == idx)
3691 return 0;
3692
Takashi Iwai55196ff2013-01-24 17:32:56 +01003693 old_path = get_input_path(codec, adc_idx, spec->cur_mux[adc_idx]);
3694 if (!old_path)
Takashi Iwai352f7f92012-12-19 12:52:06 +01003695 return 0;
Takashi Iwai55196ff2013-01-24 17:32:56 +01003696 if (old_path->active)
3697 snd_hda_activate_path(codec, old_path, false, false);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003698
3699 spec->cur_mux[adc_idx] = idx;
3700
Takashi Iwai967303d2013-02-19 17:12:42 +01003701 if (spec->hp_mic)
3702 update_hp_mic(codec, adc_idx, false);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003703
3704 if (spec->dyn_adc_switch)
3705 dyn_adc_pcm_resetup(codec, idx);
3706
Takashi Iwaic697b712013-01-07 17:09:26 +01003707 path = get_input_path(codec, adc_idx, idx);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003708 if (!path)
3709 return 0;
3710 if (path->active)
3711 return 0;
3712 snd_hda_activate_path(codec, path, true, false);
3713 if (spec->cap_sync_hook)
Takashi Iwaia90229e2013-01-18 14:10:00 +01003714 spec->cap_sync_hook(codec, NULL);
Takashi Iwai55196ff2013-01-24 17:32:56 +01003715 path_power_down_sync(codec, old_path);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003716 return 1;
3717}
3718
3719
3720/*
3721 * Jack detections for HP auto-mute and mic-switch
3722 */
3723
3724/* check each pin in the given array; returns true if any of them is plugged */
3725static bool detect_jacks(struct hda_codec *codec, int num_pins, hda_nid_t *pins)
3726{
Takashi Iwai60ea8ca2013-07-19 16:59:46 +02003727 int i;
3728 bool present = false;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003729
3730 for (i = 0; i < num_pins; i++) {
3731 hda_nid_t nid = pins[i];
3732 if (!nid)
3733 break;
Takashi Iwai0b4df932013-01-10 09:45:13 +01003734 /* don't detect pins retasked as inputs */
3735 if (snd_hda_codec_get_pin_target(codec, nid) & AC_PINCTL_IN_EN)
3736 continue;
Takashi Iwai60ea8ca2013-07-19 16:59:46 +02003737 if (snd_hda_jack_detect_state(codec, nid) == HDA_JACK_PRESENT)
3738 present = true;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003739 }
3740 return present;
3741}
3742
3743/* standard HP/line-out auto-mute helper */
3744static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
Takashi Iwai2c12c302013-01-10 09:33:29 +01003745 bool mute)
Takashi Iwai352f7f92012-12-19 12:52:06 +01003746{
3747 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003748 int i;
3749
3750 for (i = 0; i < num_pins; i++) {
3751 hda_nid_t nid = pins[i];
Takashi Iwai967303d2013-02-19 17:12:42 +01003752 unsigned int val, oldval;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003753 if (!nid)
3754 break;
Takashi Iwai7eebffd2013-06-24 16:00:21 +02003755
3756 if (spec->auto_mute_via_amp) {
3757 if (mute)
3758 spec->mute_bits |= (1ULL << nid);
3759 else
3760 spec->mute_bits &= ~(1ULL << nid);
3761 set_pin_eapd(codec, nid, !mute);
3762 continue;
3763 }
3764
Takashi Iwai967303d2013-02-19 17:12:42 +01003765 oldval = snd_hda_codec_get_pin_target(codec, nid);
3766 if (oldval & PIN_IN)
3767 continue; /* no mute for inputs */
Takashi Iwai352f7f92012-12-19 12:52:06 +01003768 /* don't reset VREF value in case it's controlling
3769 * the amp (see alc861_fixup_asus_amp_vref_0f())
3770 */
Takashi Iwai2c12c302013-01-10 09:33:29 +01003771 if (spec->keep_vref_in_automute)
Takashi Iwai967303d2013-02-19 17:12:42 +01003772 val = oldval & ~PIN_HP;
Takashi Iwai2c12c302013-01-10 09:33:29 +01003773 else
Takashi Iwai352f7f92012-12-19 12:52:06 +01003774 val = 0;
Takashi Iwai2c12c302013-01-10 09:33:29 +01003775 if (!mute)
Takashi Iwai967303d2013-02-19 17:12:42 +01003776 val |= oldval;
Takashi Iwai2c12c302013-01-10 09:33:29 +01003777 /* here we call update_pin_ctl() so that the pinctl is changed
3778 * without changing the pinctl target value;
3779 * the original target value will be still referred at the
3780 * init / resume again
3781 */
3782 update_pin_ctl(codec, nid, val);
Takashi Iwaid5a9f1b2012-12-20 15:36:30 +01003783 set_pin_eapd(codec, nid, !mute);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003784 }
3785}
3786
3787/* Toggle outputs muting */
Takashi Iwai5d550e12012-12-19 15:16:44 +01003788void snd_hda_gen_update_outputs(struct hda_codec *codec)
Takashi Iwai352f7f92012-12-19 12:52:06 +01003789{
3790 struct hda_gen_spec *spec = codec->spec;
3791 int on;
3792
3793 /* Control HP pins/amps depending on master_mute state;
3794 * in general, HP pins/amps control should be enabled in all cases,
3795 * but currently set only for master_mute, just to be safe
3796 */
Takashi Iwai967303d2013-02-19 17:12:42 +01003797 do_automute(codec, ARRAY_SIZE(spec->autocfg.hp_pins),
Takashi Iwai2c12c302013-01-10 09:33:29 +01003798 spec->autocfg.hp_pins, spec->master_mute);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003799
3800 if (!spec->automute_speaker)
3801 on = 0;
3802 else
3803 on = spec->hp_jack_present | spec->line_jack_present;
3804 on |= spec->master_mute;
Takashi Iwai47b9ddb2013-01-16 18:18:00 +01003805 spec->speaker_muted = on;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003806 do_automute(codec, ARRAY_SIZE(spec->autocfg.speaker_pins),
Takashi Iwai2c12c302013-01-10 09:33:29 +01003807 spec->autocfg.speaker_pins, on);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003808
3809 /* toggle line-out mutes if needed, too */
3810 /* if LO is a copy of either HP or Speaker, don't need to handle it */
3811 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0] ||
3812 spec->autocfg.line_out_pins[0] == spec->autocfg.speaker_pins[0])
3813 return;
3814 if (!spec->automute_lo)
3815 on = 0;
3816 else
3817 on = spec->hp_jack_present;
3818 on |= spec->master_mute;
Takashi Iwai47b9ddb2013-01-16 18:18:00 +01003819 spec->line_out_muted = on;
Takashi Iwai352f7f92012-12-19 12:52:06 +01003820 do_automute(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
Takashi Iwai2c12c302013-01-10 09:33:29 +01003821 spec->autocfg.line_out_pins, on);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003822}
Takashi Iwai5d550e12012-12-19 15:16:44 +01003823EXPORT_SYMBOL_HDA(snd_hda_gen_update_outputs);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003824
3825static void call_update_outputs(struct hda_codec *codec)
3826{
3827 struct hda_gen_spec *spec = codec->spec;
3828 if (spec->automute_hook)
3829 spec->automute_hook(codec);
3830 else
Takashi Iwai5d550e12012-12-19 15:16:44 +01003831 snd_hda_gen_update_outputs(codec);
Takashi Iwai7eebffd2013-06-24 16:00:21 +02003832
3833 /* sync the whole vmaster slaves to reflect the new auto-mute status */
3834 if (spec->auto_mute_via_amp && !codec->bus->shutdown)
3835 snd_ctl_sync_vmaster(spec->vmaster_mute.sw_kctl, false);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003836}
3837
3838/* standard HP-automute helper */
Takashi Iwai5d550e12012-12-19 15:16:44 +01003839void snd_hda_gen_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
Takashi Iwai352f7f92012-12-19 12:52:06 +01003840{
3841 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai92603c52013-01-22 07:46:31 +01003842 hda_nid_t *pins = spec->autocfg.hp_pins;
3843 int num_pins = ARRAY_SIZE(spec->autocfg.hp_pins);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003844
Takashi Iwai92603c52013-01-22 07:46:31 +01003845 /* No detection for the first HP jack during indep-HP mode */
3846 if (spec->indep_hp_enabled) {
3847 pins++;
3848 num_pins--;
3849 }
3850
3851 spec->hp_jack_present = detect_jacks(codec, num_pins, pins);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003852 if (!spec->detect_hp || (!spec->automute_speaker && !spec->automute_lo))
3853 return;
3854 call_update_outputs(codec);
3855}
Takashi Iwai5d550e12012-12-19 15:16:44 +01003856EXPORT_SYMBOL_HDA(snd_hda_gen_hp_automute);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003857
3858/* standard line-out-automute helper */
Takashi Iwai5d550e12012-12-19 15:16:44 +01003859void snd_hda_gen_line_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
Takashi Iwai352f7f92012-12-19 12:52:06 +01003860{
3861 struct hda_gen_spec *spec = codec->spec;
3862
3863 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT)
3864 return;
3865 /* check LO jack only when it's different from HP */
3866 if (spec->autocfg.line_out_pins[0] == spec->autocfg.hp_pins[0])
3867 return;
3868
3869 spec->line_jack_present =
3870 detect_jacks(codec, ARRAY_SIZE(spec->autocfg.line_out_pins),
3871 spec->autocfg.line_out_pins);
3872 if (!spec->automute_speaker || !spec->detect_lo)
3873 return;
3874 call_update_outputs(codec);
3875}
Takashi Iwai5d550e12012-12-19 15:16:44 +01003876EXPORT_SYMBOL_HDA(snd_hda_gen_line_automute);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003877
3878/* standard mic auto-switch helper */
Takashi Iwai5d550e12012-12-19 15:16:44 +01003879void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, struct hda_jack_tbl *jack)
Takashi Iwai352f7f92012-12-19 12:52:06 +01003880{
3881 struct hda_gen_spec *spec = codec->spec;
3882 int i;
3883
3884 if (!spec->auto_mic)
3885 return;
3886
3887 for (i = spec->am_num_entries - 1; i > 0; i--) {
Takashi Iwai0b4df932013-01-10 09:45:13 +01003888 hda_nid_t pin = spec->am_entry[i].pin;
3889 /* don't detect pins retasked as outputs */
3890 if (snd_hda_codec_get_pin_target(codec, pin) & AC_PINCTL_OUT_EN)
3891 continue;
Takashi Iwai60ea8ca2013-07-19 16:59:46 +02003892 if (snd_hda_jack_detect_state(codec, pin) == HDA_JACK_PRESENT) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01003893 mux_select(codec, 0, spec->am_entry[i].idx);
3894 return;
3895 }
3896 }
3897 mux_select(codec, 0, spec->am_entry[0].idx);
3898}
Takashi Iwai5d550e12012-12-19 15:16:44 +01003899EXPORT_SYMBOL_HDA(snd_hda_gen_mic_autoswitch);
Takashi Iwai352f7f92012-12-19 12:52:06 +01003900
Takashi Iwai77afe0e2013-05-31 14:10:03 +02003901/* call appropriate hooks */
3902static void call_hp_automute(struct hda_codec *codec, struct hda_jack_tbl *jack)
3903{
3904 struct hda_gen_spec *spec = codec->spec;
3905 if (spec->hp_automute_hook)
3906 spec->hp_automute_hook(codec, jack);
3907 else
3908 snd_hda_gen_hp_automute(codec, jack);
3909}
3910
3911static void call_line_automute(struct hda_codec *codec,
3912 struct hda_jack_tbl *jack)
3913{
3914 struct hda_gen_spec *spec = codec->spec;
3915 if (spec->line_automute_hook)
3916 spec->line_automute_hook(codec, jack);
3917 else
3918 snd_hda_gen_line_automute(codec, jack);
3919}
3920
3921static void call_mic_autoswitch(struct hda_codec *codec,
3922 struct hda_jack_tbl *jack)
3923{
3924 struct hda_gen_spec *spec = codec->spec;
3925 if (spec->mic_autoswitch_hook)
3926 spec->mic_autoswitch_hook(codec, jack);
3927 else
3928 snd_hda_gen_mic_autoswitch(codec, jack);
3929}
3930
Takashi Iwai963afde2013-05-31 15:20:31 +02003931/* update jack retasking */
3932static void update_automute_all(struct hda_codec *codec)
3933{
3934 call_hp_automute(codec, NULL);
3935 call_line_automute(codec, NULL);
3936 call_mic_autoswitch(codec, NULL);
3937}
3938
Takashi Iwai352f7f92012-12-19 12:52:06 +01003939/*
3940 * Auto-Mute mode mixer enum support
3941 */
3942static int automute_mode_info(struct snd_kcontrol *kcontrol,
3943 struct snd_ctl_elem_info *uinfo)
3944{
3945 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3946 struct hda_gen_spec *spec = codec->spec;
3947 static const char * const texts3[] = {
3948 "Disabled", "Speaker Only", "Line Out+Speaker"
Takashi Iwai071c73a2006-08-23 18:34:06 +02003949 };
Linus Torvalds1da177e2005-04-16 15:20:36 -07003950
Takashi Iwai352f7f92012-12-19 12:52:06 +01003951 if (spec->automute_speaker_possible && spec->automute_lo_possible)
3952 return snd_hda_enum_helper_info(kcontrol, uinfo, 3, texts3);
3953 return snd_hda_enum_bool_helper_info(kcontrol, uinfo);
3954}
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955
Takashi Iwai352f7f92012-12-19 12:52:06 +01003956static int automute_mode_get(struct snd_kcontrol *kcontrol,
3957 struct snd_ctl_elem_value *ucontrol)
3958{
3959 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3960 struct hda_gen_spec *spec = codec->spec;
3961 unsigned int val = 0;
3962 if (spec->automute_speaker)
3963 val++;
3964 if (spec->automute_lo)
3965 val++;
Takashi Iwai071c73a2006-08-23 18:34:06 +02003966
Takashi Iwai352f7f92012-12-19 12:52:06 +01003967 ucontrol->value.enumerated.item[0] = val;
3968 return 0;
3969}
3970
3971static int automute_mode_put(struct snd_kcontrol *kcontrol,
3972 struct snd_ctl_elem_value *ucontrol)
3973{
3974 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
3975 struct hda_gen_spec *spec = codec->spec;
3976
3977 switch (ucontrol->value.enumerated.item[0]) {
3978 case 0:
3979 if (!spec->automute_speaker && !spec->automute_lo)
3980 return 0;
3981 spec->automute_speaker = 0;
3982 spec->automute_lo = 0;
3983 break;
3984 case 1:
3985 if (spec->automute_speaker_possible) {
3986 if (!spec->automute_lo && spec->automute_speaker)
3987 return 0;
3988 spec->automute_speaker = 1;
3989 spec->automute_lo = 0;
3990 } else if (spec->automute_lo_possible) {
3991 if (spec->automute_lo)
3992 return 0;
3993 spec->automute_lo = 1;
3994 } else
3995 return -EINVAL;
3996 break;
3997 case 2:
3998 if (!spec->automute_lo_possible || !spec->automute_speaker_possible)
3999 return -EINVAL;
4000 if (spec->automute_speaker && spec->automute_lo)
4001 return 0;
4002 spec->automute_speaker = 1;
4003 spec->automute_lo = 1;
4004 break;
4005 default:
4006 return -EINVAL;
4007 }
4008 call_update_outputs(codec);
4009 return 1;
4010}
4011
4012static const struct snd_kcontrol_new automute_mode_enum = {
4013 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
4014 .name = "Auto-Mute Mode",
4015 .info = automute_mode_info,
4016 .get = automute_mode_get,
4017 .put = automute_mode_put,
4018};
4019
4020static int add_automute_mode_enum(struct hda_codec *codec)
4021{
4022 struct hda_gen_spec *spec = codec->spec;
4023
Takashi Iwai12c93df2012-12-19 14:38:33 +01004024 if (!snd_hda_gen_add_kctl(spec, NULL, &automute_mode_enum))
Takashi Iwai352f7f92012-12-19 12:52:06 +01004025 return -ENOMEM;
4026 return 0;
4027}
4028
4029/*
4030 * Check the availability of HP/line-out auto-mute;
4031 * Set up appropriately if really supported
4032 */
4033static int check_auto_mute_availability(struct hda_codec *codec)
4034{
4035 struct hda_gen_spec *spec = codec->spec;
4036 struct auto_pin_cfg *cfg = &spec->autocfg;
4037 int present = 0;
4038 int i, err;
4039
Takashi Iwaif72706b2013-01-16 18:20:07 +01004040 if (spec->suppress_auto_mute)
4041 return 0;
4042
Takashi Iwai352f7f92012-12-19 12:52:06 +01004043 if (cfg->hp_pins[0])
4044 present++;
4045 if (cfg->line_out_pins[0])
4046 present++;
4047 if (cfg->speaker_pins[0])
4048 present++;
4049 if (present < 2) /* need two different output types */
Takashi Iwai071c73a2006-08-23 18:34:06 +02004050 return 0;
Takashi Iwai352f7f92012-12-19 12:52:06 +01004051
4052 if (!cfg->speaker_pins[0] &&
4053 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) {
4054 memcpy(cfg->speaker_pins, cfg->line_out_pins,
4055 sizeof(cfg->speaker_pins));
4056 cfg->speaker_outs = cfg->line_outs;
Takashi Iwai071c73a2006-08-23 18:34:06 +02004057 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004058
Takashi Iwai352f7f92012-12-19 12:52:06 +01004059 if (!cfg->hp_pins[0] &&
4060 cfg->line_out_type == AUTO_PIN_HP_OUT) {
4061 memcpy(cfg->hp_pins, cfg->line_out_pins,
4062 sizeof(cfg->hp_pins));
4063 cfg->hp_outs = cfg->line_outs;
4064 }
4065
4066 for (i = 0; i < cfg->hp_outs; i++) {
4067 hda_nid_t nid = cfg->hp_pins[i];
4068 if (!is_jack_detectable(codec, nid))
4069 continue;
4070 snd_printdd("hda-codec: Enable HP auto-muting on NID 0x%x\n",
4071 nid);
4072 snd_hda_jack_detect_enable_callback(codec, nid, HDA_GEN_HP_EVENT,
Takashi Iwai77afe0e2013-05-31 14:10:03 +02004073 call_hp_automute);
Takashi Iwai352f7f92012-12-19 12:52:06 +01004074 spec->detect_hp = 1;
4075 }
4076
4077 if (cfg->line_out_type == AUTO_PIN_LINE_OUT && cfg->line_outs) {
4078 if (cfg->speaker_outs)
4079 for (i = 0; i < cfg->line_outs; i++) {
4080 hda_nid_t nid = cfg->line_out_pins[i];
4081 if (!is_jack_detectable(codec, nid))
4082 continue;
4083 snd_printdd("hda-codec: Enable Line-Out auto-muting on NID 0x%x\n", nid);
4084 snd_hda_jack_detect_enable_callback(codec, nid,
4085 HDA_GEN_FRONT_EVENT,
Takashi Iwai77afe0e2013-05-31 14:10:03 +02004086 call_line_automute);
Takashi Iwai352f7f92012-12-19 12:52:06 +01004087 spec->detect_lo = 1;
4088 }
4089 spec->automute_lo_possible = spec->detect_hp;
4090 }
4091
4092 spec->automute_speaker_possible = cfg->speaker_outs &&
4093 (spec->detect_hp || spec->detect_lo);
4094
4095 spec->automute_lo = spec->automute_lo_possible;
4096 spec->automute_speaker = spec->automute_speaker_possible;
4097
4098 if (spec->automute_speaker_possible || spec->automute_lo_possible) {
4099 /* create a control for automute mode */
4100 err = add_automute_mode_enum(codec);
4101 if (err < 0)
4102 return err;
4103 }
4104 return 0;
4105}
4106
Takashi Iwai352f7f92012-12-19 12:52:06 +01004107/* check whether all auto-mic pins are valid; setup indices if OK */
4108static bool auto_mic_check_imux(struct hda_codec *codec)
4109{
4110 struct hda_gen_spec *spec = codec->spec;
4111 const struct hda_input_mux *imux;
4112 int i;
4113
4114 imux = &spec->input_mux;
4115 for (i = 0; i < spec->am_num_entries; i++) {
4116 spec->am_entry[i].idx =
4117 find_idx_in_nid_list(spec->am_entry[i].pin,
4118 spec->imux_pins, imux->num_items);
4119 if (spec->am_entry[i].idx < 0)
4120 return false; /* no corresponding imux */
4121 }
4122
4123 /* we don't need the jack detection for the first pin */
4124 for (i = 1; i < spec->am_num_entries; i++)
4125 snd_hda_jack_detect_enable_callback(codec,
4126 spec->am_entry[i].pin,
4127 HDA_GEN_MIC_EVENT,
Takashi Iwai77afe0e2013-05-31 14:10:03 +02004128 call_mic_autoswitch);
Takashi Iwai352f7f92012-12-19 12:52:06 +01004129 return true;
4130}
4131
4132static int compare_attr(const void *ap, const void *bp)
4133{
4134 const struct automic_entry *a = ap;
4135 const struct automic_entry *b = bp;
4136 return (int)(a->attr - b->attr);
4137}
4138
4139/*
4140 * Check the availability of auto-mic switch;
4141 * Set up if really supported
4142 */
4143static int check_auto_mic_availability(struct hda_codec *codec)
4144{
4145 struct hda_gen_spec *spec = codec->spec;
4146 struct auto_pin_cfg *cfg = &spec->autocfg;
4147 unsigned int types;
4148 int i, num_pins;
4149
Takashi Iwaid12daf62013-01-07 16:32:11 +01004150 if (spec->suppress_auto_mic)
4151 return 0;
4152
Takashi Iwai352f7f92012-12-19 12:52:06 +01004153 types = 0;
4154 num_pins = 0;
4155 for (i = 0; i < cfg->num_inputs; i++) {
4156 hda_nid_t nid = cfg->inputs[i].pin;
4157 unsigned int attr;
4158 attr = snd_hda_codec_get_pincfg(codec, nid);
4159 attr = snd_hda_get_input_pin_attr(attr);
4160 if (types & (1 << attr))
4161 return 0; /* already occupied */
4162 switch (attr) {
4163 case INPUT_PIN_ATTR_INT:
4164 if (cfg->inputs[i].type != AUTO_PIN_MIC)
4165 return 0; /* invalid type */
4166 break;
4167 case INPUT_PIN_ATTR_UNUSED:
4168 return 0; /* invalid entry */
4169 default:
4170 if (cfg->inputs[i].type > AUTO_PIN_LINE_IN)
4171 return 0; /* invalid type */
4172 if (!spec->line_in_auto_switch &&
4173 cfg->inputs[i].type != AUTO_PIN_MIC)
4174 return 0; /* only mic is allowed */
4175 if (!is_jack_detectable(codec, nid))
4176 return 0; /* no unsol support */
4177 break;
4178 }
4179 if (num_pins >= MAX_AUTO_MIC_PINS)
4180 return 0;
4181 types |= (1 << attr);
4182 spec->am_entry[num_pins].pin = nid;
4183 spec->am_entry[num_pins].attr = attr;
4184 num_pins++;
4185 }
4186
4187 if (num_pins < 2)
4188 return 0;
4189
4190 spec->am_num_entries = num_pins;
4191 /* sort the am_entry in the order of attr so that the pin with a
4192 * higher attr will be selected when the jack is plugged.
4193 */
4194 sort(spec->am_entry, num_pins, sizeof(spec->am_entry[0]),
4195 compare_attr, NULL);
4196
4197 if (!auto_mic_check_imux(codec))
4198 return 0;
4199
4200 spec->auto_mic = 1;
4201 spec->num_adc_nids = 1;
4202 spec->cur_mux[0] = spec->am_entry[0].idx;
4203 snd_printdd("hda-codec: Enable auto-mic switch on NID 0x%x/0x%x/0x%x\n",
4204 spec->am_entry[0].pin,
4205 spec->am_entry[1].pin,
4206 spec->am_entry[2].pin);
4207
4208 return 0;
4209}
4210
Takashi Iwai55196ff2013-01-24 17:32:56 +01004211/* power_filter hook; make inactive widgets into power down */
4212static unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
4213 hda_nid_t nid,
4214 unsigned int power_state)
4215{
4216 if (power_state != AC_PWRST_D0)
4217 return power_state;
4218 if (get_wcaps_type(get_wcaps(codec, nid)) >= AC_WID_POWER)
4219 return power_state;
Takashi Iwaib1b9fbd2013-05-14 12:58:47 +02004220 if (is_active_nid_for_any(codec, nid))
Takashi Iwai55196ff2013-01-24 17:32:56 +01004221 return power_state;
4222 return AC_PWRST_D3;
4223}
4224
Takashi Iwai352f7f92012-12-19 12:52:06 +01004225
Takashi Iwai9eb413e2012-12-19 14:41:21 +01004226/*
4227 * Parse the given BIOS configuration and set up the hda_gen_spec
4228 *
4229 * return 1 if successful, 0 if the proper config is not found,
Takashi Iwai352f7f92012-12-19 12:52:06 +01004230 * or a negative error code
4231 */
4232int snd_hda_gen_parse_auto_config(struct hda_codec *codec,
Takashi Iwai9eb413e2012-12-19 14:41:21 +01004233 struct auto_pin_cfg *cfg)
Takashi Iwai352f7f92012-12-19 12:52:06 +01004234{
4235 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai352f7f92012-12-19 12:52:06 +01004236 int err;
4237
Takashi Iwai1c70a582013-01-11 17:48:22 +01004238 parse_user_hints(codec);
4239
Takashi Iwaie4a395e2013-01-23 17:00:31 +01004240 if (spec->mixer_nid && !spec->mixer_merge_nid)
4241 spec->mixer_merge_nid = spec->mixer_nid;
4242
Takashi Iwai9eb413e2012-12-19 14:41:21 +01004243 if (cfg != &spec->autocfg) {
4244 spec->autocfg = *cfg;
4245 cfg = &spec->autocfg;
4246 }
4247
Takashi Iwai98bd1112013-03-22 14:53:50 +01004248 if (!spec->main_out_badness)
4249 spec->main_out_badness = &hda_main_out_badness;
4250 if (!spec->extra_out_badness)
4251 spec->extra_out_badness = &hda_extra_out_badness;
4252
David Henningsson6fc4cb92013-01-16 15:58:45 +01004253 fill_all_dac_nids(codec);
4254
Takashi Iwai352f7f92012-12-19 12:52:06 +01004255 if (!cfg->line_outs) {
4256 if (cfg->dig_outs || cfg->dig_in_pin) {
4257 spec->multiout.max_channels = 2;
4258 spec->no_analog = 1;
4259 goto dig_only;
4260 }
4261 return 0; /* can't find valid BIOS pin config */
4262 }
4263
4264 if (!spec->no_primary_hp &&
4265 cfg->line_out_type == AUTO_PIN_SPEAKER_OUT &&
4266 cfg->line_outs <= cfg->hp_outs) {
4267 /* use HP as primary out */
4268 cfg->speaker_outs = cfg->line_outs;
4269 memcpy(cfg->speaker_pins, cfg->line_out_pins,
4270 sizeof(cfg->speaker_pins));
4271 cfg->line_outs = cfg->hp_outs;
4272 memcpy(cfg->line_out_pins, cfg->hp_pins, sizeof(cfg->hp_pins));
4273 cfg->hp_outs = 0;
4274 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
4275 cfg->line_out_type = AUTO_PIN_HP_OUT;
4276 }
4277
4278 err = parse_output_paths(codec);
4279 if (err < 0)
4280 return err;
4281 err = create_multi_channel_mode(codec);
4282 if (err < 0)
4283 return err;
4284 err = create_multi_out_ctls(codec, cfg);
4285 if (err < 0)
4286 return err;
4287 err = create_hp_out_ctls(codec);
4288 if (err < 0)
4289 return err;
4290 err = create_speaker_out_ctls(codec);
4291 if (err < 0)
4292 return err;
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004293 err = create_indep_hp_ctls(codec);
4294 if (err < 0)
4295 return err;
Takashi Iwaic30aa7b2013-01-04 16:42:48 +01004296 err = create_loopback_mixing_ctl(codec);
4297 if (err < 0)
4298 return err;
Takashi Iwai967303d2013-02-19 17:12:42 +01004299 err = create_hp_mic(codec);
Takashi Iwai352f7f92012-12-19 12:52:06 +01004300 if (err < 0)
4301 return err;
4302 err = create_input_ctls(codec);
Takashi Iwaid13bd412008-07-30 15:01:45 +02004303 if (err < 0)
Takashi Iwai071c73a2006-08-23 18:34:06 +02004304 return err;
4305
Takashi Iwaia07a9492013-01-07 16:44:06 +01004306 spec->const_channel_count = spec->ext_channel_count;
4307 /* check the multiple speaker and headphone pins */
4308 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT)
4309 spec->const_channel_count = max(spec->const_channel_count,
4310 cfg->speaker_outs * 2);
4311 if (cfg->line_out_type != AUTO_PIN_HP_OUT)
4312 spec->const_channel_count = max(spec->const_channel_count,
4313 cfg->hp_outs * 2);
4314 spec->multiout.max_channels = max(spec->ext_channel_count,
4315 spec->const_channel_count);
Takashi Iwai352f7f92012-12-19 12:52:06 +01004316
4317 err = check_auto_mute_availability(codec);
4318 if (err < 0)
4319 return err;
4320
4321 err = check_dyn_adc_switch(codec);
4322 if (err < 0)
4323 return err;
4324
Takashi Iwai967303d2013-02-19 17:12:42 +01004325 err = check_auto_mic_availability(codec);
4326 if (err < 0)
4327 return err;
Takashi Iwai071c73a2006-08-23 18:34:06 +02004328
Takashi Iwai352f7f92012-12-19 12:52:06 +01004329 err = create_capture_mixers(codec);
4330 if (err < 0)
4331 return err;
4332
4333 err = parse_mic_boost(codec);
4334 if (err < 0)
4335 return err;
4336
Takashi Iwaif811c3c2013-03-07 18:32:59 +01004337 if (spec->add_jack_modes) {
Takashi Iwai978e77e2013-01-10 16:57:58 +01004338 if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
4339 err = create_out_jack_modes(codec, cfg->line_outs,
4340 cfg->line_out_pins);
4341 if (err < 0)
4342 return err;
4343 }
4344 if (cfg->line_out_type != AUTO_PIN_HP_OUT) {
4345 err = create_out_jack_modes(codec, cfg->hp_outs,
4346 cfg->hp_pins);
4347 if (err < 0)
4348 return err;
4349 }
4350 }
4351
Takashi Iwai352f7f92012-12-19 12:52:06 +01004352 dig_only:
4353 parse_digital(codec);
4354
Takashi Iwai55196ff2013-01-24 17:32:56 +01004355 if (spec->power_down_unused)
4356 codec->power_filter = snd_hda_gen_path_power_filter;
4357
Takashi Iwai7504b6c2013-03-18 11:25:51 +01004358 if (!spec->no_analog && spec->beep_nid) {
4359 err = snd_hda_attach_beep_device(codec, spec->beep_nid);
4360 if (err < 0)
4361 return err;
4362 }
4363
Takashi Iwai352f7f92012-12-19 12:52:06 +01004364 return 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004365}
Takashi Iwai352f7f92012-12-19 12:52:06 +01004366EXPORT_SYMBOL_HDA(snd_hda_gen_parse_auto_config);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004367
4368
4369/*
Takashi Iwai352f7f92012-12-19 12:52:06 +01004370 * Build control elements
Linus Torvalds1da177e2005-04-16 15:20:36 -07004371 */
Takashi Iwai352f7f92012-12-19 12:52:06 +01004372
4373/* slave controls for virtual master */
4374static const char * const slave_pfxs[] = {
4375 "Front", "Surround", "Center", "LFE", "Side",
4376 "Headphone", "Speaker", "Mono", "Line Out",
4377 "CLFE", "Bass Speaker", "PCM",
Takashi Iwaiee79c692013-01-07 09:57:42 +01004378 "Speaker Front", "Speaker Surround", "Speaker CLFE", "Speaker Side",
4379 "Headphone Front", "Headphone Surround", "Headphone CLFE",
4380 "Headphone Side",
Takashi Iwai352f7f92012-12-19 12:52:06 +01004381 NULL,
4382};
4383
4384int snd_hda_gen_build_controls(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004385{
Takashi Iwai352f7f92012-12-19 12:52:06 +01004386 struct hda_gen_spec *spec = codec->spec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004387 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004388
Takashi Iwai36502d02012-12-19 15:15:10 +01004389 if (spec->kctls.used) {
4390 err = snd_hda_add_new_ctls(codec, spec->kctls.list);
4391 if (err < 0)
4392 return err;
4393 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004394
Takashi Iwai352f7f92012-12-19 12:52:06 +01004395 if (spec->multiout.dig_out_nid) {
4396 err = snd_hda_create_dig_out_ctls(codec,
4397 spec->multiout.dig_out_nid,
4398 spec->multiout.dig_out_nid,
4399 spec->pcm_rec[1].pcm_type);
4400 if (err < 0)
4401 return err;
4402 if (!spec->no_analog) {
4403 err = snd_hda_create_spdif_share_sw(codec,
4404 &spec->multiout);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004405 if (err < 0)
4406 return err;
Takashi Iwai352f7f92012-12-19 12:52:06 +01004407 spec->multiout.share_spdif = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004408 }
4409 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01004410 if (spec->dig_in_nid) {
4411 err = snd_hda_create_spdif_in_ctls(codec, spec->dig_in_nid);
4412 if (err < 0)
4413 return err;
4414 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004415
Takashi Iwai352f7f92012-12-19 12:52:06 +01004416 /* if we have no master control, let's create it */
4417 if (!spec->no_analog &&
4418 !snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) {
Takashi Iwai352f7f92012-12-19 12:52:06 +01004419 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
Takashi Iwai7a71bbf2013-01-17 10:25:15 +01004420 spec->vmaster_tlv, slave_pfxs,
Takashi Iwai352f7f92012-12-19 12:52:06 +01004421 "Playback Volume");
4422 if (err < 0)
4423 return err;
4424 }
4425 if (!spec->no_analog &&
4426 !snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) {
4427 err = __snd_hda_add_vmaster(codec, "Master Playback Switch",
4428 NULL, slave_pfxs,
4429 "Playback Switch",
4430 true, &spec->vmaster_mute.sw_kctl);
4431 if (err < 0)
4432 return err;
4433 if (spec->vmaster_mute.hook)
Takashi Iwaifd25a972012-12-20 14:57:18 +01004434 snd_hda_add_vmaster_hook(codec, &spec->vmaster_mute,
4435 spec->vmaster_mute_enum);
Takashi Iwai352f7f92012-12-19 12:52:06 +01004436 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004437
Takashi Iwai352f7f92012-12-19 12:52:06 +01004438 free_kctls(spec); /* no longer needed */
4439
Takashi Iwai352f7f92012-12-19 12:52:06 +01004440 err = snd_hda_jack_add_kctls(codec, &spec->autocfg);
4441 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004442 return err;
4443
4444 return 0;
4445}
Takashi Iwai352f7f92012-12-19 12:52:06 +01004446EXPORT_SYMBOL_HDA(snd_hda_gen_build_controls);
4447
Linus Torvalds1da177e2005-04-16 15:20:36 -07004448
4449/*
Takashi Iwai352f7f92012-12-19 12:52:06 +01004450 * PCM definitions
Linus Torvalds1da177e2005-04-16 15:20:36 -07004451 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07004452
Takashi Iwaie6b85f32013-01-07 11:54:34 +01004453static void call_pcm_playback_hook(struct hda_pcm_stream *hinfo,
4454 struct hda_codec *codec,
4455 struct snd_pcm_substream *substream,
4456 int action)
4457{
4458 struct hda_gen_spec *spec = codec->spec;
4459 if (spec->pcm_playback_hook)
4460 spec->pcm_playback_hook(hinfo, codec, substream, action);
4461}
4462
Takashi Iwaiac2e8732013-01-17 15:57:10 +01004463static void call_pcm_capture_hook(struct hda_pcm_stream *hinfo,
4464 struct hda_codec *codec,
4465 struct snd_pcm_substream *substream,
4466 int action)
4467{
4468 struct hda_gen_spec *spec = codec->spec;
4469 if (spec->pcm_capture_hook)
4470 spec->pcm_capture_hook(hinfo, codec, substream, action);
4471}
4472
Takashi Iwai352f7f92012-12-19 12:52:06 +01004473/*
4474 * Analog playback callbacks
4475 */
4476static int playback_pcm_open(struct hda_pcm_stream *hinfo,
4477 struct hda_codec *codec,
4478 struct snd_pcm_substream *substream)
4479{
4480 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004481 int err;
4482
4483 mutex_lock(&spec->pcm_mutex);
4484 err = snd_hda_multi_out_analog_open(codec,
4485 &spec->multiout, substream,
Takashi Iwai352f7f92012-12-19 12:52:06 +01004486 hinfo);
Takashi Iwaie6b85f32013-01-07 11:54:34 +01004487 if (!err) {
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004488 spec->active_streams |= 1 << STREAM_MULTI_OUT;
Takashi Iwaie6b85f32013-01-07 11:54:34 +01004489 call_pcm_playback_hook(hinfo, codec, substream,
4490 HDA_GEN_PCM_ACT_OPEN);
4491 }
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004492 mutex_unlock(&spec->pcm_mutex);
4493 return err;
Takashi Iwai352f7f92012-12-19 12:52:06 +01004494}
4495
4496static int playback_pcm_prepare(struct hda_pcm_stream *hinfo,
Takashi Iwai97ec5582006-03-21 11:29:07 +01004497 struct hda_codec *codec,
4498 unsigned int stream_tag,
4499 unsigned int format,
4500 struct snd_pcm_substream *substream)
4501{
Takashi Iwai352f7f92012-12-19 12:52:06 +01004502 struct hda_gen_spec *spec = codec->spec;
Takashi Iwaie6b85f32013-01-07 11:54:34 +01004503 int err;
4504
4505 err = snd_hda_multi_out_analog_prepare(codec, &spec->multiout,
4506 stream_tag, format, substream);
4507 if (!err)
4508 call_pcm_playback_hook(hinfo, codec, substream,
4509 HDA_GEN_PCM_ACT_PREPARE);
4510 return err;
Takashi Iwai352f7f92012-12-19 12:52:06 +01004511}
Takashi Iwai97ec5582006-03-21 11:29:07 +01004512
Takashi Iwai352f7f92012-12-19 12:52:06 +01004513static int playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4514 struct hda_codec *codec,
4515 struct snd_pcm_substream *substream)
4516{
4517 struct hda_gen_spec *spec = codec->spec;
Takashi Iwaie6b85f32013-01-07 11:54:34 +01004518 int err;
4519
4520 err = snd_hda_multi_out_analog_cleanup(codec, &spec->multiout);
4521 if (!err)
4522 call_pcm_playback_hook(hinfo, codec, substream,
4523 HDA_GEN_PCM_ACT_CLEANUP);
4524 return err;
Takashi Iwai352f7f92012-12-19 12:52:06 +01004525}
4526
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004527static int playback_pcm_close(struct hda_pcm_stream *hinfo,
4528 struct hda_codec *codec,
4529 struct snd_pcm_substream *substream)
4530{
4531 struct hda_gen_spec *spec = codec->spec;
4532 mutex_lock(&spec->pcm_mutex);
4533 spec->active_streams &= ~(1 << STREAM_MULTI_OUT);
Takashi Iwaie6b85f32013-01-07 11:54:34 +01004534 call_pcm_playback_hook(hinfo, codec, substream,
4535 HDA_GEN_PCM_ACT_CLOSE);
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004536 mutex_unlock(&spec->pcm_mutex);
4537 return 0;
4538}
4539
Takashi Iwaiac2e8732013-01-17 15:57:10 +01004540static int capture_pcm_open(struct hda_pcm_stream *hinfo,
4541 struct hda_codec *codec,
4542 struct snd_pcm_substream *substream)
4543{
4544 call_pcm_capture_hook(hinfo, codec, substream, HDA_GEN_PCM_ACT_OPEN);
4545 return 0;
4546}
4547
4548static int capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4549 struct hda_codec *codec,
4550 unsigned int stream_tag,
4551 unsigned int format,
4552 struct snd_pcm_substream *substream)
4553{
4554 snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
4555 call_pcm_capture_hook(hinfo, codec, substream,
4556 HDA_GEN_PCM_ACT_PREPARE);
4557 return 0;
4558}
4559
4560static int capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4561 struct hda_codec *codec,
4562 struct snd_pcm_substream *substream)
4563{
4564 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
4565 call_pcm_capture_hook(hinfo, codec, substream,
4566 HDA_GEN_PCM_ACT_CLEANUP);
4567 return 0;
4568}
4569
4570static int capture_pcm_close(struct hda_pcm_stream *hinfo,
4571 struct hda_codec *codec,
4572 struct snd_pcm_substream *substream)
4573{
4574 call_pcm_capture_hook(hinfo, codec, substream, HDA_GEN_PCM_ACT_CLOSE);
4575 return 0;
4576}
4577
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004578static int alt_playback_pcm_open(struct hda_pcm_stream *hinfo,
4579 struct hda_codec *codec,
4580 struct snd_pcm_substream *substream)
4581{
4582 struct hda_gen_spec *spec = codec->spec;
4583 int err = 0;
4584
4585 mutex_lock(&spec->pcm_mutex);
4586 if (!spec->indep_hp_enabled)
4587 err = -EBUSY;
4588 else
4589 spec->active_streams |= 1 << STREAM_INDEP_HP;
Takashi Iwaie6b85f32013-01-07 11:54:34 +01004590 call_pcm_playback_hook(hinfo, codec, substream,
4591 HDA_GEN_PCM_ACT_OPEN);
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004592 mutex_unlock(&spec->pcm_mutex);
4593 return err;
4594}
4595
4596static int alt_playback_pcm_close(struct hda_pcm_stream *hinfo,
4597 struct hda_codec *codec,
4598 struct snd_pcm_substream *substream)
4599{
4600 struct hda_gen_spec *spec = codec->spec;
4601 mutex_lock(&spec->pcm_mutex);
4602 spec->active_streams &= ~(1 << STREAM_INDEP_HP);
Takashi Iwaie6b85f32013-01-07 11:54:34 +01004603 call_pcm_playback_hook(hinfo, codec, substream,
4604 HDA_GEN_PCM_ACT_CLOSE);
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004605 mutex_unlock(&spec->pcm_mutex);
4606 return 0;
4607}
4608
Takashi Iwaie6b85f32013-01-07 11:54:34 +01004609static int alt_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4610 struct hda_codec *codec,
4611 unsigned int stream_tag,
4612 unsigned int format,
4613 struct snd_pcm_substream *substream)
4614{
4615 snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
4616 call_pcm_playback_hook(hinfo, codec, substream,
4617 HDA_GEN_PCM_ACT_PREPARE);
4618 return 0;
4619}
4620
4621static int alt_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4622 struct hda_codec *codec,
4623 struct snd_pcm_substream *substream)
4624{
4625 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
4626 call_pcm_playback_hook(hinfo, codec, substream,
4627 HDA_GEN_PCM_ACT_CLEANUP);
4628 return 0;
4629}
4630
Takashi Iwai352f7f92012-12-19 12:52:06 +01004631/*
4632 * Digital out
4633 */
4634static int dig_playback_pcm_open(struct hda_pcm_stream *hinfo,
4635 struct hda_codec *codec,
4636 struct snd_pcm_substream *substream)
4637{
4638 struct hda_gen_spec *spec = codec->spec;
4639 return snd_hda_multi_out_dig_open(codec, &spec->multiout);
4640}
4641
4642static int dig_playback_pcm_prepare(struct hda_pcm_stream *hinfo,
4643 struct hda_codec *codec,
4644 unsigned int stream_tag,
4645 unsigned int format,
4646 struct snd_pcm_substream *substream)
4647{
4648 struct hda_gen_spec *spec = codec->spec;
4649 return snd_hda_multi_out_dig_prepare(codec, &spec->multiout,
4650 stream_tag, format, substream);
4651}
4652
4653static int dig_playback_pcm_cleanup(struct hda_pcm_stream *hinfo,
4654 struct hda_codec *codec,
4655 struct snd_pcm_substream *substream)
4656{
4657 struct hda_gen_spec *spec = codec->spec;
4658 return snd_hda_multi_out_dig_cleanup(codec, &spec->multiout);
4659}
4660
4661static int dig_playback_pcm_close(struct hda_pcm_stream *hinfo,
4662 struct hda_codec *codec,
4663 struct snd_pcm_substream *substream)
4664{
4665 struct hda_gen_spec *spec = codec->spec;
4666 return snd_hda_multi_out_dig_close(codec, &spec->multiout);
4667}
4668
4669/*
4670 * Analog capture
4671 */
Takashi Iwaiac2e8732013-01-17 15:57:10 +01004672#define alt_capture_pcm_open capture_pcm_open
4673#define alt_capture_pcm_close capture_pcm_close
4674
Takashi Iwai352f7f92012-12-19 12:52:06 +01004675static int alt_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4676 struct hda_codec *codec,
4677 unsigned int stream_tag,
4678 unsigned int format,
4679 struct snd_pcm_substream *substream)
4680{
4681 struct hda_gen_spec *spec = codec->spec;
4682
4683 snd_hda_codec_setup_stream(codec, spec->adc_nids[substream->number + 1],
Takashi Iwai97ec5582006-03-21 11:29:07 +01004684 stream_tag, 0, format);
Takashi Iwaiac2e8732013-01-17 15:57:10 +01004685 call_pcm_capture_hook(hinfo, codec, substream,
4686 HDA_GEN_PCM_ACT_PREPARE);
Takashi Iwai97ec5582006-03-21 11:29:07 +01004687 return 0;
4688}
4689
Takashi Iwai352f7f92012-12-19 12:52:06 +01004690static int alt_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4691 struct hda_codec *codec,
4692 struct snd_pcm_substream *substream)
Takashi Iwai97ec5582006-03-21 11:29:07 +01004693{
Takashi Iwai352f7f92012-12-19 12:52:06 +01004694 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai97ec5582006-03-21 11:29:07 +01004695
Takashi Iwai352f7f92012-12-19 12:52:06 +01004696 snd_hda_codec_cleanup_stream(codec,
4697 spec->adc_nids[substream->number + 1]);
Takashi Iwaiac2e8732013-01-17 15:57:10 +01004698 call_pcm_capture_hook(hinfo, codec, substream,
4699 HDA_GEN_PCM_ACT_CLEANUP);
Takashi Iwai97ec5582006-03-21 11:29:07 +01004700 return 0;
4701}
4702
Takashi Iwai352f7f92012-12-19 12:52:06 +01004703/*
4704 */
4705static const struct hda_pcm_stream pcm_analog_playback = {
4706 .substreams = 1,
4707 .channels_min = 2,
4708 .channels_max = 8,
4709 /* NID is set in build_pcms */
4710 .ops = {
4711 .open = playback_pcm_open,
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004712 .close = playback_pcm_close,
Takashi Iwai352f7f92012-12-19 12:52:06 +01004713 .prepare = playback_pcm_prepare,
4714 .cleanup = playback_pcm_cleanup
4715 },
4716};
Linus Torvalds1da177e2005-04-16 15:20:36 -07004717
Takashi Iwai352f7f92012-12-19 12:52:06 +01004718static const struct hda_pcm_stream pcm_analog_capture = {
4719 .substreams = 1,
4720 .channels_min = 2,
4721 .channels_max = 2,
4722 /* NID is set in build_pcms */
Takashi Iwaiac2e8732013-01-17 15:57:10 +01004723 .ops = {
4724 .open = capture_pcm_open,
4725 .close = capture_pcm_close,
4726 .prepare = capture_pcm_prepare,
4727 .cleanup = capture_pcm_cleanup
4728 },
Takashi Iwai352f7f92012-12-19 12:52:06 +01004729};
4730
4731static const struct hda_pcm_stream pcm_analog_alt_playback = {
4732 .substreams = 1,
4733 .channels_min = 2,
4734 .channels_max = 2,
4735 /* NID is set in build_pcms */
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004736 .ops = {
4737 .open = alt_playback_pcm_open,
Takashi Iwaie6b85f32013-01-07 11:54:34 +01004738 .close = alt_playback_pcm_close,
4739 .prepare = alt_playback_pcm_prepare,
4740 .cleanup = alt_playback_pcm_cleanup
Takashi Iwai38cf6f12012-12-21 14:09:42 +01004741 },
Takashi Iwai352f7f92012-12-19 12:52:06 +01004742};
4743
4744static const struct hda_pcm_stream pcm_analog_alt_capture = {
4745 .substreams = 2, /* can be overridden */
4746 .channels_min = 2,
4747 .channels_max = 2,
4748 /* NID is set in build_pcms */
4749 .ops = {
Takashi Iwaiac2e8732013-01-17 15:57:10 +01004750 .open = alt_capture_pcm_open,
4751 .close = alt_capture_pcm_close,
Takashi Iwai352f7f92012-12-19 12:52:06 +01004752 .prepare = alt_capture_pcm_prepare,
4753 .cleanup = alt_capture_pcm_cleanup
4754 },
4755};
4756
4757static const struct hda_pcm_stream pcm_digital_playback = {
4758 .substreams = 1,
4759 .channels_min = 2,
4760 .channels_max = 2,
4761 /* NID is set in build_pcms */
4762 .ops = {
4763 .open = dig_playback_pcm_open,
4764 .close = dig_playback_pcm_close,
4765 .prepare = dig_playback_pcm_prepare,
4766 .cleanup = dig_playback_pcm_cleanup
4767 },
4768};
4769
4770static const struct hda_pcm_stream pcm_digital_capture = {
4771 .substreams = 1,
4772 .channels_min = 2,
4773 .channels_max = 2,
4774 /* NID is set in build_pcms */
4775};
4776
4777/* Used by build_pcms to flag that a PCM has no playback stream */
4778static const struct hda_pcm_stream pcm_null_stream = {
4779 .substreams = 0,
4780 .channels_min = 0,
4781 .channels_max = 0,
4782};
4783
4784/*
4785 * dynamic changing ADC PCM streams
4786 */
4787static bool dyn_adc_pcm_resetup(struct hda_codec *codec, int cur)
4788{
4789 struct hda_gen_spec *spec = codec->spec;
4790 hda_nid_t new_adc = spec->adc_nids[spec->dyn_adc_idx[cur]];
4791
4792 if (spec->cur_adc && spec->cur_adc != new_adc) {
4793 /* stream is running, let's swap the current ADC */
4794 __snd_hda_codec_cleanup_stream(codec, spec->cur_adc, 1);
4795 spec->cur_adc = new_adc;
4796 snd_hda_codec_setup_stream(codec, new_adc,
4797 spec->cur_adc_stream_tag, 0,
4798 spec->cur_adc_format);
4799 return true;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004800 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01004801 return false;
4802}
4803
4804/* analog capture with dynamic dual-adc changes */
4805static int dyn_adc_capture_pcm_prepare(struct hda_pcm_stream *hinfo,
4806 struct hda_codec *codec,
4807 unsigned int stream_tag,
4808 unsigned int format,
4809 struct snd_pcm_substream *substream)
4810{
4811 struct hda_gen_spec *spec = codec->spec;
4812 spec->cur_adc = spec->adc_nids[spec->dyn_adc_idx[spec->cur_mux[0]]];
4813 spec->cur_adc_stream_tag = stream_tag;
4814 spec->cur_adc_format = format;
4815 snd_hda_codec_setup_stream(codec, spec->cur_adc, stream_tag, 0, format);
4816 return 0;
4817}
4818
4819static int dyn_adc_capture_pcm_cleanup(struct hda_pcm_stream *hinfo,
4820 struct hda_codec *codec,
4821 struct snd_pcm_substream *substream)
4822{
4823 struct hda_gen_spec *spec = codec->spec;
4824 snd_hda_codec_cleanup_stream(codec, spec->cur_adc);
4825 spec->cur_adc = 0;
4826 return 0;
4827}
4828
4829static const struct hda_pcm_stream dyn_adc_pcm_analog_capture = {
4830 .substreams = 1,
4831 .channels_min = 2,
4832 .channels_max = 2,
4833 .nid = 0, /* fill later */
4834 .ops = {
4835 .prepare = dyn_adc_capture_pcm_prepare,
4836 .cleanup = dyn_adc_capture_pcm_cleanup
4837 },
4838};
4839
Takashi Iwaif873e532012-12-20 16:58:39 +01004840static void fill_pcm_stream_name(char *str, size_t len, const char *sfx,
4841 const char *chip_name)
4842{
4843 char *p;
4844
4845 if (*str)
4846 return;
4847 strlcpy(str, chip_name, len);
4848
4849 /* drop non-alnum chars after a space */
4850 for (p = strchr(str, ' '); p; p = strchr(p + 1, ' ')) {
4851 if (!isalnum(p[1])) {
4852 *p = 0;
4853 break;
4854 }
4855 }
4856 strlcat(str, sfx, len);
4857}
4858
Takashi Iwai352f7f92012-12-19 12:52:06 +01004859/* build PCM streams based on the parsed results */
4860int snd_hda_gen_build_pcms(struct hda_codec *codec)
4861{
4862 struct hda_gen_spec *spec = codec->spec;
4863 struct hda_pcm *info = spec->pcm_rec;
4864 const struct hda_pcm_stream *p;
4865 bool have_multi_adcs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004866
4867 codec->num_pcms = 1;
4868 codec->pcm_info = info;
4869
Takashi Iwai352f7f92012-12-19 12:52:06 +01004870 if (spec->no_analog)
4871 goto skip_analog;
4872
Takashi Iwaif873e532012-12-20 16:58:39 +01004873 fill_pcm_stream_name(spec->stream_name_analog,
4874 sizeof(spec->stream_name_analog),
4875 " Analog", codec->chip_name);
Takashi Iwai352f7f92012-12-19 12:52:06 +01004876 info->name = spec->stream_name_analog;
4877
4878 if (spec->multiout.num_dacs > 0) {
4879 p = spec->stream_analog_playback;
4880 if (!p)
4881 p = &pcm_analog_playback;
4882 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4883 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dac_nids[0];
4884 info->stream[SNDRV_PCM_STREAM_PLAYBACK].channels_max =
4885 spec->multiout.max_channels;
4886 if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT &&
4887 spec->autocfg.line_outs == 2)
4888 info->stream[SNDRV_PCM_STREAM_PLAYBACK].chmap =
4889 snd_pcm_2_1_chmaps;
4890 }
4891 if (spec->num_adc_nids) {
4892 p = spec->stream_analog_capture;
4893 if (!p) {
4894 if (spec->dyn_adc_switch)
4895 p = &dyn_adc_pcm_analog_capture;
4896 else
4897 p = &pcm_analog_capture;
4898 }
4899 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4900 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->adc_nids[0];
4901 }
4902
Takashi Iwai352f7f92012-12-19 12:52:06 +01004903 skip_analog:
4904 /* SPDIF for stream index #1 */
4905 if (spec->multiout.dig_out_nid || spec->dig_in_nid) {
Takashi Iwaif873e532012-12-20 16:58:39 +01004906 fill_pcm_stream_name(spec->stream_name_digital,
4907 sizeof(spec->stream_name_digital),
4908 " Digital", codec->chip_name);
Takashi Iwai352f7f92012-12-19 12:52:06 +01004909 codec->num_pcms = 2;
4910 codec->slave_dig_outs = spec->multiout.slave_dig_outs;
4911 info = spec->pcm_rec + 1;
4912 info->name = spec->stream_name_digital;
4913 if (spec->dig_out_type)
4914 info->pcm_type = spec->dig_out_type;
4915 else
4916 info->pcm_type = HDA_PCM_TYPE_SPDIF;
4917 if (spec->multiout.dig_out_nid) {
4918 p = spec->stream_digital_playback;
4919 if (!p)
4920 p = &pcm_digital_playback;
4921 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4922 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = spec->multiout.dig_out_nid;
4923 }
4924 if (spec->dig_in_nid) {
4925 p = spec->stream_digital_capture;
4926 if (!p)
4927 p = &pcm_digital_capture;
4928 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4929 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = spec->dig_in_nid;
4930 }
4931 }
4932
4933 if (spec->no_analog)
4934 return 0;
4935
4936 /* If the use of more than one ADC is requested for the current
4937 * model, configure a second analog capture-only PCM.
4938 */
4939 have_multi_adcs = (spec->num_adc_nids > 1) &&
4940 !spec->dyn_adc_switch && !spec->auto_mic;
4941 /* Additional Analaog capture for index #2 */
4942 if (spec->alt_dac_nid || have_multi_adcs) {
Takashi Iwaia6071482013-01-21 16:50:09 +01004943 fill_pcm_stream_name(spec->stream_name_alt_analog,
4944 sizeof(spec->stream_name_alt_analog),
4945 " Alt Analog", codec->chip_name);
Takashi Iwai352f7f92012-12-19 12:52:06 +01004946 codec->num_pcms = 3;
4947 info = spec->pcm_rec + 2;
Takashi Iwaia6071482013-01-21 16:50:09 +01004948 info->name = spec->stream_name_alt_analog;
Takashi Iwai352f7f92012-12-19 12:52:06 +01004949 if (spec->alt_dac_nid) {
4950 p = spec->stream_analog_alt_playback;
4951 if (!p)
4952 p = &pcm_analog_alt_playback;
4953 info->stream[SNDRV_PCM_STREAM_PLAYBACK] = *p;
4954 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid =
4955 spec->alt_dac_nid;
4956 } else {
4957 info->stream[SNDRV_PCM_STREAM_PLAYBACK] =
4958 pcm_null_stream;
4959 info->stream[SNDRV_PCM_STREAM_PLAYBACK].nid = 0;
4960 }
4961 if (have_multi_adcs) {
4962 p = spec->stream_analog_alt_capture;
4963 if (!p)
4964 p = &pcm_analog_alt_capture;
4965 info->stream[SNDRV_PCM_STREAM_CAPTURE] = *p;
4966 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid =
4967 spec->adc_nids[1];
4968 info->stream[SNDRV_PCM_STREAM_CAPTURE].substreams =
4969 spec->num_adc_nids - 1;
4970 } else {
4971 info->stream[SNDRV_PCM_STREAM_CAPTURE] =
4972 pcm_null_stream;
4973 info->stream[SNDRV_PCM_STREAM_CAPTURE].nid = 0;
4974 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004975 }
4976
4977 return 0;
4978}
Takashi Iwai352f7f92012-12-19 12:52:06 +01004979EXPORT_SYMBOL_HDA(snd_hda_gen_build_pcms);
4980
4981
4982/*
4983 * Standard auto-parser initializations
4984 */
4985
Takashi Iwaid4156932013-01-07 10:08:02 +01004986/* configure the given path as a proper output */
Takashi Iwai2c12c302013-01-10 09:33:29 +01004987static void set_output_and_unmute(struct hda_codec *codec, int path_idx)
Takashi Iwai352f7f92012-12-19 12:52:06 +01004988{
4989 struct nid_path *path;
Takashi Iwaid4156932013-01-07 10:08:02 +01004990 hda_nid_t pin;
Takashi Iwai352f7f92012-12-19 12:52:06 +01004991
Takashi Iwai196c17662013-01-04 15:01:40 +01004992 path = snd_hda_get_path_from_idx(codec, path_idx);
Takashi Iwaid4156932013-01-07 10:08:02 +01004993 if (!path || !path->depth)
Takashi Iwai352f7f92012-12-19 12:52:06 +01004994 return;
Takashi Iwaid4156932013-01-07 10:08:02 +01004995 pin = path->path[path->depth - 1];
Takashi Iwai2c12c302013-01-10 09:33:29 +01004996 restore_pin_ctl(codec, pin);
Takashi Iwai65033cc2013-04-16 12:31:05 +02004997 snd_hda_activate_path(codec, path, path->active,
4998 aamix_default(codec->spec));
Takashi Iwaie1284af2013-01-03 16:33:02 +01004999 set_pin_eapd(codec, pin, path->active);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005000}
5001
5002/* initialize primary output paths */
5003static void init_multi_out(struct hda_codec *codec)
5004{
5005 struct hda_gen_spec *spec = codec->spec;
Takashi Iwai352f7f92012-12-19 12:52:06 +01005006 int i;
5007
Takashi Iwaid4156932013-01-07 10:08:02 +01005008 for (i = 0; i < spec->autocfg.line_outs; i++)
Takashi Iwai2c12c302013-01-10 09:33:29 +01005009 set_output_and_unmute(codec, spec->out_paths[i]);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005010}
5011
Takashi Iwaidb23fd12012-12-20 15:27:24 +01005012
Takashi Iwai2c12c302013-01-10 09:33:29 +01005013static void __init_extra_out(struct hda_codec *codec, int num_outs, int *paths)
Takashi Iwai352f7f92012-12-19 12:52:06 +01005014{
Takashi Iwai352f7f92012-12-19 12:52:06 +01005015 int i;
Takashi Iwai352f7f92012-12-19 12:52:06 +01005016
Takashi Iwaid4156932013-01-07 10:08:02 +01005017 for (i = 0; i < num_outs; i++)
Takashi Iwai2c12c302013-01-10 09:33:29 +01005018 set_output_and_unmute(codec, paths[i]);
Takashi Iwaidb23fd12012-12-20 15:27:24 +01005019}
5020
5021/* initialize hp and speaker paths */
5022static void init_extra_out(struct hda_codec *codec)
5023{
5024 struct hda_gen_spec *spec = codec->spec;
5025
5026 if (spec->autocfg.line_out_type != AUTO_PIN_HP_OUT)
Takashi Iwai2c12c302013-01-10 09:33:29 +01005027 __init_extra_out(codec, spec->autocfg.hp_outs, spec->hp_paths);
Takashi Iwaidb23fd12012-12-20 15:27:24 +01005028 if (spec->autocfg.line_out_type != AUTO_PIN_SPEAKER_OUT)
5029 __init_extra_out(codec, spec->autocfg.speaker_outs,
Takashi Iwai2c12c302013-01-10 09:33:29 +01005030 spec->speaker_paths);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005031}
5032
5033/* initialize multi-io paths */
5034static void init_multi_io(struct hda_codec *codec)
5035{
5036 struct hda_gen_spec *spec = codec->spec;
5037 int i;
5038
5039 for (i = 0; i < spec->multi_ios; i++) {
5040 hda_nid_t pin = spec->multi_io[i].pin;
5041 struct nid_path *path;
Takashi Iwai196c17662013-01-04 15:01:40 +01005042 path = get_multiio_path(codec, i);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005043 if (!path)
5044 continue;
5045 if (!spec->multi_io[i].ctl_in)
5046 spec->multi_io[i].ctl_in =
Takashi Iwai2c12c302013-01-10 09:33:29 +01005047 snd_hda_codec_get_pin_target(codec, pin);
Takashi Iwai65033cc2013-04-16 12:31:05 +02005048 snd_hda_activate_path(codec, path, path->active,
5049 aamix_default(spec));
Takashi Iwai352f7f92012-12-19 12:52:06 +01005050 }
5051}
5052
Takashi Iwai352f7f92012-12-19 12:52:06 +01005053/* set up input pins and loopback paths */
5054static void init_analog_input(struct hda_codec *codec)
5055{
5056 struct hda_gen_spec *spec = codec->spec;
5057 struct auto_pin_cfg *cfg = &spec->autocfg;
5058 int i;
5059
5060 for (i = 0; i < cfg->num_inputs; i++) {
5061 hda_nid_t nid = cfg->inputs[i].pin;
5062 if (is_input_pin(codec, nid))
Takashi Iwai2c12c302013-01-10 09:33:29 +01005063 restore_pin_ctl(codec, nid);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005064
5065 /* init loopback inputs */
5066 if (spec->mixer_nid) {
Takashi Iwai3e367f12013-01-23 17:07:23 +01005067 resume_path_from_idx(codec, spec->loopback_paths[i]);
5068 resume_path_from_idx(codec, spec->loopback_merge_path);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005069 }
5070 }
5071}
5072
5073/* initialize ADC paths */
5074static void init_input_src(struct hda_codec *codec)
5075{
5076 struct hda_gen_spec *spec = codec->spec;
5077 struct hda_input_mux *imux = &spec->input_mux;
5078 struct nid_path *path;
5079 int i, c, nums;
5080
5081 if (spec->dyn_adc_switch)
5082 nums = 1;
5083 else
5084 nums = spec->num_adc_nids;
5085
5086 for (c = 0; c < nums; c++) {
5087 for (i = 0; i < imux->num_items; i++) {
Takashi Iwaic697b712013-01-07 17:09:26 +01005088 path = get_input_path(codec, c, i);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005089 if (path) {
5090 bool active = path->active;
5091 if (i == spec->cur_mux[c])
5092 active = true;
5093 snd_hda_activate_path(codec, path, active, false);
5094 }
5095 }
Takashi Iwai967303d2013-02-19 17:12:42 +01005096 if (spec->hp_mic)
5097 update_hp_mic(codec, c, true);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005098 }
5099
Takashi Iwai352f7f92012-12-19 12:52:06 +01005100 if (spec->cap_sync_hook)
Takashi Iwaia90229e2013-01-18 14:10:00 +01005101 spec->cap_sync_hook(codec, NULL);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005102}
5103
5104/* set right pin controls for digital I/O */
5105static void init_digital(struct hda_codec *codec)
5106{
5107 struct hda_gen_spec *spec = codec->spec;
5108 int i;
5109 hda_nid_t pin;
5110
Takashi Iwaid4156932013-01-07 10:08:02 +01005111 for (i = 0; i < spec->autocfg.dig_outs; i++)
Takashi Iwai2c12c302013-01-10 09:33:29 +01005112 set_output_and_unmute(codec, spec->digout_paths[i]);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005113 pin = spec->autocfg.dig_in_pin;
Takashi Iwai2430d7b2013-01-04 15:09:42 +01005114 if (pin) {
Takashi Iwai2c12c302013-01-10 09:33:29 +01005115 restore_pin_ctl(codec, pin);
Takashi Iwai3e367f12013-01-23 17:07:23 +01005116 resume_path_from_idx(codec, spec->digin_path);
Takashi Iwai2430d7b2013-01-04 15:09:42 +01005117 }
Takashi Iwai352f7f92012-12-19 12:52:06 +01005118}
5119
Takashi Iwai973e4972012-12-20 15:16:09 +01005120/* clear unsol-event tags on unused pins; Conexant codecs seem to leave
5121 * invalid unsol tags by some reason
5122 */
5123static void clear_unsol_on_unused_pins(struct hda_codec *codec)
5124{
5125 int i;
5126
5127 for (i = 0; i < codec->init_pins.used; i++) {
5128 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
5129 hda_nid_t nid = pin->nid;
5130 if (is_jack_detectable(codec, nid) &&
5131 !snd_hda_jack_tbl_get(codec, nid))
5132 snd_hda_codec_update_cache(codec, nid, 0,
5133 AC_VERB_SET_UNSOLICITED_ENABLE, 0);
5134 }
5135}
5136
Takashi Iwai5187ac12013-01-07 12:52:16 +01005137/*
5138 * initialize the generic spec;
5139 * this can be put as patch_ops.init function
5140 */
Takashi Iwai352f7f92012-12-19 12:52:06 +01005141int snd_hda_gen_init(struct hda_codec *codec)
5142{
5143 struct hda_gen_spec *spec = codec->spec;
5144
5145 if (spec->init_hook)
5146 spec->init_hook(codec);
5147
5148 snd_hda_apply_verbs(codec);
5149
Takashi Iwai3bbcd272012-12-20 11:50:58 +01005150 codec->cached_write = 1;
5151
Takashi Iwai352f7f92012-12-19 12:52:06 +01005152 init_multi_out(codec);
5153 init_extra_out(codec);
5154 init_multi_io(codec);
5155 init_analog_input(codec);
5156 init_input_src(codec);
5157 init_digital(codec);
5158
Takashi Iwai973e4972012-12-20 15:16:09 +01005159 clear_unsol_on_unused_pins(codec);
5160
Takashi Iwai352f7f92012-12-19 12:52:06 +01005161 /* call init functions of standard auto-mute helpers */
Takashi Iwaia5cc2502013-01-16 18:08:55 +01005162 update_automute_all(codec);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005163
Takashi Iwaidc870f32013-01-22 15:24:30 +01005164 snd_hda_codec_flush_cache(codec);
Takashi Iwai3bbcd272012-12-20 11:50:58 +01005165
Takashi Iwai352f7f92012-12-19 12:52:06 +01005166 if (spec->vmaster_mute.sw_kctl && spec->vmaster_mute.hook)
5167 snd_hda_sync_vmaster_hook(&spec->vmaster_mute);
5168
5169 hda_call_check_power_status(codec, 0x01);
5170 return 0;
5171}
Takashi Iwaifce52a32013-01-07 12:42:48 +01005172EXPORT_SYMBOL_HDA(snd_hda_gen_init);
5173
Takashi Iwai5187ac12013-01-07 12:52:16 +01005174/*
5175 * free the generic spec;
5176 * this can be put as patch_ops.free function
5177 */
Takashi Iwaifce52a32013-01-07 12:42:48 +01005178void snd_hda_gen_free(struct hda_codec *codec)
5179{
Takashi Iwai7504b6c2013-03-18 11:25:51 +01005180 snd_hda_detach_beep_device(codec);
Takashi Iwaifce52a32013-01-07 12:42:48 +01005181 snd_hda_gen_spec_free(codec->spec);
5182 kfree(codec->spec);
5183 codec->spec = NULL;
5184}
5185EXPORT_SYMBOL_HDA(snd_hda_gen_free);
5186
5187#ifdef CONFIG_PM
Takashi Iwai5187ac12013-01-07 12:52:16 +01005188/*
5189 * check the loopback power save state;
5190 * this can be put as patch_ops.check_power_status function
5191 */
Takashi Iwaifce52a32013-01-07 12:42:48 +01005192int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid)
5193{
5194 struct hda_gen_spec *spec = codec->spec;
5195 return snd_hda_check_amp_list_power(codec, &spec->loopback, nid);
5196}
5197EXPORT_SYMBOL_HDA(snd_hda_gen_check_power_status);
5198#endif
Takashi Iwai352f7f92012-12-19 12:52:06 +01005199
5200
5201/*
5202 * the generic codec support
5203 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07005204
Takashi Iwai352f7f92012-12-19 12:52:06 +01005205static const struct hda_codec_ops generic_patch_ops = {
5206 .build_controls = snd_hda_gen_build_controls,
5207 .build_pcms = snd_hda_gen_build_pcms,
5208 .init = snd_hda_gen_init,
Takashi Iwaifce52a32013-01-07 12:42:48 +01005209 .free = snd_hda_gen_free,
Takashi Iwai352f7f92012-12-19 12:52:06 +01005210 .unsol_event = snd_hda_jack_unsol_event,
Takashi Iwai83012a72012-08-24 18:38:08 +02005211#ifdef CONFIG_PM
Takashi Iwaifce52a32013-01-07 12:42:48 +01005212 .check_power_status = snd_hda_gen_check_power_status,
Takashi Iwaicb53c622007-08-10 17:21:45 +02005213#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07005214};
5215
Linus Torvalds1da177e2005-04-16 15:20:36 -07005216int snd_hda_parse_generic_codec(struct hda_codec *codec)
5217{
Takashi Iwai352f7f92012-12-19 12:52:06 +01005218 struct hda_gen_spec *spec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005219 int err;
5220
Takashi Iwaie560d8d2005-09-09 14:21:46 +02005221 spec = kzalloc(sizeof(*spec), GFP_KERNEL);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005222 if (!spec)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005223 return -ENOMEM;
Takashi Iwai352f7f92012-12-19 12:52:06 +01005224 snd_hda_gen_spec_init(spec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005225 codec->spec = spec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005226
Takashi Iwai9eb413e2012-12-19 14:41:21 +01005227 err = snd_hda_parse_pin_defcfg(codec, &spec->autocfg, NULL, 0);
5228 if (err < 0)
5229 return err;
5230
5231 err = snd_hda_gen_parse_auto_config(codec, &spec->autocfg);
Takashi Iwai352f7f92012-12-19 12:52:06 +01005232 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07005233 goto error;
5234
5235 codec->patch_ops = generic_patch_ops;
Linus Torvalds1da177e2005-04-16 15:20:36 -07005236 return 0;
5237
Takashi Iwai352f7f92012-12-19 12:52:06 +01005238error:
Takashi Iwaifce52a32013-01-07 12:42:48 +01005239 snd_hda_gen_free(codec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07005240 return err;
5241}
Takashi Iwaifce52a32013-01-07 12:42:48 +01005242EXPORT_SYMBOL_HDA(snd_hda_parse_generic_codec);