Lines Matching +full:codec +full:- +full:driver

1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright(c) 2021-2022 Intel Corporation
16 static int hda_codec_create_dais(struct hda_codec *codec, int pcm_count, in hda_codec_create_dais() argument
19 struct device *dev = &codec->core.dev; in hda_codec_create_dais()
26 return -ENOMEM; in hda_codec_create_dais()
28 pcm = list_first_entry(&codec->pcm_list_head, struct hda_pcm, list); in hda_codec_create_dais()
34 dev_info(dev, "creating for %s %d\n", pcm->name, i); in hda_codec_create_dais()
36 drvs[i].name = pcm->name; in hda_codec_create_dais()
41 if (!pcm->stream[dir].substreams) { in hda_codec_create_dais()
42 dev_info(dev, "skipping playback dai for %s\n", pcm->name); in hda_codec_create_dais()
46 stream->stream_name = in hda_codec_create_dais()
47 devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, in hda_codec_create_dais()
49 if (!stream->stream_name) in hda_codec_create_dais()
50 return -ENOMEM; in hda_codec_create_dais()
51 stream->channels_min = pcm->stream[dir].channels_min; in hda_codec_create_dais()
52 stream->channels_max = pcm->stream[dir].channels_max; in hda_codec_create_dais()
53 stream->rates = pcm->stream[dir].rates; in hda_codec_create_dais()
54 stream->formats = pcm->stream[dir].formats; in hda_codec_create_dais()
55 stream->subformats = pcm->stream[dir].subformats; in hda_codec_create_dais()
56 stream->sig_bits = pcm->stream[dir].maxbps; in hda_codec_create_dais()
61 if (!pcm->stream[dir].substreams) { in hda_codec_create_dais()
62 dev_info(dev, "skipping capture dai for %s\n", pcm->name); in hda_codec_create_dais()
66 stream->stream_name = in hda_codec_create_dais()
67 devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, in hda_codec_create_dais()
69 if (!stream->stream_name) in hda_codec_create_dais()
70 return -ENOMEM; in hda_codec_create_dais()
71 stream->channels_min = pcm->stream[dir].channels_min; in hda_codec_create_dais()
72 stream->channels_max = pcm->stream[dir].channels_max; in hda_codec_create_dais()
73 stream->rates = pcm->stream[dir].rates; in hda_codec_create_dais()
74 stream->formats = pcm->stream[dir].formats; in hda_codec_create_dais()
75 stream->subformats = pcm->stream[dir].subformats; in hda_codec_create_dais()
76 stream->sig_bits = pcm->stream[dir].maxbps; in hda_codec_create_dais()
83 static int hda_codec_register_dais(struct hda_codec *codec, struct snd_soc_component *component) in hda_codec_register_dais() argument
90 if (list_empty(&codec->pcm_list_head)) in hda_codec_register_dais()
91 return -EINVAL; in hda_codec_register_dais()
92 list_for_each_entry(pcm, &codec->pcm_list_head, list) in hda_codec_register_dais()
95 ret = hda_codec_create_dais(codec, pcm_count, &drvs); in hda_codec_register_dais()
101 list_for_each_entry(pcm, &codec->pcm_list_head, list) { in hda_codec_register_dais()
106 dev_err(component->dev, "register dai for %s failed\n", pcm->name); in hda_codec_register_dais()
107 return -EINVAL; in hda_codec_register_dais()
112 dev_err(component->dev, "create widgets failed: %d\n", ret); in hda_codec_register_dais()
117 snd_soc_dai_init_dma_data(dai, &pcm->stream[0], &pcm->stream[1]); in hda_codec_register_dais()
124 static void hda_codec_unregister_dais(struct hda_codec *codec, in hda_codec_unregister_dais() argument
133 list_for_each_entry(pcm, &codec->pcm_list_head, list) { in hda_codec_unregister_dais()
134 if (strcmp(dai->driver->name, pcm->name)) in hda_codec_unregister_dais()
146 int hda_codec_probe_complete(struct hda_codec *codec) in hda_codec_probe_complete() argument
148 struct hdac_device *hdev = &codec->core; in hda_codec_probe_complete()
149 struct hdac_bus *bus = hdev->bus; in hda_codec_probe_complete()
152 ret = snd_hda_codec_build_controls(codec); in hda_codec_probe_complete()
154 dev_err(&hdev->dev, "unable to create controls %d\n", ret); in hda_codec_probe_complete()
159 pm_runtime_set_active(&hdev->dev); in hda_codec_probe_complete()
161 snd_hda_codec_set_power_save(codec, 2000); in hda_codec_probe_complete()
162 snd_hda_codec_register(codec); in hda_codec_probe_complete()
165 pm_runtime_mark_last_busy(bus->dev); in hda_codec_probe_complete()
166 pm_runtime_put_autosuspend(bus->dev); in hda_codec_probe_complete()
172 /* Expects codec with usage_count=1 and status=suspended */
175 struct hda_codec *codec = dev_to_hda_codec(component->dev); in hda_codec_probe() local
176 struct hdac_device *hdev = &codec->core; in hda_codec_probe()
177 struct hdac_bus *bus = hdev->bus; in hda_codec_probe()
183 WARN_ON(atomic_read(&hdev->dev.power.usage_count) != 1 || in hda_codec_probe()
184 !pm_runtime_status_suspended(&hdev->dev)); in hda_codec_probe()
187 hlink = snd_hdac_ext_bus_get_hlink_by_addr(bus, hdev->addr); in hda_codec_probe()
189 dev_err(&hdev->dev, "hdac link not found\n"); in hda_codec_probe()
190 return -EIO; in hda_codec_probe()
193 pm_runtime_get_sync(bus->dev); in hda_codec_probe()
194 if (hda_codec_is_display(codec)) in hda_codec_probe()
195 snd_hdac_display_power(bus, hdev->addr, true); in hda_codec_probe()
198 ret = snd_hda_codec_device_new(codec->bus, component->card->snd_card, hdev->addr, codec, in hda_codec_probe()
201 dev_err(&hdev->dev, "codec create failed: %d\n", ret); in hda_codec_probe()
205 ret = snd_hda_codec_set_name(codec, codec->preset->name); in hda_codec_probe()
207 dev_err(&hdev->dev, "set name: %s failed: %d\n", codec->preset->name, ret); in hda_codec_probe()
211 ret = snd_hdac_regmap_init(&codec->core); in hda_codec_probe()
213 dev_err(&hdev->dev, "regmap init failed: %d\n", ret); in hda_codec_probe()
217 patch = (hda_codec_patch_t)codec->preset->driver_data; in hda_codec_probe()
219 dev_err(&hdev->dev, "no patch specified\n"); in hda_codec_probe()
220 ret = -EINVAL; in hda_codec_probe()
224 ret = patch(codec); in hda_codec_probe()
226 dev_err(&hdev->dev, "codec init failed: %d\n", ret); in hda_codec_probe()
230 ret = snd_hda_codec_parse_pcms(codec); in hda_codec_probe()
232 dev_err(&hdev->dev, "unable to map pcms to dai: %d\n", ret); in hda_codec_probe()
236 ret = hda_codec_register_dais(codec, component); in hda_codec_probe()
238 dev_err(&hdev->dev, "update dais failed: %d\n", ret); in hda_codec_probe()
242 if (!hda_codec_is_display(codec)) { in hda_codec_probe()
243 ret = hda_codec_probe_complete(codec); in hda_codec_probe()
248 codec->core.lazy_cache = true; in hda_codec_probe()
253 hda_codec_unregister_dais(codec, component); in hda_codec_probe()
255 if (codec->patch_ops.free) in hda_codec_probe()
256 codec->patch_ops.free(codec); in hda_codec_probe()
258 snd_hda_codec_cleanup_for_unbind(codec); in hda_codec_probe()
260 if (hda_codec_is_display(codec)) in hda_codec_probe()
261 snd_hdac_display_power(bus, hdev->addr, false); in hda_codec_probe()
265 pm_runtime_mark_last_busy(bus->dev); in hda_codec_probe()
266 pm_runtime_put_autosuspend(bus->dev); in hda_codec_probe()
270 /* Leaves codec with usage_count=1 and status=suspended */
273 struct hda_codec *codec = dev_to_hda_codec(component->dev); in hda_codec_remove() local
274 struct hdac_device *hdev = &codec->core; in hda_codec_remove()
275 struct hdac_bus *bus = hdev->bus; in hda_codec_remove()
277 bool was_registered = codec->core.registered; in hda_codec_remove()
280 pm_runtime_forbid(&hdev->dev); in hda_codec_remove()
282 hda_codec_unregister_dais(codec, component); in hda_codec_remove()
284 if (codec->patch_ops.free) in hda_codec_remove()
285 codec->patch_ops.free(codec); in hda_codec_remove()
287 snd_hda_codec_cleanup_for_unbind(codec); in hda_codec_remove()
288 pm_runtime_put_noidle(&hdev->dev); in hda_codec_remove()
290 pm_runtime_set_suspended(&hdev->dev); in hda_codec_remove()
292 if (hda_codec_is_display(codec)) in hda_codec_remove()
293 snd_hdac_display_power(bus, hdev->addr, false); in hda_codec_remove()
295 hlink = snd_hdac_ext_bus_get_hlink_by_addr(bus, hdev->addr); in hda_codec_remove()
303 pm_runtime_mark_last_busy(bus->dev); in hda_codec_remove()
304 pm_runtime_put_autosuspend(bus->dev); in hda_codec_remove()
308 WARN_ON(atomic_read(&hdev->dev.power.usage_count) != 1 || in hda_codec_remove()
309 !pm_runtime_status_suspended(&hdev->dev)); in hda_codec_remove()
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"},
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"),
344 .id = -1,
345 .name = "codec-probing-DAI",
350 struct hda_codec *codec = dev_to_hda_codec(&hdev->dev); in hda_hdev_attach() local
353 if (hda_codec_is_display(codec) && !hdev->bus->audio_component) { in hda_hdev_attach()
354 dev_dbg(&hdev->dev, "no i915, skip registration for 0x%08x\n", hdev->vendor_id); in hda_hdev_attach()
355 return -ENODEV; in hda_hdev_attach()
358 comp_drv = devm_kzalloc(&hdev->dev, sizeof(*comp_drv), GFP_KERNEL); in hda_hdev_attach()
360 return -ENOMEM; in hda_hdev_attach()
364 * driver's lifetime is directly tied to hda codec one in hda_hdev_attach()
366 comp_drv->name = dev_name(&hdev->dev); in hda_hdev_attach()
367 comp_drv->probe = hda_codec_probe; in hda_hdev_attach()
368 comp_drv->remove = hda_codec_remove; in hda_hdev_attach()
369 comp_drv->idle_bias_on = false; in hda_hdev_attach()
370 if (!hda_codec_is_display(codec)) { in hda_hdev_attach()
371 comp_drv->dapm_widgets = hda_dapm_widgets; in hda_hdev_attach()
372 comp_drv->num_dapm_widgets = ARRAY_SIZE(hda_dapm_widgets); in hda_hdev_attach()
373 comp_drv->dapm_routes = hda_dapm_routes; in hda_hdev_attach()
374 comp_drv->num_dapm_routes = ARRAY_SIZE(hda_dapm_routes); in hda_hdev_attach()
377 return snd_soc_register_component(&hdev->dev, comp_drv, &card_binder_dai, 1); in hda_hdev_attach()
382 struct hda_codec *codec = dev_to_hda_codec(&hdev->dev); in hda_hdev_detach() local
384 if (codec->core.registered) in hda_hdev_detach()
385 cancel_delayed_work_sync(&codec->jackpoll_work); in hda_hdev_detach()
387 snd_soc_unregister_component(&hdev->dev); in hda_hdev_detach()
398 MODULE_DESCRIPTION("HD-Audio codec driver");