hda_codec.c 141 KB
Newer Older
Linus Torvalds's avatar
Linus Torvalds committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/*
 * Universal Interface for Intel High Definition Audio Codec
 *
 * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
 *
 *
 *  This driver is free software; you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation; either version 2 of the License, or
 *  (at your option) any later version.
 *
 *  This driver is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
 */

22
#include <linux/mm.h>
Linus Torvalds's avatar
Linus Torvalds committed
23
24
25
26
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/pci.h>
27
#include <linux/mutex.h>
28
#include <linux/module.h>
Linus Torvalds's avatar
Linus Torvalds committed
29
30
31
#include <sound/core.h>
#include "hda_codec.h"
#include <sound/asoundef.h>
32
#include <sound/tlv.h>
Linus Torvalds's avatar
Linus Torvalds committed
33
#include <sound/initval.h>
34
#include <sound/jack.h>
Linus Torvalds's avatar
Linus Torvalds committed
35
#include "hda_local.h"
36
#include "hda_beep.h"
37
#include "hda_jack.h"
38
#include <sound/hda_hwdep.h>
Linus Torvalds's avatar
Linus Torvalds committed
39

40
41
42
#define CREATE_TRACE_POINTS
#include "hda_trace.h"

Linus Torvalds's avatar
Linus Torvalds committed
43
44
45
46
47
48
49
50
51
52
53
/*
 * vendor / preset table
 */

struct hda_vendor_id {
	unsigned int id;
	const char *name;
};

/* codec vendor labels */
static struct hda_vendor_id hda_vendor_ids[] = {
54
	{ 0x1002, "ATI" },
55
	{ 0x1013, "Cirrus Logic" },
56
	{ 0x1057, "Motorola" },
57
	{ 0x1095, "Silicon Image" },
58
	{ 0x10de, "Nvidia" },
59
	{ 0x10ec, "Realtek" },
60
	{ 0x1102, "Creative" },
61
	{ 0x1106, "VIA" },
62
	{ 0x111d, "IDT" },
63
	{ 0x11c1, "LSI" },
64
	{ 0x11d4, "Analog Devices" },
Linus Torvalds's avatar
Linus Torvalds committed
65
	{ 0x13f6, "C-Media" },
66
	{ 0x14f1, "Conexant" },
67
68
	{ 0x17e8, "Chrontel" },
	{ 0x1854, "LG" },
69
	{ 0x1aec, "Wolfson Microelectronics" },
Linus Torvalds's avatar
Linus Torvalds committed
70
	{ 0x434d, "C-Media" },
71
	{ 0x8086, "Intel" },
Matt's avatar
Matt committed
72
	{ 0x8384, "SigmaTel" },
Linus Torvalds's avatar
Linus Torvalds committed
73
74
75
	{} /* terminator */
};

76
77
78
79
80
81
82
83
84
85
static DEFINE_MUTEX(preset_mutex);
static LIST_HEAD(hda_preset_tables);

int snd_hda_add_codec_preset(struct hda_codec_preset_list *preset)
{
	mutex_lock(&preset_mutex);
	list_add_tail(&preset->list, &hda_preset_tables);
	mutex_unlock(&preset_mutex);
	return 0;
}
86
EXPORT_SYMBOL_HDA(snd_hda_add_codec_preset);
87
88
89
90
91
92
93
94

int snd_hda_delete_codec_preset(struct hda_codec_preset_list *preset)
{
	mutex_lock(&preset_mutex);
	list_del(&preset->list);
	mutex_unlock(&preset_mutex);
	return 0;
}
95
EXPORT_SYMBOL_HDA(snd_hda_delete_codec_preset);
Linus Torvalds's avatar
Linus Torvalds committed
96

97
#ifdef CONFIG_PM
98
#define codec_in_pm(codec)	((codec)->in_pm)
99
100
static void hda_power_work(struct work_struct *work);
static void hda_keep_power_on(struct hda_codec *codec);
101
#define hda_codec_is_power_on(codec)	((codec)->power_on)
102
103
104
105
106
static inline void hda_call_pm_notify(struct hda_bus *bus, bool power_up)
{
	if (bus->ops.pm_notify)
		bus->ops.pm_notify(bus, power_up);
}
107
#else
108
#define codec_in_pm(codec)	0
109
static inline void hda_keep_power_on(struct hda_codec *codec) {}
110
#define hda_codec_is_power_on(codec)	1
111
#define hda_call_pm_notify(bus, state) {}
112
113
#endif

114
115
116
117
118
119
120
/**
 * snd_hda_get_jack_location - Give a location string of the jack
 * @cfg: pin default config value
 *
 * Parse the pin default config value and returns the string of the
 * jack location, e.g. "Rear", "Front", etc.
 */
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
const char *snd_hda_get_jack_location(u32 cfg)
{
	static char *bases[7] = {
		"N/A", "Rear", "Front", "Left", "Right", "Top", "Bottom",
	};
	static unsigned char specials_idx[] = {
		0x07, 0x08,
		0x17, 0x18, 0x19,
		0x37, 0x38
	};
	static char *specials[] = {
		"Rear Panel", "Drive Bar",
		"Riser", "HDMI", "ATAPI",
		"Mobile-In", "Mobile-Out"
	};
	int i;
	cfg = (cfg & AC_DEFCFG_LOCATION) >> AC_DEFCFG_LOCATION_SHIFT;
	if ((cfg & 0x0f) < 7)
		return bases[cfg & 0x0f];
	for (i = 0; i < ARRAY_SIZE(specials_idx); i++) {
		if (cfg == specials_idx[i])
			return specials[i];
	}
	return "UNKNOWN";
}
146
EXPORT_SYMBOL_HDA(snd_hda_get_jack_location);
147

