1457c8996SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2d8a766a1STakashi Iwai /*
3d8a766a1STakashi Iwai * HD-audio codec driver binding
4d8a766a1STakashi Iwai * Copyright (c) Takashi Iwai <tiwai@suse.de>
5d8a766a1STakashi Iwai */
6d8a766a1STakashi Iwai
7d8a766a1STakashi Iwai #include <linux/init.h>
8d8a766a1STakashi Iwai #include <linux/slab.h>
9d8a766a1STakashi Iwai #include <linux/mutex.h>
10d8a766a1STakashi Iwai #include <linux/module.h>
11d8a766a1STakashi Iwai #include <linux/export.h>
1259ed1eadSTakashi Iwai #include <linux/pm.h>
13d8a766a1STakashi Iwai #include <sound/core.h>
14b4af16d6SPierre-Louis Bossart #include <sound/hda_codec.h>
15d8a766a1STakashi Iwai #include "hda_local.h"
1637c4fd0dSTakashi Iwai #include "hda_jack.h"
17d8a766a1STakashi Iwai
18d8a766a1STakashi Iwai /*
19b9a94a9cSTakashi Iwai * find a matching codec id
20d8a766a1STakashi Iwai */
hda_codec_match(struct hdac_device * dev,struct hdac_driver * drv)21e3d280fcSTakashi Iwai static int hda_codec_match(struct hdac_device *dev, struct hdac_driver *drv)
22d8a766a1STakashi Iwai {
23e3d280fcSTakashi Iwai struct hda_codec *codec = container_of(dev, struct hda_codec, core);
24d8a766a1STakashi Iwai struct hda_codec_driver *driver =
25e3d280fcSTakashi Iwai container_of(drv, struct hda_codec_driver, core);
26b9a94a9cSTakashi Iwai const struct hda_device_id *list;
27d8a766a1STakashi Iwai /* check probe_id instead of vendor_id if set */
287639a06cSTakashi Iwai u32 id = codec->probe_id ? codec->probe_id : codec->core.vendor_id;
29b9a94a9cSTakashi Iwai u32 rev_id = codec->core.revision_id;
30d8a766a1STakashi Iwai
31b9a94a9cSTakashi Iwai for (list = driver->id; list->vendor_id; list++) {
32b9a94a9cSTakashi Iwai if (list->vendor_id == id &&
33b9a94a9cSTakashi Iwai (!list->rev_id || list->rev_id == rev_id)) {
34b9a94a9cSTakashi Iwai codec->preset = list;
35d8a766a1STakashi Iwai return 1;
36d8a766a1STakashi Iwai }
37d8a766a1STakashi Iwai }
38d8a766a1STakashi Iwai return 0;
39d8a766a1STakashi Iwai }
40d8a766a1STakashi Iwai
41d068ebc2STakashi Iwai /* process an unsolicited event */
hda_codec_unsol_event(struct hdac_device * dev,unsigned int ev)42d068ebc2STakashi Iwai static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev)
43d068ebc2STakashi Iwai {
44d068ebc2STakashi Iwai struct hda_codec *codec = container_of(dev, struct hda_codec, core);
45d068ebc2STakashi Iwai
46ca58f551STakashi Iwai /* ignore unsol events during shutdown */
47ca58f551STakashi Iwai if (codec->bus->shutdown)
48ca58f551STakashi Iwai return;
49ca58f551STakashi Iwai
505ff9dde4STakashi Iwai /* ignore unsol events during system suspend/resume */
515ff9dde4STakashi Iwai if (codec->core.dev.power.power_state.event != PM_EVENT_ON)
525ff9dde4STakashi Iwai return;
535ff9dde4STakashi Iwai
54d068ebc2STakashi Iwai if (codec->patch_ops.unsol_event)
55d068ebc2STakashi Iwai codec->patch_ops.unsol_event(codec, ev);
56d068ebc2STakashi Iwai }
57d068ebc2STakashi Iwai
58ded255beSTakashi Iwai /**
59ded255beSTakashi Iwai * snd_hda_codec_set_name - set the codec name
60ded255beSTakashi Iwai * @codec: the HDA codec
61ded255beSTakashi Iwai * @name: name string to set
62ded255beSTakashi Iwai */
snd_hda_codec_set_name(struct hda_codec * codec,const char * name)63ded255beSTakashi Iwai int snd_hda_codec_set_name(struct hda_codec *codec, const char *name)
64d8a766a1STakashi Iwai {
65ded255beSTakashi Iwai int err;
66ded255beSTakashi Iwai
67ded255beSTakashi Iwai if (!name)
68ded255beSTakashi Iwai return 0;
69ded255beSTakashi Iwai err = snd_hdac_device_set_chip_name(&codec->core, name);
70ded255beSTakashi Iwai if (err < 0)
71ded255beSTakashi Iwai return err;
72ded255beSTakashi Iwai
73ded255beSTakashi Iwai /* update the mixer name */
747fbe824aSTakashi Iwai if (!*codec->card->mixername ||
752f0eaad9STakashi Iwai codec->bus->mixer_assigned >= codec->core.addr) {
76ded255beSTakashi Iwai snprintf(codec->card->mixername,
77ded255beSTakashi Iwai sizeof(codec->card->mixername), "%s %s",
78ded255beSTakashi Iwai codec->core.vendor_name, codec->core.chip_name);
792f0eaad9STakashi Iwai codec->bus->mixer_assigned = codec->core.addr;
80d8a766a1STakashi Iwai }
81ded255beSTakashi Iwai
82ded255beSTakashi Iwai return 0;
83d8a766a1STakashi Iwai }
84ded255beSTakashi Iwai EXPORT_SYMBOL_GPL(snd_hda_codec_set_name);
85d8a766a1STakashi Iwai
hda_codec_driver_probe(struct device * dev)86d8a766a1STakashi Iwai static int hda_codec_driver_probe(struct device *dev)
87d8a766a1STakashi Iwai {
88d8a766a1STakashi Iwai struct hda_codec *codec = dev_to_hda_codec(dev);
89d8a766a1STakashi Iwai struct module *owner = dev->driver->owner;
90b9a94a9cSTakashi Iwai hda_codec_patch_t patch;
91d8a766a1STakashi Iwai int err;
92d8a766a1STakashi Iwai
936bae5ea9SRakesh Ughreja if (codec->bus->core.ext_ops) {
946bae5ea9SRakesh Ughreja if (WARN_ON(!codec->bus->core.ext_ops->hdev_attach))
956bae5ea9SRakesh Ughreja return -EINVAL;
966bae5ea9SRakesh Ughreja return codec->bus->core.ext_ops->hdev_attach(&codec->core);
976bae5ea9SRakesh Ughreja }
986bae5ea9SRakesh Ughreja
99d8a766a1STakashi Iwai if (WARN_ON(!codec->preset))
100d8a766a1STakashi Iwai return -EINVAL;
101d8a766a1STakashi Iwai
102ded255beSTakashi Iwai err = snd_hda_codec_set_name(codec, codec->preset->name);
103d8a766a1STakashi Iwai if (err < 0)
104d8a766a1STakashi Iwai goto error;
1054d75faa0STakashi Iwai err = snd_hdac_regmap_init(&codec->core);
1064d75faa0STakashi Iwai if (err < 0)
1074d75faa0STakashi Iwai goto error;
108d8a766a1STakashi Iwai
109d8a766a1STakashi Iwai if (!try_module_get(owner)) {
110d8a766a1STakashi Iwai err = -EINVAL;
111d8a766a1STakashi Iwai goto error;
112d8a766a1STakashi Iwai }
113d8a766a1STakashi Iwai
114b9a94a9cSTakashi Iwai patch = (hda_codec_patch_t)codec->preset->driver_data;
115b9a94a9cSTakashi Iwai if (patch) {
116b9a94a9cSTakashi Iwai err = patch(codec);
117bcd96557STakashi Iwai if (err < 0)
118284b4c92SWang YanQing goto error_module_put;
119b9a94a9cSTakashi Iwai }
120bcd96557STakashi Iwai
121bcd96557STakashi Iwai err = snd_hda_codec_build_pcms(codec);
122bcd96557STakashi Iwai if (err < 0)
123bcd96557STakashi Iwai goto error_module;
124bcd96557STakashi Iwai err = snd_hda_codec_build_controls(codec);
125bcd96557STakashi Iwai if (err < 0)
126bcd96557STakashi Iwai goto error_module;
127305a0adeSTakashi Iwai /* only register after the bus probe finished; otherwise it's racy */
128305a0adeSTakashi Iwai if (!codec->bus->bus_probing && codec->card->registered) {
129bcd96557STakashi Iwai err = snd_card_register(codec->card);
130bcd96557STakashi Iwai if (err < 0)
131bcd96557STakashi Iwai goto error_module;
132c4c2533fSTakashi Iwai snd_hda_codec_register(codec);
133d8a766a1STakashi Iwai }
134d8a766a1STakashi Iwai
1354d75faa0STakashi Iwai codec->core.lazy_cache = true;
136d8a766a1STakashi Iwai return 0;
137d8a766a1STakashi Iwai
138bcd96557STakashi Iwai error_module:
139284b4c92SWang YanQing if (codec->patch_ops.free)
140284b4c92SWang YanQing codec->patch_ops.free(codec);
141284b4c92SWang YanQing error_module_put:
142bcd96557STakashi Iwai module_put(owner);
143bcd96557STakashi Iwai
144d8a766a1STakashi Iwai error:
145bcd96557STakashi Iwai snd_hda_codec_cleanup_for_unbind(codec);
146*87978e6aSCezary Rojewski codec->preset = NULL;
147d8a766a1STakashi Iwai return err;
148d8a766a1STakashi Iwai }
149d8a766a1STakashi Iwai
hda_codec_driver_remove(struct device * dev)150d8a766a1STakashi Iwai static int hda_codec_driver_remove(struct device *dev)
151d8a766a1STakashi Iwai {
152d8a766a1STakashi Iwai struct hda_codec *codec = dev_to_hda_codec(dev);
153d8a766a1STakashi Iwai
1546bae5ea9SRakesh Ughreja if (codec->bus->core.ext_ops) {
1556bae5ea9SRakesh Ughreja if (WARN_ON(!codec->bus->core.ext_ops->hdev_detach))
1566bae5ea9SRakesh Ughreja return -EINVAL;
1576bae5ea9SRakesh Ughreja return codec->bus->core.ext_ops->hdev_detach(&codec->core);
1586bae5ea9SRakesh Ughreja }
1596bae5ea9SRakesh Ughreja
1607206998fSTakashi Iwai snd_hda_codec_disconnect_pcms(codec);
16137c4fd0dSTakashi Iwai snd_hda_jack_tbl_disconnect(codec);
162ead3d3c5STakashi Iwai if (!refcount_dec_and_test(&codec->pcm_ref))
1637206998fSTakashi Iwai wait_event(codec->remove_sleep, !refcount_read(&codec->pcm_ref));
1647206998fSTakashi Iwai snd_power_sync_ref(codec->bus->card);
1657206998fSTakashi Iwai
166d8a766a1STakashi Iwai if (codec->patch_ops.free)
167d8a766a1STakashi Iwai codec->patch_ops.free(codec);
1689a6246ffSTakashi Iwai snd_hda_codec_cleanup_for_unbind(codec);
169*87978e6aSCezary Rojewski codec->preset = NULL;
170d8a766a1STakashi Iwai module_put(dev->driver->owner);
171d8a766a1STakashi Iwai return 0;
172d8a766a1STakashi Iwai }
173d8a766a1STakashi Iwai
hda_codec_driver_shutdown(struct device * dev)174b2a0bafaSTakashi Iwai static void hda_codec_driver_shutdown(struct device *dev)
175b2a0bafaSTakashi Iwai {
176b98444edSTakashi Iwai snd_hda_codec_shutdown(dev_to_hda_codec(dev));
177b2a0bafaSTakashi Iwai }
178b2a0bafaSTakashi Iwai
__hda_codec_driver_register(struct hda_codec_driver * drv,const char * name,struct module * owner)179d8a766a1STakashi Iwai int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
180d8a766a1STakashi Iwai struct module *owner)
181d8a766a1STakashi Iwai {
182e3d280fcSTakashi Iwai drv->core.driver.name = name;
183e3d280fcSTakashi Iwai drv->core.driver.owner = owner;
184e3d280fcSTakashi Iwai drv->core.driver.bus = &snd_hda_bus_type;
185e3d280fcSTakashi Iwai drv->core.driver.probe = hda_codec_driver_probe;
186e3d280fcSTakashi Iwai drv->core.driver.remove = hda_codec_driver_remove;
187e3d280fcSTakashi Iwai drv->core.driver.shutdown = hda_codec_driver_shutdown;
188e3d280fcSTakashi Iwai drv->core.driver.pm = &hda_codec_driver_pm;
189e3d280fcSTakashi Iwai drv->core.type = HDA_DEV_LEGACY;
190e3d280fcSTakashi Iwai drv->core.match = hda_codec_match;
191d068ebc2STakashi Iwai drv->core.unsol_event = hda_codec_unsol_event;
192e3d280fcSTakashi Iwai return driver_register(&drv->core.driver);
193d8a766a1STakashi Iwai }
194d8a766a1STakashi Iwai EXPORT_SYMBOL_GPL(__hda_codec_driver_register);
195d8a766a1STakashi Iwai
hda_codec_driver_unregister(struct hda_codec_driver * drv)196d8a766a1STakashi Iwai void hda_codec_driver_unregister(struct hda_codec_driver *drv)
197d8a766a1STakashi Iwai {
198e3d280fcSTakashi Iwai driver_unregister(&drv->core.driver);
199d8a766a1STakashi Iwai }
200d8a766a1STakashi Iwai EXPORT_SYMBOL_GPL(hda_codec_driver_unregister);
201d8a766a1STakashi Iwai
codec_probed(struct hda_codec * codec)202d8a766a1STakashi Iwai static inline bool codec_probed(struct hda_codec *codec)
203d8a766a1STakashi Iwai {
204d8a766a1STakashi Iwai return device_attach(hda_codec_dev(codec)) > 0 && codec->preset;
205d8a766a1STakashi Iwai }
206d8a766a1STakashi Iwai
207bca8e988STakashi Iwai /* try to auto-load codec module */
request_codec_module(struct hda_codec * codec)208bca8e988STakashi Iwai static void request_codec_module(struct hda_codec *codec)
209bca8e988STakashi Iwai {
210bca8e988STakashi Iwai #ifdef MODULE
211bca8e988STakashi Iwai char modalias[32];
212bca8e988STakashi Iwai const char *mod = NULL;
213bca8e988STakashi Iwai
214bca8e988STakashi Iwai switch (codec->probe_id) {
215bca8e988STakashi Iwai case HDA_CODEC_ID_GENERIC_HDMI:
216bca8e988STakashi Iwai #if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
217bca8e988STakashi Iwai mod = "snd-hda-codec-hdmi";
218bca8e988STakashi Iwai #endif
219bca8e988STakashi Iwai break;
220bca8e988STakashi Iwai case HDA_CODEC_ID_GENERIC:
221bca8e988STakashi Iwai #if IS_MODULE(CONFIG_SND_HDA_GENERIC)
222bca8e988STakashi Iwai mod = "snd-hda-codec-generic";
223bca8e988STakashi Iwai #endif
224bca8e988STakashi Iwai break;
225bca8e988STakashi Iwai default:
226bca8e988STakashi Iwai snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
227bca8e988STakashi Iwai mod = modalias;
228bca8e988STakashi Iwai break;
229bca8e988STakashi Iwai }
230bca8e988STakashi Iwai
231bca8e988STakashi Iwai if (mod)
232bca8e988STakashi Iwai request_module(mod);
233bca8e988STakashi Iwai #endif /* MODULE */
234bca8e988STakashi Iwai }
235bca8e988STakashi Iwai
236d8a766a1STakashi Iwai /* try to auto-load and bind the codec module */
codec_bind_module(struct hda_codec * codec)237d8a766a1STakashi Iwai static void codec_bind_module(struct hda_codec *codec)
238d8a766a1STakashi Iwai {
239d8a766a1STakashi Iwai #ifdef MODULE
240bca8e988STakashi Iwai request_codec_module(codec);
241d8a766a1STakashi Iwai if (codec_probed(codec))
242d8a766a1STakashi Iwai return;
243d8a766a1STakashi Iwai #endif
244d8a766a1STakashi Iwai }
245d8a766a1STakashi Iwai
246d8a766a1STakashi Iwai #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
247d8a766a1STakashi Iwai /* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */
is_likely_hdmi_codec(struct hda_codec * codec)248d8a766a1STakashi Iwai static bool is_likely_hdmi_codec(struct hda_codec *codec)
249d8a766a1STakashi Iwai {
2507639a06cSTakashi Iwai hda_nid_t nid;
251d8a766a1STakashi Iwai
2520fcc43e2SCezary Rojewski /*
2530fcc43e2SCezary Rojewski * For ASoC users, if snd_hda_hdmi_codec module is denylisted and any
2540fcc43e2SCezary Rojewski * event causes i915 enumeration to fail, ->wcaps remains uninitialized.
2550fcc43e2SCezary Rojewski */
2560fcc43e2SCezary Rojewski if (!codec->wcaps)
2570fcc43e2SCezary Rojewski return true;
2580fcc43e2SCezary Rojewski
2597639a06cSTakashi Iwai for_each_hda_codec_node(nid, codec) {
260d8a766a1STakashi Iwai unsigned int wcaps = get_wcaps(codec, nid);
261d8a766a1STakashi Iwai switch (get_wcaps_type(wcaps)) {
262d8a766a1STakashi Iwai case AC_WID_AUD_IN:
263d8a766a1STakashi Iwai return false; /* HDMI parser supports only HDMI out */
264d8a766a1STakashi Iwai case AC_WID_AUD_OUT:
265d8a766a1STakashi Iwai if (!(wcaps & AC_WCAP_DIGITAL))
266d8a766a1STakashi Iwai return false;
267d8a766a1STakashi Iwai break;
268d8a766a1STakashi Iwai }
269d8a766a1STakashi Iwai }
270d8a766a1STakashi Iwai return true;
271d8a766a1STakashi Iwai }
272d8a766a1STakashi Iwai #else
273d8a766a1STakashi Iwai /* no HDMI codec parser support */
274d8a766a1STakashi Iwai #define is_likely_hdmi_codec(codec) false
275d8a766a1STakashi Iwai #endif /* CONFIG_SND_HDA_CODEC_HDMI */
276d8a766a1STakashi Iwai
codec_bind_generic(struct hda_codec * codec)277d8a766a1STakashi Iwai static int codec_bind_generic(struct hda_codec *codec)
278d8a766a1STakashi Iwai {
279d8a766a1STakashi Iwai if (codec->probe_id)
280d8a766a1STakashi Iwai return -ENODEV;
281d8a766a1STakashi Iwai
282d8a766a1STakashi Iwai if (is_likely_hdmi_codec(codec)) {
283d8a766a1STakashi Iwai codec->probe_id = HDA_CODEC_ID_GENERIC_HDMI;
284bca8e988STakashi Iwai request_codec_module(codec);
285d8a766a1STakashi Iwai if (codec_probed(codec))
286d8a766a1STakashi Iwai return 0;
287d8a766a1STakashi Iwai }
288d8a766a1STakashi Iwai
289d8a766a1STakashi Iwai codec->probe_id = HDA_CODEC_ID_GENERIC;
290bca8e988STakashi Iwai request_codec_module(codec);
291d8a766a1STakashi Iwai if (codec_probed(codec))
292d8a766a1STakashi Iwai return 0;
293d8a766a1STakashi Iwai return -ENODEV;
294d8a766a1STakashi Iwai }
295d8a766a1STakashi Iwai
296d8a766a1STakashi Iwai #if IS_ENABLED(CONFIG_SND_HDA_GENERIC)
297d8a766a1STakashi Iwai #define is_generic_config(codec) \
298d8a766a1STakashi Iwai (codec->modelname && !strcmp(codec->modelname, "generic"))
299d8a766a1STakashi Iwai #else
300d8a766a1STakashi Iwai #define is_generic_config(codec) 0
301d8a766a1STakashi Iwai #endif
302d8a766a1STakashi Iwai
303d8a766a1STakashi Iwai /**
304d8a766a1STakashi Iwai * snd_hda_codec_configure - (Re-)configure the HD-audio codec
305d8a766a1STakashi Iwai * @codec: the HDA codec
306d8a766a1STakashi Iwai *
307d8a766a1STakashi Iwai * Start parsing of the given codec tree and (re-)initialize the whole
308d8a766a1STakashi Iwai * patch instance.
309d8a766a1STakashi Iwai *
310d8a766a1STakashi Iwai * Returns 0 if successful or a negative error code.
311d8a766a1STakashi Iwai */
snd_hda_codec_configure(struct hda_codec * codec)312d8a766a1STakashi Iwai int snd_hda_codec_configure(struct hda_codec *codec)
313d8a766a1STakashi Iwai {
314d8a766a1STakashi Iwai int err;
315d8a766a1STakashi Iwai
316c0f1886dSTakashi Iwai if (codec->configured)
317c0f1886dSTakashi Iwai return 0;
318c0f1886dSTakashi Iwai
319d8a766a1STakashi Iwai if (is_generic_config(codec))
320d8a766a1STakashi Iwai codec->probe_id = HDA_CODEC_ID_GENERIC;
321d8a766a1STakashi Iwai else
322d8a766a1STakashi Iwai codec->probe_id = 0;
323d8a766a1STakashi Iwai
324c0f1886dSTakashi Iwai if (!device_is_registered(&codec->core.dev)) {
3253256be65STakashi Iwai err = snd_hdac_device_register(&codec->core);
326d8a766a1STakashi Iwai if (err < 0)
327d8a766a1STakashi Iwai return err;
328c0f1886dSTakashi Iwai }
329d8a766a1STakashi Iwai
330d8a766a1STakashi Iwai if (!codec->preset)
331d8a766a1STakashi Iwai codec_bind_module(codec);
332d8a766a1STakashi Iwai if (!codec->preset) {
333d8a766a1STakashi Iwai err = codec_bind_generic(codec);
334d8a766a1STakashi Iwai if (err < 0) {
335c0f1886dSTakashi Iwai codec_dbg(codec, "Unable to bind the codec\n");
336d8a766a1STakashi Iwai return err;
337d8a766a1STakashi Iwai }
338c0f1886dSTakashi Iwai }
339c0f1886dSTakashi Iwai
340c0f1886dSTakashi Iwai codec->configured = 1;
341c0f1886dSTakashi Iwai return 0;
342c0f1886dSTakashi Iwai }
343d8a766a1STakashi Iwai EXPORT_SYMBOL_GPL(snd_hda_codec_configure);
344