blob: f98b47cd6cfb38fc97335c3788a8f7f5cc3afca1 [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 Iwaic8b6bf9b2005-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 Iwaib94d3532008-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 Iwaic8b6bf9b2005-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 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001089
Takashi Iwai82467612007-07-27 19:15:54 +02001090 if (is_generic_config(codec)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001091 err = snd_hda_parse_generic_codec(codec);
Takashi Iwai82467612007-07-27 19:15:54 +02001092 goto patched;
1093 }
Takashi Iwai82467612007-07-27 19:15:54 +02001094 if (codec->preset && codec->preset->patch) {
1095 err = codec->preset->patch(codec);
1096 goto patched;
1097 }
1098
1099 /* call the default parser */
Takashi Iwai82467612007-07-27 19:15:54 +02001100 err = snd_hda_parse_generic_codec(codec);
Takashi Iwai35a1e0c2007-10-19 08:13:40 +02001101 if (err < 0)
1102 printk(KERN_ERR "hda-codec: No codec parser is available\n");
Takashi Iwai82467612007-07-27 19:15:54 +02001103
1104 patched:
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001105 if (!err && codec->patch_ops.unsol_event)
1106 err = init_unsol_queue(codec->bus);
Takashi Iwaif62faed2009-12-23 09:27:51 +01001107 /* audio codec should override the mixer name */
1108 if (!err && (codec->afg || !*codec->bus->card->mixername))
1109 snprintf(codec->bus->card->mixername,
1110 sizeof(codec->bus->card->mixername),
1111 "%s %s", codec->vendor_name, codec->chip_name);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001112 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
Wu Fengguang864f92b2009-11-18 12:38:02 +08001320/**
1321 * snd_hda_pin_sense - execute pin sense measurement
1322 * @codec: the CODEC to sense
1323 * @nid: the pin NID to sense
1324 *
1325 * Execute necessary pin sense measurement and return its Presence Detect,
1326 * Impedance, ELD Valid etc. status bits.
1327 */
1328u32 snd_hda_pin_sense(struct hda_codec *codec, hda_nid_t nid)
1329{
Takashi Iwai729d55b2009-12-25 22:49:01 +01001330 u32 pincap;
Wu Fengguang864f92b2009-11-18 12:38:02 +08001331
Takashi Iwai729d55b2009-12-25 22:49:01 +01001332 if (!codec->no_trigger_sense) {
1333 pincap = snd_hda_query_pin_caps(codec, nid);
1334 if (pincap & AC_PINCAP_TRIG_REQ) /* need trigger? */
1335 snd_hda_codec_read(codec, nid, 0, AC_VERB_SET_PIN_SENSE, 0);
1336 }
Wu Fengguang864f92b2009-11-18 12:38:02 +08001337 return snd_hda_codec_read(codec, nid, 0,
1338 AC_VERB_GET_PIN_SENSE, 0);
1339}
1340EXPORT_SYMBOL_HDA(snd_hda_pin_sense);
1341
1342/**
1343 * snd_hda_jack_detect - query pin Presence Detect status
1344 * @codec: the CODEC to sense
1345 * @nid: the pin NID to sense
1346 *
1347 * Query and return the pin's Presence Detect status.
1348 */
1349int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid)
1350{
1351 u32 sense = snd_hda_pin_sense(codec, nid);
1352 return !!(sense & AC_PINSENSE_PRESENCE);
1353}
1354EXPORT_SYMBOL_HDA(snd_hda_jack_detect);
1355
Linus Torvalds1da177e2005-04-16 15:20:36 -07001356/*
1357 * read the current volume to info
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001358 * if the cache exists, read the cache value.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001359 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001360static unsigned int get_vol_mute(struct hda_codec *codec,
1361 struct hda_amp_info *info, hda_nid_t nid,
1362 int ch, int direction, int index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001363{
1364 u32 val, parm;
1365
Takashi Iwai01751f52007-08-10 16:59:39 +02001366 if (info->head.val & INFO_AMP_VOL(ch))
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001367 return info->vol[ch];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001368
1369 parm = ch ? AC_AMP_GET_RIGHT : AC_AMP_GET_LEFT;
1370 parm |= direction == HDA_OUTPUT ? AC_AMP_GET_OUTPUT : AC_AMP_GET_INPUT;
1371 parm |= index;
Takashi Iwai0ba21762007-04-16 11:29:14 +02001372 val = snd_hda_codec_read(codec, nid, 0,
1373 AC_VERB_GET_AMP_GAIN_MUTE, parm);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001374 info->vol[ch] = val & 0xff;
Takashi Iwai01751f52007-08-10 16:59:39 +02001375 info->head.val |= INFO_AMP_VOL(ch);
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001376 return info->vol[ch];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377}
1378
1379/*
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001380 * write the current volume in info to the h/w and update the cache
Linus Torvalds1da177e2005-04-16 15:20:36 -07001381 */
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001382static void put_vol_mute(struct hda_codec *codec, struct hda_amp_info *info,
Takashi Iwai0ba21762007-04-16 11:29:14 +02001383 hda_nid_t nid, int ch, int direction, int index,
1384 int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001385{
1386 u32 parm;
1387
1388 parm = ch ? AC_AMP_SET_RIGHT : AC_AMP_SET_LEFT;
1389 parm |= direction == HDA_OUTPUT ? AC_AMP_SET_OUTPUT : AC_AMP_SET_INPUT;
1390 parm |= index << AC_AMP_SET_INDEX_SHIFT;
1391 parm |= val;
1392 snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_AMP_GAIN_MUTE, parm);
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001393 info->vol[ch] = val;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001394}
1395
Takashi Iwaid5191e52009-11-16 14:58:17 +01001396/**
1397 * snd_hda_codec_amp_read - Read AMP value
1398 * @codec: HD-audio codec
1399 * @nid: NID to read the AMP value
1400 * @ch: channel (left=0 or right=1)
1401 * @direction: #HDA_INPUT or #HDA_OUTPUT
1402 * @index: the index value (only for input direction)
1403 *
1404 * Read AMP value. The volume is between 0 to 0x7f, 0x80 = mute bit.
Linus Torvalds1da177e2005-04-16 15:20:36 -07001405 */
Takashi Iwai834be882006-03-01 14:16:17 +01001406int snd_hda_codec_amp_read(struct hda_codec *codec, hda_nid_t nid, int ch,
1407 int direction, int index)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001408{
Takashi Iwai0ba21762007-04-16 11:29:14 +02001409 struct hda_amp_info *info;
1410 info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, index));
1411 if (!info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001412 return 0;
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001413 return get_vol_mute(codec, info, nid, ch, direction, index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001415EXPORT_SYMBOL_HDA(snd_hda_codec_amp_read);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001416
Takashi Iwaid5191e52009-11-16 14:58:17 +01001417/**
1418 * snd_hda_codec_amp_update - update the AMP value
1419 * @codec: HD-audio codec
1420 * @nid: NID to read the AMP value
1421 * @ch: channel (left=0 or right=1)
1422 * @direction: #HDA_INPUT or #HDA_OUTPUT
1423 * @idx: the index value (only for input direction)
1424 * @mask: bit mask to set
1425 * @val: the bits value to set
1426 *
1427 * Update the AMP value with a bit mask.
1428 * Returns 0 if the value is unchanged, 1 if changed.
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001429 */
Takashi Iwai834be882006-03-01 14:16:17 +01001430int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid, int ch,
1431 int direction, int idx, int mask, int val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001432{
Takashi Iwai0ba21762007-04-16 11:29:14 +02001433 struct hda_amp_info *info;
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001434
Takashi Iwai0ba21762007-04-16 11:29:14 +02001435 info = get_alloc_amp_hash(codec, HDA_HASH_KEY(nid, direction, idx));
1436 if (!info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001437 return 0;
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001438 val &= mask;
1439 val |= get_vol_mute(codec, info, nid, ch, direction, idx) & ~mask;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02001440 if (info->vol[ch] == val)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 return 0;
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001442 put_vol_mute(codec, info, nid, ch, direction, idx, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001443 return 1;
1444}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001445EXPORT_SYMBOL_HDA(snd_hda_codec_amp_update);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001446
Takashi Iwaid5191e52009-11-16 14:58:17 +01001447/**
1448 * snd_hda_codec_amp_stereo - update the AMP stereo values
1449 * @codec: HD-audio codec
1450 * @nid: NID to read the AMP value
1451 * @direction: #HDA_INPUT or #HDA_OUTPUT
1452 * @idx: the index value (only for input direction)
1453 * @mask: bit mask to set
1454 * @val: the bits value to set
1455 *
1456 * Update the AMP values like snd_hda_codec_amp_update(), but for a
1457 * stereo widget with the same mask and value.
Takashi Iwai47fd8302007-08-10 17:11:07 +02001458 */
1459int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
1460 int direction, int idx, int mask, int val)
1461{
1462 int ch, ret = 0;
1463 for (ch = 0; ch < 2; ch++)
1464 ret |= snd_hda_codec_amp_update(codec, nid, ch, direction,
1465 idx, mask, val);
1466 return ret;
1467}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001468EXPORT_SYMBOL_HDA(snd_hda_codec_amp_stereo);
Takashi Iwai47fd8302007-08-10 17:11:07 +02001469
Takashi Iwaicb53c622007-08-10 17:21:45 +02001470#ifdef SND_HDA_NEEDS_RESUME
Takashi Iwaid5191e52009-11-16 14:58:17 +01001471/**
1472 * snd_hda_codec_resume_amp - Resume all AMP commands from the cache
1473 * @codec: HD-audio codec
1474 *
1475 * Resume the all amp commands from the cache.
1476 */
Takashi Iwaib3ac5632007-08-10 17:03:40 +02001477void snd_hda_codec_resume_amp(struct hda_codec *codec)
1478{
Takashi Iwai603c4012008-07-30 15:01:44 +02001479 struct hda_amp_info *buffer = codec->amp_cache.buf.list;
Takashi Iwaib3ac5632007-08-10 17:03:40 +02001480 int i;
1481
Takashi Iwai603c4012008-07-30 15:01:44 +02001482 for (i = 0; i < codec->amp_cache.buf.used; i++, buffer++) {
Takashi Iwaib3ac5632007-08-10 17:03:40 +02001483 u32 key = buffer->head.key;
1484 hda_nid_t nid;
1485 unsigned int idx, dir, ch;
1486 if (!key)
1487 continue;
1488 nid = key & 0xff;
1489 idx = (key >> 16) & 0xff;
1490 dir = (key >> 24) & 0xff;
1491 for (ch = 0; ch < 2; ch++) {
1492 if (!(buffer->head.val & INFO_AMP_VOL(ch)))
1493 continue;
1494 put_vol_mute(codec, buffer, nid, ch, dir, idx,
1495 buffer->vol[ch]);
1496 }
1497 }
1498}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001499EXPORT_SYMBOL_HDA(snd_hda_codec_resume_amp);
Takashi Iwaicb53c622007-08-10 17:21:45 +02001500#endif /* SND_HDA_NEEDS_RESUME */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001501
Takashi Iwaid5191e52009-11-16 14:58:17 +01001502/**
1503 * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer
1504 *
1505 * The control element is supposed to have the private_value field
1506 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1507 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001508int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
1509 struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510{
1511 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1512 u16 nid = get_amp_nid(kcontrol);
1513 u8 chs = get_amp_channels(kcontrol);
1514 int dir = get_amp_direction(kcontrol);
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001515 unsigned int ofs = get_amp_offset(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 u32 caps;
1517
1518 caps = query_amp_caps(codec, nid, dir);
Takashi Iwai0ba21762007-04-16 11:29:14 +02001519 /* num steps */
1520 caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
1521 if (!caps) {
1522 printk(KERN_WARNING "hda_codec: "
Takashi Iwai9c8f2ab2008-01-11 16:12:23 +01001523 "num_steps = 0 for NID=0x%x (ctl = %s)\n", nid,
1524 kcontrol->id.name);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525 return -EINVAL;
1526 }
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001527 if (ofs < caps)
1528 caps -= ofs;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1530 uinfo->count = chs == 3 ? 2 : 1;
1531 uinfo->value.integer.min = 0;
1532 uinfo->value.integer.max = caps;
1533 return 0;
1534}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001535EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001536
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001537
1538static inline unsigned int
1539read_amp_value(struct hda_codec *codec, hda_nid_t nid,
1540 int ch, int dir, int idx, unsigned int ofs)
1541{
1542 unsigned int val;
1543 val = snd_hda_codec_amp_read(codec, nid, ch, dir, idx);
1544 val &= HDA_AMP_VOLMASK;
1545 if (val >= ofs)
1546 val -= ofs;
1547 else
1548 val = 0;
1549 return val;
1550}
1551
1552static inline int
1553update_amp_value(struct hda_codec *codec, hda_nid_t nid,
1554 int ch, int dir, int idx, unsigned int ofs,
1555 unsigned int val)
1556{
1557 if (val > 0)
1558 val += ofs;
1559 return snd_hda_codec_amp_update(codec, nid, ch, dir, idx,
1560 HDA_AMP_VOLMASK, val);
1561}
1562
Takashi Iwaid5191e52009-11-16 14:58:17 +01001563/**
1564 * snd_hda_mixer_amp_volume_get - Get callback for a standard AMP mixer volume
1565 *
1566 * The control element is supposed to have the private_value field
1567 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1568 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001569int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
1570 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001571{
1572 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1573 hda_nid_t nid = get_amp_nid(kcontrol);
1574 int chs = get_amp_channels(kcontrol);
1575 int dir = get_amp_direction(kcontrol);
1576 int idx = get_amp_index(kcontrol);
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001577 unsigned int ofs = get_amp_offset(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001578 long *valp = ucontrol->value.integer.value;
1579
1580 if (chs & 1)
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001581 *valp++ = read_amp_value(codec, nid, 0, dir, idx, ofs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582 if (chs & 2)
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001583 *valp = read_amp_value(codec, nid, 1, dir, idx, ofs);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 return 0;
1585}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001586EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_get);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001587
Takashi Iwaid5191e52009-11-16 14:58:17 +01001588/**
1589 * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume
1590 *
1591 * The control element is supposed to have the private_value field
1592 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1593 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001594int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
1595 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001596{
1597 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1598 hda_nid_t nid = get_amp_nid(kcontrol);
1599 int chs = get_amp_channels(kcontrol);
1600 int dir = get_amp_direction(kcontrol);
1601 int idx = get_amp_index(kcontrol);
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001602 unsigned int ofs = get_amp_offset(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001603 long *valp = ucontrol->value.integer.value;
1604 int change = 0;
1605
Takashi Iwaicb53c622007-08-10 17:21:45 +02001606 snd_hda_power_up(codec);
Nicolas Grazianob9f5a892005-07-29 12:17:20 +02001607 if (chs & 1) {
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001608 change = update_amp_value(codec, nid, 0, dir, idx, ofs, *valp);
Nicolas Grazianob9f5a892005-07-29 12:17:20 +02001609 valp++;
1610 }
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001611 if (chs & 2)
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001612 change |= update_amp_value(codec, nid, 1, dir, idx, ofs, *valp);
Takashi Iwaicb53c622007-08-10 17:21:45 +02001613 snd_hda_power_down(codec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 return change;
1615}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001616EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_volume_put);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001617
Takashi Iwaid5191e52009-11-16 14:58:17 +01001618/**
1619 * snd_hda_mixer_amp_volume_put - TLV callback for a standard AMP mixer volume
1620 *
1621 * The control element is supposed to have the private_value field
1622 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1623 */
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001624int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1625 unsigned int size, unsigned int __user *_tlv)
1626{
1627 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1628 hda_nid_t nid = get_amp_nid(kcontrol);
1629 int dir = get_amp_direction(kcontrol);
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001630 unsigned int ofs = get_amp_offset(kcontrol);
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001631 u32 caps, val1, val2;
1632
1633 if (size < 4 * sizeof(unsigned int))
1634 return -ENOMEM;
1635 caps = query_amp_caps(codec, nid, dir);
Takashi Iwai0ba21762007-04-16 11:29:14 +02001636 val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
1637 val2 = (val2 + 1) * 25;
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001638 val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
Takashi Iwai29fdbec2009-01-20 13:07:55 +01001639 val1 += ofs;
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001640 val1 = ((int)val1) * ((int)val2);
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001641 if (put_user(SNDRV_CTL_TLVT_DB_SCALE, _tlv))
1642 return -EFAULT;
1643 if (put_user(2 * sizeof(unsigned int), _tlv + 1))
1644 return -EFAULT;
1645 if (put_user(val1, _tlv + 2))
1646 return -EFAULT;
1647 if (put_user(val2, _tlv + 3))
1648 return -EFAULT;
1649 return 0;
1650}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001651EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_tlv);
Jaroslav Kysela302e9c52006-07-05 17:39:49 +02001652
Takashi Iwaid5191e52009-11-16 14:58:17 +01001653/**
1654 * snd_hda_set_vmaster_tlv - Set TLV for a virtual master control
1655 * @codec: HD-audio codec
1656 * @nid: NID of a reference widget
1657 * @dir: #HDA_INPUT or #HDA_OUTPUT
1658 * @tlv: TLV data to be stored, at least 4 elements
1659 *
1660 * Set (static) TLV data for a virtual master volume using the AMP caps
1661 * obtained from the reference NID.
1662 * The volume range is recalculated as if the max volume is 0dB.
Takashi Iwai2134ea42008-01-10 16:53:55 +01001663 */
1664void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
1665 unsigned int *tlv)
1666{
1667 u32 caps;
1668 int nums, step;
1669
1670 caps = query_amp_caps(codec, nid, dir);
1671 nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
1672 step = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
1673 step = (step + 1) * 25;
1674 tlv[0] = SNDRV_CTL_TLVT_DB_SCALE;
1675 tlv[1] = 2 * sizeof(unsigned int);
1676 tlv[2] = -nums * step;
1677 tlv[3] = step;
1678}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001679EXPORT_SYMBOL_HDA(snd_hda_set_vmaster_tlv);
Takashi Iwai2134ea42008-01-10 16:53:55 +01001680
1681/* find a mixer control element with the given name */
Takashi Iwai09f99702008-02-04 12:31:13 +01001682static struct snd_kcontrol *
1683_snd_hda_find_mixer_ctl(struct hda_codec *codec,
1684 const char *name, int idx)
Takashi Iwai2134ea42008-01-10 16:53:55 +01001685{
1686 struct snd_ctl_elem_id id;
1687 memset(&id, 0, sizeof(id));
1688 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
Takashi Iwai09f99702008-02-04 12:31:13 +01001689 id.index = idx;
Takashi Iwai18cb7102009-04-16 10:22:24 +02001690 if (snd_BUG_ON(strlen(name) >= sizeof(id.name)))
1691 return NULL;
Takashi Iwai2134ea42008-01-10 16:53:55 +01001692 strcpy(id.name, name);
1693 return snd_ctl_find_id(codec->bus->card, &id);
1694}
1695
Takashi Iwaid5191e52009-11-16 14:58:17 +01001696/**
1697 * snd_hda_find_mixer_ctl - Find a mixer control element with the given name
1698 * @codec: HD-audio codec
1699 * @name: ctl id name string
1700 *
1701 * Get the control element with the given id string and IFACE_MIXER.
1702 */
Takashi Iwai09f99702008-02-04 12:31:13 +01001703struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1704 const char *name)
1705{
1706 return _snd_hda_find_mixer_ctl(codec, name, 0);
1707}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001708EXPORT_SYMBOL_HDA(snd_hda_find_mixer_ctl);
Takashi Iwai09f99702008-02-04 12:31:13 +01001709
Takashi Iwaid5191e52009-11-16 14:58:17 +01001710/**
1711 * snd_hda_ctl-add - Add a control element and assign to the codec
1712 * @codec: HD-audio codec
1713 * @nid: corresponding NID (optional)
1714 * @kctl: the control element to assign
1715 *
1716 * Add the given control element to an array inside the codec instance.
1717 * All control elements belonging to a codec are supposed to be added
1718 * by this function so that a proper clean-up works at the free or
1719 * reconfiguration time.
1720 *
1721 * If non-zero @nid is passed, the NID is assigned to the control element.
1722 * The assignment is shown in the codec proc file.
1723 *
1724 * snd_hda_ctl_add() checks the control subdev id field whether
1725 * #HDA_SUBDEV_NID_FLAG bit is set. If set (and @nid is zero), the lower
1726 * bits value is taken as the NID to assign.
1727 */
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001728int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1729 struct snd_kcontrol *kctl)
Takashi Iwaid13bd412008-07-30 15:01:45 +02001730{
1731 int err;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001732 struct hda_nid_item *item;
Takashi Iwaid13bd412008-07-30 15:01:45 +02001733
Takashi Iwai9c96fa52009-11-16 11:25:33 +01001734 if (kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) {
Jaroslav Kysela4d02d1b2009-11-12 10:15:48 +01001735 if (nid == 0)
1736 nid = kctl->id.subdevice & 0xffff;
1737 kctl->id.subdevice = 0;
1738 }
Takashi Iwaid13bd412008-07-30 15:01:45 +02001739 err = snd_ctl_add(codec->bus->card, kctl);
1740 if (err < 0)
1741 return err;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001742 item = snd_array_new(&codec->mixers);
1743 if (!item)
Takashi Iwaid13bd412008-07-30 15:01:45 +02001744 return -ENOMEM;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001745 item->kctl = kctl;
1746 item->nid = nid;
Takashi Iwaid13bd412008-07-30 15:01:45 +02001747 return 0;
1748}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001749EXPORT_SYMBOL_HDA(snd_hda_ctl_add);
Takashi Iwaid13bd412008-07-30 15:01:45 +02001750
Takashi Iwaid5191e52009-11-16 14:58:17 +01001751/**
1752 * snd_hda_ctls_clear - Clear all controls assigned to the given codec
1753 * @codec: HD-audio codec
1754 */
Takashi Iwaid13bd412008-07-30 15:01:45 +02001755void snd_hda_ctls_clear(struct hda_codec *codec)
1756{
1757 int i;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001758 struct hda_nid_item *items = codec->mixers.list;
Takashi Iwaid13bd412008-07-30 15:01:45 +02001759 for (i = 0; i < codec->mixers.used; i++)
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001760 snd_ctl_remove(codec->bus->card, items[i].kctl);
Takashi Iwaid13bd412008-07-30 15:01:45 +02001761 snd_array_free(&codec->mixers);
1762}
1763
Takashi Iwaia65d6292009-02-23 16:57:04 +01001764/* pseudo device locking
1765 * toggle card->shutdown to allow/disallow the device access (as a hack)
1766 */
1767static int hda_lock_devices(struct snd_card *card)
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001768{
Takashi Iwaia65d6292009-02-23 16:57:04 +01001769 spin_lock(&card->files_lock);
1770 if (card->shutdown) {
1771 spin_unlock(&card->files_lock);
1772 return -EINVAL;
1773 }
1774 card->shutdown = 1;
1775 spin_unlock(&card->files_lock);
1776 return 0;
1777}
1778
1779static void hda_unlock_devices(struct snd_card *card)
1780{
1781 spin_lock(&card->files_lock);
1782 card->shutdown = 0;
1783 spin_unlock(&card->files_lock);
1784}
1785
Takashi Iwaid5191e52009-11-16 14:58:17 +01001786/**
1787 * snd_hda_codec_reset - Clear all objects assigned to the codec
1788 * @codec: HD-audio codec
1789 *
1790 * This frees the all PCM and control elements assigned to the codec, and
1791 * clears the caches and restores the pin default configurations.
1792 *
1793 * When a device is being used, it returns -EBSY. If successfully freed,
1794 * returns zero.
1795 */
Takashi Iwaia65d6292009-02-23 16:57:04 +01001796int snd_hda_codec_reset(struct hda_codec *codec)
1797{
1798 struct snd_card *card = codec->bus->card;
1799 int i, pcm;
1800
1801 if (hda_lock_devices(card) < 0)
1802 return -EBUSY;
1803 /* check whether the codec isn't used by any mixer or PCM streams */
1804 if (!list_empty(&card->ctl_files)) {
1805 hda_unlock_devices(card);
1806 return -EBUSY;
1807 }
1808 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
1809 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
1810 if (!cpcm->pcm)
1811 continue;
1812 if (cpcm->pcm->streams[0].substream_opened ||
1813 cpcm->pcm->streams[1].substream_opened) {
1814 hda_unlock_devices(card);
1815 return -EBUSY;
1816 }
1817 }
1818
1819 /* OK, let it free */
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001820
1821#ifdef CONFIG_SND_HDA_POWER_SAVE
1822 cancel_delayed_work(&codec->power_work);
Takashi Iwai6acaed32009-01-12 10:09:24 +01001823 flush_workqueue(codec->bus->workq);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001824#endif
1825 snd_hda_ctls_clear(codec);
1826 /* relase PCMs */
1827 for (i = 0; i < codec->num_pcms; i++) {
Takashi Iwai529bd6c2008-11-27 14:17:01 +01001828 if (codec->pcm_info[i].pcm) {
Takashi Iwaia65d6292009-02-23 16:57:04 +01001829 snd_device_free(card, codec->pcm_info[i].pcm);
Takashi Iwai529bd6c2008-11-27 14:17:01 +01001830 clear_bit(codec->pcm_info[i].device,
1831 codec->bus->pcm_dev_bits);
1832 }
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001833 }
1834 if (codec->patch_ops.free)
1835 codec->patch_ops.free(codec);
Takashi Iwai56d17712008-11-28 14:36:23 +01001836 codec->proc_widget_hook = NULL;
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001837 codec->spec = NULL;
1838 free_hda_cache(&codec->amp_cache);
1839 free_hda_cache(&codec->cmd_cache);
Takashi Iwai827057f2008-12-19 10:12:02 +01001840 init_hda_cache(&codec->amp_cache, sizeof(struct hda_amp_info));
1841 init_hda_cache(&codec->cmd_cache, sizeof(struct hda_cache_head));
Takashi Iwai346ff702009-02-23 09:42:57 +01001842 /* free only driver_pins so that init_pins + user_pins are restored */
1843 snd_array_free(&codec->driver_pins);
Takashi Iwai3be14142009-02-20 14:11:16 +01001844 restore_pincfgs(codec);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001845 codec->num_pcms = 0;
1846 codec->pcm_info = NULL;
1847 codec->preset = NULL;
Takashi Iwaid1f1af22009-03-02 10:35:29 +01001848 memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
1849 codec->slave_dig_outs = NULL;
1850 codec->spdif_status_reset = 0;
Takashi Iwai1289e9e2008-11-27 15:47:11 +01001851 module_put(codec->owner);
1852 codec->owner = NULL;
Takashi Iwaia65d6292009-02-23 16:57:04 +01001853
1854 /* allow device access again */
1855 hda_unlock_devices(card);
1856 return 0;
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02001857}
1858
Takashi Iwaid5191e52009-11-16 14:58:17 +01001859/**
1860 * snd_hda_add_vmaster - create a virtual master control and add slaves
1861 * @codec: HD-audio codec
1862 * @name: vmaster control name
1863 * @tlv: TLV data (optional)
1864 * @slaves: slave control names (optional)
1865 *
1866 * Create a virtual master control with the given name. The TLV data
1867 * must be either NULL or a valid data.
1868 *
1869 * @slaves is a NULL-terminated array of strings, each of which is a
1870 * slave control name. All controls with these names are assigned to
1871 * the new virtual master control.
1872 *
1873 * This function returns zero if successful or a negative error code.
1874 */
Takashi Iwai2134ea42008-01-10 16:53:55 +01001875int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1876 unsigned int *tlv, const char **slaves)
1877{
1878 struct snd_kcontrol *kctl;
1879 const char **s;
1880 int err;
1881
Takashi Iwai2f085542008-02-22 18:43:50 +01001882 for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++)
1883 ;
1884 if (!*s) {
1885 snd_printdd("No slave found for %s\n", name);
1886 return 0;
1887 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01001888 kctl = snd_ctl_make_virtual_master(name, tlv);
1889 if (!kctl)
1890 return -ENOMEM;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01001891 err = snd_hda_ctl_add(codec, 0, kctl);
Takashi Iwai2134ea42008-01-10 16:53:55 +01001892 if (err < 0)
1893 return err;
1894
1895 for (s = slaves; *s; s++) {
1896 struct snd_kcontrol *sctl;
Takashi Iwai7a411ee2009-03-06 10:08:14 +01001897 int i = 0;
1898 for (;;) {
1899 sctl = _snd_hda_find_mixer_ctl(codec, *s, i);
1900 if (!sctl) {
1901 if (!i)
1902 snd_printdd("Cannot find slave %s, "
1903 "skipped\n", *s);
1904 break;
1905 }
1906 err = snd_ctl_add_slave(kctl, sctl);
1907 if (err < 0)
1908 return err;
1909 i++;
Takashi Iwai2134ea42008-01-10 16:53:55 +01001910 }
Takashi Iwai2134ea42008-01-10 16:53:55 +01001911 }
1912 return 0;
1913}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001914EXPORT_SYMBOL_HDA(snd_hda_add_vmaster);
Takashi Iwai2134ea42008-01-10 16:53:55 +01001915
Takashi Iwaid5191e52009-11-16 14:58:17 +01001916/**
1917 * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch
1918 *
1919 * The control element is supposed to have the private_value field
1920 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1921 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001922int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
1923 struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001924{
1925 int chs = get_amp_channels(kcontrol);
1926
1927 uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
1928 uinfo->count = chs == 3 ? 2 : 1;
1929 uinfo->value.integer.min = 0;
1930 uinfo->value.integer.max = 1;
1931 return 0;
1932}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001933EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001934
Takashi Iwaid5191e52009-11-16 14:58:17 +01001935/**
1936 * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch
1937 *
1938 * The control element is supposed to have the private_value field
1939 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1940 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001941int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
1942 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001943{
1944 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1945 hda_nid_t nid = get_amp_nid(kcontrol);
1946 int chs = get_amp_channels(kcontrol);
1947 int dir = get_amp_direction(kcontrol);
1948 int idx = get_amp_index(kcontrol);
1949 long *valp = ucontrol->value.integer.value;
1950
1951 if (chs & 1)
Takashi Iwai0ba21762007-04-16 11:29:14 +02001952 *valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) &
Takashi Iwai47fd8302007-08-10 17:11:07 +02001953 HDA_AMP_MUTE) ? 0 : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001954 if (chs & 2)
Takashi Iwai0ba21762007-04-16 11:29:14 +02001955 *valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) &
Takashi Iwai47fd8302007-08-10 17:11:07 +02001956 HDA_AMP_MUTE) ? 0 : 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001957 return 0;
1958}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001959EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_get);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001960
Takashi Iwaid5191e52009-11-16 14:58:17 +01001961/**
1962 * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch
1963 *
1964 * The control element is supposed to have the private_value field
1965 * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1966 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02001967int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
1968 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001969{
1970 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1971 hda_nid_t nid = get_amp_nid(kcontrol);
1972 int chs = get_amp_channels(kcontrol);
1973 int dir = get_amp_direction(kcontrol);
1974 int idx = get_amp_index(kcontrol);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001975 long *valp = ucontrol->value.integer.value;
1976 int change = 0;
1977
Takashi Iwaicb53c622007-08-10 17:21:45 +02001978 snd_hda_power_up(codec);
Nicolas Grazianob9f5a892005-07-29 12:17:20 +02001979 if (chs & 1) {
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001980 change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
Takashi Iwai47fd8302007-08-10 17:11:07 +02001981 HDA_AMP_MUTE,
1982 *valp ? 0 : HDA_AMP_MUTE);
Nicolas Grazianob9f5a892005-07-29 12:17:20 +02001983 valp++;
1984 }
Takashi Iwai4a19fae2005-06-08 14:43:58 +02001985 if (chs & 2)
1986 change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
Takashi Iwai47fd8302007-08-10 17:11:07 +02001987 HDA_AMP_MUTE,
1988 *valp ? 0 : HDA_AMP_MUTE);
Takashi Iwaicb53c622007-08-10 17:21:45 +02001989#ifdef CONFIG_SND_HDA_POWER_SAVE
1990 if (codec->patch_ops.check_power_status)
1991 codec->patch_ops.check_power_status(codec, nid);
1992#endif
1993 snd_hda_power_down(codec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001994 return change;
1995}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01001996EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001997
Takashi Iwai67d634c2009-11-16 15:35:59 +01001998#ifdef CONFIG_SND_HDA_INPUT_BEEP
Takashi Iwaid5191e52009-11-16 14:58:17 +01001999/**
2000 * snd_hda_mixer_amp_switch_put_beep - Put callback for a beep AMP switch
2001 *
2002 * This function calls snd_hda_enable_beep_device(), which behaves differently
2003 * depending on beep_mode option.
2004 */
Jaroslav Kysela123c07a2009-10-21 14:48:23 +02002005int snd_hda_mixer_amp_switch_put_beep(struct snd_kcontrol *kcontrol,
2006 struct snd_ctl_elem_value *ucontrol)
2007{
2008 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2009 long *valp = ucontrol->value.integer.value;
2010
2011 snd_hda_enable_beep_device(codec, *valp);
2012 return snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2013}
2014EXPORT_SYMBOL_HDA(snd_hda_mixer_amp_switch_put_beep);
Takashi Iwai67d634c2009-11-16 15:35:59 +01002015#endif /* CONFIG_SND_HDA_INPUT_BEEP */
Jaroslav Kysela123c07a2009-10-21 14:48:23 +02002016
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017/*
Takashi Iwai985be542005-11-02 18:26:49 +01002018 * bound volume controls
2019 *
2020 * bind multiple volumes (# indices, from 0)
2021 */
2022
2023#define AMP_VAL_IDX_SHIFT 19
2024#define AMP_VAL_IDX_MASK (0x0f<<19)
2025
Takashi Iwaid5191e52009-11-16 14:58:17 +01002026/**
2027 * snd_hda_mixer_bind_switch_get - Get callback for a bound volume control
2028 *
2029 * The control element is supposed to have the private_value field
2030 * set up via HDA_BIND_MUTE*() macros.
2031 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02002032int snd_hda_mixer_bind_switch_get(struct snd_kcontrol *kcontrol,
2033 struct snd_ctl_elem_value *ucontrol)
Takashi Iwai985be542005-11-02 18:26:49 +01002034{
2035 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2036 unsigned long pval;
2037 int err;
2038
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002039 mutex_lock(&codec->control_mutex);
Takashi Iwai985be542005-11-02 18:26:49 +01002040 pval = kcontrol->private_value;
2041 kcontrol->private_value = pval & ~AMP_VAL_IDX_MASK; /* index 0 */
2042 err = snd_hda_mixer_amp_switch_get(kcontrol, ucontrol);
2043 kcontrol->private_value = pval;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002044 mutex_unlock(&codec->control_mutex);
Takashi Iwai985be542005-11-02 18:26:49 +01002045 return err;
2046}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002047EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_get);
Takashi Iwai985be542005-11-02 18:26:49 +01002048
Takashi Iwaid5191e52009-11-16 14:58:17 +01002049/**
2050 * snd_hda_mixer_bind_switch_put - Put callback for a bound volume control
2051 *
2052 * The control element is supposed to have the private_value field
2053 * set up via HDA_BIND_MUTE*() macros.
2054 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02002055int snd_hda_mixer_bind_switch_put(struct snd_kcontrol *kcontrol,
2056 struct snd_ctl_elem_value *ucontrol)
Takashi Iwai985be542005-11-02 18:26:49 +01002057{
2058 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2059 unsigned long pval;
2060 int i, indices, err = 0, change = 0;
2061
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002062 mutex_lock(&codec->control_mutex);
Takashi Iwai985be542005-11-02 18:26:49 +01002063 pval = kcontrol->private_value;
2064 indices = (pval & AMP_VAL_IDX_MASK) >> AMP_VAL_IDX_SHIFT;
2065 for (i = 0; i < indices; i++) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02002066 kcontrol->private_value = (pval & ~AMP_VAL_IDX_MASK) |
2067 (i << AMP_VAL_IDX_SHIFT);
Takashi Iwai985be542005-11-02 18:26:49 +01002068 err = snd_hda_mixer_amp_switch_put(kcontrol, ucontrol);
2069 if (err < 0)
2070 break;
2071 change |= err;
2072 }
2073 kcontrol->private_value = pval;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002074 mutex_unlock(&codec->control_mutex);
Takashi Iwai985be542005-11-02 18:26:49 +01002075 return err < 0 ? err : change;
2076}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002077EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_switch_put);
Takashi Iwai985be542005-11-02 18:26:49 +01002078
Takashi Iwaid5191e52009-11-16 14:58:17 +01002079/**
2080 * snd_hda_mixer_bind_ctls_info - Info callback for a generic bound control
2081 *
2082 * The control element is supposed to have the private_value field
2083 * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
Takashi Iwai532d5382007-07-27 19:02:40 +02002084 */
2085int snd_hda_mixer_bind_ctls_info(struct snd_kcontrol *kcontrol,
2086 struct snd_ctl_elem_info *uinfo)
2087{
2088 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2089 struct hda_bind_ctls *c;
2090 int err;
2091
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002092 mutex_lock(&codec->control_mutex);
Serge A. Suchkov14c65f92008-02-22 18:43:16 +01002093 c = (struct hda_bind_ctls *)kcontrol->private_value;
Takashi Iwai532d5382007-07-27 19:02:40 +02002094 kcontrol->private_value = *c->values;
2095 err = c->ops->info(kcontrol, uinfo);
2096 kcontrol->private_value = (long)c;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002097 mutex_unlock(&codec->control_mutex);
Takashi Iwai532d5382007-07-27 19:02:40 +02002098 return err;
2099}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002100EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_info);
Takashi Iwai532d5382007-07-27 19:02:40 +02002101
Takashi Iwaid5191e52009-11-16 14:58:17 +01002102/**
2103 * snd_hda_mixer_bind_ctls_get - Get callback for a generic bound control
2104 *
2105 * The control element is supposed to have the private_value field
2106 * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
2107 */
Takashi Iwai532d5382007-07-27 19:02:40 +02002108int snd_hda_mixer_bind_ctls_get(struct snd_kcontrol *kcontrol,
2109 struct snd_ctl_elem_value *ucontrol)
2110{
2111 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2112 struct hda_bind_ctls *c;
2113 int err;
2114
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002115 mutex_lock(&codec->control_mutex);
Serge A. Suchkov14c65f92008-02-22 18:43:16 +01002116 c = (struct hda_bind_ctls *)kcontrol->private_value;
Takashi Iwai532d5382007-07-27 19:02:40 +02002117 kcontrol->private_value = *c->values;
2118 err = c->ops->get(kcontrol, ucontrol);
2119 kcontrol->private_value = (long)c;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002120 mutex_unlock(&codec->control_mutex);
Takashi Iwai532d5382007-07-27 19:02:40 +02002121 return err;
2122}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002123EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_get);
Takashi Iwai532d5382007-07-27 19:02:40 +02002124
Takashi Iwaid5191e52009-11-16 14:58:17 +01002125/**
2126 * snd_hda_mixer_bind_ctls_put - Put callback for a generic bound control
2127 *
2128 * The control element is supposed to have the private_value field
2129 * set up via HDA_BIND_VOL() or HDA_BIND_SW() macros.
2130 */
Takashi Iwai532d5382007-07-27 19:02:40 +02002131int snd_hda_mixer_bind_ctls_put(struct snd_kcontrol *kcontrol,
2132 struct snd_ctl_elem_value *ucontrol)
2133{
2134 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2135 struct hda_bind_ctls *c;
2136 unsigned long *vals;
2137 int err = 0, change = 0;
2138
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002139 mutex_lock(&codec->control_mutex);
Serge A. Suchkov14c65f92008-02-22 18:43:16 +01002140 c = (struct hda_bind_ctls *)kcontrol->private_value;
Takashi Iwai532d5382007-07-27 19:02:40 +02002141 for (vals = c->values; *vals; vals++) {
2142 kcontrol->private_value = *vals;
2143 err = c->ops->put(kcontrol, ucontrol);
2144 if (err < 0)
2145 break;
2146 change |= err;
2147 }
2148 kcontrol->private_value = (long)c;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002149 mutex_unlock(&codec->control_mutex);
Takashi Iwai532d5382007-07-27 19:02:40 +02002150 return err < 0 ? err : change;
2151}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002152EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_ctls_put);
Takashi Iwai532d5382007-07-27 19:02:40 +02002153
Takashi Iwaid5191e52009-11-16 14:58:17 +01002154/**
2155 * snd_hda_mixer_bind_tlv - TLV callback for a generic bound control
2156 *
2157 * The control element is supposed to have the private_value field
2158 * set up via HDA_BIND_VOL() macro.
2159 */
Takashi Iwai532d5382007-07-27 19:02:40 +02002160int snd_hda_mixer_bind_tlv(struct snd_kcontrol *kcontrol, int op_flag,
2161 unsigned int size, unsigned int __user *tlv)
2162{
2163 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2164 struct hda_bind_ctls *c;
2165 int err;
2166
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002167 mutex_lock(&codec->control_mutex);
Serge A. Suchkov14c65f92008-02-22 18:43:16 +01002168 c = (struct hda_bind_ctls *)kcontrol->private_value;
Takashi Iwai532d5382007-07-27 19:02:40 +02002169 kcontrol->private_value = *c->values;
2170 err = c->ops->tlv(kcontrol, op_flag, size, tlv);
2171 kcontrol->private_value = (long)c;
Wu Fengguang5a9e02e2009-01-09 16:45:24 +08002172 mutex_unlock(&codec->control_mutex);
Takashi Iwai532d5382007-07-27 19:02:40 +02002173 return err;
2174}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002175EXPORT_SYMBOL_HDA(snd_hda_mixer_bind_tlv);
Takashi Iwai532d5382007-07-27 19:02:40 +02002176
2177struct hda_ctl_ops snd_hda_bind_vol = {
2178 .info = snd_hda_mixer_amp_volume_info,
2179 .get = snd_hda_mixer_amp_volume_get,
2180 .put = snd_hda_mixer_amp_volume_put,
2181 .tlv = snd_hda_mixer_amp_tlv
2182};
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002183EXPORT_SYMBOL_HDA(snd_hda_bind_vol);
Takashi Iwai532d5382007-07-27 19:02:40 +02002184
2185struct hda_ctl_ops snd_hda_bind_sw = {
2186 .info = snd_hda_mixer_amp_switch_info,
2187 .get = snd_hda_mixer_amp_switch_get,
2188 .put = snd_hda_mixer_amp_switch_put,
2189 .tlv = snd_hda_mixer_amp_tlv
2190};
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002191EXPORT_SYMBOL_HDA(snd_hda_bind_sw);
Takashi Iwai532d5382007-07-27 19:02:40 +02002192
2193/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002194 * SPDIF out controls
2195 */
2196
Takashi Iwai0ba21762007-04-16 11:29:14 +02002197static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol,
2198 struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002199{
2200 uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2201 uinfo->count = 1;
2202 return 0;
2203}
2204
Takashi Iwai0ba21762007-04-16 11:29:14 +02002205static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol,
2206 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002207{
2208 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
2209 IEC958_AES0_NONAUDIO |
2210 IEC958_AES0_CON_EMPHASIS_5015 |
2211 IEC958_AES0_CON_NOT_COPYRIGHT;
2212 ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY |
2213 IEC958_AES1_CON_ORIGINAL;
2214 return 0;
2215}
2216
Takashi Iwai0ba21762007-04-16 11:29:14 +02002217static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol,
2218 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002219{
2220 ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
2221 IEC958_AES0_NONAUDIO |
2222 IEC958_AES0_PRO_EMPHASIS_5015;
2223 return 0;
2224}
2225
Takashi Iwai0ba21762007-04-16 11:29:14 +02002226static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
2227 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002228{
2229 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2230
2231 ucontrol->value.iec958.status[0] = codec->spdif_status & 0xff;
2232 ucontrol->value.iec958.status[1] = (codec->spdif_status >> 8) & 0xff;
2233 ucontrol->value.iec958.status[2] = (codec->spdif_status >> 16) & 0xff;
2234 ucontrol->value.iec958.status[3] = (codec->spdif_status >> 24) & 0xff;
2235
2236 return 0;
2237}
2238
2239/* convert from SPDIF status bits to HDA SPDIF bits
2240 * bit 0 (DigEn) is always set zero (to be filled later)
2241 */
2242static unsigned short convert_from_spdif_status(unsigned int sbits)
2243{
2244 unsigned short val = 0;
2245
2246 if (sbits & IEC958_AES0_PROFESSIONAL)
Takashi Iwai0ba21762007-04-16 11:29:14 +02002247 val |= AC_DIG1_PROFESSIONAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002248 if (sbits & IEC958_AES0_NONAUDIO)
Takashi Iwai0ba21762007-04-16 11:29:14 +02002249 val |= AC_DIG1_NONAUDIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002250 if (sbits & IEC958_AES0_PROFESSIONAL) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02002251 if ((sbits & IEC958_AES0_PRO_EMPHASIS) ==
2252 IEC958_AES0_PRO_EMPHASIS_5015)
2253 val |= AC_DIG1_EMPHASIS;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002254 } else {
Takashi Iwai0ba21762007-04-16 11:29:14 +02002255 if ((sbits & IEC958_AES0_CON_EMPHASIS) ==
2256 IEC958_AES0_CON_EMPHASIS_5015)
2257 val |= AC_DIG1_EMPHASIS;
2258 if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
2259 val |= AC_DIG1_COPYRIGHT;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002260 if (sbits & (IEC958_AES1_CON_ORIGINAL << 8))
Takashi Iwai0ba21762007-04-16 11:29:14 +02002261 val |= AC_DIG1_LEVEL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002262 val |= sbits & (IEC958_AES1_CON_CATEGORY << 8);
2263 }
2264 return val;
2265}
2266
2267/* convert to SPDIF status bits from HDA SPDIF bits
2268 */
2269static unsigned int convert_to_spdif_status(unsigned short val)
2270{
2271 unsigned int sbits = 0;
2272
Takashi Iwai0ba21762007-04-16 11:29:14 +02002273 if (val & AC_DIG1_NONAUDIO)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002274 sbits |= IEC958_AES0_NONAUDIO;
Takashi Iwai0ba21762007-04-16 11:29:14 +02002275 if (val & AC_DIG1_PROFESSIONAL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002276 sbits |= IEC958_AES0_PROFESSIONAL;
2277 if (sbits & IEC958_AES0_PROFESSIONAL) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02002278 if (sbits & AC_DIG1_EMPHASIS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002279 sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
2280 } else {
Takashi Iwai0ba21762007-04-16 11:29:14 +02002281 if (val & AC_DIG1_EMPHASIS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002282 sbits |= IEC958_AES0_CON_EMPHASIS_5015;
Takashi Iwai0ba21762007-04-16 11:29:14 +02002283 if (!(val & AC_DIG1_COPYRIGHT))
Linus Torvalds1da177e2005-04-16 15:20:36 -07002284 sbits |= IEC958_AES0_CON_NOT_COPYRIGHT;
Takashi Iwai0ba21762007-04-16 11:29:14 +02002285 if (val & AC_DIG1_LEVEL)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002286 sbits |= (IEC958_AES1_CON_ORIGINAL << 8);
2287 sbits |= val & (0x7f << 8);
2288 }
2289 return sbits;
2290}
2291
Takashi Iwai2f728532008-09-25 16:32:41 +02002292/* set digital convert verbs both for the given NID and its slaves */
2293static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
2294 int verb, int val)
2295{
2296 hda_nid_t *d;
2297
Takashi Iwai9e976972008-11-25 08:17:20 +01002298 snd_hda_codec_write_cache(codec, nid, 0, verb, val);
Takashi Iwai2f728532008-09-25 16:32:41 +02002299 d = codec->slave_dig_outs;
2300 if (!d)
2301 return;
2302 for (; *d; d++)
Takashi Iwai9e976972008-11-25 08:17:20 +01002303 snd_hda_codec_write_cache(codec, *d, 0, verb, val);
Takashi Iwai2f728532008-09-25 16:32:41 +02002304}
2305
2306static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid,
2307 int dig1, int dig2)
2308{
2309 if (dig1 != -1)
2310 set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_1, dig1);
2311 if (dig2 != -1)
2312 set_dig_out(codec, nid, AC_VERB_SET_DIGI_CONVERT_2, dig2);
2313}
2314
Takashi Iwai0ba21762007-04-16 11:29:14 +02002315static int snd_hda_spdif_default_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);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002324 codec->spdif_status = ucontrol->value.iec958.status[0] |
2325 ((unsigned int)ucontrol->value.iec958.status[1] << 8) |
2326 ((unsigned int)ucontrol->value.iec958.status[2] << 16) |
2327 ((unsigned int)ucontrol->value.iec958.status[3] << 24);
2328 val = convert_from_spdif_status(codec->spdif_status);
2329 val |= codec->spdif_ctls & 1;
2330 change = codec->spdif_ctls != val;
2331 codec->spdif_ctls = val;
2332
Takashi Iwai2f728532008-09-25 16:32:41 +02002333 if (change)
2334 set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002335
Ingo Molnar62932df2006-01-16 16:34:20 +01002336 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002337 return change;
2338}
2339
Takashi Iwaia5ce8892007-07-23 15:42:26 +02002340#define snd_hda_spdif_out_switch_info snd_ctl_boolean_mono_info
Linus Torvalds1da177e2005-04-16 15:20:36 -07002341
Takashi Iwai0ba21762007-04-16 11:29:14 +02002342static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
2343 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002344{
2345 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2346
Takashi Iwai0ba21762007-04-16 11:29:14 +02002347 ucontrol->value.integer.value[0] = codec->spdif_ctls & AC_DIG1_ENABLE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002348 return 0;
2349}
2350
Takashi Iwai0ba21762007-04-16 11:29:14 +02002351static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
2352 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002353{
2354 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2355 hda_nid_t nid = kcontrol->private_value;
2356 unsigned short val;
2357 int change;
2358
Ingo Molnar62932df2006-01-16 16:34:20 +01002359 mutex_lock(&codec->spdif_mutex);
Takashi Iwai0ba21762007-04-16 11:29:14 +02002360 val = codec->spdif_ctls & ~AC_DIG1_ENABLE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002361 if (ucontrol->value.integer.value[0])
Takashi Iwai0ba21762007-04-16 11:29:14 +02002362 val |= AC_DIG1_ENABLE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002363 change = codec->spdif_ctls != val;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02002364 if (change) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002365 codec->spdif_ctls = val;
Takashi Iwai2f728532008-09-25 16:32:41 +02002366 set_dig_out_convert(codec, nid, val & 0xff, -1);
Takashi Iwai0ba21762007-04-16 11:29:14 +02002367 /* unmute amp switch (if any) */
2368 if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
Takashi Iwai47fd8302007-08-10 17:11:07 +02002369 (val & AC_DIG1_ENABLE))
2370 snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2371 HDA_AMP_MUTE, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002372 }
Ingo Molnar62932df2006-01-16 16:34:20 +01002373 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002374 return change;
2375}
2376
Takashi Iwaic8b6bf9b2005-11-17 14:57:47 +01002377static struct snd_kcontrol_new dig_mixes[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002378 {
2379 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2380 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2381 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,CON_MASK),
2382 .info = snd_hda_spdif_mask_info,
2383 .get = snd_hda_spdif_cmask_get,
2384 },
2385 {
2386 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2387 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2388 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,PRO_MASK),
2389 .info = snd_hda_spdif_mask_info,
2390 .get = snd_hda_spdif_pmask_get,
2391 },
2392 {
2393 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2394 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,DEFAULT),
2395 .info = snd_hda_spdif_mask_info,
2396 .get = snd_hda_spdif_default_get,
2397 .put = snd_hda_spdif_default_put,
2398 },
2399 {
2400 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2401 .name = SNDRV_CTL_NAME_IEC958("",PLAYBACK,SWITCH),
2402 .info = snd_hda_spdif_out_switch_info,
2403 .get = snd_hda_spdif_out_switch_get,
2404 .put = snd_hda_spdif_out_switch_put,
2405 },
2406 { } /* end */
2407};
2408
Takashi Iwai09f99702008-02-04 12:31:13 +01002409#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */
2410
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411/**
2412 * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
2413 * @codec: the HDA codec
2414 * @nid: audio out widget NID
2415 *
2416 * Creates controls related with the SPDIF output.
2417 * Called from each patch supporting the SPDIF out.
2418 *
2419 * Returns 0 if successful, or a negative error code.
2420 */
Takashi Iwai12f288b2007-08-02 15:51:59 +02002421int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002422{
2423 int err;
Takashi Iwaic8b6bf9b2005-11-17 14:57:47 +01002424 struct snd_kcontrol *kctl;
2425 struct snd_kcontrol_new *dig_mix;
Takashi Iwai09f99702008-02-04 12:31:13 +01002426 int idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002427
Takashi Iwai09f99702008-02-04 12:31:13 +01002428 for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
2429 if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch",
2430 idx))
2431 break;
2432 }
2433 if (idx >= SPDIF_MAX_IDX) {
2434 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
2435 return -EBUSY;
2436 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002437 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
2438 kctl = snd_ctl_new1(dig_mix, codec);
Takashi Iwaib91f0802008-11-04 08:43:08 +01002439 if (!kctl)
2440 return -ENOMEM;
Takashi Iwai09f99702008-02-04 12:31:13 +01002441 kctl->id.index = idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442 kctl->private_value = nid;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01002443 err = snd_hda_ctl_add(codec, nid, kctl);
Takashi Iwai0ba21762007-04-16 11:29:14 +02002444 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002445 return err;
2446 }
Takashi Iwai0ba21762007-04-16 11:29:14 +02002447 codec->spdif_ctls =
Andrew Paprocki3982d172007-12-19 12:13:44 +01002448 snd_hda_codec_read(codec, nid, 0,
2449 AC_VERB_GET_DIGI_CONVERT_1, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002450 codec->spdif_status = convert_to_spdif_status(codec->spdif_ctls);
2451 return 0;
2452}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002453EXPORT_SYMBOL_HDA(snd_hda_create_spdif_out_ctls);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002454
2455/*
Takashi Iwai9a081602008-02-12 18:37:26 +01002456 * SPDIF sharing with analog output
2457 */
2458static int spdif_share_sw_get(struct snd_kcontrol *kcontrol,
2459 struct snd_ctl_elem_value *ucontrol)
2460{
2461 struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
2462 ucontrol->value.integer.value[0] = mout->share_spdif;
2463 return 0;
2464}
2465
2466static int spdif_share_sw_put(struct snd_kcontrol *kcontrol,
2467 struct snd_ctl_elem_value *ucontrol)
2468{
2469 struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
2470 mout->share_spdif = !!ucontrol->value.integer.value[0];
2471 return 0;
2472}
2473
2474static struct snd_kcontrol_new spdif_share_sw = {
2475 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2476 .name = "IEC958 Default PCM Playback Switch",
2477 .info = snd_ctl_boolean_mono_info,
2478 .get = spdif_share_sw_get,
2479 .put = spdif_share_sw_put,
2480};
2481
Takashi Iwaid5191e52009-11-16 14:58:17 +01002482/**
2483 * snd_hda_create_spdif_share_sw - create Default PCM switch
2484 * @codec: the HDA codec
2485 * @mout: multi-out instance
2486 */
Takashi Iwai9a081602008-02-12 18:37:26 +01002487int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
2488 struct hda_multi_out *mout)
2489{
2490 if (!mout->dig_out_nid)
2491 return 0;
2492 /* ATTENTION: here mout is passed as private_data, instead of codec */
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01002493 return snd_hda_ctl_add(codec, mout->dig_out_nid,
2494 snd_ctl_new1(&spdif_share_sw, mout));
Takashi Iwai9a081602008-02-12 18:37:26 +01002495}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002496EXPORT_SYMBOL_HDA(snd_hda_create_spdif_share_sw);
Takashi Iwai9a081602008-02-12 18:37:26 +01002497
2498/*
Linus Torvalds1da177e2005-04-16 15:20:36 -07002499 * SPDIF input
2500 */
2501
2502#define snd_hda_spdif_in_switch_info snd_hda_spdif_out_switch_info
2503
Takashi Iwai0ba21762007-04-16 11:29:14 +02002504static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol,
2505 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002506{
2507 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2508
2509 ucontrol->value.integer.value[0] = codec->spdif_in_enable;
2510 return 0;
2511}
2512
Takashi Iwai0ba21762007-04-16 11:29:14 +02002513static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
2514 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002515{
2516 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2517 hda_nid_t nid = kcontrol->private_value;
2518 unsigned int val = !!ucontrol->value.integer.value[0];
2519 int change;
2520
Ingo Molnar62932df2006-01-16 16:34:20 +01002521 mutex_lock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002522 change = codec->spdif_in_enable != val;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02002523 if (change) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002524 codec->spdif_in_enable = val;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02002525 snd_hda_codec_write_cache(codec, nid, 0,
2526 AC_VERB_SET_DIGI_CONVERT_1, val);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002527 }
Ingo Molnar62932df2006-01-16 16:34:20 +01002528 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002529 return change;
2530}
2531
Takashi Iwai0ba21762007-04-16 11:29:14 +02002532static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
2533 struct snd_ctl_elem_value *ucontrol)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002534{
2535 struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2536 hda_nid_t nid = kcontrol->private_value;
2537 unsigned short val;
2538 unsigned int sbits;
2539
Andrew Paprocki3982d172007-12-19 12:13:44 +01002540 val = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DIGI_CONVERT_1, 0);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002541 sbits = convert_to_spdif_status(val);
2542 ucontrol->value.iec958.status[0] = sbits;
2543 ucontrol->value.iec958.status[1] = sbits >> 8;
2544 ucontrol->value.iec958.status[2] = sbits >> 16;
2545 ucontrol->value.iec958.status[3] = sbits >> 24;
2546 return 0;
2547}
2548
Takashi Iwaic8b6bf9b2005-11-17 14:57:47 +01002549static struct snd_kcontrol_new dig_in_ctls[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002550 {
2551 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2552 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,SWITCH),
2553 .info = snd_hda_spdif_in_switch_info,
2554 .get = snd_hda_spdif_in_switch_get,
2555 .put = snd_hda_spdif_in_switch_put,
2556 },
2557 {
2558 .access = SNDRV_CTL_ELEM_ACCESS_READ,
2559 .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2560 .name = SNDRV_CTL_NAME_IEC958("",CAPTURE,DEFAULT),
2561 .info = snd_hda_spdif_mask_info,
2562 .get = snd_hda_spdif_in_status_get,
2563 },
2564 { } /* end */
2565};
2566
2567/**
2568 * snd_hda_create_spdif_in_ctls - create Input SPDIF-related controls
2569 * @codec: the HDA codec
2570 * @nid: audio in widget NID
2571 *
2572 * Creates controls related with the SPDIF input.
2573 * Called from each patch supporting the SPDIF in.
2574 *
2575 * Returns 0 if successful, or a negative error code.
2576 */
Takashi Iwai12f288b2007-08-02 15:51:59 +02002577int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002578{
2579 int err;
Takashi Iwaic8b6bf9b2005-11-17 14:57:47 +01002580 struct snd_kcontrol *kctl;
2581 struct snd_kcontrol_new *dig_mix;
Takashi Iwai09f99702008-02-04 12:31:13 +01002582 int idx;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002583
Takashi Iwai09f99702008-02-04 12:31:13 +01002584 for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
2585 if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch",
2586 idx))
2587 break;
2588 }
2589 if (idx >= SPDIF_MAX_IDX) {
2590 printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
2591 return -EBUSY;
2592 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002593 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
2594 kctl = snd_ctl_new1(dig_mix, codec);
Takashi Iwaic8dcdf82009-02-06 16:21:20 +01002595 if (!kctl)
2596 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002597 kctl->private_value = nid;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01002598 err = snd_hda_ctl_add(codec, nid, kctl);
Takashi Iwai0ba21762007-04-16 11:29:14 +02002599 if (err < 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002600 return err;
2601 }
Takashi Iwai0ba21762007-04-16 11:29:14 +02002602 codec->spdif_in_enable =
Andrew Paprocki3982d172007-12-19 12:13:44 +01002603 snd_hda_codec_read(codec, nid, 0,
2604 AC_VERB_GET_DIGI_CONVERT_1, 0) &
Takashi Iwai0ba21762007-04-16 11:29:14 +02002605 AC_DIG1_ENABLE;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002606 return 0;
2607}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002608EXPORT_SYMBOL_HDA(snd_hda_create_spdif_in_ctls);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002609
Takashi Iwaicb53c622007-08-10 17:21:45 +02002610#ifdef SND_HDA_NEEDS_RESUME
Takashi Iwai82beb8f2007-08-10 17:09:26 +02002611/*
2612 * command cache
2613 */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002614
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002615/* build a 32bit cache key with the widget id and the command parameter */
2616#define build_cmd_cache_key(nid, verb) ((verb << 8) | nid)
2617#define get_cmd_cache_nid(key) ((key) & 0xff)
2618#define get_cmd_cache_cmd(key) (((key) >> 8) & 0xffff)
2619
2620/**
2621 * snd_hda_codec_write_cache - send a single command with caching
2622 * @codec: the HDA codec
2623 * @nid: NID to send the command
2624 * @direct: direct flag
2625 * @verb: the verb to send
2626 * @parm: the parameter for the verb
2627 *
2628 * Send a single command without waiting for response.
2629 *
2630 * Returns 0 if successful, or a negative error code.
2631 */
2632int snd_hda_codec_write_cache(struct hda_codec *codec, hda_nid_t nid,
2633 int direct, unsigned int verb, unsigned int parm)
2634{
Takashi Iwaiaa2936f2009-05-26 16:07:57 +02002635 int err = snd_hda_codec_write(codec, nid, direct, verb, parm);
2636 struct hda_cache_head *c;
2637 u32 key;
Takashi Iwai33fa35e2008-11-06 16:50:40 +01002638
Takashi Iwaiaa2936f2009-05-26 16:07:57 +02002639 if (err < 0)
2640 return err;
2641 /* parm may contain the verb stuff for get/set amp */
2642 verb = verb | (parm >> 8);
2643 parm &= 0xff;
2644 key = build_cmd_cache_key(nid, verb);
2645 mutex_lock(&codec->bus->cmd_mutex);
2646 c = get_alloc_hash(&codec->cmd_cache, key);
2647 if (c)
2648 c->val = parm;
2649 mutex_unlock(&codec->bus->cmd_mutex);
2650 return 0;
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002651}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002652EXPORT_SYMBOL_HDA(snd_hda_codec_write_cache);
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002653
Takashi Iwaid5191e52009-11-16 14:58:17 +01002654/**
2655 * snd_hda_codec_resume_cache - Resume the all commands from the cache
2656 * @codec: HD-audio codec
2657 *
2658 * Execute all verbs recorded in the command caches to resume.
2659 */
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002660void snd_hda_codec_resume_cache(struct hda_codec *codec)
2661{
Takashi Iwai603c4012008-07-30 15:01:44 +02002662 struct hda_cache_head *buffer = codec->cmd_cache.buf.list;
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002663 int i;
2664
Takashi Iwai603c4012008-07-30 15:01:44 +02002665 for (i = 0; i < codec->cmd_cache.buf.used; i++, buffer++) {
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002666 u32 key = buffer->key;
2667 if (!key)
2668 continue;
2669 snd_hda_codec_write(codec, get_cmd_cache_nid(key), 0,
2670 get_cmd_cache_cmd(key), buffer->val);
2671 }
2672}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002673EXPORT_SYMBOL_HDA(snd_hda_codec_resume_cache);
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002674
2675/**
2676 * snd_hda_sequence_write_cache - sequence writes with caching
2677 * @codec: the HDA codec
2678 * @seq: VERB array to send
2679 *
2680 * Send the commands sequentially from the given array.
2681 * Thte commands are recorded on cache for power-save and resume.
2682 * The array must be terminated with NID=0.
2683 */
2684void snd_hda_sequence_write_cache(struct hda_codec *codec,
2685 const struct hda_verb *seq)
2686{
2687 for (; seq->nid; seq++)
2688 snd_hda_codec_write_cache(codec, seq->nid, 0, seq->verb,
2689 seq->param);
2690}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002691EXPORT_SYMBOL_HDA(snd_hda_sequence_write_cache);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002692#endif /* SND_HDA_NEEDS_RESUME */
Takashi Iwaib3ac5632007-08-10 17:03:40 +02002693
Takashi Iwai54d17402005-11-21 16:33:22 +01002694/*
2695 * set power state of the codec
2696 */
2697static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
2698 unsigned int power_state)
2699{
Takashi Iwaicb53c622007-08-10 17:21:45 +02002700 hda_nid_t nid;
2701 int i;
Takashi Iwai54d17402005-11-21 16:33:22 +01002702
Takashi Iwai05ff7e12009-07-22 12:39:24 +02002703 /* this delay seems necessary to avoid click noise at power-down */
2704 if (power_state == AC_PWRST_D3)
2705 msleep(100);
2706 snd_hda_codec_read(codec, fg, 0, AC_VERB_SET_POWER_STATE,
Takashi Iwai54d17402005-11-21 16:33:22 +01002707 power_state);
Takashi Iwai05ff7e12009-07-22 12:39:24 +02002708 /* partial workaround for "azx_get_response timeout" */
2709 if (power_state == AC_PWRST_D0)
2710 msleep(10);
Takashi Iwai54d17402005-11-21 16:33:22 +01002711
Takashi Iwaicb53c622007-08-10 17:21:45 +02002712 nid = codec->start_nid;
2713 for (i = 0; i < codec->num_nodes; i++, nid++) {
Takashi Iwai7eba5c92007-11-14 14:53:42 +01002714 unsigned int wcaps = get_wcaps(codec, nid);
2715 if (wcaps & AC_WCAP_POWER) {
Takashi Iwaia22d5432009-07-27 12:54:26 +02002716 unsigned int wid_type = get_wcaps_type(wcaps);
Takashi Iwaia3b48c82009-04-21 13:37:29 +02002717 if (power_state == AC_PWRST_D3 &&
2718 wid_type == AC_WID_PIN) {
Takashi Iwai7eba5c92007-11-14 14:53:42 +01002719 unsigned int pincap;
2720 /*
2721 * don't power down the widget if it controls
2722 * eapd and EAPD_BTLENABLE is set.
2723 */
Takashi Iwai14bafe32009-03-23 16:35:39 +01002724 pincap = snd_hda_query_pin_caps(codec, nid);
Takashi Iwai7eba5c92007-11-14 14:53:42 +01002725 if (pincap & AC_PINCAP_EAPD) {
2726 int eapd = snd_hda_codec_read(codec,
2727 nid, 0,
2728 AC_VERB_GET_EAPD_BTLENABLE, 0);
2729 eapd &= 0x02;
Takashi Iwaia3b48c82009-04-21 13:37:29 +02002730 if (eapd)
Takashi Iwai7eba5c92007-11-14 14:53:42 +01002731 continue;
2732 }
Takashi Iwai1194b5b2007-10-10 10:04:26 +02002733 }
Takashi Iwai54d17402005-11-21 16:33:22 +01002734 snd_hda_codec_write(codec, nid, 0,
2735 AC_VERB_SET_POWER_STATE,
2736 power_state);
Takashi Iwai1194b5b2007-10-10 10:04:26 +02002737 }
Takashi Iwai54d17402005-11-21 16:33:22 +01002738 }
2739
Takashi Iwaicb53c622007-08-10 17:21:45 +02002740 if (power_state == AC_PWRST_D0) {
2741 unsigned long end_time;
2742 int state;
Takashi Iwai54d17402005-11-21 16:33:22 +01002743 msleep(10);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002744 /* wait until the codec reachs to D0 */
2745 end_time = jiffies + msecs_to_jiffies(500);
2746 do {
2747 state = snd_hda_codec_read(codec, fg, 0,
2748 AC_VERB_GET_POWER_STATE, 0);
2749 if (state == power_state)
2750 break;
2751 msleep(1);
2752 } while (time_after_eq(end_time, jiffies));
2753 }
Takashi Iwai54d17402005-11-21 16:33:22 +01002754}
2755
Takashi Iwai11aeff02008-07-30 15:01:46 +02002756#ifdef CONFIG_SND_HDA_HWDEP
2757/* execute additional init verbs */
2758static void hda_exec_init_verbs(struct hda_codec *codec)
2759{
2760 if (codec->init_verbs.list)
2761 snd_hda_sequence_write(codec, codec->init_verbs.list);
2762}
2763#else
2764static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
2765#endif
2766
Takashi Iwaicb53c622007-08-10 17:21:45 +02002767#ifdef SND_HDA_NEEDS_RESUME
2768/*
2769 * call suspend and power-down; used both from PM and power-save
2770 */
2771static void hda_call_codec_suspend(struct hda_codec *codec)
2772{
2773 if (codec->patch_ops.suspend)
2774 codec->patch_ops.suspend(codec, PMSG_SUSPEND);
2775 hda_set_power_state(codec,
2776 codec->afg ? codec->afg : codec->mfg,
2777 AC_PWRST_D3);
2778#ifdef CONFIG_SND_HDA_POWER_SAVE
Takashi Iwaia2f63092009-11-11 09:34:25 +01002779 snd_hda_update_power_acct(codec);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002780 cancel_delayed_work(&codec->power_work);
Takashi Iwai95e99fd2007-08-13 15:29:04 +02002781 codec->power_on = 0;
Takashi Iwaia221e282007-08-16 16:35:33 +02002782 codec->power_transition = 0;
Takashi Iwaia2f63092009-11-11 09:34:25 +01002783 codec->power_jiffies = jiffies;
Takashi Iwaicb53c622007-08-10 17:21:45 +02002784#endif
2785}
2786
2787/*
2788 * kick up codec; used both from PM and power-save
2789 */
2790static void hda_call_codec_resume(struct hda_codec *codec)
2791{
2792 hda_set_power_state(codec,
2793 codec->afg ? codec->afg : codec->mfg,
2794 AC_PWRST_D0);
Takashi Iwai3be14142009-02-20 14:11:16 +01002795 restore_pincfgs(codec); /* restore all current pin configs */
Takashi Iwai11aeff02008-07-30 15:01:46 +02002796 hda_exec_init_verbs(codec);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002797 if (codec->patch_ops.resume)
2798 codec->patch_ops.resume(codec);
2799 else {
Takashi Iwai9d99f312007-08-14 15:15:52 +02002800 if (codec->patch_ops.init)
2801 codec->patch_ops.init(codec);
Takashi Iwaicb53c622007-08-10 17:21:45 +02002802 snd_hda_codec_resume_amp(codec);
2803 snd_hda_codec_resume_cache(codec);
2804 }
2805}
2806#endif /* SND_HDA_NEEDS_RESUME */
2807
Takashi Iwai54d17402005-11-21 16:33:22 +01002808
Linus Torvalds1da177e2005-04-16 15:20:36 -07002809/**
2810 * snd_hda_build_controls - build mixer controls
2811 * @bus: the BUS
2812 *
2813 * Creates mixer controls for each codec included in the bus.
2814 *
2815 * Returns 0 if successful, otherwise a negative error code.
2816 */
Takashi Iwai1289e9e2008-11-27 15:47:11 +01002817int /*__devinit*/ snd_hda_build_controls(struct hda_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002818{
Takashi Iwai0ba21762007-04-16 11:29:14 +02002819 struct hda_codec *codec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002820
Takashi Iwai0ba21762007-04-16 11:29:14 +02002821 list_for_each_entry(codec, &bus->codec_list, list) {
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02002822 int err = snd_hda_codec_build_controls(codec);
Takashi Iwaif93d4612009-03-02 10:44:15 +01002823 if (err < 0) {
2824 printk(KERN_ERR "hda_codec: cannot build controls"
2825 "for #%d (error %d)\n", codec->addr, err);
2826 err = snd_hda_codec_reset(codec);
2827 if (err < 0) {
2828 printk(KERN_ERR
2829 "hda_codec: cannot revert codec\n");
2830 return err;
2831 }
2832 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002833 }
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02002834 return 0;
2835}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002836EXPORT_SYMBOL_HDA(snd_hda_build_controls);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002837
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02002838int snd_hda_codec_build_controls(struct hda_codec *codec)
2839{
2840 int err = 0;
Takashi Iwai11aeff02008-07-30 15:01:46 +02002841 hda_exec_init_verbs(codec);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02002842 /* continue to initialize... */
2843 if (codec->patch_ops.init)
2844 err = codec->patch_ops.init(codec);
2845 if (!err && codec->patch_ops.build_controls)
2846 err = codec->patch_ops.build_controls(codec);
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02002847 if (err < 0)
2848 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002849 return 0;
2850}
2851
Linus Torvalds1da177e2005-04-16 15:20:36 -07002852/*
2853 * stream formats
2854 */
Takashi Iwaibefdf312005-08-22 13:57:55 +02002855struct hda_rate_tbl {
2856 unsigned int hz;
2857 unsigned int alsa_bits;
2858 unsigned int hda_fmt;
2859};
2860
2861static struct hda_rate_tbl rate_bits[] = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002862 /* rate in Hz, ALSA rate bitmask, HDA format value */
Nicolas Graziano9d8f53f2005-08-22 13:47:16 +02002863
2864 /* autodetected value used in snd_hda_query_supported_pcm */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002865 { 8000, SNDRV_PCM_RATE_8000, 0x0500 }, /* 1/6 x 48 */
2866 { 11025, SNDRV_PCM_RATE_11025, 0x4300 }, /* 1/4 x 44 */
2867 { 16000, SNDRV_PCM_RATE_16000, 0x0200 }, /* 1/3 x 48 */
2868 { 22050, SNDRV_PCM_RATE_22050, 0x4100 }, /* 1/2 x 44 */
2869 { 32000, SNDRV_PCM_RATE_32000, 0x0a00 }, /* 2/3 x 48 */
2870 { 44100, SNDRV_PCM_RATE_44100, 0x4000 }, /* 44 */
2871 { 48000, SNDRV_PCM_RATE_48000, 0x0000 }, /* 48 */
2872 { 88200, SNDRV_PCM_RATE_88200, 0x4800 }, /* 2 x 44 */
2873 { 96000, SNDRV_PCM_RATE_96000, 0x0800 }, /* 2 x 48 */
2874 { 176400, SNDRV_PCM_RATE_176400, 0x5800 },/* 4 x 44 */
2875 { 192000, SNDRV_PCM_RATE_192000, 0x1800 }, /* 4 x 48 */
Takashi Iwaia961f9f2007-04-12 13:08:09 +02002876#define AC_PAR_PCM_RATE_BITS 11
2877 /* up to bits 10, 384kHZ isn't supported properly */
2878
2879 /* not autodetected value */
2880 { 9600, SNDRV_PCM_RATE_KNOT, 0x0400 }, /* 1/5 x 48 */
Nicolas Graziano9d8f53f2005-08-22 13:47:16 +02002881
Takashi Iwaibefdf312005-08-22 13:57:55 +02002882 { 0 } /* terminator */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002883};
2884
2885/**
2886 * snd_hda_calc_stream_format - calculate format bitset
2887 * @rate: the sample rate
2888 * @channels: the number of channels
2889 * @format: the PCM format (SNDRV_PCM_FORMAT_XXX)
2890 * @maxbps: the max. bps
2891 *
2892 * Calculate the format bitset from the given rate, channels and th PCM format.
2893 *
2894 * Return zero if invalid.
2895 */
2896unsigned int snd_hda_calc_stream_format(unsigned int rate,
2897 unsigned int channels,
2898 unsigned int format,
2899 unsigned int maxbps)
2900{
2901 int i;
2902 unsigned int val = 0;
2903
Takashi Iwaibefdf312005-08-22 13:57:55 +02002904 for (i = 0; rate_bits[i].hz; i++)
2905 if (rate_bits[i].hz == rate) {
2906 val = rate_bits[i].hda_fmt;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002907 break;
2908 }
Takashi Iwai0ba21762007-04-16 11:29:14 +02002909 if (!rate_bits[i].hz) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002910 snd_printdd("invalid rate %d\n", rate);
2911 return 0;
2912 }
2913
2914 if (channels == 0 || channels > 8) {
2915 snd_printdd("invalid channels %d\n", channels);
2916 return 0;
2917 }
2918 val |= channels - 1;
2919
2920 switch (snd_pcm_format_width(format)) {
2921 case 8: val |= 0x00; break;
2922 case 16: val |= 0x10; break;
2923 case 20:
2924 case 24:
2925 case 32:
Takashi Iwaib0bb3aa2009-07-03 23:25:37 +02002926 if (maxbps >= 32 || format == SNDRV_PCM_FORMAT_FLOAT_LE)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002927 val |= 0x40;
2928 else if (maxbps >= 24)
2929 val |= 0x30;
2930 else
2931 val |= 0x20;
2932 break;
2933 default:
Takashi Iwai0ba21762007-04-16 11:29:14 +02002934 snd_printdd("invalid format width %d\n",
2935 snd_pcm_format_width(format));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002936 return 0;
2937 }
2938
2939 return val;
2940}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01002941EXPORT_SYMBOL_HDA(snd_hda_calc_stream_format);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002942
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01002943static unsigned int get_pcm_param(struct hda_codec *codec, hda_nid_t nid)
2944{
2945 unsigned int val = 0;
2946 if (nid != codec->afg &&
2947 (get_wcaps(codec, nid) & AC_WCAP_FORMAT_OVRD))
2948 val = snd_hda_param_read(codec, nid, AC_PAR_PCM);
2949 if (!val || val == -1)
2950 val = snd_hda_param_read(codec, codec->afg, AC_PAR_PCM);
2951 if (!val || val == -1)
2952 return 0;
2953 return val;
2954}
2955
2956static unsigned int query_pcm_param(struct hda_codec *codec, hda_nid_t nid)
2957{
2958 return query_caps_hash(codec, nid, HDA_HASH_PARPCM_KEY(nid),
2959 get_pcm_param);
2960}
2961
2962static unsigned int get_stream_param(struct hda_codec *codec, hda_nid_t nid)
2963{
2964 unsigned int streams = snd_hda_param_read(codec, nid, AC_PAR_STREAM);
2965 if (!streams || streams == -1)
2966 streams = snd_hda_param_read(codec, codec->afg, AC_PAR_STREAM);
2967 if (!streams || streams == -1)
2968 return 0;
2969 return streams;
2970}
2971
2972static unsigned int query_stream_param(struct hda_codec *codec, hda_nid_t nid)
2973{
2974 return query_caps_hash(codec, nid, HDA_HASH_PARSTR_KEY(nid),
2975 get_stream_param);
2976}
2977
Linus Torvalds1da177e2005-04-16 15:20:36 -07002978/**
2979 * snd_hda_query_supported_pcm - query the supported PCM rates and formats
2980 * @codec: the HDA codec
2981 * @nid: NID to query
2982 * @ratesp: the pointer to store the detected rate bitflags
2983 * @formatsp: the pointer to store the detected formats
2984 * @bpsp: the pointer to store the detected format widths
2985 *
2986 * Queries the supported PCM rates and formats. The NULL @ratesp, @formatsp
2987 * or @bsps argument is ignored.
2988 *
2989 * Returns 0 if successful, otherwise a negative error code.
2990 */
Takashi Iwai986862b2008-11-27 12:40:13 +01002991static int snd_hda_query_supported_pcm(struct hda_codec *codec, hda_nid_t nid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07002992 u32 *ratesp, u64 *formatsp, unsigned int *bpsp)
2993{
Jaroslav Kyselaee504712009-03-17 14:30:31 +01002994 unsigned int i, val, wcaps;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002995
Jaroslav Kyselaee504712009-03-17 14:30:31 +01002996 wcaps = get_wcaps(codec, nid);
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01002997 val = query_pcm_param(codec, nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002998
2999 if (ratesp) {
3000 u32 rates = 0;
Takashi Iwaia961f9f2007-04-12 13:08:09 +02003001 for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003002 if (val & (1 << i))
Takashi Iwaibefdf312005-08-22 13:57:55 +02003003 rates |= rate_bits[i].alsa_bits;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003004 }
Jaroslav Kyselaee504712009-03-17 14:30:31 +01003005 if (rates == 0) {
3006 snd_printk(KERN_ERR "hda_codec: rates == 0 "
3007 "(nid=0x%x, val=0x%x, ovrd=%i)\n",
3008 nid, val,
3009 (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0);
3010 return -EIO;
3011 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003012 *ratesp = rates;
3013 }
3014
3015 if (formatsp || bpsp) {
3016 u64 formats = 0;
Jaroslav Kyselaee504712009-03-17 14:30:31 +01003017 unsigned int streams, bps;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003018
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01003019 streams = query_stream_param(codec, nid);
3020 if (!streams)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003021 return -EIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003022
3023 bps = 0;
3024 if (streams & AC_SUPFMT_PCM) {
3025 if (val & AC_SUPPCM_BITS_8) {
3026 formats |= SNDRV_PCM_FMTBIT_U8;
3027 bps = 8;
3028 }
3029 if (val & AC_SUPPCM_BITS_16) {
3030 formats |= SNDRV_PCM_FMTBIT_S16_LE;
3031 bps = 16;
3032 }
3033 if (wcaps & AC_WCAP_DIGITAL) {
3034 if (val & AC_SUPPCM_BITS_32)
3035 formats |= SNDRV_PCM_FMTBIT_IEC958_SUBFRAME_LE;
3036 if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24))
3037 formats |= SNDRV_PCM_FMTBIT_S32_LE;
3038 if (val & AC_SUPPCM_BITS_24)
3039 bps = 24;
3040 else if (val & AC_SUPPCM_BITS_20)
3041 bps = 20;
Takashi Iwai0ba21762007-04-16 11:29:14 +02003042 } else if (val & (AC_SUPPCM_BITS_20|AC_SUPPCM_BITS_24|
3043 AC_SUPPCM_BITS_32)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003044 formats |= SNDRV_PCM_FMTBIT_S32_LE;
3045 if (val & AC_SUPPCM_BITS_32)
3046 bps = 32;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003047 else if (val & AC_SUPPCM_BITS_24)
3048 bps = 24;
Nicolas Graziano33ef7652006-09-19 14:23:14 +02003049 else if (val & AC_SUPPCM_BITS_20)
3050 bps = 20;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003051 }
3052 }
Takashi Iwaib5025c52009-07-01 18:05:27 +02003053 if (streams & AC_SUPFMT_FLOAT32) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003054 formats |= SNDRV_PCM_FMTBIT_FLOAT_LE;
Takashi Iwaib0bb3aa2009-07-03 23:25:37 +02003055 if (!bps)
3056 bps = 32;
Takashi Iwaib5025c52009-07-01 18:05:27 +02003057 }
3058 if (streams == AC_SUPFMT_AC3) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02003059 /* should be exclusive */
Linus Torvalds1da177e2005-04-16 15:20:36 -07003060 /* temporary hack: we have still no proper support
3061 * for the direct AC3 stream...
3062 */
3063 formats |= SNDRV_PCM_FMTBIT_U8;
3064 bps = 8;
3065 }
Jaroslav Kyselaee504712009-03-17 14:30:31 +01003066 if (formats == 0) {
3067 snd_printk(KERN_ERR "hda_codec: formats == 0 "
3068 "(nid=0x%x, val=0x%x, ovrd=%i, "
3069 "streams=0x%x)\n",
3070 nid, val,
3071 (wcaps & AC_WCAP_FORMAT_OVRD) ? 1 : 0,
3072 streams);
3073 return -EIO;
3074 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003075 if (formatsp)
3076 *formatsp = formats;
3077 if (bpsp)
3078 *bpsp = bps;
3079 }
3080
3081 return 0;
3082}
3083
3084/**
Takashi Iwaid5191e52009-11-16 14:58:17 +01003085 * snd_hda_is_supported_format - Check the validity of the format
3086 * @codec: HD-audio codec
3087 * @nid: NID to check
3088 * @format: the HD-audio format value to check
3089 *
3090 * Check whether the given node supports the format value.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003091 *
3092 * Returns 1 if supported, 0 if not.
3093 */
3094int snd_hda_is_supported_format(struct hda_codec *codec, hda_nid_t nid,
3095 unsigned int format)
3096{
3097 int i;
3098 unsigned int val = 0, rate, stream;
3099
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01003100 val = query_pcm_param(codec, nid);
3101 if (!val)
3102 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003103
3104 rate = format & 0xff00;
Takashi Iwaia961f9f2007-04-12 13:08:09 +02003105 for (i = 0; i < AC_PAR_PCM_RATE_BITS; i++)
Takashi Iwaibefdf312005-08-22 13:57:55 +02003106 if (rate_bits[i].hda_fmt == rate) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003107 if (val & (1 << i))
3108 break;
3109 return 0;
3110 }
Takashi Iwaia961f9f2007-04-12 13:08:09 +02003111 if (i >= AC_PAR_PCM_RATE_BITS)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003112 return 0;
3113
Takashi Iwai92c7c8a2009-03-24 07:32:14 +01003114 stream = query_stream_param(codec, nid);
3115 if (!stream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003116 return 0;
3117
3118 if (stream & AC_SUPFMT_PCM) {
3119 switch (format & 0xf0) {
3120 case 0x00:
Takashi Iwai0ba21762007-04-16 11:29:14 +02003121 if (!(val & AC_SUPPCM_BITS_8))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003122 return 0;
3123 break;
3124 case 0x10:
Takashi Iwai0ba21762007-04-16 11:29:14 +02003125 if (!(val & AC_SUPPCM_BITS_16))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003126 return 0;
3127 break;
3128 case 0x20:
Takashi Iwai0ba21762007-04-16 11:29:14 +02003129 if (!(val & AC_SUPPCM_BITS_20))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003130 return 0;
3131 break;
3132 case 0x30:
Takashi Iwai0ba21762007-04-16 11:29:14 +02003133 if (!(val & AC_SUPPCM_BITS_24))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003134 return 0;
3135 break;
3136 case 0x40:
Takashi Iwai0ba21762007-04-16 11:29:14 +02003137 if (!(val & AC_SUPPCM_BITS_32))
Linus Torvalds1da177e2005-04-16 15:20:36 -07003138 return 0;
3139 break;
3140 default:
3141 return 0;
3142 }
3143 } else {
3144 /* FIXME: check for float32 and AC3? */
3145 }
3146
3147 return 1;
3148}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003149EXPORT_SYMBOL_HDA(snd_hda_is_supported_format);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003150
3151/*
3152 * PCM stuff
3153 */
3154static int hda_pcm_default_open_close(struct hda_pcm_stream *hinfo,
3155 struct hda_codec *codec,
Takashi Iwaic8b6bf9b2005-11-17 14:57:47 +01003156 struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003157{
3158 return 0;
3159}
3160
3161static int hda_pcm_default_prepare(struct hda_pcm_stream *hinfo,
3162 struct hda_codec *codec,
3163 unsigned int stream_tag,
3164 unsigned int format,
Takashi Iwaic8b6bf9b2005-11-17 14:57:47 +01003165 struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003166{
3167 snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
3168 return 0;
3169}
3170
3171static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
3172 struct hda_codec *codec,
Takashi Iwaic8b6bf9b2005-11-17 14:57:47 +01003173 struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003174{
Takashi Iwai888afa12008-03-18 09:57:50 +01003175 snd_hda_codec_cleanup_stream(codec, hinfo->nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003176 return 0;
3177}
3178
Takashi Iwai6c1f45e2008-07-30 15:01:45 +02003179static int set_pcm_default_values(struct hda_codec *codec,
3180 struct hda_pcm_stream *info)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003181{
Jaroslav Kyselaee504712009-03-17 14:30:31 +01003182 int err;
3183
Takashi Iwai0ba21762007-04-16 11:29:14 +02003184 /* query support PCM information from the given NID */
3185 if (info->nid && (!info->rates || !info->formats)) {
Jaroslav Kyselaee504712009-03-17 14:30:31 +01003186 err = snd_hda_query_supported_pcm(codec, info->nid,
Takashi Iwai0ba21762007-04-16 11:29:14 +02003187 info->rates ? NULL : &info->rates,
3188 info->formats ? NULL : &info->formats,
3189 info->maxbps ? NULL : &info->maxbps);
Jaroslav Kyselaee504712009-03-17 14:30:31 +01003190 if (err < 0)
3191 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003192 }
3193 if (info->ops.open == NULL)
3194 info->ops.open = hda_pcm_default_open_close;
3195 if (info->ops.close == NULL)
3196 info->ops.close = hda_pcm_default_open_close;
3197 if (info->ops.prepare == NULL) {
Takashi Iwaida3cec32008-08-08 17:12:14 +02003198 if (snd_BUG_ON(!info->nid))
3199 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003200 info->ops.prepare = hda_pcm_default_prepare;
3201 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003202 if (info->ops.cleanup == NULL) {
Takashi Iwaida3cec32008-08-08 17:12:14 +02003203 if (snd_BUG_ON(!info->nid))
3204 return -EINVAL;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003205 info->ops.cleanup = hda_pcm_default_cleanup;
3206 }
3207 return 0;
3208}
3209
Takashi Iwaid5191e52009-11-16 14:58:17 +01003210/* global */
Jaroslav Kyselae3303232009-11-10 14:53:02 +01003211const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
3212 "Audio", "SPDIF", "HDMI", "Modem"
3213};
3214
Takashi Iwai176d5332008-07-30 15:01:44 +02003215/*
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003216 * get the empty PCM device number to assign
3217 */
3218static int get_empty_pcm_device(struct hda_bus *bus, int type)
3219{
Wu Fengguangf5d6def2009-10-30 11:38:26 +01003220 /* audio device indices; not linear to keep compatibility */
3221 static int audio_idx[HDA_PCM_NTYPES][5] = {
3222 [HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 },
3223 [HDA_PCM_TYPE_SPDIF] = { 1, -1 },
Wu Fengguang92608ba2009-10-30 11:40:03 +01003224 [HDA_PCM_TYPE_HDMI] = { 3, 7, 8, 9, -1 },
Wu Fengguangf5d6def2009-10-30 11:38:26 +01003225 [HDA_PCM_TYPE_MODEM] = { 6, -1 },
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003226 };
Wu Fengguangf5d6def2009-10-30 11:38:26 +01003227 int i;
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003228
Wu Fengguangf5d6def2009-10-30 11:38:26 +01003229 if (type >= HDA_PCM_NTYPES) {
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003230 snd_printk(KERN_WARNING "Invalid PCM type %d\n", type);
3231 return -EINVAL;
3232 }
Wu Fengguangf5d6def2009-10-30 11:38:26 +01003233
3234 for (i = 0; audio_idx[type][i] >= 0 ; i++)
3235 if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
3236 return audio_idx[type][i];
3237
Jaroslav Kyselae3303232009-11-10 14:53:02 +01003238 snd_printk(KERN_WARNING "Too many %s devices\n", snd_hda_pcm_type_name[type]);
Wu Fengguangf5d6def2009-10-30 11:38:26 +01003239 return -EAGAIN;
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003240}
3241
3242/*
Takashi Iwai176d5332008-07-30 15:01:44 +02003243 * attach a new PCM stream
3244 */
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003245static int snd_hda_attach_pcm(struct hda_codec *codec, struct hda_pcm *pcm)
Takashi Iwai176d5332008-07-30 15:01:44 +02003246{
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003247 struct hda_bus *bus = codec->bus;
Takashi Iwai176d5332008-07-30 15:01:44 +02003248 struct hda_pcm_stream *info;
3249 int stream, err;
3250
Takashi Iwaib91f0802008-11-04 08:43:08 +01003251 if (snd_BUG_ON(!pcm->name))
Takashi Iwai176d5332008-07-30 15:01:44 +02003252 return -EINVAL;
3253 for (stream = 0; stream < 2; stream++) {
3254 info = &pcm->stream[stream];
3255 if (info->substreams) {
3256 err = set_pcm_default_values(codec, info);
3257 if (err < 0)
3258 return err;
3259 }
3260 }
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003261 return bus->ops.attach_pcm(bus, codec, pcm);
Takashi Iwai176d5332008-07-30 15:01:44 +02003262}
3263
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003264/* assign all PCMs of the given codec */
3265int snd_hda_codec_build_pcms(struct hda_codec *codec)
3266{
3267 unsigned int pcm;
3268 int err;
3269
3270 if (!codec->num_pcms) {
3271 if (!codec->patch_ops.build_pcms)
3272 return 0;
3273 err = codec->patch_ops.build_pcms(codec);
Takashi Iwai6e655bf2009-03-02 10:46:03 +01003274 if (err < 0) {
3275 printk(KERN_ERR "hda_codec: cannot build PCMs"
3276 "for #%d (error %d)\n", codec->addr, err);
3277 err = snd_hda_codec_reset(codec);
3278 if (err < 0) {
3279 printk(KERN_ERR
3280 "hda_codec: cannot revert codec\n");
3281 return err;
3282 }
3283 }
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003284 }
3285 for (pcm = 0; pcm < codec->num_pcms; pcm++) {
3286 struct hda_pcm *cpcm = &codec->pcm_info[pcm];
3287 int dev;
3288
3289 if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
Takashi Iwai41b5b012009-01-20 18:21:23 +01003290 continue; /* no substreams assigned */
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003291
3292 if (!cpcm->pcm) {
3293 dev = get_empty_pcm_device(codec->bus, cpcm->pcm_type);
3294 if (dev < 0)
Takashi Iwai6e655bf2009-03-02 10:46:03 +01003295 continue; /* no fatal error */
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003296 cpcm->device = dev;
3297 err = snd_hda_attach_pcm(codec, cpcm);
Takashi Iwai6e655bf2009-03-02 10:46:03 +01003298 if (err < 0) {
3299 printk(KERN_ERR "hda_codec: cannot attach "
3300 "PCM stream %d for codec #%d\n",
3301 dev, codec->addr);
3302 continue; /* no fatal error */
3303 }
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003304 }
3305 }
3306 return 0;
3307}
3308
Linus Torvalds1da177e2005-04-16 15:20:36 -07003309/**
3310 * snd_hda_build_pcms - build PCM information
3311 * @bus: the BUS
3312 *
3313 * Create PCM information for each codec included in the bus.
3314 *
3315 * The build_pcms codec patch is requested to set up codec->num_pcms and
3316 * codec->pcm_info properly. The array is referred by the top-level driver
3317 * to create its PCM instances.
3318 * The allocated codec->pcm_info should be released in codec->patch_ops.free
3319 * callback.
3320 *
3321 * At least, substreams, channels_min and channels_max must be filled for
3322 * each stream. substreams = 0 indicates that the stream doesn't exist.
3323 * When rates and/or formats are zero, the supported values are queried
3324 * from the given nid. The nid is used also by the default ops.prepare
3325 * and ops.cleanup callbacks.
3326 *
3327 * The driver needs to call ops.open in its open callback. Similarly,
3328 * ops.close is supposed to be called in the close callback.
3329 * ops.prepare should be called in the prepare or hw_params callback
3330 * with the proper parameters for set up.
3331 * ops.cleanup should be called in hw_free for clean up of streams.
3332 *
3333 * This function returns 0 if successfull, or a negative error code.
3334 */
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003335int __devinit snd_hda_build_pcms(struct hda_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003336{
Takashi Iwai0ba21762007-04-16 11:29:14 +02003337 struct hda_codec *codec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003338
Takashi Iwai0ba21762007-04-16 11:29:14 +02003339 list_for_each_entry(codec, &bus->codec_list, list) {
Takashi Iwai529bd6c2008-11-27 14:17:01 +01003340 int err = snd_hda_codec_build_pcms(codec);
3341 if (err < 0)
3342 return err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003343 }
3344 return 0;
3345}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003346EXPORT_SYMBOL_HDA(snd_hda_build_pcms);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003347
Linus Torvalds1da177e2005-04-16 15:20:36 -07003348/**
3349 * snd_hda_check_board_config - compare the current codec with the config table
3350 * @codec: the HDA codec
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003351 * @num_configs: number of config enums
3352 * @models: array of model name strings
Linus Torvalds1da177e2005-04-16 15:20:36 -07003353 * @tbl: configuration table, terminated by null entries
3354 *
3355 * Compares the modelname or PCI subsystem id of the current codec with the
3356 * given configuration table. If a matching entry is found, returns its
3357 * config value (supposed to be 0 or positive).
3358 *
3359 * If no entries are matching, the function returns a negative value.
3360 */
Takashi Iwai12f288b2007-08-02 15:51:59 +02003361int snd_hda_check_board_config(struct hda_codec *codec,
3362 int num_configs, const char **models,
3363 const struct snd_pci_quirk *tbl)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003364{
Takashi Iwaif44ac832008-07-30 15:01:45 +02003365 if (codec->modelname && models) {
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003366 int i;
3367 for (i = 0; i < num_configs; i++) {
3368 if (models[i] &&
Takashi Iwaif44ac832008-07-30 15:01:45 +02003369 !strcmp(codec->modelname, models[i])) {
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003370 snd_printd(KERN_INFO "hda_codec: model '%s' is "
3371 "selected\n", models[i]);
3372 return i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003373 }
3374 }
3375 }
3376
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003377 if (!codec->bus->pci || !tbl)
3378 return -1;
3379
3380 tbl = snd_pci_quirk_lookup(codec->bus->pci, tbl);
3381 if (!tbl)
3382 return -1;
3383 if (tbl->value >= 0 && tbl->value < num_configs) {
Takashi Iwai62cf8722008-05-20 12:15:15 +02003384#ifdef CONFIG_SND_DEBUG_VERBOSE
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003385 char tmp[10];
3386 const char *model = NULL;
3387 if (models)
3388 model = models[tbl->value];
3389 if (!model) {
3390 sprintf(tmp, "#%d", tbl->value);
3391 model = tmp;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003392 }
Takashi Iwaif5fcc132006-11-24 17:07:44 +01003393 snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
3394 "for config %x:%x (%s)\n",
3395 model, tbl->subvendor, tbl->subdevice,
3396 (tbl->name ? tbl->name : "Unknown device"));
3397#endif
3398 return tbl->value;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003399 }
3400 return -1;
3401}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003402EXPORT_SYMBOL_HDA(snd_hda_check_board_config);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003403
3404/**
Mauro Carvalho Chehab2eda3442008-08-11 10:18:39 +02003405 * snd_hda_check_board_codec_sid_config - compare the current codec
3406 subsystem ID with the
3407 config table
3408
3409 This is important for Gateway notebooks with SB450 HDA Audio
3410 where the vendor ID of the PCI device is:
3411 ATI Technologies Inc SB450 HDA Audio [1002:437b]
3412 and the vendor/subvendor are found only at the codec.
3413
3414 * @codec: the HDA codec
3415 * @num_configs: number of config enums
3416 * @models: array of model name strings
3417 * @tbl: configuration table, terminated by null entries
3418 *
3419 * Compares the modelname or PCI subsystem id of the current codec with the
3420 * given configuration table. If a matching entry is found, returns its
3421 * config value (supposed to be 0 or positive).
3422 *
3423 * If no entries are matching, the function returns a negative value.
3424 */
3425int snd_hda_check_board_codec_sid_config(struct hda_codec *codec,
3426 int num_configs, const char **models,
3427 const struct snd_pci_quirk *tbl)
3428{
3429 const struct snd_pci_quirk *q;
3430
3431 /* Search for codec ID */
3432 for (q = tbl; q->subvendor; q++) {
3433 unsigned long vendorid = (q->subdevice) | (q->subvendor << 16);
3434
3435 if (vendorid == codec->subsystem_id)
3436 break;
3437 }
3438
3439 if (!q->subvendor)
3440 return -1;
3441
3442 tbl = q;
3443
3444 if (tbl->value >= 0 && tbl->value < num_configs) {
Takashi Iwaid94ff6b2009-09-02 00:20:21 +02003445#ifdef CONFIG_SND_DEBUG_VERBOSE
Mauro Carvalho Chehab2eda3442008-08-11 10:18:39 +02003446 char tmp[10];
3447 const char *model = NULL;
3448 if (models)
3449 model = models[tbl->value];
3450 if (!model) {
3451 sprintf(tmp, "#%d", tbl->value);
3452 model = tmp;
3453 }
3454 snd_printdd(KERN_INFO "hda_codec: model '%s' is selected "
3455 "for config %x:%x (%s)\n",
3456 model, tbl->subvendor, tbl->subdevice,
3457 (tbl->name ? tbl->name : "Unknown device"));
3458#endif
3459 return tbl->value;
3460 }
3461 return -1;
3462}
3463EXPORT_SYMBOL_HDA(snd_hda_check_board_codec_sid_config);
3464
3465/**
Linus Torvalds1da177e2005-04-16 15:20:36 -07003466 * snd_hda_add_new_ctls - create controls from the array
3467 * @codec: the HDA codec
Takashi Iwaic8b6bf9b2005-11-17 14:57:47 +01003468 * @knew: the array of struct snd_kcontrol_new
Linus Torvalds1da177e2005-04-16 15:20:36 -07003469 *
3470 * This helper function creates and add new controls in the given array.
3471 * The array must be terminated with an empty entry as terminator.
3472 *
3473 * Returns 0 if successful, or a negative error code.
3474 */
Takashi Iwai12f288b2007-08-02 15:51:59 +02003475int snd_hda_add_new_ctls(struct hda_codec *codec, struct snd_kcontrol_new *knew)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003476{
Jaroslav Kysela4d02d1b2009-11-12 10:15:48 +01003477 int err;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003478
3479 for (; knew->name; knew++) {
Takashi Iwai54d17402005-11-21 16:33:22 +01003480 struct snd_kcontrol *kctl;
3481 kctl = snd_ctl_new1(knew, codec);
Takashi Iwai0ba21762007-04-16 11:29:14 +02003482 if (!kctl)
Takashi Iwai54d17402005-11-21 16:33:22 +01003483 return -ENOMEM;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01003484 err = snd_hda_ctl_add(codec, 0, kctl);
Takashi Iwai54d17402005-11-21 16:33:22 +01003485 if (err < 0) {
Takashi Iwai0ba21762007-04-16 11:29:14 +02003486 if (!codec->addr)
Takashi Iwai54d17402005-11-21 16:33:22 +01003487 return err;
3488 kctl = snd_ctl_new1(knew, codec);
Takashi Iwai0ba21762007-04-16 11:29:14 +02003489 if (!kctl)
Takashi Iwai54d17402005-11-21 16:33:22 +01003490 return -ENOMEM;
3491 kctl->id.device = codec->addr;
Jaroslav Kysela3911a4c2009-11-11 13:43:01 +01003492 err = snd_hda_ctl_add(codec, 0, kctl);
Takashi Iwai0ba21762007-04-16 11:29:14 +02003493 if (err < 0)
Takashi Iwai54d17402005-11-21 16:33:22 +01003494 return err;
3495 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003496 }
3497 return 0;
3498}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003499EXPORT_SYMBOL_HDA(snd_hda_add_new_ctls);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003500
Takashi Iwaicb53c622007-08-10 17:21:45 +02003501#ifdef CONFIG_SND_HDA_POWER_SAVE
3502static void hda_set_power_state(struct hda_codec *codec, hda_nid_t fg,
3503 unsigned int power_state);
3504
3505static void hda_power_work(struct work_struct *work)
3506{
3507 struct hda_codec *codec =
3508 container_of(work, struct hda_codec, power_work.work);
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003509 struct hda_bus *bus = codec->bus;
Takashi Iwaicb53c622007-08-10 17:21:45 +02003510
Maxim Levitsky2e492462007-09-03 15:26:57 +02003511 if (!codec->power_on || codec->power_count) {
3512 codec->power_transition = 0;
Takashi Iwaicb53c622007-08-10 17:21:45 +02003513 return;
Maxim Levitsky2e492462007-09-03 15:26:57 +02003514 }
Takashi Iwaicb53c622007-08-10 17:21:45 +02003515
3516 hda_call_codec_suspend(codec);
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003517 if (bus->ops.pm_notify)
3518 bus->ops.pm_notify(bus);
Takashi Iwaicb53c622007-08-10 17:21:45 +02003519}
3520
3521static void hda_keep_power_on(struct hda_codec *codec)
3522{
3523 codec->power_count++;
3524 codec->power_on = 1;
Takashi Iwaia2f63092009-11-11 09:34:25 +01003525 codec->power_jiffies = jiffies;
3526}
3527
Takashi Iwaid5191e52009-11-16 14:58:17 +01003528/* update the power on/off account with the current jiffies */
Takashi Iwaia2f63092009-11-11 09:34:25 +01003529void snd_hda_update_power_acct(struct hda_codec *codec)
3530{
3531 unsigned long delta = jiffies - codec->power_jiffies;
3532 if (codec->power_on)
3533 codec->power_on_acct += delta;
3534 else
3535 codec->power_off_acct += delta;
3536 codec->power_jiffies += delta;
Takashi Iwaicb53c622007-08-10 17:21:45 +02003537}
3538
Takashi Iwaid5191e52009-11-16 14:58:17 +01003539/**
3540 * snd_hda_power_up - Power-up the codec
3541 * @codec: HD-audio codec
3542 *
3543 * Increment the power-up counter and power up the hardware really when
3544 * not turned on yet.
3545 */
Takashi Iwaicb53c622007-08-10 17:21:45 +02003546void snd_hda_power_up(struct hda_codec *codec)
3547{
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003548 struct hda_bus *bus = codec->bus;
3549
Takashi Iwaicb53c622007-08-10 17:21:45 +02003550 codec->power_count++;
Takashi Iwaia221e282007-08-16 16:35:33 +02003551 if (codec->power_on || codec->power_transition)
Takashi Iwaicb53c622007-08-10 17:21:45 +02003552 return;
3553
Takashi Iwaia2f63092009-11-11 09:34:25 +01003554 snd_hda_update_power_acct(codec);
Takashi Iwaicb53c622007-08-10 17:21:45 +02003555 codec->power_on = 1;
Takashi Iwaia2f63092009-11-11 09:34:25 +01003556 codec->power_jiffies = jiffies;
Takashi Iwai33fa35e2008-11-06 16:50:40 +01003557 if (bus->ops.pm_notify)
3558 bus->ops.pm_notify(bus);
Takashi Iwaicb53c622007-08-10 17:21:45 +02003559 hda_call_codec_resume(codec);
3560 cancel_delayed_work(&codec->power_work);
Takashi Iwaia221e282007-08-16 16:35:33 +02003561 codec->power_transition = 0;
Takashi Iwaicb53c622007-08-10 17:21:45 +02003562}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003563EXPORT_SYMBOL_HDA(snd_hda_power_up);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01003564
3565#define power_save(codec) \
3566 ((codec)->bus->power_save ? *(codec)->bus->power_save : 0)
Takashi Iwaicb53c622007-08-10 17:21:45 +02003567
Takashi Iwaid5191e52009-11-16 14:58:17 +01003568/**
3569 * snd_hda_power_down - Power-down the codec
3570 * @codec: HD-audio codec
3571 *
3572 * Decrement the power-up counter and schedules the power-off work if
3573 * the counter rearches to zero.
3574 */
Takashi Iwaicb53c622007-08-10 17:21:45 +02003575void snd_hda_power_down(struct hda_codec *codec)
3576{
3577 --codec->power_count;
Takashi Iwaia221e282007-08-16 16:35:33 +02003578 if (!codec->power_on || codec->power_count || codec->power_transition)
Takashi Iwaicb53c622007-08-10 17:21:45 +02003579 return;
Takashi Iwaifee2fba2008-11-27 12:43:28 +01003580 if (power_save(codec)) {
Takashi Iwaia221e282007-08-16 16:35:33 +02003581 codec->power_transition = 1; /* avoid reentrance */
Takashi Iwaic107b412009-01-13 17:46:37 +01003582 queue_delayed_work(codec->bus->workq, &codec->power_work,
Takashi Iwaifee2fba2008-11-27 12:43:28 +01003583 msecs_to_jiffies(power_save(codec) * 1000));
Takashi Iwaia221e282007-08-16 16:35:33 +02003584 }
Takashi Iwaicb53c622007-08-10 17:21:45 +02003585}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003586EXPORT_SYMBOL_HDA(snd_hda_power_down);
Takashi Iwaicb53c622007-08-10 17:21:45 +02003587
Takashi Iwaid5191e52009-11-16 14:58:17 +01003588/**
3589 * snd_hda_check_amp_list_power - Check the amp list and update the power
3590 * @codec: HD-audio codec
3591 * @check: the object containing an AMP list and the status
3592 * @nid: NID to check / update
3593 *
3594 * Check whether the given NID is in the amp list. If it's in the list,
3595 * check the current AMP status, and update the the power-status according
3596 * to the mute status.
3597 *
3598 * This function is supposed to be set or called from the check_power_status
3599 * patch ops.
3600 */
Takashi Iwaicb53c622007-08-10 17:21:45 +02003601int snd_hda_check_amp_list_power(struct hda_codec *codec,
3602 struct hda_loopback_check *check,
3603 hda_nid_t nid)
3604{
3605 struct hda_amp_list *p;
3606 int ch, v;
3607
3608 if (!check->amplist)
3609 return 0;
3610 for (p = check->amplist; p->nid; p++) {
3611 if (p->nid == nid)
3612 break;
3613 }
3614 if (!p->nid)
3615 return 0; /* nothing changed */
3616
3617 for (p = check->amplist; p->nid; p++) {
3618 for (ch = 0; ch < 2; ch++) {
3619 v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
3620 p->idx);
3621 if (!(v & HDA_AMP_MUTE) && v > 0) {
3622 if (!check->power_on) {
3623 check->power_on = 1;
3624 snd_hda_power_up(codec);
3625 }
3626 return 1;
3627 }
3628 }
3629 }
3630 if (check->power_on) {
3631 check->power_on = 0;
3632 snd_hda_power_down(codec);
3633 }
3634 return 0;
3635}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003636EXPORT_SYMBOL_HDA(snd_hda_check_amp_list_power);
Takashi Iwaicb53c622007-08-10 17:21:45 +02003637#endif
Linus Torvalds1da177e2005-04-16 15:20:36 -07003638
Takashi Iwaic8b6bf9b2005-11-17 14:57:47 +01003639/*
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003640 * Channel mode helper
3641 */
Takashi Iwaid5191e52009-11-16 14:58:17 +01003642
3643/**
3644 * snd_hda_ch_mode_info - Info callback helper for the channel mode enum
3645 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003646int snd_hda_ch_mode_info(struct hda_codec *codec,
3647 struct snd_ctl_elem_info *uinfo,
3648 const struct hda_channel_mode *chmode,
3649 int num_chmodes)
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003650{
3651 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3652 uinfo->count = 1;
3653 uinfo->value.enumerated.items = num_chmodes;
3654 if (uinfo->value.enumerated.item >= num_chmodes)
3655 uinfo->value.enumerated.item = num_chmodes - 1;
3656 sprintf(uinfo->value.enumerated.name, "%dch",
3657 chmode[uinfo->value.enumerated.item].channels);
3658 return 0;
3659}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003660EXPORT_SYMBOL_HDA(snd_hda_ch_mode_info);
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003661
Takashi Iwaid5191e52009-11-16 14:58:17 +01003662/**
3663 * snd_hda_ch_mode_get - Get callback helper for the channel mode enum
3664 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003665int snd_hda_ch_mode_get(struct hda_codec *codec,
3666 struct snd_ctl_elem_value *ucontrol,
3667 const struct hda_channel_mode *chmode,
3668 int num_chmodes,
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003669 int max_channels)
3670{
3671 int i;
3672
3673 for (i = 0; i < num_chmodes; i++) {
3674 if (max_channels == chmode[i].channels) {
3675 ucontrol->value.enumerated.item[0] = i;
3676 break;
3677 }
3678 }
3679 return 0;
3680}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003681EXPORT_SYMBOL_HDA(snd_hda_ch_mode_get);
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003682
Takashi Iwaid5191e52009-11-16 14:58:17 +01003683/**
3684 * snd_hda_ch_mode_put - Put callback helper for the channel mode enum
3685 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003686int snd_hda_ch_mode_put(struct hda_codec *codec,
3687 struct snd_ctl_elem_value *ucontrol,
3688 const struct hda_channel_mode *chmode,
3689 int num_chmodes,
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003690 int *max_channelsp)
3691{
3692 unsigned int mode;
3693
3694 mode = ucontrol->value.enumerated.item[0];
Takashi Iwai68ea7b22007-11-15 15:54:38 +01003695 if (mode >= num_chmodes)
3696 return -EINVAL;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02003697 if (*max_channelsp == chmode[mode].channels)
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003698 return 0;
3699 /* change the current channel setting */
3700 *max_channelsp = chmode[mode].channels;
3701 if (chmode[mode].sequence)
Takashi Iwai82beb8f2007-08-10 17:09:26 +02003702 snd_hda_sequence_write_cache(codec, chmode[mode].sequence);
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003703 return 1;
3704}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003705EXPORT_SYMBOL_HDA(snd_hda_ch_mode_put);
Takashi Iwaid2a6d7d2005-11-17 11:06:29 +01003706
Linus Torvalds1da177e2005-04-16 15:20:36 -07003707/*
3708 * input MUX helper
3709 */
Takashi Iwaid5191e52009-11-16 14:58:17 +01003710
3711/**
3712 * snd_hda_input_mux_info_info - Info callback helper for the input-mux enum
3713 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003714int snd_hda_input_mux_info(const struct hda_input_mux *imux,
3715 struct snd_ctl_elem_info *uinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003716{
3717 unsigned int index;
3718
3719 uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3720 uinfo->count = 1;
3721 uinfo->value.enumerated.items = imux->num_items;
Takashi Iwai5513b0c2007-10-09 11:58:41 +02003722 if (!imux->num_items)
3723 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003724 index = uinfo->value.enumerated.item;
3725 if (index >= imux->num_items)
3726 index = imux->num_items - 1;
3727 strcpy(uinfo->value.enumerated.name, imux->items[index].label);
3728 return 0;
3729}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003730EXPORT_SYMBOL_HDA(snd_hda_input_mux_info);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003731
Takashi Iwaid5191e52009-11-16 14:58:17 +01003732/**
3733 * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum
3734 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003735int snd_hda_input_mux_put(struct hda_codec *codec,
3736 const struct hda_input_mux *imux,
3737 struct snd_ctl_elem_value *ucontrol,
3738 hda_nid_t nid,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003739 unsigned int *cur_val)
3740{
3741 unsigned int idx;
3742
Takashi Iwai5513b0c2007-10-09 11:58:41 +02003743 if (!imux->num_items)
3744 return 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07003745 idx = ucontrol->value.enumerated.item[0];
3746 if (idx >= imux->num_items)
3747 idx = imux->num_items - 1;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02003748 if (*cur_val == idx)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003749 return 0;
Takashi Iwai82beb8f2007-08-10 17:09:26 +02003750 snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
3751 imux->items[idx].index);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003752 *cur_val = idx;
3753 return 1;
3754}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003755EXPORT_SYMBOL_HDA(snd_hda_input_mux_put);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003756
3757
3758/*
3759 * Multi-channel / digital-out PCM helper functions
3760 */
3761
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003762/* setup SPDIF output stream */
3763static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
3764 unsigned int stream_tag, unsigned int format)
3765{
3766 /* turn off SPDIF once; otherwise the IEC958 bits won't be updated */
Takashi Iwai2f728532008-09-25 16:32:41 +02003767 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
3768 set_dig_out_convert(codec, nid,
3769 codec->spdif_ctls & ~AC_DIG1_ENABLE & 0xff,
3770 -1);
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003771 snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
Takashi Iwai2f728532008-09-25 16:32:41 +02003772 if (codec->slave_dig_outs) {
3773 hda_nid_t *d;
3774 for (d = codec->slave_dig_outs; *d; d++)
3775 snd_hda_codec_setup_stream(codec, *d, stream_tag, 0,
3776 format);
Matthew Ranostayde51ca12008-09-07 14:31:40 -04003777 }
Takashi Iwai2f728532008-09-25 16:32:41 +02003778 /* turn on again (if needed) */
3779 if (codec->spdif_status_reset && (codec->spdif_ctls & AC_DIG1_ENABLE))
3780 set_dig_out_convert(codec, nid,
3781 codec->spdif_ctls & 0xff, -1);
3782}
Matthew Ranostayde51ca12008-09-07 14:31:40 -04003783
Takashi Iwai2f728532008-09-25 16:32:41 +02003784static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
3785{
3786 snd_hda_codec_cleanup_stream(codec, nid);
3787 if (codec->slave_dig_outs) {
3788 hda_nid_t *d;
3789 for (d = codec->slave_dig_outs; *d; d++)
3790 snd_hda_codec_cleanup_stream(codec, *d);
3791 }
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003792}
3793
Takashi Iwaid5191e52009-11-16 14:58:17 +01003794/**
3795 * snd_hda_bus_reboot_notify - call the reboot notifier of each codec
3796 * @bus: HD-audio bus
3797 */
Takashi Iwaifb8d1a32009-11-10 16:02:29 +01003798void snd_hda_bus_reboot_notify(struct hda_bus *bus)
3799{
3800 struct hda_codec *codec;
3801
3802 if (!bus)
3803 return;
3804 list_for_each_entry(codec, &bus->codec_list, list) {
3805#ifdef CONFIG_SND_HDA_POWER_SAVE
3806 if (!codec->power_on)
3807 continue;
3808#endif
3809 if (codec->patch_ops.reboot_notify)
3810 codec->patch_ops.reboot_notify(codec);
3811 }
3812}
Takashi Iwai8f217a22009-11-10 18:26:12 +01003813EXPORT_SYMBOL_HDA(snd_hda_bus_reboot_notify);
Takashi Iwaifb8d1a32009-11-10 16:02:29 +01003814
Takashi Iwaid5191e52009-11-16 14:58:17 +01003815/**
3816 * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode
Linus Torvalds1da177e2005-04-16 15:20:36 -07003817 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003818int snd_hda_multi_out_dig_open(struct hda_codec *codec,
3819 struct hda_multi_out *mout)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003820{
Ingo Molnar62932df2006-01-16 16:34:20 +01003821 mutex_lock(&codec->spdif_mutex);
Takashi Iwai5930ca42007-04-16 11:23:56 +02003822 if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
3823 /* already opened as analog dup; reset it once */
Takashi Iwai2f728532008-09-25 16:32:41 +02003824 cleanup_dig_out_stream(codec, mout->dig_out_nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003825 mout->dig_out_used = HDA_DIG_EXCLUSIVE;
Ingo Molnar62932df2006-01-16 16:34:20 +01003826 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003827 return 0;
3828}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003829EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_open);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003830
Takashi Iwaid5191e52009-11-16 14:58:17 +01003831/**
3832 * snd_hda_multi_out_dig_prepare - prepare the digital out stream
3833 */
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003834int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
3835 struct hda_multi_out *mout,
3836 unsigned int stream_tag,
3837 unsigned int format,
3838 struct snd_pcm_substream *substream)
3839{
3840 mutex_lock(&codec->spdif_mutex);
3841 setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
3842 mutex_unlock(&codec->spdif_mutex);
3843 return 0;
3844}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003845EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_prepare);
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003846
Takashi Iwaid5191e52009-11-16 14:58:17 +01003847/**
3848 * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream
3849 */
Takashi Iwai9411e212009-02-13 11:32:28 +01003850int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
3851 struct hda_multi_out *mout)
3852{
3853 mutex_lock(&codec->spdif_mutex);
3854 cleanup_dig_out_stream(codec, mout->dig_out_nid);
3855 mutex_unlock(&codec->spdif_mutex);
3856 return 0;
3857}
3858EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_cleanup);
3859
Takashi Iwaid5191e52009-11-16 14:58:17 +01003860/**
3861 * snd_hda_multi_out_dig_close - release the digital out stream
Linus Torvalds1da177e2005-04-16 15:20:36 -07003862 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003863int snd_hda_multi_out_dig_close(struct hda_codec *codec,
3864 struct hda_multi_out *mout)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003865{
Ingo Molnar62932df2006-01-16 16:34:20 +01003866 mutex_lock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003867 mout->dig_out_used = 0;
Ingo Molnar62932df2006-01-16 16:34:20 +01003868 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003869 return 0;
3870}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003871EXPORT_SYMBOL_HDA(snd_hda_multi_out_dig_close);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003872
Takashi Iwaid5191e52009-11-16 14:58:17 +01003873/**
3874 * snd_hda_multi_out_analog_open - open analog outputs
3875 *
3876 * Open analog outputs and set up the hw-constraints.
3877 * If the digital outputs can be opened as slave, open the digital
3878 * outputs, too.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003879 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003880int snd_hda_multi_out_analog_open(struct hda_codec *codec,
3881 struct hda_multi_out *mout,
Takashi Iwai9a081602008-02-12 18:37:26 +01003882 struct snd_pcm_substream *substream,
3883 struct hda_pcm_stream *hinfo)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003884{
Takashi Iwai9a081602008-02-12 18:37:26 +01003885 struct snd_pcm_runtime *runtime = substream->runtime;
3886 runtime->hw.channels_max = mout->max_channels;
3887 if (mout->dig_out_nid) {
3888 if (!mout->analog_rates) {
3889 mout->analog_rates = hinfo->rates;
3890 mout->analog_formats = hinfo->formats;
3891 mout->analog_maxbps = hinfo->maxbps;
3892 } else {
3893 runtime->hw.rates = mout->analog_rates;
3894 runtime->hw.formats = mout->analog_formats;
3895 hinfo->maxbps = mout->analog_maxbps;
3896 }
3897 if (!mout->spdif_rates) {
3898 snd_hda_query_supported_pcm(codec, mout->dig_out_nid,
3899 &mout->spdif_rates,
3900 &mout->spdif_formats,
3901 &mout->spdif_maxbps);
3902 }
3903 mutex_lock(&codec->spdif_mutex);
3904 if (mout->share_spdif) {
Takashi Iwai022b4662009-07-03 23:03:30 +02003905 if ((runtime->hw.rates & mout->spdif_rates) &&
3906 (runtime->hw.formats & mout->spdif_formats)) {
3907 runtime->hw.rates &= mout->spdif_rates;
3908 runtime->hw.formats &= mout->spdif_formats;
3909 if (mout->spdif_maxbps < hinfo->maxbps)
3910 hinfo->maxbps = mout->spdif_maxbps;
3911 } else {
3912 mout->share_spdif = 0;
3913 /* FIXME: need notify? */
3914 }
Takashi Iwai9a081602008-02-12 18:37:26 +01003915 }
Frederik Deweerdteaa99852008-04-14 13:11:44 +02003916 mutex_unlock(&codec->spdif_mutex);
Takashi Iwai9a081602008-02-12 18:37:26 +01003917 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07003918 return snd_pcm_hw_constraint_step(substream->runtime, 0,
3919 SNDRV_PCM_HW_PARAM_CHANNELS, 2);
3920}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003921EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_open);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003922
Takashi Iwaid5191e52009-11-16 14:58:17 +01003923/**
3924 * snd_hda_multi_out_analog_prepare - Preapre the analog outputs.
3925 *
3926 * Set up the i/o for analog out.
3927 * When the digital out is available, copy the front out to digital out, too.
Linus Torvalds1da177e2005-04-16 15:20:36 -07003928 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003929int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
3930 struct hda_multi_out *mout,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003931 unsigned int stream_tag,
3932 unsigned int format,
Takashi Iwaic8b6bf9b2005-11-17 14:57:47 +01003933 struct snd_pcm_substream *substream)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003934{
3935 hda_nid_t *nids = mout->dac_nids;
3936 int chs = substream->runtime->channels;
3937 int i;
3938
Ingo Molnar62932df2006-01-16 16:34:20 +01003939 mutex_lock(&codec->spdif_mutex);
Takashi Iwai9a081602008-02-12 18:37:26 +01003940 if (mout->dig_out_nid && mout->share_spdif &&
3941 mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003942 if (chs == 2 &&
Takashi Iwai0ba21762007-04-16 11:29:14 +02003943 snd_hda_is_supported_format(codec, mout->dig_out_nid,
3944 format) &&
3945 !(codec->spdif_status & IEC958_AES0_NONAUDIO)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003946 mout->dig_out_used = HDA_DIG_ANALOG_DUP;
Takashi Iwai6b97eb42007-04-05 14:51:48 +02003947 setup_dig_out_stream(codec, mout->dig_out_nid,
3948 stream_tag, format);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003949 } else {
3950 mout->dig_out_used = 0;
Takashi Iwai2f728532008-09-25 16:32:41 +02003951 cleanup_dig_out_stream(codec, mout->dig_out_nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003952 }
3953 }
Ingo Molnar62932df2006-01-16 16:34:20 +01003954 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003955
3956 /* front */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003957 snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
3958 0, format);
Takashi Iwaid29240c2007-10-26 12:35:56 +02003959 if (!mout->no_share_stream &&
3960 mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
Linus Torvalds1da177e2005-04-16 15:20:36 -07003961 /* headphone out will just decode front left/right (stereo) */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003962 snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
3963 0, format);
Takashi Iwai82bc9552006-03-21 11:24:42 +01003964 /* extra outputs copied from front */
3965 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
Takashi Iwaid29240c2007-10-26 12:35:56 +02003966 if (!mout->no_share_stream && mout->extra_out_nid[i])
Takashi Iwai82bc9552006-03-21 11:24:42 +01003967 snd_hda_codec_setup_stream(codec,
3968 mout->extra_out_nid[i],
3969 stream_tag, 0, format);
3970
Linus Torvalds1da177e2005-04-16 15:20:36 -07003971 /* surrounds */
3972 for (i = 1; i < mout->num_dacs; i++) {
Takashi Iwai4b3acaf2005-06-10 19:48:10 +02003973 if (chs >= (i + 1) * 2) /* independent out */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003974 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
3975 i * 2, format);
Takashi Iwaid29240c2007-10-26 12:35:56 +02003976 else if (!mout->no_share_stream) /* copy front */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003977 snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
3978 0, format);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003979 }
3980 return 0;
3981}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01003982EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_prepare);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003983
Takashi Iwaid5191e52009-11-16 14:58:17 +01003984/**
3985 * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out
Linus Torvalds1da177e2005-04-16 15:20:36 -07003986 */
Takashi Iwai0ba21762007-04-16 11:29:14 +02003987int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
3988 struct hda_multi_out *mout)
Linus Torvalds1da177e2005-04-16 15:20:36 -07003989{
3990 hda_nid_t *nids = mout->dac_nids;
3991 int i;
3992
3993 for (i = 0; i < mout->num_dacs; i++)
Takashi Iwai888afa12008-03-18 09:57:50 +01003994 snd_hda_codec_cleanup_stream(codec, nids[i]);
Linus Torvalds1da177e2005-04-16 15:20:36 -07003995 if (mout->hp_nid)
Takashi Iwai888afa12008-03-18 09:57:50 +01003996 snd_hda_codec_cleanup_stream(codec, mout->hp_nid);
Takashi Iwai82bc9552006-03-21 11:24:42 +01003997 for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
3998 if (mout->extra_out_nid[i])
Takashi Iwai888afa12008-03-18 09:57:50 +01003999 snd_hda_codec_cleanup_stream(codec,
4000 mout->extra_out_nid[i]);
Ingo Molnar62932df2006-01-16 16:34:20 +01004001 mutex_lock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004002 if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
Takashi Iwai2f728532008-09-25 16:32:41 +02004003 cleanup_dig_out_stream(codec, mout->dig_out_nid);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004004 mout->dig_out_used = 0;
4005 }
Ingo Molnar62932df2006-01-16 16:34:20 +01004006 mutex_unlock(&codec->spdif_mutex);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004007 return 0;
4008}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004009EXPORT_SYMBOL_HDA(snd_hda_multi_out_analog_cleanup);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004010
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004011/*
Wu Fengguang6b345002008-10-07 14:21:41 +08004012 * Helper for automatic pin configuration
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004013 */
Kailang Yangdf694da2005-12-05 19:42:22 +01004014
Takashi Iwai12f288b2007-08-02 15:51:59 +02004015static int is_in_nid_list(hda_nid_t nid, hda_nid_t *list)
Kailang Yangdf694da2005-12-05 19:42:22 +01004016{
4017 for (; *list; list++)
4018 if (*list == nid)
4019 return 1;
4020 return 0;
4021}
4022
Steve Longerbeam81937d32007-05-08 15:33:03 +02004023
4024/*
4025 * Sort an associated group of pins according to their sequence numbers.
4026 */
4027static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
4028 int num_pins)
4029{
4030 int i, j;
4031 short seq;
4032 hda_nid_t nid;
4033
4034 for (i = 0; i < num_pins; i++) {
4035 for (j = i + 1; j < num_pins; j++) {
4036 if (sequences[i] > sequences[j]) {
4037 seq = sequences[i];
4038 sequences[i] = sequences[j];
4039 sequences[j] = seq;
4040 nid = pins[i];
4041 pins[i] = pins[j];
4042 pins[j] = nid;
4043 }
4044 }
4045 }
4046}
4047
4048
Takashi Iwai82bc9552006-03-21 11:24:42 +01004049/*
4050 * Parse all pin widgets and store the useful pin nids to cfg
4051 *
4052 * The number of line-outs or any primary output is stored in line_outs,
4053 * and the corresponding output pins are assigned to line_out_pins[],
4054 * in the order of front, rear, CLFE, side, ...
4055 *
4056 * If more extra outputs (speaker and headphone) are found, the pins are
Takashi Iwaieb06ed82006-09-20 17:10:27 +02004057 * assisnged to hp_pins[] and speaker_pins[], respectively. If no line-out jack
Takashi Iwai82bc9552006-03-21 11:24:42 +01004058 * is detected, one of speaker of HP pins is assigned as the primary
4059 * output, i.e. to line_out_pins[0]. So, line_outs is always positive
4060 * if any analog output exists.
4061 *
4062 * The analog input pins are assigned to input_pins array.
4063 * The digital input/output pins are assigned to dig_in_pin and dig_out_pin,
4064 * respectively.
4065 */
Takashi Iwai12f288b2007-08-02 15:51:59 +02004066int snd_hda_parse_pin_def_config(struct hda_codec *codec,
4067 struct auto_pin_cfg *cfg,
4068 hda_nid_t *ignore_nids)
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004069{
Takashi Iwai0ef6ce72008-01-22 15:35:37 +01004070 hda_nid_t nid, end_nid;
Steve Longerbeam81937d32007-05-08 15:33:03 +02004071 short seq, assoc_line_out, assoc_speaker;
4072 short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
4073 short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
Takashi Iwaif889fa92007-10-31 15:49:32 +01004074 short sequences_hp[ARRAY_SIZE(cfg->hp_pins)];
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004075
4076 memset(cfg, 0, sizeof(*cfg));
4077
Steve Longerbeam81937d32007-05-08 15:33:03 +02004078 memset(sequences_line_out, 0, sizeof(sequences_line_out));
4079 memset(sequences_speaker, 0, sizeof(sequences_speaker));
Takashi Iwaif889fa92007-10-31 15:49:32 +01004080 memset(sequences_hp, 0, sizeof(sequences_hp));
Steve Longerbeam81937d32007-05-08 15:33:03 +02004081 assoc_line_out = assoc_speaker = 0;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004082
Takashi Iwai0ef6ce72008-01-22 15:35:37 +01004083 end_nid = codec->start_nid + codec->num_nodes;
4084 for (nid = codec->start_nid; nid < end_nid; nid++) {
Takashi Iwai54d17402005-11-21 16:33:22 +01004085 unsigned int wid_caps = get_wcaps(codec, nid);
Takashi Iwaia22d5432009-07-27 12:54:26 +02004086 unsigned int wid_type = get_wcaps_type(wid_caps);
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004087 unsigned int def_conf;
4088 short assoc, loc;
4089
4090 /* read all default configuration for pin complex */
4091 if (wid_type != AC_WID_PIN)
4092 continue;
Kailang Yangdf694da2005-12-05 19:42:22 +01004093 /* ignore the given nids (e.g. pc-beep returns error) */
4094 if (ignore_nids && is_in_nid_list(nid, ignore_nids))
4095 continue;
4096
Takashi Iwaic17a1ab2009-02-23 09:28:12 +01004097 def_conf = snd_hda_codec_get_pincfg(codec, nid);
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004098 if (get_defcfg_connect(def_conf) == AC_JACK_PORT_NONE)
4099 continue;
4100 loc = get_defcfg_location(def_conf);
4101 switch (get_defcfg_device(def_conf)) {
4102 case AC_JACK_LINE_OUT:
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004103 seq = get_defcfg_sequence(def_conf);
4104 assoc = get_defcfg_association(def_conf);
Matthew Ranostay90da78b2008-01-24 11:48:01 +01004105
4106 if (!(wid_caps & AC_WCAP_STEREO))
4107 if (!cfg->mono_out_pin)
4108 cfg->mono_out_pin = nid;
Takashi Iwai0ba21762007-04-16 11:29:14 +02004109 if (!assoc)
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004110 continue;
Takashi Iwai0ba21762007-04-16 11:29:14 +02004111 if (!assoc_line_out)
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004112 assoc_line_out = assoc;
4113 else if (assoc_line_out != assoc)
4114 continue;
4115 if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins))
4116 continue;
4117 cfg->line_out_pins[cfg->line_outs] = nid;
Steve Longerbeam81937d32007-05-08 15:33:03 +02004118 sequences_line_out[cfg->line_outs] = seq;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004119 cfg->line_outs++;
4120 break;
Takashi Iwai8d88bc32005-11-17 11:09:23 +01004121 case AC_JACK_SPEAKER:
Steve Longerbeam81937d32007-05-08 15:33:03 +02004122 seq = get_defcfg_sequence(def_conf);
4123 assoc = get_defcfg_association(def_conf);
4124 if (! assoc)
4125 continue;
4126 if (! assoc_speaker)
4127 assoc_speaker = assoc;
4128 else if (assoc_speaker != assoc)
4129 continue;
Takashi Iwai82bc9552006-03-21 11:24:42 +01004130 if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
4131 continue;
4132 cfg->speaker_pins[cfg->speaker_outs] = nid;
Steve Longerbeam81937d32007-05-08 15:33:03 +02004133 sequences_speaker[cfg->speaker_outs] = seq;
Takashi Iwai82bc9552006-03-21 11:24:42 +01004134 cfg->speaker_outs++;
Takashi Iwai8d88bc32005-11-17 11:09:23 +01004135 break;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004136 case AC_JACK_HP_OUT:
Takashi Iwaif889fa92007-10-31 15:49:32 +01004137 seq = get_defcfg_sequence(def_conf);
4138 assoc = get_defcfg_association(def_conf);
Takashi Iwaieb06ed82006-09-20 17:10:27 +02004139 if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins))
4140 continue;
4141 cfg->hp_pins[cfg->hp_outs] = nid;
Takashi Iwaif889fa92007-10-31 15:49:32 +01004142 sequences_hp[cfg->hp_outs] = (assoc << 4) | seq;
Takashi Iwaieb06ed82006-09-20 17:10:27 +02004143 cfg->hp_outs++;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004144 break;
Takashi Iwai314634b2006-09-21 11:56:18 +02004145 case AC_JACK_MIC_IN: {
4146 int preferred, alt;
4147 if (loc == AC_JACK_LOC_FRONT) {
4148 preferred = AUTO_PIN_FRONT_MIC;
4149 alt = AUTO_PIN_MIC;
4150 } else {
4151 preferred = AUTO_PIN_MIC;
4152 alt = AUTO_PIN_FRONT_MIC;
4153 }
4154 if (!cfg->input_pins[preferred])
4155 cfg->input_pins[preferred] = nid;
4156 else if (!cfg->input_pins[alt])
4157 cfg->input_pins[alt] = nid;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004158 break;
Takashi Iwai314634b2006-09-21 11:56:18 +02004159 }
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004160 case AC_JACK_LINE_IN:
4161 if (loc == AC_JACK_LOC_FRONT)
4162 cfg->input_pins[AUTO_PIN_FRONT_LINE] = nid;
4163 else
4164 cfg->input_pins[AUTO_PIN_LINE] = nid;
4165 break;
4166 case AC_JACK_CD:
4167 cfg->input_pins[AUTO_PIN_CD] = nid;
4168 break;
4169 case AC_JACK_AUX:
4170 cfg->input_pins[AUTO_PIN_AUX] = nid;
4171 break;
4172 case AC_JACK_SPDIF_OUT:
Takashi Iwai1b52ae72009-01-20 17:17:29 +01004173 case AC_JACK_DIG_OTHER_OUT:
Takashi Iwai0852d7a2009-02-11 11:35:15 +01004174 if (cfg->dig_outs >= ARRAY_SIZE(cfg->dig_out_pins))
4175 continue;
4176 cfg->dig_out_pins[cfg->dig_outs] = nid;
4177 cfg->dig_out_type[cfg->dig_outs] =
4178 (loc == AC_JACK_LOC_HDMI) ?
4179 HDA_PCM_TYPE_HDMI : HDA_PCM_TYPE_SPDIF;
4180 cfg->dig_outs++;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004181 break;
4182 case AC_JACK_SPDIF_IN:
Takashi Iwai1b52ae72009-01-20 17:17:29 +01004183 case AC_JACK_DIG_OTHER_IN:
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004184 cfg->dig_in_pin = nid;
Takashi Iwai2297bd62009-01-20 18:24:13 +01004185 if (loc == AC_JACK_LOC_HDMI)
4186 cfg->dig_in_type = HDA_PCM_TYPE_HDMI;
4187 else
4188 cfg->dig_in_type = HDA_PCM_TYPE_SPDIF;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004189 break;
4190 }
4191 }
4192
Takashi Iwai5832fcf2008-02-12 18:30:12 +01004193 /* FIX-UP:
4194 * If no line-out is defined but multiple HPs are found,
4195 * some of them might be the real line-outs.
4196 */
4197 if (!cfg->line_outs && cfg->hp_outs > 1) {
4198 int i = 0;
4199 while (i < cfg->hp_outs) {
4200 /* The real HPs should have the sequence 0x0f */
4201 if ((sequences_hp[i] & 0x0f) == 0x0f) {
4202 i++;
4203 continue;
4204 }
4205 /* Move it to the line-out table */
4206 cfg->line_out_pins[cfg->line_outs] = cfg->hp_pins[i];
4207 sequences_line_out[cfg->line_outs] = sequences_hp[i];
4208 cfg->line_outs++;
4209 cfg->hp_outs--;
4210 memmove(cfg->hp_pins + i, cfg->hp_pins + i + 1,
4211 sizeof(cfg->hp_pins[0]) * (cfg->hp_outs - i));
4212 memmove(sequences_hp + i - 1, sequences_hp + i,
4213 sizeof(sequences_hp[0]) * (cfg->hp_outs - i));
4214 }
4215 }
4216
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004217 /* sort by sequence */
Steve Longerbeam81937d32007-05-08 15:33:03 +02004218 sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out,
4219 cfg->line_outs);
4220 sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker,
4221 cfg->speaker_outs);
Takashi Iwaif889fa92007-10-31 15:49:32 +01004222 sort_pins_by_sequence(cfg->hp_pins, sequences_hp,
4223 cfg->hp_outs);
Steve Longerbeam81937d32007-05-08 15:33:03 +02004224
Takashi Iwaif889fa92007-10-31 15:49:32 +01004225 /* if we have only one mic, make it AUTO_PIN_MIC */
4226 if (!cfg->input_pins[AUTO_PIN_MIC] &&
4227 cfg->input_pins[AUTO_PIN_FRONT_MIC]) {
4228 cfg->input_pins[AUTO_PIN_MIC] =
4229 cfg->input_pins[AUTO_PIN_FRONT_MIC];
4230 cfg->input_pins[AUTO_PIN_FRONT_MIC] = 0;
4231 }
4232 /* ditto for line-in */
4233 if (!cfg->input_pins[AUTO_PIN_LINE] &&
4234 cfg->input_pins[AUTO_PIN_FRONT_LINE]) {
4235 cfg->input_pins[AUTO_PIN_LINE] =
4236 cfg->input_pins[AUTO_PIN_FRONT_LINE];
4237 cfg->input_pins[AUTO_PIN_FRONT_LINE] = 0;
4238 }
4239
Steve Longerbeam81937d32007-05-08 15:33:03 +02004240 /*
4241 * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
4242 * as a primary output
4243 */
4244 if (!cfg->line_outs) {
4245 if (cfg->speaker_outs) {
4246 cfg->line_outs = cfg->speaker_outs;
4247 memcpy(cfg->line_out_pins, cfg->speaker_pins,
4248 sizeof(cfg->speaker_pins));
4249 cfg->speaker_outs = 0;
4250 memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
4251 cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
4252 } else if (cfg->hp_outs) {
4253 cfg->line_outs = cfg->hp_outs;
4254 memcpy(cfg->line_out_pins, cfg->hp_pins,
4255 sizeof(cfg->hp_pins));
4256 cfg->hp_outs = 0;
4257 memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
4258 cfg->line_out_type = AUTO_PIN_HP_OUT;
4259 }
4260 }
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004261
Takashi Iwaicb8e2f82005-07-29 11:54:32 +02004262 /* Reorder the surround channels
4263 * ALSA sequence is front/surr/clfe/side
4264 * HDA sequence is:
4265 * 4-ch: front/surr => OK as it is
4266 * 6-ch: front/clfe/surr
Takashi Iwai9422db42007-04-20 16:11:43 +02004267 * 8-ch: front/clfe/rear/side|fc
Takashi Iwaicb8e2f82005-07-29 11:54:32 +02004268 */
4269 switch (cfg->line_outs) {
4270 case 3:
Takashi Iwaicb8e2f82005-07-29 11:54:32 +02004271 case 4:
4272 nid = cfg->line_out_pins[1];
Takashi Iwai9422db42007-04-20 16:11:43 +02004273 cfg->line_out_pins[1] = cfg->line_out_pins[2];
Takashi Iwaicb8e2f82005-07-29 11:54:32 +02004274 cfg->line_out_pins[2] = nid;
4275 break;
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004276 }
4277
Takashi Iwai82bc9552006-03-21 11:24:42 +01004278 /*
4279 * debug prints of the parsed results
4280 */
4281 snd_printd("autoconfig: line_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
4282 cfg->line_outs, cfg->line_out_pins[0], cfg->line_out_pins[1],
4283 cfg->line_out_pins[2], cfg->line_out_pins[3],
4284 cfg->line_out_pins[4]);
4285 snd_printd(" speaker_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
4286 cfg->speaker_outs, cfg->speaker_pins[0],
4287 cfg->speaker_pins[1], cfg->speaker_pins[2],
4288 cfg->speaker_pins[3], cfg->speaker_pins[4]);
Takashi Iwaieb06ed82006-09-20 17:10:27 +02004289 snd_printd(" hp_outs=%d (0x%x/0x%x/0x%x/0x%x/0x%x)\n",
4290 cfg->hp_outs, cfg->hp_pins[0],
4291 cfg->hp_pins[1], cfg->hp_pins[2],
4292 cfg->hp_pins[3], cfg->hp_pins[4]);
Matthew Ranostay90da78b2008-01-24 11:48:01 +01004293 snd_printd(" mono: mono_out=0x%x\n", cfg->mono_out_pin);
Takashi Iwai0852d7a2009-02-11 11:35:15 +01004294 if (cfg->dig_outs)
4295 snd_printd(" dig-out=0x%x/0x%x\n",
4296 cfg->dig_out_pins[0], cfg->dig_out_pins[1]);
Takashi Iwai82bc9552006-03-21 11:24:42 +01004297 snd_printd(" inputs: mic=0x%x, fmic=0x%x, line=0x%x, fline=0x%x,"
4298 " cd=0x%x, aux=0x%x\n",
4299 cfg->input_pins[AUTO_PIN_MIC],
4300 cfg->input_pins[AUTO_PIN_FRONT_MIC],
4301 cfg->input_pins[AUTO_PIN_LINE],
4302 cfg->input_pins[AUTO_PIN_FRONT_LINE],
4303 cfg->input_pins[AUTO_PIN_CD],
4304 cfg->input_pins[AUTO_PIN_AUX]);
Takashi Iwai32d2c7f2009-02-11 11:33:13 +01004305 if (cfg->dig_in_pin)
Takashi Iwai89ce9e82009-01-20 17:15:57 +01004306 snd_printd(" dig-in=0x%x\n", cfg->dig_in_pin);
Takashi Iwai82bc9552006-03-21 11:24:42 +01004307
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004308 return 0;
4309}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004310EXPORT_SYMBOL_HDA(snd_hda_parse_pin_def_config);
Takashi Iwaie9edcee2005-06-13 14:16:38 +02004311
Takashi Iwai4a471b72005-12-07 13:56:29 +01004312/* labels for input pins */
4313const char *auto_pin_cfg_labels[AUTO_PIN_LAST] = {
4314 "Mic", "Front Mic", "Line", "Front Line", "CD", "Aux"
4315};
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004316EXPORT_SYMBOL_HDA(auto_pin_cfg_labels);
Takashi Iwai4a471b72005-12-07 13:56:29 +01004317
4318
Linus Torvalds1da177e2005-04-16 15:20:36 -07004319#ifdef CONFIG_PM
4320/*
4321 * power management
4322 */
4323
4324/**
4325 * snd_hda_suspend - suspend the codecs
4326 * @bus: the HDA bus
Linus Torvalds1da177e2005-04-16 15:20:36 -07004327 *
4328 * Returns 0 if successful.
4329 */
Takashi Iwai8dd78332009-06-02 01:16:07 +02004330int snd_hda_suspend(struct hda_bus *bus)
Linus Torvalds1da177e2005-04-16 15:20:36 -07004331{
Takashi Iwai0ba21762007-04-16 11:29:14 +02004332 struct hda_codec *codec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004333
Takashi Iwai0ba21762007-04-16 11:29:14 +02004334 list_for_each_entry(codec, &bus->codec_list, list) {
Takashi Iwai0b7a2e92007-08-14 15:18:26 +02004335#ifdef CONFIG_SND_HDA_POWER_SAVE
4336 if (!codec->power_on)
4337 continue;
4338#endif
Takashi Iwaicb53c622007-08-10 17:21:45 +02004339 hda_call_codec_suspend(codec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004340 }
4341 return 0;
4342}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004343EXPORT_SYMBOL_HDA(snd_hda_suspend);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004344
4345/**
4346 * snd_hda_resume - resume the codecs
4347 * @bus: the HDA bus
Linus Torvalds1da177e2005-04-16 15:20:36 -07004348 *
4349 * Returns 0 if successful.
Takashi Iwaicb53c622007-08-10 17:21:45 +02004350 *
4351 * This fucntion is defined only when POWER_SAVE isn't set.
4352 * In the power-save mode, the codec is resumed dynamically.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004353 */
4354int snd_hda_resume(struct hda_bus *bus)
4355{
Takashi Iwai0ba21762007-04-16 11:29:14 +02004356 struct hda_codec *codec;
Linus Torvalds1da177e2005-04-16 15:20:36 -07004357
Takashi Iwai0ba21762007-04-16 11:29:14 +02004358 list_for_each_entry(codec, &bus->codec_list, list) {
Maxim Levitskyd804ad92007-09-03 15:28:04 +02004359 if (snd_hda_codec_needs_resume(codec))
4360 hda_call_codec_resume(codec);
Linus Torvalds1da177e2005-04-16 15:20:36 -07004361 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07004362 return 0;
4363}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004364EXPORT_SYMBOL_HDA(snd_hda_resume);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01004365#endif /* CONFIG_PM */
Takashi Iwaib2e18592008-07-30 15:01:44 +02004366
4367/*
4368 * generic arrays
4369 */
4370
Takashi Iwaid5191e52009-11-16 14:58:17 +01004371/**
4372 * snd_array_new - get a new element from the given array
4373 * @array: the array object
4374 *
4375 * Get a new element from the given array. If it exceeds the
4376 * pre-allocated array size, re-allocate the array.
4377 *
4378 * Returns NULL if allocation failed.
Takashi Iwaib2e18592008-07-30 15:01:44 +02004379 */
4380void *snd_array_new(struct snd_array *array)
4381{
4382 if (array->used >= array->alloced) {
4383 int num = array->alloced + array->alloc_align;
Takashi Iwaib910d9a2008-11-07 00:26:52 +01004384 void *nlist;
4385 if (snd_BUG_ON(num >= 4096))
4386 return NULL;
4387 nlist = kcalloc(num + 1, array->elem_size, GFP_KERNEL);
Takashi Iwaib2e18592008-07-30 15:01:44 +02004388 if (!nlist)
4389 return NULL;
4390 if (array->list) {
4391 memcpy(nlist, array->list,
4392 array->elem_size * array->alloced);
4393 kfree(array->list);
4394 }
4395 array->list = nlist;
4396 array->alloced = num;
4397 }
Takashi Iwaif43aa022008-11-10 16:24:26 +01004398 return snd_array_elem(array, array->used++);
Takashi Iwaib2e18592008-07-30 15:01:44 +02004399}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004400EXPORT_SYMBOL_HDA(snd_array_new);
Takashi Iwaib2e18592008-07-30 15:01:44 +02004401
Takashi Iwaid5191e52009-11-16 14:58:17 +01004402/**
4403 * snd_array_free - free the given array elements
4404 * @array: the array object
4405 */
Takashi Iwaib2e18592008-07-30 15:01:44 +02004406void snd_array_free(struct snd_array *array)
4407{
4408 kfree(array->list);
4409 array->used = 0;
4410 array->alloced = 0;
4411 array->list = NULL;
4412}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004413EXPORT_SYMBOL_HDA(snd_array_free);
Takashi Iwaib2022262008-11-21 21:24:03 +01004414
Takashi Iwaid5191e52009-11-16 14:58:17 +01004415/**
4416 * snd_print_pcm_rates - Print the supported PCM rates to the string buffer
4417 * @pcm: PCM caps bits
4418 * @buf: the string buffer to write
4419 * @buflen: the max buffer length
4420 *
Takashi Iwaib2022262008-11-21 21:24:03 +01004421 * used by hda_proc.c and hda_eld.c
4422 */
4423void snd_print_pcm_rates(int pcm, char *buf, int buflen)
4424{
4425 static unsigned int rates[] = {
4426 8000, 11025, 16000, 22050, 32000, 44100, 48000, 88200,
4427 96000, 176400, 192000, 384000
4428 };
4429 int i, j;
4430
4431 for (i = 0, j = 0; i < ARRAY_SIZE(rates); i++)
4432 if (pcm & (1 << i))
4433 j += snprintf(buf + j, buflen - j, " %d", rates[i]);
4434
4435 buf[j] = '\0'; /* necessary when j == 0 */
4436}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004437EXPORT_SYMBOL_HDA(snd_print_pcm_rates);
Takashi Iwaib2022262008-11-21 21:24:03 +01004438
Takashi Iwaid5191e52009-11-16 14:58:17 +01004439/**
4440 * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer
4441 * @pcm: PCM caps bits
4442 * @buf: the string buffer to write
4443 * @buflen: the max buffer length
4444 *
4445 * used by hda_proc.c and hda_eld.c
4446 */
Takashi Iwaib2022262008-11-21 21:24:03 +01004447void snd_print_pcm_bits(int pcm, char *buf, int buflen)
4448{
4449 static unsigned int bits[] = { 8, 16, 20, 24, 32 };
4450 int i, j;
4451
4452 for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++)
4453 if (pcm & (AC_SUPPCM_BITS_8 << i))
4454 j += snprintf(buf + j, buflen - j, " %d", bits[i]);
4455
4456 buf[j] = '\0'; /* necessary when j == 0 */
4457}
Takashi Iwaiff7a3262008-11-28 15:17:06 +01004458EXPORT_SYMBOL_HDA(snd_print_pcm_bits);
Takashi Iwai1289e9e2008-11-27 15:47:11 +01004459
4460MODULE_DESCRIPTION("HDA codec core");
4461MODULE_LICENSE("GPL");