^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * HD-audio codec driver binding
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Copyright (c) Takashi Iwai <tiwai@suse.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/init.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <sound/core.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <sound/hda_codec.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include "hda_local.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * find a matching codec id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) static int hda_codec_match(struct hdac_device *dev, struct hdac_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) struct hda_codec *codec = container_of(dev, struct hda_codec, core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) struct hda_codec_driver *driver =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) container_of(drv, struct hda_codec_driver, core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) const struct hda_device_id *list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* check probe_id instead of vendor_id if set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) u32 id = codec->probe_id ? codec->probe_id : codec->core.vendor_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) u32 rev_id = codec->core.revision_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) for (list = driver->id; list->vendor_id; list++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) if (list->vendor_id == id &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) (!list->rev_id || list->rev_id == rev_id)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) codec->preset = list;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) return 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) /* process an unsolicited event */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) static void hda_codec_unsol_event(struct hdac_device *dev, unsigned int ev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) struct hda_codec *codec = container_of(dev, struct hda_codec, core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) /* ignore unsol events during shutdown */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) if (codec->bus->shutdown)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) /* ignore unsol events during system suspend/resume */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) if (codec->core.dev.power.power_state.event != PM_EVENT_ON)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) if (codec->patch_ops.unsol_event)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) codec->patch_ops.unsol_event(codec, ev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * snd_hda_codec_set_name - set the codec name
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) * @name: name string to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int snd_hda_codec_set_name(struct hda_codec *codec, const char *name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) if (!name)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) err = snd_hdac_device_set_chip_name(&codec->core, name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) /* update the mixer name */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) if (!*codec->card->mixername ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) codec->bus->mixer_assigned >= codec->core.addr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) snprintf(codec->card->mixername,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) sizeof(codec->card->mixername), "%s %s",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) codec->core.vendor_name, codec->core.chip_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) codec->bus->mixer_assigned = codec->core.addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) return 0;
^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_codec_set_name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) static int hda_codec_driver_probe(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) struct hda_codec *codec = dev_to_hda_codec(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) struct module *owner = dev->driver->owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) hda_codec_patch_t patch;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) if (codec->bus->core.ext_ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) if (WARN_ON(!codec->bus->core.ext_ops->hdev_attach))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) return codec->bus->core.ext_ops->hdev_attach(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) if (WARN_ON(!codec->preset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) err = snd_hda_codec_set_name(codec, codec->preset->name);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) err = snd_hdac_regmap_init(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) if (!try_module_get(owner)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) err = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) goto error;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) patch = (hda_codec_patch_t)codec->preset->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (patch) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) err = patch(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) goto error_module_put;
^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) err = snd_hda_codec_build_pcms(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) goto error_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) err = snd_hda_codec_build_controls(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) goto error_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) /* only register after the bus probe finished; otherwise it's racy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) if (!codec->bus->bus_probing && codec->card->registered) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) err = snd_card_register(codec->card);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) goto error_module;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) snd_hda_codec_register(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) codec->core.lazy_cache = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) error_module:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) if (codec->patch_ops.free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) codec->patch_ops.free(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) error_module_put:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) module_put(owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) error:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) snd_hda_codec_cleanup_for_unbind(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) static int hda_codec_driver_remove(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct hda_codec *codec = dev_to_hda_codec(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) if (codec->bus->core.ext_ops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if (WARN_ON(!codec->bus->core.ext_ops->hdev_detach))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) return codec->bus->core.ext_ops->hdev_detach(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (codec->patch_ops.free)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) codec->patch_ops.free(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) snd_hda_codec_cleanup_for_unbind(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) module_put(dev->driver->owner);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static void hda_codec_driver_shutdown(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) struct hda_codec *codec = dev_to_hda_codec(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (!pm_runtime_suspended(dev) && codec->patch_ops.reboot_notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) codec->patch_ops.reboot_notify(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) struct module *owner)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) drv->core.driver.name = name;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) drv->core.driver.owner = owner;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) drv->core.driver.bus = &snd_hda_bus_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) drv->core.driver.probe = hda_codec_driver_probe;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) drv->core.driver.remove = hda_codec_driver_remove;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) drv->core.driver.shutdown = hda_codec_driver_shutdown;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) drv->core.driver.pm = &hda_codec_driver_pm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) drv->core.type = HDA_DEV_LEGACY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) drv->core.match = hda_codec_match;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) drv->core.unsol_event = hda_codec_unsol_event;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) return driver_register(&drv->core.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) EXPORT_SYMBOL_GPL(__hda_codec_driver_register);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) void hda_codec_driver_unregister(struct hda_codec_driver *drv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) driver_unregister(&drv->core.driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) EXPORT_SYMBOL_GPL(hda_codec_driver_unregister);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) static inline bool codec_probed(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) return device_attach(hda_codec_dev(codec)) > 0 && codec->preset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* try to auto-load codec module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) static void request_codec_module(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) char modalias[32];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) const char *mod = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) switch (codec->probe_id) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) case HDA_CODEC_ID_GENERIC_HDMI:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) #if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) mod = "snd-hda-codec-hdmi";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) case HDA_CODEC_ID_GENERIC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #if IS_MODULE(CONFIG_SND_HDA_GENERIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) mod = "snd-hda-codec-generic";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) mod = modalias;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) if (mod)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) request_module(mod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) #endif /* MODULE */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) /* try to auto-load and bind the codec module */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) static void codec_bind_module(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) #ifdef MODULE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) request_codec_module(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (codec_probed(codec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) /* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) static bool is_likely_hdmi_codec(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) hda_nid_t nid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) for_each_hda_codec_node(nid, codec) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) unsigned int wcaps = get_wcaps(codec, nid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) switch (get_wcaps_type(wcaps)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) case AC_WID_AUD_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) return false; /* HDMI parser supports only HDMI out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) case AC_WID_AUD_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) if (!(wcaps & AC_WCAP_DIGITAL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) /* no HDMI codec parser support */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) #define is_likely_hdmi_codec(codec) false
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) #endif /* CONFIG_SND_HDA_CODEC_HDMI */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static int codec_bind_generic(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) if (codec->probe_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) if (is_likely_hdmi_codec(codec)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) codec->probe_id = HDA_CODEC_ID_GENERIC_HDMI;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) request_codec_module(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) if (codec_probed(codec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) codec->probe_id = HDA_CODEC_ID_GENERIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) request_codec_module(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) if (codec_probed(codec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) #if IS_ENABLED(CONFIG_SND_HDA_GENERIC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) #define is_generic_config(codec) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) (codec->modelname && !strcmp(codec->modelname, "generic"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) #define is_generic_config(codec) 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) * snd_hda_codec_configure - (Re-)configure the HD-audio codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * @codec: the HDA codec
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * Start parsing of the given codec tree and (re-)initialize the whole
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * patch instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * Returns 0 if successful or a negative error code.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) int snd_hda_codec_configure(struct hda_codec *codec)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) if (codec->configured)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) if (is_generic_config(codec))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) codec->probe_id = HDA_CODEC_ID_GENERIC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) codec->probe_id = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) if (!device_is_registered(&codec->core.dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) err = snd_hdac_device_register(&codec->core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) if (!codec->preset)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) codec_bind_module(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) if (!codec->preset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) err = codec_bind_generic(codec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (err < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) codec_dbg(codec, "Unable to bind the codec\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) codec->configured = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) EXPORT_SYMBOL_GPL(snd_hda_codec_configure);