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