xref: /OK3568_Linux_fs/kernel/sound/pci/hda/hda_codec.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0-or-later
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun  * Universal Interface for Intel High Definition Audio Codec
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
6*4882a593Smuzhiyun  */
7*4882a593Smuzhiyun 
8*4882a593Smuzhiyun #include <linux/init.h>
9*4882a593Smuzhiyun #include <linux/delay.h>
10*4882a593Smuzhiyun #include <linux/slab.h>
11*4882a593Smuzhiyun #include <linux/mutex.h>
12*4882a593Smuzhiyun #include <linux/module.h>
13*4882a593Smuzhiyun #include <linux/pm.h>
14*4882a593Smuzhiyun #include <linux/pm_runtime.h>
15*4882a593Smuzhiyun #include <sound/core.h>
16*4882a593Smuzhiyun #include <sound/hda_codec.h>
17*4882a593Smuzhiyun #include <sound/asoundef.h>
18*4882a593Smuzhiyun #include <sound/tlv.h>
19*4882a593Smuzhiyun #include <sound/initval.h>
20*4882a593Smuzhiyun #include <sound/jack.h>
21*4882a593Smuzhiyun #include "hda_local.h"
22*4882a593Smuzhiyun #include "hda_beep.h"
23*4882a593Smuzhiyun #include "hda_jack.h"
24*4882a593Smuzhiyun #include <sound/hda_hwdep.h>
25*4882a593Smuzhiyun #include <sound/hda_component.h>
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun #define codec_in_pm(codec)		snd_hdac_is_in_pm(&codec->core)
28*4882a593Smuzhiyun #define hda_codec_is_power_on(codec)	snd_hdac_is_power_on(&codec->core)
29*4882a593Smuzhiyun #define codec_has_epss(codec) \
30*4882a593Smuzhiyun 	((codec)->core.power_caps & AC_PWRST_EPSS)
31*4882a593Smuzhiyun #define codec_has_clkstop(codec) \
32*4882a593Smuzhiyun 	((codec)->core.power_caps & AC_PWRST_CLKSTOP)
33*4882a593Smuzhiyun 
34*4882a593Smuzhiyun /*
35*4882a593Smuzhiyun  * Send and receive a verb - passed to exec_verb override for hdac_device
36*4882a593Smuzhiyun  */
codec_exec_verb(struct hdac_device * dev,unsigned int cmd,unsigned int flags,unsigned int * res)37*4882a593Smuzhiyun static int codec_exec_verb(struct hdac_device *dev, unsigned int cmd,
38*4882a593Smuzhiyun 			   unsigned int flags, unsigned int *res)
39*4882a593Smuzhiyun {
40*4882a593Smuzhiyun 	struct hda_codec *codec = container_of(dev, struct hda_codec, core);
41*4882a593Smuzhiyun 	struct hda_bus *bus = codec->bus;
42*4882a593Smuzhiyun 	int err;
43*4882a593Smuzhiyun 
44*4882a593Smuzhiyun 	if (cmd == ~0)
45*4882a593Smuzhiyun 		return -1;
46*4882a593Smuzhiyun 
47*4882a593Smuzhiyun  again:
48*4882a593Smuzhiyun 	snd_hda_power_up_pm(codec);
49*4882a593Smuzhiyun 	mutex_lock(&bus->core.cmd_mutex);
50*4882a593Smuzhiyun 	if (flags & HDA_RW_NO_RESPONSE_FALLBACK)
51*4882a593Smuzhiyun 		bus->no_response_fallback = 1;
52*4882a593Smuzhiyun 	err = snd_hdac_bus_exec_verb_unlocked(&bus->core, codec->core.addr,
53*4882a593Smuzhiyun 					      cmd, res);
54*4882a593Smuzhiyun 	bus->no_response_fallback = 0;
55*4882a593Smuzhiyun 	mutex_unlock(&bus->core.cmd_mutex);
56*4882a593Smuzhiyun 	snd_hda_power_down_pm(codec);
57*4882a593Smuzhiyun 	if (!codec_in_pm(codec) && res && err == -EAGAIN) {
58*4882a593Smuzhiyun 		if (bus->response_reset) {
59*4882a593Smuzhiyun 			codec_dbg(codec,
60*4882a593Smuzhiyun 				  "resetting BUS due to fatal communication error\n");
61*4882a593Smuzhiyun 			snd_hda_bus_reset(bus);
62*4882a593Smuzhiyun 		}
63*4882a593Smuzhiyun 		goto again;
64*4882a593Smuzhiyun 	}
65*4882a593Smuzhiyun 	/* clear reset-flag when the communication gets recovered */
66*4882a593Smuzhiyun 	if (!err || codec_in_pm(codec))
67*4882a593Smuzhiyun 		bus->response_reset = 0;
68*4882a593Smuzhiyun 	return err;
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
71*4882a593Smuzhiyun /**
72*4882a593Smuzhiyun  * snd_hda_sequence_write - sequence writes
73*4882a593Smuzhiyun  * @codec: the HDA codec
74*4882a593Smuzhiyun  * @seq: VERB array to send
75*4882a593Smuzhiyun  *
76*4882a593Smuzhiyun  * Send the commands sequentially from the given array.
77*4882a593Smuzhiyun  * The array must be terminated with NID=0.
78*4882a593Smuzhiyun  */
snd_hda_sequence_write(struct hda_codec * codec,const struct hda_verb * seq)79*4882a593Smuzhiyun void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
80*4882a593Smuzhiyun {
81*4882a593Smuzhiyun 	for (; seq->nid; seq++)
82*4882a593Smuzhiyun 		snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
83*4882a593Smuzhiyun }
84*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_sequence_write);
85*4882a593Smuzhiyun 
86*4882a593Smuzhiyun /* connection list element */
87*4882a593Smuzhiyun struct hda_conn_list {
88*4882a593Smuzhiyun 	struct list_head list;
89*4882a593Smuzhiyun 	int len;
90*4882a593Smuzhiyun 	hda_nid_t nid;
91*4882a593Smuzhiyun 	hda_nid_t conns[];
92*4882a593Smuzhiyun };
93*4882a593Smuzhiyun 
94*4882a593Smuzhiyun /* look up the cached results */
95*4882a593Smuzhiyun static struct hda_conn_list *
lookup_conn_list(struct hda_codec * codec,hda_nid_t nid)96*4882a593Smuzhiyun lookup_conn_list(struct hda_codec *codec, hda_nid_t nid)
97*4882a593Smuzhiyun {
98*4882a593Smuzhiyun 	struct hda_conn_list *p;
99*4882a593Smuzhiyun 	list_for_each_entry(p, &codec->conn_list, list) {
100*4882a593Smuzhiyun 		if (p->nid == nid)
101*4882a593Smuzhiyun 			return p;
102*4882a593Smuzhiyun 	}
103*4882a593Smuzhiyun 	return NULL;
104*4882a593Smuzhiyun }
105*4882a593Smuzhiyun 
add_conn_list(struct hda_codec * codec,hda_nid_t nid,int len,const hda_nid_t * list)106*4882a593Smuzhiyun static int add_conn_list(struct hda_codec *codec, hda_nid_t nid, int len,
107*4882a593Smuzhiyun 			 const hda_nid_t *list)
108*4882a593Smuzhiyun {
109*4882a593Smuzhiyun 	struct hda_conn_list *p;
110*4882a593Smuzhiyun 
111*4882a593Smuzhiyun 	p = kmalloc(struct_size(p, conns, len), GFP_KERNEL);
112*4882a593Smuzhiyun 	if (!p)
113*4882a593Smuzhiyun 		return -ENOMEM;
114*4882a593Smuzhiyun 	p->len = len;
115*4882a593Smuzhiyun 	p->nid = nid;
116*4882a593Smuzhiyun 	memcpy(p->conns, list, len * sizeof(hda_nid_t));
117*4882a593Smuzhiyun 	list_add(&p->list, &codec->conn_list);
118*4882a593Smuzhiyun 	return 0;
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun 
remove_conn_list(struct hda_codec * codec)121*4882a593Smuzhiyun static void remove_conn_list(struct hda_codec *codec)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun 	while (!list_empty(&codec->conn_list)) {
124*4882a593Smuzhiyun 		struct hda_conn_list *p;
125*4882a593Smuzhiyun 		p = list_first_entry(&codec->conn_list, typeof(*p), list);
126*4882a593Smuzhiyun 		list_del(&p->list);
127*4882a593Smuzhiyun 		kfree(p);
128*4882a593Smuzhiyun 	}
129*4882a593Smuzhiyun }
130*4882a593Smuzhiyun 
131*4882a593Smuzhiyun /* read the connection and add to the cache */
read_and_add_raw_conns(struct hda_codec * codec,hda_nid_t nid)132*4882a593Smuzhiyun static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid)
133*4882a593Smuzhiyun {
134*4882a593Smuzhiyun 	hda_nid_t list[32];
135*4882a593Smuzhiyun 	hda_nid_t *result = list;
136*4882a593Smuzhiyun 	int len;
137*4882a593Smuzhiyun 
138*4882a593Smuzhiyun 	len = snd_hda_get_raw_connections(codec, nid, list, ARRAY_SIZE(list));
139*4882a593Smuzhiyun 	if (len == -ENOSPC) {
140*4882a593Smuzhiyun 		len = snd_hda_get_num_raw_conns(codec, nid);
141*4882a593Smuzhiyun 		result = kmalloc_array(len, sizeof(hda_nid_t), GFP_KERNEL);
142*4882a593Smuzhiyun 		if (!result)
143*4882a593Smuzhiyun 			return -ENOMEM;
144*4882a593Smuzhiyun 		len = snd_hda_get_raw_connections(codec, nid, result, len);
145*4882a593Smuzhiyun 	}
146*4882a593Smuzhiyun 	if (len >= 0)
147*4882a593Smuzhiyun 		len = snd_hda_override_conn_list(codec, nid, len, result);
148*4882a593Smuzhiyun 	if (result != list)
149*4882a593Smuzhiyun 		kfree(result);
150*4882a593Smuzhiyun 	return len;
151*4882a593Smuzhiyun }
152*4882a593Smuzhiyun 
153*4882a593Smuzhiyun /**
154*4882a593Smuzhiyun  * snd_hda_get_conn_list - get connection list
155*4882a593Smuzhiyun  * @codec: the HDA codec
156*4882a593Smuzhiyun  * @nid: NID to parse
157*4882a593Smuzhiyun  * @listp: the pointer to store NID list
158*4882a593Smuzhiyun  *
159*4882a593Smuzhiyun  * Parses the connection list of the given widget and stores the pointer
160*4882a593Smuzhiyun  * to the list of NIDs.
161*4882a593Smuzhiyun  *
162*4882a593Smuzhiyun  * Returns the number of connections, or a negative error code.
163*4882a593Smuzhiyun  *
164*4882a593Smuzhiyun  * Note that the returned pointer isn't protected against the list
165*4882a593Smuzhiyun  * modification.  If snd_hda_override_conn_list() might be called
166*4882a593Smuzhiyun  * concurrently, protect with a mutex appropriately.
167*4882a593Smuzhiyun  */
snd_hda_get_conn_list(struct hda_codec * codec,hda_nid_t nid,const hda_nid_t ** listp)168*4882a593Smuzhiyun int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
169*4882a593Smuzhiyun 			  const hda_nid_t **listp)
170*4882a593Smuzhiyun {
171*4882a593Smuzhiyun 	bool added = false;
172*4882a593Smuzhiyun 
173*4882a593Smuzhiyun 	for (;;) {
174*4882a593Smuzhiyun 		int err;
175*4882a593Smuzhiyun 		const struct hda_conn_list *p;
176*4882a593Smuzhiyun 
177*4882a593Smuzhiyun 		/* if the connection-list is already cached, read it */
178*4882a593Smuzhiyun 		p = lookup_conn_list(codec, nid);
179*4882a593Smuzhiyun 		if (p) {
180*4882a593Smuzhiyun 			if (listp)
181*4882a593Smuzhiyun 				*listp = p->conns;
182*4882a593Smuzhiyun 			return p->len;
183*4882a593Smuzhiyun 		}
184*4882a593Smuzhiyun 		if (snd_BUG_ON(added))
185*4882a593Smuzhiyun 			return -EINVAL;
186*4882a593Smuzhiyun 
187*4882a593Smuzhiyun 		err = read_and_add_raw_conns(codec, nid);
188*4882a593Smuzhiyun 		if (err < 0)
189*4882a593Smuzhiyun 			return err;
190*4882a593Smuzhiyun 		added = true;
191*4882a593Smuzhiyun 	}
192*4882a593Smuzhiyun }
193*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_get_conn_list);
194*4882a593Smuzhiyun 
195*4882a593Smuzhiyun /**
196*4882a593Smuzhiyun  * snd_hda_get_connections - copy connection list
197*4882a593Smuzhiyun  * @codec: the HDA codec
198*4882a593Smuzhiyun  * @nid: NID to parse
199*4882a593Smuzhiyun  * @conn_list: connection list array; when NULL, checks only the size
200*4882a593Smuzhiyun  * @max_conns: max. number of connections to store
201*4882a593Smuzhiyun  *
202*4882a593Smuzhiyun  * Parses the connection list of the given widget and stores the list
203*4882a593Smuzhiyun  * of NIDs.
204*4882a593Smuzhiyun  *
205*4882a593Smuzhiyun  * Returns the number of connections, or a negative error code.
206*4882a593Smuzhiyun  */
snd_hda_get_connections(struct hda_codec * codec,hda_nid_t nid,hda_nid_t * conn_list,int max_conns)207*4882a593Smuzhiyun int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
208*4882a593Smuzhiyun 			    hda_nid_t *conn_list, int max_conns)
209*4882a593Smuzhiyun {
210*4882a593Smuzhiyun 	const hda_nid_t *list;
211*4882a593Smuzhiyun 	int len = snd_hda_get_conn_list(codec, nid, &list);
212*4882a593Smuzhiyun 
213*4882a593Smuzhiyun 	if (len > 0 && conn_list) {
214*4882a593Smuzhiyun 		if (len > max_conns) {
215*4882a593Smuzhiyun 			codec_err(codec, "Too many connections %d for NID 0x%x\n",
216*4882a593Smuzhiyun 				   len, nid);
217*4882a593Smuzhiyun 			return -EINVAL;
218*4882a593Smuzhiyun 		}
219*4882a593Smuzhiyun 		memcpy(conn_list, list, len * sizeof(hda_nid_t));
220*4882a593Smuzhiyun 	}
221*4882a593Smuzhiyun 
222*4882a593Smuzhiyun 	return len;
223*4882a593Smuzhiyun }
224*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_get_connections);
225*4882a593Smuzhiyun 
226*4882a593Smuzhiyun /**
227*4882a593Smuzhiyun  * snd_hda_override_conn_list - add/modify the connection-list to cache
228*4882a593Smuzhiyun  * @codec: the HDA codec
229*4882a593Smuzhiyun  * @nid: NID to parse
230*4882a593Smuzhiyun  * @len: number of connection list entries
231*4882a593Smuzhiyun  * @list: the list of connection entries
232*4882a593Smuzhiyun  *
233*4882a593Smuzhiyun  * Add or modify the given connection-list to the cache.  If the corresponding
234*4882a593Smuzhiyun  * cache already exists, invalidate it and append a new one.
235*4882a593Smuzhiyun  *
236*4882a593Smuzhiyun  * Returns zero or a negative error code.
237*4882a593Smuzhiyun  */
snd_hda_override_conn_list(struct hda_codec * codec,hda_nid_t nid,int len,const hda_nid_t * list)238*4882a593Smuzhiyun int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len,
239*4882a593Smuzhiyun 			       const hda_nid_t *list)
240*4882a593Smuzhiyun {
241*4882a593Smuzhiyun 	struct hda_conn_list *p;
242*4882a593Smuzhiyun 
243*4882a593Smuzhiyun 	p = lookup_conn_list(codec, nid);
244*4882a593Smuzhiyun 	if (p) {
245*4882a593Smuzhiyun 		list_del(&p->list);
246*4882a593Smuzhiyun 		kfree(p);
247*4882a593Smuzhiyun 	}
248*4882a593Smuzhiyun 
249*4882a593Smuzhiyun 	return add_conn_list(codec, nid, len, list);
250*4882a593Smuzhiyun }
251*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_override_conn_list);
252*4882a593Smuzhiyun 
253*4882a593Smuzhiyun /**
254*4882a593Smuzhiyun  * snd_hda_get_conn_index - get the connection index of the given NID
255*4882a593Smuzhiyun  * @codec: the HDA codec
256*4882a593Smuzhiyun  * @mux: NID containing the list
257*4882a593Smuzhiyun  * @nid: NID to select
258*4882a593Smuzhiyun  * @recursive: 1 when searching NID recursively, otherwise 0
259*4882a593Smuzhiyun  *
260*4882a593Smuzhiyun  * Parses the connection list of the widget @mux and checks whether the
261*4882a593Smuzhiyun  * widget @nid is present.  If it is, return the connection index.
262*4882a593Smuzhiyun  * Otherwise it returns -1.
263*4882a593Smuzhiyun  */
snd_hda_get_conn_index(struct hda_codec * codec,hda_nid_t mux,hda_nid_t nid,int recursive)264*4882a593Smuzhiyun int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
265*4882a593Smuzhiyun 			   hda_nid_t nid, int recursive)
266*4882a593Smuzhiyun {
267*4882a593Smuzhiyun 	const hda_nid_t *conn;
268*4882a593Smuzhiyun 	int i, nums;
269*4882a593Smuzhiyun 
270*4882a593Smuzhiyun 	nums = snd_hda_get_conn_list(codec, mux, &conn);
271*4882a593Smuzhiyun 	for (i = 0; i < nums; i++)
272*4882a593Smuzhiyun 		if (conn[i] == nid)
273*4882a593Smuzhiyun 			return i;
274*4882a593Smuzhiyun 	if (!recursive)
275*4882a593Smuzhiyun 		return -1;
276*4882a593Smuzhiyun 	if (recursive > 10) {
277*4882a593Smuzhiyun 		codec_dbg(codec, "too deep connection for 0x%x\n", nid);
278*4882a593Smuzhiyun 		return -1;
279*4882a593Smuzhiyun 	}
280*4882a593Smuzhiyun 	recursive++;
281*4882a593Smuzhiyun 	for (i = 0; i < nums; i++) {
282*4882a593Smuzhiyun 		unsigned int type = get_wcaps_type(get_wcaps(codec, conn[i]));
283*4882a593Smuzhiyun 		if (type == AC_WID_PIN || type == AC_WID_AUD_OUT)
284*4882a593Smuzhiyun 			continue;
285*4882a593Smuzhiyun 		if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0)
286*4882a593Smuzhiyun 			return i;
287*4882a593Smuzhiyun 	}
288*4882a593Smuzhiyun 	return -1;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_get_conn_index);
291*4882a593Smuzhiyun 
292*4882a593Smuzhiyun /**
293*4882a593Smuzhiyun  * snd_hda_get_num_devices - get DEVLIST_LEN parameter of the given widget
294*4882a593Smuzhiyun  *  @codec: the HDA codec
295*4882a593Smuzhiyun  *  @nid: NID of the pin to parse
296*4882a593Smuzhiyun  *
297*4882a593Smuzhiyun  * Get the device entry number on the given widget. This is a feature of
298*4882a593Smuzhiyun  * DP MST audio. Each pin can have several device entries in it.
299*4882a593Smuzhiyun  */
snd_hda_get_num_devices(struct hda_codec * codec,hda_nid_t nid)300*4882a593Smuzhiyun unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid)
301*4882a593Smuzhiyun {
302*4882a593Smuzhiyun 	unsigned int wcaps = get_wcaps(codec, nid);
303*4882a593Smuzhiyun 	unsigned int parm;
304*4882a593Smuzhiyun 
305*4882a593Smuzhiyun 	if (!codec->dp_mst || !(wcaps & AC_WCAP_DIGITAL) ||
306*4882a593Smuzhiyun 	    get_wcaps_type(wcaps) != AC_WID_PIN)
307*4882a593Smuzhiyun 		return 0;
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	parm = snd_hdac_read_parm_uncached(&codec->core, nid, AC_PAR_DEVLIST_LEN);
310*4882a593Smuzhiyun 	if (parm == -1)
311*4882a593Smuzhiyun 		parm = 0;
312*4882a593Smuzhiyun 	return parm & AC_DEV_LIST_LEN_MASK;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_get_num_devices);
315*4882a593Smuzhiyun 
316*4882a593Smuzhiyun /**
317*4882a593Smuzhiyun  * snd_hda_get_devices - copy device list without cache
318*4882a593Smuzhiyun  * @codec: the HDA codec
319*4882a593Smuzhiyun  * @nid: NID of the pin to parse
320*4882a593Smuzhiyun  * @dev_list: device list array
321*4882a593Smuzhiyun  * @max_devices: max. number of devices to store
322*4882a593Smuzhiyun  *
323*4882a593Smuzhiyun  * Copy the device list. This info is dynamic and so not cached.
324*4882a593Smuzhiyun  * Currently called only from hda_proc.c, so not exported.
325*4882a593Smuzhiyun  */
snd_hda_get_devices(struct hda_codec * codec,hda_nid_t nid,u8 * dev_list,int max_devices)326*4882a593Smuzhiyun int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
327*4882a593Smuzhiyun 			u8 *dev_list, int max_devices)
328*4882a593Smuzhiyun {
329*4882a593Smuzhiyun 	unsigned int parm;
330*4882a593Smuzhiyun 	int i, dev_len, devices;
331*4882a593Smuzhiyun 
332*4882a593Smuzhiyun 	parm = snd_hda_get_num_devices(codec, nid);
333*4882a593Smuzhiyun 	if (!parm)	/* not multi-stream capable */
334*4882a593Smuzhiyun 		return 0;
335*4882a593Smuzhiyun 
336*4882a593Smuzhiyun 	dev_len = parm + 1;
337*4882a593Smuzhiyun 	dev_len = dev_len < max_devices ? dev_len : max_devices;
338*4882a593Smuzhiyun 
339*4882a593Smuzhiyun 	devices = 0;
340*4882a593Smuzhiyun 	while (devices < dev_len) {
341*4882a593Smuzhiyun 		if (snd_hdac_read(&codec->core, nid,
342*4882a593Smuzhiyun 				  AC_VERB_GET_DEVICE_LIST, devices, &parm))
343*4882a593Smuzhiyun 			break; /* error */
344*4882a593Smuzhiyun 
345*4882a593Smuzhiyun 		for (i = 0; i < 8; i++) {
346*4882a593Smuzhiyun 			dev_list[devices] = (u8)parm;
347*4882a593Smuzhiyun 			parm >>= 4;
348*4882a593Smuzhiyun 			devices++;
349*4882a593Smuzhiyun 			if (devices >= dev_len)
350*4882a593Smuzhiyun 				break;
351*4882a593Smuzhiyun 		}
352*4882a593Smuzhiyun 	}
353*4882a593Smuzhiyun 	return devices;
354*4882a593Smuzhiyun }
355*4882a593Smuzhiyun 
356*4882a593Smuzhiyun /**
357*4882a593Smuzhiyun  * snd_hda_get_dev_select - get device entry select on the pin
358*4882a593Smuzhiyun  * @codec: the HDA codec
359*4882a593Smuzhiyun  * @nid: NID of the pin to get device entry select
360*4882a593Smuzhiyun  *
361*4882a593Smuzhiyun  * Get the devcie entry select on the pin. Return the device entry
362*4882a593Smuzhiyun  * id selected on the pin. Return 0 means the first device entry
363*4882a593Smuzhiyun  * is selected or MST is not supported.
364*4882a593Smuzhiyun  */
snd_hda_get_dev_select(struct hda_codec * codec,hda_nid_t nid)365*4882a593Smuzhiyun int snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid)
366*4882a593Smuzhiyun {
367*4882a593Smuzhiyun 	/* not support dp_mst will always return 0, using first dev_entry */
368*4882a593Smuzhiyun 	if (!codec->dp_mst)
369*4882a593Smuzhiyun 		return 0;
370*4882a593Smuzhiyun 
371*4882a593Smuzhiyun 	return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DEVICE_SEL, 0);
372*4882a593Smuzhiyun }
373*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_get_dev_select);
374*4882a593Smuzhiyun 
375*4882a593Smuzhiyun /**
376*4882a593Smuzhiyun  * snd_hda_set_dev_select - set device entry select on the pin
377*4882a593Smuzhiyun  * @codec: the HDA codec
378*4882a593Smuzhiyun  * @nid: NID of the pin to set device entry select
379*4882a593Smuzhiyun  * @dev_id: device entry id to be set
380*4882a593Smuzhiyun  *
381*4882a593Smuzhiyun  * Set the device entry select on the pin nid.
382*4882a593Smuzhiyun  */
snd_hda_set_dev_select(struct hda_codec * codec,hda_nid_t nid,int dev_id)383*4882a593Smuzhiyun int snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id)
384*4882a593Smuzhiyun {
385*4882a593Smuzhiyun 	int ret, num_devices;
386*4882a593Smuzhiyun 
387*4882a593Smuzhiyun 	/* not support dp_mst will always return 0, using first dev_entry */
388*4882a593Smuzhiyun 	if (!codec->dp_mst)
389*4882a593Smuzhiyun 		return 0;
390*4882a593Smuzhiyun 
391*4882a593Smuzhiyun 	/* AC_PAR_DEVLIST_LEN is 0 based. */
392*4882a593Smuzhiyun 	num_devices = snd_hda_get_num_devices(codec, nid) + 1;
393*4882a593Smuzhiyun 	/* If Device List Length is 0 (num_device = 1),
394*4882a593Smuzhiyun 	 * the pin is not multi stream capable.
395*4882a593Smuzhiyun 	 * Do nothing in this case.
396*4882a593Smuzhiyun 	 */
397*4882a593Smuzhiyun 	if (num_devices == 1)
398*4882a593Smuzhiyun 		return 0;
399*4882a593Smuzhiyun 
400*4882a593Smuzhiyun 	/* Behavior of setting index being equal to or greater than
401*4882a593Smuzhiyun 	 * Device List Length is not predictable
402*4882a593Smuzhiyun 	 */
403*4882a593Smuzhiyun 	if (num_devices <= dev_id)
404*4882a593Smuzhiyun 		return -EINVAL;
405*4882a593Smuzhiyun 
406*4882a593Smuzhiyun 	ret = snd_hda_codec_write(codec, nid, 0,
407*4882a593Smuzhiyun 			AC_VERB_SET_DEVICE_SEL, dev_id);
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	return ret;
410*4882a593Smuzhiyun }
411*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_set_dev_select);
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun /*
414*4882a593Smuzhiyun  * read widget caps for each widget and store in cache
415*4882a593Smuzhiyun  */
read_widget_caps(struct hda_codec * codec,hda_nid_t fg_node)416*4882a593Smuzhiyun static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
417*4882a593Smuzhiyun {
418*4882a593Smuzhiyun 	int i;
419*4882a593Smuzhiyun 	hda_nid_t nid;
420*4882a593Smuzhiyun 
421*4882a593Smuzhiyun 	codec->wcaps = kmalloc_array(codec->core.num_nodes, 4, GFP_KERNEL);
422*4882a593Smuzhiyun 	if (!codec->wcaps)
423*4882a593Smuzhiyun 		return -ENOMEM;
424*4882a593Smuzhiyun 	nid = codec->core.start_nid;
425*4882a593Smuzhiyun 	for (i = 0; i < codec->core.num_nodes; i++, nid++)
426*4882a593Smuzhiyun 		codec->wcaps[i] = snd_hdac_read_parm_uncached(&codec->core,
427*4882a593Smuzhiyun 					nid, AC_PAR_AUDIO_WIDGET_CAP);
428*4882a593Smuzhiyun 	return 0;
429*4882a593Smuzhiyun }
430*4882a593Smuzhiyun 
431*4882a593Smuzhiyun /* read all pin default configurations and save codec->init_pins */
read_pin_defaults(struct hda_codec * codec)432*4882a593Smuzhiyun static int read_pin_defaults(struct hda_codec *codec)
433*4882a593Smuzhiyun {
434*4882a593Smuzhiyun 	hda_nid_t nid;
435*4882a593Smuzhiyun 
436*4882a593Smuzhiyun 	for_each_hda_codec_node(nid, codec) {
437*4882a593Smuzhiyun 		struct hda_pincfg *pin;
438*4882a593Smuzhiyun 		unsigned int wcaps = get_wcaps(codec, nid);
439*4882a593Smuzhiyun 		unsigned int wid_type = get_wcaps_type(wcaps);
440*4882a593Smuzhiyun 		if (wid_type != AC_WID_PIN)
441*4882a593Smuzhiyun 			continue;
442*4882a593Smuzhiyun 		pin = snd_array_new(&codec->init_pins);
443*4882a593Smuzhiyun 		if (!pin)
444*4882a593Smuzhiyun 			return -ENOMEM;
445*4882a593Smuzhiyun 		pin->nid = nid;
446*4882a593Smuzhiyun 		pin->cfg = snd_hda_codec_read(codec, nid, 0,
447*4882a593Smuzhiyun 					      AC_VERB_GET_CONFIG_DEFAULT, 0);
448*4882a593Smuzhiyun 		/*
449*4882a593Smuzhiyun 		 * all device entries are the same widget control so far
450*4882a593Smuzhiyun 		 * fixme: if any codec is different, need fix here
451*4882a593Smuzhiyun 		 */
452*4882a593Smuzhiyun 		pin->ctrl = snd_hda_codec_read(codec, nid, 0,
453*4882a593Smuzhiyun 					       AC_VERB_GET_PIN_WIDGET_CONTROL,
454*4882a593Smuzhiyun 					       0);
455*4882a593Smuzhiyun 	}
456*4882a593Smuzhiyun 	return 0;
457*4882a593Smuzhiyun }
458*4882a593Smuzhiyun 
459*4882a593Smuzhiyun /* look up the given pin config list and return the item matching with NID */
look_up_pincfg(struct hda_codec * codec,struct snd_array * array,hda_nid_t nid)460*4882a593Smuzhiyun static struct hda_pincfg *look_up_pincfg(struct hda_codec *codec,
461*4882a593Smuzhiyun 					 struct snd_array *array,
462*4882a593Smuzhiyun 					 hda_nid_t nid)
463*4882a593Smuzhiyun {
464*4882a593Smuzhiyun 	struct hda_pincfg *pin;
465*4882a593Smuzhiyun 	int i;
466*4882a593Smuzhiyun 
467*4882a593Smuzhiyun 	snd_array_for_each(array, i, pin) {
468*4882a593Smuzhiyun 		if (pin->nid == nid)
469*4882a593Smuzhiyun 			return pin;
470*4882a593Smuzhiyun 	}
471*4882a593Smuzhiyun 	return NULL;
472*4882a593Smuzhiyun }
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun /* set the current pin config value for the given NID.
475*4882a593Smuzhiyun  * the value is cached, and read via snd_hda_codec_get_pincfg()
476*4882a593Smuzhiyun  */
snd_hda_add_pincfg(struct hda_codec * codec,struct snd_array * list,hda_nid_t nid,unsigned int cfg)477*4882a593Smuzhiyun int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
478*4882a593Smuzhiyun 		       hda_nid_t nid, unsigned int cfg)
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun 	struct hda_pincfg *pin;
481*4882a593Smuzhiyun 
482*4882a593Smuzhiyun 	/* the check below may be invalid when pins are added by a fixup
483*4882a593Smuzhiyun 	 * dynamically (e.g. via snd_hda_codec_update_widgets()), so disabled
484*4882a593Smuzhiyun 	 * for now
485*4882a593Smuzhiyun 	 */
486*4882a593Smuzhiyun 	/*
487*4882a593Smuzhiyun 	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
488*4882a593Smuzhiyun 		return -EINVAL;
489*4882a593Smuzhiyun 	*/
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 	pin = look_up_pincfg(codec, list, nid);
492*4882a593Smuzhiyun 	if (!pin) {
493*4882a593Smuzhiyun 		pin = snd_array_new(list);
494*4882a593Smuzhiyun 		if (!pin)
495*4882a593Smuzhiyun 			return -ENOMEM;
496*4882a593Smuzhiyun 		pin->nid = nid;
497*4882a593Smuzhiyun 	}
498*4882a593Smuzhiyun 	pin->cfg = cfg;
499*4882a593Smuzhiyun 	return 0;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun 
502*4882a593Smuzhiyun /**
503*4882a593Smuzhiyun  * snd_hda_codec_set_pincfg - Override a pin default configuration
504*4882a593Smuzhiyun  * @codec: the HDA codec
505*4882a593Smuzhiyun  * @nid: NID to set the pin config
506*4882a593Smuzhiyun  * @cfg: the pin default config value
507*4882a593Smuzhiyun  *
508*4882a593Smuzhiyun  * Override a pin default configuration value in the cache.
509*4882a593Smuzhiyun  * This value can be read by snd_hda_codec_get_pincfg() in a higher
510*4882a593Smuzhiyun  * priority than the real hardware value.
511*4882a593Smuzhiyun  */
snd_hda_codec_set_pincfg(struct hda_codec * codec,hda_nid_t nid,unsigned int cfg)512*4882a593Smuzhiyun int snd_hda_codec_set_pincfg(struct hda_codec *codec,
513*4882a593Smuzhiyun 			     hda_nid_t nid, unsigned int cfg)
514*4882a593Smuzhiyun {
515*4882a593Smuzhiyun 	return snd_hda_add_pincfg(codec, &codec->driver_pins, nid, cfg);
516*4882a593Smuzhiyun }
517*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_set_pincfg);
518*4882a593Smuzhiyun 
519*4882a593Smuzhiyun /**
520*4882a593Smuzhiyun  * snd_hda_codec_get_pincfg - Obtain a pin-default configuration
521*4882a593Smuzhiyun  * @codec: the HDA codec
522*4882a593Smuzhiyun  * @nid: NID to get the pin config
523*4882a593Smuzhiyun  *
524*4882a593Smuzhiyun  * Get the current pin config value of the given pin NID.
525*4882a593Smuzhiyun  * If the pincfg value is cached or overridden via sysfs or driver,
526*4882a593Smuzhiyun  * returns the cached value.
527*4882a593Smuzhiyun  */
snd_hda_codec_get_pincfg(struct hda_codec * codec,hda_nid_t nid)528*4882a593Smuzhiyun unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid)
529*4882a593Smuzhiyun {
530*4882a593Smuzhiyun 	struct hda_pincfg *pin;
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun #ifdef CONFIG_SND_HDA_RECONFIG
533*4882a593Smuzhiyun 	{
534*4882a593Smuzhiyun 		unsigned int cfg = 0;
535*4882a593Smuzhiyun 		mutex_lock(&codec->user_mutex);
536*4882a593Smuzhiyun 		pin = look_up_pincfg(codec, &codec->user_pins, nid);
537*4882a593Smuzhiyun 		if (pin)
538*4882a593Smuzhiyun 			cfg = pin->cfg;
539*4882a593Smuzhiyun 		mutex_unlock(&codec->user_mutex);
540*4882a593Smuzhiyun 		if (cfg)
541*4882a593Smuzhiyun 			return cfg;
542*4882a593Smuzhiyun 	}
543*4882a593Smuzhiyun #endif
544*4882a593Smuzhiyun 	pin = look_up_pincfg(codec, &codec->driver_pins, nid);
545*4882a593Smuzhiyun 	if (pin)
546*4882a593Smuzhiyun 		return pin->cfg;
547*4882a593Smuzhiyun 	pin = look_up_pincfg(codec, &codec->init_pins, nid);
548*4882a593Smuzhiyun 	if (pin)
549*4882a593Smuzhiyun 		return pin->cfg;
550*4882a593Smuzhiyun 	return 0;
551*4882a593Smuzhiyun }
552*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_get_pincfg);
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun /**
555*4882a593Smuzhiyun  * snd_hda_codec_set_pin_target - remember the current pinctl target value
556*4882a593Smuzhiyun  * @codec: the HDA codec
557*4882a593Smuzhiyun  * @nid: pin NID
558*4882a593Smuzhiyun  * @val: assigned pinctl value
559*4882a593Smuzhiyun  *
560*4882a593Smuzhiyun  * This function stores the given value to a pinctl target value in the
561*4882a593Smuzhiyun  * pincfg table.  This isn't always as same as the actually written value
562*4882a593Smuzhiyun  * but can be referred at any time via snd_hda_codec_get_pin_target().
563*4882a593Smuzhiyun  */
snd_hda_codec_set_pin_target(struct hda_codec * codec,hda_nid_t nid,unsigned int val)564*4882a593Smuzhiyun int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid,
565*4882a593Smuzhiyun 				 unsigned int val)
566*4882a593Smuzhiyun {
567*4882a593Smuzhiyun 	struct hda_pincfg *pin;
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	pin = look_up_pincfg(codec, &codec->init_pins, nid);
570*4882a593Smuzhiyun 	if (!pin)
571*4882a593Smuzhiyun 		return -EINVAL;
572*4882a593Smuzhiyun 	pin->target = val;
573*4882a593Smuzhiyun 	return 0;
574*4882a593Smuzhiyun }
575*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_set_pin_target);
576*4882a593Smuzhiyun 
577*4882a593Smuzhiyun /**
578*4882a593Smuzhiyun  * snd_hda_codec_get_pin_target - return the current pinctl target value
579*4882a593Smuzhiyun  * @codec: the HDA codec
580*4882a593Smuzhiyun  * @nid: pin NID
581*4882a593Smuzhiyun  */
snd_hda_codec_get_pin_target(struct hda_codec * codec,hda_nid_t nid)582*4882a593Smuzhiyun int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid)
583*4882a593Smuzhiyun {
584*4882a593Smuzhiyun 	struct hda_pincfg *pin;
585*4882a593Smuzhiyun 
586*4882a593Smuzhiyun 	pin = look_up_pincfg(codec, &codec->init_pins, nid);
587*4882a593Smuzhiyun 	if (!pin)
588*4882a593Smuzhiyun 		return 0;
589*4882a593Smuzhiyun 	return pin->target;
590*4882a593Smuzhiyun }
591*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_get_pin_target);
592*4882a593Smuzhiyun 
593*4882a593Smuzhiyun /**
594*4882a593Smuzhiyun  * snd_hda_shutup_pins - Shut up all pins
595*4882a593Smuzhiyun  * @codec: the HDA codec
596*4882a593Smuzhiyun  *
597*4882a593Smuzhiyun  * Clear all pin controls to shup up before suspend for avoiding click noise.
598*4882a593Smuzhiyun  * The controls aren't cached so that they can be resumed properly.
599*4882a593Smuzhiyun  */
snd_hda_shutup_pins(struct hda_codec * codec)600*4882a593Smuzhiyun void snd_hda_shutup_pins(struct hda_codec *codec)
601*4882a593Smuzhiyun {
602*4882a593Smuzhiyun 	const struct hda_pincfg *pin;
603*4882a593Smuzhiyun 	int i;
604*4882a593Smuzhiyun 
605*4882a593Smuzhiyun 	/* don't shut up pins when unloading the driver; otherwise it breaks
606*4882a593Smuzhiyun 	 * the default pin setup at the next load of the driver
607*4882a593Smuzhiyun 	 */
608*4882a593Smuzhiyun 	if (codec->bus->shutdown)
609*4882a593Smuzhiyun 		return;
610*4882a593Smuzhiyun 	snd_array_for_each(&codec->init_pins, i, pin) {
611*4882a593Smuzhiyun 		/* use read here for syncing after issuing each verb */
612*4882a593Smuzhiyun 		snd_hda_codec_read(codec, pin->nid, 0,
613*4882a593Smuzhiyun 				   AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
614*4882a593Smuzhiyun 	}
615*4882a593Smuzhiyun 	codec->pins_shutup = 1;
616*4882a593Smuzhiyun }
617*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_shutup_pins);
618*4882a593Smuzhiyun 
619*4882a593Smuzhiyun #ifdef CONFIG_PM
620*4882a593Smuzhiyun /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */
restore_shutup_pins(struct hda_codec * codec)621*4882a593Smuzhiyun static void restore_shutup_pins(struct hda_codec *codec)
622*4882a593Smuzhiyun {
623*4882a593Smuzhiyun 	const struct hda_pincfg *pin;
624*4882a593Smuzhiyun 	int i;
625*4882a593Smuzhiyun 
626*4882a593Smuzhiyun 	if (!codec->pins_shutup)
627*4882a593Smuzhiyun 		return;
628*4882a593Smuzhiyun 	if (codec->bus->shutdown)
629*4882a593Smuzhiyun 		return;
630*4882a593Smuzhiyun 	snd_array_for_each(&codec->init_pins, i, pin) {
631*4882a593Smuzhiyun 		snd_hda_codec_write(codec, pin->nid, 0,
632*4882a593Smuzhiyun 				    AC_VERB_SET_PIN_WIDGET_CONTROL,
633*4882a593Smuzhiyun 				    pin->ctrl);
634*4882a593Smuzhiyun 	}
635*4882a593Smuzhiyun 	codec->pins_shutup = 0;
636*4882a593Smuzhiyun }
637*4882a593Smuzhiyun #endif
638*4882a593Smuzhiyun 
hda_jackpoll_work(struct work_struct * work)639*4882a593Smuzhiyun static void hda_jackpoll_work(struct work_struct *work)
640*4882a593Smuzhiyun {
641*4882a593Smuzhiyun 	struct hda_codec *codec =
642*4882a593Smuzhiyun 		container_of(work, struct hda_codec, jackpoll_work.work);
643*4882a593Smuzhiyun 
644*4882a593Smuzhiyun 	/* for non-polling trigger: we need nothing if already powered on */
645*4882a593Smuzhiyun 	if (!codec->jackpoll_interval && snd_hdac_is_power_on(&codec->core))
646*4882a593Smuzhiyun 		return;
647*4882a593Smuzhiyun 
648*4882a593Smuzhiyun 	/* the power-up/down sequence triggers the runtime resume */
649*4882a593Smuzhiyun 	snd_hda_power_up_pm(codec);
650*4882a593Smuzhiyun 	/* update jacks manually if polling is required, too */
651*4882a593Smuzhiyun 	if (codec->jackpoll_interval) {
652*4882a593Smuzhiyun 		snd_hda_jack_set_dirty_all(codec);
653*4882a593Smuzhiyun 		snd_hda_jack_poll_all(codec);
654*4882a593Smuzhiyun 	}
655*4882a593Smuzhiyun 	snd_hda_power_down_pm(codec);
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	if (!codec->jackpoll_interval)
658*4882a593Smuzhiyun 		return;
659*4882a593Smuzhiyun 
660*4882a593Smuzhiyun 	schedule_delayed_work(&codec->jackpoll_work,
661*4882a593Smuzhiyun 			      codec->jackpoll_interval);
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun 
664*4882a593Smuzhiyun /* release all pincfg lists */
free_init_pincfgs(struct hda_codec * codec)665*4882a593Smuzhiyun static void free_init_pincfgs(struct hda_codec *codec)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun 	snd_array_free(&codec->driver_pins);
668*4882a593Smuzhiyun #ifdef CONFIG_SND_HDA_RECONFIG
669*4882a593Smuzhiyun 	snd_array_free(&codec->user_pins);
670*4882a593Smuzhiyun #endif
671*4882a593Smuzhiyun 	snd_array_free(&codec->init_pins);
672*4882a593Smuzhiyun }
673*4882a593Smuzhiyun 
674*4882a593Smuzhiyun /*
675*4882a593Smuzhiyun  * audio-converter setup caches
676*4882a593Smuzhiyun  */
677*4882a593Smuzhiyun struct hda_cvt_setup {
678*4882a593Smuzhiyun 	hda_nid_t nid;
679*4882a593Smuzhiyun 	u8 stream_tag;
680*4882a593Smuzhiyun 	u8 channel_id;
681*4882a593Smuzhiyun 	u16 format_id;
682*4882a593Smuzhiyun 	unsigned char active;	/* cvt is currently used */
683*4882a593Smuzhiyun 	unsigned char dirty;	/* setups should be cleared */
684*4882a593Smuzhiyun };
685*4882a593Smuzhiyun 
686*4882a593Smuzhiyun /* get or create a cache entry for the given audio converter NID */
687*4882a593Smuzhiyun static struct hda_cvt_setup *
get_hda_cvt_setup(struct hda_codec * codec,hda_nid_t nid)688*4882a593Smuzhiyun get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
689*4882a593Smuzhiyun {
690*4882a593Smuzhiyun 	struct hda_cvt_setup *p;
691*4882a593Smuzhiyun 	int i;
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun 	snd_array_for_each(&codec->cvt_setups, i, p) {
694*4882a593Smuzhiyun 		if (p->nid == nid)
695*4882a593Smuzhiyun 			return p;
696*4882a593Smuzhiyun 	}
697*4882a593Smuzhiyun 	p = snd_array_new(&codec->cvt_setups);
698*4882a593Smuzhiyun 	if (p)
699*4882a593Smuzhiyun 		p->nid = nid;
700*4882a593Smuzhiyun 	return p;
701*4882a593Smuzhiyun }
702*4882a593Smuzhiyun 
703*4882a593Smuzhiyun /*
704*4882a593Smuzhiyun  * PCM device
705*4882a593Smuzhiyun  */
release_pcm(struct kref * kref)706*4882a593Smuzhiyun static void release_pcm(struct kref *kref)
707*4882a593Smuzhiyun {
708*4882a593Smuzhiyun 	struct hda_pcm *pcm = container_of(kref, struct hda_pcm, kref);
709*4882a593Smuzhiyun 
710*4882a593Smuzhiyun 	if (pcm->pcm)
711*4882a593Smuzhiyun 		snd_device_free(pcm->codec->card, pcm->pcm);
712*4882a593Smuzhiyun 	clear_bit(pcm->device, pcm->codec->bus->pcm_dev_bits);
713*4882a593Smuzhiyun 	kfree(pcm->name);
714*4882a593Smuzhiyun 	kfree(pcm);
715*4882a593Smuzhiyun }
716*4882a593Smuzhiyun 
snd_hda_codec_pcm_put(struct hda_pcm * pcm)717*4882a593Smuzhiyun void snd_hda_codec_pcm_put(struct hda_pcm *pcm)
718*4882a593Smuzhiyun {
719*4882a593Smuzhiyun 	kref_put(&pcm->kref, release_pcm);
720*4882a593Smuzhiyun }
721*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_put);
722*4882a593Smuzhiyun 
snd_hda_codec_pcm_new(struct hda_codec * codec,const char * fmt,...)723*4882a593Smuzhiyun struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec,
724*4882a593Smuzhiyun 				      const char *fmt, ...)
725*4882a593Smuzhiyun {
726*4882a593Smuzhiyun 	struct hda_pcm *pcm;
727*4882a593Smuzhiyun 	va_list args;
728*4882a593Smuzhiyun 
729*4882a593Smuzhiyun 	pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
730*4882a593Smuzhiyun 	if (!pcm)
731*4882a593Smuzhiyun 		return NULL;
732*4882a593Smuzhiyun 
733*4882a593Smuzhiyun 	pcm->codec = codec;
734*4882a593Smuzhiyun 	kref_init(&pcm->kref);
735*4882a593Smuzhiyun 	va_start(args, fmt);
736*4882a593Smuzhiyun 	pcm->name = kvasprintf(GFP_KERNEL, fmt, args);
737*4882a593Smuzhiyun 	va_end(args);
738*4882a593Smuzhiyun 	if (!pcm->name) {
739*4882a593Smuzhiyun 		kfree(pcm);
740*4882a593Smuzhiyun 		return NULL;
741*4882a593Smuzhiyun 	}
742*4882a593Smuzhiyun 
743*4882a593Smuzhiyun 	list_add_tail(&pcm->list, &codec->pcm_list_head);
744*4882a593Smuzhiyun 	return pcm;
745*4882a593Smuzhiyun }
746*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_new);
747*4882a593Smuzhiyun 
748*4882a593Smuzhiyun /*
749*4882a593Smuzhiyun  * codec destructor
750*4882a593Smuzhiyun  */
codec_release_pcms(struct hda_codec * codec)751*4882a593Smuzhiyun static void codec_release_pcms(struct hda_codec *codec)
752*4882a593Smuzhiyun {
753*4882a593Smuzhiyun 	struct hda_pcm *pcm, *n;
754*4882a593Smuzhiyun 
755*4882a593Smuzhiyun 	list_for_each_entry_safe(pcm, n, &codec->pcm_list_head, list) {
756*4882a593Smuzhiyun 		list_del_init(&pcm->list);
757*4882a593Smuzhiyun 		if (pcm->pcm)
758*4882a593Smuzhiyun 			snd_device_disconnect(codec->card, pcm->pcm);
759*4882a593Smuzhiyun 		snd_hda_codec_pcm_put(pcm);
760*4882a593Smuzhiyun 	}
761*4882a593Smuzhiyun }
762*4882a593Smuzhiyun 
snd_hda_codec_cleanup_for_unbind(struct hda_codec * codec)763*4882a593Smuzhiyun void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
764*4882a593Smuzhiyun {
765*4882a593Smuzhiyun 	if (codec->registered) {
766*4882a593Smuzhiyun 		/* pm_runtime_put() is called in snd_hdac_device_exit() */
767*4882a593Smuzhiyun 		pm_runtime_get_noresume(hda_codec_dev(codec));
768*4882a593Smuzhiyun 		pm_runtime_disable(hda_codec_dev(codec));
769*4882a593Smuzhiyun 		codec->registered = 0;
770*4882a593Smuzhiyun 	}
771*4882a593Smuzhiyun 
772*4882a593Smuzhiyun 	cancel_delayed_work_sync(&codec->jackpoll_work);
773*4882a593Smuzhiyun 	if (!codec->in_freeing)
774*4882a593Smuzhiyun 		snd_hda_ctls_clear(codec);
775*4882a593Smuzhiyun 	codec_release_pcms(codec);
776*4882a593Smuzhiyun 	snd_hda_detach_beep_device(codec);
777*4882a593Smuzhiyun 	memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
778*4882a593Smuzhiyun 	snd_hda_jack_tbl_clear(codec);
779*4882a593Smuzhiyun 	codec->proc_widget_hook = NULL;
780*4882a593Smuzhiyun 	codec->spec = NULL;
781*4882a593Smuzhiyun 
782*4882a593Smuzhiyun 	/* free only driver_pins so that init_pins + user_pins are restored */
783*4882a593Smuzhiyun 	snd_array_free(&codec->driver_pins);
784*4882a593Smuzhiyun 	snd_array_free(&codec->cvt_setups);
785*4882a593Smuzhiyun 	snd_array_free(&codec->spdif_out);
786*4882a593Smuzhiyun 	snd_array_free(&codec->verbs);
787*4882a593Smuzhiyun 	codec->preset = NULL;
788*4882a593Smuzhiyun 	codec->follower_dig_outs = NULL;
789*4882a593Smuzhiyun 	codec->spdif_status_reset = 0;
790*4882a593Smuzhiyun 	snd_array_free(&codec->mixers);
791*4882a593Smuzhiyun 	snd_array_free(&codec->nids);
792*4882a593Smuzhiyun 	remove_conn_list(codec);
793*4882a593Smuzhiyun 	snd_hdac_regmap_exit(&codec->core);
794*4882a593Smuzhiyun 	codec->configured = 0;
795*4882a593Smuzhiyun }
796*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup_for_unbind);
797*4882a593Smuzhiyun 
798*4882a593Smuzhiyun static unsigned int hda_set_power_state(struct hda_codec *codec,
799*4882a593Smuzhiyun 				unsigned int power_state);
800*4882a593Smuzhiyun 
801*4882a593Smuzhiyun /* enable/disable display power per codec */
codec_display_power(struct hda_codec * codec,bool enable)802*4882a593Smuzhiyun static void codec_display_power(struct hda_codec *codec, bool enable)
803*4882a593Smuzhiyun {
804*4882a593Smuzhiyun 	if (codec->display_power_control)
805*4882a593Smuzhiyun 		snd_hdac_display_power(&codec->bus->core, codec->addr, enable);
806*4882a593Smuzhiyun }
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun /* also called from hda_bind.c */
snd_hda_codec_register(struct hda_codec * codec)809*4882a593Smuzhiyun void snd_hda_codec_register(struct hda_codec *codec)
810*4882a593Smuzhiyun {
811*4882a593Smuzhiyun 	if (codec->registered)
812*4882a593Smuzhiyun 		return;
813*4882a593Smuzhiyun 	if (device_is_registered(hda_codec_dev(codec))) {
814*4882a593Smuzhiyun 		codec_display_power(codec, true);
815*4882a593Smuzhiyun 		pm_runtime_enable(hda_codec_dev(codec));
816*4882a593Smuzhiyun 		/* it was powered up in snd_hda_codec_new(), now all done */
817*4882a593Smuzhiyun 		snd_hda_power_down(codec);
818*4882a593Smuzhiyun 		codec->registered = 1;
819*4882a593Smuzhiyun 	}
820*4882a593Smuzhiyun }
821*4882a593Smuzhiyun 
snd_hda_codec_dev_register(struct snd_device * device)822*4882a593Smuzhiyun static int snd_hda_codec_dev_register(struct snd_device *device)
823*4882a593Smuzhiyun {
824*4882a593Smuzhiyun 	snd_hda_codec_register(device->device_data);
825*4882a593Smuzhiyun 	return 0;
826*4882a593Smuzhiyun }
827*4882a593Smuzhiyun 
snd_hda_codec_dev_free(struct snd_device * device)828*4882a593Smuzhiyun static int snd_hda_codec_dev_free(struct snd_device *device)
829*4882a593Smuzhiyun {
830*4882a593Smuzhiyun 	struct hda_codec *codec = device->device_data;
831*4882a593Smuzhiyun 
832*4882a593Smuzhiyun 	codec->in_freeing = 1;
833*4882a593Smuzhiyun 	/*
834*4882a593Smuzhiyun 	 * snd_hda_codec_device_new() is used by legacy HDA and ASoC driver.
835*4882a593Smuzhiyun 	 * We can't unregister ASoC device since it will be unregistered in
836*4882a593Smuzhiyun 	 * snd_hdac_ext_bus_device_remove().
837*4882a593Smuzhiyun 	 */
838*4882a593Smuzhiyun 	if (codec->core.type == HDA_DEV_LEGACY)
839*4882a593Smuzhiyun 		snd_hdac_device_unregister(&codec->core);
840*4882a593Smuzhiyun 	codec_display_power(codec, false);
841*4882a593Smuzhiyun 
842*4882a593Smuzhiyun 	/*
843*4882a593Smuzhiyun 	 * In the case of ASoC HD-audio bus, the device refcount is released in
844*4882a593Smuzhiyun 	 * snd_hdac_ext_bus_device_remove() explicitly.
845*4882a593Smuzhiyun 	 */
846*4882a593Smuzhiyun 	if (codec->core.type == HDA_DEV_LEGACY)
847*4882a593Smuzhiyun 		put_device(hda_codec_dev(codec));
848*4882a593Smuzhiyun 
849*4882a593Smuzhiyun 	return 0;
850*4882a593Smuzhiyun }
851*4882a593Smuzhiyun 
snd_hda_codec_dev_release(struct device * dev)852*4882a593Smuzhiyun static void snd_hda_codec_dev_release(struct device *dev)
853*4882a593Smuzhiyun {
854*4882a593Smuzhiyun 	struct hda_codec *codec = dev_to_hda_codec(dev);
855*4882a593Smuzhiyun 
856*4882a593Smuzhiyun 	free_init_pincfgs(codec);
857*4882a593Smuzhiyun 	snd_hdac_device_exit(&codec->core);
858*4882a593Smuzhiyun 	snd_hda_sysfs_clear(codec);
859*4882a593Smuzhiyun 	kfree(codec->modelname);
860*4882a593Smuzhiyun 	kfree(codec->wcaps);
861*4882a593Smuzhiyun 
862*4882a593Smuzhiyun 	/*
863*4882a593Smuzhiyun 	 * In the case of ASoC HD-audio, hda_codec is device managed.
864*4882a593Smuzhiyun 	 * It will be freed when the ASoC device is removed.
865*4882a593Smuzhiyun 	 */
866*4882a593Smuzhiyun 	if (codec->core.type == HDA_DEV_LEGACY)
867*4882a593Smuzhiyun 		kfree(codec);
868*4882a593Smuzhiyun }
869*4882a593Smuzhiyun 
870*4882a593Smuzhiyun #define DEV_NAME_LEN 31
871*4882a593Smuzhiyun 
snd_hda_codec_device_init(struct hda_bus * bus,struct snd_card * card,unsigned int codec_addr,struct hda_codec ** codecp)872*4882a593Smuzhiyun static int snd_hda_codec_device_init(struct hda_bus *bus, struct snd_card *card,
873*4882a593Smuzhiyun 			unsigned int codec_addr, struct hda_codec **codecp)
874*4882a593Smuzhiyun {
875*4882a593Smuzhiyun 	char name[DEV_NAME_LEN];
876*4882a593Smuzhiyun 	struct hda_codec *codec;
877*4882a593Smuzhiyun 	int err;
878*4882a593Smuzhiyun 
879*4882a593Smuzhiyun 	dev_dbg(card->dev, "%s: entry\n", __func__);
880*4882a593Smuzhiyun 
881*4882a593Smuzhiyun 	if (snd_BUG_ON(!bus))
882*4882a593Smuzhiyun 		return -EINVAL;
883*4882a593Smuzhiyun 	if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
884*4882a593Smuzhiyun 		return -EINVAL;
885*4882a593Smuzhiyun 
886*4882a593Smuzhiyun 	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
887*4882a593Smuzhiyun 	if (!codec)
888*4882a593Smuzhiyun 		return -ENOMEM;
889*4882a593Smuzhiyun 
890*4882a593Smuzhiyun 	sprintf(name, "hdaudioC%dD%d", card->number, codec_addr);
891*4882a593Smuzhiyun 	err = snd_hdac_device_init(&codec->core, &bus->core, name, codec_addr);
892*4882a593Smuzhiyun 	if (err < 0) {
893*4882a593Smuzhiyun 		kfree(codec);
894*4882a593Smuzhiyun 		return err;
895*4882a593Smuzhiyun 	}
896*4882a593Smuzhiyun 
897*4882a593Smuzhiyun 	codec->core.type = HDA_DEV_LEGACY;
898*4882a593Smuzhiyun 	*codecp = codec;
899*4882a593Smuzhiyun 
900*4882a593Smuzhiyun 	return err;
901*4882a593Smuzhiyun }
902*4882a593Smuzhiyun 
903*4882a593Smuzhiyun /**
904*4882a593Smuzhiyun  * snd_hda_codec_new - create a HDA codec
905*4882a593Smuzhiyun  * @bus: the bus to assign
906*4882a593Smuzhiyun  * @card: card for this codec
907*4882a593Smuzhiyun  * @codec_addr: the codec address
908*4882a593Smuzhiyun  * @codecp: the pointer to store the generated codec
909*4882a593Smuzhiyun  *
910*4882a593Smuzhiyun  * Returns 0 if successful, or a negative error code.
911*4882a593Smuzhiyun  */
snd_hda_codec_new(struct hda_bus * bus,struct snd_card * card,unsigned int codec_addr,struct hda_codec ** codecp)912*4882a593Smuzhiyun int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
913*4882a593Smuzhiyun 		      unsigned int codec_addr, struct hda_codec **codecp)
914*4882a593Smuzhiyun {
915*4882a593Smuzhiyun 	int ret;
916*4882a593Smuzhiyun 
917*4882a593Smuzhiyun 	ret = snd_hda_codec_device_init(bus, card, codec_addr, codecp);
918*4882a593Smuzhiyun 	if (ret < 0)
919*4882a593Smuzhiyun 		return ret;
920*4882a593Smuzhiyun 
921*4882a593Smuzhiyun 	return snd_hda_codec_device_new(bus, card, codec_addr, *codecp);
922*4882a593Smuzhiyun }
923*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_new);
924*4882a593Smuzhiyun 
snd_hda_codec_device_new(struct hda_bus * bus,struct snd_card * card,unsigned int codec_addr,struct hda_codec * codec)925*4882a593Smuzhiyun int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
926*4882a593Smuzhiyun 			unsigned int codec_addr, struct hda_codec *codec)
927*4882a593Smuzhiyun {
928*4882a593Smuzhiyun 	char component[31];
929*4882a593Smuzhiyun 	hda_nid_t fg;
930*4882a593Smuzhiyun 	int err;
931*4882a593Smuzhiyun 	static const struct snd_device_ops dev_ops = {
932*4882a593Smuzhiyun 		.dev_register = snd_hda_codec_dev_register,
933*4882a593Smuzhiyun 		.dev_free = snd_hda_codec_dev_free,
934*4882a593Smuzhiyun 	};
935*4882a593Smuzhiyun 
936*4882a593Smuzhiyun 	dev_dbg(card->dev, "%s: entry\n", __func__);
937*4882a593Smuzhiyun 
938*4882a593Smuzhiyun 	if (snd_BUG_ON(!bus))
939*4882a593Smuzhiyun 		return -EINVAL;
940*4882a593Smuzhiyun 	if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
941*4882a593Smuzhiyun 		return -EINVAL;
942*4882a593Smuzhiyun 
943*4882a593Smuzhiyun 	codec->core.dev.release = snd_hda_codec_dev_release;
944*4882a593Smuzhiyun 	codec->core.exec_verb = codec_exec_verb;
945*4882a593Smuzhiyun 
946*4882a593Smuzhiyun 	codec->bus = bus;
947*4882a593Smuzhiyun 	codec->card = card;
948*4882a593Smuzhiyun 	codec->addr = codec_addr;
949*4882a593Smuzhiyun 	mutex_init(&codec->spdif_mutex);
950*4882a593Smuzhiyun 	mutex_init(&codec->control_mutex);
951*4882a593Smuzhiyun 	snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
952*4882a593Smuzhiyun 	snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
953*4882a593Smuzhiyun 	snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
954*4882a593Smuzhiyun 	snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
955*4882a593Smuzhiyun 	snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
956*4882a593Smuzhiyun 	snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
957*4882a593Smuzhiyun 	snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
958*4882a593Smuzhiyun 	snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
959*4882a593Smuzhiyun 	INIT_LIST_HEAD(&codec->conn_list);
960*4882a593Smuzhiyun 	INIT_LIST_HEAD(&codec->pcm_list_head);
961*4882a593Smuzhiyun 
962*4882a593Smuzhiyun 	INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
963*4882a593Smuzhiyun 	codec->depop_delay = -1;
964*4882a593Smuzhiyun 	codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
965*4882a593Smuzhiyun 
966*4882a593Smuzhiyun #ifdef CONFIG_PM
967*4882a593Smuzhiyun 	codec->power_jiffies = jiffies;
968*4882a593Smuzhiyun #endif
969*4882a593Smuzhiyun 
970*4882a593Smuzhiyun 	snd_hda_sysfs_init(codec);
971*4882a593Smuzhiyun 
972*4882a593Smuzhiyun 	if (codec->bus->modelname) {
973*4882a593Smuzhiyun 		codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
974*4882a593Smuzhiyun 		if (!codec->modelname) {
975*4882a593Smuzhiyun 			err = -ENOMEM;
976*4882a593Smuzhiyun 			goto error;
977*4882a593Smuzhiyun 		}
978*4882a593Smuzhiyun 	}
979*4882a593Smuzhiyun 
980*4882a593Smuzhiyun 	fg = codec->core.afg ? codec->core.afg : codec->core.mfg;
981*4882a593Smuzhiyun 	err = read_widget_caps(codec, fg);
982*4882a593Smuzhiyun 	if (err < 0)
983*4882a593Smuzhiyun 		goto error;
984*4882a593Smuzhiyun 	err = read_pin_defaults(codec);
985*4882a593Smuzhiyun 	if (err < 0)
986*4882a593Smuzhiyun 		goto error;
987*4882a593Smuzhiyun 
988*4882a593Smuzhiyun 	/* power-up all before initialization */
989*4882a593Smuzhiyun 	hda_set_power_state(codec, AC_PWRST_D0);
990*4882a593Smuzhiyun 	codec->core.dev.power.power_state = PMSG_ON;
991*4882a593Smuzhiyun 
992*4882a593Smuzhiyun 	snd_hda_codec_proc_new(codec);
993*4882a593Smuzhiyun 
994*4882a593Smuzhiyun 	snd_hda_create_hwdep(codec);
995*4882a593Smuzhiyun 
996*4882a593Smuzhiyun 	sprintf(component, "HDA:%08x,%08x,%08x", codec->core.vendor_id,
997*4882a593Smuzhiyun 		codec->core.subsystem_id, codec->core.revision_id);
998*4882a593Smuzhiyun 	snd_component_add(card, component);
999*4882a593Smuzhiyun 
1000*4882a593Smuzhiyun 	err = snd_device_new(card, SNDRV_DEV_CODEC, codec, &dev_ops);
1001*4882a593Smuzhiyun 	if (err < 0)
1002*4882a593Smuzhiyun 		goto error;
1003*4882a593Smuzhiyun 
1004*4882a593Smuzhiyun 	/* PM runtime needs to be enabled later after binding codec */
1005*4882a593Smuzhiyun 	pm_runtime_forbid(&codec->core.dev);
1006*4882a593Smuzhiyun 
1007*4882a593Smuzhiyun 	return 0;
1008*4882a593Smuzhiyun 
1009*4882a593Smuzhiyun  error:
1010*4882a593Smuzhiyun 	put_device(hda_codec_dev(codec));
1011*4882a593Smuzhiyun 	return err;
1012*4882a593Smuzhiyun }
1013*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_device_new);
1014*4882a593Smuzhiyun 
1015*4882a593Smuzhiyun /**
1016*4882a593Smuzhiyun  * snd_hda_codec_update_widgets - Refresh widget caps and pin defaults
1017*4882a593Smuzhiyun  * @codec: the HDA codec
1018*4882a593Smuzhiyun  *
1019*4882a593Smuzhiyun  * Forcibly refresh the all widget caps and the init pin configurations of
1020*4882a593Smuzhiyun  * the given codec.
1021*4882a593Smuzhiyun  */
snd_hda_codec_update_widgets(struct hda_codec * codec)1022*4882a593Smuzhiyun int snd_hda_codec_update_widgets(struct hda_codec *codec)
1023*4882a593Smuzhiyun {
1024*4882a593Smuzhiyun 	hda_nid_t fg;
1025*4882a593Smuzhiyun 	int err;
1026*4882a593Smuzhiyun 
1027*4882a593Smuzhiyun 	err = snd_hdac_refresh_widgets(&codec->core);
1028*4882a593Smuzhiyun 	if (err < 0)
1029*4882a593Smuzhiyun 		return err;
1030*4882a593Smuzhiyun 
1031*4882a593Smuzhiyun 	/* Assume the function group node does not change,
1032*4882a593Smuzhiyun 	 * only the widget nodes may change.
1033*4882a593Smuzhiyun 	 */
1034*4882a593Smuzhiyun 	kfree(codec->wcaps);
1035*4882a593Smuzhiyun 	fg = codec->core.afg ? codec->core.afg : codec->core.mfg;
1036*4882a593Smuzhiyun 	err = read_widget_caps(codec, fg);
1037*4882a593Smuzhiyun 	if (err < 0)
1038*4882a593Smuzhiyun 		return err;
1039*4882a593Smuzhiyun 
1040*4882a593Smuzhiyun 	snd_array_free(&codec->init_pins);
1041*4882a593Smuzhiyun 	err = read_pin_defaults(codec);
1042*4882a593Smuzhiyun 
1043*4882a593Smuzhiyun 	return err;
1044*4882a593Smuzhiyun }
1045*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_update_widgets);
1046*4882a593Smuzhiyun 
1047*4882a593Smuzhiyun /* update the stream-id if changed */
update_pcm_stream_id(struct hda_codec * codec,struct hda_cvt_setup * p,hda_nid_t nid,u32 stream_tag,int channel_id)1048*4882a593Smuzhiyun static void update_pcm_stream_id(struct hda_codec *codec,
1049*4882a593Smuzhiyun 				 struct hda_cvt_setup *p, hda_nid_t nid,
1050*4882a593Smuzhiyun 				 u32 stream_tag, int channel_id)
1051*4882a593Smuzhiyun {
1052*4882a593Smuzhiyun 	unsigned int oldval, newval;
1053*4882a593Smuzhiyun 
1054*4882a593Smuzhiyun 	if (p->stream_tag != stream_tag || p->channel_id != channel_id) {
1055*4882a593Smuzhiyun 		oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
1056*4882a593Smuzhiyun 		newval = (stream_tag << 4) | channel_id;
1057*4882a593Smuzhiyun 		if (oldval != newval)
1058*4882a593Smuzhiyun 			snd_hda_codec_write(codec, nid, 0,
1059*4882a593Smuzhiyun 					    AC_VERB_SET_CHANNEL_STREAMID,
1060*4882a593Smuzhiyun 					    newval);
1061*4882a593Smuzhiyun 		p->stream_tag = stream_tag;
1062*4882a593Smuzhiyun 		p->channel_id = channel_id;
1063*4882a593Smuzhiyun 	}
1064*4882a593Smuzhiyun }
1065*4882a593Smuzhiyun 
1066*4882a593Smuzhiyun /* update the format-id if changed */
update_pcm_format(struct hda_codec * codec,struct hda_cvt_setup * p,hda_nid_t nid,int format)1067*4882a593Smuzhiyun static void update_pcm_format(struct hda_codec *codec, struct hda_cvt_setup *p,
1068*4882a593Smuzhiyun 			      hda_nid_t nid, int format)
1069*4882a593Smuzhiyun {
1070*4882a593Smuzhiyun 	unsigned int oldval;
1071*4882a593Smuzhiyun 
1072*4882a593Smuzhiyun 	if (p->format_id != format) {
1073*4882a593Smuzhiyun 		oldval = snd_hda_codec_read(codec, nid, 0,
1074*4882a593Smuzhiyun 					    AC_VERB_GET_STREAM_FORMAT, 0);
1075*4882a593Smuzhiyun 		if (oldval != format) {
1076*4882a593Smuzhiyun 			msleep(1);
1077*4882a593Smuzhiyun 			snd_hda_codec_write(codec, nid, 0,
1078*4882a593Smuzhiyun 					    AC_VERB_SET_STREAM_FORMAT,
1079*4882a593Smuzhiyun 					    format);
1080*4882a593Smuzhiyun 		}
1081*4882a593Smuzhiyun 		p->format_id = format;
1082*4882a593Smuzhiyun 	}
1083*4882a593Smuzhiyun }
1084*4882a593Smuzhiyun 
1085*4882a593Smuzhiyun /**
1086*4882a593Smuzhiyun  * snd_hda_codec_setup_stream - set up the codec for streaming
1087*4882a593Smuzhiyun  * @codec: the CODEC to set up
1088*4882a593Smuzhiyun  * @nid: the NID to set up
1089*4882a593Smuzhiyun  * @stream_tag: stream tag to pass, it's between 0x1 and 0xf.
1090*4882a593Smuzhiyun  * @channel_id: channel id to pass, zero based.
1091*4882a593Smuzhiyun  * @format: stream format.
1092*4882a593Smuzhiyun  */
snd_hda_codec_setup_stream(struct hda_codec * codec,hda_nid_t nid,u32 stream_tag,int channel_id,int format)1093*4882a593Smuzhiyun void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
1094*4882a593Smuzhiyun 				u32 stream_tag,
1095*4882a593Smuzhiyun 				int channel_id, int format)
1096*4882a593Smuzhiyun {
1097*4882a593Smuzhiyun 	struct hda_codec *c;
1098*4882a593Smuzhiyun 	struct hda_cvt_setup *p;
1099*4882a593Smuzhiyun 	int type;
1100*4882a593Smuzhiyun 	int i;
1101*4882a593Smuzhiyun 
1102*4882a593Smuzhiyun 	if (!nid)
1103*4882a593Smuzhiyun 		return;
1104*4882a593Smuzhiyun 
1105*4882a593Smuzhiyun 	codec_dbg(codec,
1106*4882a593Smuzhiyun 		  "hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
1107*4882a593Smuzhiyun 		  nid, stream_tag, channel_id, format);
1108*4882a593Smuzhiyun 	p = get_hda_cvt_setup(codec, nid);
1109*4882a593Smuzhiyun 	if (!p)
1110*4882a593Smuzhiyun 		return;
1111*4882a593Smuzhiyun 
1112*4882a593Smuzhiyun 	if (codec->patch_ops.stream_pm)
1113*4882a593Smuzhiyun 		codec->patch_ops.stream_pm(codec, nid, true);
1114*4882a593Smuzhiyun 	if (codec->pcm_format_first)
1115*4882a593Smuzhiyun 		update_pcm_format(codec, p, nid, format);
1116*4882a593Smuzhiyun 	update_pcm_stream_id(codec, p, nid, stream_tag, channel_id);
1117*4882a593Smuzhiyun 	if (!codec->pcm_format_first)
1118*4882a593Smuzhiyun 		update_pcm_format(codec, p, nid, format);
1119*4882a593Smuzhiyun 
1120*4882a593Smuzhiyun 	p->active = 1;
1121*4882a593Smuzhiyun 	p->dirty = 0;
1122*4882a593Smuzhiyun 
1123*4882a593Smuzhiyun 	/* make other inactive cvts with the same stream-tag dirty */
1124*4882a593Smuzhiyun 	type = get_wcaps_type(get_wcaps(codec, nid));
1125*4882a593Smuzhiyun 	list_for_each_codec(c, codec->bus) {
1126*4882a593Smuzhiyun 		snd_array_for_each(&c->cvt_setups, i, p) {
1127*4882a593Smuzhiyun 			if (!p->active && p->stream_tag == stream_tag &&
1128*4882a593Smuzhiyun 			    get_wcaps_type(get_wcaps(c, p->nid)) == type)
1129*4882a593Smuzhiyun 				p->dirty = 1;
1130*4882a593Smuzhiyun 		}
1131*4882a593Smuzhiyun 	}
1132*4882a593Smuzhiyun }
1133*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_setup_stream);
1134*4882a593Smuzhiyun 
1135*4882a593Smuzhiyun static void really_cleanup_stream(struct hda_codec *codec,
1136*4882a593Smuzhiyun 				  struct hda_cvt_setup *q);
1137*4882a593Smuzhiyun 
1138*4882a593Smuzhiyun /**
1139*4882a593Smuzhiyun  * __snd_hda_codec_cleanup_stream - clean up the codec for closing
1140*4882a593Smuzhiyun  * @codec: the CODEC to clean up
1141*4882a593Smuzhiyun  * @nid: the NID to clean up
1142*4882a593Smuzhiyun  * @do_now: really clean up the stream instead of clearing the active flag
1143*4882a593Smuzhiyun  */
__snd_hda_codec_cleanup_stream(struct hda_codec * codec,hda_nid_t nid,int do_now)1144*4882a593Smuzhiyun void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
1145*4882a593Smuzhiyun 				    int do_now)
1146*4882a593Smuzhiyun {
1147*4882a593Smuzhiyun 	struct hda_cvt_setup *p;
1148*4882a593Smuzhiyun 
1149*4882a593Smuzhiyun 	if (!nid)
1150*4882a593Smuzhiyun 		return;
1151*4882a593Smuzhiyun 
1152*4882a593Smuzhiyun 	if (codec->no_sticky_stream)
1153*4882a593Smuzhiyun 		do_now = 1;
1154*4882a593Smuzhiyun 
1155*4882a593Smuzhiyun 	codec_dbg(codec, "hda_codec_cleanup_stream: NID=0x%x\n", nid);
1156*4882a593Smuzhiyun 	p = get_hda_cvt_setup(codec, nid);
1157*4882a593Smuzhiyun 	if (p) {
1158*4882a593Smuzhiyun 		/* here we just clear the active flag when do_now isn't set;
1159*4882a593Smuzhiyun 		 * actual clean-ups will be done later in
1160*4882a593Smuzhiyun 		 * purify_inactive_streams() called from snd_hda_codec_prpapre()
1161*4882a593Smuzhiyun 		 */
1162*4882a593Smuzhiyun 		if (do_now)
1163*4882a593Smuzhiyun 			really_cleanup_stream(codec, p);
1164*4882a593Smuzhiyun 		else
1165*4882a593Smuzhiyun 			p->active = 0;
1166*4882a593Smuzhiyun 	}
1167*4882a593Smuzhiyun }
1168*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__snd_hda_codec_cleanup_stream);
1169*4882a593Smuzhiyun 
really_cleanup_stream(struct hda_codec * codec,struct hda_cvt_setup * q)1170*4882a593Smuzhiyun static void really_cleanup_stream(struct hda_codec *codec,
1171*4882a593Smuzhiyun 				  struct hda_cvt_setup *q)
1172*4882a593Smuzhiyun {
1173*4882a593Smuzhiyun 	hda_nid_t nid = q->nid;
1174*4882a593Smuzhiyun 	if (q->stream_tag || q->channel_id)
1175*4882a593Smuzhiyun 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
1176*4882a593Smuzhiyun 	if (q->format_id)
1177*4882a593Smuzhiyun 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0
1178*4882a593Smuzhiyun );
1179*4882a593Smuzhiyun 	memset(q, 0, sizeof(*q));
1180*4882a593Smuzhiyun 	q->nid = nid;
1181*4882a593Smuzhiyun 	if (codec->patch_ops.stream_pm)
1182*4882a593Smuzhiyun 		codec->patch_ops.stream_pm(codec, nid, false);
1183*4882a593Smuzhiyun }
1184*4882a593Smuzhiyun 
1185*4882a593Smuzhiyun /* clean up the all conflicting obsolete streams */
purify_inactive_streams(struct hda_codec * codec)1186*4882a593Smuzhiyun static void purify_inactive_streams(struct hda_codec *codec)
1187*4882a593Smuzhiyun {
1188*4882a593Smuzhiyun 	struct hda_codec *c;
1189*4882a593Smuzhiyun 	struct hda_cvt_setup *p;
1190*4882a593Smuzhiyun 	int i;
1191*4882a593Smuzhiyun 
1192*4882a593Smuzhiyun 	list_for_each_codec(c, codec->bus) {
1193*4882a593Smuzhiyun 		snd_array_for_each(&c->cvt_setups, i, p) {
1194*4882a593Smuzhiyun 			if (p->dirty)
1195*4882a593Smuzhiyun 				really_cleanup_stream(c, p);
1196*4882a593Smuzhiyun 		}
1197*4882a593Smuzhiyun 	}
1198*4882a593Smuzhiyun }
1199*4882a593Smuzhiyun 
1200*4882a593Smuzhiyun #ifdef CONFIG_PM
1201*4882a593Smuzhiyun /* clean up all streams; called from suspend */
hda_cleanup_all_streams(struct hda_codec * codec)1202*4882a593Smuzhiyun static void hda_cleanup_all_streams(struct hda_codec *codec)
1203*4882a593Smuzhiyun {
1204*4882a593Smuzhiyun 	struct hda_cvt_setup *p;
1205*4882a593Smuzhiyun 	int i;
1206*4882a593Smuzhiyun 
1207*4882a593Smuzhiyun 	snd_array_for_each(&codec->cvt_setups, i, p) {
1208*4882a593Smuzhiyun 		if (p->stream_tag)
1209*4882a593Smuzhiyun 			really_cleanup_stream(codec, p);
1210*4882a593Smuzhiyun 	}
1211*4882a593Smuzhiyun }
1212*4882a593Smuzhiyun #endif
1213*4882a593Smuzhiyun 
1214*4882a593Smuzhiyun /*
1215*4882a593Smuzhiyun  * amp access functions
1216*4882a593Smuzhiyun  */
1217*4882a593Smuzhiyun 
1218*4882a593Smuzhiyun /**
1219*4882a593Smuzhiyun  * query_amp_caps - query AMP capabilities
1220*4882a593Smuzhiyun  * @codec: the HD-auio codec
1221*4882a593Smuzhiyun  * @nid: the NID to query
1222*4882a593Smuzhiyun  * @direction: either #HDA_INPUT or #HDA_OUTPUT
1223*4882a593Smuzhiyun  *
1224*4882a593Smuzhiyun  * Query AMP capabilities for the given widget and direction.
1225*4882a593Smuzhiyun  * Returns the obtained capability bits.
1226*4882a593Smuzhiyun  *
1227*4882a593Smuzhiyun  * When cap bits have been already read, this doesn't read again but
1228*4882a593Smuzhiyun  * returns the cached value.
1229*4882a593Smuzhiyun  */
query_amp_caps(struct hda_codec * codec,hda_nid_t nid,int direction)1230*4882a593Smuzhiyun u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
1231*4882a593Smuzhiyun {
1232*4882a593Smuzhiyun 	if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
1233*4882a593Smuzhiyun 		nid = codec->core.afg;
1234*4882a593Smuzhiyun 	return snd_hda_param_read(codec, nid,
1235*4882a593Smuzhiyun 				  direction == HDA_OUTPUT ?
1236*4882a593Smuzhiyun 				  AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
1237*4882a593Smuzhiyun }
1238*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(query_amp_caps);
1239*4882a593Smuzhiyun 
1240*4882a593Smuzhiyun /**
1241*4882a593Smuzhiyun  * snd_hda_check_amp_caps - query AMP capabilities
1242*4882a593Smuzhiyun  * @codec: the HD-audio codec
1243*4882a593Smuzhiyun  * @nid: the NID to query
1244*4882a593Smuzhiyun  * @dir: either #HDA_INPUT or #HDA_OUTPUT
1245*4882a593Smuzhiyun  * @bits: bit mask to check the result
1246*4882a593Smuzhiyun  *
1247*4882a593Smuzhiyun  * Check whether the widget has the given amp capability for the direction.
1248*4882a593Smuzhiyun  */
snd_hda_check_amp_caps(struct hda_codec * codec,hda_nid_t nid,int dir,unsigned int bits)1249*4882a593Smuzhiyun bool snd_hda_check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
1250*4882a593Smuzhiyun 			   int dir, unsigned int bits)
1251*4882a593Smuzhiyun {
1252*4882a593Smuzhiyun 	if (!nid)
1253*4882a593Smuzhiyun 		return false;
1254*4882a593Smuzhiyun 	if (get_wcaps(codec, nid) & (1 << (dir + 1)))
1255*4882a593Smuzhiyun 		if (query_amp_caps(codec, nid, dir) & bits)
1256*4882a593Smuzhiyun 			return true;
1257*4882a593Smuzhiyun 	return false;
1258*4882a593Smuzhiyun }
1259*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_check_amp_caps);
1260*4882a593Smuzhiyun 
1261*4882a593Smuzhiyun /**
1262*4882a593Smuzhiyun  * snd_hda_override_amp_caps - Override the AMP capabilities
1263*4882a593Smuzhiyun  * @codec: the CODEC to clean up
1264*4882a593Smuzhiyun  * @nid: the NID to clean up
1265*4882a593Smuzhiyun  * @dir: either #HDA_INPUT or #HDA_OUTPUT
1266*4882a593Smuzhiyun  * @caps: the capability bits to set
1267*4882a593Smuzhiyun  *
1268*4882a593Smuzhiyun  * Override the cached AMP caps bits value by the given one.
1269*4882a593Smuzhiyun  * This function is useful if the driver needs to adjust the AMP ranges,
1270*4882a593Smuzhiyun  * e.g. limit to 0dB, etc.
1271*4882a593Smuzhiyun  *
1272*4882a593Smuzhiyun  * Returns zero if successful or a negative error code.
1273*4882a593Smuzhiyun  */
snd_hda_override_amp_caps(struct hda_codec * codec,hda_nid_t nid,int dir,unsigned int caps)1274*4882a593Smuzhiyun int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
1275*4882a593Smuzhiyun 			      unsigned int caps)
1276*4882a593Smuzhiyun {
1277*4882a593Smuzhiyun 	unsigned int parm;
1278*4882a593Smuzhiyun 
1279*4882a593Smuzhiyun 	snd_hda_override_wcaps(codec, nid,
1280*4882a593Smuzhiyun 			       get_wcaps(codec, nid) | AC_WCAP_AMP_OVRD);
1281*4882a593Smuzhiyun 	parm = dir == HDA_OUTPUT ? AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP;
1282*4882a593Smuzhiyun 	return snd_hdac_override_parm(&codec->core, nid, parm, caps);
1283*4882a593Smuzhiyun }
1284*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_override_amp_caps);
1285*4882a593Smuzhiyun 
encode_amp(struct hda_codec * codec,hda_nid_t nid,int ch,int dir,int idx)1286*4882a593Smuzhiyun static unsigned int encode_amp(struct hda_codec *codec, hda_nid_t nid,
1287*4882a593Smuzhiyun 			       int ch, int dir, int idx)
1288*4882a593Smuzhiyun {
1289*4882a593Smuzhiyun 	unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
1290*4882a593Smuzhiyun 
1291*4882a593Smuzhiyun 	/* enable fake mute if no h/w mute but min=mute */
1292*4882a593Smuzhiyun 	if ((query_amp_caps(codec, nid, dir) &
1293*4882a593Smuzhiyun 	     (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) == AC_AMPCAP_MIN_MUTE)
1294*4882a593Smuzhiyun 		cmd |= AC_AMP_FAKE_MUTE;
1295*4882a593Smuzhiyun 	return cmd;
1296*4882a593Smuzhiyun }
1297*4882a593Smuzhiyun 
1298*4882a593Smuzhiyun /**
1299*4882a593Smuzhiyun  * snd_hda_codec_amp_update - update the AMP mono value
1300*4882a593Smuzhiyun  * @codec: HD-audio codec
1301*4882a593Smuzhiyun  * @nid: NID to read the AMP value
1302*4882a593Smuzhiyun  * @ch: channel to update (0 or 1)
1303*4882a593Smuzhiyun  * @dir: #HDA_INPUT or #HDA_OUTPUT
1304*4882a593Smuzhiyun  * @idx: the index value (only for input direction)
1305*4882a593Smuzhiyun  * @mask: bit mask to set
1306*4882a593Smuzhiyun  * @val: the bits value to set
1307*4882a593Smuzhiyun  *
1308*4882a593Smuzhiyun  * Update the AMP values for the given channel, direction and index.
1309*4882a593Smuzhiyun  */
snd_hda_codec_amp_update(struct hda_codec * codec,hda_nid_t nid,int ch,int dir,int idx,int mask,int val)1310*4882a593Smuzhiyun int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid,
1311*4882a593Smuzhiyun 			     int ch, int dir, int idx, int mask, int val)
1312*4882a593Smuzhiyun {
1313*4882a593Smuzhiyun 	unsigned int cmd = encode_amp(codec, nid, ch, dir, idx);
1314*4882a593Smuzhiyun 
1315*4882a593Smuzhiyun 	return snd_hdac_regmap_update_raw(&codec->core, cmd, mask, val);
1316*4882a593Smuzhiyun }
1317*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_amp_update);
1318*4882a593Smuzhiyun 
1319*4882a593Smuzhiyun /**
1320*4882a593Smuzhiyun  * snd_hda_codec_amp_stereo - update the AMP stereo values
1321*4882a593Smuzhiyun  * @codec: HD-audio codec
1322*4882a593Smuzhiyun  * @nid: NID to read the AMP value
1323*4882a593Smuzhiyun  * @direction: #HDA_INPUT or #HDA_OUTPUT
1324*4882a593Smuzhiyun  * @idx: the index value (only for input direction)
1325*4882a593Smuzhiyun  * @mask: bit mask to set
1326*4882a593Smuzhiyun  * @val: the bits value to set
1327*4882a593Smuzhiyun  *
1328*4882a593Smuzhiyun  * Update the AMP values like snd_hda_codec_amp_update(), but for a
1329*4882a593Smuzhiyun  * stereo widget with the same mask and value.
1330*4882a593Smuzhiyun  */
snd_hda_codec_amp_stereo(struct hda_codec * codec,hda_nid_t nid,int direction,int idx,int mask,int val)1331*4882a593Smuzhiyun int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
1332*4882a593Smuzhiyun 			     int direction, int idx, int mask, int val)
1333*4882a593Smuzhiyun {
1334*4882a593Smuzhiyun 	int ch, ret = 0;
1335*4882a593Smuzhiyun 
1336*4882a593Smuzhiyun 	if (snd_BUG_ON(mask & ~0xff))
1337*4882a593Smuzhiyun 		mask &= 0xff;
1338*4882a593Smuzhiyun 	for (ch = 0; ch < 2; ch++)
1339*4882a593Smuzhiyun 		ret |= snd_hda_codec_amp_update(codec, nid, ch, direction,
1340*4882a593Smuzhiyun 						idx, mask, val);
1341*4882a593Smuzhiyun 	return ret;
1342*4882a593Smuzhiyun }
1343*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_amp_stereo);
1344*4882a593Smuzhiyun 
1345*4882a593Smuzhiyun /**
1346*4882a593Smuzhiyun  * snd_hda_codec_amp_init - initialize the AMP value
1347*4882a593Smuzhiyun  * @codec: the HDA codec
1348*4882a593Smuzhiyun  * @nid: NID to read the AMP value
1349*4882a593Smuzhiyun  * @ch: channel (left=0 or right=1)
1350*4882a593Smuzhiyun  * @dir: #HDA_INPUT or #HDA_OUTPUT
1351*4882a593Smuzhiyun  * @idx: the index value (only for input direction)
1352*4882a593Smuzhiyun  * @mask: bit mask to set
1353*4882a593Smuzhiyun  * @val: the bits value to set
1354*4882a593Smuzhiyun  *
1355*4882a593Smuzhiyun  * Works like snd_hda_codec_amp_update() but it writes the value only at
1356*4882a593Smuzhiyun  * the first access.  If the amp was already initialized / updated beforehand,
1357*4882a593Smuzhiyun  * this does nothing.
1358*4882a593Smuzhiyun  */
snd_hda_codec_amp_init(struct hda_codec * codec,hda_nid_t nid,int ch,int dir,int idx,int mask,int val)1359*4882a593Smuzhiyun int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch,
1360*4882a593Smuzhiyun 			   int dir, int idx, int mask, int val)
1361*4882a593Smuzhiyun {
1362*4882a593Smuzhiyun 	unsigned int cmd = encode_amp(codec, nid, ch, dir, idx);
1363*4882a593Smuzhiyun 
1364*4882a593Smuzhiyun 	if (!codec->core.regmap)
1365*4882a593Smuzhiyun 		return -EINVAL;
1366*4882a593Smuzhiyun 	return snd_hdac_regmap_update_raw_once(&codec->core, cmd, mask, val);
1367*4882a593Smuzhiyun }
1368*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_amp_init);
1369*4882a593Smuzhiyun 
1370*4882a593Smuzhiyun /**
1371*4882a593Smuzhiyun  * snd_hda_codec_amp_init_stereo - initialize the stereo AMP value
1372*4882a593Smuzhiyun  * @codec: the HDA codec
1373*4882a593Smuzhiyun  * @nid: NID to read the AMP value
1374*4882a593Smuzhiyun  * @dir: #HDA_INPUT or #HDA_OUTPUT
1375*4882a593Smuzhiyun  * @idx: the index value (only for input direction)
1376*4882a593Smuzhiyun  * @mask: bit mask to set
1377*4882a593Smuzhiyun  * @val: the bits value to set
1378*4882a593Smuzhiyun  *
1379*4882a593Smuzhiyun  * Call snd_hda_codec_amp_init() for both stereo channels.
1380*4882a593Smuzhiyun  */
snd_hda_codec_amp_init_stereo(struct hda_codec * codec,hda_nid_t nid,int dir,int idx,int mask,int val)1381*4882a593Smuzhiyun int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid,
1382*4882a593Smuzhiyun 				  int dir, int idx, int mask, int val)
1383*4882a593Smuzhiyun {
1384*4882a593Smuzhiyun 	int ch, ret = 0;
1385*4882a593Smuzhiyun 
1386*4882a593Smuzhiyun 	if (snd_BUG_ON(mask & ~0xff))
1387*4882a593Smuzhiyun 		mask &= 0xff;
1388*4882a593Smuzhiyun 	for (ch = 0; ch < 2; ch++)
1389*4882a593Smuzhiyun 		ret |= snd_hda_codec_amp_init(codec, nid, ch, dir,
1390*4882a593Smuzhiyun 					      idx, mask, val);
1391*4882a593Smuzhiyun 	return ret;
1392*4882a593Smuzhiyun }
1393*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_amp_init_stereo);
1394*4882a593Smuzhiyun 
get_amp_max_value(struct hda_codec * codec,hda_nid_t nid,int dir,unsigned int ofs)1395*4882a593Smuzhiyun static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir,
1396*4882a593Smuzhiyun 			     unsigned int ofs)
1397*4882a593Smuzhiyun {
1398*4882a593Smuzhiyun 	u32 caps = query_amp_caps(codec, nid, dir);
1399*4882a593Smuzhiyun 	/* get num steps */
1400*4882a593Smuzhiyun 	caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
1401*4882a593Smuzhiyun 	if (ofs < caps)
1402*4882a593Smuzhiyun 		caps -= ofs;
1403*4882a593Smuzhiyun 	return caps;
1404*4882a593Smuzhiyun }
1405*4882a593Smuzhiyun 
1406*4882a593Smuzhiyun /**
1407*4882a593Smuzhiyun  * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer
1408*4882a593Smuzhiyun  * @kcontrol: referred ctl element
1409*4882a593Smuzhiyun  * @uinfo: pointer to get/store the data
1410*4882a593Smuzhiyun  *
1411*4882a593Smuzhiyun  * The control element is supposed to have the private_value field
1412*4882a593Smuzhiyun  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1413*4882a593Smuzhiyun  */
snd_hda_mixer_amp_volume_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)1414*4882a593Smuzhiyun int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
1415*4882a593Smuzhiyun 				  struct snd_ctl_elem_info *uinfo)
1416*4882a593Smuzhiyun {
1417*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1418*4882a593Smuzhiyun 	u16 nid = get_amp_nid(kcontrol);
1419*4882a593Smuzhiyun 	u8 chs = get_amp_channels(kcontrol);
1420*4882a593Smuzhiyun 	int dir = get_amp_direction(kcontrol);
1421*4882a593Smuzhiyun 	unsigned int ofs = get_amp_offset(kcontrol);
1422*4882a593Smuzhiyun 
1423*4882a593Smuzhiyun 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
1424*4882a593Smuzhiyun 	uinfo->count = chs == 3 ? 2 : 1;
1425*4882a593Smuzhiyun 	uinfo->value.integer.min = 0;
1426*4882a593Smuzhiyun 	uinfo->value.integer.max = get_amp_max_value(codec, nid, dir, ofs);
1427*4882a593Smuzhiyun 	if (!uinfo->value.integer.max) {
1428*4882a593Smuzhiyun 		codec_warn(codec,
1429*4882a593Smuzhiyun 			   "num_steps = 0 for NID=0x%x (ctl = %s)\n",
1430*4882a593Smuzhiyun 			   nid, kcontrol->id.name);
1431*4882a593Smuzhiyun 		return -EINVAL;
1432*4882a593Smuzhiyun 	}
1433*4882a593Smuzhiyun 	return 0;
1434*4882a593Smuzhiyun }
1435*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_info);
1436*4882a593Smuzhiyun 
1437*4882a593Smuzhiyun 
1438*4882a593Smuzhiyun static inline unsigned int
read_amp_value(struct hda_codec * codec,hda_nid_t nid,int ch,int dir,int idx,unsigned int ofs)1439*4882a593Smuzhiyun read_amp_value(struct hda_codec *codec, hda_nid_t nid,
1440*4882a593Smuzhiyun 	       int ch, int dir, int idx, unsigned int ofs)
1441*4882a593Smuzhiyun {
1442*4882a593Smuzhiyun 	unsigned int val;
1443*4882a593Smuzhiyun 	val = snd_hda_codec_amp_read(codec, nid, ch, dir, idx);
1444*4882a593Smuzhiyun 	val &= HDA_AMP_VOLMASK;
1445*4882a593Smuzhiyun 	if (val >= ofs)
1446*4882a593Smuzhiyun 		val -= ofs;
1447*4882a593Smuzhiyun 	else
1448*4882a593Smuzhiyun 		val = 0;
1449*4882a593Smuzhiyun 	return val;
1450*4882a593Smuzhiyun }
1451*4882a593Smuzhiyun 
1452*4882a593Smuzhiyun static inline int
update_amp_value(struct hda_codec * codec,hda_nid_t nid,int ch,int dir,int idx,unsigned int ofs,unsigned int val)1453*4882a593Smuzhiyun update_amp_value(struct hda_codec *codec, hda_nid_t nid,
1454*4882a593Smuzhiyun 		 int ch, int dir, int idx, unsigned int ofs,
1455*4882a593Smuzhiyun 		 unsigned int val)
1456*4882a593Smuzhiyun {
1457*4882a593Smuzhiyun 	unsigned int maxval;
1458*4882a593Smuzhiyun 
1459*4882a593Smuzhiyun 	if (val > 0)
1460*4882a593Smuzhiyun 		val += ofs;
1461*4882a593Smuzhiyun 	/* ofs = 0: raw max value */
1462*4882a593Smuzhiyun 	maxval = get_amp_max_value(codec, nid, dir, 0);
1463*4882a593Smuzhiyun 	if (val > maxval)
1464*4882a593Smuzhiyun 		val = maxval;
1465*4882a593Smuzhiyun 	return snd_hda_codec_amp_update(codec, nid, ch, dir, idx,
1466*4882a593Smuzhiyun 					HDA_AMP_VOLMASK, val);
1467*4882a593Smuzhiyun }
1468*4882a593Smuzhiyun 
1469*4882a593Smuzhiyun /**
1470*4882a593Smuzhiyun  * snd_hda_mixer_amp_volume_get - Get callback for a standard AMP mixer volume
1471*4882a593Smuzhiyun  * @kcontrol: ctl element
1472*4882a593Smuzhiyun  * @ucontrol: pointer to get/store the data
1473*4882a593Smuzhiyun  *
1474*4882a593Smuzhiyun  * The control element is supposed to have the private_value field
1475*4882a593Smuzhiyun  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1476*4882a593Smuzhiyun  */
snd_hda_mixer_amp_volume_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1477*4882a593Smuzhiyun int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
1478*4882a593Smuzhiyun 				 struct snd_ctl_elem_value *ucontrol)
1479*4882a593Smuzhiyun {
1480*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1481*4882a593Smuzhiyun 	hda_nid_t nid = get_amp_nid(kcontrol);
1482*4882a593Smuzhiyun 	int chs = get_amp_channels(kcontrol);
1483*4882a593Smuzhiyun 	int dir = get_amp_direction(kcontrol);
1484*4882a593Smuzhiyun 	int idx = get_amp_index(kcontrol);
1485*4882a593Smuzhiyun 	unsigned int ofs = get_amp_offset(kcontrol);
1486*4882a593Smuzhiyun 	long *valp = ucontrol->value.integer.value;
1487*4882a593Smuzhiyun 
1488*4882a593Smuzhiyun 	if (chs & 1)
1489*4882a593Smuzhiyun 		*valp++ = read_amp_value(codec, nid, 0, dir, idx, ofs);
1490*4882a593Smuzhiyun 	if (chs & 2)
1491*4882a593Smuzhiyun 		*valp = read_amp_value(codec, nid, 1, dir, idx, ofs);
1492*4882a593Smuzhiyun 	return 0;
1493*4882a593Smuzhiyun }
1494*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_get);
1495*4882a593Smuzhiyun 
1496*4882a593Smuzhiyun /**
1497*4882a593Smuzhiyun  * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume
1498*4882a593Smuzhiyun  * @kcontrol: ctl element
1499*4882a593Smuzhiyun  * @ucontrol: pointer to get/store the data
1500*4882a593Smuzhiyun  *
1501*4882a593Smuzhiyun  * The control element is supposed to have the private_value field
1502*4882a593Smuzhiyun  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1503*4882a593Smuzhiyun  */
snd_hda_mixer_amp_volume_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)1504*4882a593Smuzhiyun int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
1505*4882a593Smuzhiyun 				 struct snd_ctl_elem_value *ucontrol)
1506*4882a593Smuzhiyun {
1507*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1508*4882a593Smuzhiyun 	hda_nid_t nid = get_amp_nid(kcontrol);
1509*4882a593Smuzhiyun 	int chs = get_amp_channels(kcontrol);
1510*4882a593Smuzhiyun 	int dir = get_amp_direction(kcontrol);
1511*4882a593Smuzhiyun 	int idx = get_amp_index(kcontrol);
1512*4882a593Smuzhiyun 	unsigned int ofs = get_amp_offset(kcontrol);
1513*4882a593Smuzhiyun 	long *valp = ucontrol->value.integer.value;
1514*4882a593Smuzhiyun 	int change = 0;
1515*4882a593Smuzhiyun 
1516*4882a593Smuzhiyun 	if (chs & 1) {
1517*4882a593Smuzhiyun 		change = update_amp_value(codec, nid, 0, dir, idx, ofs, *valp);
1518*4882a593Smuzhiyun 		valp++;
1519*4882a593Smuzhiyun 	}
1520*4882a593Smuzhiyun 	if (chs & 2)
1521*4882a593Smuzhiyun 		change |= update_amp_value(codec, nid, 1, dir, idx, ofs, *valp);
1522*4882a593Smuzhiyun 	return change;
1523*4882a593Smuzhiyun }
1524*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_put);
1525*4882a593Smuzhiyun 
1526*4882a593Smuzhiyun /* inquiry the amp caps and convert to TLV */
get_ctl_amp_tlv(struct snd_kcontrol * kcontrol,unsigned int * tlv)1527*4882a593Smuzhiyun static void get_ctl_amp_tlv(struct snd_kcontrol *kcontrol, unsigned int *tlv)
1528*4882a593Smuzhiyun {
1529*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
1530*4882a593Smuzhiyun 	hda_nid_t nid = get_amp_nid(kcontrol);
1531*4882a593Smuzhiyun 	int dir = get_amp_direction(kcontrol);
1532*4882a593Smuzhiyun 	unsigned int ofs = get_amp_offset(kcontrol);
1533*4882a593Smuzhiyun 	bool min_mute = get_amp_min_mute(kcontrol);
1534*4882a593Smuzhiyun 	u32 caps, val1, val2;
1535*4882a593Smuzhiyun 
1536*4882a593Smuzhiyun 	caps = query_amp_caps(codec, nid, dir);
1537*4882a593Smuzhiyun 	val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
1538*4882a593Smuzhiyun 	val2 = (val2 + 1) * 25;
1539*4882a593Smuzhiyun 	val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
1540*4882a593Smuzhiyun 	val1 += ofs;
1541*4882a593Smuzhiyun 	val1 = ((int)val1) * ((int)val2);
1542*4882a593Smuzhiyun 	if (min_mute || (caps & AC_AMPCAP_MIN_MUTE))
1543*4882a593Smuzhiyun 		val2 |= TLV_DB_SCALE_MUTE;
1544*4882a593Smuzhiyun 	tlv[SNDRV_CTL_TLVO_TYPE] = SNDRV_CTL_TLVT_DB_SCALE;
1545*4882a593Smuzhiyun 	tlv[SNDRV_CTL_TLVO_LEN] = 2 * sizeof(unsigned int);
1546*4882a593Smuzhiyun 	tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] = val1;
1547*4882a593Smuzhiyun 	tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] = val2;
1548*4882a593Smuzhiyun }
1549*4882a593Smuzhiyun 
1550*4882a593Smuzhiyun /**
1551*4882a593Smuzhiyun  * snd_hda_mixer_amp_tlv - TLV callback for a standard AMP mixer volume
1552*4882a593Smuzhiyun  * @kcontrol: ctl element
1553*4882a593Smuzhiyun  * @op_flag: operation flag
1554*4882a593Smuzhiyun  * @size: byte size of input TLV
1555*4882a593Smuzhiyun  * @_tlv: TLV data
1556*4882a593Smuzhiyun  *
1557*4882a593Smuzhiyun  * The control element is supposed to have the private_value field
1558*4882a593Smuzhiyun  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
1559*4882a593Smuzhiyun  */
snd_hda_mixer_amp_tlv(struct snd_kcontrol * kcontrol,int op_flag,unsigned int size,unsigned int __user * _tlv)1560*4882a593Smuzhiyun int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
1561*4882a593Smuzhiyun 			  unsigned int size, unsigned int __user *_tlv)
1562*4882a593Smuzhiyun {
1563*4882a593Smuzhiyun 	unsigned int tlv[4];
1564*4882a593Smuzhiyun 
1565*4882a593Smuzhiyun 	if (size < 4 * sizeof(unsigned int))
1566*4882a593Smuzhiyun 		return -ENOMEM;
1567*4882a593Smuzhiyun 	get_ctl_amp_tlv(kcontrol, tlv);
1568*4882a593Smuzhiyun 	if (copy_to_user(_tlv, tlv, sizeof(tlv)))
1569*4882a593Smuzhiyun 		return -EFAULT;
1570*4882a593Smuzhiyun 	return 0;
1571*4882a593Smuzhiyun }
1572*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_tlv);
1573*4882a593Smuzhiyun 
1574*4882a593Smuzhiyun /**
1575*4882a593Smuzhiyun  * snd_hda_set_vmaster_tlv - Set TLV for a virtual master control
1576*4882a593Smuzhiyun  * @codec: HD-audio codec
1577*4882a593Smuzhiyun  * @nid: NID of a reference widget
1578*4882a593Smuzhiyun  * @dir: #HDA_INPUT or #HDA_OUTPUT
1579*4882a593Smuzhiyun  * @tlv: TLV data to be stored, at least 4 elements
1580*4882a593Smuzhiyun  *
1581*4882a593Smuzhiyun  * Set (static) TLV data for a virtual master volume using the AMP caps
1582*4882a593Smuzhiyun  * obtained from the reference NID.
1583*4882a593Smuzhiyun  * The volume range is recalculated as if the max volume is 0dB.
1584*4882a593Smuzhiyun  */
snd_hda_set_vmaster_tlv(struct hda_codec * codec,hda_nid_t nid,int dir,unsigned int * tlv)1585*4882a593Smuzhiyun void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
1586*4882a593Smuzhiyun 			     unsigned int *tlv)
1587*4882a593Smuzhiyun {
1588*4882a593Smuzhiyun 	u32 caps;
1589*4882a593Smuzhiyun 	int nums, step;
1590*4882a593Smuzhiyun 
1591*4882a593Smuzhiyun 	caps = query_amp_caps(codec, nid, dir);
1592*4882a593Smuzhiyun 	nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
1593*4882a593Smuzhiyun 	step = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
1594*4882a593Smuzhiyun 	step = (step + 1) * 25;
1595*4882a593Smuzhiyun 	tlv[SNDRV_CTL_TLVO_TYPE] = SNDRV_CTL_TLVT_DB_SCALE;
1596*4882a593Smuzhiyun 	tlv[SNDRV_CTL_TLVO_LEN] = 2 * sizeof(unsigned int);
1597*4882a593Smuzhiyun 	tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] = -nums * step;
1598*4882a593Smuzhiyun 	tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] = step;
1599*4882a593Smuzhiyun }
1600*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_set_vmaster_tlv);
1601*4882a593Smuzhiyun 
1602*4882a593Smuzhiyun /* find a mixer control element with the given name */
1603*4882a593Smuzhiyun static struct snd_kcontrol *
find_mixer_ctl(struct hda_codec * codec,const char * name,int dev,int idx)1604*4882a593Smuzhiyun find_mixer_ctl(struct hda_codec *codec, const char *name, int dev, int idx)
1605*4882a593Smuzhiyun {
1606*4882a593Smuzhiyun 	struct snd_ctl_elem_id id;
1607*4882a593Smuzhiyun 	memset(&id, 0, sizeof(id));
1608*4882a593Smuzhiyun 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1609*4882a593Smuzhiyun 	id.device = dev;
1610*4882a593Smuzhiyun 	id.index = idx;
1611*4882a593Smuzhiyun 	if (snd_BUG_ON(strlen(name) >= sizeof(id.name)))
1612*4882a593Smuzhiyun 		return NULL;
1613*4882a593Smuzhiyun 	strcpy(id.name, name);
1614*4882a593Smuzhiyun 	return snd_ctl_find_id(codec->card, &id);
1615*4882a593Smuzhiyun }
1616*4882a593Smuzhiyun 
1617*4882a593Smuzhiyun /**
1618*4882a593Smuzhiyun  * snd_hda_find_mixer_ctl - Find a mixer control element with the given name
1619*4882a593Smuzhiyun  * @codec: HD-audio codec
1620*4882a593Smuzhiyun  * @name: ctl id name string
1621*4882a593Smuzhiyun  *
1622*4882a593Smuzhiyun  * Get the control element with the given id string and IFACE_MIXER.
1623*4882a593Smuzhiyun  */
snd_hda_find_mixer_ctl(struct hda_codec * codec,const char * name)1624*4882a593Smuzhiyun struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1625*4882a593Smuzhiyun 					    const char *name)
1626*4882a593Smuzhiyun {
1627*4882a593Smuzhiyun 	return find_mixer_ctl(codec, name, 0, 0);
1628*4882a593Smuzhiyun }
1629*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_find_mixer_ctl);
1630*4882a593Smuzhiyun 
find_empty_mixer_ctl_idx(struct hda_codec * codec,const char * name,int start_idx)1631*4882a593Smuzhiyun static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name,
1632*4882a593Smuzhiyun 				    int start_idx)
1633*4882a593Smuzhiyun {
1634*4882a593Smuzhiyun 	int i, idx;
1635*4882a593Smuzhiyun 	/* 16 ctlrs should be large enough */
1636*4882a593Smuzhiyun 	for (i = 0, idx = start_idx; i < 16; i++, idx++) {
1637*4882a593Smuzhiyun 		if (!find_mixer_ctl(codec, name, 0, idx))
1638*4882a593Smuzhiyun 			return idx;
1639*4882a593Smuzhiyun 	}
1640*4882a593Smuzhiyun 	return -EBUSY;
1641*4882a593Smuzhiyun }
1642*4882a593Smuzhiyun 
1643*4882a593Smuzhiyun /**
1644*4882a593Smuzhiyun  * snd_hda_ctl_add - Add a control element and assign to the codec
1645*4882a593Smuzhiyun  * @codec: HD-audio codec
1646*4882a593Smuzhiyun  * @nid: corresponding NID (optional)
1647*4882a593Smuzhiyun  * @kctl: the control element to assign
1648*4882a593Smuzhiyun  *
1649*4882a593Smuzhiyun  * Add the given control element to an array inside the codec instance.
1650*4882a593Smuzhiyun  * All control elements belonging to a codec are supposed to be added
1651*4882a593Smuzhiyun  * by this function so that a proper clean-up works at the free or
1652*4882a593Smuzhiyun  * reconfiguration time.
1653*4882a593Smuzhiyun  *
1654*4882a593Smuzhiyun  * If non-zero @nid is passed, the NID is assigned to the control element.
1655*4882a593Smuzhiyun  * The assignment is shown in the codec proc file.
1656*4882a593Smuzhiyun  *
1657*4882a593Smuzhiyun  * snd_hda_ctl_add() checks the control subdev id field whether
1658*4882a593Smuzhiyun  * #HDA_SUBDEV_NID_FLAG bit is set.  If set (and @nid is zero), the lower
1659*4882a593Smuzhiyun  * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit
1660*4882a593Smuzhiyun  * specifies if kctl->private_value is a HDA amplifier value.
1661*4882a593Smuzhiyun  */
snd_hda_ctl_add(struct hda_codec * codec,hda_nid_t nid,struct snd_kcontrol * kctl)1662*4882a593Smuzhiyun int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
1663*4882a593Smuzhiyun 		    struct snd_kcontrol *kctl)
1664*4882a593Smuzhiyun {
1665*4882a593Smuzhiyun 	int err;
1666*4882a593Smuzhiyun 	unsigned short flags = 0;
1667*4882a593Smuzhiyun 	struct hda_nid_item *item;
1668*4882a593Smuzhiyun 
1669*4882a593Smuzhiyun 	if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) {
1670*4882a593Smuzhiyun 		flags |= HDA_NID_ITEM_AMP;
1671*4882a593Smuzhiyun 		if (nid == 0)
1672*4882a593Smuzhiyun 			nid = get_amp_nid_(kctl->private_value);
1673*4882a593Smuzhiyun 	}
1674*4882a593Smuzhiyun 	if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0)
1675*4882a593Smuzhiyun 		nid = kctl->id.subdevice & 0xffff;
1676*4882a593Smuzhiyun 	if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG))
1677*4882a593Smuzhiyun 		kctl->id.subdevice = 0;
1678*4882a593Smuzhiyun 	err = snd_ctl_add(codec->card, kctl);
1679*4882a593Smuzhiyun 	if (err < 0)
1680*4882a593Smuzhiyun 		return err;
1681*4882a593Smuzhiyun 	item = snd_array_new(&codec->mixers);
1682*4882a593Smuzhiyun 	if (!item)
1683*4882a593Smuzhiyun 		return -ENOMEM;
1684*4882a593Smuzhiyun 	item->kctl = kctl;
1685*4882a593Smuzhiyun 	item->nid = nid;
1686*4882a593Smuzhiyun 	item->flags = flags;
1687*4882a593Smuzhiyun 	return 0;
1688*4882a593Smuzhiyun }
1689*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_ctl_add);
1690*4882a593Smuzhiyun 
1691*4882a593Smuzhiyun /**
1692*4882a593Smuzhiyun  * snd_hda_add_nid - Assign a NID to a control element
1693*4882a593Smuzhiyun  * @codec: HD-audio codec
1694*4882a593Smuzhiyun  * @nid: corresponding NID (optional)
1695*4882a593Smuzhiyun  * @kctl: the control element to assign
1696*4882a593Smuzhiyun  * @index: index to kctl
1697*4882a593Smuzhiyun  *
1698*4882a593Smuzhiyun  * Add the given control element to an array inside the codec instance.
1699*4882a593Smuzhiyun  * This function is used when #snd_hda_ctl_add cannot be used for 1:1
1700*4882a593Smuzhiyun  * NID:KCTL mapping - for example "Capture Source" selector.
1701*4882a593Smuzhiyun  */
snd_hda_add_nid(struct hda_codec * codec,struct snd_kcontrol * kctl,unsigned int index,hda_nid_t nid)1702*4882a593Smuzhiyun int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
1703*4882a593Smuzhiyun 		    unsigned int index, hda_nid_t nid)
1704*4882a593Smuzhiyun {
1705*4882a593Smuzhiyun 	struct hda_nid_item *item;
1706*4882a593Smuzhiyun 
1707*4882a593Smuzhiyun 	if (nid > 0) {
1708*4882a593Smuzhiyun 		item = snd_array_new(&codec->nids);
1709*4882a593Smuzhiyun 		if (!item)
1710*4882a593Smuzhiyun 			return -ENOMEM;
1711*4882a593Smuzhiyun 		item->kctl = kctl;
1712*4882a593Smuzhiyun 		item->index = index;
1713*4882a593Smuzhiyun 		item->nid = nid;
1714*4882a593Smuzhiyun 		return 0;
1715*4882a593Smuzhiyun 	}
1716*4882a593Smuzhiyun 	codec_err(codec, "no NID for mapping control %s:%d:%d\n",
1717*4882a593Smuzhiyun 		  kctl->id.name, kctl->id.index, index);
1718*4882a593Smuzhiyun 	return -EINVAL;
1719*4882a593Smuzhiyun }
1720*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_add_nid);
1721*4882a593Smuzhiyun 
1722*4882a593Smuzhiyun /**
1723*4882a593Smuzhiyun  * snd_hda_ctls_clear - Clear all controls assigned to the given codec
1724*4882a593Smuzhiyun  * @codec: HD-audio codec
1725*4882a593Smuzhiyun  */
snd_hda_ctls_clear(struct hda_codec * codec)1726*4882a593Smuzhiyun void snd_hda_ctls_clear(struct hda_codec *codec)
1727*4882a593Smuzhiyun {
1728*4882a593Smuzhiyun 	int i;
1729*4882a593Smuzhiyun 	struct hda_nid_item *items = codec->mixers.list;
1730*4882a593Smuzhiyun 
1731*4882a593Smuzhiyun 	down_write(&codec->card->controls_rwsem);
1732*4882a593Smuzhiyun 	for (i = 0; i < codec->mixers.used; i++)
1733*4882a593Smuzhiyun 		snd_ctl_remove(codec->card, items[i].kctl);
1734*4882a593Smuzhiyun 	up_write(&codec->card->controls_rwsem);
1735*4882a593Smuzhiyun 	snd_array_free(&codec->mixers);
1736*4882a593Smuzhiyun 	snd_array_free(&codec->nids);
1737*4882a593Smuzhiyun }
1738*4882a593Smuzhiyun 
1739*4882a593Smuzhiyun /**
1740*4882a593Smuzhiyun  * snd_hda_lock_devices - pseudo device locking
1741*4882a593Smuzhiyun  * @bus: the BUS
1742*4882a593Smuzhiyun  *
1743*4882a593Smuzhiyun  * toggle card->shutdown to allow/disallow the device access (as a hack)
1744*4882a593Smuzhiyun  */
snd_hda_lock_devices(struct hda_bus * bus)1745*4882a593Smuzhiyun int snd_hda_lock_devices(struct hda_bus *bus)
1746*4882a593Smuzhiyun {
1747*4882a593Smuzhiyun 	struct snd_card *card = bus->card;
1748*4882a593Smuzhiyun 	struct hda_codec *codec;
1749*4882a593Smuzhiyun 
1750*4882a593Smuzhiyun 	spin_lock(&card->files_lock);
1751*4882a593Smuzhiyun 	if (card->shutdown)
1752*4882a593Smuzhiyun 		goto err_unlock;
1753*4882a593Smuzhiyun 	card->shutdown = 1;
1754*4882a593Smuzhiyun 	if (!list_empty(&card->ctl_files))
1755*4882a593Smuzhiyun 		goto err_clear;
1756*4882a593Smuzhiyun 
1757*4882a593Smuzhiyun 	list_for_each_codec(codec, bus) {
1758*4882a593Smuzhiyun 		struct hda_pcm *cpcm;
1759*4882a593Smuzhiyun 		list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
1760*4882a593Smuzhiyun 			if (!cpcm->pcm)
1761*4882a593Smuzhiyun 				continue;
1762*4882a593Smuzhiyun 			if (cpcm->pcm->streams[0].substream_opened ||
1763*4882a593Smuzhiyun 			    cpcm->pcm->streams[1].substream_opened)
1764*4882a593Smuzhiyun 				goto err_clear;
1765*4882a593Smuzhiyun 		}
1766*4882a593Smuzhiyun 	}
1767*4882a593Smuzhiyun 	spin_unlock(&card->files_lock);
1768*4882a593Smuzhiyun 	return 0;
1769*4882a593Smuzhiyun 
1770*4882a593Smuzhiyun  err_clear:
1771*4882a593Smuzhiyun 	card->shutdown = 0;
1772*4882a593Smuzhiyun  err_unlock:
1773*4882a593Smuzhiyun 	spin_unlock(&card->files_lock);
1774*4882a593Smuzhiyun 	return -EINVAL;
1775*4882a593Smuzhiyun }
1776*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_lock_devices);
1777*4882a593Smuzhiyun 
1778*4882a593Smuzhiyun /**
1779*4882a593Smuzhiyun  * snd_hda_unlock_devices - pseudo device unlocking
1780*4882a593Smuzhiyun  * @bus: the BUS
1781*4882a593Smuzhiyun  */
snd_hda_unlock_devices(struct hda_bus * bus)1782*4882a593Smuzhiyun void snd_hda_unlock_devices(struct hda_bus *bus)
1783*4882a593Smuzhiyun {
1784*4882a593Smuzhiyun 	struct snd_card *card = bus->card;
1785*4882a593Smuzhiyun 
1786*4882a593Smuzhiyun 	spin_lock(&card->files_lock);
1787*4882a593Smuzhiyun 	card->shutdown = 0;
1788*4882a593Smuzhiyun 	spin_unlock(&card->files_lock);
1789*4882a593Smuzhiyun }
1790*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_unlock_devices);
1791*4882a593Smuzhiyun 
1792*4882a593Smuzhiyun /**
1793*4882a593Smuzhiyun  * snd_hda_codec_reset - Clear all objects assigned to the codec
1794*4882a593Smuzhiyun  * @codec: HD-audio codec
1795*4882a593Smuzhiyun  *
1796*4882a593Smuzhiyun  * This frees the all PCM and control elements assigned to the codec, and
1797*4882a593Smuzhiyun  * clears the caches and restores the pin default configurations.
1798*4882a593Smuzhiyun  *
1799*4882a593Smuzhiyun  * When a device is being used, it returns -EBSY.  If successfully freed,
1800*4882a593Smuzhiyun  * returns zero.
1801*4882a593Smuzhiyun  */
snd_hda_codec_reset(struct hda_codec * codec)1802*4882a593Smuzhiyun int snd_hda_codec_reset(struct hda_codec *codec)
1803*4882a593Smuzhiyun {
1804*4882a593Smuzhiyun 	struct hda_bus *bus = codec->bus;
1805*4882a593Smuzhiyun 
1806*4882a593Smuzhiyun 	if (snd_hda_lock_devices(bus) < 0)
1807*4882a593Smuzhiyun 		return -EBUSY;
1808*4882a593Smuzhiyun 
1809*4882a593Smuzhiyun 	/* OK, let it free */
1810*4882a593Smuzhiyun 	device_release_driver(hda_codec_dev(codec));
1811*4882a593Smuzhiyun 
1812*4882a593Smuzhiyun 	/* allow device access again */
1813*4882a593Smuzhiyun 	snd_hda_unlock_devices(bus);
1814*4882a593Smuzhiyun 	return 0;
1815*4882a593Smuzhiyun }
1816*4882a593Smuzhiyun 
1817*4882a593Smuzhiyun typedef int (*map_follower_func_t)(struct hda_codec *, void *, struct snd_kcontrol *);
1818*4882a593Smuzhiyun 
1819*4882a593Smuzhiyun /* apply the function to all matching follower ctls in the mixer list */
map_followers(struct hda_codec * codec,const char * const * followers,const char * suffix,map_follower_func_t func,void * data)1820*4882a593Smuzhiyun static int map_followers(struct hda_codec *codec, const char * const *followers,
1821*4882a593Smuzhiyun 			 const char *suffix, map_follower_func_t func, void *data)
1822*4882a593Smuzhiyun {
1823*4882a593Smuzhiyun 	struct hda_nid_item *items;
1824*4882a593Smuzhiyun 	const char * const *s;
1825*4882a593Smuzhiyun 	int i, err;
1826*4882a593Smuzhiyun 
1827*4882a593Smuzhiyun 	items = codec->mixers.list;
1828*4882a593Smuzhiyun 	for (i = 0; i < codec->mixers.used; i++) {
1829*4882a593Smuzhiyun 		struct snd_kcontrol *sctl = items[i].kctl;
1830*4882a593Smuzhiyun 		if (!sctl || sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
1831*4882a593Smuzhiyun 			continue;
1832*4882a593Smuzhiyun 		for (s = followers; *s; s++) {
1833*4882a593Smuzhiyun 			char tmpname[sizeof(sctl->id.name)];
1834*4882a593Smuzhiyun 			const char *name = *s;
1835*4882a593Smuzhiyun 			if (suffix) {
1836*4882a593Smuzhiyun 				snprintf(tmpname, sizeof(tmpname), "%s %s",
1837*4882a593Smuzhiyun 					 name, suffix);
1838*4882a593Smuzhiyun 				name = tmpname;
1839*4882a593Smuzhiyun 			}
1840*4882a593Smuzhiyun 			if (!strcmp(sctl->id.name, name)) {
1841*4882a593Smuzhiyun 				err = func(codec, data, sctl);
1842*4882a593Smuzhiyun 				if (err)
1843*4882a593Smuzhiyun 					return err;
1844*4882a593Smuzhiyun 				break;
1845*4882a593Smuzhiyun 			}
1846*4882a593Smuzhiyun 		}
1847*4882a593Smuzhiyun 	}
1848*4882a593Smuzhiyun 	return 0;
1849*4882a593Smuzhiyun }
1850*4882a593Smuzhiyun 
check_follower_present(struct hda_codec * codec,void * data,struct snd_kcontrol * sctl)1851*4882a593Smuzhiyun static int check_follower_present(struct hda_codec *codec,
1852*4882a593Smuzhiyun 				  void *data, struct snd_kcontrol *sctl)
1853*4882a593Smuzhiyun {
1854*4882a593Smuzhiyun 	return 1;
1855*4882a593Smuzhiyun }
1856*4882a593Smuzhiyun 
1857*4882a593Smuzhiyun /* call kctl->put with the given value(s) */
put_kctl_with_value(struct snd_kcontrol * kctl,int val)1858*4882a593Smuzhiyun static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
1859*4882a593Smuzhiyun {
1860*4882a593Smuzhiyun 	struct snd_ctl_elem_value *ucontrol;
1861*4882a593Smuzhiyun 	ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL);
1862*4882a593Smuzhiyun 	if (!ucontrol)
1863*4882a593Smuzhiyun 		return -ENOMEM;
1864*4882a593Smuzhiyun 	ucontrol->value.integer.value[0] = val;
1865*4882a593Smuzhiyun 	ucontrol->value.integer.value[1] = val;
1866*4882a593Smuzhiyun 	kctl->put(kctl, ucontrol);
1867*4882a593Smuzhiyun 	kfree(ucontrol);
1868*4882a593Smuzhiyun 	return 0;
1869*4882a593Smuzhiyun }
1870*4882a593Smuzhiyun 
1871*4882a593Smuzhiyun struct follower_init_arg {
1872*4882a593Smuzhiyun 	struct hda_codec *codec;
1873*4882a593Smuzhiyun 	int step;
1874*4882a593Smuzhiyun };
1875*4882a593Smuzhiyun 
1876*4882a593Smuzhiyun /* initialize the follower volume with 0dB via snd_ctl_apply_vmaster_followers() */
init_follower_0dB(struct snd_kcontrol * follower,struct snd_kcontrol * kctl,void * _arg)1877*4882a593Smuzhiyun static int init_follower_0dB(struct snd_kcontrol *follower,
1878*4882a593Smuzhiyun 			     struct snd_kcontrol *kctl,
1879*4882a593Smuzhiyun 			     void *_arg)
1880*4882a593Smuzhiyun {
1881*4882a593Smuzhiyun 	struct follower_init_arg *arg = _arg;
1882*4882a593Smuzhiyun 	int _tlv[4];
1883*4882a593Smuzhiyun 	const int *tlv = NULL;
1884*4882a593Smuzhiyun 	int step;
1885*4882a593Smuzhiyun 	int val;
1886*4882a593Smuzhiyun 
1887*4882a593Smuzhiyun 	if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
1888*4882a593Smuzhiyun 		if (kctl->tlv.c != snd_hda_mixer_amp_tlv) {
1889*4882a593Smuzhiyun 			codec_err(arg->codec,
1890*4882a593Smuzhiyun 				  "Unexpected TLV callback for follower %s:%d\n",
1891*4882a593Smuzhiyun 				  kctl->id.name, kctl->id.index);
1892*4882a593Smuzhiyun 			return 0; /* ignore */
1893*4882a593Smuzhiyun 		}
1894*4882a593Smuzhiyun 		get_ctl_amp_tlv(kctl, _tlv);
1895*4882a593Smuzhiyun 		tlv = _tlv;
1896*4882a593Smuzhiyun 	} else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
1897*4882a593Smuzhiyun 		tlv = kctl->tlv.p;
1898*4882a593Smuzhiyun 
1899*4882a593Smuzhiyun 	if (!tlv || tlv[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE)
1900*4882a593Smuzhiyun 		return 0;
1901*4882a593Smuzhiyun 
1902*4882a593Smuzhiyun 	step = tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP];
1903*4882a593Smuzhiyun 	step &= ~TLV_DB_SCALE_MUTE;
1904*4882a593Smuzhiyun 	if (!step)
1905*4882a593Smuzhiyun 		return 0;
1906*4882a593Smuzhiyun 	if (arg->step && arg->step != step) {
1907*4882a593Smuzhiyun 		codec_err(arg->codec,
1908*4882a593Smuzhiyun 			  "Mismatching dB step for vmaster follower (%d!=%d)\n",
1909*4882a593Smuzhiyun 			  arg->step, step);
1910*4882a593Smuzhiyun 		return 0;
1911*4882a593Smuzhiyun 	}
1912*4882a593Smuzhiyun 
1913*4882a593Smuzhiyun 	arg->step = step;
1914*4882a593Smuzhiyun 	val = -tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] / step;
1915*4882a593Smuzhiyun 	if (val > 0) {
1916*4882a593Smuzhiyun 		put_kctl_with_value(follower, val);
1917*4882a593Smuzhiyun 		return val;
1918*4882a593Smuzhiyun 	}
1919*4882a593Smuzhiyun 
1920*4882a593Smuzhiyun 	return 0;
1921*4882a593Smuzhiyun }
1922*4882a593Smuzhiyun 
1923*4882a593Smuzhiyun /* unmute the follower via snd_ctl_apply_vmaster_followers() */
init_follower_unmute(struct snd_kcontrol * follower,struct snd_kcontrol * kctl,void * _arg)1924*4882a593Smuzhiyun static int init_follower_unmute(struct snd_kcontrol *follower,
1925*4882a593Smuzhiyun 				struct snd_kcontrol *kctl,
1926*4882a593Smuzhiyun 				void *_arg)
1927*4882a593Smuzhiyun {
1928*4882a593Smuzhiyun 	return put_kctl_with_value(follower, 1);
1929*4882a593Smuzhiyun }
1930*4882a593Smuzhiyun 
add_follower(struct hda_codec * codec,void * data,struct snd_kcontrol * follower)1931*4882a593Smuzhiyun static int add_follower(struct hda_codec *codec,
1932*4882a593Smuzhiyun 			void *data, struct snd_kcontrol *follower)
1933*4882a593Smuzhiyun {
1934*4882a593Smuzhiyun 	return snd_ctl_add_follower(data, follower);
1935*4882a593Smuzhiyun }
1936*4882a593Smuzhiyun 
1937*4882a593Smuzhiyun /**
1938*4882a593Smuzhiyun  * __snd_hda_add_vmaster - create a virtual master control and add followers
1939*4882a593Smuzhiyun  * @codec: HD-audio codec
1940*4882a593Smuzhiyun  * @name: vmaster control name
1941*4882a593Smuzhiyun  * @tlv: TLV data (optional)
1942*4882a593Smuzhiyun  * @followers: follower control names (optional)
1943*4882a593Smuzhiyun  * @suffix: suffix string to each follower name (optional)
1944*4882a593Smuzhiyun  * @init_follower_vol: initialize followers to unmute/0dB
1945*4882a593Smuzhiyun  * @ctl_ret: store the vmaster kcontrol in return
1946*4882a593Smuzhiyun  *
1947*4882a593Smuzhiyun  * Create a virtual master control with the given name.  The TLV data
1948*4882a593Smuzhiyun  * must be either NULL or a valid data.
1949*4882a593Smuzhiyun  *
1950*4882a593Smuzhiyun  * @followers is a NULL-terminated array of strings, each of which is a
1951*4882a593Smuzhiyun  * follower control name.  All controls with these names are assigned to
1952*4882a593Smuzhiyun  * the new virtual master control.
1953*4882a593Smuzhiyun  *
1954*4882a593Smuzhiyun  * This function returns zero if successful or a negative error code.
1955*4882a593Smuzhiyun  */
__snd_hda_add_vmaster(struct hda_codec * codec,char * name,unsigned int * tlv,const char * const * followers,const char * suffix,bool init_follower_vol,struct snd_kcontrol ** ctl_ret)1956*4882a593Smuzhiyun int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1957*4882a593Smuzhiyun 			  unsigned int *tlv, const char * const *followers,
1958*4882a593Smuzhiyun 			  const char *suffix, bool init_follower_vol,
1959*4882a593Smuzhiyun 			  struct snd_kcontrol **ctl_ret)
1960*4882a593Smuzhiyun {
1961*4882a593Smuzhiyun 	struct snd_kcontrol *kctl;
1962*4882a593Smuzhiyun 	int err;
1963*4882a593Smuzhiyun 
1964*4882a593Smuzhiyun 	if (ctl_ret)
1965*4882a593Smuzhiyun 		*ctl_ret = NULL;
1966*4882a593Smuzhiyun 
1967*4882a593Smuzhiyun 	err = map_followers(codec, followers, suffix, check_follower_present, NULL);
1968*4882a593Smuzhiyun 	if (err != 1) {
1969*4882a593Smuzhiyun 		codec_dbg(codec, "No follower found for %s\n", name);
1970*4882a593Smuzhiyun 		return 0;
1971*4882a593Smuzhiyun 	}
1972*4882a593Smuzhiyun 	kctl = snd_ctl_make_virtual_master(name, tlv);
1973*4882a593Smuzhiyun 	if (!kctl)
1974*4882a593Smuzhiyun 		return -ENOMEM;
1975*4882a593Smuzhiyun 	err = snd_hda_ctl_add(codec, 0, kctl);
1976*4882a593Smuzhiyun 	if (err < 0)
1977*4882a593Smuzhiyun 		return err;
1978*4882a593Smuzhiyun 
1979*4882a593Smuzhiyun 	err = map_followers(codec, followers, suffix, add_follower, kctl);
1980*4882a593Smuzhiyun 	if (err < 0)
1981*4882a593Smuzhiyun 		return err;
1982*4882a593Smuzhiyun 
1983*4882a593Smuzhiyun 	/* init with master mute & zero volume */
1984*4882a593Smuzhiyun 	put_kctl_with_value(kctl, 0);
1985*4882a593Smuzhiyun 	if (init_follower_vol) {
1986*4882a593Smuzhiyun 		struct follower_init_arg arg = {
1987*4882a593Smuzhiyun 			.codec = codec,
1988*4882a593Smuzhiyun 			.step = 0,
1989*4882a593Smuzhiyun 		};
1990*4882a593Smuzhiyun 		snd_ctl_apply_vmaster_followers(kctl,
1991*4882a593Smuzhiyun 						tlv ? init_follower_0dB : init_follower_unmute,
1992*4882a593Smuzhiyun 						&arg);
1993*4882a593Smuzhiyun 	}
1994*4882a593Smuzhiyun 
1995*4882a593Smuzhiyun 	if (ctl_ret)
1996*4882a593Smuzhiyun 		*ctl_ret = kctl;
1997*4882a593Smuzhiyun 	return 0;
1998*4882a593Smuzhiyun }
1999*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(__snd_hda_add_vmaster);
2000*4882a593Smuzhiyun 
2001*4882a593Smuzhiyun /*
2002*4882a593Smuzhiyun  * mute-LED control using vmaster
2003*4882a593Smuzhiyun  */
vmaster_mute_mode_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2004*4882a593Smuzhiyun static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol,
2005*4882a593Smuzhiyun 				  struct snd_ctl_elem_info *uinfo)
2006*4882a593Smuzhiyun {
2007*4882a593Smuzhiyun 	static const char * const texts[] = {
2008*4882a593Smuzhiyun 		"On", "Off", "Follow Master"
2009*4882a593Smuzhiyun 	};
2010*4882a593Smuzhiyun 
2011*4882a593Smuzhiyun 	return snd_ctl_enum_info(uinfo, 1, 3, texts);
2012*4882a593Smuzhiyun }
2013*4882a593Smuzhiyun 
vmaster_mute_mode_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2014*4882a593Smuzhiyun static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol,
2015*4882a593Smuzhiyun 				 struct snd_ctl_elem_value *ucontrol)
2016*4882a593Smuzhiyun {
2017*4882a593Smuzhiyun 	struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
2018*4882a593Smuzhiyun 	ucontrol->value.enumerated.item[0] = hook->mute_mode;
2019*4882a593Smuzhiyun 	return 0;
2020*4882a593Smuzhiyun }
2021*4882a593Smuzhiyun 
vmaster_mute_mode_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2022*4882a593Smuzhiyun static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
2023*4882a593Smuzhiyun 				 struct snd_ctl_elem_value *ucontrol)
2024*4882a593Smuzhiyun {
2025*4882a593Smuzhiyun 	struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
2026*4882a593Smuzhiyun 	unsigned int old_mode = hook->mute_mode;
2027*4882a593Smuzhiyun 
2028*4882a593Smuzhiyun 	hook->mute_mode = ucontrol->value.enumerated.item[0];
2029*4882a593Smuzhiyun 	if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER)
2030*4882a593Smuzhiyun 		hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
2031*4882a593Smuzhiyun 	if (old_mode == hook->mute_mode)
2032*4882a593Smuzhiyun 		return 0;
2033*4882a593Smuzhiyun 	snd_hda_sync_vmaster_hook(hook);
2034*4882a593Smuzhiyun 	return 1;
2035*4882a593Smuzhiyun }
2036*4882a593Smuzhiyun 
2037*4882a593Smuzhiyun static const struct snd_kcontrol_new vmaster_mute_mode = {
2038*4882a593Smuzhiyun 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2039*4882a593Smuzhiyun 	.name = "Mute-LED Mode",
2040*4882a593Smuzhiyun 	.info = vmaster_mute_mode_info,
2041*4882a593Smuzhiyun 	.get = vmaster_mute_mode_get,
2042*4882a593Smuzhiyun 	.put = vmaster_mute_mode_put,
2043*4882a593Smuzhiyun };
2044*4882a593Smuzhiyun 
2045*4882a593Smuzhiyun /* meta hook to call each driver's vmaster hook */
vmaster_hook(void * private_data,int enabled)2046*4882a593Smuzhiyun static void vmaster_hook(void *private_data, int enabled)
2047*4882a593Smuzhiyun {
2048*4882a593Smuzhiyun 	struct hda_vmaster_mute_hook *hook = private_data;
2049*4882a593Smuzhiyun 
2050*4882a593Smuzhiyun 	if (hook->mute_mode != HDA_VMUTE_FOLLOW_MASTER)
2051*4882a593Smuzhiyun 		enabled = hook->mute_mode;
2052*4882a593Smuzhiyun 	hook->hook(hook->codec, enabled);
2053*4882a593Smuzhiyun }
2054*4882a593Smuzhiyun 
2055*4882a593Smuzhiyun /**
2056*4882a593Smuzhiyun  * snd_hda_add_vmaster_hook - Add a vmaster hook for mute-LED
2057*4882a593Smuzhiyun  * @codec: the HDA codec
2058*4882a593Smuzhiyun  * @hook: the vmaster hook object
2059*4882a593Smuzhiyun  * @expose_enum_ctl: flag to create an enum ctl
2060*4882a593Smuzhiyun  *
2061*4882a593Smuzhiyun  * Add a mute-LED hook with the given vmaster switch kctl.
2062*4882a593Smuzhiyun  * When @expose_enum_ctl is set, "Mute-LED Mode" control is automatically
2063*4882a593Smuzhiyun  * created and associated with the given hook.
2064*4882a593Smuzhiyun  */
snd_hda_add_vmaster_hook(struct hda_codec * codec,struct hda_vmaster_mute_hook * hook,bool expose_enum_ctl)2065*4882a593Smuzhiyun int snd_hda_add_vmaster_hook(struct hda_codec *codec,
2066*4882a593Smuzhiyun 			     struct hda_vmaster_mute_hook *hook,
2067*4882a593Smuzhiyun 			     bool expose_enum_ctl)
2068*4882a593Smuzhiyun {
2069*4882a593Smuzhiyun 	struct snd_kcontrol *kctl;
2070*4882a593Smuzhiyun 
2071*4882a593Smuzhiyun 	if (!hook->hook || !hook->sw_kctl)
2072*4882a593Smuzhiyun 		return 0;
2073*4882a593Smuzhiyun 	hook->codec = codec;
2074*4882a593Smuzhiyun 	hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
2075*4882a593Smuzhiyun 	snd_ctl_add_vmaster_hook(hook->sw_kctl, vmaster_hook, hook);
2076*4882a593Smuzhiyun 	if (!expose_enum_ctl)
2077*4882a593Smuzhiyun 		return 0;
2078*4882a593Smuzhiyun 	kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
2079*4882a593Smuzhiyun 	if (!kctl)
2080*4882a593Smuzhiyun 		return -ENOMEM;
2081*4882a593Smuzhiyun 	return snd_hda_ctl_add(codec, 0, kctl);
2082*4882a593Smuzhiyun }
2083*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_add_vmaster_hook);
2084*4882a593Smuzhiyun 
2085*4882a593Smuzhiyun /**
2086*4882a593Smuzhiyun  * snd_hda_sync_vmaster_hook - Sync vmaster hook
2087*4882a593Smuzhiyun  * @hook: the vmaster hook
2088*4882a593Smuzhiyun  *
2089*4882a593Smuzhiyun  * Call the hook with the current value for synchronization.
2090*4882a593Smuzhiyun  * Should be called in init callback.
2091*4882a593Smuzhiyun  */
snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook * hook)2092*4882a593Smuzhiyun void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook)
2093*4882a593Smuzhiyun {
2094*4882a593Smuzhiyun 	if (!hook->hook || !hook->codec)
2095*4882a593Smuzhiyun 		return;
2096*4882a593Smuzhiyun 	/* don't call vmaster hook in the destructor since it might have
2097*4882a593Smuzhiyun 	 * been already destroyed
2098*4882a593Smuzhiyun 	 */
2099*4882a593Smuzhiyun 	if (hook->codec->bus->shutdown)
2100*4882a593Smuzhiyun 		return;
2101*4882a593Smuzhiyun 	snd_ctl_sync_vmaster_hook(hook->sw_kctl);
2102*4882a593Smuzhiyun }
2103*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_sync_vmaster_hook);
2104*4882a593Smuzhiyun 
2105*4882a593Smuzhiyun 
2106*4882a593Smuzhiyun /**
2107*4882a593Smuzhiyun  * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch
2108*4882a593Smuzhiyun  * @kcontrol: referred ctl element
2109*4882a593Smuzhiyun  * @uinfo: pointer to get/store the data
2110*4882a593Smuzhiyun  *
2111*4882a593Smuzhiyun  * The control element is supposed to have the private_value field
2112*4882a593Smuzhiyun  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
2113*4882a593Smuzhiyun  */
snd_hda_mixer_amp_switch_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2114*4882a593Smuzhiyun int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
2115*4882a593Smuzhiyun 				  struct snd_ctl_elem_info *uinfo)
2116*4882a593Smuzhiyun {
2117*4882a593Smuzhiyun 	int chs = get_amp_channels(kcontrol);
2118*4882a593Smuzhiyun 
2119*4882a593Smuzhiyun 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
2120*4882a593Smuzhiyun 	uinfo->count = chs == 3 ? 2 : 1;
2121*4882a593Smuzhiyun 	uinfo->value.integer.min = 0;
2122*4882a593Smuzhiyun 	uinfo->value.integer.max = 1;
2123*4882a593Smuzhiyun 	return 0;
2124*4882a593Smuzhiyun }
2125*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_info);
2126*4882a593Smuzhiyun 
2127*4882a593Smuzhiyun /**
2128*4882a593Smuzhiyun  * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch
2129*4882a593Smuzhiyun  * @kcontrol: ctl element
2130*4882a593Smuzhiyun  * @ucontrol: pointer to get/store the data
2131*4882a593Smuzhiyun  *
2132*4882a593Smuzhiyun  * The control element is supposed to have the private_value field
2133*4882a593Smuzhiyun  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
2134*4882a593Smuzhiyun  */
snd_hda_mixer_amp_switch_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2135*4882a593Smuzhiyun int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
2136*4882a593Smuzhiyun 				 struct snd_ctl_elem_value *ucontrol)
2137*4882a593Smuzhiyun {
2138*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2139*4882a593Smuzhiyun 	hda_nid_t nid = get_amp_nid(kcontrol);
2140*4882a593Smuzhiyun 	int chs = get_amp_channels(kcontrol);
2141*4882a593Smuzhiyun 	int dir = get_amp_direction(kcontrol);
2142*4882a593Smuzhiyun 	int idx = get_amp_index(kcontrol);
2143*4882a593Smuzhiyun 	long *valp = ucontrol->value.integer.value;
2144*4882a593Smuzhiyun 
2145*4882a593Smuzhiyun 	if (chs & 1)
2146*4882a593Smuzhiyun 		*valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) &
2147*4882a593Smuzhiyun 			   HDA_AMP_MUTE) ? 0 : 1;
2148*4882a593Smuzhiyun 	if (chs & 2)
2149*4882a593Smuzhiyun 		*valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) &
2150*4882a593Smuzhiyun 			 HDA_AMP_MUTE) ? 0 : 1;
2151*4882a593Smuzhiyun 	return 0;
2152*4882a593Smuzhiyun }
2153*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_get);
2154*4882a593Smuzhiyun 
2155*4882a593Smuzhiyun /**
2156*4882a593Smuzhiyun  * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch
2157*4882a593Smuzhiyun  * @kcontrol: ctl element
2158*4882a593Smuzhiyun  * @ucontrol: pointer to get/store the data
2159*4882a593Smuzhiyun  *
2160*4882a593Smuzhiyun  * The control element is supposed to have the private_value field
2161*4882a593Smuzhiyun  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
2162*4882a593Smuzhiyun  */
snd_hda_mixer_amp_switch_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2163*4882a593Smuzhiyun int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
2164*4882a593Smuzhiyun 				 struct snd_ctl_elem_value *ucontrol)
2165*4882a593Smuzhiyun {
2166*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2167*4882a593Smuzhiyun 	hda_nid_t nid = get_amp_nid(kcontrol);
2168*4882a593Smuzhiyun 	int chs = get_amp_channels(kcontrol);
2169*4882a593Smuzhiyun 	int dir = get_amp_direction(kcontrol);
2170*4882a593Smuzhiyun 	int idx = get_amp_index(kcontrol);
2171*4882a593Smuzhiyun 	long *valp = ucontrol->value.integer.value;
2172*4882a593Smuzhiyun 	int change = 0;
2173*4882a593Smuzhiyun 
2174*4882a593Smuzhiyun 	if (chs & 1) {
2175*4882a593Smuzhiyun 		change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
2176*4882a593Smuzhiyun 						  HDA_AMP_MUTE,
2177*4882a593Smuzhiyun 						  *valp ? 0 : HDA_AMP_MUTE);
2178*4882a593Smuzhiyun 		valp++;
2179*4882a593Smuzhiyun 	}
2180*4882a593Smuzhiyun 	if (chs & 2)
2181*4882a593Smuzhiyun 		change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
2182*4882a593Smuzhiyun 						   HDA_AMP_MUTE,
2183*4882a593Smuzhiyun 						   *valp ? 0 : HDA_AMP_MUTE);
2184*4882a593Smuzhiyun 	hda_call_check_power_status(codec, nid);
2185*4882a593Smuzhiyun 	return change;
2186*4882a593Smuzhiyun }
2187*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_put);
2188*4882a593Smuzhiyun 
2189*4882a593Smuzhiyun /*
2190*4882a593Smuzhiyun  * SPDIF out controls
2191*4882a593Smuzhiyun  */
2192*4882a593Smuzhiyun 
snd_hda_spdif_mask_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo)2193*4882a593Smuzhiyun static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol,
2194*4882a593Smuzhiyun 				   struct snd_ctl_elem_info *uinfo)
2195*4882a593Smuzhiyun {
2196*4882a593Smuzhiyun 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
2197*4882a593Smuzhiyun 	uinfo->count = 1;
2198*4882a593Smuzhiyun 	return 0;
2199*4882a593Smuzhiyun }
2200*4882a593Smuzhiyun 
snd_hda_spdif_cmask_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2201*4882a593Smuzhiyun static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol,
2202*4882a593Smuzhiyun 				   struct snd_ctl_elem_value *ucontrol)
2203*4882a593Smuzhiyun {
2204*4882a593Smuzhiyun 	ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
2205*4882a593Smuzhiyun 					   IEC958_AES0_NONAUDIO |
2206*4882a593Smuzhiyun 					   IEC958_AES0_CON_EMPHASIS_5015 |
2207*4882a593Smuzhiyun 					   IEC958_AES0_CON_NOT_COPYRIGHT;
2208*4882a593Smuzhiyun 	ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY |
2209*4882a593Smuzhiyun 					   IEC958_AES1_CON_ORIGINAL;
2210*4882a593Smuzhiyun 	return 0;
2211*4882a593Smuzhiyun }
2212*4882a593Smuzhiyun 
snd_hda_spdif_pmask_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2213*4882a593Smuzhiyun static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol,
2214*4882a593Smuzhiyun 				   struct snd_ctl_elem_value *ucontrol)
2215*4882a593Smuzhiyun {
2216*4882a593Smuzhiyun 	ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
2217*4882a593Smuzhiyun 					   IEC958_AES0_NONAUDIO |
2218*4882a593Smuzhiyun 					   IEC958_AES0_PRO_EMPHASIS_5015;
2219*4882a593Smuzhiyun 	return 0;
2220*4882a593Smuzhiyun }
2221*4882a593Smuzhiyun 
snd_hda_spdif_default_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2222*4882a593Smuzhiyun static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
2223*4882a593Smuzhiyun 				     struct snd_ctl_elem_value *ucontrol)
2224*4882a593Smuzhiyun {
2225*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2226*4882a593Smuzhiyun 	int idx = kcontrol->private_value;
2227*4882a593Smuzhiyun 	struct hda_spdif_out *spdif;
2228*4882a593Smuzhiyun 
2229*4882a593Smuzhiyun 	if (WARN_ON(codec->spdif_out.used <= idx))
2230*4882a593Smuzhiyun 		return -EINVAL;
2231*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
2232*4882a593Smuzhiyun 	spdif = snd_array_elem(&codec->spdif_out, idx);
2233*4882a593Smuzhiyun 	ucontrol->value.iec958.status[0] = spdif->status & 0xff;
2234*4882a593Smuzhiyun 	ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff;
2235*4882a593Smuzhiyun 	ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff;
2236*4882a593Smuzhiyun 	ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff;
2237*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
2238*4882a593Smuzhiyun 
2239*4882a593Smuzhiyun 	return 0;
2240*4882a593Smuzhiyun }
2241*4882a593Smuzhiyun 
2242*4882a593Smuzhiyun /* convert from SPDIF status bits to HDA SPDIF bits
2243*4882a593Smuzhiyun  * bit 0 (DigEn) is always set zero (to be filled later)
2244*4882a593Smuzhiyun  */
convert_from_spdif_status(unsigned int sbits)2245*4882a593Smuzhiyun static unsigned short convert_from_spdif_status(unsigned int sbits)
2246*4882a593Smuzhiyun {
2247*4882a593Smuzhiyun 	unsigned short val = 0;
2248*4882a593Smuzhiyun 
2249*4882a593Smuzhiyun 	if (sbits & IEC958_AES0_PROFESSIONAL)
2250*4882a593Smuzhiyun 		val |= AC_DIG1_PROFESSIONAL;
2251*4882a593Smuzhiyun 	if (sbits & IEC958_AES0_NONAUDIO)
2252*4882a593Smuzhiyun 		val |= AC_DIG1_NONAUDIO;
2253*4882a593Smuzhiyun 	if (sbits & IEC958_AES0_PROFESSIONAL) {
2254*4882a593Smuzhiyun 		if ((sbits & IEC958_AES0_PRO_EMPHASIS) ==
2255*4882a593Smuzhiyun 		    IEC958_AES0_PRO_EMPHASIS_5015)
2256*4882a593Smuzhiyun 			val |= AC_DIG1_EMPHASIS;
2257*4882a593Smuzhiyun 	} else {
2258*4882a593Smuzhiyun 		if ((sbits & IEC958_AES0_CON_EMPHASIS) ==
2259*4882a593Smuzhiyun 		    IEC958_AES0_CON_EMPHASIS_5015)
2260*4882a593Smuzhiyun 			val |= AC_DIG1_EMPHASIS;
2261*4882a593Smuzhiyun 		if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
2262*4882a593Smuzhiyun 			val |= AC_DIG1_COPYRIGHT;
2263*4882a593Smuzhiyun 		if (sbits & (IEC958_AES1_CON_ORIGINAL << 8))
2264*4882a593Smuzhiyun 			val |= AC_DIG1_LEVEL;
2265*4882a593Smuzhiyun 		val |= sbits & (IEC958_AES1_CON_CATEGORY << 8);
2266*4882a593Smuzhiyun 	}
2267*4882a593Smuzhiyun 	return val;
2268*4882a593Smuzhiyun }
2269*4882a593Smuzhiyun 
2270*4882a593Smuzhiyun /* convert to SPDIF status bits from HDA SPDIF bits
2271*4882a593Smuzhiyun  */
convert_to_spdif_status(unsigned short val)2272*4882a593Smuzhiyun static unsigned int convert_to_spdif_status(unsigned short val)
2273*4882a593Smuzhiyun {
2274*4882a593Smuzhiyun 	unsigned int sbits = 0;
2275*4882a593Smuzhiyun 
2276*4882a593Smuzhiyun 	if (val & AC_DIG1_NONAUDIO)
2277*4882a593Smuzhiyun 		sbits |= IEC958_AES0_NONAUDIO;
2278*4882a593Smuzhiyun 	if (val & AC_DIG1_PROFESSIONAL)
2279*4882a593Smuzhiyun 		sbits |= IEC958_AES0_PROFESSIONAL;
2280*4882a593Smuzhiyun 	if (sbits & IEC958_AES0_PROFESSIONAL) {
2281*4882a593Smuzhiyun 		if (val & AC_DIG1_EMPHASIS)
2282*4882a593Smuzhiyun 			sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
2283*4882a593Smuzhiyun 	} else {
2284*4882a593Smuzhiyun 		if (val & AC_DIG1_EMPHASIS)
2285*4882a593Smuzhiyun 			sbits |= IEC958_AES0_CON_EMPHASIS_5015;
2286*4882a593Smuzhiyun 		if (!(val & AC_DIG1_COPYRIGHT))
2287*4882a593Smuzhiyun 			sbits |= IEC958_AES0_CON_NOT_COPYRIGHT;
2288*4882a593Smuzhiyun 		if (val & AC_DIG1_LEVEL)
2289*4882a593Smuzhiyun 			sbits |= (IEC958_AES1_CON_ORIGINAL << 8);
2290*4882a593Smuzhiyun 		sbits |= val & (0x7f << 8);
2291*4882a593Smuzhiyun 	}
2292*4882a593Smuzhiyun 	return sbits;
2293*4882a593Smuzhiyun }
2294*4882a593Smuzhiyun 
2295*4882a593Smuzhiyun /* set digital convert verbs both for the given NID and its followers */
set_dig_out(struct hda_codec * codec,hda_nid_t nid,int mask,int val)2296*4882a593Smuzhiyun static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
2297*4882a593Smuzhiyun 			int mask, int val)
2298*4882a593Smuzhiyun {
2299*4882a593Smuzhiyun 	const hda_nid_t *d;
2300*4882a593Smuzhiyun 
2301*4882a593Smuzhiyun 	snd_hdac_regmap_update(&codec->core, nid, AC_VERB_SET_DIGI_CONVERT_1,
2302*4882a593Smuzhiyun 			       mask, val);
2303*4882a593Smuzhiyun 	d = codec->follower_dig_outs;
2304*4882a593Smuzhiyun 	if (!d)
2305*4882a593Smuzhiyun 		return;
2306*4882a593Smuzhiyun 	for (; *d; d++)
2307*4882a593Smuzhiyun 		snd_hdac_regmap_update(&codec->core, *d,
2308*4882a593Smuzhiyun 				       AC_VERB_SET_DIGI_CONVERT_1, mask, val);
2309*4882a593Smuzhiyun }
2310*4882a593Smuzhiyun 
set_dig_out_convert(struct hda_codec * codec,hda_nid_t nid,int dig1,int dig2)2311*4882a593Smuzhiyun static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid,
2312*4882a593Smuzhiyun 				       int dig1, int dig2)
2313*4882a593Smuzhiyun {
2314*4882a593Smuzhiyun 	unsigned int mask = 0;
2315*4882a593Smuzhiyun 	unsigned int val = 0;
2316*4882a593Smuzhiyun 
2317*4882a593Smuzhiyun 	if (dig1 != -1) {
2318*4882a593Smuzhiyun 		mask |= 0xff;
2319*4882a593Smuzhiyun 		val = dig1;
2320*4882a593Smuzhiyun 	}
2321*4882a593Smuzhiyun 	if (dig2 != -1) {
2322*4882a593Smuzhiyun 		mask |= 0xff00;
2323*4882a593Smuzhiyun 		val |= dig2 << 8;
2324*4882a593Smuzhiyun 	}
2325*4882a593Smuzhiyun 	set_dig_out(codec, nid, mask, val);
2326*4882a593Smuzhiyun }
2327*4882a593Smuzhiyun 
snd_hda_spdif_default_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2328*4882a593Smuzhiyun static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
2329*4882a593Smuzhiyun 				     struct snd_ctl_elem_value *ucontrol)
2330*4882a593Smuzhiyun {
2331*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2332*4882a593Smuzhiyun 	int idx = kcontrol->private_value;
2333*4882a593Smuzhiyun 	struct hda_spdif_out *spdif;
2334*4882a593Smuzhiyun 	hda_nid_t nid;
2335*4882a593Smuzhiyun 	unsigned short val;
2336*4882a593Smuzhiyun 	int change;
2337*4882a593Smuzhiyun 
2338*4882a593Smuzhiyun 	if (WARN_ON(codec->spdif_out.used <= idx))
2339*4882a593Smuzhiyun 		return -EINVAL;
2340*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
2341*4882a593Smuzhiyun 	spdif = snd_array_elem(&codec->spdif_out, idx);
2342*4882a593Smuzhiyun 	nid = spdif->nid;
2343*4882a593Smuzhiyun 	spdif->status = ucontrol->value.iec958.status[0] |
2344*4882a593Smuzhiyun 		((unsigned int)ucontrol->value.iec958.status[1] << 8) |
2345*4882a593Smuzhiyun 		((unsigned int)ucontrol->value.iec958.status[2] << 16) |
2346*4882a593Smuzhiyun 		((unsigned int)ucontrol->value.iec958.status[3] << 24);
2347*4882a593Smuzhiyun 	val = convert_from_spdif_status(spdif->status);
2348*4882a593Smuzhiyun 	val |= spdif->ctls & 1;
2349*4882a593Smuzhiyun 	change = spdif->ctls != val;
2350*4882a593Smuzhiyun 	spdif->ctls = val;
2351*4882a593Smuzhiyun 	if (change && nid != (u16)-1)
2352*4882a593Smuzhiyun 		set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
2353*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
2354*4882a593Smuzhiyun 	return change;
2355*4882a593Smuzhiyun }
2356*4882a593Smuzhiyun 
2357*4882a593Smuzhiyun #define snd_hda_spdif_out_switch_info	snd_ctl_boolean_mono_info
2358*4882a593Smuzhiyun 
snd_hda_spdif_out_switch_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2359*4882a593Smuzhiyun static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
2360*4882a593Smuzhiyun 					struct snd_ctl_elem_value *ucontrol)
2361*4882a593Smuzhiyun {
2362*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2363*4882a593Smuzhiyun 	int idx = kcontrol->private_value;
2364*4882a593Smuzhiyun 	struct hda_spdif_out *spdif;
2365*4882a593Smuzhiyun 
2366*4882a593Smuzhiyun 	if (WARN_ON(codec->spdif_out.used <= idx))
2367*4882a593Smuzhiyun 		return -EINVAL;
2368*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
2369*4882a593Smuzhiyun 	spdif = snd_array_elem(&codec->spdif_out, idx);
2370*4882a593Smuzhiyun 	ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE;
2371*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
2372*4882a593Smuzhiyun 	return 0;
2373*4882a593Smuzhiyun }
2374*4882a593Smuzhiyun 
set_spdif_ctls(struct hda_codec * codec,hda_nid_t nid,int dig1,int dig2)2375*4882a593Smuzhiyun static inline void set_spdif_ctls(struct hda_codec *codec, hda_nid_t nid,
2376*4882a593Smuzhiyun 				  int dig1, int dig2)
2377*4882a593Smuzhiyun {
2378*4882a593Smuzhiyun 	set_dig_out_convert(codec, nid, dig1, dig2);
2379*4882a593Smuzhiyun 	/* unmute amp switch (if any) */
2380*4882a593Smuzhiyun 	if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
2381*4882a593Smuzhiyun 	    (dig1 & AC_DIG1_ENABLE))
2382*4882a593Smuzhiyun 		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
2383*4882a593Smuzhiyun 					    HDA_AMP_MUTE, 0);
2384*4882a593Smuzhiyun }
2385*4882a593Smuzhiyun 
snd_hda_spdif_out_switch_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2386*4882a593Smuzhiyun static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
2387*4882a593Smuzhiyun 					struct snd_ctl_elem_value *ucontrol)
2388*4882a593Smuzhiyun {
2389*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2390*4882a593Smuzhiyun 	int idx = kcontrol->private_value;
2391*4882a593Smuzhiyun 	struct hda_spdif_out *spdif;
2392*4882a593Smuzhiyun 	hda_nid_t nid;
2393*4882a593Smuzhiyun 	unsigned short val;
2394*4882a593Smuzhiyun 	int change;
2395*4882a593Smuzhiyun 
2396*4882a593Smuzhiyun 	if (WARN_ON(codec->spdif_out.used <= idx))
2397*4882a593Smuzhiyun 		return -EINVAL;
2398*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
2399*4882a593Smuzhiyun 	spdif = snd_array_elem(&codec->spdif_out, idx);
2400*4882a593Smuzhiyun 	nid = spdif->nid;
2401*4882a593Smuzhiyun 	val = spdif->ctls & ~AC_DIG1_ENABLE;
2402*4882a593Smuzhiyun 	if (ucontrol->value.integer.value[0])
2403*4882a593Smuzhiyun 		val |= AC_DIG1_ENABLE;
2404*4882a593Smuzhiyun 	change = spdif->ctls != val;
2405*4882a593Smuzhiyun 	spdif->ctls = val;
2406*4882a593Smuzhiyun 	if (change && nid != (u16)-1)
2407*4882a593Smuzhiyun 		set_spdif_ctls(codec, nid, val & 0xff, -1);
2408*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
2409*4882a593Smuzhiyun 	return change;
2410*4882a593Smuzhiyun }
2411*4882a593Smuzhiyun 
2412*4882a593Smuzhiyun static const struct snd_kcontrol_new dig_mixes[] = {
2413*4882a593Smuzhiyun 	{
2414*4882a593Smuzhiyun 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
2415*4882a593Smuzhiyun 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2416*4882a593Smuzhiyun 		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
2417*4882a593Smuzhiyun 		.info = snd_hda_spdif_mask_info,
2418*4882a593Smuzhiyun 		.get = snd_hda_spdif_cmask_get,
2419*4882a593Smuzhiyun 	},
2420*4882a593Smuzhiyun 	{
2421*4882a593Smuzhiyun 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
2422*4882a593Smuzhiyun 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2423*4882a593Smuzhiyun 		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
2424*4882a593Smuzhiyun 		.info = snd_hda_spdif_mask_info,
2425*4882a593Smuzhiyun 		.get = snd_hda_spdif_pmask_get,
2426*4882a593Smuzhiyun 	},
2427*4882a593Smuzhiyun 	{
2428*4882a593Smuzhiyun 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2429*4882a593Smuzhiyun 		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
2430*4882a593Smuzhiyun 		.info = snd_hda_spdif_mask_info,
2431*4882a593Smuzhiyun 		.get = snd_hda_spdif_default_get,
2432*4882a593Smuzhiyun 		.put = snd_hda_spdif_default_put,
2433*4882a593Smuzhiyun 	},
2434*4882a593Smuzhiyun 	{
2435*4882a593Smuzhiyun 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2436*4882a593Smuzhiyun 		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
2437*4882a593Smuzhiyun 		.info = snd_hda_spdif_out_switch_info,
2438*4882a593Smuzhiyun 		.get = snd_hda_spdif_out_switch_get,
2439*4882a593Smuzhiyun 		.put = snd_hda_spdif_out_switch_put,
2440*4882a593Smuzhiyun 	},
2441*4882a593Smuzhiyun 	{ } /* end */
2442*4882a593Smuzhiyun };
2443*4882a593Smuzhiyun 
2444*4882a593Smuzhiyun /**
2445*4882a593Smuzhiyun  * snd_hda_create_dig_out_ctls - create Output SPDIF-related controls
2446*4882a593Smuzhiyun  * @codec: the HDA codec
2447*4882a593Smuzhiyun  * @associated_nid: NID that new ctls associated with
2448*4882a593Smuzhiyun  * @cvt_nid: converter NID
2449*4882a593Smuzhiyun  * @type: HDA_PCM_TYPE_*
2450*4882a593Smuzhiyun  * Creates controls related with the digital output.
2451*4882a593Smuzhiyun  * Called from each patch supporting the digital out.
2452*4882a593Smuzhiyun  *
2453*4882a593Smuzhiyun  * Returns 0 if successful, or a negative error code.
2454*4882a593Smuzhiyun  */
snd_hda_create_dig_out_ctls(struct hda_codec * codec,hda_nid_t associated_nid,hda_nid_t cvt_nid,int type)2455*4882a593Smuzhiyun int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
2456*4882a593Smuzhiyun 				hda_nid_t associated_nid,
2457*4882a593Smuzhiyun 				hda_nid_t cvt_nid,
2458*4882a593Smuzhiyun 				int type)
2459*4882a593Smuzhiyun {
2460*4882a593Smuzhiyun 	int err;
2461*4882a593Smuzhiyun 	struct snd_kcontrol *kctl;
2462*4882a593Smuzhiyun 	const struct snd_kcontrol_new *dig_mix;
2463*4882a593Smuzhiyun 	int idx = 0;
2464*4882a593Smuzhiyun 	int val = 0;
2465*4882a593Smuzhiyun 	const int spdif_index = 16;
2466*4882a593Smuzhiyun 	struct hda_spdif_out *spdif;
2467*4882a593Smuzhiyun 	struct hda_bus *bus = codec->bus;
2468*4882a593Smuzhiyun 
2469*4882a593Smuzhiyun 	if (bus->primary_dig_out_type == HDA_PCM_TYPE_HDMI &&
2470*4882a593Smuzhiyun 	    type == HDA_PCM_TYPE_SPDIF) {
2471*4882a593Smuzhiyun 		idx = spdif_index;
2472*4882a593Smuzhiyun 	} else if (bus->primary_dig_out_type == HDA_PCM_TYPE_SPDIF &&
2473*4882a593Smuzhiyun 		   type == HDA_PCM_TYPE_HDMI) {
2474*4882a593Smuzhiyun 		/* suppose a single SPDIF device */
2475*4882a593Smuzhiyun 		for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
2476*4882a593Smuzhiyun 			kctl = find_mixer_ctl(codec, dig_mix->name, 0, 0);
2477*4882a593Smuzhiyun 			if (!kctl)
2478*4882a593Smuzhiyun 				break;
2479*4882a593Smuzhiyun 			kctl->id.index = spdif_index;
2480*4882a593Smuzhiyun 		}
2481*4882a593Smuzhiyun 		bus->primary_dig_out_type = HDA_PCM_TYPE_HDMI;
2482*4882a593Smuzhiyun 	}
2483*4882a593Smuzhiyun 	if (!bus->primary_dig_out_type)
2484*4882a593Smuzhiyun 		bus->primary_dig_out_type = type;
2485*4882a593Smuzhiyun 
2486*4882a593Smuzhiyun 	idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch", idx);
2487*4882a593Smuzhiyun 	if (idx < 0) {
2488*4882a593Smuzhiyun 		codec_err(codec, "too many IEC958 outputs\n");
2489*4882a593Smuzhiyun 		return -EBUSY;
2490*4882a593Smuzhiyun 	}
2491*4882a593Smuzhiyun 	spdif = snd_array_new(&codec->spdif_out);
2492*4882a593Smuzhiyun 	if (!spdif)
2493*4882a593Smuzhiyun 		return -ENOMEM;
2494*4882a593Smuzhiyun 	for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
2495*4882a593Smuzhiyun 		kctl = snd_ctl_new1(dig_mix, codec);
2496*4882a593Smuzhiyun 		if (!kctl)
2497*4882a593Smuzhiyun 			return -ENOMEM;
2498*4882a593Smuzhiyun 		kctl->id.index = idx;
2499*4882a593Smuzhiyun 		kctl->private_value = codec->spdif_out.used - 1;
2500*4882a593Smuzhiyun 		err = snd_hda_ctl_add(codec, associated_nid, kctl);
2501*4882a593Smuzhiyun 		if (err < 0)
2502*4882a593Smuzhiyun 			return err;
2503*4882a593Smuzhiyun 	}
2504*4882a593Smuzhiyun 	spdif->nid = cvt_nid;
2505*4882a593Smuzhiyun 	snd_hdac_regmap_read(&codec->core, cvt_nid,
2506*4882a593Smuzhiyun 			     AC_VERB_GET_DIGI_CONVERT_1, &val);
2507*4882a593Smuzhiyun 	spdif->ctls = val;
2508*4882a593Smuzhiyun 	spdif->status = convert_to_spdif_status(spdif->ctls);
2509*4882a593Smuzhiyun 	return 0;
2510*4882a593Smuzhiyun }
2511*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_create_dig_out_ctls);
2512*4882a593Smuzhiyun 
2513*4882a593Smuzhiyun /**
2514*4882a593Smuzhiyun  * snd_hda_spdif_out_of_nid - get the hda_spdif_out entry from the given NID
2515*4882a593Smuzhiyun  * @codec: the HDA codec
2516*4882a593Smuzhiyun  * @nid: widget NID
2517*4882a593Smuzhiyun  *
2518*4882a593Smuzhiyun  * call within spdif_mutex lock
2519*4882a593Smuzhiyun  */
snd_hda_spdif_out_of_nid(struct hda_codec * codec,hda_nid_t nid)2520*4882a593Smuzhiyun struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
2521*4882a593Smuzhiyun 					       hda_nid_t nid)
2522*4882a593Smuzhiyun {
2523*4882a593Smuzhiyun 	struct hda_spdif_out *spdif;
2524*4882a593Smuzhiyun 	int i;
2525*4882a593Smuzhiyun 
2526*4882a593Smuzhiyun 	snd_array_for_each(&codec->spdif_out, i, spdif) {
2527*4882a593Smuzhiyun 		if (spdif->nid == nid)
2528*4882a593Smuzhiyun 			return spdif;
2529*4882a593Smuzhiyun 	}
2530*4882a593Smuzhiyun 	return NULL;
2531*4882a593Smuzhiyun }
2532*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_spdif_out_of_nid);
2533*4882a593Smuzhiyun 
2534*4882a593Smuzhiyun /**
2535*4882a593Smuzhiyun  * snd_hda_spdif_ctls_unassign - Unassign the given SPDIF ctl
2536*4882a593Smuzhiyun  * @codec: the HDA codec
2537*4882a593Smuzhiyun  * @idx: the SPDIF ctl index
2538*4882a593Smuzhiyun  *
2539*4882a593Smuzhiyun  * Unassign the widget from the given SPDIF control.
2540*4882a593Smuzhiyun  */
snd_hda_spdif_ctls_unassign(struct hda_codec * codec,int idx)2541*4882a593Smuzhiyun void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx)
2542*4882a593Smuzhiyun {
2543*4882a593Smuzhiyun 	struct hda_spdif_out *spdif;
2544*4882a593Smuzhiyun 
2545*4882a593Smuzhiyun 	if (WARN_ON(codec->spdif_out.used <= idx))
2546*4882a593Smuzhiyun 		return;
2547*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
2548*4882a593Smuzhiyun 	spdif = snd_array_elem(&codec->spdif_out, idx);
2549*4882a593Smuzhiyun 	spdif->nid = (u16)-1;
2550*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
2551*4882a593Smuzhiyun }
2552*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_unassign);
2553*4882a593Smuzhiyun 
2554*4882a593Smuzhiyun /**
2555*4882a593Smuzhiyun  * snd_hda_spdif_ctls_assign - Assign the SPDIF controls to the given NID
2556*4882a593Smuzhiyun  * @codec: the HDA codec
2557*4882a593Smuzhiyun  * @idx: the SPDIF ctl idx
2558*4882a593Smuzhiyun  * @nid: widget NID
2559*4882a593Smuzhiyun  *
2560*4882a593Smuzhiyun  * Assign the widget to the SPDIF control with the given index.
2561*4882a593Smuzhiyun  */
snd_hda_spdif_ctls_assign(struct hda_codec * codec,int idx,hda_nid_t nid)2562*4882a593Smuzhiyun void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid)
2563*4882a593Smuzhiyun {
2564*4882a593Smuzhiyun 	struct hda_spdif_out *spdif;
2565*4882a593Smuzhiyun 	unsigned short val;
2566*4882a593Smuzhiyun 
2567*4882a593Smuzhiyun 	if (WARN_ON(codec->spdif_out.used <= idx))
2568*4882a593Smuzhiyun 		return;
2569*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
2570*4882a593Smuzhiyun 	spdif = snd_array_elem(&codec->spdif_out, idx);
2571*4882a593Smuzhiyun 	if (spdif->nid != nid) {
2572*4882a593Smuzhiyun 		spdif->nid = nid;
2573*4882a593Smuzhiyun 		val = spdif->ctls;
2574*4882a593Smuzhiyun 		set_spdif_ctls(codec, nid, val & 0xff, (val >> 8) & 0xff);
2575*4882a593Smuzhiyun 	}
2576*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
2577*4882a593Smuzhiyun }
2578*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_assign);
2579*4882a593Smuzhiyun 
2580*4882a593Smuzhiyun /*
2581*4882a593Smuzhiyun  * SPDIF sharing with analog output
2582*4882a593Smuzhiyun  */
spdif_share_sw_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2583*4882a593Smuzhiyun static int spdif_share_sw_get(struct snd_kcontrol *kcontrol,
2584*4882a593Smuzhiyun 			      struct snd_ctl_elem_value *ucontrol)
2585*4882a593Smuzhiyun {
2586*4882a593Smuzhiyun 	struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
2587*4882a593Smuzhiyun 	ucontrol->value.integer.value[0] = mout->share_spdif;
2588*4882a593Smuzhiyun 	return 0;
2589*4882a593Smuzhiyun }
2590*4882a593Smuzhiyun 
spdif_share_sw_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2591*4882a593Smuzhiyun static int spdif_share_sw_put(struct snd_kcontrol *kcontrol,
2592*4882a593Smuzhiyun 			      struct snd_ctl_elem_value *ucontrol)
2593*4882a593Smuzhiyun {
2594*4882a593Smuzhiyun 	struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
2595*4882a593Smuzhiyun 	mout->share_spdif = !!ucontrol->value.integer.value[0];
2596*4882a593Smuzhiyun 	return 0;
2597*4882a593Smuzhiyun }
2598*4882a593Smuzhiyun 
2599*4882a593Smuzhiyun static const struct snd_kcontrol_new spdif_share_sw = {
2600*4882a593Smuzhiyun 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2601*4882a593Smuzhiyun 	.name = "IEC958 Default PCM Playback Switch",
2602*4882a593Smuzhiyun 	.info = snd_ctl_boolean_mono_info,
2603*4882a593Smuzhiyun 	.get = spdif_share_sw_get,
2604*4882a593Smuzhiyun 	.put = spdif_share_sw_put,
2605*4882a593Smuzhiyun };
2606*4882a593Smuzhiyun 
2607*4882a593Smuzhiyun /**
2608*4882a593Smuzhiyun  * snd_hda_create_spdif_share_sw - create Default PCM switch
2609*4882a593Smuzhiyun  * @codec: the HDA codec
2610*4882a593Smuzhiyun  * @mout: multi-out instance
2611*4882a593Smuzhiyun  */
snd_hda_create_spdif_share_sw(struct hda_codec * codec,struct hda_multi_out * mout)2612*4882a593Smuzhiyun int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
2613*4882a593Smuzhiyun 				  struct hda_multi_out *mout)
2614*4882a593Smuzhiyun {
2615*4882a593Smuzhiyun 	struct snd_kcontrol *kctl;
2616*4882a593Smuzhiyun 
2617*4882a593Smuzhiyun 	if (!mout->dig_out_nid)
2618*4882a593Smuzhiyun 		return 0;
2619*4882a593Smuzhiyun 
2620*4882a593Smuzhiyun 	kctl = snd_ctl_new1(&spdif_share_sw, mout);
2621*4882a593Smuzhiyun 	if (!kctl)
2622*4882a593Smuzhiyun 		return -ENOMEM;
2623*4882a593Smuzhiyun 	/* ATTENTION: here mout is passed as private_data, instead of codec */
2624*4882a593Smuzhiyun 	return snd_hda_ctl_add(codec, mout->dig_out_nid, kctl);
2625*4882a593Smuzhiyun }
2626*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_create_spdif_share_sw);
2627*4882a593Smuzhiyun 
2628*4882a593Smuzhiyun /*
2629*4882a593Smuzhiyun  * SPDIF input
2630*4882a593Smuzhiyun  */
2631*4882a593Smuzhiyun 
2632*4882a593Smuzhiyun #define snd_hda_spdif_in_switch_info	snd_hda_spdif_out_switch_info
2633*4882a593Smuzhiyun 
snd_hda_spdif_in_switch_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2634*4882a593Smuzhiyun static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol,
2635*4882a593Smuzhiyun 				       struct snd_ctl_elem_value *ucontrol)
2636*4882a593Smuzhiyun {
2637*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2638*4882a593Smuzhiyun 
2639*4882a593Smuzhiyun 	ucontrol->value.integer.value[0] = codec->spdif_in_enable;
2640*4882a593Smuzhiyun 	return 0;
2641*4882a593Smuzhiyun }
2642*4882a593Smuzhiyun 
snd_hda_spdif_in_switch_put(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2643*4882a593Smuzhiyun static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
2644*4882a593Smuzhiyun 				       struct snd_ctl_elem_value *ucontrol)
2645*4882a593Smuzhiyun {
2646*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2647*4882a593Smuzhiyun 	hda_nid_t nid = kcontrol->private_value;
2648*4882a593Smuzhiyun 	unsigned int val = !!ucontrol->value.integer.value[0];
2649*4882a593Smuzhiyun 	int change;
2650*4882a593Smuzhiyun 
2651*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
2652*4882a593Smuzhiyun 	change = codec->spdif_in_enable != val;
2653*4882a593Smuzhiyun 	if (change) {
2654*4882a593Smuzhiyun 		codec->spdif_in_enable = val;
2655*4882a593Smuzhiyun 		snd_hdac_regmap_write(&codec->core, nid,
2656*4882a593Smuzhiyun 				      AC_VERB_SET_DIGI_CONVERT_1, val);
2657*4882a593Smuzhiyun 	}
2658*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
2659*4882a593Smuzhiyun 	return change;
2660*4882a593Smuzhiyun }
2661*4882a593Smuzhiyun 
snd_hda_spdif_in_status_get(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_value * ucontrol)2662*4882a593Smuzhiyun static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
2663*4882a593Smuzhiyun 				       struct snd_ctl_elem_value *ucontrol)
2664*4882a593Smuzhiyun {
2665*4882a593Smuzhiyun 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
2666*4882a593Smuzhiyun 	hda_nid_t nid = kcontrol->private_value;
2667*4882a593Smuzhiyun 	unsigned int val;
2668*4882a593Smuzhiyun 	unsigned int sbits;
2669*4882a593Smuzhiyun 
2670*4882a593Smuzhiyun 	snd_hdac_regmap_read(&codec->core, nid,
2671*4882a593Smuzhiyun 			     AC_VERB_GET_DIGI_CONVERT_1, &val);
2672*4882a593Smuzhiyun 	sbits = convert_to_spdif_status(val);
2673*4882a593Smuzhiyun 	ucontrol->value.iec958.status[0] = sbits;
2674*4882a593Smuzhiyun 	ucontrol->value.iec958.status[1] = sbits >> 8;
2675*4882a593Smuzhiyun 	ucontrol->value.iec958.status[2] = sbits >> 16;
2676*4882a593Smuzhiyun 	ucontrol->value.iec958.status[3] = sbits >> 24;
2677*4882a593Smuzhiyun 	return 0;
2678*4882a593Smuzhiyun }
2679*4882a593Smuzhiyun 
2680*4882a593Smuzhiyun static const struct snd_kcontrol_new dig_in_ctls[] = {
2681*4882a593Smuzhiyun 	{
2682*4882a593Smuzhiyun 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2683*4882a593Smuzhiyun 		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
2684*4882a593Smuzhiyun 		.info = snd_hda_spdif_in_switch_info,
2685*4882a593Smuzhiyun 		.get = snd_hda_spdif_in_switch_get,
2686*4882a593Smuzhiyun 		.put = snd_hda_spdif_in_switch_put,
2687*4882a593Smuzhiyun 	},
2688*4882a593Smuzhiyun 	{
2689*4882a593Smuzhiyun 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
2690*4882a593Smuzhiyun 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
2691*4882a593Smuzhiyun 		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
2692*4882a593Smuzhiyun 		.info = snd_hda_spdif_mask_info,
2693*4882a593Smuzhiyun 		.get = snd_hda_spdif_in_status_get,
2694*4882a593Smuzhiyun 	},
2695*4882a593Smuzhiyun 	{ } /* end */
2696*4882a593Smuzhiyun };
2697*4882a593Smuzhiyun 
2698*4882a593Smuzhiyun /**
2699*4882a593Smuzhiyun  * snd_hda_create_spdif_in_ctls - create Input SPDIF-related controls
2700*4882a593Smuzhiyun  * @codec: the HDA codec
2701*4882a593Smuzhiyun  * @nid: audio in widget NID
2702*4882a593Smuzhiyun  *
2703*4882a593Smuzhiyun  * Creates controls related with the SPDIF input.
2704*4882a593Smuzhiyun  * Called from each patch supporting the SPDIF in.
2705*4882a593Smuzhiyun  *
2706*4882a593Smuzhiyun  * Returns 0 if successful, or a negative error code.
2707*4882a593Smuzhiyun  */
snd_hda_create_spdif_in_ctls(struct hda_codec * codec,hda_nid_t nid)2708*4882a593Smuzhiyun int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
2709*4882a593Smuzhiyun {
2710*4882a593Smuzhiyun 	int err;
2711*4882a593Smuzhiyun 	struct snd_kcontrol *kctl;
2712*4882a593Smuzhiyun 	const struct snd_kcontrol_new *dig_mix;
2713*4882a593Smuzhiyun 	int idx;
2714*4882a593Smuzhiyun 
2715*4882a593Smuzhiyun 	idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch", 0);
2716*4882a593Smuzhiyun 	if (idx < 0) {
2717*4882a593Smuzhiyun 		codec_err(codec, "too many IEC958 inputs\n");
2718*4882a593Smuzhiyun 		return -EBUSY;
2719*4882a593Smuzhiyun 	}
2720*4882a593Smuzhiyun 	for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
2721*4882a593Smuzhiyun 		kctl = snd_ctl_new1(dig_mix, codec);
2722*4882a593Smuzhiyun 		if (!kctl)
2723*4882a593Smuzhiyun 			return -ENOMEM;
2724*4882a593Smuzhiyun 		kctl->private_value = nid;
2725*4882a593Smuzhiyun 		err = snd_hda_ctl_add(codec, nid, kctl);
2726*4882a593Smuzhiyun 		if (err < 0)
2727*4882a593Smuzhiyun 			return err;
2728*4882a593Smuzhiyun 	}
2729*4882a593Smuzhiyun 	codec->spdif_in_enable =
2730*4882a593Smuzhiyun 		snd_hda_codec_read(codec, nid, 0,
2731*4882a593Smuzhiyun 				   AC_VERB_GET_DIGI_CONVERT_1, 0) &
2732*4882a593Smuzhiyun 		AC_DIG1_ENABLE;
2733*4882a593Smuzhiyun 	return 0;
2734*4882a593Smuzhiyun }
2735*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_create_spdif_in_ctls);
2736*4882a593Smuzhiyun 
2737*4882a593Smuzhiyun /**
2738*4882a593Smuzhiyun  * snd_hda_codec_set_power_to_all - Set the power state to all widgets
2739*4882a593Smuzhiyun  * @codec: the HDA codec
2740*4882a593Smuzhiyun  * @fg: function group (not used now)
2741*4882a593Smuzhiyun  * @power_state: the power state to set (AC_PWRST_*)
2742*4882a593Smuzhiyun  *
2743*4882a593Smuzhiyun  * Set the given power state to all widgets that have the power control.
2744*4882a593Smuzhiyun  * If the codec has power_filter set, it evaluates the power state and
2745*4882a593Smuzhiyun  * filter out if it's unchanged as D3.
2746*4882a593Smuzhiyun  */
snd_hda_codec_set_power_to_all(struct hda_codec * codec,hda_nid_t fg,unsigned int power_state)2747*4882a593Smuzhiyun void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
2748*4882a593Smuzhiyun 				    unsigned int power_state)
2749*4882a593Smuzhiyun {
2750*4882a593Smuzhiyun 	hda_nid_t nid;
2751*4882a593Smuzhiyun 
2752*4882a593Smuzhiyun 	for_each_hda_codec_node(nid, codec) {
2753*4882a593Smuzhiyun 		unsigned int wcaps = get_wcaps(codec, nid);
2754*4882a593Smuzhiyun 		unsigned int state = power_state;
2755*4882a593Smuzhiyun 		if (!(wcaps & AC_WCAP_POWER))
2756*4882a593Smuzhiyun 			continue;
2757*4882a593Smuzhiyun 		if (codec->power_filter) {
2758*4882a593Smuzhiyun 			state = codec->power_filter(codec, nid, power_state);
2759*4882a593Smuzhiyun 			if (state != power_state && power_state == AC_PWRST_D3)
2760*4882a593Smuzhiyun 				continue;
2761*4882a593Smuzhiyun 		}
2762*4882a593Smuzhiyun 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
2763*4882a593Smuzhiyun 				    state);
2764*4882a593Smuzhiyun 	}
2765*4882a593Smuzhiyun }
2766*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all);
2767*4882a593Smuzhiyun 
2768*4882a593Smuzhiyun /**
2769*4882a593Smuzhiyun  * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD
2770*4882a593Smuzhiyun  * @codec: the HDA codec
2771*4882a593Smuzhiyun  * @nid: widget NID
2772*4882a593Smuzhiyun  * @power_state: power state to evalue
2773*4882a593Smuzhiyun  *
2774*4882a593Smuzhiyun  * Don't power down the widget if it controls eapd and EAPD_BTLENABLE is set.
2775*4882a593Smuzhiyun  * This can be used a codec power_filter callback.
2776*4882a593Smuzhiyun  */
snd_hda_codec_eapd_power_filter(struct hda_codec * codec,hda_nid_t nid,unsigned int power_state)2777*4882a593Smuzhiyun unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
2778*4882a593Smuzhiyun 					     hda_nid_t nid,
2779*4882a593Smuzhiyun 					     unsigned int power_state)
2780*4882a593Smuzhiyun {
2781*4882a593Smuzhiyun 	if (nid == codec->core.afg || nid == codec->core.mfg)
2782*4882a593Smuzhiyun 		return power_state;
2783*4882a593Smuzhiyun 	if (power_state == AC_PWRST_D3 &&
2784*4882a593Smuzhiyun 	    get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN &&
2785*4882a593Smuzhiyun 	    (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) {
2786*4882a593Smuzhiyun 		int eapd = snd_hda_codec_read(codec, nid, 0,
2787*4882a593Smuzhiyun 					      AC_VERB_GET_EAPD_BTLENABLE, 0);
2788*4882a593Smuzhiyun 		if (eapd & 0x02)
2789*4882a593Smuzhiyun 			return AC_PWRST_D0;
2790*4882a593Smuzhiyun 	}
2791*4882a593Smuzhiyun 	return power_state;
2792*4882a593Smuzhiyun }
2793*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_eapd_power_filter);
2794*4882a593Smuzhiyun 
2795*4882a593Smuzhiyun /*
2796*4882a593Smuzhiyun  * set power state of the codec, and return the power state
2797*4882a593Smuzhiyun  */
hda_set_power_state(struct hda_codec * codec,unsigned int power_state)2798*4882a593Smuzhiyun static unsigned int hda_set_power_state(struct hda_codec *codec,
2799*4882a593Smuzhiyun 					unsigned int power_state)
2800*4882a593Smuzhiyun {
2801*4882a593Smuzhiyun 	hda_nid_t fg = codec->core.afg ? codec->core.afg : codec->core.mfg;
2802*4882a593Smuzhiyun 	int count;
2803*4882a593Smuzhiyun 	unsigned int state;
2804*4882a593Smuzhiyun 	int flags = 0;
2805*4882a593Smuzhiyun 
2806*4882a593Smuzhiyun 	/* this delay seems necessary to avoid click noise at power-down */
2807*4882a593Smuzhiyun 	if (power_state == AC_PWRST_D3) {
2808*4882a593Smuzhiyun 		if (codec->depop_delay < 0)
2809*4882a593Smuzhiyun 			msleep(codec_has_epss(codec) ? 10 : 100);
2810*4882a593Smuzhiyun 		else if (codec->depop_delay > 0)
2811*4882a593Smuzhiyun 			msleep(codec->depop_delay);
2812*4882a593Smuzhiyun 		flags = HDA_RW_NO_RESPONSE_FALLBACK;
2813*4882a593Smuzhiyun 	}
2814*4882a593Smuzhiyun 
2815*4882a593Smuzhiyun 	/* repeat power states setting at most 10 times*/
2816*4882a593Smuzhiyun 	for (count = 0; count < 10; count++) {
2817*4882a593Smuzhiyun 		if (codec->patch_ops.set_power_state)
2818*4882a593Smuzhiyun 			codec->patch_ops.set_power_state(codec, fg,
2819*4882a593Smuzhiyun 							 power_state);
2820*4882a593Smuzhiyun 		else {
2821*4882a593Smuzhiyun 			state = power_state;
2822*4882a593Smuzhiyun 			if (codec->power_filter)
2823*4882a593Smuzhiyun 				state = codec->power_filter(codec, fg, state);
2824*4882a593Smuzhiyun 			if (state == power_state || power_state != AC_PWRST_D3)
2825*4882a593Smuzhiyun 				snd_hda_codec_read(codec, fg, flags,
2826*4882a593Smuzhiyun 						   AC_VERB_SET_POWER_STATE,
2827*4882a593Smuzhiyun 						   state);
2828*4882a593Smuzhiyun 			snd_hda_codec_set_power_to_all(codec, fg, power_state);
2829*4882a593Smuzhiyun 		}
2830*4882a593Smuzhiyun 		state = snd_hda_sync_power_state(codec, fg, power_state);
2831*4882a593Smuzhiyun 		if (!(state & AC_PWRST_ERROR))
2832*4882a593Smuzhiyun 			break;
2833*4882a593Smuzhiyun 	}
2834*4882a593Smuzhiyun 
2835*4882a593Smuzhiyun 	return state;
2836*4882a593Smuzhiyun }
2837*4882a593Smuzhiyun 
2838*4882a593Smuzhiyun /* sync power states of all widgets;
2839*4882a593Smuzhiyun  * this is called at the end of codec parsing
2840*4882a593Smuzhiyun  */
sync_power_up_states(struct hda_codec * codec)2841*4882a593Smuzhiyun static void sync_power_up_states(struct hda_codec *codec)
2842*4882a593Smuzhiyun {
2843*4882a593Smuzhiyun 	hda_nid_t nid;
2844*4882a593Smuzhiyun 
2845*4882a593Smuzhiyun 	/* don't care if no filter is used */
2846*4882a593Smuzhiyun 	if (!codec->power_filter)
2847*4882a593Smuzhiyun 		return;
2848*4882a593Smuzhiyun 
2849*4882a593Smuzhiyun 	for_each_hda_codec_node(nid, codec) {
2850*4882a593Smuzhiyun 		unsigned int wcaps = get_wcaps(codec, nid);
2851*4882a593Smuzhiyun 		unsigned int target;
2852*4882a593Smuzhiyun 		if (!(wcaps & AC_WCAP_POWER))
2853*4882a593Smuzhiyun 			continue;
2854*4882a593Smuzhiyun 		target = codec->power_filter(codec, nid, AC_PWRST_D0);
2855*4882a593Smuzhiyun 		if (target == AC_PWRST_D0)
2856*4882a593Smuzhiyun 			continue;
2857*4882a593Smuzhiyun 		if (!snd_hda_check_power_state(codec, nid, target))
2858*4882a593Smuzhiyun 			snd_hda_codec_write(codec, nid, 0,
2859*4882a593Smuzhiyun 					    AC_VERB_SET_POWER_STATE, target);
2860*4882a593Smuzhiyun 	}
2861*4882a593Smuzhiyun }
2862*4882a593Smuzhiyun 
2863*4882a593Smuzhiyun #ifdef CONFIG_SND_HDA_RECONFIG
2864*4882a593Smuzhiyun /* execute additional init verbs */
hda_exec_init_verbs(struct hda_codec * codec)2865*4882a593Smuzhiyun static void hda_exec_init_verbs(struct hda_codec *codec)
2866*4882a593Smuzhiyun {
2867*4882a593Smuzhiyun 	if (codec->init_verbs.list)
2868*4882a593Smuzhiyun 		snd_hda_sequence_write(codec, codec->init_verbs.list);
2869*4882a593Smuzhiyun }
2870*4882a593Smuzhiyun #else
hda_exec_init_verbs(struct hda_codec * codec)2871*4882a593Smuzhiyun static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
2872*4882a593Smuzhiyun #endif
2873*4882a593Smuzhiyun 
2874*4882a593Smuzhiyun #ifdef CONFIG_PM
2875*4882a593Smuzhiyun /* update the power on/off account with the current jiffies */
update_power_acct(struct hda_codec * codec,bool on)2876*4882a593Smuzhiyun static void update_power_acct(struct hda_codec *codec, bool on)
2877*4882a593Smuzhiyun {
2878*4882a593Smuzhiyun 	unsigned long delta = jiffies - codec->power_jiffies;
2879*4882a593Smuzhiyun 
2880*4882a593Smuzhiyun 	if (on)
2881*4882a593Smuzhiyun 		codec->power_on_acct += delta;
2882*4882a593Smuzhiyun 	else
2883*4882a593Smuzhiyun 		codec->power_off_acct += delta;
2884*4882a593Smuzhiyun 	codec->power_jiffies += delta;
2885*4882a593Smuzhiyun }
2886*4882a593Smuzhiyun 
snd_hda_update_power_acct(struct hda_codec * codec)2887*4882a593Smuzhiyun void snd_hda_update_power_acct(struct hda_codec *codec)
2888*4882a593Smuzhiyun {
2889*4882a593Smuzhiyun 	update_power_acct(codec, hda_codec_is_power_on(codec));
2890*4882a593Smuzhiyun }
2891*4882a593Smuzhiyun 
2892*4882a593Smuzhiyun /*
2893*4882a593Smuzhiyun  * call suspend and power-down; used both from PM and power-save
2894*4882a593Smuzhiyun  * this function returns the power state in the end
2895*4882a593Smuzhiyun  */
hda_call_codec_suspend(struct hda_codec * codec)2896*4882a593Smuzhiyun static unsigned int hda_call_codec_suspend(struct hda_codec *codec)
2897*4882a593Smuzhiyun {
2898*4882a593Smuzhiyun 	unsigned int state;
2899*4882a593Smuzhiyun 
2900*4882a593Smuzhiyun 	snd_hdac_enter_pm(&codec->core);
2901*4882a593Smuzhiyun 	if (codec->patch_ops.suspend)
2902*4882a593Smuzhiyun 		codec->patch_ops.suspend(codec);
2903*4882a593Smuzhiyun 	hda_cleanup_all_streams(codec);
2904*4882a593Smuzhiyun 	state = hda_set_power_state(codec, AC_PWRST_D3);
2905*4882a593Smuzhiyun 	update_power_acct(codec, true);
2906*4882a593Smuzhiyun 	snd_hdac_leave_pm(&codec->core);
2907*4882a593Smuzhiyun 	return state;
2908*4882a593Smuzhiyun }
2909*4882a593Smuzhiyun 
2910*4882a593Smuzhiyun /*
2911*4882a593Smuzhiyun  * kick up codec; used both from PM and power-save
2912*4882a593Smuzhiyun  */
hda_call_codec_resume(struct hda_codec * codec)2913*4882a593Smuzhiyun static void hda_call_codec_resume(struct hda_codec *codec)
2914*4882a593Smuzhiyun {
2915*4882a593Smuzhiyun 	snd_hdac_enter_pm(&codec->core);
2916*4882a593Smuzhiyun 	if (codec->core.regmap)
2917*4882a593Smuzhiyun 		regcache_mark_dirty(codec->core.regmap);
2918*4882a593Smuzhiyun 
2919*4882a593Smuzhiyun 	codec->power_jiffies = jiffies;
2920*4882a593Smuzhiyun 
2921*4882a593Smuzhiyun 	hda_set_power_state(codec, AC_PWRST_D0);
2922*4882a593Smuzhiyun 	restore_shutup_pins(codec);
2923*4882a593Smuzhiyun 	hda_exec_init_verbs(codec);
2924*4882a593Smuzhiyun 	snd_hda_jack_set_dirty_all(codec);
2925*4882a593Smuzhiyun 	if (codec->patch_ops.resume)
2926*4882a593Smuzhiyun 		codec->patch_ops.resume(codec);
2927*4882a593Smuzhiyun 	else {
2928*4882a593Smuzhiyun 		if (codec->patch_ops.init)
2929*4882a593Smuzhiyun 			codec->patch_ops.init(codec);
2930*4882a593Smuzhiyun 		snd_hda_regmap_sync(codec);
2931*4882a593Smuzhiyun 	}
2932*4882a593Smuzhiyun 
2933*4882a593Smuzhiyun 	if (codec->jackpoll_interval)
2934*4882a593Smuzhiyun 		hda_jackpoll_work(&codec->jackpoll_work.work);
2935*4882a593Smuzhiyun 	else
2936*4882a593Smuzhiyun 		snd_hda_jack_report_sync(codec);
2937*4882a593Smuzhiyun 	codec->core.dev.power.power_state = PMSG_ON;
2938*4882a593Smuzhiyun 	snd_hdac_leave_pm(&codec->core);
2939*4882a593Smuzhiyun }
2940*4882a593Smuzhiyun 
hda_codec_runtime_suspend(struct device * dev)2941*4882a593Smuzhiyun static int hda_codec_runtime_suspend(struct device *dev)
2942*4882a593Smuzhiyun {
2943*4882a593Smuzhiyun 	struct hda_codec *codec = dev_to_hda_codec(dev);
2944*4882a593Smuzhiyun 	unsigned int state;
2945*4882a593Smuzhiyun 
2946*4882a593Smuzhiyun 	/* Nothing to do if card registration fails and the component driver never probes */
2947*4882a593Smuzhiyun 	if (!codec->card)
2948*4882a593Smuzhiyun 		return 0;
2949*4882a593Smuzhiyun 
2950*4882a593Smuzhiyun 	cancel_delayed_work_sync(&codec->jackpoll_work);
2951*4882a593Smuzhiyun 	state = hda_call_codec_suspend(codec);
2952*4882a593Smuzhiyun 	if (codec->link_down_at_suspend ||
2953*4882a593Smuzhiyun 	    (codec_has_clkstop(codec) && codec_has_epss(codec) &&
2954*4882a593Smuzhiyun 	     (state & AC_PWRST_CLK_STOP_OK)))
2955*4882a593Smuzhiyun 		snd_hdac_codec_link_down(&codec->core);
2956*4882a593Smuzhiyun 	codec_display_power(codec, false);
2957*4882a593Smuzhiyun 	return 0;
2958*4882a593Smuzhiyun }
2959*4882a593Smuzhiyun 
hda_codec_runtime_resume(struct device * dev)2960*4882a593Smuzhiyun static int hda_codec_runtime_resume(struct device *dev)
2961*4882a593Smuzhiyun {
2962*4882a593Smuzhiyun 	struct hda_codec *codec = dev_to_hda_codec(dev);
2963*4882a593Smuzhiyun 
2964*4882a593Smuzhiyun 	/* Nothing to do if card registration fails and the component driver never probes */
2965*4882a593Smuzhiyun 	if (!codec->card)
2966*4882a593Smuzhiyun 		return 0;
2967*4882a593Smuzhiyun 
2968*4882a593Smuzhiyun 	codec_display_power(codec, true);
2969*4882a593Smuzhiyun 	snd_hdac_codec_link_up(&codec->core);
2970*4882a593Smuzhiyun 	hda_call_codec_resume(codec);
2971*4882a593Smuzhiyun 	pm_runtime_mark_last_busy(dev);
2972*4882a593Smuzhiyun 	return 0;
2973*4882a593Smuzhiyun }
2974*4882a593Smuzhiyun 
2975*4882a593Smuzhiyun #endif /* CONFIG_PM */
2976*4882a593Smuzhiyun 
2977*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
hda_codec_pm_prepare(struct device * dev)2978*4882a593Smuzhiyun static int hda_codec_pm_prepare(struct device *dev)
2979*4882a593Smuzhiyun {
2980*4882a593Smuzhiyun 	dev->power.power_state = PMSG_SUSPEND;
2981*4882a593Smuzhiyun 	return pm_runtime_suspended(dev);
2982*4882a593Smuzhiyun }
2983*4882a593Smuzhiyun 
hda_codec_pm_complete(struct device * dev)2984*4882a593Smuzhiyun static void hda_codec_pm_complete(struct device *dev)
2985*4882a593Smuzhiyun {
2986*4882a593Smuzhiyun 	struct hda_codec *codec = dev_to_hda_codec(dev);
2987*4882a593Smuzhiyun 
2988*4882a593Smuzhiyun 	/* If no other pm-functions are called between prepare() and complete() */
2989*4882a593Smuzhiyun 	if (dev->power.power_state.event == PM_EVENT_SUSPEND)
2990*4882a593Smuzhiyun 		dev->power.power_state = PMSG_RESUME;
2991*4882a593Smuzhiyun 
2992*4882a593Smuzhiyun 	if (pm_runtime_suspended(dev) && (codec->jackpoll_interval ||
2993*4882a593Smuzhiyun 	    hda_codec_need_resume(codec) || codec->forced_resume))
2994*4882a593Smuzhiyun 		pm_request_resume(dev);
2995*4882a593Smuzhiyun }
2996*4882a593Smuzhiyun 
hda_codec_pm_suspend(struct device * dev)2997*4882a593Smuzhiyun static int hda_codec_pm_suspend(struct device *dev)
2998*4882a593Smuzhiyun {
2999*4882a593Smuzhiyun 	dev->power.power_state = PMSG_SUSPEND;
3000*4882a593Smuzhiyun 	return pm_runtime_force_suspend(dev);
3001*4882a593Smuzhiyun }
3002*4882a593Smuzhiyun 
hda_codec_pm_resume(struct device * dev)3003*4882a593Smuzhiyun static int hda_codec_pm_resume(struct device *dev)
3004*4882a593Smuzhiyun {
3005*4882a593Smuzhiyun 	dev->power.power_state = PMSG_RESUME;
3006*4882a593Smuzhiyun 	return pm_runtime_force_resume(dev);
3007*4882a593Smuzhiyun }
3008*4882a593Smuzhiyun 
hda_codec_pm_freeze(struct device * dev)3009*4882a593Smuzhiyun static int hda_codec_pm_freeze(struct device *dev)
3010*4882a593Smuzhiyun {
3011*4882a593Smuzhiyun 	dev->power.power_state = PMSG_FREEZE;
3012*4882a593Smuzhiyun 	return pm_runtime_force_suspend(dev);
3013*4882a593Smuzhiyun }
3014*4882a593Smuzhiyun 
hda_codec_pm_thaw(struct device * dev)3015*4882a593Smuzhiyun static int hda_codec_pm_thaw(struct device *dev)
3016*4882a593Smuzhiyun {
3017*4882a593Smuzhiyun 	dev->power.power_state = PMSG_THAW;
3018*4882a593Smuzhiyun 	return pm_runtime_force_resume(dev);
3019*4882a593Smuzhiyun }
3020*4882a593Smuzhiyun 
hda_codec_pm_restore(struct device * dev)3021*4882a593Smuzhiyun static int hda_codec_pm_restore(struct device *dev)
3022*4882a593Smuzhiyun {
3023*4882a593Smuzhiyun 	dev->power.power_state = PMSG_RESTORE;
3024*4882a593Smuzhiyun 	return pm_runtime_force_resume(dev);
3025*4882a593Smuzhiyun }
3026*4882a593Smuzhiyun #endif /* CONFIG_PM_SLEEP */
3027*4882a593Smuzhiyun 
3028*4882a593Smuzhiyun /* referred in hda_bind.c */
3029*4882a593Smuzhiyun const struct dev_pm_ops hda_codec_driver_pm = {
3030*4882a593Smuzhiyun #ifdef CONFIG_PM_SLEEP
3031*4882a593Smuzhiyun 	.prepare = hda_codec_pm_prepare,
3032*4882a593Smuzhiyun 	.complete = hda_codec_pm_complete,
3033*4882a593Smuzhiyun 	.suspend = hda_codec_pm_suspend,
3034*4882a593Smuzhiyun 	.resume = hda_codec_pm_resume,
3035*4882a593Smuzhiyun 	.freeze = hda_codec_pm_freeze,
3036*4882a593Smuzhiyun 	.thaw = hda_codec_pm_thaw,
3037*4882a593Smuzhiyun 	.poweroff = hda_codec_pm_suspend,
3038*4882a593Smuzhiyun 	.restore = hda_codec_pm_restore,
3039*4882a593Smuzhiyun #endif /* CONFIG_PM_SLEEP */
3040*4882a593Smuzhiyun 	SET_RUNTIME_PM_OPS(hda_codec_runtime_suspend, hda_codec_runtime_resume,
3041*4882a593Smuzhiyun 			   NULL)
3042*4882a593Smuzhiyun };
3043*4882a593Smuzhiyun 
3044*4882a593Smuzhiyun /*
3045*4882a593Smuzhiyun  * add standard channel maps if not specified
3046*4882a593Smuzhiyun  */
add_std_chmaps(struct hda_codec * codec)3047*4882a593Smuzhiyun static int add_std_chmaps(struct hda_codec *codec)
3048*4882a593Smuzhiyun {
3049*4882a593Smuzhiyun 	struct hda_pcm *pcm;
3050*4882a593Smuzhiyun 	int str, err;
3051*4882a593Smuzhiyun 
3052*4882a593Smuzhiyun 	list_for_each_entry(pcm, &codec->pcm_list_head, list) {
3053*4882a593Smuzhiyun 		for (str = 0; str < 2; str++) {
3054*4882a593Smuzhiyun 			struct hda_pcm_stream *hinfo = &pcm->stream[str];
3055*4882a593Smuzhiyun 			struct snd_pcm_chmap *chmap;
3056*4882a593Smuzhiyun 			const struct snd_pcm_chmap_elem *elem;
3057*4882a593Smuzhiyun 
3058*4882a593Smuzhiyun 			if (!pcm->pcm || pcm->own_chmap || !hinfo->substreams)
3059*4882a593Smuzhiyun 				continue;
3060*4882a593Smuzhiyun 			elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps;
3061*4882a593Smuzhiyun 			err = snd_pcm_add_chmap_ctls(pcm->pcm, str, elem,
3062*4882a593Smuzhiyun 						     hinfo->channels_max,
3063*4882a593Smuzhiyun 						     0, &chmap);
3064*4882a593Smuzhiyun 			if (err < 0)
3065*4882a593Smuzhiyun 				return err;
3066*4882a593Smuzhiyun 			chmap->channel_mask = SND_PCM_CHMAP_MASK_2468;
3067*4882a593Smuzhiyun 		}
3068*4882a593Smuzhiyun 	}
3069*4882a593Smuzhiyun 	return 0;
3070*4882a593Smuzhiyun }
3071*4882a593Smuzhiyun 
3072*4882a593Smuzhiyun /* default channel maps for 2.1 speakers;
3073*4882a593Smuzhiyun  * since HD-audio supports only stereo, odd number channels are omitted
3074*4882a593Smuzhiyun  */
3075*4882a593Smuzhiyun const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[] = {
3076*4882a593Smuzhiyun 	{ .channels = 2,
3077*4882a593Smuzhiyun 	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
3078*4882a593Smuzhiyun 	{ .channels = 4,
3079*4882a593Smuzhiyun 	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
3080*4882a593Smuzhiyun 		   SNDRV_CHMAP_LFE, SNDRV_CHMAP_LFE } },
3081*4882a593Smuzhiyun 	{ }
3082*4882a593Smuzhiyun };
3083*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_pcm_2_1_chmaps);
3084*4882a593Smuzhiyun 
snd_hda_codec_build_controls(struct hda_codec * codec)3085*4882a593Smuzhiyun int snd_hda_codec_build_controls(struct hda_codec *codec)
3086*4882a593Smuzhiyun {
3087*4882a593Smuzhiyun 	int err = 0;
3088*4882a593Smuzhiyun 	hda_exec_init_verbs(codec);
3089*4882a593Smuzhiyun 	/* continue to initialize... */
3090*4882a593Smuzhiyun 	if (codec->patch_ops.init)
3091*4882a593Smuzhiyun 		err = codec->patch_ops.init(codec);
3092*4882a593Smuzhiyun 	if (!err && codec->patch_ops.build_controls)
3093*4882a593Smuzhiyun 		err = codec->patch_ops.build_controls(codec);
3094*4882a593Smuzhiyun 	if (err < 0)
3095*4882a593Smuzhiyun 		return err;
3096*4882a593Smuzhiyun 
3097*4882a593Smuzhiyun 	/* we create chmaps here instead of build_pcms */
3098*4882a593Smuzhiyun 	err = add_std_chmaps(codec);
3099*4882a593Smuzhiyun 	if (err < 0)
3100*4882a593Smuzhiyun 		return err;
3101*4882a593Smuzhiyun 
3102*4882a593Smuzhiyun 	if (codec->jackpoll_interval)
3103*4882a593Smuzhiyun 		hda_jackpoll_work(&codec->jackpoll_work.work);
3104*4882a593Smuzhiyun 	else
3105*4882a593Smuzhiyun 		snd_hda_jack_report_sync(codec); /* call at the last init point */
3106*4882a593Smuzhiyun 	sync_power_up_states(codec);
3107*4882a593Smuzhiyun 	return 0;
3108*4882a593Smuzhiyun }
3109*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_build_controls);
3110*4882a593Smuzhiyun 
3111*4882a593Smuzhiyun /*
3112*4882a593Smuzhiyun  * PCM stuff
3113*4882a593Smuzhiyun  */
hda_pcm_default_open_close(struct hda_pcm_stream * hinfo,struct hda_codec * codec,struct snd_pcm_substream * substream)3114*4882a593Smuzhiyun static int hda_pcm_default_open_close(struct hda_pcm_stream *hinfo,
3115*4882a593Smuzhiyun 				      struct hda_codec *codec,
3116*4882a593Smuzhiyun 				      struct snd_pcm_substream *substream)
3117*4882a593Smuzhiyun {
3118*4882a593Smuzhiyun 	return 0;
3119*4882a593Smuzhiyun }
3120*4882a593Smuzhiyun 
hda_pcm_default_prepare(struct hda_pcm_stream * hinfo,struct hda_codec * codec,unsigned int stream_tag,unsigned int format,struct snd_pcm_substream * substream)3121*4882a593Smuzhiyun static int hda_pcm_default_prepare(struct hda_pcm_stream *hinfo,
3122*4882a593Smuzhiyun 				   struct hda_codec *codec,
3123*4882a593Smuzhiyun 				   unsigned int stream_tag,
3124*4882a593Smuzhiyun 				   unsigned int format,
3125*4882a593Smuzhiyun 				   struct snd_pcm_substream *substream)
3126*4882a593Smuzhiyun {
3127*4882a593Smuzhiyun 	snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
3128*4882a593Smuzhiyun 	return 0;
3129*4882a593Smuzhiyun }
3130*4882a593Smuzhiyun 
hda_pcm_default_cleanup(struct hda_pcm_stream * hinfo,struct hda_codec * codec,struct snd_pcm_substream * substream)3131*4882a593Smuzhiyun static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
3132*4882a593Smuzhiyun 				   struct hda_codec *codec,
3133*4882a593Smuzhiyun 				   struct snd_pcm_substream *substream)
3134*4882a593Smuzhiyun {
3135*4882a593Smuzhiyun 	snd_hda_codec_cleanup_stream(codec, hinfo->nid);
3136*4882a593Smuzhiyun 	return 0;
3137*4882a593Smuzhiyun }
3138*4882a593Smuzhiyun 
set_pcm_default_values(struct hda_codec * codec,struct hda_pcm_stream * info)3139*4882a593Smuzhiyun static int set_pcm_default_values(struct hda_codec *codec,
3140*4882a593Smuzhiyun 				  struct hda_pcm_stream *info)
3141*4882a593Smuzhiyun {
3142*4882a593Smuzhiyun 	int err;
3143*4882a593Smuzhiyun 
3144*4882a593Smuzhiyun 	/* query support PCM information from the given NID */
3145*4882a593Smuzhiyun 	if (info->nid && (!info->rates || !info->formats)) {
3146*4882a593Smuzhiyun 		err = snd_hda_query_supported_pcm(codec, info->nid,
3147*4882a593Smuzhiyun 				info->rates ? NULL : &info->rates,
3148*4882a593Smuzhiyun 				info->formats ? NULL : &info->formats,
3149*4882a593Smuzhiyun 				info->maxbps ? NULL : &info->maxbps);
3150*4882a593Smuzhiyun 		if (err < 0)
3151*4882a593Smuzhiyun 			return err;
3152*4882a593Smuzhiyun 	}
3153*4882a593Smuzhiyun 	if (info->ops.open == NULL)
3154*4882a593Smuzhiyun 		info->ops.open = hda_pcm_default_open_close;
3155*4882a593Smuzhiyun 	if (info->ops.close == NULL)
3156*4882a593Smuzhiyun 		info->ops.close = hda_pcm_default_open_close;
3157*4882a593Smuzhiyun 	if (info->ops.prepare == NULL) {
3158*4882a593Smuzhiyun 		if (snd_BUG_ON(!info->nid))
3159*4882a593Smuzhiyun 			return -EINVAL;
3160*4882a593Smuzhiyun 		info->ops.prepare = hda_pcm_default_prepare;
3161*4882a593Smuzhiyun 	}
3162*4882a593Smuzhiyun 	if (info->ops.cleanup == NULL) {
3163*4882a593Smuzhiyun 		if (snd_BUG_ON(!info->nid))
3164*4882a593Smuzhiyun 			return -EINVAL;
3165*4882a593Smuzhiyun 		info->ops.cleanup = hda_pcm_default_cleanup;
3166*4882a593Smuzhiyun 	}
3167*4882a593Smuzhiyun 	return 0;
3168*4882a593Smuzhiyun }
3169*4882a593Smuzhiyun 
3170*4882a593Smuzhiyun /*
3171*4882a593Smuzhiyun  * codec prepare/cleanup entries
3172*4882a593Smuzhiyun  */
3173*4882a593Smuzhiyun /**
3174*4882a593Smuzhiyun  * snd_hda_codec_prepare - Prepare a stream
3175*4882a593Smuzhiyun  * @codec: the HDA codec
3176*4882a593Smuzhiyun  * @hinfo: PCM information
3177*4882a593Smuzhiyun  * @stream: stream tag to assign
3178*4882a593Smuzhiyun  * @format: format id to assign
3179*4882a593Smuzhiyun  * @substream: PCM substream to assign
3180*4882a593Smuzhiyun  *
3181*4882a593Smuzhiyun  * Calls the prepare callback set by the codec with the given arguments.
3182*4882a593Smuzhiyun  * Clean up the inactive streams when successful.
3183*4882a593Smuzhiyun  */
snd_hda_codec_prepare(struct hda_codec * codec,struct hda_pcm_stream * hinfo,unsigned int stream,unsigned int format,struct snd_pcm_substream * substream)3184*4882a593Smuzhiyun int snd_hda_codec_prepare(struct hda_codec *codec,
3185*4882a593Smuzhiyun 			  struct hda_pcm_stream *hinfo,
3186*4882a593Smuzhiyun 			  unsigned int stream,
3187*4882a593Smuzhiyun 			  unsigned int format,
3188*4882a593Smuzhiyun 			  struct snd_pcm_substream *substream)
3189*4882a593Smuzhiyun {
3190*4882a593Smuzhiyun 	int ret;
3191*4882a593Smuzhiyun 	mutex_lock(&codec->bus->prepare_mutex);
3192*4882a593Smuzhiyun 	if (hinfo->ops.prepare)
3193*4882a593Smuzhiyun 		ret = hinfo->ops.prepare(hinfo, codec, stream, format,
3194*4882a593Smuzhiyun 					 substream);
3195*4882a593Smuzhiyun 	else
3196*4882a593Smuzhiyun 		ret = -ENODEV;
3197*4882a593Smuzhiyun 	if (ret >= 0)
3198*4882a593Smuzhiyun 		purify_inactive_streams(codec);
3199*4882a593Smuzhiyun 	mutex_unlock(&codec->bus->prepare_mutex);
3200*4882a593Smuzhiyun 	return ret;
3201*4882a593Smuzhiyun }
3202*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_prepare);
3203*4882a593Smuzhiyun 
3204*4882a593Smuzhiyun /**
3205*4882a593Smuzhiyun  * snd_hda_codec_cleanup - Clean up stream resources
3206*4882a593Smuzhiyun  * @codec: the HDA codec
3207*4882a593Smuzhiyun  * @hinfo: PCM information
3208*4882a593Smuzhiyun  * @substream: PCM substream
3209*4882a593Smuzhiyun  *
3210*4882a593Smuzhiyun  * Calls the cleanup callback set by the codec with the given arguments.
3211*4882a593Smuzhiyun  */
snd_hda_codec_cleanup(struct hda_codec * codec,struct hda_pcm_stream * hinfo,struct snd_pcm_substream * substream)3212*4882a593Smuzhiyun void snd_hda_codec_cleanup(struct hda_codec *codec,
3213*4882a593Smuzhiyun 			   struct hda_pcm_stream *hinfo,
3214*4882a593Smuzhiyun 			   struct snd_pcm_substream *substream)
3215*4882a593Smuzhiyun {
3216*4882a593Smuzhiyun 	mutex_lock(&codec->bus->prepare_mutex);
3217*4882a593Smuzhiyun 	if (hinfo->ops.cleanup)
3218*4882a593Smuzhiyun 		hinfo->ops.cleanup(hinfo, codec, substream);
3219*4882a593Smuzhiyun 	mutex_unlock(&codec->bus->prepare_mutex);
3220*4882a593Smuzhiyun }
3221*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup);
3222*4882a593Smuzhiyun 
3223*4882a593Smuzhiyun /* global */
3224*4882a593Smuzhiyun const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
3225*4882a593Smuzhiyun 	"Audio", "SPDIF", "HDMI", "Modem"
3226*4882a593Smuzhiyun };
3227*4882a593Smuzhiyun 
3228*4882a593Smuzhiyun /*
3229*4882a593Smuzhiyun  * get the empty PCM device number to assign
3230*4882a593Smuzhiyun  */
get_empty_pcm_device(struct hda_bus * bus,unsigned int type)3231*4882a593Smuzhiyun static int get_empty_pcm_device(struct hda_bus *bus, unsigned int type)
3232*4882a593Smuzhiyun {
3233*4882a593Smuzhiyun 	/* audio device indices; not linear to keep compatibility */
3234*4882a593Smuzhiyun 	/* assigned to static slots up to dev#10; if more needed, assign
3235*4882a593Smuzhiyun 	 * the later slot dynamically (when CONFIG_SND_DYNAMIC_MINORS=y)
3236*4882a593Smuzhiyun 	 */
3237*4882a593Smuzhiyun 	static const int audio_idx[HDA_PCM_NTYPES][5] = {
3238*4882a593Smuzhiyun 		[HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 },
3239*4882a593Smuzhiyun 		[HDA_PCM_TYPE_SPDIF] = { 1, -1 },
3240*4882a593Smuzhiyun 		[HDA_PCM_TYPE_HDMI]  = { 3, 7, 8, 9, -1 },
3241*4882a593Smuzhiyun 		[HDA_PCM_TYPE_MODEM] = { 6, -1 },
3242*4882a593Smuzhiyun 	};
3243*4882a593Smuzhiyun 	int i;
3244*4882a593Smuzhiyun 
3245*4882a593Smuzhiyun 	if (type >= HDA_PCM_NTYPES) {
3246*4882a593Smuzhiyun 		dev_err(bus->card->dev, "Invalid PCM type %d\n", type);
3247*4882a593Smuzhiyun 		return -EINVAL;
3248*4882a593Smuzhiyun 	}
3249*4882a593Smuzhiyun 
3250*4882a593Smuzhiyun 	for (i = 0; audio_idx[type][i] >= 0; i++) {
3251*4882a593Smuzhiyun #ifndef CONFIG_SND_DYNAMIC_MINORS
3252*4882a593Smuzhiyun 		if (audio_idx[type][i] >= 8)
3253*4882a593Smuzhiyun 			break;
3254*4882a593Smuzhiyun #endif
3255*4882a593Smuzhiyun 		if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
3256*4882a593Smuzhiyun 			return audio_idx[type][i];
3257*4882a593Smuzhiyun 	}
3258*4882a593Smuzhiyun 
3259*4882a593Smuzhiyun #ifdef CONFIG_SND_DYNAMIC_MINORS
3260*4882a593Smuzhiyun 	/* non-fixed slots starting from 10 */
3261*4882a593Smuzhiyun 	for (i = 10; i < 32; i++) {
3262*4882a593Smuzhiyun 		if (!test_and_set_bit(i, bus->pcm_dev_bits))
3263*4882a593Smuzhiyun 			return i;
3264*4882a593Smuzhiyun 	}
3265*4882a593Smuzhiyun #endif
3266*4882a593Smuzhiyun 
3267*4882a593Smuzhiyun 	dev_warn(bus->card->dev, "Too many %s devices\n",
3268*4882a593Smuzhiyun 		snd_hda_pcm_type_name[type]);
3269*4882a593Smuzhiyun #ifndef CONFIG_SND_DYNAMIC_MINORS
3270*4882a593Smuzhiyun 	dev_warn(bus->card->dev,
3271*4882a593Smuzhiyun 		 "Consider building the kernel with CONFIG_SND_DYNAMIC_MINORS=y\n");
3272*4882a593Smuzhiyun #endif
3273*4882a593Smuzhiyun 	return -EAGAIN;
3274*4882a593Smuzhiyun }
3275*4882a593Smuzhiyun 
3276*4882a593Smuzhiyun /* call build_pcms ops of the given codec and set up the default parameters */
snd_hda_codec_parse_pcms(struct hda_codec * codec)3277*4882a593Smuzhiyun int snd_hda_codec_parse_pcms(struct hda_codec *codec)
3278*4882a593Smuzhiyun {
3279*4882a593Smuzhiyun 	struct hda_pcm *cpcm;
3280*4882a593Smuzhiyun 	int err;
3281*4882a593Smuzhiyun 
3282*4882a593Smuzhiyun 	if (!list_empty(&codec->pcm_list_head))
3283*4882a593Smuzhiyun 		return 0; /* already parsed */
3284*4882a593Smuzhiyun 
3285*4882a593Smuzhiyun 	if (!codec->patch_ops.build_pcms)
3286*4882a593Smuzhiyun 		return 0;
3287*4882a593Smuzhiyun 
3288*4882a593Smuzhiyun 	err = codec->patch_ops.build_pcms(codec);
3289*4882a593Smuzhiyun 	if (err < 0) {
3290*4882a593Smuzhiyun 		codec_err(codec, "cannot build PCMs for #%d (error %d)\n",
3291*4882a593Smuzhiyun 			  codec->core.addr, err);
3292*4882a593Smuzhiyun 		return err;
3293*4882a593Smuzhiyun 	}
3294*4882a593Smuzhiyun 
3295*4882a593Smuzhiyun 	list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
3296*4882a593Smuzhiyun 		int stream;
3297*4882a593Smuzhiyun 
3298*4882a593Smuzhiyun 		for (stream = 0; stream < 2; stream++) {
3299*4882a593Smuzhiyun 			struct hda_pcm_stream *info = &cpcm->stream[stream];
3300*4882a593Smuzhiyun 
3301*4882a593Smuzhiyun 			if (!info->substreams)
3302*4882a593Smuzhiyun 				continue;
3303*4882a593Smuzhiyun 			err = set_pcm_default_values(codec, info);
3304*4882a593Smuzhiyun 			if (err < 0) {
3305*4882a593Smuzhiyun 				codec_warn(codec,
3306*4882a593Smuzhiyun 					   "fail to setup default for PCM %s\n",
3307*4882a593Smuzhiyun 					   cpcm->name);
3308*4882a593Smuzhiyun 				return err;
3309*4882a593Smuzhiyun 			}
3310*4882a593Smuzhiyun 		}
3311*4882a593Smuzhiyun 	}
3312*4882a593Smuzhiyun 
3313*4882a593Smuzhiyun 	return 0;
3314*4882a593Smuzhiyun }
3315*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_codec_parse_pcms);
3316*4882a593Smuzhiyun 
3317*4882a593Smuzhiyun /* assign all PCMs of the given codec */
snd_hda_codec_build_pcms(struct hda_codec * codec)3318*4882a593Smuzhiyun int snd_hda_codec_build_pcms(struct hda_codec *codec)
3319*4882a593Smuzhiyun {
3320*4882a593Smuzhiyun 	struct hda_bus *bus = codec->bus;
3321*4882a593Smuzhiyun 	struct hda_pcm *cpcm;
3322*4882a593Smuzhiyun 	int dev, err;
3323*4882a593Smuzhiyun 
3324*4882a593Smuzhiyun 	err = snd_hda_codec_parse_pcms(codec);
3325*4882a593Smuzhiyun 	if (err < 0)
3326*4882a593Smuzhiyun 		return err;
3327*4882a593Smuzhiyun 
3328*4882a593Smuzhiyun 	/* attach a new PCM streams */
3329*4882a593Smuzhiyun 	list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
3330*4882a593Smuzhiyun 		if (cpcm->pcm)
3331*4882a593Smuzhiyun 			continue; /* already attached */
3332*4882a593Smuzhiyun 		if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
3333*4882a593Smuzhiyun 			continue; /* no substreams assigned */
3334*4882a593Smuzhiyun 
3335*4882a593Smuzhiyun 		dev = get_empty_pcm_device(bus, cpcm->pcm_type);
3336*4882a593Smuzhiyun 		if (dev < 0) {
3337*4882a593Smuzhiyun 			cpcm->device = SNDRV_PCM_INVALID_DEVICE;
3338*4882a593Smuzhiyun 			continue; /* no fatal error */
3339*4882a593Smuzhiyun 		}
3340*4882a593Smuzhiyun 		cpcm->device = dev;
3341*4882a593Smuzhiyun 		err =  snd_hda_attach_pcm_stream(bus, codec, cpcm);
3342*4882a593Smuzhiyun 		if (err < 0) {
3343*4882a593Smuzhiyun 			codec_err(codec,
3344*4882a593Smuzhiyun 				  "cannot attach PCM stream %d for codec #%d\n",
3345*4882a593Smuzhiyun 				  dev, codec->core.addr);
3346*4882a593Smuzhiyun 			continue; /* no fatal error */
3347*4882a593Smuzhiyun 		}
3348*4882a593Smuzhiyun 	}
3349*4882a593Smuzhiyun 
3350*4882a593Smuzhiyun 	return 0;
3351*4882a593Smuzhiyun }
3352*4882a593Smuzhiyun 
3353*4882a593Smuzhiyun /**
3354*4882a593Smuzhiyun  * snd_hda_add_new_ctls - create controls from the array
3355*4882a593Smuzhiyun  * @codec: the HDA codec
3356*4882a593Smuzhiyun  * @knew: the array of struct snd_kcontrol_new
3357*4882a593Smuzhiyun  *
3358*4882a593Smuzhiyun  * This helper function creates and add new controls in the given array.
3359*4882a593Smuzhiyun  * The array must be terminated with an empty entry as terminator.
3360*4882a593Smuzhiyun  *
3361*4882a593Smuzhiyun  * Returns 0 if successful, or a negative error code.
3362*4882a593Smuzhiyun  */
snd_hda_add_new_ctls(struct hda_codec * codec,const struct snd_kcontrol_new * knew)3363*4882a593Smuzhiyun int snd_hda_add_new_ctls(struct hda_codec *codec,
3364*4882a593Smuzhiyun 			 const struct snd_kcontrol_new *knew)
3365*4882a593Smuzhiyun {
3366*4882a593Smuzhiyun 	int err;
3367*4882a593Smuzhiyun 
3368*4882a593Smuzhiyun 	for (; knew->name; knew++) {
3369*4882a593Smuzhiyun 		struct snd_kcontrol *kctl;
3370*4882a593Smuzhiyun 		int addr = 0, idx = 0;
3371*4882a593Smuzhiyun 		if (knew->iface == (__force snd_ctl_elem_iface_t)-1)
3372*4882a593Smuzhiyun 			continue; /* skip this codec private value */
3373*4882a593Smuzhiyun 		for (;;) {
3374*4882a593Smuzhiyun 			kctl = snd_ctl_new1(knew, codec);
3375*4882a593Smuzhiyun 			if (!kctl)
3376*4882a593Smuzhiyun 				return -ENOMEM;
3377*4882a593Smuzhiyun 			if (addr > 0)
3378*4882a593Smuzhiyun 				kctl->id.device = addr;
3379*4882a593Smuzhiyun 			if (idx > 0)
3380*4882a593Smuzhiyun 				kctl->id.index = idx;
3381*4882a593Smuzhiyun 			err = snd_hda_ctl_add(codec, 0, kctl);
3382*4882a593Smuzhiyun 			if (!err)
3383*4882a593Smuzhiyun 				break;
3384*4882a593Smuzhiyun 			/* try first with another device index corresponding to
3385*4882a593Smuzhiyun 			 * the codec addr; if it still fails (or it's the
3386*4882a593Smuzhiyun 			 * primary codec), then try another control index
3387*4882a593Smuzhiyun 			 */
3388*4882a593Smuzhiyun 			if (!addr && codec->core.addr)
3389*4882a593Smuzhiyun 				addr = codec->core.addr;
3390*4882a593Smuzhiyun 			else if (!idx && !knew->index) {
3391*4882a593Smuzhiyun 				idx = find_empty_mixer_ctl_idx(codec,
3392*4882a593Smuzhiyun 							       knew->name, 0);
3393*4882a593Smuzhiyun 				if (idx <= 0)
3394*4882a593Smuzhiyun 					return err;
3395*4882a593Smuzhiyun 			} else
3396*4882a593Smuzhiyun 				return err;
3397*4882a593Smuzhiyun 		}
3398*4882a593Smuzhiyun 	}
3399*4882a593Smuzhiyun 	return 0;
3400*4882a593Smuzhiyun }
3401*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_add_new_ctls);
3402*4882a593Smuzhiyun 
3403*4882a593Smuzhiyun #ifdef CONFIG_PM
codec_set_power_save(struct hda_codec * codec,int delay)3404*4882a593Smuzhiyun static void codec_set_power_save(struct hda_codec *codec, int delay)
3405*4882a593Smuzhiyun {
3406*4882a593Smuzhiyun 	struct device *dev = hda_codec_dev(codec);
3407*4882a593Smuzhiyun 
3408*4882a593Smuzhiyun 	if (delay == 0 && codec->auto_runtime_pm)
3409*4882a593Smuzhiyun 		delay = 3000;
3410*4882a593Smuzhiyun 
3411*4882a593Smuzhiyun 	if (delay > 0) {
3412*4882a593Smuzhiyun 		pm_runtime_set_autosuspend_delay(dev, delay);
3413*4882a593Smuzhiyun 		pm_runtime_use_autosuspend(dev);
3414*4882a593Smuzhiyun 		pm_runtime_allow(dev);
3415*4882a593Smuzhiyun 		if (!pm_runtime_suspended(dev))
3416*4882a593Smuzhiyun 			pm_runtime_mark_last_busy(dev);
3417*4882a593Smuzhiyun 	} else {
3418*4882a593Smuzhiyun 		pm_runtime_dont_use_autosuspend(dev);
3419*4882a593Smuzhiyun 		pm_runtime_forbid(dev);
3420*4882a593Smuzhiyun 	}
3421*4882a593Smuzhiyun }
3422*4882a593Smuzhiyun 
3423*4882a593Smuzhiyun /**
3424*4882a593Smuzhiyun  * snd_hda_set_power_save - reprogram autosuspend for the given delay
3425*4882a593Smuzhiyun  * @bus: HD-audio bus
3426*4882a593Smuzhiyun  * @delay: autosuspend delay in msec, 0 = off
3427*4882a593Smuzhiyun  *
3428*4882a593Smuzhiyun  * Synchronize the runtime PM autosuspend state from the power_save option.
3429*4882a593Smuzhiyun  */
snd_hda_set_power_save(struct hda_bus * bus,int delay)3430*4882a593Smuzhiyun void snd_hda_set_power_save(struct hda_bus *bus, int delay)
3431*4882a593Smuzhiyun {
3432*4882a593Smuzhiyun 	struct hda_codec *c;
3433*4882a593Smuzhiyun 
3434*4882a593Smuzhiyun 	list_for_each_codec(c, bus)
3435*4882a593Smuzhiyun 		codec_set_power_save(c, delay);
3436*4882a593Smuzhiyun }
3437*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_set_power_save);
3438*4882a593Smuzhiyun 
3439*4882a593Smuzhiyun /**
3440*4882a593Smuzhiyun  * snd_hda_check_amp_list_power - Check the amp list and update the power
3441*4882a593Smuzhiyun  * @codec: HD-audio codec
3442*4882a593Smuzhiyun  * @check: the object containing an AMP list and the status
3443*4882a593Smuzhiyun  * @nid: NID to check / update
3444*4882a593Smuzhiyun  *
3445*4882a593Smuzhiyun  * Check whether the given NID is in the amp list.  If it's in the list,
3446*4882a593Smuzhiyun  * check the current AMP status, and update the power-status according
3447*4882a593Smuzhiyun  * to the mute status.
3448*4882a593Smuzhiyun  *
3449*4882a593Smuzhiyun  * This function is supposed to be set or called from the check_power_status
3450*4882a593Smuzhiyun  * patch ops.
3451*4882a593Smuzhiyun  */
snd_hda_check_amp_list_power(struct hda_codec * codec,struct hda_loopback_check * check,hda_nid_t nid)3452*4882a593Smuzhiyun int snd_hda_check_amp_list_power(struct hda_codec *codec,
3453*4882a593Smuzhiyun 				 struct hda_loopback_check *check,
3454*4882a593Smuzhiyun 				 hda_nid_t nid)
3455*4882a593Smuzhiyun {
3456*4882a593Smuzhiyun 	const struct hda_amp_list *p;
3457*4882a593Smuzhiyun 	int ch, v;
3458*4882a593Smuzhiyun 
3459*4882a593Smuzhiyun 	if (!check->amplist)
3460*4882a593Smuzhiyun 		return 0;
3461*4882a593Smuzhiyun 	for (p = check->amplist; p->nid; p++) {
3462*4882a593Smuzhiyun 		if (p->nid == nid)
3463*4882a593Smuzhiyun 			break;
3464*4882a593Smuzhiyun 	}
3465*4882a593Smuzhiyun 	if (!p->nid)
3466*4882a593Smuzhiyun 		return 0; /* nothing changed */
3467*4882a593Smuzhiyun 
3468*4882a593Smuzhiyun 	for (p = check->amplist; p->nid; p++) {
3469*4882a593Smuzhiyun 		for (ch = 0; ch < 2; ch++) {
3470*4882a593Smuzhiyun 			v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
3471*4882a593Smuzhiyun 						   p->idx);
3472*4882a593Smuzhiyun 			if (!(v & HDA_AMP_MUTE) && v > 0) {
3473*4882a593Smuzhiyun 				if (!check->power_on) {
3474*4882a593Smuzhiyun 					check->power_on = 1;
3475*4882a593Smuzhiyun 					snd_hda_power_up_pm(codec);
3476*4882a593Smuzhiyun 				}
3477*4882a593Smuzhiyun 				return 1;
3478*4882a593Smuzhiyun 			}
3479*4882a593Smuzhiyun 		}
3480*4882a593Smuzhiyun 	}
3481*4882a593Smuzhiyun 	if (check->power_on) {
3482*4882a593Smuzhiyun 		check->power_on = 0;
3483*4882a593Smuzhiyun 		snd_hda_power_down_pm(codec);
3484*4882a593Smuzhiyun 	}
3485*4882a593Smuzhiyun 	return 0;
3486*4882a593Smuzhiyun }
3487*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_check_amp_list_power);
3488*4882a593Smuzhiyun #endif
3489*4882a593Smuzhiyun 
3490*4882a593Smuzhiyun /*
3491*4882a593Smuzhiyun  * input MUX helper
3492*4882a593Smuzhiyun  */
3493*4882a593Smuzhiyun 
3494*4882a593Smuzhiyun /**
3495*4882a593Smuzhiyun  * snd_hda_input_mux_info_info - Info callback helper for the input-mux enum
3496*4882a593Smuzhiyun  * @imux: imux helper object
3497*4882a593Smuzhiyun  * @uinfo: pointer to get/store the data
3498*4882a593Smuzhiyun  */
snd_hda_input_mux_info(const struct hda_input_mux * imux,struct snd_ctl_elem_info * uinfo)3499*4882a593Smuzhiyun int snd_hda_input_mux_info(const struct hda_input_mux *imux,
3500*4882a593Smuzhiyun 			   struct snd_ctl_elem_info *uinfo)
3501*4882a593Smuzhiyun {
3502*4882a593Smuzhiyun 	unsigned int index;
3503*4882a593Smuzhiyun 
3504*4882a593Smuzhiyun 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
3505*4882a593Smuzhiyun 	uinfo->count = 1;
3506*4882a593Smuzhiyun 	uinfo->value.enumerated.items = imux->num_items;
3507*4882a593Smuzhiyun 	if (!imux->num_items)
3508*4882a593Smuzhiyun 		return 0;
3509*4882a593Smuzhiyun 	index = uinfo->value.enumerated.item;
3510*4882a593Smuzhiyun 	if (index >= imux->num_items)
3511*4882a593Smuzhiyun 		index = imux->num_items - 1;
3512*4882a593Smuzhiyun 	strcpy(uinfo->value.enumerated.name, imux->items[index].label);
3513*4882a593Smuzhiyun 	return 0;
3514*4882a593Smuzhiyun }
3515*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_input_mux_info);
3516*4882a593Smuzhiyun 
3517*4882a593Smuzhiyun /**
3518*4882a593Smuzhiyun  * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum
3519*4882a593Smuzhiyun  * @codec: the HDA codec
3520*4882a593Smuzhiyun  * @imux: imux helper object
3521*4882a593Smuzhiyun  * @ucontrol: pointer to get/store the data
3522*4882a593Smuzhiyun  * @nid: input mux NID
3523*4882a593Smuzhiyun  * @cur_val: pointer to get/store the current imux value
3524*4882a593Smuzhiyun  */
snd_hda_input_mux_put(struct hda_codec * codec,const struct hda_input_mux * imux,struct snd_ctl_elem_value * ucontrol,hda_nid_t nid,unsigned int * cur_val)3525*4882a593Smuzhiyun int snd_hda_input_mux_put(struct hda_codec *codec,
3526*4882a593Smuzhiyun 			  const struct hda_input_mux *imux,
3527*4882a593Smuzhiyun 			  struct snd_ctl_elem_value *ucontrol,
3528*4882a593Smuzhiyun 			  hda_nid_t nid,
3529*4882a593Smuzhiyun 			  unsigned int *cur_val)
3530*4882a593Smuzhiyun {
3531*4882a593Smuzhiyun 	unsigned int idx;
3532*4882a593Smuzhiyun 
3533*4882a593Smuzhiyun 	if (!imux->num_items)
3534*4882a593Smuzhiyun 		return 0;
3535*4882a593Smuzhiyun 	idx = ucontrol->value.enumerated.item[0];
3536*4882a593Smuzhiyun 	if (idx >= imux->num_items)
3537*4882a593Smuzhiyun 		idx = imux->num_items - 1;
3538*4882a593Smuzhiyun 	if (*cur_val == idx)
3539*4882a593Smuzhiyun 		return 0;
3540*4882a593Smuzhiyun 	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
3541*4882a593Smuzhiyun 				  imux->items[idx].index);
3542*4882a593Smuzhiyun 	*cur_val = idx;
3543*4882a593Smuzhiyun 	return 1;
3544*4882a593Smuzhiyun }
3545*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_input_mux_put);
3546*4882a593Smuzhiyun 
3547*4882a593Smuzhiyun 
3548*4882a593Smuzhiyun /**
3549*4882a593Smuzhiyun  * snd_hda_enum_helper_info - Helper for simple enum ctls
3550*4882a593Smuzhiyun  * @kcontrol: ctl element
3551*4882a593Smuzhiyun  * @uinfo: pointer to get/store the data
3552*4882a593Smuzhiyun  * @num_items: number of enum items
3553*4882a593Smuzhiyun  * @texts: enum item string array
3554*4882a593Smuzhiyun  *
3555*4882a593Smuzhiyun  * process kcontrol info callback of a simple string enum array
3556*4882a593Smuzhiyun  * when @num_items is 0 or @texts is NULL, assume a boolean enum array
3557*4882a593Smuzhiyun  */
snd_hda_enum_helper_info(struct snd_kcontrol * kcontrol,struct snd_ctl_elem_info * uinfo,int num_items,const char * const * texts)3558*4882a593Smuzhiyun int snd_hda_enum_helper_info(struct snd_kcontrol *kcontrol,
3559*4882a593Smuzhiyun 			     struct snd_ctl_elem_info *uinfo,
3560*4882a593Smuzhiyun 			     int num_items, const char * const *texts)
3561*4882a593Smuzhiyun {
3562*4882a593Smuzhiyun 	static const char * const texts_default[] = {
3563*4882a593Smuzhiyun 		"Disabled", "Enabled"
3564*4882a593Smuzhiyun 	};
3565*4882a593Smuzhiyun 
3566*4882a593Smuzhiyun 	if (!texts || !num_items) {
3567*4882a593Smuzhiyun 		num_items = 2;
3568*4882a593Smuzhiyun 		texts = texts_default;
3569*4882a593Smuzhiyun 	}
3570*4882a593Smuzhiyun 
3571*4882a593Smuzhiyun 	return snd_ctl_enum_info(uinfo, 1, num_items, texts);
3572*4882a593Smuzhiyun }
3573*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_enum_helper_info);
3574*4882a593Smuzhiyun 
3575*4882a593Smuzhiyun /*
3576*4882a593Smuzhiyun  * Multi-channel / digital-out PCM helper functions
3577*4882a593Smuzhiyun  */
3578*4882a593Smuzhiyun 
3579*4882a593Smuzhiyun /* setup SPDIF output stream */
setup_dig_out_stream(struct hda_codec * codec,hda_nid_t nid,unsigned int stream_tag,unsigned int format)3580*4882a593Smuzhiyun static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
3581*4882a593Smuzhiyun 				 unsigned int stream_tag, unsigned int format)
3582*4882a593Smuzhiyun {
3583*4882a593Smuzhiyun 	struct hda_spdif_out *spdif;
3584*4882a593Smuzhiyun 	unsigned int curr_fmt;
3585*4882a593Smuzhiyun 	bool reset;
3586*4882a593Smuzhiyun 
3587*4882a593Smuzhiyun 	spdif = snd_hda_spdif_out_of_nid(codec, nid);
3588*4882a593Smuzhiyun 	/* Add sanity check to pass klockwork check.
3589*4882a593Smuzhiyun 	 * This should never happen.
3590*4882a593Smuzhiyun 	 */
3591*4882a593Smuzhiyun 	if (WARN_ON(spdif == NULL))
3592*4882a593Smuzhiyun 		return;
3593*4882a593Smuzhiyun 
3594*4882a593Smuzhiyun 	curr_fmt = snd_hda_codec_read(codec, nid, 0,
3595*4882a593Smuzhiyun 				      AC_VERB_GET_STREAM_FORMAT, 0);
3596*4882a593Smuzhiyun 	reset = codec->spdif_status_reset &&
3597*4882a593Smuzhiyun 		(spdif->ctls & AC_DIG1_ENABLE) &&
3598*4882a593Smuzhiyun 		curr_fmt != format;
3599*4882a593Smuzhiyun 
3600*4882a593Smuzhiyun 	/* turn off SPDIF if needed; otherwise the IEC958 bits won't be
3601*4882a593Smuzhiyun 	   updated */
3602*4882a593Smuzhiyun 	if (reset)
3603*4882a593Smuzhiyun 		set_dig_out_convert(codec, nid,
3604*4882a593Smuzhiyun 				    spdif->ctls & ~AC_DIG1_ENABLE & 0xff,
3605*4882a593Smuzhiyun 				    -1);
3606*4882a593Smuzhiyun 	snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
3607*4882a593Smuzhiyun 	if (codec->follower_dig_outs) {
3608*4882a593Smuzhiyun 		const hda_nid_t *d;
3609*4882a593Smuzhiyun 		for (d = codec->follower_dig_outs; *d; d++)
3610*4882a593Smuzhiyun 			snd_hda_codec_setup_stream(codec, *d, stream_tag, 0,
3611*4882a593Smuzhiyun 						   format);
3612*4882a593Smuzhiyun 	}
3613*4882a593Smuzhiyun 	/* turn on again (if needed) */
3614*4882a593Smuzhiyun 	if (reset)
3615*4882a593Smuzhiyun 		set_dig_out_convert(codec, nid,
3616*4882a593Smuzhiyun 				    spdif->ctls & 0xff, -1);
3617*4882a593Smuzhiyun }
3618*4882a593Smuzhiyun 
cleanup_dig_out_stream(struct hda_codec * codec,hda_nid_t nid)3619*4882a593Smuzhiyun static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
3620*4882a593Smuzhiyun {
3621*4882a593Smuzhiyun 	snd_hda_codec_cleanup_stream(codec, nid);
3622*4882a593Smuzhiyun 	if (codec->follower_dig_outs) {
3623*4882a593Smuzhiyun 		const hda_nid_t *d;
3624*4882a593Smuzhiyun 		for (d = codec->follower_dig_outs; *d; d++)
3625*4882a593Smuzhiyun 			snd_hda_codec_cleanup_stream(codec, *d);
3626*4882a593Smuzhiyun 	}
3627*4882a593Smuzhiyun }
3628*4882a593Smuzhiyun 
3629*4882a593Smuzhiyun /**
3630*4882a593Smuzhiyun  * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode
3631*4882a593Smuzhiyun  * @codec: the HDA codec
3632*4882a593Smuzhiyun  * @mout: hda_multi_out object
3633*4882a593Smuzhiyun  */
snd_hda_multi_out_dig_open(struct hda_codec * codec,struct hda_multi_out * mout)3634*4882a593Smuzhiyun int snd_hda_multi_out_dig_open(struct hda_codec *codec,
3635*4882a593Smuzhiyun 			       struct hda_multi_out *mout)
3636*4882a593Smuzhiyun {
3637*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
3638*4882a593Smuzhiyun 	if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
3639*4882a593Smuzhiyun 		/* already opened as analog dup; reset it once */
3640*4882a593Smuzhiyun 		cleanup_dig_out_stream(codec, mout->dig_out_nid);
3641*4882a593Smuzhiyun 	mout->dig_out_used = HDA_DIG_EXCLUSIVE;
3642*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
3643*4882a593Smuzhiyun 	return 0;
3644*4882a593Smuzhiyun }
3645*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_open);
3646*4882a593Smuzhiyun 
3647*4882a593Smuzhiyun /**
3648*4882a593Smuzhiyun  * snd_hda_multi_out_dig_prepare - prepare the digital out stream
3649*4882a593Smuzhiyun  * @codec: the HDA codec
3650*4882a593Smuzhiyun  * @mout: hda_multi_out object
3651*4882a593Smuzhiyun  * @stream_tag: stream tag to assign
3652*4882a593Smuzhiyun  * @format: format id to assign
3653*4882a593Smuzhiyun  * @substream: PCM substream to assign
3654*4882a593Smuzhiyun  */
snd_hda_multi_out_dig_prepare(struct hda_codec * codec,struct hda_multi_out * mout,unsigned int stream_tag,unsigned int format,struct snd_pcm_substream * substream)3655*4882a593Smuzhiyun int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
3656*4882a593Smuzhiyun 				  struct hda_multi_out *mout,
3657*4882a593Smuzhiyun 				  unsigned int stream_tag,
3658*4882a593Smuzhiyun 				  unsigned int format,
3659*4882a593Smuzhiyun 				  struct snd_pcm_substream *substream)
3660*4882a593Smuzhiyun {
3661*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
3662*4882a593Smuzhiyun 	setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
3663*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
3664*4882a593Smuzhiyun 	return 0;
3665*4882a593Smuzhiyun }
3666*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_prepare);
3667*4882a593Smuzhiyun 
3668*4882a593Smuzhiyun /**
3669*4882a593Smuzhiyun  * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream
3670*4882a593Smuzhiyun  * @codec: the HDA codec
3671*4882a593Smuzhiyun  * @mout: hda_multi_out object
3672*4882a593Smuzhiyun  */
snd_hda_multi_out_dig_cleanup(struct hda_codec * codec,struct hda_multi_out * mout)3673*4882a593Smuzhiyun int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
3674*4882a593Smuzhiyun 				  struct hda_multi_out *mout)
3675*4882a593Smuzhiyun {
3676*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
3677*4882a593Smuzhiyun 	cleanup_dig_out_stream(codec, mout->dig_out_nid);
3678*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
3679*4882a593Smuzhiyun 	return 0;
3680*4882a593Smuzhiyun }
3681*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_cleanup);
3682*4882a593Smuzhiyun 
3683*4882a593Smuzhiyun /**
3684*4882a593Smuzhiyun  * snd_hda_multi_out_dig_close - release the digital out stream
3685*4882a593Smuzhiyun  * @codec: the HDA codec
3686*4882a593Smuzhiyun  * @mout: hda_multi_out object
3687*4882a593Smuzhiyun  */
snd_hda_multi_out_dig_close(struct hda_codec * codec,struct hda_multi_out * mout)3688*4882a593Smuzhiyun int snd_hda_multi_out_dig_close(struct hda_codec *codec,
3689*4882a593Smuzhiyun 				struct hda_multi_out *mout)
3690*4882a593Smuzhiyun {
3691*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
3692*4882a593Smuzhiyun 	mout->dig_out_used = 0;
3693*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
3694*4882a593Smuzhiyun 	return 0;
3695*4882a593Smuzhiyun }
3696*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_close);
3697*4882a593Smuzhiyun 
3698*4882a593Smuzhiyun /**
3699*4882a593Smuzhiyun  * snd_hda_multi_out_analog_open - open analog outputs
3700*4882a593Smuzhiyun  * @codec: the HDA codec
3701*4882a593Smuzhiyun  * @mout: hda_multi_out object
3702*4882a593Smuzhiyun  * @substream: PCM substream to assign
3703*4882a593Smuzhiyun  * @hinfo: PCM information to assign
3704*4882a593Smuzhiyun  *
3705*4882a593Smuzhiyun  * Open analog outputs and set up the hw-constraints.
3706*4882a593Smuzhiyun  * If the digital outputs can be opened as follower, open the digital
3707*4882a593Smuzhiyun  * outputs, too.
3708*4882a593Smuzhiyun  */
snd_hda_multi_out_analog_open(struct hda_codec * codec,struct hda_multi_out * mout,struct snd_pcm_substream * substream,struct hda_pcm_stream * hinfo)3709*4882a593Smuzhiyun int snd_hda_multi_out_analog_open(struct hda_codec *codec,
3710*4882a593Smuzhiyun 				  struct hda_multi_out *mout,
3711*4882a593Smuzhiyun 				  struct snd_pcm_substream *substream,
3712*4882a593Smuzhiyun 				  struct hda_pcm_stream *hinfo)
3713*4882a593Smuzhiyun {
3714*4882a593Smuzhiyun 	struct snd_pcm_runtime *runtime = substream->runtime;
3715*4882a593Smuzhiyun 	runtime->hw.channels_max = mout->max_channels;
3716*4882a593Smuzhiyun 	if (mout->dig_out_nid) {
3717*4882a593Smuzhiyun 		if (!mout->analog_rates) {
3718*4882a593Smuzhiyun 			mout->analog_rates = hinfo->rates;
3719*4882a593Smuzhiyun 			mout->analog_formats = hinfo->formats;
3720*4882a593Smuzhiyun 			mout->analog_maxbps = hinfo->maxbps;
3721*4882a593Smuzhiyun 		} else {
3722*4882a593Smuzhiyun 			runtime->hw.rates = mout->analog_rates;
3723*4882a593Smuzhiyun 			runtime->hw.formats = mout->analog_formats;
3724*4882a593Smuzhiyun 			hinfo->maxbps = mout->analog_maxbps;
3725*4882a593Smuzhiyun 		}
3726*4882a593Smuzhiyun 		if (!mout->spdif_rates) {
3727*4882a593Smuzhiyun 			snd_hda_query_supported_pcm(codec, mout->dig_out_nid,
3728*4882a593Smuzhiyun 						    &mout->spdif_rates,
3729*4882a593Smuzhiyun 						    &mout->spdif_formats,
3730*4882a593Smuzhiyun 						    &mout->spdif_maxbps);
3731*4882a593Smuzhiyun 		}
3732*4882a593Smuzhiyun 		mutex_lock(&codec->spdif_mutex);
3733*4882a593Smuzhiyun 		if (mout->share_spdif) {
3734*4882a593Smuzhiyun 			if ((runtime->hw.rates & mout->spdif_rates) &&
3735*4882a593Smuzhiyun 			    (runtime->hw.formats & mout->spdif_formats)) {
3736*4882a593Smuzhiyun 				runtime->hw.rates &= mout->spdif_rates;
3737*4882a593Smuzhiyun 				runtime->hw.formats &= mout->spdif_formats;
3738*4882a593Smuzhiyun 				if (mout->spdif_maxbps < hinfo->maxbps)
3739*4882a593Smuzhiyun 					hinfo->maxbps = mout->spdif_maxbps;
3740*4882a593Smuzhiyun 			} else {
3741*4882a593Smuzhiyun 				mout->share_spdif = 0;
3742*4882a593Smuzhiyun 				/* FIXME: need notify? */
3743*4882a593Smuzhiyun 			}
3744*4882a593Smuzhiyun 		}
3745*4882a593Smuzhiyun 		mutex_unlock(&codec->spdif_mutex);
3746*4882a593Smuzhiyun 	}
3747*4882a593Smuzhiyun 	return snd_pcm_hw_constraint_step(substream->runtime, 0,
3748*4882a593Smuzhiyun 					  SNDRV_PCM_HW_PARAM_CHANNELS, 2);
3749*4882a593Smuzhiyun }
3750*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_open);
3751*4882a593Smuzhiyun 
3752*4882a593Smuzhiyun /**
3753*4882a593Smuzhiyun  * snd_hda_multi_out_analog_prepare - Preapre the analog outputs.
3754*4882a593Smuzhiyun  * @codec: the HDA codec
3755*4882a593Smuzhiyun  * @mout: hda_multi_out object
3756*4882a593Smuzhiyun  * @stream_tag: stream tag to assign
3757*4882a593Smuzhiyun  * @format: format id to assign
3758*4882a593Smuzhiyun  * @substream: PCM substream to assign
3759*4882a593Smuzhiyun  *
3760*4882a593Smuzhiyun  * Set up the i/o for analog out.
3761*4882a593Smuzhiyun  * When the digital out is available, copy the front out to digital out, too.
3762*4882a593Smuzhiyun  */
snd_hda_multi_out_analog_prepare(struct hda_codec * codec,struct hda_multi_out * mout,unsigned int stream_tag,unsigned int format,struct snd_pcm_substream * substream)3763*4882a593Smuzhiyun int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
3764*4882a593Smuzhiyun 				     struct hda_multi_out *mout,
3765*4882a593Smuzhiyun 				     unsigned int stream_tag,
3766*4882a593Smuzhiyun 				     unsigned int format,
3767*4882a593Smuzhiyun 				     struct snd_pcm_substream *substream)
3768*4882a593Smuzhiyun {
3769*4882a593Smuzhiyun 	const hda_nid_t *nids = mout->dac_nids;
3770*4882a593Smuzhiyun 	int chs = substream->runtime->channels;
3771*4882a593Smuzhiyun 	struct hda_spdif_out *spdif;
3772*4882a593Smuzhiyun 	int i;
3773*4882a593Smuzhiyun 
3774*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
3775*4882a593Smuzhiyun 	spdif = snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid);
3776*4882a593Smuzhiyun 	if (mout->dig_out_nid && mout->share_spdif &&
3777*4882a593Smuzhiyun 	    mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
3778*4882a593Smuzhiyun 		if (chs == 2 && spdif != NULL &&
3779*4882a593Smuzhiyun 		    snd_hda_is_supported_format(codec, mout->dig_out_nid,
3780*4882a593Smuzhiyun 						format) &&
3781*4882a593Smuzhiyun 		    !(spdif->status & IEC958_AES0_NONAUDIO)) {
3782*4882a593Smuzhiyun 			mout->dig_out_used = HDA_DIG_ANALOG_DUP;
3783*4882a593Smuzhiyun 			setup_dig_out_stream(codec, mout->dig_out_nid,
3784*4882a593Smuzhiyun 					     stream_tag, format);
3785*4882a593Smuzhiyun 		} else {
3786*4882a593Smuzhiyun 			mout->dig_out_used = 0;
3787*4882a593Smuzhiyun 			cleanup_dig_out_stream(codec, mout->dig_out_nid);
3788*4882a593Smuzhiyun 		}
3789*4882a593Smuzhiyun 	}
3790*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
3791*4882a593Smuzhiyun 
3792*4882a593Smuzhiyun 	/* front */
3793*4882a593Smuzhiyun 	snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
3794*4882a593Smuzhiyun 				   0, format);
3795*4882a593Smuzhiyun 	if (!mout->no_share_stream &&
3796*4882a593Smuzhiyun 	    mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
3797*4882a593Smuzhiyun 		/* headphone out will just decode front left/right (stereo) */
3798*4882a593Smuzhiyun 		snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
3799*4882a593Smuzhiyun 					   0, format);
3800*4882a593Smuzhiyun 	/* extra outputs copied from front */
3801*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++)
3802*4882a593Smuzhiyun 		if (!mout->no_share_stream && mout->hp_out_nid[i])
3803*4882a593Smuzhiyun 			snd_hda_codec_setup_stream(codec,
3804*4882a593Smuzhiyun 						   mout->hp_out_nid[i],
3805*4882a593Smuzhiyun 						   stream_tag, 0, format);
3806*4882a593Smuzhiyun 
3807*4882a593Smuzhiyun 	/* surrounds */
3808*4882a593Smuzhiyun 	for (i = 1; i < mout->num_dacs; i++) {
3809*4882a593Smuzhiyun 		if (chs >= (i + 1) * 2) /* independent out */
3810*4882a593Smuzhiyun 			snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
3811*4882a593Smuzhiyun 						   i * 2, format);
3812*4882a593Smuzhiyun 		else if (!mout->no_share_stream) /* copy front */
3813*4882a593Smuzhiyun 			snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
3814*4882a593Smuzhiyun 						   0, format);
3815*4882a593Smuzhiyun 	}
3816*4882a593Smuzhiyun 
3817*4882a593Smuzhiyun 	/* extra surrounds */
3818*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) {
3819*4882a593Smuzhiyun 		int ch = 0;
3820*4882a593Smuzhiyun 		if (!mout->extra_out_nid[i])
3821*4882a593Smuzhiyun 			break;
3822*4882a593Smuzhiyun 		if (chs >= (i + 1) * 2)
3823*4882a593Smuzhiyun 			ch = i * 2;
3824*4882a593Smuzhiyun 		else if (!mout->no_share_stream)
3825*4882a593Smuzhiyun 			break;
3826*4882a593Smuzhiyun 		snd_hda_codec_setup_stream(codec, mout->extra_out_nid[i],
3827*4882a593Smuzhiyun 					   stream_tag, ch, format);
3828*4882a593Smuzhiyun 	}
3829*4882a593Smuzhiyun 
3830*4882a593Smuzhiyun 	return 0;
3831*4882a593Smuzhiyun }
3832*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_prepare);
3833*4882a593Smuzhiyun 
3834*4882a593Smuzhiyun /**
3835*4882a593Smuzhiyun  * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out
3836*4882a593Smuzhiyun  * @codec: the HDA codec
3837*4882a593Smuzhiyun  * @mout: hda_multi_out object
3838*4882a593Smuzhiyun  */
snd_hda_multi_out_analog_cleanup(struct hda_codec * codec,struct hda_multi_out * mout)3839*4882a593Smuzhiyun int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
3840*4882a593Smuzhiyun 				     struct hda_multi_out *mout)
3841*4882a593Smuzhiyun {
3842*4882a593Smuzhiyun 	const hda_nid_t *nids = mout->dac_nids;
3843*4882a593Smuzhiyun 	int i;
3844*4882a593Smuzhiyun 
3845*4882a593Smuzhiyun 	for (i = 0; i < mout->num_dacs; i++)
3846*4882a593Smuzhiyun 		snd_hda_codec_cleanup_stream(codec, nids[i]);
3847*4882a593Smuzhiyun 	if (mout->hp_nid)
3848*4882a593Smuzhiyun 		snd_hda_codec_cleanup_stream(codec, mout->hp_nid);
3849*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++)
3850*4882a593Smuzhiyun 		if (mout->hp_out_nid[i])
3851*4882a593Smuzhiyun 			snd_hda_codec_cleanup_stream(codec,
3852*4882a593Smuzhiyun 						     mout->hp_out_nid[i]);
3853*4882a593Smuzhiyun 	for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
3854*4882a593Smuzhiyun 		if (mout->extra_out_nid[i])
3855*4882a593Smuzhiyun 			snd_hda_codec_cleanup_stream(codec,
3856*4882a593Smuzhiyun 						     mout->extra_out_nid[i]);
3857*4882a593Smuzhiyun 	mutex_lock(&codec->spdif_mutex);
3858*4882a593Smuzhiyun 	if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
3859*4882a593Smuzhiyun 		cleanup_dig_out_stream(codec, mout->dig_out_nid);
3860*4882a593Smuzhiyun 		mout->dig_out_used = 0;
3861*4882a593Smuzhiyun 	}
3862*4882a593Smuzhiyun 	mutex_unlock(&codec->spdif_mutex);
3863*4882a593Smuzhiyun 	return 0;
3864*4882a593Smuzhiyun }
3865*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_cleanup);
3866*4882a593Smuzhiyun 
3867*4882a593Smuzhiyun /**
3868*4882a593Smuzhiyun  * snd_hda_get_default_vref - Get the default (mic) VREF pin bits
3869*4882a593Smuzhiyun  * @codec: the HDA codec
3870*4882a593Smuzhiyun  * @pin: referred pin NID
3871*4882a593Smuzhiyun  *
3872*4882a593Smuzhiyun  * Guess the suitable VREF pin bits to be set as the pin-control value.
3873*4882a593Smuzhiyun  * Note: the function doesn't set the AC_PINCTL_IN_EN bit.
3874*4882a593Smuzhiyun  */
snd_hda_get_default_vref(struct hda_codec * codec,hda_nid_t pin)3875*4882a593Smuzhiyun unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin)
3876*4882a593Smuzhiyun {
3877*4882a593Smuzhiyun 	unsigned int pincap;
3878*4882a593Smuzhiyun 	unsigned int oldval;
3879*4882a593Smuzhiyun 	oldval = snd_hda_codec_read(codec, pin, 0,
3880*4882a593Smuzhiyun 				    AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
3881*4882a593Smuzhiyun 	pincap = snd_hda_query_pin_caps(codec, pin);
3882*4882a593Smuzhiyun 	pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
3883*4882a593Smuzhiyun 	/* Exception: if the default pin setup is vref50, we give it priority */
3884*4882a593Smuzhiyun 	if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
3885*4882a593Smuzhiyun 		return AC_PINCTL_VREF_80;
3886*4882a593Smuzhiyun 	else if (pincap & AC_PINCAP_VREF_50)
3887*4882a593Smuzhiyun 		return AC_PINCTL_VREF_50;
3888*4882a593Smuzhiyun 	else if (pincap & AC_PINCAP_VREF_100)
3889*4882a593Smuzhiyun 		return AC_PINCTL_VREF_100;
3890*4882a593Smuzhiyun 	else if (pincap & AC_PINCAP_VREF_GRD)
3891*4882a593Smuzhiyun 		return AC_PINCTL_VREF_GRD;
3892*4882a593Smuzhiyun 	return AC_PINCTL_VREF_HIZ;
3893*4882a593Smuzhiyun }
3894*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_get_default_vref);
3895*4882a593Smuzhiyun 
3896*4882a593Smuzhiyun /**
3897*4882a593Smuzhiyun  * snd_hda_correct_pin_ctl - correct the pin ctl value for matching with the pin cap
3898*4882a593Smuzhiyun  * @codec: the HDA codec
3899*4882a593Smuzhiyun  * @pin: referred pin NID
3900*4882a593Smuzhiyun  * @val: pin ctl value to audit
3901*4882a593Smuzhiyun  */
snd_hda_correct_pin_ctl(struct hda_codec * codec,hda_nid_t pin,unsigned int val)3902*4882a593Smuzhiyun unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec,
3903*4882a593Smuzhiyun 				     hda_nid_t pin, unsigned int val)
3904*4882a593Smuzhiyun {
3905*4882a593Smuzhiyun 	static const unsigned int cap_lists[][2] = {
3906*4882a593Smuzhiyun 		{ AC_PINCTL_VREF_100, AC_PINCAP_VREF_100 },
3907*4882a593Smuzhiyun 		{ AC_PINCTL_VREF_80, AC_PINCAP_VREF_80 },
3908*4882a593Smuzhiyun 		{ AC_PINCTL_VREF_50, AC_PINCAP_VREF_50 },
3909*4882a593Smuzhiyun 		{ AC_PINCTL_VREF_GRD, AC_PINCAP_VREF_GRD },
3910*4882a593Smuzhiyun 	};
3911*4882a593Smuzhiyun 	unsigned int cap;
3912*4882a593Smuzhiyun 
3913*4882a593Smuzhiyun 	if (!val)
3914*4882a593Smuzhiyun 		return 0;
3915*4882a593Smuzhiyun 	cap = snd_hda_query_pin_caps(codec, pin);
3916*4882a593Smuzhiyun 	if (!cap)
3917*4882a593Smuzhiyun 		return val; /* don't know what to do... */
3918*4882a593Smuzhiyun 
3919*4882a593Smuzhiyun 	if (val & AC_PINCTL_OUT_EN) {
3920*4882a593Smuzhiyun 		if (!(cap & AC_PINCAP_OUT))
3921*4882a593Smuzhiyun 			val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
3922*4882a593Smuzhiyun 		else if ((val & AC_PINCTL_HP_EN) && !(cap & AC_PINCAP_HP_DRV))
3923*4882a593Smuzhiyun 			val &= ~AC_PINCTL_HP_EN;
3924*4882a593Smuzhiyun 	}
3925*4882a593Smuzhiyun 
3926*4882a593Smuzhiyun 	if (val & AC_PINCTL_IN_EN) {
3927*4882a593Smuzhiyun 		if (!(cap & AC_PINCAP_IN))
3928*4882a593Smuzhiyun 			val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN);
3929*4882a593Smuzhiyun 		else {
3930*4882a593Smuzhiyun 			unsigned int vcap, vref;
3931*4882a593Smuzhiyun 			int i;
3932*4882a593Smuzhiyun 			vcap = (cap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
3933*4882a593Smuzhiyun 			vref = val & AC_PINCTL_VREFEN;
3934*4882a593Smuzhiyun 			for (i = 0; i < ARRAY_SIZE(cap_lists); i++) {
3935*4882a593Smuzhiyun 				if (vref == cap_lists[i][0] &&
3936*4882a593Smuzhiyun 				    !(vcap & cap_lists[i][1])) {
3937*4882a593Smuzhiyun 					if (i == ARRAY_SIZE(cap_lists) - 1)
3938*4882a593Smuzhiyun 						vref = AC_PINCTL_VREF_HIZ;
3939*4882a593Smuzhiyun 					else
3940*4882a593Smuzhiyun 						vref = cap_lists[i + 1][0];
3941*4882a593Smuzhiyun 				}
3942*4882a593Smuzhiyun 			}
3943*4882a593Smuzhiyun 			val &= ~AC_PINCTL_VREFEN;
3944*4882a593Smuzhiyun 			val |= vref;
3945*4882a593Smuzhiyun 		}
3946*4882a593Smuzhiyun 	}
3947*4882a593Smuzhiyun 
3948*4882a593Smuzhiyun 	return val;
3949*4882a593Smuzhiyun }
3950*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_correct_pin_ctl);
3951*4882a593Smuzhiyun 
3952*4882a593Smuzhiyun /**
3953*4882a593Smuzhiyun  * _snd_hda_pin_ctl - Helper to set pin ctl value
3954*4882a593Smuzhiyun  * @codec: the HDA codec
3955*4882a593Smuzhiyun  * @pin: referred pin NID
3956*4882a593Smuzhiyun  * @val: pin control value to set
3957*4882a593Smuzhiyun  * @cached: access over codec pinctl cache or direct write
3958*4882a593Smuzhiyun  *
3959*4882a593Smuzhiyun  * This function is a helper to set a pin ctl value more safely.
3960*4882a593Smuzhiyun  * It corrects the pin ctl value via snd_hda_correct_pin_ctl(), stores the
3961*4882a593Smuzhiyun  * value in pin target array via snd_hda_codec_set_pin_target(), then
3962*4882a593Smuzhiyun  * actually writes the value via either snd_hda_codec_write_cache() or
3963*4882a593Smuzhiyun  * snd_hda_codec_write() depending on @cached flag.
3964*4882a593Smuzhiyun  */
_snd_hda_set_pin_ctl(struct hda_codec * codec,hda_nid_t pin,unsigned int val,bool cached)3965*4882a593Smuzhiyun int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
3966*4882a593Smuzhiyun 			 unsigned int val, bool cached)
3967*4882a593Smuzhiyun {
3968*4882a593Smuzhiyun 	val = snd_hda_correct_pin_ctl(codec, pin, val);
3969*4882a593Smuzhiyun 	snd_hda_codec_set_pin_target(codec, pin, val);
3970*4882a593Smuzhiyun 	if (cached)
3971*4882a593Smuzhiyun 		return snd_hda_codec_write_cache(codec, pin, 0,
3972*4882a593Smuzhiyun 				AC_VERB_SET_PIN_WIDGET_CONTROL, val);
3973*4882a593Smuzhiyun 	else
3974*4882a593Smuzhiyun 		return snd_hda_codec_write(codec, pin, 0,
3975*4882a593Smuzhiyun 					   AC_VERB_SET_PIN_WIDGET_CONTROL, val);
3976*4882a593Smuzhiyun }
3977*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(_snd_hda_set_pin_ctl);
3978*4882a593Smuzhiyun 
3979*4882a593Smuzhiyun /**
3980*4882a593Smuzhiyun  * snd_hda_add_imux_item - Add an item to input_mux
3981*4882a593Smuzhiyun  * @codec: the HDA codec
3982*4882a593Smuzhiyun  * @imux: imux helper object
3983*4882a593Smuzhiyun  * @label: the name of imux item to assign
3984*4882a593Smuzhiyun  * @index: index number of imux item to assign
3985*4882a593Smuzhiyun  * @type_idx: pointer to store the resultant label index
3986*4882a593Smuzhiyun  *
3987*4882a593Smuzhiyun  * When the same label is used already in the existing items, the number
3988*4882a593Smuzhiyun  * suffix is appended to the label.  This label index number is stored
3989*4882a593Smuzhiyun  * to type_idx when non-NULL pointer is given.
3990*4882a593Smuzhiyun  */
snd_hda_add_imux_item(struct hda_codec * codec,struct hda_input_mux * imux,const char * label,int index,int * type_idx)3991*4882a593Smuzhiyun int snd_hda_add_imux_item(struct hda_codec *codec,
3992*4882a593Smuzhiyun 			  struct hda_input_mux *imux, const char *label,
3993*4882a593Smuzhiyun 			  int index, int *type_idx)
3994*4882a593Smuzhiyun {
3995*4882a593Smuzhiyun 	int i, label_idx = 0;
3996*4882a593Smuzhiyun 	if (imux->num_items >= HDA_MAX_NUM_INPUTS) {
3997*4882a593Smuzhiyun 		codec_err(codec, "hda_codec: Too many imux items!\n");
3998*4882a593Smuzhiyun 		return -EINVAL;
3999*4882a593Smuzhiyun 	}
4000*4882a593Smuzhiyun 	for (i = 0; i < imux->num_items; i++) {
4001*4882a593Smuzhiyun 		if (!strncmp(label, imux->items[i].label, strlen(label)))
4002*4882a593Smuzhiyun 			label_idx++;
4003*4882a593Smuzhiyun 	}
4004*4882a593Smuzhiyun 	if (type_idx)
4005*4882a593Smuzhiyun 		*type_idx = label_idx;
4006*4882a593Smuzhiyun 	if (label_idx > 0)
4007*4882a593Smuzhiyun 		snprintf(imux->items[imux->num_items].label,
4008*4882a593Smuzhiyun 			 sizeof(imux->items[imux->num_items].label),
4009*4882a593Smuzhiyun 			 "%s %d", label, label_idx);
4010*4882a593Smuzhiyun 	else
4011*4882a593Smuzhiyun 		strlcpy(imux->items[imux->num_items].label, label,
4012*4882a593Smuzhiyun 			sizeof(imux->items[imux->num_items].label));
4013*4882a593Smuzhiyun 	imux->items[imux->num_items].index = index;
4014*4882a593Smuzhiyun 	imux->num_items++;
4015*4882a593Smuzhiyun 	return 0;
4016*4882a593Smuzhiyun }
4017*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_hda_add_imux_item);
4018*4882a593Smuzhiyun 
4019*4882a593Smuzhiyun /**
4020*4882a593Smuzhiyun  * snd_hda_bus_reset_codecs - Reset the bus
4021*4882a593Smuzhiyun  * @bus: HD-audio bus
4022*4882a593Smuzhiyun  */
snd_hda_bus_reset_codecs(struct hda_bus * bus)4023*4882a593Smuzhiyun void snd_hda_bus_reset_codecs(struct hda_bus *bus)
4024*4882a593Smuzhiyun {
4025*4882a593Smuzhiyun 	struct hda_codec *codec;
4026*4882a593Smuzhiyun 
4027*4882a593Smuzhiyun 	list_for_each_codec(codec, bus) {
4028*4882a593Smuzhiyun 		/* FIXME: maybe a better way needed for forced reset */
4029*4882a593Smuzhiyun 		if (current_work() != &codec->jackpoll_work.work)
4030*4882a593Smuzhiyun 			cancel_delayed_work_sync(&codec->jackpoll_work);
4031*4882a593Smuzhiyun #ifdef CONFIG_PM
4032*4882a593Smuzhiyun 		if (hda_codec_is_power_on(codec)) {
4033*4882a593Smuzhiyun 			hda_call_codec_suspend(codec);
4034*4882a593Smuzhiyun 			hda_call_codec_resume(codec);
4035*4882a593Smuzhiyun 		}
4036*4882a593Smuzhiyun #endif
4037*4882a593Smuzhiyun 	}
4038*4882a593Smuzhiyun }
4039*4882a593Smuzhiyun 
4040*4882a593Smuzhiyun /**
4041*4882a593Smuzhiyun  * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer
4042*4882a593Smuzhiyun  * @pcm: PCM caps bits
4043*4882a593Smuzhiyun  * @buf: the string buffer to write
4044*4882a593Smuzhiyun  * @buflen: the max buffer length
4045*4882a593Smuzhiyun  *
4046*4882a593Smuzhiyun  * used by hda_proc.c and hda_eld.c
4047*4882a593Smuzhiyun  */
snd_print_pcm_bits(int pcm,char * buf,int buflen)4048*4882a593Smuzhiyun void snd_print_pcm_bits(int pcm, char *buf, int buflen)
4049*4882a593Smuzhiyun {
4050*4882a593Smuzhiyun 	static const unsigned int bits[] = { 8, 16, 20, 24, 32 };
4051*4882a593Smuzhiyun 	int i, j;
4052*4882a593Smuzhiyun 
4053*4882a593Smuzhiyun 	for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++)
4054*4882a593Smuzhiyun 		if (pcm & (AC_SUPPCM_BITS_8 << i))
4055*4882a593Smuzhiyun 			j += scnprintf(buf + j, buflen - j,  " %d", bits[i]);
4056*4882a593Smuzhiyun 
4057*4882a593Smuzhiyun 	buf[j] = '\0'; /* necessary when j == 0 */
4058*4882a593Smuzhiyun }
4059*4882a593Smuzhiyun EXPORT_SYMBOL_GPL(snd_print_pcm_bits);
4060*4882a593Smuzhiyun 
4061*4882a593Smuzhiyun MODULE_DESCRIPTION("HDA codec core");
4062*4882a593Smuzhiyun MODULE_LICENSE("GPL");
4063