Commit 8722a949 authored by Pavel Hofman's avatar Pavel Hofman Committed by Greg Kroah-Hartman

usb: gadget: u_audio: Move dynamic srate from params to rtd

Parameters uac_params.p_srate/c_srate are dynamic now and are not part
of parametric configuration anymore. Move them to the
runtime struct uac_rtd_params for each stream.
Suggested-by: default avatarJohn Keeping <john@metanate.com>
Signed-off-by: default avatarPavel Hofman <pavel.hofman@ivitera.com>
Link: https://lore.kernel.org/r/20220121155308.48794-4-pavel.hofman@ivitera.comSigned-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent c565ad07
...@@ -1297,7 +1297,6 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) ...@@ -1297,7 +1297,6 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize); audio->out_ep_maxpsize = le16_to_cpu(as_out_ep_desc.wMaxPacketSize);
audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize); audio->in_ep_maxpsize = le16_to_cpu(as_in_ep_desc.wMaxPacketSize);
audio->params.c_chmask = audio_opts->c_chmask; audio->params.c_chmask = audio_opts->c_chmask;
audio->params.c_srate = audio_opts->c_srate;
audio->params.c_srates[0] = audio_opts->c_srate; audio->params.c_srates[0] = audio_opts->c_srate;
audio->params.c_ssize = audio_opts->c_ssize; audio->params.c_ssize = audio_opts->c_ssize;
if (FUIN_EN(audio_opts)) { if (FUIN_EN(audio_opts)) {
...@@ -1310,7 +1309,6 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f) ...@@ -1310,7 +1309,6 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
audio->params.p_fu.volume_res = audio_opts->p_volume_res; audio->params.p_fu.volume_res = audio_opts->p_volume_res;
} }
audio->params.p_chmask = audio_opts->p_chmask; audio->params.p_chmask = audio_opts->p_chmask;
audio->params.p_srate = audio_opts->p_srate;
audio->params.p_srates[0] = audio_opts->p_srate; audio->params.p_srates[0] = audio_opts->p_srate;
audio->params.p_ssize = audio_opts->p_ssize; audio->params.p_ssize = audio_opts->p_ssize;
if (FUOUT_EN(audio_opts)) { if (FUOUT_EN(audio_opts)) {
......
...@@ -1209,7 +1209,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) ...@@ -1209,7 +1209,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
agdev->gadget = gadget; agdev->gadget = gadget;
agdev->params.p_chmask = uac2_opts->p_chmask; agdev->params.p_chmask = uac2_opts->p_chmask;
agdev->params.p_srate = uac2_opts->p_srate;
agdev->params.p_srates[0] = uac2_opts->p_srate; agdev->params.p_srates[0] = uac2_opts->p_srate;
agdev->params.p_ssize = uac2_opts->p_ssize; agdev->params.p_ssize = uac2_opts->p_ssize;
if (FUIN_EN(uac2_opts)) { if (FUIN_EN(uac2_opts)) {
...@@ -1221,7 +1220,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn) ...@@ -1221,7 +1220,6 @@ afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
agdev->params.p_fu.volume_res = uac2_opts->p_volume_res; agdev->params.p_fu.volume_res = uac2_opts->p_volume_res;
} }
agdev->params.c_chmask = uac2_opts->c_chmask; agdev->params.c_chmask = uac2_opts->c_chmask;
agdev->params.c_srate = uac2_opts->c_srate;
agdev->params.c_srates[0] = uac2_opts->c_srate; agdev->params.c_srates[0] = uac2_opts->c_srate;
agdev->params.c_ssize = uac2_opts->c_ssize; agdev->params.c_ssize = uac2_opts->c_ssize;
if (FUOUT_EN(uac2_opts)) { if (FUOUT_EN(uac2_opts)) {
......
...@@ -64,6 +64,7 @@ struct uac_rtd_params { ...@@ -64,6 +64,7 @@ struct uac_rtd_params {
int mute; int mute;
struct snd_kcontrol *snd_kctl_rate; /* read-only current rate */ struct snd_kcontrol *snd_kctl_rate; /* read-only current rate */
int srate; /* selected samplerate */
spinlock_t lock; /* lock for control transfers */ spinlock_t lock; /* lock for control transfers */
...@@ -153,8 +154,6 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) ...@@ -153,8 +154,6 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
struct snd_pcm_runtime *runtime; struct snd_pcm_runtime *runtime;
struct uac_rtd_params *prm = req->context; struct uac_rtd_params *prm = req->context;
struct snd_uac_chip *uac = prm->uac; struct snd_uac_chip *uac = prm->uac;
struct g_audio *audio_dev = uac->audio_dev;
struct uac_params *params = &audio_dev->params;
unsigned int frames, p_pktsize; unsigned int frames, p_pktsize;
unsigned long long pitched_rate_mil, p_pktsize_residue_mil, unsigned long long pitched_rate_mil, p_pktsize_residue_mil,
residue_frames_mil, div_result; residue_frames_mil, div_result;
...@@ -199,15 +198,14 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req) ...@@ -199,15 +198,14 @@ static void u_audio_iso_complete(struct usb_ep *ep, struct usb_request *req)
*/ */
unsigned long long p_interval_mil = uac->p_interval * 1000000ULL; unsigned long long p_interval_mil = uac->p_interval * 1000000ULL;
pitched_rate_mil = (unsigned long long) pitched_rate_mil = (unsigned long long) prm->srate * prm->pitch;
params->p_srate * prm->pitch;
div_result = pitched_rate_mil; div_result = pitched_rate_mil;
do_div(div_result, uac->p_interval); do_div(div_result, uac->p_interval);
do_div(div_result, 1000000); do_div(div_result, 1000000);
frames = (unsigned int) div_result; frames = (unsigned int) div_result;
pr_debug("p_srate %d, pitch %d, interval_mil %llu, frames %d\n", pr_debug("p_srate %d, pitch %d, interval_mil %llu, frames %d\n",
params->p_srate, prm->pitch, p_interval_mil, frames); prm->srate, prm->pitch, p_interval_mil, frames);
p_pktsize = min_t(unsigned int, p_pktsize = min_t(unsigned int,
uac->p_framesize * frames, uac->p_framesize * frames,
...@@ -284,7 +282,6 @@ static void u_audio_iso_fback_complete(struct usb_ep *ep, ...@@ -284,7 +282,6 @@ static void u_audio_iso_fback_complete(struct usb_ep *ep,
struct uac_rtd_params *prm = req->context; struct uac_rtd_params *prm = req->context;
struct snd_uac_chip *uac = prm->uac; struct snd_uac_chip *uac = prm->uac;
struct g_audio *audio_dev = uac->audio_dev; struct g_audio *audio_dev = uac->audio_dev;
struct uac_params *params = &audio_dev->params;
int status = req->status; int status = req->status;
/* i/f shutting down */ /* i/f shutting down */
...@@ -306,7 +303,7 @@ static void u_audio_iso_fback_complete(struct usb_ep *ep, ...@@ -306,7 +303,7 @@ static void u_audio_iso_fback_complete(struct usb_ep *ep,
__func__, status, req->actual, req->length); __func__, status, req->actual, req->length);
u_audio_set_fback_frequency(audio_dev->gadget->speed, audio_dev->out_ep, u_audio_set_fback_frequency(audio_dev->gadget->speed, audio_dev->out_ep,
params->c_srate, prm->pitch, prm->srate, prm->pitch,
req->buf); req->buf);
if (usb_ep_queue(ep, req, GFP_ATOMIC)) if (usb_ep_queue(ep, req, GFP_ATOMIC))
...@@ -390,16 +387,14 @@ static int uac_pcm_open(struct snd_pcm_substream *substream) ...@@ -390,16 +387,14 @@ static int uac_pcm_open(struct snd_pcm_substream *substream)
struct snd_pcm_runtime *runtime = substream->runtime; struct snd_pcm_runtime *runtime = substream->runtime;
struct g_audio *audio_dev; struct g_audio *audio_dev;
struct uac_params *params; struct uac_params *params;
struct uac_rtd_params *prm;
int p_ssize, c_ssize; int p_ssize, c_ssize;
int p_srate, c_srate;
int p_chmask, c_chmask; int p_chmask, c_chmask;
audio_dev = uac->audio_dev; audio_dev = uac->audio_dev;
params = &audio_dev->params; params = &audio_dev->params;
p_ssize = params->p_ssize; p_ssize = params->p_ssize;
c_ssize = params->c_ssize; c_ssize = params->c_ssize;
p_srate = params->p_srate;
c_srate = params->c_srate;
p_chmask = params->p_chmask; p_chmask = params->p_chmask;
c_chmask = params->c_chmask; c_chmask = params->c_chmask;
uac->p_residue_mil = 0; uac->p_residue_mil = 0;
...@@ -407,19 +402,18 @@ static int uac_pcm_open(struct snd_pcm_substream *substream) ...@@ -407,19 +402,18 @@ static int uac_pcm_open(struct snd_pcm_substream *substream)
runtime->hw = uac_pcm_hardware; runtime->hw = uac_pcm_hardware;
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) { if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
runtime->hw.rate_min = p_srate;
runtime->hw.formats = uac_ssize_to_fmt(p_ssize); runtime->hw.formats = uac_ssize_to_fmt(p_ssize);
runtime->hw.channels_min = num_channels(p_chmask); runtime->hw.channels_min = num_channels(p_chmask);
runtime->hw.period_bytes_min = 2 * uac->p_prm.max_psize prm = &uac->p_prm;
/ runtime->hw.periods_min;
} else { } else {
runtime->hw.rate_min = c_srate;
runtime->hw.formats = uac_ssize_to_fmt(c_ssize); runtime->hw.formats = uac_ssize_to_fmt(c_ssize);
runtime->hw.channels_min = num_channels(c_chmask); runtime->hw.channels_min = num_channels(c_chmask);
runtime->hw.period_bytes_min = 2 * uac->c_prm.max_psize prm = &uac->c_prm;
/ runtime->hw.periods_min;
} }
runtime->hw.period_bytes_min = 2 * prm->max_psize
/ runtime->hw.periods_min;
runtime->hw.rate_min = prm->srate;
runtime->hw.rate_max = runtime->hw.rate_min; runtime->hw.rate_max = runtime->hw.rate_min;
runtime->hw.channels_max = runtime->hw.channels_min; runtime->hw.channels_max = runtime->hw.channels_min;
...@@ -499,12 +493,18 @@ static inline void free_ep_fback(struct uac_rtd_params *prm, struct usb_ep *ep) ...@@ -499,12 +493,18 @@ static inline void free_ep_fback(struct uac_rtd_params *prm, struct usb_ep *ep)
int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate) int u_audio_set_capture_srate(struct g_audio *audio_dev, int srate)
{ {
struct uac_params *params = &audio_dev->params; struct uac_params *params = &audio_dev->params;
struct snd_uac_chip *uac = audio_dev->uac;
struct uac_rtd_params *prm;
int i; int i;
unsigned long flags;
dev_dbg(&audio_dev->gadget->dev, "%s: srate %d\n", __func__, srate); dev_dbg(&audio_dev->gadget->dev, "%s: srate %d\n", __func__, srate);
prm = &uac->c_prm;
for (i = 0; i < UAC_MAX_RATES; i++) { for (i = 0; i < UAC_MAX_RATES; i++) {
if (params->c_srates[i] == srate) { if (params->c_srates[i] == srate) {
params->c_srate = srate; spin_lock_irqsave(&prm->lock, flags);
prm->srate = srate;
spin_unlock_irqrestore(&prm->lock, flags);
return 0; return 0;
} }
if (params->c_srates[i] == 0) if (params->c_srates[i] == 0)
...@@ -518,12 +518,18 @@ EXPORT_SYMBOL_GPL(u_audio_set_capture_srate); ...@@ -518,12 +518,18 @@ EXPORT_SYMBOL_GPL(u_audio_set_capture_srate);
int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate) int u_audio_set_playback_srate(struct g_audio *audio_dev, int srate)
{ {
struct uac_params *params = &audio_dev->params; struct uac_params *params = &audio_dev->params;
struct snd_uac_chip *uac = audio_dev->uac;
struct uac_rtd_params *prm;
int i; int i;
unsigned long flags;
dev_dbg(&audio_dev->gadget->dev, "%s: srate %d\n", __func__, srate); dev_dbg(&audio_dev->gadget->dev, "%s: srate %d\n", __func__, srate);
prm = &uac->p_prm;
for (i = 0; i < UAC_MAX_RATES; i++) { for (i = 0; i < UAC_MAX_RATES; i++) {
if (params->p_srates[i] == srate) { if (params->p_srates[i] == srate) {
params->p_srate = srate; spin_lock_irqsave(&prm->lock, flags);
prm->srate = srate;
spin_unlock_irqrestore(&prm->lock, flags);
return 0; return 0;
} }
if (params->p_srates[i] == 0) if (params->p_srates[i] == 0)
...@@ -545,9 +551,9 @@ int u_audio_start_capture(struct g_audio *audio_dev) ...@@ -545,9 +551,9 @@ int u_audio_start_capture(struct g_audio *audio_dev)
struct uac_params *params = &audio_dev->params; struct uac_params *params = &audio_dev->params;
int req_len, i; int req_len, i;
dev_dbg(dev, "start capture with rate %d\n", params->c_srate);
ep = audio_dev->out_ep;
prm = &uac->c_prm; prm = &uac->c_prm;
dev_dbg(dev, "start capture with rate %d\n", prm->srate);
ep = audio_dev->out_ep;
config_ep_by_speed(gadget, &audio_dev->func, ep); config_ep_by_speed(gadget, &audio_dev->func, ep);
req_len = ep->maxpacket; req_len = ep->maxpacket;
...@@ -604,7 +610,7 @@ int u_audio_start_capture(struct g_audio *audio_dev) ...@@ -604,7 +610,7 @@ int u_audio_start_capture(struct g_audio *audio_dev)
*/ */
prm->pitch = 1000000; prm->pitch = 1000000;
u_audio_set_fback_frequency(audio_dev->gadget->speed, ep, u_audio_set_fback_frequency(audio_dev->gadget->speed, ep,
params->c_srate, prm->pitch, prm->srate, prm->pitch,
req_fback->buf); req_fback->buf);
if (usb_ep_queue(ep_fback, req_fback, GFP_ATOMIC)) if (usb_ep_queue(ep_fback, req_fback, GFP_ATOMIC))
...@@ -638,9 +644,9 @@ int u_audio_start_playback(struct g_audio *audio_dev) ...@@ -638,9 +644,9 @@ int u_audio_start_playback(struct g_audio *audio_dev)
int req_len, i; int req_len, i;
unsigned int p_pktsize; unsigned int p_pktsize;
dev_dbg(dev, "start playback with rate %d\n", params->p_srate);
ep = audio_dev->in_ep;
prm = &uac->p_prm; prm = &uac->p_prm;
dev_dbg(dev, "start playback with rate %d\n", prm->srate);
ep = audio_dev->in_ep;
config_ep_by_speed(gadget, &audio_dev->func, ep); config_ep_by_speed(gadget, &audio_dev->func, ep);
ep_desc = ep->desc; ep_desc = ep->desc;
...@@ -661,7 +667,7 @@ int u_audio_start_playback(struct g_audio *audio_dev) ...@@ -661,7 +667,7 @@ int u_audio_start_playback(struct g_audio *audio_dev)
uac->p_interval = factor / (1 << (ep_desc->bInterval - 1)); uac->p_interval = factor / (1 << (ep_desc->bInterval - 1));
p_pktsize = min_t(unsigned int, p_pktsize = min_t(unsigned int,
uac->p_framesize * uac->p_framesize *
(params->p_srate / uac->p_interval), (prm->srate / uac->p_interval),
ep->maxpacket); ep->maxpacket);
req_len = p_pktsize; req_len = p_pktsize;
...@@ -1037,15 +1043,11 @@ static int u_audio_rate_get(struct snd_kcontrol *kcontrol, ...@@ -1037,15 +1043,11 @@ static int u_audio_rate_get(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_value *ucontrol) struct snd_ctl_elem_value *ucontrol)
{ {
struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol); struct uac_rtd_params *prm = snd_kcontrol_chip(kcontrol);
struct snd_uac_chip *uac = prm->uac; unsigned long flags;
struct g_audio *audio_dev = uac->audio_dev;
struct uac_params *params = &audio_dev->params;
if (prm == &uac->c_prm)
ucontrol->value.integer.value[0] = params->c_srate;
else
ucontrol->value.integer.value[0] = params->p_srate;
spin_lock_irqsave(&prm->lock, flags);
ucontrol->value.integer.value[0] = prm->srate;
spin_unlock_irqrestore(&prm->lock, flags);
return 0; return 0;
} }
...@@ -1117,6 +1119,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, ...@@ -1117,6 +1119,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
spin_lock_init(&prm->lock); spin_lock_init(&prm->lock);
uac->c_prm.uac = uac; uac->c_prm.uac = uac;
prm->max_psize = g_audio->out_ep_maxpsize; prm->max_psize = g_audio->out_ep_maxpsize;
prm->srate = params->c_srates[0];
prm->reqs = kcalloc(params->req_number, prm->reqs = kcalloc(params->req_number,
sizeof(struct usb_request *), sizeof(struct usb_request *),
...@@ -1141,6 +1144,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name, ...@@ -1141,6 +1144,7 @@ int g_audio_setup(struct g_audio *g_audio, const char *pcm_name,
spin_lock_init(&prm->lock); spin_lock_init(&prm->lock);
uac->p_prm.uac = uac; uac->p_prm.uac = uac;
prm->max_psize = g_audio->in_ep_maxpsize; prm->max_psize = g_audio->in_ep_maxpsize;
prm->srate = params->p_srates[0];
prm->reqs = kcalloc(params->req_number, prm->reqs = kcalloc(params->req_number,
sizeof(struct usb_request *), sizeof(struct usb_request *),
......
...@@ -42,17 +42,17 @@ struct uac_params { ...@@ -42,17 +42,17 @@ struct uac_params {
/* playback */ /* playback */
int p_chmask; /* channel mask */ int p_chmask; /* channel mask */
int p_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */ int p_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */
int p_srate; /* selected rate in Hz */
int p_ssize; /* sample size */ int p_ssize; /* sample size */
struct uac_fu_params p_fu; /* Feature Unit parameters */ struct uac_fu_params p_fu; /* Feature Unit parameters */
/* capture */ /* capture */
int c_chmask; /* channel mask */ int c_chmask; /* channel mask */
int c_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */ int c_srates[UAC_MAX_RATES]; /* available rates in Hz (0 terminated list) */
int c_srate; /* selected rate in Hz */
int c_ssize; /* sample size */ int c_ssize; /* sample size */
struct uac_fu_params c_fu; /* Feature Unit parameters */ struct uac_fu_params c_fu; /* Feature Unit parameters */
/* rates are dynamic, in uac_rtd_params */
int req_number; /* number of preallocated requests */ int req_number; /* number of preallocated requests */
int fb_max; /* upper frequency drift feedback limit per-mil */ int fb_max; /* upper frequency drift feedback limit per-mil */
}; };
......
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