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