Lines Matching +full:dmic01 +full:- +full:state

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
20 #include "skl-topology.h"
21 #include "skl-sst-dsp.h"
22 #include "skl-sst-ipc.h"
60 return substream->runtime->private_data; in get_hdac_ext_stream()
67 struct hdac_bus *bus = hstream->bus; in get_bus_ctx()
77 hdac_stream(stream)->bufsize = 0; in skl_substream_alloc_pages()
78 hdac_stream(stream)->period_bytes = 0; in skl_substream_alloc_pages()
79 hdac_stream(stream)->format_val = 0; in skl_substream_alloc_pages()
89 /* avoid wrap-around with wall-clock */ in skl_set_pcm_constrains()
96 if (bus->ppcap) in skl_get_host_stream_type()
112 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_set_suspend_active()
116 w = snd_soc_dai_get_widget(dai, substream->stream); in skl_set_suspend_active()
118 if (w->ignore_suspend && enable) in skl_set_suspend_active()
119 skl->supend_active++; in skl_set_suspend_active()
120 else if (w->ignore_suspend && !enable) in skl_set_suspend_active()
121 skl->supend_active--; in skl_set_suspend_active()
133 hstream = snd_hdac_get_stream(bus, params->stream, in skl_pcm_host_dma_prepare()
134 params->host_dma_id + 1); in skl_pcm_host_dma_prepare()
136 return -EINVAL; in skl_pcm_host_dma_prepare()
141 format_val = snd_hdac_calc_stream_format(params->s_freq, in skl_pcm_host_dma_prepare()
142 params->ch, params->format, params->host_bps, 0); in skl_pcm_host_dma_prepare()
145 format_val, params->s_freq, params->ch, params->format); in skl_pcm_host_dma_prepare()
156 if (HDA_CONTROLLER_IS_APL(skl->pci)) { in skl_pcm_host_dma_prepare()
167 hdac_stream(stream)->prepared = 1; in skl_pcm_host_dma_prepare()
181 hstream = snd_hdac_get_stream(bus, params->stream, in skl_pcm_link_dma_prepare()
182 params->link_dma_id + 1); in skl_pcm_link_dma_prepare()
184 return -EINVAL; in skl_pcm_link_dma_prepare()
188 format_val = snd_hdac_calc_stream_format(params->s_freq, params->ch, in skl_pcm_link_dma_prepare()
189 params->format, params->link_bps, 0); in skl_pcm_link_dma_prepare()
192 format_val, params->s_freq, params->ch, params->format); in skl_pcm_link_dma_prepare()
198 stream_tag = hstream->stream_tag; in skl_pcm_link_dma_prepare()
199 if (stream->hstream.direction == SNDRV_PCM_STREAM_PLAYBACK) { in skl_pcm_link_dma_prepare()
200 list_for_each_entry(link, &bus->hlink_list, list) { in skl_pcm_link_dma_prepare()
201 if (link->index == params->link_index) in skl_pcm_link_dma_prepare()
207 stream->link_prepared = 1; in skl_pcm_link_dma_prepare()
215 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_pcm_open()
217 struct snd_pcm_runtime *runtime = substream->runtime; in skl_pcm_open()
219 struct skl_dev *skl = get_skl_ctx(dai->dev); in skl_pcm_open()
222 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_pcm_open()
227 return -EBUSY; in skl_pcm_open()
235 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { in skl_pcm_open()
236 runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_WALL_CLOCK; /* legacy */ in skl_pcm_open()
237 runtime->hw.info &= ~SNDRV_PCM_INFO_HAS_LINK_ATIME; in skl_pcm_open()
240 runtime->private_data = stream; in skl_pcm_open()
244 return -ENOMEM; in skl_pcm_open()
246 dma_params->stream_tag = hdac_stream(stream)->stream_tag; in skl_pcm_open()
249 dev_dbg(dai->dev, "stream tag set in dma params=%d\n", in skl_pcm_open()
250 dma_params->stream_tag); in skl_pcm_open()
254 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); in skl_pcm_open()
257 return -EINVAL; in skl_pcm_open()
260 skl_tplg_d0i3_get(skl, mconfig->d0i3_caps); in skl_pcm_open()
268 struct skl_dev *skl = get_skl_ctx(dai->dev); in skl_pcm_prepare()
272 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_pcm_prepare()
274 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); in skl_pcm_prepare()
278 * calls prepare another time, reset the FW pipe to clean state in skl_pcm_prepare()
281 (substream->runtime->state == SNDRV_PCM_STATE_XRUN || in skl_pcm_prepare()
282 mconfig->pipe->state == SKL_PIPE_CREATED || in skl_pcm_prepare()
283 mconfig->pipe->state == SKL_PIPE_PAUSED)) { in skl_pcm_prepare()
285 ret = skl_reset_pipe(skl, mconfig->pipe); in skl_pcm_prepare()
290 ret = skl_pcm_host_dma_prepare(dai->dev, in skl_pcm_prepare()
291 mconfig->pipe->p_params); in skl_pcm_prepare()
303 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_pcm_hw_params()
305 struct snd_pcm_runtime *runtime = substream->runtime; in skl_pcm_hw_params()
310 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_pcm_hw_params()
316 dev_dbg(dai->dev, "format_val, rate=%d, ch=%d, format=%d\n", in skl_pcm_hw_params()
317 runtime->rate, runtime->channels, runtime->format); in skl_pcm_hw_params()
319 dma_id = hdac_stream(stream)->stream_tag - 1; in skl_pcm_hw_params()
320 dev_dbg(dai->dev, "dma_id=%d\n", dma_id); in skl_pcm_hw_params()
327 p_params.stream = substream->stream; in skl_pcm_hw_params()
329 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in skl_pcm_hw_params()
330 p_params.host_bps = dai->driver->playback.sig_bits; in skl_pcm_hw_params()
332 p_params.host_bps = dai->driver->capture.sig_bits; in skl_pcm_hw_params()
337 skl_tplg_update_pipe_params(dai->dev, m_cfg, &p_params); in skl_pcm_hw_params()
346 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_pcm_close()
351 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_pcm_close()
367 if (!strncmp(dai->name, "Reference Pin", 13) && in skl_pcm_close()
368 skl->miscbdcg_disabled) { in skl_pcm_close()
369 skl->enable_miscbdcge(dai->dev, true); in skl_pcm_close()
370 skl->miscbdcg_disabled = false; in skl_pcm_close()
373 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); in skl_pcm_close()
375 skl_tplg_d0i3_put(skl, mconfig->d0i3_caps); in skl_pcm_close()
384 struct skl_dev *skl = get_skl_ctx(dai->dev); in skl_pcm_hw_free()
388 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_pcm_hw_free()
390 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); in skl_pcm_hw_free()
393 ret = skl_reset_pipe(skl, mconfig->pipe); in skl_pcm_hw_free()
395 dev_err(dai->dev, "%s:Reset failed ret =%d", in skl_pcm_hw_free()
400 hdac_stream(stream)->prepared = 0; in skl_pcm_hw_free()
415 p_params.stream = substream->stream; in skl_be_hw_params()
432 if (!hstr->prepared) in skl_decoupled_trigger()
433 return -EPIPE; in skl_decoupled_trigger()
449 return -EINVAL; in skl_decoupled_trigger()
452 spin_lock_irqsave(&bus->reg_lock, cookie); in skl_decoupled_trigger()
461 spin_unlock_irqrestore(&bus->reg_lock, cookie); in skl_decoupled_trigger()
469 struct skl_dev *skl = get_skl_ctx(dai->dev); in skl_pcm_trigger()
477 mconfig = skl_tplg_fe_get_cpr_module(dai, substream->stream); in skl_pcm_trigger()
479 return -EIO; in skl_pcm_trigger()
481 w = snd_soc_dai_get_widget(dai, substream->stream); in skl_pcm_trigger()
485 if (!w->ignore_suspend) { in skl_pcm_trigger()
491 snd_hdac_stream_drsm_enable(bus, true, hstream->index); in skl_pcm_trigger()
492 snd_hdac_stream_set_dpibr(bus, hstream, hstream->lpib); in skl_pcm_trigger()
493 snd_hdac_stream_set_lpib(hstream, hstream->lpib); in skl_pcm_trigger()
508 return skl_run_pipe(skl, mconfig->pipe); in skl_pcm_trigger()
518 ret = skl_stop_pipe(skl, mconfig->pipe); in skl_pcm_trigger()
523 if ((cmd == SNDRV_PCM_TRIGGER_SUSPEND) && !w->ignore_suspend) { in skl_pcm_trigger()
525 hstream->dpib = readl(bus->remap_addr + in skl_pcm_trigger()
528 hstream->index)); in skl_pcm_trigger()
530 hstream->lpib = snd_hdac_stream_get_pos_lpib(hstream); in skl_pcm_trigger()
537 return -EINVAL; in skl_pcm_trigger()
548 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_link_hw_params()
559 return -EBUSY; in skl_link_hw_params()
563 link = snd_hdac_ext_bus_get_hlink_by_name(bus, codec_dai->component->name); in skl_link_hw_params()
565 return -EINVAL; in skl_link_hw_params()
567 stream_tag = hdac_stream(link_dev)->stream_tag; in skl_link_hw_params()
570 snd_soc_dai_set_stream(codec_dai, hdac_stream(link_dev), substream->stream); in skl_link_hw_params()
576 p_params.stream = substream->stream; in skl_link_hw_params()
577 p_params.link_dma_id = stream_tag - 1; in skl_link_hw_params()
578 p_params.link_index = link->index; in skl_link_hw_params()
581 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) in skl_link_hw_params()
582 p_params.link_bps = codec_dai->driver->playback.sig_bits; in skl_link_hw_params()
584 p_params.link_bps = codec_dai->driver->capture.sig_bits; in skl_link_hw_params()
592 struct skl_dev *skl = get_skl_ctx(dai->dev); in skl_link_pcm_prepare()
595 /* In case of XRUN recovery, reset the FW pipe to clean state */ in skl_link_pcm_prepare()
596 mconfig = skl_tplg_be_get_cpr_module(dai, substream->stream); in skl_link_pcm_prepare()
597 if (mconfig && !mconfig->pipe->passthru && in skl_link_pcm_prepare()
598 (substream->runtime->state == SNDRV_PCM_STATE_XRUN)) in skl_link_pcm_prepare()
599 skl_reset_pipe(skl, mconfig->pipe); in skl_link_pcm_prepare()
612 dev_dbg(dai->dev, "In %s cmd=%d\n", __func__, cmd); in skl_link_pcm_trigger()
629 return -EINVAL; in skl_link_pcm_trigger()
637 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_link_hw_free()
644 dev_dbg(dai->dev, "%s: %s\n", __func__, dai->name); in skl_link_hw_free()
646 link_dev->link_prepared = 0; in skl_link_hw_free()
648 link = snd_hdac_ext_bus_get_hlink_by_name(bus, asoc_rtd_to_codec(rtd, 0)->component->name); in skl_link_hw_free()
650 return -EINVAL; in skl_link_hw_free()
652 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in skl_link_hw_free()
653 stream_tag = hdac_stream(link_dev)->stream_tag; in skl_link_hw_free()
980 .name = "DMIC01 Pin",
983 .stream_name = "DMIC01 Rx",
1067 dai_drv->ops = &skl_pcm_dai_ops; in skl_dai_load()
1076 struct snd_soc_dai_link *dai_link = rtd->dai_link; in skl_platform_soc_open()
1078 dev_dbg(asoc_rtd_to_cpu(rtd, 0)->dev, "In %s:%s\n", __func__, in skl_platform_soc_open()
1079 dai_link->cpus->dai_name); in skl_platform_soc_open()
1100 dev_dbg(bus->dev, "In %s cmd=%d\n", __func__, cmd); in skl_coupled_trigger()
1102 if (!hstr->prepared) in skl_coupled_trigger()
1103 return -EPIPE; in skl_coupled_trigger()
1119 return -EINVAL; in skl_coupled_trigger()
1123 if (s->pcm->card != substream->pcm->card) in skl_coupled_trigger()
1126 sbits |= 1 << hdac_stream(stream)->index; in skl_coupled_trigger()
1130 spin_lock_irqsave(&bus->reg_lock, cookie); in skl_coupled_trigger()
1136 if (s->pcm->card != substream->pcm->card) in skl_coupled_trigger()
1144 spin_unlock_irqrestore(&bus->reg_lock, cookie); in skl_coupled_trigger()
1148 spin_lock_irqsave(&bus->reg_lock, cookie); in skl_coupled_trigger()
1154 spin_unlock_irqrestore(&bus->reg_lock, cookie); in skl_coupled_trigger()
1165 if (!bus->ppcap) in skl_platform_soc_trigger()
1180 * Use DPIB for Playback stream as the periodic DMA Position-in- in skl_platform_soc_pointer()
1196 * 3. Read the DMA Position-in-Buffer. This value now will be equal to in skl_platform_soc_pointer()
1200 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { in skl_platform_soc_pointer()
1201 pos = readl(bus->remap_addr + AZX_REG_VS_SDXDPIB_XBASE + in skl_platform_soc_pointer()
1203 hdac_stream(hstream)->index)); in skl_platform_soc_pointer()
1206 readl(bus->remap_addr + in skl_platform_soc_pointer()
1209 hdac_stream(hstream)->index)); in skl_platform_soc_pointer()
1213 if (pos >= hdac_stream(hstream)->bufsize) in skl_platform_soc_pointer()
1216 return bytes_to_frames(substream->runtime, pos); in skl_platform_soc_pointer()
1226 if (!codec_dai->driver->ops->delay) in skl_adjust_codec_delay()
1229 codec_frames = codec_dai->driver->ops->delay(substream, codec_dai); in skl_adjust_codec_delay()
1231 substream->runtime->rate); in skl_adjust_codec_delay()
1233 if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) in skl_adjust_codec_delay()
1236 return (nsec > codec_nsecs) ? nsec - codec_nsecs : 0; in skl_adjust_codec_delay()
1250 if ((substream->runtime->hw.info & SNDRV_PCM_INFO_HAS_LINK_ATIME) && in skl_platform_soc_get_time_info()
1251 (audio_tstamp_config->type_requested == SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK)) { in skl_platform_soc_get_time_info()
1253 snd_pcm_gettime(substream->runtime, system_ts); in skl_platform_soc_get_time_info()
1255 nsec = timecounter_read(&hstr->tc); in skl_platform_soc_get_time_info()
1256 if (audio_tstamp_config->report_delay) in skl_platform_soc_get_time_info()
1261 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_LINK; in skl_platform_soc_get_time_info()
1262 audio_tstamp_report->accuracy_report = 1; /* rest of struct is valid */ in skl_platform_soc_get_time_info()
1263 audio_tstamp_report->accuracy = 42; /* 24MHzWallClk == 42ns resolution */ in skl_platform_soc_get_time_info()
1266 audio_tstamp_report->actual_type = SNDRV_PCM_AUDIO_TSTAMP_TYPE_DEFAULT; in skl_platform_soc_get_time_info()
1278 struct hdac_bus *bus = dev_get_drvdata(dai->dev); in skl_platform_soc_new()
1279 struct snd_pcm *pcm = rtd->pcm; in skl_platform_soc_new()
1283 if (dai->driver->playback.channels_min || in skl_platform_soc_new()
1284 dai->driver->capture.channels_min) { in skl_platform_soc_new()
1285 /* buffer pre-allocation */ in skl_platform_soc_new()
1291 &skl->pci->dev, in skl_platform_soc_new()
1305 int i, ret = -EIO; in skl_get_module_info()
1307 uuid_mod = (guid_t *)mconfig->guid; in skl_get_module_info()
1309 if (list_empty(&skl->uuid_list)) { in skl_get_module_info()
1310 dev_err(skl->dev, "Module list is empty\n"); in skl_get_module_info()
1311 return -EIO; in skl_get_module_info()
1314 for (i = 0; i < skl->nr_modules; i++) { in skl_get_module_info()
1315 skl_module = skl->modules[i]; in skl_get_module_info()
1316 uuid_tplg = &skl_module->uuid; in skl_get_module_info()
1318 mconfig->module = skl_module; in skl_get_module_info()
1324 if (skl->nr_modules && ret) in skl_get_module_info()
1327 ret = -EIO; in skl_get_module_info()
1328 list_for_each_entry(module, &skl->uuid_list, list) { in skl_get_module_info()
1329 if (guid_equal(uuid_mod, &module->uuid)) { in skl_get_module_info()
1330 mconfig->id.module_id = module->id; in skl_get_module_info()
1331 mconfig->module->loadable = module->is_loadable; in skl_get_module_info()
1336 pin_id = &mconfig->m_in_pin[i].id; in skl_get_module_info()
1337 if (guid_equal(&pin_id->mod_uuid, &module->uuid)) in skl_get_module_info()
1338 pin_id->module_id = module->id; in skl_get_module_info()
1342 pin_id = &mconfig->m_out_pin[i].id; in skl_get_module_info()
1343 if (guid_equal(&pin_id->mod_uuid, &module->uuid)) in skl_get_module_info()
1344 pin_id->module_id = module->id; in skl_get_module_info()
1359 list_for_each_entry(p, &skl->ppl_list, node) { in skl_populate_modules()
1360 list_for_each_entry(m, &p->pipe->w_list, node) { in skl_populate_modules()
1361 w = m->w; in skl_populate_modules()
1362 mconfig = w->priv; in skl_populate_modules()
1366 dev_err(skl->dev, in skl_populate_modules()
1380 struct hdac_bus *bus = dev_get_drvdata(component->dev); in skl_platform_soc_probe()
1385 ret = pm_runtime_resume_and_get(component->dev); in skl_platform_soc_probe()
1386 if (ret < 0 && ret != -EACCES) in skl_platform_soc_probe()
1389 if (bus->ppcap) { in skl_platform_soc_probe()
1390 skl->component = component; in skl_platform_soc_probe()
1393 skl->debugfs = skl_debugfs_init(skl); in skl_platform_soc_probe()
1397 dev_err(component->dev, "Failed to init topology!\n"); in skl_platform_soc_probe()
1402 ops = skl_get_dsp_ops(skl->pci->device); in skl_platform_soc_probe()
1404 return -EIO; in skl_platform_soc_probe()
1410 skl->enable_miscbdcge(component->dev, false); in skl_platform_soc_probe()
1411 skl->clock_power_gating(component->dev, false); in skl_platform_soc_probe()
1413 ret = ops->init_fw(component->dev, skl); in skl_platform_soc_probe()
1414 skl->enable_miscbdcge(component->dev, true); in skl_platform_soc_probe()
1415 skl->clock_power_gating(component->dev, true); in skl_platform_soc_probe()
1417 dev_err(component->dev, "Failed to boot first fw: %d\n", ret); in skl_platform_soc_probe()
1421 skl->update_d0i3c = skl_update_d0i3c; in skl_platform_soc_probe()
1423 if (skl->cfg.astate_cfg != NULL) { in skl_platform_soc_probe()
1425 skl->cfg.astate_cfg->count, in skl_platform_soc_probe()
1426 skl->cfg.astate_cfg); in skl_platform_soc_probe()
1429 pm_runtime_mark_last_busy(component->dev); in skl_platform_soc_probe()
1430 pm_runtime_put_autosuspend(component->dev); in skl_platform_soc_probe()
1437 struct hdac_bus *bus = dev_get_drvdata(component->dev); in skl_platform_soc_remove()
1465 skl->dais = kmemdup(skl_platform_dai, sizeof(skl_platform_dai), in skl_platform_register()
1467 if (!skl->dais) { in skl_platform_register()
1468 ret = -ENOMEM; in skl_platform_register()
1472 if (!skl->use_tplg_pcm) { in skl_platform_register()
1473 dais = krealloc(skl->dais, sizeof(skl_fe_dai) + in skl_platform_register()
1476 kfree(skl->dais); in skl_platform_register()
1477 ret = -ENOMEM; in skl_platform_register()
1481 skl->dais = dais; in skl_platform_register()
1482 memcpy(&skl->dais[ARRAY_SIZE(skl_platform_dai)], skl_fe_dai, in skl_platform_register()
1488 skl->dais, num_dais); in skl_platform_register()
1490 kfree(skl->dais); in skl_platform_register()
1503 list_for_each_entry_safe(modules, tmp, &skl->bind_list, node) { in skl_platform_unregister()
1504 list_del(&modules->node); in skl_platform_unregister()
1508 kfree(skl->dais); in skl_platform_unregister()