18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: (GPL-2.0-only OR BSD-3-Clause) */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * This file is provided under a dual BSD/GPLv2 license. When using or 48c2ecf20Sopenharmony_ci * redistributing this file, you may do so under either license. 58c2ecf20Sopenharmony_ci * 68c2ecf20Sopenharmony_ci * Copyright(c) 2018 Intel Corporation. All rights reserved. 78c2ecf20Sopenharmony_ci * 88c2ecf20Sopenharmony_ci * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com> 98c2ecf20Sopenharmony_ci */ 108c2ecf20Sopenharmony_ci 118c2ecf20Sopenharmony_ci#ifndef __SOUND_SOC_SOF_IO_H 128c2ecf20Sopenharmony_ci#define __SOUND_SOC_SOF_IO_H 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_ci#include <linux/device.h> 158c2ecf20Sopenharmony_ci#include <linux/interrupt.h> 168c2ecf20Sopenharmony_ci#include <linux/kernel.h> 178c2ecf20Sopenharmony_ci#include <linux/types.h> 188c2ecf20Sopenharmony_ci#include <sound/pcm.h> 198c2ecf20Sopenharmony_ci#include "sof-priv.h" 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci#define sof_ops(sdev) \ 228c2ecf20Sopenharmony_ci ((sdev)->pdata->desc->ops) 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ci/* Mandatory operations are verified during probing */ 258c2ecf20Sopenharmony_ci 268c2ecf20Sopenharmony_ci/* init */ 278c2ecf20Sopenharmony_cistatic inline int snd_sof_probe(struct snd_sof_dev *sdev) 288c2ecf20Sopenharmony_ci{ 298c2ecf20Sopenharmony_ci return sof_ops(sdev)->probe(sdev); 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_cistatic inline int snd_sof_remove(struct snd_sof_dev *sdev) 338c2ecf20Sopenharmony_ci{ 348c2ecf20Sopenharmony_ci if (sof_ops(sdev)->remove) 358c2ecf20Sopenharmony_ci return sof_ops(sdev)->remove(sdev); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci return 0; 388c2ecf20Sopenharmony_ci} 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ci/* control */ 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci/* 438c2ecf20Sopenharmony_ci * snd_sof_dsp_run returns the core mask of the cores that are available 448c2ecf20Sopenharmony_ci * after successful fw boot 458c2ecf20Sopenharmony_ci */ 468c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_run(struct snd_sof_dev *sdev) 478c2ecf20Sopenharmony_ci{ 488c2ecf20Sopenharmony_ci return sof_ops(sdev)->run(sdev); 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_stall(struct snd_sof_dev *sdev) 528c2ecf20Sopenharmony_ci{ 538c2ecf20Sopenharmony_ci if (sof_ops(sdev)->stall) 548c2ecf20Sopenharmony_ci return sof_ops(sdev)->stall(sdev); 558c2ecf20Sopenharmony_ci 568c2ecf20Sopenharmony_ci return 0; 578c2ecf20Sopenharmony_ci} 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_reset(struct snd_sof_dev *sdev) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci if (sof_ops(sdev)->reset) 628c2ecf20Sopenharmony_ci return sof_ops(sdev)->reset(sdev); 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci return 0; 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_ci/* dsp core power up/power down */ 688c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_core_power_up(struct snd_sof_dev *sdev, 698c2ecf20Sopenharmony_ci unsigned int core_mask) 708c2ecf20Sopenharmony_ci{ 718c2ecf20Sopenharmony_ci if (sof_ops(sdev)->core_power_up) 728c2ecf20Sopenharmony_ci return sof_ops(sdev)->core_power_up(sdev, core_mask); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci return 0; 758c2ecf20Sopenharmony_ci} 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_core_power_down(struct snd_sof_dev *sdev, 788c2ecf20Sopenharmony_ci unsigned int core_mask) 798c2ecf20Sopenharmony_ci{ 808c2ecf20Sopenharmony_ci if (sof_ops(sdev)->core_power_down) 818c2ecf20Sopenharmony_ci return sof_ops(sdev)->core_power_down(sdev, core_mask); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci return 0; 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_ci/* pre/post fw load */ 878c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_pre_fw_run(struct snd_sof_dev *sdev) 888c2ecf20Sopenharmony_ci{ 898c2ecf20Sopenharmony_ci if (sof_ops(sdev)->pre_fw_run) 908c2ecf20Sopenharmony_ci return sof_ops(sdev)->pre_fw_run(sdev); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci return 0; 938c2ecf20Sopenharmony_ci} 948c2ecf20Sopenharmony_ci 958c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_post_fw_run(struct snd_sof_dev *sdev) 968c2ecf20Sopenharmony_ci{ 978c2ecf20Sopenharmony_ci if (sof_ops(sdev)->post_fw_run) 988c2ecf20Sopenharmony_ci return sof_ops(sdev)->post_fw_run(sdev); 998c2ecf20Sopenharmony_ci 1008c2ecf20Sopenharmony_ci return 0; 1018c2ecf20Sopenharmony_ci} 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci/* misc */ 1048c2ecf20Sopenharmony_ci 1058c2ecf20Sopenharmony_ci/** 1068c2ecf20Sopenharmony_ci * snd_sof_dsp_get_bar_index - Maps a section type with a BAR index 1078c2ecf20Sopenharmony_ci * 1088c2ecf20Sopenharmony_ci * @sdev: sof device 1098c2ecf20Sopenharmony_ci * @type: section type as described by snd_sof_fw_blk_type 1108c2ecf20Sopenharmony_ci * 1118c2ecf20Sopenharmony_ci * Returns the corresponding BAR index (a positive integer) or -EINVAL 1128c2ecf20Sopenharmony_ci * in case there is no mapping 1138c2ecf20Sopenharmony_ci */ 1148c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_get_bar_index(struct snd_sof_dev *sdev, u32 type) 1158c2ecf20Sopenharmony_ci{ 1168c2ecf20Sopenharmony_ci if (sof_ops(sdev)->get_bar_index) 1178c2ecf20Sopenharmony_ci return sof_ops(sdev)->get_bar_index(sdev, type); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci return sdev->mmio_bar; 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_get_mailbox_offset(struct snd_sof_dev *sdev) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci if (sof_ops(sdev)->get_mailbox_offset) 1258c2ecf20Sopenharmony_ci return sof_ops(sdev)->get_mailbox_offset(sdev); 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: %s not defined\n", __func__); 1288c2ecf20Sopenharmony_ci return -ENOTSUPP; 1298c2ecf20Sopenharmony_ci} 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_get_window_offset(struct snd_sof_dev *sdev, 1328c2ecf20Sopenharmony_ci u32 id) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci if (sof_ops(sdev)->get_window_offset) 1358c2ecf20Sopenharmony_ci return sof_ops(sdev)->get_window_offset(sdev, id); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: %s not defined\n", __func__); 1388c2ecf20Sopenharmony_ci return -ENOTSUPP; 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci/* power management */ 1418c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_resume(struct snd_sof_dev *sdev) 1428c2ecf20Sopenharmony_ci{ 1438c2ecf20Sopenharmony_ci if (sof_ops(sdev)->resume) 1448c2ecf20Sopenharmony_ci return sof_ops(sdev)->resume(sdev); 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_ci return 0; 1478c2ecf20Sopenharmony_ci} 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_suspend(struct snd_sof_dev *sdev, 1508c2ecf20Sopenharmony_ci u32 target_state) 1518c2ecf20Sopenharmony_ci{ 1528c2ecf20Sopenharmony_ci if (sof_ops(sdev)->suspend) 1538c2ecf20Sopenharmony_ci return sof_ops(sdev)->suspend(sdev, target_state); 1548c2ecf20Sopenharmony_ci 1558c2ecf20Sopenharmony_ci return 0; 1568c2ecf20Sopenharmony_ci} 1578c2ecf20Sopenharmony_ci 1588c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_runtime_resume(struct snd_sof_dev *sdev) 1598c2ecf20Sopenharmony_ci{ 1608c2ecf20Sopenharmony_ci if (sof_ops(sdev)->runtime_resume) 1618c2ecf20Sopenharmony_ci return sof_ops(sdev)->runtime_resume(sdev); 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci return 0; 1648c2ecf20Sopenharmony_ci} 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_runtime_suspend(struct snd_sof_dev *sdev) 1678c2ecf20Sopenharmony_ci{ 1688c2ecf20Sopenharmony_ci if (sof_ops(sdev)->runtime_suspend) 1698c2ecf20Sopenharmony_ci return sof_ops(sdev)->runtime_suspend(sdev); 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_ci return 0; 1728c2ecf20Sopenharmony_ci} 1738c2ecf20Sopenharmony_ci 1748c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_runtime_idle(struct snd_sof_dev *sdev) 1758c2ecf20Sopenharmony_ci{ 1768c2ecf20Sopenharmony_ci if (sof_ops(sdev)->runtime_idle) 1778c2ecf20Sopenharmony_ci return sof_ops(sdev)->runtime_idle(sdev); 1788c2ecf20Sopenharmony_ci 1798c2ecf20Sopenharmony_ci return 0; 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_hw_params_upon_resume(struct snd_sof_dev *sdev) 1838c2ecf20Sopenharmony_ci{ 1848c2ecf20Sopenharmony_ci if (sof_ops(sdev)->set_hw_params_upon_resume) 1858c2ecf20Sopenharmony_ci return sof_ops(sdev)->set_hw_params_upon_resume(sdev); 1868c2ecf20Sopenharmony_ci return 0; 1878c2ecf20Sopenharmony_ci} 1888c2ecf20Sopenharmony_ci 1898c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_set_clk(struct snd_sof_dev *sdev, u32 freq) 1908c2ecf20Sopenharmony_ci{ 1918c2ecf20Sopenharmony_ci if (sof_ops(sdev)->set_clk) 1928c2ecf20Sopenharmony_ci return sof_ops(sdev)->set_clk(sdev, freq); 1938c2ecf20Sopenharmony_ci 1948c2ecf20Sopenharmony_ci return 0; 1958c2ecf20Sopenharmony_ci} 1968c2ecf20Sopenharmony_ci 1978c2ecf20Sopenharmony_cistatic inline int 1988c2ecf20Sopenharmony_cisnd_sof_dsp_set_power_state(struct snd_sof_dev *sdev, 1998c2ecf20Sopenharmony_ci const struct sof_dsp_power_state *target_state) 2008c2ecf20Sopenharmony_ci{ 2018c2ecf20Sopenharmony_ci if (sof_ops(sdev)->set_power_state) 2028c2ecf20Sopenharmony_ci return sof_ops(sdev)->set_power_state(sdev, target_state); 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci /* D0 substate is not supported, do nothing here. */ 2058c2ecf20Sopenharmony_ci return 0; 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_ci/* debug */ 2098c2ecf20Sopenharmony_cistatic inline void snd_sof_dsp_dbg_dump(struct snd_sof_dev *sdev, u32 flags) 2108c2ecf20Sopenharmony_ci{ 2118c2ecf20Sopenharmony_ci if (sof_ops(sdev)->dbg_dump) 2128c2ecf20Sopenharmony_ci return sof_ops(sdev)->dbg_dump(sdev, flags); 2138c2ecf20Sopenharmony_ci} 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_cistatic inline void snd_sof_ipc_dump(struct snd_sof_dev *sdev) 2168c2ecf20Sopenharmony_ci{ 2178c2ecf20Sopenharmony_ci if (sof_ops(sdev)->ipc_dump) 2188c2ecf20Sopenharmony_ci return sof_ops(sdev)->ipc_dump(sdev); 2198c2ecf20Sopenharmony_ci} 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci/* register IO */ 2228c2ecf20Sopenharmony_cistatic inline void snd_sof_dsp_write(struct snd_sof_dev *sdev, u32 bar, 2238c2ecf20Sopenharmony_ci u32 offset, u32 value) 2248c2ecf20Sopenharmony_ci{ 2258c2ecf20Sopenharmony_ci if (sof_ops(sdev)->write) { 2268c2ecf20Sopenharmony_ci sof_ops(sdev)->write(sdev, sdev->bar[bar] + offset, value); 2278c2ecf20Sopenharmony_ci return; 2288c2ecf20Sopenharmony_ci } 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__); 2318c2ecf20Sopenharmony_ci} 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_cistatic inline void snd_sof_dsp_write64(struct snd_sof_dev *sdev, u32 bar, 2348c2ecf20Sopenharmony_ci u32 offset, u64 value) 2358c2ecf20Sopenharmony_ci{ 2368c2ecf20Sopenharmony_ci if (sof_ops(sdev)->write64) { 2378c2ecf20Sopenharmony_ci sof_ops(sdev)->write64(sdev, sdev->bar[bar] + offset, value); 2388c2ecf20Sopenharmony_ci return; 2398c2ecf20Sopenharmony_ci } 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci dev_err_ratelimited(sdev->dev, "error: %s not defined\n", __func__); 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_cistatic inline u32 snd_sof_dsp_read(struct snd_sof_dev *sdev, u32 bar, 2458c2ecf20Sopenharmony_ci u32 offset) 2468c2ecf20Sopenharmony_ci{ 2478c2ecf20Sopenharmony_ci if (sof_ops(sdev)->read) 2488c2ecf20Sopenharmony_ci return sof_ops(sdev)->read(sdev, sdev->bar[bar] + offset); 2498c2ecf20Sopenharmony_ci 2508c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: %s not defined\n", __func__); 2518c2ecf20Sopenharmony_ci return -ENOTSUPP; 2528c2ecf20Sopenharmony_ci} 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_cistatic inline u64 snd_sof_dsp_read64(struct snd_sof_dev *sdev, u32 bar, 2558c2ecf20Sopenharmony_ci u32 offset) 2568c2ecf20Sopenharmony_ci{ 2578c2ecf20Sopenharmony_ci if (sof_ops(sdev)->read64) 2588c2ecf20Sopenharmony_ci return sof_ops(sdev)->read64(sdev, sdev->bar[bar] + offset); 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci dev_err(sdev->dev, "error: %s not defined\n", __func__); 2618c2ecf20Sopenharmony_ci return -ENOTSUPP; 2628c2ecf20Sopenharmony_ci} 2638c2ecf20Sopenharmony_ci 2648c2ecf20Sopenharmony_ci/* block IO */ 2658c2ecf20Sopenharmony_cistatic inline void snd_sof_dsp_block_read(struct snd_sof_dev *sdev, u32 bar, 2668c2ecf20Sopenharmony_ci u32 offset, void *dest, size_t bytes) 2678c2ecf20Sopenharmony_ci{ 2688c2ecf20Sopenharmony_ci sof_ops(sdev)->block_read(sdev, bar, offset, dest, bytes); 2698c2ecf20Sopenharmony_ci} 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_cistatic inline void snd_sof_dsp_block_write(struct snd_sof_dev *sdev, u32 bar, 2728c2ecf20Sopenharmony_ci u32 offset, void *src, size_t bytes) 2738c2ecf20Sopenharmony_ci{ 2748c2ecf20Sopenharmony_ci sof_ops(sdev)->block_write(sdev, bar, offset, src, bytes); 2758c2ecf20Sopenharmony_ci} 2768c2ecf20Sopenharmony_ci 2778c2ecf20Sopenharmony_ci/* ipc */ 2788c2ecf20Sopenharmony_cistatic inline int snd_sof_dsp_send_msg(struct snd_sof_dev *sdev, 2798c2ecf20Sopenharmony_ci struct snd_sof_ipc_msg *msg) 2808c2ecf20Sopenharmony_ci{ 2818c2ecf20Sopenharmony_ci return sof_ops(sdev)->send_msg(sdev, msg); 2828c2ecf20Sopenharmony_ci} 2838c2ecf20Sopenharmony_ci 2848c2ecf20Sopenharmony_ci/* host DMA trace */ 2858c2ecf20Sopenharmony_cistatic inline int snd_sof_dma_trace_init(struct snd_sof_dev *sdev, 2868c2ecf20Sopenharmony_ci u32 *stream_tag) 2878c2ecf20Sopenharmony_ci{ 2888c2ecf20Sopenharmony_ci if (sof_ops(sdev)->trace_init) 2898c2ecf20Sopenharmony_ci return sof_ops(sdev)->trace_init(sdev, stream_tag); 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_ci return 0; 2928c2ecf20Sopenharmony_ci} 2938c2ecf20Sopenharmony_ci 2948c2ecf20Sopenharmony_cistatic inline int snd_sof_dma_trace_release(struct snd_sof_dev *sdev) 2958c2ecf20Sopenharmony_ci{ 2968c2ecf20Sopenharmony_ci if (sof_ops(sdev)->trace_release) 2978c2ecf20Sopenharmony_ci return sof_ops(sdev)->trace_release(sdev); 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci return 0; 3008c2ecf20Sopenharmony_ci} 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_cistatic inline int snd_sof_dma_trace_trigger(struct snd_sof_dev *sdev, int cmd) 3038c2ecf20Sopenharmony_ci{ 3048c2ecf20Sopenharmony_ci if (sof_ops(sdev)->trace_trigger) 3058c2ecf20Sopenharmony_ci return sof_ops(sdev)->trace_trigger(sdev, cmd); 3068c2ecf20Sopenharmony_ci 3078c2ecf20Sopenharmony_ci return 0; 3088c2ecf20Sopenharmony_ci} 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci/* host PCM ops */ 3118c2ecf20Sopenharmony_cistatic inline int 3128c2ecf20Sopenharmony_cisnd_sof_pcm_platform_open(struct snd_sof_dev *sdev, 3138c2ecf20Sopenharmony_ci struct snd_pcm_substream *substream) 3148c2ecf20Sopenharmony_ci{ 3158c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->pcm_open) 3168c2ecf20Sopenharmony_ci return sof_ops(sdev)->pcm_open(sdev, substream); 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci return 0; 3198c2ecf20Sopenharmony_ci} 3208c2ecf20Sopenharmony_ci 3218c2ecf20Sopenharmony_ci/* disconnect pcm substream to a host stream */ 3228c2ecf20Sopenharmony_cistatic inline int 3238c2ecf20Sopenharmony_cisnd_sof_pcm_platform_close(struct snd_sof_dev *sdev, 3248c2ecf20Sopenharmony_ci struct snd_pcm_substream *substream) 3258c2ecf20Sopenharmony_ci{ 3268c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->pcm_close) 3278c2ecf20Sopenharmony_ci return sof_ops(sdev)->pcm_close(sdev, substream); 3288c2ecf20Sopenharmony_ci 3298c2ecf20Sopenharmony_ci return 0; 3308c2ecf20Sopenharmony_ci} 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci/* host stream hw params */ 3338c2ecf20Sopenharmony_cistatic inline int 3348c2ecf20Sopenharmony_cisnd_sof_pcm_platform_hw_params(struct snd_sof_dev *sdev, 3358c2ecf20Sopenharmony_ci struct snd_pcm_substream *substream, 3368c2ecf20Sopenharmony_ci struct snd_pcm_hw_params *params, 3378c2ecf20Sopenharmony_ci struct sof_ipc_stream_params *ipc_params) 3388c2ecf20Sopenharmony_ci{ 3398c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_params) 3408c2ecf20Sopenharmony_ci return sof_ops(sdev)->pcm_hw_params(sdev, substream, 3418c2ecf20Sopenharmony_ci params, ipc_params); 3428c2ecf20Sopenharmony_ci 3438c2ecf20Sopenharmony_ci return 0; 3448c2ecf20Sopenharmony_ci} 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_ci/* host stream hw free */ 3478c2ecf20Sopenharmony_cistatic inline int 3488c2ecf20Sopenharmony_cisnd_sof_pcm_platform_hw_free(struct snd_sof_dev *sdev, 3498c2ecf20Sopenharmony_ci struct snd_pcm_substream *substream) 3508c2ecf20Sopenharmony_ci{ 3518c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->pcm_hw_free) 3528c2ecf20Sopenharmony_ci return sof_ops(sdev)->pcm_hw_free(sdev, substream); 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_ci return 0; 3558c2ecf20Sopenharmony_ci} 3568c2ecf20Sopenharmony_ci 3578c2ecf20Sopenharmony_ci/* host stream trigger */ 3588c2ecf20Sopenharmony_cistatic inline int 3598c2ecf20Sopenharmony_cisnd_sof_pcm_platform_trigger(struct snd_sof_dev *sdev, 3608c2ecf20Sopenharmony_ci struct snd_pcm_substream *substream, int cmd) 3618c2ecf20Sopenharmony_ci{ 3628c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->pcm_trigger) 3638c2ecf20Sopenharmony_ci return sof_ops(sdev)->pcm_trigger(sdev, substream, cmd); 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_ci return 0; 3668c2ecf20Sopenharmony_ci} 3678c2ecf20Sopenharmony_ci 3688c2ecf20Sopenharmony_ci/* host DSP message data */ 3698c2ecf20Sopenharmony_cistatic inline void snd_sof_ipc_msg_data(struct snd_sof_dev *sdev, 3708c2ecf20Sopenharmony_ci struct snd_pcm_substream *substream, 3718c2ecf20Sopenharmony_ci void *p, size_t sz) 3728c2ecf20Sopenharmony_ci{ 3738c2ecf20Sopenharmony_ci sof_ops(sdev)->ipc_msg_data(sdev, substream, p, sz); 3748c2ecf20Sopenharmony_ci} 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci/* host configure DSP HW parameters */ 3778c2ecf20Sopenharmony_cistatic inline int 3788c2ecf20Sopenharmony_cisnd_sof_ipc_pcm_params(struct snd_sof_dev *sdev, 3798c2ecf20Sopenharmony_ci struct snd_pcm_substream *substream, 3808c2ecf20Sopenharmony_ci const struct sof_ipc_pcm_params_reply *reply) 3818c2ecf20Sopenharmony_ci{ 3828c2ecf20Sopenharmony_ci return sof_ops(sdev)->ipc_pcm_params(sdev, substream, reply); 3838c2ecf20Sopenharmony_ci} 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci/* host stream pointer */ 3868c2ecf20Sopenharmony_cistatic inline snd_pcm_uframes_t 3878c2ecf20Sopenharmony_cisnd_sof_pcm_platform_pointer(struct snd_sof_dev *sdev, 3888c2ecf20Sopenharmony_ci struct snd_pcm_substream *substream) 3898c2ecf20Sopenharmony_ci{ 3908c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->pcm_pointer) 3918c2ecf20Sopenharmony_ci return sof_ops(sdev)->pcm_pointer(sdev, substream); 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_ci return 0; 3948c2ecf20Sopenharmony_ci} 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci#if IS_ENABLED(CONFIG_SND_SOC_SOF_DEBUG_PROBES) 3978c2ecf20Sopenharmony_cistatic inline int 3988c2ecf20Sopenharmony_cisnd_sof_probe_compr_assign(struct snd_sof_dev *sdev, 3998c2ecf20Sopenharmony_ci struct snd_compr_stream *cstream, struct snd_soc_dai *dai) 4008c2ecf20Sopenharmony_ci{ 4018c2ecf20Sopenharmony_ci return sof_ops(sdev)->probe_assign(sdev, cstream, dai); 4028c2ecf20Sopenharmony_ci} 4038c2ecf20Sopenharmony_ci 4048c2ecf20Sopenharmony_cistatic inline int 4058c2ecf20Sopenharmony_cisnd_sof_probe_compr_free(struct snd_sof_dev *sdev, 4068c2ecf20Sopenharmony_ci struct snd_compr_stream *cstream, struct snd_soc_dai *dai) 4078c2ecf20Sopenharmony_ci{ 4088c2ecf20Sopenharmony_ci return sof_ops(sdev)->probe_free(sdev, cstream, dai); 4098c2ecf20Sopenharmony_ci} 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_cistatic inline int 4128c2ecf20Sopenharmony_cisnd_sof_probe_compr_set_params(struct snd_sof_dev *sdev, 4138c2ecf20Sopenharmony_ci struct snd_compr_stream *cstream, 4148c2ecf20Sopenharmony_ci struct snd_compr_params *params, struct snd_soc_dai *dai) 4158c2ecf20Sopenharmony_ci{ 4168c2ecf20Sopenharmony_ci return sof_ops(sdev)->probe_set_params(sdev, cstream, params, dai); 4178c2ecf20Sopenharmony_ci} 4188c2ecf20Sopenharmony_ci 4198c2ecf20Sopenharmony_cistatic inline int 4208c2ecf20Sopenharmony_cisnd_sof_probe_compr_trigger(struct snd_sof_dev *sdev, 4218c2ecf20Sopenharmony_ci struct snd_compr_stream *cstream, int cmd, 4228c2ecf20Sopenharmony_ci struct snd_soc_dai *dai) 4238c2ecf20Sopenharmony_ci{ 4248c2ecf20Sopenharmony_ci return sof_ops(sdev)->probe_trigger(sdev, cstream, cmd, dai); 4258c2ecf20Sopenharmony_ci} 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_cistatic inline int 4288c2ecf20Sopenharmony_cisnd_sof_probe_compr_pointer(struct snd_sof_dev *sdev, 4298c2ecf20Sopenharmony_ci struct snd_compr_stream *cstream, 4308c2ecf20Sopenharmony_ci struct snd_compr_tstamp *tstamp, struct snd_soc_dai *dai) 4318c2ecf20Sopenharmony_ci{ 4328c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->probe_pointer) 4338c2ecf20Sopenharmony_ci return sof_ops(sdev)->probe_pointer(sdev, cstream, tstamp, dai); 4348c2ecf20Sopenharmony_ci 4358c2ecf20Sopenharmony_ci return 0; 4368c2ecf20Sopenharmony_ci} 4378c2ecf20Sopenharmony_ci#endif 4388c2ecf20Sopenharmony_ci 4398c2ecf20Sopenharmony_ci/* machine driver */ 4408c2ecf20Sopenharmony_cistatic inline int 4418c2ecf20Sopenharmony_cisnd_sof_machine_register(struct snd_sof_dev *sdev, void *pdata) 4428c2ecf20Sopenharmony_ci{ 4438c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->machine_register) 4448c2ecf20Sopenharmony_ci return sof_ops(sdev)->machine_register(sdev, pdata); 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci return 0; 4478c2ecf20Sopenharmony_ci} 4488c2ecf20Sopenharmony_ci 4498c2ecf20Sopenharmony_cistatic inline void 4508c2ecf20Sopenharmony_cisnd_sof_machine_unregister(struct snd_sof_dev *sdev, void *pdata) 4518c2ecf20Sopenharmony_ci{ 4528c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->machine_unregister) 4538c2ecf20Sopenharmony_ci sof_ops(sdev)->machine_unregister(sdev, pdata); 4548c2ecf20Sopenharmony_ci} 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_cistatic inline void 4578c2ecf20Sopenharmony_cisnd_sof_machine_select(struct snd_sof_dev *sdev) 4588c2ecf20Sopenharmony_ci{ 4598c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->machine_select) 4608c2ecf20Sopenharmony_ci sof_ops(sdev)->machine_select(sdev); 4618c2ecf20Sopenharmony_ci} 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_cistatic inline void 4648c2ecf20Sopenharmony_cisnd_sof_set_mach_params(const struct snd_soc_acpi_mach *mach, 4658c2ecf20Sopenharmony_ci struct device *dev) 4668c2ecf20Sopenharmony_ci{ 4678c2ecf20Sopenharmony_ci struct snd_sof_dev *sdev = dev_get_drvdata(dev); 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci if (sof_ops(sdev) && sof_ops(sdev)->set_mach_params) 4708c2ecf20Sopenharmony_ci sof_ops(sdev)->set_mach_params(mach, dev); 4718c2ecf20Sopenharmony_ci} 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_cistatic inline const struct snd_sof_dsp_ops 4748c2ecf20Sopenharmony_ci*sof_get_ops(const struct sof_dev_desc *d, 4758c2ecf20Sopenharmony_ci const struct sof_ops_table mach_ops[], int asize) 4768c2ecf20Sopenharmony_ci{ 4778c2ecf20Sopenharmony_ci int i; 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_ci for (i = 0; i < asize; i++) { 4808c2ecf20Sopenharmony_ci if (d == mach_ops[i].desc) 4818c2ecf20Sopenharmony_ci return mach_ops[i].ops; 4828c2ecf20Sopenharmony_ci } 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_ci /* not found */ 4858c2ecf20Sopenharmony_ci return NULL; 4868c2ecf20Sopenharmony_ci} 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci/** 4898c2ecf20Sopenharmony_ci * snd_sof_dsp_register_poll_timeout - Periodically poll an address 4908c2ecf20Sopenharmony_ci * until a condition is met or a timeout occurs 4918c2ecf20Sopenharmony_ci * @op: accessor function (takes @addr as its only argument) 4928c2ecf20Sopenharmony_ci * @addr: Address to poll 4938c2ecf20Sopenharmony_ci * @val: Variable to read the value into 4948c2ecf20Sopenharmony_ci * @cond: Break condition (usually involving @val) 4958c2ecf20Sopenharmony_ci * @sleep_us: Maximum time to sleep between reads in us (0 4968c2ecf20Sopenharmony_ci * tight-loops). Should be less than ~20ms since usleep_range 4978c2ecf20Sopenharmony_ci * is used (see Documentation/timers/timers-howto.rst). 4988c2ecf20Sopenharmony_ci * @timeout_us: Timeout in us, 0 means never timeout 4998c2ecf20Sopenharmony_ci * 5008c2ecf20Sopenharmony_ci * Returns 0 on success and -ETIMEDOUT upon a timeout. In either 5018c2ecf20Sopenharmony_ci * case, the last read value at @addr is stored in @val. Must not 5028c2ecf20Sopenharmony_ci * be called from atomic context if sleep_us or timeout_us are used. 5038c2ecf20Sopenharmony_ci * 5048c2ecf20Sopenharmony_ci * This is modelled after the readx_poll_timeout macros in linux/iopoll.h. 5058c2ecf20Sopenharmony_ci */ 5068c2ecf20Sopenharmony_ci#define snd_sof_dsp_read_poll_timeout(sdev, bar, offset, val, cond, sleep_us, timeout_us) \ 5078c2ecf20Sopenharmony_ci({ \ 5088c2ecf20Sopenharmony_ci u64 __timeout_us = (timeout_us); \ 5098c2ecf20Sopenharmony_ci unsigned long __sleep_us = (sleep_us); \ 5108c2ecf20Sopenharmony_ci ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \ 5118c2ecf20Sopenharmony_ci might_sleep_if((__sleep_us) != 0); \ 5128c2ecf20Sopenharmony_ci for (;;) { \ 5138c2ecf20Sopenharmony_ci (val) = snd_sof_dsp_read(sdev, bar, offset); \ 5148c2ecf20Sopenharmony_ci if (cond) { \ 5158c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, \ 5168c2ecf20Sopenharmony_ci "FW Poll Status: reg=%#x successful\n", (val)); \ 5178c2ecf20Sopenharmony_ci break; \ 5188c2ecf20Sopenharmony_ci } \ 5198c2ecf20Sopenharmony_ci if (__timeout_us && \ 5208c2ecf20Sopenharmony_ci ktime_compare(ktime_get(), __timeout) > 0) { \ 5218c2ecf20Sopenharmony_ci (val) = snd_sof_dsp_read(sdev, bar, offset); \ 5228c2ecf20Sopenharmony_ci dev_dbg(sdev->dev, \ 5238c2ecf20Sopenharmony_ci "FW Poll Status: reg=%#x timedout\n", (val)); \ 5248c2ecf20Sopenharmony_ci break; \ 5258c2ecf20Sopenharmony_ci } \ 5268c2ecf20Sopenharmony_ci if (__sleep_us) \ 5278c2ecf20Sopenharmony_ci usleep_range((__sleep_us >> 2) + 1, __sleep_us); \ 5288c2ecf20Sopenharmony_ci } \ 5298c2ecf20Sopenharmony_ci (cond) ? 0 : -ETIMEDOUT; \ 5308c2ecf20Sopenharmony_ci}) 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci/* This is for registers bits with attribute RWC */ 5338c2ecf20Sopenharmony_cibool snd_sof_pci_update_bits(struct snd_sof_dev *sdev, u32 offset, 5348c2ecf20Sopenharmony_ci u32 mask, u32 value); 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_cibool snd_sof_dsp_update_bits_unlocked(struct snd_sof_dev *sdev, u32 bar, 5378c2ecf20Sopenharmony_ci u32 offset, u32 mask, u32 value); 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_cibool snd_sof_dsp_update_bits64_unlocked(struct snd_sof_dev *sdev, u32 bar, 5408c2ecf20Sopenharmony_ci u32 offset, u64 mask, u64 value); 5418c2ecf20Sopenharmony_ci 5428c2ecf20Sopenharmony_cibool snd_sof_dsp_update_bits(struct snd_sof_dev *sdev, u32 bar, u32 offset, 5438c2ecf20Sopenharmony_ci u32 mask, u32 value); 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_cibool snd_sof_dsp_update_bits64(struct snd_sof_dev *sdev, u32 bar, 5468c2ecf20Sopenharmony_ci u32 offset, u64 mask, u64 value); 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_civoid snd_sof_dsp_update_bits_forced(struct snd_sof_dev *sdev, u32 bar, 5498c2ecf20Sopenharmony_ci u32 offset, u32 mask, u32 value); 5508c2ecf20Sopenharmony_ci 5518c2ecf20Sopenharmony_ciint snd_sof_dsp_register_poll(struct snd_sof_dev *sdev, u32 bar, u32 offset, 5528c2ecf20Sopenharmony_ci u32 mask, u32 target, u32 timeout_ms, 5538c2ecf20Sopenharmony_ci u32 interval_us); 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_civoid snd_sof_dsp_panic(struct snd_sof_dev *sdev, u32 offset); 5568c2ecf20Sopenharmony_ci#endif 557