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