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