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