USB gadget HAL API
[platform/core/system/libdevice-node.git] / hw / usb_gadget.h
1 /*
2  * libdevice-node
3  *
4  * Copyright (c) 2016 Samsung Electronics Co., Ltd.
5  *
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
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
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.
17  */
18
19 #ifndef __HW_USB_GADGET_H__
20 #define __HW_USB_GADGET_H__
21
22 #include <hw/common.h>
23
24 #include <stddef.h>
25 #include <stdlib.h>
26 #include <errno.h>
27
28 /**
29  * The id of this device
30  */
31 #define USB_GADGET_DEVICE_ID    "usb_gadget"
32
33 /**
34  * The version of this device
35  */
36 #define USB_GADGET_DEVICE_VERSION       MAKE_VERSION(0,1)
37
38 #ifndef container_of
39 #define container_of(ptr, type, member) ({                      \
40         const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
41         (type *)( (char *)__mptr - offsetof(type,member) );})
42 #endif
43
44 #define _HELPER_Y(x) ((x) & -(x))
45
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))
54
55 /* Function IDX in array is number of trailing zeros */
56 #define FUNC_IDX_FROM_MASK(mask) _HELPER_CTZ(mask)
57
58 typedef enum {
59         USB_FUNCTION_GROUP_SIMPLE,
60         USB_FUNCTION_GROUP_WITH_SERVICE,
61 } usb_function_group_e;
62
63 struct usb_function {
64         int function_group;
65         int id;
66         char *name;
67         char *instance;
68
69         int (*clone)(struct usb_function *func, struct usb_function **_clone);
70         void (*free_func)(struct usb_function *func);
71 };
72
73 struct usb_function_with_service {
74         struct usb_function func;
75         const char *service;
76 };
77
78 struct usb_configuration_attributes {
79         uint8_t bmAttributs;
80         int MaxPower;
81 };
82
83 struct usb_configuration_strings {
84         uint16_t lang_code;
85         char *config_str;
86 };
87
88 struct usb_configuration {
89         struct usb_configuration_attributes attrs;
90         struct usb_configuration_strings *strs;
91         struct usb_function **funcs;
92 };
93
94 struct usb_gadget_attrs {
95         uint8_t bDeviceClass;
96         uint8_t bDeviceSubClass;
97         uint8_t bDeviceProtocol;
98         uint16_t idVendor;
99         uint16_t idProduct;
100         uint16_t bcdDevice;
101 };
102
103 struct usb_gadget_strings {
104         uint16_t lang_code;
105         char *manufacturer;
106         char *product;
107         char *serial;
108 };
109
110 struct usb_gadget {
111         struct usb_gadget_attrs attrs;
112         struct usb_gadget_strings *strs;
113         struct usb_function **funcs;
114         struct usb_configuration **configs;
115 };
116
117 typedef enum {
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,
127 } usb_function_e;
128
129 static void free_simple_func_content(struct usb_function *func)
130 {
131         free(func->name);
132         free(func->instance);
133 }
134
135 static void free_simple_func(struct usb_function *func)
136 {
137         free_simple_func_content(func);
138         free(func);
139 }
140
141 static int clone_simple_func_to(struct usb_function *func,
142                               struct usb_function *other)
143 {
144         *other = *func;
145         other->name = strdup(func->name);
146         other->instance = strdup(func->instance);
147
148         if (!other->name || !other->instance)
149                 goto free_strs;
150
151         return 0;
152 free_strs:
153         free(other->name);
154         free(other->instance);
155         return -ENOMEM;
156 }
157
158 static int clone_simple_func(struct usb_function *func,
159                               struct usb_function **clone)
160 {
161         struct usb_function *other;
162         int ret;
163
164         if (!func || !clone)
165                 return -EINVAL;
166
167         other = malloc(sizeof(*other));
168         if (!other)
169                 goto out;
170
171         ret = clone_simple_func_to(func, other);
172         if (ret)
173                 goto free_other;
174
175         *clone = other;
176         return 0;
177 free_other:
178         free(other);
179 out:
180         return -ENOMEM;
181 }
182
183 #define DEFINE_SIMPLE_USB_FUNCTION(_id, _name)                       \
184         static struct usb_function _##_name##_function = {           \
185                 .function_group = USB_FUNCTION_GROUP_SIMPLE,         \
186                 .id = _id,                                           \
187                 .name = #_name,                                      \
188                 .instance = "default",                               \
189                 .free_func = free_simple_func,                       \
190                 .clone = clone_simple_func,                          \
191         }
192
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);
199
200 #undef DEFINE_SIMPLE_USB_FUNCTION
201
202 static void free_func_with_service(struct usb_function *func)
203 {
204         struct usb_function_with_service *fws;
205
206         fws = container_of(func, struct usb_function_with_service, func);
207
208         free_simple_func_content(func);
209         free(fws->service);
210         free(fws);
211 }
212
213 static int clone_func_with_service(struct usb_function *func,
214                                    struct usb_function **clone)
215 {
216         struct usb_function_with_service *fws;
217         struct usb_function_with_service *other;
218         int ret;
219
220         if (!func || !clone)
221                 return -EINVAL;
222
223         other = malloc(sizeof(*other));
224         if (!other)
225                 goto out;
226
227         ret = clone_simple_func_to(func, &other->func);
228         if (ret)
229                 goto free_other;
230
231         fws = container_of(func, struct usb_function_with_service, func);
232         if (fws->service) {
233                 other->service = strdup(fws->service);
234                 if (!other->service)
235                         goto free_content;
236         } else {
237                 other->service = NULL;
238         }
239
240         *clone = &other->func;
241         return 0;
242 free_content:
243         free_simple_func_content(&other->func);
244 free_other:
245         free(other);
246 out:
247         return -ENOMEM;
248 }
249
250 #define DEFINE_USB_FUNCTION_WITH_SERVICE(_id, _name)                    \
251         static struct usb_function_with_service _##_name##_function = { \
252                 .func = {                                               \
253                         .function_group = USB_FUNCTION_GROUP_WITH_SERVICE, \
254                         .id = _id,                                      \
255                         .name = #_name,                                 \
256                         .instance = "default",                          \
257                         .free_func = free_func_with_service,            \
258                         .clone = clone_func_with_service,               \
259                 },                                                      \
260                 .service = NULL,                                        \
261         }
262
263 DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_SDB, sdb);
264 DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_MTP, mtp);
265
266 #define MAKE_FUNC_AVAILABLE(_name, _vname)                              \
267         [FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function
268
269 #define MAKE_FUNC_WS_AVAILABLE(_name, _vname)                           \
270         [FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function.func
271
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),
281 };
282
283 #undef MAKE_FUNC_AVAILABLE
284
285 struct usb_gadget_id {
286         unsigned int function_mask;
287 };
288
289 struct usb_gadget_translator {
290         struct hw_common common;
291
292         int (*id_to_gadget)(struct usb_gadget_id *gadget_id,
293                          struct usb_gadget **gadget);
294
295         void (*cleanup_gadget)(struct usb_gadget *gadget);
296 };
297
298 #endif