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