Home | History | Annotate | Download | only in mm-camera-interface
      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 *)&reg);
    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