/* SPDX-License-Identifier: GPL-2.01*2* compress_driver.h - compress offload driver definations3*4* Copyright (C) 2011 Intel Corporation5* Authors: Vinod Koul <[email protected]>6* Pierre-Louis Bossart <[email protected]>7*/89#ifndef __COMPRESS_DRIVER_H10#define __COMPRESS_DRIVER_H1112#include <linux/types.h>13#include <linux/sched.h>14#include <sound/core.h>15#include <sound/compress_offload.h>16#include <sound/asound.h>17#include <sound/pcm.h>1819struct snd_compr_ops;2021/**22* struct snd_compr_task_runtime: task runtime description23* @list: list of all managed tasks24* @input: input DMA buffer25* @output: output DMA buffer26* @seqno: sequence number27* @input_size: really used data in the input buffer28* @output_size: really used data in the output buffer29* @flags: see SND_COMPRESS_TFLG_*30* @state: actual task state31* @private_value: used by the lowlevel driver (opaque)32*/33struct snd_compr_task_runtime {34struct list_head list;35struct dma_buf *input;36struct dma_buf *output;37u64 seqno;38u64 input_size;39u64 output_size;40u32 flags;41u8 state;42void *private_value;43};4445/**46* struct snd_compr_runtime: runtime stream description47* @state: stream state48* @ops: pointer to DSP callbacks49* @buffer: pointer to kernel buffer, valid only when not in mmap mode or50* DSP doesn't implement copy51* @buffer_size: size of the above buffer52* @fragment_size: size of buffer fragment in bytes53* @fragments: number of such fragments54* @total_bytes_available: cumulative number of bytes made available in55* the ring buffer56* @total_bytes_transferred: cumulative bytes transferred by offload DSP57* @sleep: poll sleep58* @private_data: driver private data pointer59* @dma_area: virtual buffer address60* @dma_addr: physical buffer address (not accessible from main CPU)61* @dma_bytes: size of DMA area62* @dma_buffer_p: runtime dma buffer pointer63* @active_tasks: count of active tasks64* @total_tasks: count of all tasks65* @task_seqno: last task sequence number (!= 0)66* @tasks: list of all tasks67*/68struct snd_compr_runtime {69snd_pcm_state_t state;70struct snd_compr_ops *ops;71void *buffer;72u64 buffer_size;73u32 fragment_size;74u32 fragments;75u64 total_bytes_available;76u64 total_bytes_transferred;77wait_queue_head_t sleep;78void *private_data;7980unsigned char *dma_area;81dma_addr_t dma_addr;82size_t dma_bytes;83struct snd_dma_buffer *dma_buffer_p;8485#if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL)86u32 active_tasks;87u32 total_tasks;88u64 task_seqno;89struct list_head tasks;90#endif91};9293/**94* struct snd_compr_stream: compressed stream95* @name: device name96* @ops: pointer to DSP callbacks97* @runtime: pointer to runtime structure98* @device: device pointer99* @error_work: delayed work used when closing the stream due to an error100* @direction: stream direction, playback/recording101* @metadata_set: metadata set flag, true when set102* @next_track: has userspace signal next track transition, true when set103* @partial_drain: undergoing partial_drain for stream, true when set104* @pause_in_draining: paused during draining state, true when set105* @private_data: pointer to DSP private data106* @dma_buffer: allocated buffer if any107*/108struct snd_compr_stream {109const char *name;110struct snd_compr_ops *ops;111struct snd_compr_runtime *runtime;112struct snd_compr *device;113struct delayed_work error_work;114enum snd_compr_direction direction;115bool metadata_set;116bool next_track;117bool partial_drain;118bool pause_in_draining;119void *private_data;120struct snd_dma_buffer dma_buffer;121};122123/**124* struct snd_compr_ops: compressed path DSP operations125* @open: Open the compressed stream126* This callback is mandatory and shall keep dsp ready to receive the stream127* parameter128* @free: Close the compressed stream, mandatory129* @set_params: Sets the compressed stream parameters, mandatory130* This can be called in during stream creation only to set codec params131* and the stream properties132* @get_params: retrieve the codec parameters, mandatory133* @set_metadata: Set the metadata values for a stream134* @get_metadata: retrieves the requested metadata values from stream135* @trigger: Trigger operations like start, pause, resume, drain, stop.136* This callback is mandatory137* @pointer: Retrieve current h/w pointer information. Mandatory138* @copy: Copy the compressed data to/from userspace, Optional139* Can't be implemented if DSP supports mmap140* @mmap: DSP mmap method to mmap DSP memory141* @ack: Ack for DSP when data is written to audio buffer, Optional142* Not valid if copy is implemented143* @get_caps: Retrieve DSP capabilities, mandatory144* @get_codec_caps: Retrieve capabilities for a specific codec, mandatory145* @task_create: Create a set of input/output buffers for accel operations146* @task_start: Start (queue) a task for accel operations147* @task_stop: Stop (dequeue) a task for accel operations148* @task_free: Free a set of input/output buffers for accel operations149*/150struct snd_compr_ops {151int (*open)(struct snd_compr_stream *stream);152int (*free)(struct snd_compr_stream *stream);153int (*set_params)(struct snd_compr_stream *stream,154struct snd_compr_params *params);155int (*get_params)(struct snd_compr_stream *stream,156struct snd_codec *params);157int (*set_metadata)(struct snd_compr_stream *stream,158struct snd_compr_metadata *metadata);159int (*get_metadata)(struct snd_compr_stream *stream,160struct snd_compr_metadata *metadata);161int (*trigger)(struct snd_compr_stream *stream, int cmd);162int (*pointer)(struct snd_compr_stream *stream,163struct snd_compr_tstamp *tstamp);164int (*copy)(struct snd_compr_stream *stream, char __user *buf,165size_t count);166int (*mmap)(struct snd_compr_stream *stream,167struct vm_area_struct *vma);168int (*ack)(struct snd_compr_stream *stream, size_t bytes);169int (*get_caps) (struct snd_compr_stream *stream,170struct snd_compr_caps *caps);171int (*get_codec_caps) (struct snd_compr_stream *stream,172struct snd_compr_codec_caps *codec);173#if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL)174int (*task_create) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task);175int (*task_start) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task);176int (*task_stop) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task);177int (*task_free) (struct snd_compr_stream *stream, struct snd_compr_task_runtime *task);178#endif179};180181/**182* struct snd_compr: Compressed device183* @name: DSP device name184* @dev: associated device instance185* @ops: pointer to DSP callbacks186* @private_data: pointer to DSP pvt data187* @card: sound card pointer188* @direction: Playback or capture direction189* @lock: device lock190* @device: device id191* @use_pause_in_draining: allow pause in draining, true when set192*/193struct snd_compr {194const char *name;195struct device *dev;196struct snd_compr_ops *ops;197void *private_data;198struct snd_card *card;199unsigned int direction;200struct mutex lock;201int device;202bool use_pause_in_draining;203#ifdef CONFIG_SND_VERBOSE_PROCFS204/* private: */205char id[64];206struct snd_info_entry *proc_root;207struct snd_info_entry *proc_info_entry;208#endif209};210211/* compress device register APIs */212int snd_compress_new(struct snd_card *card, int device,213int type, const char *id, struct snd_compr *compr);214215/**216* snd_compr_use_pause_in_draining - Allow pause and resume in draining state217* @substream: compress substream to set218*219* Allow pause and resume in draining state.220* Only HW driver supports this transition can call this API.221*/222static inline void snd_compr_use_pause_in_draining(struct snd_compr_stream *substream)223{224substream->device->use_pause_in_draining = true;225}226227/* dsp driver callback apis228* For playback: driver should call snd_compress_fragment_elapsed() to let the229* framework know that a fragment has been consumed from the ring buffer230*231* For recording: we want to know when a frame is available or when232* at least one frame is available so snd_compress_frame_elapsed()233* callback should be called when a encodeded frame is available234*/235static inline void snd_compr_fragment_elapsed(struct snd_compr_stream *stream)236{237wake_up(&stream->runtime->sleep);238}239240static inline void snd_compr_drain_notify(struct snd_compr_stream *stream)241{242if (snd_BUG_ON(!stream))243return;244245/* for partial_drain case we are back to running state on success */246if (stream->partial_drain) {247stream->runtime->state = SNDRV_PCM_STATE_RUNNING;248stream->partial_drain = false; /* clear this flag as well */249} else {250stream->runtime->state = SNDRV_PCM_STATE_SETUP;251}252253wake_up(&stream->runtime->sleep);254}255256/**257* snd_compr_set_runtime_buffer - Set the Compress runtime buffer258* @stream: compress stream to set259* @bufp: the buffer information, NULL to clear260*261* Copy the buffer information to runtime buffer when @bufp is non-NULL.262* Otherwise it clears the current buffer information.263*/264static inline void265snd_compr_set_runtime_buffer(struct snd_compr_stream *stream,266struct snd_dma_buffer *bufp)267{268struct snd_compr_runtime *runtime = stream->runtime;269270if (bufp) {271runtime->dma_buffer_p = bufp;272runtime->dma_area = bufp->area;273runtime->dma_addr = bufp->addr;274runtime->dma_bytes = bufp->bytes;275} else {276runtime->dma_buffer_p = NULL;277runtime->dma_area = NULL;278runtime->dma_addr = 0;279runtime->dma_bytes = 0;280}281}282283int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size);284int snd_compr_free_pages(struct snd_compr_stream *stream);285286int snd_compr_stop_error(struct snd_compr_stream *stream,287snd_pcm_state_t state);288289#if IS_ENABLED(CONFIG_SND_COMPRESS_ACCEL)290void snd_compr_task_finished(struct snd_compr_stream *stream,291struct snd_compr_task_runtime *task);292#endif293294#endif295296297