mm_camera.c revision d2288970ead06a397966b05878c05026ed150af3
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                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_parm_supported(mm_camera_obj_t *my_obj,
521                                   mm_camera_parm_type_t parm_type,
522                                   uint8_t *support_set_parm,
523                                   uint8_t *support_get_parm)
524{
525    /* TODO: need to sync with backend if it can support set/get */
526    int32_t rc = 0;
527    *support_set_parm = GET_PARM_BIT32(parm_type,
528                                       my_obj->properties.parm);
529    *support_get_parm = GET_PARM_BIT32(parm_type,
530                                       my_obj->properties.parm);
531    pthread_mutex_unlock(&my_obj->cam_lock);
532
533    return rc;
534}
535
536int32_t mm_camera_util_set_op_mode(mm_camera_obj_t * my_obj,
537                                   mm_camera_op_mode_type_t *op_mode)
538{
539    int32_t rc = 0;
540    int32_t v4l2_op_mode = MSM_V4L2_CAM_OP_DEFAULT;
541
542    if (my_obj->op_mode == *op_mode)
543        goto end;
544    switch(*op_mode) {
545    case MM_CAMERA_OP_MODE_ZSL:
546        v4l2_op_mode = MSM_V4L2_CAM_OP_ZSL;
547            break;
548    case MM_CAMERA_OP_MODE_CAPTURE:
549        v4l2_op_mode = MSM_V4L2_CAM_OP_CAPTURE;
550            break;
551    case MM_CAMERA_OP_MODE_VIDEO:
552        v4l2_op_mode = MSM_V4L2_CAM_OP_VIDEO;
553            break;
554    default:
555        rc = - 1;
556        goto end;
557        break;
558    }
559    if(0 != (rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd,
560            MSM_V4L2_PID_CAM_MODE, v4l2_op_mode))){
561        CDBG_ERROR("%s: input op_mode=%d, s_ctrl rc=%d\n", __func__, *op_mode, rc);
562        goto end;
563    }
564    /* if success update mode field */
565    my_obj->op_mode = *op_mode;
566end:
567    CDBG("%s: op_mode=%d,rc=%d\n", __func__, *op_mode, rc);
568    return rc;
569}
570
571int32_t mm_camera_set_parm(mm_camera_obj_t *my_obj,
572                           mm_camera_parm_type_t parm_type,
573                           void* p_value)
574{
575    int32_t rc = 0;
576    CDBG("%s type =%d", __func__, parm_type);
577    switch(parm_type) {
578    case MM_CAMERA_PARM_OP_MODE:
579        rc = mm_camera_util_set_op_mode(my_obj,
580                        (mm_camera_op_mode_type_t *)p_value);
581        break;
582    case MM_CAMERA_PARM_DIMENSION:
583        rc = mm_camera_send_native_ctrl_cmd(my_obj,
584                    CAMERA_SET_PARM_DIMENSION, sizeof(cam_ctrl_dimension_t), p_value);
585        if(rc != 0) {
586            CDBG("%s: mm_camera_send_native_ctrl_cmd err=%d\n", __func__, rc);
587            break;
588        }
589        memcpy(&my_obj->dim, (cam_ctrl_dimension_t *)p_value,
590                     sizeof(cam_ctrl_dimension_t));
591        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",
592                 __func__,
593                 my_obj->dim.display_width,my_obj->dim.display_height,
594                 my_obj->dim.video_width, my_obj->dim.video_height,
595                 my_obj->dim.picture_width,my_obj->dim.picture_height,
596                 my_obj->dim.ui_thumbnail_width,my_obj->dim.ui_thumbnail_height,
597                 my_obj->dim.raw_picture_width,my_obj->dim.raw_picture_height);
598        break;
599    case MM_CAMERA_PARM_SNAPSHOT_BURST_NUM:
600        my_obj->snap_burst_num_by_user = *((uint32_t *)p_value);
601        break;
602    default:
603        rc = mm_camera_set_general_parm(my_obj, parm_type, p_value);
604        break;
605    }
606    pthread_mutex_unlock(&my_obj->cam_lock);
607    return rc;
608}
609
610int32_t mm_camera_get_parm(mm_camera_obj_t *my_obj,
611                           mm_camera_parm_type_t parm_type,
612                           void* p_value)
613{
614    int32_t rc = 0;
615
616    switch(parm_type) {
617    case MM_CAMERA_PARM_MAX_PICTURE_SIZE:
618        {
619            mm_camera_dimension_t *dim =
620                (mm_camera_dimension_t *)p_value;
621            dim->height = my_obj->properties.max_pict_height;
622            dim->width = my_obj->properties.max_pict_width;
623            CDBG("%s: Max Picture Size: %d X %d\n", __func__,
624                 dim->width, dim->height);
625        }
626        break;
627    case MM_CAMERA_PARM_PREVIEW_FORMAT:
628        *((int *)p_value) = my_obj->properties.preview_format;
629        break;
630    case MM_CAMERA_PARM_PREVIEW_SIZES_CNT:
631        *((int *)p_value) = my_obj->properties.preview_sizes_cnt;
632        break;
633    case MM_CAMERA_PARM_VIDEO_SIZES_CNT:
634        *((int *)p_value) = my_obj->properties.video_sizes_cnt;
635        break;
636    case MM_CAMERA_PARM_THUMB_SIZES_CNT:
637        *((int *)p_value) = my_obj->properties.thumb_sizes_cnt;
638        break;
639    case MM_CAMERA_PARM_HFR_SIZES_CNT:
640        *((int *)p_value) = my_obj->properties.hfr_sizes_cnt;
641        break;
642    case MM_CAMERA_PARM_HFR_FRAME_SKIP:
643        *((int *)p_value) = my_obj->properties.hfr_frame_skip;
644        break;
645    case MM_CAMERA_PARM_DEFAULT_PREVIEW_WIDTH:
646        *((int *)p_value) = my_obj->properties.default_preview_width;
647        break;
648    case MM_CAMERA_PARM_DEFAULT_PREVIEW_HEIGHT:
649        *((int *)p_value) = my_obj->properties.default_preview_height;
650        break;
651    case MM_CAMERA_PARM_MAX_PREVIEW_SIZE:
652        {
653            mm_camera_dimension_t *dim =
654                (mm_camera_dimension_t *)p_value;
655            dim->height = my_obj->properties.max_preview_height;
656            dim->width = my_obj->properties.max_preview_width;
657            CDBG("%s: Max Preview Size: %d X %d\n", __func__,
658                 dim->width, dim->height);
659        }
660        break;
661    case MM_CAMERA_PARM_MAX_VIDEO_SIZE:
662        {
663            mm_camera_dimension_t *dim =
664                (mm_camera_dimension_t *)p_value;
665            dim->height = my_obj->properties.max_video_height;
666            dim->width = my_obj->properties.max_video_width;
667            CDBG("%s: Max Video Size: %d X %d\n", __func__,
668                 dim->width, dim->height);
669        }
670        break;
671    case MM_CAMERA_PARM_MAX_HFR_MODE:
672        rc = mm_camera_send_native_ctrl_cmd(my_obj,
673                                            CAMERA_GET_PARM_MAX_HFR_MODE,
674                                            sizeof(camera_hfr_mode_t),
675                                            p_value);
676        break;
677    case MM_CAMERA_PARM_FOCAL_LENGTH:
678        rc = mm_camera_send_native_ctrl_cmd(my_obj,
679                                            CAMERA_GET_PARM_FOCAL_LENGTH,
680                                            sizeof(float),
681                                            p_value);
682        break;
683    case MM_CAMERA_PARM_HORIZONTAL_VIEW_ANGLE:
684        rc = mm_camera_send_native_ctrl_cmd(my_obj,
685                                            CAMERA_GET_PARM_HORIZONTAL_VIEW_ANGLE,
686                                            sizeof(float),
687                                            p_value);
688        break;
689    case MM_CAMERA_PARM_VERTICAL_VIEW_ANGLE:
690        rc = mm_camera_send_native_ctrl_cmd(my_obj,
691                                            CAMERA_GET_PARM_VERTICAL_VIEW_ANGLE,
692                                            sizeof(float),
693                                            p_value);
694        break;
695    case MM_CAMERA_PARM_FOCUS_DISTANCES:
696        rc = mm_camera_send_native_ctrl_cmd(my_obj,
697                                            CAMERA_GET_PARM_FOCUS_DISTANCES,
698                                            sizeof(focus_distances_info_t),
699                                            p_value);
700        break;
701    case MM_CAMERA_PARM_QUERY_FALSH4SNAP:
702        rc = mm_camera_send_native_ctrl_cmd(my_obj,
703                                            CAMERA_QUERY_FLASH_FOR_SNAPSHOT,
704                                            sizeof(int),
705                                            p_value);
706        break;
707    case MM_CAMERA_PARM_3D_FRAME_FORMAT:
708        rc = mm_camera_send_native_ctrl_cmd(my_obj,
709                                            CAMERA_GET_PARM_3D_FRAME_FORMAT,
710                                            sizeof(camera_3d_frame_t),
711                                            p_value);
712        break;
713    case MM_CAMERA_PARM_MAXZOOM:
714        rc = mm_camera_send_native_ctrl_cmd(my_obj,
715                                            CAMERA_GET_PARM_MAXZOOM,
716                                            sizeof(int),
717                                            p_value);
718        break;
719    case MM_CAMERA_PARM_ZOOM_RATIO:
720        {
721            mm_camera_zoom_tbl_t *tbl = (mm_camera_zoom_tbl_t *)p_value;
722            rc = mm_camera_send_native_ctrl_cmd(my_obj,
723                                                CAMERA_GET_PARM_ZOOMRATIOS,
724                                                sizeof(int16_t)*tbl->size,
725                                                (void *)(tbl->zoom_ratio_tbl));
726        }
727        break;
728    case MM_CAMERA_PARM_DEF_PREVIEW_SIZES:
729        {
730            default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
731            rc = mm_camera_send_native_ctrl_cmd(my_obj,
732                                                CAMERA_GET_PARM_DEF_PREVIEW_SIZES,
733                                                sizeof(struct camera_size_type)*tbl->tbl_size,
734                                                (void* )(tbl->sizes_tbl));
735        }
736        break;
737    case MM_CAMERA_PARM_DEF_VIDEO_SIZES:
738        {
739            default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
740            rc = mm_camera_send_native_ctrl_cmd(my_obj,
741                                                CAMERA_GET_PARM_DEF_VIDEO_SIZES,
742                                                sizeof(struct camera_size_type)*tbl->tbl_size,
743                                                (void *)(tbl->sizes_tbl));
744        }
745        break;
746    case MM_CAMERA_PARM_DEF_THUMB_SIZES:
747        {
748            default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
749            rc = mm_camera_send_native_ctrl_cmd(my_obj,
750                                                CAMERA_GET_PARM_DEF_THUMB_SIZES,
751                                                sizeof(struct camera_size_type)*tbl->tbl_size,
752                                                (void *)(tbl->sizes_tbl));
753        }
754        break;
755    case MM_CAMERA_PARM_DEF_HFR_SIZES:
756        {
757            default_sizes_tbl_t *tbl = (default_sizes_tbl_t*)p_value;
758            rc = mm_camera_send_native_ctrl_cmd(my_obj,
759                                                CAMERA_GET_PARM_DEF_HFR_SIZES,
760                                                sizeof(struct camera_size_type)*tbl->tbl_size,
761                                                (void *)(tbl->sizes_tbl));
762        }
763        break;
764    case MM_CAMERA_PARM_SNAPSHOT_BURST_NUM:
765        *((int *)p_value) = my_obj->snap_burst_num_by_user;
766        break;
767    case MM_CAMERA_PARM_VFE_OUTPUT_ENABLE:
768        *((int *)p_value) = my_obj->properties.vfe_output_enable;
769        break;
770    case MM_CAMERA_PARM_DIMENSION:
771        memcpy(p_value, &my_obj->dim, sizeof(my_obj->dim));
772        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",
773                 __func__,
774                 my_obj->dim.display_width,my_obj->dim.display_height,
775                 my_obj->dim.video_width,my_obj->dim.video_height,
776                 my_obj->dim.picture_width,my_obj->dim.picture_height,
777                 my_obj->dim.ui_thumbnail_width,my_obj->dim.ui_thumbnail_height,
778                 my_obj->dim.orig_video_width,my_obj->dim.orig_video_height,
779                 my_obj->dim.orig_picture_width,my_obj->dim.orig_picture_height,
780                 my_obj->dim.main_img_format, my_obj->dim.thumb_format);
781        break;
782    case MM_CAMERA_PARM_OP_MODE:
783        *((mm_camera_op_mode_type_t *)p_value) = my_obj->op_mode;
784        break;
785    case MM_CAMERA_PARM_MAX_NUM_FACES_DECT:
786        rc = mm_camera_send_native_ctrl_cmd(my_obj,
787                                            CAMERA_GET_MAX_NUM_FACES_DECT,
788                                            sizeof(int),
789                                            p_value);
790        break;
791    default:
792        /* needs to add more implementation */
793        rc = -1;
794        break;
795    }
796
797    pthread_mutex_unlock(&my_obj->cam_lock);
798    return rc;
799}
800
801uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj)
802{
803    mm_channel_t *ch_obj = NULL;
804    uint8_t ch_idx = 0;
805    uint32_t ch_hdl = 0;
806
807    for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
808        if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
809            ch_obj = &my_obj->ch[ch_idx];
810            break;
811        }
812    }
813
814    if (NULL != ch_obj) {
815        /* initialize channel obj */
816        memset(ch_obj, 0, sizeof(mm_channel_t));
817        ch_hdl = mm_camera_util_generate_handler(ch_idx);
818        ch_obj->my_hdl = ch_hdl;
819        ch_obj->state = MM_CHANNEL_STATE_STOPPED;
820        ch_obj->cam_obj = my_obj;
821        pthread_mutex_init(&ch_obj->ch_lock, NULL);
822    }
823
824    mm_channel_init(ch_obj);
825    pthread_mutex_unlock(&my_obj->cam_lock);
826
827    return ch_hdl;
828}
829
830void mm_camera_del_channel(mm_camera_obj_t *my_obj,
831                           uint32_t ch_id)
832{
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        mm_channel_fsm_fn(ch_obj,
841                               MM_CHANNEL_EVT_DELETE,
842                               NULL,
843                               NULL);
844
845        pthread_mutex_destroy(&ch_obj->ch_lock);
846        memset(ch_obj, 0, sizeof(mm_channel_t));
847    } else {
848        pthread_mutex_unlock(&my_obj->cam_lock);
849    }
850}
851
852uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
853                              uint32_t ch_id,
854                              mm_camera_buf_notify_t buf_cb, void *user_data,
855                              uint32_t ext_image_mode, uint32_t sensor_idx)
856{
857    uint32_t s_hdl = 0;
858    mm_channel_t * ch_obj =
859        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
860    mm_evt_paylod_add_stream_t payload;
861
862    if (NULL != ch_obj) {
863        pthread_mutex_lock(&ch_obj->ch_lock);
864        pthread_mutex_unlock(&my_obj->cam_lock);
865
866        memset(&payload, 0, sizeof(mm_evt_paylod_add_stream_t));
867        payload.buf_cb = buf_cb;
868        payload.user_data = user_data;
869        payload.ext_image_mode = ext_image_mode;
870        payload.sensor_idx = sensor_idx;
871        mm_channel_fsm_fn(ch_obj,
872                               MM_CHANNEL_EVT_ADD_STREAM,
873                               (void*)&payload,
874                               (void*)&s_hdl);
875    } else {
876        pthread_mutex_unlock(&my_obj->cam_lock);
877    }
878
879    return s_hdl;
880}
881
882int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
883                             uint32_t ch_id,
884                             uint32_t stream_id)
885{
886    int32_t rc = -1;
887    mm_channel_t * ch_obj =
888        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
889
890    if (NULL != ch_obj) {
891        pthread_mutex_lock(&ch_obj->ch_lock);
892        pthread_mutex_unlock(&my_obj->cam_lock);
893
894        rc = mm_channel_fsm_fn(ch_obj,
895                               MM_CHANNEL_EVT_DEL_STREAM,
896                               (void*)&stream_id,
897                               NULL);
898    } else {
899        pthread_mutex_unlock(&my_obj->cam_lock);
900    }
901
902    return rc;
903}
904
905int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
906                                uint32_t ch_id,
907                                uint32_t stream_id,
908                                mm_camera_stream_config_t *config)
909{
910    int32_t rc = -1;
911    mm_channel_t * ch_obj =
912        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
913    mm_evt_paylod_config_stream_t payload;
914
915    if (NULL != ch_obj) {
916        pthread_mutex_lock(&ch_obj->ch_lock);
917        pthread_mutex_unlock(&my_obj->cam_lock);
918
919        memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
920        payload.stream_id = stream_id;
921        payload.config = config;
922        rc = mm_channel_fsm_fn(ch_obj,
923                               MM_CHANNEL_EVT_CONFIG_STREAM,
924                               (void*)&payload,
925                               NULL);
926    } else {
927        pthread_mutex_unlock(&my_obj->cam_lock);
928    }
929
930    return rc;
931}
932
933int32_t mm_camera_bundle_streams(mm_camera_obj_t *my_obj,
934                                 uint32_t ch_id,
935                                 mm_camera_buf_notify_t super_frame_notify_cb,
936                                 void *user_data,
937                                 mm_camera_bundle_attr_t *attr,
938                                 uint8_t num_streams,
939                                 uint32_t *stream_ids)
940{
941    int32_t rc = -1;
942    mm_channel_t * ch_obj =
943        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
944    mm_evt_payload_bundle_stream_t payload;
945
946    if (NULL != ch_obj) {
947        pthread_mutex_lock(&ch_obj->ch_lock);
948        pthread_mutex_unlock(&my_obj->cam_lock);
949
950        memset(&payload, 0, sizeof(mm_evt_payload_bundle_stream_t));
951        payload.super_frame_notify_cb = super_frame_notify_cb;
952        payload.user_data = user_data;
953        payload.attr = attr;
954        payload.num_streams = num_streams;
955        payload.stream_ids = stream_ids;
956        rc = mm_channel_fsm_fn(ch_obj,
957                               MM_CHANNEL_EVT_INIT_BUNDLE,
958                               (void*)&payload,
959                               NULL);
960    } else {
961        pthread_mutex_unlock(&my_obj->cam_lock);
962    }
963
964    return rc;
965}
966
967int32_t mm_camera_destroy_bundle(mm_camera_obj_t *my_obj, uint32_t ch_id)
968{
969    int32_t rc = -1;
970    mm_channel_t * ch_obj =
971        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
972
973    if (NULL != ch_obj) {
974        pthread_mutex_lock(&ch_obj->ch_lock);
975        pthread_mutex_unlock(&my_obj->cam_lock);
976
977        rc = mm_channel_fsm_fn(ch_obj,
978                               MM_CHANNEL_EVT_DESTROY_BUNDLE,
979                               NULL,
980                               NULL);
981    } else {
982        pthread_mutex_unlock(&my_obj->cam_lock);
983    }
984
985    return rc;
986}
987
988int32_t mm_camera_start_streams(mm_camera_obj_t *my_obj,
989                                uint32_t ch_id,
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_start_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_start_stream_t));
1003        payload.num_streams = num_streams;
1004        payload.stream_ids = stream_ids;
1005        rc = mm_channel_fsm_fn(ch_obj,
1006                               MM_CHANNEL_EVT_START_STREAM,
1007                               (void*)&payload,
1008                               NULL);
1009    } else {
1010        pthread_mutex_unlock(&my_obj->cam_lock);
1011    }
1012
1013    return rc;
1014}
1015
1016int32_t mm_camera_stop_streams(mm_camera_obj_t *my_obj,
1017                               uint32_t ch_id,
1018                               uint8_t num_streams,
1019                               uint32_t *stream_ids)
1020{
1021    int32_t rc = 0;
1022    mm_evt_payload_stop_stream_t payload;
1023    mm_camera_cmdcb_t * node = NULL;
1024
1025    mm_channel_t * ch_obj =
1026        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1027
1028    if (NULL != ch_obj) {
1029        pthread_mutex_lock(&ch_obj->ch_lock);
1030        pthread_mutex_unlock(&my_obj->cam_lock);
1031
1032        memset(&payload, 0, sizeof(mm_evt_payload_stop_stream_t));
1033        payload.num_streams = num_streams;
1034        payload.stream_ids = stream_ids;
1035
1036        rc = mm_channel_fsm_fn(ch_obj,
1037                               MM_CHANNEL_EVT_STOP_STREAM,
1038                               (void*)&payload,
1039                               NULL);
1040    } else {
1041        pthread_mutex_unlock(&my_obj->cam_lock);
1042    }
1043    return rc;
1044}
1045
1046int32_t mm_camera_async_teardown_streams(mm_camera_obj_t *my_obj,
1047                                          uint32_t ch_id,
1048                                          uint8_t num_streams,
1049                                          uint32_t *stream_ids)
1050{
1051    int32_t rc = 0;
1052    mm_evt_payload_stop_stream_t payload;
1053    mm_camera_cmdcb_t * node = NULL;
1054
1055    mm_channel_t * ch_obj =
1056        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1057
1058    if (NULL != ch_obj) {
1059        pthread_mutex_lock(&ch_obj->ch_lock);
1060        pthread_mutex_unlock(&my_obj->cam_lock);
1061
1062        /* enqueu asyn stop cmd to async_cmd_thread */
1063        node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
1064        if (NULL != node) {
1065            memset(node, 0, sizeof(mm_camera_cmdcb_t));
1066            node->cmd_type = MM_CAMERA_CMD_TYPE_ASYNC_CB;
1067            node->u.async.cmd_type = MM_CAMERA_ASYNC_CMD_TYPE_STOP;
1068            node->u.async.u.stop_cmd.ch_obj = ch_obj;
1069            node->u.async.u.stop_cmd.num_streams = num_streams;
1070            memcpy(node->u.async.u.stop_cmd.stream_ids, stream_ids, sizeof(uint32_t)*num_streams);
1071
1072            /* enqueue to async cmd thread */
1073            mm_camera_queue_enq(&(my_obj->async_cmd_thread.cmd_queue), node);
1074            /* wake up async cmd thread */
1075            sem_post(&(my_obj->async_cmd_thread.cmd_sem));
1076        } else {
1077            CDBG_ERROR("%s: No memory for mm_camera_cmdcb_t", __func__);
1078            pthread_mutex_unlock(&ch_obj->ch_lock);
1079            rc = -1;
1080            return rc;
1081        }
1082    } else {
1083        pthread_mutex_unlock(&my_obj->cam_lock);
1084    }
1085    return rc;
1086}
1087
1088int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1089                                    uint32_t ch_id,
1090                                    uint32_t num_buf_requested)
1091{
1092    int32_t rc = -1;
1093    mm_channel_t * ch_obj =
1094        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1095
1096    if (NULL != ch_obj) {
1097        pthread_mutex_lock(&ch_obj->ch_lock);
1098        pthread_mutex_unlock(&my_obj->cam_lock);
1099
1100        rc = mm_channel_fsm_fn(ch_obj,
1101                               MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
1102                               (void*)num_buf_requested,
1103                               NULL);
1104    } else {
1105        pthread_mutex_unlock(&my_obj->cam_lock);
1106    }
1107
1108    return rc;
1109}
1110
1111int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
1112{
1113    int32_t rc = -1;
1114    mm_channel_t * ch_obj =
1115        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1116
1117    if (NULL != ch_obj) {
1118        pthread_mutex_lock(&ch_obj->ch_lock);
1119        pthread_mutex_unlock(&my_obj->cam_lock);
1120
1121        rc = mm_channel_fsm_fn(ch_obj,
1122                               MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
1123                               NULL,
1124                               NULL);
1125    } else {
1126        pthread_mutex_unlock(&my_obj->cam_lock);
1127    }
1128
1129    return rc;
1130}
1131
1132int32_t mm_camera_start_focus(mm_camera_obj_t *my_obj,
1133                              uint32_t ch_id,
1134                              uint32_t sensor_idx,
1135                              uint32_t focus_mode)
1136{
1137    int32_t rc = -1;
1138    mm_evt_payload_start_focus_t payload;
1139    mm_channel_t * ch_obj =
1140        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1141
1142    if (NULL != ch_obj) {
1143        pthread_mutex_lock(&ch_obj->ch_lock);
1144        pthread_mutex_unlock(&my_obj->cam_lock);
1145
1146        memset(&payload, 0, sizeof(mm_evt_payload_start_focus_t));
1147        payload.sensor_idx = sensor_idx;
1148        payload.focus_mode = focus_mode;
1149        rc = mm_channel_fsm_fn(ch_obj,
1150                               MM_CHANNEL_EVT_START_FOCUS,
1151                               (void *)&payload,
1152                               NULL);
1153    } else {
1154        pthread_mutex_unlock(&my_obj->cam_lock);
1155    }
1156
1157    return rc;
1158}
1159
1160int32_t mm_camera_abort_focus(mm_camera_obj_t *my_obj,
1161                              uint32_t ch_id,
1162                              uint32_t sensor_idx)
1163{
1164    int32_t rc = -1;
1165    mm_channel_t * ch_obj =
1166        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1167
1168    if (NULL != ch_obj) {
1169        pthread_mutex_lock(&ch_obj->ch_lock);
1170        pthread_mutex_unlock(&my_obj->cam_lock);
1171
1172        rc = mm_channel_fsm_fn(ch_obj,
1173                               MM_CHANNEL_EVT_ABORT_FOCUS,
1174                               (void*)sensor_idx,
1175                               NULL);
1176    } else {
1177        pthread_mutex_unlock(&my_obj->cam_lock);
1178    }
1179
1180    return rc;
1181}
1182
1183int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
1184                                   uint32_t ch_id,
1185                                   uint32_t sensor_idx)
1186{
1187    int32_t rc = -1;
1188    mm_channel_t * ch_obj =
1189        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1190
1191    if (NULL != ch_obj) {
1192        pthread_mutex_lock(&ch_obj->ch_lock);
1193        pthread_mutex_unlock(&my_obj->cam_lock);
1194
1195        rc = mm_channel_fsm_fn(ch_obj,
1196                               MM_CHANNEL_EVT_PREPARE_SNAPSHOT,
1197                               (void *)sensor_idx,
1198                               NULL);
1199    } else {
1200        pthread_mutex_unlock(&my_obj->cam_lock);
1201    }
1202
1203    return rc;
1204}
1205
1206int32_t mm_camera_set_stream_parm(mm_camera_obj_t *my_obj,
1207                                  uint32_t ch_id,
1208                                  uint32_t s_id,
1209                                  mm_camera_stream_parm_t parm_type,
1210                                  void* p_value)
1211{
1212    int32_t rc = -1;
1213    mm_evt_paylod_stream_parm_t payload;
1214    mm_channel_t * ch_obj =
1215        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1216
1217    if (NULL != ch_obj) {
1218        pthread_mutex_lock(&ch_obj->ch_lock);
1219        pthread_mutex_unlock(&my_obj->cam_lock);
1220
1221        memset(&payload,0,sizeof(mm_evt_paylod_stream_parm_t));
1222        payload.parm_type = parm_type;
1223        payload.value = p_value;
1224        rc = mm_channel_fsm_fn(ch_obj,
1225                               MM_CHANNEL_EVT_SET_STREAM_PARM,
1226                               (void *)s_id,
1227                               &payload);
1228    } else {
1229        pthread_mutex_unlock(&my_obj->cam_lock);
1230    }
1231
1232    return rc;
1233}
1234
1235int32_t mm_camera_get_stream_parm(mm_camera_obj_t *my_obj,
1236                                  uint32_t ch_id,
1237                                  uint32_t s_id,
1238                                  mm_camera_stream_parm_t parm_type,
1239                                  void* p_value)
1240{
1241    int32_t rc = -1;
1242    mm_evt_paylod_stream_parm_t payload;
1243    mm_channel_t * ch_obj =
1244        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1245
1246    if (NULL != ch_obj) {
1247        pthread_mutex_lock(&ch_obj->ch_lock);
1248        pthread_mutex_unlock(&my_obj->cam_lock);
1249
1250        memset(&payload,0,sizeof(mm_evt_paylod_stream_parm_t));
1251        payload.parm_type = parm_type;
1252        payload.value = p_value;
1253        rc = mm_channel_fsm_fn(ch_obj,
1254                               MM_CHANNEL_EVT_GET_STREAM_PARM,
1255                               (void *)s_id,
1256                               &payload);
1257    } else {
1258        pthread_mutex_unlock(&my_obj->cam_lock);
1259    }
1260
1261    return rc;
1262}
1263
1264int32_t mm_camera_send_private_ioctl(mm_camera_obj_t *my_obj,
1265                                     uint32_t cmd_id,
1266                                     uint32_t cmd_length,
1267                                     void *cmd)
1268{
1269    int32_t rc = -1;
1270
1271    struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
1272
1273    CDBG("%s: cmd = %p, length = %d",
1274               __func__, cmd, cmd_length);
1275    memset(&v4l2_ioctl, 0, sizeof(v4l2_ioctl));
1276    v4l2_ioctl.id = cmd_id;
1277    v4l2_ioctl.len = cmd_length;
1278    v4l2_ioctl.ioctl_ptr = cmd;
1279    rc = ioctl (my_obj->ctrl_fd, MSM_CAM_V4L2_IOCTL_PRIVATE_GENERAL, &v4l2_ioctl);
1280
1281    if(rc < 0) {
1282        CDBG_ERROR("%s: cmd = %p, id = %d, length = %d, rc = %d\n",
1283                   __func__, cmd, cmd_id, cmd_length, rc);
1284    } else {
1285        rc = 0;
1286    }
1287
1288    return rc;
1289}
1290
1291int32_t mm_camera_ctrl_set_specialEffect (mm_camera_obj_t *my_obj, int32_t effect) {
1292    struct v4l2_control ctrl;
1293    if (effect == CAMERA_EFFECT_MAX)
1294        effect = CAMERA_EFFECT_OFF;
1295    int rc = 0;
1296
1297    ctrl.id = MSM_V4L2_PID_EFFECT;
1298    ctrl.value = effect;
1299    rc = ioctl(my_obj->ctrl_fd, VIDIOC_S_CTRL, &ctrl);
1300    return (rc >= 0)? 0: -1;;
1301}
1302
1303int32_t mm_camera_ctrl_set_auto_focus (mm_camera_obj_t *my_obj, int32_t value)
1304{
1305    int32_t rc = 0;
1306    struct v4l2_queryctrl queryctrl;
1307
1308    memset (&queryctrl, 0, sizeof (queryctrl));
1309    queryctrl.id = V4L2_CID_FOCUS_AUTO;
1310
1311    if(value != 0 && value != 1) {
1312        CDBG("%s:boolean required, invalid value = %d\n",__func__, value);
1313        return -1;
1314    }
1315    if (-1 == ioctl (my_obj->ctrl_fd, VIDIOC_QUERYCTRL, &queryctrl)) {
1316        CDBG ("V4L2_CID_FOCUS_AUTO is not supported\n");
1317    } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
1318        CDBG ("%s:V4L2_CID_FOCUS_AUTO is not supported\n", __func__);
1319    } else {
1320        if(0 != (rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1321                V4L2_CID_FOCUS_AUTO, value))){
1322            CDBG("%s: error, id=0x%x, value=%d, rc = %d\n",
1323                     __func__, V4L2_CID_FOCUS_AUTO, value, rc);
1324            rc = -1;
1325        }
1326    }
1327    return rc;
1328}
1329
1330int32_t mm_camera_ctrl_set_whitebalance (mm_camera_obj_t *my_obj, int32_t mode) {
1331
1332    int32_t rc = 0, value;
1333    uint32_t id;
1334
1335    switch(mode) {
1336    case MM_CAMERA_WHITE_BALANCE_AUTO:
1337        id = V4L2_CID_AUTO_WHITE_BALANCE;
1338        value = 1; /* TRUE */
1339        break;
1340    case MM_CAMERA_WHITE_BALANCE_OFF:
1341        id = V4L2_CID_AUTO_WHITE_BALANCE;
1342        value = 0; /* FALSE */
1343        break;
1344    case MM_CAMERA_WHITE_BALANCE_DAYLIGHT:
1345        id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
1346        value = 6500;
1347        break;
1348    case MM_CAMERA_WHITE_BALANCE_INCANDESCENT:
1349        id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
1350        value = 2800;
1351        break;
1352    case MM_CAMERA_WHITE_BALANCE_FLUORESCENT:
1353        id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
1354        value = 4200;
1355        break;
1356    case MM_CAMERA_WHITE_BALANCE_CLOUDY:
1357        id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
1358        value = 7500;
1359        break;
1360    default:
1361        id = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
1362        value = 4200;
1363        break;
1364    }
1365    rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd, id, value);
1366    if(0 != rc){
1367        CDBG("%s: error, exp_metering_action_param=%d, rc = %d\n", __func__, value, rc);
1368    }
1369    return rc;
1370}
1371
1372int32_t mm_camera_set_general_parm(mm_camera_obj_t * my_obj,
1373                                   mm_camera_parm_type_t parm_type,
1374                                   void* p_value)
1375{
1376    int rc = -1;
1377    int isZSL =0;
1378
1379    switch(parm_type)  {
1380    case MM_CAMERA_PARM_EXPOSURE:
1381        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1382                                   MSM_V4L2_PID_EXP_METERING,
1383                                   *((int32_t *)p_value));
1384        break;
1385    case MM_CAMERA_PARM_SHARPNESS:
1386        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1387                                   V4L2_CID_SHARPNESS,
1388                                   *((int32_t *)p_value));
1389        break;
1390    case MM_CAMERA_PARM_CONTRAST:
1391        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1392                                   V4L2_CID_CONTRAST,
1393                                   *((int32_t *)p_value));
1394        break;
1395    case MM_CAMERA_PARM_SATURATION:
1396        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1397                                   V4L2_CID_SATURATION,
1398                                   *((int32_t *)p_value));
1399        break;
1400    case MM_CAMERA_PARM_BRIGHTNESS:
1401        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1402                                   V4L2_CID_BRIGHTNESS,
1403                                   *((int32_t *)p_value));
1404        break;
1405    case MM_CAMERA_PARM_WHITE_BALANCE:
1406        rc = mm_camera_ctrl_set_whitebalance (my_obj, *((int32_t *)p_value));
1407        break;
1408    case MM_CAMERA_PARM_ISO:
1409        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1410                                   MSM_V4L2_PID_ISO,
1411                                   *((int32_t *)p_value));
1412        break;
1413    case MM_CAMERA_PARM_ZOOM:
1414        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1415                                   V4L2_CID_ZOOM_ABSOLUTE,
1416                                   *((int32_t *)p_value));
1417        break;
1418    case MM_CAMERA_PARM_LUMA_ADAPTATION:
1419        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1420                                   MSM_V4L2_PID_LUMA_ADAPTATION,
1421                                   *((int32_t *)p_value));
1422        break;
1423    case MM_CAMERA_PARM_ANTIBANDING:
1424        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1425                                   V4L2_CID_POWER_LINE_FREQUENCY,
1426                                   *((int32_t *)p_value));
1427        break;
1428    case MM_CAMERA_PARM_CONTINUOUS_AF:
1429        rc = mm_camera_ctrl_set_auto_focus(my_obj,
1430                                           *((int32_t *)p_value));
1431        break;
1432    case MM_CAMERA_PARM_HJR:
1433        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1434                                   MSM_V4L2_PID_HJR,
1435                                   *((int32_t *)p_value));
1436        break;
1437    case MM_CAMERA_PARM_EFFECT:
1438        rc = mm_camera_ctrl_set_specialEffect (my_obj,
1439                                               *((int32_t *)p_value));
1440        break;
1441    case MM_CAMERA_PARM_FPS:
1442        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1443                                            CAMERA_SET_PARM_FPS,
1444                                            sizeof(uint32_t),
1445                                            p_value);
1446        break;
1447    case MM_CAMERA_PARM_FPS_MODE:
1448        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1449                                            CAMERA_SET_FPS_MODE,
1450                                            sizeof(int32_t),
1451                                            p_value);
1452        break;
1453    case MM_CAMERA_PARM_EXPOSURE_COMPENSATION:
1454        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1455                                            CAMERA_SET_PARM_EXPOSURE_COMPENSATION,
1456                                            sizeof(int32_t),
1457                                            p_value);
1458        break;
1459    case MM_CAMERA_PARM_LED_MODE:
1460        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1461                                            CAMERA_SET_PARM_LED_MODE,
1462                                            sizeof(int32_t),
1463                                            p_value);
1464        break;
1465    case MM_CAMERA_PARM_ROLLOFF:
1466        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1467                                            CAMERA_SET_PARM_ROLLOFF,
1468                                            sizeof(int32_t),
1469                                            p_value);
1470        break;
1471    case MM_CAMERA_PARM_MODE:
1472        my_obj->current_mode = *((camera_mode_t *)p_value);
1473        break;
1474    case MM_CAMERA_PARM_FOCUS_RECT:
1475        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1476                                            CAMERA_SET_PARM_FOCUS_RECT,
1477                                            sizeof(int32_t),
1478                                            p_value);
1479        break;
1480    case MM_CAMERA_PARM_AEC_ROI:
1481        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1482                                            CAMERA_SET_PARM_AEC_ROI,
1483                                            sizeof(cam_set_aec_roi_t),
1484                                            p_value);
1485        break;
1486    case MM_CAMERA_PARM_AF_ROI:
1487        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1488                                            CAMERA_SET_PARM_AF_ROI,
1489                                            sizeof(roi_info_t),
1490                                            p_value);
1491        break;
1492    case MM_CAMERA_PARM_FOCUS_MODE:
1493        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1494                                            CAMERA_SET_PARM_AF_MODE,
1495                                            sizeof(int32_t),
1496                                            p_value);
1497        break;
1498#if 0 /* to be enabled later: @punits */
1499    case MM_CAMERA_PARM_AF_MTR_AREA:
1500        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1501                                            CAMERA_SET_PARM_AF_MTR_AREA,
1502                                            sizeof(af_mtr_area_t),
1503                                            p_value);
1504        break;
1505    case MM_CAMERA_PARM_AEC_MTR_AREA:
1506        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1507                                            CAMERA_SET_AEC_MTR_AREA,
1508                                            sizeof(aec_mtr_area_t),
1509                                            p_value);
1510        break;
1511#endif
1512    case MM_CAMERA_PARM_CAF_ENABLE:
1513        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1514                                            CAMERA_SET_PARM_CAF,
1515                                            sizeof(uint32_t),
1516                                            p_value);
1517        break;
1518    case MM_CAMERA_PARM_BESTSHOT_MODE:
1519        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1520                                            CAMERA_SET_PARM_BESTSHOT_MODE,
1521                                            sizeof(int32_t),
1522                                            p_value);
1523        break;
1524    case MM_CAMERA_PARM_VIDEO_DIS:
1525        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1526                                            CAMERA_SET_VIDEO_DIS_PARAMS,
1527                                            sizeof(video_dis_param_ctrl_t),
1528                                            p_value);
1529        break;
1530    case MM_CAMERA_PARM_VIDEO_ROT:
1531        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1532                                            CAMERA_SET_VIDEO_ROT_PARAMS,
1533                                            sizeof(video_rotation_param_ctrl_t),
1534                                            p_value);
1535        break;
1536    case MM_CAMERA_PARM_SCE_FACTOR:
1537        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1538                                            CAMERA_SET_SCE_FACTOR,
1539                                            sizeof(int32_t),
1540                                            p_value);
1541        break;
1542    case MM_CAMERA_PARM_FD:
1543        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1544                                            CAMERA_SET_PARM_FD,
1545                                            sizeof(fd_set_parm_t),
1546                                            p_value);
1547        break;
1548    case MM_CAMERA_PARM_AEC_LOCK:
1549        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1550                                            CAMERA_SET_AEC_LOCK,
1551                                            sizeof(int32_t),
1552                                            p_value);
1553        break;
1554    case MM_CAMERA_PARM_AWB_LOCK:
1555        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1556                                            CAMERA_SET_AWB_LOCK,
1557                                            sizeof(int32_t),
1558                                            p_value);
1559        break;
1560    case MM_CAMERA_PARM_MCE:
1561        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1562                                            CAMERA_SET_PARM_MCE,
1563                                            sizeof(int32_t),
1564                                            p_value);
1565        break;
1566    case MM_CAMERA_PARM_HORIZONTAL_VIEW_ANGLE:
1567        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1568                                            CAMERA_GET_PARM_HORIZONTAL_VIEW_ANGLE,
1569                                            sizeof(focus_distances_info_t),
1570                                            p_value);
1571        break;
1572    case MM_CAMERA_PARM_VERTICAL_VIEW_ANGLE:
1573        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1574                                            CAMERA_GET_PARM_VERTICAL_VIEW_ANGLE,
1575                                            sizeof(focus_distances_info_t),
1576                                            p_value);
1577        break;
1578    case MM_CAMERA_PARM_RESET_LENS_TO_INFINITY:
1579        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1580                                            CAMERA_SET_PARM_RESET_LENS_TO_INFINITY,
1581                                            0, NULL);
1582        break;
1583    case MM_CAMERA_PARM_SNAPSHOTDATA:
1584        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1585                                            CAMERA_GET_PARM_SNAPSHOTDATA,
1586                                            sizeof(snapshotData_info_t),
1587                                            p_value);
1588        break;
1589    case MM_CAMERA_PARM_HFR:
1590        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1591                                            CAMERA_SET_PARM_HFR,
1592                                            sizeof(int32_t),
1593                                            p_value);
1594        break;
1595    case MM_CAMERA_PARM_REDEYE_REDUCTION:
1596        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1597                                            CAMERA_SET_REDEYE_REDUCTION,
1598                                            sizeof(int32_t),
1599                                            p_value);
1600        break;
1601    case MM_CAMERA_PARM_WAVELET_DENOISE:
1602        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1603                                            CAMERA_SET_PARM_WAVELET_DENOISE,
1604                                            sizeof(denoise_param_t),
1605                                            p_value);
1606        break;
1607    case MM_CAMERA_PARM_3D_DISPLAY_DISTANCE:
1608        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1609                                            CAMERA_SET_PARM_3D_DISPLAY_DISTANCE,
1610                                            sizeof(float),
1611                                            p_value);
1612        break;
1613    case MM_CAMERA_PARM_3D_VIEW_ANGLE:
1614        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1615                                            CAMERA_SET_PARM_3D_VIEW_ANGLE,
1616                                            sizeof(uint32_t),
1617                                            p_value);
1618        break;
1619    case MM_CAMERA_PARM_ZOOM_RATIO:
1620        break;
1621    case MM_CAMERA_PARM_HISTOGRAM:
1622        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1623                                            CAMERA_SET_PARM_HISTOGRAM,
1624                                            sizeof(int8_t),
1625                                            p_value);
1626        break;
1627    case MM_CAMERA_PARM_ASD_ENABLE:
1628        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1629                                          CAMERA_SET_ASD_ENABLE,
1630                                          sizeof(uint32_t),
1631                                          p_value);
1632        break;
1633    case MM_CAMERA_PARM_RECORDING_HINT:
1634        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1635                                            CAMERA_SET_RECORDING_HINT,
1636                                            sizeof(uint32_t),
1637                                            p_value);
1638        break;
1639    case MM_CAMERA_PARM_PREVIEW_FORMAT:
1640        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1641                                            CAMERA_SET_PARM_PREVIEW_FORMAT,
1642                                            sizeof(uint32_t),
1643                                            p_value);
1644        break;
1645    /* TODO: need code review to determine any of the three is redundent
1646     * MM_CAMERA_PARM_DIS_ENABLE,
1647     * MM_CAMERA_PARM_FULL_LIVESHOT,
1648     * MM_CAMERA_PARM_LOW_POWER_MODE*/
1649    case MM_CAMERA_PARM_DIS_ENABLE:
1650        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1651                                            CAMERA_SET_DIS_ENABLE,
1652                                            sizeof(uint32_t),
1653                                            p_value);
1654        break;
1655    case MM_CAMERA_PARM_FULL_LIVESHOT:
1656        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1657                                            CAMERA_SET_FULL_LIVESHOT,
1658                                            sizeof(uint32_t),
1659                                            p_value);
1660        break;
1661    case MM_CAMERA_PARM_LOW_POWER_MODE:
1662        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1663                                            CAMERA_SET_LOW_POWER_MODE,
1664                                            sizeof(uint32_t),
1665                                            p_value);
1666        break;
1667    case MM_CAMERA_PARM_HDR:
1668        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1669                                            CAMERA_SET_PARM_HDR,
1670                                            sizeof(exp_bracketing_t),
1671                                            p_value);
1672        break;
1673    default:
1674        CDBG("%s: default: parm %d not supported\n", __func__, parm_type);
1675        break;
1676    }
1677    return rc;
1678}
1679
1680int32_t mm_camera_util_private_s_ctrl(int32_t fd, uint32_t id, void* value)
1681{
1682    int rc = -1;
1683    struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
1684
1685    memset(&v4l2_ioctl, 0, sizeof(v4l2_ioctl));
1686    v4l2_ioctl.id = id;
1687    v4l2_ioctl.ioctl_ptr = value;
1688    rc = ioctl (fd, MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL, &v4l2_ioctl);
1689
1690    if(rc < 0) {
1691        CDBG_ERROR("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
1692                   __func__, fd, id, (uint32_t)value, rc);
1693        rc = -1;
1694    } else {
1695        rc = 0;
1696    }
1697    return rc;
1698}
1699
1700int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
1701                                              cam_ctrl_type type,
1702                                              uint32_t length,
1703                                              void *value)
1704{
1705    return mm_camera_send_native_ctrl_timeout_cmd(my_obj, type,
1706                                                  length, value,
1707                                                  1000);
1708}
1709
1710int32_t mm_camera_send_native_ctrl_timeout_cmd(mm_camera_obj_t * my_obj,
1711                                                      cam_ctrl_type type,
1712                                                      uint32_t length,
1713                                                      void *value,
1714                                                      int timeout)
1715{
1716    int rc = -1;
1717    struct msm_ctrl_cmd ctrl_cmd;
1718
1719    memset(&ctrl_cmd, 0, sizeof(ctrl_cmd));
1720    ctrl_cmd.type = type;
1721    ctrl_cmd.length = (uint16_t)length;
1722    ctrl_cmd.timeout_ms = timeout;
1723    ctrl_cmd.value = value;
1724    ctrl_cmd.status = (uint16_t)CAM_CTRL_SUCCESS;
1725    rc = mm_camera_util_private_s_ctrl(my_obj->ctrl_fd,
1726                               MSM_V4L2_PID_CTRL_CMD,
1727                               (void*)&ctrl_cmd);
1728    CDBG("%s: type=%d, rc = %d, status = %d\n",
1729        __func__, type, rc, ctrl_cmd.status);
1730    if(rc != 0 || ((ctrl_cmd.status != CAM_CTRL_ACCEPTED) &&
1731        (ctrl_cmd.status != CAM_CTRL_SUCCESS) &&
1732        (ctrl_cmd.status != CAM_CTRL_INVALID_PARM)))
1733        rc = -1;
1734    return rc;
1735}
1736
1737int mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1738                      mm_camera_event_type_t evt_type,
1739                      int reg_count)
1740{
1741    int rc = 0;
1742    struct v4l2_event_subscription sub;
1743
1744    memset(&sub, 0, sizeof(sub));
1745    sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_EVENT;
1746    if(reg_count == 0) {
1747        /* unsubscribe */
1748        if(my_obj->evt_type_mask == (uint32_t)(1 << evt_type)) {
1749            rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1750            CDBG("%s: unsubscribe event 0x%x, rc = %d", __func__, sub.type, rc);
1751            sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_ERROR_EVENT;
1752            rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1753            CDBG("%s: unsubscribe event 0x%x, rc = %d", __func__, sub.type, rc);
1754        }
1755        my_obj->evt_type_mask &= ~(1 << evt_type);
1756        if(my_obj->evt_type_mask == 0) {
1757            /* remove evt fd from the polling thraed when unreg the last event */
1758            mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread, my_obj->my_hdl);
1759        }
1760    } else {
1761        if(!my_obj->evt_type_mask) {
1762            /* this is the first reg event */
1763            rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1764            CDBG("%s: subscribe event 0x%x, rc = %d", __func__, sub.type, rc);
1765            if (rc < 0)
1766                goto end;
1767            sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_ERROR_EVENT;
1768            rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1769            CDBG("%s: subscribe event 0x%x, rc = %d", __func__, sub.type, rc);
1770            if (rc < 0)
1771                goto end;
1772        }
1773        my_obj->evt_type_mask |= (1 << evt_type);
1774        if(my_obj->evt_type_mask == (uint32_t)(1 << evt_type)) {
1775            /* add evt fd to polling thread when subscribe the first event */
1776            rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1777                                                   my_obj->my_hdl,
1778                                                   my_obj->ctrl_fd,
1779                                                   mm_camera_event_notify,
1780                                                   (void*)my_obj);
1781        }
1782    }
1783end:
1784    return rc;
1785}
1786
1787int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj, void *msg, uint32_t buf_size, int sendfd)
1788{
1789    return mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd);
1790}
1791
1792int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1793                          int ext_mode,
1794                          int idx,
1795                          int fd,
1796                          uint32_t size)
1797{
1798    cam_sock_packet_t packet;
1799    memset(&packet, 0, sizeof(cam_sock_packet_t));
1800    packet.msg_type = CAM_SOCK_MSG_TYPE_FD_MAPPING;
1801    packet.payload.frame_fd_map.ext_mode = ext_mode;
1802    packet.payload.frame_fd_map.frame_idx = idx;
1803    packet.payload.frame_fd_map.fd = fd;
1804    packet.payload.frame_fd_map.size = size;
1805
1806    return mm_camera_util_sendmsg(my_obj, &packet,
1807                                  sizeof(cam_sock_packet_t),
1808                                  packet.payload.frame_fd_map.fd);
1809}
1810
1811int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
1812                            int ext_mode,
1813                            int idx)
1814{
1815    cam_sock_packet_t packet;
1816    memset(&packet, 0, sizeof(cam_sock_packet_t));
1817    packet.msg_type = CAM_SOCK_MSG_TYPE_FD_UNMAPPING;
1818    packet.payload.frame_fd_unmap.ext_mode = ext_mode;
1819    packet.payload.frame_fd_unmap.frame_idx = idx;
1820    return mm_camera_util_sendmsg(my_obj, &packet,
1821                                  sizeof(cam_sock_packet_t),
1822                                  packet.payload.frame_fd_map.fd);
1823}
1824
1825int32_t mm_camera_util_s_ctrl(int32_t fd,  uint32_t id, int32_t value)
1826{
1827    int rc = 0;
1828    struct v4l2_control control;
1829
1830    memset(&control, 0, sizeof(control));
1831    control.id = id;
1832    control.value = value;
1833    rc = ioctl (fd, VIDIOC_S_CTRL, &control);
1834
1835    CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
1836         __func__, fd, id, (uint32_t)value, rc);
1837    return (rc >= 0)? 0 : -1;
1838}
1839
1840int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
1841{
1842    int rc = 0;
1843    struct v4l2_control control;
1844
1845    memset(&control, 0, sizeof(control));
1846    control.id = id;
1847    control.value = (int32_t)value;
1848    rc = ioctl (fd, VIDIOC_G_CTRL, &control);
1849    *value = control.value;
1850    CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc);
1851    return (rc >= 0)? 0 : -1;
1852}
1853
1854uint8_t mm_camera_util_get_pp_mask(mm_camera_obj_t *my_obj)
1855{
1856    uint8_t pp_mask = 0;
1857    int32_t rc = 0;
1858
1859    /* query pp mask from mctl */
1860    rc = mm_camera_send_native_ctrl_cmd(my_obj,
1861                                        CAMERA_GET_PP_MASK,
1862                                        sizeof(uint8_t),
1863                                        (void *)&pp_mask);
1864    if (0 != rc) {
1865        CDBG_ERROR("%s: error getting post processing mask (rc=%d)",
1866                   __func__, rc);
1867    }
1868
1869    return pp_mask;
1870}
1871
1872int32_t mm_camera_open_repro_isp(mm_camera_obj_t *my_obj,
1873                                 uint32_t ch_id,
1874                                 mm_camera_repro_isp_type_t repro_isp_type,
1875                                 uint32_t *repro_isp_handle)
1876{
1877    int32_t rc = -1;
1878    uint32_t repro_hdl = 0;
1879    mm_channel_t * ch_obj =
1880        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1881
1882    if (NULL != ch_obj) {
1883        pthread_mutex_lock(&ch_obj->ch_lock);
1884        pthread_mutex_unlock(&my_obj->cam_lock);
1885
1886        rc = mm_channel_fsm_fn(ch_obj,
1887                               MM_CHANNEL_EVT_OPEN_REPRO_ISP,
1888                               (void*)repro_isp_type,
1889                               (void*)&repro_hdl);
1890    } else {
1891        pthread_mutex_unlock(&my_obj->cam_lock);
1892        CDBG_ERROR("%s: no channel obj exist", __func__);
1893    }
1894
1895    if (NULL != repro_isp_handle) {
1896        *repro_isp_handle = repro_hdl;
1897    }
1898    return rc;
1899}
1900
1901int32_t mm_camera_config_repro_isp(mm_camera_obj_t *my_obj,
1902                                   uint32_t ch_id,
1903                                   uint32_t repro_isp_handle,
1904                                   mm_camera_repro_isp_config_t *config)
1905{
1906    int32_t rc = -1;
1907    mm_channel_t * ch_obj =
1908        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1909    mm_evt_paylod_config_repro_isp_t payload;
1910
1911    if (NULL != ch_obj) {
1912        pthread_mutex_lock(&ch_obj->ch_lock);
1913        pthread_mutex_unlock(&my_obj->cam_lock);
1914
1915        memset(&payload, 0, sizeof(mm_evt_paylod_config_repro_isp_t));
1916        payload.repro_isp_handle = repro_isp_handle;
1917        payload.config = config;
1918        rc = mm_channel_fsm_fn(ch_obj,
1919                               MM_CHANNEL_EVT_CONFIG_REPRO_ISP,
1920                               (void*)&payload,
1921                               NULL);
1922    } else {
1923        pthread_mutex_unlock(&my_obj->cam_lock);
1924        CDBG_ERROR("%s: no channel obj exist", __func__);
1925    }
1926
1927    return rc;
1928}
1929
1930int32_t mm_camera_attach_stream_to_repro_isp(mm_camera_obj_t *my_obj,
1931                                             uint32_t ch_id,
1932                                             uint32_t repro_isp_handle,
1933                                             uint32_t stream_id)
1934{
1935    int32_t rc = -1;
1936    mm_channel_t * ch_obj =
1937        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1938    mm_evt_paylod_stream_to_repro_isp_t payload;
1939
1940    if (NULL != ch_obj) {
1941        pthread_mutex_lock(&ch_obj->ch_lock);
1942        pthread_mutex_unlock(&my_obj->cam_lock);
1943
1944        memset(&payload, 0, sizeof(mm_evt_paylod_stream_to_repro_isp_t));
1945        payload.repro_isp_handle = repro_isp_handle;
1946        payload.stream_id = stream_id;
1947        rc = mm_channel_fsm_fn(ch_obj,
1948                               MM_CHANNEL_EVT_ATTACH_STREAM_TO_REPRO_ISP,
1949                               (void*)&payload,
1950                               NULL);
1951    } else {
1952        pthread_mutex_unlock(&my_obj->cam_lock);
1953        CDBG_ERROR("%s: no channel obj exist", __func__);
1954    }
1955
1956    return rc;
1957}
1958
1959int32_t mm_camera_start_repro_isp(mm_camera_obj_t *my_obj,
1960                                  uint32_t ch_id,
1961                                  uint32_t repro_isp_handle,
1962                                  uint32_t stream_id)
1963{
1964    int32_t rc = -1;
1965    mm_evt_paylod_repro_start_stop_t payload;
1966    mm_channel_t * ch_obj =
1967        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1968
1969    if (NULL != ch_obj) {
1970        pthread_mutex_lock(&ch_obj->ch_lock);
1971        pthread_mutex_unlock(&my_obj->cam_lock);
1972
1973        memset(&payload, 0, sizeof(mm_evt_paylod_repro_start_stop_t));
1974        payload.repro_isp_handle = repro_isp_handle;
1975        payload.stream_id = stream_id;
1976        rc = mm_channel_fsm_fn(ch_obj,
1977                               MM_CHANNEL_EVT_START_REPRO_ISP,
1978                               (void*)&payload,
1979                               NULL);
1980    } else {
1981        pthread_mutex_unlock(&my_obj->cam_lock);
1982        CDBG_ERROR("%s: no channel obj exist", __func__);
1983    }
1984
1985    return rc;
1986}
1987
1988int32_t mm_camera_reprocess(mm_camera_obj_t *my_obj,
1989                            uint32_t ch_id,
1990                            uint32_t repro_isp_handle,
1991                            mm_camera_repro_data_t *repro_data)
1992{
1993    int32_t rc = -1;
1994    mm_channel_t * ch_obj =
1995        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1996    mm_evt_paylod_reprocess_t payload;
1997
1998    if (NULL != ch_obj) {
1999        pthread_mutex_lock(&ch_obj->ch_lock);
2000        pthread_mutex_unlock(&my_obj->cam_lock);
2001
2002        memset(&payload, 0, sizeof(mm_evt_paylod_reprocess_t));
2003        payload.repro_isp_handle = repro_isp_handle;
2004        payload.repro_data = repro_data;
2005        rc = mm_channel_fsm_fn(ch_obj,
2006                               MM_CHANNEL_EVT_ATTACH_STREAM_TO_REPRO_ISP,
2007                               (void*)&payload,
2008                               NULL);
2009    } else {
2010        pthread_mutex_unlock(&my_obj->cam_lock);
2011        CDBG_ERROR("%s: no channel obj exist", __func__);
2012    }
2013
2014    return rc;
2015}
2016
2017int32_t mm_camera_stop_repro_isp(mm_camera_obj_t *my_obj,
2018                                 uint32_t ch_id,
2019                                 uint32_t repro_isp_handle,
2020                                 uint32_t stream_id)
2021{
2022    int32_t rc = -1;
2023    mm_evt_paylod_repro_start_stop_t payload;
2024    mm_channel_t * ch_obj =
2025        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2026
2027    if (NULL != ch_obj) {
2028        pthread_mutex_lock(&ch_obj->ch_lock);
2029        pthread_mutex_unlock(&my_obj->cam_lock);
2030
2031        memset(&payload, 0, sizeof(mm_evt_paylod_repro_start_stop_t));
2032        payload.repro_isp_handle = repro_isp_handle;
2033        payload.stream_id = stream_id;
2034        rc = mm_channel_fsm_fn(ch_obj,
2035                               MM_CHANNEL_EVT_STOP_REPRO_ISP,
2036                               (void*)&payload,
2037                               NULL);
2038    } else {
2039        pthread_mutex_unlock(&my_obj->cam_lock);
2040        CDBG_ERROR("%s: no channel obj exist", __func__);
2041    }
2042
2043    return rc;
2044}
2045
2046int32_t mm_camera_detach_stream_from_repro_isp(mm_camera_obj_t *my_obj,
2047                                               uint32_t ch_id,
2048                                               uint32_t repro_isp_handle,
2049                                               uint32_t stream_id)
2050{
2051    int32_t rc = -1;
2052    mm_channel_t * ch_obj =
2053        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2054    mm_evt_paylod_stream_to_repro_isp_t payload;
2055
2056    if (NULL != ch_obj) {
2057        pthread_mutex_lock(&ch_obj->ch_lock);
2058        pthread_mutex_unlock(&my_obj->cam_lock);
2059
2060        memset(&payload, 0, sizeof(mm_evt_paylod_stream_to_repro_isp_t));
2061        payload.repro_isp_handle = repro_isp_handle;
2062        payload.stream_id = stream_id;
2063        rc = mm_channel_fsm_fn(ch_obj,
2064                               MM_CHANNEL_EVT_DETACH_STREAM_FROM_REPRO_ISP,
2065                               (void*)&payload,
2066                               NULL);
2067    } else {
2068        pthread_mutex_unlock(&my_obj->cam_lock);
2069        CDBG_ERROR("%s: no channel obj exist", __func__);
2070    }
2071
2072    return rc;
2073}
2074
2075int32_t mm_camera_close_repro_isp(mm_camera_obj_t *my_obj,
2076                                  uint32_t ch_id,
2077                                  uint32_t repro_isp_handle)
2078{
2079    int32_t rc = -1;
2080    mm_channel_t * ch_obj =
2081        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2082
2083    if (NULL != ch_obj) {
2084        pthread_mutex_lock(&ch_obj->ch_lock);
2085        pthread_mutex_unlock(&my_obj->cam_lock);
2086
2087        rc = mm_channel_fsm_fn(ch_obj,
2088                               MM_CHANNEL_EVT_CLOSE_REPRO_ISP,
2089                               (void*)repro_isp_handle,
2090                               NULL);
2091    } else {
2092        pthread_mutex_unlock(&my_obj->cam_lock);
2093        CDBG_ERROR("%s: no channel obj exist", __func__);
2094    }
2095
2096    return rc;
2097}
2098