1 /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved. 2 * 3 * Redistribution and use in source and binary forms, with or without 4 * modification, are permitted provided that the following conditions are 5 * met: 6 * * Redistributions of source code must retain the above copyright 7 * notice, this list of conditions and the following disclaimer. 8 * * Redistributions in binary form must reproduce the above 9 * copyright notice, this list of conditions and the following 10 * disclaimer in the documentation and/or other materials provided 11 * with the distribution. 12 * * Neither the name of The Linux Foundation nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 */ 29 30 #include <pthread.h> 31 #include <errno.h> 32 #include <sys/ioctl.h> 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <fcntl.h> 36 #include <poll.h> 37 #include <linux/media.h> 38 #include <signal.h> 39 #include <media/msm_cam_sensor.h> 40 #include <cutils/properties.h> 41 #include <stdlib.h> 42 43 #include "mm_camera_dbg.h" 44 #include "mm_camera_interface.h" 45 #include "mm_camera_sock.h" 46 #include "mm_camera.h" 47 48 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER; 49 50 static mm_camera_ctrl_t g_cam_ctrl = {0, {{0}}, {0}, {{0}}}; 51 52 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER; 53 static uint16_t g_handler_history_count = 0; /* history count for handler */ 54 volatile uint32_t gMmCameraIntfLogLevel = 1; 55 56 /*=========================================================================== 57 * FUNCTION : mm_camera_util_generate_handler 58 * 59 * DESCRIPTION: utility function to generate handler for camera/channel/stream 60 * 61 * PARAMETERS : 62 * @index: index of the object to have handler 63 * 64 * RETURN : uint32_t type of handle that uniquely identify the object 65 *==========================================================================*/ 66 uint32_t mm_camera_util_generate_handler(uint8_t index) 67 { 68 uint32_t handler = 0; 69 pthread_mutex_lock(&g_handler_lock); 70 g_handler_history_count++; 71 if (0 == g_handler_history_count) { 72 g_handler_history_count++; 73 } 74 handler = g_handler_history_count; 75 handler = (handler<<8) | index; 76 pthread_mutex_unlock(&g_handler_lock); 77 return handler; 78 } 79 80 /*=========================================================================== 81 * FUNCTION : mm_camera_util_get_index_by_handler 82 * 83 * DESCRIPTION: utility function to get index from handle 84 * 85 * PARAMETERS : 86 * @handler: object handle 87 * 88 * RETURN : uint8_t type of index derived from handle 89 *==========================================================================*/ 90 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler) 91 { 92 return (handler&0x000000ff); 93 } 94 95 /*=========================================================================== 96 * FUNCTION : mm_camera_util_get_dev_name 97 * 98 * DESCRIPTION: utility function to get device name from camera handle 99 * 100 * PARAMETERS : 101 * @cam_handle: camera handle 102 * 103 * RETURN : char ptr to the device name stored in global variable 104 * NOTE : caller should not free the char ptr 105 *==========================================================================*/ 106 const char *mm_camera_util_get_dev_name(uint32_t cam_handle) 107 { 108 char *dev_name = NULL; 109 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle); 110 if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) { 111 dev_name = g_cam_ctrl.video_dev_name[cam_idx]; 112 } 113 return dev_name; 114 } 115 116 /*=========================================================================== 117 * FUNCTION : mm_camera_util_get_camera_by_handler 118 * 119 * DESCRIPTION: utility function to get camera object from camera handle 120 * 121 * PARAMETERS : 122 * @cam_handle: camera handle 123 * 124 * RETURN : ptr to the camera object stored in global variable 125 * NOTE : caller should not free the camera object ptr 126 *==========================================================================*/ 127 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle) 128 { 129 mm_camera_obj_t *cam_obj = NULL; 130 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle); 131 132 if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS && 133 (NULL != g_cam_ctrl.cam_obj[cam_idx]) && 134 (cam_handle == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) { 135 cam_obj = g_cam_ctrl.cam_obj[cam_idx]; 136 } 137 return cam_obj; 138 } 139 140 /*=========================================================================== 141 * FUNCTION : mm_camera_intf_query_capability 142 * 143 * DESCRIPTION: query camera capability 144 * 145 * PARAMETERS : 146 * @camera_handle: camera handle 147 * 148 * RETURN : int32_t type of status 149 * 0 -- success 150 * -1 -- failure 151 *==========================================================================*/ 152 static int32_t mm_camera_intf_query_capability(uint32_t camera_handle) 153 { 154 int32_t rc = -1; 155 mm_camera_obj_t * my_obj = NULL; 156 157 CDBG("%s E: camera_handler = %d ", __func__, camera_handle); 158 159 pthread_mutex_lock(&g_intf_lock); 160 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 161 162 if(my_obj) { 163 pthread_mutex_lock(&my_obj->cam_lock); 164 pthread_mutex_unlock(&g_intf_lock); 165 rc = mm_camera_query_capability(my_obj); 166 } else { 167 pthread_mutex_unlock(&g_intf_lock); 168 } 169 CDBG("%s :X rc = %d", __func__, rc); 170 return rc; 171 } 172 173 /*=========================================================================== 174 * FUNCTION : mm_camera_intf_set_parms 175 * 176 * DESCRIPTION: set parameters per camera 177 * 178 * PARAMETERS : 179 * @camera_handle: camera handle 180 * @parms : ptr to a param struct to be set to server 181 * 182 * RETURN : int32_t type of status 183 * 0 -- success 184 * -1 -- failure 185 * NOTE : Assume the parms struct buf is already mapped to server via 186 * domain socket. Corresponding fields of parameters to be set 187 * are already filled in by upper layer caller. 188 *==========================================================================*/ 189 static int32_t mm_camera_intf_set_parms(uint32_t camera_handle, 190 parm_buffer_t *parms) 191 { 192 int32_t rc = -1; 193 mm_camera_obj_t * my_obj = NULL; 194 195 pthread_mutex_lock(&g_intf_lock); 196 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 197 198 if(my_obj) { 199 pthread_mutex_lock(&my_obj->cam_lock); 200 pthread_mutex_unlock(&g_intf_lock); 201 rc = mm_camera_set_parms(my_obj, parms); 202 } else { 203 pthread_mutex_unlock(&g_intf_lock); 204 } 205 return rc; 206 } 207 208 /*=========================================================================== 209 * FUNCTION : mm_camera_intf_get_parms 210 * 211 * DESCRIPTION: get parameters per camera 212 * 213 * PARAMETERS : 214 * @camera_handle: camera handle 215 * @parms : ptr to a param struct to be get from server 216 * 217 * RETURN : int32_t type of status 218 * 0 -- success 219 * -1 -- failure 220 * NOTE : Assume the parms struct buf is already mapped to server via 221 * domain socket. Parameters to be get from server are already 222 * filled in by upper layer caller. After this call, corresponding 223 * fields of requested parameters will be filled in by server with 224 * detailed information. 225 *==========================================================================*/ 226 static int32_t mm_camera_intf_get_parms(uint32_t camera_handle, 227 parm_buffer_t *parms) 228 { 229 int32_t rc = -1; 230 mm_camera_obj_t * my_obj = NULL; 231 232 pthread_mutex_lock(&g_intf_lock); 233 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 234 235 if(my_obj) { 236 pthread_mutex_lock(&my_obj->cam_lock); 237 pthread_mutex_unlock(&g_intf_lock); 238 rc = mm_camera_get_parms(my_obj, parms); 239 } else { 240 pthread_mutex_unlock(&g_intf_lock); 241 } 242 return rc; 243 } 244 245 /*=========================================================================== 246 * FUNCTION : mm_camera_intf_do_auto_focus 247 * 248 * DESCRIPTION: performing auto focus 249 * 250 * PARAMETERS : 251 * @camera_handle: camera handle 252 * 253 * RETURN : int32_t type of status 254 * 0 -- success 255 * -1 -- failure 256 * NOTE : if this call success, we will always assume there will 257 * be an auto_focus event following up. 258 *==========================================================================*/ 259 static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle) 260 { 261 int32_t rc = -1; 262 mm_camera_obj_t * my_obj = NULL; 263 264 pthread_mutex_lock(&g_intf_lock); 265 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 266 267 if(my_obj) { 268 pthread_mutex_lock(&my_obj->cam_lock); 269 pthread_mutex_unlock(&g_intf_lock); 270 rc = mm_camera_do_auto_focus(my_obj); 271 } else { 272 pthread_mutex_unlock(&g_intf_lock); 273 } 274 return rc; 275 } 276 277 /*=========================================================================== 278 * FUNCTION : mm_camera_intf_cancel_auto_focus 279 * 280 * DESCRIPTION: cancel auto focus 281 * 282 * PARAMETERS : 283 * @camera_handle: camera handle 284 * 285 * RETURN : int32_t type of status 286 * 0 -- success 287 * -1 -- failure 288 *==========================================================================*/ 289 static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle) 290 { 291 int32_t rc = -1; 292 mm_camera_obj_t * my_obj = NULL; 293 294 pthread_mutex_lock(&g_intf_lock); 295 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 296 297 if(my_obj) { 298 pthread_mutex_lock(&my_obj->cam_lock); 299 pthread_mutex_unlock(&g_intf_lock); 300 rc = mm_camera_cancel_auto_focus(my_obj); 301 } else { 302 pthread_mutex_unlock(&g_intf_lock); 303 } 304 return rc; 305 } 306 307 /*=========================================================================== 308 * FUNCTION : mm_camera_intf_prepare_snapshot 309 * 310 * DESCRIPTION: prepare hardware for snapshot 311 * 312 * PARAMETERS : 313 * @camera_handle: camera handle 314 * @do_af_flag : flag indicating if AF is needed 315 * 316 * RETURN : int32_t type of status 317 * 0 -- success 318 * -1 -- failure 319 *==========================================================================*/ 320 static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle, 321 int32_t do_af_flag) 322 { 323 int32_t rc = -1; 324 mm_camera_obj_t * my_obj = NULL; 325 326 pthread_mutex_lock(&g_intf_lock); 327 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 328 329 if(my_obj) { 330 pthread_mutex_lock(&my_obj->cam_lock); 331 pthread_mutex_unlock(&g_intf_lock); 332 rc = mm_camera_prepare_snapshot(my_obj, do_af_flag); 333 } else { 334 pthread_mutex_unlock(&g_intf_lock); 335 } 336 return rc; 337 } 338 339 /*=========================================================================== 340 * FUNCTION : mm_camera_intf_close 341 * 342 * DESCRIPTION: close a camera by its handle 343 * 344 * PARAMETERS : 345 * @camera_handle: camera handle 346 * 347 * RETURN : int32_t type of status 348 * 0 -- success 349 * -1 -- failure 350 *==========================================================================*/ 351 static int32_t mm_camera_intf_close(uint32_t camera_handle) 352 { 353 int32_t rc = -1; 354 uint8_t cam_idx = camera_handle & 0x00ff; 355 mm_camera_obj_t * my_obj = NULL; 356 357 CDBG("%s E: camera_handler = %d ", __func__, camera_handle); 358 359 pthread_mutex_lock(&g_intf_lock); 360 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 361 362 if (my_obj){ 363 my_obj->ref_count--; 364 365 if(my_obj->ref_count > 0) { 366 /* still have reference to obj, return here */ 367 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count); 368 pthread_mutex_unlock(&g_intf_lock); 369 rc = 0; 370 } else { 371 /* need close camera here as no other reference 372 * first empty g_cam_ctrl's referent to cam_obj */ 373 g_cam_ctrl.cam_obj[cam_idx] = NULL; 374 375 pthread_mutex_lock(&my_obj->cam_lock); 376 pthread_mutex_unlock(&g_intf_lock); 377 378 rc = mm_camera_close(my_obj); 379 380 pthread_mutex_destroy(&my_obj->cam_lock); 381 free(my_obj); 382 } 383 } else { 384 pthread_mutex_unlock(&g_intf_lock); 385 } 386 387 return rc; 388 } 389 390 /*=========================================================================== 391 * FUNCTION : mm_camera_intf_add_channel 392 * 393 * DESCRIPTION: add a channel 394 * 395 * PARAMETERS : 396 * @camera_handle: camera handle 397 * @attr : bundle attribute of the channel if needed 398 * @channel_cb : callback function for bundle data notify 399 * @userdata : user data ptr 400 * 401 * RETURN : uint32_t type of channel handle 402 * 0 -- invalid channel handle, meaning the op failed 403 * >0 -- successfully added a channel with a valid handle 404 * NOTE : if no bundle data notify is needed, meaning each stream in the 405 * channel will have its own stream data notify callback, then 406 * attr, channel_cb, and userdata can be NULL. In this case, 407 * no matching logic will be performed in channel for the bundling. 408 *==========================================================================*/ 409 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle, 410 mm_camera_channel_attr_t *attr, 411 mm_camera_buf_notify_t channel_cb, 412 void *userdata) 413 { 414 uint32_t ch_id = 0; 415 mm_camera_obj_t * my_obj = NULL; 416 417 CDBG("%s :E camera_handler = %d", __func__, camera_handle); 418 pthread_mutex_lock(&g_intf_lock); 419 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 420 421 if(my_obj) { 422 pthread_mutex_lock(&my_obj->cam_lock); 423 pthread_mutex_unlock(&g_intf_lock); 424 ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata); 425 } else { 426 pthread_mutex_unlock(&g_intf_lock); 427 } 428 CDBG("%s :X ch_id = %d", __func__, ch_id); 429 return ch_id; 430 } 431 432 /*=========================================================================== 433 * FUNCTION : mm_camera_intf_del_channel 434 * 435 * DESCRIPTION: delete a channel by its handle 436 * 437 * PARAMETERS : 438 * @camera_handle: camera handle 439 * @ch_id : channel handle 440 * 441 * RETURN : int32_t type of status 442 * 0 -- success 443 * -1 -- failure 444 * NOTE : all streams in the channel should be stopped already before 445 * this channel can be deleted. 446 *==========================================================================*/ 447 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle, 448 uint32_t ch_id) 449 { 450 int32_t rc = -1; 451 mm_camera_obj_t * my_obj = NULL; 452 453 CDBG("%s :E ch_id = %d", __func__, ch_id); 454 pthread_mutex_lock(&g_intf_lock); 455 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 456 457 if(my_obj) { 458 pthread_mutex_lock(&my_obj->cam_lock); 459 pthread_mutex_unlock(&g_intf_lock); 460 rc = mm_camera_del_channel(my_obj, ch_id); 461 } else { 462 pthread_mutex_unlock(&g_intf_lock); 463 } 464 CDBG("%s :X", __func__); 465 return rc; 466 } 467 468 /*=========================================================================== 469 * FUNCTION : mm_camera_intf_get_bundle_info 470 * 471 * DESCRIPTION: query bundle info of the channel 472 * 473 * PARAMETERS : 474 * @camera_handle: camera handle 475 * @ch_id : channel handle 476 * @bundle_info : bundle info to be filled in 477 * 478 * RETURN : int32_t type of status 479 * 0 -- success 480 * -1 -- failure 481 * NOTE : all streams in the channel should be stopped already before 482 * this channel can be deleted. 483 *==========================================================================*/ 484 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle, 485 uint32_t ch_id, 486 cam_bundle_config_t *bundle_info) 487 { 488 int32_t rc = -1; 489 mm_camera_obj_t * my_obj = NULL; 490 491 CDBG("%s :E ch_id = %d", __func__, ch_id); 492 pthread_mutex_lock(&g_intf_lock); 493 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 494 495 if(my_obj) { 496 pthread_mutex_lock(&my_obj->cam_lock); 497 pthread_mutex_unlock(&g_intf_lock); 498 rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info); 499 } else { 500 pthread_mutex_unlock(&g_intf_lock); 501 } 502 CDBG("%s :X", __func__); 503 return rc; 504 } 505 506 /*=========================================================================== 507 * FUNCTION : mm_camera_intf_register_event_notify 508 * 509 * DESCRIPTION: register for event notify 510 * 511 * PARAMETERS : 512 * @camera_handle: camera handle 513 * @evt_cb : callback for event notify 514 * @user_data : user data ptr 515 * 516 * RETURN : int32_t type of status 517 * 0 -- success 518 * -1 -- failure 519 *==========================================================================*/ 520 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle, 521 mm_camera_event_notify_t evt_cb, 522 void * user_data) 523 { 524 int32_t rc = -1; 525 mm_camera_obj_t * my_obj = NULL; 526 527 CDBG("%s :E ", __func__); 528 pthread_mutex_lock(&g_intf_lock); 529 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 530 531 if(my_obj) { 532 pthread_mutex_lock(&my_obj->cam_lock); 533 pthread_mutex_unlock(&g_intf_lock); 534 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data); 535 } else { 536 pthread_mutex_unlock(&g_intf_lock); 537 } 538 CDBG("%s :E rc = %d", __func__, rc); 539 return rc; 540 } 541 542 /*=========================================================================== 543 * FUNCTION : mm_camera_intf_qbuf 544 * 545 * DESCRIPTION: enqueue buffer back to kernel 546 * 547 * PARAMETERS : 548 * @camera_handle: camera handle 549 * @ch_id : channel handle 550 * @buf : buf ptr to be enqueued 551 * 552 * RETURN : int32_t type of status 553 * 0 -- success 554 * -1 -- failure 555 *==========================================================================*/ 556 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle, 557 uint32_t ch_id, 558 mm_camera_buf_def_t *buf) 559 { 560 int32_t rc = -1; 561 mm_camera_obj_t * my_obj = NULL; 562 563 pthread_mutex_lock(&g_intf_lock); 564 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 565 566 if(my_obj) { 567 pthread_mutex_lock(&my_obj->cam_lock); 568 pthread_mutex_unlock(&g_intf_lock); 569 rc = mm_camera_qbuf(my_obj, ch_id, buf); 570 } else { 571 pthread_mutex_unlock(&g_intf_lock); 572 } 573 CDBG("%s :X evt_type = %d",__func__,rc); 574 return rc; 575 } 576 577 /*=========================================================================== 578 * FUNCTION : mm_camera_intf_add_stream 579 * 580 * DESCRIPTION: add a stream into a channel 581 * 582 * PARAMETERS : 583 * @camera_handle: camera handle 584 * @ch_id : channel handle 585 * 586 * RETURN : uint32_t type of stream handle 587 * 0 -- invalid stream handle, meaning the op failed 588 * >0 -- successfully added a stream with a valid handle 589 *==========================================================================*/ 590 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle, 591 uint32_t ch_id) 592 { 593 uint32_t stream_id = 0; 594 mm_camera_obj_t * my_obj = NULL; 595 596 CDBG("%s : E handle = %d ch_id = %d", 597 __func__, camera_handle, ch_id); 598 599 pthread_mutex_lock(&g_intf_lock); 600 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 601 602 if(my_obj) { 603 pthread_mutex_lock(&my_obj->cam_lock); 604 pthread_mutex_unlock(&g_intf_lock); 605 stream_id = mm_camera_add_stream(my_obj, ch_id); 606 } else { 607 pthread_mutex_unlock(&g_intf_lock); 608 } 609 CDBG("%s :X stream_id = %d", __func__, stream_id); 610 return stream_id; 611 } 612 613 /*=========================================================================== 614 * FUNCTION : mm_camera_intf_del_stream 615 * 616 * DESCRIPTION: delete a stream by its handle 617 * 618 * PARAMETERS : 619 * @camera_handle: camera handle 620 * @ch_id : channel handle 621 * @stream_id : stream handle 622 * 623 * RETURN : int32_t type of status 624 * 0 -- success 625 * -1 -- failure 626 * NOTE : stream should be stopped already before it can be deleted. 627 *==========================================================================*/ 628 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle, 629 uint32_t ch_id, 630 uint32_t stream_id) 631 { 632 int32_t rc = -1; 633 mm_camera_obj_t * my_obj = NULL; 634 635 CDBG("%s : E handle = %d ch_id = %d stream_id = %d", 636 __func__, camera_handle, ch_id, stream_id); 637 638 pthread_mutex_lock(&g_intf_lock); 639 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 640 641 if(my_obj) { 642 pthread_mutex_lock(&my_obj->cam_lock); 643 pthread_mutex_unlock(&g_intf_lock); 644 rc = mm_camera_del_stream(my_obj, ch_id, stream_id); 645 } else { 646 pthread_mutex_unlock(&g_intf_lock); 647 } 648 CDBG("%s :X rc = %d", __func__, rc); 649 return rc; 650 } 651 652 /*=========================================================================== 653 * FUNCTION : mm_camera_intf_config_stream 654 * 655 * DESCRIPTION: configure a stream 656 * 657 * PARAMETERS : 658 * @camera_handle: camera handle 659 * @ch_id : channel handle 660 * @stream_id : stream handle 661 * @config : stream configuration 662 * 663 * RETURN : int32_t type of status 664 * 0 -- success 665 * -1 -- failure 666 *==========================================================================*/ 667 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle, 668 uint32_t ch_id, 669 uint32_t stream_id, 670 mm_camera_stream_config_t *config) 671 { 672 int32_t rc = -1; 673 mm_camera_obj_t * my_obj = NULL; 674 675 CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d", 676 __func__, camera_handle, ch_id, stream_id); 677 678 pthread_mutex_lock(&g_intf_lock); 679 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 680 681 CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id); 682 683 if(my_obj) { 684 pthread_mutex_lock(&my_obj->cam_lock); 685 pthread_mutex_unlock(&g_intf_lock); 686 rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config); 687 } else { 688 pthread_mutex_unlock(&g_intf_lock); 689 } 690 CDBG("%s :X rc = %d", __func__, rc); 691 return rc; 692 } 693 694 /*=========================================================================== 695 * FUNCTION : mm_camera_intf_start_channel 696 * 697 * DESCRIPTION: start a channel, which will start all streams in the channel 698 * 699 * PARAMETERS : 700 * @camera_handle: camera handle 701 * @ch_id : channel handle 702 * 703 * RETURN : int32_t type of status 704 * 0 -- success 705 * -1 -- failure 706 *==========================================================================*/ 707 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle, 708 uint32_t ch_id) 709 { 710 int32_t rc = -1; 711 mm_camera_obj_t * my_obj = NULL; 712 713 pthread_mutex_lock(&g_intf_lock); 714 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 715 716 if(my_obj) { 717 pthread_mutex_lock(&my_obj->cam_lock); 718 pthread_mutex_unlock(&g_intf_lock); 719 rc = mm_camera_start_channel(my_obj, ch_id); 720 } else { 721 pthread_mutex_unlock(&g_intf_lock); 722 } 723 CDBG("%s :X rc = %d", __func__, rc); 724 return rc; 725 } 726 727 /*=========================================================================== 728 * FUNCTION : mm_camera_intf_stop_channel 729 * 730 * DESCRIPTION: stop a channel, which will stop all streams in the channel 731 * 732 * PARAMETERS : 733 * @camera_handle: camera handle 734 * @ch_id : channel handle 735 * 736 * RETURN : int32_t type of status 737 * 0 -- success 738 * -1 -- failure 739 *==========================================================================*/ 740 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle, 741 uint32_t ch_id) 742 { 743 int32_t rc = -1; 744 mm_camera_obj_t * my_obj = NULL; 745 746 pthread_mutex_lock(&g_intf_lock); 747 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 748 749 if(my_obj) { 750 pthread_mutex_lock(&my_obj->cam_lock); 751 pthread_mutex_unlock(&g_intf_lock); 752 rc = mm_camera_stop_channel(my_obj, ch_id); 753 } else { 754 pthread_mutex_unlock(&g_intf_lock); 755 } 756 CDBG("%s :X rc = %d", __func__, rc); 757 return rc; 758 } 759 760 /*=========================================================================== 761 * FUNCTION : mm_camera_intf_request_super_buf 762 * 763 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched 764 * frames from superbuf queue 765 * 766 * PARAMETERS : 767 * @camera_handle: camera handle 768 * @ch_id : channel handle 769 * @num_buf_requested : number of matched frames needed 770 * 771 * RETURN : int32_t type of status 772 * 0 -- success 773 * -1 -- failure 774 *==========================================================================*/ 775 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle, 776 uint32_t ch_id, 777 uint32_t num_buf_requested, 778 uint32_t num_retro_buf_requested) 779 { 780 int32_t rc = -1; 781 CDBG("%s :E camera_handler = %d,ch_id = %d", 782 __func__, camera_handle, ch_id); 783 mm_camera_obj_t * my_obj = NULL; 784 785 pthread_mutex_lock(&g_intf_lock); 786 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 787 788 if(my_obj) { 789 pthread_mutex_lock(&my_obj->cam_lock); 790 pthread_mutex_unlock(&g_intf_lock); 791 rc = mm_camera_request_super_buf (my_obj, ch_id, 792 num_buf_requested, num_retro_buf_requested); 793 } else { 794 pthread_mutex_unlock(&g_intf_lock); 795 } 796 CDBG("%s :X rc = %d", __func__, rc); 797 return rc; 798 } 799 800 /*=========================================================================== 801 * FUNCTION : mm_camera_intf_cancel_super_buf_request 802 * 803 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount 804 * of matched frames from superbuf queue 805 * 806 * PARAMETERS : 807 * @camera_handle: camera handle 808 * @ch_id : channel handle 809 * 810 * RETURN : int32_t type of status 811 * 0 -- success 812 * -1 -- failure 813 *==========================================================================*/ 814 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle, 815 uint32_t ch_id) 816 { 817 int32_t rc = -1; 818 mm_camera_obj_t * my_obj = NULL; 819 820 CDBG("%s :E camera_handler = %d,ch_id = %d", 821 __func__, camera_handle, ch_id); 822 pthread_mutex_lock(&g_intf_lock); 823 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 824 825 if(my_obj) { 826 pthread_mutex_lock(&my_obj->cam_lock); 827 pthread_mutex_unlock(&g_intf_lock); 828 rc = mm_camera_cancel_super_buf_request(my_obj, ch_id); 829 } else { 830 pthread_mutex_unlock(&g_intf_lock); 831 } 832 CDBG("%s :X rc = %d", __func__, rc); 833 return rc; 834 } 835 836 /*=========================================================================== 837 * FUNCTION : mm_camera_intf_flush_super_buf_queue 838 * 839 * DESCRIPTION: flush out all frames in the superbuf queue 840 * 841 * PARAMETERS : 842 * @camera_handle: camera handle 843 * @ch_id : channel handle 844 * @frame_idx : frame index 845 * 846 * RETURN : int32_t type of status 847 * 0 -- success 848 * -1 -- failure 849 *==========================================================================*/ 850 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle, 851 uint32_t ch_id, uint32_t frame_idx) 852 { 853 int32_t rc = -1; 854 mm_camera_obj_t * my_obj = NULL; 855 856 CDBG("%s :E camera_handler = %d,ch_id = %d", 857 __func__, camera_handle, ch_id); 858 pthread_mutex_lock(&g_intf_lock); 859 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 860 861 if(my_obj) { 862 pthread_mutex_lock(&my_obj->cam_lock); 863 pthread_mutex_unlock(&g_intf_lock); 864 rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx); 865 } else { 866 pthread_mutex_unlock(&g_intf_lock); 867 } 868 CDBG("%s :X rc = %d", __func__, rc); 869 return rc; 870 } 871 872 /*=========================================================================== 873 * FUNCTION : mm_camera_intf_start_zsl_snapshot 874 * 875 * DESCRIPTION: Starts zsl snapshot 876 * 877 * PARAMETERS : 878 * @camera_handle: camera handle 879 * @ch_id : channel handle 880 * 881 * RETURN : int32_t type of status 882 * 0 -- success 883 * -1 -- failure 884 *==========================================================================*/ 885 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle, 886 uint32_t ch_id) 887 { 888 int32_t rc = -1; 889 mm_camera_obj_t * my_obj = NULL; 890 891 CDBG("%s :E camera_handler = %d,ch_id = %d", 892 __func__, camera_handle, ch_id); 893 pthread_mutex_lock(&g_intf_lock); 894 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 895 896 if(my_obj) { 897 pthread_mutex_lock(&my_obj->cam_lock); 898 pthread_mutex_unlock(&g_intf_lock); 899 rc = mm_camera_start_zsl_snapshot_ch(my_obj, ch_id); 900 } else { 901 pthread_mutex_unlock(&g_intf_lock); 902 } 903 CDBG("%s :X rc = %d", __func__, rc); 904 return rc; 905 } 906 907 /*=========================================================================== 908 * FUNCTION : mm_camera_intf_stop_zsl_snapshot 909 * 910 * DESCRIPTION: Stops zsl snapshot 911 * 912 * PARAMETERS : 913 * @camera_handle: camera handle 914 * @ch_id : channel handle 915 * 916 * RETURN : int32_t type of status 917 * 0 -- success 918 * -1 -- failure 919 *==========================================================================*/ 920 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle, 921 uint32_t ch_id) 922 { 923 int32_t rc = -1; 924 mm_camera_obj_t * my_obj = NULL; 925 926 CDBG("%s :E camera_handler = %d,ch_id = %d", 927 __func__, camera_handle, ch_id); 928 pthread_mutex_lock(&g_intf_lock); 929 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 930 931 if(my_obj) { 932 pthread_mutex_lock(&my_obj->cam_lock); 933 pthread_mutex_unlock(&g_intf_lock); 934 rc = mm_camera_stop_zsl_snapshot_ch(my_obj, ch_id); 935 } else { 936 pthread_mutex_unlock(&g_intf_lock); 937 } 938 CDBG("%s :X rc = %d", __func__, rc); 939 return rc; 940 } 941 942 /*=========================================================================== 943 * FUNCTION : mm_camera_intf_configure_notify_mode 944 * 945 * DESCRIPTION: Configures channel notification mode 946 * 947 * PARAMETERS : 948 * @camera_handle: camera handle 949 * @ch_id : channel handle 950 * @notify_mode : notification mode 951 * 952 * RETURN : int32_t type of status 953 * 0 -- success 954 * -1 -- failure 955 *==========================================================================*/ 956 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle, 957 uint32_t ch_id, 958 mm_camera_super_buf_notify_mode_t notify_mode) 959 { 960 int32_t rc = -1; 961 mm_camera_obj_t * my_obj = NULL; 962 963 CDBG("%s :E camera_handler = %d,ch_id = %d", 964 __func__, camera_handle, ch_id); 965 pthread_mutex_lock(&g_intf_lock); 966 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 967 968 if(my_obj) { 969 pthread_mutex_lock(&my_obj->cam_lock); 970 pthread_mutex_unlock(&g_intf_lock); 971 rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode); 972 } else { 973 pthread_mutex_unlock(&g_intf_lock); 974 } 975 CDBG("%s :X rc = %d", __func__, rc); 976 return rc; 977 } 978 979 /*=========================================================================== 980 * FUNCTION : mm_camera_intf_map_buf 981 * 982 * DESCRIPTION: mapping camera buffer via domain socket to server 983 * 984 * PARAMETERS : 985 * @camera_handle: camera handle 986 * @buf_type : type of buffer to be mapped. could be following values: 987 * CAM_MAPPING_BUF_TYPE_CAPABILITY 988 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 989 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 990 * @fd : file descriptor of the buffer 991 * @size : size of the buffer 992 * 993 * RETURN : int32_t type of status 994 * 0 -- success 995 * -1 -- failure 996 *==========================================================================*/ 997 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle, 998 uint8_t buf_type, 999 int fd, 1000 uint32_t size) 1001 { 1002 int32_t rc = -1; 1003 mm_camera_obj_t * my_obj = NULL; 1004 1005 pthread_mutex_lock(&g_intf_lock); 1006 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1007 1008 if(my_obj) { 1009 pthread_mutex_lock(&my_obj->cam_lock); 1010 pthread_mutex_unlock(&g_intf_lock); 1011 rc = mm_camera_map_buf(my_obj, buf_type, fd, size); 1012 } else { 1013 pthread_mutex_unlock(&g_intf_lock); 1014 } 1015 return rc; 1016 } 1017 1018 /*=========================================================================== 1019 * FUNCTION : mm_camera_intf_unmap_buf 1020 * 1021 * DESCRIPTION: unmapping camera buffer via domain socket to server 1022 * 1023 * PARAMETERS : 1024 * @camera_handle: camera handle 1025 * @buf_type : type of buffer to be unmapped. could be following values: 1026 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1027 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1028 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1029 * 1030 * RETURN : int32_t type of status 1031 * 0 -- success 1032 * -1 -- failure 1033 *==========================================================================*/ 1034 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle, 1035 uint8_t buf_type) 1036 { 1037 int32_t rc = -1; 1038 mm_camera_obj_t * my_obj = NULL; 1039 1040 pthread_mutex_lock(&g_intf_lock); 1041 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1042 1043 if(my_obj) { 1044 pthread_mutex_lock(&my_obj->cam_lock); 1045 pthread_mutex_unlock(&g_intf_lock); 1046 rc = mm_camera_unmap_buf(my_obj, buf_type); 1047 } else { 1048 pthread_mutex_unlock(&g_intf_lock); 1049 } 1050 return rc; 1051 } 1052 1053 /*=========================================================================== 1054 * FUNCTION : mm_camera_intf_set_stream_parms 1055 * 1056 * DESCRIPTION: set parameters per stream 1057 * 1058 * PARAMETERS : 1059 * @camera_handle: camera handle 1060 * @ch_id : channel handle 1061 * @s_id : stream handle 1062 * @parms : ptr to a param struct to be set to server 1063 * 1064 * RETURN : int32_t type of status 1065 * 0 -- success 1066 * -1 -- failure 1067 * NOTE : Assume the parms struct buf is already mapped to server via 1068 * domain socket. Corresponding fields of parameters to be set 1069 * are already filled in by upper layer caller. 1070 *==========================================================================*/ 1071 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle, 1072 uint32_t ch_id, 1073 uint32_t s_id, 1074 cam_stream_parm_buffer_t *parms) 1075 { 1076 int32_t rc = -1; 1077 mm_camera_obj_t * my_obj = NULL; 1078 1079 pthread_mutex_lock(&g_intf_lock); 1080 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1081 1082 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d", 1083 __func__, camera_handle, ch_id, s_id); 1084 1085 if(my_obj) { 1086 pthread_mutex_lock(&my_obj->cam_lock); 1087 pthread_mutex_unlock(&g_intf_lock); 1088 rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms); 1089 }else{ 1090 pthread_mutex_unlock(&g_intf_lock); 1091 } 1092 CDBG("%s :X rc = %d", __func__, rc); 1093 return rc; 1094 } 1095 1096 /*=========================================================================== 1097 * FUNCTION : mm_camera_intf_get_stream_parms 1098 * 1099 * DESCRIPTION: get parameters per stream 1100 * 1101 * PARAMETERS : 1102 * @camera_handle: camera handle 1103 * @ch_id : channel handle 1104 * @s_id : stream handle 1105 * @parms : ptr to a param struct to be get from server 1106 * 1107 * RETURN : int32_t type of status 1108 * 0 -- success 1109 * -1 -- failure 1110 * NOTE : Assume the parms struct buf is already mapped to server via 1111 * domain socket. Parameters to be get from server are already 1112 * filled in by upper layer caller. After this call, corresponding 1113 * fields of requested parameters will be filled in by server with 1114 * detailed information. 1115 *==========================================================================*/ 1116 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle, 1117 uint32_t ch_id, 1118 uint32_t s_id, 1119 cam_stream_parm_buffer_t *parms) 1120 { 1121 int32_t rc = -1; 1122 mm_camera_obj_t * my_obj = NULL; 1123 1124 pthread_mutex_lock(&g_intf_lock); 1125 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1126 1127 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d", 1128 __func__, camera_handle, ch_id, s_id); 1129 1130 if(my_obj) { 1131 pthread_mutex_lock(&my_obj->cam_lock); 1132 pthread_mutex_unlock(&g_intf_lock); 1133 rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms); 1134 }else{ 1135 pthread_mutex_unlock(&g_intf_lock); 1136 } 1137 1138 CDBG("%s :X rc = %d", __func__, rc); 1139 return rc; 1140 } 1141 1142 /*=========================================================================== 1143 * FUNCTION : mm_camera_intf_map_stream_buf 1144 * 1145 * DESCRIPTION: mapping stream buffer via domain socket to server 1146 * 1147 * PARAMETERS : 1148 * @camera_handle: camera handle 1149 * @ch_id : channel handle 1150 * @s_id : stream handle 1151 * @buf_type : type of buffer to be mapped. could be following values: 1152 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1153 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1154 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1155 * @buf_idx : index of buffer within the stream buffers, only valid if 1156 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1157 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1158 * @plane_idx : plane index. If all planes share the same fd, 1159 * plane_idx = -1; otherwise, plean_idx is the 1160 * index to plane (0..num_of_planes) 1161 * @fd : file descriptor of the buffer 1162 * @size : size of the buffer 1163 * 1164 * RETURN : int32_t type of status 1165 * 0 -- success 1166 * -1 -- failure 1167 *==========================================================================*/ 1168 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle, 1169 uint32_t ch_id, 1170 uint32_t stream_id, 1171 uint8_t buf_type, 1172 uint32_t buf_idx, 1173 int32_t plane_idx, 1174 int fd, 1175 uint32_t size) 1176 { 1177 int32_t rc = -1; 1178 mm_camera_obj_t * my_obj = NULL; 1179 1180 pthread_mutex_lock(&g_intf_lock); 1181 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1182 1183 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", 1184 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx); 1185 1186 if(my_obj) { 1187 pthread_mutex_lock(&my_obj->cam_lock); 1188 pthread_mutex_unlock(&g_intf_lock); 1189 rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id, 1190 buf_type, buf_idx, plane_idx, 1191 fd, size); 1192 }else{ 1193 pthread_mutex_unlock(&g_intf_lock); 1194 } 1195 1196 CDBG("%s :X rc = %d", __func__, rc); 1197 return rc; 1198 } 1199 1200 /*=========================================================================== 1201 * FUNCTION : mm_camera_intf_unmap_stream_buf 1202 * 1203 * DESCRIPTION: unmapping stream buffer via domain socket to server 1204 * 1205 * PARAMETERS : 1206 * @camera_handle: camera handle 1207 * @ch_id : channel handle 1208 * @s_id : stream handle 1209 * @buf_type : type of buffer to be unmapped. could be following values: 1210 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1211 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1212 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1213 * @buf_idx : index of buffer within the stream buffers, only valid if 1214 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1215 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1216 * @plane_idx : plane index. If all planes share the same fd, 1217 * plane_idx = -1; otherwise, plean_idx is the 1218 * index to plane (0..num_of_planes) 1219 * 1220 * RETURN : int32_t type of status 1221 * 0 -- success 1222 * -1 -- failure 1223 *==========================================================================*/ 1224 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle, 1225 uint32_t ch_id, 1226 uint32_t stream_id, 1227 uint8_t buf_type, 1228 uint32_t buf_idx, 1229 int32_t plane_idx) 1230 { 1231 int32_t rc = -1; 1232 mm_camera_obj_t * my_obj = NULL; 1233 1234 pthread_mutex_lock(&g_intf_lock); 1235 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1236 1237 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", 1238 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx); 1239 1240 if(my_obj) { 1241 pthread_mutex_lock(&my_obj->cam_lock); 1242 pthread_mutex_unlock(&g_intf_lock); 1243 rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id, 1244 buf_type, buf_idx, plane_idx); 1245 }else{ 1246 pthread_mutex_unlock(&g_intf_lock); 1247 } 1248 1249 CDBG("%s :X rc = %d", __func__, rc); 1250 return rc; 1251 } 1252 1253 /*=========================================================================== 1254 * FUNCTION : get_sensor_info 1255 * 1256 * DESCRIPTION: get sensor info like facing(back/front) and mount angle 1257 * 1258 * PARAMETERS : 1259 * 1260 * RETURN : 1261 *==========================================================================*/ 1262 void get_sensor_info() 1263 { 1264 int rc = 0; 1265 int dev_fd = -1; 1266 struct media_device_info mdev_info; 1267 int num_media_devices = 0; 1268 uint8_t num_cameras = 0; 1269 1270 CDBG("%s : E", __func__); 1271 while (1) { 1272 char dev_name[32]; 1273 int num_entities; 1274 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 1275 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 1276 if (dev_fd < 0) { 1277 CDBG("Done discovering media devices\n"); 1278 break; 1279 } 1280 num_media_devices++; 1281 memset(&mdev_info, 0, sizeof(mdev_info)); 1282 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 1283 if (rc < 0) { 1284 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 1285 close(dev_fd); 1286 dev_fd = -1; 1287 num_cameras = 0; 1288 break; 1289 } 1290 1291 if(strncmp(mdev_info.model, MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) { 1292 close(dev_fd); 1293 dev_fd = -1; 1294 continue; 1295 } 1296 1297 num_entities = 1; 1298 while (1) { 1299 struct media_entity_desc entity; 1300 unsigned long temp; 1301 unsigned int mount_angle; 1302 unsigned int facing; 1303 1304 memset(&entity, 0, sizeof(entity)); 1305 entity.id = num_entities++; 1306 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 1307 if (rc < 0) { 1308 CDBG("Done enumerating media entities\n"); 1309 rc = 0; 1310 break; 1311 } 1312 if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV && 1313 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) { 1314 temp = entity.flags >> 8; 1315 mount_angle = (temp & 0xFF) * 90; 1316 facing = (temp >> 8); 1317 ALOGD("index = %d flag = %x mount_angle = %d facing = %d\n" 1318 , num_cameras, (unsigned int)temp, (unsigned int)mount_angle, 1319 (unsigned int)facing); 1320 g_cam_ctrl.info[num_cameras].facing = facing; 1321 g_cam_ctrl.info[num_cameras].orientation = mount_angle; 1322 num_cameras++; 1323 continue; 1324 } 1325 } 1326 1327 CDBG("%s: dev_info[id=%d,name='%s']\n", 1328 __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]); 1329 1330 close(dev_fd); 1331 dev_fd = -1; 1332 } 1333 1334 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam); 1335 return; 1336 } 1337 1338 /*=========================================================================== 1339 * FUNCTION : get_num_of_cameras 1340 * 1341 * DESCRIPTION: get number of cameras 1342 * 1343 * PARAMETERS : 1344 * 1345 * RETURN : number of cameras supported 1346 *==========================================================================*/ 1347 uint8_t get_num_of_cameras() 1348 { 1349 int rc = 0; 1350 int dev_fd = 0; 1351 struct media_device_info mdev_info; 1352 int num_media_devices = 0; 1353 uint8_t num_cameras = 0; 1354 char subdev_name[32]; 1355 int32_t sd_fd = 0; 1356 struct sensor_init_cfg_data cfg; 1357 char prop[PROPERTY_VALUE_MAX]; 1358 1359 property_get("persist.camera.logs", prop, "0"); 1360 gMmCameraIntfLogLevel = atoi(prop); 1361 1362 CDBG("%s : E", __func__); 1363 1364 int decrypt = property_get("vold.decrypt", prop, NULL); 1365 if (0 < decrypt) { 1366 if(strncmp(prop, "trigger_restart_min_framework", decrypt) == 0) { 1367 return 0; 1368 } 1369 } 1370 1371 /* lock the mutex */ 1372 pthread_mutex_lock(&g_intf_lock); 1373 1374 while (1) { 1375 int32_t num_entities = 1; 1376 char dev_name[32]; 1377 1378 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 1379 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 1380 if (dev_fd < 0) { 1381 CDBG("Done discovering media devices\n"); 1382 break; 1383 } 1384 num_media_devices++; 1385 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 1386 if (rc < 0) { 1387 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 1388 close(dev_fd); 1389 dev_fd = -1; 1390 break; 1391 } 1392 1393 if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME, 1394 sizeof(mdev_info.model)) != 0) { 1395 close(dev_fd); 1396 dev_fd = -1; 1397 continue; 1398 } 1399 1400 while (1) { 1401 struct media_entity_desc entity; 1402 memset(&entity, 0, sizeof(entity)); 1403 entity.id = num_entities++; 1404 CDBG_ERROR("entity id %d", entity.id); 1405 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 1406 if (rc < 0) { 1407 CDBG_ERROR("Done enumerating media entities"); 1408 rc = 0; 1409 break; 1410 } 1411 CDBG_ERROR("entity name %s type %d group id %d", 1412 entity.name, entity.type, entity.group_id); 1413 if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV && 1414 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) { 1415 snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name); 1416 break; 1417 } 1418 } 1419 close(dev_fd); 1420 dev_fd = -1; 1421 } 1422 1423 /* Open sensor_init subdev */ 1424 sd_fd = open(subdev_name, O_RDWR); 1425 if (sd_fd < 0) { 1426 CDBG_ERROR("Open sensor_init subdev failed"); 1427 return FALSE; 1428 } 1429 1430 cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE; 1431 cfg.cfg.setting = NULL; 1432 if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) { 1433 CDBG_ERROR("failed"); 1434 } 1435 close(sd_fd); 1436 dev_fd = -1; 1437 1438 1439 num_media_devices = 0; 1440 while (1) { 1441 char dev_name[32]; 1442 int num_entities; 1443 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 1444 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 1445 if (dev_fd < 0) { 1446 CDBG("Done discovering media devices: %s\n", strerror(errno)); 1447 break; 1448 } 1449 num_media_devices++; 1450 memset(&mdev_info, 0, sizeof(mdev_info)); 1451 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 1452 if (rc < 0) { 1453 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 1454 close(dev_fd); 1455 dev_fd = -1; 1456 num_cameras = 0; 1457 break; 1458 } 1459 1460 if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) { 1461 close(dev_fd); 1462 dev_fd = -1; 1463 continue; 1464 } 1465 1466 num_entities = 1; 1467 while (1) { 1468 struct media_entity_desc entity; 1469 memset(&entity, 0, sizeof(entity)); 1470 entity.id = num_entities++; 1471 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 1472 if (rc < 0) { 1473 CDBG("Done enumerating media entities\n"); 1474 rc = 0; 1475 break; 1476 } 1477 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) { 1478 strncpy(g_cam_ctrl.video_dev_name[num_cameras], 1479 entity.name, sizeof(entity.name)); 1480 break; 1481 } 1482 } 1483 1484 CDBG("%s: dev_info[id=%d,name='%s']\n", 1485 __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]); 1486 1487 num_cameras++; 1488 close(dev_fd); 1489 dev_fd = -1; 1490 } 1491 g_cam_ctrl.num_cam = num_cameras; 1492 1493 get_sensor_info(); 1494 /* unlock the mutex */ 1495 pthread_mutex_unlock(&g_intf_lock); 1496 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam); 1497 return g_cam_ctrl.num_cam; 1498 } 1499 1500 /*=========================================================================== 1501 * FUNCTION : mm_camera_intf_process_advanced_capture 1502 * 1503 * DESCRIPTION: Configures channel advanced capture mode 1504 * 1505 * PARAMETERS : 1506 * @camera_handle: camera handle 1507 * @advanced_capture_type : advanced capture type 1508 * @ch_id : channel handle 1509 * @notify_mode : notification mode 1510 * 1511 * RETURN : int32_t type of status 1512 * 0 -- success 1513 * -1 -- failure 1514 *==========================================================================*/ 1515 static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle, 1516 mm_camera_advanced_capture_t advanced_capture_type, 1517 uint32_t ch_id, 1518 int8_t start_flag) 1519 { 1520 int32_t rc = -1; 1521 mm_camera_obj_t * my_obj = NULL; 1522 1523 CDBG("%s: E camera_handler = %d,ch_id = %d", 1524 __func__, camera_handle, ch_id); 1525 pthread_mutex_lock(&g_intf_lock); 1526 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1527 1528 if(my_obj) { 1529 pthread_mutex_lock(&my_obj->cam_lock); 1530 pthread_mutex_unlock(&g_intf_lock); 1531 rc = mm_camera_channel_advanced_capture(my_obj, advanced_capture_type, ch_id, start_flag); 1532 } else { 1533 pthread_mutex_unlock(&g_intf_lock); 1534 } 1535 CDBG("%s: X ", __func__); 1536 return rc; 1537 } 1538 1539 struct camera_info *get_cam_info(int camera_id) 1540 { 1541 return &g_cam_ctrl.info[camera_id]; 1542 } 1543 1544 /* camera ops v-table */ 1545 static mm_camera_ops_t mm_camera_ops = { 1546 .query_capability = mm_camera_intf_query_capability, 1547 .register_event_notify = mm_camera_intf_register_event_notify, 1548 .close_camera = mm_camera_intf_close, 1549 .set_parms = mm_camera_intf_set_parms, 1550 .get_parms = mm_camera_intf_get_parms, 1551 .do_auto_focus = mm_camera_intf_do_auto_focus, 1552 .cancel_auto_focus = mm_camera_intf_cancel_auto_focus, 1553 .prepare_snapshot = mm_camera_intf_prepare_snapshot, 1554 .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot, 1555 .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot, 1556 .map_buf = mm_camera_intf_map_buf, 1557 .unmap_buf = mm_camera_intf_unmap_buf, 1558 .add_channel = mm_camera_intf_add_channel, 1559 .delete_channel = mm_camera_intf_del_channel, 1560 .get_bundle_info = mm_camera_intf_get_bundle_info, 1561 .add_stream = mm_camera_intf_add_stream, 1562 .delete_stream = mm_camera_intf_del_stream, 1563 .config_stream = mm_camera_intf_config_stream, 1564 .qbuf = mm_camera_intf_qbuf, 1565 .map_stream_buf = mm_camera_intf_map_stream_buf, 1566 .unmap_stream_buf = mm_camera_intf_unmap_stream_buf, 1567 .set_stream_parms = mm_camera_intf_set_stream_parms, 1568 .get_stream_parms = mm_camera_intf_get_stream_parms, 1569 .start_channel = mm_camera_intf_start_channel, 1570 .stop_channel = mm_camera_intf_stop_channel, 1571 .request_super_buf = mm_camera_intf_request_super_buf, 1572 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request, 1573 .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue, 1574 .configure_notify_mode = mm_camera_intf_configure_notify_mode, 1575 .process_advanced_capture = mm_camera_intf_process_advanced_capture 1576 }; 1577 1578 /*=========================================================================== 1579 * FUNCTION : camera_open 1580 * 1581 * DESCRIPTION: open a camera by camera index 1582 * 1583 * PARAMETERS : 1584 * @camera_idx : camera index. should within range of 0 to num_of_cameras 1585 * 1586 * RETURN : ptr to a virtual table containing camera handle and operation table. 1587 * NULL if failed. 1588 *==========================================================================*/ 1589 mm_camera_vtbl_t * camera_open(uint8_t camera_idx) 1590 { 1591 int32_t rc = 0; 1592 mm_camera_obj_t* cam_obj = NULL; 1593 1594 CDBG("%s: E camera_idx = %d\n", __func__, camera_idx); 1595 if (camera_idx >= g_cam_ctrl.num_cam) { 1596 CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx); 1597 return NULL; 1598 } 1599 1600 pthread_mutex_lock(&g_intf_lock); 1601 /* opened already */ 1602 if(NULL != g_cam_ctrl.cam_obj[camera_idx]) { 1603 /* Add reference */ 1604 g_cam_ctrl.cam_obj[camera_idx]->ref_count++; 1605 pthread_mutex_unlock(&g_intf_lock); 1606 CDBG("%s: opened alreadyn", __func__); 1607 return &g_cam_ctrl.cam_obj[camera_idx]->vtbl; 1608 } 1609 1610 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t)); 1611 if(NULL == cam_obj) { 1612 pthread_mutex_unlock(&g_intf_lock); 1613 CDBG("%s: no mem", __func__); 1614 return NULL; 1615 } 1616 1617 /* initialize camera obj */ 1618 memset(cam_obj, 0, sizeof(mm_camera_obj_t)); 1619 cam_obj->ctrl_fd = -1; 1620 cam_obj->ds_fd = -1; 1621 cam_obj->ref_count++; 1622 cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx); 1623 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */ 1624 cam_obj->vtbl.ops = &mm_camera_ops; 1625 pthread_mutex_init(&cam_obj->cam_lock, NULL); 1626 1627 rc = mm_camera_open(cam_obj); 1628 if(rc != 0) { 1629 CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc); 1630 pthread_mutex_destroy(&cam_obj->cam_lock); 1631 g_cam_ctrl.cam_obj[camera_idx] = NULL; 1632 free(cam_obj); 1633 cam_obj = NULL; 1634 pthread_mutex_unlock(&g_intf_lock); 1635 return NULL; 1636 }else{ 1637 CDBG("%s: Open succeded\n", __func__); 1638 g_cam_ctrl.cam_obj[camera_idx] = cam_obj; 1639 pthread_mutex_unlock(&g_intf_lock); 1640 return &cam_obj->vtbl; 1641 } 1642 } 1643