1 /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #include <pthread.h>
31 #include <errno.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <poll.h>
37
38 #include <cam_semaphore.h>
39
40 #include "mm_camera_dbg.h"
41 #include "mm_camera_sock.h"
42 #include "mm_camera_interface.h"
43 #include "mm_camera.h"
44
45 #define SET_PARM_BIT32(parm, parm_arr) \
46 (parm_arr[parm/32] |= (1<<(parm%32)))
47
48 #define GET_PARM_BIT32(parm, parm_arr) \
49 ((parm_arr[parm/32]>>(parm%32))& 0x1)
50
51 /* internal function declare */
52 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
53 uint8_t reg_flag);
54 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
55 mm_camera_event_t *event);
56
57 /*===========================================================================
58 * FUNCTION : mm_camera_util_get_channel_by_handler
59 *
60 * DESCRIPTION: utility function to get a channel object from its handle
61 *
62 * PARAMETERS :
63 * @cam_obj: ptr to a camera object
64 * @handler: channel handle
65 *
66 * RETURN : ptr to a channel object.
67 * NULL if failed.
68 *==========================================================================*/
mm_camera_util_get_channel_by_handler(mm_camera_obj_t * cam_obj,uint32_t handler)69 mm_channel_t * mm_camera_util_get_channel_by_handler(
70 mm_camera_obj_t * cam_obj,
71 uint32_t handler)
72 {
73 int i;
74 mm_channel_t *ch_obj = NULL;
75 for(i = 0; i < MM_CAMERA_CHANNEL_MAX; i++) {
76 if (handler == cam_obj->ch[i].my_hdl) {
77 ch_obj = &cam_obj->ch[i];
78 break;
79 }
80 }
81 return ch_obj;
82 }
83
84 /*===========================================================================
85 * FUNCTION : mm_camera_util_chip_is_a_family
86 *
87 * DESCRIPTION: utility function to check if the host is A family chip
88 *
89 * PARAMETERS :
90 *
91 * RETURN : TRUE if A family.
92 * FALSE otherwise.
93 *==========================================================================*/
mm_camera_util_chip_is_a_family(void)94 uint8_t mm_camera_util_chip_is_a_family(void)
95 {
96 #ifdef USE_A_FAMILY
97 return TRUE;
98 #else
99 return FALSE;
100 #endif
101 }
102
103 /*===========================================================================
104 * FUNCTION : mm_camera_dispatch_app_event
105 *
106 * DESCRIPTION: dispatch event to apps who regitster for event notify
107 *
108 * PARAMETERS :
109 * @cmd_cb: ptr to a struct storing event info
110 * @user_data: user data ptr (camera object)
111 *
112 * RETURN : none
113 *==========================================================================*/
mm_camera_dispatch_app_event(mm_camera_cmdcb_t * cmd_cb,void * user_data)114 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
115 void* user_data)
116 {
117 mm_camera_cmd_thread_name("mm_cam_event");
118 int i;
119 mm_camera_event_t *event = &cmd_cb->u.evt;
120 mm_camera_obj_t * my_obj = (mm_camera_obj_t *)user_data;
121 if (NULL != my_obj) {
122 pthread_mutex_lock(&my_obj->cb_lock);
123 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
124 if(my_obj->evt.evt[i].evt_cb) {
125 my_obj->evt.evt[i].evt_cb(
126 my_obj->my_hdl,
127 event,
128 my_obj->evt.evt[i].user_data);
129 }
130 }
131 pthread_mutex_unlock(&my_obj->cb_lock);
132 }
133 }
134
135 /*===========================================================================
136 * FUNCTION : mm_camera_event_notify
137 *
138 * DESCRIPTION: callback to handle event notify from kernel. This call will
139 * dequeue event from kernel.
140 *
141 * PARAMETERS :
142 * @user_data: user data ptr (camera object)
143 *
144 * RETURN : none
145 *==========================================================================*/
mm_camera_event_notify(void * user_data)146 static void mm_camera_event_notify(void* user_data)
147 {
148 struct v4l2_event ev;
149 struct msm_v4l2_event_data *msm_evt = NULL;
150 int rc;
151 mm_camera_event_t evt;
152 memset(&evt, 0, sizeof(mm_camera_event_t));
153
154 mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
155 if (NULL != my_obj) {
156 /* read evt */
157 memset(&ev, 0, sizeof(ev));
158 rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
159
160 if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
161 msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
162 switch (msm_evt->command) {
163 case CAM_EVENT_TYPE_DAEMON_PULL_REQ:
164 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_PULL_REQ;
165 mm_camera_enqueue_evt(my_obj, &evt);
166 break;
167 case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
168 pthread_mutex_lock(&my_obj->evt_lock);
169 my_obj->evt_rcvd.server_event_type = msm_evt->command;
170 my_obj->evt_rcvd.status = msm_evt->status;
171 pthread_cond_signal(&my_obj->evt_cond);
172 pthread_mutex_unlock(&my_obj->evt_lock);
173 break;
174 case MSM_CAMERA_PRIV_SHUTDOWN:
175 {
176 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
177 mm_camera_enqueue_evt(my_obj, &evt);
178 }
179 break;
180 default:
181 break;
182 }
183 }
184 }
185 }
186
187 /*===========================================================================
188 * FUNCTION : mm_camera_enqueue_evt
189 *
190 * DESCRIPTION: enqueue received event into event queue to be processed by
191 * event thread.
192 *
193 * PARAMETERS :
194 * @my_obj : ptr to a camera object
195 * @event : event to be queued
196 *
197 * RETURN : int32_t type of status
198 * 0 -- success
199 * -1 -- failure
200 *==========================================================================*/
mm_camera_enqueue_evt(mm_camera_obj_t * my_obj,mm_camera_event_t * event)201 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
202 mm_camera_event_t *event)
203 {
204 int32_t rc = 0;
205 mm_camera_cmdcb_t *node = NULL;
206
207 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
208 if (NULL != node) {
209 memset(node, 0, sizeof(mm_camera_cmdcb_t));
210 node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
211 node->u.evt = *event;
212
213 /* enqueue to evt cmd thread */
214 cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
215 /* wake up evt cmd thread */
216 cam_sem_post(&(my_obj->evt_thread.cmd_sem));
217 } else {
218 CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
219 rc = -1;
220 }
221
222 return rc;
223 }
224
225 /*===========================================================================
226 * FUNCTION : mm_camera_open
227 *
228 * DESCRIPTION: open a camera
229 *
230 * PARAMETERS :
231 * @my_obj : ptr to a camera object
232 *
233 * RETURN : int32_t type of status
234 * 0 -- success
235 * -1 -- failure
236 *==========================================================================*/
mm_camera_open(mm_camera_obj_t * my_obj)237 int32_t mm_camera_open(mm_camera_obj_t *my_obj)
238 {
239 char dev_name[MM_CAMERA_DEV_NAME_LEN];
240 int32_t rc = 0;
241 int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
242 uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
243 unsigned int cam_idx = 0;
244
245 CDBG("%s: begin\n", __func__);
246
247 if (NULL == my_obj) {
248 goto on_error;
249 }
250 snprintf(dev_name, sizeof(dev_name), "/dev/%s",
251 mm_camera_util_get_dev_name(my_obj->my_hdl));
252 sscanf(dev_name, "/dev/video%u", &cam_idx);
253 CDBG_HIGH("%s: dev name = %s, cam_idx = %d", __func__, dev_name, cam_idx);
254
255 do{
256 n_try--;
257 errno = 0;
258 my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
259 CDBG("%s: ctrl_fd = %d, errno == %d", __func__, my_obj->ctrl_fd, errno);
260 if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) {
261 CDBG_HIGH("%s: opened, break out while loop", __func__);
262 break;
263 }
264 ALOGE("%s:Failed with %s error, retrying after %d milli-seconds",
265 __func__, strerror(errno), sleep_msec);
266 usleep(sleep_msec * 1000);
267 }while (n_try > 0);
268
269 if (my_obj->ctrl_fd < 0) {
270 CDBG_ERROR("%s: cannot open control fd of '%s' (%s)\n",
271 __func__, dev_name, strerror(errno));
272 rc = -1;
273 goto on_error;
274 }
275
276 /* open domain socket*/
277 n_try = MM_CAMERA_DEV_OPEN_TRIES;
278 do {
279 n_try--;
280 my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
281 CDBG("%s: ds_fd = %d, errno = %d", __func__, my_obj->ds_fd, errno);
282 if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {
283 CDBG("%s: opened, break out while loop", __func__);
284 break;
285 }
286 CDBG("%s:failed with I/O error retrying after %d milli-seconds",
287 __func__, sleep_msec);
288 usleep(sleep_msec * 1000);
289 } while (n_try > 0);
290
291 if (my_obj->ds_fd < 0) {
292 CDBG_ERROR("%s: cannot open domain socket fd of '%s'(%s)\n",
293 __func__, dev_name, strerror(errno));
294 rc = -1;
295 goto on_error;
296 }
297 pthread_mutex_init(&my_obj->msg_lock, NULL);
298
299 pthread_mutex_init(&my_obj->cb_lock, NULL);
300 pthread_mutex_init(&my_obj->evt_lock, NULL);
301 pthread_cond_init(&my_obj->evt_cond, NULL);
302
303 CDBG("%s : Launch evt Thread in Cam Open",__func__);
304 mm_camera_cmd_thread_launch(&my_obj->evt_thread,
305 mm_camera_dispatch_app_event,
306 (void *)my_obj);
307
308 /* launch event poll thread
309 * we will add evt fd into event poll thread upon user first register for evt */
310 CDBG("%s : Launch evt Poll Thread in Cam Open", __func__);
311 mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
312 MM_CAMERA_POLL_TYPE_EVT);
313 mm_camera_evt_sub(my_obj, TRUE);
314
315 CDBG("%s: end (rc = %d)\n", __func__, rc);
316 /* we do not need to unlock cam_lock here before return
317 * because for open, it's done within intf_lock */
318 return rc;
319
320 on_error:
321 if (NULL == my_obj) {
322 CDBG_ERROR("%s: Invalid camera object\n", __func__);
323 rc = -1;
324 } else {
325 if (my_obj->ctrl_fd >= 0) {
326 close(my_obj->ctrl_fd);
327 my_obj->ctrl_fd = -1;
328 }
329 if (my_obj->ds_fd >= 0) {
330 mm_camera_socket_close(my_obj->ds_fd);
331 my_obj->ds_fd = -1;
332 }
333 }
334
335 /* we do not need to unlock cam_lock here before return
336 * because for open, it's done within intf_lock */
337 return rc;
338 }
339
340 /*===========================================================================
341 * FUNCTION : mm_camera_close
342 *
343 * DESCRIPTION: enqueue received event into event queue to be processed by
344 * event thread.
345 *
346 * PARAMETERS :
347 * @my_obj : ptr to a camera object
348 * @event : event to be queued
349 *
350 * RETURN : int32_t type of status
351 * 0 -- success
352 * -1 -- failure
353 *==========================================================================*/
mm_camera_close(mm_camera_obj_t * my_obj)354 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
355 {
356 CDBG("%s : unsubscribe evt", __func__);
357 mm_camera_evt_sub(my_obj, FALSE);
358
359 CDBG("%s : Close evt Poll Thread in Cam Close",__func__);
360 mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
361
362 CDBG("%s : Close evt cmd Thread in Cam Close",__func__);
363 mm_camera_cmd_thread_release(&my_obj->evt_thread);
364
365 if(my_obj->ctrl_fd >= 0) {
366 close(my_obj->ctrl_fd);
367 my_obj->ctrl_fd = -1;
368 }
369 if(my_obj->ds_fd >= 0) {
370 mm_camera_socket_close(my_obj->ds_fd);
371 my_obj->ds_fd = -1;
372 }
373 pthread_mutex_destroy(&my_obj->msg_lock);
374
375 pthread_mutex_destroy(&my_obj->cb_lock);
376 pthread_mutex_destroy(&my_obj->evt_lock);
377 pthread_cond_destroy(&my_obj->evt_cond);
378
379 pthread_mutex_unlock(&my_obj->cam_lock);
380 return 0;
381 }
382
383 /*===========================================================================
384 * FUNCTION : mm_camera_close_fd
385 *
386 * DESCRIPTION: close the ctrl_fd and socket fd in case of an error so that
387 * the backend will close
388 * Do NOT close or release any HAL resources since a close_camera
389 * has not been called yet.
390 * PARAMETERS :
391 * @my_obj : ptr to a camera object
392 * @event : event to be queued
393 *
394 * RETURN : int32_t type of status
395 * 0 -- success
396 * -1 -- failure
397 *==========================================================================*/
mm_camera_close_fd(mm_camera_obj_t * my_obj)398 int32_t mm_camera_close_fd(mm_camera_obj_t *my_obj)
399 {
400 if(my_obj->ctrl_fd >= 0) {
401 close(my_obj->ctrl_fd);
402 my_obj->ctrl_fd = -1;
403 }
404 if(my_obj->ds_fd >= 0) {
405 mm_camera_socket_close(my_obj->ds_fd);
406 my_obj->ds_fd = -1;
407 }
408 pthread_mutex_unlock(&my_obj->cam_lock);
409 return 0;
410 }
411
412 /*===========================================================================
413 * FUNCTION : mm_camera_register_event_notify_internal
414 *
415 * DESCRIPTION: internal implementation for registering callback for event notify.
416 *
417 * PARAMETERS :
418 * @my_obj : ptr to a camera object
419 * @evt_cb : callback to be registered to handle event notify
420 * @user_data: user data ptr
421 *
422 * RETURN : int32_t type of status
423 * 0 -- success
424 * -1 -- failure
425 *==========================================================================*/
mm_camera_register_event_notify_internal(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)426 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
427 mm_camera_event_notify_t evt_cb,
428 void * user_data)
429 {
430 int i;
431 int rc = -1;
432 mm_camera_evt_obj_t *evt_array = NULL;
433
434 pthread_mutex_lock(&my_obj->cb_lock);
435 evt_array = &my_obj->evt;
436 if(evt_cb) {
437 /* this is reg case */
438 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
439 if(evt_array->evt[i].user_data == NULL) {
440 evt_array->evt[i].evt_cb = evt_cb;
441 evt_array->evt[i].user_data = user_data;
442 evt_array->reg_count++;
443 rc = 0;
444 break;
445 }
446 }
447 } else {
448 /* this is unreg case */
449 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
450 if(evt_array->evt[i].user_data == user_data) {
451 evt_array->evt[i].evt_cb = NULL;
452 evt_array->evt[i].user_data = NULL;
453 evt_array->reg_count--;
454 rc = 0;
455 break;
456 }
457 }
458 }
459
460 pthread_mutex_unlock(&my_obj->cb_lock);
461 return rc;
462 }
463
464 /*===========================================================================
465 * FUNCTION : mm_camera_register_event_notify
466 *
467 * DESCRIPTION: registering a callback for event notify.
468 *
469 * PARAMETERS :
470 * @my_obj : ptr to a camera object
471 * @evt_cb : callback to be registered to handle event notify
472 * @user_data: user data ptr
473 *
474 * RETURN : int32_t type of status
475 * 0 -- success
476 * -1 -- failure
477 *==========================================================================*/
mm_camera_register_event_notify(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)478 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
479 mm_camera_event_notify_t evt_cb,
480 void * user_data)
481 {
482 int rc = -1;
483 rc = mm_camera_register_event_notify_internal(my_obj,
484 evt_cb,
485 user_data);
486 pthread_mutex_unlock(&my_obj->cam_lock);
487 return rc;
488 }
489
490 /*===========================================================================
491 * FUNCTION : mm_camera_qbuf
492 *
493 * DESCRIPTION: enqueue buffer back to kernel
494 *
495 * PARAMETERS :
496 * @my_obj : camera object
497 * @ch_id : channel handle
498 * @buf : buf ptr to be enqueued
499 *
500 * RETURN : int32_t type of status
501 * 0 -- success
502 * -1 -- failure
503 *==========================================================================*/
mm_camera_qbuf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_buf_def_t * buf)504 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
505 uint32_t ch_id,
506 mm_camera_buf_def_t *buf)
507 {
508 int rc = -1;
509 mm_channel_t * ch_obj = NULL;
510 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
511
512 pthread_mutex_unlock(&my_obj->cam_lock);
513
514 /* we always assume qbuf will be done before channel/stream is fully stopped
515 * because qbuf is done within dataCB context
516 * in order to avoid deadlock, we are not locking ch_lock for qbuf */
517 if (NULL != ch_obj) {
518 rc = mm_channel_qbuf(ch_obj, buf);
519 }
520
521 return rc;
522 }
523
524 /*===========================================================================
525 * FUNCTION : mm_camera_query_capability
526 *
527 * DESCRIPTION: query camera capability
528 *
529 * PARAMETERS :
530 * @my_obj: camera object
531 *
532 * RETURN : int32_t type of status
533 * 0 -- success
534 * -1 -- failure
535 *==========================================================================*/
mm_camera_query_capability(mm_camera_obj_t * my_obj)536 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
537 {
538 int32_t rc = 0;
539 struct v4l2_capability cap;
540
541 /* get camera capabilities */
542 memset(&cap, 0, sizeof(cap));
543 rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
544 if (rc != 0) {
545 CDBG_ERROR("%s: cannot get camera capabilities, rc = %d\n", __func__, rc);
546 }
547
548 pthread_mutex_unlock(&my_obj->cam_lock);
549 return rc;
550
551 }
552
553 /*===========================================================================
554 * FUNCTION : mm_camera_set_parms
555 *
556 * DESCRIPTION: set parameters per camera
557 *
558 * PARAMETERS :
559 * @my_obj : camera object
560 * @parms : ptr to a param struct to be set to server
561 *
562 * RETURN : int32_t type of status
563 * 0 -- success
564 * -1 -- failure
565 * NOTE : Assume the parms struct buf is already mapped to server via
566 * domain socket. Corresponding fields of parameters to be set
567 * are already filled in by upper layer caller.
568 *==========================================================================*/
mm_camera_set_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)569 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj,
570 parm_buffer_t *parms)
571 {
572 int32_t rc = -1;
573 int32_t value = 0;
574 if (parms != NULL) {
575 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
576 }
577 pthread_mutex_unlock(&my_obj->cam_lock);
578 return rc;
579 }
580
581 /*===========================================================================
582 * FUNCTION : mm_camera_get_parms
583 *
584 * DESCRIPTION: get parameters per camera
585 *
586 * PARAMETERS :
587 * @my_obj : camera object
588 * @parms : ptr to a param struct to be get from server
589 *
590 * RETURN : int32_t type of status
591 * 0 -- success
592 * -1 -- failure
593 * NOTE : Assume the parms struct buf is already mapped to server via
594 * domain socket. Parameters to be get from server are already
595 * filled in by upper layer caller. After this call, corresponding
596 * fields of requested parameters will be filled in by server with
597 * detailed information.
598 *==========================================================================*/
mm_camera_get_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)599 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
600 parm_buffer_t *parms)
601 {
602 int32_t rc = -1;
603 int32_t value = 0;
604 if (parms != NULL) {
605 rc = mm_camera_util_g_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
606 }
607 pthread_mutex_unlock(&my_obj->cam_lock);
608 return rc;
609 }
610
611 /*===========================================================================
612 * FUNCTION : mm_camera_do_auto_focus
613 *
614 * DESCRIPTION: performing auto focus
615 *
616 * PARAMETERS :
617 * @camera_handle: camera handle
618 *
619 * RETURN : int32_t type of status
620 * 0 -- success
621 * -1 -- failure
622 * NOTE : if this call success, we will always assume there will
623 * be an auto_focus event following up.
624 *==========================================================================*/
mm_camera_do_auto_focus(mm_camera_obj_t * my_obj)625 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
626 {
627 int32_t rc = -1;
628 int32_t value = 0;
629 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
630 pthread_mutex_unlock(&my_obj->cam_lock);
631 return rc;
632 }
633
634 /*===========================================================================
635 * FUNCTION : mm_camera_cancel_auto_focus
636 *
637 * DESCRIPTION: cancel auto focus
638 *
639 * PARAMETERS :
640 * @camera_handle: camera handle
641 *
642 * RETURN : int32_t type of status
643 * 0 -- success
644 * -1 -- failure
645 *==========================================================================*/
mm_camera_cancel_auto_focus(mm_camera_obj_t * my_obj)646 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
647 {
648 int32_t rc = -1;
649 int32_t value = 0;
650 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
651 pthread_mutex_unlock(&my_obj->cam_lock);
652 return rc;
653 }
654
655 /*===========================================================================
656 * FUNCTION : mm_camera_prepare_snapshot
657 *
658 * DESCRIPTION: prepare hardware for snapshot
659 *
660 * PARAMETERS :
661 * @my_obj : camera object
662 * @do_af_flag : flag indicating if AF is needed
663 *
664 * RETURN : int32_t type of status
665 * 0 -- success
666 * -1 -- failure
667 *==========================================================================*/
mm_camera_prepare_snapshot(mm_camera_obj_t * my_obj,int32_t do_af_flag)668 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
669 int32_t do_af_flag)
670 {
671 int32_t rc = -1;
672 int32_t value = do_af_flag;
673 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
674 pthread_mutex_unlock(&my_obj->cam_lock);
675 return rc;
676 }
677
678 /*===========================================================================
679 * FUNCTION : mm_camera_start_zsl_snapshot
680 *
681 * DESCRIPTION: start zsl snapshot
682 *
683 * PARAMETERS :
684 * @my_obj : camera object
685 *
686 * RETURN : int32_t type of status
687 * 0 -- success
688 * -1 -- failure
689 *==========================================================================*/
mm_camera_start_zsl_snapshot(mm_camera_obj_t * my_obj)690 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
691 {
692 int32_t rc = -1;
693 int32_t value = 0;
694
695 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
696 CAM_PRIV_START_ZSL_SNAPSHOT, &value);
697 return rc;
698 }
699
700 /*===========================================================================
701 * FUNCTION : mm_camera_stop_zsl_snapshot
702 *
703 * DESCRIPTION: stop zsl capture
704 *
705 * PARAMETERS :
706 * @my_obj : camera object
707 *
708 * RETURN : int32_t type of status
709 * 0 -- success
710 * -1 -- failure
711 *==========================================================================*/
mm_camera_stop_zsl_snapshot(mm_camera_obj_t * my_obj)712 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
713 {
714 int32_t rc = -1;
715 int32_t value;
716 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
717 CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
718 return rc;
719 }
720
721 /*===========================================================================
722 * FUNCTION : mm_camera_add_channel
723 *
724 * DESCRIPTION: add a channel
725 *
726 * PARAMETERS :
727 * @my_obj : camera object
728 * @attr : bundle attribute of the channel if needed
729 * @channel_cb : callback function for bundle data notify
730 * @userdata : user data ptr
731 *
732 * RETURN : uint32_t type of channel handle
733 * 0 -- invalid channel handle, meaning the op failed
734 * >0 -- successfully added a channel with a valid handle
735 * NOTE : if no bundle data notify is needed, meaning each stream in the
736 * channel will have its own stream data notify callback, then
737 * attr, channel_cb, and userdata can be NULL. In this case,
738 * no matching logic will be performed in channel for the bundling.
739 *==========================================================================*/
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)740 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
741 mm_camera_channel_attr_t *attr,
742 mm_camera_buf_notify_t channel_cb,
743 void *userdata)
744 {
745 mm_channel_t *ch_obj = NULL;
746 uint8_t ch_idx = 0;
747 uint32_t ch_hdl = 0;
748
749 for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
750 if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
751 ch_obj = &my_obj->ch[ch_idx];
752 break;
753 }
754 }
755
756 if (NULL != ch_obj) {
757 /* initialize channel obj */
758 memset(ch_obj, 0, sizeof(mm_channel_t));
759 ch_hdl = mm_camera_util_generate_handler(ch_idx);
760 ch_obj->my_hdl = ch_hdl;
761 ch_obj->state = MM_CHANNEL_STATE_STOPPED;
762 ch_obj->cam_obj = my_obj;
763 pthread_mutex_init(&ch_obj->ch_lock, NULL);
764 mm_channel_init(ch_obj, attr, channel_cb, userdata);
765 }
766
767 pthread_mutex_unlock(&my_obj->cam_lock);
768
769 return ch_hdl;
770 }
771
772 /*===========================================================================
773 * FUNCTION : mm_camera_del_channel
774 *
775 * DESCRIPTION: delete a channel by its handle
776 *
777 * PARAMETERS :
778 * @my_obj : camera object
779 * @ch_id : channel handle
780 *
781 * RETURN : int32_t type of status
782 * 0 -- success
783 * -1 -- failure
784 * NOTE : all streams in the channel should be stopped already before
785 * this channel can be deleted.
786 *==========================================================================*/
mm_camera_del_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)787 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
788 uint32_t ch_id)
789 {
790 int32_t rc = -1;
791 mm_channel_t * ch_obj =
792 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
793
794 if (NULL != ch_obj) {
795 pthread_mutex_lock(&ch_obj->ch_lock);
796 pthread_mutex_unlock(&my_obj->cam_lock);
797
798 rc = mm_channel_fsm_fn(ch_obj,
799 MM_CHANNEL_EVT_DELETE,
800 NULL,
801 NULL);
802
803 pthread_mutex_destroy(&ch_obj->ch_lock);
804 memset(ch_obj, 0, sizeof(mm_channel_t));
805 } else {
806 pthread_mutex_unlock(&my_obj->cam_lock);
807 }
808 return rc;
809 }
810
811 /*===========================================================================
812 * FUNCTION : mm_camera_get_bundle_info
813 *
814 * DESCRIPTION: query bundle info of the channel
815 *
816 * PARAMETERS :
817 * @my_obj : camera object
818 * @ch_id : channel handle
819 * @bundle_info : bundle info to be filled in
820 *
821 * RETURN : int32_t type of status
822 * 0 -- success
823 * -1 -- failure
824 * NOTE : all streams in the channel should be stopped already before
825 * this channel can be deleted.
826 *==========================================================================*/
mm_camera_get_bundle_info(mm_camera_obj_t * my_obj,uint32_t ch_id,cam_bundle_config_t * bundle_info)827 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
828 uint32_t ch_id,
829 cam_bundle_config_t *bundle_info)
830 {
831 int32_t rc = -1;
832 mm_channel_t * ch_obj =
833 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
834
835 if (NULL != ch_obj) {
836 pthread_mutex_lock(&ch_obj->ch_lock);
837 pthread_mutex_unlock(&my_obj->cam_lock);
838
839 rc = mm_channel_fsm_fn(ch_obj,
840 MM_CHANNEL_EVT_GET_BUNDLE_INFO,
841 (void *)bundle_info,
842 NULL);
843 } else {
844 pthread_mutex_unlock(&my_obj->cam_lock);
845 }
846 return rc;
847 }
848
849 /*===========================================================================
850 * FUNCTION : mm_camera_add_stream
851 *
852 * DESCRIPTION: add a stream into a channel
853 *
854 * PARAMETERS :
855 * @my_obj : camera object
856 * @ch_id : channel handle
857 *
858 * RETURN : uint32_t type of stream handle
859 * 0 -- invalid stream handle, meaning the op failed
860 * >0 -- successfully added a stream with a valid handle
861 *==========================================================================*/
mm_camera_add_stream(mm_camera_obj_t * my_obj,uint32_t ch_id)862 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
863 uint32_t ch_id)
864 {
865 uint32_t s_hdl = 0;
866 mm_channel_t * ch_obj =
867 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
868
869 if (NULL != ch_obj) {
870 pthread_mutex_lock(&ch_obj->ch_lock);
871 pthread_mutex_unlock(&my_obj->cam_lock);
872
873 mm_channel_fsm_fn(ch_obj,
874 MM_CHANNEL_EVT_ADD_STREAM,
875 NULL,
876 (void*)&s_hdl);
877 } else {
878 pthread_mutex_unlock(&my_obj->cam_lock);
879 }
880
881 return s_hdl;
882 }
883
884 /*===========================================================================
885 * FUNCTION : mm_camera_del_stream
886 *
887 * DESCRIPTION: delete a stream by its handle
888 *
889 * PARAMETERS :
890 * @my_obj : camera object
891 * @ch_id : channel handle
892 * @stream_id : stream handle
893 *
894 * RETURN : int32_t type of status
895 * 0 -- success
896 * -1 -- failure
897 * NOTE : stream should be stopped already before it can be deleted.
898 *==========================================================================*/
mm_camera_del_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)899 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
900 uint32_t ch_id,
901 uint32_t stream_id)
902 {
903 int32_t rc = -1;
904 mm_channel_t * ch_obj =
905 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
906
907 if (NULL != ch_obj) {
908 pthread_mutex_lock(&ch_obj->ch_lock);
909 pthread_mutex_unlock(&my_obj->cam_lock);
910
911 rc = mm_channel_fsm_fn(ch_obj,
912 MM_CHANNEL_EVT_DEL_STREAM,
913 (void*)stream_id,
914 NULL);
915 } else {
916 pthread_mutex_unlock(&my_obj->cam_lock);
917 }
918
919 return rc;
920 }
921
922 /*===========================================================================
923 * FUNCTION : mm_camera_start_zsl_snapshot_ch
924 *
925 * DESCRIPTION: starts zsl snapshot for specific channel
926 *
927 * PARAMETERS :
928 * @my_obj : camera object
929 * @ch_id : channel handle
930 *
931 * RETURN : int32_t type of status
932 * 0 -- success
933 * -1 -- failure
934 *==========================================================================*/
mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)935 int32_t mm_camera_start_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
936 uint32_t ch_id)
937 {
938 int32_t rc = -1;
939 mm_channel_t * ch_obj =
940 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
941
942 if (NULL != ch_obj) {
943 pthread_mutex_lock(&ch_obj->ch_lock);
944 pthread_mutex_unlock(&my_obj->cam_lock);
945
946 rc = mm_channel_fsm_fn(ch_obj,
947 MM_CHANNEL_EVT_START_ZSL_SNAPSHOT,
948 NULL,
949 NULL);
950 } else {
951 pthread_mutex_unlock(&my_obj->cam_lock);
952 }
953
954 return rc;
955 }
956
957 /*===========================================================================
958 * FUNCTION : mm_camera_stop_zsl_snapshot_ch
959 *
960 * DESCRIPTION: stops zsl snapshot for specific channel
961 *
962 * PARAMETERS :
963 * @my_obj : camera object
964 * @ch_id : channel handle
965 *
966 * RETURN : int32_t type of status
967 * 0 -- success
968 * -1 -- failure
969 *==========================================================================*/
mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t * my_obj,uint32_t ch_id)970 int32_t mm_camera_stop_zsl_snapshot_ch(mm_camera_obj_t *my_obj,
971 uint32_t ch_id)
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_STOP_ZSL_SNAPSHOT,
983 NULL,
984 NULL);
985 } else {
986 pthread_mutex_unlock(&my_obj->cam_lock);
987 }
988
989 return rc;
990 }
991
992 /*===========================================================================
993 * FUNCTION : mm_camera_config_stream
994 *
995 * DESCRIPTION: configure a stream
996 *
997 * PARAMETERS :
998 * @my_obj : camera object
999 * @ch_id : channel handle
1000 * @stream_id : stream handle
1001 * @config : stream configuration
1002 *
1003 * RETURN : int32_t type of status
1004 * 0 -- success
1005 * -1 -- failure
1006 *==========================================================================*/
mm_camera_config_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)1007 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
1008 uint32_t ch_id,
1009 uint32_t stream_id,
1010 mm_camera_stream_config_t *config)
1011 {
1012 int32_t rc = -1;
1013 mm_channel_t * ch_obj =
1014 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1015 mm_evt_paylod_config_stream_t payload;
1016
1017 if (NULL != ch_obj) {
1018 pthread_mutex_lock(&ch_obj->ch_lock);
1019 pthread_mutex_unlock(&my_obj->cam_lock);
1020
1021 memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
1022 payload.stream_id = stream_id;
1023 payload.config = config;
1024 rc = mm_channel_fsm_fn(ch_obj,
1025 MM_CHANNEL_EVT_CONFIG_STREAM,
1026 (void*)&payload,
1027 NULL);
1028 } else {
1029 pthread_mutex_unlock(&my_obj->cam_lock);
1030 }
1031
1032 return rc;
1033 }
1034
1035 /*===========================================================================
1036 * FUNCTION : mm_camera_start_channel
1037 *
1038 * DESCRIPTION: start a channel, which will start all streams in the channel
1039 *
1040 * PARAMETERS :
1041 * @my_obj : camera object
1042 * @ch_id : channel handle
1043 *
1044 * RETURN : int32_t type of status
1045 * 0 -- success
1046 * -1 -- failure
1047 *==========================================================================*/
mm_camera_start_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1048 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj,
1049 uint32_t ch_id)
1050 {
1051 int32_t rc = -1;
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 rc = mm_channel_fsm_fn(ch_obj,
1060 MM_CHANNEL_EVT_START,
1061 NULL,
1062 NULL);
1063 } else {
1064 pthread_mutex_unlock(&my_obj->cam_lock);
1065 }
1066
1067 return rc;
1068 }
1069
1070 /*===========================================================================
1071 * FUNCTION : mm_camera_stop_channel
1072 *
1073 * DESCRIPTION: stop a channel, which will stop all streams in the channel
1074 *
1075 * PARAMETERS :
1076 * @my_obj : camera object
1077 * @ch_id : channel handle
1078 *
1079 * RETURN : int32_t type of status
1080 * 0 -- success
1081 * -1 -- failure
1082 *==========================================================================*/
mm_camera_stop_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)1083 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
1084 uint32_t ch_id)
1085 {
1086 int32_t rc = 0;
1087 mm_channel_t * ch_obj =
1088 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1089
1090 if (NULL != ch_obj) {
1091 pthread_mutex_lock(&ch_obj->ch_lock);
1092 pthread_mutex_unlock(&my_obj->cam_lock);
1093
1094 rc = mm_channel_fsm_fn(ch_obj,
1095 MM_CHANNEL_EVT_STOP,
1096 NULL,
1097 NULL);
1098 } else {
1099 pthread_mutex_unlock(&my_obj->cam_lock);
1100 }
1101 return rc;
1102 }
1103
1104 /*===========================================================================
1105 * FUNCTION : mm_camera_request_super_buf
1106 *
1107 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1108 * frames from superbuf queue
1109 *
1110 * PARAMETERS :
1111 * @my_obj : camera object
1112 * @ch_id : channel handle
1113 * @num_buf_requested : number of matched frames needed
1114 *
1115 * RETURN : int32_t type of status
1116 * 0 -- success
1117 * -1 -- failure
1118 *==========================================================================*/
mm_camera_request_super_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t num_buf_requested,uint32_t num_retro_buf_requested)1119 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1120 uint32_t ch_id,
1121 uint32_t num_buf_requested,
1122 uint32_t num_retro_buf_requested)
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_REQUEST_SUPER_BUF,
1134 (void*)num_buf_requested,
1135 (void*)num_retro_buf_requested);
1136 } else {
1137 pthread_mutex_unlock(&my_obj->cam_lock);
1138 }
1139
1140 return rc;
1141 }
1142
1143 /*===========================================================================
1144 * FUNCTION : mm_camera_cancel_super_buf_request
1145 *
1146 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
1147 * of matched frames from superbuf queue
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_cancel_super_buf_request(mm_camera_obj_t * my_obj,uint32_t ch_id)1157 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, 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_CANCEL_REQUEST_SUPER_BUF,
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_flush_super_buf_queue
1180 *
1181 * DESCRIPTION: flush out all frames in the superbuf queue
1182 *
1183 * PARAMETERS :
1184 * @my_obj : camera object
1185 * @ch_id : channel handle
1186 *
1187 * RETURN : int32_t type of status
1188 * 0 -- success
1189 * -1 -- failure
1190 *==========================================================================*/
mm_camera_flush_super_buf_queue(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t frame_idx)1191 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
1192 uint32_t frame_idx)
1193 {
1194 int32_t rc = -1;
1195 mm_channel_t * ch_obj =
1196 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1197
1198 if (NULL != ch_obj) {
1199 pthread_mutex_lock(&ch_obj->ch_lock);
1200 pthread_mutex_unlock(&my_obj->cam_lock);
1201
1202 rc = mm_channel_fsm_fn(ch_obj,
1203 MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
1204 (void *)frame_idx,
1205 NULL);
1206 } else {
1207 pthread_mutex_unlock(&my_obj->cam_lock);
1208 }
1209
1210 return rc;
1211 }
1212
1213 /*===========================================================================
1214 * FUNCTION : mm_camera_config_channel_notify
1215 *
1216 * DESCRIPTION: configures the channel notification mode
1217 *
1218 * PARAMETERS :
1219 * @my_obj : camera object
1220 * @ch_id : channel handle
1221 * @notify_mode : notification mode
1222 *
1223 * RETURN : int32_t type of status
1224 * 0 -- success
1225 * -1 -- failure
1226 *==========================================================================*/
mm_camera_config_channel_notify(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)1227 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
1228 uint32_t ch_id,
1229 mm_camera_super_buf_notify_mode_t notify_mode)
1230 {
1231 int32_t rc = -1;
1232 mm_channel_t * ch_obj =
1233 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1234
1235 if (NULL != ch_obj) {
1236 pthread_mutex_lock(&ch_obj->ch_lock);
1237 pthread_mutex_unlock(&my_obj->cam_lock);
1238
1239 rc = mm_channel_fsm_fn(ch_obj,
1240 MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
1241 (void *)notify_mode,
1242 NULL);
1243 } else {
1244 pthread_mutex_unlock(&my_obj->cam_lock);
1245 }
1246
1247 return rc;
1248 }
1249
1250 /*===========================================================================
1251 * FUNCTION : mm_camera_set_stream_parms
1252 *
1253 * DESCRIPTION: set parameters per stream
1254 *
1255 * PARAMETERS :
1256 * @my_obj : camera object
1257 * @ch_id : channel handle
1258 * @s_id : stream handle
1259 * @parms : ptr to a param struct to be set to server
1260 *
1261 * RETURN : int32_t type of status
1262 * 0 -- success
1263 * -1 -- failure
1264 * NOTE : Assume the parms struct buf is already mapped to server via
1265 * domain socket. Corresponding fields of parameters to be set
1266 * are already filled in by upper layer caller.
1267 *==========================================================================*/
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)1268 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
1269 uint32_t ch_id,
1270 uint32_t s_id,
1271 cam_stream_parm_buffer_t *parms)
1272 {
1273 int32_t rc = -1;
1274 mm_evt_paylod_set_get_stream_parms_t payload;
1275 mm_channel_t * ch_obj =
1276 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1277
1278 if (NULL != ch_obj) {
1279 pthread_mutex_lock(&ch_obj->ch_lock);
1280 pthread_mutex_unlock(&my_obj->cam_lock);
1281
1282 memset(&payload, 0, sizeof(payload));
1283 payload.stream_id = s_id;
1284 payload.parms = parms;
1285
1286 rc = mm_channel_fsm_fn(ch_obj,
1287 MM_CHANNEL_EVT_SET_STREAM_PARM,
1288 (void *)&payload,
1289 NULL);
1290 } else {
1291 pthread_mutex_unlock(&my_obj->cam_lock);
1292 }
1293
1294 return rc;
1295 }
1296
1297 /*===========================================================================
1298 * FUNCTION : mm_camera_get_stream_parms
1299 *
1300 * DESCRIPTION: get parameters per stream
1301 *
1302 * PARAMETERS :
1303 * @my_obj : camera object
1304 * @ch_id : channel handle
1305 * @s_id : stream handle
1306 * @parms : ptr to a param struct to be get from server
1307 *
1308 * RETURN : int32_t type of status
1309 * 0 -- success
1310 * -1 -- failure
1311 * NOTE : Assume the parms struct buf is already mapped to server via
1312 * domain socket. Parameters to be get from server are already
1313 * filled in by upper layer caller. After this call, corresponding
1314 * fields of requested parameters will be filled in by server with
1315 * detailed information.
1316 *==========================================================================*/
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)1317 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
1318 uint32_t ch_id,
1319 uint32_t s_id,
1320 cam_stream_parm_buffer_t *parms)
1321 {
1322 int32_t rc = -1;
1323 mm_evt_paylod_set_get_stream_parms_t payload;
1324 mm_channel_t * ch_obj =
1325 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1326
1327 if (NULL != ch_obj) {
1328 pthread_mutex_lock(&ch_obj->ch_lock);
1329 pthread_mutex_unlock(&my_obj->cam_lock);
1330
1331 memset(&payload, 0, sizeof(payload));
1332 payload.stream_id = s_id;
1333 payload.parms = parms;
1334
1335 rc = mm_channel_fsm_fn(ch_obj,
1336 MM_CHANNEL_EVT_GET_STREAM_PARM,
1337 (void *)&payload,
1338 NULL);
1339 } else {
1340 pthread_mutex_unlock(&my_obj->cam_lock);
1341 }
1342
1343 return rc;
1344 }
1345
1346 /*===========================================================================
1347 * FUNCTION : mm_camera_do_stream_action
1348 *
1349 * DESCRIPTION: request server to perform stream based action. Maybe removed later
1350 * if the functionality is included in mm_camera_set_parms
1351 *
1352 * PARAMETERS :
1353 * @my_obj : camera object
1354 * @ch_id : channel handle
1355 * @s_id : stream handle
1356 * @actions : ptr to an action struct buf to be performed by server
1357 *
1358 * RETURN : int32_t type of status
1359 * 0 -- success
1360 * -1 -- failure
1361 * NOTE : Assume the action struct buf is already mapped to server via
1362 * domain socket. Actions to be performed by server are already
1363 * filled in by upper layer caller.
1364 *==========================================================================*/
mm_camera_do_stream_action(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,void * actions)1365 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
1366 uint32_t ch_id,
1367 uint32_t stream_id,
1368 void *actions)
1369 {
1370 int32_t rc = -1;
1371 mm_evt_paylod_do_stream_action_t payload;
1372 mm_channel_t * ch_obj =
1373 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1374
1375 if (NULL != ch_obj) {
1376 pthread_mutex_lock(&ch_obj->ch_lock);
1377 pthread_mutex_unlock(&my_obj->cam_lock);
1378
1379 memset(&payload, 0, sizeof(payload));
1380 payload.stream_id = stream_id;
1381 payload.actions = actions;
1382
1383 rc = mm_channel_fsm_fn(ch_obj,
1384 MM_CHANNEL_EVT_DO_STREAM_ACTION,
1385 (void*)&payload,
1386 NULL);
1387 } else {
1388 pthread_mutex_unlock(&my_obj->cam_lock);
1389 }
1390
1391 return rc;
1392 }
1393
1394 /*===========================================================================
1395 * FUNCTION : mm_camera_map_stream_buf
1396 *
1397 * DESCRIPTION: mapping stream buffer via domain socket to server
1398 *
1399 * PARAMETERS :
1400 * @my_obj : camera object
1401 * @ch_id : channel handle
1402 * @s_id : stream handle
1403 * @buf_type : type of buffer to be mapped. could be following values:
1404 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1405 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1406 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1407 * @buf_idx : index of buffer within the stream buffers, only valid if
1408 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1409 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1410 * @plane_idx : plane index. If all planes share the same fd,
1411 * plane_idx = -1; otherwise, plean_idx is the
1412 * index to plane (0..num_of_planes)
1413 * @fd : file descriptor of the buffer
1414 * @size : size of the buffer
1415 *
1416 * RETURN : int32_t type of status
1417 * 0 -- success
1418 * -1 -- failure
1419 *==========================================================================*/
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,uint32_t size)1420 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
1421 uint32_t ch_id,
1422 uint32_t stream_id,
1423 uint8_t buf_type,
1424 uint32_t buf_idx,
1425 int32_t plane_idx,
1426 int fd,
1427 uint32_t size)
1428 {
1429 int32_t rc = -1;
1430 mm_evt_paylod_map_stream_buf_t payload;
1431 mm_channel_t * ch_obj =
1432 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1433
1434 if (NULL != ch_obj) {
1435 pthread_mutex_lock(&ch_obj->ch_lock);
1436 pthread_mutex_unlock(&my_obj->cam_lock);
1437
1438 memset(&payload, 0, sizeof(payload));
1439 payload.stream_id = stream_id;
1440 payload.buf_type = buf_type;
1441 payload.buf_idx = buf_idx;
1442 payload.plane_idx = plane_idx;
1443 payload.fd = fd;
1444 payload.size = size;
1445 rc = mm_channel_fsm_fn(ch_obj,
1446 MM_CHANNEL_EVT_MAP_STREAM_BUF,
1447 (void*)&payload,
1448 NULL);
1449 } else {
1450 pthread_mutex_unlock(&my_obj->cam_lock);
1451 }
1452
1453 return rc;
1454 }
1455
1456 /*===========================================================================
1457 * FUNCTION : mm_camera_unmap_stream_buf
1458 *
1459 * DESCRIPTION: unmapping stream buffer via domain socket to server
1460 *
1461 * PARAMETERS :
1462 * @my_obj : camera object
1463 * @ch_id : channel handle
1464 * @s_id : stream handle
1465 * @buf_type : type of buffer to be mapped. could be following values:
1466 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1467 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1468 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1469 * @buf_idx : index of buffer within the stream buffers, only valid if
1470 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1471 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1472 * @plane_idx : plane index. If all planes share the same fd,
1473 * plane_idx = -1; otherwise, plean_idx is the
1474 * index to plane (0..num_of_planes)
1475 *
1476 * RETURN : int32_t type of status
1477 * 0 -- success
1478 * -1 -- failure
1479 *==========================================================================*/
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)1480 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
1481 uint32_t ch_id,
1482 uint32_t stream_id,
1483 uint8_t buf_type,
1484 uint32_t buf_idx,
1485 int32_t plane_idx)
1486 {
1487 int32_t rc = -1;
1488 mm_evt_paylod_unmap_stream_buf_t payload;
1489 mm_channel_t * ch_obj =
1490 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1491
1492 if (NULL != ch_obj) {
1493 pthread_mutex_lock(&ch_obj->ch_lock);
1494 pthread_mutex_unlock(&my_obj->cam_lock);
1495
1496 memset(&payload, 0, sizeof(payload));
1497 payload.stream_id = stream_id;
1498 payload.buf_type = buf_type;
1499 payload.buf_idx = buf_idx;
1500 payload.plane_idx = plane_idx;
1501 rc = mm_channel_fsm_fn(ch_obj,
1502 MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
1503 (void*)&payload,
1504 NULL);
1505 } else {
1506 pthread_mutex_unlock(&my_obj->cam_lock);
1507 }
1508
1509 return rc;
1510 }
1511
1512 /*===========================================================================
1513 * FUNCTION : mm_camera_evt_sub
1514 *
1515 * DESCRIPTION: subscribe/unsubscribe event notify from kernel
1516 *
1517 * PARAMETERS :
1518 * @my_obj : camera object
1519 * @reg_flag : 1 -- subscribe ; 0 -- unsubscribe
1520 *
1521 * RETURN : int32_t type of status
1522 * 0 -- success
1523 * -1 -- failure
1524 *==========================================================================*/
mm_camera_evt_sub(mm_camera_obj_t * my_obj,uint8_t reg_flag)1525 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1526 uint8_t reg_flag)
1527 {
1528 int32_t rc = 0;
1529 struct v4l2_event_subscription sub;
1530
1531 memset(&sub, 0, sizeof(sub));
1532 sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
1533 sub.id = MSM_CAMERA_MSM_NOTIFY;
1534 if(FALSE == reg_flag) {
1535 /* unsubscribe */
1536 rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1537 if (rc < 0) {
1538 CDBG_ERROR("%s: unsubscribe event rc = %d", __func__, rc);
1539 return rc;
1540 }
1541 /* remove evt fd from the polling thraed when unreg the last event */
1542 rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
1543 my_obj->my_hdl,
1544 mm_camera_sync_call);
1545 } else {
1546 rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1547 if (rc < 0) {
1548 CDBG_ERROR("%s: subscribe event rc = %d", __func__, rc);
1549 return rc;
1550 }
1551 /* add evt fd to polling thread when subscribe the first event */
1552 rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1553 my_obj->my_hdl,
1554 my_obj->ctrl_fd,
1555 mm_camera_event_notify,
1556 (void*)my_obj,
1557 mm_camera_sync_call);
1558 }
1559 return rc;
1560 }
1561
1562 /*===========================================================================
1563 * FUNCTION : mm_camera_util_wait_for_event
1564 *
1565 * DESCRIPTION: utility function to wait for certain events
1566 *
1567 * PARAMETERS :
1568 * @my_obj : camera object
1569 * @evt_mask : mask for events to be waited. Any of event in the mask would
1570 * trigger the wait to end
1571 * @status : status of the event
1572 *
1573 * RETURN : none
1574 *==========================================================================*/
mm_camera_util_wait_for_event(mm_camera_obj_t * my_obj,uint32_t evt_mask,int32_t * status)1575 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
1576 uint32_t evt_mask,
1577 int32_t *status)
1578 {
1579 pthread_mutex_lock(&my_obj->evt_lock);
1580 while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
1581 pthread_cond_wait(&my_obj->evt_cond, &my_obj->evt_lock);
1582 }
1583 *status = my_obj->evt_rcvd.status;
1584 /* reset local storage for recieved event for next event */
1585 memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
1586 pthread_mutex_unlock(&my_obj->evt_lock);
1587 }
1588
1589 /*===========================================================================
1590 * FUNCTION : mm_camera_util_sendmsg
1591 *
1592 * DESCRIPTION: utility function to send msg via domain socket
1593 *
1594 * PARAMETERS :
1595 * @my_obj : camera object
1596 * @msg : message to be sent
1597 * @buf_size : size of the message to be sent
1598 * @sendfd : >0 if any file descriptor need to be passed across process
1599 *
1600 * RETURN : int32_t type of status
1601 * 0 -- success
1602 * -1 -- failure
1603 *==========================================================================*/
mm_camera_util_sendmsg(mm_camera_obj_t * my_obj,void * msg,uint32_t buf_size,int sendfd)1604 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
1605 void *msg,
1606 uint32_t buf_size,
1607 int sendfd)
1608 {
1609 int32_t rc = -1;
1610 int32_t status;
1611
1612 /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
1613 pthread_mutex_lock(&my_obj->msg_lock);
1614 if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
1615 /* wait for event that mapping/unmapping is done */
1616 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1617 if (MSM_CAMERA_STATUS_SUCCESS == status) {
1618 rc = 0;
1619 }
1620 }
1621 pthread_mutex_unlock(&my_obj->msg_lock);
1622 return rc;
1623 }
1624
1625 /*===========================================================================
1626 * FUNCTION : mm_camera_map_buf
1627 *
1628 * DESCRIPTION: mapping camera buffer via domain socket to server
1629 *
1630 * PARAMETERS :
1631 * @my_obj : camera object
1632 * @buf_type : type of buffer to be mapped. could be following values:
1633 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1634 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1635 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1636 * @fd : file descriptor of the buffer
1637 * @size : size of the buffer
1638 *
1639 * RETURN : int32_t type of status
1640 * 0 -- success
1641 * -1 -- failure
1642 *==========================================================================*/
mm_camera_map_buf(mm_camera_obj_t * my_obj,uint8_t buf_type,int fd,uint32_t size)1643 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1644 uint8_t buf_type,
1645 int fd,
1646 uint32_t size)
1647 {
1648 int32_t rc = 0;
1649 cam_sock_packet_t packet;
1650 memset(&packet, 0, sizeof(cam_sock_packet_t));
1651 packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
1652 packet.payload.buf_map.type = buf_type;
1653 packet.payload.buf_map.fd = fd;
1654 packet.payload.buf_map.size = size;
1655 rc = mm_camera_util_sendmsg(my_obj,
1656 &packet,
1657 sizeof(cam_sock_packet_t),
1658 fd);
1659 pthread_mutex_unlock(&my_obj->cam_lock);
1660 return rc;
1661 }
1662
1663 /*===========================================================================
1664 * FUNCTION : mm_camera_unmap_buf
1665 *
1666 * DESCRIPTION: unmapping camera buffer via domain socket to server
1667 *
1668 * PARAMETERS :
1669 * @my_obj : camera object
1670 * @buf_type : type of buffer to be mapped. could be following values:
1671 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1672 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1673 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1674 *
1675 * RETURN : int32_t type of status
1676 * 0 -- success
1677 * -1 -- failure
1678 *==========================================================================*/
mm_camera_unmap_buf(mm_camera_obj_t * my_obj,uint8_t buf_type)1679 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
1680 uint8_t buf_type)
1681 {
1682 int32_t rc = 0;
1683 cam_sock_packet_t packet;
1684 memset(&packet, 0, sizeof(cam_sock_packet_t));
1685 packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
1686 packet.payload.buf_unmap.type = buf_type;
1687 rc = mm_camera_util_sendmsg(my_obj,
1688 &packet,
1689 sizeof(cam_sock_packet_t),
1690 0);
1691 pthread_mutex_unlock(&my_obj->cam_lock);
1692 return rc;
1693 }
1694
1695 /*===========================================================================
1696 * FUNCTION : mm_camera_util_s_ctrl
1697 *
1698 * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
1699 *
1700 * PARAMETERS :
1701 * @fd : file descritpor for sending ioctl
1702 * @id : control id
1703 * @value : value of the ioctl to be sent
1704 *
1705 * RETURN : int32_t type of status
1706 * 0 -- success
1707 * -1 -- failure
1708 *==========================================================================*/
mm_camera_util_s_ctrl(int32_t fd,uint32_t id,int32_t * value)1709 int32_t mm_camera_util_s_ctrl(int32_t fd, uint32_t id, int32_t *value)
1710 {
1711 int rc = 0;
1712 struct v4l2_control control;
1713
1714 memset(&control, 0, sizeof(control));
1715 control.id = id;
1716 if (value != NULL) {
1717 control.value = *value;
1718 }
1719 rc = ioctl(fd, VIDIOC_S_CTRL, &control);
1720
1721 CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
1722 __func__, fd, id, (uint32_t)value, rc);
1723 if (value != NULL) {
1724 *value = control.value;
1725 }
1726 return (rc >= 0)? 0 : -1;
1727 }
1728
1729 /*===========================================================================
1730 * FUNCTION : mm_camera_util_g_ctrl
1731 *
1732 * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
1733 *
1734 * PARAMETERS :
1735 * @fd : file descritpor for sending ioctl
1736 * @id : control id
1737 * @value : value of the ioctl to be sent
1738 *
1739 * RETURN : int32_t type of status
1740 * 0 -- success
1741 * -1 -- failure
1742 *==========================================================================*/
mm_camera_util_g_ctrl(int32_t fd,uint32_t id,int32_t * value)1743 int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
1744 {
1745 int rc = 0;
1746 struct v4l2_control control;
1747
1748 memset(&control, 0, sizeof(control));
1749 control.id = id;
1750 if (value != NULL) {
1751 control.value = *value;
1752 }
1753 rc = ioctl(fd, VIDIOC_G_CTRL, &control);
1754 CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc);
1755 if (value != NULL) {
1756 *value = control.value;
1757 }
1758 return (rc >= 0)? 0 : -1;
1759 }
1760
1761 /*===========================================================================
1762 * FUNCTION : mm_camera_channel_advanced_capture
1763 *
1764 * DESCRIPTION: sets the channel advanced capture
1765 *
1766 * PARAMETERS :
1767 * @my_obj : camera object
1768 * @advanced_capture_type : advanced capture type.
1769 * @ch_id : channel handle
1770 * @start_flag : flag to indicate start/stop
1771 *
1772 * RETURN : int32_t type of status
1773 * 0 -- success
1774 * -1 -- failure
1775 *==========================================================================*/
mm_camera_channel_advanced_capture(mm_camera_obj_t * my_obj,mm_camera_advanced_capture_t advanced_capture_type,uint32_t ch_id,int32_t start_flag)1776 int32_t mm_camera_channel_advanced_capture(mm_camera_obj_t *my_obj,
1777 mm_camera_advanced_capture_t advanced_capture_type,
1778 uint32_t ch_id,
1779 int32_t start_flag)
1780 {
1781 CDBG("%s: E",__func__);
1782 int32_t rc = -1;
1783 mm_channel_t * ch_obj =
1784 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1785
1786 if (NULL != ch_obj) {
1787 pthread_mutex_lock(&ch_obj->ch_lock);
1788 pthread_mutex_unlock(&my_obj->cam_lock);
1789 switch (advanced_capture_type) {
1790 case MM_CAMERA_AF_BRACKETING:
1791 rc = mm_channel_fsm_fn(ch_obj,
1792 MM_CHANNEL_EVT_AF_BRACKETING,
1793 (void *)start_flag,
1794 NULL);
1795 break;
1796 case MM_CAMERA_AE_BRACKETING:
1797 rc = mm_channel_fsm_fn(ch_obj,
1798 MM_CHANNEL_EVT_AE_BRACKETING,
1799 (void *)start_flag,
1800 NULL);
1801 break;
1802 case MM_CAMERA_FLASH_BRACKETING:
1803 rc = mm_channel_fsm_fn(ch_obj,
1804 MM_CHANNEL_EVT_FLASH_BRACKETING,
1805 (void *)start_flag,
1806 NULL);
1807 break;
1808 case MM_CAMERA_ZOOM_1X:
1809 rc = mm_channel_fsm_fn(ch_obj,
1810 MM_CHANNEL_EVT_ZOOM_1X,
1811 (void *)start_flag,
1812 NULL);
1813 break;
1814 default:
1815 break;
1816 }
1817
1818 } else {
1819 pthread_mutex_unlock(&my_obj->cam_lock);
1820 }
1821
1822 CDBG("%s: X",__func__);
1823 return rc;
1824 }
1825