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