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 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 .ch_acquire = mm_camera_ops_ch_acquire, 468 .ch_release = mm_camera_ops_ch_release, 469 .ch_set_attr = mm_camera_ops_ch_attr, 470 .sendmsg = mm_camera_ops_sendmsg 471 }; 472 473 static uint8_t mm_camera_notify_is_event_supported(mm_camera_t * camera, 474 mm_camera_event_type_t evt_type) 475 { 476 switch(evt_type) { 477 case MM_CAMERA_EVT_TYPE_CH: 478 case MM_CAMERA_EVT_TYPE_CTRL: 479 case MM_CAMERA_EVT_TYPE_STATS: 480 case MM_CAMERA_EVT_TYPE_INFO: 481 return 1; 482 default: 483 return 0; 484 } 485 return 0; 486 } 487 488 static int32_t mm_camera_notify_register_event_cb(mm_camera_t * camera, 489 mm_camera_event_notify_t evt_cb, 490 void * user_data, 491 mm_camera_event_type_t evt_type) 492 { 493 mm_camera_obj_t * my_obj = NULL; 494 mm_camera_buf_cb_t reg ; 495 int rc = -1; 496 497 pthread_mutex_lock(&g_mutex); 498 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 499 pthread_mutex_unlock(&g_mutex); 500 if(my_obj) { 501 pthread_mutex_lock(&my_obj->mutex); 502 rc = mm_camera_reg_event(my_obj, evt_cb, user_data, evt_type); 503 pthread_mutex_unlock(&my_obj->mutex); 504 } 505 return rc; 506 } 507 508 static int32_t mm_camera_register_buf_notify ( 509 mm_camera_t * camera, 510 mm_camera_channel_type_t ch_type, 511 mm_camera_buf_notify_t buf_cb, 512 mm_camera_register_buf_cb_type_t cb_type, 513 uint32_t cb_count, 514 void * user_data) 515 { 516 mm_camera_obj_t * my_obj = NULL; 517 mm_camera_buf_cb_t reg ; 518 int rc = -1; 519 520 reg.cb = buf_cb; 521 reg.user_data = user_data; 522 reg.cb_type=cb_type; 523 reg.cb_count=cb_count; 524 pthread_mutex_lock(&g_mutex); 525 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 526 pthread_mutex_unlock(&g_mutex); 527 if(my_obj) { 528 pthread_mutex_lock(&my_obj->mutex); 529 rc = mm_camera_ch_fn(my_obj,ch_type, 530 MM_CAMERA_STATE_EVT_REG_BUF_CB, (void *)®); 531 pthread_mutex_unlock(&my_obj->mutex); 532 } 533 return rc; 534 } 535 static int32_t mm_camera_buf_done(mm_camera_t * camera, mm_camera_ch_data_buf_t * bufs) 536 { 537 mm_camera_obj_t * my_obj = NULL; 538 int rc = -1; 539 my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id]; 540 if(my_obj) { 541 /*pthread_mutex_lock(&my_obj->mutex);*/ 542 rc = mm_camera_ch_fn(my_obj, bufs->type, 543 MM_CAMERA_STATE_EVT_QBUF, (void *)bufs); 544 /*pthread_mutex_unlock(&my_obj->mutex);*/ 545 } 546 return rc; 547 } 548 549 static mm_camera_notify_t mm_camera_notify = { 550 .is_event_supported = mm_camera_notify_is_event_supported, 551 .register_event_notify = mm_camera_notify_register_event_cb, 552 .register_buf_notify = mm_camera_register_buf_notify, 553 .buf_done = mm_camera_buf_done 554 }; 555 556 static uint8_t mm_camera_jpeg_is_jpeg_supported (mm_camera_t * camera) 557 { 558 return FALSE; 559 } 560 static int32_t mm_camera_jpeg_set_parm (mm_camera_t * camera, 561 mm_camera_jpeg_parm_type_t parm_type, 562 void* p_value) 563 { 564 return -1; 565 } 566 static int32_t mm_camera_jpeg_get_parm (mm_camera_t * camera, 567 mm_camera_jpeg_parm_type_t parm_type, 568 void* p_value) 569 { 570 return -1; 571 } 572 static int32_t mm_camera_jpeg_register_event_cb(mm_camera_t * camera, 573 mm_camera_jpeg_cb_t * evt_cb, 574 void * user_data) 575 { 576 return -1; 577 } 578 static int32_t mm_camera_jpeg_encode (mm_camera_t * camera, uint8_t start, 579 mm_camera_jpeg_encode_t *data) 580 { 581 return -1; 582 } 583 584 static mm_camera_jpeg_t mm_camera_jpeg = { 585 .is_jpeg_supported = mm_camera_jpeg_is_jpeg_supported, 586 .set_parm = mm_camera_jpeg_set_parm, 587 .get_parm = mm_camera_jpeg_get_parm, 588 .register_event_cb = mm_camera_jpeg_register_event_cb, 589 .encode = mm_camera_jpeg_encode, 590 }; 591 592 extern mm_camera_t * mm_camera_query (uint8_t *num_cameras) 593 { 594 int i = 0, rc = MM_CAMERA_OK; 595 int dev_fd = 0; 596 struct media_device_info mdev_info; 597 int num_media_devices = 0; 598 if (!num_cameras) 599 return NULL; 600 /* lock the mutex */ 601 pthread_mutex_lock(&g_mutex); 602 *num_cameras = 0; 603 while (1) { 604 char dev_name[32]; 605 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices); 606 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK); 607 if (dev_fd < 0) { 608 CDBG("Done discovering media devices\n"); 609 break; 610 } 611 num_media_devices++; 612 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info); 613 if (rc < 0) { 614 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno)); 615 close(dev_fd); 616 break; 617 } 618 619 if(strncmp(mdev_info.model, QCAMERA_NAME, sizeof(mdev_info.model) != 0)) { 620 close(dev_fd); 621 continue; 622 } 623 624 char * mdev_cfg; 625 int cam_type = 0, mount_angle = 0, info_index = 0; 626 mdev_cfg = strtok(mdev_info.serial, "-"); 627 while(mdev_cfg != NULL) { 628 if(info_index == 0) { 629 if(strcmp(mdev_cfg, QCAMERA_NAME)) 630 break; 631 } else if(info_index == 1) { 632 mount_angle = atoi(mdev_cfg); 633 } else if(info_index == 2) { 634 cam_type = atoi(mdev_cfg); 635 } 636 mdev_cfg = strtok(NULL, "-"); 637 info_index++; 638 } 639 640 if(info_index == 0) { 641 close(dev_fd); 642 continue; 643 } 644 645 int num_entities = 1; 646 while (1) { 647 struct media_entity_desc entity; 648 memset(&entity, 0, sizeof(entity)); 649 entity.id = num_entities++; 650 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity); 651 if (rc < 0) { 652 CDBG("Done enumerating media entities\n"); 653 rc = 0; 654 break; 655 } 656 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) { 657 strncpy(g_cam_ctrl.camera[*num_cameras].video_dev_name, 658 entity.name, sizeof(entity.name)); 659 break; 660 } 661 } 662 663 g_cam_ctrl.camera[*num_cameras].camera_info.camera_id = *num_cameras; 664 665 g_cam_ctrl.camera[*num_cameras]. 666 camera_info.modes_supported = CAMERA_MODE_2D; 667 if(cam_type > 1) 668 g_cam_ctrl.camera[*num_cameras]. 669 camera_info.modes_supported |= CAMERA_MODE_3D; 670 671 g_cam_ctrl.camera[*num_cameras].camera_info.position = 672 (cam_type == 1) ? FRONT_CAMERA : BACK_CAMERA; 673 g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle = 674 mount_angle; 675 g_cam_ctrl.camera[*num_cameras].sensor_type = 0; 676 g_cam_ctrl.camera[*num_cameras].cfg = &mm_camera_cfg; 677 g_cam_ctrl.camera[*num_cameras].ops = &mm_camera_ops; 678 g_cam_ctrl.camera[*num_cameras].evt = &mm_camera_notify; 679 g_cam_ctrl.camera[*num_cameras].jpeg_ops = NULL; 680 681 CDBG("%s: dev_info[id=%d,name='%s',pos=%d,modes=0x%x,sensor=%d]\n", 682 __func__, *num_cameras, 683 g_cam_ctrl.camera[*num_cameras].video_dev_name, 684 g_cam_ctrl.camera[*num_cameras].camera_info.position, 685 g_cam_ctrl.camera[*num_cameras].camera_info.modes_supported, 686 g_cam_ctrl.camera[*num_cameras].sensor_type); 687 688 *num_cameras+=1; 689 if (dev_fd > 0) { 690 close(dev_fd); 691 } 692 } 693 *num_cameras = *num_cameras; 694 g_cam_ctrl.num_cam = *num_cameras; 695 end: 696 /* unlock the mutex */ 697 pthread_mutex_unlock(&g_mutex); 698 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam); 699 if(rc == 0) 700 return &g_cam_ctrl.camera[0]; 701 else 702 return NULL; 703 } 704 705 706 static mm_camera_t * get_camera_by_id( int cam_id) 707 { 708 mm_camera_t * mm_cam; 709 if( cam_id < 0 || cam_id >= g_cam_ctrl.num_cam) { 710 mm_cam = NULL; 711 } else { 712 mm_cam = & g_cam_ctrl.camera[cam_id]; 713 } 714 return mm_cam; 715 } 716 717 /*configure methods*/ 718 uint8_t cam_config_is_parm_supported( 719 int cam_id, 720 mm_camera_parm_type_t parm_type) 721 { 722 uint8_t rc = 0; 723 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 724 if (mm_cam && mm_cam->cfg) { 725 rc = mm_cam->cfg->is_parm_supported(mm_cam, parm_type); 726 } 727 return rc; 728 } 729 730 uint8_t cam_config_is_ch_supported( 731 int cam_id, 732 mm_camera_channel_type_t ch_type) 733 { 734 uint8_t rc = 0; 735 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 736 if (mm_cam) { 737 rc = mm_cam->cfg->is_ch_supported(mm_cam, ch_type); 738 } 739 return rc; 740 741 } 742 743 /* set a parms current value */ 744 int32_t cam_config_set_parm( 745 int cam_id, 746 mm_camera_parm_type_t parm_type, 747 void* p_value) 748 { 749 int32_t rc = -1; 750 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 751 if (mm_cam) { 752 rc = mm_cam->cfg->set_parm(mm_cam, parm_type, p_value); 753 } 754 return rc; 755 } 756 757 /* get a parms current value */ 758 int32_t cam_config_get_parm( 759 int cam_id, 760 mm_camera_parm_type_t parm_type, 761 void* p_value) 762 { 763 int32_t rc = -1; 764 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 765 if (mm_cam) { 766 rc = mm_cam->cfg->get_parm(mm_cam, parm_type, p_value); 767 } 768 return rc; 769 } 770 771 int32_t cam_config_request_buf(int cam_id, mm_camera_reg_buf_t *buf) 772 { 773 774 int32_t rc = -1; 775 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 776 if (mm_cam) { 777 rc = mm_cam->cfg->request_buf(mm_cam, buf); 778 } 779 return rc; 780 } 781 782 int32_t cam_config_enqueue_buf(int cam_id, mm_camera_reg_buf_t *buf) 783 { 784 785 int32_t rc = -1; 786 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 787 if (mm_cam) { 788 rc = mm_cam->cfg->enqueue_buf(mm_cam, buf); 789 } 790 return rc; 791 } 792 793 int32_t cam_config_prepare_buf(int cam_id, mm_camera_reg_buf_t *buf) 794 { 795 796 int32_t rc = -1; 797 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 798 if (mm_cam) { 799 rc = mm_cam->cfg->prepare_buf(mm_cam, buf); 800 } 801 return rc; 802 } 803 int32_t cam_config_unprepare_buf(int cam_id, mm_camera_channel_type_t ch_type) 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->unprepare_buf(mm_cam, ch_type); 809 } 810 return rc; 811 } 812 813 /*operation methods*/ 814 uint8_t cam_ops_is_op_supported(int cam_id, mm_camera_ops_type_t opcode) 815 { 816 uint8_t rc = 0; 817 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 818 if (mm_cam) { 819 rc = mm_cam->ops->is_op_supported(mm_cam, opcode); 820 } 821 return rc; 822 } 823 /* val is reserved for some action such as MM_CAMERA_OPS_FOCUS */ 824 int32_t cam_ops_action(int cam_id, uint8_t start, 825 mm_camera_ops_type_t opcode, void *val) 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->action(mm_cam, start, opcode, val); 831 } 832 return rc; 833 } 834 835 int32_t cam_ops_open(int cam_id, mm_camera_op_mode_type_t op_mode) 836 { 837 int32_t rc = -1; 838 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 839 if (mm_cam) { 840 rc = mm_cam->ops->open(mm_cam, op_mode); 841 } 842 return rc; 843 } 844 845 void cam_ops_close(int cam_id) 846 { 847 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 848 if (mm_cam) { 849 mm_cam->ops->close(mm_cam); 850 } 851 } 852 853 int32_t cam_ops_ch_acquire(int cam_id, mm_camera_channel_type_t ch_type) 854 { 855 int32_t rc = -1; 856 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 857 if (mm_cam) { 858 rc = mm_cam->ops->ch_acquire(mm_cam, ch_type); 859 } 860 return rc; 861 } 862 863 void cam_ops_ch_release(int cam_id, mm_camera_channel_type_t ch_type) 864 { 865 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 866 if (mm_cam) { 867 mm_cam->ops->ch_release(mm_cam, ch_type); 868 } 869 } 870 871 int32_t cam_ops_ch_set_attr(int cam_id, mm_camera_channel_type_t ch_type, 872 mm_camera_channel_attr_t *attr) 873 { 874 int32_t rc = -1; 875 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 876 if (mm_cam) { 877 rc = mm_cam->ops->ch_set_attr(mm_cam, ch_type, attr); 878 } 879 return rc; 880 } 881 882 int32_t cam_ops_sendmsg(int cam_id, void *msg, uint32_t buf_size, int sendfd) 883 { 884 int32_t rc = -1; 885 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 886 if (mm_cam) { 887 rc = mm_cam->ops->sendmsg(mm_cam, msg, buf_size, sendfd); 888 } 889 return rc; 890 } 891 892 /*call-back notify methods*/ 893 uint8_t cam_evt_is_event_supported(int cam_id, mm_camera_event_type_t evt_type) 894 { 895 uint8_t rc = 0; 896 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 897 if (mm_cam) { 898 rc = mm_cam->evt->is_event_supported(mm_cam, evt_type); 899 } 900 return rc; 901 } 902 903 int32_t cam_evt_register_event_notify(int cam_id, 904 mm_camera_event_notify_t evt_cb, 905 void * user_data, 906 mm_camera_event_type_t evt_type) 907 { 908 int32_t rc = -1; 909 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 910 if (mm_cam) { 911 rc = mm_cam->evt->register_event_notify( 912 mm_cam, evt_cb, user_data, evt_type); 913 } 914 return rc; 915 } 916 917 int32_t cam_evt_register_buf_notify(int cam_id, 918 mm_camera_channel_type_t ch_type, 919 mm_camera_buf_notify_t buf_cb, 920 mm_camera_register_buf_cb_type_t cb_type, 921 uint32_t cb_count, 922 void * user_data) 923 { 924 int32_t rc = -1; 925 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 926 if (mm_cam) { 927 rc = mm_cam->evt->register_buf_notify( 928 mm_cam, ch_type, buf_cb, cb_type, 929 cb_count, user_data); 930 } 931 return rc; 932 } 933 934 int32_t cam_evt_buf_done(int cam_id, mm_camera_ch_data_buf_t *bufs) 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->buf_done(mm_cam, bufs); 940 } 941 return rc; 942 } 943 944 /*camera JPEG methods*/ 945 uint8_t cam_jpeg_is_jpeg_supported(int cam_id) 946 { 947 uint8_t rc = 0; 948 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 949 if (mm_cam) { 950 rc = mm_cam->jpeg_ops->is_jpeg_supported(mm_cam); 951 } 952 return rc; 953 } 954 955 int32_t cam_jpeg_set_parm(int cam_id, mm_camera_jpeg_parm_type_t parm_type, 956 void* p_value) 957 { 958 int32_t rc = -1; 959 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 960 if (mm_cam) { 961 rc = mm_cam->jpeg_ops->set_parm(mm_cam, parm_type, p_value); 962 } 963 return rc; 964 } 965 966 int32_t cam_jpeg_get_parm(int cam_id, mm_camera_jpeg_parm_type_t parm_type, 967 void* p_value) 968 { 969 int32_t rc = -1; 970 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 971 if (mm_cam) { 972 rc = mm_cam->jpeg_ops->get_parm(mm_cam, parm_type, p_value); 973 } 974 return rc; 975 } 976 int32_t cam_jpeg_register_event_cb(int cam_id, mm_camera_jpeg_cb_t * evt_cb, 977 void * user_data) 978 { 979 int32_t rc = -1; 980 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 981 if (mm_cam) { 982 rc = mm_cam->jpeg_ops->register_event_cb(mm_cam, evt_cb, user_data); 983 } 984 return rc; 985 } 986 int32_t cam_jpeg_encode(int cam_id, uint8_t start, 987 mm_camera_jpeg_encode_t *data) 988 { 989 int32_t rc = -1; 990 mm_camera_t * mm_cam = get_camera_by_id(cam_id); 991 if (mm_cam) { 992 rc = mm_cam->jpeg_ops->encode(mm_cam, start, data); 993 } 994 return rc; 995 } 996 997