static enum hdac_ext_stream_type skl_get_host_stream_type(struct hdac_ext_bus *ebus)
{
- if (ebus->ppcap)
+ if ((ebus_to_hbus(ebus))->ppcap)
return HDAC_EXT_STREAM_TYPE_HOST;
else
return HDAC_EXT_STREAM_TYPE_COUPLED;
struct hdac_ext_bus *ebus = dev_get_drvdata(dai->dev);
int format_val = 0;
- if (ebus->ppcap) {
+ if ((ebus_to_hbus(ebus))->ppcap) {
struct snd_pcm_runtime *runtime = substream->runtime;
format_val = snd_hdac_calc_stream_format(runtime->rate,
.channels_min = HDA_MONO,
.channels_max = HDA_STEREO,
.rates = SNDRV_PCM_RATE_48000 | SNDRV_PCM_RATE_16000 | SNDRV_PCM_RATE_8000,
- .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S24_LE,
+ .formats = SNDRV_PCM_FMTBIT_S16_LE |
+ SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE,
},
.capture = {
.stream_name = "System Capture",
{
struct hdac_ext_bus *ebus = get_bus_ctx(substream);
- if (!ebus->ppcap)
+ if (!(ebus_to_hbus(ebus))->ppcap)
return skl_coupled_trigger(substream, cmd);
return 0;
(struct snd_pcm_substream *substream)
{
struct hdac_ext_stream *hstream = get_hdac_ext_stream(substream);
+ struct hdac_ext_bus *ebus = get_bus_ctx(substream);
unsigned int pos;
- /* use the position buffer as default */
- pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream));
+ /*
+ * Use DPIB for Playback stream as the periodic DMA Position-in-
+ * Buffer Writes may be scheduled at the same time or later than
+ * the MSI and does not guarantee to reflect the Position of the
+ * last buffer that was transferred. Whereas DPIB register in
+ * HAD space reflects the actual data that is transferred.
+ * Use the position buffer for capture, as DPIB write gets
+ * completed earlier than the actual data written to the DDR.
+ */
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
+ pos = readl(ebus->bus.remap_addr + AZX_REG_VS_SDXDPIB_XBASE +
+ (AZX_REG_VS_SDXDPIB_XINTERVAL *
+ hdac_stream(hstream)->index));
+ else
+ pos = snd_hdac_stream_get_pos_posbuf(hdac_stream(hstream));
if (pos >= hdac_stream(hstream)->bufsize)
pos = 0;
return 0;
}
-static struct snd_pcm_ops skl_platform_ops = {
+static const struct snd_pcm_ops skl_platform_ops = {
.open = skl_platform_open,
.ioctl = snd_pcm_lib_ioctl,
.trigger = skl_platform_pcm_trigger,
return retval;
}
+static int skl_populate_modules(struct skl *skl)
+{
+ struct skl_pipeline *p;
+ struct skl_pipe_module *m;
+ struct snd_soc_dapm_widget *w;
+ struct skl_module_cfg *mconfig;
+ int ret;
+
+ list_for_each_entry(p, &skl->ppl_list, node) {
+ list_for_each_entry(m, &p->pipe->w_list, node) {
+
+ w = m->w;
+ mconfig = w->priv;
+
+ ret = snd_skl_get_module_info(skl->skl_sst, mconfig);
+ if (ret < 0) {
+ dev_err(skl->skl_sst->dev,
+ "query module info failed:%d\n", ret);
+ goto err;
+ }
+ }
+ }
+err:
+ return ret;
+}
+
static int skl_platform_soc_probe(struct snd_soc_platform *platform)
{
struct hdac_ext_bus *ebus = dev_get_drvdata(platform->dev);
struct skl *skl = ebus_to_skl(ebus);
+ const struct skl_dsp_ops *ops;
int ret;
- if (ebus->ppcap) {
+ pm_runtime_get_sync(platform->dev);
+ if ((ebus_to_hbus(ebus))->ppcap) {
ret = skl_tplg_init(platform, ebus);
if (ret < 0) {
dev_err(platform->dev, "Failed to init topology!\n");
return ret;
}
skl->platform = platform;
+
+ /* load the firmwares, since all is set */
+ ops = skl_get_dsp_ops(skl->pci->device);
+ if (!ops)
+ return -EIO;
+
+ if (skl->skl_sst->is_first_boot == false) {
+ dev_err(platform->dev, "DSP reports first boot done!!!\n");
+ return -EIO;
+ }
+
+ ret = ops->init_fw(platform->dev, skl->skl_sst);
+ if (ret < 0) {
+ dev_err(platform->dev, "Failed to boot first fw: %d\n", ret);
+ return ret;
+ }
+ skl_populate_modules(skl);
}
+ pm_runtime_mark_last_busy(platform->dev);
+ pm_runtime_put_autosuspend(platform->dev);
return 0;
}