• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2012-2013, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #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 
38 #include <cam_semaphore.h>
39 
40 #include "mm_camera_dbg.h"
41 #include "mm_camera_sock.h"
42 #include "mm_camera_interface.h"
43 #include "mm_camera.h"
44 
45 #define SET_PARM_BIT32(parm, parm_arr) \
46     (parm_arr[parm/32] |= (1<<(parm%32)))
47 
48 #define GET_PARM_BIT32(parm, parm_arr) \
49     ((parm_arr[parm/32]>>(parm%32))& 0x1)
50 
51 /* internal function declare */
52 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
53                           uint8_t reg_flag);
54 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
55                               mm_camera_event_t *event);
56 
57 /*===========================================================================
58  * FUNCTION   : mm_camera_util_get_channel_by_handler
59  *
60  * DESCRIPTION: utility function to get a channel object from its handle
61  *
62  * PARAMETERS :
63  *   @cam_obj: ptr to a camera object
64  *   @handler: channel handle
65  *
66  * RETURN     : ptr to a channel object.
67  *              NULL if failed.
68  *==========================================================================*/
mm_camera_util_get_channel_by_handler(mm_camera_obj_t * cam_obj,uint32_t handler)69 mm_channel_t * mm_camera_util_get_channel_by_handler(
70                                     mm_camera_obj_t * cam_obj,
71                                     uint32_t handler)
72 {
73     int i;
74     mm_channel_t *ch_obj = NULL;
75     for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
76         if (handler == cam_obj->ch[i].my_hdl) {
77             ch_obj = &cam_obj->ch[i];
78             break;
79         }
80     }
81     return ch_obj;
82 }
83 
84 /*===========================================================================
85  * FUNCTION   : mm_camera_util_chip_is_a_family
86  *
87  * DESCRIPTION: utility function to check if the host is A family chip
88  *
89  * PARAMETERS :
90  *
91  * RETURN     : TRUE if A family.
92  *              FALSE otherwise.
93  *==========================================================================*/
mm_camera_util_chip_is_a_family(void)94 uint8_t mm_camera_util_chip_is_a_family(void)
95 {
96 #ifdef USE_A_FAMILY
97     return TRUE;
98 #else
99     return FALSE;
100 #endif
101 }
102 
103 /*===========================================================================
104  * FUNCTION   : mm_camera_dispatch_app_event
105  *
106  * DESCRIPTION: dispatch event to apps who regitster for event notify
107  *
108  * PARAMETERS :
109  *   @cmd_cb: ptr to a struct storing event info
110  *   @user_data: user data ptr (camera object)
111  *
112  * RETURN     : none
113  *==========================================================================*/
mm_camera_dispatch_app_event(mm_camera_cmdcb_t * cmd_cb,void * user_data)114 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
115                                          void* user_data)
116 {
117     mm_camera_cmd_thread_name("mm_cam_event");
118     int i;
119     mm_camera_event_t *event = &cmd_cb->u.evt;
120     mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data;
121     if (NULL != my_obj) {
122         pthread_mutex_lock(&my_obj->cb_lock);
123         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
124             if(my_obj->evt.evt[i].evt_cb) {
125                 my_obj->evt.evt[i].evt_cb(
126                     my_obj->my_hdl,
127                     event,
128                     my_obj->evt.evt[i].user_data);
129             }
130         }
131         pthread_mutex_unlock(&my_obj->cb_lock);
132     }
133 }
134 
135 /*===========================================================================
136  * FUNCTION   : mm_camera_event_notify
137  *
138  * DESCRIPTION: callback to handle event notify from kernel. This call will
139  *              dequeue event from kernel.
140  *
141  * PARAMETERS :
142  *   @user_data: user data ptr (camera object)
143  *
144  * RETURN     : none
145  *==========================================================================*/
mm_camera_event_notify(void * user_data)146 static void mm_camera_event_notify(void* user_data)
147 {
148     struct v4l2_event ev;
149     struct msm_v4l2_event_data *msm_evt = NULL;
150     int rc;
151     mm_camera_event_t evt;
152     memset(&evt, 0, sizeof(mm_camera_event_t));
153 
154     mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
155     if (NULL != my_obj) {
156         /* read evt */
157         memset(&ev, 0, sizeof(ev));
158         rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
159 
160         if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
161             msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
162             switch (msm_evt->command) {
163             case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
164                 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ;
165                 mm_camera_enqueue_evt(my_obj, &evt);
166                 break;
167             case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
168                 pthread_mutex_lock(&my_obj->evt_lock);
169                 my_obj->evt_rcvd.server_event_type = msm_evt->command;
170                 my_obj->evt_rcvd.status = msm_evt->status;
171                 pthread_cond_signal(&my_obj->evt_cond);
172                 pthread_mutex_unlock(&my_obj->evt_lock);
173                 break;
174             case MSM_CAMERA_PRIV_SHUTDOWN:
175                 {
176                     evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
177                     mm_camera_enqueue_evt(my_obj, &evt);
178                 }
179                 break;
180             default:
181                 break;
182             }
183         }
184     }
185 }
186 
187 /*===========================================================================
188  * FUNCTION   : mm_camera_enqueue_evt
189  *
190  * DESCRIPTION: enqueue received event into event queue to be processed by
191  *              event thread.
192  *
193  * PARAMETERS :
194  *   @my_obj   : ptr to a camera object
195  *   @event    : event to be queued
196  *
197  * RETURN     : int32_t type of status
198  *              0  -- success
199  *              -1 -- failure
200  *==========================================================================*/
mm_camera_enqueue_evt(mm_camera_obj_t * my_obj,mm_camera_event_t * event)201 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
202                               mm_camera_event_t *event)
203 {
204     int32_t rc = 0;
205     mm_camera_cmdcb_t *node = NULL;
206 
207     node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
208     if (NULL != node) {
209         memset(node, 0, sizeof(mm_camera_cmdcb_t));
210         node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
211         node->u.evt = *event;
212 
213         /* enqueue to evt cmd thread */
214         cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
215         /* wake up evt cmd thread */
216         cam_sem_post(&(my_obj->evt_thread.cmd_sem));
217     } else {
218         CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
219         rc = -1;
220     }
221 
222     return rc;
223 }
224 
225 /*===========================================================================
226  * FUNCTION   : mm_camera_open
227  *
228  * DESCRIPTION: open a camera
229  *
230  * PARAMETERS :
231  *   @my_obj   : ptr to a camera object
232  *
233  * RETURN     : int32_t type of status
234  *              0  -- success
235  *              -1 -- failure
236  *==========================================================================*/
mm_camera_open(mm_camera_obj_t * my_obj)237 int32_t mm_camera_open(mm_camera_obj_t *my_obj)
238 {
239     char dev_name[MM_CAMERA_DEV_NAME_LEN];
240     int32_t rc = 0;
241     int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
242     uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
243     unsigned int cam_idx = 0;
244 
245     CDBG("%s:  begin\n", __func__);
246 
247     if (NULL == my_obj) {
248         goto on_error;
249     }
250     snprintf(dev_name, sizeof(dev_name), "/dev/%s",
251              mm_camera_util_get_dev_name(my_obj->my_hdl));
252     sscanf(dev_name, "/dev/video%u", &cam_idx);
253     CDBG_HIGH("%s: dev name = %s, cam_idx = %d", __func__, dev_name, cam_idx);
254 
255     do{
256         n_try--;
257         my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
258         CDBG("%s:  ctrl_fd = %d, errno == %d", __func__, my_obj->ctrl_fd, errno);
259         if((my_obj->ctrl_fd >= 0) || (errno != EIO) || (n_try <= 0 )) {
260             CDBG_HIGH("%s:  opened, break out while loop", __func__);
261             break;
262         }
263         CDBG("%s:failed with I/O error retrying after %d milli-seconds",
264              __func__, sleep_msec);
265         usleep(sleep_msec * 1000);
266     }while (n_try > 0);
267 
268     if (my_obj->ctrl_fd < 0) {
269         CDBG_ERROR("%s: cannot open control fd of '%s' (%s)\n",
270                  __func__, dev_name, strerror(errno));
271         rc = -1;
272         goto on_error;
273     }
274 
275     /* open domain socket*/
276     n_try = MM_CAMERA_DEV_OPEN_TRIES;
277     do {
278         n_try--;
279         my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
280         CDBG("%s:  ds_fd = %d, errno = %d", __func__, my_obj->ds_fd, errno);
281         if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {
282             CDBG("%s:  opened, break out while loop", __func__);
283             break;
284         }
285         CDBG("%s:failed with I/O error retrying after %d milli-seconds",
286              __func__, sleep_msec);
287         usleep(sleep_msec * 1000);
288     } while (n_try > 0);
289 
290     if (my_obj->ds_fd < 0) {
291         CDBG_ERROR("%s: cannot open domain socket fd of '%s'(%s)\n",
292                  __func__, dev_name, strerror(errno));
293         rc = -1;
294         goto on_error;
295     }
296     pthread_mutex_init(&my_obj->msg_lock, NULL);
297 
298     pthread_mutex_init(&my_obj->cb_lock, NULL);
299     pthread_mutex_init(&my_obj->evt_lock, NULL);
300     pthread_cond_init(&my_obj->evt_cond, NULL);
301 
302     CDBG("%s : Launch evt Thread in Cam Open",__func__);
303     mm_camera_cmd_thread_launch(&my_obj->evt_thread,
304                                 mm_camera_dispatch_app_event,
305                                 (void *)my_obj);
306 
307     /* launch event poll thread
308      * we will add evt fd into event poll thread upon user first register for evt */
309     CDBG("%s : Launch evt Poll Thread in Cam Open", __func__);
310     mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
311                                  MM_CAMERA_POLL_TYPE_EVT);
312     mm_camera_evt_sub(my_obj, TRUE);
313 
314     CDBG("%s:  end (rc = %d)\n", __func__, rc);
315     /* we do not need to unlock cam_lock here before return
316      * because for open, it's done within intf_lock */
317     return rc;
318 
319 on_error:
320     if (NULL == my_obj) {
321         CDBG_ERROR("%s: Invalid camera object\n", __func__);
322         rc = -1;
323     } else {
324         if (my_obj->ctrl_fd >= 0) {
325             close(my_obj->ctrl_fd);
326             my_obj->ctrl_fd = -1;
327         }
328         if (my_obj->ds_fd >= 0) {
329             mm_camera_socket_close(my_obj->ds_fd);
330             my_obj->ds_fd = -1;
331         }
332     }
333 
334     /* we do not need to unlock cam_lock here before return
335      * because for open, it's done within intf_lock */
336     return rc;
337 }
338 
339 /*===========================================================================
340  * FUNCTION   : mm_camera_close
341  *
342  * DESCRIPTION: enqueue received event into event queue to be processed by
343  *              event thread.
344  *
345  * PARAMETERS :
346  *   @my_obj   : ptr to a camera object
347  *   @event    : event to be queued
348  *
349  * RETURN     : int32_t type of status
350  *              0  -- success
351  *              -1 -- failure
352  *==========================================================================*/
mm_camera_close(mm_camera_obj_t * my_obj)353 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
354 {
355     CDBG("%s : unsubscribe evt", __func__);
356     mm_camera_evt_sub(my_obj, FALSE);
357 
358     CDBG("%s : Close evt Poll Thread in Cam Close",__func__);
359     mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
360 
361     CDBG("%s : Close evt cmd Thread in Cam Close",__func__);
362     mm_camera_cmd_thread_release(&my_obj->evt_thread);
363 
364     if(my_obj->ctrl_fd >= 0) {
365         close(my_obj->ctrl_fd);
366         my_obj->ctrl_fd = -1;
367     }
368     if(my_obj->ds_fd >= 0) {
369         mm_camera_socket_close(my_obj->ds_fd);
370         my_obj->ds_fd = -1;
371     }
372     pthread_mutex_destroy(&my_obj->msg_lock);
373 
374     pthread_mutex_destroy(&my_obj->cb_lock);
375     pthread_mutex_destroy(&my_obj->evt_lock);
376     pthread_cond_destroy(&my_obj->evt_cond);
377 
378     pthread_mutex_unlock(&my_obj->cam_lock);
379     return 0;
380 }
381 
382 /*===========================================================================
383  * FUNCTION   : mm_camera_register_event_notify_internal
384  *
385  * DESCRIPTION: internal implementation for registering callback for event notify.
386  *
387  * PARAMETERS :
388  *   @my_obj   : ptr to a camera object
389  *   @evt_cb   : callback to be registered to handle event notify
390  *   @user_data: user data ptr
391  *
392  * RETURN     : int32_t type of status
393  *              0  -- success
394  *              -1 -- failure
395  *==========================================================================*/
mm_camera_register_event_notify_internal(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)396 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
397                                                  mm_camera_event_notify_t evt_cb,
398                                                  void * user_data)
399 {
400     int i;
401     int rc = -1;
402     mm_camera_evt_obj_t *evt_array = NULL;
403 
404     pthread_mutex_lock(&my_obj->cb_lock);
405     evt_array = &my_obj->evt;
406     if(evt_cb) {
407         /* this is reg case */
408         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
409             if(evt_array->evt[i].user_data == NULL) {
410                 evt_array->evt[i].evt_cb = evt_cb;
411                 evt_array->evt[i].user_data = user_data;
412                 evt_array->reg_count++;
413                 rc = 0;
414                 break;
415             }
416         }
417     } else {
418         /* this is unreg case */
419         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
420             if(evt_array->evt[i].user_data == user_data) {
421                 evt_array->evt[i].evt_cb = NULL;
422                 evt_array->evt[i].user_data = NULL;
423                 evt_array->reg_count--;
424                 rc = 0;
425                 break;
426             }
427         }
428     }
429 
430     pthread_mutex_unlock(&my_obj->cb_lock);
431     return rc;
432 }
433 
434 /*===========================================================================
435  * FUNCTION   : mm_camera_register_event_notify
436  *
437  * DESCRIPTION: registering a callback for event notify.
438  *
439  * PARAMETERS :
440  *   @my_obj   : ptr to a camera object
441  *   @evt_cb   : callback to be registered to handle event notify
442  *   @user_data: user data ptr
443  *
444  * RETURN     : int32_t type of status
445  *              0  -- success
446  *              -1 -- failure
447  *==========================================================================*/
mm_camera_register_event_notify(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)448 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
449                                         mm_camera_event_notify_t evt_cb,
450                                         void * user_data)
451 {
452     int rc = -1;
453     rc = mm_camera_register_event_notify_internal(my_obj,
454                                                   evt_cb,
455                                                   user_data);
456     pthread_mutex_unlock(&my_obj->cam_lock);
457     return rc;
458 }
459 
460 /*===========================================================================
461  * FUNCTION   : mm_camera_qbuf
462  *
463  * DESCRIPTION: enqueue buffer back to kernel
464  *
465  * PARAMETERS :
466  *   @my_obj       : camera object
467  *   @ch_id        : channel handle
468  *   @buf          : buf ptr to be enqueued
469  *
470  * RETURN     : int32_t type of status
471  *              0  -- success
472  *              -1 -- failure
473  *==========================================================================*/
mm_camera_qbuf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_buf_def_t * buf)474 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
475                        uint32_t ch_id,
476                        mm_camera_buf_def_t *buf)
477 {
478     int rc = -1;
479     mm_channel_t * ch_obj = NULL;
480     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
481 
482     pthread_mutex_unlock(&my_obj->cam_lock);
483 
484     /* we always assume qbuf will be done before channel/stream is fully stopped
485      * because qbuf is done within dataCB context
486      * in order to avoid deadlock, we are not locking ch_lock for qbuf */
487     if (NULL != ch_obj) {
488         rc = mm_channel_qbuf(ch_obj, buf);
489     }
490 
491     return rc;
492 }
493 
494 /*===========================================================================
495  * FUNCTION   : mm_camera_query_capability
496  *
497  * DESCRIPTION: query camera capability
498  *
499  * PARAMETERS :
500  *   @my_obj: camera object
501  *
502  * RETURN     : int32_t type of status
503  *              0  -- success
504  *              -1 -- failure
505  *==========================================================================*/
mm_camera_query_capability(mm_camera_obj_t * my_obj)506 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
507 {
508     int32_t rc = 0;
509     struct v4l2_capability cap;
510 
511     /* get camera capabilities */
512     memset(&cap, 0, sizeof(cap));
513     rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
514     if (rc != 0) {
515         CDBG_ERROR("%s: cannot get camera capabilities, rc = %d\n", __func__, rc);
516     }
517 
518     pthread_mutex_unlock(&my_obj->cam_lock);
519     return rc;
520 
521 }
522 
523 /*===========================================================================
524  * FUNCTION   : mm_camera_set_parms
525  *
526  * DESCRIPTION: set parameters per camera
527  *
528  * PARAMETERS :
529  *   @my_obj       : camera object
530  *   @parms        : ptr to a param struct to be set to server
531  *
532  * RETURN     : int32_t type of status
533  *              0  -- success
534  *              -1 -- failure
535  * NOTE       : Assume the parms struct buf is already mapped to server via
536  *              domain socket. Corresponding fields of parameters to be set
537  *              are already filled in by upper layer caller.
538  *==========================================================================*/
mm_camera_set_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)539 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj,
540                             parm_buffer_t *parms)
541 {
542     int32_t rc = -1;
543     int32_t value = 0;
544     if (parms !=  NULL) {
545         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
546     }
547     pthread_mutex_unlock(&my_obj->cam_lock);
548     return rc;
549 }
550 
551 /*===========================================================================
552  * FUNCTION   : mm_camera_get_parms
553  *
554  * DESCRIPTION: get parameters per camera
555  *
556  * PARAMETERS :
557  *   @my_obj       : camera object
558  *   @parms        : ptr to a param struct to be get from server
559  *
560  * RETURN     : int32_t type of status
561  *              0  -- success
562  *              -1 -- failure
563  * NOTE       : Assume the parms struct buf is already mapped to server via
564  *              domain socket. Parameters to be get from server are already
565  *              filled in by upper layer caller. After this call, corresponding
566  *              fields of requested parameters will be filled in by server with
567  *              detailed information.
568  *==========================================================================*/
mm_camera_get_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)569 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
570                             parm_buffer_t *parms)
571 {
572     int32_t rc = -1;
573     int32_t value = 0;
574     if (parms != NULL) {
575         rc = mm_camera_util_g_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
576     }
577     pthread_mutex_unlock(&my_obj->cam_lock);
578     return rc;
579 }
580 
581 /*===========================================================================
582  * FUNCTION   : mm_camera_do_auto_focus
583  *
584  * DESCRIPTION: performing auto focus
585  *
586  * PARAMETERS :
587  *   @camera_handle: camera handle
588  *
589  * RETURN     : int32_t type of status
590  *              0  -- success
591  *              -1 -- failure
592  * NOTE       : if this call success, we will always assume there will
593  *              be an auto_focus event following up.
594  *==========================================================================*/
mm_camera_do_auto_focus(mm_camera_obj_t * my_obj)595 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
596 {
597     int32_t rc = -1;
598     int32_t value = 0;
599     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
600     pthread_mutex_unlock(&my_obj->cam_lock);
601     return rc;
602 }
603 
604 /*===========================================================================
605  * FUNCTION   : mm_camera_cancel_auto_focus
606  *
607  * DESCRIPTION: cancel auto focus
608  *
609  * PARAMETERS :
610  *   @camera_handle: camera handle
611  *
612  * RETURN     : int32_t type of status
613  *              0  -- success
614  *              -1 -- failure
615  *==========================================================================*/
mm_camera_cancel_auto_focus(mm_camera_obj_t * my_obj)616 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
617 {
618     int32_t rc = -1;
619     int32_t value = 0;
620     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
621     pthread_mutex_unlock(&my_obj->cam_lock);
622     return rc;
623 }
624 
625 /*===========================================================================
626  * FUNCTION   : mm_camera_prepare_snapshot
627  *
628  * DESCRIPTION: prepare hardware for snapshot
629  *
630  * PARAMETERS :
631  *   @my_obj       : camera object
632  *   @do_af_flag   : flag indicating if AF is needed
633  *
634  * RETURN     : int32_t type of status
635  *              0  -- success
636  *              -1 -- failure
637  *==========================================================================*/
mm_camera_prepare_snapshot(mm_camera_obj_t * my_obj,int32_t do_af_flag)638 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
639                                    int32_t do_af_flag)
640 {
641     int32_t rc = -1;
642     int32_t value = do_af_flag;
643     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
644     pthread_mutex_unlock(&my_obj->cam_lock);
645     return rc;
646 }
647 
648 /*===========================================================================
649  * FUNCTION   : mm_camera_start_zsl_snapshot
650  *
651  * DESCRIPTION: start zsl snapshot
652  *
653  * PARAMETERS :
654  *   @my_obj       : camera object
655  *
656  * RETURN     : int32_t type of status
657  *              0  -- success
658  *              -1 -- failure
659  *==========================================================================*/
mm_camera_start_zsl_snapshot(mm_camera_obj_t * my_obj)660 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
661 {
662     int32_t rc = -1;
663     int32_t value = 0;
664 
665     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
666              CAM_PRIV_START_ZSL_SNAPSHOT, &value);
667     return rc;
668 }
669 
670 /*===========================================================================
671  * FUNCTION   : mm_camera_stop_zsl_snapshot
672  *
673  * DESCRIPTION: stop zsl capture
674  *
675  * PARAMETERS :
676  *   @my_obj       : camera object
677  *
678  * RETURN     : int32_t type of status
679  *              0  -- success
680  *              -1 -- failure
681  *==========================================================================*/
mm_camera_stop_zsl_snapshot(mm_camera_obj_t * my_obj)682 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
683 {
684     int32_t rc = -1;
685     int32_t value;
686     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
687              CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
688     return rc;
689 }
690 
691 /*===========================================================================
692  * FUNCTION   : mm_camera_add_channel
693  *
694  * DESCRIPTION: add a channel
695  *
696  * PARAMETERS :
697  *   @my_obj       : camera object
698  *   @attr         : bundle attribute of the channel if needed
699  *   @channel_cb   : callback function for bundle data notify
700  *   @userdata     : user data ptr
701  *
702  * RETURN     : uint32_t type of channel handle
703  *              0  -- invalid channel handle, meaning the op failed
704  *              >0 -- successfully added a channel with a valid handle
705  * NOTE       : if no bundle data notify is needed, meaning each stream in the
706  *              channel will have its own stream data notify callback, then
707  *              attr, channel_cb, and userdata can be NULL. In this case,
708  *              no matching logic will be performed in channel for the bundling.
709  *==========================================================================*/
mm_camera_add_channel(mm_camera_obj_t * my_obj,mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t channel_cb,void * userdata)710 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
711                                mm_camera_channel_attr_t *attr,
712                                mm_camera_buf_notify_t channel_cb,
713                                void *userdata)
714 {
715     mm_channel_t *ch_obj = NULL;
716     uint8_t ch_idx = 0;
717     uint32_t ch_hdl = 0;
718 
719     for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
720         if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
721             ch_obj = &my_obj->ch[ch_idx];
722             break;
723         }
724     }
725 
726     if (NULL != ch_obj) {
727         /* initialize channel obj */
728         memset(ch_obj, 0, sizeof(mm_channel_t));
729         ch_hdl = mm_camera_util_generate_handler(ch_idx);
730         ch_obj->my_hdl = ch_hdl;
731         ch_obj->state = MM_CHANNEL_STATE_STOPPED;
732         ch_obj->cam_obj = my_obj;
733         pthread_mutex_init(&ch_obj->ch_lock, NULL);
734         mm_channel_init(ch_obj, attr, channel_cb, userdata);
735     }
736 
737     pthread_mutex_unlock(&my_obj->cam_lock);
738 
739     return ch_hdl;
740 }
741 
742 /*===========================================================================
743  * FUNCTION   : mm_camera_del_channel
744  *
745  * DESCRIPTION: delete a channel by its handle
746  *
747  * PARAMETERS :
748  *   @my_obj       : camera object
749  *   @ch_id        : channel handle
750  *
751  * RETURN     : int32_t type of status
752  *              0  -- success
753  *              -1 -- failure
754  * NOTE       : all streams in the channel should be stopped already before
755  *              this channel can be deleted.
756  *==========================================================================*/
mm_camera_del_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)757 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
758                               uint32_t ch_id)
759 {
760     int32_t rc = -1;
761     mm_channel_t * ch_obj =
762         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
763 
764     if (NULL != ch_obj) {
765         pthread_mutex_lock(&ch_obj->ch_lock);
766         pthread_mutex_unlock(&my_obj->cam_lock);
767 
768         rc = mm_channel_fsm_fn(ch_obj,
769                                MM_CHANNEL_EVT_DELETE,
770                                NULL,
771                                NULL);
772 
773         pthread_mutex_destroy(&ch_obj->ch_lock);
774         memset(ch_obj, 0, sizeof(mm_channel_t));
775     } else {
776         pthread_mutex_unlock(&my_obj->cam_lock);
777     }
778     return rc;
779 }
780 
781 /*===========================================================================
782  * FUNCTION   : mm_camera_get_bundle_info
783  *
784  * DESCRIPTION: query bundle info of the channel
785  *
786  * PARAMETERS :
787  *   @my_obj       : camera object
788  *   @ch_id        : channel handle
789  *   @bundle_info  : bundle info to be filled in
790  *
791  * RETURN     : int32_t type of status
792  *              0  -- success
793  *              -1 -- failure
794  * NOTE       : all streams in the channel should be stopped already before
795  *              this channel can be deleted.
796  *==========================================================================*/
mm_camera_get_bundle_info(mm_camera_obj_t * my_obj,uint32_t ch_id,cam_bundle_config_t * bundle_info)797 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
798                                   uint32_t ch_id,
799                                   cam_bundle_config_t *bundle_info)
800 {
801     int32_t rc = -1;
802     mm_channel_t * ch_obj =
803         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
804 
805     if (NULL != ch_obj) {
806         pthread_mutex_lock(&ch_obj->ch_lock);
807         pthread_mutex_unlock(&my_obj->cam_lock);
808 
809         rc = mm_channel_fsm_fn(ch_obj,
810                                MM_CHANNEL_EVT_GET_BUNDLE_INFO,
811                                (void *)bundle_info,
812                                NULL);
813     } else {
814         pthread_mutex_unlock(&my_obj->cam_lock);
815     }
816     return rc;
817 }
818 
819 /*===========================================================================
820  * FUNCTION   : mm_camera_add_stream
821  *
822  * DESCRIPTION: add a stream into a channel
823  *
824  * PARAMETERS :
825  *   @my_obj       : camera object
826  *   @ch_id        : channel handle
827  *
828  * RETURN     : uint32_t type of stream handle
829  *              0  -- invalid stream handle, meaning the op failed
830  *              >0 -- successfully added a stream with a valid handle
831  *==========================================================================*/
mm_camera_add_stream(mm_camera_obj_t * my_obj,uint32_t ch_id)832 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
833                               uint32_t ch_id)
834 {
835     uint32_t s_hdl = 0;
836     mm_channel_t * ch_obj =
837         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
838 
839     if (NULL != ch_obj) {
840         pthread_mutex_lock(&ch_obj->ch_lock);
841         pthread_mutex_unlock(&my_obj->cam_lock);
842 
843         mm_channel_fsm_fn(ch_obj,
844                           MM_CHANNEL_EVT_ADD_STREAM,
845                           NULL,
846                           (void*)&s_hdl);
847     } else {
848         pthread_mutex_unlock(&my_obj->cam_lock);
849     }
850 
851     return s_hdl;
852 }
853 
854 /*===========================================================================
855  * FUNCTION   : mm_camera_del_stream
856  *
857  * DESCRIPTION: delete a stream by its handle
858  *
859  * PARAMETERS :
860  *   @my_obj       : camera object
861  *   @ch_id        : channel handle
862  *   @stream_id    : stream handle
863  *
864  * RETURN     : int32_t type of status
865  *              0  -- success
866  *              -1 -- failure
867  * NOTE       : stream should be stopped already before it can be deleted.
868  *==========================================================================*/
mm_camera_del_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)869 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
870                              uint32_t ch_id,
871                              uint32_t stream_id)
872 {
873     int32_t rc = -1;
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         rc = mm_channel_fsm_fn(ch_obj,
882                                MM_CHANNEL_EVT_DEL_STREAM,
883                                (void*)stream_id,
884                                NULL);
885     } else {
886         pthread_mutex_unlock(&my_obj->cam_lock);
887     }
888 
889     return rc;
890 }
891 
892 /*===========================================================================
893  * FUNCTION   : mm_camera_start_zsl_snapshot_ch
894  *
895  * DESCRIPTION: starts zsl snapshot for specific channel
896  *
897  * PARAMETERS :
898  *   @my_obj       : camera object
899  *   @ch_id        : channel handle
900  *
901  * RETURN     : int32_t type of status
902  *              0  -- success
903  *              -1 -- failure
904  *==========================================================================*/
mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)905 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
906         uint32_t ch_id)
907 {
908     int32_t rc = -1;
909     mm_channel_t * ch_obj =
910         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
911 
912     if (NULL != ch_obj) {
913         pthread_mutex_lock(&ch_obj->ch_lock);
914         pthread_mutex_unlock(&my_obj->cam_lock);
915 
916         rc = mm_channel_fsm_fn(ch_obj,
917                                MM_CHANNEL_EVT_START_ZSL_SNAPSHOT,
918                                NULL,
919                                NULL);
920     } else {
921         pthread_mutex_unlock(&my_obj->cam_lock);
922     }
923 
924     return rc;
925 }
926 
927 /*===========================================================================
928  * FUNCTION   : mm_camera_stop_zsl_snapshot_ch
929  *
930  * DESCRIPTION: stops zsl snapshot for specific channel
931  *
932  * PARAMETERS :
933  *   @my_obj       : camera object
934  *   @ch_id        : channel handle
935  *
936  * RETURN     : int32_t type of status
937  *              0  -- success
938  *              -1 -- failure
939  *==========================================================================*/
mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)940 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
941         uint32_t ch_id)
942 {
943     int32_t rc = -1;
944     mm_channel_t * ch_obj =
945         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
946 
947     if (NULL != ch_obj) {
948         pthread_mutex_lock(&ch_obj->ch_lock);
949         pthread_mutex_unlock(&my_obj->cam_lock);
950 
951         rc = mm_channel_fsm_fn(ch_obj,
952                                MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT,
953                                NULL,
954                                NULL);
955     } else {
956         pthread_mutex_unlock(&my_obj->cam_lock);
957     }
958 
959     return rc;
960 }
961 
962 /*===========================================================================
963  * FUNCTION   : mm_camera_config_stream
964  *
965  * DESCRIPTION: configure a stream
966  *
967  * PARAMETERS :
968  *   @my_obj       : camera object
969  *   @ch_id        : channel handle
970  *   @stream_id    : stream handle
971  *   @config       : stream configuration
972  *
973  * RETURN     : int32_t type of status
974  *              0  -- success
975  *              -1 -- failure
976  *==========================================================================*/
mm_camera_config_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)977 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
978                                 uint32_t ch_id,
979                                 uint32_t stream_id,
980                                 mm_camera_stream_config_t *config)
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_paylod_config_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_paylod_config_stream_t));
992         payload.stream_id = stream_id;
993         payload.config = config;
994         rc = mm_channel_fsm_fn(ch_obj,
995                                MM_CHANNEL_EVT_CONFIG_STREAM,
996                                (void*)&payload,
997                                NULL);
998     } else {
999         pthread_mutex_unlock(&my_obj->cam_lock);
1000     }
1001 
1002     return rc;
1003 }
1004 
1005 /*===========================================================================
1006  * FUNCTION   : mm_camera_start_channel
1007  *
1008  * DESCRIPTION: start a channel, which will start all streams in the channel
1009  *
1010  * PARAMETERS :
1011  *   @my_obj       : camera object
1012  *   @ch_id        : channel handle
1013  *
1014  * RETURN     : int32_t type of status
1015  *              0  -- success
1016  *              -1 -- failure
1017  *==========================================================================*/
mm_camera_start_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1018 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj,
1019                                 uint32_t ch_id)
1020 {
1021     int32_t rc = -1;
1022     mm_channel_t * ch_obj =
1023         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1024 
1025     if (NULL != ch_obj) {
1026         pthread_mutex_lock(&ch_obj->ch_lock);
1027         pthread_mutex_unlock(&my_obj->cam_lock);
1028 
1029         rc = mm_channel_fsm_fn(ch_obj,
1030                                MM_CHANNEL_EVT_START,
1031                                NULL,
1032                                NULL);
1033     } else {
1034         pthread_mutex_unlock(&my_obj->cam_lock);
1035     }
1036 
1037     return rc;
1038 }
1039 
1040 /*===========================================================================
1041  * FUNCTION   : mm_camera_stop_channel
1042  *
1043  * DESCRIPTION: stop a channel, which will stop all streams in the channel
1044  *
1045  * PARAMETERS :
1046  *   @my_obj       : camera object
1047  *   @ch_id        : channel handle
1048  *
1049  * RETURN     : int32_t type of status
1050  *              0  -- success
1051  *              -1 -- failure
1052  *==========================================================================*/
mm_camera_stop_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1053 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
1054                                uint32_t ch_id)
1055 {
1056     int32_t rc = 0;
1057     mm_channel_t * ch_obj =
1058         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1059 
1060     if (NULL != ch_obj) {
1061         pthread_mutex_lock(&ch_obj->ch_lock);
1062         pthread_mutex_unlock(&my_obj->cam_lock);
1063 
1064         rc = mm_channel_fsm_fn(ch_obj,
1065                                MM_CHANNEL_EVT_STOP,
1066                                NULL,
1067                                NULL);
1068     } else {
1069         pthread_mutex_unlock(&my_obj->cam_lock);
1070     }
1071     return rc;
1072 }
1073 
1074 /*===========================================================================
1075  * FUNCTION   : mm_camera_request_super_buf
1076  *
1077  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1078  *              frames from superbuf queue
1079  *
1080  * PARAMETERS :
1081  *   @my_obj       : camera object
1082  *   @ch_id        : channel handle
1083  *   @num_buf_requested : number of matched frames needed
1084  *
1085  * RETURN     : int32_t type of status
1086  *              0  -- success
1087  *              -1 -- failure
1088  *==========================================================================*/
mm_camera_request_super_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t num_buf_requested,uint32_t num_retro_buf_requested)1089 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1090                                     uint32_t ch_id,
1091                                     uint32_t num_buf_requested,
1092                                     uint32_t num_retro_buf_requested)
1093 {
1094     int32_t rc = -1;
1095     mm_channel_t * ch_obj =
1096         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1097 
1098     if (NULL != ch_obj) {
1099         pthread_mutex_lock(&ch_obj->ch_lock);
1100         pthread_mutex_unlock(&my_obj->cam_lock);
1101 
1102         rc = mm_channel_fsm_fn(ch_obj,
1103                                MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
1104                                (void*)num_buf_requested,
1105                                (void*)num_retro_buf_requested);
1106     } else {
1107         pthread_mutex_unlock(&my_obj->cam_lock);
1108     }
1109 
1110     return rc;
1111 }
1112 
1113 /*===========================================================================
1114  * FUNCTION   : mm_camera_cancel_super_buf_request
1115  *
1116  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
1117  *              of matched frames from superbuf queue
1118  *
1119  * PARAMETERS :
1120  *   @my_obj       : camera object
1121  *   @ch_id        : channel handle
1122  *
1123  * RETURN     : int32_t type of status
1124  *              0  -- success
1125  *              -1 -- failure
1126  *==========================================================================*/
mm_camera_cancel_super_buf_request(mm_camera_obj_t * my_obj,uint32_t ch_id)1127 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
1128 {
1129     int32_t rc = -1;
1130     mm_channel_t * ch_obj =
1131         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1132 
1133     if (NULL != ch_obj) {
1134         pthread_mutex_lock(&ch_obj->ch_lock);
1135         pthread_mutex_unlock(&my_obj->cam_lock);
1136 
1137         rc = mm_channel_fsm_fn(ch_obj,
1138                                MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
1139                                NULL,
1140                                NULL);
1141     } else {
1142         pthread_mutex_unlock(&my_obj->cam_lock);
1143     }
1144 
1145     return rc;
1146 }
1147 
1148 /*===========================================================================
1149  * FUNCTION   : mm_camera_flush_super_buf_queue
1150  *
1151  * DESCRIPTION: flush out all frames in the superbuf queue
1152  *
1153  * PARAMETERS :
1154  *   @my_obj       : camera object
1155  *   @ch_id        : channel handle
1156  *
1157  * RETURN     : int32_t type of status
1158  *              0  -- success
1159  *              -1 -- failure
1160  *==========================================================================*/
mm_camera_flush_super_buf_queue(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t frame_idx)1161 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
1162                                                              uint32_t frame_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_FLUSH_SUPER_BUF_QUEUE,
1174                                (void *)frame_idx,
1175                                NULL);
1176     } else {
1177         pthread_mutex_unlock(&my_obj->cam_lock);
1178     }
1179 
1180     return rc;
1181 }
1182 
1183 /*===========================================================================
1184  * FUNCTION   : mm_camera_config_channel_notify
1185  *
1186  * DESCRIPTION: configures the channel notification mode
1187  *
1188  * PARAMETERS :
1189  *   @my_obj       : camera object
1190  *   @ch_id        : channel handle
1191  *   @notify_mode  : notification mode
1192  *
1193  * RETURN     : int32_t type of status
1194  *              0  -- success
1195  *              -1 -- failure
1196  *==========================================================================*/
mm_camera_config_channel_notify(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)1197 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
1198                                         uint32_t ch_id,
1199                                         mm_camera_super_buf_notify_mode_t notify_mode)
1200 {
1201     int32_t rc = -1;
1202     mm_channel_t * ch_obj =
1203         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1204 
1205     if (NULL != ch_obj) {
1206         pthread_mutex_lock(&ch_obj->ch_lock);
1207         pthread_mutex_unlock(&my_obj->cam_lock);
1208 
1209         rc = mm_channel_fsm_fn(ch_obj,
1210                                MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
1211                                (void *)notify_mode,
1212                                NULL);
1213     } else {
1214         pthread_mutex_unlock(&my_obj->cam_lock);
1215     }
1216 
1217     return rc;
1218 }
1219 
1220 /*===========================================================================
1221  * FUNCTION   : mm_camera_set_stream_parms
1222  *
1223  * DESCRIPTION: set parameters per stream
1224  *
1225  * PARAMETERS :
1226  *   @my_obj       : camera object
1227  *   @ch_id        : channel handle
1228  *   @s_id         : stream handle
1229  *   @parms        : ptr to a param struct to be set to server
1230  *
1231  * RETURN     : int32_t type of status
1232  *              0  -- success
1233  *              -1 -- failure
1234  * NOTE       : Assume the parms struct buf is already mapped to server via
1235  *              domain socket. Corresponding fields of parameters to be set
1236  *              are already filled in by upper layer caller.
1237  *==========================================================================*/
mm_camera_set_stream_parms(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1238 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
1239                                    uint32_t ch_id,
1240                                    uint32_t s_id,
1241                                    cam_stream_parm_buffer_t *parms)
1242 {
1243     int32_t rc = -1;
1244     mm_evt_paylod_set_get_stream_parms_t payload;
1245     mm_channel_t * ch_obj =
1246         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1247 
1248     if (NULL != ch_obj) {
1249         pthread_mutex_lock(&ch_obj->ch_lock);
1250         pthread_mutex_unlock(&my_obj->cam_lock);
1251 
1252         memset(&payload, 0, sizeof(payload));
1253         payload.stream_id = s_id;
1254         payload.parms = parms;
1255 
1256         rc = mm_channel_fsm_fn(ch_obj,
1257                                MM_CHANNEL_EVT_SET_STREAM_PARM,
1258                                (void *)&payload,
1259                                NULL);
1260     } else {
1261         pthread_mutex_unlock(&my_obj->cam_lock);
1262     }
1263 
1264     return rc;
1265 }
1266 
1267 /*===========================================================================
1268  * FUNCTION   : mm_camera_get_stream_parms
1269  *
1270  * DESCRIPTION: get parameters per stream
1271  *
1272  * PARAMETERS :
1273  *   @my_obj       : camera object
1274  *   @ch_id        : channel handle
1275  *   @s_id         : stream handle
1276  *   @parms        : ptr to a param struct to be get from server
1277  *
1278  * RETURN     : int32_t type of status
1279  *              0  -- success
1280  *              -1 -- failure
1281  * NOTE       : Assume the parms struct buf is already mapped to server via
1282  *              domain socket. Parameters to be get from server are already
1283  *              filled in by upper layer caller. After this call, corresponding
1284  *              fields of requested parameters will be filled in by server with
1285  *              detailed information.
1286  *==========================================================================*/
mm_camera_get_stream_parms(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1287 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
1288                                    uint32_t ch_id,
1289                                    uint32_t s_id,
1290                                    cam_stream_parm_buffer_t *parms)
1291 {
1292     int32_t rc = -1;
1293     mm_evt_paylod_set_get_stream_parms_t payload;
1294     mm_channel_t * ch_obj =
1295         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1296 
1297     if (NULL != ch_obj) {
1298         pthread_mutex_lock(&ch_obj->ch_lock);
1299         pthread_mutex_unlock(&my_obj->cam_lock);
1300 
1301         memset(&payload, 0, sizeof(payload));
1302         payload.stream_id = s_id;
1303         payload.parms = parms;
1304 
1305         rc = mm_channel_fsm_fn(ch_obj,
1306                                MM_CHANNEL_EVT_GET_STREAM_PARM,
1307                                (void *)&payload,
1308                                NULL);
1309     } else {
1310         pthread_mutex_unlock(&my_obj->cam_lock);
1311     }
1312 
1313     return rc;
1314 }
1315 
1316 /*===========================================================================
1317  * FUNCTION   : mm_camera_do_stream_action
1318  *
1319  * DESCRIPTION: request server to perform stream based action. Maybe removed later
1320  *              if the functionality is included in mm_camera_set_parms
1321  *
1322  * PARAMETERS :
1323  *   @my_obj       : camera object
1324  *   @ch_id        : channel handle
1325  *   @s_id         : stream handle
1326  *   @actions      : ptr to an action struct buf to be performed by server
1327  *
1328  * RETURN     : int32_t type of status
1329  *              0  -- success
1330  *              -1 -- failure
1331  * NOTE       : Assume the action struct buf is already mapped to server via
1332  *              domain socket. Actions to be performed by server are already
1333  *              filled in by upper layer caller.
1334  *==========================================================================*/
mm_camera_do_stream_action(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,void * actions)1335 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
1336                                    uint32_t ch_id,
1337                                    uint32_t stream_id,
1338                                    void *actions)
1339 {
1340     int32_t rc = -1;
1341     mm_evt_paylod_do_stream_action_t payload;
1342     mm_channel_t * ch_obj =
1343         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1344 
1345     if (NULL != ch_obj) {
1346         pthread_mutex_lock(&ch_obj->ch_lock);
1347         pthread_mutex_unlock(&my_obj->cam_lock);
1348 
1349         memset(&payload, 0, sizeof(payload));
1350         payload.stream_id = stream_id;
1351         payload.actions = actions;
1352 
1353         rc = mm_channel_fsm_fn(ch_obj,
1354                                MM_CHANNEL_EVT_DO_STREAM_ACTION,
1355                                (void*)&payload,
1356                                NULL);
1357     } else {
1358         pthread_mutex_unlock(&my_obj->cam_lock);
1359     }
1360 
1361     return rc;
1362 }
1363 
1364 /*===========================================================================
1365  * FUNCTION   : mm_camera_map_stream_buf
1366  *
1367  * DESCRIPTION: mapping stream buffer via domain socket to server
1368  *
1369  * PARAMETERS :
1370  *   @my_obj       : camera object
1371  *   @ch_id        : channel handle
1372  *   @s_id         : stream handle
1373  *   @buf_type     : type of buffer to be mapped. could be following values:
1374  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1375  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1376  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1377  *   @buf_idx      : index of buffer within the stream buffers, only valid if
1378  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1379  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1380  *   @plane_idx    : plane index. If all planes share the same fd,
1381  *                   plane_idx = -1; otherwise, plean_idx is the
1382  *                   index to plane (0..num_of_planes)
1383  *   @fd           : file descriptor of the buffer
1384  *   @size         : size of the buffer
1385  *
1386  * RETURN     : int32_t type of status
1387  *              0  -- success
1388  *              -1 -- failure
1389  *==========================================================================*/
mm_camera_map_stream_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx,int fd,uint32_t size)1390 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
1391                                  uint32_t ch_id,
1392                                  uint32_t stream_id,
1393                                  uint8_t buf_type,
1394                                  uint32_t buf_idx,
1395                                  int32_t plane_idx,
1396                                  int fd,
1397                                  uint32_t size)
1398 {
1399     int32_t rc = -1;
1400     mm_evt_paylod_map_stream_buf_t payload;
1401     mm_channel_t * ch_obj =
1402         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1403 
1404     if (NULL != ch_obj) {
1405         pthread_mutex_lock(&ch_obj->ch_lock);
1406         pthread_mutex_unlock(&my_obj->cam_lock);
1407 
1408         memset(&payload, 0, sizeof(payload));
1409         payload.stream_id = stream_id;
1410         payload.buf_type = buf_type;
1411         payload.buf_idx = buf_idx;
1412         payload.plane_idx = plane_idx;
1413         payload.fd = fd;
1414         payload.size = size;
1415         rc = mm_channel_fsm_fn(ch_obj,
1416                                MM_CHANNEL_EVT_MAP_STREAM_BUF,
1417                                (void*)&payload,
1418                                NULL);
1419     } else {
1420         pthread_mutex_unlock(&my_obj->cam_lock);
1421     }
1422 
1423     return rc;
1424 }
1425 
1426 /*===========================================================================
1427  * FUNCTION   : mm_camera_unmap_stream_buf
1428  *
1429  * DESCRIPTION: unmapping stream buffer via domain socket to server
1430  *
1431  * PARAMETERS :
1432  *   @my_obj       : camera object
1433  *   @ch_id        : channel handle
1434  *   @s_id         : stream handle
1435  *   @buf_type     : type of buffer to be mapped. could be following values:
1436  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1437  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1438  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1439  *   @buf_idx      : index of buffer within the stream buffers, only valid if
1440  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1441  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1442  *   @plane_idx    : plane index. If all planes share the same fd,
1443  *                   plane_idx = -1; otherwise, plean_idx is the
1444  *                   index to plane (0..num_of_planes)
1445  *
1446  * RETURN     : int32_t type of status
1447  *              0  -- success
1448  *              -1 -- failure
1449  *==========================================================================*/
mm_camera_unmap_stream_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx)1450 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
1451                                    uint32_t ch_id,
1452                                    uint32_t stream_id,
1453                                    uint8_t buf_type,
1454                                    uint32_t buf_idx,
1455                                    int32_t plane_idx)
1456 {
1457     int32_t rc = -1;
1458     mm_evt_paylod_unmap_stream_buf_t payload;
1459     mm_channel_t * ch_obj =
1460         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1461 
1462     if (NULL != ch_obj) {
1463         pthread_mutex_lock(&ch_obj->ch_lock);
1464         pthread_mutex_unlock(&my_obj->cam_lock);
1465 
1466         memset(&payload, 0, sizeof(payload));
1467         payload.stream_id = stream_id;
1468         payload.buf_type = buf_type;
1469         payload.buf_idx = buf_idx;
1470         payload.plane_idx = plane_idx;
1471         rc = mm_channel_fsm_fn(ch_obj,
1472                                MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
1473                                (void*)&payload,
1474                                NULL);
1475     } else {
1476         pthread_mutex_unlock(&my_obj->cam_lock);
1477     }
1478 
1479     return rc;
1480 }
1481 
1482 /*===========================================================================
1483  * FUNCTION   : mm_camera_evt_sub
1484  *
1485  * DESCRIPTION: subscribe/unsubscribe event notify from kernel
1486  *
1487  * PARAMETERS :
1488  *   @my_obj       : camera object
1489  *   @reg_flag     : 1 -- subscribe ; 0 -- unsubscribe
1490  *
1491  * RETURN     : int32_t type of status
1492  *              0  -- success
1493  *              -1 -- failure
1494  *==========================================================================*/
mm_camera_evt_sub(mm_camera_obj_t * my_obj,uint8_t reg_flag)1495 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1496                           uint8_t reg_flag)
1497 {
1498     int32_t rc = 0;
1499     struct v4l2_event_subscription sub;
1500 
1501     memset(&sub, 0, sizeof(sub));
1502     sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
1503     sub.id = MSM_CAMERA_MSM_NOTIFY;
1504     if(FALSE == reg_flag) {
1505         /* unsubscribe */
1506         rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1507         if (rc < 0) {
1508             CDBG_ERROR("%s: unsubscribe event rc = %d", __func__, rc);
1509             return rc;
1510         }
1511         /* remove evt fd from the polling thraed when unreg the last event */
1512         rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
1513                                                my_obj->my_hdl,
1514                                                mm_camera_sync_call);
1515     } else {
1516         rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1517         if (rc < 0) {
1518             CDBG_ERROR("%s: subscribe event rc = %d", __func__, rc);
1519             return rc;
1520         }
1521         /* add evt fd to polling thread when subscribe the first event */
1522         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1523                                                my_obj->my_hdl,
1524                                                my_obj->ctrl_fd,
1525                                                mm_camera_event_notify,
1526                                                (void*)my_obj,
1527                                                mm_camera_sync_call);
1528     }
1529     return rc;
1530 }
1531 
1532 /*===========================================================================
1533  * FUNCTION   : mm_camera_util_wait_for_event
1534  *
1535  * DESCRIPTION: utility function to wait for certain events
1536  *
1537  * PARAMETERS :
1538  *   @my_obj       : camera object
1539  *   @evt_mask     : mask for events to be waited. Any of event in the mask would
1540  *                   trigger the wait to end
1541  *   @status       : status of the event
1542  *
1543  * RETURN     : none
1544  *==========================================================================*/
mm_camera_util_wait_for_event(mm_camera_obj_t * my_obj,uint32_t evt_mask,int32_t * status)1545 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
1546                                    uint32_t evt_mask,
1547                                    int32_t *status)
1548 {
1549     pthread_mutex_lock(&my_obj->evt_lock);
1550     while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
1551         pthread_cond_wait(&my_obj->evt_cond, &my_obj->evt_lock);
1552     }
1553     *status = my_obj->evt_rcvd.status;
1554     /* reset local storage for recieved event for next event */
1555     memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
1556     pthread_mutex_unlock(&my_obj->evt_lock);
1557 }
1558 
1559 /*===========================================================================
1560  * FUNCTION   : mm_camera_util_sendmsg
1561  *
1562  * DESCRIPTION: utility function to send msg via domain socket
1563  *
1564  * PARAMETERS :
1565  *   @my_obj       : camera object
1566  *   @msg          : message to be sent
1567  *   @buf_size     : size of the message to be sent
1568  *   @sendfd       : >0 if any file descriptor need to be passed across process
1569  *
1570  * RETURN     : int32_t type of status
1571  *              0  -- success
1572  *              -1 -- failure
1573  *==========================================================================*/
mm_camera_util_sendmsg(mm_camera_obj_t * my_obj,void * msg,uint32_t buf_size,int sendfd)1574 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
1575                                void *msg,
1576                                uint32_t buf_size,
1577                                int sendfd)
1578 {
1579     int32_t rc = -1;
1580     int32_t status;
1581 
1582     /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
1583     pthread_mutex_lock(&my_obj->msg_lock);
1584     if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
1585         /* wait for event that mapping/unmapping is done */
1586         mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1587         if (MSM_CAMERA_STATUS_SUCCESS == status) {
1588             rc = 0;
1589         }
1590     }
1591     pthread_mutex_unlock(&my_obj->msg_lock);
1592     return rc;
1593 }
1594 
1595 /*===========================================================================
1596  * FUNCTION   : mm_camera_map_buf
1597  *
1598  * DESCRIPTION: mapping camera buffer via domain socket to server
1599  *
1600  * PARAMETERS :
1601  *   @my_obj       : camera object
1602  *   @buf_type     : type of buffer to be mapped. could be following values:
1603  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1604  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1605  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1606  *   @fd           : file descriptor of the buffer
1607  *   @size         : size of the buffer
1608  *
1609  * RETURN     : int32_t type of status
1610  *              0  -- success
1611  *              -1 -- failure
1612  *==========================================================================*/
mm_camera_map_buf(mm_camera_obj_t * my_obj,uint8_t buf_type,int fd,uint32_t size)1613 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1614                           uint8_t buf_type,
1615                           int fd,
1616                           uint32_t size)
1617 {
1618     int32_t rc = 0;
1619     cam_sock_packet_t packet;
1620     memset(&packet, 0, sizeof(cam_sock_packet_t));
1621     packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
1622     packet.payload.buf_map.type = buf_type;
1623     packet.payload.buf_map.fd = fd;
1624     packet.payload.buf_map.size = size;
1625     rc = mm_camera_util_sendmsg(my_obj,
1626                                 &packet,
1627                                 sizeof(cam_sock_packet_t),
1628                                 fd);
1629     pthread_mutex_unlock(&my_obj->cam_lock);
1630     return rc;
1631 }
1632 
1633 /*===========================================================================
1634  * FUNCTION   : mm_camera_unmap_buf
1635  *
1636  * DESCRIPTION: unmapping camera buffer via domain socket to server
1637  *
1638  * PARAMETERS :
1639  *   @my_obj       : camera object
1640  *   @buf_type     : type of buffer to be mapped. could be following values:
1641  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1642  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1643  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1644  *
1645  * RETURN     : int32_t type of status
1646  *              0  -- success
1647  *              -1 -- failure
1648  *==========================================================================*/
mm_camera_unmap_buf(mm_camera_obj_t * my_obj,uint8_t buf_type)1649 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
1650                             uint8_t buf_type)
1651 {
1652     int32_t rc = 0;
1653     cam_sock_packet_t packet;
1654     memset(&packet, 0, sizeof(cam_sock_packet_t));
1655     packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
1656     packet.payload.buf_unmap.type = buf_type;
1657     rc = mm_camera_util_sendmsg(my_obj,
1658                                 &packet,
1659                                 sizeof(cam_sock_packet_t),
1660                                 0);
1661     pthread_mutex_unlock(&my_obj->cam_lock);
1662     return rc;
1663 }
1664 
1665 /*===========================================================================
1666  * FUNCTION   : mm_camera_util_s_ctrl
1667  *
1668  * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
1669  *
1670  * PARAMETERS :
1671  *   @fd      : file descritpor for sending ioctl
1672  *   @id      : control id
1673  *   @value   : value of the ioctl to be sent
1674  *
1675  * RETURN     : int32_t type of status
1676  *              0  -- success
1677  *              -1 -- failure
1678  *==========================================================================*/
mm_camera_util_s_ctrl(int32_t fd,uint32_t id,int32_t * value)1679 int32_t mm_camera_util_s_ctrl(int32_t fd,  uint32_t id, int32_t *value)
1680 {
1681     int rc = 0;
1682     struct v4l2_control control;
1683 
1684     memset(&control, 0, sizeof(control));
1685     control.id = id;
1686     if (value != NULL) {
1687         control.value = *value;
1688     }
1689     rc = ioctl(fd, VIDIOC_S_CTRL, &control);
1690 
1691     CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
1692          __func__, fd, id, (uint32_t)value, rc);
1693     if (value != NULL) {
1694         *value = control.value;
1695     }
1696     return (rc >= 0)? 0 : -1;
1697 }
1698 
1699 /*===========================================================================
1700  * FUNCTION   : mm_camera_util_g_ctrl
1701  *
1702  * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
1703  *
1704  * PARAMETERS :
1705  *   @fd      : file descritpor for sending ioctl
1706  *   @id      : control id
1707  *   @value   : value of the ioctl to be sent
1708  *
1709  * RETURN     : int32_t type of status
1710  *              0  -- success
1711  *              -1 -- failure
1712  *==========================================================================*/
mm_camera_util_g_ctrl(int32_t fd,uint32_t id,int32_t * value)1713 int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
1714 {
1715     int rc = 0;
1716     struct v4l2_control control;
1717 
1718     memset(&control, 0, sizeof(control));
1719     control.id = id;
1720     if (value != NULL) {
1721         control.value = *value;
1722     }
1723     rc = ioctl(fd, VIDIOC_G_CTRL, &control);
1724     CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc);
1725     if (value != NULL) {
1726         *value = control.value;
1727     }
1728     return (rc >= 0)? 0 : -1;
1729 }
1730 
1731 /*===========================================================================
1732  * FUNCTION   : mm_camera_channel_advanced_capture
1733  *
1734  * DESCRIPTION: sets the channel advanced capture
1735  *
1736  * PARAMETERS :
1737  *   @my_obj       : camera object
1738  *   @advanced_capture_type : advanced capture type.
1739  *   @ch_id        : channel handle
1740  *   @start_flag  : flag to indicate start/stop
1741  *
1742  * RETURN     : int32_t type of status
1743  *              0  -- success
1744  *              -1 -- failure
1745  *==========================================================================*/
mm_camera_channel_advanced_capture(mm_camera_obj_t * my_obj,mm_camera_advanced_capture_t advanced_capture_type,uint32_t ch_id,int32_t start_flag)1746 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj,
1747                                         mm_camera_advanced_capture_t advanced_capture_type,
1748                                         uint32_t ch_id,
1749                                         int32_t start_flag)
1750 {
1751     CDBG("%s: E",__func__);
1752     int32_t rc = -1;
1753     mm_channel_t * ch_obj =
1754         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1755 
1756     if (NULL != ch_obj) {
1757         pthread_mutex_lock(&ch_obj->ch_lock);
1758         pthread_mutex_unlock(&my_obj->cam_lock);
1759         switch (advanced_capture_type) {
1760             case MM_CAMERA_AF_BRACKETING:
1761                 rc = mm_channel_fsm_fn(ch_obj,
1762                                        MM_CHANNEL_EVT_AF_BRACKETING,
1763                                        (void *)start_flag,
1764                                        NULL);
1765                 break;
1766             case MM_CAMERA_AE_BRACKETING:
1767                 rc = mm_channel_fsm_fn(ch_obj,
1768                                        MM_CHANNEL_EVT_AE_BRACKETING,
1769                                        (void *)start_flag,
1770                                        NULL);
1771                 break;
1772             case MM_CAMERA_FLASH_BRACKETING:
1773                 rc = mm_channel_fsm_fn(ch_obj,
1774                                        MM_CHANNEL_EVT_FLASH_BRACKETING,
1775                                        (void *)start_flag,
1776                                        NULL);
1777                 break;
1778             case MM_CAMERA_ZOOM_1X:
1779                 rc = mm_channel_fsm_fn(ch_obj,
1780                                        MM_CHANNEL_EVT_ZOOM_1X,
1781                                        (void *)start_flag,
1782                                        NULL);
1783                 break;
1784             default:
1785                 break;
1786         }
1787 
1788     } else {
1789         pthread_mutex_unlock(&my_obj->cam_lock);
1790     }
1791 
1792     CDBG("%s: X",__func__);
1793     return rc;
1794 }
1795