1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright(c) 2021-2022 Intel Corporation
5 // Author: Cezary Rojewski <cezary.rojewski@intel.com>
8 #include <linux/module.h>
9 #include <linux/pm_runtime.h>
10 #include <sound/soc.h>
11 #include <sound/hdaudio_ext.h>
12 #include <sound/hda_i915.h>
13 #include <sound/hda_codec.h>
16 static int hda_codec_create_dais(struct hda_codec
*codec
, int pcm_count
,
17 struct snd_soc_dai_driver
**drivers
)
19 struct device
*dev
= &codec
->core
.dev
;
20 struct snd_soc_dai_driver
*drvs
;
24 drvs
= devm_kcalloc(dev
, pcm_count
, sizeof(*drvs
), GFP_KERNEL
);
28 pcm
= list_first_entry(&codec
->pcm_list_head
, struct hda_pcm
, list
);
30 for (i
= 0; i
< pcm_count
; i
++, pcm
= list_next_entry(pcm
, list
)) {
31 struct snd_soc_pcm_stream
*stream
;
34 dev_info(dev
, "creating for %s %d\n", pcm
->name
, i
);
36 drvs
[i
].name
= pcm
->name
;
37 drvs
[i
].ops
= &snd_soc_hda_codec_dai_ops
;
39 dir
= SNDRV_PCM_STREAM_PLAYBACK
;
40 stream
= &drvs
[i
].playback
;
41 if (!pcm
->stream
[dir
].substreams
) {
42 dev_info(dev
, "skipping playback dai for %s\n", pcm
->name
);
47 devm_kasprintf(dev
, GFP_KERNEL
, "%s %s", pcm
->name
,
48 snd_pcm_direction_name(dir
));
49 if (!stream
->stream_name
)
51 stream
->channels_min
= pcm
->stream
[dir
].channels_min
;
52 stream
->channels_max
= pcm
->stream
[dir
].channels_max
;
53 stream
->rates
= pcm
->stream
[dir
].rates
;
54 stream
->formats
= pcm
->stream
[dir
].formats
;
55 stream
->subformats
= pcm
->stream
[dir
].subformats
;
56 stream
->sig_bits
= pcm
->stream
[dir
].maxbps
;
59 dir
= SNDRV_PCM_STREAM_CAPTURE
;
60 stream
= &drvs
[i
].capture
;
61 if (!pcm
->stream
[dir
].substreams
) {
62 dev_info(dev
, "skipping capture dai for %s\n", pcm
->name
);
67 devm_kasprintf(dev
, GFP_KERNEL
, "%s %s", pcm
->name
,
68 snd_pcm_direction_name(dir
));
69 if (!stream
->stream_name
)
71 stream
->channels_min
= pcm
->stream
[dir
].channels_min
;
72 stream
->channels_max
= pcm
->stream
[dir
].channels_max
;
73 stream
->rates
= pcm
->stream
[dir
].rates
;
74 stream
->formats
= pcm
->stream
[dir
].formats
;
75 stream
->subformats
= pcm
->stream
[dir
].subformats
;
76 stream
->sig_bits
= pcm
->stream
[dir
].maxbps
;
83 static int hda_codec_register_dais(struct hda_codec
*codec
, struct snd_soc_component
*component
)
85 struct snd_soc_dai_driver
*drvs
= NULL
;
86 struct snd_soc_dapm_context
*dapm
;
88 int ret
, pcm_count
= 0;
90 if (list_empty(&codec
->pcm_list_head
))
92 list_for_each_entry(pcm
, &codec
->pcm_list_head
, list
)
95 ret
= hda_codec_create_dais(codec
, pcm_count
, &drvs
);
99 dapm
= snd_soc_component_get_dapm(component
);
101 list_for_each_entry(pcm
, &codec
->pcm_list_head
, list
) {
102 struct snd_soc_dai
*dai
;
104 dai
= snd_soc_register_dai(component
, drvs
, false);
106 dev_err(component
->dev
, "register dai for %s failed\n", pcm
->name
);
110 ret
= snd_soc_dapm_new_dai_widgets(dapm
, dai
);
112 dev_err(component
->dev
, "create widgets failed: %d\n", ret
);
113 snd_soc_unregister_dai(dai
);
117 snd_soc_dai_init_dma_data(dai
, &pcm
->stream
[0], &pcm
->stream
[1]);
124 static void hda_codec_unregister_dais(struct hda_codec
*codec
,
125 struct snd_soc_component
*component
)
127 struct snd_soc_dai
*dai
, *save
;
130 for_each_component_dais_safe(component
, dai
, save
) {
133 list_for_each_entry(pcm
, &codec
->pcm_list_head
, list
) {
134 if (strcmp(dai
->driver
->name
, pcm
->name
))
137 for_each_pcm_streams(stream
)
138 snd_soc_dapm_free_widget(snd_soc_dai_get_widget(dai
, stream
));
140 snd_soc_unregister_dai(dai
);
146 int hda_codec_probe_complete(struct hda_codec
*codec
)
148 struct hdac_device
*hdev
= &codec
->core
;
149 struct hdac_bus
*bus
= hdev
->bus
;
152 ret
= snd_hda_codec_build_controls(codec
);
154 dev_err(&hdev
->dev
, "unable to create controls %d\n", ret
);
158 /* Bus suspended codecs as it does not manage their pm */
159 pm_runtime_set_active(&hdev
->dev
);
160 /* rpm was forbidden in snd_hda_codec_device_new() */
161 snd_hda_codec_set_power_save(codec
, 2000);
162 snd_hda_codec_register(codec
);
164 /* Complement pm_runtime_get_sync(bus) in probe */
165 pm_runtime_mark_last_busy(bus
->dev
);
166 pm_runtime_put_autosuspend(bus
->dev
);
170 EXPORT_SYMBOL_GPL(hda_codec_probe_complete
);
172 /* Expects codec with usage_count=1 and status=suspended */
173 static int hda_codec_probe(struct snd_soc_component
*component
)
175 struct hda_codec
*codec
= dev_to_hda_codec(component
->dev
);
176 struct hdac_device
*hdev
= &codec
->core
;
177 struct hdac_bus
*bus
= hdev
->bus
;
178 struct hdac_ext_link
*hlink
;
179 hda_codec_patch_t patch
;
183 WARN_ON(atomic_read(&hdev
->dev
.power
.usage_count
) != 1 ||
184 !pm_runtime_status_suspended(&hdev
->dev
));
187 hlink
= snd_hdac_ext_bus_get_hlink_by_addr(bus
, hdev
->addr
);
189 dev_err(&hdev
->dev
, "hdac link not found\n");
193 pm_runtime_get_sync(bus
->dev
);
194 if (hda_codec_is_display(codec
))
195 snd_hdac_display_power(bus
, hdev
->addr
, true);
196 snd_hdac_ext_bus_link_get(bus
, hlink
);
198 ret
= snd_hda_codec_device_new(codec
->bus
, component
->card
->snd_card
, hdev
->addr
, codec
,
201 dev_err(&hdev
->dev
, "codec create failed: %d\n", ret
);
205 ret
= snd_hda_codec_set_name(codec
, codec
->preset
->name
);
207 dev_err(&hdev
->dev
, "set name: %s failed: %d\n", codec
->preset
->name
, ret
);
211 ret
= snd_hdac_regmap_init(&codec
->core
);
213 dev_err(&hdev
->dev
, "regmap init failed: %d\n", ret
);
217 patch
= (hda_codec_patch_t
)codec
->preset
->driver_data
;
219 dev_err(&hdev
->dev
, "no patch specified\n");
226 dev_err(&hdev
->dev
, "codec init failed: %d\n", ret
);
230 ret
= snd_hda_codec_parse_pcms(codec
);
232 dev_err(&hdev
->dev
, "unable to map pcms to dai: %d\n", ret
);
236 ret
= hda_codec_register_dais(codec
, component
);
238 dev_err(&hdev
->dev
, "update dais failed: %d\n", ret
);
242 if (!hda_codec_is_display(codec
)) {
243 ret
= hda_codec_probe_complete(codec
);
248 codec
->core
.lazy_cache
= true;
253 hda_codec_unregister_dais(codec
, component
);
255 if (codec
->patch_ops
.free
)
256 codec
->patch_ops
.free(codec
);
258 snd_hda_codec_cleanup_for_unbind(codec
);
260 if (hda_codec_is_display(codec
))
261 snd_hdac_display_power(bus
, hdev
->addr
, false);
263 snd_hdac_ext_bus_link_put(bus
, hlink
);
265 pm_runtime_mark_last_busy(bus
->dev
);
266 pm_runtime_put_autosuspend(bus
->dev
);
270 /* Leaves codec with usage_count=1 and status=suspended */
271 static void hda_codec_remove(struct snd_soc_component
*component
)
273 struct hda_codec
*codec
= dev_to_hda_codec(component
->dev
);
274 struct hdac_device
*hdev
= &codec
->core
;
275 struct hdac_bus
*bus
= hdev
->bus
;
276 struct hdac_ext_link
*hlink
;
277 bool was_registered
= codec
->core
.registered
;
279 /* Don't allow any more runtime suspends */
280 pm_runtime_forbid(&hdev
->dev
);
282 hda_codec_unregister_dais(codec
, component
);
284 if (codec
->patch_ops
.free
)
285 codec
->patch_ops
.free(codec
);
287 snd_hda_codec_cleanup_for_unbind(codec
);
288 pm_runtime_put_noidle(&hdev
->dev
);
289 /* snd_hdac_device_exit() is only called on bus remove */
290 pm_runtime_set_suspended(&hdev
->dev
);
292 if (hda_codec_is_display(codec
))
293 snd_hdac_display_power(bus
, hdev
->addr
, false);
295 hlink
= snd_hdac_ext_bus_get_hlink_by_addr(bus
, hdev
->addr
);
297 snd_hdac_ext_bus_link_put(bus
, hlink
);
299 * HDMI card's hda_codec_probe_complete() (see late_probe()) may
300 * not be called due to early error, leaving bus uc unbalanced
302 if (!was_registered
) {
303 pm_runtime_mark_last_busy(bus
->dev
);
304 pm_runtime_put_autosuspend(bus
->dev
);
308 WARN_ON(atomic_read(&hdev
->dev
.power
.usage_count
) != 1 ||
309 !pm_runtime_status_suspended(&hdev
->dev
));
313 static const struct snd_soc_dapm_route hda_dapm_routes
[] = {
314 {"AIF1TX", NULL
, "Codec Input Pin1"},
315 {"AIF2TX", NULL
, "Codec Input Pin2"},
316 {"AIF3TX", NULL
, "Codec Input Pin3"},
318 {"Codec Output Pin1", NULL
, "AIF1RX"},
319 {"Codec Output Pin2", NULL
, "AIF2RX"},
320 {"Codec Output Pin3", NULL
, "AIF3RX"},
323 static const struct snd_soc_dapm_widget hda_dapm_widgets
[] = {
324 /* Audio Interface */
325 SND_SOC_DAPM_AIF_IN("AIF1RX", "Analog Codec Playback", 0, SND_SOC_NOPM
, 0, 0),
326 SND_SOC_DAPM_AIF_IN("AIF2RX", "Digital Codec Playback", 0, SND_SOC_NOPM
, 0, 0),
327 SND_SOC_DAPM_AIF_IN("AIF3RX", "Alt Analog Codec Playback", 0, SND_SOC_NOPM
, 0, 0),
328 SND_SOC_DAPM_AIF_OUT("AIF1TX", "Analog Codec Capture", 0, SND_SOC_NOPM
, 0, 0),
329 SND_SOC_DAPM_AIF_OUT("AIF2TX", "Digital Codec Capture", 0, SND_SOC_NOPM
, 0, 0),
330 SND_SOC_DAPM_AIF_OUT("AIF3TX", "Alt Analog Codec Capture", 0, SND_SOC_NOPM
, 0, 0),
333 SND_SOC_DAPM_INPUT("Codec Input Pin1"),
334 SND_SOC_DAPM_INPUT("Codec Input Pin2"),
335 SND_SOC_DAPM_INPUT("Codec Input Pin3"),
338 SND_SOC_DAPM_OUTPUT("Codec Output Pin1"),
339 SND_SOC_DAPM_OUTPUT("Codec Output Pin2"),
340 SND_SOC_DAPM_OUTPUT("Codec Output Pin3"),
343 static struct snd_soc_dai_driver card_binder_dai
= {
345 .name
= "codec-probing-DAI",
348 static int hda_hdev_attach(struct hdac_device
*hdev
)
350 struct hda_codec
*codec
= dev_to_hda_codec(&hdev
->dev
);
351 struct snd_soc_component_driver
*comp_drv
;
353 if (hda_codec_is_display(codec
) && !hdev
->bus
->audio_component
) {
354 dev_dbg(&hdev
->dev
, "no i915, skip registration for 0x%08x\n", hdev
->vendor_id
);
358 comp_drv
= devm_kzalloc(&hdev
->dev
, sizeof(*comp_drv
), GFP_KERNEL
);
363 * It's save to rely on dev_name() rather than a copy as component
364 * driver's lifetime is directly tied to hda codec one
366 comp_drv
->name
= dev_name(&hdev
->dev
);
367 comp_drv
->probe
= hda_codec_probe
;
368 comp_drv
->remove
= hda_codec_remove
;
369 comp_drv
->idle_bias_on
= false;
370 if (!hda_codec_is_display(codec
)) {
371 comp_drv
->dapm_widgets
= hda_dapm_widgets
;
372 comp_drv
->num_dapm_widgets
= ARRAY_SIZE(hda_dapm_widgets
);
373 comp_drv
->dapm_routes
= hda_dapm_routes
;
374 comp_drv
->num_dapm_routes
= ARRAY_SIZE(hda_dapm_routes
);
377 return snd_soc_register_component(&hdev
->dev
, comp_drv
, &card_binder_dai
, 1);
380 static int hda_hdev_detach(struct hdac_device
*hdev
)
382 struct hda_codec
*codec
= dev_to_hda_codec(&hdev
->dev
);
384 if (codec
->core
.registered
)
385 cancel_delayed_work_sync(&codec
->jackpoll_work
);
387 snd_soc_unregister_component(&hdev
->dev
);
392 const struct hdac_ext_bus_ops soc_hda_ext_bus_ops
= {
393 .hdev_attach
= hda_hdev_attach
,
394 .hdev_detach
= hda_hdev_detach
,
396 EXPORT_SYMBOL_GPL(soc_hda_ext_bus_ops
);
398 MODULE_DESCRIPTION("HD-Audio codec driver");
399 MODULE_AUTHOR("Cezary Rojewski <cezary.rojewski@intel.com>");
400 MODULE_LICENSE("GPL");