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