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