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