blob: 2be61b31fb3cce05a5b2e988081aee8d25086644 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
2 * Universal Interface for Intel High Definition Audio Codec
3 *
4 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
5 *
6 *
7 * This driver is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This driver is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
Linus Torvalds1da177e2005-04-16 15:20:36 -070022#include <linux/init.h>
23#include <linux/delay.h>
24#include <linux/slab.h>
25#include <linux/pci.h>
Ingo Molnar62932df2006-01-16 16:34:20 +010026#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070027#include <sound/core.h>
28#include "hda_codec.h"
29#include <sound/asoundef.h>
Jaroslav Kysela302e9c52006-07-05 17:39:49 +020030#include <sound/tlv.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070031#include <sound/initval.h>
32#include "hda_local.h"
Jaroslav Kysela123c07a2009-10-21 14:48:23 +020033#include "hda_beep.h"
Takashi Iwai28073142007-07-27 18:58:06 +020034#include <sound/hda_hwdep.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070035
Linus Torvalds1da177e2005-04-16 15:20:36 -070036/*
37 * vendor / preset table
38 */
39
40struct hda_vendor_id {
41 unsigned int id;
42 const char *name;
43};
44
45/* codec vendor labels */
46static struct hda_vendor_id hda_vendor_ids[] = {
Takashi Iwaic8cd1282008-02-13 16:59:29 +010047 { 0x1002, "ATI" },
Takashi Iwaie5f14242009-07-01 18:11:44 +020048 { 0x1013, "Cirrus Logic" },
Takashi Iwaia9226252006-09-17 22:05:54 +020049 { 0x1057, "Motorola" },
Takashi Iwaic8cd1282008-02-13 16:59:29 +010050 { 0x1095, "Silicon Image" },
Takashi Iwai31117b72008-12-16 14:43:21 +010051 { 0x10de, "Nvidia" },
Takashi Iwaic8cd1282008-02-13 16:59:29 +010052 { 0x10ec, "Realtek" },
Takashi Iwai4e01f542009-04-16 08:53:34 +020053 { 0x1102, "Creative" },
Joseph Chanc577b8a2006-11-29 15:29:40 +010054 { 0x1106, "VIA" },
Matthew Ranostay7f168592007-10-18 17:38:17 +020055 { 0x111d, "IDT" },
Takashi Iwaic8cd1282008-02-13 16:59:29 +010056 { 0x11c1, "LSI" },
Takashi Iwai54b903e2005-05-15 14:30:10 +020057 { 0x11d4, "Analog Devices" },
Linus Torvalds1da177e2005-04-16 15:20:36 -070058 { 0x13f6, "C-Media" },
Takashi Iwaia9226252006-09-17 22:05:54 +020059 { 0x14f1, "Conexant" },
Takashi Iwaic8cd1282008-02-13 16:59:29 +010060 { 0x17e8, "Chrontel" },
61 { 0x1854, "LG" },
Mark Brown8199de32008-10-28 14:50:13 +000062 { 0x1aec, "Wolfson Microelectronics" },
Linus Torvalds1da177e2005-04-16 15:20:36 -070063 { 0x434d, "C-Media" },
Takashi Iwai74c61132008-12-18 09:11:33 +010064 { 0x8086, "Intel" },
Matt2f2f4252005-04-13 14:45:30 +020065 { 0x8384, "SigmaTel" },
Linus Torvalds1da177e2005-04-16 15:20:36 -070066 {} /* terminator */
67};
68
Takashi Iwai1289e9e2008-11-27 15:47:11 +010069static DEFINE_MUTEX(preset_mutex);
70static LIST_HEAD(hda_preset_tables);
71
72int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset)
73{
74 mutex_lock(&preset_mutex);
75 list_add_tail(&preset->list, &hda_preset_tables);
76 mutex_unlock(&preset_mutex);
77 return 0;
78}
Takashi Iwaiff7a3262008-11-28 15:17:06 +010079EXPORT_SYMBOL_HDA(snd_hda_add_codec_preset);
Takashi Iwai1289e9e2008-11-27 15:47:11 +010080
81int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset)
82{
83 mutex_lock(&preset_mutex);
84 list_del(&preset->list);
85 mutex_unlock(&preset_mutex);
86 return 0;
87}
Takashi Iwaiff7a3262008-11-28 15:17:06 +010088EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
Linus Torvalds1da177e2005-04-16 15:20:36 -070089
Takashi Iwaicb53c622007-08-10 17:21:45 +020090#ifdef CONFIG_SND_HDA_POWER_SAVE
91static void hda_power_work(struct work_struct *work);
92static void hda_keep_power_on(struct hda_codec *codec);
93#else
94static inline void hda_keep_power_on(struct hda_codec *codec) {}
95#endif
96
Takashi Iwaid5191e52009-11-16 14:58:17 +010097/**
98 * snd_hda_get_jack_location - Give a location string of the jack
99 * @cfg: pin default config value
100 *
101 * Parse the pin default config value and returns the string of the
102 * jack location, e.g. "Rear", "Front", etc.
103 */
Matthew Ranostay50a9f792008-10-25 01:05:45 -0400104const char *snd_hda_get_jack_location(u32 cfg)
105{
106 static char *bases[7] = {
107 "N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
108 };
109 static unsigned char specials_idx[] = {
110 0x07, 0x08,
111 0x17, 0x18, 0x19,
112 0x37, 0x38
113 };
114 static char *specials[] = {
115 "Rear Panel", "Drive Bar",
116 "Riser", "HDMI", "ATAPI",
117 "Mobile-In", "Mobile-Out"
118 };
119 int i;
120 cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
121 if ((cfg & 0x0f) < 7)
122 return bases[cfg & 0x0f];
123 for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
124 if (cfg == specials_idx[i])
125 return specials[i];
126 }
127 return "UNKNOWN";
128}
Takashi Iwaiff7a3262008-11-28 15:17:06 +0100129EXPORT_SYMBOL_HDA(snd_hda_get_jack_location);
Matthew Ranostay50a9f792008-10-25 01:05:45 -0400130
Takashi Iwaid5191e52009-11-16 14:58:17 +0100131/**
132 * snd_hda_get_jack_connectivity - Give a connectivity string of the jack
133 * @cfg: pin default config value
134 *
135 * Parse the pin default config value and returns the string of the
136 * jack connectivity, i.e. external or internal connection.
137 */
Matthew Ranostay50a9f792008-10-25 01:05:45 -0400138const char *snd_hda_get_jack_connectivity(u32 cfg)
139{
140 static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };
141
142 return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
143}
Takashi Iwaiff7a3262008-11-28 15:17:06 +0100144EXPORT_SYMBOL_HDA(snd_hda_get_jack_connectivity);
Matthew Ranostay50a9f792008-10-25 01:05:45 -0400145
Takashi Iwaid5191e52009-11-16 14:58:17 +0100146/**
147 * snd_hda_get_jack_type - Give a type string of the jack
148 * @cfg: pin default config value
149 *
150 * Parse the pin default config value and returns the string of the
151 * jack type, i.e. the purpose of the jack, such as Line-Out or CD.
152 */
Matthew Ranostay50a9f792008-10-25 01:05:45 -0400153const char *snd_hda_get_jack_type(u32 cfg)
154{
155 static char *jack_types[16] = {
156 "Line Out", "Speaker", "HP Out", "CD",
157 "SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
158 "Line In", "Aux", "Mic", "Telephony",
159 "SPDIF In", "Digitial In", "Reserved", "Other"
160 };
161
162 return jack_types[(cfg & AC_DEFCFG_DEVICE)
163 >> AC_DEFCFG_DEVICE_SHIFT];
164}
Takashi Iwaiff7a3262008-11-28 15:17:06 +0100165EXPORT_SYMBOL_HDA(snd_hda_get_jack_type);
Matthew Ranostay50a9f792008-10-25 01:05:45 -0400166
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100167/*
168 * Compose a 32bit command word to be sent to the HD-audio controller
169 */
170static inline unsigned int
171make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
172 unsigned int verb, unsigned int parm)
173{
174 u32 val;
175
Takashi Iwai82e1b802009-07-17 12:47:34 +0200176 if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) ||
177 (verb & ~0xfff) || (parm & ~0xffff)) {
Wu Fengguang6430aee2009-07-17 16:49:19 +0800178 printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
179 codec->addr, direct, nid, verb, parm);
180 return ~0;
181 }
182
183 val = (u32)codec->addr << 28;
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100184 val |= (u32)direct << 27;
185 val |= (u32)nid << 20;
186 val |= verb << 8;
187 val |= parm;
188 return val;
189}
190
Takashi Iwaiaa2936f2009-05-26 16:07:57 +0200191/*
192 * Send and receive a verb
193 */
194static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
195 unsigned int *res)
196{
197 struct hda_bus *bus = codec->bus;
Takashi Iwai8dd78332009-06-02 01:16:07 +0200198 int err;
Takashi Iwaiaa2936f2009-05-26 16:07:57 +0200199
Wu Fengguang6430aee2009-07-17 16:49:19 +0800200 if (cmd == ~0)
201 return -1;
202
Takashi Iwaiaa2936f2009-05-26 16:07:57 +0200203 if (res)
204 *res = -1;
Takashi Iwai8dd78332009-06-02 01:16:07 +0200205 again:
Takashi Iwaiaa2936f2009-05-26 16:07:57 +0200206 snd_hda_power_up(codec);
207 mutex_lock(&bus->cmd_mutex);
Takashi Iwaiaa2936f2009-05-26 16:07:57 +0200208 err = bus->ops.command(bus, cmd);
Takashi Iwai8dd78332009-06-02 01:16:07 +0200209 if (!err && res)
Wu Fengguangdeadff12009-08-01 18:45:16 +0800210 *res = bus->ops.get_response(bus, codec->addr);
Takashi Iwaiaa2936f2009-05-26 16:07:57 +0200211 mutex_unlock(&bus->cmd_mutex);
212 snd_hda_power_down(codec);
Takashi Iwai8dd78332009-06-02 01:16:07 +0200213 if (res && *res == -1 && bus->rirb_error) {
214 if (bus->response_reset) {
215 snd_printd("hda_codec: resetting BUS due to "
216 "fatal communication error\n");
217 bus->ops.bus_reset(bus);
218 }
219 goto again;
220 }
221 /* clear reset-flag when the communication gets recovered */
222 if (!err)
223 bus->response_reset = 0;
Takashi Iwaiaa2936f2009-05-26 16:07:57 +0200224 return err;
225}
226
Linus Torvalds1da177e2005-04-16 15:20:36 -0700227/**
228 * snd_hda_codec_read - send a command and get the response
229 * @codec: the HDA codec
230 * @nid: NID to send the command
231 * @direct: direct flag
232 * @verb: the verb to send
233 * @parm: the parameter for the verb
234 *
235 * Send a single command and read the corresponding response.
236 *
237 * Returns the obtained response value, or -1 for an error.
238 */
Takashi Iwai0ba21762007-04-16 11:29:14 +0200239unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
240 int direct,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700241 unsigned int verb, unsigned int parm)
242{
Takashi Iwaiaa2936f2009-05-26 16:07:57 +0200243 unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm);
244 unsigned int res;
245 codec_exec_verb(codec, cmd, &res);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700246 return res;
247}
Takashi Iwaiff7a3262008-11-28 15:17:06 +0100248EXPORT_SYMBOL_HDA(snd_hda_codec_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249
250/**
251 * snd_hda_codec_write - send a single command without waiting for response
252 * @codec: the HDA codec
253 * @nid: NID to send the command
254 * @direct: direct flag
255 * @verb: the verb to send
256 * @parm: the parameter for the verb
257 *
258 * Send a single command without waiting for response.
259 *
260 * Returns 0 if successful, or a negative error code.
261 */
262int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
263 unsigned int verb, unsigned int parm)
264{
Takashi Iwaiaa2936f2009-05-26 16:07:57 +0200265 unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm);
Takashi Iwai33fa35e2008-11-06 16:50:40 +0100266 unsigned int res;
Takashi Iwaib20f3b82009-06-02 01:20:22 +0200267 return codec_exec_verb(codec, cmd,
268 codec->bus->sync_write ? &res : NULL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700269}
Takashi Iwaiff7a3262008-11-28 15:17:06 +0100270EXPORT_SYMBOL_HDA(snd_hda_codec_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700271
272/**
273 * snd_hda_sequence_write - sequence writes
274 * @codec: the HDA codec
275 * @seq: VERB array to send
276 *
277 * Send the commands sequentially from the given array.
278 * The array must be terminated with NID=0.
279 */
280void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
281{
282 for (; seq->nid; seq++)
283 snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
284}
Takashi Iwaiff7a3262008-11-28 15:17:06 +0100285EXPORT_SYMBOL_HDA(snd_hda_sequence_write);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700286
287/**
288 * snd_hda_get_sub_nodes - get the range of sub nodes
289 * @codec: the HDA codec
290 * @nid: NID to parse
291 * @start_id: the pointer to store the start NID
292 *
293 * Parse the NID and store the start NID of its sub-nodes.
294 * Returns the number of sub-nodes.
295 */
Takashi Iwai0ba21762007-04-16 11:29:14 +0200296int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
297 hda_nid_t *start_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298{
299 unsigned int parm;
300
301 parm = snd_hda_param_read(codec, nid, AC_PAR_NODE_COUNT);
Danny Tholene8a7f132007-09-11 21:41:56 +0200302 if (parm == -1)
303 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700304 *start_id = (parm >> 16) & 0x7fff;
305 return (int)(parm & 0x7fff);
306}
Takashi Iwaiff7a3262008-11-28 15:17:06 +0100307EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700308
309/**
310 * snd_hda_get_connections - get connection list
311 * @codec: the HDA codec
312 * @nid: NID to parse
313 * @conn_list: connection list array
314 * @max_conns: max. number of connections to store
315 *
316 * Parses the connection list of the given widget and stores the list
317 * of NIDs.
318 *
319 * Returns the number of connections, or a negative error code.
320 */
321int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
322 hda_nid_t *conn_list, int max_conns)
323{
324 unsigned int parm;
Takashi Iwai54d17402005-11-21 16:33:22 +0100325 int i, conn_len, conns;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700326 unsigned int shift, num_elems, mask;
Takashi Iwai1ba7a7c2009-07-27 12:56:26 +0200327 unsigned int wcaps;
Takashi Iwai54d17402005-11-21 16:33:22 +0100328 hda_nid_t prev_nid;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700329
Takashi Iwaida3cec32008-08-08 17:12:14 +0200330 if (snd_BUG_ON(!conn_list || max_conns <= 0))
331 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700332
Takashi Iwai1ba7a7c2009-07-27 12:56:26 +0200333 wcaps = get_wcaps(codec, nid);
334 if (!(wcaps & AC_WCAP_CONN_LIST) &&
335 get_wcaps_type(wcaps) != AC_WID_VOL_KNB) {
Jaroslav Kysela16a433d2009-07-22 16:20:40 +0200336 snd_printk(KERN_WARNING "hda_codec: "
337 "connection list not available for 0x%x\n", nid);
338 return -EINVAL;
339 }
340
Linus Torvalds1da177e2005-04-16 15:20:36 -0700341 parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
342 if (parm & AC_CLIST_LONG) {
343 /* long form */
344 shift = 16;
345 num_elems = 2;
346 } else {
347 /* short form */
348 shift = 8;
349 num_elems = 4;
350 }
351 conn_len = parm & AC_CLIST_LENGTH;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700352 mask = (1 << (shift-1)) - 1;
353
Takashi Iwai0ba21762007-04-16 11:29:14 +0200354 if (!conn_len)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700355 return 0; /* no connection */
356
357 if (conn_len == 1) {
358 /* single connection */
Takashi Iwai0ba21762007-04-16 11:29:14 +0200359 parm = snd_hda_codec_read(codec, nid, 0,
360 AC_VERB_GET_CONNECT_LIST, 0);
Takashi Iwai3c6aae42009-07-10 12:52:27 +0200361 if (parm == -1 && codec->bus->rirb_error)
362 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700363 conn_list[0] = parm & mask;
364 return 1;
365 }
366
367 /* multi connection */
368 conns = 0;
Takashi Iwai54d17402005-11-21 16:33:22 +0100369 prev_nid = 0;
370 for (i = 0; i < conn_len; i++) {
371 int range_val;
372 hda_nid_t val, n;
373
Takashi Iwai3c6aae42009-07-10 12:52:27 +0200374 if (i % num_elems == 0) {
Takashi Iwai54d17402005-11-21 16:33:22 +0100375 parm = snd_hda_codec_read(codec, nid, 0,
376 AC_VERB_GET_CONNECT_LIST, i);
Takashi Iwai3c6aae42009-07-10 12:52:27 +0200377 if (parm == -1 && codec->bus->rirb_error)
378 return -EIO;
379 }
Takashi Iwai0ba21762007-04-16 11:29:14 +0200380 range_val = !!(parm & (1 << (shift-1))); /* ranges */
Takashi Iwai54d17402005-11-21 16:33:22 +0100381 val = parm & mask;
Jaroslav Kysela2e9bf242009-07-18 11:48:19 +0200382 if (val == 0) {
383 snd_printk(KERN_WARNING "hda_codec: "
384 "invalid CONNECT_LIST verb %x[%i]:%x\n",
385 nid, i, parm);
386 return 0;
387 }
Takashi Iwai54d17402005-11-21 16:33:22 +0100388 parm >>= shift;
389 if (range_val) {
390 /* ranges between the previous and this one */
Takashi Iwai0ba21762007-04-16 11:29:14 +0200391 if (!prev_nid || prev_nid >= val) {
392 snd_printk(KERN_WARNING "hda_codec: "
393 "invalid dep_range_val %x:%x\n",
394 prev_nid, val);
Takashi Iwai54d17402005-11-21 16:33:22 +0100395 continue;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700396 }
Takashi Iwai54d17402005-11-21 16:33:22 +0100397 for (n = prev_nid + 1; n <= val; n++) {
398 if (conns >= max_conns) {
Takashi Iwai0ba21762007-04-16 11:29:14 +0200399 snd_printk(KERN_ERR
400 "Too many connections\n");
Takashi Iwai54d17402005-11-21 16:33:22 +0100401 return -EINVAL;
402 }
403 conn_list[conns++] = n;
404 }
405 } else {
406 if (conns >= max_conns) {
407 snd_printk(KERN_ERR "Too many connections\n");
408 return -EINVAL;
409 }
410 conn_list[conns++] = val;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700411 }
Takashi Iwai54d17402005-11-21 16:33:22 +0100412 prev_nid = val;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700413 }
414 return conns;
415}
Takashi Iwaiff7a3262008-11-28 15:17:06 +0100416EXPORT_SYMBOL_HDA(snd_hda_get_connections);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700417
418
419/**
420 * snd_hda_queue_unsol_event - add an unsolicited event to queue
421 * @bus: the BUS
422 * @res: unsolicited event (lower 32bit of RIRB entry)
423 * @res_ex: codec addr and flags (upper 32bit or RIRB entry)
424 *
425 * Adds the given event to the queue. The events are processed in
426 * the workqueue asynchronously. Call this function in the interrupt
427 * hanlder when RIRB receives an unsolicited event.
428 *
429 * Returns 0 if successful, or a negative error code.
430 */
431int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
432{
433 struct hda_bus_unsolicited *unsol;
434 unsigned int wp;
435
Takashi Iwai0ba21762007-04-16 11:29:14 +0200436 unsol = bus->unsol;
437 if (!unsol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700438 return 0;
439
440 wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE;
441 unsol->wp = wp;
442
443 wp <<= 1;
444 unsol->queue[wp] = res;
445 unsol->queue[wp + 1] = res_ex;
446
Takashi Iwai6acaed32009-01-12 10:09:24 +0100447 queue_work(bus->workq, &unsol->work);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700448
449 return 0;
450}
Takashi Iwaiff7a3262008-11-28 15:17:06 +0100451EXPORT_SYMBOL_HDA(snd_hda_queue_unsol_event);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700452
453/*
Wu Fengguang5c1d1a92008-10-07 14:17:53 +0800454 * process queued unsolicited events
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 */
David Howellsc4028952006-11-22 14:57:56 +0000456static void process_unsol_events(struct work_struct *work)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700457{
David Howellsc4028952006-11-22 14:57:56 +0000458 struct hda_bus_unsolicited *unsol =
459 container_of(work, struct hda_bus_unsolicited, work);
460 struct hda_bus *bus = unsol->bus;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700461 struct hda_codec *codec;
462 unsigned int rp, caddr, res;
463
464 while (unsol->rp != unsol->wp) {
465 rp = (unsol->rp + 1) % HDA_UNSOL_QUEUE_SIZE;
466 unsol->rp = rp;
467 rp <<= 1;
468 res = unsol->queue[rp];
469 caddr = unsol->queue[rp + 1];
Takashi Iwai0ba21762007-04-16 11:29:14 +0200470 if (!(caddr & (1 << 4))) /* no unsolicited event? */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700471 continue;
472 codec = bus->caddr_tbl[caddr & 0x0f];
473 if (codec && codec->patch_ops.unsol_event)
474 codec->patch_ops.unsol_event(codec, res);
475 }
476}
477
478/*
479 * initialize unsolicited queue
480 */
Takashi Iwai6c1f45e2008-07-30 15:01:45 +0200481static int init_unsol_queue(struct hda_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700482{
483 struct hda_bus_unsolicited *unsol;
484
Takashi Iwai9f146bb2005-11-17 11:07:49 +0100485 if (bus->unsol) /* already initialized */
486 return 0;
487
Takashi Iwaie560d8d2005-09-09 14:21:46 +0200488 unsol = kzalloc(sizeof(*unsol), GFP_KERNEL);
Takashi Iwai0ba21762007-04-16 11:29:14 +0200489 if (!unsol) {
490 snd_printk(KERN_ERR "hda_codec: "
491 "can't allocate unsolicited queue\n");
Linus Torvalds1da177e2005-04-16 15:20:36 -0700492 return -ENOMEM;
493 }
David Howellsc4028952006-11-22 14:57:56 +0000494 INIT_WORK(&unsol->work, process_unsol_events);
495 unsol->bus = bus;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700496 bus->unsol = unsol;
497 return 0;
498}
499
500/*
501 * destructor
502 */
503static void snd_hda_codec_free(struct hda_codec *codec);
504
505static int snd_hda_bus_free(struct hda_bus *bus)
506{
Takashi Iwai0ba21762007-04-16 11:29:14 +0200507 struct hda_codec *codec, *n;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700508
Takashi Iwai0ba21762007-04-16 11:29:14 +0200509 if (!bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700510 return 0;
Takashi Iwai6acaed32009-01-12 10:09:24 +0100511 if (bus->workq)
512 flush_workqueue(bus->workq);
513 if (bus->unsol)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700514 kfree(bus->unsol);
Takashi Iwai0ba21762007-04-16 11:29:14 +0200515 list_for_each_entry_safe(codec, n, &bus->codec_list, list) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516 snd_hda_codec_free(codec);
517 }
518 if (bus->ops.private_free)
519 bus->ops.private_free(bus);
Takashi Iwai6acaed32009-01-12 10:09:24 +0100520 if (bus->workq)
521 destroy_workqueue(bus->workq);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522 kfree(bus);
523 return 0;
524}
525
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100526static int snd_hda_bus_dev_free(struct snd_device *device)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700527{
528 struct hda_bus *bus = device->device_data;
Takashi Iwaib94d35392008-11-21 09:08:06 +0100529 bus->shutdown = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700530 return snd_hda_bus_free(bus);
531}
532
Takashi Iwaid7ffba12008-07-30 15:01:46 +0200533#ifdef CONFIG_SND_HDA_HWDEP
534static int snd_hda_bus_dev_register(struct snd_device *device)
535{
536 struct hda_bus *bus = device->device_data;
537 struct hda_codec *codec;
538 list_for_each_entry(codec, &bus->codec_list, list) {
539 snd_hda_hwdep_add_sysfs(codec);
Takashi Iwaia2f63092009-11-11 09:34:25 +0100540 snd_hda_hwdep_add_power_sysfs(codec);
Takashi Iwaid7ffba12008-07-30 15:01:46 +0200541 }
542 return 0;
543}
544#else
545#define snd_hda_bus_dev_register NULL
546#endif
547
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548/**
549 * snd_hda_bus_new - create a HDA bus
550 * @card: the card entry
551 * @temp: the template for hda_bus information
552 * @busp: the pointer to store the created bus instance
553 *
554 * Returns 0 if successful, or a negative error code.
555 */
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100556int /*__devinit*/ snd_hda_bus_new(struct snd_card *card,
Takashi Iwai756e2b02007-04-16 11:27:07 +0200557 const struct hda_bus_template *temp,
558 struct hda_bus **busp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700559{
560 struct hda_bus *bus;
561 int err;
Takashi Iwaic8b6bf92005-11-17 14:57:47 +0100562 static struct snd_device_ops dev_ops = {
Takashi Iwaid7ffba12008-07-30 15:01:46 +0200563 .dev_register = snd_hda_bus_dev_register,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700564 .dev_free = snd_hda_bus_dev_free,
565 };
566
Takashi Iwaida3cec32008-08-08 17:12:14 +0200567 if (snd_BUG_ON(!temp))
568 return -EINVAL;
569 if (snd_BUG_ON(!temp->ops.command || !temp->ops.get_response))
570 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700571
572 if (busp)
573 *busp = NULL;
574
Takashi Iwaie560d8d2005-09-09 14:21:46 +0200575 bus = kzalloc(sizeof(*bus), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 if (bus == NULL) {
577 snd_printk(KERN_ERR "can't allocate struct hda_bus\n");
578 return -ENOMEM;
579 }
580
581 bus->card = card;
582 bus->private_data = temp->private_data;
583 bus->pci = temp->pci;
584 bus->modelname = temp->modelname;
Takashi Iwaifee2fba2008-11-27 12:43:28 +0100585 bus->power_save = temp->power_save;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700586 bus->ops = temp->ops;
587
Ingo Molnar62932df2006-01-16 16:34:20 +0100588 mutex_init(&bus->cmd_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700589 INIT_LIST_HEAD(&bus->codec_list);
590
Takashi Iwaie8c0ee52009-02-05 07:34:28 +0100591 snprintf(bus->workq_name, sizeof(bus->workq_name),
592 "hd-audio%d", card->number);
593 bus->workq = create_singlethread_workqueue(bus->workq_name);
Takashi Iwai6acaed32009-01-12 10:09:24 +0100594 if (!bus->workq) {
Takashi Iwaie8c0ee52009-02-05 07:34:28 +0100595 snd_printk(KERN_ERR "cannot create workqueue %s\n",
596 bus->workq_name);
Takashi Iwai6acaed32009-01-12 10:09:24 +0100597 kfree(bus);
598 return -ENOMEM;
599 }
600
Takashi Iwai0ba21762007-04-16 11:29:14 +0200601 err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
602 if (err < 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 snd_hda_bus_free(bus);
604 return err;
605 }
606 if (busp)
607 *busp = bus;
608 return 0;
609}
Takashi Iwaiff7a3262008-11-28 15:17:06 +0100610EXPORT_SYMBOL_HDA(snd_hda_bus_new);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700611
Takashi Iwai82467612007-07-27 19:15:54 +0200612#ifdef CONFIG_SND_HDA_GENERIC
613#define is_generic_config(codec) \
Takashi Iwaif44ac832008-07-30 15:01:45 +0200614 (codec->modelname && !strcmp(codec->modelname, "generic"))
Takashi Iwai82467612007-07-27 19:15:54 +0200615#else
616#define is_generic_config(codec) 0
617#endif
618
Takashi Iwai645f10c2008-11-28 15:07:37 +0100619#ifdef MODULE
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100620#define HDA_MODREQ_MAX_COUNT 2 /* two request_modules()'s */
621#else
Takashi Iwai645f10c2008-11-28 15:07:37 +0100622#define HDA_MODREQ_MAX_COUNT 0 /* all presets are statically linked */
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100623#endif
624
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625/*
626 * find a matching codec preset
627 */
Takashi Iwai6c1f45e2008-07-30 15:01:45 +0200628static const struct hda_codec_preset *
Takashi Iwai756e2b02007-04-16 11:27:07 +0200629find_codec_preset(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700630{
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100631 struct hda_codec_preset_list *tbl;
632 const struct hda_codec_preset *preset;
633 int mod_requested = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700634
Takashi Iwai82467612007-07-27 19:15:54 +0200635 if (is_generic_config(codec))
Takashi Iwaid5ad6302007-03-07 15:55:59 +0100636 return NULL; /* use the generic parser */
637
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100638 again:
639 mutex_lock(&preset_mutex);
640 list_for_each_entry(tbl, &hda_preset_tables, list) {
641 if (!try_module_get(tbl->owner)) {
642 snd_printk(KERN_ERR "hda_codec: cannot module_get\n");
643 continue;
644 }
645 for (preset = tbl->preset; preset->id; preset++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700646 u32 mask = preset->mask;
Marc Boucherca7cfae2008-01-22 15:32:25 +0100647 if (preset->afg && preset->afg != codec->afg)
648 continue;
649 if (preset->mfg && preset->mfg != codec->mfg)
650 continue;
Takashi Iwai0ba21762007-04-16 11:29:14 +0200651 if (!mask)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700652 mask = ~0;
Takashi Iwai9c7f8522006-06-28 15:08:22 +0200653 if (preset->id == (codec->vendor_id & mask) &&
Takashi Iwai0ba21762007-04-16 11:29:14 +0200654 (!preset->rev ||
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100655 preset->rev == codec->revision_id)) {
656 mutex_unlock(&preset_mutex);
657 codec->owner = tbl->owner;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700658 return preset;
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100659 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700660 }
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100661 module_put(tbl->owner);
662 }
663 mutex_unlock(&preset_mutex);
664
665 if (mod_requested < HDA_MODREQ_MAX_COUNT) {
666 char name[32];
667 if (!mod_requested)
668 snprintf(name, sizeof(name), "snd-hda-codec-id:%08x",
669 codec->vendor_id);
670 else
671 snprintf(name, sizeof(name), "snd-hda-codec-id:%04x*",
672 (codec->vendor_id >> 16) & 0xffff);
673 request_module(name);
674 mod_requested++;
675 goto again;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700676 }
677 return NULL;
678}
679
680/*
Takashi Iwaif44ac832008-07-30 15:01:45 +0200681 * get_codec_name - store the codec name
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 */
Takashi Iwaif44ac832008-07-30 15:01:45 +0200683static int get_codec_name(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700684{
685 const struct hda_vendor_id *c;
686 const char *vendor = NULL;
687 u16 vendor_id = codec->vendor_id >> 16;
Takashi Iwai812a2cc2009-05-16 10:00:49 +0200688 char tmp[16];
689
690 if (codec->vendor_name)
691 goto get_chip_name;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700692
693 for (c = hda_vendor_ids; c->id; c++) {
694 if (c->id == vendor_id) {
695 vendor = c->name;
696 break;
697 }
698 }
Takashi Iwai0ba21762007-04-16 11:29:14 +0200699 if (!vendor) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700700 sprintf(tmp, "Generic %04x", vendor_id);
701 vendor = tmp;
702 }
Takashi Iwai812a2cc2009-05-16 10:00:49 +0200703 codec->vendor_name = kstrdup(vendor, GFP_KERNEL);
704 if (!codec->vendor_name)
705 return -ENOMEM;
706
707 get_chip_name:
708 if (codec->chip_name)
709 return 0;
710
Linus Torvalds1da177e2005-04-16 15:20:36 -0700711 if (codec->preset && codec->preset->name)
Takashi Iwai812a2cc2009-05-16 10:00:49 +0200712 codec->chip_name = kstrdup(codec->preset->name, GFP_KERNEL);
713 else {
714 sprintf(tmp, "ID %x", codec->vendor_id & 0xffff);
715 codec->chip_name = kstrdup(tmp, GFP_KERNEL);
716 }
717 if (!codec->chip_name)
Takashi Iwaif44ac832008-07-30 15:01:45 +0200718 return -ENOMEM;
719 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700720}
721
722/*
Sasha Khapyorsky673b6832005-08-11 11:00:16 +0200723 * look for an AFG and MFG nodes
Linus Torvalds1da177e2005-04-16 15:20:36 -0700724 */
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100725static void /*__devinit*/ setup_fg_nodes(struct hda_codec *codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700726{
Takashi Iwai93e82ae2009-04-17 18:04:41 +0200727 int i, total_nodes, function_id;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728 hda_nid_t nid;
729
730 total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
731 for (i = 0; i < total_nodes; i++, nid++) {
Takashi Iwai93e82ae2009-04-17 18:04:41 +0200732 function_id = snd_hda_param_read(codec, nid,
Pascal de Bruijn234b4342009-03-23 11:15:59 +0100733 AC_PAR_FUNCTION_TYPE) & 0xff;
Takashi Iwai93e82ae2009-04-17 18:04:41 +0200734 switch (function_id) {
Sasha Khapyorsky673b6832005-08-11 11:00:16 +0200735 case AC_GRP_AUDIO_FUNCTION:
736 codec->afg = nid;
Takashi Iwai93e82ae2009-04-17 18:04:41 +0200737 codec->function_id = function_id;
Sasha Khapyorsky673b6832005-08-11 11:00:16 +0200738 break;
739 case AC_GRP_MODEM_FUNCTION:
740 codec->mfg = nid;
Takashi Iwai93e82ae2009-04-17 18:04:41 +0200741 codec->function_id = function_id;
Sasha Khapyorsky673b6832005-08-11 11:00:16 +0200742 break;
743 default:
744 break;
745 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700746 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747}
748
749/*
Takashi Iwai54d17402005-11-21 16:33:22 +0100750 * read widget caps for each widget and store in cache
751 */
752static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
753{
754 int i;
755 hda_nid_t nid;
756
757 codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node,
758 &codec->start_nid);
759 codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL);
Takashi Iwai0ba21762007-04-16 11:29:14 +0200760 if (!codec->wcaps)
Takashi Iwai54d17402005-11-21 16:33:22 +0100761 return -ENOMEM;
762 nid = codec->start_nid;
763 for (i = 0; i < codec->num_nodes; i++, nid++)
764 codec->wcaps[i] = snd_hda_param_read(codec, nid,
765 AC_PAR_AUDIO_WIDGET_CAP);
766 return 0;
767}
768
Takashi Iwai3be14142009-02-20 14:11:16 +0100769/* read all pin default configurations and save codec->init_pins */
770static int read_pin_defaults(struct hda_codec *codec)
771{
772 int i;
773 hda_nid_t nid = codec->start_nid;
774
775 for (i = 0; i < codec->num_nodes; i++, nid++) {
776 struct hda_pincfg *pin;
777 unsigned int wcaps = get_wcaps(codec, nid);
Takashi Iwaia22d5432009-07-27 12:54:26 +0200778 unsigned int wid_type = get_wcaps_type(wcaps);
Takashi Iwai3be14142009-02-20 14:11:16 +0100779 if (wid_type != AC_WID_PIN)
780 continue;
781 pin = snd_array_new(&codec->init_pins);
782 if (!pin)
783 return -ENOMEM;
784 pin->nid = nid;
785 pin->cfg = snd_hda_codec_read(codec, nid, 0,
786 AC_VERB_GET_CONFIG_DEFAULT, 0);
787 }
788 return 0;
789}
790
791/* look up the given pin config list and return the item matching with NID */
792static struct hda_pincfg *look_up_pincfg(struct hda_codec *codec,
793 struct snd_array *array,
794 hda_nid_t nid)
795{
796 int i;
797 for (i = 0; i < array->used; i++) {
798 struct hda_pincfg *pin = snd_array_elem(array, i);
799 if (pin->nid == nid)
800 return pin;
801 }
802 return NULL;
803}
804
805/* write a config value for the given NID */
806static void set_pincfg(struct hda_codec *codec, hda_nid_t nid,
807 unsigned int cfg)
808{
809 int i;
810 for (i = 0; i < 4; i++) {
811 snd_hda_codec_write(codec, nid, 0,
812 AC_VERB_SET_CONFIG_DEFAULT_BYTES_0 + i,
813 cfg & 0xff);
814 cfg >>= 8;
815 }
816}
817
818/* set the current pin config value for the given NID.
819 * the value is cached, and read via snd_hda_codec_get_pincfg()
820 */
821int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
822 hda_nid_t nid, unsigned int cfg)
823{
824 struct hda_pincfg *pin;
Takashi Iwai5e7b8e02009-02-23 09:45:59 +0100825 unsigned int oldcfg;
Takashi Iwai3be14142009-02-20 14:11:16 +0100826
Takashi Iwai5e7b8e02009-02-23 09:45:59 +0100827 oldcfg = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwai3be14142009-02-20 14:11:16 +0100828 pin = look_up_pincfg(codec, list, nid);
829 if (!pin) {
830 pin = snd_array_new(list);
831 if (!pin)
832 return -ENOMEM;
833 pin->nid = nid;
834 }
835 pin->cfg = cfg;
Takashi Iwai5e7b8e02009-02-23 09:45:59 +0100836
837 /* change only when needed; e.g. if the pincfg is already present
838 * in user_pins[], don't write it
839 */
840 cfg = snd_hda_codec_get_pincfg(codec, nid);
841 if (oldcfg != cfg)
842 set_pincfg(codec, nid, cfg);
Takashi Iwai3be14142009-02-20 14:11:16 +0100843 return 0;
844}
845
Takashi Iwaid5191e52009-11-16 14:58:17 +0100846/**
847 * snd_hda_codec_set_pincfg - Override a pin default configuration
848 * @codec: the HDA codec
849 * @nid: NID to set the pin config
850 * @cfg: the pin default config value
851 *
852 * Override a pin default configuration value in the cache.
853 * This value can be read by snd_hda_codec_get_pincfg() in a higher
854 * priority than the real hardware value.
855 */
Takashi Iwai3be14142009-02-20 14:11:16 +0100856int snd_hda_codec_set_pincfg(struct hda_codec *codec,
857 hda_nid_t nid, unsigned int cfg)
858{
Takashi Iwai346ff702009-02-23 09:42:57 +0100859 return snd_hda_add_pincfg(codec, &codec->driver_pins, nid, cfg);
Takashi Iwai3be14142009-02-20 14:11:16 +0100860}
861EXPORT_SYMBOL_HDA(snd_hda_codec_set_pincfg);
862
Takashi Iwaid5191e52009-11-16 14:58:17 +0100863/**
864 * snd_hda_codec_get_pincfg - Obtain a pin-default configuration
865 * @codec: the HDA codec
866 * @nid: NID to get the pin config
867 *
868 * Get the current pin config value of the given pin NID.
869 * If the pincfg value is cached or overridden via sysfs or driver,
870 * returns the cached value.
871 */
Takashi Iwai3be14142009-02-20 14:11:16 +0100872unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid)
873{
874 struct hda_pincfg *pin;
875
Takashi Iwai3be14142009-02-20 14:11:16 +0100876#ifdef CONFIG_SND_HDA_HWDEP
Takashi Iwai346ff702009-02-23 09:42:57 +0100877 pin = look_up_pincfg(codec, &codec->user_pins, nid);
Takashi Iwai3be14142009-02-20 14:11:16 +0100878 if (pin)
879 return pin->cfg;
880#endif
Takashi Iwai5e7b8e02009-02-23 09:45:59 +0100881 pin = look_up_pincfg(codec, &codec->driver_pins, nid);
882 if (pin)
883 return pin->cfg;
Takashi Iwai3be14142009-02-20 14:11:16 +0100884 pin = look_up_pincfg(codec, &codec->init_pins, nid);
885 if (pin)
886 return pin->cfg;
887 return 0;
888}
889EXPORT_SYMBOL_HDA(snd_hda_codec_get_pincfg);
890
891/* restore all current pin configs */
892static void restore_pincfgs(struct hda_codec *codec)
893{
894 int i;
895 for (i = 0; i < codec->init_pins.used; i++) {
896 struct hda_pincfg *pin = snd_array_elem(&codec->init_pins, i);
897 set_pincfg(codec, pin->nid,
898 snd_hda_codec_get_pincfg(codec, pin->nid));
899 }
900}
Takashi Iwai54d17402005-11-21 16:33:22 +0100901
Takashi Iwai01751f52007-08-10 16:59:39 +0200902static void init_hda_cache(struct hda_cache_rec *cache,
903 unsigned int record_size);
Takashi Iwai1fcaee62007-08-23 00:01:09 +0200904static void free_hda_cache(struct hda_cache_rec *cache);
Takashi Iwai01751f52007-08-10 16:59:39 +0200905
Takashi Iwai3be14142009-02-20 14:11:16 +0100906/* restore the initial pin cfgs and release all pincfg lists */
907static void restore_init_pincfgs(struct hda_codec *codec)
908{
Takashi Iwai346ff702009-02-23 09:42:57 +0100909 /* first free driver_pins and user_pins, then call restore_pincfg
Takashi Iwai3be14142009-02-20 14:11:16 +0100910 * so that only the values in init_pins are restored
911 */
Takashi Iwai346ff702009-02-23 09:42:57 +0100912 snd_array_free(&codec->driver_pins);
Takashi Iwai3be14142009-02-20 14:11:16 +0100913#ifdef CONFIG_SND_HDA_HWDEP
Takashi Iwai346ff702009-02-23 09:42:57 +0100914 snd_array_free(&codec->user_pins);
Takashi Iwai3be14142009-02-20 14:11:16 +0100915#endif
916 restore_pincfgs(codec);
917 snd_array_free(&codec->init_pins);
918}
919
Takashi Iwai54d17402005-11-21 16:33:22 +0100920/*
Linus Torvalds1da177e2005-04-16 15:20:36 -0700921 * codec destructor
922 */
923static void snd_hda_codec_free(struct hda_codec *codec)
924{
Takashi Iwai0ba21762007-04-16 11:29:14 +0200925 if (!codec)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700926 return;
Takashi Iwai3be14142009-02-20 14:11:16 +0100927 restore_init_pincfgs(codec);
Takashi Iwaicb53c622007-08-10 17:21:45 +0200928#ifdef CONFIG_SND_HDA_POWER_SAVE
929 cancel_delayed_work(&codec->power_work);
Takashi Iwai6acaed32009-01-12 10:09:24 +0100930 flush_workqueue(codec->bus->workq);
Takashi Iwaicb53c622007-08-10 17:21:45 +0200931#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 list_del(&codec->list);
Takashi Iwaid13bd412008-07-30 15:01:45 +0200933 snd_array_free(&codec->mixers);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700934 codec->bus->caddr_tbl[codec->addr] = NULL;
935 if (codec->patch_ops.free)
936 codec->patch_ops.free(codec);
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100937 module_put(codec->owner);
Takashi Iwai01751f52007-08-10 16:59:39 +0200938 free_hda_cache(&codec->amp_cache);
Takashi Iwaib3ac5632007-08-10 17:03:40 +0200939 free_hda_cache(&codec->cmd_cache);
Takashi Iwai812a2cc2009-05-16 10:00:49 +0200940 kfree(codec->vendor_name);
941 kfree(codec->chip_name);
Takashi Iwaif44ac832008-07-30 15:01:45 +0200942 kfree(codec->modelname);
Takashi Iwai54d17402005-11-21 16:33:22 +0100943 kfree(codec->wcaps);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700944 kfree(codec);
945}
946
Takashi Iwaibb6ac722009-03-13 09:02:42 +0100947static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
948 unsigned int power_state);
949
Linus Torvalds1da177e2005-04-16 15:20:36 -0700950/**
951 * snd_hda_codec_new - create a HDA codec
952 * @bus: the bus to assign
953 * @codec_addr: the codec address
954 * @codecp: the pointer to store the generated codec
955 *
956 * Returns 0 if successful, or a negative error code.
957 */
Takashi Iwai1289e9e2008-11-27 15:47:11 +0100958int /*__devinit*/ snd_hda_codec_new(struct hda_bus *bus, unsigned int codec_addr,
Takashi Iwaia1e21c92009-06-17 09:33:52 +0200959 struct hda_codec **codecp)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960{
961 struct hda_codec *codec;
Jaroslav Kyselaba443682008-08-13 20:55:32 +0200962 char component[31];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700963 int err;
964
Takashi Iwaida3cec32008-08-08 17:12:14 +0200965 if (snd_BUG_ON(!bus))
966 return -EINVAL;
967 if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
968 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700969
970 if (bus->caddr_tbl[codec_addr]) {
Takashi Iwai0ba21762007-04-16 11:29:14 +0200971 snd_printk(KERN_ERR "hda_codec: "
972 "address 0x%x is already occupied\n", codec_addr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700973 return -EBUSY;
974 }
975
Takashi Iwaie560d8d2005-09-09 14:21:46 +0200976 codec = kzalloc(sizeof(*codec), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700977 if (codec == NULL) {
978 snd_printk(KERN_ERR "can't allocate struct hda_codec\n");
979 return -ENOMEM;
980 }
981
982 codec->bus = bus;
983 codec->addr = codec_addr;
Ingo Molnar62932df2006-01-16 16:34:20 +0100984 mutex_init(&codec->spdif_mutex);
Wu Fengguang5a9e02e2009-01-09 16:45:24 +0800985 mutex_init(&codec->control_mutex);
Takashi Iwai01751f52007-08-10 16:59:39 +0200986 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
Takashi Iwaib3ac5632007-08-10 17:03:40 +0200987 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +0100988 snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 60);
Takashi Iwai3be14142009-02-20 14:11:16 +0100989 snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
Takashi Iwai346ff702009-02-23 09:42:57 +0100990 snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +0200991 if (codec->bus->modelname) {
992 codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
993 if (!codec->modelname) {
994 snd_hda_codec_free(codec);
995 return -ENODEV;
996 }
997 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700998
Takashi Iwaicb53c622007-08-10 17:21:45 +0200999#ifdef CONFIG_SND_HDA_POWER_SAVE
1000 INIT_DELAYED_WORK(&codec->power_work, hda_power_work);
1001 /* snd_hda_codec_new() marks the codec as power-up, and leave it as is.
1002 * the caller has to power down appropriatley after initialization
1003 * phase.
1004 */
1005 hda_keep_power_on(codec);
1006#endif
1007
Linus Torvalds1da177e2005-04-16 15:20:36 -07001008 list_add_tail(&codec->list, &bus->codec_list);
1009 bus->caddr_tbl[codec_addr] = codec;
1010
Takashi Iwai0ba21762007-04-16 11:29:14 +02001011 codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
1012 AC_PAR_VENDOR_ID);
Takashi Iwai111d3af2006-02-16 18:17:58 +01001013 if (codec->vendor_id == -1)
1014 /* read again, hopefully the access method was corrected
1015 * in the last read...
1016 */
1017 codec->vendor_id = snd_hda_param_read(codec, AC_NODE_ROOT,
1018 AC_PAR_VENDOR_ID);
Takashi Iwai0ba21762007-04-16 11:29:14 +02001019 codec->subsystem_id = snd_hda_param_read(codec, AC_NODE_ROOT,
1020 AC_PAR_SUBSYSTEM_ID);
1021 codec->revision_id = snd_hda_param_read(codec, AC_NODE_ROOT,
1022 AC_PAR_REV_ID);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001023
Sasha Khapyorsky673b6832005-08-11 11:00:16 +02001024 setup_fg_nodes(codec);
Takashi Iwai0ba21762007-04-16 11:29:14 +02001025 if (!codec->afg && !codec->mfg) {
Sasha Khapyorsky673b6832005-08-11 11:00:16 +02001026 snd_printdd("hda_codec: no AFG or MFG node found\n");
Takashi Iwai3be14142009-02-20 14:11:16 +01001027 err = -ENODEV;
1028 goto error;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001029 }
1030
Takashi Iwai3be14142009-02-20 14:11:16 +01001031 err = read_widget_caps(codec, codec->afg ? codec->afg : codec->mfg);
1032 if (err < 0) {
Takashi Iwai54d17402005-11-21 16:33:22 +01001033 snd_printk(KERN_ERR "hda_codec: cannot malloc\n");
Takashi Iwai3be14142009-02-20 14:11:16 +01001034 goto error;
Takashi Iwai54d17402005-11-21 16:33:22 +01001035 }
Takashi Iwai3be14142009-02-20 14:11:16 +01001036 err = read_pin_defaults(codec);
1037 if (err < 0)
1038 goto error;
Takashi Iwai54d17402005-11-21 16:33:22 +01001039
Takashi Iwai0ba21762007-04-16 11:29:14 +02001040 if (!codec->subsystem_id) {
Takashi Iwai86284e42005-10-11 15:05:54 +02001041 hda_nid_t nid = codec->afg ? codec->afg : codec->mfg;
Takashi Iwai0ba21762007-04-16 11:29:14 +02001042 codec->subsystem_id =
1043 snd_hda_codec_read(codec, nid, 0,
1044 AC_VERB_GET_SUBSYSTEM_ID, 0);
Takashi Iwai86284e42005-10-11 15:05:54 +02001045 }
1046
Takashi Iwaibb6ac722009-03-13 09:02:42 +01001047 /* power-up all before initialization */
1048 hda_set_power_state(codec,
1049 codec->afg ? codec->afg : codec->mfg,
1050 AC_PWRST_D0);
1051
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001052 snd_hda_codec_proc_new(codec);
1053
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001054 snd_hda_create_hwdep(codec);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001055
1056 sprintf(component, "HDA:%08x,%08x,%08x", codec->vendor_id,
1057 codec->subsystem_id, codec->revision_id);
1058 snd_component_add(codec->bus->card, component);
1059
1060 if (codecp)
1061 *codecp = codec;
1062 return 0;
Takashi Iwai3be14142009-02-20 14:11:16 +01001063
1064 error:
1065 snd_hda_codec_free(codec);
1066 return err;
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001067}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001068EXPORT_SYMBOL_HDA(snd_hda_codec_new);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001069
Takashi Iwaid5191e52009-11-16 14:58:17 +01001070/**
1071 * snd_hda_codec_configure - (Re-)configure the HD-audio codec
1072 * @codec: the HDA codec
1073 *
1074 * Start parsing of the given codec tree and (re-)initialize the whole
1075 * patch instance.
1076 *
1077 * Returns 0 if successful or a negative error code.
1078 */
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001079int snd_hda_codec_configure(struct hda_codec *codec)
1080{
1081 int err;
1082
Takashi Iwaid5ad6302007-03-07 15:55:59 +01001083 codec->preset = find_codec_preset(codec);
Takashi Iwai812a2cc2009-05-16 10:00:49 +02001084 if (!codec->vendor_name || !codec->chip_name) {
Takashi Iwaif44ac832008-07-30 15:01:45 +02001085 err = get_codec_name(codec);
1086 if (err < 0)
1087 return err;
1088 }
Takashi Iwai43ea1d42007-04-26 19:12:08 +02001089 /* audio codec should override the mixer name */
Takashi Iwaif44ac832008-07-30 15:01:45 +02001090 if (codec->afg || !*codec->bus->card->mixername)
Takashi Iwai812a2cc2009-05-16 10:00:49 +02001091 snprintf(codec->bus->card->mixername,
1092 sizeof(codec->bus->card->mixername),
1093 "%s %s", codec->vendor_name, codec->chip_name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001094
Takashi Iwai82467612007-07-27 19:15:54 +02001095 if (is_generic_config(codec)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001096 err = snd_hda_parse_generic_codec(codec);
Takashi Iwai82467612007-07-27 19:15:54 +02001097 goto patched;
1098 }
Takashi Iwai82467612007-07-27 19:15:54 +02001099 if (codec->preset && codec->preset->patch) {
1100 err = codec->preset->patch(codec);
1101 goto patched;
1102 }
1103
1104 /* call the default parser */
Takashi Iwai82467612007-07-27 19:15:54 +02001105 err = snd_hda_parse_generic_codec(codec);
Takashi Iwai35a1e0c2007-10-19 08:13:40 +02001106 if (err < 0)
1107 printk(KERN_ERR "hda-codec: No codec parser is available\n");
Takashi Iwai82467612007-07-27 19:15:54 +02001108
1109 patched:
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001110 if (!err && codec->patch_ops.unsol_event)
1111 err = init_unsol_queue(codec->bus);
1112 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001113}
Takashi Iwaia1e21c92009-06-17 09:33:52 +02001114EXPORT_SYMBOL_HDA(snd_hda_codec_configure);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001115
1116/**
1117 * snd_hda_codec_setup_stream - set up the codec for streaming
1118 * @codec: the CODEC to set up
1119 * @nid: the NID to set up
1120 * @stream_tag: stream tag to pass, it's between 0x1 and 0xf.
1121 * @channel_id: channel id to pass, zero based.
1122 * @format: stream format.
1123 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001124void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1125 u32 stream_tag,
Linus Torvalds1da177e2005-04-16 15:20:36 -07001126 int channel_id, int format)
1127{
Takashi Iwai0ba21762007-04-16 11:29:14 +02001128 if (!nid)
Takashi Iwaid21b37e2005-04-20 13:45:55 +02001129 return;
1130
Takashi Iwai0ba21762007-04-16 11:29:14 +02001131 snd_printdd("hda_codec_setup_stream: "
1132 "NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001133 nid, stream_tag, channel_id, format);
1134 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID,
1135 (stream_tag << 4) | channel_id);
1136 msleep(1);
1137 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, format);
1138}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001139EXPORT_SYMBOL_HDA(snd_hda_codec_setup_stream);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001140
Takashi Iwaid5191e52009-11-16 14:58:17 +01001141/**
1142 * snd_hda_codec_cleanup_stream - clean up the codec for closing
1143 * @codec: the CODEC to clean up
1144 * @nid: the NID to clean up
1145 */
Takashi Iwai888afa12008-03-18 09:57:50 +01001146void snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid)
1147{
1148 if (!nid)
1149 return;
1150
1151 snd_printdd("hda_codec_cleanup_stream: NID=0x%x\n", nid);
1152 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
1153#if 0 /* keep the format */
1154 msleep(1);
1155 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0);
1156#endif
1157}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001158EXPORT_SYMBOL_HDA(snd_hda_codec_cleanup_stream);
Takashi Iwai888afa12008-03-18 09:57:50 +01001159
Linus Torvalds1da177e2005-04-16 15:20:36 -07001160/*
1161 * amp access functions
1162 */
1163
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001164/* FIXME: more better hash key? */
1165#define HDA_HASH_KEY(nid,dir,idx) (u32)((nid) + ((idx) << 16) + ((dir) << 24))
Takashi Iwai1327a322009-03-23 13:07:47 +01001166#define HDA_HASH_PINCAP_KEY(nid) (u32)((nid) + (0x02 << 24))
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01001167#define HDA_HASH_PARPCM_KEY(nid) (u32)((nid) + (0x03 << 24))
1168#define HDA_HASH_PARSTR_KEY(nid) (u32)((nid) + (0x04 << 24))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001169#define INFO_AMP_CAPS (1<<0)
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001170#define INFO_AMP_VOL(ch) (1 << (1 + (ch)))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001171
1172/* initialize the hash table */
Takashi Iwai1289e9e2008-11-27 15:47:11 +01001173static void /*__devinit*/ init_hda_cache(struct hda_cache_rec *cache,
Takashi Iwai01751f52007-08-10 16:59:39 +02001174 unsigned int record_size)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175{
Takashi Iwai01751f52007-08-10 16:59:39 +02001176 memset(cache, 0, sizeof(*cache));
1177 memset(cache->hash, 0xff, sizeof(cache->hash));
Takashi Iwai603c4012008-07-30 15:01:44 +02001178 snd_array_init(&cache->buf, record_size, 64);
Takashi Iwai01751f52007-08-10 16:59:39 +02001179}
1180
Takashi Iwai1fcaee62007-08-23 00:01:09 +02001181static void free_hda_cache(struct hda_cache_rec *cache)
Takashi Iwai01751f52007-08-10 16:59:39 +02001182{
Takashi Iwai603c4012008-07-30 15:01:44 +02001183 snd_array_free(&cache->buf);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001184}
1185
1186/* query the hash. allocate an entry if not found. */
Takashi Iwai01751f52007-08-10 16:59:39 +02001187static struct hda_cache_head *get_alloc_hash(struct hda_cache_rec *cache,
1188 u32 key)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189{
Takashi Iwai01751f52007-08-10 16:59:39 +02001190 u16 idx = key % (u16)ARRAY_SIZE(cache->hash);
1191 u16 cur = cache->hash[idx];
1192 struct hda_cache_head *info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193
1194 while (cur != 0xffff) {
Takashi Iwaif43aa022008-11-10 16:24:26 +01001195 info = snd_array_elem(&cache->buf, cur);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 if (info->key == key)
1197 return info;
1198 cur = info->next;
1199 }
1200
1201 /* add a new hash entry */
Takashi Iwai603c4012008-07-30 15:01:44 +02001202 info = snd_array_new(&cache->buf);
Takashi Iwaic2174292008-11-07 00:23:30 +01001203 if (!info)
1204 return NULL;
Takashi Iwaif43aa022008-11-10 16:24:26 +01001205 cur = snd_array_index(&cache->buf, info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001206 info->key = key;
Takashi Iwai01751f52007-08-10 16:59:39 +02001207 info->val = 0;
1208 info->next = cache->hash[idx];
1209 cache->hash[idx] = cur;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001210
1211 return info;
1212}
1213
Takashi Iwai01751f52007-08-10 16:59:39 +02001214/* query and allocate an amp hash entry */
1215static inline struct hda_amp_info *
1216get_alloc_amp_hash(struct hda_codec *codec, u32 key)
1217{
1218 return (struct hda_amp_info *)get_alloc_hash(&codec->amp_cache, key);
1219}
1220
Takashi Iwaid5191e52009-11-16 14:58:17 +01001221/**
1222 * query_amp_caps - query AMP capabilities
1223 * @codec: the HD-auio codec
1224 * @nid: the NID to query
1225 * @direction: either #HDA_INPUT or #HDA_OUTPUT
1226 *
1227 * Query AMP capabilities for the given widget and direction.
1228 * Returns the obtained capability bits.
1229 *
1230 * When cap bits have been already read, this doesn't read again but
1231 * returns the cached value.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001232 */
Matthew Ranostay09a99952008-01-24 11:49:21 +01001233u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001234{
Takashi Iwai0ba21762007-04-16 11:29:14 +02001235 struct hda_amp_info *info;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236
Takashi Iwai0ba21762007-04-16 11:29:14 +02001237 info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, 0));
1238 if (!info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001239 return 0;
Takashi Iwai01751f52007-08-10 16:59:39 +02001240 if (!(info->head.val & INFO_AMP_CAPS)) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02001241 if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 nid = codec->afg;
Takashi Iwai0ba21762007-04-16 11:29:14 +02001243 info->amp_caps = snd_hda_param_read(codec, nid,
1244 direction == HDA_OUTPUT ?
1245 AC_PAR_AMP_OUT_CAP :
1246 AC_PAR_AMP_IN_CAP);
Takashi Iwaib75e53f2007-05-10 16:56:09 +02001247 if (info->amp_caps)
Takashi Iwai01751f52007-08-10 16:59:39 +02001248 info->head.val |= INFO_AMP_CAPS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001249 }
1250 return info->amp_caps;
1251}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001252EXPORT_SYMBOL_HDA(query_amp_caps);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001253
Takashi Iwaid5191e52009-11-16 14:58:17 +01001254/**
1255 * snd_hda_override_amp_caps - Override the AMP capabilities
1256 * @codec: the CODEC to clean up
1257 * @nid: the NID to clean up
1258 * @direction: either #HDA_INPUT or #HDA_OUTPUT
1259 * @caps: the capability bits to set
1260 *
1261 * Override the cached AMP caps bits value by the given one.
1262 * This function is useful if the driver needs to adjust the AMP ranges,
1263 * e.g. limit to 0dB, etc.
1264 *
1265 * Returns zero if successful or a negative error code.
1266 */
Takashi Iwai897cc182007-05-29 19:01:37 +02001267int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
1268 unsigned int caps)
1269{
1270 struct hda_amp_info *info;
1271
1272 info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, dir, 0));
1273 if (!info)
1274 return -EINVAL;
1275 info->amp_caps = caps;
Takashi Iwai01751f52007-08-10 16:59:39 +02001276 info->head.val |= INFO_AMP_CAPS;
Takashi Iwai897cc182007-05-29 19:01:37 +02001277 return 0;
1278}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001279EXPORT_SYMBOL_HDA(snd_hda_override_amp_caps);
Takashi Iwai897cc182007-05-29 19:01:37 +02001280
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01001281static unsigned int
1282query_caps_hash(struct hda_codec *codec, hda_nid_t nid, u32 key,
1283 unsigned int (*func)(struct hda_codec *, hda_nid_t))
Takashi Iwai1327a322009-03-23 13:07:47 +01001284{
1285 struct hda_amp_info *info;
1286
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01001287 info = get_alloc_amp_hash(codec, key);
Takashi Iwai1327a322009-03-23 13:07:47 +01001288 if (!info)
1289 return 0;
1290 if (!info->head.val) {
Takashi Iwai1327a322009-03-23 13:07:47 +01001291 info->head.val |= INFO_AMP_CAPS;
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01001292 info->amp_caps = func(codec, nid);
Takashi Iwai1327a322009-03-23 13:07:47 +01001293 }
1294 return info->amp_caps;
1295}
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01001296
1297static unsigned int read_pin_cap(struct hda_codec *codec, hda_nid_t nid)
1298{
1299 return snd_hda_param_read(codec, nid, AC_PAR_PIN_CAP);
1300}
1301
Takashi Iwaid5191e52009-11-16 14:58:17 +01001302/**
1303 * snd_hda_query_pin_caps - Query PIN capabilities
1304 * @codec: the HD-auio codec
1305 * @nid: the NID to query
1306 *
1307 * Query PIN capabilities for the given widget.
1308 * Returns the obtained capability bits.
1309 *
1310 * When cap bits have been already read, this doesn't read again but
1311 * returns the cached value.
1312 */
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01001313u32 snd_hda_query_pin_caps(struct hda_codec *codec, hda_nid_t nid)
1314{
1315 return query_caps_hash(codec, nid, HDA_HASH_PINCAP_KEY(nid),
1316 read_pin_cap);
1317}
Takashi Iwai1327a322009-03-23 13:07:47 +01001318EXPORT_SYMBOL_HDA(snd_hda_query_pin_caps);
1319
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320/*
1321 * read the current volume to info
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001322 * if the cache exists, read the cache value.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001323 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001324static unsigned int get_vol_mute(struct hda_codec *codec,
1325 struct hda_amp_info *info, hda_nid_t nid,
1326 int ch, int direction, int index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001327{
1328 u32 val, parm;
1329
Takashi Iwai01751f52007-08-10 16:59:39 +02001330 if (info->head.val & INFO_AMP_VOL(ch))
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001331 return info->vol[ch];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332
1333 parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT;
1334 parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
1335 parm |= index;
Takashi Iwai0ba21762007-04-16 11:29:14 +02001336 val = snd_hda_codec_read(codec, nid, 0,
1337 AC_VERB_GET_AMP_GAIN_MUTE, parm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 info->vol[ch] = val & 0xff;
Takashi Iwai01751f52007-08-10 16:59:39 +02001339 info->head.val |= INFO_AMP_VOL(ch);
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001340 return info->vol[ch];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001341}
1342
1343/*
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001344 * write the current volume in info to the h/w and update the cache
Linus Torvalds1da177e2005-04-16 15:20:36 -07001345 */
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001346static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
Takashi Iwai0ba21762007-04-16 11:29:14 +02001347 hda_nid_t nid, int ch, int direction, int index,
1348 int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001349{
1350 u32 parm;
1351
1352 parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;
1353 parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;
1354 parm |= index << AC_AMP_SET_INDEX_SHIFT;
1355 parm |= val;
1356 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001357 info->vol[ch] = val;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001358}
1359
Takashi Iwaid5191e52009-11-16 14:58:17 +01001360/**
1361 * snd_hda_codec_amp_read - Read AMP value
1362 * @codec: HD-audio codec
1363 * @nid: NID to read the AMP value
1364 * @ch: channel (left=0 or right=1)
1365 * @direction: #HDA_INPUT or #HDA_OUTPUT
1366 * @index: the index value (only for input direction)
1367 *
1368 * Read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001369 */
Takashi Iwai834be882006-03-01 14:16:17 +01001370int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
1371 int direction, int index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001372{
Takashi Iwai0ba21762007-04-16 11:29:14 +02001373 struct hda_amp_info *info;
1374 info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
1375 if (!info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001376 return 0;
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001377 return get_vol_mute(codec, info, nid, ch, direction, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001378}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001379EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001380
Takashi Iwaid5191e52009-11-16 14:58:17 +01001381/**
1382 * snd_hda_codec_amp_update - update the AMP value
1383 * @codec: HD-audio codec
1384 * @nid: NID to read the AMP value
1385 * @ch: channel (left=0 or right=1)
1386 * @direction: #HDA_INPUT or #HDA_OUTPUT
1387 * @idx: the index value (only for input direction)
1388 * @mask: bit mask to set
1389 * @val: the bits value to set
1390 *
1391 * Update the AMP value with a bit mask.
1392 * Returns 0 if the value is unchanged, 1 if changed.
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001393 */
Takashi Iwai834be882006-03-01 14:16:17 +01001394int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
1395 int direction, int idx, int mask, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396{
Takashi Iwai0ba21762007-04-16 11:29:14 +02001397 struct hda_amp_info *info;
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001398
Takashi Iwai0ba21762007-04-16 11:29:14 +02001399 info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
1400 if (!info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001401 return 0;
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001402 val &= mask;
1403 val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02001404 if (info->vol[ch] == val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 return 0;
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001406 put_vol_mute(codec, info, nid, ch, direction, idx, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001407 return 1;
1408}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001409EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001410
Takashi Iwaid5191e52009-11-16 14:58:17 +01001411/**
1412 * snd_hda_codec_amp_stereo - update the AMP stereo values
1413 * @codec: HD-audio codec
1414 * @nid: NID to read the AMP value
1415 * @direction: #HDA_INPUT or #HDA_OUTPUT
1416 * @idx: the index value (only for input direction)
1417 * @mask: bit mask to set
1418 * @val: the bits value to set
1419 *
1420 * Update the AMP values like snd_hda_codec_amp_update(), but for a
1421 * stereo widget with the same mask and value.
Takashi Iwai47fd8302007-08-10 17:11:07 +02001422 */
1423int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
1424 int direction, int idx, int mask, int val)
1425{
1426 int ch, ret = 0;
1427 for (ch = 0; ch < 2; ch++)
1428 ret |= snd_hda_codec_amp_update(codec, nid, ch, direction,
1429 idx, mask, val);
1430 return ret;
1431}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001432EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);
Takashi Iwai47fd8302007-08-10 17:11:07 +02001433
Takashi Iwaicb53c622007-08-10 17:21:45 +02001434#ifdef SND_HDA_NEEDS_RESUME
Takashi Iwaid5191e52009-11-16 14:58:17 +01001435/**
1436 * snd_hda_codec_resume_amp - Resume all AMP commands from the cache
1437 * @codec: HD-audio codec
1438 *
1439 * Resume the all amp commands from the cache.
1440 */
Takashi Iwaib3ac5632007-08-10 17:03:40 +02001441void snd_hda_codec_resume_amp(struct hda_codec *codec)
1442{
Takashi Iwai603c4012008-07-30 15:01:44 +02001443 struct hda_amp_info *buffer = codec->amp_cache.buf.list;
Takashi Iwaib3ac5632007-08-10 17:03:40 +02001444 int i;
1445
Takashi Iwai603c4012008-07-30 15:01:44 +02001446 for (i = 0; i < codec->amp_cache.buf.used; i++, buffer++) {
Takashi Iwaib3ac5632007-08-10 17:03:40 +02001447 u32 key = buffer->head.key;
1448 hda_nid_t nid;
1449 unsigned int idx, dir, ch;
1450 if (!key)
1451 continue;
1452 nid = key & 0xff;
1453 idx = (key >> 16) & 0xff;
1454 dir = (key >> 24) & 0xff;
1455 for (ch = 0; ch < 2; ch++) {
1456 if (!(buffer->head.val & INFO_AMP_VOL(ch)))
1457 continue;
1458 put_vol_mute(codec, buffer, nid, ch, dir, idx,
1459 buffer->vol[ch]);
1460 }
1461 }
1462}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001463EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
Takashi Iwaicb53c622007-08-10 17:21:45 +02001464#endif /* SND_HDA_NEEDS_RESUME */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001465
Takashi Iwaid5191e52009-11-16 14:58:17 +01001466/**
1467 * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer
1468 *
1469 * The control element is supposed to have the private_value field
1470 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1471 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001472int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
1473 struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001474{
1475 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1476 u16 nid = get_amp_nid(kcontrol);
1477 u8 chs = get_amp_channels(kcontrol);
1478 int dir = get_amp_direction(kcontrol);
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001479 unsigned int ofs = get_amp_offset(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001480 u32 caps;
1481
1482 caps = query_amp_caps(codec, nid, dir);
Takashi Iwai0ba21762007-04-16 11:29:14 +02001483 /* num steps */
1484 caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
1485 if (!caps) {
1486 printk(KERN_WARNING "hda_codec: "
Takashi Iwai9c8f2ab2008-01-11 16:12:23 +01001487 "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid,
1488 kcontrol->id.name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001489 return -EINVAL;
1490 }
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001491 if (ofs < caps)
1492 caps -= ofs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001493 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1494 uinfo->count = chs == 3 ? 2 : 1;
1495 uinfo->value.integer.min = 0;
1496 uinfo->value.integer.max = caps;
1497 return 0;
1498}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001499EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001500
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001501
1502static inline unsigned int
1503read_amp_value(struct hda_codec *codec, hda_nid_t nid,
1504 int ch, int dir, int idx, unsigned int ofs)
1505{
1506 unsigned int val;
1507 val = snd_hda_codec_amp_read(codec, nid, ch, dir, idx);
1508 val &= HDA_AMP_VOLMASK;
1509 if (val >= ofs)
1510 val -= ofs;
1511 else
1512 val = 0;
1513 return val;
1514}
1515
1516static inline int
1517update_amp_value(struct hda_codec *codec, hda_nid_t nid,
1518 int ch, int dir, int idx, unsigned int ofs,
1519 unsigned int val)
1520{
1521 if (val > 0)
1522 val += ofs;
1523 return snd_hda_codec_amp_update(codec, nid, ch, dir, idx,
1524 HDA_AMP_VOLMASK, val);
1525}
1526
Takashi Iwaid5191e52009-11-16 14:58:17 +01001527/**
1528 * snd_hda_mixer_amp_volume_get - Get callback for a standard AMP mixer volume
1529 *
1530 * The control element is supposed to have the private_value field
1531 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1532 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001533int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
1534 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535{
1536 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1537 hda_nid_t nid = get_amp_nid(kcontrol);
1538 int chs = get_amp_channels(kcontrol);
1539 int dir = get_amp_direction(kcontrol);
1540 int idx = get_amp_index(kcontrol);
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001541 unsigned int ofs = get_amp_offset(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001542 long *valp = ucontrol->value.integer.value;
1543
1544 if (chs & 1)
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001545 *valp++ = read_amp_value(codec, nid, 0, dir, idx, ofs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 if (chs & 2)
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001547 *valp = read_amp_value(codec, nid, 1, dir, idx, ofs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001548 return 0;
1549}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001550EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_get);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551
Takashi Iwaid5191e52009-11-16 14:58:17 +01001552/**
1553 * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume
1554 *
1555 * The control element is supposed to have the private_value field
1556 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1557 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001558int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
1559 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001560{
1561 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1562 hda_nid_t nid = get_amp_nid(kcontrol);
1563 int chs = get_amp_channels(kcontrol);
1564 int dir = get_amp_direction(kcontrol);
1565 int idx = get_amp_index(kcontrol);
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001566 unsigned int ofs = get_amp_offset(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 long *valp = ucontrol->value.integer.value;
1568 int change = 0;
1569
Takashi Iwaicb53c622007-08-10 17:21:45 +02001570 snd_hda_power_up(codec);
Nicolas Grazianob9f5a892005-07-29 12:17:20 +02001571 if (chs & 1) {
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001572 change = update_amp_value(codec, nid, 0, dir, idx, ofs, *valp);
Nicolas Grazianob9f5a892005-07-29 12:17:20 +02001573 valp++;
1574 }
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001575 if (chs & 2)
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001576 change |= update_amp_value(codec, nid, 1, dir, idx, ofs, *valp);
Takashi Iwaicb53c622007-08-10 17:21:45 +02001577 snd_hda_power_down(codec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 return change;
1579}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001580EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_put);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001581
Takashi Iwaid5191e52009-11-16 14:58:17 +01001582/**
1583 * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume
1584 *
1585 * The control element is supposed to have the private_value field
1586 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1587 */
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001588int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1589 unsigned int size, unsigned int __user *_tlv)
1590{
1591 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1592 hda_nid_t nid = get_amp_nid(kcontrol);
1593 int dir = get_amp_direction(kcontrol);
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001594 unsigned int ofs = get_amp_offset(kcontrol);
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001595 u32 caps, val1, val2;
1596
1597 if (size < 4 * sizeof(unsigned int))
1598 return -ENOMEM;
1599 caps = query_amp_caps(codec, nid, dir);
Takashi Iwai0ba21762007-04-16 11:29:14 +02001600 val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
1601 val2 = (val2 + 1) * 25;
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001602 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001603 val1 += ofs;
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001604 val1 = ((int)val1) * ((int)val2);
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001605 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
1606 return -EFAULT;
1607 if (put_user(2 * sizeof(unsigned int), _tlv + 1))
1608 return -EFAULT;
1609 if (put_user(val1, _tlv + 2))
1610 return -EFAULT;
1611 if (put_user(val2, _tlv + 3))
1612 return -EFAULT;
1613 return 0;
1614}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001615EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_tlv);
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001616
Takashi Iwaid5191e52009-11-16 14:58:17 +01001617/**
1618 * snd_hda_set_vmaster_tlv - Set TLV for a virtual master control
1619 * @codec: HD-audio codec
1620 * @nid: NID of a reference widget
1621 * @dir: #HDA_INPUT or #HDA_OUTPUT
1622 * @tlv: TLV data to be stored, at least 4 elements
1623 *
1624 * Set (static) TLV data for a virtual master volume using the AMP caps
1625 * obtained from the reference NID.
1626 * The volume range is recalculated as if the max volume is 0dB.
Takashi Iwai2134ea42008-01-10 16:53:55 +01001627 */
1628void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
1629 unsigned int *tlv)
1630{
1631 u32 caps;
1632 int nums, step;
1633
1634 caps = query_amp_caps(codec, nid, dir);
1635 nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
1636 step = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
1637 step = (step + 1) * 25;
1638 tlv[0] = SNDRV_CTL_TLVT_DB_SCALE;
1639 tlv[1] = 2 * sizeof(unsigned int);
1640 tlv[2] = -nums * step;
1641 tlv[3] = step;
1642}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001643EXPORT_SYMBOL_HDA(snd_hda_set_vmaster_tlv);
Takashi Iwai2134ea42008-01-10 16:53:55 +01001644
1645/* find a mixer control element with the given name */
Takashi Iwai09f99702008-02-04 12:31:13 +01001646static struct snd_kcontrol *
1647_snd_hda_find_mixer_ctl(struct hda_codec *codec,
1648 const char *name, int idx)
Takashi Iwai2134ea42008-01-10 16:53:55 +01001649{
1650 struct snd_ctl_elem_id id;
1651 memset(&id, 0, sizeof(id));
1652 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
Takashi Iwai09f99702008-02-04 12:31:13 +01001653 id.index = idx;
Takashi Iwai18cb7102009-04-16 10:22:24 +02001654 if (snd_BUG_ON(strlen(name) >= sizeof(id.name)))
1655 return NULL;
Takashi Iwai2134ea42008-01-10 16:53:55 +01001656 strcpy(id.name, name);
1657 return snd_ctl_find_id(codec->bus->card, &id);
1658}
1659
Takashi Iwaid5191e52009-11-16 14:58:17 +01001660/**
1661 * snd_hda_find_mixer_ctl - Find a mixer control element with the given name
1662 * @codec: HD-audio codec
1663 * @name: ctl id name string
1664 *
1665 * Get the control element with the given id string and IFACE_MIXER.
1666 */
Takashi Iwai09f99702008-02-04 12:31:13 +01001667struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1668 const char *name)
1669{
1670 return _snd_hda_find_mixer_ctl(codec, name, 0);
1671}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001672EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
Takashi Iwai09f99702008-02-04 12:31:13 +01001673
Takashi Iwaid5191e52009-11-16 14:58:17 +01001674/**
1675 * snd_hda_ctl-add - Add a control element and assign to the codec
1676 * @codec: HD-audio codec
1677 * @nid: corresponding NID (optional)
1678 * @kctl: the control element to assign
1679 *
1680 * Add the given control element to an array inside the codec instance.
1681 * All control elements belonging to a codec are supposed to be added
1682 * by this function so that a proper clean-up works at the free or
1683 * reconfiguration time.
1684 *
1685 * If non-zero @nid is passed, the NID is assigned to the control element.
1686 * The assignment is shown in the codec proc file.
1687 *
1688 * snd_hda_ctl_add() checks the control subdev id field whether
1689 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower
1690 * bits value is taken as the NID to assign.
1691 */
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001692int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1693 struct snd_kcontrol *kctl)
Takashi Iwaid13bd412008-07-30 15:01:45 +02001694{
1695 int err;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001696 struct hda_nid_item *item;
Takashi Iwaid13bd412008-07-30 15:01:45 +02001697
Takashi Iwai9c96fa52009-11-16 11:25:33 +01001698 if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) {
Jaroslav Kysela4d02d1b2009-11-12 10:15:48 +01001699 if (nid == 0)
1700 nid = kctl->id.subdevice & 0xffff;
1701 kctl->id.subdevice = 0;
1702 }
Takashi Iwaid13bd412008-07-30 15:01:45 +02001703 err = snd_ctl_add(codec->bus->card, kctl);
1704 if (err < 0)
1705 return err;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001706 item = snd_array_new(&codec->mixers);
1707 if (!item)
Takashi Iwaid13bd412008-07-30 15:01:45 +02001708 return -ENOMEM;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001709 item->kctl = kctl;
1710 item->nid = nid;
Takashi Iwaid13bd412008-07-30 15:01:45 +02001711 return 0;
1712}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001713EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
Takashi Iwaid13bd412008-07-30 15:01:45 +02001714
Takashi Iwaid5191e52009-11-16 14:58:17 +01001715/**
1716 * snd_hda_ctls_clear - Clear all controls assigned to the given codec
1717 * @codec: HD-audio codec
1718 */
Takashi Iwaid13bd412008-07-30 15:01:45 +02001719void snd_hda_ctls_clear(struct hda_codec *codec)
1720{
1721 int i;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001722 struct hda_nid_item *items = codec->mixers.list;
Takashi Iwaid13bd412008-07-30 15:01:45 +02001723 for (i = 0; i < codec->mixers.used; i++)
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001724 snd_ctl_remove(codec->bus->card, items[i].kctl);
Takashi Iwaid13bd412008-07-30 15:01:45 +02001725 snd_array_free(&codec->mixers);
1726}
1727
Takashi Iwaia65d6292009-02-23 16:57:04 +01001728/* pseudo device locking
1729 * toggle card->shutdown to allow/disallow the device access (as a hack)
1730 */
1731static int hda_lock_devices(struct snd_card *card)
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001732{
Takashi Iwaia65d6292009-02-23 16:57:04 +01001733 spin_lock(&card->files_lock);
1734 if (card->shutdown) {
1735 spin_unlock(&card->files_lock);
1736 return -EINVAL;
1737 }
1738 card->shutdown = 1;
1739 spin_unlock(&card->files_lock);
1740 return 0;
1741}
1742
1743static void hda_unlock_devices(struct snd_card *card)
1744{
1745 spin_lock(&card->files_lock);
1746 card->shutdown = 0;
1747 spin_unlock(&card->files_lock);
1748}
1749
Takashi Iwaid5191e52009-11-16 14:58:17 +01001750/**
1751 * snd_hda_codec_reset - Clear all objects assigned to the codec
1752 * @codec: HD-audio codec
1753 *
1754 * This frees the all PCM and control elements assigned to the codec, and
1755 * clears the caches and restores the pin default configurations.
1756 *
1757 * When a device is being used, it returns -EBSY. If successfully freed,
1758 * returns zero.
1759 */
Takashi Iwaia65d6292009-02-23 16:57:04 +01001760int snd_hda_codec_reset(struct hda_codec *codec)
1761{
1762 struct snd_card *card = codec->bus->card;
1763 int i, pcm;
1764
1765 if (hda_lock_devices(card) < 0)
1766 return -EBUSY;
1767 /* check whether the codec isn't used by any mixer or PCM streams */
1768 if (!list_empty(&card->ctl_files)) {
1769 hda_unlock_devices(card);
1770 return -EBUSY;
1771 }
1772 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
1773 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
1774 if (!cpcm->pcm)
1775 continue;
1776 if (cpcm->pcm->streams[0].substream_opened ||
1777 cpcm->pcm->streams[1].substream_opened) {
1778 hda_unlock_devices(card);
1779 return -EBUSY;
1780 }
1781 }
1782
1783 /* OK, let it free */
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001784
1785#ifdef CONFIG_SND_HDA_POWER_SAVE
1786 cancel_delayed_work(&codec->power_work);
Takashi Iwai6acaed32009-01-12 10:09:24 +01001787 flush_workqueue(codec->bus->workq);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001788#endif
1789 snd_hda_ctls_clear(codec);
1790 /* relase PCMs */
1791 for (i = 0; i < codec->num_pcms; i++) {
Takashi Iwai529bd6c2008-11-27 14:17:01 +01001792 if (codec->pcm_info[i].pcm) {
Takashi Iwaia65d6292009-02-23 16:57:04 +01001793 snd_device_free(card, codec->pcm_info[i].pcm);
Takashi Iwai529bd6c2008-11-27 14:17:01 +01001794 clear_bit(codec->pcm_info[i].device,
1795 codec->bus->pcm_dev_bits);
1796 }
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001797 }
1798 if (codec->patch_ops.free)
1799 codec->patch_ops.free(codec);
Takashi Iwai56d17712008-11-28 14:36:23 +01001800 codec->proc_widget_hook = NULL;
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001801 codec->spec = NULL;
1802 free_hda_cache(&codec->amp_cache);
1803 free_hda_cache(&codec->cmd_cache);
Takashi Iwai827057f2008-12-19 10:12:02 +01001804 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
1805 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
Takashi Iwai346ff702009-02-23 09:42:57 +01001806 /* free only driver_pins so that init_pins + user_pins are restored */
1807 snd_array_free(&codec->driver_pins);
Takashi Iwai3be14142009-02-20 14:11:16 +01001808 restore_pincfgs(codec);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001809 codec->num_pcms = 0;
1810 codec->pcm_info = NULL;
1811 codec->preset = NULL;
Takashi Iwaid1f1af22009-03-02 10:35:29 +01001812 memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
1813 codec->slave_dig_outs = NULL;
1814 codec->spdif_status_reset = 0;
Takashi Iwai1289e9e2008-11-27 15:47:11 +01001815 module_put(codec->owner);
1816 codec->owner = NULL;
Takashi Iwaia65d6292009-02-23 16:57:04 +01001817
1818 /* allow device access again */
1819 hda_unlock_devices(card);
1820 return 0;
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001821}
1822
Takashi Iwaid5191e52009-11-16 14:58:17 +01001823/**
1824 * snd_hda_add_vmaster - create a virtual master control and add slaves
1825 * @codec: HD-audio codec
1826 * @name: vmaster control name
1827 * @tlv: TLV data (optional)
1828 * @slaves: slave control names (optional)
1829 *
1830 * Create a virtual master control with the given name. The TLV data
1831 * must be either NULL or a valid data.
1832 *
1833 * @slaves is a NULL-terminated array of strings, each of which is a
1834 * slave control name. All controls with these names are assigned to
1835 * the new virtual master control.
1836 *
1837 * This function returns zero if successful or a negative error code.
1838 */
Takashi Iwai2134ea42008-01-10 16:53:55 +01001839int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1840 unsigned int *tlv, const char **slaves)
1841{
1842 struct snd_kcontrol *kctl;
1843 const char **s;
1844 int err;
1845
Takashi Iwai2f085542008-02-22 18:43:50 +01001846 for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++)
1847 ;
1848 if (!*s) {
1849 snd_printdd("No slave found for %s\n", name);
1850 return 0;
1851 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01001852 kctl = snd_ctl_make_virtual_master(name, tlv);
1853 if (!kctl)
1854 return -ENOMEM;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001855 err = snd_hda_ctl_add(codec, 0, kctl);
Takashi Iwai2134ea42008-01-10 16:53:55 +01001856 if (err < 0)
1857 return err;
1858
1859 for (s = slaves; *s; s++) {
1860 struct snd_kcontrol *sctl;
Takashi Iwai7a411ee2009-03-06 10:08:14 +01001861 int i = 0;
1862 for (;;) {
1863 sctl = _snd_hda_find_mixer_ctl(codec, *s, i);
1864 if (!sctl) {
1865 if (!i)
1866 snd_printdd("Cannot find slave %s, "
1867 "skipped\n", *s);
1868 break;
1869 }
1870 err = snd_ctl_add_slave(kctl, sctl);
1871 if (err < 0)
1872 return err;
1873 i++;
Takashi Iwai2134ea42008-01-10 16:53:55 +01001874 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01001875 }
1876 return 0;
1877}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001878EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);
Takashi Iwai2134ea42008-01-10 16:53:55 +01001879
Takashi Iwaid5191e52009-11-16 14:58:17 +01001880/**
1881 * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch
1882 *
1883 * The control element is supposed to have the private_value field
1884 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1885 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001886int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
1887 struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001888{
1889 int chs = get_amp_channels(kcontrol);
1890
1891 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1892 uinfo->count = chs == 3 ? 2 : 1;
1893 uinfo->value.integer.min = 0;
1894 uinfo->value.integer.max = 1;
1895 return 0;
1896}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001897EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001898
Takashi Iwaid5191e52009-11-16 14:58:17 +01001899/**
1900 * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch
1901 *
1902 * The control element is supposed to have the private_value field
1903 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1904 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001905int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
1906 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001907{
1908 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1909 hda_nid_t nid = get_amp_nid(kcontrol);
1910 int chs = get_amp_channels(kcontrol);
1911 int dir = get_amp_direction(kcontrol);
1912 int idx = get_amp_index(kcontrol);
1913 long *valp = ucontrol->value.integer.value;
1914
1915 if (chs & 1)
Takashi Iwai0ba21762007-04-16 11:29:14 +02001916 *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) &
Takashi Iwai47fd8302007-08-10 17:11:07 +02001917 HDA_AMP_MUTE) ? 0 : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001918 if (chs & 2)
Takashi Iwai0ba21762007-04-16 11:29:14 +02001919 *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) &
Takashi Iwai47fd8302007-08-10 17:11:07 +02001920 HDA_AMP_MUTE) ? 0 : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001921 return 0;
1922}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001923EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924
Takashi Iwaid5191e52009-11-16 14:58:17 +01001925/**
1926 * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch
1927 *
1928 * The control element is supposed to have the private_value field
1929 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1930 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001931int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
1932 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001933{
1934 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1935 hda_nid_t nid = get_amp_nid(kcontrol);
1936 int chs = get_amp_channels(kcontrol);
1937 int dir = get_amp_direction(kcontrol);
1938 int idx = get_amp_index(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001939 long *valp = ucontrol->value.integer.value;
1940 int change = 0;
1941
Takashi Iwaicb53c622007-08-10 17:21:45 +02001942 snd_hda_power_up(codec);
Nicolas Grazianob9f5a892005-07-29 12:17:20 +02001943 if (chs & 1) {
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001944 change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
Takashi Iwai47fd8302007-08-10 17:11:07 +02001945 HDA_AMP_MUTE,
1946 *valp ? 0 : HDA_AMP_MUTE);
Nicolas Grazianob9f5a892005-07-29 12:17:20 +02001947 valp++;
1948 }
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001949 if (chs & 2)
1950 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
Takashi Iwai47fd8302007-08-10 17:11:07 +02001951 HDA_AMP_MUTE,
1952 *valp ? 0 : HDA_AMP_MUTE);
Takashi Iwaicb53c622007-08-10 17:21:45 +02001953#ifdef CONFIG_SND_HDA_POWER_SAVE
1954 if (codec->patch_ops.check_power_status)
1955 codec->patch_ops.check_power_status(codec, nid);
1956#endif
1957 snd_hda_power_down(codec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001958 return change;
1959}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001960EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001961
Takashi Iwai67d634c2009-11-16 15:35:59 +01001962#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaid5191e52009-11-16 14:58:17 +01001963/**
1964 * snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch
1965 *
1966 * This function calls snd_hda_enable_beep_device(), which behaves differently
1967 * depending on beep_mode option.
1968 */
Jaroslav Kysela123c07a2009-10-21 14:48:23 +02001969int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
1970 struct snd_ctl_elem_value *ucontrol)
1971{
1972 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1973 long *valp = ucontrol->value.integer.value;
1974
1975 snd_hda_enable_beep_device(codec, *valp);
1976 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
1977}
1978EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
Takashi Iwai67d634c2009-11-16 15:35:59 +01001979#endif /* CONFIG_SND_HDA_INPUT_BEEP */
Jaroslav Kysela123c07a2009-10-21 14:48:23 +02001980
Linus Torvalds1da177e2005-04-16 15:20:36 -07001981/*
Takashi Iwai985be542005-11-02 18:26:49 +01001982 * bound volume controls
1983 *
1984 * bind multiple volumes (# indices, from 0)
1985 */
1986
1987#define AMP_VAL_IDX_SHIFT 19
1988#define AMP_VAL_IDX_MASK (0x0f<<19)
1989
Takashi Iwaid5191e52009-11-16 14:58:17 +01001990/**
1991 * snd_hda_mixer_bind_switch_get - Get callback for a bound volume control
1992 *
1993 * The control element is supposed to have the private_value field
1994 * set up via HDA_BIND_MUTE*() macros.
1995 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001996int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
1997 struct snd_ctl_elem_value *ucontrol)
Takashi Iwai985be542005-11-02 18:26:49 +01001998{
1999 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2000 unsigned long pval;
2001 int err;
2002
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002003 mutex_lock(&codec->control_mutex);
Takashi Iwai985be542005-11-02 18:26:49 +01002004 pval = kcontrol->private_value;
2005 kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
2006 err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
2007 kcontrol->private_value = pval;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002008 mutex_unlock(&codec->control_mutex);
Takashi Iwai985be542005-11-02 18:26:49 +01002009 return err;
2010}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002011EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get);
Takashi Iwai985be542005-11-02 18:26:49 +01002012
Takashi Iwaid5191e52009-11-16 14:58:17 +01002013/**
2014 * snd_hda_mixer_bind_switch_put - Put callback for a bound volume control
2015 *
2016 * The control element is supposed to have the private_value field
2017 * set up via HDA_BIND_MUTE*() macros.
2018 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02002019int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
2020 struct snd_ctl_elem_value *ucontrol)
Takashi Iwai985be542005-11-02 18:26:49 +01002021{
2022 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2023 unsigned long pval;
2024 int i, indices, err = 0, change = 0;
2025
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002026 mutex_lock(&codec->control_mutex);
Takashi Iwai985be542005-11-02 18:26:49 +01002027 pval = kcontrol->private_value;
2028 indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
2029 for (i = 0; i < indices; i++) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02002030 kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) |
2031 (i << AMP_VAL_IDX_SHIFT);
Takashi Iwai985be542005-11-02 18:26:49 +01002032 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2033 if (err < 0)
2034 break;
2035 change |= err;
2036 }
2037 kcontrol->private_value = pval;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002038 mutex_unlock(&codec->control_mutex);
Takashi Iwai985be542005-11-02 18:26:49 +01002039 return err < 0 ? err : change;
2040}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002041EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put);
Takashi Iwai985be542005-11-02 18:26:49 +01002042
Takashi Iwaid5191e52009-11-16 14:58:17 +01002043/**
2044 * snd_hda_mixer_bind_ctls_info - Info callback for a generic bound control
2045 *
2046 * The control element is supposed to have the private_value field
2047 * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
Takashi Iwai532d5382007-07-27 19:02:40 +02002048 */
2049int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
2050 struct snd_ctl_elem_info *uinfo)
2051{
2052 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2053 struct hda_bind_ctls *c;
2054 int err;
2055
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002056 mutex_lock(&codec->control_mutex);
Serge A. Suchkov14c65f92008-02-22 18:43:16 +01002057 c = (struct hda_bind_ctls *)kcontrol->private_value;
Takashi Iwai532d5382007-07-27 19:02:40 +02002058 kcontrol->private_value = *c->values;
2059 err = c->ops->info(kcontrol, uinfo);
2060 kcontrol->private_value = (long)c;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002061 mutex_unlock(&codec->control_mutex);
Takashi Iwai532d5382007-07-27 19:02:40 +02002062 return err;
2063}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002064EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info);
Takashi Iwai532d5382007-07-27 19:02:40 +02002065
Takashi Iwaid5191e52009-11-16 14:58:17 +01002066/**
2067 * snd_hda_mixer_bind_ctls_get - Get callback for a generic bound control
2068 *
2069 * The control element is supposed to have the private_value field
2070 * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
2071 */
Takashi Iwai532d5382007-07-27 19:02:40 +02002072int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
2073 struct snd_ctl_elem_value *ucontrol)
2074{
2075 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2076 struct hda_bind_ctls *c;
2077 int err;
2078
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002079 mutex_lock(&codec->control_mutex);
Serge A. Suchkov14c65f92008-02-22 18:43:16 +01002080 c = (struct hda_bind_ctls *)kcontrol->private_value;
Takashi Iwai532d5382007-07-27 19:02:40 +02002081 kcontrol->private_value = *c->values;
2082 err = c->ops->get(kcontrol, ucontrol);
2083 kcontrol->private_value = (long)c;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002084 mutex_unlock(&codec->control_mutex);
Takashi Iwai532d5382007-07-27 19:02:40 +02002085 return err;
2086}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002087EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get);
Takashi Iwai532d5382007-07-27 19:02:40 +02002088
Takashi Iwaid5191e52009-11-16 14:58:17 +01002089/**
2090 * snd_hda_mixer_bind_ctls_put - Put callback for a generic bound control
2091 *
2092 * The control element is supposed to have the private_value field
2093 * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
2094 */
Takashi Iwai532d5382007-07-27 19:02:40 +02002095int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
2096 struct snd_ctl_elem_value *ucontrol)
2097{
2098 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2099 struct hda_bind_ctls *c;
2100 unsigned long *vals;
2101 int err = 0, change = 0;
2102
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002103 mutex_lock(&codec->control_mutex);
Serge A. Suchkov14c65f92008-02-22 18:43:16 +01002104 c = (struct hda_bind_ctls *)kcontrol->private_value;
Takashi Iwai532d5382007-07-27 19:02:40 +02002105 for (vals = c->values; *vals; vals++) {
2106 kcontrol->private_value = *vals;
2107 err = c->ops->put(kcontrol, ucontrol);
2108 if (err < 0)
2109 break;
2110 change |= err;
2111 }
2112 kcontrol->private_value = (long)c;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002113 mutex_unlock(&codec->control_mutex);
Takashi Iwai532d5382007-07-27 19:02:40 +02002114 return err < 0 ? err : change;
2115}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002116EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put);
Takashi Iwai532d5382007-07-27 19:02:40 +02002117
Takashi Iwaid5191e52009-11-16 14:58:17 +01002118/**
2119 * snd_hda_mixer_bind_tlv - TLV callback for a generic bound control
2120 *
2121 * The control element is supposed to have the private_value field
2122 * set up via HDA_BIND_VOL() macro.
2123 */
Takashi Iwai532d5382007-07-27 19:02:40 +02002124int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2125 unsigned int size, unsigned int __user *tlv)
2126{
2127 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2128 struct hda_bind_ctls *c;
2129 int err;
2130
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002131 mutex_lock(&codec->control_mutex);
Serge A. Suchkov14c65f92008-02-22 18:43:16 +01002132 c = (struct hda_bind_ctls *)kcontrol->private_value;
Takashi Iwai532d5382007-07-27 19:02:40 +02002133 kcontrol->private_value = *c->values;
2134 err = c->ops->tlv(kcontrol, op_flag, size, tlv);
2135 kcontrol->private_value = (long)c;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002136 mutex_unlock(&codec->control_mutex);
Takashi Iwai532d5382007-07-27 19:02:40 +02002137 return err;
2138}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002139EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv);
Takashi Iwai532d5382007-07-27 19:02:40 +02002140
2141struct hda_ctl_ops snd_hda_bind_vol = {
2142 .info = snd_hda_mixer_amp_volume_info,
2143 .get = snd_hda_mixer_amp_volume_get,
2144 .put = snd_hda_mixer_amp_volume_put,
2145 .tlv = snd_hda_mixer_amp_tlv
2146};
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002147EXPORT_SYMBOL_HDA(snd_hda_bind_vol);
Takashi Iwai532d5382007-07-27 19:02:40 +02002148
2149struct hda_ctl_ops snd_hda_bind_sw = {
2150 .info = snd_hda_mixer_amp_switch_info,
2151 .get = snd_hda_mixer_amp_switch_get,
2152 .put = snd_hda_mixer_amp_switch_put,
2153 .tlv = snd_hda_mixer_amp_tlv
2154};
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002155EXPORT_SYMBOL_HDA(snd_hda_bind_sw);
Takashi Iwai532d5382007-07-27 19:02:40 +02002156
2157/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002158 * SPDIF out controls
2159 */
2160
Takashi Iwai0ba21762007-04-16 11:29:14 +02002161static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol,
2162 struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002163{
2164 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2165 uinfo->count = 1;
2166 return 0;
2167}
2168
Takashi Iwai0ba21762007-04-16 11:29:14 +02002169static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol,
2170 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002171{
2172 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
2173 IEC958_AES0_NONAUDIO |
2174 IEC958_AES0_CON_EMPHASIS_5015 |
2175 IEC958_AES0_CON_NOT_COPYRIGHT;
2176 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY |
2177 IEC958_AES1_CON_ORIGINAL;
2178 return 0;
2179}
2180
Takashi Iwai0ba21762007-04-16 11:29:14 +02002181static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol,
2182 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002183{
2184 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
2185 IEC958_AES0_NONAUDIO |
2186 IEC958_AES0_PRO_EMPHASIS_5015;
2187 return 0;
2188}
2189
Takashi Iwai0ba21762007-04-16 11:29:14 +02002190static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
2191 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002192{
2193 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2194
2195 ucontrol->value.iec958.status[0] = codec->spdif_status & 0xff;
2196 ucontrol->value.iec958.status[1] = (codec->spdif_status >> 8) & 0xff;
2197 ucontrol->value.iec958.status[2] = (codec->spdif_status >> 16) & 0xff;
2198 ucontrol->value.iec958.status[3] = (codec->spdif_status >> 24) & 0xff;
2199
2200 return 0;
2201}
2202
2203/* convert from SPDIF status bits to HDA SPDIF bits
2204 * bit 0 (DigEn) is always set zero (to be filled later)
2205 */
2206static unsigned short convert_from_spdif_status(unsigned int sbits)
2207{
2208 unsigned short val = 0;
2209
2210 if (sbits & IEC958_AES0_PROFESSIONAL)
Takashi Iwai0ba21762007-04-16 11:29:14 +02002211 val |= AC_DIG1_PROFESSIONAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212 if (sbits & IEC958_AES0_NONAUDIO)
Takashi Iwai0ba21762007-04-16 11:29:14 +02002213 val |= AC_DIG1_NONAUDIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002214 if (sbits & IEC958_AES0_PROFESSIONAL) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02002215 if ((sbits & IEC958_AES0_PRO_EMPHASIS) ==
2216 IEC958_AES0_PRO_EMPHASIS_5015)
2217 val |= AC_DIG1_EMPHASIS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002218 } else {
Takashi Iwai0ba21762007-04-16 11:29:14 +02002219 if ((sbits & IEC958_AES0_CON_EMPHASIS) ==
2220 IEC958_AES0_CON_EMPHASIS_5015)
2221 val |= AC_DIG1_EMPHASIS;
2222 if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
2223 val |= AC_DIG1_COPYRIGHT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002224 if (sbits & (IEC958_AES1_CON_ORIGINAL << 8))
Takashi Iwai0ba21762007-04-16 11:29:14 +02002225 val |= AC_DIG1_LEVEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226 val |= sbits & (IEC958_AES1_CON_CATEGORY << 8);
2227 }
2228 return val;
2229}
2230
2231/* convert to SPDIF status bits from HDA SPDIF bits
2232 */
2233static unsigned int convert_to_spdif_status(unsigned short val)
2234{
2235 unsigned int sbits = 0;
2236
Takashi Iwai0ba21762007-04-16 11:29:14 +02002237 if (val & AC_DIG1_NONAUDIO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002238 sbits |= IEC958_AES0_NONAUDIO;
Takashi Iwai0ba21762007-04-16 11:29:14 +02002239 if (val & AC_DIG1_PROFESSIONAL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002240 sbits |= IEC958_AES0_PROFESSIONAL;
2241 if (sbits & IEC958_AES0_PROFESSIONAL) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02002242 if (sbits & AC_DIG1_EMPHASIS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002243 sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
2244 } else {
Takashi Iwai0ba21762007-04-16 11:29:14 +02002245 if (val & AC_DIG1_EMPHASIS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002246 sbits |= IEC958_AES0_CON_EMPHASIS_5015;
Takashi Iwai0ba21762007-04-16 11:29:14 +02002247 if (!(val & AC_DIG1_COPYRIGHT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248 sbits |= IEC958_AES0_CON_NOT_COPYRIGHT;
Takashi Iwai0ba21762007-04-16 11:29:14 +02002249 if (val & AC_DIG1_LEVEL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 sbits |= (IEC958_AES1_CON_ORIGINAL << 8);
2251 sbits |= val & (0x7f << 8);
2252 }
2253 return sbits;
2254}
2255
Takashi Iwai2f728532008-09-25 16:32:41 +02002256/* set digital convert verbs both for the given NID and its slaves */
2257static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
2258 int verb, int val)
2259{
2260 hda_nid_t *d;
2261
Takashi Iwai9e976972008-11-25 08:17:20 +01002262 snd_hda_codec_write_cache(codec, nid, 0, verb, val);
Takashi Iwai2f728532008-09-25 16:32:41 +02002263 d = codec->slave_dig_outs;
2264 if (!d)
2265 return;
2266 for (; *d; d++)
Takashi Iwai9e976972008-11-25 08:17:20 +01002267 snd_hda_codec_write_cache(codec, *d, 0, verb, val);
Takashi Iwai2f728532008-09-25 16:32:41 +02002268}
2269
2270static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid,
2271 int dig1, int dig2)
2272{
2273 if (dig1 != -1)
2274 set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_1, dig1);
2275 if (dig2 != -1)
2276 set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_2, dig2);
2277}
2278
Takashi Iwai0ba21762007-04-16 11:29:14 +02002279static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
2280 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002281{
2282 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2283 hda_nid_t nid = kcontrol->private_value;
2284 unsigned short val;
2285 int change;
2286
Ingo Molnar62932df2006-01-16 16:34:20 +01002287 mutex_lock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002288 codec->spdif_status = ucontrol->value.iec958.status[0] |
2289 ((unsigned int)ucontrol->value.iec958.status[1] << 8) |
2290 ((unsigned int)ucontrol->value.iec958.status[2] << 16) |
2291 ((unsigned int)ucontrol->value.iec958.status[3] << 24);
2292 val = convert_from_spdif_status(codec->spdif_status);
2293 val |= codec->spdif_ctls & 1;
2294 change = codec->spdif_ctls != val;
2295 codec->spdif_ctls = val;
2296
Takashi Iwai2f728532008-09-25 16:32:41 +02002297 if (change)
2298 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002299
Ingo Molnar62932df2006-01-16 16:34:20 +01002300 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002301 return change;
2302}
2303
Takashi Iwaia5ce8892007-07-23 15:42:26 +02002304#define snd_hda_spdif_out_switch_info snd_ctl_boolean_mono_info
Linus Torvalds1da177e2005-04-16 15:20:36 -07002305
Takashi Iwai0ba21762007-04-16 11:29:14 +02002306static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
2307 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002308{
2309 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2310
Takashi Iwai0ba21762007-04-16 11:29:14 +02002311 ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002312 return 0;
2313}
2314
Takashi Iwai0ba21762007-04-16 11:29:14 +02002315static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
2316 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002317{
2318 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2319 hda_nid_t nid = kcontrol->private_value;
2320 unsigned short val;
2321 int change;
2322
Ingo Molnar62932df2006-01-16 16:34:20 +01002323 mutex_lock(&codec->spdif_mutex);
Takashi Iwai0ba21762007-04-16 11:29:14 +02002324 val = codec->spdif_ctls & ~AC_DIG1_ENABLE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002325 if (ucontrol->value.integer.value[0])
Takashi Iwai0ba21762007-04-16 11:29:14 +02002326 val |= AC_DIG1_ENABLE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002327 change = codec->spdif_ctls != val;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02002328 if (change) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002329 codec->spdif_ctls = val;
Takashi Iwai2f728532008-09-25 16:32:41 +02002330 set_dig_out_convert(codec, nid, val & 0xff, -1);
Takashi Iwai0ba21762007-04-16 11:29:14 +02002331 /* unmute amp switch (if any) */
2332 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
Takashi Iwai47fd8302007-08-10 17:11:07 +02002333 (val & AC_DIG1_ENABLE))
2334 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2335 HDA_AMP_MUTE, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002336 }
Ingo Molnar62932df2006-01-16 16:34:20 +01002337 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002338 return change;
2339}
2340
Takashi Iwaic8b6bf92005-11-17 14:57:47 +01002341static struct snd_kcontrol_new dig_mixes[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002342 {
2343 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2344 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2345 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
2346 .info = snd_hda_spdif_mask_info,
2347 .get = snd_hda_spdif_cmask_get,
2348 },
2349 {
2350 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2351 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2352 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
2353 .info = snd_hda_spdif_mask_info,
2354 .get = snd_hda_spdif_pmask_get,
2355 },
2356 {
2357 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2358 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2359 .info = snd_hda_spdif_mask_info,
2360 .get = snd_hda_spdif_default_get,
2361 .put = snd_hda_spdif_default_put,
2362 },
2363 {
2364 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2365 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
2366 .info = snd_hda_spdif_out_switch_info,
2367 .get = snd_hda_spdif_out_switch_get,
2368 .put = snd_hda_spdif_out_switch_put,
2369 },
2370 { } /* end */
2371};
2372
Takashi Iwai09f99702008-02-04 12:31:13 +01002373#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */
2374
Linus Torvalds1da177e2005-04-16 15:20:36 -07002375/**
2376 * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
2377 * @codec: the HDA codec
2378 * @nid: audio out widget NID
2379 *
2380 * Creates controls related with the SPDIF output.
2381 * Called from each patch supporting the SPDIF out.
2382 *
2383 * Returns 0 if successful, or a negative error code.
2384 */
Takashi Iwai12f288b2007-08-02 15:51:59 +02002385int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002386{
2387 int err;
Takashi Iwaic8b6bf92005-11-17 14:57:47 +01002388 struct snd_kcontrol *kctl;
2389 struct snd_kcontrol_new *dig_mix;
Takashi Iwai09f99702008-02-04 12:31:13 +01002390 int idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002391
Takashi Iwai09f99702008-02-04 12:31:13 +01002392 for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
2393 if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch",
2394 idx))
2395 break;
2396 }
2397 if (idx >= SPDIF_MAX_IDX) {
2398 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
2399 return -EBUSY;
2400 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002401 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
2402 kctl = snd_ctl_new1(dig_mix, codec);
Takashi Iwaib91f0802008-11-04 08:43:08 +01002403 if (!kctl)
2404 return -ENOMEM;
Takashi Iwai09f99702008-02-04 12:31:13 +01002405 kctl->id.index = idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002406 kctl->private_value = nid;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01002407 err = snd_hda_ctl_add(codec, nid, kctl);
Takashi Iwai0ba21762007-04-16 11:29:14 +02002408 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002409 return err;
2410 }
Takashi Iwai0ba21762007-04-16 11:29:14 +02002411 codec->spdif_ctls =
Andrew Paprocki3982d172007-12-19 12:13:44 +01002412 snd_hda_codec_read(codec, nid, 0,
2413 AC_VERB_GET_DIGI_CONVERT_1, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002414 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls);
2415 return 0;
2416}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002417EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418
2419/*
Takashi Iwai9a081602008-02-12 18:37:26 +01002420 * SPDIF sharing with analog output
2421 */
2422static int spdif_share_sw_get(struct snd_kcontrol *kcontrol,
2423 struct snd_ctl_elem_value *ucontrol)
2424{
2425 struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
2426 ucontrol->value.integer.value[0] = mout->share_spdif;
2427 return 0;
2428}
2429
2430static int spdif_share_sw_put(struct snd_kcontrol *kcontrol,
2431 struct snd_ctl_elem_value *ucontrol)
2432{
2433 struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
2434 mout->share_spdif = !!ucontrol->value.integer.value[0];
2435 return 0;
2436}
2437
2438static struct snd_kcontrol_new spdif_share_sw = {
2439 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2440 .name = "IEC958 Default PCM Playback Switch",
2441 .info = snd_ctl_boolean_mono_info,
2442 .get = spdif_share_sw_get,
2443 .put = spdif_share_sw_put,
2444};
2445
Takashi Iwaid5191e52009-11-16 14:58:17 +01002446/**
2447 * snd_hda_create_spdif_share_sw - create Default PCM switch
2448 * @codec: the HDA codec
2449 * @mout: multi-out instance
2450 */
Takashi Iwai9a081602008-02-12 18:37:26 +01002451int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
2452 struct hda_multi_out *mout)
2453{
2454 if (!mout->dig_out_nid)
2455 return 0;
2456 /* ATTENTION: here mout is passed as private_data, instead of codec */
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01002457 return snd_hda_ctl_add(codec, mout->dig_out_nid,
2458 snd_ctl_new1(&spdif_share_sw, mout));
Takashi Iwai9a081602008-02-12 18:37:26 +01002459}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002460EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw);
Takashi Iwai9a081602008-02-12 18:37:26 +01002461
2462/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002463 * SPDIF input
2464 */
2465
2466#define snd_hda_spdif_in_switch_info snd_hda_spdif_out_switch_info
2467
Takashi Iwai0ba21762007-04-16 11:29:14 +02002468static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol,
2469 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002470{
2471 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2472
2473 ucontrol->value.integer.value[0] = codec->spdif_in_enable;
2474 return 0;
2475}
2476
Takashi Iwai0ba21762007-04-16 11:29:14 +02002477static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
2478 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002479{
2480 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2481 hda_nid_t nid = kcontrol->private_value;
2482 unsigned int val = !!ucontrol->value.integer.value[0];
2483 int change;
2484
Ingo Molnar62932df2006-01-16 16:34:20 +01002485 mutex_lock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002486 change = codec->spdif_in_enable != val;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02002487 if (change) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002488 codec->spdif_in_enable = val;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02002489 snd_hda_codec_write_cache(codec, nid, 0,
2490 AC_VERB_SET_DIGI_CONVERT_1, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002491 }
Ingo Molnar62932df2006-01-16 16:34:20 +01002492 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002493 return change;
2494}
2495
Takashi Iwai0ba21762007-04-16 11:29:14 +02002496static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
2497 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002498{
2499 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2500 hda_nid_t nid = kcontrol->private_value;
2501 unsigned short val;
2502 unsigned int sbits;
2503
Andrew Paprocki3982d172007-12-19 12:13:44 +01002504 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT_1, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002505 sbits = convert_to_spdif_status(val);
2506 ucontrol->value.iec958.status[0] = sbits;
2507 ucontrol->value.iec958.status[1] = sbits >> 8;
2508 ucontrol->value.iec958.status[2] = sbits >> 16;
2509 ucontrol->value.iec958.status[3] = sbits >> 24;
2510 return 0;
2511}
2512
Takashi Iwaic8b6bf92005-11-17 14:57:47 +01002513static struct snd_kcontrol_new dig_in_ctls[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002514 {
2515 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2516 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
2517 .info = snd_hda_spdif_in_switch_info,
2518 .get = snd_hda_spdif_in_switch_get,
2519 .put = snd_hda_spdif_in_switch_put,
2520 },
2521 {
2522 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2523 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2524 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
2525 .info = snd_hda_spdif_mask_info,
2526 .get = snd_hda_spdif_in_status_get,
2527 },
2528 { } /* end */
2529};
2530
2531/**
2532 * snd_hda_create_spdif_in_ctls - create Input SPDIF-related controls
2533 * @codec: the HDA codec
2534 * @nid: audio in widget NID
2535 *
2536 * Creates controls related with the SPDIF input.
2537 * Called from each patch supporting the SPDIF in.
2538 *
2539 * Returns 0 if successful, or a negative error code.
2540 */
Takashi Iwai12f288b2007-08-02 15:51:59 +02002541int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002542{
2543 int err;
Takashi Iwaic8b6bf92005-11-17 14:57:47 +01002544 struct snd_kcontrol *kctl;
2545 struct snd_kcontrol_new *dig_mix;
Takashi Iwai09f99702008-02-04 12:31:13 +01002546 int idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002547
Takashi Iwai09f99702008-02-04 12:31:13 +01002548 for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
2549 if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch",
2550 idx))
2551 break;
2552 }
2553 if (idx >= SPDIF_MAX_IDX) {
2554 printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
2555 return -EBUSY;
2556 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002557 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
2558 kctl = snd_ctl_new1(dig_mix, codec);
Takashi Iwaic8dcdf82009-02-06 16:21:20 +01002559 if (!kctl)
2560 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002561 kctl->private_value = nid;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01002562 err = snd_hda_ctl_add(codec, nid, kctl);
Takashi Iwai0ba21762007-04-16 11:29:14 +02002563 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002564 return err;
2565 }
Takashi Iwai0ba21762007-04-16 11:29:14 +02002566 codec->spdif_in_enable =
Andrew Paprocki3982d172007-12-19 12:13:44 +01002567 snd_hda_codec_read(codec, nid, 0,
2568 AC_VERB_GET_DIGI_CONVERT_1, 0) &
Takashi Iwai0ba21762007-04-16 11:29:14 +02002569 AC_DIG1_ENABLE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002570 return 0;
2571}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002572EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002573
Takashi Iwaicb53c622007-08-10 17:21:45 +02002574#ifdef SND_HDA_NEEDS_RESUME
Takashi Iwai82beb8f2007-08-10 17:09:26 +02002575/*
2576 * command cache
2577 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002579/* build a 32bit cache key with the widget id and the command parameter */
2580#define build_cmd_cache_key(nid, verb) ((verb << 8) | nid)
2581#define get_cmd_cache_nid(key) ((key) & 0xff)
2582#define get_cmd_cache_cmd(key) (((key) >> 8) & 0xffff)
2583
2584/**
2585 * snd_hda_codec_write_cache - send a single command with caching
2586 * @codec: the HDA codec
2587 * @nid: NID to send the command
2588 * @direct: direct flag
2589 * @verb: the verb to send
2590 * @parm: the parameter for the verb
2591 *
2592 * Send a single command without waiting for response.
2593 *
2594 * Returns 0 if successful, or a negative error code.
2595 */
2596int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
2597 int direct, unsigned int verb, unsigned int parm)
2598{
Takashi Iwaiaa2936f2009-05-26 16:07:57 +02002599 int err = snd_hda_codec_write(codec, nid, direct, verb, parm);
2600 struct hda_cache_head *c;
2601 u32 key;
Takashi Iwai33fa35e2008-11-06 16:50:40 +01002602
Takashi Iwaiaa2936f2009-05-26 16:07:57 +02002603 if (err < 0)
2604 return err;
2605 /* parm may contain the verb stuff for get/set amp */
2606 verb = verb | (parm >> 8);
2607 parm &= 0xff;
2608 key = build_cmd_cache_key(nid, verb);
2609 mutex_lock(&codec->bus->cmd_mutex);
2610 c = get_alloc_hash(&codec->cmd_cache, key);
2611 if (c)
2612 c->val = parm;
2613 mutex_unlock(&codec->bus->cmd_mutex);
2614 return 0;
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002615}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002616EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002617
Takashi Iwaid5191e52009-11-16 14:58:17 +01002618/**
2619 * snd_hda_codec_resume_cache - Resume the all commands from the cache
2620 * @codec: HD-audio codec
2621 *
2622 * Execute all verbs recorded in the command caches to resume.
2623 */
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002624void snd_hda_codec_resume_cache(struct hda_codec *codec)
2625{
Takashi Iwai603c4012008-07-30 15:01:44 +02002626 struct hda_cache_head *buffer = codec->cmd_cache.buf.list;
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002627 int i;
2628
Takashi Iwai603c4012008-07-30 15:01:44 +02002629 for (i = 0; i < codec->cmd_cache.buf.used; i++, buffer++) {
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002630 u32 key = buffer->key;
2631 if (!key)
2632 continue;
2633 snd_hda_codec_write(codec, get_cmd_cache_nid(key), 0,
2634 get_cmd_cache_cmd(key), buffer->val);
2635 }
2636}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002637EXPORT_SYMBOL_HDA(snd_hda_codec_resume_cache);
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002638
2639/**
2640 * snd_hda_sequence_write_cache - sequence writes with caching
2641 * @codec: the HDA codec
2642 * @seq: VERB array to send
2643 *
2644 * Send the commands sequentially from the given array.
2645 * Thte commands are recorded on cache for power-save and resume.
2646 * The array must be terminated with NID=0.
2647 */
2648void snd_hda_sequence_write_cache(struct hda_codec *codec,
2649 const struct hda_verb *seq)
2650{
2651 for (; seq->nid; seq++)
2652 snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
2653 seq->param);
2654}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002655EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002656#endif /* SND_HDA_NEEDS_RESUME */
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002657
Takashi Iwai54d17402005-11-21 16:33:22 +01002658/*
2659 * set power state of the codec
2660 */
2661static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2662 unsigned int power_state)
2663{
Takashi Iwaicb53c622007-08-10 17:21:45 +02002664 hda_nid_t nid;
2665 int i;
Takashi Iwai54d17402005-11-21 16:33:22 +01002666
Takashi Iwai05ff7e12009-07-22 12:39:24 +02002667 /* this delay seems necessary to avoid click noise at power-down */
2668 if (power_state == AC_PWRST_D3)
2669 msleep(100);
2670 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
Takashi Iwai54d17402005-11-21 16:33:22 +01002671 power_state);
Takashi Iwai05ff7e12009-07-22 12:39:24 +02002672 /* partial workaround for "azx_get_response timeout" */
2673 if (power_state == AC_PWRST_D0)
2674 msleep(10);
Takashi Iwai54d17402005-11-21 16:33:22 +01002675
Takashi Iwaicb53c622007-08-10 17:21:45 +02002676 nid = codec->start_nid;
2677 for (i = 0; i < codec->num_nodes; i++, nid++) {
Takashi Iwai7eba5c92007-11-14 14:53:42 +01002678 unsigned int wcaps = get_wcaps(codec, nid);
2679 if (wcaps & AC_WCAP_POWER) {
Takashi Iwaia22d5432009-07-27 12:54:26 +02002680 unsigned int wid_type = get_wcaps_type(wcaps);
Takashi Iwaia3b48c82009-04-21 13:37:29 +02002681 if (power_state == AC_PWRST_D3 &&
2682 wid_type == AC_WID_PIN) {
Takashi Iwai7eba5c92007-11-14 14:53:42 +01002683 unsigned int pincap;
2684 /*
2685 * don't power down the widget if it controls
2686 * eapd and EAPD_BTLENABLE is set.
2687 */
Takashi Iwai14bafe32009-03-23 16:35:39 +01002688 pincap = snd_hda_query_pin_caps(codec, nid);
Takashi Iwai7eba5c92007-11-14 14:53:42 +01002689 if (pincap & AC_PINCAP_EAPD) {
2690 int eapd = snd_hda_codec_read(codec,
2691 nid, 0,
2692 AC_VERB_GET_EAPD_BTLENABLE, 0);
2693 eapd &= 0x02;
Takashi Iwaia3b48c82009-04-21 13:37:29 +02002694 if (eapd)
Takashi Iwai7eba5c92007-11-14 14:53:42 +01002695 continue;
2696 }
Takashi Iwai1194b5b2007-10-10 10:04:26 +02002697 }
Takashi Iwai54d17402005-11-21 16:33:22 +01002698 snd_hda_codec_write(codec, nid, 0,
2699 AC_VERB_SET_POWER_STATE,
2700 power_state);
Takashi Iwai1194b5b2007-10-10 10:04:26 +02002701 }
Takashi Iwai54d17402005-11-21 16:33:22 +01002702 }
2703
Takashi Iwaicb53c622007-08-10 17:21:45 +02002704 if (power_state == AC_PWRST_D0) {
2705 unsigned long end_time;
2706 int state;
Takashi Iwai54d17402005-11-21 16:33:22 +01002707 msleep(10);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002708 /* wait until the codec reachs to D0 */
2709 end_time = jiffies + msecs_to_jiffies(500);
2710 do {
2711 state = snd_hda_codec_read(codec, fg, 0,
2712 AC_VERB_GET_POWER_STATE, 0);
2713 if (state == power_state)
2714 break;
2715 msleep(1);
2716 } while (time_after_eq(end_time, jiffies));
2717 }
Takashi Iwai54d17402005-11-21 16:33:22 +01002718}
2719
Takashi Iwai11aeff02008-07-30 15:01:46 +02002720#ifdef CONFIG_SND_HDA_HWDEP
2721/* execute additional init verbs */
2722static void hda_exec_init_verbs(struct hda_codec *codec)
2723{
2724 if (codec->init_verbs.list)
2725 snd_hda_sequence_write(codec, codec->init_verbs.list);
2726}
2727#else
2728static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
2729#endif
2730
Takashi Iwaicb53c622007-08-10 17:21:45 +02002731#ifdef SND_HDA_NEEDS_RESUME
2732/*
2733 * call suspend and power-down; used both from PM and power-save
2734 */
2735static void hda_call_codec_suspend(struct hda_codec *codec)
2736{
2737 if (codec->patch_ops.suspend)
2738 codec->patch_ops.suspend(codec, PMSG_SUSPEND);
2739 hda_set_power_state(codec,
2740 codec->afg ? codec->afg : codec->mfg,
2741 AC_PWRST_D3);
2742#ifdef CONFIG_SND_HDA_POWER_SAVE
Takashi Iwaia2f63092009-11-11 09:34:25 +01002743 snd_hda_update_power_acct(codec);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002744 cancel_delayed_work(&codec->power_work);
Takashi Iwai95e99fd2007-08-13 15:29:04 +02002745 codec->power_on = 0;
Takashi Iwaia221e282007-08-16 16:35:33 +02002746 codec->power_transition = 0;
Takashi Iwaia2f63092009-11-11 09:34:25 +01002747 codec->power_jiffies = jiffies;
Takashi Iwaicb53c622007-08-10 17:21:45 +02002748#endif
2749}
2750
2751/*
2752 * kick up codec; used both from PM and power-save
2753 */
2754static void hda_call_codec_resume(struct hda_codec *codec)
2755{
2756 hda_set_power_state(codec,
2757 codec->afg ? codec->afg : codec->mfg,
2758 AC_PWRST_D0);
Takashi Iwai3be14142009-02-20 14:11:16 +01002759 restore_pincfgs(codec); /* restore all current pin configs */
Takashi Iwai11aeff02008-07-30 15:01:46 +02002760 hda_exec_init_verbs(codec);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002761 if (codec->patch_ops.resume)
2762 codec->patch_ops.resume(codec);
2763 else {
Takashi Iwai9d99f312007-08-14 15:15:52 +02002764 if (codec->patch_ops.init)
2765 codec->patch_ops.init(codec);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002766 snd_hda_codec_resume_amp(codec);
2767 snd_hda_codec_resume_cache(codec);
2768 }
2769}
2770#endif /* SND_HDA_NEEDS_RESUME */
2771
Takashi Iwai54d17402005-11-21 16:33:22 +01002772
Linus Torvalds1da177e2005-04-16 15:20:36 -07002773/**
2774 * snd_hda_build_controls - build mixer controls
2775 * @bus: the BUS
2776 *
2777 * Creates mixer controls for each codec included in the bus.
2778 *
2779 * Returns 0 if successful, otherwise a negative error code.
2780 */
Takashi Iwai1289e9e2008-11-27 15:47:11 +01002781int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002782{
Takashi Iwai0ba21762007-04-16 11:29:14 +02002783 struct hda_codec *codec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002784
Takashi Iwai0ba21762007-04-16 11:29:14 +02002785 list_for_each_entry(codec, &bus->codec_list, list) {
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02002786 int err = snd_hda_codec_build_controls(codec);
Takashi Iwaif93d4612009-03-02 10:44:15 +01002787 if (err < 0) {
2788 printk(KERN_ERR "hda_codec: cannot build controls"
2789 "for #%d (error %d)\n", codec->addr, err);
2790 err = snd_hda_codec_reset(codec);
2791 if (err < 0) {
2792 printk(KERN_ERR
2793 "hda_codec: cannot revert codec\n");
2794 return err;
2795 }
2796 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002797 }
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02002798 return 0;
2799}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002800EXPORT_SYMBOL_HDA(snd_hda_build_controls);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02002802int snd_hda_codec_build_controls(struct hda_codec *codec)
2803{
2804 int err = 0;
Takashi Iwai11aeff02008-07-30 15:01:46 +02002805 hda_exec_init_verbs(codec);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02002806 /* continue to initialize... */
2807 if (codec->patch_ops.init)
2808 err = codec->patch_ops.init(codec);
2809 if (!err && codec->patch_ops.build_controls)
2810 err = codec->patch_ops.build_controls(codec);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02002811 if (err < 0)
2812 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002813 return 0;
2814}
2815
Linus Torvalds1da177e2005-04-16 15:20:36 -07002816/*
2817 * stream formats
2818 */
Takashi Iwaibefdf312005-08-22 13:57:55 +02002819struct hda_rate_tbl {
2820 unsigned int hz;
2821 unsigned int alsa_bits;
2822 unsigned int hda_fmt;
2823};
2824
2825static struct hda_rate_tbl rate_bits[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002826 /* rate in Hz, ALSA rate bitmask, HDA format value */
Nicolas Graziano9d8f53f2005-08-22 13:47:16 +02002827
2828 /* autodetected value used in snd_hda_query_supported_pcm */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002829 { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */
2830 { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */
2831 { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */
2832 { 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */
2833 { 32000, SNDRV_PCM_RATE_32000, 0x0a00 }, /* 2/3 x 48 */
2834 { 44100, SNDRV_PCM_RATE_44100, 0x4000 }, /* 44 */
2835 { 48000, SNDRV_PCM_RATE_48000, 0x0000 }, /* 48 */
2836 { 88200, SNDRV_PCM_RATE_88200, 0x4800 }, /* 2 x 44 */
2837 { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */
2838 { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */
2839 { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */
Takashi Iwaia961f9f2007-04-12 13:08:09 +02002840#define AC_PAR_PCM_RATE_BITS 11
2841 /* up to bits 10, 384kHZ isn't supported properly */
2842
2843 /* not autodetected value */
2844 { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */
Nicolas Graziano9d8f53f2005-08-22 13:47:16 +02002845
Takashi Iwaibefdf312005-08-22 13:57:55 +02002846 { 0 } /* terminator */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002847};
2848
2849/**
2850 * snd_hda_calc_stream_format - calculate format bitset
2851 * @rate: the sample rate
2852 * @channels: the number of channels
2853 * @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
2854 * @maxbps: the max. bps
2855 *
2856 * Calculate the format bitset from the given rate, channels and th PCM format.
2857 *
2858 * Return zero if invalid.
2859 */
2860unsigned int snd_hda_calc_stream_format(unsigned int rate,
2861 unsigned int channels,
2862 unsigned int format,
2863 unsigned int maxbps)
2864{
2865 int i;
2866 unsigned int val = 0;
2867
Takashi Iwaibefdf312005-08-22 13:57:55 +02002868 for (i = 0; rate_bits[i].hz; i++)
2869 if (rate_bits[i].hz == rate) {
2870 val = rate_bits[i].hda_fmt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002871 break;
2872 }
Takashi Iwai0ba21762007-04-16 11:29:14 +02002873 if (!rate_bits[i].hz) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002874 snd_printdd("invalid rate %d\n", rate);
2875 return 0;
2876 }
2877
2878 if (channels == 0 || channels > 8) {
2879 snd_printdd("invalid channels %d\n", channels);
2880 return 0;
2881 }
2882 val |= channels - 1;
2883
2884 switch (snd_pcm_format_width(format)) {
2885 case 8: val |= 0x00; break;
2886 case 16: val |= 0x10; break;
2887 case 20:
2888 case 24:
2889 case 32:
Takashi Iwaib0bb3aa2009-07-03 23:25:37 +02002890 if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002891 val |= 0x40;
2892 else if (maxbps >= 24)
2893 val |= 0x30;
2894 else
2895 val |= 0x20;
2896 break;
2897 default:
Takashi Iwai0ba21762007-04-16 11:29:14 +02002898 snd_printdd("invalid format width %d\n",
2899 snd_pcm_format_width(format));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002900 return 0;
2901 }
2902
2903 return val;
2904}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002905EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002906
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01002907static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid)
2908{
2909 unsigned int val = 0;
2910 if (nid != codec->afg &&
2911 (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD))
2912 val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
2913 if (!val || val == -1)
2914 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
2915 if (!val || val == -1)
2916 return 0;
2917 return val;
2918}
2919
2920static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid)
2921{
2922 return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid),
2923 get_pcm_param);
2924}
2925
2926static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid)
2927{
2928 unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
2929 if (!streams || streams == -1)
2930 streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
2931 if (!streams || streams == -1)
2932 return 0;
2933 return streams;
2934}
2935
2936static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
2937{
2938 return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid),
2939 get_stream_param);
2940}
2941
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942/**
2943 * snd_hda_query_supported_pcm - query the supported PCM rates and formats
2944 * @codec: the HDA codec
2945 * @nid: NID to query
2946 * @ratesp: the pointer to store the detected rate bitflags
2947 * @formatsp: the pointer to store the detected formats
2948 * @bpsp: the pointer to store the detected format widths
2949 *
2950 * Queries the supported PCM rates and formats. The NULL @ratesp, @formatsp
2951 * or @bsps argument is ignored.
2952 *
2953 * Returns 0 if successful, otherwise a negative error code.
2954 */
Takashi Iwai986862bd2008-11-27 12:40:13 +01002955static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002956 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
2957{
Jaroslav Kyselaee504712009-03-17 14:30:31 +01002958 unsigned int i, val, wcaps;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002959
Jaroslav Kyselaee504712009-03-17 14:30:31 +01002960 wcaps = get_wcaps(codec, nid);
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01002961 val = query_pcm_param(codec, nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002962
2963 if (ratesp) {
2964 u32 rates = 0;
Takashi Iwaia961f9f2007-04-12 13:08:09 +02002965 for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002966 if (val & (1 << i))
Takashi Iwaibefdf312005-08-22 13:57:55 +02002967 rates |= rate_bits[i].alsa_bits;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002968 }
Jaroslav Kyselaee504712009-03-17 14:30:31 +01002969 if (rates == 0) {
2970 snd_printk(KERN_ERR "hda_codec: rates == 0 "
2971 "(nid=0x%x, val=0x%x, ovrd=%i)\n",
2972 nid, val,
2973 (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0);
2974 return -EIO;
2975 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002976 *ratesp = rates;
2977 }
2978
2979 if (formatsp || bpsp) {
2980 u64 formats = 0;
Jaroslav Kyselaee504712009-03-17 14:30:31 +01002981 unsigned int streams, bps;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002982
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01002983 streams = query_stream_param(codec, nid);
2984 if (!streams)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002985 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002986
2987 bps = 0;
2988 if (streams & AC_SUPFMT_PCM) {
2989 if (val & AC_SUPPCM_BITS_8) {
2990 formats |= SNDRV_PCM_FMTBIT_U8;
2991 bps = 8;
2992 }
2993 if (val & AC_SUPPCM_BITS_16) {
2994 formats |= SNDRV_PCM_FMTBIT_S16_LE;
2995 bps = 16;
2996 }
2997 if (wcaps & AC_WCAP_DIGITAL) {
2998 if (val & AC_SUPPCM_BITS_32)
2999 formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
3000 if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24))
3001 formats |= SNDRV_PCM_FMTBIT_S32_LE;
3002 if (val & AC_SUPPCM_BITS_24)
3003 bps = 24;
3004 else if (val & AC_SUPPCM_BITS_20)
3005 bps = 20;
Takashi Iwai0ba21762007-04-16 11:29:14 +02003006 } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
3007 AC_SUPPCM_BITS_32)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003008 formats |= SNDRV_PCM_FMTBIT_S32_LE;
3009 if (val & AC_SUPPCM_BITS_32)
3010 bps = 32;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003011 else if (val & AC_SUPPCM_BITS_24)
3012 bps = 24;
Nicolas Graziano33ef76512006-09-19 14:23:14 +02003013 else if (val & AC_SUPPCM_BITS_20)
3014 bps = 20;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003015 }
3016 }
Takashi Iwaib5025c52009-07-01 18:05:27 +02003017 if (streams & AC_SUPFMT_FLOAT32) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
Takashi Iwaib0bb3aa2009-07-03 23:25:37 +02003019 if (!bps)
3020 bps = 32;
Takashi Iwaib5025c52009-07-01 18:05:27 +02003021 }
3022 if (streams == AC_SUPFMT_AC3) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02003023 /* should be exclusive */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003024 /* temporary hack: we have still no proper support
3025 * for the direct AC3 stream...
3026 */
3027 formats |= SNDRV_PCM_FMTBIT_U8;
3028 bps = 8;
3029 }
Jaroslav Kyselaee504712009-03-17 14:30:31 +01003030 if (formats == 0) {
3031 snd_printk(KERN_ERR "hda_codec: formats == 0 "
3032 "(nid=0x%x, val=0x%x, ovrd=%i, "
3033 "streams=0x%x)\n",
3034 nid, val,
3035 (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0,
3036 streams);
3037 return -EIO;
3038 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003039 if (formatsp)
3040 *formatsp = formats;
3041 if (bpsp)
3042 *bpsp = bps;
3043 }
3044
3045 return 0;
3046}
3047
3048/**
Takashi Iwaid5191e52009-11-16 14:58:17 +01003049 * snd_hda_is_supported_format - Check the validity of the format
3050 * @codec: HD-audio codec
3051 * @nid: NID to check
3052 * @format: the HD-audio format value to check
3053 *
3054 * Check whether the given node supports the format value.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003055 *
3056 * Returns 1 if supported, 0 if not.
3057 */
3058int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
3059 unsigned int format)
3060{
3061 int i;
3062 unsigned int val = 0, rate, stream;
3063
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01003064 val = query_pcm_param(codec, nid);
3065 if (!val)
3066 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003067
3068 rate = format & 0xff00;
Takashi Iwaia961f9f2007-04-12 13:08:09 +02003069 for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
Takashi Iwaibefdf312005-08-22 13:57:55 +02003070 if (rate_bits[i].hda_fmt == rate) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003071 if (val & (1 << i))
3072 break;
3073 return 0;
3074 }
Takashi Iwaia961f9f2007-04-12 13:08:09 +02003075 if (i >= AC_PAR_PCM_RATE_BITS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003076 return 0;
3077
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01003078 stream = query_stream_param(codec, nid);
3079 if (!stream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003080 return 0;
3081
3082 if (stream & AC_SUPFMT_PCM) {
3083 switch (format & 0xf0) {
3084 case 0x00:
Takashi Iwai0ba21762007-04-16 11:29:14 +02003085 if (!(val & AC_SUPPCM_BITS_8))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003086 return 0;
3087 break;
3088 case 0x10:
Takashi Iwai0ba21762007-04-16 11:29:14 +02003089 if (!(val & AC_SUPPCM_BITS_16))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003090 return 0;
3091 break;
3092 case 0x20:
Takashi Iwai0ba21762007-04-16 11:29:14 +02003093 if (!(val & AC_SUPPCM_BITS_20))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003094 return 0;
3095 break;
3096 case 0x30:
Takashi Iwai0ba21762007-04-16 11:29:14 +02003097 if (!(val & AC_SUPPCM_BITS_24))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003098 return 0;
3099 break;
3100 case 0x40:
Takashi Iwai0ba21762007-04-16 11:29:14 +02003101 if (!(val & AC_SUPPCM_BITS_32))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003102 return 0;
3103 break;
3104 default:
3105 return 0;
3106 }
3107 } else {
3108 /* FIXME: check for float32 and AC3? */
3109 }
3110
3111 return 1;
3112}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003113EXPORT_SYMBOL_HDA(snd_hda_is_supported_format);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003114
3115/*
3116 * PCM stuff
3117 */
3118static int hda_pcm_default_open_close(struct hda_pcm_stream *hinfo,
3119 struct hda_codec *codec,
Takashi Iwaic8b6bf92005-11-17 14:57:47 +01003120 struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003121{
3122 return 0;
3123}
3124
3125static int hda_pcm_default_prepare(struct hda_pcm_stream *hinfo,
3126 struct hda_codec *codec,
3127 unsigned int stream_tag,
3128 unsigned int format,
Takashi Iwaic8b6bf92005-11-17 14:57:47 +01003129 struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130{
3131 snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
3132 return 0;
3133}
3134
3135static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
3136 struct hda_codec *codec,
Takashi Iwaic8b6bf92005-11-17 14:57:47 +01003137 struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138{
Takashi Iwai888afa12008-03-18 09:57:50 +01003139 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003140 return 0;
3141}
3142
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02003143static int set_pcm_default_values(struct hda_codec *codec,
3144 struct hda_pcm_stream *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003145{
Jaroslav Kyselaee504712009-03-17 14:30:31 +01003146 int err;
3147
Takashi Iwai0ba21762007-04-16 11:29:14 +02003148 /* query support PCM information from the given NID */
3149 if (info->nid && (!info->rates || !info->formats)) {
Jaroslav Kyselaee504712009-03-17 14:30:31 +01003150 err = snd_hda_query_supported_pcm(codec, info->nid,
Takashi Iwai0ba21762007-04-16 11:29:14 +02003151 info->rates ? NULL : &info->rates,
3152 info->formats ? NULL : &info->formats,
3153 info->maxbps ? NULL : &info->maxbps);
Jaroslav Kyselaee504712009-03-17 14:30:31 +01003154 if (err < 0)
3155 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003156 }
3157 if (info->ops.open == NULL)
3158 info->ops.open = hda_pcm_default_open_close;
3159 if (info->ops.close == NULL)
3160 info->ops.close = hda_pcm_default_open_close;
3161 if (info->ops.prepare == NULL) {
Takashi Iwaida3cec32008-08-08 17:12:14 +02003162 if (snd_BUG_ON(!info->nid))
3163 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003164 info->ops.prepare = hda_pcm_default_prepare;
3165 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003166 if (info->ops.cleanup == NULL) {
Takashi Iwaida3cec32008-08-08 17:12:14 +02003167 if (snd_BUG_ON(!info->nid))
3168 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003169 info->ops.cleanup = hda_pcm_default_cleanup;
3170 }
3171 return 0;
3172}
3173
Takashi Iwaid5191e52009-11-16 14:58:17 +01003174/* global */
Jaroslav Kyselae3303232009-11-10 14:53:02 +01003175const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
3176 "Audio", "SPDIF", "HDMI", "Modem"
3177};
3178
Takashi Iwai176d5332008-07-30 15:01:44 +02003179/*
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003180 * get the empty PCM device number to assign
3181 */
3182static int get_empty_pcm_device(struct hda_bus *bus, int type)
3183{
Wu Fengguangf5d6def52009-10-30 11:38:26 +01003184 /* audio device indices; not linear to keep compatibility */
3185 static int audio_idx[HDA_PCM_NTYPES][5] = {
3186 [HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 },
3187 [HDA_PCM_TYPE_SPDIF] = { 1, -1 },
Wu Fengguang92608ba2009-10-30 11:40:03 +01003188 [HDA_PCM_TYPE_HDMI] = { 3, 7, 8, 9, -1 },
Wu Fengguangf5d6def52009-10-30 11:38:26 +01003189 [HDA_PCM_TYPE_MODEM] = { 6, -1 },
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003190 };
Wu Fengguangf5d6def52009-10-30 11:38:26 +01003191 int i;
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003192
Wu Fengguangf5d6def52009-10-30 11:38:26 +01003193 if (type >= HDA_PCM_NTYPES) {
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003194 snd_printk(KERN_WARNING "Invalid PCM type %d\n", type);
3195 return -EINVAL;
3196 }
Wu Fengguangf5d6def52009-10-30 11:38:26 +01003197
3198 for (i = 0; audio_idx[type][i] >= 0 ; i++)
3199 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
3200 return audio_idx[type][i];
3201
Jaroslav Kyselae3303232009-11-10 14:53:02 +01003202 snd_printk(KERN_WARNING "Too many %s devices\n", snd_hda_pcm_type_name[type]);
Wu Fengguangf5d6def52009-10-30 11:38:26 +01003203 return -EAGAIN;
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003204}
3205
3206/*
Takashi Iwai176d5332008-07-30 15:01:44 +02003207 * attach a new PCM stream
3208 */
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003209static int snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
Takashi Iwai176d5332008-07-30 15:01:44 +02003210{
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003211 struct hda_bus *bus = codec->bus;
Takashi Iwai176d5332008-07-30 15:01:44 +02003212 struct hda_pcm_stream *info;
3213 int stream, err;
3214
Takashi Iwaib91f0802008-11-04 08:43:08 +01003215 if (snd_BUG_ON(!pcm->name))
Takashi Iwai176d5332008-07-30 15:01:44 +02003216 return -EINVAL;
3217 for (stream = 0; stream < 2; stream++) {
3218 info = &pcm->stream[stream];
3219 if (info->substreams) {
3220 err = set_pcm_default_values(codec, info);
3221 if (err < 0)
3222 return err;
3223 }
3224 }
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003225 return bus->ops.attach_pcm(bus, codec, pcm);
Takashi Iwai176d5332008-07-30 15:01:44 +02003226}
3227
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003228/* assign all PCMs of the given codec */
3229int snd_hda_codec_build_pcms(struct hda_codec *codec)
3230{
3231 unsigned int pcm;
3232 int err;
3233
3234 if (!codec->num_pcms) {
3235 if (!codec->patch_ops.build_pcms)
3236 return 0;
3237 err = codec->patch_ops.build_pcms(codec);
Takashi Iwai6e655bf2009-03-02 10:46:03 +01003238 if (err < 0) {
3239 printk(KERN_ERR "hda_codec: cannot build PCMs"
3240 "for #%d (error %d)\n", codec->addr, err);
3241 err = snd_hda_codec_reset(codec);
3242 if (err < 0) {
3243 printk(KERN_ERR
3244 "hda_codec: cannot revert codec\n");
3245 return err;
3246 }
3247 }
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003248 }
3249 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
3250 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
3251 int dev;
3252
3253 if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
Takashi Iwai41b5b012009-01-20 18:21:23 +01003254 continue; /* no substreams assigned */
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003255
3256 if (!cpcm->pcm) {
3257 dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type);
3258 if (dev < 0)
Takashi Iwai6e655bf2009-03-02 10:46:03 +01003259 continue; /* no fatal error */
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003260 cpcm->device = dev;
3261 err = snd_hda_attach_pcm(codec, cpcm);
Takashi Iwai6e655bf2009-03-02 10:46:03 +01003262 if (err < 0) {
3263 printk(KERN_ERR "hda_codec: cannot attach "
3264 "PCM stream %d for codec #%d\n",
3265 dev, codec->addr);
3266 continue; /* no fatal error */
3267 }
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003268 }
3269 }
3270 return 0;
3271}
3272
Linus Torvalds1da177e2005-04-16 15:20:36 -07003273/**
3274 * snd_hda_build_pcms - build PCM information
3275 * @bus: the BUS
3276 *
3277 * Create PCM information for each codec included in the bus.
3278 *
3279 * The build_pcms codec patch is requested to set up codec->num_pcms and
3280 * codec->pcm_info properly. The array is referred by the top-level driver
3281 * to create its PCM instances.
3282 * The allocated codec->pcm_info should be released in codec->patch_ops.free
3283 * callback.
3284 *
3285 * At least, substreams, channels_min and channels_max must be filled for
3286 * each stream. substreams = 0 indicates that the stream doesn't exist.
3287 * When rates and/or formats are zero, the supported values are queried
3288 * from the given nid. The nid is used also by the default ops.prepare
3289 * and ops.cleanup callbacks.
3290 *
3291 * The driver needs to call ops.open in its open callback. Similarly,
3292 * ops.close is supposed to be called in the close callback.
3293 * ops.prepare should be called in the prepare or hw_params callback
3294 * with the proper parameters for set up.
3295 * ops.cleanup should be called in hw_free for clean up of streams.
3296 *
3297 * This function returns 0 if successfull, or a negative error code.
3298 */
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003299int __devinit snd_hda_build_pcms(struct hda_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003300{
Takashi Iwai0ba21762007-04-16 11:29:14 +02003301 struct hda_codec *codec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003302
Takashi Iwai0ba21762007-04-16 11:29:14 +02003303 list_for_each_entry(codec, &bus->codec_list, list) {
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003304 int err = snd_hda_codec_build_pcms(codec);
3305 if (err < 0)
3306 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003307 }
3308 return 0;
3309}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003310EXPORT_SYMBOL_HDA(snd_hda_build_pcms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003311
Linus Torvalds1da177e2005-04-16 15:20:36 -07003312/**
3313 * snd_hda_check_board_config - compare the current codec with the config table
3314 * @codec: the HDA codec
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003315 * @num_configs: number of config enums
3316 * @models: array of model name strings
Linus Torvalds1da177e2005-04-16 15:20:36 -07003317 * @tbl: configuration table, terminated by null entries
3318 *
3319 * Compares the modelname or PCI subsystem id of the current codec with the
3320 * given configuration table. If a matching entry is found, returns its
3321 * config value (supposed to be 0 or positive).
3322 *
3323 * If no entries are matching, the function returns a negative value.
3324 */
Takashi Iwai12f288b2007-08-02 15:51:59 +02003325int snd_hda_check_board_config(struct hda_codec *codec,
3326 int num_configs, const char **models,
3327 const struct snd_pci_quirk *tbl)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003328{
Takashi Iwaif44ac832008-07-30 15:01:45 +02003329 if (codec->modelname && models) {
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003330 int i;
3331 for (i = 0; i < num_configs; i++) {
3332 if (models[i] &&
Takashi Iwaif44ac832008-07-30 15:01:45 +02003333 !strcmp(codec->modelname, models[i])) {
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003334 snd_printd(KERN_INFO "hda_codec: model '%s' is "
3335 "selected\n", models[i]);
3336 return i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003337 }
3338 }
3339 }
3340
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003341 if (!codec->bus->pci || !tbl)
3342 return -1;
3343
3344 tbl = snd_pci_quirk_lookup(codec->bus->pci, tbl);
3345 if (!tbl)
3346 return -1;
3347 if (tbl->value >= 0 && tbl->value < num_configs) {
Takashi Iwai62cf8722008-05-20 12:15:15 +02003348#ifdef CONFIG_SND_DEBUG_VERBOSE
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003349 char tmp[10];
3350 const char *model = NULL;
3351 if (models)
3352 model = models[tbl->value];
3353 if (!model) {
3354 sprintf(tmp, "#%d", tbl->value);
3355 model = tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003356 }
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003357 snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
3358 "for config %x:%x (%s)\n",
3359 model, tbl->subvendor, tbl->subdevice,
3360 (tbl->name ? tbl->name : "Unknown device"));
3361#endif
3362 return tbl->value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003363 }
3364 return -1;
3365}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003366EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003367
3368/**
Mauro Carvalho Chehab2eda3442008-08-11 10:18:39 +02003369 * snd_hda_check_board_codec_sid_config - compare the current codec
3370 subsystem ID with the
3371 config table
3372
3373 This is important for Gateway notebooks with SB450 HDA Audio
3374 where the vendor ID of the PCI device is:
3375 ATI Technologies Inc SB450 HDA Audio [1002:437b]
3376 and the vendor/subvendor are found only at the codec.
3377
3378 * @codec: the HDA codec
3379 * @num_configs: number of config enums
3380 * @models: array of model name strings
3381 * @tbl: configuration table, terminated by null entries
3382 *
3383 * Compares the modelname or PCI subsystem id of the current codec with the
3384 * given configuration table. If a matching entry is found, returns its
3385 * config value (supposed to be 0 or positive).
3386 *
3387 * If no entries are matching, the function returns a negative value.
3388 */
3389int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
3390 int num_configs, const char **models,
3391 const struct snd_pci_quirk *tbl)
3392{
3393 const struct snd_pci_quirk *q;
3394
3395 /* Search for codec ID */
3396 for (q = tbl; q->subvendor; q++) {
3397 unsigned long vendorid = (q->subdevice) | (q->subvendor << 16);
3398
3399 if (vendorid == codec->subsystem_id)
3400 break;
3401 }
3402
3403 if (!q->subvendor)
3404 return -1;
3405
3406 tbl = q;
3407
3408 if (tbl->value >= 0 && tbl->value < num_configs) {
Takashi Iwaid94ff6b2009-09-02 00:20:21 +02003409#ifdef CONFIG_SND_DEBUG_VERBOSE
Mauro Carvalho Chehab2eda3442008-08-11 10:18:39 +02003410 char tmp[10];
3411 const char *model = NULL;
3412 if (models)
3413 model = models[tbl->value];
3414 if (!model) {
3415 sprintf(tmp, "#%d", tbl->value);
3416 model = tmp;
3417 }
3418 snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
3419 "for config %x:%x (%s)\n",
3420 model, tbl->subvendor, tbl->subdevice,
3421 (tbl->name ? tbl->name : "Unknown device"));
3422#endif
3423 return tbl->value;
3424 }
3425 return -1;
3426}
3427EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config);
3428
3429/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07003430 * snd_hda_add_new_ctls - create controls from the array
3431 * @codec: the HDA codec
Takashi Iwaic8b6bf92005-11-17 14:57:47 +01003432 * @knew: the array of struct snd_kcontrol_new
Linus Torvalds1da177e2005-04-16 15:20:36 -07003433 *
3434 * This helper function creates and add new controls in the given array.
3435 * The array must be terminated with an empty entry as terminator.
3436 *
3437 * Returns 0 if successful, or a negative error code.
3438 */
Takashi Iwai12f288b2007-08-02 15:51:59 +02003439int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003440{
Jaroslav Kysela4d02d1b2009-11-12 10:15:48 +01003441 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003442
3443 for (; knew->name; knew++) {
Takashi Iwai54d17402005-11-21 16:33:22 +01003444 struct snd_kcontrol *kctl;
3445 kctl = snd_ctl_new1(knew, codec);
Takashi Iwai0ba21762007-04-16 11:29:14 +02003446 if (!kctl)
Takashi Iwai54d17402005-11-21 16:33:22 +01003447 return -ENOMEM;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01003448 err = snd_hda_ctl_add(codec, 0, kctl);
Takashi Iwai54d17402005-11-21 16:33:22 +01003449 if (err < 0) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02003450 if (!codec->addr)
Takashi Iwai54d17402005-11-21 16:33:22 +01003451 return err;
3452 kctl = snd_ctl_new1(knew, codec);
Takashi Iwai0ba21762007-04-16 11:29:14 +02003453 if (!kctl)
Takashi Iwai54d17402005-11-21 16:33:22 +01003454 return -ENOMEM;
3455 kctl->id.device = codec->addr;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01003456 err = snd_hda_ctl_add(codec, 0, kctl);
Takashi Iwai0ba21762007-04-16 11:29:14 +02003457 if (err < 0)
Takashi Iwai54d17402005-11-21 16:33:22 +01003458 return err;
3459 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003460 }
3461 return 0;
3462}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003463EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003464
Takashi Iwaicb53c622007-08-10 17:21:45 +02003465#ifdef CONFIG_SND_HDA_POWER_SAVE
3466static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3467 unsigned int power_state);
3468
3469static void hda_power_work(struct work_struct *work)
3470{
3471 struct hda_codec *codec =
3472 container_of(work, struct hda_codec, power_work.work);
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003473 struct hda_bus *bus = codec->bus;
Takashi Iwaicb53c622007-08-10 17:21:45 +02003474
Maxim Levitsky2e492462007-09-03 15:26:57 +02003475 if (!codec->power_on || codec->power_count) {
3476 codec->power_transition = 0;
Takashi Iwaicb53c622007-08-10 17:21:45 +02003477 return;
Maxim Levitsky2e492462007-09-03 15:26:57 +02003478 }
Takashi Iwaicb53c622007-08-10 17:21:45 +02003479
3480 hda_call_codec_suspend(codec);
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003481 if (bus->ops.pm_notify)
3482 bus->ops.pm_notify(bus);
Takashi Iwaicb53c622007-08-10 17:21:45 +02003483}
3484
3485static void hda_keep_power_on(struct hda_codec *codec)
3486{
3487 codec->power_count++;
3488 codec->power_on = 1;
Takashi Iwaia2f63092009-11-11 09:34:25 +01003489 codec->power_jiffies = jiffies;
3490}
3491
Takashi Iwaid5191e52009-11-16 14:58:17 +01003492/* update the power on/off account with the current jiffies */
Takashi Iwaia2f63092009-11-11 09:34:25 +01003493void snd_hda_update_power_acct(struct hda_codec *codec)
3494{
3495 unsigned long delta = jiffies - codec->power_jiffies;
3496 if (codec->power_on)
3497 codec->power_on_acct += delta;
3498 else
3499 codec->power_off_acct += delta;
3500 codec->power_jiffies += delta;
Takashi Iwaicb53c622007-08-10 17:21:45 +02003501}
3502
Takashi Iwaid5191e52009-11-16 14:58:17 +01003503/**
3504 * snd_hda_power_up - Power-up the codec
3505 * @codec: HD-audio codec
3506 *
3507 * Increment the power-up counter and power up the hardware really when
3508 * not turned on yet.
3509 */
Takashi Iwaicb53c622007-08-10 17:21:45 +02003510void snd_hda_power_up(struct hda_codec *codec)
3511{
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003512 struct hda_bus *bus = codec->bus;
3513
Takashi Iwaicb53c622007-08-10 17:21:45 +02003514 codec->power_count++;
Takashi Iwaia221e282007-08-16 16:35:33 +02003515 if (codec->power_on || codec->power_transition)
Takashi Iwaicb53c622007-08-10 17:21:45 +02003516 return;
3517
Takashi Iwaia2f63092009-11-11 09:34:25 +01003518 snd_hda_update_power_acct(codec);
Takashi Iwaicb53c622007-08-10 17:21:45 +02003519 codec->power_on = 1;
Takashi Iwaia2f63092009-11-11 09:34:25 +01003520 codec->power_jiffies = jiffies;
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003521 if (bus->ops.pm_notify)
3522 bus->ops.pm_notify(bus);
Takashi Iwaicb53c622007-08-10 17:21:45 +02003523 hda_call_codec_resume(codec);
3524 cancel_delayed_work(&codec->power_work);
Takashi Iwaia221e282007-08-16 16:35:33 +02003525 codec->power_transition = 0;
Takashi Iwaicb53c622007-08-10 17:21:45 +02003526}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003527EXPORT_SYMBOL_HDA(snd_hda_power_up);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01003528
3529#define power_save(codec) \
3530 ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
Takashi Iwaicb53c622007-08-10 17:21:45 +02003531
Takashi Iwaid5191e52009-11-16 14:58:17 +01003532/**
3533 * snd_hda_power_down - Power-down the codec
3534 * @codec: HD-audio codec
3535 *
3536 * Decrement the power-up counter and schedules the power-off work if
3537 * the counter rearches to zero.
3538 */
Takashi Iwaicb53c622007-08-10 17:21:45 +02003539void snd_hda_power_down(struct hda_codec *codec)
3540{
3541 --codec->power_count;
Takashi Iwaia221e282007-08-16 16:35:33 +02003542 if (!codec->power_on || codec->power_count || codec->power_transition)
Takashi Iwaicb53c622007-08-10 17:21:45 +02003543 return;
Takashi Iwaifee2fba2008-11-27 12:43:28 +01003544 if (power_save(codec)) {
Takashi Iwaia221e282007-08-16 16:35:33 +02003545 codec->power_transition = 1; /* avoid reentrance */
Takashi Iwaic107b412009-01-13 17:46:37 +01003546 queue_delayed_work(codec->bus->workq, &codec->power_work,
Takashi Iwaifee2fba2008-11-27 12:43:28 +01003547 msecs_to_jiffies(power_save(codec) * 1000));
Takashi Iwaia221e282007-08-16 16:35:33 +02003548 }
Takashi Iwaicb53c622007-08-10 17:21:45 +02003549}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003550EXPORT_SYMBOL_HDA(snd_hda_power_down);
Takashi Iwaicb53c622007-08-10 17:21:45 +02003551
Takashi Iwaid5191e52009-11-16 14:58:17 +01003552/**
3553 * snd_hda_check_amp_list_power - Check the amp list and update the power
3554 * @codec: HD-audio codec
3555 * @check: the object containing an AMP list and the status
3556 * @nid: NID to check / update
3557 *
3558 * Check whether the given NID is in the amp list. If it's in the list,
3559 * check the current AMP status, and update the the power-status according
3560 * to the mute status.
3561 *
3562 * This function is supposed to be set or called from the check_power_status
3563 * patch ops.
3564 */
Takashi Iwaicb53c622007-08-10 17:21:45 +02003565int snd_hda_check_amp_list_power(struct hda_codec *codec,
3566 struct hda_loopback_check *check,
3567 hda_nid_t nid)
3568{
3569 struct hda_amp_list *p;
3570 int ch, v;
3571
3572 if (!check->amplist)
3573 return 0;
3574 for (p = check->amplist; p->nid; p++) {
3575 if (p->nid == nid)
3576 break;
3577 }
3578 if (!p->nid)
3579 return 0; /* nothing changed */
3580
3581 for (p = check->amplist; p->nid; p++) {
3582 for (ch = 0; ch < 2; ch++) {
3583 v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
3584 p->idx);
3585 if (!(v & HDA_AMP_MUTE) && v > 0) {
3586 if (!check->power_on) {
3587 check->power_on = 1;
3588 snd_hda_power_up(codec);
3589 }
3590 return 1;
3591 }
3592 }
3593 }
3594 if (check->power_on) {
3595 check->power_on = 0;
3596 snd_hda_power_down(codec);
3597 }
3598 return 0;
3599}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003600EXPORT_SYMBOL_HDA(snd_hda_check_amp_list_power);
Takashi Iwaicb53c622007-08-10 17:21:45 +02003601#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003602
Takashi Iwaic8b6bf92005-11-17 14:57:47 +01003603/*
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003604 * Channel mode helper
3605 */
Takashi Iwaid5191e52009-11-16 14:58:17 +01003606
3607/**
3608 * snd_hda_ch_mode_info - Info callback helper for the channel mode enum
3609 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003610int snd_hda_ch_mode_info(struct hda_codec *codec,
3611 struct snd_ctl_elem_info *uinfo,
3612 const struct hda_channel_mode *chmode,
3613 int num_chmodes)
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003614{
3615 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3616 uinfo->count = 1;
3617 uinfo->value.enumerated.items = num_chmodes;
3618 if (uinfo->value.enumerated.item >= num_chmodes)
3619 uinfo->value.enumerated.item = num_chmodes - 1;
3620 sprintf(uinfo->value.enumerated.name, "%dch",
3621 chmode[uinfo->value.enumerated.item].channels);
3622 return 0;
3623}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003624EXPORT_SYMBOL_HDA(snd_hda_ch_mode_info);
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003625
Takashi Iwaid5191e52009-11-16 14:58:17 +01003626/**
3627 * snd_hda_ch_mode_get - Get callback helper for the channel mode enum
3628 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003629int snd_hda_ch_mode_get(struct hda_codec *codec,
3630 struct snd_ctl_elem_value *ucontrol,
3631 const struct hda_channel_mode *chmode,
3632 int num_chmodes,
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003633 int max_channels)
3634{
3635 int i;
3636
3637 for (i = 0; i < num_chmodes; i++) {
3638 if (max_channels == chmode[i].channels) {
3639 ucontrol->value.enumerated.item[0] = i;
3640 break;
3641 }
3642 }
3643 return 0;
3644}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003645EXPORT_SYMBOL_HDA(snd_hda_ch_mode_get);
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003646
Takashi Iwaid5191e52009-11-16 14:58:17 +01003647/**
3648 * snd_hda_ch_mode_put - Put callback helper for the channel mode enum
3649 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003650int snd_hda_ch_mode_put(struct hda_codec *codec,
3651 struct snd_ctl_elem_value *ucontrol,
3652 const struct hda_channel_mode *chmode,
3653 int num_chmodes,
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003654 int *max_channelsp)
3655{
3656 unsigned int mode;
3657
3658 mode = ucontrol->value.enumerated.item[0];
Takashi Iwai68ea7b22007-11-15 15:54:38 +01003659 if (mode >= num_chmodes)
3660 return -EINVAL;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02003661 if (*max_channelsp == chmode[mode].channels)
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003662 return 0;
3663 /* change the current channel setting */
3664 *max_channelsp = chmode[mode].channels;
3665 if (chmode[mode].sequence)
Takashi Iwai82beb8f2007-08-10 17:09:26 +02003666 snd_hda_sequence_write_cache(codec, chmode[mode].sequence);
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003667 return 1;
3668}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003669EXPORT_SYMBOL_HDA(snd_hda_ch_mode_put);
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003670
Linus Torvalds1da177e2005-04-16 15:20:36 -07003671/*
3672 * input MUX helper
3673 */
Takashi Iwaid5191e52009-11-16 14:58:17 +01003674
3675/**
3676 * snd_hda_input_mux_info_info - Info callback helper for the input-mux enum
3677 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003678int snd_hda_input_mux_info(const struct hda_input_mux *imux,
3679 struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003680{
3681 unsigned int index;
3682
3683 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3684 uinfo->count = 1;
3685 uinfo->value.enumerated.items = imux->num_items;
Takashi Iwai5513b0c2007-10-09 11:58:41 +02003686 if (!imux->num_items)
3687 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003688 index = uinfo->value.enumerated.item;
3689 if (index >= imux->num_items)
3690 index = imux->num_items - 1;
3691 strcpy(uinfo->value.enumerated.name, imux->items[index].label);
3692 return 0;
3693}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003694EXPORT_SYMBOL_HDA(snd_hda_input_mux_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003695
Takashi Iwaid5191e52009-11-16 14:58:17 +01003696/**
3697 * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum
3698 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003699int snd_hda_input_mux_put(struct hda_codec *codec,
3700 const struct hda_input_mux *imux,
3701 struct snd_ctl_elem_value *ucontrol,
3702 hda_nid_t nid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003703 unsigned int *cur_val)
3704{
3705 unsigned int idx;
3706
Takashi Iwai5513b0c2007-10-09 11:58:41 +02003707 if (!imux->num_items)
3708 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003709 idx = ucontrol->value.enumerated.item[0];
3710 if (idx >= imux->num_items)
3711 idx = imux->num_items - 1;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02003712 if (*cur_val == idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003713 return 0;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02003714 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
3715 imux->items[idx].index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003716 *cur_val = idx;
3717 return 1;
3718}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003719EXPORT_SYMBOL_HDA(snd_hda_input_mux_put);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003720
3721
3722/*
3723 * Multi-channel / digital-out PCM helper functions
3724 */
3725
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003726/* setup SPDIF output stream */
3727static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
3728 unsigned int stream_tag, unsigned int format)
3729{
3730 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
Takashi Iwai2f728532008-09-25 16:32:41 +02003731 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
3732 set_dig_out_convert(codec, nid,
3733 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
3734 -1);
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003735 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
Takashi Iwai2f728532008-09-25 16:32:41 +02003736 if (codec->slave_dig_outs) {
3737 hda_nid_t *d;
3738 for (d = codec->slave_dig_outs; *d; d++)
3739 snd_hda_codec_setup_stream(codec, *d, stream_tag, 0,
3740 format);
Matthew Ranostayde51ca12008-09-07 14:31:40 -04003741 }
Takashi Iwai2f728532008-09-25 16:32:41 +02003742 /* turn on again (if needed) */
3743 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
3744 set_dig_out_convert(codec, nid,
3745 codec->spdif_ctls & 0xff, -1);
3746}
Matthew Ranostayde51ca12008-09-07 14:31:40 -04003747
Takashi Iwai2f728532008-09-25 16:32:41 +02003748static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
3749{
3750 snd_hda_codec_cleanup_stream(codec, nid);
3751 if (codec->slave_dig_outs) {
3752 hda_nid_t *d;
3753 for (d = codec->slave_dig_outs; *d; d++)
3754 snd_hda_codec_cleanup_stream(codec, *d);
3755 }
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003756}
3757
Takashi Iwaid5191e52009-11-16 14:58:17 +01003758/**
3759 * snd_hda_bus_reboot_notify - call the reboot notifier of each codec
3760 * @bus: HD-audio bus
3761 */
Takashi Iwaifb8d1a32009-11-10 16:02:29 +01003762void snd_hda_bus_reboot_notify(struct hda_bus *bus)
3763{
3764 struct hda_codec *codec;
3765
3766 if (!bus)
3767 return;
3768 list_for_each_entry(codec, &bus->codec_list, list) {
3769#ifdef CONFIG_SND_HDA_POWER_SAVE
3770 if (!codec->power_on)
3771 continue;
3772#endif
3773 if (codec->patch_ops.reboot_notify)
3774 codec->patch_ops.reboot_notify(codec);
3775 }
3776}
Takashi Iwai8f217a22009-11-10 18:26:12 +01003777EXPORT_SYMBOL_HDA(snd_hda_bus_reboot_notify);
Takashi Iwaifb8d1a32009-11-10 16:02:29 +01003778
Takashi Iwaid5191e52009-11-16 14:58:17 +01003779/**
3780 * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode
Linus Torvalds1da177e2005-04-16 15:20:36 -07003781 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003782int snd_hda_multi_out_dig_open(struct hda_codec *codec,
3783 struct hda_multi_out *mout)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003784{
Ingo Molnar62932df2006-01-16 16:34:20 +01003785 mutex_lock(&codec->spdif_mutex);
Takashi Iwai5930ca42007-04-16 11:23:56 +02003786 if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
3787 /* already opened as analog dup; reset it once */
Takashi Iwai2f728532008-09-25 16:32:41 +02003788 cleanup_dig_out_stream(codec, mout->dig_out_nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003789 mout->dig_out_used = HDA_DIG_EXCLUSIVE;
Ingo Molnar62932df2006-01-16 16:34:20 +01003790 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003791 return 0;
3792}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003793EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_open);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003794
Takashi Iwaid5191e52009-11-16 14:58:17 +01003795/**
3796 * snd_hda_multi_out_dig_prepare - prepare the digital out stream
3797 */
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003798int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
3799 struct hda_multi_out *mout,
3800 unsigned int stream_tag,
3801 unsigned int format,
3802 struct snd_pcm_substream *substream)
3803{
3804 mutex_lock(&codec->spdif_mutex);
3805 setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
3806 mutex_unlock(&codec->spdif_mutex);
3807 return 0;
3808}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003809EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare);
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003810
Takashi Iwaid5191e52009-11-16 14:58:17 +01003811/**
3812 * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream
3813 */
Takashi Iwai9411e212009-02-13 11:32:28 +01003814int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
3815 struct hda_multi_out *mout)
3816{
3817 mutex_lock(&codec->spdif_mutex);
3818 cleanup_dig_out_stream(codec, mout->dig_out_nid);
3819 mutex_unlock(&codec->spdif_mutex);
3820 return 0;
3821}
3822EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup);
3823
Takashi Iwaid5191e52009-11-16 14:58:17 +01003824/**
3825 * snd_hda_multi_out_dig_close - release the digital out stream
Linus Torvalds1da177e2005-04-16 15:20:36 -07003826 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003827int snd_hda_multi_out_dig_close(struct hda_codec *codec,
3828 struct hda_multi_out *mout)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003829{
Ingo Molnar62932df2006-01-16 16:34:20 +01003830 mutex_lock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003831 mout->dig_out_used = 0;
Ingo Molnar62932df2006-01-16 16:34:20 +01003832 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003833 return 0;
3834}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003835EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_close);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003836
Takashi Iwaid5191e52009-11-16 14:58:17 +01003837/**
3838 * snd_hda_multi_out_analog_open - open analog outputs
3839 *
3840 * Open analog outputs and set up the hw-constraints.
3841 * If the digital outputs can be opened as slave, open the digital
3842 * outputs, too.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003843 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003844int snd_hda_multi_out_analog_open(struct hda_codec *codec,
3845 struct hda_multi_out *mout,
Takashi Iwai9a081602008-02-12 18:37:26 +01003846 struct snd_pcm_substream *substream,
3847 struct hda_pcm_stream *hinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003848{
Takashi Iwai9a081602008-02-12 18:37:26 +01003849 struct snd_pcm_runtime *runtime = substream->runtime;
3850 runtime->hw.channels_max = mout->max_channels;
3851 if (mout->dig_out_nid) {
3852 if (!mout->analog_rates) {
3853 mout->analog_rates = hinfo->rates;
3854 mout->analog_formats = hinfo->formats;
3855 mout->analog_maxbps = hinfo->maxbps;
3856 } else {
3857 runtime->hw.rates = mout->analog_rates;
3858 runtime->hw.formats = mout->analog_formats;
3859 hinfo->maxbps = mout->analog_maxbps;
3860 }
3861 if (!mout->spdif_rates) {
3862 snd_hda_query_supported_pcm(codec, mout->dig_out_nid,
3863 &mout->spdif_rates,
3864 &mout->spdif_formats,
3865 &mout->spdif_maxbps);
3866 }
3867 mutex_lock(&codec->spdif_mutex);
3868 if (mout->share_spdif) {
Takashi Iwai022b4662009-07-03 23:03:30 +02003869 if ((runtime->hw.rates & mout->spdif_rates) &&
3870 (runtime->hw.formats & mout->spdif_formats)) {
3871 runtime->hw.rates &= mout->spdif_rates;
3872 runtime->hw.formats &= mout->spdif_formats;
3873 if (mout->spdif_maxbps < hinfo->maxbps)
3874 hinfo->maxbps = mout->spdif_maxbps;
3875 } else {
3876 mout->share_spdif = 0;
3877 /* FIXME: need notify? */
3878 }
Takashi Iwai9a081602008-02-12 18:37:26 +01003879 }
Frederik Deweerdteaa99852008-04-14 13:11:44 +02003880 mutex_unlock(&codec->spdif_mutex);
Takashi Iwai9a081602008-02-12 18:37:26 +01003881 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003882 return snd_pcm_hw_constraint_step(substream->runtime, 0,
3883 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
3884}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003885EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003886
Takashi Iwaid5191e52009-11-16 14:58:17 +01003887/**
3888 * snd_hda_multi_out_analog_prepare - Preapre the analog outputs.
3889 *
3890 * Set up the i/o for analog out.
3891 * When the digital out is available, copy the front out to digital out, too.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003892 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003893int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
3894 struct hda_multi_out *mout,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003895 unsigned int stream_tag,
3896 unsigned int format,
Takashi Iwaic8b6bf92005-11-17 14:57:47 +01003897 struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003898{
3899 hda_nid_t *nids = mout->dac_nids;
3900 int chs = substream->runtime->channels;
3901 int i;
3902
Ingo Molnar62932df2006-01-16 16:34:20 +01003903 mutex_lock(&codec->spdif_mutex);
Takashi Iwai9a081602008-02-12 18:37:26 +01003904 if (mout->dig_out_nid && mout->share_spdif &&
3905 mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003906 if (chs == 2 &&
Takashi Iwai0ba21762007-04-16 11:29:14 +02003907 snd_hda_is_supported_format(codec, mout->dig_out_nid,
3908 format) &&
3909 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003910 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003911 setup_dig_out_stream(codec, mout->dig_out_nid,
3912 stream_tag, format);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003913 } else {
3914 mout->dig_out_used = 0;
Takashi Iwai2f728532008-09-25 16:32:41 +02003915 cleanup_dig_out_stream(codec, mout->dig_out_nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003916 }
3917 }
Ingo Molnar62932df2006-01-16 16:34:20 +01003918 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003919
3920 /* front */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003921 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
3922 0, format);
Takashi Iwaid29240c2007-10-26 12:35:56 +02003923 if (!mout->no_share_stream &&
3924 mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
Linus Torvalds1da177e2005-04-16 15:20:36 -07003925 /* headphone out will just decode front left/right (stereo) */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003926 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
3927 0, format);
Takashi Iwai82bc9552006-03-21 11:24:42 +01003928 /* extra outputs copied from front */
3929 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
Takashi Iwaid29240c2007-10-26 12:35:56 +02003930 if (!mout->no_share_stream && mout->extra_out_nid[i])
Takashi Iwai82bc9552006-03-21 11:24:42 +01003931 snd_hda_codec_setup_stream(codec,
3932 mout->extra_out_nid[i],
3933 stream_tag, 0, format);
3934
Linus Torvalds1da177e2005-04-16 15:20:36 -07003935 /* surrounds */
3936 for (i = 1; i < mout->num_dacs; i++) {
Takashi Iwai4b3acaf2005-06-10 19:48:10 +02003937 if (chs >= (i + 1) * 2) /* independent out */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003938 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
3939 i * 2, format);
Takashi Iwaid29240c2007-10-26 12:35:56 +02003940 else if (!mout->no_share_stream) /* copy front */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003941 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
3942 0, format);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003943 }
3944 return 0;
3945}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003946EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003947
Takashi Iwaid5191e52009-11-16 14:58:17 +01003948/**
3949 * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out
Linus Torvalds1da177e2005-04-16 15:20:36 -07003950 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003951int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
3952 struct hda_multi_out *mout)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003953{
3954 hda_nid_t *nids = mout->dac_nids;
3955 int i;
3956
3957 for (i = 0; i < mout->num_dacs; i++)
Takashi Iwai888afa12008-03-18 09:57:50 +01003958 snd_hda_codec_cleanup_stream(codec, nids[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003959 if (mout->hp_nid)
Takashi Iwai888afa12008-03-18 09:57:50 +01003960 snd_hda_codec_cleanup_stream(codec, mout->hp_nid);
Takashi Iwai82bc9552006-03-21 11:24:42 +01003961 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
3962 if (mout->extra_out_nid[i])
Takashi Iwai888afa12008-03-18 09:57:50 +01003963 snd_hda_codec_cleanup_stream(codec,
3964 mout->extra_out_nid[i]);
Ingo Molnar62932df2006-01-16 16:34:20 +01003965 mutex_lock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003966 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
Takashi Iwai2f728532008-09-25 16:32:41 +02003967 cleanup_dig_out_stream(codec, mout->dig_out_nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003968 mout->dig_out_used = 0;
3969 }
Ingo Molnar62932df2006-01-16 16:34:20 +01003970 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971 return 0;
3972}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003973EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003974
Takashi Iwaie9edcee2005-06-13 14:16:38 +02003975/*
Wu Fengguang6b345002008-10-07 14:21:41 +08003976 * Helper for automatic pin configuration
Takashi Iwaie9edcee2005-06-13 14:16:38 +02003977 */
Kailang Yangdf694da2005-12-05 19:42:22 +01003978
Takashi Iwai12f288b2007-08-02 15:51:59 +02003979static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
Kailang Yangdf694da2005-12-05 19:42:22 +01003980{
3981 for (; *list; list++)
3982 if (*list == nid)
3983 return 1;
3984 return 0;
3985}
3986
Steve Longerbeam81937d32007-05-08 15:33:03 +02003987
3988/*
3989 * Sort an associated group of pins according to their sequence numbers.
3990 */
3991static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
3992 int num_pins)
3993{
3994 int i, j;
3995 short seq;
3996 hda_nid_t nid;
3997
3998 for (i = 0; i < num_pins; i++) {
3999 for (j = i + 1; j < num_pins; j++) {
4000 if (sequences[i] > sequences[j]) {
4001 seq = sequences[i];
4002 sequences[i] = sequences[j];
4003 sequences[j] = seq;
4004 nid = pins[i];
4005 pins[i] = pins[j];
4006 pins[j] = nid;
4007 }
4008 }
4009 }
4010}
4011
4012
Takashi Iwai82bc9552006-03-21 11:24:42 +01004013/*
4014 * Parse all pin widgets and store the useful pin nids to cfg
4015 *
4016 * The number of line-outs or any primary output is stored in line_outs,
4017 * and the corresponding output pins are assigned to line_out_pins[],
4018 * in the order of front, rear, CLFE, side, ...
4019 *
4020 * If more extra outputs (speaker and headphone) are found, the pins are
Takashi Iwaieb06ed82006-09-20 17:10:27 +02004021 * assisnged to hp_pins[] and speaker_pins[], respectively. If no line-out jack
Takashi Iwai82bc9552006-03-21 11:24:42 +01004022 * is detected, one of speaker of HP pins is assigned as the primary
4023 * output, i.e. to line_out_pins[0]. So, line_outs is always positive
4024 * if any analog output exists.
4025 *
4026 * The analog input pins are assigned to input_pins array.
4027 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
4028 * respectively.
4029 */
Takashi Iwai12f288b2007-08-02 15:51:59 +02004030int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4031 struct auto_pin_cfg *cfg,
4032 hda_nid_t *ignore_nids)
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004033{
Takashi Iwai0ef6ce72008-01-22 15:35:37 +01004034 hda_nid_t nid, end_nid;
Steve Longerbeam81937d32007-05-08 15:33:03 +02004035 short seq, assoc_line_out, assoc_speaker;
4036 short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
4037 short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
Takashi Iwaif889fa92007-10-31 15:49:32 +01004038 short sequences_hp[ARRAY_SIZE(cfg->hp_pins)];
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004039
4040 memset(cfg, 0, sizeof(*cfg));
4041
Steve Longerbeam81937d32007-05-08 15:33:03 +02004042 memset(sequences_line_out, 0, sizeof(sequences_line_out));
4043 memset(sequences_speaker, 0, sizeof(sequences_speaker));
Takashi Iwaif889fa92007-10-31 15:49:32 +01004044 memset(sequences_hp, 0, sizeof(sequences_hp));
Steve Longerbeam81937d32007-05-08 15:33:03 +02004045 assoc_line_out = assoc_speaker = 0;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004046
Takashi Iwai0ef6ce72008-01-22 15:35:37 +01004047 end_nid = codec->start_nid + codec->num_nodes;
4048 for (nid = codec->start_nid; nid < end_nid; nid++) {
Takashi Iwai54d17402005-11-21 16:33:22 +01004049 unsigned int wid_caps = get_wcaps(codec, nid);
Takashi Iwaia22d5432009-07-27 12:54:26 +02004050 unsigned int wid_type = get_wcaps_type(wid_caps);
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004051 unsigned int def_conf;
4052 short assoc, loc;
4053
4054 /* read all default configuration for pin complex */
4055 if (wid_type != AC_WID_PIN)
4056 continue;
Kailang Yangdf694da2005-12-05 19:42:22 +01004057 /* ignore the given nids (e.g. pc-beep returns error) */
4058 if (ignore_nids && is_in_nid_list(nid, ignore_nids))
4059 continue;
4060
Takashi Iwaic17a1ab2009-02-23 09:28:12 +01004061 def_conf = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004062 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
4063 continue;
4064 loc = get_defcfg_location(def_conf);
4065 switch (get_defcfg_device(def_conf)) {
4066 case AC_JACK_LINE_OUT:
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004067 seq = get_defcfg_sequence(def_conf);
4068 assoc = get_defcfg_association(def_conf);
Matthew Ranostay90da78b2008-01-24 11:48:01 +01004069
4070 if (!(wid_caps & AC_WCAP_STEREO))
4071 if (!cfg->mono_out_pin)
4072 cfg->mono_out_pin = nid;
Takashi Iwai0ba21762007-04-16 11:29:14 +02004073 if (!assoc)
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004074 continue;
Takashi Iwai0ba21762007-04-16 11:29:14 +02004075 if (!assoc_line_out)
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004076 assoc_line_out = assoc;
4077 else if (assoc_line_out != assoc)
4078 continue;
4079 if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins))
4080 continue;
4081 cfg->line_out_pins[cfg->line_outs] = nid;
Steve Longerbeam81937d32007-05-08 15:33:03 +02004082 sequences_line_out[cfg->line_outs] = seq;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004083 cfg->line_outs++;
4084 break;
Takashi Iwai8d88bc32005-11-17 11:09:23 +01004085 case AC_JACK_SPEAKER:
Steve Longerbeam81937d32007-05-08 15:33:03 +02004086 seq = get_defcfg_sequence(def_conf);
4087 assoc = get_defcfg_association(def_conf);
4088 if (! assoc)
4089 continue;
4090 if (! assoc_speaker)
4091 assoc_speaker = assoc;
4092 else if (assoc_speaker != assoc)
4093 continue;
Takashi Iwai82bc9552006-03-21 11:24:42 +01004094 if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
4095 continue;
4096 cfg->speaker_pins[cfg->speaker_outs] = nid;
Steve Longerbeam81937d32007-05-08 15:33:03 +02004097 sequences_speaker[cfg->speaker_outs] = seq;
Takashi Iwai82bc9552006-03-21 11:24:42 +01004098 cfg->speaker_outs++;
Takashi Iwai8d88bc32005-11-17 11:09:23 +01004099 break;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004100 case AC_JACK_HP_OUT:
Takashi Iwaif889fa92007-10-31 15:49:32 +01004101 seq = get_defcfg_sequence(def_conf);
4102 assoc = get_defcfg_association(def_conf);
Takashi Iwaieb06ed82006-09-20 17:10:27 +02004103 if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins))
4104 continue;
4105 cfg->hp_pins[cfg->hp_outs] = nid;
Takashi Iwaif889fa92007-10-31 15:49:32 +01004106 sequences_hp[cfg->hp_outs] = (assoc << 4) | seq;
Takashi Iwaieb06ed82006-09-20 17:10:27 +02004107 cfg->hp_outs++;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004108 break;
Takashi Iwai314634b2006-09-21 11:56:18 +02004109 case AC_JACK_MIC_IN: {
4110 int preferred, alt;
4111 if (loc == AC_JACK_LOC_FRONT) {
4112 preferred = AUTO_PIN_FRONT_MIC;
4113 alt = AUTO_PIN_MIC;
4114 } else {
4115 preferred = AUTO_PIN_MIC;
4116 alt = AUTO_PIN_FRONT_MIC;
4117 }
4118 if (!cfg->input_pins[preferred])
4119 cfg->input_pins[preferred] = nid;
4120 else if (!cfg->input_pins[alt])
4121 cfg->input_pins[alt] = nid;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004122 break;
Takashi Iwai314634b2006-09-21 11:56:18 +02004123 }
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004124 case AC_JACK_LINE_IN:
4125 if (loc == AC_JACK_LOC_FRONT)
4126 cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid;
4127 else
4128 cfg->input_pins[AUTO_PIN_LINE] = nid;
4129 break;
4130 case AC_JACK_CD:
4131 cfg->input_pins[AUTO_PIN_CD] = nid;
4132 break;
4133 case AC_JACK_AUX:
4134 cfg->input_pins[AUTO_PIN_AUX] = nid;
4135 break;
4136 case AC_JACK_SPDIF_OUT:
Takashi Iwai1b52ae72009-01-20 17:17:29 +01004137 case AC_JACK_DIG_OTHER_OUT:
Takashi Iwai0852d7a2009-02-11 11:35:15 +01004138 if (cfg->dig_outs >= ARRAY_SIZE(cfg->dig_out_pins))
4139 continue;
4140 cfg->dig_out_pins[cfg->dig_outs] = nid;
4141 cfg->dig_out_type[cfg->dig_outs] =
4142 (loc == AC_JACK_LOC_HDMI) ?
4143 HDA_PCM_TYPE_HDMI : HDA_PCM_TYPE_SPDIF;
4144 cfg->dig_outs++;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004145 break;
4146 case AC_JACK_SPDIF_IN:
Takashi Iwai1b52ae72009-01-20 17:17:29 +01004147 case AC_JACK_DIG_OTHER_IN:
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004148 cfg->dig_in_pin = nid;
Takashi Iwai2297bd62009-01-20 18:24:13 +01004149 if (loc == AC_JACK_LOC_HDMI)
4150 cfg->dig_in_type = HDA_PCM_TYPE_HDMI;
4151 else
4152 cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004153 break;
4154 }
4155 }
4156
Takashi Iwai5832fcf82008-02-12 18:30:12 +01004157 /* FIX-UP:
4158 * If no line-out is defined but multiple HPs are found,
4159 * some of them might be the real line-outs.
4160 */
4161 if (!cfg->line_outs && cfg->hp_outs > 1) {
4162 int i = 0;
4163 while (i < cfg->hp_outs) {
4164 /* The real HPs should have the sequence 0x0f */
4165 if ((sequences_hp[i] & 0x0f) == 0x0f) {
4166 i++;
4167 continue;
4168 }
4169 /* Move it to the line-out table */
4170 cfg->line_out_pins[cfg->line_outs] = cfg->hp_pins[i];
4171 sequences_line_out[cfg->line_outs] = sequences_hp[i];
4172 cfg->line_outs++;
4173 cfg->hp_outs--;
4174 memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1,
4175 sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i));
4176 memmove(sequences_hp + i - 1, sequences_hp + i,
4177 sizeof(sequences_hp[0]) * (cfg->hp_outs - i));
4178 }
4179 }
4180
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004181 /* sort by sequence */
Steve Longerbeam81937d32007-05-08 15:33:03 +02004182 sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out,
4183 cfg->line_outs);
4184 sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker,
4185 cfg->speaker_outs);
Takashi Iwaif889fa92007-10-31 15:49:32 +01004186 sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
4187 cfg->hp_outs);
Steve Longerbeam81937d32007-05-08 15:33:03 +02004188
Takashi Iwaif889fa92007-10-31 15:49:32 +01004189 /* if we have only one mic, make it AUTO_PIN_MIC */
4190 if (!cfg->input_pins[AUTO_PIN_MIC] &&
4191 cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
4192 cfg->input_pins[AUTO_PIN_MIC] =
4193 cfg->input_pins[AUTO_PIN_FRONT_MIC];
4194 cfg->input_pins[AUTO_PIN_FRONT_MIC] = 0;
4195 }
4196 /* ditto for line-in */
4197 if (!cfg->input_pins[AUTO_PIN_LINE] &&
4198 cfg->input_pins[AUTO_PIN_FRONT_LINE]) {
4199 cfg->input_pins[AUTO_PIN_LINE] =
4200 cfg->input_pins[AUTO_PIN_FRONT_LINE];
4201 cfg->input_pins[AUTO_PIN_FRONT_LINE] = 0;
4202 }
4203
Steve Longerbeam81937d32007-05-08 15:33:03 +02004204 /*
4205 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
4206 * as a primary output
4207 */
4208 if (!cfg->line_outs) {
4209 if (cfg->speaker_outs) {
4210 cfg->line_outs = cfg->speaker_outs;
4211 memcpy(cfg->line_out_pins, cfg->speaker_pins,
4212 sizeof(cfg->speaker_pins));
4213 cfg->speaker_outs = 0;
4214 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
4215 cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
4216 } else if (cfg->hp_outs) {
4217 cfg->line_outs = cfg->hp_outs;
4218 memcpy(cfg->line_out_pins, cfg->hp_pins,
4219 sizeof(cfg->hp_pins));
4220 cfg->hp_outs = 0;
4221 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
4222 cfg->line_out_type = AUTO_PIN_HP_OUT;
4223 }
4224 }
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004225
Takashi Iwaicb8e2f82005-07-29 11:54:32 +02004226 /* Reorder the surround channels
4227 * ALSA sequence is front/surr/clfe/side
4228 * HDA sequence is:
4229 * 4-ch: front/surr => OK as it is
4230 * 6-ch: front/clfe/surr
Takashi Iwai9422db42007-04-20 16:11:43 +02004231 * 8-ch: front/clfe/rear/side|fc
Takashi Iwaicb8e2f82005-07-29 11:54:32 +02004232 */
4233 switch (cfg->line_outs) {
4234 case 3:
Takashi Iwaicb8e2f82005-07-29 11:54:32 +02004235 case 4:
4236 nid = cfg->line_out_pins[1];
Takashi Iwai9422db42007-04-20 16:11:43 +02004237 cfg->line_out_pins[1] = cfg->line_out_pins[2];
Takashi Iwaicb8e2f82005-07-29 11:54:32 +02004238 cfg->line_out_pins[2] = nid;
4239 break;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004240 }
4241
Takashi Iwai82bc9552006-03-21 11:24:42 +01004242 /*
4243 * debug prints of the parsed results
4244 */
4245 snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
4246 cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1],
4247 cfg->line_out_pins[2], cfg->line_out_pins[3],
4248 cfg->line_out_pins[4]);
4249 snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
4250 cfg->speaker_outs, cfg->speaker_pins[0],
4251 cfg->speaker_pins[1], cfg->speaker_pins[2],
4252 cfg->speaker_pins[3], cfg->speaker_pins[4]);
Takashi Iwaieb06ed82006-09-20 17:10:27 +02004253 snd_printd(" hp_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
4254 cfg->hp_outs, cfg->hp_pins[0],
4255 cfg->hp_pins[1], cfg->hp_pins[2],
4256 cfg->hp_pins[3], cfg->hp_pins[4]);
Matthew Ranostay90da78b2008-01-24 11:48:01 +01004257 snd_printd(" mono: mono_out=0x%x\n", cfg->mono_out_pin);
Takashi Iwai0852d7a2009-02-11 11:35:15 +01004258 if (cfg->dig_outs)
4259 snd_printd(" dig-out=0x%x/0x%x\n",
4260 cfg->dig_out_pins[0], cfg->dig_out_pins[1]);
Takashi Iwai82bc9552006-03-21 11:24:42 +01004261 snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
4262 " cd=0x%x, aux=0x%x\n",
4263 cfg->input_pins[AUTO_PIN_MIC],
4264 cfg->input_pins[AUTO_PIN_FRONT_MIC],
4265 cfg->input_pins[AUTO_PIN_LINE],
4266 cfg->input_pins[AUTO_PIN_FRONT_LINE],
4267 cfg->input_pins[AUTO_PIN_CD],
4268 cfg->input_pins[AUTO_PIN_AUX]);
Takashi Iwai32d2c7f2009-02-11 11:33:13 +01004269 if (cfg->dig_in_pin)
Takashi Iwai89ce9e82009-01-20 17:15:57 +01004270 snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin);
Takashi Iwai82bc9552006-03-21 11:24:42 +01004271
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004272 return 0;
4273}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004274EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config);
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004275
Takashi Iwai4a471b72005-12-07 13:56:29 +01004276/* labels for input pins */
4277const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = {
4278 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
4279};
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004280EXPORT_SYMBOL_HDA(auto_pin_cfg_labels);
Takashi Iwai4a471b72005-12-07 13:56:29 +01004281
4282
Linus Torvalds1da177e2005-04-16 15:20:36 -07004283#ifdef CONFIG_PM
4284/*
4285 * power management
4286 */
4287
4288/**
4289 * snd_hda_suspend - suspend the codecs
4290 * @bus: the HDA bus
Linus Torvalds1da177e2005-04-16 15:20:36 -07004291 *
4292 * Returns 0 if successful.
4293 */
Takashi Iwai8dd78332009-06-02 01:16:07 +02004294int snd_hda_suspend(struct hda_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004295{
Takashi Iwai0ba21762007-04-16 11:29:14 +02004296 struct hda_codec *codec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004297
Takashi Iwai0ba21762007-04-16 11:29:14 +02004298 list_for_each_entry(codec, &bus->codec_list, list) {
Takashi Iwai0b7a2e92007-08-14 15:18:26 +02004299#ifdef CONFIG_SND_HDA_POWER_SAVE
4300 if (!codec->power_on)
4301 continue;
4302#endif
Takashi Iwaicb53c622007-08-10 17:21:45 +02004303 hda_call_codec_suspend(codec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004304 }
4305 return 0;
4306}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004307EXPORT_SYMBOL_HDA(snd_hda_suspend);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004308
4309/**
4310 * snd_hda_resume - resume the codecs
4311 * @bus: the HDA bus
Linus Torvalds1da177e2005-04-16 15:20:36 -07004312 *
4313 * Returns 0 if successful.
Takashi Iwaicb53c622007-08-10 17:21:45 +02004314 *
4315 * This fucntion is defined only when POWER_SAVE isn't set.
4316 * In the power-save mode, the codec is resumed dynamically.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004317 */
4318int snd_hda_resume(struct hda_bus *bus)
4319{
Takashi Iwai0ba21762007-04-16 11:29:14 +02004320 struct hda_codec *codec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004321
Takashi Iwai0ba21762007-04-16 11:29:14 +02004322 list_for_each_entry(codec, &bus->codec_list, list) {
Maxim Levitskyd804ad92007-09-03 15:28:04 +02004323 if (snd_hda_codec_needs_resume(codec))
4324 hda_call_codec_resume(codec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004325 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004326 return 0;
4327}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004328EXPORT_SYMBOL_HDA(snd_hda_resume);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01004329#endif /* CONFIG_PM */
Takashi Iwaib2e18592008-07-30 15:01:44 +02004330
4331/*
4332 * generic arrays
4333 */
4334
Takashi Iwaid5191e52009-11-16 14:58:17 +01004335/**
4336 * snd_array_new - get a new element from the given array
4337 * @array: the array object
4338 *
4339 * Get a new element from the given array. If it exceeds the
4340 * pre-allocated array size, re-allocate the array.
4341 *
4342 * Returns NULL if allocation failed.
Takashi Iwaib2e18592008-07-30 15:01:44 +02004343 */
4344void *snd_array_new(struct snd_array *array)
4345{
4346 if (array->used >= array->alloced) {
4347 int num = array->alloced + array->alloc_align;
Takashi Iwaib910d9a2008-11-07 00:26:52 +01004348 void *nlist;
4349 if (snd_BUG_ON(num >= 4096))
4350 return NULL;
4351 nlist = kcalloc(num + 1, array->elem_size, GFP_KERNEL);
Takashi Iwaib2e18592008-07-30 15:01:44 +02004352 if (!nlist)
4353 return NULL;
4354 if (array->list) {
4355 memcpy(nlist, array->list,
4356 array->elem_size * array->alloced);
4357 kfree(array->list);
4358 }
4359 array->list = nlist;
4360 array->alloced = num;
4361 }
Takashi Iwaif43aa022008-11-10 16:24:26 +01004362 return snd_array_elem(array, array->used++);
Takashi Iwaib2e18592008-07-30 15:01:44 +02004363}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004364EXPORT_SYMBOL_HDA(snd_array_new);
Takashi Iwaib2e18592008-07-30 15:01:44 +02004365
Takashi Iwaid5191e52009-11-16 14:58:17 +01004366/**
4367 * snd_array_free - free the given array elements
4368 * @array: the array object
4369 */
Takashi Iwaib2e18592008-07-30 15:01:44 +02004370void snd_array_free(struct snd_array *array)
4371{
4372 kfree(array->list);
4373 array->used = 0;
4374 array->alloced = 0;
4375 array->list = NULL;
4376}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004377EXPORT_SYMBOL_HDA(snd_array_free);
Takashi Iwaib2022262008-11-21 21:24:03 +01004378
Takashi Iwaid5191e52009-11-16 14:58:17 +01004379/**
4380 * snd_print_pcm_rates - Print the supported PCM rates to the string buffer
4381 * @pcm: PCM caps bits
4382 * @buf: the string buffer to write
4383 * @buflen: the max buffer length
4384 *
Takashi Iwaib2022262008-11-21 21:24:03 +01004385 * used by hda_proc.c and hda_eld.c
4386 */
4387void snd_print_pcm_rates(int pcm, char *buf, int buflen)
4388{
4389 static unsigned int rates[] = {
4390 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
4391 96000, 176400, 192000, 384000
4392 };
4393 int i, j;
4394
4395 for (i = 0, j = 0; i < ARRAY_SIZE(rates); i++)
4396 if (pcm & (1 << i))
4397 j += snprintf(buf + j, buflen - j, " %d", rates[i]);
4398
4399 buf[j] = '\0'; /* necessary when j == 0 */
4400}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004401EXPORT_SYMBOL_HDA(snd_print_pcm_rates);
Takashi Iwaib2022262008-11-21 21:24:03 +01004402
Takashi Iwaid5191e52009-11-16 14:58:17 +01004403/**
4404 * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer
4405 * @pcm: PCM caps bits
4406 * @buf: the string buffer to write
4407 * @buflen: the max buffer length
4408 *
4409 * used by hda_proc.c and hda_eld.c
4410 */
Takashi Iwaib2022262008-11-21 21:24:03 +01004411void snd_print_pcm_bits(int pcm, char *buf, int buflen)
4412{
4413 static unsigned int bits[] = { 8, 16, 20, 24, 32 };
4414 int i, j;
4415
4416 for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++)
4417 if (pcm & (AC_SUPPCM_BITS_8 << i))
4418 j += snprintf(buf + j, buflen - j, " %d", bits[i]);
4419
4420 buf[j] = '\0'; /* necessary when j == 0 */
4421}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004422EXPORT_SYMBOL_HDA(snd_print_pcm_bits);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01004423
4424MODULE_DESCRIPTION("HDA codec core");
4425MODULE_LICENSE("GPL");