148
149
150
151
152
153
154
/**
 * snd_hda_get_jack_connectivity - Give a connectivity string of the jack
 * @cfg: pin default config value
 *
 * Parse the pin default config value and returns the string of the
 * jack connectivity, i.e. external or internal connection.
 */
155
156
157
158
159
160
const char *snd_hda_get_jack_connectivity(u32 cfg)
{
	static char *jack_locations[4] = { "Ext", "Int", "Sep", "Oth" };

	return jack_locations[(cfg >> (AC_DEFCFG_LOCATION_SHIFT + 4)) & 3];
}
161
EXPORT_SYMBOL_HDA(snd_hda_get_jack_connectivity);
162

163
164
165
166
167
168
169
/**
 * snd_hda_get_jack_type - Give a type string of the jack
 * @cfg: pin default config value
 *
 * Parse the pin default config value and returns the string of the
 * jack type, i.e. the purpose of the jack, such as Line-Out or CD.
 */
170
171
172
173
174
175
176
177
178
179
180
181
const char *snd_hda_get_jack_type(u32 cfg)
{
	static char *jack_types[16] = {
		"Line Out", "Speaker", "HP Out", "CD",
		"SPDIF Out", "Digital Out", "Modem Line", "Modem Hand",
		"Line In", "Aux", "Mic", "Telephony",
		"SPDIF In", "Digitial In", "Reserved", "Other"
	};

	return jack_types[(cfg & AC_DEFCFG_DEVICE)
				>> AC_DEFCFG_DEVICE_SHIFT];
}
182
EXPORT_SYMBOL_HDA(snd_hda_get_jack_type);
183

184
185
186
187
188
189
190
191
192
/*
 * Compose a 32bit command word to be sent to the HD-audio controller
 */
static inline unsigned int
make_codec_cmd(struct hda_codec *codec, hda_nid_t nid, int direct,
	       unsigned int verb, unsigned int parm)
{
	u32 val;

193
194
	if ((codec->addr & ~0xf) || (direct & ~1) || (nid & ~0x7f) ||
	    (verb & ~0xfff) || (parm & ~0xffff)) {
195
196
197
198
199
200
		printk(KERN_ERR "hda-codec: out of range cmd %x:%x:%x:%x:%x\n",
		       codec->addr, direct, nid, verb, parm);
		return ~0;
	}

	val = (u32)codec->addr << 28;
201
202
203
204
205
206
207
	val |= (u32)direct << 27;
	val |= (u32)nid << 20;
	val |= verb << 8;
	val |= parm;
	return val;
}

208
209
210
211
212
213
214
/*
 * Send and receive a verb
 */
static int codec_exec_verb(struct hda_codec *codec, unsigned int cmd,
			   unsigned int *res)
{
	struct hda_bus *bus = codec->bus;
215
	int err;
216

217
218
219
	if (cmd == ~0)
		return -1;

220
221
	if (res)
		*res = -1;
222
 again:
223
224
	snd_hda_power_up(codec);
	mutex_lock(&bus->cmd_mutex);
225
	trace_hda_send_cmd(codec, cmd);
226
	err = bus->ops.command(bus, cmd);
227
	if (!err && res) {
228
		*res = bus->ops.get_response(bus, codec->addr);
229
230
		trace_hda_get_response(codec, *res);
	}
231
232
	mutex_unlock(&bus->cmd_mutex);
	snd_hda_power_down(codec);
233
	if (!codec_in_pm(codec) && res && *res == -1 && bus->rirb_error) {
234
235
236
		if (bus->response_reset) {
			snd_printd("hda_codec: resetting BUS due to "
				   "fatal communication error\n");
237
			trace_hda_bus_reset(bus);
238
239
240
241
242
			bus->ops.bus_reset(bus);
		}
		goto again;
	}
	/* clear reset-flag when the communication gets recovered */
243
	if (!err || codec_in_pm(codec))
244
		bus->response_reset = 0;
245
246
247
	return err;
}

Linus Torvalds's avatar
Linus Torvalds committed
248
249
250
251
252
253
254
255
256
257
258
259
/**
 * snd_hda_codec_read - send a command and get the response
 * @codec: the HDA codec
 * @nid: NID to send the command
 * @direct: direct flag
 * @verb: the verb to send
 * @parm: the parameter for the verb
 *
 * Send a single command and read the corresponding response.
 *
 * Returns the obtained response value, or -1 for an error.
 */
