^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");