Skip to content

Commit 199b577

Browse files
Meng Dongyangrkhuangtao
authored andcommitted
usb: gadget: uac: add support of different sample rate
The sample rate is force to 44100 in current code. This code add numbers of sample rate up to 15 and support set or get by PC. Change-Id: I543d84f3081f82a4c96071c2b2442d37a9a835fb Signed-off-by: Meng Dongyang <daniel.meng@rock-chips.com>
1 parent fd61a2d commit 199b577

1 file changed

Lines changed: 108 additions & 21 deletions

File tree

drivers/usb/gadget/function/f_audio_source.c

Lines changed: 108 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,10 @@
2929
#include <linux/usb/composite.h>
3030
#include <linux/module.h>
3131
#include <linux/moduleparam.h>
32-
#define SAMPLE_RATE 44100
33-
#define FRAMES_PER_MSEC (SAMPLE_RATE / 1000)
32+
#define DEFAULT_SAMPLE_RATE 44100
33+
#define MAX_SAMPLE_RATE 96000
34+
#define MIN_SAMPLE_RATE 8000
35+
#define DEFAULT_FRAMES_PER_MSEC (DEFAULT_SAMPLE_RATE / 1000)
3436

3537
#define IN_EP_MAX_PACKET_SIZE 256
3638

@@ -42,6 +44,12 @@
4244
#define AUDIO_NUM_INTERFACES 2
4345
#define MAX_INST_NAME_LEN 40
4446

