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