Back to home page

OSCL-LXR

 
 

    


0001 /* SPDX-License-Identifier: GPL-2.0
0002  *
0003  *  compress_driver.h - compress offload driver definations
0004  *
0005  *  Copyright (C) 2011 Intel Corporation
0006  *  Authors:    Vinod Koul <vinod.koul@linux.intel.com>
0007  *      Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
0008  */
0009 
0010 #ifndef __COMPRESS_DRIVER_H
0011 #define __COMPRESS_DRIVER_H
0012 
0013 #include <linux/types.h>
0014 #include <linux/sched.h>
0015 #include <sound/core.h>
0016 #include <sound/compress_offload.h>
0017 #include <sound/asound.h>
0018 #include <sound/pcm.h>
0019 
0020 struct snd_compr_ops;
0021 
0022 /**
0023  * struct snd_compr_runtime: runtime stream description
0024  * @state: stream state
0025  * @ops: pointer to DSP callbacks
0026  * @buffer: pointer to kernel buffer, valid only when not in mmap mode or
0027  *  DSP doesn't implement copy
0028  * @buffer_size: size of the above buffer
0029  * @fragment_size: size of buffer fragment in bytes
0030  * @fragments: number of such fragments
0031  * @total_bytes_available: cumulative number of bytes made available in
0032  *  the ring buffer
0033  * @total_bytes_transferred: cumulative bytes transferred by offload DSP
0034  * @sleep: poll sleep
0035  * @private_data: driver private data pointer
0036  * @dma_area: virtual buffer address
0037  * @dma_addr: physical buffer address (not accessible from main CPU)
0038  * @dma_bytes: size of DMA area
0039  * @dma_buffer_p: runtime dma buffer pointer
0040  */
0041 struct snd_compr_runtime {
0042     snd_pcm_state_t state;
0043     struct snd_compr_ops *ops;
0044     void *buffer;
0045     u64 buffer_size;
0046     u32 fragment_size;
0047     u32 fragments;
0048     u64 total_bytes_available;
0049     u64 total_bytes_transferred;
0050     wait_queue_head_t sleep;
0051     void *private_data;
0052 
0053     unsigned char *dma_area;
0054     dma_addr_t dma_addr;
0055     size_t dma_bytes;
0056     struct snd_dma_buffer *dma_buffer_p;
0057 };
0058 
0059 /**
0060  * struct snd_compr_stream: compressed stream
0061  * @name: device name
0062  * @ops: pointer to DSP callbacks
0063  * @runtime: pointer to runtime structure
0064  * @device: device pointer
0065  * @error_work: delayed work used when closing the stream due to an error
0066  * @direction: stream direction, playback/recording
0067  * @metadata_set: metadata set flag, true when set
0068  * @next_track: has userspace signal next track transition, true when set
0069  * @partial_drain: undergoing partial_drain for stream, true when set
0070  * @pause_in_draining: paused during draining state, true when set
0071  * @private_data: pointer to DSP private data
0072  * @dma_buffer: allocated buffer if any
0073  */
0074 struct snd_compr_stream {
0075     const char *name;
0076     struct snd_compr_ops *ops;
0077     struct snd_compr_runtime *runtime;
0078     struct snd_compr *device;
0079     struct delayed_work error_work;
0080     enum snd_compr_direction direction;
0081     bool metadata_set;
0082     bool next_track;
0083     bool partial_drain;
0084     bool pause_in_draining;
0085     void *private_data;
0086     struct snd_dma_buffer dma_buffer;
0087 };
0088 
0089 /**
0090  * struct snd_compr_ops: compressed path DSP operations
0091  * @open: Open the compressed stream
0092  * This callback is mandatory and shall keep dsp ready to receive the stream
0093  * parameter
0094  * @free: Close the compressed stream, mandatory
0095  * @set_params: Sets the compressed stream parameters, mandatory
0096  * This can be called in during stream creation only to set codec params
0097  * and the stream properties
0098  * @get_params: retrieve the codec parameters, mandatory
0099  * @set_metadata: Set the metadata values for a stream
0100  * @get_metadata: retrieves the requested metadata values from stream
0101  * @trigger: Trigger operations like start, pause, resume, drain, stop.
0102  * This callback is mandatory
0103  * @pointer: Retrieve current h/w pointer information. Mandatory
0104  * @copy: Copy the compressed data to/from userspace, Optional
0105  * Can't be implemented if DSP supports mmap
0106  * @mmap: DSP mmap method to mmap DSP memory
0107  * @ack: Ack for DSP when data is written to audio buffer, Optional
0108  * Not valid if copy is implemented
0109  * @get_caps: Retrieve DSP capabilities, mandatory
0110  * @get_codec_caps: Retrieve capabilities for a specific codec, mandatory
0111  */
0112 struct snd_compr_ops {
0113     int (*open)(struct snd_compr_stream *stream);
0114     int (*free)(struct snd_compr_stream *stream);
0115     int (*set_params)(struct snd_compr_stream *stream,
0116             struct snd_compr_params *params);
0117     int (*get_params)(struct snd_compr_stream *stream,
0118             struct snd_codec *params);
0119     int (*set_metadata)(struct snd_compr_stream *stream,
0120             struct snd_compr_metadata *metadata);
0121     int (*get_metadata)(struct snd_compr_stream *stream,
0122             struct snd_compr_metadata *metadata);
0123     int (*trigger)(struct snd_compr_stream *stream, int cmd);
0124     int (*pointer)(struct snd_compr_stream *stream,
0125             struct snd_compr_tstamp *tstamp);
0126     int (*copy)(struct snd_compr_stream *stream, char __user *buf,
0127                size_t count);
0128     int (*mmap)(struct snd_compr_stream *stream,
0129             struct vm_area_struct *vma);
0130     int (*ack)(struct snd_compr_stream *stream, size_t bytes);
0131     int (*get_caps) (struct snd_compr_stream *stream,
0132             struct snd_compr_caps *caps);
0133     int (*get_codec_caps) (struct snd_compr_stream *stream,
0134             struct snd_compr_codec_caps *codec);
0135 };
0136 
0137 /**
0138  * struct snd_compr: Compressed device
0139  * @name: DSP device name
0140  * @dev: associated device instance
0141  * @ops: pointer to DSP callbacks
0142  * @private_data: pointer to DSP pvt data
0143  * @card: sound card pointer
0144  * @direction: Playback or capture direction
0145  * @lock: device lock
0146  * @device: device id
0147  * @use_pause_in_draining: allow pause in draining, true when set
0148  */
0149 struct snd_compr {
0150     const char *name;
0151     struct device dev;
0152     struct snd_compr_ops *ops;
0153     void *private_data;
0154     struct snd_card *card;
0155     unsigned int direction;
0156     struct mutex lock;
0157     int device;
0158     bool use_pause_in_draining;
0159 #ifdef CONFIG_SND_VERBOSE_PROCFS
0160     /* private: */
0161     char id[64];
0162     struct snd_info_entry *proc_root;
0163     struct snd_info_entry *proc_info_entry;
0164 #endif
0165 };
0166 
0167 /* compress device register APIs */
0168 int snd_compress_new(struct snd_card *card, int device,
0169             int type, const char *id, struct snd_compr *compr);
0170 
0171 /**
0172  * snd_compr_use_pause_in_draining - Allow pause and resume in draining state
0173  * @substream: compress substream to set
0174  *
0175  * Allow pause and resume in draining state.
0176  * Only HW driver supports this transition can call this API.
0177  */
0178 static inline void snd_compr_use_pause_in_draining(struct snd_compr_stream *substream)
0179 {
0180     substream->device->use_pause_in_draining = true;
0181 }
0182 
0183 /* dsp driver callback apis
0184  * For playback: driver should call snd_compress_fragment_elapsed() to let the
0185  * framework know that a fragment has been consumed from the ring buffer
0186  *
0187  * For recording: we want to know when a frame is available or when
0188  * at least one frame is available so snd_compress_frame_elapsed()
0189  * callback should be called when a encodeded frame is available
0190  */
0191 static inline void snd_compr_fragment_elapsed(struct snd_compr_stream *stream)
0192 {
0193     wake_up(&stream->runtime->sleep);
0194 }
0195 
0196 static inline void snd_compr_drain_notify(struct snd_compr_stream *stream)
0197 {
0198     if (snd_BUG_ON(!stream))
0199         return;
0200 
0201     /* for partial_drain case we are back to running state on success */
0202     if (stream->partial_drain) {
0203         stream->runtime->state = SNDRV_PCM_STATE_RUNNING;
0204         stream->partial_drain = false; /* clear this flag as well */
0205     } else {
0206         stream->runtime->state = SNDRV_PCM_STATE_SETUP;
0207     }
0208 
0209     wake_up(&stream->runtime->sleep);
0210 }
0211 
0212 /**
0213  * snd_compr_set_runtime_buffer - Set the Compress runtime buffer
0214  * @stream: compress stream to set
0215  * @bufp: the buffer information, NULL to clear
0216  *
0217  * Copy the buffer information to runtime buffer when @bufp is non-NULL.
0218  * Otherwise it clears the current buffer information.
0219  */
0220 static inline void
0221 snd_compr_set_runtime_buffer(struct snd_compr_stream *stream,
0222                  struct snd_dma_buffer *bufp)
0223 {
0224     struct snd_compr_runtime *runtime = stream->runtime;
0225 
0226     if (bufp) {
0227         runtime->dma_buffer_p = bufp;
0228         runtime->dma_area = bufp->area;
0229         runtime->dma_addr = bufp->addr;
0230         runtime->dma_bytes = bufp->bytes;
0231     } else {
0232         runtime->dma_buffer_p = NULL;
0233         runtime->dma_area = NULL;
0234         runtime->dma_addr = 0;
0235         runtime->dma_bytes = 0;
0236     }
0237 }
0238 
0239 int snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size);
0240 int snd_compr_free_pages(struct snd_compr_stream *stream);
0241 
0242 int snd_compr_stop_error(struct snd_compr_stream *stream,
0243              snd_pcm_state_t state);
0244 
0245 #endif