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