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