| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * HD-audio codec driver binding |
|---|
| 3 | 4 | * Copyright (c) Takashi Iwai <tiwai@suse.de> |
|---|
| .. | .. |
|---|
| 11 | 12 | #include <linux/pm.h> |
|---|
| 12 | 13 | #include <linux/pm_runtime.h> |
|---|
| 13 | 14 | #include <sound/core.h> |
|---|
| 14 | | -#include "hda_codec.h" |
|---|
| 15 | +#include <sound/hda_codec.h> |
|---|
| 15 | 16 | #include "hda_local.h" |
|---|
| 16 | 17 | |
|---|
| 17 | 18 | /* |
|---|
| .. | .. |
|---|
| 89 | 90 | hda_codec_patch_t patch; |
|---|
| 90 | 91 | int err; |
|---|
| 91 | 92 | |
|---|
| 93 | + if (codec->bus->core.ext_ops) { |
|---|
| 94 | + if (WARN_ON(!codec->bus->core.ext_ops->hdev_attach)) |
|---|
| 95 | + return -EINVAL; |
|---|
| 96 | + return codec->bus->core.ext_ops->hdev_attach(&codec->core); |
|---|
| 97 | + } |
|---|
| 98 | + |
|---|
| 92 | 99 | if (WARN_ON(!codec->preset)) |
|---|
| 93 | 100 | return -EINVAL; |
|---|
| 94 | 101 | |
|---|
| .. | .. |
|---|
| 136 | 143 | |
|---|
| 137 | 144 | error: |
|---|
| 138 | 145 | snd_hda_codec_cleanup_for_unbind(codec); |
|---|
| 146 | + codec->preset = NULL; |
|---|
| 139 | 147 | return err; |
|---|
| 140 | 148 | } |
|---|
| 141 | 149 | |
|---|
| .. | .. |
|---|
| 143 | 151 | { |
|---|
| 144 | 152 | struct hda_codec *codec = dev_to_hda_codec(dev); |
|---|
| 145 | 153 | |
|---|
| 154 | + if (codec->bus->core.ext_ops) { |
|---|
| 155 | + if (WARN_ON(!codec->bus->core.ext_ops->hdev_detach)) |
|---|
| 156 | + return -EINVAL; |
|---|
| 157 | + return codec->bus->core.ext_ops->hdev_detach(&codec->core); |
|---|
| 158 | + } |
|---|
| 159 | + |
|---|
| 146 | 160 | if (codec->patch_ops.free) |
|---|
| 147 | 161 | codec->patch_ops.free(codec); |
|---|
| 148 | 162 | snd_hda_codec_cleanup_for_unbind(codec); |
|---|
| 163 | + codec->preset = NULL; |
|---|
| 149 | 164 | module_put(dev->driver->owner); |
|---|
| 150 | 165 | return 0; |
|---|
| 151 | 166 | } |
|---|
| .. | .. |
|---|
| 288 | 303 | { |
|---|
| 289 | 304 | int err; |
|---|
| 290 | 305 | |
|---|
| 306 | + if (codec->configured) |
|---|
| 307 | + return 0; |
|---|
| 308 | + |
|---|
| 291 | 309 | if (is_generic_config(codec)) |
|---|
| 292 | 310 | codec->probe_id = HDA_CODEC_ID_GENERIC; |
|---|
| 293 | 311 | else |
|---|
| 294 | 312 | codec->probe_id = 0; |
|---|
| 295 | 313 | |
|---|
| 296 | | - err = snd_hdac_device_register(&codec->core); |
|---|
| 297 | | - if (err < 0) |
|---|
| 298 | | - return err; |
|---|
| 314 | + if (!device_is_registered(&codec->core.dev)) { |
|---|
| 315 | + err = snd_hdac_device_register(&codec->core); |
|---|
| 316 | + if (err < 0) |
|---|
| 317 | + return err; |
|---|
| 318 | + } |
|---|
| 299 | 319 | |
|---|
| 300 | 320 | if (!codec->preset) |
|---|
| 301 | 321 | codec_bind_module(codec); |
|---|
| 302 | 322 | if (!codec->preset) { |
|---|
| 303 | 323 | err = codec_bind_generic(codec); |
|---|
| 304 | 324 | if (err < 0) { |
|---|
| 305 | | - codec_err(codec, "Unable to bind the codec\n"); |
|---|
| 306 | | - goto error; |
|---|
| 325 | + codec_dbg(codec, "Unable to bind the codec\n"); |
|---|
| 326 | + return err; |
|---|
| 307 | 327 | } |
|---|
| 308 | 328 | } |
|---|
| 309 | 329 | |
|---|
| 330 | + codec->configured = 1; |
|---|
| 310 | 331 | return 0; |
|---|
| 311 | | - |
|---|
| 312 | | - error: |
|---|
| 313 | | - snd_hdac_device_unregister(&codec->core); |
|---|
| 314 | | - return err; |
|---|
| 315 | 332 | } |
|---|
| 316 | 333 | EXPORT_SYMBOL_GPL(snd_hda_codec_configure); |
|---|