Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundation nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  *
     28  */
     29 
     30 #include <pthread.h>
     31 #include <errno.h>
     32 #include <sys/ioctl.h>
     33 #include <sys/types.h>
     34 #include <sys/stat.h>
     35 #include <fcntl.h>
     36 #include <poll.h>
     37 #include <linux/media.h>
     38 #include <signal.h>
     39 #include <media/msm_cam_sensor.h>
     40 #include <cutils/properties.h>
     41 #include <stdlib.h>
     42 
     43 #include "mm_camera_dbg.h"
     44 #include "mm_camera_interface.h"
     45 #include "mm_camera_sock.h"
     46 #include "mm_camera.h"
     47 
     48 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
     49 
     50 static mm_camera_ctrl_t g_cam_ctrl = {0, {{0}}, {0}, {{0}}};
     51 
     52 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
     53 static uint16_t g_handler_history_count = 0; /* history count for handler */
     54 volatile uint32_t gMmCameraIntfLogLevel = 1;
     55 
     56 /*===========================================================================
     57  * FUNCTION   : mm_camera_util_generate_handler
     58  *
     59  * DESCRIPTION: utility function to generate handler for camera/channel/stream
     60  *
     61  * PARAMETERS :
     62  *   @index: index of the object to have handler
     63  *
     64  * RETURN     : uint32_t type of handle that uniquely identify the object
     65  *==========================================================================*/
     66 uint32_t mm_camera_util_generate_handler(uint8_t index)
     67 {
     68     uint32_t handler = 0;
     69     pthread_mutex_lock(&g_handler_lock);
     70     g_handler_history_count++;
     71     if (0 == g_handler_history_count) {
     72         g_handler_history_count++;
     73     }
     74     handler = g_handler_history_count;
     75     handler = (handler<<8) | index;
     76     pthread_mutex_unlock(&g_handler_lock);
     77     return handler;
     78 }
     79 
     80 /*===========================================================================
     81  * FUNCTION   : mm_camera_util_get_index_by_handler
     82  *
     83  * DESCRIPTION: utility function to get index from handle
     84  *
     85  * PARAMETERS :
     86  *   @handler: object handle
     87  *
     88  * RETURN     : uint8_t type of index derived from handle
     89  *==========================================================================*/
     90 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
     91 {
     92     return (handler&0x000000ff);
     93 }
     94 
     95 /*===========================================================================
     96  * FUNCTION   : mm_camera_util_get_dev_name
     97  *
     98  * DESCRIPTION: utility function to get device name from camera handle
     99  *
    100  * PARAMETERS :
    101  *   @cam_handle: camera handle
    102  *
    103  * RETURN     : char ptr to the device name stored in global variable
    104  * NOTE       : caller should not free the char ptr
    105  *==========================================================================*/
    106 const char *mm_camera_util_get_dev_name(uint32_t cam_handle)
    107 {
    108     char *dev_name = NULL;
    109     uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
    110     if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) {
    111         dev_name = g_cam_ctrl.video_dev_name[cam_idx];
    112     }
    113     return dev_name;
    114 }
    115 
    116 /*===========================================================================
    117  * FUNCTION   : mm_camera_util_get_camera_by_handler
    118  *
    119  * DESCRIPTION: utility function to get camera object from camera handle
    120  *
    121  * PARAMETERS :
    122  *   @cam_handle: camera handle
    123  *
    124  * RETURN     : ptr to the camera object stored in global variable
    125  * NOTE       : caller should not free the camera object ptr
    126  *==========================================================================*/
    127 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle)
    128 {
    129     mm_camera_obj_t *cam_obj = NULL;
    130     uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
    131 
    132     if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS &&
    133         (NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
    134         (cam_handle == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
    135         cam_obj = g_cam_ctrl.cam_obj[cam_idx];
    136     }
    137     return cam_obj;
    138 }
    139 
    140 /*===========================================================================
    141  * FUNCTION   : mm_camera_intf_query_capability
    142  *
    143  * DESCRIPTION: query camera capability
    144  *
    145  * PARAMETERS :
    146  *   @camera_handle: camera handle
    147  *
    148  * RETURN     : int32_t type of status
    149  *              0  -- success
    150  *              -1 -- failure
    151  *==========================================================================*/
    152 static int32_t mm_camera_intf_query_capability(uint32_t camera_handle)
    153 {
    154     int32_t rc = -1;
    155     mm_camera_obj_t * my_obj = NULL;
    156 
    157     CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
    158 
    159     pthread_mutex_lock(&g_intf_lock);
    160     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    161 
    162     if(my_obj) {
    163         pthread_mutex_lock(&my_obj->cam_lock);
    164         pthread_mutex_unlock(&g_intf_lock);
    165         rc = mm_camera_query_capability(my_obj);
    166     } else {
    167         pthread_mutex_unlock(&g_intf_lock);
    168     }
    169     CDBG("%s :X rc = %d", __func__, rc);
    170     return rc;
    171 }
    172 
    173 /*===========================================================================
    174  * FUNCTION   : mm_camera_intf_set_parms
    175  *
    176  * DESCRIPTION: set parameters per camera
    177  *
    178  * PARAMETERS :
    179  *   @camera_handle: camera handle
    180  *   @parms        : ptr to a param struct to be set to server
    181  *
    182  * RETURN     : int32_t type of status
    183  *              0  -- success
    184  *              -1 -- failure
    185  * NOTE       : Assume the parms struct buf is already mapped to server via
    186  *              domain socket. Corresponding fields of parameters to be set
    187  *              are already filled in by upper layer caller.
    188  *==========================================================================*/
    189 static int32_t mm_camera_intf_set_parms(uint32_t camera_handle,
    190                                         parm_buffer_t *parms)
    191 {
    192     int32_t rc = -1;
    193     mm_camera_obj_t * my_obj = NULL;
    194 
    195     pthread_mutex_lock(&g_intf_lock);
    196     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    197 
    198     if(my_obj) {
    199         pthread_mutex_lock(&my_obj->cam_lock);
    200         pthread_mutex_unlock(&g_intf_lock);
    201         rc = mm_camera_set_parms(my_obj, parms);
    202     } else {
    203         pthread_mutex_unlock(&g_intf_lock);
    204     }
    205     return rc;
    206 }
    207 
    208 /*===========================================================================
    209  * FUNCTION   : mm_camera_intf_get_parms
    210  *
    211  * DESCRIPTION: get parameters per camera
    212  *
    213  * PARAMETERS :
    214  *   @camera_handle: camera handle
    215  *   @parms        : ptr to a param struct to be get from server
    216  *
    217  * RETURN     : int32_t type of status
    218  *              0  -- success
    219  *              -1 -- failure
    220  * NOTE       : Assume the parms struct buf is already mapped to server via
    221  *              domain socket. Parameters to be get from server are already
    222  *              filled in by upper layer caller. After this call, corresponding
    223  *              fields of requested parameters will be filled in by server with
    224  *              detailed information.
    225  *==========================================================================*/
    226 static int32_t mm_camera_intf_get_parms(uint32_t camera_handle,
    227                                         parm_buffer_t *parms)
    228 {
    229     int32_t rc = -1;
    230     mm_camera_obj_t * my_obj = NULL;
    231 
    232     pthread_mutex_lock(&g_intf_lock);
    233     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    234 
    235     if(my_obj) {
    236         pthread_mutex_lock(&my_obj->cam_lock);
    237         pthread_mutex_unlock(&g_intf_lock);
    238         rc = mm_camera_get_parms(my_obj, parms);
    239     } else {
    240         pthread_mutex_unlock(&g_intf_lock);
    241     }
    242     return rc;
    243 }
    244 
    245 /*===========================================================================
    246  * FUNCTION   : mm_camera_intf_do_auto_focus
    247  *
    248  * DESCRIPTION: performing auto focus
    249  *
    250  * PARAMETERS :
    251  *   @camera_handle: camera handle
    252  *
    253  * RETURN     : int32_t type of status
    254  *              0  -- success
    255  *              -1 -- failure
    256  * NOTE       : if this call success, we will always assume there will
    257  *              be an auto_focus event following up.
    258  *==========================================================================*/
    259 static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle)
    260 {
    261     int32_t rc = -1;
    262     mm_camera_obj_t * my_obj = NULL;
    263 
    264     pthread_mutex_lock(&g_intf_lock);
    265     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    266 
    267     if(my_obj) {
    268         pthread_mutex_lock(&my_obj->cam_lock);
    269         pthread_mutex_unlock(&g_intf_lock);
    270         rc = mm_camera_do_auto_focus(my_obj);
    271     } else {
    272         pthread_mutex_unlock(&g_intf_lock);
    273     }
    274     return rc;
    275 }
    276 
    277 /*===========================================================================
    278  * FUNCTION   : mm_camera_intf_cancel_auto_focus
    279  *
    280  * DESCRIPTION: cancel auto focus
    281  *
    282  * PARAMETERS :
    283  *   @camera_handle: camera handle
    284  *
    285  * RETURN     : int32_t type of status
    286  *              0  -- success
    287  *              -1 -- failure
    288  *==========================================================================*/
    289 static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle)
    290 {
    291     int32_t rc = -1;
    292     mm_camera_obj_t * my_obj = NULL;
    293 
    294     pthread_mutex_lock(&g_intf_lock);
    295     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    296 
    297     if(my_obj) {
    298         pthread_mutex_lock(&my_obj->cam_lock);
    299         pthread_mutex_unlock(&g_intf_lock);
    300         rc = mm_camera_cancel_auto_focus(my_obj);
    301     } else {
    302         pthread_mutex_unlock(&g_intf_lock);
    303     }
    304     return rc;
    305 }
    306 
    307 /*===========================================================================
    308  * FUNCTION   : mm_camera_intf_prepare_snapshot
    309  *
    310  * DESCRIPTION: prepare hardware for snapshot
    311  *
    312  * PARAMETERS :
    313  *   @camera_handle: camera handle
    314  *   @do_af_flag   : flag indicating if AF is needed
    315  *
    316  * RETURN     : int32_t type of status
    317  *              0  -- success
    318  *              -1 -- failure
    319  *==========================================================================*/
    320 static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle,
    321                                                int32_t do_af_flag)
    322 {
    323     int32_t rc = -1;
    324     mm_camera_obj_t * my_obj = NULL;
    325 
    326     pthread_mutex_lock(&g_intf_lock);
    327     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    328 
    329     if(my_obj) {
    330         pthread_mutex_lock(&my_obj->cam_lock);
    331         pthread_mutex_unlock(&g_intf_lock);
    332         rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
    333     } else {
    334         pthread_mutex_unlock(&g_intf_lock);
    335     }
    336     return rc;
    337 }
    338 
    339 /*===========================================================================
    340  * FUNCTION   : mm_camera_intf_close
    341  *
    342  * DESCRIPTION: close a camera by its handle
    343  *
    344  * PARAMETERS :
    345  *   @camera_handle: camera handle
    346  *
    347  * RETURN     : int32_t type of status
    348  *              0  -- success
    349  *              -1 -- failure
    350  *==========================================================================*/
    351 static int32_t mm_camera_intf_close(uint32_t camera_handle)
    352 {
    353     int32_t rc = -1;
    354     uint8_t cam_idx = camera_handle & 0x00ff;
    355     mm_camera_obj_t * my_obj = NULL;
    356 
    357     CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
    358 
    359     pthread_mutex_lock(&g_intf_lock);
    360     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    361 
    362     if (my_obj){
    363         my_obj->ref_count--;
    364 
    365         if(my_obj->ref_count > 0) {
    366             /* still have reference to obj, return here */
    367             CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
    368             pthread_mutex_unlock(&g_intf_lock);
    369             rc = 0;
    370         } else {
    371             /* need close camera here as no other reference
    372              * first empty g_cam_ctrl's referent to cam_obj */
    373             g_cam_ctrl.cam_obj[cam_idx] = NULL;
    374 
    375             pthread_mutex_lock(&my_obj->cam_lock);
    376             pthread_mutex_unlock(&g_intf_lock);
    377 
    378             rc = mm_camera_close(my_obj);
    379 
    380             pthread_mutex_destroy(&my_obj->cam_lock);
    381             free(my_obj);
    382         }
    383     } else {
    384         pthread_mutex_unlock(&g_intf_lock);
    385     }
    386 
    387     return rc;
    388 }
    389 
    390 /*===========================================================================
    391  * FUNCTION   : mm_camera_intf_error_close
    392  *
    393  * DESCRIPTION: close the daemon after an unrecoverable error
    394  *
    395  * PARAMETERS :
    396  *   @camera_handle: camera handle
    397  *
    398  * RETURN     : int32_t type of status
    399  *              0  -- success
    400  *              -1 -- failure
    401  *==========================================================================*/
    402 static int32_t mm_camera_intf_error_close(uint32_t camera_handle)
    403 {
    404     int32_t rc = -1;
    405     uint8_t cam_idx = camera_handle & 0x00ff;
    406     mm_camera_obj_t * my_obj = NULL;
    407 
    408     CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
    409 
    410     pthread_mutex_lock(&g_intf_lock);
    411     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    412 
    413     if (my_obj){
    414         /*do not decrement the ref_count yet since that will happen during close*/
    415         if((my_obj->ref_count - 1) > 0) {
    416             /* still have reference to obj, return here */
    417             CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
    418             pthread_mutex_unlock(&g_intf_lock);
    419             rc = 0;
    420         } else {
    421             /* need close camera here as no other reference*/
    422             pthread_mutex_lock(&my_obj->cam_lock);
    423             pthread_mutex_unlock(&g_intf_lock);
    424 
    425             rc = mm_camera_close_fd(my_obj);
    426         }
    427     } else {
    428         pthread_mutex_unlock(&g_intf_lock);
    429     }
    430 
    431     return rc;
    432 }
    433 
    434 /*===========================================================================
    435  * FUNCTION   : mm_camera_intf_add_channel
    436  *
    437  * DESCRIPTION: add a channel
    438  *
    439  * PARAMETERS :
    440  *   @camera_handle: camera handle
    441  *   @attr         : bundle attribute of the channel if needed
    442  *   @channel_cb   : callback function for bundle data notify
    443  *   @userdata     : user data ptr
    444  *
    445  * RETURN     : uint32_t type of channel handle
    446  *              0  -- invalid channel handle, meaning the op failed
    447  *              >0 -- successfully added a channel with a valid handle
    448  * NOTE       : if no bundle data notify is needed, meaning each stream in the
    449  *              channel will have its own stream data notify callback, then
    450  *              attr, channel_cb, and userdata can be NULL. In this case,
    451  *              no matching logic will be performed in channel for the bundling.
    452  *==========================================================================*/
    453 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle,
    454                                            mm_camera_channel_attr_t *attr,
    455                                            mm_camera_buf_notify_t channel_cb,
    456                                            void *userdata)
    457 {
    458     uint32_t ch_id = 0;
    459     mm_camera_obj_t * my_obj = NULL;
    460 
    461     CDBG("%s :E camera_handler = %d", __func__, camera_handle);
    462     pthread_mutex_lock(&g_intf_lock);
    463     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    464 
    465     if(my_obj) {
    466         pthread_mutex_lock(&my_obj->cam_lock);
    467         pthread_mutex_unlock(&g_intf_lock);
    468         ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
    469     } else {
    470         pthread_mutex_unlock(&g_intf_lock);
    471     }
    472     CDBG("%s :X ch_id = %d", __func__, ch_id);
    473     return ch_id;
    474 }
    475 
    476 /*===========================================================================
    477  * FUNCTION   : mm_camera_intf_del_channel
    478  *
    479  * DESCRIPTION: delete a channel by its handle
    480  *
    481  * PARAMETERS :
    482  *   @camera_handle: camera handle
    483  *   @ch_id        : channel handle
    484  *
    485  * RETURN     : int32_t type of status
    486  *              0  -- success
    487  *              -1 -- failure
    488  * NOTE       : all streams in the channel should be stopped already before
    489  *              this channel can be deleted.
    490  *==========================================================================*/
    491 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle,
    492                                           uint32_t ch_id)
    493 {
    494     int32_t rc = -1;
    495     mm_camera_obj_t * my_obj = NULL;
    496 
    497     CDBG("%s :E ch_id = %d", __func__, ch_id);
    498     pthread_mutex_lock(&g_intf_lock);
    499     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    500 
    501     if(my_obj) {
    502         pthread_mutex_lock(&my_obj->cam_lock);
    503         pthread_mutex_unlock(&g_intf_lock);
    504         rc = mm_camera_del_channel(my_obj, ch_id);
    505     } else {
    506         pthread_mutex_unlock(&g_intf_lock);
    507     }
    508     CDBG("%s :X", __func__);
    509     return rc;
    510 }
    511 
    512 /*===========================================================================
    513  * FUNCTION   : mm_camera_intf_get_bundle_info
    514  *
    515  * DESCRIPTION: query bundle info of the channel
    516  *
    517  * PARAMETERS :
    518  *   @camera_handle: camera handle
    519  *   @ch_id        : channel handle
    520  *   @bundle_info  : bundle info to be filled in
    521  *
    522  * RETURN     : int32_t type of status
    523  *              0  -- success
    524  *              -1 -- failure
    525  * NOTE       : all streams in the channel should be stopped already before
    526  *              this channel can be deleted.
    527  *==========================================================================*/
    528 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle,
    529                                               uint32_t ch_id,
    530                                               cam_bundle_config_t *bundle_info)
    531 {
    532     int32_t rc = -1;
    533     mm_camera_obj_t * my_obj = NULL;
    534 
    535     CDBG("%s :E ch_id = %d", __func__, ch_id);
    536     pthread_mutex_lock(&g_intf_lock);
    537     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    538 
    539     if(my_obj) {
    540         pthread_mutex_lock(&my_obj->cam_lock);
    541         pthread_mutex_unlock(&g_intf_lock);
    542         rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
    543     } else {
    544         pthread_mutex_unlock(&g_intf_lock);
    545     }
    546     CDBG("%s :X", __func__);
    547     return rc;
    548 }
    549 
    550 /*===========================================================================
    551  * FUNCTION   : mm_camera_intf_register_event_notify
    552  *
    553  * DESCRIPTION: register for event notify
    554  *
    555  * PARAMETERS :
    556  *   @camera_handle: camera handle
    557  *   @evt_cb       : callback for event notify
    558  *   @user_data    : user data ptr
    559  *
    560  * RETURN     : int32_t type of status
    561  *              0  -- success
    562  *              -1 -- failure
    563  *==========================================================================*/
    564 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle,
    565                                                     mm_camera_event_notify_t evt_cb,
    566                                                     void * user_data)
    567 {
    568     int32_t rc = -1;
    569     mm_camera_obj_t * my_obj = NULL;
    570 
    571     CDBG("%s :E ", __func__);
    572     pthread_mutex_lock(&g_intf_lock);
    573     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    574 
    575     if(my_obj) {
    576         pthread_mutex_lock(&my_obj->cam_lock);
    577         pthread_mutex_unlock(&g_intf_lock);
    578         rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
    579     } else {
    580         pthread_mutex_unlock(&g_intf_lock);
    581     }
    582     CDBG("%s :E rc = %d", __func__, rc);
    583     return rc;
    584 }
    585 
    586 /*===========================================================================
    587  * FUNCTION   : mm_camera_intf_qbuf
    588  *
    589  * DESCRIPTION: enqueue buffer back to kernel
    590  *
    591  * PARAMETERS :
    592  *   @camera_handle: camera handle
    593  *   @ch_id        : channel handle
    594  *   @buf          : buf ptr to be enqueued
    595  *
    596  * RETURN     : int32_t type of status
    597  *              0  -- success
    598  *              -1 -- failure
    599  *==========================================================================*/
    600 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle,
    601                                     uint32_t ch_id,
    602                                     mm_camera_buf_def_t *buf)
    603 {
    604     int32_t rc = -1;
    605     mm_camera_obj_t * my_obj = NULL;
    606 
    607     pthread_mutex_lock(&g_intf_lock);
    608     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    609 
    610     if(my_obj) {
    611         pthread_mutex_lock(&my_obj->cam_lock);
    612         pthread_mutex_unlock(&g_intf_lock);
    613         rc = mm_camera_qbuf(my_obj, ch_id, buf);
    614     } else {
    615         pthread_mutex_unlock(&g_intf_lock);
    616     }
    617     CDBG("%s :X evt_type = %d",__func__,rc);
    618     return rc;
    619 }
    620 
    621 /*===========================================================================
    622  * FUNCTION   : mm_camera_intf_get_queued_buf_count
    623  *
    624  * DESCRIPTION: returns the queued buffer count
    625  *
    626  * PARAMETERS :
    627  *   @camera_handle: camera handle
    628  *   @ch_id        : channel handle
    629  *   @stream_id : stream id
    630  *
    631  * RETURN     : int32_t - queued buffer count
    632  *
    633  *==========================================================================*/
    634 static int32_t mm_camera_intf_get_queued_buf_count(uint32_t camera_handle,
    635         uint32_t ch_id, uint32_t stream_id)
    636 {
    637     int32_t rc = -1;
    638     mm_camera_obj_t * my_obj = NULL;
    639 
    640     pthread_mutex_lock(&g_intf_lock);
    641     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    642 
    643     if(my_obj) {
    644         pthread_mutex_lock(&my_obj->cam_lock);
    645         pthread_mutex_unlock(&g_intf_lock);
    646         rc = mm_camera_get_queued_buf_count(my_obj, ch_id, stream_id);
    647     } else {
    648         pthread_mutex_unlock(&g_intf_lock);
    649     }
    650     CDBG("%s :X queued buffer count = %d",__func__,rc);
    651     return rc;
    652 }
    653 
    654 /*===========================================================================
    655  * FUNCTION   : mm_camera_intf_link_stream
    656  *
    657  * DESCRIPTION: link a stream into a new channel
    658  *
    659  * PARAMETERS :
    660  *   @camera_handle: camera handle
    661  *   @ch_id        : channel handle
    662  *   @stream_id    : stream id
    663  *   @linked_ch_id : channel in which the stream will be linked
    664  *
    665  * RETURN     : int32_t type of stream handle
    666  *              0  -- invalid stream handle, meaning the op failed
    667  *              >0 -- successfully linked a stream with a valid handle
    668  *==========================================================================*/
    669 static int32_t mm_camera_intf_link_stream(uint32_t camera_handle,
    670         uint32_t ch_id,
    671         uint32_t stream_id,
    672         uint32_t linked_ch_id)
    673 {
    674     uint32_t id = 0;
    675     mm_camera_obj_t * my_obj = NULL;
    676 
    677     CDBG("%s : E handle = %u ch_id = %u",
    678          __func__, camera_handle, ch_id);
    679 
    680     pthread_mutex_lock(&g_intf_lock);
    681     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    682 
    683     if(my_obj) {
    684         pthread_mutex_lock(&my_obj->cam_lock);
    685         pthread_mutex_unlock(&g_intf_lock);
    686         id = mm_camera_link_stream(my_obj, ch_id, stream_id, linked_ch_id);
    687     } else {
    688         pthread_mutex_unlock(&g_intf_lock);
    689     }
    690 
    691     CDBG("%s :X stream_id = %u", __func__, stream_id);
    692     return (int32_t)id;
    693 }
    694 
    695 /*===========================================================================
    696  * FUNCTION   : mm_camera_intf_add_stream
    697  *
    698  * DESCRIPTION: add a stream into a channel
    699  *
    700  * PARAMETERS :
    701  *   @camera_handle: camera handle
    702  *   @ch_id        : channel handle
    703  *
    704  * RETURN     : uint32_t type of stream handle
    705  *              0  -- invalid stream handle, meaning the op failed
    706  *              >0 -- successfully added a stream with a valid handle
    707  *==========================================================================*/
    708 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle,
    709                                           uint32_t ch_id)
    710 {
    711     uint32_t stream_id = 0;
    712     mm_camera_obj_t * my_obj = NULL;
    713 
    714     CDBG("%s : E handle = %d ch_id = %d",
    715          __func__, camera_handle, ch_id);
    716 
    717     pthread_mutex_lock(&g_intf_lock);
    718     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    719 
    720     if(my_obj) {
    721         pthread_mutex_lock(&my_obj->cam_lock);
    722         pthread_mutex_unlock(&g_intf_lock);
    723         stream_id = mm_camera_add_stream(my_obj, ch_id);
    724     } else {
    725         pthread_mutex_unlock(&g_intf_lock);
    726     }
    727     CDBG("%s :X stream_id = %d", __func__, stream_id);
    728     return stream_id;
    729 }
    730 
    731 /*===========================================================================
    732  * FUNCTION   : mm_camera_intf_del_stream
    733  *
    734  * DESCRIPTION: delete a stream by its handle
    735  *
    736  * PARAMETERS :
    737  *   @camera_handle: camera handle
    738  *   @ch_id        : channel handle
    739  *   @stream_id    : stream handle
    740  *
    741  * RETURN     : int32_t type of status
    742  *              0  -- success
    743  *              -1 -- failure
    744  * NOTE       : stream should be stopped already before it can be deleted.
    745  *==========================================================================*/
    746 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle,
    747                                          uint32_t ch_id,
    748                                          uint32_t stream_id)
    749 {
    750     int32_t rc = -1;
    751     mm_camera_obj_t * my_obj = NULL;
    752 
    753     CDBG("%s : E handle = %d ch_id = %d stream_id = %d",
    754          __func__, camera_handle, ch_id, stream_id);
    755 
    756     pthread_mutex_lock(&g_intf_lock);
    757     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    758 
    759     if(my_obj) {
    760         pthread_mutex_lock(&my_obj->cam_lock);
    761         pthread_mutex_unlock(&g_intf_lock);
    762         rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
    763     } else {
    764         pthread_mutex_unlock(&g_intf_lock);
    765     }
    766     CDBG("%s :X rc = %d", __func__, rc);
    767     return rc;
    768 }
    769 
    770 /*===========================================================================
    771  * FUNCTION   : mm_camera_intf_config_stream
    772  *
    773  * DESCRIPTION: configure a stream
    774  *
    775  * PARAMETERS :
    776  *   @camera_handle: camera handle
    777  *   @ch_id        : channel handle
    778  *   @stream_id    : stream handle
    779  *   @config       : stream configuration
    780  *
    781  * RETURN     : int32_t type of status
    782  *              0  -- success
    783  *              -1 -- failure
    784  *==========================================================================*/
    785 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle,
    786                                             uint32_t ch_id,
    787                                             uint32_t stream_id,
    788                                             mm_camera_stream_config_t *config)
    789 {
    790     int32_t rc = -1;
    791     mm_camera_obj_t * my_obj = NULL;
    792 
    793     CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",
    794          __func__, camera_handle, ch_id, stream_id);
    795 
    796     pthread_mutex_lock(&g_intf_lock);
    797     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    798 
    799     CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
    800 
    801     if(my_obj) {
    802         pthread_mutex_lock(&my_obj->cam_lock);
    803         pthread_mutex_unlock(&g_intf_lock);
    804         rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
    805     } else {
    806         pthread_mutex_unlock(&g_intf_lock);
    807     }
    808     CDBG("%s :X rc = %d", __func__, rc);
    809     return rc;
    810 }
    811 
    812 /*===========================================================================
    813  * FUNCTION   : mm_camera_intf_start_channel
    814  *
    815  * DESCRIPTION: start a channel, which will start all streams in the channel
    816  *
    817  * PARAMETERS :
    818  *   @camera_handle: camera handle
    819  *   @ch_id        : channel handle
    820  *
    821  * RETURN     : int32_t type of status
    822  *              0  -- success
    823  *              -1 -- failure
    824  *==========================================================================*/
    825 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle,
    826                                             uint32_t ch_id)
    827 {
    828     int32_t rc = -1;
    829     mm_camera_obj_t * my_obj = NULL;
    830 
    831     pthread_mutex_lock(&g_intf_lock);
    832     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    833 
    834     if(my_obj) {
    835         pthread_mutex_lock(&my_obj->cam_lock);
    836         pthread_mutex_unlock(&g_intf_lock);
    837         rc = mm_camera_start_channel(my_obj, ch_id);
    838     } else {
    839         pthread_mutex_unlock(&g_intf_lock);
    840     }
    841     CDBG("%s :X rc = %d", __func__, rc);
    842     return rc;
    843 }
    844 
    845 /*===========================================================================
    846  * FUNCTION   : mm_camera_intf_stop_channel
    847  *
    848  * DESCRIPTION: stop a channel, which will stop all streams in the channel
    849  *
    850  * PARAMETERS :
    851  *   @camera_handle: camera handle
    852  *   @ch_id        : channel handle
    853  *
    854  * RETURN     : int32_t type of status
    855  *              0  -- success
    856  *              -1 -- failure
    857  *==========================================================================*/
    858 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle,
    859                                            uint32_t ch_id)
    860 {
    861     int32_t rc = -1;
    862     mm_camera_obj_t * my_obj = NULL;
    863 
    864     pthread_mutex_lock(&g_intf_lock);
    865     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    866 
    867     if(my_obj) {
    868         pthread_mutex_lock(&my_obj->cam_lock);
    869         pthread_mutex_unlock(&g_intf_lock);
    870         rc = mm_camera_stop_channel(my_obj, ch_id);
    871     } else {
    872         pthread_mutex_unlock(&g_intf_lock);
    873     }
    874     CDBG("%s :X rc = %d", __func__, rc);
    875     return rc;
    876 }
    877 
    878 /*===========================================================================
    879  * FUNCTION   : mm_camera_intf_request_super_buf
    880  *
    881  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
    882  *              frames from superbuf queue
    883  *
    884  * PARAMETERS :
    885  *   @camera_handle: camera handle
    886  *   @ch_id        : channel handle
    887  *   @num_buf_requested : number of matched frames needed
    888  *
    889  * RETURN     : int32_t type of status
    890  *              0  -- success
    891  *              -1 -- failure
    892  *==========================================================================*/
    893 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle,
    894                                                 uint32_t ch_id,
    895                                                 uint32_t num_buf_requested,
    896                                                 uint32_t num_retro_buf_requested)
    897 {
    898     int32_t rc = -1;
    899     CDBG("%s :E camera_handler = %d,ch_id = %d",
    900          __func__, camera_handle, ch_id);
    901     mm_camera_obj_t * my_obj = NULL;
    902 
    903     pthread_mutex_lock(&g_intf_lock);
    904     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    905 
    906     if(my_obj) {
    907         pthread_mutex_lock(&my_obj->cam_lock);
    908         pthread_mutex_unlock(&g_intf_lock);
    909         rc = mm_camera_request_super_buf (my_obj, ch_id,
    910           num_buf_requested, num_retro_buf_requested);
    911     } else {
    912         pthread_mutex_unlock(&g_intf_lock);
    913     }
    914     CDBG("%s :X rc = %d", __func__, rc);
    915     return rc;
    916 }
    917 
    918 /*===========================================================================
    919  * FUNCTION   : mm_camera_intf_cancel_super_buf_request
    920  *
    921  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
    922  *              of matched frames from superbuf queue
    923  *
    924  * PARAMETERS :
    925  *   @camera_handle: camera handle
    926  *   @ch_id        : channel handle
    927  *
    928  * RETURN     : int32_t type of status
    929  *              0  -- success
    930  *              -1 -- failure
    931  *==========================================================================*/
    932 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,
    933                                                        uint32_t ch_id)
    934 {
    935     int32_t rc = -1;
    936     mm_camera_obj_t * my_obj = NULL;
    937 
    938     CDBG("%s :E camera_handler = %d,ch_id = %d",
    939          __func__, camera_handle, ch_id);
    940     pthread_mutex_lock(&g_intf_lock);
    941     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    942 
    943     if(my_obj) {
    944         pthread_mutex_lock(&my_obj->cam_lock);
    945         pthread_mutex_unlock(&g_intf_lock);
    946         rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
    947     } else {
    948         pthread_mutex_unlock(&g_intf_lock);
    949     }
    950     CDBG("%s :X rc = %d", __func__, rc);
    951     return rc;
    952 }
    953 
    954 /*===========================================================================
    955  * FUNCTION   : mm_camera_intf_flush_super_buf_queue
    956  *
    957  * DESCRIPTION: flush out all frames in the superbuf queue
    958  *
    959  * PARAMETERS :
    960  *   @camera_handle: camera handle
    961  *   @ch_id        : channel handle
    962  *   @frame_idx    : frame index
    963  *
    964  * RETURN     : int32_t type of status
    965  *              0  -- success
    966  *              -1 -- failure
    967  *==========================================================================*/
    968 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,
    969                                                     uint32_t ch_id, uint32_t frame_idx)
    970 {
    971     int32_t rc = -1;
    972     mm_camera_obj_t * my_obj = NULL;
    973 
    974     CDBG("%s :E camera_handler = %d,ch_id = %d",
    975          __func__, camera_handle, ch_id);
    976     pthread_mutex_lock(&g_intf_lock);
    977     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    978 
    979     if(my_obj) {
    980         pthread_mutex_lock(&my_obj->cam_lock);
    981         pthread_mutex_unlock(&g_intf_lock);
    982         rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
    983     } else {
    984         pthread_mutex_unlock(&g_intf_lock);
    985     }
    986     CDBG("%s :X rc = %d", __func__, rc);
    987     return rc;
    988 }
    989 
    990 /*===========================================================================
    991  * FUNCTION   : mm_camera_intf_start_zsl_snapshot
    992  *
    993  * DESCRIPTION: Starts zsl snapshot
    994  *
    995  * PARAMETERS :
    996  *   @camera_handle: camera handle
    997  *   @ch_id        : channel handle
    998  *
    999  * RETURN     : int32_t type of status
   1000  *              0  -- success
   1001  *              -1 -- failure
   1002  *==========================================================================*/
   1003 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle,
   1004         uint32_t ch_id)
   1005 {
   1006     int32_t rc = -1;
   1007     mm_camera_obj_t * my_obj = NULL;
   1008 
   1009     CDBG("%s :E camera_handler = %d,ch_id = %d",
   1010          __func__, camera_handle, ch_id);
   1011     pthread_mutex_lock(&g_intf_lock);
   1012     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1013 
   1014     if(my_obj) {
   1015         pthread_mutex_lock(&my_obj->cam_lock);
   1016         pthread_mutex_unlock(&g_intf_lock);
   1017         rc = mm_camera_start_zsl_snapshot_ch(my_obj, ch_id);
   1018     } else {
   1019         pthread_mutex_unlock(&g_intf_lock);
   1020     }
   1021     CDBG("%s :X rc = %d", __func__, rc);
   1022     return rc;
   1023 }
   1024 
   1025 /*===========================================================================
   1026  * FUNCTION   : mm_camera_intf_stop_zsl_snapshot
   1027  *
   1028  * DESCRIPTION: Stops zsl snapshot
   1029  *
   1030  * PARAMETERS :
   1031  *   @camera_handle: camera handle
   1032  *   @ch_id        : channel handle
   1033  *
   1034  * RETURN     : int32_t type of status
   1035  *              0  -- success
   1036  *              -1 -- failure
   1037  *==========================================================================*/
   1038 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle,
   1039         uint32_t ch_id)
   1040 {
   1041     int32_t rc = -1;
   1042     mm_camera_obj_t * my_obj = NULL;
   1043 
   1044     CDBG("%s :E camera_handler = %d,ch_id = %d",
   1045          __func__, camera_handle, ch_id);
   1046     pthread_mutex_lock(&g_intf_lock);
   1047     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1048 
   1049     if(my_obj) {
   1050         pthread_mutex_lock(&my_obj->cam_lock);
   1051         pthread_mutex_unlock(&g_intf_lock);
   1052         rc = mm_camera_stop_zsl_snapshot_ch(my_obj, ch_id);
   1053     } else {
   1054         pthread_mutex_unlock(&g_intf_lock);
   1055     }
   1056     CDBG("%s :X rc = %d", __func__, rc);
   1057     return rc;
   1058 }
   1059 
   1060 /*===========================================================================
   1061  * FUNCTION   : mm_camera_intf_configure_notify_mode
   1062  *
   1063  * DESCRIPTION: Configures channel notification mode
   1064  *
   1065  * PARAMETERS :
   1066  *   @camera_handle: camera handle
   1067  *   @ch_id        : channel handle
   1068  *   @notify_mode  : notification mode
   1069  *
   1070  * RETURN     : int32_t type of status
   1071  *              0  -- success
   1072  *              -1 -- failure
   1073  *==========================================================================*/
   1074 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle,
   1075                                                     uint32_t ch_id,
   1076                                                     mm_camera_super_buf_notify_mode_t notify_mode)
   1077 {
   1078     int32_t rc = -1;
   1079     mm_camera_obj_t * my_obj = NULL;
   1080 
   1081     CDBG("%s :E camera_handler = %d,ch_id = %d",
   1082          __func__, camera_handle, ch_id);
   1083     pthread_mutex_lock(&g_intf_lock);
   1084     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1085 
   1086     if(my_obj) {
   1087         pthread_mutex_lock(&my_obj->cam_lock);
   1088         pthread_mutex_unlock(&g_intf_lock);
   1089         rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
   1090     } else {
   1091         pthread_mutex_unlock(&g_intf_lock);
   1092     }
   1093     CDBG("%s :X rc = %d", __func__, rc);
   1094     return rc;
   1095 }
   1096 
   1097 /*===========================================================================
   1098  * FUNCTION   : mm_camera_intf_map_buf
   1099  *
   1100  * DESCRIPTION: mapping camera buffer via domain socket to server
   1101  *
   1102  * PARAMETERS :
   1103  *   @camera_handle: camera handle
   1104  *   @buf_type     : type of buffer to be mapped. could be following values:
   1105  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1106  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1107  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1108  *   @fd           : file descriptor of the buffer
   1109  *   @size         : size of the buffer
   1110  *
   1111  * RETURN     : int32_t type of status
   1112  *              0  -- success
   1113  *              -1 -- failure
   1114  *==========================================================================*/
   1115 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle,
   1116                                       uint8_t buf_type,
   1117                                       int fd,
   1118                                       size_t size)
   1119 {
   1120     int32_t rc = -1;
   1121     mm_camera_obj_t * my_obj = NULL;
   1122 
   1123     pthread_mutex_lock(&g_intf_lock);
   1124     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1125 
   1126     if(my_obj) {
   1127         pthread_mutex_lock(&my_obj->cam_lock);
   1128         pthread_mutex_unlock(&g_intf_lock);
   1129         rc = mm_camera_map_buf(my_obj, buf_type, fd, size);
   1130     } else {
   1131         pthread_mutex_unlock(&g_intf_lock);
   1132     }
   1133     return rc;
   1134 }
   1135 
   1136 /*===========================================================================
   1137  * FUNCTION   : mm_camera_intf_unmap_buf
   1138  *
   1139  * DESCRIPTION: unmapping camera buffer via domain socket to server
   1140  *
   1141  * PARAMETERS :
   1142  *   @camera_handle: camera handle
   1143  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1144  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1145  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1146  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1147  *
   1148  * RETURN     : int32_t type of status
   1149  *              0  -- success
   1150  *              -1 -- failure
   1151  *==========================================================================*/
   1152 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle,
   1153                                         uint8_t buf_type)
   1154 {
   1155     int32_t rc = -1;
   1156     mm_camera_obj_t * my_obj = NULL;
   1157 
   1158     pthread_mutex_lock(&g_intf_lock);
   1159     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1160 
   1161     if(my_obj) {
   1162         pthread_mutex_lock(&my_obj->cam_lock);
   1163         pthread_mutex_unlock(&g_intf_lock);
   1164         rc = mm_camera_unmap_buf(my_obj, buf_type);
   1165     } else {
   1166         pthread_mutex_unlock(&g_intf_lock);
   1167     }
   1168     return rc;
   1169 }
   1170 
   1171 /*===========================================================================
   1172  * FUNCTION   : mm_camera_intf_set_stream_parms
   1173  *
   1174  * DESCRIPTION: set parameters per stream
   1175  *
   1176  * PARAMETERS :
   1177  *   @camera_handle: camera handle
   1178  *   @ch_id        : channel handle
   1179  *   @s_id         : stream handle
   1180  *   @parms        : ptr to a param struct to be set to server
   1181  *
   1182  * RETURN     : int32_t type of status
   1183  *              0  -- success
   1184  *              -1 -- failure
   1185  * NOTE       : Assume the parms struct buf is already mapped to server via
   1186  *              domain socket. Corresponding fields of parameters to be set
   1187  *              are already filled in by upper layer caller.
   1188  *==========================================================================*/
   1189 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle,
   1190                                                uint32_t ch_id,
   1191                                                uint32_t s_id,
   1192                                                cam_stream_parm_buffer_t *parms)
   1193 {
   1194     int32_t rc = -1;
   1195     mm_camera_obj_t * my_obj = NULL;
   1196 
   1197     pthread_mutex_lock(&g_intf_lock);
   1198     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1199 
   1200     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
   1201          __func__, camera_handle, ch_id, s_id);
   1202 
   1203     if(my_obj) {
   1204         pthread_mutex_lock(&my_obj->cam_lock);
   1205         pthread_mutex_unlock(&g_intf_lock);
   1206         rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
   1207     }else{
   1208         pthread_mutex_unlock(&g_intf_lock);
   1209     }
   1210     CDBG("%s :X rc = %d", __func__, rc);
   1211     return rc;
   1212 }
   1213 
   1214 /*===========================================================================
   1215  * FUNCTION   : mm_camera_intf_get_stream_parms
   1216  *
   1217  * DESCRIPTION: get parameters per stream
   1218  *
   1219  * PARAMETERS :
   1220  *   @camera_handle: camera handle
   1221  *   @ch_id        : channel handle
   1222  *   @s_id         : stream handle
   1223  *   @parms        : ptr to a param struct to be get from server
   1224  *
   1225  * RETURN     : int32_t type of status
   1226  *              0  -- success
   1227  *              -1 -- failure
   1228  * NOTE       : Assume the parms struct buf is already mapped to server via
   1229  *              domain socket. Parameters to be get from server are already
   1230  *              filled in by upper layer caller. After this call, corresponding
   1231  *              fields of requested parameters will be filled in by server with
   1232  *              detailed information.
   1233  *==========================================================================*/
   1234 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle,
   1235                                                uint32_t ch_id,
   1236                                                uint32_t s_id,
   1237                                                cam_stream_parm_buffer_t *parms)
   1238 {
   1239     int32_t rc = -1;
   1240     mm_camera_obj_t * my_obj = NULL;
   1241 
   1242     pthread_mutex_lock(&g_intf_lock);
   1243     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1244 
   1245     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
   1246          __func__, camera_handle, ch_id, s_id);
   1247 
   1248     if(my_obj) {
   1249         pthread_mutex_lock(&my_obj->cam_lock);
   1250         pthread_mutex_unlock(&g_intf_lock);
   1251         rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
   1252     }else{
   1253         pthread_mutex_unlock(&g_intf_lock);
   1254     }
   1255 
   1256     CDBG("%s :X rc = %d", __func__, rc);
   1257     return rc;
   1258 }
   1259 
   1260 /*===========================================================================
   1261  * FUNCTION   : mm_camera_intf_map_stream_buf
   1262  *
   1263  * DESCRIPTION: mapping stream buffer via domain socket to server
   1264  *
   1265  * PARAMETERS :
   1266  *   @camera_handle: camera handle
   1267  *   @ch_id        : channel handle
   1268  *   @s_id         : stream handle
   1269  *   @buf_type     : type of buffer to be mapped. could be following values:
   1270  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1271  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1272  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1273  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1274  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1275  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1276  *   @plane_idx    : plane index. If all planes share the same fd,
   1277  *                   plane_idx = -1; otherwise, plean_idx is the
   1278  *                   index to plane (0..num_of_planes)
   1279  *   @fd           : file descriptor of the buffer
   1280  *   @size         : size of the buffer
   1281  *
   1282  * RETURN     : int32_t type of status
   1283  *              0  -- success
   1284  *              -1 -- failure
   1285  *==========================================================================*/
   1286 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle,
   1287                                              uint32_t ch_id,
   1288                                              uint32_t stream_id,
   1289                                              uint8_t buf_type,
   1290                                              uint32_t buf_idx,
   1291                                              int32_t plane_idx,
   1292                                              int fd,
   1293                                              size_t size)
   1294 {
   1295     int32_t rc = -1;
   1296     mm_camera_obj_t * my_obj = NULL;
   1297 
   1298     pthread_mutex_lock(&g_intf_lock);
   1299     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1300 
   1301     CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   1302          __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   1303 
   1304     if(my_obj) {
   1305         pthread_mutex_lock(&my_obj->cam_lock);
   1306         pthread_mutex_unlock(&g_intf_lock);
   1307         rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
   1308                                       buf_type, buf_idx, plane_idx,
   1309                                       fd, size);
   1310     }else{
   1311         pthread_mutex_unlock(&g_intf_lock);
   1312     }
   1313 
   1314     CDBG("%s :X rc = %d", __func__, rc);
   1315     return rc;
   1316 }
   1317 
   1318 /*===========================================================================
   1319  * FUNCTION   : mm_camera_intf_unmap_stream_buf
   1320  *
   1321  * DESCRIPTION: unmapping stream buffer via domain socket to server
   1322  *
   1323  * PARAMETERS :
   1324  *   @camera_handle: camera handle
   1325  *   @ch_id        : channel handle
   1326  *   @s_id         : stream handle
   1327  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1328  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1329  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1330  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1331  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1332  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1333  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1334  *   @plane_idx    : plane index. If all planes share the same fd,
   1335  *                   plane_idx = -1; otherwise, plean_idx is the
   1336  *                   index to plane (0..num_of_planes)
   1337  *
   1338  * RETURN     : int32_t type of status
   1339  *              0  -- success
   1340  *              -1 -- failure
   1341  *==========================================================================*/
   1342 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle,
   1343                                                uint32_t ch_id,
   1344                                                uint32_t stream_id,
   1345                                                uint8_t buf_type,
   1346                                                uint32_t buf_idx,
   1347                                                int32_t plane_idx)
   1348 {
   1349     int32_t rc = -1;
   1350     mm_camera_obj_t * my_obj = NULL;
   1351 
   1352     pthread_mutex_lock(&g_intf_lock);
   1353     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1354 
   1355     CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   1356          __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   1357 
   1358     if(my_obj) {
   1359         pthread_mutex_lock(&my_obj->cam_lock);
   1360         pthread_mutex_unlock(&g_intf_lock);
   1361         rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
   1362                                         buf_type, buf_idx, plane_idx);
   1363     }else{
   1364         pthread_mutex_unlock(&g_intf_lock);
   1365     }
   1366 
   1367     CDBG("%s :X rc = %d", __func__, rc);
   1368     return rc;
   1369 }
   1370 
   1371 /*===========================================================================
   1372  * FUNCTION   : get_sensor_info
   1373  *
   1374  * DESCRIPTION: get sensor info like facing(back/front) and mount angle
   1375  *
   1376  * PARAMETERS :
   1377  *
   1378  * RETURN     :
   1379  *==========================================================================*/
   1380 void get_sensor_info()
   1381 {
   1382     int rc = 0;
   1383     int dev_fd = -1;
   1384     struct media_device_info mdev_info;
   1385     int num_media_devices = 0;
   1386     size_t num_cameras = 0;
   1387 
   1388     CDBG("%s : E", __func__);
   1389     while (1) {
   1390         char dev_name[32];
   1391         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   1392         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   1393         if (dev_fd < 0) {
   1394             CDBG("Done discovering media devices\n");
   1395             break;
   1396         }
   1397         num_media_devices++;
   1398         memset(&mdev_info, 0, sizeof(mdev_info));
   1399         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   1400         if (rc < 0) {
   1401             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
   1402             close(dev_fd);
   1403             dev_fd = -1;
   1404             num_cameras = 0;
   1405             break;
   1406         }
   1407 
   1408         if(strncmp(mdev_info.model,  MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) {
   1409             close(dev_fd);
   1410             dev_fd = -1;
   1411             continue;
   1412         }
   1413 
   1414         unsigned int num_entities = 1;
   1415         while (1) {
   1416             struct media_entity_desc entity;
   1417             uint32_t temp;
   1418             uint32_t mount_angle;
   1419             uint32_t facing;
   1420 
   1421             memset(&entity, 0, sizeof(entity));
   1422             entity.id = num_entities++;
   1423             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   1424             if (rc < 0) {
   1425                 CDBG("Done enumerating media entities\n");
   1426                 rc = 0;
   1427                 break;
   1428             }
   1429             if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
   1430                 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) {
   1431                 temp = entity.flags >> 8;
   1432                 mount_angle = (temp & 0xFF) * 90;
   1433                 facing = (temp >> 8);
   1434                 ALOGD("index = %u flag = %x mount_angle = %u facing = %u\n",
   1435                     (unsigned int)num_cameras, (unsigned int)temp,
   1436                     (unsigned int)mount_angle, (unsigned int)facing);
   1437                 g_cam_ctrl.info[num_cameras].facing = (int)facing;
   1438                 g_cam_ctrl.info[num_cameras].orientation = (int)mount_angle;
   1439                 num_cameras++;
   1440                 continue;
   1441             }
   1442         }
   1443 
   1444         CDBG("%s: dev_info[id=%zu,name='%s']\n",
   1445             __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
   1446 
   1447         close(dev_fd);
   1448         dev_fd = -1;
   1449     }
   1450 
   1451     CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
   1452     return;
   1453 }
   1454 
   1455 /*===========================================================================
   1456  * FUNCTION   : sort_camera_info
   1457  *
   1458  * DESCRIPTION: sort camera info to keep back cameras idx is smaller than front cameras idx
   1459  *
   1460  * PARAMETERS : number of cameras
   1461  *
   1462  * RETURN     :
   1463  *==========================================================================*/
   1464 void sort_camera_info(int num_cam)
   1465 {
   1466     int idx = 0, i;
   1467     struct camera_info temp_info[MM_CAMERA_MAX_NUM_SENSORS];
   1468     char temp_dev_name[MM_CAMERA_MAX_NUM_SENSORS][MM_CAMERA_DEV_NAME_LEN];
   1469     memset(temp_info, 0, sizeof(temp_info));
   1470     memset(temp_dev_name, 0, sizeof(temp_dev_name));
   1471 
   1472     /* firstly save the back cameras info*/
   1473     for (i = 0; i < num_cam; i++) {
   1474         if (g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) {
   1475             temp_info[idx] = g_cam_ctrl.info[i];
   1476             memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
   1477                 MM_CAMERA_DEV_NAME_LEN);
   1478         }
   1479     }
   1480 
   1481     /* then save the front cameras info*/
   1482     for (i = 0; i < num_cam; i++) {
   1483         if (g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) {
   1484             temp_info[idx] = g_cam_ctrl.info[i];
   1485             memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
   1486                 MM_CAMERA_DEV_NAME_LEN);
   1487         }
   1488     }
   1489 
   1490     if (idx == num_cam) {
   1491         memcpy(g_cam_ctrl.info, temp_info, sizeof(temp_info));
   1492         memcpy(g_cam_ctrl.video_dev_name, temp_dev_name, sizeof(temp_dev_name));
   1493     } else {
   1494         ALOGE("%s: Failed to sort all cameras!", __func__);
   1495         ALOGE("%s: Number of cameras %d sorted %d", __func__, num_cam, idx);
   1496     }
   1497     return;
   1498 }
   1499 
   1500 /*===========================================================================
   1501  * FUNCTION   : get_num_of_cameras
   1502  *
   1503  * DESCRIPTION: get number of cameras
   1504  *
   1505  * PARAMETERS :
   1506  *
   1507  * RETURN     : number of cameras supported
   1508  *==========================================================================*/
   1509 uint8_t get_num_of_cameras()
   1510 {
   1511     int rc = 0;
   1512     int dev_fd = -1;
   1513     struct media_device_info mdev_info;
   1514     int num_media_devices = 0;
   1515     int8_t num_cameras = 0;
   1516     char subdev_name[32];
   1517     int32_t sd_fd = -1;
   1518     struct sensor_init_cfg_data cfg;
   1519     char prop[PROPERTY_VALUE_MAX];
   1520     uint32_t globalLogLevel = 0;
   1521 
   1522     property_get("persist.camera.hal.debug", prop, "0");
   1523     int val = atoi(prop);
   1524     if (0 <= val) {
   1525         gMmCameraIntfLogLevel = (uint32_t)val;
   1526     }
   1527     property_get("persist.camera.global.debug", prop, "0");
   1528     val = atoi(prop);
   1529     if (0 <= val) {
   1530         globalLogLevel = (uint32_t)val;
   1531     }
   1532 
   1533     /* Highest log level among hal.logs and global.logs is selected */
   1534     if (gMmCameraIntfLogLevel < globalLogLevel)
   1535         gMmCameraIntfLogLevel = globalLogLevel;
   1536 
   1537     CDBG("%s : E", __func__);
   1538 
   1539     property_get("vold.decrypt", prop, "0");
   1540     int decrypt = atoi(prop);
   1541     if (decrypt == 1)
   1542      return 0;
   1543 
   1544     /* lock the mutex */
   1545     pthread_mutex_lock(&g_intf_lock);
   1546 
   1547     while (1) {
   1548         uint32_t num_entities = 1U;
   1549         char dev_name[32];
   1550 
   1551         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   1552         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   1553         if (dev_fd < 0) {
   1554             CDBG("Done discovering media devices\n");
   1555             break;
   1556         }
   1557         num_media_devices++;
   1558         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   1559         if (rc < 0) {
   1560             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
   1561             close(dev_fd);
   1562             dev_fd = -1;
   1563             break;
   1564         }
   1565 
   1566         if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME,
   1567           sizeof(mdev_info.model)) != 0) {
   1568             close(dev_fd);
   1569             dev_fd = -1;
   1570             continue;
   1571         }
   1572 
   1573         while (1) {
   1574             struct media_entity_desc entity;
   1575             memset(&entity, 0, sizeof(entity));
   1576             entity.id = num_entities++;
   1577             CDBG("entity id %d", entity.id);
   1578             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   1579             if (rc < 0) {
   1580                 CDBG("Done enumerating media entities");
   1581                 rc = 0;
   1582                 break;
   1583             }
   1584             CDBG("entity name %s type %d group id %d",
   1585                 entity.name, entity.type, entity.group_id);
   1586             if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
   1587                 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) {
   1588                 snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name);
   1589                 break;
   1590             }
   1591         }
   1592         close(dev_fd);
   1593         dev_fd = -1;
   1594     }
   1595 
   1596     /* Open sensor_init subdev */
   1597     sd_fd = open(subdev_name, O_RDWR);
   1598     if (sd_fd < 0) {
   1599         CDBG_ERROR("Open sensor_init subdev failed");
   1600         return FALSE;
   1601     }
   1602 
   1603     cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE;
   1604     cfg.cfg.setting = NULL;
   1605     if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
   1606         CDBG_ERROR("failed");
   1607     }
   1608     close(sd_fd);
   1609     dev_fd = -1;
   1610 
   1611 
   1612     num_media_devices = 0;
   1613     while (1) {
   1614         uint32_t num_entities = 1U;
   1615         char dev_name[32];
   1616 
   1617         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   1618         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   1619         if (dev_fd < 0) {
   1620             CDBG("Done discovering media devices: %s\n", strerror(errno));
   1621             break;
   1622         }
   1623         num_media_devices++;
   1624         memset(&mdev_info, 0, sizeof(mdev_info));
   1625         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   1626         if (rc < 0) {
   1627             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
   1628             close(dev_fd);
   1629             dev_fd = -1;
   1630             num_cameras = 0;
   1631             break;
   1632         }
   1633 
   1634         if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) {
   1635             close(dev_fd);
   1636             dev_fd = -1;
   1637             continue;
   1638         }
   1639 
   1640         while (1) {
   1641             struct media_entity_desc entity;
   1642             memset(&entity, 0, sizeof(entity));
   1643             entity.id = num_entities++;
   1644             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   1645             if (rc < 0) {
   1646                 CDBG("Done enumerating media entities\n");
   1647                 rc = 0;
   1648                 break;
   1649             }
   1650             if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
   1651                 strlcpy(g_cam_ctrl.video_dev_name[num_cameras],
   1652                      entity.name, sizeof(entity.name));
   1653                 break;
   1654             }
   1655         }
   1656 
   1657         CDBG("%s: dev_info[id=%d,name='%s']\n",
   1658             __func__, (int)num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
   1659 
   1660         num_cameras++;
   1661         close(dev_fd);
   1662         dev_fd = -1;
   1663     }
   1664     g_cam_ctrl.num_cam = num_cameras;
   1665 
   1666     get_sensor_info();
   1667     sort_camera_info(g_cam_ctrl.num_cam);
   1668     /* unlock the mutex */
   1669     pthread_mutex_unlock(&g_intf_lock);
   1670     CDBG("%s: num_cameras=%d\n", __func__, (int)g_cam_ctrl.num_cam);
   1671     return(uint8_t)g_cam_ctrl.num_cam;
   1672 }
   1673 
   1674 /*===========================================================================
   1675  * FUNCTION   : mm_camera_intf_process_advanced_capture
   1676  *
   1677  * DESCRIPTION: Configures channel advanced capture mode
   1678  *
   1679  * PARAMETERS :
   1680  *   @camera_handle: camera handle
   1681  *   @type : advanced capture type
   1682  *   @ch_id        : channel handle
   1683  *   @trigger  : 1 for start and 0 for cancel/stop
   1684  *   @value  : input capture configaration
   1685  *
   1686  * RETURN     : int32_t type of status
   1687  *              0  -- success
   1688  *              -1 -- failure
   1689  *==========================================================================*/
   1690 static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle,
   1691         uint32_t ch_id, mm_camera_advanced_capture_t type,
   1692         int8_t trigger, void *in_value)
   1693 {
   1694     int32_t rc = -1;
   1695     mm_camera_obj_t * my_obj = NULL;
   1696 
   1697     CDBG("%s: E camera_handler = %d,ch_id = %d",
   1698          __func__, camera_handle, ch_id);
   1699     pthread_mutex_lock(&g_intf_lock);
   1700     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1701 
   1702     if(my_obj) {
   1703         pthread_mutex_lock(&my_obj->cam_lock);
   1704         pthread_mutex_unlock(&g_intf_lock);
   1705         rc = mm_camera_channel_advanced_capture(my_obj, ch_id, type,
   1706                 (uint32_t)trigger, in_value);
   1707     } else {
   1708         pthread_mutex_unlock(&g_intf_lock);
   1709     }
   1710     CDBG("%s: X ", __func__);
   1711     return rc;
   1712 }
   1713 
   1714 struct camera_info *get_cam_info(uint32_t camera_id)
   1715 {
   1716     return &g_cam_ctrl.info[camera_id];
   1717 }
   1718 
   1719 /* camera ops v-table */
   1720 static mm_camera_ops_t mm_camera_ops = {
   1721     .query_capability = mm_camera_intf_query_capability,
   1722     .register_event_notify = mm_camera_intf_register_event_notify,
   1723     .close_camera = mm_camera_intf_close,
   1724     .error_close_camera = mm_camera_intf_error_close,
   1725     .set_parms = mm_camera_intf_set_parms,
   1726     .get_parms = mm_camera_intf_get_parms,
   1727     .do_auto_focus = mm_camera_intf_do_auto_focus,
   1728     .cancel_auto_focus = mm_camera_intf_cancel_auto_focus,
   1729     .prepare_snapshot = mm_camera_intf_prepare_snapshot,
   1730     .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,
   1731     .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,
   1732     .map_buf = mm_camera_intf_map_buf,
   1733     .unmap_buf = mm_camera_intf_unmap_buf,
   1734     .add_channel = mm_camera_intf_add_channel,
   1735     .delete_channel = mm_camera_intf_del_channel,
   1736     .get_bundle_info = mm_camera_intf_get_bundle_info,
   1737     .add_stream = mm_camera_intf_add_stream,
   1738     .link_stream = mm_camera_intf_link_stream,
   1739     .delete_stream = mm_camera_intf_del_stream,
   1740     .config_stream = mm_camera_intf_config_stream,
   1741     .qbuf = mm_camera_intf_qbuf,
   1742     .get_queued_buf_count = mm_camera_intf_get_queued_buf_count,
   1743     .map_stream_buf = mm_camera_intf_map_stream_buf,
   1744     .unmap_stream_buf = mm_camera_intf_unmap_stream_buf,
   1745     .set_stream_parms = mm_camera_intf_set_stream_parms,
   1746     .get_stream_parms = mm_camera_intf_get_stream_parms,
   1747     .start_channel = mm_camera_intf_start_channel,
   1748     .stop_channel = mm_camera_intf_stop_channel,
   1749     .request_super_buf = mm_camera_intf_request_super_buf,
   1750     .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
   1751     .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,
   1752     .configure_notify_mode = mm_camera_intf_configure_notify_mode,
   1753     .process_advanced_capture = mm_camera_intf_process_advanced_capture
   1754 };
   1755 
   1756 /*===========================================================================
   1757  * FUNCTION   : camera_open
   1758  *
   1759  * DESCRIPTION: open a camera by camera index
   1760  *
   1761  * PARAMETERS :
   1762  *   @camera_idx  : camera index. should within range of 0 to num_of_cameras
   1763  *   @camera_vtbl : ptr to a virtual table containing camera handle and operation table.
   1764  *
   1765  * RETURN     : int32_t type of status
   1766  *              0  -- success
   1767  *              non-zero error code -- failure
   1768  *==========================================================================*/
   1769 int32_t camera_open(uint8_t camera_idx, mm_camera_vtbl_t **camera_vtbl)
   1770 {
   1771     int32_t rc = 0;
   1772     mm_camera_obj_t *cam_obj = NULL;
   1773 
   1774     CDBG("%s: E camera_idx = %d\n", __func__, camera_idx);
   1775     if (camera_idx >= g_cam_ctrl.num_cam) {
   1776         CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
   1777         return -EINVAL;
   1778     }
   1779 
   1780     pthread_mutex_lock(&g_intf_lock);
   1781     /* opened already */
   1782     if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
   1783         /* Add reference */
   1784         g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
   1785         pthread_mutex_unlock(&g_intf_lock);
   1786         CDBG("%s:  opened alreadyn", __func__);
   1787         *camera_vtbl = &g_cam_ctrl.cam_obj[camera_idx]->vtbl;
   1788         return rc;
   1789     }
   1790 
   1791     cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
   1792     if(NULL == cam_obj) {
   1793         pthread_mutex_unlock(&g_intf_lock);
   1794         CDBG_ERROR("%s:  no mem", __func__);
   1795         return -EINVAL;
   1796     }
   1797 
   1798     /* initialize camera obj */
   1799     memset(cam_obj, 0, sizeof(mm_camera_obj_t));
   1800     cam_obj->ctrl_fd = -1;
   1801     cam_obj->ds_fd = -1;
   1802     cam_obj->ref_count++;
   1803     cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
   1804     cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
   1805     cam_obj->vtbl.ops = &mm_camera_ops;
   1806     pthread_mutex_init(&cam_obj->cam_lock, NULL);
   1807     /* unlock global interface lock, if not, in dual camera use case,
   1808       * current open will block operation of another opened camera obj*/
   1809     pthread_mutex_lock(&cam_obj->cam_lock);
   1810     pthread_mutex_unlock(&g_intf_lock);
   1811 
   1812     rc = mm_camera_open(cam_obj);
   1813 
   1814     pthread_mutex_lock(&g_intf_lock);
   1815     if (rc != 0) {
   1816         CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
   1817         pthread_mutex_destroy(&cam_obj->cam_lock);
   1818         g_cam_ctrl.cam_obj[camera_idx] = NULL;
   1819         free(cam_obj);
   1820         cam_obj = NULL;
   1821         pthread_mutex_unlock(&g_intf_lock);
   1822         *camera_vtbl = NULL;
   1823         return rc;
   1824     } else {
   1825         CDBG("%s: Open succeded\n", __func__);
   1826         g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
   1827         pthread_mutex_unlock(&g_intf_lock);
   1828         *camera_vtbl = &cam_obj->vtbl;
   1829         return 0;
   1830     }
   1831 }
   1832