Home | History | Annotate | Download | only in src
      1 /*
      2 Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are
      6 met:
      7     * Redistributions of source code must retain the above copyright
      8       notice, this list of conditions and the following disclaimer.
      9     * Redistributions in binary form must reproduce the above
     10       copyright notice, this list of conditions and the following
     11       disclaimer in the documentation and/or other materials provided
     12       with the distribution.
     13     * Neither the name of The Linux Foundation nor the names of its
     14       contributors may be used to endorse or promote products derived
     15       from this software without specific prior written permission.
     16 
     17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 */
     29 
     30 #include <pthread.h>
     31 #include <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 <semaphore.h>
     39 
     40 #include "mm_camera_dbg.h"
     41 #include "mm_camera_interface.h"
     42 #include "mm_camera_sock.h"
     43 #include "mm_camera.h"
     44 
     45 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
     46 static pthread_mutex_t g_oem_lock = PTHREAD_MUTEX_INITIALIZER;
     47 
     48 static mm_camera_ctrl_t g_cam_ctrl = {{{0, {0, 0, 0, 0}, 0, 0}}, 0, {{0}}, {0}};
     49 
     50 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
     51 static uint16_t g_handler_history_count = 0; /* history count for handler */
     52 
     53 extern int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
     54                                        cam_ctrl_type type,
     55                                        uint32_t length,
     56                                        void *value);
     57 
     58 /* utility function to generate handler */
     59 uint32_t mm_camera_util_generate_handler(uint8_t index)
     60 {
     61     uint32_t handler = 0;
     62     pthread_mutex_lock(&g_handler_lock);
     63     g_handler_history_count++;
     64     if (0 == g_handler_history_count) {
     65         g_handler_history_count++;
     66     }
     67     handler = g_handler_history_count;
     68     handler = (handler<<8) | index;
     69     pthread_mutex_unlock(&g_handler_lock);
     70     return handler;
     71 }
     72 
     73 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
     74 {
     75     return (handler&0x000000ff);
     76 }
     77 
     78 const char *mm_camera_util_get_dev_name(uint32_t cam_handler)
     79 {
     80     char *dev_name = NULL;
     81     uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler);
     82     dev_name = g_cam_ctrl.camera[cam_idx].video_dev_name;
     83     return dev_name;
     84 }
     85 
     86 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler)
     87 {
     88     mm_camera_obj_t *cam_obj = NULL;
     89     uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler);
     90 
     91     if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
     92         (cam_handler == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
     93         cam_obj = g_cam_ctrl.cam_obj[cam_idx];
     94     }
     95     return cam_obj;
     96 }
     97 
     98 static int32_t mm_camera_intf_sync(uint32_t camera_handler)
     99 {
    100     int32_t rc = -1;
    101     mm_camera_obj_t * my_obj = NULL;
    102 
    103     CDBG("%s E: camera_handler = %d ",__func__,camera_handler);
    104 
    105     pthread_mutex_lock(&g_intf_lock);
    106     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    107 
    108     if(my_obj) {
    109         pthread_mutex_lock(&my_obj->cam_lock);
    110         pthread_mutex_unlock(&g_intf_lock);
    111         rc = mm_camera_sync(my_obj);
    112     } else {
    113         pthread_mutex_unlock(&g_intf_lock);
    114     }
    115     CDBG("%s :X rc = %d",__func__,rc);
    116     return rc;
    117 }
    118 
    119 /* check if the operation is supported */
    120 static int32_t mm_camera_intf_is_op_supported(uint32_t camera_handler,mm_camera_ops_type_t opcode)
    121 {
    122     int32_t rc = -1;
    123     mm_camera_obj_t * my_obj = NULL;
    124 
    125     pthread_mutex_lock(&g_intf_lock);
    126     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    127 
    128     if(my_obj) {
    129         pthread_mutex_lock(&my_obj->cam_lock);
    130         pthread_mutex_unlock(&g_intf_lock);
    131         rc = mm_camera_is_op_supported(my_obj, opcode);
    132     } else {
    133         pthread_mutex_unlock(&g_intf_lock);
    134     }
    135     return rc;
    136 }
    137 
    138 /* check if the parm is supported */
    139 static int32_t mm_camera_intf_is_parm_supported(uint32_t camera_handler,
    140                                    mm_camera_parm_type_t parm_type,
    141                                    uint8_t *support_set_parm,
    142                                    uint8_t *support_get_parm)
    143 {
    144     int32_t rc = -1;
    145     mm_camera_obj_t * my_obj = NULL;
    146 
    147     pthread_mutex_lock(&g_intf_lock);
    148     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    149     *support_set_parm = 0;
    150     *support_get_parm = 0;
    151 
    152     if(my_obj) {
    153         pthread_mutex_lock(&my_obj->cam_lock);
    154         pthread_mutex_unlock(&g_intf_lock);
    155         rc = mm_camera_is_parm_supported(my_obj, parm_type, support_set_parm, support_get_parm);
    156     } else {
    157         pthread_mutex_unlock(&g_intf_lock);
    158     }
    159     return rc;
    160 }
    161 
    162 /* set a parms current value */
    163 static int32_t mm_camera_intf_set_parm(uint32_t camera_handler,
    164                                    mm_camera_parm_type_t parm_type,
    165                                    void* p_value)
    166 {
    167     int32_t rc = -1;
    168     mm_camera_obj_t * my_obj = NULL;
    169 
    170     pthread_mutex_lock(&g_intf_lock);
    171     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    172 
    173     if(my_obj) {
    174         pthread_mutex_lock(&my_obj->cam_lock);
    175         pthread_mutex_unlock(&g_intf_lock);
    176         rc = mm_camera_set_parm(my_obj, parm_type, p_value);
    177     } else {
    178         pthread_mutex_unlock(&g_intf_lock);
    179     }
    180     return rc;
    181 }
    182 
    183 /* get a parms current value */
    184 static int32_t mm_camera_intf_get_parm(uint32_t camera_handler,
    185                                 mm_camera_parm_type_t parm_type,
    186                                 void* p_value)
    187 {
    188     int32_t rc = -1;
    189     mm_camera_obj_t * my_obj = NULL;
    190 
    191     pthread_mutex_lock(&g_intf_lock);
    192     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    193 
    194     if(my_obj) {
    195         pthread_mutex_lock(&my_obj->cam_lock);
    196         pthread_mutex_unlock(&g_intf_lock);
    197         rc = mm_camera_get_parm(my_obj, parm_type, p_value);
    198     } else {
    199         pthread_mutex_unlock(&g_intf_lock);
    200     }
    201     return rc;
    202 }
    203 
    204 static void mm_camera_intf_close(uint32_t camera_handler)
    205 {
    206     int32_t rc = -1;
    207     uint8_t cam_idx = camera_handler & 0x00ff;
    208     mm_camera_obj_t * my_obj = NULL;
    209 
    210     CDBG("%s E: camera_handler = %d ",__func__,camera_handler);
    211 
    212     /* first we need to get oem_lock,
    213      * in case oem private ioctl is still processing,
    214      * we need to wait until it finishes */
    215     pthread_mutex_lock(&g_oem_lock);
    216 
    217     /* then we get intf_lock */
    218     pthread_mutex_lock(&g_intf_lock);
    219     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    220 
    221     if (my_obj){
    222         my_obj->ref_count--;
    223 
    224         if(my_obj->ref_count > 0) {
    225             /* still have reference to obj, return here */
    226             CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
    227             pthread_mutex_unlock(&g_intf_lock);
    228         } else {
    229             /* need close camera here as no other reference
    230              * first empty g_cam_ctrl's referent to cam_obj */
    231             g_cam_ctrl.cam_obj[cam_idx] = NULL;
    232 
    233             pthread_mutex_lock(&my_obj->cam_lock);
    234             pthread_mutex_unlock(&g_intf_lock);
    235 
    236             mm_camera_close(my_obj);
    237 
    238             pthread_mutex_destroy(&my_obj->cam_lock);
    239             free(my_obj);
    240         }
    241     } else {
    242         pthread_mutex_unlock(&g_intf_lock);
    243     }
    244 
    245     /* unlock oem_lock before we leave */
    246     pthread_mutex_unlock(&g_oem_lock);
    247 }
    248 
    249 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handler)
    250 {
    251     uint32_t ch_id = 0;
    252     mm_camera_obj_t * my_obj = NULL;
    253 
    254     CDBG("%s :E camera_handler = %d",__func__,camera_handler);
    255     pthread_mutex_lock(&g_intf_lock);
    256     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    257 
    258     if(my_obj) {
    259         pthread_mutex_lock(&my_obj->cam_lock);
    260         pthread_mutex_unlock(&g_intf_lock);
    261         ch_id = mm_camera_add_channel(my_obj);
    262     } else {
    263         pthread_mutex_unlock(&g_intf_lock);
    264     }
    265     CDBG("%s :X ch_id = %d",__func__,ch_id);
    266     return ch_id;
    267 }
    268 
    269 static void mm_camera_intf_del_channel(uint32_t camera_handler, uint32_t ch_id)
    270 {
    271     mm_camera_obj_t * my_obj = NULL;
    272 
    273     CDBG("%s :E ch_id = %d",__func__,ch_id);
    274     pthread_mutex_lock(&g_intf_lock);
    275     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    276 
    277     if(my_obj) {
    278         pthread_mutex_lock(&my_obj->cam_lock);
    279         pthread_mutex_unlock(&g_intf_lock);
    280         mm_camera_del_channel(my_obj, ch_id);
    281     } else {
    282         pthread_mutex_unlock(&g_intf_lock);
    283     }
    284     CDBG("%s :X",__func__);
    285 }
    286 
    287 static uint8_t mm_camera_intf_is_event_supported(uint32_t camera_handler,
    288                                     mm_camera_event_type_t evt_type)
    289 {
    290     switch(evt_type) {
    291     case MM_CAMERA_EVT_TYPE_CH:
    292     case MM_CAMERA_EVT_TYPE_CTRL:
    293     case MM_CAMERA_EVT_TYPE_STATS:
    294     case MM_CAMERA_EVT_TYPE_INFO:
    295         return 1;
    296     default:
    297         return 0;
    298     }
    299     return 0;
    300 }
    301 
    302 static int32_t mm_camera_intf_register_event_notify(
    303                                     uint32_t camera_handler,
    304                                     mm_camera_event_notify_t evt_cb,
    305                                     void * user_data,
    306                                     mm_camera_event_type_t evt_type)
    307 {
    308     int32_t rc = -1;
    309     mm_camera_obj_t * my_obj = NULL;
    310 
    311     CDBG("%s :E evt_type = %d",__func__,evt_type);
    312     pthread_mutex_lock(&g_intf_lock);
    313     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    314 
    315     if(my_obj) {
    316         pthread_mutex_lock(&my_obj->cam_lock);
    317         pthread_mutex_unlock(&g_intf_lock);
    318         rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data, evt_type);
    319     } else {
    320         pthread_mutex_unlock(&g_intf_lock);
    321     }
    322     CDBG("%s :E rc = %d",__func__,rc);
    323     return rc;
    324 }
    325 
    326 static mm_camera_2nd_sensor_t * mm_camera_intf_query_2nd_sensor_info(uint32_t camera_handler)
    327 {
    328     mm_camera_2nd_sensor_t *sensor_info = NULL;
    329     mm_camera_obj_t * my_obj = NULL;
    330 
    331     CDBG("%s :E camera_handler = %d",__func__,camera_handler);
    332     pthread_mutex_lock(&g_intf_lock);
    333     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    334 
    335     if(my_obj) {
    336         pthread_mutex_lock(&my_obj->cam_lock);
    337         pthread_mutex_unlock(&g_intf_lock);
    338         sensor_info = mm_camera_query_2nd_sensor_info(my_obj);
    339     } else {
    340         pthread_mutex_unlock(&g_intf_lock);
    341     }
    342     CDBG("%s :X",__func__);
    343     return sensor_info;
    344 }
    345 
    346 static int32_t mm_camera_intf_qbuf(uint32_t camera_handler,
    347                                     uint32_t ch_id,
    348                                     mm_camera_buf_def_t *buf)
    349 {
    350     int32_t rc = -1;
    351     mm_camera_obj_t * my_obj = NULL;
    352 
    353     pthread_mutex_lock(&g_intf_lock);
    354     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    355 
    356     if(my_obj) {
    357         pthread_mutex_lock(&my_obj->cam_lock);
    358         pthread_mutex_unlock(&g_intf_lock);
    359         rc = mm_camera_qbuf(my_obj, ch_id, buf);
    360     } else {
    361         pthread_mutex_unlock(&g_intf_lock);
    362     }
    363     CDBG("%s :X evt_type = %d",__func__,rc);
    364     return rc;
    365 }
    366 
    367 static uint32_t mm_camera_intf_add_stream(
    368                                     uint32_t camera_handler,
    369                                     uint32_t ch_id,
    370                                     mm_camera_buf_notify_t buf_cb, void *user_data,
    371                                     uint32_t ext_image_mode, uint32_t sensor_idx)
    372 {
    373     uint32_t stream_id = 0;
    374     mm_camera_obj_t * my_obj = NULL;
    375 
    376     CDBG("%s : E handle = %d ch_id = %d",__func__,camera_handler,
    377          ch_id);
    378 
    379     pthread_mutex_lock(&g_intf_lock);
    380     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    381 
    382     if(my_obj) {
    383         pthread_mutex_lock(&my_obj->cam_lock);
    384         pthread_mutex_unlock(&g_intf_lock);
    385         stream_id = mm_camera_add_stream(my_obj, ch_id, buf_cb,
    386                                   user_data, ext_image_mode, sensor_idx);
    387     } else {
    388         pthread_mutex_unlock(&g_intf_lock);
    389     }
    390     CDBG("%s :X stream_id = %d",__func__,stream_id);
    391     return stream_id;
    392 }
    393 
    394 static int32_t mm_camera_intf_del_stream(
    395                                     uint32_t camera_handler,
    396                                     uint32_t ch_id,
    397                                     uint32_t stream_id)
    398 {
    399     int32_t rc = -1;
    400     mm_camera_obj_t * my_obj = NULL;
    401 
    402     CDBG("%s : E handle = %d ch_id = %d stream_id = %d",__func__,camera_handler,
    403          ch_id,stream_id);
    404 
    405     pthread_mutex_lock(&g_intf_lock);
    406     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    407 
    408     if(my_obj) {
    409         pthread_mutex_lock(&my_obj->cam_lock);
    410         pthread_mutex_unlock(&g_intf_lock);
    411         rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
    412     } else {
    413         pthread_mutex_unlock(&g_intf_lock);
    414     }
    415     CDBG("%s :X rc = %d",__func__,rc);
    416     return rc;
    417 }
    418 
    419 static int32_t mm_camera_intf_config_stream(
    420                                     uint32_t camera_handler,
    421                                     uint32_t ch_id,
    422                                     uint32_t stream_id,
    423                                     mm_camera_stream_config_t *config)
    424 {
    425     int32_t rc = -1;
    426     mm_camera_obj_t * my_obj = NULL;
    427 
    428     CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",__func__,
    429          camera_handler,ch_id,stream_id);
    430 
    431     pthread_mutex_lock(&g_intf_lock);
    432     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    433 
    434     CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
    435 
    436     if(my_obj) {
    437         pthread_mutex_lock(&my_obj->cam_lock);
    438         pthread_mutex_unlock(&g_intf_lock);
    439         rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
    440     } else {
    441         pthread_mutex_unlock(&g_intf_lock);
    442     }
    443     CDBG("%s :X rc = %d",__func__,rc);
    444     return rc;
    445 }
    446 
    447 static int32_t mm_camera_intf_bundle_streams(
    448                                     uint32_t camera_handler,
    449                                     uint32_t ch_id,
    450                                     mm_camera_buf_notify_t super_frame_notify_cb,
    451                                     void *user_data,
    452                                     mm_camera_bundle_attr_t *attr,
    453                                     uint8_t num_streams,
    454                                     uint32_t *stream_ids)
    455 {
    456     int32_t rc = -1;
    457     mm_camera_obj_t * my_obj = NULL;
    458 
    459     CDBG("%s :E handle = %d, ch_id = %d",__func__,
    460          camera_handler,ch_id);
    461 
    462     if (MM_CAMEAR_MAX_STRAEM_BUNDLE < num_streams) {
    463         CDBG_ERROR("%s: number of streams (%d) exceeds max (%d)",
    464                    __func__, num_streams, MM_CAMEAR_MAX_STRAEM_BUNDLE);
    465         return rc;
    466     }
    467 
    468     pthread_mutex_lock(&g_intf_lock);
    469     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    470 
    471     if(my_obj) {
    472         pthread_mutex_lock(&my_obj->cam_lock);
    473         pthread_mutex_unlock(&g_intf_lock);
    474         rc = mm_camera_bundle_streams(my_obj, ch_id,
    475                                       super_frame_notify_cb,
    476                                       user_data, attr,
    477                                       num_streams, stream_ids);
    478     } else {
    479         pthread_mutex_unlock(&g_intf_lock);
    480     }
    481     CDBG("%s :X rc = %d",__func__,rc);
    482     return rc;
    483 }
    484 
    485 static int32_t mm_camera_intf_destroy_bundle(uint32_t camera_handler,
    486                                     uint32_t ch_id)
    487 {
    488     int32_t rc = -1;
    489     mm_camera_obj_t * my_obj = NULL;
    490 
    491     CDBG("%s :E handle = %d, ch_id = %d",__func__,
    492          camera_handler,ch_id);
    493     pthread_mutex_lock(&g_intf_lock);
    494     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    495 
    496     if(my_obj) {
    497         pthread_mutex_lock(&my_obj->cam_lock);
    498         pthread_mutex_unlock(&g_intf_lock);
    499         rc = mm_camera_destroy_bundle(my_obj, ch_id);
    500     } else {
    501         pthread_mutex_unlock(&g_intf_lock);
    502     }
    503     CDBG("%s :X rc = %d",__func__,rc);
    504     return rc;
    505 }
    506 
    507 static int32_t mm_camera_intf_start_streams(
    508                                     uint32_t camera_handler,
    509                                     uint32_t ch_id,
    510                                     uint8_t num_streams,
    511                                     uint32_t *stream_ids)
    512 {
    513     int32_t rc = -1;
    514     mm_camera_obj_t * my_obj = NULL;
    515 
    516     CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
    517          __func__,camera_handler,ch_id,num_streams);
    518     if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
    519         CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
    520                    __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
    521         return rc;
    522     }
    523 
    524     pthread_mutex_lock(&g_intf_lock);
    525     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    526 
    527     if(my_obj) {
    528         pthread_mutex_lock(&my_obj->cam_lock);
    529         pthread_mutex_unlock(&g_intf_lock);
    530         rc = mm_camera_start_streams(my_obj, ch_id, num_streams, stream_ids);
    531     } else {
    532         pthread_mutex_unlock(&g_intf_lock);
    533     }
    534     CDBG("%s :X rc = %d",__func__,rc);
    535     return rc;
    536 }
    537 
    538 static int32_t mm_camera_intf_stop_streams(
    539                                     uint32_t camera_handler,
    540                                     uint32_t ch_id,
    541                                     uint8_t num_streams,
    542                                     uint32_t *stream_ids)
    543 {
    544     int32_t rc = -1;
    545     mm_camera_obj_t * my_obj = NULL;
    546 
    547     CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
    548          __func__,camera_handler,ch_id,num_streams);
    549 
    550     if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
    551         CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
    552                    __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
    553         return rc;
    554     }
    555 
    556     pthread_mutex_lock(&g_intf_lock);
    557     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    558 
    559     if(my_obj) {
    560         pthread_mutex_lock(&my_obj->cam_lock);
    561         pthread_mutex_unlock(&g_intf_lock);
    562         rc = mm_camera_stop_streams(my_obj, ch_id,
    563                                     num_streams, stream_ids);
    564     } else {
    565         pthread_mutex_unlock(&g_intf_lock);
    566     }
    567     CDBG("%s :X rc = %d",__func__,rc);
    568     return rc;
    569 }
    570 
    571 static int32_t mm_camera_intf_async_teardown_streams(
    572                                     uint32_t camera_handler,
    573                                     uint32_t ch_id,
    574                                     uint8_t num_streams,
    575                                     uint32_t *stream_ids)
    576 {
    577     int32_t rc = -1;
    578     mm_camera_obj_t * my_obj = NULL;
    579 
    580     CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
    581          __func__,camera_handler,ch_id,num_streams);
    582 
    583     if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
    584         CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
    585                    __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
    586         return rc;
    587     }
    588 
    589     pthread_mutex_lock(&g_intf_lock);
    590     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    591 
    592     if(my_obj) {
    593         pthread_mutex_lock(&my_obj->cam_lock);
    594         pthread_mutex_unlock(&g_intf_lock);
    595         rc = mm_camera_async_teardown_streams(my_obj, ch_id,
    596                                               num_streams, stream_ids);
    597     } else {
    598         pthread_mutex_unlock(&g_intf_lock);
    599     }
    600     CDBG("%s :X rc = %d",__func__,rc);
    601     return rc;
    602 }
    603 
    604 static int32_t mm_camera_intf_request_super_buf(
    605                                     uint32_t camera_handler,
    606                                     uint32_t ch_id,
    607                                     uint32_t num_buf_requested)
    608 {
    609     int32_t rc = -1;
    610     CDBG("%s :E camera_handler = %d,ch_id = %d",
    611          __func__,camera_handler,ch_id);
    612     mm_camera_obj_t * my_obj = NULL;
    613 
    614     pthread_mutex_lock(&g_intf_lock);
    615     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    616 
    617     if(my_obj) {
    618         pthread_mutex_lock(&my_obj->cam_lock);
    619         pthread_mutex_unlock(&g_intf_lock);
    620         rc = mm_camera_request_super_buf(my_obj, ch_id, num_buf_requested);
    621     } else {
    622         pthread_mutex_unlock(&g_intf_lock);
    623     }
    624     CDBG("%s :X rc = %d",__func__,rc);
    625     return rc;
    626 }
    627 
    628 static int32_t mm_camera_intf_cancel_super_buf_request(
    629                                     uint32_t camera_handler,
    630                                     uint32_t ch_id)
    631 {
    632     int32_t rc = -1;
    633     mm_camera_obj_t * my_obj = NULL;
    634 
    635     CDBG("%s :E camera_handler = %d,ch_id = %d",
    636          __func__,camera_handler,ch_id);
    637     pthread_mutex_lock(&g_intf_lock);
    638     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    639 
    640     if(my_obj) {
    641         pthread_mutex_lock(&my_obj->cam_lock);
    642         pthread_mutex_unlock(&g_intf_lock);
    643         rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
    644     } else {
    645         pthread_mutex_unlock(&g_intf_lock);
    646     }
    647     CDBG("%s :X rc = %d",__func__,rc);
    648     return rc;
    649 }
    650 
    651 static int32_t mm_camera_intf_start_focus(
    652                                     uint32_t camera_handler,
    653                                     uint32_t ch_id,
    654                                     uint32_t sensor_idx,
    655                                     uint32_t focus_mode)
    656 {
    657     int32_t rc = -1;
    658     mm_camera_obj_t * my_obj = NULL;
    659 
    660     CDBG("%s :E camera_handler = %d,ch_id = %d, focus_mode = %d",
    661          __func__,camera_handler,ch_id,focus_mode);
    662     pthread_mutex_lock(&g_intf_lock);
    663     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    664 
    665     if(my_obj) {
    666         pthread_mutex_lock(&my_obj->cam_lock);
    667         pthread_mutex_unlock(&g_intf_lock);
    668         rc = mm_camera_start_focus(my_obj, ch_id, sensor_idx, focus_mode);
    669     } else {
    670         pthread_mutex_unlock(&g_intf_lock);
    671     }
    672     CDBG("%s :X rc = %d",__func__,rc);
    673     return rc;
    674 }
    675 
    676 static int32_t mm_camera_intf_abort_focus(
    677                                     uint32_t camera_handler,
    678                                     uint32_t ch_id,
    679                                     uint32_t sensor_idx)
    680 {
    681     int32_t rc = -1;
    682     mm_camera_obj_t * my_obj = NULL;
    683 
    684     pthread_mutex_lock(&g_intf_lock);
    685     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    686 
    687     if(my_obj) {
    688         pthread_mutex_lock(&my_obj->cam_lock);
    689         pthread_mutex_unlock(&g_intf_lock);
    690         rc = mm_camera_abort_focus(my_obj, ch_id, sensor_idx);
    691     } else {
    692         pthread_mutex_unlock(&g_intf_lock);
    693     }
    694     CDBG("%s :X rc = %d",__func__,rc);
    695     return rc;
    696 }
    697 
    698 static int32_t mm_camera_intf_prepare_snapshot(
    699                                     uint32_t camera_handler,
    700                                     uint32_t ch_id,
    701                                     uint32_t sensor_idx)
    702 {
    703     int32_t rc = -1;
    704     mm_camera_obj_t * my_obj = NULL;
    705 
    706     pthread_mutex_lock(&g_intf_lock);
    707     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    708 
    709     if(my_obj) {
    710         pthread_mutex_lock(&my_obj->cam_lock);
    711         pthread_mutex_unlock(&g_intf_lock);
    712         rc = mm_camera_prepare_snapshot(my_obj, ch_id, sensor_idx);
    713     } else {
    714         pthread_mutex_unlock(&g_intf_lock);
    715     }
    716     CDBG("%s :X rc = %d",__func__,rc);
    717     return rc;
    718 }
    719 
    720 static int32_t mm_camera_intf_set_stream_parm(
    721                                      uint32_t camera_handle,
    722                                      uint32_t ch_id,
    723                                      uint32_t s_id,
    724                                      mm_camera_stream_parm_t parm_type,
    725                                      void* p_value)
    726 {
    727     int32_t rc = -1;
    728     mm_camera_obj_t * my_obj = NULL;
    729 
    730     pthread_mutex_lock(&g_intf_lock);
    731     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    732 
    733     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__,
    734             camera_handle,ch_id,s_id,parm_type);
    735 
    736     if(my_obj) {
    737         pthread_mutex_lock(&my_obj->cam_lock);
    738         pthread_mutex_unlock(&g_intf_lock);
    739         rc = mm_camera_set_stream_parm(my_obj,ch_id,s_id,
    740                                        parm_type,
    741                                        p_value);
    742     }else{
    743         pthread_mutex_unlock(&g_intf_lock);
    744     }
    745     CDBG("%s :X rc = %d",__func__,rc);
    746     return rc;
    747 }
    748 
    749 static int32_t mm_camera_intf_get_stream_parm(
    750                                      uint32_t camera_handle,
    751                                      uint32_t ch_id,
    752                                      uint32_t s_id,
    753                                      mm_camera_stream_parm_t parm_type,
    754                                      void* p_value)
    755 {
    756     int32_t rc = -1;
    757     mm_camera_obj_t * my_obj = NULL;
    758 
    759     pthread_mutex_lock(&g_intf_lock);
    760     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    761 
    762     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__,
    763             camera_handle,ch_id,s_id,parm_type);
    764 
    765     if(my_obj) {
    766         pthread_mutex_lock(&my_obj->cam_lock);
    767         pthread_mutex_unlock(&g_intf_lock);
    768         rc = mm_camera_get_stream_parm(my_obj,ch_id,s_id,
    769                                        parm_type,
    770                                        p_value);
    771     }else{
    772         pthread_mutex_unlock(&g_intf_lock);
    773     }
    774 
    775     CDBG("%s :X rc = %d",__func__,rc);
    776     return rc;
    777 }
    778 
    779 static int32_t mm_camera_intf_send_private_ioctl(uint32_t camera_handle,
    780                                                  uint32_t cmd_id,
    781                                                  uint32_t cmd_length,
    782                                                  void *cmd)
    783 {
    784     int32_t rc = -1;
    785     mm_camera_obj_t *my_obj = NULL;
    786 
    787     pthread_mutex_lock(&g_oem_lock);
    788     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    789 
    790     if (my_obj) {
    791         rc = mm_camera_send_private_ioctl(my_obj, cmd_id, cmd_length, cmd);
    792     }
    793 
    794     pthread_mutex_unlock(&g_oem_lock);
    795     CDBG("%s :X rc = %d", __func__, rc);
    796     return rc;
    797 }
    798 
    799 static int32_t mm_camera_intf_send_native_cmd(uint32_t camera_handle,
    800                                               uint32_t cmd_id,
    801                                               uint32_t cmd_length,
    802                                               void *cmd)
    803 {
    804     int32_t rc = -1;
    805     mm_camera_obj_t *my_obj = NULL;
    806 
    807     pthread_mutex_lock(&g_intf_lock);
    808     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    809 
    810     if (!cmd) {
    811         CDBG_ERROR("%s Null cmd ", __func__);
    812         return -EINVAL;
    813     }
    814 
    815     if (my_obj) {
    816         pthread_mutex_lock(&my_obj->cam_lock);
    817         pthread_mutex_unlock(&g_intf_lock);
    818         switch(cmd_id) {
    819         case NATIVE_CMD_ID_SOCKET_MAP: {
    820             cam_sock_packet_t packet;
    821             memset(&packet, 0, sizeof(cam_sock_packet_t));
    822             memcpy(&packet.payload.frame_fd_map, cmd, sizeof(mm_camera_frame_map_type));
    823             if(packet.payload.frame_fd_map.is_hist) {
    824                 packet.msg_type = CAM_SOCK_MSG_TYPE_HIST_MAPPING;
    825             } else {
    826                 packet.msg_type = CAM_SOCK_MSG_TYPE_FD_MAPPING;
    827             }
    828             rc = mm_camera_util_sendmsg(my_obj, &packet,
    829                                       sizeof(cam_sock_packet_t),
    830                                       packet.payload.frame_fd_map.fd);
    831           }
    832           break;
    833         case NATIVE_CMD_ID_SOCKET_UNMAP: {
    834             cam_sock_packet_t packet;
    835             memset(&packet, 0, sizeof(cam_sock_packet_t));
    836             memcpy(&packet.payload.frame_fd_unmap, cmd, sizeof(mm_camera_frame_unmap_type));
    837             if(packet.payload.frame_fd_unmap.is_hist) {
    838                 packet.msg_type = CAM_SOCK_MSG_TYPE_HIST_UNMAPPING;
    839             } else {
    840                 packet.msg_type = CAM_SOCK_MSG_TYPE_FD_UNMAPPING;
    841             }
    842             rc = mm_camera_util_sendmsg(my_obj, &packet,
    843                                       sizeof(cam_sock_packet_t), 0);
    844           }
    845           break;
    846        case NATIVE_CMD_ID_IOCTL_CTRL:
    847            /* may switch to send through native ctrl cmd ioctl */
    848            rc = mm_camera_util_sendmsg(my_obj, cmd,
    849                                       cmd_length, 0);
    850 #if 0
    851            rc = mm_camera_send_native_ctrl_cmd(my_obj, cmd_id,
    852                                                 cmd_length, cmd);
    853 #endif
    854           break;
    855        default:
    856           CDBG_ERROR("%s Invalid native cmd id %d ", __func__, cmd_id);
    857           rc = -EINVAL;
    858           break;
    859         }
    860         pthread_mutex_unlock(&my_obj->cam_lock);
    861     } else {
    862         pthread_mutex_unlock(&g_intf_lock);
    863     }
    864 
    865     CDBG("%s :X rc = %d", __func__, rc);
    866     return rc;
    867 }
    868 
    869 static int32_t mm_camera_intf_send_cmd(uint32_t camera_handle,
    870                                        mm_camera_cmd_type_t cmd_type,
    871                                        uint32_t cmd_id,
    872                                        uint32_t cmd_length,
    873                                        void *cmd)
    874 {
    875     int32_t rc = -1;
    876 
    877     switch (cmd_type) {
    878     case MM_CAMERA_CMD_TYPE_PRIVATE:
    879         /* OEM private ioctl */
    880         rc = mm_camera_intf_send_private_ioctl(camera_handle, cmd_id, cmd_length, cmd);
    881         break;
    882     case MM_CAMERA_CMD_TYPE_NATIVE:
    883         rc = mm_camera_intf_send_native_cmd(camera_handle, cmd_id, cmd_length, cmd);
    884         break;
    885     }
    886 
    887     return rc;
    888 }
    889 
    890 static uint32_t mm_camera_intf_open_repro_isp(uint32_t camera_handle,
    891                                               uint32_t ch_id,
    892                                               mm_camera_repro_isp_type_t repro_isp_type)
    893 {
    894     int32_t rc = -1;
    895     mm_camera_obj_t * my_obj = NULL;
    896     uint32_t repro_isp_handle = 0;
    897 
    898     pthread_mutex_lock(&g_intf_lock);
    899     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    900 
    901     if(my_obj) {
    902         pthread_mutex_lock(&my_obj->cam_lock);
    903         pthread_mutex_unlock(&g_intf_lock);
    904         rc = mm_camera_open_repro_isp(my_obj,
    905                                      ch_id,
    906                                      repro_isp_type,
    907                                      &repro_isp_handle);
    908     }else{
    909         pthread_mutex_unlock(&g_intf_lock);
    910     }
    911 
    912     CDBG("%s :X rc = %d",__func__,rc);
    913     return repro_isp_handle;
    914 }
    915 
    916 static int32_t mm_camera_intf_config_repro_isp(uint32_t camera_handle,
    917                                                uint32_t ch_id,
    918                                                uint32_t repro_isp_handle,
    919                                                mm_camera_repro_isp_config_t *config)
    920 {
    921     int32_t rc = -1;
    922     mm_camera_obj_t * my_obj = NULL;
    923 
    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_config_repro_isp(my_obj,
    931                                         ch_id,
    932                                         repro_isp_handle,
    933                                         config);
    934     }else{
    935         pthread_mutex_unlock(&g_intf_lock);
    936     }
    937 
    938     CDBG("%s :X rc = %d",__func__,rc);
    939     return rc;
    940 }
    941 
    942 static int32_t mm_camera_intf_attach_stream_to_repro_isp(uint32_t camera_handle,
    943                                                          uint32_t ch_id,
    944                                                          uint32_t repro_isp_handle,
    945                                                          uint32_t stream_id)
    946 {
    947     int32_t rc = -1;
    948     mm_camera_obj_t * my_obj = NULL;
    949 
    950     pthread_mutex_lock(&g_intf_lock);
    951     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    952 
    953     if(my_obj) {
    954         pthread_mutex_lock(&my_obj->cam_lock);
    955         pthread_mutex_unlock(&g_intf_lock);
    956         rc = mm_camera_attach_stream_to_repro_isp(my_obj,
    957                                                   ch_id,
    958                                                   repro_isp_handle,
    959                                                   stream_id);
    960     }else{
    961         pthread_mutex_unlock(&g_intf_lock);
    962     }
    963 
    964     CDBG("%s :X rc = %d",__func__,rc);
    965     return rc;
    966 }
    967 
    968 static int32_t mm_camera_intf_start_repro_isp(uint32_t camera_handle,
    969                                               uint32_t ch_id,
    970                                               uint32_t repro_isp_handle,
    971                                               uint32_t stream_id)
    972 {
    973     int32_t rc = -1;
    974     mm_camera_obj_t * my_obj = NULL;
    975 
    976     pthread_mutex_lock(&g_intf_lock);
    977     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    978 
    979     if(my_obj) {
    980         pthread_mutex_lock(&my_obj->cam_lock);
    981         pthread_mutex_unlock(&g_intf_lock);
    982         rc = mm_camera_start_repro_isp(my_obj,
    983                                        ch_id,
    984                                        repro_isp_handle,
    985                                        stream_id);
    986     }else{
    987         pthread_mutex_unlock(&g_intf_lock);
    988     }
    989 
    990     CDBG("%s :X rc = %d",__func__,rc);
    991     return rc;
    992 }
    993 
    994 static int32_t mm_camera_intf_reprocess(uint32_t camera_handle,
    995                                         uint32_t ch_id,
    996                                         uint32_t repro_isp_handle,
    997                                         mm_camera_repro_data_t *repro_data)
    998 {
    999     int32_t rc = -1;
   1000     mm_camera_obj_t * my_obj = NULL;
   1001 
   1002     pthread_mutex_lock(&g_intf_lock);
   1003     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1004 
   1005     if(my_obj) {
   1006         pthread_mutex_lock(&my_obj->cam_lock);
   1007         pthread_mutex_unlock(&g_intf_lock);
   1008         rc = mm_camera_reprocess(my_obj,
   1009                                  ch_id,
   1010                                  repro_isp_handle,
   1011                                  repro_data);
   1012     }else{
   1013         pthread_mutex_unlock(&g_intf_lock);
   1014     }
   1015 
   1016     CDBG("%s :X rc = %d",__func__,rc);
   1017     return rc;
   1018 }
   1019 
   1020 static int32_t mm_camera_intf_stop_repro_isp(uint32_t camera_handle,
   1021                                              uint32_t ch_id,
   1022                                              uint32_t repro_isp_handle,
   1023                                              uint32_t stream_id)
   1024 {
   1025     int32_t rc = -1;
   1026     mm_camera_obj_t * my_obj = NULL;
   1027 
   1028     pthread_mutex_lock(&g_intf_lock);
   1029     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1030 
   1031     if(my_obj) {
   1032         pthread_mutex_lock(&my_obj->cam_lock);
   1033         pthread_mutex_unlock(&g_intf_lock);
   1034         rc = mm_camera_stop_repro_isp(my_obj,
   1035                                       ch_id,
   1036                                       repro_isp_handle,
   1037                                       stream_id);
   1038     }else{
   1039         pthread_mutex_unlock(&g_intf_lock);
   1040     }
   1041 
   1042     CDBG("%s :X rc = %d",__func__,rc);
   1043     return rc;
   1044 }
   1045 
   1046 static int32_t mm_camera_intf_detach_stream_from_repro_isp(uint32_t camera_handle,
   1047                                                            uint32_t ch_id,
   1048                                                            uint32_t repro_isp_handle,
   1049                                                            uint32_t stream_id)
   1050 {
   1051     int32_t rc = -1;
   1052     mm_camera_obj_t * my_obj = NULL;
   1053 
   1054     pthread_mutex_lock(&g_intf_lock);
   1055     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
   1056 
   1057     if(my_obj) {
   1058         pthread_mutex_lock(&my_obj->cam_lock);
   1059         pthread_mutex_unlock(&g_intf_lock);
   1060         rc = mm_camera_detach_stream_from_repro_isp(my_obj,
   1061                                                     ch_id,
   1062                                                     repro_isp_handle,
   1063                                                     stream_id);
   1064     }else{
   1065         pthread_mutex_unlock(&g_intf_lock);
   1066     }
   1067 
   1068     CDBG("%s :X rc = %d",__func__,rc);
   1069     return rc;
   1070 }
   1071 
   1072 static int32_t mm_camera_intf_close_repro_isp(uint32_t camera_handle,
   1073                                               uint32_t ch_id,
   1074                                               uint32_t repro_isp_handle)
   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     if(my_obj) {
   1083         pthread_mutex_lock(&my_obj->cam_lock);
   1084         pthread_mutex_unlock(&g_intf_lock);
   1085         rc = mm_camera_close_repro_isp(my_obj,
   1086                                        ch_id,
   1087                                        repro_isp_handle);
   1088     }else{
   1089         pthread_mutex_unlock(&g_intf_lock);
   1090     }
   1091 
   1092     CDBG("%s :X rc = %d",__func__,rc);
   1093     return rc;
   1094 }
   1095 
   1096 mm_camera_info_t * camera_query(uint8_t *num_cameras)
   1097 {
   1098     int i = 0, rc = 0;
   1099     int dev_fd = 0;
   1100     struct media_device_info mdev_info;
   1101     int num_media_devices = 0;
   1102     if (!num_cameras) {
   1103         CDBG_ERROR("%s: num_cameras is NULL\n", __func__);
   1104         return NULL;
   1105     }
   1106 
   1107     CDBG("%s : E",__func__);
   1108     /* lock the mutex */
   1109     pthread_mutex_lock(&g_intf_lock);
   1110     *num_cameras = 0;
   1111     while (1) {
   1112         char dev_name[32];
   1113         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
   1114         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
   1115         if (dev_fd < 0) {
   1116             CDBG("Done discovering media devices\n");
   1117             break;
   1118         }
   1119         num_media_devices++;
   1120         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
   1121         if (rc < 0) {
   1122             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
   1123             close(dev_fd);
   1124             break;
   1125         }
   1126 
   1127         if(strncmp(mdev_info.model, QCAMERA_NAME, sizeof(mdev_info.model) != 0)) {
   1128             close(dev_fd);
   1129             continue;
   1130         }
   1131 
   1132         char * mdev_cfg;
   1133         int cam_type = 0, mount_angle = 0, info_index = 0;
   1134         mdev_cfg = strtok(mdev_info.serial, "-");
   1135         while(mdev_cfg != NULL) {
   1136             if(info_index == 0) {
   1137                 if(strcmp(mdev_cfg, QCAMERA_NAME))
   1138                   break;
   1139             } else if(info_index == 1) {
   1140                 mount_angle = atoi(mdev_cfg);
   1141             } else if(info_index == 2) {
   1142                 cam_type = atoi(mdev_cfg);
   1143             }
   1144             mdev_cfg = strtok(NULL, "-");
   1145             info_index++;
   1146         }
   1147 
   1148         if(info_index == 0) {
   1149             close(dev_fd);
   1150             continue;
   1151         }
   1152 
   1153         int num_entities = 1;
   1154         while (1) {
   1155             struct media_entity_desc entity;
   1156             memset(&entity, 0, sizeof(entity));
   1157             entity.id = num_entities++;
   1158             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
   1159             if (rc < 0) {
   1160                 CDBG("Done enumerating media entities\n");
   1161                 rc = 0;
   1162                 break;
   1163             }
   1164             if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
   1165                 strncpy(g_cam_ctrl.video_dev_name[*num_cameras],
   1166                      entity.name, sizeof(entity.name));
   1167                 g_cam_ctrl.camera[*num_cameras].video_dev_name =
   1168                     &g_cam_ctrl.video_dev_name[*num_cameras][0];
   1169                 break;
   1170             }
   1171         }
   1172 
   1173         //g_cam_ctrl.camera[*num_cameras].camera_info.camera_id = *num_cameras;
   1174         g_cam_ctrl.camera[*num_cameras].camera_id = *num_cameras;
   1175 
   1176         g_cam_ctrl.camera[*num_cameras].
   1177             camera_info.modes_supported = CAMERA_MODE_2D;
   1178 
   1179         if(cam_type > 1) {
   1180             g_cam_ctrl.camera[*num_cameras].
   1181                 camera_info.modes_supported |= CAMERA_MODE_3D;
   1182         }
   1183 
   1184         g_cam_ctrl.camera[*num_cameras].camera_info.position =
   1185             (cam_type == 1) ? FRONT_CAMERA : BACK_CAMERA;
   1186 
   1187         g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle =
   1188             mount_angle;
   1189 
   1190         g_cam_ctrl.camera[*num_cameras].main_sensor_type = 0;
   1191 
   1192         CDBG("%s: dev_info[id=%d,name='%s',pos=%d,modes=0x%x,sensor=%d mount_angle = %d]\n",
   1193             __func__, *num_cameras,
   1194             g_cam_ctrl.camera[*num_cameras].video_dev_name,
   1195             g_cam_ctrl.camera[*num_cameras].camera_info.position,
   1196             g_cam_ctrl.camera[*num_cameras].camera_info.modes_supported,
   1197             g_cam_ctrl.camera[*num_cameras].main_sensor_type,
   1198             g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle);
   1199 
   1200         *num_cameras += 1;
   1201         if (dev_fd > 0) {
   1202             close(dev_fd);
   1203         }
   1204     }
   1205     *num_cameras = *num_cameras;
   1206     g_cam_ctrl.num_cam = *num_cameras;
   1207 
   1208     /* unlock the mutex */
   1209     pthread_mutex_unlock(&g_intf_lock);
   1210     CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
   1211     if(rc == 0)
   1212         return &g_cam_ctrl.camera[0];
   1213     else
   1214         return NULL;
   1215 }
   1216 
   1217 /* camera ops v-table */
   1218 static mm_camera_ops_t mm_camera_ops = {
   1219     .sync = mm_camera_intf_sync,
   1220     .is_event_supported = mm_camera_intf_is_event_supported,
   1221     .register_event_notify = mm_camera_intf_register_event_notify,
   1222     .qbuf = mm_camera_intf_qbuf,
   1223     .camera_close = mm_camera_intf_close,
   1224     .query_2nd_sensor_info = mm_camera_intf_query_2nd_sensor_info,
   1225     .is_op_supported = mm_camera_intf_is_op_supported,
   1226     .is_parm_supported = mm_camera_intf_is_parm_supported,
   1227     .set_parm = mm_camera_intf_set_parm,
   1228     .get_parm = mm_camera_intf_get_parm,
   1229     .ch_acquire = mm_camera_intf_add_channel,
   1230     .ch_release = mm_camera_intf_del_channel,
   1231     .add_stream = mm_camera_intf_add_stream,
   1232     .del_stream = mm_camera_intf_del_stream,
   1233     .config_stream = mm_camera_intf_config_stream,
   1234     .init_stream_bundle = mm_camera_intf_bundle_streams,
   1235     .destroy_stream_bundle = mm_camera_intf_destroy_bundle,
   1236     .start_streams = mm_camera_intf_start_streams,
   1237     .stop_streams = mm_camera_intf_stop_streams,
   1238     .async_teardown_streams = mm_camera_intf_async_teardown_streams,
   1239     .request_super_buf = mm_camera_intf_request_super_buf,
   1240     .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
   1241     .start_focus = mm_camera_intf_start_focus,
   1242     .abort_focus = mm_camera_intf_abort_focus,
   1243     .prepare_snapshot = mm_camera_intf_prepare_snapshot,
   1244     .set_stream_parm = mm_camera_intf_set_stream_parm,
   1245     .get_stream_parm = mm_camera_intf_get_stream_parm,
   1246     .send_command = mm_camera_intf_send_cmd,
   1247     .open_repro_isp = mm_camera_intf_open_repro_isp,
   1248     .config_repro_isp = mm_camera_intf_config_repro_isp,
   1249     .attach_stream_to_repro_isp = mm_camera_intf_attach_stream_to_repro_isp,
   1250     .start_repro_isp = mm_camera_intf_start_repro_isp,
   1251     .reprocess =  mm_camera_intf_reprocess,
   1252     .stop_repro_isp = mm_camera_intf_stop_repro_isp,
   1253     .detach_stream_from_repro_isp = mm_camera_intf_detach_stream_from_repro_isp,
   1254     .close_repro_isp = mm_camera_intf_close_repro_isp
   1255 };
   1256 
   1257 /* open camera. */
   1258 mm_camera_vtbl_t * camera_open(uint8_t camera_idx,
   1259                                mm_camear_mem_vtbl_t *mem_vtbl)
   1260 {
   1261     int32_t rc = 0;
   1262     mm_camera_obj_t* cam_obj = NULL;
   1263 
   1264     CDBG("%s: E camera_idx = %d\n", __func__,camera_idx);
   1265     if (MSM_MAX_CAMERA_SENSORS <= camera_idx) {
   1266         CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
   1267         return NULL;
   1268     }
   1269 
   1270     pthread_mutex_lock(&g_oem_lock);
   1271     pthread_mutex_lock(&g_intf_lock);
   1272     /* opened already */
   1273     if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
   1274         /* Add reference */
   1275         g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
   1276         pthread_mutex_unlock(&g_intf_lock);
   1277         pthread_mutex_unlock(&g_oem_lock);
   1278         CDBG("%s:  opened alreadyn", __func__);
   1279         return &cam_obj->vtbl;
   1280     }
   1281 
   1282     cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
   1283     if(NULL == cam_obj) {
   1284         pthread_mutex_unlock(&g_intf_lock);
   1285         pthread_mutex_unlock(&g_oem_lock);
   1286         CDBG("%s:  no mem", __func__);
   1287         return NULL;
   1288     }
   1289 
   1290     /* initialize camera obj */
   1291     memset(cam_obj, 0, sizeof(mm_camera_obj_t));
   1292     cam_obj->ctrl_fd = -1;
   1293     cam_obj->ds_fd = -1;
   1294     cam_obj->ref_count++;
   1295     cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
   1296     cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
   1297     cam_obj->vtbl.camera_info = &g_cam_ctrl.camera[camera_idx];
   1298     cam_obj->vtbl.ops = &mm_camera_ops;
   1299     cam_obj->mem_vtbl = mem_vtbl; /* save mem_vtbl */
   1300     pthread_mutex_init(&cam_obj->cam_lock, NULL);
   1301 
   1302     rc = mm_camera_open(cam_obj);
   1303     if(rc != 0) {
   1304         CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
   1305         pthread_mutex_destroy(&cam_obj->cam_lock);
   1306         g_cam_ctrl.cam_obj[camera_idx] = NULL;
   1307         free(cam_obj);
   1308         cam_obj = NULL;
   1309         pthread_mutex_unlock(&g_intf_lock);
   1310         pthread_mutex_unlock(&g_oem_lock);
   1311         return NULL;
   1312     }else{
   1313         CDBG("%s: Open succeded\n", __func__);
   1314         g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
   1315         pthread_mutex_unlock(&g_intf_lock);
   1316         pthread_mutex_unlock(&g_oem_lock);
   1317         return &cam_obj->vtbl;
   1318     }
   1319 }
   1320