1 /* 2 Copyright (c) 2011-2012, The Linux Foundation. All rights reserved. 3 4 Redistribution and use in source and binary forms, with or without 5 modification, are permitted provided that the following conditions are 6 met: 7 * Redistributions of source code must retain the above copyright 8 notice, this list of conditions and the following disclaimer. 9 * Redistributions in binary form must reproduce the above 10 copyright notice, this list of conditions and the following 11 disclaimer in the documentation and/or other materials provided 12 with the distribution. 13 * Neither the name of The Linux Foundation nor the names of its 14 contributors may be used to endorse or promote products derived 15 from this software without specific prior written permission. 16 17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED 18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT 20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS 21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN 27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 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 <semaphore.h> 39 40 #include "mm_camera_dbg.h" 41 #include "mm_camera_interface.h" 42 #include "mm_camera_sock.h" 43 #include "mm_camera.h" 44 45 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER; 46 static pthread_mutex_t g_oem_lock = PTHREAD_MUTEX_INITIALIZER; 47 48 static mm_camera_ctrl_t g_cam_ctrl = {{{0, {0, 0, 0, 0}, 0, 0}}, 0, {{0}}, {0}}; 49 50 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER; 51 static uint16_t g_handler_history_count = 0; /* history count for handler */ 52 53 extern int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj, 54 cam_ctrl_type type, 55 uint32_t length, 56 void *value); 57 58 /* utility function to generate handler */ 59 uint32_t mm_camera_util_generate_handler(uint8_t index) 60 { 61 uint32_t handler = 0; 62 pthread_mutex_lock(&g_handler_lock); 63 g_handler_history_count++; 64 if (0 == g_handler_history_count) { 65 g_handler_history_count++; 66 } 67 handler = g_handler_history_count; 68 handler = (handler<<8) | index; 69 pthread_mutex_unlock(&g_handler_lock); 70 return handler; 71 } 72 73 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler) 74 { 75 return (handler&0x000000ff); 76 } 77 78 const char *mm_camera_util_get_dev_name(uint32_t cam_handler) 79 { 80 char *dev_name = NULL; 81 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler); 82 dev_name = g_cam_ctrl.camera[cam_idx].video_dev_name; 83 return dev_name; 84 } 85 86 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler) 87 { 88 mm_camera_obj_t *cam_obj = NULL; 89 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler); 90 91 if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) && 92 (cam_handler == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) { 93 cam_obj = g_cam_ctrl.cam_obj[cam_idx]; 94 } 95 return cam_obj; 96 } 97 98 static int32_t mm_camera_intf_sync(uint32_t camera_handler) 99 { 100 int32_t rc = -1; 101 mm_camera_obj_t * my_obj = NULL; 102 103 CDBG("%s E: camera_handler = %d ",__func__,camera_handler); 104 105 pthread_mutex_lock(&g_intf_lock); 106 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 107 108 if(my_obj) { 109 pthread_mutex_lock(&my_obj->cam_lock); 110 pthread_mutex_unlock(&g_intf_lock); 111 rc = mm_camera_sync(my_obj); 112 } else { 113 pthread_mutex_unlock(&g_intf_lock); 114 } 115 CDBG("%s :X rc = %d",__func__,rc); 116 return rc; 117 } 118 119 /* check if the operation is supported */ 120 static int32_t mm_camera_intf_is_op_supported(uint32_t camera_handler,mm_camera_ops_type_t opcode) 121 { 122 int32_t rc = -1; 123 mm_camera_obj_t * my_obj = NULL; 124 125 pthread_mutex_lock(&g_intf_lock); 126 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 127 128 if(my_obj) { 129 pthread_mutex_lock(&my_obj->cam_lock); 130 pthread_mutex_unlock(&g_intf_lock); 131 rc = mm_camera_is_op_supported(my_obj, opcode); 132 } else { 133 pthread_mutex_unlock(&g_intf_lock); 134 } 135 return rc; 136 } 137 138 /* check if the parm is supported */ 139 static int32_t mm_camera_intf_is_parm_supported(uint32_t camera_handler, 140 mm_camera_parm_type_t parm_type, 141 uint8_t *support_set_parm, 142 uint8_t *support_get_parm) 143 { 144 int32_t rc = -1; 145 mm_camera_obj_t * my_obj = NULL; 146 147 pthread_mutex_lock(&g_intf_lock); 148 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 149 *support_set_parm = 0; 150 *support_get_parm = 0; 151 152 if(my_obj) { 153 pthread_mutex_lock(&my_obj->cam_lock); 154 pthread_mutex_unlock(&g_intf_lock); 155 rc = mm_camera_is_parm_supported(my_obj, parm_type, support_set_parm, support_get_parm); 156 } else { 157 pthread_mutex_unlock(&g_intf_lock); 158 } 159 return rc; 160 } 161 162 /* set a parms current value */ 163 static int32_t mm_camera_intf_set_parm(uint32_t camera_handler, 164 mm_camera_parm_type_t parm_type, 165 void* p_value) 166 { 167 int32_t rc = -1; 168 mm_camera_obj_t * my_obj = NULL; 169 170 pthread_mutex_lock(&g_intf_lock); 171 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 172 173 if(my_obj) { 174 pthread_mutex_lock(&my_obj->cam_lock); 175 pthread_mutex_unlock(&g_intf_lock); 176 rc = mm_camera_set_parm(my_obj, parm_type, p_value); 177 } else { 178 pthread_mutex_unlock(&g_intf_lock); 179 } 180 return rc; 181 } 182 183 /* get a parms current value */ 184 static int32_t mm_camera_intf_get_parm(uint32_t camera_handler, 185 mm_camera_parm_type_t parm_type, 186 void* p_value) 187 { 188 int32_t rc = -1; 189 mm_camera_obj_t * my_obj = NULL; 190 191 pthread_mutex_lock(&g_intf_lock); 192 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 193 194 if(my_obj) { 195 pthread_mutex_lock(&my_obj->cam_lock); 196 pthread_mutex_unlock(&g_intf_lock); 197 rc = mm_camera_get_parm(my_obj, parm_type, p_value); 198 } else { 199 pthread_mutex_unlock(&g_intf_lock); 200 } 201 return rc; 202 } 203 204 static void mm_camera_intf_close(uint32_t camera_handler) 205 { 206 int32_t rc = -1; 207 uint8_t cam_idx = camera_handler & 0x00ff; 208 mm_camera_obj_t * my_obj = NULL; 209 210 CDBG("%s E: camera_handler = %d ",__func__,camera_handler); 211 212 /* first we need to get oem_lock, 213 * in case oem private ioctl is still processing, 214 * we need to wait until it finishes */ 215 pthread_mutex_lock(&g_oem_lock); 216 217 /* then we get intf_lock */ 218 pthread_mutex_lock(&g_intf_lock); 219 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 220 221 if (my_obj){ 222 my_obj->ref_count--; 223 224 if(my_obj->ref_count > 0) { 225 /* still have reference to obj, return here */ 226 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count); 227 pthread_mutex_unlock(&g_intf_lock); 228 } else { 229 /* need close camera here as no other reference 230 * first empty g_cam_ctrl's referent to cam_obj */ 231 g_cam_ctrl.cam_obj[cam_idx] = NULL; 232 233 pthread_mutex_lock(&my_obj->cam_lock); 234 pthread_mutex_unlock(&g_intf_lock); 235 236 mm_camera_close(my_obj); 237 238 pthread_mutex_destroy(&my_obj->cam_lock); 239 free(my_obj); 240 } 241 } else { 242 pthread_mutex_unlock(&g_intf_lock); 243 } 244 245 /* unlock oem_lock before we leave */ 246 pthread_mutex_unlock(&g_oem_lock); 247 } 248 249 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handler) 250 { 251 uint32_t ch_id = 0; 252 mm_camera_obj_t * my_obj = NULL; 253 254 CDBG("%s :E camera_handler = %d",__func__,camera_handler); 255 pthread_mutex_lock(&g_intf_lock); 256 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 257 258 if(my_obj) { 259 pthread_mutex_lock(&my_obj->cam_lock); 260 pthread_mutex_unlock(&g_intf_lock); 261 ch_id = mm_camera_add_channel(my_obj); 262 } else { 263 pthread_mutex_unlock(&g_intf_lock); 264 } 265 CDBG("%s :X ch_id = %d",__func__,ch_id); 266 return ch_id; 267 } 268 269 static void mm_camera_intf_del_channel(uint32_t camera_handler, uint32_t ch_id) 270 { 271 mm_camera_obj_t * my_obj = NULL; 272 273 CDBG("%s :E ch_id = %d",__func__,ch_id); 274 pthread_mutex_lock(&g_intf_lock); 275 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 276 277 if(my_obj) { 278 pthread_mutex_lock(&my_obj->cam_lock); 279 pthread_mutex_unlock(&g_intf_lock); 280 mm_camera_del_channel(my_obj, ch_id); 281 } else { 282 pthread_mutex_unlock(&g_intf_lock); 283 } 284 CDBG("%s :X",__func__); 285 } 286 287 static uint8_t mm_camera_intf_is_event_supported(uint32_t camera_handler, 288 mm_camera_event_type_t evt_type) 289 { 290 switch(evt_type) { 291 case MM_CAMERA_EVT_TYPE_CH: 292 case MM_CAMERA_EVT_TYPE_CTRL: 293 case MM_CAMERA_EVT_TYPE_STATS: 294 case MM_CAMERA_EVT_TYPE_INFO: 295 return 1; 296 default: 297 return 0; 298 } 299 return 0; 300 } 301 302 static int32_t mm_camera_intf_register_event_notify( 303 uint32_t camera_handler, 304 mm_camera_event_notify_t evt_cb, 305 void * user_data, 306 mm_camera_event_type_t evt_type) 307 { 308 int32_t rc = -1; 309 mm_camera_obj_t * my_obj = NULL; 310 311 CDBG("%s :E evt_type = %d",__func__,evt_type); 312 pthread_mutex_lock(&g_intf_lock); 313 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 314 315 if(my_obj) { 316 pthread_mutex_lock(&my_obj->cam_lock); 317 pthread_mutex_unlock(&g_intf_lock); 318 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data, evt_type); 319 } else { 320 pthread_mutex_unlock(&g_intf_lock); 321 } 322 CDBG("%s :E rc = %d",__func__,rc); 323 return rc; 324 } 325 326 static mm_camera_2nd_sensor_t * mm_camera_intf_query_2nd_sensor_info(uint32_t camera_handler) 327 { 328 mm_camera_2nd_sensor_t *sensor_info = NULL; 329 mm_camera_obj_t * my_obj = NULL; 330 331 CDBG("%s :E camera_handler = %d",__func__,camera_handler); 332 pthread_mutex_lock(&g_intf_lock); 333 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 334 335 if(my_obj) { 336 pthread_mutex_lock(&my_obj->cam_lock); 337 pthread_mutex_unlock(&g_intf_lock); 338 sensor_info = mm_camera_query_2nd_sensor_info(my_obj); 339 } else { 340 pthread_mutex_unlock(&g_intf_lock); 341 } 342 CDBG("%s :X",__func__); 343 return sensor_info; 344 } 345 346 static int32_t mm_camera_intf_qbuf(uint32_t camera_handler, 347 uint32_t ch_id, 348 mm_camera_buf_def_t *buf) 349 { 350 int32_t rc = -1; 351 mm_camera_obj_t * my_obj = NULL; 352 353 pthread_mutex_lock(&g_intf_lock); 354 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 355 356 if(my_obj) { 357 pthread_mutex_lock(&my_obj->cam_lock); 358 pthread_mutex_unlock(&g_intf_lock); 359 rc = mm_camera_qbuf(my_obj, ch_id, buf); 360 } else { 361 pthread_mutex_unlock(&g_intf_lock); 362 } 363 CDBG("%s :X evt_type = %d",__func__,rc); 364 return rc; 365 } 366 367 static uint32_t mm_camera_intf_add_stream( 368 uint32_t camera_handler, 369 uint32_t ch_id, 370 mm_camera_buf_notify_t buf_cb, void *user_data, 371 uint32_t ext_image_mode, uint32_t sensor_idx) 372 { 373 uint32_t stream_id = 0; 374 mm_camera_obj_t * my_obj = NULL; 375 376 CDBG("%s : E handle = %d ch_id = %d",__func__,camera_handler, 377 ch_id); 378 379 pthread_mutex_lock(&g_intf_lock); 380 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 381 382 if(my_obj) { 383 pthread_mutex_lock(&my_obj->cam_lock); 384 pthread_mutex_unlock(&g_intf_lock); 385 stream_id = mm_camera_add_stream(my_obj, ch_id, buf_cb, 386 user_data, ext_image_mode, sensor_idx); 387 } else { 388 pthread_mutex_unlock(&g_intf_lock); 389 } 390 CDBG("%s :X stream_id = %d",__func__,stream_id); 391 return stream_id; 392 } 393 394 static int32_t mm_camera_intf_del_stream( 395 uint32_t camera_handler, 396 uint32_t ch_id, 397 uint32_t stream_id) 398 { 399 int32_t rc = -1; 400 mm_camera_obj_t * my_obj = NULL; 401 402 CDBG("%s : E handle = %d ch_id = %d stream_id = %d",__func__,camera_handler, 403 ch_id,stream_id); 404 405 pthread_mutex_lock(&g_intf_lock); 406 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 407 408 if(my_obj) { 409 pthread_mutex_lock(&my_obj->cam_lock); 410 pthread_mutex_unlock(&g_intf_lock); 411 rc = mm_camera_del_stream(my_obj, ch_id, stream_id); 412 } else { 413 pthread_mutex_unlock(&g_intf_lock); 414 } 415 CDBG("%s :X rc = %d",__func__,rc); 416 return rc; 417 } 418 419 static int32_t mm_camera_intf_config_stream( 420 uint32_t camera_handler, 421 uint32_t ch_id, 422 uint32_t stream_id, 423 mm_camera_stream_config_t *config) 424 { 425 int32_t rc = -1; 426 mm_camera_obj_t * my_obj = NULL; 427 428 CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",__func__, 429 camera_handler,ch_id,stream_id); 430 431 pthread_mutex_lock(&g_intf_lock); 432 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 433 434 CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id); 435 436 if(my_obj) { 437 pthread_mutex_lock(&my_obj->cam_lock); 438 pthread_mutex_unlock(&g_intf_lock); 439 rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config); 440 } else { 441 pthread_mutex_unlock(&g_intf_lock); 442 } 443 CDBG("%s :X rc = %d",__func__,rc); 444 return rc; 445 } 446 447 static int32_t mm_camera_intf_bundle_streams( 448 uint32_t camera_handler, 449 uint32_t ch_id, 450 mm_camera_buf_notify_t super_frame_notify_cb, 451 void *user_data, 452 mm_camera_bundle_attr_t *attr, 453 uint8_t num_streams, 454 uint32_t *stream_ids) 455 { 456 int32_t rc = -1; 457 mm_camera_obj_t * my_obj = NULL; 458 459 CDBG("%s :E handle = %d, ch_id = %d",__func__, 460 camera_handler,ch_id); 461 462 if (MM_CAMEAR_MAX_STRAEM_BUNDLE < num_streams) { 463 CDBG_ERROR("%s: number of streams (%d) exceeds max (%d)", 464 __func__, num_streams, MM_CAMEAR_MAX_STRAEM_BUNDLE); 465 return rc; 466 } 467 468 pthread_mutex_lock(&g_intf_lock); 469 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 470 471 if(my_obj) { 472 pthread_mutex_lock(&my_obj->cam_lock); 473 pthread_mutex_unlock(&g_intf_lock); 474 rc = mm_camera_bundle_streams(my_obj, ch_id, 475 super_frame_notify_cb, 476 user_data, attr, 477 num_streams, stream_ids); 478 } else { 479 pthread_mutex_unlock(&g_intf_lock); 480 } 481 CDBG("%s :X rc = %d",__func__,rc); 482 return rc; 483 } 484 485 static int32_t mm_camera_intf_destroy_bundle(uint32_t camera_handler, 486 uint32_t ch_id) 487 { 488 int32_t rc = -1; 489 mm_camera_obj_t * my_obj = NULL; 490 491 CDBG("%s :E handle = %d, ch_id = %d",__func__, 492 camera_handler,ch_id); 493 pthread_mutex_lock(&g_intf_lock); 494 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 495 496 if(my_obj) { 497 pthread_mutex_lock(&my_obj->cam_lock); 498 pthread_mutex_unlock(&g_intf_lock); 499 rc = mm_camera_destroy_bundle(my_obj, ch_id); 500 } else { 501 pthread_mutex_unlock(&g_intf_lock); 502 } 503 CDBG("%s :X rc = %d",__func__,rc); 504 return rc; 505 } 506 507 static int32_t mm_camera_intf_start_streams( 508 uint32_t camera_handler, 509 uint32_t ch_id, 510 uint8_t num_streams, 511 uint32_t *stream_ids) 512 { 513 int32_t rc = -1; 514 mm_camera_obj_t * my_obj = NULL; 515 516 CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d", 517 __func__,camera_handler,ch_id,num_streams); 518 if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) { 519 CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)", 520 __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX); 521 return rc; 522 } 523 524 pthread_mutex_lock(&g_intf_lock); 525 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 526 527 if(my_obj) { 528 pthread_mutex_lock(&my_obj->cam_lock); 529 pthread_mutex_unlock(&g_intf_lock); 530 rc = mm_camera_start_streams(my_obj, ch_id, num_streams, stream_ids); 531 } else { 532 pthread_mutex_unlock(&g_intf_lock); 533 } 534 CDBG("%s :X rc = %d",__func__,rc); 535 return rc; 536 } 537 538 static int32_t mm_camera_intf_stop_streams( 539 uint32_t camera_handler, 540 uint32_t ch_id, 541 uint8_t num_streams, 542 uint32_t *stream_ids) 543 { 544 int32_t rc = -1; 545 mm_camera_obj_t * my_obj = NULL; 546 547 CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d", 548 __func__,camera_handler,ch_id,num_streams); 549 550 if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) { 551 CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)", 552 __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX); 553 return rc; 554 } 555 556 pthread_mutex_lock(&g_intf_lock); 557 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 558 559 if(my_obj) { 560 pthread_mutex_lock(&my_obj->cam_lock); 561 pthread_mutex_unlock(&g_intf_lock); 562 rc = mm_camera_stop_streams(my_obj, ch_id, 563 num_streams, stream_ids); 564 } else { 565 pthread_mutex_unlock(&g_intf_lock); 566 } 567 CDBG("%s :X rc = %d",__func__,rc); 568 return rc; 569 } 570 571 static int32_t mm_camera_intf_async_teardown_streams( 572 uint32_t camera_handler, 573 uint32_t ch_id, 574 uint8_t num_streams, 575 uint32_t *stream_ids) 576 { 577 int32_t rc = -1; 578 mm_camera_obj_t * my_obj = NULL; 579 580 CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d", 581 __func__,camera_handler,ch_id,num_streams); 582 583 if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) { 584 CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)", 585 __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX); 586 return rc; 587 } 588 589 pthread_mutex_lock(&g_intf_lock); 590 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 591 592 if(my_obj) { 593 pthread_mutex_lock(&my_obj->cam_lock); 594 pthread_mutex_unlock(&g_intf_lock); 595 rc = mm_camera_async_teardown_streams(my_obj, ch_id, 596 num_streams, stream_ids); 597 } else { 598 pthread_mutex_unlock(&g_intf_lock); 599 } 600 CDBG("%s :X rc = %d",__func__,rc); 601 return rc; 602 } 603 604 static int32_t mm_camera_intf_request_super_buf( 605 uint32_t camera_handler, 606 uint32_t ch_id, 607 uint32_t num_buf_requested) 608 { 609 int32_t rc = -1; 610 CDBG("%s :E camera_handler = %d,ch_id = %d", 611 __func__,camera_handler,ch_id); 612 mm_camera_obj_t * my_obj = NULL; 613 614 pthread_mutex_lock(&g_intf_lock); 615 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 616 617 if(my_obj) { 618 pthread_mutex_lock(&my_obj->cam_lock); 619 pthread_mutex_unlock(&g_intf_lock); 620 rc = mm_camera_request_super_buf(my_obj, ch_id, num_buf_requested); 621 } else { 622 pthread_mutex_unlock(&g_intf_lock); 623 } 624 CDBG("%s :X rc = %d",__func__,rc); 625 return rc; 626 } 627 628 static int32_t mm_camera_intf_cancel_super_buf_request( 629 uint32_t camera_handler, 630 uint32_t ch_id) 631 { 632 int32_t rc = -1; 633 mm_camera_obj_t * my_obj = NULL; 634 635 CDBG("%s :E camera_handler = %d,ch_id = %d", 636 __func__,camera_handler,ch_id); 637 pthread_mutex_lock(&g_intf_lock); 638 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 639 640 if(my_obj) { 641 pthread_mutex_lock(&my_obj->cam_lock); 642 pthread_mutex_unlock(&g_intf_lock); 643 rc = mm_camera_cancel_super_buf_request(my_obj, ch_id); 644 } else { 645 pthread_mutex_unlock(&g_intf_lock); 646 } 647 CDBG("%s :X rc = %d",__func__,rc); 648 return rc; 649 } 650 651 static int32_t mm_camera_intf_start_focus( 652 uint32_t camera_handler, 653 uint32_t ch_id, 654 uint32_t sensor_idx, 655 uint32_t focus_mode) 656 { 657 int32_t rc = -1; 658 mm_camera_obj_t * my_obj = NULL; 659 660 CDBG("%s :E camera_handler = %d,ch_id = %d, focus_mode = %d", 661 __func__,camera_handler,ch_id,focus_mode); 662 pthread_mutex_lock(&g_intf_lock); 663 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 664 665 if(my_obj) { 666 pthread_mutex_lock(&my_obj->cam_lock); 667 pthread_mutex_unlock(&g_intf_lock); 668 rc = mm_camera_start_focus(my_obj, ch_id, sensor_idx, focus_mode); 669 } else { 670 pthread_mutex_unlock(&g_intf_lock); 671 } 672 CDBG("%s :X rc = %d",__func__,rc); 673 return rc; 674 } 675 676 static int32_t mm_camera_intf_abort_focus( 677 uint32_t camera_handler, 678 uint32_t ch_id, 679 uint32_t sensor_idx) 680 { 681 int32_t rc = -1; 682 mm_camera_obj_t * my_obj = NULL; 683 684 pthread_mutex_lock(&g_intf_lock); 685 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 686 687 if(my_obj) { 688 pthread_mutex_lock(&my_obj->cam_lock); 689 pthread_mutex_unlock(&g_intf_lock); 690 rc = mm_camera_abort_focus(my_obj, ch_id, sensor_idx); 691 } else { 692 pthread_mutex_unlock(&g_intf_lock); 693 } 694 CDBG("%s :X rc = %d",__func__,rc); 695 return rc; 696 } 697 698 static int32_t mm_camera_intf_prepare_snapshot( 699 uint32_t camera_handler, 700 uint32_t ch_id, 701 uint32_t sensor_idx) 702 { 703 int32_t rc = -1; 704 mm_camera_obj_t * my_obj = NULL; 705 706 pthread_mutex_lock(&g_intf_lock); 707 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 708 709 if(my_obj) { 710 pthread_mutex_lock(&my_obj->cam_lock); 711 pthread_mutex_unlock(&g_intf_lock); 712 rc = mm_camera_prepare_snapshot(my_obj, ch_id, sensor_idx); 713 } else { 714 pthread_mutex_unlock(&g_intf_lock); 715 } 716 CDBG("%s :X rc = %d",__func__,rc); 717 return rc; 718 } 719 720 static int32_t mm_camera_intf_set_stream_parm( 721 uint32_t camera_handle, 722 uint32_t ch_id, 723 uint32_t s_id, 724 mm_camera_stream_parm_t parm_type, 725 void* p_value) 726 { 727 int32_t rc = -1; 728 mm_camera_obj_t * my_obj = NULL; 729 730 pthread_mutex_lock(&g_intf_lock); 731 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 732 733 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__, 734 camera_handle,ch_id,s_id,parm_type); 735 736 if(my_obj) { 737 pthread_mutex_lock(&my_obj->cam_lock); 738 pthread_mutex_unlock(&g_intf_lock); 739 rc = mm_camera_set_stream_parm(my_obj,ch_id,s_id, 740 parm_type, 741 p_value); 742 }else{ 743 pthread_mutex_unlock(&g_intf_lock); 744 } 745 CDBG("%s :X rc = %d",__func__,rc); 746 return rc; 747 } 748 749 static int32_t mm_camera_intf_get_stream_parm( 750 uint32_t camera_handle, 751 uint32_t ch_id, 752 uint32_t s_id, 753 mm_camera_stream_parm_t parm_type, 754 void* p_value) 755 { 756 int32_t rc = -1; 757 mm_camera_obj_t * my_obj = NULL; 758 759 pthread_mutex_lock(&g_intf_lock); 760 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 761 762 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__, 763 camera_handle,ch_id,s_id,parm_type); 764 765 if(my_obj) { 766 pthread_mutex_lock(&my_obj->cam_lock); 767 pthread_mutex_unlock(&g_intf_lock); 768 rc = mm_camera_get_stream_parm(my_obj,ch_id,s_id, 769 parm_type, 770 p_value); 771 }else{ 772 pthread_mutex_unlock(&g_intf_lock); 773 } 774 775 CDBG("%s :X rc = %d",__func__,rc); 776 return rc; 777 } 778 779 static int32_t mm_camera_intf_send_private_ioctl(uint32_t camera_handle, 780 uint32_t cmd_id, 781 uint32_t cmd_length, 782 void *cmd) 783 { 784 int32_t rc = -1; 785 mm_camera_obj_t *my_obj = NULL; 786 787 pthread_mutex_lock(&g_oem_lock); 788 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 789 790 if (my_obj) { 791 rc = mm_camera_send_private_ioctl(my_obj, cmd_id, cmd_length, cmd); 792 } 793 794 pthread_mutex_unlock(&g_oem_lock); 795 CDBG("%s :X rc = %d", __func__, rc); 796 return rc; 797 } 798 799 static int32_t mm_camera_intf_send_native_cmd(uint32_t camera_handle, 800 uint32_t cmd_id, 801 uint32_t cmd_length, 802 void *cmd) 803 { 804 int32_t rc = -1; 805 mm_camera_obj_t *my_obj = NULL; 806 807 pthread_mutex_lock(&g_intf_lock); 808 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 809 810 if (!cmd) { 811 CDBG_ERROR("%s Null cmd ", __func__); 812 return -EINVAL; 813 } 814 815 if (my_obj) { 816 pthread_mutex_lock(&my_obj->cam_lock); 817 pthread_mutex_unlock(&g_intf_lock); 818 switch(cmd_id) { 819 case NATIVE_CMD_ID_SOCKET_MAP: { 820 cam_sock_packet_t packet; 821 memset(&packet, 0, sizeof(cam_sock_packet_t)); 822 memcpy(&packet.payload.frame_fd_map, cmd, sizeof(mm_camera_frame_map_type)); 823 if(packet.payload.frame_fd_map.is_hist) { 824 packet.msg_type = CAM_SOCK_MSG_TYPE_HIST_MAPPING; 825 } else { 826 packet.msg_type = CAM_SOCK_MSG_TYPE_FD_MAPPING; 827 } 828 rc = mm_camera_util_sendmsg(my_obj, &packet, 829 sizeof(cam_sock_packet_t), 830 packet.payload.frame_fd_map.fd); 831 } 832 break; 833 case NATIVE_CMD_ID_SOCKET_UNMAP: { 834 cam_sock_packet_t packet; 835 memset(&packet, 0, sizeof(cam_sock_packet_t)); 836 memcpy(&packet.payload.frame_fd_unmap, cmd, sizeof(mm_camera_frame_unmap_type)); 837 if(packet.payload.frame_fd_unmap.is_hist) { 838 packet.msg_type = CAM_SOCK_MSG_TYPE_HIST_UNMAPPING; 839 } else { 840 packet.msg_type = CAM_SOCK_MSG_TYPE_FD_UNMAPPING; 841 } 842 rc = mm_camera_util_sendmsg(my_obj, &packet, 843 sizeof(cam_sock_packet_t), 0); 844 } 845 break; 846 case NATIVE_CMD_ID_IOCTL_CTRL: 847 /* may switch to send through native ctrl cmd ioctl */ 848 rc = mm_camera_util_sendmsg(my_obj, cmd, 849 cmd_length, 0); 850 #if 0 851 rc = mm_camera_send_native_ctrl_cmd(my_obj, cmd_id, 852 cmd_length, cmd); 853 #endif 854 break; 855 default: 856 CDBG_ERROR("%s Invalid native cmd id %d ", __func__, cmd_id); 857 rc = -EINVAL; 858 break; 859 } 860 pthread_mutex_unlock(&my_obj->cam_lock); 861 } else { 862 pthread_mutex_unlock(&g_intf_lock); 863 } 864 865 CDBG("%s :X rc = %d", __func__, rc); 866 return rc; 867 } 868 869 static int32_t mm_camera_intf_send_cmd(uint32_t camera_handle, 870 mm_camera_cmd_type_t cmd_type, 871 uint32_t cmd_id, 872 uint32_t cmd_length, 873 void *cmd) 874 { 875 int32_t rc = -1; 876 877 switch (cmd_type) { 878 case MM_CAMERA_CMD_TYPE_PRIVATE: 879 /* OEM private ioctl */ 880 rc = mm_camera_intf_send_private_ioctl(camera_handle, cmd_id, cmd_length, cmd); 881 break; 882 case MM_CAMERA_CMD_TYPE_NATIVE: 883 rc = mm_camera_intf_send_native_cmd(camera_handle, cmd_id, cmd_length, cmd); 884 break; 885 } 886 887 return rc; 888 } 889 890 static uint32_t mm_camera_intf_open_repro_isp(uint32_t camera_handle, 891 uint32_t ch_id, 892 mm_camera_repro_isp_type_t repro_isp_type) 893 { 894 int32_t rc = -1; 895 mm_camera_obj_t * my_obj = NULL; 896 uint32_t repro_isp_handle = 0; 897 898 pthread_mutex_lock(&g_intf_lock); 899 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 900 901 if(my_obj) { 902 pthread_mutex_lock(&my_obj->cam_lock); 903 pthread_mutex_unlock(&g_intf_lock); 904 rc = mm_camera_open_repro_isp(my_obj, 905 ch_id, 906 repro_isp_type, 907 &repro_isp_handle); 908 }else{ 909 pthread_mutex_unlock(&g_intf_lock); 910 } 911 912 CDBG("%s :X rc = %d",__func__,rc); 913 return repro_isp_handle; 914 } 915 916 static int32_t mm_camera_intf_config_repro_isp(uint32_t camera_handle, 917 uint32_t ch_id, 918 uint32_t repro_isp_handle, 919 mm_camera_repro_isp_config_t *config) 920 { 921 int32_t rc = -1; 922 mm_camera_obj_t * my_obj = NULL; 923 924 pthread_mutex_lock(&g_intf_lock); 925 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 926 927 if(my_obj) { 928 pthread_mutex_lock(&my_obj->cam_lock); 929 pthread_mutex_unlock(&g_intf_lock); 930 rc = mm_camera_config_repro_isp(my_obj, 931 ch_id, 932 repro_isp_handle, 933 config); 934 }else{ 935 pthread_mutex_unlock(&g_intf_lock); 936 } 937 938 CDBG("%s :X rc = %d",__func__,rc); 939 return rc; 940 } 941 942 static int32_t mm_camera_intf_attach_stream_to_repro_isp(uint32_t camera_handle, 943 uint32_t ch_id, 944 uint32_t repro_isp_handle, 945 uint32_t stream_id) 946 { 947 int32_t rc = -1; 948 mm_camera_obj_t * my_obj = NULL; 949 950 pthread_mutex_lock(&g_intf_lock); 951 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 952 953 if(my_obj) { 954 pthread_mutex_lock(&my_obj->cam_lock); 955 pthread_mutex_unlock(&g_intf_lock); 956 rc = mm_camera_attach_stream_to_repro_isp(my_obj, 957 ch_id, 958 repro_isp_handle, 959 stream_id); 960 }else{ 961 pthread_mutex_unlock(&g_intf_lock); 962 } 963 964 CDBG("%s :X rc = %d",__func__,rc); 965 return rc; 966 } 967 968 static int32_t mm_camera_intf_start_repro_isp(uint32_t camera_handle, 969 uint32_t ch_id, 970 uint32_t repro_isp_handle, 971 uint32_t stream_id) 972 { 973 int32_t rc = -1; 974 mm_camera_obj_t * my_obj = NULL; 975 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_start_repro_isp(my_obj, 983 ch_id, 984 repro_isp_handle, 985 stream_id); 986 }else{ 987 pthread_mutex_unlock(&g_intf_lock); 988 } 989 990 CDBG("%s :X rc = %d",__func__,rc); 991 return rc; 992 } 993 994 static int32_t mm_camera_intf_reprocess(uint32_t camera_handle, 995 uint32_t ch_id, 996 uint32_t repro_isp_handle, 997 mm_camera_repro_data_t *repro_data) 998 { 999 int32_t rc = -1; 1000 mm_camera_obj_t * my_obj = NULL; 1001 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_reprocess(my_obj, 1009 ch_id, 1010 repro_isp_handle, 1011 repro_data); 1012 }else{ 1013 pthread_mutex_unlock(&g_intf_lock); 1014 } 1015 1016 CDBG("%s :X rc = %d",__func__,rc); 1017 return rc; 1018 } 1019 1020 static int32_t mm_camera_intf_stop_repro_isp(uint32_t camera_handle, 1021 uint32_t ch_id, 1022 uint32_t repro_isp_handle, 1023 uint32_t stream_id) 1024 { 1025 int32_t rc = -1; 1026 mm_camera_obj_t * my_obj = NULL; 1027 1028 pthread_mutex_lock(&g_intf_lock); 1029 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1030 1031 if(my_obj) { 1032 pthread_mutex_lock(&my_obj->cam_lock); 1033 pthread_mutex_unlock(&g_intf_lock); 1034 rc = mm_camera_stop_repro_isp(my_obj, 1035 ch_id, 1036 repro_isp_handle, 1037 stream_id); 1038 }else{ 1039 pthread_mutex_unlock(&g_intf_lock); 1040 } 1041 1042 CDBG("%s :X rc = %d",__func__,rc); 1043 return rc; 1044 } 1045 1046 static int32_t mm_camera_intf_detach_stream_from_repro_isp(uint32_t camera_handle, 1047 uint32_t ch_id, 1048 uint32_t repro_isp_handle, 1049 uint32_t stream_id) 1050 { 1051 int32_t rc = -1; 1052 mm_camera_obj_t * my_obj = NULL; 1053 1054 pthread_mutex_lock(&g_intf_lock); 1055 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 1056 1057 if(my_obj) { 1058 pthread_mutex_lock(&my_obj->cam_lock); 1059 pthread_mutex_unlock(&g_intf_lock); 1060 rc = mm_camera_detach_stream_from_repro_isp(my_obj, 1061 ch_id, 1062 repro_isp_handle, 1063 stream_id); 1064 }else{ 1065 pthread_mutex_unlock(&g_intf_lock); 1066 } 1067 1068 CDBG("%s :X rc = %d",__func__,rc); 1069 return rc; 1070 } 1071 1072 static int32_t mm_camera_intf_close_repro_isp(uint32_t camera_handle, 1073 uint32_t ch_id, 1074 uint32_t repro_isp_handle) 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_close_repro_isp(my_obj, 1086 ch_id, 1087 repro_isp_handle); 1088 }else{ 1089 pthread_mutex_unlock(&g_intf_lock); 1090 } 1091 1092 CDBG("%s :X rc = %d",__func__,rc); 1093 return rc; 1094 } 1095 1096 mm_camera_info_t * camera_query(uint8_t *num_cameras) 1097 { 1098 int i = 0, rc = 0; 1099 int dev_fd = 0; 1100 struct media_device_info mdev_info; 1101 int num_media_devices = 0; 1102 if (!num_cameras) { 1103 CDBG_ERROR("%s: num_cameras is NULL\n", __func__); 1104 return NULL; 1105 } 1106 1107 CDBG("%s : E",__func__); 1108 /* lock the mutex */ 1109 pthread_mutex_lock(&g_intf_lock); 1110 *num_cameras = 0; 1111 while (1) { 1112 char dev_name[32]; 1113 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 1114 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 1115 if (dev_fd < 0) { 1116 CDBG("Done discovering media devices\n"); 1117 break; 1118 } 1119 num_media_devices++; 1120 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 1121 if (rc < 0) { 1122 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 1123 close(dev_fd); 1124 break; 1125 } 1126 1127 if(strncmp(mdev_info.model, QCAMERA_NAME, sizeof(mdev_info.model) != 0)) { 1128 close(dev_fd); 1129 continue; 1130 } 1131 1132 char * mdev_cfg; 1133 int cam_type = 0, mount_angle = 0, info_index = 0; 1134 mdev_cfg = strtok(mdev_info.serial, "-"); 1135 while(mdev_cfg != NULL) { 1136 if(info_index == 0) { 1137 if(strcmp(mdev_cfg, QCAMERA_NAME)) 1138 break; 1139 } else if(info_index == 1) { 1140 mount_angle = atoi(mdev_cfg); 1141 } else if(info_index == 2) { 1142 cam_type = atoi(mdev_cfg); 1143 } 1144 mdev_cfg = strtok(NULL, "-"); 1145 info_index++; 1146 } 1147 1148 if(info_index == 0) { 1149 close(dev_fd); 1150 continue; 1151 } 1152 1153 int num_entities = 1; 1154 while (1) { 1155 struct media_entity_desc entity; 1156 memset(&entity, 0, sizeof(entity)); 1157 entity.id = num_entities++; 1158 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 1159 if (rc < 0) { 1160 CDBG("Done enumerating media entities\n"); 1161 rc = 0; 1162 break; 1163 } 1164 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) { 1165 strncpy(g_cam_ctrl.video_dev_name[*num_cameras], 1166 entity.name, sizeof(entity.name)); 1167 g_cam_ctrl.camera[*num_cameras].video_dev_name = 1168 &g_cam_ctrl.video_dev_name[*num_cameras][0]; 1169 break; 1170 } 1171 } 1172 1173 //g_cam_ctrl.camera[*num_cameras].camera_info.camera_id = *num_cameras; 1174 g_cam_ctrl.camera[*num_cameras].camera_id = *num_cameras; 1175 1176 g_cam_ctrl.camera[*num_cameras]. 1177 camera_info.modes_supported = CAMERA_MODE_2D; 1178 1179 if(cam_type > 1) { 1180 g_cam_ctrl.camera[*num_cameras]. 1181 camera_info.modes_supported |= CAMERA_MODE_3D; 1182 } 1183 1184 g_cam_ctrl.camera[*num_cameras].camera_info.position = 1185 (cam_type == 1) ? FRONT_CAMERA : BACK_CAMERA; 1186 1187 g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle = 1188 mount_angle; 1189 1190 g_cam_ctrl.camera[*num_cameras].main_sensor_type = 0; 1191 1192 CDBG("%s: dev_info[id=%d,name='%s',pos=%d,modes=0x%x,sensor=%d mount_angle = %d]\n", 1193 __func__, *num_cameras, 1194 g_cam_ctrl.camera[*num_cameras].video_dev_name, 1195 g_cam_ctrl.camera[*num_cameras].camera_info.position, 1196 g_cam_ctrl.camera[*num_cameras].camera_info.modes_supported, 1197 g_cam_ctrl.camera[*num_cameras].main_sensor_type, 1198 g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle); 1199 1200 *num_cameras += 1; 1201 if (dev_fd > 0) { 1202 close(dev_fd); 1203 } 1204 } 1205 *num_cameras = *num_cameras; 1206 g_cam_ctrl.num_cam = *num_cameras; 1207 1208 /* unlock the mutex */ 1209 pthread_mutex_unlock(&g_intf_lock); 1210 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam); 1211 if(rc == 0) 1212 return &g_cam_ctrl.camera[0]; 1213 else 1214 return NULL; 1215 } 1216 1217 /* camera ops v-table */ 1218 static mm_camera_ops_t mm_camera_ops = { 1219 .sync = mm_camera_intf_sync, 1220 .is_event_supported = mm_camera_intf_is_event_supported, 1221 .register_event_notify = mm_camera_intf_register_event_notify, 1222 .qbuf = mm_camera_intf_qbuf, 1223 .camera_close = mm_camera_intf_close, 1224 .query_2nd_sensor_info = mm_camera_intf_query_2nd_sensor_info, 1225 .is_op_supported = mm_camera_intf_is_op_supported, 1226 .is_parm_supported = mm_camera_intf_is_parm_supported, 1227 .set_parm = mm_camera_intf_set_parm, 1228 .get_parm = mm_camera_intf_get_parm, 1229 .ch_acquire = mm_camera_intf_add_channel, 1230 .ch_release = mm_camera_intf_del_channel, 1231 .add_stream = mm_camera_intf_add_stream, 1232 .del_stream = mm_camera_intf_del_stream, 1233 .config_stream = mm_camera_intf_config_stream, 1234 .init_stream_bundle = mm_camera_intf_bundle_streams, 1235 .destroy_stream_bundle = mm_camera_intf_destroy_bundle, 1236 .start_streams = mm_camera_intf_start_streams, 1237 .stop_streams = mm_camera_intf_stop_streams, 1238 .async_teardown_streams = mm_camera_intf_async_teardown_streams, 1239 .request_super_buf = mm_camera_intf_request_super_buf, 1240 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request, 1241 .start_focus = mm_camera_intf_start_focus, 1242 .abort_focus = mm_camera_intf_abort_focus, 1243 .prepare_snapshot = mm_camera_intf_prepare_snapshot, 1244 .set_stream_parm = mm_camera_intf_set_stream_parm, 1245 .get_stream_parm = mm_camera_intf_get_stream_parm, 1246 .send_command = mm_camera_intf_send_cmd, 1247 .open_repro_isp = mm_camera_intf_open_repro_isp, 1248 .config_repro_isp = mm_camera_intf_config_repro_isp, 1249 .attach_stream_to_repro_isp = mm_camera_intf_attach_stream_to_repro_isp, 1250 .start_repro_isp = mm_camera_intf_start_repro_isp, 1251 .reprocess = mm_camera_intf_reprocess, 1252 .stop_repro_isp = mm_camera_intf_stop_repro_isp, 1253 .detach_stream_from_repro_isp = mm_camera_intf_detach_stream_from_repro_isp, 1254 .close_repro_isp = mm_camera_intf_close_repro_isp 1255 }; 1256 1257 /* open camera. */ 1258 mm_camera_vtbl_t * camera_open(uint8_t camera_idx, 1259 mm_camear_mem_vtbl_t *mem_vtbl) 1260 { 1261 int32_t rc = 0; 1262 mm_camera_obj_t* cam_obj = NULL; 1263 1264 CDBG("%s: E camera_idx = %d\n", __func__,camera_idx); 1265 if (MSM_MAX_CAMERA_SENSORS <= camera_idx) { 1266 CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx); 1267 return NULL; 1268 } 1269 1270 pthread_mutex_lock(&g_oem_lock); 1271 pthread_mutex_lock(&g_intf_lock); 1272 /* opened already */ 1273 if(NULL != g_cam_ctrl.cam_obj[camera_idx]) { 1274 /* Add reference */ 1275 g_cam_ctrl.cam_obj[camera_idx]->ref_count++; 1276 pthread_mutex_unlock(&g_intf_lock); 1277 pthread_mutex_unlock(&g_oem_lock); 1278 CDBG("%s: opened alreadyn", __func__); 1279 return &cam_obj->vtbl; 1280 } 1281 1282 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t)); 1283 if(NULL == cam_obj) { 1284 pthread_mutex_unlock(&g_intf_lock); 1285 pthread_mutex_unlock(&g_oem_lock); 1286 CDBG("%s: no mem", __func__); 1287 return NULL; 1288 } 1289 1290 /* initialize camera obj */ 1291 memset(cam_obj, 0, sizeof(mm_camera_obj_t)); 1292 cam_obj->ctrl_fd = -1; 1293 cam_obj->ds_fd = -1; 1294 cam_obj->ref_count++; 1295 cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx); 1296 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */ 1297 cam_obj->vtbl.camera_info = &g_cam_ctrl.camera[camera_idx]; 1298 cam_obj->vtbl.ops = &mm_camera_ops; 1299 cam_obj->mem_vtbl = mem_vtbl; /* save mem_vtbl */ 1300 pthread_mutex_init(&cam_obj->cam_lock, NULL); 1301 1302 rc = mm_camera_open(cam_obj); 1303 if(rc != 0) { 1304 CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc); 1305 pthread_mutex_destroy(&cam_obj->cam_lock); 1306 g_cam_ctrl.cam_obj[camera_idx] = NULL; 1307 free(cam_obj); 1308 cam_obj = NULL; 1309 pthread_mutex_unlock(&g_intf_lock); 1310 pthread_mutex_unlock(&g_oem_lock); 1311 return NULL; 1312 }else{ 1313 CDBG("%s: Open succeded\n", __func__); 1314 g_cam_ctrl.cam_obj[camera_idx] = cam_obj; 1315 pthread_mutex_unlock(&g_intf_lock); 1316 pthread_mutex_unlock(&g_oem_lock); 1317 return &cam_obj->vtbl; 1318 } 1319 } 1320