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