mm_camera.c revision 074b84eb8d67ed16da734dbe9a81f1600f330887
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_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    default:
833        /* needs to add more implementation */
834        rc = -1;
835        break;
836    }
837
838    pthread_mutex_unlock(&my_obj->cam_lock);
839    return rc;
840}
841
842uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj)
843{
844    mm_channel_t *ch_obj = NULL;
845    uint8_t ch_idx = 0;
846    uint32_t ch_hdl = 0;
847
848    for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
849        if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
850            ch_obj = &my_obj->ch[ch_idx];
851            break;
852        }
853    }
854
855    if (NULL != ch_obj) {
856        /* initialize channel obj */
857        memset(ch_obj, 0, sizeof(mm_channel_t));
858        ch_hdl = mm_camera_util_generate_handler(ch_idx);
859        ch_obj->my_hdl = ch_hdl;
860        ch_obj->state = MM_CHANNEL_STATE_STOPPED;
861        ch_obj->cam_obj = my_obj;
862        pthread_mutex_init(&ch_obj->ch_lock, NULL);
863    }
864
865    mm_channel_init(ch_obj);
866    pthread_mutex_unlock(&my_obj->cam_lock);
867
868    return ch_hdl;
869}
870
871void mm_camera_del_channel(mm_camera_obj_t *my_obj,
872                           uint32_t ch_id)
873{
874    mm_channel_t * ch_obj =
875        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
876
877    if (NULL != ch_obj) {
878        pthread_mutex_lock(&ch_obj->ch_lock);
879        pthread_mutex_unlock(&my_obj->cam_lock);
880
881        mm_channel_fsm_fn(ch_obj,
882                               MM_CHANNEL_EVT_DELETE,
883                               NULL,
884                               NULL);
885
886        pthread_mutex_destroy(&ch_obj->ch_lock);
887        memset(ch_obj, 0, sizeof(mm_channel_t));
888    } else {
889        pthread_mutex_unlock(&my_obj->cam_lock);
890    }
891}
892
893uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
894                              uint32_t ch_id,
895                              mm_camera_buf_notify_t buf_cb, void *user_data,
896                              uint32_t ext_image_mode, uint32_t sensor_idx)
897{
898    uint32_t s_hdl = 0;
899    mm_channel_t * ch_obj =
900        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
901    mm_evt_paylod_add_stream_t payload;
902
903    if (NULL != ch_obj) {
904        pthread_mutex_lock(&ch_obj->ch_lock);
905        pthread_mutex_unlock(&my_obj->cam_lock);
906
907        memset(&payload, 0, sizeof(mm_evt_paylod_add_stream_t));
908        payload.buf_cb = buf_cb;
909        payload.user_data = user_data;
910        payload.ext_image_mode = ext_image_mode;
911        payload.sensor_idx = sensor_idx;
912        mm_channel_fsm_fn(ch_obj,
913                               MM_CHANNEL_EVT_ADD_STREAM,
914                               (void*)&payload,
915                               (void*)&s_hdl);
916    } else {
917        pthread_mutex_unlock(&my_obj->cam_lock);
918    }
919
920    return s_hdl;
921}
922
923int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
924                             uint32_t ch_id,
925                             uint32_t stream_id)
926{
927    int32_t rc = -1;
928    mm_channel_t * ch_obj =
929        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
930
931    if (NULL != ch_obj) {
932        pthread_mutex_lock(&ch_obj->ch_lock);
933        pthread_mutex_unlock(&my_obj->cam_lock);
934
935        rc = mm_channel_fsm_fn(ch_obj,
936                               MM_CHANNEL_EVT_DEL_STREAM,
937                               (void*)&stream_id,
938                               NULL);
939    } else {
940        pthread_mutex_unlock(&my_obj->cam_lock);
941    }
942
943    return rc;
944}
945
946int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
947                                uint32_t ch_id,
948                                uint32_t stream_id,
949                                mm_camera_stream_config_t *config)
950{
951    int32_t rc = -1;
952    mm_channel_t * ch_obj =
953        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
954    mm_evt_paylod_config_stream_t payload;
955
956    if (NULL != ch_obj) {
957        pthread_mutex_lock(&ch_obj->ch_lock);
958        pthread_mutex_unlock(&my_obj->cam_lock);
959
960        memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
961        payload.stream_id = stream_id;
962        payload.config = config;
963        rc = mm_channel_fsm_fn(ch_obj,
964                               MM_CHANNEL_EVT_CONFIG_STREAM,
965                               (void*)&payload,
966                               NULL);
967    } else {
968        pthread_mutex_unlock(&my_obj->cam_lock);
969    }
970
971    return rc;
972}
973
974int32_t mm_camera_bundle_streams(mm_camera_obj_t *my_obj,
975                                 uint32_t ch_id,
976                                 mm_camera_buf_notify_t super_frame_notify_cb,
977                                 void *user_data,
978                                 mm_camera_bundle_attr_t *attr,
979                                 uint8_t num_streams,
980                                 uint32_t *stream_ids)
981{
982    int32_t rc = -1;
983    mm_channel_t * ch_obj =
984        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
985    mm_evt_payload_bundle_stream_t payload;
986
987    if (NULL != ch_obj) {
988        pthread_mutex_lock(&ch_obj->ch_lock);
989        pthread_mutex_unlock(&my_obj->cam_lock);
990
991        memset(&payload, 0, sizeof(mm_evt_payload_bundle_stream_t));
992        payload.super_frame_notify_cb = super_frame_notify_cb;
993        payload.user_data = user_data;
994        payload.attr = attr;
995        payload.num_streams = num_streams;
996        payload.stream_ids = stream_ids;
997        rc = mm_channel_fsm_fn(ch_obj,
998                               MM_CHANNEL_EVT_INIT_BUNDLE,
999                               (void*)&payload,
1000                               NULL);
1001    } else {
1002        pthread_mutex_unlock(&my_obj->cam_lock);
1003    }
1004
1005    return rc;
1006}
1007
1008int32_t mm_camera_destroy_bundle(mm_camera_obj_t *my_obj, uint32_t ch_id)
1009{
1010    int32_t rc = -1;
1011    mm_channel_t * ch_obj =
1012        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1013
1014    if (NULL != ch_obj) {
1015        pthread_mutex_lock(&ch_obj->ch_lock);
1016        pthread_mutex_unlock(&my_obj->cam_lock);
1017
1018        rc = mm_channel_fsm_fn(ch_obj,
1019                               MM_CHANNEL_EVT_DESTROY_BUNDLE,
1020                               NULL,
1021                               NULL);
1022    } else {
1023        pthread_mutex_unlock(&my_obj->cam_lock);
1024    }
1025
1026    return rc;
1027}
1028
1029int32_t mm_camera_start_streams(mm_camera_obj_t *my_obj,
1030                                uint32_t ch_id,
1031                                uint8_t num_streams,
1032                                uint32_t *stream_ids)
1033{
1034    int32_t rc = -1;
1035    mm_channel_t * ch_obj =
1036        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1037    mm_evt_payload_start_stream_t payload;
1038
1039    if (NULL != ch_obj) {
1040        pthread_mutex_lock(&ch_obj->ch_lock);
1041        pthread_mutex_unlock(&my_obj->cam_lock);
1042
1043        memset(&payload, 0, sizeof(mm_evt_payload_start_stream_t));
1044        payload.num_streams = num_streams;
1045        payload.stream_ids = stream_ids;
1046        rc = mm_channel_fsm_fn(ch_obj,
1047                               MM_CHANNEL_EVT_START_STREAM,
1048                               (void*)&payload,
1049                               NULL);
1050    } else {
1051        pthread_mutex_unlock(&my_obj->cam_lock);
1052    }
1053
1054    return rc;
1055}
1056
1057int32_t mm_camera_stop_streams(mm_camera_obj_t *my_obj,
1058                               uint32_t ch_id,
1059                               uint8_t num_streams,
1060                               uint32_t *stream_ids)
1061{
1062    int32_t rc = 0;
1063    mm_evt_payload_stop_stream_t payload;
1064    mm_camera_cmdcb_t * node = NULL;
1065
1066    mm_channel_t * ch_obj =
1067        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1068
1069    if (NULL != ch_obj) {
1070        pthread_mutex_lock(&ch_obj->ch_lock);
1071        pthread_mutex_unlock(&my_obj->cam_lock);
1072
1073        memset(&payload, 0, sizeof(mm_evt_payload_stop_stream_t));
1074        payload.num_streams = num_streams;
1075        payload.stream_ids = stream_ids;
1076
1077        rc = mm_channel_fsm_fn(ch_obj,
1078                               MM_CHANNEL_EVT_STOP_STREAM,
1079                               (void*)&payload,
1080                               NULL);
1081    } else {
1082        pthread_mutex_unlock(&my_obj->cam_lock);
1083    }
1084    return rc;
1085}
1086
1087int32_t mm_camera_async_teardown_streams(mm_camera_obj_t *my_obj,
1088                                          uint32_t ch_id,
1089                                          uint8_t num_streams,
1090                                          uint32_t *stream_ids)
1091{
1092    int32_t rc = 0;
1093    mm_evt_payload_stop_stream_t payload;
1094    mm_camera_cmdcb_t * node = NULL;
1095
1096    mm_channel_t * ch_obj =
1097        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1098
1099    if (NULL != ch_obj) {
1100        pthread_mutex_lock(&ch_obj->ch_lock);
1101        pthread_mutex_unlock(&my_obj->cam_lock);
1102
1103        /* enqueu asyn stop cmd to async_cmd_thread */
1104        node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
1105        if (NULL != node) {
1106            memset(node, 0, sizeof(mm_camera_cmdcb_t));
1107            node->cmd_type = MM_CAMERA_CMD_TYPE_ASYNC_CB;
1108            node->u.async.cmd_type = MM_CAMERA_ASYNC_CMD_TYPE_STOP;
1109            node->u.async.u.stop_cmd.ch_obj = ch_obj;
1110            node->u.async.u.stop_cmd.num_streams = num_streams;
1111            memcpy(node->u.async.u.stop_cmd.stream_ids, stream_ids, sizeof(uint32_t)*num_streams);
1112
1113            /* enqueue to async cmd thread */
1114            mm_camera_queue_enq(&(my_obj->async_cmd_thread.cmd_queue), node);
1115            /* wake up async cmd thread */
1116            sem_post(&(my_obj->async_cmd_thread.cmd_sem));
1117        } else {
1118            CDBG_ERROR("%s: No memory for mm_camera_cmdcb_t", __func__);
1119            pthread_mutex_unlock(&ch_obj->ch_lock);
1120            rc = -1;
1121            return rc;
1122        }
1123    } else {
1124        pthread_mutex_unlock(&my_obj->cam_lock);
1125    }
1126    return rc;
1127}
1128
1129int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1130                                    uint32_t ch_id,
1131                                    uint32_t num_buf_requested)
1132{
1133    int32_t rc = -1;
1134    mm_channel_t * ch_obj =
1135        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1136
1137    if (NULL != ch_obj) {
1138        pthread_mutex_lock(&ch_obj->ch_lock);
1139        pthread_mutex_unlock(&my_obj->cam_lock);
1140
1141        rc = mm_channel_fsm_fn(ch_obj,
1142                               MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
1143                               (void*)num_buf_requested,
1144                               NULL);
1145    } else {
1146        pthread_mutex_unlock(&my_obj->cam_lock);
1147    }
1148
1149    return rc;
1150}
1151
1152int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
1153{
1154    int32_t rc = -1;
1155    mm_channel_t * ch_obj =
1156        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1157
1158    if (NULL != ch_obj) {
1159        pthread_mutex_lock(&ch_obj->ch_lock);
1160        pthread_mutex_unlock(&my_obj->cam_lock);
1161
1162        rc = mm_channel_fsm_fn(ch_obj,
1163                               MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
1164                               NULL,
1165                               NULL);
1166    } else {
1167        pthread_mutex_unlock(&my_obj->cam_lock);
1168    }
1169
1170    return rc;
1171}
1172
1173int32_t mm_camera_start_focus(mm_camera_obj_t *my_obj,
1174                              uint32_t ch_id,
1175                              uint32_t sensor_idx,
1176                              uint32_t focus_mode)
1177{
1178    int32_t rc = -1;
1179    mm_evt_payload_start_focus_t payload;
1180    mm_channel_t * ch_obj =
1181        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1182
1183    if (NULL != ch_obj) {
1184        pthread_mutex_lock(&ch_obj->ch_lock);
1185        pthread_mutex_unlock(&my_obj->cam_lock);
1186
1187        memset(&payload, 0, sizeof(mm_evt_payload_start_focus_t));
1188        payload.sensor_idx = sensor_idx;
1189        payload.focus_mode = focus_mode;
1190        rc = mm_channel_fsm_fn(ch_obj,
1191                               MM_CHANNEL_EVT_START_FOCUS,
1192                               (void *)&payload,
1193                               NULL);
1194        if (0 != rc) {
1195            mm_camera_event_t event;
1196            event.event_type = MM_CAMERA_EVT_TYPE_CTRL;
1197            event.e.ctrl.evt = MM_CAMERA_CTRL_EVT_AUTO_FOCUS_DONE;
1198            event.e.ctrl.status = CAM_CTRL_FAILED;
1199            rc = mm_camera_enqueue_evt(my_obj, &event);
1200        }
1201    } else {
1202        pthread_mutex_unlock(&my_obj->cam_lock);
1203    }
1204
1205    return rc;
1206}
1207
1208int32_t mm_camera_abort_focus(mm_camera_obj_t *my_obj,
1209                              uint32_t ch_id,
1210                              uint32_t sensor_idx)
1211{
1212    int32_t rc = -1;
1213    mm_channel_t * ch_obj =
1214        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1215
1216    if (NULL != ch_obj) {
1217        pthread_mutex_lock(&ch_obj->ch_lock);
1218        pthread_mutex_unlock(&my_obj->cam_lock);
1219
1220        rc = mm_channel_fsm_fn(ch_obj,
1221                               MM_CHANNEL_EVT_ABORT_FOCUS,
1222                               (void*)sensor_idx,
1223                               NULL);
1224    } else {
1225        pthread_mutex_unlock(&my_obj->cam_lock);
1226    }
1227
1228    return rc;
1229}
1230
1231int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
1232                                   uint32_t ch_id,
1233                                   uint32_t sensor_idx)
1234{
1235    int32_t rc = -1;
1236    mm_channel_t * ch_obj =
1237        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1238
1239    if (NULL != ch_obj) {
1240        pthread_mutex_lock(&ch_obj->ch_lock);
1241        pthread_mutex_unlock(&my_obj->cam_lock);
1242
1243        rc = mm_channel_fsm_fn(ch_obj,
1244                               MM_CHANNEL_EVT_PREPARE_SNAPSHOT,
1245                               (void *)sensor_idx,
1246                               NULL);
1247    } else {
1248        pthread_mutex_unlock(&my_obj->cam_lock);
1249    }
1250
1251    return rc;
1252}
1253
1254int32_t mm_camera_set_stream_parm(mm_camera_obj_t *my_obj,
1255                                  uint32_t ch_id,
1256                                  uint32_t s_id,
1257                                  mm_camera_stream_parm_t parm_type,
1258                                  void* p_value)
1259{
1260    int32_t rc = -1;
1261    mm_evt_paylod_stream_parm_t payload;
1262    mm_channel_t * ch_obj =
1263        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1264
1265    if (NULL != ch_obj) {
1266        pthread_mutex_lock(&ch_obj->ch_lock);
1267        pthread_mutex_unlock(&my_obj->cam_lock);
1268
1269        memset(&payload,0,sizeof(mm_evt_paylod_stream_parm_t));
1270        payload.parm_type = parm_type;
1271        payload.value = p_value;
1272        rc = mm_channel_fsm_fn(ch_obj,
1273                               MM_CHANNEL_EVT_SET_STREAM_PARM,
1274                               (void *)s_id,
1275                               &payload);
1276    } else {
1277        pthread_mutex_unlock(&my_obj->cam_lock);
1278    }
1279
1280    return rc;
1281}
1282
1283int32_t mm_camera_get_stream_parm(mm_camera_obj_t *my_obj,
1284                                  uint32_t ch_id,
1285                                  uint32_t s_id,
1286                                  mm_camera_stream_parm_t parm_type,
1287                                  void* p_value)
1288{
1289    int32_t rc = -1;
1290    mm_evt_paylod_stream_parm_t payload;
1291    mm_channel_t * ch_obj =
1292        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1293
1294    if (NULL != ch_obj) {
1295        pthread_mutex_lock(&ch_obj->ch_lock);
1296        pthread_mutex_unlock(&my_obj->cam_lock);
1297
1298        memset(&payload,0,sizeof(mm_evt_paylod_stream_parm_t));
1299        payload.parm_type = parm_type;
1300        payload.value = p_value;
1301        rc = mm_channel_fsm_fn(ch_obj,
1302                               MM_CHANNEL_EVT_GET_STREAM_PARM,
1303                               (void *)s_id,
1304                               &payload);
1305    } else {
1306        pthread_mutex_unlock(&my_obj->cam_lock);
1307    }
1308
1309    return rc;
1310}
1311
1312int32_t mm_camera_send_private_ioctl(mm_camera_obj_t *my_obj,
1313                                     uint32_t cmd_id,
1314                                     uint32_t cmd_length,
1315                                     void *cmd)
1316{
1317    int32_t rc = -1;
1318
1319    struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
1320
1321    CDBG("%s: cmd = %p, length = %d",
1322               __func__, cmd, cmd_length);
1323    memset(&v4l2_ioctl, 0, sizeof(v4l2_ioctl));
1324    v4l2_ioctl.id = cmd_id;
1325    v4l2_ioctl.len = cmd_length;
1326    v4l2_ioctl.ioctl_ptr = cmd;
1327    rc = ioctl (my_obj->ctrl_fd, MSM_CAM_V4L2_IOCTL_PRIVATE_GENERAL, &v4l2_ioctl);
1328
1329    if(rc < 0) {
1330        CDBG_ERROR("%s: cmd = %p, id = %d, length = %d, rc = %d\n",
1331                   __func__, cmd, cmd_id, cmd_length, rc);
1332    } else {
1333        rc = 0;
1334    }
1335
1336    return rc;
1337}
1338
1339int32_t mm_camera_ctrl_set_specialEffect (mm_camera_obj_t *my_obj, int32_t effect) {
1340    struct v4l2_control ctrl;
1341    if (effect == CAMERA_EFFECT_MAX)
1342        effect = CAMERA_EFFECT_OFF;
1343    int rc = 0;
1344
1345    ctrl.id = MSM_V4L2_PID_EFFECT;
1346    ctrl.value = effect;
1347    rc = ioctl(my_obj->ctrl_fd, VIDIOC_S_CTRL, &ctrl);
1348    return (rc >= 0)? 0: -1;;
1349}
1350
1351int32_t mm_camera_ctrl_set_auto_focus (mm_camera_obj_t *my_obj, int32_t value)
1352{
1353    int32_t rc = 0;
1354    struct v4l2_queryctrl queryctrl;
1355
1356    memset (&queryctrl, 0, sizeof (queryctrl));
1357    queryctrl.id = V4L2_CID_FOCUS_AUTO;
1358
1359    if(value != 0 && value != 1) {
1360        CDBG("%s:boolean required, invalid value = %d\n",__func__, value);
1361        return -1;
1362    }
1363    if (-1 == ioctl (my_obj->ctrl_fd, VIDIOC_QUERYCTRL, &queryctrl)) {
1364        CDBG ("V4L2_CID_FOCUS_AUTO is not supported\n");
1365    } else if (queryctrl.flags & V4L2_CTRL_FLAG_DISABLED) {
1366        CDBG ("%s:V4L2_CID_FOCUS_AUTO is not supported\n", __func__);
1367    } else {
1368        if(0 != (rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1369                V4L2_CID_FOCUS_AUTO, value))){
1370            CDBG("%s: error, id=0x%x, value=%d, rc = %d\n",
1371                     __func__, V4L2_CID_FOCUS_AUTO, value, rc);
1372            rc = -1;
1373        }
1374    }
1375    return rc;
1376}
1377
1378int32_t mm_camera_ctrl_set_whitebalance (mm_camera_obj_t *my_obj, int32_t mode) {
1379
1380    int32_t rc = 0, auto_wb, temperature;
1381    uint32_t id_auto_wb, id_temperature;
1382
1383    id_auto_wb = V4L2_CID_AUTO_WHITE_BALANCE;
1384    id_temperature = V4L2_CID_WHITE_BALANCE_TEMPERATURE;
1385
1386    switch(mode) {
1387    case CAMERA_WB_DAYLIGHT:
1388        auto_wb = 0;
1389        temperature = 6500;
1390        break;
1391    case CAMERA_WB_INCANDESCENT:
1392        auto_wb = 0;
1393        temperature = 2800;
1394        break;
1395    case CAMERA_WB_FLUORESCENT:
1396        auto_wb = 0;
1397        temperature = 4200;
1398        break;
1399    case CAMERA_WB_CLOUDY_DAYLIGHT:
1400        auto_wb = 0;
1401        temperature = 7500;
1402        break;
1403    case CAMERA_WB_AUTO:
1404    default:
1405        auto_wb = 1; /* TRUE */
1406        temperature = 0;
1407        break;
1408    }
1409
1410    rc =  mm_camera_util_s_ctrl(my_obj->ctrl_fd, id_auto_wb, auto_wb);
1411    if(0 != rc){
1412        CDBG_ERROR("%s: error, V4L2_CID_AUTO_WHITE_BALANCE value = %d, rc = %d\n",
1413            __func__, auto_wb, rc);
1414        return rc;
1415    }
1416    if (!auto_wb) {
1417        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, id_temperature, temperature);
1418        if (0 != rc) {
1419            CDBG_ERROR("%s: error, V4L2_CID_WHITE_BALANCE_TEMPERATURE value = %d, rc = %d\n",
1420                __func__, temperature, rc);
1421            return rc;
1422        }
1423    }
1424    return rc;
1425}
1426
1427int32_t mm_camera_set_general_parm(mm_camera_obj_t * my_obj,
1428                                   mm_camera_parm_type_t parm_type,
1429                                   void* p_value)
1430{
1431    int rc = -1;
1432    int isZSL =0;
1433
1434    switch(parm_type)  {
1435    case MM_CAMERA_PARM_EXPOSURE:
1436        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1437                                   MSM_V4L2_PID_EXP_METERING,
1438                                   *((int32_t *)p_value));
1439        break;
1440    case MM_CAMERA_PARM_SHARPNESS:
1441        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1442                                   V4L2_CID_SHARPNESS,
1443                                   *((int32_t *)p_value));
1444        break;
1445    case MM_CAMERA_PARM_CONTRAST:
1446        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1447                                   V4L2_CID_CONTRAST,
1448                                   *((int32_t *)p_value));
1449        break;
1450    case MM_CAMERA_PARM_SATURATION:
1451        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1452                                   V4L2_CID_SATURATION,
1453                                   *((int32_t *)p_value));
1454        break;
1455    case MM_CAMERA_PARM_BRIGHTNESS:
1456        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1457                                   V4L2_CID_BRIGHTNESS,
1458                                   *((int32_t *)p_value));
1459        break;
1460    case MM_CAMERA_PARM_WHITE_BALANCE:
1461        rc = mm_camera_ctrl_set_whitebalance (my_obj, *((int32_t *)p_value));
1462        break;
1463    case MM_CAMERA_PARM_ISO:
1464        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1465                                   MSM_V4L2_PID_ISO,
1466                                   *((int32_t *)p_value));
1467        break;
1468    case MM_CAMERA_PARM_ZOOM:
1469        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1470                                   V4L2_CID_ZOOM_ABSOLUTE,
1471                                   *((int32_t *)p_value));
1472        break;
1473    case MM_CAMERA_PARM_LUMA_ADAPTATION:
1474        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1475                                   MSM_V4L2_PID_LUMA_ADAPTATION,
1476                                   *((int32_t *)p_value));
1477        break;
1478    case MM_CAMERA_PARM_ANTIBANDING:
1479        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1480                                   V4L2_CID_POWER_LINE_FREQUENCY,
1481                                   *((int32_t *)p_value));
1482        break;
1483    case MM_CAMERA_PARM_CONTINUOUS_AF:
1484        rc = mm_camera_ctrl_set_auto_focus(my_obj,
1485                                           *((int32_t *)p_value));
1486        break;
1487    case MM_CAMERA_PARM_HJR:
1488        rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
1489                                   MSM_V4L2_PID_HJR,
1490                                   *((int32_t *)p_value));
1491        break;
1492    case MM_CAMERA_PARM_EFFECT:
1493        rc = mm_camera_ctrl_set_specialEffect (my_obj,
1494                                               *((int32_t *)p_value));
1495        break;
1496    case MM_CAMERA_PARM_FPS:
1497        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1498                                            CAMERA_SET_PARM_FPS,
1499                                            sizeof(uint32_t),
1500                                            p_value);
1501        break;
1502    case MM_CAMERA_PARM_FPS_MODE:
1503        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1504                                            CAMERA_SET_FPS_MODE,
1505                                            sizeof(int32_t),
1506                                            p_value);
1507        break;
1508    case MM_CAMERA_PARM_EXPOSURE_COMPENSATION:
1509        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1510                                            CAMERA_SET_PARM_EXPOSURE_COMPENSATION,
1511                                            sizeof(int32_t),
1512                                            p_value);
1513        break;
1514    case MM_CAMERA_PARM_LED_MODE:
1515        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1516                                            CAMERA_SET_PARM_LED_MODE,
1517                                            sizeof(int32_t),
1518                                            p_value);
1519        break;
1520    case MM_CAMERA_PARM_ROLLOFF:
1521        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1522                                            CAMERA_SET_PARM_ROLLOFF,
1523                                            sizeof(int32_t),
1524                                            p_value);
1525        break;
1526    case MM_CAMERA_PARM_MODE:
1527        my_obj->current_mode = *((camera_mode_t *)p_value);
1528        break;
1529    case MM_CAMERA_PARM_FOCUS_RECT:
1530        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1531                                            CAMERA_SET_PARM_FOCUS_RECT,
1532                                            sizeof(int32_t),
1533                                            p_value);
1534        break;
1535    case MM_CAMERA_PARM_AEC_ROI:
1536        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1537                                            CAMERA_SET_PARM_AEC_ROI,
1538                                            sizeof(cam_set_aec_roi_t),
1539                                            p_value);
1540        break;
1541    case MM_CAMERA_PARM_AF_ROI:
1542        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1543                                            CAMERA_SET_PARM_AF_ROI,
1544                                            sizeof(roi_info_t),
1545                                            p_value);
1546        break;
1547    case MM_CAMERA_PARM_FOCUS_MODE:
1548        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1549                                            CAMERA_SET_PARM_AF_MODE,
1550                                            sizeof(int32_t),
1551                                            p_value);
1552        break;
1553#if 0 /* to be enabled later: @punits */
1554    case MM_CAMERA_PARM_AF_MTR_AREA:
1555        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1556                                            CAMERA_SET_PARM_AF_MTR_AREA,
1557                                            sizeof(af_mtr_area_t),
1558                                            p_value);
1559        break;
1560    case MM_CAMERA_PARM_AEC_MTR_AREA:
1561        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1562                                            CAMERA_SET_AEC_MTR_AREA,
1563                                            sizeof(aec_mtr_area_t),
1564                                            p_value);
1565        break;
1566#endif
1567    case MM_CAMERA_PARM_CAF_ENABLE:
1568        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1569                                            CAMERA_SET_PARM_CAF,
1570                                            sizeof(uint32_t),
1571                                            p_value);
1572        break;
1573    case MM_CAMERA_PARM_BESTSHOT_MODE:
1574        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1575                                            CAMERA_SET_PARM_BESTSHOT_MODE,
1576                                            sizeof(int32_t),
1577                                            p_value);
1578        break;
1579    case MM_CAMERA_PARM_VIDEO_DIS:
1580        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1581                                            CAMERA_SET_VIDEO_DIS_PARAMS,
1582                                            sizeof(video_dis_param_ctrl_t),
1583                                            p_value);
1584        break;
1585    case MM_CAMERA_PARM_VIDEO_ROT:
1586        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1587                                            CAMERA_SET_VIDEO_ROT_PARAMS,
1588                                            sizeof(video_rotation_param_ctrl_t),
1589                                            p_value);
1590        break;
1591    case MM_CAMERA_PARM_SCE_FACTOR:
1592        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1593                                            CAMERA_SET_SCE_FACTOR,
1594                                            sizeof(int32_t),
1595                                            p_value);
1596        break;
1597    case MM_CAMERA_PARM_FD:
1598        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1599                                            CAMERA_SET_PARM_FD,
1600                                            sizeof(fd_set_parm_t),
1601                                            p_value);
1602        break;
1603    case MM_CAMERA_PARM_AEC_LOCK:
1604        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1605                                            CAMERA_SET_AEC_LOCK,
1606                                            sizeof(int32_t),
1607                                            p_value);
1608        break;
1609    case MM_CAMERA_PARM_AWB_LOCK:
1610        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1611                                            CAMERA_SET_AWB_LOCK,
1612                                            sizeof(int32_t),
1613                                            p_value);
1614        break;
1615    case MM_CAMERA_PARM_MCE:
1616        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1617                                            CAMERA_SET_PARM_MCE,
1618                                            sizeof(int32_t),
1619                                            p_value);
1620        break;
1621    case MM_CAMERA_PARM_HORIZONTAL_VIEW_ANGLE:
1622        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1623                                            CAMERA_GET_PARM_HORIZONTAL_VIEW_ANGLE,
1624                                            sizeof(focus_distances_info_t),
1625                                            p_value);
1626        break;
1627    case MM_CAMERA_PARM_VERTICAL_VIEW_ANGLE:
1628        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1629                                            CAMERA_GET_PARM_VERTICAL_VIEW_ANGLE,
1630                                            sizeof(focus_distances_info_t),
1631                                            p_value);
1632        break;
1633    case MM_CAMERA_PARM_RESET_LENS_TO_INFINITY:
1634        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1635                                            CAMERA_SET_PARM_RESET_LENS_TO_INFINITY,
1636                                            0, NULL);
1637        break;
1638    case MM_CAMERA_PARM_SNAPSHOTDATA:
1639        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1640                                            CAMERA_GET_PARM_SNAPSHOTDATA,
1641                                            sizeof(snapshotData_info_t),
1642                                            p_value);
1643        break;
1644    case MM_CAMERA_PARM_HFR:
1645        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1646                                            CAMERA_SET_PARM_HFR,
1647                                            sizeof(int32_t),
1648                                            p_value);
1649        break;
1650    case MM_CAMERA_PARM_REDEYE_REDUCTION:
1651        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1652                                            CAMERA_SET_REDEYE_REDUCTION,
1653                                            sizeof(int32_t),
1654                                            p_value);
1655        break;
1656    case MM_CAMERA_PARM_WAVELET_DENOISE:
1657        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1658                                            CAMERA_SET_PARM_WAVELET_DENOISE,
1659                                            sizeof(denoise_param_t),
1660                                            p_value);
1661        break;
1662    case MM_CAMERA_PARM_3D_DISPLAY_DISTANCE:
1663        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1664                                            CAMERA_SET_PARM_3D_DISPLAY_DISTANCE,
1665                                            sizeof(float),
1666                                            p_value);
1667        break;
1668    case MM_CAMERA_PARM_3D_VIEW_ANGLE:
1669        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1670                                            CAMERA_SET_PARM_3D_VIEW_ANGLE,
1671                                            sizeof(uint32_t),
1672                                            p_value);
1673        break;
1674    case MM_CAMERA_PARM_ZOOM_RATIO:
1675        break;
1676    case MM_CAMERA_PARM_HISTOGRAM:
1677        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1678                                            CAMERA_SET_PARM_HISTOGRAM,
1679                                            sizeof(int8_t),
1680                                            p_value);
1681        break;
1682    case MM_CAMERA_PARM_ASD_ENABLE:
1683        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1684                                          CAMERA_SET_ASD_ENABLE,
1685                                          sizeof(uint32_t),
1686                                          p_value);
1687        break;
1688    case MM_CAMERA_PARM_RECORDING_HINT:
1689        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1690                                            CAMERA_SET_RECORDING_HINT,
1691                                            sizeof(uint32_t),
1692                                            p_value);
1693        break;
1694    case MM_CAMERA_PARM_PREVIEW_FORMAT:
1695        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1696                                            CAMERA_SET_PARM_PREVIEW_FORMAT,
1697                                            sizeof(uint32_t),
1698                                            p_value);
1699        break;
1700    /* TODO: need code review to determine any of the three is redundent
1701     * MM_CAMERA_PARM_DIS_ENABLE,
1702     * MM_CAMERA_PARM_FULL_LIVESHOT,
1703     * MM_CAMERA_PARM_LOW_POWER_MODE*/
1704    case MM_CAMERA_PARM_DIS_ENABLE:
1705        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1706                                            CAMERA_SET_DIS_ENABLE,
1707                                            sizeof(uint32_t),
1708                                            p_value);
1709        break;
1710    case MM_CAMERA_PARM_FULL_LIVESHOT:
1711        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1712                                            CAMERA_SET_FULL_LIVESHOT,
1713                                            sizeof(uint32_t),
1714                                            p_value);
1715        break;
1716    case MM_CAMERA_PARM_LOW_POWER_MODE:
1717        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1718                                            CAMERA_SET_LOW_POWER_MODE,
1719                                            sizeof(uint32_t),
1720                                            p_value);
1721        break;
1722    case MM_CAMERA_PARM_HDR:
1723        rc = mm_camera_send_native_ctrl_cmd(my_obj,
1724                                            CAMERA_SET_PARM_HDR,
1725                                            sizeof(exp_bracketing_t),
1726                                            p_value);
1727        break;
1728    default:
1729        CDBG("%s: default: parm %d not supported\n", __func__, parm_type);
1730        break;
1731    }
1732    return rc;
1733}
1734
1735int32_t mm_camera_util_private_s_ctrl(int32_t fd, uint32_t id, void* value)
1736{
1737    int rc = -1;
1738    struct msm_camera_v4l2_ioctl_t v4l2_ioctl;
1739
1740    memset(&v4l2_ioctl, 0, sizeof(v4l2_ioctl));
1741    v4l2_ioctl.id = id;
1742    v4l2_ioctl.ioctl_ptr = value;
1743    rc = ioctl (fd, MSM_CAM_V4L2_IOCTL_PRIVATE_S_CTRL, &v4l2_ioctl);
1744
1745    if(rc < 0) {
1746        CDBG_ERROR("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
1747                   __func__, fd, id, (uint32_t)value, rc);
1748        rc = -1;
1749    } else {
1750        rc = 0;
1751    }
1752    return rc;
1753}
1754
1755int32_t mm_camera_send_native_ctrl_cmd(mm_camera_obj_t * my_obj,
1756                                              cam_ctrl_type type,
1757                                              uint32_t length,
1758                                              void *value)
1759{
1760    return mm_camera_send_native_ctrl_timeout_cmd(my_obj, type,
1761                                                  length, value,
1762                                                  1000);
1763}
1764
1765int32_t mm_camera_send_native_ctrl_timeout_cmd(mm_camera_obj_t * my_obj,
1766                                                      cam_ctrl_type type,
1767                                                      uint32_t length,
1768                                                      void *value,
1769                                                      int timeout)
1770{
1771    int rc = -1;
1772    struct msm_ctrl_cmd ctrl_cmd;
1773
1774    memset(&ctrl_cmd, 0, sizeof(ctrl_cmd));
1775    ctrl_cmd.type = type;
1776    ctrl_cmd.length = (uint16_t)length;
1777    ctrl_cmd.timeout_ms = timeout;
1778    ctrl_cmd.value = value;
1779    ctrl_cmd.status = (uint16_t)CAM_CTRL_SUCCESS;
1780    rc = mm_camera_util_private_s_ctrl(my_obj->ctrl_fd,
1781                               MSM_V4L2_PID_CTRL_CMD,
1782                               (void*)&ctrl_cmd);
1783    CDBG("%s: type=%d, rc = %d, status = %d\n",
1784        __func__, type, rc, ctrl_cmd.status);
1785    if(rc != 0 || ((ctrl_cmd.status != CAM_CTRL_ACCEPTED) &&
1786        (ctrl_cmd.status != CAM_CTRL_SUCCESS) &&
1787        (ctrl_cmd.status != CAM_CTRL_INVALID_PARM)))
1788        rc = -1;
1789    return rc;
1790}
1791
1792int mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1793                      mm_camera_event_type_t evt_type,
1794                      int reg_count)
1795{
1796    int rc = 0;
1797    struct v4l2_event_subscription sub;
1798
1799    memset(&sub, 0, sizeof(sub));
1800    sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_EVENT;
1801    if(reg_count == 0) {
1802        /* unsubscribe */
1803        if(my_obj->evt_type_mask == (uint32_t)(1 << evt_type)) {
1804            rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1805            CDBG("%s: unsubscribe event 0x%x, rc = %d", __func__, sub.type, rc);
1806            sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_ERROR_EVENT;
1807            rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1808            CDBG("%s: unsubscribe event 0x%x, rc = %d", __func__, sub.type, rc);
1809        }
1810        my_obj->evt_type_mask &= ~(1 << evt_type);
1811        if(my_obj->evt_type_mask == 0) {
1812            /* remove evt fd from the polling thraed when unreg the last event */
1813            mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread, my_obj->my_hdl);
1814        }
1815    } else {
1816        if(!my_obj->evt_type_mask) {
1817            /* this is the first reg event */
1818            rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1819            CDBG("%s: subscribe event 0x%x, rc = %d", __func__, sub.type, rc);
1820            if (rc < 0)
1821                goto end;
1822            sub.type = V4L2_EVENT_PRIVATE_START+MSM_CAM_APP_NOTIFY_ERROR_EVENT;
1823            rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1824            CDBG("%s: subscribe event 0x%x, rc = %d", __func__, sub.type, rc);
1825            if (rc < 0)
1826                goto end;
1827        }
1828        my_obj->evt_type_mask |= (1 << evt_type);
1829        if(my_obj->evt_type_mask == (uint32_t)(1 << evt_type)) {
1830            /* add evt fd to polling thread when subscribe the first event */
1831            rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1832                                                   my_obj->my_hdl,
1833                                                   my_obj->ctrl_fd,
1834                                                   mm_camera_event_notify,
1835                                                   (void*)my_obj);
1836        }
1837    }
1838end:
1839    return rc;
1840}
1841
1842int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj, void *msg, uint32_t buf_size, int sendfd)
1843{
1844    return mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd);
1845}
1846
1847int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1848                          int ext_mode,
1849                          int idx,
1850                          int fd,
1851                          uint32_t size)
1852{
1853    cam_sock_packet_t packet;
1854    memset(&packet, 0, sizeof(cam_sock_packet_t));
1855    packet.msg_type = CAM_SOCK_MSG_TYPE_FD_MAPPING;
1856    packet.payload.frame_fd_map.ext_mode = ext_mode;
1857    packet.payload.frame_fd_map.frame_idx = idx;
1858    packet.payload.frame_fd_map.fd = fd;
1859    packet.payload.frame_fd_map.size = size;
1860
1861    return mm_camera_util_sendmsg(my_obj, &packet,
1862                                  sizeof(cam_sock_packet_t),
1863                                  packet.payload.frame_fd_map.fd);
1864}
1865
1866int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
1867                            int ext_mode,
1868                            int idx)
1869{
1870    cam_sock_packet_t packet;
1871    memset(&packet, 0, sizeof(cam_sock_packet_t));
1872    packet.msg_type = CAM_SOCK_MSG_TYPE_FD_UNMAPPING;
1873    packet.payload.frame_fd_unmap.ext_mode = ext_mode;
1874    packet.payload.frame_fd_unmap.frame_idx = idx;
1875    return mm_camera_util_sendmsg(my_obj, &packet,
1876                                  sizeof(cam_sock_packet_t),
1877                                  packet.payload.frame_fd_map.fd);
1878}
1879
1880int32_t mm_camera_util_s_ctrl(int32_t fd,  uint32_t id, int32_t value)
1881{
1882    int rc = 0;
1883    struct v4l2_control control;
1884
1885    memset(&control, 0, sizeof(control));
1886    control.id = id;
1887    control.value = value;
1888    rc = ioctl (fd, VIDIOC_S_CTRL, &control);
1889
1890    CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
1891         __func__, fd, id, (uint32_t)value, rc);
1892    return (rc >= 0)? 0 : -1;
1893}
1894
1895int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
1896{
1897    int rc = 0;
1898    struct v4l2_control control;
1899
1900    memset(&control, 0, sizeof(control));
1901    control.id = id;
1902    control.value = (int32_t)value;
1903    rc = ioctl (fd, VIDIOC_G_CTRL, &control);
1904    *value = control.value;
1905    CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc);
1906    return (rc >= 0)? 0 : -1;
1907}
1908
1909uint8_t mm_camera_util_get_pp_mask(mm_camera_obj_t *my_obj)
1910{
1911    uint8_t pp_mask = 0;
1912    int32_t rc = 0;
1913
1914    /* query pp mask from mctl */
1915    rc = mm_camera_send_native_ctrl_cmd(my_obj,
1916                                        CAMERA_GET_PP_MASK,
1917                                        sizeof(uint8_t),
1918                                        (void *)&pp_mask);
1919    if (0 != rc) {
1920        CDBG_ERROR("%s: error getting post processing mask (rc=%d)",
1921                   __func__, rc);
1922    }
1923
1924    return pp_mask;
1925}
1926
1927int32_t mm_camera_open_repro_isp(mm_camera_obj_t *my_obj,
1928                                 uint32_t ch_id,
1929                                 mm_camera_repro_isp_type_t repro_isp_type,
1930                                 uint32_t *repro_isp_handle)
1931{
1932    int32_t rc = -1;
1933    uint32_t repro_hdl = 0;
1934    mm_channel_t * ch_obj =
1935        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1936
1937    if (NULL != ch_obj) {
1938        pthread_mutex_lock(&ch_obj->ch_lock);
1939        pthread_mutex_unlock(&my_obj->cam_lock);
1940
1941        rc = mm_channel_fsm_fn(ch_obj,
1942                               MM_CHANNEL_EVT_OPEN_REPRO_ISP,
1943                               (void*)repro_isp_type,
1944                               (void*)&repro_hdl);
1945    } else {
1946        pthread_mutex_unlock(&my_obj->cam_lock);
1947        CDBG_ERROR("%s: no channel obj exist", __func__);
1948    }
1949
1950    if (NULL != repro_isp_handle) {
1951        *repro_isp_handle = repro_hdl;
1952    }
1953    return rc;
1954}
1955
1956int32_t mm_camera_config_repro_isp(mm_camera_obj_t *my_obj,
1957                                   uint32_t ch_id,
1958                                   uint32_t repro_isp_handle,
1959                                   mm_camera_repro_isp_config_t *config)
1960{
1961    int32_t rc = -1;
1962    mm_channel_t * ch_obj =
1963        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1964    mm_evt_paylod_config_repro_isp_t payload;
1965
1966    if (NULL != ch_obj) {
1967        pthread_mutex_lock(&ch_obj->ch_lock);
1968        pthread_mutex_unlock(&my_obj->cam_lock);
1969
1970        memset(&payload, 0, sizeof(mm_evt_paylod_config_repro_isp_t));
1971        payload.repro_isp_handle = repro_isp_handle;
1972        payload.config = config;
1973        rc = mm_channel_fsm_fn(ch_obj,
1974                               MM_CHANNEL_EVT_CONFIG_REPRO_ISP,
1975                               (void*)&payload,
1976                               NULL);
1977    } else {
1978        pthread_mutex_unlock(&my_obj->cam_lock);
1979        CDBG_ERROR("%s: no channel obj exist", __func__);
1980    }
1981
1982    return rc;
1983}
1984
1985int32_t mm_camera_attach_stream_to_repro_isp(mm_camera_obj_t *my_obj,
1986                                             uint32_t ch_id,
1987                                             uint32_t repro_isp_handle,
1988                                             uint32_t stream_id)
1989{
1990    int32_t rc = -1;
1991    mm_channel_t * ch_obj =
1992        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1993    mm_evt_paylod_stream_to_repro_isp_t payload;
1994
1995    if (NULL != ch_obj) {
1996        pthread_mutex_lock(&ch_obj->ch_lock);
1997        pthread_mutex_unlock(&my_obj->cam_lock);
1998
1999        memset(&payload, 0, sizeof(mm_evt_paylod_stream_to_repro_isp_t));
2000        payload.repro_isp_handle = repro_isp_handle;
2001        payload.stream_id = stream_id;
2002        rc = mm_channel_fsm_fn(ch_obj,
2003                               MM_CHANNEL_EVT_ATTACH_STREAM_TO_REPRO_ISP,
2004                               (void*)&payload,
2005                               NULL);
2006    } else {
2007        pthread_mutex_unlock(&my_obj->cam_lock);
2008        CDBG_ERROR("%s: no channel obj exist", __func__);
2009    }
2010
2011    return rc;
2012}
2013
2014int32_t mm_camera_start_repro_isp(mm_camera_obj_t *my_obj,
2015                                  uint32_t ch_id,
2016                                  uint32_t repro_isp_handle,
2017                                  uint32_t stream_id)
2018{
2019    int32_t rc = -1;
2020    mm_evt_paylod_repro_start_stop_t payload;
2021    mm_channel_t * ch_obj =
2022        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2023
2024    if (NULL != ch_obj) {
2025        pthread_mutex_lock(&ch_obj->ch_lock);
2026        pthread_mutex_unlock(&my_obj->cam_lock);
2027
2028        memset(&payload, 0, sizeof(mm_evt_paylod_repro_start_stop_t));
2029        payload.repro_isp_handle = repro_isp_handle;
2030        payload.stream_id = stream_id;
2031        rc = mm_channel_fsm_fn(ch_obj,
2032                               MM_CHANNEL_EVT_START_REPRO_ISP,
2033                               (void*)&payload,
2034                               NULL);
2035    } else {
2036        pthread_mutex_unlock(&my_obj->cam_lock);
2037        CDBG_ERROR("%s: no channel obj exist", __func__);
2038    }
2039
2040    return rc;
2041}
2042
2043int32_t mm_camera_reprocess(mm_camera_obj_t *my_obj,
2044                            uint32_t ch_id,
2045                            uint32_t repro_isp_handle,
2046                            mm_camera_repro_data_t *repro_data)
2047{
2048    int32_t rc = -1;
2049    mm_channel_t * ch_obj =
2050        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2051    mm_evt_paylod_reprocess_t payload;
2052
2053    if (NULL != ch_obj) {
2054        pthread_mutex_lock(&ch_obj->ch_lock);
2055        pthread_mutex_unlock(&my_obj->cam_lock);
2056
2057        memset(&payload, 0, sizeof(mm_evt_paylod_reprocess_t));
2058        payload.repro_isp_handle = repro_isp_handle;
2059        payload.repro_data = repro_data;
2060        rc = mm_channel_fsm_fn(ch_obj,
2061                               MM_CHANNEL_EVT_ATTACH_STREAM_TO_REPRO_ISP,
2062                               (void*)&payload,
2063                               NULL);
2064    } else {
2065        pthread_mutex_unlock(&my_obj->cam_lock);
2066        CDBG_ERROR("%s: no channel obj exist", __func__);
2067    }
2068
2069    return rc;
2070}
2071
2072int32_t mm_camera_stop_repro_isp(mm_camera_obj_t *my_obj,
2073                                 uint32_t ch_id,
2074                                 uint32_t repro_isp_handle,
2075                                 uint32_t stream_id)
2076{
2077    int32_t rc = -1;
2078    mm_evt_paylod_repro_start_stop_t payload;
2079    mm_channel_t * ch_obj =
2080        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2081
2082    if (NULL != ch_obj) {
2083        pthread_mutex_lock(&ch_obj->ch_lock);
2084        pthread_mutex_unlock(&my_obj->cam_lock);
2085
2086        memset(&payload, 0, sizeof(mm_evt_paylod_repro_start_stop_t));
2087        payload.repro_isp_handle = repro_isp_handle;
2088        payload.stream_id = stream_id;
2089        rc = mm_channel_fsm_fn(ch_obj,
2090                               MM_CHANNEL_EVT_STOP_REPRO_ISP,
2091                               (void*)&payload,
2092                               NULL);
2093    } else {
2094        pthread_mutex_unlock(&my_obj->cam_lock);
2095        CDBG_ERROR("%s: no channel obj exist", __func__);
2096    }
2097
2098    return rc;
2099}
2100
2101int32_t mm_camera_detach_stream_from_repro_isp(mm_camera_obj_t *my_obj,
2102                                               uint32_t ch_id,
2103                                               uint32_t repro_isp_handle,
2104                                               uint32_t stream_id)
2105{
2106    int32_t rc = -1;
2107    mm_channel_t * ch_obj =
2108        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2109    mm_evt_paylod_stream_to_repro_isp_t payload;
2110
2111    if (NULL != ch_obj) {
2112        pthread_mutex_lock(&ch_obj->ch_lock);
2113        pthread_mutex_unlock(&my_obj->cam_lock);
2114
2115        memset(&payload, 0, sizeof(mm_evt_paylod_stream_to_repro_isp_t));
2116        payload.repro_isp_handle = repro_isp_handle;
2117        payload.stream_id = stream_id;
2118        rc = mm_channel_fsm_fn(ch_obj,
2119                               MM_CHANNEL_EVT_DETACH_STREAM_FROM_REPRO_ISP,
2120                               (void*)&payload,
2121                               NULL);
2122    } else {
2123        pthread_mutex_unlock(&my_obj->cam_lock);
2124        CDBG_ERROR("%s: no channel obj exist", __func__);
2125    }
2126
2127    return rc;
2128}
2129
2130int32_t mm_camera_close_repro_isp(mm_camera_obj_t *my_obj,
2131                                  uint32_t ch_id,
2132                                  uint32_t repro_isp_handle)
2133{
2134    int32_t rc = -1;
2135    mm_channel_t * ch_obj =
2136        mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2137
2138    if (NULL != ch_obj) {
2139        pthread_mutex_lock(&ch_obj->ch_lock);
2140        pthread_mutex_unlock(&my_obj->cam_lock);
2141
2142        rc = mm_channel_fsm_fn(ch_obj,
2143                               MM_CHANNEL_EVT_CLOSE_REPRO_ISP,
2144                               (void*)repro_isp_handle,
2145                               NULL);
2146    } else {
2147        pthread_mutex_unlock(&my_obj->cam_lock);
2148        CDBG_ERROR("%s: no channel obj exist", __func__);
2149    }
2150
2151    return rc;
2152}
2153