Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    2) // Copyright (c) 2011-2017, The Linux Foundation. All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    3) // Copyright (c) 2018, Linaro Limited
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5) #include <linux/mutex.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8) #include <linux/soc/qcom/apr.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) #include <linux/of_platform.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/spinlock.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/kref.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <uapi/sound/asound.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <uapi/sound/compress_params.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include <linux/mm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include "q6asm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include "q6core.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include "q6dsp-errno.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) #include "q6dsp-common.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) #define ASM_STREAM_CMD_CLOSE			0x00010BCD
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) #define ASM_STREAM_CMD_FLUSH			0x00010BCE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26) #define ASM_SESSION_CMD_PAUSE			0x00010BD3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27) #define ASM_DATA_CMD_EOS			0x00010BDB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #define ASM_DATA_EVENT_RENDERED_EOS		0x00010C1C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define ASM_NULL_POPP_TOPOLOGY			0x00010C68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define ASM_STREAM_CMD_FLUSH_READBUFS		0x00010C09
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define ASM_STREAM_CMD_SET_ENCDEC_PARAM		0x00010C10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define ASM_STREAM_POSTPROC_TOPO_ID_NONE	0x00010C68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #define ASM_CMD_SHARED_MEM_MAP_REGIONS		0x00010D92
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define ASM_CMDRSP_SHARED_MEM_MAP_REGIONS	0x00010D93
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define ASM_CMD_SHARED_MEM_UNMAP_REGIONS	0x00010D94
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2	0x00010D98
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define ASM_DATA_EVENT_WRITE_DONE_V2		0x00010D99
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2	0x00010DA3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define ASM_SESSION_CMD_RUN_V2			0x00010DAA
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2	0x00010DA5
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define ASM_MEDIA_FMT_MP3			0x00010BE9
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define ASM_MEDIA_FMT_FLAC			0x00010C16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define ASM_MEDIA_FMT_WMA_V9			0x00010DA8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define ASM_MEDIA_FMT_WMA_V10			0x00010DA7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define ASM_DATA_CMD_WRITE_V2			0x00010DAB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define ASM_DATA_CMD_READ_V2			0x00010DAC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define ASM_SESSION_CMD_SUSPEND			0x00010DEC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define ASM_STREAM_CMD_OPEN_WRITE_V3		0x00010DB3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define ASM_STREAM_CMD_OPEN_READ_V3                 0x00010DB4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define ASM_DATA_EVENT_READ_DONE_V2 0x00010D9A
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define ASM_STREAM_CMD_OPEN_READWRITE_V2        0x00010D8D
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define ASM_MEDIA_FMT_ALAC			0x00012f31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define ASM_MEDIA_FMT_APE			0x00012f32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define ASM_DATA_CMD_REMOVE_INITIAL_SILENCE	0x00010D67
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) #define ASM_DATA_CMD_REMOVE_TRAILING_SILENCE	0x00010D68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define ASM_LEGACY_STREAM_SESSION	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) /* Bit shift for the stream_perf_mode subfield. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ              29
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define ASM_END_POINT_DEVICE_MATRIX	0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define ASM_DEFAULT_APP_TYPE		0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) #define ASM_SYNC_IO_MODE		0x0001
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) #define ASM_ASYNC_IO_MODE		0x0002
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) #define ASM_TUN_READ_IO_MODE		0x0004	/* tunnel read write mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define ASM_TUN_WRITE_IO_MODE		0x0008	/* tunnel read write mode */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define ASM_SHIFT_GAPLESS_MODE_FLAG	31
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) #define ADSP_MEMORY_MAP_SHMEM8_4K_POOL	3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) struct avs_cmd_shared_mem_map_regions {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 	u16 mem_pool_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) 	u16 num_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 	u32 property_flag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) struct avs_shared_map_region_payload {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) 	u32 shm_addr_lsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	u32 shm_addr_msw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	u32 mem_size_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) struct avs_cmd_shared_mem_unmap_regions {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) 	u32 mem_map_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86) struct asm_data_cmd_media_fmt_update_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87) 	u32 fmt_blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) struct asm_multi_channel_pcm_fmt_blk_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) 	struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) 	u16 num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) 	u16 bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) 	u32 sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) 	u16 is_signed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) 	u16 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 	u8 channel_mapping[PCM_MAX_NUM_CHANNEL];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100) struct asm_flac_fmt_blk_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) 	struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) 	u16 is_stream_info_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) 	u16 num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) 	u16 min_blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) 	u16 max_blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) 	u16 md5_sum[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 	u32 sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) 	u32 min_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 	u32 max_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) 	u16 sample_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) 	u16 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) struct asm_wmastdv9_fmt_blk_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) 	u16          fmtag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 	u16          num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) 	u32          sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) 	u32          bytes_per_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	u16          blk_align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) 	u16          bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 	u32          channel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) 	u16          enc_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 	u16          reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) struct asm_wmaprov10_fmt_blk_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) 	struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 	u16          fmtag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) 	u16          num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 	u32          sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) 	u32          bytes_per_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	u16          blk_align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) 	u16          bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 	u32          channel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) 	u16          enc_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) 	u16          advanced_enc_options1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	u32          advanced_enc_options2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) struct asm_alac_fmt_blk_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) 	struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	u32 frame_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) 	u8 compatible_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 	u8 bit_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) 	u8 pb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) 	u8 mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	u8 kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) 	u8 num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 	u16 max_run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) 	u32 max_frame_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) 	u32 avg_bit_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	u32 sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	u32 channel_layout_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) struct asm_ape_fmt_blk_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	struct asm_data_cmd_media_fmt_update_v2 fmt_blk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 	u16 compatible_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	u16 compression_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 	u32 format_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 	u32 blocks_per_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	u32 final_frame_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	u32 total_frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 	u16 bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	u16 num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 	u32 sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 	u32 seek_table_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) struct asm_stream_cmd_set_encdec_param {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	u32                  param_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	u32                  param_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) struct asm_enc_cfg_blk_param_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 	u32                  frames_per_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	u32                  enc_cfg_blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) struct asm_multi_channel_pcm_enc_cfg_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) 	struct asm_stream_cmd_set_encdec_param  encdec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	struct asm_enc_cfg_blk_param_v2	encblk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	uint16_t  num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 	uint16_t  bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	uint32_t  sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	uint16_t  is_signed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 	uint16_t  reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 	uint8_t   channel_mapping[8];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) struct asm_data_cmd_read_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	u32                  buf_addr_lsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 	u32                  buf_addr_msw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	u32                  mem_map_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	u32                  buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	u32                  seq_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) struct asm_data_cmd_read_v2_done {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 	u32	status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) 	u32	buf_addr_lsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 	u32	buf_addr_msw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) struct asm_stream_cmd_open_read_v3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	u32                    mode_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) 	u32                    src_endpointype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 	u32                    preprocopo_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) 	u32                    enc_cfg_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 	u16                    bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) 	u16                    reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) struct asm_data_cmd_write_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	u32 buf_addr_lsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 	u32 buf_addr_msw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	u32 mem_map_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 	u32 buf_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 	u32 seq_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 	u32 timestamp_lsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	u32 timestamp_msw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 	u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) struct asm_stream_cmd_open_write_v3 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) 	uint32_t mode_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228) 	uint16_t sink_endpointype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229) 	uint16_t bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230) 	uint32_t postprocopo_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231) 	uint32_t dec_fmt_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) struct asm_session_cmd_run_v2 {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	u32 flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 	u32 time_lsw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	u32 time_msw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) } __packed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) struct audio_buffer {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) 	phys_addr_t phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 	uint32_t size;		/* size of buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) struct audio_port_data {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	struct audio_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 	uint32_t num_periods;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	uint32_t dsp_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 	uint32_t mem_map_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) struct q6asm {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 	struct apr_device *adev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) 	struct q6core_svc_api_info ainfo;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 	wait_queue_head_t mem_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) 	spinlock_t slock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) 	struct audio_client *session[MAX_SESSIONS + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) struct audio_client {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	int session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	q6asm_cb cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	void *priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	uint32_t io_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 	struct apr_device *adev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	struct mutex cmd_lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 	spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 	struct kref refcount;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	/* idx:1 out port, 0: in port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 	struct audio_port_data port[2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 	wait_queue_head_t cmd_wait;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 	struct aprv2_ibasic_rsp_result_t result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 	int perf_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 	struct q6asm *q6asm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 	struct device *dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) static inline void q6asm_add_hdr(struct audio_client *ac, struct apr_hdr *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 				 uint32_t pkt_size, bool cmd_flg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 				 uint32_t stream_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	hdr->hdr_field = APR_SEQ_CMD_HDR_FIELD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 	hdr->src_port = ((ac->session << 8) & 0xFF00) | (stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	hdr->dest_port = ((ac->session << 8) & 0xFF00) | (stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	hdr->pkt_size = pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	if (cmd_flg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 		hdr->token = ac->session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) static int q6asm_apr_send_session_pkt(struct q6asm *a, struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 				      struct apr_pkt *pkt, uint32_t rsp_opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 	struct apr_hdr *hdr = &pkt->hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 	mutex_lock(&ac->cmd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	ac->result.opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 	ac->result.status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	rc = apr_send_pkt(a->adev, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	if (rsp_opcode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 		rc = wait_event_timeout(a->mem_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 					(ac->result.opcode == hdr->opcode) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 					(ac->result.opcode == rsp_opcode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 					5 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 		rc = wait_event_timeout(a->mem_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) 					(ac->result.opcode == hdr->opcode),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 					5 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) 	if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 		dev_err(a->dev, "CMD %x timeout\n", hdr->opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		rc = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 	} else if (ac->result.status > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		dev_err(a->dev, "DSP returned error[%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 			ac->result.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) 	mutex_unlock(&ac->cmd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) static int __q6asm_memory_unmap(struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 				phys_addr_t buf_add, int dir)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  331) 	struct avs_cmd_shared_mem_unmap_regions *mem_unmap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  332) 	struct q6asm *a = dev_get_drvdata(ac->dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  333) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) 	int rc, pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	if (ac->port[dir].mem_map_handle == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 		dev_err(ac->dev, "invalid mem handle\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	pkt_size = APR_HDR_SIZE + sizeof(*mem_unmap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 	mem_unmap = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 	pkt->hdr.hdr_field = APR_SEQ_CMD_HDR_FIELD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 	pkt->hdr.src_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 	pkt->hdr.dest_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	pkt->hdr.pkt_size = pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 	pkt->hdr.token = ((ac->session << 8) | dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 	pkt->hdr.opcode = ASM_CMD_SHARED_MEM_UNMAP_REGIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 	mem_unmap->mem_map_handle = ac->port[dir].mem_map_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	rc = q6asm_apr_send_session_pkt(a, ac, pkt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 	if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 		kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) 	ac->port[dir].mem_map_handle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) static void q6asm_audio_client_free_buf(struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 					struct audio_port_data *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) 	spin_lock_irqsave(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	port->num_periods = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	kfree(port->buf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 	port->buf = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385)  * q6asm_unmap_memory_regions() - unmap memory regions in the dsp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387)  * @dir: direction of audio stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388)  * @ac: audio client instanace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390)  * Return: Will be an negative value on failure or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) int q6asm_unmap_memory_regions(unsigned int dir, struct audio_client *ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	struct audio_port_data *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 	int cnt = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	port = &ac->port[dir];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 	if (!port->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	cnt = port->num_periods - 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 	if (cnt >= 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) 		rc = __q6asm_memory_unmap(ac, port->buf[dir].phys, dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 		if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) 			dev_err(ac->dev, "%s: Memory_unmap_regions failed %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) 				__func__, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	q6asm_audio_client_free_buf(ac, port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) EXPORT_SYMBOL_GPL(q6asm_unmap_memory_regions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) static int __q6asm_memory_map_regions(struct audio_client *ac, int dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 				      size_t period_sz, unsigned int periods,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 				      bool is_contiguous)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 	struct avs_cmd_shared_mem_map_regions *cmd = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 	struct avs_shared_map_region_payload *mregions = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 	struct q6asm *a = dev_get_drvdata(ac->dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 	struct audio_port_data *port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 	struct audio_buffer *ab = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 	uint32_t num_regions, buf_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 	int rc, i, pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 	if (is_contiguous) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 		num_regions = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		buf_sz = period_sz * periods;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		buf_sz = period_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 		num_regions = periods;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 	/* DSP expects size should be aligned to 4K */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 	buf_sz = ALIGN(buf_sz, 4096);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 	pkt_size = APR_HDR_SIZE + sizeof(*cmd) +
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		   (sizeof(*mregions) * num_regions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 	cmd = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 	mregions = p + APR_HDR_SIZE +  sizeof(*cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 	pkt->hdr.hdr_field = APR_SEQ_CMD_HDR_FIELD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	pkt->hdr.src_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) 	pkt->hdr.dest_port = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 	pkt->hdr.pkt_size = pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) 	pkt->hdr.token = ((ac->session << 8) | dir);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) 	pkt->hdr.opcode = ASM_CMD_SHARED_MEM_MAP_REGIONS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	cmd->mem_pool_id = ADSP_MEMORY_MAP_SHMEM8_4K_POOL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	cmd->num_regions = num_regions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 	cmd->property_flag = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 	spin_lock_irqsave(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	port = &ac->port[dir];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 	for (i = 0; i < num_regions; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 		ab = &port->buf[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		mregions->shm_addr_lsw = lower_32_bits(ab->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 		mregions->shm_addr_msw = upper_32_bits(ab->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 		mregions->mem_size_bytes = buf_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		++mregions;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 	spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 	rc = q6asm_apr_send_session_pkt(a, ac, pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 					ASM_CMDRSP_SHARED_MEM_MAP_REGIONS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490)  * q6asm_map_memory_regions() - map memory regions in the dsp.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492)  * @dir: direction of audio stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493)  * @ac: audio client instanace
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494)  * @phys: physcial address that needs mapping.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495)  * @period_sz: audio period size
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496)  * @periods: number of periods
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498)  * Return: Will be an negative value on failure or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) int q6asm_map_memory_regions(unsigned int dir, struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			     phys_addr_t phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 			     size_t period_sz, unsigned int periods)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 	struct audio_buffer *buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	int cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 	spin_lock_irqsave(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 	if (ac->port[dir].buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 		dev_err(ac->dev, "Buffer already allocated\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 		spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 	buf = kzalloc(((sizeof(struct audio_buffer)) * periods), GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 	if (!buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 		spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 	ac->port[dir].buf = buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  525) 	buf[0].phys = phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  526) 	buf[0].size = period_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	for (cnt = 1; cnt < periods; cnt++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) 		if (period_sz > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 			buf[cnt].phys = buf[0].phys + (cnt * period_sz);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) 			buf[cnt].size = period_sz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	ac->port[dir].num_periods = periods;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 	spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 	rc = __q6asm_memory_map_regions(ac, dir, period_sz, periods, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	if (rc < 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 		dev_err(ac->dev, "Memory_map_regions failed\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 		q6asm_audio_client_free_buf(ac, &ac->port[dir]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) EXPORT_SYMBOL_GPL(q6asm_map_memory_regions);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) static void q6asm_audio_client_release(struct kref *ref)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	struct audio_client *ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	struct q6asm *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) 	ac = container_of(ref, struct audio_client, refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) 	a = ac->q6asm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 	spin_lock_irqsave(&a->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	a->session[ac->session] = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 	spin_unlock_irqrestore(&a->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	kfree(ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565)  * q6asm_audio_client_free() - Freee allocated audio client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567)  * @ac: audio client to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  569) void q6asm_audio_client_free(struct audio_client *ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  570) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  571) 	kref_put(&ac->refcount, q6asm_audio_client_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) EXPORT_SYMBOL_GPL(q6asm_audio_client_free);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) static struct audio_client *q6asm_get_audio_client(struct q6asm *a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 						   int session_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 	struct audio_client *ac = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	spin_lock_irqsave(&a->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	if ((session_id <= 0) || (session_id > MAX_SESSIONS)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 		dev_err(a->dev, "invalid session: %d\n", session_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 	/* check for valid session */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	if (!a->session[session_id])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	else if (a->session[session_id]->session != session_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	ac = a->session[session_id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	kref_get(&ac->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	spin_unlock_irqrestore(&a->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 	return ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) static int32_t q6asm_stream_callback(struct apr_device *adev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 				     struct apr_resp_pkt *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 				     int session_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 	struct q6asm *q6asm = dev_get_drvdata(&adev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) 	struct aprv2_ibasic_rsp_result_t *result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 	struct apr_hdr *hdr = &data->hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 	struct audio_port_data *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) 	struct audio_client *ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	uint32_t client_event = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	ac = q6asm_get_audio_client(q6asm, session_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 	if (!ac)/* Audio client might already be freed by now */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 	result = data->payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	switch (hdr->opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 	case APR_BASIC_RSP_RESULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 		switch (result->opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 		case ASM_SESSION_CMD_PAUSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 			client_event = ASM_CLIENT_EVENT_CMD_PAUSE_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 		case ASM_SESSION_CMD_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 			client_event = ASM_CLIENT_EVENT_CMD_SUSPEND_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 		case ASM_STREAM_CMD_FLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 			client_event = ASM_CLIENT_EVENT_CMD_FLUSH_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 		case ASM_SESSION_CMD_RUN_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 			client_event = ASM_CLIENT_EVENT_CMD_RUN_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 		case ASM_STREAM_CMD_CLOSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 			client_event = ASM_CLIENT_EVENT_CMD_CLOSE_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 		case ASM_STREAM_CMD_FLUSH_READBUFS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 			client_event = ASM_CLIENT_EVENT_CMD_OUT_FLUSH_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		case ASM_STREAM_CMD_OPEN_WRITE_V3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 		case ASM_STREAM_CMD_OPEN_READ_V3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 		case ASM_STREAM_CMD_OPEN_READWRITE_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 		case ASM_STREAM_CMD_SET_ENCDEC_PARAM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		case ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 		case ASM_DATA_CMD_REMOVE_INITIAL_SILENCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 		case ASM_DATA_CMD_REMOVE_TRAILING_SILENCE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 			if (result->status != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 				dev_err(ac->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 					"cmd = 0x%x returned error = 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 					result->opcode, result->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 				ac->result = *result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 				wake_up(&ac->cmd_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 				ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 			dev_err(ac->dev, "command[0x%x] not expecting rsp\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 				result->opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) 		ac->result = *result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 		wake_up(&ac->cmd_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 		if (ac->cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) 			ac->cb(client_event, hdr->token,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) 			       data->payload, ac->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 		ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	case ASM_DATA_EVENT_WRITE_DONE_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 		client_event = ASM_CLIENT_EVENT_DATA_WRITE_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 		if (ac->io_mode & ASM_SYNC_IO_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 			phys_addr_t phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 			unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 			int token = hdr->token & ASM_WRITE_TOKEN_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 			spin_lock_irqsave(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 			port =  &ac->port[SNDRV_PCM_STREAM_PLAYBACK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 			if (!port->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 				spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 				ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 			phys = port->buf[token].phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			if (lower_32_bits(phys) != result->opcode ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 			    upper_32_bits(phys) != result->status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 				dev_err(ac->dev, "Expected addr %pa\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 					&port->buf[token].phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 				spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 				ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 			spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 	case ASM_DATA_EVENT_READ_DONE_V2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 		client_event = ASM_CLIENT_EVENT_DATA_READ_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 		if (ac->io_mode & ASM_SYNC_IO_MODE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 			struct asm_data_cmd_read_v2_done *done = data->payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) 			unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 			phys_addr_t phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 			spin_lock_irqsave(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) 			port =  &ac->port[SNDRV_PCM_STREAM_CAPTURE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 			if (!port->buf) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 				spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 				ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 			phys = port->buf[hdr->token].phys;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 			if (upper_32_bits(phys) != done->buf_addr_msw ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) 			    lower_32_bits(phys) != done->buf_addr_lsw) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 				dev_err(ac->dev, "Expected addr %pa %08x-%08x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) 					&port->buf[hdr->token].phys,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 					done->buf_addr_lsw,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) 					done->buf_addr_msw);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 				spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 				ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 				goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 			spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 	case ASM_DATA_EVENT_RENDERED_EOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		client_event = ASM_CLIENT_EVENT_CMD_EOS_DONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	if (ac->cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		ac->cb(client_event, hdr->token, data->payload, ac->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) 	kref_put(&ac->refcount, q6asm_audio_client_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) static int q6asm_srvc_callback(struct apr_device *adev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 			       struct apr_resp_pkt *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 	struct q6asm *q6asm = dev_get_drvdata(&adev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	struct aprv2_ibasic_rsp_result_t *result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 	struct audio_port_data *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 	struct audio_client *ac = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 	struct apr_hdr *hdr = &data->hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 	struct q6asm *a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 	uint32_t sid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 	uint32_t dir = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 	int session_id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 	session_id = (hdr->dest_port >> 8) & 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	if (session_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 		return q6asm_stream_callback(adev, data, session_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 	sid = (hdr->token >> 8) & 0x0F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 	ac = q6asm_get_audio_client(q6asm, sid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 	if (!ac) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 		dev_err(&adev->dev, "Audio Client not active\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 		return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) 	a = dev_get_drvdata(ac->dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	dir = (hdr->token & 0x0F);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 	port = &ac->port[dir];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	result = data->payload;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 	switch (hdr->opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) 	case APR_BASIC_RSP_RESULT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) 		switch (result->opcode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 		case ASM_CMD_SHARED_MEM_MAP_REGIONS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 		case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 			ac->result = *result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 			wake_up(&a->mem_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 			dev_err(&adev->dev, "command[0x%x] not expecting rsp\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 				 result->opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) 		goto done;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) 	case ASM_CMDRSP_SHARED_MEM_MAP_REGIONS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 		ac->result.status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 		ac->result.opcode = hdr->opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		port->mem_map_handle = result->opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		wake_up(&a->mem_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 	case ASM_CMD_SHARED_MEM_UNMAP_REGIONS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		ac->result.opcode = hdr->opcode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 		ac->result.status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		port->mem_map_handle = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		wake_up(&a->mem_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		dev_dbg(&adev->dev, "command[0x%x]success [0x%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 			result->opcode, result->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) 	if (ac->cb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 		ac->cb(hdr->opcode, hdr->token, data->payload, ac->priv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) done:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	kref_put(&ac->refcount, q6asm_audio_client_release);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817)  * q6asm_get_session_id() - get session id for audio client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819)  * @c: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821)  * Return: Will be an session id of the audio client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) int q6asm_get_session_id(struct audio_client *c)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	return c->session;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) EXPORT_SYMBOL_GPL(q6asm_get_session_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830)  * q6asm_audio_client_alloc() - Allocate a new audio client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832)  * @dev: Pointer to asm child device.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833)  * @cb: event callback.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834)  * @priv: private data associated with this client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835)  * @session_id: session id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836)  * @perf_mode: performace mode for this client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838)  * Return: Will be an error pointer on error or a valid audio client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839)  * on success.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) struct audio_client *q6asm_audio_client_alloc(struct device *dev, q6asm_cb cb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) 					      void *priv, int session_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 					      int perf_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	struct q6asm *a = dev_get_drvdata(dev->parent);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 	struct audio_client *ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 	ac = q6asm_get_audio_client(a, session_id + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	if (ac) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 		dev_err(dev, "Audio Client already active\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 		return ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	ac = kzalloc(sizeof(*ac), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 	if (!ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 		return ERR_PTR(-ENOMEM);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 	spin_lock_irqsave(&a->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 	a->session[session_id + 1] = ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	spin_unlock_irqrestore(&a->slock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 	ac->session = session_id + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 	ac->cb = cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 	ac->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 	ac->q6asm = a;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 	ac->priv = priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 	ac->io_mode = ASM_SYNC_IO_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 	ac->perf_mode = perf_mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 	ac->adev = a->adev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 	kref_init(&ac->refcount);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 	init_waitqueue_head(&ac->cmd_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 	mutex_init(&ac->cmd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	spin_lock_init(&ac->lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	return ac;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) EXPORT_SYMBOL_GPL(q6asm_audio_client_alloc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) static int q6asm_ac_send_cmd_sync(struct audio_client *ac, struct apr_pkt *pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 	struct apr_hdr *hdr = &pkt->hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 	mutex_lock(&ac->cmd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 	ac->result.opcode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 	ac->result.status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 	rc = apr_send_pkt(ac->adev, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 	rc = wait_event_timeout(ac->cmd_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 				(ac->result.opcode == hdr->opcode), 5 * HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 	if (!rc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 		dev_err(ac->dev, "CMD %x timeout\n", hdr->opcode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 		rc =  -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 	if (ac->result.status > 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 		dev_err(ac->dev, "DSP returned error[%x]\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 			ac->result.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	mutex_unlock(&ac->cmd_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916)  * q6asm_open_write() - Open audio client for writing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917)  * @ac: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918)  * @stream_id: stream id of q6asm session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919)  * @format: audio sample format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920)  * @codec_profile: compressed format profile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921)  * @bits_per_sample: bits per sample
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922)  * @is_gapless: flag to indicate if this is a gapless stream
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924)  * Return: Will be an negative value on error or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) int q6asm_open_write(struct audio_client *ac, uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 		     uint32_t format, u32 codec_profile,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 		     uint16_t bits_per_sample, bool is_gapless)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	struct asm_stream_cmd_open_write_v3 *open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	int rc, pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	pkt_size = APR_HDR_SIZE + sizeof(*open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 	open = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	pkt->hdr.opcode = ASM_STREAM_CMD_OPEN_WRITE_V3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	open->mode_flags = 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	open->mode_flags |= ASM_LEGACY_STREAM_SESSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	if (is_gapless)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 		open->mode_flags |= BIT(ASM_SHIFT_GAPLESS_MODE_FLAG);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	/* source endpoint : matrix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 	open->sink_endpointype = ASM_END_POINT_DEVICE_MATRIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 	open->bits_per_sample = bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	open->postprocopo_id = ASM_NULL_POPP_TOPOLOGY;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	switch (format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 	case SND_AUDIOCODEC_MP3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		open->dec_fmt_id = ASM_MEDIA_FMT_MP3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 	case FORMAT_LINEAR_PCM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 		open->dec_fmt_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	case SND_AUDIOCODEC_FLAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		open->dec_fmt_id = ASM_MEDIA_FMT_FLAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	case SND_AUDIOCODEC_WMA:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 		switch (codec_profile) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 		case SND_AUDIOPROFILE_WMA9:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 			open->dec_fmt_id = ASM_MEDIA_FMT_WMA_V9;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		case SND_AUDIOPROFILE_WMA10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		case SND_AUDIOPROFILE_WMA9_PRO:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 		case SND_AUDIOPROFILE_WMA9_LOSSLESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 		case SND_AUDIOPROFILE_WMA10_LOSSLESS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 			open->dec_fmt_id = ASM_MEDIA_FMT_WMA_V10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 			dev_err(ac->dev, "Invalid codec profile 0x%x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 				codec_profile);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 			rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 	case SND_AUDIOCODEC_ALAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		open->dec_fmt_id = ASM_MEDIA_FMT_ALAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 	case SND_AUDIOCODEC_APE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 		open->dec_fmt_id = ASM_MEDIA_FMT_APE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 		dev_err(ac->dev, "Invalid format 0x%x\n", format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 	rc = q6asm_ac_send_cmd_sync(ac, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 	ac->io_mode |= ASM_TUN_WRITE_IO_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006) EXPORT_SYMBOL_GPL(q6asm_open_write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) static int __q6asm_run(struct audio_client *ac, uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		       uint32_t flags, uint32_t msw_ts, uint32_t lsw_ts,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 		       bool wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	struct asm_session_cmd_run_v2 *run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) 	int pkt_size, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	pkt_size = APR_HDR_SIZE + sizeof(*run);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	p = kzalloc(pkt_size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	run = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 	pkt->hdr.opcode = ASM_SESSION_CMD_RUN_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	run->flags = flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 	run->time_lsw = lsw_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	run->time_msw = msw_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 	if (wait) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 		rc = q6asm_ac_send_cmd_sync(ac, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 		rc = apr_send_pkt(ac->adev, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 		if (rc == pkt_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 			rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044)  * q6asm_run() - start the audio client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046)  * @ac: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047)  * @stream_id: stream id of q6asm session
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048)  * @flags: flags associated with write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049)  * @msw_ts: timestamp msw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050)  * @lsw_ts: timestamp lsw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052)  * Return: Will be an negative value on error or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) int q6asm_run(struct audio_client *ac, uint32_t stream_id, uint32_t flags,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) 	      uint32_t msw_ts, uint32_t lsw_ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	return __q6asm_run(ac, stream_id, flags, msw_ts, lsw_ts, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) EXPORT_SYMBOL_GPL(q6asm_run);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062)  * q6asm_run_nowait() - start the audio client withou blocking
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064)  * @ac: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)  * @stream_id: stream id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066)  * @flags: flags associated with write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067)  * @msw_ts: timestamp msw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)  * @lsw_ts: timestamp lsw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070)  * Return: Will be an negative value on error or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) int q6asm_run_nowait(struct audio_client *ac, uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 		     uint32_t flags, uint32_t msw_ts, uint32_t lsw_ts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 	return __q6asm_run(ac, stream_id, flags, msw_ts, lsw_ts, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) EXPORT_SYMBOL_GPL(q6asm_run_nowait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)  * q6asm_media_format_block_multi_ch_pcm() - setup pcm configuration
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082)  * @ac: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083)  * @stream_id: stream id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)  * @rate: audio sample rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085)  * @channels: number of audio channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086)  * @channel_map: channel map pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087)  * @bits_per_sample: bits per sample
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089)  * Return: Will be an negative value on error or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) int q6asm_media_format_block_multi_ch_pcm(struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 					  uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 					  uint32_t rate, uint32_t channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 					  u8 channel_map[PCM_MAX_NUM_CHANNEL],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 					  uint16_t bits_per_sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 	struct asm_multi_channel_pcm_fmt_blk_v2 *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 	u8 *channel_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 	int rc, pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 	pkt_size = APR_HDR_SIZE + sizeof(*fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 	fmt = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 	pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 	fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	fmt->num_channels = channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) 	fmt->bits_per_sample = bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 	fmt->sample_rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) 	fmt->is_signed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) 	channel_mapping = fmt->channel_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	if (channel_map) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 		memcpy(channel_mapping, channel_map, PCM_MAX_NUM_CHANNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 		if (q6dsp_map_channels(channel_mapping, channels)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 			dev_err(ac->dev, " map channels failed %d\n", channels);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 			rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 	rc = q6asm_ac_send_cmd_sync(ac, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) EXPORT_SYMBOL_GPL(q6asm_media_format_block_multi_ch_pcm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) int q6asm_stream_media_format_block_flac(struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) 					 uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 					 struct q6asm_flac_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	struct asm_flac_fmt_blk_v2 *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	int rc, pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 	pkt_size = APR_HDR_SIZE + sizeof(*fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	fmt = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 	pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 	fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 	fmt->is_stream_info_present = cfg->stream_info_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) 	fmt->num_channels = cfg->ch_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	fmt->min_blk_size = cfg->min_blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 	fmt->max_blk_size = cfg->max_blk_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	fmt->sample_rate = cfg->sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	fmt->min_frame_size = cfg->min_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 	fmt->max_frame_size = cfg->max_frame_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 	fmt->sample_size = cfg->sample_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	rc = q6asm_ac_send_cmd_sync(ac, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_flac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) int q6asm_stream_media_format_block_wma_v9(struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) 					   uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 					   struct q6asm_wma_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) 	struct asm_wmastdv9_fmt_blk_v2 *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 	int rc, pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	pkt_size = APR_HDR_SIZE + sizeof(*fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) 	fmt = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 	fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 	fmt->fmtag = cfg->fmtag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	fmt->num_channels = cfg->num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) 	fmt->sample_rate = cfg->sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 	fmt->bytes_per_sec = cfg->bytes_per_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) 	fmt->blk_align = cfg->block_align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) 	fmt->bits_per_sample = cfg->bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	fmt->channel_mask = cfg->channel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 	fmt->enc_options = cfg->enc_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	fmt->reserved = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 	rc = q6asm_ac_send_cmd_sync(ac, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_wma_v9);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) int q6asm_stream_media_format_block_wma_v10(struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 					    uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 					    struct q6asm_wma_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	struct asm_wmaprov10_fmt_blk_v2 *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	int rc, pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	pkt_size = APR_HDR_SIZE + sizeof(*fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	fmt = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 	pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 	fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	fmt->fmtag = cfg->fmtag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) 	fmt->num_channels = cfg->num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 	fmt->sample_rate = cfg->sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) 	fmt->bytes_per_sec = cfg->bytes_per_sec;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) 	fmt->blk_align = cfg->block_align;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	fmt->bits_per_sample = cfg->bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 	fmt->channel_mask = cfg->channel_mask;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	fmt->enc_options = cfg->enc_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	fmt->advanced_enc_options1 = cfg->adv_enc_options;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	fmt->advanced_enc_options2 = cfg->adv_enc_options2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 	rc = q6asm_ac_send_cmd_sync(ac, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_wma_v10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) int q6asm_stream_media_format_block_alac(struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 					 uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 					 struct q6asm_alac_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 	struct asm_alac_fmt_blk_v2 *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 	int rc, pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 	pkt_size = APR_HDR_SIZE + sizeof(*fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	fmt = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) 	pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	fmt->frame_length = cfg->frame_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) 	fmt->compatible_version = cfg->compatible_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 	fmt->bit_depth =  cfg->bit_depth;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) 	fmt->num_channels = cfg->num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	fmt->max_run = cfg->max_run;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	fmt->max_frame_bytes = cfg->max_frame_bytes;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	fmt->avg_bit_rate = cfg->avg_bit_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	fmt->sample_rate = cfg->sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	fmt->channel_layout_tag = cfg->channel_layout_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) 	fmt->pb = cfg->pb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 	fmt->mb = cfg->mb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) 	fmt->kb = cfg->kb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	rc = q6asm_ac_send_cmd_sync(ac, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_alac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) int q6asm_stream_media_format_block_ape(struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) 					uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 					struct q6asm_ape_cfg *cfg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) 	struct asm_ape_fmt_blk_v2 *fmt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) 	int rc, pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) 	pkt_size = APR_HDR_SIZE + sizeof(*fmt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) 	fmt = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) 	pkt->hdr.opcode = ASM_DATA_CMD_MEDIA_FMT_UPDATE_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) 	fmt->fmt_blk.fmt_blk_size = sizeof(*fmt) - sizeof(fmt->fmt_blk);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) 	fmt->compatible_version = cfg->compatible_version;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) 	fmt->compression_level = cfg->compression_level;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) 	fmt->format_flags = cfg->format_flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) 	fmt->blocks_per_frame = cfg->blocks_per_frame;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322) 	fmt->final_frame_blocks = cfg->final_frame_blocks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) 	fmt->total_frames = cfg->total_frames;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) 	fmt->bits_per_sample = cfg->bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) 	fmt->num_channels = cfg->num_channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) 	fmt->sample_rate = cfg->sample_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) 	fmt->seek_table_present = cfg->seek_table_present;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) 	rc = q6asm_ac_send_cmd_sync(ac, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334) EXPORT_SYMBOL_GPL(q6asm_stream_media_format_block_ape);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) static int q6asm_stream_remove_silence(struct audio_client *ac, uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) 				       uint32_t cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) 				       uint32_t num_samples)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340) 	uint32_t *samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) 	int rc, pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) 	pkt_size = APR_HDR_SIZE + sizeof(uint32_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) 	p = kzalloc(pkt_size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) 	samples = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) 	pkt->hdr.opcode = cmd;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) 	*samples = num_samples;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357) 	rc = apr_send_pkt(ac->adev, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) 	if (rc == pkt_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) int q6asm_stream_remove_initial_silence(struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) 					uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) 					uint32_t initial_samples)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) 	return q6asm_stream_remove_silence(ac, stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371) 					   ASM_DATA_CMD_REMOVE_INITIAL_SILENCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) 					   initial_samples);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) EXPORT_SYMBOL_GPL(q6asm_stream_remove_initial_silence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) int q6asm_stream_remove_trailing_silence(struct audio_client *ac, uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) 					 uint32_t trailing_samples)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379) 	return q6asm_stream_remove_silence(ac, stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) 				   ASM_DATA_CMD_REMOVE_TRAILING_SILENCE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) 				   trailing_samples);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) EXPORT_SYMBOL_GPL(q6asm_stream_remove_trailing_silence);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386)  * q6asm_enc_cfg_blk_pcm_format_support() - setup pcm configuration for capture
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388)  * @ac: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389)  * @stream_id: stream id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1390)  * @rate: audio sample rate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1391)  * @channels: number of audio channels.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1392)  * @bits_per_sample: bits per sample
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1393)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1394)  * Return: Will be an negative value on error or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1395)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1396) int q6asm_enc_cfg_blk_pcm_format_support(struct audio_client *ac,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1397) 					 uint32_t stream_id, uint32_t rate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1398) 					 uint32_t channels,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1399) 					 uint16_t bits_per_sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1400) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1401) 	struct asm_multi_channel_pcm_enc_cfg_v2  *enc_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1402) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1403) 	u8 *channel_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1404) 	u32 frames_per_buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1405) 	int pkt_size, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1406) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1408) 	pkt_size = APR_HDR_SIZE + sizeof(*enc_cfg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1409) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1410) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1411) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1412) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1413) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1414) 	enc_cfg = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1415) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1416) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1417) 	pkt->hdr.opcode = ASM_STREAM_CMD_SET_ENCDEC_PARAM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1418) 	enc_cfg->encdec.param_id = ASM_PARAM_ID_ENCDEC_ENC_CFG_BLK_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1419) 	enc_cfg->encdec.param_size = sizeof(*enc_cfg) - sizeof(enc_cfg->encdec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1420) 	enc_cfg->encblk.frames_per_buf = frames_per_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1421) 	enc_cfg->encblk.enc_cfg_blk_size  = enc_cfg->encdec.param_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1422) 					sizeof(struct asm_enc_cfg_blk_param_v2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1423) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1424) 	enc_cfg->num_channels = channels;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1425) 	enc_cfg->bits_per_sample = bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1426) 	enc_cfg->sample_rate = rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1427) 	enc_cfg->is_signed = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1428) 	channel_mapping = enc_cfg->channel_mapping;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1429) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1430) 	if (q6dsp_map_channels(channel_mapping, channels)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1431) 		rc = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1432) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1433) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1434) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1435) 	rc = q6asm_ac_send_cmd_sync(ac, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1436) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1437) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1438) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1439) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1440) EXPORT_SYMBOL_GPL(q6asm_enc_cfg_blk_pcm_format_support);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1441) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1442) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1443) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1444)  * q6asm_read() - read data of period size from audio client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1445)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1446)  * @ac: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1447)  * @stream_id: stream id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1448)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1449)  * Return: Will be an negative value on error or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1450)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1451) int q6asm_read(struct audio_client *ac, uint32_t stream_id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1452) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1453) 	struct asm_data_cmd_read_v2 *read;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1454) 	struct audio_port_data *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1455) 	struct audio_buffer *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1456) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1457) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1458) 	int pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1459) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1460) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1462) 	pkt_size = APR_HDR_SIZE + sizeof(*read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1463) 	p = kzalloc(pkt_size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1464) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1465) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1466) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1467) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1468) 	read = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1470) 	spin_lock_irqsave(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1471) 	port = &ac->port[SNDRV_PCM_STREAM_CAPTURE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1472) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, false, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1473) 	ab = &port->buf[port->dsp_buf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1474) 	pkt->hdr.opcode = ASM_DATA_CMD_READ_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1475) 	read->buf_addr_lsw = lower_32_bits(ab->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1476) 	read->buf_addr_msw = upper_32_bits(ab->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1477) 	read->mem_map_handle = port->mem_map_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1478) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1479) 	read->buf_size = ab->size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1480) 	read->seq_id = port->dsp_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1481) 	pkt->hdr.token = port->dsp_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1482) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1483) 	port->dsp_buf++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1484) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1485) 	if (port->dsp_buf >= port->num_periods)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1486) 		port->dsp_buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1487) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1488) 	spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1489) 	rc = apr_send_pkt(ac->adev, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1490) 	if (rc == pkt_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1491) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1492) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1493) 		pr_err("read op[0x%x]rc[%d]\n", pkt->hdr.opcode, rc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1494) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1495) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1496) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1497) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1498) EXPORT_SYMBOL_GPL(q6asm_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1499) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1500) static int __q6asm_open_read(struct audio_client *ac, uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1501) 		uint32_t format, uint16_t bits_per_sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1502) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1503) 	struct asm_stream_cmd_open_read_v3 *open;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1504) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1505) 	int pkt_size, rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1506) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1507) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1508) 	pkt_size = APR_HDR_SIZE + sizeof(*open);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1509) 	p = kzalloc(pkt_size, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1510) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1511) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1512) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1513) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1514) 	open = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1515) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1516) 	q6asm_add_hdr(ac, &pkt->hdr,  pkt_size, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1517) 	pkt->hdr.opcode = ASM_STREAM_CMD_OPEN_READ_V3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1518) 	/* Stream prio : High, provide meta info with encoded frames */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1519) 	open->src_endpointype = ASM_END_POINT_DEVICE_MATRIX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1520) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1521) 	open->preprocopo_id = ASM_STREAM_POSTPROC_TOPO_ID_NONE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1522) 	open->bits_per_sample = bits_per_sample;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1523) 	open->mode_flags = 0x0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1524) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1525) 	open->mode_flags |= ASM_LEGACY_STREAM_SESSION <<
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1526) 				ASM_SHIFT_STREAM_PERF_MODE_FLAG_IN_OPEN_READ;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1527) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1528) 	switch (format) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1529) 	case FORMAT_LINEAR_PCM:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1530) 		open->mode_flags |= 0x00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1531) 		open->enc_cfg_id = ASM_MEDIA_FMT_MULTI_CHANNEL_PCM_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1532) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1533) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1534) 		pr_err("Invalid format[%d]\n", format);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1535) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1536) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1537) 	rc = q6asm_ac_send_cmd_sync(ac, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1538) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1539) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1540) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1541) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1542) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1543) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1544)  * q6asm_open_read() - Open audio client for reading
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1545)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1546)  * @ac: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1547)  * @stream_id: stream id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1548)  * @format: audio sample format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1549)  * @bits_per_sample: bits per sample
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1550)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1551)  * Return: Will be an negative value on error or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1552)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1553) int q6asm_open_read(struct audio_client *ac, uint32_t stream_id,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1554) 		    uint32_t format, uint16_t bits_per_sample)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1556) 	return __q6asm_open_read(ac, stream_id, format, bits_per_sample);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1557) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1558) EXPORT_SYMBOL_GPL(q6asm_open_read);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1560) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1561)  * q6asm_write_async() - non blocking write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1562)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1563)  * @ac: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1564)  * @stream_id: stream id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1565)  * @len: length in bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1566)  * @msw_ts: timestamp msw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1567)  * @lsw_ts: timestamp lsw
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1568)  * @wflags: flags associated with write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1569)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1570)  * Return: Will be an negative value on error or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1571)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1572) int q6asm_write_async(struct audio_client *ac, uint32_t stream_id, uint32_t len,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1573) 		      uint32_t msw_ts, uint32_t lsw_ts, uint32_t wflags)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1575) 	struct asm_data_cmd_write_v2 *write;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1576) 	struct audio_port_data *port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1577) 	struct audio_buffer *ab;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1578) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1579) 	struct apr_pkt *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1580) 	int pkt_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1581) 	int rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1582) 	void *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1584) 	pkt_size = APR_HDR_SIZE + sizeof(*write);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1585) 	p = kzalloc(pkt_size, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1586) 	if (!p)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1587) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1588) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1589) 	pkt = p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1590) 	write = p + APR_HDR_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1591) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1592) 	spin_lock_irqsave(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1593) 	port = &ac->port[SNDRV_PCM_STREAM_PLAYBACK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1594) 	q6asm_add_hdr(ac, &pkt->hdr, pkt_size, false, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1596) 	ab = &port->buf[port->dsp_buf];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1597) 	pkt->hdr.token = port->dsp_buf | (len << ASM_WRITE_TOKEN_LEN_SHIFT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1598) 	pkt->hdr.opcode = ASM_DATA_CMD_WRITE_V2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1599) 	write->buf_addr_lsw = lower_32_bits(ab->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1600) 	write->buf_addr_msw = upper_32_bits(ab->phys);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1601) 	write->buf_size = len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1602) 	write->seq_id = port->dsp_buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1603) 	write->timestamp_lsw = lsw_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1604) 	write->timestamp_msw = msw_ts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1605) 	write->mem_map_handle =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1606) 	    ac->port[SNDRV_PCM_STREAM_PLAYBACK].mem_map_handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1607) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1608) 	write->flags = wflags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1609) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1610) 	port->dsp_buf++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1611) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1612) 	if (port->dsp_buf >= port->num_periods)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1613) 		port->dsp_buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1614) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1615) 	spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1616) 	rc = apr_send_pkt(ac->adev, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1617) 	if (rc == pkt_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1618) 		rc = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1620) 	kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1621) 	return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1622) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1623) EXPORT_SYMBOL_GPL(q6asm_write_async);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1624) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1625) static void q6asm_reset_buf_state(struct audio_client *ac)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1626) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1627) 	struct audio_port_data *port = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1628) 	unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1629) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1630) 	spin_lock_irqsave(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1631) 	port = &ac->port[SNDRV_PCM_STREAM_PLAYBACK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1632) 	port->dsp_buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1633) 	port = &ac->port[SNDRV_PCM_STREAM_CAPTURE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1634) 	port->dsp_buf = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1635) 	spin_unlock_irqrestore(&ac->lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1636) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1637) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1638) static int __q6asm_cmd(struct audio_client *ac, uint32_t stream_id, int cmd,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1639) 		       bool wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1640) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1641) 	struct apr_pkt pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1642) 	int rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1643) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1644) 	q6asm_add_hdr(ac, &pkt.hdr, APR_HDR_SIZE, true, stream_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1645) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1646) 	switch (cmd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1647) 	case CMD_PAUSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1648) 		pkt.hdr.opcode = ASM_SESSION_CMD_PAUSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1649) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1650) 	case CMD_SUSPEND:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1651) 		pkt.hdr.opcode = ASM_SESSION_CMD_SUSPEND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1652) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1653) 	case CMD_FLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1654) 		pkt.hdr.opcode = ASM_STREAM_CMD_FLUSH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1655) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1656) 	case CMD_OUT_FLUSH:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1657) 		pkt.hdr.opcode = ASM_STREAM_CMD_FLUSH_READBUFS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1658) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1659) 	case CMD_EOS:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1660) 		pkt.hdr.opcode = ASM_DATA_CMD_EOS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1661) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1662) 	case CMD_CLOSE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1663) 		pkt.hdr.opcode = ASM_STREAM_CMD_CLOSE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1664) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1665) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1666) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1667) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1668) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1669) 	if (wait)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1670) 		rc = q6asm_ac_send_cmd_sync(ac, &pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1671) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1672) 		return apr_send_pkt(ac->adev, &pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1673) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1674) 	if (rc < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1675) 		return rc;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1677) 	if (cmd == CMD_FLUSH)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1678) 		q6asm_reset_buf_state(ac);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1679) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1680) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1682) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1683) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1684)  * q6asm_cmd() - run cmd on audio client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1685)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1686)  * @ac: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1687)  * @stream_id: stream id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1688)  * @cmd: command to run on audio client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1689)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1690)  * Return: Will be an negative value on error or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1691)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1692) int q6asm_cmd(struct audio_client *ac, uint32_t stream_id, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1693) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1694) 	return __q6asm_cmd(ac, stream_id, cmd, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1695) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1696) EXPORT_SYMBOL_GPL(q6asm_cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1697) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1698) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1699)  * q6asm_cmd_nowait() - non blocking, run cmd on audio client
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1700)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1701)  * @ac: audio client pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1702)  * @stream_id: stream id
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1703)  * @cmd: command to run on audio client.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1704)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1705)  * Return: Will be an negative value on error or zero on success
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1706)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1707) int q6asm_cmd_nowait(struct audio_client *ac, uint32_t stream_id, int cmd)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1708) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1709) 	return __q6asm_cmd(ac, stream_id, cmd, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1710) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1711) EXPORT_SYMBOL_GPL(q6asm_cmd_nowait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1712) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1713) static int q6asm_probe(struct apr_device *adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1714) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1715) 	struct device *dev = &adev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1716) 	struct q6asm *q6asm;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1717) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1718) 	q6asm = devm_kzalloc(dev, sizeof(*q6asm), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1719) 	if (!q6asm)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1720) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1722) 	q6core_get_svc_api_info(adev->svc_id, &q6asm->ainfo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1723) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1724) 	q6asm->dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1725) 	q6asm->adev = adev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1726) 	init_waitqueue_head(&q6asm->mem_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1727) 	spin_lock_init(&q6asm->slock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1728) 	dev_set_drvdata(dev, q6asm);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1730) 	return of_platform_populate(dev->of_node, NULL, NULL, dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1731) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1732) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1733) static int q6asm_remove(struct apr_device *adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1734) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1735) 	of_platform_depopulate(&adev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1736) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1737) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1738) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1739) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1740) #ifdef CONFIG_OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1741) static const struct of_device_id q6asm_device_id[]  = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1742) 	{ .compatible = "qcom,q6asm" },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1743) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1744) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1745) MODULE_DEVICE_TABLE(of, q6asm_device_id);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1746) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1747) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1748) static struct apr_driver qcom_q6asm_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1749) 	.probe = q6asm_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1750) 	.remove = q6asm_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1751) 	.callback = q6asm_srvc_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1752) 	.driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1753) 		.name = "qcom-q6asm",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1754) 		.of_match_table = of_match_ptr(q6asm_device_id),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1755) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1756) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1757) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1758) module_apr_driver(qcom_q6asm_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1759) MODULE_DESCRIPTION("Q6 Audio Stream Manager driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1760) MODULE_LICENSE("GPL v2");