260
261
unsigned int snd_hda_codec_read(struct hda_codec *codec, hda_nid_t nid,
				int direct,
Linus Torvalds's avatar
Linus Torvalds committed
262
263
				unsigned int verb, unsigned int parm)
{
264
265
	unsigned cmd = make_codec_cmd(codec, nid, direct, verb, parm);
	unsigned int res;
266
267
	if (codec_exec_verb(codec, cmd, &res))
		return -1;
Linus Torvalds's avatar
Linus Torvalds committed
268
269
	return res;
}
270
EXPORT_SYMBOL_HDA(snd_hda_codec_read);
Linus Torvalds's avatar
Linus Torvalds committed
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286

/**
 * snd_hda_codec_write - send a single command without waiting for response
 * @codec: the HDA codec
 * @nid: NID to send the command
 * @direct: direct flag
 * @verb: the verb to send
 * @parm: the parameter for the verb
 *
 * Send a single command without waiting for response.
 *
 * Returns 0 if successful, or a negative error code.
 */
int snd_hda_codec_write(struct hda_codec *codec, hda_nid_t nid, int direct,
			 unsigned int verb, unsigned int parm)
{
287
	unsigned int cmd = make_codec_cmd(codec, nid, direct, verb, parm);
288
	unsigned int res;
289
290
	return codec_exec_verb(codec, cmd,
			       codec->bus->sync_write ? &res : NULL);
Linus Torvalds's avatar
Linus Torvalds committed
291
}
292
EXPORT_SYMBOL_HDA(snd_hda_codec_write);
Linus Torvalds's avatar
Linus Torvalds committed
293
294
295
296
297
298
299
300
301
302
303
304
305
306

/**
 * snd_hda_sequence_write - sequence writes
 * @codec: the HDA codec
 * @seq: VERB array to send
 *
 * Send the commands sequentially from the given array.
 * The array must be terminated with NID=0.
 */
void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
{
	for (; seq->nid; seq++)
		snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
}
307
EXPORT_SYMBOL_HDA(snd_hda_sequence_write);
Linus Torvalds's avatar
Linus Torvalds committed
308
309
310
311
312
313
314
315
316
317

/**
 * snd_hda_get_sub_nodes - get the range of sub nodes
 * @codec: the HDA codec
 * @nid: NID to parse
 * @start_id: the pointer to store the start NID
 *
 * Parse the NID and store the start NID of its sub-nodes.
 * Returns the number of sub-nodes.
 */
318
319
int snd_hda_get_sub_nodes(struct hda_codec *codec, hda_nid_t nid,
			  hda_nid_t *start_id)
Linus Torvalds's avatar
Linus Torvalds committed
320
321
322
323
{
	unsigned int parm;

	parm = snd_hda_param_read(codec, nid, AC_PAR_NODE_COUNT);
324
325
	if (parm == -1)
		return 0;
Linus Torvalds's avatar
Linus Torvalds committed
326
327
328
	*start_id = (parm >> 16) & 0x7fff;
	return (int)(parm & 0x7fff);
}
329
EXPORT_SYMBOL_HDA(snd_hda_get_sub_nodes);
Linus Torvalds's avatar
Linus Torvalds committed
330

331
332
333
334
335
336
337
338
339
340
341
342
343
/* look up the cached results */
static hda_nid_t *lookup_conn_list(struct snd_array *array, hda_nid_t nid)
{
	int i, len;
	for (i = 0; i < array->used; ) {
		hda_nid_t *p = snd_array_elem(array, i);
		if (nid == *p)
			return p;
		len = p[1];
		i += len + 2;
	}
	return NULL;
}
344

345
346
347
348
349
350
351
352
353
354
355
356
/* read the connection and add to the cache */
static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid)
{
	hda_nid_t list[HDA_MAX_CONNECTIONS];
	int len;

	len = snd_hda_get_raw_connections(codec, nid, list, ARRAY_SIZE(list));
	if (len < 0)
		return len;
	return snd_hda_override_conn_list(codec, nid, len, list);
}

Linus Torvalds's avatar
Linus Torvalds committed
357
/**
358
 * snd_hda_get_connections - copy connection list
Linus Torvalds's avatar
Linus Torvalds committed
359
360
 * @codec: the HDA codec
 * @nid: NID to parse
361
362
 * @conn_list: connection list array; when NULL, checks only the size
 * @max_conns: max. number of connections to store
Linus Torvalds's avatar
Linus Torvalds committed
363
364
365
366
367
368
 *
 * Parses the connection list of the given widget and stores the list
 * of NIDs.
 *
 * Returns the number of connections, or a negative error code.
 */
369
370
int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
			    hda_nid_t *conn_list, int max_conns)
371
372
{
	struct snd_array *array = &codec->conn_lists;
373
	int len;
374
	hda_nid_t *p;
375
	bool added = false;
376

377
 again:
378
379
	mutex_lock(&codec->hash_mutex);
	len = -1;
380
381
382
	/* if the connection-list is already cached, read it */
	p = lookup_conn_list(array, nid);
	if (p) {
383
384
385
386
387
388
389
390
391
392
		len = p[1];
		if (conn_list && len > max_conns) {
			snd_printk(KERN_ERR "hda_codec: "
				   "Too many connections %d for NID 0x%x\n",
				   len, nid);
			mutex_unlock(&codec->hash_mutex);
			return -EINVAL;
		}
		if (conn_list && len)
			memcpy(conn_list, p + 2, len * sizeof(hda_nid_t));
393
	}
394
395
396
	mutex_unlock(&codec->hash_mutex);
	if (len >= 0)
		return len;
397
398
	if (snd_BUG_ON(added))
		return -EINVAL;
399

400
	len = read_and_add_raw_conns(codec, nid);
401
402
	if (len < 0)
		return len;
403
404
	added = true;
	goto again;
405
406
407
}
EXPORT_SYMBOL_HDA(snd_hda_get_connections);

