Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 35ec7aa2 authored by Dylan Reid's avatar Dylan Reid Committed by Takashi Iwai
Browse files

ALSA: usb-audio: Don't require hw_params in endpoint.



Change the interface to configure an endpoint so that it doesn't require
a hw_params struct.  This will allow it to be called from prepare
instead of hw_params, configuring it after system resume.

Signed-off-by: default avatarDylan Reid <dgreid@chromium.org>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent 715a1705
Loading
Loading
Loading
Loading
+18 −13
Original line number Original line Diff line number Diff line
@@ -567,20 +567,19 @@ static void release_urbs(struct snd_usb_endpoint *ep, int force)
 * configure a data endpoint
 * configure a data endpoint
 */
 */
static int data_ep_set_params(struct snd_usb_endpoint *ep,
static int data_ep_set_params(struct snd_usb_endpoint *ep,
			      struct snd_pcm_hw_params *hw_params,
			      snd_pcm_format_t pcm_format,
			      unsigned int channels,
			      unsigned int period_bytes,
			      struct audioformat *fmt,
			      struct audioformat *fmt,
			      struct snd_usb_endpoint *sync_ep)
			      struct snd_usb_endpoint *sync_ep)
{
{
	unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms;
	unsigned int maxsize, i, urb_packs, total_packs, packs_per_ms;
	int period_bytes = params_period_bytes(hw_params);
	int format = params_format(hw_params);
	int is_playback = usb_pipeout(ep->pipe);
	int is_playback = usb_pipeout(ep->pipe);
	int frame_bits = snd_pcm_format_physical_width(params_format(hw_params)) *
	int frame_bits = snd_pcm_format_physical_width(pcm_format) * channels;
							params_channels(hw_params);


	ep->datainterval = fmt->datainterval;
	ep->datainterval = fmt->datainterval;
	ep->stride = frame_bits >> 3;
	ep->stride = frame_bits >> 3;
	ep->silence_value = format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0;
	ep->silence_value = pcm_format == SNDRV_PCM_FORMAT_U8 ? 0x80 : 0;


	/* calculate max. frequency */
	/* calculate max. frequency */
	if (ep->maxpacksize) {
	if (ep->maxpacksize) {
@@ -693,7 +692,6 @@ static int data_ep_set_params(struct snd_usb_endpoint *ep,
 * configure a sync endpoint
 * configure a sync endpoint
 */
 */
static int sync_ep_set_params(struct snd_usb_endpoint *ep,
static int sync_ep_set_params(struct snd_usb_endpoint *ep,
			      struct snd_pcm_hw_params *hw_params,
			      struct audioformat *fmt)
			      struct audioformat *fmt)
{
{
	int i;
	int i;
@@ -736,7 +734,10 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep,
 * snd_usb_endpoint_set_params: configure an snd_usb_endpoint
 * snd_usb_endpoint_set_params: configure an snd_usb_endpoint
 *
 *
 * @ep: the snd_usb_endpoint to configure
 * @ep: the snd_usb_endpoint to configure
 * @hw_params: the hardware parameters
 * @pcm_format: the audio fomat.
 * @channels: the number of audio channels.
 * @period_bytes: the number of bytes in one alsa period.
 * @rate: the frame rate.
 * @fmt: the USB audio format information
 * @fmt: the USB audio format information
 * @sync_ep: the sync endpoint to use, if any
 * @sync_ep: the sync endpoint to use, if any
 *
 *
@@ -745,7 +746,10 @@ static int sync_ep_set_params(struct snd_usb_endpoint *ep,
 * An endpoint that is already running can not be reconfigured.
 * An endpoint that is already running can not be reconfigured.
 */
 */
int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
				struct snd_pcm_hw_params *hw_params,
				snd_pcm_format_t pcm_format,
				unsigned int channels,
				unsigned int period_bytes,
				unsigned int rate,
				struct audioformat *fmt,
				struct audioformat *fmt,
				struct snd_usb_endpoint *sync_ep)
				struct snd_usb_endpoint *sync_ep)
{
{
@@ -765,9 +769,9 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
	ep->fill_max = !!(fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX);
	ep->fill_max = !!(fmt->attributes & UAC_EP_CS_ATTR_FILL_MAX);


	if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_FULL)
	if (snd_usb_get_speed(ep->chip->dev) == USB_SPEED_FULL)
		ep->freqn = get_usb_full_speed_rate(params_rate(hw_params));
		ep->freqn = get_usb_full_speed_rate(rate);
	else
	else
		ep->freqn = get_usb_high_speed_rate(params_rate(hw_params));
		ep->freqn = get_usb_high_speed_rate(rate);


	/* calculate the frequency in 16.16 format */
	/* calculate the frequency in 16.16 format */
	ep->freqm = ep->freqn;
	ep->freqm = ep->freqn;
@@ -777,10 +781,11 @@ int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,


	switch (ep->type) {
	switch (ep->type) {
	case  SND_USB_ENDPOINT_TYPE_DATA:
	case  SND_USB_ENDPOINT_TYPE_DATA:
		err = data_ep_set_params(ep, hw_params, fmt, sync_ep);
		err = data_ep_set_params(ep, pcm_format, channels,
					 period_bytes, fmt, sync_ep);
		break;
		break;
	case  SND_USB_ENDPOINT_TYPE_SYNC:
	case  SND_USB_ENDPOINT_TYPE_SYNC:
		err = sync_ep_set_params(ep, hw_params, fmt);
		err = sync_ep_set_params(ep, fmt);
		break;
		break;
	default:
	default:
		err = -EINVAL;
		err = -EINVAL;
+4 −1
Original line number Original line Diff line number Diff line
@@ -9,7 +9,10 @@ struct snd_usb_endpoint *snd_usb_add_endpoint(struct snd_usb_audio *chip,
					      int ep_num, int direction, int type);
					      int ep_num, int direction, int type);


int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
int snd_usb_endpoint_set_params(struct snd_usb_endpoint *ep,
				struct snd_pcm_hw_params *hw_params,
				snd_pcm_format_t pcm_format,
				unsigned int channels,
				unsigned int period_bytes,
				unsigned int rate,
				struct audioformat *fmt,
				struct audioformat *fmt,
				struct snd_usb_endpoint *sync_ep);
				struct snd_usb_endpoint *sync_ep);


+13 −3
Original line number Original line Diff line number Diff line
@@ -491,14 +491,24 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
		mutex_lock(&subs->stream->chip->shutdown_mutex);
		mutex_lock(&subs->stream->chip->shutdown_mutex);
		/* format changed */
		/* format changed */
		stop_endpoints(subs, 0, 0, 0);
		stop_endpoints(subs, 0, 0, 0);
		ret = snd_usb_endpoint_set_params(subs->data_endpoint, hw_params, fmt,
		ret = snd_usb_endpoint_set_params(subs->data_endpoint,
						  format,
						  channels,
						  subs->period_bytes,
						  rate,
						  fmt,
						  subs->sync_endpoint);
						  subs->sync_endpoint);
		if (ret < 0)
		if (ret < 0)
			goto unlock;
			goto unlock;


		if (subs->sync_endpoint)
		if (subs->sync_endpoint)
			ret = snd_usb_endpoint_set_params(subs->sync_endpoint,
			ret = snd_usb_endpoint_set_params(subs->data_endpoint,
							  hw_params, fmt, NULL);
							  format,
							  channels,
							  subs->period_bytes,
							  rate,
							  fmt,
							  NULL);
unlock:
unlock:
		mutex_unlock(&subs->stream->chip->shutdown_mutex);
		mutex_unlock(&subs->stream->chip->shutdown_mutex);
	}
	}