4 * Copyright (c) 2016 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
19 #ifndef __HW_USB_GADGET_H__
20 #define __HW_USB_GADGET_H__
22 #include <hw/common.h>
29 * The id of this device
31 #define USB_GADGET_DEVICE_ID "usb_gadget"
34 * The version of this device
36 #define USB_GADGET_DEVICE_VERSION MAKE_VERSION(0,1)
39 #define container_of(ptr, type, member) ({ \
40 const typeof( ((type *)0)->member ) *__mptr = (ptr); \
41 (type *)( (char *)__mptr - offsetof(type,member) );})
44 #define _HELPER_Y(x) ((x) & -(x))
46 /* Count number of trailing zeros using Dean Gaudet's algorithm */
47 #define _HELPER_CTZ(mask) \
48 ((_HELPER_Y(mask) ? 0 : 1) + \
49 ((_HELPER_Y(mask) & 0x0000FFFF) ? 0 : 16) + \
50 ((_HELPER_Y(mask) & 0x00FF00FF) ? 0 : 8) + \
51 ((_HELPER_Y(mask) & 0x0F0F0F0F) ? 0 : 4) + \
52 ((_HELPER_Y(mask) & 0x33333333) ? 0 : 2) + \
53 ((_HELPER_Y(mask) & 0x55555555) ? 0 : 1))
55 /* Function IDX in array is number of trailing zeros */
56 #define FUNC_IDX_FROM_MASK(mask) _HELPER_CTZ(mask)
59 USB_FUNCTION_GROUP_SIMPLE,
60 USB_FUNCTION_GROUP_WITH_SERVICE,
61 } usb_function_group_e;
69 int (*clone)(struct usb_function *func, struct usb_function **_clone);
70 void (*free_func)(struct usb_function *func);
73 struct usb_function_with_service {
74 struct usb_function func;
78 struct usb_configuration_attributes {
83 struct usb_configuration_strings {
88 struct usb_configuration {
89 struct usb_configuration_attributes attrs;
90 struct usb_configuration_strings *strs;
91 struct usb_function **funcs;
94 struct usb_gadget_attrs {
96 uint8_t bDeviceSubClass;
97 uint8_t bDeviceProtocol;
103 struct usb_gadget_strings {
111 struct usb_gadget_attrs attrs;
112 struct usb_gadget_strings *strs;
113 struct usb_function **funcs;
114 struct usb_configuration **configs;
118 USB_FUNCTION_NONE = 0,
119 USB_FUNCTION_MTP = 1 << 0,
120 USB_FUNCTION_ACM = 1 << 1,
121 USB_FUNCTION_SDB = 1 << 2,
122 USB_FUNCTION_RNDIS = 1 << 3,
123 USB_FUNCTION_DIAG = 1 << 4,
124 USB_FUNCTION_CONN_GADGET = 1 << 5,
125 USB_FUNCTION_DM = 1 << 6,
126 USB_FUNCTION_RMNET = 1 << 7,
129 static void free_simple_func_content(struct usb_function *func)
132 free(func->instance);
135 static void free_simple_func(struct usb_function *func)
137 free_simple_func_content(func);
141 static int clone_simple_func_to(struct usb_function *func,
142 struct usb_function *other)
145 other->name = strdup(func->name);
146 other->instance = strdup(func->instance);
148 if (!other->name || !other->instance)
154 free(other->instance);
158 static int clone_simple_func(struct usb_function *func,
159 struct usb_function **clone)
161 struct usb_function *other;
167 other = malloc(sizeof(*other));
171 ret = clone_simple_func_to(func, other);
183 #define DEFINE_SIMPLE_USB_FUNCTION(_id, _name) \
184 static struct usb_function _##_name##_function = { \
185 .function_group = USB_FUNCTION_GROUP_SIMPLE, \
188 .instance = "default", \
189 .free_func = free_simple_func, \
190 .clone = clone_simple_func, \
193 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_ACM, acm);
194 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_RNDIS, rndis);
195 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_DIAG, diag);
196 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_RMNET, rmnet);
197 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_DM, dm);
198 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_CONN_GADGET, conn_gadget);
200 #undef DEFINE_SIMPLE_USB_FUNCTION
202 static void free_func_with_service(struct usb_function *func)
204 struct usb_function_with_service *fws;
206 fws = container_of(func, struct usb_function_with_service, func);
208 free_simple_func_content(func);
213 static int clone_func_with_service(struct usb_function *func,
214 struct usb_function **clone)
216 struct usb_function_with_service *fws;
217 struct usb_function_with_service *other;
223 other = malloc(sizeof(*other));
227 ret = clone_simple_func_to(func, &other->func);
231 fws = container_of(func, struct usb_function_with_service, func);
233 other->service = strdup(fws->service);
237 other->service = NULL;
240 *clone = &other->func;
243 free_simple_func_content(&other->func);
250 #define DEFINE_USB_FUNCTION_WITH_SERVICE(_id, _name) \
251 static struct usb_function_with_service _##_name##_function = { \
253 .function_group = USB_FUNCTION_GROUP_WITH_SERVICE, \
256 .instance = "default", \
257 .free_func = free_func_with_service, \
258 .clone = clone_func_with_service, \
263 DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_SDB, sdb);
264 DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_MTP, mtp);
266 #define MAKE_FUNC_AVAILABLE(_name, _vname) \
267 [FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function
269 #define MAKE_FUNC_WS_AVAILABLE(_name, _vname) \
270 [FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function.func
272 static struct usb_function *_available_funcs[] = {
273 MAKE_FUNC_WS_AVAILABLE(MTP, mtp),
274 MAKE_FUNC_AVAILABLE(ACM, acm),
275 MAKE_FUNC_WS_AVAILABLE(SDB, sdb),
276 MAKE_FUNC_AVAILABLE(RNDIS, rndis),
277 MAKE_FUNC_AVAILABLE(DIAG, diag),
278 MAKE_FUNC_AVAILABLE(CONN_GADGET, conn_gadget),
279 MAKE_FUNC_AVAILABLE(DM, dm),
280 MAKE_FUNC_AVAILABLE(RMNET, rmnet),
283 #undef MAKE_FUNC_AVAILABLE
285 struct usb_gadget_id {
286 unsigned int function_mask;
289 struct usb_gadget_translator {
290 struct hw_common common;
292 int (*id_to_gadget)(struct usb_gadget_id *gadget_id,
293 struct usb_gadget **gadget);
295 void (*cleanup_gadget)(struct usb_gadget *gadget);