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