Commit 4c414216 authored by Takashi Iwai's avatar Takashi Iwai

Merge branch 'topic/kerneldoc' into for-next

parents ce40a6d3 67faa6eb
...@@ -57,7 +57,7 @@ ...@@ -57,7 +57,7 @@
!Esound/core/pcm.c !Esound/core/pcm.c
!Esound/core/pcm_lib.c !Esound/core/pcm_lib.c
!Esound/core/pcm_native.c !Esound/core/pcm_native.c
!include/sound/pcm.h !Iinclude/sound/pcm.h
</sect1> </sect1>
<sect1><title>PCM Format Helpers</title> <sect1><title>PCM Format Helpers</title>
!Esound/core/pcm_misc.c !Esound/core/pcm_misc.c
...@@ -104,13 +104,30 @@ ...@@ -104,13 +104,30 @@
!Iinclude/sound/compress_driver.h !Iinclude/sound/compress_driver.h
</sect1> </sect1>
</chapter> </chapter>
<chapter><title>ASoC</title>
<sect1><title>ASoC Core API</title>
!Iinclude/sound/soc.h
!Esound/soc/soc-core.c
!Esound/soc/soc-cache.c
!Esound/soc/soc-devres.c
!Esound/soc/soc-io.c
!Esound/soc/soc-pcm.c
</sect1>
<sect1><title>ASoC DAPM API</title>
!Esound/soc/soc-dapm.c
</sect1>
<sect1><title>ASoC DMA Engine API</title>
!Esound/soc/soc-generic-dmaengine-pcm.c
</sect1>
</chapter>
<chapter><title>Miscellaneous Functions</title> <chapter><title>Miscellaneous Functions</title>
<sect1><title>Hardware-Dependent Devices API</title> <sect1><title>Hardware-Dependent Devices API</title>
!Esound/core/hwdep.c !Esound/core/hwdep.c
</sect1> </sect1>
<sect1><title>Jack Abstraction Layer API</title> <sect1><title>Jack Abstraction Layer API</title>
!Esound/core/jack.c
!Iinclude/sound/jack.h !Iinclude/sound/jack.h
!Esound/core/jack.c
!Esound/soc/soc-jack.c
</sect1> </sect1>
<sect1><title>ISA DMA Helpers</title> <sect1><title>ISA DMA Helpers</title>
!Esound/core/isadma.c !Esound/core/isadma.c
......
...@@ -533,6 +533,12 @@ snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size) ...@@ -533,6 +533,12 @@ snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size)
* PCM library * PCM library
*/ */
/**
* snd_pcm_stream_linked - Check whether the substream is linked with others
* @substream: substream to check
*
* Returns true if the given substream is being linked with others.
*/
static inline int snd_pcm_stream_linked(struct snd_pcm_substream *substream) static inline int snd_pcm_stream_linked(struct snd_pcm_substream *substream)
{ {
return substream->group != &substream->self_group; return substream->group != &substream->self_group;
...@@ -543,6 +549,16 @@ void snd_pcm_stream_unlock(struct snd_pcm_substream *substream); ...@@ -543,6 +549,16 @@ void snd_pcm_stream_unlock(struct snd_pcm_substream *substream);
void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream); void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream);
void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream); void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream);
unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream); unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream);
/**
* snd_pcm_stream_lock_irqsave - Lock the PCM stream
* @substream: PCM substream
* @flags: irq flags
*
* This locks the PCM stream like snd_pcm_stream_lock() but with the local
* IRQ (only when nonatomic is false). In nonatomic case, this is identical
* as snd_pcm_stream_lock().
*/
#define snd_pcm_stream_lock_irqsave(substream, flags) \ #define snd_pcm_stream_lock_irqsave(substream, flags) \
do { \ do { \
typecheck(unsigned long, flags); \ typecheck(unsigned long, flags); \
...@@ -551,9 +567,25 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream); ...@@ -551,9 +567,25 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream);
void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
unsigned long flags); unsigned long flags);
/**
* snd_pcm_group_for_each_entry - iterate over the linked substreams
* @s: the iterator
* @substream: the substream
*
* Iterate over the all linked substreams to the given @substream.
* When @substream isn't linked with any others, this gives returns @substream
* itself once.
*/
#define snd_pcm_group_for_each_entry(s, substream) \ #define snd_pcm_group_for_each_entry(s, substream) \
list_for_each_entry(s, &substream->group->substreams, link_list) list_for_each_entry(s, &substream->group->substreams, link_list)
/**
* snd_pcm_running - Check whether the substream is in a running state
* @substream: substream to check
*
* Returns true if the given substream is in the state RUNNING, or in the
* state DRAINING for playback.
*/
static inline int snd_pcm_running(struct snd_pcm_substream *substream) static inline int snd_pcm_running(struct snd_pcm_substream *substream)
{ {
return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING || return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING ||
...@@ -561,45 +593,81 @@ static inline int snd_pcm_running(struct snd_pcm_substream *substream) ...@@ -561,45 +593,81 @@ static inline int snd_pcm_running(struct snd_pcm_substream *substream)
substream->stream == SNDRV_PCM_STREAM_PLAYBACK)); substream->stream == SNDRV_PCM_STREAM_PLAYBACK));
} }
/**
* bytes_to_samples - Unit conversion of the size from bytes to samples
* @runtime: PCM runtime instance
* @size: size in bytes
*/
static inline ssize_t bytes_to_samples(struct snd_pcm_runtime *runtime, ssize_t size) static inline ssize_t bytes_to_samples(struct snd_pcm_runtime *runtime, ssize_t size)
{ {
return size * 8 / runtime->sample_bits; return size * 8 / runtime->sample_bits;
} }
/**
* bytes_to_frames - Unit conversion of the size from bytes to frames
* @runtime: PCM runtime instance
* @size: size in bytes
*/
static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, ssize_t size) static inline snd_pcm_sframes_t bytes_to_frames(struct snd_pcm_runtime *runtime, ssize_t size)
{ {
return size * 8 / runtime->frame_bits; return size * 8 / runtime->frame_bits;
} }
/**
* samples_to_bytes - Unit conversion of the size from samples to bytes
* @runtime: PCM runtime instance
* @size: size in samples
*/
static inline ssize_t samples_to_bytes(struct snd_pcm_runtime *runtime, ssize_t size) static inline ssize_t samples_to_bytes(struct snd_pcm_runtime *runtime, ssize_t size)
{ {
return size * runtime->sample_bits / 8; return size * runtime->sample_bits / 8;
} }
/**
* frames_to_bytes - Unit conversion of the size from frames to bytes
* @runtime: PCM runtime instance
* @size: size in frames
*/
static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_sframes_t size) static inline ssize_t frames_to_bytes(struct snd_pcm_runtime *runtime, snd_pcm_sframes_t size)
{ {
return size * runtime->frame_bits / 8; return size * runtime->frame_bits / 8;
} }
/**
* frame_aligned - Check whether the byte size is aligned to frames
* @runtime: PCM runtime instance
* @bytes: size in bytes
*/
static inline int frame_aligned(struct snd_pcm_runtime *runtime, ssize_t bytes) static inline int frame_aligned(struct snd_pcm_runtime *runtime, ssize_t bytes)
{ {
return bytes % runtime->byte_align == 0; return bytes % runtime->byte_align == 0;
} }
/**
* snd_pcm_lib_buffer_bytes - Get the buffer size of the current PCM in bytes
* @substream: PCM substream
*/
static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substream) static inline size_t snd_pcm_lib_buffer_bytes(struct snd_pcm_substream *substream)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
return frames_to_bytes(runtime, runtime->buffer_size); return frames_to_bytes(runtime, runtime->buffer_size);
} }
/**
* snd_pcm_lib_period_bytes - Get the period size of the current PCM in bytes
* @substream: PCM substream
*/
static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substream) static inline size_t snd_pcm_lib_period_bytes(struct snd_pcm_substream *substream)
{ {
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
return frames_to_bytes(runtime, runtime->period_size); return frames_to_bytes(runtime, runtime->period_size);
} }
/* /**
* result is: 0 ... (boundary - 1) * snd_pcm_playback_avail - Get the available (writable) space for playback
* @runtime: PCM runtime instance
*
* Result is between 0 ... (boundary - 1)
*/ */
static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime) static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *runtime)
{ {
...@@ -611,8 +679,11 @@ static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *r ...@@ -611,8 +679,11 @@ static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *r
return avail; return avail;
} }
/* /**
* result is: 0 ... (boundary - 1) * snd_pcm_playback_avail - Get the available (readable) space for capture
* @runtime: PCM runtime instance
*
* Result is between 0 ... (boundary - 1)
*/ */
static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *runtime) static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *runtime)
{ {
...@@ -622,11 +693,19 @@ static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *ru ...@@ -622,11 +693,19 @@ static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *ru
return avail; return avail;
} }
/**
* snd_pcm_playback_hw_avail - Get the queued space for playback
* @runtime: PCM runtime instance
*/
static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime *runtime) static inline snd_pcm_sframes_t snd_pcm_playback_hw_avail(struct snd_pcm_runtime *runtime)
{ {
return runtime->buffer_size - snd_pcm_playback_avail(runtime); return runtime->buffer_size - snd_pcm_playback_avail(runtime);
} }
/**
* snd_pcm_capture_hw_avail - Get the free space for capture
* @runtime: PCM runtime instance
*/
static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(struct snd_pcm_runtime *runtime) static inline snd_pcm_sframes_t snd_pcm_capture_hw_avail(struct snd_pcm_runtime *runtime)
{ {
return runtime->buffer_size - snd_pcm_capture_avail(runtime); return runtime->buffer_size - snd_pcm_capture_avail(runtime);
...@@ -706,6 +785,20 @@ static inline int snd_pcm_capture_empty(struct snd_pcm_substream *substream) ...@@ -706,6 +785,20 @@ static inline int snd_pcm_capture_empty(struct snd_pcm_substream *substream)
return snd_pcm_capture_avail(runtime) == 0; return snd_pcm_capture_avail(runtime) == 0;
} }
/**
* snd_pcm_trigger_done - Mark the master substream
* @substream: the pcm substream instance
* @master: the linked master substream
*
* When multiple substreams of the same card are linked and the hardware
* supports the single-shot operation, the driver calls this in the loop
* in snd_pcm_group_for_each_entry() for marking the substream as "done".
* Then most of trigger operations are performed only to the given master
* substream.
*
* The trigger_master mark is cleared at timestamp updates at the end
* of trigger operations.
*/
static inline void snd_pcm_trigger_done(struct snd_pcm_substream *substream, static inline void snd_pcm_trigger_done(struct snd_pcm_substream *substream,
struct snd_pcm_substream *master) struct snd_pcm_substream *master)
{ {
...@@ -748,18 +841,59 @@ static inline const struct snd_interval *hw_param_interval_c(const struct snd_pc ...@@ -748,18 +841,59 @@ static inline const struct snd_interval *hw_param_interval_c(const struct snd_pc
return &params->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]; return &params->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL];
} }
#define params_channels(p) \ /**
(hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_CHANNELS)->min) * params_channels - Get the number of channels from the hw params
#define params_rate(p) \ * @p: hw params
(hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_RATE)->min) */
#define params_period_size(p) \ static inline unsigned int params_channels(const struct snd_pcm_hw_params *p)
(hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min) {
#define params_periods(p) \ return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_CHANNELS)->min;
(hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_PERIODS)->min) }
#define params_buffer_size(p) \
(hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_BUFFER_SIZE)->min) /**
#define params_buffer_bytes(p) \ * params_channels - Get the sample rate from the hw params
(hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min) * @p: hw params
*/
static inline unsigned int params_rate(const struct snd_pcm_hw_params *p)
{
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_RATE)->min;
}
/**
* params_channels - Get the period size (in frames) from the hw params
* @p: hw params
*/
static inline unsigned int params_period_size(const struct snd_pcm_hw_params *p)
{
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min;
}
/**
* params_channels - Get the number of periods from the hw params
* @p: hw params
*/
static inline unsigned int params_periods(const struct snd_pcm_hw_params *p)
{
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_PERIODS)->min;
}
/**
* params_channels - Get the buffer size (in frames) from the hw params
* @p: hw params
*/
static inline unsigned int params_buffer_size(const struct snd_pcm_hw_params *p)
{
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_BUFFER_SIZE)->min;
}
/**
* params_channels - Get the buffer size (in bytes) from the hw params
* @p: hw params
*/
static inline unsigned int params_buffer_bytes(const struct snd_pcm_hw_params *p)
{
return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min;
}
int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v); int snd_interval_refine(struct snd_interval *i, const struct snd_interval *v);
void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c); void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c);
...@@ -881,6 +1015,14 @@ unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit); ...@@ -881,6 +1015,14 @@ unsigned int snd_pcm_rate_bit_to_rate(unsigned int rate_bit);
unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a, unsigned int snd_pcm_rate_mask_intersect(unsigned int rates_a,
unsigned int rates_b); unsigned int rates_b);
/**
* snd_pcm_set_runtime_buffer - Set the PCM runtime buffer
* @substream: PCM substream to set
* @bufp: the buffer information, NULL to clear
*
* Copy the buffer information to runtime->dma_buffer when @bufp is non-NULL.
* Otherwise it clears the current buffer information.
*/
static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream, static inline void snd_pcm_set_runtime_buffer(struct snd_pcm_substream *substream,
struct snd_dma_buffer *bufp) struct snd_dma_buffer *bufp)
{ {
...@@ -906,6 +1048,11 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream); ...@@ -906,6 +1048,11 @@ void snd_pcm_timer_resolution_change(struct snd_pcm_substream *substream);
void snd_pcm_timer_init(struct snd_pcm_substream *substream); void snd_pcm_timer_init(struct snd_pcm_substream *substream);
void snd_pcm_timer_done(struct snd_pcm_substream *substream); void snd_pcm_timer_done(struct snd_pcm_substream *substream);
/**
* snd_pcm_gettime - Fill the timespec depending on the timestamp mode
* @runtime: PCM runtime instance
* @tv: timespec to fill
*/
static inline void snd_pcm_gettime(struct snd_pcm_runtime *runtime, static inline void snd_pcm_gettime(struct snd_pcm_runtime *runtime,
struct timespec *tv) struct timespec *tv)
{ {
...@@ -942,7 +1089,6 @@ int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream, ...@@ -942,7 +1089,6 @@ int _snd_pcm_lib_alloc_vmalloc_buffer(struct snd_pcm_substream *substream,
int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream); int snd_pcm_lib_free_vmalloc_buffer(struct snd_pcm_substream *substream);
struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
unsigned long offset); unsigned long offset);
#if 0 /* for kernel-doc */
/** /**
* snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer * snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer
* @substream: the substream to allocate the buffer to * @substream: the substream to allocate the buffer to
...@@ -955,8 +1101,13 @@ struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, ...@@ -955,8 +1101,13 @@ struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream,
* Return: 1 if the buffer was changed, 0 if not changed, or a negative error * Return: 1 if the buffer was changed, 0 if not changed, or a negative error
* code. * code.
*/ */
static int snd_pcm_lib_alloc_vmalloc_buffer static inline int snd_pcm_lib_alloc_vmalloc_buffer
(struct snd_pcm_substream *substream, size_t size); (struct snd_pcm_substream *substream, size_t size)
{
return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size,
GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO);
}
/** /**
* snd_pcm_lib_alloc_vmalloc_32_buffer - allocate 32-bit-addressable buffer * snd_pcm_lib_alloc_vmalloc_32_buffer - allocate 32-bit-addressable buffer
* @substream: the substream to allocate the buffer to * @substream: the substream to allocate the buffer to
...@@ -968,15 +1119,12 @@ static int snd_pcm_lib_alloc_vmalloc_buffer ...@@ -968,15 +1119,12 @@ static int snd_pcm_lib_alloc_vmalloc_buffer
* Return: 1 if the buffer was changed, 0 if not changed, or a negative error * Return: 1 if the buffer was changed, 0 if not changed, or a negative error
* code. * code.
*/ */
static int snd_pcm_lib_alloc_vmalloc_32_buffer static inline int snd_pcm_lib_alloc_vmalloc_32_buffer
(struct snd_pcm_substream *substream, size_t size); (struct snd_pcm_substream *substream, size_t size)
#endif {
#define snd_pcm_lib_alloc_vmalloc_buffer(subs, size) \ return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size,
_snd_pcm_lib_alloc_vmalloc_buffer \ GFP_KERNEL | GFP_DMA32 | __GFP_ZERO);
(subs, size, GFP_KERNEL | __GFP_HIGHMEM | __GFP_ZERO) }
#define snd_pcm_lib_alloc_vmalloc_32_buffer(subs, size) \
_snd_pcm_lib_alloc_vmalloc_buffer \
(subs, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO)
#define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p) #define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p)
...@@ -996,18 +1144,35 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, ...@@ -996,18 +1144,35 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream,
#define snd_pcm_sgbuf_ops_page NULL #define snd_pcm_sgbuf_ops_page NULL
#endif /* SND_DMA_SGBUF */ #endif /* SND_DMA_SGBUF */
/**
* snd_pcm_sgbuf_get_addr - Get the DMA address at the corresponding offset
* @substream: PCM substream
* @ofs: byte offset
*/
static inline dma_addr_t static inline dma_addr_t
snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs) snd_pcm_sgbuf_get_addr(struct snd_pcm_substream *substream, unsigned int ofs)
{ {
return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs); return snd_sgbuf_get_addr(snd_pcm_get_dma_buf(substream), ofs);
} }
/**
* snd_pcm_sgbuf_get_ptr - Get the virtual address at the corresponding offset
* @substream: PCM substream
* @ofs: byte offset
*/
static inline void * static inline void *
snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs) snd_pcm_sgbuf_get_ptr(struct snd_pcm_substream *substream, unsigned int ofs)
{ {
return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs); return snd_sgbuf_get_ptr(snd_pcm_get_dma_buf(substream), ofs);
} }
/**
* snd_pcm_sgbuf_chunk_size - Compute the max size that fits within the contig.
* page from the given size
* @substream: PCM substream
* @ofs: byte offset
* @size: byte size to examine
*/
static inline unsigned int static inline unsigned int
snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
unsigned int ofs, unsigned int size) unsigned int ofs, unsigned int size)
...@@ -1015,13 +1180,24 @@ snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, ...@@ -1015,13 +1180,24 @@ snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream,
return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size); return snd_sgbuf_get_chunk_size(snd_pcm_get_dma_buf(substream), ofs, size);
} }
/* handle mmap counter - PCM mmap callback should handle this counter properly */ /**
* snd_pcm_mmap_data_open - increase the mmap counter
* @area: VMA
*
* PCM mmap callback should handle this counter properly
*/
static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area) static inline void snd_pcm_mmap_data_open(struct vm_area_struct *area)
{ {
struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
atomic_inc(&substream->mmap_count); atomic_inc(&substream->mmap_count);
} }
/**
* snd_pcm_mmap_data_close - decrease the mmap counter
* @area: VMA
*
* PCM mmap callback should handle this counter properly
*/
static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area) static inline void snd_pcm_mmap_data_close(struct vm_area_struct *area)
{ {
struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data;
...@@ -1041,6 +1217,11 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s ...@@ -1041,6 +1217,11 @@ int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, struct vm_area_s
#define snd_pcm_lib_mmap_vmalloc NULL #define snd_pcm_lib_mmap_vmalloc NULL
/**
* snd_pcm_limit_isa_dma_size - Get the max size fitting with ISA DMA transfer
* @dma: DMA number
* @max: pointer to store the max size
*/
static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max) static inline void snd_pcm_limit_isa_dma_size(int dma, size_t *max)
{ {
*max = dma < 4 ? 64 * 1024 : 128 * 1024; *max = dma < 4 ? 64 * 1024 : 128 * 1024;
...@@ -1093,7 +1274,11 @@ struct snd_pcm_chmap { ...@@ -1093,7 +1274,11 @@ struct snd_pcm_chmap {
void *private_data; /* optional: private data pointer */ void *private_data; /* optional: private data pointer */
}; };
/* get the PCM substream assigned to the given chmap info */ /**
* snd_pcm_chmap_substream - get the PCM substream assigned to the given chmap info
* @info: chmap information
* @idx: the substream number index
*/
static inline struct snd_pcm_substream * static inline struct snd_pcm_substream *
snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx) snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx)
{ {
...@@ -1120,7 +1305,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, ...@@ -1120,7 +1305,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream,
unsigned long private_value, unsigned long private_value,
struct snd_pcm_chmap **info_ret); struct snd_pcm_chmap **info_ret);
/* Strong-typed conversion of pcm_format to bitwise */ /**
* pcm_format_to_bits - Strong-typed conversion of pcm_format to bitwise
* @pcm_format: PCM format
*/
static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format) static inline u64 pcm_format_to_bits(snd_pcm_format_t pcm_format)
{ {
return 1ULL << (__force int) pcm_format; return 1ULL << (__force int) pcm_format;
......
...@@ -141,6 +141,16 @@ static int snd_ctl_release(struct inode *inode, struct file *file) ...@@ -141,6 +141,16 @@ static int snd_ctl_release(struct inode *inode, struct file *file)
return 0; return 0;
} }
/**
* snd_ctl_notify - Send notification to user-space for a control change
* @card: the card to send notification
* @mask: the event mask, SNDRV_CTL_EVENT_*
* @id: the ctl element id to send notification
*
* This function adds an event record with the given id and mask, appends
* to the list and wakes up the user-space for notification. This can be
* called in the atomic context.
*/
void snd_ctl_notify(struct snd_card *card, unsigned int mask, void snd_ctl_notify(struct snd_card *card, unsigned int mask,
struct snd_ctl_elem_id *id) struct snd_ctl_elem_id *id)
{ {
...@@ -179,7 +189,6 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, ...@@ -179,7 +189,6 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask,
} }
read_unlock(&card->ctl_files_rwlock); read_unlock(&card->ctl_files_rwlock);
} }
EXPORT_SYMBOL(snd_ctl_notify); EXPORT_SYMBOL(snd_ctl_notify);
/** /**
...@@ -261,7 +270,6 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, ...@@ -261,7 +270,6 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol,
kctl.private_data = private_data; kctl.private_data = private_data;
return snd_ctl_new(&kctl, access); return snd_ctl_new(&kctl, access);
} }
EXPORT_SYMBOL(snd_ctl_new1); EXPORT_SYMBOL(snd_ctl_new1);
/** /**
...@@ -280,7 +288,6 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol) ...@@ -280,7 +288,6 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol)
kfree(kcontrol); kfree(kcontrol);
} }
} }
EXPORT_SYMBOL(snd_ctl_free_one); EXPORT_SYMBOL(snd_ctl_free_one);
static bool snd_ctl_remove_numid_conflict(struct snd_card *card, static bool snd_ctl_remove_numid_conflict(struct snd_card *card,
...@@ -376,7 +383,6 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) ...@@ -376,7 +383,6 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol)
snd_ctl_free_one(kcontrol); snd_ctl_free_one(kcontrol);
return err; return err;
} }
EXPORT_SYMBOL(snd_ctl_add); EXPORT_SYMBOL(snd_ctl_add);
/** /**
...@@ -471,7 +477,6 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) ...@@ -471,7 +477,6 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol)
snd_ctl_free_one(kcontrol); snd_ctl_free_one(kcontrol);
return 0; return 0;
} }
EXPORT_SYMBOL(snd_ctl_remove); EXPORT_SYMBOL(snd_ctl_remove);
/** /**
...@@ -499,7 +504,6 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) ...@@ -499,7 +504,6 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id)
up_write(&card->controls_rwsem); up_write(&card->controls_rwsem);
return ret; return ret;
} }
EXPORT_SYMBOL(snd_ctl_remove_id); EXPORT_SYMBOL(snd_ctl_remove_id);
/** /**
...@@ -617,7 +621,6 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id, ...@@ -617,7 +621,6 @@ int snd_ctl_rename_id(struct snd_card *card, struct snd_ctl_elem_id *src_id,
up_write(&card->controls_rwsem); up_write(&card->controls_rwsem);
return 0; return 0;
} }
EXPORT_SYMBOL(snd_ctl_rename_id); EXPORT_SYMBOL(snd_ctl_rename_id);
/** /**
...@@ -645,7 +648,6 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi ...@@ -645,7 +648,6 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi
} }
return NULL; return NULL;
} }
EXPORT_SYMBOL(snd_ctl_find_numid); EXPORT_SYMBOL(snd_ctl_find_numid);
/** /**
...@@ -687,7 +689,6 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, ...@@ -687,7 +689,6 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card,
} }
return NULL; return NULL;
} }
EXPORT_SYMBOL(snd_ctl_find_id); EXPORT_SYMBOL(snd_ctl_find_id);
static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl,
...@@ -1526,19 +1527,28 @@ static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head * ...@@ -1526,19 +1527,28 @@ static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head *
return 0; return 0;
} }
/**
* snd_ctl_register_ioctl - register the device-specific control-ioctls
* @fcn: ioctl callback function
*
* called from each device manager like pcm.c, hwdep.c, etc.
*/
int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn) int snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn)
{ {
return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls);
} }
EXPORT_SYMBOL(snd_ctl_register_ioctl); EXPORT_SYMBOL(snd_ctl_register_ioctl);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
/**
* snd_ctl_register_ioctl_compat - register the device-specific 32bit compat
* control-ioctls
* @fcn: ioctl callback function
*/
int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn) int snd_ctl_register_ioctl_compat(snd_kctl_ioctl_func_t fcn)
{ {
return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls);
} }
EXPORT_SYMBOL(snd_ctl_register_ioctl_compat); EXPORT_SYMBOL(snd_ctl_register_ioctl_compat);
#endif #endif
...@@ -1566,19 +1576,26 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, ...@@ -1566,19 +1576,26 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn,
return -EINVAL; return -EINVAL;
} }
/**
* snd_ctl_unregister_ioctl - de-register the device-specific control-ioctls
* @fcn: ioctl callback function to unregister
*/
int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn) int snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn)
{ {
return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls);
} }
EXPORT_SYMBOL(snd_ctl_unregister_ioctl); EXPORT_SYMBOL(snd_ctl_unregister_ioctl);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
/**
* snd_ctl_unregister_ioctl - de-register the device-specific compat 32bit
* control-ioctls
* @fcn: ioctl callback function to unregister
*/
int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn) int snd_ctl_unregister_ioctl_compat(snd_kctl_ioctl_func_t fcn)
{ {
return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls);
} }
EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat); EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat);
#endif #endif
...@@ -1702,6 +1719,16 @@ int snd_ctl_create(struct snd_card *card) ...@@ -1702,6 +1719,16 @@ int snd_ctl_create(struct snd_card *card)
/* /*
* Frequently used control callbacks/helpers * Frequently used control callbacks/helpers
*/ */
/**
* snd_ctl_boolean_mono_info - Helper function for a standard boolean info
* callback with a mono channel
* @kcontrol: the kcontrol instance
* @uinfo: info to store
*
* This is a function that can be used as info callback for a standard
* boolean control with a single mono channel.
*/
int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo) struct snd_ctl_elem_info *uinfo)
{ {
...@@ -1711,9 +1738,17 @@ int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, ...@@ -1711,9 +1738,17 @@ int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol,
uinfo->value.integer.max = 1; uinfo->value.integer.max = 1;
return 0; return 0;
} }
EXPORT_SYMBOL(snd_ctl_boolean_mono_info); EXPORT_SYMBOL(snd_ctl_boolean_mono_info);
/**
* snd_ctl_boolean_stereo_info - Helper function for a standard boolean info
* callback with stereo two channels
* @kcontrol: the kcontrol instance
* @uinfo: info to store
*
* This is a function that can be used as info callback for a standard
* boolean control with stereo two channels.
*/
int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo) struct snd_ctl_elem_info *uinfo)
{ {
...@@ -1723,7 +1758,6 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, ...@@ -1723,7 +1758,6 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol,
uinfo->value.integer.max = 1; uinfo->value.integer.max = 1;
return 0; return 0;
} }
EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); EXPORT_SYMBOL(snd_ctl_boolean_stereo_info);
/** /**
......
...@@ -438,17 +438,6 @@ int snd_card_disconnect(struct snd_card *card) ...@@ -438,17 +438,6 @@ int snd_card_disconnect(struct snd_card *card)
EXPORT_SYMBOL(snd_card_disconnect); EXPORT_SYMBOL(snd_card_disconnect);
/**
* snd_card_free - frees given soundcard structure
* @card: soundcard structure
*
* This function releases the soundcard structure and the all assigned
* devices automatically. That is, you don't have to release the devices
* by yourself.
*
* Return: Zero. Frees all associated devices and frees the control
* interface associated to given soundcard.
*/
static int snd_card_do_free(struct snd_card *card) static int snd_card_do_free(struct snd_card *card)
{ {
#if IS_ENABLED(CONFIG_SND_MIXER_OSS) #if IS_ENABLED(CONFIG_SND_MIXER_OSS)
...@@ -469,6 +458,15 @@ static int snd_card_do_free(struct snd_card *card) ...@@ -469,6 +458,15 @@ static int snd_card_do_free(struct snd_card *card)
return 0; return 0;
} }
/**
* snd_card_free_when_closed - Disconnect the card, free it later eventually
* @card: soundcard structure
*
* Unlike snd_card_free(), this function doesn't try to release the card
* resource immediately, but tries to disconnect at first. When the card
* is still in use, the function returns before freeing the resources.
* The card resources will be freed when the refcount gets to zero.
*/
int snd_card_free_when_closed(struct snd_card *card) int snd_card_free_when_closed(struct snd_card *card)
{ {
int ret = snd_card_disconnect(card); int ret = snd_card_disconnect(card);
...@@ -479,6 +477,19 @@ int snd_card_free_when_closed(struct snd_card *card) ...@@ -479,6 +477,19 @@ int snd_card_free_when_closed(struct snd_card *card)
} }
EXPORT_SYMBOL(snd_card_free_when_closed); EXPORT_SYMBOL(snd_card_free_when_closed);
/**
* snd_card_free - frees given soundcard structure
* @card: soundcard structure
*
* This function releases the soundcard structure and the all assigned
* devices automatically. That is, you don't have to release the devices
* by yourself.
*
* This function waits until the all resources are properly released.
*
* Return: Zero. Frees all associated devices and frees the control
* interface associated to given soundcard.
*/
int snd_card_free(struct snd_card *card) int snd_card_free(struct snd_card *card)
{ {
struct completion released; struct completion released;
......
...@@ -218,6 +218,10 @@ static char *snd_pcm_format_names[] = { ...@@ -218,6 +218,10 @@ static char *snd_pcm_format_names[] = {
FORMAT(DSD_U32_LE), FORMAT(DSD_U32_LE),
}; };
/**
* snd_pcm_format_name - Return a name string for the given PCM format
* @format: PCM format
*/
const char *snd_pcm_format_name(snd_pcm_format_t format) const char *snd_pcm_format_name(snd_pcm_format_t format)
{ {
if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names)) if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names))
...@@ -707,7 +711,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) ...@@ -707,7 +711,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count)
} }
return 0; return 0;
} }
EXPORT_SYMBOL(snd_pcm_new_stream); EXPORT_SYMBOL(snd_pcm_new_stream);
static int _snd_pcm_new(struct snd_card *card, const char *id, int device, static int _snd_pcm_new(struct snd_card *card, const char *id, int device,
...@@ -1155,6 +1158,15 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) ...@@ -1155,6 +1158,15 @@ static int snd_pcm_dev_disconnect(struct snd_device *device)
return 0; return 0;
} }
/**
* snd_pcm_notify - Add/remove the notify list
* @notify: PCM notify list
* @nfree: 0 = register, 1 = unregister
*
* This adds the given notifier to the global list so that the callback is
* called for each registered PCM devices. This exists only for PCM OSS
* emulation, so far.
*/
int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
{ {
struct snd_pcm *pcm; struct snd_pcm *pcm;
...@@ -1177,7 +1189,6 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) ...@@ -1177,7 +1189,6 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree)
mutex_unlock(&register_mutex); mutex_unlock(&register_mutex);
return 0; return 0;
} }
EXPORT_SYMBOL(snd_pcm_notify); EXPORT_SYMBOL(snd_pcm_notify);
#ifdef CONFIG_PROC_FS #ifdef CONFIG_PROC_FS
......
...@@ -74,6 +74,14 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream); ...@@ -74,6 +74,14 @@ static int snd_pcm_open(struct file *file, struct snd_pcm *pcm, int stream);
static DEFINE_RWLOCK(snd_pcm_link_rwlock); static DEFINE_RWLOCK(snd_pcm_link_rwlock);
static DECLARE_RWSEM(snd_pcm_link_rwsem); static DECLARE_RWSEM(snd_pcm_link_rwsem);
/**
* snd_pcm_stream_lock - Lock the PCM stream
* @substream: PCM substream
*
* This locks the PCM stream's spinlock or mutex depending on the nonatomic
* flag of the given substream. This also takes the global link rw lock
* (or rw sem), too, for avoiding the race with linked streams.
*/
void snd_pcm_stream_lock(struct snd_pcm_substream *substream) void snd_pcm_stream_lock(struct snd_pcm_substream *substream)
{ {
if (substream->pcm->nonatomic) { if (substream->pcm->nonatomic) {
...@@ -86,6 +94,12 @@ void snd_pcm_stream_lock(struct snd_pcm_substream *substream) ...@@ -86,6 +94,12 @@ void snd_pcm_stream_lock(struct snd_pcm_substream *substream)
} }
EXPORT_SYMBOL_GPL(snd_pcm_stream_lock); EXPORT_SYMBOL_GPL(snd_pcm_stream_lock);
/**
* snd_pcm_stream_lock - Unlock the PCM stream
* @substream: PCM substream
*
* This unlocks the PCM stream that has been locked via snd_pcm_stream_lock().
*/
void snd_pcm_stream_unlock(struct snd_pcm_substream *substream) void snd_pcm_stream_unlock(struct snd_pcm_substream *substream)
{ {
if (substream->pcm->nonatomic) { if (substream->pcm->nonatomic) {
...@@ -98,6 +112,14 @@ void snd_pcm_stream_unlock(struct snd_pcm_substream *substream) ...@@ -98,6 +112,14 @@ void snd_pcm_stream_unlock(struct snd_pcm_substream *substream)
} }
EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock); EXPORT_SYMBOL_GPL(snd_pcm_stream_unlock);
/**
* snd_pcm_stream_lock_irq - Lock the PCM stream
* @substream: PCM substream
*
* This locks the PCM stream like snd_pcm_stream_lock() and disables the local
* IRQ (only when nonatomic is false). In nonatomic case, this is identical
* as snd_pcm_stream_lock().
*/
void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream)
{ {
if (!substream->pcm->nonatomic) if (!substream->pcm->nonatomic)
...@@ -106,6 +128,12 @@ void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream) ...@@ -106,6 +128,12 @@ void snd_pcm_stream_lock_irq(struct snd_pcm_substream *substream)
} }
EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq); EXPORT_SYMBOL_GPL(snd_pcm_stream_lock_irq);
/**
* snd_pcm_stream_unlock_irq - Unlock the PCM stream
* @substream: PCM substream
*
* This is a counter-part of snd_pcm_stream_lock_irq().
*/
void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream) void snd_pcm_stream_unlock_irq(struct snd_pcm_substream *substream)
{ {
snd_pcm_stream_unlock(substream); snd_pcm_stream_unlock(substream);
...@@ -124,6 +152,13 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream) ...@@ -124,6 +152,13 @@ unsigned long _snd_pcm_stream_lock_irqsave(struct snd_pcm_substream *substream)
} }
EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave); EXPORT_SYMBOL_GPL(_snd_pcm_stream_lock_irqsave);
/**
* snd_pcm_stream_unlock_irqrestore - Unlock the PCM stream
* @substream: PCM substream
* @flags: irq flags
*
* This is a counter-part of snd_pcm_stream_lock_irqsave().
*/
void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream, void snd_pcm_stream_unlock_irqrestore(struct snd_pcm_substream *substream,
unsigned long flags) unsigned long flags)
{ {
...@@ -3312,6 +3347,15 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = { ...@@ -3312,6 +3347,15 @@ static const struct vm_operations_struct snd_pcm_vm_ops_data_fault = {
/* /*
* mmap the DMA buffer on RAM * mmap the DMA buffer on RAM
*/ */
/**
* snd_pcm_lib_default_mmap - Default PCM data mmap function
* @substream: PCM substream
* @area: VMA
*
* This is the default mmap handler for PCM data. When mmap pcm_ops is NULL,
* this function is invoked implicitly.
*/
int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream, int snd_pcm_lib_default_mmap(struct snd_pcm_substream *substream,
struct vm_area_struct *area) struct vm_area_struct *area)
{ {
...@@ -3343,6 +3387,15 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap); ...@@ -3343,6 +3387,15 @@ EXPORT_SYMBOL_GPL(snd_pcm_lib_default_mmap);
* mmap the DMA buffer on I/O memory area * mmap the DMA buffer on I/O memory area
*/ */
#if SNDRV_PCM_INFO_MMAP_IOMEM #if SNDRV_PCM_INFO_MMAP_IOMEM
/**
* snd_pcm_lib_mmap_iomem - Default PCM data mmap function for I/O mem
* @substream: PCM substream
* @area: VMA
*
* When your hardware uses the iomapped pages as the hardware buffer and
* wants to mmap it, pass this function as mmap pcm_ops. Note that this
* is supposed to work only on limited architectures.
*/
int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream, int snd_pcm_lib_mmap_iomem(struct snd_pcm_substream *substream,
struct vm_area_struct *area) struct vm_area_struct *area)
{ {
......
...@@ -355,8 +355,13 @@ int snd_unregister_device(int type, struct snd_card *card, int dev) ...@@ -355,8 +355,13 @@ int snd_unregister_device(int type, struct snd_card *card, int dev)
EXPORT_SYMBOL(snd_unregister_device); EXPORT_SYMBOL(snd_unregister_device);
/* get the assigned device to the given type and device number; /**
* the caller needs to release it via put_device() after using it * snd_get_device - get the assigned device to the given type and device number
* @type: the device type, SNDRV_DEVICE_TYPE_XXX
* @card:the card instance
* @dev: the device index
*
* The caller needs to release it via put_device() after using it.
*/ */
struct device *snd_get_device(int type, struct snd_card *card, int dev) struct device *snd_get_device(int type, struct snd_card *card, int dev)
{ {
......
...@@ -40,7 +40,12 @@ ...@@ -40,7 +40,12 @@
#include "hda_generic.h" #include "hda_generic.h"
/* initialize hda_gen_spec struct */ /**
* snd_hda_gen_spec_init - initialize hda_gen_spec struct
* @spec: hda_gen_spec object to initialize
*
* Initialize the given hda_gen_spec object.
*/
int snd_hda_gen_spec_init(struct hda_gen_spec *spec) int snd_hda_gen_spec_init(struct hda_gen_spec *spec)
{ {
snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32); snd_array_init(&spec->kctls, sizeof(struct snd_kcontrol_new), 32);
...@@ -51,6 +56,17 @@ int snd_hda_gen_spec_init(struct hda_gen_spec *spec) ...@@ -51,6 +56,17 @@ int snd_hda_gen_spec_init(struct hda_gen_spec *spec)
} }
EXPORT_SYMBOL_GPL(snd_hda_gen_spec_init); EXPORT_SYMBOL_GPL(snd_hda_gen_spec_init);
/**
* snd_hda_gen_add_kctl - Add a new kctl_new struct from the template
* @spec: hda_gen_spec object
* @name: name string to override the template, NULL if unchanged
* @temp: template for the new kctl
*
* Add a new kctl (actually snd_kcontrol_new to be instantiated later)
* element based on the given snd_kcontrol_new template @temp and the
* name string @name to the list in @spec.
* Returns the newly created object or NULL as error.
*/
struct snd_kcontrol_new * struct snd_kcontrol_new *
snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name, snd_hda_gen_add_kctl(struct hda_gen_spec *spec, const char *name,
const struct snd_kcontrol_new *temp) const struct snd_kcontrol_new *temp)
...@@ -259,8 +275,14 @@ static struct nid_path *get_nid_path(struct hda_codec *codec, ...@@ -259,8 +275,14 @@ static struct nid_path *get_nid_path(struct hda_codec *codec,
return NULL; return NULL;
} }
/* get the path between the given NIDs; /**
* passing 0 to either @pin or @dac behaves as a wildcard * snd_hda_get_nid_path - get the path between the given NIDs
* @codec: the HDA codec
* @from_nid: the NID where the path start from
* @to_nid: the NID where the path ends at
*
* Return the found nid_path object or NULL for error.
* Passing 0 to either @from_nid or @to_nid behaves as a wildcard.
*/ */
struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec,
hda_nid_t from_nid, hda_nid_t to_nid) hda_nid_t from_nid, hda_nid_t to_nid)
...@@ -269,8 +291,14 @@ struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec, ...@@ -269,8 +291,14 @@ struct nid_path *snd_hda_get_nid_path(struct hda_codec *codec,
} }
EXPORT_SYMBOL_GPL(snd_hda_get_nid_path); EXPORT_SYMBOL_GPL(snd_hda_get_nid_path);
/* get the index number corresponding to the path instance; /**
* the index starts from 1, for easier checking the invalid value * snd_hda_get_path_idx - get the index number corresponding to the path
* instance
* @codec: the HDA codec
* @path: nid_path object
*
* The returned index starts from 1, i.e. the actual array index with offset 1,
* and zero is handled as an invalid path
*/ */
int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path)
{ {
...@@ -287,7 +315,12 @@ int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path) ...@@ -287,7 +315,12 @@ int snd_hda_get_path_idx(struct hda_codec *codec, struct nid_path *path)
} }
EXPORT_SYMBOL_GPL(snd_hda_get_path_idx); EXPORT_SYMBOL_GPL(snd_hda_get_path_idx);
/* get the path instance corresponding to the given index number */ /**
* snd_hda_get_path_from_idx - get the path instance corresponding to the
* given index number
* @codec: the HDA codec
* @idx: the path index
*/
struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx) struct nid_path *snd_hda_get_path_from_idx(struct hda_codec *codec, int idx)
{ {
struct hda_gen_spec *spec = codec->spec; struct hda_gen_spec *spec = codec->spec;
...@@ -415,7 +448,18 @@ static bool __parse_nid_path(struct hda_codec *codec, ...@@ -415,7 +448,18 @@ static bool __parse_nid_path(struct hda_codec *codec,
return true; return true;
} }
/* parse the widget path from the given nid to the target nid; /**
* snd_hda_parse_nid_path - parse the widget path from the given nid to
* the target nid
* @codec: the HDA codec
* @from_nid: the NID where the path start from
* @to_nid: the NID where the path ends at
* @anchor_nid: the anchor indication
* @path: the path object to store the result
*
* Returns true if a matching path is found.
*
* The parsing behavior depends on parameters:
* when @from_nid is 0, try to find an empty DAC; * when @from_nid is 0, try to find an empty DAC;
* when @anchor_nid is set to a positive value, only paths through the widget * when @anchor_nid is set to a positive value, only paths through the widget
* with the given value are evaluated. * with the given value are evaluated.
...@@ -436,9 +480,15 @@ bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid, ...@@ -436,9 +480,15 @@ bool snd_hda_parse_nid_path(struct hda_codec *codec, hda_nid_t from_nid,
} }
EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path); EXPORT_SYMBOL_GPL(snd_hda_parse_nid_path);
/* /**
* parse the path between the given NIDs and add to the path list. * snd_hda_add_new_path - parse the path between the given NIDs and
* if no valid path is found, return NULL * add to the path list
* @codec: the HDA codec
* @from_nid: the NID where the path start from
* @to_nid: the NID where the path ends at
* @anchor_nid: the anchor indication, see snd_hda_parse_nid_path()
*
* If no valid path is found, returns NULL.
*/ */
struct nid_path * struct nid_path *
snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid, snd_hda_add_new_path(struct hda_codec *codec, hda_nid_t from_nid,
...@@ -724,8 +774,14 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path, ...@@ -724,8 +774,14 @@ static void activate_amp_in(struct hda_codec *codec, struct nid_path *path,
} }
} }
/* activate or deactivate the given path /**
* if @add_aamix is set, enable the input from aa-mix NID as well (if any) * snd_hda_activate_path - activate or deactivate the given path
* @codec: the HDA codec
* @path: the path to activate/deactivate
* @enable: flag to activate or not
* @add_aamix: enable the input from aamix NID
*
* If @add_aamix is set, enable the input from aa-mix NID as well (if any).
*/ */
void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path, void snd_hda_activate_path(struct hda_codec *codec, struct nid_path *path,
bool enable, bool add_aamix) bool enable, bool add_aamix)
...@@ -3883,7 +3939,12 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins, ...@@ -3883,7 +3939,12 @@ static void do_automute(struct hda_codec *codec, int num_pins, hda_nid_t *pins,
} }
} }
/* Toggle outputs muting */ /**
* snd_hda_gen_update_outputs - Toggle outputs muting
* @codec: the HDA codec
*
* Update the mute status of all outputs based on the current jack states.
*/
void snd_hda_gen_update_outputs(struct hda_codec *codec) void snd_hda_gen_update_outputs(struct hda_codec *codec)
{ {
struct hda_gen_spec *spec = codec->spec; struct hda_gen_spec *spec = codec->spec;
...@@ -3944,7 +4005,11 @@ static void call_update_outputs(struct hda_codec *codec) ...@@ -3944,7 +4005,11 @@ static void call_update_outputs(struct hda_codec *codec)
snd_ctl_sync_vmaster(spec->vmaster_mute.sw_kctl, false); snd_ctl_sync_vmaster(spec->vmaster_mute.sw_kctl, false);
} }
/* standard HP-automute helper */ /**
* snd_hda_gen_hp_automute - standard HP-automute helper
* @codec: the HDA codec
* @jack: jack object, NULL for the whole
*/
void snd_hda_gen_hp_automute(struct hda_codec *codec, void snd_hda_gen_hp_automute(struct hda_codec *codec,
struct hda_jack_callback *jack) struct hda_jack_callback *jack)
{ {
...@@ -3965,7 +4030,11 @@ void snd_hda_gen_hp_automute(struct hda_codec *codec, ...@@ -3965,7 +4030,11 @@ void snd_hda_gen_hp_automute(struct hda_codec *codec,
} }
EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute); EXPORT_SYMBOL_GPL(snd_hda_gen_hp_automute);
/* standard line-out-automute helper */ /**
* snd_hda_gen_line_automute - standard line-out-automute helper
* @codec: the HDA codec
* @jack: jack object, NULL for the whole
*/
void snd_hda_gen_line_automute(struct hda_codec *codec, void snd_hda_gen_line_automute(struct hda_codec *codec,
struct hda_jack_callback *jack) struct hda_jack_callback *jack)
{ {
...@@ -3986,7 +4055,11 @@ void snd_hda_gen_line_automute(struct hda_codec *codec, ...@@ -3986,7 +4055,11 @@ void snd_hda_gen_line_automute(struct hda_codec *codec,
} }
EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute); EXPORT_SYMBOL_GPL(snd_hda_gen_line_automute);
/* standard mic auto-switch helper */ /**
* snd_hda_gen_mic_autoswitch - standard mic auto-switch helper
* @codec: the HDA codec
* @jack: jack object, NULL for the whole
*/
void snd_hda_gen_mic_autoswitch(struct hda_codec *codec, void snd_hda_gen_mic_autoswitch(struct hda_codec *codec,
struct hda_jack_callback *jack) struct hda_jack_callback *jack)
{ {
...@@ -4318,7 +4391,13 @@ static int check_auto_mic_availability(struct hda_codec *codec) ...@@ -4318,7 +4391,13 @@ static int check_auto_mic_availability(struct hda_codec *codec)
return 0; return 0;
} }
/* power_filter hook; make inactive widgets into power down */ /**
* snd_hda_gen_path_power_filter - power_filter hook to make inactive widgets
* into power down
* @codec: the HDA codec
* @nid: NID to evalute
* @power_state: target power state
*/
unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec, unsigned int snd_hda_gen_path_power_filter(struct hda_codec *codec,
hda_nid_t nid, hda_nid_t nid,
unsigned int power_state) unsigned int power_state)
...@@ -4354,8 +4433,11 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix) ...@@ -4354,8 +4433,11 @@ static void mute_all_mixer_nid(struct hda_codec *codec, hda_nid_t mix)
} }
} }
/* /**
* Parse the given BIOS configuration and set up the hda_gen_spec * snd_hda_gen_parse_auto_config - Parse the given BIOS configuration and
* set up the hda_gen_spec
* @codec: the HDA codec
* @cfg: Parsed pin configuration
* *
* return 1 if successful, 0 if the proper config is not found, * return 1 if successful, 0 if the proper config is not found,
* or a negative error code * or a negative error code
...@@ -4541,6 +4623,12 @@ static const char * const slave_pfxs[] = { ...@@ -4541,6 +4623,12 @@ static const char * const slave_pfxs[] = {
NULL, NULL,
}; };
/**
* snd_hda_gen_build_controls - Build controls from the parsed results
* @codec: the HDA codec
*
* Pass this to build_controls patch_ops.
*/
int snd_hda_gen_build_controls(struct hda_codec *codec) int snd_hda_gen_build_controls(struct hda_codec *codec)
{ {
struct hda_gen_spec *spec = codec->spec; struct hda_gen_spec *spec = codec->spec;
...@@ -5018,7 +5106,12 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx, ...@@ -5018,7 +5106,12 @@ static void fill_pcm_stream_name(char *str, size_t len, const char *sfx,
strlcat(str, sfx, len); strlcat(str, sfx, len);
} }
/* build PCM streams based on the parsed results */ /**
* snd_hda_gen_build_pcms - build PCM streams based on the parsed results
* @codec: the HDA codec
*
* Pass this to build_pcms patch_ops.
*/
int snd_hda_gen_build_pcms(struct hda_codec *codec) int snd_hda_gen_build_pcms(struct hda_codec *codec)
{ {
struct hda_gen_spec *spec = codec->spec; struct hda_gen_spec *spec = codec->spec;
...@@ -5313,9 +5406,11 @@ static void clear_unsol_on_unused_pins(struct hda_codec *codec) ...@@ -5313,9 +5406,11 @@ static void clear_unsol_on_unused_pins(struct hda_codec *codec)
} }
} }
/* /**
* initialize the generic spec; * snd_hda_gen_init - initialize the generic spec
* this can be put as patch_ops.init function * @codec: the HDA codec
*
* This can be put as patch_ops init function.
*/ */
int snd_hda_gen_init(struct hda_codec *codec) int snd_hda_gen_init(struct hda_codec *codec)
{ {
...@@ -5351,9 +5446,11 @@ int snd_hda_gen_init(struct hda_codec *codec) ...@@ -5351,9 +5446,11 @@ int snd_hda_gen_init(struct hda_codec *codec)
} }
EXPORT_SYMBOL_GPL(snd_hda_gen_init); EXPORT_SYMBOL_GPL(snd_hda_gen_init);
/* /**
* free the generic spec; * snd_hda_gen_free - free the generic spec
* this can be put as patch_ops.free function * @codec: the HDA codec
*
* This can be put as patch_ops free function.
*/ */
void snd_hda_gen_free(struct hda_codec *codec) void snd_hda_gen_free(struct hda_codec *codec)
{ {
...@@ -5365,9 +5462,12 @@ void snd_hda_gen_free(struct hda_codec *codec) ...@@ -5365,9 +5462,12 @@ void snd_hda_gen_free(struct hda_codec *codec)
EXPORT_SYMBOL_GPL(snd_hda_gen_free); EXPORT_SYMBOL_GPL(snd_hda_gen_free);
#ifdef CONFIG_PM #ifdef CONFIG_PM
/* /**
* check the loopback power save state; * snd_hda_gen_check_power_status - check the loopback power save state
* this can be put as patch_ops.check_power_status function * @codec: the HDA codec
* @nid: NID to inspect
*
* This can be put as patch_ops check_power_status function.
*/ */
int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid) int snd_hda_gen_check_power_status(struct hda_codec *codec, hda_nid_t nid)
{ {
...@@ -5393,6 +5493,12 @@ static const struct hda_codec_ops generic_patch_ops = { ...@@ -5393,6 +5493,12 @@ static const struct hda_codec_ops generic_patch_ops = {
#endif #endif
}; };
/**
* snd_hda_parse_generic_codec - Generic codec parser
* @codec: the HDA codec
*
* This should be called from the HDA codec core.
*/
int snd_hda_parse_generic_codec(struct hda_codec *codec) int snd_hda_parse_generic_codec(struct hda_codec *codec)
{ {
struct hda_gen_spec *spec; struct hda_gen_spec *spec;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment