ALSA: usb-audio: Export USB SND APIs for modules
Some vendor modules will utilize useful parsing and endpoint management APIs to start audio playback/capture. Reviewed-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com> Tested-by: Puma Hsu <pumahsu@google.com> Tested-by: Daehwan Jung <dh10.jung@samsung.com> Signed-off-by: Wesley Cheng <quic_wcheng@quicinc.com> Acked-by: Mark Brown <broonie@kernel.org> Link: https://lore.kernel.org/r/20250409194804.3773260-9-quic_wcheng@quicinc.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>pull/1259/head
parent
67890d5794
commit
5a49a6ba22
|
|
@ -1030,6 +1030,7 @@ int snd_usb_lock_shutdown(struct snd_usb_audio *chip)
|
|||
wake_up(&chip->shutdown_wait);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_usb_lock_shutdown);
|
||||
|
||||
/* autosuspend and unlock the shutdown */
|
||||
void snd_usb_unlock_shutdown(struct snd_usb_audio *chip)
|
||||
|
|
@ -1038,6 +1039,7 @@ void snd_usb_unlock_shutdown(struct snd_usb_audio *chip)
|
|||
if (atomic_dec_and_test(&chip->usage_count))
|
||||
wake_up(&chip->shutdown_wait);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_usb_unlock_shutdown);
|
||||
|
||||
int snd_usb_autoresume(struct snd_usb_audio *chip)
|
||||
{
|
||||
|
|
@ -1060,6 +1062,7 @@ int snd_usb_autoresume(struct snd_usb_audio *chip)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_usb_autoresume);
|
||||
|
||||
void snd_usb_autosuspend(struct snd_usb_audio *chip)
|
||||
{
|
||||
|
|
@ -1073,6 +1076,7 @@ void snd_usb_autosuspend(struct snd_usb_audio *chip)
|
|||
for (i = 0; i < chip->num_interfaces; i++)
|
||||
usb_autopm_put_interface(chip->intf[i]);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_usb_autosuspend);
|
||||
|
||||
static int usb_audio_suspend(struct usb_interface *intf, pm_message_t message)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -1524,6 +1524,7 @@ unlock:
|
|||
mutex_unlock(&chip->mutex);
|
||||
return err;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_usb_endpoint_prepare);
|
||||
|
||||
/* get the current rate set to the given clock by any endpoint */
|
||||
int snd_usb_endpoint_get_clock_rate(struct snd_usb_audio *chip, int clock)
|
||||
|
|
|
|||
|
|
@ -62,6 +62,7 @@ void *snd_usb_find_csint_desc(void *buffer, int buflen, void *after, u8 dsubtype
|
|||
}
|
||||
return NULL;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_usb_find_csint_desc);
|
||||
|
||||
/*
|
||||
* Wrapper for usb_control_msg().
|
||||
|
|
|
|||
|
|
@ -148,6 +148,16 @@ find_format(struct list_head *fmt_list_head, snd_pcm_format_t format,
|
|||
return found;
|
||||
}
|
||||
|
||||
const struct audioformat *
|
||||
snd_usb_find_format(struct list_head *fmt_list_head, snd_pcm_format_t format,
|
||||
unsigned int rate, unsigned int channels, bool strict_match,
|
||||
struct snd_usb_substream *subs)
|
||||
{
|
||||
return find_format(fmt_list_head, format, rate, channels, strict_match,
|
||||
subs);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_usb_find_format);
|
||||
|
||||
static const struct audioformat *
|
||||
find_substream_format(struct snd_usb_substream *subs,
|
||||
const struct snd_pcm_hw_params *params)
|
||||
|
|
@ -157,6 +167,14 @@ find_substream_format(struct snd_usb_substream *subs,
|
|||
true, subs);
|
||||
}
|
||||
|
||||
const struct audioformat *
|
||||
snd_usb_find_substream_format(struct snd_usb_substream *subs,
|
||||
const struct snd_pcm_hw_params *params)
|
||||
{
|
||||
return find_substream_format(subs, params);
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_usb_find_substream_format);
|
||||
|
||||
bool snd_usb_pcm_has_fixed_rate(struct snd_usb_substream *subs)
|
||||
{
|
||||
const struct audioformat *fp;
|
||||
|
|
@ -461,20 +479,9 @@ static void close_endpoints(struct snd_usb_audio *chip,
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* hw_params callback
|
||||
*
|
||||
* allocate a buffer and set the given audio format.
|
||||
*
|
||||
* so far we use a physically linear buffer although packetize transfer
|
||||
* doesn't need a continuous area.
|
||||
* if sg buffer is supported on the later version of alsa, we'll follow
|
||||
* that.
|
||||
*/
|
||||
static int snd_usb_hw_params(struct snd_pcm_substream *substream,
|
||||
int snd_usb_hw_params(struct snd_usb_substream *subs,
|
||||
struct snd_pcm_hw_params *hw_params)
|
||||
{
|
||||
struct snd_usb_substream *subs = substream->runtime->private_data;
|
||||
struct snd_usb_audio *chip = subs->stream->chip;
|
||||
const struct audioformat *fmt;
|
||||
const struct audioformat *sync_fmt;
|
||||
|
|
@ -499,7 +506,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
|
|||
if (fmt->implicit_fb) {
|
||||
sync_fmt = snd_usb_find_implicit_fb_sync_format(chip, fmt,
|
||||
hw_params,
|
||||
!substream->stream,
|
||||
!subs->direction,
|
||||
&sync_fixed_rate);
|
||||
if (!sync_fmt) {
|
||||
usb_audio_dbg(chip,
|
||||
|
|
@ -579,15 +586,28 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
|
|||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_usb_hw_params);
|
||||
|
||||
/*
|
||||
* hw_free callback
|
||||
* hw_params callback
|
||||
*
|
||||
* reset the audio format and release the buffer
|
||||
* allocate a buffer and set the given audio format.
|
||||
*
|
||||
* so far we use a physically linear buffer although packetize transfer
|
||||
* doesn't need a continuous area.
|
||||
* if sg buffer is supported on the later version of alsa, we'll follow
|
||||
* that.
|
||||
*/
|
||||
static int snd_usb_hw_free(struct snd_pcm_substream *substream)
|
||||
static int snd_usb_pcm_hw_params(struct snd_pcm_substream *substream,
|
||||
struct snd_pcm_hw_params *hw_params)
|
||||
{
|
||||
struct snd_usb_substream *subs = substream->runtime->private_data;
|
||||
|
||||
return snd_usb_hw_params(subs, hw_params);
|
||||
}
|
||||
|
||||
int snd_usb_hw_free(struct snd_usb_substream *subs)
|
||||
{
|
||||
struct snd_usb_audio *chip = subs->stream->chip;
|
||||
|
||||
snd_media_stop_pipeline(subs);
|
||||
|
|
@ -603,6 +623,19 @@ static int snd_usb_hw_free(struct snd_pcm_substream *substream)
|
|||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(snd_usb_hw_free);
|
||||
|
||||
/*
|
||||
* hw_free callback
|
||||
*
|
||||
* reset the audio format and release the buffer
|
||||
*/
|
||||
static int snd_usb_pcm_hw_free(struct snd_pcm_substream *substream)
|
||||
{
|
||||
struct snd_usb_substream *subs = substream->runtime->private_data;
|
||||
|
||||
return snd_usb_hw_free(subs);
|
||||
}
|
||||
|
||||
/* free-wheeling mode? (e.g. dmix) */
|
||||
static int in_free_wheeling_mode(struct snd_pcm_runtime *runtime)
|
||||
|
|
@ -1746,8 +1779,8 @@ static int snd_usb_substream_capture_trigger(struct snd_pcm_substream *substream
|
|||
static const struct snd_pcm_ops snd_usb_playback_ops = {
|
||||
.open = snd_usb_pcm_open,
|
||||
.close = snd_usb_pcm_close,
|
||||
.hw_params = snd_usb_hw_params,
|
||||
.hw_free = snd_usb_hw_free,
|
||||
.hw_params = snd_usb_pcm_hw_params,
|
||||
.hw_free = snd_usb_pcm_hw_free,
|
||||
.prepare = snd_usb_pcm_prepare,
|
||||
.trigger = snd_usb_substream_playback_trigger,
|
||||
.sync_stop = snd_usb_pcm_sync_stop,
|
||||
|
|
@ -1758,8 +1791,8 @@ static const struct snd_pcm_ops snd_usb_playback_ops = {
|
|||
static const struct snd_pcm_ops snd_usb_capture_ops = {
|
||||
.open = snd_usb_pcm_open,
|
||||
.close = snd_usb_pcm_close,
|
||||
.hw_params = snd_usb_hw_params,
|
||||
.hw_free = snd_usb_hw_free,
|
||||
.hw_params = snd_usb_pcm_hw_params,
|
||||
.hw_free = snd_usb_pcm_hw_free,
|
||||
.prepare = snd_usb_pcm_prepare,
|
||||
.trigger = snd_usb_substream_capture_trigger,
|
||||
.sync_stop = snd_usb_pcm_sync_stop,
|
||||
|
|
|
|||
|
|
@ -15,4 +15,15 @@ void snd_usb_preallocate_buffer(struct snd_usb_substream *subs);
|
|||
int snd_usb_audioformat_set_sync_ep(struct snd_usb_audio *chip,
|
||||
struct audioformat *fmt);
|
||||
|
||||
const struct audioformat *
|
||||
snd_usb_find_format(struct list_head *fmt_list_head, snd_pcm_format_t format,
|
||||
unsigned int rate, unsigned int channels, bool strict_match,
|
||||
struct snd_usb_substream *subs);
|
||||
const struct audioformat *
|
||||
snd_usb_find_substream_format(struct snd_usb_substream *subs,
|
||||
const struct snd_pcm_hw_params *params);
|
||||
|
||||
int snd_usb_hw_params(struct snd_usb_substream *subs,
|
||||
struct snd_pcm_hw_params *hw_params);
|
||||
int snd_usb_hw_free(struct snd_usb_substream *subs);
|
||||
#endif /* __USBAUDIO_PCM_H */
|
||||
|
|
|
|||
Loading…
Reference in New Issue