1 /* SPDX-License-Identifier: BSD-3-Clause 2 * 3 * Copyright(c) 2020 Intel Corporation. All rights reserved. 4 * 5 * 6 * \file generic.h 7 * \brief Generic Codec API header file 8 * \author Marcin Rajwa <marcin.rajwa@linux.intel.com> 9 * 10 */ 11 12 #ifndef __SOF_AUDIO_CODEC_GENERIC__ 13 #define __SOF_AUDIO_CODEC_GENERIC__ 14 15 #include <sof/audio/component.h> 16 #include <sof/ut.h> 17 #include <sof/lib/memory.h> 18 19 #define comp_get_codec(d) (&(((struct comp_data *)((d)->priv_data))->codec)) 20 #define CODEC_GET_INTERFACE_ID(id) ((id) >> 0x8) 21 #define CODEC_GET_API_ID(id) ((id) & 0xFF) 22 #define API_CALL(cd, cmd, sub_cmd, value, ret) \ 23 do { \ 24 ret = (cd)->api((cd)->self, \ 25 (cmd), \ 26 (sub_cmd), \ 27 (value)); \ 28 } while (0) 29 30 #define DECLARE_CODEC_ADAPTER(adapter, uuid, tr) \ 31 static struct comp_dev *adapter_shim_new(const struct comp_driver *drv, \ 32 struct comp_ipc_config *config, \ 33 void *spec) \ 34 { \ 35 return codec_adapter_new(drv, config, &(adapter), spec);\ 36 } \ 37 \ 38 static const struct comp_driver comp_codec_adapter = { \ 39 .type = SOF_COMP_CODEC_ADAPTOR, \ 40 .uid = SOF_RT_UUID(uuid), \ 41 .tctx = &(tr), \ 42 .ops = { \ 43 .create = adapter_shim_new, \ 44 .prepare = codec_adapter_prepare, \ 45 .params = codec_adapter_params, \ 46 .copy = codec_adapter_copy, \ 47 .cmd = codec_adapter_cmd, \ 48 .trigger = codec_adapter_trigger, \ 49 .reset = codec_adapter_reset, \ 50 .free = codec_adapter_free, \ 51 }, \ 52 }; \ 53 \ 54 static SHARED_DATA struct comp_driver_info comp_codec_adapter_info = { \ 55 .drv = &comp_codec_adapter, \ 56 }; \ 57 \ 58 UT_STATIC void sys_comp_codec_##adapter_init(void) \ 59 { \ 60 comp_register(platform_shared_get(&comp_codec_adapter_info, \ 61 sizeof(comp_codec_adapter_info))); \ 62 } \ 63 \ 64 DECLARE_MODULE(sys_comp_codec_##adapter_init) 65 66 /*****************************************************************************/ 67 /* Codec generic data types */ 68 /*****************************************************************************/ 69 /** 70 * \struct codec_interface 71 * \brief Codec specific interfaces 72 */ 73 struct codec_interface { 74 /** 75 * The unique ID for a codec, used for initialization as well as 76 * parameters loading. 77 */ 78 uint32_t id; 79 /** 80 * Codec specific initialization procedure, called as part of 81 * codec_adapter component creation in .new() 82 */ 83 int (*init)(struct comp_dev *dev); 84 /** 85 * Codec specific prepare procedure, called as part of codec_adapter 86 * component preparation in .prepare() 87 */ 88 int (*prepare)(struct comp_dev *dev); 89 /** 90 * Codec specific. Returns the number of PCM output 91 * samples after decoding one input compressed frame. 92 * Codecs will return 0 for don't care. 93 */ 94 int (*get_samples)(struct comp_dev *dev); 95 /** 96 * Codec specific init processing procedure, called as a part of 97 * codec_adapter component copy in .copy(). Typically in this 98 * phase a processing algorithm searches for the valid header, 99 * does header decoding to get the parameters and initializes 100 * state and configuration structures. 101 */ 102 int (*init_process)(struct comp_dev *dev); 103 /** 104 * Codec specific processing procedure, called as part of codec_adapter 105 * component copy in .copy(). This procedure is responsible to consume 106 * samples provided by the codec_adapter and produce/output the processed 107 * ones back to codec_adapter. 108 */ 109 int (*process)(struct comp_dev *dev); 110 /** 111 * Codec specific apply config procedure, called by codec_adapter every time 112 * a new RUNTIME configuration has been sent if the adapter has been 113 * prepared. This will not be called for SETUP cfg. 114 */ 115 int (*apply_config)(struct comp_dev *dev); 116 /** 117 * Codec specific reset procedure, called as part of codec_adapter component 118 * reset in .reset(). This should reset all parameters to their initial stage 119 * but leave allocated memory intact. 120 */ 121 int (*reset)(struct comp_dev *dev); 122 /** 123 * Codec specific free procedure, called as part of codec_adapter component 124 * free in .free(). This should free all memory allocated by codec. 125 */ 126 int (*free)(struct comp_dev *dev); 127 }; 128 129 /** 130 * \enum codec_cfg_type 131 * \brief Specific configuration types which can be either: 132 */ 133 enum codec_cfg_type { 134 CODEC_CFG_SETUP, /**< Used to pass setup parameters */ 135 CODEC_CFG_RUNTIME /**< Used every time runtime parameters has been loaded. */ 136 }; 137 138 /** 139 * \enum codec_state 140 * \brief Codec specific states 141 */ 142 enum codec_state { 143 CODEC_DISABLED, /**< Codec isn't initialized yet or has been freed.*/ 144 CODEC_INITIALIZED, /**< Codec initialized or reset. */ 145 CODEC_IDLE, /**< Codec is idle now. */ 146 CODEC_PROCESSING, /**< Codec is processing samples now. */ 147 }; 148 149 /** codec adapter setup config parameters */ 150 struct ca_config { 151 uint32_t codec_id; 152 uint32_t reserved; 153 uint32_t sample_rate; 154 uint32_t sample_width; 155 uint32_t channels; 156 }; 157 158 /** 159 * \struct codec_config 160 * \brief Codec TLV parameters container - used for both config types. 161 * For example if one want to set the sample_rate to 16 [kHz] and this 162 * parameter was assigned to id 0x01, its max size is four bytes then the 163 * configuration filed should look like this (note little-endian format): 164 * 0x01 0x00 0x00 0x00, 0x0C 0x00 0x00 0x00, 0x10 0x00 0x00 0x00. 165 */ 166 struct codec_param { 167 /** 168 * Specifies the unique id of a parameter. For example the parameter 169 * sample_rate may have an id of 0x01. 170 */ 171 uint32_t id; 172 uint32_t size; /**< The size of whole parameter - id + size + data */ 173 int32_t data[]; /**< A pointer to memory where config is stored.*/ 174 }; 175 176 /** 177 * \struct codec_config 178 * \brief Codec config container, used for both config types. 179 */ 180 struct codec_config { 181 size_t size; /**< Specifies the size of whole config */ 182 bool avail; /**< Marks config as available to use.*/ 183 void *data; /**< tlv config, a pointer to memory where config is stored. */ 184 }; 185 186 /** 187 * \struct codec_memory 188 * \brief codec memory block - used for every memory allocated by codec 189 */ 190 struct codec_memory { 191 void *ptr; /**< A pointr to particular memory block */ 192 struct list_item mem_list; /**< list of memory allocated by codec */ 193 }; 194 195 /** 196 * \struct codec_processing_data 197 * \brief Processing data shared between particular codec & codec_adapter 198 */ 199 struct codec_processing_data { 200 uint32_t in_buff_size; /**< Specifies the size of codec input buffer. */ 201 uint32_t out_buff_size; /**< Specifies the size of codec output buffer.*/ 202 uint32_t avail; /**< Specifies how much data is available for codec to process.*/ 203 uint32_t produced; /**< Specifies how much data the codec produced in its last task.*/ 204 uint32_t consumed; /**< Specified how much data the codec consumed in its last task */ 205 uint32_t init_done; /**< Specifies if the codec initialization is finished */ 206 void *in_buff; /**< A pointer to codec input buffer. */ 207 void *out_buff; /**< A pointer to codec output buffer. */ 208 }; 209 210 /** private, runtime codec data */ 211 struct codec_data { 212 uint32_t id; 213 enum codec_state state; 214 void *private; /**< self object, memory tables etc here */ 215 void *runtime_params; 216 struct codec_config s_cfg; /**< setup config */ 217 struct codec_config r_cfg; /**< runtime config */ 218 struct codec_interface *ops; /**< codec specific operations */ 219 struct codec_memory memory; /**< memory allocated by codec */ 220 struct codec_processing_data cpd; /**< shared data comp <-> codec */ 221 }; 222 223 /* codec_adapter private, runtime data */ 224 struct comp_data { 225 struct ca_config ca_config; 226 struct codec_data codec; /**< codec private data */ 227 struct comp_buffer *ca_sink; 228 struct comp_buffer *ca_source; 229 struct comp_buffer *local_buff; 230 struct sof_ipc_stream_params stream_params; 231 uint32_t period_bytes; /** pipeline period bytes */ 232 uint32_t deep_buff_bytes; /**< copy start threshold */ 233 }; 234 235 /*****************************************************************************/ 236 /* Codec generic interfaces */ 237 /*****************************************************************************/ 238 int codec_load_config(struct comp_dev *dev, void *cfg, size_t size, 239 enum codec_cfg_type type); 240 int codec_init(struct comp_dev *dev, struct codec_interface *interface); 241 void *codec_allocate_memory(struct comp_dev *dev, uint32_t size, 242 uint32_t alignment); 243 int codec_free_memory(struct comp_dev *dev, void *ptr); 244 void codec_free_all_memory(struct comp_dev *dev); 245 int codec_prepare(struct comp_dev *dev); 246 int codec_get_samples(struct comp_dev *dev); 247 int codec_init_process(struct comp_dev *dev); 248 int codec_process(struct comp_dev *dev); 249 int codec_apply_runtime_config(struct comp_dev *dev); 250 int codec_reset(struct comp_dev *dev); 251 int codec_free(struct comp_dev *dev); 252 253 struct comp_dev *codec_adapter_new(const struct comp_driver *drv, 254 struct comp_ipc_config *config, 255 struct codec_interface *interface, 256 void *spec); 257 int codec_adapter_prepare(struct comp_dev *dev); 258 int codec_adapter_params(struct comp_dev *dev, struct sof_ipc_stream_params *params); 259 int codec_adapter_copy(struct comp_dev *dev); 260 int codec_adapter_cmd(struct comp_dev *dev, int cmd, void *data, int max_data_size); 261 int codec_adapter_trigger(struct comp_dev *dev, int cmd); 262 void codec_adapter_free(struct comp_dev *dev); 263 int codec_adapter_reset(struct comp_dev *dev); 264 265 #endif /* __SOF_AUDIO_CODEC_GENERIC__ */ 266