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 <sound/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 (codec->bus->core.ext_ops) {
  85                if (WARN_ON(!codec->bus->core.ext_ops->hdev_attach))
  86                        return -EINVAL;
  87                return codec->bus->core.ext_ops->hdev_attach(&codec->core);
  88        }
  89
  90        if (WARN_ON(!codec->preset))
  91                return -EINVAL;
  92
  93        err = snd_hda_codec_set_name(codec, codec->preset->name);
  94        if (err < 0)
  95                goto error;
  96        err = snd_hdac_regmap_init(&codec->core);
  97        if (err < 0)
  98                goto error;
  99
 100        if (!try_module_get(owner)) {
 101                err = -EINVAL;
 102                goto error;
 103        }
 104
 105        patch = (hda_codec_patch_t)codec->preset->driver_data;
 106        if (patch) {
 107                err = patch(codec);
 108                if (err < 0)
 109                        goto error_module_put;
 110        }
 111
 112        err = snd_hda_codec_build_pcms(codec);
 113        if (err < 0)
 114                goto error_module;
 115        err = snd_hda_codec_build_controls(codec);
 116        if (err < 0)
 117                goto error_module;
 118        if (codec->card->registered) {
 119                err = snd_card_register(codec->card);
 120                if (err < 0)
 121                        goto error_module;
 122                snd_hda_codec_register(codec);
 123        }
 124
 125        codec->core.lazy_cache = true;
 126        return 0;
 127
 128 error_module:
 129        if (codec->patch_ops.free)
 130                codec->patch_ops.free(codec);
 131 error_module_put:
 132        module_put(owner);
 133
 134 error:
 135        snd_hda_codec_cleanup_for_unbind(codec);
 136        return err;
 137}
 138
 139static int hda_codec_driver_remove(struct device *dev)
 140{
 141        struct hda_codec *codec = dev_to_hda_codec(dev);
 142
 143        if (codec->bus->core.ext_ops) {
 144                if (WARN_ON(!codec->bus->core.ext_ops->hdev_detach))
 145                        return -EINVAL;
 146                return codec->bus->core.ext_ops->hdev_detach(&codec->core);
 147        }
 148
 149        if (codec->patch_ops.free)
 150                codec->patch_ops.free(codec);
 151        snd_hda_codec_cleanup_for_unbind(codec);
 152        module_put(dev->driver->owner);
 153        return 0;
 154}
 155
 156static void hda_codec_driver_shutdown(struct device *dev)
 157{
 158        struct hda_codec *codec = dev_to_hda_codec(dev);
 159
 160        if (!pm_runtime_suspended(dev) && codec->patch_ops.reboot_notify)
 161                codec->patch_ops.reboot_notify(codec);
 162}
 163
 164int __hda_codec_driver_register(struct hda_codec_driver *drv, const char *name,
 165                               struct module *owner)
 166{
 167        drv->core.driver.name = name;
 168        drv->core.driver.owner = owner;
 169        drv->core.driver.bus = &snd_hda_bus_type;
 170        drv->core.driver.probe = hda_codec_driver_probe;
 171        drv->core.driver.remove = hda_codec_driver_remove;
 172        drv->core.driver.shutdown = hda_codec_driver_shutdown;
 173        drv->core.driver.pm = &hda_codec_driver_pm;
 174        drv->core.type = HDA_DEV_LEGACY;
 175        drv->core.match = hda_codec_match;
 176        drv->core.unsol_event = hda_codec_unsol_event;
 177        return driver_register(&drv->core.driver);
 178}
 179EXPORT_SYMBOL_GPL(__hda_codec_driver_register);
 180
 181void hda_codec_driver_unregister(struct hda_codec_driver *drv)
 182{
 183        driver_unregister(&drv->core.driver);
 184}
 185EXPORT_SYMBOL_GPL(hda_codec_driver_unregister);
 186
 187static inline bool codec_probed(struct hda_codec *codec)
 188{
 189        return device_attach(hda_codec_dev(codec)) > 0 && codec->preset;
 190}
 191
 192/* try to auto-load codec module */
 193static void request_codec_module(struct hda_codec *codec)
 194{
 195#ifdef MODULE
 196        char modalias[32];
 197        const char *mod = NULL;
 198
 199        switch (codec->probe_id) {
 200        case HDA_CODEC_ID_GENERIC_HDMI:
 201#if IS_MODULE(CONFIG_SND_HDA_CODEC_HDMI)
 202                mod = "snd-hda-codec-hdmi";
 203#endif
 204                break;
 205        case HDA_CODEC_ID_GENERIC:
 206#if IS_MODULE(CONFIG_SND_HDA_GENERIC)
 207                mod = "snd-hda-codec-generic";
 208#endif
 209                break;
 210        default:
 211                snd_hdac_codec_modalias(&codec->core, modalias, sizeof(modalias));
 212                mod = modalias;
 213                break;
 214        }
 215
 216        if (mod)
 217                request_module(mod);
 218#endif /* MODULE */
 219}
 220
 221/* try to auto-load and bind the codec module */
 222static void codec_bind_module(struct hda_codec *codec)
 223{
 224#ifdef MODULE
 225        request_codec_module(codec);
 226        if (codec_probed(codec))
 227                return;
 228#endif
 229}
 230
 231#if IS_ENABLED(CONFIG_SND_HDA_CODEC_HDMI)
 232/* if all audio out widgets are digital, let's assume the codec as a HDMI/DP */
 233static bool is_likely_hdmi_codec(struct hda_codec *codec)
 234{
 235        hda_nid_t nid;
 236
 237        for_each_hda_codec_node(nid, codec) {
 238                unsigned int wcaps = get_wcaps(codec, nid);
 239                switch (get_wcaps_type(wcaps)) {
 240                case AC_WID_AUD_IN:
 241                        return false; /* HDMI parser supports only HDMI out */
 242                case AC_WID_AUD_OUT:
 243                        if (!(wcaps & AC_WCAP_DIGITAL))
 244                                return false;
 245                        break;
 246                }
 247        }
 248        return true;
 249}
 250#else
 251/* no HDMI codec parser support */
 252#define is_likely_hdmi_codec(codec)     false
 253#endif /* CONFIG_SND_HDA_CODEC_HDMI */
 254
 255static int codec_bind_generic(struct hda_codec *codec)
 256{
 257        if (codec->probe_id)
 258                return -ENODEV;
 259
 260        if (is_likely_hdmi_codec(codec)) {
 261                codec->probe_id = HDA_CODEC_ID_GENERIC_HDMI;
 262                request_codec_module(codec);
 263                if (codec_probed(codec))
 264                        return 0;
 265        }
 266
 267        codec->probe_id = HDA_CODEC_ID_GENERIC;
 268        request_codec_module(codec);
 269        if (codec_probed(codec))
 270                return 0;
 271        return -ENODEV;
 272}
 273
 274#if IS_ENABLED(CONFIG_SND_HDA_GENERIC)
 275#define is_generic_config(codec) \
 276        (codec->modelname && !strcmp(codec->modelname, "generic"))
 277#else
 278#define is_generic_config(codec)        0
 279#endif
 280
 281/**
 282 * snd_hda_codec_configure - (Re-)configure the HD-audio codec
 283 * @codec: the HDA codec
 284 *
 285 * Start parsing of the given codec tree and (re-)initialize the whole
 286 * patch instance.
 287 *
 288 * Returns 0 if successful or a negative error code.
 289 */
 290int snd_hda_codec_configure(struct hda_codec *codec)
 291{
 292        int err;
 293
 294        if (is_generic_config(codec))
 295                codec->probe_id = HDA_CODEC_ID_GENERIC;
 296        else
 297                codec->probe_id = 0;
 298
 299        err = snd_hdac_device_register(&codec->core);
 300        if (err < 0)
 301                return err;
 302
 303        if (!codec->preset)
 304                codec_bind_module(codec);
 305        if (!codec->preset) {
 306                err = codec_bind_generic(codec);
 307                if (err < 0) {
 308                        codec_err(codec, "Unable to bind the codec\n");
 309                        goto error;
 310                }
 311        }
 312
 313        return 0;
 314
 315 error:
 316        snd_hdac_device_unregister(&codec->core);
 317        return err;
 318}
 319EXPORT_SYMBOL_GPL(snd_hda_codec_configure);
 320