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