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 #include <linux/media.h> 38 39 #include "mm_camera_dbg.h" 40 #include "mm_camera_interface.h" 41 #include "mm_camera_sock.h" 42 #include "mm_camera.h" 43 44 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER; 45 46 static mm_camera_ctrl_t g_cam_ctrl = {0, {{0}}, {0}}; 47 48 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER; 49 static uint16_t g_handler_history_count = 0; /* history count for handler */ 50 51 /*=========================================================================== 52 * FUNCTION : mm_camera_util_generate_handler 53 * 54 * DESCRIPTION: utility function to generate handler for camera/channel/stream 55 * 56 * PARAMETERS : 57 * @index: index of the object to have handler 58 * 59 * RETURN : uint32_t type of handle that uniquely identify the object 60 *==========================================================================*/ 61 uint32_t mm_camera_util_generate_handler(uint8_t index) 62 { 63 uint32_t handler = 0; 64 pthread_mutex_lock(&g_handler_lock); 65 g_handler_history_count++; 66 if (0 == g_handler_history_count) { 67 g_handler_history_count++; 68 } 69 handler = g_handler_history_count; 70 handler = (handler<<8) | index; 71 pthread_mutex_unlock(&g_handler_lock); 72 return handler; 73 } 74 75 /*=========================================================================== 76 * FUNCTION : mm_camera_util_get_index_by_handler 77 * 78 * DESCRIPTION: utility function to get index from handle 79 * 80 * PARAMETERS : 81 * @handler: object handle 82 * 83 * RETURN : uint8_t type of index derived from handle 84 *==========================================================================*/ 85 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler) 86 { 87 return (handler&0x000000ff); 88 } 89 90 /*=========================================================================== 91 * FUNCTION : mm_camera_util_get_dev_name 92 * 93 * DESCRIPTION: utility function to get device name from camera handle 94 * 95 * PARAMETERS : 96 * @cam_handle: camera handle 97 * 98 * RETURN : char ptr to the device name stored in global variable 99 * NOTE : caller should not free the char ptr 100 *==========================================================================*/ 101 const char *mm_camera_util_get_dev_name(uint32_t cam_handle) 102 { 103 char *dev_name = NULL; 104 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle); 105 if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) { 106 dev_name = g_cam_ctrl.video_dev_name[cam_idx]; 107 } 108 return dev_name; 109 } 110 111 /*=========================================================================== 112 * FUNCTION : mm_camera_util_get_camera_by_handler 113 * 114 * DESCRIPTION: utility function to get camera object from camera handle 115 * 116 * PARAMETERS : 117 * @cam_handle: camera handle 118 * 119 * RETURN : ptr to the camera object stored in global variable 120 * NOTE : caller should not free the camera object ptr 121 *==========================================================================*/ 122 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle) 123 { 124 mm_camera_obj_t *cam_obj = NULL; 125 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle); 126 127 if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS && 128 (NULL != g_cam_ctrl.cam_obj[cam_idx]) && 129 (cam_handle == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) { 130 cam_obj = g_cam_ctrl.cam_obj[cam_idx]; 131 } 132 return cam_obj; 133 } 134 135 /*=========================================================================== 136 * FUNCTION : mm_camera_intf_query_capability 137 * 138 * DESCRIPTION: query camera capability 139 * 140 * PARAMETERS : 141 * @camera_handle: camera handle 142 * 143 * RETURN : int32_t type of status 144 * 0 -- success 145 * -1 -- failure 146 *==========================================================================*/ 147 static int32_t mm_camera_intf_query_capability(uint32_t camera_handle) 148 { 149 int32_t rc = -1; 150 mm_camera_obj_t * my_obj = NULL; 151 152 CDBG("%s E: camera_handler = %d ", __func__, camera_handle); 153 154 pthread_mutex_lock(&g_intf_lock); 155 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 156 157 if(my_obj) { 158 pthread_mutex_lock(&my_obj->cam_lock); 159 pthread_mutex_unlock(&g_intf_lock); 160 rc = mm_camera_query_capability(my_obj); 161 } else { 162 pthread_mutex_unlock(&g_intf_lock); 163 } 164 CDBG("%s :X rc = %d", __func__, rc); 165 return rc; 166 } 167 168 /*=========================================================================== 169 * FUNCTION : mm_camera_intf_set_parms 170 * 171 * DESCRIPTION: set parameters per camera 172 * 173 * PARAMETERS : 174 * @camera_handle: camera handle 175 * @parms : ptr to a param struct to be set to server 176 * 177 * RETURN : int32_t type of status 178 * 0 -- success 179 * -1 -- failure 180 * NOTE : Assume the parms struct buf is already mapped to server via 181 * domain socket. Corresponding fields of parameters to be set 182 * are already filled in by upper layer caller. 183 *==========================================================================*/ 184 static int32_t mm_camera_intf_set_parms(uint32_t camera_handle, 185 parm_buffer_t *parms) 186 { 187 int32_t rc = -1; 188 mm_camera_obj_t * my_obj = NULL; 189 190 pthread_mutex_lock(&g_intf_lock); 191 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 192 193 if(my_obj) { 194 pthread_mutex_lock(&my_obj->cam_lock); 195 pthread_mutex_unlock(&g_intf_lock); 196 rc = mm_camera_set_parms(my_obj, parms); 197 } else { 198 pthread_mutex_unlock(&g_intf_lock); 199 } 200 return rc; 201 } 202 203 /*=========================================================================== 204 * FUNCTION : mm_camera_intf_get_parms 205 * 206 * DESCRIPTION: get parameters per camera 207 * 208 * PARAMETERS : 209 * @camera_handle: camera handle 210 * @parms : ptr to a param struct to be get from server 211 * 212 * RETURN : int32_t type of status 213 * 0 -- success 214 * -1 -- failure 215 * NOTE : Assume the parms struct buf is already mapped to server via 216 * domain socket. Parameters to be get from server are already 217 * filled in by upper layer caller. After this call, corresponding 218 * fields of requested parameters will be filled in by server with 219 * detailed information. 220 *==========================================================================*/ 221 static int32_t mm_camera_intf_get_parms(uint32_t camera_handle, 222 parm_buffer_t *parms) 223 { 224 int32_t rc = -1; 225 mm_camera_obj_t * my_obj = NULL; 226 227 pthread_mutex_lock(&g_intf_lock); 228 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 229 230 if(my_obj) { 231 pthread_mutex_lock(&my_obj->cam_lock); 232 pthread_mutex_unlock(&g_intf_lock); 233 rc = mm_camera_get_parms(my_obj, parms); 234 } else { 235 pthread_mutex_unlock(&g_intf_lock); 236 } 237 return rc; 238 } 239 240 /*=========================================================================== 241 * FUNCTION : mm_camera_intf_do_auto_focus 242 * 243 * DESCRIPTION: performing auto focus 244 * 245 * PARAMETERS : 246 * @camera_handle: camera handle 247 * 248 * RETURN : int32_t type of status 249 * 0 -- success 250 * -1 -- failure 251 * NOTE : if this call success, we will always assume there will 252 * be an auto_focus event following up. 253 *==========================================================================*/ 254 static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle) 255 { 256 int32_t rc = -1; 257 mm_camera_obj_t * my_obj = NULL; 258 259 pthread_mutex_lock(&g_intf_lock); 260 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 261 262 if(my_obj) { 263 pthread_mutex_lock(&my_obj->cam_lock); 264 pthread_mutex_unlock(&g_intf_lock); 265 rc = mm_camera_do_auto_focus(my_obj); 266 } else { 267 pthread_mutex_unlock(&g_intf_lock); 268 } 269 return rc; 270 } 271 272 /*=========================================================================== 273 * FUNCTION : mm_camera_intf_cancel_auto_focus 274 * 275 * DESCRIPTION: cancel auto focus 276 * 277 * PARAMETERS : 278 * @camera_handle: camera handle 279 * 280 * RETURN : int32_t type of status 281 * 0 -- success 282 * -1 -- failure 283 *==========================================================================*/ 284 static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle) 285 { 286 int32_t rc = -1; 287 mm_camera_obj_t * my_obj = NULL; 288 289 pthread_mutex_lock(&g_intf_lock); 290 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 291 292 if(my_obj) { 293 pthread_mutex_lock(&my_obj->cam_lock); 294 pthread_mutex_unlock(&g_intf_lock); 295 rc = mm_camera_cancel_auto_focus(my_obj); 296 } else { 297 pthread_mutex_unlock(&g_intf_lock); 298 } 299 return rc; 300 } 301 302 /*=========================================================================== 303 * FUNCTION : mm_camera_intf_prepare_snapshot 304 * 305 * DESCRIPTION: prepare hardware for snapshot 306 * 307 * PARAMETERS : 308 * @camera_handle: camera handle 309 * @do_af_flag : flag indicating if AF is needed 310 * 311 * RETURN : int32_t type of status 312 * 0 -- success 313 * -1 -- failure 314 *==========================================================================*/ 315 static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle, 316 int32_t do_af_flag) 317 { 318 int32_t rc = -1; 319 mm_camera_obj_t * my_obj = NULL; 320 321 pthread_mutex_lock(&g_intf_lock); 322 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 323 324 if(my_obj) { 325 pthread_mutex_lock(&my_obj->cam_lock); 326 pthread_mutex_unlock(&g_intf_lock); 327 rc = mm_camera_prepare_snapshot(my_obj, do_af_flag); 328 } else { 329 pthread_mutex_unlock(&g_intf_lock); 330 } 331 return rc; 332 } 333 334 /*=========================================================================== 335 * FUNCTION : mm_camera_intf_start_zsl_snapshot 336 * 337 * DESCRIPTION: start zsl snapshot 338 * 339 * PARAMETERS : 340 * @camera_handle: camera handle 341 * 342 * RETURN : int32_t type of status 343 * 0 -- success 344 * -1 -- failure 345 *==========================================================================*/ 346 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle) 347 { 348 int32_t rc = -1; 349 mm_camera_obj_t * my_obj = NULL; 350 351 pthread_mutex_lock(&g_intf_lock); 352 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 353 354 if(my_obj) { 355 pthread_mutex_lock(&my_obj->cam_lock); 356 pthread_mutex_unlock(&g_intf_lock); 357 rc = mm_camera_start_zsl_snapshot(my_obj); 358 } else { 359 pthread_mutex_unlock(&g_intf_lock); 360 } 361 return rc; 362 } 363 364 /*=========================================================================== 365 * FUNCTION : mm_camera_intf_stop_zsl_snapshot 366 * 367 * DESCRIPTION: stop zsl snapshot 368 * 369 * PARAMETERS : 370 * @camera_handle: camera handle 371 * 372 * RETURN : int32_t type of status 373 * 0 -- success 374 * -1 -- failure 375 *==========================================================================*/ 376 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle) 377 { 378 int32_t rc = -1; 379 mm_camera_obj_t * my_obj = NULL; 380 381 pthread_mutex_lock(&g_intf_lock); 382 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 383 384 if(my_obj) { 385 pthread_mutex_lock(&my_obj->cam_lock); 386 pthread_mutex_unlock(&g_intf_lock); 387 rc = mm_camera_stop_zsl_snapshot(my_obj); 388 } else { 389 pthread_mutex_unlock(&g_intf_lock); 390 } 391 return rc; 392 } 393 394 /*=========================================================================== 395 * FUNCTION : mm_camera_intf_close 396 * 397 * DESCRIPTION: close a camera by its handle 398 * 399 * PARAMETERS : 400 * @camera_handle: camera handle 401 * 402 * RETURN : int32_t type of status 403 * 0 -- success 404 * -1 -- failure 405 *==========================================================================*/ 406 static int32_t mm_camera_intf_close(uint32_t camera_handle) 407 { 408 int32_t rc = -1; 409 uint8_t cam_idx = camera_handle & 0x00ff; 410 mm_camera_obj_t * my_obj = NULL; 411 412 CDBG("%s E: camera_handler = %d ", __func__, camera_handle); 413 414 pthread_mutex_lock(&g_intf_lock); 415 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 416 417 if (my_obj){ 418 my_obj->ref_count--; 419 420 if(my_obj->ref_count > 0) { 421 /* still have reference to obj, return here */ 422 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count); 423 pthread_mutex_unlock(&g_intf_lock); 424 rc = 0; 425 } else { 426 /* need close camera here as no other reference 427 * first empty g_cam_ctrl's referent to cam_obj */ 428 g_cam_ctrl.cam_obj[cam_idx] = NULL; 429 430 pthread_mutex_lock(&my_obj->cam_lock); 431 pthread_mutex_unlock(&g_intf_lock); 432 433 rc = mm_camera_close(my_obj); 434 435 pthread_mutex_destroy(&my_obj->cam_lock); 436 free(my_obj); 437 } 438 } else { 439 pthread_mutex_unlock(&g_intf_lock); 440 } 441 442 return rc; 443 } 444 445 /*=========================================================================== 446 * FUNCTION : mm_camera_intf_add_channel 447 * 448 * DESCRIPTION: add a channel 449 * 450 * PARAMETERS : 451 * @camera_handle: camera handle 452 * @attr : bundle attribute of the channel if needed 453 * @channel_cb : callback function for bundle data notify 454 * @userdata : user data ptr 455 * 456 * RETURN : uint32_t type of channel handle 457 * 0 -- invalid channel handle, meaning the op failed 458 * >0 -- successfully added a channel with a valid handle 459 * NOTE : if no bundle data notify is needed, meaning each stream in the 460 * channel will have its own stream data notify callback, then 461 * attr, channel_cb, and userdata can be NULL. In this case, 462 * no matching logic will be performed in channel for the bundling. 463 *==========================================================================*/ 464 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle, 465 mm_camera_channel_attr_t *attr, 466 mm_camera_buf_notify_t channel_cb, 467 void *userdata) 468 { 469 uint32_t ch_id = 0; 470 mm_camera_obj_t * my_obj = NULL; 471 472 CDBG("%s :E camera_handler = %d", __func__, camera_handle); 473 pthread_mutex_lock(&g_intf_lock); 474 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 475 476 if(my_obj) { 477 pthread_mutex_lock(&my_obj->cam_lock); 478 pthread_mutex_unlock(&g_intf_lock); 479 ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata); 480 } else { 481 pthread_mutex_unlock(&g_intf_lock); 482 } 483 CDBG("%s :X ch_id = %d", __func__, ch_id); 484 return ch_id; 485 } 486 487 /*=========================================================================== 488 * FUNCTION : mm_camera_intf_del_channel 489 * 490 * DESCRIPTION: delete a channel by its handle 491 * 492 * PARAMETERS : 493 * @camera_handle: camera handle 494 * @ch_id : channel handle 495 * 496 * RETURN : int32_t type of status 497 * 0 -- success 498 * -1 -- failure 499 * NOTE : all streams in the channel should be stopped already before 500 * this channel can be deleted. 501 *==========================================================================*/ 502 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle, 503 uint32_t ch_id) 504 { 505 int32_t rc = -1; 506 mm_camera_obj_t * my_obj = NULL; 507 508 CDBG("%s :E ch_id = %d", __func__, ch_id); 509 pthread_mutex_lock(&g_intf_lock); 510 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 511 512 if(my_obj) { 513 pthread_mutex_lock(&my_obj->cam_lock); 514 pthread_mutex_unlock(&g_intf_lock); 515 rc = mm_camera_del_channel(my_obj, ch_id); 516 } else { 517 pthread_mutex_unlock(&g_intf_lock); 518 } 519 CDBG("%s :X", __func__); 520 return rc; 521 } 522 523 /*=========================================================================== 524 * FUNCTION : mm_camera_intf_get_bundle_info 525 * 526 * DESCRIPTION: query bundle info of the channel 527 * 528 * PARAMETERS : 529 * @camera_handle: camera handle 530 * @ch_id : channel handle 531 * @bundle_info : bundle info to be filled in 532 * 533 * RETURN : int32_t type of status 534 * 0 -- success 535 * -1 -- failure 536 * NOTE : all streams in the channel should be stopped already before 537 * this channel can be deleted. 538 *==========================================================================*/ 539 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle, 540 uint32_t ch_id, 541 cam_bundle_config_t *bundle_info) 542 { 543 int32_t rc = -1; 544 mm_camera_obj_t * my_obj = NULL; 545 546 CDBG("%s :E ch_id = %d", __func__, ch_id); 547 pthread_mutex_lock(&g_intf_lock); 548 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 549 550 if(my_obj) { 551 pthread_mutex_lock(&my_obj->cam_lock); 552 pthread_mutex_unlock(&g_intf_lock); 553 rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info); 554 } else { 555 pthread_mutex_unlock(&g_intf_lock); 556 } 557 CDBG("%s :X", __func__); 558 return rc; 559 } 560 561 /*=========================================================================== 562 * FUNCTION : mm_camera_intf_register_event_notify 563 * 564 * DESCRIPTION: register for event notify 565 * 566 * PARAMETERS : 567 * @camera_handle: camera handle 568 * @evt_cb : callback for event notify 569 * @user_data : user data ptr 570 * 571 * RETURN : int32_t type of status 572 * 0 -- success 573 * -1 -- failure 574 *==========================================================================*/ 575 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle, 576 mm_camera_event_notify_t evt_cb, 577 void * user_data) 578 { 579 int32_t rc = -1; 580 mm_camera_obj_t * my_obj = NULL; 581 582 CDBG("%s :E ", __func__); 583 pthread_mutex_lock(&g_intf_lock); 584 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 585 586 if(my_obj) { 587 pthread_mutex_lock(&my_obj->cam_lock); 588 pthread_mutex_unlock(&g_intf_lock); 589 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data); 590 } else { 591 pthread_mutex_unlock(&g_intf_lock); 592 } 593 CDBG("%s :E rc = %d", __func__, rc); 594 return rc; 595 } 596 597 /*=========================================================================== 598 * FUNCTION : mm_camera_intf_qbuf 599 * 600 * DESCRIPTION: enqueue buffer back to kernel 601 * 602 * PARAMETERS : 603 * @camera_handle: camera handle 604 * @ch_id : channel handle 605 * @buf : buf ptr to be enqueued 606 * 607 * RETURN : int32_t type of status 608 * 0 -- success 609 * -1 -- failure 610 *==========================================================================*/ 611 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle, 612 uint32_t ch_id, 613 mm_camera_buf_def_t *buf) 614 { 615 int32_t rc = -1; 616 mm_camera_obj_t * my_obj = NULL; 617 618 pthread_mutex_lock(&g_intf_lock); 619 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 620 621 if(my_obj) { 622 pthread_mutex_lock(&my_obj->cam_lock); 623 pthread_mutex_unlock(&g_intf_lock); 624 rc = mm_camera_qbuf(my_obj, ch_id, buf); 625 } else { 626 pthread_mutex_unlock(&g_intf_lock); 627 } 628 CDBG("%s :X evt_type = %d",__func__,rc); 629 return rc; 630 } 631 632 /*=========================================================================== 633 * FUNCTION : mm_camera_intf_add_stream 634 * 635 * DESCRIPTION: add a stream into a channel 636 * 637 * PARAMETERS : 638 * @camera_handle: camera handle 639 * @ch_id : channel handle 640 * 641 * RETURN : uint32_t type of stream handle 642 * 0 -- invalid stream handle, meaning the op failed 643 * >0 -- successfully added a stream with a valid handle 644 *==========================================================================*/ 645 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle, 646 uint32_t ch_id) 647 { 648 uint32_t stream_id = 0; 649 mm_camera_obj_t * my_obj = NULL; 650 651 CDBG("%s : E handle = %d ch_id = %d", 652 __func__, camera_handle, ch_id); 653 654 pthread_mutex_lock(&g_intf_lock); 655 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 656 657 if(my_obj) { 658 pthread_mutex_lock(&my_obj->cam_lock); 659 pthread_mutex_unlock(&g_intf_lock); 660 stream_id = mm_camera_add_stream(my_obj, ch_id); 661 } else { 662 pthread_mutex_unlock(&g_intf_lock); 663 } 664 CDBG("%s :X stream_id = %d", __func__, stream_id); 665 return stream_id; 666 } 667 668 /*=========================================================================== 669 * FUNCTION : mm_camera_intf_del_stream 670 * 671 * DESCRIPTION: delete a stream by its handle 672 * 673 * PARAMETERS : 674 * @camera_handle: camera handle 675 * @ch_id : channel handle 676 * @stream_id : stream handle 677 * 678 * RETURN : int32_t type of status 679 * 0 -- success 680 * -1 -- failure 681 * NOTE : stream should be stopped already before it can be deleted. 682 *==========================================================================*/ 683 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle, 684 uint32_t ch_id, 685 uint32_t stream_id) 686 { 687 int32_t rc = -1; 688 mm_camera_obj_t * my_obj = NULL; 689 690 CDBG("%s : E handle = %d ch_id = %d stream_id = %d", 691 __func__, camera_handle, ch_id, stream_id); 692 693 pthread_mutex_lock(&g_intf_lock); 694 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 695 696 if(my_obj) { 697 pthread_mutex_lock(&my_obj->cam_lock); 698 pthread_mutex_unlock(&g_intf_lock); 699 rc = mm_camera_del_stream(my_obj, ch_id, stream_id); 700 } else { 701 pthread_mutex_unlock(&g_intf_lock); 702 } 703 CDBG("%s :X rc = %d", __func__, rc); 704 return rc; 705 } 706 707 /*=========================================================================== 708 * FUNCTION : mm_camera_intf_config_stream 709 * 710 * DESCRIPTION: configure a stream 711 * 712 * PARAMETERS : 713 * @camera_handle: camera handle 714 * @ch_id : channel handle 715 * @stream_id : stream handle 716 * @config : stream configuration 717 * 718 * RETURN : int32_t type of status 719 * 0 -- success 720 * -1 -- failure 721 *==========================================================================*/ 722 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle, 723 uint32_t ch_id, 724 uint32_t stream_id, 725 mm_camera_stream_config_t *config) 726 { 727 int32_t rc = -1; 728 mm_camera_obj_t * my_obj = NULL; 729 730 CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d", 731 __func__, camera_handle, ch_id, stream_id); 732 733 pthread_mutex_lock(&g_intf_lock); 734 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 735 736 CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id); 737 738 if(my_obj) { 739 pthread_mutex_lock(&my_obj->cam_lock); 740 pthread_mutex_unlock(&g_intf_lock); 741 rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config); 742 } else { 743 pthread_mutex_unlock(&g_intf_lock); 744 } 745 CDBG("%s :X rc = %d", __func__, rc); 746 return rc; 747 } 748 749 /*=========================================================================== 750 * FUNCTION : mm_camera_intf_start_channel 751 * 752 * DESCRIPTION: start a channel, which will start all streams in the channel 753 * 754 * PARAMETERS : 755 * @camera_handle: camera handle 756 * @ch_id : channel handle 757 * 758 * RETURN : int32_t type of status 759 * 0 -- success 760 * -1 -- failure 761 *==========================================================================*/ 762 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle, 763 uint32_t ch_id) 764 { 765 int32_t rc = -1; 766 mm_camera_obj_t * my_obj = NULL; 767 768 pthread_mutex_lock(&g_intf_lock); 769 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 770 771 if(my_obj) { 772 pthread_mutex_lock(&my_obj->cam_lock); 773 pthread_mutex_unlock(&g_intf_lock); 774 rc = mm_camera_start_channel(my_obj, ch_id); 775 } else { 776 pthread_mutex_unlock(&g_intf_lock); 777 } 778 CDBG("%s :X rc = %d", __func__, rc); 779 return rc; 780 } 781 782 /*=========================================================================== 783 * FUNCTION : mm_camera_intf_stop_channel 784 * 785 * DESCRIPTION: stop a channel, which will stop all streams in the channel 786 * 787 * PARAMETERS : 788 * @camera_handle: camera handle 789 * @ch_id : channel handle 790 * 791 * RETURN : int32_t type of status 792 * 0 -- success 793 * -1 -- failure 794 *==========================================================================*/ 795 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle, 796 uint32_t ch_id) 797 { 798 int32_t rc = -1; 799 mm_camera_obj_t * my_obj = NULL; 800 801 pthread_mutex_lock(&g_intf_lock); 802 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 803 804 if(my_obj) { 805 pthread_mutex_lock(&my_obj->cam_lock); 806 pthread_mutex_unlock(&g_intf_lock); 807 rc = mm_camera_stop_channel(my_obj, ch_id); 808 } else { 809 pthread_mutex_unlock(&g_intf_lock); 810 } 811 CDBG("%s :X rc = %d", __func__, rc); 812 return rc; 813 } 814 815 /*=========================================================================== 816 * FUNCTION : mm_camera_intf_request_super_buf 817 * 818 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched 819 * frames from superbuf queue 820 * 821 * PARAMETERS : 822 * @camera_handle: camera handle 823 * @ch_id : channel handle 824 * @num_buf_requested : number of matched frames needed 825 * 826 * RETURN : int32_t type of status 827 * 0 -- success 828 * -1 -- failure 829 *==========================================================================*/ 830 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle, 831 uint32_t ch_id, 832 uint32_t num_buf_requested) 833 { 834 int32_t rc = -1; 835 CDBG("%s :E camera_handler = %d,ch_id = %d", 836 __func__, camera_handle, ch_id); 837 mm_camera_obj_t * my_obj = NULL; 838 839 pthread_mutex_lock(&g_intf_lock); 840 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 841 842 if(my_obj) { 843 pthread_mutex_lock(&my_obj->cam_lock); 844 pthread_mutex_unlock(&g_intf_lock); 845 rc = mm_camera_request_super_buf(my_obj, ch_id, num_buf_requested); 846 } else { 847 pthread_mutex_unlock(&g_intf_lock); 848 } 849 CDBG("%s :X rc = %d", __func__, rc); 850 return rc; 851 } 852 853 /*=========================================================================== 854 * FUNCTION : mm_camera_intf_cancel_super_buf_request 855 * 856 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount 857 * of matched frames from superbuf queue 858 * 859 * PARAMETERS : 860 * @camera_handle: camera handle 861 * @ch_id : channel handle 862 * 863 * RETURN : int32_t type of status 864 * 0 -- success 865 * -1 -- failure 866 *==========================================================================*/ 867 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle, 868 uint32_t ch_id) 869 { 870 int32_t rc = -1; 871 mm_camera_obj_t * my_obj = NULL; 872 873 CDBG("%s :E camera_handler = %d,ch_id = %d", 874 __func__, camera_handle, ch_id); 875 pthread_mutex_lock(&g_intf_lock); 876 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 877 878 if(my_obj) { 879 pthread_mutex_lock(&my_obj->cam_lock); 880 pthread_mutex_unlock(&g_intf_lock); 881 rc = mm_camera_cancel_super_buf_request(my_obj, ch_id); 882 } else { 883 pthread_mutex_unlock(&g_intf_lock); 884 } 885 CDBG("%s :X rc = %d", __func__, rc); 886 return rc; 887 } 888 889 /*=========================================================================== 890 * FUNCTION : mm_camera_intf_flush_super_buf_queue 891 * 892 * DESCRIPTION: flush out all frames in the superbuf queue 893 * 894 * PARAMETERS : 895 * @camera_handle: camera handle 896 * @ch_id : channel handle 897 * @frame_idx : frame index 898 * 899 * RETURN : int32_t type of status 900 * 0 -- success 901 * -1 -- failure 902 *==========================================================================*/ 903 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle, 904 uint32_t ch_id, uint32_t frame_idx) 905 { 906 int32_t rc = -1; 907 mm_camera_obj_t * my_obj = NULL; 908 909 CDBG("%s :E camera_handler = %d,ch_id = %d", 910 __func__, camera_handle, ch_id); 911 pthread_mutex_lock(&g_intf_lock); 912 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 913 914 if(my_obj) { 915 pthread_mutex_lock(&my_obj->cam_lock); 916 pthread_mutex_unlock(&g_intf_lock); 917 rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx); 918 } else { 919 pthread_mutex_unlock(&g_intf_lock); 920 } 921 CDBG("%s :X rc = %d", __func__, rc); 922 return rc; 923 } 924 925 /*=========================================================================== 926 * FUNCTION : mm_camera_intf_configure_notify_mode 927 * 928 * DESCRIPTION: Configures channel notification mode 929 * 930 * PARAMETERS : 931 * @camera_handle: camera handle 932 * @ch_id : channel handle 933 * @notify_mode : notification mode 934 * 935 * RETURN : int32_t type of status 936 * 0 -- success 937 * -1 -- failure 938 *==========================================================================*/ 939 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle, 940 uint32_t ch_id, 941 mm_camera_super_buf_notify_mode_t notify_mode) 942 { 943 int32_t rc = -1; 944 mm_camera_obj_t * my_obj = NULL; 945 946 CDBG("%s :E camera_handler = %d,ch_id = %d", 947 __func__, camera_handle, ch_id); 948 pthread_mutex_lock(&g_intf_lock); 949 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 950 951 if(my_obj) { 952 pthread_mutex_lock(&my_obj->cam_lock); 953 pthread_mutex_unlock(&g_intf_lock); 954 rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode); 955 } else { 956 pthread_mutex_unlock(&g_intf_lock); 957 } 958 CDBG("%s :X rc = %d", __func__, rc); 959 return rc; 960 } 961 962 /*=========================================================================== 963 * FUNCTION : mm_camera_intf_map_buf 964 * 965 * DESCRIPTION: mapping camera buffer via domain socket to server 966 * 967 * PARAMETERS : 968 * @camera_handle: camera handle 969 * @buf_type : type of buffer to be mapped. could be following values: 970 * CAM_MAPPING_BUF_TYPE_CAPABILITY 971 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 972 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 973 * @fd : file descriptor of the buffer 974 * @size : size of the buffer 975 * 976 * RETURN : int32_t type of status 977 * 0 -- success 978 * -1 -- failure 979 *==========================================================================*/ 980 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle, 981 uint8_t buf_type, 982 int fd, 983 uint32_t size) 984 { 985 int32_t rc = -1; 986 mm_camera_obj_t * my_obj = NULL; 987 988 pthread_mutex_lock(&g_intf_lock); 989 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 990 991 if(my_obj) { 992 pthread_mutex_lock(&my_obj->cam_lock); 993 pthread_mutex_unlock(&g_intf_lock); 994 rc = mm_camera_map_buf(my_obj, buf_type, fd, size); 995 } else { 996 pthread_mutex_unlock(&g_intf_lock); 997 } 998 return rc; 999 } 1000 1001 /*=========================================================================== 1002 * FUNCTION : mm_camera_intf_unmap_buf 1003 * 1004 * DESCRIPTION: unmapping camera buffer via domain socket to server 1005 * 1006 * PARAMETERS : 1007 * @camera_handle: camera handle 1008 * @buf_type : type of buffer to be unmapped. could be following values: 1009 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1010 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1011 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1012 * 1013 * RETURN : int32_t type of status 1014 * 0 -- success 1015 * -1 -- failure 1016 *==========================================================================*/ 1017 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle, 1018 uint8_t buf_type) 1019 { 1020 int32_t rc = -1; 1021 mm_camera_obj_t * my_obj = NULL; 1022 1023 pthread_mutex_lock(&g_intf_lock); 1024 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1025 1026 if(my_obj) { 1027 pthread_mutex_lock(&my_obj->cam_lock); 1028 pthread_mutex_unlock(&g_intf_lock); 1029 rc = mm_camera_unmap_buf(my_obj, buf_type); 1030 } else { 1031 pthread_mutex_unlock(&g_intf_lock); 1032 } 1033 return rc; 1034 } 1035 1036 /*=========================================================================== 1037 * FUNCTION : mm_camera_intf_set_stream_parms 1038 * 1039 * DESCRIPTION: set parameters per stream 1040 * 1041 * PARAMETERS : 1042 * @camera_handle: camera handle 1043 * @ch_id : channel handle 1044 * @s_id : stream handle 1045 * @parms : ptr to a param struct to be set to server 1046 * 1047 * RETURN : int32_t type of status 1048 * 0 -- success 1049 * -1 -- failure 1050 * NOTE : Assume the parms struct buf is already mapped to server via 1051 * domain socket. Corresponding fields of parameters to be set 1052 * are already filled in by upper layer caller. 1053 *==========================================================================*/ 1054 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle, 1055 uint32_t ch_id, 1056 uint32_t s_id, 1057 cam_stream_parm_buffer_t *parms) 1058 { 1059 int32_t rc = -1; 1060 mm_camera_obj_t * my_obj = NULL; 1061 1062 pthread_mutex_lock(&g_intf_lock); 1063 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1064 1065 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d", 1066 __func__, camera_handle, ch_id, s_id); 1067 1068 if(my_obj) { 1069 pthread_mutex_lock(&my_obj->cam_lock); 1070 pthread_mutex_unlock(&g_intf_lock); 1071 rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms); 1072 }else{ 1073 pthread_mutex_unlock(&g_intf_lock); 1074 } 1075 CDBG("%s :X rc = %d", __func__, rc); 1076 return rc; 1077 } 1078 1079 /*=========================================================================== 1080 * FUNCTION : mm_camera_intf_get_stream_parms 1081 * 1082 * DESCRIPTION: get parameters per stream 1083 * 1084 * PARAMETERS : 1085 * @camera_handle: camera handle 1086 * @ch_id : channel handle 1087 * @s_id : stream handle 1088 * @parms : ptr to a param struct to be get from server 1089 * 1090 * RETURN : int32_t type of status 1091 * 0 -- success 1092 * -1 -- failure 1093 * NOTE : Assume the parms struct buf is already mapped to server via 1094 * domain socket. Parameters to be get from server are already 1095 * filled in by upper layer caller. After this call, corresponding 1096 * fields of requested parameters will be filled in by server with 1097 * detailed information. 1098 *==========================================================================*/ 1099 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle, 1100 uint32_t ch_id, 1101 uint32_t s_id, 1102 cam_stream_parm_buffer_t *parms) 1103 { 1104 int32_t rc = -1; 1105 mm_camera_obj_t * my_obj = NULL; 1106 1107 pthread_mutex_lock(&g_intf_lock); 1108 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1109 1110 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d", 1111 __func__, camera_handle, ch_id, s_id); 1112 1113 if(my_obj) { 1114 pthread_mutex_lock(&my_obj->cam_lock); 1115 pthread_mutex_unlock(&g_intf_lock); 1116 rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms); 1117 }else{ 1118 pthread_mutex_unlock(&g_intf_lock); 1119 } 1120 1121 CDBG("%s :X rc = %d", __func__, rc); 1122 return rc; 1123 } 1124 1125 /*=========================================================================== 1126 * FUNCTION : mm_camera_intf_map_stream_buf 1127 * 1128 * DESCRIPTION: mapping stream buffer via domain socket to server 1129 * 1130 * PARAMETERS : 1131 * @camera_handle: camera handle 1132 * @ch_id : channel handle 1133 * @s_id : stream handle 1134 * @buf_type : type of buffer to be mapped. could be following values: 1135 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1136 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1137 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1138 * @buf_idx : index of buffer within the stream buffers, only valid if 1139 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1140 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1141 * @plane_idx : plane index. If all planes share the same fd, 1142 * plane_idx = -1; otherwise, plean_idx is the 1143 * index to plane (0..num_of_planes) 1144 * @fd : file descriptor of the buffer 1145 * @size : size of the buffer 1146 * 1147 * RETURN : int32_t type of status 1148 * 0 -- success 1149 * -1 -- failure 1150 *==========================================================================*/ 1151 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle, 1152 uint32_t ch_id, 1153 uint32_t stream_id, 1154 uint8_t buf_type, 1155 uint32_t buf_idx, 1156 int32_t plane_idx, 1157 int fd, 1158 uint32_t size) 1159 { 1160 int32_t rc = -1; 1161 mm_camera_obj_t * my_obj = NULL; 1162 1163 pthread_mutex_lock(&g_intf_lock); 1164 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1165 1166 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", 1167 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx); 1168 1169 if(my_obj) { 1170 pthread_mutex_lock(&my_obj->cam_lock); 1171 pthread_mutex_unlock(&g_intf_lock); 1172 rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id, 1173 buf_type, buf_idx, plane_idx, 1174 fd, size); 1175 }else{ 1176 pthread_mutex_unlock(&g_intf_lock); 1177 } 1178 1179 CDBG("%s :X rc = %d", __func__, rc); 1180 return rc; 1181 } 1182 1183 /*=========================================================================== 1184 * FUNCTION : mm_camera_intf_unmap_stream_buf 1185 * 1186 * DESCRIPTION: unmapping stream buffer via domain socket to server 1187 * 1188 * PARAMETERS : 1189 * @camera_handle: camera handle 1190 * @ch_id : channel handle 1191 * @s_id : stream handle 1192 * @buf_type : type of buffer to be unmapped. could be following values: 1193 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1194 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1195 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1196 * @buf_idx : index of buffer within the stream buffers, only valid if 1197 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1198 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1199 * @plane_idx : plane index. If all planes share the same fd, 1200 * plane_idx = -1; otherwise, plean_idx is the 1201 * index to plane (0..num_of_planes) 1202 * 1203 * RETURN : int32_t type of status 1204 * 0 -- success 1205 * -1 -- failure 1206 *==========================================================================*/ 1207 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle, 1208 uint32_t ch_id, 1209 uint32_t stream_id, 1210 uint8_t buf_type, 1211 uint32_t buf_idx, 1212 int32_t plane_idx) 1213 { 1214 int32_t rc = -1; 1215 mm_camera_obj_t * my_obj = NULL; 1216 1217 pthread_mutex_lock(&g_intf_lock); 1218 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1219 1220 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", 1221 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx); 1222 1223 if(my_obj) { 1224 pthread_mutex_lock(&my_obj->cam_lock); 1225 pthread_mutex_unlock(&g_intf_lock); 1226 rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id, 1227 buf_type, buf_idx, plane_idx); 1228 }else{ 1229 pthread_mutex_unlock(&g_intf_lock); 1230 } 1231 1232 CDBG("%s :X rc = %d", __func__, rc); 1233 return rc; 1234 } 1235 1236 /*=========================================================================== 1237 * FUNCTION : get_num_of_cameras 1238 * 1239 * DESCRIPTION: get number of cameras 1240 * 1241 * PARAMETERS : 1242 * 1243 * RETURN : number of cameras supported 1244 *==========================================================================*/ 1245 uint8_t get_num_of_cameras() 1246 { 1247 int rc = 0; 1248 int dev_fd = 0; 1249 struct media_device_info mdev_info; 1250 int num_media_devices = 0; 1251 uint8_t num_cameras = 0; 1252 1253 CDBG("%s : E", __func__); 1254 /* lock the mutex */ 1255 pthread_mutex_lock(&g_intf_lock); 1256 while (1) { 1257 char dev_name[32]; 1258 int num_entities; 1259 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 1260 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 1261 if (dev_fd <= 0) { 1262 CDBG("Done discovering media devices\n"); 1263 break; 1264 } 1265 num_media_devices++; 1266 memset(&mdev_info, 0, sizeof(mdev_info)); 1267 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 1268 if (rc < 0) { 1269 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 1270 close(dev_fd); 1271 dev_fd = 0; 1272 num_cameras = 0; 1273 break; 1274 } 1275 1276 if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) { 1277 close(dev_fd); 1278 dev_fd = 0; 1279 continue; 1280 } 1281 1282 num_entities = 1; 1283 while (1) { 1284 struct media_entity_desc entity; 1285 memset(&entity, 0, sizeof(entity)); 1286 entity.id = num_entities++; 1287 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 1288 if (rc < 0) { 1289 CDBG("Done enumerating media entities\n"); 1290 rc = 0; 1291 break; 1292 } 1293 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) { 1294 strncpy(g_cam_ctrl.video_dev_name[num_cameras], 1295 entity.name, sizeof(entity.name)); 1296 break; 1297 } 1298 } 1299 1300 CDBG("%s: dev_info[id=%d,name='%s']\n", 1301 __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]); 1302 1303 num_cameras++; 1304 close(dev_fd); 1305 dev_fd = 0; 1306 } 1307 g_cam_ctrl.num_cam = num_cameras; 1308 1309 /* unlock the mutex */ 1310 pthread_mutex_unlock(&g_intf_lock); 1311 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam); 1312 return g_cam_ctrl.num_cam; 1313 } 1314 1315 /* camera ops v-table */ 1316 static mm_camera_ops_t mm_camera_ops = { 1317 .query_capability = mm_camera_intf_query_capability, 1318 .register_event_notify = mm_camera_intf_register_event_notify, 1319 .close_camera = mm_camera_intf_close, 1320 .set_parms = mm_camera_intf_set_parms, 1321 .get_parms = mm_camera_intf_get_parms, 1322 .do_auto_focus = mm_camera_intf_do_auto_focus, 1323 .cancel_auto_focus = mm_camera_intf_cancel_auto_focus, 1324 .prepare_snapshot = mm_camera_intf_prepare_snapshot, 1325 .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot, 1326 .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot, 1327 .map_buf = mm_camera_intf_map_buf, 1328 .unmap_buf = mm_camera_intf_unmap_buf, 1329 .add_channel = mm_camera_intf_add_channel, 1330 .delete_channel = mm_camera_intf_del_channel, 1331 .get_bundle_info = mm_camera_intf_get_bundle_info, 1332 .add_stream = mm_camera_intf_add_stream, 1333 .delete_stream = mm_camera_intf_del_stream, 1334 .config_stream = mm_camera_intf_config_stream, 1335 .qbuf = mm_camera_intf_qbuf, 1336 .map_stream_buf = mm_camera_intf_map_stream_buf, 1337 .unmap_stream_buf = mm_camera_intf_unmap_stream_buf, 1338 .set_stream_parms = mm_camera_intf_set_stream_parms, 1339 .get_stream_parms = mm_camera_intf_get_stream_parms, 1340 .start_channel = mm_camera_intf_start_channel, 1341 .stop_channel = mm_camera_intf_stop_channel, 1342 .request_super_buf = mm_camera_intf_request_super_buf, 1343 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request, 1344 .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue, 1345 .configure_notify_mode = mm_camera_intf_configure_notify_mode 1346 }; 1347 1348 /*=========================================================================== 1349 * FUNCTION : camera_open 1350 * 1351 * DESCRIPTION: open a camera by camera index 1352 * 1353 * PARAMETERS : 1354 * @camera_idx : camera index. should within range of 0 to num_of_cameras 1355 * 1356 * RETURN : ptr to a virtual table containing camera handle and operation table. 1357 * NULL if failed. 1358 *==========================================================================*/ 1359 mm_camera_vtbl_t * camera_open(uint8_t camera_idx) 1360 { 1361 int32_t rc = 0; 1362 mm_camera_obj_t* cam_obj = NULL; 1363 1364 CDBG("%s: E camera_idx = %d\n", __func__, camera_idx); 1365 if (camera_idx >= g_cam_ctrl.num_cam) { 1366 CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx); 1367 return NULL; 1368 } 1369 1370 pthread_mutex_lock(&g_intf_lock); 1371 /* opened already */ 1372 if(NULL != g_cam_ctrl.cam_obj[camera_idx]) { 1373 /* Add reference */ 1374 g_cam_ctrl.cam_obj[camera_idx]->ref_count++; 1375 pthread_mutex_unlock(&g_intf_lock); 1376 CDBG("%s: opened alreadyn", __func__); 1377 return &g_cam_ctrl.cam_obj[camera_idx]->vtbl; 1378 } 1379 1380 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t)); 1381 if(NULL == cam_obj) { 1382 pthread_mutex_unlock(&g_intf_lock); 1383 CDBG("%s: no mem", __func__); 1384 return NULL; 1385 } 1386 1387 /* initialize camera obj */ 1388 memset(cam_obj, 0, sizeof(mm_camera_obj_t)); 1389 cam_obj->ref_count++; 1390 cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx); 1391 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */ 1392 cam_obj->vtbl.ops = &mm_camera_ops; 1393 pthread_mutex_init(&cam_obj->cam_lock, NULL); 1394 1395 rc = mm_camera_open(cam_obj); 1396 if(rc != 0) { 1397 CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc); 1398 pthread_mutex_destroy(&cam_obj->cam_lock); 1399 g_cam_ctrl.cam_obj[camera_idx] = NULL; 1400 free(cam_obj); 1401 cam_obj = NULL; 1402 pthread_mutex_unlock(&g_intf_lock); 1403 return NULL; 1404 }else{ 1405 CDBG("%s: Open succeded\n", __func__); 1406 g_cam_ctrl.cam_obj[camera_idx] = cam_obj; 1407 pthread_mutex_unlock(&g_intf_lock); 1408 return &cam_obj->vtbl; 1409 } 1410 } 1411