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