31e1a91025e0fb0bb5ea5144e06218da860bd72c
[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 <string.h>
27 #include <errno.h>
28
29 /**
30  * The id of this device
31  */
32 #define USB_GADGET_DEVICE_ID    "usb_gadget"
33
34 /**
35  * The version of this device
36  */
37 #define USB_GADGET_DEVICE_VERSION       MAKE_VERSION(0,1)
38
39 #define _HELPER_Y(x) ((x) & -(x))
40
41 /* Count number of trailing zeros using Dean Gaudet's algorithm */
42 #define _HELPER_CTZ(mask)                                       \
43         ((_HELPER_Y(mask) ? 0 : 1) +                            \
44          ((_HELPER_Y(mask) & 0x0000FFFF) ? 0 : 16) +            \
45          ((_HELPER_Y(mask) & 0x00FF00FF) ? 0 :  8) +            \
46          ((_HELPER_Y(mask) & 0x0F0F0F0F) ? 0 :  4) +            \
47          ((_HELPER_Y(mask) & 0x33333333) ? 0 :  2) +            \
48          ((_HELPER_Y(mask) & 0x55555555) ? 0 :  1))
49
50 /* Function IDX in array is number of trailing zeros */
51 #define FUNC_IDX_FROM_MASK(mask) _HELPER_CTZ(mask)
52
53 typedef enum {
54         USB_FUNCTION_GROUP_SIMPLE,
55         USB_FUNCTION_GROUP_WITH_SERVICE,
56 } usb_function_group_e;
57
58 struct usb_function {
59         int function_group;
60         int id;
61         const char *name;
62         const char *instance;
63
64         int (*clone)(struct usb_function *func, struct usb_function **_clone);
65         void (*free_func)(struct usb_function *func);
66 };
67
68 struct usb_function_with_service {
69         struct usb_function func;
70         const char *service;
71 };
72
73 struct usb_configuration_attributes {
74         uint8_t bmAttributs;
75         int MaxPower;
76 };
77
78 struct usb_configuration_strings {
79         uint16_t lang_code;
80         char *config_str;
81 };
82
83 struct usb_configuration {
84         struct usb_configuration_attributes attrs;
85         struct usb_configuration_strings *strs;
86         struct usb_function **funcs;
87 };
88
89 struct usb_gadget_attrs {
90         uint8_t bDeviceClass;
91         uint8_t bDeviceSubClass;
92         uint8_t bDeviceProtocol;
93         uint16_t idVendor;
94         uint16_t idProduct;
95         uint16_t bcdDevice;
96 };
97
98 struct usb_gadget_strings {
99         uint16_t lang_code;
100         char *manufacturer;
101         char *product;
102         char *serial;
103 };
104
105 struct usb_gadget {
106         struct usb_gadget_attrs attrs;
107         struct usb_gadget_strings *strs;
108         struct usb_function **funcs;
109         struct usb_configuration **configs;
110 };
111
112 typedef enum {
113         USB_FUNCTION_NONE               = 0,
114         USB_FUNCTION_MTP                = 1 << 0,
115         USB_FUNCTION_ACM                = 1 << 1,
116         USB_FUNCTION_SDB                = 1 << 2,
117         USB_FUNCTION_RNDIS              = 1 << 3,
118         USB_FUNCTION_DIAG               = 1 << 4,
119         USB_FUNCTION_CONN_GADGET        = 1 << 5,
120         USB_FUNCTION_DM                 = 1 << 6,
121         USB_FUNCTION_RMNET              = 1 << 7,
122 } usb_function_e;
123
124 static void free_simple_func_content(struct usb_function *func)
125 {
126         free((void *)func->name);
127         free((void *)func->instance);
128 }
129
130 static void free_simple_func(struct usb_function *func)
131 {
132         free_simple_func_content(func);
133         free(func);
134 }
135
136 static int clone_simple_func_to(struct usb_function *func,
137                               struct usb_function *other)
138 {
139         *other = *func;
140         other->name = strdup(func->name);
141         other->instance = strdup(func->instance);
142
143         if (!other->name || !other->instance)
144                 goto free_strs;
145
146         return 0;
147 free_strs:
148         free((void *)other->name);
149         free((void *)other->instance);
150         return -ENOMEM;
151 }
152
153 static int clone_simple_func(struct usb_function *func,
154                               struct usb_function **clone)
155 {
156         struct usb_function *other;
157         int ret;
158
159         if (!func || !clone)
160                 return -EINVAL;
161
162         other = (struct usb_function *)malloc(sizeof(*other));
163         if (!other)
164                 goto out;
165
166         ret = clone_simple_func_to(func, other);
167         if (ret)
168                 goto free_other;
169
170         *clone = other;
171         return 0;
172 free_other:
173         free(other);
174 out:
175         return -ENOMEM;
176 }
177
178 #define DEFINE_SIMPLE_USB_FUNCTION(_id, _name)                       \
179         static struct usb_function _##_name##_function = {           \
180                 .function_group = USB_FUNCTION_GROUP_SIMPLE,         \
181                 .id = _id,                                           \
182                 .name = #_name,                                      \
183                 .instance = "default",                               \
184                 .clone = clone_simple_func,                      \
185                 .free_func = free_simple_func,                       \
186         }
187
188 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_ACM, acm);
189 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_RNDIS, rndis);
190 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_DIAG, diag);
191 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_RMNET, rmnet);
192 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_DM, dm);
193 DEFINE_SIMPLE_USB_FUNCTION(USB_FUNCTION_CONN_GADGET, conn_gadget);
194
195 #undef DEFINE_SIMPLE_USB_FUNCTION
196
197 static void free_func_with_service(struct usb_function *func)
198 {
199         struct usb_function_with_service *fws;
200
201         fws = container_of(func, struct usb_function_with_service, func);
202
203         free_simple_func_content(func);
204         free((void *)fws->service);
205         free(fws);
206 }
207
208 static int clone_func_with_service(struct usb_function *func,
209                                    struct usb_function **clone)
210 {
211         struct usb_function_with_service *fws;
212         struct usb_function_with_service *other;
213         int ret;
214
215         if (!func || !clone)
216                 return -EINVAL;
217
218         other = (struct usb_function_with_service *)malloc(sizeof(*other));
219         if (!other)
220                 goto out;
221
222         ret = clone_simple_func_to(func, &other->func);
223         if (ret)
224                 goto free_other;
225
226         fws = container_of(func, struct usb_function_with_service, func);
227         if (fws->service) {
228                 other->service = strdup(fws->service);
229                 if (!other->service)
230                         goto free_content;
231         } else {
232                 other->service = NULL;
233         }
234
235         *clone = &other->func;
236         return 0;
237 free_content:
238         free_simple_func_content(&other->func);
239 free_other:
240         free(other);
241 out:
242         return -ENOMEM;
243 }
244
245 #define DEFINE_USB_FUNCTION_WITH_SERVICE(_id, _name, _service)          \
246         static struct usb_function_with_service _##_name##_function = { \
247                 .func = {                                               \
248                         .function_group = USB_FUNCTION_GROUP_WITH_SERVICE, \
249                         .id = _id,                                      \
250                         .name = #_name,                                 \
251                         .instance = "default",                          \
252                         .clone = clone_func_with_service,               \
253                         .free_func = free_func_with_service,            \
254                 },                                                      \
255                 .service = _service,                                    \
256         }
257
258 DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_SDB, sdb, "sdbd");
259 DEFINE_USB_FUNCTION_WITH_SERVICE(USB_FUNCTION_MTP, mtp, "mtp-responder");
260
261 #define MAKE_FUNC_AVAILABLE(_name, _vname)                              \
262         [FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function
263
264 #define MAKE_FUNC_WS_AVAILABLE(_name, _vname)                           \
265         [FUNC_IDX_FROM_MASK(USB_FUNCTION_##_name)] = &_##_vname##_function.func
266
267 static struct usb_function *_available_funcs[] = {
268         MAKE_FUNC_WS_AVAILABLE(MTP, mtp),
269         MAKE_FUNC_AVAILABLE(ACM, acm),
270         MAKE_FUNC_WS_AVAILABLE(SDB, sdb),
271         MAKE_FUNC_AVAILABLE(RNDIS, rndis),
272         MAKE_FUNC_AVAILABLE(DIAG, diag),
273         MAKE_FUNC_AVAILABLE(CONN_GADGET, conn_gadget),
274         MAKE_FUNC_AVAILABLE(DM, dm),
275         MAKE_FUNC_AVAILABLE(RMNET, rmnet),
276 };
277
278 #undef MAKE_FUNC_AVAILABLE
279
280 struct usb_gadget_id {
281         unsigned int function_mask;
282 };
283
284 struct usb_gadget_translator {
285         struct hw_common common;
286
287         int (*id_to_gadget)(struct usb_gadget_id *gadget_id,
288                          struct usb_gadget **gadget);
289
290         void (*cleanup_gadget)(struct usb_gadget *gadget);
291 };
292
293 int simple_translator_open(struct hw_info *info,
294                 const char *id, struct hw_common **common);
295 int simple_translator_close(struct hw_common *common);
296
297 #endif