1 /* ----------------------------------------------------------------------------
2 * Copyright (c) Huawei Technologies Co., Ltd. 2017-2019. All rights reserved.
3 * Description: LiteOS USB Driver Hicamera Control
4 * Author: huangjieliang
5 * Create: 2017-11-25
6 * Redistribution and use in source and binary forms, with or without modification,
7 * are permitted provided that the following conditions are met:
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
14 * to endorse or promote products derived from this software without specific prior written
15 * permission.
16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
20 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 * --------------------------------------------------------------------------- */
28 /* ----------------------------------------------------------------------------
29 * Notice of Export Control Law
30 * ===============================================
31 * Huawei LiteOS may be subject to applicable export control laws and regulations, which might
32 * include those applicable to Huawei LiteOS of U.S. and the country in which you are located.
33 * Import, export and usage of Huawei LiteOS in any manner by you shall be in compliance with such
34 * applicable export control laws and regulations.
35 * --------------------------------------------------------------------------- */
36
37 #include "implementation/global_implementation.h"
38 #include "hicamera_control.h"
39 #include "gadget/f_uvc.h"
40
41 #ifdef __cplusplus
42 #if __cplusplus
43 extern "C" {
44 #endif /* __cplusplus */
45 #endif /* __cplusplus */
46
47 #define UVC_UNIT_MAP_SIZE 4
48 static struct uvc_camera_cmd g_cmd_map[CMD_MAX_NUM] = {0};
49 static bool g_uvc_unit_is_register = false;
50 static struct uvc_camera_cmd g_uvc_unit_mappings[UVC_UNIT_MAP_SIZE];
51 DEFINE_SPINLOCK(g_cmd_spinlock);
52
cmd_check(struct uvc_camera_cmd * cmd)53 static int cmd_check(struct uvc_camera_cmd *cmd)
54 {
55 if (cmd->id >= CMD_MAX_NUM)
56 {
57 usb_err("the cmd id is too big, make sure it less than %d\n", CMD_MAX_NUM);
58 return -1;
59 }
60
61 return 0;
62 }
63
uvc_unit_control_register(void)64 void uvc_unit_control_register(void)
65 {
66 int ret;
67 uint32_t i;
68
69 if (g_uvc_unit_is_register == false)
70 {
71 hi_camera_cmd_init();
72
73 for (i = 0; i < sizeof(g_uvc_unit_mappings) / sizeof(g_uvc_unit_mappings[0]); i++)
74 {
75 ret = hi_camera_register_cmd(&g_uvc_unit_mappings[i]);
76 if (ret < 0)
77 {
78 usb_err("register cmd failed\n");
79 }
80 }
81 }
82 }
83
run_cmd_func(void * buf,uint32_t len,uint32_t event_id,uint32_t cmdtype,uint32_t cmd_id)84 int run_cmd_func(void *buf, uint32_t len, uint32_t event_id, uint32_t cmdtype, uint32_t cmd_id)
85 {
86 struct uvc_camera_cmd *cmd_cb;
87 uint32_t flags;
88 int ret;
89
90 if (cmd_id >= CMD_MAX_NUM)
91 {
92 return -1;
93 }
94
95 spin_lock_irqsave(&g_cmd_spinlock, flags);
96 cmd_cb = &g_cmd_map[cmd_id];
97
98 ret = cmd_check(cmd_cb);
99 if (ret < 0)
100 {
101 spin_unlock_irqrestore(&g_cmd_spinlock, flags);
102 usb_err("cmd check is invalid\n");
103 return -1;
104 }
105
106 if (cmd_cb->uvc_control_func != NULL)
107 {
108 ret = (int)cmd_cb->uvc_control_func(buf, len, event_id, cmdtype);
109 }
110 spin_unlock_irqrestore(&g_cmd_spinlock, flags);
111
112 return ret;
113 }
114
hi_camera_cmd_init(void)115 void hi_camera_cmd_init(void)
116 {
117 uint32_t flags;
118
119 spin_lock_irqsave(&g_cmd_spinlock, flags);
120 (void)memset_s(g_cmd_map, (CMD_MAX_NUM * sizeof(struct uvc_camera_cmd)),
121 0, (CMD_MAX_NUM * sizeof(struct uvc_camera_cmd)));
122 g_uvc_unit_is_register = false;
123 spin_unlock_irqrestore(&g_cmd_spinlock, flags);
124 }
125
new_cmd_add(struct uvc_camera_cmd * cmd)126 static void new_cmd_add(struct uvc_camera_cmd *cmd)
127 {
128 uint32_t cmd_id = cmd->id;
129 struct uvc_camera_cmd *cmd_cb = &g_cmd_map[cmd_id];
130
131 cmd_cb->id = cmd_id;
132 (void)memcpy_s(cmd_cb->name, sizeof(cmd_cb->name), cmd->name, sizeof(cmd->name));
133 cmd_cb->uvc_control_func = cmd->uvc_control_func;
134 }
135
hi_camera_register_cmd(struct uvc_camera_cmd * cmd)136 int hi_camera_register_cmd(struct uvc_camera_cmd *cmd)
137 {
138 uint32_t flags;
139 int ret;
140
141 if (cmd == NULL)
142 {
143 usb_err("the arg is NULL\n");
144 return -1;
145 }
146
147 ret = cmd_check(cmd);
148 if (ret == -1)
149 {
150 usb_err("cmd check is invalid\n");
151 return -1;
152 }
153
154 spin_lock_irqsave(&g_cmd_spinlock, flags);
155 new_cmd_add(cmd);
156 g_uvc_unit_is_register = true;
157 spin_unlock_irqrestore(&g_cmd_spinlock, flags);
158
159 return 0;
160 }
161
hi_camera_cmd_info_print(void)162 void hi_camera_cmd_info_print(void)
163 {
164 int i;
165
166 for (i = 0; i < CMD_MAX_NUM; i++)
167 {
168 dprintf("cmd_id=%u, name:%s, func:%x\n", g_cmd_map[i].id, g_cmd_map[i].name, g_cmd_map[i].uvc_control_func);
169 }
170 }
171
camera_unit_control_sample(void * buf,uint32_t len,uint32_t cmdtype)172 static uint32_t camera_unit_control_sample(void *buf, uint32_t len, uint32_t cmdtype)
173 {
174 uint8_t *data = (uint8_t *)buf;
175 uint32_t ret = 0;
176
177 (void)len;
178
179 switch (cmdtype)
180 {
181 case UVC_RC_SETCUR:
182 case UVC_RC_GETCUR:
183 case UVC_RC_GETMIN:
184 ret = 4;
185 break;
186
187 case UVC_RC_GETLEN:
188 data[0] = 0x40;
189 data[1] = 0x00;
190 ret = 2;
191 break;
192
193 case UVC_RC_GETINFO:
194 data[0] = 0x03;
195 ret = 1;
196 break;
197
198 default:
199 break;
200 }
201
202 return ret;
203 }
204
hicamera_unit_control(void * buf,uint32_t len,uint32_t event_id,uint32_t cmdtype)205 static uint32_t hicamera_unit_control(void *buf, uint32_t len, uint32_t event_id, uint32_t cmdtype)
206 {
207 uint32_t ret;
208
209 PRINT_INFO("%s %d, event_id=%u, len=%u, cmdtype=%02x\n", __FUNCTION__, __LINE__, event_id, len, cmdtype);
210
211 switch(event_id)
212 {
213 case HICAMERA_GET_VERSION_CONTROL:
214 case HICAMERA_START_UPDATE_CONTROL:
215 case HICAMERA_TRUN_ON_CONTROL:
216 case HICAMERA_RESET_CONTROL:
217 case HICAMERA_TRUN_OFF_CONTROL:
218 case HICAMERA_VIBRATOR_UP_CONTROL:
219 case HICAMERA_VIBRATOR_DOWN_CONTROL:
220 case HICAMERA_VIBRATOR_LEFT_CONTROL:
221 case HICAMERA_VIBRATOR_RIGHT_CONTROL:
222 default:
223 ret = camera_unit_control_sample(buf, len, cmdtype);
224 break;
225 }
226
227 return ret;
228 }
229
h264_unit_control(void * buf,uint32_t len,uint32_t event_id,uint32_t cmdtype)230 static uint32_t h264_unit_control(void *buf, uint32_t len, uint32_t event_id, uint32_t cmdtype)
231 {
232 uint32_t ret = 0;
233 uint8_t *data = (uint8_t *)buf;
234
235 PRINT_INFO("%s %d, event_id=%u, len=%u, cmdtype=%02x\n", __FUNCTION__, __LINE__, event_id, len, cmdtype);
236
237 switch (cmdtype)
238 {
239 case UVC_RC_SETCUR:
240 ret = 4;
241 break;
242
243 case UVC_RC_GETLEN:
244 data[0] = 0x40;
245 data[1] = 0x00;
246 ret = 0x2;
247 break;
248
249 case UVC_RC_GETINFO:
250 data[0] = 0x3;
251 ret = 0x1;
252 break;
253
254 case UVC_RC_GETMIN:
255 case UVC_RC_GETMAX:
256 case UVC_RC_GETRES:
257 case UVC_RC_GETDEF:
258 ret = 4;
259 break;
260
261 default:
262 usb_err("Yet to be supported cmdtype: %#x\n", cmdtype);
263 break;
264 }
265
266 return ret;
267 }
268
histream_pu_set_brightness(uint16_t val)269 static void histream_pu_set_brightness(uint16_t val)
270 {
271 PRINT_INFO("set brightness val = %u\n", val);
272 }
273
histream_pu_get_brightness(void)274 static uint16_t histream_pu_get_brightness(void)
275 {
276 const uint16_t cur_val = 30;
277
278 PRINT_INFO("get brightness val = %u\n", cur_val);
279
280 return cur_val;
281 }
282
sample_uvc_pu_brightness_ctrl(void * buf,uint32_t len,uint32_t cmdtype)283 static uint32_t sample_uvc_pu_brightness_ctrl(void *buf, uint32_t len, uint32_t cmdtype)
284 {
285 uint32_t ret = 0;
286 uint8_t *data = (uint8_t *)buf;
287 uint16_t val;
288
289 (void)len;
290
291 switch (cmdtype)
292 {
293 case UVC_RC_SETCUR:
294 val = data[0] + (data[1] << 8);
295 histream_pu_set_brightness(val);
296 ret = 2;
297 break;
298
299 case UVC_RC_GETCUR:
300 val = histream_pu_get_brightness();
301 data[0] = val & 0xff;
302 data[1] = (val >> 8) & 0xff;
303 ret = 2;
304 break;
305
306 case UVC_RC_GETRES:
307 data[0] = 0x1;
308 ret = 2;
309 break;
310
311 case UVC_RC_GETINFO:
312 data[0] = 0x3;
313 ret = 1;
314 break;
315
316 case UVC_RC_GETMIN:
317 val = 0;
318 data[0] = val & 0xff;
319 data[1] = (val >> 8) & 0xff;
320 ret = 2;
321 break;
322
323 case UVC_RC_GETMAX:
324 val = 0x64;
325 data[0] = val & 0xff;
326 data[1] = (val >> 8) & 0xff;
327 ret = 2;
328 break;
329
330 case UVC_RC_GETDEF:
331 val = 0x32;
332 data[0] = val & 0xff;
333 data[1] = (val >> 8) & 0xff;
334 ret = 2;
335 break;
336
337 default:
338 break;
339 }
340
341 return ret;
342 }
343
histream_pu_set_contrast(uint16_t val)344 static void histream_pu_set_contrast(uint16_t val)
345 {
346 PRINT_INFO("set contrast val = %u\n", val);
347 }
348
histream_pu_get_contrast(void)349 static uint16_t histream_pu_get_contrast(void)
350 {
351 const uint16_t cur_cal = 30;
352
353 PRINT_INFO("get contrast val = %u\n", __FUNCTION__, __LINE__);
354
355 return cur_cal;
356 }
357
sample_uvc_pu_contrast_ctrl(void * buf,uint32_t len,uint32_t cmdtype)358 static uint32_t sample_uvc_pu_contrast_ctrl(void *buf, uint32_t len, uint32_t cmdtype)
359 {
360 uint32_t ret = 0;
361 uint8_t *data = (uint8_t *)buf;
362 uint16_t val;
363
364 (void)len;
365
366 switch (cmdtype)
367 {
368 case UVC_RC_SETCUR:
369 val = data[0] + (data[1] << 8);
370 histream_pu_set_contrast(val);
371 ret = 2;
372 break;
373
374 case UVC_RC_GETCUR:
375 val = histream_pu_get_contrast();
376 data[0] = val & 0xff;
377 data[1] = (val >> 8) & 0xff;
378 ret = 2;
379 break;
380
381 case UVC_RC_GETRES:
382 data[0] = 0x1;
383 ret = 2;
384 break;
385
386 case UVC_RC_GETINFO:
387 data[0] = 0x3;
388 ret = 1;
389 break;
390
391 case UVC_RC_GETMIN:
392 val = 0;
393 data[0] = val & 0xff;
394 data[1] = (val >> 8) & 0xff;
395 ret = 2;
396 break;
397
398 case UVC_RC_GETMAX:
399 val = 0x64;
400 data[0] = val & 0xff;
401 data[1] = (val >> 8) & 0xff;
402 ret = 2;
403 break;
404
405 case UVC_RC_GETDEF:
406 val = 0x32;
407 data[0] = val & 0xff;
408 data[1] = (val >> 8) & 0xff;
409 ret = 2;
410 break;
411
412 default:
413 break;
414 }
415
416 return ret;
417 }
418
uvc_process_unit_contorl(void * buf,uint32_t len,uint32_t event_id,uint32_t cmdtype)419 static uint32_t uvc_process_unit_contorl(void *buf, uint32_t len, uint32_t event_id, uint32_t cmdtype)
420 {
421 uint32_t ret = 0;
422
423 PRINT_INFO("%s %d, event_id=%u, len=%u, cmdtype=%02x\n", __FUNCTION__, __LINE__, event_id, len, cmdtype);
424
425 switch (event_id)
426 {
427 case USBD_UVC_PU_CONTROL_UNDEFINED:
428 break;
429
430 case USBD_UVC_PU_BACKLIGHT_COMPENSATION_CONTROL:
431 break;
432
433 case USBD_UVC_PU_BRIGHTNESS_CONTROL:
434 ret = sample_uvc_pu_brightness_ctrl(buf, len, cmdtype);
435 break;
436
437 case USBD_UVC_PU_CONTRAST_CONTROL:
438 ret = sample_uvc_pu_contrast_ctrl(buf, len, cmdtype);
439 break;
440
441 case USBD_UVC_PU_GAIN_CONTROL:
442 break;
443
444 case USBD_UVC_PU_POWER_LINE_FREQUENCY_CONTROL:
445 break;
446
447 case USBD_UVC_PU_HUE_CONTROL:
448 break;
449
450 case USBD_UVC_PU_SATURATION_CONTROL:
451 break;
452
453 case USBD_UVC_PU_SHARPNESS_CONTROL:
454 break;
455
456 case USBD_UVC_PU_GAMMA_CONTROL:
457 break;
458
459 case USBD_UVC_PU_WHITE_BALANCE_TEMPERATURE_CONTROL:
460 break;
461
462 case USBD_UVC_PU_WHITE_BALANCE_TEMPERATURE_AUTO_CONTORL:
463 break;
464
465 case USBD_UVC_PU_WHITE_BALANCE_COMPONENT_CONTROL:
466 break;
467
468 case USBD_UVC_PU_WHITE_BALANCE_COMPONENT_AUTO_CONTROL:
469 break;
470
471 case USBD_UVC_PU_DIGITAL_MULTIPLIER_CONTROL:
472 break;
473
474 case USBD_UVC_PU_DIGITAL_MULTIPLIER_LIMIT_CONTROL:
475 break;
476
477 case USBD_UVC_PU_HUE_AUTO_CONTROL:
478 break;
479
480 case USBD_UVC_PU_ANALOG_VIDEO_STANDARD_CONTROL:
481 break;
482
483 case USBD_UVC_PU_ANALOG_LOCK_STATUS_CONTROL:
484 break;
485
486 case USBD_UVC_PU_CONTRAST_AUTO_CONTROL:
487 break;
488
489 default:
490 break;
491 }
492
493 return ret;
494 }
495
camera_terminal_unit_contorl(void * buf,uint32_t len,uint32_t event_id,uint32_t cmdtype)496 static uint32_t camera_terminal_unit_contorl(void *buf, uint32_t len, uint32_t event_id, uint32_t cmdtype)
497 {
498 (void)buf;
499
500 PRINT_INFO("%s %d, event_id=%u, len=%u, cmdtype=%02x\n", __FUNCTION__, __LINE__, event_id, len, cmdtype);
501
502 switch (event_id)
503 {
504 case USBD_UVC_CT_CONTROL_UNDEFINED:
505 break;
506
507 case USBD_UVC_CT_SCANNING_MODE_CONTROL:
508 break;
509
510 case USBD_UVC_CT_AE_MODE_CONTROL:
511 break;
512
513 case USBD_UVC_CT_AE_PRIORITY_CONTROL:
514 break;
515
516 case USBD_UVC_CT_EXPOSURE_TIME_ABSOLUTE_CONTROL:
517 break;
518
519 case USBD_UVC_CT_EXPOSURE_TIME_RELATIVE_CONTROL:
520 break;
521
522 case USBD_UVC_CT_FOCUS_ABSOLUTE_CONTROL:
523 break;
524
525 case USBD_UVC_CT_FOCUS_RELATIVE_CONTROL:
526 break;
527
528 case USBD_UVC_CT_FOCUS_AUTO_CONTROL:
529 break;
530
531 case USBD_UVC_CT_IRIS_ABSOLUTE_CONTROL:
532 break;
533
534 case USBD_UVC_CT_IRIS_RELATIVE_CONTROL:
535 break;
536
537 case USBD_UVC_CT_ZOOM_ABSOLUTE_CONTROL:
538 break;
539
540 case USBD_UVC_CT_ZOOM_RELATIVE_CONTROL:
541 break;
542
543 case USBD_UVC_CT_PANTILT_ABSOLUTE_CONTROL:
544 break;
545
546 case USBD_UVC_CT_PANTILT_RELATIVE_CONTROL:
547 break;
548
549 case USBD_UVC_CT_ROLL_ABSOLUTE_CONTROL:
550 break;
551
552 case USBD_UVC_CT_ROLL_RELATIVE_CONTROL:
553 break;
554
555 case USBD_UVC_CT_PRIVACY_CONTROL:
556 break;
557
558 case USBD_UVC_CT_FOCUS_SIMPLE_CONTROL:
559 break;
560
561 case USBD_UVC_CT_WINDOW_CONTROL:
562 break;
563
564 case USBD_UVC_CT_REGION_OF_INTEREST_CONTROL:
565 break;
566
567 default:
568 break;
569 }
570
571 return 0;
572 }
573
574 static struct uvc_camera_cmd g_uvc_unit_mappings[UVC_UNIT_MAP_SIZE] =
575 {
576 {
577 .id = CMD_HICAMERA_UNIT_CONTROL,
578 .name = "hicamera_unit_control",
579 .uvc_control_func = hicamera_unit_control,
580 },
581 {
582 .id = CMD_H264_UNIT_CONTROL,
583 .name = "h264_unit_control",
584 .uvc_control_func = h264_unit_control,
585 },
586 {
587 .id = CMD_CAMERA_UNIT_CONTROL,
588 .name = "camera_terminal_unit_contorl",
589 .uvc_control_func = camera_terminal_unit_contorl,
590 },
591 {
592 .id = CMD_PROCESS_UNIT_CONTROL,
593 .name = "uvc_process_unit_contorl",
594 .uvc_control_func = uvc_process_unit_contorl,
595 },
596 };
597
598 #ifdef __cplusplus
599 #if __cplusplus
600 }
601 #endif /* __cplusplus */
602 #endif /* __cplusplus */
603