Home | History | Annotate | Download | only in src
      1 /*
      2 Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are
      6 met:
      7     * Redistributions of source code must retain the above copyright
      8       notice, this list of conditions and the following disclaimer.
      9     * Redistributions in binary form must reproduce the above
     10       copyright notice, this list of conditions and the following
     11       disclaimer in the documentation and/or other materials provided
     12       with the distribution.
     13     * Neither the name of The Linux Foundation nor the names of its
     14       contributors may be used to endorse or promote products derived
     15       from this software without specific prior written permission.
     16 
     17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     20 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     28 */
     29 
     30 #include <pthread.h>
     31 #include <errno.h>
     32 #include <sys/ioctl.h>
     33 #include <sys/types.h>
     34 #include <sys/stat.h>
     35 #include <fcntl.h>
     36 #include <poll.h>
     37 #include <semaphore.h>
     38 
     39 #include "mm_camera_dbg.h"
     40 #include "mm_camera_sock.h"
     41 #include "mm_camera_interface.h"
     42 #include "mm_camera.h"
     43 
     44 #define SET_PARM_BIT32(parm, parm_arr) \
     45     (parm_arr[parm/32] |= (1<<(parm%32)))
     46 
     47 #define GET_PARM_BIT32(parm, parm_arr) \
     48     ((parm_arr[parm/32]>>(parm%32))& 0x1)
     49 
     50 /* internal function declare */
     51 int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
     52                                        cam_ctrl_type type,
     53                                        uint32_t length,
     54                                        void *value);
     55 int32_t mm_camera_send_native_ctrl_timeout_cmd(mm_camera_obj_t * my_obj,
     56                                                cam_ctrl_type type,
     57                                                uint32_t length,
     58                                                void *value,
     59                                                int timeout);
     60 int mm_camera_evt_sub(mm_camera_obj_t * my_obj,
     61                       mm_camera_event_type_t evt_type,
     62                       int reg_count);
     63 int32_t mm_camera_set_general_parm(mm_camera_obj_t * my_obj,
     64                                    mm_camera_parm_type_t parm_type,
     65                                    void* p_value);
     66 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
     67                               mm_camera_event_t *event);
     68 extern int32_t mm_channel_init(mm_channel_t *my_obj);
     69 
     70 mm_channel_t * mm_camera_util_get_channel_by_handler(
     71                                     mm_camera_obj_t * cam_obj,
     72                                     uint32_t handler)
     73 {
     74     int i;
     75     mm_channel_t *ch_obj = NULL;
     76     uint8_t ch_idx = mm_camera_util_get_index_by_handler(handler);
     77 
     78     for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
     79         if (handler == cam_obj->ch[i].my_hdl) {
     80             ch_obj = &cam_obj->ch[i];
     81             break;
     82         }
     83     }
     84     return ch_obj;
     85 }
     86 
     87 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
     88                                          void* user_data)
     89 {
     90     int i;
     91     mm_camera_event_type_t evt_type = cmd_cb->u.evt.event_type;
     92     mm_camera_event_t *event = &cmd_cb->u.evt;
     93     mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data;
     94     if (NULL != my_obj) {
     95         if (evt_type < MM_CAMERA_EVT_TYPE_MAX) {
     96             pthread_mutex_lock(&my_obj->cb_lock);
     97             for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
     98                 if(my_obj->evt[evt_type].evt[i].evt_cb) {
     99                     my_obj->evt[evt_type].evt[i].evt_cb(
    100                         my_obj->my_hdl,
    101                         event,
    102                         my_obj->evt[evt_type].evt[i].user_data);
    103                 }
    104             }
    105             pthread_mutex_unlock(&my_obj->cb_lock);
    106         }
    107     }
    108 }
    109 
    110 static void mm_camera_handle_async_cmd(mm_camera_cmdcb_t *cmd_cb,
    111                                        void* user_data)
    112 {
    113     int i;
    114     mm_camera_async_cmd_t *async_cmd = &cmd_cb->u.async;
    115     mm_camera_obj_t * my_obj = NULL;
    116     mm_evt_payload_stop_stream_t payload;
    117 
    118     my_obj = (mm_camera_obj_t *)user_data;
    119     if (NULL != my_obj) {
    120         if (MM_CAMERA_ASYNC_CMD_TYPE_STOP == async_cmd->cmd_type) {
    121             memset(&payload, 0, sizeof(mm_evt_payload_stop_stream_t));
    122             payload.num_streams = async_cmd->u.stop_cmd.num_streams;
    123             payload.stream_ids = async_cmd->u.stop_cmd.stream_ids;
    124             mm_channel_fsm_fn(async_cmd->u.stop_cmd.ch_obj,
    125                                    MM_CHANNEL_EVT_TEARDOWN_STREAM,
    126                                    (void*)&payload,
    127                                    NULL);
    128         }
    129     }
    130 }
    131 
    132 static void mm_camera_event_notify(void* user_data)
    133 {
    134     struct v4l2_event ev;
    135     int rc;
    136     mm_camera_event_t *evt = NULL;
    137     mm_camera_cmdcb_t *node = NULL;
    138 
    139     mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
    140     if (NULL != my_obj) {
    141         /* read evt */
    142         memset(&ev, 0, sizeof(ev));
    143         rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
    144         evt = (mm_camera_event_t *)ev.u.data;
    145 
    146         if (rc >= 0) {
    147             if(ev.type == V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_ERROR_EVENT) {
    148                 evt->event_type = MM_CAMERA_EVT_TYPE_CTRL;
    149                 evt->e.ctrl.evt = MM_CAMERA_CTRL_EVT_ERROR;
    150                 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    151                 if (NULL != node) {
    152                     memset(node, 0, sizeof(mm_camera_cmdcb_t));
    153                     node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
    154                     memcpy(&node->u.evt, evt, sizeof(mm_camera_event_t));
    155                 }
    156             } else {
    157                 switch (evt->event_type) {
    158                 case MM_CAMERA_EVT_TYPE_CH:
    159                 case MM_CAMERA_EVT_TYPE_CTRL:
    160                 case MM_CAMERA_EVT_TYPE_STATS:
    161                 case MM_CAMERA_EVT_TYPE_INFO:
    162                     {
    163                         node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    164                         if (NULL != node) {
    165                             memset(node, 0, sizeof(mm_camera_cmdcb_t));
    166                             node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
    167                             memcpy(&node->u.evt, evt, sizeof(mm_camera_event_t));
    168                         }
    169                     }
    170                     break;
    171                 case MM_CAMERA_EVT_TYPE_PRIVATE_EVT:
    172                     {
    173                         CDBG("%s: MM_CAMERA_EVT_TYPE_PRIVATE_EVT", __func__);
    174                         struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
    175                         int32_t length =
    176                             sizeof(mm_camera_cmdcb_t) + evt->e.pri_evt.data_length;
    177                         node = (mm_camera_cmdcb_t *)malloc(length);
    178                         if (NULL != node) {
    179                             memset(node, 0, length);
    180                             node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
    181                             memcpy(&node->u.evt, evt, sizeof(mm_camera_event_t));
    182 
    183                             if (evt->e.pri_evt.data_length > 0) {
    184                                 CDBG("%s: data_length =%d (trans_id=%d), dequeue payload",
    185                                      __func__, evt->e.pri_evt.data_length,
    186                                      node->u.evt.e.pri_evt.trans_id);
    187                                 /* dequeue event payload if length > 0 */
    188                                 memset(&v4l2_ioctl, 0, sizeof(v4l2_ioctl));
    189                                 v4l2_ioctl.trans_code = node->u.evt.e.pri_evt.trans_id;
    190                                 v4l2_ioctl.len = node->u.evt.e.pri_evt.data_length;
    191                                 v4l2_ioctl.ioctl_ptr = &(node->u.evt.e.pri_evt.evt_data[0]);
    192                                 rc = ioctl(my_obj->ctrl_fd, MSM_CAM_V4L2_IOCTL_GET_EVENT_PAYLOAD,
    193                                            &v4l2_ioctl);
    194                                 if (rc < 0) {
    195                                     CDBG_ERROR("%s: get event payload returns error = %d",
    196                                                __func__, rc);
    197                                     free(node);
    198                                     node = NULL;
    199                                 } else {
    200                                     CDBG("%s: data_length =%d (trans_id=%d) (payload=%s)",
    201                                          __func__, evt->e.pri_evt.data_length,
    202                                          node->u.evt.e.pri_evt.trans_id,
    203                                          (char*)&node->u.evt.e.pri_evt.evt_data[0]);
    204                                 }
    205                             }
    206                         }
    207                     }
    208                     break;
    209                 default:
    210                     break;
    211                 }
    212             }
    213             if (NULL != node) {
    214                 /* enqueue to evt cmd thread */
    215                 mm_camera_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
    216                 /* wake up evt cmd thread */
    217                 sem_post(&(my_obj->evt_thread.cmd_sem));
    218             }
    219         }
    220     }
    221 }
    222 
    223 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
    224                               mm_camera_event_t *event)
    225 {
    226     int32_t rc = 0;
    227     mm_camera_cmdcb_t *node = NULL;
    228 
    229     node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
    230     if (NULL != node) {
    231         memset(node, 0, sizeof(mm_camera_cmdcb_t));
    232         node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
    233         memcpy(&node->u.evt, event, sizeof(mm_camera_event_t));
    234 
    235         /* enqueue to evt cmd thread */
    236         mm_camera_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
    237         /* wake up evt cmd thread */
    238         sem_post(&(my_obj->evt_thread.cmd_sem));
    239     } else {
    240         CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
    241         rc = -1;
    242     }
    243 
    244     return rc;
    245 }
    246 
    247 /* send local CH evt to HAL
    248  * may not needed since we have return val for each channel/stream operation */
    249 int32_t mm_camera_send_ch_event(mm_camera_obj_t *my_obj,
    250                                 uint32_t ch_id,
    251                                 uint32_t stream_id,
    252                                 mm_camera_ch_event_type_t evt)
    253 {
    254     int rc = 0;
    255     mm_camera_event_t event;
    256     event.event_type = MM_CAMERA_EVT_TYPE_CH;
    257     event.e.ch.evt = evt;
    258     /* TODO: need to change the ch evt struct to include ch_id and stream_id. */
    259     event.e.ch.ch = stream_id;
    260     CDBG("%s: stream on event, type=0x%x, ch=%d, evt=%d",
    261          __func__, event.event_type, event.e.ch.ch, event.e.ch.evt);
    262     rc = mm_camera_enqueue_evt(my_obj, &event);
    263     return rc;
    264 }
    265 
    266 int32_t mm_camera_open(mm_camera_obj_t *my_obj)
    267 {
    268     char dev_name[MM_CAMERA_DEV_NAME_LEN];
    269     int32_t rc = 0;
    270     int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
    271     uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
    272     uint8_t i;
    273     uint8_t cam_idx = mm_camera_util_get_index_by_handler(my_obj->my_hdl);
    274 
    275     CDBG("%s:  begin\n", __func__);
    276 
    277     snprintf(dev_name, sizeof(dev_name), "/dev/%s",
    278              mm_camera_util_get_dev_name(my_obj->my_hdl));
    279 
    280     do{
    281         n_try--;
    282         my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
    283         CDBG("%s:  ctrl_fd = %d, errno == %d", __func__, my_obj->ctrl_fd, errno);
    284         if((my_obj->ctrl_fd > 0) || (errno != EIO) || (n_try <= 0 )) {
    285             CDBG_ERROR("%s:  opened, break out while loop", __func__);
    286             break;
    287         }
    288         CDBG("%s:failed with I/O error retrying after %d milli-seconds",
    289              __func__,sleep_msec);
    290         usleep(sleep_msec*1000);
    291     }while(n_try>0);
    292 
    293     if (my_obj->ctrl_fd <= 0) {
    294         CDBG_ERROR("%s: cannot open control fd of '%s' (%s)\n",
    295                  __func__, dev_name, strerror(errno));
    296         rc = -1;
    297         goto on_error;
    298     }
    299 
    300     /* open domain socket*/
    301     n_try=MM_CAMERA_DEV_OPEN_TRIES;
    302     do{
    303         n_try--;
    304         my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
    305         CDBG("%s:  ds_fd = %d, errno = %d", __func__, my_obj->ds_fd, errno);
    306         if((my_obj->ds_fd > 0) || (n_try <= 0 )) {
    307             CDBG("%s:  opened, break out while loop", __func__);
    308             break;
    309         }
    310         CDBG("%s:failed with I/O error retrying after %d milli-seconds",
    311              __func__,sleep_msec);
    312         usleep(sleep_msec*1000);
    313     }while(n_try>0);
    314 
    315     if (my_obj->ds_fd <= 0) {
    316         CDBG_ERROR("%s: cannot open domain socket fd of '%s'(%s)\n",
    317                  __func__, dev_name, strerror(errno));
    318         rc = -1;
    319         goto on_error;
    320     }
    321 
    322     /* set ctrl_fd to be the mem_mapping fd */
    323     rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd,
    324                         MSM_V4L2_PID_MMAP_INST, 0);
    325     if (rc < 0) {
    326         CDBG_ERROR("error: ioctl VIDIOC_S_CTRL MSM_V4L2_PID_MMAP_INST failed: %s\n",
    327                    strerror(errno));
    328         goto on_error;
    329     }
    330 
    331     /* set geo mode to 2D by default */
    332     my_obj->current_mode = CAMERA_MODE_2D;
    333 
    334     pthread_mutex_init(&my_obj->cb_lock, NULL);
    335 
    336     CDBG("%s : Launch async cmd Thread in Cam Open",__func__);
    337     mm_camera_cmd_thread_launch(&my_obj->async_cmd_thread,
    338                                 mm_camera_handle_async_cmd,
    339                                 (void *)my_obj);
    340 
    341     CDBG("%s : Launch evt Thread in Cam Open",__func__);
    342     mm_camera_cmd_thread_launch(&my_obj->evt_thread,
    343                                 mm_camera_dispatch_app_event,
    344                                 (void *)my_obj);
    345 
    346     /* launch event poll thread
    347      * we will add evt fd into event poll thread upon user first register for evt */
    348     CDBG("%s : Launch evt Poll Thread in Cam Open",__func__);
    349     mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
    350                                  MM_CAMERA_POLL_TYPE_EVT);
    351 
    352     CDBG("%s:  end (rc = %d)\n", __func__, rc);
    353     /* we do not need to unlock cam_lock here before return
    354      * because for open, it's done within intf_lock */
    355     return rc;
    356 
    357 on_error:
    358     if (my_obj->ctrl_fd > 0) {
    359         close(my_obj->ctrl_fd);
    360         my_obj->ctrl_fd = -1;
    361     }
    362     if (my_obj->ds_fd > 0) {
    363         mm_camera_socket_close(my_obj->ds_fd);
    364        my_obj->ds_fd = -1;
    365     }
    366 
    367     /* we do not need to unlock cam_lock here before return
    368      * because for open, it's done within intf_lock */
    369     return rc;
    370 }
    371 
    372 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
    373 {
    374     CDBG("%s : Close evt Poll Thread in Cam Close",__func__);
    375     mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
    376 
    377     CDBG("%s : Close evt cmd Thread in Cam Close",__func__);
    378     mm_camera_cmd_thread_release(&my_obj->evt_thread);
    379 
    380     CDBG("%s : Close asyn cmd Thread in Cam Close",__func__);
    381     mm_camera_cmd_thread_release(&my_obj->async_cmd_thread);
    382 
    383     if(my_obj->ctrl_fd > 0) {
    384         close(my_obj->ctrl_fd);
    385         my_obj->ctrl_fd = -1;
    386     }
    387     if(my_obj->ds_fd > 0) {
    388         mm_camera_socket_close(my_obj->ds_fd);
    389         my_obj->ds_fd = -1;
    390     }
    391 
    392     pthread_mutex_destroy(&my_obj->cb_lock);
    393 
    394     pthread_mutex_unlock(&my_obj->cam_lock);
    395     return 0;
    396 }
    397 
    398 uint8_t mm_camera_is_event_supported(mm_camera_obj_t *my_obj, mm_camera_event_type_t evt_type)
    399 {
    400     switch(evt_type) {
    401     case MM_CAMERA_EVT_TYPE_CH:
    402     case MM_CAMERA_EVT_TYPE_CTRL:
    403     case MM_CAMERA_EVT_TYPE_STATS:
    404     case MM_CAMERA_EVT_TYPE_INFO:
    405       return 1;
    406     default:
    407       return 0;
    408     }
    409     return 0;
    410 }
    411 
    412 int32_t mm_camera_register_event_notify_internal(
    413                                    mm_camera_obj_t *my_obj,
    414                                    mm_camera_event_notify_t evt_cb,
    415                                    void * user_data,
    416                                    mm_camera_event_type_t evt_type)
    417 {
    418     int i;
    419     int rc = -1;
    420     mm_camera_evt_obj_t *evt_array = NULL;
    421 
    422     pthread_mutex_lock(&my_obj->cb_lock);
    423     evt_array = &my_obj->evt[evt_type];
    424     if(evt_cb) {
    425         /* this is reg case */
    426         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
    427             if(evt_array->evt[i].user_data == NULL) {
    428                 evt_array->evt[i].evt_cb = evt_cb;
    429                 evt_array->evt[i].user_data = user_data;
    430                 evt_array->reg_count++;
    431                 rc = 0;
    432                 break;
    433             }
    434         }
    435     } else {
    436         /* this is unreg case */
    437         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
    438             if(evt_array->evt[i].user_data == user_data) {
    439                 evt_array->evt[i].evt_cb = NULL;
    440                 evt_array->evt[i].user_data = NULL;
    441                 evt_array->reg_count--;
    442                 rc = 0;
    443                 break;
    444             }
    445         }
    446     }
    447 
    448     if(rc == 0 && evt_array->reg_count <= 1) {
    449         /* subscribe/unsubscribe event to kernel */
    450         rc = mm_camera_evt_sub(my_obj, evt_type, evt_array->reg_count);
    451     }
    452 
    453     pthread_mutex_unlock(&my_obj->cb_lock);
    454     return rc;
    455 }
    456 
    457 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
    458                                    mm_camera_event_notify_t evt_cb,
    459                                    void * user_data,
    460                                    mm_camera_event_type_t evt_type)
    461 {
    462     int i;
    463     int rc = -1;
    464     mm_camera_evt_obj_t *evt_array = &my_obj->evt[evt_type];
    465 
    466     rc = mm_camera_register_event_notify_internal(my_obj, evt_cb,
    467                                                   user_data, evt_type);
    468 
    469     pthread_mutex_unlock(&my_obj->cam_lock);
    470     return rc;
    471 }
    472 
    473 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
    474                        uint32_t ch_id,
    475                        mm_camera_buf_def_t *buf)
    476 {
    477     int rc = -1;
    478     mm_channel_t * ch_obj = NULL;
    479     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    480 
    481     pthread_mutex_unlock(&my_obj->cam_lock);
    482 
    483     /* we always assume qbuf will be done before channel/stream is fully stopped
    484      * because qbuf is done within dataCB context
    485      * in order to avoid deadlock, we are not locking ch_lock for qbuf */
    486     if (NULL != ch_obj) {
    487         rc = mm_channel_qbuf(ch_obj, buf);
    488     }
    489 
    490     return rc;
    491 }
    492 
    493 mm_camera_2nd_sensor_t * mm_camera_query_2nd_sensor_info(mm_camera_obj_t *my_obj)
    494 {
    495     /* TODO: need to sync with backend how to get 2nd sensor info */
    496     return NULL;
    497 }
    498 
    499 int32_t mm_camera_sync(mm_camera_obj_t *my_obj)
    500 {
    501     int32_t rc = 0;
    502 
    503     /* get camera capabilities */
    504     memset(&my_obj->properties, 0, sizeof(cam_prop_t));
    505     rc = mm_camera_send_native_ctrl_cmd(my_obj,
    506                                         CAMERA_GET_CAPABILITIES,
    507                                         sizeof(cam_prop_t),
    508                                         (void *)&my_obj->properties);
    509     if (rc != 0) {
    510         CDBG_ERROR("%s: cannot get camera capabilities\n", __func__);
    511         goto on_error;
    512     }
    513 
    514 on_error:
    515     pthread_mutex_unlock(&my_obj->cam_lock);
    516     return rc;
    517 
    518 }
    519 
    520 int32_t mm_camera_is_op_supported(mm_camera_obj_t *my_obj,
    521                                    mm_camera_ops_type_t op_code)
    522 {
    523     int32_t rc = 0;
    524     int32_t is_ops_supported = false;
    525     int index = 0;
    526 
    527     if (op_code != MM_CAMERA_OPS_LOCAL) {
    528         index = op_code/32;
    529         is_ops_supported = ((my_obj->properties.ops[index] &
    530             (1<<op_code)) != 0);
    531 
    532     }
    533     pthread_mutex_unlock(&my_obj->cam_lock);
    534     return is_ops_supported;
    535 }
    536 
    537 int32_t mm_camera_is_parm_supported(mm_camera_obj_t *my_obj,
    538                                    mm_camera_parm_type_t parm_type,
    539                                    uint8_t *support_set_parm,
    540                                    uint8_t *support_get_parm)
    541 {
    542     /* TODO: need to sync with backend if it can support set/get */
    543     int32_t rc = 0;
    544     *support_set_parm = GET_PARM_BIT32(parm_type,
    545                                        my_obj->properties.parm);
    546     *support_get_parm = GET_PARM_BIT32(parm_type,
    547                                        my_obj->properties.parm);
    548     pthread_mutex_unlock(&my_obj->cam_lock);
    549 
    550     return rc;
    551 }
    552 
    553 int32_t mm_camera_util_set_op_mode(mm_camera_obj_t * my_obj,
    554                                    mm_camera_op_mode_type_t *op_mode)
    555 {
    556     int32_t rc = 0;
    557     int32_t v4l2_op_mode = MSM_V4L2_CAM_OP_DEFAULT;
    558 
    559     if (my_obj->op_mode == *op_mode)
    560         goto end;
    561     switch(*op_mode) {
    562     case MM_CAMERA_OP_MODE_ZSL:
    563         v4l2_op_mode = MSM_V4L2_CAM_OP_ZSL;
    564             break;
    565     case MM_CAMERA_OP_MODE_CAPTURE:
    566         v4l2_op_mode = MSM_V4L2_CAM_OP_CAPTURE;
    567             break;
    568     case MM_CAMERA_OP_MODE_VIDEO:
    569         v4l2_op_mode = MSM_V4L2_CAM_OP_VIDEO;
    570             break;
    571     case MM_CAMERA_OP_MODE_RAW:
    572         v4l2_op_mode = MSM_V4L2_CAM_OP_RAW;
    573             break;
    574     default:
    575         rc = - 1;
    576         goto end;
    577         break;
    578     }
    579     if(0 != (rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd,
    580             MSM_V4L2_PID_CAM_MODE, v4l2_op_mode))){
    581         CDBG_ERROR("%s: input op_mode=%d, s_ctrl rc=%d\n", __func__, *op_mode, rc);
    582         goto end;
    583     }
    584     /* if success update mode field */
    585     my_obj->op_mode = *op_mode;
    586 end:
    587     CDBG("%s: op_mode=%d,rc=%d\n", __func__, *op_mode, rc);
    588     return rc;
    589 }
    590 
    591 int32_t mm_camera_set_parm(mm_camera_obj_t *my_obj,
    592                            mm_camera_parm_type_t parm_type,
    593                            void* p_value)
    594 {
    595     int32_t rc = 0;
    596     CDBG("%s type =%d", __func__, parm_type);
    597     switch(parm_type) {
    598     case MM_CAMERA_PARM_OP_MODE:
    599         rc = mm_camera_util_set_op_mode(my_obj,
    600                         (mm_camera_op_mode_type_t *)p_value);
    601         break;
    602     case MM_CAMERA_PARM_DIMENSION:
    603         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    604                     CAMERA_SET_PARM_DIMENSION, sizeof(cam_ctrl_dimension_t), p_value);
    605         if(rc != 0) {
    606             CDBG("%s: mm_camera_send_native_ctrl_cmd err=%d\n", __func__, rc);
    607             break;
    608         }
    609         memcpy(&my_obj->dim, (cam_ctrl_dimension_t *)p_value,
    610                      sizeof(cam_ctrl_dimension_t));
    611         CDBG("%s: dw=%d,dh=%d,vw=%d,vh=%d,pw=%d,ph=%d,tw=%d,th=%d,raw_w=%d,raw_h=%d\n",
    612                  __func__,
    613                  my_obj->dim.display_width,my_obj->dim.display_height,
    614                  my_obj->dim.video_width, my_obj->dim.video_height,
    615                  my_obj->dim.picture_width,my_obj->dim.picture_height,
    616                  my_obj->dim.ui_thumbnail_width,my_obj->dim.ui_thumbnail_height,
    617                  my_obj->dim.raw_picture_width,my_obj->dim.raw_picture_height);
    618         break;
    619     case MM_CAMERA_PARM_SNAPSHOT_BURST_NUM:
    620         my_obj->snap_burst_num_by_user = *((uint32_t *)p_value);
    621         break;
    622     default:
    623         rc = mm_camera_set_general_parm(my_obj, parm_type, p_value);
    624         break;
    625     }
    626     pthread_mutex_unlock(&my_obj->cam_lock);
    627     return rc;
    628 }
    629 
    630 int32_t mm_camera_get_parm(mm_camera_obj_t *my_obj,
    631                            mm_camera_parm_type_t parm_type,
    632                            void* p_value)
    633 {
    634     int32_t rc = 0;
    635 
    636     switch(parm_type) {
    637     case MM_CAMERA_PARM_FRAME_RESOLUTION:
    638         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    639                                             CAMERA_GET_PARM_FRAME_RESOLUTION,
    640                                             sizeof(cam_frame_resolution_t),
    641                                             p_value);
    642         if (rc < 0)
    643             CDBG_ERROR("%s: ERROR in CAMERA_GET_PARM_FRAME_RESOLUTION, rc = %d",
    644                  __func__, rc);
    645         break;
    646     case MM_CAMERA_PARM_MAX_PICTURE_SIZE:
    647         {
    648             mm_camera_dimension_t *dim =
    649                 (mm_camera_dimension_t *)p_value;
    650             dim->height = my_obj->properties.max_pict_height;
    651             dim->width = my_obj->properties.max_pict_width;
    652             CDBG("%s: Max Picture Size: %d X %d\n", __func__,
    653                  dim->width, dim->height);
    654         }
    655         break;
    656     case MM_CAMERA_PARM_PREVIEW_FORMAT:
    657         *((int *)p_value) = my_obj->properties.preview_format;
    658         break;
    659     case MM_CAMERA_PARM_PREVIEW_SIZES_CNT:
    660         *((int *)p_value) = my_obj->properties.preview_sizes_cnt;
    661         break;
    662     case MM_CAMERA_PARM_VIDEO_SIZES_CNT:
    663         *((int *)p_value) = my_obj->properties.video_sizes_cnt;
    664         break;
    665     case MM_CAMERA_PARM_THUMB_SIZES_CNT:
    666         *((int *)p_value) = my_obj->properties.thumb_sizes_cnt;
    667         break;
    668     case MM_CAMERA_PARM_HFR_SIZES_CNT:
    669         *((int *)p_value) = my_obj->properties.hfr_sizes_cnt;
    670         break;
    671     case MM_CAMERA_PARM_HFR_FRAME_SKIP:
    672         *((int *)p_value) = my_obj->properties.hfr_frame_skip;
    673         break;
    674     case MM_CAMERA_PARM_DEFAULT_PREVIEW_WIDTH:
    675         *((int *)p_value) = my_obj->properties.default_preview_width;
    676         break;
    677     case MM_CAMERA_PARM_DEFAULT_PREVIEW_HEIGHT:
    678         *((int *)p_value) = my_obj->properties.default_preview_height;
    679         break;
    680     case MM_CAMERA_PARM_MAX_PREVIEW_SIZE:
    681         {
    682             mm_camera_dimension_t *dim =
    683                 (mm_camera_dimension_t *)p_value;
    684             dim->height = my_obj->properties.max_preview_height;
    685             dim->width = my_obj->properties.max_preview_width;
    686             CDBG("%s: Max Preview Size: %d X %d\n", __func__,
    687                  dim->width, dim->height);
    688         }
    689         break;
    690     case MM_CAMERA_PARM_MAX_VIDEO_SIZE:
    691         {
    692             mm_camera_dimension_t *dim =
    693                 (mm_camera_dimension_t *)p_value;
    694             dim->height = my_obj->properties.max_video_height;
    695             dim->width = my_obj->properties.max_video_width;
    696             CDBG("%s: Max Video Size: %d X %d\n", __func__,
    697                  dim->width, dim->height);
    698         }
    699         break;
    700     case MM_CAMERA_PARM_MAX_HFR_MODE:
    701         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    702                                             CAMERA_GET_PARM_MAX_HFR_MODE,
    703                                             sizeof(camera_hfr_mode_t),
    704                                             p_value);
    705         break;
    706     case MM_CAMERA_PARM_FOCAL_LENGTH:
    707         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    708                                             CAMERA_GET_PARM_FOCAL_LENGTH,
    709                                             sizeof(float),
    710                                             p_value);
    711         break;
    712     case MM_CAMERA_PARM_HORIZONTAL_VIEW_ANGLE:
    713         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    714                                             CAMERA_GET_PARM_HORIZONTAL_VIEW_ANGLE,
    715                                             sizeof(float),
    716                                             p_value);
    717         break;
    718     case MM_CAMERA_PARM_VERTICAL_VIEW_ANGLE:
    719         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    720                                             CAMERA_GET_PARM_VERTICAL_VIEW_ANGLE,
    721                                             sizeof(float),
    722                                             p_value);
    723         break;
    724     case MM_CAMERA_PARM_FOCUS_DISTANCES:
    725         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    726                                             CAMERA_GET_PARM_FOCUS_DISTANCES,
    727                                             sizeof(focus_distances_info_t),
    728                                             p_value);
    729         break;
    730     case MM_CAMERA_PARM_QUERY_FALSH4SNAP:
    731         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    732                                             CAMERA_QUERY_FLASH_FOR_SNAPSHOT,
    733                                             sizeof(int),
    734                                             p_value);
    735         break;
    736     case MM_CAMERA_PARM_3D_FRAME_FORMAT:
    737         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    738                                             CAMERA_GET_PARM_3D_FRAME_FORMAT,
    739                                             sizeof(camera_3d_frame_t),
    740                                             p_value);
    741         break;
    742     case MM_CAMERA_PARM_MAXZOOM:
    743         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    744                                             CAMERA_GET_PARM_MAXZOOM,
    745                                             sizeof(int),
    746                                             p_value);
    747         break;
    748     case MM_CAMERA_PARM_ZOOM_RATIO:
    749         {
    750             mm_camera_zoom_tbl_t *tbl = (mm_camera_zoom_tbl_t *)p_value;
    751             rc = mm_camera_send_native_ctrl_cmd(my_obj,
    752                                                 CAMERA_GET_PARM_ZOOMRATIOS,
    753                                                 sizeof(int16_t)*tbl->size,
    754                                                 (void *)(tbl->zoom_ratio_tbl));
    755         }
    756         break;
    757     case MM_CAMERA_PARM_DEF_PREVIEW_SIZES:
    758         {
    759             default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
    760             rc = mm_camera_send_native_ctrl_cmd(my_obj,
    761                                                 CAMERA_GET_PARM_DEF_PREVIEW_SIZES,
    762                                                 sizeof(struct camera_size_type)*tbl->tbl_size,
    763                                                 (void* )(tbl->sizes_tbl));
    764         }
    765         break;
    766     case MM_CAMERA_PARM_DEF_VIDEO_SIZES:
    767         {
    768             default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
    769             rc = mm_camera_send_native_ctrl_cmd(my_obj,
    770                                                 CAMERA_GET_PARM_DEF_VIDEO_SIZES,
    771                                                 sizeof(struct camera_size_type)*tbl->tbl_size,
    772                                                 (void *)(tbl->sizes_tbl));
    773         }
    774         break;
    775     case MM_CAMERA_PARM_DEF_THUMB_SIZES:
    776         {
    777             default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
    778             rc = mm_camera_send_native_ctrl_cmd(my_obj,
    779                                                 CAMERA_GET_PARM_DEF_THUMB_SIZES,
    780                                                 sizeof(struct camera_size_type)*tbl->tbl_size,
    781                                                 (void *)(tbl->sizes_tbl));
    782         }
    783         break;
    784     case MM_CAMERA_PARM_DEF_HFR_SIZES:
    785         {
    786             default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
    787             rc = mm_camera_send_native_ctrl_cmd(my_obj,
    788                                                 CAMERA_GET_PARM_DEF_HFR_SIZES,
    789                                                 sizeof(struct camera_size_type)*tbl->tbl_size,
    790                                                 (void *)(tbl->sizes_tbl));
    791         }
    792         break;
    793     case MM_CAMERA_PARM_SNAPSHOT_BURST_NUM:
    794         *((int *)p_value) = my_obj->snap_burst_num_by_user;
    795         break;
    796     case MM_CAMERA_PARM_VFE_OUTPUT_ENABLE:
    797         *((int *)p_value) = my_obj->properties.vfe_output_enable;
    798         break;
    799     case MM_CAMERA_PARM_DIMENSION:
    800         memcpy(p_value, &my_obj->dim, sizeof(my_obj->dim));
    801         CDBG("%s: dw=%d,dh=%d,vw=%d,vh=%d,pw=%d,ph=%d,tw=%d,th=%d,ovx=%x,ovy=%d,opx=%d,opy=%d, m_fmt=%d, t_ftm=%d\n",
    802                  __func__,
    803                  my_obj->dim.display_width,my_obj->dim.display_height,
    804                  my_obj->dim.video_width,my_obj->dim.video_height,
    805                  my_obj->dim.picture_width,my_obj->dim.picture_height,
    806                  my_obj->dim.ui_thumbnail_width,my_obj->dim.ui_thumbnail_height,
    807                  my_obj->dim.orig_video_width,my_obj->dim.orig_video_height,
    808                  my_obj->dim.orig_picture_width,my_obj->dim.orig_picture_height,
    809                  my_obj->dim.main_img_format, my_obj->dim.thumb_format);
    810         break;
    811     case MM_CAMERA_PARM_OP_MODE:
    812         *((mm_camera_op_mode_type_t *)p_value) = my_obj->op_mode;
    813         break;
    814     case MM_CAMERA_PARM_MAX_NUM_FACES_DECT:
    815         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    816                                             CAMERA_GET_MAX_NUM_FACES_DECT,
    817                                             sizeof(int),
    818                                             p_value);
    819         break;
    820     case MM_CAMERA_PARM_HDR:
    821         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    822                                             CAMERA_GET_PARM_HDR,
    823                                             sizeof(exp_bracketing_t),
    824                                             p_value);
    825         break;
    826     case MM_CAMERA_PARM_FPS_RANGE:
    827         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    828                                             CAMERA_GET_PARM_FPS_RANGE,
    829                                             sizeof(cam_sensor_fps_range_t),
    830                                             p_value);
    831         break;
    832 
    833     case MM_CAMERA_PARM_BESTSHOT_RECONFIGURE:
    834         *((int *)p_value) = my_obj->properties.bestshot_reconfigure;
    835         break;
    836 
    837     case MM_CAMERA_PARM_MOBICAT:
    838         rc = mm_camera_send_native_ctrl_cmd(my_obj,
    839                                             CAMERA_GET_PARM_MOBICAT,
    840                                             sizeof(cam_exif_tags_t),
    841                                             p_value);
    842         break;
    843     default:
    844         /* needs to add more implementation */
    845         rc = -1;
    846         break;
    847     }
    848 
    849     pthread_mutex_unlock(&my_obj->cam_lock);
    850     return rc;
    851 }
    852 
    853 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj)
    854 {
    855     mm_channel_t *ch_obj = NULL;
    856     uint8_t ch_idx = 0;
    857     uint32_t ch_hdl = 0;
    858 
    859     for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
    860         if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
    861             ch_obj = &my_obj->ch[ch_idx];
    862             break;
    863         }
    864     }
    865 
    866     if (NULL != ch_obj) {
    867         /* initialize channel obj */
    868         memset(ch_obj, 0, sizeof(mm_channel_t));
    869         ch_hdl = mm_camera_util_generate_handler(ch_idx);
    870         ch_obj->my_hdl = ch_hdl;
    871         ch_obj->state = MM_CHANNEL_STATE_STOPPED;
    872         ch_obj->cam_obj = my_obj;
    873         pthread_mutex_init(&ch_obj->ch_lock, NULL);
    874     }
    875 
    876     mm_channel_init(ch_obj);
    877     pthread_mutex_unlock(&my_obj->cam_lock);
    878 
    879     return ch_hdl;
    880 }
    881 
    882 void mm_camera_del_channel(mm_camera_obj_t *my_obj,
    883                            uint32_t ch_id)
    884 {
    885     mm_channel_t * ch_obj =
    886         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    887 
    888     if (NULL != ch_obj) {
    889         pthread_mutex_lock(&ch_obj->ch_lock);
    890         pthread_mutex_unlock(&my_obj->cam_lock);
    891 
    892         mm_channel_fsm_fn(ch_obj,
    893                                MM_CHANNEL_EVT_DELETE,
    894                                NULL,
    895                                NULL);
    896 
    897         pthread_mutex_destroy(&ch_obj->ch_lock);
    898         memset(ch_obj, 0, sizeof(mm_channel_t));
    899     } else {
    900         pthread_mutex_unlock(&my_obj->cam_lock);
    901     }
    902 }
    903 
    904 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
    905                               uint32_t ch_id,
    906                               mm_camera_buf_notify_t buf_cb, void *user_data,
    907                               uint32_t ext_image_mode, uint32_t sensor_idx)
    908 {
    909     uint32_t s_hdl = 0;
    910     mm_channel_t * ch_obj =
    911         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    912     mm_evt_paylod_add_stream_t payload;
    913 
    914     if (NULL != ch_obj) {
    915         pthread_mutex_lock(&ch_obj->ch_lock);
    916         pthread_mutex_unlock(&my_obj->cam_lock);
    917 
    918         memset(&payload, 0, sizeof(mm_evt_paylod_add_stream_t));
    919         payload.buf_cb = buf_cb;
    920         payload.user_data = user_data;
    921         payload.ext_image_mode = ext_image_mode;
    922         payload.sensor_idx = sensor_idx;
    923         mm_channel_fsm_fn(ch_obj,
    924                                MM_CHANNEL_EVT_ADD_STREAM,
    925                                (void*)&payload,
    926                                (void*)&s_hdl);
    927     } else {
    928         pthread_mutex_unlock(&my_obj->cam_lock);
    929     }
    930 
    931     return s_hdl;
    932 }
    933 
    934 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
    935                              uint32_t ch_id,
    936                              uint32_t stream_id)
    937 {
    938     int32_t rc = -1;
    939     mm_channel_t * ch_obj =
    940         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    941 
    942     if (NULL != ch_obj) {
    943         pthread_mutex_lock(&ch_obj->ch_lock);
    944         pthread_mutex_unlock(&my_obj->cam_lock);
    945 
    946         rc = mm_channel_fsm_fn(ch_obj,
    947                                MM_CHANNEL_EVT_DEL_STREAM,
    948                                (void*)&stream_id,
    949                                NULL);
    950     } else {
    951         pthread_mutex_unlock(&my_obj->cam_lock);
    952     }
    953 
    954     return rc;
    955 }
    956 
    957 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
    958                                 uint32_t ch_id,
    959                                 uint32_t stream_id,
    960                                 mm_camera_stream_config_t *config)
    961 {
    962     int32_t rc = -1;
    963     mm_channel_t * ch_obj =
    964         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    965     mm_evt_paylod_config_stream_t payload;
    966 
    967     if (NULL != ch_obj) {
    968         pthread_mutex_lock(&ch_obj->ch_lock);
    969         pthread_mutex_unlock(&my_obj->cam_lock);
    970 
    971         memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
    972         payload.stream_id = stream_id;
    973         payload.config = config;
    974         rc = mm_channel_fsm_fn(ch_obj,
    975                                MM_CHANNEL_EVT_CONFIG_STREAM,
    976                                (void*)&payload,
    977                                NULL);
    978     } else {
    979         pthread_mutex_unlock(&my_obj->cam_lock);
    980     }
    981 
    982     return rc;
    983 }
    984 
    985 int32_t mm_camera_bundle_streams(mm_camera_obj_t *my_obj,
    986                                  uint32_t ch_id,
    987                                  mm_camera_buf_notify_t super_frame_notify_cb,
    988                                  void *user_data,
    989                                  mm_camera_bundle_attr_t *attr,
    990                                  uint8_t num_streams,
    991                                  uint32_t *stream_ids)
    992 {
    993     int32_t rc = -1;
    994     mm_channel_t * ch_obj =
    995         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
    996     mm_evt_payload_bundle_stream_t payload;
    997 
    998     if (NULL != ch_obj) {
    999         pthread_mutex_lock(&ch_obj->ch_lock);
   1000         pthread_mutex_unlock(&my_obj->cam_lock);
   1001 
   1002         memset(&payload, 0, sizeof(mm_evt_payload_bundle_stream_t));
   1003         payload.super_frame_notify_cb = super_frame_notify_cb;
   1004         payload.user_data = user_data;
   1005         payload.attr = attr;
   1006         payload.num_streams = num_streams;
   1007         payload.stream_ids = stream_ids;
   1008         rc = mm_channel_fsm_fn(ch_obj,
   1009                                MM_CHANNEL_EVT_INIT_BUNDLE,
   1010                                (void*)&payload,
   1011                                NULL);
   1012     } else {
   1013         pthread_mutex_unlock(&my_obj->cam_lock);
   1014     }
   1015 
   1016     return rc;
   1017 }
   1018 
   1019 int32_t mm_camera_destroy_bundle(mm_camera_obj_t *my_obj, uint32_t ch_id)
   1020 {
   1021     int32_t rc = -1;
   1022     mm_channel_t * ch_obj =
   1023         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1024 
   1025     if (NULL != ch_obj) {
   1026         pthread_mutex_lock(&ch_obj->ch_lock);
   1027         pthread_mutex_unlock(&my_obj->cam_lock);
   1028 
   1029         rc = mm_channel_fsm_fn(ch_obj,
   1030                                MM_CHANNEL_EVT_DESTROY_BUNDLE,
   1031                                NULL,
   1032                                NULL);
   1033     } else {
   1034         pthread_mutex_unlock(&my_obj->cam_lock);
   1035     }
   1036 
   1037     return rc;
   1038 }
   1039 
   1040 int32_t mm_camera_start_streams(mm_camera_obj_t *my_obj,
   1041                                 uint32_t ch_id,
   1042                                 uint8_t num_streams,
   1043                                 uint32_t *stream_ids)
   1044 {
   1045     int32_t rc = -1;
   1046     mm_channel_t * ch_obj =
   1047         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1048     mm_evt_payload_start_stream_t payload;
   1049 
   1050     if (NULL != ch_obj) {
   1051         pthread_mutex_lock(&ch_obj->ch_lock);
   1052         pthread_mutex_unlock(&my_obj->cam_lock);
   1053 
   1054         memset(&payload, 0, sizeof(mm_evt_payload_start_stream_t));
   1055         payload.num_streams = num_streams;
   1056         payload.stream_ids = stream_ids;
   1057         rc = mm_channel_fsm_fn(ch_obj,
   1058                                MM_CHANNEL_EVT_START_STREAM,
   1059                                (void*)&payload,
   1060                                NULL);
   1061     } else {
   1062         pthread_mutex_unlock(&my_obj->cam_lock);
   1063     }
   1064 
   1065     return rc;
   1066 }
   1067 
   1068 int32_t mm_camera_stop_streams(mm_camera_obj_t *my_obj,
   1069                                uint32_t ch_id,
   1070                                uint8_t num_streams,
   1071                                uint32_t *stream_ids)
   1072 {
   1073     int32_t rc = 0;
   1074     mm_evt_payload_stop_stream_t payload;
   1075     mm_camera_cmdcb_t * node = NULL;
   1076 
   1077     mm_channel_t * ch_obj =
   1078         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1079 
   1080     if (NULL != ch_obj) {
   1081         pthread_mutex_lock(&ch_obj->ch_lock);
   1082         pthread_mutex_unlock(&my_obj->cam_lock);
   1083 
   1084         memset(&payload, 0, sizeof(mm_evt_payload_stop_stream_t));
   1085         payload.num_streams = num_streams;
   1086         payload.stream_ids = stream_ids;
   1087 
   1088         rc = mm_channel_fsm_fn(ch_obj,
   1089                                MM_CHANNEL_EVT_STOP_STREAM,
   1090                                (void*)&payload,
   1091                                NULL);
   1092     } else {
   1093         pthread_mutex_unlock(&my_obj->cam_lock);
   1094     }
   1095     return rc;
   1096 }
   1097 
   1098 int32_t mm_camera_async_teardown_streams(mm_camera_obj_t *my_obj,
   1099                                           uint32_t ch_id,
   1100                                           uint8_t num_streams,
   1101                                           uint32_t *stream_ids)
   1102 {
   1103     int32_t rc = 0;
   1104     mm_evt_payload_stop_stream_t payload;
   1105     mm_camera_cmdcb_t * node = NULL;
   1106 
   1107     mm_channel_t * ch_obj =
   1108         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1109 
   1110     if (NULL != ch_obj) {
   1111         pthread_mutex_lock(&ch_obj->ch_lock);
   1112         pthread_mutex_unlock(&my_obj->cam_lock);
   1113 
   1114         /* enqueu asyn stop cmd to async_cmd_thread */
   1115         node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
   1116         if (NULL != node) {
   1117             memset(node, 0, sizeof(mm_camera_cmdcb_t));
   1118             node->cmd_type = MM_CAMERA_CMD_TYPE_ASYNC_CB;
   1119             node->u.async.cmd_type = MM_CAMERA_ASYNC_CMD_TYPE_STOP;
   1120             node->u.async.u.stop_cmd.ch_obj = ch_obj;
   1121             node->u.async.u.stop_cmd.num_streams = num_streams;
   1122             memcpy(node->u.async.u.stop_cmd.stream_ids, stream_ids, sizeof(uint32_t)*num_streams);
   1123 
   1124             /* enqueue to async cmd thread */
   1125             mm_camera_queue_enq(&(my_obj->async_cmd_thread.cmd_queue), node);
   1126             /* wake up async cmd thread */
   1127             sem_post(&(my_obj->async_cmd_thread.cmd_sem));
   1128         } else {
   1129             CDBG_ERROR("%s: No memory for mm_camera_cmdcb_t", __func__);
   1130             pthread_mutex_unlock(&ch_obj->ch_lock);
   1131             rc = -1;
   1132             return rc;
   1133         }
   1134     } else {
   1135         pthread_mutex_unlock(&my_obj->cam_lock);
   1136     }
   1137     return rc;
   1138 }
   1139 
   1140 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
   1141                                     uint32_t ch_id,
   1142                                     uint32_t num_buf_requested)
   1143 {
   1144     int32_t rc = -1;
   1145     mm_channel_t * ch_obj =
   1146         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1147 
   1148     if (NULL != ch_obj) {
   1149         pthread_mutex_lock(&ch_obj->ch_lock);
   1150         pthread_mutex_unlock(&my_obj->cam_lock);
   1151 
   1152         rc = mm_channel_fsm_fn(ch_obj,
   1153                                MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
   1154                                (void*)num_buf_requested,
   1155                                NULL);
   1156     } else {
   1157         pthread_mutex_unlock(&my_obj->cam_lock);
   1158     }
   1159 
   1160     return rc;
   1161 }
   1162 
   1163 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
   1164 {
   1165     int32_t rc = -1;
   1166     mm_channel_t * ch_obj =
   1167         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1168 
   1169     if (NULL != ch_obj) {
   1170         pthread_mutex_lock(&ch_obj->ch_lock);
   1171         pthread_mutex_unlock(&my_obj->cam_lock);
   1172 
   1173         rc = mm_channel_fsm_fn(ch_obj,
   1174                                MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
   1175                                NULL,
   1176                                NULL);
   1177     } else {
   1178         pthread_mutex_unlock(&my_obj->cam_lock);
   1179     }
   1180 
   1181     return rc;
   1182 }
   1183 
   1184 int32_t mm_camera_start_focus(mm_camera_obj_t *my_obj,
   1185                               uint32_t ch_id,
   1186                               uint32_t sensor_idx,
   1187                               uint32_t focus_mode)
   1188 {
   1189     int32_t rc = -1;
   1190     mm_evt_payload_start_focus_t payload;
   1191     mm_channel_t * ch_obj =
   1192         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1193 
   1194     if (NULL != ch_obj) {
   1195         pthread_mutex_lock(&ch_obj->ch_lock);
   1196         pthread_mutex_unlock(&my_obj->cam_lock);
   1197 
   1198         memset(&payload, 0, sizeof(mm_evt_payload_start_focus_t));
   1199         payload.sensor_idx = sensor_idx;
   1200         payload.focus_mode = focus_mode;
   1201         rc = mm_channel_fsm_fn(ch_obj,
   1202                                MM_CHANNEL_EVT_START_FOCUS,
   1203                                (void *)&payload,
   1204                                NULL);
   1205         if (0 != rc) {
   1206             mm_camera_event_t event;
   1207             event.event_type = MM_CAMERA_EVT_TYPE_CTRL;
   1208             event.e.ctrl.evt = MM_CAMERA_CTRL_EVT_AUTO_FOCUS_DONE;
   1209             event.e.ctrl.status = CAM_CTRL_FAILED;
   1210             rc = mm_camera_enqueue_evt(my_obj, &event);
   1211         }
   1212     } else {
   1213         pthread_mutex_unlock(&my_obj->cam_lock);
   1214     }
   1215 
   1216     return rc;
   1217 }
   1218 
   1219 int32_t mm_camera_abort_focus(mm_camera_obj_t *my_obj,
   1220                               uint32_t ch_id,
   1221                               uint32_t sensor_idx)
   1222 {
   1223     int32_t rc = -1;
   1224     mm_channel_t * ch_obj =
   1225         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1226 
   1227     if (NULL != ch_obj) {
   1228         pthread_mutex_lock(&ch_obj->ch_lock);
   1229         pthread_mutex_unlock(&my_obj->cam_lock);
   1230 
   1231         rc = mm_channel_fsm_fn(ch_obj,
   1232                                MM_CHANNEL_EVT_ABORT_FOCUS,
   1233                                (void*)sensor_idx,
   1234                                NULL);
   1235     } else {
   1236         pthread_mutex_unlock(&my_obj->cam_lock);
   1237     }
   1238 
   1239     return rc;
   1240 }
   1241 
   1242 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
   1243                                    uint32_t ch_id,
   1244                                    uint32_t sensor_idx)
   1245 {
   1246     int32_t rc = -1;
   1247     mm_channel_t * ch_obj =
   1248         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1249 
   1250     if (NULL != ch_obj) {
   1251         pthread_mutex_lock(&ch_obj->ch_lock);
   1252         pthread_mutex_unlock(&my_obj->cam_lock);
   1253 
   1254         rc = mm_channel_fsm_fn(ch_obj,
   1255                                MM_CHANNEL_EVT_PREPARE_SNAPSHOT,
   1256                                (void *)sensor_idx,
   1257                                NULL);
   1258     } else {
   1259         pthread_mutex_unlock(&my_obj->cam_lock);
   1260     }
   1261 
   1262     return rc;
   1263 }
   1264 
   1265 int32_t mm_camera_set_stream_parm(mm_camera_obj_t *my_obj,
   1266                                   uint32_t ch_id,
   1267                                   uint32_t s_id,
   1268                                   mm_camera_stream_parm_t parm_type,
   1269                                   void* p_value)
   1270 {
   1271     int32_t rc = -1;
   1272     mm_evt_paylod_stream_parm_t payload;
   1273     mm_channel_t * ch_obj =
   1274         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1275 
   1276     if (NULL != ch_obj) {
   1277         pthread_mutex_lock(&ch_obj->ch_lock);
   1278         pthread_mutex_unlock(&my_obj->cam_lock);
   1279 
   1280         memset(&payload,0,sizeof(mm_evt_paylod_stream_parm_t));
   1281         payload.parm_type = parm_type;
   1282         payload.value = p_value;
   1283         rc = mm_channel_fsm_fn(ch_obj,
   1284                                MM_CHANNEL_EVT_SET_STREAM_PARM,
   1285                                (void *)s_id,
   1286                                &payload);
   1287     } else {
   1288         pthread_mutex_unlock(&my_obj->cam_lock);
   1289     }
   1290 
   1291     return rc;
   1292 }
   1293 
   1294 int32_t mm_camera_get_stream_parm(mm_camera_obj_t *my_obj,
   1295                                   uint32_t ch_id,
   1296                                   uint32_t s_id,
   1297                                   mm_camera_stream_parm_t parm_type,
   1298                                   void* p_value)
   1299 {
   1300     int32_t rc = -1;
   1301     mm_evt_paylod_stream_parm_t payload;
   1302     mm_channel_t * ch_obj =
   1303         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1304 
   1305     if (NULL != ch_obj) {
   1306         pthread_mutex_lock(&ch_obj->ch_lock);
   1307         pthread_mutex_unlock(&my_obj->cam_lock);
   1308 
   1309         memset(&payload,0,sizeof(mm_evt_paylod_stream_parm_t));
   1310         payload.parm_type = parm_type;
   1311         payload.value = p_value;
   1312         rc = mm_channel_fsm_fn(ch_obj,
   1313                                MM_CHANNEL_EVT_GET_STREAM_PARM,
   1314                                (void *)s_id,
   1315                                &payload);
   1316     } else {
   1317         pthread_mutex_unlock(&my_obj->cam_lock);
   1318     }
   1319 
   1320     return rc;
   1321 }
   1322 
   1323 int32_t mm_camera_send_private_ioctl(mm_camera_obj_t *my_obj,
   1324                                      uint32_t cmd_id,
   1325                                      uint32_t cmd_length,
   1326                                      void *cmd)
   1327 {
   1328     int32_t rc = -1;
   1329 
   1330     struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
   1331 
   1332     CDBG("%s: cmd = %p, length = %d",
   1333                __func__, cmd, cmd_length);
   1334     memset(&v4l2_ioctl, 0, sizeof(v4l2_ioctl));
   1335     v4l2_ioctl.id = cmd_id;
   1336     v4l2_ioctl.len = cmd_length;
   1337     v4l2_ioctl.ioctl_ptr = cmd;
   1338     rc = ioctl (my_obj->ctrl_fd, MSM_CAM_V4L2_IOCTL_PRIVATE_GENERAL, &v4l2_ioctl);
   1339 
   1340     if(rc < 0) {
   1341         CDBG_ERROR("%s: cmd = %p, id = %d, length = %d, rc = %d\n",
   1342                    __func__, cmd, cmd_id, cmd_length, rc);
   1343     } else {
   1344         rc = 0;
   1345     }
   1346 
   1347     return rc;
   1348 }
   1349 
   1350 int32_t mm_camera_ctrl_set_specialEffect (mm_camera_obj_t *my_obj, int32_t effect) {
   1351     struct v4l2_control ctrl;
   1352     if (effect == CAMERA_EFFECT_MAX)
   1353         effect = CAMERA_EFFECT_OFF;
   1354     int rc = 0;
   1355 
   1356     ctrl.id = MSM_V4L2_PID_EFFECT;
   1357     ctrl.value = effect;
   1358     rc = ioctl(my_obj->ctrl_fd, VIDIOC_S_CTRL, &ctrl);
   1359     return (rc >= 0)? 0: -1;;
   1360 }
   1361 
   1362 int32_t mm_camera_ctrl_set_auto_focus (mm_camera_obj_t *my_obj, int32_t value)
   1363 {
   1364     int32_t rc = 0;
   1365     struct v4l2_queryctrl queryctrl;
   1366 
   1367     memset (&queryctrl, 0, sizeof (queryctrl));
   1368     queryctrl.id = V4L2_CID_FOCUS_AUTO;
   1369 
   1370     if(value != 0 && value != 1) {
   1371         CDBG("%s:boolean required, invalid value = %d\n",__func__, value);
   1372         return -1;
   1373     }
   1374     if (-1 == ioctl (my_obj->ctrl_fd, VIDIOC_QUERYCTRL, &queryctrl)) {
   1375         CDBG ("V4L2_CID_FOCUS_AUTO is not supported\n");
   1376     } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
   1377         CDBG ("%s:V4L2_CID_FOCUS_AUTO is not supported\n", __func__);
   1378     } else {
   1379         if(0 != (rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1380                 V4L2_CID_FOCUS_AUTO, value))){
   1381             CDBG("%s: error, id=0x%x, value=%d, rc = %d\n",
   1382                      __func__, V4L2_CID_FOCUS_AUTO, value, rc);
   1383             rc = -1;
   1384         }
   1385     }
   1386     return rc;
   1387 }
   1388 
   1389 int32_t mm_camera_ctrl_set_whitebalance (mm_camera_obj_t *my_obj, int32_t mode) {
   1390 
   1391     int32_t rc = 0, auto_wb, temperature;
   1392     uint32_t id_auto_wb, id_temperature;
   1393 
   1394     id_auto_wb = V4L2_CID_AUTO_WHITE_BALANCE;
   1395     id_temperature = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
   1396 
   1397     switch(mode) {
   1398     case CAMERA_WB_DAYLIGHT:
   1399         auto_wb = 0;
   1400         temperature = 6500;
   1401         break;
   1402     case CAMERA_WB_INCANDESCENT:
   1403         auto_wb = 0;
   1404         temperature = 2800;
   1405         break;
   1406     case CAMERA_WB_FLUORESCENT:
   1407         auto_wb = 0;
   1408         temperature = 4200;
   1409         break;
   1410     case CAMERA_WB_CLOUDY_DAYLIGHT:
   1411         auto_wb = 0;
   1412         temperature = 7500;
   1413         break;
   1414     case CAMERA_WB_AUTO:
   1415     default:
   1416         auto_wb = 1; /* TRUE */
   1417         temperature = 0;
   1418         break;
   1419     }
   1420 
   1421     rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd, id_auto_wb, auto_wb);
   1422     if(0 != rc){
   1423         CDBG_ERROR("%s: error, V4L2_CID_AUTO_WHITE_BALANCE value = %d, rc = %d\n",
   1424             __func__, auto_wb, rc);
   1425         return rc;
   1426     }
   1427     if (!auto_wb) {
   1428         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, id_temperature, temperature);
   1429         if (0 != rc) {
   1430             CDBG_ERROR("%s: error, V4L2_CID_WHITE_BALANCE_TEMPERATURE value = %d, rc = %d\n",
   1431                 __func__, temperature, rc);
   1432             return rc;
   1433         }
   1434     }
   1435     return rc;
   1436 }
   1437 
   1438 int32_t mm_camera_set_general_parm(mm_camera_obj_t * my_obj,
   1439                                    mm_camera_parm_type_t parm_type,
   1440                                    void* p_value)
   1441 {
   1442     int rc = -1;
   1443     int isZSL =0;
   1444 
   1445     switch(parm_type)  {
   1446     case MM_CAMERA_PARM_EXPOSURE:
   1447         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1448                                    MSM_V4L2_PID_EXP_METERING,
   1449                                    *((int32_t *)p_value));
   1450         break;
   1451     case MM_CAMERA_PARM_SHARPNESS:
   1452         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1453                                    V4L2_CID_SHARPNESS,
   1454                                    *((int32_t *)p_value));
   1455         break;
   1456     case MM_CAMERA_PARM_CONTRAST:
   1457         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1458                                    V4L2_CID_CONTRAST,
   1459                                    *((int32_t *)p_value));
   1460         break;
   1461     case MM_CAMERA_PARM_SATURATION:
   1462         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1463                                    V4L2_CID_SATURATION,
   1464                                    *((int32_t *)p_value));
   1465         break;
   1466     case MM_CAMERA_PARM_BRIGHTNESS:
   1467         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1468                                    V4L2_CID_BRIGHTNESS,
   1469                                    *((int32_t *)p_value));
   1470         break;
   1471     case MM_CAMERA_PARM_WHITE_BALANCE:
   1472         rc = mm_camera_ctrl_set_whitebalance (my_obj, *((int32_t *)p_value));
   1473         break;
   1474     case MM_CAMERA_PARM_ISO:
   1475         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1476                                    MSM_V4L2_PID_ISO,
   1477                                    *((int32_t *)p_value));
   1478         break;
   1479     case MM_CAMERA_PARM_ZOOM:
   1480         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1481                                    V4L2_CID_ZOOM_ABSOLUTE,
   1482                                    *((int32_t *)p_value));
   1483         break;
   1484     case MM_CAMERA_PARM_LUMA_ADAPTATION:
   1485         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1486                                    MSM_V4L2_PID_LUMA_ADAPTATION,
   1487                                    *((int32_t *)p_value));
   1488         break;
   1489     case MM_CAMERA_PARM_ANTIBANDING:
   1490         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1491                                    V4L2_CID_POWER_LINE_FREQUENCY,
   1492                                    *((int32_t *)p_value));
   1493         break;
   1494     case MM_CAMERA_PARM_CONTINUOUS_AF:
   1495         rc = mm_camera_ctrl_set_auto_focus(my_obj,
   1496                                            *((int32_t *)p_value));
   1497         break;
   1498     case MM_CAMERA_PARM_HJR:
   1499         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
   1500                                    MSM_V4L2_PID_HJR,
   1501                                    *((int32_t *)p_value));
   1502         break;
   1503     case MM_CAMERA_PARM_EFFECT:
   1504         rc = mm_camera_ctrl_set_specialEffect (my_obj,
   1505                                                *((int32_t *)p_value));
   1506         break;
   1507     case MM_CAMERA_PARM_FPS:
   1508         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1509                                             CAMERA_SET_PARM_FPS,
   1510                                             sizeof(uint32_t),
   1511                                             p_value);
   1512         break;
   1513     case MM_CAMERA_PARM_FPS_MODE:
   1514         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1515                                             CAMERA_SET_FPS_MODE,
   1516                                             sizeof(int32_t),
   1517                                             p_value);
   1518         break;
   1519     case MM_CAMERA_PARM_EXPOSURE_COMPENSATION:
   1520         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1521                                             CAMERA_SET_PARM_EXPOSURE_COMPENSATION,
   1522                                             sizeof(int32_t),
   1523                                             p_value);
   1524         break;
   1525     case MM_CAMERA_PARM_LED_MODE:
   1526         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1527                                             CAMERA_SET_PARM_LED_MODE,
   1528                                             sizeof(int32_t),
   1529                                             p_value);
   1530         break;
   1531     case MM_CAMERA_PARM_ROLLOFF:
   1532         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1533                                             CAMERA_SET_PARM_ROLLOFF,
   1534                                             sizeof(int32_t),
   1535                                             p_value);
   1536         break;
   1537     case MM_CAMERA_PARM_MODE:
   1538         my_obj->current_mode = *((camera_mode_t *)p_value);
   1539         break;
   1540     case MM_CAMERA_PARM_FOCUS_RECT:
   1541         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1542                                             CAMERA_SET_PARM_FOCUS_RECT,
   1543                                             sizeof(int32_t),
   1544                                             p_value);
   1545         break;
   1546     case MM_CAMERA_PARM_AEC_ROI:
   1547         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1548                                             CAMERA_SET_PARM_AEC_ROI,
   1549                                             sizeof(cam_set_aec_roi_t),
   1550                                             p_value);
   1551         break;
   1552     case MM_CAMERA_PARM_AF_ROI:
   1553         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1554                                             CAMERA_SET_PARM_AF_ROI,
   1555                                             sizeof(roi_info_t),
   1556                                             p_value);
   1557         break;
   1558     case MM_CAMERA_PARM_FOCUS_MODE:
   1559         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1560                                             CAMERA_SET_PARM_AF_MODE,
   1561                                             sizeof(int32_t),
   1562                                             p_value);
   1563         break;
   1564 #if 0 /* to be enabled later: @punits */
   1565     case MM_CAMERA_PARM_AF_MTR_AREA:
   1566         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1567                                             CAMERA_SET_PARM_AF_MTR_AREA,
   1568                                             sizeof(af_mtr_area_t),
   1569                                             p_value);
   1570         break;
   1571     case MM_CAMERA_PARM_AEC_MTR_AREA:
   1572         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1573                                             CAMERA_SET_AEC_MTR_AREA,
   1574                                             sizeof(aec_mtr_area_t),
   1575                                             p_value);
   1576         break;
   1577 #endif
   1578     case MM_CAMERA_PARM_CAF_ENABLE:
   1579         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1580                                             CAMERA_SET_PARM_CAF,
   1581                                             sizeof(uint32_t),
   1582                                             p_value);
   1583         break;
   1584     case MM_CAMERA_PARM_BESTSHOT_MODE:
   1585         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1586                                             CAMERA_SET_PARM_BESTSHOT_MODE,
   1587                                             sizeof(int32_t),
   1588                                             p_value);
   1589         break;
   1590     case MM_CAMERA_PARM_VIDEO_DIS:
   1591         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1592                                             CAMERA_SET_VIDEO_DIS_PARAMS,
   1593                                             sizeof(video_dis_param_ctrl_t),
   1594                                             p_value);
   1595         break;
   1596     case MM_CAMERA_PARM_VIDEO_ROT:
   1597         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1598                                             CAMERA_SET_VIDEO_ROT_PARAMS,
   1599                                             sizeof(video_rotation_param_ctrl_t),
   1600                                             p_value);
   1601         break;
   1602     case MM_CAMERA_PARM_SCE_FACTOR:
   1603         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1604                                             CAMERA_SET_SCE_FACTOR,
   1605                                             sizeof(int32_t),
   1606                                             p_value);
   1607         break;
   1608     case MM_CAMERA_PARM_FD:
   1609         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1610                                             CAMERA_SET_PARM_FD,
   1611                                             sizeof(fd_set_parm_t),
   1612                                             p_value);
   1613         break;
   1614     case MM_CAMERA_PARM_AEC_LOCK:
   1615         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1616                                             CAMERA_SET_AEC_LOCK,
   1617                                             sizeof(int32_t),
   1618                                             p_value);
   1619         break;
   1620     case MM_CAMERA_PARM_AWB_LOCK:
   1621         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1622                                             CAMERA_SET_AWB_LOCK,
   1623                                             sizeof(int32_t),
   1624                                             p_value);
   1625         break;
   1626     case MM_CAMERA_PARM_MCE:
   1627         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1628                                             CAMERA_SET_PARM_MCE,
   1629                                             sizeof(int32_t),
   1630                                             p_value);
   1631         break;
   1632     case MM_CAMERA_PARM_HORIZONTAL_VIEW_ANGLE:
   1633         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1634                                             CAMERA_GET_PARM_HORIZONTAL_VIEW_ANGLE,
   1635                                             sizeof(focus_distances_info_t),
   1636                                             p_value);
   1637         break;
   1638     case MM_CAMERA_PARM_VERTICAL_VIEW_ANGLE:
   1639         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1640                                             CAMERA_GET_PARM_VERTICAL_VIEW_ANGLE,
   1641                                             sizeof(focus_distances_info_t),
   1642                                             p_value);
   1643         break;
   1644     case MM_CAMERA_PARM_RESET_LENS_TO_INFINITY:
   1645         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1646                                             CAMERA_SET_PARM_RESET_LENS_TO_INFINITY,
   1647                                             0, NULL);
   1648         break;
   1649     case MM_CAMERA_PARM_SNAPSHOTDATA:
   1650         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1651                                             CAMERA_GET_PARM_SNAPSHOTDATA,
   1652                                             sizeof(snapshotData_info_t),
   1653                                             p_value);
   1654         break;
   1655     case MM_CAMERA_PARM_HFR:
   1656         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1657                                             CAMERA_SET_PARM_HFR,
   1658                                             sizeof(int32_t),
   1659                                             p_value);
   1660         break;
   1661     case MM_CAMERA_PARM_REDEYE_REDUCTION:
   1662         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1663                                             CAMERA_SET_REDEYE_REDUCTION,
   1664                                             sizeof(int32_t),
   1665                                             p_value);
   1666         break;
   1667     case MM_CAMERA_PARM_WAVELET_DENOISE:
   1668         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1669                                             CAMERA_SET_PARM_WAVELET_DENOISE,
   1670                                             sizeof(denoise_param_t),
   1671                                             p_value);
   1672         break;
   1673     case MM_CAMERA_PARM_3D_DISPLAY_DISTANCE:
   1674         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1675                                             CAMERA_SET_PARM_3D_DISPLAY_DISTANCE,
   1676                                             sizeof(float),
   1677                                             p_value);
   1678         break;
   1679     case MM_CAMERA_PARM_3D_VIEW_ANGLE:
   1680         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1681                                             CAMERA_SET_PARM_3D_VIEW_ANGLE,
   1682                                             sizeof(uint32_t),
   1683                                             p_value);
   1684         break;
   1685     case MM_CAMERA_PARM_ZOOM_RATIO:
   1686         break;
   1687     case MM_CAMERA_PARM_HISTOGRAM:
   1688         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1689                                             CAMERA_SET_PARM_HISTOGRAM,
   1690                                             sizeof(int8_t),
   1691                                             p_value);
   1692         break;
   1693     case MM_CAMERA_PARM_ASD_ENABLE:
   1694         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1695                                           CAMERA_SET_ASD_ENABLE,
   1696                                           sizeof(uint32_t),
   1697                                           p_value);
   1698         break;
   1699     case MM_CAMERA_PARM_RECORDING_HINT:
   1700         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1701                                             CAMERA_SET_RECORDING_HINT,
   1702                                             sizeof(uint32_t),
   1703                                             p_value);
   1704         break;
   1705     case MM_CAMERA_PARM_PREVIEW_FORMAT:
   1706         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1707                                             CAMERA_SET_PARM_PREVIEW_FORMAT,
   1708                                             sizeof(uint32_t),
   1709                                             p_value);
   1710         break;
   1711     /* TODO: need code review to determine any of the three is redundent
   1712      * MM_CAMERA_PARM_DIS_ENABLE,
   1713      * MM_CAMERA_PARM_FULL_LIVESHOT,
   1714      * MM_CAMERA_PARM_LOW_POWER_MODE*/
   1715     case MM_CAMERA_PARM_DIS_ENABLE:
   1716         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1717                                             CAMERA_SET_DIS_ENABLE,
   1718                                             sizeof(uint32_t),
   1719                                             p_value);
   1720         break;
   1721     case MM_CAMERA_PARM_FULL_LIVESHOT:
   1722         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1723                                             CAMERA_SET_FULL_LIVESHOT,
   1724                                             sizeof(uint32_t),
   1725                                             p_value);
   1726         break;
   1727     case MM_CAMERA_PARM_LOW_POWER_MODE:
   1728         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1729                                             CAMERA_SET_LOW_POWER_MODE,
   1730                                             sizeof(uint32_t),
   1731                                             p_value);
   1732         break;
   1733     case MM_CAMERA_PARM_HDR:
   1734         rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1735                                             CAMERA_SET_PARM_HDR,
   1736                                             sizeof(exp_bracketing_t),
   1737                                             p_value);
   1738         break;
   1739     case MM_CAMERA_PARM_MOBICAT:
   1740 	    rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1741                                             CAMERA_ENABLE_MOBICAT,
   1742                                             sizeof(mm_cam_mobicat_info_t),
   1743                                             p_value);
   1744     default:
   1745         CDBG("%s: default: parm %d not supported\n", __func__, parm_type);
   1746         break;
   1747     }
   1748     return rc;
   1749 }
   1750 
   1751 int32_t mm_camera_util_private_s_ctrl(int32_t fd, uint32_t id, void* value)
   1752 {
   1753     int rc = -1;
   1754     struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
   1755 
   1756     memset(&v4l2_ioctl, 0, sizeof(v4l2_ioctl));
   1757     v4l2_ioctl.id = id;
   1758     v4l2_ioctl.ioctl_ptr = value;
   1759     rc = ioctl (fd, MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL, &v4l2_ioctl);
   1760 
   1761     if(rc < 0) {
   1762         CDBG_ERROR("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
   1763                    __func__, fd, id, (uint32_t)value, rc);
   1764         rc = -1;
   1765     } else {
   1766         rc = 0;
   1767     }
   1768     return rc;
   1769 }
   1770 
   1771 int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
   1772                                               cam_ctrl_type type,
   1773                                               uint32_t length,
   1774                                               void *value)
   1775 {
   1776     return mm_camera_send_native_ctrl_timeout_cmd(my_obj, type,
   1777                                                   length, value,
   1778                                                   1000);
   1779 }
   1780 
   1781 int32_t mm_camera_send_native_ctrl_timeout_cmd(mm_camera_obj_t * my_obj,
   1782                                                       cam_ctrl_type type,
   1783                                                       uint32_t length,
   1784                                                       void *value,
   1785                                                       int timeout)
   1786 {
   1787     int rc = -1;
   1788     struct msm_ctrl_cmd ctrl_cmd;
   1789 
   1790     memset(&ctrl_cmd, 0, sizeof(ctrl_cmd));
   1791     ctrl_cmd.type = type;
   1792     ctrl_cmd.length = (uint16_t)length;
   1793     ctrl_cmd.timeout_ms = timeout;
   1794     ctrl_cmd.value = value;
   1795     ctrl_cmd.status = (uint16_t)CAM_CTRL_SUCCESS;
   1796     rc = mm_camera_util_private_s_ctrl(my_obj->ctrl_fd,
   1797                                MSM_V4L2_PID_CTRL_CMD,
   1798                                (void*)&ctrl_cmd);
   1799     CDBG("%s: type=%d, rc = %d, status = %d\n",
   1800         __func__, type, rc, ctrl_cmd.status);
   1801     if(rc != 0 || ((ctrl_cmd.status != CAM_CTRL_ACCEPTED) &&
   1802         (ctrl_cmd.status != CAM_CTRL_SUCCESS) &&
   1803         (ctrl_cmd.status != CAM_CTRL_INVALID_PARM)))
   1804         rc = -1;
   1805     return rc;
   1806 }
   1807 
   1808 int mm_camera_evt_sub(mm_camera_obj_t * my_obj,
   1809                       mm_camera_event_type_t evt_type,
   1810                       int reg_count)
   1811 {
   1812     int rc = 0;
   1813     struct v4l2_event_subscription sub;
   1814 
   1815     memset(&sub, 0, sizeof(sub));
   1816     sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_EVENT;
   1817     if(reg_count == 0) {
   1818         /* unsubscribe */
   1819         if(my_obj->evt_type_mask == (uint32_t)(1 << evt_type)) {
   1820             rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
   1821             CDBG("%s: unsubscribe event 0x%x, rc = %d", __func__, sub.type, rc);
   1822             sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_ERROR_EVENT;
   1823             rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
   1824             CDBG("%s: unsubscribe event 0x%x, rc = %d", __func__, sub.type, rc);
   1825         }
   1826         my_obj->evt_type_mask &= ~(1 << evt_type);
   1827         if(my_obj->evt_type_mask == 0) {
   1828             /* remove evt fd from the polling thraed when unreg the last event */
   1829             mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread, my_obj->my_hdl);
   1830         }
   1831     } else {
   1832         if(!my_obj->evt_type_mask) {
   1833             /* this is the first reg event */
   1834             rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
   1835             CDBG("%s: subscribe event 0x%x, rc = %d", __func__, sub.type, rc);
   1836             if (rc < 0)
   1837                 goto end;
   1838             sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_ERROR_EVENT;
   1839             rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
   1840             CDBG("%s: subscribe event 0x%x, rc = %d", __func__, sub.type, rc);
   1841             if (rc < 0)
   1842                 goto end;
   1843         }
   1844         my_obj->evt_type_mask |= (1 << evt_type);
   1845         if(my_obj->evt_type_mask == (uint32_t)(1 << evt_type)) {
   1846             /* add evt fd to polling thread when subscribe the first event */
   1847             rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
   1848                                                    my_obj->my_hdl,
   1849                                                    my_obj->ctrl_fd,
   1850                                                    mm_camera_event_notify,
   1851                                                    (void*)my_obj);
   1852         }
   1853     }
   1854 end:
   1855     return rc;
   1856 }
   1857 
   1858 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj, void *msg, uint32_t buf_size, int sendfd)
   1859 {
   1860     return mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd);
   1861 }
   1862 
   1863 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
   1864                           int ext_mode,
   1865                           int idx,
   1866                           int fd,
   1867                           uint32_t size)
   1868 {
   1869     cam_sock_packet_t packet;
   1870     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1871     packet.msg_type = CAM_SOCK_MSG_TYPE_FD_MAPPING;
   1872     packet.payload.frame_fd_map.ext_mode = ext_mode;
   1873     packet.payload.frame_fd_map.frame_idx = idx;
   1874     packet.payload.frame_fd_map.fd = fd;
   1875     packet.payload.frame_fd_map.size = size;
   1876 
   1877     return mm_camera_util_sendmsg(my_obj, &packet,
   1878                                   sizeof(cam_sock_packet_t),
   1879                                   packet.payload.frame_fd_map.fd);
   1880 }
   1881 
   1882 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
   1883                             int ext_mode,
   1884                             int idx)
   1885 {
   1886     cam_sock_packet_t packet;
   1887     memset(&packet, 0, sizeof(cam_sock_packet_t));
   1888     packet.msg_type = CAM_SOCK_MSG_TYPE_FD_UNMAPPING;
   1889     packet.payload.frame_fd_unmap.ext_mode = ext_mode;
   1890     packet.payload.frame_fd_unmap.frame_idx = idx;
   1891     return mm_camera_util_sendmsg(my_obj, &packet,
   1892                                   sizeof(cam_sock_packet_t),
   1893                                   packet.payload.frame_fd_map.fd);
   1894 }
   1895 
   1896 int32_t mm_camera_util_s_ctrl(int32_t fd,  uint32_t id, int32_t value)
   1897 {
   1898     int rc = 0;
   1899     struct v4l2_control control;
   1900 
   1901     memset(&control, 0, sizeof(control));
   1902     control.id = id;
   1903     control.value = value;
   1904     rc = ioctl (fd, VIDIOC_S_CTRL, &control);
   1905 
   1906     CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
   1907          __func__, fd, id, (uint32_t)value, rc);
   1908     return (rc >= 0)? 0 : -1;
   1909 }
   1910 
   1911 int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
   1912 {
   1913     int rc = 0;
   1914     struct v4l2_control control;
   1915 
   1916     memset(&control, 0, sizeof(control));
   1917     control.id = id;
   1918     control.value = (int32_t)value;
   1919     rc = ioctl (fd, VIDIOC_G_CTRL, &control);
   1920     *value = control.value;
   1921     CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc);
   1922     return (rc >= 0)? 0 : -1;
   1923 }
   1924 
   1925 uint8_t mm_camera_util_get_pp_mask(mm_camera_obj_t *my_obj)
   1926 {
   1927     uint8_t pp_mask = 0;
   1928     int32_t rc = 0;
   1929 
   1930     /* query pp mask from mctl */
   1931     rc = mm_camera_send_native_ctrl_cmd(my_obj,
   1932                                         CAMERA_GET_PP_MASK,
   1933                                         sizeof(uint8_t),
   1934                                         (void *)&pp_mask);
   1935     if (0 != rc) {
   1936         CDBG_ERROR("%s: error getting post processing mask (rc=%d)",
   1937                    __func__, rc);
   1938     }
   1939 
   1940     return pp_mask;
   1941 }
   1942 
   1943 int32_t mm_camera_open_repro_isp(mm_camera_obj_t *my_obj,
   1944                                  uint32_t ch_id,
   1945                                  mm_camera_repro_isp_type_t repro_isp_type,
   1946                                  uint32_t *repro_isp_handle)
   1947 {
   1948     int32_t rc = -1;
   1949     uint32_t repro_hdl = 0;
   1950     mm_channel_t * ch_obj =
   1951         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1952 
   1953     if (NULL != ch_obj) {
   1954         pthread_mutex_lock(&ch_obj->ch_lock);
   1955         pthread_mutex_unlock(&my_obj->cam_lock);
   1956 
   1957         rc = mm_channel_fsm_fn(ch_obj,
   1958                                MM_CHANNEL_EVT_OPEN_REPRO_ISP,
   1959                                (void*)repro_isp_type,
   1960                                (void*)&repro_hdl);
   1961     } else {
   1962         pthread_mutex_unlock(&my_obj->cam_lock);
   1963         CDBG_ERROR("%s: no channel obj exist", __func__);
   1964     }
   1965 
   1966     if (NULL != repro_isp_handle) {
   1967         *repro_isp_handle = repro_hdl;
   1968     }
   1969     return rc;
   1970 }
   1971 
   1972 int32_t mm_camera_config_repro_isp(mm_camera_obj_t *my_obj,
   1973                                    uint32_t ch_id,
   1974                                    uint32_t repro_isp_handle,
   1975                                    mm_camera_repro_isp_config_t *config)
   1976 {
   1977     int32_t rc = -1;
   1978     mm_channel_t * ch_obj =
   1979         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   1980     mm_evt_paylod_config_repro_isp_t payload;
   1981 
   1982     if (NULL != ch_obj) {
   1983         pthread_mutex_lock(&ch_obj->ch_lock);
   1984         pthread_mutex_unlock(&my_obj->cam_lock);
   1985 
   1986         memset(&payload, 0, sizeof(mm_evt_paylod_config_repro_isp_t));
   1987         payload.repro_isp_handle = repro_isp_handle;
   1988         payload.config = config;
   1989         rc = mm_channel_fsm_fn(ch_obj,
   1990                                MM_CHANNEL_EVT_CONFIG_REPRO_ISP,
   1991                                (void*)&payload,
   1992                                NULL);
   1993     } else {
   1994         pthread_mutex_unlock(&my_obj->cam_lock);
   1995         CDBG_ERROR("%s: no channel obj exist", __func__);
   1996     }
   1997 
   1998     return rc;
   1999 }
   2000 
   2001 int32_t mm_camera_attach_stream_to_repro_isp(mm_camera_obj_t *my_obj,
   2002                                              uint32_t ch_id,
   2003                                              uint32_t repro_isp_handle,
   2004                                              uint32_t stream_id)
   2005 {
   2006     int32_t rc = -1;
   2007     mm_channel_t * ch_obj =
   2008         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   2009     mm_evt_paylod_stream_to_repro_isp_t payload;
   2010 
   2011     if (NULL != ch_obj) {
   2012         pthread_mutex_lock(&ch_obj->ch_lock);
   2013         pthread_mutex_unlock(&my_obj->cam_lock);
   2014 
   2015         memset(&payload, 0, sizeof(mm_evt_paylod_stream_to_repro_isp_t));
   2016         payload.repro_isp_handle = repro_isp_handle;
   2017         payload.stream_id = stream_id;
   2018         rc = mm_channel_fsm_fn(ch_obj,
   2019                                MM_CHANNEL_EVT_ATTACH_STREAM_TO_REPRO_ISP,
   2020                                (void*)&payload,
   2021                                NULL);
   2022     } else {
   2023         pthread_mutex_unlock(&my_obj->cam_lock);
   2024         CDBG_ERROR("%s: no channel obj exist", __func__);
   2025     }
   2026 
   2027     return rc;
   2028 }
   2029 
   2030 int32_t mm_camera_start_repro_isp(mm_camera_obj_t *my_obj,
   2031                                   uint32_t ch_id,
   2032                                   uint32_t repro_isp_handle,
   2033                                   uint32_t stream_id)
   2034 {
   2035     int32_t rc = -1;
   2036     mm_evt_paylod_repro_start_stop_t payload;
   2037     mm_channel_t * ch_obj =
   2038         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   2039 
   2040     if (NULL != ch_obj) {
   2041         pthread_mutex_lock(&ch_obj->ch_lock);
   2042         pthread_mutex_unlock(&my_obj->cam_lock);
   2043 
   2044         memset(&payload, 0, sizeof(mm_evt_paylod_repro_start_stop_t));
   2045         payload.repro_isp_handle = repro_isp_handle;
   2046         payload.stream_id = stream_id;
   2047         rc = mm_channel_fsm_fn(ch_obj,
   2048                                MM_CHANNEL_EVT_START_REPRO_ISP,
   2049                                (void*)&payload,
   2050                                NULL);
   2051     } else {
   2052         pthread_mutex_unlock(&my_obj->cam_lock);
   2053         CDBG_ERROR("%s: no channel obj exist", __func__);
   2054     }
   2055 
   2056     return rc;
   2057 }
   2058 
   2059 int32_t mm_camera_reprocess(mm_camera_obj_t *my_obj,
   2060                             uint32_t ch_id,
   2061                             uint32_t repro_isp_handle,
   2062                             mm_camera_repro_data_t *repro_data)
   2063 {
   2064     int32_t rc = -1;
   2065     mm_channel_t * ch_obj =
   2066         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   2067     mm_evt_paylod_reprocess_t payload;
   2068 
   2069     if (NULL != ch_obj) {
   2070         pthread_mutex_lock(&ch_obj->ch_lock);
   2071         pthread_mutex_unlock(&my_obj->cam_lock);
   2072 
   2073         memset(&payload, 0, sizeof(mm_evt_paylod_reprocess_t));
   2074         payload.repro_isp_handle = repro_isp_handle;
   2075         payload.repro_data = repro_data;
   2076         rc = mm_channel_fsm_fn(ch_obj,
   2077                                MM_CHANNEL_EVT_ATTACH_STREAM_TO_REPRO_ISP,
   2078                                (void*)&payload,
   2079                                NULL);
   2080     } else {
   2081         pthread_mutex_unlock(&my_obj->cam_lock);
   2082         CDBG_ERROR("%s: no channel obj exist", __func__);
   2083     }
   2084 
   2085     return rc;
   2086 }
   2087 
   2088 int32_t mm_camera_stop_repro_isp(mm_camera_obj_t *my_obj,
   2089                                  uint32_t ch_id,
   2090                                  uint32_t repro_isp_handle,
   2091                                  uint32_t stream_id)
   2092 {
   2093     int32_t rc = -1;
   2094     mm_evt_paylod_repro_start_stop_t payload;
   2095     mm_channel_t * ch_obj =
   2096         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   2097 
   2098     if (NULL != ch_obj) {
   2099         pthread_mutex_lock(&ch_obj->ch_lock);
   2100         pthread_mutex_unlock(&my_obj->cam_lock);
   2101 
   2102         memset(&payload, 0, sizeof(mm_evt_paylod_repro_start_stop_t));
   2103         payload.repro_isp_handle = repro_isp_handle;
   2104         payload.stream_id = stream_id;
   2105         rc = mm_channel_fsm_fn(ch_obj,
   2106                                MM_CHANNEL_EVT_STOP_REPRO_ISP,
   2107                                (void*)&payload,
   2108                                NULL);
   2109     } else {
   2110         pthread_mutex_unlock(&my_obj->cam_lock);
   2111         CDBG_ERROR("%s: no channel obj exist", __func__);
   2112     }
   2113 
   2114     return rc;
   2115 }
   2116 
   2117 int32_t mm_camera_detach_stream_from_repro_isp(mm_camera_obj_t *my_obj,
   2118                                                uint32_t ch_id,
   2119                                                uint32_t repro_isp_handle,
   2120                                                uint32_t stream_id)
   2121 {
   2122     int32_t rc = -1;
   2123     mm_channel_t * ch_obj =
   2124         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   2125     mm_evt_paylod_stream_to_repro_isp_t payload;
   2126 
   2127     if (NULL != ch_obj) {
   2128         pthread_mutex_lock(&ch_obj->ch_lock);
   2129         pthread_mutex_unlock(&my_obj->cam_lock);
   2130 
   2131         memset(&payload, 0, sizeof(mm_evt_paylod_stream_to_repro_isp_t));
   2132         payload.repro_isp_handle = repro_isp_handle;
   2133         payload.stream_id = stream_id;
   2134         rc = mm_channel_fsm_fn(ch_obj,
   2135                                MM_CHANNEL_EVT_DETACH_STREAM_FROM_REPRO_ISP,
   2136                                (void*)&payload,
   2137                                NULL);
   2138     } else {
   2139         pthread_mutex_unlock(&my_obj->cam_lock);
   2140         CDBG_ERROR("%s: no channel obj exist", __func__);
   2141     }
   2142 
   2143     return rc;
   2144 }
   2145 
   2146 int32_t mm_camera_close_repro_isp(mm_camera_obj_t *my_obj,
   2147                                   uint32_t ch_id,
   2148                                   uint32_t repro_isp_handle)
   2149 {
   2150     int32_t rc = -1;
   2151     mm_channel_t * ch_obj =
   2152         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
   2153 
   2154     if (NULL != ch_obj) {
   2155         pthread_mutex_lock(&ch_obj->ch_lock);
   2156         pthread_mutex_unlock(&my_obj->cam_lock);
   2157 
   2158         rc = mm_channel_fsm_fn(ch_obj,
   2159                                MM_CHANNEL_EVT_CLOSE_REPRO_ISP,
   2160                                (void*)repro_isp_handle,
   2161                                NULL);
   2162     } else {
   2163         pthread_mutex_unlock(&my_obj->cam_lock);
   2164         CDBG_ERROR("%s: no channel obj exist", __func__);
   2165     }
   2166 
   2167     return rc;
   2168 }
   2169