1 /* SPDX-License-Identifier: GPL-2.0 2 * 3 * compress_driver.h - compress offload driver definations 4 * 5 * Copyright (C) 2011 Intel Corporation 6 * Authors: Vinod Koul <vinod.koul@linux.intel.com> 7 * Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> 8 */ 9 10 #ifndef __COMPRESS_DRIVER_H 11 #define __COMPRESS_DRIVER_H 12 13 #include <linux/types.h> 14 #include <linux/sched.h> 15 #include <sound/core.h> 16 #include <sound/compress_offload.h> 17 #include <sound/asound.h> 18 #include <sound/pcm.h> 19 20 struct snd_compr_ops; 21 22 /** 23 * struct snd_compr_task_runtime: task runtime description 24 * @list: list of all managed tasks 25 * @input: input DMA buffer 26 * @output: output DMA buffer 27 * @seqno: sequence number 28 * @input_size: really used data in the input buffer 29 * @output_size: really used data in the output buffer 30 * @flags: see SND_COMPRESS_TFLG_* 31 * @state: actual task state 32 * @private_value: used by the lowlevel driver (opaque) 33 */ 34 struct snd_compr_task_runtime { 35 struct list_head list; 36 struct dma_buf *input; 37 struct dma_buf *output; 38 u64 seqno; 39 u64 input_size; 40 u64 output_size; 41 u32 flags; 42 u8 state; 43 void *private_value; 44 }; 45 46 /** 47 * struct snd_compr_runtime: runtime stream description 48 * @state: stream state 49 * @ops: pointer to DSP callbacks 50 * @buffer: pointer to kernel buffer, valid only when not in mmap mode or 51 * DSP doesn't implement copy 52 * @buffer_size: size of the above buffer 53 * @fragment_size: size of buffer fragment in bytes 54 * @fragments: number of such fragments 55 * @total_bytes_available: cumulative number of bytes made available in 56 * the ring buffer 57 * @total_bytes_transferred: cumulative bytes transferred by offload DSP 58 * @sleep: poll sleep 59 * @private_data: driver private data pointer 60 * @dma_area: virtual buffer address 61 * @dma_addr: physical buffer address (not accessible from main CPU) 62 * @dma_bytes: size of DMA area 63 * @dma_buffer_p: runtime dma buffer pointer 64 * @active_tasks: count of active tasks 65 * @total_tasks: count of all tasks 66 * @task_seqno: last task sequence number (!= 0) 67 * @tasks: list of all tasks 68 */ 69 struct snd_compr_runtime { 70 snd_pcm_state_t state; 71 struct snd_compr_ops *ops; 72 void *buffer; 73 u64 buffer_size; 74 u32 fragment_size; 75 u32 fragments; 76 u64 total_bytes_available; 77 u64 total_bytes_transferred; 78 wait_queue_head_t sleep; 79 void *private_data; 80 81 unsigned char *dma_area; 82 dma_addr_t dma_addr; 83 size_t dma_bytes; 84 struct snd_dma_buffer *dma_buffer_p; 85 86 #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL) 87 u32 active_tasks; 88 u32 total_tasks; 89 u64 task_seqno; 90 struct list_head tasks; 91 #endif 92 }; 93 94 /** 95 * struct snd_compr_stream: compressed stream 96 * @name: device name 97 * @ops: pointer to DSP callbacks 98 * @runtime: pointer to runtime structure 99 * @device: device pointer 100 * @error_work: delayed work used when closing the stream due to an error 101 * @direction: stream direction, playback/recording 102 * @metadata_set: metadata set flag, true when set 103 * @next_track: has userspace signal next track transition, true when set 104 * @partial_drain: undergoing partial_drain for stream, true when set 105 * @pause_in_draining: paused during draining state, true when set 106 * @private_data: pointer to DSP private data 107 * @dma_buffer: allocated buffer if any 108 */ 109 struct snd_compr_stream { 110 const char *name; 111 struct snd_compr_ops *ops; 112 struct snd_compr_runtime *runtime; 113 struct snd_compr *device; 114 struct delayed_work error_work; 115 enum snd_compr_direction direction; 116 bool metadata_set; 117 bool next_track; 118 bool partial_drain; 119 bool pause_in_draining; 120 void *private_data; 121 struct snd_dma_buffer dma_buffer; 122 }; 123 124 /** 125 * struct snd_compr_ops: compressed path DSP operations 126 * @open: Open the compressed stream 127 * This callback is mandatory and shall keep dsp ready to receive the stream 128 * parameter 129 * @free: Close the compressed stream, mandatory 130 * @set_params: Sets the compressed stream parameters, mandatory 131 * This can be called in during stream creation only to set codec params 132 * and the stream properties 133 * @get_params: retrieve the codec parameters, mandatory 134 * @set_metadata: Set the metadata values for a stream 135 * @get_metadata: retrieves the requested metadata values from stream 136 * @trigger: Trigger operations like start, pause, resume, drain, stop. 137 * This callback is mandatory 138 * @pointer: Retrieve current h/w pointer information. Mandatory 139 * @copy: Copy the compressed data to/from userspace, Optional 140 * Can't be implemented if DSP supports mmap 141 * @mmap: DSP mmap method to mmap DSP memory 142 * @ack: Ack for DSP when data is written to audio buffer, Optional 143 * Not valid if copy is implemented 144 * @get_caps: Retrieve DSP capabilities, mandatory 145 * @get_codec_caps: Retrieve capabilities for a specific codec, mandatory 146 * @task_create: Create a set of input/output buffers for accel operations 147 * @task_start: Start (queue) a task for accel operations 148 * @task_stop: Stop (dequeue) a task for accel operations 149 * @task_free: Free a set of input/output buffers for accel operations 150 */ 151 struct snd_compr_ops { 152 int (*open)(struct snd_compr_stream *stream); 153 int (*free)(struct snd_compr_stream *stream); 154 int (*set_params)(struct snd_compr_stream *stream, 155 struct snd_compr_params *params); 156 int (*get_params)(struct snd_compr_stream *stream, 157 struct snd_codec *params); 158 int (*set_metadata)(struct snd_compr_stream *stream, 159 struct snd_compr_metadata *metadata); 160 int (*get_metadata)(struct snd_compr_stream *stream, 161 struct snd_compr_metadata *metadata); 162 int (*trigger)(struct snd_compr_stream *stream, int cmd); 163 int (*pointer)(struct snd_compr_stream *stream, 164 struct snd_compr_tstamp *tstamp); 165 int (*copy)(struct snd_compr_stream *stream, char __user *buf, 166 size_t count); 167 int (*mmap)(struct snd_compr_stream *stream, 168 struct vm_area_struct *vma); 169 int (*ack)(struct snd_compr_stream *stream, size_t bytes); 170 int (*get_caps) (struct snd_compr_stream *stream, 171 struct snd_compr_caps *caps); 172 int (*get_codec_caps) (struct snd_compr_stream *stream, 173 struct snd_compr_codec_caps *codec); 174 #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL) 175 int (*task_create) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task); 176 int (*task_start) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task); 177 int (*task_stop) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task); 178 int (*task_free) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task); 179 #endif 180 }; 181 182 /** 183 * struct snd_compr: Compressed device 184 * @name: DSP device name 185 * @dev: associated device instance 186 * @ops: pointer to DSP callbacks 187 * @private_data: pointer to DSP pvt data 188 * @card: sound card pointer 189 * @direction: Playback or capture direction 190 * @lock: device lock 191 * @device: device id 192 * @use_pause_in_draining: allow pause in draining, true when set 193 */ 194 struct snd_compr { 195 const char *name; 196 struct device *dev; 197 struct snd_compr_ops *ops; 198 void *private_data; 199 struct snd_card *card; 200 unsigned int direction; 201 struct mutex lock; 202 int device; 203 bool use_pause_in_draining; 204 #ifdef CONFIG_SND_VERBOSE_PROCFS 205 /* private: */ 206 char id[64]; 207 struct snd_info_entry *proc_root; 208 struct snd_info_entry *proc_info_entry; 209 #endif 210 }; 211 212 /* compress device register APIs */ 213 int snd_compress_new(struct snd_card *card, int device, 214 int type, const char *id, struct snd_compr *compr); 215 216 /** 217 * snd_compr_use_pause_in_draining - Allow pause and resume in draining state 218 * @substream: compress substream to set 219 * 220 * Allow pause and resume in draining state. 221 * Only HW driver supports this transition can call this API. 222 */ 223 static inline void snd_compr_use_pause_in_draining(struct snd_compr_stream *substream) 224 { 225 substream->device->use_pause_in_draining = true; 226 } 227 228 /* dsp driver callback apis 229 * For playback: driver should call snd_compress_fragment_elapsed() to let the 230 * framework know that a fragment has been consumed from the ring buffer 231 * 232 * For recording: we want to know when a frame is available or when 233 * at least one frame is available so snd_compress_frame_elapsed() 234 * callback should be called when a encodeded frame is available 235 */ 236 static inline void snd_compr_fragment_elapsed(struct snd_compr_stream *stream) 237 { 238 wake_up(&stream->runtime->sleep); 239 } 240 241 static inline void snd_compr_drain_notify(struct snd_compr_stream *stream) 242 { 243 if (snd_BUG_ON(!stream)) 244 return; 245 246 /* for partial_drain case we are back to running state on success */ 247 if (stream->partial_drain) { 248 stream->runtime->state = SNDRV_PCM_STATE_RUNNING; 249 stream->partial_drain = false; /* clear this flag as well */ 250 } else { 251 stream->runtime->state = SNDRV_PCM_STATE_SETUP; 252 } 253 254 wake_up(&stream->runtime->sleep); 255 } 256 257 /** 258 * snd_compr_set_runtime_buffer - Set the Compress runtime buffer 259 * @stream: compress stream to set 260 * @bufp: the buffer information, NULL to clear 261 * 262 * Copy the buffer information to runtime buffer when @bufp is non-NULL. 263 * Otherwise it clears the current buffer information. 264 */ 265 static inline void 266 snd_compr_set_runtime_buffer(struct snd_compr_stream *stream, 267 struct snd_dma_buffer *bufp) 268 { 269 struct snd_compr_runtime *runtime = stream->runtime; 270 271 if (bufp) { 272 runtime->dma_buffer_p = bufp; 273 runtime->dma_area = bufp->area; 274 runtime->dma_addr = bufp->addr; 275 runtime->dma_bytes = bufp->bytes; 276 } else { 277 runtime->dma_buffer_p = NULL; 278 runtime->dma_area = NULL; 279 runtime->dma_addr = 0; 280 runtime->dma_bytes = 0; 281 } 282 } 283 284 int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size); 285 int snd_compr_free_pages(struct snd_compr_stream *stream); 286 287 int snd_compr_stop_error(struct snd_compr_stream *stream, 288 snd_pcm_state_t state); 289 290 #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL) 291 void snd_compr_task_finished(struct snd_compr_stream *stream, 292 struct snd_compr_task_runtime *task); 293 #endif 294 295 #endif 296