408
409
410
411
412
413
414
415
416
417
418
419
420
/**
 * snd_hda_get_raw_connections - copy connection list without cache
 * @codec: the HDA codec
 * @nid: NID to parse
 * @conn_list: connection list array
 * @max_conns: max. number of connections to store
 *
 * Like snd_hda_get_connections(), copy the connection list but without
 * checking through the connection-list cache.
 * Currently called only from hda_proc.c, so not exported.
 */
int snd_hda_get_raw_connections(struct hda_codec *codec, hda_nid_t nid,
				hda_nid_t *conn_list, int max_conns)
Linus Torvalds's avatar
Linus Torvalds committed
421
422
{
	unsigned int parm;
423
	int i, conn_len, conns;
Linus Torvalds's avatar
Linus Torvalds committed
424
	unsigned int shift, num_elems, mask;
425
	unsigned int wcaps;
426
	hda_nid_t prev_nid;
Linus Torvalds's avatar
Linus Torvalds committed
427

428
429
	if (snd_BUG_ON(!conn_list || max_conns <= 0))
		return -EINVAL;
Linus Torvalds's avatar
Linus Torvalds committed
430

431
432
	wcaps = get_wcaps(codec, nid);
	if (!(wcaps & AC_WCAP_CONN_LIST) &&
433
434
	    get_wcaps_type(wcaps) != AC_WID_VOL_KNB)
		return 0;
435

Linus Torvalds's avatar
Linus Torvalds committed
436
437
438
439
440
441
442
443
444
445
446
447
448
	parm = snd_hda_param_read(codec, nid, AC_PAR_CONNLIST_LEN);
	if (parm & AC_CLIST_LONG) {
		/* long form */
		shift = 16;
		num_elems = 2;
	} else {
		/* short form */
		shift = 8;
		num_elems = 4;
	}
	conn_len = parm & AC_CLIST_LENGTH;
	mask = (1 << (shift-1)) - 1;

449
	if (!conn_len)
Linus Torvalds's avatar
Linus Torvalds committed
450
451
452
453
		return 0; /* no connection */

	if (conn_len == 1) {
		/* single connection */
454
455
		parm = snd_hda_codec_read(codec, nid, 0,
					  AC_VERB_GET_CONNECT_LIST, 0);
456
457
		if (parm == -1 && codec->bus->rirb_error)
			return -EIO;
Linus Torvalds's avatar
Linus Torvalds committed
458
459
460
461
462
463
		conn_list[0] = parm & mask;
		return 1;
	}

	/* multi connection */
	conns = 0;
464
465
466
467
468
	prev_nid = 0;
	for (i = 0; i < conn_len; i++) {
		int range_val;
		hda_nid_t val, n;

469
		if (i % num_elems == 0) {
470
471
			parm = snd_hda_codec_read(codec, nid, 0,
						  AC_VERB_GET_CONNECT_LIST, i);
472
473
474
			if (parm == -1 && codec->bus->rirb_error)
				return -EIO;
		}
475
		range_val = !!(parm & (1 << (shift-1))); /* ranges */
476
		val = parm & mask;
477
478
479
480
481
482
		if (val == 0) {
			snd_printk(KERN_WARNING "hda_codec: "
				   "invalid CONNECT_LIST verb %x[%i]:%x\n",
				    nid, i, parm);
			return 0;
		}
483
484
485
		parm >>= shift;
		if (range_val) {
			/* ranges between the previous and this one */
486
487
488
489
			if (!prev_nid || prev_nid >= val) {
				snd_printk(KERN_WARNING "hda_codec: "
					   "invalid dep_range_val %x:%x\n",
					   prev_nid, val);
490
491
492
493
				continue;
			}
			for (n = prev_nid + 1; n <= val; n++) {
				if (conns >= max_conns) {
494
495
496
					snd_printk(KERN_ERR "hda_codec: "
						   "Too many connections %d for NID 0x%x\n",
						   conns, nid);
Linus Torvalds's avatar
Linus Torvalds committed
497
					return -EINVAL;
498
499
				}
				conn_list[conns++] = n;
Linus Torvalds's avatar
Linus Torvalds committed
500
			}
501
502
		} else {
			if (conns >= max_conns) {
503
504
505
				snd_printk(KERN_ERR "hda_codec: "
					   "Too many connections %d for NID 0x%x\n",
					   conns, nid);
506
507
508
				return -EINVAL;
			}
			conn_list[conns++] = val;
Linus Torvalds's avatar
Linus Torvalds committed
509
		}
510
		prev_nid = val;
Linus Torvalds's avatar
Linus Torvalds committed
511
512
513
514
	}
	return conns;
}

