1 /* Copyright (c) 2012-2014, 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 int id = 0;
97 FILE *fp;
98 if ((fp = fopen("/sys/devices/system/soc/soc0/id", "r")) != NULL) {
99 fscanf(fp, "%d", &id);
100 fclose(fp);
101 }
102 if (id == 126)
103 return FALSE;
104 else
105 return TRUE;
106 }
107
108 /*===========================================================================
109 * FUNCTION : mm_camera_dispatch_app_event
110 *
111 * DESCRIPTION: dispatch event to apps who regitster for event notify
112 *
113 * PARAMETERS :
114 * @cmd_cb: ptr to a struct storing event info
115 * @user_data: user data ptr (camera object)
116 *
117 * RETURN : none
118 *==========================================================================*/
mm_camera_dispatch_app_event(mm_camera_cmdcb_t * cmd_cb,void * user_data)119 static void mm_camera_dispatch_app_event(mm_camera_cmdcb_t *cmd_cb,
120 void* user_data)
121 {
122 mm_camera_cmd_thread_name("mm_cam_event");
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 pthread_mutex_lock(&my_obj->cb_lock);
128 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
129 if(my_obj->evt.evt[i].evt_cb) {
130 my_obj->evt.evt[i].evt_cb(
131 my_obj->my_hdl,
132 event,
133 my_obj->evt.evt[i].user_data);
134 }
135 }
136 pthread_mutex_unlock(&my_obj->cb_lock);
137 }
138 }
139
140 /*===========================================================================
141 * FUNCTION : mm_camera_event_notify
142 *
143 * DESCRIPTION: callback to handle event notify from kernel. This call will
144 * dequeue event from kernel.
145 *
146 * PARAMETERS :
147 * @user_data: user data ptr (camera object)
148 *
149 * RETURN : none
150 *==========================================================================*/
mm_camera_event_notify(void * user_data)151 static void mm_camera_event_notify(void* user_data)
152 {
153 struct v4l2_event ev;
154 struct msm_v4l2_event_data *msm_evt = NULL;
155 int rc;
156 mm_camera_event_t evt;
157 memset(&evt, 0, sizeof(mm_camera_event_t));
158
159 mm_camera_obj_t *my_obj = (mm_camera_obj_t*)user_data;
160 if (NULL != my_obj) {
161 /* read evt */
162 memset(&ev, 0, sizeof(ev));
163 rc = ioctl(my_obj->ctrl_fd, VIDIOC_DQEVENT, &ev);
164
165 if (rc >= 0 && ev.id == MSM_CAMERA_MSM_NOTIFY) {
166 msm_evt = (struct msm_v4l2_event_data *)ev.u.data;
167 switch (msm_evt->command) {
168 case CAM_EVENT_TYPE_MAP_UNMAP_DONE:
169 pthread_mutex_lock(&my_obj->evt_lock);
170 my_obj->evt_rcvd.server_event_type = msm_evt->command;
171 my_obj->evt_rcvd.status = msm_evt->status;
172 pthread_cond_signal(&my_obj->evt_cond);
173 pthread_mutex_unlock(&my_obj->evt_lock);
174 break;
175 case MSM_CAMERA_PRIV_SHUTDOWN:
176 {
177 evt.server_event_type = CAM_EVENT_TYPE_DAEMON_DIED;
178 mm_camera_enqueue_evt(my_obj, &evt);
179 }
180 break;
181 default:
182 break;
183 }
184 }
185 }
186 }
187
188 /*===========================================================================
189 * FUNCTION : mm_camera_enqueue_evt
190 *
191 * DESCRIPTION: enqueue received event into event queue to be processed by
192 * event thread.
193 *
194 * PARAMETERS :
195 * @my_obj : ptr to a camera object
196 * @event : event to be queued
197 *
198 * RETURN : int32_t type of status
199 * 0 -- success
200 * -1 -- failure
201 *==========================================================================*/
mm_camera_enqueue_evt(mm_camera_obj_t * my_obj,mm_camera_event_t * event)202 int32_t mm_camera_enqueue_evt(mm_camera_obj_t *my_obj,
203 mm_camera_event_t *event)
204 {
205 int32_t rc = 0;
206 mm_camera_cmdcb_t *node = NULL;
207
208 node = (mm_camera_cmdcb_t *)malloc(sizeof(mm_camera_cmdcb_t));
209 if (NULL != node) {
210 memset(node, 0, sizeof(mm_camera_cmdcb_t));
211 node->cmd_type = MM_CAMERA_CMD_TYPE_EVT_CB;
212 node->u.evt = *event;
213
214 /* enqueue to evt cmd thread */
215 cam_queue_enq(&(my_obj->evt_thread.cmd_queue), node);
216 /* wake up evt cmd thread */
217 cam_sem_post(&(my_obj->evt_thread.cmd_sem));
218 } else {
219 CDBG_ERROR("%s: No memory for mm_camera_node_t", __func__);
220 rc = -1;
221 }
222
223 return rc;
224 }
225
226 /*===========================================================================
227 * FUNCTION : mm_camera_open
228 *
229 * DESCRIPTION: open a camera
230 *
231 * PARAMETERS :
232 * @my_obj : ptr to a camera object
233 *
234 * RETURN : int32_t type of status
235 * 0 -- success
236 * -1 -- failure
237 *==========================================================================*/
mm_camera_open(mm_camera_obj_t * my_obj)238 int32_t mm_camera_open(mm_camera_obj_t *my_obj)
239 {
240 char dev_name[MM_CAMERA_DEV_NAME_LEN];
241 int32_t rc = 0;
242 int8_t n_try=MM_CAMERA_DEV_OPEN_TRIES;
243 uint8_t sleep_msec=MM_CAMERA_DEV_OPEN_RETRY_SLEEP;
244 unsigned int cam_idx = 0;
245
246 CDBG("%s: begin\n", __func__);
247
248 snprintf(dev_name, sizeof(dev_name), "/dev/%s",
249 mm_camera_util_get_dev_name(my_obj->my_hdl));
250 sscanf(dev_name, "/dev/video%u", &cam_idx);
251 CDBG_HIGH("%s: dev name = %s, cam_idx = %d", __func__, dev_name, cam_idx);
252
253 do{
254 n_try--;
255 errno = 0;
256 my_obj->ctrl_fd = open(dev_name, O_RDWR | O_NONBLOCK);
257 CDBG("%s: ctrl_fd = %d, errno == %d", __func__, my_obj->ctrl_fd, errno);
258 if((my_obj->ctrl_fd >= 0) || (errno != EIO && errno != ETIMEDOUT) || (n_try <= 0 )) {
259 CDBG_HIGH("%s: opened, break out while loop", __func__);
260 break;
261 }
262 ALOGE("%s:Failed with %s error, retrying after %d milli-seconds",
263 __func__, strerror(errno), sleep_msec);
264 usleep(sleep_msec * 1000);
265 }while (n_try > 0);
266
267 if (my_obj->ctrl_fd < 0) {
268 CDBG_ERROR("%s: cannot open control fd of '%s' (%s)\n",
269 __func__, dev_name, strerror(errno));
270 rc = -1;
271 goto on_error;
272 }
273
274 /* open domain socket*/
275 n_try = MM_CAMERA_DEV_OPEN_TRIES;
276 do {
277 n_try--;
278 my_obj->ds_fd = mm_camera_socket_create(cam_idx, MM_CAMERA_SOCK_TYPE_UDP);
279 CDBG("%s: ds_fd = %d, errno = %d", __func__, my_obj->ds_fd, errno);
280 if((my_obj->ds_fd >= 0) || (n_try <= 0 )) {
281 CDBG("%s: opened, break out while loop", __func__);
282 break;
283 }
284 CDBG("%s:failed with I/O error retrying after %d milli-seconds",
285 __func__, sleep_msec);
286 usleep(sleep_msec * 1000);
287 } while (n_try > 0);
288
289 if (my_obj->ds_fd < 0) {
290 CDBG_ERROR("%s: cannot open domain socket fd of '%s'(%s)\n",
291 __func__, dev_name, strerror(errno));
292 rc = -1;
293 goto on_error;
294 }
295 pthread_mutex_init(&my_obj->msg_lock, NULL);
296
297 pthread_mutex_init(&my_obj->cb_lock, NULL);
298 pthread_mutex_init(&my_obj->evt_lock, NULL);
299 pthread_cond_init(&my_obj->evt_cond, NULL);
300
301 CDBG("%s : Launch evt Thread in Cam Open",__func__);
302 mm_camera_cmd_thread_launch(&my_obj->evt_thread,
303 mm_camera_dispatch_app_event,
304 (void *)my_obj);
305
306 /* launch event poll thread
307 * we will add evt fd into event poll thread upon user first register for evt */
308 CDBG("%s : Launch evt Poll Thread in Cam Open", __func__);
309 mm_camera_poll_thread_launch(&my_obj->evt_poll_thread,
310 MM_CAMERA_POLL_TYPE_EVT);
311 mm_camera_evt_sub(my_obj, TRUE);
312
313 CDBG("%s: end (rc = %d)\n", __func__, rc);
314 /* we do not need to unlock cam_lock here before return
315 * because for open, it's done within intf_lock */
316 return rc;
317
318 on_error:
319 if (my_obj->ctrl_fd >= 0) {
320 close(my_obj->ctrl_fd);
321 my_obj->ctrl_fd = -1;
322 }
323 if (my_obj->ds_fd >= 0) {
324 mm_camera_socket_close(my_obj->ds_fd);
325 my_obj->ds_fd = -1;
326 }
327
328 /* we do not need to unlock cam_lock here before return
329 * because for open, it's done within intf_lock */
330 return rc;
331 }
332
333 /*===========================================================================
334 * FUNCTION : mm_camera_close
335 *
336 * DESCRIPTION: enqueue received event into event queue to be processed by
337 * event thread.
338 *
339 * PARAMETERS :
340 * @my_obj : ptr to a camera object
341 * @event : event to be queued
342 *
343 * RETURN : int32_t type of status
344 * 0 -- success
345 * -1 -- failure
346 *==========================================================================*/
mm_camera_close(mm_camera_obj_t * my_obj)347 int32_t mm_camera_close(mm_camera_obj_t *my_obj)
348 {
349 CDBG("%s : unsubscribe evt", __func__);
350 mm_camera_evt_sub(my_obj, FALSE);
351
352 CDBG("%s : Close evt Poll Thread in Cam Close",__func__);
353 mm_camera_poll_thread_release(&my_obj->evt_poll_thread);
354
355 CDBG("%s : Close evt cmd Thread in Cam Close",__func__);
356 mm_camera_cmd_thread_release(&my_obj->evt_thread);
357
358 if(my_obj->ctrl_fd >= 0) {
359 close(my_obj->ctrl_fd);
360 my_obj->ctrl_fd = -1;
361 }
362 if(my_obj->ds_fd >= 0) {
363 mm_camera_socket_close(my_obj->ds_fd);
364 my_obj->ds_fd = -1;
365 }
366 pthread_mutex_destroy(&my_obj->msg_lock);
367
368 pthread_mutex_destroy(&my_obj->cb_lock);
369 pthread_mutex_destroy(&my_obj->evt_lock);
370 pthread_cond_destroy(&my_obj->evt_cond);
371
372 pthread_mutex_unlock(&my_obj->cam_lock);
373 return 0;
374 }
375
376 /*===========================================================================
377 * FUNCTION : mm_camera_register_event_notify_internal
378 *
379 * DESCRIPTION: internal implementation for registering callback for event notify.
380 *
381 * PARAMETERS :
382 * @my_obj : ptr to a camera object
383 * @evt_cb : callback to be registered to handle event notify
384 * @user_data: user data ptr
385 *
386 * RETURN : int32_t type of status
387 * 0 -- success
388 * -1 -- failure
389 *==========================================================================*/
mm_camera_register_event_notify_internal(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)390 int32_t mm_camera_register_event_notify_internal(mm_camera_obj_t *my_obj,
391 mm_camera_event_notify_t evt_cb,
392 void * user_data)
393 {
394 int i;
395 int rc = -1;
396 mm_camera_evt_obj_t *evt_array = NULL;
397
398 pthread_mutex_lock(&my_obj->cb_lock);
399 evt_array = &my_obj->evt;
400 if(evt_cb) {
401 /* this is reg case */
402 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
403 if(evt_array->evt[i].user_data == NULL) {
404 evt_array->evt[i].evt_cb = evt_cb;
405 evt_array->evt[i].user_data = user_data;
406 evt_array->reg_count++;
407 rc = 0;
408 break;
409 }
410 }
411 } else {
412 /* this is unreg case */
413 for(i = 0; i < MM_CAMERA_EVT_ENTRY_MAX; i++) {
414 if(evt_array->evt[i].user_data == user_data) {
415 evt_array->evt[i].evt_cb = NULL;
416 evt_array->evt[i].user_data = NULL;
417 evt_array->reg_count--;
418 rc = 0;
419 break;
420 }
421 }
422 }
423
424 pthread_mutex_unlock(&my_obj->cb_lock);
425 return rc;
426 }
427
428 /*===========================================================================
429 * FUNCTION : mm_camera_register_event_notify
430 *
431 * DESCRIPTION: registering a callback for event notify.
432 *
433 * PARAMETERS :
434 * @my_obj : ptr to a camera object
435 * @evt_cb : callback to be registered to handle event notify
436 * @user_data: user data ptr
437 *
438 * RETURN : int32_t type of status
439 * 0 -- success
440 * -1 -- failure
441 *==========================================================================*/
mm_camera_register_event_notify(mm_camera_obj_t * my_obj,mm_camera_event_notify_t evt_cb,void * user_data)442 int32_t mm_camera_register_event_notify(mm_camera_obj_t *my_obj,
443 mm_camera_event_notify_t evt_cb,
444 void * user_data)
445 {
446 int rc = -1;
447 rc = mm_camera_register_event_notify_internal(my_obj,
448 evt_cb,
449 user_data);
450 pthread_mutex_unlock(&my_obj->cam_lock);
451 return rc;
452 }
453
454 /*===========================================================================
455 * FUNCTION : mm_camera_qbuf
456 *
457 * DESCRIPTION: enqueue buffer back to kernel
458 *
459 * PARAMETERS :
460 * @my_obj : camera object
461 * @ch_id : channel handle
462 * @buf : buf ptr to be enqueued
463 *
464 * RETURN : int32_t type of status
465 * 0 -- success
466 * -1 -- failure
467 *==========================================================================*/
mm_camera_qbuf(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_buf_def_t * buf)468 int32_t mm_camera_qbuf(mm_camera_obj_t *my_obj,
469 uint32_t ch_id,
470 mm_camera_buf_def_t *buf)
471 {
472 int rc = -1;
473 mm_channel_t * ch_obj = NULL;
474 ch_obj = mm_camera_util_get_channel_by_handler(my_obj, ch_id);
475
476 pthread_mutex_unlock(&my_obj->cam_lock);
477
478 /* we always assume qbuf will be done before channel/stream is fully stopped
479 * because qbuf is done within dataCB context
480 * in order to avoid deadlock, we are not locking ch_lock for qbuf */
481 if (NULL != ch_obj) {
482 rc = mm_channel_qbuf(ch_obj, buf);
483 }
484
485 return rc;
486 }
487
488 /*===========================================================================
489 * FUNCTION : mm_camera_query_capability
490 *
491 * DESCRIPTION: query camera capability
492 *
493 * PARAMETERS :
494 * @my_obj: camera object
495 *
496 * RETURN : int32_t type of status
497 * 0 -- success
498 * -1 -- failure
499 *==========================================================================*/
mm_camera_query_capability(mm_camera_obj_t * my_obj)500 int32_t mm_camera_query_capability(mm_camera_obj_t *my_obj)
501 {
502 int32_t rc = 0;
503 struct v4l2_capability cap;
504
505 /* get camera capabilities */
506 memset(&cap, 0, sizeof(cap));
507 rc = ioctl(my_obj->ctrl_fd, VIDIOC_QUERYCAP, &cap);
508 if (rc != 0) {
509 CDBG_ERROR("%s: cannot get camera capabilities, rc = %d\n", __func__, rc);
510 }
511
512 pthread_mutex_unlock(&my_obj->cam_lock);
513 return rc;
514
515 }
516
517 /*===========================================================================
518 * FUNCTION : mm_camera_set_parms
519 *
520 * DESCRIPTION: set parameters per camera
521 *
522 * PARAMETERS :
523 * @my_obj : camera object
524 * @parms : ptr to a param struct to be set to server
525 *
526 * RETURN : int32_t type of status
527 * 0 -- success
528 * -1 -- failure
529 * NOTE : Assume the parms struct buf is already mapped to server via
530 * domain socket. Corresponding fields of parameters to be set
531 * are already filled in by upper layer caller.
532 *==========================================================================*/
mm_camera_set_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)533 int32_t mm_camera_set_parms(mm_camera_obj_t *my_obj,
534 parm_buffer_t *parms)
535 {
536 int32_t rc = -1;
537 int32_t value = 0;
538 if (parms != NULL) {
539 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
540 }
541 pthread_mutex_unlock(&my_obj->cam_lock);
542 return rc;
543 }
544
545 /*===========================================================================
546 * FUNCTION : mm_camera_get_parms
547 *
548 * DESCRIPTION: get parameters per camera
549 *
550 * PARAMETERS :
551 * @my_obj : camera object
552 * @parms : ptr to a param struct to be get from server
553 *
554 * RETURN : int32_t type of status
555 * 0 -- success
556 * -1 -- failure
557 * NOTE : Assume the parms struct buf is already mapped to server via
558 * domain socket. Parameters to be get from server are already
559 * filled in by upper layer caller. After this call, corresponding
560 * fields of requested parameters will be filled in by server with
561 * detailed information.
562 *==========================================================================*/
mm_camera_get_parms(mm_camera_obj_t * my_obj,parm_buffer_t * parms)563 int32_t mm_camera_get_parms(mm_camera_obj_t *my_obj,
564 parm_buffer_t *parms)
565 {
566 int32_t rc = -1;
567 int32_t value = 0;
568 if (parms != NULL) {
569 rc = mm_camera_util_g_ctrl(my_obj->ctrl_fd, CAM_PRIV_PARM, &value);
570 }
571 pthread_mutex_unlock(&my_obj->cam_lock);
572 return rc;
573 }
574
575 /*===========================================================================
576 * FUNCTION : mm_camera_do_auto_focus
577 *
578 * DESCRIPTION: performing auto focus
579 *
580 * PARAMETERS :
581 * @camera_handle: camera handle
582 *
583 * RETURN : int32_t type of status
584 * 0 -- success
585 * -1 -- failure
586 * NOTE : if this call success, we will always assume there will
587 * be an auto_focus event following up.
588 *==========================================================================*/
mm_camera_do_auto_focus(mm_camera_obj_t * my_obj)589 int32_t mm_camera_do_auto_focus(mm_camera_obj_t *my_obj)
590 {
591 int32_t rc = -1;
592 int32_t value = 0;
593 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_DO_AUTO_FOCUS, &value);
594 pthread_mutex_unlock(&my_obj->cam_lock);
595 return rc;
596 }
597
598 /*===========================================================================
599 * FUNCTION : mm_camera_cancel_auto_focus
600 *
601 * DESCRIPTION: cancel auto focus
602 *
603 * PARAMETERS :
604 * @camera_handle: camera handle
605 *
606 * RETURN : int32_t type of status
607 * 0 -- success
608 * -1 -- failure
609 *==========================================================================*/
mm_camera_cancel_auto_focus(mm_camera_obj_t * my_obj)610 int32_t mm_camera_cancel_auto_focus(mm_camera_obj_t *my_obj)
611 {
612 int32_t rc = -1;
613 int32_t value = 0;
614 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_CANCEL_AUTO_FOCUS, &value);
615 pthread_mutex_unlock(&my_obj->cam_lock);
616 return rc;
617 }
618
619 /*===========================================================================
620 * FUNCTION : mm_camera_prepare_snapshot
621 *
622 * DESCRIPTION: prepare hardware for snapshot
623 *
624 * PARAMETERS :
625 * @my_obj : camera object
626 * @do_af_flag : flag indicating if AF is needed
627 *
628 * RETURN : int32_t type of status
629 * 0 -- success
630 * -1 -- failure
631 *==========================================================================*/
mm_camera_prepare_snapshot(mm_camera_obj_t * my_obj,int32_t do_af_flag)632 int32_t mm_camera_prepare_snapshot(mm_camera_obj_t *my_obj,
633 int32_t do_af_flag)
634 {
635 int32_t rc = -1;
636 int32_t value = do_af_flag;
637 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd, CAM_PRIV_PREPARE_SNAPSHOT, &value);
638 pthread_mutex_unlock(&my_obj->cam_lock);
639 return rc;
640 }
641
642 /*===========================================================================
643 * FUNCTION : mm_camera_start_zsl_snapshot
644 *
645 * DESCRIPTION: start zsl snapshot
646 *
647 * PARAMETERS :
648 * @my_obj : camera object
649 *
650 * RETURN : int32_t type of status
651 * 0 -- success
652 * -1 -- failure
653 *==========================================================================*/
mm_camera_start_zsl_snapshot(mm_camera_obj_t * my_obj)654 int32_t mm_camera_start_zsl_snapshot(mm_camera_obj_t *my_obj)
655 {
656 int32_t rc = -1;
657 int32_t value = 0;
658
659 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
660 CAM_PRIV_START_ZSL_SNAPSHOT, &value);
661
662 pthread_mutex_unlock(&my_obj->cam_lock);
663 return rc;
664 }
665
666 /*===========================================================================
667 * FUNCTION : mm_camera_stop_zsl_snapshot
668 *
669 * DESCRIPTION: stop zsl capture
670 *
671 * PARAMETERS :
672 * @my_obj : camera object
673 *
674 * RETURN : int32_t type of status
675 * 0 -- success
676 * -1 -- failure
677 *==========================================================================*/
mm_camera_stop_zsl_snapshot(mm_camera_obj_t * my_obj)678 int32_t mm_camera_stop_zsl_snapshot(mm_camera_obj_t *my_obj)
679 {
680 int32_t rc = -1;
681 int32_t value;
682 rc = mm_camera_util_s_ctrl(my_obj->ctrl_fd,
683 CAM_PRIV_STOP_ZSL_SNAPSHOT, &value);
684 pthread_mutex_unlock(&my_obj->cam_lock);
685 return rc;
686 }
687
688 /*===========================================================================
689 * FUNCTION : mm_camera_add_channel
690 *
691 * DESCRIPTION: add a channel
692 *
693 * PARAMETERS :
694 * @my_obj : camera object
695 * @attr : bundle attribute of the channel if needed
696 * @channel_cb : callback function for bundle data notify
697 * @userdata : user data ptr
698 *
699 * RETURN : uint32_t type of channel handle
700 * 0 -- invalid channel handle, meaning the op failed
701 * >0 -- successfully added a channel with a valid handle
702 * NOTE : if no bundle data notify is needed, meaning each stream in the
703 * channel will have its own stream data notify callback, then
704 * attr, channel_cb, and userdata can be NULL. In this case,
705 * no matching logic will be performed in channel for the bundling.
706 *==========================================================================*/
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)707 uint32_t mm_camera_add_channel(mm_camera_obj_t *my_obj,
708 mm_camera_channel_attr_t *attr,
709 mm_camera_buf_notify_t channel_cb,
710 void *userdata)
711 {
712 mm_channel_t *ch_obj = NULL;
713 uint8_t ch_idx = 0;
714 uint32_t ch_hdl = 0;
715
716 for(ch_idx = 0; ch_idx < MM_CAMERA_CHANNEL_MAX; ch_idx++) {
717 if (MM_CHANNEL_STATE_NOTUSED == my_obj->ch[ch_idx].state) {
718 ch_obj = &my_obj->ch[ch_idx];
719 break;
720 }
721 }
722
723 if (NULL != ch_obj) {
724 /* initialize channel obj */
725 memset(ch_obj, 0, sizeof(mm_channel_t));
726 ch_hdl = mm_camera_util_generate_handler(ch_idx);
727 ch_obj->my_hdl = ch_hdl;
728 ch_obj->state = MM_CHANNEL_STATE_STOPPED;
729 ch_obj->cam_obj = my_obj;
730 pthread_mutex_init(&ch_obj->ch_lock, NULL);
731 mm_channel_init(ch_obj, attr, channel_cb, userdata);
732 }
733
734 pthread_mutex_unlock(&my_obj->cam_lock);
735
736 return ch_hdl;
737 }
738
739 /*===========================================================================
740 * FUNCTION : mm_camera_del_channel
741 *
742 * DESCRIPTION: delete a channel by its handle
743 *
744 * PARAMETERS :
745 * @my_obj : camera object
746 * @ch_id : channel handle
747 *
748 * RETURN : int32_t type of status
749 * 0 -- success
750 * -1 -- failure
751 * NOTE : all streams in the channel should be stopped already before
752 * this channel can be deleted.
753 *==========================================================================*/
mm_camera_del_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)754 int32_t mm_camera_del_channel(mm_camera_obj_t *my_obj,
755 uint32_t ch_id)
756 {
757 int32_t rc = -1;
758 mm_channel_t * ch_obj =
759 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
760
761 if (NULL != ch_obj) {
762 pthread_mutex_lock(&ch_obj->ch_lock);
763 pthread_mutex_unlock(&my_obj->cam_lock);
764
765 rc = mm_channel_fsm_fn(ch_obj,
766 MM_CHANNEL_EVT_DELETE,
767 NULL,
768 NULL);
769
770 pthread_mutex_destroy(&ch_obj->ch_lock);
771 memset(ch_obj, 0, sizeof(mm_channel_t));
772 } else {
773 pthread_mutex_unlock(&my_obj->cam_lock);
774 }
775 return rc;
776 }
777
778 /*===========================================================================
779 * FUNCTION : mm_camera_get_bundle_info
780 *
781 * DESCRIPTION: query bundle info of the channel
782 *
783 * PARAMETERS :
784 * @my_obj : camera object
785 * @ch_id : channel handle
786 * @bundle_info : bundle info to be filled in
787 *
788 * RETURN : int32_t type of status
789 * 0 -- success
790 * -1 -- failure
791 * NOTE : all streams in the channel should be stopped already before
792 * this channel can be deleted.
793 *==========================================================================*/
mm_camera_get_bundle_info(mm_camera_obj_t * my_obj,uint32_t ch_id,cam_bundle_config_t * bundle_info)794 int32_t mm_camera_get_bundle_info(mm_camera_obj_t *my_obj,
795 uint32_t ch_id,
796 cam_bundle_config_t *bundle_info)
797 {
798 int32_t rc = -1;
799 mm_channel_t * ch_obj =
800 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
801
802 if (NULL != ch_obj) {
803 pthread_mutex_lock(&ch_obj->ch_lock);
804 pthread_mutex_unlock(&my_obj->cam_lock);
805
806 rc = mm_channel_fsm_fn(ch_obj,
807 MM_CHANNEL_EVT_GET_BUNDLE_INFO,
808 (void *)bundle_info,
809 NULL);
810 } else {
811 pthread_mutex_unlock(&my_obj->cam_lock);
812 }
813 return rc;
814 }
815
816 /*===========================================================================
817 * FUNCTION : mm_camera_add_stream
818 *
819 * DESCRIPTION: add a stream into a channel
820 *
821 * PARAMETERS :
822 * @my_obj : camera object
823 * @ch_id : channel handle
824 *
825 * RETURN : uint32_t type of stream handle
826 * 0 -- invalid stream handle, meaning the op failed
827 * >0 -- successfully added a stream with a valid handle
828 *==========================================================================*/
mm_camera_add_stream(mm_camera_obj_t * my_obj,uint32_t ch_id)829 uint32_t mm_camera_add_stream(mm_camera_obj_t *my_obj,
830 uint32_t ch_id)
831 {
832 uint32_t s_hdl = 0;
833 mm_channel_t * ch_obj =
834 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
835
836 if (NULL != ch_obj) {
837 pthread_mutex_lock(&ch_obj->ch_lock);
838 pthread_mutex_unlock(&my_obj->cam_lock);
839
840 mm_channel_fsm_fn(ch_obj,
841 MM_CHANNEL_EVT_ADD_STREAM,
842 NULL,
843 (void*)&s_hdl);
844 } else {
845 pthread_mutex_unlock(&my_obj->cam_lock);
846 }
847
848 return s_hdl;
849 }
850
851 /*===========================================================================
852 * FUNCTION : mm_camera_del_stream
853 *
854 * DESCRIPTION: delete a stream by its handle
855 *
856 * PARAMETERS :
857 * @my_obj : camera object
858 * @ch_id : channel handle
859 * @stream_id : stream handle
860 *
861 * RETURN : int32_t type of status
862 * 0 -- success
863 * -1 -- failure
864 * NOTE : stream should be stopped already before it can be deleted.
865 *==========================================================================*/
mm_camera_del_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id)866 int32_t mm_camera_del_stream(mm_camera_obj_t *my_obj,
867 uint32_t ch_id,
868 uint32_t stream_id)
869 {
870 int32_t rc = -1;
871 mm_channel_t * ch_obj =
872 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
873
874 if (NULL != ch_obj) {
875 pthread_mutex_lock(&ch_obj->ch_lock);
876 pthread_mutex_unlock(&my_obj->cam_lock);
877
878 rc = mm_channel_fsm_fn(ch_obj,
879 MM_CHANNEL_EVT_DEL_STREAM,
880 (void*)stream_id,
881 NULL);
882 } else {
883 pthread_mutex_unlock(&my_obj->cam_lock);
884 }
885
886 return rc;
887 }
888
889 /*===========================================================================
890 * FUNCTION : mm_camera_config_stream
891 *
892 * DESCRIPTION: configure a stream
893 *
894 * PARAMETERS :
895 * @my_obj : camera object
896 * @ch_id : channel handle
897 * @stream_id : stream handle
898 * @config : stream configuration
899 *
900 * RETURN : int32_t type of status
901 * 0 -- success
902 * -1 -- failure
903 *==========================================================================*/
mm_camera_config_stream(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)904 int32_t mm_camera_config_stream(mm_camera_obj_t *my_obj,
905 uint32_t ch_id,
906 uint32_t stream_id,
907 mm_camera_stream_config_t *config)
908 {
909 int32_t rc = -1;
910 mm_channel_t * ch_obj =
911 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
912 mm_evt_paylod_config_stream_t payload;
913
914 if (NULL != ch_obj) {
915 pthread_mutex_lock(&ch_obj->ch_lock);
916 pthread_mutex_unlock(&my_obj->cam_lock);
917
918 memset(&payload, 0, sizeof(mm_evt_paylod_config_stream_t));
919 payload.stream_id = stream_id;
920 payload.config = config;
921 rc = mm_channel_fsm_fn(ch_obj,
922 MM_CHANNEL_EVT_CONFIG_STREAM,
923 (void*)&payload,
924 NULL);
925 } else {
926 pthread_mutex_unlock(&my_obj->cam_lock);
927 }
928
929 return rc;
930 }
931
932 /*===========================================================================
933 * FUNCTION : mm_camera_start_channel
934 *
935 * DESCRIPTION: start a channel, which will start all streams in the channel
936 *
937 * PARAMETERS :
938 * @my_obj : camera object
939 * @ch_id : channel handle
940 *
941 * RETURN : int32_t type of status
942 * 0 -- success
943 * -1 -- failure
944 *==========================================================================*/
mm_camera_start_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)945 int32_t mm_camera_start_channel(mm_camera_obj_t *my_obj,
946 uint32_t ch_id)
947 {
948 int32_t rc = -1;
949 mm_channel_t * ch_obj =
950 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
951
952 if (NULL != ch_obj) {
953 pthread_mutex_lock(&ch_obj->ch_lock);
954 pthread_mutex_unlock(&my_obj->cam_lock);
955
956 rc = mm_channel_fsm_fn(ch_obj,
957 MM_CHANNEL_EVT_START,
958 NULL,
959 NULL);
960 } else {
961 pthread_mutex_unlock(&my_obj->cam_lock);
962 }
963
964 return rc;
965 }
966
967 /*===========================================================================
968 * FUNCTION : mm_camera_stop_channel
969 *
970 * DESCRIPTION: stop a channel, which will stop all streams in the channel
971 *
972 * PARAMETERS :
973 * @my_obj : camera object
974 * @ch_id : channel handle
975 *
976 * RETURN : int32_t type of status
977 * 0 -- success
978 * -1 -- failure
979 *==========================================================================*/
mm_camera_stop_channel(mm_camera_obj_t * my_obj,uint32_t ch_id)980 int32_t mm_camera_stop_channel(mm_camera_obj_t *my_obj,
981 uint32_t ch_id)
982 {
983 int32_t rc = 0;
984 mm_channel_t * ch_obj =
985 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
986
987 if (NULL != ch_obj) {
988 pthread_mutex_lock(&ch_obj->ch_lock);
989 pthread_mutex_unlock(&my_obj->cam_lock);
990
991 rc = mm_channel_fsm_fn(ch_obj,
992 MM_CHANNEL_EVT_STOP,
993 NULL,
994 NULL);
995 } else {
996 pthread_mutex_unlock(&my_obj->cam_lock);
997 }
998 return rc;
999 }
1000
1001 /*===========================================================================
1002 * FUNCTION : mm_camera_request_super_buf
1003 *
1004 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
1005 * frames from superbuf queue
1006 *
1007 * PARAMETERS :
1008 * @my_obj : camera object
1009 * @ch_id : channel handle
1010 * @num_buf_requested : number of matched frames needed
1011 *
1012 * RETURN : int32_t type of status
1013 * 0 -- success
1014 * -1 -- failure
1015 *==========================================================================*/
mm_camera_request_super_buf(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t num_buf_requested)1016 int32_t mm_camera_request_super_buf(mm_camera_obj_t *my_obj,
1017 uint32_t ch_id,
1018 uint32_t num_buf_requested)
1019 {
1020 int32_t rc = -1;
1021 mm_channel_t * ch_obj =
1022 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1023
1024 if (NULL != ch_obj) {
1025 pthread_mutex_lock(&ch_obj->ch_lock);
1026 pthread_mutex_unlock(&my_obj->cam_lock);
1027
1028 rc = mm_channel_fsm_fn(ch_obj,
1029 MM_CHANNEL_EVT_REQUEST_SUPER_BUF,
1030 (void*)num_buf_requested,
1031 NULL);
1032 } else {
1033 pthread_mutex_unlock(&my_obj->cam_lock);
1034 }
1035
1036 return rc;
1037 }
1038
1039 /*===========================================================================
1040 * FUNCTION : mm_camera_cancel_super_buf_request
1041 *
1042 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
1043 * of matched frames from superbuf queue
1044 *
1045 * PARAMETERS :
1046 * @my_obj : camera object
1047 * @ch_id : channel handle
1048 *
1049 * RETURN : int32_t type of status
1050 * 0 -- success
1051 * -1 -- failure
1052 *==========================================================================*/
mm_camera_cancel_super_buf_request(mm_camera_obj_t * my_obj,uint32_t ch_id)1053 int32_t mm_camera_cancel_super_buf_request(mm_camera_obj_t *my_obj, uint32_t ch_id)
1054 {
1055 int32_t rc = -1;
1056 mm_channel_t * ch_obj =
1057 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1058
1059 if (NULL != ch_obj) {
1060 pthread_mutex_lock(&ch_obj->ch_lock);
1061 pthread_mutex_unlock(&my_obj->cam_lock);
1062
1063 rc = mm_channel_fsm_fn(ch_obj,
1064 MM_CHANNEL_EVT_CANCEL_REQUEST_SUPER_BUF,
1065 NULL,
1066 NULL);
1067 } else {
1068 pthread_mutex_unlock(&my_obj->cam_lock);
1069 }
1070
1071 return rc;
1072 }
1073
1074 /*===========================================================================
1075 * FUNCTION : mm_camera_flush_super_buf_queue
1076 *
1077 * DESCRIPTION: flush out all frames in the superbuf queue
1078 *
1079 * PARAMETERS :
1080 * @my_obj : camera object
1081 * @ch_id : channel handle
1082 *
1083 * RETURN : int32_t type of status
1084 * 0 -- success
1085 * -1 -- failure
1086 *==========================================================================*/
mm_camera_flush_super_buf_queue(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t frame_idx)1087 int32_t mm_camera_flush_super_buf_queue(mm_camera_obj_t *my_obj, uint32_t ch_id,
1088 uint32_t frame_idx)
1089 {
1090 int32_t rc = -1;
1091 mm_channel_t * ch_obj =
1092 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1093
1094 if (NULL != ch_obj) {
1095 pthread_mutex_lock(&ch_obj->ch_lock);
1096 pthread_mutex_unlock(&my_obj->cam_lock);
1097
1098 rc = mm_channel_fsm_fn(ch_obj,
1099 MM_CHANNEL_EVT_FLUSH_SUPER_BUF_QUEUE,
1100 (void *)frame_idx,
1101 NULL);
1102 } else {
1103 pthread_mutex_unlock(&my_obj->cam_lock);
1104 }
1105
1106 return rc;
1107 }
1108
1109 /*===========================================================================
1110 * FUNCTION : mm_camera_config_channel_notify
1111 *
1112 * DESCRIPTION: configures the channel notification mode
1113 *
1114 * PARAMETERS :
1115 * @my_obj : camera object
1116 * @ch_id : channel handle
1117 * @notify_mode : notification mode
1118 *
1119 * RETURN : int32_t type of status
1120 * 0 -- success
1121 * -1 -- failure
1122 *==========================================================================*/
mm_camera_config_channel_notify(mm_camera_obj_t * my_obj,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)1123 int32_t mm_camera_config_channel_notify(mm_camera_obj_t *my_obj,
1124 uint32_t ch_id,
1125 mm_camera_super_buf_notify_mode_t notify_mode)
1126 {
1127 int32_t rc = -1;
1128 mm_channel_t * ch_obj =
1129 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1130
1131 if (NULL != ch_obj) {
1132 pthread_mutex_lock(&ch_obj->ch_lock);
1133 pthread_mutex_unlock(&my_obj->cam_lock);
1134
1135 rc = mm_channel_fsm_fn(ch_obj,
1136 MM_CHANNEL_EVT_CONFIG_NOTIFY_MODE,
1137 (void *)notify_mode,
1138 NULL);
1139 } else {
1140 pthread_mutex_unlock(&my_obj->cam_lock);
1141 }
1142
1143 return rc;
1144 }
1145
1146 /*===========================================================================
1147 * FUNCTION : mm_camera_set_stream_parms
1148 *
1149 * DESCRIPTION: set parameters per stream
1150 *
1151 * PARAMETERS :
1152 * @my_obj : camera object
1153 * @ch_id : channel handle
1154 * @s_id : stream handle
1155 * @parms : ptr to a param struct to be set to server
1156 *
1157 * RETURN : int32_t type of status
1158 * 0 -- success
1159 * -1 -- failure
1160 * NOTE : Assume the parms struct buf is already mapped to server via
1161 * domain socket. Corresponding fields of parameters to be set
1162 * are already filled in by upper layer caller.
1163 *==========================================================================*/
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)1164 int32_t mm_camera_set_stream_parms(mm_camera_obj_t *my_obj,
1165 uint32_t ch_id,
1166 uint32_t s_id,
1167 cam_stream_parm_buffer_t *parms)
1168 {
1169 int32_t rc = -1;
1170 mm_evt_paylod_set_get_stream_parms_t payload;
1171 mm_channel_t * ch_obj =
1172 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1173
1174 if (NULL != ch_obj) {
1175 pthread_mutex_lock(&ch_obj->ch_lock);
1176 pthread_mutex_unlock(&my_obj->cam_lock);
1177
1178 memset(&payload, 0, sizeof(payload));
1179 payload.stream_id = s_id;
1180 payload.parms = parms;
1181
1182 rc = mm_channel_fsm_fn(ch_obj,
1183 MM_CHANNEL_EVT_SET_STREAM_PARM,
1184 (void *)&payload,
1185 NULL);
1186 } else {
1187 pthread_mutex_unlock(&my_obj->cam_lock);
1188 }
1189
1190 return rc;
1191 }
1192
1193 /*===========================================================================
1194 * FUNCTION : mm_camera_get_stream_parms
1195 *
1196 * DESCRIPTION: get parameters per stream
1197 *
1198 * PARAMETERS :
1199 * @my_obj : camera object
1200 * @ch_id : channel handle
1201 * @s_id : stream handle
1202 * @parms : ptr to a param struct to be get from server
1203 *
1204 * RETURN : int32_t type of status
1205 * 0 -- success
1206 * -1 -- failure
1207 * NOTE : Assume the parms struct buf is already mapped to server via
1208 * domain socket. Parameters to be get from server are already
1209 * filled in by upper layer caller. After this call, corresponding
1210 * fields of requested parameters will be filled in by server with
1211 * detailed information.
1212 *==========================================================================*/
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)1213 int32_t mm_camera_get_stream_parms(mm_camera_obj_t *my_obj,
1214 uint32_t ch_id,
1215 uint32_t s_id,
1216 cam_stream_parm_buffer_t *parms)
1217 {
1218 int32_t rc = -1;
1219 mm_evt_paylod_set_get_stream_parms_t payload;
1220 mm_channel_t * ch_obj =
1221 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1222
1223 if (NULL != ch_obj) {
1224 pthread_mutex_lock(&ch_obj->ch_lock);
1225 pthread_mutex_unlock(&my_obj->cam_lock);
1226
1227 memset(&payload, 0, sizeof(payload));
1228 payload.stream_id = s_id;
1229 payload.parms = parms;
1230
1231 rc = mm_channel_fsm_fn(ch_obj,
1232 MM_CHANNEL_EVT_GET_STREAM_PARM,
1233 (void *)&payload,
1234 NULL);
1235 } else {
1236 pthread_mutex_unlock(&my_obj->cam_lock);
1237 }
1238
1239 return rc;
1240 }
1241
1242 /*===========================================================================
1243 * FUNCTION : mm_camera_do_stream_action
1244 *
1245 * DESCRIPTION: request server to perform stream based action. Maybe removed later
1246 * if the functionality is included in mm_camera_set_parms
1247 *
1248 * PARAMETERS :
1249 * @my_obj : camera object
1250 * @ch_id : channel handle
1251 * @s_id : stream handle
1252 * @actions : ptr to an action struct buf to be performed by server
1253 *
1254 * RETURN : int32_t type of status
1255 * 0 -- success
1256 * -1 -- failure
1257 * NOTE : Assume the action struct buf is already mapped to server via
1258 * domain socket. Actions to be performed by server are already
1259 * filled in by upper layer caller.
1260 *==========================================================================*/
mm_camera_do_stream_action(mm_camera_obj_t * my_obj,uint32_t ch_id,uint32_t stream_id,void * actions)1261 int32_t mm_camera_do_stream_action(mm_camera_obj_t *my_obj,
1262 uint32_t ch_id,
1263 uint32_t stream_id,
1264 void *actions)
1265 {
1266 int32_t rc = -1;
1267 mm_evt_paylod_do_stream_action_t payload;
1268 mm_channel_t * ch_obj =
1269 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1270
1271 if (NULL != ch_obj) {
1272 pthread_mutex_lock(&ch_obj->ch_lock);
1273 pthread_mutex_unlock(&my_obj->cam_lock);
1274
1275 memset(&payload, 0, sizeof(payload));
1276 payload.stream_id = stream_id;
1277 payload.actions = actions;
1278
1279 rc = mm_channel_fsm_fn(ch_obj,
1280 MM_CHANNEL_EVT_DO_STREAM_ACTION,
1281 (void*)&payload,
1282 NULL);
1283 } else {
1284 pthread_mutex_unlock(&my_obj->cam_lock);
1285 }
1286
1287 return rc;
1288 }
1289
1290 /*===========================================================================
1291 * FUNCTION : mm_camera_map_stream_buf
1292 *
1293 * DESCRIPTION: mapping stream buffer via domain socket to server
1294 *
1295 * PARAMETERS :
1296 * @my_obj : camera object
1297 * @ch_id : channel handle
1298 * @s_id : stream handle
1299 * @buf_type : type of buffer to be mapped. could be following values:
1300 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1301 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1302 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1303 * @buf_idx : index of buffer within the stream buffers, only valid if
1304 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1305 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1306 * @plane_idx : plane index. If all planes share the same fd,
1307 * plane_idx = -1; otherwise, plean_idx is the
1308 * index to plane (0..num_of_planes)
1309 * @fd : file descriptor of the buffer
1310 * @size : size of the buffer
1311 *
1312 * RETURN : int32_t type of status
1313 * 0 -- success
1314 * -1 -- failure
1315 *==========================================================================*/
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)1316 int32_t mm_camera_map_stream_buf(mm_camera_obj_t *my_obj,
1317 uint32_t ch_id,
1318 uint32_t stream_id,
1319 uint8_t buf_type,
1320 uint32_t buf_idx,
1321 int32_t plane_idx,
1322 int fd,
1323 uint32_t size)
1324 {
1325 int32_t rc = -1;
1326 mm_evt_paylod_map_stream_buf_t payload;
1327 mm_channel_t * ch_obj =
1328 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1329
1330 if (NULL != ch_obj) {
1331 pthread_mutex_lock(&ch_obj->ch_lock);
1332 pthread_mutex_unlock(&my_obj->cam_lock);
1333
1334 memset(&payload, 0, sizeof(payload));
1335 payload.stream_id = stream_id;
1336 payload.buf_type = buf_type;
1337 payload.buf_idx = buf_idx;
1338 payload.plane_idx = plane_idx;
1339 payload.fd = fd;
1340 payload.size = size;
1341 rc = mm_channel_fsm_fn(ch_obj,
1342 MM_CHANNEL_EVT_MAP_STREAM_BUF,
1343 (void*)&payload,
1344 NULL);
1345 } else {
1346 pthread_mutex_unlock(&my_obj->cam_lock);
1347 }
1348
1349 return rc;
1350 }
1351
1352 /*===========================================================================
1353 * FUNCTION : mm_camera_unmap_stream_buf
1354 *
1355 * DESCRIPTION: unmapping stream buffer via domain socket to server
1356 *
1357 * PARAMETERS :
1358 * @my_obj : camera object
1359 * @ch_id : channel handle
1360 * @s_id : stream handle
1361 * @buf_type : type of buffer to be mapped. could be following values:
1362 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1363 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1364 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1365 * @buf_idx : index of buffer within the stream buffers, only valid if
1366 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1367 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1368 * @plane_idx : plane index. If all planes share the same fd,
1369 * plane_idx = -1; otherwise, plean_idx is the
1370 * index to plane (0..num_of_planes)
1371 *
1372 * RETURN : int32_t type of status
1373 * 0 -- success
1374 * -1 -- failure
1375 *==========================================================================*/
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)1376 int32_t mm_camera_unmap_stream_buf(mm_camera_obj_t *my_obj,
1377 uint32_t ch_id,
1378 uint32_t stream_id,
1379 uint8_t buf_type,
1380 uint32_t buf_idx,
1381 int32_t plane_idx)
1382 {
1383 int32_t rc = -1;
1384 mm_evt_paylod_unmap_stream_buf_t payload;
1385 mm_channel_t * ch_obj =
1386 mm_camera_util_get_channel_by_handler(my_obj, ch_id);
1387
1388 if (NULL != ch_obj) {
1389 pthread_mutex_lock(&ch_obj->ch_lock);
1390 pthread_mutex_unlock(&my_obj->cam_lock);
1391
1392 memset(&payload, 0, sizeof(payload));
1393 payload.stream_id = stream_id;
1394 payload.buf_type = buf_type;
1395 payload.buf_idx = buf_idx;
1396 payload.plane_idx = plane_idx;
1397 rc = mm_channel_fsm_fn(ch_obj,
1398 MM_CHANNEL_EVT_UNMAP_STREAM_BUF,
1399 (void*)&payload,
1400 NULL);
1401 } else {
1402 pthread_mutex_unlock(&my_obj->cam_lock);
1403 }
1404
1405 return rc;
1406 }
1407
1408 /*===========================================================================
1409 * FUNCTION : mm_camera_evt_sub
1410 *
1411 * DESCRIPTION: subscribe/unsubscribe event notify from kernel
1412 *
1413 * PARAMETERS :
1414 * @my_obj : camera object
1415 * @reg_flag : 1 -- subscribe ; 0 -- unsubscribe
1416 *
1417 * RETURN : int32_t type of status
1418 * 0 -- success
1419 * -1 -- failure
1420 *==========================================================================*/
mm_camera_evt_sub(mm_camera_obj_t * my_obj,uint8_t reg_flag)1421 int32_t mm_camera_evt_sub(mm_camera_obj_t * my_obj,
1422 uint8_t reg_flag)
1423 {
1424 int32_t rc = 0;
1425 struct v4l2_event_subscription sub;
1426
1427 memset(&sub, 0, sizeof(sub));
1428 sub.type = MSM_CAMERA_V4L2_EVENT_TYPE;
1429 sub.id = MSM_CAMERA_MSM_NOTIFY;
1430 if(FALSE == reg_flag) {
1431 /* unsubscribe */
1432 rc = ioctl(my_obj->ctrl_fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
1433 if (rc < 0) {
1434 CDBG_ERROR("%s: unsubscribe event rc = %d", __func__, rc);
1435 return rc;
1436 }
1437 /* remove evt fd from the polling thraed when unreg the last event */
1438 rc = mm_camera_poll_thread_del_poll_fd(&my_obj->evt_poll_thread,
1439 my_obj->my_hdl,
1440 mm_camera_sync_call);
1441 } else {
1442 rc = ioctl(my_obj->ctrl_fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
1443 if (rc < 0) {
1444 CDBG_ERROR("%s: subscribe event rc = %d", __func__, rc);
1445 return rc;
1446 }
1447 /* add evt fd to polling thread when subscribe the first event */
1448 rc = mm_camera_poll_thread_add_poll_fd(&my_obj->evt_poll_thread,
1449 my_obj->my_hdl,
1450 my_obj->ctrl_fd,
1451 mm_camera_event_notify,
1452 (void*)my_obj,
1453 mm_camera_sync_call);
1454 }
1455 return rc;
1456 }
1457
1458 /*===========================================================================
1459 * FUNCTION : mm_camera_util_wait_for_event
1460 *
1461 * DESCRIPTION: utility function to wait for certain events
1462 *
1463 * PARAMETERS :
1464 * @my_obj : camera object
1465 * @evt_mask : mask for events to be waited. Any of event in the mask would
1466 * trigger the wait to end
1467 * @status : status of the event
1468 *
1469 * RETURN : none
1470 *==========================================================================*/
mm_camera_util_wait_for_event(mm_camera_obj_t * my_obj,uint32_t evt_mask,int32_t * status)1471 void mm_camera_util_wait_for_event(mm_camera_obj_t *my_obj,
1472 uint32_t evt_mask,
1473 int32_t *status)
1474 {
1475 pthread_mutex_lock(&my_obj->evt_lock);
1476 while (!(my_obj->evt_rcvd.server_event_type & evt_mask)) {
1477 pthread_cond_wait(&my_obj->evt_cond, &my_obj->evt_lock);
1478 }
1479 *status = my_obj->evt_rcvd.status;
1480 /* reset local storage for recieved event for next event */
1481 memset(&my_obj->evt_rcvd, 0, sizeof(mm_camera_event_t));
1482 pthread_mutex_unlock(&my_obj->evt_lock);
1483 }
1484
1485 /*===========================================================================
1486 * FUNCTION : mm_camera_util_sendmsg
1487 *
1488 * DESCRIPTION: utility function to send msg via domain socket
1489 *
1490 * PARAMETERS :
1491 * @my_obj : camera object
1492 * @msg : message to be sent
1493 * @buf_size : size of the message to be sent
1494 * @sendfd : >0 if any file descriptor need to be passed across process
1495 *
1496 * RETURN : int32_t type of status
1497 * 0 -- success
1498 * -1 -- failure
1499 *==========================================================================*/
mm_camera_util_sendmsg(mm_camera_obj_t * my_obj,void * msg,uint32_t buf_size,int sendfd)1500 int32_t mm_camera_util_sendmsg(mm_camera_obj_t *my_obj,
1501 void *msg,
1502 uint32_t buf_size,
1503 int sendfd)
1504 {
1505 int32_t rc = -1;
1506 int32_t status;
1507
1508 /* need to lock msg_lock, since sendmsg until reposonse back is deemed as one operation*/
1509 pthread_mutex_lock(&my_obj->msg_lock);
1510 if(mm_camera_socket_sendmsg(my_obj->ds_fd, msg, buf_size, sendfd) > 0) {
1511 /* wait for event that mapping/unmapping is done */
1512 mm_camera_util_wait_for_event(my_obj, CAM_EVENT_TYPE_MAP_UNMAP_DONE, &status);
1513 if (MSM_CAMERA_STATUS_SUCCESS == status) {
1514 rc = 0;
1515 }
1516 }
1517 pthread_mutex_unlock(&my_obj->msg_lock);
1518 return rc;
1519 }
1520
1521 /*===========================================================================
1522 * FUNCTION : mm_camera_map_buf
1523 *
1524 * DESCRIPTION: mapping camera buffer via domain socket to server
1525 *
1526 * PARAMETERS :
1527 * @my_obj : camera object
1528 * @buf_type : type of buffer to be mapped. could be following values:
1529 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1530 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1531 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1532 * @fd : file descriptor of the buffer
1533 * @size : size of the buffer
1534 *
1535 * RETURN : int32_t type of status
1536 * 0 -- success
1537 * -1 -- failure
1538 *==========================================================================*/
mm_camera_map_buf(mm_camera_obj_t * my_obj,uint8_t buf_type,int fd,uint32_t size)1539 int32_t mm_camera_map_buf(mm_camera_obj_t *my_obj,
1540 uint8_t buf_type,
1541 int fd,
1542 uint32_t size)
1543 {
1544 int32_t rc = 0;
1545 cam_sock_packet_t packet;
1546 memset(&packet, 0, sizeof(cam_sock_packet_t));
1547 packet.msg_type = CAM_MAPPING_TYPE_FD_MAPPING;
1548 packet.payload.buf_map.type = buf_type;
1549 packet.payload.buf_map.fd = fd;
1550 packet.payload.buf_map.size = size;
1551 rc = mm_camera_util_sendmsg(my_obj,
1552 &packet,
1553 sizeof(cam_sock_packet_t),
1554 fd);
1555 pthread_mutex_unlock(&my_obj->cam_lock);
1556 return rc;
1557 }
1558
1559 /*===========================================================================
1560 * FUNCTION : mm_camera_unmap_buf
1561 *
1562 * DESCRIPTION: unmapping camera buffer via domain socket to server
1563 *
1564 * PARAMETERS :
1565 * @my_obj : camera object
1566 * @buf_type : type of buffer to be mapped. could be following values:
1567 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1568 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1569 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1570 *
1571 * RETURN : int32_t type of status
1572 * 0 -- success
1573 * -1 -- failure
1574 *==========================================================================*/
mm_camera_unmap_buf(mm_camera_obj_t * my_obj,uint8_t buf_type)1575 int32_t mm_camera_unmap_buf(mm_camera_obj_t *my_obj,
1576 uint8_t buf_type)
1577 {
1578 int32_t rc = 0;
1579 cam_sock_packet_t packet;
1580 memset(&packet, 0, sizeof(cam_sock_packet_t));
1581 packet.msg_type = CAM_MAPPING_TYPE_FD_UNMAPPING;
1582 packet.payload.buf_unmap.type = buf_type;
1583 rc = mm_camera_util_sendmsg(my_obj,
1584 &packet,
1585 sizeof(cam_sock_packet_t),
1586 0);
1587 pthread_mutex_unlock(&my_obj->cam_lock);
1588 return rc;
1589 }
1590
1591 /*===========================================================================
1592 * FUNCTION : mm_camera_util_s_ctrl
1593 *
1594 * DESCRIPTION: utility function to send v4l2 ioctl for s_ctrl
1595 *
1596 * PARAMETERS :
1597 * @fd : file descritpor for sending ioctl
1598 * @id : control id
1599 * @value : value of the ioctl to be sent
1600 *
1601 * RETURN : int32_t type of status
1602 * 0 -- success
1603 * -1 -- failure
1604 *==========================================================================*/
mm_camera_util_s_ctrl(int32_t fd,uint32_t id,int32_t * value)1605 int32_t mm_camera_util_s_ctrl(int32_t fd, uint32_t id, int32_t *value)
1606 {
1607 int rc = 0;
1608 struct v4l2_control control;
1609
1610 memset(&control, 0, sizeof(control));
1611 control.id = id;
1612 if (value != NULL) {
1613 control.value = *value;
1614 }
1615 rc = ioctl(fd, VIDIOC_S_CTRL, &control);
1616
1617 CDBG("%s: fd=%d, S_CTRL, id=0x%x, value = 0x%x, rc = %d\n",
1618 __func__, fd, id, (uint32_t)value, rc);
1619 if (value != NULL) {
1620 *value = control.value;
1621 }
1622 return (rc >= 0)? 0 : -1;
1623 }
1624
1625 /*===========================================================================
1626 * FUNCTION : mm_camera_util_g_ctrl
1627 *
1628 * DESCRIPTION: utility function to send v4l2 ioctl for g_ctrl
1629 *
1630 * PARAMETERS :
1631 * @fd : file descritpor for sending ioctl
1632 * @id : control id
1633 * @value : value of the ioctl to be sent
1634 *
1635 * RETURN : int32_t type of status
1636 * 0 -- success
1637 * -1 -- failure
1638 *==========================================================================*/
mm_camera_util_g_ctrl(int32_t fd,uint32_t id,int32_t * value)1639 int32_t mm_camera_util_g_ctrl( int32_t fd, uint32_t id, int32_t *value)
1640 {
1641 int rc = 0;
1642 struct v4l2_control control;
1643
1644 memset(&control, 0, sizeof(control));
1645 control.id = id;
1646 if (value != NULL) {
1647 control.value = *value;
1648 }
1649 rc = ioctl(fd, VIDIOC_G_CTRL, &control);
1650 CDBG("%s: fd=%d, G_CTRL, id=0x%x, rc = %d\n", __func__, fd, id, rc);
1651 if (value != NULL) {
1652 *value = control.value;
1653 }
1654 return (rc >= 0)? 0 : -1;
1655 }
1656