^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");