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

Commit 671d495b authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "USB: gadget: android: Integrate f_midi USB MIDI gadget driver part deux"

parents 19ef72f1 c34e22c4
Loading
Loading
Loading
Loading
+66 −0
Original line number Diff line number Diff line
@@ -39,6 +39,9 @@
#include "u_fs.h"
#include "u_ecm.h"
#include "u_ncm.h"
#ifdef CONFIG_SND_RAWMIDI
#include "f_midi.c"
#endif
#include "f_diag.c"
#include "f_qdss.c"
#include "f_rmnet.c"
@@ -81,6 +84,11 @@ static const char longname[] = "Gadget Android";
#define PRODUCT_ID		0x0001

#define ANDROID_DEVICE_NODE_NAME_LENGTH 11
/* f_midi configuration */
#define MIDI_INPUT_PORTS    1
#define MIDI_OUTPUT_PORTS   1
#define MIDI_BUFFER_SIZE    256
#define MIDI_QUEUE_LENGTH   32

struct android_usb_function {
	char *name;
@@ -2762,6 +2770,61 @@ static struct android_usb_function audio_source_function = {
	.bind_config	= audio_source_function_bind_config,
};

#ifdef CONFIG_SND_RAWMIDI
static int midi_function_init(struct android_usb_function *f,
					struct usb_composite_dev *cdev)
{
	struct midi_alsa_config *config;

	config = kzalloc(sizeof(struct midi_alsa_config), GFP_KERNEL);
	f->config = config;
	if (!config)
		return -ENOMEM;
	config->card = -1;
	config->device = -1;
	return 0;
}

static void midi_function_cleanup(struct android_usb_function *f)
{
	kfree(f->config);
}

static int midi_function_bind_config(struct android_usb_function *f,
						struct usb_configuration *c)
{
	struct midi_alsa_config *config = f->config;

	return f_midi_bind_config(c, SNDRV_DEFAULT_IDX1, SNDRV_DEFAULT_STR1,
			MIDI_INPUT_PORTS, MIDI_OUTPUT_PORTS, MIDI_BUFFER_SIZE,
			MIDI_QUEUE_LENGTH, config);
}

static ssize_t midi_alsa_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	struct android_usb_function *f = dev_get_drvdata(dev);
	struct midi_alsa_config *config = f->config;

	/* print ALSA card and device numbers */
	return sprintf(buf, "%d %d\n", config->card, config->device);
}

static DEVICE_ATTR(alsa, S_IRUGO, midi_alsa_show, NULL);

static struct device_attribute *midi_function_attributes[] = {
	&dev_attr_alsa,
	NULL
};

