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