515
516
517
518
519
520
521
522
523
static bool add_conn_list(struct snd_array *array, hda_nid_t nid)
{
	hda_nid_t *p = snd_array_new(array);
	if (!p)
		return false;
	*p = nid;
	return true;
}

524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
/**
 * snd_hda_override_conn_list - add/modify the connection-list to cache
 * @codec: the HDA codec
 * @nid: NID to parse
 * @len: number of connection list entries
 * @list: the list of connection entries
 *
 * Add or modify the given connection-list to the cache.  If the corresponding
 * cache already exists, invalidate it and append a new one.
 *
 * Returns zero or a negative error code.
 */
int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len,
			       const hda_nid_t *list)
{
	struct snd_array *array = &codec->conn_lists;
	hda_nid_t *p;
	int i, old_used;

543
	mutex_lock(&codec->hash_mutex);
544
545
546
547
548
549
550
551
552
553
	p = lookup_conn_list(array, nid);
	if (p)
		*p = -1; /* invalidate the old entry */

	old_used = array->used;
	if (!add_conn_list(array, nid) || !add_conn_list(array, len))
		goto error_add;
	for (i = 0; i < len; i++)
		if (!add_conn_list(array, list[i]))
			goto error_add;
554
	mutex_unlock(&codec->hash_mutex);
555
556
557
558
	return 0;

 error_add:
	array->used = old_used;
559
	mutex_unlock(&codec->hash_mutex);
560
561
562
563
	return -ENOMEM;
}
EXPORT_SYMBOL_HDA(snd_hda_override_conn_list);

564
565
566
567
568
569
570
571
572
573
574
575
576
/**
 * snd_hda_get_conn_index - get the connection index of the given NID
 * @codec: the HDA codec
 * @mux: NID containing the list
 * @nid: NID to select
 * @recursive: 1 when searching NID recursively, otherwise 0
 *
 * Parses the connection list of the widget @mux and checks whether the
 * widget @nid is present.  If it is, return the connection index.
 * Otherwise it returns -1.
 */
int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
			   hda_nid_t nid, int recursive)
577
{
578
579
580
581
582
583
584
585
586
587
588
589
	hda_nid_t conn[HDA_MAX_NUM_INPUTS];
	int i, nums;

	nums = snd_hda_get_connections(codec, mux, conn, ARRAY_SIZE(conn));
	for (i = 0; i < nums; i++)
		if (conn[i] == nid)
			return i;
	if (!recursive)
		return -1;
	if (recursive > 5) {
		snd_printd("hda_codec: too deep connection for 0x%x\n", nid);
		return -1;
590
	}
591
	recursive++;
592
593
594
595
	for (i = 0; i < nums; i++) {
		unsigned int type = get_wcaps_type(get_wcaps(codec, conn[i]));
		if (type == AC_WID_PIN || type == AC_WID_AUD_OUT)
			continue;
596
597
		if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0)
			return i;
598
	}
599
	return -1;
600
}
601
EXPORT_SYMBOL_HDA(snd_hda_get_conn_index);
Linus Torvalds's avatar
Linus Torvalds committed
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619

/**
 * snd_hda_queue_unsol_event - add an unsolicited event to queue
 * @bus: the BUS
 * @res: unsolicited event (lower 32bit of RIRB entry)
 * @res_ex: codec addr and flags (upper 32bit or RIRB entry)
 *
 * Adds the given event to the queue.  The events are processed in
 * the workqueue asynchronously.  Call this function in the interrupt
 * hanlder when RIRB receives an unsolicited event.
 *
 * Returns 0 if successful, or a negative error code.
 */
int snd_hda_queue_unsol_event(struct hda_bus *bus, u32 res, u32 res_ex)
{
	struct hda_bus_unsolicited *unsol;
	unsigned int wp;

620
	trace_hda_unsol_event(bus, res, res_ex);
621
622
	unsol = bus->unsol;
	if (!unsol)
Linus Torvalds's avatar
Linus Torvalds committed
623
624
625
626
627
628
629
630
631
		return 0;

	wp = (unsol->wp + 1) % HDA_UNSOL_QUEUE_SIZE;
	unsol->wp = wp;

	wp <<= 1;
	unsol->queue[wp] = res;
	unsol->queue[wp + 1] = res_ex;

Takashi Iwai's avatar
Takashi Iwai committed
632
	queue_work(bus->workq, &unsol->work);
Linus Torvalds's avatar
Linus Torvalds committed
633
634
635

	return 0;
}
636
EXPORT_SYMBOL_HDA(snd_hda_queue_unsol_event);
Linus Torvalds's avatar
Linus Torvalds committed
637
638

/*
Wu Fengguang's avatar
Wu Fengguang committed
639
 * process queued unsolicited events
Linus Torvalds's avatar
Linus Torvalds committed
640
 */