47+
static u32 sample_rate_table[] = {
48+
8000, 11025, 16000, 22050, 24000,
49+
32000, 40000, 44100, 48000, 56000,
50+
64000, 72000, 80000, 88200, 96000,
51+
};
52+
4553
/* B.3.1 Standard AC Interface Descriptor */
4654
static struct usb_interface_descriptor ac_interface_desc = {
4755
.bLength = USB_DT_INTERFACE_SIZE,
@@ -135,16 +143,16 @@ static struct uac1_as_header_descriptor as_header_desc = {
135143
.wFormatTag = UAC_FORMAT_TYPE_I_PCM,
136144
};
137145

138-
DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(1);
146+
DECLARE_UAC_FORMAT_TYPE_I_DISCRETE_DESC(15);
139147

140-
static struct uac_format_type_i_discrete_descriptor_1 as_type_i_desc = {
141-
.bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(1),
148+
static struct uac_format_type_i_discrete_descriptor_15 as_type_i_desc = {
149+
.bLength = UAC_FORMAT_TYPE_I_DISCRETE_DESC_SIZE(15),
142150
.bDescriptorType = USB_DT_CS_INTERFACE,
143151
.bDescriptorSubtype = UAC_FORMAT_TYPE,
144152
.bFormatType = UAC_FORMAT_TYPE_I,
145153
.bSubframeSize = 2,
146154
.bBitResolution = 16,
147-
.bSamFreqType = 1,
155+
.bSamFreqType = ARRAY_SIZE(sample_rate_table),
148156
};
149157

150158
/* Standard ISO IN Endpoint Descriptor for highspeed */
@@ -227,8 +235,8 @@ static struct snd_pcm_hardware audio_hw_info = {
227235
.formats = SNDRV_PCM_FMTBIT_S16_LE,
228236
.channels_min = 2,
229237
.channels_max = 2,
230-
.rate_min = SAMPLE_RATE,
231-
.rate_max = SAMPLE_RATE,
238+
.rate_min = MIN_SAMPLE_RATE,
239+
.rate_max = MAX_SAMPLE_RATE,
232240

233241
.buffer_bytes_max = 1024 * 1024,
234242
.period_bytes_min = 64,
@@ -239,6 +247,9 @@ static struct snd_pcm_hardware audio_hw_info = {
239247

240248
/*-------------------------------------------------------------------------*/
241249

250+
static u16 g_w_value;
251+
static u8 g_bRequest;
252+
242253
struct audio_source_config {
243254
int card;
244255
int device;
@@ -275,6 +286,13 @@ struct audio_dev {
275286
ktime_t start_time;
276287
/* number of frames sent since start_time */
277288
s64 frames_sent;
289+
290+
/* number of frames sent per millisecond */
291+
s64 frames_per_msec;
292+
293+
/* current sample rate */
294+
s64 sample_rate;
295+
278296
struct audio_source_config *config;
279297
/* for creating and issuing QoS requests */
280298
struct pm_qos_request pm_qos;
@@ -468,20 +486,20 @@ static void audio_send(struct audio_dev *audio)
468486
now = ktime_get();
469487
msecs = div_s64((ktime_to_ns(now) - ktime_to_ns(audio->start_time)),
470488
1000000);
471-
frames = div_s64((msecs * SAMPLE_RATE), 1000);
489+
frames = div_s64((msecs * audio->sample_rate), 1000);
472490

473491
/* Readjust our frames_sent if we fall too far behind.
474492
* If we get too far behind it is better to drop some frames than
475493
* to keep sending data too fast in an attempt to catch up.
476494
*/
477-
if (frames - audio->frames_sent > 10 * FRAMES_PER_MSEC)
478-
audio->frames_sent = frames - FRAMES_PER_MSEC;
495+
if (frames - audio->frames_sent > 10 * audio->frames_per_msec)
496+
audio->frames_sent = frames - audio->frames_per_msec;
479497

480498
frames -= audio->frames_sent;
481499

482500
/* We need to send something to keep the pipeline going */
483501
if (frames <= 0)
484-
frames = FRAMES_PER_MSEC;
502+
frames = audio->frames_per_msec;
485503

486504
while (frames > 0) {
487505
req = audio_req_get(audio);
@@ -526,7 +544,40 @@ static void audio_send(struct audio_dev *audio)
526544

527545
static void audio_control_complete(struct usb_ep *ep, struct usb_request *req)
528546
{
529-
/* nothing to do here */
547+
struct audio_dev *audio = ep->driver_data;
548+
u8 *buf = req->buf;
549+
550+
pr_debug("audio_control_complete req->status %d req->actual %d\n",
551+
req->status, req->actual);
552+
553+
if (req->status)
554+
return;
555+
556+
if (g_w_value == UAC_EP_CS_ATTR_SAMPLE_RATE << 8) {
557+
switch (g_bRequest) {
558+
case UAC_SET_CUR:
559+
g_w_value = 0;
560+
g_bRequest = 0;
561+
562+
audio->sample_rate = (s64)buf[0];
563+
audio->sample_rate += ((s64)buf[1]) << 8;
564+
audio->sample_rate += ((s64)buf[2]) << 16;
565+
audio->frames_per_msec = audio->sample_rate;
566+
do_div(audio->frames_per_msec, 1000);
567+
pr_info("audio source set sample rate to %lld\n",
568+
audio->sample_rate);
569+
break;
570+
case UAC_SET_MIN:
571+
/* fallthrough */
572+
case UAC_SET_MAX:
573+
/* fallthrough */
574+
case UAC_SET_RES:
575+
/* fallthrough */
576+
break;
577+
default:
578+
break;
579+
}
580+
}
530581
}
531582

532583
static void audio_data_complete(struct usb_ep *ep, struct usb_request *req)
@@ -562,8 +613,15 @@ static int audio_set_endpoint_req(struct usb_function *f,
562613

563614
switch (ctrl->bRequest) {
564615
case UAC_SET_CUR:
616+
if (w_value == UAC_EP_CS_ATTR_SAMPLE_RATE << 8) {
617+
g_w_value = w_value;
618+
g_bRequest = ctrl->bRequest;
619+
}
620+
/* fallthrough */
565621
case UAC_SET_MIN:
622+
/* fallthrough */
566623
case UAC_SET_MAX:
624+
/* fallthrough */
567625
case UAC_SET_RES:
568626
value = len;
569627
break;
@@ -577,6 +635,7 @@ static int audio_set_endpoint_req(struct usb_function *f,
577635
static int audio_get_endpoint_req(struct usb_function *f,
578636
const struct usb_ctrlrequest *ctrl)
579637
{
638+
struct audio_dev *audio = func_to_audio(f);
580639
struct usb_composite_dev *cdev = f->config->cdev;
581640
int value = -EOPNOTSUPP;
582641
u8 ep = ((le16_to_cpu(ctrl->wIndex) >> 8) & 0xFF);
@@ -590,13 +649,31 @@ static int audio_get_endpoint_req(struct usb_function *f,
590649
if (w_value == UAC_EP_CS_ATTR_SAMPLE_RATE << 8) {
591650
switch (ctrl->bRequest) {
592651
case UAC_GET_CUR:
652+
buf[0] = (u8)audio->sample_rate;
653+
buf[1] = (u8)(audio->sample_rate >> 8);
654+
buf[2] = (u8)(audio->sample_rate >> 16);
655+
value = 3;
656+
break;
657+
593658
case UAC_GET_MIN:
659+
buf[0] = (u8)MIN_SAMPLE_RATE;
660+
buf[1] = (u8)(MIN_SAMPLE_RATE >> 8);
661+
buf[2] = (u8)(MIN_SAMPLE_RATE >> 16);
662+
value = 3;
663+
break;
664+
594665
case UAC_GET_MAX:
666+
buf[0] = (u8)MAX_SAMPLE_RATE;
667+
buf[1] = (u8)(MAX_SAMPLE_RATE >> 8);
668+
buf[2] = (u8)(MAX_SAMPLE_RATE >> 16);
669+
value = 3;
670+
break;
671+
595672
case UAC_GET_RES:
596673
/* return our sample rate */
597-
buf[0] = (u8)SAMPLE_RATE;
598-
buf[1] = (u8)(SAMPLE_RATE >> 8);
599-
buf[2] = (u8)(SAMPLE_RATE >> 16);
674+
buf[0] = (u8)MAX_SAMPLE_RATE;
675+
buf[1] = (u8)(MAX_SAMPLE_RATE >> 8);
676+
buf[2] = (u8)(MAX_SAMPLE_RATE >> 16);
600677
value = 3;
601678
break;
602679
default:
@@ -686,16 +763,18 @@ static void audio_free_func(struct usb_function *f)
686763
static void audio_build_desc(struct audio_dev *audio)
687764
{
688765
u8 *sam_freq;
689-
int rate;
766+
u32 rate, i;
690767

691768
/* Set channel numbers */
692769
input_terminal_desc.bNrChannels = 2;
693770
as_type_i_desc.bNrChannels = 2;
694771

695772
/* Set sample rates */
696-
rate = SAMPLE_RATE;
697-
sam_freq = as_type_i_desc.tSamFreq[0];
698-
memcpy(sam_freq, &rate, 3);
773+
for (i = 0; i < ARRAY_SIZE(sample_rate_table); i++) {
774+
rate = sample_rate_table[i];
775+
sam_freq = as_type_i_desc.tSamFreq[i];
776+
memcpy(sam_freq, &rate, 3);
777+
}
699778
}
700779

701780

@@ -723,6 +802,10 @@ audio_bind(struct usb_configuration *c, struct usb_function *f)
723802
struct audio_source_config *config =
724803
fi_audio->config;
725804

805+
audio->alt = 0;
806+
audio->sample_rate = DEFAULT_SAMPLE_RATE;
807+
audio->frames_per_msec = DEFAULT_FRAMES_PER_MSEC;
808+
726809
err = snd_card_setup(c, config);
727810
if (err)
728811
return err;
@@ -874,7 +957,7 @@ static int audio_pcm_hw_params(struct snd_pcm_substream *substream,
874957
unsigned int channels = params_channels(params);
875958
unsigned int rate = params_rate(params);
876959

877-
if (rate != SAMPLE_RATE)
960+
if (rate > MAX_SAMPLE_RATE || rate < MIN_SAMPLE_RATE)
878961
return -EINVAL;
879962
if (channels != 2)
880963
return -EINVAL;
@@ -973,6 +1056,10 @@ int audio_source_bind_config(struct usb_configuration *c,
9731056

9741057
audio = &_audio_dev;
9751058

1059+
audio->alt = 0;
1060+
audio->sample_rate = DEFAULT_SAMPLE_RATE;
1061+
audio->frames_per_msec = DEFAULT_FRAMES_PER_MSEC;
1062+
9761063
err = snd_card_setup(c, config);
9771064
if (err)
9781065
return err;

0 commit comments

Comments
 (0)