1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2019 Intel Corporation. All rights reserved. 4 * 5 * Author: Artur Kloniecki <arturx.kloniecki@linux.intel.com> 6 */ 7 8 /** 9 * \file include/sof/audio/mux.h 10 * \brief Multiplexer component header file 11 * \authors Artur Kloniecki <arturx.kloniecki@linux.intel.com> 12 */ 13 14 #ifndef __SOF_AUDIO_MUX_H__ 15 #define __SOF_AUDIO_MUX_H__ 16 17 #if CONFIG_COMP_MUX 18 19 #include <sof/common.h> 20 #include <sof/platform.h> 21 #include <sof/trace/trace.h> 22 #include <sof/ut.h> 23 #include <user/trace.h> 24 #include <stdint.h> 25 #if CONFIG_IPC_MAJOR_4 26 #include <ipc4/base-config.h> 27 #endif 28 struct comp_buffer; 29 struct comp_dev; 30 31 /** \brief Supported streams count. */ 32 #if CONFIG_IPC_MAJOR_3 33 #define MUX_MAX_STREAMS 4 34 #else 35 #define MUX_MAX_STREAMS 2 36 #endif 37 #define BASE_CFG_QUEUED_ID 0 38 /** guard against invalid amount of streams defined */ 39 STATIC_ASSERT(MUX_MAX_STREAMS < PLATFORM_MAX_STREAMS, 40 unsupported_amount_of_streams_for_mux); 41 42 struct mux_copy_elem { 43 uint32_t stream_id; 44 uint32_t in_ch; 45 uint32_t out_ch; 46 47 void *dest; 48 void *src; 49 50 uint32_t dest_inc; 51 uint32_t src_inc; 52 }; 53 54 struct mux_look_up { 55 uint32_t num_elems; 56 struct mux_copy_elem copy_elem[PLATFORM_MAX_CHANNELS]; 57 }; 58 59 struct mux_stream_data { 60 uint32_t pipeline_id; 61 uint8_t num_channels_deprecated; /* deprecated in ABI 3.15 */ 62 uint8_t mask[PLATFORM_MAX_CHANNELS]; 63 64 uint8_t reserved1[8 - PLATFORM_MAX_CHANNELS]; // padding for extra channels 65 uint8_t reserved2[3]; // padding to ensure proper alignment of following instances 66 } __attribute__((packed, aligned(4))); 67 68 typedef void(*demux_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, 69 const struct audio_stream __sparse_cache *source, uint32_t frames, 70 struct mux_look_up *look_up); 71 typedef void(*mux_func)(struct comp_dev *dev, struct audio_stream __sparse_cache *sink, 72 const struct audio_stream __sparse_cache **sources, uint32_t frames, 73 struct mux_look_up *look_up); 74 75 /** 76 * \brief Mux/Demux component config structure. 77 * 78 * The multiplexer/demultiplexer component copies its input audio channels 79 * into output audio channels according to a specific routing matrix. 80 * Multiplexer has multiple input audio streams and a single audio output 81 * stream. Demultiplexer has a single input stream and multiple output streams. 82 * 83 * Struct sof_mux_config includes array of mux_stream_data struct elements - 84 * streams[]. Each element of streams[] array refers to streams on "many" side 85 * of mux/demux component i.e. input streams for mux and output streams for 86 * demux. 87 * 88 * Struct mux_stream_data consists mask[] array. 89 * In the mux case, one mask[] element per input channel - each mask shows, to 90 * which output channel data should be copied. 91 * In the demux case, one mask[] element per output channel - each mask shows, 92 * from which input channel data should be taken. 93 * 94 * Mux example: 95 * Assuming that below mask array refers to x input stream: 96 * mask[] = { 0b00000001, 97 * 0b00000100 } 98 * it means that: 99 * - first input channel of stream x (mask[0]) will be copied to first output 100 * channel (0b00000001 & BIT(0)); 101 * - second input channel of stream x (mask[1]) will be copied to third output 102 * channel (0b00000100 & BIT(2)). 103 * 104 * Demux example: 105 * Assuming that below mask array refers to x output stream: 106 * mask[] = { 0b00000001, 107 * 0b00000100 } 108 * it means that: 109 * - first input channel (0b00000001 & BIT(0)) will be copied to first output 110 * (mask[0]) channel of stream x; 111 * - third input channel (0b00000100 & BIT(2)) will be copied to second output 112 * (mask[1]) channel of stream x. 113 */ 114 struct sof_mux_config { 115 uint16_t frame_format_deprecated; /* deprecated in ABI 3.15 */ 116 uint16_t num_channels_deprecated; /* deprecated in ABI 3.15 */ 117 uint16_t num_streams; 118 119 uint16_t reserved; // padding to ensure proper alignment 120 121 struct mux_stream_data streams[]; 122 } __attribute__((packed, aligned(4))); 123 124 #if CONFIG_IPC_MAJOR_4 125 /** 126 * \brief MUX module configuration in IPC4. 127 * 128 * This module output map is statically defined by the adapter (shim) as: 129 * - Input pin 0 channel "x" ("x" = 0.."M", "M" <=3) to output channel "x", 130 * where "M" is number of channels on input pin 0, 131 * - Input pin 1 (reference) channel "y" (y = 0..1) to output channel "M"+1+"y". 132 * 133 * If input pin 0 is not connected, module will not produce any output. 134 * If input pin 1 (know also as reference pin) is not connected then module will 135 * in output (for time slot meant for pin 1) generate zeros. 136 * 137 * Setting masks for streams is done according to the order of pins and channels. 138 * First the first input stream, then the reference. 139 * For example, for base config 2-channel and reference 2-channel, masks 140 * should look like: mask[] = { 0b00000001, 0b00000010 } for the first 141 * stream and mask[] = { 0b00000100, 0b00001000 } for the second 142 * (reference) 143 * +---+ +---+ 144 * | 0 |---------> | 0 | 145 * INPUT +---+ +---+ 146 * STREAM 0 | 1 |---------> | 1 | 147 * +---+ +---+ OUTPUT 148 * +----> | 2 | STREAM 149 * +---+ | +---+ 150 * | 0 |----+ +-> | 3 | 151 * INPUT +---+ | +---+ 152 * STREAM 1 | 1 |-------+ 153 * +---+ 154 */ 155 struct mux_data { 156 struct ipc4_base_module_cfg base_cfg; 157 //! Reference pin format. 158 struct ipc4_audio_format reference_format; 159 //! Output pin format. 160 struct ipc4_audio_format output_format; 161 }; 162 #endif 163 164 struct comp_data { 165 #if CONFIG_IPC_MAJOR_4 166 struct mux_data md; 167 #endif 168 union { 169 mux_func mux; 170 demux_func demux; 171 }; 172 173 struct mux_look_up lookup[MUX_MAX_STREAMS]; 174 struct mux_look_up active_lookup; 175 struct comp_data_blob_handler *model_handler; 176 struct sof_mux_config config; /* Keep last due to flexible array member in end */ 177 }; 178 179 struct comp_func_map { 180 uint16_t frame_format; 181 mux_func mux_proc_func; 182 demux_func demux_proc_func; 183 }; 184 185 extern const struct comp_func_map mux_func_map[]; 186 187 void mux_prepare_look_up_table(struct processing_module *mod); 188 void demux_prepare_look_up_table(struct processing_module *mod); 189 190 mux_func mux_get_processing_function(struct processing_module *mod); 191 demux_func demux_get_processing_function(struct processing_module *mod); 192 193 #ifdef UNIT_TEST 194 195 #if CONFIG_FORMAT_S16LE 196 int32_t calc_sample_s16le(const struct audio_stream *source, 197 uint32_t offset, uint8_t mask); 198 #endif /* CONFIG_FORMAT_S16LE */ 199 #if CONFIG_FORMAT_S24LE 200 int32_t calc_sample_s24le(const struct audio_stream *source, 201 uint32_t offset, uint8_t mask); 202 #endif /* CONFIG_FORMAT_S24LE */ 203 #if CONFIG_FORMAT_S32LE 204 int64_t calc_sample_s32le(const struct audio_stream *source, 205 uint32_t offset, uint8_t mask); 206 #endif /* CONFIG_FORMAT_S32LE */ 207 208 void sys_comp_module_mux_interface_init(void); 209 void sys_comp_module_demux_interface_init(void); 210 211 #endif /* UNIT_TEST */ 212 213 #endif /* CONFIG_COMP_MUX */ 214 215 #endif /* __SOF_AUDIO_MUX_H__ */ 216