• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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