David Howells's avatar
David Howells committed
641
static void process_unsol_events(struct work_struct *work)
Linus Torvalds's avatar
Linus Torvalds committed
642
{
David Howells's avatar
David Howells committed
643
644
645
	struct hda_bus_unsolicited *unsol =
		container_of(work, struct hda_bus_unsolicited, work);
	struct hda_bus *bus = unsol->bus;
Linus Torvalds's avatar
Linus Torvalds committed
646
647
648
649
650
651
652
653
654
	struct hda_codec *codec;
	unsigned int rp, caddr, res;

	while (unsol->rp != unsol->wp) {
		rp = (unsol->rp + 1) % HDA_UNSOL_QUEUE_SIZE;
		unsol->rp = rp;
		rp <<= 1;
		res = unsol->queue[rp];
		caddr = unsol->queue[rp + 1];
655
		if (!(caddr & (1 << 4))) /* no unsolicited event? */
Linus Torvalds's avatar
Linus Torvalds committed
656
657
658
659
660
661
662
663
664
665
			continue;
		codec = bus->caddr_tbl[caddr & 0x0f];
		if (codec && codec->patch_ops.unsol_event)
			codec->patch_ops.unsol_event(codec, res);
	}
}

/*
 * initialize unsolicited queue
 */
666
static int init_unsol_queue(struct hda_bus *bus)
Linus Torvalds's avatar
Linus Torvalds committed
667
668
669
{
	struct hda_bus_unsolicited *unsol;

670
671
672
	if (bus->unsol) /* already initialized */
		return 0;

673
	unsol = kzalloc(sizeof(*unsol), GFP_KERNEL);
674
675
676
	if (!unsol) {
		snd_printk(KERN_ERR "hda_codec: "
			   "can't allocate unsolicited queue\n");
Linus Torvalds's avatar
Linus Torvalds committed
677
678
		return -ENOMEM;
	}
David Howells's avatar
David Howells committed
679
680
	INIT_WORK(&unsol->work, process_unsol_events);
	unsol->bus = bus;
Linus Torvalds's avatar
Linus Torvalds committed
681
682
683
684
685
686
687
688
689
690
691
	bus->unsol = unsol;
	return 0;
}

/*
 * destructor
 */
static void snd_hda_codec_free(struct hda_codec *codec);

static int snd_hda_bus_free(struct hda_bus *bus)
{
692
	struct hda_codec *codec, *n;
Linus Torvalds's avatar
Linus Torvalds committed
693

694
	if (!bus)
Linus Torvalds's avatar
Linus Torvalds committed
695
		return 0;
Takashi Iwai's avatar
Takashi Iwai committed
696
697
698
	if (bus->workq)
		flush_workqueue(bus->workq);
	if (bus->unsol)
Linus Torvalds's avatar
Linus Torvalds committed
699
		kfree(bus->unsol);
700
	list_for_each_entry_safe(codec, n, &bus->codec_list, list) {
Linus Torvalds's avatar
Linus Torvalds committed
701
702
703
704
		snd_hda_codec_free(codec);
	}
	if (bus->ops.private_free)
		bus->ops.private_free(bus);
Takashi Iwai's avatar
Takashi Iwai committed
705
706
	if (bus->workq)
		destroy_workqueue(bus->workq);
Linus Torvalds's avatar
Linus Torvalds committed
707
708
709
710
	kfree(bus);
	return 0;
}

711
static int snd_hda_bus_dev_free(struct snd_device *device)
Linus Torvalds's avatar
Linus Torvalds committed
712
713
{
	struct hda_bus *bus = device->device_data;
714
	bus->shutdown = 1;
Linus Torvalds's avatar
Linus Torvalds committed
715
716
717
	return snd_hda_bus_free(bus);
}

718
719
720
721
722
723
724
#ifdef CONFIG_SND_HDA_HWDEP
static int snd_hda_bus_dev_register(struct snd_device *device)
{
	struct hda_bus *bus = device->device_data;
	struct hda_codec *codec;
	list_for_each_entry(codec, &bus->codec_list, list) {
		snd_hda_hwdep_add_sysfs(codec);
725
		snd_hda_hwdep_add_power_sysfs(codec);
726
727
728
729
730
731
732
	}
	return 0;
}
#else
#define snd_hda_bus_dev_register	NULL
#endif

Linus Torvalds's avatar
Linus Torvalds committed
733
734
735
736
737
738
739
740
/**
 * snd_hda_bus_new - create a HDA bus
 * @card: the card entry
 * @temp: the template for hda_bus information
 * @busp: the pointer to store the created bus instance
 *
 * Returns 0 if successful, or a negative error code.
 */
741
int snd_hda_bus_new(struct snd_card *card,
742
743
			      const struct hda_bus_template *temp,
			      struct hda_bus **busp)
