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