• Home
  • Raw
  • Download

Lines Matching +full:dai +full:- +full:format

1 // SPDX-License-Identifier: GPL-2.0-only
3 * skl-pcm.c -ASoC HDA Platform driver file implementing PCM functionality
5 * Copyright (C) 2014-2015 Intel Corp
19 #include "skl-topology.h"
20 #include "skl-sst-dsp.h"
21 #include "skl-sst-ipc.h"
59 return substream->runtime->private_data; in get_hdac_ext_stream()
66 struct hdac_bus *bus = hstream->bus; in get_bus_ctx()
76 hdac_stream(stream)->bufsize = 0; in skl_substream_alloc_pages()
77 hdac_stream(stream)->period_bytes = 0; in skl_substream_alloc_pages()
78 hdac_stream(stream)->format_val = 0; in skl_substream_alloc_pages()
88 /* avoid wrap-around with wall-clock */ in skl_set_pcm_constrains()
95 if (bus->ppcap) in skl_get_host_stream_type()
109 struct snd_soc_dai *dai, bool enable) in skl_set_suspend_active() argument
111 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_set_suspend_active()
115 w = snd_soc_dai_get_widget(dai, substream->stream); in skl_set_suspend_active()
117 if (w->ignore_suspend && enable) in skl_set_suspend_active()
118 skl->supend_active++; in skl_set_suspend_active()
119 else if (w->ignore_suspend && !enable) in skl_set_suspend_active()
120 skl->supend_active--; in skl_set_suspend_active()
132 hstream = snd_hdac_get_stream(bus, params->stream, in skl_pcm_host_dma_prepare()
133 params->host_dma_id + 1); in skl_pcm_host_dma_prepare()
135 return -EINVAL; in skl_pcm_host_dma_prepare()
140 format_val = snd_hdac_calc_stream_format(params->s_freq, in skl_pcm_host_dma_prepare()
141 params->ch, params->format, params->host_bps, 0); in skl_pcm_host_dma_prepare()
143 dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n", in skl_pcm_host_dma_prepare()
144 format_val, params->s_freq, params->ch, params->format); in skl_pcm_host_dma_prepare()
153 * platforms is to couple the stream before writing the format in skl_pcm_host_dma_prepare()
155 if (IS_BXT(skl->pci)) { in skl_pcm_host_dma_prepare()
166 hdac_stream(stream)->prepared = 1; in skl_pcm_host_dma_prepare()
180 hstream = snd_hdac_get_stream(bus, params->stream, in skl_pcm_link_dma_prepare()
181 params->link_dma_id + 1); in skl_pcm_link_dma_prepare()
183 return -EINVAL; in skl_pcm_link_dma_prepare()
187 format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch, in skl_pcm_link_dma_prepare()
188 params->format, params->link_bps, 0); in skl_pcm_link_dma_prepare()
190 dev_dbg(dev, "format_val=%d, rate=%d, ch=%d, format=%d\n", in skl_pcm_link_dma_prepare()
191 format_val, params->s_freq, params->ch, params->format); in skl_pcm_link_dma_prepare()
197 stream_tag = hstream->stream_tag; in skl_pcm_link_dma_prepare()
198 if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) { in skl_pcm_link_dma_prepare()
199 list_for_each_entry(link, &bus->hlink_list, list) { in skl_pcm_link_dma_prepare()
200 if (link->index == params->link_index) in skl_pcm_link_dma_prepare()
206 stream->link_prepared = 1; in skl_pcm_link_dma_prepare()
212 struct snd_soc_dai *dai) in skl_pcm_open() argument
214 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_pcm_open()
216 struct snd_pcm_runtime *runtime = substream->runtime; in skl_pcm_open()
218 struct skl_dev *skl = get_skl_ctx(dai->dev); in skl_pcm_open()
221 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_pcm_open()
226 return -EBUSY; in skl_pcm_open()
234 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in skl_pcm_open()
235 runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; /* legacy */ in skl_pcm_open()
236 runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_LINK_ATIME; in skl_pcm_open()
239 runtime->private_data = stream; in skl_pcm_open()
243 return -ENOMEM; in skl_pcm_open()
245 dma_params->stream_tag = hdac_stream(stream)->stream_tag; in skl_pcm_open()
246 snd_soc_dai_set_dma_data(dai, substream, dma_params); in skl_pcm_open()
248 dev_dbg(dai->dev, "stream tag set in dma params=%d\n", in skl_pcm_open()
249 dma_params->stream_tag); in skl_pcm_open()
250 skl_set_suspend_active(substream, dai, true); in skl_pcm_open()
253 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); in skl_pcm_open()
255 return -EINVAL; in skl_pcm_open()
257 skl_tplg_d0i3_get(skl, mconfig->d0i3_caps); in skl_pcm_open()
263 struct snd_soc_dai *dai) in skl_pcm_prepare() argument
265 struct skl_dev *skl = get_skl_ctx(dai->dev); in skl_pcm_prepare()
269 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_pcm_prepare()
271 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); in skl_pcm_prepare()
278 (substream->runtime->status->state == SNDRV_PCM_STATE_XRUN || in skl_pcm_prepare()
279 mconfig->pipe->state == SKL_PIPE_CREATED || in skl_pcm_prepare()
280 mconfig->pipe->state == SKL_PIPE_PAUSED)) { in skl_pcm_prepare()
282 ret = skl_reset_pipe(skl, mconfig->pipe); in skl_pcm_prepare()
287 ret = skl_pcm_host_dma_prepare(dai->dev, in skl_pcm_prepare()
288 mconfig->pipe->p_params); in skl_pcm_prepare()
298 struct snd_soc_dai *dai) in skl_pcm_hw_params() argument
300 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_pcm_hw_params()
302 struct snd_pcm_runtime *runtime = substream->runtime; in skl_pcm_hw_params()
307 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_pcm_hw_params()
313 dev_dbg(dai->dev, "format_val, rate=%d, ch=%d, format=%d\n", in skl_pcm_hw_params()
314 runtime->rate, runtime->channels, runtime->format); in skl_pcm_hw_params()
316 dma_id = hdac_stream(stream)->stream_tag - 1; in skl_pcm_hw_params()
317 dev_dbg(dai->dev, "dma_id=%d\n", dma_id); in skl_pcm_hw_params()
323 p_params.stream = substream->stream; in skl_pcm_hw_params()
324 p_params.format = params_format(params); in skl_pcm_hw_params()
325 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in skl_pcm_hw_params()
326 p_params.host_bps = dai->driver->playback.sig_bits; in skl_pcm_hw_params()
328 p_params.host_bps = dai->driver->capture.sig_bits; in skl_pcm_hw_params()
331 m_cfg = skl_tplg_fe_get_cpr_module(dai, p_params.stream); in skl_pcm_hw_params()
333 skl_tplg_update_pipe_params(dai->dev, m_cfg, &p_params); in skl_pcm_hw_params()
339 struct snd_soc_dai *dai) in skl_pcm_close() argument
342 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_pcm_close()
347 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_pcm_close()
351 dma_params = snd_soc_dai_get_dma_data(dai, substream); in skl_pcm_close()
356 snd_soc_dai_set_dma_data(dai, substream, NULL); in skl_pcm_close()
357 skl_set_suspend_active(substream, dai, false); in skl_pcm_close()
363 if (!strncmp(dai->name, "Reference Pin", 13) && in skl_pcm_close()
364 skl->miscbdcg_disabled) { in skl_pcm_close()
365 skl->enable_miscbdcge(dai->dev, true); in skl_pcm_close()
366 skl->miscbdcg_disabled = false; in skl_pcm_close()
369 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); in skl_pcm_close()
371 skl_tplg_d0i3_put(skl, mconfig->d0i3_caps); in skl_pcm_close()
377 struct snd_soc_dai *dai) in skl_pcm_hw_free() argument
380 struct skl_dev *skl = get_skl_ctx(dai->dev); in skl_pcm_hw_free()
384 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_pcm_hw_free()
386 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); in skl_pcm_hw_free()
389 ret = skl_reset_pipe(skl, mconfig->pipe); in skl_pcm_hw_free()
391 dev_err(dai->dev, "%s:Reset failed ret =%d", in skl_pcm_hw_free()
396 hdac_stream(stream)->prepared = 0; in skl_pcm_hw_free()
403 struct snd_soc_dai *dai) in skl_be_hw_params() argument
410 p_params.stream = substream->stream; in skl_be_hw_params()
412 return skl_tplg_be_update_params(dai, &p_params); in skl_be_hw_params()
427 if (!hstr->prepared) in skl_decoupled_trigger()
428 return -EPIPE; in skl_decoupled_trigger()
444 return -EINVAL; in skl_decoupled_trigger()
447 spin_lock_irqsave(&bus->reg_lock, cookie); in skl_decoupled_trigger()
456 spin_unlock_irqrestore(&bus->reg_lock, cookie); in skl_decoupled_trigger()
462 struct snd_soc_dai *dai) in skl_pcm_trigger() argument
464 struct skl_dev *skl = get_skl_ctx(dai->dev); in skl_pcm_trigger()
471 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); in skl_pcm_trigger()
473 return -EIO; in skl_pcm_trigger()
475 w = snd_soc_dai_get_widget(dai, substream->stream); in skl_pcm_trigger()
479 if (!w->ignore_suspend) { in skl_pcm_trigger()
486 hdac_stream(stream)->index); in skl_pcm_trigger()
488 stream->lpib); in skl_pcm_trigger()
489 snd_hdac_ext_stream_set_lpib(stream, stream->lpib); in skl_pcm_trigger()
504 return skl_run_pipe(skl, mconfig->pipe); in skl_pcm_trigger()
515 ret = skl_stop_pipe(skl, mconfig->pipe); in skl_pcm_trigger()
520 if ((cmd == SNDRV_PCM_TRIGGER_SUSPEND) && !w->ignore_suspend) { in skl_pcm_trigger()
522 stream->dpib = readl(bus->remap_addr + in skl_pcm_trigger()
525 hdac_stream(stream)->index)); in skl_pcm_trigger()
527 stream->lpib = snd_hdac_stream_get_pos_lpib( in skl_pcm_trigger()
534 return -EINVAL; in skl_pcm_trigger()
543 struct snd_soc_dai *dai) in skl_link_hw_params() argument
545 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_link_hw_params()
556 return -EBUSY; in skl_link_hw_params()
558 snd_soc_dai_set_dma_data(dai, substream, (void *)link_dev); in skl_link_hw_params()
560 link = snd_hdac_ext_bus_get_link(bus, codec_dai->component->name); in skl_link_hw_params()
562 return -EINVAL; in skl_link_hw_params()
564 stream_tag = hdac_stream(link_dev)->stream_tag; in skl_link_hw_params()
566 /* set the stream tag in the codec dai dma params */ in skl_link_hw_params()
567 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in skl_link_hw_params()
575 p_params.stream = substream->stream; in skl_link_hw_params()
576 p_params.link_dma_id = stream_tag - 1; in skl_link_hw_params()
577 p_params.link_index = link->index; in skl_link_hw_params()
578 p_params.format = params_format(params); in skl_link_hw_params()
580 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in skl_link_hw_params()
581 p_params.link_bps = codec_dai->driver->playback.sig_bits; in skl_link_hw_params()
583 p_params.link_bps = codec_dai->driver->capture.sig_bits; in skl_link_hw_params()
585 return skl_tplg_be_update_params(dai, &p_params); in skl_link_hw_params()
589 struct snd_soc_dai *dai) in skl_link_pcm_prepare() argument
591 struct skl_dev *skl = get_skl_ctx(dai->dev); in skl_link_pcm_prepare()
595 mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream); in skl_link_pcm_prepare()
596 if (mconfig && !mconfig->pipe->passthru && in skl_link_pcm_prepare()
597 (substream->runtime->status->state == SNDRV_PCM_STATE_XRUN)) in skl_link_pcm_prepare()
598 skl_reset_pipe(skl, mconfig->pipe); in skl_link_pcm_prepare()
604 int cmd, struct snd_soc_dai *dai) in skl_link_pcm_trigger() argument
607 snd_soc_dai_get_dma_data(dai, substream); in skl_link_pcm_trigger()
611 dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd); in skl_link_pcm_trigger()
628 return -EINVAL; in skl_link_pcm_trigger()
634 struct snd_soc_dai *dai) in skl_link_hw_free() argument
636 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_link_hw_free()
639 snd_soc_dai_get_dma_data(dai, substream); in skl_link_hw_free()
643 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_link_hw_free()
645 link_dev->link_prepared = 0; in skl_link_hw_free()
647 link = snd_hdac_ext_bus_get_link(bus, asoc_rtd_to_codec(rtd, 0)->component->name); in skl_link_hw_free()
649 return -EINVAL; in skl_link_hw_free()
651 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in skl_link_hw_free()
652 stream_tag = hdac_stream(link_dev)->stream_tag; in skl_link_hw_free()
1001 .name = "Analog CPU DAI",
1021 .name = "Alt Analog CPU DAI",
1041 .name = "Digital CPU DAI",
1064 struct snd_soc_tplg_pcm *pcm, struct snd_soc_dai *dai) in skl_dai_load() argument
1066 dai_drv->ops = &skl_pcm_dai_ops; in skl_dai_load()
1075 struct snd_soc_dai_link *dai_link = rtd->dai_link; in skl_platform_soc_open()
1077 dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "In %s:%s\n", __func__, in skl_platform_soc_open()
1078 dai_link->cpus->dai_name); in skl_platform_soc_open()
1099 dev_dbg(bus->dev, "In %s cmd=%d\n", __func__, cmd); in skl_coupled_trigger()
1101 if (!hstr->prepared) in skl_coupled_trigger()
1102 return -EPIPE; in skl_coupled_trigger()
1118 return -EINVAL; in skl_coupled_trigger()
1122 if (s->pcm->card != substream->pcm->card) in skl_coupled_trigger()
1125 sbits |= 1 << hdac_stream(stream)->index; in skl_coupled_trigger()
1129 spin_lock_irqsave(&bus->reg_lock, cookie); in skl_coupled_trigger()
1135 if (s->pcm->card != substream->pcm->card) in skl_coupled_trigger()
1143 spin_unlock_irqrestore(&bus->reg_lock, cookie); in skl_coupled_trigger()
1147 spin_lock_irqsave(&bus->reg_lock, cookie); in skl_coupled_trigger()
1153 spin_unlock_irqrestore(&bus->reg_lock, cookie); in skl_coupled_trigger()
1164 if (!bus->ppcap) in skl_platform_soc_trigger()
1179 * Use DPIB for Playback stream as the periodic DMA Position-in- in skl_platform_soc_pointer()
1195 * 3. Read the DMA Position-in-Buffer. This value now will be equal to in skl_platform_soc_pointer()
1199 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in skl_platform_soc_pointer()
1200 pos = readl(bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE + in skl_platform_soc_pointer()
1202 hdac_stream(hstream)->index)); in skl_platform_soc_pointer()
1205 readl(bus->remap_addr + in skl_platform_soc_pointer()
1208 hdac_stream(hstream)->index)); in skl_platform_soc_pointer()
1212 if (pos >= hdac_stream(hstream)->bufsize) in skl_platform_soc_pointer()
1215 return bytes_to_frames(substream->runtime, pos); in skl_platform_soc_pointer()
1232 if (!codec_dai->driver->ops->delay) in skl_adjust_codec_delay()
1235 codec_frames = codec_dai->driver->ops->delay(substream, codec_dai); in skl_adjust_codec_delay()
1237 substream->runtime->rate); in skl_adjust_codec_delay()
1239 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) in skl_adjust_codec_delay()
1242 return (nsec > codec_nsecs) ? nsec - codec_nsecs : 0; in skl_adjust_codec_delay()
1256 if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) && in skl_platform_soc_get_time_info()
1257 (audio_tstamp_config->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK)) { in skl_platform_soc_get_time_info()
1259 snd_pcm_gettime(substream->runtime, system_ts); in skl_platform_soc_get_time_info()
1261 nsec = timecounter_read(&hstr->tc); in skl_platform_soc_get_time_info()
1263 if (audio_tstamp_config->report_delay) in skl_platform_soc_get_time_info()
1268 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK; in skl_platform_soc_get_time_info()
1269 audio_tstamp_report->accuracy_report = 1; /* rest of struct is valid */ in skl_platform_soc_get_time_info()
1270 audio_tstamp_report->accuracy = 42; /* 24MHzWallClk == 42ns resolution */ in skl_platform_soc_get_time_info()
1273 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT; in skl_platform_soc_get_time_info()
1284 struct snd_soc_dai *dai = asoc_rtd_to_cpu(rtd, 0); in skl_platform_soc_new() local
1285 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_platform_soc_new()
1286 struct snd_pcm *pcm = rtd->pcm; in skl_platform_soc_new()
1290 if (dai->driver->playback.channels_min || in skl_platform_soc_new()
1291 dai->driver->capture.channels_min) { in skl_platform_soc_new()
1292 /* buffer pre-allocation */ in skl_platform_soc_new()
1298 &skl->pci->dev, in skl_platform_soc_new()
1312 int i, ret = -EIO; in skl_get_module_info()
1314 uuid_mod = (guid_t *)mconfig->guid; in skl_get_module_info()
1316 if (list_empty(&skl->uuid_list)) { in skl_get_module_info()
1317 dev_err(skl->dev, "Module list is empty\n"); in skl_get_module_info()
1318 return -EIO; in skl_get_module_info()
1321 for (i = 0; i < skl->nr_modules; i++) { in skl_get_module_info()
1322 skl_module = skl->modules[i]; in skl_get_module_info()
1323 uuid_tplg = &skl_module->uuid; in skl_get_module_info()
1325 mconfig->module = skl_module; in skl_get_module_info()
1331 if (skl->nr_modules && ret) in skl_get_module_info()
1334 ret = -EIO; in skl_get_module_info()
1335 list_for_each_entry(module, &skl->uuid_list, list) { in skl_get_module_info()
1336 if (guid_equal(uuid_mod, &module->uuid)) { in skl_get_module_info()
1337 mconfig->id.module_id = module->id; in skl_get_module_info()
1338 mconfig->module->loadable = module->is_loadable; in skl_get_module_info()
1343 pin_id = &mconfig->m_in_pin[i].id; in skl_get_module_info()
1344 if (guid_equal(&pin_id->mod_uuid, &module->uuid)) in skl_get_module_info()
1345 pin_id->module_id = module->id; in skl_get_module_info()
1349 pin_id = &mconfig->m_out_pin[i].id; in skl_get_module_info()
1350 if (guid_equal(&pin_id->mod_uuid, &module->uuid)) in skl_get_module_info()
1351 pin_id->module_id = module->id; in skl_get_module_info()
1366 list_for_each_entry(p, &skl->ppl_list, node) { in skl_populate_modules()
1367 list_for_each_entry(m, &p->pipe->w_list, node) { in skl_populate_modules()
1368 w = m->w; in skl_populate_modules()
1369 mconfig = w->priv; in skl_populate_modules()
1373 dev_err(skl->dev, in skl_populate_modules()
1387 struct hdac_bus *bus = dev_get_drvdata(component->dev); in skl_platform_soc_probe()
1392 pm_runtime_get_sync(component->dev); in skl_platform_soc_probe()
1393 if (bus->ppcap) { in skl_platform_soc_probe()
1394 skl->component = component; in skl_platform_soc_probe()
1397 skl->debugfs = skl_debugfs_init(skl); in skl_platform_soc_probe()
1401 dev_err(component->dev, "Failed to init topology!\n"); in skl_platform_soc_probe()
1406 ops = skl_get_dsp_ops(skl->pci->device); in skl_platform_soc_probe()
1408 return -EIO; in skl_platform_soc_probe()
1414 skl->enable_miscbdcge(component->dev, false); in skl_platform_soc_probe()
1415 skl->clock_power_gating(component->dev, false); in skl_platform_soc_probe()
1417 ret = ops->init_fw(component->dev, skl); in skl_platform_soc_probe()
1418 skl->enable_miscbdcge(component->dev, true); in skl_platform_soc_probe()
1419 skl->clock_power_gating(component->dev, true); in skl_platform_soc_probe()
1421 dev_err(component->dev, "Failed to boot first fw: %d\n", ret); in skl_platform_soc_probe()
1425 skl->update_d0i3c = skl_update_d0i3c; in skl_platform_soc_probe()
1427 if (skl->cfg.astate_cfg != NULL) { in skl_platform_soc_probe()
1429 skl->cfg.astate_cfg->count, in skl_platform_soc_probe()
1430 skl->cfg.astate_cfg); in skl_platform_soc_probe()
1433 pm_runtime_mark_last_busy(component->dev); in skl_platform_soc_probe()
1434 pm_runtime_put_autosuspend(component->dev); in skl_platform_soc_probe()
1441 struct hdac_bus *bus = dev_get_drvdata(component->dev); in skl_platform_soc_remove()
1470 skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai), in skl_platform_register()
1472 if (!skl->dais) { in skl_platform_register()
1473 ret = -ENOMEM; in skl_platform_register()
1477 if (!skl->use_tplg_pcm) { in skl_platform_register()
1478 dais = krealloc(skl->dais, sizeof(skl_fe_dai) + in skl_platform_register()
1481 ret = -ENOMEM; in skl_platform_register()
1485 skl->dais = dais; in skl_platform_register()
1486 memcpy(&skl->dais[ARRAY_SIZE(skl_platform_dai)], skl_fe_dai, in skl_platform_register()
1492 skl->dais, num_dais); in skl_platform_register()
1505 list_for_each_entry_safe(modules, tmp, &skl->bind_list, node) { in skl_platform_unregister()
1506 list_del(&modules->node); in skl_platform_unregister()
1510 kfree(skl->dais); in skl_platform_unregister()