Linus Torvalds's avatar
Linus Torvalds committed
744
745
746
{
	struct hda_bus *bus;
	int err;
747
	static struct snd_device_ops dev_ops = {
748
		.dev_register = snd_hda_bus_dev_register,
Linus Torvalds's avatar
Linus Torvalds committed
749
750
751
		.dev_free = snd_hda_bus_dev_free,
	};

752
753
754
755
	if (snd_BUG_ON(!temp))
		return -EINVAL;
	if (snd_BUG_ON(!temp->ops.command || !temp->ops.get_response))
		return -EINVAL;
Linus Torvalds's avatar
Linus Torvalds committed
756
757
758
759

	if (busp)
		*busp = NULL;

760
	bus = kzalloc(sizeof(*bus), GFP_KERNEL);
Linus Torvalds's avatar
Linus Torvalds committed
761
762
763
764
765
766
767
768
769
	if (bus == NULL) {
		snd_printk(KERN_ERR "can't allocate struct hda_bus\n");
		return -ENOMEM;
	}

	bus->card = card;
	bus->private_data = temp->private_data;
	bus->pci = temp->pci;
	bus->modelname = temp->modelname;
770
	bus->power_save = temp->power_save;
Linus Torvalds's avatar
Linus Torvalds committed
771
772
	bus->ops = temp->ops;

773
	mutex_init(&bus->cmd_mutex);
774
	mutex_init(&bus->prepare_mutex);
Linus Torvalds's avatar
Linus Torvalds committed
775
776
	INIT_LIST_HEAD(&bus->codec_list);

777
778
779
	snprintf(bus->workq_name, sizeof(bus->workq_name),
		 "hd-audio%d", card->number);
	bus->workq = create_singlethread_workqueue(bus->workq_name);
Takashi Iwai's avatar
Takashi Iwai committed
780
	if (!bus->workq) {
781
782
		snd_printk(KERN_ERR "cannot create workqueue %s\n",
			   bus->workq_name);
Takashi Iwai's avatar
Takashi Iwai committed
783
784
785
786
		kfree(bus);
		return -ENOMEM;
	}

787
788
	err = snd_device_new(card, SNDRV_DEV_BUS, bus, &dev_ops);
	if (err < 0) {
Linus Torvalds's avatar
Linus Torvalds committed
789
790
791
792
793
794
795
		snd_hda_bus_free(bus);
		return err;
	}
	if (busp)
		*busp = bus;
	return 0;
}
796
EXPORT_SYMBOL_HDA(snd_hda_bus_new);
Linus Torvalds's avatar
Linus Torvalds committed
797

798
799
#ifdef CONFIG_SND_HDA_GENERIC
#define is_generic_config(codec) \
800
	(codec->modelname && !strcmp(codec->modelname, "generic"))
801
802
803
804
#else
#define is_generic_config(codec)	0
#endif

805
#ifdef MODULE
806
807
#define HDA_MODREQ_MAX_COUNT	2	/* two request_modules()'s */
#else
808
#define HDA_MODREQ_MAX_COUNT	0	/* all presets are statically linked */
809
810
#endif

Linus Torvalds's avatar
Linus Torvalds committed
811
812
813
/*
 * find a matching codec preset
 */
814
static const struct hda_codec_preset *
815
find_codec_preset(struct hda_codec *codec)
Linus Torvalds's avatar
Linus Torvalds committed
816
{
817
818
	struct hda_codec_preset_list *tbl;
	const struct hda_codec_preset *preset;
819
	unsigned int mod_requested = 0;
Linus Torvalds's avatar
Linus Torvalds committed
820

821
	if (is_generic_config(codec))
822
823
		return NULL; /* use the generic parser */

824
825
826
827
828
829
830
831
 again:
	mutex_lock(&preset_mutex);
	list_for_each_entry(tbl, &hda_preset_tables, list) {
		if (!try_module_get(tbl->owner)) {
			snd_printk(KERN_ERR "hda_codec: cannot module_get\n");
			continue;
		}
		for (preset = tbl->preset; preset->id; preset++) {
Linus Torvalds's avatar
Linus Torvalds committed
832
			u32 mask = preset->mask;
833
834
835
836
			if (preset->afg && preset->afg != codec->afg)
				continue;
			if (preset->mfg && preset->mfg != codec->mfg)
				continue;
837
			if (!mask)
Linus Torvalds's avatar
Linus Torvalds committed
838
				mask = ~0;
839
			if (preset->id == (codec->vendor_id & mask) &&
840
			    (!preset->rev ||
841
842
843
			     preset->rev == codec->revision_id)) {
				mutex_unlock(&preset_mutex);
				codec->owner = tbl->owner;
Linus Torvalds's avatar
Linus Torvalds committed
844
				return preset;
845
			}
Linus Torvalds's avatar
Linus Torvalds committed
846
		}
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
		module_put(tbl->owner);
	}
	mutex_unlock(&preset_mutex);

	if (mod_requested < HDA_MODREQ_MAX_COUNT) {
		char name[32];
		if (!mod_requested)
			snprintf(name, sizeof(name), "snd-hda-codec-id:%08x",
				 codec->vendor_id);
		else
			snprintf(name, sizeof(name), "snd-hda-codec-id:%04x*",
				 (codec->vendor_id >> 16) & 0xffff);
		request_module(name);
		mod_requested++;
		goto again;
Linus Torvalds's avatar
Linus Torvalds committed
862
863
864
865
866
	}
	return NULL;
}

/*
867
 * get_codec_name - store the codec name
Linus Torvalds's avatar
Linus Torvalds committed
868
 */
