mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-25 03:50:24 +09:00
Revert "ALSA: usb-audio: Split endpoint setups for hw_params and prepare (take#2)"
This reverts commit56e28371fawhich is commit2be79d5864upstream. It breaks the Android kernel abi and can be brought back in the future in an abi-safe way if it is really needed. Bug: 161946584 Change-Id: Ia50296da98428649613548dfe31c8dc9669da0d6 Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
This commit is contained in:
@@ -42,7 +42,6 @@ struct snd_usb_clock_ref {
|
||||
unsigned char clock;
|
||||
atomic_t locked;
|
||||
int rate;
|
||||
bool need_setup;
|
||||
struct list_head list;
|
||||
};
|
||||
|
||||
@@ -768,8 +767,7 @@ bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip,
|
||||
* The endpoint needs to be closed via snd_usb_endpoint_close() later.
|
||||
*
|
||||
* Note that this function doesn't configure the endpoint. The substream
|
||||
* needs to set it up later via snd_usb_endpoint_set_params() and
|
||||
* snd_usb_endpoint_prepare().
|
||||
* needs to set it up later via snd_usb_endpoint_configure().
|
||||
*/
|
||||
struct snd_usb_endpoint *
|
||||
snd_usb_endpoint_open(struct snd_usb_audio *chip,
|
||||
@@ -1302,39 +1300,15 @@ out_of_memory:
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* update the rate of the referred clock; return the actual rate */
|
||||
static int update_clock_ref_rate(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep)
|
||||
{
|
||||
struct snd_usb_clock_ref *clock = ep->clock_ref;
|
||||
int rate = ep->cur_rate;
|
||||
|
||||
if (!clock || clock->rate == rate)
|
||||
return rate;
|
||||
if (clock->rate) {
|
||||
if (atomic_read(&clock->locked))
|
||||
return clock->rate;
|
||||
if (clock->rate != rate) {
|
||||
usb_audio_err(chip, "Mismatched sample rate %d vs %d for EP 0x%x\n",
|
||||
clock->rate, rate, ep->ep_num);
|
||||
return clock->rate;
|
||||
}
|
||||
}
|
||||
clock->rate = rate;
|
||||
clock->need_setup = true;
|
||||
return rate;
|
||||
}
|
||||
|
||||
/*
|
||||
* snd_usb_endpoint_set_params: configure an snd_usb_endpoint
|
||||
*
|
||||
* It's called either from hw_params callback.
|
||||
* Determine the number of URBs to be used on this endpoint.
|
||||
* An endpoint must be configured before it can be started.
|
||||
* An endpoint that is already running can not be reconfigured.
|
||||
*/
|
||||
int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep)
|
||||
static int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep)
|
||||
{
|
||||
const struct audioformat *fmt = ep->cur_audiofmt;
|
||||
int err;
|
||||
@@ -1386,46 +1360,49 @@ int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
|
||||
ep->maxframesize = ep->maxpacksize / ep->cur_frame_bytes;
|
||||
ep->curframesize = ep->curpacksize / ep->cur_frame_bytes;
|
||||
|
||||
return update_clock_ref_rate(chip, ep);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_sample_rate(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep)
|
||||
{
|
||||
struct snd_usb_clock_ref *clock = ep->clock_ref;
|
||||
int rate, err;
|
||||
int err;
|
||||
|
||||
rate = update_clock_ref_rate(chip, ep);
|
||||
if (rate < 0)
|
||||
return rate;
|
||||
if (clock && !clock->need_setup)
|
||||
return 0;
|
||||
|
||||
err = snd_usb_init_sample_rate(chip, ep->cur_audiofmt, rate);
|
||||
if (err < 0) {
|
||||
if (clock)
|
||||
clock->rate = 0; /* reset rate */
|
||||
return err;
|
||||
if (clock) {
|
||||
if (atomic_read(&clock->locked))
|
||||
return 0;
|
||||
if (clock->rate == ep->cur_rate)
|
||||
return 0;
|
||||
if (clock->rate && clock->rate != ep->cur_rate) {
|
||||
usb_audio_dbg(chip, "Mismatched sample rate %d vs %d for EP 0x%x\n",
|
||||
clock->rate, ep->cur_rate, ep->ep_num);
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
err = snd_usb_init_sample_rate(chip, ep->cur_audiofmt, ep->cur_rate);
|
||||
if (err < 0)
|
||||
return err;
|
||||
|
||||
if (clock)
|
||||
clock->need_setup = false;
|
||||
clock->rate = ep->cur_rate;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* snd_usb_endpoint_prepare: Prepare the endpoint
|
||||
* snd_usb_endpoint_configure: Configure the endpoint
|
||||
*
|
||||
* This function sets up the EP to be fully usable state.
|
||||
* It's called either from prepare callback.
|
||||
* It's called either from hw_params or prepare callback.
|
||||
* The function checks need_setup flag, and performs nothing unless needed,
|
||||
* so it's safe to call this multiple times.
|
||||
*
|
||||
* This returns zero if unchanged, 1 if the configuration has changed,
|
||||
* or a negative error code.
|
||||
*/
|
||||
int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep)
|
||||
int snd_usb_endpoint_configure(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep)
|
||||
{
|
||||
bool iface_first;
|
||||
int err = 0;
|
||||
@@ -1446,6 +1423,9 @@ int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
}
|
||||
err = snd_usb_endpoint_set_params(chip, ep);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
goto done;
|
||||
}
|
||||
|
||||
@@ -1473,6 +1453,10 @@ int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
err = snd_usb_endpoint_set_params(chip, ep);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
err = snd_usb_select_mode_quirk(chip, ep->cur_audiofmt);
|
||||
if (err < 0)
|
||||
goto unlock;
|
||||
|
||||
@@ -17,10 +17,8 @@ snd_usb_endpoint_open(struct snd_usb_audio *chip,
|
||||
bool is_sync_ep);
|
||||
void snd_usb_endpoint_close(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep);
|
||||
int snd_usb_endpoint_set_params(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep);
|
||||
int snd_usb_endpoint_prepare(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep);
|
||||
int snd_usb_endpoint_configure(struct snd_usb_audio *chip,
|
||||
struct snd_usb_endpoint *ep);
|
||||
int snd_usb_endpoint_get_clock_rate(struct snd_usb_audio *chip, int clock);
|
||||
|
||||
bool snd_usb_endpoint_compatible(struct snd_usb_audio *chip,
|
||||
|
||||
@@ -442,6 +442,35 @@ static void close_endpoints(struct snd_usb_audio *chip,
|
||||
}
|
||||
}
|
||||
|
||||
static int configure_endpoints(struct snd_usb_audio *chip,
|
||||
struct snd_usb_substream *subs)
|
||||
{
|
||||
int err;
|
||||
|
||||
if (subs->data_endpoint->need_setup) {
|
||||
/* stop any running stream beforehand */
|
||||
if (stop_endpoints(subs, false))
|
||||
sync_pending_stops(subs);
|
||||
if (subs->sync_endpoint) {
|
||||
err = snd_usb_endpoint_configure(chip, subs->sync_endpoint);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
err = snd_usb_endpoint_configure(chip, subs->data_endpoint);
|
||||
if (err < 0)
|
||||
return err;
|
||||
snd_usb_set_format_quirk(subs, subs->cur_audiofmt);
|
||||
} else {
|
||||
if (subs->sync_endpoint) {
|
||||
err = snd_usb_endpoint_configure(chip, subs->sync_endpoint);
|
||||
if (err < 0)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* hw_params callback
|
||||
*
|
||||
@@ -533,16 +562,7 @@ static int snd_usb_hw_params(struct snd_pcm_substream *substream,
|
||||
subs->cur_audiofmt = fmt;
|
||||
mutex_unlock(&chip->mutex);
|
||||
|
||||
if (!subs->data_endpoint->need_setup)
|
||||
goto unlock;
|
||||
|
||||
if (subs->sync_endpoint) {
|
||||
ret = snd_usb_endpoint_set_params(chip, subs->sync_endpoint);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ret = snd_usb_endpoint_set_params(chip, subs->data_endpoint);
|
||||
ret = configure_endpoints(chip, subs);
|
||||
|
||||
unlock:
|
||||
if (ret < 0)
|
||||
@@ -625,18 +645,9 @@ static int snd_usb_pcm_prepare(struct snd_pcm_substream *substream)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
if (subs->sync_endpoint) {
|
||||
ret = snd_usb_endpoint_prepare(chip, subs->sync_endpoint);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ret = snd_usb_endpoint_prepare(chip, subs->data_endpoint);
|
||||
ret = configure_endpoints(chip, subs);
|
||||
if (ret < 0)
|
||||
goto unlock;
|
||||
else if (ret > 0)
|
||||
snd_usb_set_format_quirk(subs, subs->cur_audiofmt);
|
||||
ret = 0;
|
||||
|
||||
/* reset the pointer */
|
||||
subs->buffer_bytes = frames_to_bytes(runtime, runtime->buffer_size);
|
||||
|
||||
Reference in New Issue
Block a user