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