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