1 /* Copyright (c) 2012-2015, 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 #include <pthread.h> 31 #include <errno.h> 32 #include <sys/ioctl.h> 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <fcntl.h> 36 #include <poll.h> 37 #include <cutils/properties.h> 38 #include <stdlib.h> 39 40 #include <cam_semaphore.h> 41 42 #include "mm_camera_dbg.h" 43 #include "mm_camera_sock.h" 44 #include "mm_camera_interface.h" 45 #include "mm_camera.h" 46 47 #define SET_PARM_BIT32(parm, parm_arr) \ 48 (parm_arr[parm/32] |= (1<<(parm%32))) 49 50 #define GET_PARM_BIT32(parm, parm_arr) \ 51 ((parm_arr[parm/32]>>(parm%32))& 0x1) 52 53 #define WAIT_TIMEOUT 3 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 61 /*=========================================================================== 62 * FUNCTION : mm_camera_util_get_channel_by_handler 63 * 64 * DESCRIPTION: utility function to get a channel object from its handle 65 * 66 * PARAMETERS : 67 * @cam_obj: ptr to a camera object 68 * @handler: channel handle 69 * 70 * RETURN : ptr to a channel object. 71 * NULL if failed. 72 *==========================================================================*/ 73 mm_channel_t * mm_camera_util_get_channel_by_handler( 74 mm_camera_obj_t * cam_obj, 75 uint32_t handler) 76 { 77 int i; 78 mm_channel_t *ch_obj = NULL; 79 for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) { 80 if (handler == cam_obj->ch[i].my_hdl) { 81 ch_obj = &cam_obj->ch[i]; 82 break; 83 } 84 } 85 return ch_obj; 86 } 87 88 /*=========================================================================== 89 * FUNCTION : mm_camera_util_chip_is_a_family 90 * 91 * DESCRIPTION: utility function to check if the host is A family chip 92 * 93 * PARAMETERS : 94 * 95 * RETURN : TRUE if A family. 96 * FALSE otherwise. 97 *==========================================================================*/ 98 uint8_t mm_camera_util_chip_is_a_family(void) 99 { 100 #ifdef USE_A_FAMILY 101 return TRUE; 102 #else 103 return FALSE; 104 #endif 105 } 106 107 /*=========================================================================== 108 * FUNCTION : mm_camera_dispatch_app_event 109 * 110 * DESCRIPTION: dispatch event to apps who regitster for event notify 111 * 112 * PARAMETERS : 113 * @cmd_cb: ptr to a struct storing event info 114 * @user_data: user data ptr (camera object) 115 * 116 * RETURN : none 117 *==========================================================================*/ 118 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb, 119 void* user_data) 120 { 121 mm_camera_cmd_thread_name("mm_cam_event"); 122 int i; 123 mm_camera_event_t *event = &cmd_cb->u.evt; 124 mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data; 125 if (NULL != my_obj) { 126 pthread_mutex_lock(&my_obj->cb_lock); 127 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 128 if(my_obj->evt.evt[i].evt_cb) { 129 my_obj->evt.evt[i].evt_cb( 130 my_obj->my_hdl, 131 event, 132 my_obj->evt.evt[i].user_data); 133 } 134 } 135 pthread_mutex_unlock(&my_obj->cb_lock); 136 } 137 } 138 139 /*=========================================================================== 140 * FUNCTION : mm_camera_event_notify 141 * 142 * DESCRIPTION: callback to handle event notify from kernel. This call will 143 * dequeue event from kernel. 144 * 145 * PARAMETERS : 146 * @user_data: user data ptr (camera object) 147 * 148 * RETURN : none 149 *==========================================================================*/ 150 static void mm_camera_event_notify(void* user_data) 151 { 152 struct v4l2_event ev; 153 struct msm_v4l2_event_data *msm_evt = NULL; 154 int rc; 155 mm_camera_event_t evt; 156 memset(&evt, 0, sizeof(mm_camera_event_t)); 157 158 mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data; 159 if (NULL != my_obj) { 160 /* read evt */ 161 memset(&ev, 0, sizeof(ev)); 162 rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev); 163 164 if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) { 165 msm_evt = (struct msm_v4l2_event_data *)ev.u.data; 166 switch (msm_evt->command) { 167 case CAM_EVENT_TYPE_DAEMON_PULL_REQ: 168 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ; 169 mm_camera_enqueue_evt(my_obj, &evt); 170 break; 171 case CAM_EVENT_TYPE_MAP_UNMAP_DONE: 172 pthread_mutex_lock(&my_obj->evt_lock); 173 my_obj->evt_rcvd.server_event_type = msm_evt->command; 174 my_obj->evt_rcvd.status = msm_evt->status; 175 pthread_cond_signal(&my_obj->evt_cond); 176 pthread_mutex_unlock(&my_obj->evt_lock); 177 break; 178 case CAM_EVENT_TYPE_INT_TAKE_JPEG: 179 case CAM_EVENT_TYPE_INT_TAKE_RAW: 180 { 181 evt.server_event_type = msm_evt->command; 182 mm_camera_enqueue_evt(my_obj, &evt); 183 } 184 break; 185 case MSM_CAMERA_PRIV_SHUTDOWN: 186 { 187 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED; 188 mm_camera_enqueue_evt(my_obj, &evt); 189 } 190 break; 191 default: 192 break; 193 } 194 } 195 } 196 } 197 198 /*=========================================================================== 199 * FUNCTION : mm_camera_enqueue_evt 200 * 201 * DESCRIPTION: enqueue received event into event queue to be processed by 202 * event thread. 203 * 204 * PARAMETERS : 205 * @my_obj : ptr to a camera object 206 * @event : event to be queued 207 * 208 * RETURN : int32_t type of status 209 * 0 -- success 210 * -1 -- failure 211 *==========================================================================*/ 212 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj, 213 mm_camera_event_t *event) 214 { 215 int32_t rc = 0; 216 mm_camera_cmdcb_t *node = NULL; 217 218 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 219 if (NULL != node) { 220 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 221 node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB; 222 node->u.evt = *event; 223 224 /* enqueue to evt cmd thread */ 225 cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node); 226 /* wake up evt cmd thread */ 227 cam_sem_post(&(my_obj->evt_thread.cmd_sem)); 228 } else { 229 CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__); 230 rc = -1; 231 } 232 233 return rc; 234 } 235 236 /*=========================================================================== 237 * FUNCTION : mm_camera_open 238 * 239 * DESCRIPTION: open a camera 240 * 241 * PARAMETERS : 242 * @my_obj : ptr to a camera object 243 * 244 * RETURN : int32_t type of status 245 * 0 -- success 246 * -1 -- failure 247 *==========================================================================*/ 248 int32_t mm_camera_open(mm_camera_obj_t *my_obj) 249 { 250 char dev_name[MM_CAMERA_DEV_NAME_LEN]; 251 int32_t rc = 0; 252 int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES; 253 uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP; 254 int cam_idx = 0; 255 const char *dev_name_value = NULL; 256 char prop[PROPERTY_VALUE_MAX]; 257 uint32_t globalLogLevel = 0; 258 259 property_get("persist.camera.hal.debug", prop, "0"); 260 int val = atoi(prop); 261 if (0 <= val) { 262 gMmCameraIntfLogLevel = (uint32_t)val; 263 } 264 property_get("persist.camera.global.debug", prop, "0"); 265 val = atoi(prop); 266 if (0 <= val) { 267 globalLogLevel = (uint32_t)val; 268 } 269 270 /* Highest log level among hal.logs and global.logs is selected */ 271 if (gMmCameraIntfLogLevel < globalLogLevel) 272 gMmCameraIntfLogLevel = globalLogLevel; 273 274 CDBG("%s: begin\n", __func__); 275 276 if (NULL == my_obj) { 277 goto on_error; 278 } 279 dev_name_value = mm_camera_util_get_dev_name(my_obj->my_hdl); 280 if (NULL == dev_name_value) { 281 goto on_error; 282 } 283 snprintf(dev_name, sizeof(dev_name), "/dev/%s", 284 dev_name_value); 285 sscanf(dev_name, "/dev/video%d", &cam_idx); 286 CDBG("%s: dev name = %s, cam_idx = %d", __func__, dev_name, cam_idx); 287 288 do{ 289 n_try--; 290 errno = 0; 291 my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK); 292 CDBG("%s: ctrl_fd = %d, errno == %d", __func__, my_obj->ctrl_fd, errno); 293 if((my_obj->ctrl_fd >= 0) || 294 (errno != EIO && errno != ETIMEDOUT && errno != ENODEV) || 295 (n_try <= 0 )) { 296 CDBG_HIGH("%s: opened, break out while loop", __func__); 297 if (my_obj->ctrl_fd < 0) { 298 ALOGE("%s: Failed to open %s: %s(%d).", __func__, dev_name, 299 strerror(-errno), errno); 300 } 301 break; 302 } 303 ALOGE("%s:Failed with %s error, retrying after %d milli-seconds", 304 __func__, strerror(errno), sleep_msec); 305 usleep(sleep_msec * 1000U); 306 }while (n_try > 0); 307 308 if (my_obj->ctrl_fd < 0) { 309 CDBG_ERROR("%s: cannot open control fd of '%s' (%s)\n", 310 __func__, dev_name, strerror(errno)); 311 if (errno == EBUSY) 312 rc = -EUSERS; 313 else 314 rc = -1; 315 goto on_error; 316 } 317 318 /* open domain socket*/ 319 n_try = MM_CAMERA_DEV_OPEN_TRIES; 320 do { 321 n_try--; 322 my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP); 323 CDBG("%s: ds_fd = %d, errno = %d", __func__, my_obj->ds_fd, errno); 324 if((my_obj->ds_fd >= 0) || (n_try <= 0 )) { 325 CDBG("%s: opened, break out while loop", __func__); 326 break; 327 } 328 CDBG("%s:failed with I/O error retrying after %d milli-seconds", 329 __func__, sleep_msec); 330 usleep(sleep_msec * 1000U); 331 } while (n_try > 0); 332 333 if (my_obj->ds_fd < 0) { 334 CDBG_ERROR("%s: cannot open domain socket fd of '%s'(%s)\n", 335 __func__, dev_name, strerror(errno)); 336 rc = -1; 337 goto on_error; 338 } 339 pthread_mutex_init(&my_obj->msg_lock, NULL); 340 341 pthread_mutex_init(&my_obj->cb_lock, NULL); 342 pthread_mutex_init(&my_obj->evt_lock, NULL); 343 pthread_cond_init(&my_obj->evt_cond, NULL); 344 345 CDBG("%s : Launch evt Thread in Cam Open",__func__); 346 snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch"); 347 mm_camera_cmd_thread_launch(&my_obj->evt_thread, 348 mm_camera_dispatch_app_event, 349 (void *)my_obj); 350 351 /* launch event poll thread 352 * we will add evt fd into event poll thread upon user first register for evt */ 353 CDBG("%s : Launch evt Poll Thread in Cam Open", __func__); 354 snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Poll"); 355 mm_camera_poll_thread_launch(&my_obj->evt_poll_thread, 356 MM_CAMERA_POLL_TYPE_EVT); 357 mm_camera_evt_sub(my_obj, TRUE); 358 359 /* unlock cam_lock, we need release global intf_lock in camera_open(), 360 * in order not block operation of other Camera in dual camera use case.*/ 361 pthread_mutex_unlock(&my_obj->cam_lock); 362 CDBG("%s: end (rc = %d)\n", __func__, rc); 363 return rc; 364 365 on_error: 366 367 if (NULL == dev_name_value) { 368 CDBG_ERROR("%s: Invalid device name\n", __func__); 369 rc = -1; 370 } 371 372 if (NULL == my_obj) { 373 CDBG_ERROR("%s: Invalid camera object\n", __func__); 374 rc = -1; 375 } else { 376 if (my_obj->ctrl_fd >= 0) { 377 close(my_obj->ctrl_fd); 378 my_obj->ctrl_fd = -1; 379 } 380 if (my_obj->ds_fd >= 0) { 381 mm_camera_socket_close(my_obj->ds_fd); 382 my_obj->ds_fd = -1; 383 } 384 } 385 386 /* unlock cam_lock, we need release global intf_lock in camera_open(), 387 * in order not block operation of other Camera in dual camera use case.*/ 388 pthread_mutex_unlock(&my_obj->cam_lock); 389 return rc; 390 } 391 392 /*=========================================================================== 393 * FUNCTION : mm_camera_close 394 * 395 * DESCRIPTION: enqueue received event into event queue to be processed by 396 * event thread. 397 * 398 * PARAMETERS : 399 * @my_obj : ptr to a camera object 400 * @event : event to be queued 401 * 402 * RETURN : int32_t type of status 403 * 0 -- success 404 * -1 -- failure 405 *==========================================================================*/ 406 int32_t mm_camera_close(mm_camera_obj_t *my_obj) 407 { 408 CDBG("%s : unsubscribe evt", __func__); 409 mm_camera_evt_sub(my_obj, FALSE); 410 411 CDBG("%s : Close evt Poll Thread in Cam Close",__func__); 412 mm_camera_poll_thread_release(&my_obj->evt_poll_thread); 413 414 CDBG("%s : Close evt cmd Thread in Cam Close",__func__); 415 mm_camera_cmd_thread_release(&my_obj->evt_thread); 416 417 if(my_obj->ctrl_fd >= 0) { 418 close(my_obj->ctrl_fd); 419 my_obj->ctrl_fd = -1; 420 } 421 if(my_obj->ds_fd >= 0) { 422 mm_camera_socket_close(my_obj->ds_fd); 423 my_obj->ds_fd = -1; 424 } 425 pthread_mutex_destroy(&my_obj->msg_lock); 426 427 pthread_mutex_destroy(&my_obj->cb_lock); 428 pthread_mutex_destroy(&my_obj->evt_lock); 429 pthread_cond_destroy(&my_obj->evt_cond); 430 431 pthread_mutex_unlock(&my_obj->cam_lock); 432 return 0; 433 } 434 435 /*=========================================================================== 436 * FUNCTION : mm_camera_close_fd 437 * 438 * DESCRIPTION: close the ctrl_fd and socket fd in case of an error so that 439 * the backend will close 440 * Do NOT close or release any HAL resources since a close_camera 441 * has not been called yet. 442 * PARAMETERS : 443 * @my_obj : ptr to a camera object 444 * @event : event to be queued 445 * 446 * RETURN : int32_t type of status 447 * 0 -- success 448 * -1 -- failure 449 *==========================================================================*/ 450 int32_t mm_camera_close_fd(mm_camera_obj_t *my_obj) 451 { 452 if(my_obj->ctrl_fd >= 0) { 453 close(my_obj->ctrl_fd); 454 my_obj->ctrl_fd = -1; 455 } 456 if(my_obj->ds_fd >= 0) { 457 mm_camera_socket_close(my_obj->ds_fd); 458 my_obj->ds_fd = -1; 459 } 460 pthread_mutex_unlock(&my_obj->cam_lock); 461 return 0; 462 } 463 464 /*=========================================================================== 465 * FUNCTION : mm_camera_register_event_notify_internal 466 * 467 * DESCRIPTION: internal implementation for registering callback for event notify. 468 * 469 * PARAMETERS : 470 * @my_obj : ptr to a camera object 471 * @evt_cb : callback to be registered to handle event notify 472 * @user_data: user data ptr 473 * 474 * RETURN : int32_t type of status 475 * 0 -- success 476 * -1 -- failure 477 *==========================================================================*/ 478 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj, 479 mm_camera_event_notify_t evt_cb, 480 void * user_data) 481 { 482 int i; 483 int rc = -1; 484 mm_camera_evt_obj_t *evt_array = NULL; 485 486 pthread_mutex_lock(&my_obj->cb_lock); 487 evt_array = &my_obj->evt; 488 if(evt_cb) { 489 /* this is reg case */ 490 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 491 if(evt_array->evt[i].user_data == NULL) { 492 evt_array->evt[i].evt_cb = evt_cb; 493 evt_array->evt[i].user_data = user_data; 494 evt_array->reg_count++; 495 rc = 0; 496 break; 497 } 498 } 499 } else { 500 /* this is unreg case */ 501 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 502 if(evt_array->evt[i].user_data == user_data) { 503 evt_array->evt[i].evt_cb = NULL; 504 evt_array->evt[i].user_data = NULL; 505 evt_array->reg_count--; 506 rc = 0; 507 break; 508 } 509 } 510 } 511 512 pthread_mutex_unlock(&my_obj->cb_lock); 513 return rc; 514 } 515 516 /*=========================================================================== 517 * FUNCTION : mm_camera_register_event_notify 518 * 519 * DESCRIPTION: registering a callback for event notify. 520 * 521 * PARAMETERS : 522 * @my_obj : ptr to a camera object 523 * @evt_cb : callback to be registered to handle event notify 524 * @user_data: user data ptr 525 * 526 * RETURN : int32_t type of status 527 * 0 -- success 528 * -1 -- failure 529 *==========================================================================*/ 530 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj, 531 mm_camera_event_notify_t evt_cb, 532 void * user_data) 533 { 534 int rc = -1; 535 rc = mm_camera_register_event_notify_internal(my_obj, 536 evt_cb, 537 user_data); 538 pthread_mutex_unlock(&my_obj->cam_lock); 539 return rc; 540 } 541 542 /*=========================================================================== 543 * FUNCTION : mm_camera_qbuf 544 * 545 * DESCRIPTION: enqueue buffer back to kernel 546 * 547 * PARAMETERS : 548 * @my_obj : camera object 549 * @ch_id : channel handle 550 * @buf : buf ptr to be enqueued 551 * 552 * RETURN : int32_t type of status 553 * 0 -- success 554 * -1 -- failure 555 *==========================================================================*/ 556 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj, 557 uint32_t ch_id, 558 mm_camera_buf_def_t *buf) 559 { 560 int rc = -1; 561 mm_channel_t * ch_obj = NULL; 562 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id); 563 564 pthread_mutex_unlock(&my_obj->cam_lock); 565 566 /* we always assume qbuf will be done before channel/stream is fully stopped 567 * because qbuf is done within dataCB context 568 * in order to avoid deadlock, we are not locking ch_lock for qbuf */ 569 if (NULL != ch_obj) { 570 rc = mm_channel_qbuf(ch_obj, buf); 571 } 572 573 return rc; 574 } 575 576 /*=========================================================================== 577 * FUNCTION : mm_camera_get_queued_buf_count 578 * 579 * DESCRIPTION: return queued buffer count 580 * 581 * PARAMETERS : 582 * @my_obj : camera object 583 * @ch_id : channel handle 584 * @stream_id : stream id 585 * 586 * RETURN : queued buffer count 587 *==========================================================================*/ 588 int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj, 589 uint32_t ch_id, uint32_t stream_id) 590 { 591 int rc = -1; 592 mm_channel_t * ch_obj = NULL; 593 uint32_t payload; 594 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id); 595 payload = stream_id; 596 597 if (NULL != ch_obj) { 598 pthread_mutex_lock(&ch_obj->ch_lock); 599 pthread_mutex_unlock(&my_obj->cam_lock); 600 rc = mm_channel_fsm_fn(ch_obj, 601 MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT, 602 (void *)&payload, 603 NULL); 604 } else { 605 pthread_mutex_unlock(&my_obj->cam_lock); 606 } 607 608 return rc; 609 } 610 611 /*=========================================================================== 612 * FUNCTION : mm_camera_query_capability 613 * 614 * DESCRIPTION: query camera capability 615 * 616 * PARAMETERS : 617 * @my_obj: camera object 618 * 619 * RETURN : int32_t type of status 620 * 0 -- success 621 * -1 -- failure 622 *==========================================================================*/ 623 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj) 624 { 625 int32_t rc = 0; 626 struct v4l2_capability cap; 627 628 /* get camera capabilities */ 629 memset(&cap, 0, sizeof(cap)); 630 rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap); 631 if (rc != 0) { 632 CDBG_ERROR("%s: cannot get camera capabilities, rc = %d\n", __func__, rc); 633 } 634 635 pthread_mutex_unlock(&my_obj->cam_lock); 636 return rc; 637 638 } 639 640 /*=========================================================================== 641 * FUNCTION : mm_camera_set_parms 642 * 643 * DESCRIPTION: set parameters per camera 644 * 645 * PARAMETERS : 646 * @my_obj : camera object 647 * @parms : ptr to a param struct to be set to server 648 * 649 * RETURN : int32_t type of status 650 * 0 -- success 651 * -1 -- failure 652 * NOTE : Assume the parms struct buf is already mapped to server via 653 * domain socket. Corresponding fields of parameters to be set 654 * are already filled in by upper layer caller. 655 *==========================================================================*/ 656 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj, 657 parm_buffer_t *parms) 658 { 659 int32_t rc = -1; 660 int32_t value = 0; 661 if (parms != NULL) { 662 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value); 663 } 664 pthread_mutex_unlock(&my_obj->cam_lock); 665 return rc; 666 } 667 668 /*=========================================================================== 669 * FUNCTION : mm_camera_get_parms 670 * 671 * DESCRIPTION: get parameters per camera 672 * 673 * PARAMETERS : 674 * @my_obj : camera object 675 * @parms : ptr to a param struct to be get from server 676 * 677 * RETURN : int32_t type of status 678 * 0 -- success 679 * -1 -- failure 680 * NOTE : Assume the parms struct buf is already mapped to server via 681 * domain socket. Parameters to be get from server are already 682 * filled in by upper layer caller. After this call, corresponding 683 * fields of requested parameters will be filled in by server with 684 * detailed information. 685 *==========================================================================*/ 686 int32_t mm_camera_get_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_g_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value); 693 } 694 pthread_mutex_unlock(&my_obj->cam_lock); 695 return rc; 696 } 697 698 /*=========================================================================== 699 * FUNCTION : mm_camera_do_auto_focus 700 * 701 * DESCRIPTION: performing auto focus 702 * 703 * PARAMETERS : 704 * @camera_handle: camera handle 705 * 706 * RETURN : int32_t type of status 707 * 0 -- success 708 * -1 -- failure 709 * NOTE : if this call success, we will always assume there will 710 * be an auto_focus event following up. 711 *==========================================================================*/ 712 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj) 713 { 714 int32_t rc = -1; 715 int32_t value = 0; 716 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value); 717 pthread_mutex_unlock(&my_obj->cam_lock); 718 return rc; 719 } 720 721 /*=========================================================================== 722 * FUNCTION : mm_camera_cancel_auto_focus 723 * 724 * DESCRIPTION: cancel auto focus 725 * 726 * PARAMETERS : 727 * @camera_handle: camera handle 728 * 729 * RETURN : int32_t type of status 730 * 0 -- success 731 * -1 -- failure 732 *==========================================================================*/ 733 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj) 734 { 735 int32_t rc = -1; 736 int32_t value = 0; 737 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value); 738 pthread_mutex_unlock(&my_obj->cam_lock); 739 return rc; 740 } 741 742 /*=========================================================================== 743 * FUNCTION : mm_camera_prepare_snapshot 744 * 745 * DESCRIPTION: prepare hardware for snapshot 746 * 747 * PARAMETERS : 748 * @my_obj : camera object 749 * @do_af_flag : flag indicating if AF is needed 750 * 751 * RETURN : int32_t type of status 752 * 0 -- success 753 * -1 -- failure 754 *==========================================================================*/ 755 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj, 756 int32_t do_af_flag) 757 { 758 int32_t rc = -1; 759 int32_t value = do_af_flag; 760 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value); 761 pthread_mutex_unlock(&my_obj->cam_lock); 762 return rc; 763 } 764 765 /*=========================================================================== 766 * FUNCTION : mm_camera_start_zsl_snapshot 767 * 768 * DESCRIPTION: start zsl snapshot 769 * 770 * PARAMETERS : 771 * @my_obj : camera object 772 * 773 * RETURN : int32_t type of status 774 * 0 -- success 775 * -1 -- failure 776 *==========================================================================*/ 777 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj) 778 { 779 int32_t rc = -1; 780 int32_t value = 0; 781 782 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, 783 CAM_PRIV_START_ZSL_SNAPSHOT, &value); 784 return rc; 785 } 786 787 /*=========================================================================== 788 * FUNCTION : mm_camera_stop_zsl_snapshot 789 * 790 * DESCRIPTION: stop zsl capture 791 * 792 * PARAMETERS : 793 * @my_obj : camera object 794 * 795 * RETURN : int32_t type of status 796 * 0 -- success 797 * -1 -- failure 798 *==========================================================================*/ 799 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj) 800 { 801 int32_t rc = -1; 802 int32_t value; 803 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, 804 CAM_PRIV_STOP_ZSL_SNAPSHOT, &value); 805 return rc; 806 } 807 808 /*=========================================================================== 809 * FUNCTION : mm_camera_add_channel 810 * 811 * DESCRIPTION: add a channel 812 * 813 * PARAMETERS : 814 * @my_obj : camera object 815 * @attr : bundle attribute of the channel if needed 816 * @channel_cb : callback function for bundle data notify 817 * @userdata : user data ptr 818 * 819 * RETURN : uint32_t type of channel handle 820 * 0 -- invalid channel handle, meaning the op failed 821 * >0 -- successfully added a channel with a valid handle 822 * NOTE : if no bundle data notify is needed, meaning each stream in the 823 * channel will have its own stream data notify callback, then 824 * attr, channel_cb, and userdata can be NULL. In this case, 825 * no matching logic will be performed in channel for the bundling. 826 *==========================================================================*/ 827 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj, 828 mm_camera_channel_attr_t *attr, 829 mm_camera_buf_notify_t channel_cb, 830 void *userdata) 831 { 832 mm_channel_t *ch_obj = NULL; 833 uint8_t ch_idx = 0; 834 uint32_t ch_hdl = 0; 835 836 for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) { 837 if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) { 838 ch_obj = &my_obj->ch[ch_idx]; 839 break; 840 } 841 } 842 843 if (NULL != ch_obj) { 844 /* initialize channel obj */ 845 memset(ch_obj, 0, sizeof(mm_channel_t)); 846 ch_hdl = mm_camera_util_generate_handler(ch_idx); 847 ch_obj->my_hdl = ch_hdl; 848 ch_obj->state = MM_CHANNEL_STATE_STOPPED; 849 ch_obj->cam_obj = my_obj; 850 pthread_mutex_init(&ch_obj->ch_lock, NULL); 851 mm_channel_init(ch_obj, attr, channel_cb, userdata); 852 } 853 854 pthread_mutex_unlock(&my_obj->cam_lock); 855 856 return ch_hdl; 857 } 858 859 /*=========================================================================== 860 * FUNCTION : mm_camera_del_channel 861 * 862 * DESCRIPTION: delete a channel by its handle 863 * 864 * PARAMETERS : 865 * @my_obj : camera object 866 * @ch_id : channel handle 867 * 868 * RETURN : int32_t type of status 869 * 0 -- success 870 * -1 -- failure 871 * NOTE : all streams in the channel should be stopped already before 872 * this channel can be deleted. 873 *==========================================================================*/ 874 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj, 875 uint32_t ch_id) 876 { 877 int32_t rc = -1; 878 mm_channel_t * ch_obj = 879 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 880 881 if (NULL != ch_obj) { 882 pthread_mutex_lock(&ch_obj->ch_lock); 883 pthread_mutex_unlock(&my_obj->cam_lock); 884 885 rc = mm_channel_fsm_fn(ch_obj, 886 MM_CHANNEL_EVT_DELETE, 887 NULL, 888 NULL); 889 890 pthread_mutex_destroy(&ch_obj->ch_lock); 891 memset(ch_obj, 0, sizeof(mm_channel_t)); 892 } else { 893 pthread_mutex_unlock(&my_obj->cam_lock); 894 } 895 return rc; 896 } 897 898 /*=========================================================================== 899 * FUNCTION : mm_camera_get_bundle_info 900 * 901 * DESCRIPTION: query bundle info of the channel 902 * 903 * PARAMETERS : 904 * @my_obj : camera object 905 * @ch_id : channel handle 906 * @bundle_info : bundle info to be filled in 907 * 908 * RETURN : int32_t type of status 909 * 0 -- success 910 * -1 -- failure 911 * NOTE : all streams in the channel should be stopped already before 912 * this channel can be deleted. 913 *==========================================================================*/ 914 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj, 915 uint32_t ch_id, 916 cam_bundle_config_t *bundle_info) 917 { 918 int32_t rc = -1; 919 mm_channel_t * ch_obj = 920 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 921 922 if (NULL != ch_obj) { 923 pthread_mutex_lock(&ch_obj->ch_lock); 924 pthread_mutex_unlock(&my_obj->cam_lock); 925 926 rc = mm_channel_fsm_fn(ch_obj, 927 MM_CHANNEL_EVT_GET_BUNDLE_INFO, 928 (void *)bundle_info, 929 NULL); 930 } else { 931 pthread_mutex_unlock(&my_obj->cam_lock); 932 } 933 return rc; 934 } 935 936 /*=========================================================================== 937 * FUNCTION : mm_camera_link_stream 938 * 939 * DESCRIPTION: link a stream into a channel 940 * 941 * PARAMETERS : 942 * @my_obj : camera object 943 * @ch_id : channel handle 944 * @stream_id : stream that will be linked 945 * @linked_ch_id : channel in which the stream will be linked 946 * 947 * RETURN : uint32_t type of stream handle 948 * 0 -- invalid stream handle, meaning the op failed 949 * >0 -- successfully linked a stream with a valid handle 950 *==========================================================================*/ 951 uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj, 952 uint32_t ch_id, 953 uint32_t stream_id, 954 uint32_t linked_ch_id) 955 { 956 uint32_t s_hdl = 0; 957 mm_channel_t * ch_obj = 958 mm_camera_util_get_channel_by_handler(my_obj, linked_ch_id); 959 mm_channel_t * owner_obj = 960 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 961 962 if ((NULL != ch_obj) && (NULL != owner_obj)) { 963 pthread_mutex_lock(&ch_obj->ch_lock); 964 pthread_mutex_unlock(&my_obj->cam_lock); 965 966 mm_camera_stream_link_t stream_link; 967 memset(&stream_link, 0, sizeof(mm_camera_stream_link_t)); 968 stream_link.ch = owner_obj; 969 stream_link.stream_id = stream_id; 970 mm_channel_fsm_fn(ch_obj, 971 MM_CHANNEL_EVT_LINK_STREAM, 972 (void*)&stream_link, 973 (void*)&s_hdl); 974 } else { 975 pthread_mutex_unlock(&my_obj->cam_lock); 976 } 977 978 return s_hdl; 979 } 980 981 /*=========================================================================== 982 * FUNCTION : mm_camera_add_stream 983 * 984 * DESCRIPTION: add a stream into a channel 985 * 986 * PARAMETERS : 987 * @my_obj : camera object 988 * @ch_id : channel handle 989 * 990 * RETURN : uint32_t type of stream handle 991 * 0 -- invalid stream handle, meaning the op failed 992 * >0 -- successfully added a stream with a valid handle 993 *==========================================================================*/ 994 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj, 995 uint32_t ch_id) 996 { 997 uint32_t s_hdl = 0; 998 mm_channel_t * ch_obj = 999 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1000 1001 if (NULL != ch_obj) { 1002 pthread_mutex_lock(&ch_obj->ch_lock); 1003 pthread_mutex_unlock(&my_obj->cam_lock); 1004 1005 mm_channel_fsm_fn(ch_obj, 1006 MM_CHANNEL_EVT_ADD_STREAM, 1007 NULL, 1008 (void *)&s_hdl); 1009 } else { 1010 pthread_mutex_unlock(&my_obj->cam_lock); 1011 } 1012 1013 return s_hdl; 1014 } 1015 1016 /*=========================================================================== 1017 * FUNCTION : mm_camera_del_stream 1018 * 1019 * DESCRIPTION: delete a stream by its handle 1020 * 1021 * PARAMETERS : 1022 * @my_obj : camera object 1023 * @ch_id : channel handle 1024 * @stream_id : stream handle 1025 * 1026 * RETURN : int32_t type of status 1027 * 0 -- success 1028 * -1 -- failure 1029 * NOTE : stream should be stopped already before it can be deleted. 1030 *==========================================================================*/ 1031 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj, 1032 uint32_t ch_id, 1033 uint32_t stream_id) 1034 { 1035 int32_t rc = -1; 1036 mm_channel_t * ch_obj = 1037 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1038 1039 if (NULL != ch_obj) { 1040 pthread_mutex_lock(&ch_obj->ch_lock); 1041 pthread_mutex_unlock(&my_obj->cam_lock); 1042 1043 rc = mm_channel_fsm_fn(ch_obj, 1044 MM_CHANNEL_EVT_DEL_STREAM, 1045 (void *)&stream_id, 1046 NULL); 1047 } else { 1048 pthread_mutex_unlock(&my_obj->cam_lock); 1049 } 1050 1051 return rc; 1052 } 1053 1054 /*=========================================================================== 1055 * FUNCTION : mm_camera_start_zsl_snapshot_ch 1056 * 1057 * DESCRIPTION: starts zsl snapshot for specific channel 1058 * 1059 * PARAMETERS : 1060 * @my_obj : camera object 1061 * @ch_id : channel handle 1062 * 1063 * RETURN : int32_t type of status 1064 * 0 -- success 1065 * -1 -- failure 1066 *==========================================================================*/ 1067 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj, 1068 uint32_t ch_id) 1069 { 1070 int32_t rc = -1; 1071 mm_channel_t * ch_obj = 1072 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1073 1074 if (NULL != ch_obj) { 1075 pthread_mutex_lock(&ch_obj->ch_lock); 1076 pthread_mutex_unlock(&my_obj->cam_lock); 1077 1078 rc = mm_channel_fsm_fn(ch_obj, 1079 MM_CHANNEL_EVT_START_ZSL_SNAPSHOT, 1080 NULL, 1081 NULL); 1082 } else { 1083 pthread_mutex_unlock(&my_obj->cam_lock); 1084 } 1085 1086 return rc; 1087 } 1088 1089 /*=========================================================================== 1090 * FUNCTION : mm_camera_stop_zsl_snapshot_ch 1091 * 1092 * DESCRIPTION: stops zsl snapshot for specific channel 1093 * 1094 * PARAMETERS : 1095 * @my_obj : camera object 1096 * @ch_id : channel handle 1097 * 1098 * RETURN : int32_t type of status 1099 * 0 -- success 1100 * -1 -- failure 1101 *==========================================================================*/ 1102 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj, 1103 uint32_t ch_id) 1104 { 1105 int32_t rc = -1; 1106 mm_channel_t * ch_obj = 1107 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1108 1109 if (NULL != ch_obj) { 1110 pthread_mutex_lock(&ch_obj->ch_lock); 1111 pthread_mutex_unlock(&my_obj->cam_lock); 1112 1113 rc = mm_channel_fsm_fn(ch_obj, 1114 MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT, 1115 NULL, 1116 NULL); 1117 } else { 1118 pthread_mutex_unlock(&my_obj->cam_lock); 1119 } 1120 1121 return rc; 1122 } 1123 1124 /*=========================================================================== 1125 * FUNCTION : mm_camera_config_stream 1126 * 1127 * DESCRIPTION: configure a stream 1128 * 1129 * PARAMETERS : 1130 * @my_obj : camera object 1131 * @ch_id : channel handle 1132 * @stream_id : stream handle 1133 * @config : stream configuration 1134 * 1135 * RETURN : int32_t type of status 1136 * 0 -- success 1137 * -1 -- failure 1138 *==========================================================================*/ 1139 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj, 1140 uint32_t ch_id, 1141 uint32_t stream_id, 1142 mm_camera_stream_config_t *config) 1143 { 1144 int32_t rc = -1; 1145 mm_channel_t * ch_obj = 1146 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1147 mm_evt_paylod_config_stream_t payload; 1148 1149 if (NULL != ch_obj) { 1150 pthread_mutex_lock(&ch_obj->ch_lock); 1151 pthread_mutex_unlock(&my_obj->cam_lock); 1152 1153 memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t)); 1154 payload.stream_id = stream_id; 1155 payload.config = config; 1156 rc = mm_channel_fsm_fn(ch_obj, 1157 MM_CHANNEL_EVT_CONFIG_STREAM, 1158 (void *)&payload, 1159 NULL); 1160 } else { 1161 pthread_mutex_unlock(&my_obj->cam_lock); 1162 } 1163 1164 return rc; 1165 } 1166 1167 /*=========================================================================== 1168 * FUNCTION : mm_camera_start_channel 1169 * 1170 * DESCRIPTION: start a channel, which will start all streams in the channel 1171 * 1172 * PARAMETERS : 1173 * @my_obj : camera object 1174 * @ch_id : channel handle 1175 * 1176 * RETURN : int32_t type of status 1177 * 0 -- success 1178 * -1 -- failure 1179 *==========================================================================*/ 1180 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj, 1181 uint32_t ch_id) 1182 { 1183 int32_t rc = -1; 1184 mm_channel_t * ch_obj = 1185 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1186 1187 if (NULL != ch_obj) { 1188 pthread_mutex_lock(&ch_obj->ch_lock); 1189 pthread_mutex_unlock(&my_obj->cam_lock); 1190 1191 rc = mm_channel_fsm_fn(ch_obj, 1192 MM_CHANNEL_EVT_START, 1193 NULL, 1194 NULL); 1195 } else { 1196 pthread_mutex_unlock(&my_obj->cam_lock); 1197 } 1198 1199 return rc; 1200 } 1201 1202 /*=========================================================================== 1203 * FUNCTION : mm_camera_stop_channel 1204 * 1205 * DESCRIPTION: stop a channel, which will stop all streams in the channel 1206 * 1207 * PARAMETERS : 1208 * @my_obj : camera object 1209 * @ch_id : channel handle 1210 * 1211 * RETURN : int32_t type of status 1212 * 0 -- success 1213 * -1 -- failure 1214 *==========================================================================*/ 1215 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj, 1216 uint32_t ch_id) 1217 { 1218 int32_t rc = 0; 1219 mm_channel_t * ch_obj = 1220 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1221 1222 if (NULL != ch_obj) { 1223 pthread_mutex_lock(&ch_obj->ch_lock); 1224 pthread_mutex_unlock(&my_obj->cam_lock); 1225 1226 rc = mm_channel_fsm_fn(ch_obj, 1227 MM_CHANNEL_EVT_STOP, 1228 NULL, 1229 NULL); 1230 } else { 1231 pthread_mutex_unlock(&my_obj->cam_lock); 1232 } 1233 return rc; 1234 } 1235 1236 /*=========================================================================== 1237 * FUNCTION : mm_camera_request_super_buf 1238 * 1239 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched 1240 * frames from superbuf queue 1241 * 1242 * PARAMETERS : 1243 * @my_obj : camera object 1244 * @ch_id : channel handle 1245 * @num_buf_requested : number of matched frames needed 1246 * 1247 * RETURN : int32_t type of status 1248 * 0 -- success 1249 * -1 -- failure 1250 *==========================================================================*/ 1251 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj, 1252 uint32_t ch_id, 1253 uint32_t num_buf_requested, 1254 uint32_t num_retro_buf_requested) 1255 { 1256 int32_t rc = -1; 1257 mm_channel_t * ch_obj = 1258 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1259 1260 if (NULL != ch_obj) { 1261 pthread_mutex_lock(&ch_obj->ch_lock); 1262 pthread_mutex_unlock(&my_obj->cam_lock); 1263 1264 rc = mm_channel_fsm_fn(ch_obj, 1265 MM_CHANNEL_EVT_REQUEST_SUPER_BUF, 1266 (void *)&num_buf_requested, 1267 (void *)&num_retro_buf_requested); 1268 } else { 1269 pthread_mutex_unlock(&my_obj->cam_lock); 1270 } 1271 1272 return rc; 1273 } 1274 1275 /*=========================================================================== 1276 * FUNCTION : mm_camera_cancel_super_buf_request 1277 * 1278 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount 1279 * of matched frames from superbuf queue 1280 * 1281 * PARAMETERS : 1282 * @my_obj : camera object 1283 * @ch_id : channel handle 1284 * 1285 * RETURN : int32_t type of status 1286 * 0 -- success 1287 * -1 -- failure 1288 *==========================================================================*/ 1289 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id) 1290 { 1291 int32_t rc = -1; 1292 mm_channel_t * ch_obj = 1293 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1294 1295 if (NULL != ch_obj) { 1296 pthread_mutex_lock(&ch_obj->ch_lock); 1297 pthread_mutex_unlock(&my_obj->cam_lock); 1298 1299 rc = mm_channel_fsm_fn(ch_obj, 1300 MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF, 1301 NULL, 1302 NULL); 1303 } else { 1304 pthread_mutex_unlock(&my_obj->cam_lock); 1305 } 1306 1307 return rc; 1308 } 1309 1310 /*=========================================================================== 1311 * FUNCTION : mm_camera_flush_super_buf_queue 1312 * 1313 * DESCRIPTION: flush out all frames in the superbuf queue 1314 * 1315 * PARAMETERS : 1316 * @my_obj : camera object 1317 * @ch_id : channel handle 1318 * 1319 * RETURN : int32_t type of status 1320 * 0 -- success 1321 * -1 -- failure 1322 *==========================================================================*/ 1323 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id, 1324 uint32_t frame_idx) 1325 { 1326 int32_t rc = -1; 1327 mm_channel_t * ch_obj = 1328 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1329 1330 if (NULL != ch_obj) { 1331 pthread_mutex_lock(&ch_obj->ch_lock); 1332 pthread_mutex_unlock(&my_obj->cam_lock); 1333 1334 rc = mm_channel_fsm_fn(ch_obj, 1335 MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE, 1336 (void *)&frame_idx, 1337 NULL); 1338 } else { 1339 pthread_mutex_unlock(&my_obj->cam_lock); 1340 } 1341 1342 return rc; 1343 } 1344 1345 /*=========================================================================== 1346 * FUNCTION : mm_camera_config_channel_notify 1347 * 1348 * DESCRIPTION: configures the channel notification mode 1349 * 1350 * PARAMETERS : 1351 * @my_obj : camera object 1352 * @ch_id : channel handle 1353 * @notify_mode : notification mode 1354 * 1355 * RETURN : int32_t type of status 1356 * 0 -- success 1357 * -1 -- failure 1358 *==========================================================================*/ 1359 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj, 1360 uint32_t ch_id, 1361 mm_camera_super_buf_notify_mode_t notify_mode) 1362 { 1363 int32_t rc = -1; 1364 mm_channel_t * ch_obj = 1365 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1366 1367 if (NULL != ch_obj) { 1368 pthread_mutex_lock(&ch_obj->ch_lock); 1369 pthread_mutex_unlock(&my_obj->cam_lock); 1370 1371 rc = mm_channel_fsm_fn(ch_obj, 1372 MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE, 1373 (void *)¬ify_mode, 1374 NULL); 1375 } else { 1376 pthread_mutex_unlock(&my_obj->cam_lock); 1377 } 1378 1379 return rc; 1380 } 1381 1382 /*=========================================================================== 1383 * FUNCTION : mm_camera_set_stream_parms 1384 * 1385 * DESCRIPTION: set parameters per stream 1386 * 1387 * PARAMETERS : 1388 * @my_obj : camera object 1389 * @ch_id : channel handle 1390 * @s_id : stream handle 1391 * @parms : ptr to a param struct to be set to server 1392 * 1393 * RETURN : int32_t type of status 1394 * 0 -- success 1395 * -1 -- failure 1396 * NOTE : Assume the parms struct buf is already mapped to server via 1397 * domain socket. Corresponding fields of parameters to be set 1398 * are already filled in by upper layer caller. 1399 *==========================================================================*/ 1400 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj, 1401 uint32_t ch_id, 1402 uint32_t s_id, 1403 cam_stream_parm_buffer_t *parms) 1404 { 1405 int32_t rc = -1; 1406 mm_evt_paylod_set_get_stream_parms_t payload; 1407 mm_channel_t * ch_obj = 1408 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1409 1410 if (NULL != ch_obj) { 1411 pthread_mutex_lock(&ch_obj->ch_lock); 1412 pthread_mutex_unlock(&my_obj->cam_lock); 1413 1414 memset(&payload, 0, sizeof(payload)); 1415 payload.stream_id = s_id; 1416 payload.parms = parms; 1417 1418 rc = mm_channel_fsm_fn(ch_obj, 1419 MM_CHANNEL_EVT_SET_STREAM_PARM, 1420 (void *)&payload, 1421 NULL); 1422 } else { 1423 pthread_mutex_unlock(&my_obj->cam_lock); 1424 } 1425 1426 return rc; 1427 } 1428 1429 /*=========================================================================== 1430 * FUNCTION : mm_camera_get_stream_parms 1431 * 1432 * DESCRIPTION: get parameters per stream 1433 * 1434 * PARAMETERS : 1435 * @my_obj : camera object 1436 * @ch_id : channel handle 1437 * @s_id : stream handle 1438 * @parms : ptr to a param struct to be get from server 1439 * 1440 * RETURN : int32_t type of status 1441 * 0 -- success 1442 * -1 -- failure 1443 * NOTE : Assume the parms struct buf is already mapped to server via 1444 * domain socket. Parameters to be get from server are already 1445 * filled in by upper layer caller. After this call, corresponding 1446 * fields of requested parameters will be filled in by server with 1447 * detailed information. 1448 *==========================================================================*/ 1449 int32_t mm_camera_get_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_GET_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_do_stream_action 1480 * 1481 * DESCRIPTION: request server to perform stream based action. Maybe removed later 1482 * if the functionality is included in mm_camera_set_parms 1483 * 1484 * PARAMETERS : 1485 * @my_obj : camera object 1486 * @ch_id : channel handle 1487 * @s_id : stream handle 1488 * @actions : ptr to an action struct buf to be performed by server 1489 * 1490 * RETURN : int32_t type of status 1491 * 0 -- success 1492 * -1 -- failure 1493 * NOTE : Assume the action struct buf is already mapped to server via 1494 * domain socket. Actions to be performed by server are already 1495 * filled in by upper layer caller. 1496 *==========================================================================*/ 1497 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj, 1498 uint32_t ch_id, 1499 uint32_t stream_id, 1500 void *actions) 1501 { 1502 int32_t rc = -1; 1503 mm_evt_paylod_do_stream_action_t payload; 1504 mm_channel_t * ch_obj = 1505 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1506 1507 if (NULL != ch_obj) { 1508 pthread_mutex_lock(&ch_obj->ch_lock); 1509 pthread_mutex_unlock(&my_obj->cam_lock); 1510 1511 memset(&payload, 0, sizeof(payload)); 1512 payload.stream_id = stream_id; 1513 payload.actions = actions; 1514 1515 rc = mm_channel_fsm_fn(ch_obj, 1516 MM_CHANNEL_EVT_DO_STREAM_ACTION, 1517 (void*)&payload, 1518 NULL); 1519 } else { 1520 pthread_mutex_unlock(&my_obj->cam_lock); 1521 } 1522 1523 return rc; 1524 } 1525 1526 /*=========================================================================== 1527 * FUNCTION : mm_camera_map_stream_buf 1528 * 1529 * DESCRIPTION: mapping stream buffer via domain socket to server 1530 * 1531 * PARAMETERS : 1532 * @my_obj : camera object 1533 * @ch_id : channel handle 1534 * @s_id : stream handle 1535 * @buf_type : type of buffer to be mapped. could be following values: 1536 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1537 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1538 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1539 * @buf_idx : index of buffer within the stream buffers, only valid if 1540 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1541 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1542 * @plane_idx : plane index. If all planes share the same fd, 1543 * plane_idx = -1; otherwise, plean_idx is the 1544 * index to plane (0..num_of_planes) 1545 * @fd : file descriptor of the buffer 1546 * @size : size of the buffer 1547 * 1548 * RETURN : int32_t type of status 1549 * 0 -- success 1550 * -1 -- failure 1551 *==========================================================================*/ 1552 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj, 1553 uint32_t ch_id, 1554 uint32_t stream_id, 1555 uint8_t buf_type, 1556 uint32_t buf_idx, 1557 int32_t plane_idx, 1558 int fd, 1559 size_t size) 1560 { 1561 int32_t rc = -1; 1562 mm_evt_paylod_map_stream_buf_t payload; 1563 mm_channel_t * ch_obj = 1564 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1565 1566 if (NULL != ch_obj) { 1567 pthread_mutex_lock(&ch_obj->ch_lock); 1568 pthread_mutex_unlock(&my_obj->cam_lock); 1569 1570 memset(&payload, 0, sizeof(payload)); 1571 payload.stream_id = stream_id; 1572 payload.buf_type = buf_type; 1573 payload.buf_idx = buf_idx; 1574 payload.plane_idx = plane_idx; 1575 payload.fd = fd; 1576 payload.size = size; 1577 rc = mm_channel_fsm_fn(ch_obj, 1578 MM_CHANNEL_EVT_MAP_STREAM_BUF, 1579 (void*)&payload, 1580 NULL); 1581 } else { 1582 pthread_mutex_unlock(&my_obj->cam_lock); 1583 } 1584 1585 return rc; 1586 } 1587 1588 /*=========================================================================== 1589 * FUNCTION : mm_camera_unmap_stream_buf 1590 * 1591 * DESCRIPTION: unmapping stream buffer via domain socket to server 1592 * 1593 * PARAMETERS : 1594 * @my_obj : camera object 1595 * @ch_id : channel handle 1596 * @s_id : stream handle 1597 * @buf_type : type of buffer to be mapped. could be following values: 1598 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1599 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1600 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1601 * @buf_idx : index of buffer within the stream buffers, only valid if 1602 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1603 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1604 * @plane_idx : plane index. If all planes share the same fd, 1605 * plane_idx = -1; otherwise, plean_idx is the 1606 * index to plane (0..num_of_planes) 1607 * 1608 * RETURN : int32_t type of status 1609 * 0 -- success 1610 * -1 -- failure 1611 *==========================================================================*/ 1612 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj, 1613 uint32_t ch_id, 1614 uint32_t stream_id, 1615 uint8_t buf_type, 1616 uint32_t buf_idx, 1617 int32_t plane_idx) 1618 { 1619 int32_t rc = -1; 1620 mm_evt_paylod_unmap_stream_buf_t payload; 1621 mm_channel_t * ch_obj = 1622 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1623 1624 if (NULL != ch_obj) { 1625 pthread_mutex_lock(&ch_obj->ch_lock); 1626 pthread_mutex_unlock(&my_obj->cam_lock); 1627 1628 memset(&payload, 0, sizeof(payload)); 1629 payload.stream_id = stream_id; 1630 payload.buf_type = buf_type; 1631 payload.buf_idx = buf_idx; 1632 payload.plane_idx = plane_idx; 1633 rc = mm_channel_fsm_fn(ch_obj, 1634 MM_CHANNEL_EVT_UNMAP_STREAM_BUF, 1635 (void*)&payload, 1636 NULL); 1637 } else { 1638 pthread_mutex_unlock(&my_obj->cam_lock); 1639 } 1640 1641 return rc; 1642 } 1643 1644 /*=========================================================================== 1645 * FUNCTION : mm_camera_evt_sub 1646 * 1647 * DESCRIPTION: subscribe/unsubscribe event notify from kernel 1648 * 1649 * PARAMETERS : 1650 * @my_obj : camera object 1651 * @reg_flag : 1 -- subscribe ; 0 -- unsubscribe 1652 * 1653 * RETURN : int32_t type of status 1654 * 0 -- success 1655 * -1 -- failure 1656 *==========================================================================*/ 1657 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj, 1658 uint8_t reg_flag) 1659 { 1660 int32_t rc = 0; 1661 struct v4l2_event_subscription sub; 1662 1663 memset(&sub, 0, sizeof(sub)); 1664 sub.type = MSM_CAMERA_V4L2_EVENT_TYPE; 1665 sub.id = MSM_CAMERA_MSM_NOTIFY; 1666 if(FALSE == reg_flag) { 1667 /* unsubscribe */ 1668 rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 1669 if (rc < 0) { 1670 CDBG_ERROR("%s: unsubscribe event rc = %d", __func__, rc); 1671 return rc; 1672 } 1673 /* remove evt fd from the polling thraed when unreg the last event */ 1674 rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread, 1675 my_obj->my_hdl, 1676 mm_camera_sync_call); 1677 } else { 1678 rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 1679 if (rc < 0) { 1680 CDBG_ERROR("%s: subscribe event rc = %d", __func__, rc); 1681 return rc; 1682 } 1683 /* add evt fd to polling thread when subscribe the first event */ 1684 rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread, 1685 my_obj->my_hdl, 1686 my_obj->ctrl_fd, 1687 mm_camera_event_notify, 1688 (void*)my_obj, 1689 mm_camera_sync_call); 1690 } 1691 return rc; 1692 } 1693 1694 /*=========================================================================== 1695 * FUNCTION : mm_camera_util_wait_for_event 1696 * 1697 * DESCRIPTION: utility function to wait for certain events 1698 * 1699 * PARAMETERS : 1700 * @my_obj : camera object 1701 * @evt_mask : mask for events to be waited. Any of event in the mask would 1702 * trigger the wait to end 1703 * @status : status of the event 1704 * 1705 * RETURN : none 1706 *==========================================================================*/ 1707 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj, 1708 uint32_t evt_mask, 1709 uint32_t *status) 1710 { 1711 int rc = 0; 1712 struct timespec ts; 1713 1714 pthread_mutex_lock(&my_obj->evt_lock); 1715 while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) { 1716 clock_gettime(CLOCK_REALTIME, &ts); 1717 ts.tv_sec += WAIT_TIMEOUT; 1718 rc = pthread_cond_timedwait(&my_obj->evt_cond, &my_obj->evt_lock, &ts); 1719 if (rc == ETIMEDOUT) { 1720 ALOGE("%s pthread_cond_timedwait success\n", __func__); 1721 break; 1722 } 1723 } 1724 *status = my_obj->evt_rcvd.status; 1725 /* reset local storage for recieved event for next event */ 1726 memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t)); 1727 pthread_mutex_unlock(&my_obj->evt_lock); 1728 } 1729 1730 /*=========================================================================== 1731 * FUNCTION : mm_camera_util_sendmsg 1732 * 1733 * DESCRIPTION: utility function to send msg via domain socket 1734 * 1735 * PARAMETERS : 1736 * @my_obj : camera object 1737 * @msg : message to be sent 1738 * @buf_size : size of the message to be sent 1739 * @sendfd : >0 if any file descriptor need to be passed across process 1740 * 1741 * RETURN : int32_t type of status 1742 * 0 -- success 1743 * -1 -- failure 1744 *==========================================================================*/ 1745 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj, 1746 void *msg, 1747 size_t buf_size, 1748 int sendfd) 1749 { 1750 int32_t rc = -1; 1751 uint32_t status; 1752 1753 /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/ 1754 pthread_mutex_lock(&my_obj->msg_lock); 1755 if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) { 1756 /* wait for event that mapping/unmapping is done */ 1757 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status); 1758 if (MSM_CAMERA_STATUS_SUCCESS == status) { 1759 rc = 0; 1760 } 1761 } 1762 pthread_mutex_unlock(&my_obj->msg_lock); 1763 return rc; 1764 } 1765 1766 /*=========================================================================== 1767 * FUNCTION : mm_camera_map_buf 1768 * 1769 * DESCRIPTION: mapping camera buffer via domain socket to server 1770 * 1771 * PARAMETERS : 1772 * @my_obj : camera object 1773 * @buf_type : type of buffer to be mapped. could be following values: 1774 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1775 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1776 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1777 * @fd : file descriptor of the buffer 1778 * @size : size of the buffer 1779 * 1780 * RETURN : int32_t type of status 1781 * 0 -- success 1782 * -1 -- failure 1783 *==========================================================================*/ 1784 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj, 1785 uint8_t buf_type, 1786 int fd, 1787 size_t size) 1788 { 1789 int32_t rc = 0; 1790 cam_sock_packet_t packet; 1791 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1792 packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING; 1793 packet.payload.buf_map.type = buf_type; 1794 packet.payload.buf_map.fd = fd; 1795 packet.payload.buf_map.size = size; 1796 rc = mm_camera_util_sendmsg(my_obj, 1797 &packet, 1798 sizeof(cam_sock_packet_t), 1799 fd); 1800 pthread_mutex_unlock(&my_obj->cam_lock); 1801 return rc; 1802 } 1803 1804 /*=========================================================================== 1805 * FUNCTION : mm_camera_unmap_buf 1806 * 1807 * DESCRIPTION: unmapping camera buffer via domain socket to server 1808 * 1809 * PARAMETERS : 1810 * @my_obj : camera object 1811 * @buf_type : type of buffer to be mapped. could be following values: 1812 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1813 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1814 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1815 * 1816 * RETURN : int32_t type of status 1817 * 0 -- success 1818 * -1 -- failure 1819 *==========================================================================*/ 1820 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj, 1821 uint8_t buf_type) 1822 { 1823 int32_t rc = 0; 1824 cam_sock_packet_t packet; 1825 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1826 packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING; 1827 packet.payload.buf_unmap.type = buf_type; 1828 rc = mm_camera_util_sendmsg(my_obj, 1829 &packet, 1830 sizeof(cam_sock_packet_t), 1831 -1); 1832 pthread_mutex_unlock(&my_obj->cam_lock); 1833 return rc; 1834 } 1835 1836 /*=========================================================================== 1837 * FUNCTION : mm_camera_util_s_ctrl 1838 * 1839 * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl 1840 * 1841 * PARAMETERS : 1842 * @fd : file descritpor for sending ioctl 1843 * @id : control id 1844 * @value : value of the ioctl to be sent 1845 * 1846 * RETURN : int32_t type of status 1847 * 0 -- success 1848 * -1 -- failure 1849 *==========================================================================*/ 1850 int32_t mm_camera_util_s_ctrl(int32_t fd, uint32_t id, int32_t *value) 1851 { 1852 int rc = 0; 1853 struct v4l2_control control; 1854 1855 memset(&control, 0, sizeof(control)); 1856 control.id = id; 1857 if (value != NULL) { 1858 control.value = *value; 1859 } 1860 rc = ioctl(fd, VIDIOC_S_CTRL, &control); 1861 1862 CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = %p, rc = %d\n", 1863 __func__, fd, id, value, rc); 1864 if (value != NULL) { 1865 *value = control.value; 1866 } 1867 return (rc >= 0)? 0 : -1; 1868 } 1869 1870 /*=========================================================================== 1871 * FUNCTION : mm_camera_util_g_ctrl 1872 * 1873 * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl 1874 * 1875 * PARAMETERS : 1876 * @fd : file descritpor for sending ioctl 1877 * @id : control id 1878 * @value : value of the ioctl to be sent 1879 * 1880 * RETURN : int32_t type of status 1881 * 0 -- success 1882 * -1 -- failure 1883 *==========================================================================*/ 1884 int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value) 1885 { 1886 int rc = 0; 1887 struct v4l2_control control; 1888 1889 memset(&control, 0, sizeof(control)); 1890 control.id = id; 1891 if (value != NULL) { 1892 control.value = *value; 1893 } 1894 rc = ioctl(fd, VIDIOC_G_CTRL, &control); 1895 CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc); 1896 if (value != NULL) { 1897 *value = control.value; 1898 } 1899 return (rc >= 0)? 0 : -1; 1900 } 1901 1902 /*=========================================================================== 1903 * FUNCTION : mm_camera_channel_advanced_capture 1904 * 1905 * DESCRIPTION: sets the channel advanced capture 1906 * 1907 * PARAMETERS : 1908 * @my_obj : camera object 1909 * @ch_id : channel handle 1910 * @type : advanced capture type. 1911 * @start_flag : flag to indicate start/stop 1912 * @in_value : input configaration 1913 * 1914 * RETURN : int32_t type of status 1915 * 0 -- success 1916 * -1 -- failure 1917 *==========================================================================*/ 1918 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj, 1919 uint32_t ch_id, mm_camera_advanced_capture_t type, 1920 uint32_t trigger, void *in_value) 1921 { 1922 CDBG("%s: E type = %d",__func__, type); 1923 int32_t rc = -1; 1924 mm_channel_t * ch_obj = 1925 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1926 1927 if (NULL != ch_obj) { 1928 pthread_mutex_lock(&ch_obj->ch_lock); 1929 pthread_mutex_unlock(&my_obj->cam_lock); 1930 switch (type) { 1931 case MM_CAMERA_AF_BRACKETING: 1932 rc = mm_channel_fsm_fn(ch_obj, 1933 MM_CHANNEL_EVT_AF_BRACKETING, 1934 (void *)&trigger, 1935 NULL); 1936 break; 1937 case MM_CAMERA_AE_BRACKETING: 1938 rc = mm_channel_fsm_fn(ch_obj, 1939 MM_CHANNEL_EVT_AE_BRACKETING, 1940 (void *)&trigger, 1941 NULL); 1942 break; 1943 case MM_CAMERA_FLASH_BRACKETING: 1944 rc = mm_channel_fsm_fn(ch_obj, 1945 MM_CHANNEL_EVT_FLASH_BRACKETING, 1946 (void *)&trigger, 1947 NULL); 1948 break; 1949 case MM_CAMERA_ZOOM_1X: 1950 rc = mm_channel_fsm_fn(ch_obj, 1951 MM_CHANNEL_EVT_ZOOM_1X, 1952 (void *)&trigger, 1953 NULL); 1954 break; 1955 case MM_CAMERA_FRAME_CAPTURE: 1956 rc = mm_channel_fsm_fn(ch_obj, 1957 MM_CAMERA_EVT_CAPTURE_SETTING, 1958 (void *)in_value, 1959 NULL); 1960 break; 1961 default: 1962 break; 1963 } 1964 1965 } else { 1966 pthread_mutex_unlock(&my_obj->cam_lock); 1967 } 1968 1969 CDBG("%s: X",__func__); 1970 return rc; 1971 } 1972