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