usb: gadget: f_midi: convert to new function interface with backward compatibility
Converting midi to the new function interface requires converting the USB midi's function code and its users. This patch converts the f_midi.c to the new function interface. The file can now be compiled into a separate usb_f_midi.ko module. The old function interface is provided by means of a preprocessor conditional directives. After all users are converted, the old interface can be removed. Signed-off-by: Andrzej Pietrasiewicz <andrzej.p@samsung.com> Signed-off-by: Felipe Balbi <balbi@ti.com>
This commit is contained in:
parent
d23b4c3ee2
commit
b85e9de9e8
@ -190,6 +190,9 @@ config USB_F_UAC2
|
||||
config USB_F_UVC
|
||||
tristate
|
||||
|
||||
config USB_F_MIDI
|
||||
tristate
|
||||
|
||||
choice
|
||||
tristate "USB Gadget Drivers"
|
||||
default USB_ETH
|
||||
|
@ -38,3 +38,5 @@ usb_f_uac2-y := f_uac2.o
|
||||
obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o
|
||||
usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o
|
||||
obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o
|
||||
usb_f_midi-y := f_midi.o
|
||||
obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o
|
||||
|
@ -20,6 +20,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/device.h>
|
||||
|
||||
@ -33,6 +34,7 @@
|
||||
#include <linux/usb/midi.h>
|
||||
|
||||
#include "u_f.h"
|
||||
#include "u_midi.h"
|
||||
|
||||
MODULE_AUTHOR("Ben Williamson");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
@ -99,7 +101,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 = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
/* .bInterfaceNumber = DYNAMIC */
|
||||
@ -110,7 +112,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 = {
|
||||
.bLength = UAC_DT_AC_HEADER_SIZE(1),
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_MS_HEADER,
|
||||
@ -121,7 +123,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 = {
|
||||
.bLength = USB_DT_INTERFACE_SIZE,
|
||||
.bDescriptorType = USB_DT_INTERFACE,
|
||||
/* .bInterfaceNumber = DYNAMIC */
|
||||
@ -132,7 +134,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 = {
|
||||
.bLength = USB_DT_MS_HEADER_SIZE,
|
||||
.bDescriptorType = USB_DT_CS_INTERFACE,
|
||||
.bDescriptorSubtype = USB_MS_HEADER,
|
||||
@ -387,6 +389,7 @@ static void f_midi_disable(struct usb_function *f)
|
||||
usb_ep_disable(midi->out_ep);
|
||||
}
|
||||
|
||||
#ifdef USBF_MIDI_INCLUDED
|
||||
static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
@ -409,6 +412,7 @@ static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
usb_free_all_descriptors(f);
|
||||
kfree(midi);
|
||||
}
|
||||
#endif
|
||||
|
||||
static int f_midi_snd_free(struct snd_device *device)
|
||||
{
|
||||
@ -729,8 +733,7 @@ fail:
|
||||
|
||||
/* MIDI function driver setup/binding */
|
||||
|
||||
static int __init
|
||||
f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
struct usb_descriptor_header **midi_function;
|
||||
struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS];
|
||||
@ -741,6 +744,14 @@ f_midi_bind(struct usb_configuration *c, struct usb_function *f)
|
||||
struct f_midi *midi = func_to_midi(f);
|
||||
int status, n, jack = 1, i = 0;
|
||||
|
||||
#ifndef USBF_MIDI_INCLUDED
|
||||
midi->gadget = cdev->gadget;
|
||||
tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi);
|
||||
status = f_midi_register_card(midi);
|
||||
if (status < 0)
|
||||
goto fail_register;
|
||||
|
||||
#endif
|
||||
/* maybe allocate device-global string ID */
|
||||
if (midi_string_defs[0].id == 0) {
|
||||
status = usb_string_id(c->cdev);
|
||||
@ -897,6 +908,10 @@ fail_f_midi:
|
||||
kfree(midi_function);
|
||||
usb_free_descriptors(f->hs_descriptors);
|
||||
fail:
|
||||
#ifndef USBF_MIDI_INCLUDED
|
||||
f_midi_unregister_card(midi);
|
||||
fail_register:
|
||||
#endif
|
||||
/* we might as well release our claims on endpoints */
|
||||
if (midi->out_ep)
|
||||
midi->out_ep->driver_data = NULL;
|
||||
@ -908,6 +923,7 @@ fail:
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef USBF_MIDI_INCLUDED
|
||||
/**
|
||||
* f_midi_bind_config - add USB MIDI function to a configuration
|
||||
* @c: the configuration to supcard the USB audio function
|
||||
@ -997,3 +1013,122 @@ fail:
|
||||
return status;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void f_midi_free_inst(struct usb_function_instance *f)
|
||||
{
|
||||
struct f_midi_opts *opts;
|
||||
|
||||
opts = container_of(f, struct f_midi_opts, func_inst);
|
||||
|
||||
kfree(opts);
|
||||
}
|
||||
|
||||
static struct usb_function_instance *f_midi_alloc_inst(void)
|
||||
{
|
||||
struct f_midi_opts *opts;
|
||||
|
||||
opts = kzalloc(sizeof(*opts), GFP_KERNEL);
|
||||
if (!opts)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
opts->func_inst.free_func_inst = f_midi_free_inst;
|
||||
|
||||
return &opts->func_inst;
|
||||
}
|
||||
|
||||
static void f_midi_free(struct usb_function *f)
|
||||
{
|
||||
struct f_midi *midi;
|
||||
struct f_midi_opts *opts;
|
||||
int i;
|
||||
|
||||
midi = func_to_midi(f);
|
||||
opts = container_of(f->fi, struct f_midi_opts, func_inst);
|
||||
kfree(midi->id);
|
||||
for (i = opts->in_ports - 1; i >= 0; --i)
|
||||
kfree(midi->in_port[i]);
|
||||
kfree(midi);
|
||||
}
|
||||
|
||||
static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
|
||||
{
|
||||
struct usb_composite_dev *cdev = f->config->cdev;
|
||||
struct f_midi *midi = func_to_midi(f);
|
||||
struct snd_card *card;
|
||||
|
||||
DBG(cdev, "unbind\n");
|
||||
|
||||
/* just to be sure */
|
||||
f_midi_disable(f);
|
||||
|
||||
card = midi->card;
|
||||
midi->card = NULL;
|
||||
if (card)
|
||||
snd_card_free(card);
|
||||
|
||||
usb_free_all_descriptors(f);
|
||||
}
|
||||
|
||||
struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
|
||||
{
|
||||
struct f_midi *midi;
|
||||
struct f_midi_opts *opts;
|
||||
int status, i;
|
||||
|
||||
opts = container_of(fi, struct f_midi_opts, func_inst);
|
||||
/* sanity check */
|
||||
if (opts->in_ports > MAX_PORTS || opts->out_ports > MAX_PORTS)
|
||||
return ERR_PTR(-EINVAL);
|
||||
|
||||
/* allocate and initialize one new instance */
|
||||
midi = kzalloc(sizeof(*midi), GFP_KERNEL);
|
||||
if (!midi)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
for (i = 0; i < opts->in_ports; i++) {
|
||||
struct gmidi_in_port *port = kzalloc(sizeof(*port), GFP_KERNEL);
|
||||
|
||||
if (!port) {
|
||||
status = -ENOMEM;
|
||||
goto setup_fail;
|
||||
}
|
||||
|
||||
port->midi = midi;
|
||||
port->active = 0;
|
||||
port->cable = i;
|
||||
midi->in_port[i] = port;
|
||||
}
|
||||
|
||||
/* set up ALSA midi devices */
|
||||
midi->id = kstrdup(opts->id, GFP_KERNEL);
|
||||
if (opts->id && !midi->id) {
|
||||
status = -ENOMEM;
|
||||
goto kstrdup_fail;
|
||||
}
|
||||
midi->in_ports = opts->in_ports;
|
||||
midi->out_ports = opts->out_ports;
|
||||
midi->index = opts->index;
|
||||
midi->buflen = opts->buflen;
|
||||
midi->qlen = opts->qlen;
|
||||
|
||||
midi->func.name = "gmidi function";
|
||||
midi->func.strings = midi_strings;
|
||||
midi->func.bind = f_midi_bind;
|
||||
midi->func.unbind = f_midi_unbind;
|
||||
midi->func.set_alt = f_midi_set_alt;
|
||||
midi->func.disable = f_midi_disable;
|
||||
midi->func.free_func = f_midi_free;
|
||||
|
||||
return &midi->func;
|
||||
|
||||
kstrdup_fail:
|
||||
f_midi_unregister_card(midi);
|
||||
setup_fail:
|
||||
for (--i; i >= 0; i--)
|
||||
kfree(midi->in_port[i]);
|
||||
kfree(midi);
|
||||
return ERR_PTR(status);
|
||||
}
|
||||
|
||||
DECLARE_USB_FUNCTION_INIT(midi, f_midi_alloc_inst, f_midi_alloc);
|
||||
#endif
|
||||
|
32
drivers/usb/gadget/function/u_midi.h
Normal file
32
drivers/usb/gadget/function/u_midi.h
Normal file
@ -0,0 +1,32 @@
|
||||
/*
|
||||
* u_midi.h
|
||||
*
|
||||
* Utility definitions for the midi function
|
||||
*
|
||||
* Copyright (c) 2014 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com
|
||||
*
|
||||
* Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
|
||||
*
|
||||
* 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_MIDI_H
|
||||
#define U_MIDI_H
|
||||
|
||||
#include <linux/usb/composite.h>
|
||||
|
||||
struct f_midi_opts {
|
||||
struct usb_function_instance func_inst;
|
||||
int index;
|
||||
char *id;
|
||||
unsigned int in_ports;
|
||||
unsigned int out_ports;
|
||||
unsigned int buflen;
|
||||
unsigned int qlen;
|
||||
};
|
||||
|
||||
#endif /* U_MIDI_H */
|
||||
|
@ -37,6 +37,7 @@
|
||||
|
||||
#include "gadget_chips.h"
|
||||
|
||||
#define USBF_MIDI_INCLUDED
|
||||
#include "f_midi.c"
|
||||
|
||||
/*-------------------------------------------------------------------------*/
|
||||
|
Loading…
Reference in New Issue
Block a user