Lines Matching +full:codec +full:- +full:1
1 // SPDX-License-Identifier: GPL-2.0
3 // Copyright(c) 2021-2022 Intel Corporation. All rights reserved.
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->sig_bits = pcm->stream[dir].maxbps; in hda_codec_create_dais()
60 if (!pcm->stream[dir].substreams) { in hda_codec_create_dais()
61 dev_info(dev, "skipping capture dai for %s\n", pcm->name); in hda_codec_create_dais()
65 stream->stream_name = in hda_codec_create_dais()
66 devm_kasprintf(dev, GFP_KERNEL, "%s %s", pcm->name, in hda_codec_create_dais()
68 if (!stream->stream_name) in hda_codec_create_dais()
69 return -ENOMEM; in hda_codec_create_dais()
70 stream->channels_min = pcm->stream[dir].channels_min; in hda_codec_create_dais()
71 stream->channels_max = pcm->stream[dir].channels_max; in hda_codec_create_dais()
72 stream->rates = pcm->stream[dir].rates; in hda_codec_create_dais()
73 stream->formats = pcm->stream[dir].formats; in hda_codec_create_dais()
74 stream->sig_bits = pcm->stream[dir].maxbps; in hda_codec_create_dais()
81 static int hda_codec_register_dais(struct hda_codec *codec, struct snd_soc_component *component) in hda_codec_register_dais() argument
88 if (list_empty(&codec->pcm_list_head)) in hda_codec_register_dais()
89 return -EINVAL; in hda_codec_register_dais()
90 list_for_each_entry(pcm, &codec->pcm_list_head, list) in hda_codec_register_dais()
93 ret = hda_codec_create_dais(codec, pcm_count, &drvs); in hda_codec_register_dais()
99 list_for_each_entry(pcm, &codec->pcm_list_head, list) { in hda_codec_register_dais()
104 dev_err(component->dev, "register dai for %s failed\n", pcm->name); in hda_codec_register_dais()
105 return -EINVAL; in hda_codec_register_dais()
110 dev_err(component->dev, "create widgets failed: %d\n", ret); in hda_codec_register_dais()
115 snd_soc_dai_init_dma_data(dai, &pcm->stream[0], &pcm->stream[1]); in hda_codec_register_dais()
122 static void hda_codec_unregister_dais(struct hda_codec *codec, in hda_codec_unregister_dais() argument
131 list_for_each_entry(pcm, &codec->pcm_list_head, list) { in hda_codec_unregister_dais()
132 if (strcmp(dai->driver->name, pcm->name)) in hda_codec_unregister_dais()
144 int hda_codec_probe_complete(struct hda_codec *codec) in hda_codec_probe_complete() argument
146 struct hdac_device *hdev = &codec->core; in hda_codec_probe_complete()
147 struct hdac_bus *bus = hdev->bus; in hda_codec_probe_complete()
150 ret = snd_hda_codec_build_controls(codec); in hda_codec_probe_complete()
152 dev_err(&hdev->dev, "unable to create controls %d\n", ret); in hda_codec_probe_complete()
157 pm_runtime_set_active(&hdev->dev); in hda_codec_probe_complete()
159 snd_hda_codec_set_power_save(codec, 2000); in hda_codec_probe_complete()
160 snd_hda_codec_register(codec); in hda_codec_probe_complete()
163 pm_runtime_mark_last_busy(bus->dev); in hda_codec_probe_complete()
164 pm_runtime_put_autosuspend(bus->dev); in hda_codec_probe_complete()
170 /* Expects codec with usage_count=1 and status=suspended */
173 struct hda_codec *codec = dev_to_hda_codec(component->dev); in hda_codec_probe() local
174 struct hdac_device *hdev = &codec->core; in hda_codec_probe()
175 struct hdac_bus *bus = hdev->bus; in hda_codec_probe()
181 WARN_ON(atomic_read(&hdev->dev.power.usage_count) != 1 || in hda_codec_probe()
182 !pm_runtime_status_suspended(&hdev->dev)); in hda_codec_probe()
185 hlink = snd_hdac_ext_bus_get_hlink_by_addr(bus, hdev->addr); in hda_codec_probe()
187 dev_err(&hdev->dev, "hdac link not found\n"); in hda_codec_probe()
188 return -EIO; in hda_codec_probe()
191 pm_runtime_get_sync(bus->dev); in hda_codec_probe()
192 if (hda_codec_is_display(codec)) in hda_codec_probe()
193 snd_hdac_display_power(bus, hdev->addr, true); in hda_codec_probe()
196 ret = snd_hda_codec_device_new(codec->bus, component->card->snd_card, hdev->addr, codec, in hda_codec_probe()
199 dev_err(&hdev->dev, "create hda codec failed: %d\n", ret); in hda_codec_probe()
203 ret = snd_hda_codec_set_name(codec, codec->preset->name); in hda_codec_probe()
205 dev_err(&hdev->dev, "name failed %s\n", codec->preset->name); in hda_codec_probe()
209 ret = snd_hdac_regmap_init(&codec->core); in hda_codec_probe()
211 dev_err(&hdev->dev, "regmap init failed\n"); in hda_codec_probe()
215 patch = (hda_codec_patch_t)codec->preset->driver_data; in hda_codec_probe()
217 dev_err(&hdev->dev, "no patch specified\n"); in hda_codec_probe()
218 ret = -EINVAL; in hda_codec_probe()
222 ret = patch(codec); in hda_codec_probe()
224 dev_err(&hdev->dev, "patch failed %d\n", ret); in hda_codec_probe()
228 ret = snd_hda_codec_parse_pcms(codec); in hda_codec_probe()
230 dev_err(&hdev->dev, "unable to map pcms to dai %d\n", ret); in hda_codec_probe()
234 ret = hda_codec_register_dais(codec, component); in hda_codec_probe()
236 dev_err(&hdev->dev, "update dais failed: %d\n", ret); in hda_codec_probe()
240 if (!hda_codec_is_display(codec)) { in hda_codec_probe()
241 ret = hda_codec_probe_complete(codec); in hda_codec_probe()
246 codec->core.lazy_cache = true; in hda_codec_probe()
251 hda_codec_unregister_dais(codec, component); in hda_codec_probe()
253 if (codec->patch_ops.free) in hda_codec_probe()
254 codec->patch_ops.free(codec); in hda_codec_probe()
256 snd_hda_codec_cleanup_for_unbind(codec); in hda_codec_probe()
258 if (hda_codec_is_display(codec)) in hda_codec_probe()
259 snd_hdac_display_power(bus, hdev->addr, false); in hda_codec_probe()
263 pm_runtime_mark_last_busy(bus->dev); in hda_codec_probe()
264 pm_runtime_put_autosuspend(bus->dev); in hda_codec_probe()
268 /* Leaves codec with usage_count=1 and status=suspended */
271 struct hda_codec *codec = dev_to_hda_codec(component->dev); in hda_codec_remove() local
272 struct hdac_device *hdev = &codec->core; in hda_codec_remove()
273 struct hdac_bus *bus = hdev->bus; in hda_codec_remove()
275 bool was_registered = codec->core.registered; in hda_codec_remove()
278 pm_runtime_forbid(&hdev->dev); in hda_codec_remove()
280 hda_codec_unregister_dais(codec, component); in hda_codec_remove()
282 if (codec->patch_ops.free) in hda_codec_remove()
283 codec->patch_ops.free(codec); in hda_codec_remove()
285 snd_hda_codec_cleanup_for_unbind(codec); in hda_codec_remove()
286 pm_runtime_put_noidle(&hdev->dev); in hda_codec_remove()
288 pm_runtime_set_suspended(&hdev->dev); in hda_codec_remove()
290 if (hda_codec_is_display(codec)) in hda_codec_remove()
291 snd_hdac_display_power(bus, hdev->addr, false); in hda_codec_remove()
293 hlink = snd_hdac_ext_bus_get_hlink_by_addr(bus, hdev->addr); in hda_codec_remove()
301 pm_runtime_mark_last_busy(bus->dev); in hda_codec_remove()
302 pm_runtime_put_autosuspend(bus->dev); in hda_codec_remove()
306 WARN_ON(atomic_read(&hdev->dev.power.usage_count) != 1 || in hda_codec_remove()
307 !pm_runtime_status_suspended(&hdev->dev)); in hda_codec_remove()
312 {"AIF1TX", NULL, "Codec Input Pin1"},
313 {"AIF2TX", NULL, "Codec Input Pin2"},
314 {"AIF3TX", NULL, "Codec Input Pin3"},
316 {"Codec Output Pin1", NULL, "AIF1RX"},
317 {"Codec Output Pin2", NULL, "AIF2RX"},
318 {"Codec Output Pin3", NULL, "AIF3RX"},
323 SND_SOC_DAPM_AIF_IN("AIF1RX", "Analog Codec Playback", 0, SND_SOC_NOPM, 0, 0),
324 SND_SOC_DAPM_AIF_IN("AIF2RX", "Digital Codec Playback", 0, SND_SOC_NOPM, 0, 0),
325 SND_SOC_DAPM_AIF_IN("AIF3RX", "Alt Analog Codec Playback", 0, SND_SOC_NOPM, 0, 0),
326 SND_SOC_DAPM_AIF_OUT("AIF1TX", "Analog Codec Capture", 0, SND_SOC_NOPM, 0, 0),
327 SND_SOC_DAPM_AIF_OUT("AIF2TX", "Digital Codec Capture", 0, SND_SOC_NOPM, 0, 0),
328 SND_SOC_DAPM_AIF_OUT("AIF3TX", "Alt Analog Codec Capture", 0, SND_SOC_NOPM, 0, 0),
331 SND_SOC_DAPM_INPUT("Codec Input Pin1"),
332 SND_SOC_DAPM_INPUT("Codec Input Pin2"),
333 SND_SOC_DAPM_INPUT("Codec Input Pin3"),
336 SND_SOC_DAPM_OUTPUT("Codec Output Pin1"),
337 SND_SOC_DAPM_OUTPUT("Codec Output Pin2"),
338 SND_SOC_DAPM_OUTPUT("Codec Output Pin3"),
342 .id = -1,
343 .name = "codec-probing-DAI",
348 struct hda_codec *codec = dev_to_hda_codec(&hdev->dev); in hda_hdev_attach() local
351 comp_drv = devm_kzalloc(&hdev->dev, sizeof(*comp_drv), GFP_KERNEL); in hda_hdev_attach()
353 return -ENOMEM; in hda_hdev_attach()
357 * driver's lifetime is directly tied to hda codec one in hda_hdev_attach()
359 comp_drv->name = dev_name(&hdev->dev); in hda_hdev_attach()
360 comp_drv->probe = hda_codec_probe; in hda_hdev_attach()
361 comp_drv->remove = hda_codec_remove; in hda_hdev_attach()
362 comp_drv->idle_bias_on = false; in hda_hdev_attach()
363 if (!hda_codec_is_display(codec)) { in hda_hdev_attach()
364 comp_drv->dapm_widgets = hda_dapm_widgets; in hda_hdev_attach()
365 comp_drv->num_dapm_widgets = ARRAY_SIZE(hda_dapm_widgets); in hda_hdev_attach()
366 comp_drv->dapm_routes = hda_dapm_routes; in hda_hdev_attach()
367 comp_drv->num_dapm_routes = ARRAY_SIZE(hda_dapm_routes); in hda_hdev_attach()
370 return snd_soc_register_component(&hdev->dev, comp_drv, &card_binder_dai, 1); in hda_hdev_attach()
375 struct hda_codec *codec = dev_to_hda_codec(&hdev->dev); in hda_hdev_detach() local
377 if (codec->core.registered) in hda_hdev_detach()
378 cancel_delayed_work_sync(&codec->jackpoll_work); in hda_hdev_detach()
380 snd_soc_unregister_component(&hdev->dev); in hda_hdev_detach()
391 MODULE_DESCRIPTION("HD-Audio codec driver");