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 43extern "C" { 44#endif /* __cplusplus */ 45#endif /* __cplusplus */ 46 47#define UVC_UNIT_MAP_SIZE 4 48static struct uvc_camera_cmd g_cmd_map[CMD_MAX_NUM] = {0}; 49static bool g_uvc_unit_is_register = false; 50static struct uvc_camera_cmd g_uvc_unit_mappings[UVC_UNIT_MAP_SIZE]; 51DEFINE_SPINLOCK(g_cmd_spinlock); 52 53static 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 64void 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 84int 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 115void 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 126static 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 136int 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 162void 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 172static 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 205static 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 230static 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 269static void histream_pu_set_brightness(uint16_t val) 270{ 271 PRINT_INFO("set brightness val = %u\n", val); 272} 273 274static 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 283static 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 344static void histream_pu_set_contrast(uint16_t val) 345{ 346 PRINT_INFO("set contrast val = %u\n", val); 347} 348 349static 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 358static 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 419static 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 496static 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 574static 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