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