Loading Documentation/DocBook/alsa-driver-api.tmpl +19 −2 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ !Esound/core/pcm.c !Esound/core/pcm_lib.c !Esound/core/pcm_native.c !include/sound/pcm.h !Iinclude/sound/pcm.h </sect1> <sect1><title>PCM Format Helpers</title> !Esound/core/pcm_misc.c Loading Loading @@ -104,13 +104,30 @@ !Iinclude/sound/compress_driver.h </sect1> </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> <sect1><title>Hardware-Dependent Devices API</title> !Esound/core/hwdep.c </sect1> <sect1><title>Jack Abstraction Layer API</title> !Esound/core/jack.c !Iinclude/sound/jack.h !Esound/core/jack.c !Esound/soc/soc-jack.c </sect1> <sect1><title>ISA DMA Helpers</title> !Esound/core/isadma.c Loading include/sound/pcm.h +219 −31 Original line number Diff line number Diff line Loading @@ -533,6 +533,12 @@ snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size) * 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) { return substream->group != &substream->self_group; Loading @@ -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_unlock_irq(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) \ do { \ typecheck(unsigned long, flags); \ Loading @@ -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, 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) \ 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) { return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING || Loading @@ -561,45 +593,81 @@ static inline int snd_pcm_running(struct snd_pcm_substream *substream) 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) { 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) { 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) { 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) { 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) { 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) { struct snd_pcm_runtime *runtime = substream->runtime; 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) { struct snd_pcm_runtime *runtime = substream->runtime; 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) { Loading @@ -611,8 +679,11 @@ static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *r 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) { Loading @@ -622,11 +693,19 @@ static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *ru 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) { 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) { return runtime->buffer_size - snd_pcm_capture_avail(runtime); Loading Loading @@ -706,6 +785,20 @@ static inline int snd_pcm_capture_empty(struct snd_pcm_substream *substream) 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, struct snd_pcm_substream *master) { Loading Loading @@ -748,18 +841,59 @@ static inline const struct snd_interval *hw_param_interval_c(const struct snd_pc return ¶ms->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]; } #define params_channels(p) \ (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_CHANNELS)->min) #define params_rate(p) \ (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_RATE)->min) #define params_period_size(p) \ (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min) #define params_periods(p) \ (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) \ (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min) /** * params_channels - Get the number of channels from the hw params * @p: hw params */ static inline unsigned int params_channels(const struct snd_pcm_hw_params *p) { return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_CHANNELS)->min; } /** * params_channels - Get the sample rate from the hw params * @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); void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c); Loading Loading @@ -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 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, struct snd_dma_buffer *bufp) { Loading @@ -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_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, struct timespec *tv) { Loading Loading @@ -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); struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, unsigned long offset); #if 0 /* for kernel-doc */ /** * snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer * @substream: the substream to allocate the buffer to Loading @@ -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 * code. */ static int snd_pcm_lib_alloc_vmalloc_buffer (struct snd_pcm_substream *substream, size_t size); static inline int snd_pcm_lib_alloc_vmalloc_buffer (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 * @substream: the substream to allocate the buffer to Loading @@ -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 * code. */ static int snd_pcm_lib_alloc_vmalloc_32_buffer (struct snd_pcm_substream *substream, size_t size); #endif #define snd_pcm_lib_alloc_vmalloc_buffer(subs, size) \ _snd_pcm_lib_alloc_vmalloc_buffer \ (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) static inline int snd_pcm_lib_alloc_vmalloc_32_buffer (struct snd_pcm_substream *substream, size_t size) { return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); } #define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p) Loading @@ -996,18 +1144,35 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, #define snd_pcm_sgbuf_ops_page NULL #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 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); } /** * snd_pcm_sgbuf_get_ptr - Get the virtual address at the corresponding offset * @substream: PCM substream * @ofs: byte offset */ static inline void * 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); } /** * 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 snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, unsigned int ofs, unsigned int size) Loading @@ -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); } /* 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) { struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; 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) { struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; Loading @@ -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 /** * 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) { *max = dma < 4 ? 64 * 1024 : 128 * 1024; Loading Loading @@ -1093,7 +1274,11 @@ struct snd_pcm_chmap { 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 * snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx) { Loading @@ -1120,7 +1305,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, unsigned long private_value, 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) { return 1ULL << (__force int) pcm_format; Loading sound/core/control.c +49 −15 Original line number Diff line number Diff line Loading @@ -141,6 +141,16 @@ static int snd_ctl_release(struct inode *inode, struct file *file) 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, struct snd_ctl_elem_id *id) { Loading Loading @@ -179,7 +189,6 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, } read_unlock(&card->ctl_files_rwlock); } EXPORT_SYMBOL(snd_ctl_notify); /** Loading Loading @@ -261,7 +270,6 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, kctl.private_data = private_data; return snd_ctl_new(&kctl, access); } EXPORT_SYMBOL(snd_ctl_new1); /** Loading @@ -280,7 +288,6 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol) kfree(kcontrol); } } EXPORT_SYMBOL(snd_ctl_free_one); static bool snd_ctl_remove_numid_conflict(struct snd_card *card, Loading Loading @@ -376,7 +383,6 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) snd_ctl_free_one(kcontrol); return err; } EXPORT_SYMBOL(snd_ctl_add); /** Loading Loading @@ -471,7 +477,6 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) snd_ctl_free_one(kcontrol); return 0; } EXPORT_SYMBOL(snd_ctl_remove); /** Loading Loading @@ -499,7 +504,6 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) up_write(&card->controls_rwsem); return ret; } EXPORT_SYMBOL(snd_ctl_remove_id); /** Loading Loading @@ -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); return 0; } EXPORT_SYMBOL(snd_ctl_rename_id); /** Loading Loading @@ -645,7 +648,6 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi } return NULL; } EXPORT_SYMBOL(snd_ctl_find_numid); /** Loading Loading @@ -687,7 +689,6 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, } return NULL; } EXPORT_SYMBOL(snd_ctl_find_id); static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, Loading Loading @@ -1526,19 +1527,28 @@ static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head * 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) { return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); } EXPORT_SYMBOL(snd_ctl_register_ioctl); #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) { return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); } EXPORT_SYMBOL(snd_ctl_register_ioctl_compat); #endif Loading Loading @@ -1566,19 +1576,26 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, 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) { return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); } EXPORT_SYMBOL(snd_ctl_unregister_ioctl); #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) { return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); } EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat); #endif Loading Loading @@ -1702,6 +1719,16 @@ int snd_ctl_create(struct snd_card *card) /* * 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, struct snd_ctl_elem_info *uinfo) { Loading @@ -1711,9 +1738,17 @@ int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.max = 1; return 0; } 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, struct snd_ctl_elem_info *uinfo) { Loading @@ -1723,7 +1758,6 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.max = 1; return 0; } EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); /** Loading sound/core/init.c +22 −11 Original line number Diff line number Diff line Loading @@ -438,17 +438,6 @@ int snd_card_disconnect(struct snd_card *card) 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) { #if IS_ENABLED(CONFIG_SND_MIXER_OSS) Loading @@ -469,6 +458,15 @@ static int snd_card_do_free(struct snd_card *card) 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 ret = snd_card_disconnect(card); Loading @@ -479,6 +477,19 @@ int snd_card_free_when_closed(struct snd_card *card) } 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) { struct completion released; Loading sound/core/pcm.c +13 −2 Original line number Diff line number Diff line Loading @@ -218,6 +218,10 @@ static char *snd_pcm_format_names[] = { 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) { if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names)) Loading Loading @@ -707,7 +711,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) } return 0; } EXPORT_SYMBOL(snd_pcm_new_stream); static int _snd_pcm_new(struct snd_card *card, const char *id, int device, Loading Loading @@ -1155,6 +1158,15 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) 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) { struct snd_pcm *pcm; Loading @@ -1177,7 +1189,6 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) mutex_unlock(®ister_mutex); return 0; } EXPORT_SYMBOL(snd_pcm_notify); #ifdef CONFIG_PROC_FS Loading Loading
Documentation/DocBook/alsa-driver-api.tmpl +19 −2 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ !Esound/core/pcm.c !Esound/core/pcm_lib.c !Esound/core/pcm_native.c !include/sound/pcm.h !Iinclude/sound/pcm.h </sect1> <sect1><title>PCM Format Helpers</title> !Esound/core/pcm_misc.c Loading Loading @@ -104,13 +104,30 @@ !Iinclude/sound/compress_driver.h </sect1> </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> <sect1><title>Hardware-Dependent Devices API</title> !Esound/core/hwdep.c </sect1> <sect1><title>Jack Abstraction Layer API</title> !Esound/core/jack.c !Iinclude/sound/jack.h !Esound/core/jack.c !Esound/soc/soc-jack.c </sect1> <sect1><title>ISA DMA Helpers</title> !Esound/core/isadma.c Loading
include/sound/pcm.h +219 −31 Original line number Diff line number Diff line Loading @@ -533,6 +533,12 @@ snd_pcm_debug_name(struct snd_pcm_substream *substream, char *buf, size_t size) * 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) { return substream->group != &substream->self_group; Loading @@ -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_unlock_irq(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) \ do { \ typecheck(unsigned long, flags); \ Loading @@ -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, 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) \ 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) { return (substream->runtime->status->state == SNDRV_PCM_STATE_RUNNING || Loading @@ -561,45 +593,81 @@ static inline int snd_pcm_running(struct snd_pcm_substream *substream) 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) { 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) { 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) { 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) { 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) { 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) { struct snd_pcm_runtime *runtime = substream->runtime; 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) { struct snd_pcm_runtime *runtime = substream->runtime; 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) { Loading @@ -611,8 +679,11 @@ static inline snd_pcm_uframes_t snd_pcm_playback_avail(struct snd_pcm_runtime *r 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) { Loading @@ -622,11 +693,19 @@ static inline snd_pcm_uframes_t snd_pcm_capture_avail(struct snd_pcm_runtime *ru 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) { 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) { return runtime->buffer_size - snd_pcm_capture_avail(runtime); Loading Loading @@ -706,6 +785,20 @@ static inline int snd_pcm_capture_empty(struct snd_pcm_substream *substream) 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, struct snd_pcm_substream *master) { Loading Loading @@ -748,18 +841,59 @@ static inline const struct snd_interval *hw_param_interval_c(const struct snd_pc return ¶ms->intervals[var - SNDRV_PCM_HW_PARAM_FIRST_INTERVAL]; } #define params_channels(p) \ (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_CHANNELS)->min) #define params_rate(p) \ (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_RATE)->min) #define params_period_size(p) \ (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_PERIOD_SIZE)->min) #define params_periods(p) \ (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) \ (hw_param_interval_c((p), SNDRV_PCM_HW_PARAM_BUFFER_BYTES)->min) /** * params_channels - Get the number of channels from the hw params * @p: hw params */ static inline unsigned int params_channels(const struct snd_pcm_hw_params *p) { return hw_param_interval_c(p, SNDRV_PCM_HW_PARAM_CHANNELS)->min; } /** * params_channels - Get the sample rate from the hw params * @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); void snd_interval_mul(const struct snd_interval *a, const struct snd_interval *b, struct snd_interval *c); Loading Loading @@ -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 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, struct snd_dma_buffer *bufp) { Loading @@ -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_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, struct timespec *tv) { Loading Loading @@ -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); struct page *snd_pcm_lib_get_vmalloc_page(struct snd_pcm_substream *substream, unsigned long offset); #if 0 /* for kernel-doc */ /** * snd_pcm_lib_alloc_vmalloc_buffer - allocate virtual DMA buffer * @substream: the substream to allocate the buffer to Loading @@ -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 * code. */ static int snd_pcm_lib_alloc_vmalloc_buffer (struct snd_pcm_substream *substream, size_t size); static inline int snd_pcm_lib_alloc_vmalloc_buffer (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 * @substream: the substream to allocate the buffer to Loading @@ -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 * code. */ static int snd_pcm_lib_alloc_vmalloc_32_buffer (struct snd_pcm_substream *substream, size_t size); #endif #define snd_pcm_lib_alloc_vmalloc_buffer(subs, size) \ _snd_pcm_lib_alloc_vmalloc_buffer \ (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) static inline int snd_pcm_lib_alloc_vmalloc_32_buffer (struct snd_pcm_substream *substream, size_t size) { return _snd_pcm_lib_alloc_vmalloc_buffer(substream, size, GFP_KERNEL | GFP_DMA32 | __GFP_ZERO); } #define snd_pcm_get_dma_buf(substream) ((substream)->runtime->dma_buffer_p) Loading @@ -996,18 +1144,35 @@ struct page *snd_pcm_sgbuf_ops_page(struct snd_pcm_substream *substream, #define snd_pcm_sgbuf_ops_page NULL #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 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); } /** * snd_pcm_sgbuf_get_ptr - Get the virtual address at the corresponding offset * @substream: PCM substream * @ofs: byte offset */ static inline void * 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); } /** * 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 snd_pcm_sgbuf_get_chunk_size(struct snd_pcm_substream *substream, unsigned int ofs, unsigned int size) Loading @@ -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); } /* 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) { struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; 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) { struct snd_pcm_substream *substream = (struct snd_pcm_substream *)area->vm_private_data; Loading @@ -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 /** * 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) { *max = dma < 4 ? 64 * 1024 : 128 * 1024; Loading Loading @@ -1093,7 +1274,11 @@ struct snd_pcm_chmap { 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 * snd_pcm_chmap_substream(struct snd_pcm_chmap *info, unsigned int idx) { Loading @@ -1120,7 +1305,10 @@ int snd_pcm_add_chmap_ctls(struct snd_pcm *pcm, int stream, unsigned long private_value, 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) { return 1ULL << (__force int) pcm_format; Loading
sound/core/control.c +49 −15 Original line number Diff line number Diff line Loading @@ -141,6 +141,16 @@ static int snd_ctl_release(struct inode *inode, struct file *file) 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, struct snd_ctl_elem_id *id) { Loading Loading @@ -179,7 +189,6 @@ void snd_ctl_notify(struct snd_card *card, unsigned int mask, } read_unlock(&card->ctl_files_rwlock); } EXPORT_SYMBOL(snd_ctl_notify); /** Loading Loading @@ -261,7 +270,6 @@ struct snd_kcontrol *snd_ctl_new1(const struct snd_kcontrol_new *ncontrol, kctl.private_data = private_data; return snd_ctl_new(&kctl, access); } EXPORT_SYMBOL(snd_ctl_new1); /** Loading @@ -280,7 +288,6 @@ void snd_ctl_free_one(struct snd_kcontrol *kcontrol) kfree(kcontrol); } } EXPORT_SYMBOL(snd_ctl_free_one); static bool snd_ctl_remove_numid_conflict(struct snd_card *card, Loading Loading @@ -376,7 +383,6 @@ int snd_ctl_add(struct snd_card *card, struct snd_kcontrol *kcontrol) snd_ctl_free_one(kcontrol); return err; } EXPORT_SYMBOL(snd_ctl_add); /** Loading Loading @@ -471,7 +477,6 @@ int snd_ctl_remove(struct snd_card *card, struct snd_kcontrol *kcontrol) snd_ctl_free_one(kcontrol); return 0; } EXPORT_SYMBOL(snd_ctl_remove); /** Loading Loading @@ -499,7 +504,6 @@ int snd_ctl_remove_id(struct snd_card *card, struct snd_ctl_elem_id *id) up_write(&card->controls_rwsem); return ret; } EXPORT_SYMBOL(snd_ctl_remove_id); /** Loading Loading @@ -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); return 0; } EXPORT_SYMBOL(snd_ctl_rename_id); /** Loading Loading @@ -645,7 +648,6 @@ struct snd_kcontrol *snd_ctl_find_numid(struct snd_card *card, unsigned int numi } return NULL; } EXPORT_SYMBOL(snd_ctl_find_numid); /** Loading Loading @@ -687,7 +689,6 @@ struct snd_kcontrol *snd_ctl_find_id(struct snd_card *card, } return NULL; } EXPORT_SYMBOL(snd_ctl_find_id); static int snd_ctl_card_info(struct snd_card *card, struct snd_ctl_file * ctl, Loading Loading @@ -1526,19 +1527,28 @@ static int _snd_ctl_register_ioctl(snd_kctl_ioctl_func_t fcn, struct list_head * 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) { return _snd_ctl_register_ioctl(fcn, &snd_control_ioctls); } EXPORT_SYMBOL(snd_ctl_register_ioctl); #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) { return _snd_ctl_register_ioctl(fcn, &snd_control_compat_ioctls); } EXPORT_SYMBOL(snd_ctl_register_ioctl_compat); #endif Loading Loading @@ -1566,19 +1576,26 @@ static int _snd_ctl_unregister_ioctl(snd_kctl_ioctl_func_t fcn, 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) { return _snd_ctl_unregister_ioctl(fcn, &snd_control_ioctls); } EXPORT_SYMBOL(snd_ctl_unregister_ioctl); #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) { return _snd_ctl_unregister_ioctl(fcn, &snd_control_compat_ioctls); } EXPORT_SYMBOL(snd_ctl_unregister_ioctl_compat); #endif Loading Loading @@ -1702,6 +1719,16 @@ int snd_ctl_create(struct snd_card *card) /* * 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, struct snd_ctl_elem_info *uinfo) { Loading @@ -1711,9 +1738,17 @@ int snd_ctl_boolean_mono_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.max = 1; return 0; } 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, struct snd_ctl_elem_info *uinfo) { Loading @@ -1723,7 +1758,6 @@ int snd_ctl_boolean_stereo_info(struct snd_kcontrol *kcontrol, uinfo->value.integer.max = 1; return 0; } EXPORT_SYMBOL(snd_ctl_boolean_stereo_info); /** Loading
sound/core/init.c +22 −11 Original line number Diff line number Diff line Loading @@ -438,17 +438,6 @@ int snd_card_disconnect(struct snd_card *card) 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) { #if IS_ENABLED(CONFIG_SND_MIXER_OSS) Loading @@ -469,6 +458,15 @@ static int snd_card_do_free(struct snd_card *card) 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 ret = snd_card_disconnect(card); Loading @@ -479,6 +477,19 @@ int snd_card_free_when_closed(struct snd_card *card) } 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) { struct completion released; Loading
sound/core/pcm.c +13 −2 Original line number Diff line number Diff line Loading @@ -218,6 +218,10 @@ static char *snd_pcm_format_names[] = { 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) { if ((__force unsigned int)format >= ARRAY_SIZE(snd_pcm_format_names)) Loading Loading @@ -707,7 +711,6 @@ int snd_pcm_new_stream(struct snd_pcm *pcm, int stream, int substream_count) } return 0; } EXPORT_SYMBOL(snd_pcm_new_stream); static int _snd_pcm_new(struct snd_card *card, const char *id, int device, Loading Loading @@ -1155,6 +1158,15 @@ static int snd_pcm_dev_disconnect(struct snd_device *device) 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) { struct snd_pcm *pcm; Loading @@ -1177,7 +1189,6 @@ int snd_pcm_notify(struct snd_pcm_notify *notify, int nfree) mutex_unlock(®ister_mutex); return 0; } EXPORT_SYMBOL(snd_pcm_notify); #ifdef CONFIG_PROC_FS Loading