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