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