18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci * 38c2ecf20Sopenharmony_ci * compress_driver.h - compress offload driver definations 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 2011 Intel Corporation 68c2ecf20Sopenharmony_ci * Authors: Vinod Koul <vinod.koul@linux.intel.com> 78c2ecf20Sopenharmony_ci * Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef __COMPRESS_DRIVER_H 118c2ecf20Sopenharmony_ci#define __COMPRESS_DRIVER_H 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/types.h> 148c2ecf20Sopenharmony_ci#include <linux/sched.h> 158c2ecf20Sopenharmony_ci#include <sound/core.h> 168c2ecf20Sopenharmony_ci#include <sound/compress_offload.h> 178c2ecf20Sopenharmony_ci#include <sound/asound.h> 188c2ecf20Sopenharmony_ci#include <sound/pcm.h> 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_cistruct snd_compr_ops; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci/** 238c2ecf20Sopenharmony_ci * struct snd_compr_runtime: runtime stream description 248c2ecf20Sopenharmony_ci * @state: stream state 258c2ecf20Sopenharmony_ci * @ops: pointer to DSP callbacks 268c2ecf20Sopenharmony_ci * @buffer: pointer to kernel buffer, valid only when not in mmap mode or 278c2ecf20Sopenharmony_ci * DSP doesn't implement copy 288c2ecf20Sopenharmony_ci * @buffer_size: size of the above buffer 298c2ecf20Sopenharmony_ci * @fragment_size: size of buffer fragment in bytes 308c2ecf20Sopenharmony_ci * @fragments: number of such fragments 318c2ecf20Sopenharmony_ci * @total_bytes_available: cumulative number of bytes made available in 328c2ecf20Sopenharmony_ci * the ring buffer 338c2ecf20Sopenharmony_ci * @total_bytes_transferred: cumulative bytes transferred by offload DSP 348c2ecf20Sopenharmony_ci * @sleep: poll sleep 358c2ecf20Sopenharmony_ci * @private_data: driver private data pointer 368c2ecf20Sopenharmony_ci * @dma_area: virtual buffer address 378c2ecf20Sopenharmony_ci * @dma_addr: physical buffer address (not accessible from main CPU) 388c2ecf20Sopenharmony_ci * @dma_bytes: size of DMA area 398c2ecf20Sopenharmony_ci * @dma_buffer_p: runtime dma buffer pointer 408c2ecf20Sopenharmony_ci */ 418c2ecf20Sopenharmony_cistruct snd_compr_runtime { 428c2ecf20Sopenharmony_ci snd_pcm_state_t state; 438c2ecf20Sopenharmony_ci struct snd_compr_ops *ops; 448c2ecf20Sopenharmony_ci void *buffer; 458c2ecf20Sopenharmony_ci u64 buffer_size; 468c2ecf20Sopenharmony_ci u32 fragment_size; 478c2ecf20Sopenharmony_ci u32 fragments; 488c2ecf20Sopenharmony_ci u64 total_bytes_available; 498c2ecf20Sopenharmony_ci u64 total_bytes_transferred; 508c2ecf20Sopenharmony_ci wait_queue_head_t sleep; 518c2ecf20Sopenharmony_ci void *private_data; 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_ci unsigned char *dma_area; 548c2ecf20Sopenharmony_ci dma_addr_t dma_addr; 558c2ecf20Sopenharmony_ci size_t dma_bytes; 568c2ecf20Sopenharmony_ci struct snd_dma_buffer *dma_buffer_p; 578c2ecf20Sopenharmony_ci}; 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci/** 608c2ecf20Sopenharmony_ci * struct snd_compr_stream: compressed stream 618c2ecf20Sopenharmony_ci * @name: device name 628c2ecf20Sopenharmony_ci * @ops: pointer to DSP callbacks 638c2ecf20Sopenharmony_ci * @runtime: pointer to runtime structure 648c2ecf20Sopenharmony_ci * @device: device pointer 658c2ecf20Sopenharmony_ci * @error_work: delayed work used when closing the stream due to an error 668c2ecf20Sopenharmony_ci * @direction: stream direction, playback/recording 678c2ecf20Sopenharmony_ci * @metadata_set: metadata set flag, true when set 688c2ecf20Sopenharmony_ci * @next_track: has userspace signal next track transition, true when set 698c2ecf20Sopenharmony_ci * @partial_drain: undergoing partial_drain for stream, true when set 708c2ecf20Sopenharmony_ci * @private_data: pointer to DSP private data 718c2ecf20Sopenharmony_ci * @dma_buffer: allocated buffer if any 728c2ecf20Sopenharmony_ci */ 738c2ecf20Sopenharmony_cistruct snd_compr_stream { 748c2ecf20Sopenharmony_ci const char *name; 758c2ecf20Sopenharmony_ci struct snd_compr_ops *ops; 768c2ecf20Sopenharmony_ci struct snd_compr_runtime *runtime; 778c2ecf20Sopenharmony_ci struct snd_compr *device; 788c2ecf20Sopenharmony_ci struct delayed_work error_work; 798c2ecf20Sopenharmony_ci enum snd_compr_direction direction; 808c2ecf20Sopenharmony_ci bool metadata_set; 818c2ecf20Sopenharmony_ci bool next_track; 828c2ecf20Sopenharmony_ci bool partial_drain; 838c2ecf20Sopenharmony_ci void *private_data; 848c2ecf20Sopenharmony_ci struct snd_dma_buffer dma_buffer; 858c2ecf20Sopenharmony_ci}; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci/** 888c2ecf20Sopenharmony_ci * struct snd_compr_ops: compressed path DSP operations 898c2ecf20Sopenharmony_ci * @open: Open the compressed stream 908c2ecf20Sopenharmony_ci * This callback is mandatory and shall keep dsp ready to receive the stream 918c2ecf20Sopenharmony_ci * parameter 928c2ecf20Sopenharmony_ci * @free: Close the compressed stream, mandatory 938c2ecf20Sopenharmony_ci * @set_params: Sets the compressed stream parameters, mandatory 948c2ecf20Sopenharmony_ci * This can be called in during stream creation only to set codec params 958c2ecf20Sopenharmony_ci * and the stream properties 968c2ecf20Sopenharmony_ci * @get_params: retrieve the codec parameters, mandatory 978c2ecf20Sopenharmony_ci * @set_metadata: Set the metadata values for a stream 988c2ecf20Sopenharmony_ci * @get_metadata: retrieves the requested metadata values from stream 998c2ecf20Sopenharmony_ci * @trigger: Trigger operations like start, pause, resume, drain, stop. 1008c2ecf20Sopenharmony_ci * This callback is mandatory 1018c2ecf20Sopenharmony_ci * @pointer: Retrieve current h/w pointer information. Mandatory 1028c2ecf20Sopenharmony_ci * @copy: Copy the compressed data to/from userspace, Optional 1038c2ecf20Sopenharmony_ci * Can't be implemented if DSP supports mmap 1048c2ecf20Sopenharmony_ci * @mmap: DSP mmap method to mmap DSP memory 1058c2ecf20Sopenharmony_ci * @ack: Ack for DSP when data is written to audio buffer, Optional 1068c2ecf20Sopenharmony_ci * Not valid if copy is implemented 1078c2ecf20Sopenharmony_ci * @get_caps: Retrieve DSP capabilities, mandatory 1088c2ecf20Sopenharmony_ci * @get_codec_caps: Retrieve capabilities for a specific codec, mandatory 1098c2ecf20Sopenharmony_ci */ 1108c2ecf20Sopenharmony_cistruct snd_compr_ops { 1118c2ecf20Sopenharmony_ci int (*open)(struct snd_compr_stream *stream); 1128c2ecf20Sopenharmony_ci int (*free)(struct snd_compr_stream *stream); 1138c2ecf20Sopenharmony_ci int (*set_params)(struct snd_compr_stream *stream, 1148c2ecf20Sopenharmony_ci struct snd_compr_params *params); 1158c2ecf20Sopenharmony_ci int (*get_params)(struct snd_compr_stream *stream, 1168c2ecf20Sopenharmony_ci struct snd_codec *params); 1178c2ecf20Sopenharmony_ci int (*set_metadata)(struct snd_compr_stream *stream, 1188c2ecf20Sopenharmony_ci struct snd_compr_metadata *metadata); 1198c2ecf20Sopenharmony_ci int (*get_metadata)(struct snd_compr_stream *stream, 1208c2ecf20Sopenharmony_ci struct snd_compr_metadata *metadata); 1218c2ecf20Sopenharmony_ci int (*trigger)(struct snd_compr_stream *stream, int cmd); 1228c2ecf20Sopenharmony_ci int (*pointer)(struct snd_compr_stream *stream, 1238c2ecf20Sopenharmony_ci struct snd_compr_tstamp *tstamp); 1248c2ecf20Sopenharmony_ci int (*copy)(struct snd_compr_stream *stream, char __user *buf, 1258c2ecf20Sopenharmony_ci size_t count); 1268c2ecf20Sopenharmony_ci int (*mmap)(struct snd_compr_stream *stream, 1278c2ecf20Sopenharmony_ci struct vm_area_struct *vma); 1288c2ecf20Sopenharmony_ci int (*ack)(struct snd_compr_stream *stream, size_t bytes); 1298c2ecf20Sopenharmony_ci int (*get_caps) (struct snd_compr_stream *stream, 1308c2ecf20Sopenharmony_ci struct snd_compr_caps *caps); 1318c2ecf20Sopenharmony_ci int (*get_codec_caps) (struct snd_compr_stream *stream, 1328c2ecf20Sopenharmony_ci struct snd_compr_codec_caps *codec); 1338c2ecf20Sopenharmony_ci}; 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci/** 1368c2ecf20Sopenharmony_ci * struct snd_compr: Compressed device 1378c2ecf20Sopenharmony_ci * @name: DSP device name 1388c2ecf20Sopenharmony_ci * @dev: associated device instance 1398c2ecf20Sopenharmony_ci * @ops: pointer to DSP callbacks 1408c2ecf20Sopenharmony_ci * @private_data: pointer to DSP pvt data 1418c2ecf20Sopenharmony_ci * @card: sound card pointer 1428c2ecf20Sopenharmony_ci * @direction: Playback or capture direction 1438c2ecf20Sopenharmony_ci * @lock: device lock 1448c2ecf20Sopenharmony_ci * @device: device id 1458c2ecf20Sopenharmony_ci */ 1468c2ecf20Sopenharmony_cistruct snd_compr { 1478c2ecf20Sopenharmony_ci const char *name; 1488c2ecf20Sopenharmony_ci struct device dev; 1498c2ecf20Sopenharmony_ci struct snd_compr_ops *ops; 1508c2ecf20Sopenharmony_ci void *private_data; 1518c2ecf20Sopenharmony_ci struct snd_card *card; 1528c2ecf20Sopenharmony_ci unsigned int direction; 1538c2ecf20Sopenharmony_ci struct mutex lock; 1548c2ecf20Sopenharmony_ci int device; 1558c2ecf20Sopenharmony_ci#ifdef CONFIG_SND_VERBOSE_PROCFS 1568c2ecf20Sopenharmony_ci /* private: */ 1578c2ecf20Sopenharmony_ci char id[64]; 1588c2ecf20Sopenharmony_ci struct snd_info_entry *proc_root; 1598c2ecf20Sopenharmony_ci struct snd_info_entry *proc_info_entry; 1608c2ecf20Sopenharmony_ci#endif 1618c2ecf20Sopenharmony_ci}; 1628c2ecf20Sopenharmony_ci 1638c2ecf20Sopenharmony_ci/* compress device register APIs */ 1648c2ecf20Sopenharmony_ciint snd_compress_register(struct snd_compr *device); 1658c2ecf20Sopenharmony_ciint snd_compress_deregister(struct snd_compr *device); 1668c2ecf20Sopenharmony_ciint snd_compress_new(struct snd_card *card, int device, 1678c2ecf20Sopenharmony_ci int type, const char *id, struct snd_compr *compr); 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci/* dsp driver callback apis 1708c2ecf20Sopenharmony_ci * For playback: driver should call snd_compress_fragment_elapsed() to let the 1718c2ecf20Sopenharmony_ci * framework know that a fragment has been consumed from the ring buffer 1728c2ecf20Sopenharmony_ci * 1738c2ecf20Sopenharmony_ci * For recording: we want to know when a frame is available or when 1748c2ecf20Sopenharmony_ci * at least one frame is available so snd_compress_frame_elapsed() 1758c2ecf20Sopenharmony_ci * callback should be called when a encodeded frame is available 1768c2ecf20Sopenharmony_ci */ 1778c2ecf20Sopenharmony_cistatic inline void snd_compr_fragment_elapsed(struct snd_compr_stream *stream) 1788c2ecf20Sopenharmony_ci{ 1798c2ecf20Sopenharmony_ci wake_up(&stream->runtime->sleep); 1808c2ecf20Sopenharmony_ci} 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_cistatic inline void snd_compr_drain_notify(struct snd_compr_stream *stream) 1838c2ecf20Sopenharmony_ci{ 1848c2ecf20Sopenharmony_ci if (snd_BUG_ON(!stream)) 1858c2ecf20Sopenharmony_ci return; 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci /* for partial_drain case we are back to running state on success */ 1888c2ecf20Sopenharmony_ci if (stream->partial_drain) { 1898c2ecf20Sopenharmony_ci stream->runtime->state = SNDRV_PCM_STATE_RUNNING; 1908c2ecf20Sopenharmony_ci stream->partial_drain = false; /* clear this flag as well */ 1918c2ecf20Sopenharmony_ci } else { 1928c2ecf20Sopenharmony_ci stream->runtime->state = SNDRV_PCM_STATE_SETUP; 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci wake_up(&stream->runtime->sleep); 1968c2ecf20Sopenharmony_ci} 1978c2ecf20Sopenharmony_ci 1988c2ecf20Sopenharmony_ci/** 1998c2ecf20Sopenharmony_ci * snd_compr_set_runtime_buffer - Set the Compress runtime buffer 2008c2ecf20Sopenharmony_ci * @stream: compress stream to set 2018c2ecf20Sopenharmony_ci * @bufp: the buffer information, NULL to clear 2028c2ecf20Sopenharmony_ci * 2038c2ecf20Sopenharmony_ci * Copy the buffer information to runtime buffer when @bufp is non-NULL. 2048c2ecf20Sopenharmony_ci * Otherwise it clears the current buffer information. 2058c2ecf20Sopenharmony_ci */ 2068c2ecf20Sopenharmony_cistatic inline void 2078c2ecf20Sopenharmony_cisnd_compr_set_runtime_buffer(struct snd_compr_stream *stream, 2088c2ecf20Sopenharmony_ci struct snd_dma_buffer *bufp) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci struct snd_compr_runtime *runtime = stream->runtime; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci if (bufp) { 2138c2ecf20Sopenharmony_ci runtime->dma_buffer_p = bufp; 2148c2ecf20Sopenharmony_ci runtime->dma_area = bufp->area; 2158c2ecf20Sopenharmony_ci runtime->dma_addr = bufp->addr; 2168c2ecf20Sopenharmony_ci runtime->dma_bytes = bufp->bytes; 2178c2ecf20Sopenharmony_ci } else { 2188c2ecf20Sopenharmony_ci runtime->dma_buffer_p = NULL; 2198c2ecf20Sopenharmony_ci runtime->dma_area = NULL; 2208c2ecf20Sopenharmony_ci runtime->dma_addr = 0; 2218c2ecf20Sopenharmony_ci runtime->dma_bytes = 0; 2228c2ecf20Sopenharmony_ci } 2238c2ecf20Sopenharmony_ci} 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_ciint snd_compr_malloc_pages(struct snd_compr_stream *stream, size_t size); 2268c2ecf20Sopenharmony_ciint snd_compr_free_pages(struct snd_compr_stream *stream); 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ciint snd_compr_stop_error(struct snd_compr_stream *stream, 2298c2ecf20Sopenharmony_ci snd_pcm_state_t state); 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci#endif 232