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