mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-09 12:17:12 +09:00
FROMLIST: usb: gadget: f_uac*: Reduce code duplication
This replaces the dedicated headers for uac1 and uac2 functions with a shared header for both of them. Apart from unifying the struct names, further duplicated code for configfs setup is moved out of the function files into the shared header. Link: https://lore.kernel.org/patchwork/patch/805285/ Signed-off-by: Julian Scheel <julian@jusst.de> Signed-off-by: Ren Jianing <jianing.ren@rock-chips.com> Change-Id: Ie866bd02f174dc91168fe0bc49b571a77d849a42
This commit is contained in:
@@ -17,18 +17,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include "u_audio.h"
|
#include "u_audio.h"
|
||||||
#include "u_uac1.h"
|
#include "u_uac.h"
|
||||||
|
|
||||||
struct f_uac1 {
|
|
||||||
struct g_audio g_audio;
|
|
||||||
u8 ac_intf, as_in_intf, as_out_intf;
|
|
||||||
u8 ac_alt, as_in_alt, as_out_alt; /* needed for get_alt() */
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct f_uac1 *func_to_uac1(struct usb_function *f)
|
|
||||||
{
|
|
||||||
return container_of(f, struct f_uac1, g_audio.func);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* DESCRIPTORS ... most are static, but strings and full
|
* DESCRIPTORS ... most are static, but strings and full
|
||||||
@@ -445,7 +434,7 @@ static int f_audio_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
|
|||||||
struct usb_composite_dev *cdev = f->config->cdev;
|
struct usb_composite_dev *cdev = f->config->cdev;
|
||||||
struct usb_gadget *gadget = cdev->gadget;
|
struct usb_gadget *gadget = cdev->gadget;
|
||||||
struct device *dev = &gadget->dev;
|
struct device *dev = &gadget->dev;
|
||||||
struct f_uac1 *uac1 = func_to_uac1(f);
|
struct f_uac *uac1 = func_to_uac(f);
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
/* No i/f has more than 2 alt settings */
|
/* No i/f has more than 2 alt settings */
|
||||||
@@ -490,7 +479,7 @@ static int f_audio_get_alt(struct usb_function *f, unsigned intf)
|
|||||||
struct usb_composite_dev *cdev = f->config->cdev;
|
struct usb_composite_dev *cdev = f->config->cdev;
|
||||||
struct usb_gadget *gadget = cdev->gadget;
|
struct usb_gadget *gadget = cdev->gadget;
|
||||||
struct device *dev = &gadget->dev;
|
struct device *dev = &gadget->dev;
|
||||||
struct f_uac1 *uac1 = func_to_uac1(f);
|
struct f_uac *uac1 = func_to_uac(f);
|
||||||
|
|
||||||
if (intf == uac1->ac_intf)
|
if (intf == uac1->ac_intf)
|
||||||
return uac1->ac_alt;
|
return uac1->ac_alt;
|
||||||
@@ -508,7 +497,7 @@ static int f_audio_get_alt(struct usb_function *f, unsigned intf)
|
|||||||
|
|
||||||
static void f_audio_disable(struct usb_function *f)
|
static void f_audio_disable(struct usb_function *f)
|
||||||
{
|
{
|
||||||
struct f_uac1 *uac1 = func_to_uac1(f);
|
struct f_uac *uac1 = func_to_uac(f);
|
||||||
|
|
||||||
uac1->as_out_alt = 0;
|
uac1->as_out_alt = 0;
|
||||||
uac1->as_in_alt = 0;
|
uac1->as_in_alt = 0;
|
||||||
@@ -523,16 +512,16 @@ static int f_audio_bind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
{
|
{
|
||||||
struct usb_composite_dev *cdev = c->cdev;
|
struct usb_composite_dev *cdev = c->cdev;
|
||||||
struct usb_gadget *gadget = cdev->gadget;
|
struct usb_gadget *gadget = cdev->gadget;
|
||||||
struct f_uac1 *uac1 = func_to_uac1(f);
|
struct f_uac *uac1 = func_to_uac(f);
|
||||||
struct g_audio *audio = func_to_g_audio(f);
|
struct g_audio *audio = func_to_g_audio(f);
|
||||||
struct f_uac1_opts *audio_opts;
|
struct f_uac_opts *audio_opts;
|
||||||
struct usb_ep *ep = NULL;
|
struct usb_ep *ep = NULL;
|
||||||
struct usb_string *us;
|
struct usb_string *us;
|
||||||
u8 *sam_freq;
|
u8 *sam_freq;
|
||||||
int rate;
|
int rate;
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
audio_opts = container_of(f->fi, struct f_uac1_opts, func_inst);
|
audio_opts = container_of(f->fi, struct f_uac_opts, func_inst);
|
||||||
|
|
||||||
us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1));
|
us = usb_gstrings_attach(cdev, uac1_strings, ARRAY_SIZE(strings_uac1));
|
||||||
if (IS_ERR(us))
|
if (IS_ERR(us))
|
||||||
@@ -643,82 +632,26 @@ fail:
|
|||||||
|
|
||||||
/*-------------------------------------------------------------------------*/
|
/*-------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static inline struct f_uac1_opts *to_f_uac1_opts(struct config_item *item)
|
|
||||||
{
|
|
||||||
return container_of(to_config_group(item), struct f_uac1_opts,
|
|
||||||
func_inst.group);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void f_uac1_attr_release(struct config_item *item)
|
|
||||||
{
|
|
||||||
struct f_uac1_opts *opts = to_f_uac1_opts(item);
|
|
||||||
|
|
||||||
usb_put_function_instance(&opts->func_inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct configfs_item_operations f_uac1_item_ops = {
|
static struct configfs_item_operations f_uac1_item_ops = {
|
||||||
.release = f_uac1_attr_release,
|
.release = f_uac_attr_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UAC1_ATTRIBUTE(name) \
|
UAC_ATTRIBUTE(c_chmask);
|
||||||
static ssize_t f_uac1_opts_##name##_show( \
|
UAC_ATTRIBUTE(c_srate);
|
||||||
struct config_item *item, \
|
UAC_ATTRIBUTE(c_ssize);
|
||||||
char *page) \
|
UAC_ATTRIBUTE(p_chmask);
|
||||||
{ \
|
UAC_ATTRIBUTE(p_srate);
|
||||||
struct f_uac1_opts *opts = to_f_uac1_opts(item); \
|
UAC_ATTRIBUTE(p_ssize);
|
||||||
int result; \
|
UAC_ATTRIBUTE(req_number);
|
||||||
\
|
|
||||||
mutex_lock(&opts->lock); \
|
|
||||||
result = sprintf(page, "%u\n", opts->name); \
|
|
||||||
mutex_unlock(&opts->lock); \
|
|
||||||
\
|
|
||||||
return result; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
static ssize_t f_uac1_opts_##name##_store( \
|
|
||||||
struct config_item *item, \
|
|
||||||
const char *page, size_t len) \
|
|
||||||
{ \
|
|
||||||
struct f_uac1_opts *opts = to_f_uac1_opts(item); \
|
|
||||||
int ret; \
|
|
||||||
u32 num; \
|
|
||||||
\
|
|
||||||
mutex_lock(&opts->lock); \
|
|
||||||
if (opts->refcnt) { \
|
|
||||||
ret = -EBUSY; \
|
|
||||||
goto end; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
ret = kstrtou32(page, 0, &num); \
|
|
||||||
if (ret) \
|
|
||||||
goto end; \
|
|
||||||
\
|
|
||||||
opts->name = num; \
|
|
||||||
ret = len; \
|
|
||||||
\
|
|
||||||
end: \
|
|
||||||
mutex_unlock(&opts->lock); \
|
|
||||||
return ret; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
CONFIGFS_ATTR(f_uac1_opts_, name)
|
|
||||||
|
|
||||||
UAC1_ATTRIBUTE(c_chmask);
|
|
||||||
UAC1_ATTRIBUTE(c_srate);
|
|
||||||
UAC1_ATTRIBUTE(c_ssize);
|
|
||||||
UAC1_ATTRIBUTE(p_chmask);
|
|
||||||
UAC1_ATTRIBUTE(p_srate);
|
|
||||||
UAC1_ATTRIBUTE(p_ssize);
|
|
||||||
UAC1_ATTRIBUTE(req_number);
|
|
||||||
|
|
||||||
static struct configfs_attribute *f_uac1_attrs[] = {
|
static struct configfs_attribute *f_uac1_attrs[] = {
|
||||||
&f_uac1_opts_attr_c_chmask,
|
&f_uac_opts_attr_c_chmask,
|
||||||
&f_uac1_opts_attr_c_srate,
|
&f_uac_opts_attr_c_srate,
|
||||||
&f_uac1_opts_attr_c_ssize,
|
&f_uac_opts_attr_c_ssize,
|
||||||
&f_uac1_opts_attr_p_chmask,
|
&f_uac_opts_attr_p_chmask,
|
||||||
&f_uac1_opts_attr_p_srate,
|
&f_uac_opts_attr_p_srate,
|
||||||
&f_uac1_opts_attr_p_ssize,
|
&f_uac_opts_attr_p_ssize,
|
||||||
&f_uac1_opts_attr_req_number,
|
&f_uac_opts_attr_req_number,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -730,15 +663,15 @@ static const struct config_item_type f_uac1_func_type = {
|
|||||||
|
|
||||||
static void f_audio_free_inst(struct usb_function_instance *f)
|
static void f_audio_free_inst(struct usb_function_instance *f)
|
||||||
{
|
{
|
||||||
struct f_uac1_opts *opts;
|
struct f_uac_opts *opts;
|
||||||
|
|
||||||
opts = container_of(f, struct f_uac1_opts, func_inst);
|
opts = container_of(f, struct f_uac_opts, func_inst);
|
||||||
kfree(opts);
|
kfree(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_function_instance *f_audio_alloc_inst(void)
|
static struct usb_function_instance *f_audio_alloc_inst(void)
|
||||||
{
|
{
|
||||||
struct f_uac1_opts *opts;
|
struct f_uac_opts *opts;
|
||||||
|
|
||||||
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
|
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
|
||||||
if (!opts)
|
if (!opts)
|
||||||
@@ -750,23 +683,23 @@ static struct usb_function_instance *f_audio_alloc_inst(void)
|
|||||||
config_group_init_type_name(&opts->func_inst.group, "",
|
config_group_init_type_name(&opts->func_inst.group, "",
|
||||||
&f_uac1_func_type);
|
&f_uac1_func_type);
|
||||||
|
|
||||||
opts->c_chmask = UAC1_DEF_CCHMASK;
|
opts->c_chmask = UAC_DEF_CCHMASK;
|
||||||
opts->c_srate = UAC1_DEF_CSRATE;
|
opts->c_srate = UAC_DEF_CSRATE;
|
||||||
opts->c_ssize = UAC1_DEF_CSSIZE;
|
opts->c_ssize = UAC_DEF_CSSIZE;
|
||||||
opts->p_chmask = UAC1_DEF_PCHMASK;
|
opts->p_chmask = UAC_DEF_PCHMASK;
|
||||||
opts->p_srate = UAC1_DEF_PSRATE;
|
opts->p_srate = UAC_DEF_PSRATE;
|
||||||
opts->p_ssize = UAC1_DEF_PSSIZE;
|
opts->p_ssize = UAC_DEF_PSSIZE;
|
||||||
opts->req_number = UAC1_DEF_REQ_NUM;
|
opts->req_number = UAC_DEF_REQ_NUM;
|
||||||
return &opts->func_inst;
|
return &opts->func_inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void f_audio_free(struct usb_function *f)
|
static void f_audio_free(struct usb_function *f)
|
||||||
{
|
{
|
||||||
struct g_audio *audio;
|
struct g_audio *audio;
|
||||||
struct f_uac1_opts *opts;
|
struct f_uac_opts *opts;
|
||||||
|
|
||||||
audio = func_to_g_audio(f);
|
audio = func_to_g_audio(f);
|
||||||
opts = container_of(f->fi, struct f_uac1_opts, func_inst);
|
opts = container_of(f->fi, struct f_uac_opts, func_inst);
|
||||||
kfree(audio);
|
kfree(audio);
|
||||||
mutex_lock(&opts->lock);
|
mutex_lock(&opts->lock);
|
||||||
--opts->refcnt;
|
--opts->refcnt;
|
||||||
@@ -785,15 +718,15 @@ static void f_audio_unbind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
|
|
||||||
static struct usb_function *f_audio_alloc(struct usb_function_instance *fi)
|
static struct usb_function *f_audio_alloc(struct usb_function_instance *fi)
|
||||||
{
|
{
|
||||||
struct f_uac1 *uac1;
|
struct f_uac *uac1;
|
||||||
struct f_uac1_opts *opts;
|
struct f_uac_opts *opts;
|
||||||
|
|
||||||
/* allocate and initialize one new instance */
|
/* allocate and initialize one new instance */
|
||||||
uac1 = kzalloc(sizeof(*uac1), GFP_KERNEL);
|
uac1 = kzalloc(sizeof(*uac1), GFP_KERNEL);
|
||||||
if (!uac1)
|
if (!uac1)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
opts = container_of(fi, struct f_uac1_opts, func_inst);
|
opts = container_of(fi, struct f_uac_opts, func_inst);
|
||||||
mutex_lock(&opts->lock);
|
mutex_lock(&opts->lock);
|
||||||
++opts->refcnt;
|
++opts->refcnt;
|
||||||
mutex_unlock(&opts->lock);
|
mutex_unlock(&opts->lock);
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#include <linux/module.h>
|
#include <linux/module.h>
|
||||||
|
|
||||||
#include "u_audio.h"
|
#include "u_audio.h"
|
||||||
#include "u_uac2.h"
|
#include "u_uac.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The driver implements a simple UAC_2 topology.
|
* The driver implements a simple UAC_2 topology.
|
||||||
@@ -42,23 +42,6 @@
|
|||||||
#define EPIN_EN(_opts) ((_opts)->p_chmask != 0)
|
#define EPIN_EN(_opts) ((_opts)->p_chmask != 0)
|
||||||
#define EPOUT_EN(_opts) ((_opts)->c_chmask != 0)
|
#define EPOUT_EN(_opts) ((_opts)->c_chmask != 0)
|
||||||
|
|
||||||
struct f_uac2 {
|
|
||||||
struct g_audio g_audio;
|
|
||||||
u8 ac_intf, as_in_intf, as_out_intf;
|
|
||||||
u8 ac_alt, as_in_alt, as_out_alt; /* needed for get_alt() */
|
|
||||||
};
|
|
||||||
|
|
||||||
static inline struct f_uac2 *func_to_uac2(struct usb_function *f)
|
|
||||||
{
|
|
||||||
return container_of(f, struct f_uac2, g_audio.func);
|
|
||||||
}
|
|
||||||
|
|
||||||
static inline
|
|
||||||
struct f_uac2_opts *g_audio_to_uac2_opts(struct g_audio *agdev)
|
|
||||||
{
|
|
||||||
return container_of(agdev->func.fi, struct f_uac2_opts, func_inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* --------- USB Function Interface ------------- */
|
/* --------- USB Function Interface ------------- */
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -447,7 +430,7 @@ struct cntrl_range_lay3 {
|
|||||||
__le32 dRES;
|
__le32 dRES;
|
||||||
} __packed;
|
} __packed;
|
||||||
|
|
||||||
static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
|
static void set_ep_max_packet_size(const struct f_uac_opts *uac2_opts,
|
||||||
struct usb_endpoint_descriptor *ep_desc,
|
struct usb_endpoint_descriptor *ep_desc,
|
||||||
unsigned int factor, bool is_playback)
|
unsigned int factor, bool is_playback)
|
||||||
{
|
{
|
||||||
@@ -473,7 +456,7 @@ static void set_ep_max_packet_size(const struct f_uac2_opts *uac2_opts,
|
|||||||
/* Use macro to overcome line length limitation */
|
/* Use macro to overcome line length limitation */
|
||||||
#define USBDHDR(p) (struct usb_descriptor_header *)(p)
|
#define USBDHDR(p) (struct usb_descriptor_header *)(p)
|
||||||
|
|
||||||
static void setup_descriptor(struct f_uac2_opts *opts)
|
static void setup_descriptor(struct f_uac_opts *opts)
|
||||||
{
|
{
|
||||||
/* patch descriptors */
|
/* patch descriptors */
|
||||||
int i = 1; /* ID's start with 1 */
|
int i = 1; /* ID's start with 1 */
|
||||||
@@ -592,16 +575,16 @@ static void setup_descriptor(struct f_uac2_opts *opts)
|
|||||||
static int
|
static int
|
||||||
afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
|
afunc_bind(struct usb_configuration *cfg, struct usb_function *fn)
|
||||||
{
|
{
|
||||||
struct f_uac2 *uac2 = func_to_uac2(fn);
|
struct f_uac *uac2 = func_to_uac(fn);
|
||||||
struct g_audio *agdev = func_to_g_audio(fn);
|
struct g_audio *agdev = func_to_g_audio(fn);
|
||||||
struct usb_composite_dev *cdev = cfg->cdev;
|
struct usb_composite_dev *cdev = cfg->cdev;
|
||||||
struct usb_gadget *gadget = cdev->gadget;
|
struct usb_gadget *gadget = cdev->gadget;
|
||||||
struct device *dev = &gadget->dev;
|
struct device *dev = &gadget->dev;
|
||||||
struct f_uac2_opts *uac2_opts;
|
struct f_uac_opts *uac2_opts;
|
||||||
struct usb_string *us;
|
struct usb_string *us;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
uac2_opts = container_of(fn->fi, struct f_uac2_opts, func_inst);
|
uac2_opts = container_of(fn->fi, struct f_uac_opts, func_inst);
|
||||||
|
|
||||||
us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn));
|
us = usb_gstrings_attach(cdev, fn_strings, ARRAY_SIZE(strings_fn));
|
||||||
if (IS_ERR(us))
|
if (IS_ERR(us))
|
||||||
@@ -735,7 +718,7 @@ static int
|
|||||||
afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
|
afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
|
||||||
{
|
{
|
||||||
struct usb_composite_dev *cdev = fn->config->cdev;
|
struct usb_composite_dev *cdev = fn->config->cdev;
|
||||||
struct f_uac2 *uac2 = func_to_uac2(fn);
|
struct f_uac *uac2 = func_to_uac(fn);
|
||||||
struct usb_gadget *gadget = cdev->gadget;
|
struct usb_gadget *gadget = cdev->gadget;
|
||||||
struct device *dev = &gadget->dev;
|
struct device *dev = &gadget->dev;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@@ -780,7 +763,7 @@ afunc_set_alt(struct usb_function *fn, unsigned intf, unsigned alt)
|
|||||||
static int
|
static int
|
||||||
afunc_get_alt(struct usb_function *fn, unsigned intf)
|
afunc_get_alt(struct usb_function *fn, unsigned intf)
|
||||||
{
|
{
|
||||||
struct f_uac2 *uac2 = func_to_uac2(fn);
|
struct f_uac *uac2 = func_to_uac(fn);
|
||||||
struct g_audio *agdev = func_to_g_audio(fn);
|
struct g_audio *agdev = func_to_g_audio(fn);
|
||||||
|
|
||||||
if (intf == uac2->ac_intf)
|
if (intf == uac2->ac_intf)
|
||||||
@@ -800,7 +783,7 @@ afunc_get_alt(struct usb_function *fn, unsigned intf)
|
|||||||
static void
|
static void
|
||||||
afunc_disable(struct usb_function *fn)
|
afunc_disable(struct usb_function *fn)
|
||||||
{
|
{
|
||||||
struct f_uac2 *uac2 = func_to_uac2(fn);
|
struct f_uac *uac2 = func_to_uac(fn);
|
||||||
|
|
||||||
uac2->as_in_alt = 0;
|
uac2->as_in_alt = 0;
|
||||||
uac2->as_out_alt = 0;
|
uac2->as_out_alt = 0;
|
||||||
@@ -813,7 +796,7 @@ in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr)
|
|||||||
{
|
{
|
||||||
struct usb_request *req = fn->config->cdev->req;
|
struct usb_request *req = fn->config->cdev->req;
|
||||||
struct g_audio *agdev = func_to_g_audio(fn);
|
struct g_audio *agdev = func_to_g_audio(fn);
|
||||||
struct f_uac2_opts *opts;
|
struct f_uac_opts *opts;
|
||||||
u16 w_length = le16_to_cpu(cr->wLength);
|
u16 w_length = le16_to_cpu(cr->wLength);
|
||||||
u16 w_index = le16_to_cpu(cr->wIndex);
|
u16 w_index = le16_to_cpu(cr->wIndex);
|
||||||
u16 w_value = le16_to_cpu(cr->wValue);
|
u16 w_value = le16_to_cpu(cr->wValue);
|
||||||
@@ -822,7 +805,7 @@ in_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr)
|
|||||||
int value = -EOPNOTSUPP;
|
int value = -EOPNOTSUPP;
|
||||||
int p_srate, c_srate;
|
int p_srate, c_srate;
|
||||||
|
|
||||||
opts = g_audio_to_uac2_opts(agdev);
|
opts = g_audio_to_uac_opts(agdev);
|
||||||
p_srate = opts->p_srate;
|
p_srate = opts->p_srate;
|
||||||
c_srate = opts->c_srate;
|
c_srate = opts->c_srate;
|
||||||
|
|
||||||
@@ -854,7 +837,7 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr)
|
|||||||
{
|
{
|
||||||
struct usb_request *req = fn->config->cdev->req;
|
struct usb_request *req = fn->config->cdev->req;
|
||||||
struct g_audio *agdev = func_to_g_audio(fn);
|
struct g_audio *agdev = func_to_g_audio(fn);
|
||||||
struct f_uac2_opts *opts;
|
struct f_uac_opts *opts;
|
||||||
u16 w_length = le16_to_cpu(cr->wLength);
|
u16 w_length = le16_to_cpu(cr->wLength);
|
||||||
u16 w_index = le16_to_cpu(cr->wIndex);
|
u16 w_index = le16_to_cpu(cr->wIndex);
|
||||||
u16 w_value = le16_to_cpu(cr->wValue);
|
u16 w_value = le16_to_cpu(cr->wValue);
|
||||||
@@ -864,7 +847,7 @@ in_rq_range(struct usb_function *fn, const struct usb_ctrlrequest *cr)
|
|||||||
int value = -EOPNOTSUPP;
|
int value = -EOPNOTSUPP;
|
||||||
int p_srate, c_srate;
|
int p_srate, c_srate;
|
||||||
|
|
||||||
opts = g_audio_to_uac2_opts(agdev);
|
opts = g_audio_to_uac_opts(agdev);
|
||||||
p_srate = opts->p_srate;
|
p_srate = opts->p_srate;
|
||||||
c_srate = opts->c_srate;
|
c_srate = opts->c_srate;
|
||||||
|
|
||||||
@@ -918,7 +901,7 @@ out_rq_cur(struct usb_function *fn, const struct usb_ctrlrequest *cr)
|
|||||||
static int
|
static int
|
||||||
setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr)
|
setup_rq_inf(struct usb_function *fn, const struct usb_ctrlrequest *cr)
|
||||||
{
|
{
|
||||||
struct f_uac2 *uac2 = func_to_uac2(fn);
|
struct f_uac *uac2 = func_to_uac(fn);
|
||||||
struct g_audio *agdev = func_to_g_audio(fn);
|
struct g_audio *agdev = func_to_g_audio(fn);
|
||||||
u16 w_index = le16_to_cpu(cr->wIndex);
|
u16 w_index = le16_to_cpu(cr->wIndex);
|
||||||
u8 intf = w_index & 0xff;
|
u8 intf = w_index & 0xff;
|
||||||
@@ -970,80 +953,26 @@ afunc_setup(struct usb_function *fn, const struct usb_ctrlrequest *cr)
|
|||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline struct f_uac2_opts *to_f_uac2_opts(struct config_item *item)
|
|
||||||
{
|
|
||||||
return container_of(to_config_group(item), struct f_uac2_opts,
|
|
||||||
func_inst.group);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void f_uac2_attr_release(struct config_item *item)
|
|
||||||
{
|
|
||||||
struct f_uac2_opts *opts = to_f_uac2_opts(item);
|
|
||||||
|
|
||||||
usb_put_function_instance(&opts->func_inst);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct configfs_item_operations f_uac2_item_ops = {
|
static struct configfs_item_operations f_uac2_item_ops = {
|
||||||
.release = f_uac2_attr_release,
|
.release = f_uac_attr_release,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define UAC2_ATTRIBUTE(name) \
|
UAC_ATTRIBUTE(p_chmask);
|
||||||
static ssize_t f_uac2_opts_##name##_show(struct config_item *item, \
|
UAC_ATTRIBUTE(p_srate);
|
||||||
char *page) \
|
UAC_ATTRIBUTE(p_ssize);
|
||||||
{ \
|
UAC_ATTRIBUTE(c_chmask);
|
||||||
struct f_uac2_opts *opts = to_f_uac2_opts(item); \
|
UAC_ATTRIBUTE(c_srate);
|
||||||
int result; \
|
UAC_ATTRIBUTE(c_ssize);
|
||||||
\
|
UAC_ATTRIBUTE(req_number);
|
||||||
mutex_lock(&opts->lock); \
|
|
||||||
result = sprintf(page, "%u\n", opts->name); \
|
|
||||||
mutex_unlock(&opts->lock); \
|
|
||||||
\
|
|
||||||
return result; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
static ssize_t f_uac2_opts_##name##_store(struct config_item *item, \
|
|
||||||
const char *page, size_t len) \
|
|
||||||
{ \
|
|
||||||
struct f_uac2_opts *opts = to_f_uac2_opts(item); \
|
|
||||||
int ret; \
|
|
||||||
u32 num; \
|
|
||||||
\
|
|
||||||
mutex_lock(&opts->lock); \
|
|
||||||
if (opts->refcnt) { \
|
|
||||||
ret = -EBUSY; \
|
|
||||||
goto end; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
ret = kstrtou32(page, 0, &num); \
|
|
||||||
if (ret) \
|
|
||||||
goto end; \
|
|
||||||
\
|
|
||||||
opts->name = num; \
|
|
||||||
ret = len; \
|
|
||||||
\
|
|
||||||
end: \
|
|
||||||
mutex_unlock(&opts->lock); \
|
|
||||||
return ret; \
|
|
||||||
} \
|
|
||||||
\
|
|
||||||
CONFIGFS_ATTR(f_uac2_opts_, name)
|
|
||||||
|
|
||||||
UAC2_ATTRIBUTE(p_chmask);
|
|
||||||
UAC2_ATTRIBUTE(p_srate);
|
|
||||||
UAC2_ATTRIBUTE(p_ssize);
|
|
||||||
UAC2_ATTRIBUTE(c_chmask);
|
|
||||||
UAC2_ATTRIBUTE(c_srate);
|
|
||||||
UAC2_ATTRIBUTE(c_ssize);
|
|
||||||
UAC2_ATTRIBUTE(req_number);
|
|
||||||
|
|
||||||
static struct configfs_attribute *f_uac2_attrs[] = {
|
static struct configfs_attribute *f_uac2_attrs[] = {
|
||||||
&f_uac2_opts_attr_p_chmask,
|
&f_uac_opts_attr_p_chmask,
|
||||||
&f_uac2_opts_attr_p_srate,
|
&f_uac_opts_attr_p_srate,
|
||||||
&f_uac2_opts_attr_p_ssize,
|
&f_uac_opts_attr_p_ssize,
|
||||||
&f_uac2_opts_attr_c_chmask,
|
&f_uac_opts_attr_c_chmask,
|
||||||
&f_uac2_opts_attr_c_srate,
|
&f_uac_opts_attr_c_srate,
|
||||||
&f_uac2_opts_attr_c_ssize,
|
&f_uac_opts_attr_c_ssize,
|
||||||
&f_uac2_opts_attr_req_number,
|
&f_uac_opts_attr_req_number,
|
||||||
NULL,
|
NULL,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1055,15 +984,15 @@ static const struct config_item_type f_uac2_func_type = {
|
|||||||
|
|
||||||
static void afunc_free_inst(struct usb_function_instance *f)
|
static void afunc_free_inst(struct usb_function_instance *f)
|
||||||
{
|
{
|
||||||
struct f_uac2_opts *opts;
|
struct f_uac_opts *opts;
|
||||||
|
|
||||||
opts = container_of(f, struct f_uac2_opts, func_inst);
|
opts = container_of(f, struct f_uac_opts, func_inst);
|
||||||
kfree(opts);
|
kfree(opts);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct usb_function_instance *afunc_alloc_inst(void)
|
static struct usb_function_instance *afunc_alloc_inst(void)
|
||||||
{
|
{
|
||||||
struct f_uac2_opts *opts;
|
struct f_uac_opts *opts;
|
||||||
|
|
||||||
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
|
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
|
||||||
if (!opts)
|
if (!opts)
|
||||||
@@ -1075,23 +1004,23 @@ static struct usb_function_instance *afunc_alloc_inst(void)
|
|||||||
config_group_init_type_name(&opts->func_inst.group, "",
|
config_group_init_type_name(&opts->func_inst.group, "",
|
||||||
&f_uac2_func_type);
|
&f_uac2_func_type);
|
||||||
|
|
||||||
opts->p_chmask = UAC2_DEF_PCHMASK;
|
opts->p_chmask = UAC_DEF_PCHMASK;
|
||||||
opts->p_srate = UAC2_DEF_PSRATE;
|
opts->p_srate = UAC_DEF_PSRATE;
|
||||||
opts->p_ssize = UAC2_DEF_PSSIZE;
|
opts->p_ssize = UAC_DEF_PSSIZE;
|
||||||
opts->c_chmask = UAC2_DEF_CCHMASK;
|
opts->c_chmask = UAC_DEF_CCHMASK;
|
||||||
opts->c_srate = UAC2_DEF_CSRATE;
|
opts->c_srate = UAC_DEF_CSRATE;
|
||||||
opts->c_ssize = UAC2_DEF_CSSIZE;
|
opts->c_ssize = UAC_DEF_CSSIZE;
|
||||||
opts->req_number = UAC2_DEF_REQ_NUM;
|
opts->req_number = UAC_DEF_REQ_NUM;
|
||||||
return &opts->func_inst;
|
return &opts->func_inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void afunc_free(struct usb_function *f)
|
static void afunc_free(struct usb_function *f)
|
||||||
{
|
{
|
||||||
struct g_audio *agdev;
|
struct g_audio *agdev;
|
||||||
struct f_uac2_opts *opts;
|
struct f_uac_opts *opts;
|
||||||
|
|
||||||
agdev = func_to_g_audio(f);
|
agdev = func_to_g_audio(f);
|
||||||
opts = container_of(f->fi, struct f_uac2_opts, func_inst);
|
opts = container_of(f->fi, struct f_uac_opts, func_inst);
|
||||||
kfree(agdev);
|
kfree(agdev);
|
||||||
mutex_lock(&opts->lock);
|
mutex_lock(&opts->lock);
|
||||||
--opts->refcnt;
|
--opts->refcnt;
|
||||||
@@ -1110,14 +1039,14 @@ static void afunc_unbind(struct usb_configuration *c, struct usb_function *f)
|
|||||||
|
|
||||||
static struct usb_function *afunc_alloc(struct usb_function_instance *fi)
|
static struct usb_function *afunc_alloc(struct usb_function_instance *fi)
|
||||||
{
|
{
|
||||||
struct f_uac2 *uac2;
|
struct f_uac *uac2;
|
||||||
struct f_uac2_opts *opts;
|
struct f_uac_opts *opts;
|
||||||
|
|
||||||
uac2 = kzalloc(sizeof(*uac2), GFP_KERNEL);
|
uac2 = kzalloc(sizeof(*uac2), GFP_KERNEL);
|
||||||
if (uac2 == NULL)
|
if (uac2 == NULL)
|
||||||
return ERR_PTR(-ENOMEM);
|
return ERR_PTR(-ENOMEM);
|
||||||
|
|
||||||
opts = container_of(fi, struct f_uac2_opts, func_inst);
|
opts = container_of(fi, struct f_uac_opts, func_inst);
|
||||||
mutex_lock(&opts->lock);
|
mutex_lock(&opts->lock);
|
||||||
++opts->refcnt;
|
++opts->refcnt;
|
||||||
mutex_unlock(&opts->lock);
|
mutex_unlock(&opts->lock);
|
||||||
|
|||||||
@@ -361,7 +361,6 @@ static inline void free_ep(struct uac_rtd_params *prm, struct usb_ep *ep)
|
|||||||
dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__);
|
dev_err(uac->card->dev, "%s:%d Error!\n", __func__, __LINE__);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int u_audio_start_capture(struct g_audio *audio_dev)
|
int u_audio_start_capture(struct g_audio *audio_dev)
|
||||||
{
|
{
|
||||||
struct snd_uac_chip *uac = audio_dev->uac;
|
struct snd_uac_chip *uac = audio_dev->uac;
|
||||||
|
|||||||
115
drivers/usb/gadget/function/u_uac.h
Normal file
115
drivers/usb/gadget/function/u_uac.h
Normal file
@@ -0,0 +1,115 @@
|
|||||||
|
/*
|
||||||
|
* u_uac.h - Utility definitions for UAC function
|
||||||
|
*
|
||||||
|
* Copyright (C) 2016 Ruslan Bilovol <ruslan.bilovol@gmail.com>
|
||||||
|
* Copyright (C) 2017 Julian Scheel <julian@juss.de>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License version 2 as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __U_UAC_H
|
||||||
|
#define __U_UAC_H
|
||||||
|
|
||||||
|
#include <linux/usb/composite.h>
|
||||||
|
|
||||||
|
#define UAC_DEF_CCHMASK 0x3
|
||||||
|
#define UAC_DEF_CSRATE 48000
|
||||||
|
#define UAC_DEF_CSSIZE 2
|
||||||
|
#define UAC_DEF_PCHMASK 0x3
|
||||||
|
#define UAC_DEF_PSRATE 48000
|
||||||
|
#define UAC_DEF_PSSIZE 2
|
||||||
|
#define UAC_DEF_REQ_NUM 2
|
||||||
|
|
||||||
|
#define UAC1_OUT_EP_MAX_PACKET_SIZE 200
|
||||||
|
|
||||||
|
struct f_uac_opts {
|
||||||
|
struct usb_function_instance func_inst;
|
||||||
|
int c_chmask;
|
||||||
|
int c_srate;
|
||||||
|
int c_ssize;
|
||||||
|
int p_chmask;
|
||||||
|
int p_srate;
|
||||||
|
int p_ssize;
|
||||||
|
int req_number;
|
||||||
|
unsigned bound:1;
|
||||||
|
|
||||||
|
struct mutex lock;
|
||||||
|
int refcnt;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define UAC_ATTRIBUTE(name) \
|
||||||
|
static ssize_t f_uac_opts_##name##_show( \
|
||||||
|
struct config_item *item, \
|
||||||
|
char *page) \
|
||||||
|
{ \
|
||||||
|
struct f_uac_opts *opts = to_f_uac_opts(item); \
|
||||||
|
int result; \
|
||||||
|
\
|
||||||
|
mutex_lock(&opts->lock); \
|
||||||
|
result = sprintf(page, "%u\n", opts->name); \
|
||||||
|
mutex_unlock(&opts->lock); \
|
||||||
|
\
|
||||||
|
return result; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
static ssize_t f_uac_opts_##name##_store( \
|
||||||
|
struct config_item *item, \
|
||||||
|
const char *page, size_t len) \
|
||||||
|
{ \
|
||||||
|
struct f_uac_opts *opts = to_f_uac_opts(item); \
|
||||||
|
int ret; \
|
||||||
|
u32 num; \
|
||||||
|
\
|
||||||
|
mutex_lock(&opts->lock); \
|
||||||
|
if (opts->refcnt) { \
|
||||||
|
ret = -EBUSY; \
|
||||||
|
goto end; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
ret = kstrtou32(page, 0, &num); \
|
||||||
|
if (ret) \
|
||||||
|
goto end; \
|
||||||
|
\
|
||||||
|
opts->name = num; \
|
||||||
|
ret = len; \
|
||||||
|
\
|
||||||
|
end: \
|
||||||
|
mutex_unlock(&opts->lock); \
|
||||||
|
return ret; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
CONFIGFS_ATTR(f_uac_opts_, name)
|
||||||
|
|
||||||
|
struct f_uac {
|
||||||
|
struct g_audio g_audio;
|
||||||
|
u8 ac_intf, as_in_intf, as_out_intf;
|
||||||
|
u8 ac_alt, as_in_alt, as_out_alt; /* needed for get_alt() */
|
||||||
|
};
|
||||||
|
|
||||||
|
static inline struct f_uac *func_to_uac(struct usb_function *f)
|
||||||
|
{
|
||||||
|
return container_of(f, struct f_uac, g_audio.func);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline
|
||||||
|
struct f_uac_opts *g_audio_to_uac_opts(struct g_audio *agdev)
|
||||||
|
{
|
||||||
|
return container_of(agdev->func.fi, struct f_uac_opts, func_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline struct f_uac_opts *to_f_uac_opts(struct config_item *item)
|
||||||
|
{
|
||||||
|
return container_of(to_config_group(item), struct f_uac_opts,
|
||||||
|
func_inst.group);
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline void f_uac_attr_release(struct config_item *item)
|
||||||
|
{
|
||||||
|
struct f_uac_opts *opts = to_f_uac_opts(item);
|
||||||
|
|
||||||
|
usb_put_function_instance(&opts->func_inst);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif /* __U_UAC_H */
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* u_uac1.h - Utility definitions for UAC1 function
|
|
||||||
*
|
|
||||||
* Copyright (C) 2016 Ruslan Bilovol <ruslan.bilovol@gmail.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __U_UAC1_H
|
|
||||||
#define __U_UAC1_H
|
|
||||||
|
|
||||||
#include <linux/usb/composite.h>
|
|
||||||
|
|
||||||
#define UAC1_OUT_EP_MAX_PACKET_SIZE 200
|
|
||||||
#define UAC1_DEF_CCHMASK 0x3
|
|
||||||
#define UAC1_DEF_CSRATE 48000
|
|
||||||
#define UAC1_DEF_CSSIZE 2
|
|
||||||
#define UAC1_DEF_PCHMASK 0x3
|
|
||||||
#define UAC1_DEF_PSRATE 48000
|
|
||||||
#define UAC1_DEF_PSSIZE 2
|
|
||||||
#define UAC1_DEF_REQ_NUM 2
|
|
||||||
|
|
||||||
|
|
||||||
struct f_uac1_opts {
|
|
||||||
struct usb_function_instance func_inst;
|
|
||||||
int c_chmask;
|
|
||||||
int c_srate;
|
|
||||||
int c_ssize;
|
|
||||||
int p_chmask;
|
|
||||||
int p_srate;
|
|
||||||
int p_ssize;
|
|
||||||
int req_number;
|
|
||||||
unsigned bound:1;
|
|
||||||
|
|
||||||
struct mutex lock;
|
|
||||||
int refcnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif /* __U_UAC1_H */
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
// SPDX-License-Identifier: GPL-2.0
|
|
||||||
/*
|
|
||||||
* u_uac2.h
|
|
||||||
*
|
|
||||||
* Utility definitions for UAC2 function
|
|
||||||
*
|
|
||||||
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
|
|
||||||
* http://www.samsung.com
|
|
||||||
*
|
|
||||||
* Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef U_UAC2_H
|
|
||||||
#define U_UAC2_H
|
|
||||||
|
|
||||||
#include <linux/usb/composite.h>
|
|
||||||
|
|
||||||
#define UAC2_DEF_PCHMASK 0x3
|
|
||||||
#define UAC2_DEF_PSRATE 48000
|
|
||||||
#define UAC2_DEF_PSSIZE 2
|
|
||||||
#define UAC2_DEF_CCHMASK 0x3
|
|
||||||
#define UAC2_DEF_CSRATE 64000
|
|
||||||
#define UAC2_DEF_CSSIZE 2
|
|
||||||
#define UAC2_DEF_REQ_NUM 2
|
|
||||||
|
|
||||||
struct f_uac2_opts {
|
|
||||||
struct usb_function_instance func_inst;
|
|
||||||
int p_chmask;
|
|
||||||
int p_srate;
|
|
||||||
int p_ssize;
|
|
||||||
int c_chmask;
|
|
||||||
int c_srate;
|
|
||||||
int c_ssize;
|
|
||||||
int req_number;
|
|
||||||
bool bound;
|
|
||||||
|
|
||||||
struct mutex lock;
|
|
||||||
int refcnt;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -17,69 +17,36 @@
|
|||||||
|
|
||||||
USB_GADGET_COMPOSITE_OPTIONS();
|
USB_GADGET_COMPOSITE_OPTIONS();
|
||||||
|
|
||||||
#ifndef CONFIG_GADGET_UAC1
|
#if !defined(CONFIG_GADGET_UAC1) || !defined(CONFIG_GADGET_UAC1_LEGACY)
|
||||||
#include "u_uac2.h"
|
#include "u_uac.h"
|
||||||
|
|
||||||
/* Playback(USB-IN) Default Stereo - Fl/Fr */
|
/* Playback(USB-IN) Default Stereo - Fl/Fr */
|
||||||
static int p_chmask = UAC2_DEF_PCHMASK;
|
static int p_chmask = UAC_DEF_PCHMASK;
|
||||||
module_param(p_chmask, uint, S_IRUGO);
|
module_param(p_chmask, uint, S_IRUGO);
|
||||||
MODULE_PARM_DESC(p_chmask, "Playback Channel Mask");
|
MODULE_PARM_DESC(p_chmask, "Playback Channel Mask");
|
||||||
|
|
||||||
/* Playback Default 48 KHz */
|
/* Playback Default 48 KHz */
|
||||||
static int p_srate = UAC2_DEF_PSRATE;
|
static int p_srate = UAC_DEF_PSRATE;
|
||||||
module_param(p_srate, uint, S_IRUGO);
|
module_param(p_srate, uint, S_IRUGO);
|
||||||
MODULE_PARM_DESC(p_srate, "Playback Sampling Rate");
|
MODULE_PARM_DESC(p_srate, "Playback Sampling Rate");
|
||||||
|
|
||||||
/* Playback Default 16bits/sample */
|
/* Playback Default 16bits/sample */
|
||||||
static int p_ssize = UAC2_DEF_PSSIZE;
|
static int p_ssize = UAC_DEF_PSSIZE;
|
||||||
module_param(p_ssize, uint, S_IRUGO);
|
module_param(p_ssize, uint, S_IRUGO);
|
||||||
MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)");
|
MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)");
|
||||||
|
|
||||||
/* Capture(USB-OUT) Default Stereo - Fl/Fr */
|
/* Capture(USB-OUT) Default Stereo - Fl/Fr */
|
||||||
static int c_chmask = UAC2_DEF_CCHMASK;
|
static int c_chmask = UAC_DEF_CCHMASK;
|
||||||
module_param(c_chmask, uint, S_IRUGO);
|
module_param(c_chmask, uint, S_IRUGO);
|
||||||
MODULE_PARM_DESC(c_chmask, "Capture Channel Mask");
|
MODULE_PARM_DESC(c_chmask, "Capture Channel Mask");
|
||||||
|
|
||||||
/* Capture Default 64 KHz */
|
/* Capture Default 64 KHz */
|
||||||
static int c_srate = UAC2_DEF_CSRATE;
|
static int c_srate = UAC_DEF_CSRATE;
|
||||||
module_param(c_srate, uint, S_IRUGO);
|
module_param(c_srate, uint, S_IRUGO);
|
||||||
MODULE_PARM_DESC(c_srate, "Capture Sampling Rate");
|
MODULE_PARM_DESC(c_srate, "Capture Sampling Rate");
|
||||||
|
|
||||||
/* Capture Default 16bits/sample */
|
/* Capture Default 16bits/sample */
|
||||||
static int c_ssize = UAC2_DEF_CSSIZE;
|
static int c_ssize = UAC_DEF_CSSIZE;
|
||||||
module_param(c_ssize, uint, S_IRUGO);
|
|
||||||
MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)");
|
|
||||||
#else
|
|
||||||
#ifndef CONFIG_GADGET_UAC1_LEGACY
|
|
||||||
#include "u_uac1.h"
|
|
||||||
|
|
||||||
/* Playback(USB-IN) Default Stereo - Fl/Fr */
|
|
||||||
static int p_chmask = UAC1_DEF_PCHMASK;
|
|
||||||
module_param(p_chmask, uint, S_IRUGO);
|
|
||||||
MODULE_PARM_DESC(p_chmask, "Playback Channel Mask");
|
|
||||||
|
|
||||||
/* Playback Default 48 KHz */
|
|
||||||
static int p_srate = UAC1_DEF_PSRATE;
|
|
||||||
module_param(p_srate, uint, S_IRUGO);
|
|
||||||
MODULE_PARM_DESC(p_srate, "Playback Sampling Rate");
|
|
||||||
|
|
||||||
/* Playback Default 16bits/sample */
|
|
||||||
static int p_ssize = UAC1_DEF_PSSIZE;
|
|
||||||
module_param(p_ssize, uint, S_IRUGO);
|
|
||||||
MODULE_PARM_DESC(p_ssize, "Playback Sample Size(bytes)");
|
|
||||||
|
|
||||||
/* Capture(USB-OUT) Default Stereo - Fl/Fr */
|
|
||||||
static int c_chmask = UAC1_DEF_CCHMASK;
|
|
||||||
module_param(c_chmask, uint, S_IRUGO);
|
|
||||||
MODULE_PARM_DESC(c_chmask, "Capture Channel Mask");
|
|
||||||
|
|
||||||
/* Capture Default 48 KHz */
|
|
||||||
static int c_srate = UAC1_DEF_CSRATE;
|
|
||||||
module_param(c_srate, uint, S_IRUGO);
|
|
||||||
MODULE_PARM_DESC(c_srate, "Capture Sampling Rate");
|
|
||||||
|
|
||||||
/* Capture Default 16bits/sample */
|
|
||||||
static int c_ssize = UAC1_DEF_CSSIZE;
|
|
||||||
module_param(c_ssize, uint, S_IRUGO);
|
module_param(c_ssize, uint, S_IRUGO);
|
||||||
MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)");
|
MODULE_PARM_DESC(c_ssize, "Capture Sample Size(bytes)");
|
||||||
#else /* CONFIG_GADGET_UAC1_LEGACY */
|
#else /* CONFIG_GADGET_UAC1_LEGACY */
|
||||||
@@ -109,7 +76,6 @@ static int audio_buf_size = UAC1_AUDIO_BUF_SIZE;
|
|||||||
module_param(audio_buf_size, int, S_IRUGO);
|
module_param(audio_buf_size, int, S_IRUGO);
|
||||||
MODULE_PARM_DESC(audio_buf_size, "Audio buffer size");
|
MODULE_PARM_DESC(audio_buf_size, "Audio buffer size");
|
||||||
#endif /* CONFIG_GADGET_UAC1_LEGACY */
|
#endif /* CONFIG_GADGET_UAC1_LEGACY */
|
||||||
#endif
|
|
||||||
|
|
||||||
/* string IDs are assigned dynamically */
|
/* string IDs are assigned dynamically */
|
||||||
|
|
||||||
@@ -235,14 +201,10 @@ static struct usb_configuration audio_config_driver = {
|
|||||||
|
|
||||||
static int audio_bind(struct usb_composite_dev *cdev)
|
static int audio_bind(struct usb_composite_dev *cdev)
|
||||||
{
|
{
|
||||||
#ifndef CONFIG_GADGET_UAC1
|
#if !defined(CONFIG_GADGET_UAC1) || !defined(CONFIG_GADGET_UAC1_LEGACY)
|
||||||
struct f_uac2_opts *uac2_opts;
|
struct f_uac_opts *uac_opts;
|
||||||
#else
|
|
||||||
#ifndef CONFIG_GADGET_UAC1_LEGACY
|
|
||||||
struct f_uac1_opts *uac1_opts;
|
|
||||||
#else
|
#else
|
||||||
struct f_uac1_legacy_opts *uac1_opts;
|
struct f_uac1_legacy_opts *uac1_opts;
|
||||||
#endif
|
|
||||||
#endif
|
#endif
|
||||||
int status;
|
int status;
|
||||||
|
|
||||||
@@ -250,9 +212,11 @@ static int audio_bind(struct usb_composite_dev *cdev)
|
|||||||
fi_uac2 = usb_get_function_instance("uac2");
|
fi_uac2 = usb_get_function_instance("uac2");
|
||||||
if (IS_ERR(fi_uac2))
|
if (IS_ERR(fi_uac2))
|
||||||
return PTR_ERR(fi_uac2);
|
return PTR_ERR(fi_uac2);
|
||||||
|
uac_opts = container_of(fi_uac2, struct f_uac_opts, func_inst);
|
||||||
#else
|
#else
|
||||||
#ifndef CONFIG_GADGET_UAC1_LEGACY
|
#ifndef CONFIG_GADGET_UAC1_LEGACY
|
||||||
fi_uac1 = usb_get_function_instance("uac1");
|
fi_uac1 = usb_get_function_instance("uac1");
|
||||||
|
uac_opts = container_of(fi_uac1, struct f_uac_opts, func_inst);
|
||||||
#else
|
#else
|
||||||
fi_uac1 = usb_get_function_instance("uac1_legacy");
|
fi_uac1 = usb_get_function_instance("uac1_legacy");
|
||||||
#endif
|
#endif
|
||||||
@@ -260,25 +224,17 @@ static int audio_bind(struct usb_composite_dev *cdev)
|
|||||||
return PTR_ERR(fi_uac1);
|
return PTR_ERR(fi_uac1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef CONFIG_GADGET_UAC1
|
#if !defined(CONFIG_GADGET_UAC1) || !defined(CONFIG_GADGET_UAC1_LEGACY)
|
||||||
uac2_opts = container_of(fi_uac2, struct f_uac2_opts, func_inst);
|
memset(uac_opts, 0x0, sizeof(uac_opts));
|
||||||
uac2_opts->p_chmask = p_chmask;
|
uac_opts->p_chmask = p_chmask;
|
||||||
uac2_opts->p_srate = p_srate;
|
uac_opts->p_srate[0] = p_srate;
|
||||||
uac2_opts->p_ssize = p_ssize;
|
uac_opts->p_srate_active = p_srate;
|
||||||
uac2_opts->c_chmask = c_chmask;
|
uac_opts->p_ssize = p_ssize;
|
||||||
uac2_opts->c_srate = c_srate;
|
uac_opts->c_chmask = c_chmask;
|
||||||
uac2_opts->c_ssize = c_ssize;
|
uac_opts->c_srate[0] = c_srate;
|
||||||
uac2_opts->req_number = UAC2_DEF_REQ_NUM;
|
uac_opts->c_srate_active = c_srate;
|
||||||
#else
|
uac_opts->c_ssize = c_ssize;
|
||||||
#ifndef CONFIG_GADGET_UAC1_LEGACY
|
uac_opts->req_number = UAC_DEF_REQ_NUM;
|
||||||
uac1_opts = container_of(fi_uac1, struct f_uac1_opts, func_inst);
|
|
||||||
uac1_opts->p_chmask = p_chmask;
|
|
||||||
uac1_opts->p_srate = p_srate;
|
|
||||||
uac1_opts->p_ssize = p_ssize;
|
|
||||||
uac1_opts->c_chmask = c_chmask;
|
|
||||||
uac1_opts->c_srate = c_srate;
|
|
||||||
uac1_opts->c_ssize = c_ssize;
|
|
||||||
uac1_opts->req_number = UAC1_DEF_REQ_NUM;
|
|
||||||
#else /* CONFIG_GADGET_UAC1_LEGACY */
|
#else /* CONFIG_GADGET_UAC1_LEGACY */
|
||||||
uac1_opts = container_of(fi_uac1, struct f_uac1_legacy_opts, func_inst);
|
uac1_opts = container_of(fi_uac1, struct f_uac1_legacy_opts, func_inst);
|
||||||
uac1_opts->fn_play = fn_play;
|
uac1_opts->fn_play = fn_play;
|
||||||
@@ -288,7 +244,6 @@ static int audio_bind(struct usb_composite_dev *cdev)
|
|||||||
uac1_opts->req_count = req_count;
|
uac1_opts->req_count = req_count;
|
||||||
uac1_opts->audio_buf_size = audio_buf_size;
|
uac1_opts->audio_buf_size = audio_buf_size;
|
||||||
#endif /* CONFIG_GADGET_UAC1_LEGACY */
|
#endif /* CONFIG_GADGET_UAC1_LEGACY */
|
||||||
#endif
|
|
||||||
|
|
||||||
status = usb_string_ids_tab(cdev, strings_dev);
|
status = usb_string_ids_tab(cdev, strings_dev);
|
||||||
if (status < 0)
|
if (status < 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user