Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0-or-later
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3)  * Universal Interface for Intel High Definition Audio Codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (c) 2004 Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <sound/hda_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <sound/asoundef.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <sound/tlv.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include <sound/initval.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include <sound/jack.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include "hda_local.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "hda_beep.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "hda_jack.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #include <sound/hda_hwdep.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #include <sound/hda_component.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #define codec_in_pm(codec)		snd_hdac_is_in_pm(&codec->core)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #define hda_codec_is_power_on(codec)	snd_hdac_is_power_on(&codec->core)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define codec_has_epss(codec) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) 	((codec)->core.power_caps & AC_PWRST_EPSS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define codec_has_clkstop(codec) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) 	((codec)->core.power_caps & AC_PWRST_CLKSTOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35)  * Send and receive a verb - passed to exec_verb override for hdac_device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) static int codec_exec_verb(struct hdac_device *dev, unsigned int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) 			   unsigned int flags, unsigned int *res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) 	struct hda_codec *codec = container_of(dev, struct hda_codec, core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) 	struct hda_bus *bus = codec->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) 	if (cmd == ~0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47)  again:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) 	snd_hda_power_up_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) 	mutex_lock(&bus->core.cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) 	if (flags & HDA_RW_NO_RESPONSE_FALLBACK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) 		bus->no_response_fallback = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) 	err = snd_hdac_bus_exec_verb_unlocked(&bus->core, codec->core.addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) 					      cmd, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) 	bus->no_response_fallback = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 	mutex_unlock(&bus->core.cmd_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 	snd_hda_power_down_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 	if (!codec_in_pm(codec) && res && err == -EAGAIN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) 		if (bus->response_reset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) 			codec_dbg(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) 				  "resetting BUS due to fatal communication error\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) 			snd_hda_bus_reset(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 		goto again;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) 	/* clear reset-flag when the communication gets recovered */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) 	if (!err || codec_in_pm(codec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) 		bus->response_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72)  * snd_hda_sequence_write - sequence writes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74)  * @seq: VERB array to send
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76)  * Send the commands sequentially from the given array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77)  * The array must be terminated with NID=0.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) void snd_hda_sequence_write(struct hda_codec *codec, const struct hda_verb *seq)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	for (; seq->nid; seq++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 		snd_hda_codec_write(codec, seq->nid, 0, seq->verb, seq->param);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) EXPORT_SYMBOL_GPL(snd_hda_sequence_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) /* connection list element */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) struct hda_conn_list {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) 	struct list_head list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) 	hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	hda_nid_t conns[];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) /* look up the cached results */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) static struct hda_conn_list *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) lookup_conn_list(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) 	struct hda_conn_list *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 	list_for_each_entry(p, &codec->conn_list, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) 		if (p->nid == nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 			return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) static int add_conn_list(struct hda_codec *codec, hda_nid_t nid, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 			 const hda_nid_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	struct hda_conn_list *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	p = kmalloc(struct_size(p, conns, len), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) 	p->len = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	p->nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	memcpy(p->conns, list, len * sizeof(hda_nid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	list_add(&p->list, &codec->conn_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) static void remove_conn_list(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	while (!list_empty(&codec->conn_list)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 		struct hda_conn_list *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) 		p = list_first_entry(&codec->conn_list, typeof(*p), list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 		list_del(&p->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 		kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) /* read the connection and add to the cache */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) static int read_and_add_raw_conns(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	hda_nid_t list[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	hda_nid_t *result = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	int len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	len = snd_hda_get_raw_connections(codec, nid, list, ARRAY_SIZE(list));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) 	if (len == -ENOSPC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 		len = snd_hda_get_num_raw_conns(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) 		result = kmalloc_array(len, sizeof(hda_nid_t), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 		if (!result)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 		len = snd_hda_get_raw_connections(codec, nid, result, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	if (len >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 		len = snd_hda_override_conn_list(codec, nid, len, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	if (result != list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 		kfree(result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154)  * snd_hda_get_conn_list - get connection list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156)  * @nid: NID to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157)  * @listp: the pointer to store NID list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159)  * Parses the connection list of the given widget and stores the pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160)  * to the list of NIDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162)  * Returns the number of connections, or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164)  * Note that the returned pointer isn't protected against the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165)  * modification.  If snd_hda_override_conn_list() might be called
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166)  * concurrently, protect with a mutex appropriately.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) int snd_hda_get_conn_list(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 			  const hda_nid_t **listp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	bool added = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 		int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 		const struct hda_conn_list *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 		/* if the connection-list is already cached, read it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 		p = lookup_conn_list(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) 		if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 			if (listp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) 				*listp = p->conns;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 			return p->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 		if (snd_BUG_ON(added))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 		err = read_and_add_raw_conns(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 		added = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) EXPORT_SYMBOL_GPL(snd_hda_get_conn_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196)  * snd_hda_get_connections - copy connection list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198)  * @nid: NID to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199)  * @conn_list: connection list array; when NULL, checks only the size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200)  * @max_conns: max. number of connections to store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202)  * Parses the connection list of the given widget and stores the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203)  * of NIDs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205)  * Returns the number of connections, or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) int snd_hda_get_connections(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 			    hda_nid_t *conn_list, int max_conns)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	const hda_nid_t *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	int len = snd_hda_get_conn_list(codec, nid, &list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	if (len > 0 && conn_list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 		if (len > max_conns) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 			codec_err(codec, "Too many connections %d for NID 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 				   len, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		memcpy(conn_list, list, len * sizeof(hda_nid_t));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	return len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) EXPORT_SYMBOL_GPL(snd_hda_get_connections);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227)  * snd_hda_override_conn_list - add/modify the connection-list to cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229)  * @nid: NID to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230)  * @len: number of connection list entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231)  * @list: the list of connection entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233)  * Add or modify the given connection-list to the cache.  If the corresponding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234)  * cache already exists, invalidate it and append a new one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236)  * Returns zero or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) int snd_hda_override_conn_list(struct hda_codec *codec, hda_nid_t nid, int len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 			       const hda_nid_t *list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	struct hda_conn_list *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) 	p = lookup_conn_list(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 	if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 		list_del(&p->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 		kfree(p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	return add_conn_list(codec, nid, len, list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) EXPORT_SYMBOL_GPL(snd_hda_override_conn_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254)  * snd_hda_get_conn_index - get the connection index of the given NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256)  * @mux: NID containing the list
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257)  * @nid: NID to select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258)  * @recursive: 1 when searching NID recursively, otherwise 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260)  * Parses the connection list of the widget @mux and checks whether the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261)  * widget @nid is present.  If it is, return the connection index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262)  * Otherwise it returns -1.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) int snd_hda_get_conn_index(struct hda_codec *codec, hda_nid_t mux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 			   hda_nid_t nid, int recursive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	const hda_nid_t *conn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	int i, nums;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	nums = snd_hda_get_conn_list(codec, mux, &conn);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	for (i = 0; i < nums; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 		if (conn[i] == nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	if (!recursive)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	if (recursive > 10) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 		codec_dbg(codec, "too deep connection for 0x%x\n", nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 		return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 	recursive++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 	for (i = 0; i < nums; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		unsigned int type = get_wcaps_type(get_wcaps(codec, conn[i]));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 		if (type == AC_WID_PIN || type == AC_WID_AUD_OUT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 		if (snd_hda_get_conn_index(codec, conn[i], nid, recursive) >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) EXPORT_SYMBOL_GPL(snd_hda_get_conn_index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293)  * snd_hda_get_num_devices - get DEVLIST_LEN parameter of the given widget
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294)  *  @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295)  *  @nid: NID of the pin to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297)  * Get the device entry number on the given widget. This is a feature of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298)  * DP MST audio. Each pin can have several device entries in it.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) unsigned int snd_hda_get_num_devices(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 	unsigned int wcaps = get_wcaps(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 	unsigned int parm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 	if (!codec->dp_mst || !(wcaps & AC_WCAP_DIGITAL) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	    get_wcaps_type(wcaps) != AC_WID_PIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	parm = snd_hdac_read_parm_uncached(&codec->core, nid, AC_PAR_DEVLIST_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	if (parm == -1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 		parm = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 	return parm & AC_DEV_LIST_LEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) EXPORT_SYMBOL_GPL(snd_hda_get_num_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317)  * snd_hda_get_devices - copy device list without cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319)  * @nid: NID of the pin to parse
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320)  * @dev_list: device list array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321)  * @max_devices: max. number of devices to store
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323)  * Copy the device list. This info is dynamic and so not cached.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324)  * Currently called only from hda_proc.c, so not exported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) int snd_hda_get_devices(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 			u8 *dev_list, int max_devices)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	unsigned int parm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 	int i, dev_len, devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	parm = snd_hda_get_num_devices(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	if (!parm)	/* not multi-stream capable */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	dev_len = parm + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	dev_len = dev_len < max_devices ? dev_len : max_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	devices = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	while (devices < dev_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 		if (snd_hdac_read(&codec->core, nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 				  AC_VERB_GET_DEVICE_LIST, devices, &parm))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 			break; /* error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		for (i = 0; i < 8; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 			dev_list[devices] = (u8)parm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 			parm >>= 4;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 			devices++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 			if (devices >= dev_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	return devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357)  * snd_hda_get_dev_select - get device entry select on the pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359)  * @nid: NID of the pin to get device entry select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361)  * Get the devcie entry select on the pin. Return the device entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362)  * id selected on the pin. Return 0 means the first device entry
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363)  * is selected or MST is not supported.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) int snd_hda_get_dev_select(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	/* not support dp_mst will always return 0, using first dev_entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	if (!codec->dp_mst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	return snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_DEVICE_SEL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) EXPORT_SYMBOL_GPL(snd_hda_get_dev_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376)  * snd_hda_set_dev_select - set device entry select on the pin
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378)  * @nid: NID of the pin to set device entry select
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379)  * @dev_id: device entry id to be set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381)  * Set the device entry select on the pin nid.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) int snd_hda_set_dev_select(struct hda_codec *codec, hda_nid_t nid, int dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	int ret, num_devices;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	/* not support dp_mst will always return 0, using first dev_entry */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 	if (!codec->dp_mst)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	/* AC_PAR_DEVLIST_LEN is 0 based. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 	num_devices = snd_hda_get_num_devices(codec, nid) + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 	/* If Device List Length is 0 (num_device = 1),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	 * the pin is not multi stream capable.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	 * Do nothing in this case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 	if (num_devices == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	/* Behavior of setting index being equal to or greater than
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 	 * Device List Length is not predictable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 	if (num_devices <= dev_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 	ret = snd_hda_codec_write(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 			AC_VERB_SET_DEVICE_SEL, dev_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) EXPORT_SYMBOL_GPL(snd_hda_set_dev_select);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414)  * read widget caps for each widget and store in cache
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) static int read_widget_caps(struct hda_codec *codec, hda_nid_t fg_node)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 	hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 	codec->wcaps = kmalloc_array(codec->core.num_nodes, 4, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 	if (!codec->wcaps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 	nid = codec->core.start_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	for (i = 0; i < codec->core.num_nodes; i++, nid++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 		codec->wcaps[i] = snd_hdac_read_parm_uncached(&codec->core,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 					nid, AC_PAR_AUDIO_WIDGET_CAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) /* read all pin default configurations and save codec->init_pins */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) static int read_pin_defaults(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	for_each_hda_codec_node(nid, codec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		struct hda_pincfg *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		unsigned int wcaps = get_wcaps(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 		unsigned int wid_type = get_wcaps_type(wcaps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		if (wid_type != AC_WID_PIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		pin = snd_array_new(&codec->init_pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 		if (!pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 		pin->nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		pin->cfg = snd_hda_codec_read(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 					      AC_VERB_GET_CONFIG_DEFAULT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 		 * all device entries are the same widget control so far
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		 * fixme: if any codec is different, need fix here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		pin->ctrl = snd_hda_codec_read(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 					       AC_VERB_GET_PIN_WIDGET_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 					       0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) /* look up the given pin config list and return the item matching with NID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) static struct hda_pincfg *look_up_pincfg(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 					 struct snd_array *array,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 					 hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	struct hda_pincfg *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	snd_array_for_each(array, i, pin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 		if (pin->nid == nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 			return pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) /* set the current pin config value for the given NID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475)  * the value is cached, and read via snd_hda_codec_get_pincfg()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) int snd_hda_add_pincfg(struct hda_codec *codec, struct snd_array *list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 		       hda_nid_t nid, unsigned int cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 	struct hda_pincfg *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 	/* the check below may be invalid when pins are added by a fixup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 	 * dynamically (e.g. via snd_hda_codec_update_widgets()), so disabled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	 * for now
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 	if (get_wcaps_type(get_wcaps(codec, nid)) != AC_WID_PIN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	pin = look_up_pincfg(codec, list, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 	if (!pin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 		pin = snd_array_new(list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 		if (!pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 		pin->nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 	pin->cfg = cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503)  * snd_hda_codec_set_pincfg - Override a pin default configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505)  * @nid: NID to set the pin config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506)  * @cfg: the pin default config value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508)  * Override a pin default configuration value in the cache.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509)  * This value can be read by snd_hda_codec_get_pincfg() in a higher
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510)  * priority than the real hardware value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) int snd_hda_codec_set_pincfg(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 			     hda_nid_t nid, unsigned int cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 	return snd_hda_add_pincfg(codec, &codec->driver_pins, nid, cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) EXPORT_SYMBOL_GPL(snd_hda_codec_set_pincfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520)  * snd_hda_codec_get_pincfg - Obtain a pin-default configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522)  * @nid: NID to get the pin config
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524)  * Get the current pin config value of the given pin NID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525)  * If the pincfg value is cached or overridden via sysfs or driver,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526)  * returns the cached value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) unsigned int snd_hda_codec_get_pincfg(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 	struct hda_pincfg *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) #ifdef CONFIG_SND_HDA_RECONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 		unsigned int cfg = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		mutex_lock(&codec->user_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		pin = look_up_pincfg(codec, &codec->user_pins, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		if (pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 			cfg = pin->cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 		mutex_unlock(&codec->user_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		if (cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 			return cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	pin = look_up_pincfg(codec, &codec->driver_pins, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	if (pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 		return pin->cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	pin = look_up_pincfg(codec, &codec->init_pins, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	if (pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 		return pin->cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) EXPORT_SYMBOL_GPL(snd_hda_codec_get_pincfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555)  * snd_hda_codec_set_pin_target - remember the current pinctl target value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557)  * @nid: pin NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558)  * @val: assigned pinctl value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560)  * This function stores the given value to a pinctl target value in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561)  * pincfg table.  This isn't always as same as the actually written value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562)  * but can be referred at any time via snd_hda_codec_get_pin_target().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) int snd_hda_codec_set_pin_target(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 				 unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 	struct hda_pincfg *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) 	pin = look_up_pincfg(codec, &codec->init_pins, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) 	if (!pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 	pin->target = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) EXPORT_SYMBOL_GPL(snd_hda_codec_set_pin_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578)  * snd_hda_codec_get_pin_target - return the current pinctl target value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580)  * @nid: pin NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) int snd_hda_codec_get_pin_target(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	struct hda_pincfg *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	pin = look_up_pincfg(codec, &codec->init_pins, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	if (!pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 	return pin->target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) EXPORT_SYMBOL_GPL(snd_hda_codec_get_pin_target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594)  * snd_hda_shutup_pins - Shut up all pins
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597)  * Clear all pin controls to shup up before suspend for avoiding click noise.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598)  * The controls aren't cached so that they can be resumed properly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) void snd_hda_shutup_pins(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	const struct hda_pincfg *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	/* don't shut up pins when unloading the driver; otherwise it breaks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	 * the default pin setup at the next load of the driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	if (codec->bus->shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	snd_array_for_each(&codec->init_pins, i, pin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 		/* use read here for syncing after issuing each verb */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 		snd_hda_codec_read(codec, pin->nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 				   AC_VERB_SET_PIN_WIDGET_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 	codec->pins_shutup = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) EXPORT_SYMBOL_GPL(snd_hda_shutup_pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) /* Restore the pin controls cleared previously via snd_hda_shutup_pins() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) static void restore_shutup_pins(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	const struct hda_pincfg *pin;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	if (!codec->pins_shutup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	if (codec->bus->shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	snd_array_for_each(&codec->init_pins, i, pin) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 		snd_hda_codec_write(codec, pin->nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 				    AC_VERB_SET_PIN_WIDGET_CONTROL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 				    pin->ctrl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	codec->pins_shutup = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) static void hda_jackpoll_work(struct work_struct *work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 	struct hda_codec *codec =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		container_of(work, struct hda_codec, jackpoll_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 	/* for non-polling trigger: we need nothing if already powered on */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	if (!codec->jackpoll_interval && snd_hdac_is_power_on(&codec->core))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 	/* the power-up/down sequence triggers the runtime resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 	snd_hda_power_up_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 	/* update jacks manually if polling is required, too */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 	if (codec->jackpoll_interval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 		snd_hda_jack_set_dirty_all(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		snd_hda_jack_poll_all(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 	snd_hda_power_down_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	if (!codec->jackpoll_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 	schedule_delayed_work(&codec->jackpoll_work,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 			      codec->jackpoll_interval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) /* release all pincfg lists */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) static void free_init_pincfgs(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 	snd_array_free(&codec->driver_pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) #ifdef CONFIG_SND_HDA_RECONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 	snd_array_free(&codec->user_pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	snd_array_free(&codec->init_pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675)  * audio-converter setup caches
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) struct hda_cvt_setup {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 	u8 stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 	u8 channel_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	u16 format_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 	unsigned char active;	/* cvt is currently used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 	unsigned char dirty;	/* setups should be cleared */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) /* get or create a cache entry for the given audio converter NID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) static struct hda_cvt_setup *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) get_hda_cvt_setup(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 	struct hda_cvt_setup *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 	snd_array_for_each(&codec->cvt_setups, i, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 		if (p->nid == nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 			return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 	p = snd_array_new(&codec->cvt_setups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	if (p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		p->nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 	return p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704)  * PCM device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) static void release_pcm(struct kref *kref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 	struct hda_pcm *pcm = container_of(kref, struct hda_pcm, kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 	if (pcm->pcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 		snd_device_free(pcm->codec->card, pcm->pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	clear_bit(pcm->device, pcm->codec->bus->pcm_dev_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 	kfree(pcm->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	kfree(pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) void snd_hda_codec_pcm_put(struct hda_pcm *pcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 	kref_put(&pcm->kref, release_pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) struct hda_pcm *snd_hda_codec_pcm_new(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 				      const char *fmt, ...)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	struct hda_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 	va_list args;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 	pcm = kzalloc(sizeof(*pcm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	if (!pcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	pcm->codec = codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 	kref_init(&pcm->kref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	va_start(args, fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	pcm->name = kvasprintf(GFP_KERNEL, fmt, args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	va_end(args);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	if (!pcm->name) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		kfree(pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	list_add_tail(&pcm->list, &codec->pcm_list_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) 	return pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) EXPORT_SYMBOL_GPL(snd_hda_codec_pcm_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749)  * codec destructor
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) static void codec_release_pcms(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	struct hda_pcm *pcm, *n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	list_for_each_entry_safe(pcm, n, &codec->pcm_list_head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 		list_del_init(&pcm->list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 		if (pcm->pcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 			snd_device_disconnect(codec->card, pcm->pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 		snd_hda_codec_pcm_put(pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) void snd_hda_codec_cleanup_for_unbind(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	if (codec->registered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		/* pm_runtime_put() is called in snd_hdac_device_exit() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		pm_runtime_get_noresume(hda_codec_dev(codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 		pm_runtime_disable(hda_codec_dev(codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 		codec->registered = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	cancel_delayed_work_sync(&codec->jackpoll_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	if (!codec->in_freeing)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 		snd_hda_ctls_clear(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	codec_release_pcms(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	snd_hda_detach_beep_device(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 	memset(&codec->patch_ops, 0, sizeof(codec->patch_ops));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	snd_hda_jack_tbl_clear(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 	codec->proc_widget_hook = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	codec->spec = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	/* free only driver_pins so that init_pins + user_pins are restored */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 	snd_array_free(&codec->driver_pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	snd_array_free(&codec->cvt_setups);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 	snd_array_free(&codec->spdif_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 	snd_array_free(&codec->verbs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 	codec->preset = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 	codec->follower_dig_outs = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	codec->spdif_status_reset = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	snd_array_free(&codec->mixers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	snd_array_free(&codec->nids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 	remove_conn_list(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 	snd_hdac_regmap_exit(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	codec->configured = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup_for_unbind);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) static unsigned int hda_set_power_state(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 				unsigned int power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) /* enable/disable display power per codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) static void codec_display_power(struct hda_codec *codec, bool enable)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 	if (codec->display_power_control)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		snd_hdac_display_power(&codec->bus->core, codec->addr, enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) /* also called from hda_bind.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) void snd_hda_codec_register(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	if (codec->registered)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	if (device_is_registered(hda_codec_dev(codec))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 		codec_display_power(codec, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 		pm_runtime_enable(hda_codec_dev(codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 		/* it was powered up in snd_hda_codec_new(), now all done */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 		snd_hda_power_down(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 		codec->registered = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) static int snd_hda_codec_dev_register(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	snd_hda_codec_register(device->device_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) static int snd_hda_codec_dev_free(struct snd_device *device)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	struct hda_codec *codec = device->device_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 	codec->in_freeing = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) 	 * snd_hda_codec_device_new() is used by legacy HDA and ASoC driver.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	 * We can't unregister ASoC device since it will be unregistered in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 	 * snd_hdac_ext_bus_device_remove().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	if (codec->core.type == HDA_DEV_LEGACY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) 		snd_hdac_device_unregister(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 	codec_display_power(codec, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	 * In the case of ASoC HD-audio bus, the device refcount is released in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	 * snd_hdac_ext_bus_device_remove() explicitly.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	if (codec->core.type == HDA_DEV_LEGACY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 		put_device(hda_codec_dev(codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) static void snd_hda_codec_dev_release(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	struct hda_codec *codec = dev_to_hda_codec(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	free_init_pincfgs(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	snd_hdac_device_exit(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 	snd_hda_sysfs_clear(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	kfree(codec->modelname);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	kfree(codec->wcaps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	 * In the case of ASoC HD-audio, hda_codec is device managed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	 * It will be freed when the ASoC device is removed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	if (codec->core.type == HDA_DEV_LEGACY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		kfree(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) #define DEV_NAME_LEN 31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) static int snd_hda_codec_device_init(struct hda_bus *bus, struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 			unsigned int codec_addr, struct hda_codec **codecp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 	char name[DEV_NAME_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	struct hda_codec *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 	dev_dbg(card->dev, "%s: entry\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 	if (snd_BUG_ON(!bus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	codec = kzalloc(sizeof(*codec), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	if (!codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	sprintf(name, "hdaudioC%dD%d", card->number, codec_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 	err = snd_hdac_device_init(&codec->core, &bus->core, name, codec_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 		kfree(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 	codec->core.type = HDA_DEV_LEGACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	*codecp = codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904)  * snd_hda_codec_new - create a HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905)  * @bus: the bus to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906)  * @card: card for this codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907)  * @codec_addr: the codec address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908)  * @codecp: the pointer to store the generated codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910)  * Returns 0 if successful, or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) int snd_hda_codec_new(struct hda_bus *bus, struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 		      unsigned int codec_addr, struct hda_codec **codecp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 	ret = snd_hda_codec_device_init(bus, card, codec_addr, codecp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 		return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	return snd_hda_codec_device_new(bus, card, codec_addr, *codecp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) EXPORT_SYMBOL_GPL(snd_hda_codec_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) int snd_hda_codec_device_new(struct hda_bus *bus, struct snd_card *card,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 			unsigned int codec_addr, struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 	char component[31];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	hda_nid_t fg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	static const struct snd_device_ops dev_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 		.dev_register = snd_hda_codec_dev_register,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 		.dev_free = snd_hda_codec_dev_free,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	dev_dbg(card->dev, "%s: entry\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	if (snd_BUG_ON(!bus))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	if (snd_BUG_ON(codec_addr > HDA_MAX_CODEC_ADDRESS))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	codec->core.dev.release = snd_hda_codec_dev_release;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 	codec->core.exec_verb = codec_exec_verb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	codec->bus = bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	codec->card = card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	codec->addr = codec_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 	mutex_init(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	mutex_init(&codec->control_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	snd_array_init(&codec->mixers, sizeof(struct hda_nid_item), 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	snd_array_init(&codec->nids, sizeof(struct hda_nid_item), 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	snd_array_init(&codec->init_pins, sizeof(struct hda_pincfg), 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	snd_array_init(&codec->driver_pins, sizeof(struct hda_pincfg), 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	snd_array_init(&codec->cvt_setups, sizeof(struct hda_cvt_setup), 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	snd_array_init(&codec->spdif_out, sizeof(struct hda_spdif_out), 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	snd_array_init(&codec->jacktbl, sizeof(struct hda_jack_tbl), 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 	snd_array_init(&codec->verbs, sizeof(struct hda_verb *), 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	INIT_LIST_HEAD(&codec->conn_list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	INIT_LIST_HEAD(&codec->pcm_list_head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	INIT_DELAYED_WORK(&codec->jackpoll_work, hda_jackpoll_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	codec->depop_delay = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 	codec->fixup_id = HDA_FIXUP_ID_NOT_SET;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 	codec->power_jiffies = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	snd_hda_sysfs_init(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 	if (codec->bus->modelname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		codec->modelname = kstrdup(codec->bus->modelname, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		if (!codec->modelname) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			err = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 			goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 	fg = codec->core.afg ? codec->core.afg : codec->core.mfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	err = read_widget_caps(codec, fg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	err = read_pin_defaults(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	/* power-up all before initialization */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	hda_set_power_state(codec, AC_PWRST_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	codec->core.dev.power.power_state = PMSG_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	snd_hda_codec_proc_new(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	snd_hda_create_hwdep(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	sprintf(component, "HDA:%08x,%08x,%08x", codec->core.vendor_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 		codec->core.subsystem_id, codec->core.revision_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	snd_component_add(card, component);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	err = snd_device_new(card, SNDRV_DEV_CODEC, codec, &dev_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 		goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	/* PM runtime needs to be enabled later after binding codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) 	pm_runtime_forbid(&codec->core.dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009)  error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	put_device(hda_codec_dev(codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) EXPORT_SYMBOL_GPL(snd_hda_codec_device_new);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016)  * snd_hda_codec_update_widgets - Refresh widget caps and pin defaults
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019)  * Forcibly refresh the all widget caps and the init pin configurations of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020)  * the given codec.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) int snd_hda_codec_update_widgets(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	hda_nid_t fg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	err = snd_hdac_refresh_widgets(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	/* Assume the function group node does not change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	 * only the widget nodes may change.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 	kfree(codec->wcaps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	fg = codec->core.afg ? codec->core.afg : codec->core.mfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 	err = read_widget_caps(codec, fg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	snd_array_free(&codec->init_pins);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	err = read_pin_defaults(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) EXPORT_SYMBOL_GPL(snd_hda_codec_update_widgets);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) /* update the stream-id if changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) static void update_pcm_stream_id(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 				 struct hda_cvt_setup *p, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 				 u32 stream_tag, int channel_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) 	unsigned int oldval, newval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) 	if (p->stream_tag != stream_tag || p->channel_id != channel_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 		oldval = snd_hda_codec_read(codec, nid, 0, AC_VERB_GET_CONV, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 		newval = (stream_tag << 4) | channel_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 		if (oldval != newval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 			snd_hda_codec_write(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 					    AC_VERB_SET_CHANNEL_STREAMID,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 					    newval);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 		p->stream_tag = stream_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		p->channel_id = channel_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* update the format-id if changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) static void update_pcm_format(struct hda_codec *codec, struct hda_cvt_setup *p,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			      hda_nid_t nid, int format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 	unsigned int oldval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 	if (p->format_id != format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		oldval = snd_hda_codec_read(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 					    AC_VERB_GET_STREAM_FORMAT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 		if (oldval != format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 			msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 			snd_hda_codec_write(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 					    AC_VERB_SET_STREAM_FORMAT,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 					    format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 		p->format_id = format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)  * snd_hda_codec_setup_stream - set up the codec for streaming
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)  * @codec: the CODEC to set up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)  * @nid: the NID to set up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)  * @stream_tag: stream tag to pass, it's between 0x1 and 0xf.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)  * @channel_id: channel id to pass, zero based.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091)  * @format: stream format.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) void snd_hda_codec_setup_stream(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 				u32 stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 				int channel_id, int format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	struct hda_codec *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	struct hda_cvt_setup *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	int type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 	if (!nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	codec_dbg(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		  "hda_codec_setup_stream: NID=0x%x, stream=0x%x, channel=%d, format=0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 		  nid, stream_tag, channel_id, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	p = get_hda_cvt_setup(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 	if (codec->patch_ops.stream_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		codec->patch_ops.stream_pm(codec, nid, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	if (codec->pcm_format_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 		update_pcm_format(codec, p, nid, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	update_pcm_stream_id(codec, p, nid, stream_tag, channel_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	if (!codec->pcm_format_first)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 		update_pcm_format(codec, p, nid, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	p->active = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	p->dirty = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 	/* make other inactive cvts with the same stream-tag dirty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	type = get_wcaps_type(get_wcaps(codec, nid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	list_for_each_codec(c, codec->bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		snd_array_for_each(&c->cvt_setups, i, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 			if (!p->active && p->stream_tag == stream_tag &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			    get_wcaps_type(get_wcaps(c, p->nid)) == type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 				p->dirty = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) EXPORT_SYMBOL_GPL(snd_hda_codec_setup_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) static void really_cleanup_stream(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 				  struct hda_cvt_setup *q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)  * __snd_hda_codec_cleanup_stream - clean up the codec for closing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140)  * @codec: the CODEC to clean up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141)  * @nid: the NID to clean up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)  * @do_now: really clean up the stream instead of clearing the active flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) void __snd_hda_codec_cleanup_stream(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 				    int do_now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	struct hda_cvt_setup *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	if (!nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 	if (codec->no_sticky_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 		do_now = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	codec_dbg(codec, "hda_codec_cleanup_stream: NID=0x%x\n", nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 	p = get_hda_cvt_setup(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	if (p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 		/* here we just clear the active flag when do_now isn't set;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 		 * actual clean-ups will be done later in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 		 * purify_inactive_streams() called from snd_hda_codec_prpapre()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 		if (do_now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 			really_cleanup_stream(codec, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 			p->active = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) EXPORT_SYMBOL_GPL(__snd_hda_codec_cleanup_stream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) static void really_cleanup_stream(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 				  struct hda_cvt_setup *q)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	hda_nid_t nid = q->nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 	if (q->stream_tag || q->channel_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CHANNEL_STREAMID, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 	if (q->format_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_STREAM_FORMAT, 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) );
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 	memset(q, 0, sizeof(*q));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 	q->nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	if (codec->patch_ops.stream_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 		codec->patch_ops.stream_pm(codec, nid, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* clean up the all conflicting obsolete streams */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) static void purify_inactive_streams(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	struct hda_codec *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	struct hda_cvt_setup *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	list_for_each_codec(c, codec->bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 		snd_array_for_each(&c->cvt_setups, i, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 			if (p->dirty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 				really_cleanup_stream(c, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) /* clean up all streams; called from suspend */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) static void hda_cleanup_all_streams(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	struct hda_cvt_setup *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 	snd_array_for_each(&codec->cvt_setups, i, p) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 		if (p->stream_tag)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 			really_cleanup_stream(codec, p);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)  * amp access functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219)  * query_amp_caps - query AMP capabilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220)  * @codec: the HD-auio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221)  * @nid: the NID to query
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222)  * @direction: either #HDA_INPUT or #HDA_OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224)  * Query AMP capabilities for the given widget and direction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225)  * Returns the obtained capability bits.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)  * When cap bits have been already read, this doesn't read again but
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228)  * returns the cached value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) u32 query_amp_caps(struct hda_codec *codec, hda_nid_t nid, int direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	if (!(get_wcaps(codec, nid) & AC_WCAP_AMP_OVRD))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 		nid = codec->core.afg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	return snd_hda_param_read(codec, nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 				  direction == HDA_OUTPUT ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 				  AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) EXPORT_SYMBOL_GPL(query_amp_caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241)  * snd_hda_check_amp_caps - query AMP capabilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242)  * @codec: the HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243)  * @nid: the NID to query
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244)  * @dir: either #HDA_INPUT or #HDA_OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245)  * @bits: bit mask to check the result
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247)  * Check whether the widget has the given amp capability for the direction.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) bool snd_hda_check_amp_caps(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 			   int dir, unsigned int bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	if (!nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 	if (get_wcaps(codec, nid) & (1 << (dir + 1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 		if (query_amp_caps(codec, nid, dir) & bits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 			return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 	return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) EXPORT_SYMBOL_GPL(snd_hda_check_amp_caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262)  * snd_hda_override_amp_caps - Override the AMP capabilities
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)  * @codec: the CODEC to clean up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264)  * @nid: the NID to clean up
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265)  * @dir: either #HDA_INPUT or #HDA_OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266)  * @caps: the capability bits to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268)  * Override the cached AMP caps bits value by the given one.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269)  * This function is useful if the driver needs to adjust the AMP ranges,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270)  * e.g. limit to 0dB, etc.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272)  * Returns zero if successful or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) int snd_hda_override_amp_caps(struct hda_codec *codec, hda_nid_t nid, int dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 			      unsigned int caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	unsigned int parm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	snd_hda_override_wcaps(codec, nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 			       get_wcaps(codec, nid) | AC_WCAP_AMP_OVRD);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	parm = dir == HDA_OUTPUT ? AC_PAR_AMP_OUT_CAP : AC_PAR_AMP_IN_CAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	return snd_hdac_override_parm(&codec->core, nid, parm, caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) EXPORT_SYMBOL_GPL(snd_hda_override_amp_caps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) static unsigned int encode_amp(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 			       int ch, int dir, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	unsigned int cmd = snd_hdac_regmap_encode_amp(nid, ch, dir, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	/* enable fake mute if no h/w mute but min=mute */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	if ((query_amp_caps(codec, nid, dir) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 	     (AC_AMPCAP_MUTE | AC_AMPCAP_MIN_MUTE)) == AC_AMPCAP_MIN_MUTE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		cmd |= AC_AMP_FAKE_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	return cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299)  * snd_hda_codec_amp_update - update the AMP mono value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300)  * @codec: HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)  * @nid: NID to read the AMP value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302)  * @ch: channel to update (0 or 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303)  * @dir: #HDA_INPUT or #HDA_OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304)  * @idx: the index value (only for input direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305)  * @mask: bit mask to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)  * @val: the bits value to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)  * Update the AMP values for the given channel, direction and index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) int snd_hda_codec_amp_update(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 			     int ch, int dir, int idx, int mask, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	unsigned int cmd = encode_amp(codec, nid, ch, dir, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	return snd_hdac_regmap_update_raw(&codec->core, cmd, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) EXPORT_SYMBOL_GPL(snd_hda_codec_amp_update);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320)  * snd_hda_codec_amp_stereo - update the AMP stereo values
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321)  * @codec: HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)  * @nid: NID to read the AMP value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323)  * @direction: #HDA_INPUT or #HDA_OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324)  * @idx: the index value (only for input direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325)  * @mask: bit mask to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326)  * @val: the bits value to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328)  * Update the AMP values like snd_hda_codec_amp_update(), but for a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329)  * stereo widget with the same mask and value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) int snd_hda_codec_amp_stereo(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 			     int direction, int idx, int mask, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) 	int ch, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) 	if (snd_BUG_ON(mask & ~0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 		mask &= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 	for (ch = 0; ch < 2; ch++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) 		ret |= snd_hda_codec_amp_update(codec, nid, ch, direction,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 						idx, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) EXPORT_SYMBOL_GPL(snd_hda_codec_amp_stereo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346)  * snd_hda_codec_amp_init - initialize the AMP value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)  * @nid: NID to read the AMP value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349)  * @ch: channel (left=0 or right=1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)  * @dir: #HDA_INPUT or #HDA_OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351)  * @idx: the index value (only for input direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352)  * @mask: bit mask to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353)  * @val: the bits value to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355)  * Works like snd_hda_codec_amp_update() but it writes the value only at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356)  * the first access.  If the amp was already initialized / updated beforehand,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)  * this does nothing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) int snd_hda_codec_amp_init(struct hda_codec *codec, hda_nid_t nid, int ch,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 			   int dir, int idx, int mask, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 	unsigned int cmd = encode_amp(codec, nid, ch, dir, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) 	if (!codec->core.regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) 	return snd_hdac_regmap_update_raw_once(&codec->core, cmd, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) EXPORT_SYMBOL_GPL(snd_hda_codec_amp_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)  * snd_hda_codec_amp_init_stereo - initialize the stereo AMP value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373)  * @nid: NID to read the AMP value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374)  * @dir: #HDA_INPUT or #HDA_OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375)  * @idx: the index value (only for input direction)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376)  * @mask: bit mask to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377)  * @val: the bits value to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)  * Call snd_hda_codec_amp_init() for both stereo channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) int snd_hda_codec_amp_init_stereo(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) 				  int dir, int idx, int mask, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 	int ch, ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) 	if (snd_BUG_ON(mask & ~0xff))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) 		mask &= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) 	for (ch = 0; ch < 2; ch++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) 		ret |= snd_hda_codec_amp_init(codec, nid, ch, dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390) 					      idx, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393) EXPORT_SYMBOL_GPL(snd_hda_codec_amp_init_stereo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395) static u32 get_amp_max_value(struct hda_codec *codec, hda_nid_t nid, int dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) 			     unsigned int ofs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 	u32 caps = query_amp_caps(codec, nid, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 	/* get num steps */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) 	caps = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	if (ofs < caps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 		caps -= ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	return caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407)  * snd_hda_mixer_amp_volume_info - Info callback for a standard AMP mixer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408)  * @kcontrol: referred ctl element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409)  * @uinfo: pointer to get/store the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411)  * The control element is supposed to have the private_value field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412)  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) int snd_hda_mixer_amp_volume_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	u16 nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	u8 chs = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	int dir = get_amp_direction(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	unsigned int ofs = get_amp_offset(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	uinfo->count = chs == 3 ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	uinfo->value.integer.max = get_amp_max_value(codec, nid, dir, ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	if (!uinfo->value.integer.max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 		codec_warn(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 			   "num_steps = 0 for NID=0x%x (ctl = %s)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 			   nid, kcontrol->id.name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) static inline unsigned int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) read_amp_value(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) 	       int ch, int dir, int idx, unsigned int ofs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) 	val = snd_hda_codec_amp_read(codec, nid, ch, dir, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444) 	val &= HDA_AMP_VOLMASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445) 	if (val >= ofs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446) 		val -= ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448) 		val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) static inline int
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) update_amp_value(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 		 int ch, int dir, int idx, unsigned int ofs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 		 unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	unsigned int maxval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	if (val > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 		val += ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 	/* ofs = 0: raw max value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	maxval = get_amp_max_value(codec, nid, dir, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	if (val > maxval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 		val = maxval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 	return snd_hda_codec_amp_update(codec, nid, ch, dir, idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 					HDA_AMP_VOLMASK, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470)  * snd_hda_mixer_amp_volume_get - Get callback for a standard AMP mixer volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471)  * @kcontrol: ctl element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472)  * @ucontrol: pointer to get/store the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474)  * The control element is supposed to have the private_value field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475)  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) int snd_hda_mixer_amp_volume_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 	int chs = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	int dir = get_amp_direction(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 	int idx = get_amp_index(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	unsigned int ofs = get_amp_offset(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 	long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	if (chs & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 		*valp++ = read_amp_value(codec, nid, 0, dir, idx, ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	if (chs & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 		*valp = read_amp_value(codec, nid, 1, dir, idx, ofs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497)  * snd_hda_mixer_amp_volume_put - Put callback for a standard AMP mixer volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498)  * @kcontrol: ctl element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499)  * @ucontrol: pointer to get/store the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501)  * The control element is supposed to have the private_value field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502)  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) int snd_hda_mixer_amp_volume_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	int chs = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	int dir = get_amp_direction(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 	int idx = get_amp_index(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 	unsigned int ofs = get_amp_offset(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	if (chs & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 		change = update_amp_value(codec, nid, 0, dir, idx, ofs, *valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 		valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 	if (chs & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 		change |= update_amp_value(codec, nid, 1, dir, idx, ofs, *valp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_volume_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) /* inquiry the amp caps and convert to TLV */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) static void get_ctl_amp_tlv(struct snd_kcontrol *kcontrol, unsigned int *tlv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 	hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 	int dir = get_amp_direction(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 	unsigned int ofs = get_amp_offset(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	bool min_mute = get_amp_min_mute(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 	u32 caps, val1, val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 	caps = query_amp_caps(codec, nid, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	val2 = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 	val2 = (val2 + 1) * 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	val1 = -((caps & AC_AMPCAP_OFFSET) >> AC_AMPCAP_OFFSET_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	val1 += ofs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) 	val1 = ((int)val1) * ((int)val2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 	if (min_mute || (caps & AC_AMPCAP_MIN_MUTE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) 		val2 |= TLV_DB_SCALE_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544) 	tlv[SNDRV_CTL_TLVO_TYPE] = SNDRV_CTL_TLVT_DB_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545) 	tlv[SNDRV_CTL_TLVO_LEN] = 2 * sizeof(unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546) 	tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] = val1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547) 	tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] = val2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)  * snd_hda_mixer_amp_tlv - TLV callback for a standard AMP mixer volume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)  * @kcontrol: ctl element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553)  * @op_flag: operation flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554)  * @size: byte size of input TLV
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555)  * @_tlv: TLV data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557)  * The control element is supposed to have the private_value field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558)  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) int snd_hda_mixer_amp_tlv(struct snd_kcontrol *kcontrol, int op_flag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561) 			  unsigned int size, unsigned int __user *_tlv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563) 	unsigned int tlv[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565) 	if (size < 4 * sizeof(unsigned int))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567) 	get_ctl_amp_tlv(kcontrol, tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568) 	if (copy_to_user(_tlv, tlv, sizeof(tlv)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569) 		return -EFAULT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575)  * snd_hda_set_vmaster_tlv - Set TLV for a virtual master control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576)  * @codec: HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577)  * @nid: NID of a reference widget
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578)  * @dir: #HDA_INPUT or #HDA_OUTPUT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579)  * @tlv: TLV data to be stored, at least 4 elements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581)  * Set (static) TLV data for a virtual master volume using the AMP caps
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582)  * obtained from the reference NID.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583)  * The volume range is recalculated as if the max volume is 0dB.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 			     unsigned int *tlv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 	u32 caps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	int nums, step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 	caps = query_amp_caps(codec, nid, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	nums = (caps & AC_AMPCAP_NUM_STEPS) >> AC_AMPCAP_NUM_STEPS_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	step = (caps & AC_AMPCAP_STEP_SIZE) >> AC_AMPCAP_STEP_SIZE_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	step = (step + 1) * 25;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 	tlv[SNDRV_CTL_TLVO_TYPE] = SNDRV_CTL_TLVT_DB_SCALE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	tlv[SNDRV_CTL_TLVO_LEN] = 2 * sizeof(unsigned int);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] = -nums * step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP] = step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) EXPORT_SYMBOL_GPL(snd_hda_set_vmaster_tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) /* find a mixer control element with the given name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) static struct snd_kcontrol *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) find_mixer_ctl(struct hda_codec *codec, const char *name, int dev, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	struct snd_ctl_elem_id id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 	memset(&id, 0, sizeof(id));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 	id.device = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	id.index = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 	if (snd_BUG_ON(strlen(name) >= sizeof(id.name)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 	strcpy(id.name, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 	return snd_ctl_find_id(codec->card, &id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618)  * snd_hda_find_mixer_ctl - Find a mixer control element with the given name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619)  * @codec: HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620)  * @name: ctl id name string
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622)  * Get the control element with the given id string and IFACE_MIXER.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) 					    const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	return find_mixer_ctl(codec, name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) EXPORT_SYMBOL_GPL(snd_hda_find_mixer_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) static int find_empty_mixer_ctl_idx(struct hda_codec *codec, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 				    int start_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	int i, idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	/* 16 ctlrs should be large enough */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) 	for (i = 0, idx = start_idx; i < 16; i++, idx++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 		if (!find_mixer_ctl(codec, name, 0, idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) 			return idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) 	return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644)  * snd_hda_ctl_add - Add a control element and assign to the codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645)  * @codec: HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646)  * @nid: corresponding NID (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647)  * @kctl: the control element to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649)  * Add the given control element to an array inside the codec instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650)  * All control elements belonging to a codec are supposed to be added
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651)  * by this function so that a proper clean-up works at the free or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652)  * reconfiguration time.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654)  * If non-zero @nid is passed, the NID is assigned to the control element.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655)  * The assignment is shown in the codec proc file.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657)  * snd_hda_ctl_add() checks the control subdev id field whether
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658)  * #HDA_SUBDEV_NID_FLAG bit is set.  If set (and @nid is zero), the lower
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659)  * bits value is taken as the NID to assign. The #HDA_NID_ITEM_AMP bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660)  * specifies if kctl->private_value is a HDA amplifier value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) int snd_hda_ctl_add(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		    struct snd_kcontrol *kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 	unsigned short flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	struct hda_nid_item *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	if (kctl->id.subdevice & HDA_SUBDEV_AMP_FLAG) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 		flags |= HDA_NID_ITEM_AMP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 		if (nid == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 			nid = get_amp_nid_(kctl->private_value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	if ((kctl->id.subdevice & HDA_SUBDEV_NID_FLAG) != 0 && nid == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 		nid = kctl->id.subdevice & 0xffff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 	if (kctl->id.subdevice & (HDA_SUBDEV_NID_FLAG|HDA_SUBDEV_AMP_FLAG))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 		kctl->id.subdevice = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 	err = snd_ctl_add(codec->card, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) 	item = snd_array_new(&codec->mixers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 	if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684) 	item->kctl = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685) 	item->nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686) 	item->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689) EXPORT_SYMBOL_GPL(snd_hda_ctl_add);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692)  * snd_hda_add_nid - Assign a NID to a control element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693)  * @codec: HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694)  * @nid: corresponding NID (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695)  * @kctl: the control element to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696)  * @index: index to kctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698)  * Add the given control element to an array inside the codec instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)  * This function is used when #snd_hda_ctl_add cannot be used for 1:1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)  * NID:KCTL mapping - for example "Capture Source" selector.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702) int snd_hda_add_nid(struct hda_codec *codec, struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703) 		    unsigned int index, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705) 	struct hda_nid_item *item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) 	if (nid > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) 		item = snd_array_new(&codec->nids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 		if (!item)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) 		item->kctl = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 		item->index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) 		item->nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	codec_err(codec, "no NID for mapping control %s:%d:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 		  kctl->id.name, kctl->id.index, index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) EXPORT_SYMBOL_GPL(snd_hda_add_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723)  * snd_hda_ctls_clear - Clear all controls assigned to the given codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724)  * @codec: HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) void snd_hda_ctls_clear(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 	struct hda_nid_item *items = codec->mixers.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) 	down_write(&codec->card->controls_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 	for (i = 0; i < codec->mixers.used; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) 		snd_ctl_remove(codec->card, items[i].kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) 	up_write(&codec->card->controls_rwsem);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	snd_array_free(&codec->mixers);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 	snd_array_free(&codec->nids);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740)  * snd_hda_lock_devices - pseudo device locking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741)  * @bus: the BUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743)  * toggle card->shutdown to allow/disallow the device access (as a hack)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) int snd_hda_lock_devices(struct hda_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 	struct snd_card *card = bus->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) 	struct hda_codec *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	spin_lock(&card->files_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 	if (card->shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 		goto err_unlock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 	card->shutdown = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 	if (!list_empty(&card->ctl_files))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 		goto err_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 	list_for_each_codec(codec, bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) 		struct hda_pcm *cpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) 		list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) 			if (!cpcm->pcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1761) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1762) 			if (cpcm->pcm->streams[0].substream_opened ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1763) 			    cpcm->pcm->streams[1].substream_opened)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1764) 				goto err_clear;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1765) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1766) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1767) 	spin_unlock(&card->files_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1768) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1770)  err_clear:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1771) 	card->shutdown = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1772)  err_unlock:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1773) 	spin_unlock(&card->files_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1774) 	return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1775) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1776) EXPORT_SYMBOL_GPL(snd_hda_lock_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1777) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1778) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1779)  * snd_hda_unlock_devices - pseudo device unlocking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1780)  * @bus: the BUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1781)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1782) void snd_hda_unlock_devices(struct hda_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1783) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1784) 	struct snd_card *card = bus->card;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1785) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1786) 	spin_lock(&card->files_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1787) 	card->shutdown = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1788) 	spin_unlock(&card->files_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1789) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1790) EXPORT_SYMBOL_GPL(snd_hda_unlock_devices);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1792) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1793)  * snd_hda_codec_reset - Clear all objects assigned to the codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1794)  * @codec: HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1795)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1796)  * This frees the all PCM and control elements assigned to the codec, and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1797)  * clears the caches and restores the pin default configurations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1798)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1799)  * When a device is being used, it returns -EBSY.  If successfully freed,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1800)  * returns zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1801)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1802) int snd_hda_codec_reset(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1803) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1804) 	struct hda_bus *bus = codec->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1806) 	if (snd_hda_lock_devices(bus) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1807) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1809) 	/* OK, let it free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1810) 	device_release_driver(hda_codec_dev(codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1811) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1812) 	/* allow device access again */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1813) 	snd_hda_unlock_devices(bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1814) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1815) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1817) typedef int (*map_follower_func_t)(struct hda_codec *, void *, struct snd_kcontrol *);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1819) /* apply the function to all matching follower ctls in the mixer list */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1820) static int map_followers(struct hda_codec *codec, const char * const *followers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1821) 			 const char *suffix, map_follower_func_t func, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1822) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1823) 	struct hda_nid_item *items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1824) 	const char * const *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1825) 	int i, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1827) 	items = codec->mixers.list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1828) 	for (i = 0; i < codec->mixers.used; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1829) 		struct snd_kcontrol *sctl = items[i].kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1830) 		if (!sctl || sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1831) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1832) 		for (s = followers; *s; s++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1833) 			char tmpname[sizeof(sctl->id.name)];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1834) 			const char *name = *s;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1835) 			if (suffix) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1836) 				snprintf(tmpname, sizeof(tmpname), "%s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1837) 					 name, suffix);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1838) 				name = tmpname;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1839) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1840) 			if (!strcmp(sctl->id.name, name)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1841) 				err = func(codec, data, sctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1842) 				if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1843) 					return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1844) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1845) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1846) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1847) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1848) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1849) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1850) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1851) static int check_follower_present(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1852) 				  void *data, struct snd_kcontrol *sctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1853) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1854) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1855) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1857) /* call kctl->put with the given value(s) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1858) static int put_kctl_with_value(struct snd_kcontrol *kctl, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1859) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1860) 	struct snd_ctl_elem_value *ucontrol;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1861) 	ucontrol = kzalloc(sizeof(*ucontrol), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1862) 	if (!ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1863) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1864) 	ucontrol->value.integer.value[0] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1865) 	ucontrol->value.integer.value[1] = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1866) 	kctl->put(kctl, ucontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1867) 	kfree(ucontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1868) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1870) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1871) struct follower_init_arg {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1872) 	struct hda_codec *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1873) 	int step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1874) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1876) /* initialize the follower volume with 0dB via snd_ctl_apply_vmaster_followers() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1877) static int init_follower_0dB(struct snd_kcontrol *follower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1878) 			     struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1879) 			     void *_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1880) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1881) 	struct follower_init_arg *arg = _arg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1882) 	int _tlv[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1883) 	const int *tlv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1884) 	int step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1885) 	int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1887) 	if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_CALLBACK) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1888) 		if (kctl->tlv.c != snd_hda_mixer_amp_tlv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1889) 			codec_err(arg->codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1890) 				  "Unexpected TLV callback for follower %s:%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1891) 				  kctl->id.name, kctl->id.index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1892) 			return 0; /* ignore */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1893) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1894) 		get_ctl_amp_tlv(kctl, _tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1895) 		tlv = _tlv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1896) 	} else if (kctl->vd[0].access & SNDRV_CTL_ELEM_ACCESS_TLV_READ)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1897) 		tlv = kctl->tlv.p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1898) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1899) 	if (!tlv || tlv[SNDRV_CTL_TLVO_TYPE] != SNDRV_CTL_TLVT_DB_SCALE)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1900) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1901) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1902) 	step = tlv[SNDRV_CTL_TLVO_DB_SCALE_MUTE_AND_STEP];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1903) 	step &= ~TLV_DB_SCALE_MUTE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1904) 	if (!step)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1905) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1906) 	if (arg->step && arg->step != step) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1907) 		codec_err(arg->codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1908) 			  "Mismatching dB step for vmaster follower (%d!=%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1909) 			  arg->step, step);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1910) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1911) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1913) 	arg->step = step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1914) 	val = -tlv[SNDRV_CTL_TLVO_DB_SCALE_MIN] / step;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1915) 	if (val > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1916) 		put_kctl_with_value(follower, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1917) 		return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1918) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1919) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1920) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1921) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1922) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1923) /* unmute the follower via snd_ctl_apply_vmaster_followers() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1924) static int init_follower_unmute(struct snd_kcontrol *follower,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1925) 				struct snd_kcontrol *kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1926) 				void *_arg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1927) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1928) 	return put_kctl_with_value(follower, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1929) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1930) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1931) static int add_follower(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1932) 			void *data, struct snd_kcontrol *follower)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1933) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1934) 	return snd_ctl_add_follower(data, follower);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1935) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1937) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1938)  * __snd_hda_add_vmaster - create a virtual master control and add followers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1939)  * @codec: HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1940)  * @name: vmaster control name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1941)  * @tlv: TLV data (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1942)  * @followers: follower control names (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1943)  * @suffix: suffix string to each follower name (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1944)  * @init_follower_vol: initialize followers to unmute/0dB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1945)  * @ctl_ret: store the vmaster kcontrol in return
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1946)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1947)  * Create a virtual master control with the given name.  The TLV data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1948)  * must be either NULL or a valid data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1949)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1950)  * @followers is a NULL-terminated array of strings, each of which is a
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1951)  * follower control name.  All controls with these names are assigned to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1952)  * the new virtual master control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1953)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1954)  * This function returns zero if successful or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1955)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1956) int __snd_hda_add_vmaster(struct hda_codec *codec, char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1957) 			  unsigned int *tlv, const char * const *followers,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1958) 			  const char *suffix, bool init_follower_vol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1959) 			  struct snd_kcontrol **ctl_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1960) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1961) 	struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1962) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1964) 	if (ctl_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1965) 		*ctl_ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1966) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1967) 	err = map_followers(codec, followers, suffix, check_follower_present, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1968) 	if (err != 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1969) 		codec_dbg(codec, "No follower found for %s\n", name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1970) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1971) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1972) 	kctl = snd_ctl_make_virtual_master(name, tlv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1973) 	if (!kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1974) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1975) 	err = snd_hda_ctl_add(codec, 0, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1976) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1977) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1979) 	err = map_followers(codec, followers, suffix, add_follower, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1980) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1981) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1982) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1983) 	/* init with master mute & zero volume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1984) 	put_kctl_with_value(kctl, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1985) 	if (init_follower_vol) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1986) 		struct follower_init_arg arg = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1987) 			.codec = codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1988) 			.step = 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1989) 		};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1990) 		snd_ctl_apply_vmaster_followers(kctl,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1991) 						tlv ? init_follower_0dB : init_follower_unmute,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1992) 						&arg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1993) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1994) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1995) 	if (ctl_ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1996) 		*ctl_ret = kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1997) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1998) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1999) EXPORT_SYMBOL_GPL(__snd_hda_add_vmaster);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2000) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2001) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2002)  * mute-LED control using vmaster
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2003)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2004) static int vmaster_mute_mode_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2005) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2006) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2007) 	static const char * const texts[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2008) 		"On", "Off", "Follow Master"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2009) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2010) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2011) 	return snd_ctl_enum_info(uinfo, 1, 3, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2014) static int vmaster_mute_mode_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2015) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2017) 	struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2018) 	ucontrol->value.enumerated.item[0] = hook->mute_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2019) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2020) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2022) static int vmaster_mute_mode_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2023) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2025) 	struct hda_vmaster_mute_hook *hook = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2026) 	unsigned int old_mode = hook->mute_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2028) 	hook->mute_mode = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2029) 	if (hook->mute_mode > HDA_VMUTE_FOLLOW_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2030) 		hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2031) 	if (old_mode == hook->mute_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2032) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2033) 	snd_hda_sync_vmaster_hook(hook);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2034) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2035) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2037) static const struct snd_kcontrol_new vmaster_mute_mode = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2038) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2039) 	.name = "Mute-LED Mode",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2040) 	.info = vmaster_mute_mode_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2041) 	.get = vmaster_mute_mode_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2042) 	.put = vmaster_mute_mode_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2043) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2045) /* meta hook to call each driver's vmaster hook */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2046) static void vmaster_hook(void *private_data, int enabled)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2047) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2048) 	struct hda_vmaster_mute_hook *hook = private_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2049) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2050) 	if (hook->mute_mode != HDA_VMUTE_FOLLOW_MASTER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2051) 		enabled = hook->mute_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2052) 	hook->hook(hook->codec, enabled);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2053) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2054) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2055) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2056)  * snd_hda_add_vmaster_hook - Add a vmaster hook for mute-LED
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2057)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2058)  * @hook: the vmaster hook object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2059)  * @expose_enum_ctl: flag to create an enum ctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2060)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2061)  * Add a mute-LED hook with the given vmaster switch kctl.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2062)  * When @expose_enum_ctl is set, "Mute-LED Mode" control is automatically
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2063)  * created and associated with the given hook.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2064)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2065) int snd_hda_add_vmaster_hook(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2066) 			     struct hda_vmaster_mute_hook *hook,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2067) 			     bool expose_enum_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2068) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2069) 	struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2070) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2071) 	if (!hook->hook || !hook->sw_kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2072) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2073) 	hook->codec = codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2074) 	hook->mute_mode = HDA_VMUTE_FOLLOW_MASTER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2075) 	snd_ctl_add_vmaster_hook(hook->sw_kctl, vmaster_hook, hook);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2076) 	if (!expose_enum_ctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2077) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2078) 	kctl = snd_ctl_new1(&vmaster_mute_mode, hook);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2079) 	if (!kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2080) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2081) 	return snd_hda_ctl_add(codec, 0, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2082) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2083) EXPORT_SYMBOL_GPL(snd_hda_add_vmaster_hook);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2085) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2086)  * snd_hda_sync_vmaster_hook - Sync vmaster hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2087)  * @hook: the vmaster hook
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2088)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2089)  * Call the hook with the current value for synchronization.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2090)  * Should be called in init callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2091)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2092) void snd_hda_sync_vmaster_hook(struct hda_vmaster_mute_hook *hook)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2093) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2094) 	if (!hook->hook || !hook->codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2095) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2096) 	/* don't call vmaster hook in the destructor since it might have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2097) 	 * been already destroyed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2098) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2099) 	if (hook->codec->bus->shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2100) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2101) 	snd_ctl_sync_vmaster_hook(hook->sw_kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2102) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2103) EXPORT_SYMBOL_GPL(snd_hda_sync_vmaster_hook);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2105) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2106) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2107)  * snd_hda_mixer_amp_switch_info - Info callback for a standard AMP mixer switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2108)  * @kcontrol: referred ctl element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2109)  * @uinfo: pointer to get/store the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2110)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2111)  * The control element is supposed to have the private_value field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2112)  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2113)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2114) int snd_hda_mixer_amp_switch_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2115) 				  struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2116) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2117) 	int chs = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2118) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2119) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_BOOLEAN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2120) 	uinfo->count = chs == 3 ? 2 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2121) 	uinfo->value.integer.min = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2122) 	uinfo->value.integer.max = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2123) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2124) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2125) EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2127) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2128)  * snd_hda_mixer_amp_switch_get - Get callback for a standard AMP mixer switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2129)  * @kcontrol: ctl element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2130)  * @ucontrol: pointer to get/store the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2131)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2132)  * The control element is supposed to have the private_value field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2133)  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2134)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2135) int snd_hda_mixer_amp_switch_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2136) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2138) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2139) 	hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2140) 	int chs = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2141) 	int dir = get_amp_direction(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2142) 	int idx = get_amp_index(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2143) 	long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2145) 	if (chs & 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2146) 		*valp++ = (snd_hda_codec_amp_read(codec, nid, 0, dir, idx) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2147) 			   HDA_AMP_MUTE) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2148) 	if (chs & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2149) 		*valp = (snd_hda_codec_amp_read(codec, nid, 1, dir, idx) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2150) 			 HDA_AMP_MUTE) ? 0 : 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2151) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2153) EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_get);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2155) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2156)  * snd_hda_mixer_amp_switch_put - Put callback for a standard AMP mixer switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2157)  * @kcontrol: ctl element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2158)  * @ucontrol: pointer to get/store the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2159)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2160)  * The control element is supposed to have the private_value field
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2161)  * set up via HDA_COMPOSE_AMP_VAL*() or related macros.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2162)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2163) int snd_hda_mixer_amp_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2164) 				 struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2165) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2166) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2167) 	hda_nid_t nid = get_amp_nid(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2168) 	int chs = get_amp_channels(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2169) 	int dir = get_amp_direction(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2170) 	int idx = get_amp_index(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2171) 	long *valp = ucontrol->value.integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2172) 	int change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2173) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2174) 	if (chs & 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2175) 		change = snd_hda_codec_amp_update(codec, nid, 0, dir, idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2176) 						  HDA_AMP_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2177) 						  *valp ? 0 : HDA_AMP_MUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2178) 		valp++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2179) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2180) 	if (chs & 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2181) 		change |= snd_hda_codec_amp_update(codec, nid, 1, dir, idx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2182) 						   HDA_AMP_MUTE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2183) 						   *valp ? 0 : HDA_AMP_MUTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2184) 	hda_call_check_power_status(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2185) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2187) EXPORT_SYMBOL_GPL(snd_hda_mixer_amp_switch_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2188) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2189) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2190)  * SPDIF out controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2191)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2192) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2193) static int snd_hda_spdif_mask_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2194) 				   struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2195) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2196) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_IEC958;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2197) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2198) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2200) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2201) static int snd_hda_spdif_cmask_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2202) 				   struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2204) 	ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2205) 					   IEC958_AES0_NONAUDIO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2206) 					   IEC958_AES0_CON_EMPHASIS_5015 |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2207) 					   IEC958_AES0_CON_NOT_COPYRIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2208) 	ucontrol->value.iec958.status[1] = IEC958_AES1_CON_CATEGORY |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2209) 					   IEC958_AES1_CON_ORIGINAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2210) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2211) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2213) static int snd_hda_spdif_pmask_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2214) 				   struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2216) 	ucontrol->value.iec958.status[0] = IEC958_AES0_PROFESSIONAL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2217) 					   IEC958_AES0_NONAUDIO |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2218) 					   IEC958_AES0_PRO_EMPHASIS_5015;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2219) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2221) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2222) static int snd_hda_spdif_default_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2223) 				     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2225) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2226) 	int idx = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2227) 	struct hda_spdif_out *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2229) 	if (WARN_ON(codec->spdif_out.used <= idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2230) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2231) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2232) 	spdif = snd_array_elem(&codec->spdif_out, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2233) 	ucontrol->value.iec958.status[0] = spdif->status & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2234) 	ucontrol->value.iec958.status[1] = (spdif->status >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2235) 	ucontrol->value.iec958.status[2] = (spdif->status >> 16) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2236) 	ucontrol->value.iec958.status[3] = (spdif->status >> 24) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2237) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2239) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2241) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2242) /* convert from SPDIF status bits to HDA SPDIF bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2243)  * bit 0 (DigEn) is always set zero (to be filled later)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2244)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2245) static unsigned short convert_from_spdif_status(unsigned int sbits)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2246) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2247) 	unsigned short val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2248) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2249) 	if (sbits & IEC958_AES0_PROFESSIONAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2250) 		val |= AC_DIG1_PROFESSIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2251) 	if (sbits & IEC958_AES0_NONAUDIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2252) 		val |= AC_DIG1_NONAUDIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2253) 	if (sbits & IEC958_AES0_PROFESSIONAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2254) 		if ((sbits & IEC958_AES0_PRO_EMPHASIS) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2255) 		    IEC958_AES0_PRO_EMPHASIS_5015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2256) 			val |= AC_DIG1_EMPHASIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2257) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2258) 		if ((sbits & IEC958_AES0_CON_EMPHASIS) ==
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2259) 		    IEC958_AES0_CON_EMPHASIS_5015)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2260) 			val |= AC_DIG1_EMPHASIS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2261) 		if (!(sbits & IEC958_AES0_CON_NOT_COPYRIGHT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2262) 			val |= AC_DIG1_COPYRIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2263) 		if (sbits & (IEC958_AES1_CON_ORIGINAL << 8))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2264) 			val |= AC_DIG1_LEVEL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2265) 		val |= sbits & (IEC958_AES1_CON_CATEGORY << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2266) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2267) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2268) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2270) /* convert to SPDIF status bits from HDA SPDIF bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2271)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2272) static unsigned int convert_to_spdif_status(unsigned short val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2274) 	unsigned int sbits = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2276) 	if (val & AC_DIG1_NONAUDIO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2277) 		sbits |= IEC958_AES0_NONAUDIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2278) 	if (val & AC_DIG1_PROFESSIONAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2279) 		sbits |= IEC958_AES0_PROFESSIONAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2280) 	if (sbits & IEC958_AES0_PROFESSIONAL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2281) 		if (val & AC_DIG1_EMPHASIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2282) 			sbits |= IEC958_AES0_PRO_EMPHASIS_5015;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2283) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2284) 		if (val & AC_DIG1_EMPHASIS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2285) 			sbits |= IEC958_AES0_CON_EMPHASIS_5015;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2286) 		if (!(val & AC_DIG1_COPYRIGHT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2287) 			sbits |= IEC958_AES0_CON_NOT_COPYRIGHT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2288) 		if (val & AC_DIG1_LEVEL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2289) 			sbits |= (IEC958_AES1_CON_ORIGINAL << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2290) 		sbits |= val & (0x7f << 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2291) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2292) 	return sbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2295) /* set digital convert verbs both for the given NID and its followers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2296) static void set_dig_out(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2297) 			int mask, int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2298) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2299) 	const hda_nid_t *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2301) 	snd_hdac_regmap_update(&codec->core, nid, AC_VERB_SET_DIGI_CONVERT_1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2302) 			       mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2303) 	d = codec->follower_dig_outs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2304) 	if (!d)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2305) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2306) 	for (; *d; d++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2307) 		snd_hdac_regmap_update(&codec->core, *d,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2308) 				       AC_VERB_SET_DIGI_CONVERT_1, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2309) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2310) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2311) static inline void set_dig_out_convert(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2312) 				       int dig1, int dig2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2313) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2314) 	unsigned int mask = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2315) 	unsigned int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2317) 	if (dig1 != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2318) 		mask |= 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2319) 		val = dig1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2320) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2321) 	if (dig2 != -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2322) 		mask |= 0xff00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2323) 		val |= dig2 << 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2324) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2325) 	set_dig_out(codec, nid, mask, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2328) static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2329) 				     struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2331) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2332) 	int idx = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2333) 	struct hda_spdif_out *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2334) 	hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2335) 	unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2336) 	int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2337) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2338) 	if (WARN_ON(codec->spdif_out.used <= idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2339) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2340) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2341) 	spdif = snd_array_elem(&codec->spdif_out, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2342) 	nid = spdif->nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2343) 	spdif->status = ucontrol->value.iec958.status[0] |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2344) 		((unsigned int)ucontrol->value.iec958.status[1] << 8) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2345) 		((unsigned int)ucontrol->value.iec958.status[2] << 16) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2346) 		((unsigned int)ucontrol->value.iec958.status[3] << 24);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2347) 	val = convert_from_spdif_status(spdif->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2348) 	val |= spdif->ctls & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2349) 	change = spdif->ctls != val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2350) 	spdif->ctls = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2351) 	if (change && nid != (u16)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2352) 		set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2353) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2354) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2355) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2356) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2357) #define snd_hda_spdif_out_switch_info	snd_ctl_boolean_mono_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2359) static int snd_hda_spdif_out_switch_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2360) 					struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2361) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2362) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2363) 	int idx = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2364) 	struct hda_spdif_out *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2366) 	if (WARN_ON(codec->spdif_out.used <= idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2367) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2368) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2369) 	spdif = snd_array_elem(&codec->spdif_out, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2370) 	ucontrol->value.integer.value[0] = spdif->ctls & AC_DIG1_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2371) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2372) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2374) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2375) static inline void set_spdif_ctls(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2376) 				  int dig1, int dig2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2378) 	set_dig_out_convert(codec, nid, dig1, dig2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2379) 	/* unmute amp switch (if any) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2380) 	if ((get_wcaps(codec, nid) & AC_WCAP_OUT_AMP) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2381) 	    (dig1 & AC_DIG1_ENABLE))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2382) 		snd_hda_codec_amp_stereo(codec, nid, HDA_OUTPUT, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2383) 					    HDA_AMP_MUTE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2384) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2385) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2386) static int snd_hda_spdif_out_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2387) 					struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2388) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2389) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2390) 	int idx = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2391) 	struct hda_spdif_out *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2392) 	hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2393) 	unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2394) 	int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2395) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2396) 	if (WARN_ON(codec->spdif_out.used <= idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2397) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2398) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2399) 	spdif = snd_array_elem(&codec->spdif_out, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2400) 	nid = spdif->nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2401) 	val = spdif->ctls & ~AC_DIG1_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2402) 	if (ucontrol->value.integer.value[0])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2403) 		val |= AC_DIG1_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2404) 	change = spdif->ctls != val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2405) 	spdif->ctls = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2406) 	if (change && nid != (u16)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2407) 		set_spdif_ctls(codec, nid, val & 0xff, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2408) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2409) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2410) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2411) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2412) static const struct snd_kcontrol_new dig_mixes[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2413) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2414) 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2415) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2416) 		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, CON_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2417) 		.info = snd_hda_spdif_mask_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2418) 		.get = snd_hda_spdif_cmask_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2419) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2420) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2421) 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2422) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2423) 		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, PRO_MASK),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2424) 		.info = snd_hda_spdif_mask_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2425) 		.get = snd_hda_spdif_pmask_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2426) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2427) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2428) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2429) 		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2430) 		.info = snd_hda_spdif_mask_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2431) 		.get = snd_hda_spdif_default_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2432) 		.put = snd_hda_spdif_default_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2433) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2434) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2435) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2436) 		.name = SNDRV_CTL_NAME_IEC958("", PLAYBACK, SWITCH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2437) 		.info = snd_hda_spdif_out_switch_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2438) 		.get = snd_hda_spdif_out_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2439) 		.put = snd_hda_spdif_out_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2440) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2441) 	{ } /* end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2442) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2444) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2445)  * snd_hda_create_dig_out_ctls - create Output SPDIF-related controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2446)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2447)  * @associated_nid: NID that new ctls associated with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2448)  * @cvt_nid: converter NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2449)  * @type: HDA_PCM_TYPE_*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2450)  * Creates controls related with the digital output.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2451)  * Called from each patch supporting the digital out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2452)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2453)  * Returns 0 if successful, or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2454)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2455) int snd_hda_create_dig_out_ctls(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2456) 				hda_nid_t associated_nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2457) 				hda_nid_t cvt_nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2458) 				int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2459) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2460) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2461) 	struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2462) 	const struct snd_kcontrol_new *dig_mix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2463) 	int idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2464) 	int val = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2465) 	const int spdif_index = 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2466) 	struct hda_spdif_out *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2467) 	struct hda_bus *bus = codec->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2469) 	if (bus->primary_dig_out_type == HDA_PCM_TYPE_HDMI &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2470) 	    type == HDA_PCM_TYPE_SPDIF) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2471) 		idx = spdif_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2472) 	} else if (bus->primary_dig_out_type == HDA_PCM_TYPE_SPDIF &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2473) 		   type == HDA_PCM_TYPE_HDMI) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2474) 		/* suppose a single SPDIF device */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2475) 		for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2476) 			kctl = find_mixer_ctl(codec, dig_mix->name, 0, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2477) 			if (!kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2478) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2479) 			kctl->id.index = spdif_index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2480) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2481) 		bus->primary_dig_out_type = HDA_PCM_TYPE_HDMI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2482) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2483) 	if (!bus->primary_dig_out_type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2484) 		bus->primary_dig_out_type = type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2486) 	idx = find_empty_mixer_ctl_idx(codec, "IEC958 Playback Switch", idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2487) 	if (idx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2488) 		codec_err(codec, "too many IEC958 outputs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2489) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2490) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2491) 	spdif = snd_array_new(&codec->spdif_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2492) 	if (!spdif)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2493) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2494) 	for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2495) 		kctl = snd_ctl_new1(dig_mix, codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2496) 		if (!kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2497) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2498) 		kctl->id.index = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2499) 		kctl->private_value = codec->spdif_out.used - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2500) 		err = snd_hda_ctl_add(codec, associated_nid, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2501) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2502) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2503) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2504) 	spdif->nid = cvt_nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2505) 	snd_hdac_regmap_read(&codec->core, cvt_nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2506) 			     AC_VERB_GET_DIGI_CONVERT_1, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2507) 	spdif->ctls = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2508) 	spdif->status = convert_to_spdif_status(spdif->ctls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2509) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2510) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2511) EXPORT_SYMBOL_GPL(snd_hda_create_dig_out_ctls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2513) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2514)  * snd_hda_spdif_out_of_nid - get the hda_spdif_out entry from the given NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2515)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2516)  * @nid: widget NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2517)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2518)  * call within spdif_mutex lock
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2519)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2520) struct hda_spdif_out *snd_hda_spdif_out_of_nid(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2521) 					       hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2523) 	struct hda_spdif_out *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2524) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2525) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2526) 	snd_array_for_each(&codec->spdif_out, i, spdif) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2527) 		if (spdif->nid == nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2528) 			return spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2529) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2530) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2531) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2532) EXPORT_SYMBOL_GPL(snd_hda_spdif_out_of_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2533) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2534) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2535)  * snd_hda_spdif_ctls_unassign - Unassign the given SPDIF ctl
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2536)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2537)  * @idx: the SPDIF ctl index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2538)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2539)  * Unassign the widget from the given SPDIF control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2540)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2541) void snd_hda_spdif_ctls_unassign(struct hda_codec *codec, int idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2542) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2543) 	struct hda_spdif_out *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2544) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2545) 	if (WARN_ON(codec->spdif_out.used <= idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2546) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2547) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2548) 	spdif = snd_array_elem(&codec->spdif_out, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2549) 	spdif->nid = (u16)-1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2550) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2551) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2552) EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_unassign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2554) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2555)  * snd_hda_spdif_ctls_assign - Assign the SPDIF controls to the given NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2556)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2557)  * @idx: the SPDIF ctl idx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2558)  * @nid: widget NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2559)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2560)  * Assign the widget to the SPDIF control with the given index.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2561)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2562) void snd_hda_spdif_ctls_assign(struct hda_codec *codec, int idx, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2563) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2564) 	struct hda_spdif_out *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2565) 	unsigned short val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2566) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2567) 	if (WARN_ON(codec->spdif_out.used <= idx))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2568) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2569) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2570) 	spdif = snd_array_elem(&codec->spdif_out, idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2571) 	if (spdif->nid != nid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2572) 		spdif->nid = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2573) 		val = spdif->ctls;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2574) 		set_spdif_ctls(codec, nid, val & 0xff, (val >> 8) & 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2575) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2576) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2577) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2578) EXPORT_SYMBOL_GPL(snd_hda_spdif_ctls_assign);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2579) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2580) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2581)  * SPDIF sharing with analog output
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2582)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2583) static int spdif_share_sw_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2584) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2585) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2586) 	struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2587) 	ucontrol->value.integer.value[0] = mout->share_spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2588) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2589) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2590) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2591) static int spdif_share_sw_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2592) 			      struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2593) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2594) 	struct hda_multi_out *mout = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2595) 	mout->share_spdif = !!ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2596) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2597) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2598) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2599) static const struct snd_kcontrol_new spdif_share_sw = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2600) 	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2601) 	.name = "IEC958 Default PCM Playback Switch",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2602) 	.info = snd_ctl_boolean_mono_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2603) 	.get = spdif_share_sw_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2604) 	.put = spdif_share_sw_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2605) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2606) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2607) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2608)  * snd_hda_create_spdif_share_sw - create Default PCM switch
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2609)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2610)  * @mout: multi-out instance
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2611)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2612) int snd_hda_create_spdif_share_sw(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2613) 				  struct hda_multi_out *mout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2615) 	struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2616) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2617) 	if (!mout->dig_out_nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2618) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2620) 	kctl = snd_ctl_new1(&spdif_share_sw, mout);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2621) 	if (!kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2622) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2623) 	/* ATTENTION: here mout is passed as private_data, instead of codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2624) 	return snd_hda_ctl_add(codec, mout->dig_out_nid, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2626) EXPORT_SYMBOL_GPL(snd_hda_create_spdif_share_sw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2627) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2628) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2629)  * SPDIF input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2630)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2631) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2632) #define snd_hda_spdif_in_switch_info	snd_hda_spdif_out_switch_info
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2633) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2634) static int snd_hda_spdif_in_switch_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2635) 				       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2637) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2638) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2639) 	ucontrol->value.integer.value[0] = codec->spdif_in_enable;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2640) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2641) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2642) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2643) static int snd_hda_spdif_in_switch_put(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2644) 				       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2645) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2646) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2647) 	hda_nid_t nid = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2648) 	unsigned int val = !!ucontrol->value.integer.value[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2649) 	int change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2650) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2651) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2652) 	change = codec->spdif_in_enable != val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2653) 	if (change) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2654) 		codec->spdif_in_enable = val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2655) 		snd_hdac_regmap_write(&codec->core, nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2656) 				      AC_VERB_SET_DIGI_CONVERT_1, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2657) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2658) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2659) 	return change;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2660) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2662) static int snd_hda_spdif_in_status_get(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2663) 				       struct snd_ctl_elem_value *ucontrol)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2664) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2665) 	struct hda_codec *codec = snd_kcontrol_chip(kcontrol);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2666) 	hda_nid_t nid = kcontrol->private_value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2667) 	unsigned int val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2668) 	unsigned int sbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2669) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2670) 	snd_hdac_regmap_read(&codec->core, nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2671) 			     AC_VERB_GET_DIGI_CONVERT_1, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2672) 	sbits = convert_to_spdif_status(val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2673) 	ucontrol->value.iec958.status[0] = sbits;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2674) 	ucontrol->value.iec958.status[1] = sbits >> 8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2675) 	ucontrol->value.iec958.status[2] = sbits >> 16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2676) 	ucontrol->value.iec958.status[3] = sbits >> 24;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2677) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2680) static const struct snd_kcontrol_new dig_in_ctls[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2681) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2682) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2683) 		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, SWITCH),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2684) 		.info = snd_hda_spdif_in_switch_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2685) 		.get = snd_hda_spdif_in_switch_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2686) 		.put = snd_hda_spdif_in_switch_put,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2687) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2688) 	{
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2689) 		.access = SNDRV_CTL_ELEM_ACCESS_READ,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2690) 		.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2691) 		.name = SNDRV_CTL_NAME_IEC958("", CAPTURE, DEFAULT),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2692) 		.info = snd_hda_spdif_mask_info,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2693) 		.get = snd_hda_spdif_in_status_get,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2694) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2695) 	{ } /* end */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2696) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2698) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2699)  * snd_hda_create_spdif_in_ctls - create Input SPDIF-related controls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2700)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2701)  * @nid: audio in widget NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2702)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2703)  * Creates controls related with the SPDIF input.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2704)  * Called from each patch supporting the SPDIF in.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2705)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2706)  * Returns 0 if successful, or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2707)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2708) int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2709) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2710) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2711) 	struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2712) 	const struct snd_kcontrol_new *dig_mix;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2713) 	int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2714) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2715) 	idx = find_empty_mixer_ctl_idx(codec, "IEC958 Capture Switch", 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2716) 	if (idx < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2717) 		codec_err(codec, "too many IEC958 inputs\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2718) 		return -EBUSY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2719) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2720) 	for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2721) 		kctl = snd_ctl_new1(dig_mix, codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2722) 		if (!kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2723) 			return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2724) 		kctl->private_value = nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2725) 		err = snd_hda_ctl_add(codec, nid, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2726) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2727) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2728) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2729) 	codec->spdif_in_enable =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2730) 		snd_hda_codec_read(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2731) 				   AC_VERB_GET_DIGI_CONVERT_1, 0) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2732) 		AC_DIG1_ENABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2733) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2734) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2735) EXPORT_SYMBOL_GPL(snd_hda_create_spdif_in_ctls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2737) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2738)  * snd_hda_codec_set_power_to_all - Set the power state to all widgets
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2739)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2740)  * @fg: function group (not used now)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2741)  * @power_state: the power state to set (AC_PWRST_*)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2742)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2743)  * Set the given power state to all widgets that have the power control.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2744)  * If the codec has power_filter set, it evaluates the power state and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2745)  * filter out if it's unchanged as D3.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2746)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2747) void snd_hda_codec_set_power_to_all(struct hda_codec *codec, hda_nid_t fg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2748) 				    unsigned int power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2749) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2750) 	hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2752) 	for_each_hda_codec_node(nid, codec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2753) 		unsigned int wcaps = get_wcaps(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2754) 		unsigned int state = power_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2755) 		if (!(wcaps & AC_WCAP_POWER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2756) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2757) 		if (codec->power_filter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2758) 			state = codec->power_filter(codec, nid, power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2759) 			if (state != power_state && power_state == AC_PWRST_D3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2760) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2761) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2762) 		snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_POWER_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2763) 				    state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2764) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2765) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2766) EXPORT_SYMBOL_GPL(snd_hda_codec_set_power_to_all);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2768) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2769)  * snd_hda_codec_eapd_power_filter - A power filter callback for EAPD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2770)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2771)  * @nid: widget NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2772)  * @power_state: power state to evalue
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2773)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2774)  * Don't power down the widget if it controls eapd and EAPD_BTLENABLE is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2775)  * This can be used a codec power_filter callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2776)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2777) unsigned int snd_hda_codec_eapd_power_filter(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2778) 					     hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2779) 					     unsigned int power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2780) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2781) 	if (nid == codec->core.afg || nid == codec->core.mfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2782) 		return power_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2783) 	if (power_state == AC_PWRST_D3 &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2784) 	    get_wcaps_type(get_wcaps(codec, nid)) == AC_WID_PIN &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2785) 	    (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_EAPD)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2786) 		int eapd = snd_hda_codec_read(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2787) 					      AC_VERB_GET_EAPD_BTLENABLE, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2788) 		if (eapd & 0x02)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2789) 			return AC_PWRST_D0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2790) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2791) 	return power_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2792) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2793) EXPORT_SYMBOL_GPL(snd_hda_codec_eapd_power_filter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2794) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2795) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2796)  * set power state of the codec, and return the power state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2797)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2798) static unsigned int hda_set_power_state(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2799) 					unsigned int power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2801) 	hda_nid_t fg = codec->core.afg ? codec->core.afg : codec->core.mfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2802) 	int count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2803) 	unsigned int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2804) 	int flags = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2805) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2806) 	/* this delay seems necessary to avoid click noise at power-down */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2807) 	if (power_state == AC_PWRST_D3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2808) 		if (codec->depop_delay < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2809) 			msleep(codec_has_epss(codec) ? 10 : 100);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2810) 		else if (codec->depop_delay > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2811) 			msleep(codec->depop_delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2812) 		flags = HDA_RW_NO_RESPONSE_FALLBACK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2813) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2814) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2815) 	/* repeat power states setting at most 10 times*/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2816) 	for (count = 0; count < 10; count++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2817) 		if (codec->patch_ops.set_power_state)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2818) 			codec->patch_ops.set_power_state(codec, fg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2819) 							 power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2820) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2821) 			state = power_state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2822) 			if (codec->power_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2823) 				state = codec->power_filter(codec, fg, state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2824) 			if (state == power_state || power_state != AC_PWRST_D3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2825) 				snd_hda_codec_read(codec, fg, flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2826) 						   AC_VERB_SET_POWER_STATE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2827) 						   state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2828) 			snd_hda_codec_set_power_to_all(codec, fg, power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2829) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2830) 		state = snd_hda_sync_power_state(codec, fg, power_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2831) 		if (!(state & AC_PWRST_ERROR))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2832) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2833) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2834) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2835) 	return state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2836) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2837) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2838) /* sync power states of all widgets;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2839)  * this is called at the end of codec parsing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2840)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2841) static void sync_power_up_states(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2843) 	hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2845) 	/* don't care if no filter is used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2846) 	if (!codec->power_filter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2847) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2849) 	for_each_hda_codec_node(nid, codec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2850) 		unsigned int wcaps = get_wcaps(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2851) 		unsigned int target;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2852) 		if (!(wcaps & AC_WCAP_POWER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2853) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2854) 		target = codec->power_filter(codec, nid, AC_PWRST_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2855) 		if (target == AC_PWRST_D0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2856) 			continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2857) 		if (!snd_hda_check_power_state(codec, nid, target))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2858) 			snd_hda_codec_write(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2859) 					    AC_VERB_SET_POWER_STATE, target);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2860) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2862) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2863) #ifdef CONFIG_SND_HDA_RECONFIG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2864) /* execute additional init verbs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2865) static void hda_exec_init_verbs(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2866) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2867) 	if (codec->init_verbs.list)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2868) 		snd_hda_sequence_write(codec, codec->init_verbs.list);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2870) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2871) static inline void hda_exec_init_verbs(struct hda_codec *codec) {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2872) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2873) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2874) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2875) /* update the power on/off account with the current jiffies */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2876) static void update_power_acct(struct hda_codec *codec, bool on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2877) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2878) 	unsigned long delta = jiffies - codec->power_jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2880) 	if (on)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2881) 		codec->power_on_acct += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2882) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2883) 		codec->power_off_acct += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2884) 	codec->power_jiffies += delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2885) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2886) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2887) void snd_hda_update_power_acct(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2888) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2889) 	update_power_acct(codec, hda_codec_is_power_on(codec));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2890) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2891) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2892) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2893)  * call suspend and power-down; used both from PM and power-save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2894)  * this function returns the power state in the end
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2895)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2896) static unsigned int hda_call_codec_suspend(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2897) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2898) 	unsigned int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2900) 	snd_hdac_enter_pm(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2901) 	if (codec->patch_ops.suspend)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2902) 		codec->patch_ops.suspend(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2903) 	hda_cleanup_all_streams(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2904) 	state = hda_set_power_state(codec, AC_PWRST_D3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2905) 	update_power_acct(codec, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2906) 	snd_hdac_leave_pm(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2907) 	return state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2908) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2910) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2911)  * kick up codec; used both from PM and power-save
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2912)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2913) static void hda_call_codec_resume(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2914) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2915) 	snd_hdac_enter_pm(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2916) 	if (codec->core.regmap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2917) 		regcache_mark_dirty(codec->core.regmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2919) 	codec->power_jiffies = jiffies;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2921) 	hda_set_power_state(codec, AC_PWRST_D0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2922) 	restore_shutup_pins(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2923) 	hda_exec_init_verbs(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2924) 	snd_hda_jack_set_dirty_all(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2925) 	if (codec->patch_ops.resume)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2926) 		codec->patch_ops.resume(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2927) 	else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2928) 		if (codec->patch_ops.init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2929) 			codec->patch_ops.init(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2930) 		snd_hda_regmap_sync(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2931) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2932) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2933) 	if (codec->jackpoll_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2934) 		hda_jackpoll_work(&codec->jackpoll_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2935) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2936) 		snd_hda_jack_report_sync(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2937) 	codec->core.dev.power.power_state = PMSG_ON;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2938) 	snd_hdac_leave_pm(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2941) static int hda_codec_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2942) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2943) 	struct hda_codec *codec = dev_to_hda_codec(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2944) 	unsigned int state;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2945) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2946) 	/* Nothing to do if card registration fails and the component driver never probes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2947) 	if (!codec->card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2948) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2950) 	cancel_delayed_work_sync(&codec->jackpoll_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2951) 	state = hda_call_codec_suspend(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2952) 	if (codec->link_down_at_suspend ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2953) 	    (codec_has_clkstop(codec) && codec_has_epss(codec) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2954) 	     (state & AC_PWRST_CLK_STOP_OK)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2955) 		snd_hdac_codec_link_down(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2956) 	codec_display_power(codec, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2957) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2958) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2959) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2960) static int hda_codec_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2961) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2962) 	struct hda_codec *codec = dev_to_hda_codec(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2963) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2964) 	/* Nothing to do if card registration fails and the component driver never probes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2965) 	if (!codec->card)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2966) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2968) 	codec_display_power(codec, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2969) 	snd_hdac_codec_link_up(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2970) 	hda_call_codec_resume(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2971) 	pm_runtime_mark_last_busy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2972) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2973) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2975) #endif /* CONFIG_PM */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2976) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2977) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2978) static int hda_codec_pm_prepare(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2979) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2980) 	dev->power.power_state = PMSG_SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2981) 	return pm_runtime_suspended(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2982) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2983) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2984) static void hda_codec_pm_complete(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2985) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2986) 	struct hda_codec *codec = dev_to_hda_codec(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2988) 	/* If no other pm-functions are called between prepare() and complete() */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2989) 	if (dev->power.power_state.event == PM_EVENT_SUSPEND)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2990) 		dev->power.power_state = PMSG_RESUME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2992) 	if (pm_runtime_suspended(dev) && (codec->jackpoll_interval ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2993) 	    hda_codec_need_resume(codec) || codec->forced_resume))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2994) 		pm_request_resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2995) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2996) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2997) static int hda_codec_pm_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2998) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2999) 	dev->power.power_state = PMSG_SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3000) 	return pm_runtime_force_suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3001) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3002) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3003) static int hda_codec_pm_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3004) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3005) 	dev->power.power_state = PMSG_RESUME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3006) 	return pm_runtime_force_resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3007) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3008) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3009) static int hda_codec_pm_freeze(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3010) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3011) 	dev->power.power_state = PMSG_FREEZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3012) 	return pm_runtime_force_suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3013) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3014) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3015) static int hda_codec_pm_thaw(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3016) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3017) 	dev->power.power_state = PMSG_THAW;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3018) 	return pm_runtime_force_resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3021) static int hda_codec_pm_restore(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3023) 	dev->power.power_state = PMSG_RESTORE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3024) 	return pm_runtime_force_resume(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3025) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3026) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3028) /* referred in hda_bind.c */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3029) const struct dev_pm_ops hda_codec_driver_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3030) #ifdef CONFIG_PM_SLEEP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3031) 	.prepare = hda_codec_pm_prepare,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3032) 	.complete = hda_codec_pm_complete,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3033) 	.suspend = hda_codec_pm_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3034) 	.resume = hda_codec_pm_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3035) 	.freeze = hda_codec_pm_freeze,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3036) 	.thaw = hda_codec_pm_thaw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3037) 	.poweroff = hda_codec_pm_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3038) 	.restore = hda_codec_pm_restore,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3039) #endif /* CONFIG_PM_SLEEP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3040) 	SET_RUNTIME_PM_OPS(hda_codec_runtime_suspend, hda_codec_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3041) 			   NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3042) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3043) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3044) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3045)  * add standard channel maps if not specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3046)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3047) static int add_std_chmaps(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3048) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3049) 	struct hda_pcm *pcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3050) 	int str, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3051) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3052) 	list_for_each_entry(pcm, &codec->pcm_list_head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3053) 		for (str = 0; str < 2; str++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3054) 			struct hda_pcm_stream *hinfo = &pcm->stream[str];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3055) 			struct snd_pcm_chmap *chmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3056) 			const struct snd_pcm_chmap_elem *elem;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3057) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3058) 			if (!pcm->pcm || pcm->own_chmap || !hinfo->substreams)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3059) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3060) 			elem = hinfo->chmap ? hinfo->chmap : snd_pcm_std_chmaps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3061) 			err = snd_pcm_add_chmap_ctls(pcm->pcm, str, elem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3062) 						     hinfo->channels_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3063) 						     0, &chmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3064) 			if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3065) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3066) 			chmap->channel_mask = SND_PCM_CHMAP_MASK_2468;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3067) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3068) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3069) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3070) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3071) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3072) /* default channel maps for 2.1 speakers;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3073)  * since HD-audio supports only stereo, odd number channels are omitted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3074)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3075) const struct snd_pcm_chmap_elem snd_pcm_2_1_chmaps[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3076) 	{ .channels = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3077) 	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3078) 	{ .channels = 4,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3079) 	  .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3080) 		   SNDRV_CHMAP_LFE, SNDRV_CHMAP_LFE } },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3081) 	{ }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3082) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3083) EXPORT_SYMBOL_GPL(snd_pcm_2_1_chmaps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3084) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3085) int snd_hda_codec_build_controls(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3086) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3087) 	int err = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3088) 	hda_exec_init_verbs(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3089) 	/* continue to initialize... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3090) 	if (codec->patch_ops.init)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3091) 		err = codec->patch_ops.init(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3092) 	if (!err && codec->patch_ops.build_controls)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3093) 		err = codec->patch_ops.build_controls(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3094) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3095) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3096) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3097) 	/* we create chmaps here instead of build_pcms */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3098) 	err = add_std_chmaps(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3099) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3100) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3102) 	if (codec->jackpoll_interval)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3103) 		hda_jackpoll_work(&codec->jackpoll_work.work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3104) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3105) 		snd_hda_jack_report_sync(codec); /* call at the last init point */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3106) 	sync_power_up_states(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3107) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3108) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3109) EXPORT_SYMBOL_GPL(snd_hda_codec_build_controls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3111) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3112)  * PCM stuff
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3113)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3114) static int hda_pcm_default_open_close(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3115) 				      struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3116) 				      struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3117) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3118) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3119) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3121) static int hda_pcm_default_prepare(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3122) 				   struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3123) 				   unsigned int stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3124) 				   unsigned int format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3125) 				   struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3126) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3127) 	snd_hda_codec_setup_stream(codec, hinfo->nid, stream_tag, 0, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3128) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3130) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3131) static int hda_pcm_default_cleanup(struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3132) 				   struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3133) 				   struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3134) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3135) 	snd_hda_codec_cleanup_stream(codec, hinfo->nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3136) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3138) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3139) static int set_pcm_default_values(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3140) 				  struct hda_pcm_stream *info)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3141) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3142) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3143) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3144) 	/* query support PCM information from the given NID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3145) 	if (info->nid && (!info->rates || !info->formats)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3146) 		err = snd_hda_query_supported_pcm(codec, info->nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3147) 				info->rates ? NULL : &info->rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3148) 				info->formats ? NULL : &info->formats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3149) 				info->maxbps ? NULL : &info->maxbps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3150) 		if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3151) 			return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3152) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3153) 	if (info->ops.open == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3154) 		info->ops.open = hda_pcm_default_open_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3155) 	if (info->ops.close == NULL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3156) 		info->ops.close = hda_pcm_default_open_close;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3157) 	if (info->ops.prepare == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3158) 		if (snd_BUG_ON(!info->nid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3159) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3160) 		info->ops.prepare = hda_pcm_default_prepare;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3162) 	if (info->ops.cleanup == NULL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3163) 		if (snd_BUG_ON(!info->nid))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3164) 			return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3165) 		info->ops.cleanup = hda_pcm_default_cleanup;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3166) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3167) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3170) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3171)  * codec prepare/cleanup entries
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3172)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3173) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3174)  * snd_hda_codec_prepare - Prepare a stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3175)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3176)  * @hinfo: PCM information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3177)  * @stream: stream tag to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3178)  * @format: format id to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3179)  * @substream: PCM substream to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3180)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3181)  * Calls the prepare callback set by the codec with the given arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3182)  * Clean up the inactive streams when successful.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3183)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3184) int snd_hda_codec_prepare(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3185) 			  struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3186) 			  unsigned int stream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3187) 			  unsigned int format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3188) 			  struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3189) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3190) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3191) 	mutex_lock(&codec->bus->prepare_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3192) 	if (hinfo->ops.prepare)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3193) 		ret = hinfo->ops.prepare(hinfo, codec, stream, format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3194) 					 substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3195) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3196) 		ret = -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3197) 	if (ret >= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3198) 		purify_inactive_streams(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3199) 	mutex_unlock(&codec->bus->prepare_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3200) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3201) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3202) EXPORT_SYMBOL_GPL(snd_hda_codec_prepare);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3203) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3204) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3205)  * snd_hda_codec_cleanup - Clean up stream resources
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3206)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3207)  * @hinfo: PCM information
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3208)  * @substream: PCM substream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3209)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3210)  * Calls the cleanup callback set by the codec with the given arguments.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3211)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3212) void snd_hda_codec_cleanup(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3213) 			   struct hda_pcm_stream *hinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3214) 			   struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3215) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3216) 	mutex_lock(&codec->bus->prepare_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3217) 	if (hinfo->ops.cleanup)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3218) 		hinfo->ops.cleanup(hinfo, codec, substream);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3219) 	mutex_unlock(&codec->bus->prepare_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3220) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3221) EXPORT_SYMBOL_GPL(snd_hda_codec_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3223) /* global */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3224) const char *snd_hda_pcm_type_name[HDA_PCM_NTYPES] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3225) 	"Audio", "SPDIF", "HDMI", "Modem"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3226) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3228) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3229)  * get the empty PCM device number to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3230)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3231) static int get_empty_pcm_device(struct hda_bus *bus, unsigned int type)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3232) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3233) 	/* audio device indices; not linear to keep compatibility */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3234) 	/* assigned to static slots up to dev#10; if more needed, assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3235) 	 * the later slot dynamically (when CONFIG_SND_DYNAMIC_MINORS=y)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3236) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3237) 	static const int audio_idx[HDA_PCM_NTYPES][5] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3238) 		[HDA_PCM_TYPE_AUDIO] = { 0, 2, 4, 5, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3239) 		[HDA_PCM_TYPE_SPDIF] = { 1, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3240) 		[HDA_PCM_TYPE_HDMI]  = { 3, 7, 8, 9, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3241) 		[HDA_PCM_TYPE_MODEM] = { 6, -1 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3242) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3243) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3245) 	if (type >= HDA_PCM_NTYPES) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3246) 		dev_err(bus->card->dev, "Invalid PCM type %d\n", type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3247) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3248) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3250) 	for (i = 0; audio_idx[type][i] >= 0; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3251) #ifndef CONFIG_SND_DYNAMIC_MINORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3252) 		if (audio_idx[type][i] >= 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3253) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3254) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3255) 		if (!test_and_set_bit(audio_idx[type][i], bus->pcm_dev_bits))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3256) 			return audio_idx[type][i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3257) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3258) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3259) #ifdef CONFIG_SND_DYNAMIC_MINORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3260) 	/* non-fixed slots starting from 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3261) 	for (i = 10; i < 32; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3262) 		if (!test_and_set_bit(i, bus->pcm_dev_bits))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3263) 			return i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3264) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3265) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3267) 	dev_warn(bus->card->dev, "Too many %s devices\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3268) 		snd_hda_pcm_type_name[type]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3269) #ifndef CONFIG_SND_DYNAMIC_MINORS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3270) 	dev_warn(bus->card->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3271) 		 "Consider building the kernel with CONFIG_SND_DYNAMIC_MINORS=y\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3272) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3273) 	return -EAGAIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3274) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3276) /* call build_pcms ops of the given codec and set up the default parameters */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3277) int snd_hda_codec_parse_pcms(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3279) 	struct hda_pcm *cpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3280) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3281) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3282) 	if (!list_empty(&codec->pcm_list_head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3283) 		return 0; /* already parsed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3285) 	if (!codec->patch_ops.build_pcms)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3286) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3287) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3288) 	err = codec->patch_ops.build_pcms(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3289) 	if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3290) 		codec_err(codec, "cannot build PCMs for #%d (error %d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3291) 			  codec->core.addr, err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3292) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3293) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3294) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3295) 	list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3296) 		int stream;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3297) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3298) 		for (stream = 0; stream < 2; stream++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3299) 			struct hda_pcm_stream *info = &cpcm->stream[stream];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3300) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3301) 			if (!info->substreams)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3302) 				continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3303) 			err = set_pcm_default_values(codec, info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3304) 			if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3305) 				codec_warn(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3306) 					   "fail to setup default for PCM %s\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3307) 					   cpcm->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3308) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3309) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3310) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3311) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3313) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3314) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3315) EXPORT_SYMBOL_GPL(snd_hda_codec_parse_pcms);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3316) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3317) /* assign all PCMs of the given codec */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3318) int snd_hda_codec_build_pcms(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3319) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3320) 	struct hda_bus *bus = codec->bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3321) 	struct hda_pcm *cpcm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3322) 	int dev, err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3324) 	err = snd_hda_codec_parse_pcms(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3325) 	if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3326) 		return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3328) 	/* attach a new PCM streams */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3329) 	list_for_each_entry(cpcm, &codec->pcm_list_head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3330) 		if (cpcm->pcm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3331) 			continue; /* already attached */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3332) 		if (!cpcm->stream[0].substreams && !cpcm->stream[1].substreams)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3333) 			continue; /* no substreams assigned */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3334) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3335) 		dev = get_empty_pcm_device(bus, cpcm->pcm_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3336) 		if (dev < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3337) 			cpcm->device = SNDRV_PCM_INVALID_DEVICE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3338) 			continue; /* no fatal error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3339) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3340) 		cpcm->device = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3341) 		err =  snd_hda_attach_pcm_stream(bus, codec, cpcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3342) 		if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3343) 			codec_err(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3344) 				  "cannot attach PCM stream %d for codec #%d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3345) 				  dev, codec->core.addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3346) 			continue; /* no fatal error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3347) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3348) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3350) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3351) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3353) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3354)  * snd_hda_add_new_ctls - create controls from the array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3355)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3356)  * @knew: the array of struct snd_kcontrol_new
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3357)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3358)  * This helper function creates and add new controls in the given array.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3359)  * The array must be terminated with an empty entry as terminator.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3360)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3361)  * Returns 0 if successful, or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3362)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3363) int snd_hda_add_new_ctls(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3364) 			 const struct snd_kcontrol_new *knew)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3366) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3367) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3368) 	for (; knew->name; knew++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3369) 		struct snd_kcontrol *kctl;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3370) 		int addr = 0, idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3371) 		if (knew->iface == (__force snd_ctl_elem_iface_t)-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3372) 			continue; /* skip this codec private value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3373) 		for (;;) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3374) 			kctl = snd_ctl_new1(knew, codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3375) 			if (!kctl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3376) 				return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3377) 			if (addr > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3378) 				kctl->id.device = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3379) 			if (idx > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3380) 				kctl->id.index = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3381) 			err = snd_hda_ctl_add(codec, 0, kctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3382) 			if (!err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3383) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3384) 			/* try first with another device index corresponding to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3385) 			 * the codec addr; if it still fails (or it's the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3386) 			 * primary codec), then try another control index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3387) 			 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3388) 			if (!addr && codec->core.addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3389) 				addr = codec->core.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3390) 			else if (!idx && !knew->index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3391) 				idx = find_empty_mixer_ctl_idx(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3392) 							       knew->name, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3393) 				if (idx <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3394) 					return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3395) 			} else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3396) 				return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3397) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3398) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3399) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3400) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3401) EXPORT_SYMBOL_GPL(snd_hda_add_new_ctls);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3402) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3403) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3404) static void codec_set_power_save(struct hda_codec *codec, int delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3405) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3406) 	struct device *dev = hda_codec_dev(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3408) 	if (delay == 0 && codec->auto_runtime_pm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3409) 		delay = 3000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3410) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3411) 	if (delay > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3412) 		pm_runtime_set_autosuspend_delay(dev, delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3413) 		pm_runtime_use_autosuspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3414) 		pm_runtime_allow(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3415) 		if (!pm_runtime_suspended(dev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3416) 			pm_runtime_mark_last_busy(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3417) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3418) 		pm_runtime_dont_use_autosuspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3419) 		pm_runtime_forbid(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3420) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3422) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3423) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3424)  * snd_hda_set_power_save - reprogram autosuspend for the given delay
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3425)  * @bus: HD-audio bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3426)  * @delay: autosuspend delay in msec, 0 = off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3427)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3428)  * Synchronize the runtime PM autosuspend state from the power_save option.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3429)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3430) void snd_hda_set_power_save(struct hda_bus *bus, int delay)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3431) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3432) 	struct hda_codec *c;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3433) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3434) 	list_for_each_codec(c, bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3435) 		codec_set_power_save(c, delay);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3436) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3437) EXPORT_SYMBOL_GPL(snd_hda_set_power_save);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3438) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3439) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3440)  * snd_hda_check_amp_list_power - Check the amp list and update the power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3441)  * @codec: HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3442)  * @check: the object containing an AMP list and the status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3443)  * @nid: NID to check / update
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3444)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3445)  * Check whether the given NID is in the amp list.  If it's in the list,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3446)  * check the current AMP status, and update the power-status according
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3447)  * to the mute status.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3448)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3449)  * This function is supposed to be set or called from the check_power_status
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3450)  * patch ops.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3451)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3452) int snd_hda_check_amp_list_power(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3453) 				 struct hda_loopback_check *check,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3454) 				 hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3455) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3456) 	const struct hda_amp_list *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3457) 	int ch, v;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3459) 	if (!check->amplist)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3460) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3461) 	for (p = check->amplist; p->nid; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3462) 		if (p->nid == nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3463) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3464) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3465) 	if (!p->nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3466) 		return 0; /* nothing changed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3468) 	for (p = check->amplist; p->nid; p++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3469) 		for (ch = 0; ch < 2; ch++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3470) 			v = snd_hda_codec_amp_read(codec, p->nid, ch, p->dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3471) 						   p->idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3472) 			if (!(v & HDA_AMP_MUTE) && v > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3473) 				if (!check->power_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3474) 					check->power_on = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3475) 					snd_hda_power_up_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3476) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3477) 				return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3478) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3479) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3480) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3481) 	if (check->power_on) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3482) 		check->power_on = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3483) 		snd_hda_power_down_pm(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3484) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3485) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3486) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3487) EXPORT_SYMBOL_GPL(snd_hda_check_amp_list_power);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3488) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3489) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3490) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3491)  * input MUX helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3492)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3493) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3494) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3495)  * snd_hda_input_mux_info_info - Info callback helper for the input-mux enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3496)  * @imux: imux helper object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3497)  * @uinfo: pointer to get/store the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3498)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3499) int snd_hda_input_mux_info(const struct hda_input_mux *imux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3500) 			   struct snd_ctl_elem_info *uinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3501) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3502) 	unsigned int index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3503) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3504) 	uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3505) 	uinfo->count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3506) 	uinfo->value.enumerated.items = imux->num_items;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3507) 	if (!imux->num_items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3508) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3509) 	index = uinfo->value.enumerated.item;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3510) 	if (index >= imux->num_items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3511) 		index = imux->num_items - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3512) 	strcpy(uinfo->value.enumerated.name, imux->items[index].label);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3513) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3515) EXPORT_SYMBOL_GPL(snd_hda_input_mux_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3516) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3517) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3518)  * snd_hda_input_mux_info_put - Put callback helper for the input-mux enum
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3519)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3520)  * @imux: imux helper object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3521)  * @ucontrol: pointer to get/store the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3522)  * @nid: input mux NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3523)  * @cur_val: pointer to get/store the current imux value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3524)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3525) int snd_hda_input_mux_put(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3526) 			  const struct hda_input_mux *imux,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3527) 			  struct snd_ctl_elem_value *ucontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3528) 			  hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3529) 			  unsigned int *cur_val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3530) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3531) 	unsigned int idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3532) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3533) 	if (!imux->num_items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3534) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3535) 	idx = ucontrol->value.enumerated.item[0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3536) 	if (idx >= imux->num_items)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3537) 		idx = imux->num_items - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3538) 	if (*cur_val == idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3539) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3540) 	snd_hda_codec_write_cache(codec, nid, 0, AC_VERB_SET_CONNECT_SEL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3541) 				  imux->items[idx].index);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3542) 	*cur_val = idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3543) 	return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3544) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3545) EXPORT_SYMBOL_GPL(snd_hda_input_mux_put);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3546) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3548) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3549)  * snd_hda_enum_helper_info - Helper for simple enum ctls
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3550)  * @kcontrol: ctl element
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3551)  * @uinfo: pointer to get/store the data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3552)  * @num_items: number of enum items
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3553)  * @texts: enum item string array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3554)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3555)  * process kcontrol info callback of a simple string enum array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3556)  * when @num_items is 0 or @texts is NULL, assume a boolean enum array
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3557)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3558) int snd_hda_enum_helper_info(struct snd_kcontrol *kcontrol,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3559) 			     struct snd_ctl_elem_info *uinfo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3560) 			     int num_items, const char * const *texts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3561) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3562) 	static const char * const texts_default[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3563) 		"Disabled", "Enabled"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3564) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3565) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3566) 	if (!texts || !num_items) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3567) 		num_items = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3568) 		texts = texts_default;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3569) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3570) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3571) 	return snd_ctl_enum_info(uinfo, 1, num_items, texts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3573) EXPORT_SYMBOL_GPL(snd_hda_enum_helper_info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3575) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3576)  * Multi-channel / digital-out PCM helper functions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3577)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3578) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3579) /* setup SPDIF output stream */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3580) static void setup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3581) 				 unsigned int stream_tag, unsigned int format)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3582) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3583) 	struct hda_spdif_out *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3584) 	unsigned int curr_fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3585) 	bool reset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3587) 	spdif = snd_hda_spdif_out_of_nid(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3588) 	/* Add sanity check to pass klockwork check.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3589) 	 * This should never happen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3590) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3591) 	if (WARN_ON(spdif == NULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3592) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3593) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3594) 	curr_fmt = snd_hda_codec_read(codec, nid, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3595) 				      AC_VERB_GET_STREAM_FORMAT, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3596) 	reset = codec->spdif_status_reset &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3597) 		(spdif->ctls & AC_DIG1_ENABLE) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3598) 		curr_fmt != format;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3600) 	/* turn off SPDIF if needed; otherwise the IEC958 bits won't be
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3601) 	   updated */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3602) 	if (reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3603) 		set_dig_out_convert(codec, nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3604) 				    spdif->ctls & ~AC_DIG1_ENABLE & 0xff,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3605) 				    -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3606) 	snd_hda_codec_setup_stream(codec, nid, stream_tag, 0, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3607) 	if (codec->follower_dig_outs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3608) 		const hda_nid_t *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3609) 		for (d = codec->follower_dig_outs; *d; d++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3610) 			snd_hda_codec_setup_stream(codec, *d, stream_tag, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3611) 						   format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3612) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3613) 	/* turn on again (if needed) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3614) 	if (reset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3615) 		set_dig_out_convert(codec, nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3616) 				    spdif->ctls & 0xff, -1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3618) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3619) static void cleanup_dig_out_stream(struct hda_codec *codec, hda_nid_t nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3620) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3621) 	snd_hda_codec_cleanup_stream(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3622) 	if (codec->follower_dig_outs) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3623) 		const hda_nid_t *d;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3624) 		for (d = codec->follower_dig_outs; *d; d++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3625) 			snd_hda_codec_cleanup_stream(codec, *d);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3626) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3627) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3628) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3629) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3630)  * snd_hda_multi_out_dig_open - open the digital out in the exclusive mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3631)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3632)  * @mout: hda_multi_out object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3633)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3634) int snd_hda_multi_out_dig_open(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3635) 			       struct hda_multi_out *mout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3636) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3637) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3638) 	if (mout->dig_out_used == HDA_DIG_ANALOG_DUP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3639) 		/* already opened as analog dup; reset it once */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3640) 		cleanup_dig_out_stream(codec, mout->dig_out_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3641) 	mout->dig_out_used = HDA_DIG_EXCLUSIVE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3642) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3643) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3644) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3645) EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3646) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3647) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3648)  * snd_hda_multi_out_dig_prepare - prepare the digital out stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3649)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3650)  * @mout: hda_multi_out object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3651)  * @stream_tag: stream tag to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3652)  * @format: format id to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3653)  * @substream: PCM substream to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3654)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3655) int snd_hda_multi_out_dig_prepare(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3656) 				  struct hda_multi_out *mout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3657) 				  unsigned int stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3658) 				  unsigned int format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3659) 				  struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3660) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3661) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3662) 	setup_dig_out_stream(codec, mout->dig_out_nid, stream_tag, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3663) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3664) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3666) EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_prepare);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3667) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3668) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3669)  * snd_hda_multi_out_dig_cleanup - clean-up the digital out stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3670)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3671)  * @mout: hda_multi_out object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3672)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3673) int snd_hda_multi_out_dig_cleanup(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3674) 				  struct hda_multi_out *mout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3675) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3676) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3677) 	cleanup_dig_out_stream(codec, mout->dig_out_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3678) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3679) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3680) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3681) EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3683) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3684)  * snd_hda_multi_out_dig_close - release the digital out stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3685)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3686)  * @mout: hda_multi_out object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3687)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3688) int snd_hda_multi_out_dig_close(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3689) 				struct hda_multi_out *mout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3690) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3691) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3692) 	mout->dig_out_used = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3693) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3694) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3696) EXPORT_SYMBOL_GPL(snd_hda_multi_out_dig_close);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3698) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3699)  * snd_hda_multi_out_analog_open - open analog outputs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3700)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3701)  * @mout: hda_multi_out object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3702)  * @substream: PCM substream to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3703)  * @hinfo: PCM information to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3704)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3705)  * Open analog outputs and set up the hw-constraints.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3706)  * If the digital outputs can be opened as follower, open the digital
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3707)  * outputs, too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3708)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3709) int snd_hda_multi_out_analog_open(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3710) 				  struct hda_multi_out *mout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3711) 				  struct snd_pcm_substream *substream,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3712) 				  struct hda_pcm_stream *hinfo)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3713) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3714) 	struct snd_pcm_runtime *runtime = substream->runtime;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3715) 	runtime->hw.channels_max = mout->max_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3716) 	if (mout->dig_out_nid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3717) 		if (!mout->analog_rates) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3718) 			mout->analog_rates = hinfo->rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3719) 			mout->analog_formats = hinfo->formats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3720) 			mout->analog_maxbps = hinfo->maxbps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3721) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3722) 			runtime->hw.rates = mout->analog_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3723) 			runtime->hw.formats = mout->analog_formats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3724) 			hinfo->maxbps = mout->analog_maxbps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3725) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3726) 		if (!mout->spdif_rates) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3727) 			snd_hda_query_supported_pcm(codec, mout->dig_out_nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3728) 						    &mout->spdif_rates,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3729) 						    &mout->spdif_formats,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3730) 						    &mout->spdif_maxbps);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3731) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3732) 		mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3733) 		if (mout->share_spdif) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3734) 			if ((runtime->hw.rates & mout->spdif_rates) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3735) 			    (runtime->hw.formats & mout->spdif_formats)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3736) 				runtime->hw.rates &= mout->spdif_rates;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3737) 				runtime->hw.formats &= mout->spdif_formats;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3738) 				if (mout->spdif_maxbps < hinfo->maxbps)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3739) 					hinfo->maxbps = mout->spdif_maxbps;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3740) 			} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3741) 				mout->share_spdif = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3742) 				/* FIXME: need notify? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3743) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3744) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3745) 		mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3746) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3747) 	return snd_pcm_hw_constraint_step(substream->runtime, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3748) 					  SNDRV_PCM_HW_PARAM_CHANNELS, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3750) EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3751) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3752) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3753)  * snd_hda_multi_out_analog_prepare - Preapre the analog outputs.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3754)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3755)  * @mout: hda_multi_out object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3756)  * @stream_tag: stream tag to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3757)  * @format: format id to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3758)  * @substream: PCM substream to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3759)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3760)  * Set up the i/o for analog out.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3761)  * When the digital out is available, copy the front out to digital out, too.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3762)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3763) int snd_hda_multi_out_analog_prepare(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3764) 				     struct hda_multi_out *mout,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3765) 				     unsigned int stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3766) 				     unsigned int format,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3767) 				     struct snd_pcm_substream *substream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3768) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3769) 	const hda_nid_t *nids = mout->dac_nids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3770) 	int chs = substream->runtime->channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3771) 	struct hda_spdif_out *spdif;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3772) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3773) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3774) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3775) 	spdif = snd_hda_spdif_out_of_nid(codec, mout->dig_out_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3776) 	if (mout->dig_out_nid && mout->share_spdif &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3777) 	    mout->dig_out_used != HDA_DIG_EXCLUSIVE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3778) 		if (chs == 2 && spdif != NULL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3779) 		    snd_hda_is_supported_format(codec, mout->dig_out_nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3780) 						format) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3781) 		    !(spdif->status & IEC958_AES0_NONAUDIO)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3782) 			mout->dig_out_used = HDA_DIG_ANALOG_DUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3783) 			setup_dig_out_stream(codec, mout->dig_out_nid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3784) 					     stream_tag, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3785) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3786) 			mout->dig_out_used = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3787) 			cleanup_dig_out_stream(codec, mout->dig_out_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3788) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3789) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3790) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3791) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3792) 	/* front */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3793) 	snd_hda_codec_setup_stream(codec, nids[HDA_FRONT], stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3794) 				   0, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3795) 	if (!mout->no_share_stream &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3796) 	    mout->hp_nid && mout->hp_nid != nids[HDA_FRONT])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3797) 		/* headphone out will just decode front left/right (stereo) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3798) 		snd_hda_codec_setup_stream(codec, mout->hp_nid, stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3799) 					   0, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3800) 	/* extra outputs copied from front */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3801) 	for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3802) 		if (!mout->no_share_stream && mout->hp_out_nid[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3803) 			snd_hda_codec_setup_stream(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3804) 						   mout->hp_out_nid[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3805) 						   stream_tag, 0, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3807) 	/* surrounds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3808) 	for (i = 1; i < mout->num_dacs; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3809) 		if (chs >= (i + 1) * 2) /* independent out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3810) 			snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3811) 						   i * 2, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3812) 		else if (!mout->no_share_stream) /* copy front */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3813) 			snd_hda_codec_setup_stream(codec, nids[i], stream_tag,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3814) 						   0, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3815) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3816) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3817) 	/* extra surrounds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3818) 	for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3819) 		int ch = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3820) 		if (!mout->extra_out_nid[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3821) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3822) 		if (chs >= (i + 1) * 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3823) 			ch = i * 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3824) 		else if (!mout->no_share_stream)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3825) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3826) 		snd_hda_codec_setup_stream(codec, mout->extra_out_nid[i],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3827) 					   stream_tag, ch, format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3828) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3830) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3832) EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_prepare);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3833) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3834) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3835)  * snd_hda_multi_out_analog_cleanup - clean up the setting for analog out
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3836)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3837)  * @mout: hda_multi_out object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3838)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3839) int snd_hda_multi_out_analog_cleanup(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3840) 				     struct hda_multi_out *mout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3841) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3842) 	const hda_nid_t *nids = mout->dac_nids;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3843) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3844) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3845) 	for (i = 0; i < mout->num_dacs; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3846) 		snd_hda_codec_cleanup_stream(codec, nids[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3847) 	if (mout->hp_nid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3848) 		snd_hda_codec_cleanup_stream(codec, mout->hp_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3849) 	for (i = 0; i < ARRAY_SIZE(mout->hp_out_nid); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3850) 		if (mout->hp_out_nid[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3851) 			snd_hda_codec_cleanup_stream(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3852) 						     mout->hp_out_nid[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3853) 	for (i = 0; i < ARRAY_SIZE(mout->extra_out_nid); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3854) 		if (mout->extra_out_nid[i])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3855) 			snd_hda_codec_cleanup_stream(codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3856) 						     mout->extra_out_nid[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3857) 	mutex_lock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3858) 	if (mout->dig_out_nid && mout->dig_out_used == HDA_DIG_ANALOG_DUP) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3859) 		cleanup_dig_out_stream(codec, mout->dig_out_nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3860) 		mout->dig_out_used = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3861) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3862) 	mutex_unlock(&codec->spdif_mutex);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3863) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3864) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3865) EXPORT_SYMBOL_GPL(snd_hda_multi_out_analog_cleanup);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3867) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3868)  * snd_hda_get_default_vref - Get the default (mic) VREF pin bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3869)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3870)  * @pin: referred pin NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3871)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3872)  * Guess the suitable VREF pin bits to be set as the pin-control value.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3873)  * Note: the function doesn't set the AC_PINCTL_IN_EN bit.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3874)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3875) unsigned int snd_hda_get_default_vref(struct hda_codec *codec, hda_nid_t pin)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3876) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3877) 	unsigned int pincap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3878) 	unsigned int oldval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3879) 	oldval = snd_hda_codec_read(codec, pin, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3880) 				    AC_VERB_GET_PIN_WIDGET_CONTROL, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3881) 	pincap = snd_hda_query_pin_caps(codec, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3882) 	pincap = (pincap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3883) 	/* Exception: if the default pin setup is vref50, we give it priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3884) 	if ((pincap & AC_PINCAP_VREF_80) && oldval != PIN_VREF50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3885) 		return AC_PINCTL_VREF_80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3886) 	else if (pincap & AC_PINCAP_VREF_50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3887) 		return AC_PINCTL_VREF_50;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3888) 	else if (pincap & AC_PINCAP_VREF_100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3889) 		return AC_PINCTL_VREF_100;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3890) 	else if (pincap & AC_PINCAP_VREF_GRD)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3891) 		return AC_PINCTL_VREF_GRD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3892) 	return AC_PINCTL_VREF_HIZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3893) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3894) EXPORT_SYMBOL_GPL(snd_hda_get_default_vref);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3895) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3896) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3897)  * snd_hda_correct_pin_ctl - correct the pin ctl value for matching with the pin cap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3898)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3899)  * @pin: referred pin NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3900)  * @val: pin ctl value to audit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3901)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3902) unsigned int snd_hda_correct_pin_ctl(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3903) 				     hda_nid_t pin, unsigned int val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3904) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3905) 	static const unsigned int cap_lists[][2] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3906) 		{ AC_PINCTL_VREF_100, AC_PINCAP_VREF_100 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3907) 		{ AC_PINCTL_VREF_80, AC_PINCAP_VREF_80 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3908) 		{ AC_PINCTL_VREF_50, AC_PINCAP_VREF_50 },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3909) 		{ AC_PINCTL_VREF_GRD, AC_PINCAP_VREF_GRD },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3910) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3911) 	unsigned int cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3913) 	if (!val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3914) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3915) 	cap = snd_hda_query_pin_caps(codec, pin);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3916) 	if (!cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3917) 		return val; /* don't know what to do... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3918) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3919) 	if (val & AC_PINCTL_OUT_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3920) 		if (!(cap & AC_PINCAP_OUT))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3921) 			val &= ~(AC_PINCTL_OUT_EN | AC_PINCTL_HP_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3922) 		else if ((val & AC_PINCTL_HP_EN) && !(cap & AC_PINCAP_HP_DRV))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3923) 			val &= ~AC_PINCTL_HP_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3924) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3925) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3926) 	if (val & AC_PINCTL_IN_EN) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3927) 		if (!(cap & AC_PINCAP_IN))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3928) 			val &= ~(AC_PINCTL_IN_EN | AC_PINCTL_VREFEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3929) 		else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3930) 			unsigned int vcap, vref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3931) 			int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3932) 			vcap = (cap & AC_PINCAP_VREF) >> AC_PINCAP_VREF_SHIFT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3933) 			vref = val & AC_PINCTL_VREFEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3934) 			for (i = 0; i < ARRAY_SIZE(cap_lists); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3935) 				if (vref == cap_lists[i][0] &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3936) 				    !(vcap & cap_lists[i][1])) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3937) 					if (i == ARRAY_SIZE(cap_lists) - 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3938) 						vref = AC_PINCTL_VREF_HIZ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3939) 					else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3940) 						vref = cap_lists[i + 1][0];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3941) 				}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3942) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3943) 			val &= ~AC_PINCTL_VREFEN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3944) 			val |= vref;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3945) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3946) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3947) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3948) 	return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3949) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3950) EXPORT_SYMBOL_GPL(snd_hda_correct_pin_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3951) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3952) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3953)  * _snd_hda_pin_ctl - Helper to set pin ctl value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3954)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3955)  * @pin: referred pin NID
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3956)  * @val: pin control value to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3957)  * @cached: access over codec pinctl cache or direct write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3958)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3959)  * This function is a helper to set a pin ctl value more safely.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3960)  * It corrects the pin ctl value via snd_hda_correct_pin_ctl(), stores the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3961)  * value in pin target array via snd_hda_codec_set_pin_target(), then
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3962)  * actually writes the value via either snd_hda_codec_write_cache() or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3963)  * snd_hda_codec_write() depending on @cached flag.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3964)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3965) int _snd_hda_set_pin_ctl(struct hda_codec *codec, hda_nid_t pin,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3966) 			 unsigned int val, bool cached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3967) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3968) 	val = snd_hda_correct_pin_ctl(codec, pin, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3969) 	snd_hda_codec_set_pin_target(codec, pin, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3970) 	if (cached)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3971) 		return snd_hda_codec_write_cache(codec, pin, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3972) 				AC_VERB_SET_PIN_WIDGET_CONTROL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3973) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3974) 		return snd_hda_codec_write(codec, pin, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3975) 					   AC_VERB_SET_PIN_WIDGET_CONTROL, val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3976) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3977) EXPORT_SYMBOL_GPL(_snd_hda_set_pin_ctl);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3978) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3979) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3980)  * snd_hda_add_imux_item - Add an item to input_mux
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3981)  * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3982)  * @imux: imux helper object
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3983)  * @label: the name of imux item to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3984)  * @index: index number of imux item to assign
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3985)  * @type_idx: pointer to store the resultant label index
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3986)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3987)  * When the same label is used already in the existing items, the number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3988)  * suffix is appended to the label.  This label index number is stored
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3989)  * to type_idx when non-NULL pointer is given.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3990)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3991) int snd_hda_add_imux_item(struct hda_codec *codec,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3992) 			  struct hda_input_mux *imux, const char *label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3993) 			  int index, int *type_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3994) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3995) 	int i, label_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3996) 	if (imux->num_items >= HDA_MAX_NUM_INPUTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3997) 		codec_err(codec, "hda_codec: Too many imux items!\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3998) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3999) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4000) 	for (i = 0; i < imux->num_items; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4001) 		if (!strncmp(label, imux->items[i].label, strlen(label)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4002) 			label_idx++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4003) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4004) 	if (type_idx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4005) 		*type_idx = label_idx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4006) 	if (label_idx > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4007) 		snprintf(imux->items[imux->num_items].label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4008) 			 sizeof(imux->items[imux->num_items].label),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4009) 			 "%s %d", label, label_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4010) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4011) 		strlcpy(imux->items[imux->num_items].label, label,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4012) 			sizeof(imux->items[imux->num_items].label));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4013) 	imux->items[imux->num_items].index = index;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4014) 	imux->num_items++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4015) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4016) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4017) EXPORT_SYMBOL_GPL(snd_hda_add_imux_item);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4018) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4019) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4020)  * snd_hda_bus_reset_codecs - Reset the bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4021)  * @bus: HD-audio bus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4022)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4023) void snd_hda_bus_reset_codecs(struct hda_bus *bus)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4024) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4025) 	struct hda_codec *codec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4027) 	list_for_each_codec(codec, bus) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4028) 		/* FIXME: maybe a better way needed for forced reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4029) 		if (current_work() != &codec->jackpoll_work.work)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4030) 			cancel_delayed_work_sync(&codec->jackpoll_work);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4031) #ifdef CONFIG_PM
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4032) 		if (hda_codec_is_power_on(codec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4033) 			hda_call_codec_suspend(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4034) 			hda_call_codec_resume(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4035) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4036) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4037) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4038) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4040) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4041)  * snd_print_pcm_bits - Print the supported PCM fmt bits to the string buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4042)  * @pcm: PCM caps bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4043)  * @buf: the string buffer to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4044)  * @buflen: the max buffer length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4045)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4046)  * used by hda_proc.c and hda_eld.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4047)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4048) void snd_print_pcm_bits(int pcm, char *buf, int buflen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4049) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4050) 	static const unsigned int bits[] = { 8, 16, 20, 24, 32 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4051) 	int i, j;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4052) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4053) 	for (i = 0, j = 0; i < ARRAY_SIZE(bits); i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4054) 		if (pcm & (AC_SUPPCM_BITS_8 << i))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4055) 			j += scnprintf(buf + j, buflen - j,  " %d", bits[i]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4056) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4057) 	buf[j] = '\0'; /* necessary when j == 0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4059) EXPORT_SYMBOL_GPL(snd_print_pcm_bits);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4061) MODULE_DESCRIPTION("HDA codec core");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4062) MODULE_LICENSE("GPL");