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