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