static struct android_usb_function midi_function = {
	.name		= "midi",
	.init		= midi_function_init,
	.cleanup	= midi_function_cleanup,
	.bind_config	= midi_function_bind_config,
	.attributes	= midi_function_attributes,
};
#endif
static struct android_usb_function *supported_functions[] = {
	&ffs_function,
	&mbim_function,
@@ -2786,6 +2849,9 @@ static struct android_usb_function *supported_functions[] = {
	&accessory_function,
	&audio_source_function,
	&charger_function,
#ifdef CONFIG_SND_RAWMIDI
	&midi_function,
#endif
	NULL
};

+32 −16
Original line number Diff line number Diff line
@@ -67,6 +67,11 @@ struct gmidi_in_port {
	uint8_t data[2];
};

struct midi_alsa_config {
	int	card;
	int	device;
};

struct f_midi {
	struct usb_function	func;
	struct usb_gadget	*gadget;
@@ -99,7 +104,7 @@ DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16);

/* B.3.1  Standard AC Interface Descriptor */
static struct usb_interface_descriptor ac_interface_desc __initdata = {
static struct usb_interface_descriptor ac_interface_desc /* __initdata */ = {
	.bLength =		USB_DT_INTERFACE_SIZE,
	.bDescriptorType =	USB_DT_INTERFACE,
	/* .bInterfaceNumber =	DYNAMIC */
@@ -110,7 +115,7 @@ static struct usb_interface_descriptor ac_interface_desc __initdata = {
};

/* B.3.2  Class-Specific AC Interface Descriptor */
static struct uac1_ac_header_descriptor_1 ac_header_desc __initdata = {
static struct uac1_ac_header_descriptor_1 ac_header_desc /* __initdata */ = {
	.bLength =		UAC_DT_AC_HEADER_SIZE(1),
	.bDescriptorType =	USB_DT_CS_INTERFACE,
	.bDescriptorSubtype =	USB_MS_HEADER,
@@ -121,7 +126,7 @@ static struct uac1_ac_header_descriptor_1 ac_header_desc __initdata = {
};

/* B.4.1  Standard MS Interface Descriptor */
static struct usb_interface_descriptor ms_interface_desc __initdata = {
static struct usb_interface_descriptor ms_interface_desc /* __initdata */ = {
	.bLength =		USB_DT_INTERFACE_SIZE,
	.bDescriptorType =	USB_DT_INTERFACE,
	/* .bInterfaceNumber =	DYNAMIC */
@@ -132,7 +137,7 @@ static struct usb_interface_descriptor ms_interface_desc __initdata = {
};

/* B.4.2  Class-Specific MS Interface Descriptor */
static struct usb_ms_header_descriptor ms_header_desc __initdata = {
static struct usb_ms_header_descriptor ms_header_desc /* __initdata */ = {
	.bLength =		USB_DT_MS_HEADER_SIZE,
	.bDescriptorType =	USB_DT_CS_INTERFACE,
	.bDescriptorSubtype =	USB_MS_HEADER,
@@ -199,7 +204,7 @@ static inline struct usb_request *midi_alloc_ep_req(struct usb_ep *ep,
	return alloc_ep_req(ep, length, length);
}

static void free_ep_req(struct usb_ep *ep, struct usb_request *req)
static void midi_free_ep_req(struct usb_ep *ep, struct usb_request *req)
{
	kfree(req->buf);
	usb_ep_free_request(ep, req);
@@ -270,7 +275,7 @@ f_midi_complete(struct usb_ep *ep, struct usb_request *req)
		if (ep == midi->out_ep)
			f_midi_handle_out_data(ep, req);

		free_ep_req(ep, req);
		midi_free_ep_req(ep, req);
		return;

	case -EOVERFLOW:	/* buffer overrun on read means that
@@ -541,7 +546,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req)
		req = midi_alloc_ep_req(ep, midi->buflen);

	if (!req) {
		ERROR(midi, "gmidi_transmit: alloc_ep_request failed\n");
		ERROR(midi, "gmidi_transmit: midi_alloc_ep_request failed\n");
		return;
	}
	req->length = 0;
@@ -567,7 +572,7 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req)
	if (req->length > 0)
		usb_ep_queue(ep, req, GFP_ATOMIC);
	else
		free_ep_req(ep, req);
		midi_free_ep_req(ep, req);
}

static void f_midi_in_tasklet(unsigned long data)
@@ -724,7 +729,7 @@ fail:

/* MIDI function driver setup/binding */

static int __init
static int /* __init */
f_midi_bind(struct usb_configuration *c, struct usb_function *f)
{
	struct usb_descriptor_header **midi_function;
@@ -914,16 +919,22 @@ fail:
 *
 * Returns zero on success, else negative errno.
 */
int __init f_midi_bind_config(struct usb_configuration *c,
int /* __init */ f_midi_bind_config(struct usb_configuration *c,
			      int index, char *id,
			      unsigned int in_ports,
			      unsigned int out_ports,
			      unsigned int buflen,
			      unsigned int qlen)
			      unsigned int qlen,
			      struct midi_alsa_config* config)
{
	struct f_midi *midi;
	int status, i;

	if (config) {
		config->card = -1;
		config->device = -1;
	}

	/* sanity check */
	if (in_ports > MAX_PORTS || out_ports > MAX_PORTS)
		return -EINVAL;
@@ -952,6 +963,10 @@ int __init f_midi_bind_config(struct usb_configuration *c,
	tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi);

	/* set up ALSA midi devices */
	midi->id = kstrdup(id, GFP_KERNEL);
	midi->index = index;
	midi->buflen = buflen;
	midi->qlen = qlen;
	midi->in_ports = in_ports;
	midi->out_ports = out_ports;
	status = f_midi_register_card(midi);
@@ -965,15 +980,16 @@ int __init f_midi_bind_config(struct usb_configuration *c,
	midi->func.set_alt     = f_midi_set_alt;
	midi->func.disable     = f_midi_disable;

	midi->id = kstrdup(id, GFP_KERNEL);
	midi->index = index;
	midi->buflen = buflen;
	midi->qlen = qlen;

	status = usb_add_function(c, &midi->func);
	if (status)
		goto setup_fail;


	if (config) {
		config->card = midi->rmidi->card->number;
		config->device = midi->rmidi->device;
	}

	return 0;

setup_fail: