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 "mm_camera_dbg.h" 32 #include <errno.h> 33 #include <sys/ioctl.h> 34 #include <sys/types.h> 35 #include <sys/stat.h> 36 #include <fcntl.h> 37 #include <stddef.h> 38 #include <poll.h> 39 #include <linux/media.h> 40 41 #include "mm_camera_interface2.h" 42 #include "mm_camera.h" 43 44 #define SET_PARM_BIT32(parm, parm_arr) \ 45 (parm_arr[parm/32] |= (1<<(parm%32))) 46 47 #define GET_PARM_BIT32(parm, parm_arr) \ 48 ((parm_arr[parm/32]>>(parm%32))& 0x1) 49 50 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER; 51 52 static mm_camera_ctrl_t g_cam_ctrl; 53 54 static int mm_camera_util_opcode_2_ch_type(mm_camera_obj_t *my_obj, 55 mm_camera_ops_type_t opcode) 56 { 57 switch(opcode) { 58 case MM_CAMERA_OPS_PREVIEW: 59 return MM_CAMERA_CH_PREVIEW; 60 case MM_CAMERA_OPS_ZSL: 61 case MM_CAMERA_OPS_SNAPSHOT: 62 return MM_CAMERA_CH_SNAPSHOT; 63 case MM_CAMERA_OPS_PREPARE_SNAPSHOT: 64 return MM_CAMERA_CH_SNAPSHOT; 65 case MM_CAMERA_OPS_RAW: 66 return MM_CAMERA_CH_RAW; 67 default: 68 break; 69 } 70 return -1; 71 } 72 73 const char *mm_camera_util_get_dev_name(mm_camera_obj_t * my_obj) 74 { 75 CDBG("%s: Returning %s at index :%d\n", 76 __func__,g_cam_ctrl.camera[my_obj->my_id].video_dev_name,my_obj->my_id); 77 return g_cam_ctrl.camera[my_obj->my_id].video_dev_name; 78 } 79 80 /* used for querying the camera_info of the given camera_id */ 81 static const qcamera_info_t * mm_camera_cfg_query_camera_info (int8_t camera_id) 82 { 83 if(camera_id >= MSM_MAX_CAMERA_SENSORS) 84 return NULL; 85 return &g_cam_ctrl.camera[camera_id].camera_info; 86 } 87 /* check if the parm is supported */ 88 static uint8_t mm_camera_cfg_is_parm_supported (mm_camera_t * camera, 89 mm_camera_parm_type_t parm_type) 90 { 91 int is_parm_supported = 0; 92 mm_camera_obj_t * my_obj = NULL; 93 94 pthread_mutex_lock(&g_mutex); 95 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 96 pthread_mutex_unlock(&g_mutex); 97 if(my_obj) { 98 pthread_mutex_lock(&my_obj->mutex); 99 is_parm_supported = GET_PARM_BIT32(parm_type, 100 my_obj->properties.parm); 101 pthread_mutex_unlock(&my_obj->mutex); 102 } 103 104 return is_parm_supported; 105 } 106 107 /* check if the channel is supported */ 108 static uint8_t mm_camera_cfg_is_ch_supported (mm_camera_t * camera, 109 mm_camera_channel_type_t ch_type) 110 { 111 switch(ch_type) { 112 case MM_CAMERA_CH_PREVIEW: 113 case MM_CAMERA_CH_VIDEO: 114 case MM_CAMERA_CH_SNAPSHOT: 115 case MM_CAMERA_CH_RAW: 116 return TRUE; 117 case MM_CAMERA_CH_MAX: 118 default: 119 return FALSE; 120 } 121 return FALSE; 122 } 123 124 /* set a parms current value */ 125 static int32_t mm_camera_cfg_set_parm (mm_camera_t * camera, 126 mm_camera_parm_type_t parm_type, 127 void *p_value) 128 { 129 int32_t rc = -MM_CAMERA_E_GENERAL; 130 uint32_t tmp; 131 mm_camera_obj_t * my_obj = NULL; 132 mm_camera_parm_t parm = {.parm_type = parm_type, .p_value = p_value}; 133 134 pthread_mutex_lock(&g_mutex); 135 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 136 pthread_mutex_unlock(&g_mutex); 137 if(my_obj) { 138 pthread_mutex_lock(&my_obj->mutex); 139 rc = mm_camera_set_parm(my_obj, &parm); 140 pthread_mutex_unlock(&my_obj->mutex); 141 } 142 return rc; 143 } 144 145 /* get a parms current value */ 146 static int32_t mm_camera_cfg_get_parm (mm_camera_t * camera, 147 mm_camera_parm_type_t parm_type, 148 void* p_value) 149 { 150 int32_t rc = -MM_CAMERA_E_GENERAL; 151 uint32_t tmp; 152 mm_camera_obj_t * my_obj = NULL; 153 mm_camera_parm_t parm = {.parm_type = parm_type, .p_value = p_value}; 154 155 pthread_mutex_lock(&g_mutex); 156 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 157 pthread_mutex_unlock(&g_mutex); 158 if(my_obj) { 159 pthread_mutex_lock(&my_obj->mutex); 160 rc = mm_camera_get_parm(my_obj, &parm); 161 pthread_mutex_unlock(&my_obj->mutex); 162 } 163 return rc; 164 } 165 166 static int32_t mm_camera_cfg_request_buf(mm_camera_t * camera, 167 mm_camera_reg_buf_t *buf) 168 { 169 int32_t rc = -MM_CAMERA_E_GENERAL; 170 uint32_t tmp; 171 mm_camera_obj_t * my_obj = NULL; 172 173 pthread_mutex_lock(&g_mutex); 174 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 175 pthread_mutex_unlock(&g_mutex); 176 if(my_obj) { 177 pthread_mutex_lock(&my_obj->mutex); 178 rc = mm_camera_request_buf(my_obj, buf); 179 pthread_mutex_unlock(&my_obj->mutex); 180 } 181 return rc; 182 } 183 184 static int32_t mm_camera_cfg_enqueue_buf(mm_camera_t * camera, 185 mm_camera_reg_buf_t *buf) 186 { 187 int32_t rc = -MM_CAMERA_E_GENERAL; 188 uint32_t tmp; 189 mm_camera_obj_t * my_obj = NULL; 190 191 pthread_mutex_lock(&g_mutex); 192 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 193 pthread_mutex_unlock(&g_mutex); 194 if(my_obj) { 195 pthread_mutex_lock(&my_obj->mutex); 196 rc = mm_camera_enqueue_buf(my_obj, buf); 197 pthread_mutex_unlock(&my_obj->mutex); 198 } 199 return rc; 200 } 201 202 static int32_t mm_camera_cfg_prepare_buf(mm_camera_t * camera, 203 mm_camera_reg_buf_t *buf) 204 { 205 int32_t rc = -MM_CAMERA_E_GENERAL; 206 uint32_t tmp; 207 mm_camera_obj_t * my_obj = NULL; 208 209 pthread_mutex_lock(&g_mutex); 210 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 211 pthread_mutex_unlock(&g_mutex); 212 if(my_obj) { 213 pthread_mutex_lock(&my_obj->mutex); 214 rc = mm_camera_prepare_buf(my_obj, buf); 215 pthread_mutex_unlock(&my_obj->mutex); 216 } 217 return rc; 218 } 219 static int32_t mm_camera_cfg_unprepare_buf(mm_camera_t * camera, 220 mm_camera_channel_type_t ch_type) 221 { 222 int32_t rc = -MM_CAMERA_E_GENERAL; 223 uint32_t tmp; 224 mm_camera_obj_t * my_obj = NULL; 225 226 pthread_mutex_lock(&g_mutex); 227 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 228 pthread_mutex_unlock(&g_mutex); 229 if(my_obj) { 230 pthread_mutex_lock(&my_obj->mutex); 231 rc = mm_camera_unprepare_buf(my_obj,ch_type); 232 pthread_mutex_unlock(&my_obj->mutex); 233 } 234 return rc; 235 } 236 237 static mm_camera_config_t mm_camera_cfg = { 238 .is_parm_supported = mm_camera_cfg_is_parm_supported, 239 .is_ch_supported = mm_camera_cfg_is_ch_supported, 240 .set_parm = mm_camera_cfg_set_parm, 241 .get_parm = mm_camera_cfg_get_parm, 242 .request_buf = mm_camera_cfg_request_buf, 243 .enqueue_buf = mm_camera_cfg_enqueue_buf, 244 .prepare_buf = mm_camera_cfg_prepare_buf, 245 .unprepare_buf = mm_camera_cfg_unprepare_buf 246 }; 247 248 static uint8_t mm_camera_ops_is_op_supported (mm_camera_t * camera, 249 mm_camera_ops_type_t opcode) 250 { 251 uint8_t is_ops_supported; 252 mm_camera_obj_t * my_obj = NULL; 253 int index = 0; 254 mm_camera_legacy_ops_type_t legacy_opcode = CAMERA_OPS_MAX; 255 256 /* Temp: We will be translating our new opcode 257 to legacy ops type. This is just a hack to 258 temporarily unblock APT team. New design is 259 under discussion */ 260 switch (opcode) { 261 case MM_CAMERA_OPS_PREVIEW: 262 legacy_opcode = CAMERA_OPS_STREAMING_PREVIEW; 263 break; 264 case MM_CAMERA_OPS_VIDEO: 265 legacy_opcode = CAMERA_OPS_STREAMING_VIDEO; 266 break; 267 case MM_CAMERA_OPS_PREPARE_SNAPSHOT: 268 legacy_opcode = CAMERA_OPS_PREPARE_SNAPSHOT; 269 break; 270 case MM_CAMERA_OPS_SNAPSHOT: 271 legacy_opcode = CAMERA_OPS_SNAPSHOT; 272 break; 273 case MM_CAMERA_OPS_RAW: 274 legacy_opcode = CAMERA_OPS_RAW_CAPTURE; 275 break; 276 case MM_CAMERA_OPS_ZSL: 277 legacy_opcode = CAMERA_OPS_STREAMING_ZSL; 278 break; 279 case MM_CAMERA_OPS_FOCUS: 280 legacy_opcode = CAMERA_OPS_FOCUS; 281 break; 282 case MM_CAMERA_OPS_GET_BUFFERED_FRAME: 283 legacy_opcode = CAMERA_OPS_LOCAL; 284 is_ops_supported = TRUE; 285 CDBG("MM_CAMERA_OPS_GET_BUFFERED_FRAME not handled"); 286 break; 287 default: 288 CDBG_ERROR("%s: case %d not handled", __func__, opcode); 289 legacy_opcode = CAMERA_OPS_LOCAL; 290 is_ops_supported = FALSE; 291 break; 292 } 293 if (legacy_opcode != CAMERA_OPS_LOCAL) { 294 pthread_mutex_lock(&g_mutex); 295 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 296 pthread_mutex_unlock(&g_mutex); 297 if(my_obj) { 298 pthread_mutex_lock(&my_obj->mutex); 299 index = legacy_opcode/32; /* 32 bits */ 300 is_ops_supported = ((my_obj->properties.ops[index] & 301 (1<<legacy_opcode)) != 0); 302 pthread_mutex_unlock(&my_obj->mutex); 303 } else { 304 is_ops_supported = FALSE; 305 } 306 } 307 308 return is_ops_supported; 309 } 310 311 static int32_t mm_camera_ops_action (mm_camera_t * camera, uint8_t start, 312 mm_camera_ops_type_t opcode, void *val) 313 { 314 int32_t rc = -MM_CAMERA_E_GENERAL; 315 mm_camera_obj_t * my_obj = NULL; 316 pthread_mutex_lock(&g_mutex); 317 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 318 pthread_mutex_unlock(&g_mutex); 319 if(my_obj) { 320 pthread_mutex_lock(&my_obj->mutex); 321 rc = mm_camera_action(my_obj, start, opcode, val); 322 pthread_mutex_unlock(&my_obj->mutex); 323 } 324 return rc; 325 } 326 327 /* open uses flags to optionally disable jpeg/vpe interface. */ 328 static int32_t mm_camera_ops_open (mm_camera_t * camera, 329 mm_camera_op_mode_type_t op_mode) 330 { 331 int8_t camera_id = camera->camera_info.camera_id; 332 int32_t rc = MM_CAMERA_OK; 333 334 CDBG("%s: BEGIN\n", __func__); 335 pthread_mutex_lock(&g_mutex); 336 /* not first open */ 337 if(g_cam_ctrl.cam_obj[camera_id]) { 338 g_cam_ctrl.cam_obj[camera_id]->ref_count++; 339 CDBG("%s: opened alreadyn", __func__); 340 goto end; 341 } 342 g_cam_ctrl.cam_obj[camera_id] = 343 (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t)); 344 if(!g_cam_ctrl.cam_obj[camera_id]) { 345 rc = -MM_CAMERA_E_NO_MEMORY; 346 CDBG("%s: no mem", __func__); 347 goto end; 348 } 349 memset(g_cam_ctrl.cam_obj[camera_id], 0, 350 sizeof(mm_camera_obj_t)); 351 //g_cam_ctrl.cam_obj[camera_id]->ctrl_fd = -1; 352 g_cam_ctrl.cam_obj[camera_id]->ref_count++; 353 g_cam_ctrl.cam_obj[camera_id]->my_id=camera_id; 354 355 pthread_mutex_init(&g_cam_ctrl.cam_obj[camera_id]->mutex, NULL); 356 rc = mm_camera_open(g_cam_ctrl.cam_obj[camera_id], op_mode); 357 if(rc < 0) { 358 CDBG("%s: open failed, rc = %d\n", __func__, rc); 359 pthread_mutex_destroy(&g_cam_ctrl.cam_obj[camera_id]->mutex); 360 g_cam_ctrl.cam_obj[camera_id]->ref_count--; 361 free(g_cam_ctrl.cam_obj[camera_id]); 362 g_cam_ctrl.cam_obj[camera_id]=NULL; 363 CDBG("%s: mm_camera_open err = %d", __func__, rc); 364 goto end; 365 }else{ 366 CDBG("%s: open succeded\n", __func__); 367 } 368 end: 369 pthread_mutex_unlock(&g_mutex); 370 CDBG("%s: END, rc=%d\n", __func__, rc); 371 return rc; 372 } 373 374 static void mm_camera_ops_close (mm_camera_t * camera) 375 { 376 mm_camera_obj_t * my_obj; 377 int i; 378 int8_t camera_id = camera->camera_info.camera_id; 379 380 pthread_mutex_lock(&g_mutex); 381 my_obj = g_cam_ctrl.cam_obj[camera_id]; 382 if(my_obj) { 383 my_obj->ref_count--; 384 if(my_obj->ref_count > 0) { 385 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count); 386 } else { 387 // mm_camera_poll_thread_release(my_obj, MM_CAMERA_CH_MAX); 388 (void)mm_camera_close(g_cam_ctrl.cam_obj[camera_id]); 389 pthread_mutex_destroy(&my_obj->mutex); 390 free(my_obj); 391 g_cam_ctrl.cam_obj[camera_id] = NULL; 392 } 393 } 394 pthread_mutex_unlock(&g_mutex); 395 } 396 397 static void mm_camera_ops_stop (mm_camera_t * camera) 398 { 399 mm_camera_obj_t * my_obj; 400 int i; 401 int8_t camera_id = camera->camera_info.camera_id; 402 403 pthread_mutex_lock(&g_mutex); 404 my_obj = g_cam_ctrl.cam_obj[camera_id]; 405 if(my_obj) { 406 CDBG("%s : Close Threads in mm_camera_ops_stop",__func__); 407 for(i = 0; i <= MM_CAMERA_CH_MAX; i++) { 408 mm_camera_poll_thread_release(my_obj,(mm_camera_channel_type_t)i); 409 } 410 mm_camera_poll_threads_deinit(my_obj); 411 } 412 pthread_mutex_unlock(&g_mutex); 413 } 414 415 416 static int32_t mm_camera_ops_ch_acquire(mm_camera_t * camera, 417 mm_camera_channel_type_t ch_type) 418 { 419 int32_t rc = -MM_CAMERA_E_GENERAL; 420 mm_camera_obj_t * my_obj = NULL; 421 pthread_mutex_lock(&g_mutex); 422 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 423 pthread_mutex_unlock(&g_mutex); 424 if(my_obj) { 425 pthread_mutex_lock(&my_obj->mutex); 426 rc = mm_camera_ch_acquire(my_obj, ch_type); 427 pthread_mutex_unlock(&my_obj->mutex); 428 } 429 return rc; 430 431 } 432 static void mm_camera_ops_ch_release(mm_camera_t * camera, mm_camera_channel_type_t ch_type) 433 { 434 mm_camera_obj_t * my_obj = NULL; 435 pthread_mutex_lock(&g_mutex); 436 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 437 pthread_mutex_unlock(&g_mutex); 438 if(my_obj) { 439 pthread_mutex_lock(&my_obj->mutex); 440 mm_camera_ch_release(my_obj, ch_type); 441 pthread_mutex_unlock(&my_obj->mutex); 442 } 443 } 444 445 static int32_t mm_camera_ops_ch_attr(mm_camera_t * camera, 446 mm_camera_channel_type_t ch_type, 447 mm_camera_channel_attr_t *attr) 448 { 449 mm_camera_obj_t * my_obj = NULL; 450 int32_t rc = -MM_CAMERA_E_GENERAL; 451 pthread_mutex_lock(&g_mutex); 452 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 453 pthread_mutex_unlock(&g_mutex); 454 if(my_obj) { 455 pthread_mutex_lock(&my_obj->mutex); 456 rc = mm_camera_ch_fn(my_obj, ch_type, MM_CAMERA_STATE_EVT_ATTR, 457 (void *)attr); 458 pthread_mutex_unlock(&my_obj->mutex); 459 } 460 return rc; 461 } 462 463 static int32_t mm_camera_ops_sendmsg(mm_camera_t * camera, 464 void *msg, 465 uint32_t buf_size, 466 int sendfd) 467 { 468 int32_t rc = -MM_CAMERA_E_GENERAL; 469 mm_camera_obj_t * my_obj = NULL; 470 pthread_mutex_lock(&g_mutex); 471 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 472 pthread_mutex_unlock(&g_mutex); 473 if(my_obj) { 474 pthread_mutex_lock(&my_obj->mutex); 475 rc = mm_camera_sendmsg(my_obj, msg, buf_size, sendfd); 476 pthread_mutex_unlock(&my_obj->mutex); 477 } 478 return rc; 479 } 480 481 static mm_camera_ops_t mm_camera_ops = { 482 .is_op_supported = mm_camera_ops_is_op_supported, 483 .action = mm_camera_ops_action, 484 .open = mm_camera_ops_open, 485 .close = mm_camera_ops_close, 486 .stop = mm_camera_ops_stop, 487 .ch_acquire = mm_camera_ops_ch_acquire, 488 .ch_release = mm_camera_ops_ch_release, 489 .ch_set_attr = mm_camera_ops_ch_attr, 490 .sendmsg = mm_camera_ops_sendmsg 491 }; 492 493 static uint8_t mm_camera_notify_is_event_supported(mm_camera_t * camera, 494 mm_camera_event_type_t evt_type) 495 { 496 switch(evt_type) { 497 case MM_CAMERA_EVT_TYPE_CH: 498 case MM_CAMERA_EVT_TYPE_CTRL: 499 case MM_CAMERA_EVT_TYPE_STATS: 500 case MM_CAMERA_EVT_TYPE_INFO: 501 return 1; 502 default: 503 return 0; 504 } 505 return 0; 506 } 507 508 static int32_t mm_camera_notify_register_event_cb(mm_camera_t * camera, 509 mm_camera_event_notify_t evt_cb, 510 void * user_data, 511 mm_camera_event_type_t evt_type) 512 { 513 mm_camera_obj_t * my_obj = NULL; 514 mm_camera_buf_cb_t reg ; 515 int rc = -1; 516 517 pthread_mutex_lock(&g_mutex); 518 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 519 pthread_mutex_unlock(&g_mutex); 520 if(my_obj) { 521 pthread_mutex_lock(&my_obj->mutex); 522 rc = mm_camera_reg_event(my_obj, evt_cb, user_data, evt_type); 523 pthread_mutex_unlock(&my_obj->mutex); 524 } 525 return rc; 526 } 527 528 static int32_t mm_camera_register_buf_notify ( 529 mm_camera_t * camera, 530 mm_camera_channel_type_t ch_type, 531 mm_camera_buf_notify_t buf_cb, 532 mm_camera_register_buf_cb_type_t cb_type, 533 uint32_t cb_count, 534 void * user_data) 535 { 536 mm_camera_obj_t * my_obj = NULL; 537 mm_camera_buf_cb_t reg ; 538 int rc = -1; 539 540 reg.cb = buf_cb; 541 reg.user_data = user_data; 542 reg.cb_type=cb_type; 543 reg.cb_count=cb_count; 544 pthread_mutex_lock(&g_mutex); 545 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 546 pthread_mutex_unlock(&g_mutex); 547 if(my_obj) { 548 pthread_mutex_lock(&my_obj->mutex); 549 rc = mm_camera_ch_fn(my_obj,ch_type, 550 MM_CAMERA_STATE_EVT_REG_BUF_CB, (void *)®); 551 pthread_mutex_unlock(&my_obj->mutex); 552 } 553 return rc; 554 } 555 static int32_t mm_camera_buf_done(mm_camera_t * camera, mm_camera_ch_data_buf_t * bufs) 556 { 557 mm_camera_obj_t * my_obj = NULL; 558 int rc = -1; 559 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 560 if(my_obj) { 561 /*pthread_mutex_lock(&my_obj->mutex);*/ 562 rc = mm_camera_ch_fn(my_obj, bufs->type, 563 MM_CAMERA_STATE_EVT_QBUF, (void *)bufs); 564 /*pthread_mutex_unlock(&my_obj->mutex);*/ 565 } 566 return rc; 567 } 568 569 static mm_camera_notify_t mm_camera_notify = { 570 .is_event_supported = mm_camera_notify_is_event_supported, 571 .register_event_notify = mm_camera_notify_register_event_cb, 572 .register_buf_notify = mm_camera_register_buf_notify, 573 .buf_done = mm_camera_buf_done 574 }; 575 576 static uint8_t mm_camera_jpeg_is_jpeg_supported (mm_camera_t * camera) 577 { 578 return FALSE; 579 } 580 static int32_t mm_camera_jpeg_set_parm (mm_camera_t * camera, 581 mm_camera_jpeg_parm_type_t parm_type, 582 void* p_value) 583 { 584 return -1; 585 } 586 static int32_t mm_camera_jpeg_get_parm (mm_camera_t * camera, 587 mm_camera_jpeg_parm_type_t parm_type, 588 void* p_value) 589 { 590 return -1; 591 } 592 static int32_t mm_camera_jpeg_register_event_cb(mm_camera_t * camera, 593 mm_camera_jpeg_cb_t * evt_cb, 594 void * user_data) 595 { 596 return -1; 597 } 598 static int32_t mm_camera_jpeg_encode (mm_camera_t * camera, uint8_t start, 599 mm_camera_jpeg_encode_t *data) 600 { 601 return -1; 602 } 603 604 static mm_camera_jpeg_t mm_camera_jpeg = { 605 .is_jpeg_supported = mm_camera_jpeg_is_jpeg_supported, 606 .set_parm = mm_camera_jpeg_set_parm, 607 .get_parm = mm_camera_jpeg_get_parm, 608 .register_event_cb = mm_camera_jpeg_register_event_cb, 609 .encode = mm_camera_jpeg_encode, 610 }; 611 612 extern mm_camera_t * mm_camera_query (uint8_t *num_cameras) 613 { 614 int i = 0, rc = MM_CAMERA_OK; 615 int dev_fd = 0; 616 struct media_device_info mdev_info; 617 int num_media_devices = 0; 618 if (!num_cameras) 619 return NULL; 620 /* lock the mutex */ 621 pthread_mutex_lock(&g_mutex); 622 *num_cameras = 0; 623 while (1) { 624 char dev_name[32]; 625 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 626 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 627 if (dev_fd < 0) { 628 CDBG("Done discovering media devices\n"); 629 break; 630 } 631 num_media_devices++; 632 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 633 if (rc < 0) { 634 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 635 close(dev_fd); 636 break; 637 } 638 639 if(strncmp(mdev_info.model, QCAMERA_NAME, sizeof(mdev_info.model) != 0)) { 640 close(dev_fd); 641 continue; 642 } 643 644 char * mdev_cfg; 645 int cam_type = 0, mount_angle = 0, info_index = 0; 646 mdev_cfg = strtok(mdev_info.serial, "-"); 647 while(mdev_cfg != NULL) { 648 if(info_index == 0) { 649 if(strcmp(mdev_cfg, QCAMERA_NAME)) 650 break; 651 } else if(info_index == 1) { 652 mount_angle = atoi(mdev_cfg); 653 } else if(info_index == 2) { 654 cam_type = atoi(mdev_cfg); 655 } 656 mdev_cfg = strtok(NULL, "-"); 657 info_index++; 658 } 659 660 if(info_index == 0) { 661 close(dev_fd); 662 continue; 663 } 664 665 int num_entities = 1; 666 while (1) { 667 struct media_entity_desc entity; 668 memset(&entity, 0, sizeof(entity)); 669 entity.id = num_entities++; 670 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 671 if (rc < 0) { 672 CDBG("Done enumerating media entities\n"); 673 rc = 0; 674 break; 675 } 676 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) { 677 strncpy(g_cam_ctrl.camera[*num_cameras].video_dev_name, 678 entity.name, sizeof(entity.name)); 679 break; 680 } 681 } 682 683 g_cam_ctrl.camera[*num_cameras].camera_info.camera_id = *num_cameras; 684 685 g_cam_ctrl.camera[*num_cameras]. 686 camera_info.modes_supported = CAMERA_MODE_2D; 687 if(cam_type > 1) 688 g_cam_ctrl.camera[*num_cameras]. 689 camera_info.modes_supported |= CAMERA_MODE_3D; 690 691 g_cam_ctrl.camera[*num_cameras].camera_info.position = 692 (cam_type == 1) ? FRONT_CAMERA : BACK_CAMERA; 693 g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle = 694 mount_angle; 695 g_cam_ctrl.camera[*num_cameras].sensor_type = 0; 696 g_cam_ctrl.camera[*num_cameras].cfg = &mm_camera_cfg; 697 g_cam_ctrl.camera[*num_cameras].ops = &mm_camera_ops; 698 g_cam_ctrl.camera[*num_cameras].evt = &mm_camera_notify; 699 g_cam_ctrl.camera[*num_cameras].jpeg_ops = NULL; 700 701 CDBG("%s: dev_info[id=%d,name='%s',pos=%d,modes=0x%x,sensor=%d]\n", 702 __func__, *num_cameras, 703 g_cam_ctrl.camera[*num_cameras].video_dev_name, 704 g_cam_ctrl.camera[*num_cameras].camera_info.position, 705 g_cam_ctrl.camera[*num_cameras].camera_info.modes_supported, 706 g_cam_ctrl.camera[*num_cameras].sensor_type); 707 708 *num_cameras+=1; 709 if (dev_fd > 0) { 710 close(dev_fd); 711 } 712 } 713 *num_cameras = *num_cameras; 714 g_cam_ctrl.num_cam = *num_cameras; 715 end: 716 /* unlock the mutex */ 717 pthread_mutex_unlock(&g_mutex); 718 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam); 719 if(rc == 0) 720 return &g_cam_ctrl.camera[0]; 721 else 722 return NULL; 723 } 724 725 726 static mm_camera_t * get_camera_by_id( int cam_id) 727 { 728 mm_camera_t * mm_cam; 729 if( cam_id < 0 || cam_id >= g_cam_ctrl.num_cam) { 730 mm_cam = NULL; 731 } else { 732 mm_cam = & g_cam_ctrl.camera[cam_id]; 733 } 734 return mm_cam; 735 } 736 737 /*configure methods*/ 738 uint8_t cam_config_is_parm_supported( 739 int cam_id, 740 mm_camera_parm_type_t parm_type) 741 { 742 uint8_t rc = 0; 743 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 744 if (mm_cam && mm_cam->cfg) { 745 rc = mm_cam->cfg->is_parm_supported(mm_cam, parm_type); 746 } 747 return rc; 748 } 749 750 uint8_t cam_config_is_ch_supported( 751 int cam_id, 752 mm_camera_channel_type_t ch_type) 753 { 754 uint8_t rc = 0; 755 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 756 if (mm_cam) { 757 rc = mm_cam->cfg->is_ch_supported(mm_cam, ch_type); 758 } 759 return rc; 760 761 } 762 763 /* set a parms current value */ 764 int32_t cam_config_set_parm( 765 int cam_id, 766 mm_camera_parm_type_t parm_type, 767 void* p_value) 768 { 769 int32_t rc = -1; 770 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 771 if (mm_cam) { 772 rc = mm_cam->cfg->set_parm(mm_cam, parm_type, p_value); 773 } 774 return rc; 775 } 776 777 /* get a parms current value */ 778 int32_t cam_config_get_parm( 779 int cam_id, 780 mm_camera_parm_type_t parm_type, 781 void* p_value) 782 { 783 int32_t rc = -1; 784 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 785 if (mm_cam) { 786 rc = mm_cam->cfg->get_parm(mm_cam, parm_type, p_value); 787 } 788 return rc; 789 } 790 791 int32_t cam_config_request_buf(int cam_id, mm_camera_reg_buf_t *buf) 792 { 793 794 int32_t rc = -1; 795 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 796 if (mm_cam) { 797 rc = mm_cam->cfg->request_buf(mm_cam, buf); 798 } 799 return rc; 800 } 801 802 int32_t cam_config_enqueue_buf(int cam_id, mm_camera_reg_buf_t *buf) 803 { 804 805 int32_t rc = -1; 806 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 807 if (mm_cam) { 808 rc = mm_cam->cfg->enqueue_buf(mm_cam, buf); 809 } 810 return rc; 811 } 812 813 int32_t cam_config_prepare_buf(int cam_id, mm_camera_reg_buf_t *buf) 814 { 815 816 int32_t rc = -1; 817 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 818 if (mm_cam) { 819 rc = mm_cam->cfg->prepare_buf(mm_cam, buf); 820 } 821 return rc; 822 } 823 int32_t cam_config_unprepare_buf(int cam_id, mm_camera_channel_type_t ch_type) 824 { 825 int32_t rc = -1; 826 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 827 if (mm_cam) { 828 rc = mm_cam->cfg->unprepare_buf(mm_cam, ch_type); 829 } 830 return rc; 831 } 832 833 /*operation methods*/ 834 uint8_t cam_ops_is_op_supported(int cam_id, mm_camera_ops_type_t opcode) 835 { 836 uint8_t rc = 0; 837 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 838 if (mm_cam) { 839 rc = mm_cam->ops->is_op_supported(mm_cam, opcode); 840 } 841 return rc; 842 } 843 /* val is reserved for some action such as MM_CAMERA_OPS_FOCUS */ 844 int32_t cam_ops_action(int cam_id, uint8_t start, 845 mm_camera_ops_type_t opcode, void *val) 846 { 847 int32_t rc = -1; 848 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 849 if (mm_cam) { 850 rc = mm_cam->ops->action(mm_cam, start, opcode, val); 851 } 852 return rc; 853 } 854 855 int32_t cam_ops_open(int cam_id, mm_camera_op_mode_type_t op_mode) 856 { 857 int32_t rc = -1; 858 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 859 if (mm_cam) { 860 rc = mm_cam->ops->open(mm_cam, op_mode); 861 } 862 return rc; 863 } 864 865 void cam_ops_close(int cam_id) 866 { 867 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 868 if (mm_cam) { 869 mm_cam->ops->close(mm_cam); 870 } 871 } 872 873 void cam_ops_stop(int cam_id) 874 { 875 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 876 if (mm_cam) { 877 mm_cam->ops->stop(mm_cam); 878 } 879 } 880 881 int32_t cam_ops_ch_acquire(int cam_id, mm_camera_channel_type_t ch_type) 882 { 883 int32_t rc = -1; 884 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 885 if (mm_cam) { 886 rc = mm_cam->ops->ch_acquire(mm_cam, ch_type); 887 } 888 return rc; 889 } 890 891 void cam_ops_ch_release(int cam_id, mm_camera_channel_type_t ch_type) 892 { 893 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 894 if (mm_cam) { 895 mm_cam->ops->ch_release(mm_cam, ch_type); 896 } 897 } 898 899 int32_t cam_ops_ch_set_attr(int cam_id, mm_camera_channel_type_t ch_type, 900 mm_camera_channel_attr_t *attr) 901 { 902 int32_t rc = -1; 903 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 904 if (mm_cam) { 905 rc = mm_cam->ops->ch_set_attr(mm_cam, ch_type, attr); 906 } 907 return rc; 908 } 909 910 int32_t cam_ops_sendmsg(int cam_id, void *msg, uint32_t buf_size, int sendfd) 911 { 912 int32_t rc = -1; 913 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 914 if (mm_cam) { 915 rc = mm_cam->ops->sendmsg(mm_cam, msg, buf_size, sendfd); 916 } 917 return rc; 918 } 919 920 /*call-back notify methods*/ 921 uint8_t cam_evt_is_event_supported(int cam_id, mm_camera_event_type_t evt_type) 922 { 923 uint8_t rc = 0; 924 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 925 if (mm_cam) { 926 rc = mm_cam->evt->is_event_supported(mm_cam, evt_type); 927 } 928 return rc; 929 } 930 931 int32_t cam_evt_register_event_notify(int cam_id, 932 mm_camera_event_notify_t evt_cb, 933 void * user_data, 934 mm_camera_event_type_t evt_type) 935 { 936 int32_t rc = -1; 937 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 938 if (mm_cam) { 939 rc = mm_cam->evt->register_event_notify( 940 mm_cam, evt_cb, user_data, evt_type); 941 } 942 return rc; 943 } 944 945 int32_t cam_evt_register_buf_notify(int cam_id, 946 mm_camera_channel_type_t ch_type, 947 mm_camera_buf_notify_t buf_cb, 948 mm_camera_register_buf_cb_type_t cb_type, 949 uint32_t cb_count, 950 void * user_data) 951 { 952 int32_t rc = -1; 953 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 954 if (mm_cam) { 955 rc = mm_cam->evt->register_buf_notify( 956 mm_cam, ch_type, buf_cb, cb_type, 957 cb_count, user_data); 958 } 959 return rc; 960 } 961 962 int32_t cam_evt_buf_done(int cam_id, mm_camera_ch_data_buf_t *bufs) 963 { 964 int32_t rc = -1; 965 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 966 if (mm_cam) { 967 rc = mm_cam->evt->buf_done(mm_cam, bufs); 968 } 969 return rc; 970 } 971 972 /*camera JPEG methods*/ 973 uint8_t cam_jpeg_is_jpeg_supported(int cam_id) 974 { 975 uint8_t rc = 0; 976 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 977 if (mm_cam) { 978 rc = mm_cam->jpeg_ops->is_jpeg_supported(mm_cam); 979 } 980 return rc; 981 } 982 983 int32_t cam_jpeg_set_parm(int cam_id, mm_camera_jpeg_parm_type_t parm_type, 984 void* p_value) 985 { 986 int32_t rc = -1; 987 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 988 if (mm_cam) { 989 rc = mm_cam->jpeg_ops->set_parm(mm_cam, parm_type, p_value); 990 } 991 return rc; 992 } 993 994 int32_t cam_jpeg_get_parm(int cam_id, mm_camera_jpeg_parm_type_t parm_type, 995 void* p_value) 996 { 997 int32_t rc = -1; 998 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 999 if (mm_cam) { 1000 rc = mm_cam->jpeg_ops->get_parm(mm_cam, parm_type, p_value); 1001 } 1002 return rc; 1003 } 1004 int32_t cam_jpeg_register_event_cb(int cam_id, mm_camera_jpeg_cb_t * evt_cb, 1005 void * user_data) 1006 { 1007 int32_t rc = -1; 1008 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 1009 if (mm_cam) { 1010 rc = mm_cam->jpeg_ops->register_event_cb(mm_cam, evt_cb, user_data); 1011 } 1012 return rc; 1013 } 1014 int32_t cam_jpeg_encode(int cam_id, uint8_t start, 1015 mm_camera_jpeg_encode_t *data) 1016 { 1017 int32_t rc = -1; 1018 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 1019 if (mm_cam) { 1020 rc = mm_cam->jpeg_ops->encode(mm_cam, start, data); 1021 } 1022 return rc; 1023 } 1024 1025