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