869
static int get_codec_name(struct hda_codec *codec)
Linus Torvalds's avatar
Linus Torvalds committed
870
871
872
873
{
	const struct hda_vendor_id *c;
	const char *vendor = NULL;
	u16 vendor_id = codec->vendor_id >> 16;
874
875
876
877
	char tmp[16];

	if (codec->vendor_name)
		goto get_chip_name;
Linus Torvalds's avatar
Linus Torvalds committed
878
879
880
881
882
883
884

	for (c = hda_vendor_ids; c->id; c++) {
		if (c->id == vendor_id) {
			vendor = c->name;
			break;
		}
	}
885
	if (!vendor) {
Linus Torvalds's avatar
Linus Torvalds committed
886
887
888
		sprintf(tmp, "Generic %04x", vendor_id);
		vendor = tmp;
	}
889
890
891
892
893
894
895
896
	codec->vendor_name = kstrdup(vendor, GFP_KERNEL);
	if (!codec->vendor_name)
		return -ENOMEM;

 get_chip_name:
	if (codec->chip_name)
		return 0;

Linus Torvalds's avatar
Linus Torvalds committed
897
	if (codec->preset && codec->preset->name)
898
899
900
901
902
903
		codec->chip_name = kstrdup(codec->preset->name, GFP_KERNEL);
	else {
		sprintf(tmp, "ID %x", codec->vendor_id & 0xffff);
		codec->chip_name = kstrdup(tmp, GFP_KERNEL);
	}
	if (!codec->chip_name)
904
905
		return -ENOMEM;
	return 0;
Linus Torvalds's avatar
Linus Torvalds committed
906
907
908
}

/*
Sasha Khapyorsky's avatar
Sasha Khapyorsky committed
909
 * look for an AFG and MFG nodes
Linus Torvalds's avatar
Linus Torvalds committed
910
 */
911
static void setup_fg_nodes(struct hda_codec *codec)
Linus Torvalds's avatar
Linus Torvalds committed
912
{
913
	int i, total_nodes, function_id;
Linus Torvalds's avatar
Linus Torvalds committed
914
915
916
917
	hda_nid_t nid;

	total_nodes = snd_hda_get_sub_nodes(codec, AC_NODE_ROOT, &nid);
	for (i = 0; i < total_nodes; i++, nid++) {
918
		function_id = snd_hda_param_read(codec, nid,
919
						AC_PAR_FUNCTION_TYPE);
920
		switch (function_id & 0xff) {
Sasha Khapyorsky's avatar
Sasha Khapyorsky committed
921
922
		case AC_GRP_AUDIO_FUNCTION:
			codec->afg = nid;
923
924
			codec->afg_function_id = function_id & 0xff;
			codec->afg_unsol = (function_id >> 8) & 1;
Sasha Khapyorsky's avatar
Sasha Khapyorsky committed
925
926
927
			break;
		case AC_GRP_MODEM_FUNCTION:
			codec->mfg = nid;
928
929
			codec->mfg_function_id = function_id & 0xff;
			codec->mfg_unsol = (function_id >> 8) & 1;
Sasha Khapyorsky's avatar
Sasha Khapyorsky committed
930
931
932
933
			break;
		default:
			break;
		}
Linus Torvalds's avatar
Linus Torvalds committed
934
935
936
	}
}

937
938
939
940
941
942
943
944
945
946
947
/*
 * read widget caps for each widget and store in cache
 */
static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
{
	int i;
	hda_nid_t nid;

	codec->num_nodes = snd_hda_get_sub_nodes(codec, fg_node,
						 &codec->start_nid);
	codec->wcaps = kmalloc(codec->num_nodes * 4, GFP_KERNEL);
948
	if (!codec->wcaps)
949
950
951
952
953
954
955
956
		return -ENOMEM;
	nid = codec->start_nid;
	for (i = 0; i < codec->num_nodes; i++, nid++)
		codec->wcaps[i] = snd_hda_param_read(codec, nid,
						     AC_PAR_AUDIO_WIDGET_CAP);
	return 0;
}

957
958
959
960
961
962
963
964
965
/* read all pin default configurations and save codec->init_pins */
static int read_pin_defaults(struct hda_codec *codec)
{
	int i;
	hda_nid_t nid = codec->start_nid;

	for (i = 0; i < codec->num_nodes; i++, nid++) {
		struct hda_pincfg *pin;
		unsigned int wcaps = get_wcaps(codec, nid);
966
		unsigned int wid_type = get_wcaps_type(wcaps);
967
968
969
970
971
972
973
974
		if (wid_type != AC_WID_PIN)
			continue;
		pin = snd_array_new(&codec->init_pins);
		if (!pin)
			return -ENOMEM;
		pin->nid = nid;
		pin->cfg = snd_hda_codec_read(codec, nid, 0,
					      AC_VERB_GET_CONFIG_DEFAULT, 0);
975
976
977
		pin->ctrl = snd_hda_codec_read(codec, nid, 0,
					       AC_VERB_GET_PIN_WIDGET_CONTROL,
					       0);
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
	}
	return 0;
}

/* look up the given pin config list and return the item matching with NID */
static struct hda_pincfg *look_up_pincfg(struct hda_codec *codec,
					 struct snd_array *array,
					 hda_nid_t nid)
{
	int i;
	for (i = 0; i < array->used; i++) {
		struct hda_pincfg *pin = snd_array_elem(array, i);
		if (pin->nid == nid)
			return pin;
	}
	return NULL;
}

/* set the current pin config value for the given NID.
 * the value is cached, and read via snd_hda_codec_get_pincfg()
 */
int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
		       hda_nid_t nid, unsigned int cfg)