1 /* Copyright (c) 2012-2016, 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 // To remove
31 #include <cutils/properties.h>
32
33 // System dependencies
34 #include <pthread.h>
35 #include <errno.h>
36 #include <fcntl.h>
37 #include <stdlib.h>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <unistd.h>
41 #include <dlfcn.h>
42 #define IOCTL_H <SYSTEM_HEADER_PREFIX/ioctl.h>
43 #include IOCTL_H
44
45 // Camera dependencies
46 #include "cam_semaphore.h"
47 #include "mm_camera_dbg.h"
48 #include "mm_camera_sock.h"
49 #include "mm_camera_interface.h"
50 #include "mm_camera.h"
51 #include "mm_camera_muxer.h"
52 #include "cam_cond.h"
53
54 #define SET_PARM_BIT32(parm, parm_arr) \
55 (parm_arr[parm/32] |= (1<<(parm%32)))
56
57 #define GET_PARM_BIT32(parm, parm_arr) \
58 ((parm_arr[parm/32]>>(parm%32))& 0x1)
59
60 /* internal function declare */
61 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
62 uint8_t reg_flag);
63 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
64 mm_camera_event_t *event);
65 extern mm_camera_obj_t* mm_camera_util_get_camera_by_session_id
66 (uint32_t session_id);
67
68 /*===========================================================================
69 * FUNCTION : mm_camera_util_get_channel_by_handler
70 *
71 * DESCRIPTION: utility function to get a channel object from its handle
72 *
73 * PARAMETERS :
74 * @cam_obj: ptr to a camera object
75 * @handler: channel handle
76 *
77 * RETURN : ptr to a channel object.
78 * NULL if failed.
79 *==========================================================================*/
mm_camera_util_get_channel_by_handler(mm_camera_obj_t * cam_obj,uint32_t handler)80 mm_channel_t * mm_camera_util_get_channel_by_handler(
81 mm_camera_obj_t * cam_obj,
82 uint32_t handler)
83 {
84 int i;
85 mm_channel_t *ch_obj = NULL;
86 for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
87 if (handler == cam_obj->ch[i].my_hdl) {
88 ch_obj = &cam_obj->ch[i];
89 break;
90 }
91 }
92 return ch_obj;
93 }
94
95 /*===========================================================================
96 * FUNCTION : mm_camera_util_chip_is_a_family
97 *
98 * DESCRIPTION: utility function to check if the host is A family chip
99 *
100 * PARAMETERS :
101 *
102 * RETURN : TRUE if A family.
103 * FALSE otherwise.
104 *==========================================================================*/
mm_camera_util_chip_is_a_family(void)105 uint8_t mm_camera_util_chip_is_a_family(void)
106 {
107 #ifdef USE_A_FAMILY
108 return TRUE;
109 #else
110 return FALSE;
111 #endif
112 }
113
114 /*===========================================================================
115 * FUNCTION : mm_camera_dispatch_app_event
116 *
117 * DESCRIPTION: dispatch event to apps who regitster for event notify
118 *
119 * PARAMETERS :
120 * @cmd_cb: ptr to a struct storing event info
121 * @user_data: user data ptr (camera object)
122 *
123 * RETURN : none
124 *==========================================================================*/
mm_camera_dispatch_app_event(mm_camera_cmdcb_t * cmd_cb,void * user_data)125 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
126 void* user_data)
127 {
128 int i;
129 mm_camera_event_t *event = &cmd_cb->u.evt;
130 mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data;
131 if (NULL != my_obj) {
132 mm_camera_cmd_thread_name(my_obj->evt_thread.threadName);
133 pthread_mutex_lock(&my_obj->cb_lock);
134 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
135 if(my_obj->evt.evt[i].evt_cb) {
136 my_obj->evt.evt[i].evt_cb(
137 my_obj->my_hdl,
138 event,
139 my_obj->evt.evt[i].user_data);
140 }
141 }
142 pthread_mutex_unlock(&my_obj->cb_lock);
143 }
144 }
145
146 /*===========================================================================
147 * FUNCTION : mm_camera_event_notify
148 *
149 * DESCRIPTION: callback to handle event notify from kernel. This call will
150 * dequeue event from kernel.
151 *
152 * PARAMETERS :
153 * @user_data: user data ptr (camera object)
154 *
155 * RETURN : none
156 *==========================================================================*/
mm_camera_event_notify(void * user_data)157 static void mm_camera_event_notify(void* user_data)
158 {
159 struct v4l2_event ev;
160 struct msm_v4l2_event_data *msm_evt = NULL;
161 int rc;
162 mm_camera_event_t evt;
163 memset(&evt, 0, sizeof(mm_camera_event_t));
164
165 mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
166 if (NULL != my_obj) {
167 /* read evt */
168 memset(&ev, 0, sizeof(ev));
169 rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
170
171 if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
172 msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
173 switch (msm_evt->command) {
174 case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
175 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ;
176 mm_camera_enqueue_evt(my_obj, &evt);
177 break;
178 case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
179 pthread_mutex_lock(&my_obj->evt_lock);
180 my_obj->evt_rcvd.server_event_type = msm_evt->command;
181 my_obj->evt_rcvd.status = msm_evt->status;
182 pthread_cond_signal(&my_obj->evt_cond);
183 pthread_mutex_unlock(&my_obj->evt_lock);
184 break;
185 case CAM_EVENT_TYPE_INT_TAKE_JPEG:
186 case CAM_EVENT_TYPE_INT_TAKE_RAW:
187 {
188 evt.server_event_type = msm_evt->command;
189 mm_camera_enqueue_evt(my_obj, &evt);
190 }
191 break;
192 case MSM_CAMERA_PRIV_SHUTDOWN:
193 {
194 LOGE("Camera Event DAEMON DIED received");
195 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
196 mm_camera_enqueue_evt(my_obj, &evt);
197 }
198 break;
199 case CAM_EVENT_TYPE_CAC_DONE:
200 {
201 evt.server_event_type = CAM_EVENT_TYPE_CAC_DONE;
202 mm_camera_enqueue_evt(my_obj, &evt);
203 }
204 break;
205 default:
206 break;
207 }
208 }
209 }
210 }
211
212 /*===========================================================================
213 * FUNCTION : mm_camera_enqueue_evt
214 *
215 * DESCRIPTION: enqueue received event into event queue to be processed by
216 * event thread.
217 *
218 * PARAMETERS :
219 * @my_obj : ptr to a camera object
220 * @event : event to be queued
221 *
222 * RETURN : int32_t type of status
223 * 0 -- success
224 * -1 -- failure
225 *==========================================================================*/
mm_camera_enqueue_evt(mm_camera_obj_t * my_obj,mm_camera_event_t * event)226 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
227 mm_camera_event_t *event)
228 {
229 int32_t rc = 0;
230 mm_camera_cmdcb_t *node = NULL;
231
232 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
233 if (NULL != node) {
234 memset(node, 0, sizeof(mm_camera_cmdcb_t));
235 node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
236 node->u.evt = *event;
237
238 /* enqueue to evt cmd thread */
239 cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
240 /* wake up evt cmd thread */
241 cam_sem_post(&(my_obj->evt_thread.cmd_sem));
242 } else {
243 LOGE("No memory for mm_camera_node_t");
244 rc = -1;
245 }
246
247 return rc;
248 }
249
250 /*===========================================================================
251 * FUNCTION : mm_camera_open
252 *
253 * DESCRIPTION: open a camera
254 *
255 * PARAMETERS :
256 * @my_obj : ptr to a camera object
257 *
258 * RETURN : int32_t type of status
259 * 0 -- success
260 * -1 -- failure
261 *==========================================================================*/
mm_camera_open(mm_camera_obj_t * my_obj)262 int32_t mm_camera_open(mm_camera_obj_t *my_obj)
263 {
264 char dev_name[MM_CAMERA_DEV_NAME_LEN];
265 int32_t rc = 0;
266 int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
267 uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
268 int cam_idx = 0;
269 const char *dev_name_value = NULL;
270 int l_errno = 0;
271
272 LOGD("begin\n");
273
274 if (NULL == my_obj) {
275 goto on_error;
276 }
277
278 dev_name_value = mm_camera_util_get_dev_name_by_num(my_obj->my_num,
279 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 LOGD("dev name = %s, cam_idx = %d", 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 l_errno = errno;
293 LOGD("ctrl_fd = %d, errno == %d", my_obj->ctrl_fd, l_errno);
294 if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) {
295 break;
296 }
297 LOGE("Failed with %s error, retrying after %d milli-seconds",
298 strerror(errno), sleep_msec);
299 usleep(sleep_msec * 1000U);
300 }while (n_try > 0);
301
302 if (my_obj->ctrl_fd < 0) {
303 LOGE("cannot open control fd of '%s' (%s)\n",
304 dev_name, strerror(l_errno));
305 if (l_errno == EBUSY)
306 rc = -EUSERS;
307 else
308 rc = -1;
309 goto on_error;
310 } else {
311 mm_camera_get_session_id(my_obj, &my_obj->sessionid);
312 LOGH("Camera Opened id = %d sessionid = %d", cam_idx, my_obj->sessionid);
313 }
314
315 #ifdef DAEMON_PRESENT
316 /* open domain socket*/
317 n_try = MM_CAMERA_DEV_OPEN_TRIES;
318 do {
319 n_try--;
320 my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
321 l_errno = errno;
322 LOGD("ds_fd = %d, errno = %d", my_obj->ds_fd, l_errno);
323 if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {
324 LOGD("opened, break out while loop");
325 break;
326 }
327 LOGD("failed with I/O error retrying after %d milli-seconds",
328 sleep_msec);
329 usleep(sleep_msec * 1000U);
330 } while (n_try > 0);
331
332 if (my_obj->ds_fd < 0) {
333 LOGE("cannot open domain socket fd of '%s'(%s)\n",
334 dev_name, strerror(l_errno));
335 rc = -1;
336 goto on_error;
337 }
338 #else /* DAEMON_PRESENT */
339 cam_status_t cam_status;
340 cam_status = mm_camera_module_open_session(my_obj->sessionid,
341 mm_camera_module_event_handler);
342 if (cam_status < 0) {
343 LOGE("Failed to open session");
344 if (cam_status == CAM_STATUS_BUSY) {
345 rc = -EUSERS;
346 } else {
347 rc = -1;
348 }
349 goto on_error;
350 }
351 #endif /* DAEMON_PRESENT */
352
353 pthread_mutex_init(&my_obj->msg_lock, NULL);
354 pthread_mutex_init(&my_obj->cb_lock, NULL);
355 pthread_mutex_init(&my_obj->evt_lock, NULL);
356 PTHREAD_COND_INIT(&my_obj->evt_cond);
357
358 LOGD("Launch evt Thread in Cam Open");
359 snprintf(my_obj->evt_thread.threadName, THREAD_NAME_SIZE, "CAM_Dispatch");
360 mm_camera_cmd_thread_launch(&my_obj->evt_thread,
361 mm_camera_dispatch_app_event,
362 (void *)my_obj);
363
364 /* launch event poll thread
365 * we will add evt fd into event poll thread upon user first register for evt */
366 LOGD("Launch evt Poll Thread in Cam Open");
367 snprintf(my_obj->evt_poll_thread.threadName, THREAD_NAME_SIZE, "CAM_evntPoll");
368 mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
369 MM_CAMERA_POLL_TYPE_EVT);
370 mm_camera_evt_sub(my_obj, TRUE);
371
372 /* unlock cam_lock, we need release global intf_lock in camera_open(),
373 * in order not block operation of other Camera in dual camera use case.*/
374 pthread_mutex_unlock(&my_obj->cam_lock);
375 LOGD("end (rc = %d)\n", rc);
376 return rc;
377
378 on_error:
379
380 if (NULL == dev_name_value) {
381 LOGE("Invalid device name\n");
382 rc = -1;
383 }
384
385 if (NULL == my_obj) {
386 LOGE("Invalid camera object\n");
387 rc = -1;
388 } else {
389 if (my_obj->ctrl_fd >= 0) {
390 close(my_obj->ctrl_fd);
391 my_obj->ctrl_fd = -1;
392 }
393 #ifdef DAEMON_PRESENT
394 if (my_obj->ds_fd >= 0) {
395 mm_camera_socket_close(my_obj->ds_fd);
396 my_obj->ds_fd = -1;
397 }
398 #endif
399 }
400
401 /* unlock cam_lock, we need release global intf_lock in camera_open(),
402 * in order not block operation of other Camera in dual camera use case.*/
403 pthread_mutex_unlock(&my_obj->cam_lock);
404 return rc;
405 }
406
407 /*===========================================================================
408 * FUNCTION : mm_camera_close
409 *
410 * DESCRIPTION: enqueue received event into event queue to be processed by
411 * event thread.
412 *
413 * PARAMETERS :
414 * @my_obj : ptr to a camera object
415 * @event : event to be queued
416 *
417 * RETURN : int32_t type of status
418 * 0 -- success
419 * -1 -- failure
420 *==========================================================================*/
mm_camera_close(mm_camera_obj_t * my_obj)421 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
422 {
423 LOGD("unsubscribe evt");
424
425 #ifndef DAEMON_PRESENT
426 mm_camera_module_close_session(my_obj->sessionid);
427 #endif /* DAEMON_PRESENT */
428
429 mm_camera_evt_sub(my_obj, FALSE);
430
431 LOGD("Close evt Poll Thread in Cam Close");
432 mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
433
434 LOGD("Close evt cmd Thread in Cam Close");
435 mm_camera_cmd_thread_release(&my_obj->evt_thread);
436
437 if(my_obj->ctrl_fd >= 0) {
438 close(my_obj->ctrl_fd);
439 my_obj->ctrl_fd = -1;
440 }
441
442 #ifdef DAEMON_PRESENT
443 if(my_obj->ds_fd >= 0) {
444 mm_camera_socket_close(my_obj->ds_fd);
445 my_obj->ds_fd = -1;
446 }
447 #endif
448
449 if (my_obj->master_cam_obj != NULL) {
450 my_obj->master_cam_obj->num_s_cnt--;
451 my_obj->master_cam_obj->aux_cam_obj[my_obj->master_cam_obj->num_s_cnt] = NULL;
452 }
453 pthread_mutex_destroy(&my_obj->msg_lock);
454 pthread_mutex_destroy(&my_obj->cb_lock);
455 pthread_mutex_destroy(&my_obj->evt_lock);
456 pthread_cond_destroy(&my_obj->evt_cond);
457 pthread_mutex_unlock(&my_obj->cam_lock);
458 return 0;
459 }
460
461 /*===========================================================================
462 * FUNCTION : mm_camera_register_event_notify_internal
463 *
464 * DESCRIPTION: internal implementation for registering callback for event notify.
465 *
466 * PARAMETERS :
467 * @my_obj : ptr to a camera object
468 * @evt_cb : callback to be registered to handle event notify
469 * @user_data: user data ptr
470 *
471 * RETURN : int32_t type of status
472 * 0 -- success
473 * -1 -- failure
474 *==========================================================================*/
mm_camera_register_event_notify_internal(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)475 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
476 mm_camera_event_notify_t evt_cb,
477 void * user_data)
478 {
479 int i;
480 int rc = -1;
481 mm_camera_evt_obj_t *evt_array = NULL;
482
483 pthread_mutex_lock(&my_obj->cb_lock);
484 evt_array = &my_obj->evt;
485 if(evt_cb) {
486 /* this is reg case */
487 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
488 if(evt_array->evt[i].user_data == NULL) {
489 evt_array->evt[i].evt_cb = evt_cb;
490 evt_array->evt[i].user_data = user_data;
491 evt_array->reg_count++;
492 rc = 0;
493 break;
494 }
495 }
496 } else {
497 /* this is unreg case */
498 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
499 if(evt_array->evt[i].user_data == user_data) {
500 evt_array->evt[i].evt_cb = NULL;
501 evt_array->evt[i].user_data = NULL;
502 evt_array->reg_count--;
503 rc = 0;
504 break;
505 }
506 }
507 }
508
509 pthread_mutex_unlock(&my_obj->cb_lock);
510 return rc;
511 }
512
513 /*===========================================================================
514 * FUNCTION : mm_camera_register_event_notify
515 *
516 * DESCRIPTION: registering a callback for event notify.
517 *
518 * PARAMETERS :
519 * @my_obj : ptr to a camera object
520 * @evt_cb : callback to be registered to handle event notify
521 * @user_data: user data ptr
522 *
523 * RETURN : int32_t type of status
524 * 0 -- success
525 * -1 -- failure
526 *==========================================================================*/
mm_camera_register_event_notify(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)527 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
528 mm_camera_event_notify_t evt_cb,
529 void * user_data)
530 {
531 int rc = -1;
532 rc = mm_camera_register_event_notify_internal(my_obj,
533 evt_cb,
534 user_data);
535 pthread_mutex_unlock(&my_obj->cam_lock);
536 return rc;
537 }
538
539 /*===========================================================================
540 * FUNCTION : mm_camera_qbuf
541 *
542 * DESCRIPTION: enqueue buffer back to kernel
543 *
544 * PARAMETERS :
545 * @my_obj : camera object
546 * @ch_id : channel handle
547 * @buf : buf ptr to be enqueued
548 *
549 * RETURN : int32_t type of status
550 * 0 -- success
551 * -1 -- failure
552 *==========================================================================*/
mm_camera_qbuf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_buf_def_t * buf)553 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
554 uint32_t ch_id,
555 mm_camera_buf_def_t *buf)
556 {
557 int rc = -1;
558 mm_channel_t * ch_obj = NULL;
559 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
560
561 pthread_mutex_unlock(&my_obj->cam_lock);
562
563 /* we always assume qbuf will be done before channel/stream is fully stopped
564 * because qbuf is done within dataCB context
565 * in order to avoid deadlock, we are not locking ch_lock for qbuf */
566 if (NULL != ch_obj) {
567 rc = mm_channel_qbuf(ch_obj, buf);
568 }
569
570 return rc;
571 }
572
573 /*===========================================================================
574 * FUNCTION : mm_camera_cancel_buf
575 *
576 * DESCRIPTION: Cancel an already queued buffer
577 *
578 * PARAMETERS :
579 * @my_obj : camera object
580 * @ch_id : channel handle
581 *
582 * @buf : buf ptr to be enqueued
583 *
584 * RETURN : int32_t type of status
585 * 0 -- success
586 * -1 -- failure
587 *==========================================================================*/
mm_camera_cancel_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint32_t buf_idx)588 int32_t mm_camera_cancel_buf(mm_camera_obj_t *my_obj,
589 uint32_t ch_id,
590 uint32_t stream_id,
591 uint32_t buf_idx)
592 {
593 int rc = -1;
594 mm_channel_t * ch_obj = NULL;
595 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
596
597 if (NULL != ch_obj) {
598 pthread_mutex_unlock(&my_obj->cam_lock);
599 rc = mm_channel_cancel_buf(ch_obj,stream_id,buf_idx);
600 }
601
602 return rc;
603 }
604
605 /*===========================================================================
606 * FUNCTION : mm_camera_get_queued_buf_count
607 *
608 * DESCRIPTION: return queued buffer count
609 *
610 * PARAMETERS :
611 * @my_obj : camera object
612 * @ch_id : channel handle
613 * @stream_id : stream id
614 *
615 * RETURN : queued buffer count
616 *==========================================================================*/
mm_camera_get_queued_buf_count(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)617 int32_t mm_camera_get_queued_buf_count(mm_camera_obj_t *my_obj,
618 uint32_t ch_id, uint32_t stream_id)
619 {
620 int rc = -1;
621 mm_channel_t * ch_obj = NULL;
622 uint32_t payload;
623 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
624 payload = stream_id;
625
626 if (NULL != ch_obj) {
627 pthread_mutex_lock(&ch_obj->ch_lock);
628 pthread_mutex_unlock(&my_obj->cam_lock);
629 rc = mm_channel_fsm_fn(ch_obj,
630 MM_CHANNEL_EVT_GET_STREAM_QUEUED_BUF_COUNT,
631 (void *)&payload,
632 NULL);
633 } else {
634 pthread_mutex_unlock(&my_obj->cam_lock);
635 }
636
637 return rc;
638 }
639
640 /*===========================================================================
641 * FUNCTION : mm_camera_query_capability
642 *
643 * DESCRIPTION: query camera capability
644 *
645 * PARAMETERS :
646 * @my_obj: camera object
647 *
648 * RETURN : int32_t type of status
649 * 0 -- success
650 * -1 -- failure
651 *==========================================================================*/
mm_camera_query_capability(mm_camera_obj_t * my_obj)652 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
653 {
654 int32_t rc = 0;
655
656 #ifdef DAEMON_PRESENT
657 struct v4l2_capability cap;
658 /* get camera capabilities */
659 memset(&cap, 0, sizeof(cap));
660 rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
661 #else /* DAEMON_PRESENT */
662 cam_shim_packet_t *shim_cmd;
663 cam_shim_cmd_data shim_cmd_data;
664 memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
665 shim_cmd_data.command = MSM_CAMERA_PRIV_QUERY_CAP;
666 shim_cmd_data.stream_id = 0;
667 shim_cmd_data.value = NULL;
668 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM,
669 my_obj->sessionid,&shim_cmd_data);
670 rc = mm_camera_module_send_cmd(shim_cmd);
671 mm_camera_destroy_shim_cmd_packet(shim_cmd);
672 #endif /* DAEMON_PRESENT */
673 if (rc != 0) {
674 LOGE("cannot get camera capabilities, rc = %d, errno %d",
675 rc, errno);
676 }
677 pthread_mutex_unlock(&my_obj->cam_lock);
678 return rc;
679 }
680
681 /*===========================================================================
682 * FUNCTION : mm_camera_set_parms
683 *
684 * DESCRIPTION: set parameters per camera
685 *
686 * PARAMETERS :
687 * @my_obj : camera object
688 * @parms : ptr to a param struct to be set to server
689 *
690 * RETURN : int32_t type of status
691 * 0 -- success
692 * -1 -- failure
693 * NOTE : Assume the parms struct buf is already mapped to server via
694 * domain socket. Corresponding fields of parameters to be set
695 * are already filled in by upper layer caller.
696 *==========================================================================*/
mm_camera_set_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)697 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj,
698 parm_buffer_t *parms)
699 {
700 int32_t rc = -1;
701 int32_t value = 0;
702 if (parms != NULL) {
703 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
704 CAM_PRIV_PARM, &value);
705 }
706 pthread_mutex_unlock(&my_obj->cam_lock);
707 return rc;
708 }
709
710 /*===========================================================================
711 * FUNCTION : mm_camera_get_parms
712 *
713 * DESCRIPTION: get parameters per camera
714 *
715 * PARAMETERS :
716 * @my_obj : camera object
717 * @parms : ptr to a param struct to be get from server
718 *
719 * RETURN : int32_t type of status
720 * 0 -- success
721 * -1 -- failure
722 * NOTE : Assume the parms struct buf is already mapped to server via
723 * domain socket. Parameters to be get from server are already
724 * filled in by upper layer caller. After this call, corresponding
725 * fields of requested parameters will be filled in by server with
726 * detailed information.
727 *==========================================================================*/
mm_camera_get_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)728 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
729 parm_buffer_t *parms)
730 {
731 int32_t rc = -1;
732 int32_t value = 0;
733 if (parms != NULL) {
734 rc = mm_camera_util_g_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
735 }
736 pthread_mutex_unlock(&my_obj->cam_lock);
737 return rc;
738 }
739
740 /*===========================================================================
741 * FUNCTION : mm_camera_do_auto_focus
742 *
743 * DESCRIPTION: performing auto focus
744 *
745 * PARAMETERS :
746 * @camera_handle: camera handle
747 *
748 * RETURN : int32_t type of status
749 * 0 -- success
750 * -1 -- failure
751 * NOTE : if this call success, we will always assume there will
752 * be an auto_focus event following up.
753 *==========================================================================*/
mm_camera_do_auto_focus(mm_camera_obj_t * my_obj)754 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
755 {
756 int32_t rc = -1;
757 int32_t value = 0;
758 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
759 pthread_mutex_unlock(&my_obj->cam_lock);
760 return rc;
761 }
762
763 /*===========================================================================
764 * FUNCTION : mm_camera_cancel_auto_focus
765 *
766 * DESCRIPTION: cancel auto focus
767 *
768 * PARAMETERS :
769 * @camera_handle: camera handle
770 *
771 * RETURN : int32_t type of status
772 * 0 -- success
773 * -1 -- failure
774 *==========================================================================*/
mm_camera_cancel_auto_focus(mm_camera_obj_t * my_obj)775 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
776 {
777 int32_t rc = -1;
778 int32_t value = 0;
779 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
780 pthread_mutex_unlock(&my_obj->cam_lock);
781 return rc;
782 }
783
784 /*===========================================================================
785 * FUNCTION : mm_camera_prepare_snapshot
786 *
787 * DESCRIPTION: prepare hardware for snapshot
788 *
789 * PARAMETERS :
790 * @my_obj : camera object
791 * @do_af_flag : flag indicating if AF is needed
792 *
793 * RETURN : int32_t type of status
794 * 0 -- success
795 * -1 -- failure
796 *==========================================================================*/
mm_camera_prepare_snapshot(mm_camera_obj_t * my_obj,int32_t do_af_flag)797 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
798 int32_t do_af_flag)
799 {
800 int32_t rc = -1;
801 int32_t value = do_af_flag;
802 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
803 pthread_mutex_unlock(&my_obj->cam_lock);
804 return rc;
805 }
806
807 /*===========================================================================
808 * FUNCTION : mm_camera_start_zsl_snapshot
809 *
810 * DESCRIPTION: start zsl snapshot
811 *
812 * PARAMETERS :
813 * @my_obj : camera object
814 *
815 * RETURN : int32_t type of status
816 * 0 -- success
817 * -1 -- failure
818 *==========================================================================*/
mm_camera_start_zsl_snapshot(mm_camera_obj_t * my_obj)819 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
820 {
821 int32_t rc = -1;
822 int32_t value = 0;
823
824 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
825 CAM_PRIV_START_ZSL_SNAPSHOT, &value);
826 return rc;
827 }
828
829 /*===========================================================================
830 * FUNCTION : mm_camera_stop_zsl_snapshot
831 *
832 * DESCRIPTION: stop zsl capture
833 *
834 * PARAMETERS :
835 * @my_obj : camera object
836 *
837 * RETURN : int32_t type of status
838 * 0 -- success
839 * -1 -- failure
840 *==========================================================================*/
mm_camera_stop_zsl_snapshot(mm_camera_obj_t * my_obj)841 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
842 {
843 int32_t rc = -1;
844 int32_t value;
845 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
846 CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
847 return rc;
848 }
849
850 /*===========================================================================
851 * FUNCTION : mm_camera_flush
852 *
853 * DESCRIPTION: flush the current camera state and buffers
854 *
855 * PARAMETERS :
856 * @my_obj : camera object
857 *
858 * RETURN : int32_t type of status
859 * 0 -- success
860 * -1 -- failure
861 *==========================================================================*/
mm_camera_flush(mm_camera_obj_t * my_obj)862 int32_t mm_camera_flush(mm_camera_obj_t *my_obj)
863 {
864 int32_t rc = -1;
865 int32_t value;
866 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
867 CAM_PRIV_FLUSH, &value);
868 pthread_mutex_unlock(&my_obj->cam_lock);
869 return rc;
870 }
871
872 /*===========================================================================
873 * FUNCTION : mm_camera_add_channel
874 *
875 * DESCRIPTION: add a channel
876 *
877 * PARAMETERS :
878 * @my_obj : camera object
879 * @attr : bundle attribute of the channel if needed
880 * @channel_cb : callback function for bundle data notify
881 * @userdata : user data ptr
882 *
883 * RETURN : uint32_t type of channel handle
884 * 0 -- invalid channel handle, meaning the op failed
885 * >0 -- successfully added a channel with a valid handle
886 * NOTE : if no bundle data notify is needed, meaning each stream in the
887 * channel will have its own stream data notify callback, then
888 * attr, channel_cb, and userdata can be NULL. In this case,
889 * no matching logic will be performed in channel for the bundling.
890 *==========================================================================*/
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)891 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
892 mm_camera_channel_attr_t *attr,
893 mm_camera_buf_notify_t channel_cb,
894 void *userdata)
895 {
896 mm_channel_t *ch_obj = NULL;
897 uint8_t ch_idx = 0;
898 uint32_t ch_hdl = 0;
899
900 for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
901 if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
902 ch_obj = &my_obj->ch[ch_idx];
903 break;
904 }
905 }
906
907 if (NULL != ch_obj) {
908 /* initialize channel obj */
909 memset(ch_obj, 0, sizeof(mm_channel_t));
910 ch_hdl = mm_camera_util_generate_handler_by_num(my_obj->my_num, ch_idx);
911 ch_obj->my_hdl = ch_hdl;
912 ch_obj->state = MM_CHANNEL_STATE_STOPPED;
913 ch_obj->cam_obj = my_obj;
914 pthread_mutex_init(&ch_obj->ch_lock, NULL);
915 ch_obj->sessionid = my_obj->sessionid;
916 mm_channel_init(ch_obj, attr, channel_cb, userdata);
917 }
918
919 pthread_mutex_unlock(&my_obj->cam_lock);
920 return ch_hdl;
921 }
922
923 /*===========================================================================
924 * FUNCTION : mm_camera_del_channel
925 *
926 * DESCRIPTION: delete a channel by its handle
927 *
928 * PARAMETERS :
929 * @my_obj : camera object
930 * @ch_id : channel handle
931 *
932 * RETURN : int32_t type of status
933 * 0 -- success
934 * -1 -- failure
935 * NOTE : all streams in the channel should be stopped already before
936 * this channel can be deleted.
937 *==========================================================================*/
mm_camera_del_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)938 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
939 uint32_t ch_id)
940 {
941 int32_t rc = -1;
942 mm_channel_t * ch_obj =
943 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
944
945 if (NULL != ch_obj) {
946 pthread_mutex_lock(&ch_obj->ch_lock);
947 pthread_mutex_unlock(&my_obj->cam_lock);
948
949 rc = mm_channel_fsm_fn(ch_obj,
950 MM_CHANNEL_EVT_DELETE,
951 NULL,
952 NULL);
953
954 if (ch_obj->master_ch_obj != NULL) {
955 ch_obj->master_ch_obj->num_s_cnt--;
956 ch_obj->master_ch_obj->aux_ch_obj[ch_obj->master_ch_obj->num_s_cnt] = NULL;
957 }
958 pthread_mutex_destroy(&ch_obj->ch_lock);
959 memset(ch_obj, 0, sizeof(mm_channel_t));
960 } else {
961 pthread_mutex_unlock(&my_obj->cam_lock);
962 }
963 return rc;
964 }
965
966 /*===========================================================================
967 * FUNCTION : mm_camera_get_bundle_info
968 *
969 * DESCRIPTION: query bundle info of the channel
970 *
971 * PARAMETERS :
972 * @my_obj : camera object
973 * @ch_id : channel handle
974 * @bundle_info : bundle info to be filled in
975 *
976 * RETURN : int32_t type of status
977 * 0 -- success
978 * -1 -- failure
979 * NOTE : all streams in the channel should be stopped already before
980 * this channel can be deleted.
981 *==========================================================================*/
mm_camera_get_bundle_info(mm_camera_obj_t * my_obj,uint32_t ch_id,cam_bundle_config_t * bundle_info)982 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
983 uint32_t ch_id,
984 cam_bundle_config_t *bundle_info)
985 {
986 int32_t rc = -1;
987 mm_channel_t * ch_obj =
988 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
989
990 if (NULL != ch_obj) {
991 pthread_mutex_lock(&ch_obj->ch_lock);
992 pthread_mutex_unlock(&my_obj->cam_lock);
993
994 rc = mm_channel_fsm_fn(ch_obj,
995 MM_CHANNEL_EVT_GET_BUNDLE_INFO,
996 (void *)bundle_info,
997 NULL);
998 } else {
999 pthread_mutex_unlock(&my_obj->cam_lock);
1000 }
1001 return rc;
1002 }
1003
1004 /*===========================================================================
1005 * FUNCTION : mm_camera_link_stream
1006 *
1007 * DESCRIPTION: link a stream into a channel
1008 *
1009 * PARAMETERS :
1010 * @my_obj : camera object
1011 * @ch_id : channel handle
1012 * @stream_id : stream that will be linked
1013 * @linked_ch_id : channel in which the stream will be linked
1014 *
1015 * RETURN : uint32_t type of stream handle
1016 * 0 -- invalid stream handle, meaning the op failed
1017 * >0 -- successfully linked a stream with a valid handle
1018 *==========================================================================*/
mm_camera_link_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,uint32_t linked_ch_id)1019 uint32_t mm_camera_link_stream(mm_camera_obj_t *my_obj,
1020 uint32_t ch_id,
1021 uint32_t stream_id,
1022 uint32_t linked_ch_id)
1023 {
1024 uint32_t s_hdl = 0;
1025 mm_channel_t * ch_obj =
1026 mm_camera_util_get_channel_by_handler(my_obj, linked_ch_id);
1027 mm_channel_t * owner_obj =
1028 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1029
1030 if ((NULL != ch_obj) && (NULL != owner_obj)) {
1031 pthread_mutex_lock(&ch_obj->ch_lock);
1032 pthread_mutex_unlock(&my_obj->cam_lock);
1033
1034 mm_camera_stream_link_t stream_link;
1035 memset(&stream_link, 0, sizeof(mm_camera_stream_link_t));
1036 stream_link.ch = owner_obj;
1037 stream_link.stream_id = stream_id;
1038 mm_channel_fsm_fn(ch_obj,
1039 MM_CHANNEL_EVT_LINK_STREAM,
1040 (void*)&stream_link,
1041 (void*)&s_hdl);
1042 } else {
1043 pthread_mutex_unlock(&my_obj->cam_lock);
1044 }
1045
1046 return s_hdl;
1047 }
1048
1049 /*===========================================================================
1050 * FUNCTION : mm_camera_add_stream
1051 *
1052 * DESCRIPTION: add a stream into a channel
1053 *
1054 * PARAMETERS :
1055 * @my_obj : camera object
1056 * @ch_id : channel handle
1057 *
1058 * RETURN : uint32_t type of stream handle
1059 * 0 -- invalid stream handle, meaning the op failed
1060 * >0 -- successfully added a stream with a valid handle
1061 *==========================================================================*/
mm_camera_add_stream(mm_camera_obj_t * my_obj,uint32_t ch_id)1062 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
1063 uint32_t ch_id)
1064 {
1065 uint32_t s_hdl = 0;
1066 mm_channel_t * ch_obj =
1067 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1068
1069 if (NULL != ch_obj) {
1070 pthread_mutex_lock(&ch_obj->ch_lock);
1071 pthread_mutex_unlock(&my_obj->cam_lock);
1072
1073 mm_channel_fsm_fn(ch_obj,
1074 MM_CHANNEL_EVT_ADD_STREAM,
1075 NULL,
1076 (void *)&s_hdl);
1077 } else {
1078 pthread_mutex_unlock(&my_obj->cam_lock);
1079 }
1080 return s_hdl;
1081 }
1082
1083 /*===========================================================================
1084 * FUNCTION : mm_camera_del_stream
1085 *
1086 * DESCRIPTION: delete a stream by its handle
1087 *
1088 * PARAMETERS :
1089 * @my_obj : camera object
1090 * @ch_id : channel handle
1091 * @stream_id : stream handle
1092 *
1093 * RETURN : int32_t type of status
1094 * 0 -- success
1095 * -1 -- failure
1096 * NOTE : stream should be stopped already before it can be deleted.
1097 *==========================================================================*/
mm_camera_del_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)1098 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
1099 uint32_t ch_id,
1100 uint32_t stream_id)
1101 {
1102 int32_t rc = -1;
1103 mm_channel_t * ch_obj =
1104 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1105
1106 if (NULL != ch_obj) {
1107 pthread_mutex_lock(&ch_obj->ch_lock);
1108 pthread_mutex_unlock(&my_obj->cam_lock);
1109
1110 rc = mm_channel_fsm_fn(ch_obj,
1111 MM_CHANNEL_EVT_DEL_STREAM,
1112 (void *)&stream_id,
1113 NULL);
1114 } else {
1115 pthread_mutex_unlock(&my_obj->cam_lock);
1116 }
1117
1118 return rc;
1119 }
1120
1121 /*===========================================================================
1122 * FUNCTION : mm_camera_start_zsl_snapshot_ch
1123 *
1124 * DESCRIPTION: starts zsl snapshot for specific channel
1125 *
1126 * PARAMETERS :
1127 * @my_obj : camera object
1128 * @ch_id : channel handle
1129 *
1130 * RETURN : int32_t type of status
1131 * 0 -- success
1132 * -1 -- failure
1133 *==========================================================================*/
mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)1134 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
1135 uint32_t ch_id)
1136 {
1137 int32_t rc = -1;
1138 mm_channel_t *ch_obj =
1139 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1140
1141 if (NULL != ch_obj) {
1142 pthread_mutex_lock(&ch_obj->ch_lock);
1143 pthread_mutex_unlock(&my_obj->cam_lock);
1144
1145 rc = mm_channel_fsm_fn(ch_obj,
1146 MM_CHANNEL_EVT_START_ZSL_SNAPSHOT,
1147 NULL,
1148 NULL);
1149 } else {
1150 pthread_mutex_unlock(&my_obj->cam_lock);
1151 }
1152
1153 return rc;
1154 }
1155
1156 /*===========================================================================
1157 * FUNCTION : mm_camera_stop_zsl_snapshot_ch
1158 *
1159 * DESCRIPTION: stops zsl snapshot for specific channel
1160 *
1161 * PARAMETERS :
1162 * @my_obj : camera object
1163 * @ch_id : channel handle
1164 *
1165 * RETURN : int32_t type of status
1166 * 0 -- success
1167 * -1 -- failure
1168 *==========================================================================*/
mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)1169 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
1170 uint32_t ch_id)
1171 {
1172 int32_t rc = -1;
1173 mm_channel_t * ch_obj =
1174 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1175
1176 if (NULL != ch_obj) {
1177 pthread_mutex_lock(&ch_obj->ch_lock);
1178 pthread_mutex_unlock(&my_obj->cam_lock);
1179
1180 rc = mm_channel_fsm_fn(ch_obj,
1181 MM_CHANNEL_EVT_STOP_ZSL_SNAPSHOT,
1182 NULL,
1183 NULL);
1184 } else {
1185 pthread_mutex_unlock(&my_obj->cam_lock);
1186 }
1187
1188 return rc;
1189 }
1190
1191 /*===========================================================================
1192 * FUNCTION : mm_camera_config_stream
1193 *
1194 * DESCRIPTION: configure a stream
1195 *
1196 * PARAMETERS :
1197 * @my_obj : camera object
1198 * @ch_id : channel handle
1199 * @stream_id : stream handle
1200 * @config : stream configuration
1201 *
1202 * RETURN : int32_t type of status
1203 * 0 -- success
1204 * -1 -- failure
1205 *==========================================================================*/
mm_camera_config_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)1206 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
1207 uint32_t ch_id,
1208 uint32_t stream_id,
1209 mm_camera_stream_config_t *config)
1210 {
1211 int32_t rc = -1;
1212 mm_channel_t * ch_obj =
1213 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1214 mm_evt_paylod_config_stream_t payload;
1215
1216 if (NULL != ch_obj) {
1217 pthread_mutex_lock(&ch_obj->ch_lock);
1218 pthread_mutex_unlock(&my_obj->cam_lock);
1219
1220 memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
1221 payload.stream_id = stream_id;
1222 payload.config = config;
1223 rc = mm_channel_fsm_fn(ch_obj,
1224 MM_CHANNEL_EVT_CONFIG_STREAM,
1225 (void *)&payload,
1226 NULL);
1227 } else {
1228 pthread_mutex_unlock(&my_obj->cam_lock);
1229 }
1230
1231 return rc;
1232 }
1233
1234 /*===========================================================================
1235 * FUNCTION : mm_camera_start_channel
1236 *
1237 * DESCRIPTION: start a channel, which will start all streams in the channel
1238 *
1239 * PARAMETERS :
1240 * @my_obj : camera object
1241 * @ch_id : channel handle
1242 *
1243 * RETURN : int32_t type of status
1244 * 0 -- success
1245 * -1 -- failure
1246 *==========================================================================*/
mm_camera_start_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1247 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj, uint32_t ch_id)
1248 {
1249 int32_t rc = -1;
1250 mm_channel_t * ch_obj =
1251 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1252
1253 if (NULL != ch_obj) {
1254 pthread_mutex_lock(&ch_obj->ch_lock);
1255 pthread_mutex_unlock(&my_obj->cam_lock);
1256
1257 rc = mm_channel_fsm_fn(ch_obj,
1258 MM_CHANNEL_EVT_START,
1259 NULL,
1260 NULL);
1261 } else {
1262 pthread_mutex_unlock(&my_obj->cam_lock);
1263 }
1264
1265 return rc;
1266 }
1267
mm_camera_start_sensor_stream_on(mm_camera_obj_t * my_obj,uint32_t ch_id)1268 int32_t mm_camera_start_sensor_stream_on(mm_camera_obj_t *my_obj, uint32_t ch_id)
1269 {
1270 int32_t rc = -1;
1271 mm_channel_t * ch_obj =
1272 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1273
1274 if (NULL != ch_obj) {
1275 pthread_mutex_lock(&ch_obj->ch_lock);
1276 pthread_mutex_unlock(&my_obj->cam_lock);
1277
1278 rc = mm_channel_fsm_fn(ch_obj,
1279 MM_CHANNEL_EVT_START_SENSOR_STREAMING,
1280 NULL,
1281 NULL);
1282 } else {
1283 pthread_mutex_unlock(&my_obj->cam_lock);
1284 }
1285
1286 return rc;
1287 }
1288
1289 /*===========================================================================
1290 * FUNCTION : mm_camera_stop_channel
1291 *
1292 * DESCRIPTION: stop a channel, which will stop all streams in the channel
1293 *
1294 * PARAMETERS :
1295 * @my_obj : camera object
1296 * @ch_id : channel handle
1297 * @stop_immediately : stop channel immediately without waiting for frame
1298 * boundary.
1299 *
1300 * RETURN : int32_t type of status
1301 * 0 -- success
1302 * -1 -- failure
1303 *==========================================================================*/
mm_camera_stop_channel(mm_camera_obj_t * my_obj,uint32_t ch_id,bool stop_immediately)1304 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
1305 uint32_t ch_id, bool stop_immediately)
1306 {
1307 int32_t rc = 0;
1308 mm_channel_t * ch_obj =
1309 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1310
1311 if (NULL != ch_obj) {
1312 pthread_mutex_lock(&ch_obj->ch_lock);
1313 pthread_mutex_unlock(&my_obj->cam_lock);
1314 rc = mm_channel_fsm_fn(ch_obj,
1315 MM_CHANNEL_EVT_STOP,
1316 &stop_immediately,
1317 NULL);
1318 } else {
1319 pthread_mutex_unlock(&my_obj->cam_lock);
1320 }
1321 return rc;
1322 }
1323
1324 /*===========================================================================
1325 * FUNCTION : mm_camera_request_super_buf
1326 *
1327 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1328 * frames from superbuf queue
1329 *
1330 * PARAMETERS :
1331 * @my_obj : camera object
1332 * @ch_id : channel handle
1333 * @num_buf_requested : number of matched frames needed
1334 *
1335 * RETURN : int32_t type of status
1336 * 0 -- success
1337 * -1 -- failure
1338 *==========================================================================*/
mm_camera_request_super_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_req_buf_t * buf)1339 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1340 uint32_t ch_id, mm_camera_req_buf_t *buf)
1341 {
1342 int32_t rc = -1;
1343 mm_channel_t * ch_obj =
1344 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1345
1346 if ((NULL != ch_obj) && (buf != NULL)) {
1347 pthread_mutex_lock(&ch_obj->ch_lock);
1348 pthread_mutex_unlock(&my_obj->cam_lock);
1349
1350 rc = mm_channel_fsm_fn(ch_obj, MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
1351 (void *)buf, NULL);
1352 } else {
1353 pthread_mutex_unlock(&my_obj->cam_lock);
1354 }
1355
1356 return rc;
1357 }
1358
1359 /*===========================================================================
1360 * FUNCTION : mm_camera_cancel_super_buf_request
1361 *
1362 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
1363 * of matched frames from superbuf queue
1364 *
1365 * PARAMETERS :
1366 * @my_obj : camera object
1367 * @ch_id : channel handle
1368 *
1369 * RETURN : int32_t type of status
1370 * 0 -- success
1371 * -1 -- failure
1372 *==========================================================================*/
mm_camera_cancel_super_buf_request(mm_camera_obj_t * my_obj,uint32_t ch_id)1373 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
1374 {
1375 int32_t rc = -1;
1376 mm_channel_t * ch_obj =
1377 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1378
1379 if (NULL != ch_obj) {
1380 pthread_mutex_lock(&ch_obj->ch_lock);
1381 pthread_mutex_unlock(&my_obj->cam_lock);
1382
1383 rc = mm_channel_fsm_fn(ch_obj,
1384 MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
1385 NULL,
1386 NULL);
1387 } else {
1388 pthread_mutex_unlock(&my_obj->cam_lock);
1389 }
1390
1391 return rc;
1392 }
1393
1394 /*===========================================================================
1395 * FUNCTION : mm_camera_flush_super_buf_queue
1396 *
1397 * DESCRIPTION: flush out all frames in the superbuf queue
1398 *
1399 * PARAMETERS :
1400 * @my_obj : camera object
1401 * @ch_id : channel handle
1402 *
1403 * RETURN : int32_t type of status
1404 * 0 -- success
1405 * -1 -- failure
1406 *==========================================================================*/
mm_camera_flush_super_buf_queue(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t frame_idx)1407 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
1408 uint32_t frame_idx)
1409 {
1410 int32_t rc = -1;
1411 mm_channel_t * ch_obj =
1412 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1413
1414 if (NULL != ch_obj) {
1415 pthread_mutex_lock(&ch_obj->ch_lock);
1416 pthread_mutex_unlock(&my_obj->cam_lock);
1417
1418 rc = mm_channel_fsm_fn(ch_obj,
1419 MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
1420 (void *)&frame_idx,
1421 NULL);
1422 } else {
1423 pthread_mutex_unlock(&my_obj->cam_lock);
1424 }
1425
1426 return rc;
1427 }
1428
1429 /*===========================================================================
1430 * FUNCTION : mm_camera_config_channel_notify
1431 *
1432 * DESCRIPTION: configures the channel notification mode
1433 *
1434 * PARAMETERS :
1435 * @my_obj : camera object
1436 * @ch_id : channel handle
1437 * @notify_mode : notification mode
1438 *
1439 * RETURN : int32_t type of status
1440 * 0 -- success
1441 * -1 -- failure
1442 *==========================================================================*/
mm_camera_config_channel_notify(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)1443 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
1444 uint32_t ch_id,
1445 mm_camera_super_buf_notify_mode_t notify_mode)
1446 {
1447 int32_t rc = -1;
1448 mm_channel_t * ch_obj =
1449 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1450
1451 if (NULL != ch_obj) {
1452 pthread_mutex_lock(&ch_obj->ch_lock);
1453 pthread_mutex_unlock(&my_obj->cam_lock);
1454
1455 rc = mm_channel_fsm_fn(ch_obj,
1456 MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
1457 (void *)¬ify_mode,
1458 NULL);
1459 } else {
1460 pthread_mutex_unlock(&my_obj->cam_lock);
1461 }
1462
1463 return rc;
1464 }
1465
1466 /*===========================================================================
1467 * FUNCTION : mm_camera_set_stream_parms
1468 *
1469 * DESCRIPTION: set parameters per stream
1470 *
1471 * PARAMETERS :
1472 * @my_obj : camera object
1473 * @ch_id : channel handle
1474 * @s_id : stream handle
1475 * @parms : ptr to a param struct to be set to server
1476 *
1477 * RETURN : int32_t type of status
1478 * 0 -- success
1479 * -1 -- failure
1480 * NOTE : Assume the parms struct buf is already mapped to server via
1481 * domain socket. Corresponding fields of parameters to be set
1482 * are already filled in by upper layer caller.
1483 *==========================================================================*/
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)1484 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
1485 uint32_t ch_id,
1486 uint32_t s_id,
1487 cam_stream_parm_buffer_t *parms)
1488 {
1489 int32_t rc = -1;
1490 mm_evt_paylod_set_get_stream_parms_t payload;
1491 mm_channel_t * ch_obj =
1492 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1493
1494 if (NULL != ch_obj) {
1495 pthread_mutex_lock(&ch_obj->ch_lock);
1496 pthread_mutex_unlock(&my_obj->cam_lock);
1497
1498 memset(&payload, 0, sizeof(payload));
1499 payload.stream_id = s_id;
1500 payload.parms = parms;
1501
1502 rc = mm_channel_fsm_fn(ch_obj,
1503 MM_CHANNEL_EVT_SET_STREAM_PARM,
1504 (void *)&payload,
1505 NULL);
1506 } else {
1507 pthread_mutex_unlock(&my_obj->cam_lock);
1508 }
1509
1510 return rc;
1511 }
1512
1513 /*===========================================================================
1514 * FUNCTION : mm_camera_get_stream_parms
1515 *
1516 * DESCRIPTION: get parameters per stream
1517 *
1518 * PARAMETERS :
1519 * @my_obj : camera object
1520 * @ch_id : channel handle
1521 * @s_id : stream handle
1522 * @parms : ptr to a param struct to be get from server
1523 *
1524 * RETURN : int32_t type of status
1525 * 0 -- success
1526 * -1 -- failure
1527 * NOTE : Assume the parms struct buf is already mapped to server via
1528 * domain socket. Parameters to be get from server are already
1529 * filled in by upper layer caller. After this call, corresponding
1530 * fields of requested parameters will be filled in by server with
1531 * detailed information.
1532 *==========================================================================*/
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)1533 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
1534 uint32_t ch_id,
1535 uint32_t s_id,
1536 cam_stream_parm_buffer_t *parms)
1537 {
1538 int32_t rc = -1;
1539 mm_evt_paylod_set_get_stream_parms_t payload;
1540 mm_channel_t * ch_obj =
1541 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1542
1543 if (NULL != ch_obj) {
1544 pthread_mutex_lock(&ch_obj->ch_lock);
1545 pthread_mutex_unlock(&my_obj->cam_lock);
1546
1547 memset(&payload, 0, sizeof(payload));
1548 payload.stream_id = s_id;
1549 payload.parms = parms;
1550
1551 rc = mm_channel_fsm_fn(ch_obj,
1552 MM_CHANNEL_EVT_GET_STREAM_PARM,
1553 (void *)&payload,
1554 NULL);
1555 } else {
1556 pthread_mutex_unlock(&my_obj->cam_lock);
1557 }
1558
1559 return rc;
1560 }
1561
1562 /*===========================================================================
1563 * FUNCTION : mm_camera_do_stream_action
1564 *
1565 * DESCRIPTION: request server to perform stream based action. Maybe removed later
1566 * if the functionality is included in mm_camera_set_parms
1567 *
1568 * PARAMETERS :
1569 * @my_obj : camera object
1570 * @ch_id : channel handle
1571 * @s_id : stream handle
1572 * @actions : ptr to an action struct buf to be performed by server
1573 *
1574 * RETURN : int32_t type of status
1575 * 0 -- success
1576 * -1 -- failure
1577 * NOTE : Assume the action struct buf is already mapped to server via
1578 * domain socket. Actions to be performed by server are already
1579 * filled in by upper layer caller.
1580 *==========================================================================*/
mm_camera_do_stream_action(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,void * actions)1581 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
1582 uint32_t ch_id,
1583 uint32_t stream_id,
1584 void *actions)
1585 {
1586 int32_t rc = -1;
1587 mm_evt_paylod_do_stream_action_t payload;
1588 mm_channel_t * ch_obj =
1589 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1590
1591 if (NULL != ch_obj) {
1592 pthread_mutex_lock(&ch_obj->ch_lock);
1593 pthread_mutex_unlock(&my_obj->cam_lock);
1594
1595 memset(&payload, 0, sizeof(payload));
1596 payload.stream_id = stream_id;
1597 payload.actions = actions;
1598
1599 rc = mm_channel_fsm_fn(ch_obj,
1600 MM_CHANNEL_EVT_DO_ACTION,
1601 (void*)&payload, NULL);
1602 } else {
1603 pthread_mutex_unlock(&my_obj->cam_lock);
1604 }
1605
1606 return rc;
1607 }
1608
1609 /*===========================================================================
1610 * FUNCTION : mm_camera_map_stream_buf
1611 *
1612 * DESCRIPTION: mapping stream buffer via domain socket to server
1613 *
1614 * PARAMETERS :
1615 * @my_obj : camera object
1616 * @ch_id : channel handle
1617 * @s_id : stream handle
1618 * @buf_type : type of buffer to be mapped. could be following values:
1619 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1620 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1621 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1622 * @buf_idx : index of buffer within the stream buffers, only valid if
1623 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1624 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1625 * @plane_idx : plane index. If all planes share the same fd,
1626 * plane_idx = -1; otherwise, plean_idx is the
1627 * index to plane (0..num_of_planes)
1628 * @fd : file descriptor of the buffer
1629 * @size : size of the buffer
1630 *
1631 * RETURN : int32_t type of status
1632 * 0 -- success
1633 * -1 -- failure
1634 *==========================================================================*/
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,void * buffer)1635 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
1636 uint32_t ch_id,
1637 uint32_t stream_id,
1638 uint8_t buf_type,
1639 uint32_t buf_idx,
1640 int32_t plane_idx,
1641 int fd,
1642 size_t size,
1643 void *buffer)
1644 {
1645 int32_t rc = -1;
1646 cam_buf_map_type payload;
1647 mm_channel_t * ch_obj =
1648 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1649
1650 if (NULL != ch_obj) {
1651 pthread_mutex_lock(&ch_obj->ch_lock);
1652 pthread_mutex_unlock(&my_obj->cam_lock);
1653
1654 memset(&payload, 0, sizeof(payload));
1655 payload.stream_id = stream_id;
1656 payload.type = buf_type;
1657 payload.frame_idx = buf_idx;
1658 payload.plane_idx = plane_idx;
1659 payload.fd = fd;
1660 payload.size = size;
1661 payload.buffer = buffer;
1662 rc = mm_channel_fsm_fn(ch_obj,
1663 MM_CHANNEL_EVT_MAP_STREAM_BUF,
1664 (void*)&payload,
1665 NULL);
1666 } else {
1667 pthread_mutex_unlock(&my_obj->cam_lock);
1668 }
1669
1670 return rc;
1671 }
1672
1673 /*===========================================================================
1674 * FUNCTION : mm_camera_map_stream_bufs
1675 *
1676 * DESCRIPTION: mapping stream buffers via domain socket to server
1677 *
1678 * PARAMETERS :
1679 * @my_obj : camera object
1680 * @ch_id : channel handle
1681 * @buf_map_list : list of buffers to be mapped
1682 *
1683 * RETURN : int32_t type of status
1684 * 0 -- success
1685 * -1 -- failure
1686 *==========================================================================*/
mm_camera_map_stream_bufs(mm_camera_obj_t * my_obj,uint32_t ch_id,const cam_buf_map_type_list * buf_map_list)1687 int32_t mm_camera_map_stream_bufs(mm_camera_obj_t *my_obj,
1688 uint32_t ch_id,
1689 const cam_buf_map_type_list *buf_map_list)
1690 {
1691 int32_t rc = -1;
1692 cam_buf_map_type_list payload;
1693 mm_channel_t * ch_obj =
1694 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1695
1696 if (NULL != ch_obj) {
1697 pthread_mutex_lock(&ch_obj->ch_lock);
1698 pthread_mutex_unlock(&my_obj->cam_lock);
1699
1700 memcpy(&payload, buf_map_list, sizeof(payload));
1701 rc = mm_channel_fsm_fn(ch_obj,
1702 MM_CHANNEL_EVT_MAP_STREAM_BUFS,
1703 (void*)&payload,
1704 NULL);
1705 } else {
1706 pthread_mutex_unlock(&my_obj->cam_lock);
1707 }
1708
1709 return rc;
1710 }
1711
1712 /*===========================================================================
1713 * FUNCTION : mm_camera_unmap_stream_buf
1714 *
1715 * DESCRIPTION: unmapping stream buffer via domain socket to server
1716 *
1717 * PARAMETERS :
1718 * @my_obj : camera object
1719 * @ch_id : channel handle
1720 * @s_id : stream handle
1721 * @buf_type : type of buffer to be mapped. could be following values:
1722 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1723 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1724 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1725 * @buf_idx : index of buffer within the stream buffers, only valid if
1726 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1727 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1728 * @plane_idx : plane index. If all planes share the same fd,
1729 * plane_idx = -1; otherwise, plean_idx is the
1730 * index to plane (0..num_of_planes)
1731 *
1732 * RETURN : int32_t type of status
1733 * 0 -- success
1734 * -1 -- failure
1735 *==========================================================================*/
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)1736 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
1737 uint32_t ch_id,
1738 uint32_t stream_id,
1739 uint8_t buf_type,
1740 uint32_t buf_idx,
1741 int32_t plane_idx)
1742 {
1743 int32_t rc = -1;
1744 cam_buf_unmap_type payload;
1745 mm_channel_t * ch_obj =
1746 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1747
1748 if (NULL != ch_obj) {
1749 pthread_mutex_lock(&ch_obj->ch_lock);
1750 pthread_mutex_unlock(&my_obj->cam_lock);
1751
1752 memset(&payload, 0, sizeof(payload));
1753 payload.stream_id = stream_id;
1754 payload.type = buf_type;
1755 payload.frame_idx = buf_idx;
1756 payload.plane_idx = plane_idx;
1757 rc = mm_channel_fsm_fn(ch_obj,
1758 MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
1759 (void*)&payload,
1760 NULL);
1761 } else {
1762 pthread_mutex_unlock(&my_obj->cam_lock);
1763 }
1764
1765 return rc;
1766 }
1767
1768 /*===========================================================================
1769 * FUNCTION : mm_camera_evt_sub
1770 *
1771 * DESCRIPTION: subscribe/unsubscribe event notify from kernel
1772 *
1773 * PARAMETERS :
1774 * @my_obj : camera object
1775 * @reg_flag : 1 -- subscribe ; 0 -- unsubscribe
1776 *
1777 * RETURN : int32_t type of status
1778 * 0 -- success
1779 * -1 -- failure
1780 *==========================================================================*/
mm_camera_evt_sub(mm_camera_obj_t * my_obj,uint8_t reg_flag)1781 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1782 uint8_t reg_flag)
1783 {
1784 int32_t rc = 0;
1785 struct v4l2_event_subscription sub;
1786
1787 memset(&sub, 0, sizeof(sub));
1788 sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
1789 sub.id = MSM_CAMERA_MSM_NOTIFY;
1790 if(FALSE == reg_flag) {
1791 /* unsubscribe */
1792 rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1793 if (rc < 0) {
1794 LOGE("unsubscribe event rc = %d, errno %d",
1795 rc, errno);
1796 return rc;
1797 }
1798 /* remove evt fd from the polling thraed when unreg the last event */
1799 rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
1800 0, my_obj->my_hdl, mm_camera_sync_call);
1801 } else {
1802 rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1803 if (rc < 0) {
1804 LOGE("subscribe event rc = %d, errno %d",
1805 rc, errno);
1806 return rc;
1807 }
1808 /* add evt fd to polling thread when subscribe the first event */
1809 rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1810 0, my_obj->my_hdl, my_obj->ctrl_fd, mm_camera_event_notify,
1811 (void*)my_obj, mm_camera_sync_call);
1812 }
1813 return rc;
1814 }
1815
1816 /*===========================================================================
1817 * FUNCTION : mm_camera_util_wait_for_event
1818 *
1819 * DESCRIPTION: utility function to wait for certain events
1820 *
1821 * PARAMETERS :
1822 * @my_obj : camera object
1823 * @evt_mask : mask for events to be waited. Any of event in the mask would
1824 * trigger the wait to end
1825 * @status : status of the event
1826 *
1827 * RETURN : none
1828 *==========================================================================*/
mm_camera_util_wait_for_event(mm_camera_obj_t * my_obj,uint32_t evt_mask,uint32_t * status)1829 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
1830 uint32_t evt_mask,
1831 uint32_t *status)
1832 {
1833 int32_t rc = 0;
1834 struct timespec ts;
1835
1836 pthread_mutex_lock(&my_obj->evt_lock);
1837 while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
1838 clock_gettime(CLOCK_MONOTONIC, &ts);
1839 ts.tv_sec += WAIT_TIMEOUT;
1840 rc = pthread_cond_timedwait(&my_obj->evt_cond, &my_obj->evt_lock, &ts);
1841 if (rc) {
1842 LOGE("pthread_cond_timedwait of evt_mask 0x%x failed %d",
1843 evt_mask, rc);
1844 break;
1845 }
1846 }
1847 if (!rc) {
1848 *status = my_obj->evt_rcvd.status;
1849 } else {
1850 *status = MSM_CAMERA_STATUS_FAIL;
1851 }
1852 /* reset local storage for recieved event for next event */
1853 memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
1854 pthread_mutex_unlock(&my_obj->evt_lock);
1855 }
1856
1857 /*===========================================================================
1858 * FUNCTION : mm_camera_util_bundled_sendmsg
1859 *
1860 * DESCRIPTION: utility function to send bundled msg via domain socket
1861 *
1862 * PARAMETERS :
1863 * @my_obj : camera object
1864 * @msg : message to be sent
1865 * @buf_size : size of the message to be sent
1866 * @sendfds : array of file descriptors to be sent
1867 * @numfds : number of file descriptors to be sent
1868 *
1869 * RETURN : int32_t type of status
1870 * 0 -- success
1871 * -1 -- failure
1872 *==========================================================================*/
mm_camera_util_bundled_sendmsg(mm_camera_obj_t * my_obj,void * msg,size_t buf_size,int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],int numfds)1873 int32_t mm_camera_util_bundled_sendmsg(mm_camera_obj_t *my_obj,
1874 void *msg,
1875 size_t buf_size,
1876 int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM],
1877 int numfds)
1878 {
1879 int32_t rc = -1;
1880 uint32_t status;
1881
1882 /* need to lock msg_lock, since sendmsg until response back is deemed as one operation*/
1883 pthread_mutex_lock(&my_obj->msg_lock);
1884 if(mm_camera_socket_bundle_sendmsg(my_obj->ds_fd, msg, buf_size, sendfds, numfds) > 0) {
1885 /* wait for event that mapping/unmapping is done */
1886 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1887 if (MSM_CAMERA_STATUS_SUCCESS == status) {
1888 rc = 0;
1889 }
1890 }
1891 pthread_mutex_unlock(&my_obj->msg_lock);
1892 return rc;
1893 }
1894
1895 /*===========================================================================
1896 * FUNCTION : mm_camera_util_sendmsg
1897 *
1898 * DESCRIPTION: utility function to send msg via domain socket
1899 *
1900 * PARAMETERS :
1901 * @my_obj : camera object
1902 * @msg : message to be sent
1903 * @buf_size : size of the message to be sent
1904 * @sendfd : >0 if any file descriptor need to be passed across process
1905 *
1906 * RETURN : int32_t type of status
1907 * 0 -- success
1908 * -1 -- failure
1909 *==========================================================================*/
mm_camera_util_sendmsg(mm_camera_obj_t * my_obj,void * msg,size_t buf_size,int sendfd)1910 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
1911 void *msg,
1912 size_t buf_size,
1913 int sendfd)
1914 {
1915 int32_t rc = -1;
1916 uint32_t status;
1917
1918 /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
1919 pthread_mutex_lock(&my_obj->msg_lock);
1920 if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
1921 /* wait for event that mapping/unmapping is done */
1922 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1923 if (MSM_CAMERA_STATUS_SUCCESS == status) {
1924 rc = 0;
1925 }
1926 }
1927 pthread_mutex_unlock(&my_obj->msg_lock);
1928 return rc;
1929 }
1930
1931 /*===========================================================================
1932 * FUNCTIOa : mm_camera_map_buf
1933 *
1934 * DESCRIPTION: mapping camera buffer via domain socket to server
1935 *
1936 * PARAMETERS :
1937 * @my_obj : camera object
1938 * @buf_type : type of buffer to be mapped. could be following values:
1939 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1940 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1941 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1942 * @fd : file descriptor of the buffer
1943 * @size : size of the buffer
1944 *
1945 * RETURN : int32_t type of status
1946 * 0 -- success
1947 * -1 -- failure
1948 *==========================================================================*/
mm_camera_map_buf(mm_camera_obj_t * my_obj,uint8_t buf_type,int fd,size_t size,void * buffer)1949 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1950 uint8_t buf_type, int fd, size_t size, void *buffer)
1951 {
1952 int32_t rc = 0;
1953
1954 cam_sock_packet_t packet;
1955 memset(&packet, 0, sizeof(cam_sock_packet_t));
1956 packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
1957 packet.payload.buf_map.type = buf_type;
1958 packet.payload.buf_map.fd = fd;
1959 packet.payload.buf_map.size = size;
1960 packet.payload.buf_map.buffer = buffer;
1961 #ifdef DAEMON_PRESENT
1962 rc = mm_camera_util_sendmsg(my_obj,
1963 &packet,
1964 sizeof(cam_sock_packet_t),
1965 fd);
1966 #else
1967 cam_shim_packet_t *shim_cmd;
1968 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
1969 my_obj->sessionid, &packet);
1970 rc = mm_camera_module_send_cmd(shim_cmd);
1971 mm_camera_destroy_shim_cmd_packet(shim_cmd);
1972 #endif
1973 pthread_mutex_unlock(&my_obj->cam_lock);
1974 return rc;
1975 }
1976
1977 /*===========================================================================
1978 * FUNCTION : mm_camera_map_bufs
1979 *
1980 * DESCRIPTION: mapping camera buffers via domain socket to server
1981 *
1982 * PARAMETERS :
1983 * @my_obj : camera object
1984 * @buf_map_list : list of buffers to be mapped
1985 *
1986 * RETURN : int32_t type of status
1987 * 0 -- success
1988 * -1 -- failure
1989 *==========================================================================*/
mm_camera_map_bufs(mm_camera_obj_t * my_obj,const cam_buf_map_type_list * buf_map_list)1990 int32_t mm_camera_map_bufs(mm_camera_obj_t *my_obj,
1991 const cam_buf_map_type_list* buf_map_list)
1992 {
1993 int32_t rc = 0;
1994 cam_sock_packet_t packet;
1995 memset(&packet, 0, sizeof(cam_sock_packet_t));
1996 packet.msg_type = CAM_MAPPING_TYPE_FD_BUNDLED_MAPPING;
1997
1998 memcpy(&packet.payload.buf_map_list, buf_map_list,
1999 sizeof(packet.payload.buf_map_list));
2000
2001 int sendfds[CAM_MAX_NUM_BUFS_PER_STREAM];
2002 uint32_t numbufs = packet.payload.buf_map_list.length;
2003 uint32_t i;
2004 for (i = 0; i < numbufs; i++) {
2005 sendfds[i] = packet.payload.buf_map_list.buf_maps[i].fd;
2006 packet.payload.buf_map_list.buf_maps[i].buffer =
2007 buf_map_list->buf_maps[i].buffer;
2008 }
2009 for (i = numbufs; i < CAM_MAX_NUM_BUFS_PER_STREAM; i++) {
2010 packet.payload.buf_map_list.buf_maps[i].fd = -1;
2011 sendfds[i] = -1;
2012 }
2013
2014 #ifdef DAEMON_PRESENT
2015 rc = mm_camera_util_bundled_sendmsg(my_obj,
2016 &packet, sizeof(cam_sock_packet_t),
2017 sendfds, numbufs);
2018 #else
2019 cam_shim_packet_t *shim_cmd;
2020 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
2021 my_obj->sessionid, &packet);
2022 rc = mm_camera_module_send_cmd(shim_cmd);
2023 mm_camera_destroy_shim_cmd_packet(shim_cmd);
2024 #endif
2025
2026 pthread_mutex_unlock(&my_obj->cam_lock);
2027 return rc;
2028 }
2029
2030 /*===========================================================================
2031 * FUNCTION : mm_camera_unmap_buf
2032 *
2033 * DESCRIPTION: unmapping camera buffer via domain socket to server
2034 *
2035 * PARAMETERS :
2036 * @my_obj : camera object
2037 * @buf_type : type of buffer to be mapped. could be following values:
2038 * CAM_MAPPING_BUF_TYPE_CAPABILITY
2039 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
2040 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
2041 *
2042 * RETURN : int32_t type of status
2043 * 0 -- success
2044 * -1 -- failure
2045 *==========================================================================*/
mm_camera_unmap_buf(mm_camera_obj_t * my_obj,uint8_t buf_type)2046 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
2047 uint8_t buf_type)
2048 {
2049 int32_t rc = 0;
2050 cam_sock_packet_t packet;
2051 memset(&packet, 0, sizeof(cam_sock_packet_t));
2052 packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
2053 packet.payload.buf_unmap.type = buf_type;
2054 #ifdef DAEMON_PRESENT
2055 rc = mm_camera_util_sendmsg(my_obj,
2056 &packet,
2057 sizeof(cam_sock_packet_t),
2058 -1);
2059 #else
2060 cam_shim_packet_t *shim_cmd;
2061 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_REG_BUF,
2062 my_obj->sessionid, &packet);
2063 rc = mm_camera_module_send_cmd(shim_cmd);
2064 mm_camera_destroy_shim_cmd_packet(shim_cmd);
2065 #endif
2066 pthread_mutex_unlock(&my_obj->cam_lock);
2067 return rc;
2068 }
2069
2070 /*===========================================================================
2071 * FUNCTION : mm_camera_util_s_ctrl
2072 *
2073 * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
2074 *
2075 * PARAMETERS :
2076 * @my_obj :Camera object
2077 * @stream_id :streamID
2078 * @fd : file descritpor for sending ioctl
2079 * @id : control id
2080 * @value : value of the ioctl to be sent
2081 *
2082 * RETURN : int32_t type of status
2083 * 0 -- success
2084 * -1 -- failure
2085 *==========================================================================*/
mm_camera_util_s_ctrl(__unused mm_camera_obj_t * my_obj,__unused int stream_id,int32_t fd,uint32_t id,int32_t * value)2086 int32_t mm_camera_util_s_ctrl(__unused mm_camera_obj_t *my_obj,
2087 __unused int stream_id, int32_t fd,
2088 uint32_t id, int32_t *value)
2089 {
2090 int rc = 0;
2091
2092 #ifdef DAEMON_PRESENT
2093 struct v4l2_control control;
2094 memset(&control, 0, sizeof(control));
2095 control.id = id;
2096 if (value != NULL) {
2097 control.value = *value;
2098 }
2099 rc = ioctl(fd, VIDIOC_S_CTRL, &control);
2100 LOGD("fd=%d, S_CTRL, id=0x%x, value = %p, rc = %d\n",
2101 fd, id, value, rc);
2102 if (rc < 0) {
2103 LOGE("ioctl failed %d, errno %d", rc, errno);
2104 } else if (value != NULL) {
2105 *value = control.value;
2106 }
2107 #else /* DAEMON_PRESENT */
2108 cam_shim_packet_t *shim_cmd;
2109 cam_shim_cmd_data shim_cmd_data;
2110 (void)fd;
2111 (void)value;
2112 memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
2113
2114 shim_cmd_data.command = id;
2115 shim_cmd_data.stream_id = stream_id;
2116 shim_cmd_data.value = NULL;
2117 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_SET_PARM,
2118 my_obj->sessionid,&shim_cmd_data);
2119 rc = mm_camera_module_send_cmd(shim_cmd);
2120 mm_camera_destroy_shim_cmd_packet(shim_cmd);
2121 #endif /* DAEMON_PRESENT */
2122 return (rc >= 0)? 0 : -1;
2123 }
2124
2125 /*===========================================================================
2126 * FUNCTION : mm_camera_util_g_ctrl
2127 *
2128 * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
2129 *
2130 * PARAMETERS :
2131 * @my_obj :Camera object
2132 * @stream_id :streamID
2133 * @fd : file descritpor for sending ioctl
2134 * @id : control id
2135 * @value : value of the ioctl to be sent
2136 *
2137 * RETURN : int32_t type of status
2138 * 0 -- success
2139 * -1 -- failure
2140 *==========================================================================*/
mm_camera_util_g_ctrl(__unused mm_camera_obj_t * my_obj,__unused int stream_id,int32_t fd,uint32_t id,int32_t * value)2141 int32_t mm_camera_util_g_ctrl(__unused mm_camera_obj_t *my_obj,
2142 __unused int stream_id, int32_t fd, uint32_t id, int32_t *value)
2143 {
2144 int rc = 0;
2145 struct v4l2_control control;
2146
2147 memset(&control, 0, sizeof(control));
2148 control.id = id;
2149 if (value != NULL) {
2150 control.value = *value;
2151 }
2152
2153 #ifdef DAEMON_PRESENT
2154 rc = ioctl(fd, VIDIOC_G_CTRL, &control);
2155 LOGD("fd=%d, G_CTRL, id=0x%x, rc = %d\n", fd, id, rc);
2156 if (value != NULL) {
2157 *value = control.value;
2158 }
2159 #else /* DAEMON_PRESENT */
2160 cam_shim_packet_t *shim_cmd;
2161 cam_shim_cmd_data shim_cmd_data;
2162 (void)fd;
2163 memset(&shim_cmd_data, 0, sizeof(shim_cmd_data));
2164
2165 shim_cmd_data.command = id;
2166 shim_cmd_data.stream_id = stream_id;
2167 shim_cmd_data.value = value;
2168 shim_cmd = mm_camera_create_shim_cmd_packet(CAM_SHIM_GET_PARM,
2169 my_obj->sessionid, &shim_cmd_data);
2170
2171 rc = mm_camera_module_send_cmd(shim_cmd);
2172 mm_camera_destroy_shim_cmd_packet(shim_cmd);
2173 #endif /* DAEMON_PRESENT */
2174 return (rc >= 0)? 0 : -1;
2175 }
2176
2177 /*===========================================================================
2178 * FUNCTION : mm_camera_create_shim_cmd
2179 *
2180 * DESCRIPTION: Prepare comand packet to pass to back-end through shim layer
2181 *
2182 * PARAMETERS :
2183 * @type : type of command
2184 * @sessionID : camera sessionID
2185 * @data : command data
2186 *
2187 * RETURN : NULL in case of failures
2188 allocated pointer to shim packet
2189 *==========================================================================*/
mm_camera_create_shim_cmd_packet(cam_shim_cmd_type type,uint32_t sessionID,void * data)2190 cam_shim_packet_t *mm_camera_create_shim_cmd_packet(cam_shim_cmd_type type,
2191 uint32_t sessionID, void *data)
2192 {
2193 cam_shim_packet_t *shim_pack = NULL;
2194 uint32_t i = 0;
2195
2196 shim_pack = (cam_shim_packet_t *)malloc(sizeof(cam_shim_packet_t));
2197 if (shim_pack == NULL) {
2198 LOGE("Cannot allocate a memory for shim packet");
2199 return NULL;
2200 }
2201 memset(shim_pack, 0, sizeof(cam_shim_packet_t));
2202 shim_pack->cmd_type = type;
2203 shim_pack->session_id = sessionID;
2204 switch (type) {
2205 case CAM_SHIM_SET_PARM:
2206 case CAM_SHIM_GET_PARM: {
2207 cam_shim_cmd_data *cmd_data = (cam_shim_cmd_data *)data;
2208 shim_pack->cmd_data = *cmd_data;
2209 break;
2210 }
2211 case CAM_SHIM_REG_BUF: {
2212 cam_reg_buf_t *cmd_data = (cam_reg_buf_t *)data;
2213 shim_pack->reg_buf = *cmd_data;
2214 break;
2215 }
2216 case CAM_SHIM_BUNDLE_CMD: {
2217 cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)data;
2218 for (i = 0; i < cmd_data->stream_count; i++) {
2219 shim_pack->bundle_cmd.stream_event[i] = cmd_data->stream_event[i];
2220 }
2221 shim_pack->bundle_cmd.stream_count = cmd_data->stream_count;
2222 break;
2223 }
2224 default:
2225 LOGW("No Data for this command");
2226 }
2227 return shim_pack;
2228 }
2229
2230 /*===========================================================================
2231 * FUNCTION : mm_camera_destroy_shim_cmd
2232 *
2233 * DESCRIPTION: destroy shim packet
2234 *
2235 * PARAMETERS :
2236 * @cmd : ptr to shim packet
2237
2238 * RETURN : int32_t type of status
2239 * 0 -- success
2240 * -1 -- failure
2241 *==========================================================================*/
mm_camera_destroy_shim_cmd_packet(cam_shim_packet_t * cmd)2242 int32_t mm_camera_destroy_shim_cmd_packet(cam_shim_packet_t *cmd)
2243 {
2244 int32_t rc = 0;
2245 uint32_t i = 0, j = 0;
2246
2247 if (cmd == NULL) {
2248 LOGW("Command is NULL");
2249 return rc;
2250 }
2251
2252 switch (cmd->cmd_type) {
2253 case CAM_SHIM_SET_PARM:
2254 case CAM_SHIM_GET_PARM:
2255 case CAM_SHIM_REG_BUF:
2256 break;
2257 case CAM_SHIM_BUNDLE_CMD: {
2258 cam_shim_stream_cmd_packet_t *cmd_data = (cam_shim_stream_cmd_packet_t *)cmd;
2259 for (i = 0; i < cmd_data->stream_count; i++) {
2260 cam_shim_cmd_packet_t *stream_evt = &cmd_data->stream_event[i];
2261 for (j = 0; j < stream_evt->cmd_count; j++) {
2262 if (stream_evt->cmd != NULL) {
2263 if(stream_evt->cmd->cmd_type == CAM_SHIM_BUNDLE_CMD) {
2264 mm_camera_destroy_shim_cmd_packet(stream_evt->cmd);
2265 }
2266 free(stream_evt->cmd);
2267 stream_evt->cmd = NULL;
2268 }
2269 }
2270 }
2271 break;
2272 }
2273 default:
2274 LOGW("No Data for this command");
2275 }
2276 free(cmd);
2277 cmd = NULL;
2278 return rc;
2279 }
2280
2281 /*===========================================================================
2282 * FUNCTION : mm_camera_channel_advanced_capture
2283 *
2284 * DESCRIPTION: sets the channel advanced capture
2285 *
2286 * PARAMETERS :
2287 * @my_obj : camera object
2288 * @ch_id : channel handle
2289 * @type : advanced capture type.
2290 * @start_flag : flag to indicate start/stop
2291 * @in_value : input configaration
2292 *
2293 * RETURN : int32_t type of status
2294 * 0 -- success
2295 * -1 -- failure
2296 *==========================================================================*/
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)2297 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj,
2298 uint32_t ch_id, mm_camera_advanced_capture_t type,
2299 uint32_t trigger, void *in_value)
2300 {
2301 LOGD("E type = %d", type);
2302 int32_t rc = -1;
2303 mm_channel_t * ch_obj =
2304 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2305
2306 if (NULL != ch_obj) {
2307 pthread_mutex_lock(&ch_obj->ch_lock);
2308 pthread_mutex_unlock(&my_obj->cam_lock);
2309 switch (type) {
2310 case MM_CAMERA_AF_BRACKETING:
2311 rc = mm_channel_fsm_fn(ch_obj,
2312 MM_CHANNEL_EVT_AF_BRACKETING,
2313 (void *)&trigger,
2314 NULL);
2315 break;
2316 case MM_CAMERA_AE_BRACKETING:
2317 rc = mm_channel_fsm_fn(ch_obj,
2318 MM_CHANNEL_EVT_AE_BRACKETING,
2319 (void *)&trigger,
2320 NULL);
2321 break;
2322 case MM_CAMERA_FLASH_BRACKETING:
2323 rc = mm_channel_fsm_fn(ch_obj,
2324 MM_CHANNEL_EVT_FLASH_BRACKETING,
2325 (void *)&trigger,
2326 NULL);
2327 break;
2328 case MM_CAMERA_ZOOM_1X:
2329 rc = mm_channel_fsm_fn(ch_obj,
2330 MM_CHANNEL_EVT_ZOOM_1X,
2331 (void *)&trigger,
2332 NULL);
2333 break;
2334 case MM_CAMERA_FRAME_CAPTURE:
2335 rc = mm_channel_fsm_fn(ch_obj,
2336 MM_CAMERA_EVT_CAPTURE_SETTING,
2337 (void *)in_value,
2338 NULL);
2339 break;
2340 default:
2341 break;
2342 }
2343
2344 } else {
2345 pthread_mutex_unlock(&my_obj->cam_lock);
2346 }
2347
2348 LOGD("X");
2349 return rc;
2350 }
2351
2352 /*===========================================================================
2353 * FUNCTION : mm_camera_get_session_id
2354 *
2355 * DESCRIPTION: get the session identity
2356 *
2357 * PARAMETERS :
2358 * @my_obj : camera object
2359 * @sessionid: pointer to the output session id
2360 *
2361 * RETURN : int32_t type of status
2362 * 0 -- success
2363 * -1 -- failure
2364 * NOTE : if this call succeeds, we will get a valid session id
2365 *==========================================================================*/
mm_camera_get_session_id(mm_camera_obj_t * my_obj,uint32_t * sessionid)2366 int32_t mm_camera_get_session_id(mm_camera_obj_t *my_obj,
2367 uint32_t* sessionid)
2368 {
2369 int32_t rc = -1;
2370 int32_t value = 0;
2371 if(sessionid != NULL) {
2372 struct v4l2_control control;
2373 memset(&control, 0, sizeof(control));
2374 control.id = MSM_CAMERA_PRIV_G_SESSION_ID;
2375 control.value = value;
2376
2377 rc = ioctl(my_obj->ctrl_fd, VIDIOC_G_CTRL, &control);
2378 value = control.value;
2379 LOGD("fd=%d, get_session_id, id=0x%x, value = %d, rc = %d\n",
2380 my_obj->ctrl_fd, MSM_CAMERA_PRIV_G_SESSION_ID,
2381 value, rc);
2382 *sessionid = value;
2383 }
2384 return rc;
2385 }
2386
2387 /*===========================================================================
2388 * FUNCTION : mm_camera_set_dual_cam_cmd
2389 *
2390 * DESCRIPTION: send sync cmd
2391 *
2392 * PARAMETERS :
2393 * @my_obj : camera object
2394 *
2395 * RETURN : int32_t type of status
2396 * 0 -- success
2397 * -1 -- failure
2398 * NOTE : Assume the sync struct buf is already mapped to server via
2399 * domain socket. Corresponding fields of parameters to be set
2400 * are already filled in by upper layer caller.
2401 *==========================================================================*/
mm_camera_set_dual_cam_cmd(mm_camera_obj_t * my_obj)2402 int32_t mm_camera_set_dual_cam_cmd(mm_camera_obj_t *my_obj)
2403 {
2404 int32_t rc = -1;
2405 int32_t value = 0;
2406 rc = mm_camera_util_s_ctrl(my_obj, 0, my_obj->ctrl_fd,
2407 CAM_PRIV_DUAL_CAM_CMD, &value);
2408 pthread_mutex_unlock(&my_obj->cam_lock);
2409 return rc;
2410 }
2411
2412 /*===========================================================================
2413 * FUNCTION : mm_camera_reg_stream_buf_cb
2414 *
2415 * DESCRIPTION: Register callback for stream buffer
2416 *
2417 * PARAMETERS :
2418 * @my_obj : camera object
2419 * @ch_id : channel handle
2420 * @stream_id : stream that will be linked
2421 * @buf_cb : special callback needs to be registered for stream buffer
2422 * @cb_type : Callback type SYNC/ASYNC
2423 * @userdata : user data pointer
2424 *
2425 * RETURN : int32_t type of status
2426 * 0 -- success
2427 * 1 -- failure
2428 *==========================================================================*/
mm_camera_reg_stream_buf_cb(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_buf_notify_t stream_cb,mm_camera_stream_cb_type cb_type,void * userdata)2429 int32_t mm_camera_reg_stream_buf_cb(mm_camera_obj_t *my_obj,
2430 uint32_t ch_id, uint32_t stream_id, mm_camera_buf_notify_t stream_cb,
2431 mm_camera_stream_cb_type cb_type, void *userdata)
2432 {
2433 int rc = 0;
2434 mm_stream_data_cb_t buf_cb;
2435 mm_channel_t * ch_obj =
2436 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2437
2438 if (NULL != ch_obj) {
2439 pthread_mutex_lock(&ch_obj->ch_lock);
2440 pthread_mutex_unlock(&my_obj->cam_lock);
2441
2442 memset(&buf_cb, 0, sizeof(mm_stream_data_cb_t));
2443 buf_cb.cb = stream_cb;
2444 buf_cb.cb_count = -1;
2445 buf_cb.cb_type = cb_type;
2446 buf_cb.user_data = userdata;
2447
2448 mm_evt_paylod_reg_stream_buf_cb payload;
2449 memset(&payload, 0, sizeof(mm_evt_paylod_reg_stream_buf_cb));
2450 payload.buf_cb = buf_cb;
2451 payload.stream_id = stream_id;
2452 mm_channel_fsm_fn(ch_obj,
2453 MM_CHANNEL_EVT_REG_STREAM_BUF_CB,
2454 (void*)&payload, NULL);
2455 } else {
2456 pthread_mutex_unlock(&my_obj->cam_lock);
2457 }
2458 return rc;
2459 }
2460
2461 /*===========================================================================
2462 * FUNCTION : mm_camera_register_frame_sync
2463 *
2464 * DESCRIPTION: register/configure frame sync for this camera
2465 *
2466 * PARAMETERS :
2467 * @my_obj : camera object
2468 * @ch_id : channel handle
2469 * @stream_id : stream that will be linked
2470 * @sync_attr : attibutes for sync queue
2471 *
2472 * RETURN : int32_t type of status
2473 * 0 -- success
2474 * 1 -- failure
2475 *==========================================================================*/
mm_camera_reg_frame_sync(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_frame_sync_t * sync_attr)2476 int32_t mm_camera_reg_frame_sync(mm_camera_obj_t *my_obj,
2477 uint32_t ch_id, uint32_t stream_id,
2478 mm_camera_frame_sync_t *sync_attr)
2479 {
2480 int32_t rc = -1;
2481 uint32_t sync_id = 0;
2482 mm_evt_paylod_reg_frame_sync payload;
2483
2484 mm_channel_t *ch_obj =
2485 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2486 mm_channel_t *a_ch_obj = NULL;
2487
2488 if (sync_attr != NULL && sync_attr->a_cam_obj != NULL) {
2489 a_ch_obj = mm_camera_util_get_channel_by_handler(
2490 sync_attr->a_cam_obj, sync_attr->a_ch_id);
2491 } else {
2492 LOGE("Invalid arguments");
2493 pthread_mutex_unlock(&my_obj->cam_lock);
2494 return rc;
2495 }
2496
2497 if (NULL != ch_obj && a_ch_obj != NULL) {
2498 pthread_mutex_lock(&ch_obj->ch_lock);
2499 pthread_mutex_unlock(&my_obj->cam_lock);
2500 memset(&payload, 0, sizeof(payload));
2501 payload.stream_id = stream_id;
2502 payload.sync_attr = sync_attr;
2503 payload.a_ch_obj = a_ch_obj;
2504 rc = mm_channel_fsm_fn(ch_obj,
2505 MM_CHANNEL_EVT_REG_FRAME_SYNC,
2506 (void*)&payload, (void*)&sync_id);
2507 } else {
2508 pthread_mutex_unlock(&my_obj->cam_lock);
2509 }
2510 return rc;
2511 }
2512
2513 /*===========================================================================
2514 * FUNCTION : mm_camera_handle_frame_sync_cb
2515 *
2516 * DESCRIPTION: enable or disable callbacks in case of frame sync
2517 *
2518 * PARAMETERS :
2519 * @my_obj : camera object
2520 * @ch_id : channel handle
2521 * @stream_id : stream id
2522 *
2523 * RETURN : int32_t type of status
2524 * 0 -- success
2525 * 1 -- failure
2526 *==========================================================================*/
mm_camera_handle_frame_sync_cb(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_cb_req_type req_type)2527 int32_t mm_camera_handle_frame_sync_cb(mm_camera_obj_t *my_obj,
2528 uint32_t ch_id, uint32_t stream_id, mm_camera_cb_req_type req_type)
2529 {
2530 int rc = -1;
2531 mm_channel_t *ch_obj = NULL;
2532 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
2533
2534 if (NULL != ch_obj) {
2535 pthread_mutex_lock(&ch_obj->ch_lock);
2536 pthread_mutex_unlock(&my_obj->cam_lock);
2537 mm_evt_paylod_trigger_frame_sync payload;
2538 payload.type = req_type;
2539 payload.stream_id = stream_id;
2540 rc = mm_channel_fsm_fn(ch_obj,
2541 MM_CHANNEL_EVT_TRIGGER_FRAME_SYNC,
2542 (void*)&payload, NULL);
2543 } else {
2544 pthread_mutex_unlock(&my_obj->cam_lock);
2545 }
2546 return rc;
2547 }
2548
2549 #ifdef QCAMERA_REDEFINE_LOG
2550 /*===========================================================================
2551 * DESCRIPTION: mm camera debug interface
2552 *
2553 *==========================================================================*/
2554 pthread_mutex_t dbg_log_mutex;
2555
2556 static int cam_soft_assert = 0;
2557 static FILE *cam_log_fd = NULL;
2558 static const char *cam_log_filename = "/data/misc/camera/cam_dbg_log_hal.txt";
2559
2560 #undef LOG_TAG
2561 #define LOG_TAG "QCamera"
2562 #define CDBG_MAX_STR_LEN 1024
2563 #define CDBG_MAX_LINE_LENGTH 256
2564
2565 /* current trace loggin permissions
2566 * {NONE, ERR, WARN, HIGH, DEBUG, LOW, INFO} */
2567 int g_cam_log[CAM_LAST_MODULE][CAM_GLBL_DBG_INFO + 1] = {
2568 {0, 1, 0, 0, 0, 0, 1}, /* CAM_NO_MODULE */
2569 {0, 1, 0, 0, 0, 0, 1}, /* CAM_HAL_MODULE */
2570 {0, 1, 0, 0, 0, 0, 1}, /* CAM_MCI_MODULE */
2571 {0, 1, 0, 0, 0, 0, 1}, /* CAM_JPEG_MODULE */
2572 };
2573
2574 /* string representation for logging level */
2575 static const char *cam_dbg_level_to_str[] = {
2576 "", /* CAM_GLBL_DBG_NONE */
2577 "<ERROR>", /* CAM_GLBL_DBG_ERR */
2578 "<WARN>", /* CAM_GLBL_DBG_WARN */
2579 "<HIGH>", /* CAM_GLBL_DBG_HIGH */
2580 "<DBG>", /* CAM_GLBL_DBG_DEBUG */
2581 "<LOW>", /* CAM_GLBL_DBG_LOW */
2582 "<INFO>" /* CAM_GLBL_DBG_INFO */
2583 };
2584
2585 /* current trace logging configuration */
2586 typedef struct {
2587 cam_global_debug_level_t level;
2588 int initialized;
2589 const char *name;
2590 const char *prop;
2591 } module_debug_t;
2592
2593 static module_debug_t cam_loginfo[(int)CAM_LAST_MODULE] = {
2594 {CAM_GLBL_DBG_ERR, 1,
2595 "", "persist.camera.global.debug" }, /* CAM_NO_MODULE */
2596 {CAM_GLBL_DBG_ERR, 1,
2597 "<HAL>", "persist.camera.hal.debug" }, /* CAM_HAL_MODULE */
2598 {CAM_GLBL_DBG_ERR, 1,
2599 "<MCI>", "persist.camera.mci.debug" }, /* CAM_MCI_MODULE */
2600 {CAM_GLBL_DBG_ERR, 1,
2601 "<JPEG>", "persist.camera.mmstill.logs" }, /* CAM_JPEG_MODULE */
2602 };
2603
2604 /** cam_get_dbg_level
2605 *
2606 * @module: module name
2607 * @level: module debug logging level
2608 *
2609 * Maps debug log string to value.
2610 *
2611 * Return: logging level
2612 **/
2613 __unused
cam_get_dbg_level(const char * module,char * pValue)2614 static cam_global_debug_level_t cam_get_dbg_level(const char *module,
2615 char *pValue) {
2616
2617 cam_global_debug_level_t rc = CAM_GLBL_DBG_NONE;
2618
2619 if (!strcmp(pValue, "none")) {
2620 rc = CAM_GLBL_DBG_NONE;
2621 } else if (!strcmp(pValue, "warn")) {
2622 rc = CAM_GLBL_DBG_WARN;
2623 } else if (!strcmp(pValue, "debug")) {
2624 rc = CAM_GLBL_DBG_DEBUG;
2625 } else if (!strcmp(pValue, "error")) {
2626 rc = CAM_GLBL_DBG_ERR;
2627 } else if (!strcmp(pValue, "low")) {
2628 rc = CAM_GLBL_DBG_LOW;
2629 } else if (!strcmp(pValue, "high")) {
2630 rc = CAM_GLBL_DBG_HIGH;
2631 } else if (!strcmp(pValue, "info")) {
2632 rc = CAM_GLBL_DBG_INFO;
2633 } else {
2634 ALOGE("Invalid %s debug log level %s\n", module, pValue);
2635 }
2636
2637 ALOGD("%s debug log level: %s\n", module, cam_dbg_level_to_str[rc]);
2638
2639 return rc;
2640 }
2641
2642 /** cam_vsnprintf
2643 * @pdst: destination buffer pointer
2644 * @size: size of destination b uffer
2645 * @pfmt: string format
2646 * @argptr: variabkle length argument list
2647 *
2648 * Processes variable length argument list to a formatted string.
2649 *
2650 * Return: n/a
2651 **/
cam_vsnprintf(char * pdst,unsigned int size,const char * pfmt,va_list argptr)2652 static void cam_vsnprintf(char* pdst, unsigned int size,
2653 const char* pfmt, va_list argptr) {
2654 int num_chars_written = 0;
2655
2656 pdst[0] = '\0';
2657 num_chars_written = vsnprintf(pdst, size, pfmt, argptr);
2658
2659 if ((num_chars_written >= (int)size) && (size > 0)) {
2660 /* Message length exceeds the buffer limit size */
2661 num_chars_written = size - 1;
2662 pdst[size - 1] = '\0';
2663 }
2664 }
2665
2666 /** mm_camera_debug_log
2667 * @module: origin or log message
2668 * @level: logging level
2669 * @func: caller function name
2670 * @line: caller line number
2671 * @fmt: log message formatting string
2672 * @...: variable argument list
2673 *
2674 * Generig logger method.
2675 *
2676 * Return: N/A
2677 **/
mm_camera_debug_log(const cam_modules_t module,const cam_global_debug_level_t level,const char * func,const int line,const char * fmt,...)2678 void mm_camera_debug_log(const cam_modules_t module,
2679 const cam_global_debug_level_t level,
2680 const char *func, const int line, const char *fmt, ...) {
2681 char str_buffer[CDBG_MAX_STR_LEN];
2682 va_list args;
2683
2684 va_start(args, fmt);
2685 cam_vsnprintf(str_buffer, CDBG_MAX_STR_LEN, fmt, args);
2686 va_end(args);
2687
2688 switch (level) {
2689 case CAM_GLBL_DBG_WARN:
2690 ALOGW("%s%s %s: %d: %s", cam_loginfo[module].name,
2691 cam_dbg_level_to_str[level], func, line, str_buffer);
2692 break;
2693 case CAM_GLBL_DBG_ERR:
2694 ALOGE("%s%s %s: %d: %s", cam_loginfo[module].name,
2695 cam_dbg_level_to_str[level], func, line, str_buffer);
2696 break;
2697 case CAM_GLBL_DBG_INFO:
2698 ALOGI("%s%s %s: %d: %s", cam_loginfo[module].name,
2699 cam_dbg_level_to_str[level], func, line, str_buffer);
2700 break;
2701 case CAM_GLBL_DBG_HIGH:
2702 case CAM_GLBL_DBG_DEBUG:
2703 case CAM_GLBL_DBG_LOW:
2704 default:
2705 ALOGD("%s%s %s: %d: %s", cam_loginfo[module].name,
2706 cam_dbg_level_to_str[level], func, line, str_buffer);
2707 }
2708
2709
2710 if (cam_log_fd != NULL) {
2711 char new_str_buffer[CDBG_MAX_STR_LEN];
2712 pthread_mutex_lock(&dbg_log_mutex);
2713
2714 struct timeval tv;
2715 struct timezone tz;
2716 gettimeofday(&tv, &tz);
2717
2718 struct tm *now;
2719 now = gmtime((time_t *)&tv.tv_sec);
2720 if (now != NULL) {
2721 snprintf(new_str_buffer, CDBG_MAX_STR_LEN,
2722 "%2d %02d:%02d:%02d.%03ld %d:%d Camera%s%s %d: %s: %s", now->tm_mday,
2723 now->tm_hour, now->tm_min, now->tm_sec, tv.tv_usec, getpid(),gettid(),
2724 cam_dbg_level_to_str[level], cam_loginfo[module].name,
2725 line, func, str_buffer);
2726 fprintf(cam_log_fd, "%s", new_str_buffer);
2727 } else {
2728 LOGE("Invalid gmtime");
2729 }
2730 pthread_mutex_unlock(&dbg_log_mutex);
2731 }
2732
2733 }
2734
2735 /** mm_camera_set_dbg_log_properties
2736 *
2737 * Set global and module log level properties.
2738 *
2739 * Return: N/A
2740 **/
mm_camera_set_dbg_log_properties(void)2741 void mm_camera_set_dbg_log_properties(void) {
2742 int i;
2743 unsigned int j;
2744 char property_value[PROPERTY_VALUE_MAX] = {0};
2745 char default_value[PROPERTY_VALUE_MAX] = {0};
2746
2747 /* set global and individual module logging levels */
2748 pthread_mutex_lock(&dbg_log_mutex);
2749 for (i = CAM_NO_MODULE; i < CAM_LAST_MODULE; i++) {
2750 cam_global_debug_level_t log_level;
2751 snprintf(default_value, PROPERTY_VALUE_MAX, "%d", (int)cam_loginfo[i].level);
2752 property_get(cam_loginfo[i].prop, property_value, default_value);
2753 log_level = (cam_global_debug_level_t)atoi(property_value);
2754
2755 /* fix KW warnings */
2756 if (log_level > CAM_GLBL_DBG_INFO) {
2757 log_level = CAM_GLBL_DBG_INFO;
2758 }
2759
2760 cam_loginfo[i].level = log_level;
2761
2762 /* The logging macros will produce a log message when logging level for
2763 * a module is less or equal to the level specified in the property for
2764 * the module, or less or equal the level specified by the global logging
2765 * property. Currently we don't allow INFO logging to be turned off */
2766 for (j = CAM_GLBL_DBG_ERR; j <= CAM_GLBL_DBG_LOW; j++) {
2767 g_cam_log[i][j] = (cam_loginfo[CAM_NO_MODULE].level != CAM_GLBL_DBG_NONE) &&
2768 (cam_loginfo[i].level != CAM_GLBL_DBG_NONE) &&
2769 ((j <= cam_loginfo[i].level) ||
2770 (j <= cam_loginfo[CAM_NO_MODULE].level));
2771 }
2772 }
2773 pthread_mutex_unlock(&dbg_log_mutex);
2774 }
2775
2776 /** mm_camera_debug_open
2777 *
2778 * Open log file if it is enabled
2779 *
2780 * Return: N/A
2781 **/
mm_camera_debug_open(void)2782 void mm_camera_debug_open(void) {
2783 char property_value[PROPERTY_VALUE_MAX] = {0};
2784
2785 pthread_mutex_init(&dbg_log_mutex, 0);
2786 mm_camera_set_dbg_log_properties();
2787
2788 /* configure asserts */
2789 property_get("persist.camera.debug.assert", property_value, "0");
2790 cam_soft_assert = atoi(property_value);
2791
2792 /* open default log file according to property setting */
2793 if (cam_log_fd == NULL) {
2794 property_get("persist.camera.debug.logfile", property_value, "0");
2795 if (atoi(property_value)) {
2796 /* we always put the current process id at end of log file name */
2797 char pid_str[255] = {0};
2798 char new_log_file_name[1024] = {0};
2799
2800 snprintf(pid_str, 255, "_%d", getpid());
2801 strlcpy(new_log_file_name, cam_log_filename, sizeof(new_log_file_name));
2802 strlcat(new_log_file_name, pid_str, sizeof(new_log_file_name));
2803
2804 cam_log_fd = fopen(new_log_file_name, "a");
2805 if (cam_log_fd == NULL) {
2806 ALOGE("Failed to create debug log file %s\n",
2807 new_log_file_name);
2808 } else {
2809 ALOGD("Debug log file %s open\n", new_log_file_name);
2810 }
2811 } else {
2812 property_set("persist.camera.debug.logfile", "0");
2813 ALOGD("Debug log file is not enabled");
2814 return;
2815 }
2816 }
2817 }
2818
2819 /** cam_debug_close
2820 *
2821 * Release logging resources.
2822 *
2823 * Return: N/A
2824 **/
mm_camera_debug_close(void)2825 void mm_camera_debug_close(void) {
2826
2827 if (cam_log_fd != NULL) {
2828 fclose(cam_log_fd);
2829 cam_log_fd = NULL;
2830 }
2831
2832 pthread_mutex_destroy(&dbg_log_mutex);
2833 }
2834 #endif
2835