Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2016, The Linux Foundation. All rights reserved.
      2  *
      3  * Redistribution and use in source and binary forms, with or without
      4  * modification, are permitted provided that the following conditions are
      5  * met:
      6  *     * Redistributions of source code must retain the above copyright
      7  *       notice, this list of conditions and the following disclaimer.
      8  *     * Redistributions in binary form must reproduce the above
      9  *       copyright notice, this list of conditions and the following
     10  *       disclaimer in the documentation and/or other materials provided
     11  *       with the distribution.
     12  *     * Neither the name of The Linux Foundation nor the names of its
     13  *       contributors may be used to endorse or promote products derived
     14  *       from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27  *
     28  */
     29 
     30 // To remove
     31 #include <cutils/properties.h>
     32 
     33 // System dependencies
     34 #include <pthread.h>
     35 #include <errno.h>
     36 #include <fcntl.h>
     37 #include <stdlib.h>
     38 #include <dlfcn.h>
     39 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
     40 #include IOCTL_H
     41 
     42 // Camera dependencies
     43 #include "cam_semaphore.h"
     44 #include "mm_camera_dbg.h"
     45 #include "mm_camera_sock.h"
     46 #include "mm_camera_interface.h"
     47 #include "mm_camera.h"
     48 #include "cam_cond.h"
     49 
     50 #define SET_PARM_BIT32(parm, parm_arr) \
     51     (parm_arr[parm/32] |= (1<<(parm%32)))
     52 
     53 #define GET_PARM_BIT32(parm, parm_arr) \
     54     ((parm_arr[parm/32]>>(parm%32))& 0x1)
     55 
     56 /* internal function declare */
     57 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
     58                           uint8_t reg_flag);
     59 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
     60                               mm_camera_event_t *event);
     61 extern mm_camera_obj_t* mm_camera_util_get_camera_by_session_id
     62         (uint32_t session_id);
     63 
     64 /*===========================================================================
     65  * FUNCTION   : mm_camera_util_get_channel_by_handler
     66  *
     67  * DESCRIPTION: utility function to get a channel object from its handle
     68  *
     69  * PARAMETERS :
     70  *   @cam_obj: ptr to a camera object
     71  *   @handler: channel handle
     72  *
     73  * RETURN     : ptr to a channel object.
     74  *              NULL if failed.
     75  *==========================================================================*/
     76 mm_channel_t * mm_camera_util_get_channel_by_handler(
     77                                     mm_camera_obj_t * cam_obj,
     78                                     uint32_t handler)
     79 {
     80     int i;
     81     mm_channel_t *ch_obj = NULL;
     82     for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
     83         if (handler == cam_obj->ch[i].my_hdl) {
     84             ch_obj = &cam_obj->ch[i];
     85             break;
     86         }
     87     }
     88     return ch_obj;
     89 }
     90 
     91 /*===========================================================================
     92  * FUNCTION   : mm_camera_util_chip_is_a_family
     93  *
     94  * DESCRIPTION: utility function to check if the host is A family chip
     95  *
     96  * PARAMETERS :
     97  *
     98  * RETURN     : TRUE if A family.
     99  *              FALSE otherwise.
    100  *==========================================================================*/
    101 uint8_t mm_camera_util_chip_is_a_family(void)
    102 {
    103 #ifdef USE_A_FAMILY
    104     return TRUE;
    105 #else
    106     return FALSE;
    107 #endif
    108 }
    109 
    110 /*===========================================================================
    111  * FUNCTION   : mm_camera_dispatch_app_event
    112  *
    113  * DESCRIPTION: dispatch event to apps who regitster for event notify
    114  *
    115  * PARAMETERS :
    116  *   @cmd_cb: ptr to a struct storing event info
    117  *   @user_data: user data ptr (camera object)
    118  *
    119  * RETURN     : none
    120  *==========================================================================*/
    121 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
    122                                          void* user_data)
    123 {
    124     int i;
    125     mm_camera_event_t *event = &cmd_cb->u.evt;
    126     mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data;
    127     if (NULL != my_obj) {
    128         mm_camera_cmd_thread_name(my_obj->evt_thread.threadName);
    129         pthread_mutex_lock(&my_obj->cb_lock);
    130         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
    131             if(my_obj->evt.evt[i].evt_cb) {
    132                 my_obj->evt.evt[i].evt_cb(
    133                     my_obj->my_hdl,
    134                     event,
    135                     my_obj->evt.evt[i].user_data);
    136             }
    137         }
    138         pthread_mutex_unlock(&my_obj->cb_lock);
    139     }
    140 }
    141 
    142 /*===========================================================================
    143  * FUNCTION   : mm_camera_event_notify
    144  *
    145  * DESCRIPTION: callback to handle event notify from kernel. This call will
    146  *              dequeue event from kernel.
    147  *
    148  * PARAMETERS :
    149  *   @user_data: user data ptr (camera object)
    150  *
    151  * RETURN     : none
    152  *==========================================================================*/
    153 static void mm_camera_event_notify(void* user_data)
    154 {
    155     struct v4l2_event ev;
    156     struct msm_v4l2_event_data *msm_evt = NULL;
    157     int rc;
    158     mm_camera_event_t evt;
    159     memset(&evt, 0, sizeof(mm_camera_event_t));
    160 
    161     mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
    162     if (NULL != my_obj) {
    163         /* read evt */
    164         memset(&ev, 0, sizeof(ev));
    165         rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
    166 
    167         if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
    168             msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
    169             switch (msm_evt->command) {
    170             case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
    171                 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ;
    172                 mm_camera_enqueue_evt(my_obj, &evt);
    173                 break;
    174             case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
    175                 pthread_mutex_lock(&my_obj->evt_lock);
    176                 my_obj->evt_rcvd.server_event_type = msm_evt->command;
    177                 my_obj->evt_rcvd.status = msm_evt->status;
    178                 pthread_cond_signal(&my_obj->evt_cond);
    179                 pthread_mutex_unlock(&my_obj->evt_lock);
    180                 break;
    181             case CAM_EVENT_TYPE_INT_TAKE_JPEG:
    182             case CAM_EVENT_TYPE_INT_TAKE_RAW:
    183                 {
    184                     evt.server_event_type = msm_evt->command;
    185                     mm_camera_enqueue_evt(my_obj, &evt);
    186                 }
    187                 break;
    188             case MSM_CAMERA_PRIV_SHUTDOWN:
    189                 {
    190                     LOGE("Camera Event DAEMON DIED received");
    191                     evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
    192                     mm_camera_enqueue_evt(my_obj, &evt);
    193                 }
    194                 break;
    195             case CAM_EVENT_TYPE_CAC_DONE:
    196                 {
    197                     evt.server_event_type = CAM_EVENT_TYPE_CAC_DONE;
    198                     mm_camera_enqueue_evt(my_obj, &evt);
    199                 }
    200                 break;
    201             default:
    202                 break;
    203             }
    204         }
    205     }
    206 }
    207 
    208 /*===========================================================================
    209  * FUNCTION   : mm_camera_enqueue_evt
    210  *
    211  * DESCRIPTION: enqueue received event into event queue to be processed by
    212  *              event thread.
    213  *
    214  * PARAMETERS :
    215  *   @my_obj   : ptr to a camera object
    216  *   @event    : event to be queued
    217  *
    218  * RETURN     : int32_t type of status
    219  *              0  -- success
    220  *              -1 -- failure
    221  *==========================================================================*/
    222 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
    223                               mm_camera_event_t *event)
    224 {
    225     int32_t rc = 0;
    226     mm_camera_cmdcb_t *node = NULL;
    227 
    228     node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    229     if (NULL != node) {
    230         memset(node, 0, sizeof(mm_camera_cmdcb_t));
    231         node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
    232         node->u.evt = *event;
    233 
    234         /* enqueue to evt cmd thread */
    235         cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
    236         /* wake up evt cmd thread */
    237         cam_sem_post(&(my_obj->evt_thread.cmd_sem));
    238     } else {
    239         LOGE("No memory for mm_camera_node_t");
    240         rc = -1;
    241     }
    242 
    243     return rc;
    244 }
    245 
    246 /*===========================================================================
    247  * FUNCTION   : mm_camera_open
    248  *
    249  * DESCRIPTION: open a camera
    250  *
    251  * PARAMETERS :
    252  *   @my_obj   : ptr to a camera object
    253  *
    254  * RETURN     : int32_t type of status
    255  *              0  -- success
    256  *              -1 -- failure
    257  *==========================================================================*/
    258 int32_t mm_camera_open(mm_camera_obj_t *my_obj)
    259 {
    260     char dev_name[MM_CAMERA_DEV_NAME_LEN];
    261     int32_t rc = 0;
    262     int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
    263     uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
    264     int cam_idx = 0;
    265     const char *dev_name_value = NULL;
    266     int l_errno = 0;
    267 
    268     LOGD("begin\n");
    269 
    270     if (NULL == my_obj) {
    271         goto on_error;
    272     }
    273     dev_name_value = mm_camera_util_get_dev_name(my_obj->my_hdl);
    274     if (NULL == dev_name_value) {
    275         goto on_error;
    276     }
    277     snprintf(dev_name, sizeof(dev_name), "/dev/%s",
    278              dev_name_value);
    279     sscanf(dev_name, "/dev/video%d", &cam_idx);
    280     LOGD("dev name = %s, cam_idx = %d", dev_name, cam_idx);
    281 
    282     do{
    283         n_try--;
    284         errno = 0;
    285         my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
    286         l_errno = errno;
    287         LOGD("ctrl_fd = %d, errno == %d", my_obj->ctrl_fd, l_errno);
    288         if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) {
    289             break;
    290         }
    291         LOGE("Failed with %s error, retrying after %d milli-seconds",
    292               strerror(errno), sleep_msec);
    293         usleep(sleep_msec * 1000U);
    294     }while (n_try > 0);
    295 
    296     if (my_obj->ctrl_fd < 0) {
    297         LOGE("cannot open control fd of '%s' (%s)\n",
    298                   dev_name, strerror(l_errno));
    299         if (l_errno == EBUSY)
    300             rc = -EUSERS;
    301         else
    302             rc = -1;
    303         goto on_error;
    304     } else {
    305         mm_camera_get_session_id(my_obj, &my_obj->sessionid);
    306         LOGH("Camera Opened id = %d sessionid = %d", cam_idx, my_obj->sessionid);
    307     }
    308 
    309 #ifdef DAEMON_PRESENT
    310     /* open domain socket*/
    311     n_try = MM_CAMERA_DEV_OPEN_TRIES;
    312     do {
    313         n_try--;
    314         my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
    315         l_errno = errno;
    316         LOGD("ds_fd = %d, errno = %d", my_obj->ds_fd, l_errno);
    317         if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {
    318             LOGD("opened, break out while loop");
    319             break;
    320         }
    321         LOGD("failed with I/O error retrying after %d milli-seconds",
    322               sleep_msec);
    323         usleep(sleep_msec * 1000U);
    324     } while (n_try > 0);
    325 
    326     if (my_obj->ds_fd < 0) {
    327         LOGE("cannot open domain socket fd of '%s'(%s)\n",
    328                   dev_name, strerror(l_errno));
    329         rc = -1;
    330         goto on_error;
    331     }
    332 #else /* DAEMON_PRESENT */
    333     cam_status_t cam_status;
    334     cam_status = mm_camera_module_open_session(my_obj->sessionid,
    335             mm_camera_module_event_handler);
    336     if (cam_status < 0) {
    337         LOGE("Failed to open session");
    338         if (cam_status == CAM_STATUS_BUSY) {
    339             rc = -EUSERS;
    340         } else {
    341             rc = -1;
    342         }
    343         goto on_error;
    344     }
    345 #endif /* DAEMON_PRESENT */
    346 
    347     pthread_mutex_init(&my_obj->msg_lock, NULL);
    348     pthread_mutex_init(&my_obj->cb_lock, NULL);
    349     pthread_mutex_init(&my_obj->evt_lock, NULL);
    350     PTHREAD_COND_INIT(&my_obj->evt_cond);
    351 
    352     LOGD("Launch evt Thread in Cam Open");
    353     snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch");
    354     mm_camera_cmd_thread_launch(&my_obj->evt_thread,
    355                                 mm_camera_dispatch_app_event,
    356                                 (void *)my_obj);
    357 
    358     /* launch event poll thread
    359      * we will add evt fd into event poll thread upon user first register for evt */
    360     LOGD("Launch evt Poll Thread in Cam Open");
    361     snprintf(my_obj->evt_poll_thread.threadName, THREAD_NAME_SIZE, "CAM_evntPoll");
    362     mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
    363                                  MM_CAMERA_POLL_TYPE_EVT);
    364     mm_camera_evt_sub(my_obj, TRUE);
    365 
    366     /* unlock cam_lock, we need release global intf_lock in camera_open(),
    367      * in order not block operation of other Camera in dual camera use case.*/
    368     pthread_mutex_unlock(&my_obj->cam_lock);
    369     LOGD("end (rc = %d)\n", rc);
    370     return rc;
    371 
    372 on_error:
    373 
    374     if (NULL == dev_name_value) {
    375         LOGE("Invalid device name\n");
    376         rc = -1;
    377     }
    378 
    379     if (NULL == my_obj) {
    380         LOGE("Invalid camera object\n");
    381         rc = -1;
    382     } else {
    383         if (my_obj->ctrl_fd >= 0) {
    384             close(my_obj->ctrl_fd);
    385             my_obj->ctrl_fd = -1;
    386         }
    387 #ifdef DAEMON_PRESENT
    388         if (my_obj->ds_fd >= 0) {
    389             mm_camera_socket_close(my_obj->ds_fd);
    390             my_obj->ds_fd = -1;
    391         }
    392 #endif
    393     }
    394 
    395     /* unlock cam_lock, we need release global intf_lock in camera_open(),
    396      * in order not block operation of other Camera in dual camera use case.*/
    397     pthread_mutex_unlock(&my_obj->cam_lock);
    398     return rc;
    399 }
    400 
    401 /*===========================================================================
    402  * FUNCTION   : mm_camera_close
    403  *
    404  * DESCRIPTION: enqueue received event into event queue to be processed by
    405  *              event thread.
    406  *
    407  * PARAMETERS :
    408  *   @my_obj   : ptr to a camera object
    409  *   @event    : event to be queued
    410  *
    411  * RETURN     : int32_t type of status
    412  *              0  -- success
    413  *              -1 -- failure
    414  *==========================================================================*/
    415 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
    416 {
    417     LOGD("unsubscribe evt");
    418 
    419 #ifndef DAEMON_PRESENT
    420     mm_camera_module_close_session(my_obj->sessionid);
    421 #endif /* DAEMON_PRESENT */
    422 
    423     mm_camera_evt_sub(my_obj, FALSE);
    424 
    425     LOGD("Close evt Poll Thread in Cam Close");
    426     mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
    427 
    428     LOGD("Close evt cmd Thread in Cam Close");
    429     mm_camera_cmd_thread_release(&my_obj->evt_thread);
    430 
    431     if(my_obj->ctrl_fd >= 0) {
    432         close(my_obj->ctrl_fd);
    433         my_obj->ctrl_fd = -1;
    434     }
    435 
    436 #ifdef DAEMON_PRESENT
    437     if(my_obj->ds_fd >= 0) {
    438         mm_camera_socket_close(my_obj->ds_fd);
    439         my_obj->ds_fd = -1;
    440     }
    441 #endif
    442 
    443     pthread_mutex_destroy(&my_obj->msg_lock);
    444     pthread_mutex_destroy(&my_obj->cb_lock);
    445     pthread_mutex_destroy(&my_obj->evt_lock);
    446     pthread_cond_destroy(&my_obj->evt_cond);
    447     pthread_mutex_unlock(&my_obj->cam_lock);
    448     return 0;
    449 }
    450 
    451 /*===========================================================================
    452  * FUNCTION   : mm_camera_register_event_notify_internal
    453  *
    454  * DESCRIPTION: internal implementation for registering callback for event notify.
    455  *
    456  * PARAMETERS :
    457  *   @my_obj   : ptr to a camera object
    458  *   @evt_cb   : callback to be registered to handle event notify
    459  *   @user_data: user data ptr
    460  *
    461  * RETURN     : int32_t type of status
    462  *              0  -- success
    463  *              -1 -- failure
    464  *==========================================================================*/
    465 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
    466                                                  mm_camera_event_notify_t evt_cb,
    467                                                  void * user_data)
    468 {
    469     int i;
    470     int rc = -1;
    471     mm_camera_evt_obj_t *evt_array = NULL;
    472 
    473     pthread_mutex_lock(&my_obj->cb_lock);
    474     evt_array = &my_obj->evt;
    475     if(evt_cb) {
    476         /* this is reg case */
    477         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
    478             if(evt_array->evt[i].user_data == NULL) {
    479                 evt_array->evt[i].evt_cb = evt_cb;
    480                 evt_array->evt[i].user_data = user_data;
    481                 evt_array->reg_count++;
    482                 rc = 0;
    483                 break;
    484             }
    485         }
    486     } else {
    487         /* this is unreg case */
    488         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
    489             if(evt_array->evt[i].user_data == user_data) {
    490                 evt_array->evt[i].evt_cb = NULL;
    491                 evt_array->evt[i].user_data = NULL;
    492                 evt_array->reg_count--;
    493                 rc = 0;
    494                 break;
    495             }
    496         }
    497     }
    498 
    499     pthread_mutex_unlock(&my_obj->cb_lock);
    500     return rc;
    501 }
    502 
    503 /*===========================================================================
    504  * FUNCTION   : mm_camera_register_event_notify
    505  *
    506  * DESCRIPTION: registering a callback for event notify.
    507  *
    508  * PARAMETERS :
    509  *   @my_obj   : ptr to a camera object
    510  *   @evt_cb   : callback to be registered to handle event notify
    511  *   @user_data: user data ptr
    512  *
    513  * RETURN     : int32_t type of status
    514  *              0  -- success
    515  *              -1 -- failure
    516  *==========================================================================*/
    517 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
    518                                         mm_camera_event_notify_t evt_cb,
    519                                         void * user_data)
    520 {
    521     int rc = -1;
    522     rc = mm_camera_register_event_notify_internal(my_obj,
    523                                                   evt_cb,
    524                                                   user_data);
    525     pthread_mutex_unlock(&my_obj->cam_lock);
    526     return rc;
    527 }
    528 
    529 /*===========================================================================
    530  * FUNCTION   : mm_camera_qbuf
    531  *
    532  * DESCRIPTION: enqueue buffer back to kernel
    533  *
    534  * PARAMETERS :
    535  *   @my_obj       : camera object
    536  *   @ch_id        : channel handle
    537  *   @buf          : buf ptr to be enqueued
    538  *
    539  * RETURN     : int32_t type of status
    540  *              0  -- success
    541  *              -1 -- failure
    542  *==========================================================================*/
    543 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
    544                        uint32_t ch_id,
    545                        mm_camera_buf_def_t *buf)
    546 {
    547     int rc = -1;
    548     mm_channel_t * ch_obj = NULL;
    549     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    550 
    551     pthread_mutex_unlock(&my_obj->cam_lock);
    552 
    553     /* we always assume qbuf will be done before channel/stream is fully stopped
    554      * because qbuf is done within dataCB context
    555      * in order to avoid deadlock, we are not locking ch_lock for qbuf */
    556     if (NULL != ch_obj) {
    557         rc = mm_channel_qbuf(ch_obj, buf);
    558     }
    559 
    560     return rc;
    561 }
    562 
    563 /*===========================================================================
    564  * FUNCTION   : mm_camera_cancel_buf
    565  *
    566  * DESCRIPTION: Cancel an already queued buffer
    567  *
    568  * PARAMETERS :
    569  *   @my_obj       : camera object
    570  *   @ch_id        : channel handle
    571  *
    572  *   @buf          : buf ptr to be enqueued
    573  *
    574  * RETURN     : int32_t type of status
    575  *              0  -- success
    576  *              -1 -- failure
    577  *==========================================================================*/
    578 int32_t mm_camera_cancel_buf(mm_camera_obj_t *my_obj,
    579                        uint32_t ch_id,
    580                        uint32_t stream_id,
    581                        uint32_t buf_idx)
    582 {
    583     int rc = -1;
    584     mm_channel_t * ch_obj = NULL;
    585     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    586 
    587     if (NULL != ch_obj) {
    588         pthread_mutex_unlock(&my_obj->cam_lock);
    589         rc = mm_channel_cancel_buf(ch_obj,stream_id,buf_idx);
    590     }
    591 
    592     return rc;
    593 }
    594 
    595 /*===========================================================================
    596  * FUNCTION   : mm_camera_get_queued_buf_count
    597  *
    598  * DESCRIPTION: return queued buffer count
    599  *
    600  * PARAMETERS :
    601  *   @my_obj       : camera object
    602  *   @ch_id        : channel handle
    603  *   @stream_id : stream id
    604  *
    605  * RETURN     : queued buffer count
    606  *==========================================================================*/
    607 int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj,
    608         uint32_t ch_id, uint32_t stream_id)
    609 {
    610     int rc = -1;
    611     mm_channel_t * ch_obj = NULL;
    612     uint32_t payload;
    613     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    614     payload = stream_id;
    615 
    616     if (NULL != ch_obj) {
    617         pthread_mutex_lock(&ch_obj->ch_lock);
    618         pthread_mutex_unlock(&my_obj->cam_lock);
    619         rc = mm_channel_fsm_fn(ch_obj,
    620                 MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT,
    621                 (void *)&payload,
    622                 NULL);
    623     } else {
    624         pthread_mutex_unlock(&my_obj->cam_lock);
    625     }
    626 
    627     return rc;
    628 }
    629 
    630 /*===========================================================================
    631  * FUNCTION   : mm_camera_query_capability
    632  *
    633  * DESCRIPTION: query camera capability
    634  *
    635  * PARAMETERS :
    636  *   @my_obj: camera object
    637  *
    638  * RETURN     : int32_t type of status
    639  *              0  -- success
    640  *              -1 -- failure
    641  *==========================================================================*/
    642 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
    643 {
    644     int32_t rc = 0;
    645 
    646 #ifdef DAEMON_PRESENT
    647     struct v4l2_capability cap;
    648     /* get camera capabilities */
    649     memset(&cap, 0, sizeof(cap));
    650     rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
    651 #else /* DAEMON_PRESENT */
    652     cam_shim_packet_t *shim_cmd;
    653     cam_shim_cmd_data shim_cmd_data;
    654     memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
    655     shim_cmd_data.command = MSM_CAMERA_PRIV_QUERY_CAP;
    656     shim_cmd_data.stream_id = 0;
    657     shim_cmd_data.value = NULL;
    658     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM,
    659             my_obj->sessionid,&shim_cmd_data);
    660     rc = mm_camera_module_send_cmd(shim_cmd);
    661     mm_camera_destroy_shim_cmd_packet(shim_cmd);
    662 #endif /* DAEMON_PRESENT */
    663     if (rc != 0) {
    664         LOGE("cannot get camera capabilities, rc = %d, errno %d",
    665                 rc, errno);
    666     }
    667     pthread_mutex_unlock(&my_obj->cam_lock);
    668     return rc;
    669 }
    670 
    671 /*===========================================================================
    672  * FUNCTION   : mm_camera_set_parms
    673  *
    674  * DESCRIPTION: set parameters per camera
    675  *
    676  * PARAMETERS :
    677  *   @my_obj       : camera object
    678  *   @parms        : ptr to a param struct to be set to server
    679  *
    680  * RETURN     : int32_t type of status
    681  *              0  -- success
    682  *              -1 -- failure
    683  * NOTE       : Assume the parms struct buf is already mapped to server via
    684  *              domain socket. Corresponding fields of parameters to be set
    685  *              are already filled in by upper layer caller.
    686  *==========================================================================*/
    687 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj,
    688                             parm_buffer_t *parms)
    689 {
    690     int32_t rc = -1;
    691     int32_t value = 0;
    692     if (parms !=  NULL) {
    693         rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
    694             CAM_PRIV_PARM, &value);
    695     }
    696     pthread_mutex_unlock(&my_obj->cam_lock);
    697     return rc;
    698 }
    699 
    700 /*===========================================================================
    701  * FUNCTION   : mm_camera_get_parms
    702  *
    703  * DESCRIPTION: get parameters per camera
    704  *
    705  * PARAMETERS :
    706  *   @my_obj       : camera object
    707  *   @parms        : ptr to a param struct to be get from server
    708  *
    709  * RETURN     : int32_t type of status
    710  *              0  -- success
    711  *              -1 -- failure
    712  * NOTE       : Assume the parms struct buf is already mapped to server via
    713  *              domain socket. Parameters to be get from server are already
    714  *              filled in by upper layer caller. After this call, corresponding
    715  *              fields of requested parameters will be filled in by server with
    716  *              detailed information.
    717  *==========================================================================*/
    718 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
    719                             parm_buffer_t *parms)
    720 {
    721     int32_t rc = -1;
    722     int32_t value = 0;
    723     if (parms != NULL) {
    724         rc = mm_camera_util_g_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
    725     }
    726     pthread_mutex_unlock(&my_obj->cam_lock);
    727     return rc;
    728 }
    729 
    730 /*===========================================================================
    731  * FUNCTION   : mm_camera_do_auto_focus
    732  *
    733  * DESCRIPTION: performing auto focus
    734  *
    735  * PARAMETERS :
    736  *   @camera_handle: camera handle
    737  *
    738  * RETURN     : int32_t type of status
    739  *              0  -- success
    740  *              -1 -- failure
    741  * NOTE       : if this call success, we will always assume there will
    742  *              be an auto_focus event following up.
    743  *==========================================================================*/
    744 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
    745 {
    746     int32_t rc = -1;
    747     int32_t value = 0;
    748     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
    749     pthread_mutex_unlock(&my_obj->cam_lock);
    750     return rc;
    751 }
    752 
    753 /*===========================================================================
    754  * FUNCTION   : mm_camera_cancel_auto_focus
    755  *
    756  * DESCRIPTION: cancel auto focus
    757  *
    758  * PARAMETERS :
    759  *   @camera_handle: camera handle
    760  *
    761  * RETURN     : int32_t type of status
    762  *              0  -- success
    763  *              -1 -- failure
    764  *==========================================================================*/
    765 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
    766 {
    767     int32_t rc = -1;
    768     int32_t value = 0;
    769     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
    770     pthread_mutex_unlock(&my_obj->cam_lock);
    771     return rc;
    772 }
    773 
    774 /*===========================================================================
    775  * FUNCTION   : mm_camera_prepare_snapshot
    776  *
    777  * DESCRIPTION: prepare hardware for snapshot
    778  *
    779  * PARAMETERS :
    780  *   @my_obj       : camera object
    781  *   @do_af_flag   : flag indicating if AF is needed
    782  *
    783  * RETURN     : int32_t type of status
    784  *              0  -- success
    785  *              -1 -- failure
    786  *==========================================================================*/
    787 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
    788                                    int32_t do_af_flag)
    789 {
    790     int32_t rc = -1;
    791     int32_t value = do_af_flag;
    792     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
    793     pthread_mutex_unlock(&my_obj->cam_lock);
    794     return rc;
    795 }
    796 
    797 /*===========================================================================
    798  * FUNCTION   : mm_camera_start_zsl_snapshot
    799  *
    800  * DESCRIPTION: start zsl snapshot
    801  *
    802  * PARAMETERS :
    803  *   @my_obj       : camera object
    804  *
    805  * RETURN     : int32_t type of status
    806  *              0  -- success
    807  *              -1 -- failure
    808  *==========================================================================*/
    809 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
    810 {
    811     int32_t rc = -1;
    812     int32_t value = 0;
    813 
    814     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
    815              CAM_PRIV_START_ZSL_SNAPSHOT, &value);
    816     return rc;
    817 }
    818 
    819 /*===========================================================================
    820  * FUNCTION   : mm_camera_stop_zsl_snapshot
    821  *
    822  * DESCRIPTION: stop zsl capture
    823  *
    824  * PARAMETERS :
    825  *   @my_obj       : camera object
    826  *
    827  * RETURN     : int32_t type of status
    828  *              0  -- success
    829  *              -1 -- failure
    830  *==========================================================================*/
    831 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
    832 {
    833     int32_t rc = -1;
    834     int32_t value;
    835     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
    836              CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
    837     return rc;
    838 }
    839 
    840 /*===========================================================================
    841  * FUNCTION   : mm_camera_flush
    842  *
    843  * DESCRIPTION: flush the current camera state and buffers
    844  *
    845  * PARAMETERS :
    846  *   @my_obj       : camera object
    847  *
    848  * RETURN     : int32_t type of status
    849  *              0  -- success
    850  *              -1 -- failure
    851  *==========================================================================*/
    852 int32_t mm_camera_flush(mm_camera_obj_t *my_obj)
    853 {
    854     int32_t rc = -1;
    855     int32_t value;
    856     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
    857             CAM_PRIV_FLUSH, &value);
    858     pthread_mutex_unlock(&my_obj->cam_lock);
    859     return rc;
    860 }
    861 
    862 /*===========================================================================
    863  * FUNCTION   : mm_camera_add_channel
    864  *
    865  * DESCRIPTION: add a channel
    866  *
    867  * PARAMETERS :
    868  *   @my_obj       : camera object
    869  *   @attr         : bundle attribute of the channel if needed
    870  *   @channel_cb   : callback function for bundle data notify
    871  *   @userdata     : user data ptr
    872  *
    873  * RETURN     : uint32_t type of channel handle
    874  *              0  -- invalid channel handle, meaning the op failed
    875  *              >0 -- successfully added a channel with a valid handle
    876  * NOTE       : if no bundle data notify is needed, meaning each stream in the
    877  *              channel will have its own stream data notify callback, then
    878  *              attr, channel_cb, and userdata can be NULL. In this case,
    879  *              no matching logic will be performed in channel for the bundling.
    880  *==========================================================================*/
    881 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
    882                                mm_camera_channel_attr_t *attr,
    883                                mm_camera_buf_notify_t channel_cb,
    884                                void *userdata)
    885 {
    886     mm_channel_t *ch_obj = NULL;
    887     uint8_t ch_idx = 0;
    888     uint32_t ch_hdl = 0;
    889 
    890     for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
    891         if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
    892             ch_obj = &my_obj->ch[ch_idx];
    893             break;
    894         }
    895     }
    896 
    897     if (NULL != ch_obj) {
    898         /* initialize channel obj */
    899         memset(ch_obj, 0, sizeof(mm_channel_t));
    900         ch_hdl = mm_camera_util_generate_handler(ch_idx);
    901         ch_obj->my_hdl = ch_hdl;
    902         ch_obj->state = MM_CHANNEL_STATE_STOPPED;
    903         ch_obj->cam_obj = my_obj;
    904         pthread_mutex_init(&ch_obj->ch_lock, NULL);
    905         ch_obj->sessionid = my_obj->sessionid;
    906         mm_channel_init(ch_obj, attr, channel_cb, userdata);
    907     }
    908 
    909     pthread_mutex_unlock(&my_obj->cam_lock);
    910 
    911     return ch_hdl;
    912 }
    913 
    914 /*===========================================================================
    915  * FUNCTION   : mm_camera_del_channel
    916  *
    917  * DESCRIPTION: delete a channel by its handle
    918  *
    919  * PARAMETERS :
    920  *   @my_obj       : camera object
    921  *   @ch_id        : channel handle
    922  *
    923  * RETURN     : int32_t type of status
    924  *              0  -- success
    925  *              -1 -- failure
    926  * NOTE       : all streams in the channel should be stopped already before
    927  *              this channel can be deleted.
    928  *==========================================================================*/
    929 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
    930                               uint32_t ch_id)
    931 {
    932     int32_t rc = -1;
    933     mm_channel_t * ch_obj =
    934         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    935 
    936     if (NULL != ch_obj) {
    937         pthread_mutex_lock(&ch_obj->ch_lock);
    938         pthread_mutex_unlock(&my_obj->cam_lock);
    939 
    940         rc = mm_channel_fsm_fn(ch_obj,
    941                                MM_CHANNEL_EVT_DELETE,
    942                                NULL,
    943                                NULL);
    944 
    945         pthread_mutex_destroy(&ch_obj->ch_lock);
    946         memset(ch_obj, 0, sizeof(mm_channel_t));
    947     } else {
    948         pthread_mutex_unlock(&my_obj->cam_lock);
    949     }
    950     return rc;
    951 }
    952 
    953 /*===========================================================================
    954  * FUNCTION   : mm_camera_get_bundle_info
    955  *
    956  * DESCRIPTION: query bundle info of the channel
    957  *
    958  * PARAMETERS :
    959  *   @my_obj       : camera object
    960  *   @ch_id        : channel handle
    961  *   @bundle_info  : bundle info to be filled in
    962  *
    963  * RETURN     : int32_t type of status
    964  *              0  -- success
    965  *              -1 -- failure
    966  * NOTE       : all streams in the channel should be stopped already before
    967  *              this channel can be deleted.
    968  *==========================================================================*/
    969 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
    970                                   uint32_t ch_id,
    971                                   cam_bundle_config_t *bundle_info)
    972 {
    973     int32_t rc = -1;
    974     mm_channel_t * ch_obj =
    975         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    976 
    977     if (NULL != ch_obj) {
    978         pthread_mutex_lock(&ch_obj->ch_lock);
    979         pthread_mutex_unlock(&my_obj->cam_lock);
    980 
    981         rc = mm_channel_fsm_fn(ch_obj,
    982                                MM_CHANNEL_EVT_GET_BUNDLE_INFO,
    983                                (void *)bundle_info,
    984                                NULL);
    985     } else {
    986         pthread_mutex_unlock(&my_obj->cam_lock);
    987     }
    988     return rc;
    989 }
    990 
    991 /*===========================================================================
    992  * FUNCTION   : mm_camera_link_stream
    993  *
    994  * DESCRIPTION: link a stream into a channel
    995  *
    996  * PARAMETERS :
    997  *   @my_obj       : camera object
    998  *   @ch_id        : channel handle
    999  *   @stream_id    : stream that will be linked
   1000  *   @linked_ch_id : channel in which the stream will be linked
   1001  *
   1002  * RETURN     : uint32_t type of stream handle
   1003  *              0  -- invalid stream handle, meaning the op failed
   1004  *              >0 -- successfully linked a stream with a valid handle
   1005  *==========================================================================*/
   1006 uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj,
   1007         uint32_t ch_id,
   1008         uint32_t stream_id,
   1009         uint32_t linked_ch_id)
   1010 {
   1011     uint32_t s_hdl = 0;
   1012     mm_channel_t * ch_obj =
   1013             mm_camera_util_get_channel_by_handler(my_obj, linked_ch_id);
   1014     mm_channel_t * owner_obj =
   1015             mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1016 
   1017     if ((NULL != ch_obj) && (NULL != owner_obj)) {
   1018         pthread_mutex_lock(&ch_obj->ch_lock);
   1019         pthread_mutex_unlock(&my_obj->cam_lock);
   1020 
   1021         mm_camera_stream_link_t stream_link;
   1022         memset(&stream_link, 0, sizeof(mm_camera_stream_link_t));
   1023         stream_link.ch = owner_obj;
   1024         stream_link.stream_id = stream_id;
   1025         mm_channel_fsm_fn(ch_obj,
   1026                           MM_CHANNEL_EVT_LINK_STREAM,
   1027                           (void*)&stream_link,
   1028                           (void*)&s_hdl);
   1029     } else {
   1030         pthread_mutex_unlock(&my_obj->cam_lock);
   1031     }
   1032 
   1033     return s_hdl;
   1034 }
   1035 
   1036 /*===========================================================================
   1037  * FUNCTION   : mm_camera_add_stream
   1038  *
   1039  * DESCRIPTION: add a stream into a channel
   1040  *
   1041  * PARAMETERS :
   1042  *   @my_obj       : camera object
   1043  *   @ch_id        : channel handle
   1044  *
   1045  * RETURN     : uint32_t type of stream handle
   1046  *              0  -- invalid stream handle, meaning the op failed
   1047  *              >0 -- successfully added a stream with a valid handle
   1048  *==========================================================================*/
   1049 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
   1050                               uint32_t ch_id)
   1051 {
   1052     uint32_t s_hdl = 0;
   1053     mm_channel_t * ch_obj =
   1054         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1055 
   1056     if (NULL != ch_obj) {
   1057         pthread_mutex_lock(&ch_obj->ch_lock);
   1058         pthread_mutex_unlock(&my_obj->cam_lock);
   1059 
   1060         mm_channel_fsm_fn(ch_obj,
   1061                           MM_CHANNEL_EVT_ADD_STREAM,
   1062                           NULL,
   1063                           (void *)&s_hdl);
   1064     } else {
   1065         pthread_mutex_unlock(&my_obj->cam_lock);
   1066     }
   1067 
   1068     return s_hdl;
   1069 }
   1070 
   1071 /*===========================================================================
   1072  * FUNCTION   : mm_camera_del_stream
   1073  *
   1074  * DESCRIPTION: delete a stream by its handle
   1075  *
   1076  * PARAMETERS :
   1077  *   @my_obj       : camera object
   1078  *   @ch_id        : channel handle
   1079  *   @stream_id    : stream handle
   1080  *
   1081  * RETURN     : int32_t type of status
   1082  *              0  -- success
   1083  *              -1 -- failure
   1084  * NOTE       : stream should be stopped already before it can be deleted.
   1085  *==========================================================================*/
   1086 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
   1087                              uint32_t ch_id,
   1088                              uint32_t stream_id)
   1089 {
   1090     int32_t rc = -1;
   1091     mm_channel_t * ch_obj =
   1092         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1093 
   1094     if (NULL != ch_obj) {
   1095         pthread_mutex_lock(&ch_obj->ch_lock);
   1096         pthread_mutex_unlock(&my_obj->cam_lock);
   1097 
   1098         rc = mm_channel_fsm_fn(ch_obj,
   1099                                MM_CHANNEL_EVT_DEL_STREAM,
   1100                                (void *)&stream_id,
   1101                                NULL);
   1102     } else {
   1103         pthread_mutex_unlock(&my_obj->cam_lock);
   1104     }
   1105 
   1106     return rc;
   1107 }
   1108 
   1109 /*===========================================================================
   1110  * FUNCTION   : mm_camera_start_zsl_snapshot_ch
   1111  *
   1112  * DESCRIPTION: starts zsl snapshot for specific channel
   1113  *
   1114  * PARAMETERS :
   1115  *   @my_obj       : camera object
   1116  *   @ch_id        : channel handle
   1117  *
   1118  * RETURN     : int32_t type of status
   1119  *              0  -- success
   1120  *              -1 -- failure
   1121  *==========================================================================*/
   1122 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
   1123         uint32_t ch_id)
   1124 {
   1125     int32_t rc = -1;
   1126     mm_channel_t * ch_obj =
   1127         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1128 
   1129     if (NULL != ch_obj) {
   1130         pthread_mutex_lock(&ch_obj->ch_lock);
   1131         pthread_mutex_unlock(&my_obj->cam_lock);
   1132 
   1133         rc = mm_channel_fsm_fn(ch_obj,
   1134                                MM_CHANNEL_EVT_START_ZSL_SNAPSHOT,
   1135                                NULL,
   1136                                NULL);
   1137     } else {
   1138         pthread_mutex_unlock(&my_obj->cam_lock);
   1139     }
   1140 
   1141     return rc;
   1142 }
   1143 
   1144 /*===========================================================================
   1145  * FUNCTION   : mm_camera_stop_zsl_snapshot_ch
   1146  *
   1147  * DESCRIPTION: stops zsl snapshot for specific channel
   1148  *
   1149  * PARAMETERS :
   1150  *   @my_obj       : camera object
   1151  *   @ch_id        : channel handle
   1152  *
   1153  * RETURN     : int32_t type of status
   1154  *              0  -- success
   1155  *              -1 -- failure
   1156  *==========================================================================*/
   1157 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
   1158         uint32_t ch_id)
   1159 {
   1160     int32_t rc = -1;
   1161     mm_channel_t * ch_obj =
   1162         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1163 
   1164     if (NULL != ch_obj) {
   1165         pthread_mutex_lock(&ch_obj->ch_lock);
   1166         pthread_mutex_unlock(&my_obj->cam_lock);
   1167 
   1168         rc = mm_channel_fsm_fn(ch_obj,
   1169                                MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT,
   1170                                NULL,
   1171                                NULL);
   1172     } else {
   1173         pthread_mutex_unlock(&my_obj->cam_lock);
   1174     }
   1175 
   1176     return rc;
   1177 }
   1178 
   1179 /*===========================================================================
   1180  * FUNCTION   : mm_camera_config_stream
   1181  *
   1182  * DESCRIPTION: configure a stream
   1183  *
   1184  * PARAMETERS :
   1185  *   @my_obj       : camera object
   1186  *   @ch_id        : channel handle
   1187  *   @stream_id    : stream handle
   1188  *   @config       : stream configuration
   1189  *
   1190  * RETURN     : int32_t type of status
   1191  *              0  -- success
   1192  *              -1 -- failure
   1193  *==========================================================================*/
   1194 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
   1195                                 uint32_t ch_id,
   1196                                 uint32_t stream_id,
   1197                                 mm_camera_stream_config_t *config)
   1198 {
   1199     int32_t rc = -1;
   1200     mm_channel_t * ch_obj =
   1201         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1202     mm_evt_paylod_config_stream_t payload;
   1203 
   1204     if (NULL != ch_obj) {
   1205         pthread_mutex_lock(&ch_obj->ch_lock);
   1206         pthread_mutex_unlock(&my_obj->cam_lock);
   1207 
   1208         memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
   1209         payload.stream_id = stream_id;
   1210         payload.config = config;
   1211         rc = mm_channel_fsm_fn(ch_obj,
   1212                                MM_CHANNEL_EVT_CONFIG_STREAM,
   1213                                (void *)&payload,
   1214                                NULL);
   1215     } else {
   1216         pthread_mutex_unlock(&my_obj->cam_lock);
   1217     }
   1218 
   1219     return rc;
   1220 }
   1221 
   1222 /*===========================================================================
   1223  * FUNCTION   : mm_camera_start_channel
   1224  *
   1225  * DESCRIPTION: start a channel, which will start all streams in the channel
   1226  *
   1227  * PARAMETERS :
   1228  *   @my_obj       : camera object
   1229  *   @ch_id        : channel handle
   1230  *
   1231  * RETURN     : int32_t type of status
   1232  *              0  -- success
   1233  *              -1 -- failure
   1234  *==========================================================================*/
   1235 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj, uint32_t ch_id)
   1236 {
   1237     int32_t rc = -1;
   1238     mm_channel_t * ch_obj =
   1239         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1240 
   1241     if (NULL != ch_obj) {
   1242         pthread_mutex_lock(&ch_obj->ch_lock);
   1243         pthread_mutex_unlock(&my_obj->cam_lock);
   1244 
   1245         rc = mm_channel_fsm_fn(ch_obj,
   1246                                MM_CHANNEL_EVT_START,
   1247                                NULL,
   1248                                NULL);
   1249     } else {
   1250         pthread_mutex_unlock(&my_obj->cam_lock);
   1251     }
   1252 
   1253     return rc;
   1254 }
   1255 
   1256 /*===========================================================================
   1257  * FUNCTION   : mm_camera_stop_channel
   1258  *
   1259  * DESCRIPTION: stop a channel, which will stop all streams in the channel
   1260  *
   1261  * PARAMETERS :
   1262  *   @my_obj       : camera object
   1263  *   @ch_id        : channel handle
   1264  *
   1265  * RETURN     : int32_t type of status
   1266  *              0  -- success
   1267  *              -1 -- failure
   1268  *==========================================================================*/
   1269 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
   1270                                uint32_t ch_id)
   1271 {
   1272     int32_t rc = 0;
   1273     mm_channel_t * ch_obj =
   1274         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1275 
   1276     if (NULL != ch_obj) {
   1277         pthread_mutex_lock(&ch_obj->ch_lock);
   1278         pthread_mutex_unlock(&my_obj->cam_lock);
   1279 
   1280         rc = mm_channel_fsm_fn(ch_obj,
   1281                                MM_CHANNEL_EVT_STOP,
   1282                                NULL,
   1283                                NULL);
   1284     } else {
   1285         pthread_mutex_unlock(&my_obj->cam_lock);
   1286     }
   1287     return rc;
   1288 }
   1289 
   1290 /*===========================================================================
   1291  * FUNCTION   : mm_camera_request_super_buf
   1292  *
   1293  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
   1294  *              frames from superbuf queue
   1295  *
   1296  * PARAMETERS :
   1297  *   @my_obj       : camera object
   1298  *   @ch_id        : channel handle
   1299  *   @num_buf_requested : number of matched frames needed
   1300  *
   1301  * RETURN     : int32_t type of status
   1302  *              0  -- success
   1303  *              -1 -- failure
   1304  *==========================================================================*/
   1305 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
   1306         uint32_t ch_id, mm_camera_req_buf_t *buf)
   1307 {
   1308     int32_t rc = -1;
   1309     mm_channel_t * ch_obj =
   1310         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1311 
   1312     if ((NULL != ch_obj) && (buf != NULL)) {
   1313         pthread_mutex_lock(&ch_obj->ch_lock);
   1314         pthread_mutex_unlock(&my_obj->cam_lock);
   1315 
   1316         rc = mm_channel_fsm_fn(ch_obj, MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
   1317                 (void *)buf, NULL);
   1318     } else {
   1319         pthread_mutex_unlock(&my_obj->cam_lock);
   1320     }
   1321 
   1322     return rc;
   1323 }
   1324 
   1325 /*===========================================================================
   1326  * FUNCTION   : mm_camera_cancel_super_buf_request
   1327  *
   1328  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
   1329  *              of matched frames from superbuf queue
   1330  *
   1331  * PARAMETERS :
   1332  *   @my_obj       : camera object
   1333  *   @ch_id        : channel handle
   1334  *
   1335  * RETURN     : int32_t type of status
   1336  *              0  -- success
   1337  *              -1 -- failure
   1338  *==========================================================================*/
   1339 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
   1340 {
   1341     int32_t rc = -1;
   1342     mm_channel_t * ch_obj =
   1343         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1344 
   1345     if (NULL != ch_obj) {
   1346         pthread_mutex_lock(&ch_obj->ch_lock);
   1347         pthread_mutex_unlock(&my_obj->cam_lock);
   1348 
   1349         rc = mm_channel_fsm_fn(ch_obj,
   1350                                MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
   1351                                NULL,
   1352                                NULL);
   1353     } else {
   1354         pthread_mutex_unlock(&my_obj->cam_lock);
   1355     }
   1356 
   1357     return rc;
   1358 }
   1359 
   1360 /*===========================================================================
   1361  * FUNCTION   : mm_camera_flush_super_buf_queue
   1362  *
   1363  * DESCRIPTION: flush out all frames in the superbuf queue
   1364  *
   1365  * PARAMETERS :
   1366  *   @my_obj       : camera object
   1367  *   @ch_id        : channel handle
   1368  *
   1369  * RETURN     : int32_t type of status
   1370  *              0  -- success
   1371  *              -1 -- failure
   1372  *==========================================================================*/
   1373 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
   1374                                                              uint32_t frame_idx)
   1375 {
   1376     int32_t rc = -1;
   1377     mm_channel_t * ch_obj =
   1378         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1379 
   1380     if (NULL != ch_obj) {
   1381         pthread_mutex_lock(&ch_obj->ch_lock);
   1382         pthread_mutex_unlock(&my_obj->cam_lock);
   1383 
   1384         rc = mm_channel_fsm_fn(ch_obj,
   1385                                MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
   1386                                (void *)&frame_idx,
   1387                                NULL);
   1388     } else {
   1389         pthread_mutex_unlock(&my_obj->cam_lock);
   1390     }
   1391 
   1392     return rc;
   1393 }
   1394 
   1395 /*===========================================================================
   1396  * FUNCTION   : mm_camera_config_channel_notify
   1397  *
   1398  * DESCRIPTION: configures the channel notification mode
   1399  *
   1400  * PARAMETERS :
   1401  *   @my_obj       : camera object
   1402  *   @ch_id        : channel handle
   1403  *   @notify_mode  : notification mode
   1404  *
   1405  * RETURN     : int32_t type of status
   1406  *              0  -- success
   1407  *              -1 -- failure
   1408  *==========================================================================*/
   1409 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
   1410                                         uint32_t ch_id,
   1411                                         mm_camera_super_buf_notify_mode_t notify_mode)
   1412 {
   1413     int32_t rc = -1;
   1414     mm_channel_t * ch_obj =
   1415         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1416 
   1417     if (NULL != ch_obj) {
   1418         pthread_mutex_lock(&ch_obj->ch_lock);
   1419         pthread_mutex_unlock(&my_obj->cam_lock);
   1420 
   1421         rc = mm_channel_fsm_fn(ch_obj,
   1422                                MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
   1423                                (void *)&notify_mode,
   1424                                NULL);
   1425     } else {
   1426         pthread_mutex_unlock(&my_obj->cam_lock);
   1427     }
   1428 
   1429     return rc;
   1430 }
   1431 
   1432 /*===========================================================================
   1433  * FUNCTION   : mm_camera_set_stream_parms
   1434  *
   1435  * DESCRIPTION: set parameters per stream
   1436  *
   1437  * PARAMETERS :
   1438  *   @my_obj       : camera object
   1439  *   @ch_id        : channel handle
   1440  *   @s_id         : stream handle
   1441  *   @parms        : ptr to a param struct to be set to server
   1442  *
   1443  * RETURN     : int32_t type of status
   1444  *              0  -- success
   1445  *              -1 -- failure
   1446  * NOTE       : Assume the parms struct buf is already mapped to server via
   1447  *              domain socket. Corresponding fields of parameters to be set
   1448  *              are already filled in by upper layer caller.
   1449  *==========================================================================*/
   1450 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
   1451                                    uint32_t ch_id,
   1452                                    uint32_t s_id,
   1453                                    cam_stream_parm_buffer_t *parms)
   1454 {
   1455     int32_t rc = -1;
   1456     mm_evt_paylod_set_get_stream_parms_t payload;
   1457     mm_channel_t * ch_obj =
   1458         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1459 
   1460     if (NULL != ch_obj) {
   1461         pthread_mutex_lock(&ch_obj->ch_lock);
   1462         pthread_mutex_unlock(&my_obj->cam_lock);
   1463 
   1464         memset(&payload, 0, sizeof(payload));
   1465         payload.stream_id = s_id;
   1466         payload.parms = parms;
   1467 
   1468         rc = mm_channel_fsm_fn(ch_obj,
   1469                                MM_CHANNEL_EVT_SET_STREAM_PARM,
   1470                                (void *)&payload,
   1471                                NULL);
   1472     } else {
   1473         pthread_mutex_unlock(&my_obj->cam_lock);
   1474     }
   1475 
   1476     return rc;
   1477 }
   1478 
   1479 /*===========================================================================
   1480  * FUNCTION   : mm_camera_get_stream_parms
   1481  *
   1482  * DESCRIPTION: get parameters per stream
   1483  *
   1484  * PARAMETERS :
   1485  *   @my_obj       : camera object
   1486  *   @ch_id        : channel handle
   1487  *   @s_id         : stream handle
   1488  *   @parms        : ptr to a param struct to be get from server
   1489  *
   1490  * RETURN     : int32_t type of status
   1491  *              0  -- success
   1492  *              -1 -- failure
   1493  * NOTE       : Assume the parms struct buf is already mapped to server via
   1494  *              domain socket. Parameters to be get from server are already
   1495  *              filled in by upper layer caller. After this call, corresponding
   1496  *              fields of requested parameters will be filled in by server with
   1497  *              detailed information.
   1498  *==========================================================================*/
   1499 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
   1500                                    uint32_t ch_id,
   1501                                    uint32_t s_id,
   1502                                    cam_stream_parm_buffer_t *parms)
   1503 {
   1504     int32_t rc = -1;
   1505     mm_evt_paylod_set_get_stream_parms_t payload;
   1506     mm_channel_t * ch_obj =
   1507         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1508 
   1509     if (NULL != ch_obj) {
   1510         pthread_mutex_lock(&ch_obj->ch_lock);
   1511         pthread_mutex_unlock(&my_obj->cam_lock);
   1512 
   1513         memset(&payload, 0, sizeof(payload));
   1514         payload.stream_id = s_id;
   1515         payload.parms = parms;
   1516 
   1517         rc = mm_channel_fsm_fn(ch_obj,
   1518                                MM_CHANNEL_EVT_GET_STREAM_PARM,
   1519                                (void *)&payload,
   1520                                NULL);
   1521     } else {
   1522         pthread_mutex_unlock(&my_obj->cam_lock);
   1523     }
   1524 
   1525     return rc;
   1526 }
   1527 
   1528 /*===========================================================================
   1529  * FUNCTION   : mm_camera_do_stream_action
   1530  *
   1531  * DESCRIPTION: request server to perform stream based action. Maybe removed later
   1532  *              if the functionality is included in mm_camera_set_parms
   1533  *
   1534  * PARAMETERS :
   1535  *   @my_obj       : camera object
   1536  *   @ch_id        : channel handle
   1537  *   @s_id         : stream handle
   1538  *   @actions      : ptr to an action struct buf to be performed by server
   1539  *
   1540  * RETURN     : int32_t type of status
   1541  *              0  -- success
   1542  *              -1 -- failure
   1543  * NOTE       : Assume the action struct buf is already mapped to server via
   1544  *              domain socket. Actions to be performed by server are already
   1545  *              filled in by upper layer caller.
   1546  *==========================================================================*/
   1547 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
   1548                                    uint32_t ch_id,
   1549                                    uint32_t stream_id,
   1550                                    void *actions)
   1551 {
   1552     int32_t rc = -1;
   1553     mm_evt_paylod_do_stream_action_t payload;
   1554     mm_channel_t * ch_obj =
   1555         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1556 
   1557     if (NULL != ch_obj) {
   1558         pthread_mutex_lock(&ch_obj->ch_lock);
   1559         pthread_mutex_unlock(&my_obj->cam_lock);
   1560 
   1561         memset(&payload, 0, sizeof(payload));
   1562         payload.stream_id = stream_id;
   1563         payload.actions = actions;
   1564 
   1565         rc = mm_channel_fsm_fn(ch_obj,
   1566                                MM_CHANNEL_EVT_DO_STREAM_ACTION,
   1567                                (void*)&payload,
   1568                                NULL);
   1569     } else {
   1570         pthread_mutex_unlock(&my_obj->cam_lock);
   1571     }
   1572 
   1573     return rc;
   1574 }
   1575 
   1576 /*===========================================================================
   1577  * FUNCTION   : mm_camera_map_stream_buf
   1578  *
   1579  * DESCRIPTION: mapping stream buffer via domain socket to server
   1580  *
   1581  * PARAMETERS :
   1582  *   @my_obj       : camera object
   1583  *   @ch_id        : channel handle
   1584  *   @s_id         : stream handle
   1585  *   @buf_type     : type of buffer to be mapped. could be following values:
   1586  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1587  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1588  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1589  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1590  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1591  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1592  *   @plane_idx    : plane index. If all planes share the same fd,
   1593  *                   plane_idx = -1; otherwise, plean_idx is the
   1594  *                   index to plane (0..num_of_planes)
   1595  *   @fd           : file descriptor of the buffer
   1596  *   @size         : size of the buffer
   1597  *
   1598  * RETURN     : int32_t type of status
   1599  *              0  -- success
   1600  *              -1 -- failure
   1601  *==========================================================================*/
   1602 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
   1603                                  uint32_t ch_id,
   1604                                  uint32_t stream_id,
   1605                                  uint8_t buf_type,
   1606                                  uint32_t buf_idx,
   1607                                  int32_t plane_idx,
   1608                                  int fd,
   1609                                  size_t size,
   1610                                  void *buffer)
   1611 {
   1612     int32_t rc = -1;
   1613     cam_buf_map_type payload;
   1614     mm_channel_t * ch_obj =
   1615         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1616 
   1617     if (NULL != ch_obj) {
   1618         pthread_mutex_lock(&ch_obj->ch_lock);
   1619         pthread_mutex_unlock(&my_obj->cam_lock);
   1620 
   1621         memset(&payload, 0, sizeof(payload));
   1622         payload.stream_id = stream_id;
   1623         payload.type = buf_type;
   1624         payload.frame_idx = buf_idx;
   1625         payload.plane_idx = plane_idx;
   1626         payload.fd = fd;
   1627         payload.size = size;
   1628         payload.buffer = buffer;
   1629         rc = mm_channel_fsm_fn(ch_obj,
   1630                                MM_CHANNEL_EVT_MAP_STREAM_BUF,
   1631                                (void*)&payload,
   1632                                NULL);
   1633     } else {
   1634         pthread_mutex_unlock(&my_obj->cam_lock);
   1635     }
   1636 
   1637     return rc;
   1638 }
   1639 
   1640 /*===========================================================================
   1641  * FUNCTION   : mm_camera_map_stream_bufs
   1642  *
   1643  * DESCRIPTION: mapping stream buffers via domain socket to server
   1644  *
   1645  * PARAMETERS :
   1646  *   @my_obj       : camera object
   1647  *   @ch_id        : channel handle
   1648  *   @buf_map_list : list of buffers to be mapped
   1649  *
   1650  * RETURN     : int32_t type of status
   1651  *              0  -- success
   1652  *              -1 -- failure
   1653  *==========================================================================*/
   1654 int32_t mm_camera_map_stream_bufs(mm_camera_obj_t *my_obj,
   1655                                   uint32_t ch_id,
   1656                                   const cam_buf_map_type_list *buf_map_list)
   1657 {
   1658     int32_t rc = -1;
   1659     cam_buf_map_type_list payload;
   1660     mm_channel_t * ch_obj =
   1661         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1662 
   1663     if (NULL != ch_obj) {
   1664         pthread_mutex_lock(&ch_obj->ch_lock);
   1665         pthread_mutex_unlock(&my_obj->cam_lock);
   1666 
   1667         memcpy(&payload, buf_map_list, sizeof(payload));
   1668         rc = mm_channel_fsm_fn(ch_obj,
   1669                                MM_CHANNEL_EVT_MAP_STREAM_BUFS,
   1670                                (void*)&payload,
   1671                                NULL);
   1672     } else {
   1673         pthread_mutex_unlock(&my_obj->cam_lock);
   1674     }
   1675 
   1676     return rc;
   1677 }
   1678 
   1679 /*===========================================================================
   1680  * FUNCTION   : mm_camera_unmap_stream_buf
   1681  *
   1682  * DESCRIPTION: unmapping stream buffer via domain socket to server
   1683  *
   1684  * PARAMETERS :
   1685  *   @my_obj       : camera object
   1686  *   @ch_id        : channel handle
   1687  *   @s_id         : stream handle
   1688  *   @buf_type     : type of buffer to be mapped. could be following values:
   1689  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1690  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1691  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1692  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1693  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1694  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1695  *   @plane_idx    : plane index. If all planes share the same fd,
   1696  *                   plane_idx = -1; otherwise, plean_idx is the
   1697  *                   index to plane (0..num_of_planes)
   1698  *
   1699  * RETURN     : int32_t type of status
   1700  *              0  -- success
   1701  *              -1 -- failure
   1702  *==========================================================================*/
   1703 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
   1704                                    uint32_t ch_id,
   1705                                    uint32_t stream_id,
   1706                                    uint8_t buf_type,
   1707                                    uint32_t buf_idx,
   1708                                    int32_t plane_idx)
   1709 {
   1710     int32_t rc = -1;
   1711     cam_buf_unmap_type payload;
   1712     mm_channel_t * ch_obj =
   1713         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1714 
   1715     if (NULL != ch_obj) {
   1716         pthread_mutex_lock(&ch_obj->ch_lock);
   1717         pthread_mutex_unlock(&my_obj->cam_lock);
   1718 
   1719         memset(&payload, 0, sizeof(payload));
   1720         payload.stream_id = stream_id;
   1721         payload.type = buf_type;
   1722         payload.frame_idx = buf_idx;
   1723         payload.plane_idx = plane_idx;
   1724         rc = mm_channel_fsm_fn(ch_obj,
   1725                                MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
   1726                                (void*)&payload,
   1727                                NULL);
   1728     } else {
   1729         pthread_mutex_unlock(&my_obj->cam_lock);
   1730     }
   1731 
   1732     return rc;
   1733 }
   1734 
   1735 /*===========================================================================
   1736  * FUNCTION   : mm_camera_evt_sub
   1737  *
   1738  * DESCRIPTION: subscribe/unsubscribe event notify from kernel
   1739  *
   1740  * PARAMETERS :
   1741  *   @my_obj       : camera object
   1742  *   @reg_flag     : 1 -- subscribe ; 0 -- unsubscribe
   1743  *
   1744  * RETURN     : int32_t type of status
   1745  *              0  -- success
   1746  *              -1 -- failure
   1747  *==========================================================================*/
   1748 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
   1749                           uint8_t reg_flag)
   1750 {
   1751     int32_t rc = 0;
   1752     struct v4l2_event_subscription sub;
   1753 
   1754     memset(&sub, 0, sizeof(sub));
   1755     sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
   1756     sub.id = MSM_CAMERA_MSM_NOTIFY;
   1757     if(FALSE == reg_flag) {
   1758         /* unsubscribe */
   1759         rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
   1760         if (rc < 0) {
   1761             LOGE("unsubscribe event rc = %d, errno %d",
   1762                      rc, errno);
   1763             return rc;
   1764         }
   1765         /* remove evt fd from the polling thraed when unreg the last event */
   1766         rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
   1767                                                my_obj->my_hdl,
   1768                                                mm_camera_sync_call);
   1769     } else {
   1770         rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
   1771         if (rc < 0) {
   1772             LOGE("subscribe event rc = %d, errno %d",
   1773              rc, errno);
   1774             return rc;
   1775         }
   1776         /* add evt fd to polling thread when subscribe the first event */
   1777         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
   1778                                                my_obj->my_hdl,
   1779                                                my_obj->ctrl_fd,
   1780                                                mm_camera_event_notify,
   1781                                                (void*)my_obj,
   1782                                                mm_camera_sync_call);
   1783     }
   1784     return rc;
   1785 }
   1786 
   1787 /*===========================================================================
   1788  * FUNCTION   : mm_camera_util_wait_for_event
   1789  *
   1790  * DESCRIPTION: utility function to wait for certain events
   1791  *
   1792  * PARAMETERS :
   1793  *   @my_obj       : camera object
   1794  *   @evt_mask     : mask for events to be waited. Any of event in the mask would
   1795  *                   trigger the wait to end
   1796  *   @status       : status of the event
   1797  *
   1798  * RETURN     : none
   1799  *==========================================================================*/
   1800 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
   1801                                    uint32_t evt_mask,
   1802                                    uint32_t *status)
   1803 {
   1804     int32_t rc = 0;
   1805     struct timespec ts;
   1806 
   1807     pthread_mutex_lock(&my_obj->evt_lock);
   1808     while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
   1809         clock_gettime(CLOCK_MONOTONIC, &ts);
   1810         ts.tv_sec += WAIT_TIMEOUT;
   1811         rc = pthread_cond_timedwait(&my_obj->evt_cond, &my_obj->evt_lock, &ts);
   1812         if (rc) {
   1813             LOGE("pthread_cond_timedwait of evt_mask 0x%x failed %d",
   1814                      evt_mask, rc);
   1815             break;
   1816         }
   1817     }
   1818     if (!rc) {
   1819         *status = my_obj->evt_rcvd.status;
   1820     } else {
   1821         *status = MSM_CAMERA_STATUS_FAIL;
   1822     }
   1823     /* reset local storage for recieved event for next event */
   1824     memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
   1825     pthread_mutex_unlock(&my_obj->evt_lock);
   1826 }
   1827 
   1828 /*===========================================================================
   1829  * FUNCTION   : mm_camera_util_bundled_sendmsg
   1830  *
   1831  * DESCRIPTION: utility function to send bundled msg via domain socket
   1832  *
   1833  * PARAMETERS :
   1834  *   @my_obj       : camera object
   1835  *   @msg          : message to be sent
   1836  *   @buf_size     : size of the message to be sent
   1837  *   @sendfds      : array of file descriptors to be sent
   1838  *   @numfds       : number of file descriptors to be sent
   1839  *
   1840  * RETURN     : int32_t type of status
   1841  *              0  -- success
   1842  *              -1 -- failure
   1843  *==========================================================================*/
   1844 int32_t mm_camera_util_bundled_sendmsg(mm_camera_obj_t *my_obj,
   1845                                        void *msg,
   1846                                        size_t buf_size,
   1847                                        int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],
   1848                                        int numfds)
   1849 {
   1850     int32_t rc = -1;
   1851     uint32_t status;
   1852 
   1853     /* need to lock msg_lock, since sendmsg until response back is deemed as one operation*/
   1854     pthread_mutex_lock(&my_obj->msg_lock);
   1855     if(mm_camera_socket_bundle_sendmsg(my_obj->ds_fd, msg, buf_size, sendfds, numfds) > 0) {
   1856         /* wait for event that mapping/unmapping is done */
   1857         mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
   1858         if (MSM_CAMERA_STATUS_SUCCESS == status) {
   1859             rc = 0;
   1860         }
   1861     }
   1862     pthread_mutex_unlock(&my_obj->msg_lock);
   1863     return rc;
   1864 }
   1865 
   1866 /*===========================================================================
   1867  * FUNCTION   : mm_camera_util_sendmsg
   1868  *
   1869  * DESCRIPTION: utility function to send msg via domain socket
   1870  *
   1871  * PARAMETERS :
   1872  *   @my_obj       : camera object
   1873  *   @msg          : message to be sent
   1874  *   @buf_size     : size of the message to be sent
   1875  *   @sendfd       : >0 if any file descriptor need to be passed across process
   1876  *
   1877  * RETURN     : int32_t type of status
   1878  *              0  -- success
   1879  *              -1 -- failure
   1880  *==========================================================================*/
   1881 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
   1882                                void *msg,
   1883                                size_t buf_size,
   1884                                int sendfd)
   1885 {
   1886     int32_t rc = -1;
   1887     uint32_t status;
   1888 
   1889     /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
   1890     pthread_mutex_lock(&my_obj->msg_lock);
   1891     if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
   1892         /* wait for event that mapping/unmapping is done */
   1893         mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
   1894         if (MSM_CAMERA_STATUS_SUCCESS == status) {
   1895             rc = 0;
   1896         }
   1897     }
   1898     pthread_mutex_unlock(&my_obj->msg_lock);
   1899     return rc;
   1900 }
   1901 
   1902 /*===========================================================================
   1903  * FUNCTIOa   : mm_camera_map_buf
   1904  *
   1905  * DESCRIPTION: mapping camera buffer via domain socket to server
   1906  *
   1907  * PARAMETERS :
   1908  *   @my_obj       : camera object
   1909  *   @buf_type     : type of buffer to be mapped. could be following values:
   1910  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1911  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1912  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1913  *   @fd           : file descriptor of the buffer
   1914  *   @size         : size of the buffer
   1915  *
   1916  * RETURN     : int32_t type of status
   1917  *              0  -- success
   1918  *              -1 -- failure
   1919  *==========================================================================*/
   1920 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
   1921         uint8_t buf_type, int fd, size_t size, void *buffer)
   1922 {
   1923     int32_t rc = 0;
   1924 
   1925     cam_sock_packet_t packet;
   1926     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1927     packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
   1928     packet.payload.buf_map.type = buf_type;
   1929     packet.payload.buf_map.fd = fd;
   1930     packet.payload.buf_map.size = size;
   1931     packet.payload.buf_map.buffer = buffer;
   1932 #ifdef DAEMON_PRESENT
   1933     rc = mm_camera_util_sendmsg(my_obj,
   1934                                 &packet,
   1935                                 sizeof(cam_sock_packet_t),
   1936                                 fd);
   1937 #else
   1938     cam_shim_packet_t *shim_cmd;
   1939     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
   1940             my_obj->sessionid, &packet);
   1941     rc = mm_camera_module_send_cmd(shim_cmd);
   1942     mm_camera_destroy_shim_cmd_packet(shim_cmd);
   1943 #endif
   1944     pthread_mutex_unlock(&my_obj->cam_lock);
   1945     return rc;
   1946 }
   1947 
   1948 /*===========================================================================
   1949  * FUNCTION   : mm_camera_map_bufs
   1950  *
   1951  * DESCRIPTION: mapping camera buffers via domain socket to server
   1952  *
   1953  * PARAMETERS :
   1954  *   @my_obj       : camera object
   1955  *   @buf_map_list : list of buffers to be mapped
   1956  *
   1957  * RETURN     : int32_t type of status
   1958  *              0  -- success
   1959  *              -1 -- failure
   1960  *==========================================================================*/
   1961 int32_t mm_camera_map_bufs(mm_camera_obj_t *my_obj,
   1962                            const cam_buf_map_type_list* buf_map_list)
   1963 {
   1964     int32_t rc = 0;
   1965     cam_sock_packet_t packet;
   1966     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1967     packet.msg_type = CAM_MAPPING_TYPE_FD_BUNDLED_MAPPING;
   1968 
   1969     memcpy(&packet.payload.buf_map_list, buf_map_list,
   1970            sizeof(packet.payload.buf_map_list));
   1971 
   1972     int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM];
   1973     uint32_t numbufs = packet.payload.buf_map_list.length;
   1974     uint32_t i;
   1975     for (i = 0; i < numbufs; i++) {
   1976         sendfds[i] = packet.payload.buf_map_list.buf_maps[i].fd;
   1977         packet.payload.buf_map_list.buf_maps[i].buffer =
   1978                 buf_map_list->buf_maps[i].buffer;
   1979     }
   1980     for (i = numbufs; i < CAM_MAX_NUM_BUFS_PER_STREAM; i++) {
   1981         packet.payload.buf_map_list.buf_maps[i].fd = -1;
   1982         sendfds[i] = -1;
   1983     }
   1984 
   1985 #ifdef DAEMON_PRESENT
   1986     rc = mm_camera_util_bundled_sendmsg(my_obj,
   1987             &packet, sizeof(cam_sock_packet_t),
   1988             sendfds, numbufs);
   1989 #else
   1990     cam_shim_packet_t *shim_cmd;
   1991     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
   1992             my_obj->sessionid, &packet);
   1993     rc = mm_camera_module_send_cmd(shim_cmd);
   1994     mm_camera_destroy_shim_cmd_packet(shim_cmd);
   1995 #endif
   1996 
   1997     pthread_mutex_unlock(&my_obj->cam_lock);
   1998     return rc;
   1999 }
   2000 
   2001 /*===========================================================================
   2002  * FUNCTION   : mm_camera_unmap_buf
   2003  *
   2004  * DESCRIPTION: unmapping camera buffer via domain socket to server
   2005  *
   2006  * PARAMETERS :
   2007  *   @my_obj       : camera object
   2008  *   @buf_type     : type of buffer to be mapped. could be following values:
   2009  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   2010  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   2011  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   2012  *
   2013  * RETURN     : int32_t type of status
   2014  *              0  -- success
   2015  *              -1 -- failure
   2016  *==========================================================================*/
   2017 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
   2018                             uint8_t buf_type)
   2019 {
   2020     int32_t rc = 0;
   2021     cam_sock_packet_t packet;
   2022     memset(&packet, 0, sizeof(cam_sock_packet_t));
   2023     packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
   2024     packet.payload.buf_unmap.type = buf_type;
   2025 #ifdef DAEMON_PRESENT
   2026     rc = mm_camera_util_sendmsg(my_obj,
   2027                                 &packet,
   2028                                 sizeof(cam_sock_packet_t),
   2029                                 -1);
   2030 #else
   2031     cam_shim_packet_t *shim_cmd;
   2032     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
   2033             my_obj->sessionid, &packet);
   2034     rc = mm_camera_module_send_cmd(shim_cmd);
   2035     mm_camera_destroy_shim_cmd_packet(shim_cmd);
   2036 #endif
   2037     pthread_mutex_unlock(&my_obj->cam_lock);
   2038     return rc;
   2039 }
   2040 
   2041 /*===========================================================================
   2042  * FUNCTION   : mm_camera_util_s_ctrl
   2043  *
   2044  * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
   2045  *
   2046  * PARAMETERS :
   2047  *   @my_obj     :Camera object
   2048  *   @stream_id :streamID
   2049  *   @fd      : file descritpor for sending ioctl
   2050  *   @id      : control id
   2051  *   @value   : value of the ioctl to be sent
   2052  *
   2053  * RETURN     : int32_t type of status
   2054  *              0  -- success
   2055  *              -1 -- failure
   2056  *==========================================================================*/
   2057 int32_t mm_camera_util_s_ctrl(__unused mm_camera_obj_t *my_obj,
   2058         __unused int stream_id, int32_t fd,
   2059         uint32_t id, int32_t *value)
   2060 {
   2061     int rc = 0;
   2062 
   2063 #ifdef DAEMON_PRESENT
   2064     struct v4l2_control control;
   2065     memset(&control, 0, sizeof(control));
   2066     control.id = id;
   2067     if (value != NULL) {
   2068         control.value = *value;
   2069     }
   2070     rc = ioctl(fd, VIDIOC_S_CTRL, &control);
   2071     LOGD("fd=%d, S_CTRL, id=0x%x, value = %p, rc = %d\n",
   2072           fd, id, value, rc);
   2073     if (rc < 0) {
   2074         LOGE("ioctl failed %d, errno %d", rc, errno);
   2075     } else if (value != NULL) {
   2076         *value = control.value;
   2077     }
   2078 #else /* DAEMON_PRESENT */
   2079     cam_shim_packet_t *shim_cmd;
   2080     cam_shim_cmd_data shim_cmd_data;
   2081     (void)fd;
   2082     (void)value;
   2083     memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
   2084 
   2085     shim_cmd_data.command = id;
   2086     shim_cmd_data.stream_id = stream_id;
   2087     shim_cmd_data.value = NULL;
   2088     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM,
   2089             my_obj->sessionid,&shim_cmd_data);
   2090     rc = mm_camera_module_send_cmd(shim_cmd);
   2091     mm_camera_destroy_shim_cmd_packet(shim_cmd);
   2092 #endif /* DAEMON_PRESENT */
   2093     return (rc >= 0)? 0 : -1;
   2094 }
   2095 
   2096 /*===========================================================================
   2097  * FUNCTION   : mm_camera_util_g_ctrl
   2098  *
   2099  * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
   2100  *
   2101  * PARAMETERS :
   2102  *   @my_obj     :Camera object
   2103  *   @stream_id :streamID
   2104  *   @fd      : file descritpor for sending ioctl
   2105  *   @id      : control id
   2106  *   @value   : value of the ioctl to be sent
   2107  *
   2108  * RETURN     : int32_t type of status
   2109  *              0  -- success
   2110  *              -1 -- failure
   2111  *==========================================================================*/
   2112 int32_t mm_camera_util_g_ctrl(__unused mm_camera_obj_t *my_obj,
   2113         __unused int stream_id, int32_t fd, uint32_t id, int32_t *value)
   2114 {
   2115     int rc = 0;
   2116     struct v4l2_control control;
   2117 
   2118     memset(&control, 0, sizeof(control));
   2119     control.id = id;
   2120     if (value != NULL) {
   2121         control.value = *value;
   2122     }
   2123 
   2124 #ifdef DAEMON_PRESENT
   2125     rc = ioctl(fd, VIDIOC_G_CTRL, &control);
   2126     LOGD("fd=%d, G_CTRL, id=0x%x, rc = %d\n", fd, id, rc);
   2127     if (value != NULL) {
   2128         *value = control.value;
   2129     }
   2130 #else /* DAEMON_PRESENT */
   2131     cam_shim_packet_t *shim_cmd;
   2132     cam_shim_cmd_data shim_cmd_data;
   2133     (void)fd;
   2134     memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
   2135 
   2136     shim_cmd_data.command = id;
   2137     shim_cmd_data.stream_id = stream_id;
   2138     shim_cmd_data.value = value;
   2139     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM,
   2140             my_obj->sessionid, &shim_cmd_data);
   2141 
   2142     rc = mm_camera_module_send_cmd(shim_cmd);
   2143     mm_camera_destroy_shim_cmd_packet(shim_cmd);
   2144 #endif /* DAEMON_PRESENT */
   2145     return (rc >= 0)? 0 : -1;
   2146 }
   2147 
   2148 /*===========================================================================
   2149  * FUNCTION   : mm_camera_create_shim_cmd
   2150  *
   2151  * DESCRIPTION: Prepare comand packet to pass to back-end through shim layer
   2152  *
   2153  * PARAMETERS :
   2154  *   @type                : type of command
   2155  *   @sessionID        : camera sessionID
   2156   *  @data                : command data
   2157  *
   2158  * RETURN     : NULL in case of failures
   2159                       allocated pointer to shim packet
   2160  *==========================================================================*/
   2161 cam_shim_packet_t *mm_camera_create_shim_cmd_packet(cam_shim_cmd_type type,
   2162         uint32_t sessionID, void *data)
   2163 {
   2164     cam_shim_packet_t *shim_pack = NULL;
   2165     uint32_t i = 0;
   2166 
   2167     shim_pack = (cam_shim_packet_t *)malloc(sizeof(cam_shim_packet_t));
   2168     if (shim_pack == NULL) {
   2169         LOGE("Cannot allocate a memory for shim packet");
   2170         return NULL;
   2171     }
   2172     memset(shim_pack, 0, sizeof(cam_shim_packet_t));
   2173     shim_pack->cmd_type = type;
   2174     shim_pack->session_id = sessionID;
   2175     switch (type) {
   2176         case CAM_SHIM_SET_PARM:
   2177         case CAM_SHIM_GET_PARM: {
   2178             cam_shim_cmd_data *cmd_data = (cam_shim_cmd_data *)data;
   2179             shim_pack->cmd_data = *cmd_data;
   2180             break;
   2181         }
   2182         case CAM_SHIM_REG_BUF: {
   2183             cam_reg_buf_t *cmd_data = (cam_reg_buf_t *)data;
   2184             shim_pack->reg_buf = *cmd_data;
   2185             break;
   2186         }
   2187         case CAM_SHIM_BUNDLE_CMD: {
   2188             cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)data;
   2189             for (i = 0; i < cmd_data->stream_count; i++) {
   2190                 shim_pack->bundle_cmd.stream_event[i] = cmd_data->stream_event[i];
   2191             }
   2192             shim_pack->bundle_cmd.stream_count = cmd_data->stream_count;
   2193             break;
   2194         }
   2195         default:
   2196             LOGW("No Data for this command");
   2197     }
   2198     return shim_pack;
   2199 }
   2200 
   2201 /*===========================================================================
   2202  * FUNCTION   : mm_camera_destroy_shim_cmd
   2203  *
   2204  * DESCRIPTION: destroy shim packet
   2205  *
   2206  * PARAMETERS :
   2207  *   @cmd                : ptr to shim packet
   2208 
   2209  * RETURN     : int32_t type of status
   2210  *              0  -- success
   2211  *              -1 -- failure
   2212  *==========================================================================*/
   2213 int32_t mm_camera_destroy_shim_cmd_packet(cam_shim_packet_t *cmd)
   2214 {
   2215     int32_t rc = 0;
   2216     uint32_t i = 0, j = 0;
   2217 
   2218     if (cmd == NULL) {
   2219         LOGW("Command is NULL");
   2220         return rc;
   2221     }
   2222 
   2223     switch (cmd->cmd_type) {
   2224         case CAM_SHIM_SET_PARM:
   2225         case CAM_SHIM_GET_PARM:
   2226         case CAM_SHIM_REG_BUF:
   2227             break;
   2228         case CAM_SHIM_BUNDLE_CMD: {
   2229             cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)cmd;
   2230             for (i = 0; i < cmd_data->stream_count; i++) {
   2231                 cam_shim_cmd_packet_t *stream_evt = &cmd_data->stream_event[i];
   2232                 for (j = 0; j < stream_evt->cmd_count; j++) {
   2233                     if (stream_evt->cmd != NULL) {
   2234                         if(stream_evt->cmd->cmd_type == CAM_SHIM_BUNDLE_CMD) {
   2235                             mm_camera_destroy_shim_cmd_packet(stream_evt->cmd);
   2236                         }
   2237                         free(stream_evt->cmd);
   2238                         stream_evt->cmd = NULL;
   2239                     }
   2240                 }
   2241             }
   2242             break;
   2243         }
   2244         default:
   2245             LOGW("No Data for this command");
   2246     }
   2247     free(cmd);
   2248     cmd = NULL;
   2249     return rc;
   2250 }
   2251 
   2252 /*===========================================================================
   2253  * FUNCTION   : mm_camera_channel_advanced_capture
   2254  *
   2255  * DESCRIPTION: sets the channel advanced capture
   2256  *
   2257  * PARAMETERS :
   2258  *   @my_obj       : camera object
   2259  *   @ch_id        : channel handle
   2260   *   @type : advanced capture type.
   2261  *   @start_flag  : flag to indicate start/stop
   2262   *   @in_value  : input configaration
   2263  *
   2264  * RETURN     : int32_t type of status
   2265  *              0  -- success
   2266  *              -1 -- failure
   2267  *==========================================================================*/
   2268 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj,
   2269             uint32_t ch_id, mm_camera_advanced_capture_t type,
   2270             uint32_t trigger, void *in_value)
   2271 {
   2272     LOGD("E type = %d", type);
   2273     int32_t rc = -1;
   2274     mm_channel_t * ch_obj =
   2275         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   2276 
   2277     if (NULL != ch_obj) {
   2278         pthread_mutex_lock(&ch_obj->ch_lock);
   2279         pthread_mutex_unlock(&my_obj->cam_lock);
   2280         switch (type) {
   2281             case MM_CAMERA_AF_BRACKETING:
   2282                 rc = mm_channel_fsm_fn(ch_obj,
   2283                                        MM_CHANNEL_EVT_AF_BRACKETING,
   2284                                        (void *)&trigger,
   2285                                        NULL);
   2286                 break;
   2287             case MM_CAMERA_AE_BRACKETING:
   2288                 rc = mm_channel_fsm_fn(ch_obj,
   2289                                        MM_CHANNEL_EVT_AE_BRACKETING,
   2290                                        (void *)&trigger,
   2291                                        NULL);
   2292                 break;
   2293             case MM_CAMERA_FLASH_BRACKETING:
   2294                 rc = mm_channel_fsm_fn(ch_obj,
   2295                                        MM_CHANNEL_EVT_FLASH_BRACKETING,
   2296                                        (void *)&trigger,
   2297                                        NULL);
   2298                 break;
   2299             case MM_CAMERA_ZOOM_1X:
   2300                 rc = mm_channel_fsm_fn(ch_obj,
   2301                                        MM_CHANNEL_EVT_ZOOM_1X,
   2302                                        (void *)&trigger,
   2303                                        NULL);
   2304                 break;
   2305             case MM_CAMERA_FRAME_CAPTURE:
   2306                 rc = mm_channel_fsm_fn(ch_obj,
   2307                                        MM_CAMERA_EVT_CAPTURE_SETTING,
   2308                                        (void *)in_value,
   2309                                        NULL);
   2310                 break;
   2311             default:
   2312                 break;
   2313         }
   2314 
   2315     } else {
   2316         pthread_mutex_unlock(&my_obj->cam_lock);
   2317     }
   2318 
   2319     LOGD("X");
   2320     return rc;
   2321 }
   2322 
   2323 /*===========================================================================
   2324  * FUNCTION   : mm_camera_get_session_id
   2325  *
   2326  * DESCRIPTION: get the session identity
   2327  *
   2328  * PARAMETERS :
   2329  *   @my_obj       : camera object
   2330  *   @sessionid: pointer to the output session id
   2331  *
   2332  * RETURN     : int32_t type of status
   2333  *              0  -- success
   2334  *              -1 -- failure
   2335  * NOTE       : if this call succeeds, we will get a valid session id
   2336  *==========================================================================*/
   2337 int32_t mm_camera_get_session_id(mm_camera_obj_t *my_obj,
   2338         uint32_t* sessionid)
   2339 {
   2340     int32_t rc = -1;
   2341     int32_t value = 0;
   2342     if(sessionid != NULL) {
   2343         struct v4l2_control control;
   2344         memset(&control, 0, sizeof(control));
   2345         control.id = MSM_CAMERA_PRIV_G_SESSION_ID;
   2346         control.value = value;
   2347 
   2348         rc = ioctl(my_obj->ctrl_fd, VIDIOC_G_CTRL, &control);
   2349         value = control.value;
   2350         LOGD("fd=%d, get_session_id, id=0x%x, value = %d, rc = %d\n",
   2351                  my_obj->ctrl_fd, MSM_CAMERA_PRIV_G_SESSION_ID,
   2352                 value, rc);
   2353         *sessionid = value;
   2354     }
   2355     return rc;
   2356 }
   2357 
   2358 /*===========================================================================
   2359  * FUNCTION   : mm_camera_sync_related_sensors
   2360  *
   2361  * DESCRIPTION: send sync cmd
   2362  *
   2363  * PARAMETERS :
   2364  *   @my_obj       : camera object
   2365  *   @parms        : ptr to the related cam info to be sent to server
   2366  *
   2367  * RETURN     : int32_t type of status
   2368  *              0  -- success
   2369  *              -1 -- failure
   2370  * NOTE       : Assume the sync struct buf is already mapped to server via
   2371  *              domain socket. Corresponding fields of parameters to be set
   2372  *              are already filled in by upper layer caller.
   2373  *==========================================================================*/
   2374 int32_t mm_camera_sync_related_sensors(mm_camera_obj_t *my_obj,
   2375         cam_sync_related_sensors_event_info_t* parms)
   2376 {
   2377     int32_t rc = -1;
   2378     int32_t value = 0;
   2379     if (parms !=  NULL) {
   2380         rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
   2381                 CAM_PRIV_SYNC_RELATED_SENSORS, &value);
   2382     }
   2383     pthread_mutex_unlock(&my_obj->cam_lock);
   2384     return rc;
   2385 }
   2386 
   2387 /*===========================================================================
   2388  * FUNCTION   : mm_camera_reg_stream_buf_cb
   2389  *
   2390  * DESCRIPTION: Register callback for stream buffer
   2391  *
   2392  * PARAMETERS :
   2393  *   @my_obj    : camera object
   2394  *   @ch_id     : channel handle
   2395  *   @stream_id : stream that will be linked
   2396  *   @buf_cb    : special callback needs to be registered for stream buffer
   2397  *   @cb_type   : Callback type SYNC/ASYNC
   2398  *   @userdata  : user data pointer
   2399  *
   2400  * RETURN    : int32_t type of status
   2401  *             0  -- success
   2402  *             1 --  failure
   2403  *==========================================================================*/
   2404 int32_t mm_camera_reg_stream_buf_cb(mm_camera_obj_t *my_obj,
   2405         uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t stream_cb,
   2406         mm_camera_stream_cb_type cb_type, void *userdata)
   2407 {
   2408     int rc = 0;
   2409     mm_stream_data_cb_t buf_cb;
   2410     mm_channel_t * ch_obj =
   2411             mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   2412 
   2413     if (NULL != ch_obj) {
   2414         pthread_mutex_lock(&ch_obj->ch_lock);
   2415         pthread_mutex_unlock(&my_obj->cam_lock);
   2416 
   2417         memset(&buf_cb, 0, sizeof(mm_stream_data_cb_t));
   2418         buf_cb.cb = stream_cb;
   2419         buf_cb.cb_count = -1;
   2420         buf_cb.cb_type = cb_type;
   2421         buf_cb.user_data = userdata;
   2422 
   2423         mm_evt_paylod_reg_stream_buf_cb payload;
   2424         memset(&payload, 0, sizeof(mm_evt_paylod_reg_stream_buf_cb));
   2425         payload.buf_cb = buf_cb;
   2426         payload.stream_id = stream_id;
   2427         mm_channel_fsm_fn(ch_obj,
   2428                 MM_CHANNEL_EVT_REG_STREAM_BUF_CB,
   2429                 (void*)&payload, NULL);
   2430     } else {
   2431         pthread_mutex_unlock(&my_obj->cam_lock);
   2432     }
   2433     return rc;
   2434 }
   2435 
   2436 #ifdef QCAMERA_REDEFINE_LOG
   2437 
   2438 /*===========================================================================
   2439  * DESCRIPTION: mm camera debug interface
   2440  *
   2441  *==========================================================================*/
   2442 pthread_mutex_t dbg_log_mutex;
   2443 
   2444 #undef LOG_TAG
   2445 #define LOG_TAG "QCamera"
   2446 #define CDBG_MAX_STR_LEN 1024
   2447 #define CDBG_MAX_LINE_LENGTH 256
   2448 
   2449 /* current trace loggin permissions
   2450    * {NONE, ERR, WARN, HIGH, DEBUG, LOW, INFO} */
   2451 int g_cam_log[CAM_LAST_MODULE][CAM_GLBL_DBG_INFO + 1] = {
   2452     {0, 1, 0, 0, 0, 0, 1}, /* CAM_NO_MODULE     */
   2453     {0, 1, 0, 0, 0, 0, 1}, /* CAM_HAL_MODULE    */
   2454     {0, 1, 0, 0, 0, 0, 1}, /* CAM_MCI_MODULE    */
   2455     {0, 1, 0, 0, 0, 0, 1}, /* CAM_JPEG_MODULE   */
   2456 };
   2457 
   2458 /* string representation for logging level */
   2459 static const char *cam_dbg_level_to_str[] = {
   2460      "",        /* CAM_GLBL_DBG_NONE  */
   2461      "<ERROR>", /* CAM_GLBL_DBG_ERR   */
   2462      "<WARN>", /* CAM_GLBL_DBG_WARN  */
   2463      "<HIGH>", /* CAM_GLBL_DBG_HIGH  */
   2464      "<DBG>", /* CAM_GLBL_DBG_DEBUG */
   2465      "<LOW>", /* CAM_GLBL_DBG_LOW   */
   2466      "<INFO>"  /* CAM_GLBL_DBG_INFO  */
   2467 };
   2468 
   2469 /* current trace logging configuration */
   2470 typedef struct {
   2471    cam_global_debug_level_t  level;
   2472    int                       initialized;
   2473    const char               *name;
   2474    const char               *prop;
   2475 } module_debug_t;
   2476 
   2477 static module_debug_t cam_loginfo[(int)CAM_LAST_MODULE] = {
   2478   {CAM_GLBL_DBG_ERR, 1,
   2479       "",         "persist.camera.global.debug"     }, /* CAM_NO_MODULE     */
   2480   {CAM_GLBL_DBG_ERR, 1,
   2481       "<HAL>", "persist.camera.hal.debug"        }, /* CAM_HAL_MODULE    */
   2482   {CAM_GLBL_DBG_ERR, 1,
   2483       "<MCI>", "persist.camera.mci.debug"        }, /* CAM_MCI_MODULE    */
   2484   {CAM_GLBL_DBG_ERR, 1,
   2485       "<JPEG>", "persist.camera.mmstill.logs"     }, /* CAM_JPEG_MODULE   */
   2486 };
   2487 
   2488 /** cam_get_dbg_level
   2489  *
   2490  *    @module: module name
   2491  *    @level:  module debug logging level
   2492  *
   2493  *  Maps debug log string to value.
   2494  *
   2495  *  Return: logging level
   2496  **/
   2497 __unused
   2498 static cam_global_debug_level_t cam_get_dbg_level(const char *module,
   2499   char *pValue) {
   2500 
   2501   cam_global_debug_level_t rc = CAM_GLBL_DBG_NONE;
   2502 
   2503   if (!strcmp(pValue, "none")) {
   2504     rc = CAM_GLBL_DBG_NONE;
   2505   } else if (!strcmp(pValue, "warn")) {
   2506     rc = CAM_GLBL_DBG_WARN;
   2507   } else if (!strcmp(pValue, "debug")) {
   2508     rc = CAM_GLBL_DBG_DEBUG;
   2509   } else if (!strcmp(pValue, "error")) {
   2510     rc = CAM_GLBL_DBG_ERR;
   2511   } else if (!strcmp(pValue, "low")) {
   2512     rc = CAM_GLBL_DBG_LOW;
   2513   } else if (!strcmp(pValue, "high")) {
   2514     rc = CAM_GLBL_DBG_HIGH;
   2515   } else if (!strcmp(pValue, "info")) {
   2516     rc = CAM_GLBL_DBG_INFO;
   2517   } else {
   2518     ALOGE("Invalid %s debug log level %s\n", module, pValue);
   2519   }
   2520 
   2521   ALOGD("%s debug log level: %s\n", module, cam_dbg_level_to_str[rc]);
   2522 
   2523   return rc;
   2524 }
   2525 
   2526 /** cam_vsnprintf
   2527  *    @pdst:   destination buffer pointer
   2528  *    @size:   size of destination b uffer
   2529  *    @pfmt:   string format
   2530  *    @argptr: variabkle length argument list
   2531  *
   2532  *  Processes variable length argument list to a formatted string.
   2533  *
   2534  *  Return: n/a
   2535  **/
   2536 static void cam_vsnprintf(char* pdst, unsigned int size,
   2537                           const char* pfmt, va_list argptr) {
   2538   int num_chars_written = 0;
   2539 
   2540   pdst[0] = '\0';
   2541   num_chars_written = vsnprintf(pdst, size, pfmt, argptr);
   2542 
   2543   if ((num_chars_written >= (int)size) && (size > 0)) {
   2544      /* Message length exceeds the buffer limit size */
   2545      num_chars_written = size - 1;
   2546      pdst[size - 1] = '\0';
   2547   }
   2548 }
   2549 
   2550 /** mm_camera_debug_log
   2551  *    @module: origin or log message
   2552  *    @level:  logging level
   2553  *    @func:   caller function name
   2554  *    @line:   caller line number
   2555  *    @fmt:    log message formatting string
   2556  *    @...:    variable argument list
   2557  *
   2558  *  Generig logger method.
   2559  *
   2560  *  Return: N/A
   2561  **/
   2562 void mm_camera_debug_log(const cam_modules_t module,
   2563                    const cam_global_debug_level_t level,
   2564                    const char *func, const int line, const char *fmt, ...) {
   2565   char    str_buffer[CDBG_MAX_STR_LEN];
   2566   va_list args;
   2567 
   2568   va_start(args, fmt);
   2569   cam_vsnprintf(str_buffer, CDBG_MAX_STR_LEN, fmt, args);
   2570   va_end(args);
   2571 
   2572   switch (level) {
   2573   case CAM_GLBL_DBG_WARN:
   2574     ALOGW("%s%s %s: %d: %s", cam_loginfo[module].name,
   2575       cam_dbg_level_to_str[level], func, line, str_buffer);
   2576     break;
   2577   case CAM_GLBL_DBG_ERR:
   2578     ALOGE("%s%s %s: %d: %s", cam_loginfo[module].name,
   2579       cam_dbg_level_to_str[level], func, line, str_buffer);
   2580     break;
   2581   case CAM_GLBL_DBG_INFO:
   2582     ALOGI("%s%s %s: %d: %s", cam_loginfo[module].name,
   2583       cam_dbg_level_to_str[level], func, line, str_buffer);
   2584     break;
   2585   case CAM_GLBL_DBG_HIGH:
   2586   case CAM_GLBL_DBG_DEBUG:
   2587   case CAM_GLBL_DBG_LOW:
   2588   default:
   2589     ALOGD("%s%s %s: %d: %s", cam_loginfo[module].name,
   2590       cam_dbg_level_to_str[level], func, line, str_buffer);
   2591   }
   2592 }
   2593 
   2594  /** mm_camera_set_dbg_log_properties
   2595  *
   2596  *  Set global and module log level properties.
   2597  *
   2598  *  Return: N/A
   2599  **/
   2600 void mm_camera_set_dbg_log_properties(void) {
   2601   int          i;
   2602   unsigned int j;
   2603   static int   boot_init = 1;
   2604   char         property_value[PROPERTY_VALUE_MAX] = {0};
   2605   char         default_value[PROPERTY_VALUE_MAX]  = {0};
   2606 
   2607   if (boot_init) {
   2608       boot_init = 0;
   2609       pthread_mutex_init(&dbg_log_mutex, 0);
   2610   }
   2611 
   2612   /* set global and individual module logging levels */
   2613   pthread_mutex_lock(&dbg_log_mutex);
   2614   for (i = CAM_NO_MODULE; i < CAM_LAST_MODULE; i++) {
   2615     cam_global_debug_level_t log_level;
   2616     snprintf(default_value, PROPERTY_VALUE_MAX, "%d", (int)cam_loginfo[i].level);
   2617     property_get(cam_loginfo[i].prop, property_value, default_value);
   2618     log_level = (cam_global_debug_level_t)atoi(property_value);
   2619 
   2620     /* fix KW warnings */
   2621     if (log_level > CAM_GLBL_DBG_INFO) {
   2622        log_level = CAM_GLBL_DBG_INFO;
   2623     }
   2624 
   2625     cam_loginfo[i].level = log_level;
   2626 
   2627     /* The logging macros will produce a log message when logging level for
   2628      * a module is less or equal to the level specified in the property for
   2629      * the module, or less or equal the level specified by the global logging
   2630      * property. Currently we don't allow INFO logging to be turned off */
   2631     for (j = CAM_GLBL_DBG_ERR; j <= CAM_GLBL_DBG_LOW; j++) {
   2632       g_cam_log[i][j] = (cam_loginfo[CAM_NO_MODULE].level != CAM_GLBL_DBG_NONE)     &&
   2633                         (cam_loginfo[i].level             != CAM_GLBL_DBG_NONE)     &&
   2634                         ((j                                <= cam_loginfo[i].level) ||
   2635                          (j                                <= cam_loginfo[CAM_NO_MODULE].level));
   2636     }
   2637   }
   2638   pthread_mutex_unlock(&dbg_log_mutex);
   2639 }
   2640 
   2641 #endif
   2642