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