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