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