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.h" 43 44 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER; 45 46 static mm_camera_ctrl_t g_cam_ctrl = {{{0, {0, 0, 0, 0}, 0, 0}}, 0, {{0}}, {0}}; 47 48 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER; 49 static uint16_t g_handler_history_count = 0; /* history count for handler */ 50 51 /* utility function to generate handler */ 52 uint32_t mm_camera_util_generate_handler(uint8_t index) 53 { 54 uint32_t handler = 0; 55 pthread_mutex_lock(&g_handler_lock); 56 g_handler_history_count++; 57 if (0 == g_handler_history_count) { 58 g_handler_history_count++; 59 } 60 handler = g_handler_history_count; 61 handler = (handler<<8) | index; 62 pthread_mutex_unlock(&g_handler_lock); 63 return handler; 64 } 65 66 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler) 67 { 68 return (handler&0x000000ff); 69 } 70 71 const char *mm_camera_util_get_dev_name(uint32_t cam_handler) 72 { 73 char *dev_name = NULL; 74 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler); 75 dev_name = g_cam_ctrl.camera[cam_idx].video_dev_name; 76 return dev_name; 77 } 78 79 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler) 80 { 81 mm_camera_obj_t *cam_obj = NULL; 82 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler); 83 84 if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) && 85 (cam_handler == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) { 86 cam_obj = g_cam_ctrl.cam_obj[cam_idx]; 87 } 88 return cam_obj; 89 } 90 91 static int32_t mm_camera_intf_sync(uint32_t camera_handler) 92 { 93 int32_t rc = -1; 94 mm_camera_obj_t * my_obj = NULL; 95 96 CDBG("%s E: camera_handler = %d ",__func__,camera_handler); 97 98 pthread_mutex_lock(&g_intf_lock); 99 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 100 101 if(my_obj) { 102 pthread_mutex_lock(&my_obj->cam_lock); 103 pthread_mutex_unlock(&g_intf_lock); 104 rc = mm_camera_sync(my_obj); 105 } else { 106 pthread_mutex_unlock(&g_intf_lock); 107 } 108 CDBG("%s :X rc = %d",__func__,rc); 109 return rc; 110 } 111 112 /* check if the parm is supported */ 113 static int32_t mm_camera_intf_is_parm_supported(uint32_t camera_handler, 114 mm_camera_parm_type_t parm_type, 115 uint8_t *support_set_parm, 116 uint8_t *support_get_parm) 117 { 118 int32_t rc = -1; 119 mm_camera_obj_t * my_obj = NULL; 120 121 pthread_mutex_lock(&g_intf_lock); 122 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 123 *support_set_parm = 0; 124 *support_get_parm = 0; 125 126 if(my_obj) { 127 pthread_mutex_lock(&my_obj->cam_lock); 128 pthread_mutex_unlock(&g_intf_lock); 129 rc = mm_camera_is_parm_supported(my_obj, parm_type, support_set_parm, support_get_parm); 130 } else { 131 pthread_mutex_unlock(&g_intf_lock); 132 } 133 return rc; 134 } 135 136 /* set a parms current value */ 137 static int32_t mm_camera_intf_set_parm(uint32_t camera_handler, 138 mm_camera_parm_type_t parm_type, 139 void* p_value) 140 { 141 int32_t rc = -1; 142 mm_camera_obj_t * my_obj = NULL; 143 144 pthread_mutex_lock(&g_intf_lock); 145 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 146 147 if(my_obj) { 148 pthread_mutex_lock(&my_obj->cam_lock); 149 pthread_mutex_unlock(&g_intf_lock); 150 rc = mm_camera_set_parm(my_obj, parm_type, p_value); 151 } else { 152 pthread_mutex_unlock(&g_intf_lock); 153 } 154 return rc; 155 } 156 157 /* get a parms current value */ 158 static int32_t mm_camera_intf_get_parm(uint32_t camera_handler, 159 mm_camera_parm_type_t parm_type, 160 void* p_value) 161 { 162 int32_t rc = -1; 163 mm_camera_obj_t * my_obj = NULL; 164 165 pthread_mutex_lock(&g_intf_lock); 166 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 167 168 if(my_obj) { 169 pthread_mutex_lock(&my_obj->cam_lock); 170 pthread_mutex_unlock(&g_intf_lock); 171 rc = mm_camera_get_parm(my_obj, parm_type, p_value); 172 } else { 173 pthread_mutex_unlock(&g_intf_lock); 174 } 175 return rc; 176 } 177 178 static void mm_camera_intf_close(uint32_t camera_handler) 179 { 180 int32_t rc = -1; 181 uint8_t cam_idx = camera_handler & 0x00ff; 182 mm_camera_obj_t * my_obj = NULL; 183 184 CDBG("%s E: camera_handler = %d ",__func__,camera_handler); 185 pthread_mutex_lock(&g_intf_lock); 186 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 187 188 if (my_obj){ 189 my_obj->ref_count--; 190 191 if(my_obj->ref_count > 0) { 192 /* still have reference to obj, return here */ 193 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count); 194 pthread_mutex_unlock(&g_intf_lock); 195 return; 196 } 197 198 /* need close camera here as no other reference 199 * first empty g_cam_ctrl's referent to cam_obj */ 200 g_cam_ctrl.cam_obj[cam_idx] = NULL; 201 202 pthread_mutex_lock(&my_obj->cam_lock); 203 pthread_mutex_unlock(&g_intf_lock); 204 205 mm_camera_close(my_obj); 206 207 pthread_mutex_destroy(&my_obj->cam_lock); 208 free(my_obj); 209 210 } else { 211 pthread_mutex_unlock(&g_intf_lock); 212 } 213 } 214 215 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handler) 216 { 217 uint32_t ch_id = 0; 218 mm_camera_obj_t * my_obj = NULL; 219 220 CDBG("%s :E camera_handler = %d",__func__,camera_handler); 221 pthread_mutex_lock(&g_intf_lock); 222 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 223 224 if(my_obj) { 225 pthread_mutex_lock(&my_obj->cam_lock); 226 pthread_mutex_unlock(&g_intf_lock); 227 ch_id = mm_camera_add_channel(my_obj); 228 } else { 229 pthread_mutex_unlock(&g_intf_lock); 230 } 231 CDBG("%s :X ch_id = %d",__func__,ch_id); 232 return ch_id; 233 } 234 235 static void mm_camera_intf_del_channel(uint32_t camera_handler, uint32_t ch_id) 236 { 237 mm_camera_obj_t * my_obj = NULL; 238 239 CDBG("%s :E ch_id = %d",__func__,ch_id); 240 pthread_mutex_lock(&g_intf_lock); 241 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 242 243 if(my_obj) { 244 pthread_mutex_lock(&my_obj->cam_lock); 245 pthread_mutex_unlock(&g_intf_lock); 246 mm_camera_del_channel(my_obj, ch_id); 247 } else { 248 pthread_mutex_unlock(&g_intf_lock); 249 } 250 CDBG("%s :X",__func__); 251 } 252 253 static uint8_t mm_camera_intf_is_event_supported(uint32_t camera_handler, 254 mm_camera_event_type_t evt_type) 255 { 256 switch(evt_type) { 257 case MM_CAMERA_EVT_TYPE_CH: 258 case MM_CAMERA_EVT_TYPE_CTRL: 259 case MM_CAMERA_EVT_TYPE_STATS: 260 case MM_CAMERA_EVT_TYPE_INFO: 261 return 1; 262 default: 263 return 0; 264 } 265 return 0; 266 } 267 268 static int32_t mm_camera_intf_register_event_notify( 269 uint32_t camera_handler, 270 mm_camera_event_notify_t evt_cb, 271 void * user_data, 272 mm_camera_event_type_t evt_type) 273 { 274 int32_t rc = -1; 275 mm_camera_obj_t * my_obj = NULL; 276 277 CDBG("%s :E evt_type = %d",__func__,evt_type); 278 pthread_mutex_lock(&g_intf_lock); 279 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 280 281 if(my_obj) { 282 pthread_mutex_lock(&my_obj->cam_lock); 283 pthread_mutex_unlock(&g_intf_lock); 284 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data, evt_type); 285 } else { 286 pthread_mutex_unlock(&g_intf_lock); 287 } 288 CDBG("%s :E rc = %d",__func__,rc); 289 return rc; 290 } 291 292 static mm_camera_2nd_sensor_t * mm_camera_intf_query_2nd_sensor_info(uint32_t camera_handler) 293 { 294 mm_camera_2nd_sensor_t *sensor_info = NULL; 295 mm_camera_obj_t * my_obj = NULL; 296 297 CDBG("%s :E camera_handler = %d",__func__,camera_handler); 298 pthread_mutex_lock(&g_intf_lock); 299 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 300 301 if(my_obj) { 302 pthread_mutex_lock(&my_obj->cam_lock); 303 pthread_mutex_unlock(&g_intf_lock); 304 sensor_info = mm_camera_query_2nd_sensor_info(my_obj); 305 } else { 306 pthread_mutex_unlock(&g_intf_lock); 307 } 308 CDBG("%s :X",__func__); 309 return sensor_info; 310 } 311 312 static int32_t mm_camera_intf_qbuf(uint32_t camera_handler, 313 uint32_t ch_id, 314 mm_camera_buf_def_t *buf) 315 { 316 int32_t rc = -1; 317 mm_camera_obj_t * my_obj = NULL; 318 319 pthread_mutex_lock(&g_intf_lock); 320 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 321 322 if(my_obj) { 323 pthread_mutex_lock(&my_obj->cam_lock); 324 pthread_mutex_unlock(&g_intf_lock); 325 rc = mm_camera_qbuf(my_obj, ch_id, buf); 326 } else { 327 pthread_mutex_unlock(&g_intf_lock); 328 } 329 CDBG("%s :X evt_type = %d",__func__,rc); 330 return rc; 331 } 332 333 static uint32_t mm_camera_intf_add_stream( 334 uint32_t camera_handler, 335 uint32_t ch_id, 336 mm_camera_buf_notify_t buf_cb, void *user_data, 337 uint32_t ext_image_mode, uint32_t sensor_idx) 338 { 339 uint32_t stream_id = 0; 340 mm_camera_obj_t * my_obj = NULL; 341 342 CDBG("%s : E handle = %d ch_id = %d",__func__,camera_handler, 343 ch_id); 344 345 pthread_mutex_lock(&g_intf_lock); 346 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 347 348 if(my_obj) { 349 pthread_mutex_lock(&my_obj->cam_lock); 350 pthread_mutex_unlock(&g_intf_lock); 351 stream_id = mm_camera_add_stream(my_obj, ch_id, buf_cb, 352 user_data, ext_image_mode, sensor_idx); 353 } else { 354 pthread_mutex_unlock(&g_intf_lock); 355 } 356 CDBG("%s :X stream_id = %d",__func__,stream_id); 357 return stream_id; 358 } 359 360 static int32_t mm_camera_intf_del_stream( 361 uint32_t camera_handler, 362 uint32_t ch_id, 363 uint32_t stream_id) 364 { 365 int32_t rc = -1; 366 mm_camera_obj_t * my_obj = NULL; 367 368 CDBG("%s : E handle = %d ch_id = %d stream_id = %d",__func__,camera_handler, 369 ch_id,stream_id); 370 371 pthread_mutex_lock(&g_intf_lock); 372 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 373 374 if(my_obj) { 375 pthread_mutex_lock(&my_obj->cam_lock); 376 pthread_mutex_unlock(&g_intf_lock); 377 rc = mm_camera_del_stream(my_obj, ch_id, stream_id); 378 } else { 379 pthread_mutex_unlock(&g_intf_lock); 380 } 381 CDBG("%s :X rc = %d",__func__,rc); 382 return rc; 383 } 384 385 static int32_t mm_camera_intf_config_stream( 386 uint32_t camera_handler, 387 uint32_t ch_id, 388 uint32_t stream_id, 389 mm_camera_stream_config_t *config) 390 { 391 int32_t rc = -1; 392 mm_camera_obj_t * my_obj = NULL; 393 394 CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",__func__, 395 camera_handler,ch_id,stream_id); 396 397 pthread_mutex_lock(&g_intf_lock); 398 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 399 400 CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id); 401 402 if(my_obj) { 403 pthread_mutex_lock(&my_obj->cam_lock); 404 pthread_mutex_unlock(&g_intf_lock); 405 rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config); 406 } else { 407 pthread_mutex_unlock(&g_intf_lock); 408 } 409 CDBG("%s :X rc = %d",__func__,rc); 410 return rc; 411 } 412 413 static int32_t mm_camera_intf_bundle_streams( 414 uint32_t camera_handler, 415 uint32_t ch_id, 416 mm_camera_buf_notify_t super_frame_notify_cb, 417 void *user_data, 418 mm_camera_bundle_attr_t *attr, 419 uint8_t num_streams, 420 uint32_t *stream_ids) 421 { 422 int32_t rc = -1; 423 mm_camera_obj_t * my_obj = NULL; 424 425 CDBG("%s :E handle = %d, ch_id = %d",__func__, 426 camera_handler,ch_id); 427 428 if (MM_CAMEAR_MAX_STRAEM_BUNDLE < num_streams) { 429 CDBG_ERROR("%s: number of streams (%d) exceeds max (%d)", 430 __func__, num_streams, MM_CAMEAR_MAX_STRAEM_BUNDLE); 431 return rc; 432 } 433 434 pthread_mutex_lock(&g_intf_lock); 435 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 436 437 if(my_obj) { 438 pthread_mutex_lock(&my_obj->cam_lock); 439 pthread_mutex_unlock(&g_intf_lock); 440 rc = mm_camera_bundle_streams(my_obj, ch_id, 441 super_frame_notify_cb, 442 user_data, attr, 443 num_streams, stream_ids); 444 } else { 445 pthread_mutex_unlock(&g_intf_lock); 446 } 447 CDBG("%s :X rc = %d",__func__,rc); 448 return rc; 449 } 450 451 static int32_t mm_camera_intf_destroy_bundle(uint32_t camera_handler, 452 uint32_t ch_id) 453 { 454 int32_t rc = -1; 455 mm_camera_obj_t * my_obj = NULL; 456 457 CDBG("%s :E handle = %d, ch_id = %d",__func__, 458 camera_handler,ch_id); 459 pthread_mutex_lock(&g_intf_lock); 460 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 461 462 if(my_obj) { 463 pthread_mutex_lock(&my_obj->cam_lock); 464 pthread_mutex_unlock(&g_intf_lock); 465 rc = mm_camera_destroy_bundle(my_obj, ch_id); 466 } else { 467 pthread_mutex_unlock(&g_intf_lock); 468 } 469 CDBG("%s :X rc = %d",__func__,rc); 470 return rc; 471 } 472 473 static int32_t mm_camera_intf_start_streams( 474 uint32_t camera_handler, 475 uint32_t ch_id, 476 uint8_t num_streams, 477 uint32_t *stream_ids) 478 { 479 int32_t rc = -1; 480 mm_camera_obj_t * my_obj = NULL; 481 482 CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d", 483 __func__,camera_handler,ch_id,num_streams); 484 if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) { 485 CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)", 486 __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX); 487 return rc; 488 } 489 490 pthread_mutex_lock(&g_intf_lock); 491 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 492 493 if(my_obj) { 494 pthread_mutex_lock(&my_obj->cam_lock); 495 pthread_mutex_unlock(&g_intf_lock); 496 rc = mm_camera_start_streams(my_obj, ch_id, num_streams, stream_ids); 497 } else { 498 pthread_mutex_unlock(&g_intf_lock); 499 } 500 CDBG("%s :X rc = %d",__func__,rc); 501 return rc; 502 } 503 504 static int32_t mm_camera_intf_stop_streams( 505 uint32_t camera_handler, 506 uint32_t ch_id, 507 uint8_t num_streams, 508 uint32_t *stream_ids) 509 { 510 int32_t rc = -1; 511 mm_camera_obj_t * my_obj = NULL; 512 513 CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d", 514 __func__,camera_handler,ch_id,num_streams); 515 516 if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) { 517 CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)", 518 __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX); 519 return rc; 520 } 521 522 pthread_mutex_lock(&g_intf_lock); 523 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 524 525 if(my_obj) { 526 pthread_mutex_lock(&my_obj->cam_lock); 527 pthread_mutex_unlock(&g_intf_lock); 528 rc = mm_camera_stop_streams(my_obj, ch_id, 529 num_streams, stream_ids); 530 } else { 531 pthread_mutex_unlock(&g_intf_lock); 532 } 533 CDBG("%s :X rc = %d",__func__,rc); 534 return rc; 535 } 536 537 static int32_t mm_camera_intf_async_teardown_streams( 538 uint32_t camera_handler, 539 uint32_t ch_id, 540 uint8_t num_streams, 541 uint32_t *stream_ids) 542 { 543 int32_t rc = -1; 544 mm_camera_obj_t * my_obj = NULL; 545 546 CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d", 547 __func__,camera_handler,ch_id,num_streams); 548 549 if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) { 550 CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)", 551 __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX); 552 return rc; 553 } 554 555 pthread_mutex_lock(&g_intf_lock); 556 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 557 558 if(my_obj) { 559 pthread_mutex_lock(&my_obj->cam_lock); 560 pthread_mutex_unlock(&g_intf_lock); 561 rc = mm_camera_async_teardown_streams(my_obj, ch_id, 562 num_streams, stream_ids); 563 } else { 564 pthread_mutex_unlock(&g_intf_lock); 565 } 566 CDBG("%s :X rc = %d",__func__,rc); 567 return rc; 568 } 569 570 static int32_t mm_camera_intf_request_super_buf( 571 uint32_t camera_handler, 572 uint32_t ch_id) 573 { 574 int32_t rc = -1; 575 CDBG("%s :E camera_handler = %d,ch_id = %d", 576 __func__,camera_handler,ch_id); 577 mm_camera_obj_t * my_obj = NULL; 578 579 pthread_mutex_lock(&g_intf_lock); 580 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 581 582 if(my_obj) { 583 pthread_mutex_lock(&my_obj->cam_lock); 584 pthread_mutex_unlock(&g_intf_lock); 585 rc = mm_camera_request_super_buf(my_obj, ch_id); 586 } else { 587 pthread_mutex_unlock(&g_intf_lock); 588 } 589 CDBG("%s :X rc = %d",__func__,rc); 590 return rc; 591 } 592 593 static int32_t mm_camera_intf_cancel_super_buf_request( 594 uint32_t camera_handler, 595 uint32_t ch_id) 596 { 597 int32_t rc = -1; 598 mm_camera_obj_t * my_obj = NULL; 599 600 CDBG("%s :E camera_handler = %d,ch_id = %d", 601 __func__,camera_handler,ch_id); 602 pthread_mutex_lock(&g_intf_lock); 603 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 604 605 if(my_obj) { 606 pthread_mutex_lock(&my_obj->cam_lock); 607 pthread_mutex_unlock(&g_intf_lock); 608 rc = mm_camera_cancel_super_buf_request(my_obj, ch_id); 609 } else { 610 pthread_mutex_unlock(&g_intf_lock); 611 } 612 CDBG("%s :X rc = %d",__func__,rc); 613 return rc; 614 } 615 616 static int32_t mm_camera_intf_start_focus( 617 uint32_t camera_handler, 618 uint32_t ch_id, 619 uint32_t sensor_idx, 620 uint32_t focus_mode) 621 { 622 int32_t rc = -1; 623 mm_camera_obj_t * my_obj = NULL; 624 625 CDBG("%s :E camera_handler = %d,ch_id = %d, focus_mode = %d", 626 __func__,camera_handler,ch_id,focus_mode); 627 pthread_mutex_lock(&g_intf_lock); 628 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 629 630 if(my_obj) { 631 pthread_mutex_lock(&my_obj->cam_lock); 632 pthread_mutex_unlock(&g_intf_lock); 633 rc = mm_camera_start_focus(my_obj, ch_id, sensor_idx, focus_mode); 634 } else { 635 pthread_mutex_unlock(&g_intf_lock); 636 } 637 CDBG("%s :X rc = %d",__func__,rc); 638 return rc; 639 } 640 641 static int32_t mm_camera_intf_abort_focus( 642 uint32_t camera_handler, 643 uint32_t ch_id, 644 uint32_t sensor_idx) 645 { 646 int32_t rc = -1; 647 mm_camera_obj_t * my_obj = NULL; 648 649 pthread_mutex_lock(&g_intf_lock); 650 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 651 652 if(my_obj) { 653 pthread_mutex_lock(&my_obj->cam_lock); 654 pthread_mutex_unlock(&g_intf_lock); 655 rc = mm_camera_abort_focus(my_obj, ch_id, sensor_idx); 656 } else { 657 pthread_mutex_unlock(&g_intf_lock); 658 } 659 CDBG("%s :X rc = %d",__func__,rc); 660 return rc; 661 } 662 663 static int32_t mm_camera_intf_prepare_snapshot( 664 uint32_t camera_handler, 665 uint32_t ch_id, 666 uint32_t sensor_idx) 667 { 668 int32_t rc = -1; 669 mm_camera_obj_t * my_obj = NULL; 670 671 pthread_mutex_lock(&g_intf_lock); 672 my_obj = mm_camera_util_get_camera_by_handler(camera_handler); 673 674 if(my_obj) { 675 pthread_mutex_lock(&my_obj->cam_lock); 676 pthread_mutex_unlock(&g_intf_lock); 677 rc = mm_camera_prepare_snapshot(my_obj, ch_id, sensor_idx); 678 } else { 679 pthread_mutex_unlock(&g_intf_lock); 680 } 681 CDBG("%s :X rc = %d",__func__,rc); 682 return rc; 683 } 684 685 static int32_t mm_camera_intf_set_stream_parm( 686 uint32_t camera_handle, 687 uint32_t ch_id, 688 uint32_t s_id, 689 mm_camera_stream_parm_t parm_type, 690 void* p_value) 691 { 692 int32_t rc = -1; 693 mm_camera_obj_t * my_obj = NULL; 694 695 pthread_mutex_lock(&g_intf_lock); 696 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 697 698 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__, 699 camera_handle,ch_id,s_id,parm_type); 700 701 if(my_obj) { 702 pthread_mutex_lock(&my_obj->cam_lock); 703 pthread_mutex_unlock(&g_intf_lock); 704 rc = mm_camera_set_stream_parm(my_obj,ch_id,s_id, 705 parm_type, 706 p_value); 707 }else{ 708 pthread_mutex_unlock(&g_intf_lock); 709 } 710 CDBG("%s :X rc = %d",__func__,rc); 711 return rc; 712 } 713 714 static int32_t mm_camera_intf_get_stream_parm( 715 uint32_t camera_handle, 716 uint32_t ch_id, 717 uint32_t s_id, 718 mm_camera_stream_parm_t parm_type, 719 void* p_value) 720 { 721 int32_t rc = -1; 722 mm_camera_obj_t * my_obj = NULL; 723 724 pthread_mutex_lock(&g_intf_lock); 725 my_obj = mm_camera_util_get_camera_by_handler(camera_handle); 726 727 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__, 728 camera_handle,ch_id,s_id,parm_type); 729 730 if(my_obj) { 731 pthread_mutex_lock(&my_obj->cam_lock); 732 pthread_mutex_unlock(&g_intf_lock); 733 rc = mm_camera_get_stream_parm(my_obj,ch_id,s_id, 734 parm_type, 735 p_value); 736 }else{ 737 pthread_mutex_unlock(&g_intf_lock); 738 } 739 740 CDBG("%s :X rc = %d",__func__,rc); 741 return rc; 742 } 743 mm_camera_info_t * camera_query(uint8_t *num_cameras) 744 { 745 int i = 0, rc = 0; 746 int dev_fd = 0; 747 struct media_device_info mdev_info; 748 int num_media_devices = 0; 749 if (!num_cameras) { 750 CDBG_ERROR("%s: num_cameras is NULL\n", __func__); 751 return NULL; 752 } 753 754 CDBG("%s : E",__func__); 755 /* lock the mutex */ 756 pthread_mutex_lock(&g_intf_lock); 757 *num_cameras = 0; 758 while (1) { 759 char dev_name[32]; 760 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 761 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 762 if (dev_fd < 0) { 763 CDBG("Done discovering media devices\n"); 764 break; 765 } 766 num_media_devices++; 767 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 768 if (rc < 0) { 769 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 770 close(dev_fd); 771 break; 772 } 773 774 if(strncmp(mdev_info.model, QCAMERA_NAME, sizeof(mdev_info.model) != 0)) { 775 close(dev_fd); 776 continue; 777 } 778 779 char * mdev_cfg; 780 int cam_type = 0, mount_angle = 0, info_index = 0; 781 mdev_cfg = strtok(mdev_info.serial, "-"); 782 while(mdev_cfg != NULL) { 783 if(info_index == 0) { 784 if(strcmp(mdev_cfg, QCAMERA_NAME)) 785 break; 786 } else if(info_index == 1) { 787 mount_angle = atoi(mdev_cfg); 788 } else if(info_index == 2) { 789 cam_type = atoi(mdev_cfg); 790 } 791 mdev_cfg = strtok(NULL, "-"); 792 info_index++; 793 } 794 795 if(info_index == 0) { 796 close(dev_fd); 797 continue; 798 } 799 800 int num_entities = 1; 801 while (1) { 802 struct media_entity_desc entity; 803 memset(&entity, 0, sizeof(entity)); 804 entity.id = num_entities++; 805 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 806 if (rc < 0) { 807 CDBG("Done enumerating media entities\n"); 808 rc = 0; 809 break; 810 } 811 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) { 812 strncpy(g_cam_ctrl.video_dev_name[*num_cameras], 813 entity.name, sizeof(entity.name)); 814 g_cam_ctrl.camera[*num_cameras].video_dev_name = 815 &g_cam_ctrl.video_dev_name[*num_cameras][0]; 816 break; 817 } 818 } 819 820 //g_cam_ctrl.camera[*num_cameras].camera_info.camera_id = *num_cameras; 821 g_cam_ctrl.camera[*num_cameras].camera_id = *num_cameras; 822 823 g_cam_ctrl.camera[*num_cameras]. 824 camera_info.modes_supported = CAMERA_MODE_2D; 825 826 if(cam_type > 1) { 827 g_cam_ctrl.camera[*num_cameras]. 828 camera_info.modes_supported |= CAMERA_MODE_3D; 829 } 830 831 g_cam_ctrl.camera[*num_cameras].camera_info.position = 832 (cam_type == 1) ? FRONT_CAMERA : BACK_CAMERA; 833 834 g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle = 835 mount_angle; 836 837 g_cam_ctrl.camera[*num_cameras].main_sensor_type = 0; 838 839 CDBG("%s: dev_info[id=%d,name='%s',pos=%d,modes=0x%x,sensor=%d mount_angle = %d]\n", 840 __func__, *num_cameras, 841 g_cam_ctrl.camera[*num_cameras].video_dev_name, 842 g_cam_ctrl.camera[*num_cameras].camera_info.position, 843 g_cam_ctrl.camera[*num_cameras].camera_info.modes_supported, 844 g_cam_ctrl.camera[*num_cameras].main_sensor_type, 845 g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle); 846 847 *num_cameras += 1; 848 if (dev_fd > 0) { 849 close(dev_fd); 850 } 851 } 852 *num_cameras = *num_cameras; 853 g_cam_ctrl.num_cam = *num_cameras; 854 855 /* unlock the mutex */ 856 pthread_mutex_unlock(&g_intf_lock); 857 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam); 858 if(rc == 0) 859 return &g_cam_ctrl.camera[0]; 860 else 861 return NULL; 862 } 863 864 /* camera ops v-table */ 865 static mm_camera_ops_t mm_camera_ops = { 866 .sync = mm_camera_intf_sync, 867 .is_event_supported = mm_camera_intf_is_event_supported, 868 .register_event_notify = mm_camera_intf_register_event_notify, 869 .qbuf = mm_camera_intf_qbuf, 870 .camera_close = mm_camera_intf_close, 871 .query_2nd_sensor_info = mm_camera_intf_query_2nd_sensor_info, 872 .is_parm_supported = mm_camera_intf_is_parm_supported, 873 .set_parm = mm_camera_intf_set_parm, 874 .get_parm = mm_camera_intf_get_parm, 875 .ch_acquire = mm_camera_intf_add_channel, 876 .ch_release = mm_camera_intf_del_channel, 877 .add_stream = mm_camera_intf_add_stream, 878 .del_stream = mm_camera_intf_del_stream, 879 .config_stream = mm_camera_intf_config_stream, 880 .init_stream_bundle = mm_camera_intf_bundle_streams, 881 .destroy_stream_bundle = mm_camera_intf_destroy_bundle, 882 .start_streams = mm_camera_intf_start_streams, 883 .stop_streams = mm_camera_intf_stop_streams, 884 .async_teardown_streams = mm_camera_intf_async_teardown_streams, 885 .request_super_buf = mm_camera_intf_request_super_buf, 886 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request, 887 .start_focus = mm_camera_intf_start_focus, 888 .abort_focus = mm_camera_intf_abort_focus, 889 .prepare_snapshot = mm_camera_intf_prepare_snapshot, 890 .set_stream_parm = mm_camera_intf_set_stream_parm, 891 .get_stream_parm = mm_camera_intf_get_stream_parm 892 }; 893 894 /* open camera. */ 895 mm_camera_vtbl_t * camera_open(uint8_t camera_idx, 896 mm_camear_mem_vtbl_t *mem_vtbl) 897 { 898 int32_t rc = 0; 899 mm_camera_obj_t* cam_obj = NULL; 900 901 CDBG("%s: E camera_idx = %d\n", __func__,camera_idx); 902 if (MSM_MAX_CAMERA_SENSORS <= camera_idx) { 903 CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx); 904 return NULL; 905 } 906 907 pthread_mutex_lock(&g_intf_lock); 908 /* opened already */ 909 if(NULL != g_cam_ctrl.cam_obj[camera_idx]) { 910 /* Add reference */ 911 g_cam_ctrl.cam_obj[camera_idx]->ref_count++; 912 pthread_mutex_unlock(&g_intf_lock); 913 CDBG("%s: opened alreadyn", __func__); 914 return &cam_obj->vtbl; 915 } 916 917 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t)); 918 if(NULL == cam_obj) { 919 pthread_mutex_unlock(&g_intf_lock); 920 CDBG("%s: no mem", __func__); 921 return NULL; 922 } 923 924 /* initialize camera obj */ 925 memset(cam_obj, 0, sizeof(mm_camera_obj_t)); 926 cam_obj->ctrl_fd = -1; 927 cam_obj->ds_fd = -1; 928 cam_obj->ref_count++; 929 cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx); 930 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */ 931 cam_obj->vtbl.camera_info = &g_cam_ctrl.camera[camera_idx]; 932 cam_obj->vtbl.ops = &mm_camera_ops; 933 cam_obj->mem_vtbl = mem_vtbl; /* save mem_vtbl */ 934 pthread_mutex_init(&cam_obj->cam_lock, NULL); 935 936 rc = mm_camera_open(cam_obj); 937 if(rc != 0) { 938 CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc); 939 pthread_mutex_destroy(&cam_obj->cam_lock); 940 g_cam_ctrl.cam_obj[camera_idx] = NULL; 941 free(cam_obj); 942 cam_obj = NULL; 943 pthread_mutex_unlock(&g_intf_lock); 944 return NULL; 945 }else{ 946 CDBG("%s: Open succeded\n", __func__); 947 g_cam_ctrl.cam_obj[camera_idx] = cam_obj; 948 pthread_mutex_unlock(&g_intf_lock); 949 return &cam_obj->vtbl; 950 } 951 } 952