diff options
author | Andrzej Pietrasiewicz <andrzej.p@samsung.com> | 2014-10-16 07:33:27 -0400 |
---|---|---|
committer | Felipe Balbi <balbi@ti.com> | 2014-11-05 14:36:09 -0500 |
commit | b85e9de9e818de0dcbc50b7b4242192eb6194855 (patch) | |
tree | 4e46fffc034ea985138adafcba9a0e7111c792da | |
parent | d23b4c3ee2d5cbdeaec9f8e7d8a9bdcc73836fb9 (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/Kconfig | 3 | ||||
-rw-r--r-- | drivers/usb/gadget/function/Makefile | 2 | ||||
-rw-r--r-- | drivers/usb/gadget/function/f_midi.c | 147 | ||||
-rw-r--r-- | drivers/usb/gadget/function/u_midi.h | 32 | ||||
-rw-r--r-- | drivers/usb/gadget/legacy/gmidi.c | 1 |
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 | |||
190 | config USB_F_UVC | 190 | config USB_F_UVC |
191 | tristate | 191 | tristate |
192 | 192 | ||
193 | config USB_F_MIDI | ||
194 | tristate | ||
195 | |||
193 | choice | 196 | choice |
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 | |||
38 | obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o | 38 | obj-$(CONFIG_USB_F_UAC2) += usb_f_uac2.o |
39 | usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o | 39 | usb_f_uvc-y := f_uvc.o uvc_queue.o uvc_v4l2.o uvc_video.o |
40 | obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o | 40 | obj-$(CONFIG_USB_F_UVC) += usb_f_uvc.o |
41 | usb_f_midi-y := f_midi.o | ||
42 | obj-$(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 | ||
37 | MODULE_AUTHOR("Ben Williamson"); | 39 | MODULE_AUTHOR("Ben Williamson"); |
38 | MODULE_LICENSE("GPL v2"); | 40 | MODULE_LICENSE("GPL v2"); |
@@ -99,7 +101,7 @@ DECLARE_USB_MIDI_OUT_JACK_DESCRIPTOR(1); | |||
99 | DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16); | 101 | DECLARE_USB_MS_ENDPOINT_DESCRIPTOR(16); |
100 | 102 | ||
101 | /* B.3.1 Standard AC Interface Descriptor */ | 103 | /* B.3.1 Standard AC Interface Descriptor */ |
102 | static struct usb_interface_descriptor ac_interface_desc __initdata = { | 104 | static 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 */ |
113 | static struct uac1_ac_header_descriptor_1 ac_header_desc __initdata = { | 115 | static 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 */ |
124 | static struct usb_interface_descriptor ms_interface_desc __initdata = { | 126 | static 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 */ |
135 | static struct usb_ms_header_descriptor ms_header_desc __initdata = { | 137 | static 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 | ||
390 | static void f_midi_unbind(struct usb_configuration *c, struct usb_function *f) | 393 | static 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 | ||
413 | static int f_midi_snd_free(struct snd_device *device) | 417 | static 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 | ||
732 | static int __init | 736 | static int f_midi_bind(struct usb_configuration *c, struct usb_function *f) |
733 | f_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); |
899 | fail: | 910 | fail: |
911 | #ifndef USBF_MIDI_INCLUDED | ||
912 | f_midi_unregister_card(midi); | ||
913 | fail_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 | |||
1018 | static 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 | |||
1027 | static 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 | |||
1039 | static 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 | |||
1053 | static 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 | |||
1072 | struct 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 | |||
1124 | kstrdup_fail: | ||
1125 | f_midi_unregister_card(midi); | ||
1126 | setup_fail: | ||
1127 | for (--i; i >= 0; i--) | ||
1128 | kfree(midi->in_port[i]); | ||
1129 | kfree(midi); | ||
1130 | return ERR_PTR(status); | ||
1131 | } | ||
1132 | |||
1133 | DECLARE_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 | |||
21 | struct 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 | /*-------------------------------------------------------------------------*/ |