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.h"
     43 
     44 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
     45 
     46 static mm_camera_ctrl_t g_cam_ctrl = {{{0, {0, 0, 0, 0}, 0, 0}}, 0, {{0}}, {0}};
     47 
     48 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
     49 static uint16_t g_handler_history_count = 0; /* history count for handler */
     50 
     51 /* utility function to generate handler */
     52 uint32_t mm_camera_util_generate_handler(uint8_t index)
     53 {
     54     uint32_t handler = 0;
     55     pthread_mutex_lock(&g_handler_lock);
     56     g_handler_history_count++;
     57     if (0 == g_handler_history_count) {
     58         g_handler_history_count++;
     59     }
     60     handler = g_handler_history_count;
     61     handler = (handler<<8) | index;
     62     pthread_mutex_unlock(&g_handler_lock);
     63     return handler;
     64 }
     65 
     66 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
     67 {
     68     return (handler&0x000000ff);
     69 }
     70 
     71 const char *mm_camera_util_get_dev_name(uint32_t cam_handler)
     72 {
     73     char *dev_name = NULL;
     74     uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler);
     75     dev_name = g_cam_ctrl.camera[cam_idx].video_dev_name;
     76     return dev_name;
     77 }
     78 
     79 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler)
     80 {
     81     mm_camera_obj_t *cam_obj = NULL;
     82     uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler);
     83 
     84     if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
     85         (cam_handler == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
     86         cam_obj = g_cam_ctrl.cam_obj[cam_idx];
     87     }
     88     return cam_obj;
     89 }
     90 
     91 static int32_t mm_camera_intf_sync(uint32_t camera_handler)
     92 {
     93     int32_t rc = -1;
     94     mm_camera_obj_t * my_obj = NULL;
     95 
     96     CDBG("%s E: camera_handler = %d ",__func__,camera_handler);
     97 
     98     pthread_mutex_lock(&g_intf_lock);
     99     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    100 
    101     if(my_obj) {
    102         pthread_mutex_lock(&my_obj->cam_lock);
    103         pthread_mutex_unlock(&g_intf_lock);
    104         rc = mm_camera_sync(my_obj);
    105     } else {
    106         pthread_mutex_unlock(&g_intf_lock);
    107     }
    108     CDBG("%s :X rc = %d",__func__,rc);
    109     return rc;
    110 }
    111 
    112 /* check if the parm is supported */
    113 static int32_t mm_camera_intf_is_parm_supported(uint32_t camera_handler,
    114                                    mm_camera_parm_type_t parm_type,
    115                                    uint8_t *support_set_parm,
    116                                    uint8_t *support_get_parm)
    117 {
    118     int32_t rc = -1;
    119     mm_camera_obj_t * my_obj = NULL;
    120 
    121     pthread_mutex_lock(&g_intf_lock);
    122     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    123     *support_set_parm = 0;
    124     *support_get_parm = 0;
    125 
    126     if(my_obj) {
    127         pthread_mutex_lock(&my_obj->cam_lock);
    128         pthread_mutex_unlock(&g_intf_lock);
    129         rc = mm_camera_is_parm_supported(my_obj, parm_type, support_set_parm, support_get_parm);
    130     } else {
    131         pthread_mutex_unlock(&g_intf_lock);
    132     }
    133     return rc;
    134 }
    135 
    136 /* set a parms current value */
    137 static int32_t mm_camera_intf_set_parm(uint32_t camera_handler,
    138                                    mm_camera_parm_type_t parm_type,
    139                                    void* p_value)
    140 {
    141     int32_t rc = -1;
    142     mm_camera_obj_t * my_obj = NULL;
    143 
    144     pthread_mutex_lock(&g_intf_lock);
    145     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    146 
    147     if(my_obj) {
    148         pthread_mutex_lock(&my_obj->cam_lock);
    149         pthread_mutex_unlock(&g_intf_lock);
    150         rc = mm_camera_set_parm(my_obj, parm_type, p_value);
    151     } else {
    152         pthread_mutex_unlock(&g_intf_lock);
    153     }
    154     return rc;
    155 }
    156 
    157 /* get a parms current value */
    158 static int32_t mm_camera_intf_get_parm(uint32_t camera_handler,
    159                                 mm_camera_parm_type_t parm_type,
    160                                 void* p_value)
    161 {
    162     int32_t rc = -1;
    163     mm_camera_obj_t * my_obj = NULL;
    164 
    165     pthread_mutex_lock(&g_intf_lock);
    166     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    167 
    168     if(my_obj) {
    169         pthread_mutex_lock(&my_obj->cam_lock);
    170         pthread_mutex_unlock(&g_intf_lock);
    171         rc = mm_camera_get_parm(my_obj, parm_type, p_value);
    172     } else {
    173         pthread_mutex_unlock(&g_intf_lock);
    174     }
    175     return rc;
    176 }
    177 
    178 static void mm_camera_intf_close(uint32_t camera_handler)
    179 {
    180     int32_t rc = -1;
    181     uint8_t cam_idx = camera_handler & 0x00ff;
    182     mm_camera_obj_t * my_obj = NULL;
    183 
    184     CDBG("%s E: camera_handler = %d ",__func__,camera_handler);
    185     pthread_mutex_lock(&g_intf_lock);
    186     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    187 
    188     if (my_obj){
    189         my_obj->ref_count--;
    190 
    191         if(my_obj->ref_count > 0) {
    192             /* still have reference to obj, return here */
    193             CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
    194             pthread_mutex_unlock(&g_intf_lock);
    195             return;
    196         }
    197 
    198         /* need close camera here as no other reference
    199          * first empty g_cam_ctrl's referent to cam_obj */
    200         g_cam_ctrl.cam_obj[cam_idx] = NULL;
    201 
    202         pthread_mutex_lock(&my_obj->cam_lock);
    203         pthread_mutex_unlock(&g_intf_lock);
    204 
    205         mm_camera_close(my_obj);
    206 
    207         pthread_mutex_destroy(&my_obj->cam_lock);
    208         free(my_obj);
    209 
    210     } else {
    211         pthread_mutex_unlock(&g_intf_lock);
    212     }
    213 }
    214 
    215 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handler)
    216 {
    217     uint32_t ch_id = 0;
    218     mm_camera_obj_t * my_obj = NULL;
    219 
    220     CDBG("%s :E camera_handler = %d",__func__,camera_handler);
    221     pthread_mutex_lock(&g_intf_lock);
    222     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    223 
    224     if(my_obj) {
    225         pthread_mutex_lock(&my_obj->cam_lock);
    226         pthread_mutex_unlock(&g_intf_lock);
    227         ch_id = mm_camera_add_channel(my_obj);
    228     } else {
    229         pthread_mutex_unlock(&g_intf_lock);
    230     }
    231     CDBG("%s :X ch_id = %d",__func__,ch_id);
    232     return ch_id;
    233 }
    234 
    235 static void mm_camera_intf_del_channel(uint32_t camera_handler, uint32_t ch_id)
    236 {
    237     mm_camera_obj_t * my_obj = NULL;
    238 
    239     CDBG("%s :E ch_id = %d",__func__,ch_id);
    240     pthread_mutex_lock(&g_intf_lock);
    241     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    242 
    243     if(my_obj) {
    244         pthread_mutex_lock(&my_obj->cam_lock);
    245         pthread_mutex_unlock(&g_intf_lock);
    246         mm_camera_del_channel(my_obj, ch_id);
    247     } else {
    248         pthread_mutex_unlock(&g_intf_lock);
    249     }
    250     CDBG("%s :X",__func__);
    251 }
    252 
    253 static uint8_t mm_camera_intf_is_event_supported(uint32_t camera_handler,
    254                                     mm_camera_event_type_t evt_type)
    255 {
    256     switch(evt_type) {
    257     case MM_CAMERA_EVT_TYPE_CH:
    258     case MM_CAMERA_EVT_TYPE_CTRL:
    259     case MM_CAMERA_EVT_TYPE_STATS:
    260     case MM_CAMERA_EVT_TYPE_INFO:
    261         return 1;
    262     default:
    263         return 0;
    264     }
    265     return 0;
    266 }
    267 
    268 static int32_t mm_camera_intf_register_event_notify(
    269                                     uint32_t camera_handler,
    270                                     mm_camera_event_notify_t evt_cb,
    271                                     void * user_data,
    272                                     mm_camera_event_type_t evt_type)
    273 {
    274     int32_t rc = -1;
    275     mm_camera_obj_t * my_obj = NULL;
    276 
    277     CDBG("%s :E evt_type = %d",__func__,evt_type);
    278     pthread_mutex_lock(&g_intf_lock);
    279     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    280 
    281     if(my_obj) {
    282         pthread_mutex_lock(&my_obj->cam_lock);
    283         pthread_mutex_unlock(&g_intf_lock);
    284         rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data, evt_type);
    285     } else {
    286         pthread_mutex_unlock(&g_intf_lock);
    287     }
    288     CDBG("%s :E rc = %d",__func__,rc);
    289     return rc;
    290 }
    291 
    292 static mm_camera_2nd_sensor_t * mm_camera_intf_query_2nd_sensor_info(uint32_t camera_handler)
    293 {
    294     mm_camera_2nd_sensor_t *sensor_info = NULL;
    295     mm_camera_obj_t * my_obj = NULL;
    296 
    297     CDBG("%s :E camera_handler = %d",__func__,camera_handler);
    298     pthread_mutex_lock(&g_intf_lock);
    299     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    300 
    301     if(my_obj) {
    302         pthread_mutex_lock(&my_obj->cam_lock);
    303         pthread_mutex_unlock(&g_intf_lock);
    304         sensor_info = mm_camera_query_2nd_sensor_info(my_obj);
    305     } else {
    306         pthread_mutex_unlock(&g_intf_lock);
    307     }
    308     CDBG("%s :X",__func__);
    309     return sensor_info;
    310 }
    311 
    312 static int32_t mm_camera_intf_qbuf(uint32_t camera_handler,
    313                                     uint32_t ch_id,
    314                                     mm_camera_buf_def_t *buf)
    315 {
    316     int32_t rc = -1;
    317     mm_camera_obj_t * my_obj = NULL;
    318 
    319     pthread_mutex_lock(&g_intf_lock);
    320     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    321 
    322     if(my_obj) {
    323         pthread_mutex_lock(&my_obj->cam_lock);
    324         pthread_mutex_unlock(&g_intf_lock);
    325         rc = mm_camera_qbuf(my_obj, ch_id, buf);
    326     } else {
    327         pthread_mutex_unlock(&g_intf_lock);
    328     }
    329     CDBG("%s :X evt_type = %d",__func__,rc);
    330     return rc;
    331 }
    332 
    333 static uint32_t mm_camera_intf_add_stream(
    334                                     uint32_t camera_handler,
    335                                     uint32_t ch_id,
    336                                     mm_camera_buf_notify_t buf_cb, void *user_data,
    337                                     uint32_t ext_image_mode, uint32_t sensor_idx)
    338 {
    339     uint32_t stream_id = 0;
    340     mm_camera_obj_t * my_obj = NULL;
    341 
    342     CDBG("%s : E handle = %d ch_id = %d",__func__,camera_handler,
    343          ch_id);
    344 
    345     pthread_mutex_lock(&g_intf_lock);
    346     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    347 
    348     if(my_obj) {
    349         pthread_mutex_lock(&my_obj->cam_lock);
    350         pthread_mutex_unlock(&g_intf_lock);
    351         stream_id = mm_camera_add_stream(my_obj, ch_id, buf_cb,
    352                                   user_data, ext_image_mode, sensor_idx);
    353     } else {
    354         pthread_mutex_unlock(&g_intf_lock);
    355     }
    356     CDBG("%s :X stream_id = %d",__func__,stream_id);
    357     return stream_id;
    358 }
    359 
    360 static int32_t mm_camera_intf_del_stream(
    361                                     uint32_t camera_handler,
    362                                     uint32_t ch_id,
    363                                     uint32_t stream_id)
    364 {
    365     int32_t rc = -1;
    366     mm_camera_obj_t * my_obj = NULL;
    367 
    368     CDBG("%s : E handle = %d ch_id = %d stream_id = %d",__func__,camera_handler,
    369          ch_id,stream_id);
    370 
    371     pthread_mutex_lock(&g_intf_lock);
    372     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    373 
    374     if(my_obj) {
    375         pthread_mutex_lock(&my_obj->cam_lock);
    376         pthread_mutex_unlock(&g_intf_lock);
    377         rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
    378     } else {
    379         pthread_mutex_unlock(&g_intf_lock);
    380     }
    381     CDBG("%s :X rc = %d",__func__,rc);
    382     return rc;
    383 }
    384 
    385 static int32_t mm_camera_intf_config_stream(
    386                                     uint32_t camera_handler,
    387                                     uint32_t ch_id,
    388                                     uint32_t stream_id,
    389                                     mm_camera_stream_config_t *config)
    390 {
    391     int32_t rc = -1;
    392     mm_camera_obj_t * my_obj = NULL;
    393 
    394     CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",__func__,
    395          camera_handler,ch_id,stream_id);
    396 
    397     pthread_mutex_lock(&g_intf_lock);
    398     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    399 
    400     CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
    401 
    402     if(my_obj) {
    403         pthread_mutex_lock(&my_obj->cam_lock);
    404         pthread_mutex_unlock(&g_intf_lock);
    405         rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
    406     } else {
    407         pthread_mutex_unlock(&g_intf_lock);
    408     }
    409     CDBG("%s :X rc = %d",__func__,rc);
    410     return rc;
    411 }
    412 
    413 static int32_t mm_camera_intf_bundle_streams(
    414                                     uint32_t camera_handler,
    415                                     uint32_t ch_id,
    416                                     mm_camera_buf_notify_t super_frame_notify_cb,
    417                                     void *user_data,
    418                                     mm_camera_bundle_attr_t *attr,
    419                                     uint8_t num_streams,
    420                                     uint32_t *stream_ids)
    421 {
    422     int32_t rc = -1;
    423     mm_camera_obj_t * my_obj = NULL;
    424 
    425     CDBG("%s :E handle = %d, ch_id = %d",__func__,
    426          camera_handler,ch_id);
    427 
    428     if (MM_CAMEAR_MAX_STRAEM_BUNDLE < num_streams) {
    429         CDBG_ERROR("%s: number of streams (%d) exceeds max (%d)",
    430                    __func__, num_streams, MM_CAMEAR_MAX_STRAEM_BUNDLE);
    431         return rc;
    432     }
    433 
    434     pthread_mutex_lock(&g_intf_lock);
    435     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    436 
    437     if(my_obj) {
    438         pthread_mutex_lock(&my_obj->cam_lock);
    439         pthread_mutex_unlock(&g_intf_lock);
    440         rc = mm_camera_bundle_streams(my_obj, ch_id,
    441                                       super_frame_notify_cb,
    442                                       user_data, attr,
    443                                       num_streams, stream_ids);
    444     } else {
    445         pthread_mutex_unlock(&g_intf_lock);
    446     }
    447     CDBG("%s :X rc = %d",__func__,rc);
    448     return rc;
    449 }
    450 
    451 static int32_t mm_camera_intf_destroy_bundle(uint32_t camera_handler,
    452                                     uint32_t ch_id)
    453 {
    454     int32_t rc = -1;
    455     mm_camera_obj_t * my_obj = NULL;
    456 
    457     CDBG("%s :E handle = %d, ch_id = %d",__func__,
    458          camera_handler,ch_id);
    459     pthread_mutex_lock(&g_intf_lock);
    460     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    461 
    462     if(my_obj) {
    463         pthread_mutex_lock(&my_obj->cam_lock);
    464         pthread_mutex_unlock(&g_intf_lock);
    465         rc = mm_camera_destroy_bundle(my_obj, ch_id);
    466     } else {
    467         pthread_mutex_unlock(&g_intf_lock);
    468     }
    469     CDBG("%s :X rc = %d",__func__,rc);
    470     return rc;
    471 }
    472 
    473 static int32_t mm_camera_intf_start_streams(
    474                                     uint32_t camera_handler,
    475                                     uint32_t ch_id,
    476                                     uint8_t num_streams,
    477                                     uint32_t *stream_ids)
    478 {
    479     int32_t rc = -1;
    480     mm_camera_obj_t * my_obj = NULL;
    481 
    482     CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
    483          __func__,camera_handler,ch_id,num_streams);
    484     if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
    485         CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
    486                    __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
    487         return rc;
    488     }
    489 
    490     pthread_mutex_lock(&g_intf_lock);
    491     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    492 
    493     if(my_obj) {
    494         pthread_mutex_lock(&my_obj->cam_lock);
    495         pthread_mutex_unlock(&g_intf_lock);
    496         rc = mm_camera_start_streams(my_obj, ch_id, num_streams, stream_ids);
    497     } else {
    498         pthread_mutex_unlock(&g_intf_lock);
    499     }
    500     CDBG("%s :X rc = %d",__func__,rc);
    501     return rc;
    502 }
    503 
    504 static int32_t mm_camera_intf_stop_streams(
    505                                     uint32_t camera_handler,
    506                                     uint32_t ch_id,
    507                                     uint8_t num_streams,
    508                                     uint32_t *stream_ids)
    509 {
    510     int32_t rc = -1;
    511     mm_camera_obj_t * my_obj = NULL;
    512 
    513     CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
    514          __func__,camera_handler,ch_id,num_streams);
    515 
    516     if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
    517         CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
    518                    __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
    519         return rc;
    520     }
    521 
    522     pthread_mutex_lock(&g_intf_lock);
    523     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    524 
    525     if(my_obj) {
    526         pthread_mutex_lock(&my_obj->cam_lock);
    527         pthread_mutex_unlock(&g_intf_lock);
    528         rc = mm_camera_stop_streams(my_obj, ch_id,
    529                                     num_streams, stream_ids);
    530     } else {
    531         pthread_mutex_unlock(&g_intf_lock);
    532     }
    533     CDBG("%s :X rc = %d",__func__,rc);
    534     return rc;
    535 }
    536 
    537 static int32_t mm_camera_intf_async_teardown_streams(
    538                                     uint32_t camera_handler,
    539                                     uint32_t ch_id,
    540                                     uint8_t num_streams,
    541                                     uint32_t *stream_ids)
    542 {
    543     int32_t rc = -1;
    544     mm_camera_obj_t * my_obj = NULL;
    545 
    546     CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
    547          __func__,camera_handler,ch_id,num_streams);
    548 
    549     if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
    550         CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
    551                    __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
    552         return rc;
    553     }
    554 
    555     pthread_mutex_lock(&g_intf_lock);
    556     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    557 
    558     if(my_obj) {
    559         pthread_mutex_lock(&my_obj->cam_lock);
    560         pthread_mutex_unlock(&g_intf_lock);
    561         rc = mm_camera_async_teardown_streams(my_obj, ch_id,
    562                                               num_streams, stream_ids);
    563     } else {
    564         pthread_mutex_unlock(&g_intf_lock);
    565     }
    566     CDBG("%s :X rc = %d",__func__,rc);
    567     return rc;
    568 }
    569 
    570 static int32_t mm_camera_intf_request_super_buf(
    571                                     uint32_t camera_handler,
    572                                     uint32_t ch_id)
    573 {
    574     int32_t rc = -1;
    575     CDBG("%s :E camera_handler = %d,ch_id = %d",
    576          __func__,camera_handler,ch_id);
    577     mm_camera_obj_t * my_obj = NULL;
    578 
    579     pthread_mutex_lock(&g_intf_lock);
    580     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    581 
    582     if(my_obj) {
    583         pthread_mutex_lock(&my_obj->cam_lock);
    584         pthread_mutex_unlock(&g_intf_lock);
    585         rc = mm_camera_request_super_buf(my_obj, ch_id);
    586     } else {
    587         pthread_mutex_unlock(&g_intf_lock);
    588     }
    589     CDBG("%s :X rc = %d",__func__,rc);
    590     return rc;
    591 }
    592 
    593 static int32_t mm_camera_intf_cancel_super_buf_request(
    594                                     uint32_t camera_handler,
    595                                     uint32_t ch_id)
    596 {
    597     int32_t rc = -1;
    598     mm_camera_obj_t * my_obj = NULL;
    599 
    600     CDBG("%s :E camera_handler = %d,ch_id = %d",
    601          __func__,camera_handler,ch_id);
    602     pthread_mutex_lock(&g_intf_lock);
    603     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    604 
    605     if(my_obj) {
    606         pthread_mutex_lock(&my_obj->cam_lock);
    607         pthread_mutex_unlock(&g_intf_lock);
    608         rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
    609     } else {
    610         pthread_mutex_unlock(&g_intf_lock);
    611     }
    612     CDBG("%s :X rc = %d",__func__,rc);
    613     return rc;
    614 }
    615 
    616 static int32_t mm_camera_intf_start_focus(
    617                                     uint32_t camera_handler,
    618                                     uint32_t ch_id,
    619                                     uint32_t sensor_idx,
    620                                     uint32_t focus_mode)
    621 {
    622     int32_t rc = -1;
    623     mm_camera_obj_t * my_obj = NULL;
    624 
    625     CDBG("%s :E camera_handler = %d,ch_id = %d, focus_mode = %d",
    626          __func__,camera_handler,ch_id,focus_mode);
    627     pthread_mutex_lock(&g_intf_lock);
    628     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    629 
    630     if(my_obj) {
    631         pthread_mutex_lock(&my_obj->cam_lock);
    632         pthread_mutex_unlock(&g_intf_lock);
    633         rc = mm_camera_start_focus(my_obj, ch_id, sensor_idx, focus_mode);
    634     } else {
    635         pthread_mutex_unlock(&g_intf_lock);
    636     }
    637     CDBG("%s :X rc = %d",__func__,rc);
    638     return rc;
    639 }
    640 
    641 static int32_t mm_camera_intf_abort_focus(
    642                                     uint32_t camera_handler,
    643                                     uint32_t ch_id,
    644                                     uint32_t sensor_idx)
    645 {
    646     int32_t rc = -1;
    647     mm_camera_obj_t * my_obj = NULL;
    648 
    649     pthread_mutex_lock(&g_intf_lock);
    650     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    651 
    652     if(my_obj) {
    653         pthread_mutex_lock(&my_obj->cam_lock);
    654         pthread_mutex_unlock(&g_intf_lock);
    655         rc = mm_camera_abort_focus(my_obj, ch_id, sensor_idx);
    656     } else {
    657         pthread_mutex_unlock(&g_intf_lock);
    658     }
    659     CDBG("%s :X rc = %d",__func__,rc);
    660     return rc;
    661 }
    662 
    663 static int32_t mm_camera_intf_prepare_snapshot(
    664                                     uint32_t camera_handler,
    665                                     uint32_t ch_id,
    666                                     uint32_t sensor_idx)
    667 {
    668     int32_t rc = -1;
    669     mm_camera_obj_t * my_obj = NULL;
    670 
    671     pthread_mutex_lock(&g_intf_lock);
    672     my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
    673 
    674     if(my_obj) {
    675         pthread_mutex_lock(&my_obj->cam_lock);
    676         pthread_mutex_unlock(&g_intf_lock);
    677         rc = mm_camera_prepare_snapshot(my_obj, ch_id, sensor_idx);
    678     } else {
    679         pthread_mutex_unlock(&g_intf_lock);
    680     }
    681     CDBG("%s :X rc = %d",__func__,rc);
    682     return rc;
    683 }
    684 
    685 static int32_t mm_camera_intf_set_stream_parm(
    686                                      uint32_t camera_handle,
    687                                      uint32_t ch_id,
    688                                      uint32_t s_id,
    689                                      mm_camera_stream_parm_t parm_type,
    690                                      void* p_value)
    691 {
    692     int32_t rc = -1;
    693     mm_camera_obj_t * my_obj = NULL;
    694 
    695     pthread_mutex_lock(&g_intf_lock);
    696     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    697 
    698     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__,
    699             camera_handle,ch_id,s_id,parm_type);
    700 
    701     if(my_obj) {
    702         pthread_mutex_lock(&my_obj->cam_lock);
    703         pthread_mutex_unlock(&g_intf_lock);
    704         rc = mm_camera_set_stream_parm(my_obj,ch_id,s_id,
    705                                        parm_type,
    706                                        p_value);
    707     }else{
    708         pthread_mutex_unlock(&g_intf_lock);
    709     }
    710     CDBG("%s :X rc = %d",__func__,rc);
    711     return rc;
    712 }
    713 
    714 static int32_t mm_camera_intf_get_stream_parm(
    715                                      uint32_t camera_handle,
    716                                      uint32_t ch_id,
    717                                      uint32_t s_id,
    718                                      mm_camera_stream_parm_t parm_type,
    719                                      void* p_value)
    720 {
    721     int32_t rc = -1;
    722     mm_camera_obj_t * my_obj = NULL;
    723 
    724     pthread_mutex_lock(&g_intf_lock);
    725     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
    726 
    727     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__,
    728             camera_handle,ch_id,s_id,parm_type);
    729 
    730     if(my_obj) {
    731         pthread_mutex_lock(&my_obj->cam_lock);
    732         pthread_mutex_unlock(&g_intf_lock);
    733         rc = mm_camera_get_stream_parm(my_obj,ch_id,s_id,
    734                                        parm_type,
    735                                        p_value);
    736     }else{
    737         pthread_mutex_unlock(&g_intf_lock);
    738     }
    739 
    740     CDBG("%s :X rc = %d",__func__,rc);
    741     return rc;
    742 }
    743 mm_camera_info_t * camera_query(uint8_t *num_cameras)
    744 {
    745     int i = 0, rc = 0;
    746     int dev_fd = 0;
    747     struct media_device_info mdev_info;
    748     int num_media_devices = 0;
    749     if (!num_cameras) {
    750         CDBG_ERROR("%s: num_cameras is NULL\n", __func__);
    751         return NULL;
    752     }
    753 
    754     CDBG("%s : E",__func__);
    755     /* lock the mutex */
    756     pthread_mutex_lock(&g_intf_lock);
    757     *num_cameras = 0;
    758     while (1) {
    759         char dev_name[32];
    760         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
    761         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
    762         if (dev_fd < 0) {
    763             CDBG("Done discovering media devices\n");
    764             break;
    765         }
    766         num_media_devices++;
    767         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
    768         if (rc < 0) {
    769             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
    770             close(dev_fd);
    771             break;
    772         }
    773 
    774         if(strncmp(mdev_info.model, QCAMERA_NAME, sizeof(mdev_info.model) != 0)) {
    775             close(dev_fd);
    776             continue;
    777         }
    778 
    779         char * mdev_cfg;
    780         int cam_type = 0, mount_angle = 0, info_index = 0;
    781         mdev_cfg = strtok(mdev_info.serial, "-");
    782         while(mdev_cfg != NULL) {
    783             if(info_index == 0) {
    784                 if(strcmp(mdev_cfg, QCAMERA_NAME))
    785                   break;
    786             } else if(info_index == 1) {
    787                 mount_angle = atoi(mdev_cfg);
    788             } else if(info_index == 2) {
    789                 cam_type = atoi(mdev_cfg);
    790             }
    791             mdev_cfg = strtok(NULL, "-");
    792             info_index++;
    793         }
    794 
    795         if(info_index == 0) {
    796             close(dev_fd);
    797             continue;
    798         }
    799 
    800         int num_entities = 1;
    801         while (1) {
    802             struct media_entity_desc entity;
    803             memset(&entity, 0, sizeof(entity));
    804             entity.id = num_entities++;
    805             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
    806             if (rc < 0) {
    807                 CDBG("Done enumerating media entities\n");
    808                 rc = 0;
    809                 break;
    810             }
    811             if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
    812                 strncpy(g_cam_ctrl.video_dev_name[*num_cameras],
    813                      entity.name, sizeof(entity.name));
    814                 g_cam_ctrl.camera[*num_cameras].video_dev_name =
    815                     &g_cam_ctrl.video_dev_name[*num_cameras][0];
    816                 break;
    817             }
    818         }
    819 
    820         //g_cam_ctrl.camera[*num_cameras].camera_info.camera_id = *num_cameras;
    821         g_cam_ctrl.camera[*num_cameras].camera_id = *num_cameras;
    822 
    823         g_cam_ctrl.camera[*num_cameras].
    824             camera_info.modes_supported = CAMERA_MODE_2D;
    825 
    826         if(cam_type > 1) {
    827             g_cam_ctrl.camera[*num_cameras].
    828                 camera_info.modes_supported |= CAMERA_MODE_3D;
    829         }
    830 
    831         g_cam_ctrl.camera[*num_cameras].camera_info.position =
    832             (cam_type == 1) ? FRONT_CAMERA : BACK_CAMERA;
    833 
    834         g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle =
    835             mount_angle;
    836 
    837         g_cam_ctrl.camera[*num_cameras].main_sensor_type = 0;
    838 
    839         CDBG("%s: dev_info[id=%d,name='%s',pos=%d,modes=0x%x,sensor=%d mount_angle = %d]\n",
    840             __func__, *num_cameras,
    841             g_cam_ctrl.camera[*num_cameras].video_dev_name,
    842             g_cam_ctrl.camera[*num_cameras].camera_info.position,
    843             g_cam_ctrl.camera[*num_cameras].camera_info.modes_supported,
    844             g_cam_ctrl.camera[*num_cameras].main_sensor_type,
    845             g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle);
    846 
    847         *num_cameras += 1;
    848         if (dev_fd > 0) {
    849             close(dev_fd);
    850         }
    851     }
    852     *num_cameras = *num_cameras;
    853     g_cam_ctrl.num_cam = *num_cameras;
    854 
    855     /* unlock the mutex */
    856     pthread_mutex_unlock(&g_intf_lock);
    857     CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
    858     if(rc == 0)
    859         return &g_cam_ctrl.camera[0];
    860     else
    861         return NULL;
    862 }
    863 
    864 /* camera ops v-table */
    865 static mm_camera_ops_t mm_camera_ops = {
    866     .sync = mm_camera_intf_sync,
    867     .is_event_supported = mm_camera_intf_is_event_supported,
    868     .register_event_notify = mm_camera_intf_register_event_notify,
    869     .qbuf = mm_camera_intf_qbuf,
    870     .camera_close = mm_camera_intf_close,
    871     .query_2nd_sensor_info = mm_camera_intf_query_2nd_sensor_info,
    872     .is_parm_supported = mm_camera_intf_is_parm_supported,
    873     .set_parm = mm_camera_intf_set_parm,
    874     .get_parm = mm_camera_intf_get_parm,
    875     .ch_acquire = mm_camera_intf_add_channel,
    876     .ch_release = mm_camera_intf_del_channel,
    877     .add_stream = mm_camera_intf_add_stream,
    878     .del_stream = mm_camera_intf_del_stream,
    879     .config_stream = mm_camera_intf_config_stream,
    880     .init_stream_bundle = mm_camera_intf_bundle_streams,
    881     .destroy_stream_bundle = mm_camera_intf_destroy_bundle,
    882     .start_streams = mm_camera_intf_start_streams,
    883     .stop_streams = mm_camera_intf_stop_streams,
    884     .async_teardown_streams = mm_camera_intf_async_teardown_streams,
    885     .request_super_buf = mm_camera_intf_request_super_buf,
    886     .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
    887     .start_focus = mm_camera_intf_start_focus,
    888     .abort_focus = mm_camera_intf_abort_focus,
    889     .prepare_snapshot = mm_camera_intf_prepare_snapshot,
    890     .set_stream_parm = mm_camera_intf_set_stream_parm,
    891     .get_stream_parm = mm_camera_intf_get_stream_parm
    892 };
    893 
    894 /* open camera. */
    895 mm_camera_vtbl_t * camera_open(uint8_t camera_idx,
    896                                mm_camear_mem_vtbl_t *mem_vtbl)
    897 {
    898     int32_t rc = 0;
    899     mm_camera_obj_t* cam_obj = NULL;
    900 
    901     CDBG("%s: E camera_idx = %d\n", __func__,camera_idx);
    902     if (MSM_MAX_CAMERA_SENSORS <= camera_idx) {
    903         CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
    904         return NULL;
    905     }
    906 
    907     pthread_mutex_lock(&g_intf_lock);
    908     /* opened already */
    909     if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
    910         /* Add reference */
    911         g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
    912         pthread_mutex_unlock(&g_intf_lock);
    913         CDBG("%s:  opened alreadyn", __func__);
    914         return &cam_obj->vtbl;
    915     }
    916 
    917     cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
    918     if(NULL == cam_obj) {
    919         pthread_mutex_unlock(&g_intf_lock);
    920         CDBG("%s:  no mem", __func__);
    921         return NULL;
    922     }
    923 
    924     /* initialize camera obj */
    925     memset(cam_obj, 0, sizeof(mm_camera_obj_t));
    926     cam_obj->ctrl_fd = -1;
    927     cam_obj->ds_fd = -1;
    928     cam_obj->ref_count++;
    929     cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
    930     cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
    931     cam_obj->vtbl.camera_info = &g_cam_ctrl.camera[camera_idx];
    932     cam_obj->vtbl.ops = &mm_camera_ops;
    933     cam_obj->mem_vtbl = mem_vtbl; /* save mem_vtbl */
    934     pthread_mutex_init(&cam_obj->cam_lock, NULL);
    935 
    936     rc = mm_camera_open(cam_obj);
    937     if(rc != 0) {
    938         CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
    939         pthread_mutex_destroy(&cam_obj->cam_lock);
    940         g_cam_ctrl.cam_obj[camera_idx] = NULL;
    941         free(cam_obj);
    942         cam_obj = NULL;
    943         pthread_mutex_unlock(&g_intf_lock);
    944         return NULL;
    945     }else{
    946         CDBG("%s: Open succeded\n", __func__);
    947         g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
    948         pthread_mutex_unlock(&g_intf_lock);
    949         return &cam_obj->vtbl;
    950     }
    951 }
    952