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

Commit 07c188dd 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 de00bc2b 19bcb452
Loading
Loading
Loading
Loading
+66 −0
Original line number Diff line number Diff line
@@ -40,6 +40,9 @@
#ifdef CONFIG_SND_PCM
#include "f_audio_source.c"
#endif
#ifdef CONFIG_SND_RAWMIDI
#include "f_midi.c"
#endif
#include "f_mass_storage.c"
#define USB_ETH_RNDIS y
#include "f_diag.c"
@@ -89,6 +92,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;
@@ -2782,6 +2790,61 @@ static struct android_usb_function uasp_function = {
	.bind_config	= uasp_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,
@@ -2810,6 +2873,9 @@ static struct android_usb_function *supported_functions[] = {
#endif
	&uasp_function,
	&charger_function,
#ifdef CONFIG_SND_RAWMIDI
	&midi_function,
#endif
	NULL
};

+35 −19
Original line number Diff line number Diff line
@@ -65,6 +65,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;
@@ -97,7 +102,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 */
@@ -108,7 +113,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,
@@ -119,7 +124,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 */
@@ -130,7 +135,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,
@@ -191,7 +196,7 @@ static struct usb_gadget_strings *midi_strings[] = {
	NULL,
};

static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
static struct usb_request *midi_alloc_ep_req(struct usb_ep *ep, unsigned length)
{
	struct usb_request *req;

@@ -207,7 +212,7 @@ static struct usb_request *alloc_ep_req(struct usb_ep *ep, unsigned length)
	return req;
}

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);
@@ -278,7 +283,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
@@ -365,7 +370,7 @@ static int f_midi_set_alt(struct usb_function *f, unsigned intf, unsigned alt)
	/* allocate a bunch of read buffers and queue them all at once. */
	for (i = 0; i < midi->qlen && err == 0; i++) {
		struct usb_request *req =
			alloc_ep_req(midi->out_ep, midi->buflen);
			midi_alloc_ep_req(midi->out_ep, midi->buflen);
		if (req == NULL)
			return -ENOMEM;

@@ -546,10 +551,10 @@ static void f_midi_transmit(struct f_midi *midi, struct usb_request *req)
		return;

	if (!req)
		req = alloc_ep_req(ep, midi->buflen);
		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;
@@ -575,7 +580,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)
@@ -733,7 +738,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;
@@ -923,16 +928,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;
@@ -961,6 +972,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);
@@ -974,15 +989,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: