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