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