Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2014, 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     mm_camera_obj_t * my_obj = NULL;
    406 
    407     CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
    408 
    409     pthread_mutex_lock(&g_intf_lock);
    410     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    411 
    412     if (my_obj){
    413         /*do not decrement the ref_count yet since that will happen during close*/
    414         if((my_obj->ref_count - 1) > 0) {
    415             /* still have reference to obj, return here */
    416             CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
    417             pthread_mutex_unlock(&g_intf_lock);
    418             rc = 0;
    419         } else {
    420             /* need close camera here as no other reference*/
    421             pthread_mutex_lock(&my_obj->cam_lock);
    422             pthread_mutex_unlock(&g_intf_lock);
    423 
    424             rc = mm_camera_close_fd(my_obj);
    425         }
    426     } else {
    427         pthread_mutex_unlock(&g_intf_lock);
    428     }
    429 
    430     return rc;
    431 }
    432 
    433 /*===========================================================================
    434  * FUNCTION   : mm_camera_intf_add_channel
    435  *
    436  * DESCRIPTION: add a channel
    437  *
    438  * PARAMETERS :
    439  *   @camera_handle: camera handle
    440  *   @attr         : bundle attribute of the channel if needed
    441  *   @channel_cb   : callback function for bundle data notify
    442  *   @userdata     : user data ptr
    443  *
    444  * RETURN     : uint32_t type of channel handle
    445  *              0  -- invalid channel handle, meaning the op failed
    446  *              >0 -- successfully added a channel with a valid handle
    447  * NOTE       : if no bundle data notify is needed, meaning each stream in the
    448  *              channel will have its own stream data notify callback, then
    449  *              attr, channel_cb, and userdata can be NULL. In this case,
    450  *              no matching logic will be performed in channel for the bundling.
    451  *==========================================================================*/
    452 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle,
    453                                            mm_camera_channel_attr_t *attr,
    454                                            mm_camera_buf_notify_t channel_cb,
    455                                            void *userdata)
    456 {
    457     uint32_t ch_id = 0;
    458     mm_camera_obj_t * my_obj = NULL;
    459 
    460     CDBG("%s :E camera_handler = %d", __func__, camera_handle);
    461     pthread_mutex_lock(&g_intf_lock);
    462     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    463 
    464     if(my_obj) {
    465         pthread_mutex_lock(&my_obj->cam_lock);
    466         pthread_mutex_unlock(&g_intf_lock);
    467         ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
    468     } else {
    469         pthread_mutex_unlock(&g_intf_lock);
    470     }
    471     CDBG("%s :X ch_id = %d", __func__, ch_id);
    472     return ch_id;
    473 }
    474 
    475 /*===========================================================================
    476  * FUNCTION   : mm_camera_intf_del_channel
    477  *
    478  * DESCRIPTION: delete a channel by its handle
    479  *
    480  * PARAMETERS :
    481  *   @camera_handle: camera handle
    482  *   @ch_id        : channel handle
    483  *
    484  * RETURN     : int32_t type of status
    485  *              0  -- success
    486  *              -1 -- failure
    487  * NOTE       : all streams in the channel should be stopped already before
    488  *              this channel can be deleted.
    489  *==========================================================================*/
    490 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle,
    491                                           uint32_t ch_id)
    492 {
    493     int32_t rc = -1;
    494     mm_camera_obj_t * my_obj = NULL;
    495 
    496     CDBG("%s :E ch_id = %d", __func__, ch_id);
    497     pthread_mutex_lock(&g_intf_lock);
    498     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    499 
    500     if(my_obj) {
    501         pthread_mutex_lock(&my_obj->cam_lock);
    502         pthread_mutex_unlock(&g_intf_lock);
    503         rc = mm_camera_del_channel(my_obj, ch_id);
    504     } else {
    505         pthread_mutex_unlock(&g_intf_lock);
    506     }
    507     CDBG("%s :X", __func__);
    508     return rc;
    509 }
    510 
    511 /*===========================================================================
    512  * FUNCTION   : mm_camera_intf_get_bundle_info
    513  *
    514  * DESCRIPTION: query bundle info of the channel
    515  *
    516  * PARAMETERS :
    517  *   @camera_handle: camera handle
    518  *   @ch_id        : channel handle
    519  *   @bundle_info  : bundle info to be filled in
    520  *
    521  * RETURN     : int32_t type of status
    522  *              0  -- success
    523  *              -1 -- failure
    524  * NOTE       : all streams in the channel should be stopped already before
    525  *              this channel can be deleted.
    526  *==========================================================================*/
    527 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle,
    528                                               uint32_t ch_id,
    529                                               cam_bundle_config_t *bundle_info)
    530 {
    531     int32_t rc = -1;
    532     mm_camera_obj_t * my_obj = NULL;
    533 
    534     CDBG("%s :E ch_id = %d", __func__, ch_id);
    535     pthread_mutex_lock(&g_intf_lock);
    536     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    537 
    538     if(my_obj) {
    539         pthread_mutex_lock(&my_obj->cam_lock);
    540         pthread_mutex_unlock(&g_intf_lock);
    541         rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
    542     } else {
    543         pthread_mutex_unlock(&g_intf_lock);
    544     }
    545     CDBG("%s :X", __func__);
    546     return rc;
    547 }
    548 
    549 /*===========================================================================
    550  * FUNCTION   : mm_camera_intf_register_event_notify
    551  *
    552  * DESCRIPTION: register for event notify
    553  *
    554  * PARAMETERS :
    555  *   @camera_handle: camera handle
    556  *   @evt_cb       : callback for event notify
    557  *   @user_data    : user data ptr
    558  *
    559  * RETURN     : int32_t type of status
    560  *              0  -- success
    561  *              -1 -- failure
    562  *==========================================================================*/
    563 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle,
    564                                                     mm_camera_event_notify_t evt_cb,
    565                                                     void * user_data)
    566 {
    567     int32_t rc = -1;
    568     mm_camera_obj_t * my_obj = NULL;
    569 
    570     CDBG("%s :E ", __func__);
    571     pthread_mutex_lock(&g_intf_lock);
    572     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    573 
    574     if(my_obj) {
    575         pthread_mutex_lock(&my_obj->cam_lock);
    576         pthread_mutex_unlock(&g_intf_lock);
    577         rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
    578     } else {
    579         pthread_mutex_unlock(&g_intf_lock);
    580     }
    581     CDBG("%s :E rc = %d", __func__, rc);
    582     return rc;
    583 }
    584 
    585 /*===========================================================================
    586  * FUNCTION   : mm_camera_intf_qbuf
    587  *
    588  * DESCRIPTION: enqueue buffer back to kernel
    589  *
    590  * PARAMETERS :
    591  *   @camera_handle: camera handle
    592  *   @ch_id        : channel handle
    593  *   @buf          : buf ptr to be enqueued
    594  *
    595  * RETURN     : int32_t type of status
    596  *              0  -- success
    597  *              -1 -- failure
    598  *==========================================================================*/
    599 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle,
    600                                     uint32_t ch_id,
    601                                     mm_camera_buf_def_t *buf)
    602 {
    603     int32_t rc = -1;
    604     mm_camera_obj_t * my_obj = NULL;
    605 
    606     pthread_mutex_lock(&g_intf_lock);
    607     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    608 
    609     if(my_obj) {
    610         pthread_mutex_lock(&my_obj->cam_lock);
    611         pthread_mutex_unlock(&g_intf_lock);
    612         rc = mm_camera_qbuf(my_obj, ch_id, buf);
    613     } else {
    614         pthread_mutex_unlock(&g_intf_lock);
    615     }
    616     CDBG("%s :X evt_type = %d",__func__,rc);
    617     return rc;
    618 }
    619 
    620 /*===========================================================================
    621  * FUNCTION   : mm_camera_intf_add_stream
    622  *
    623  * DESCRIPTION: add a stream into a channel
    624  *
    625  * PARAMETERS :
    626  *   @camera_handle: camera handle
    627  *   @ch_id        : channel handle
    628  *
    629  * RETURN     : uint32_t type of stream handle
    630  *              0  -- invalid stream handle, meaning the op failed
    631  *              >0 -- successfully added a stream with a valid handle
    632  *==========================================================================*/
    633 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle,
    634                                           uint32_t ch_id)
    635 {
    636     uint32_t stream_id = 0;
    637     mm_camera_obj_t * my_obj = NULL;
    638 
    639     CDBG("%s : E handle = %d ch_id = %d",
    640          __func__, camera_handle, ch_id);
    641 
    642     pthread_mutex_lock(&g_intf_lock);
    643     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    644 
    645     if(my_obj) {
    646         pthread_mutex_lock(&my_obj->cam_lock);
    647         pthread_mutex_unlock(&g_intf_lock);
    648         stream_id = mm_camera_add_stream(my_obj, ch_id);
    649     } else {
    650         pthread_mutex_unlock(&g_intf_lock);
    651     }
    652     CDBG("%s :X stream_id = %d", __func__, stream_id);
    653     return stream_id;
    654 }
    655 
    656 /*===========================================================================
    657  * FUNCTION   : mm_camera_intf_del_stream
    658  *
    659  * DESCRIPTION: delete a stream by its handle
    660  *
    661  * PARAMETERS :
    662  *   @camera_handle: camera handle
    663  *   @ch_id        : channel handle
    664  *   @stream_id    : stream handle
    665  *
    666  * RETURN     : int32_t type of status
    667  *              0  -- success
    668  *              -1 -- failure
    669  * NOTE       : stream should be stopped already before it can be deleted.
    670  *==========================================================================*/
    671 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle,
    672                                          uint32_t ch_id,
    673                                          uint32_t stream_id)
    674 {
    675     int32_t rc = -1;
    676     mm_camera_obj_t * my_obj = NULL;
    677 
    678     CDBG("%s : E handle = %d ch_id = %d stream_id = %d",
    679          __func__, camera_handle, ch_id, stream_id);
    680 
    681     pthread_mutex_lock(&g_intf_lock);
    682     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    683 
    684     if(my_obj) {
    685         pthread_mutex_lock(&my_obj->cam_lock);
    686         pthread_mutex_unlock(&g_intf_lock);
    687         rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
    688     } else {
    689         pthread_mutex_unlock(&g_intf_lock);
    690     }
    691     CDBG("%s :X rc = %d", __func__, rc);
    692     return rc;
    693 }
    694 
    695 /*===========================================================================
    696  * FUNCTION   : mm_camera_intf_config_stream
    697  *
    698  * DESCRIPTION: configure a stream
    699  *
    700  * PARAMETERS :
    701  *   @camera_handle: camera handle
    702  *   @ch_id        : channel handle
    703  *   @stream_id    : stream handle
    704  *   @config       : stream configuration
    705  *
    706  * RETURN     : int32_t type of status
    707  *              0  -- success
    708  *              -1 -- failure
    709  *==========================================================================*/
    710 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle,
    711                                             uint32_t ch_id,
    712                                             uint32_t stream_id,
    713                                             mm_camera_stream_config_t *config)
    714 {
    715     int32_t rc = -1;
    716     mm_camera_obj_t * my_obj = NULL;
    717 
    718     CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",
    719          __func__, camera_handle, ch_id, stream_id);
    720 
    721     pthread_mutex_lock(&g_intf_lock);
    722     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    723 
    724     CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
    725 
    726     if(my_obj) {
    727         pthread_mutex_lock(&my_obj->cam_lock);
    728         pthread_mutex_unlock(&g_intf_lock);
    729         rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
    730     } else {
    731         pthread_mutex_unlock(&g_intf_lock);
    732     }
    733     CDBG("%s :X rc = %d", __func__, rc);
    734     return rc;
    735 }
    736 
    737 /*===========================================================================
    738  * FUNCTION   : mm_camera_intf_start_channel
    739  *
    740  * DESCRIPTION: start a channel, which will start all streams in the channel
    741  *
    742  * PARAMETERS :
    743  *   @camera_handle: camera handle
    744  *   @ch_id        : channel handle
    745  *
    746  * RETURN     : int32_t type of status
    747  *              0  -- success
    748  *              -1 -- failure
    749  *==========================================================================*/
    750 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle,
    751                                             uint32_t ch_id)
    752 {
    753     int32_t rc = -1;
    754     mm_camera_obj_t * my_obj = NULL;
    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_start_channel(my_obj, ch_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_stop_channel
    772  *
    773  * DESCRIPTION: stop a channel, which will stop all streams in the channel
    774  *
    775  * PARAMETERS :
    776  *   @camera_handle: camera handle
    777  *   @ch_id        : channel handle
    778  *
    779  * RETURN     : int32_t type of status
    780  *              0  -- success
    781  *              -1 -- failure
    782  *==========================================================================*/
    783 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle,
    784                                            uint32_t ch_id)
    785 {
    786     int32_t rc = -1;
    787     mm_camera_obj_t * my_obj = NULL;
    788 
    789     pthread_mutex_lock(&g_intf_lock);
    790     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    791 
    792     if(my_obj) {
    793         pthread_mutex_lock(&my_obj->cam_lock);
    794         pthread_mutex_unlock(&g_intf_lock);
    795         rc = mm_camera_stop_channel(my_obj, ch_id);
    796     } else {
    797         pthread_mutex_unlock(&g_intf_lock);
    798     }
    799     CDBG("%s :X rc = %d", __func__, rc);
    800     return rc;
    801 }
    802 
    803 /*===========================================================================
    804  * FUNCTION   : mm_camera_intf_request_super_buf
    805  *
    806  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
    807  *              frames from superbuf queue
    808  *
    809  * PARAMETERS :
    810  *   @camera_handle: camera handle
    811  *   @ch_id        : channel handle
    812  *   @num_buf_requested : number of matched frames needed
    813  *
    814  * RETURN     : int32_t type of status
    815  *              0  -- success
    816  *              -1 -- failure
    817  *==========================================================================*/
    818 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle,
    819                                                 uint32_t ch_id,
    820                                                 uint32_t num_buf_requested,
    821                                                 uint32_t num_retro_buf_requested)
    822 {
    823     int32_t rc = -1;
    824     CDBG("%s :E camera_handler = %d,ch_id = %d",
    825          __func__, camera_handle, ch_id);
    826     mm_camera_obj_t * my_obj = NULL;
    827 
    828     pthread_mutex_lock(&g_intf_lock);
    829     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    830 
    831     if(my_obj) {
    832         pthread_mutex_lock(&my_obj->cam_lock);
    833         pthread_mutex_unlock(&g_intf_lock);
    834         rc = mm_camera_request_super_buf (my_obj, ch_id,
    835           num_buf_requested, num_retro_buf_requested);
    836     } else {
    837         pthread_mutex_unlock(&g_intf_lock);
    838     }
    839     CDBG("%s :X rc = %d", __func__, rc);
    840     return rc;
    841 }
    842 
    843 /*===========================================================================
    844  * FUNCTION   : mm_camera_intf_cancel_super_buf_request
    845  *
    846  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
    847  *              of matched frames from superbuf queue
    848  *
    849  * PARAMETERS :
    850  *   @camera_handle: camera handle
    851  *   @ch_id        : channel handle
    852  *
    853  * RETURN     : int32_t type of status
    854  *              0  -- success
    855  *              -1 -- failure
    856  *==========================================================================*/
    857 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,
    858                                                        uint32_t ch_id)
    859 {
    860     int32_t rc = -1;
    861     mm_camera_obj_t * my_obj = NULL;
    862 
    863     CDBG("%s :E camera_handler = %d,ch_id = %d",
    864          __func__, camera_handle, ch_id);
    865     pthread_mutex_lock(&g_intf_lock);
    866     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    867 
    868     if(my_obj) {
    869         pthread_mutex_lock(&my_obj->cam_lock);
    870         pthread_mutex_unlock(&g_intf_lock);
    871         rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
    872     } else {
    873         pthread_mutex_unlock(&g_intf_lock);
    874     }
    875     CDBG("%s :X rc = %d", __func__, rc);
    876     return rc;
    877 }
    878 
    879 /*===========================================================================
    880  * FUNCTION   : mm_camera_intf_flush_super_buf_queue
    881  *
    882  * DESCRIPTION: flush out all frames in the superbuf queue
    883  *
    884  * PARAMETERS :
    885  *   @camera_handle: camera handle
    886  *   @ch_id        : channel handle
    887  *   @frame_idx    : frame index
    888  *
    889  * RETURN     : int32_t type of status
    890  *              0  -- success
    891  *              -1 -- failure
    892  *==========================================================================*/
    893 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,
    894                                                     uint32_t ch_id, uint32_t frame_idx)
    895 {
    896     int32_t rc = -1;
    897     mm_camera_obj_t * my_obj = NULL;
    898 
    899     CDBG("%s :E camera_handler = %d,ch_id = %d",
    900          __func__, camera_handle, ch_id);
    901     pthread_mutex_lock(&g_intf_lock);
    902     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    903 
    904     if(my_obj) {
    905         pthread_mutex_lock(&my_obj->cam_lock);
    906         pthread_mutex_unlock(&g_intf_lock);
    907         rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
    908     } else {
    909         pthread_mutex_unlock(&g_intf_lock);
    910     }
    911     CDBG("%s :X rc = %d", __func__, rc);
    912     return rc;
    913 }
    914 
    915 /*===========================================================================
    916  * FUNCTION   : mm_camera_intf_start_zsl_snapshot
    917  *
    918  * DESCRIPTION: Starts zsl snapshot
    919  *
    920  * PARAMETERS :
    921  *   @camera_handle: camera handle
    922  *   @ch_id        : channel handle
    923  *
    924  * RETURN     : int32_t type of status
    925  *              0  -- success
    926  *              -1 -- failure
    927  *==========================================================================*/
    928 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle,
    929         uint32_t ch_id)
    930 {
    931     int32_t rc = -1;
    932     mm_camera_obj_t * my_obj = NULL;
    933 
    934     CDBG("%s :E camera_handler = %d,ch_id = %d",
    935          __func__, camera_handle, ch_id);
    936     pthread_mutex_lock(&g_intf_lock);
    937     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    938 
    939     if(my_obj) {
    940         pthread_mutex_lock(&my_obj->cam_lock);
    941         pthread_mutex_unlock(&g_intf_lock);
    942         rc = mm_camera_start_zsl_snapshot_ch(my_obj, ch_id);
    943     } else {
    944         pthread_mutex_unlock(&g_intf_lock);
    945     }
    946     CDBG("%s :X rc = %d", __func__, rc);
    947     return rc;
    948 }
    949 
    950 /*===========================================================================
    951  * FUNCTION   : mm_camera_intf_stop_zsl_snapshot
    952  *
    953  * DESCRIPTION: Stops zsl snapshot
    954  *
    955  * PARAMETERS :
    956  *   @camera_handle: camera handle
    957  *   @ch_id        : channel handle
    958  *
    959  * RETURN     : int32_t type of status
    960  *              0  -- success
    961  *              -1 -- failure
    962  *==========================================================================*/
    963 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle,
    964         uint32_t ch_id)
    965 {
    966     int32_t rc = -1;
    967     mm_camera_obj_t * my_obj = NULL;
    968 
    969     CDBG("%s :E camera_handler = %d,ch_id = %d",
    970          __func__, camera_handle, ch_id);
    971     pthread_mutex_lock(&g_intf_lock);
    972     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    973 
    974     if(my_obj) {
    975         pthread_mutex_lock(&my_obj->cam_lock);
    976         pthread_mutex_unlock(&g_intf_lock);
    977         rc = mm_camera_stop_zsl_snapshot_ch(my_obj, ch_id);
    978     } else {
    979         pthread_mutex_unlock(&g_intf_lock);
    980     }
    981     CDBG("%s :X rc = %d", __func__, rc);
    982     return rc;
    983 }
    984 
    985 /*===========================================================================
    986  * FUNCTION   : mm_camera_intf_configure_notify_mode
    987  *
    988  * DESCRIPTION: Configures channel notification mode
    989  *
    990  * PARAMETERS :
    991  *   @camera_handle: camera handle
    992  *   @ch_id        : channel handle
    993  *   @notify_mode  : notification mode
    994  *
    995  * RETURN     : int32_t type of status
    996  *              0  -- success
    997  *              -1 -- failure
    998  *==========================================================================*/
    999 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle,
   1000                                                     uint32_t ch_id,
   1001                                                     mm_camera_super_buf_notify_mode_t notify_mode)
   1002 {
   1003     int32_t rc = -1;
   1004     mm_camera_obj_t * my_obj = NULL;
   1005 
   1006     CDBG("%s :E camera_handler = %d,ch_id = %d",
   1007          __func__, camera_handle, ch_id);
   1008     pthread_mutex_lock(&g_intf_lock);
   1009     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1010 
   1011     if(my_obj) {
   1012         pthread_mutex_lock(&my_obj->cam_lock);
   1013         pthread_mutex_unlock(&g_intf_lock);
   1014         rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
   1015     } else {
   1016         pthread_mutex_unlock(&g_intf_lock);
   1017     }
   1018     CDBG("%s :X rc = %d", __func__, rc);
   1019     return rc;
   1020 }
   1021 
   1022 /*===========================================================================
   1023  * FUNCTION   : mm_camera_intf_map_buf
   1024  *
   1025  * DESCRIPTION: mapping camera buffer via domain socket to server
   1026  *
   1027  * PARAMETERS :
   1028  *   @camera_handle: camera handle
   1029  *   @buf_type     : type of buffer to be mapped. could be following values:
   1030  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1031  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1032  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1033  *   @fd           : file descriptor of the buffer
   1034  *   @size         : size of the buffer
   1035  *
   1036  * RETURN     : int32_t type of status
   1037  *              0  -- success
   1038  *              -1 -- failure
   1039  *==========================================================================*/
   1040 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle,
   1041                                       uint8_t buf_type,
   1042                                       int fd,
   1043                                       uint32_t size)
   1044 {
   1045     int32_t rc = -1;
   1046     mm_camera_obj_t * my_obj = NULL;
   1047 
   1048     pthread_mutex_lock(&g_intf_lock);
   1049     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1050 
   1051     if(my_obj) {
   1052         pthread_mutex_lock(&my_obj->cam_lock);
   1053         pthread_mutex_unlock(&g_intf_lock);
   1054         rc = mm_camera_map_buf(my_obj, buf_type, fd, size);
   1055     } else {
   1056         pthread_mutex_unlock(&g_intf_lock);
   1057     }
   1058     return rc;
   1059 }
   1060 
   1061 /*===========================================================================
   1062  * FUNCTION   : mm_camera_intf_unmap_buf
   1063  *
   1064  * DESCRIPTION: unmapping camera buffer via domain socket to server
   1065  *
   1066  * PARAMETERS :
   1067  *   @camera_handle: camera handle
   1068  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1069  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1070  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1071  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1072  *
   1073  * RETURN     : int32_t type of status
   1074  *              0  -- success
   1075  *              -1 -- failure
   1076  *==========================================================================*/
   1077 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle,
   1078                                         uint8_t buf_type)
   1079 {
   1080     int32_t rc = -1;
   1081     mm_camera_obj_t * my_obj = NULL;
   1082 
   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_unmap_buf(my_obj, buf_type);
   1090     } else {
   1091         pthread_mutex_unlock(&g_intf_lock);
   1092     }
   1093     return rc;
   1094 }
   1095 
   1096 /*===========================================================================
   1097  * FUNCTION   : mm_camera_intf_set_stream_parms
   1098  *
   1099  * DESCRIPTION: set parameters per stream
   1100  *
   1101  * PARAMETERS :
   1102  *   @camera_handle: camera handle
   1103  *   @ch_id        : channel handle
   1104  *   @s_id         : stream handle
   1105  *   @parms        : ptr to a param struct to be set to server
   1106  *
   1107  * RETURN     : int32_t type of status
   1108  *              0  -- success
   1109  *              -1 -- failure
   1110  * NOTE       : Assume the parms struct buf is already mapped to server via
   1111  *              domain socket. Corresponding fields of parameters to be set
   1112  *              are already filled in by upper layer caller.
   1113  *==========================================================================*/
   1114 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle,
   1115                                                uint32_t ch_id,
   1116                                                uint32_t s_id,
   1117                                                cam_stream_parm_buffer_t *parms)
   1118 {
   1119     int32_t rc = -1;
   1120     mm_camera_obj_t * my_obj = NULL;
   1121 
   1122     pthread_mutex_lock(&g_intf_lock);
   1123     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1124 
   1125     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
   1126          __func__, camera_handle, ch_id, s_id);
   1127 
   1128     if(my_obj) {
   1129         pthread_mutex_lock(&my_obj->cam_lock);
   1130         pthread_mutex_unlock(&g_intf_lock);
   1131         rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
   1132     }else{
   1133         pthread_mutex_unlock(&g_intf_lock);
   1134     }
   1135     CDBG("%s :X rc = %d", __func__, rc);
   1136     return rc;
   1137 }
   1138 
   1139 /*===========================================================================
   1140  * FUNCTION   : mm_camera_intf_get_stream_parms
   1141  *
   1142  * DESCRIPTION: get parameters per stream
   1143  *
   1144  * PARAMETERS :
   1145  *   @camera_handle: camera handle
   1146  *   @ch_id        : channel handle
   1147  *   @s_id         : stream handle
   1148  *   @parms        : ptr to a param struct to be get from server
   1149  *
   1150  * RETURN     : int32_t type of status
   1151  *              0  -- success
   1152  *              -1 -- failure
   1153  * NOTE       : Assume the parms struct buf is already mapped to server via
   1154  *              domain socket. Parameters to be get from server are already
   1155  *              filled in by upper layer caller. After this call, corresponding
   1156  *              fields of requested parameters will be filled in by server with
   1157  *              detailed information.
   1158  *==========================================================================*/
   1159 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle,
   1160                                                uint32_t ch_id,
   1161                                                uint32_t s_id,
   1162                                                cam_stream_parm_buffer_t *parms)
   1163 {
   1164     int32_t rc = -1;
   1165     mm_camera_obj_t * my_obj = NULL;
   1166 
   1167     pthread_mutex_lock(&g_intf_lock);
   1168     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1169 
   1170     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
   1171          __func__, camera_handle, ch_id, s_id);
   1172 
   1173     if(my_obj) {
   1174         pthread_mutex_lock(&my_obj->cam_lock);
   1175         pthread_mutex_unlock(&g_intf_lock);
   1176         rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
   1177     }else{
   1178         pthread_mutex_unlock(&g_intf_lock);
   1179     }
   1180 
   1181     CDBG("%s :X rc = %d", __func__, rc);
   1182     return rc;
   1183 }
   1184 
   1185 /*===========================================================================
   1186  * FUNCTION   : mm_camera_intf_map_stream_buf
   1187  *
   1188  * DESCRIPTION: mapping stream buffer via domain socket to server
   1189  *
   1190  * PARAMETERS :
   1191  *   @camera_handle: camera handle
   1192  *   @ch_id        : channel handle
   1193  *   @s_id         : stream handle
   1194  *   @buf_type     : type of buffer to be mapped. could be following values:
   1195  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1196  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1197  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1198  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1199  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1200  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1201  *   @plane_idx    : plane index. If all planes share the same fd,
   1202  *                   plane_idx = -1; otherwise, plean_idx is the
   1203  *                   index to plane (0..num_of_planes)
   1204  *   @fd           : file descriptor of the buffer
   1205  *   @size         : size of the buffer
   1206  *
   1207  * RETURN     : int32_t type of status
   1208  *              0  -- success
   1209  *              -1 -- failure
   1210  *==========================================================================*/
   1211 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle,
   1212                                              uint32_t ch_id,
   1213                                              uint32_t stream_id,
   1214                                              uint8_t buf_type,
   1215                                              uint32_t buf_idx,
   1216                                              int32_t plane_idx,
   1217                                              int fd,
   1218                                              uint32_t size)
   1219 {
   1220     int32_t rc = -1;
   1221     mm_camera_obj_t * my_obj = NULL;
   1222 
   1223     pthread_mutex_lock(&g_intf_lock);
   1224     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1225 
   1226     CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   1227          __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   1228 
   1229     if(my_obj) {
   1230         pthread_mutex_lock(&my_obj->cam_lock);
   1231         pthread_mutex_unlock(&g_intf_lock);
   1232         rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
   1233                                       buf_type, buf_idx, plane_idx,
   1234                                       fd, size);
   1235     }else{
   1236         pthread_mutex_unlock(&g_intf_lock);
   1237     }
   1238 
   1239     CDBG("%s :X rc = %d", __func__, rc);
   1240     return rc;
   1241 }
   1242 
   1243 /*===========================================================================
   1244  * FUNCTION   : mm_camera_intf_unmap_stream_buf
   1245  *
   1246  * DESCRIPTION: unmapping stream buffer via domain socket to server
   1247  *
   1248  * PARAMETERS :
   1249  *   @camera_handle: camera handle
   1250  *   @ch_id        : channel handle
   1251  *   @s_id         : stream handle
   1252  *   @buf_type     : type of buffer to be unmapped. could be following values:
   1253  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1254  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1255  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1256  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1257  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1258  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1259  *   @plane_idx    : plane index. If all planes share the same fd,
   1260  *                   plane_idx = -1; otherwise, plean_idx is the
   1261  *                   index to plane (0..num_of_planes)
   1262  *
   1263  * RETURN     : int32_t type of status
   1264  *              0  -- success
   1265  *              -1 -- failure
   1266  *==========================================================================*/
   1267 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle,
   1268                                                uint32_t ch_id,
   1269                                                uint32_t stream_id,
   1270                                                uint8_t buf_type,
   1271                                                uint32_t buf_idx,
   1272                                                int32_t plane_idx)
   1273 {
   1274     int32_t rc = -1;
   1275     mm_camera_obj_t * my_obj = NULL;
   1276 
   1277     pthread_mutex_lock(&g_intf_lock);
   1278     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1279 
   1280     CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
   1281          __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
   1282 
   1283     if(my_obj) {
   1284         pthread_mutex_lock(&my_obj->cam_lock);
   1285         pthread_mutex_unlock(&g_intf_lock);
   1286         rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
   1287                                         buf_type, buf_idx, plane_idx);
   1288     }else{
   1289         pthread_mutex_unlock(&g_intf_lock);
   1290     }
   1291 
   1292     CDBG("%s :X rc = %d", __func__, rc);
   1293     return rc;
   1294 }
   1295 
   1296 /*===========================================================================
   1297  * FUNCTION   : get_sensor_info
   1298  *
   1299  * DESCRIPTION: get sensor info like facing(back/front) and mount angle
   1300  *
   1301  * PARAMETERS :
   1302  *
   1303  * RETURN     :
   1304  *==========================================================================*/
   1305 void get_sensor_info()
   1306 {
   1307     int rc = 0;
   1308     int dev_fd = -1;
   1309     struct media_device_info mdev_info;
   1310     int num_media_devices = 0;
   1311     uint8_t num_cameras = 0;
   1312 
   1313     CDBG("%s : E", __func__);
   1314     while (1) {
   1315         char dev_name[32];
   1316         int num_entities;
   1317         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   1318         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   1319         if (dev_fd < 0) {
   1320             CDBG("Done discovering media devices\n");
   1321             break;
   1322         }
   1323         num_media_devices++;
   1324         memset(&mdev_info, 0, sizeof(mdev_info));
   1325         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   1326         if (rc < 0) {
   1327             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
   1328             close(dev_fd);
   1329             dev_fd = -1;
   1330             num_cameras = 0;
   1331             break;
   1332         }
   1333 
   1334         if(strncmp(mdev_info.model,  MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) {
   1335             close(dev_fd);
   1336             dev_fd = -1;
   1337             continue;
   1338         }
   1339 
   1340         num_entities = 1;
   1341         while (1) {
   1342             struct media_entity_desc entity;
   1343             unsigned long temp;
   1344             unsigned int mount_angle;
   1345             unsigned int facing;
   1346 
   1347             memset(&entity, 0, sizeof(entity));
   1348             entity.id = num_entities++;
   1349             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   1350             if (rc < 0) {
   1351                 CDBG("Done enumerating media entities\n");
   1352                 rc = 0;
   1353                 break;
   1354             }
   1355             if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
   1356                 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) {
   1357                 temp = entity.flags >> 8;
   1358                 mount_angle = (temp & 0xFF) * 90;
   1359                 facing = (temp >> 8);
   1360                 ALOGD("index = %d flag = %x mount_angle = %d facing = %d\n"
   1361                     , num_cameras, (unsigned int)temp, (unsigned int)mount_angle,
   1362                     (unsigned int)facing);
   1363                 g_cam_ctrl.info[num_cameras].facing = facing;
   1364                 g_cam_ctrl.info[num_cameras].orientation = mount_angle;
   1365                 num_cameras++;
   1366                 continue;
   1367             }
   1368         }
   1369 
   1370         CDBG("%s: dev_info[id=%d,name='%s']\n",
   1371             __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
   1372 
   1373         close(dev_fd);
   1374         dev_fd = -1;
   1375     }
   1376 
   1377     CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
   1378     return;
   1379 }
   1380 
   1381 /*===========================================================================
   1382  * FUNCTION   : get_num_of_cameras
   1383  *
   1384  * DESCRIPTION: get number of cameras
   1385  *
   1386  * PARAMETERS :
   1387  *
   1388  * RETURN     : number of cameras supported
   1389  *==========================================================================*/
   1390 uint8_t get_num_of_cameras()
   1391 {
   1392     int rc = 0;
   1393     int dev_fd = 0;
   1394     struct media_device_info mdev_info;
   1395     int num_media_devices = 0;
   1396     uint8_t num_cameras = 0;
   1397     char subdev_name[32];
   1398     int32_t sd_fd = 0;
   1399     struct sensor_init_cfg_data cfg;
   1400     char prop[PROPERTY_VALUE_MAX];
   1401 
   1402     property_get("persist.camera.logs", prop, "0");
   1403     gMmCameraIntfLogLevel = atoi(prop);
   1404 
   1405     CDBG("%s : E", __func__);
   1406 
   1407     int decrypt = property_get("vold.decrypt", prop, NULL);
   1408     if (0 < decrypt) {
   1409         if(strncmp(prop, "trigger_restart_min_framework", decrypt) == 0) {
   1410             return 0;
   1411         }
   1412     }
   1413 
   1414     /* lock the mutex */
   1415     pthread_mutex_lock(&g_intf_lock);
   1416 
   1417     while (1) {
   1418         int32_t num_entities = 1;
   1419         char dev_name[32];
   1420 
   1421         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   1422         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   1423         if (dev_fd < 0) {
   1424             CDBG("Done discovering media devices\n");
   1425             break;
   1426         }
   1427         num_media_devices++;
   1428         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   1429         if (rc < 0) {
   1430             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
   1431             close(dev_fd);
   1432             dev_fd = -1;
   1433             break;
   1434         }
   1435 
   1436         if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME,
   1437           sizeof(mdev_info.model)) != 0) {
   1438             close(dev_fd);
   1439             dev_fd = -1;
   1440             continue;
   1441         }
   1442 
   1443         while (1) {
   1444             struct media_entity_desc entity;
   1445             memset(&entity, 0, sizeof(entity));
   1446             entity.id = num_entities++;
   1447             CDBG_ERROR("entity id %d", entity.id);
   1448             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   1449             if (rc < 0) {
   1450                 CDBG_ERROR("Done enumerating media entities");
   1451                 rc = 0;
   1452                 break;
   1453             }
   1454             CDBG_ERROR("entity name %s type %d group id %d",
   1455                 entity.name, entity.type, entity.group_id);
   1456             if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
   1457                 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) {
   1458                 snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name);
   1459                 break;
   1460             }
   1461         }
   1462         close(dev_fd);
   1463         dev_fd = -1;
   1464     }
   1465 
   1466     /* Open sensor_init subdev */
   1467     sd_fd = open(subdev_name, O_RDWR);
   1468     if (sd_fd < 0) {
   1469         CDBG_ERROR("Open sensor_init subdev failed");
   1470         return FALSE;
   1471     }
   1472 
   1473     cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE;
   1474     cfg.cfg.setting = NULL;
   1475     if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
   1476         CDBG_ERROR("failed");
   1477     }
   1478     close(sd_fd);
   1479     dev_fd = -1;
   1480 
   1481 
   1482     num_media_devices = 0;
   1483     while (1) {
   1484         char dev_name[32];
   1485         int num_entities;
   1486         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   1487         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   1488         if (dev_fd < 0) {
   1489             CDBG("Done discovering media devices: %s\n", strerror(errno));
   1490             break;
   1491         }
   1492         num_media_devices++;
   1493         memset(&mdev_info, 0, sizeof(mdev_info));
   1494         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   1495         if (rc < 0) {
   1496             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
   1497             close(dev_fd);
   1498             dev_fd = -1;
   1499             num_cameras = 0;
   1500             break;
   1501         }
   1502 
   1503         if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) {
   1504             close(dev_fd);
   1505             dev_fd = -1;
   1506             continue;
   1507         }
   1508 
   1509         num_entities = 1;
   1510         while (1) {
   1511             struct media_entity_desc entity;
   1512             memset(&entity, 0, sizeof(entity));
   1513             entity.id = num_entities++;
   1514             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   1515             if (rc < 0) {
   1516                 CDBG("Done enumerating media entities\n");
   1517                 rc = 0;
   1518                 break;
   1519             }
   1520             if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
   1521                 strncpy(g_cam_ctrl.video_dev_name[num_cameras],
   1522                      entity.name, sizeof(entity.name));
   1523                 break;
   1524             }
   1525         }
   1526 
   1527         CDBG("%s: dev_info[id=%d,name='%s']\n",
   1528             __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
   1529 
   1530         num_cameras++;
   1531         close(dev_fd);
   1532         dev_fd = -1;
   1533     }
   1534     g_cam_ctrl.num_cam = num_cameras;
   1535 
   1536     get_sensor_info();
   1537     /* unlock the mutex */
   1538     pthread_mutex_unlock(&g_intf_lock);
   1539     CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
   1540     return g_cam_ctrl.num_cam;
   1541 }
   1542 
   1543 /*===========================================================================
   1544  * FUNCTION   : mm_camera_intf_process_advanced_capture
   1545  *
   1546  * DESCRIPTION: Configures channel advanced capture mode
   1547  *
   1548  * PARAMETERS :
   1549  *   @camera_handle: camera handle
   1550  *   @advanced_capture_type : advanced capture type
   1551  *   @ch_id        : channel handle
   1552  *   @notify_mode  : notification mode
   1553  *
   1554  * RETURN     : int32_t type of status
   1555  *              0  -- success
   1556  *              -1 -- failure
   1557  *==========================================================================*/
   1558 static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle,
   1559     mm_camera_advanced_capture_t advanced_capture_type,
   1560     uint32_t ch_id,
   1561     int8_t start_flag)
   1562 {
   1563     int32_t rc = -1;
   1564     mm_camera_obj_t * my_obj = NULL;
   1565 
   1566     CDBG("%s: E camera_handler = %d,ch_id = %d",
   1567          __func__, camera_handle, ch_id);
   1568     pthread_mutex_lock(&g_intf_lock);
   1569     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1570 
   1571     if(my_obj) {
   1572         pthread_mutex_lock(&my_obj->cam_lock);
   1573         pthread_mutex_unlock(&g_intf_lock);
   1574         rc = mm_camera_channel_advanced_capture(my_obj, advanced_capture_type, ch_id, start_flag);
   1575     } else {
   1576         pthread_mutex_unlock(&g_intf_lock);
   1577     }
   1578     CDBG("%s: X ", __func__);
   1579     return rc;
   1580 }
   1581 
   1582 struct camera_info *get_cam_info(int camera_id)
   1583 {
   1584     return &g_cam_ctrl.info[camera_id];
   1585 }
   1586 
   1587 /* camera ops v-table */
   1588 static mm_camera_ops_t mm_camera_ops = {
   1589     .query_capability = mm_camera_intf_query_capability,
   1590     .register_event_notify = mm_camera_intf_register_event_notify,
   1591     .close_camera = mm_camera_intf_close,
   1592     .error_close_camera = mm_camera_intf_error_close,
   1593     .set_parms = mm_camera_intf_set_parms,
   1594     .get_parms = mm_camera_intf_get_parms,
   1595     .do_auto_focus = mm_camera_intf_do_auto_focus,
   1596     .cancel_auto_focus = mm_camera_intf_cancel_auto_focus,
   1597     .prepare_snapshot = mm_camera_intf_prepare_snapshot,
   1598     .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,
   1599     .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,
   1600     .map_buf = mm_camera_intf_map_buf,
   1601     .unmap_buf = mm_camera_intf_unmap_buf,
   1602     .add_channel = mm_camera_intf_add_channel,
   1603     .delete_channel = mm_camera_intf_del_channel,
   1604     .get_bundle_info = mm_camera_intf_get_bundle_info,
   1605     .add_stream = mm_camera_intf_add_stream,
   1606     .delete_stream = mm_camera_intf_del_stream,
   1607     .config_stream = mm_camera_intf_config_stream,
   1608     .qbuf = mm_camera_intf_qbuf,
   1609     .map_stream_buf = mm_camera_intf_map_stream_buf,
   1610     .unmap_stream_buf = mm_camera_intf_unmap_stream_buf,
   1611     .set_stream_parms = mm_camera_intf_set_stream_parms,
   1612     .get_stream_parms = mm_camera_intf_get_stream_parms,
   1613     .start_channel = mm_camera_intf_start_channel,
   1614     .stop_channel = mm_camera_intf_stop_channel,
   1615     .request_super_buf = mm_camera_intf_request_super_buf,
   1616     .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
   1617     .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,
   1618     .configure_notify_mode = mm_camera_intf_configure_notify_mode,
   1619     .process_advanced_capture = mm_camera_intf_process_advanced_capture
   1620 };
   1621 
   1622 /*===========================================================================
   1623  * FUNCTION   : camera_open
   1624  *
   1625  * DESCRIPTION: open a camera by camera index
   1626  *
   1627  * PARAMETERS :
   1628  *   @camera_idx : camera index. should within range of 0 to num_of_cameras
   1629  *
   1630  * RETURN     : ptr to a virtual table containing camera handle and operation table.
   1631  *              NULL if failed.
   1632  *==========================================================================*/
   1633 mm_camera_vtbl_t * camera_open(uint8_t camera_idx)
   1634 {
   1635     int32_t rc = 0;
   1636     mm_camera_obj_t* cam_obj = NULL;
   1637 
   1638     CDBG("%s: E camera_idx = %d\n", __func__, camera_idx);
   1639     if (camera_idx >= g_cam_ctrl.num_cam) {
   1640         CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
   1641         return NULL;
   1642     }
   1643 
   1644     pthread_mutex_lock(&g_intf_lock);
   1645     /* opened already */
   1646     if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
   1647         /* Add reference */
   1648         g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
   1649         pthread_mutex_unlock(&g_intf_lock);
   1650         CDBG("%s:  opened alreadyn", __func__);
   1651         return &g_cam_ctrl.cam_obj[camera_idx]->vtbl;
   1652     }
   1653 
   1654     cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
   1655     if(NULL == cam_obj) {
   1656         pthread_mutex_unlock(&g_intf_lock);
   1657         CDBG("%s:  no mem", __func__);
   1658         return NULL;
   1659     }
   1660 
   1661     /* initialize camera obj */
   1662     memset(cam_obj, 0, sizeof(mm_camera_obj_t));
   1663     cam_obj->ctrl_fd = -1;
   1664     cam_obj->ds_fd = -1;
   1665     cam_obj->ref_count++;
   1666     cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
   1667     cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
   1668     cam_obj->vtbl.ops = &mm_camera_ops;
   1669     pthread_mutex_init(&cam_obj->cam_lock, NULL);
   1670 
   1671     rc = mm_camera_open(cam_obj);
   1672     if(rc != 0) {
   1673         CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
   1674         pthread_mutex_destroy(&cam_obj->cam_lock);
   1675         g_cam_ctrl.cam_obj[camera_idx] = NULL;
   1676         free(cam_obj);
   1677         cam_obj = NULL;
   1678         pthread_mutex_unlock(&g_intf_lock);
   1679         return NULL;
   1680     }else{
   1681         CDBG("%s: Open succeded\n", __func__);
   1682         g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
   1683         pthread_mutex_unlock(&g_intf_lock);
   1684         return &cam_obj->vtbl;
   1685     }
   1686 }
   1687