1/* Copyright (c) 2012-2014, 2016, 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// To remove 31#include <cutils/properties.h> 32 33// System dependencies 34#include <pthread.h> 35#include <errno.h> 36#include <fcntl.h> 37#include <stdlib.h> 38#define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h> 39#include IOCTL_H 40 41// Camera dependencies 42#include "cam_semaphore.h" 43#include "mm_camera_dbg.h" 44#include "mm_camera_sock.h" 45#include "mm_camera_interface.h" 46#include "mm_camera.h" 47 48#define SET_PARM_BIT32(parm, parm_arr) \ 49 (parm_arr[parm/32] |= (1<<(parm%32))) 50 51#define GET_PARM_BIT32(parm, parm_arr) \ 52 ((parm_arr[parm/32]>>(parm%32))& 0x1) 53 54/* internal function declare */ 55int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj, 56 uint8_t reg_flag); 57int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj, 58 mm_camera_event_t *event); 59 60/*=========================================================================== 61 * FUNCTION : mm_camera_util_get_channel_by_handler 62 * 63 * DESCRIPTION: utility function to get a channel object from its handle 64 * 65 * PARAMETERS : 66 * @cam_obj: ptr to a camera object 67 * @handler: channel handle 68 * 69 * RETURN : ptr to a channel object. 70 * NULL if failed. 71 *==========================================================================*/ 72mm_channel_t * mm_camera_util_get_channel_by_handler( 73 mm_camera_obj_t * cam_obj, 74 uint32_t handler) 75{ 76 int i; 77 mm_channel_t *ch_obj = NULL; 78 for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) { 79 if (handler == cam_obj->ch[i].my_hdl) { 80 ch_obj = &cam_obj->ch[i]; 81 break; 82 } 83 } 84 return ch_obj; 85} 86 87/*=========================================================================== 88 * FUNCTION : mm_camera_util_chip_is_a_family 89 * 90 * DESCRIPTION: utility function to check if the host is A family chip 91 * 92 * PARAMETERS : 93 * 94 * RETURN : TRUE if A family. 95 * FALSE otherwise. 96 *==========================================================================*/ 97uint8_t mm_camera_util_chip_is_a_family(void) 98{ 99#ifdef USE_A_FAMILY 100 return TRUE; 101#else 102 return FALSE; 103#endif 104} 105 106/*=========================================================================== 107 * FUNCTION : mm_camera_dispatch_app_event 108 * 109 * DESCRIPTION: dispatch event to apps who regitster for event notify 110 * 111 * PARAMETERS : 112 * @cmd_cb: ptr to a struct storing event info 113 * @user_data: user data ptr (camera object) 114 * 115 * RETURN : none 116 *==========================================================================*/ 117static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb, 118 void* user_data) 119{ 120 int i; 121 mm_camera_event_t *event = &cmd_cb->u.evt; 122 mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data; 123 if (NULL != my_obj) { 124 mm_camera_cmd_thread_name(my_obj->evt_thread.threadName); 125 pthread_mutex_lock(&my_obj->cb_lock); 126 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 127 if(my_obj->evt.evt[i].evt_cb) { 128 my_obj->evt.evt[i].evt_cb( 129 my_obj->my_hdl, 130 event, 131 my_obj->evt.evt[i].user_data); 132 } 133 } 134 pthread_mutex_unlock(&my_obj->cb_lock); 135 } 136} 137 138/*=========================================================================== 139 * FUNCTION : mm_camera_event_notify 140 * 141 * DESCRIPTION: callback to handle event notify from kernel. This call will 142 * dequeue event from kernel. 143 * 144 * PARAMETERS : 145 * @user_data: user data ptr (camera object) 146 * 147 * RETURN : none 148 *==========================================================================*/ 149static void mm_camera_event_notify(void* user_data) 150{ 151 struct v4l2_event ev; 152 struct msm_v4l2_event_data *msm_evt = NULL; 153 int rc; 154 mm_camera_event_t evt; 155 memset(&evt, 0, sizeof(mm_camera_event_t)); 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_DAEMON_PULL_REQ: 167 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ; 168 mm_camera_enqueue_evt(my_obj, &evt); 169 break; 170 case CAM_EVENT_TYPE_MAP_UNMAP_DONE: 171 pthread_mutex_lock(&my_obj->evt_lock); 172 my_obj->evt_rcvd.server_event_type = msm_evt->command; 173 my_obj->evt_rcvd.status = msm_evt->status; 174 pthread_cond_signal(&my_obj->evt_cond); 175 pthread_mutex_unlock(&my_obj->evt_lock); 176 break; 177 case CAM_EVENT_TYPE_INT_TAKE_JPEG: 178 case CAM_EVENT_TYPE_INT_TAKE_RAW: 179 { 180 evt.server_event_type = msm_evt->command; 181 mm_camera_enqueue_evt(my_obj, &evt); 182 } 183 break; 184 case MSM_CAMERA_PRIV_SHUTDOWN: 185 { 186 LOGE("Camera Event DAEMON DIED received"); 187 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED; 188 mm_camera_enqueue_evt(my_obj, &evt); 189 } 190 break; 191 case CAM_EVENT_TYPE_CAC_DONE: 192 { 193 evt.server_event_type = CAM_EVENT_TYPE_CAC_DONE; 194 mm_camera_enqueue_evt(my_obj, &evt); 195 } 196 break; 197 default: 198 break; 199 } 200 } 201 } 202} 203 204/*=========================================================================== 205 * FUNCTION : mm_camera_enqueue_evt 206 * 207 * DESCRIPTION: enqueue received event into event queue to be processed by 208 * event thread. 209 * 210 * PARAMETERS : 211 * @my_obj : ptr to a camera object 212 * @event : event to be queued 213 * 214 * RETURN : int32_t type of status 215 * 0 -- success 216 * -1 -- failure 217 *==========================================================================*/ 218int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj, 219 mm_camera_event_t *event) 220{ 221 int32_t rc = 0; 222 mm_camera_cmdcb_t *node = NULL; 223 224 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t)); 225 if (NULL != node) { 226 memset(node, 0, sizeof(mm_camera_cmdcb_t)); 227 node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB; 228 node->u.evt = *event; 229 230 /* enqueue to evt cmd thread */ 231 cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node); 232 /* wake up evt cmd thread */ 233 cam_sem_post(&(my_obj->evt_thread.cmd_sem)); 234 } else { 235 LOGE("No memory for mm_camera_node_t"); 236 rc = -1; 237 } 238 239 return rc; 240} 241 242/*=========================================================================== 243 * FUNCTION : mm_camera_open 244 * 245 * DESCRIPTION: open a camera 246 * 247 * PARAMETERS : 248 * @my_obj : ptr to a camera object 249 * 250 * RETURN : int32_t type of status 251 * 0 -- success 252 * -1 -- failure 253 *==========================================================================*/ 254int32_t mm_camera_open(mm_camera_obj_t *my_obj) 255{ 256 char dev_name[MM_CAMERA_DEV_NAME_LEN]; 257 int32_t rc = 0; 258 int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES; 259 uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP; 260 int cam_idx = 0; 261 const char *dev_name_value = NULL; 262 int l_errno = 0; 263 264 LOGD("begin\n"); 265 266 if (NULL == my_obj) { 267 goto on_error; 268 } 269 dev_name_value = mm_camera_util_get_dev_name(my_obj->my_hdl); 270 if (NULL == dev_name_value) { 271 goto on_error; 272 } 273 snprintf(dev_name, sizeof(dev_name), "/dev/%s", 274 dev_name_value); 275 sscanf(dev_name, "/dev/video%d", &cam_idx); 276 LOGD("dev name = %s, cam_idx = %d", dev_name, cam_idx); 277 278 do{ 279 n_try--; 280 errno = 0; 281 my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK); 282 l_errno = errno; 283 LOGD("ctrl_fd = %d, errno == %d", my_obj->ctrl_fd, l_errno); 284 if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) { 285 LOGH("opened, break out while loop"); 286 break; 287 } 288 LOGE("Failed with %s error, retrying after %d milli-seconds", 289 strerror(errno), sleep_msec); 290 usleep(sleep_msec * 1000U); 291 }while (n_try > 0); 292 293 if (my_obj->ctrl_fd < 0) { 294 LOGE("cannot open control fd of '%s' (%s)\n", 295 dev_name, strerror(l_errno)); 296 if (l_errno == EBUSY) 297 rc = -EUSERS; 298 else 299 rc = -1; 300 goto on_error; 301 } 302 303 /* open domain socket*/ 304 n_try = MM_CAMERA_DEV_OPEN_TRIES; 305 do { 306 n_try--; 307 my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP); 308 l_errno = errno; 309 LOGD("ds_fd = %d, errno = %d", my_obj->ds_fd, l_errno); 310 if((my_obj->ds_fd >= 0) || (n_try <= 0 )) { 311 LOGD("opened, break out while loop"); 312 break; 313 } 314 LOGD("failed with I/O error retrying after %d milli-seconds", 315 sleep_msec); 316 usleep(sleep_msec * 1000U); 317 } while (n_try > 0); 318 319 if (my_obj->ds_fd < 0) { 320 LOGE("cannot open domain socket fd of '%s'(%s)\n", 321 dev_name, strerror(l_errno)); 322 rc = -1; 323 goto on_error; 324 } 325 pthread_mutex_init(&my_obj->msg_lock, NULL); 326 327 pthread_mutex_init(&my_obj->cb_lock, NULL); 328 pthread_mutex_init(&my_obj->evt_lock, NULL); 329 pthread_cond_init(&my_obj->evt_cond, NULL); 330 331 LOGD("Launch evt Thread in Cam Open"); 332 snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch"); 333 mm_camera_cmd_thread_launch(&my_obj->evt_thread, 334 mm_camera_dispatch_app_event, 335 (void *)my_obj); 336 337 /* launch event poll thread 338 * we will add evt fd into event poll thread upon user first register for evt */ 339 LOGD("Launch evt Poll Thread in Cam Open"); 340 snprintf(my_obj->evt_poll_thread.threadName, THREAD_NAME_SIZE, "CAM_evntPoll"); 341 mm_camera_poll_thread_launch(&my_obj->evt_poll_thread, 342 MM_CAMERA_POLL_TYPE_EVT); 343 mm_camera_evt_sub(my_obj, TRUE); 344 345 /* unlock cam_lock, we need release global intf_lock in camera_open(), 346 * in order not block operation of other Camera in dual camera use case.*/ 347 pthread_mutex_unlock(&my_obj->cam_lock); 348 LOGD("end (rc = %d)\n", rc); 349 return rc; 350 351on_error: 352 353 if (NULL == dev_name_value) { 354 LOGE("Invalid device name\n"); 355 rc = -1; 356 } 357 358 if (NULL == my_obj) { 359 LOGE("Invalid camera object\n"); 360 rc = -1; 361 } else { 362 if (my_obj->ctrl_fd >= 0) { 363 close(my_obj->ctrl_fd); 364 my_obj->ctrl_fd = -1; 365 } 366 if (my_obj->ds_fd >= 0) { 367 mm_camera_socket_close(my_obj->ds_fd); 368 my_obj->ds_fd = -1; 369 } 370 } 371 372 /* unlock cam_lock, we need release global intf_lock in camera_open(), 373 * in order not block operation of other Camera in dual camera use case.*/ 374 pthread_mutex_unlock(&my_obj->cam_lock); 375 return rc; 376} 377 378/*=========================================================================== 379 * FUNCTION : mm_camera_close 380 * 381 * DESCRIPTION: enqueue received event into event queue to be processed by 382 * event thread. 383 * 384 * PARAMETERS : 385 * @my_obj : ptr to a camera object 386 * @event : event to be queued 387 * 388 * RETURN : int32_t type of status 389 * 0 -- success 390 * -1 -- failure 391 *==========================================================================*/ 392int32_t mm_camera_close(mm_camera_obj_t *my_obj) 393{ 394 LOGD("unsubscribe evt"); 395 mm_camera_evt_sub(my_obj, FALSE); 396 397 LOGD("Close evt Poll Thread in Cam Close"); 398 mm_camera_poll_thread_release(&my_obj->evt_poll_thread); 399 400 LOGD("Close evt cmd Thread in Cam Close"); 401 mm_camera_cmd_thread_release(&my_obj->evt_thread); 402 403 if(my_obj->ctrl_fd >= 0) { 404 close(my_obj->ctrl_fd); 405 my_obj->ctrl_fd = -1; 406 } 407 if(my_obj->ds_fd >= 0) { 408 mm_camera_socket_close(my_obj->ds_fd); 409 my_obj->ds_fd = -1; 410 } 411 pthread_mutex_destroy(&my_obj->msg_lock); 412 413 pthread_mutex_destroy(&my_obj->cb_lock); 414 pthread_mutex_destroy(&my_obj->evt_lock); 415 pthread_cond_destroy(&my_obj->evt_cond); 416 417 pthread_mutex_unlock(&my_obj->cam_lock); 418 return 0; 419} 420 421/*=========================================================================== 422 * FUNCTION : mm_camera_register_event_notify_internal 423 * 424 * DESCRIPTION: internal implementation for registering callback for event notify. 425 * 426 * PARAMETERS : 427 * @my_obj : ptr to a camera object 428 * @evt_cb : callback to be registered to handle event notify 429 * @user_data: user data ptr 430 * 431 * RETURN : int32_t type of status 432 * 0 -- success 433 * -1 -- failure 434 *==========================================================================*/ 435int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj, 436 mm_camera_event_notify_t evt_cb, 437 void * user_data) 438{ 439 int i; 440 int rc = -1; 441 mm_camera_evt_obj_t *evt_array = NULL; 442 443 pthread_mutex_lock(&my_obj->cb_lock); 444 evt_array = &my_obj->evt; 445 if(evt_cb) { 446 /* this is reg case */ 447 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 448 if(evt_array->evt[i].user_data == NULL) { 449 evt_array->evt[i].evt_cb = evt_cb; 450 evt_array->evt[i].user_data = user_data; 451 evt_array->reg_count++; 452 rc = 0; 453 break; 454 } 455 } 456 } else { 457 /* this is unreg case */ 458 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) { 459 if(evt_array->evt[i].user_data == user_data) { 460 evt_array->evt[i].evt_cb = NULL; 461 evt_array->evt[i].user_data = NULL; 462 evt_array->reg_count--; 463 rc = 0; 464 break; 465 } 466 } 467 } 468 469 pthread_mutex_unlock(&my_obj->cb_lock); 470 return rc; 471} 472 473/*=========================================================================== 474 * FUNCTION : mm_camera_register_event_notify 475 * 476 * DESCRIPTION: registering a callback for event notify. 477 * 478 * PARAMETERS : 479 * @my_obj : ptr to a camera object 480 * @evt_cb : callback to be registered to handle event notify 481 * @user_data: user data ptr 482 * 483 * RETURN : int32_t type of status 484 * 0 -- success 485 * -1 -- failure 486 *==========================================================================*/ 487int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj, 488 mm_camera_event_notify_t evt_cb, 489 void * user_data) 490{ 491 int rc = -1; 492 rc = mm_camera_register_event_notify_internal(my_obj, 493 evt_cb, 494 user_data); 495 pthread_mutex_unlock(&my_obj->cam_lock); 496 return rc; 497} 498 499/*=========================================================================== 500 * FUNCTION : mm_camera_qbuf 501 * 502 * DESCRIPTION: enqueue buffer back to kernel 503 * 504 * PARAMETERS : 505 * @my_obj : camera object 506 * @ch_id : channel handle 507 * @buf : buf ptr to be enqueued 508 * 509 * RETURN : int32_t type of status 510 * 0 -- success 511 * -1 -- failure 512 *==========================================================================*/ 513int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj, 514 uint32_t ch_id, 515 mm_camera_buf_def_t *buf) 516{ 517 int rc = -1; 518 mm_channel_t * ch_obj = NULL; 519 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id); 520 521 pthread_mutex_unlock(&my_obj->cam_lock); 522 523 /* we always assume qbuf will be done before channel/stream is fully stopped 524 * because qbuf is done within dataCB context 525 * in order to avoid deadlock, we are not locking ch_lock for qbuf */ 526 if (NULL != ch_obj) { 527 rc = mm_channel_qbuf(ch_obj, buf); 528 } 529 530 return rc; 531} 532 533/*=========================================================================== 534 * FUNCTION : mm_camera_get_queued_buf_count 535 * 536 * DESCRIPTION: return queued buffer count 537 * 538 * PARAMETERS : 539 * @my_obj : camera object 540 * @ch_id : channel handle 541 * @stream_id : stream id 542 * 543 * RETURN : queued buffer count 544 *==========================================================================*/ 545int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj, 546 uint32_t ch_id, uint32_t stream_id) 547{ 548 int rc = -1; 549 mm_channel_t * ch_obj = NULL; 550 uint32_t payload; 551 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id); 552 payload = stream_id; 553 554 if (NULL != ch_obj) { 555 pthread_mutex_lock(&ch_obj->ch_lock); 556 pthread_mutex_unlock(&my_obj->cam_lock); 557 rc = mm_channel_fsm_fn(ch_obj, 558 MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT, 559 (void *)&payload, 560 NULL); 561 } else { 562 pthread_mutex_unlock(&my_obj->cam_lock); 563 } 564 565 return rc; 566} 567 568/*=========================================================================== 569 * FUNCTION : mm_camera_query_capability 570 * 571 * DESCRIPTION: query camera capability 572 * 573 * PARAMETERS : 574 * @my_obj: camera object 575 * 576 * RETURN : int32_t type of status 577 * 0 -- success 578 * -1 -- failure 579 *==========================================================================*/ 580int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj) 581{ 582 int32_t rc = 0; 583 struct v4l2_capability cap; 584 585 /* get camera capabilities */ 586 memset(&cap, 0, sizeof(cap)); 587 rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap); 588 if (rc != 0) { 589 LOGE("cannot get camera capabilities, rc = %d, errno %d", 590 rc, errno); 591 } 592 593 pthread_mutex_unlock(&my_obj->cam_lock); 594 return rc; 595 596} 597 598/*=========================================================================== 599 * FUNCTION : mm_camera_set_parms 600 * 601 * DESCRIPTION: set parameters per camera 602 * 603 * PARAMETERS : 604 * @my_obj : camera object 605 * @parms : ptr to a param struct to be set to server 606 * 607 * RETURN : int32_t type of status 608 * 0 -- success 609 * -1 -- failure 610 * NOTE : Assume the parms struct buf is already mapped to server via 611 * domain socket. Corresponding fields of parameters to be set 612 * are already filled in by upper layer caller. 613 *==========================================================================*/ 614int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj, 615 parm_buffer_t *parms) 616{ 617 int32_t rc = -1; 618 int32_t value = 0; 619 if (parms != NULL) { 620 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value); 621 } 622 pthread_mutex_unlock(&my_obj->cam_lock); 623 return rc; 624} 625 626/*=========================================================================== 627 * FUNCTION : mm_camera_get_parms 628 * 629 * DESCRIPTION: get parameters per camera 630 * 631 * PARAMETERS : 632 * @my_obj : camera object 633 * @parms : ptr to a param struct to be get from server 634 * 635 * RETURN : int32_t type of status 636 * 0 -- success 637 * -1 -- failure 638 * NOTE : Assume the parms struct buf is already mapped to server via 639 * domain socket. Parameters to be get from server are already 640 * filled in by upper layer caller. After this call, corresponding 641 * fields of requested parameters will be filled in by server with 642 * detailed information. 643 *==========================================================================*/ 644int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj, 645 parm_buffer_t *parms) 646{ 647 int32_t rc = -1; 648 int32_t value = 0; 649 if (parms != NULL) { 650 rc = mm_camera_util_g_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value); 651 } 652 pthread_mutex_unlock(&my_obj->cam_lock); 653 return rc; 654} 655 656/*=========================================================================== 657 * FUNCTION : mm_camera_do_auto_focus 658 * 659 * DESCRIPTION: performing auto focus 660 * 661 * PARAMETERS : 662 * @camera_handle: camera handle 663 * 664 * RETURN : int32_t type of status 665 * 0 -- success 666 * -1 -- failure 667 * NOTE : if this call success, we will always assume there will 668 * be an auto_focus event following up. 669 *==========================================================================*/ 670int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj) 671{ 672 int32_t rc = -1; 673 int32_t value = 0; 674 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value); 675 pthread_mutex_unlock(&my_obj->cam_lock); 676 return rc; 677} 678 679/*=========================================================================== 680 * FUNCTION : mm_camera_cancel_auto_focus 681 * 682 * DESCRIPTION: cancel auto focus 683 * 684 * PARAMETERS : 685 * @camera_handle: camera handle 686 * 687 * RETURN : int32_t type of status 688 * 0 -- success 689 * -1 -- failure 690 *==========================================================================*/ 691int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj) 692{ 693 int32_t rc = -1; 694 int32_t value = 0; 695 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value); 696 pthread_mutex_unlock(&my_obj->cam_lock); 697 return rc; 698} 699 700/*=========================================================================== 701 * FUNCTION : mm_camera_prepare_snapshot 702 * 703 * DESCRIPTION: prepare hardware for snapshot 704 * 705 * PARAMETERS : 706 * @my_obj : camera object 707 * @do_af_flag : flag indicating if AF is needed 708 * 709 * RETURN : int32_t type of status 710 * 0 -- success 711 * -1 -- failure 712 *==========================================================================*/ 713int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj, 714 int32_t do_af_flag) 715{ 716 int32_t rc = -1; 717 int32_t value = do_af_flag; 718 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value); 719 pthread_mutex_unlock(&my_obj->cam_lock); 720 return rc; 721} 722 723/*=========================================================================== 724 * FUNCTION : mm_camera_start_zsl_snapshot 725 * 726 * DESCRIPTION: start zsl snapshot 727 * 728 * PARAMETERS : 729 * @my_obj : camera object 730 * 731 * RETURN : int32_t type of status 732 * 0 -- success 733 * -1 -- failure 734 *==========================================================================*/ 735int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj) 736{ 737 int32_t rc = -1; 738 int32_t value = 0; 739 740 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, 741 CAM_PRIV_START_ZSL_SNAPSHOT, &value); 742 return rc; 743} 744 745/*=========================================================================== 746 * FUNCTION : mm_camera_stop_zsl_snapshot 747 * 748 * DESCRIPTION: stop zsl capture 749 * 750 * PARAMETERS : 751 * @my_obj : camera object 752 * 753 * RETURN : int32_t type of status 754 * 0 -- success 755 * -1 -- failure 756 *==========================================================================*/ 757int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj) 758{ 759 int32_t rc = -1; 760 int32_t value; 761 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, 762 CAM_PRIV_STOP_ZSL_SNAPSHOT, &value); 763 return rc; 764} 765 766/*=========================================================================== 767 * FUNCTION : mm_camera_flush 768 * 769 * DESCRIPTION: flush the current camera state and buffers 770 * 771 * PARAMETERS : 772 * @my_obj : camera object 773 * 774 * RETURN : int32_t type of status 775 * 0 -- success 776 * -1 -- failure 777 *==========================================================================*/ 778int32_t mm_camera_flush(mm_camera_obj_t *my_obj) 779{ 780 int32_t rc = -1; 781 int32_t value; 782 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, 783 CAM_PRIV_FLUSH, &value); 784 pthread_mutex_unlock(&my_obj->cam_lock); 785 return rc; 786} 787 788/*=========================================================================== 789 * FUNCTION : mm_camera_add_channel 790 * 791 * DESCRIPTION: add a channel 792 * 793 * PARAMETERS : 794 * @my_obj : camera object 795 * @attr : bundle attribute of the channel if needed 796 * @channel_cb : callback function for bundle data notify 797 * @userdata : user data ptr 798 * 799 * RETURN : uint32_t type of channel handle 800 * 0 -- invalid channel handle, meaning the op failed 801 * >0 -- successfully added a channel with a valid handle 802 * NOTE : if no bundle data notify is needed, meaning each stream in the 803 * channel will have its own stream data notify callback, then 804 * attr, channel_cb, and userdata can be NULL. In this case, 805 * no matching logic will be performed in channel for the bundling. 806 *==========================================================================*/ 807uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj, 808 mm_camera_channel_attr_t *attr, 809 mm_camera_buf_notify_t channel_cb, 810 void *userdata) 811{ 812 mm_channel_t *ch_obj = NULL; 813 uint8_t ch_idx = 0; 814 uint32_t ch_hdl = 0; 815 816 for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) { 817 if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) { 818 ch_obj = &my_obj->ch[ch_idx]; 819 break; 820 } 821 } 822 823 if (NULL != ch_obj) { 824 /* initialize channel obj */ 825 memset(ch_obj, 0, sizeof(mm_channel_t)); 826 ch_hdl = mm_camera_util_generate_handler(ch_idx); 827 ch_obj->my_hdl = ch_hdl; 828 ch_obj->state = MM_CHANNEL_STATE_STOPPED; 829 ch_obj->cam_obj = my_obj; 830 pthread_mutex_init(&ch_obj->ch_lock, NULL); 831 ch_obj->sessionid = my_obj->sessionid; 832 mm_channel_init(ch_obj, attr, channel_cb, userdata); 833 } 834 835 pthread_mutex_unlock(&my_obj->cam_lock); 836 837 return ch_hdl; 838} 839 840/*=========================================================================== 841 * FUNCTION : mm_camera_del_channel 842 * 843 * DESCRIPTION: delete a channel by its handle 844 * 845 * PARAMETERS : 846 * @my_obj : camera object 847 * @ch_id : channel handle 848 * 849 * RETURN : int32_t type of status 850 * 0 -- success 851 * -1 -- failure 852 * NOTE : all streams in the channel should be stopped already before 853 * this channel can be deleted. 854 *==========================================================================*/ 855int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj, 856 uint32_t ch_id) 857{ 858 int32_t rc = -1; 859 mm_channel_t * ch_obj = 860 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 861 862 if (NULL != ch_obj) { 863 pthread_mutex_lock(&ch_obj->ch_lock); 864 pthread_mutex_unlock(&my_obj->cam_lock); 865 866 rc = mm_channel_fsm_fn(ch_obj, 867 MM_CHANNEL_EVT_DELETE, 868 NULL, 869 NULL); 870 871 pthread_mutex_destroy(&ch_obj->ch_lock); 872 memset(ch_obj, 0, sizeof(mm_channel_t)); 873 } else { 874 pthread_mutex_unlock(&my_obj->cam_lock); 875 } 876 return rc; 877} 878 879/*=========================================================================== 880 * FUNCTION : mm_camera_get_bundle_info 881 * 882 * DESCRIPTION: query bundle info of the channel 883 * 884 * PARAMETERS : 885 * @my_obj : camera object 886 * @ch_id : channel handle 887 * @bundle_info : bundle info to be filled in 888 * 889 * RETURN : int32_t type of status 890 * 0 -- success 891 * -1 -- failure 892 * NOTE : all streams in the channel should be stopped already before 893 * this channel can be deleted. 894 *==========================================================================*/ 895int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj, 896 uint32_t ch_id, 897 cam_bundle_config_t *bundle_info) 898{ 899 int32_t rc = -1; 900 mm_channel_t * ch_obj = 901 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 902 903 if (NULL != ch_obj) { 904 pthread_mutex_lock(&ch_obj->ch_lock); 905 pthread_mutex_unlock(&my_obj->cam_lock); 906 907 rc = mm_channel_fsm_fn(ch_obj, 908 MM_CHANNEL_EVT_GET_BUNDLE_INFO, 909 (void *)bundle_info, 910 NULL); 911 } else { 912 pthread_mutex_unlock(&my_obj->cam_lock); 913 } 914 return rc; 915} 916 917/*=========================================================================== 918 * FUNCTION : mm_camera_link_stream 919 * 920 * DESCRIPTION: link a stream into a channel 921 * 922 * PARAMETERS : 923 * @my_obj : camera object 924 * @ch_id : channel handle 925 * @stream_id : stream that will be linked 926 * @linked_ch_id : channel in which the stream will be linked 927 * 928 * RETURN : uint32_t type of stream handle 929 * 0 -- invalid stream handle, meaning the op failed 930 * >0 -- successfully linked a stream with a valid handle 931 *==========================================================================*/ 932uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj, 933 uint32_t ch_id, 934 uint32_t stream_id, 935 uint32_t linked_ch_id) 936{ 937 uint32_t s_hdl = 0; 938 mm_channel_t * ch_obj = 939 mm_camera_util_get_channel_by_handler(my_obj, linked_ch_id); 940 mm_channel_t * owner_obj = 941 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 942 943 if ((NULL != ch_obj) && (NULL != owner_obj)) { 944 pthread_mutex_lock(&ch_obj->ch_lock); 945 pthread_mutex_unlock(&my_obj->cam_lock); 946 947 mm_camera_stream_link_t stream_link; 948 memset(&stream_link, 0, sizeof(mm_camera_stream_link_t)); 949 stream_link.ch = owner_obj; 950 stream_link.stream_id = stream_id; 951 mm_channel_fsm_fn(ch_obj, 952 MM_CHANNEL_EVT_LINK_STREAM, 953 (void*)&stream_link, 954 (void*)&s_hdl); 955 } else { 956 pthread_mutex_unlock(&my_obj->cam_lock); 957 } 958 959 return s_hdl; 960} 961 962/*=========================================================================== 963 * FUNCTION : mm_camera_add_stream 964 * 965 * DESCRIPTION: add a stream into a channel 966 * 967 * PARAMETERS : 968 * @my_obj : camera object 969 * @ch_id : channel handle 970 * 971 * RETURN : uint32_t type of stream handle 972 * 0 -- invalid stream handle, meaning the op failed 973 * >0 -- successfully added a stream with a valid handle 974 *==========================================================================*/ 975uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj, 976 uint32_t ch_id) 977{ 978 uint32_t s_hdl = 0; 979 mm_channel_t * ch_obj = 980 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 981 982 if (NULL != ch_obj) { 983 pthread_mutex_lock(&ch_obj->ch_lock); 984 pthread_mutex_unlock(&my_obj->cam_lock); 985 986 mm_channel_fsm_fn(ch_obj, 987 MM_CHANNEL_EVT_ADD_STREAM, 988 NULL, 989 (void *)&s_hdl); 990 } else { 991 pthread_mutex_unlock(&my_obj->cam_lock); 992 } 993 994 return s_hdl; 995} 996 997/*=========================================================================== 998 * FUNCTION : mm_camera_del_stream 999 * 1000 * DESCRIPTION: delete a stream by its handle 1001 * 1002 * PARAMETERS : 1003 * @my_obj : camera object 1004 * @ch_id : channel handle 1005 * @stream_id : stream handle 1006 * 1007 * RETURN : int32_t type of status 1008 * 0 -- success 1009 * -1 -- failure 1010 * NOTE : stream should be stopped already before it can be deleted. 1011 *==========================================================================*/ 1012int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj, 1013 uint32_t ch_id, 1014 uint32_t stream_id) 1015{ 1016 int32_t rc = -1; 1017 mm_channel_t * ch_obj = 1018 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1019 1020 if (NULL != ch_obj) { 1021 pthread_mutex_lock(&ch_obj->ch_lock); 1022 pthread_mutex_unlock(&my_obj->cam_lock); 1023 1024 rc = mm_channel_fsm_fn(ch_obj, 1025 MM_CHANNEL_EVT_DEL_STREAM, 1026 (void *)&stream_id, 1027 NULL); 1028 } else { 1029 pthread_mutex_unlock(&my_obj->cam_lock); 1030 } 1031 1032 return rc; 1033} 1034 1035/*=========================================================================== 1036 * FUNCTION : mm_camera_start_zsl_snapshot_ch 1037 * 1038 * DESCRIPTION: starts zsl snapshot for specific channel 1039 * 1040 * PARAMETERS : 1041 * @my_obj : camera object 1042 * @ch_id : channel handle 1043 * 1044 * RETURN : int32_t type of status 1045 * 0 -- success 1046 * -1 -- failure 1047 *==========================================================================*/ 1048int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj, 1049 uint32_t ch_id) 1050{ 1051 int32_t rc = -1; 1052 mm_channel_t * ch_obj = 1053 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1054 1055 if (NULL != ch_obj) { 1056 pthread_mutex_lock(&ch_obj->ch_lock); 1057 pthread_mutex_unlock(&my_obj->cam_lock); 1058 1059 rc = mm_channel_fsm_fn(ch_obj, 1060 MM_CHANNEL_EVT_START_ZSL_SNAPSHOT, 1061 NULL, 1062 NULL); 1063 } else { 1064 pthread_mutex_unlock(&my_obj->cam_lock); 1065 } 1066 1067 return rc; 1068} 1069 1070/*=========================================================================== 1071 * FUNCTION : mm_camera_stop_zsl_snapshot_ch 1072 * 1073 * DESCRIPTION: stops zsl snapshot for specific channel 1074 * 1075 * PARAMETERS : 1076 * @my_obj : camera object 1077 * @ch_id : channel handle 1078 * 1079 * RETURN : int32_t type of status 1080 * 0 -- success 1081 * -1 -- failure 1082 *==========================================================================*/ 1083int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj, 1084 uint32_t ch_id) 1085{ 1086 int32_t rc = -1; 1087 mm_channel_t * ch_obj = 1088 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1089 1090 if (NULL != ch_obj) { 1091 pthread_mutex_lock(&ch_obj->ch_lock); 1092 pthread_mutex_unlock(&my_obj->cam_lock); 1093 1094 rc = mm_channel_fsm_fn(ch_obj, 1095 MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT, 1096 NULL, 1097 NULL); 1098 } else { 1099 pthread_mutex_unlock(&my_obj->cam_lock); 1100 } 1101 1102 return rc; 1103} 1104 1105/*=========================================================================== 1106 * FUNCTION : mm_camera_config_stream 1107 * 1108 * DESCRIPTION: configure a stream 1109 * 1110 * PARAMETERS : 1111 * @my_obj : camera object 1112 * @ch_id : channel handle 1113 * @stream_id : stream handle 1114 * @config : stream configuration 1115 * 1116 * RETURN : int32_t type of status 1117 * 0 -- success 1118 * -1 -- failure 1119 *==========================================================================*/ 1120int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj, 1121 uint32_t ch_id, 1122 uint32_t stream_id, 1123 mm_camera_stream_config_t *config) 1124{ 1125 int32_t rc = -1; 1126 mm_channel_t * ch_obj = 1127 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1128 mm_evt_paylod_config_stream_t payload; 1129 1130 if (NULL != ch_obj) { 1131 pthread_mutex_lock(&ch_obj->ch_lock); 1132 pthread_mutex_unlock(&my_obj->cam_lock); 1133 1134 memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t)); 1135 payload.stream_id = stream_id; 1136 payload.config = config; 1137 rc = mm_channel_fsm_fn(ch_obj, 1138 MM_CHANNEL_EVT_CONFIG_STREAM, 1139 (void *)&payload, 1140 NULL); 1141 } else { 1142 pthread_mutex_unlock(&my_obj->cam_lock); 1143 } 1144 1145 return rc; 1146} 1147 1148/*=========================================================================== 1149 * FUNCTION : mm_camera_start_channel 1150 * 1151 * DESCRIPTION: start a channel, which will start all streams in the channel 1152 * 1153 * PARAMETERS : 1154 * @my_obj : camera object 1155 * @ch_id : channel handle 1156 * 1157 * RETURN : int32_t type of status 1158 * 0 -- success 1159 * -1 -- failure 1160 *==========================================================================*/ 1161int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj, uint32_t ch_id) 1162{ 1163 int32_t rc = -1; 1164 mm_channel_t * ch_obj = 1165 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1166 1167 if (NULL != ch_obj) { 1168 pthread_mutex_lock(&ch_obj->ch_lock); 1169 pthread_mutex_unlock(&my_obj->cam_lock); 1170 1171 rc = mm_channel_fsm_fn(ch_obj, 1172 MM_CHANNEL_EVT_START, 1173 NULL, 1174 NULL); 1175 } else { 1176 pthread_mutex_unlock(&my_obj->cam_lock); 1177 } 1178 1179 return rc; 1180} 1181 1182/*=========================================================================== 1183 * FUNCTION : mm_camera_stop_channel 1184 * 1185 * DESCRIPTION: stop a channel, which will stop all streams in the channel 1186 * 1187 * PARAMETERS : 1188 * @my_obj : camera object 1189 * @ch_id : channel handle 1190 * 1191 * RETURN : int32_t type of status 1192 * 0 -- success 1193 * -1 -- failure 1194 *==========================================================================*/ 1195int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj, 1196 uint32_t ch_id) 1197{ 1198 int32_t rc = 0; 1199 mm_channel_t * ch_obj = 1200 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1201 1202 if (NULL != ch_obj) { 1203 pthread_mutex_lock(&ch_obj->ch_lock); 1204 pthread_mutex_unlock(&my_obj->cam_lock); 1205 1206 rc = mm_channel_fsm_fn(ch_obj, 1207 MM_CHANNEL_EVT_STOP, 1208 NULL, 1209 NULL); 1210 } else { 1211 pthread_mutex_unlock(&my_obj->cam_lock); 1212 } 1213 return rc; 1214} 1215 1216/*=========================================================================== 1217 * FUNCTION : mm_camera_request_super_buf 1218 * 1219 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched 1220 * frames from superbuf queue 1221 * 1222 * PARAMETERS : 1223 * @my_obj : camera object 1224 * @ch_id : channel handle 1225 * @num_buf_requested : number of matched frames needed 1226 * 1227 * RETURN : int32_t type of status 1228 * 0 -- success 1229 * -1 -- failure 1230 *==========================================================================*/ 1231int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj, 1232 uint32_t ch_id, mm_camera_req_buf_t *buf) 1233{ 1234 int32_t rc = -1; 1235 mm_channel_t * ch_obj = 1236 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1237 1238 if ((NULL != ch_obj) && (buf != NULL)) { 1239 pthread_mutex_lock(&ch_obj->ch_lock); 1240 pthread_mutex_unlock(&my_obj->cam_lock); 1241 1242 rc = mm_channel_fsm_fn(ch_obj, MM_CHANNEL_EVT_REQUEST_SUPER_BUF, 1243 (void *)buf, NULL); 1244 } else { 1245 pthread_mutex_unlock(&my_obj->cam_lock); 1246 } 1247 1248 return rc; 1249} 1250 1251/*=========================================================================== 1252 * FUNCTION : mm_camera_cancel_super_buf_request 1253 * 1254 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount 1255 * of matched frames from superbuf queue 1256 * 1257 * PARAMETERS : 1258 * @my_obj : camera object 1259 * @ch_id : channel handle 1260 * 1261 * RETURN : int32_t type of status 1262 * 0 -- success 1263 * -1 -- failure 1264 *==========================================================================*/ 1265int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id) 1266{ 1267 int32_t rc = -1; 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 rc = mm_channel_fsm_fn(ch_obj, 1276 MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF, 1277 NULL, 1278 NULL); 1279 } else { 1280 pthread_mutex_unlock(&my_obj->cam_lock); 1281 } 1282 1283 return rc; 1284} 1285 1286/*=========================================================================== 1287 * FUNCTION : mm_camera_flush_super_buf_queue 1288 * 1289 * DESCRIPTION: flush out all frames in the superbuf queue 1290 * 1291 * PARAMETERS : 1292 * @my_obj : camera object 1293 * @ch_id : channel handle 1294 * 1295 * RETURN : int32_t type of status 1296 * 0 -- success 1297 * -1 -- failure 1298 *==========================================================================*/ 1299int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id, 1300 uint32_t frame_idx) 1301{ 1302 int32_t rc = -1; 1303 mm_channel_t * ch_obj = 1304 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1305 1306 if (NULL != ch_obj) { 1307 pthread_mutex_lock(&ch_obj->ch_lock); 1308 pthread_mutex_unlock(&my_obj->cam_lock); 1309 1310 rc = mm_channel_fsm_fn(ch_obj, 1311 MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE, 1312 (void *)&frame_idx, 1313 NULL); 1314 } else { 1315 pthread_mutex_unlock(&my_obj->cam_lock); 1316 } 1317 1318 return rc; 1319} 1320 1321/*=========================================================================== 1322 * FUNCTION : mm_camera_config_channel_notify 1323 * 1324 * DESCRIPTION: configures the channel notification mode 1325 * 1326 * PARAMETERS : 1327 * @my_obj : camera object 1328 * @ch_id : channel handle 1329 * @notify_mode : notification mode 1330 * 1331 * RETURN : int32_t type of status 1332 * 0 -- success 1333 * -1 -- failure 1334 *==========================================================================*/ 1335int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj, 1336 uint32_t ch_id, 1337 mm_camera_super_buf_notify_mode_t notify_mode) 1338{ 1339 int32_t rc = -1; 1340 mm_channel_t * ch_obj = 1341 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1342 1343 if (NULL != ch_obj) { 1344 pthread_mutex_lock(&ch_obj->ch_lock); 1345 pthread_mutex_unlock(&my_obj->cam_lock); 1346 1347 rc = mm_channel_fsm_fn(ch_obj, 1348 MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE, 1349 (void *)¬ify_mode, 1350 NULL); 1351 } else { 1352 pthread_mutex_unlock(&my_obj->cam_lock); 1353 } 1354 1355 return rc; 1356} 1357 1358/*=========================================================================== 1359 * FUNCTION : mm_camera_set_stream_parms 1360 * 1361 * DESCRIPTION: set parameters per stream 1362 * 1363 * PARAMETERS : 1364 * @my_obj : camera object 1365 * @ch_id : channel handle 1366 * @s_id : stream handle 1367 * @parms : ptr to a param struct to be set to server 1368 * 1369 * RETURN : int32_t type of status 1370 * 0 -- success 1371 * -1 -- failure 1372 * NOTE : Assume the parms struct buf is already mapped to server via 1373 * domain socket. Corresponding fields of parameters to be set 1374 * are already filled in by upper layer caller. 1375 *==========================================================================*/ 1376int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj, 1377 uint32_t ch_id, 1378 uint32_t s_id, 1379 cam_stream_parm_buffer_t *parms) 1380{ 1381 int32_t rc = -1; 1382 mm_evt_paylod_set_get_stream_parms_t payload; 1383 mm_channel_t * ch_obj = 1384 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1385 1386 if (NULL != ch_obj) { 1387 pthread_mutex_lock(&ch_obj->ch_lock); 1388 pthread_mutex_unlock(&my_obj->cam_lock); 1389 1390 memset(&payload, 0, sizeof(payload)); 1391 payload.stream_id = s_id; 1392 payload.parms = parms; 1393 1394 rc = mm_channel_fsm_fn(ch_obj, 1395 MM_CHANNEL_EVT_SET_STREAM_PARM, 1396 (void *)&payload, 1397 NULL); 1398 } else { 1399 pthread_mutex_unlock(&my_obj->cam_lock); 1400 } 1401 1402 return rc; 1403} 1404 1405/*=========================================================================== 1406 * FUNCTION : mm_camera_get_stream_parms 1407 * 1408 * DESCRIPTION: get parameters per stream 1409 * 1410 * PARAMETERS : 1411 * @my_obj : camera object 1412 * @ch_id : channel handle 1413 * @s_id : stream handle 1414 * @parms : ptr to a param struct to be get from server 1415 * 1416 * RETURN : int32_t type of status 1417 * 0 -- success 1418 * -1 -- failure 1419 * NOTE : Assume the parms struct buf is already mapped to server via 1420 * domain socket. Parameters to be get from server are already 1421 * filled in by upper layer caller. After this call, corresponding 1422 * fields of requested parameters will be filled in by server with 1423 * detailed information. 1424 *==========================================================================*/ 1425int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj, 1426 uint32_t ch_id, 1427 uint32_t s_id, 1428 cam_stream_parm_buffer_t *parms) 1429{ 1430 int32_t rc = -1; 1431 mm_evt_paylod_set_get_stream_parms_t payload; 1432 mm_channel_t * ch_obj = 1433 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1434 1435 if (NULL != ch_obj) { 1436 pthread_mutex_lock(&ch_obj->ch_lock); 1437 pthread_mutex_unlock(&my_obj->cam_lock); 1438 1439 memset(&payload, 0, sizeof(payload)); 1440 payload.stream_id = s_id; 1441 payload.parms = parms; 1442 1443 rc = mm_channel_fsm_fn(ch_obj, 1444 MM_CHANNEL_EVT_GET_STREAM_PARM, 1445 (void *)&payload, 1446 NULL); 1447 } else { 1448 pthread_mutex_unlock(&my_obj->cam_lock); 1449 } 1450 1451 return rc; 1452} 1453 1454/*=========================================================================== 1455 * FUNCTION : mm_camera_do_stream_action 1456 * 1457 * DESCRIPTION: request server to perform stream based action. Maybe removed later 1458 * if the functionality is included in mm_camera_set_parms 1459 * 1460 * PARAMETERS : 1461 * @my_obj : camera object 1462 * @ch_id : channel handle 1463 * @s_id : stream handle 1464 * @actions : ptr to an action struct buf to be performed by server 1465 * 1466 * RETURN : int32_t type of status 1467 * 0 -- success 1468 * -1 -- failure 1469 * NOTE : Assume the action struct buf is already mapped to server via 1470 * domain socket. Actions to be performed by server are already 1471 * filled in by upper layer caller. 1472 *==========================================================================*/ 1473int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj, 1474 uint32_t ch_id, 1475 uint32_t stream_id, 1476 void *actions) 1477{ 1478 int32_t rc = -1; 1479 mm_evt_paylod_do_stream_action_t payload; 1480 mm_channel_t * ch_obj = 1481 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1482 1483 if (NULL != ch_obj) { 1484 pthread_mutex_lock(&ch_obj->ch_lock); 1485 pthread_mutex_unlock(&my_obj->cam_lock); 1486 1487 memset(&payload, 0, sizeof(payload)); 1488 payload.stream_id = stream_id; 1489 payload.actions = actions; 1490 1491 rc = mm_channel_fsm_fn(ch_obj, 1492 MM_CHANNEL_EVT_DO_STREAM_ACTION, 1493 (void*)&payload, 1494 NULL); 1495 } else { 1496 pthread_mutex_unlock(&my_obj->cam_lock); 1497 } 1498 1499 return rc; 1500} 1501 1502/*=========================================================================== 1503 * FUNCTION : mm_camera_map_stream_buf 1504 * 1505 * DESCRIPTION: mapping stream buffer via domain socket to server 1506 * 1507 * PARAMETERS : 1508 * @my_obj : camera object 1509 * @ch_id : channel handle 1510 * @s_id : stream handle 1511 * @buf_type : type of buffer to be mapped. could be following values: 1512 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1513 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1514 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1515 * @buf_idx : index of buffer within the stream buffers, only valid if 1516 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1517 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1518 * @plane_idx : plane index. If all planes share the same fd, 1519 * plane_idx = -1; otherwise, plean_idx is the 1520 * index to plane (0..num_of_planes) 1521 * @fd : file descriptor of the buffer 1522 * @size : size of the buffer 1523 * 1524 * RETURN : int32_t type of status 1525 * 0 -- success 1526 * -1 -- failure 1527 *==========================================================================*/ 1528int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj, 1529 uint32_t ch_id, 1530 uint32_t stream_id, 1531 uint8_t buf_type, 1532 uint32_t buf_idx, 1533 int32_t plane_idx, 1534 int fd, 1535 size_t size) 1536{ 1537 int32_t rc = -1; 1538 cam_buf_map_type payload; 1539 mm_channel_t * ch_obj = 1540 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1541 1542 if (NULL != ch_obj) { 1543 pthread_mutex_lock(&ch_obj->ch_lock); 1544 pthread_mutex_unlock(&my_obj->cam_lock); 1545 1546 memset(&payload, 0, sizeof(payload)); 1547 payload.stream_id = stream_id; 1548 payload.type = buf_type; 1549 payload.frame_idx = buf_idx; 1550 payload.plane_idx = plane_idx; 1551 payload.fd = fd; 1552 payload.size = size; 1553 rc = mm_channel_fsm_fn(ch_obj, 1554 MM_CHANNEL_EVT_MAP_STREAM_BUF, 1555 (void*)&payload, 1556 NULL); 1557 } else { 1558 pthread_mutex_unlock(&my_obj->cam_lock); 1559 } 1560 1561 return rc; 1562} 1563 1564/*=========================================================================== 1565 * FUNCTION : mm_camera_map_stream_bufs 1566 * 1567 * DESCRIPTION: mapping stream buffers via domain socket to server 1568 * 1569 * PARAMETERS : 1570 * @my_obj : camera object 1571 * @ch_id : channel handle 1572 * @buf_map_list : list of buffers to be mapped 1573 * 1574 * RETURN : int32_t type of status 1575 * 0 -- success 1576 * -1 -- failure 1577 *==========================================================================*/ 1578int32_t mm_camera_map_stream_bufs(mm_camera_obj_t *my_obj, 1579 uint32_t ch_id, 1580 const cam_buf_map_type_list *buf_map_list) 1581{ 1582 int32_t rc = -1; 1583 cam_buf_map_type_list payload; 1584 mm_channel_t * ch_obj = 1585 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1586 1587 if (NULL != ch_obj) { 1588 pthread_mutex_lock(&ch_obj->ch_lock); 1589 pthread_mutex_unlock(&my_obj->cam_lock); 1590 1591 memcpy(&payload, buf_map_list, sizeof(payload)); 1592 rc = mm_channel_fsm_fn(ch_obj, 1593 MM_CHANNEL_EVT_MAP_STREAM_BUFS, 1594 (void*)&payload, 1595 NULL); 1596 } else { 1597 pthread_mutex_unlock(&my_obj->cam_lock); 1598 } 1599 1600 return rc; 1601} 1602 1603/*=========================================================================== 1604 * FUNCTION : mm_camera_unmap_stream_buf 1605 * 1606 * DESCRIPTION: unmapping stream buffer via domain socket to server 1607 * 1608 * PARAMETERS : 1609 * @my_obj : camera object 1610 * @ch_id : channel handle 1611 * @s_id : stream handle 1612 * @buf_type : type of buffer to be mapped. could be following values: 1613 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1614 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1615 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1616 * @buf_idx : index of buffer within the stream buffers, only valid if 1617 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1618 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1619 * @plane_idx : plane index. If all planes share the same fd, 1620 * plane_idx = -1; otherwise, plean_idx is the 1621 * index to plane (0..num_of_planes) 1622 * 1623 * RETURN : int32_t type of status 1624 * 0 -- success 1625 * -1 -- failure 1626 *==========================================================================*/ 1627int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj, 1628 uint32_t ch_id, 1629 uint32_t stream_id, 1630 uint8_t buf_type, 1631 uint32_t buf_idx, 1632 int32_t plane_idx) 1633{ 1634 int32_t rc = -1; 1635 cam_buf_unmap_type payload; 1636 mm_channel_t * ch_obj = 1637 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 1638 1639 if (NULL != ch_obj) { 1640 pthread_mutex_lock(&ch_obj->ch_lock); 1641 pthread_mutex_unlock(&my_obj->cam_lock); 1642 1643 memset(&payload, 0, sizeof(payload)); 1644 payload.stream_id = stream_id; 1645 payload.type = buf_type; 1646 payload.frame_idx = buf_idx; 1647 payload.plane_idx = plane_idx; 1648 rc = mm_channel_fsm_fn(ch_obj, 1649 MM_CHANNEL_EVT_UNMAP_STREAM_BUF, 1650 (void*)&payload, 1651 NULL); 1652 } else { 1653 pthread_mutex_unlock(&my_obj->cam_lock); 1654 } 1655 1656 return rc; 1657} 1658 1659/*=========================================================================== 1660 * FUNCTION : mm_camera_evt_sub 1661 * 1662 * DESCRIPTION: subscribe/unsubscribe event notify from kernel 1663 * 1664 * PARAMETERS : 1665 * @my_obj : camera object 1666 * @reg_flag : 1 -- subscribe ; 0 -- unsubscribe 1667 * 1668 * RETURN : int32_t type of status 1669 * 0 -- success 1670 * -1 -- failure 1671 *==========================================================================*/ 1672int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj, 1673 uint8_t reg_flag) 1674{ 1675 int32_t rc = 0; 1676 struct v4l2_event_subscription sub; 1677 1678 memset(&sub, 0, sizeof(sub)); 1679 sub.type = MSM_CAMERA_V4L2_EVENT_TYPE; 1680 sub.id = MSM_CAMERA_MSM_NOTIFY; 1681 if(FALSE == reg_flag) { 1682 /* unsubscribe */ 1683 rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub); 1684 if (rc < 0) { 1685 LOGE("unsubscribe event rc = %d, errno %d", 1686 rc, errno); 1687 return rc; 1688 } 1689 /* remove evt fd from the polling thraed when unreg the last event */ 1690 rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread, 1691 my_obj->my_hdl, 1692 mm_camera_sync_call); 1693 } else { 1694 rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub); 1695 if (rc < 0) { 1696 LOGE("subscribe event rc = %d, errno %d", 1697 rc, errno); 1698 return rc; 1699 } 1700 /* add evt fd to polling thread when subscribe the first event */ 1701 rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread, 1702 my_obj->my_hdl, 1703 my_obj->ctrl_fd, 1704 mm_camera_event_notify, 1705 (void*)my_obj, 1706 mm_camera_sync_call); 1707 } 1708 return rc; 1709} 1710 1711/*=========================================================================== 1712 * FUNCTION : mm_camera_util_wait_for_event 1713 * 1714 * DESCRIPTION: utility function to wait for certain events 1715 * 1716 * PARAMETERS : 1717 * @my_obj : camera object 1718 * @evt_mask : mask for events to be waited. Any of event in the mask would 1719 * trigger the wait to end 1720 * @status : status of the event 1721 * 1722 * RETURN : none 1723 *==========================================================================*/ 1724void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj, 1725 uint32_t evt_mask, 1726 uint32_t *status) 1727{ 1728 int32_t rc = 0; 1729 struct timespec ts; 1730 1731 pthread_mutex_lock(&my_obj->evt_lock); 1732 while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) { 1733 clock_gettime(CLOCK_REALTIME, &ts); 1734 ts.tv_sec += WAIT_TIMEOUT; 1735 rc = pthread_cond_timedwait(&my_obj->evt_cond, &my_obj->evt_lock, &ts); 1736 if (rc) { 1737 LOGE("pthread_cond_timedwait of evt_mask 0x%x failed %d", 1738 evt_mask, rc); 1739 break; 1740 } 1741 } 1742 if (!rc) { 1743 *status = my_obj->evt_rcvd.status; 1744 } else { 1745 *status = MSM_CAMERA_STATUS_FAIL; 1746 } 1747 /* reset local storage for recieved event for next event */ 1748 memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t)); 1749 pthread_mutex_unlock(&my_obj->evt_lock); 1750} 1751 1752/*=========================================================================== 1753 * FUNCTION : mm_camera_util_bundled_sendmsg 1754 * 1755 * DESCRIPTION: utility function to send bundled msg via domain socket 1756 * 1757 * PARAMETERS : 1758 * @my_obj : camera object 1759 * @msg : message to be sent 1760 * @buf_size : size of the message to be sent 1761 * @sendfds : array of file descriptors to be sent 1762 * @numfds : number of file descriptors to be sent 1763 * 1764 * RETURN : int32_t type of status 1765 * 0 -- success 1766 * -1 -- failure 1767 *==========================================================================*/ 1768int32_t mm_camera_util_bundled_sendmsg(mm_camera_obj_t *my_obj, 1769 void *msg, 1770 size_t buf_size, 1771 int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM], 1772 int numfds) 1773{ 1774 int32_t rc = -1; 1775 uint32_t status; 1776 1777 /* need to lock msg_lock, since sendmsg until response back is deemed as one operation*/ 1778 pthread_mutex_lock(&my_obj->msg_lock); 1779 if(mm_camera_socket_bundle_sendmsg(my_obj->ds_fd, msg, buf_size, sendfds, numfds) > 0) { 1780 /* wait for event that mapping/unmapping is done */ 1781 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status); 1782 if (MSM_CAMERA_STATUS_SUCCESS == status) { 1783 rc = 0; 1784 } 1785 } 1786 pthread_mutex_unlock(&my_obj->msg_lock); 1787 return rc; 1788} 1789 1790/*=========================================================================== 1791 * FUNCTION : mm_camera_util_sendmsg 1792 * 1793 * DESCRIPTION: utility function to send msg via domain socket 1794 * 1795 * PARAMETERS : 1796 * @my_obj : camera object 1797 * @msg : message to be sent 1798 * @buf_size : size of the message to be sent 1799 * @sendfd : >0 if any file descriptor need to be passed across process 1800 * 1801 * RETURN : int32_t type of status 1802 * 0 -- success 1803 * -1 -- failure 1804 *==========================================================================*/ 1805int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj, 1806 void *msg, 1807 size_t buf_size, 1808 int sendfd) 1809{ 1810 int32_t rc = -1; 1811 uint32_t status; 1812 1813 /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/ 1814 pthread_mutex_lock(&my_obj->msg_lock); 1815 if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) { 1816 /* wait for event that mapping/unmapping is done */ 1817 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status); 1818 if (MSM_CAMERA_STATUS_SUCCESS == status) { 1819 rc = 0; 1820 } 1821 } 1822 pthread_mutex_unlock(&my_obj->msg_lock); 1823 return rc; 1824} 1825 1826/*=========================================================================== 1827 * FUNCTION : mm_camera_map_buf 1828 * 1829 * DESCRIPTION: mapping camera buffer via domain socket to server 1830 * 1831 * PARAMETERS : 1832 * @my_obj : camera object 1833 * @buf_type : type of buffer to be mapped. could be following values: 1834 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1835 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1836 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1837 * @fd : file descriptor of the buffer 1838 * @size : size of the buffer 1839 * 1840 * RETURN : int32_t type of status 1841 * 0 -- success 1842 * -1 -- failure 1843 *==========================================================================*/ 1844int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj, 1845 uint8_t buf_type, 1846 int fd, 1847 size_t size) 1848{ 1849 int32_t rc = 0; 1850 cam_sock_packet_t packet; 1851 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1852 packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING; 1853 packet.payload.buf_map.type = buf_type; 1854 packet.payload.buf_map.fd = fd; 1855 packet.payload.buf_map.size = size; 1856 rc = mm_camera_util_sendmsg(my_obj, 1857 &packet, 1858 sizeof(cam_sock_packet_t), 1859 fd); 1860 pthread_mutex_unlock(&my_obj->cam_lock); 1861 return rc; 1862} 1863 1864/*=========================================================================== 1865 * FUNCTION : mm_camera_map_bufs 1866 * 1867 * DESCRIPTION: mapping camera buffers via domain socket to server 1868 * 1869 * PARAMETERS : 1870 * @my_obj : camera object 1871 * @buf_map_list : list of buffers to be mapped 1872 * 1873 * RETURN : int32_t type of status 1874 * 0 -- success 1875 * -1 -- failure 1876 *==========================================================================*/ 1877int32_t mm_camera_map_bufs(mm_camera_obj_t *my_obj, 1878 const cam_buf_map_type_list* buf_map_list) 1879{ 1880 int32_t rc = 0; 1881 cam_sock_packet_t packet; 1882 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1883 packet.msg_type = CAM_MAPPING_TYPE_FD_BUNDLED_MAPPING; 1884 1885 memcpy(&packet.payload.buf_map_list, buf_map_list, 1886 sizeof(packet.payload.buf_map_list)); 1887 1888 int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM]; 1889 uint32_t numbufs = packet.payload.buf_map_list.length; 1890 uint32_t i; 1891 for (i = 0; i < numbufs; i++) { 1892 sendfds[i] = packet.payload.buf_map_list.buf_maps[i].fd; 1893 } 1894 1895 for (i = numbufs; i < CAM_MAX_NUM_BUFS_PER_STREAM; i++) { 1896 packet.payload.buf_map_list.buf_maps[i].fd = -1; 1897 sendfds[i] = -1; 1898 } 1899 1900 rc = mm_camera_util_bundled_sendmsg(my_obj, 1901 &packet, 1902 sizeof(cam_sock_packet_t), 1903 sendfds, 1904 numbufs); 1905 1906 pthread_mutex_unlock(&my_obj->cam_lock); 1907 return rc; 1908} 1909 1910/*=========================================================================== 1911 * FUNCTION : mm_camera_unmap_buf 1912 * 1913 * DESCRIPTION: unmapping camera buffer via domain socket to server 1914 * 1915 * PARAMETERS : 1916 * @my_obj : camera object 1917 * @buf_type : type of buffer to be mapped. could be following values: 1918 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1919 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1920 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1921 * 1922 * RETURN : int32_t type of status 1923 * 0 -- success 1924 * -1 -- failure 1925 *==========================================================================*/ 1926int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj, 1927 uint8_t buf_type) 1928{ 1929 int32_t rc = 0; 1930 cam_sock_packet_t packet; 1931 memset(&packet, 0, sizeof(cam_sock_packet_t)); 1932 packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING; 1933 packet.payload.buf_unmap.type = buf_type; 1934 rc = mm_camera_util_sendmsg(my_obj, 1935 &packet, 1936 sizeof(cam_sock_packet_t), 1937 -1); 1938 pthread_mutex_unlock(&my_obj->cam_lock); 1939 return rc; 1940} 1941 1942/*=========================================================================== 1943 * FUNCTION : mm_camera_util_s_ctrl 1944 * 1945 * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl 1946 * 1947 * PARAMETERS : 1948 * @fd : file descritpor for sending ioctl 1949 * @id : control id 1950 * @value : value of the ioctl to be sent 1951 * 1952 * RETURN : int32_t type of status 1953 * 0 -- success 1954 * -1 -- failure 1955 *==========================================================================*/ 1956int32_t mm_camera_util_s_ctrl(int32_t fd, uint32_t id, int32_t *value) 1957{ 1958 int rc = 0; 1959 struct v4l2_control control; 1960 1961 memset(&control, 0, sizeof(control)); 1962 control.id = id; 1963 if (value != NULL) { 1964 control.value = *value; 1965 } 1966 rc = ioctl(fd, VIDIOC_S_CTRL, &control); 1967 1968 LOGD("fd=%d, S_CTRL, id=0x%x, value = %p, rc = %d\n", 1969 fd, id, value, rc); 1970 if (rc < 0) { 1971 LOGE("ioctl failed %d, errno %d", rc, errno); 1972 } else if (value != NULL) { 1973 *value = control.value; 1974 } 1975 return (rc >= 0)? 0 : -1; 1976} 1977 1978/*=========================================================================== 1979 * FUNCTION : mm_camera_util_g_ctrl 1980 * 1981 * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl 1982 * 1983 * PARAMETERS : 1984 * @fd : file descritpor for sending ioctl 1985 * @id : control id 1986 * @value : value of the ioctl to be sent 1987 * 1988 * RETURN : int32_t type of status 1989 * 0 -- success 1990 * -1 -- failure 1991 *==========================================================================*/ 1992int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value) 1993{ 1994 int rc = 0; 1995 struct v4l2_control control; 1996 1997 memset(&control, 0, sizeof(control)); 1998 control.id = id; 1999 if (value != NULL) { 2000 control.value = *value; 2001 } 2002 rc = ioctl(fd, VIDIOC_G_CTRL, &control); 2003 LOGD("fd=%d, G_CTRL, id=0x%x, rc = %d\n", fd, id, rc); 2004 if (value != NULL) { 2005 *value = control.value; 2006 } 2007 return (rc >= 0)? 0 : -1; 2008} 2009 2010/*=========================================================================== 2011 * FUNCTION : mm_camera_channel_advanced_capture 2012 * 2013 * DESCRIPTION: sets the channel advanced capture 2014 * 2015 * PARAMETERS : 2016 * @my_obj : camera object 2017 * @ch_id : channel handle 2018 * @type : advanced capture type. 2019 * @start_flag : flag to indicate start/stop 2020 * @in_value : input configaration 2021 * 2022 * RETURN : int32_t type of status 2023 * 0 -- success 2024 * -1 -- failure 2025 *==========================================================================*/ 2026int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj, 2027 uint32_t ch_id, mm_camera_advanced_capture_t type, 2028 uint32_t trigger, void *in_value) 2029{ 2030 LOGD("E type = %d", type); 2031 int32_t rc = -1; 2032 mm_channel_t * ch_obj = 2033 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 2034 2035 if (NULL != ch_obj) { 2036 pthread_mutex_lock(&ch_obj->ch_lock); 2037 pthread_mutex_unlock(&my_obj->cam_lock); 2038 switch (type) { 2039 case MM_CAMERA_AF_BRACKETING: 2040 rc = mm_channel_fsm_fn(ch_obj, 2041 MM_CHANNEL_EVT_AF_BRACKETING, 2042 (void *)&trigger, 2043 NULL); 2044 break; 2045 case MM_CAMERA_AE_BRACKETING: 2046 rc = mm_channel_fsm_fn(ch_obj, 2047 MM_CHANNEL_EVT_AE_BRACKETING, 2048 (void *)&trigger, 2049 NULL); 2050 break; 2051 case MM_CAMERA_FLASH_BRACKETING: 2052 rc = mm_channel_fsm_fn(ch_obj, 2053 MM_CHANNEL_EVT_FLASH_BRACKETING, 2054 (void *)&trigger, 2055 NULL); 2056 break; 2057 case MM_CAMERA_ZOOM_1X: 2058 rc = mm_channel_fsm_fn(ch_obj, 2059 MM_CHANNEL_EVT_ZOOM_1X, 2060 (void *)&trigger, 2061 NULL); 2062 break; 2063 case MM_CAMERA_FRAME_CAPTURE: 2064 rc = mm_channel_fsm_fn(ch_obj, 2065 MM_CAMERA_EVT_CAPTURE_SETTING, 2066 (void *)in_value, 2067 NULL); 2068 break; 2069 default: 2070 break; 2071 } 2072 2073 } else { 2074 pthread_mutex_unlock(&my_obj->cam_lock); 2075 } 2076 2077 LOGD("X"); 2078 return rc; 2079} 2080 2081/*=========================================================================== 2082 * FUNCTION : mm_camera_get_session_id 2083 * 2084 * DESCRIPTION: get the session identity 2085 * 2086 * PARAMETERS : 2087 * @my_obj : camera object 2088 * @sessionid: pointer to the output session id 2089 * 2090 * RETURN : int32_t type of status 2091 * 0 -- success 2092 * -1 -- failure 2093 * NOTE : if this call succeeds, we will get a valid session id 2094 *==========================================================================*/ 2095int32_t mm_camera_get_session_id(mm_camera_obj_t *my_obj, 2096 uint32_t* sessionid) 2097{ 2098 int32_t rc = -1; 2099 int32_t value = 0; 2100 if(sessionid != NULL) { 2101 rc = mm_camera_util_g_ctrl(my_obj->ctrl_fd, 2102 MSM_CAMERA_PRIV_G_SESSION_ID, &value); 2103 LOGD("fd=%d, get_session_id, id=0x%x, value = %d, rc = %d\n", 2104 my_obj->ctrl_fd, MSM_CAMERA_PRIV_G_SESSION_ID, 2105 value, rc); 2106 *sessionid = value; 2107 my_obj->sessionid = value; 2108 } 2109 2110 pthread_mutex_unlock(&my_obj->cam_lock); 2111 return rc; 2112} 2113 2114/*=========================================================================== 2115 * FUNCTION : mm_camera_sync_related_sensors 2116 * 2117 * DESCRIPTION: send sync cmd 2118 * 2119 * PARAMETERS : 2120 * @my_obj : camera object 2121 * @parms : ptr to the related cam info to be sent to server 2122 * 2123 * RETURN : int32_t type of status 2124 * 0 -- success 2125 * -1 -- failure 2126 * NOTE : Assume the sync struct buf is already mapped to server via 2127 * domain socket. Corresponding fields of parameters to be set 2128 * are already filled in by upper layer caller. 2129 *==========================================================================*/ 2130int32_t mm_camera_sync_related_sensors(mm_camera_obj_t *my_obj, 2131 cam_sync_related_sensors_event_info_t* parms) 2132{ 2133 int32_t rc = -1; 2134 int32_t value = 0; 2135 if (parms != NULL) { 2136 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, 2137 CAM_PRIV_SYNC_RELATED_SENSORS, &value); 2138 } 2139 pthread_mutex_unlock(&my_obj->cam_lock); 2140 return rc; 2141} 2142 2143/*=========================================================================== 2144 * FUNCTION : mm_camera_reg_stream_buf_cb 2145 * 2146 * DESCRIPTION: Register callback for stream buffer 2147 * 2148 * PARAMETERS : 2149 * @my_obj : camera object 2150 * @ch_id : channel handle 2151 * @stream_id : stream that will be linked 2152 * @buf_cb : special callback needs to be registered for stream buffer 2153 * @cb_type : Callback type SYNC/ASYNC 2154 * @userdata : user data pointer 2155 * 2156 * RETURN : int32_t type of status 2157 * 0 -- success 2158 * 1 -- failure 2159 *==========================================================================*/ 2160int32_t mm_camera_reg_stream_buf_cb(mm_camera_obj_t *my_obj, 2161 uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t stream_cb, 2162 mm_camera_stream_cb_type cb_type, void *userdata) 2163{ 2164 int rc = 0; 2165 mm_stream_data_cb_t buf_cb; 2166 mm_channel_t * ch_obj = 2167 mm_camera_util_get_channel_by_handler(my_obj, ch_id); 2168 2169 if (NULL != ch_obj) { 2170 pthread_mutex_lock(&ch_obj->ch_lock); 2171 pthread_mutex_unlock(&my_obj->cam_lock); 2172 2173 memset(&buf_cb, 0, sizeof(mm_stream_data_cb_t)); 2174 buf_cb.cb = stream_cb; 2175 buf_cb.cb_count = -1; 2176 buf_cb.cb_type = cb_type; 2177 buf_cb.user_data = userdata; 2178 2179 mm_evt_paylod_reg_stream_buf_cb payload; 2180 memset(&payload, 0, sizeof(mm_evt_paylod_reg_stream_buf_cb)); 2181 payload.buf_cb = buf_cb; 2182 payload.stream_id = stream_id; 2183 mm_channel_fsm_fn(ch_obj, 2184 MM_CHANNEL_EVT_REG_STREAM_BUF_CB, 2185 (void*)&payload, NULL); 2186 } else { 2187 pthread_mutex_unlock(&my_obj->cam_lock); 2188 } 2189 return rc; 2190} 2191 2192#ifdef QCAMERA_REDEFINE_LOG 2193 2194/*=========================================================================== 2195 * DESCRIPTION: mm camera debug interface 2196 * 2197 *==========================================================================*/ 2198pthread_mutex_t dbg_log_mutex; 2199 2200#undef LOG_TAG 2201#define LOG_TAG "QCamera" 2202#define CDBG_MAX_STR_LEN 1024 2203#define CDBG_MAX_LINE_LENGTH 256 2204 2205/* current trace loggin permissions 2206 * {NONE, ERR, WARN, HIGH, DEBUG, LOW, INFO} */ 2207int g_cam_log[CAM_LAST_MODULE][CAM_GLBL_DBG_INFO + 1] = { 2208 {0, 1, 0, 0, 0, 0, 1}, /* CAM_NO_MODULE */ 2209 {0, 1, 0, 0, 0, 0, 1}, /* CAM_HAL_MODULE */ 2210 {0, 1, 0, 0, 0, 0, 1}, /* CAM_MCI_MODULE */ 2211 {0, 1, 0, 0, 0, 0, 1}, /* CAM_JPEG_MODULE */ 2212}; 2213 2214/* string representation for logging level */ 2215static const char *cam_dbg_level_to_str[] = { 2216 "", /* CAM_GLBL_DBG_NONE */ 2217 "<ERROR>", /* CAM_GLBL_DBG_ERR */ 2218 "<WARN>", /* CAM_GLBL_DBG_WARN */ 2219 "<HIGH>", /* CAM_GLBL_DBG_HIGH */ 2220 "<DBG>", /* CAM_GLBL_DBG_DEBUG */ 2221 "<LOW>", /* CAM_GLBL_DBG_LOW */ 2222 "<INFO>" /* CAM_GLBL_DBG_INFO */ 2223}; 2224 2225/* current trace logging configuration */ 2226typedef struct { 2227 cam_global_debug_level_t level; 2228 int initialized; 2229 const char *name; 2230 const char *prop; 2231} module_debug_t; 2232 2233static module_debug_t cam_loginfo[(int)CAM_LAST_MODULE] = { 2234 {CAM_GLBL_DBG_ERR, 1, 2235 "", "persist.camera.global.debug" }, /* CAM_NO_MODULE */ 2236 {CAM_GLBL_DBG_ERR, 1, 2237 "<HAL>", "persist.camera.hal.debug" }, /* CAM_HAL_MODULE */ 2238 {CAM_GLBL_DBG_ERR, 1, 2239 "<MCI>", "persist.camera.mci.debug" }, /* CAM_MCI_MODULE */ 2240 {CAM_GLBL_DBG_ERR, 1, 2241 "<JPEG>", "persist.camera.mmstill.logs" }, /* CAM_JPEG_MODULE */ 2242}; 2243 2244/** cam_get_dbg_level 2245 * 2246 * @module: module name 2247 * @level: module debug logging level 2248 * 2249 * Maps debug log string to value. 2250 * 2251 * Return: logging level 2252 **/ 2253__unused 2254static cam_global_debug_level_t cam_get_dbg_level(const char *module, 2255 char *pValue) { 2256 2257 cam_global_debug_level_t rc = CAM_GLBL_DBG_NONE; 2258 2259 if (!strcmp(pValue, "none")) { 2260 rc = CAM_GLBL_DBG_NONE; 2261 } else if (!strcmp(pValue, "warn")) { 2262 rc = CAM_GLBL_DBG_WARN; 2263 } else if (!strcmp(pValue, "debug")) { 2264 rc = CAM_GLBL_DBG_DEBUG; 2265 } else if (!strcmp(pValue, "error")) { 2266 rc = CAM_GLBL_DBG_ERR; 2267 } else if (!strcmp(pValue, "low")) { 2268 rc = CAM_GLBL_DBG_LOW; 2269 } else if (!strcmp(pValue, "high")) { 2270 rc = CAM_GLBL_DBG_HIGH; 2271 } else if (!strcmp(pValue, "info")) { 2272 rc = CAM_GLBL_DBG_INFO; 2273 } else { 2274 ALOGE("Invalid %s debug log level %s\n", module, pValue); 2275 } 2276 2277 ALOGD("%s debug log level: %s\n", module, cam_dbg_level_to_str[rc]); 2278 2279 return rc; 2280} 2281 2282/** cam_vsnprintf 2283 * @pdst: destination buffer pointer 2284 * @size: size of destination b uffer 2285 * @pfmt: string format 2286 * @argptr: variabkle length argument list 2287 * 2288 * Processes variable length argument list to a formatted string. 2289 * 2290 * Return: n/a 2291 **/ 2292static void cam_vsnprintf(char* pdst, unsigned int size, 2293 const char* pfmt, va_list argptr) { 2294 int num_chars_written = 0; 2295 2296 pdst[0] = '\0'; 2297 num_chars_written = vsnprintf(pdst, size, pfmt, argptr); 2298 2299 if ((num_chars_written >= (int)size) && (size > 0)) { 2300 /* Message length exceeds the buffer limit size */ 2301 num_chars_written = size - 1; 2302 pdst[size - 1] = '\0'; 2303 } 2304} 2305 2306/** mm_camera_debug_log 2307 * @module: origin or log message 2308 * @level: logging level 2309 * @func: caller function name 2310 * @line: caller line number 2311 * @fmt: log message formatting string 2312 * @...: variable argument list 2313 * 2314 * Generig logger method. 2315 * 2316 * Return: N/A 2317 **/ 2318void mm_camera_debug_log(const cam_modules_t module, 2319 const cam_global_debug_level_t level, 2320 const char *func, const int line, const char *fmt, ...) { 2321 char str_buffer[CDBG_MAX_STR_LEN]; 2322 va_list args; 2323 2324 va_start(args, fmt); 2325 cam_vsnprintf(str_buffer, CDBG_MAX_STR_LEN, fmt, args); 2326 va_end(args); 2327 2328 switch (level) { 2329 case CAM_GLBL_DBG_WARN: 2330 ALOGW("%s%s %s: %d: %s", cam_loginfo[module].name, 2331 cam_dbg_level_to_str[level], func, line, str_buffer); 2332 break; 2333 case CAM_GLBL_DBG_ERR: 2334 ALOGE("%s%s %s: %d: %s", cam_loginfo[module].name, 2335 cam_dbg_level_to_str[level], func, line, str_buffer); 2336 break; 2337 case CAM_GLBL_DBG_INFO: 2338 ALOGI("%s%s %s: %d: %s", cam_loginfo[module].name, 2339 cam_dbg_level_to_str[level], func, line, str_buffer); 2340 break; 2341 case CAM_GLBL_DBG_HIGH: 2342 case CAM_GLBL_DBG_DEBUG: 2343 case CAM_GLBL_DBG_LOW: 2344 default: 2345 ALOGD("%s%s %s: %d: %s", cam_loginfo[module].name, 2346 cam_dbg_level_to_str[level], func, line, str_buffer); 2347 } 2348} 2349 2350 /** mm_camera_set_dbg_log_properties 2351 * 2352 * Set global and module log level properties. 2353 * 2354 * Return: N/A 2355 **/ 2356void mm_camera_set_dbg_log_properties(void) { 2357 int i; 2358 unsigned int j; 2359 static int boot_init = 1; 2360 char property_value[PROPERTY_VALUE_MAX] = {0}; 2361 char default_value[PROPERTY_VALUE_MAX] = {0}; 2362 2363 if (boot_init) { 2364 boot_init = 0; 2365 pthread_mutex_init(&dbg_log_mutex, 0); 2366 } 2367 2368 /* set global and individual module logging levels */ 2369 pthread_mutex_lock(&dbg_log_mutex); 2370 for (i = CAM_NO_MODULE; i < CAM_LAST_MODULE; i++) { 2371 cam_global_debug_level_t log_level; 2372 snprintf(default_value, PROPERTY_VALUE_MAX, "%d", (int)cam_loginfo[i].level); 2373 property_get(cam_loginfo[i].prop, property_value, default_value); 2374 log_level = (cam_global_debug_level_t)atoi(property_value); 2375 2376 /* fix KW warnings */ 2377 if (log_level > CAM_GLBL_DBG_INFO) { 2378 log_level = CAM_GLBL_DBG_INFO; 2379 } 2380 2381 cam_loginfo[i].level = log_level; 2382 2383 /* The logging macros will produce a log message when logging level for 2384 * a module is less or equal to the level specified in the property for 2385 * the module, or less or equal the level specified by the global logging 2386 * property. Currently we don't allow INFO logging to be turned off */ 2387 for (j = CAM_GLBL_DBG_ERR; j <= CAM_GLBL_DBG_LOW; j++) { 2388 g_cam_log[i][j] = (cam_loginfo[CAM_NO_MODULE].level != CAM_GLBL_DBG_NONE) && 2389 (cam_loginfo[i].level != CAM_GLBL_DBG_NONE) && 2390 ((j <= cam_loginfo[i].level) || 2391 (j <= cam_loginfo[CAM_NO_MODULE].level)); 2392 } 2393 } 2394 pthread_mutex_unlock(&dbg_log_mutex); 2395} 2396 2397#endif 2398