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 */ 147 struct snd_compr_ops { 148 int (*open)(struct snd_compr_stream *stream); 149 int (*free)(struct snd_compr_stream *stream); 150 int (*set_params)(struct snd_compr_stream *stream, 151 struct snd_compr_params *params); 152 int (*get_params)(struct snd_compr_stream *stream, 153 struct snd_codec *params); 154 int (*set_metadata)(struct snd_compr_stream *stream, 155 struct snd_compr_metadata *metadata); 156 int (*get_metadata)(struct snd_compr_stream *stream, 157 struct snd_compr_metadata *metadata); 158 int (*trigger)(struct snd_compr_stream *stream, int cmd); 159 int (*pointer)(struct snd_compr_stream *stream, 160 struct snd_compr_tstamp *tstamp); 161 int (*copy)(struct snd_compr_stream *stream, char __user *buf, 162 size_t count); 163 int (*mmap)(struct snd_compr_stream *stream, 164 struct vm_area_struct *vma); 165 int (*ack)(struct snd_compr_stream *stream, size_t bytes); 166 int (*get_caps) (struct snd_compr_stream *stream, 167 struct snd_compr_caps *caps); 168 int (*get_codec_caps) (struct snd_compr_stream *stream, 169 struct snd_compr_codec_caps *codec); 170 #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL) 171 int (*task_create) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task); 172 int (*task_start) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task); 173 int (*task_stop) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task); 174 int (*task_free) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task); 175 #endif 176 }; 177 178 /** 179 * struct snd_compr: Compressed device 180 * @name: DSP device name 181 * @dev: associated device instance 182 * @ops: pointer to DSP callbacks 183 * @private_data: pointer to DSP pvt data 184 * @card: sound card pointer 185 * @direction: Playback or capture direction 186 * @lock: device lock 187 * @device: device id 188 * @use_pause_in_draining: allow pause in draining, true when set 189 */ 190 struct snd_compr { 191 const char *name; 192 struct device *dev; 193 struct snd_compr_ops *ops; 194 void *private_data; 195 struct snd_card *card; 196 unsigned int direction; 197 struct mutex lock; 198 int device; 199 bool use_pause_in_draining; 200 #ifdef CONFIG_SND_VERBOSE_PROCFS 201 /* private: */ 202 char id[64]; 203 struct snd_info_entry *proc_root; 204 struct snd_info_entry *proc_info_entry; 205 #endif 206 }; 207 208 /* compress device register APIs */ 209 int snd_compress_new(struct snd_card *card, int device, 210 int type, const char *id, struct snd_compr *compr); 211 212 /** 213 * snd_compr_use_pause_in_draining - Allow pause and resume in draining state 214 * @substream: compress substream to set 215 * 216 * Allow pause and resume in draining state. 217 * Only HW driver supports this transition can call this API. 218 */ 219 static inline void snd_compr_use_pause_in_draining(struct snd_compr_stream *substream) 220 { 221 substream->device->use_pause_in_draining = true; 222 } 223 224 /* dsp driver callback apis 225 * For playback: driver should call snd_compress_fragment_elapsed() to let the 226 * framework know that a fragment has been consumed from the ring buffer 227 * 228 * For recording: we want to know when a frame is available or when 229 * at least one frame is available so snd_compress_frame_elapsed() 230 * callback should be called when a encodeded frame is available 231 */ 232 static inline void snd_compr_fragment_elapsed(struct snd_compr_stream *stream) 233 { 234 wake_up(&stream->runtime->sleep); 235 } 236 237 static inline void snd_compr_drain_notify(struct snd_compr_stream *stream) 238 { 239 if (snd_BUG_ON(!stream)) 240 return; 241 242 /* for partial_drain case we are back to running state on success */ 243 if (stream->partial_drain) { 244 stream->runtime->state = SNDRV_PCM_STATE_RUNNING; 245 stream->partial_drain = false; /* clear this flag as well */ 246 } else { 247 stream->runtime->state = SNDRV_PCM_STATE_SETUP; 248 } 249 250 wake_up(&stream->runtime->sleep); 251 } 252 253 /** 254 * snd_compr_set_runtime_buffer - Set the Compress runtime buffer 255 * @stream: compress stream to set 256 * @bufp: the buffer information, NULL to clear 257 * 258 * Copy the buffer information to runtime buffer when @bufp is non-NULL. 259 * Otherwise it clears the current buffer information. 260 */ 261 static inline void 262 snd_compr_set_runtime_buffer(struct snd_compr_stream *stream, 263 struct snd_dma_buffer *bufp) 264 { 265 struct snd_compr_runtime *runtime = stream->runtime; 266 267 if (bufp) { 268 runtime->dma_buffer_p = bufp; 269 runtime->dma_area = bufp->area; 270 runtime->dma_addr = bufp->addr; 271 runtime->dma_bytes = bufp->bytes; 272 } else { 273 runtime->dma_buffer_p = NULL; 274 runtime->dma_area = NULL; 275 runtime->dma_addr = 0; 276 runtime->dma_bytes = 0; 277 } 278 } 279 280 int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size); 281 int snd_compr_free_pages(struct snd_compr_stream *stream); 282 283 int snd_compr_stop_error(struct snd_compr_stream *stream, 284 snd_pcm_state_t state); 285 286 #if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL) 287 void snd_compr_task_finished(struct snd_compr_stream *stream, 288 struct snd_compr_task_runtime *task); 289 #endif 290 291 #endif 292