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