aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndrzej Pietrasiewicz <andrzej.p@samsung.com>2014-10-16 07:33:27 -0400
committerFelipe Balbi <balbi@ti.com>2014-11-05 14:36:09 -0500
commitb85e9de9e818de0dcbc50b7b4242192eb6194855 (patch)
tree4e46fffc034ea985138adafcba9a0e7111c792da
parentd23b4c3ee2d5cbdeaec9f8e7d8a9bdcc73836fb9 (diff)
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>
-rw-r--r--drivers/usb/gadget/Kconfig3
-rw-r--r--drivers/usb/gadget/function/Makefile2
-rw-r--r--drivers/usb/gadget/function/f_midi.c147
-rw-r--r--drivers/usb/gadget/function/u_midi.h32
-rw-r--r--drivers/usb/gadget/legacy/gmidi.c1
5 files changed, 179 insertions, 6 deletions
diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig
index c8a0784b8d5e..b51307805151 100644
--- a/drivers/usb/gadget/Kconfig
+++ b/drivers/usb/gadget/Kconfig
@@ -190,6 +190,9 @@ config USB_F_UAC2
190config USB_F_UVC 190config USB_F_UVC
191 tristate 191 tristate
192 192
193config USB_F_MIDI
194 tristate
195
193choice 196choice
194 tristate "USB Gadget Drivers" 197 tristate "USB Gadget Drivers"
195 default USB_ETH 198 default USB_ETH
diff --git a/drivers/usb/gadget/function/Makefile b/drivers/usb/gadget/function/Makefile
index 90701aa5a826..576eea5c0a8b 100644
--- a/drivers/usb/gadget/function/Makefile
+++ b/drivers/usb/gadget/function/Makefile
@@ -38,3 +38,5 @@ usb_f_uac2-y := f_uac2.o
38obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o 38obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o
39usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o 39usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o
40obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o 40obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o
41usb_f_midi-y := f_midi.o
42obj-$(CONFIG_USB_F_MIDI) += usb_f_midi.o
diff --git a/drivers/usb/gadget/function/f_midi.c b/drivers/usb/gadget/function/f_midi.c
index a920eee9e878..f3e7d951f0ff 100644
--- a/drivers/usb/gadget/function/f_midi.c
+++ b/drivers/usb/gadget/function/f_midi.c
@@ -20,6 +20,7 @@
20 */ 20 */
21 21
22#include <linux/kernel.h> 22#include <linux/kernel.h>
23#include <linux/module.h>
23#include <linux/slab.h> 24#include <linux/slab.h>
24#include <linux/device.h> 25#include <linux/device.h>
25 26
@@ -33,6 +34,7 @@
33#include <linux/usb/midi.h> 34#include <linux/usb/midi.h>
34 35
35#include "u_f.h" 36#include "u_f.h"
37#include "u_midi.h"
36 38
37MODULE_AUTHOR("Ben Williamson"); 39MODULE_AUTHOR("Ben Williamson");
38MODULE_LICENSE("GPL v2"); 40MODULE_LICENSE("GPL v2");
@@ -99,7 +101,7 @@ DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1);
99DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16); 101DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16);
100 102
101/* B.3.1 Standard AC Interface Descriptor */ 103/* B.3.1 Standard AC Interface Descriptor */
102static struct usb_interface_descriptor ac_interface_desc __initdata = { 104static struct usb_interface_descriptor ac_interface_desc = {
103 .bLength = USB_DT_INTERFACE_SIZE, 105 .bLength = USB_DT_INTERFACE_SIZE,
104 .bDescriptorType = USB_DT_INTERFACE, 106 .bDescriptorType = USB_DT_INTERFACE,
105 /* .bInterfaceNumber = DYNAMIC */ 107 /* .bInterfaceNumber = DYNAMIC */
@@ -110,7 +112,7 @@ static struct usb_interface_descriptor ac_interface_desc __initdata = {
110}; 112};
111 113
112/* B.3.2 Class-Specific AC Interface Descriptor */ 114/* B.3.2 Class-Specific AC Interface Descriptor */
113static struct uac1_ac_header_descriptor_1 ac_header_desc __initdata = { 115static struct uac1_ac_header_descriptor_1 ac_header_desc = {
114 .bLength = UAC_DT_AC_HEADER_SIZE(1), 116 .bLength = UAC_DT_AC_HEADER_SIZE(1),
115 .bDescriptorType = USB_DT_CS_INTERFACE, 117 .bDescriptorType = USB_DT_CS_INTERFACE,
116 .bDescriptorSubtype = USB_MS_HEADER, 118 .bDescriptorSubtype = USB_MS_HEADER,
@@ -121,7 +123,7 @@ static struct uac1_ac_header_descriptor_1 ac_header_desc __initdata = {
121}; 123};
122 124
123/* B.4.1 Standard MS Interface Descriptor */ 125/* B.4.1 Standard MS Interface Descriptor */
124static struct usb_interface_descriptor ms_interface_desc __initdata = { 126static struct usb_interface_descriptor ms_interface_desc = {
125 .bLength = USB_DT_INTERFACE_SIZE, 127 .bLength = USB_DT_INTERFACE_SIZE,
126 .bDescriptorType = USB_DT_INTERFACE, 128 .bDescriptorType = USB_DT_INTERFACE,
127 /* .bInterfaceNumber = DYNAMIC */ 129 /* .bInterfaceNumber = DYNAMIC */
@@ -132,7 +134,7 @@ static struct usb_interface_descriptor ms_interface_desc __initdata = {
132}; 134};
133 135
134/* B.4.2 Class-Specific MS Interface Descriptor */ 136/* B.4.2 Class-Specific MS Interface Descriptor */
135static struct usb_ms_header_descriptor ms_header_desc __initdata = { 137static struct usb_ms_header_descriptor ms_header_desc = {
136 .bLength = USB_DT_MS_HEADER_SIZE, 138 .bLength = USB_DT_MS_HEADER_SIZE,
137 .bDescriptorType = USB_DT_CS_INTERFACE, 139 .bDescriptorType = USB_DT_CS_INTERFACE,
138 .bDescriptorSubtype = USB_MS_HEADER, 140 .bDescriptorSubtype = USB_MS_HEADER,
@@ -387,6 +389,7 @@ static void f_midi_disable(struct usb_function *f)
387 usb_ep_disable(midi->out_ep); 389 usb_ep_disable(midi->out_ep);
388} 390}
389 391
392#ifdef USBF_MIDI_INCLUDED
390static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) 393static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
391{ 394{
392 struct usb_composite_dev *cdev = f->config->cdev; 395 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)
409 usb_free_all_descriptors(f); 412 usb_free_all_descriptors(f);
410 kfree(midi); 413 kfree(midi);
411} 414}
415#endif
412 416
413static int f_midi_snd_free(struct snd_device *device) 417static int f_midi_snd_free(struct snd_device *device)
414{ 418{
@@ -729,8 +733,7 @@ fail:
729 733
730/* MIDI function driver setup/binding */ 734/* MIDI function driver setup/binding */
731 735
732static int __init 736static int f_midi_bind(struct usb_configuration *c, struct usb_function *f)
733f_midi_bind(struct usb_configuration *c, struct usb_function *f)
734{ 737{
735 struct usb_descriptor_header **midi_function; 738 struct usb_descriptor_header **midi_function;
736 struct usb_midi_in_jack_descriptor jack_in_ext_desc[MAX_PORTS]; 739 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)
741 struct f_midi *midi = func_to_midi(f); 744 struct f_midi *midi = func_to_midi(f);
742 int status, n, jack = 1, i = 0; 745 int status, n, jack = 1, i = 0;
743 746
747#ifndef USBF_MIDI_INCLUDED
748 midi->gadget = cdev->gadget;
749 tasklet_init(&midi->tasklet, f_midi_in_tasklet, (unsigned long) midi);
750 status = f_midi_register_card(midi);
751 if (status < 0)
752 goto fail_register;
753
754#endif
744 /* maybe allocate device-global string ID */ 755 /* maybe allocate device-global string ID */
745 if (midi_string_defs[0].id == 0) { 756 if (midi_string_defs[0].id == 0) {
746 status = usb_string_id(c->cdev); 757 status = usb_string_id(c->cdev);
@@ -897,6 +908,10 @@ fail_f_midi:
897 kfree(midi_function); 908 kfree(midi_function);
898 usb_free_descriptors(f->hs_descriptors); 909 usb_free_descriptors(f->hs_descriptors);
899fail: 910fail:
911#ifndef USBF_MIDI_INCLUDED
912 f_midi_unregister_card(midi);
913fail_register:
914#endif
900 /* we might as well release our claims on endpoints */ 915 /* we might as well release our claims on endpoints */
901 if (midi->out_ep) 916 if (midi->out_ep)
902 midi->out_ep->driver_data = NULL; 917 midi->out_ep->driver_data = NULL;
@@ -908,6 +923,7 @@ fail:
908 return status; 923 return status;
909} 924}
910 925
926#ifdef USBF_MIDI_INCLUDED
911/** 927/**
912 * f_midi_bind_config - add USB MIDI function to a configuration 928 * f_midi_bind_config - add USB MIDI function to a configuration
913 * @c: the configuration to supcard the USB audio function 929 * @c: the configuration to supcard the USB audio function
@@ -997,3 +1013,122 @@ fail:
997 return status; 1013 return status;
998} 1014}
999 1015
1016#else
1017
1018static void f_midi_free_inst(struct usb_function_instance *f)
1019{
1020 struct f_midi_opts *opts;
1021
1022 opts = container_of(f, struct f_midi_opts, func_inst);
1023
1024 kfree(opts);
1025}
1026
1027static struct usb_function_instance *f_midi_alloc_inst(void)
1028{
1029 struct f_midi_opts *opts;
1030
1031 opts = kzalloc(sizeof(*opts), GFP_KERNEL);
1032 if (!opts)
1033 return ERR_PTR(-ENOMEM);
1034 opts->func_inst.free_func_inst = f_midi_free_inst;
1035
1036 return &opts->func_inst;
1037}
1038
1039static void f_midi_free(struct usb_function *f)
1040{
1041 struct f_midi *midi;
1042 struct f_midi_opts *opts;
1043 int i;
1044
1045 midi = func_to_midi(f);
1046 opts = container_of(f->fi, struct f_midi_opts, func_inst);
1047 kfree(midi->id);
1048 for (i = opts->in_ports - 1; i >= 0; --i)
1049 kfree(midi->in_port[i]);
1050 kfree(midi);
1051}
1052
1053static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f)
1054{
1055 struct usb_composite_dev *cdev = f->config->cdev;
1056 struct f_midi *midi = func_to_midi(f);
1057 struct snd_card *card;
1058
1059 DBG(cdev, "unbind\n");
1060
1061 /* just to be sure */
1062 f_midi_disable(f);
1063
1064 card = midi->card;
1065 midi->card = NULL;
1066 if (card)
1067 snd_card_free(card);
1068
1069 usb_free_all_descriptors(f);
1070}
1071
1072struct usb_function *f_midi_alloc(struct usb_function_instance *fi)
1073{
1074 struct f_midi *midi;
1075 struct f_midi_opts *opts;
1076 int status, i;
1077
1078 opts = container_of(fi, struct f_midi_opts, func_inst);
1079 /* sanity check */
1080 if (opts->in_ports > MAX_PORTS || opts->out_ports > MAX_PORTS)
1081 return ERR_PTR(-EINVAL);
1082
1083 /* allocate and initialize one new instance */
1084 midi = kzalloc(sizeof(*midi), GFP_KERNEL);
1085 if (!midi)
1086 return ERR_PTR(-ENOMEM);
1087
1088 for (i = 0; i < opts->in_ports; i++) {
1089 struct gmidi_in_port *port = kzalloc(sizeof(*port), GFP_KERNEL);
1090
1091 if (!port) {
1092 status = -ENOMEM;
1093 goto setup_fail;
1094 }
1095
1096 port->midi = midi;
1097 port->active = 0;
1098 port->cable = i;
1099 midi->in_port[i] = port;
1100 }
1101
1102 /* set up ALSA midi devices */
1103 midi->id = kstrdup(opts->id, GFP_KERNEL);
1104 if (opts->id && !midi->id) {
1105 status = -ENOMEM;
1106 goto kstrdup_fail;
1107 }
1108 midi->in_ports = opts->in_ports;
1109 midi->out_ports = opts->out_ports;
1110 midi->index = opts->index;
1111 midi->buflen = opts->buflen;
1112 midi->qlen = opts->qlen;
1113
1114 midi->func.name = "gmidi function";
1115 midi->func.strings = midi_strings;
1116 midi->func.bind = f_midi_bind;
1117 midi->func.unbind = f_midi_unbind;
1118 midi->func.set_alt = f_midi_set_alt;
1119 midi->func.disable = f_midi_disable;
1120 midi->func.free_func = f_midi_free;
1121
1122 return &midi->func;
1123
1124kstrdup_fail:
1125 f_midi_unregister_card(midi);
1126setup_fail:
1127 for (--i; i >= 0; i--)
1128 kfree(midi->in_port[i]);
1129 kfree(midi);
1130 return ERR_PTR(status);
1131}
1132
1133DECLARE_USB_FUNCTION_INIT(midi, f_midi_alloc_inst, f_midi_alloc);
1134#endif
diff --git a/drivers/usb/gadget/function/u_midi.h b/drivers/usb/gadget/function/u_midi.h
new file mode 100644
index 000000000000..76bccc1fdbb4
--- /dev/null
+++ b/drivers/usb/gadget/function/u_midi.h
@@ -0,0 +1,32 @@
1/*
2 * u_midi.h
3 *
4 * Utility definitions for the midi function
5 *
6 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
7 * http://www.samsung.com
8 *
9 * Author: Andrzej Pietrasiewicz <andrzej.p@samsung.com>
10 *
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License version 2 as
13 * published by the Free Software Foundation.
14 */
15
16#ifndef U_MIDI_H
17#define U_MIDI_H
18
19#include <linux/usb/composite.h>
20
21struct f_midi_opts {
22 struct usb_function_instance func_inst;
23 int index;
24 char *id;
25 unsigned int in_ports;
26 unsigned int out_ports;
27 unsigned int buflen;
28 unsigned int qlen;
29};
30
31#endif /* U_MIDI_H */
32
diff --git a/drivers/usb/gadget/legacy/gmidi.c b/drivers/usb/gadget/legacy/gmidi.c
index 3d696b86ff76..f704c5557d19 100644
--- a/drivers/usb/gadget/legacy/gmidi.c
+++ b/drivers/usb/gadget/legacy/gmidi.c
@@ -37,6 +37,7 @@
37 37
38#include "gadget_chips.h" 38#include "gadget_chips.h"
39 39
40#define USBF_MIDI_INCLUDED
40#include "f_midi.c" 41#include "f_midi.c"
41 42
42/*-------------------------------------------------------------------------*/ 43/*-------------------------------------------------------------------------*/