Home | History | Annotate | Download | only in src
      1 /* Copyright (c) 2012-2015, 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 #include <pthread.h>
     31 #include <errno.h>
     32 #include <sys/ioctl.h>
     33 #include <sys/types.h>
     34 #include <sys/stat.h>
     35 #include <fcntl.h>
     36 #include <poll.h>
     37 #include <cutils/properties.h>
     38 #include <stdlib.h>
     39 
     40 #include <cam_semaphore.h>
     41 
     42 #include "mm_camera_dbg.h"
     43 #include "mm_camera_sock.h"
     44 #include "mm_camera_interface.h"
     45 #include "mm_camera.h"
     46 
     47 #define SET_PARM_BIT32(parm, parm_arr) \
     48     (parm_arr[parm/32] |= (1<<(parm%32)))
     49 
     50 #define GET_PARM_BIT32(parm, parm_arr) \
     51     ((parm_arr[parm/32]>>(parm%32))& 0x1)
     52 
     53 #define WAIT_TIMEOUT 3
     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 
     61 /*===========================================================================
     62  * FUNCTION   : mm_camera_util_get_channel_by_handler
     63  *
     64  * DESCRIPTION: utility function to get a channel object from its handle
     65  *
     66  * PARAMETERS :
     67  *   @cam_obj: ptr to a camera object
     68  *   @handler: channel handle
     69  *
     70  * RETURN     : ptr to a channel object.
     71  *              NULL if failed.
     72  *==========================================================================*/
     73 mm_channel_t * mm_camera_util_get_channel_by_handler(
     74                                     mm_camera_obj_t * cam_obj,
     75                                     uint32_t handler)
     76 {
     77     int i;
     78     mm_channel_t *ch_obj = NULL;
     79     for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
     80         if (handler == cam_obj->ch[i].my_hdl) {
     81             ch_obj = &cam_obj->ch[i];
     82             break;
     83         }
     84     }
     85     return ch_obj;
     86 }
     87 
     88 /*===========================================================================
     89  * FUNCTION   : mm_camera_util_chip_is_a_family
     90  *
     91  * DESCRIPTION: utility function to check if the host is A family chip
     92  *
     93  * PARAMETERS :
     94  *
     95  * RETURN     : TRUE if A family.
     96  *              FALSE otherwise.
     97  *==========================================================================*/
     98 uint8_t mm_camera_util_chip_is_a_family(void)
     99 {
    100 #ifdef USE_A_FAMILY
    101     return TRUE;
    102 #else
    103     return FALSE;
    104 #endif
    105 }
    106 
    107 /*===========================================================================
    108  * FUNCTION   : mm_camera_dispatch_app_event
    109  *
    110  * DESCRIPTION: dispatch event to apps who regitster for event notify
    111  *
    112  * PARAMETERS :
    113  *   @cmd_cb: ptr to a struct storing event info
    114  *   @user_data: user data ptr (camera object)
    115  *
    116  * RETURN     : none
    117  *==========================================================================*/
    118 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
    119                                          void* user_data)
    120 {
    121     mm_camera_cmd_thread_name("mm_cam_event");
    122     int i;
    123     mm_camera_event_t *event = &cmd_cb->u.evt;
    124     mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data;
    125     if (NULL != my_obj) {
    126         pthread_mutex_lock(&my_obj->cb_lock);
    127         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
    128             if(my_obj->evt.evt[i].evt_cb) {
    129                 my_obj->evt.evt[i].evt_cb(
    130                     my_obj->my_hdl,
    131                     event,
    132                     my_obj->evt.evt[i].user_data);
    133             }
    134         }
    135         pthread_mutex_unlock(&my_obj->cb_lock);
    136     }
    137 }
    138 
    139 /*===========================================================================
    140  * FUNCTION   : mm_camera_event_notify
    141  *
    142  * DESCRIPTION: callback to handle event notify from kernel. This call will
    143  *              dequeue event from kernel.
    144  *
    145  * PARAMETERS :
    146  *   @user_data: user data ptr (camera object)
    147  *
    148  * RETURN     : none
    149  *==========================================================================*/
    150 static void mm_camera_event_notify(void* user_data)
    151 {
    152     struct v4l2_event ev;
    153     struct msm_v4l2_event_data *msm_evt = NULL;
    154     int rc;
    155     mm_camera_event_t evt;
    156     memset(&evt, 0, sizeof(mm_camera_event_t));
    157 
    158     mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
    159     if (NULL != my_obj) {
    160         /* read evt */
    161         memset(&ev, 0, sizeof(ev));
    162         rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
    163 
    164         if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
    165             msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
    166             switch (msm_evt->command) {
    167             case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
    168                 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ;
    169                 mm_camera_enqueue_evt(my_obj, &evt);
    170                 break;
    171             case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
    172                 pthread_mutex_lock(&my_obj->evt_lock);
    173                 my_obj->evt_rcvd.server_event_type = msm_evt->command;
    174                 my_obj->evt_rcvd.status = msm_evt->status;
    175                 pthread_cond_signal(&my_obj->evt_cond);
    176                 pthread_mutex_unlock(&my_obj->evt_lock);
    177                 break;
    178             case CAM_EVENT_TYPE_INT_TAKE_JPEG:
    179             case CAM_EVENT_TYPE_INT_TAKE_RAW:
    180                 {
    181                     evt.server_event_type = msm_evt->command;
    182                     mm_camera_enqueue_evt(my_obj, &evt);
    183                 }
    184                 break;
    185             case MSM_CAMERA_PRIV_SHUTDOWN:
    186                 {
    187                     evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
    188                     mm_camera_enqueue_evt(my_obj, &evt);
    189                 }
    190                 break;
    191             default:
    192                 break;
    193             }
    194         }
    195     }
    196 }
    197 
    198 /*===========================================================================
    199  * FUNCTION   : mm_camera_enqueue_evt
    200  *
    201  * DESCRIPTION: enqueue received event into event queue to be processed by
    202  *              event thread.
    203  *
    204  * PARAMETERS :
    205  *   @my_obj   : ptr to a camera object
    206  *   @event    : event to be queued
    207  *
    208  * RETURN     : int32_t type of status
    209  *              0  -- success
    210  *              -1 -- failure
    211  *==========================================================================*/
    212 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
    213                               mm_camera_event_t *event)
    214 {
    215     int32_t rc = 0;
    216     mm_camera_cmdcb_t *node = NULL;
    217 
    218     node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    219     if (NULL != node) {
    220         memset(node, 0, sizeof(mm_camera_cmdcb_t));
    221         node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
    222         node->u.evt = *event;
    223 
    224         /* enqueue to evt cmd thread */
    225         cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
    226         /* wake up evt cmd thread */
    227         cam_sem_post(&(my_obj->evt_thread.cmd_sem));
    228     } else {
    229         CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
    230         rc = -1;
    231     }
    232 
    233     return rc;
    234 }
    235 
    236 /*===========================================================================
    237  * FUNCTION   : mm_camera_open
    238  *
    239  * DESCRIPTION: open a camera
    240  *
    241  * PARAMETERS :
    242  *   @my_obj   : ptr to a camera object
    243  *
    244  * RETURN     : int32_t type of status
    245  *              0  -- success
    246  *              -1 -- failure
    247  *==========================================================================*/
    248 int32_t mm_camera_open(mm_camera_obj_t *my_obj)
    249 {
    250     char dev_name[MM_CAMERA_DEV_NAME_LEN];
    251     int32_t rc = 0;
    252     int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
    253     uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
    254     int cam_idx = 0;
    255     const char *dev_name_value = NULL;
    256     char prop[PROPERTY_VALUE_MAX];
    257     uint32_t globalLogLevel = 0;
    258 
    259     property_get("persist.camera.hal.debug", prop, "0");
    260     int val = atoi(prop);
    261     if (0 <= val) {
    262         gMmCameraIntfLogLevel = (uint32_t)val;
    263     }
    264     property_get("persist.camera.global.debug", prop, "0");
    265     val = atoi(prop);
    266     if (0 <= val) {
    267         globalLogLevel = (uint32_t)val;
    268     }
    269 
    270     /* Highest log level among hal.logs and global.logs is selected */
    271     if (gMmCameraIntfLogLevel < globalLogLevel)
    272         gMmCameraIntfLogLevel = globalLogLevel;
    273 
    274     CDBG("%s:  begin\n", __func__);
    275 
    276     if (NULL == my_obj) {
    277         goto on_error;
    278     }
    279     dev_name_value = mm_camera_util_get_dev_name(my_obj->my_hdl);
    280     if (NULL == dev_name_value) {
    281         goto on_error;
    282     }
    283     snprintf(dev_name, sizeof(dev_name), "/dev/%s",
    284              dev_name_value);
    285     sscanf(dev_name, "/dev/video%d", &cam_idx);
    286     CDBG("%s: dev name = %s, cam_idx = %d", __func__, dev_name, cam_idx);
    287 
    288     do{
    289         n_try--;
    290         errno = 0;
    291         my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
    292         CDBG("%s:  ctrl_fd = %d, errno == %d", __func__, my_obj->ctrl_fd, errno);
    293         if((my_obj->ctrl_fd >= 0) ||
    294                 (errno != EIO && errno != ETIMEDOUT && errno != ENODEV) ||
    295                 (n_try <= 0 )) {
    296             CDBG_HIGH("%s:  opened, break out while loop", __func__);
    297             if (my_obj->ctrl_fd < 0) {
    298                     ALOGE("%s: Failed to open %s: %s(%d).", __func__, dev_name,
    299                             strerror(-errno), errno);
    300             }
    301             break;
    302         }
    303         ALOGE("%s:Failed with %s error, retrying after %d milli-seconds",
    304              __func__, strerror(errno), sleep_msec);
    305         usleep(sleep_msec * 1000U);
    306     }while (n_try > 0);
    307 
    308     if (my_obj->ctrl_fd < 0) {
    309         CDBG_ERROR("%s: cannot open control fd of '%s' (%s)\n",
    310                  __func__, dev_name, strerror(errno));
    311         if (errno == EBUSY)
    312             rc = -EUSERS;
    313         else
    314             rc = -1;
    315         goto on_error;
    316     }
    317 
    318     /* open domain socket*/
    319     n_try = MM_CAMERA_DEV_OPEN_TRIES;
    320     do {
    321         n_try--;
    322         my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
    323         CDBG("%s:  ds_fd = %d, errno = %d", __func__, my_obj->ds_fd, errno);
    324         if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {
    325             CDBG("%s:  opened, break out while loop", __func__);
    326             break;
    327         }
    328         CDBG("%s:failed with I/O error retrying after %d milli-seconds",
    329              __func__, sleep_msec);
    330         usleep(sleep_msec * 1000U);
    331     } while (n_try > 0);
    332 
    333     if (my_obj->ds_fd < 0) {
    334         CDBG_ERROR("%s: cannot open domain socket fd of '%s'(%s)\n",
    335                  __func__, dev_name, strerror(errno));
    336         rc = -1;
    337         goto on_error;
    338     }
    339     pthread_mutex_init(&my_obj->msg_lock, NULL);
    340 
    341     pthread_mutex_init(&my_obj->cb_lock, NULL);
    342     pthread_mutex_init(&my_obj->evt_lock, NULL);
    343     pthread_cond_init(&my_obj->evt_cond, NULL);
    344 
    345     CDBG("%s : Launch evt Thread in Cam Open",__func__);
    346     snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch");
    347     mm_camera_cmd_thread_launch(&my_obj->evt_thread,
    348                                 mm_camera_dispatch_app_event,
    349                                 (void *)my_obj);
    350 
    351     /* launch event poll thread
    352      * we will add evt fd into event poll thread upon user first register for evt */
    353     CDBG("%s : Launch evt Poll Thread in Cam Open", __func__);
    354     snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Poll");
    355     mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
    356                                  MM_CAMERA_POLL_TYPE_EVT);
    357     mm_camera_evt_sub(my_obj, TRUE);
    358 
    359     /* unlock cam_lock, we need release global intf_lock in camera_open(),
    360      * in order not block operation of other Camera in dual camera use case.*/
    361     pthread_mutex_unlock(&my_obj->cam_lock);
    362     CDBG("%s:  end (rc = %d)\n", __func__, rc);
    363     return rc;
    364 
    365 on_error:
    366 
    367     if (NULL == dev_name_value) {
    368         CDBG_ERROR("%s: Invalid device name\n", __func__);
    369         rc = -1;
    370     }
    371 
    372     if (NULL == my_obj) {
    373         CDBG_ERROR("%s: Invalid camera object\n", __func__);
    374         rc = -1;
    375     } else {
    376         if (my_obj->ctrl_fd >= 0) {
    377             close(my_obj->ctrl_fd);
    378             my_obj->ctrl_fd = -1;
    379         }
    380         if (my_obj->ds_fd >= 0) {
    381             mm_camera_socket_close(my_obj->ds_fd);
    382             my_obj->ds_fd = -1;
    383         }
    384     }
    385 
    386     /* unlock cam_lock, we need release global intf_lock in camera_open(),
    387      * in order not block operation of other Camera in dual camera use case.*/
    388     pthread_mutex_unlock(&my_obj->cam_lock);
    389     return rc;
    390 }
    391 
    392 /*===========================================================================
    393  * FUNCTION   : mm_camera_close
    394  *
    395  * DESCRIPTION: enqueue received event into event queue to be processed by
    396  *              event thread.
    397  *
    398  * PARAMETERS :
    399  *   @my_obj   : ptr to a camera object
    400  *   @event    : event to be queued
    401  *
    402  * RETURN     : int32_t type of status
    403  *              0  -- success
    404  *              -1 -- failure
    405  *==========================================================================*/
    406 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
    407 {
    408     CDBG("%s : unsubscribe evt", __func__);
    409     mm_camera_evt_sub(my_obj, FALSE);
    410 
    411     CDBG("%s : Close evt Poll Thread in Cam Close",__func__);
    412     mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
    413 
    414     CDBG("%s : Close evt cmd Thread in Cam Close",__func__);
    415     mm_camera_cmd_thread_release(&my_obj->evt_thread);
    416 
    417     if(my_obj->ctrl_fd >= 0) {
    418         close(my_obj->ctrl_fd);
    419         my_obj->ctrl_fd = -1;
    420     }
    421     if(my_obj->ds_fd >= 0) {
    422         mm_camera_socket_close(my_obj->ds_fd);
    423         my_obj->ds_fd = -1;
    424     }
    425     pthread_mutex_destroy(&my_obj->msg_lock);
    426 
    427     pthread_mutex_destroy(&my_obj->cb_lock);
    428     pthread_mutex_destroy(&my_obj->evt_lock);
    429     pthread_cond_destroy(&my_obj->evt_cond);
    430 
    431     pthread_mutex_unlock(&my_obj->cam_lock);
    432     return 0;
    433 }
    434 
    435 /*===========================================================================
    436  * FUNCTION   : mm_camera_close_fd
    437  *
    438  * DESCRIPTION: close the ctrl_fd and socket fd in case of an error so that
    439  *              the backend will close
    440  *              Do NOT close or release any HAL resources since a close_camera
    441  *              has not been called yet.
    442  * PARAMETERS :
    443  *   @my_obj   : ptr to a camera object
    444  *   @event    : event to be queued
    445  *
    446  * RETURN     : int32_t type of status
    447  *              0  -- success
    448  *              -1 -- failure
    449  *==========================================================================*/
    450 int32_t mm_camera_close_fd(mm_camera_obj_t *my_obj)
    451 {
    452     if(my_obj->ctrl_fd >= 0) {
    453         close(my_obj->ctrl_fd);
    454         my_obj->ctrl_fd = -1;
    455     }
    456     if(my_obj->ds_fd >= 0) {
    457         mm_camera_socket_close(my_obj->ds_fd);
    458         my_obj->ds_fd = -1;
    459     }
    460     pthread_mutex_unlock(&my_obj->cam_lock);
    461     return 0;
    462 }
    463 
    464 /*===========================================================================
    465  * FUNCTION   : mm_camera_register_event_notify_internal
    466  *
    467  * DESCRIPTION: internal implementation for registering callback for event notify.
    468  *
    469  * PARAMETERS :
    470  *   @my_obj   : ptr to a camera object
    471  *   @evt_cb   : callback to be registered to handle event notify
    472  *   @user_data: user data ptr
    473  *
    474  * RETURN     : int32_t type of status
    475  *              0  -- success
    476  *              -1 -- failure
    477  *==========================================================================*/
    478 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
    479                                                  mm_camera_event_notify_t evt_cb,
    480                                                  void * user_data)
    481 {
    482     int i;
    483     int rc = -1;
    484     mm_camera_evt_obj_t *evt_array = NULL;
    485 
    486     pthread_mutex_lock(&my_obj->cb_lock);
    487     evt_array = &my_obj->evt;
    488     if(evt_cb) {
    489         /* this is reg case */
    490         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
    491             if(evt_array->evt[i].user_data == NULL) {
    492                 evt_array->evt[i].evt_cb = evt_cb;
    493                 evt_array->evt[i].user_data = user_data;
    494                 evt_array->reg_count++;
    495                 rc = 0;
    496                 break;
    497             }
    498         }
    499     } else {
    500         /* this is unreg case */
    501         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
    502             if(evt_array->evt[i].user_data == user_data) {
    503                 evt_array->evt[i].evt_cb = NULL;
    504                 evt_array->evt[i].user_data = NULL;
    505                 evt_array->reg_count--;
    506                 rc = 0;
    507                 break;
    508             }
    509         }
    510     }
    511 
    512     pthread_mutex_unlock(&my_obj->cb_lock);
    513     return rc;
    514 }
    515 
    516 /*===========================================================================
    517  * FUNCTION   : mm_camera_register_event_notify
    518  *
    519  * DESCRIPTION: registering a callback for event notify.
    520  *
    521  * PARAMETERS :
    522  *   @my_obj   : ptr to a camera object
    523  *   @evt_cb   : callback to be registered to handle event notify
    524  *   @user_data: user data ptr
    525  *
    526  * RETURN     : int32_t type of status
    527  *              0  -- success
    528  *              -1 -- failure
    529  *==========================================================================*/
    530 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
    531                                         mm_camera_event_notify_t evt_cb,
    532                                         void * user_data)
    533 {
    534     int rc = -1;
    535     rc = mm_camera_register_event_notify_internal(my_obj,
    536                                                   evt_cb,
    537                                                   user_data);
    538     pthread_mutex_unlock(&my_obj->cam_lock);
    539     return rc;
    540 }
    541 
    542 /*===========================================================================
    543  * FUNCTION   : mm_camera_qbuf
    544  *
    545  * DESCRIPTION: enqueue buffer back to kernel
    546  *
    547  * PARAMETERS :
    548  *   @my_obj       : camera object
    549  *   @ch_id        : channel handle
    550  *   @buf          : buf ptr to be enqueued
    551  *
    552  * RETURN     : int32_t type of status
    553  *              0  -- success
    554  *              -1 -- failure
    555  *==========================================================================*/
    556 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
    557                        uint32_t ch_id,
    558                        mm_camera_buf_def_t *buf)
    559 {
    560     int rc = -1;
    561     mm_channel_t * ch_obj = NULL;
    562     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    563 
    564     pthread_mutex_unlock(&my_obj->cam_lock);
    565 
    566     /* we always assume qbuf will be done before channel/stream is fully stopped
    567      * because qbuf is done within dataCB context
    568      * in order to avoid deadlock, we are not locking ch_lock for qbuf */
    569     if (NULL != ch_obj) {
    570         rc = mm_channel_qbuf(ch_obj, buf);
    571     }
    572 
    573     return rc;
    574 }
    575 
    576 /*===========================================================================
    577  * FUNCTION   : mm_camera_get_queued_buf_count
    578  *
    579  * DESCRIPTION: return queued buffer count
    580  *
    581  * PARAMETERS :
    582  *   @my_obj       : camera object
    583  *   @ch_id        : channel handle
    584  *   @stream_id : stream id
    585  *
    586  * RETURN     : queued buffer count
    587  *==========================================================================*/
    588 int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj,
    589         uint32_t ch_id, uint32_t stream_id)
    590 {
    591     int rc = -1;
    592     mm_channel_t * ch_obj = NULL;
    593     uint32_t payload;
    594     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    595     payload = stream_id;
    596 
    597     if (NULL != ch_obj) {
    598         pthread_mutex_lock(&ch_obj->ch_lock);
    599         pthread_mutex_unlock(&my_obj->cam_lock);
    600         rc = mm_channel_fsm_fn(ch_obj,
    601                 MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT,
    602                 (void *)&payload,
    603                 NULL);
    604     } else {
    605         pthread_mutex_unlock(&my_obj->cam_lock);
    606     }
    607 
    608     return rc;
    609 }
    610 
    611 /*===========================================================================
    612  * FUNCTION   : mm_camera_query_capability
    613  *
    614  * DESCRIPTION: query camera capability
    615  *
    616  * PARAMETERS :
    617  *   @my_obj: camera object
    618  *
    619  * RETURN     : int32_t type of status
    620  *              0  -- success
    621  *              -1 -- failure
    622  *==========================================================================*/
    623 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
    624 {
    625     int32_t rc = 0;
    626     struct v4l2_capability cap;
    627 
    628     /* get camera capabilities */
    629     memset(&cap, 0, sizeof(cap));
    630     rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
    631     if (rc != 0) {
    632         CDBG_ERROR("%s: cannot get camera capabilities, rc = %d\n", __func__, rc);
    633     }
    634 
    635     pthread_mutex_unlock(&my_obj->cam_lock);
    636     return rc;
    637 
    638 }
    639 
    640 /*===========================================================================
    641  * FUNCTION   : mm_camera_set_parms
    642  *
    643  * DESCRIPTION: set parameters per camera
    644  *
    645  * PARAMETERS :
    646  *   @my_obj       : camera object
    647  *   @parms        : ptr to a param struct to be set to server
    648  *
    649  * RETURN     : int32_t type of status
    650  *              0  -- success
    651  *              -1 -- failure
    652  * NOTE       : Assume the parms struct buf is already mapped to server via
    653  *              domain socket. Corresponding fields of parameters to be set
    654  *              are already filled in by upper layer caller.
    655  *==========================================================================*/
    656 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj,
    657                             parm_buffer_t *parms)
    658 {
    659     int32_t rc = -1;
    660     int32_t value = 0;
    661     if (parms !=  NULL) {
    662         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
    663     }
    664     pthread_mutex_unlock(&my_obj->cam_lock);
    665     return rc;
    666 }
    667 
    668 /*===========================================================================
    669  * FUNCTION   : mm_camera_get_parms
    670  *
    671  * DESCRIPTION: get parameters per camera
    672  *
    673  * PARAMETERS :
    674  *   @my_obj       : camera object
    675  *   @parms        : ptr to a param struct to be get from server
    676  *
    677  * RETURN     : int32_t type of status
    678  *              0  -- success
    679  *              -1 -- failure
    680  * NOTE       : Assume the parms struct buf is already mapped to server via
    681  *              domain socket. Parameters to be get from server are already
    682  *              filled in by upper layer caller. After this call, corresponding
    683  *              fields of requested parameters will be filled in by server with
    684  *              detailed information.
    685  *==========================================================================*/
    686 int32_t mm_camera_get_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_g_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
    693     }
    694     pthread_mutex_unlock(&my_obj->cam_lock);
    695     return rc;
    696 }
    697 
    698 /*===========================================================================
    699  * FUNCTION   : mm_camera_do_auto_focus
    700  *
    701  * DESCRIPTION: performing auto focus
    702  *
    703  * PARAMETERS :
    704  *   @camera_handle: camera handle
    705  *
    706  * RETURN     : int32_t type of status
    707  *              0  -- success
    708  *              -1 -- failure
    709  * NOTE       : if this call success, we will always assume there will
    710  *              be an auto_focus event following up.
    711  *==========================================================================*/
    712 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
    713 {
    714     int32_t rc = -1;
    715     int32_t value = 0;
    716     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
    717     pthread_mutex_unlock(&my_obj->cam_lock);
    718     return rc;
    719 }
    720 
    721 /*===========================================================================
    722  * FUNCTION   : mm_camera_cancel_auto_focus
    723  *
    724  * DESCRIPTION: cancel auto focus
    725  *
    726  * PARAMETERS :
    727  *   @camera_handle: camera handle
    728  *
    729  * RETURN     : int32_t type of status
    730  *              0  -- success
    731  *              -1 -- failure
    732  *==========================================================================*/
    733 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
    734 {
    735     int32_t rc = -1;
    736     int32_t value = 0;
    737     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
    738     pthread_mutex_unlock(&my_obj->cam_lock);
    739     return rc;
    740 }
    741 
    742 /*===========================================================================
    743  * FUNCTION   : mm_camera_prepare_snapshot
    744  *
    745  * DESCRIPTION: prepare hardware for snapshot
    746  *
    747  * PARAMETERS :
    748  *   @my_obj       : camera object
    749  *   @do_af_flag   : flag indicating if AF is needed
    750  *
    751  * RETURN     : int32_t type of status
    752  *              0  -- success
    753  *              -1 -- failure
    754  *==========================================================================*/
    755 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
    756                                    int32_t do_af_flag)
    757 {
    758     int32_t rc = -1;
    759     int32_t value = do_af_flag;
    760     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
    761     pthread_mutex_unlock(&my_obj->cam_lock);
    762     return rc;
    763 }
    764 
    765 /*===========================================================================
    766  * FUNCTION   : mm_camera_start_zsl_snapshot
    767  *
    768  * DESCRIPTION: start zsl snapshot
    769  *
    770  * PARAMETERS :
    771  *   @my_obj       : camera object
    772  *
    773  * RETURN     : int32_t type of status
    774  *              0  -- success
    775  *              -1 -- failure
    776  *==========================================================================*/
    777 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
    778 {
    779     int32_t rc = -1;
    780     int32_t value = 0;
    781 
    782     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
    783              CAM_PRIV_START_ZSL_SNAPSHOT, &value);
    784     return rc;
    785 }
    786 
    787 /*===========================================================================
    788  * FUNCTION   : mm_camera_stop_zsl_snapshot
    789  *
    790  * DESCRIPTION: stop zsl capture
    791  *
    792  * PARAMETERS :
    793  *   @my_obj       : camera object
    794  *
    795  * RETURN     : int32_t type of status
    796  *              0  -- success
    797  *              -1 -- failure
    798  *==========================================================================*/
    799 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
    800 {
    801     int32_t rc = -1;
    802     int32_t value;
    803     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
    804              CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
    805     return rc;
    806 }
    807 
    808 /*===========================================================================
    809  * FUNCTION   : mm_camera_add_channel
    810  *
    811  * DESCRIPTION: add a channel
    812  *
    813  * PARAMETERS :
    814  *   @my_obj       : camera object
    815  *   @attr         : bundle attribute of the channel if needed
    816  *   @channel_cb   : callback function for bundle data notify
    817  *   @userdata     : user data ptr
    818  *
    819  * RETURN     : uint32_t type of channel handle
    820  *              0  -- invalid channel handle, meaning the op failed
    821  *              >0 -- successfully added a channel with a valid handle
    822  * NOTE       : if no bundle data notify is needed, meaning each stream in the
    823  *              channel will have its own stream data notify callback, then
    824  *              attr, channel_cb, and userdata can be NULL. In this case,
    825  *              no matching logic will be performed in channel for the bundling.
    826  *==========================================================================*/
    827 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
    828                                mm_camera_channel_attr_t *attr,
    829                                mm_camera_buf_notify_t channel_cb,
    830                                void *userdata)
    831 {
    832     mm_channel_t *ch_obj = NULL;
    833     uint8_t ch_idx = 0;
    834     uint32_t ch_hdl = 0;
    835 
    836     for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
    837         if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
    838             ch_obj = &my_obj->ch[ch_idx];
    839             break;
    840         }
    841     }
    842 
    843     if (NULL != ch_obj) {
    844         /* initialize channel obj */
    845         memset(ch_obj, 0, sizeof(mm_channel_t));
    846         ch_hdl = mm_camera_util_generate_handler(ch_idx);
    847         ch_obj->my_hdl = ch_hdl;
    848         ch_obj->state = MM_CHANNEL_STATE_STOPPED;
    849         ch_obj->cam_obj = my_obj;
    850         pthread_mutex_init(&ch_obj->ch_lock, NULL);
    851         mm_channel_init(ch_obj, attr, channel_cb, userdata);
    852     }
    853 
    854     pthread_mutex_unlock(&my_obj->cam_lock);
    855 
    856     return ch_hdl;
    857 }
    858 
    859 /*===========================================================================
    860  * FUNCTION   : mm_camera_del_channel
    861  *
    862  * DESCRIPTION: delete a channel by its handle
    863  *
    864  * PARAMETERS :
    865  *   @my_obj       : camera object
    866  *   @ch_id        : channel handle
    867  *
    868  * RETURN     : int32_t type of status
    869  *              0  -- success
    870  *              -1 -- failure
    871  * NOTE       : all streams in the channel should be stopped already before
    872  *              this channel can be deleted.
    873  *==========================================================================*/
    874 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
    875                               uint32_t ch_id)
    876 {
    877     int32_t rc = -1;
    878     mm_channel_t * ch_obj =
    879         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    880 
    881     if (NULL != ch_obj) {
    882         pthread_mutex_lock(&ch_obj->ch_lock);
    883         pthread_mutex_unlock(&my_obj->cam_lock);
    884 
    885         rc = mm_channel_fsm_fn(ch_obj,
    886                                MM_CHANNEL_EVT_DELETE,
    887                                NULL,
    888                                NULL);
    889 
    890         pthread_mutex_destroy(&ch_obj->ch_lock);
    891         memset(ch_obj, 0, sizeof(mm_channel_t));
    892     } else {
    893         pthread_mutex_unlock(&my_obj->cam_lock);
    894     }
    895     return rc;
    896 }
    897 
    898 /*===========================================================================
    899  * FUNCTION   : mm_camera_get_bundle_info
    900  *
    901  * DESCRIPTION: query bundle info of the channel
    902  *
    903  * PARAMETERS :
    904  *   @my_obj       : camera object
    905  *   @ch_id        : channel handle
    906  *   @bundle_info  : bundle info to be filled in
    907  *
    908  * RETURN     : int32_t type of status
    909  *              0  -- success
    910  *              -1 -- failure
    911  * NOTE       : all streams in the channel should be stopped already before
    912  *              this channel can be deleted.
    913  *==========================================================================*/
    914 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
    915                                   uint32_t ch_id,
    916                                   cam_bundle_config_t *bundle_info)
    917 {
    918     int32_t rc = -1;
    919     mm_channel_t * ch_obj =
    920         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    921 
    922     if (NULL != ch_obj) {
    923         pthread_mutex_lock(&ch_obj->ch_lock);
    924         pthread_mutex_unlock(&my_obj->cam_lock);
    925 
    926         rc = mm_channel_fsm_fn(ch_obj,
    927                                MM_CHANNEL_EVT_GET_BUNDLE_INFO,
    928                                (void *)bundle_info,
    929                                NULL);
    930     } else {
    931         pthread_mutex_unlock(&my_obj->cam_lock);
    932     }
    933     return rc;
    934 }
    935 
    936 /*===========================================================================
    937  * FUNCTION   : mm_camera_link_stream
    938  *
    939  * DESCRIPTION: link a stream into a channel
    940  *
    941  * PARAMETERS :
    942  *   @my_obj       : camera object
    943  *   @ch_id        : channel handle
    944  *   @stream_id    : stream that will be linked
    945  *   @linked_ch_id : channel in which the stream will be linked
    946  *
    947  * RETURN     : uint32_t type of stream handle
    948  *              0  -- invalid stream handle, meaning the op failed
    949  *              >0 -- successfully linked a stream with a valid handle
    950  *==========================================================================*/
    951 uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj,
    952         uint32_t ch_id,
    953         uint32_t stream_id,
    954         uint32_t linked_ch_id)
    955 {
    956     uint32_t s_hdl = 0;
    957     mm_channel_t * ch_obj =
    958             mm_camera_util_get_channel_by_handler(my_obj, linked_ch_id);
    959     mm_channel_t * owner_obj =
    960             mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    961 
    962     if ((NULL != ch_obj) && (NULL != owner_obj)) {
    963         pthread_mutex_lock(&ch_obj->ch_lock);
    964         pthread_mutex_unlock(&my_obj->cam_lock);
    965 
    966         mm_camera_stream_link_t stream_link;
    967         memset(&stream_link, 0, sizeof(mm_camera_stream_link_t));
    968         stream_link.ch = owner_obj;
    969         stream_link.stream_id = stream_id;
    970         mm_channel_fsm_fn(ch_obj,
    971                           MM_CHANNEL_EVT_LINK_STREAM,
    972                           (void*)&stream_link,
    973                           (void*)&s_hdl);
    974     } else {
    975         pthread_mutex_unlock(&my_obj->cam_lock);
    976     }
    977 
    978     return s_hdl;
    979 }
    980 
    981 /*===========================================================================
    982  * FUNCTION   : mm_camera_add_stream
    983  *
    984  * DESCRIPTION: add a stream into a channel
    985  *
    986  * PARAMETERS :
    987  *   @my_obj       : camera object
    988  *   @ch_id        : channel handle
    989  *
    990  * RETURN     : uint32_t type of stream handle
    991  *              0  -- invalid stream handle, meaning the op failed
    992  *              >0 -- successfully added a stream with a valid handle
    993  *==========================================================================*/
    994 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
    995                               uint32_t ch_id)
    996 {
    997     uint32_t s_hdl = 0;
    998     mm_channel_t * ch_obj =
    999         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1000 
   1001     if (NULL != ch_obj) {
   1002         pthread_mutex_lock(&ch_obj->ch_lock);
   1003         pthread_mutex_unlock(&my_obj->cam_lock);
   1004 
   1005         mm_channel_fsm_fn(ch_obj,
   1006                           MM_CHANNEL_EVT_ADD_STREAM,
   1007                           NULL,
   1008                           (void *)&s_hdl);
   1009     } else {
   1010         pthread_mutex_unlock(&my_obj->cam_lock);
   1011     }
   1012 
   1013     return s_hdl;
   1014 }
   1015 
   1016 /*===========================================================================
   1017  * FUNCTION   : mm_camera_del_stream
   1018  *
   1019  * DESCRIPTION: delete a stream by its handle
   1020  *
   1021  * PARAMETERS :
   1022  *   @my_obj       : camera object
   1023  *   @ch_id        : channel handle
   1024  *   @stream_id    : stream handle
   1025  *
   1026  * RETURN     : int32_t type of status
   1027  *              0  -- success
   1028  *              -1 -- failure
   1029  * NOTE       : stream should be stopped already before it can be deleted.
   1030  *==========================================================================*/
   1031 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
   1032                              uint32_t ch_id,
   1033                              uint32_t stream_id)
   1034 {
   1035     int32_t rc = -1;
   1036     mm_channel_t * ch_obj =
   1037         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1038 
   1039     if (NULL != ch_obj) {
   1040         pthread_mutex_lock(&ch_obj->ch_lock);
   1041         pthread_mutex_unlock(&my_obj->cam_lock);
   1042 
   1043         rc = mm_channel_fsm_fn(ch_obj,
   1044                                MM_CHANNEL_EVT_DEL_STREAM,
   1045                                (void *)&stream_id,
   1046                                NULL);
   1047     } else {
   1048         pthread_mutex_unlock(&my_obj->cam_lock);
   1049     }
   1050 
   1051     return rc;
   1052 }
   1053 
   1054 /*===========================================================================
   1055  * FUNCTION   : mm_camera_start_zsl_snapshot_ch
   1056  *
   1057  * DESCRIPTION: starts zsl snapshot for specific channel
   1058  *
   1059  * PARAMETERS :
   1060  *   @my_obj       : camera object
   1061  *   @ch_id        : channel handle
   1062  *
   1063  * RETURN     : int32_t type of status
   1064  *              0  -- success
   1065  *              -1 -- failure
   1066  *==========================================================================*/
   1067 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
   1068         uint32_t ch_id)
   1069 {
   1070     int32_t rc = -1;
   1071     mm_channel_t * ch_obj =
   1072         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1073 
   1074     if (NULL != ch_obj) {
   1075         pthread_mutex_lock(&ch_obj->ch_lock);
   1076         pthread_mutex_unlock(&my_obj->cam_lock);
   1077 
   1078         rc = mm_channel_fsm_fn(ch_obj,
   1079                                MM_CHANNEL_EVT_START_ZSL_SNAPSHOT,
   1080                                NULL,
   1081                                NULL);
   1082     } else {
   1083         pthread_mutex_unlock(&my_obj->cam_lock);
   1084     }
   1085 
   1086     return rc;
   1087 }
   1088 
   1089 /*===========================================================================
   1090  * FUNCTION   : mm_camera_stop_zsl_snapshot_ch
   1091  *
   1092  * DESCRIPTION: stops zsl snapshot for specific channel
   1093  *
   1094  * PARAMETERS :
   1095  *   @my_obj       : camera object
   1096  *   @ch_id        : channel handle
   1097  *
   1098  * RETURN     : int32_t type of status
   1099  *              0  -- success
   1100  *              -1 -- failure
   1101  *==========================================================================*/
   1102 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
   1103         uint32_t ch_id)
   1104 {
   1105     int32_t rc = -1;
   1106     mm_channel_t * ch_obj =
   1107         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1108 
   1109     if (NULL != ch_obj) {
   1110         pthread_mutex_lock(&ch_obj->ch_lock);
   1111         pthread_mutex_unlock(&my_obj->cam_lock);
   1112 
   1113         rc = mm_channel_fsm_fn(ch_obj,
   1114                                MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT,
   1115                                NULL,
   1116                                NULL);
   1117     } else {
   1118         pthread_mutex_unlock(&my_obj->cam_lock);
   1119     }
   1120 
   1121     return rc;
   1122 }
   1123 
   1124 /*===========================================================================
   1125  * FUNCTION   : mm_camera_config_stream
   1126  *
   1127  * DESCRIPTION: configure a stream
   1128  *
   1129  * PARAMETERS :
   1130  *   @my_obj       : camera object
   1131  *   @ch_id        : channel handle
   1132  *   @stream_id    : stream handle
   1133  *   @config       : stream configuration
   1134  *
   1135  * RETURN     : int32_t type of status
   1136  *              0  -- success
   1137  *              -1 -- failure
   1138  *==========================================================================*/
   1139 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
   1140                                 uint32_t ch_id,
   1141                                 uint32_t stream_id,
   1142                                 mm_camera_stream_config_t *config)
   1143 {
   1144     int32_t rc = -1;
   1145     mm_channel_t * ch_obj =
   1146         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1147     mm_evt_paylod_config_stream_t payload;
   1148 
   1149     if (NULL != ch_obj) {
   1150         pthread_mutex_lock(&ch_obj->ch_lock);
   1151         pthread_mutex_unlock(&my_obj->cam_lock);
   1152 
   1153         memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
   1154         payload.stream_id = stream_id;
   1155         payload.config = config;
   1156         rc = mm_channel_fsm_fn(ch_obj,
   1157                                MM_CHANNEL_EVT_CONFIG_STREAM,
   1158                                (void *)&payload,
   1159                                NULL);
   1160     } else {
   1161         pthread_mutex_unlock(&my_obj->cam_lock);
   1162     }
   1163 
   1164     return rc;
   1165 }
   1166 
   1167 /*===========================================================================
   1168  * FUNCTION   : mm_camera_start_channel
   1169  *
   1170  * DESCRIPTION: start a channel, which will start all streams in the channel
   1171  *
   1172  * PARAMETERS :
   1173  *   @my_obj       : camera object
   1174  *   @ch_id        : channel handle
   1175  *
   1176  * RETURN     : int32_t type of status
   1177  *              0  -- success
   1178  *              -1 -- failure
   1179  *==========================================================================*/
   1180 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj,
   1181                                 uint32_t ch_id)
   1182 {
   1183     int32_t rc = -1;
   1184     mm_channel_t * ch_obj =
   1185         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1186 
   1187     if (NULL != ch_obj) {
   1188         pthread_mutex_lock(&ch_obj->ch_lock);
   1189         pthread_mutex_unlock(&my_obj->cam_lock);
   1190 
   1191         rc = mm_channel_fsm_fn(ch_obj,
   1192                                MM_CHANNEL_EVT_START,
   1193                                NULL,
   1194                                NULL);
   1195     } else {
   1196         pthread_mutex_unlock(&my_obj->cam_lock);
   1197     }
   1198 
   1199     return rc;
   1200 }
   1201 
   1202 /*===========================================================================
   1203  * FUNCTION   : mm_camera_stop_channel
   1204  *
   1205  * DESCRIPTION: stop a channel, which will stop all streams in the channel
   1206  *
   1207  * PARAMETERS :
   1208  *   @my_obj       : camera object
   1209  *   @ch_id        : channel handle
   1210  *
   1211  * RETURN     : int32_t type of status
   1212  *              0  -- success
   1213  *              -1 -- failure
   1214  *==========================================================================*/
   1215 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
   1216                                uint32_t ch_id)
   1217 {
   1218     int32_t rc = 0;
   1219     mm_channel_t * ch_obj =
   1220         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1221 
   1222     if (NULL != ch_obj) {
   1223         pthread_mutex_lock(&ch_obj->ch_lock);
   1224         pthread_mutex_unlock(&my_obj->cam_lock);
   1225 
   1226         rc = mm_channel_fsm_fn(ch_obj,
   1227                                MM_CHANNEL_EVT_STOP,
   1228                                NULL,
   1229                                NULL);
   1230     } else {
   1231         pthread_mutex_unlock(&my_obj->cam_lock);
   1232     }
   1233     return rc;
   1234 }
   1235 
   1236 /*===========================================================================
   1237  * FUNCTION   : mm_camera_request_super_buf
   1238  *
   1239  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
   1240  *              frames from superbuf queue
   1241  *
   1242  * PARAMETERS :
   1243  *   @my_obj       : camera object
   1244  *   @ch_id        : channel handle
   1245  *   @num_buf_requested : number of matched frames needed
   1246  *
   1247  * RETURN     : int32_t type of status
   1248  *              0  -- success
   1249  *              -1 -- failure
   1250  *==========================================================================*/
   1251 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
   1252                                     uint32_t ch_id,
   1253                                     uint32_t num_buf_requested,
   1254                                     uint32_t num_retro_buf_requested)
   1255 {
   1256     int32_t rc = -1;
   1257     mm_channel_t * ch_obj =
   1258         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1259 
   1260     if (NULL != ch_obj) {
   1261         pthread_mutex_lock(&ch_obj->ch_lock);
   1262         pthread_mutex_unlock(&my_obj->cam_lock);
   1263 
   1264         rc = mm_channel_fsm_fn(ch_obj,
   1265                                MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
   1266                                (void *)&num_buf_requested,
   1267                                (void *)&num_retro_buf_requested);
   1268     } else {
   1269         pthread_mutex_unlock(&my_obj->cam_lock);
   1270     }
   1271 
   1272     return rc;
   1273 }
   1274 
   1275 /*===========================================================================
   1276  * FUNCTION   : mm_camera_cancel_super_buf_request
   1277  *
   1278  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
   1279  *              of matched frames from superbuf queue
   1280  *
   1281  * PARAMETERS :
   1282  *   @my_obj       : camera object
   1283  *   @ch_id        : channel handle
   1284  *
   1285  * RETURN     : int32_t type of status
   1286  *              0  -- success
   1287  *              -1 -- failure
   1288  *==========================================================================*/
   1289 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
   1290 {
   1291     int32_t rc = -1;
   1292     mm_channel_t * ch_obj =
   1293         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1294 
   1295     if (NULL != ch_obj) {
   1296         pthread_mutex_lock(&ch_obj->ch_lock);
   1297         pthread_mutex_unlock(&my_obj->cam_lock);
   1298 
   1299         rc = mm_channel_fsm_fn(ch_obj,
   1300                                MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
   1301                                NULL,
   1302                                NULL);
   1303     } else {
   1304         pthread_mutex_unlock(&my_obj->cam_lock);
   1305     }
   1306 
   1307     return rc;
   1308 }
   1309 
   1310 /*===========================================================================
   1311  * FUNCTION   : mm_camera_flush_super_buf_queue
   1312  *
   1313  * DESCRIPTION: flush out all frames in the superbuf queue
   1314  *
   1315  * PARAMETERS :
   1316  *   @my_obj       : camera object
   1317  *   @ch_id        : channel handle
   1318  *
   1319  * RETURN     : int32_t type of status
   1320  *              0  -- success
   1321  *              -1 -- failure
   1322  *==========================================================================*/
   1323 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
   1324                                                              uint32_t frame_idx)
   1325 {
   1326     int32_t rc = -1;
   1327     mm_channel_t * ch_obj =
   1328         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1329 
   1330     if (NULL != ch_obj) {
   1331         pthread_mutex_lock(&ch_obj->ch_lock);
   1332         pthread_mutex_unlock(&my_obj->cam_lock);
   1333 
   1334         rc = mm_channel_fsm_fn(ch_obj,
   1335                                MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
   1336                                (void *)&frame_idx,
   1337                                NULL);
   1338     } else {
   1339         pthread_mutex_unlock(&my_obj->cam_lock);
   1340     }
   1341 
   1342     return rc;
   1343 }
   1344 
   1345 /*===========================================================================
   1346  * FUNCTION   : mm_camera_config_channel_notify
   1347  *
   1348  * DESCRIPTION: configures the channel notification mode
   1349  *
   1350  * PARAMETERS :
   1351  *   @my_obj       : camera object
   1352  *   @ch_id        : channel handle
   1353  *   @notify_mode  : notification mode
   1354  *
   1355  * RETURN     : int32_t type of status
   1356  *              0  -- success
   1357  *              -1 -- failure
   1358  *==========================================================================*/
   1359 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
   1360                                         uint32_t ch_id,
   1361                                         mm_camera_super_buf_notify_mode_t notify_mode)
   1362 {
   1363     int32_t rc = -1;
   1364     mm_channel_t * ch_obj =
   1365         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1366 
   1367     if (NULL != ch_obj) {
   1368         pthread_mutex_lock(&ch_obj->ch_lock);
   1369         pthread_mutex_unlock(&my_obj->cam_lock);
   1370 
   1371         rc = mm_channel_fsm_fn(ch_obj,
   1372                                MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
   1373                                (void *)&notify_mode,
   1374                                NULL);
   1375     } else {
   1376         pthread_mutex_unlock(&my_obj->cam_lock);
   1377     }
   1378 
   1379     return rc;
   1380 }
   1381 
   1382 /*===========================================================================
   1383  * FUNCTION   : mm_camera_set_stream_parms
   1384  *
   1385  * DESCRIPTION: set parameters per stream
   1386  *
   1387  * PARAMETERS :
   1388  *   @my_obj       : camera object
   1389  *   @ch_id        : channel handle
   1390  *   @s_id         : stream handle
   1391  *   @parms        : ptr to a param struct to be set to server
   1392  *
   1393  * RETURN     : int32_t type of status
   1394  *              0  -- success
   1395  *              -1 -- failure
   1396  * NOTE       : Assume the parms struct buf is already mapped to server via
   1397  *              domain socket. Corresponding fields of parameters to be set
   1398  *              are already filled in by upper layer caller.
   1399  *==========================================================================*/
   1400 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
   1401                                    uint32_t ch_id,
   1402                                    uint32_t s_id,
   1403                                    cam_stream_parm_buffer_t *parms)
   1404 {
   1405     int32_t rc = -1;
   1406     mm_evt_paylod_set_get_stream_parms_t payload;
   1407     mm_channel_t * ch_obj =
   1408         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1409 
   1410     if (NULL != ch_obj) {
   1411         pthread_mutex_lock(&ch_obj->ch_lock);
   1412         pthread_mutex_unlock(&my_obj->cam_lock);
   1413 
   1414         memset(&payload, 0, sizeof(payload));
   1415         payload.stream_id = s_id;
   1416         payload.parms = parms;
   1417 
   1418         rc = mm_channel_fsm_fn(ch_obj,
   1419                                MM_CHANNEL_EVT_SET_STREAM_PARM,
   1420                                (void *)&payload,
   1421                                NULL);
   1422     } else {
   1423         pthread_mutex_unlock(&my_obj->cam_lock);
   1424     }
   1425 
   1426     return rc;
   1427 }
   1428 
   1429 /*===========================================================================
   1430  * FUNCTION   : mm_camera_get_stream_parms
   1431  *
   1432  * DESCRIPTION: get parameters per stream
   1433  *
   1434  * PARAMETERS :
   1435  *   @my_obj       : camera object
   1436  *   @ch_id        : channel handle
   1437  *   @s_id         : stream handle
   1438  *   @parms        : ptr to a param struct to be get from server
   1439  *
   1440  * RETURN     : int32_t type of status
   1441  *              0  -- success
   1442  *              -1 -- failure
   1443  * NOTE       : Assume the parms struct buf is already mapped to server via
   1444  *              domain socket. Parameters to be get from server are already
   1445  *              filled in by upper layer caller. After this call, corresponding
   1446  *              fields of requested parameters will be filled in by server with
   1447  *              detailed information.
   1448  *==========================================================================*/
   1449 int32_t mm_camera_get_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_GET_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_do_stream_action
   1480  *
   1481  * DESCRIPTION: request server to perform stream based action. Maybe removed later
   1482  *              if the functionality is included in mm_camera_set_parms
   1483  *
   1484  * PARAMETERS :
   1485  *   @my_obj       : camera object
   1486  *   @ch_id        : channel handle
   1487  *   @s_id         : stream handle
   1488  *   @actions      : ptr to an action struct buf to be performed by server
   1489  *
   1490  * RETURN     : int32_t type of status
   1491  *              0  -- success
   1492  *              -1 -- failure
   1493  * NOTE       : Assume the action struct buf is already mapped to server via
   1494  *              domain socket. Actions to be performed by server are already
   1495  *              filled in by upper layer caller.
   1496  *==========================================================================*/
   1497 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
   1498                                    uint32_t ch_id,
   1499                                    uint32_t stream_id,
   1500                                    void *actions)
   1501 {
   1502     int32_t rc = -1;
   1503     mm_evt_paylod_do_stream_action_t payload;
   1504     mm_channel_t * ch_obj =
   1505         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1506 
   1507     if (NULL != ch_obj) {
   1508         pthread_mutex_lock(&ch_obj->ch_lock);
   1509         pthread_mutex_unlock(&my_obj->cam_lock);
   1510 
   1511         memset(&payload, 0, sizeof(payload));
   1512         payload.stream_id = stream_id;
   1513         payload.actions = actions;
   1514 
   1515         rc = mm_channel_fsm_fn(ch_obj,
   1516                                MM_CHANNEL_EVT_DO_STREAM_ACTION,
   1517                                (void*)&payload,
   1518                                NULL);
   1519     } else {
   1520         pthread_mutex_unlock(&my_obj->cam_lock);
   1521     }
   1522 
   1523     return rc;
   1524 }
   1525 
   1526 /*===========================================================================
   1527  * FUNCTION   : mm_camera_map_stream_buf
   1528  *
   1529  * DESCRIPTION: mapping stream buffer via domain socket to server
   1530  *
   1531  * PARAMETERS :
   1532  *   @my_obj       : camera object
   1533  *   @ch_id        : channel handle
   1534  *   @s_id         : stream handle
   1535  *   @buf_type     : type of buffer to be mapped. could be following values:
   1536  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1537  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1538  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1539  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1540  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1541  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1542  *   @plane_idx    : plane index. If all planes share the same fd,
   1543  *                   plane_idx = -1; otherwise, plean_idx is the
   1544  *                   index to plane (0..num_of_planes)
   1545  *   @fd           : file descriptor of the buffer
   1546  *   @size         : size of the buffer
   1547  *
   1548  * RETURN     : int32_t type of status
   1549  *              0  -- success
   1550  *              -1 -- failure
   1551  *==========================================================================*/
   1552 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
   1553                                  uint32_t ch_id,
   1554                                  uint32_t stream_id,
   1555                                  uint8_t buf_type,
   1556                                  uint32_t buf_idx,
   1557                                  int32_t plane_idx,
   1558                                  int fd,
   1559                                  size_t size)
   1560 {
   1561     int32_t rc = -1;
   1562     mm_evt_paylod_map_stream_buf_t payload;
   1563     mm_channel_t * ch_obj =
   1564         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1565 
   1566     if (NULL != ch_obj) {
   1567         pthread_mutex_lock(&ch_obj->ch_lock);
   1568         pthread_mutex_unlock(&my_obj->cam_lock);
   1569 
   1570         memset(&payload, 0, sizeof(payload));
   1571         payload.stream_id = stream_id;
   1572         payload.buf_type = buf_type;
   1573         payload.buf_idx = buf_idx;
   1574         payload.plane_idx = plane_idx;
   1575         payload.fd = fd;
   1576         payload.size = size;
   1577         rc = mm_channel_fsm_fn(ch_obj,
   1578                                MM_CHANNEL_EVT_MAP_STREAM_BUF,
   1579                                (void*)&payload,
   1580                                NULL);
   1581     } else {
   1582         pthread_mutex_unlock(&my_obj->cam_lock);
   1583     }
   1584 
   1585     return rc;
   1586 }
   1587 
   1588 /*===========================================================================
   1589  * FUNCTION   : mm_camera_unmap_stream_buf
   1590  *
   1591  * DESCRIPTION: unmapping stream buffer via domain socket to server
   1592  *
   1593  * PARAMETERS :
   1594  *   @my_obj       : camera object
   1595  *   @ch_id        : channel handle
   1596  *   @s_id         : stream handle
   1597  *   @buf_type     : type of buffer to be mapped. could be following values:
   1598  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
   1599  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
   1600  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1601  *   @buf_idx      : index of buffer within the stream buffers, only valid if
   1602  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
   1603  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
   1604  *   @plane_idx    : plane index. If all planes share the same fd,
   1605  *                   plane_idx = -1; otherwise, plean_idx is the
   1606  *                   index to plane (0..num_of_planes)
   1607  *
   1608  * RETURN     : int32_t type of status
   1609  *              0  -- success
   1610  *              -1 -- failure
   1611  *==========================================================================*/
   1612 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
   1613                                    uint32_t ch_id,
   1614                                    uint32_t stream_id,
   1615                                    uint8_t buf_type,
   1616                                    uint32_t buf_idx,
   1617                                    int32_t plane_idx)
   1618 {
   1619     int32_t rc = -1;
   1620     mm_evt_paylod_unmap_stream_buf_t payload;
   1621     mm_channel_t * ch_obj =
   1622         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1623 
   1624     if (NULL != ch_obj) {
   1625         pthread_mutex_lock(&ch_obj->ch_lock);
   1626         pthread_mutex_unlock(&my_obj->cam_lock);
   1627 
   1628         memset(&payload, 0, sizeof(payload));
   1629         payload.stream_id = stream_id;
   1630         payload.buf_type = buf_type;
   1631         payload.buf_idx = buf_idx;
   1632         payload.plane_idx = plane_idx;
   1633         rc = mm_channel_fsm_fn(ch_obj,
   1634                                MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
   1635                                (void*)&payload,
   1636                                NULL);
   1637     } else {
   1638         pthread_mutex_unlock(&my_obj->cam_lock);
   1639     }
   1640 
   1641     return rc;
   1642 }
   1643 
   1644 /*===========================================================================
   1645  * FUNCTION   : mm_camera_evt_sub
   1646  *
   1647  * DESCRIPTION: subscribe/unsubscribe event notify from kernel
   1648  *
   1649  * PARAMETERS :
   1650  *   @my_obj       : camera object
   1651  *   @reg_flag     : 1 -- subscribe ; 0 -- unsubscribe
   1652  *
   1653  * RETURN     : int32_t type of status
   1654  *              0  -- success
   1655  *              -1 -- failure
   1656  *==========================================================================*/
   1657 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
   1658                           uint8_t reg_flag)
   1659 {
   1660     int32_t rc = 0;
   1661     struct v4l2_event_subscription sub;
   1662 
   1663     memset(&sub, 0, sizeof(sub));
   1664     sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
   1665     sub.id = MSM_CAMERA_MSM_NOTIFY;
   1666     if(FALSE == reg_flag) {
   1667         /* unsubscribe */
   1668         rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
   1669         if (rc < 0) {
   1670             CDBG_ERROR("%s: unsubscribe event rc = %d", __func__, rc);
   1671             return rc;
   1672         }
   1673         /* remove evt fd from the polling thraed when unreg the last event */
   1674         rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
   1675                                                my_obj->my_hdl,
   1676                                                mm_camera_sync_call);
   1677     } else {
   1678         rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
   1679         if (rc < 0) {
   1680             CDBG_ERROR("%s: subscribe event rc = %d", __func__, rc);
   1681             return rc;
   1682         }
   1683         /* add evt fd to polling thread when subscribe the first event */
   1684         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
   1685                                                my_obj->my_hdl,
   1686                                                my_obj->ctrl_fd,
   1687                                                mm_camera_event_notify,
   1688                                                (void*)my_obj,
   1689                                                mm_camera_sync_call);
   1690     }
   1691     return rc;
   1692 }
   1693 
   1694 /*===========================================================================
   1695  * FUNCTION   : mm_camera_util_wait_for_event
   1696  *
   1697  * DESCRIPTION: utility function to wait for certain events
   1698  *
   1699  * PARAMETERS :
   1700  *   @my_obj       : camera object
   1701  *   @evt_mask     : mask for events to be waited. Any of event in the mask would
   1702  *                   trigger the wait to end
   1703  *   @status       : status of the event
   1704  *
   1705  * RETURN     : none
   1706  *==========================================================================*/
   1707 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
   1708                                    uint32_t evt_mask,
   1709                                    uint32_t *status)
   1710 {
   1711     int rc = 0;
   1712     struct timespec ts;
   1713 
   1714     pthread_mutex_lock(&my_obj->evt_lock);
   1715     while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
   1716         clock_gettime(CLOCK_REALTIME, &ts);
   1717         ts.tv_sec += WAIT_TIMEOUT;
   1718         rc = pthread_cond_timedwait(&my_obj->evt_cond, &my_obj->evt_lock, &ts);
   1719         if (rc == ETIMEDOUT) {
   1720             ALOGE("%s pthread_cond_timedwait success\n", __func__);
   1721             break;
   1722         }
   1723     }
   1724     *status = my_obj->evt_rcvd.status;
   1725     /* reset local storage for recieved event for next event */
   1726     memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
   1727     pthread_mutex_unlock(&my_obj->evt_lock);
   1728 }
   1729 
   1730 /*===========================================================================
   1731  * FUNCTION   : mm_camera_util_sendmsg
   1732  *
   1733  * DESCRIPTION: utility function to send msg via domain socket
   1734  *
   1735  * PARAMETERS :
   1736  *   @my_obj       : camera object
   1737  *   @msg          : message to be sent
   1738  *   @buf_size     : size of the message to be sent
   1739  *   @sendfd       : >0 if any file descriptor need to be passed across process
   1740  *
   1741  * RETURN     : int32_t type of status
   1742  *              0  -- success
   1743  *              -1 -- failure
   1744  *==========================================================================*/
   1745 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
   1746                                void *msg,
   1747                                size_t buf_size,
   1748                                int sendfd)
   1749 {
   1750     int32_t rc = -1;
   1751     uint32_t status;
   1752 
   1753     /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
   1754     pthread_mutex_lock(&my_obj->msg_lock);
   1755     if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
   1756         /* wait for event that mapping/unmapping is done */
   1757         mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
   1758         if (MSM_CAMERA_STATUS_SUCCESS == status) {
   1759             rc = 0;
   1760         }
   1761     }
   1762     pthread_mutex_unlock(&my_obj->msg_lock);
   1763     return rc;
   1764 }
   1765 
   1766 /*===========================================================================
   1767  * FUNCTION   : mm_camera_map_buf
   1768  *
   1769  * DESCRIPTION: mapping camera buffer via domain socket to server
   1770  *
   1771  * PARAMETERS :
   1772  *   @my_obj       : camera object
   1773  *   @buf_type     : type of buffer to be mapped. could be following values:
   1774  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1775  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1776  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1777  *   @fd           : file descriptor of the buffer
   1778  *   @size         : size of the buffer
   1779  *
   1780  * RETURN     : int32_t type of status
   1781  *              0  -- success
   1782  *              -1 -- failure
   1783  *==========================================================================*/
   1784 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
   1785                           uint8_t buf_type,
   1786                           int fd,
   1787                           size_t size)
   1788 {
   1789     int32_t rc = 0;
   1790     cam_sock_packet_t packet;
   1791     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1792     packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
   1793     packet.payload.buf_map.type = buf_type;
   1794     packet.payload.buf_map.fd = fd;
   1795     packet.payload.buf_map.size = size;
   1796     rc = mm_camera_util_sendmsg(my_obj,
   1797                                 &packet,
   1798                                 sizeof(cam_sock_packet_t),
   1799                                 fd);
   1800     pthread_mutex_unlock(&my_obj->cam_lock);
   1801     return rc;
   1802 }
   1803 
   1804 /*===========================================================================
   1805  * FUNCTION   : mm_camera_unmap_buf
   1806  *
   1807  * DESCRIPTION: unmapping camera buffer via domain socket to server
   1808  *
   1809  * PARAMETERS :
   1810  *   @my_obj       : camera object
   1811  *   @buf_type     : type of buffer to be mapped. could be following values:
   1812  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
   1813  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
   1814  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
   1815  *
   1816  * RETURN     : int32_t type of status
   1817  *              0  -- success
   1818  *              -1 -- failure
   1819  *==========================================================================*/
   1820 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
   1821                             uint8_t buf_type)
   1822 {
   1823     int32_t rc = 0;
   1824     cam_sock_packet_t packet;
   1825     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1826     packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
   1827     packet.payload.buf_unmap.type = buf_type;
   1828     rc = mm_camera_util_sendmsg(my_obj,
   1829                                 &packet,
   1830                                 sizeof(cam_sock_packet_t),
   1831                                 -1);
   1832     pthread_mutex_unlock(&my_obj->cam_lock);
   1833     return rc;
   1834 }
   1835 
   1836 /*===========================================================================
   1837  * FUNCTION   : mm_camera_util_s_ctrl
   1838  *
   1839  * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
   1840  *
   1841  * PARAMETERS :
   1842  *   @fd      : file descritpor for sending ioctl
   1843  *   @id      : control id
   1844  *   @value   : value of the ioctl to be sent
   1845  *
   1846  * RETURN     : int32_t type of status
   1847  *              0  -- success
   1848  *              -1 -- failure
   1849  *==========================================================================*/
   1850 int32_t mm_camera_util_s_ctrl(int32_t fd,  uint32_t id, int32_t *value)
   1851 {
   1852     int rc = 0;
   1853     struct v4l2_control control;
   1854 
   1855     memset(&control, 0, sizeof(control));
   1856     control.id = id;
   1857     if (value != NULL) {
   1858         control.value = *value;
   1859     }
   1860     rc = ioctl(fd, VIDIOC_S_CTRL, &control);
   1861 
   1862     CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = %p, rc = %d\n",
   1863          __func__, fd, id, value, rc);
   1864     if (value != NULL) {
   1865         *value = control.value;
   1866     }
   1867     return (rc >= 0)? 0 : -1;
   1868 }
   1869 
   1870 /*===========================================================================
   1871  * FUNCTION   : mm_camera_util_g_ctrl
   1872  *
   1873  * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
   1874  *
   1875  * PARAMETERS :
   1876  *   @fd      : file descritpor for sending ioctl
   1877  *   @id      : control id
   1878  *   @value   : value of the ioctl to be sent
   1879  *
   1880  * RETURN     : int32_t type of status
   1881  *              0  -- success
   1882  *              -1 -- failure
   1883  *==========================================================================*/
   1884 int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
   1885 {
   1886     int rc = 0;
   1887     struct v4l2_control control;
   1888 
   1889     memset(&control, 0, sizeof(control));
   1890     control.id = id;
   1891     if (value != NULL) {
   1892         control.value = *value;
   1893     }
   1894     rc = ioctl(fd, VIDIOC_G_CTRL, &control);
   1895     CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc);
   1896     if (value != NULL) {
   1897         *value = control.value;
   1898     }
   1899     return (rc >= 0)? 0 : -1;
   1900 }
   1901 
   1902 /*===========================================================================
   1903  * FUNCTION   : mm_camera_channel_advanced_capture
   1904  *
   1905  * DESCRIPTION: sets the channel advanced capture
   1906  *
   1907  * PARAMETERS :
   1908  *   @my_obj       : camera object
   1909  *   @ch_id        : channel handle
   1910   *   @type : advanced capture type.
   1911  *   @start_flag  : flag to indicate start/stop
   1912   *   @in_value  : input configaration
   1913  *
   1914  * RETURN     : int32_t type of status
   1915  *              0  -- success
   1916  *              -1 -- failure
   1917  *==========================================================================*/
   1918 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj,
   1919             uint32_t ch_id, mm_camera_advanced_capture_t type,
   1920             uint32_t trigger, void *in_value)
   1921 {
   1922     CDBG("%s: E type = %d",__func__, type);
   1923     int32_t rc = -1;
   1924     mm_channel_t * ch_obj =
   1925         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1926 
   1927     if (NULL != ch_obj) {
   1928         pthread_mutex_lock(&ch_obj->ch_lock);
   1929         pthread_mutex_unlock(&my_obj->cam_lock);
   1930         switch (type) {
   1931             case MM_CAMERA_AF_BRACKETING:
   1932                 rc = mm_channel_fsm_fn(ch_obj,
   1933                                        MM_CHANNEL_EVT_AF_BRACKETING,
   1934                                        (void *)&trigger,
   1935                                        NULL);
   1936                 break;
   1937             case MM_CAMERA_AE_BRACKETING:
   1938                 rc = mm_channel_fsm_fn(ch_obj,
   1939                                        MM_CHANNEL_EVT_AE_BRACKETING,
   1940                                        (void *)&trigger,
   1941                                        NULL);
   1942                 break;
   1943             case MM_CAMERA_FLASH_BRACKETING:
   1944                 rc = mm_channel_fsm_fn(ch_obj,
   1945                                        MM_CHANNEL_EVT_FLASH_BRACKETING,
   1946                                        (void *)&trigger,
   1947                                        NULL);
   1948                 break;
   1949             case MM_CAMERA_ZOOM_1X:
   1950                 rc = mm_channel_fsm_fn(ch_obj,
   1951                                        MM_CHANNEL_EVT_ZOOM_1X,
   1952                                        (void *)&trigger,
   1953                                        NULL);
   1954                 break;
   1955             case MM_CAMERA_FRAME_CAPTURE:
   1956                 rc = mm_channel_fsm_fn(ch_obj,
   1957                                        MM_CAMERA_EVT_CAPTURE_SETTING,
   1958                                        (void *)in_value,
   1959                                        NULL);
   1960                 break;
   1961             default:
   1962                 break;
   1963         }
   1964 
   1965     } else {
   1966         pthread_mutex_unlock(&my_obj->cam_lock);
   1967     }
   1968 
   1969     CDBG("%s: X",__func__);
   1970     return rc;
   1971 }
   1972