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