• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2012-2016, 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 // To remove
31 #include <cutils/properties.h>
32 
33 // System dependencies
34 #include <pthread.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <stdlib.h>
38 #include <dlfcn.h>
39 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
40 #include IOCTL_H
41 
42 // Camera dependencies
43 #include "cam_semaphore.h"
44 #include "mm_camera_dbg.h"
45 #include "mm_camera_sock.h"
46 #include "mm_camera_interface.h"
47 #include "mm_camera.h"
48 
49 #define SET_PARM_BIT32(parm, parm_arr) \
50     (parm_arr[parm/32] |= (1<<(parm%32)))
51 
52 #define GET_PARM_BIT32(parm, parm_arr) \
53     ((parm_arr[parm/32]>>(parm%32))& 0x1)
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 extern mm_camera_obj_t* mm_camera_util_get_camera_by_session_id
61         (uint32_t session_id);
62 
63 /*===========================================================================
64  * FUNCTION   : mm_camera_util_get_channel_by_handler
65  *
66  * DESCRIPTION: utility function to get a channel object from its handle
67  *
68  * PARAMETERS :
69  *   @cam_obj: ptr to a camera object
70  *   @handler: channel handle
71  *
72  * RETURN     : ptr to a channel object.
73  *              NULL if failed.
74  *==========================================================================*/
mm_camera_util_get_channel_by_handler(mm_camera_obj_t * cam_obj,uint32_t handler)75 mm_channel_t * mm_camera_util_get_channel_by_handler(
76                                     mm_camera_obj_t * cam_obj,
77                                     uint32_t handler)
78 {
79     int i;
80     mm_channel_t *ch_obj = NULL;
81     for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
82         if (handler == cam_obj->ch[i].my_hdl) {
83             ch_obj = &cam_obj->ch[i];
84             break;
85         }
86     }
87     return ch_obj;
88 }
89 
90 /*===========================================================================
91  * FUNCTION   : mm_camera_util_chip_is_a_family
92  *
93  * DESCRIPTION: utility function to check if the host is A family chip
94  *
95  * PARAMETERS :
96  *
97  * RETURN     : TRUE if A family.
98  *              FALSE otherwise.
99  *==========================================================================*/
mm_camera_util_chip_is_a_family(void)100 uint8_t mm_camera_util_chip_is_a_family(void)
101 {
102 #ifdef USE_A_FAMILY
103     return TRUE;
104 #else
105     return FALSE;
106 #endif
107 }
108 
109 /*===========================================================================
110  * FUNCTION   : mm_camera_dispatch_app_event
111  *
112  * DESCRIPTION: dispatch event to apps who regitster for event notify
113  *
114  * PARAMETERS :
115  *   @cmd_cb: ptr to a struct storing event info
116  *   @user_data: user data ptr (camera object)
117  *
118  * RETURN     : none
119  *==========================================================================*/
mm_camera_dispatch_app_event(mm_camera_cmdcb_t * cmd_cb,void * user_data)120 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
121                                          void* user_data)
122 {
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         mm_camera_cmd_thread_name(my_obj->evt_thread.threadName);
128         pthread_mutex_lock(&my_obj->cb_lock);
129         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
130             if(my_obj->evt.evt[i].evt_cb) {
131                 my_obj->evt.evt[i].evt_cb(
132                     my_obj->my_hdl,
133                     event,
134                     my_obj->evt.evt[i].user_data);
135             }
136         }
137         pthread_mutex_unlock(&my_obj->cb_lock);
138     }
139 }
140 
141 /*===========================================================================
142  * FUNCTION   : mm_camera_event_notify
143  *
144  * DESCRIPTION: callback to handle event notify from kernel. This call will
145  *              dequeue event from kernel.
146  *
147  * PARAMETERS :
148  *   @user_data: user data ptr (camera object)
149  *
150  * RETURN     : none
151  *==========================================================================*/
mm_camera_event_notify(void * user_data)152 static void mm_camera_event_notify(void* user_data)
153 {
154     struct v4l2_event ev;
155     struct msm_v4l2_event_data *msm_evt = NULL;
156     int rc;
157     mm_camera_event_t evt;
158     memset(&evt, 0, sizeof(mm_camera_event_t));
159 
160     mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
161     if (NULL != my_obj) {
162         /* read evt */
163         memset(&ev, 0, sizeof(ev));
164         rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
165 
166         if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
167             msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
168             switch (msm_evt->command) {
169             case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
170                 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ;
171                 mm_camera_enqueue_evt(my_obj, &evt);
172                 break;
173             case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
174                 pthread_mutex_lock(&my_obj->evt_lock);
175                 my_obj->evt_rcvd.server_event_type = msm_evt->command;
176                 my_obj->evt_rcvd.status = msm_evt->status;
177                 pthread_cond_signal(&my_obj->evt_cond);
178                 pthread_mutex_unlock(&my_obj->evt_lock);
179                 break;
180             case CAM_EVENT_TYPE_INT_TAKE_JPEG:
181             case CAM_EVENT_TYPE_INT_TAKE_RAW:
182                 {
183                     evt.server_event_type = msm_evt->command;
184                     mm_camera_enqueue_evt(my_obj, &evt);
185                 }
186                 break;
187             case MSM_CAMERA_PRIV_SHUTDOWN:
188                 {
189                     LOGE("Camera Event DAEMON DIED received");
190                     evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
191                     mm_camera_enqueue_evt(my_obj, &evt);
192                 }
193                 break;
194             case CAM_EVENT_TYPE_CAC_DONE:
195                 {
196                     evt.server_event_type = CAM_EVENT_TYPE_CAC_DONE;
197                     mm_camera_enqueue_evt(my_obj, &evt);
198                 }
199                 break;
200             default:
201                 break;
202             }
203         }
204     }
205 }
206 
207 /*===========================================================================
208  * FUNCTION   : mm_camera_enqueue_evt
209  *
210  * DESCRIPTION: enqueue received event into event queue to be processed by
211  *              event thread.
212  *
213  * PARAMETERS :
214  *   @my_obj   : ptr to a camera object
215  *   @event    : event to be queued
216  *
217  * RETURN     : int32_t type of status
218  *              0  -- success
219  *              -1 -- failure
220  *==========================================================================*/
mm_camera_enqueue_evt(mm_camera_obj_t * my_obj,mm_camera_event_t * event)221 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
222                               mm_camera_event_t *event)
223 {
224     int32_t rc = 0;
225     mm_camera_cmdcb_t *node = NULL;
226 
227     node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
228     if (NULL != node) {
229         memset(node, 0, sizeof(mm_camera_cmdcb_t));
230         node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
231         node->u.evt = *event;
232 
233         /* enqueue to evt cmd thread */
234         cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
235         /* wake up evt cmd thread */
236         cam_sem_post(&(my_obj->evt_thread.cmd_sem));
237     } else {
238         LOGE("No memory for mm_camera_node_t");
239         rc = -1;
240     }
241 
242     return rc;
243 }
244 
245 /*===========================================================================
246  * FUNCTION   : mm_camera_open
247  *
248  * DESCRIPTION: open a camera
249  *
250  * PARAMETERS :
251  *   @my_obj   : ptr to a camera object
252  *
253  * RETURN     : int32_t type of status
254  *              0  -- success
255  *              -1 -- failure
256  *==========================================================================*/
mm_camera_open(mm_camera_obj_t * my_obj)257 int32_t mm_camera_open(mm_camera_obj_t *my_obj)
258 {
259     char dev_name[MM_CAMERA_DEV_NAME_LEN];
260     int32_t rc = 0;
261     int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
262     uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
263     int cam_idx = 0;
264     const char *dev_name_value = NULL;
265     int l_errno = 0;
266 
267     LOGD("begin\n");
268 
269     if (NULL == my_obj) {
270         goto on_error;
271     }
272     dev_name_value = mm_camera_util_get_dev_name(my_obj->my_hdl);
273     if (NULL == dev_name_value) {
274         goto on_error;
275     }
276     snprintf(dev_name, sizeof(dev_name), "/dev/%s",
277              dev_name_value);
278     sscanf(dev_name, "/dev/video%d", &cam_idx);
279     LOGD("dev name = %s, cam_idx = %d", dev_name, cam_idx);
280 
281     do{
282         n_try--;
283         errno = 0;
284         my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
285         l_errno = errno;
286         LOGD("ctrl_fd = %d, errno == %d", my_obj->ctrl_fd, l_errno);
287         if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) {
288             break;
289         }
290         LOGE("Failed with %s error, retrying after %d milli-seconds",
291               strerror(errno), sleep_msec);
292         usleep(sleep_msec * 1000U);
293     }while (n_try > 0);
294 
295     if (my_obj->ctrl_fd < 0) {
296         LOGE("cannot open control fd of '%s' (%s)\n",
297                   dev_name, strerror(l_errno));
298         if (l_errno == EBUSY)
299             rc = -EUSERS;
300         else
301             rc = -1;
302         goto on_error;
303     } else {
304         mm_camera_get_session_id(my_obj, &my_obj->sessionid);
305         LOGH("Camera Opened id = %d sessionid = %d", cam_idx, my_obj->sessionid);
306     }
307 
308 #ifdef DAEMON_PRESENT
309     /* open domain socket*/
310     n_try = MM_CAMERA_DEV_OPEN_TRIES;
311     do {
312         n_try--;
313         my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
314         l_errno = errno;
315         LOGD("ds_fd = %d, errno = %d", my_obj->ds_fd, l_errno);
316         if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {
317             LOGD("opened, break out while loop");
318             break;
319         }
320         LOGD("failed with I/O error retrying after %d milli-seconds",
321               sleep_msec);
322         usleep(sleep_msec * 1000U);
323     } while (n_try > 0);
324 
325     if (my_obj->ds_fd < 0) {
326         LOGE("cannot open domain socket fd of '%s'(%s)\n",
327                   dev_name, strerror(l_errno));
328         rc = -1;
329         goto on_error;
330     }
331 #else /* DAEMON_PRESENT */
332     cam_status_t cam_status;
333     cam_status = mm_camera_module_open_session(my_obj->sessionid,
334             mm_camera_module_event_handler);
335     if (cam_status < 0) {
336         LOGE("Failed to open session");
337         if (cam_status == CAM_STATUS_BUSY) {
338             rc = -EUSERS;
339         } else {
340             rc = -1;
341         }
342         goto on_error;
343     }
344 #endif /* DAEMON_PRESENT */
345 
346     pthread_mutex_init(&my_obj->msg_lock, NULL);
347     pthread_mutex_init(&my_obj->cb_lock, NULL);
348     pthread_mutex_init(&my_obj->evt_lock, NULL);
349     pthread_cond_init(&my_obj->evt_cond, NULL);
350 
351     LOGD("Launch evt Thread in Cam Open");
352     snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch");
353     mm_camera_cmd_thread_launch(&my_obj->evt_thread,
354                                 mm_camera_dispatch_app_event,
355                                 (void *)my_obj);
356 
357     /* launch event poll thread
358      * we will add evt fd into event poll thread upon user first register for evt */
359     LOGD("Launch evt Poll Thread in Cam Open");
360     snprintf(my_obj->evt_poll_thread.threadName, THREAD_NAME_SIZE, "CAM_evntPoll");
361     mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
362                                  MM_CAMERA_POLL_TYPE_EVT);
363     mm_camera_evt_sub(my_obj, TRUE);
364 
365     /* unlock cam_lock, we need release global intf_lock in camera_open(),
366      * in order not block operation of other Camera in dual camera use case.*/
367     pthread_mutex_unlock(&my_obj->cam_lock);
368     LOGD("end (rc = %d)\n", rc);
369     return rc;
370 
371 on_error:
372 
373     if (NULL == dev_name_value) {
374         LOGE("Invalid device name\n");
375         rc = -1;
376     }
377 
378     if (NULL == my_obj) {
379         LOGE("Invalid camera object\n");
380         rc = -1;
381     } else {
382         if (my_obj->ctrl_fd >= 0) {
383             close(my_obj->ctrl_fd);
384             my_obj->ctrl_fd = -1;
385         }
386 #ifdef DAEMON_PRESENT
387         if (my_obj->ds_fd >= 0) {
388             mm_camera_socket_close(my_obj->ds_fd);
389             my_obj->ds_fd = -1;
390         }
391 #endif
392     }
393 
394     /* unlock cam_lock, we need release global intf_lock in camera_open(),
395      * in order not block operation of other Camera in dual camera use case.*/
396     pthread_mutex_unlock(&my_obj->cam_lock);
397     return rc;
398 }
399 
400 /*===========================================================================
401  * FUNCTION   : mm_camera_close
402  *
403  * DESCRIPTION: enqueue received event into event queue to be processed by
404  *              event thread.
405  *
406  * PARAMETERS :
407  *   @my_obj   : ptr to a camera object
408  *   @event    : event to be queued
409  *
410  * RETURN     : int32_t type of status
411  *              0  -- success
412  *              -1 -- failure
413  *==========================================================================*/
mm_camera_close(mm_camera_obj_t * my_obj)414 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
415 {
416     LOGD("unsubscribe evt");
417 
418 #ifndef DAEMON_PRESENT
419     mm_camera_module_close_session(my_obj->sessionid);
420 #endif /* DAEMON_PRESENT */
421 
422     mm_camera_evt_sub(my_obj, FALSE);
423 
424     LOGD("Close evt Poll Thread in Cam Close");
425     mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
426 
427     LOGD("Close evt cmd Thread in Cam Close");
428     mm_camera_cmd_thread_release(&my_obj->evt_thread);
429 
430     if(my_obj->ctrl_fd >= 0) {
431         close(my_obj->ctrl_fd);
432         my_obj->ctrl_fd = -1;
433     }
434 
435 #ifdef DAEMON_PRESENT
436     if(my_obj->ds_fd >= 0) {
437         mm_camera_socket_close(my_obj->ds_fd);
438         my_obj->ds_fd = -1;
439     }
440 #endif
441 
442     pthread_mutex_destroy(&my_obj->msg_lock);
443     pthread_mutex_destroy(&my_obj->cb_lock);
444     pthread_mutex_destroy(&my_obj->evt_lock);
445     pthread_cond_destroy(&my_obj->evt_cond);
446     pthread_mutex_unlock(&my_obj->cam_lock);
447     return 0;
448 }
449 
450 /*===========================================================================
451  * FUNCTION   : mm_camera_register_event_notify_internal
452  *
453  * DESCRIPTION: internal implementation for registering callback for event notify.
454  *
455  * PARAMETERS :
456  *   @my_obj   : ptr to a camera object
457  *   @evt_cb   : callback to be registered to handle event notify
458  *   @user_data: user data ptr
459  *
460  * RETURN     : int32_t type of status
461  *              0  -- success
462  *              -1 -- failure
463  *==========================================================================*/
mm_camera_register_event_notify_internal(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)464 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
465                                                  mm_camera_event_notify_t evt_cb,
466                                                  void * user_data)
467 {
468     int i;
469     int rc = -1;
470     mm_camera_evt_obj_t *evt_array = NULL;
471 
472     pthread_mutex_lock(&my_obj->cb_lock);
473     evt_array = &my_obj->evt;
474     if(evt_cb) {
475         /* this is reg case */
476         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
477             if(evt_array->evt[i].user_data == NULL) {
478                 evt_array->evt[i].evt_cb = evt_cb;
479                 evt_array->evt[i].user_data = user_data;
480                 evt_array->reg_count++;
481                 rc = 0;
482                 break;
483             }
484         }
485     } else {
486         /* this is unreg case */
487         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
488             if(evt_array->evt[i].user_data == user_data) {
489                 evt_array->evt[i].evt_cb = NULL;
490                 evt_array->evt[i].user_data = NULL;
491                 evt_array->reg_count--;
492                 rc = 0;
493                 break;
494             }
495         }
496     }
497 
498     pthread_mutex_unlock(&my_obj->cb_lock);
499     return rc;
500 }
501 
502 /*===========================================================================
503  * FUNCTION   : mm_camera_register_event_notify
504  *
505  * DESCRIPTION: registering a callback for event notify.
506  *
507  * PARAMETERS :
508  *   @my_obj   : ptr to a camera object
509  *   @evt_cb   : callback to be registered to handle event notify
510  *   @user_data: user data ptr
511  *
512  * RETURN     : int32_t type of status
513  *              0  -- success
514  *              -1 -- failure
515  *==========================================================================*/
mm_camera_register_event_notify(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)516 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
517                                         mm_camera_event_notify_t evt_cb,
518                                         void * user_data)
519 {
520     int rc = -1;
521     rc = mm_camera_register_event_notify_internal(my_obj,
522                                                   evt_cb,
523                                                   user_data);
524     pthread_mutex_unlock(&my_obj->cam_lock);
525     return rc;
526 }
527 
528 /*===========================================================================
529  * FUNCTION   : mm_camera_qbuf
530  *
531  * DESCRIPTION: enqueue buffer back to kernel
532  *
533  * PARAMETERS :
534  *   @my_obj       : camera object
535  *   @ch_id        : channel handle
536  *   @buf          : buf ptr to be enqueued
537  *
538  * RETURN     : int32_t type of status
539  *              0  -- success
540  *              -1 -- failure
541  *==========================================================================*/
mm_camera_qbuf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_buf_def_t * buf)542 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
543                        uint32_t ch_id,
544                        mm_camera_buf_def_t *buf)
545 {
546     int rc = -1;
547     mm_channel_t * ch_obj = NULL;
548     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
549 
550     pthread_mutex_unlock(&my_obj->cam_lock);
551 
552     /* we always assume qbuf will be done before channel/stream is fully stopped
553      * because qbuf is done within dataCB context
554      * in order to avoid deadlock, we are not locking ch_lock for qbuf */
555     if (NULL != ch_obj) {
556         rc = mm_channel_qbuf(ch_obj, buf);
557     }
558 
559     return rc;
560 }
561 
562 /*===========================================================================
563  * FUNCTION   : mm_camera_cancel_buf
564  *
565  * DESCRIPTION: Cancel an already queued buffer
566  *
567  * PARAMETERS :
568  *   @my_obj       : camera object
569  *   @ch_id        : channel handle
570  *
571  *   @buf          : buf ptr to be enqueued
572  *
573  * RETURN     : int32_t type of status
574  *              0  -- success
575  *              -1 -- failure
576  *==========================================================================*/
mm_camera_cancel_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint32_t buf_idx)577 int32_t mm_camera_cancel_buf(mm_camera_obj_t *my_obj,
578                        uint32_t ch_id,
579                        uint32_t stream_id,
580                        uint32_t buf_idx)
581 {
582     int rc = -1;
583     mm_channel_t * ch_obj = NULL;
584     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
585 
586     if (NULL != ch_obj) {
587         pthread_mutex_unlock(&my_obj->cam_lock);
588         rc = mm_channel_cancel_buf(ch_obj,stream_id,buf_idx);
589     }
590 
591     return rc;
592 }
593 
594 /*===========================================================================
595  * FUNCTION   : mm_camera_get_queued_buf_count
596  *
597  * DESCRIPTION: return queued buffer count
598  *
599  * PARAMETERS :
600  *   @my_obj       : camera object
601  *   @ch_id        : channel handle
602  *   @stream_id : stream id
603  *
604  * RETURN     : queued buffer count
605  *==========================================================================*/
mm_camera_get_queued_buf_count(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)606 int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj,
607         uint32_t ch_id, uint32_t stream_id)
608 {
609     int rc = -1;
610     mm_channel_t * ch_obj = NULL;
611     uint32_t payload;
612     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
613     payload = stream_id;
614 
615     if (NULL != ch_obj) {
616         pthread_mutex_lock(&ch_obj->ch_lock);
617         pthread_mutex_unlock(&my_obj->cam_lock);
618         rc = mm_channel_fsm_fn(ch_obj,
619                 MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT,
620                 (void *)&payload,
621                 NULL);
622     } else {
623         pthread_mutex_unlock(&my_obj->cam_lock);
624     }
625 
626     return rc;
627 }
628 
629 /*===========================================================================
630  * FUNCTION   : mm_camera_query_capability
631  *
632  * DESCRIPTION: query camera capability
633  *
634  * PARAMETERS :
635  *   @my_obj: camera object
636  *
637  * RETURN     : int32_t type of status
638  *              0  -- success
639  *              -1 -- failure
640  *==========================================================================*/
mm_camera_query_capability(mm_camera_obj_t * my_obj)641 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
642 {
643     int32_t rc = 0;
644 
645 #ifdef DAEMON_PRESENT
646     struct v4l2_capability cap;
647     /* get camera capabilities */
648     memset(&cap, 0, sizeof(cap));
649     rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
650 #else /* DAEMON_PRESENT */
651     cam_shim_packet_t *shim_cmd;
652     cam_shim_cmd_data shim_cmd_data;
653     memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
654     shim_cmd_data.command = MSM_CAMERA_PRIV_QUERY_CAP;
655     shim_cmd_data.stream_id = 0;
656     shim_cmd_data.value = NULL;
657     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM,
658             my_obj->sessionid,&shim_cmd_data);
659     rc = mm_camera_module_send_cmd(shim_cmd);
660     mm_camera_destroy_shim_cmd_packet(shim_cmd);
661 #endif /* DAEMON_PRESENT */
662     if (rc != 0) {
663         LOGE("cannot get camera capabilities, rc = %d, errno %d",
664                 rc, errno);
665     }
666     pthread_mutex_unlock(&my_obj->cam_lock);
667     return rc;
668 }
669 
670 /*===========================================================================
671  * FUNCTION   : mm_camera_set_parms
672  *
673  * DESCRIPTION: set parameters per camera
674  *
675  * PARAMETERS :
676  *   @my_obj       : camera object
677  *   @parms        : ptr to a param struct to be set to server
678  *
679  * RETURN     : int32_t type of status
680  *              0  -- success
681  *              -1 -- failure
682  * NOTE       : Assume the parms struct buf is already mapped to server via
683  *              domain socket. Corresponding fields of parameters to be set
684  *              are already filled in by upper layer caller.
685  *==========================================================================*/
mm_camera_set_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)686 int32_t mm_camera_set_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_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
693             CAM_PRIV_PARM, &value);
694     }
695     pthread_mutex_unlock(&my_obj->cam_lock);
696     return rc;
697 }
698 
699 /*===========================================================================
700  * FUNCTION   : mm_camera_get_parms
701  *
702  * DESCRIPTION: get parameters per camera
703  *
704  * PARAMETERS :
705  *   @my_obj       : camera object
706  *   @parms        : ptr to a param struct to be get from server
707  *
708  * RETURN     : int32_t type of status
709  *              0  -- success
710  *              -1 -- failure
711  * NOTE       : Assume the parms struct buf is already mapped to server via
712  *              domain socket. Parameters to be get from server are already
713  *              filled in by upper layer caller. After this call, corresponding
714  *              fields of requested parameters will be filled in by server with
715  *              detailed information.
716  *==========================================================================*/
mm_camera_get_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)717 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
718                             parm_buffer_t *parms)
719 {
720     int32_t rc = -1;
721     int32_t value = 0;
722     if (parms != NULL) {
723         rc = mm_camera_util_g_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
724     }
725     pthread_mutex_unlock(&my_obj->cam_lock);
726     return rc;
727 }
728 
729 /*===========================================================================
730  * FUNCTION   : mm_camera_do_auto_focus
731  *
732  * DESCRIPTION: performing auto focus
733  *
734  * PARAMETERS :
735  *   @camera_handle: camera handle
736  *
737  * RETURN     : int32_t type of status
738  *              0  -- success
739  *              -1 -- failure
740  * NOTE       : if this call success, we will always assume there will
741  *              be an auto_focus event following up.
742  *==========================================================================*/
mm_camera_do_auto_focus(mm_camera_obj_t * my_obj)743 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
744 {
745     int32_t rc = -1;
746     int32_t value = 0;
747     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
748     pthread_mutex_unlock(&my_obj->cam_lock);
749     return rc;
750 }
751 
752 /*===========================================================================
753  * FUNCTION   : mm_camera_cancel_auto_focus
754  *
755  * DESCRIPTION: cancel auto focus
756  *
757  * PARAMETERS :
758  *   @camera_handle: camera handle
759  *
760  * RETURN     : int32_t type of status
761  *              0  -- success
762  *              -1 -- failure
763  *==========================================================================*/
mm_camera_cancel_auto_focus(mm_camera_obj_t * my_obj)764 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
765 {
766     int32_t rc = -1;
767     int32_t value = 0;
768     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
769     pthread_mutex_unlock(&my_obj->cam_lock);
770     return rc;
771 }
772 
773 /*===========================================================================
774  * FUNCTION   : mm_camera_prepare_snapshot
775  *
776  * DESCRIPTION: prepare hardware for snapshot
777  *
778  * PARAMETERS :
779  *   @my_obj       : camera object
780  *   @do_af_flag   : flag indicating if AF is needed
781  *
782  * RETURN     : int32_t type of status
783  *              0  -- success
784  *              -1 -- failure
785  *==========================================================================*/
mm_camera_prepare_snapshot(mm_camera_obj_t * my_obj,int32_t do_af_flag)786 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
787                                    int32_t do_af_flag)
788 {
789     int32_t rc = -1;
790     int32_t value = do_af_flag;
791     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
792     pthread_mutex_unlock(&my_obj->cam_lock);
793     return rc;
794 }
795 
796 /*===========================================================================
797  * FUNCTION   : mm_camera_start_zsl_snapshot
798  *
799  * DESCRIPTION: start zsl snapshot
800  *
801  * PARAMETERS :
802  *   @my_obj       : camera object
803  *
804  * RETURN     : int32_t type of status
805  *              0  -- success
806  *              -1 -- failure
807  *==========================================================================*/
mm_camera_start_zsl_snapshot(mm_camera_obj_t * my_obj)808 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
809 {
810     int32_t rc = -1;
811     int32_t value = 0;
812 
813     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
814              CAM_PRIV_START_ZSL_SNAPSHOT, &value);
815     return rc;
816 }
817 
818 /*===========================================================================
819  * FUNCTION   : mm_camera_stop_zsl_snapshot
820  *
821  * DESCRIPTION: stop zsl capture
822  *
823  * PARAMETERS :
824  *   @my_obj       : camera object
825  *
826  * RETURN     : int32_t type of status
827  *              0  -- success
828  *              -1 -- failure
829  *==========================================================================*/
mm_camera_stop_zsl_snapshot(mm_camera_obj_t * my_obj)830 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
831 {
832     int32_t rc = -1;
833     int32_t value;
834     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
835              CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
836     return rc;
837 }
838 
839 /*===========================================================================
840  * FUNCTION   : mm_camera_flush
841  *
842  * DESCRIPTION: flush the current camera state and buffers
843  *
844  * PARAMETERS :
845  *   @my_obj       : camera object
846  *
847  * RETURN     : int32_t type of status
848  *              0  -- success
849  *              -1 -- failure
850  *==========================================================================*/
mm_camera_flush(mm_camera_obj_t * my_obj)851 int32_t mm_camera_flush(mm_camera_obj_t *my_obj)
852 {
853     int32_t rc = -1;
854     int32_t value;
855     rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
856             CAM_PRIV_FLUSH, &value);
857     pthread_mutex_unlock(&my_obj->cam_lock);
858     return rc;
859 }
860 
861 /*===========================================================================
862  * FUNCTION   : mm_camera_add_channel
863  *
864  * DESCRIPTION: add a channel
865  *
866  * PARAMETERS :
867  *   @my_obj       : camera object
868  *   @attr         : bundle attribute of the channel if needed
869  *   @channel_cb   : callback function for bundle data notify
870  *   @userdata     : user data ptr
871  *
872  * RETURN     : uint32_t type of channel handle
873  *              0  -- invalid channel handle, meaning the op failed
874  *              >0 -- successfully added a channel with a valid handle
875  * NOTE       : if no bundle data notify is needed, meaning each stream in the
876  *              channel will have its own stream data notify callback, then
877  *              attr, channel_cb, and userdata can be NULL. In this case,
878  *              no matching logic will be performed in channel for the bundling.
879  *==========================================================================*/
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)880 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
881                                mm_camera_channel_attr_t *attr,
882                                mm_camera_buf_notify_t channel_cb,
883                                void *userdata)
884 {
885     mm_channel_t *ch_obj = NULL;
886     uint8_t ch_idx = 0;
887     uint32_t ch_hdl = 0;
888 
889     for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
890         if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
891             ch_obj = &my_obj->ch[ch_idx];
892             break;
893         }
894     }
895 
896     if (NULL != ch_obj) {
897         /* initialize channel obj */
898         memset(ch_obj, 0, sizeof(mm_channel_t));
899         ch_hdl = mm_camera_util_generate_handler(ch_idx);
900         ch_obj->my_hdl = ch_hdl;
901         ch_obj->state = MM_CHANNEL_STATE_STOPPED;
902         ch_obj->cam_obj = my_obj;
903         pthread_mutex_init(&ch_obj->ch_lock, NULL);
904         ch_obj->sessionid = my_obj->sessionid;
905         mm_channel_init(ch_obj, attr, channel_cb, userdata);
906     }
907 
908     pthread_mutex_unlock(&my_obj->cam_lock);
909 
910     return ch_hdl;
911 }
912 
913 /*===========================================================================
914  * FUNCTION   : mm_camera_del_channel
915  *
916  * DESCRIPTION: delete a channel by its handle
917  *
918  * PARAMETERS :
919  *   @my_obj       : camera object
920  *   @ch_id        : channel handle
921  *
922  * RETURN     : int32_t type of status
923  *              0  -- success
924  *              -1 -- failure
925  * NOTE       : all streams in the channel should be stopped already before
926  *              this channel can be deleted.
927  *==========================================================================*/
mm_camera_del_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)928 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
929                               uint32_t ch_id)
930 {
931     int32_t rc = -1;
932     mm_channel_t * ch_obj =
933         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
934 
935     if (NULL != ch_obj) {
936         pthread_mutex_lock(&ch_obj->ch_lock);
937         pthread_mutex_unlock(&my_obj->cam_lock);
938 
939         rc = mm_channel_fsm_fn(ch_obj,
940                                MM_CHANNEL_EVT_DELETE,
941                                NULL,
942                                NULL);
943 
944         pthread_mutex_destroy(&ch_obj->ch_lock);
945         memset(ch_obj, 0, sizeof(mm_channel_t));
946     } else {
947         pthread_mutex_unlock(&my_obj->cam_lock);
948     }
949     return rc;
950 }
951 
952 /*===========================================================================
953  * FUNCTION   : mm_camera_get_bundle_info
954  *
955  * DESCRIPTION: query bundle info of the channel
956  *
957  * PARAMETERS :
958  *   @my_obj       : camera object
959  *   @ch_id        : channel handle
960  *   @bundle_info  : bundle info to be filled in
961  *
962  * RETURN     : int32_t type of status
963  *              0  -- success
964  *              -1 -- failure
965  * NOTE       : all streams in the channel should be stopped already before
966  *              this channel can be deleted.
967  *==========================================================================*/
mm_camera_get_bundle_info(mm_camera_obj_t * my_obj,uint32_t ch_id,cam_bundle_config_t * bundle_info)968 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
969                                   uint32_t ch_id,
970                                   cam_bundle_config_t *bundle_info)
971 {
972     int32_t rc = -1;
973     mm_channel_t * ch_obj =
974         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
975 
976     if (NULL != ch_obj) {
977         pthread_mutex_lock(&ch_obj->ch_lock);
978         pthread_mutex_unlock(&my_obj->cam_lock);
979 
980         rc = mm_channel_fsm_fn(ch_obj,
981                                MM_CHANNEL_EVT_GET_BUNDLE_INFO,
982                                (void *)bundle_info,
983                                NULL);
984     } else {
985         pthread_mutex_unlock(&my_obj->cam_lock);
986     }
987     return rc;
988 }
989 
990 /*===========================================================================
991  * FUNCTION   : mm_camera_link_stream
992  *
993  * DESCRIPTION: link a stream into a channel
994  *
995  * PARAMETERS :
996  *   @my_obj       : camera object
997  *   @ch_id        : channel handle
998  *   @stream_id    : stream that will be linked
999  *   @linked_ch_id : channel in which the stream will be linked
1000  *
1001  * RETURN     : uint32_t type of stream handle
1002  *              0  -- invalid stream handle, meaning the op failed
1003  *              >0 -- successfully linked a stream with a valid handle
1004  *==========================================================================*/
mm_camera_link_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint32_t linked_ch_id)1005 uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj,
1006         uint32_t ch_id,
1007         uint32_t stream_id,
1008         uint32_t linked_ch_id)
1009 {
1010     uint32_t s_hdl = 0;
1011     mm_channel_t * ch_obj =
1012             mm_camera_util_get_channel_by_handler(my_obj, linked_ch_id);
1013     mm_channel_t * owner_obj =
1014             mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1015 
1016     if ((NULL != ch_obj) && (NULL != owner_obj)) {
1017         pthread_mutex_lock(&ch_obj->ch_lock);
1018         pthread_mutex_unlock(&my_obj->cam_lock);
1019 
1020         mm_camera_stream_link_t stream_link;
1021         memset(&stream_link, 0, sizeof(mm_camera_stream_link_t));
1022         stream_link.ch = owner_obj;
1023         stream_link.stream_id = stream_id;
1024         mm_channel_fsm_fn(ch_obj,
1025                           MM_CHANNEL_EVT_LINK_STREAM,
1026                           (void*)&stream_link,
1027                           (void*)&s_hdl);
1028     } else {
1029         pthread_mutex_unlock(&my_obj->cam_lock);
1030     }
1031 
1032     return s_hdl;
1033 }
1034 
1035 /*===========================================================================
1036  * FUNCTION   : mm_camera_add_stream
1037  *
1038  * DESCRIPTION: add a stream into a channel
1039  *
1040  * PARAMETERS :
1041  *   @my_obj       : camera object
1042  *   @ch_id        : channel handle
1043  *
1044  * RETURN     : uint32_t type of stream handle
1045  *              0  -- invalid stream handle, meaning the op failed
1046  *              >0 -- successfully added a stream with a valid handle
1047  *==========================================================================*/
mm_camera_add_stream(mm_camera_obj_t * my_obj,uint32_t ch_id)1048 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
1049                               uint32_t ch_id)
1050 {
1051     uint32_t s_hdl = 0;
1052     mm_channel_t * ch_obj =
1053         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1054 
1055     if (NULL != ch_obj) {
1056         pthread_mutex_lock(&ch_obj->ch_lock);
1057         pthread_mutex_unlock(&my_obj->cam_lock);
1058 
1059         mm_channel_fsm_fn(ch_obj,
1060                           MM_CHANNEL_EVT_ADD_STREAM,
1061                           NULL,
1062                           (void *)&s_hdl);
1063     } else {
1064         pthread_mutex_unlock(&my_obj->cam_lock);
1065     }
1066 
1067     return s_hdl;
1068 }
1069 
1070 /*===========================================================================
1071  * FUNCTION   : mm_camera_del_stream
1072  *
1073  * DESCRIPTION: delete a stream by its handle
1074  *
1075  * PARAMETERS :
1076  *   @my_obj       : camera object
1077  *   @ch_id        : channel handle
1078  *   @stream_id    : stream handle
1079  *
1080  * RETURN     : int32_t type of status
1081  *              0  -- success
1082  *              -1 -- failure
1083  * NOTE       : stream should be stopped already before it can be deleted.
1084  *==========================================================================*/
mm_camera_del_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)1085 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
1086                              uint32_t ch_id,
1087                              uint32_t stream_id)
1088 {
1089     int32_t rc = -1;
1090     mm_channel_t * ch_obj =
1091         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1092 
1093     if (NULL != ch_obj) {
1094         pthread_mutex_lock(&ch_obj->ch_lock);
1095         pthread_mutex_unlock(&my_obj->cam_lock);
1096 
1097         rc = mm_channel_fsm_fn(ch_obj,
1098                                MM_CHANNEL_EVT_DEL_STREAM,
1099                                (void *)&stream_id,
1100                                NULL);
1101     } else {
1102         pthread_mutex_unlock(&my_obj->cam_lock);
1103     }
1104 
1105     return rc;
1106 }
1107 
1108 /*===========================================================================
1109  * FUNCTION   : mm_camera_start_zsl_snapshot_ch
1110  *
1111  * DESCRIPTION: starts zsl snapshot for specific channel
1112  *
1113  * PARAMETERS :
1114  *   @my_obj       : camera object
1115  *   @ch_id        : channel handle
1116  *
1117  * RETURN     : int32_t type of status
1118  *              0  -- success
1119  *              -1 -- failure
1120  *==========================================================================*/
mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)1121 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
1122         uint32_t ch_id)
1123 {
1124     int32_t rc = -1;
1125     mm_channel_t * ch_obj =
1126         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1127 
1128     if (NULL != ch_obj) {
1129         pthread_mutex_lock(&ch_obj->ch_lock);
1130         pthread_mutex_unlock(&my_obj->cam_lock);
1131 
1132         rc = mm_channel_fsm_fn(ch_obj,
1133                                MM_CHANNEL_EVT_START_ZSL_SNAPSHOT,
1134                                NULL,
1135                                NULL);
1136     } else {
1137         pthread_mutex_unlock(&my_obj->cam_lock);
1138     }
1139 
1140     return rc;
1141 }
1142 
1143 /*===========================================================================
1144  * FUNCTION   : mm_camera_stop_zsl_snapshot_ch
1145  *
1146  * DESCRIPTION: stops zsl snapshot for specific channel
1147  *
1148  * PARAMETERS :
1149  *   @my_obj       : camera object
1150  *   @ch_id        : channel handle
1151  *
1152  * RETURN     : int32_t type of status
1153  *              0  -- success
1154  *              -1 -- failure
1155  *==========================================================================*/
mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)1156 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
1157         uint32_t ch_id)
1158 {
1159     int32_t rc = -1;
1160     mm_channel_t * ch_obj =
1161         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1162 
1163     if (NULL != ch_obj) {
1164         pthread_mutex_lock(&ch_obj->ch_lock);
1165         pthread_mutex_unlock(&my_obj->cam_lock);
1166 
1167         rc = mm_channel_fsm_fn(ch_obj,
1168                                MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT,
1169                                NULL,
1170                                NULL);
1171     } else {
1172         pthread_mutex_unlock(&my_obj->cam_lock);
1173     }
1174 
1175     return rc;
1176 }
1177 
1178 /*===========================================================================
1179  * FUNCTION   : mm_camera_config_stream
1180  *
1181  * DESCRIPTION: configure a stream
1182  *
1183  * PARAMETERS :
1184  *   @my_obj       : camera object
1185  *   @ch_id        : channel handle
1186  *   @stream_id    : stream handle
1187  *   @config       : stream configuration
1188  *
1189  * RETURN     : int32_t type of status
1190  *              0  -- success
1191  *              -1 -- failure
1192  *==========================================================================*/
mm_camera_config_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)1193 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
1194                                 uint32_t ch_id,
1195                                 uint32_t stream_id,
1196                                 mm_camera_stream_config_t *config)
1197 {
1198     int32_t rc = -1;
1199     mm_channel_t * ch_obj =
1200         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1201     mm_evt_paylod_config_stream_t payload;
1202 
1203     if (NULL != ch_obj) {
1204         pthread_mutex_lock(&ch_obj->ch_lock);
1205         pthread_mutex_unlock(&my_obj->cam_lock);
1206 
1207         memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
1208         payload.stream_id = stream_id;
1209         payload.config = config;
1210         rc = mm_channel_fsm_fn(ch_obj,
1211                                MM_CHANNEL_EVT_CONFIG_STREAM,
1212                                (void *)&payload,
1213                                NULL);
1214     } else {
1215         pthread_mutex_unlock(&my_obj->cam_lock);
1216     }
1217 
1218     return rc;
1219 }
1220 
1221 /*===========================================================================
1222  * FUNCTION   : mm_camera_start_channel
1223  *
1224  * DESCRIPTION: start a channel, which will start all streams in the channel
1225  *
1226  * PARAMETERS :
1227  *   @my_obj       : camera object
1228  *   @ch_id        : channel handle
1229  *
1230  * RETURN     : int32_t type of status
1231  *              0  -- success
1232  *              -1 -- failure
1233  *==========================================================================*/
mm_camera_start_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1234 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj, uint32_t ch_id)
1235 {
1236     int32_t rc = -1;
1237     mm_channel_t * ch_obj =
1238         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1239 
1240     if (NULL != ch_obj) {
1241         pthread_mutex_lock(&ch_obj->ch_lock);
1242         pthread_mutex_unlock(&my_obj->cam_lock);
1243 
1244         rc = mm_channel_fsm_fn(ch_obj,
1245                                MM_CHANNEL_EVT_START,
1246                                NULL,
1247                                NULL);
1248     } else {
1249         pthread_mutex_unlock(&my_obj->cam_lock);
1250     }
1251 
1252     return rc;
1253 }
1254 
1255 /*===========================================================================
1256  * FUNCTION   : mm_camera_stop_channel
1257  *
1258  * DESCRIPTION: stop a channel, which will stop all streams in the channel
1259  *
1260  * PARAMETERS :
1261  *   @my_obj       : camera object
1262  *   @ch_id        : channel handle
1263  *
1264  * RETURN     : int32_t type of status
1265  *              0  -- success
1266  *              -1 -- failure
1267  *==========================================================================*/
mm_camera_stop_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1268 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
1269                                uint32_t ch_id)
1270 {
1271     int32_t rc = 0;
1272     mm_channel_t * ch_obj =
1273         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1274 
1275     if (NULL != ch_obj) {
1276         pthread_mutex_lock(&ch_obj->ch_lock);
1277         pthread_mutex_unlock(&my_obj->cam_lock);
1278 
1279         rc = mm_channel_fsm_fn(ch_obj,
1280                                MM_CHANNEL_EVT_STOP,
1281                                NULL,
1282                                NULL);
1283     } else {
1284         pthread_mutex_unlock(&my_obj->cam_lock);
1285     }
1286     return rc;
1287 }
1288 
1289 /*===========================================================================
1290  * FUNCTION   : mm_camera_request_super_buf
1291  *
1292  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1293  *              frames from superbuf queue
1294  *
1295  * PARAMETERS :
1296  *   @my_obj       : camera object
1297  *   @ch_id        : channel handle
1298  *   @num_buf_requested : number of matched frames needed
1299  *
1300  * RETURN     : int32_t type of status
1301  *              0  -- success
1302  *              -1 -- failure
1303  *==========================================================================*/
mm_camera_request_super_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_req_buf_t * buf)1304 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1305         uint32_t ch_id, mm_camera_req_buf_t *buf)
1306 {
1307     int32_t rc = -1;
1308     mm_channel_t * ch_obj =
1309         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1310 
1311     if ((NULL != ch_obj) && (buf != NULL)) {
1312         pthread_mutex_lock(&ch_obj->ch_lock);
1313         pthread_mutex_unlock(&my_obj->cam_lock);
1314 
1315         rc = mm_channel_fsm_fn(ch_obj, MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
1316                 (void *)buf, NULL);
1317     } else {
1318         pthread_mutex_unlock(&my_obj->cam_lock);
1319     }
1320 
1321     return rc;
1322 }
1323 
1324 /*===========================================================================
1325  * FUNCTION   : mm_camera_cancel_super_buf_request
1326  *
1327  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
1328  *              of matched frames from superbuf queue
1329  *
1330  * PARAMETERS :
1331  *   @my_obj       : camera object
1332  *   @ch_id        : channel handle
1333  *
1334  * RETURN     : int32_t type of status
1335  *              0  -- success
1336  *              -1 -- failure
1337  *==========================================================================*/
mm_camera_cancel_super_buf_request(mm_camera_obj_t * my_obj,uint32_t ch_id)1338 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
1339 {
1340     int32_t rc = -1;
1341     mm_channel_t * ch_obj =
1342         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1343 
1344     if (NULL != ch_obj) {
1345         pthread_mutex_lock(&ch_obj->ch_lock);
1346         pthread_mutex_unlock(&my_obj->cam_lock);
1347 
1348         rc = mm_channel_fsm_fn(ch_obj,
1349                                MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
1350                                NULL,
1351                                NULL);
1352     } else {
1353         pthread_mutex_unlock(&my_obj->cam_lock);
1354     }
1355 
1356     return rc;
1357 }
1358 
1359 /*===========================================================================
1360  * FUNCTION   : mm_camera_flush_super_buf_queue
1361  *
1362  * DESCRIPTION: flush out all frames in the superbuf queue
1363  *
1364  * PARAMETERS :
1365  *   @my_obj       : camera object
1366  *   @ch_id        : channel handle
1367  *
1368  * RETURN     : int32_t type of status
1369  *              0  -- success
1370  *              -1 -- failure
1371  *==========================================================================*/
mm_camera_flush_super_buf_queue(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t frame_idx)1372 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
1373                                                              uint32_t frame_idx)
1374 {
1375     int32_t rc = -1;
1376     mm_channel_t * ch_obj =
1377         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1378 
1379     if (NULL != ch_obj) {
1380         pthread_mutex_lock(&ch_obj->ch_lock);
1381         pthread_mutex_unlock(&my_obj->cam_lock);
1382 
1383         rc = mm_channel_fsm_fn(ch_obj,
1384                                MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
1385                                (void *)&frame_idx,
1386                                NULL);
1387     } else {
1388         pthread_mutex_unlock(&my_obj->cam_lock);
1389     }
1390 
1391     return rc;
1392 }
1393 
1394 /*===========================================================================
1395  * FUNCTION   : mm_camera_config_channel_notify
1396  *
1397  * DESCRIPTION: configures the channel notification mode
1398  *
1399  * PARAMETERS :
1400  *   @my_obj       : camera object
1401  *   @ch_id        : channel handle
1402  *   @notify_mode  : notification mode
1403  *
1404  * RETURN     : int32_t type of status
1405  *              0  -- success
1406  *              -1 -- failure
1407  *==========================================================================*/
mm_camera_config_channel_notify(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)1408 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
1409                                         uint32_t ch_id,
1410                                         mm_camera_super_buf_notify_mode_t notify_mode)
1411 {
1412     int32_t rc = -1;
1413     mm_channel_t * ch_obj =
1414         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1415 
1416     if (NULL != ch_obj) {
1417         pthread_mutex_lock(&ch_obj->ch_lock);
1418         pthread_mutex_unlock(&my_obj->cam_lock);
1419 
1420         rc = mm_channel_fsm_fn(ch_obj,
1421                                MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
1422                                (void *)&notify_mode,
1423                                NULL);
1424     } else {
1425         pthread_mutex_unlock(&my_obj->cam_lock);
1426     }
1427 
1428     return rc;
1429 }
1430 
1431 /*===========================================================================
1432  * FUNCTION   : mm_camera_set_stream_parms
1433  *
1434  * DESCRIPTION: set parameters per stream
1435  *
1436  * PARAMETERS :
1437  *   @my_obj       : camera object
1438  *   @ch_id        : channel handle
1439  *   @s_id         : stream handle
1440  *   @parms        : ptr to a param struct to be set to server
1441  *
1442  * RETURN     : int32_t type of status
1443  *              0  -- success
1444  *              -1 -- failure
1445  * NOTE       : Assume the parms struct buf is already mapped to server via
1446  *              domain socket. Corresponding fields of parameters to be set
1447  *              are already filled in by upper layer caller.
1448  *==========================================================================*/
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)1449 int32_t mm_camera_set_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_SET_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_get_stream_parms
1480  *
1481  * DESCRIPTION: get parameters per stream
1482  *
1483  * PARAMETERS :
1484  *   @my_obj       : camera object
1485  *   @ch_id        : channel handle
1486  *   @s_id         : stream handle
1487  *   @parms        : ptr to a param struct to be get from server
1488  *
1489  * RETURN     : int32_t type of status
1490  *              0  -- success
1491  *              -1 -- failure
1492  * NOTE       : Assume the parms struct buf is already mapped to server via
1493  *              domain socket. Parameters to be get from server are already
1494  *              filled in by upper layer caller. After this call, corresponding
1495  *              fields of requested parameters will be filled in by server with
1496  *              detailed information.
1497  *==========================================================================*/
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)1498 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
1499                                    uint32_t ch_id,
1500                                    uint32_t s_id,
1501                                    cam_stream_parm_buffer_t *parms)
1502 {
1503     int32_t rc = -1;
1504     mm_evt_paylod_set_get_stream_parms_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 = s_id;
1514         payload.parms = parms;
1515 
1516         rc = mm_channel_fsm_fn(ch_obj,
1517                                MM_CHANNEL_EVT_GET_STREAM_PARM,
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_do_stream_action
1529  *
1530  * DESCRIPTION: request server to perform stream based action. Maybe removed later
1531  *              if the functionality is included in mm_camera_set_parms
1532  *
1533  * PARAMETERS :
1534  *   @my_obj       : camera object
1535  *   @ch_id        : channel handle
1536  *   @s_id         : stream handle
1537  *   @actions      : ptr to an action struct buf to be performed by server
1538  *
1539  * RETURN     : int32_t type of status
1540  *              0  -- success
1541  *              -1 -- failure
1542  * NOTE       : Assume the action struct buf is already mapped to server via
1543  *              domain socket. Actions to be performed by server are already
1544  *              filled in by upper layer caller.
1545  *==========================================================================*/
mm_camera_do_stream_action(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,void * actions)1546 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
1547                                    uint32_t ch_id,
1548                                    uint32_t stream_id,
1549                                    void *actions)
1550 {
1551     int32_t rc = -1;
1552     mm_evt_paylod_do_stream_action_t payload;
1553     mm_channel_t * ch_obj =
1554         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1555 
1556     if (NULL != ch_obj) {
1557         pthread_mutex_lock(&ch_obj->ch_lock);
1558         pthread_mutex_unlock(&my_obj->cam_lock);
1559 
1560         memset(&payload, 0, sizeof(payload));
1561         payload.stream_id = stream_id;
1562         payload.actions = actions;
1563 
1564         rc = mm_channel_fsm_fn(ch_obj,
1565                                MM_CHANNEL_EVT_DO_STREAM_ACTION,
1566                                (void*)&payload,
1567                                NULL);
1568     } else {
1569         pthread_mutex_unlock(&my_obj->cam_lock);
1570     }
1571 
1572     return rc;
1573 }
1574 
1575 /*===========================================================================
1576  * FUNCTION   : mm_camera_map_stream_buf
1577  *
1578  * DESCRIPTION: mapping stream buffer via domain socket to server
1579  *
1580  * PARAMETERS :
1581  *   @my_obj       : camera object
1582  *   @ch_id        : channel handle
1583  *   @s_id         : stream handle
1584  *   @buf_type     : type of buffer to be mapped. could be following values:
1585  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1586  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1587  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1588  *   @buf_idx      : index of buffer within the stream buffers, only valid if
1589  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1590  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1591  *   @plane_idx    : plane index. If all planes share the same fd,
1592  *                   plane_idx = -1; otherwise, plean_idx is the
1593  *                   index to plane (0..num_of_planes)
1594  *   @fd           : file descriptor of the buffer
1595  *   @size         : size of the buffer
1596  *
1597  * RETURN     : int32_t type of status
1598  *              0  -- success
1599  *              -1 -- failure
1600  *==========================================================================*/
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,void * buffer)1601 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
1602                                  uint32_t ch_id,
1603                                  uint32_t stream_id,
1604                                  uint8_t buf_type,
1605                                  uint32_t buf_idx,
1606                                  int32_t plane_idx,
1607                                  int fd,
1608                                  size_t size,
1609                                  void *buffer)
1610 {
1611     int32_t rc = -1;
1612     cam_buf_map_type payload;
1613     mm_channel_t * ch_obj =
1614         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1615 
1616     if (NULL != ch_obj) {
1617         pthread_mutex_lock(&ch_obj->ch_lock);
1618         pthread_mutex_unlock(&my_obj->cam_lock);
1619 
1620         memset(&payload, 0, sizeof(payload));
1621         payload.stream_id = stream_id;
1622         payload.type = buf_type;
1623         payload.frame_idx = buf_idx;
1624         payload.plane_idx = plane_idx;
1625         payload.fd = fd;
1626         payload.size = size;
1627         payload.buffer = buffer;
1628         rc = mm_channel_fsm_fn(ch_obj,
1629                                MM_CHANNEL_EVT_MAP_STREAM_BUF,
1630                                (void*)&payload,
1631                                NULL);
1632     } else {
1633         pthread_mutex_unlock(&my_obj->cam_lock);
1634     }
1635 
1636     return rc;
1637 }
1638 
1639 /*===========================================================================
1640  * FUNCTION   : mm_camera_map_stream_bufs
1641  *
1642  * DESCRIPTION: mapping stream buffers via domain socket to server
1643  *
1644  * PARAMETERS :
1645  *   @my_obj       : camera object
1646  *   @ch_id        : channel handle
1647  *   @buf_map_list : list of buffers to be mapped
1648  *
1649  * RETURN     : int32_t type of status
1650  *              0  -- success
1651  *              -1 -- failure
1652  *==========================================================================*/
mm_camera_map_stream_bufs(mm_camera_obj_t * my_obj,uint32_t ch_id,const cam_buf_map_type_list * buf_map_list)1653 int32_t mm_camera_map_stream_bufs(mm_camera_obj_t *my_obj,
1654                                   uint32_t ch_id,
1655                                   const cam_buf_map_type_list *buf_map_list)
1656 {
1657     int32_t rc = -1;
1658     cam_buf_map_type_list payload;
1659     mm_channel_t * ch_obj =
1660         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1661 
1662     if (NULL != ch_obj) {
1663         pthread_mutex_lock(&ch_obj->ch_lock);
1664         pthread_mutex_unlock(&my_obj->cam_lock);
1665 
1666         memcpy(&payload, buf_map_list, sizeof(payload));
1667         rc = mm_channel_fsm_fn(ch_obj,
1668                                MM_CHANNEL_EVT_MAP_STREAM_BUFS,
1669                                (void*)&payload,
1670                                NULL);
1671     } else {
1672         pthread_mutex_unlock(&my_obj->cam_lock);
1673     }
1674 
1675     return rc;
1676 }
1677 
1678 /*===========================================================================
1679  * FUNCTION   : mm_camera_unmap_stream_buf
1680  *
1681  * DESCRIPTION: unmapping stream buffer via domain socket to server
1682  *
1683  * PARAMETERS :
1684  *   @my_obj       : camera object
1685  *   @ch_id        : channel handle
1686  *   @s_id         : stream handle
1687  *   @buf_type     : type of buffer to be mapped. could be following values:
1688  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1689  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1690  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1691  *   @buf_idx      : index of buffer within the stream buffers, only valid if
1692  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1693  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1694  *   @plane_idx    : plane index. If all planes share the same fd,
1695  *                   plane_idx = -1; otherwise, plean_idx is the
1696  *                   index to plane (0..num_of_planes)
1697  *
1698  * RETURN     : int32_t type of status
1699  *              0  -- success
1700  *              -1 -- failure
1701  *==========================================================================*/
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)1702 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
1703                                    uint32_t ch_id,
1704                                    uint32_t stream_id,
1705                                    uint8_t buf_type,
1706                                    uint32_t buf_idx,
1707                                    int32_t plane_idx)
1708 {
1709     int32_t rc = -1;
1710     cam_buf_unmap_type payload;
1711     mm_channel_t * ch_obj =
1712         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1713 
1714     if (NULL != ch_obj) {
1715         pthread_mutex_lock(&ch_obj->ch_lock);
1716         pthread_mutex_unlock(&my_obj->cam_lock);
1717 
1718         memset(&payload, 0, sizeof(payload));
1719         payload.stream_id = stream_id;
1720         payload.type = buf_type;
1721         payload.frame_idx = buf_idx;
1722         payload.plane_idx = plane_idx;
1723         rc = mm_channel_fsm_fn(ch_obj,
1724                                MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
1725                                (void*)&payload,
1726                                NULL);
1727     } else {
1728         pthread_mutex_unlock(&my_obj->cam_lock);
1729     }
1730 
1731     return rc;
1732 }
1733 
1734 /*===========================================================================
1735  * FUNCTION   : mm_camera_evt_sub
1736  *
1737  * DESCRIPTION: subscribe/unsubscribe event notify from kernel
1738  *
1739  * PARAMETERS :
1740  *   @my_obj       : camera object
1741  *   @reg_flag     : 1 -- subscribe ; 0 -- unsubscribe
1742  *
1743  * RETURN     : int32_t type of status
1744  *              0  -- success
1745  *              -1 -- failure
1746  *==========================================================================*/
mm_camera_evt_sub(mm_camera_obj_t * my_obj,uint8_t reg_flag)1747 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1748                           uint8_t reg_flag)
1749 {
1750     int32_t rc = 0;
1751     struct v4l2_event_subscription sub;
1752 
1753     memset(&sub, 0, sizeof(sub));
1754     sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
1755     sub.id = MSM_CAMERA_MSM_NOTIFY;
1756     if(FALSE == reg_flag) {
1757         /* unsubscribe */
1758         rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1759         if (rc < 0) {
1760             LOGE("unsubscribe event rc = %d, errno %d",
1761                      rc, errno);
1762             return rc;
1763         }
1764         /* remove evt fd from the polling thraed when unreg the last event */
1765         rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
1766                                                my_obj->my_hdl,
1767                                                mm_camera_sync_call);
1768     } else {
1769         rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1770         if (rc < 0) {
1771             LOGE("subscribe event rc = %d, errno %d",
1772              rc, errno);
1773             return rc;
1774         }
1775         /* add evt fd to polling thread when subscribe the first event */
1776         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1777                                                my_obj->my_hdl,
1778                                                my_obj->ctrl_fd,
1779                                                mm_camera_event_notify,
1780                                                (void*)my_obj,
1781                                                mm_camera_sync_call);
1782     }
1783     return rc;
1784 }
1785 
1786 /*===========================================================================
1787  * FUNCTION   : mm_camera_util_wait_for_event
1788  *
1789  * DESCRIPTION: utility function to wait for certain events
1790  *
1791  * PARAMETERS :
1792  *   @my_obj       : camera object
1793  *   @evt_mask     : mask for events to be waited. Any of event in the mask would
1794  *                   trigger the wait to end
1795  *   @status       : status of the event
1796  *
1797  * RETURN     : none
1798  *==========================================================================*/
mm_camera_util_wait_for_event(mm_camera_obj_t * my_obj,uint32_t evt_mask,uint32_t * status)1799 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
1800                                    uint32_t evt_mask,
1801                                    uint32_t *status)
1802 {
1803     int32_t rc = 0;
1804     struct timespec ts;
1805 
1806     pthread_mutex_lock(&my_obj->evt_lock);
1807     while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
1808         clock_gettime(CLOCK_REALTIME, &ts);
1809         ts.tv_sec += WAIT_TIMEOUT;
1810         rc = pthread_cond_timedwait(&my_obj->evt_cond, &my_obj->evt_lock, &ts);
1811         if (rc) {
1812             LOGE("pthread_cond_timedwait of evt_mask 0x%x failed %d",
1813                      evt_mask, rc);
1814             break;
1815         }
1816     }
1817     if (!rc) {
1818         *status = my_obj->evt_rcvd.status;
1819     } else {
1820         *status = MSM_CAMERA_STATUS_FAIL;
1821     }
1822     /* reset local storage for recieved event for next event */
1823     memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
1824     pthread_mutex_unlock(&my_obj->evt_lock);
1825 }
1826 
1827 /*===========================================================================
1828  * FUNCTION   : mm_camera_util_bundled_sendmsg
1829  *
1830  * DESCRIPTION: utility function to send bundled msg via domain socket
1831  *
1832  * PARAMETERS :
1833  *   @my_obj       : camera object
1834  *   @msg          : message to be sent
1835  *   @buf_size     : size of the message to be sent
1836  *   @sendfds      : array of file descriptors to be sent
1837  *   @numfds       : number of file descriptors to be sent
1838  *
1839  * RETURN     : int32_t type of status
1840  *              0  -- success
1841  *              -1 -- failure
1842  *==========================================================================*/
mm_camera_util_bundled_sendmsg(mm_camera_obj_t * my_obj,void * msg,size_t buf_size,int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],int numfds)1843 int32_t mm_camera_util_bundled_sendmsg(mm_camera_obj_t *my_obj,
1844                                        void *msg,
1845                                        size_t buf_size,
1846                                        int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],
1847                                        int numfds)
1848 {
1849     int32_t rc = -1;
1850     uint32_t status;
1851 
1852     /* need to lock msg_lock, since sendmsg until response back is deemed as one operation*/
1853     pthread_mutex_lock(&my_obj->msg_lock);
1854     if(mm_camera_socket_bundle_sendmsg(my_obj->ds_fd, msg, buf_size, sendfds, numfds) > 0) {
1855         /* wait for event that mapping/unmapping is done */
1856         mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1857         if (MSM_CAMERA_STATUS_SUCCESS == status) {
1858             rc = 0;
1859         }
1860     }
1861     pthread_mutex_unlock(&my_obj->msg_lock);
1862     return rc;
1863 }
1864 
1865 /*===========================================================================
1866  * FUNCTION   : mm_camera_util_sendmsg
1867  *
1868  * DESCRIPTION: utility function to send msg via domain socket
1869  *
1870  * PARAMETERS :
1871  *   @my_obj       : camera object
1872  *   @msg          : message to be sent
1873  *   @buf_size     : size of the message to be sent
1874  *   @sendfd       : >0 if any file descriptor need to be passed across process
1875  *
1876  * RETURN     : int32_t type of status
1877  *              0  -- success
1878  *              -1 -- failure
1879  *==========================================================================*/
mm_camera_util_sendmsg(mm_camera_obj_t * my_obj,void * msg,size_t buf_size,int sendfd)1880 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
1881                                void *msg,
1882                                size_t buf_size,
1883                                int sendfd)
1884 {
1885     int32_t rc = -1;
1886     uint32_t status;
1887 
1888     /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
1889     pthread_mutex_lock(&my_obj->msg_lock);
1890     if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
1891         /* wait for event that mapping/unmapping is done */
1892         mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1893         if (MSM_CAMERA_STATUS_SUCCESS == status) {
1894             rc = 0;
1895         }
1896     }
1897     pthread_mutex_unlock(&my_obj->msg_lock);
1898     return rc;
1899 }
1900 
1901 /*===========================================================================
1902  * FUNCTIOa   : mm_camera_map_buf
1903  *
1904  * DESCRIPTION: mapping camera buffer via domain socket to server
1905  *
1906  * PARAMETERS :
1907  *   @my_obj       : camera object
1908  *   @buf_type     : type of buffer to be mapped. could be following values:
1909  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1910  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1911  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1912  *   @fd           : file descriptor of the buffer
1913  *   @size         : size of the buffer
1914  *
1915  * RETURN     : int32_t type of status
1916  *              0  -- success
1917  *              -1 -- failure
1918  *==========================================================================*/
mm_camera_map_buf(mm_camera_obj_t * my_obj,uint8_t buf_type,int fd,size_t size,void * buffer)1919 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1920         uint8_t buf_type, int fd, size_t size, void *buffer)
1921 {
1922     int32_t rc = 0;
1923 
1924     cam_sock_packet_t packet;
1925     memset(&packet, 0, sizeof(cam_sock_packet_t));
1926     packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
1927     packet.payload.buf_map.type = buf_type;
1928     packet.payload.buf_map.fd = fd;
1929     packet.payload.buf_map.size = size;
1930     packet.payload.buf_map.buffer = buffer;
1931 #ifdef DAEMON_PRESENT
1932     rc = mm_camera_util_sendmsg(my_obj,
1933                                 &packet,
1934                                 sizeof(cam_sock_packet_t),
1935                                 fd);
1936 #else
1937     cam_shim_packet_t *shim_cmd;
1938     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
1939             my_obj->sessionid, &packet);
1940     rc = mm_camera_module_send_cmd(shim_cmd);
1941     mm_camera_destroy_shim_cmd_packet(shim_cmd);
1942 #endif
1943     pthread_mutex_unlock(&my_obj->cam_lock);
1944     return rc;
1945 }
1946 
1947 /*===========================================================================
1948  * FUNCTION   : mm_camera_map_bufs
1949  *
1950  * DESCRIPTION: mapping camera buffers via domain socket to server
1951  *
1952  * PARAMETERS :
1953  *   @my_obj       : camera object
1954  *   @buf_map_list : list of buffers to be mapped
1955  *
1956  * RETURN     : int32_t type of status
1957  *              0  -- success
1958  *              -1 -- failure
1959  *==========================================================================*/
mm_camera_map_bufs(mm_camera_obj_t * my_obj,const cam_buf_map_type_list * buf_map_list)1960 int32_t mm_camera_map_bufs(mm_camera_obj_t *my_obj,
1961                            const cam_buf_map_type_list* buf_map_list)
1962 {
1963     int32_t rc = 0;
1964     cam_sock_packet_t packet;
1965     memset(&packet, 0, sizeof(cam_sock_packet_t));
1966     packet.msg_type = CAM_MAPPING_TYPE_FD_BUNDLED_MAPPING;
1967 
1968     memcpy(&packet.payload.buf_map_list, buf_map_list,
1969            sizeof(packet.payload.buf_map_list));
1970 
1971     int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM];
1972     uint32_t numbufs = packet.payload.buf_map_list.length;
1973     uint32_t i;
1974     for (i = 0; i < numbufs; i++) {
1975         sendfds[i] = packet.payload.buf_map_list.buf_maps[i].fd;
1976         packet.payload.buf_map_list.buf_maps[i].buffer =
1977                 buf_map_list->buf_maps[i].buffer;
1978     }
1979     for (i = numbufs; i < CAM_MAX_NUM_BUFS_PER_STREAM; i++) {
1980         packet.payload.buf_map_list.buf_maps[i].fd = -1;
1981         sendfds[i] = -1;
1982     }
1983 
1984 #ifdef DAEMON_PRESENT
1985     rc = mm_camera_util_bundled_sendmsg(my_obj,
1986             &packet, sizeof(cam_sock_packet_t),
1987             sendfds, numbufs);
1988 #else
1989     cam_shim_packet_t *shim_cmd;
1990     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
1991             my_obj->sessionid, &packet);
1992     rc = mm_camera_module_send_cmd(shim_cmd);
1993     mm_camera_destroy_shim_cmd_packet(shim_cmd);
1994 #endif
1995 
1996     pthread_mutex_unlock(&my_obj->cam_lock);
1997     return rc;
1998 }
1999 
2000 /*===========================================================================
2001  * FUNCTION   : mm_camera_unmap_buf
2002  *
2003  * DESCRIPTION: unmapping camera buffer via domain socket to server
2004  *
2005  * PARAMETERS :
2006  *   @my_obj       : camera object
2007  *   @buf_type     : type of buffer to be mapped. could be following values:
2008  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
2009  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
2010  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
2011  *
2012  * RETURN     : int32_t type of status
2013  *              0  -- success
2014  *              -1 -- failure
2015  *==========================================================================*/
mm_camera_unmap_buf(mm_camera_obj_t * my_obj,uint8_t buf_type)2016 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
2017                             uint8_t buf_type)
2018 {
2019     int32_t rc = 0;
2020     cam_sock_packet_t packet;
2021     memset(&packet, 0, sizeof(cam_sock_packet_t));
2022     packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
2023     packet.payload.buf_unmap.type = buf_type;
2024 #ifdef DAEMON_PRESENT
2025     rc = mm_camera_util_sendmsg(my_obj,
2026                                 &packet,
2027                                 sizeof(cam_sock_packet_t),
2028                                 -1);
2029 #else
2030     cam_shim_packet_t *shim_cmd;
2031     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
2032             my_obj->sessionid, &packet);
2033     rc = mm_camera_module_send_cmd(shim_cmd);
2034     mm_camera_destroy_shim_cmd_packet(shim_cmd);
2035 #endif
2036     pthread_mutex_unlock(&my_obj->cam_lock);
2037     return rc;
2038 }
2039 
2040 /*===========================================================================
2041  * FUNCTION   : mm_camera_util_s_ctrl
2042  *
2043  * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
2044  *
2045  * PARAMETERS :
2046  *   @my_obj     :Camera object
2047  *   @stream_id :streamID
2048  *   @fd      : file descritpor for sending ioctl
2049  *   @id      : control id
2050  *   @value   : value of the ioctl to be sent
2051  *
2052  * RETURN     : int32_t type of status
2053  *              0  -- success
2054  *              -1 -- failure
2055  *==========================================================================*/
mm_camera_util_s_ctrl(__unused mm_camera_obj_t * my_obj,__unused int stream_id,int32_t fd,uint32_t id,int32_t * value)2056 int32_t mm_camera_util_s_ctrl(__unused mm_camera_obj_t *my_obj,
2057         __unused int stream_id, int32_t fd,
2058         uint32_t id, int32_t *value)
2059 {
2060     int rc = 0;
2061 
2062 #ifdef DAEMON_PRESENT
2063     struct v4l2_control control;
2064     memset(&control, 0, sizeof(control));
2065     control.id = id;
2066     if (value != NULL) {
2067         control.value = *value;
2068     }
2069     rc = ioctl(fd, VIDIOC_S_CTRL, &control);
2070     LOGD("fd=%d, S_CTRL, id=0x%x, value = %p, rc = %d\n",
2071           fd, id, value, rc);
2072     if (rc < 0) {
2073         LOGE("ioctl failed %d, errno %d", rc, errno);
2074     } else if (value != NULL) {
2075         *value = control.value;
2076     }
2077 #else /* DAEMON_PRESENT */
2078     cam_shim_packet_t *shim_cmd;
2079     cam_shim_cmd_data shim_cmd_data;
2080     (void)fd;
2081     (void)value;
2082     memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
2083 
2084     shim_cmd_data.command = id;
2085     shim_cmd_data.stream_id = stream_id;
2086     shim_cmd_data.value = NULL;
2087     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM,
2088             my_obj->sessionid,&shim_cmd_data);
2089     rc = mm_camera_module_send_cmd(shim_cmd);
2090     mm_camera_destroy_shim_cmd_packet(shim_cmd);
2091 #endif /* DAEMON_PRESENT */
2092     return (rc >= 0)? 0 : -1;
2093 }
2094 
2095 /*===========================================================================
2096  * FUNCTION   : mm_camera_util_g_ctrl
2097  *
2098  * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
2099  *
2100  * PARAMETERS :
2101  *   @my_obj     :Camera object
2102  *   @stream_id :streamID
2103  *   @fd      : file descritpor for sending ioctl
2104  *   @id      : control id
2105  *   @value   : value of the ioctl to be sent
2106  *
2107  * RETURN     : int32_t type of status
2108  *              0  -- success
2109  *              -1 -- failure
2110  *==========================================================================*/
mm_camera_util_g_ctrl(__unused mm_camera_obj_t * my_obj,__unused int stream_id,int32_t fd,uint32_t id,int32_t * value)2111 int32_t mm_camera_util_g_ctrl(__unused mm_camera_obj_t *my_obj,
2112         __unused int stream_id, int32_t fd, uint32_t id, int32_t *value)
2113 {
2114     int rc = 0;
2115     struct v4l2_control control;
2116 
2117     memset(&control, 0, sizeof(control));
2118     control.id = id;
2119     if (value != NULL) {
2120         control.value = *value;
2121     }
2122 
2123 #ifdef DAEMON_PRESENT
2124     rc = ioctl(fd, VIDIOC_G_CTRL, &control);
2125     LOGD("fd=%d, G_CTRL, id=0x%x, rc = %d\n", fd, id, rc);
2126     if (value != NULL) {
2127         *value = control.value;
2128     }
2129 #else /* DAEMON_PRESENT */
2130     cam_shim_packet_t *shim_cmd;
2131     cam_shim_cmd_data shim_cmd_data;
2132     (void)fd;
2133     memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
2134 
2135     shim_cmd_data.command = id;
2136     shim_cmd_data.stream_id = stream_id;
2137     shim_cmd_data.value = value;
2138     shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM,
2139             my_obj->sessionid, &shim_cmd_data);
2140 
2141     rc = mm_camera_module_send_cmd(shim_cmd);
2142     mm_camera_destroy_shim_cmd_packet(shim_cmd);
2143 #endif /* DAEMON_PRESENT */
2144     return (rc >= 0)? 0 : -1;
2145 }
2146 
2147 /*===========================================================================
2148  * FUNCTION   : mm_camera_create_shim_cmd
2149  *
2150  * DESCRIPTION: Prepare comand packet to pass to back-end through shim layer
2151  *
2152  * PARAMETERS :
2153  *   @type                : type of command
2154  *   @sessionID        : camera sessionID
2155   *  @data                : command data
2156  *
2157  * RETURN     : NULL in case of failures
2158                       allocated pointer to shim packet
2159  *==========================================================================*/
mm_camera_create_shim_cmd_packet(cam_shim_cmd_type type,uint32_t sessionID,void * data)2160 cam_shim_packet_t *mm_camera_create_shim_cmd_packet(cam_shim_cmd_type type,
2161         uint32_t sessionID, void *data)
2162 {
2163     cam_shim_packet_t *shim_pack = NULL;
2164     uint32_t i = 0;
2165 
2166     shim_pack = (cam_shim_packet_t *)malloc(sizeof(cam_shim_packet_t));
2167     if (shim_pack == NULL) {
2168         LOGE("Cannot allocate a memory for shim packet");
2169         return NULL;
2170     }
2171     memset(shim_pack, 0, sizeof(cam_shim_packet_t));
2172     shim_pack->cmd_type = type;
2173     shim_pack->session_id = sessionID;
2174     switch (type) {
2175         case CAM_SHIM_SET_PARM:
2176         case CAM_SHIM_GET_PARM: {
2177             cam_shim_cmd_data *cmd_data = (cam_shim_cmd_data *)data;
2178             shim_pack->cmd_data = *cmd_data;
2179             break;
2180         }
2181         case CAM_SHIM_REG_BUF: {
2182             cam_reg_buf_t *cmd_data = (cam_reg_buf_t *)data;
2183             shim_pack->reg_buf = *cmd_data;
2184             break;
2185         }
2186         case CAM_SHIM_BUNDLE_CMD: {
2187             cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)data;
2188             for (i = 0; i < cmd_data->stream_count; i++) {
2189                 shim_pack->bundle_cmd.stream_event[i] = cmd_data->stream_event[i];
2190             }
2191             shim_pack->bundle_cmd.stream_count = cmd_data->stream_count;
2192             break;
2193         }
2194         default:
2195             LOGW("No Data for this command");
2196     }
2197     return shim_pack;
2198 }
2199 
2200 /*===========================================================================
2201  * FUNCTION   : mm_camera_destroy_shim_cmd
2202  *
2203  * DESCRIPTION: destroy shim packet
2204  *
2205  * PARAMETERS :
2206  *   @cmd                : ptr to shim packet
2207 
2208  * RETURN     : int32_t type of status
2209  *              0  -- success
2210  *              -1 -- failure
2211  *==========================================================================*/
mm_camera_destroy_shim_cmd_packet(cam_shim_packet_t * cmd)2212 int32_t mm_camera_destroy_shim_cmd_packet(cam_shim_packet_t *cmd)
2213 {
2214     int32_t rc = 0;
2215     uint32_t i = 0, j = 0;
2216 
2217     if (cmd == NULL) {
2218         LOGW("Command is NULL");
2219         return rc;
2220     }
2221 
2222     switch (cmd->cmd_type) {
2223         case CAM_SHIM_SET_PARM:
2224         case CAM_SHIM_GET_PARM:
2225         case CAM_SHIM_REG_BUF:
2226             break;
2227         case CAM_SHIM_BUNDLE_CMD: {
2228             cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)cmd;
2229             for (i = 0; i < cmd_data->stream_count; i++) {
2230                 cam_shim_cmd_packet_t *stream_evt = &cmd_data->stream_event[i];
2231                 for (j = 0; j < stream_evt->cmd_count; j++) {
2232                     if (stream_evt->cmd != NULL) {
2233                         if(stream_evt->cmd->cmd_type == CAM_SHIM_BUNDLE_CMD) {
2234                             mm_camera_destroy_shim_cmd_packet(stream_evt->cmd);
2235                         }
2236                         free(stream_evt->cmd);
2237                         stream_evt->cmd = NULL;
2238                     }
2239                 }
2240             }
2241             break;
2242         }
2243         default:
2244             LOGW("No Data for this command");
2245     }
2246     free(cmd);
2247     cmd = NULL;
2248     return rc;
2249 }
2250 
2251 /*===========================================================================
2252  * FUNCTION   : mm_camera_channel_advanced_capture
2253  *
2254  * DESCRIPTION: sets the channel advanced capture
2255  *
2256  * PARAMETERS :
2257  *   @my_obj       : camera object
2258  *   @ch_id        : channel handle
2259   *   @type : advanced capture type.
2260  *   @start_flag  : flag to indicate start/stop
2261   *   @in_value  : input configaration
2262  *
2263  * RETURN     : int32_t type of status
2264  *              0  -- success
2265  *              -1 -- failure
2266  *==========================================================================*/
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)2267 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj,
2268             uint32_t ch_id, mm_camera_advanced_capture_t type,
2269             uint32_t trigger, void *in_value)
2270 {
2271     LOGD("E type = %d", type);
2272     int32_t rc = -1;
2273     mm_channel_t * ch_obj =
2274         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2275 
2276     if (NULL != ch_obj) {
2277         pthread_mutex_lock(&ch_obj->ch_lock);
2278         pthread_mutex_unlock(&my_obj->cam_lock);
2279         switch (type) {
2280             case MM_CAMERA_AF_BRACKETING:
2281                 rc = mm_channel_fsm_fn(ch_obj,
2282                                        MM_CHANNEL_EVT_AF_BRACKETING,
2283                                        (void *)&trigger,
2284                                        NULL);
2285                 break;
2286             case MM_CAMERA_AE_BRACKETING:
2287                 rc = mm_channel_fsm_fn(ch_obj,
2288                                        MM_CHANNEL_EVT_AE_BRACKETING,
2289                                        (void *)&trigger,
2290                                        NULL);
2291                 break;
2292             case MM_CAMERA_FLASH_BRACKETING:
2293                 rc = mm_channel_fsm_fn(ch_obj,
2294                                        MM_CHANNEL_EVT_FLASH_BRACKETING,
2295                                        (void *)&trigger,
2296                                        NULL);
2297                 break;
2298             case MM_CAMERA_ZOOM_1X:
2299                 rc = mm_channel_fsm_fn(ch_obj,
2300                                        MM_CHANNEL_EVT_ZOOM_1X,
2301                                        (void *)&trigger,
2302                                        NULL);
2303                 break;
2304             case MM_CAMERA_FRAME_CAPTURE:
2305                 rc = mm_channel_fsm_fn(ch_obj,
2306                                        MM_CAMERA_EVT_CAPTURE_SETTING,
2307                                        (void *)in_value,
2308                                        NULL);
2309                 break;
2310             default:
2311                 break;
2312         }
2313 
2314     } else {
2315         pthread_mutex_unlock(&my_obj->cam_lock);
2316     }
2317 
2318     LOGD("X");
2319     return rc;
2320 }
2321 
2322 /*===========================================================================
2323  * FUNCTION   : mm_camera_get_session_id
2324  *
2325  * DESCRIPTION: get the session identity
2326  *
2327  * PARAMETERS :
2328  *   @my_obj       : camera object
2329  *   @sessionid: pointer to the output session id
2330  *
2331  * RETURN     : int32_t type of status
2332  *              0  -- success
2333  *              -1 -- failure
2334  * NOTE       : if this call succeeds, we will get a valid session id
2335  *==========================================================================*/
mm_camera_get_session_id(mm_camera_obj_t * my_obj,uint32_t * sessionid)2336 int32_t mm_camera_get_session_id(mm_camera_obj_t *my_obj,
2337         uint32_t* sessionid)
2338 {
2339     int32_t rc = -1;
2340     int32_t value = 0;
2341     if(sessionid != NULL) {
2342         struct v4l2_control control;
2343         memset(&control, 0, sizeof(control));
2344         control.id = MSM_CAMERA_PRIV_G_SESSION_ID;
2345         control.value = value;
2346 
2347         rc = ioctl(my_obj->ctrl_fd, VIDIOC_G_CTRL, &control);
2348         value = control.value;
2349         LOGD("fd=%d, get_session_id, id=0x%x, value = %d, rc = %d\n",
2350                  my_obj->ctrl_fd, MSM_CAMERA_PRIV_G_SESSION_ID,
2351                 value, rc);
2352         *sessionid = value;
2353     }
2354     return rc;
2355 }
2356 
2357 /*===========================================================================
2358  * FUNCTION   : mm_camera_sync_related_sensors
2359  *
2360  * DESCRIPTION: send sync cmd
2361  *
2362  * PARAMETERS :
2363  *   @my_obj       : camera object
2364  *   @parms        : ptr to the related cam info to be sent to server
2365  *
2366  * RETURN     : int32_t type of status
2367  *              0  -- success
2368  *              -1 -- failure
2369  * NOTE       : Assume the sync struct buf is already mapped to server via
2370  *              domain socket. Corresponding fields of parameters to be set
2371  *              are already filled in by upper layer caller.
2372  *==========================================================================*/
mm_camera_sync_related_sensors(mm_camera_obj_t * my_obj,cam_sync_related_sensors_event_info_t * parms)2373 int32_t mm_camera_sync_related_sensors(mm_camera_obj_t *my_obj,
2374         cam_sync_related_sensors_event_info_t* parms)
2375 {
2376     int32_t rc = -1;
2377     int32_t value = 0;
2378     if (parms !=  NULL) {
2379         rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
2380                 CAM_PRIV_SYNC_RELATED_SENSORS, &value);
2381     }
2382     pthread_mutex_unlock(&my_obj->cam_lock);
2383     return rc;
2384 }
2385 
2386 /*===========================================================================
2387  * FUNCTION   : mm_camera_reg_stream_buf_cb
2388  *
2389  * DESCRIPTION: Register callback for stream buffer
2390  *
2391  * PARAMETERS :
2392  *   @my_obj    : camera object
2393  *   @ch_id     : channel handle
2394  *   @stream_id : stream that will be linked
2395  *   @buf_cb    : special callback needs to be registered for stream buffer
2396  *   @cb_type   : Callback type SYNC/ASYNC
2397  *   @userdata  : user data pointer
2398  *
2399  * RETURN    : int32_t type of status
2400  *             0  -- success
2401  *             1 --  failure
2402  *==========================================================================*/
mm_camera_reg_stream_buf_cb(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_buf_notify_t stream_cb,mm_camera_stream_cb_type cb_type,void * userdata)2403 int32_t mm_camera_reg_stream_buf_cb(mm_camera_obj_t *my_obj,
2404         uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t stream_cb,
2405         mm_camera_stream_cb_type cb_type, void *userdata)
2406 {
2407     int rc = 0;
2408     mm_stream_data_cb_t buf_cb;
2409     mm_channel_t * ch_obj =
2410             mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2411 
2412     if (NULL != ch_obj) {
2413         pthread_mutex_lock(&ch_obj->ch_lock);
2414         pthread_mutex_unlock(&my_obj->cam_lock);
2415 
2416         memset(&buf_cb, 0, sizeof(mm_stream_data_cb_t));
2417         buf_cb.cb = stream_cb;
2418         buf_cb.cb_count = -1;
2419         buf_cb.cb_type = cb_type;
2420         buf_cb.user_data = userdata;
2421 
2422         mm_evt_paylod_reg_stream_buf_cb payload;
2423         memset(&payload, 0, sizeof(mm_evt_paylod_reg_stream_buf_cb));
2424         payload.buf_cb = buf_cb;
2425         payload.stream_id = stream_id;
2426         mm_channel_fsm_fn(ch_obj,
2427                 MM_CHANNEL_EVT_REG_STREAM_BUF_CB,
2428                 (void*)&payload, NULL);
2429     } else {
2430         pthread_mutex_unlock(&my_obj->cam_lock);
2431     }
2432     return rc;
2433 }
2434 
2435 #ifdef QCAMERA_REDEFINE_LOG
2436 
2437 /*===========================================================================
2438  * DESCRIPTION: mm camera debug interface
2439  *
2440  *==========================================================================*/
2441 pthread_mutex_t dbg_log_mutex;
2442 
2443 #undef LOG_TAG
2444 #define LOG_TAG "QCamera"
2445 #define CDBG_MAX_STR_LEN 1024
2446 #define CDBG_MAX_LINE_LENGTH 256
2447 
2448 /* current trace loggin permissions
2449    * {NONE, ERR, WARN, HIGH, DEBUG, LOW, INFO} */
2450 int g_cam_log[CAM_LAST_MODULE][CAM_GLBL_DBG_INFO + 1] = {
2451     {0, 1, 0, 0, 0, 0, 1}, /* CAM_NO_MODULE     */
2452     {0, 1, 0, 0, 0, 0, 1}, /* CAM_HAL_MODULE    */
2453     {0, 1, 0, 0, 0, 0, 1}, /* CAM_MCI_MODULE    */
2454     {0, 1, 0, 0, 0, 0, 1}, /* CAM_JPEG_MODULE   */
2455 };
2456 
2457 /* string representation for logging level */
2458 static const char *cam_dbg_level_to_str[] = {
2459      "",        /* CAM_GLBL_DBG_NONE  */
2460      "<ERROR>", /* CAM_GLBL_DBG_ERR   */
2461      "<WARN>", /* CAM_GLBL_DBG_WARN  */
2462      "<HIGH>", /* CAM_GLBL_DBG_HIGH  */
2463      "<DBG>", /* CAM_GLBL_DBG_DEBUG */
2464      "<LOW>", /* CAM_GLBL_DBG_LOW   */
2465      "<INFO>"  /* CAM_GLBL_DBG_INFO  */
2466 };
2467 
2468 /* current trace logging configuration */
2469 typedef struct {
2470    cam_global_debug_level_t  level;
2471    int                       initialized;
2472    const char               *name;
2473    const char               *prop;
2474 } module_debug_t;
2475 
2476 static module_debug_t cam_loginfo[(int)CAM_LAST_MODULE] = {
2477   {CAM_GLBL_DBG_ERR, 1,
2478       "",         "persist.camera.global.debug"     }, /* CAM_NO_MODULE     */
2479   {CAM_GLBL_DBG_ERR, 1,
2480       "<HAL>", "persist.camera.hal.debug"        }, /* CAM_HAL_MODULE    */
2481   {CAM_GLBL_DBG_ERR, 1,
2482       "<MCI>", "persist.camera.mci.debug"        }, /* CAM_MCI_MODULE    */
2483   {CAM_GLBL_DBG_ERR, 1,
2484       "<JPEG>", "persist.camera.mmstill.logs"     }, /* CAM_JPEG_MODULE   */
2485 };
2486 
2487 /** cam_get_dbg_level
2488  *
2489  *    @module: module name
2490  *    @level:  module debug logging level
2491  *
2492  *  Maps debug log string to value.
2493  *
2494  *  Return: logging level
2495  **/
2496 __unused
cam_get_dbg_level(const char * module,char * pValue)2497 static cam_global_debug_level_t cam_get_dbg_level(const char *module,
2498   char *pValue) {
2499 
2500   cam_global_debug_level_t rc = CAM_GLBL_DBG_NONE;
2501 
2502   if (!strcmp(pValue, "none")) {
2503     rc = CAM_GLBL_DBG_NONE;
2504   } else if (!strcmp(pValue, "warn")) {
2505     rc = CAM_GLBL_DBG_WARN;
2506   } else if (!strcmp(pValue, "debug")) {
2507     rc = CAM_GLBL_DBG_DEBUG;
2508   } else if (!strcmp(pValue, "error")) {
2509     rc = CAM_GLBL_DBG_ERR;
2510   } else if (!strcmp(pValue, "low")) {
2511     rc = CAM_GLBL_DBG_LOW;
2512   } else if (!strcmp(pValue, "high")) {
2513     rc = CAM_GLBL_DBG_HIGH;
2514   } else if (!strcmp(pValue, "info")) {
2515     rc = CAM_GLBL_DBG_INFO;
2516   } else {
2517     ALOGE("Invalid %s debug log level %s\n", module, pValue);
2518   }
2519 
2520   ALOGD("%s debug log level: %s\n", module, cam_dbg_level_to_str[rc]);
2521 
2522   return rc;
2523 }
2524 
2525 /** cam_vsnprintf
2526  *    @pdst:   destination buffer pointer
2527  *    @size:   size of destination b uffer
2528  *    @pfmt:   string format
2529  *    @argptr: variabkle length argument list
2530  *
2531  *  Processes variable length argument list to a formatted string.
2532  *
2533  *  Return: n/a
2534  **/
cam_vsnprintf(char * pdst,unsigned int size,const char * pfmt,va_list argptr)2535 static void cam_vsnprintf(char* pdst, unsigned int size,
2536                           const char* pfmt, va_list argptr) {
2537   int num_chars_written = 0;
2538 
2539   pdst[0] = '\0';
2540   num_chars_written = vsnprintf(pdst, size, pfmt, argptr);
2541 
2542   if ((num_chars_written >= (int)size) && (size > 0)) {
2543      /* Message length exceeds the buffer limit size */
2544      num_chars_written = size - 1;
2545      pdst[size - 1] = '\0';
2546   }
2547 }
2548 
2549 /** mm_camera_debug_log
2550  *    @module: origin or log message
2551  *    @level:  logging level
2552  *    @func:   caller function name
2553  *    @line:   caller line number
2554  *    @fmt:    log message formatting string
2555  *    @...:    variable argument list
2556  *
2557  *  Generig logger method.
2558  *
2559  *  Return: N/A
2560  **/
mm_camera_debug_log(const cam_modules_t module,const cam_global_debug_level_t level,const char * func,const int line,const char * fmt,...)2561 void mm_camera_debug_log(const cam_modules_t module,
2562                    const cam_global_debug_level_t level,
2563                    const char *func, const int line, const char *fmt, ...) {
2564   char    str_buffer[CDBG_MAX_STR_LEN];
2565   va_list args;
2566 
2567   va_start(args, fmt);
2568   cam_vsnprintf(str_buffer, CDBG_MAX_STR_LEN, fmt, args);
2569   va_end(args);
2570 
2571   switch (level) {
2572   case CAM_GLBL_DBG_WARN:
2573     ALOGW("%s%s %s: %d: %s", cam_loginfo[module].name,
2574       cam_dbg_level_to_str[level], func, line, str_buffer);
2575     break;
2576   case CAM_GLBL_DBG_ERR:
2577     ALOGE("%s%s %s: %d: %s", cam_loginfo[module].name,
2578       cam_dbg_level_to_str[level], func, line, str_buffer);
2579     break;
2580   case CAM_GLBL_DBG_INFO:
2581     ALOGI("%s%s %s: %d: %s", cam_loginfo[module].name,
2582       cam_dbg_level_to_str[level], func, line, str_buffer);
2583     break;
2584   case CAM_GLBL_DBG_HIGH:
2585   case CAM_GLBL_DBG_DEBUG:
2586   case CAM_GLBL_DBG_LOW:
2587   default:
2588     ALOGD("%s%s %s: %d: %s", cam_loginfo[module].name,
2589       cam_dbg_level_to_str[level], func, line, str_buffer);
2590   }
2591 }
2592 
2593  /** mm_camera_set_dbg_log_properties
2594  *
2595  *  Set global and module log level properties.
2596  *
2597  *  Return: N/A
2598  **/
mm_camera_set_dbg_log_properties(void)2599 void mm_camera_set_dbg_log_properties(void) {
2600   int          i;
2601   unsigned int j;
2602   static int   boot_init = 1;
2603   char         property_value[PROPERTY_VALUE_MAX] = {0};
2604   char         default_value[PROPERTY_VALUE_MAX]  = {0};
2605 
2606   if (boot_init) {
2607       boot_init = 0;
2608       pthread_mutex_init(&dbg_log_mutex, 0);
2609   }
2610 
2611   /* set global and individual module logging levels */
2612   pthread_mutex_lock(&dbg_log_mutex);
2613   for (i = CAM_NO_MODULE; i < CAM_LAST_MODULE; i++) {
2614     cam_global_debug_level_t log_level;
2615     snprintf(default_value, PROPERTY_VALUE_MAX, "%d", (int)cam_loginfo[i].level);
2616     property_get(cam_loginfo[i].prop, property_value, default_value);
2617     log_level = (cam_global_debug_level_t)atoi(property_value);
2618 
2619     /* fix KW warnings */
2620     if (log_level > CAM_GLBL_DBG_INFO) {
2621        log_level = CAM_GLBL_DBG_INFO;
2622     }
2623 
2624     cam_loginfo[i].level = log_level;
2625 
2626     /* The logging macros will produce a log message when logging level for
2627      * a module is less or equal to the level specified in the property for
2628      * the module, or less or equal the level specified by the global logging
2629      * property. Currently we don't allow INFO logging to be turned off */
2630     for (j = CAM_GLBL_DBG_ERR; j <= CAM_GLBL_DBG_LOW; j++) {
2631       g_cam_log[i][j] = (cam_loginfo[CAM_NO_MODULE].level != CAM_GLBL_DBG_NONE)     &&
2632                         (cam_loginfo[i].level             != CAM_GLBL_DBG_NONE)     &&
2633                         ((j                                <= cam_loginfo[i].level) ||
2634                          (j                                <= cam_loginfo[CAM_NO_MODULE].level));
2635     }
2636   }
2637   pthread_mutex_unlock(&dbg_log_mutex);
2638 }
2639 
2640 #endif
2641