1 /* Copyright (c) 2012-2015, 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         errno = 0;
258         my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
259         CDBG("%s:  ctrl_fd = %d, errno == %d", __func__, my_obj->ctrl_fd, errno);
260         if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) {
261             CDBG_HIGH("%s:  opened, break out while loop", __func__);
262             break;
263         }
264         ALOGE("%s:Failed with %s error, retrying after %d milli-seconds",
265              __func__, strerror(errno), sleep_msec);
266         usleep(sleep_msec * 1000);
267     }while (n_try > 0);
268 
269     if (my_obj->ctrl_fd < 0) {
270         CDBG_ERROR("%s: cannot open control fd of '%s' (%s)\n",
271                  __func__, dev_name, strerror(errno));
272         rc = -1;
273         goto on_error;
274     }
275 
276     /* open domain socket*/
277     n_try = MM_CAMERA_DEV_OPEN_TRIES;
278     do {
279         n_try--;
280         my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
281         CDBG("%s:  ds_fd = %d, errno = %d", __func__, my_obj->ds_fd, errno);
282         if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {
283             CDBG("%s:  opened, break out while loop", __func__);
284             break;
285         }
286         CDBG("%s:failed with I/O error retrying after %d milli-seconds",
287              __func__, sleep_msec);
288         usleep(sleep_msec * 1000);
289     } while (n_try > 0);
290 
291     if (my_obj->ds_fd < 0) {
292         CDBG_ERROR("%s: cannot open domain socket fd of '%s'(%s)\n",
293                  __func__, dev_name, strerror(errno));
294         rc = -1;
295         goto on_error;
296     }
297     pthread_mutex_init(&my_obj->msg_lock, NULL);
298 
299     pthread_mutex_init(&my_obj->cb_lock, NULL);
300     pthread_mutex_init(&my_obj->evt_lock, NULL);
301     pthread_cond_init(&my_obj->evt_cond, NULL);
302 
303     CDBG("%s : Launch evt Thread in Cam Open",__func__);
304     mm_camera_cmd_thread_launch(&my_obj->evt_thread,
305                                 mm_camera_dispatch_app_event,
306                                 (void *)my_obj);
307 
308     /* launch event poll thread
309      * we will add evt fd into event poll thread upon user first register for evt */
310     CDBG("%s : Launch evt Poll Thread in Cam Open", __func__);
311     mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
312                                  MM_CAMERA_POLL_TYPE_EVT);
313     mm_camera_evt_sub(my_obj, TRUE);
314 
315     CDBG("%s:  end (rc = %d)\n", __func__, rc);
316     /* we do not need to unlock cam_lock here before return
317      * because for open, it's done within intf_lock */
318     return rc;
319 
320 on_error:
321     if (NULL == my_obj) {
322         CDBG_ERROR("%s: Invalid camera object\n", __func__);
323         rc = -1;
324     } else {
325         if (my_obj->ctrl_fd >= 0) {
326             close(my_obj->ctrl_fd);
327             my_obj->ctrl_fd = -1;
328         }
329         if (my_obj->ds_fd >= 0) {
330             mm_camera_socket_close(my_obj->ds_fd);
331             my_obj->ds_fd = -1;
332         }
333     }
334 
335     /* we do not need to unlock cam_lock here before return
336      * because for open, it's done within intf_lock */
337     return rc;
338 }
339 
340 /*===========================================================================
341  * FUNCTION   : mm_camera_close
342  *
343  * DESCRIPTION: enqueue received event into event queue to be processed by
344  *              event thread.
345  *
346  * PARAMETERS :
347  *   @my_obj   : ptr to a camera object
348  *   @event    : event to be queued
349  *
350  * RETURN     : int32_t type of status
351  *              0  -- success
352  *              -1 -- failure
353  *==========================================================================*/
mm_camera_close(mm_camera_obj_t * my_obj)354 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
355 {
356     CDBG("%s : unsubscribe evt", __func__);
357     mm_camera_evt_sub(my_obj, FALSE);
358 
359     CDBG("%s : Close evt Poll Thread in Cam Close",__func__);
360     mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
361 
362     CDBG("%s : Close evt cmd Thread in Cam Close",__func__);
363     mm_camera_cmd_thread_release(&my_obj->evt_thread);
364 
365     if(my_obj->ctrl_fd >= 0) {
366         close(my_obj->ctrl_fd);
367         my_obj->ctrl_fd = -1;
368     }
369     if(my_obj->ds_fd >= 0) {
370         mm_camera_socket_close(my_obj->ds_fd);
371         my_obj->ds_fd = -1;
372     }
373     pthread_mutex_destroy(&my_obj->msg_lock);
374 
375     pthread_mutex_destroy(&my_obj->cb_lock);
376     pthread_mutex_destroy(&my_obj->evt_lock);
377     pthread_cond_destroy(&my_obj->evt_cond);
378 
379     pthread_mutex_unlock(&my_obj->cam_lock);
380     return 0;
381 }
382 
383 /*===========================================================================
384  * FUNCTION   : mm_camera_close_fd
385  *
386  * DESCRIPTION: close the ctrl_fd and socket fd in case of an error so that
387  *              the backend will close
388  *              Do NOT close or release any HAL resources since a close_camera
389  *              has not been called yet.
390  * PARAMETERS :
391  *   @my_obj   : ptr to a camera object
392  *   @event    : event to be queued
393  *
394  * RETURN     : int32_t type of status
395  *              0  -- success
396  *              -1 -- failure
397  *==========================================================================*/
mm_camera_close_fd(mm_camera_obj_t * my_obj)398 int32_t mm_camera_close_fd(mm_camera_obj_t *my_obj)
399 {
400     if(my_obj->ctrl_fd >= 0) {
401         close(my_obj->ctrl_fd);
402         my_obj->ctrl_fd = -1;
403     }
404     if(my_obj->ds_fd >= 0) {
405         mm_camera_socket_close(my_obj->ds_fd);
406         my_obj->ds_fd = -1;
407     }
408     pthread_mutex_unlock(&my_obj->cam_lock);
409     return 0;
410 }
411 
412 /*===========================================================================
413  * FUNCTION   : mm_camera_register_event_notify_internal
414  *
415  * DESCRIPTION: internal implementation for registering callback for event notify.
416  *
417  * PARAMETERS :
418  *   @my_obj   : ptr to a camera object
419  *   @evt_cb   : callback to be registered to handle event notify
420  *   @user_data: user data ptr
421  *
422  * RETURN     : int32_t type of status
423  *              0  -- success
424  *              -1 -- failure
425  *==========================================================================*/
mm_camera_register_event_notify_internal(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)426 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
427                                                  mm_camera_event_notify_t evt_cb,
428                                                  void * user_data)
429 {
430     int i;
431     int rc = -1;
432     mm_camera_evt_obj_t *evt_array = NULL;
433 
434     pthread_mutex_lock(&my_obj->cb_lock);
435     evt_array = &my_obj->evt;
436     if(evt_cb) {
437         /* this is reg case */
438         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
439             if(evt_array->evt[i].user_data == NULL) {
440                 evt_array->evt[i].evt_cb = evt_cb;
441                 evt_array->evt[i].user_data = user_data;
442                 evt_array->reg_count++;
443                 rc = 0;
444                 break;
445             }
446         }
447     } else {
448         /* this is unreg case */
449         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
450             if(evt_array->evt[i].user_data == user_data) {
451                 evt_array->evt[i].evt_cb = NULL;
452                 evt_array->evt[i].user_data = NULL;
453                 evt_array->reg_count--;
454                 rc = 0;
455                 break;
456             }
457         }
458     }
459 
460     pthread_mutex_unlock(&my_obj->cb_lock);
461     return rc;
462 }
463 
464 /*===========================================================================
465  * FUNCTION   : mm_camera_register_event_notify
466  *
467  * DESCRIPTION: registering a callback for event notify.
468  *
469  * PARAMETERS :
470  *   @my_obj   : ptr to a camera object
471  *   @evt_cb   : callback to be registered to handle event notify
472  *   @user_data: user data ptr
473  *
474  * RETURN     : int32_t type of status
475  *              0  -- success
476  *              -1 -- failure
477  *==========================================================================*/
mm_camera_register_event_notify(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)478 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
479                                         mm_camera_event_notify_t evt_cb,
480                                         void * user_data)
481 {
482     int rc = -1;
483     rc = mm_camera_register_event_notify_internal(my_obj,
484                                                   evt_cb,
485                                                   user_data);
486     pthread_mutex_unlock(&my_obj->cam_lock);
487     return rc;
488 }
489 
490 /*===========================================================================
491  * FUNCTION   : mm_camera_qbuf
492  *
493  * DESCRIPTION: enqueue buffer back to kernel
494  *
495  * PARAMETERS :
496  *   @my_obj       : camera object
497  *   @ch_id        : channel handle
498  *   @buf          : buf ptr to be enqueued
499  *
500  * RETURN     : int32_t type of status
501  *              0  -- success
502  *              -1 -- failure
503  *==========================================================================*/
mm_camera_qbuf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_buf_def_t * buf)504 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
505                        uint32_t ch_id,
506                        mm_camera_buf_def_t *buf)
507 {
508     int rc = -1;
509     mm_channel_t * ch_obj = NULL;
510     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
511 
512     pthread_mutex_unlock(&my_obj->cam_lock);
513 
514     /* we always assume qbuf will be done before channel/stream is fully stopped
515      * because qbuf is done within dataCB context
516      * in order to avoid deadlock, we are not locking ch_lock for qbuf */
517     if (NULL != ch_obj) {
518         rc = mm_channel_qbuf(ch_obj, buf);
519     }
520 
521     return rc;
522 }
523 
524 /*===========================================================================
525  * FUNCTION   : mm_camera_query_capability
526  *
527  * DESCRIPTION: query camera capability
528  *
529  * PARAMETERS :
530  *   @my_obj: camera object
531  *
532  * RETURN     : int32_t type of status
533  *              0  -- success
534  *              -1 -- failure
535  *==========================================================================*/
mm_camera_query_capability(mm_camera_obj_t * my_obj)536 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
537 {
538     int32_t rc = 0;
539     struct v4l2_capability cap;
540 
541     /* get camera capabilities */
542     memset(&cap, 0, sizeof(cap));
543     rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
544     if (rc != 0) {
545         CDBG_ERROR("%s: cannot get camera capabilities, rc = %d\n", __func__, rc);
546     }
547 
548     pthread_mutex_unlock(&my_obj->cam_lock);
549     return rc;
550 
551 }
552 
553 /*===========================================================================
554  * FUNCTION   : mm_camera_set_parms
555  *
556  * DESCRIPTION: set parameters per camera
557  *
558  * PARAMETERS :
559  *   @my_obj       : camera object
560  *   @parms        : ptr to a param struct to be set to server
561  *
562  * RETURN     : int32_t type of status
563  *              0  -- success
564  *              -1 -- failure
565  * NOTE       : Assume the parms struct buf is already mapped to server via
566  *              domain socket. Corresponding fields of parameters to be set
567  *              are already filled in by upper layer caller.
568  *==========================================================================*/
mm_camera_set_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)569 int32_t mm_camera_set_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_s_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_get_parms
583  *
584  * DESCRIPTION: get parameters per camera
585  *
586  * PARAMETERS :
587  *   @my_obj       : camera object
588  *   @parms        : ptr to a param struct to be get from server
589  *
590  * RETURN     : int32_t type of status
591  *              0  -- success
592  *              -1 -- failure
593  * NOTE       : Assume the parms struct buf is already mapped to server via
594  *              domain socket. Parameters to be get from server are already
595  *              filled in by upper layer caller. After this call, corresponding
596  *              fields of requested parameters will be filled in by server with
597  *              detailed information.
598  *==========================================================================*/
mm_camera_get_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)599 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
600                             parm_buffer_t *parms)
601 {
602     int32_t rc = -1;
603     int32_t value = 0;
604     if (parms != NULL) {
605         rc = mm_camera_util_g_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
606     }
607     pthread_mutex_unlock(&my_obj->cam_lock);
608     return rc;
609 }
610 
611 /*===========================================================================
612  * FUNCTION   : mm_camera_do_auto_focus
613  *
614  * DESCRIPTION: performing auto focus
615  *
616  * PARAMETERS :
617  *   @camera_handle: camera handle
618  *
619  * RETURN     : int32_t type of status
620  *              0  -- success
621  *              -1 -- failure
622  * NOTE       : if this call success, we will always assume there will
623  *              be an auto_focus event following up.
624  *==========================================================================*/
mm_camera_do_auto_focus(mm_camera_obj_t * my_obj)625 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
626 {
627     int32_t rc = -1;
628     int32_t value = 0;
629     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
630     pthread_mutex_unlock(&my_obj->cam_lock);
631     return rc;
632 }
633 
634 /*===========================================================================
635  * FUNCTION   : mm_camera_cancel_auto_focus
636  *
637  * DESCRIPTION: cancel auto focus
638  *
639  * PARAMETERS :
640  *   @camera_handle: camera handle
641  *
642  * RETURN     : int32_t type of status
643  *              0  -- success
644  *              -1 -- failure
645  *==========================================================================*/
mm_camera_cancel_auto_focus(mm_camera_obj_t * my_obj)646 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
647 {
648     int32_t rc = -1;
649     int32_t value = 0;
650     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
651     pthread_mutex_unlock(&my_obj->cam_lock);
652     return rc;
653 }
654 
655 /*===========================================================================
656  * FUNCTION   : mm_camera_prepare_snapshot
657  *
658  * DESCRIPTION: prepare hardware for snapshot
659  *
660  * PARAMETERS :
661  *   @my_obj       : camera object
662  *   @do_af_flag   : flag indicating if AF is needed
663  *
664  * RETURN     : int32_t type of status
665  *              0  -- success
666  *              -1 -- failure
667  *==========================================================================*/
mm_camera_prepare_snapshot(mm_camera_obj_t * my_obj,int32_t do_af_flag)668 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
669                                    int32_t do_af_flag)
670 {
671     int32_t rc = -1;
672     int32_t value = do_af_flag;
673     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
674     pthread_mutex_unlock(&my_obj->cam_lock);
675     return rc;
676 }
677 
678 /*===========================================================================
679  * FUNCTION   : mm_camera_start_zsl_snapshot
680  *
681  * DESCRIPTION: start zsl snapshot
682  *
683  * PARAMETERS :
684  *   @my_obj       : camera object
685  *
686  * RETURN     : int32_t type of status
687  *              0  -- success
688  *              -1 -- failure
689  *==========================================================================*/
mm_camera_start_zsl_snapshot(mm_camera_obj_t * my_obj)690 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
691 {
692     int32_t rc = -1;
693     int32_t value = 0;
694 
695     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
696              CAM_PRIV_START_ZSL_SNAPSHOT, &value);
697     return rc;
698 }
699 
700 /*===========================================================================
701  * FUNCTION   : mm_camera_stop_zsl_snapshot
702  *
703  * DESCRIPTION: stop zsl capture
704  *
705  * PARAMETERS :
706  *   @my_obj       : camera object
707  *
708  * RETURN     : int32_t type of status
709  *              0  -- success
710  *              -1 -- failure
711  *==========================================================================*/
mm_camera_stop_zsl_snapshot(mm_camera_obj_t * my_obj)712 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
713 {
714     int32_t rc = -1;
715     int32_t value;
716     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
717              CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
718     return rc;
719 }
720 
721 /*===========================================================================
722  * FUNCTION   : mm_camera_add_channel
723  *
724  * DESCRIPTION: add a channel
725  *
726  * PARAMETERS :
727  *   @my_obj       : camera object
728  *   @attr         : bundle attribute of the channel if needed
729  *   @channel_cb   : callback function for bundle data notify
730  *   @userdata     : user data ptr
731  *
732  * RETURN     : uint32_t type of channel handle
733  *              0  -- invalid channel handle, meaning the op failed
734  *              >0 -- successfully added a channel with a valid handle
735  * NOTE       : if no bundle data notify is needed, meaning each stream in the
736  *              channel will have its own stream data notify callback, then
737  *              attr, channel_cb, and userdata can be NULL. In this case,
738  *              no matching logic will be performed in channel for the bundling.
739  *==========================================================================*/
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)740 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
741                                mm_camera_channel_attr_t *attr,
742                                mm_camera_buf_notify_t channel_cb,
743                                void *userdata)
744 {
745     mm_channel_t *ch_obj = NULL;
746     uint8_t ch_idx = 0;
747     uint32_t ch_hdl = 0;
748 
749     for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
750         if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
751             ch_obj = &my_obj->ch[ch_idx];
752             break;
753         }
754     }
755 
756     if (NULL != ch_obj) {
757         /* initialize channel obj */
758         memset(ch_obj, 0, sizeof(mm_channel_t));
759         ch_hdl = mm_camera_util_generate_handler(ch_idx);
760         ch_obj->my_hdl = ch_hdl;
761         ch_obj->state = MM_CHANNEL_STATE_STOPPED;
762         ch_obj->cam_obj = my_obj;
763         pthread_mutex_init(&ch_obj->ch_lock, NULL);
764         mm_channel_init(ch_obj, attr, channel_cb, userdata);
765     }
766 
767     pthread_mutex_unlock(&my_obj->cam_lock);
768 
769     return ch_hdl;
770 }
771 
772 /*===========================================================================
773  * FUNCTION   : mm_camera_del_channel
774  *
775  * DESCRIPTION: delete a channel by its handle
776  *
777  * PARAMETERS :
778  *   @my_obj       : camera object
779  *   @ch_id        : channel handle
780  *
781  * RETURN     : int32_t type of status
782  *              0  -- success
783  *              -1 -- failure
784  * NOTE       : all streams in the channel should be stopped already before
785  *              this channel can be deleted.
786  *==========================================================================*/
mm_camera_del_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)787 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
788                               uint32_t ch_id)
789 {
790     int32_t rc = -1;
791     mm_channel_t * ch_obj =
792         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
793 
794     if (NULL != ch_obj) {
795         pthread_mutex_lock(&ch_obj->ch_lock);
796         pthread_mutex_unlock(&my_obj->cam_lock);
797 
798         rc = mm_channel_fsm_fn(ch_obj,
799                                MM_CHANNEL_EVT_DELETE,
800                                NULL,
801                                NULL);
802 
803         pthread_mutex_destroy(&ch_obj->ch_lock);
804         memset(ch_obj, 0, sizeof(mm_channel_t));
805     } else {
806         pthread_mutex_unlock(&my_obj->cam_lock);
807     }
808     return rc;
809 }
810 
811 /*===========================================================================
812  * FUNCTION   : mm_camera_get_bundle_info
813  *
814  * DESCRIPTION: query bundle info of the channel
815  *
816  * PARAMETERS :
817  *   @my_obj       : camera object
818  *   @ch_id        : channel handle
819  *   @bundle_info  : bundle info to be filled in
820  *
821  * RETURN     : int32_t type of status
822  *              0  -- success
823  *              -1 -- failure
824  * NOTE       : all streams in the channel should be stopped already before
825  *              this channel can be deleted.
826  *==========================================================================*/
mm_camera_get_bundle_info(mm_camera_obj_t * my_obj,uint32_t ch_id,cam_bundle_config_t * bundle_info)827 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
828                                   uint32_t ch_id,
829                                   cam_bundle_config_t *bundle_info)
830 {
831     int32_t rc = -1;
832     mm_channel_t * ch_obj =
833         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
834 
835     if (NULL != ch_obj) {
836         pthread_mutex_lock(&ch_obj->ch_lock);
837         pthread_mutex_unlock(&my_obj->cam_lock);
838 
839         rc = mm_channel_fsm_fn(ch_obj,
840                                MM_CHANNEL_EVT_GET_BUNDLE_INFO,
841                                (void *)bundle_info,
842                                NULL);
843     } else {
844         pthread_mutex_unlock(&my_obj->cam_lock);
845     }
846     return rc;
847 }
848 
849 /*===========================================================================
850  * FUNCTION   : mm_camera_add_stream
851  *
852  * DESCRIPTION: add a stream into a channel
853  *
854  * PARAMETERS :
855  *   @my_obj       : camera object
856  *   @ch_id        : channel handle
857  *
858  * RETURN     : uint32_t type of stream handle
859  *              0  -- invalid stream handle, meaning the op failed
860  *              >0 -- successfully added a stream with a valid handle
861  *==========================================================================*/
mm_camera_add_stream(mm_camera_obj_t * my_obj,uint32_t ch_id)862 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
863                               uint32_t ch_id)
864 {
865     uint32_t s_hdl = 0;
866     mm_channel_t * ch_obj =
867         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
868 
869     if (NULL != ch_obj) {
870         pthread_mutex_lock(&ch_obj->ch_lock);
871         pthread_mutex_unlock(&my_obj->cam_lock);
872 
873         mm_channel_fsm_fn(ch_obj,
874                           MM_CHANNEL_EVT_ADD_STREAM,
875                           NULL,
876                           (void*)&s_hdl);
877     } else {
878         pthread_mutex_unlock(&my_obj->cam_lock);
879     }
880 
881     return s_hdl;
882 }
883 
884 /*===========================================================================
885  * FUNCTION   : mm_camera_del_stream
886  *
887  * DESCRIPTION: delete a stream by its handle
888  *
889  * PARAMETERS :
890  *   @my_obj       : camera object
891  *   @ch_id        : channel handle
892  *   @stream_id    : stream handle
893  *
894  * RETURN     : int32_t type of status
895  *              0  -- success
896  *              -1 -- failure
897  * NOTE       : stream should be stopped already before it can be deleted.
898  *==========================================================================*/
mm_camera_del_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)899 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
900                              uint32_t ch_id,
901                              uint32_t stream_id)
902 {
903     int32_t rc = -1;
904     mm_channel_t * ch_obj =
905         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
906 
907     if (NULL != ch_obj) {
908         pthread_mutex_lock(&ch_obj->ch_lock);
909         pthread_mutex_unlock(&my_obj->cam_lock);
910 
911         rc = mm_channel_fsm_fn(ch_obj,
912                                MM_CHANNEL_EVT_DEL_STREAM,
913                                (void*)stream_id,
914                                NULL);
915     } else {
916         pthread_mutex_unlock(&my_obj->cam_lock);
917     }
918 
919     return rc;
920 }
921 
922 /*===========================================================================
923  * FUNCTION   : mm_camera_start_zsl_snapshot_ch
924  *
925  * DESCRIPTION: starts zsl snapshot for specific channel
926  *
927  * PARAMETERS :
928  *   @my_obj       : camera object
929  *   @ch_id        : channel handle
930  *
931  * RETURN     : int32_t type of status
932  *              0  -- success
933  *              -1 -- failure
934  *==========================================================================*/
mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)935 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
936         uint32_t ch_id)
937 {
938     int32_t rc = -1;
939     mm_channel_t * ch_obj =
940         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
941 
942     if (NULL != ch_obj) {
943         pthread_mutex_lock(&ch_obj->ch_lock);
944         pthread_mutex_unlock(&my_obj->cam_lock);
945 
946         rc = mm_channel_fsm_fn(ch_obj,
947                                MM_CHANNEL_EVT_START_ZSL_SNAPSHOT,
948                                NULL,
949                                NULL);
950     } else {
951         pthread_mutex_unlock(&my_obj->cam_lock);
952     }
953 
954     return rc;
955 }
956 
957 /*===========================================================================
958  * FUNCTION   : mm_camera_stop_zsl_snapshot_ch
959  *
960  * DESCRIPTION: stops zsl snapshot for specific channel
961  *
962  * PARAMETERS :
963  *   @my_obj       : camera object
964  *   @ch_id        : channel handle
965  *
966  * RETURN     : int32_t type of status
967  *              0  -- success
968  *              -1 -- failure
969  *==========================================================================*/
mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)970 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
971         uint32_t ch_id)
972 {
973     int32_t rc = -1;
974     mm_channel_t * ch_obj =
975         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
976 
977     if (NULL != ch_obj) {
978         pthread_mutex_lock(&ch_obj->ch_lock);
979         pthread_mutex_unlock(&my_obj->cam_lock);
980 
981         rc = mm_channel_fsm_fn(ch_obj,
982                                MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT,
983                                NULL,
984                                NULL);
985     } else {
986         pthread_mutex_unlock(&my_obj->cam_lock);
987     }
988 
989     return rc;
990 }
991 
992 /*===========================================================================
993  * FUNCTION   : mm_camera_config_stream
994  *
995  * DESCRIPTION: configure a stream
996  *
997  * PARAMETERS :
998  *   @my_obj       : camera object
999  *   @ch_id        : channel handle
1000  *   @stream_id    : stream handle
1001  *   @config       : stream configuration
1002  *
1003  * RETURN     : int32_t type of status
1004  *              0  -- success
1005  *              -1 -- failure
1006  *==========================================================================*/
mm_camera_config_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)1007 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
1008                                 uint32_t ch_id,
1009                                 uint32_t stream_id,
1010                                 mm_camera_stream_config_t *config)
1011 {
1012     int32_t rc = -1;
1013     mm_channel_t * ch_obj =
1014         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1015     mm_evt_paylod_config_stream_t payload;
1016 
1017     if (NULL != ch_obj) {
1018         pthread_mutex_lock(&ch_obj->ch_lock);
1019         pthread_mutex_unlock(&my_obj->cam_lock);
1020 
1021         memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
1022         payload.stream_id = stream_id;
1023         payload.config = config;
1024         rc = mm_channel_fsm_fn(ch_obj,
1025                                MM_CHANNEL_EVT_CONFIG_STREAM,
1026                                (void*)&payload,
1027                                NULL);
1028     } else {
1029         pthread_mutex_unlock(&my_obj->cam_lock);
1030     }
1031 
1032     return rc;
1033 }
1034 
1035 /*===========================================================================
1036  * FUNCTION   : mm_camera_start_channel
1037  *
1038  * DESCRIPTION: start a channel, which will start all streams in the channel
1039  *
1040  * PARAMETERS :
1041  *   @my_obj       : camera object
1042  *   @ch_id        : channel handle
1043  *
1044  * RETURN     : int32_t type of status
1045  *              0  -- success
1046  *              -1 -- failure
1047  *==========================================================================*/
mm_camera_start_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1048 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj,
1049                                 uint32_t ch_id)
1050 {
1051     int32_t rc = -1;
1052     mm_channel_t * ch_obj =
1053         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1054 
1055     if (NULL != ch_obj) {
1056         pthread_mutex_lock(&ch_obj->ch_lock);
1057         pthread_mutex_unlock(&my_obj->cam_lock);
1058 
1059         rc = mm_channel_fsm_fn(ch_obj,
1060                                MM_CHANNEL_EVT_START,
1061                                NULL,
1062                                NULL);
1063     } else {
1064         pthread_mutex_unlock(&my_obj->cam_lock);
1065     }
1066 
1067     return rc;
1068 }
1069 
1070 /*===========================================================================
1071  * FUNCTION   : mm_camera_stop_channel
1072  *
1073  * DESCRIPTION: stop a channel, which will stop all streams in the channel
1074  *
1075  * PARAMETERS :
1076  *   @my_obj       : camera object
1077  *   @ch_id        : channel handle
1078  *
1079  * RETURN     : int32_t type of status
1080  *              0  -- success
1081  *              -1 -- failure
1082  *==========================================================================*/
mm_camera_stop_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1083 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
1084                                uint32_t ch_id)
1085 {
1086     int32_t rc = 0;
1087     mm_channel_t * ch_obj =
1088         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1089 
1090     if (NULL != ch_obj) {
1091         pthread_mutex_lock(&ch_obj->ch_lock);
1092         pthread_mutex_unlock(&my_obj->cam_lock);
1093 
1094         rc = mm_channel_fsm_fn(ch_obj,
1095                                MM_CHANNEL_EVT_STOP,
1096                                NULL,
1097                                NULL);
1098     } else {
1099         pthread_mutex_unlock(&my_obj->cam_lock);
1100     }
1101     return rc;
1102 }
1103 
1104 /*===========================================================================
1105  * FUNCTION   : mm_camera_request_super_buf
1106  *
1107  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1108  *              frames from superbuf queue
1109  *
1110  * PARAMETERS :
1111  *   @my_obj       : camera object
1112  *   @ch_id        : channel handle
1113  *   @num_buf_requested : number of matched frames needed
1114  *
1115  * RETURN     : int32_t type of status
1116  *              0  -- success
1117  *              -1 -- failure
1118  *==========================================================================*/
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)1119 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1120                                     uint32_t ch_id,
1121                                     uint32_t num_buf_requested,
1122                                     uint32_t num_retro_buf_requested)
1123 {
1124     int32_t rc = -1;
1125     mm_channel_t * ch_obj =
1126         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1127 
1128     if (NULL != ch_obj) {
1129         pthread_mutex_lock(&ch_obj->ch_lock);
1130         pthread_mutex_unlock(&my_obj->cam_lock);
1131 
1132         rc = mm_channel_fsm_fn(ch_obj,
1133                                MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
1134                                (void*)num_buf_requested,
1135                                (void*)num_retro_buf_requested);
1136     } else {
1137         pthread_mutex_unlock(&my_obj->cam_lock);
1138     }
1139 
1140     return rc;
1141 }
1142 
1143 /*===========================================================================
1144  * FUNCTION   : mm_camera_cancel_super_buf_request
1145  *
1146  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
1147  *              of matched frames from superbuf queue
1148  *
1149  * PARAMETERS :
1150  *   @my_obj       : camera object
1151  *   @ch_id        : channel handle
1152  *
1153  * RETURN     : int32_t type of status
1154  *              0  -- success
1155  *              -1 -- failure
1156  *==========================================================================*/
mm_camera_cancel_super_buf_request(mm_camera_obj_t * my_obj,uint32_t ch_id)1157 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
1158 {
1159     int32_t rc = -1;
1160     mm_channel_t * ch_obj =
1161         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1162 
1163     if (NULL != ch_obj) {
1164         pthread_mutex_lock(&ch_obj->ch_lock);
1165         pthread_mutex_unlock(&my_obj->cam_lock);
1166 
1167         rc = mm_channel_fsm_fn(ch_obj,
1168                                MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
1169                                NULL,
1170                                NULL);
1171     } else {
1172         pthread_mutex_unlock(&my_obj->cam_lock);
1173     }
1174 
1175     return rc;
1176 }
1177 
1178 /*===========================================================================
1179  * FUNCTION   : mm_camera_flush_super_buf_queue
1180  *
1181  * DESCRIPTION: flush out all frames in the superbuf queue
1182  *
1183  * PARAMETERS :
1184  *   @my_obj       : camera object
1185  *   @ch_id        : channel handle
1186  *
1187  * RETURN     : int32_t type of status
1188  *              0  -- success
1189  *              -1 -- failure
1190  *==========================================================================*/
mm_camera_flush_super_buf_queue(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t frame_idx)1191 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
1192                                                              uint32_t frame_idx)
1193 {
1194     int32_t rc = -1;
1195     mm_channel_t * ch_obj =
1196         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1197 
1198     if (NULL != ch_obj) {
1199         pthread_mutex_lock(&ch_obj->ch_lock);
1200         pthread_mutex_unlock(&my_obj->cam_lock);
1201 
1202         rc = mm_channel_fsm_fn(ch_obj,
1203                                MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
1204                                (void *)frame_idx,
1205                                NULL);
1206     } else {
1207         pthread_mutex_unlock(&my_obj->cam_lock);
1208     }
1209 
1210     return rc;
1211 }
1212 
1213 /*===========================================================================
1214  * FUNCTION   : mm_camera_config_channel_notify
1215  *
1216  * DESCRIPTION: configures the channel notification mode
1217  *
1218  * PARAMETERS :
1219  *   @my_obj       : camera object
1220  *   @ch_id        : channel handle
1221  *   @notify_mode  : notification mode
1222  *
1223  * RETURN     : int32_t type of status
1224  *              0  -- success
1225  *              -1 -- failure
1226  *==========================================================================*/
mm_camera_config_channel_notify(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)1227 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
1228                                         uint32_t ch_id,
1229                                         mm_camera_super_buf_notify_mode_t notify_mode)
1230 {
1231     int32_t rc = -1;
1232     mm_channel_t * ch_obj =
1233         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1234 
1235     if (NULL != ch_obj) {
1236         pthread_mutex_lock(&ch_obj->ch_lock);
1237         pthread_mutex_unlock(&my_obj->cam_lock);
1238 
1239         rc = mm_channel_fsm_fn(ch_obj,
1240                                MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
1241                                (void *)notify_mode,
1242                                NULL);
1243     } else {
1244         pthread_mutex_unlock(&my_obj->cam_lock);
1245     }
1246 
1247     return rc;
1248 }
1249 
1250 /*===========================================================================
1251  * FUNCTION   : mm_camera_set_stream_parms
1252  *
1253  * DESCRIPTION: set parameters per stream
1254  *
1255  * PARAMETERS :
1256  *   @my_obj       : camera object
1257  *   @ch_id        : channel handle
1258  *   @s_id         : stream handle
1259  *   @parms        : ptr to a param struct to be set to server
1260  *
1261  * RETURN     : int32_t type of status
1262  *              0  -- success
1263  *              -1 -- failure
1264  * NOTE       : Assume the parms struct buf is already mapped to server via
1265  *              domain socket. Corresponding fields of parameters to be set
1266  *              are already filled in by upper layer caller.
1267  *==========================================================================*/
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)1268 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
1269                                    uint32_t ch_id,
1270                                    uint32_t s_id,
1271                                    cam_stream_parm_buffer_t *parms)
1272 {
1273     int32_t rc = -1;
1274     mm_evt_paylod_set_get_stream_parms_t payload;
1275     mm_channel_t * ch_obj =
1276         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1277 
1278     if (NULL != ch_obj) {
1279         pthread_mutex_lock(&ch_obj->ch_lock);
1280         pthread_mutex_unlock(&my_obj->cam_lock);
1281 
1282         memset(&payload, 0, sizeof(payload));
1283         payload.stream_id = s_id;
1284         payload.parms = parms;
1285 
1286         rc = mm_channel_fsm_fn(ch_obj,
1287                                MM_CHANNEL_EVT_SET_STREAM_PARM,
1288                                (void *)&payload,
1289                                NULL);
1290     } else {
1291         pthread_mutex_unlock(&my_obj->cam_lock);
1292     }
1293 
1294     return rc;
1295 }
1296 
1297 /*===========================================================================
1298  * FUNCTION   : mm_camera_get_stream_parms
1299  *
1300  * DESCRIPTION: get parameters per stream
1301  *
1302  * PARAMETERS :
1303  *   @my_obj       : camera object
1304  *   @ch_id        : channel handle
1305  *   @s_id         : stream handle
1306  *   @parms        : ptr to a param struct to be get from server
1307  *
1308  * RETURN     : int32_t type of status
1309  *              0  -- success
1310  *              -1 -- failure
1311  * NOTE       : Assume the parms struct buf is already mapped to server via
1312  *              domain socket. Parameters to be get from server are already
1313  *              filled in by upper layer caller. After this call, corresponding
1314  *              fields of requested parameters will be filled in by server with
1315  *              detailed information.
1316  *==========================================================================*/
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)1317 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
1318                                    uint32_t ch_id,
1319                                    uint32_t s_id,
1320                                    cam_stream_parm_buffer_t *parms)
1321 {
1322     int32_t rc = -1;
1323     mm_evt_paylod_set_get_stream_parms_t payload;
1324     mm_channel_t * ch_obj =
1325         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1326 
1327     if (NULL != ch_obj) {
1328         pthread_mutex_lock(&ch_obj->ch_lock);
1329         pthread_mutex_unlock(&my_obj->cam_lock);
1330 
1331         memset(&payload, 0, sizeof(payload));
1332         payload.stream_id = s_id;
1333         payload.parms = parms;
1334 
1335         rc = mm_channel_fsm_fn(ch_obj,
1336                                MM_CHANNEL_EVT_GET_STREAM_PARM,
1337                                (void *)&payload,
1338                                NULL);
1339     } else {
1340         pthread_mutex_unlock(&my_obj->cam_lock);
1341     }
1342 
1343     return rc;
1344 }
1345 
1346 /*===========================================================================
1347  * FUNCTION   : mm_camera_do_stream_action
1348  *
1349  * DESCRIPTION: request server to perform stream based action. Maybe removed later
1350  *              if the functionality is included in mm_camera_set_parms
1351  *
1352  * PARAMETERS :
1353  *   @my_obj       : camera object
1354  *   @ch_id        : channel handle
1355  *   @s_id         : stream handle
1356  *   @actions      : ptr to an action struct buf to be performed by server
1357  *
1358  * RETURN     : int32_t type of status
1359  *              0  -- success
1360  *              -1 -- failure
1361  * NOTE       : Assume the action struct buf is already mapped to server via
1362  *              domain socket. Actions to be performed by server are already
1363  *              filled in by upper layer caller.
1364  *==========================================================================*/
mm_camera_do_stream_action(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,void * actions)1365 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
1366                                    uint32_t ch_id,
1367                                    uint32_t stream_id,
1368                                    void *actions)
1369 {
1370     int32_t rc = -1;
1371     mm_evt_paylod_do_stream_action_t payload;
1372     mm_channel_t * ch_obj =
1373         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1374 
1375     if (NULL != ch_obj) {
1376         pthread_mutex_lock(&ch_obj->ch_lock);
1377         pthread_mutex_unlock(&my_obj->cam_lock);
1378 
1379         memset(&payload, 0, sizeof(payload));
1380         payload.stream_id = stream_id;
1381         payload.actions = actions;
1382 
1383         rc = mm_channel_fsm_fn(ch_obj,
1384                                MM_CHANNEL_EVT_DO_STREAM_ACTION,
1385                                (void*)&payload,
1386                                NULL);
1387     } else {
1388         pthread_mutex_unlock(&my_obj->cam_lock);
1389     }
1390 
1391     return rc;
1392 }
1393 
1394 /*===========================================================================
1395  * FUNCTION   : mm_camera_map_stream_buf
1396  *
1397  * DESCRIPTION: mapping stream buffer via domain socket to server
1398  *
1399  * PARAMETERS :
1400  *   @my_obj       : camera object
1401  *   @ch_id        : channel handle
1402  *   @s_id         : stream handle
1403  *   @buf_type     : type of buffer to be mapped. could be following values:
1404  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1405  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1406  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1407  *   @buf_idx      : index of buffer within the stream buffers, only valid if
1408  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1409  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1410  *   @plane_idx    : plane index. If all planes share the same fd,
1411  *                   plane_idx = -1; otherwise, plean_idx is the
1412  *                   index to plane (0..num_of_planes)
1413  *   @fd           : file descriptor of the buffer
1414  *   @size         : size of the buffer
1415  *
1416  * RETURN     : int32_t type of status
1417  *              0  -- success
1418  *              -1 -- failure
1419  *==========================================================================*/
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)1420 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
1421                                  uint32_t ch_id,
1422                                  uint32_t stream_id,
1423                                  uint8_t buf_type,
1424                                  uint32_t buf_idx,
1425                                  int32_t plane_idx,
1426                                  int fd,
1427                                  uint32_t size)
1428 {
1429     int32_t rc = -1;
1430     mm_evt_paylod_map_stream_buf_t payload;
1431     mm_channel_t * ch_obj =
1432         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1433 
1434     if (NULL != ch_obj) {
1435         pthread_mutex_lock(&ch_obj->ch_lock);
1436         pthread_mutex_unlock(&my_obj->cam_lock);
1437 
1438         memset(&payload, 0, sizeof(payload));
1439         payload.stream_id = stream_id;
1440         payload.buf_type = buf_type;
1441         payload.buf_idx = buf_idx;
1442         payload.plane_idx = plane_idx;
1443         payload.fd = fd;
1444         payload.size = size;
1445         rc = mm_channel_fsm_fn(ch_obj,
1446                                MM_CHANNEL_EVT_MAP_STREAM_BUF,
1447                                (void*)&payload,
1448                                NULL);
1449     } else {
1450         pthread_mutex_unlock(&my_obj->cam_lock);
1451     }
1452 
1453     return rc;
1454 }
1455 
1456 /*===========================================================================
1457  * FUNCTION   : mm_camera_unmap_stream_buf
1458  *
1459  * DESCRIPTION: unmapping stream buffer via domain socket to server
1460  *
1461  * PARAMETERS :
1462  *   @my_obj       : camera object
1463  *   @ch_id        : channel handle
1464  *   @s_id         : stream handle
1465  *   @buf_type     : type of buffer to be mapped. could be following values:
1466  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1467  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1468  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1469  *   @buf_idx      : index of buffer within the stream buffers, only valid if
1470  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1471  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1472  *   @plane_idx    : plane index. If all planes share the same fd,
1473  *                   plane_idx = -1; otherwise, plean_idx is the
1474  *                   index to plane (0..num_of_planes)
1475  *
1476  * RETURN     : int32_t type of status
1477  *              0  -- success
1478  *              -1 -- failure
1479  *==========================================================================*/
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)1480 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
1481                                    uint32_t ch_id,
1482                                    uint32_t stream_id,
1483                                    uint8_t buf_type,
1484                                    uint32_t buf_idx,
1485                                    int32_t plane_idx)
1486 {
1487     int32_t rc = -1;
1488     mm_evt_paylod_unmap_stream_buf_t payload;
1489     mm_channel_t * ch_obj =
1490         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1491 
1492     if (NULL != ch_obj) {
1493         pthread_mutex_lock(&ch_obj->ch_lock);
1494         pthread_mutex_unlock(&my_obj->cam_lock);
1495 
1496         memset(&payload, 0, sizeof(payload));
1497         payload.stream_id = stream_id;
1498         payload.buf_type = buf_type;
1499         payload.buf_idx = buf_idx;
1500         payload.plane_idx = plane_idx;
1501         rc = mm_channel_fsm_fn(ch_obj,
1502                                MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
1503                                (void*)&payload,
1504                                NULL);
1505     } else {
1506         pthread_mutex_unlock(&my_obj->cam_lock);
1507     }
1508 
1509     return rc;
1510 }
1511 
1512 /*===========================================================================
1513  * FUNCTION   : mm_camera_evt_sub
1514  *
1515  * DESCRIPTION: subscribe/unsubscribe event notify from kernel
1516  *
1517  * PARAMETERS :
1518  *   @my_obj       : camera object
1519  *   @reg_flag     : 1 -- subscribe ; 0 -- unsubscribe
1520  *
1521  * RETURN     : int32_t type of status
1522  *              0  -- success
1523  *              -1 -- failure
1524  *==========================================================================*/
mm_camera_evt_sub(mm_camera_obj_t * my_obj,uint8_t reg_flag)1525 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1526                           uint8_t reg_flag)
1527 {
1528     int32_t rc = 0;
1529     struct v4l2_event_subscription sub;
1530 
1531     memset(&sub, 0, sizeof(sub));
1532     sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
1533     sub.id = MSM_CAMERA_MSM_NOTIFY;
1534     if(FALSE == reg_flag) {
1535         /* unsubscribe */
1536         rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1537         if (rc < 0) {
1538             CDBG_ERROR("%s: unsubscribe event rc = %d", __func__, rc);
1539             return rc;
1540         }
1541         /* remove evt fd from the polling thraed when unreg the last event */
1542         rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
1543                                                my_obj->my_hdl,
1544                                                mm_camera_sync_call);
1545     } else {
1546         rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1547         if (rc < 0) {
1548             CDBG_ERROR("%s: subscribe event rc = %d", __func__, rc);
1549             return rc;
1550         }
1551         /* add evt fd to polling thread when subscribe the first event */
1552         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1553                                                my_obj->my_hdl,
1554                                                my_obj->ctrl_fd,
1555                                                mm_camera_event_notify,
1556                                                (void*)my_obj,
1557                                                mm_camera_sync_call);
1558     }
1559     return rc;
1560 }
1561 
1562 /*===========================================================================
1563  * FUNCTION   : mm_camera_util_wait_for_event
1564  *
1565  * DESCRIPTION: utility function to wait for certain events
1566  *
1567  * PARAMETERS :
1568  *   @my_obj       : camera object
1569  *   @evt_mask     : mask for events to be waited. Any of event in the mask would
1570  *                   trigger the wait to end
1571  *   @status       : status of the event
1572  *
1573  * RETURN     : none
1574  *==========================================================================*/
mm_camera_util_wait_for_event(mm_camera_obj_t * my_obj,uint32_t evt_mask,int32_t * status)1575 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
1576                                    uint32_t evt_mask,
1577                                    int32_t *status)
1578 {
1579     pthread_mutex_lock(&my_obj->evt_lock);
1580     while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
1581         pthread_cond_wait(&my_obj->evt_cond, &my_obj->evt_lock);
1582     }
1583     *status = my_obj->evt_rcvd.status;
1584     /* reset local storage for recieved event for next event */
1585     memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
1586     pthread_mutex_unlock(&my_obj->evt_lock);
1587 }
1588 
1589 /*===========================================================================
1590  * FUNCTION   : mm_camera_util_sendmsg
1591  *
1592  * DESCRIPTION: utility function to send msg via domain socket
1593  *
1594  * PARAMETERS :
1595  *   @my_obj       : camera object
1596  *   @msg          : message to be sent
1597  *   @buf_size     : size of the message to be sent
1598  *   @sendfd       : >0 if any file descriptor need to be passed across process
1599  *
1600  * RETURN     : int32_t type of status
1601  *              0  -- success
1602  *              -1 -- failure
1603  *==========================================================================*/
mm_camera_util_sendmsg(mm_camera_obj_t * my_obj,void * msg,uint32_t buf_size,int sendfd)1604 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
1605                                void *msg,
1606                                uint32_t buf_size,
1607                                int sendfd)
1608 {
1609     int32_t rc = -1;
1610     int32_t status;
1611 
1612     /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
1613     pthread_mutex_lock(&my_obj->msg_lock);
1614     if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
1615         /* wait for event that mapping/unmapping is done */
1616         mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1617         if (MSM_CAMERA_STATUS_SUCCESS == status) {
1618             rc = 0;
1619         }
1620     }
1621     pthread_mutex_unlock(&my_obj->msg_lock);
1622     return rc;
1623 }
1624 
1625 /*===========================================================================
1626  * FUNCTION   : mm_camera_map_buf
1627  *
1628  * DESCRIPTION: mapping camera buffer via domain socket to server
1629  *
1630  * PARAMETERS :
1631  *   @my_obj       : camera object
1632  *   @buf_type     : type of buffer to be mapped. could be following values:
1633  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1634  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1635  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1636  *   @fd           : file descriptor of the buffer
1637  *   @size         : size of the buffer
1638  *
1639  * RETURN     : int32_t type of status
1640  *              0  -- success
1641  *              -1 -- failure
1642  *==========================================================================*/
mm_camera_map_buf(mm_camera_obj_t * my_obj,uint8_t buf_type,int fd,uint32_t size)1643 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1644                           uint8_t buf_type,
1645                           int fd,
1646                           uint32_t size)
1647 {
1648     int32_t rc = 0;
1649     cam_sock_packet_t packet;
1650     memset(&packet, 0, sizeof(cam_sock_packet_t));
1651     packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
1652     packet.payload.buf_map.type = buf_type;
1653     packet.payload.buf_map.fd = fd;
1654     packet.payload.buf_map.size = size;
1655     rc = mm_camera_util_sendmsg(my_obj,
1656                                 &packet,
1657                                 sizeof(cam_sock_packet_t),
1658                                 fd);
1659     pthread_mutex_unlock(&my_obj->cam_lock);
1660     return rc;
1661 }
1662 
1663 /*===========================================================================
1664  * FUNCTION   : mm_camera_unmap_buf
1665  *
1666  * DESCRIPTION: unmapping camera buffer via domain socket to server
1667  *
1668  * PARAMETERS :
1669  *   @my_obj       : camera object
1670  *   @buf_type     : type of buffer to be mapped. could be following values:
1671  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1672  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1673  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1674  *
1675  * RETURN     : int32_t type of status
1676  *              0  -- success
1677  *              -1 -- failure
1678  *==========================================================================*/
mm_camera_unmap_buf(mm_camera_obj_t * my_obj,uint8_t buf_type)1679 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
1680                             uint8_t buf_type)
1681 {
1682     int32_t rc = 0;
1683     cam_sock_packet_t packet;
1684     memset(&packet, 0, sizeof(cam_sock_packet_t));
1685     packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
1686     packet.payload.buf_unmap.type = buf_type;
1687     rc = mm_camera_util_sendmsg(my_obj,
1688                                 &packet,
1689                                 sizeof(cam_sock_packet_t),
1690                                 0);
1691     pthread_mutex_unlock(&my_obj->cam_lock);
1692     return rc;
1693 }
1694 
1695 /*===========================================================================
1696  * FUNCTION   : mm_camera_util_s_ctrl
1697  *
1698  * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
1699  *
1700  * PARAMETERS :
1701  *   @fd      : file descritpor for sending ioctl
1702  *   @id      : control id
1703  *   @value   : value of the ioctl to be sent
1704  *
1705  * RETURN     : int32_t type of status
1706  *              0  -- success
1707  *              -1 -- failure
1708  *==========================================================================*/
mm_camera_util_s_ctrl(int32_t fd,uint32_t id,int32_t * value)1709 int32_t mm_camera_util_s_ctrl(int32_t fd,  uint32_t id, int32_t *value)
1710 {
1711     int rc = 0;
1712     struct v4l2_control control;
1713 
1714     memset(&control, 0, sizeof(control));
1715     control.id = id;
1716     if (value != NULL) {
1717         control.value = *value;
1718     }
1719     rc = ioctl(fd, VIDIOC_S_CTRL, &control);
1720 
1721     CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
1722          __func__, fd, id, (uint32_t)value, rc);
1723     if (value != NULL) {
1724         *value = control.value;
1725     }
1726     return (rc >= 0)? 0 : -1;
1727 }
1728 
1729 /*===========================================================================
1730  * FUNCTION   : mm_camera_util_g_ctrl
1731  *
1732  * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
1733  *
1734  * PARAMETERS :
1735  *   @fd      : file descritpor for sending ioctl
1736  *   @id      : control id
1737  *   @value   : value of the ioctl to be sent
1738  *
1739  * RETURN     : int32_t type of status
1740  *              0  -- success
1741  *              -1 -- failure
1742  *==========================================================================*/
mm_camera_util_g_ctrl(int32_t fd,uint32_t id,int32_t * value)1743 int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
1744 {
1745     int rc = 0;
1746     struct v4l2_control control;
1747 
1748     memset(&control, 0, sizeof(control));
1749     control.id = id;
1750     if (value != NULL) {
1751         control.value = *value;
1752     }
1753     rc = ioctl(fd, VIDIOC_G_CTRL, &control);
1754     CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc);
1755     if (value != NULL) {
1756         *value = control.value;
1757     }
1758     return (rc >= 0)? 0 : -1;
1759 }
1760 
1761 /*===========================================================================
1762  * FUNCTION   : mm_camera_channel_advanced_capture
1763  *
1764  * DESCRIPTION: sets the channel advanced capture
1765  *
1766  * PARAMETERS :
1767  *   @my_obj       : camera object
1768  *   @advanced_capture_type : advanced capture type.
1769  *   @ch_id        : channel handle
1770  *   @start_flag  : flag to indicate start/stop
1771  *
1772  * RETURN     : int32_t type of status
1773  *              0  -- success
1774  *              -1 -- failure
1775  *==========================================================================*/
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)1776 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj,
1777                                         mm_camera_advanced_capture_t advanced_capture_type,
1778                                         uint32_t ch_id,
1779                                         int32_t start_flag)
1780 {
1781     CDBG("%s: E",__func__);
1782     int32_t rc = -1;
1783     mm_channel_t * ch_obj =
1784         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1785 
1786     if (NULL != ch_obj) {
1787         pthread_mutex_lock(&ch_obj->ch_lock);
1788         pthread_mutex_unlock(&my_obj->cam_lock);
1789         switch (advanced_capture_type) {
1790             case MM_CAMERA_AF_BRACKETING:
1791                 rc = mm_channel_fsm_fn(ch_obj,
1792                                        MM_CHANNEL_EVT_AF_BRACKETING,
1793                                        (void *)start_flag,
1794                                        NULL);
1795                 break;
1796             case MM_CAMERA_AE_BRACKETING:
1797                 rc = mm_channel_fsm_fn(ch_obj,
1798                                        MM_CHANNEL_EVT_AE_BRACKETING,
1799                                        (void *)start_flag,
1800                                        NULL);
1801                 break;
1802             case MM_CAMERA_FLASH_BRACKETING:
1803                 rc = mm_channel_fsm_fn(ch_obj,
1804                                        MM_CHANNEL_EVT_FLASH_BRACKETING,
1805                                        (void *)start_flag,
1806                                        NULL);
1807                 break;
1808             case MM_CAMERA_ZOOM_1X:
1809                 rc = mm_channel_fsm_fn(ch_obj,
1810                                        MM_CHANNEL_EVT_ZOOM_1X,
1811                                        (void *)start_flag,
1812                                        NULL);
1813                 break;
1814             default:
1815                 break;
1816         }
1817 
1818     } else {
1819         pthread_mutex_unlock(&my_obj->cam_lock);
1820     }
1821 
1822     CDBG("%s: X",__func__);
1823     return rc;
1824 }
1825