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_error_close 392 * 393 * DESCRIPTION: close the daemon after an unrecoverable error 394 * 395 * PARAMETERS : 396 * @camera_handle: camera handle 397 * 398 * RETURN : int32_t type of status 399 * 0 -- success 400 * -1 -- failure 401 *==========================================================================*/ 402 static int32_t mm_camera_intf_error_close(uint32_t camera_handle) 403 { 404 int32_t rc = -1; 405 mm_camera_obj_t * my_obj = NULL; 406 407 CDBG("%s E: camera_handler = %d ", __func__, camera_handle); 408 409 pthread_mutex_lock(&g_intf_lock); 410 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 411 412 if (my_obj){ 413 /*do not decrement the ref_count yet since that will happen during close*/ 414 if((my_obj->ref_count - 1) > 0) { 415 /* still have reference to obj, return here */ 416 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count); 417 pthread_mutex_unlock(&g_intf_lock); 418 rc = 0; 419 } else { 420 /* need close camera here as no other reference*/ 421 pthread_mutex_lock(&my_obj->cam_lock); 422 pthread_mutex_unlock(&g_intf_lock); 423 424 rc = mm_camera_close_fd(my_obj); 425 } 426 } else { 427 pthread_mutex_unlock(&g_intf_lock); 428 } 429 430 return rc; 431 } 432 433 /*=========================================================================== 434 * FUNCTION : mm_camera_intf_add_channel 435 * 436 * DESCRIPTION: add a channel 437 * 438 * PARAMETERS : 439 * @camera_handle: camera handle 440 * @attr : bundle attribute of the channel if needed 441 * @channel_cb : callback function for bundle data notify 442 * @userdata : user data ptr 443 * 444 * RETURN : uint32_t type of channel handle 445 * 0 -- invalid channel handle, meaning the op failed 446 * >0 -- successfully added a channel with a valid handle 447 * NOTE : if no bundle data notify is needed, meaning each stream in the 448 * channel will have its own stream data notify callback, then 449 * attr, channel_cb, and userdata can be NULL. In this case, 450 * no matching logic will be performed in channel for the bundling. 451 *==========================================================================*/ 452 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle, 453 mm_camera_channel_attr_t *attr, 454 mm_camera_buf_notify_t channel_cb, 455 void *userdata) 456 { 457 uint32_t ch_id = 0; 458 mm_camera_obj_t * my_obj = NULL; 459 460 CDBG("%s :E camera_handler = %d", __func__, camera_handle); 461 pthread_mutex_lock(&g_intf_lock); 462 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 463 464 if(my_obj) { 465 pthread_mutex_lock(&my_obj->cam_lock); 466 pthread_mutex_unlock(&g_intf_lock); 467 ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata); 468 } else { 469 pthread_mutex_unlock(&g_intf_lock); 470 } 471 CDBG("%s :X ch_id = %d", __func__, ch_id); 472 return ch_id; 473 } 474 475 /*=========================================================================== 476 * FUNCTION : mm_camera_intf_del_channel 477 * 478 * DESCRIPTION: delete a channel by its handle 479 * 480 * PARAMETERS : 481 * @camera_handle: camera handle 482 * @ch_id : channel handle 483 * 484 * RETURN : int32_t type of status 485 * 0 -- success 486 * -1 -- failure 487 * NOTE : all streams in the channel should be stopped already before 488 * this channel can be deleted. 489 *==========================================================================*/ 490 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle, 491 uint32_t ch_id) 492 { 493 int32_t rc = -1; 494 mm_camera_obj_t * my_obj = NULL; 495 496 CDBG("%s :E ch_id = %d", __func__, ch_id); 497 pthread_mutex_lock(&g_intf_lock); 498 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 499 500 if(my_obj) { 501 pthread_mutex_lock(&my_obj->cam_lock); 502 pthread_mutex_unlock(&g_intf_lock); 503 rc = mm_camera_del_channel(my_obj, ch_id); 504 } else { 505 pthread_mutex_unlock(&g_intf_lock); 506 } 507 CDBG("%s :X", __func__); 508 return rc; 509 } 510 511 /*=========================================================================== 512 * FUNCTION : mm_camera_intf_get_bundle_info 513 * 514 * DESCRIPTION: query bundle info of the channel 515 * 516 * PARAMETERS : 517 * @camera_handle: camera handle 518 * @ch_id : channel handle 519 * @bundle_info : bundle info to be filled in 520 * 521 * RETURN : int32_t type of status 522 * 0 -- success 523 * -1 -- failure 524 * NOTE : all streams in the channel should be stopped already before 525 * this channel can be deleted. 526 *==========================================================================*/ 527 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle, 528 uint32_t ch_id, 529 cam_bundle_config_t *bundle_info) 530 { 531 int32_t rc = -1; 532 mm_camera_obj_t * my_obj = NULL; 533 534 CDBG("%s :E ch_id = %d", __func__, ch_id); 535 pthread_mutex_lock(&g_intf_lock); 536 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 537 538 if(my_obj) { 539 pthread_mutex_lock(&my_obj->cam_lock); 540 pthread_mutex_unlock(&g_intf_lock); 541 rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info); 542 } else { 543 pthread_mutex_unlock(&g_intf_lock); 544 } 545 CDBG("%s :X", __func__); 546 return rc; 547 } 548 549 /*=========================================================================== 550 * FUNCTION : mm_camera_intf_register_event_notify 551 * 552 * DESCRIPTION: register for event notify 553 * 554 * PARAMETERS : 555 * @camera_handle: camera handle 556 * @evt_cb : callback for event notify 557 * @user_data : user data ptr 558 * 559 * RETURN : int32_t type of status 560 * 0 -- success 561 * -1 -- failure 562 *==========================================================================*/ 563 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle, 564 mm_camera_event_notify_t evt_cb, 565 void * user_data) 566 { 567 int32_t rc = -1; 568 mm_camera_obj_t * my_obj = NULL; 569 570 CDBG("%s :E ", __func__); 571 pthread_mutex_lock(&g_intf_lock); 572 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 573 574 if(my_obj) { 575 pthread_mutex_lock(&my_obj->cam_lock); 576 pthread_mutex_unlock(&g_intf_lock); 577 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data); 578 } else { 579 pthread_mutex_unlock(&g_intf_lock); 580 } 581 CDBG("%s :E rc = %d", __func__, rc); 582 return rc; 583 } 584 585 /*=========================================================================== 586 * FUNCTION : mm_camera_intf_qbuf 587 * 588 * DESCRIPTION: enqueue buffer back to kernel 589 * 590 * PARAMETERS : 591 * @camera_handle: camera handle 592 * @ch_id : channel handle 593 * @buf : buf ptr to be enqueued 594 * 595 * RETURN : int32_t type of status 596 * 0 -- success 597 * -1 -- failure 598 *==========================================================================*/ 599 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle, 600 uint32_t ch_id, 601 mm_camera_buf_def_t *buf) 602 { 603 int32_t rc = -1; 604 mm_camera_obj_t * my_obj = NULL; 605 606 pthread_mutex_lock(&g_intf_lock); 607 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 608 609 if(my_obj) { 610 pthread_mutex_lock(&my_obj->cam_lock); 611 pthread_mutex_unlock(&g_intf_lock); 612 rc = mm_camera_qbuf(my_obj, ch_id, buf); 613 } else { 614 pthread_mutex_unlock(&g_intf_lock); 615 } 616 CDBG("%s :X evt_type = %d",__func__,rc); 617 return rc; 618 } 619 620 /*=========================================================================== 621 * FUNCTION : mm_camera_intf_add_stream 622 * 623 * DESCRIPTION: add a stream into a channel 624 * 625 * PARAMETERS : 626 * @camera_handle: camera handle 627 * @ch_id : channel handle 628 * 629 * RETURN : uint32_t type of stream handle 630 * 0 -- invalid stream handle, meaning the op failed 631 * >0 -- successfully added a stream with a valid handle 632 *==========================================================================*/ 633 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle, 634 uint32_t ch_id) 635 { 636 uint32_t stream_id = 0; 637 mm_camera_obj_t * my_obj = NULL; 638 639 CDBG("%s : E handle = %d ch_id = %d", 640 __func__, camera_handle, ch_id); 641 642 pthread_mutex_lock(&g_intf_lock); 643 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 644 645 if(my_obj) { 646 pthread_mutex_lock(&my_obj->cam_lock); 647 pthread_mutex_unlock(&g_intf_lock); 648 stream_id = mm_camera_add_stream(my_obj, ch_id); 649 } else { 650 pthread_mutex_unlock(&g_intf_lock); 651 } 652 CDBG("%s :X stream_id = %d", __func__, stream_id); 653 return stream_id; 654 } 655 656 /*=========================================================================== 657 * FUNCTION : mm_camera_intf_del_stream 658 * 659 * DESCRIPTION: delete a stream by its handle 660 * 661 * PARAMETERS : 662 * @camera_handle: camera handle 663 * @ch_id : channel handle 664 * @stream_id : stream handle 665 * 666 * RETURN : int32_t type of status 667 * 0 -- success 668 * -1 -- failure 669 * NOTE : stream should be stopped already before it can be deleted. 670 *==========================================================================*/ 671 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle, 672 uint32_t ch_id, 673 uint32_t stream_id) 674 { 675 int32_t rc = -1; 676 mm_camera_obj_t * my_obj = NULL; 677 678 CDBG("%s : E handle = %d ch_id = %d stream_id = %d", 679 __func__, camera_handle, ch_id, stream_id); 680 681 pthread_mutex_lock(&g_intf_lock); 682 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 683 684 if(my_obj) { 685 pthread_mutex_lock(&my_obj->cam_lock); 686 pthread_mutex_unlock(&g_intf_lock); 687 rc = mm_camera_del_stream(my_obj, ch_id, stream_id); 688 } else { 689 pthread_mutex_unlock(&g_intf_lock); 690 } 691 CDBG("%s :X rc = %d", __func__, rc); 692 return rc; 693 } 694 695 /*=========================================================================== 696 * FUNCTION : mm_camera_intf_config_stream 697 * 698 * DESCRIPTION: configure a stream 699 * 700 * PARAMETERS : 701 * @camera_handle: camera handle 702 * @ch_id : channel handle 703 * @stream_id : stream handle 704 * @config : stream configuration 705 * 706 * RETURN : int32_t type of status 707 * 0 -- success 708 * -1 -- failure 709 *==========================================================================*/ 710 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle, 711 uint32_t ch_id, 712 uint32_t stream_id, 713 mm_camera_stream_config_t *config) 714 { 715 int32_t rc = -1; 716 mm_camera_obj_t * my_obj = NULL; 717 718 CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d", 719 __func__, camera_handle, ch_id, stream_id); 720 721 pthread_mutex_lock(&g_intf_lock); 722 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 723 724 CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id); 725 726 if(my_obj) { 727 pthread_mutex_lock(&my_obj->cam_lock); 728 pthread_mutex_unlock(&g_intf_lock); 729 rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config); 730 } else { 731 pthread_mutex_unlock(&g_intf_lock); 732 } 733 CDBG("%s :X rc = %d", __func__, rc); 734 return rc; 735 } 736 737 /*=========================================================================== 738 * FUNCTION : mm_camera_intf_start_channel 739 * 740 * DESCRIPTION: start a channel, which will start all streams in the channel 741 * 742 * PARAMETERS : 743 * @camera_handle: camera handle 744 * @ch_id : channel handle 745 * 746 * RETURN : int32_t type of status 747 * 0 -- success 748 * -1 -- failure 749 *==========================================================================*/ 750 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle, 751 uint32_t ch_id) 752 { 753 int32_t rc = -1; 754 mm_camera_obj_t * my_obj = NULL; 755 756 pthread_mutex_lock(&g_intf_lock); 757 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 758 759 if(my_obj) { 760 pthread_mutex_lock(&my_obj->cam_lock); 761 pthread_mutex_unlock(&g_intf_lock); 762 rc = mm_camera_start_channel(my_obj, ch_id); 763 } else { 764 pthread_mutex_unlock(&g_intf_lock); 765 } 766 CDBG("%s :X rc = %d", __func__, rc); 767 return rc; 768 } 769 770 /*=========================================================================== 771 * FUNCTION : mm_camera_intf_stop_channel 772 * 773 * DESCRIPTION: stop a channel, which will stop all streams in the channel 774 * 775 * PARAMETERS : 776 * @camera_handle: camera handle 777 * @ch_id : channel handle 778 * 779 * RETURN : int32_t type of status 780 * 0 -- success 781 * -1 -- failure 782 *==========================================================================*/ 783 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle, 784 uint32_t ch_id) 785 { 786 int32_t rc = -1; 787 mm_camera_obj_t * my_obj = NULL; 788 789 pthread_mutex_lock(&g_intf_lock); 790 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 791 792 if(my_obj) { 793 pthread_mutex_lock(&my_obj->cam_lock); 794 pthread_mutex_unlock(&g_intf_lock); 795 rc = mm_camera_stop_channel(my_obj, ch_id); 796 } else { 797 pthread_mutex_unlock(&g_intf_lock); 798 } 799 CDBG("%s :X rc = %d", __func__, rc); 800 return rc; 801 } 802 803 /*=========================================================================== 804 * FUNCTION : mm_camera_intf_request_super_buf 805 * 806 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched 807 * frames from superbuf queue 808 * 809 * PARAMETERS : 810 * @camera_handle: camera handle 811 * @ch_id : channel handle 812 * @num_buf_requested : number of matched frames needed 813 * 814 * RETURN : int32_t type of status 815 * 0 -- success 816 * -1 -- failure 817 *==========================================================================*/ 818 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle, 819 uint32_t ch_id, 820 uint32_t num_buf_requested, 821 uint32_t num_retro_buf_requested) 822 { 823 int32_t rc = -1; 824 CDBG("%s :E camera_handler = %d,ch_id = %d", 825 __func__, camera_handle, ch_id); 826 mm_camera_obj_t * my_obj = NULL; 827 828 pthread_mutex_lock(&g_intf_lock); 829 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 830 831 if(my_obj) { 832 pthread_mutex_lock(&my_obj->cam_lock); 833 pthread_mutex_unlock(&g_intf_lock); 834 rc = mm_camera_request_super_buf (my_obj, ch_id, 835 num_buf_requested, num_retro_buf_requested); 836 } else { 837 pthread_mutex_unlock(&g_intf_lock); 838 } 839 CDBG("%s :X rc = %d", __func__, rc); 840 return rc; 841 } 842 843 /*=========================================================================== 844 * FUNCTION : mm_camera_intf_cancel_super_buf_request 845 * 846 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount 847 * of matched frames from superbuf queue 848 * 849 * PARAMETERS : 850 * @camera_handle: camera handle 851 * @ch_id : channel handle 852 * 853 * RETURN : int32_t type of status 854 * 0 -- success 855 * -1 -- failure 856 *==========================================================================*/ 857 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle, 858 uint32_t ch_id) 859 { 860 int32_t rc = -1; 861 mm_camera_obj_t * my_obj = NULL; 862 863 CDBG("%s :E camera_handler = %d,ch_id = %d", 864 __func__, camera_handle, ch_id); 865 pthread_mutex_lock(&g_intf_lock); 866 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 867 868 if(my_obj) { 869 pthread_mutex_lock(&my_obj->cam_lock); 870 pthread_mutex_unlock(&g_intf_lock); 871 rc = mm_camera_cancel_super_buf_request(my_obj, ch_id); 872 } else { 873 pthread_mutex_unlock(&g_intf_lock); 874 } 875 CDBG("%s :X rc = %d", __func__, rc); 876 return rc; 877 } 878 879 /*=========================================================================== 880 * FUNCTION : mm_camera_intf_flush_super_buf_queue 881 * 882 * DESCRIPTION: flush out all frames in the superbuf queue 883 * 884 * PARAMETERS : 885 * @camera_handle: camera handle 886 * @ch_id : channel handle 887 * @frame_idx : frame index 888 * 889 * RETURN : int32_t type of status 890 * 0 -- success 891 * -1 -- failure 892 *==========================================================================*/ 893 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle, 894 uint32_t ch_id, uint32_t frame_idx) 895 { 896 int32_t rc = -1; 897 mm_camera_obj_t * my_obj = NULL; 898 899 CDBG("%s :E camera_handler = %d,ch_id = %d", 900 __func__, camera_handle, ch_id); 901 pthread_mutex_lock(&g_intf_lock); 902 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 903 904 if(my_obj) { 905 pthread_mutex_lock(&my_obj->cam_lock); 906 pthread_mutex_unlock(&g_intf_lock); 907 rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx); 908 } else { 909 pthread_mutex_unlock(&g_intf_lock); 910 } 911 CDBG("%s :X rc = %d", __func__, rc); 912 return rc; 913 } 914 915 /*=========================================================================== 916 * FUNCTION : mm_camera_intf_start_zsl_snapshot 917 * 918 * DESCRIPTION: Starts zsl snapshot 919 * 920 * PARAMETERS : 921 * @camera_handle: camera handle 922 * @ch_id : channel handle 923 * 924 * RETURN : int32_t type of status 925 * 0 -- success 926 * -1 -- failure 927 *==========================================================================*/ 928 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle, 929 uint32_t ch_id) 930 { 931 int32_t rc = -1; 932 mm_camera_obj_t * my_obj = NULL; 933 934 CDBG("%s :E camera_handler = %d,ch_id = %d", 935 __func__, camera_handle, ch_id); 936 pthread_mutex_lock(&g_intf_lock); 937 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 938 939 if(my_obj) { 940 pthread_mutex_lock(&my_obj->cam_lock); 941 pthread_mutex_unlock(&g_intf_lock); 942 rc = mm_camera_start_zsl_snapshot_ch(my_obj, ch_id); 943 } else { 944 pthread_mutex_unlock(&g_intf_lock); 945 } 946 CDBG("%s :X rc = %d", __func__, rc); 947 return rc; 948 } 949 950 /*=========================================================================== 951 * FUNCTION : mm_camera_intf_stop_zsl_snapshot 952 * 953 * DESCRIPTION: Stops zsl snapshot 954 * 955 * PARAMETERS : 956 * @camera_handle: camera handle 957 * @ch_id : channel handle 958 * 959 * RETURN : int32_t type of status 960 * 0 -- success 961 * -1 -- failure 962 *==========================================================================*/ 963 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle, 964 uint32_t ch_id) 965 { 966 int32_t rc = -1; 967 mm_camera_obj_t * my_obj = NULL; 968 969 CDBG("%s :E camera_handler = %d,ch_id = %d", 970 __func__, camera_handle, ch_id); 971 pthread_mutex_lock(&g_intf_lock); 972 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 973 974 if(my_obj) { 975 pthread_mutex_lock(&my_obj->cam_lock); 976 pthread_mutex_unlock(&g_intf_lock); 977 rc = mm_camera_stop_zsl_snapshot_ch(my_obj, ch_id); 978 } else { 979 pthread_mutex_unlock(&g_intf_lock); 980 } 981 CDBG("%s :X rc = %d", __func__, rc); 982 return rc; 983 } 984 985 /*=========================================================================== 986 * FUNCTION : mm_camera_intf_configure_notify_mode 987 * 988 * DESCRIPTION: Configures channel notification mode 989 * 990 * PARAMETERS : 991 * @camera_handle: camera handle 992 * @ch_id : channel handle 993 * @notify_mode : notification mode 994 * 995 * RETURN : int32_t type of status 996 * 0 -- success 997 * -1 -- failure 998 *==========================================================================*/ 999 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle, 1000 uint32_t ch_id, 1001 mm_camera_super_buf_notify_mode_t notify_mode) 1002 { 1003 int32_t rc = -1; 1004 mm_camera_obj_t * my_obj = NULL; 1005 1006 CDBG("%s :E camera_handler = %d,ch_id = %d", 1007 __func__, camera_handle, ch_id); 1008 pthread_mutex_lock(&g_intf_lock); 1009 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1010 1011 if(my_obj) { 1012 pthread_mutex_lock(&my_obj->cam_lock); 1013 pthread_mutex_unlock(&g_intf_lock); 1014 rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode); 1015 } else { 1016 pthread_mutex_unlock(&g_intf_lock); 1017 } 1018 CDBG("%s :X rc = %d", __func__, rc); 1019 return rc; 1020 } 1021 1022 /*=========================================================================== 1023 * FUNCTION : mm_camera_intf_map_buf 1024 * 1025 * DESCRIPTION: mapping camera buffer via domain socket to server 1026 * 1027 * PARAMETERS : 1028 * @camera_handle: camera handle 1029 * @buf_type : type of buffer to be mapped. could be following values: 1030 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1031 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1032 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1033 * @fd : file descriptor of the buffer 1034 * @size : size of the buffer 1035 * 1036 * RETURN : int32_t type of status 1037 * 0 -- success 1038 * -1 -- failure 1039 *==========================================================================*/ 1040 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle, 1041 uint8_t buf_type, 1042 int fd, 1043 uint32_t size) 1044 { 1045 int32_t rc = -1; 1046 mm_camera_obj_t * my_obj = NULL; 1047 1048 pthread_mutex_lock(&g_intf_lock); 1049 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1050 1051 if(my_obj) { 1052 pthread_mutex_lock(&my_obj->cam_lock); 1053 pthread_mutex_unlock(&g_intf_lock); 1054 rc = mm_camera_map_buf(my_obj, buf_type, fd, size); 1055 } else { 1056 pthread_mutex_unlock(&g_intf_lock); 1057 } 1058 return rc; 1059 } 1060 1061 /*=========================================================================== 1062 * FUNCTION : mm_camera_intf_unmap_buf 1063 * 1064 * DESCRIPTION: unmapping camera buffer via domain socket to server 1065 * 1066 * PARAMETERS : 1067 * @camera_handle: camera handle 1068 * @buf_type : type of buffer to be unmapped. could be following values: 1069 * CAM_MAPPING_BUF_TYPE_CAPABILITY 1070 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF 1071 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF 1072 * 1073 * RETURN : int32_t type of status 1074 * 0 -- success 1075 * -1 -- failure 1076 *==========================================================================*/ 1077 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle, 1078 uint8_t buf_type) 1079 { 1080 int32_t rc = -1; 1081 mm_camera_obj_t * my_obj = NULL; 1082 1083 pthread_mutex_lock(&g_intf_lock); 1084 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1085 1086 if(my_obj) { 1087 pthread_mutex_lock(&my_obj->cam_lock); 1088 pthread_mutex_unlock(&g_intf_lock); 1089 rc = mm_camera_unmap_buf(my_obj, buf_type); 1090 } else { 1091 pthread_mutex_unlock(&g_intf_lock); 1092 } 1093 return rc; 1094 } 1095 1096 /*=========================================================================== 1097 * FUNCTION : mm_camera_intf_set_stream_parms 1098 * 1099 * DESCRIPTION: set 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 set to 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. Corresponding fields of parameters to be set 1112 * are already filled in by upper layer caller. 1113 *==========================================================================*/ 1114 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle, 1115 uint32_t ch_id, 1116 uint32_t s_id, 1117 cam_stream_parm_buffer_t *parms) 1118 { 1119 int32_t rc = -1; 1120 mm_camera_obj_t * my_obj = NULL; 1121 1122 pthread_mutex_lock(&g_intf_lock); 1123 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1124 1125 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d", 1126 __func__, camera_handle, ch_id, s_id); 1127 1128 if(my_obj) { 1129 pthread_mutex_lock(&my_obj->cam_lock); 1130 pthread_mutex_unlock(&g_intf_lock); 1131 rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms); 1132 }else{ 1133 pthread_mutex_unlock(&g_intf_lock); 1134 } 1135 CDBG("%s :X rc = %d", __func__, rc); 1136 return rc; 1137 } 1138 1139 /*=========================================================================== 1140 * FUNCTION : mm_camera_intf_get_stream_parms 1141 * 1142 * DESCRIPTION: get parameters per stream 1143 * 1144 * PARAMETERS : 1145 * @camera_handle: camera handle 1146 * @ch_id : channel handle 1147 * @s_id : stream handle 1148 * @parms : ptr to a param struct to be get from server 1149 * 1150 * RETURN : int32_t type of status 1151 * 0 -- success 1152 * -1 -- failure 1153 * NOTE : Assume the parms struct buf is already mapped to server via 1154 * domain socket. Parameters to be get from server are already 1155 * filled in by upper layer caller. After this call, corresponding 1156 * fields of requested parameters will be filled in by server with 1157 * detailed information. 1158 *==========================================================================*/ 1159 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle, 1160 uint32_t ch_id, 1161 uint32_t s_id, 1162 cam_stream_parm_buffer_t *parms) 1163 { 1164 int32_t rc = -1; 1165 mm_camera_obj_t * my_obj = NULL; 1166 1167 pthread_mutex_lock(&g_intf_lock); 1168 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1169 1170 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d", 1171 __func__, camera_handle, ch_id, s_id); 1172 1173 if(my_obj) { 1174 pthread_mutex_lock(&my_obj->cam_lock); 1175 pthread_mutex_unlock(&g_intf_lock); 1176 rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms); 1177 }else{ 1178 pthread_mutex_unlock(&g_intf_lock); 1179 } 1180 1181 CDBG("%s :X rc = %d", __func__, rc); 1182 return rc; 1183 } 1184 1185 /*=========================================================================== 1186 * FUNCTION : mm_camera_intf_map_stream_buf 1187 * 1188 * DESCRIPTION: mapping stream buffer via domain socket to server 1189 * 1190 * PARAMETERS : 1191 * @camera_handle: camera handle 1192 * @ch_id : channel handle 1193 * @s_id : stream handle 1194 * @buf_type : type of buffer to be mapped. could be following values: 1195 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1196 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1197 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1198 * @buf_idx : index of buffer within the stream buffers, only valid if 1199 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1200 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1201 * @plane_idx : plane index. If all planes share the same fd, 1202 * plane_idx = -1; otherwise, plean_idx is the 1203 * index to plane (0..num_of_planes) 1204 * @fd : file descriptor of the buffer 1205 * @size : size of the buffer 1206 * 1207 * RETURN : int32_t type of status 1208 * 0 -- success 1209 * -1 -- failure 1210 *==========================================================================*/ 1211 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle, 1212 uint32_t ch_id, 1213 uint32_t stream_id, 1214 uint8_t buf_type, 1215 uint32_t buf_idx, 1216 int32_t plane_idx, 1217 int fd, 1218 uint32_t size) 1219 { 1220 int32_t rc = -1; 1221 mm_camera_obj_t * my_obj = NULL; 1222 1223 pthread_mutex_lock(&g_intf_lock); 1224 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1225 1226 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", 1227 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx); 1228 1229 if(my_obj) { 1230 pthread_mutex_lock(&my_obj->cam_lock); 1231 pthread_mutex_unlock(&g_intf_lock); 1232 rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id, 1233 buf_type, buf_idx, plane_idx, 1234 fd, size); 1235 }else{ 1236 pthread_mutex_unlock(&g_intf_lock); 1237 } 1238 1239 CDBG("%s :X rc = %d", __func__, rc); 1240 return rc; 1241 } 1242 1243 /*=========================================================================== 1244 * FUNCTION : mm_camera_intf_unmap_stream_buf 1245 * 1246 * DESCRIPTION: unmapping stream buffer via domain socket to server 1247 * 1248 * PARAMETERS : 1249 * @camera_handle: camera handle 1250 * @ch_id : channel handle 1251 * @s_id : stream handle 1252 * @buf_type : type of buffer to be unmapped. could be following values: 1253 * CAM_MAPPING_BUF_TYPE_STREAM_BUF 1254 * CAM_MAPPING_BUF_TYPE_STREAM_INFO 1255 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1256 * @buf_idx : index of buffer within the stream buffers, only valid if 1257 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or 1258 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF 1259 * @plane_idx : plane index. If all planes share the same fd, 1260 * plane_idx = -1; otherwise, plean_idx is the 1261 * index to plane (0..num_of_planes) 1262 * 1263 * RETURN : int32_t type of status 1264 * 0 -- success 1265 * -1 -- failure 1266 *==========================================================================*/ 1267 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle, 1268 uint32_t ch_id, 1269 uint32_t stream_id, 1270 uint8_t buf_type, 1271 uint32_t buf_idx, 1272 int32_t plane_idx) 1273 { 1274 int32_t rc = -1; 1275 mm_camera_obj_t * my_obj = NULL; 1276 1277 pthread_mutex_lock(&g_intf_lock); 1278 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1279 1280 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d", 1281 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx); 1282 1283 if(my_obj) { 1284 pthread_mutex_lock(&my_obj->cam_lock); 1285 pthread_mutex_unlock(&g_intf_lock); 1286 rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id, 1287 buf_type, buf_idx, plane_idx); 1288 }else{ 1289 pthread_mutex_unlock(&g_intf_lock); 1290 } 1291 1292 CDBG("%s :X rc = %d", __func__, rc); 1293 return rc; 1294 } 1295 1296 /*=========================================================================== 1297 * FUNCTION : get_sensor_info 1298 * 1299 * DESCRIPTION: get sensor info like facing(back/front) and mount angle 1300 * 1301 * PARAMETERS : 1302 * 1303 * RETURN : 1304 *==========================================================================*/ 1305 void get_sensor_info() 1306 { 1307 int rc = 0; 1308 int dev_fd = -1; 1309 struct media_device_info mdev_info; 1310 int num_media_devices = 0; 1311 uint8_t num_cameras = 0; 1312 1313 CDBG("%s : E", __func__); 1314 while (1) { 1315 char dev_name[32]; 1316 int num_entities; 1317 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 1318 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 1319 if (dev_fd < 0) { 1320 CDBG("Done discovering media devices\n"); 1321 break; 1322 } 1323 num_media_devices++; 1324 memset(&mdev_info, 0, sizeof(mdev_info)); 1325 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 1326 if (rc < 0) { 1327 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 1328 close(dev_fd); 1329 dev_fd = -1; 1330 num_cameras = 0; 1331 break; 1332 } 1333 1334 if(strncmp(mdev_info.model, MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) { 1335 close(dev_fd); 1336 dev_fd = -1; 1337 continue; 1338 } 1339 1340 num_entities = 1; 1341 while (1) { 1342 struct media_entity_desc entity; 1343 unsigned long temp; 1344 unsigned int mount_angle; 1345 unsigned int facing; 1346 1347 memset(&entity, 0, sizeof(entity)); 1348 entity.id = num_entities++; 1349 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 1350 if (rc < 0) { 1351 CDBG("Done enumerating media entities\n"); 1352 rc = 0; 1353 break; 1354 } 1355 if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV && 1356 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) { 1357 temp = entity.flags >> 8; 1358 mount_angle = (temp & 0xFF) * 90; 1359 facing = (temp >> 8); 1360 ALOGD("index = %d flag = %x mount_angle = %d facing = %d\n" 1361 , num_cameras, (unsigned int)temp, (unsigned int)mount_angle, 1362 (unsigned int)facing); 1363 g_cam_ctrl.info[num_cameras].facing = facing; 1364 g_cam_ctrl.info[num_cameras].orientation = mount_angle; 1365 num_cameras++; 1366 continue; 1367 } 1368 } 1369 1370 CDBG("%s: dev_info[id=%d,name='%s']\n", 1371 __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]); 1372 1373 close(dev_fd); 1374 dev_fd = -1; 1375 } 1376 1377 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam); 1378 return; 1379 } 1380 1381 /*=========================================================================== 1382 * FUNCTION : get_num_of_cameras 1383 * 1384 * DESCRIPTION: get number of cameras 1385 * 1386 * PARAMETERS : 1387 * 1388 * RETURN : number of cameras supported 1389 *==========================================================================*/ 1390 uint8_t get_num_of_cameras() 1391 { 1392 int rc = 0; 1393 int dev_fd = 0; 1394 struct media_device_info mdev_info; 1395 int num_media_devices = 0; 1396 uint8_t num_cameras = 0; 1397 char subdev_name[32]; 1398 int32_t sd_fd = 0; 1399 struct sensor_init_cfg_data cfg; 1400 char prop[PROPERTY_VALUE_MAX]; 1401 1402 property_get("persist.camera.logs", prop, "0"); 1403 gMmCameraIntfLogLevel = atoi(prop); 1404 1405 CDBG("%s : E", __func__); 1406 1407 int decrypt = property_get("vold.decrypt", prop, NULL); 1408 if (0 < decrypt) { 1409 if(strncmp(prop, "trigger_restart_min_framework", decrypt) == 0) { 1410 return 0; 1411 } 1412 } 1413 1414 /* lock the mutex */ 1415 pthread_mutex_lock(&g_intf_lock); 1416 1417 while (1) { 1418 int32_t num_entities = 1; 1419 char dev_name[32]; 1420 1421 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 1422 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 1423 if (dev_fd < 0) { 1424 CDBG("Done discovering media devices\n"); 1425 break; 1426 } 1427 num_media_devices++; 1428 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 1429 if (rc < 0) { 1430 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 1431 close(dev_fd); 1432 dev_fd = -1; 1433 break; 1434 } 1435 1436 if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME, 1437 sizeof(mdev_info.model)) != 0) { 1438 close(dev_fd); 1439 dev_fd = -1; 1440 continue; 1441 } 1442 1443 while (1) { 1444 struct media_entity_desc entity; 1445 memset(&entity, 0, sizeof(entity)); 1446 entity.id = num_entities++; 1447 CDBG_ERROR("entity id %d", entity.id); 1448 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 1449 if (rc < 0) { 1450 CDBG_ERROR("Done enumerating media entities"); 1451 rc = 0; 1452 break; 1453 } 1454 CDBG_ERROR("entity name %s type %d group id %d", 1455 entity.name, entity.type, entity.group_id); 1456 if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV && 1457 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) { 1458 snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name); 1459 break; 1460 } 1461 } 1462 close(dev_fd); 1463 dev_fd = -1; 1464 } 1465 1466 /* Open sensor_init subdev */ 1467 sd_fd = open(subdev_name, O_RDWR); 1468 if (sd_fd < 0) { 1469 CDBG_ERROR("Open sensor_init subdev failed"); 1470 return FALSE; 1471 } 1472 1473 cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE; 1474 cfg.cfg.setting = NULL; 1475 if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) { 1476 CDBG_ERROR("failed"); 1477 } 1478 close(sd_fd); 1479 dev_fd = -1; 1480 1481 1482 num_media_devices = 0; 1483 while (1) { 1484 char dev_name[32]; 1485 int num_entities; 1486 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 1487 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 1488 if (dev_fd < 0) { 1489 CDBG("Done discovering media devices: %s\n", strerror(errno)); 1490 break; 1491 } 1492 num_media_devices++; 1493 memset(&mdev_info, 0, sizeof(mdev_info)); 1494 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 1495 if (rc < 0) { 1496 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 1497 close(dev_fd); 1498 dev_fd = -1; 1499 num_cameras = 0; 1500 break; 1501 } 1502 1503 if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) { 1504 close(dev_fd); 1505 dev_fd = -1; 1506 continue; 1507 } 1508 1509 num_entities = 1; 1510 while (1) { 1511 struct media_entity_desc entity; 1512 memset(&entity, 0, sizeof(entity)); 1513 entity.id = num_entities++; 1514 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 1515 if (rc < 0) { 1516 CDBG("Done enumerating media entities\n"); 1517 rc = 0; 1518 break; 1519 } 1520 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) { 1521 strncpy(g_cam_ctrl.video_dev_name[num_cameras], 1522 entity.name, sizeof(entity.name)); 1523 break; 1524 } 1525 } 1526 1527 CDBG("%s: dev_info[id=%d,name='%s']\n", 1528 __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]); 1529 1530 num_cameras++; 1531 close(dev_fd); 1532 dev_fd = -1; 1533 } 1534 g_cam_ctrl.num_cam = num_cameras; 1535 1536 get_sensor_info(); 1537 /* unlock the mutex */ 1538 pthread_mutex_unlock(&g_intf_lock); 1539 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam); 1540 return g_cam_ctrl.num_cam; 1541 } 1542 1543 /*=========================================================================== 1544 * FUNCTION : mm_camera_intf_process_advanced_capture 1545 * 1546 * DESCRIPTION: Configures channel advanced capture mode 1547 * 1548 * PARAMETERS : 1549 * @camera_handle: camera handle 1550 * @advanced_capture_type : advanced capture type 1551 * @ch_id : channel handle 1552 * @notify_mode : notification mode 1553 * 1554 * RETURN : int32_t type of status 1555 * 0 -- success 1556 * -1 -- failure 1557 *==========================================================================*/ 1558 static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle, 1559 mm_camera_advanced_capture_t advanced_capture_type, 1560 uint32_t ch_id, 1561 int8_t start_flag) 1562 { 1563 int32_t rc = -1; 1564 mm_camera_obj_t * my_obj = NULL; 1565 1566 CDBG("%s: E camera_handler = %d,ch_id = %d", 1567 __func__, camera_handle, ch_id); 1568 pthread_mutex_lock(&g_intf_lock); 1569 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1570 1571 if(my_obj) { 1572 pthread_mutex_lock(&my_obj->cam_lock); 1573 pthread_mutex_unlock(&g_intf_lock); 1574 rc = mm_camera_channel_advanced_capture(my_obj, advanced_capture_type, ch_id, start_flag); 1575 } else { 1576 pthread_mutex_unlock(&g_intf_lock); 1577 } 1578 CDBG("%s: X ", __func__); 1579 return rc; 1580 } 1581 1582 struct camera_info *get_cam_info(int camera_id) 1583 { 1584 return &g_cam_ctrl.info[camera_id]; 1585 } 1586 1587 /* camera ops v-table */ 1588 static mm_camera_ops_t mm_camera_ops = { 1589 .query_capability = mm_camera_intf_query_capability, 1590 .register_event_notify = mm_camera_intf_register_event_notify, 1591 .close_camera = mm_camera_intf_close, 1592 .error_close_camera = mm_camera_intf_error_close, 1593 .set_parms = mm_camera_intf_set_parms, 1594 .get_parms = mm_camera_intf_get_parms, 1595 .do_auto_focus = mm_camera_intf_do_auto_focus, 1596 .cancel_auto_focus = mm_camera_intf_cancel_auto_focus, 1597 .prepare_snapshot = mm_camera_intf_prepare_snapshot, 1598 .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot, 1599 .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot, 1600 .map_buf = mm_camera_intf_map_buf, 1601 .unmap_buf = mm_camera_intf_unmap_buf, 1602 .add_channel = mm_camera_intf_add_channel, 1603 .delete_channel = mm_camera_intf_del_channel, 1604 .get_bundle_info = mm_camera_intf_get_bundle_info, 1605 .add_stream = mm_camera_intf_add_stream, 1606 .delete_stream = mm_camera_intf_del_stream, 1607 .config_stream = mm_camera_intf_config_stream, 1608 .qbuf = mm_camera_intf_qbuf, 1609 .map_stream_buf = mm_camera_intf_map_stream_buf, 1610 .unmap_stream_buf = mm_camera_intf_unmap_stream_buf, 1611 .set_stream_parms = mm_camera_intf_set_stream_parms, 1612 .get_stream_parms = mm_camera_intf_get_stream_parms, 1613 .start_channel = mm_camera_intf_start_channel, 1614 .stop_channel = mm_camera_intf_stop_channel, 1615 .request_super_buf = mm_camera_intf_request_super_buf, 1616 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request, 1617 .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue, 1618 .configure_notify_mode = mm_camera_intf_configure_notify_mode, 1619 .process_advanced_capture = mm_camera_intf_process_advanced_capture 1620 }; 1621 1622 /*=========================================================================== 1623 * FUNCTION : camera_open 1624 * 1625 * DESCRIPTION: open a camera by camera index 1626 * 1627 * PARAMETERS : 1628 * @camera_idx : camera index. should within range of 0 to num_of_cameras 1629 * 1630 * RETURN : ptr to a virtual table containing camera handle and operation table. 1631 * NULL if failed. 1632 *==========================================================================*/ 1633 mm_camera_vtbl_t * camera_open(uint8_t camera_idx) 1634 { 1635 int32_t rc = 0; 1636 mm_camera_obj_t* cam_obj = NULL; 1637 1638 CDBG("%s: E camera_idx = %d\n", __func__, camera_idx); 1639 if (camera_idx >= g_cam_ctrl.num_cam) { 1640 CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx); 1641 return NULL; 1642 } 1643 1644 pthread_mutex_lock(&g_intf_lock); 1645 /* opened already */ 1646 if(NULL != g_cam_ctrl.cam_obj[camera_idx]) { 1647 /* Add reference */ 1648 g_cam_ctrl.cam_obj[camera_idx]->ref_count++; 1649 pthread_mutex_unlock(&g_intf_lock); 1650 CDBG("%s: opened alreadyn", __func__); 1651 return &g_cam_ctrl.cam_obj[camera_idx]->vtbl; 1652 } 1653 1654 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t)); 1655 if(NULL == cam_obj) { 1656 pthread_mutex_unlock(&g_intf_lock); 1657 CDBG("%s: no mem", __func__); 1658 return NULL; 1659 } 1660 1661 /* initialize camera obj */ 1662 memset(cam_obj, 0, sizeof(mm_camera_obj_t)); 1663 cam_obj->ctrl_fd = -1; 1664 cam_obj->ds_fd = -1; 1665 cam_obj->ref_count++; 1666 cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx); 1667 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */ 1668 cam_obj->vtbl.ops = &mm_camera_ops; 1669 pthread_mutex_init(&cam_obj->cam_lock, NULL); 1670 1671 rc = mm_camera_open(cam_obj); 1672 if(rc != 0) { 1673 CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc); 1674 pthread_mutex_destroy(&cam_obj->cam_lock); 1675 g_cam_ctrl.cam_obj[camera_idx] = NULL; 1676 free(cam_obj); 1677 cam_obj = NULL; 1678 pthread_mutex_unlock(&g_intf_lock); 1679 return NULL; 1680 }else{ 1681 CDBG("%s: Open succeded\n", __func__); 1682 g_cam_ctrl.cam_obj[camera_idx] = cam_obj; 1683 pthread_mutex_unlock(&g_intf_lock); 1684 return &cam_obj->vtbl; 1685 } 1686 } 1687