• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
2  *
3  * Redistribution and use in source and binary forms, with or without
4  * modification, are permitted provided that the following conditions are
5  * met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above
9  *       copyright notice, this list of conditions and the following
10  *       disclaimer in the documentation and/or other materials provided
11  *       with the distribution.
12  *     * Neither the name of The Linux Foundation nor the names of its
13  *       contributors may be used to endorse or promote products derived
14  *       from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19  * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23  * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  *
28  */
29 
30 #include <pthread.h>
31 #include <errno.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <poll.h>
37 
38 #include <cam_semaphore.h>
39 
40 #include "mm_camera_dbg.h"
41 #include "mm_camera_sock.h"
42 #include "mm_camera_interface.h"
43 #include "mm_camera.h"
44 
45 #define SET_PARM_BIT32(parm, parm_arr) \
46     (parm_arr[parm/32] |= (1<<(parm%32)))
47 
48 #define GET_PARM_BIT32(parm, parm_arr) \
49     ((parm_arr[parm/32]>>(parm%32))& 0x1)
50 
51 /* internal function declare */
52 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
53                           uint8_t reg_flag);
54 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
55                               mm_camera_event_t *event);
56 
57 /*===========================================================================
58  * FUNCTION   : mm_camera_util_get_channel_by_handler
59  *
60  * DESCRIPTION: utility function to get a channel object from its handle
61  *
62  * PARAMETERS :
63  *   @cam_obj: ptr to a camera object
64  *   @handler: channel handle
65  *
66  * RETURN     : ptr to a channel object.
67  *              NULL if failed.
68  *==========================================================================*/
mm_camera_util_get_channel_by_handler(mm_camera_obj_t * cam_obj,uint32_t handler)69 mm_channel_t * mm_camera_util_get_channel_by_handler(
70                                     mm_camera_obj_t * cam_obj,
71                                     uint32_t handler)
72 {
73     int i;
74     mm_channel_t *ch_obj = NULL;
75     for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
76         if (handler == cam_obj->ch[i].my_hdl) {
77             ch_obj = &cam_obj->ch[i];
78             break;
79         }
80     }
81     return ch_obj;
82 }
83 
84 /*===========================================================================
85  * FUNCTION   : mm_camera_util_chip_is_a_family
86  *
87  * DESCRIPTION: utility function to check if the host is A family chip
88  *
89  * PARAMETERS :
90  *
91  * RETURN     : TRUE if A family.
92  *              FALSE otherwise.
93  *==========================================================================*/
mm_camera_util_chip_is_a_family(void)94 uint8_t mm_camera_util_chip_is_a_family(void)
95 {
96     int id = 0;
97     FILE *fp;
98     if ((fp = fopen("/sys/devices/system/soc/soc0/id", "r")) != NULL) {
99         fscanf(fp, "%d", &id);
100         fclose(fp);
101     }
102     if (id == 126)
103         return FALSE;
104     else
105         return TRUE;
106 }
107 
108 /*===========================================================================
109  * FUNCTION   : mm_camera_dispatch_app_event
110  *
111  * DESCRIPTION: dispatch event to apps who regitster for event notify
112  *
113  * PARAMETERS :
114  *   @cmd_cb: ptr to a struct storing event info
115  *   @user_data: user data ptr (camera object)
116  *
117  * RETURN     : none
118  *==========================================================================*/
mm_camera_dispatch_app_event(mm_camera_cmdcb_t * cmd_cb,void * user_data)119 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
120                                          void* user_data)
121 {
122     mm_camera_cmd_thread_name("mm_cam_event");
123     int i;
124     mm_camera_event_t *event = &cmd_cb->u.evt;
125     mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data;
126     if (NULL != my_obj) {
127         pthread_mutex_lock(&my_obj->cb_lock);
128         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
129             if(my_obj->evt.evt[i].evt_cb) {
130                 my_obj->evt.evt[i].evt_cb(
131                     my_obj->my_hdl,
132                     event,
133                     my_obj->evt.evt[i].user_data);
134             }
135         }
136         pthread_mutex_unlock(&my_obj->cb_lock);
137     }
138 }
139 
140 /*===========================================================================
141  * FUNCTION   : mm_camera_event_notify
142  *
143  * DESCRIPTION: callback to handle event notify from kernel. This call will
144  *              dequeue event from kernel.
145  *
146  * PARAMETERS :
147  *   @user_data: user data ptr (camera object)
148  *
149  * RETURN     : none
150  *==========================================================================*/
mm_camera_event_notify(void * user_data)151 static void mm_camera_event_notify(void* user_data)
152 {
153     struct v4l2_event ev;
154     struct msm_v4l2_event_data *msm_evt = NULL;
155     int rc;
156     mm_camera_event_t evt;
157     memset(&evt, 0, sizeof(mm_camera_event_t));
158 
159     mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
160     if (NULL != my_obj) {
161         /* read evt */
162         memset(&ev, 0, sizeof(ev));
163         rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
164 
165         if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
166             msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
167             switch (msm_evt->command) {
168             case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
169                 pthread_mutex_lock(&my_obj->evt_lock);
170                 my_obj->evt_rcvd.server_event_type = msm_evt->command;
171                 my_obj->evt_rcvd.status = msm_evt->status;
172                 pthread_cond_signal(&my_obj->evt_cond);
173                 pthread_mutex_unlock(&my_obj->evt_lock);
174                 break;
175             case MSM_CAMERA_PRIV_SHUTDOWN:
176                 {
177                     evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
178                     mm_camera_enqueue_evt(my_obj, &evt);
179                 }
180                 break;
181             default:
182                 break;
183             }
184         }
185     }
186 }
187 
188 /*===========================================================================
189  * FUNCTION   : mm_camera_enqueue_evt
190  *
191  * DESCRIPTION: enqueue received event into event queue to be processed by
192  *              event thread.
193  *
194  * PARAMETERS :
195  *   @my_obj   : ptr to a camera object
196  *   @event    : event to be queued
197  *
198  * RETURN     : int32_t type of status
199  *              0  -- success
200  *              -1 -- failure
201  *==========================================================================*/
mm_camera_enqueue_evt(mm_camera_obj_t * my_obj,mm_camera_event_t * event)202 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
203                               mm_camera_event_t *event)
204 {
205     int32_t rc = 0;
206     mm_camera_cmdcb_t *node = NULL;
207 
208     node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
209     if (NULL != node) {
210         memset(node, 0, sizeof(mm_camera_cmdcb_t));
211         node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
212         node->u.evt = *event;
213 
214         /* enqueue to evt cmd thread */
215         cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
216         /* wake up evt cmd thread */
217         cam_sem_post(&(my_obj->evt_thread.cmd_sem));
218     } else {
219         CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
220         rc = -1;
221     }
222 
223     return rc;
224 }
225 
226 /*===========================================================================
227  * FUNCTION   : mm_camera_open
228  *
229  * DESCRIPTION: open a camera
230  *
231  * PARAMETERS :
232  *   @my_obj   : ptr to a camera object
233  *
234  * RETURN     : int32_t type of status
235  *              0  -- success
236  *              -1 -- failure
237  *==========================================================================*/
mm_camera_open(mm_camera_obj_t * my_obj)238 int32_t mm_camera_open(mm_camera_obj_t *my_obj)
239 {
240     char dev_name[MM_CAMERA_DEV_NAME_LEN];
241     int32_t rc = 0;
242     int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
243     uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
244     unsigned int cam_idx = 0;
245 
246     CDBG("%s:  begin\n", __func__);
247 
248     snprintf(dev_name, sizeof(dev_name), "/dev/%s",
249              mm_camera_util_get_dev_name(my_obj->my_hdl));
250     sscanf(dev_name, "/dev/video%u", &cam_idx);
251     CDBG_HIGH("%s: dev name = %s, cam_idx = %d", __func__, dev_name, cam_idx);
252 
253     do{
254         n_try--;
255         my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
256         CDBG("%s:  ctrl_fd = %d, errno == %d", __func__, my_obj->ctrl_fd, errno);
257         if((my_obj->ctrl_fd > 0) || (errno != EIO) || (n_try <= 0 )) {
258             CDBG_HIGH("%s:  opened, break out while loop", __func__);
259             break;
260         }
261         CDBG_HIGH("%s:failed with I/O error retrying after %d milli-seconds",
262              __func__, sleep_msec);
263         usleep(sleep_msec * 1000);
264     }while (n_try > 0);
265 
266     if (my_obj->ctrl_fd <= 0) {
267         CDBG_ERROR("%s: cannot open control fd of '%s' (%s)\n",
268                  __func__, dev_name, strerror(errno));
269         rc = -1;
270         goto on_error;
271     }
272 
273     /* open domain socket*/
274     n_try = MM_CAMERA_DEV_OPEN_TRIES;
275     do {
276         n_try--;
277         my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
278         CDBG("%s:  ds_fd = %d, errno = %d", __func__, my_obj->ds_fd, errno);
279         if((my_obj->ds_fd > 0) || (n_try <= 0 )) {
280             CDBG("%s:  opened, break out while loop", __func__);
281             break;
282         }
283         CDBG("%s:failed with I/O error retrying after %d milli-seconds",
284              __func__, sleep_msec);
285         usleep(sleep_msec * 1000);
286     } while (n_try > 0);
287 
288     if (my_obj->ds_fd <= 0) {
289         CDBG_ERROR("%s: cannot open domain socket fd of '%s'(%s)\n",
290                  __func__, dev_name, strerror(errno));
291         rc = -1;
292         goto on_error;
293     }
294     pthread_mutex_init(&my_obj->msg_lock, NULL);
295 
296     pthread_mutex_init(&my_obj->cb_lock, NULL);
297     pthread_mutex_init(&my_obj->evt_lock, NULL);
298     pthread_cond_init(&my_obj->evt_cond, NULL);
299 
300     CDBG("%s : Launch evt Thread in Cam Open",__func__);
301     mm_camera_cmd_thread_launch(&my_obj->evt_thread,
302                                 mm_camera_dispatch_app_event,
303                                 (void *)my_obj);
304 
305     /* launch event poll thread
306      * we will add evt fd into event poll thread upon user first register for evt */
307     CDBG("%s : Launch evt Poll Thread in Cam Open", __func__);
308     mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
309                                  MM_CAMERA_POLL_TYPE_EVT);
310     mm_camera_evt_sub(my_obj, TRUE);
311 
312     CDBG("%s:  end (rc = %d)\n", __func__, rc);
313     /* we do not need to unlock cam_lock here before return
314      * because for open, it's done within intf_lock */
315     return rc;
316 
317 on_error:
318     if (my_obj->ctrl_fd > 0) {
319         close(my_obj->ctrl_fd);
320         my_obj->ctrl_fd = 0;
321     }
322     if (my_obj->ds_fd > 0) {
323         mm_camera_socket_close(my_obj->ds_fd);
324        my_obj->ds_fd = 0;
325     }
326 
327     /* we do not need to unlock cam_lock here before return
328      * because for open, it's done within intf_lock */
329     return rc;
330 }
331 
332 /*===========================================================================
333  * FUNCTION   : mm_camera_close
334  *
335  * DESCRIPTION: enqueue received event into event queue to be processed by
336  *              event thread.
337  *
338  * PARAMETERS :
339  *   @my_obj   : ptr to a camera object
340  *   @event    : event to be queued
341  *
342  * RETURN     : int32_t type of status
343  *              0  -- success
344  *              -1 -- failure
345  *==========================================================================*/
mm_camera_close(mm_camera_obj_t * my_obj)346 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
347 {
348     CDBG("%s : unsubscribe evt", __func__);
349     mm_camera_evt_sub(my_obj, FALSE);
350 
351     CDBG("%s : Close evt Poll Thread in Cam Close",__func__);
352     mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
353 
354     CDBG("%s : Close evt cmd Thread in Cam Close",__func__);
355     mm_camera_cmd_thread_release(&my_obj->evt_thread);
356 
357     if(my_obj->ctrl_fd > 0) {
358         close(my_obj->ctrl_fd);
359         my_obj->ctrl_fd = 0;
360     }
361     if(my_obj->ds_fd > 0) {
362         mm_camera_socket_close(my_obj->ds_fd);
363         my_obj->ds_fd = 0;
364     }
365     pthread_mutex_destroy(&my_obj->msg_lock);
366 
367     pthread_mutex_destroy(&my_obj->cb_lock);
368     pthread_mutex_destroy(&my_obj->evt_lock);
369     pthread_cond_destroy(&my_obj->evt_cond);
370 
371     pthread_mutex_unlock(&my_obj->cam_lock);
372     return 0;
373 }
374 
375 /*===========================================================================
376  * FUNCTION   : mm_camera_register_event_notify_internal
377  *
378  * DESCRIPTION: internal implementation for registering callback for event notify.
379  *
380  * PARAMETERS :
381  *   @my_obj   : ptr to a camera object
382  *   @evt_cb   : callback to be registered to handle event notify
383  *   @user_data: user data ptr
384  *
385  * RETURN     : int32_t type of status
386  *              0  -- success
387  *              -1 -- failure
388  *==========================================================================*/
mm_camera_register_event_notify_internal(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)389 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
390                                                  mm_camera_event_notify_t evt_cb,
391                                                  void * user_data)
392 {
393     int i;
394     int rc = -1;
395     mm_camera_evt_obj_t *evt_array = NULL;
396 
397     pthread_mutex_lock(&my_obj->cb_lock);
398     evt_array = &my_obj->evt;
399     if(evt_cb) {
400         /* this is reg case */
401         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
402             if(evt_array->evt[i].user_data == NULL) {
403                 evt_array->evt[i].evt_cb = evt_cb;
404                 evt_array->evt[i].user_data = user_data;
405                 evt_array->reg_count++;
406                 rc = 0;
407                 break;
408             }
409         }
410     } else {
411         /* this is unreg case */
412         for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
413             if(evt_array->evt[i].user_data == user_data) {
414                 evt_array->evt[i].evt_cb = NULL;
415                 evt_array->evt[i].user_data = NULL;
416                 evt_array->reg_count--;
417                 rc = 0;
418                 break;
419             }
420         }
421     }
422 
423     pthread_mutex_unlock(&my_obj->cb_lock);
424     return rc;
425 }
426 
427 /*===========================================================================
428  * FUNCTION   : mm_camera_register_event_notify
429  *
430  * DESCRIPTION: registering a callback for event notify.
431  *
432  * PARAMETERS :
433  *   @my_obj   : ptr to a camera object
434  *   @evt_cb   : callback to be registered to handle event notify
435  *   @user_data: user data ptr
436  *
437  * RETURN     : int32_t type of status
438  *              0  -- success
439  *              -1 -- failure
440  *==========================================================================*/
mm_camera_register_event_notify(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)441 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
442                                         mm_camera_event_notify_t evt_cb,
443                                         void * user_data)
444 {
445     int rc = -1;
446     rc = mm_camera_register_event_notify_internal(my_obj,
447                                                   evt_cb,
448                                                   user_data);
449     pthread_mutex_unlock(&my_obj->cam_lock);
450     return rc;
451 }
452 
453 /*===========================================================================
454  * FUNCTION   : mm_camera_qbuf
455  *
456  * DESCRIPTION: enqueue buffer back to kernel
457  *
458  * PARAMETERS :
459  *   @my_obj       : camera object
460  *   @ch_id        : channel handle
461  *   @buf          : buf ptr to be enqueued
462  *
463  * RETURN     : int32_t type of status
464  *              0  -- success
465  *              -1 -- failure
466  *==========================================================================*/
mm_camera_qbuf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_buf_def_t * buf)467 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
468                        uint32_t ch_id,
469                        mm_camera_buf_def_t *buf)
470 {
471     int rc = -1;
472     mm_channel_t * ch_obj = NULL;
473     ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
474 
475     pthread_mutex_unlock(&my_obj->cam_lock);
476 
477     /* we always assume qbuf will be done before channel/stream is fully stopped
478      * because qbuf is done within dataCB context
479      * in order to avoid deadlock, we are not locking ch_lock for qbuf */
480     if (NULL != ch_obj) {
481         rc = mm_channel_qbuf(ch_obj, buf);
482     }
483 
484     return rc;
485 }
486 
487 /*===========================================================================
488  * FUNCTION   : mm_camera_query_capability
489  *
490  * DESCRIPTION: query camera capability
491  *
492  * PARAMETERS :
493  *   @my_obj: camera object
494  *
495  * RETURN     : int32_t type of status
496  *              0  -- success
497  *              -1 -- failure
498  *==========================================================================*/
mm_camera_query_capability(mm_camera_obj_t * my_obj)499 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
500 {
501     int32_t rc = 0;
502     struct v4l2_capability cap;
503 
504     /* get camera capabilities */
505     memset(&cap, 0, sizeof(cap));
506     rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
507     if (rc != 0) {
508         CDBG_ERROR("%s: cannot get camera capabilities, rc = %d\n", __func__, rc);
509     }
510 
511     pthread_mutex_unlock(&my_obj->cam_lock);
512     return rc;
513 
514 }
515 
516 /*===========================================================================
517  * FUNCTION   : mm_camera_set_parms
518  *
519  * DESCRIPTION: set parameters per camera
520  *
521  * PARAMETERS :
522  *   @my_obj       : camera object
523  *   @parms        : ptr to a param struct to be set to server
524  *
525  * RETURN     : int32_t type of status
526  *              0  -- success
527  *              -1 -- failure
528  * NOTE       : Assume the parms struct buf is already mapped to server via
529  *              domain socket. Corresponding fields of parameters to be set
530  *              are already filled in by upper layer caller.
531  *==========================================================================*/
mm_camera_set_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)532 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj,
533                             parm_buffer_t *parms)
534 {
535     int32_t rc = -1;
536     int32_t value = 0;
537     if (parms !=  NULL) {
538         rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
539     }
540     pthread_mutex_unlock(&my_obj->cam_lock);
541     return rc;
542 }
543 
544 /*===========================================================================
545  * FUNCTION   : mm_camera_get_parms
546  *
547  * DESCRIPTION: get parameters per camera
548  *
549  * PARAMETERS :
550  *   @my_obj       : camera object
551  *   @parms        : ptr to a param struct to be get from server
552  *
553  * RETURN     : int32_t type of status
554  *              0  -- success
555  *              -1 -- failure
556  * NOTE       : Assume the parms struct buf is already mapped to server via
557  *              domain socket. Parameters to be get from server are already
558  *              filled in by upper layer caller. After this call, corresponding
559  *              fields of requested parameters will be filled in by server with
560  *              detailed information.
561  *==========================================================================*/
mm_camera_get_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)562 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
563                             parm_buffer_t *parms)
564 {
565     int32_t rc = -1;
566     int32_t value = 0;
567     if (parms != NULL) {
568         rc = mm_camera_util_g_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
569     }
570     pthread_mutex_unlock(&my_obj->cam_lock);
571     return rc;
572 }
573 
574 /*===========================================================================
575  * FUNCTION   : mm_camera_do_auto_focus
576  *
577  * DESCRIPTION: performing auto focus
578  *
579  * PARAMETERS :
580  *   @camera_handle: camera handle
581  *
582  * RETURN     : int32_t type of status
583  *              0  -- success
584  *              -1 -- failure
585  * NOTE       : if this call success, we will always assume there will
586  *              be an auto_focus event following up.
587  *==========================================================================*/
mm_camera_do_auto_focus(mm_camera_obj_t * my_obj)588 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
589 {
590     int32_t rc = -1;
591     int32_t value = 0;
592     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
593     pthread_mutex_unlock(&my_obj->cam_lock);
594     return rc;
595 }
596 
597 /*===========================================================================
598  * FUNCTION   : mm_camera_cancel_auto_focus
599  *
600  * DESCRIPTION: cancel auto focus
601  *
602  * PARAMETERS :
603  *   @camera_handle: camera handle
604  *
605  * RETURN     : int32_t type of status
606  *              0  -- success
607  *              -1 -- failure
608  *==========================================================================*/
mm_camera_cancel_auto_focus(mm_camera_obj_t * my_obj)609 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
610 {
611     int32_t rc = -1;
612     int32_t value = 0;
613     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
614     pthread_mutex_unlock(&my_obj->cam_lock);
615     return rc;
616 }
617 
618 /*===========================================================================
619  * FUNCTION   : mm_camera_prepare_snapshot
620  *
621  * DESCRIPTION: prepare hardware for snapshot
622  *
623  * PARAMETERS :
624  *   @my_obj       : camera object
625  *   @do_af_flag   : flag indicating if AF is needed
626  *
627  * RETURN     : int32_t type of status
628  *              0  -- success
629  *              -1 -- failure
630  *==========================================================================*/
mm_camera_prepare_snapshot(mm_camera_obj_t * my_obj,int32_t do_af_flag)631 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
632                                    int32_t do_af_flag)
633 {
634     int32_t rc = -1;
635     int32_t value = do_af_flag;
636     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
637     pthread_mutex_unlock(&my_obj->cam_lock);
638     return rc;
639 }
640 
641 /*===========================================================================
642  * FUNCTION   : mm_camera_start_zsl_snapshot
643  *
644  * DESCRIPTION: start zsl snapshot
645  *
646  * PARAMETERS :
647  *   @my_obj       : camera object
648  *
649  * RETURN     : int32_t type of status
650  *              0  -- success
651  *              -1 -- failure
652  *==========================================================================*/
mm_camera_start_zsl_snapshot(mm_camera_obj_t * my_obj)653 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
654 {
655     int32_t rc = -1;
656     int32_t value = 0;
657 
658     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
659              CAM_PRIV_START_ZSL_SNAPSHOT, &value);
660 
661     pthread_mutex_unlock(&my_obj->cam_lock);
662     return rc;
663 }
664 
665 /*===========================================================================
666  * FUNCTION   : mm_camera_stop_zsl_snapshot
667  *
668  * DESCRIPTION: stop zsl capture
669  *
670  * PARAMETERS :
671  *   @my_obj       : camera object
672  *
673  * RETURN     : int32_t type of status
674  *              0  -- success
675  *              -1 -- failure
676  *==========================================================================*/
mm_camera_stop_zsl_snapshot(mm_camera_obj_t * my_obj)677 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
678 {
679     int32_t rc = -1;
680     int32_t value;
681     rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
682              CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
683     pthread_mutex_unlock(&my_obj->cam_lock);
684     return rc;
685 }
686 
687 /*===========================================================================
688  * FUNCTION   : mm_camera_add_channel
689  *
690  * DESCRIPTION: add a channel
691  *
692  * PARAMETERS :
693  *   @my_obj       : camera object
694  *   @attr         : bundle attribute of the channel if needed
695  *   @channel_cb   : callback function for bundle data notify
696  *   @userdata     : user data ptr
697  *
698  * RETURN     : uint32_t type of channel handle
699  *              0  -- invalid channel handle, meaning the op failed
700  *              >0 -- successfully added a channel with a valid handle
701  * NOTE       : if no bundle data notify is needed, meaning each stream in the
702  *              channel will have its own stream data notify callback, then
703  *              attr, channel_cb, and userdata can be NULL. In this case,
704  *              no matching logic will be performed in channel for the bundling.
705  *==========================================================================*/
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)706 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
707                                mm_camera_channel_attr_t *attr,
708                                mm_camera_buf_notify_t channel_cb,
709                                void *userdata)
710 {
711     mm_channel_t *ch_obj = NULL;
712     uint8_t ch_idx = 0;
713     uint32_t ch_hdl = 0;
714 
715     for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
716         if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
717             ch_obj = &my_obj->ch[ch_idx];
718             break;
719         }
720     }
721 
722     if (NULL != ch_obj) {
723         /* initialize channel obj */
724         memset(ch_obj, 0, sizeof(mm_channel_t));
725         ch_hdl = mm_camera_util_generate_handler(ch_idx);
726         ch_obj->my_hdl = ch_hdl;
727         ch_obj->state = MM_CHANNEL_STATE_STOPPED;
728         ch_obj->cam_obj = my_obj;
729         pthread_mutex_init(&ch_obj->ch_lock, NULL);
730         mm_channel_init(ch_obj, attr, channel_cb, userdata);
731     }
732 
733     pthread_mutex_unlock(&my_obj->cam_lock);
734 
735     return ch_hdl;
736 }
737 
738 /*===========================================================================
739  * FUNCTION   : mm_camera_del_channel
740  *
741  * DESCRIPTION: delete a channel by its handle
742  *
743  * PARAMETERS :
744  *   @my_obj       : camera object
745  *   @ch_id        : channel handle
746  *
747  * RETURN     : int32_t type of status
748  *              0  -- success
749  *              -1 -- failure
750  * NOTE       : all streams in the channel should be stopped already before
751  *              this channel can be deleted.
752  *==========================================================================*/
mm_camera_del_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)753 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
754                               uint32_t ch_id)
755 {
756     int32_t rc = -1;
757     mm_channel_t * ch_obj =
758         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
759 
760     if (NULL != ch_obj) {
761         pthread_mutex_lock(&ch_obj->ch_lock);
762         pthread_mutex_unlock(&my_obj->cam_lock);
763 
764         rc = mm_channel_fsm_fn(ch_obj,
765                                MM_CHANNEL_EVT_DELETE,
766                                NULL,
767                                NULL);
768 
769         pthread_mutex_destroy(&ch_obj->ch_lock);
770         memset(ch_obj, 0, sizeof(mm_channel_t));
771     } else {
772         pthread_mutex_unlock(&my_obj->cam_lock);
773     }
774     return rc;
775 }
776 
777 /*===========================================================================
778  * FUNCTION   : mm_camera_get_bundle_info
779  *
780  * DESCRIPTION: query bundle info of the channel
781  *
782  * PARAMETERS :
783  *   @my_obj       : camera object
784  *   @ch_id        : channel handle
785  *   @bundle_info  : bundle info to be filled in
786  *
787  * RETURN     : int32_t type of status
788  *              0  -- success
789  *              -1 -- failure
790  * NOTE       : all streams in the channel should be stopped already before
791  *              this channel can be deleted.
792  *==========================================================================*/
mm_camera_get_bundle_info(mm_camera_obj_t * my_obj,uint32_t ch_id,cam_bundle_config_t * bundle_info)793 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
794                                   uint32_t ch_id,
795                                   cam_bundle_config_t *bundle_info)
796 {
797     int32_t rc = -1;
798     mm_channel_t * ch_obj =
799         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
800 
801     if (NULL != ch_obj) {
802         pthread_mutex_lock(&ch_obj->ch_lock);
803         pthread_mutex_unlock(&my_obj->cam_lock);
804 
805         rc = mm_channel_fsm_fn(ch_obj,
806                                MM_CHANNEL_EVT_GET_BUNDLE_INFO,
807                                (void *)bundle_info,
808                                NULL);
809     } else {
810         pthread_mutex_unlock(&my_obj->cam_lock);
811     }
812     return rc;
813 }
814 
815 /*===========================================================================
816  * FUNCTION   : mm_camera_add_stream
817  *
818  * DESCRIPTION: add a stream into a channel
819  *
820  * PARAMETERS :
821  *   @my_obj       : camera object
822  *   @ch_id        : channel handle
823  *
824  * RETURN     : uint32_t type of stream handle
825  *              0  -- invalid stream handle, meaning the op failed
826  *              >0 -- successfully added a stream with a valid handle
827  *==========================================================================*/
mm_camera_add_stream(mm_camera_obj_t * my_obj,uint32_t ch_id)828 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
829                               uint32_t ch_id)
830 {
831     uint32_t s_hdl = 0;
832     mm_channel_t * ch_obj =
833         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
834 
835     if (NULL != ch_obj) {
836         pthread_mutex_lock(&ch_obj->ch_lock);
837         pthread_mutex_unlock(&my_obj->cam_lock);
838 
839         mm_channel_fsm_fn(ch_obj,
840                           MM_CHANNEL_EVT_ADD_STREAM,
841                           NULL,
842                           (void*)&s_hdl);
843     } else {
844         pthread_mutex_unlock(&my_obj->cam_lock);
845     }
846 
847     return s_hdl;
848 }
849 
850 /*===========================================================================
851  * FUNCTION   : mm_camera_del_stream
852  *
853  * DESCRIPTION: delete a stream by its handle
854  *
855  * PARAMETERS :
856  *   @my_obj       : camera object
857  *   @ch_id        : channel handle
858  *   @stream_id    : stream handle
859  *
860  * RETURN     : int32_t type of status
861  *              0  -- success
862  *              -1 -- failure
863  * NOTE       : stream should be stopped already before it can be deleted.
864  *==========================================================================*/
mm_camera_del_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)865 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
866                              uint32_t ch_id,
867                              uint32_t stream_id)
868 {
869     int32_t rc = -1;
870     mm_channel_t * ch_obj =
871         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
872 
873     if (NULL != ch_obj) {
874         pthread_mutex_lock(&ch_obj->ch_lock);
875         pthread_mutex_unlock(&my_obj->cam_lock);
876 
877         rc = mm_channel_fsm_fn(ch_obj,
878                                MM_CHANNEL_EVT_DEL_STREAM,
879                                (void*)stream_id,
880                                NULL);
881     } else {
882         pthread_mutex_unlock(&my_obj->cam_lock);
883     }
884 
885     return rc;
886 }
887 
888 /*===========================================================================
889  * FUNCTION   : mm_camera_config_stream
890  *
891  * DESCRIPTION: configure a stream
892  *
893  * PARAMETERS :
894  *   @my_obj       : camera object
895  *   @ch_id        : channel handle
896  *   @stream_id    : stream handle
897  *   @config       : stream configuration
898  *
899  * RETURN     : int32_t type of status
900  *              0  -- success
901  *              -1 -- failure
902  *==========================================================================*/
mm_camera_config_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)903 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
904                                 uint32_t ch_id,
905                                 uint32_t stream_id,
906                                 mm_camera_stream_config_t *config)
907 {
908     int32_t rc = -1;
909     mm_channel_t * ch_obj =
910         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
911     mm_evt_paylod_config_stream_t payload;
912 
913     if (NULL != ch_obj) {
914         pthread_mutex_lock(&ch_obj->ch_lock);
915         pthread_mutex_unlock(&my_obj->cam_lock);
916 
917         memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
918         payload.stream_id = stream_id;
919         payload.config = config;
920         rc = mm_channel_fsm_fn(ch_obj,
921                                MM_CHANNEL_EVT_CONFIG_STREAM,
922                                (void*)&payload,
923                                NULL);
924     } else {
925         pthread_mutex_unlock(&my_obj->cam_lock);
926     }
927 
928     return rc;
929 }
930 
931 /*===========================================================================
932  * FUNCTION   : mm_camera_start_channel
933  *
934  * DESCRIPTION: start a channel, which will start all streams in the channel
935  *
936  * PARAMETERS :
937  *   @my_obj       : camera object
938  *   @ch_id        : channel handle
939  *
940  * RETURN     : int32_t type of status
941  *              0  -- success
942  *              -1 -- failure
943  *==========================================================================*/
mm_camera_start_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)944 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj,
945                                 uint32_t ch_id)
946 {
947     int32_t rc = -1;
948     mm_channel_t * ch_obj =
949         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
950 
951     if (NULL != ch_obj) {
952         pthread_mutex_lock(&ch_obj->ch_lock);
953         pthread_mutex_unlock(&my_obj->cam_lock);
954 
955         rc = mm_channel_fsm_fn(ch_obj,
956                                MM_CHANNEL_EVT_START,
957                                NULL,
958                                NULL);
959     } else {
960         pthread_mutex_unlock(&my_obj->cam_lock);
961     }
962 
963     return rc;
964 }
965 
966 /*===========================================================================
967  * FUNCTION   : mm_camera_stop_channel
968  *
969  * DESCRIPTION: stop a channel, which will stop all streams in the channel
970  *
971  * PARAMETERS :
972  *   @my_obj       : camera object
973  *   @ch_id        : channel handle
974  *
975  * RETURN     : int32_t type of status
976  *              0  -- success
977  *              -1 -- failure
978  *==========================================================================*/
mm_camera_stop_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)979 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
980                                uint32_t ch_id)
981 {
982     int32_t rc = 0;
983     mm_channel_t * ch_obj =
984         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
985 
986     if (NULL != ch_obj) {
987         pthread_mutex_lock(&ch_obj->ch_lock);
988         pthread_mutex_unlock(&my_obj->cam_lock);
989 
990         rc = mm_channel_fsm_fn(ch_obj,
991                                MM_CHANNEL_EVT_STOP,
992                                NULL,
993                                NULL);
994     } else {
995         pthread_mutex_unlock(&my_obj->cam_lock);
996     }
997     return rc;
998 }
999 
1000 /*===========================================================================
1001  * FUNCTION   : mm_camera_request_super_buf
1002  *
1003  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1004  *              frames from superbuf queue
1005  *
1006  * PARAMETERS :
1007  *   @my_obj       : camera object
1008  *   @ch_id        : channel handle
1009  *   @num_buf_requested : number of matched frames needed
1010  *
1011  * RETURN     : int32_t type of status
1012  *              0  -- success
1013  *              -1 -- failure
1014  *==========================================================================*/
mm_camera_request_super_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t num_buf_requested)1015 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1016                                     uint32_t ch_id,
1017                                     uint32_t num_buf_requested)
1018 {
1019     int32_t rc = -1;
1020     mm_channel_t * ch_obj =
1021         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1022 
1023     if (NULL != ch_obj) {
1024         pthread_mutex_lock(&ch_obj->ch_lock);
1025         pthread_mutex_unlock(&my_obj->cam_lock);
1026 
1027         rc = mm_channel_fsm_fn(ch_obj,
1028                                MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
1029                                (void*)num_buf_requested,
1030                                NULL);
1031     } else {
1032         pthread_mutex_unlock(&my_obj->cam_lock);
1033     }
1034 
1035     return rc;
1036 }
1037 
1038 /*===========================================================================
1039  * FUNCTION   : mm_camera_cancel_super_buf_request
1040  *
1041  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
1042  *              of matched frames from superbuf queue
1043  *
1044  * PARAMETERS :
1045  *   @my_obj       : camera object
1046  *   @ch_id        : channel handle
1047  *
1048  * RETURN     : int32_t type of status
1049  *              0  -- success
1050  *              -1 -- failure
1051  *==========================================================================*/
mm_camera_cancel_super_buf_request(mm_camera_obj_t * my_obj,uint32_t ch_id)1052 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
1053 {
1054     int32_t rc = -1;
1055     mm_channel_t * ch_obj =
1056         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1057 
1058     if (NULL != ch_obj) {
1059         pthread_mutex_lock(&ch_obj->ch_lock);
1060         pthread_mutex_unlock(&my_obj->cam_lock);
1061 
1062         rc = mm_channel_fsm_fn(ch_obj,
1063                                MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
1064                                NULL,
1065                                NULL);
1066     } else {
1067         pthread_mutex_unlock(&my_obj->cam_lock);
1068     }
1069 
1070     return rc;
1071 }
1072 
1073 /*===========================================================================
1074  * FUNCTION   : mm_camera_flush_super_buf_queue
1075  *
1076  * DESCRIPTION: flush out all frames in the superbuf queue
1077  *
1078  * PARAMETERS :
1079  *   @my_obj       : camera object
1080  *   @ch_id        : channel handle
1081  *
1082  * RETURN     : int32_t type of status
1083  *              0  -- success
1084  *              -1 -- failure
1085  *==========================================================================*/
mm_camera_flush_super_buf_queue(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t frame_idx)1086 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
1087                                                              uint32_t frame_idx)
1088 {
1089     int32_t rc = -1;
1090     mm_channel_t * ch_obj =
1091         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1092 
1093     if (NULL != ch_obj) {
1094         pthread_mutex_lock(&ch_obj->ch_lock);
1095         pthread_mutex_unlock(&my_obj->cam_lock);
1096 
1097         rc = mm_channel_fsm_fn(ch_obj,
1098                                MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
1099                                (void *)frame_idx,
1100                                NULL);
1101     } else {
1102         pthread_mutex_unlock(&my_obj->cam_lock);
1103     }
1104 
1105     return rc;
1106 }
1107 
1108 /*===========================================================================
1109  * FUNCTION   : mm_camera_config_channel_notify
1110  *
1111  * DESCRIPTION: configures the channel notification mode
1112  *
1113  * PARAMETERS :
1114  *   @my_obj       : camera object
1115  *   @ch_id        : channel handle
1116  *   @notify_mode  : notification mode
1117  *
1118  * RETURN     : int32_t type of status
1119  *              0  -- success
1120  *              -1 -- failure
1121  *==========================================================================*/
mm_camera_config_channel_notify(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)1122 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
1123                                         uint32_t ch_id,
1124                                         mm_camera_super_buf_notify_mode_t notify_mode)
1125 {
1126     int32_t rc = -1;
1127     mm_channel_t * ch_obj =
1128         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1129 
1130     if (NULL != ch_obj) {
1131         pthread_mutex_lock(&ch_obj->ch_lock);
1132         pthread_mutex_unlock(&my_obj->cam_lock);
1133 
1134         rc = mm_channel_fsm_fn(ch_obj,
1135                                MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
1136                                (void *)notify_mode,
1137                                NULL);
1138     } else {
1139         pthread_mutex_unlock(&my_obj->cam_lock);
1140     }
1141 
1142     return rc;
1143 }
1144 
1145 /*===========================================================================
1146  * FUNCTION   : mm_camera_set_stream_parms
1147  *
1148  * DESCRIPTION: set parameters per stream
1149  *
1150  * PARAMETERS :
1151  *   @my_obj       : camera object
1152  *   @ch_id        : channel handle
1153  *   @s_id         : stream handle
1154  *   @parms        : ptr to a param struct to be set to server
1155  *
1156  * RETURN     : int32_t type of status
1157  *              0  -- success
1158  *              -1 -- failure
1159  * NOTE       : Assume the parms struct buf is already mapped to server via
1160  *              domain socket. Corresponding fields of parameters to be set
1161  *              are already filled in by upper layer caller.
1162  *==========================================================================*/
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)1163 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
1164                                    uint32_t ch_id,
1165                                    uint32_t s_id,
1166                                    cam_stream_parm_buffer_t *parms)
1167 {
1168     int32_t rc = -1;
1169     mm_evt_paylod_set_get_stream_parms_t payload;
1170     mm_channel_t * ch_obj =
1171         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1172 
1173     if (NULL != ch_obj) {
1174         pthread_mutex_lock(&ch_obj->ch_lock);
1175         pthread_mutex_unlock(&my_obj->cam_lock);
1176 
1177         memset(&payload, 0, sizeof(payload));
1178         payload.stream_id = s_id;
1179         payload.parms = parms;
1180 
1181         rc = mm_channel_fsm_fn(ch_obj,
1182                                MM_CHANNEL_EVT_SET_STREAM_PARM,
1183                                (void *)&payload,
1184                                NULL);
1185     } else {
1186         pthread_mutex_unlock(&my_obj->cam_lock);
1187     }
1188 
1189     return rc;
1190 }
1191 
1192 /*===========================================================================
1193  * FUNCTION   : mm_camera_get_stream_parms
1194  *
1195  * DESCRIPTION: get parameters per stream
1196  *
1197  * PARAMETERS :
1198  *   @my_obj       : camera object
1199  *   @ch_id        : channel handle
1200  *   @s_id         : stream handle
1201  *   @parms        : ptr to a param struct to be get from server
1202  *
1203  * RETURN     : int32_t type of status
1204  *              0  -- success
1205  *              -1 -- failure
1206  * NOTE       : Assume the parms struct buf is already mapped to server via
1207  *              domain socket. Parameters to be get from server are already
1208  *              filled in by upper layer caller. After this call, corresponding
1209  *              fields of requested parameters will be filled in by server with
1210  *              detailed information.
1211  *==========================================================================*/
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)1212 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
1213                                    uint32_t ch_id,
1214                                    uint32_t s_id,
1215                                    cam_stream_parm_buffer_t *parms)
1216 {
1217     int32_t rc = -1;
1218     mm_evt_paylod_set_get_stream_parms_t payload;
1219     mm_channel_t * ch_obj =
1220         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1221 
1222     if (NULL != ch_obj) {
1223         pthread_mutex_lock(&ch_obj->ch_lock);
1224         pthread_mutex_unlock(&my_obj->cam_lock);
1225 
1226         memset(&payload, 0, sizeof(payload));
1227         payload.stream_id = s_id;
1228         payload.parms = parms;
1229 
1230         rc = mm_channel_fsm_fn(ch_obj,
1231                                MM_CHANNEL_EVT_GET_STREAM_PARM,
1232                                (void *)&payload,
1233                                NULL);
1234     } else {
1235         pthread_mutex_unlock(&my_obj->cam_lock);
1236     }
1237 
1238     return rc;
1239 }
1240 
1241 /*===========================================================================
1242  * FUNCTION   : mm_camera_do_stream_action
1243  *
1244  * DESCRIPTION: request server to perform stream based action. Maybe removed later
1245  *              if the functionality is included in mm_camera_set_parms
1246  *
1247  * PARAMETERS :
1248  *   @my_obj       : camera object
1249  *   @ch_id        : channel handle
1250  *   @s_id         : stream handle
1251  *   @actions      : ptr to an action struct buf to be performed by server
1252  *
1253  * RETURN     : int32_t type of status
1254  *              0  -- success
1255  *              -1 -- failure
1256  * NOTE       : Assume the action struct buf is already mapped to server via
1257  *              domain socket. Actions to be performed by server are already
1258  *              filled in by upper layer caller.
1259  *==========================================================================*/
mm_camera_do_stream_action(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,void * actions)1260 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
1261                                    uint32_t ch_id,
1262                                    uint32_t stream_id,
1263                                    void *actions)
1264 {
1265     int32_t rc = -1;
1266     mm_evt_paylod_do_stream_action_t payload;
1267     mm_channel_t * ch_obj =
1268         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1269 
1270     if (NULL != ch_obj) {
1271         pthread_mutex_lock(&ch_obj->ch_lock);
1272         pthread_mutex_unlock(&my_obj->cam_lock);
1273 
1274         memset(&payload, 0, sizeof(payload));
1275         payload.stream_id = stream_id;
1276         payload.actions = actions;
1277 
1278         rc = mm_channel_fsm_fn(ch_obj,
1279                                MM_CHANNEL_EVT_DO_STREAM_ACTION,
1280                                (void*)&payload,
1281                                NULL);
1282     } else {
1283         pthread_mutex_unlock(&my_obj->cam_lock);
1284     }
1285 
1286     return rc;
1287 }
1288 
1289 /*===========================================================================
1290  * FUNCTION   : mm_camera_map_stream_buf
1291  *
1292  * DESCRIPTION: mapping stream buffer via domain socket to server
1293  *
1294  * PARAMETERS :
1295  *   @my_obj       : camera object
1296  *   @ch_id        : channel handle
1297  *   @s_id         : stream handle
1298  *   @buf_type     : type of buffer to be mapped. could be following values:
1299  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1300  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1301  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1302  *   @buf_idx      : index of buffer within the stream buffers, only valid if
1303  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1304  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1305  *   @plane_idx    : plane index. If all planes share the same fd,
1306  *                   plane_idx = -1; otherwise, plean_idx is the
1307  *                   index to plane (0..num_of_planes)
1308  *   @fd           : file descriptor of the buffer
1309  *   @size         : size of the buffer
1310  *
1311  * RETURN     : int32_t type of status
1312  *              0  -- success
1313  *              -1 -- failure
1314  *==========================================================================*/
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,uint32_t size)1315 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
1316                                  uint32_t ch_id,
1317                                  uint32_t stream_id,
1318                                  uint8_t buf_type,
1319                                  uint32_t buf_idx,
1320                                  int32_t plane_idx,
1321                                  int fd,
1322                                  uint32_t size)
1323 {
1324     int32_t rc = -1;
1325     mm_evt_paylod_map_stream_buf_t payload;
1326     mm_channel_t * ch_obj =
1327         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1328 
1329     if (NULL != ch_obj) {
1330         pthread_mutex_lock(&ch_obj->ch_lock);
1331         pthread_mutex_unlock(&my_obj->cam_lock);
1332 
1333         memset(&payload, 0, sizeof(payload));
1334         payload.stream_id = stream_id;
1335         payload.buf_type = buf_type;
1336         payload.buf_idx = buf_idx;
1337         payload.plane_idx = plane_idx;
1338         payload.fd = fd;
1339         payload.size = size;
1340         rc = mm_channel_fsm_fn(ch_obj,
1341                                MM_CHANNEL_EVT_MAP_STREAM_BUF,
1342                                (void*)&payload,
1343                                NULL);
1344     } else {
1345         pthread_mutex_unlock(&my_obj->cam_lock);
1346     }
1347 
1348     return rc;
1349 }
1350 
1351 /*===========================================================================
1352  * FUNCTION   : mm_camera_unmap_stream_buf
1353  *
1354  * DESCRIPTION: unmapping stream buffer via domain socket to server
1355  *
1356  * PARAMETERS :
1357  *   @my_obj       : camera object
1358  *   @ch_id        : channel handle
1359  *   @s_id         : stream handle
1360  *   @buf_type     : type of buffer to be mapped. could be following values:
1361  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1362  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1363  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1364  *   @buf_idx      : index of buffer within the stream buffers, only valid if
1365  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1366  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1367  *   @plane_idx    : plane index. If all planes share the same fd,
1368  *                   plane_idx = -1; otherwise, plean_idx is the
1369  *                   index to plane (0..num_of_planes)
1370  *
1371  * RETURN     : int32_t type of status
1372  *              0  -- success
1373  *              -1 -- failure
1374  *==========================================================================*/
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)1375 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
1376                                    uint32_t ch_id,
1377                                    uint32_t stream_id,
1378                                    uint8_t buf_type,
1379                                    uint32_t buf_idx,
1380                                    int32_t plane_idx)
1381 {
1382     int32_t rc = -1;
1383     mm_evt_paylod_unmap_stream_buf_t payload;
1384     mm_channel_t * ch_obj =
1385         mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1386 
1387     if (NULL != ch_obj) {
1388         pthread_mutex_lock(&ch_obj->ch_lock);
1389         pthread_mutex_unlock(&my_obj->cam_lock);
1390 
1391         memset(&payload, 0, sizeof(payload));
1392         payload.stream_id = stream_id;
1393         payload.buf_type = buf_type;
1394         payload.buf_idx = buf_idx;
1395         payload.plane_idx = plane_idx;
1396         rc = mm_channel_fsm_fn(ch_obj,
1397                                MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
1398                                (void*)&payload,
1399                                NULL);
1400     } else {
1401         pthread_mutex_unlock(&my_obj->cam_lock);
1402     }
1403 
1404     return rc;
1405 }
1406 
1407 /*===========================================================================
1408  * FUNCTION   : mm_camera_evt_sub
1409  *
1410  * DESCRIPTION: subscribe/unsubscribe event notify from kernel
1411  *
1412  * PARAMETERS :
1413  *   @my_obj       : camera object
1414  *   @reg_flag     : 1 -- subscribe ; 0 -- unsubscribe
1415  *
1416  * RETURN     : int32_t type of status
1417  *              0  -- success
1418  *              -1 -- failure
1419  *==========================================================================*/
mm_camera_evt_sub(mm_camera_obj_t * my_obj,uint8_t reg_flag)1420 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1421                           uint8_t reg_flag)
1422 {
1423     int32_t rc = 0;
1424     struct v4l2_event_subscription sub;
1425 
1426     memset(&sub, 0, sizeof(sub));
1427     sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
1428     sub.id = MSM_CAMERA_MSM_NOTIFY;
1429     if(FALSE == reg_flag) {
1430         /* unsubscribe */
1431         rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1432         if (rc < 0) {
1433             CDBG_ERROR("%s: unsubscribe event rc = %d", __func__, rc);
1434             return rc;
1435         }
1436         /* remove evt fd from the polling thraed when unreg the last event */
1437         rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
1438                                                my_obj->my_hdl,
1439                                                mm_camera_sync_call);
1440     } else {
1441         rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1442         if (rc < 0) {
1443             CDBG_ERROR("%s: subscribe event rc = %d", __func__, rc);
1444             return rc;
1445         }
1446         /* add evt fd to polling thread when subscribe the first event */
1447         rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1448                                                my_obj->my_hdl,
1449                                                my_obj->ctrl_fd,
1450                                                mm_camera_event_notify,
1451                                                (void*)my_obj,
1452                                                mm_camera_sync_call);
1453     }
1454     return rc;
1455 }
1456 
1457 /*===========================================================================
1458  * FUNCTION   : mm_camera_util_wait_for_event
1459  *
1460  * DESCRIPTION: utility function to wait for certain events
1461  *
1462  * PARAMETERS :
1463  *   @my_obj       : camera object
1464  *   @evt_mask     : mask for events to be waited. Any of event in the mask would
1465  *                   trigger the wait to end
1466  *   @status       : status of the event
1467  *
1468  * RETURN     : none
1469  *==========================================================================*/
mm_camera_util_wait_for_event(mm_camera_obj_t * my_obj,uint32_t evt_mask,int32_t * status)1470 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
1471                                    uint32_t evt_mask,
1472                                    int32_t *status)
1473 {
1474     pthread_mutex_lock(&my_obj->evt_lock);
1475     while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
1476         pthread_cond_wait(&my_obj->evt_cond, &my_obj->evt_lock);
1477     }
1478     *status = my_obj->evt_rcvd.status;
1479     /* reset local storage for recieved event for next event */
1480     memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
1481     pthread_mutex_unlock(&my_obj->evt_lock);
1482 }
1483 
1484 /*===========================================================================
1485  * FUNCTION   : mm_camera_util_sendmsg
1486  *
1487  * DESCRIPTION: utility function to send msg via domain socket
1488  *
1489  * PARAMETERS :
1490  *   @my_obj       : camera object
1491  *   @msg          : message to be sent
1492  *   @buf_size     : size of the message to be sent
1493  *   @sendfd       : >0 if any file descriptor need to be passed across process
1494  *
1495  * RETURN     : int32_t type of status
1496  *              0  -- success
1497  *              -1 -- failure
1498  *==========================================================================*/
mm_camera_util_sendmsg(mm_camera_obj_t * my_obj,void * msg,uint32_t buf_size,int sendfd)1499 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
1500                                void *msg,
1501                                uint32_t buf_size,
1502                                int sendfd)
1503 {
1504     int32_t rc = -1;
1505     int32_t status;
1506 
1507     /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
1508     pthread_mutex_lock(&my_obj->msg_lock);
1509     if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
1510         /* wait for event that mapping/unmapping is done */
1511         mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1512         if (MSM_CAMERA_STATUS_SUCCESS == status) {
1513             rc = 0;
1514         }
1515     }
1516     pthread_mutex_unlock(&my_obj->msg_lock);
1517     return rc;
1518 }
1519 
1520 /*===========================================================================
1521  * FUNCTION   : mm_camera_map_buf
1522  *
1523  * DESCRIPTION: mapping camera buffer via domain socket to server
1524  *
1525  * PARAMETERS :
1526  *   @my_obj       : camera object
1527  *   @buf_type     : type of buffer to be mapped. could be following values:
1528  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1529  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1530  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1531  *   @fd           : file descriptor of the buffer
1532  *   @size         : size of the buffer
1533  *
1534  * RETURN     : int32_t type of status
1535  *              0  -- success
1536  *              -1 -- failure
1537  *==========================================================================*/
mm_camera_map_buf(mm_camera_obj_t * my_obj,uint8_t buf_type,int fd,uint32_t size)1538 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1539                           uint8_t buf_type,
1540                           int fd,
1541                           uint32_t size)
1542 {
1543     int32_t rc = 0;
1544     cam_sock_packet_t packet;
1545     memset(&packet, 0, sizeof(cam_sock_packet_t));
1546     packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
1547     packet.payload.buf_map.type = buf_type;
1548     packet.payload.buf_map.fd = fd;
1549     packet.payload.buf_map.size = size;
1550     rc = mm_camera_util_sendmsg(my_obj,
1551                                 &packet,
1552                                 sizeof(cam_sock_packet_t),
1553                                 fd);
1554     pthread_mutex_unlock(&my_obj->cam_lock);
1555     return rc;
1556 }
1557 
1558 /*===========================================================================
1559  * FUNCTION   : mm_camera_unmap_buf
1560  *
1561  * DESCRIPTION: unmapping camera buffer via domain socket to server
1562  *
1563  * PARAMETERS :
1564  *   @my_obj       : camera object
1565  *   @buf_type     : type of buffer to be mapped. could be following values:
1566  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1567  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1568  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1569  *
1570  * RETURN     : int32_t type of status
1571  *              0  -- success
1572  *              -1 -- failure
1573  *==========================================================================*/
mm_camera_unmap_buf(mm_camera_obj_t * my_obj,uint8_t buf_type)1574 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
1575                             uint8_t buf_type)
1576 {
1577     int32_t rc = 0;
1578     cam_sock_packet_t packet;
1579     memset(&packet, 0, sizeof(cam_sock_packet_t));
1580     packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
1581     packet.payload.buf_unmap.type = buf_type;
1582     rc = mm_camera_util_sendmsg(my_obj,
1583                                 &packet,
1584                                 sizeof(cam_sock_packet_t),
1585                                 0);
1586     pthread_mutex_unlock(&my_obj->cam_lock);
1587     return rc;
1588 }
1589 
1590 /*===========================================================================
1591  * FUNCTION   : mm_camera_util_s_ctrl
1592  *
1593  * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
1594  *
1595  * PARAMETERS :
1596  *   @fd      : file descritpor for sending ioctl
1597  *   @id      : control id
1598  *   @value   : value of the ioctl to be sent
1599  *
1600  * RETURN     : int32_t type of status
1601  *              0  -- success
1602  *              -1 -- failure
1603  *==========================================================================*/
mm_camera_util_s_ctrl(int32_t fd,uint32_t id,int32_t * value)1604 int32_t mm_camera_util_s_ctrl(int32_t fd,  uint32_t id, int32_t *value)
1605 {
1606     int rc = 0;
1607     struct v4l2_control control;
1608 
1609     memset(&control, 0, sizeof(control));
1610     control.id = id;
1611     if (value != NULL) {
1612         control.value = *value;
1613     }
1614     rc = ioctl(fd, VIDIOC_S_CTRL, &control);
1615 
1616     CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
1617          __func__, fd, id, (uint32_t)value, rc);
1618     if (value != NULL) {
1619         *value = control.value;
1620     }
1621     return (rc >= 0)? 0 : -1;
1622 }
1623 
1624 /*===========================================================================
1625  * FUNCTION   : mm_camera_util_g_ctrl
1626  *
1627  * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
1628  *
1629  * PARAMETERS :
1630  *   @fd      : file descritpor for sending ioctl
1631  *   @id      : control id
1632  *   @value   : value of the ioctl to be sent
1633  *
1634  * RETURN     : int32_t type of status
1635  *              0  -- success
1636  *              -1 -- failure
1637  *==========================================================================*/
mm_camera_util_g_ctrl(int32_t fd,uint32_t id,int32_t * value)1638 int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
1639 {
1640     int rc = 0;
1641     struct v4l2_control control;
1642 
1643     memset(&control, 0, sizeof(control));
1644     control.id = id;
1645     if (value != NULL) {
1646         control.value = *value;
1647     }
1648     rc = ioctl(fd, VIDIOC_G_CTRL, &control);
1649     CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc);
1650     if (value != NULL) {
1651         *value = control.value;
1652     }
1653     return (rc >= 0)? 0 : -1;
1654 }
1655