1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 // To remove 31 #include <cutils/properties.h> 32 33 // System dependencies 34 #include <pthread.h> 35 #include <errno.h> 36 #include <fcntl.h> 37 #include <stdlib.h> 38 #include <dlfcn.h> 39 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h> 40 #include IOCTL_H 41 42 // Camera dependencies 43 #include "cam_semaphore.h" 44 #include "mm_camera_dbg.h" 45 #include "mm_camera_sock.h" 46 #include "mm_camera_interface.h" 47 #include "mm_camera.h" 48 #include "cam_cond.h" 49 50 #define SET_PARM_BIT32(parm, parm_arr) \ 51 (parm_arr[parm/32] |= (1<<(parm%32))) 52 53 #define GET_PARM_BIT32(parm, parm_arr) \ 54 ((parm_arr[parm/32]>>(parm%32))& 0x1) 55 56 /* internal function declare */ 57 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj, 58 uint8_t reg_flag); 59 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj, 60 mm_camera_event_t *event); 61 extern mm_camera_obj_t* mm_camera_util_get_camera_by_session_id 62 (uint32_t session_id); 63 64 /*=========================================================================== 65 * FUNCTION : mm_camera_util_get_channel_by_handler 66 * 67 * DESCRIPTION: utility function to get a channel object from its handle 68 * 69 * PARAMETERS : 70 * @cam_obj: ptr to a camera object 71 * @handler: channel handle 72 * 73 * RETURN : ptr to a channel object. 74 * NULL if failed. 75 *==========================================================================*/ 76 mm_channel_t * mm_camera_util_get_channel_by_handler( 77 mm_camera_obj_t * cam_obj, 78 uint32_t handler) 79 { 80 int i; 81 mm_channel_t *ch_obj = NULL; 82 for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) { 83 if (handler == cam_obj->ch[i].my_hdl) { 84 ch_obj = &cam_obj->ch[i]; 85 break; 86 } 87 } 88 return ch_obj; 89 } 90 91 /*=========================================================================== 92 * FUNCTION : mm_camera_util_chip_is_a_family 93 * 94 * DESCRIPTION: utility function to check if the host is A family chip 95 * 96 * PARAMETERS : 97 * 98 * RETURN : TRUE if A family. 99 * FALSE otherwise. 100 *==========================================================================*/ 101 uint8_t mm_camera_util_chip_is_a_family(void) 102 { 103 #ifdef USE_A_FAMILY 104 return TRUE; 105 #else 106 return FALSE; 107 #endif 108 } 109 110 /*=========================================================================== 111 * FUNCTION : mm_camera_dispatch_app_event 112 * 113 * DESCRIPTION: dispatch event to apps who regitster for event notify 114 * 115 * PARAMETERS : 116 * @cmd_cb: ptr to a struct storing event info 117 * @user_data: user data ptr (camera object) 118 * 119 * RETURN : none 120 *==========================================================================*/ 121 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb, 122 void* user_data) 123 { 124 int i; 125 mm_camera_event_t *event = &cmd_cb->u.evt; 126 mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data; 127 if (NULL != my_obj) { 128 mm_camera_cmd_thread_name(my_obj->evt_thread.threadName); 129 pthread_mutex_lock(&my_obj->cb_lock); 130 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 131 if(my_obj->evt.evt[i].evt_cb) { 132 my_obj->evt.evt[i].evt_cb( 133 my_obj->my_hdl, 134 event, 135 my_obj->evt.evt[i].user_data); 136 } 137 } 138 pthread_mutex_unlock(&my_obj->cb_lock); 139 } 140 } 141 142 /*=========================================================================== 143 * FUNCTION : mm_camera_event_notify 144 * 145 * DESCRIPTION: callback to handle event notify from kernel. This call will 146 * dequeue event from kernel. 147 * 148 * PARAMETERS : 149 * @user_data: user data ptr (camera object) 150 * 151 * RETURN : none 152 *==========================================================================*/ 153 static void mm_camera_event_notify(void* user_data) 154 { 155 struct v4l2_event ev; 156 struct msm_v4l2_event_data *msm_evt = NULL; 157 int rc; 158 mm_camera_event_t evt; 159 memset(&evt, 0, sizeof(mm_camera_event_t)); 160 161 mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data; 162 if (NULL != my_obj) { 163 /* read evt */ 164 memset(&ev, 0, sizeof(ev)); 165 rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev); 166 167 if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) { 168 msm_evt = (struct msm_v4l2_event_data *)ev.u.data; 169 switch (msm_evt->command) { 170 case CAM_EVENT_TYPE_DAEMON_PULL_REQ: 171 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ; 172 mm_camera_enqueue_evt(my_obj, &evt); 173 break; 174 case CAM_EVENT_TYPE_MAP_UNMAP_DONE: 175 pthread_mutex_lock(&my_obj->evt_lock); 176 my_obj->evt_rcvd.server_event_type = msm_evt->command; 177 my_obj->evt_rcvd.status = msm_evt->status; 178 pthread_cond_signal(&my_obj->evt_cond); 179 pthread_mutex_unlock(&my_obj->evt_lock); 180 break; 181 case CAM_EVENT_TYPE_INT_TAKE_JPEG: 182 case CAM_EVENT_TYPE_INT_TAKE_RAW: 183 { 184 evt.server_event_type = msm_evt->command; 185 mm_camera_enqueue_evt(my_obj, &evt); 186 } 187 break; 188 case MSM_CAMERA_PRIV_SHUTDOWN: 189 { 190 LOGE("Camera Event DAEMON DIED received"); 191 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED; 192 mm_camera_enqueue_evt(my_obj, &evt); 193 } 194 break; 195 case CAM_EVENT_TYPE_CAC_DONE: 196 { 197 evt.server_event_type = CAM_EVENT_TYPE_CAC_DONE; 198 mm_camera_enqueue_evt(my_obj, &evt); 199 } 200 break; 201 default: 202 break; 203 } 204 } 205 } 206 } 207 208 /*=========================================================================== 209 * FUNCTION : mm_camera_enqueue_evt 210 * 211 * DESCRIPTION: enqueue received event into event queue to be processed by 212 * event thread. 213 * 214 * PARAMETERS : 215 * @my_obj : ptr to a camera object 216 * @event : event to be queued 217 * 218 * RETURN : int32_t type of status 219 * 0 -- success 220 * -1 -- failure 221 *==========================================================================*/ 222 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj, 223 mm_camera_event_t *event) 224 { 225 int32_t rc = 0; 226 mm_camera_cmdcb_t *node = NULL; 227 228 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 229 if (NULL != node) { 230 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 231 node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB; 232 node->u.evt = *event; 233 234 /* enqueue to evt cmd thread */ 235 cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node); 236 /* wake up evt cmd thread */ 237 cam_sem_post(&(my_obj->evt_thread.cmd_sem)); 238 } else { 239 LOGE("No memory for mm_camera_node_t"); 240 rc = -1; 241 } 242 243 return rc; 244 } 245 246 /*=========================================================================== 247 * FUNCTION : mm_camera_open 248 * 249 * DESCRIPTION: open a camera 250 * 251 * PARAMETERS : 252 * @my_obj : ptr to a camera object 253 * 254 * RETURN : int32_t type of status 255 * 0 -- success 256 * -1 -- failure 257 *==========================================================================*/ 258 int32_t mm_camera_open(mm_camera_obj_t *my_obj) 259 { 260 char dev_name[MM_CAMERA_DEV_NAME_LEN]; 261 int32_t rc = 0; 262 int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES; 263 uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP; 264 int cam_idx = 0; 265 const char *dev_name_value = NULL; 266 int l_errno = 0; 267 268 LOGD("begin\n"); 269 270 if (NULL == my_obj) { 271 goto on_error; 272 } 273 dev_name_value = mm_camera_util_get_dev_name(my_obj->my_hdl); 274 if (NULL == dev_name_value) { 275 goto on_error; 276 } 277 snprintf(dev_name, sizeof(dev_name), "/dev/%s", 278 dev_name_value); 279 sscanf(dev_name, "/dev/video%d", &cam_idx); 280 LOGD("dev name = %s, cam_idx = %d", dev_name, cam_idx); 281 282 do{ 283 n_try--; 284 errno = 0; 285 my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK); 286 l_errno = errno; 287 LOGD("ctrl_fd = %d, errno == %d", my_obj->ctrl_fd, l_errno); 288 if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) { 289 break; 290 } 291 LOGE("Failed with %s error, retrying after %d milli-seconds", 292 strerror(errno), sleep_msec); 293 usleep(sleep_msec * 1000U); 294 }while (n_try > 0); 295 296 if (my_obj->ctrl_fd < 0) { 297 LOGE("cannot open control fd of '%s' (%s)\n", 298 dev_name, strerror(l_errno)); 299 if (l_errno == EBUSY) 300 rc = -EUSERS; 301 else 302 rc = -1; 303 goto on_error; 304 } else { 305 mm_camera_get_session_id(my_obj, &my_obj->sessionid); 306 LOGH("Camera Opened id = %d sessionid = %d", cam_idx, my_obj->sessionid); 307 } 308 309 #ifdef DAEMON_PRESENT 310 /* open domain socket*/ 311 n_try = MM_CAMERA_DEV_OPEN_TRIES; 312 do { 313 n_try--; 314 my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP); 315 l_errno = errno; 316 LOGD("ds_fd = %d, errno = %d", my_obj->ds_fd, l_errno); 317 if((my_obj->ds_fd >= 0) || (n_try <= 0 )) { 318 LOGD("opened, break out while loop"); 319 break; 320 } 321 LOGD("failed with I/O error retrying after %d milli-seconds", 322 sleep_msec); 323 usleep(sleep_msec * 1000U); 324 } while (n_try > 0); 325 326 if (my_obj->ds_fd < 0) { 327 LOGE("cannot open domain socket fd of '%s'(%s)\n", 328 dev_name, strerror(l_errno)); 329 rc = -1; 330 goto on_error; 331 } 332 #else /* DAEMON_PRESENT */ 333 cam_status_t cam_status; 334 cam_status = mm_camera_module_open_session(my_obj->sessionid, 335 mm_camera_module_event_handler); 336 if (cam_status < 0) { 337 LOGE("Failed to open session"); 338 if (cam_status == CAM_STATUS_BUSY) { 339 rc = -EUSERS; 340 } else { 341 rc = -1; 342 } 343 goto on_error; 344 } 345 #endif /* DAEMON_PRESENT */ 346 347 pthread_mutex_init(&my_obj->msg_lock, NULL); 348 pthread_mutex_init(&my_obj->cb_lock, NULL); 349 pthread_mutex_init(&my_obj->evt_lock, NULL); 350 PTHREAD_COND_INIT(&my_obj->evt_cond); 351 352 LOGD("Launch evt Thread in Cam Open"); 353 snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch"); 354 mm_camera_cmd_thread_launch(&my_obj->evt_thread, 355 mm_camera_dispatch_app_event, 356 (void *)my_obj); 357 358 /* launch event poll thread 359 * we will add evt fd into event poll thread upon user first register for evt */ 360 LOGD("Launch evt Poll Thread in Cam Open"); 361 snprintf(my_obj->evt_poll_thread.threadName, THREAD_NAME_SIZE, "CAM_evntPoll"); 362 mm_camera_poll_thread_launch(&my_obj->evt_poll_thread, 363 MM_CAMERA_POLL_TYPE_EVT); 364 mm_camera_evt_sub(my_obj, TRUE); 365 366 /* unlock cam_lock, we need release global intf_lock in camera_open(), 367 * in order not block operation of other Camera in dual camera use case.*/ 368 pthread_mutex_unlock(&my_obj->cam_lock); 369 LOGD("end (rc = %d)\n", rc); 370 return rc; 371 372 on_error: 373 374 if (NULL == dev_name_value) { 375 LOGE("Invalid device name\n"); 376 rc = -1; 377 } 378 379 if (NULL == my_obj) { 380 LOGE("Invalid camera object\n"); 381 rc = -1; 382 } else { 383 if (my_obj->ctrl_fd >= 0) { 384 close(my_obj->ctrl_fd); 385 my_obj->ctrl_fd = -1; 386 } 387 #ifdef DAEMON_PRESENT 388 if (my_obj->ds_fd >= 0) { 389 mm_camera_socket_close(my_obj->ds_fd); 390 my_obj->ds_fd = -1; 391 } 392 #endif 393 } 394 395 /* unlock cam_lock, we need release global intf_lock in camera_open(), 396 * in order not block operation of other Camera in dual camera use case.*/ 397 pthread_mutex_unlock(&my_obj->cam_lock); 398 return rc; 399 } 400 401 /*=========================================================================== 402 * FUNCTION : mm_camera_close 403 * 404 * DESCRIPTION: enqueue received event into event queue to be processed by 405 * event thread. 406 * 407 * PARAMETERS : 408 * @my_obj : ptr to a camera object 409 * @event : event to be queued 410 * 411 * RETURN : int32_t type of status 412 * 0 -- success 413 * -1 -- failure 414 *==========================================================================*/ 415 int32_t mm_camera_close(mm_camera_obj_t *my_obj) 416 { 417 LOGD("unsubscribe evt"); 418 419 #ifndef DAEMON_PRESENT 420 mm_camera_module_close_session(my_obj->sessionid); 421 #endif /* DAEMON_PRESENT */ 422 423 mm_camera_evt_sub(my_obj, FALSE); 424 425 LOGD("Close evt Poll Thread in Cam Close"); 426 mm_camera_poll_thread_release(&my_obj->evt_poll_thread); 427 428 LOGD("Close evt cmd Thread in Cam Close"); 429 mm_camera_cmd_thread_release(&my_obj->evt_thread); 430 431 if(my_obj->ctrl_fd >= 0) { 432 close(my_obj->ctrl_fd); 433 my_obj->ctrl_fd = -1; 434 } 435 436 #ifdef DAEMON_PRESENT 437 if(my_obj->ds_fd >= 0) { 438 mm_camera_socket_close(my_obj->ds_fd); 439 my_obj->ds_fd = -1; 440 } 441 #endif 442 443 pthread_mutex_destroy(&my_obj->msg_lock); 444 pthread_mutex_destroy(&my_obj->cb_lock); 445 pthread_mutex_destroy(&my_obj->evt_lock); 446 pthread_cond_destroy(&my_obj->evt_cond); 447 pthread_mutex_unlock(&my_obj->cam_lock); 448 return 0; 449 } 450 451 /*=========================================================================== 452 * FUNCTION : mm_camera_register_event_notify_internal 453 * 454 * DESCRIPTION: internal implementation for registering callback for event notify. 455 * 456 * PARAMETERS : 457 * @my_obj : ptr to a camera object 458 * @evt_cb : callback to be registered to handle event notify 459 * @user_data: user data ptr 460 * 461 * RETURN : int32_t type of status 462 * 0 -- success 463 * -1 -- failure 464 *==========================================================================*/ 465 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj, 466 mm_camera_event_notify_t evt_cb, 467 void * user_data) 468 { 469 int i; 470 int rc = -1; 471 mm_camera_evt_obj_t *evt_array = NULL; 472 473 pthread_mutex_lock(&my_obj->cb_lock); 474 evt_array = &my_obj->evt; 475 if(evt_cb) { 476 /* this is reg case */ 477 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 478 if(evt_array->evt[i].user_data == NULL) { 479 evt_array->evt[i].evt_cb = evt_cb; 480 evt_array->evt[i].user_data = user_data; 481 evt_array->reg_count++; 482 rc = 0; 483 break; 484 } 485 } 486 } else { 487 /* this is unreg case */ 488 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 489 if(evt_array->evt[i].user_data == user_data) { 490 evt_array->evt[i].evt_cb = NULL; 491 evt_array->evt[i].user_data = NULL; 492 evt_array->reg_count--; 493 rc = 0; 494 break; 495 } 496 } 497 } 498 499 pthread_mutex_unlock(&my_obj->cb_lock); 500 return rc; 501 } 502 503 /*=========================================================================== 504 * FUNCTION : mm_camera_register_event_notify 505 * 506 * DESCRIPTION: registering a callback for event notify. 507 * 508 * PARAMETERS : 509 * @my_obj : ptr to a camera object 510 * @evt_cb : callback to be registered to handle event notify 511 * @user_data: user data ptr 512 * 513 * RETURN : int32_t type of status 514 * 0 -- success 515 * -1 -- failure 516 *==========================================================================*/ 517 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj, 518 mm_camera_event_notify_t evt_cb, 519 void * user_data) 520 { 521 int rc = -1; 522 rc = mm_camera_register_event_notify_internal(my_obj, 523 evt_cb, 524 user_data); 525 pthread_mutex_unlock(&my_obj->cam_lock); 526 return rc; 527 } 528 529 /*=========================================================================== 530 * FUNCTION : mm_camera_qbuf 531 * 532 * DESCRIPTION: enqueue buffer back to kernel 533 * 534 * PARAMETERS : 535 * @my_obj : camera object 536 * @ch_id : channel handle 537 * @buf : buf ptr to be enqueued 538 * 539 * RETURN : int32_t type of status 540 * 0 -- success 541 * -1 -- failure 542 *==========================================================================*/ 543 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj, 544 uint32_t ch_id, 545 mm_camera_buf_def_t *buf) 546 { 547 int rc = -1; 548 mm_channel_t * ch_obj = NULL; 549 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id); 550 551 pthread_mutex_unlock(&my_obj->cam_lock); 552 553 /* we always assume qbuf will be done before channel/stream is fully stopped 554 * because qbuf is done within dataCB context 555 * in order to avoid deadlock, we are not locking ch_lock for qbuf */ 556 if (NULL != ch_obj) { 557 rc = mm_channel_qbuf(ch_obj, buf); 558 } 559 560 return rc; 561 } 562 563 /*=========================================================================== 564 * FUNCTION : mm_camera_cancel_buf 565 * 566 * DESCRIPTION: Cancel an already queued buffer 567 * 568 * PARAMETERS : 569 * @my_obj : camera object 570 * @ch_id : channel handle 571 * 572 * @buf : buf ptr to be enqueued 573 * 574 * RETURN : int32_t type of status 575 * 0 -- success 576 * -1 -- failure 577 *==========================================================================*/ 578 int32_t mm_camera_cancel_buf(mm_camera_obj_t *my_obj, 579 uint32_t ch_id, 580 uint32_t stream_id, 581 uint32_t buf_idx) 582 { 583 int rc = -1; 584 mm_channel_t * ch_obj = NULL; 585 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id); 586 587 if (NULL != ch_obj) { 588 pthread_mutex_unlock(&my_obj->cam_lock); 589 rc = mm_channel_cancel_buf(ch_obj,stream_id,buf_idx); 590 } 591 592 return rc; 593 } 594 595 /*=========================================================================== 596 * FUNCTION : mm_camera_get_queued_buf_count 597 * 598 * DESCRIPTION: return queued buffer count 599 * 600 * PARAMETERS : 601 * @my_obj : camera object 602 * @ch_id : channel handle 603 * @stream_id : stream id 604 * 605 * RETURN : queued buffer count 606 *==========================================================================*/ 607 int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj, 608 uint32_t ch_id, uint32_t stream_id) 609 { 610 int rc = -1; 611 mm_channel_t * ch_obj = NULL; 612 uint32_t payload; 613 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id); 614 payload = stream_id; 615 616 if (NULL != ch_obj) { 617 pthread_mutex_lock(&ch_obj->ch_lock); 618 pthread_mutex_unlock(&my_obj->cam_lock); 619 rc = mm_channel_fsm_fn(ch_obj, 620 MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT, 621 (void *)&payload, 622 NULL); 623 } else { 624 pthread_mutex_unlock(&my_obj->cam_lock); 625 } 626 627 return rc; 628 } 629 630 /*=========================================================================== 631 * FUNCTION : mm_camera_query_capability 632 * 633 * DESCRIPTION: query camera capability 634 * 635 * PARAMETERS : 636 * @my_obj: camera object 637 * 638 * RETURN : int32_t type of status 639 * 0 -- success 640 * -1 -- failure 641 *==========================================================================*/ 642 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj) 643 { 644 int32_t rc = 0; 645 646 #ifdef DAEMON_PRESENT 647 struct v4l2_capability cap; 648 /* get camera capabilities */ 649 memset(&cap, 0, sizeof(cap)); 650 rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap); 651 #else /* DAEMON_PRESENT */ 652 cam_shim_packet_t *shim_cmd; 653 cam_shim_cmd_data shim_cmd_data; 654 memset(&shim_cmd_data, 0, sizeof(shim_cmd_data)); 655 shim_cmd_data.command = MSM_CAMERA_PRIV_QUERY_CAP; 656 shim_cmd_data.stream_id = 0; 657 shim_cmd_data.value = NULL; 658 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM, 659 my_obj->sessionid,&shim_cmd_data); 660 rc = mm_camera_module_send_cmd(shim_cmd); 661 mm_camera_destroy_shim_cmd_packet(shim_cmd); 662 #endif /* DAEMON_PRESENT */ 663 if (rc != 0) { 664 LOGE("cannot get camera capabilities, rc = %d, errno %d", 665 rc, errno); 666 } 667 pthread_mutex_unlock(&my_obj->cam_lock); 668 return rc; 669 } 670 671 /*=========================================================================== 672 * FUNCTION : mm_camera_set_parms 673 * 674 * DESCRIPTION: set parameters per camera 675 * 676 * PARAMETERS : 677 * @my_obj : camera object 678 * @parms : ptr to a param struct to be set to server 679 * 680 * RETURN : int32_t type of status 681 * 0 -- success 682 * -1 -- failure 683 * NOTE : Assume the parms struct buf is already mapped to server via 684 * domain socket. Corresponding fields of parameters to be set 685 * are already filled in by upper layer caller. 686 *==========================================================================*/ 687 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj, 688 parm_buffer_t *parms) 689 { 690 int32_t rc = -1; 691 int32_t value = 0; 692 if (parms != NULL) { 693 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, 694 CAM_PRIV_PARM, &value); 695 } 696 pthread_mutex_unlock(&my_obj->cam_lock); 697 return rc; 698 } 699 700 /*=========================================================================== 701 * FUNCTION : mm_camera_get_parms 702 * 703 * DESCRIPTION: get parameters per camera 704 * 705 * PARAMETERS : 706 * @my_obj : camera object 707 * @parms : ptr to a param struct to be get from server 708 * 709 * RETURN : int32_t type of status 710 * 0 -- success 711 * -1 -- failure 712 * NOTE : Assume the parms struct buf is already mapped to server via 713 * domain socket. Parameters to be get from server are already 714 * filled in by upper layer caller. After this call, corresponding 715 * fields of requested parameters will be filled in by server with 716 * detailed information. 717 *==========================================================================*/ 718 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj, 719 parm_buffer_t *parms) 720 { 721 int32_t rc = -1; 722 int32_t value = 0; 723 if (parms != NULL) { 724 rc = mm_camera_util_g_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PARM, &value); 725 } 726 pthread_mutex_unlock(&my_obj->cam_lock); 727 return rc; 728 } 729 730 /*=========================================================================== 731 * FUNCTION : mm_camera_do_auto_focus 732 * 733 * DESCRIPTION: performing auto focus 734 * 735 * PARAMETERS : 736 * @camera_handle: camera handle 737 * 738 * RETURN : int32_t type of status 739 * 0 -- success 740 * -1 -- failure 741 * NOTE : if this call success, we will always assume there will 742 * be an auto_focus event following up. 743 *==========================================================================*/ 744 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj) 745 { 746 int32_t rc = -1; 747 int32_t value = 0; 748 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value); 749 pthread_mutex_unlock(&my_obj->cam_lock); 750 return rc; 751 } 752 753 /*=========================================================================== 754 * FUNCTION : mm_camera_cancel_auto_focus 755 * 756 * DESCRIPTION: cancel auto focus 757 * 758 * PARAMETERS : 759 * @camera_handle: camera handle 760 * 761 * RETURN : int32_t type of status 762 * 0 -- success 763 * -1 -- failure 764 *==========================================================================*/ 765 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj) 766 { 767 int32_t rc = -1; 768 int32_t value = 0; 769 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value); 770 pthread_mutex_unlock(&my_obj->cam_lock); 771 return rc; 772 } 773 774 /*=========================================================================== 775 * FUNCTION : mm_camera_prepare_snapshot 776 * 777 * DESCRIPTION: prepare hardware for snapshot 778 * 779 * PARAMETERS : 780 * @my_obj : camera object 781 * @do_af_flag : flag indicating if AF is needed 782 * 783 * RETURN : int32_t type of status 784 * 0 -- success 785 * -1 -- failure 786 *==========================================================================*/ 787 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj, 788 int32_t do_af_flag) 789 { 790 int32_t rc = -1; 791 int32_t value = do_af_flag; 792 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value); 793 pthread_mutex_unlock(&my_obj->cam_lock); 794 return rc; 795 } 796 797 /*=========================================================================== 798 * FUNCTION : mm_camera_start_zsl_snapshot 799 * 800 * DESCRIPTION: start zsl snapshot 801 * 802 * PARAMETERS : 803 * @my_obj : camera object 804 * 805 * RETURN : int32_t type of status 806 * 0 -- success 807 * -1 -- failure 808 *==========================================================================*/ 809 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj) 810 { 811 int32_t rc = -1; 812 int32_t value = 0; 813 814 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, 815 CAM_PRIV_START_ZSL_SNAPSHOT, &value); 816 return rc; 817 } 818 819 /*=========================================================================== 820 * FUNCTION : mm_camera_stop_zsl_snapshot 821 * 822 * DESCRIPTION: stop zsl capture 823 * 824 * PARAMETERS : 825 * @my_obj : camera object 826 * 827 * RETURN : int32_t type of status 828 * 0 -- success 829 * -1 -- failure 830 *==========================================================================*/ 831 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj) 832 { 833 int32_t rc = -1; 834 int32_t value; 835 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, 836 CAM_PRIV_STOP_ZSL_SNAPSHOT, &value); 837 return rc; 838 } 839 840 /*=========================================================================== 841 * FUNCTION : mm_camera_flush 842 * 843 * DESCRIPTION: flush the current camera state and buffers 844 * 845 * PARAMETERS : 846 * @my_obj : camera object 847 * 848 * RETURN : int32_t type of status 849 * 0 -- success 850 * -1 -- failure 851 *==========================================================================*/ 852 int32_t mm_camera_flush(mm_camera_obj_t *my_obj) 853 { 854 int32_t rc = -1; 855 int32_t value; 856 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, 857 CAM_PRIV_FLUSH, &value); 858 pthread_mutex_unlock(&my_obj->cam_lock); 859 return rc; 860 } 861 862 /*=========================================================================== 863 * FUNCTION : mm_camera_add_channel 864 * 865 * DESCRIPTION: add a channel 866 * 867 * PARAMETERS : 868 * @my_obj : camera object 869 * @attr : bundle attribute of the channel if needed 870 * @channel_cb : callback function for bundle data notify 871 * @userdata : user data ptr 872 * 873 * RETURN : uint32_t type of channel handle 874 * 0 -- invalid channel handle, meaning the op failed 875 * >0 -- successfully added a channel with a valid handle 876 * NOTE : if no bundle data notify is needed, meaning each stream in the 877 * channel will have its own stream data notify callback, then 878 * attr, channel_cb, and userdata can be NULL. In this case, 879 * no matching logic will be performed in channel for the bundling. 880 *==========================================================================*/ 881 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj, 882 mm_camera_channel_attr_t *attr, 883 mm_camera_buf_notify_t channel_cb, 884 void *userdata) 885 { 886 mm_channel_t *ch_obj = NULL; 887 uint8_t ch_idx = 0; 888 uint32_t ch_hdl = 0; 889 890 for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) { 891 if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) { 892 ch_obj = &my_obj->ch[ch_idx]; 893 break; 894 } 895 } 896 897 if (NULL != ch_obj) { 898 /* initialize channel obj */ 899 memset(ch_obj, 0, sizeof(mm_channel_t)); 900 ch_hdl = mm_camera_util_generate_handler(ch_idx); 901 ch_obj->my_hdl = ch_hdl; 902 ch_obj->state = MM_CHANNEL_STATE_STOPPED; 903 ch_obj->cam_obj = my_obj; 904 pthread_mutex_init(&ch_obj->ch_lock, NULL); 905 ch_obj->sessionid = my_obj->sessionid; 906 mm_channel_init(ch_obj, attr, channel_cb, userdata); 907 } 908 909 pthread_mutex_unlock(&my_obj->cam_lock); 910 911 return ch_hdl; 912 } 913 914 /*=========================================================================== 915 * FUNCTION : mm_camera_del_channel 916 * 917 * DESCRIPTION: delete a channel by its handle 918 * 919 * PARAMETERS : 920 * @my_obj : camera object 921 * @ch_id : channel handle 922 * 923 * RETURN : int32_t type of status 924 * 0 -- success 925 * -1 -- failure 926 * NOTE : all streams in the channel should be stopped already before 927 * this channel can be deleted. 928 *==========================================================================*/ 929 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj, 930 uint32_t ch_id) 931 { 932 int32_t rc = -1; 933 mm_channel_t * ch_obj = 934 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 935 936 if (NULL != ch_obj) { 937 pthread_mutex_lock(&ch_obj->ch_lock); 938 pthread_mutex_unlock(&my_obj->cam_lock); 939 940 rc = mm_channel_fsm_fn(ch_obj, 941 MM_CHANNEL_EVT_DELETE, 942 NULL, 943 NULL); 944 945 pthread_mutex_destroy(&ch_obj->ch_lock); 946 memset(ch_obj, 0, sizeof(mm_channel_t)); 947 } else { 948 pthread_mutex_unlock(&my_obj->cam_lock); 949 } 950 return rc; 951 } 952 953 /*=========================================================================== 954 * FUNCTION : mm_camera_get_bundle_info 955 * 956 * DESCRIPTION: query bundle info of the channel 957 * 958 * PARAMETERS : 959 * @my_obj : camera object 960 * @ch_id : channel handle 961 * @bundle_info : bundle info to be filled in 962 * 963 * RETURN : int32_t type of status 964 * 0 -- success 965 * -1 -- failure 966 * NOTE : all streams in the channel should be stopped already before 967 * this channel can be deleted. 968 *==========================================================================*/ 969 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj, 970 uint32_t ch_id, 971 cam_bundle_config_t *bundle_info) 972 { 973 int32_t rc = -1; 974 mm_channel_t * ch_obj = 975 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 976 977 if (NULL != ch_obj) { 978 pthread_mutex_lock(&ch_obj->ch_lock); 979 pthread_mutex_unlock(&my_obj->cam_lock); 980 981 rc = mm_channel_fsm_fn(ch_obj, 982 MM_CHANNEL_EVT_GET_BUNDLE_INFO, 983 (void *)bundle_info, 984 NULL); 985 } else { 986 pthread_mutex_unlock(&my_obj->cam_lock); 987 } 988 return rc; 989 } 990 991 /*=========================================================================== 992 * FUNCTION : mm_camera_link_stream 993 * 994 * DESCRIPTION: link a stream into a channel 995 * 996 * PARAMETERS : 997 * @my_obj : camera object 998 * @ch_id : channel handle 999 * @stream_id : stream that will be linked 1000 * @linked_ch_id : channel in which the stream will be linked 1001 * 1002 * RETURN : uint32_t type of stream handle 1003 * 0 -- invalid stream handle, meaning the op failed 1004 * >0 -- successfully linked a stream with a valid handle 1005 *==========================================================================*/ 1006 uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj, 1007 uint32_t ch_id, 1008 uint32_t stream_id, 1009 uint32_t linked_ch_id) 1010 { 1011 uint32_t s_hdl = 0; 1012 mm_channel_t * ch_obj = 1013 mm_camera_util_get_channel_by_handler(my_obj, linked_ch_id); 1014 mm_channel_t * owner_obj = 1015 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1016 1017 if ((NULL != ch_obj) && (NULL != owner_obj)) { 1018 pthread_mutex_lock(&ch_obj->ch_lock); 1019 pthread_mutex_unlock(&my_obj->cam_lock); 1020 1021 mm_camera_stream_link_t stream_link; 1022 memset(&stream_link, 0, sizeof(mm_camera_stream_link_t)); 1023 stream_link.ch = owner_obj; 1024 stream_link.stream_id = stream_id; 1025 mm_channel_fsm_fn(ch_obj, 1026 MM_CHANNEL_EVT_LINK_STREAM, 1027 (void*)&stream_link, 1028 (void*)&s_hdl); 1029 } else { 1030 pthread_mutex_unlock(&my_obj->cam_lock); 1031 } 1032 1033 return s_hdl; 1034 } 1035 1036 /*=========================================================================== 1037 * FUNCTION : mm_camera_add_stream 1038 * 1039 * DESCRIPTION: add a stream into a channel 1040 * 1041 * PARAMETERS : 1042 * @my_obj : camera object 1043 * @ch_id : channel handle 1044 * 1045 * RETURN : uint32_t type of stream handle 1046 * 0 -- invalid stream handle, meaning the op failed 1047 * >0 -- successfully added a stream with a valid handle 1048 *==========================================================================*/ 1049 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj, 1050 uint32_t ch_id) 1051 { 1052 uint32_t s_hdl = 0; 1053 mm_channel_t * ch_obj = 1054 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1055 1056 if (NULL != ch_obj) { 1057 pthread_mutex_lock(&ch_obj->ch_lock); 1058 pthread_mutex_unlock(&my_obj->cam_lock); 1059 1060 mm_channel_fsm_fn(ch_obj, 1061 MM_CHANNEL_EVT_ADD_STREAM, 1062 NULL, 1063 (void *)&s_hdl); 1064 } else { 1065 pthread_mutex_unlock(&my_obj->cam_lock); 1066 } 1067 1068 return s_hdl; 1069 } 1070 1071 /*=========================================================================== 1072 * FUNCTION : mm_camera_del_stream 1073 * 1074 * DESCRIPTION: delete a stream by its handle 1075 * 1076 * PARAMETERS : 1077 * @my_obj : camera object 1078 * @ch_id : channel handle 1079 * @stream_id : stream handle 1080 * 1081 * RETURN : int32_t type of status 1082 * 0 -- success 1083 * -1 -- failure 1084 * NOTE : stream should be stopped already before it can be deleted. 1085 *==========================================================================*/ 1086 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj, 1087 uint32_t ch_id, 1088 uint32_t stream_id) 1089 { 1090 int32_t rc = -1; 1091 mm_channel_t * ch_obj = 1092 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1093 1094 if (NULL != ch_obj) { 1095 pthread_mutex_lock(&ch_obj->ch_lock); 1096 pthread_mutex_unlock(&my_obj->cam_lock); 1097 1098 rc = mm_channel_fsm_fn(ch_obj, 1099 MM_CHANNEL_EVT_DEL_STREAM, 1100 (void *)&stream_id, 1101 NULL); 1102 } else { 1103 pthread_mutex_unlock(&my_obj->cam_lock); 1104 } 1105 1106 return rc; 1107 } 1108 1109 /*=========================================================================== 1110 * FUNCTION : mm_camera_start_zsl_snapshot_ch 1111 * 1112 * DESCRIPTION: starts zsl snapshot for specific channel 1113 * 1114 * PARAMETERS : 1115 * @my_obj : camera object 1116 * @ch_id : channel handle 1117 * 1118 * RETURN : int32_t type of status 1119 * 0 -- success 1120 * -1 -- failure 1121 *==========================================================================*/ 1122 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj, 1123 uint32_t ch_id) 1124 { 1125 int32_t rc = -1; 1126 mm_channel_t * ch_obj = 1127 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1128 1129 if (NULL != ch_obj) { 1130 pthread_mutex_lock(&ch_obj->ch_lock); 1131 pthread_mutex_unlock(&my_obj->cam_lock); 1132 1133 rc = mm_channel_fsm_fn(ch_obj, 1134 MM_CHANNEL_EVT_START_ZSL_SNAPSHOT, 1135 NULL, 1136 NULL); 1137 } else { 1138 pthread_mutex_unlock(&my_obj->cam_lock); 1139 } 1140 1141 return rc; 1142 } 1143 1144 /*=========================================================================== 1145 * FUNCTION : mm_camera_stop_zsl_snapshot_ch 1146 * 1147 * DESCRIPTION: stops zsl snapshot for specific channel 1148 * 1149 * PARAMETERS : 1150 * @my_obj : camera object 1151 * @ch_id : channel handle 1152 * 1153 * RETURN : int32_t type of status 1154 * 0 -- success 1155 * -1 -- failure 1156 *==========================================================================*/ 1157 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj, 1158 uint32_t ch_id) 1159 { 1160 int32_t rc = -1; 1161 mm_channel_t * ch_obj = 1162 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1163 1164 if (NULL != ch_obj) { 1165 pthread_mutex_lock(&ch_obj->ch_lock); 1166 pthread_mutex_unlock(&my_obj->cam_lock); 1167 1168 rc = mm_channel_fsm_fn(ch_obj, 1169 MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT, 1170 NULL, 1171 NULL); 1172 } else { 1173 pthread_mutex_unlock(&my_obj->cam_lock); 1174 } 1175 1176 return rc; 1177 } 1178 1179 /*=========================================================================== 1180 * FUNCTION : mm_camera_config_stream 1181 * 1182 * DESCRIPTION: configure a stream 1183 * 1184 * PARAMETERS : 1185 * @my_obj : camera object 1186 * @ch_id : channel handle 1187 * @stream_id : stream handle 1188 * @config : stream configuration 1189 * 1190 * RETURN : int32_t type of status 1191 * 0 -- success 1192 * -1 -- failure 1193 *==========================================================================*/ 1194 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj, 1195 uint32_t ch_id, 1196 uint32_t stream_id, 1197 mm_camera_stream_config_t *config) 1198 { 1199 int32_t rc = -1; 1200 mm_channel_t * ch_obj = 1201 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1202 mm_evt_paylod_config_stream_t payload; 1203 1204 if (NULL != ch_obj) { 1205 pthread_mutex_lock(&ch_obj->ch_lock); 1206 pthread_mutex_unlock(&my_obj->cam_lock); 1207 1208 memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t)); 1209 payload.stream_id = stream_id; 1210 payload.config = config; 1211 rc = mm_channel_fsm_fn(ch_obj, 1212 MM_CHANNEL_EVT_CONFIG_STREAM, 1213 (void *)&payload, 1214 NULL); 1215 } else { 1216 pthread_mutex_unlock(&my_obj->cam_lock); 1217 } 1218 1219 return rc; 1220 } 1221 1222 /*=========================================================================== 1223 * FUNCTION : mm_camera_start_channel 1224 * 1225 * DESCRIPTION: start a channel, which will start all streams in the channel 1226 * 1227 * PARAMETERS : 1228 * @my_obj : camera object 1229 * @ch_id : channel handle 1230 * 1231 * RETURN : int32_t type of status 1232 * 0 -- success 1233 * -1 -- failure 1234 *==========================================================================*/ 1235 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj, uint32_t ch_id) 1236 { 1237 int32_t rc = -1; 1238 mm_channel_t * ch_obj = 1239 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1240 1241 if (NULL != ch_obj) { 1242 pthread_mutex_lock(&ch_obj->ch_lock); 1243 pthread_mutex_unlock(&my_obj->cam_lock); 1244 1245 rc = mm_channel_fsm_fn(ch_obj, 1246 MM_CHANNEL_EVT_START, 1247 NULL, 1248 NULL); 1249 } else { 1250 pthread_mutex_unlock(&my_obj->cam_lock); 1251 } 1252 1253 return rc; 1254 } 1255 1256 /*=========================================================================== 1257 * FUNCTION : mm_camera_stop_channel 1258 * 1259 * DESCRIPTION: stop a channel, which will stop all streams in the channel 1260 * 1261 * PARAMETERS : 1262 * @my_obj : camera object 1263 * @ch_id : channel handle 1264 * 1265 * RETURN : int32_t type of status 1266 * 0 -- success 1267 * -1 -- failure 1268 *==========================================================================*/ 1269 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj, 1270 uint32_t ch_id) 1271 { 1272 int32_t rc = 0; 1273 mm_channel_t * ch_obj = 1274 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1275 1276 if (NULL != ch_obj) { 1277 pthread_mutex_lock(&ch_obj->ch_lock); 1278 pthread_mutex_unlock(&my_obj->cam_lock); 1279 1280 rc = mm_channel_fsm_fn(ch_obj, 1281 MM_CHANNEL_EVT_STOP, 1282 NULL, 1283 NULL); 1284 } else { 1285 pthread_mutex_unlock(&my_obj->cam_lock); 1286 } 1287 return rc; 1288 } 1289 1290 /*=========================================================================== 1291 * FUNCTION : mm_camera_request_super_buf 1292 * 1293 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched 1294 * frames from superbuf queue 1295 * 1296 * PARAMETERS : 1297 * @my_obj : camera object 1298 * @ch_id : channel handle 1299 * @num_buf_requested : number of matched frames needed 1300 * 1301 * RETURN : int32_t type of status 1302 * 0 -- success 1303 * -1 -- failure 1304 *==========================================================================*/ 1305 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj, 1306 uint32_t ch_id, mm_camera_req_buf_t *buf) 1307 { 1308 int32_t rc = -1; 1309 mm_channel_t * ch_obj = 1310 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1311 1312 if ((NULL != ch_obj) && (buf != NULL)) { 1313 pthread_mutex_lock(&ch_obj->ch_lock); 1314 pthread_mutex_unlock(&my_obj->cam_lock); 1315 1316 rc = mm_channel_fsm_fn(ch_obj, MM_CHANNEL_EVT_REQUEST_SUPER_BUF, 1317 (void *)buf, NULL); 1318 } else { 1319 pthread_mutex_unlock(&my_obj->cam_lock); 1320 } 1321 1322 return rc; 1323 } 1324 1325 /*=========================================================================== 1326 * FUNCTION : mm_camera_cancel_super_buf_request 1327 * 1328 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount 1329 * of matched frames from superbuf queue 1330 * 1331 * PARAMETERS : 1332 * @my_obj : camera object 1333 * @ch_id : channel handle 1334 * 1335 * RETURN : int32_t type of status 1336 * 0 -- success 1337 * -1 -- failure 1338 *==========================================================================*/ 1339 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id) 1340 { 1341 int32_t rc = -1; 1342 mm_channel_t * ch_obj = 1343 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1344 1345 if (NULL != ch_obj) { 1346 pthread_mutex_lock(&ch_obj->ch_lock); 1347 pthread_mutex_unlock(&my_obj->cam_lock); 1348 1349 rc = mm_channel_fsm_fn(ch_obj, 1350 MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF, 1351 NULL, 1352 NULL); 1353 } else { 1354 pthread_mutex_unlock(&my_obj->cam_lock); 1355 } 1356 1357 return rc; 1358 } 1359 1360 /*=========================================================================== 1361 * FUNCTION : mm_camera_flush_super_buf_queue 1362 * 1363 * DESCRIPTION: flush out all frames in the superbuf queue 1364 * 1365 * PARAMETERS : 1366 * @my_obj : camera object 1367 * @ch_id : channel handle 1368 * 1369 * RETURN : int32_t type of status 1370 * 0 -- success 1371 * -1 -- failure 1372 *==========================================================================*/ 1373 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id, 1374 uint32_t frame_idx) 1375 { 1376 int32_t rc = -1; 1377 mm_channel_t * ch_obj = 1378 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1379 1380 if (NULL != ch_obj) { 1381 pthread_mutex_lock(&ch_obj->ch_lock); 1382 pthread_mutex_unlock(&my_obj->cam_lock); 1383 1384 rc = mm_channel_fsm_fn(ch_obj, 1385 MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE, 1386 (void *)&frame_idx, 1387 NULL); 1388 } else { 1389 pthread_mutex_unlock(&my_obj->cam_lock); 1390 } 1391 1392 return rc; 1393 } 1394 1395 /*=========================================================================== 1396 * FUNCTION : mm_camera_config_channel_notify 1397 * 1398 * DESCRIPTION: configures the channel notification mode 1399 * 1400 * PARAMETERS : 1401 * @my_obj : camera object 1402 * @ch_id : channel handle 1403 * @notify_mode : notification mode 1404 * 1405 * RETURN : int32_t type of status 1406 * 0 -- success 1407 * -1 -- failure 1408 *==========================================================================*/ 1409 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj, 1410 uint32_t ch_id, 1411 mm_camera_super_buf_notify_mode_t notify_mode) 1412 { 1413 int32_t rc = -1; 1414 mm_channel_t * ch_obj = 1415 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1416 1417 if (NULL != ch_obj) { 1418 pthread_mutex_lock(&ch_obj->ch_lock); 1419 pthread_mutex_unlock(&my_obj->cam_lock); 1420 1421 rc = mm_channel_fsm_fn(ch_obj, 1422 MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE, 1423 (void *)¬ify_mode, 1424 NULL); 1425 } else { 1426 pthread_mutex_unlock(&my_obj->cam_lock); 1427 } 1428 1429 return rc; 1430 } 1431 1432 /*=========================================================================== 1433 * FUNCTION : mm_camera_set_stream_parms 1434 * 1435 * DESCRIPTION: set parameters per stream 1436 * 1437 * PARAMETERS : 1438 * @my_obj : camera object 1439 * @ch_id : channel handle 1440 * @s_id : stream handle 1441 * @parms : ptr to a param struct to be set to server 1442 * 1443 * RETURN : int32_t type of status 1444 * 0 -- success 1445 * -1 -- failure 1446 * NOTE : Assume the parms struct buf is already mapped to server via 1447 * domain socket. Corresponding fields of parameters to be set 1448 * are already filled in by upper layer caller. 1449 *==========================================================================*/ 1450 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj, 1451 uint32_t ch_id, 1452 uint32_t s_id, 1453 cam_stream_parm_buffer_t *parms) 1454 { 1455 int32_t rc = -1; 1456 mm_evt_paylod_set_get_stream_parms_t payload; 1457 mm_channel_t * ch_obj = 1458 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1459 1460 if (NULL != ch_obj) { 1461 pthread_mutex_lock(&ch_obj->ch_lock); 1462 pthread_mutex_unlock(&my_obj->cam_lock); 1463 1464 memset(&payload, 0, sizeof(payload)); 1465 payload.stream_id = s_id; 1466 payload.parms = parms; 1467 1468 rc = mm_channel_fsm_fn(ch_obj, 1469 MM_CHANNEL_EVT_SET_STREAM_PARM, 1470 (void *)&payload, 1471 NULL); 1472 } else { 1473 pthread_mutex_unlock(&my_obj->cam_lock); 1474 } 1475 1476 return rc; 1477 } 1478 1479 /*=========================================================================== 1480 * FUNCTION : mm_camera_get_stream_parms 1481 * 1482 * DESCRIPTION: get parameters per stream 1483 * 1484 * PARAMETERS : 1485 * @my_obj : camera object 1486 * @ch_id : channel handle 1487 * @s_id : stream handle 1488 * @parms : ptr to a param struct to be get from server 1489 * 1490 * RETURN : int32_t type of status 1491 * 0 -- success 1492 * -1 -- failure 1493 * NOTE : Assume the parms struct buf is already mapped to server via 1494 * domain socket. Parameters to be get from server are already 1495 * filled in by upper layer caller. After this call, corresponding 1496 * fields of requested parameters will be filled in by server with 1497 * detailed information. 1498 *==========================================================================*/ 1499 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj, 1500 uint32_t ch_id, 1501 uint32_t s_id, 1502 cam_stream_parm_buffer_t *parms) 1503 { 1504 int32_t rc = -1; 1505 mm_evt_paylod_set_get_stream_parms_t payload; 1506 mm_channel_t * ch_obj = 1507 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1508 1509 if (NULL != ch_obj) { 1510 pthread_mutex_lock(&ch_obj->ch_lock); 1511 pthread_mutex_unlock(&my_obj->cam_lock); 1512 1513 memset(&payload, 0, sizeof(payload)); 1514 payload.stream_id = s_id; 1515 payload.parms = parms; 1516 1517 rc = mm_channel_fsm_fn(ch_obj, 1518 MM_CHANNEL_EVT_GET_STREAM_PARM, 1519 (void *)&payload, 1520 NULL); 1521 } else { 1522 pthread_mutex_unlock(&my_obj->cam_lock); 1523 } 1524 1525 return rc; 1526 } 1527 1528 /*=========================================================================== 1529 * FUNCTION : mm_camera_do_stream_action 1530 * 1531 * DESCRIPTION: request server to perform stream based action. Maybe removed later 1532 * if the functionality is included in mm_camera_set_parms 1533 * 1534 * PARAMETERS : 1535 * @my_obj : camera object 1536 * @ch_id : channel handle 1537 * @s_id : stream handle 1538 * @actions : ptr to an action struct buf to be performed by server 1539 * 1540 * RETURN : int32_t type of status 1541 * 0 -- success 1542 * -1 -- failure 1543 * NOTE : Assume the action struct buf is already mapped to server via 1544 * domain socket. Actions to be performed by server are already 1545 * filled in by upper layer caller. 1546 *==========================================================================*/ 1547 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj, 1548 uint32_t ch_id, 1549 uint32_t stream_id, 1550 void *actions) 1551 { 1552 int32_t rc = -1; 1553 mm_evt_paylod_do_stream_action_t payload; 1554 mm_channel_t * ch_obj = 1555 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1556 1557 if (NULL != ch_obj) { 1558 pthread_mutex_lock(&ch_obj->ch_lock); 1559 pthread_mutex_unlock(&my_obj->cam_lock); 1560 1561 memset(&payload, 0, sizeof(payload)); 1562 payload.stream_id = stream_id; 1563 payload.actions = actions; 1564 1565 rc = mm_channel_fsm_fn(ch_obj, 1566 MM_CHANNEL_EVT_DO_STREAM_ACTION, 1567 (void*)&payload, 1568 NULL); 1569 } else { 1570 pthread_mutex_unlock(&my_obj->cam_lock); 1571 } 1572 1573 return rc; 1574 } 1575 1576 /*=========================================================================== 1577 * FUNCTION : mm_camera_map_stream_buf 1578 * 1579 * DESCRIPTION: mapping stream buffer via domain socket to server 1580 * 1581 * PARAMETERS : 1582 * @my_obj : camera object 1583 * @ch_id : channel handle 1584 * @s_id : stream handle 1585 * @buf_type : type of buffer to be mapped. could be following values: 1586 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1587 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1588 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1589 * @buf_idx : index of buffer within the stream buffers, only valid if 1590 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1591 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1592 * @plane_idx : plane index. If all planes share the same fd, 1593 * plane_idx = -1; otherwise, plean_idx is the 1594 * index to plane (0..num_of_planes) 1595 * @fd : file descriptor of the buffer 1596 * @size : size of the buffer 1597 * 1598 * RETURN : int32_t type of status 1599 * 0 -- success 1600 * -1 -- failure 1601 *==========================================================================*/ 1602 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj, 1603 uint32_t ch_id, 1604 uint32_t stream_id, 1605 uint8_t buf_type, 1606 uint32_t buf_idx, 1607 int32_t plane_idx, 1608 int fd, 1609 size_t size, 1610 void *buffer) 1611 { 1612 int32_t rc = -1; 1613 cam_buf_map_type payload; 1614 mm_channel_t * ch_obj = 1615 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1616 1617 if (NULL != ch_obj) { 1618 pthread_mutex_lock(&ch_obj->ch_lock); 1619 pthread_mutex_unlock(&my_obj->cam_lock); 1620 1621 memset(&payload, 0, sizeof(payload)); 1622 payload.stream_id = stream_id; 1623 payload.type = buf_type; 1624 payload.frame_idx = buf_idx; 1625 payload.plane_idx = plane_idx; 1626 payload.fd = fd; 1627 payload.size = size; 1628 payload.buffer = buffer; 1629 rc = mm_channel_fsm_fn(ch_obj, 1630 MM_CHANNEL_EVT_MAP_STREAM_BUF, 1631 (void*)&payload, 1632 NULL); 1633 } else { 1634 pthread_mutex_unlock(&my_obj->cam_lock); 1635 } 1636 1637 return rc; 1638 } 1639 1640 /*=========================================================================== 1641 * FUNCTION : mm_camera_map_stream_bufs 1642 * 1643 * DESCRIPTION: mapping stream buffers via domain socket to server 1644 * 1645 * PARAMETERS : 1646 * @my_obj : camera object 1647 * @ch_id : channel handle 1648 * @buf_map_list : list of buffers to be mapped 1649 * 1650 * RETURN : int32_t type of status 1651 * 0 -- success 1652 * -1 -- failure 1653 *==========================================================================*/ 1654 int32_t mm_camera_map_stream_bufs(mm_camera_obj_t *my_obj, 1655 uint32_t ch_id, 1656 const cam_buf_map_type_list *buf_map_list) 1657 { 1658 int32_t rc = -1; 1659 cam_buf_map_type_list payload; 1660 mm_channel_t * ch_obj = 1661 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1662 1663 if (NULL != ch_obj) { 1664 pthread_mutex_lock(&ch_obj->ch_lock); 1665 pthread_mutex_unlock(&my_obj->cam_lock); 1666 1667 memcpy(&payload, buf_map_list, sizeof(payload)); 1668 rc = mm_channel_fsm_fn(ch_obj, 1669 MM_CHANNEL_EVT_MAP_STREAM_BUFS, 1670 (void*)&payload, 1671 NULL); 1672 } else { 1673 pthread_mutex_unlock(&my_obj->cam_lock); 1674 } 1675 1676 return rc; 1677 } 1678 1679 /*=========================================================================== 1680 * FUNCTION : mm_camera_unmap_stream_buf 1681 * 1682 * DESCRIPTION: unmapping stream buffer via domain socket to server 1683 * 1684 * PARAMETERS : 1685 * @my_obj : camera object 1686 * @ch_id : channel handle 1687 * @s_id : stream handle 1688 * @buf_type : type of buffer to be mapped. could be following values: 1689 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1690 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1691 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1692 * @buf_idx : index of buffer within the stream buffers, only valid if 1693 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1694 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1695 * @plane_idx : plane index. If all planes share the same fd, 1696 * plane_idx = -1; otherwise, plean_idx is the 1697 * index to plane (0..num_of_planes) 1698 * 1699 * RETURN : int32_t type of status 1700 * 0 -- success 1701 * -1 -- failure 1702 *==========================================================================*/ 1703 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj, 1704 uint32_t ch_id, 1705 uint32_t stream_id, 1706 uint8_t buf_type, 1707 uint32_t buf_idx, 1708 int32_t plane_idx) 1709 { 1710 int32_t rc = -1; 1711 cam_buf_unmap_type payload; 1712 mm_channel_t * ch_obj = 1713 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1714 1715 if (NULL != ch_obj) { 1716 pthread_mutex_lock(&ch_obj->ch_lock); 1717 pthread_mutex_unlock(&my_obj->cam_lock); 1718 1719 memset(&payload, 0, sizeof(payload)); 1720 payload.stream_id = stream_id; 1721 payload.type = buf_type; 1722 payload.frame_idx = buf_idx; 1723 payload.plane_idx = plane_idx; 1724 rc = mm_channel_fsm_fn(ch_obj, 1725 MM_CHANNEL_EVT_UNMAP_STREAM_BUF, 1726 (void*)&payload, 1727 NULL); 1728 } else { 1729 pthread_mutex_unlock(&my_obj->cam_lock); 1730 } 1731 1732 return rc; 1733 } 1734 1735 /*=========================================================================== 1736 * FUNCTION : mm_camera_evt_sub 1737 * 1738 * DESCRIPTION: subscribe/unsubscribe event notify from kernel 1739 * 1740 * PARAMETERS : 1741 * @my_obj : camera object 1742 * @reg_flag : 1 -- subscribe ; 0 -- unsubscribe 1743 * 1744 * RETURN : int32_t type of status 1745 * 0 -- success 1746 * -1 -- failure 1747 *==========================================================================*/ 1748 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj, 1749 uint8_t reg_flag) 1750 { 1751 int32_t rc = 0; 1752 struct v4l2_event_subscription sub; 1753 1754 memset(&sub, 0, sizeof(sub)); 1755 sub.type = MSM_CAMERA_V4L2_EVENT_TYPE; 1756 sub.id = MSM_CAMERA_MSM_NOTIFY; 1757 if(FALSE == reg_flag) { 1758 /* unsubscribe */ 1759 rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 1760 if (rc < 0) { 1761 LOGE("unsubscribe event rc = %d, errno %d", 1762 rc, errno); 1763 return rc; 1764 } 1765 /* remove evt fd from the polling thraed when unreg the last event */ 1766 rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread, 1767 my_obj->my_hdl, 1768 mm_camera_sync_call); 1769 } else { 1770 rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 1771 if (rc < 0) { 1772 LOGE("subscribe event rc = %d, errno %d", 1773 rc, errno); 1774 return rc; 1775 } 1776 /* add evt fd to polling thread when subscribe the first event */ 1777 rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread, 1778 my_obj->my_hdl, 1779 my_obj->ctrl_fd, 1780 mm_camera_event_notify, 1781 (void*)my_obj, 1782 mm_camera_sync_call); 1783 } 1784 return rc; 1785 } 1786 1787 /*=========================================================================== 1788 * FUNCTION : mm_camera_util_wait_for_event 1789 * 1790 * DESCRIPTION: utility function to wait for certain events 1791 * 1792 * PARAMETERS : 1793 * @my_obj : camera object 1794 * @evt_mask : mask for events to be waited. Any of event in the mask would 1795 * trigger the wait to end 1796 * @status : status of the event 1797 * 1798 * RETURN : none 1799 *==========================================================================*/ 1800 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj, 1801 uint32_t evt_mask, 1802 uint32_t *status) 1803 { 1804 int32_t rc = 0; 1805 struct timespec ts; 1806 1807 pthread_mutex_lock(&my_obj->evt_lock); 1808 while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) { 1809 clock_gettime(CLOCK_MONOTONIC, &ts); 1810 ts.tv_sec += WAIT_TIMEOUT; 1811 rc = pthread_cond_timedwait(&my_obj->evt_cond, &my_obj->evt_lock, &ts); 1812 if (rc) { 1813 LOGE("pthread_cond_timedwait of evt_mask 0x%x failed %d", 1814 evt_mask, rc); 1815 break; 1816 } 1817 } 1818 if (!rc) { 1819 *status = my_obj->evt_rcvd.status; 1820 } else { 1821 *status = MSM_CAMERA_STATUS_FAIL; 1822 } 1823 /* reset local storage for recieved event for next event */ 1824 memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t)); 1825 pthread_mutex_unlock(&my_obj->evt_lock); 1826 } 1827 1828 /*=========================================================================== 1829 * FUNCTION : mm_camera_util_bundled_sendmsg 1830 * 1831 * DESCRIPTION: utility function to send bundled msg via domain socket 1832 * 1833 * PARAMETERS : 1834 * @my_obj : camera object 1835 * @msg : message to be sent 1836 * @buf_size : size of the message to be sent 1837 * @sendfds : array of file descriptors to be sent 1838 * @numfds : number of file descriptors to be sent 1839 * 1840 * RETURN : int32_t type of status 1841 * 0 -- success 1842 * -1 -- failure 1843 *==========================================================================*/ 1844 int32_t mm_camera_util_bundled_sendmsg(mm_camera_obj_t *my_obj, 1845 void *msg, 1846 size_t buf_size, 1847 int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM], 1848 int numfds) 1849 { 1850 int32_t rc = -1; 1851 uint32_t status; 1852 1853 /* need to lock msg_lock, since sendmsg until response back is deemed as one operation*/ 1854 pthread_mutex_lock(&my_obj->msg_lock); 1855 if(mm_camera_socket_bundle_sendmsg(my_obj->ds_fd, msg, buf_size, sendfds, numfds) > 0) { 1856 /* wait for event that mapping/unmapping is done */ 1857 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status); 1858 if (MSM_CAMERA_STATUS_SUCCESS == status) { 1859 rc = 0; 1860 } 1861 } 1862 pthread_mutex_unlock(&my_obj->msg_lock); 1863 return rc; 1864 } 1865 1866 /*=========================================================================== 1867 * FUNCTION : mm_camera_util_sendmsg 1868 * 1869 * DESCRIPTION: utility function to send msg via domain socket 1870 * 1871 * PARAMETERS : 1872 * @my_obj : camera object 1873 * @msg : message to be sent 1874 * @buf_size : size of the message to be sent 1875 * @sendfd : >0 if any file descriptor need to be passed across process 1876 * 1877 * RETURN : int32_t type of status 1878 * 0 -- success 1879 * -1 -- failure 1880 *==========================================================================*/ 1881 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj, 1882 void *msg, 1883 size_t buf_size, 1884 int sendfd) 1885 { 1886 int32_t rc = -1; 1887 uint32_t status; 1888 1889 /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/ 1890 pthread_mutex_lock(&my_obj->msg_lock); 1891 if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) { 1892 /* wait for event that mapping/unmapping is done */ 1893 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status); 1894 if (MSM_CAMERA_STATUS_SUCCESS == status) { 1895 rc = 0; 1896 } 1897 } 1898 pthread_mutex_unlock(&my_obj->msg_lock); 1899 return rc; 1900 } 1901 1902 /*=========================================================================== 1903 * FUNCTIOa : mm_camera_map_buf 1904 * 1905 * DESCRIPTION: mapping camera buffer via domain socket to server 1906 * 1907 * PARAMETERS : 1908 * @my_obj : camera object 1909 * @buf_type : type of buffer to be mapped. could be following values: 1910 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1911 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1912 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1913 * @fd : file descriptor of the buffer 1914 * @size : size of the buffer 1915 * 1916 * RETURN : int32_t type of status 1917 * 0 -- success 1918 * -1 -- failure 1919 *==========================================================================*/ 1920 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj, 1921 uint8_t buf_type, int fd, size_t size, void *buffer) 1922 { 1923 int32_t rc = 0; 1924 1925 cam_sock_packet_t packet; 1926 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1927 packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING; 1928 packet.payload.buf_map.type = buf_type; 1929 packet.payload.buf_map.fd = fd; 1930 packet.payload.buf_map.size = size; 1931 packet.payload.buf_map.buffer = buffer; 1932 #ifdef DAEMON_PRESENT 1933 rc = mm_camera_util_sendmsg(my_obj, 1934 &packet, 1935 sizeof(cam_sock_packet_t), 1936 fd); 1937 #else 1938 cam_shim_packet_t *shim_cmd; 1939 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF, 1940 my_obj->sessionid, &packet); 1941 rc = mm_camera_module_send_cmd(shim_cmd); 1942 mm_camera_destroy_shim_cmd_packet(shim_cmd); 1943 #endif 1944 pthread_mutex_unlock(&my_obj->cam_lock); 1945 return rc; 1946 } 1947 1948 /*=========================================================================== 1949 * FUNCTION : mm_camera_map_bufs 1950 * 1951 * DESCRIPTION: mapping camera buffers via domain socket to server 1952 * 1953 * PARAMETERS : 1954 * @my_obj : camera object 1955 * @buf_map_list : list of buffers to be mapped 1956 * 1957 * RETURN : int32_t type of status 1958 * 0 -- success 1959 * -1 -- failure 1960 *==========================================================================*/ 1961 int32_t mm_camera_map_bufs(mm_camera_obj_t *my_obj, 1962 const cam_buf_map_type_list* buf_map_list) 1963 { 1964 int32_t rc = 0; 1965 cam_sock_packet_t packet; 1966 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1967 packet.msg_type = CAM_MAPPING_TYPE_FD_BUNDLED_MAPPING; 1968 1969 memcpy(&packet.payload.buf_map_list, buf_map_list, 1970 sizeof(packet.payload.buf_map_list)); 1971 1972 int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM]; 1973 uint32_t numbufs = packet.payload.buf_map_list.length; 1974 uint32_t i; 1975 for (i = 0; i < numbufs; i++) { 1976 sendfds[i] = packet.payload.buf_map_list.buf_maps[i].fd; 1977 packet.payload.buf_map_list.buf_maps[i].buffer = 1978 buf_map_list->buf_maps[i].buffer; 1979 } 1980 for (i = numbufs; i < CAM_MAX_NUM_BUFS_PER_STREAM; i++) { 1981 packet.payload.buf_map_list.buf_maps[i].fd = -1; 1982 sendfds[i] = -1; 1983 } 1984 1985 #ifdef DAEMON_PRESENT 1986 rc = mm_camera_util_bundled_sendmsg(my_obj, 1987 &packet, sizeof(cam_sock_packet_t), 1988 sendfds, numbufs); 1989 #else 1990 cam_shim_packet_t *shim_cmd; 1991 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF, 1992 my_obj->sessionid, &packet); 1993 rc = mm_camera_module_send_cmd(shim_cmd); 1994 mm_camera_destroy_shim_cmd_packet(shim_cmd); 1995 #endif 1996 1997 pthread_mutex_unlock(&my_obj->cam_lock); 1998 return rc; 1999 } 2000 2001 /*=========================================================================== 2002 * FUNCTION : mm_camera_unmap_buf 2003 * 2004 * DESCRIPTION: unmapping camera buffer via domain socket to server 2005 * 2006 * PARAMETERS : 2007 * @my_obj : camera object 2008 * @buf_type : type of buffer to be mapped. could be following values: 2009 * CAM_MAPPING_BUF_TYPE_CAPABILITY 2010 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 2011 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 2012 * 2013 * RETURN : int32_t type of status 2014 * 0 -- success 2015 * -1 -- failure 2016 *==========================================================================*/ 2017 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj, 2018 uint8_t buf_type) 2019 { 2020 int32_t rc = 0; 2021 cam_sock_packet_t packet; 2022 memset(&packet, 0, sizeof(cam_sock_packet_t)); 2023 packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING; 2024 packet.payload.buf_unmap.type = buf_type; 2025 #ifdef DAEMON_PRESENT 2026 rc = mm_camera_util_sendmsg(my_obj, 2027 &packet, 2028 sizeof(cam_sock_packet_t), 2029 -1); 2030 #else 2031 cam_shim_packet_t *shim_cmd; 2032 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF, 2033 my_obj->sessionid, &packet); 2034 rc = mm_camera_module_send_cmd(shim_cmd); 2035 mm_camera_destroy_shim_cmd_packet(shim_cmd); 2036 #endif 2037 pthread_mutex_unlock(&my_obj->cam_lock); 2038 return rc; 2039 } 2040 2041 /*=========================================================================== 2042 * FUNCTION : mm_camera_util_s_ctrl 2043 * 2044 * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl 2045 * 2046 * PARAMETERS : 2047 * @my_obj :Camera object 2048 * @stream_id :streamID 2049 * @fd : file descritpor for sending ioctl 2050 * @id : control id 2051 * @value : value of the ioctl to be sent 2052 * 2053 * RETURN : int32_t type of status 2054 * 0 -- success 2055 * -1 -- failure 2056 *==========================================================================*/ 2057 int32_t mm_camera_util_s_ctrl(__unused mm_camera_obj_t *my_obj, 2058 __unused int stream_id, int32_t fd, 2059 uint32_t id, int32_t *value) 2060 { 2061 int rc = 0; 2062 2063 #ifdef DAEMON_PRESENT 2064 struct v4l2_control control; 2065 memset(&control, 0, sizeof(control)); 2066 control.id = id; 2067 if (value != NULL) { 2068 control.value = *value; 2069 } 2070 rc = ioctl(fd, VIDIOC_S_CTRL, &control); 2071 LOGD("fd=%d, S_CTRL, id=0x%x, value = %p, rc = %d\n", 2072 fd, id, value, rc); 2073 if (rc < 0) { 2074 LOGE("ioctl failed %d, errno %d", rc, errno); 2075 } else if (value != NULL) { 2076 *value = control.value; 2077 } 2078 #else /* DAEMON_PRESENT */ 2079 cam_shim_packet_t *shim_cmd; 2080 cam_shim_cmd_data shim_cmd_data; 2081 (void)fd; 2082 (void)value; 2083 memset(&shim_cmd_data, 0, sizeof(shim_cmd_data)); 2084 2085 shim_cmd_data.command = id; 2086 shim_cmd_data.stream_id = stream_id; 2087 shim_cmd_data.value = NULL; 2088 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM, 2089 my_obj->sessionid,&shim_cmd_data); 2090 rc = mm_camera_module_send_cmd(shim_cmd); 2091 mm_camera_destroy_shim_cmd_packet(shim_cmd); 2092 #endif /* DAEMON_PRESENT */ 2093 return (rc >= 0)? 0 : -1; 2094 } 2095 2096 /*=========================================================================== 2097 * FUNCTION : mm_camera_util_g_ctrl 2098 * 2099 * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl 2100 * 2101 * PARAMETERS : 2102 * @my_obj :Camera object 2103 * @stream_id :streamID 2104 * @fd : file descritpor for sending ioctl 2105 * @id : control id 2106 * @value : value of the ioctl to be sent 2107 * 2108 * RETURN : int32_t type of status 2109 * 0 -- success 2110 * -1 -- failure 2111 *==========================================================================*/ 2112 int32_t mm_camera_util_g_ctrl(__unused mm_camera_obj_t *my_obj, 2113 __unused int stream_id, int32_t fd, uint32_t id, int32_t *value) 2114 { 2115 int rc = 0; 2116 struct v4l2_control control; 2117 2118 memset(&control, 0, sizeof(control)); 2119 control.id = id; 2120 if (value != NULL) { 2121 control.value = *value; 2122 } 2123 2124 #ifdef DAEMON_PRESENT 2125 rc = ioctl(fd, VIDIOC_G_CTRL, &control); 2126 LOGD("fd=%d, G_CTRL, id=0x%x, rc = %d\n", fd, id, rc); 2127 if (value != NULL) { 2128 *value = control.value; 2129 } 2130 #else /* DAEMON_PRESENT */ 2131 cam_shim_packet_t *shim_cmd; 2132 cam_shim_cmd_data shim_cmd_data; 2133 (void)fd; 2134 memset(&shim_cmd_data, 0, sizeof(shim_cmd_data)); 2135 2136 shim_cmd_data.command = id; 2137 shim_cmd_data.stream_id = stream_id; 2138 shim_cmd_data.value = value; 2139 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM, 2140 my_obj->sessionid, &shim_cmd_data); 2141 2142 rc = mm_camera_module_send_cmd(shim_cmd); 2143 mm_camera_destroy_shim_cmd_packet(shim_cmd); 2144 #endif /* DAEMON_PRESENT */ 2145 return (rc >= 0)? 0 : -1; 2146 } 2147 2148 /*=========================================================================== 2149 * FUNCTION : mm_camera_create_shim_cmd 2150 * 2151 * DESCRIPTION: Prepare comand packet to pass to back-end through shim layer 2152 * 2153 * PARAMETERS : 2154 * @type : type of command 2155 * @sessionID : camera sessionID 2156 * @data : command data 2157 * 2158 * RETURN : NULL in case of failures 2159 allocated pointer to shim packet 2160 *==========================================================================*/ 2161 cam_shim_packet_t *mm_camera_create_shim_cmd_packet(cam_shim_cmd_type type, 2162 uint32_t sessionID, void *data) 2163 { 2164 cam_shim_packet_t *shim_pack = NULL; 2165 uint32_t i = 0; 2166 2167 shim_pack = (cam_shim_packet_t *)malloc(sizeof(cam_shim_packet_t)); 2168 if (shim_pack == NULL) { 2169 LOGE("Cannot allocate a memory for shim packet"); 2170 return NULL; 2171 } 2172 memset(shim_pack, 0, sizeof(cam_shim_packet_t)); 2173 shim_pack->cmd_type = type; 2174 shim_pack->session_id = sessionID; 2175 switch (type) { 2176 case CAM_SHIM_SET_PARM: 2177 case CAM_SHIM_GET_PARM: { 2178 cam_shim_cmd_data *cmd_data = (cam_shim_cmd_data *)data; 2179 shim_pack->cmd_data = *cmd_data; 2180 break; 2181 } 2182 case CAM_SHIM_REG_BUF: { 2183 cam_reg_buf_t *cmd_data = (cam_reg_buf_t *)data; 2184 shim_pack->reg_buf = *cmd_data; 2185 break; 2186 } 2187 case CAM_SHIM_BUNDLE_CMD: { 2188 cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)data; 2189 for (i = 0; i < cmd_data->stream_count; i++) { 2190 shim_pack->bundle_cmd.stream_event[i] = cmd_data->stream_event[i]; 2191 } 2192 shim_pack->bundle_cmd.stream_count = cmd_data->stream_count; 2193 break; 2194 } 2195 default: 2196 LOGW("No Data for this command"); 2197 } 2198 return shim_pack; 2199 } 2200 2201 /*=========================================================================== 2202 * FUNCTION : mm_camera_destroy_shim_cmd 2203 * 2204 * DESCRIPTION: destroy shim packet 2205 * 2206 * PARAMETERS : 2207 * @cmd : ptr to shim packet 2208 2209 * RETURN : int32_t type of status 2210 * 0 -- success 2211 * -1 -- failure 2212 *==========================================================================*/ 2213 int32_t mm_camera_destroy_shim_cmd_packet(cam_shim_packet_t *cmd) 2214 { 2215 int32_t rc = 0; 2216 uint32_t i = 0, j = 0; 2217 2218 if (cmd == NULL) { 2219 LOGW("Command is NULL"); 2220 return rc; 2221 } 2222 2223 switch (cmd->cmd_type) { 2224 case CAM_SHIM_SET_PARM: 2225 case CAM_SHIM_GET_PARM: 2226 case CAM_SHIM_REG_BUF: 2227 break; 2228 case CAM_SHIM_BUNDLE_CMD: { 2229 cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)cmd; 2230 for (i = 0; i < cmd_data->stream_count; i++) { 2231 cam_shim_cmd_packet_t *stream_evt = &cmd_data->stream_event[i]; 2232 for (j = 0; j < stream_evt->cmd_count; j++) { 2233 if (stream_evt->cmd != NULL) { 2234 if(stream_evt->cmd->cmd_type == CAM_SHIM_BUNDLE_CMD) { 2235 mm_camera_destroy_shim_cmd_packet(stream_evt->cmd); 2236 } 2237 free(stream_evt->cmd); 2238 stream_evt->cmd = NULL; 2239 } 2240 } 2241 } 2242 break; 2243 } 2244 default: 2245 LOGW("No Data for this command"); 2246 } 2247 free(cmd); 2248 cmd = NULL; 2249 return rc; 2250 } 2251 2252 /*=========================================================================== 2253 * FUNCTION : mm_camera_channel_advanced_capture 2254 * 2255 * DESCRIPTION: sets the channel advanced capture 2256 * 2257 * PARAMETERS : 2258 * @my_obj : camera object 2259 * @ch_id : channel handle 2260 * @type : advanced capture type. 2261 * @start_flag : flag to indicate start/stop 2262 * @in_value : input configaration 2263 * 2264 * RETURN : int32_t type of status 2265 * 0 -- success 2266 * -1 -- failure 2267 *==========================================================================*/ 2268 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj, 2269 uint32_t ch_id, mm_camera_advanced_capture_t type, 2270 uint32_t trigger, void *in_value) 2271 { 2272 LOGD("E type = %d", type); 2273 int32_t rc = -1; 2274 mm_channel_t * ch_obj = 2275 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 2276 2277 if (NULL != ch_obj) { 2278 pthread_mutex_lock(&ch_obj->ch_lock); 2279 pthread_mutex_unlock(&my_obj->cam_lock); 2280 switch (type) { 2281 case MM_CAMERA_AF_BRACKETING: 2282 rc = mm_channel_fsm_fn(ch_obj, 2283 MM_CHANNEL_EVT_AF_BRACKETING, 2284 (void *)&trigger, 2285 NULL); 2286 break; 2287 case MM_CAMERA_AE_BRACKETING: 2288 rc = mm_channel_fsm_fn(ch_obj, 2289 MM_CHANNEL_EVT_AE_BRACKETING, 2290 (void *)&trigger, 2291 NULL); 2292 break; 2293 case MM_CAMERA_FLASH_BRACKETING: 2294 rc = mm_channel_fsm_fn(ch_obj, 2295 MM_CHANNEL_EVT_FLASH_BRACKETING, 2296 (void *)&trigger, 2297 NULL); 2298 break; 2299 case MM_CAMERA_ZOOM_1X: 2300 rc = mm_channel_fsm_fn(ch_obj, 2301 MM_CHANNEL_EVT_ZOOM_1X, 2302 (void *)&trigger, 2303 NULL); 2304 break; 2305 case MM_CAMERA_FRAME_CAPTURE: 2306 rc = mm_channel_fsm_fn(ch_obj, 2307 MM_CAMERA_EVT_CAPTURE_SETTING, 2308 (void *)in_value, 2309 NULL); 2310 break; 2311 default: 2312 break; 2313 } 2314 2315 } else { 2316 pthread_mutex_unlock(&my_obj->cam_lock); 2317 } 2318 2319 LOGD("X"); 2320 return rc; 2321 } 2322 2323 /*=========================================================================== 2324 * FUNCTION : mm_camera_get_session_id 2325 * 2326 * DESCRIPTION: get the session identity 2327 * 2328 * PARAMETERS : 2329 * @my_obj : camera object 2330 * @sessionid: pointer to the output session id 2331 * 2332 * RETURN : int32_t type of status 2333 * 0 -- success 2334 * -1 -- failure 2335 * NOTE : if this call succeeds, we will get a valid session id 2336 *==========================================================================*/ 2337 int32_t mm_camera_get_session_id(mm_camera_obj_t *my_obj, 2338 uint32_t* sessionid) 2339 { 2340 int32_t rc = -1; 2341 int32_t value = 0; 2342 if(sessionid != NULL) { 2343 struct v4l2_control control; 2344 memset(&control, 0, sizeof(control)); 2345 control.id = MSM_CAMERA_PRIV_G_SESSION_ID; 2346 control.value = value; 2347 2348 rc = ioctl(my_obj->ctrl_fd, VIDIOC_G_CTRL, &control); 2349 value = control.value; 2350 LOGD("fd=%d, get_session_id, id=0x%x, value = %d, rc = %d\n", 2351 my_obj->ctrl_fd, MSM_CAMERA_PRIV_G_SESSION_ID, 2352 value, rc); 2353 *sessionid = value; 2354 } 2355 return rc; 2356 } 2357 2358 /*=========================================================================== 2359 * FUNCTION : mm_camera_sync_related_sensors 2360 * 2361 * DESCRIPTION: send sync cmd 2362 * 2363 * PARAMETERS : 2364 * @my_obj : camera object 2365 * @parms : ptr to the related cam info to be sent to server 2366 * 2367 * RETURN : int32_t type of status 2368 * 0 -- success 2369 * -1 -- failure 2370 * NOTE : Assume the sync struct buf is already mapped to server via 2371 * domain socket. Corresponding fields of parameters to be set 2372 * are already filled in by upper layer caller. 2373 *==========================================================================*/ 2374 int32_t mm_camera_sync_related_sensors(mm_camera_obj_t *my_obj, 2375 cam_sync_related_sensors_event_info_t* parms) 2376 { 2377 int32_t rc = -1; 2378 int32_t value = 0; 2379 if (parms != NULL) { 2380 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, 2381 CAM_PRIV_SYNC_RELATED_SENSORS, &value); 2382 } 2383 pthread_mutex_unlock(&my_obj->cam_lock); 2384 return rc; 2385 } 2386 2387 /*=========================================================================== 2388 * FUNCTION : mm_camera_reg_stream_buf_cb 2389 * 2390 * DESCRIPTION: Register callback for stream buffer 2391 * 2392 * PARAMETERS : 2393 * @my_obj : camera object 2394 * @ch_id : channel handle 2395 * @stream_id : stream that will be linked 2396 * @buf_cb : special callback needs to be registered for stream buffer 2397 * @cb_type : Callback type SYNC/ASYNC 2398 * @userdata : user data pointer 2399 * 2400 * RETURN : int32_t type of status 2401 * 0 -- success 2402 * 1 -- failure 2403 *==========================================================================*/ 2404 int32_t mm_camera_reg_stream_buf_cb(mm_camera_obj_t *my_obj, 2405 uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t stream_cb, 2406 mm_camera_stream_cb_type cb_type, void *userdata) 2407 { 2408 int rc = 0; 2409 mm_stream_data_cb_t buf_cb; 2410 mm_channel_t * ch_obj = 2411 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 2412 2413 if (NULL != ch_obj) { 2414 pthread_mutex_lock(&ch_obj->ch_lock); 2415 pthread_mutex_unlock(&my_obj->cam_lock); 2416 2417 memset(&buf_cb, 0, sizeof(mm_stream_data_cb_t)); 2418 buf_cb.cb = stream_cb; 2419 buf_cb.cb_count = -1; 2420 buf_cb.cb_type = cb_type; 2421 buf_cb.user_data = userdata; 2422 2423 mm_evt_paylod_reg_stream_buf_cb payload; 2424 memset(&payload, 0, sizeof(mm_evt_paylod_reg_stream_buf_cb)); 2425 payload.buf_cb = buf_cb; 2426 payload.stream_id = stream_id; 2427 mm_channel_fsm_fn(ch_obj, 2428 MM_CHANNEL_EVT_REG_STREAM_BUF_CB, 2429 (void*)&payload, NULL); 2430 } else { 2431 pthread_mutex_unlock(&my_obj->cam_lock); 2432 } 2433 return rc; 2434 } 2435 2436 #ifdef QCAMERA_REDEFINE_LOG 2437 2438 /*=========================================================================== 2439 * DESCRIPTION: mm camera debug interface 2440 * 2441 *==========================================================================*/ 2442 pthread_mutex_t dbg_log_mutex; 2443 2444 #undef LOG_TAG 2445 #define LOG_TAG "QCamera" 2446 #define CDBG_MAX_STR_LEN 1024 2447 #define CDBG_MAX_LINE_LENGTH 256 2448 2449 /* current trace loggin permissions 2450 * {NONE, ERR, WARN, HIGH, DEBUG, LOW, INFO} */ 2451 int g_cam_log[CAM_LAST_MODULE][CAM_GLBL_DBG_INFO + 1] = { 2452 {0, 1, 0, 0, 0, 0, 1}, /* CAM_NO_MODULE */ 2453 {0, 1, 0, 0, 0, 0, 1}, /* CAM_HAL_MODULE */ 2454 {0, 1, 0, 0, 0, 0, 1}, /* CAM_MCI_MODULE */ 2455 {0, 1, 0, 0, 0, 0, 1}, /* CAM_JPEG_MODULE */ 2456 }; 2457 2458 /* string representation for logging level */ 2459 static const char *cam_dbg_level_to_str[] = { 2460 "", /* CAM_GLBL_DBG_NONE */ 2461 "<ERROR>", /* CAM_GLBL_DBG_ERR */ 2462 "<WARN>", /* CAM_GLBL_DBG_WARN */ 2463 "<HIGH>", /* CAM_GLBL_DBG_HIGH */ 2464 "<DBG>", /* CAM_GLBL_DBG_DEBUG */ 2465 "<LOW>", /* CAM_GLBL_DBG_LOW */ 2466 "<INFO>" /* CAM_GLBL_DBG_INFO */ 2467 }; 2468 2469 /* current trace logging configuration */ 2470 typedef struct { 2471 cam_global_debug_level_t level; 2472 int initialized; 2473 const char *name; 2474 const char *prop; 2475 } module_debug_t; 2476 2477 static module_debug_t cam_loginfo[(int)CAM_LAST_MODULE] = { 2478 {CAM_GLBL_DBG_ERR, 1, 2479 "", "persist.camera.global.debug" }, /* CAM_NO_MODULE */ 2480 {CAM_GLBL_DBG_ERR, 1, 2481 "<HAL>", "persist.camera.hal.debug" }, /* CAM_HAL_MODULE */ 2482 {CAM_GLBL_DBG_ERR, 1, 2483 "<MCI>", "persist.camera.mci.debug" }, /* CAM_MCI_MODULE */ 2484 {CAM_GLBL_DBG_ERR, 1, 2485 "<JPEG>", "persist.camera.mmstill.logs" }, /* CAM_JPEG_MODULE */ 2486 }; 2487 2488 /** cam_get_dbg_level 2489 * 2490 * @module: module name 2491 * @level: module debug logging level 2492 * 2493 * Maps debug log string to value. 2494 * 2495 * Return: logging level 2496 **/ 2497 __unused 2498 static cam_global_debug_level_t cam_get_dbg_level(const char *module, 2499 char *pValue) { 2500 2501 cam_global_debug_level_t rc = CAM_GLBL_DBG_NONE; 2502 2503 if (!strcmp(pValue, "none")) { 2504 rc = CAM_GLBL_DBG_NONE; 2505 } else if (!strcmp(pValue, "warn")) { 2506 rc = CAM_GLBL_DBG_WARN; 2507 } else if (!strcmp(pValue, "debug")) { 2508 rc = CAM_GLBL_DBG_DEBUG; 2509 } else if (!strcmp(pValue, "error")) { 2510 rc = CAM_GLBL_DBG_ERR; 2511 } else if (!strcmp(pValue, "low")) { 2512 rc = CAM_GLBL_DBG_LOW; 2513 } else if (!strcmp(pValue, "high")) { 2514 rc = CAM_GLBL_DBG_HIGH; 2515 } else if (!strcmp(pValue, "info")) { 2516 rc = CAM_GLBL_DBG_INFO; 2517 } else { 2518 ALOGE("Invalid %s debug log level %s\n", module, pValue); 2519 } 2520 2521 ALOGD("%s debug log level: %s\n", module, cam_dbg_level_to_str[rc]); 2522 2523 return rc; 2524 } 2525 2526 /** cam_vsnprintf 2527 * @pdst: destination buffer pointer 2528 * @size: size of destination b uffer 2529 * @pfmt: string format 2530 * @argptr: variabkle length argument list 2531 * 2532 * Processes variable length argument list to a formatted string. 2533 * 2534 * Return: n/a 2535 **/ 2536 static void cam_vsnprintf(char* pdst, unsigned int size, 2537 const char* pfmt, va_list argptr) { 2538 int num_chars_written = 0; 2539 2540 pdst[0] = '\0'; 2541 num_chars_written = vsnprintf(pdst, size, pfmt, argptr); 2542 2543 if ((num_chars_written >= (int)size) && (size > 0)) { 2544 /* Message length exceeds the buffer limit size */ 2545 num_chars_written = size - 1; 2546 pdst[size - 1] = '\0'; 2547 } 2548 } 2549 2550 /** mm_camera_debug_log 2551 * @module: origin or log message 2552 * @level: logging level 2553 * @func: caller function name 2554 * @line: caller line number 2555 * @fmt: log message formatting string 2556 * @...: variable argument list 2557 * 2558 * Generig logger method. 2559 * 2560 * Return: N/A 2561 **/ 2562 void mm_camera_debug_log(const cam_modules_t module, 2563 const cam_global_debug_level_t level, 2564 const char *func, const int line, const char *fmt, ...) { 2565 char str_buffer[CDBG_MAX_STR_LEN]; 2566 va_list args; 2567 2568 va_start(args, fmt); 2569 cam_vsnprintf(str_buffer, CDBG_MAX_STR_LEN, fmt, args); 2570 va_end(args); 2571 2572 switch (level) { 2573 case CAM_GLBL_DBG_WARN: 2574 ALOGW("%s%s %s: %d: %s", cam_loginfo[module].name, 2575 cam_dbg_level_to_str[level], func, line, str_buffer); 2576 break; 2577 case CAM_GLBL_DBG_ERR: 2578 ALOGE("%s%s %s: %d: %s", cam_loginfo[module].name, 2579 cam_dbg_level_to_str[level], func, line, str_buffer); 2580 break; 2581 case CAM_GLBL_DBG_INFO: 2582 ALOGI("%s%s %s: %d: %s", cam_loginfo[module].name, 2583 cam_dbg_level_to_str[level], func, line, str_buffer); 2584 break; 2585 case CAM_GLBL_DBG_HIGH: 2586 case CAM_GLBL_DBG_DEBUG: 2587 case CAM_GLBL_DBG_LOW: 2588 default: 2589 ALOGD("%s%s %s: %d: %s", cam_loginfo[module].name, 2590 cam_dbg_level_to_str[level], func, line, str_buffer); 2591 } 2592 } 2593 2594 /** mm_camera_set_dbg_log_properties 2595 * 2596 * Set global and module log level properties. 2597 * 2598 * Return: N/A 2599 **/ 2600 void mm_camera_set_dbg_log_properties(void) { 2601 int i; 2602 unsigned int j; 2603 static int boot_init = 1; 2604 char property_value[PROPERTY_VALUE_MAX] = {0}; 2605 char default_value[PROPERTY_VALUE_MAX] = {0}; 2606 2607 if (boot_init) { 2608 boot_init = 0; 2609 pthread_mutex_init(&dbg_log_mutex, 0); 2610 } 2611 2612 /* set global and individual module logging levels */ 2613 pthread_mutex_lock(&dbg_log_mutex); 2614 for (i = CAM_NO_MODULE; i < CAM_LAST_MODULE; i++) { 2615 cam_global_debug_level_t log_level; 2616 snprintf(default_value, PROPERTY_VALUE_MAX, "%d", (int)cam_loginfo[i].level); 2617 property_get(cam_loginfo[i].prop, property_value, default_value); 2618 log_level = (cam_global_debug_level_t)atoi(property_value); 2619 2620 /* fix KW warnings */ 2621 if (log_level > CAM_GLBL_DBG_INFO) { 2622 log_level = CAM_GLBL_DBG_INFO; 2623 } 2624 2625 cam_loginfo[i].level = log_level; 2626 2627 /* The logging macros will produce a log message when logging level for 2628 * a module is less or equal to the level specified in the property for 2629 * the module, or less or equal the level specified by the global logging 2630 * property. Currently we don't allow INFO logging to be turned off */ 2631 for (j = CAM_GLBL_DBG_ERR; j <= CAM_GLBL_DBG_LOW; j++) { 2632 g_cam_log[i][j] = (cam_loginfo[CAM_NO_MODULE].level != CAM_GLBL_DBG_NONE) && 2633 (cam_loginfo[i].level != CAM_GLBL_DBG_NONE) && 2634 ((j <= cam_loginfo[i].level) || 2635 (j <= cam_loginfo[CAM_NO_MODULE].level)); 2636 } 2637 } 2638 pthread_mutex_unlock(&dbg_log_mutex); 2639 } 2640 2641 #endif 2642