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