162306a36Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * This file is provided under a dual BSD/GPLv2 license.  When using or
462306a36Sopenharmony_ci * redistributing this file, you may do so under either license.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright(c) 2018 Intel Corporation. All rights reserved.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
962306a36Sopenharmony_ci */
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#ifndef __SOUND_SOC_SOF_IO_H
1262306a36Sopenharmony_ci#define __SOUND_SOC_SOF_IO_H
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/device.h>
1562306a36Sopenharmony_ci#include <linux/interrupt.h>
1662306a36Sopenharmony_ci#include <linux/kernel.h>
1762306a36Sopenharmony_ci#include <linux/types.h>
1862306a36Sopenharmony_ci#include <sound/pcm.h>
1962306a36Sopenharmony_ci#include "sof-priv.h"
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_ci#define sof_ops(sdev) \
2262306a36Sopenharmony_ci	((sdev)->pdata->desc->ops)
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistatic inline int sof_ops_init(struct snd_sof_dev *sdev)
2562306a36Sopenharmony_ci{
2662306a36Sopenharmony_ci	if (sdev->pdata->desc->ops_init)
2762306a36Sopenharmony_ci		return sdev->pdata->desc->ops_init(sdev);
2862306a36Sopenharmony_ci
2962306a36Sopenharmony_ci	return 0;
3062306a36Sopenharmony_ci}
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cistatic inline void sof_ops_free(struct snd_sof_dev *sdev)
3362306a36Sopenharmony_ci{
3462306a36Sopenharmony_ci	if (sdev->pdata->desc->ops_free)
3562306a36Sopenharmony_ci		sdev->pdata->desc->ops_free(sdev);
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci/* Mandatory operations are verified during probing */
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci/* init */
4162306a36Sopenharmony_cistatic inline int snd_sof_probe(struct snd_sof_dev *sdev)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	return sof_ops(sdev)->probe(sdev);
4462306a36Sopenharmony_ci}
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic inline int snd_sof_remove(struct snd_sof_dev *sdev)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	if (sof_ops(sdev)->remove)
4962306a36Sopenharmony_ci		return sof_ops(sdev)->remove(sdev);
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	return 0;
5262306a36Sopenharmony_ci}
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistatic inline int snd_sof_shutdown(struct snd_sof_dev *sdev)
5562306a36Sopenharmony_ci{
5662306a36Sopenharmony_ci	if (sof_ops(sdev)->shutdown)
5762306a36Sopenharmony_ci		return sof_ops(sdev)->shutdown(sdev);
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	return 0;
6062306a36Sopenharmony_ci}
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci/* control */
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/*
6562306a36Sopenharmony_ci * snd_sof_dsp_run returns the core mask of the cores that are available
6662306a36Sopenharmony_ci * after successful fw boot
6762306a36Sopenharmony_ci */
6862306a36Sopenharmony_cistatic inline int snd_sof_dsp_run(struct snd_sof_dev *sdev)
6962306a36Sopenharmony_ci{
7062306a36Sopenharmony_ci	return sof_ops(sdev)->run(sdev);
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cistatic inline int snd_sof_dsp_stall(struct snd_sof_dev *sdev, unsigned int core_mask)
7462306a36Sopenharmony_ci{
7562306a36Sopenharmony_ci	if (sof_ops(sdev)->stall)
7662306a36Sopenharmony_ci		return sof_ops(sdev)->stall(sdev, core_mask);
7762306a36Sopenharmony_ci
7862306a36Sopenharmony_ci	return 0;
7962306a36Sopenharmony_ci}
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cistatic inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev)
8262306a36Sopenharmony_ci{
8362306a36Sopenharmony_ci	if (sof_ops(sdev)->reset)
8462306a36Sopenharmony_ci		return sof_ops(sdev)->reset(sdev);
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_ci	return 0;
8762306a36Sopenharmony_ci}
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci/* dsp core get/put */
9062306a36Sopenharmony_cistatic inline int snd_sof_dsp_core_get(struct snd_sof_dev *sdev, int core)
9162306a36Sopenharmony_ci{
9262306a36Sopenharmony_ci	if (core > sdev->num_cores - 1) {
9362306a36Sopenharmony_ci		dev_err(sdev->dev, "invalid core id: %d for num_cores: %d\n", core,
9462306a36Sopenharmony_ci			sdev->num_cores);
9562306a36Sopenharmony_ci		return -EINVAL;
9662306a36Sopenharmony_ci	}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_ci	if (sof_ops(sdev)->core_get) {
9962306a36Sopenharmony_ci		int ret;
10062306a36Sopenharmony_ci
10162306a36Sopenharmony_ci		/* if current ref_count is > 0, increment it and return */
10262306a36Sopenharmony_ci		if (sdev->dsp_core_ref_count[core] > 0) {
10362306a36Sopenharmony_ci			sdev->dsp_core_ref_count[core]++;
10462306a36Sopenharmony_ci			return 0;
10562306a36Sopenharmony_ci		}
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci		/* power up the core */
10862306a36Sopenharmony_ci		ret = sof_ops(sdev)->core_get(sdev, core);
10962306a36Sopenharmony_ci		if (ret < 0)
11062306a36Sopenharmony_ci			return ret;
11162306a36Sopenharmony_ci
11262306a36Sopenharmony_ci		/* increment ref_count */
11362306a36Sopenharmony_ci		sdev->dsp_core_ref_count[core]++;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci		/* and update enabled_cores_mask */
11662306a36Sopenharmony_ci		sdev->enabled_cores_mask |= BIT(core);
11762306a36Sopenharmony_ci
11862306a36Sopenharmony_ci		dev_dbg(sdev->dev, "Core %d powered up\n", core);
11962306a36Sopenharmony_ci	}
12062306a36Sopenharmony_ci
12162306a36Sopenharmony_ci	return 0;
12262306a36Sopenharmony_ci}
12362306a36Sopenharmony_ci
12462306a36Sopenharmony_cistatic inline int snd_sof_dsp_core_put(struct snd_sof_dev *sdev, int core)
12562306a36Sopenharmony_ci{
12662306a36Sopenharmony_ci	if (core > sdev->num_cores - 1) {
12762306a36Sopenharmony_ci		dev_err(sdev->dev, "invalid core id: %d for num_cores: %d\n", core,
12862306a36Sopenharmony_ci			sdev->num_cores);
12962306a36Sopenharmony_ci		return -EINVAL;
13062306a36Sopenharmony_ci	}
13162306a36Sopenharmony_ci
13262306a36Sopenharmony_ci	if (sof_ops(sdev)->core_put) {
13362306a36Sopenharmony_ci		int ret;
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_ci		/* decrement ref_count and return if it is > 0 */
13662306a36Sopenharmony_ci		if (--(sdev->dsp_core_ref_count[core]) > 0)
13762306a36Sopenharmony_ci			return 0;
13862306a36Sopenharmony_ci
13962306a36Sopenharmony_ci		/* power down the core */
14062306a36Sopenharmony_ci		ret = sof_ops(sdev)->core_put(sdev, core);
14162306a36Sopenharmony_ci		if (ret < 0)
14262306a36Sopenharmony_ci			return ret;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci		/* and update enabled_cores_mask */
14562306a36Sopenharmony_ci		sdev->enabled_cores_mask &= ~BIT(core);
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci		dev_dbg(sdev->dev, "Core %d powered down\n", core);
14862306a36Sopenharmony_ci	}
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_ci	return 0;
15162306a36Sopenharmony_ci}
15262306a36Sopenharmony_ci
15362306a36Sopenharmony_ci/* pre/post fw load */
15462306a36Sopenharmony_cistatic inline int snd_sof_dsp_pre_fw_run(struct snd_sof_dev *sdev)
15562306a36Sopenharmony_ci{
15662306a36Sopenharmony_ci	if (sof_ops(sdev)->pre_fw_run)
15762306a36Sopenharmony_ci		return sof_ops(sdev)->pre_fw_run(sdev);
15862306a36Sopenharmony_ci
15962306a36Sopenharmony_ci	return 0;
16062306a36Sopenharmony_ci}
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cistatic inline int snd_sof_dsp_post_fw_run(struct snd_sof_dev *sdev)
16362306a36Sopenharmony_ci{
16462306a36Sopenharmony_ci	if (sof_ops(sdev)->post_fw_run)
16562306a36Sopenharmony_ci		return sof_ops(sdev)->post_fw_run(sdev);
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci	return 0;
16862306a36Sopenharmony_ci}
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci/* parse platform specific extended manifest */
17162306a36Sopenharmony_cistatic inline int snd_sof_dsp_parse_platform_ext_manifest(struct snd_sof_dev *sdev,
17262306a36Sopenharmony_ci							  const struct sof_ext_man_elem_header *hdr)
17362306a36Sopenharmony_ci{
17462306a36Sopenharmony_ci	if (sof_ops(sdev)->parse_platform_ext_manifest)
17562306a36Sopenharmony_ci		return sof_ops(sdev)->parse_platform_ext_manifest(sdev, hdr);
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci	return 0;
17862306a36Sopenharmony_ci}
17962306a36Sopenharmony_ci
18062306a36Sopenharmony_ci/* misc */
18162306a36Sopenharmony_ci
18262306a36Sopenharmony_ci/**
18362306a36Sopenharmony_ci * snd_sof_dsp_get_bar_index - Maps a section type with a BAR index
18462306a36Sopenharmony_ci *
18562306a36Sopenharmony_ci * @sdev: sof device
18662306a36Sopenharmony_ci * @type: section type as described by snd_sof_fw_blk_type
18762306a36Sopenharmony_ci *
18862306a36Sopenharmony_ci * Returns the corresponding BAR index (a positive integer) or -EINVAL
18962306a36Sopenharmony_ci * in case there is no mapping
19062306a36Sopenharmony_ci */
19162306a36Sopenharmony_cistatic inline int snd_sof_dsp_get_bar_index(struct snd_sof_dev *sdev, u32 type)
19262306a36Sopenharmony_ci{
19362306a36Sopenharmony_ci	if (sof_ops(sdev)->get_bar_index)
19462306a36Sopenharmony_ci		return sof_ops(sdev)->get_bar_index(sdev, type);
19562306a36Sopenharmony_ci
19662306a36Sopenharmony_ci	return sdev->mmio_bar;
19762306a36Sopenharmony_ci}
19862306a36Sopenharmony_ci
19962306a36Sopenharmony_cistatic inline int snd_sof_dsp_get_mailbox_offset(struct snd_sof_dev *sdev)
20062306a36Sopenharmony_ci{
20162306a36Sopenharmony_ci	if (sof_ops(sdev)->get_mailbox_offset)
20262306a36Sopenharmony_ci		return sof_ops(sdev)->get_mailbox_offset(sdev);
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	dev_err(sdev->dev, "error: %s not defined\n", __func__);
20562306a36Sopenharmony_ci	return -ENOTSUPP;
20662306a36Sopenharmony_ci}
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_cistatic inline int snd_sof_dsp_get_window_offset(struct snd_sof_dev *sdev,
20962306a36Sopenharmony_ci						u32 id)
21062306a36Sopenharmony_ci{
21162306a36Sopenharmony_ci	if (sof_ops(sdev)->get_window_offset)
21262306a36Sopenharmony_ci		return sof_ops(sdev)->get_window_offset(sdev, id);
21362306a36Sopenharmony_ci
21462306a36Sopenharmony_ci	dev_err(sdev->dev, "error: %s not defined\n", __func__);
21562306a36Sopenharmony_ci	return -ENOTSUPP;
21662306a36Sopenharmony_ci}
21762306a36Sopenharmony_ci/* power management */
21862306a36Sopenharmony_cistatic inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev)
21962306a36Sopenharmony_ci{
22062306a36Sopenharmony_ci	if (sof_ops(sdev)->resume)
22162306a36Sopenharmony_ci		return sof_ops(sdev)->resume(sdev);
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	return 0;
22462306a36Sopenharmony_ci}
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_cistatic inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev,
22762306a36Sopenharmony_ci				      u32 target_state)
22862306a36Sopenharmony_ci{
22962306a36Sopenharmony_ci	if (sof_ops(sdev)->suspend)
23062306a36Sopenharmony_ci		return sof_ops(sdev)->suspend(sdev, target_state);
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci	return 0;
23362306a36Sopenharmony_ci}
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_cistatic inline int snd_sof_dsp_runtime_resume(struct snd_sof_dev *sdev)
23662306a36Sopenharmony_ci{
23762306a36Sopenharmony_ci	if (sof_ops(sdev)->runtime_resume)
23862306a36Sopenharmony_ci		return sof_ops(sdev)->runtime_resume(sdev);
23962306a36Sopenharmony_ci
24062306a36Sopenharmony_ci	return 0;
24162306a36Sopenharmony_ci}
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_cistatic inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev)
24462306a36Sopenharmony_ci{
24562306a36Sopenharmony_ci	if (sof_ops(sdev)->runtime_suspend)
24662306a36Sopenharmony_ci		return sof_ops(sdev)->runtime_suspend(sdev);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci	return 0;
24962306a36Sopenharmony_ci}
25062306a36Sopenharmony_ci
25162306a36Sopenharmony_cistatic inline int snd_sof_dsp_runtime_idle(struct snd_sof_dev *sdev)
25262306a36Sopenharmony_ci{
25362306a36Sopenharmony_ci	if (sof_ops(sdev)->runtime_idle)
25462306a36Sopenharmony_ci		return sof_ops(sdev)->runtime_idle(sdev);
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci	return 0;
25762306a36Sopenharmony_ci}
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_cistatic inline int snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev)
26062306a36Sopenharmony_ci{
26162306a36Sopenharmony_ci	if (sof_ops(sdev)->set_hw_params_upon_resume)
26262306a36Sopenharmony_ci		return sof_ops(sdev)->set_hw_params_upon_resume(sdev);
26362306a36Sopenharmony_ci	return 0;
26462306a36Sopenharmony_ci}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_cistatic inline int snd_sof_dsp_set_clk(struct snd_sof_dev *sdev, u32 freq)
26762306a36Sopenharmony_ci{
26862306a36Sopenharmony_ci	if (sof_ops(sdev)->set_clk)
26962306a36Sopenharmony_ci		return sof_ops(sdev)->set_clk(sdev, freq);
27062306a36Sopenharmony_ci
27162306a36Sopenharmony_ci	return 0;
27262306a36Sopenharmony_ci}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_cistatic inline int
27562306a36Sopenharmony_cisnd_sof_dsp_set_power_state(struct snd_sof_dev *sdev,
27662306a36Sopenharmony_ci			    const struct sof_dsp_power_state *target_state)
27762306a36Sopenharmony_ci{
27862306a36Sopenharmony_ci	int ret = 0;
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	mutex_lock(&sdev->power_state_access);
28162306a36Sopenharmony_ci
28262306a36Sopenharmony_ci	if (sof_ops(sdev)->set_power_state)
28362306a36Sopenharmony_ci		ret = sof_ops(sdev)->set_power_state(sdev, target_state);
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_ci	mutex_unlock(&sdev->power_state_access);
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	return ret;
28862306a36Sopenharmony_ci}
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci/* debug */
29162306a36Sopenharmony_civoid snd_sof_dsp_dbg_dump(struct snd_sof_dev *sdev, const char *msg, u32 flags);
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_cistatic inline int snd_sof_debugfs_add_region_item(struct snd_sof_dev *sdev,
29462306a36Sopenharmony_ci		enum snd_sof_fw_blk_type blk_type, u32 offset, size_t size,
29562306a36Sopenharmony_ci		const char *name, enum sof_debugfs_access_type access_type)
29662306a36Sopenharmony_ci{
29762306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->debugfs_add_region_item)
29862306a36Sopenharmony_ci		return sof_ops(sdev)->debugfs_add_region_item(sdev, blk_type, offset,
29962306a36Sopenharmony_ci							      size, name, access_type);
30062306a36Sopenharmony_ci
30162306a36Sopenharmony_ci	return 0;
30262306a36Sopenharmony_ci}
30362306a36Sopenharmony_ci
30462306a36Sopenharmony_ci/* register IO */
30562306a36Sopenharmony_cistatic inline void snd_sof_dsp_write8(struct snd_sof_dev *sdev, u32 bar,
30662306a36Sopenharmony_ci				      u32 offset, u8 value)
30762306a36Sopenharmony_ci{
30862306a36Sopenharmony_ci	if (sof_ops(sdev)->write8)
30962306a36Sopenharmony_ci		sof_ops(sdev)->write8(sdev, sdev->bar[bar] + offset, value);
31062306a36Sopenharmony_ci	else
31162306a36Sopenharmony_ci		writeb(value,  sdev->bar[bar] + offset);
31262306a36Sopenharmony_ci}
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_cistatic inline void snd_sof_dsp_write(struct snd_sof_dev *sdev, u32 bar,
31562306a36Sopenharmony_ci				     u32 offset, u32 value)
31662306a36Sopenharmony_ci{
31762306a36Sopenharmony_ci	if (sof_ops(sdev)->write)
31862306a36Sopenharmony_ci		sof_ops(sdev)->write(sdev, sdev->bar[bar] + offset, value);
31962306a36Sopenharmony_ci	else
32062306a36Sopenharmony_ci		writel(value,  sdev->bar[bar] + offset);
32162306a36Sopenharmony_ci}
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_cistatic inline void snd_sof_dsp_write64(struct snd_sof_dev *sdev, u32 bar,
32462306a36Sopenharmony_ci				       u32 offset, u64 value)
32562306a36Sopenharmony_ci{
32662306a36Sopenharmony_ci	if (sof_ops(sdev)->write64)
32762306a36Sopenharmony_ci		sof_ops(sdev)->write64(sdev, sdev->bar[bar] + offset, value);
32862306a36Sopenharmony_ci	else
32962306a36Sopenharmony_ci		writeq(value, sdev->bar[bar] + offset);
33062306a36Sopenharmony_ci}
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_cistatic inline u8 snd_sof_dsp_read8(struct snd_sof_dev *sdev, u32 bar,
33362306a36Sopenharmony_ci				   u32 offset)
33462306a36Sopenharmony_ci{
33562306a36Sopenharmony_ci	if (sof_ops(sdev)->read8)
33662306a36Sopenharmony_ci		return sof_ops(sdev)->read8(sdev, sdev->bar[bar] + offset);
33762306a36Sopenharmony_ci	else
33862306a36Sopenharmony_ci		return readb(sdev->bar[bar] + offset);
33962306a36Sopenharmony_ci}
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_cistatic inline u32 snd_sof_dsp_read(struct snd_sof_dev *sdev, u32 bar,
34262306a36Sopenharmony_ci				   u32 offset)
34362306a36Sopenharmony_ci{
34462306a36Sopenharmony_ci	if (sof_ops(sdev)->read)
34562306a36Sopenharmony_ci		return sof_ops(sdev)->read(sdev, sdev->bar[bar] + offset);
34662306a36Sopenharmony_ci	else
34762306a36Sopenharmony_ci		return readl(sdev->bar[bar] + offset);
34862306a36Sopenharmony_ci}
34962306a36Sopenharmony_ci
35062306a36Sopenharmony_cistatic inline u64 snd_sof_dsp_read64(struct snd_sof_dev *sdev, u32 bar,
35162306a36Sopenharmony_ci				     u32 offset)
35262306a36Sopenharmony_ci{
35362306a36Sopenharmony_ci	if (sof_ops(sdev)->read64)
35462306a36Sopenharmony_ci		return sof_ops(sdev)->read64(sdev, sdev->bar[bar] + offset);
35562306a36Sopenharmony_ci	else
35662306a36Sopenharmony_ci		return readq(sdev->bar[bar] + offset);
35762306a36Sopenharmony_ci}
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_cistatic inline void snd_sof_dsp_update8(struct snd_sof_dev *sdev, u32 bar,
36062306a36Sopenharmony_ci				       u32 offset, u8 mask, u8 value)
36162306a36Sopenharmony_ci{
36262306a36Sopenharmony_ci	u8 reg;
36362306a36Sopenharmony_ci
36462306a36Sopenharmony_ci	reg = snd_sof_dsp_read8(sdev, bar, offset);
36562306a36Sopenharmony_ci	reg &= ~mask;
36662306a36Sopenharmony_ci	reg |= value;
36762306a36Sopenharmony_ci	snd_sof_dsp_write8(sdev, bar, offset, reg);
36862306a36Sopenharmony_ci}
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci/* block IO */
37162306a36Sopenharmony_cistatic inline int snd_sof_dsp_block_read(struct snd_sof_dev *sdev,
37262306a36Sopenharmony_ci					 enum snd_sof_fw_blk_type blk_type,
37362306a36Sopenharmony_ci					 u32 offset, void *dest, size_t bytes)
37462306a36Sopenharmony_ci{
37562306a36Sopenharmony_ci	return sof_ops(sdev)->block_read(sdev, blk_type, offset, dest, bytes);
37662306a36Sopenharmony_ci}
37762306a36Sopenharmony_ci
37862306a36Sopenharmony_cistatic inline int snd_sof_dsp_block_write(struct snd_sof_dev *sdev,
37962306a36Sopenharmony_ci					  enum snd_sof_fw_blk_type blk_type,
38062306a36Sopenharmony_ci					  u32 offset, void *src, size_t bytes)
38162306a36Sopenharmony_ci{
38262306a36Sopenharmony_ci	return sof_ops(sdev)->block_write(sdev, blk_type, offset, src, bytes);
38362306a36Sopenharmony_ci}
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci/* mailbox IO */
38662306a36Sopenharmony_cistatic inline void snd_sof_dsp_mailbox_read(struct snd_sof_dev *sdev,
38762306a36Sopenharmony_ci					    u32 offset, void *dest, size_t bytes)
38862306a36Sopenharmony_ci{
38962306a36Sopenharmony_ci	if (sof_ops(sdev)->mailbox_read)
39062306a36Sopenharmony_ci		sof_ops(sdev)->mailbox_read(sdev, offset, dest, bytes);
39162306a36Sopenharmony_ci}
39262306a36Sopenharmony_ci
39362306a36Sopenharmony_cistatic inline void snd_sof_dsp_mailbox_write(struct snd_sof_dev *sdev,
39462306a36Sopenharmony_ci					     u32 offset, void *src, size_t bytes)
39562306a36Sopenharmony_ci{
39662306a36Sopenharmony_ci	if (sof_ops(sdev)->mailbox_write)
39762306a36Sopenharmony_ci		sof_ops(sdev)->mailbox_write(sdev, offset, src, bytes);
39862306a36Sopenharmony_ci}
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ci/* ipc */
40162306a36Sopenharmony_cistatic inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev,
40262306a36Sopenharmony_ci				       struct snd_sof_ipc_msg *msg)
40362306a36Sopenharmony_ci{
40462306a36Sopenharmony_ci	return sof_ops(sdev)->send_msg(sdev, msg);
40562306a36Sopenharmony_ci}
40662306a36Sopenharmony_ci
40762306a36Sopenharmony_ci/* host PCM ops */
40862306a36Sopenharmony_cistatic inline int
40962306a36Sopenharmony_cisnd_sof_pcm_platform_open(struct snd_sof_dev *sdev,
41062306a36Sopenharmony_ci			  struct snd_pcm_substream *substream)
41162306a36Sopenharmony_ci{
41262306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->pcm_open)
41362306a36Sopenharmony_ci		return sof_ops(sdev)->pcm_open(sdev, substream);
41462306a36Sopenharmony_ci
41562306a36Sopenharmony_ci	return 0;
41662306a36Sopenharmony_ci}
41762306a36Sopenharmony_ci
41862306a36Sopenharmony_ci/* disconnect pcm substream to a host stream */
41962306a36Sopenharmony_cistatic inline int
42062306a36Sopenharmony_cisnd_sof_pcm_platform_close(struct snd_sof_dev *sdev,
42162306a36Sopenharmony_ci			   struct snd_pcm_substream *substream)
42262306a36Sopenharmony_ci{
42362306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->pcm_close)
42462306a36Sopenharmony_ci		return sof_ops(sdev)->pcm_close(sdev, substream);
42562306a36Sopenharmony_ci
42662306a36Sopenharmony_ci	return 0;
42762306a36Sopenharmony_ci}
42862306a36Sopenharmony_ci
42962306a36Sopenharmony_ci/* host stream hw params */
43062306a36Sopenharmony_cistatic inline int
43162306a36Sopenharmony_cisnd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev,
43262306a36Sopenharmony_ci			       struct snd_pcm_substream *substream,
43362306a36Sopenharmony_ci			       struct snd_pcm_hw_params *params,
43462306a36Sopenharmony_ci			       struct snd_sof_platform_stream_params *platform_params)
43562306a36Sopenharmony_ci{
43662306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_params)
43762306a36Sopenharmony_ci		return sof_ops(sdev)->pcm_hw_params(sdev, substream, params,
43862306a36Sopenharmony_ci						    platform_params);
43962306a36Sopenharmony_ci
44062306a36Sopenharmony_ci	return 0;
44162306a36Sopenharmony_ci}
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci/* host stream hw free */
44462306a36Sopenharmony_cistatic inline int
44562306a36Sopenharmony_cisnd_sof_pcm_platform_hw_free(struct snd_sof_dev *sdev,
44662306a36Sopenharmony_ci			     struct snd_pcm_substream *substream)
44762306a36Sopenharmony_ci{
44862306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_free)
44962306a36Sopenharmony_ci		return sof_ops(sdev)->pcm_hw_free(sdev, substream);
45062306a36Sopenharmony_ci
45162306a36Sopenharmony_ci	return 0;
45262306a36Sopenharmony_ci}
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci/* host stream trigger */
45562306a36Sopenharmony_cistatic inline int
45662306a36Sopenharmony_cisnd_sof_pcm_platform_trigger(struct snd_sof_dev *sdev,
45762306a36Sopenharmony_ci			     struct snd_pcm_substream *substream, int cmd)
45862306a36Sopenharmony_ci{
45962306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->pcm_trigger)
46062306a36Sopenharmony_ci		return sof_ops(sdev)->pcm_trigger(sdev, substream, cmd);
46162306a36Sopenharmony_ci
46262306a36Sopenharmony_ci	return 0;
46362306a36Sopenharmony_ci}
46462306a36Sopenharmony_ci
46562306a36Sopenharmony_ci/* Firmware loading */
46662306a36Sopenharmony_cistatic inline int snd_sof_load_firmware(struct snd_sof_dev *sdev)
46762306a36Sopenharmony_ci{
46862306a36Sopenharmony_ci	dev_dbg(sdev->dev, "loading firmware\n");
46962306a36Sopenharmony_ci
47062306a36Sopenharmony_ci	return sof_ops(sdev)->load_firmware(sdev);
47162306a36Sopenharmony_ci}
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci/* host DSP message data */
47462306a36Sopenharmony_cistatic inline int snd_sof_ipc_msg_data(struct snd_sof_dev *sdev,
47562306a36Sopenharmony_ci				       struct snd_sof_pcm_stream *sps,
47662306a36Sopenharmony_ci				       void *p, size_t sz)
47762306a36Sopenharmony_ci{
47862306a36Sopenharmony_ci	return sof_ops(sdev)->ipc_msg_data(sdev, sps, p, sz);
47962306a36Sopenharmony_ci}
48062306a36Sopenharmony_ci/* host side configuration of the stream's data offset in stream mailbox area */
48162306a36Sopenharmony_cistatic inline int
48262306a36Sopenharmony_cisnd_sof_set_stream_data_offset(struct snd_sof_dev *sdev,
48362306a36Sopenharmony_ci			       struct snd_sof_pcm_stream *sps,
48462306a36Sopenharmony_ci			       size_t posn_offset)
48562306a36Sopenharmony_ci{
48662306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->set_stream_data_offset)
48762306a36Sopenharmony_ci		return sof_ops(sdev)->set_stream_data_offset(sdev, sps,
48862306a36Sopenharmony_ci							     posn_offset);
48962306a36Sopenharmony_ci
49062306a36Sopenharmony_ci	return 0;
49162306a36Sopenharmony_ci}
49262306a36Sopenharmony_ci
49362306a36Sopenharmony_ci/* host stream pointer */
49462306a36Sopenharmony_cistatic inline snd_pcm_uframes_t
49562306a36Sopenharmony_cisnd_sof_pcm_platform_pointer(struct snd_sof_dev *sdev,
49662306a36Sopenharmony_ci			     struct snd_pcm_substream *substream)
49762306a36Sopenharmony_ci{
49862306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->pcm_pointer)
49962306a36Sopenharmony_ci		return sof_ops(sdev)->pcm_pointer(sdev, substream);
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci	return 0;
50262306a36Sopenharmony_ci}
50362306a36Sopenharmony_ci
50462306a36Sopenharmony_ci/* pcm ack */
50562306a36Sopenharmony_cistatic inline int snd_sof_pcm_platform_ack(struct snd_sof_dev *sdev,
50662306a36Sopenharmony_ci					   struct snd_pcm_substream *substream)
50762306a36Sopenharmony_ci{
50862306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->pcm_ack)
50962306a36Sopenharmony_ci		return sof_ops(sdev)->pcm_ack(sdev, substream);
51062306a36Sopenharmony_ci
51162306a36Sopenharmony_ci	return 0;
51262306a36Sopenharmony_ci}
51362306a36Sopenharmony_ci
51462306a36Sopenharmony_cistatic inline u64 snd_sof_pcm_get_stream_position(struct snd_sof_dev *sdev,
51562306a36Sopenharmony_ci						  struct snd_soc_component *component,
51662306a36Sopenharmony_ci						  struct snd_pcm_substream *substream)
51762306a36Sopenharmony_ci{
51862306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->get_stream_position)
51962306a36Sopenharmony_ci		return sof_ops(sdev)->get_stream_position(sdev, component, substream);
52062306a36Sopenharmony_ci
52162306a36Sopenharmony_ci	return 0;
52262306a36Sopenharmony_ci}
52362306a36Sopenharmony_ci
52462306a36Sopenharmony_ci/* machine driver */
52562306a36Sopenharmony_cistatic inline int
52662306a36Sopenharmony_cisnd_sof_machine_register(struct snd_sof_dev *sdev, void *pdata)
52762306a36Sopenharmony_ci{
52862306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->machine_register)
52962306a36Sopenharmony_ci		return sof_ops(sdev)->machine_register(sdev, pdata);
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci	return 0;
53262306a36Sopenharmony_ci}
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_cistatic inline void
53562306a36Sopenharmony_cisnd_sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata)
53662306a36Sopenharmony_ci{
53762306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->machine_unregister)
53862306a36Sopenharmony_ci		sof_ops(sdev)->machine_unregister(sdev, pdata);
53962306a36Sopenharmony_ci}
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_cistatic inline struct snd_soc_acpi_mach *
54262306a36Sopenharmony_cisnd_sof_machine_select(struct snd_sof_dev *sdev)
54362306a36Sopenharmony_ci{
54462306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->machine_select)
54562306a36Sopenharmony_ci		return sof_ops(sdev)->machine_select(sdev);
54662306a36Sopenharmony_ci
54762306a36Sopenharmony_ci	return NULL;
54862306a36Sopenharmony_ci}
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_cistatic inline void
55162306a36Sopenharmony_cisnd_sof_set_mach_params(struct snd_soc_acpi_mach *mach,
55262306a36Sopenharmony_ci			struct snd_sof_dev *sdev)
55362306a36Sopenharmony_ci{
55462306a36Sopenharmony_ci	if (sof_ops(sdev) && sof_ops(sdev)->set_mach_params)
55562306a36Sopenharmony_ci		sof_ops(sdev)->set_mach_params(mach, sdev);
55662306a36Sopenharmony_ci}
55762306a36Sopenharmony_ci
55862306a36Sopenharmony_ci/**
55962306a36Sopenharmony_ci * snd_sof_dsp_register_poll_timeout - Periodically poll an address
56062306a36Sopenharmony_ci * until a condition is met or a timeout occurs
56162306a36Sopenharmony_ci * @op: accessor function (takes @addr as its only argument)
56262306a36Sopenharmony_ci * @addr: Address to poll
56362306a36Sopenharmony_ci * @val: Variable to read the value into
56462306a36Sopenharmony_ci * @cond: Break condition (usually involving @val)
56562306a36Sopenharmony_ci * @sleep_us: Maximum time to sleep between reads in us (0
56662306a36Sopenharmony_ci *            tight-loops).  Should be less than ~20ms since usleep_range
56762306a36Sopenharmony_ci *            is used (see Documentation/timers/timers-howto.rst).
56862306a36Sopenharmony_ci * @timeout_us: Timeout in us, 0 means never timeout
56962306a36Sopenharmony_ci *
57062306a36Sopenharmony_ci * Returns 0 on success and -ETIMEDOUT upon a timeout. In either
57162306a36Sopenharmony_ci * case, the last read value at @addr is stored in @val. Must not
57262306a36Sopenharmony_ci * be called from atomic context if sleep_us or timeout_us are used.
57362306a36Sopenharmony_ci *
57462306a36Sopenharmony_ci * This is modelled after the readx_poll_timeout macros in linux/iopoll.h.
57562306a36Sopenharmony_ci */
57662306a36Sopenharmony_ci#define snd_sof_dsp_read_poll_timeout(sdev, bar, offset, val, cond, sleep_us, timeout_us) \
57762306a36Sopenharmony_ci({ \
57862306a36Sopenharmony_ci	u64 __timeout_us = (timeout_us); \
57962306a36Sopenharmony_ci	unsigned long __sleep_us = (sleep_us); \
58062306a36Sopenharmony_ci	ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
58162306a36Sopenharmony_ci	might_sleep_if((__sleep_us) != 0); \
58262306a36Sopenharmony_ci	for (;;) {							\
58362306a36Sopenharmony_ci		(val) = snd_sof_dsp_read(sdev, bar, offset);		\
58462306a36Sopenharmony_ci		if (cond) { \
58562306a36Sopenharmony_ci			dev_dbg(sdev->dev, \
58662306a36Sopenharmony_ci				"FW Poll Status: reg[%#x]=%#x successful\n", \
58762306a36Sopenharmony_ci				(offset), (val)); \
58862306a36Sopenharmony_ci			break; \
58962306a36Sopenharmony_ci		} \
59062306a36Sopenharmony_ci		if (__timeout_us && \
59162306a36Sopenharmony_ci		    ktime_compare(ktime_get(), __timeout) > 0) { \
59262306a36Sopenharmony_ci			(val) = snd_sof_dsp_read(sdev, bar, offset); \
59362306a36Sopenharmony_ci			dev_dbg(sdev->dev, \
59462306a36Sopenharmony_ci				"FW Poll Status: reg[%#x]=%#x timedout\n", \
59562306a36Sopenharmony_ci				(offset), (val)); \
59662306a36Sopenharmony_ci			break; \
59762306a36Sopenharmony_ci		} \
59862306a36Sopenharmony_ci		if (__sleep_us) \
59962306a36Sopenharmony_ci			usleep_range((__sleep_us >> 2) + 1, __sleep_us); \
60062306a36Sopenharmony_ci	} \
60162306a36Sopenharmony_ci	(cond) ? 0 : -ETIMEDOUT; \
60262306a36Sopenharmony_ci})
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci/* This is for registers bits with attribute RWC */
60562306a36Sopenharmony_cibool snd_sof_pci_update_bits(struct snd_sof_dev *sdev, u32 offset,
60662306a36Sopenharmony_ci			     u32 mask, u32 value);
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_cibool snd_sof_dsp_update_bits_unlocked(struct snd_sof_dev *sdev, u32 bar,
60962306a36Sopenharmony_ci				      u32 offset, u32 mask, u32 value);
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_cibool snd_sof_dsp_update_bits64_unlocked(struct snd_sof_dev *sdev, u32 bar,
61262306a36Sopenharmony_ci					u32 offset, u64 mask, u64 value);
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_cibool snd_sof_dsp_update_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset,
61562306a36Sopenharmony_ci			     u32 mask, u32 value);
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_cibool snd_sof_dsp_update_bits64(struct snd_sof_dev *sdev, u32 bar,
61862306a36Sopenharmony_ci			       u32 offset, u64 mask, u64 value);
61962306a36Sopenharmony_ci
62062306a36Sopenharmony_civoid snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar,
62162306a36Sopenharmony_ci				    u32 offset, u32 mask, u32 value);
62262306a36Sopenharmony_ci
62362306a36Sopenharmony_ciint snd_sof_dsp_register_poll(struct snd_sof_dev *sdev, u32 bar, u32 offset,
62462306a36Sopenharmony_ci			      u32 mask, u32 target, u32 timeout_ms,
62562306a36Sopenharmony_ci			      u32 interval_us);
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_civoid snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset, bool non_recoverable);
62862306a36Sopenharmony_ci#endif
629