1 /* Copyright (c) 2012-2013, 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 #include <linux/media.h>
38
39 #include "mm_camera_dbg.h"
40 #include "mm_camera_interface.h"
41 #include "mm_camera_sock.h"
42 #include "mm_camera.h"
43
44 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
45
46 static mm_camera_ctrl_t g_cam_ctrl = {0, {{0}}, {0}};
47
48 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
49 static uint16_t g_handler_history_count = 0; /* history count for handler */
50
51 /*===========================================================================
52 * FUNCTION : mm_camera_util_generate_handler
53 *
54 * DESCRIPTION: utility function to generate handler for camera/channel/stream
55 *
56 * PARAMETERS :
57 * @index: index of the object to have handler
58 *
59 * RETURN : uint32_t type of handle that uniquely identify the object
60 *==========================================================================*/
mm_camera_util_generate_handler(uint8_t index)61 uint32_t mm_camera_util_generate_handler(uint8_t index)
62 {
63 uint32_t handler = 0;
64 pthread_mutex_lock(&g_handler_lock);
65 g_handler_history_count++;
66 if (0 == g_handler_history_count) {
67 g_handler_history_count++;
68 }
69 handler = g_handler_history_count;
70 handler = (handler<<8) | index;
71 pthread_mutex_unlock(&g_handler_lock);
72 return handler;
73 }
74
75 /*===========================================================================
76 * FUNCTION : mm_camera_util_get_index_by_handler
77 *
78 * DESCRIPTION: utility function to get index from handle
79 *
80 * PARAMETERS :
81 * @handler: object handle
82 *
83 * RETURN : uint8_t type of index derived from handle
84 *==========================================================================*/
mm_camera_util_get_index_by_handler(uint32_t handler)85 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
86 {
87 return (handler&0x000000ff);
88 }
89
90 /*===========================================================================
91 * FUNCTION : mm_camera_util_get_dev_name
92 *
93 * DESCRIPTION: utility function to get device name from camera handle
94 *
95 * PARAMETERS :
96 * @cam_handle: camera handle
97 *
98 * RETURN : char ptr to the device name stored in global variable
99 * NOTE : caller should not free the char ptr
100 *==========================================================================*/
mm_camera_util_get_dev_name(uint32_t cam_handle)101 const char *mm_camera_util_get_dev_name(uint32_t cam_handle)
102 {
103 char *dev_name = NULL;
104 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
105 if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) {
106 dev_name = g_cam_ctrl.video_dev_name[cam_idx];
107 }
108 return dev_name;
109 }
110
111 /*===========================================================================
112 * FUNCTION : mm_camera_util_get_camera_by_handler
113 *
114 * DESCRIPTION: utility function to get camera object from camera handle
115 *
116 * PARAMETERS :
117 * @cam_handle: camera handle
118 *
119 * RETURN : ptr to the camera object stored in global variable
120 * NOTE : caller should not free the camera object ptr
121 *==========================================================================*/
mm_camera_util_get_camera_by_handler(uint32_t cam_handle)122 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle)
123 {
124 mm_camera_obj_t *cam_obj = NULL;
125 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
126
127 if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS &&
128 (NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
129 (cam_handle == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
130 cam_obj = g_cam_ctrl.cam_obj[cam_idx];
131 }
132 return cam_obj;
133 }
134
135 /*===========================================================================
136 * FUNCTION : mm_camera_intf_query_capability
137 *
138 * DESCRIPTION: query camera capability
139 *
140 * PARAMETERS :
141 * @camera_handle: camera handle
142 *
143 * RETURN : int32_t type of status
144 * 0 -- success
145 * -1 -- failure
146 *==========================================================================*/
mm_camera_intf_query_capability(uint32_t camera_handle)147 static int32_t mm_camera_intf_query_capability(uint32_t camera_handle)
148 {
149 int32_t rc = -1;
150 mm_camera_obj_t * my_obj = NULL;
151
152 CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
153
154 pthread_mutex_lock(&g_intf_lock);
155 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
156
157 if(my_obj) {
158 pthread_mutex_lock(&my_obj->cam_lock);
159 pthread_mutex_unlock(&g_intf_lock);
160 rc = mm_camera_query_capability(my_obj);
161 } else {
162 pthread_mutex_unlock(&g_intf_lock);
163 }
164 CDBG("%s :X rc = %d", __func__, rc);
165 return rc;
166 }
167
168 /*===========================================================================
169 * FUNCTION : mm_camera_intf_set_parms
170 *
171 * DESCRIPTION: set parameters per camera
172 *
173 * PARAMETERS :
174 * @camera_handle: camera handle
175 * @parms : ptr to a param struct to be set to server
176 *
177 * RETURN : int32_t type of status
178 * 0 -- success
179 * -1 -- failure
180 * NOTE : Assume the parms struct buf is already mapped to server via
181 * domain socket. Corresponding fields of parameters to be set
182 * are already filled in by upper layer caller.
183 *==========================================================================*/
mm_camera_intf_set_parms(uint32_t camera_handle,parm_buffer_t * parms)184 static int32_t mm_camera_intf_set_parms(uint32_t camera_handle,
185 parm_buffer_t *parms)
186 {
187 int32_t rc = -1;
188 mm_camera_obj_t * my_obj = NULL;
189
190 pthread_mutex_lock(&g_intf_lock);
191 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
192
193 if(my_obj) {
194 pthread_mutex_lock(&my_obj->cam_lock);
195 pthread_mutex_unlock(&g_intf_lock);
196 rc = mm_camera_set_parms(my_obj, parms);
197 } else {
198 pthread_mutex_unlock(&g_intf_lock);
199 }
200 return rc;
201 }
202
203 /*===========================================================================
204 * FUNCTION : mm_camera_intf_get_parms
205 *
206 * DESCRIPTION: get parameters per camera
207 *
208 * PARAMETERS :
209 * @camera_handle: camera handle
210 * @parms : ptr to a param struct to be get from server
211 *
212 * RETURN : int32_t type of status
213 * 0 -- success
214 * -1 -- failure
215 * NOTE : Assume the parms struct buf is already mapped to server via
216 * domain socket. Parameters to be get from server are already
217 * filled in by upper layer caller. After this call, corresponding
218 * fields of requested parameters will be filled in by server with
219 * detailed information.
220 *==========================================================================*/
mm_camera_intf_get_parms(uint32_t camera_handle,parm_buffer_t * parms)221 static int32_t mm_camera_intf_get_parms(uint32_t camera_handle,
222 parm_buffer_t *parms)
223 {
224 int32_t rc = -1;
225 mm_camera_obj_t * my_obj = NULL;
226
227 pthread_mutex_lock(&g_intf_lock);
228 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
229
230 if(my_obj) {
231 pthread_mutex_lock(&my_obj->cam_lock);
232 pthread_mutex_unlock(&g_intf_lock);
233 rc = mm_camera_get_parms(my_obj, parms);
234 } else {
235 pthread_mutex_unlock(&g_intf_lock);
236 }
237 return rc;
238 }
239
240 /*===========================================================================
241 * FUNCTION : mm_camera_intf_do_auto_focus
242 *
243 * DESCRIPTION: performing auto focus
244 *
245 * PARAMETERS :
246 * @camera_handle: camera handle
247 *
248 * RETURN : int32_t type of status
249 * 0 -- success
250 * -1 -- failure
251 * NOTE : if this call success, we will always assume there will
252 * be an auto_focus event following up.
253 *==========================================================================*/
mm_camera_intf_do_auto_focus(uint32_t camera_handle)254 static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle)
255 {
256 int32_t rc = -1;
257 mm_camera_obj_t * my_obj = NULL;
258
259 pthread_mutex_lock(&g_intf_lock);
260 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
261
262 if(my_obj) {
263 pthread_mutex_lock(&my_obj->cam_lock);
264 pthread_mutex_unlock(&g_intf_lock);
265 rc = mm_camera_do_auto_focus(my_obj);
266 } else {
267 pthread_mutex_unlock(&g_intf_lock);
268 }
269 return rc;
270 }
271
272 /*===========================================================================
273 * FUNCTION : mm_camera_intf_cancel_auto_focus
274 *
275 * DESCRIPTION: cancel auto focus
276 *
277 * PARAMETERS :
278 * @camera_handle: camera handle
279 *
280 * RETURN : int32_t type of status
281 * 0 -- success
282 * -1 -- failure
283 *==========================================================================*/
mm_camera_intf_cancel_auto_focus(uint32_t camera_handle)284 static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle)
285 {
286 int32_t rc = -1;
287 mm_camera_obj_t * my_obj = NULL;
288
289 pthread_mutex_lock(&g_intf_lock);
290 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
291
292 if(my_obj) {
293 pthread_mutex_lock(&my_obj->cam_lock);
294 pthread_mutex_unlock(&g_intf_lock);
295 rc = mm_camera_cancel_auto_focus(my_obj);
296 } else {
297 pthread_mutex_unlock(&g_intf_lock);
298 }
299 return rc;
300 }
301
302 /*===========================================================================
303 * FUNCTION : mm_camera_intf_prepare_snapshot
304 *
305 * DESCRIPTION: prepare hardware for snapshot
306 *
307 * PARAMETERS :
308 * @camera_handle: camera handle
309 * @do_af_flag : flag indicating if AF is needed
310 *
311 * RETURN : int32_t type of status
312 * 0 -- success
313 * -1 -- failure
314 *==========================================================================*/
mm_camera_intf_prepare_snapshot(uint32_t camera_handle,int32_t do_af_flag)315 static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle,
316 int32_t do_af_flag)
317 {
318 int32_t rc = -1;
319 mm_camera_obj_t * my_obj = NULL;
320
321 pthread_mutex_lock(&g_intf_lock);
322 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
323
324 if(my_obj) {
325 pthread_mutex_lock(&my_obj->cam_lock);
326 pthread_mutex_unlock(&g_intf_lock);
327 rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
328 } else {
329 pthread_mutex_unlock(&g_intf_lock);
330 }
331 return rc;
332 }
333
334 /*===========================================================================
335 * FUNCTION : mm_camera_intf_start_zsl_snapshot
336 *
337 * DESCRIPTION: start zsl snapshot
338 *
339 * PARAMETERS :
340 * @camera_handle: camera handle
341 *
342 * RETURN : int32_t type of status
343 * 0 -- success
344 * -1 -- failure
345 *==========================================================================*/
mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle)346 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle)
347 {
348 int32_t rc = -1;
349 mm_camera_obj_t * my_obj = NULL;
350
351 pthread_mutex_lock(&g_intf_lock);
352 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
353
354 if(my_obj) {
355 pthread_mutex_lock(&my_obj->cam_lock);
356 pthread_mutex_unlock(&g_intf_lock);
357 rc = mm_camera_start_zsl_snapshot(my_obj);
358 } else {
359 pthread_mutex_unlock(&g_intf_lock);
360 }
361 return rc;
362 }
363
364 /*===========================================================================
365 * FUNCTION : mm_camera_intf_stop_zsl_snapshot
366 *
367 * DESCRIPTION: stop zsl snapshot
368 *
369 * PARAMETERS :
370 * @camera_handle: camera handle
371 *
372 * RETURN : int32_t type of status
373 * 0 -- success
374 * -1 -- failure
375 *==========================================================================*/
mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle)376 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle)
377 {
378 int32_t rc = -1;
379 mm_camera_obj_t * my_obj = NULL;
380
381 pthread_mutex_lock(&g_intf_lock);
382 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
383
384 if(my_obj) {
385 pthread_mutex_lock(&my_obj->cam_lock);
386 pthread_mutex_unlock(&g_intf_lock);
387 rc = mm_camera_stop_zsl_snapshot(my_obj);
388 } else {
389 pthread_mutex_unlock(&g_intf_lock);
390 }
391 return rc;
392 }
393
394 /*===========================================================================
395 * FUNCTION : mm_camera_intf_close
396 *
397 * DESCRIPTION: close a camera by its handle
398 *
399 * PARAMETERS :
400 * @camera_handle: camera handle
401 *
402 * RETURN : int32_t type of status
403 * 0 -- success
404 * -1 -- failure
405 *==========================================================================*/
mm_camera_intf_close(uint32_t camera_handle)406 static int32_t mm_camera_intf_close(uint32_t camera_handle)
407 {
408 int32_t rc = -1;
409 uint8_t cam_idx = camera_handle & 0x00ff;
410 mm_camera_obj_t * my_obj = NULL;
411
412 CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
413
414 pthread_mutex_lock(&g_intf_lock);
415 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
416
417 if (my_obj){
418 my_obj->ref_count--;
419
420 if(my_obj->ref_count > 0) {
421 /* still have reference to obj, return here */
422 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
423 pthread_mutex_unlock(&g_intf_lock);
424 rc = 0;
425 } else {
426 /* need close camera here as no other reference
427 * first empty g_cam_ctrl's referent to cam_obj */
428 g_cam_ctrl.cam_obj[cam_idx] = NULL;
429
430 pthread_mutex_lock(&my_obj->cam_lock);
431 pthread_mutex_unlock(&g_intf_lock);
432
433 rc = mm_camera_close(my_obj);
434
435 pthread_mutex_destroy(&my_obj->cam_lock);
436 free(my_obj);
437 }
438 } else {
439 pthread_mutex_unlock(&g_intf_lock);
440 }
441
442 return rc;
443 }
444
445 /*===========================================================================
446 * FUNCTION : mm_camera_intf_add_channel
447 *
448 * DESCRIPTION: add a channel
449 *
450 * PARAMETERS :
451 * @camera_handle: camera handle
452 * @attr : bundle attribute of the channel if needed
453 * @channel_cb : callback function for bundle data notify
454 * @userdata : user data ptr
455 *
456 * RETURN : uint32_t type of channel handle
457 * 0 -- invalid channel handle, meaning the op failed
458 * >0 -- successfully added a channel with a valid handle
459 * NOTE : if no bundle data notify is needed, meaning each stream in the
460 * channel will have its own stream data notify callback, then
461 * attr, channel_cb, and userdata can be NULL. In this case,
462 * no matching logic will be performed in channel for the bundling.
463 *==========================================================================*/
mm_camera_intf_add_channel(uint32_t camera_handle,mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t channel_cb,void * userdata)464 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle,
465 mm_camera_channel_attr_t *attr,
466 mm_camera_buf_notify_t channel_cb,
467 void *userdata)
468 {
469 uint32_t ch_id = 0;
470 mm_camera_obj_t * my_obj = NULL;
471
472 CDBG("%s :E camera_handler = %d", __func__, camera_handle);
473 pthread_mutex_lock(&g_intf_lock);
474 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
475
476 if(my_obj) {
477 pthread_mutex_lock(&my_obj->cam_lock);
478 pthread_mutex_unlock(&g_intf_lock);
479 ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
480 } else {
481 pthread_mutex_unlock(&g_intf_lock);
482 }
483 CDBG("%s :X ch_id = %d", __func__, ch_id);
484 return ch_id;
485 }
486
487 /*===========================================================================
488 * FUNCTION : mm_camera_intf_del_channel
489 *
490 * DESCRIPTION: delete a channel by its handle
491 *
492 * PARAMETERS :
493 * @camera_handle: camera handle
494 * @ch_id : channel handle
495 *
496 * RETURN : int32_t type of status
497 * 0 -- success
498 * -1 -- failure
499 * NOTE : all streams in the channel should be stopped already before
500 * this channel can be deleted.
501 *==========================================================================*/
mm_camera_intf_del_channel(uint32_t camera_handle,uint32_t ch_id)502 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle,
503 uint32_t ch_id)
504 {
505 int32_t rc = -1;
506 mm_camera_obj_t * my_obj = NULL;
507
508 CDBG("%s :E ch_id = %d", __func__, ch_id);
509 pthread_mutex_lock(&g_intf_lock);
510 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
511
512 if(my_obj) {
513 pthread_mutex_lock(&my_obj->cam_lock);
514 pthread_mutex_unlock(&g_intf_lock);
515 rc = mm_camera_del_channel(my_obj, ch_id);
516 } else {
517 pthread_mutex_unlock(&g_intf_lock);
518 }
519 CDBG("%s :X", __func__);
520 return rc;
521 }
522
523 /*===========================================================================
524 * FUNCTION : mm_camera_intf_get_bundle_info
525 *
526 * DESCRIPTION: query bundle info of the channel
527 *
528 * PARAMETERS :
529 * @camera_handle: camera handle
530 * @ch_id : channel handle
531 * @bundle_info : bundle info to be filled in
532 *
533 * RETURN : int32_t type of status
534 * 0 -- success
535 * -1 -- failure
536 * NOTE : all streams in the channel should be stopped already before
537 * this channel can be deleted.
538 *==========================================================================*/
mm_camera_intf_get_bundle_info(uint32_t camera_handle,uint32_t ch_id,cam_bundle_config_t * bundle_info)539 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle,
540 uint32_t ch_id,
541 cam_bundle_config_t *bundle_info)
542 {
543 int32_t rc = -1;
544 mm_camera_obj_t * my_obj = NULL;
545
546 CDBG("%s :E ch_id = %d", __func__, ch_id);
547 pthread_mutex_lock(&g_intf_lock);
548 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
549
550 if(my_obj) {
551 pthread_mutex_lock(&my_obj->cam_lock);
552 pthread_mutex_unlock(&g_intf_lock);
553 rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
554 } else {
555 pthread_mutex_unlock(&g_intf_lock);
556 }
557 CDBG("%s :X", __func__);
558 return rc;
559 }
560
561 /*===========================================================================
562 * FUNCTION : mm_camera_intf_register_event_notify
563 *
564 * DESCRIPTION: register for event notify
565 *
566 * PARAMETERS :
567 * @camera_handle: camera handle
568 * @evt_cb : callback for event notify
569 * @user_data : user data ptr
570 *
571 * RETURN : int32_t type of status
572 * 0 -- success
573 * -1 -- failure
574 *==========================================================================*/
mm_camera_intf_register_event_notify(uint32_t camera_handle,mm_camera_event_notify_t evt_cb,void * user_data)575 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle,
576 mm_camera_event_notify_t evt_cb,
577 void * user_data)
578 {
579 int32_t rc = -1;
580 mm_camera_obj_t * my_obj = NULL;
581
582 CDBG("%s :E ", __func__);
583 pthread_mutex_lock(&g_intf_lock);
584 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
585
586 if(my_obj) {
587 pthread_mutex_lock(&my_obj->cam_lock);
588 pthread_mutex_unlock(&g_intf_lock);
589 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
590 } else {
591 pthread_mutex_unlock(&g_intf_lock);
592 }
593 CDBG("%s :E rc = %d", __func__, rc);
594 return rc;
595 }
596
597 /*===========================================================================
598 * FUNCTION : mm_camera_intf_qbuf
599 *
600 * DESCRIPTION: enqueue buffer back to kernel
601 *
602 * PARAMETERS :
603 * @camera_handle: camera handle
604 * @ch_id : channel handle
605 * @buf : buf ptr to be enqueued
606 *
607 * RETURN : int32_t type of status
608 * 0 -- success
609 * -1 -- failure
610 *==========================================================================*/
mm_camera_intf_qbuf(uint32_t camera_handle,uint32_t ch_id,mm_camera_buf_def_t * buf)611 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle,
612 uint32_t ch_id,
613 mm_camera_buf_def_t *buf)
614 {
615 int32_t rc = -1;
616 mm_camera_obj_t * my_obj = NULL;
617
618 pthread_mutex_lock(&g_intf_lock);
619 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
620
621 if(my_obj) {
622 pthread_mutex_lock(&my_obj->cam_lock);
623 pthread_mutex_unlock(&g_intf_lock);
624 rc = mm_camera_qbuf(my_obj, ch_id, buf);
625 } else {
626 pthread_mutex_unlock(&g_intf_lock);
627 }
628 CDBG("%s :X evt_type = %d",__func__,rc);
629 return rc;
630 }
631
632 /*===========================================================================
633 * FUNCTION : mm_camera_intf_add_stream
634 *
635 * DESCRIPTION: add a stream into a channel
636 *
637 * PARAMETERS :
638 * @camera_handle: camera handle
639 * @ch_id : channel handle
640 *
641 * RETURN : uint32_t type of stream handle
642 * 0 -- invalid stream handle, meaning the op failed
643 * >0 -- successfully added a stream with a valid handle
644 *==========================================================================*/
mm_camera_intf_add_stream(uint32_t camera_handle,uint32_t ch_id)645 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle,
646 uint32_t ch_id)
647 {
648 uint32_t stream_id = 0;
649 mm_camera_obj_t * my_obj = NULL;
650
651 CDBG("%s : E handle = %d ch_id = %d",
652 __func__, camera_handle, ch_id);
653
654 pthread_mutex_lock(&g_intf_lock);
655 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
656
657 if(my_obj) {
658 pthread_mutex_lock(&my_obj->cam_lock);
659 pthread_mutex_unlock(&g_intf_lock);
660 stream_id = mm_camera_add_stream(my_obj, ch_id);
661 } else {
662 pthread_mutex_unlock(&g_intf_lock);
663 }
664 CDBG("%s :X stream_id = %d", __func__, stream_id);
665 return stream_id;
666 }
667
668 /*===========================================================================
669 * FUNCTION : mm_camera_intf_del_stream
670 *
671 * DESCRIPTION: delete a stream by its handle
672 *
673 * PARAMETERS :
674 * @camera_handle: camera handle
675 * @ch_id : channel handle
676 * @stream_id : stream handle
677 *
678 * RETURN : int32_t type of status
679 * 0 -- success
680 * -1 -- failure
681 * NOTE : stream should be stopped already before it can be deleted.
682 *==========================================================================*/
mm_camera_intf_del_stream(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id)683 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle,
684 uint32_t ch_id,
685 uint32_t stream_id)
686 {
687 int32_t rc = -1;
688 mm_camera_obj_t * my_obj = NULL;
689
690 CDBG("%s : E handle = %d ch_id = %d stream_id = %d",
691 __func__, camera_handle, ch_id, stream_id);
692
693 pthread_mutex_lock(&g_intf_lock);
694 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
695
696 if(my_obj) {
697 pthread_mutex_lock(&my_obj->cam_lock);
698 pthread_mutex_unlock(&g_intf_lock);
699 rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
700 } else {
701 pthread_mutex_unlock(&g_intf_lock);
702 }
703 CDBG("%s :X rc = %d", __func__, rc);
704 return rc;
705 }
706
707 /*===========================================================================
708 * FUNCTION : mm_camera_intf_config_stream
709 *
710 * DESCRIPTION: configure a stream
711 *
712 * PARAMETERS :
713 * @camera_handle: camera handle
714 * @ch_id : channel handle
715 * @stream_id : stream handle
716 * @config : stream configuration
717 *
718 * RETURN : int32_t type of status
719 * 0 -- success
720 * -1 -- failure
721 *==========================================================================*/
mm_camera_intf_config_stream(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)722 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle,
723 uint32_t ch_id,
724 uint32_t stream_id,
725 mm_camera_stream_config_t *config)
726 {
727 int32_t rc = -1;
728 mm_camera_obj_t * my_obj = NULL;
729
730 CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",
731 __func__, camera_handle, ch_id, stream_id);
732
733 pthread_mutex_lock(&g_intf_lock);
734 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
735
736 CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
737
738 if(my_obj) {
739 pthread_mutex_lock(&my_obj->cam_lock);
740 pthread_mutex_unlock(&g_intf_lock);
741 rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
742 } else {
743 pthread_mutex_unlock(&g_intf_lock);
744 }
745 CDBG("%s :X rc = %d", __func__, rc);
746 return rc;
747 }
748
749 /*===========================================================================
750 * FUNCTION : mm_camera_intf_start_channel
751 *
752 * DESCRIPTION: start a channel, which will start all streams in the channel
753 *
754 * PARAMETERS :
755 * @camera_handle: camera handle
756 * @ch_id : channel handle
757 *
758 * RETURN : int32_t type of status
759 * 0 -- success
760 * -1 -- failure
761 *==========================================================================*/
mm_camera_intf_start_channel(uint32_t camera_handle,uint32_t ch_id)762 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle,
763 uint32_t ch_id)
764 {
765 int32_t rc = -1;
766 mm_camera_obj_t * my_obj = NULL;
767
768 pthread_mutex_lock(&g_intf_lock);
769 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
770
771 if(my_obj) {
772 pthread_mutex_lock(&my_obj->cam_lock);
773 pthread_mutex_unlock(&g_intf_lock);
774 rc = mm_camera_start_channel(my_obj, ch_id);
775 } else {
776 pthread_mutex_unlock(&g_intf_lock);
777 }
778 CDBG("%s :X rc = %d", __func__, rc);
779 return rc;
780 }
781
782 /*===========================================================================
783 * FUNCTION : mm_camera_intf_stop_channel
784 *
785 * DESCRIPTION: stop a channel, which will stop all streams in the channel
786 *
787 * PARAMETERS :
788 * @camera_handle: camera handle
789 * @ch_id : channel handle
790 *
791 * RETURN : int32_t type of status
792 * 0 -- success
793 * -1 -- failure
794 *==========================================================================*/
mm_camera_intf_stop_channel(uint32_t camera_handle,uint32_t ch_id)795 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle,
796 uint32_t ch_id)
797 {
798 int32_t rc = -1;
799 mm_camera_obj_t * my_obj = NULL;
800
801 pthread_mutex_lock(&g_intf_lock);
802 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
803
804 if(my_obj) {
805 pthread_mutex_lock(&my_obj->cam_lock);
806 pthread_mutex_unlock(&g_intf_lock);
807 rc = mm_camera_stop_channel(my_obj, ch_id);
808 } else {
809 pthread_mutex_unlock(&g_intf_lock);
810 }
811 CDBG("%s :X rc = %d", __func__, rc);
812 return rc;
813 }
814
815 /*===========================================================================
816 * FUNCTION : mm_camera_intf_request_super_buf
817 *
818 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
819 * frames from superbuf queue
820 *
821 * PARAMETERS :
822 * @camera_handle: camera handle
823 * @ch_id : channel handle
824 * @num_buf_requested : number of matched frames needed
825 *
826 * RETURN : int32_t type of status
827 * 0 -- success
828 * -1 -- failure
829 *==========================================================================*/
mm_camera_intf_request_super_buf(uint32_t camera_handle,uint32_t ch_id,uint32_t num_buf_requested)830 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle,
831 uint32_t ch_id,
832 uint32_t num_buf_requested)
833 {
834 int32_t rc = -1;
835 CDBG("%s :E camera_handler = %d,ch_id = %d",
836 __func__, camera_handle, ch_id);
837 mm_camera_obj_t * my_obj = NULL;
838
839 pthread_mutex_lock(&g_intf_lock);
840 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
841
842 if(my_obj) {
843 pthread_mutex_lock(&my_obj->cam_lock);
844 pthread_mutex_unlock(&g_intf_lock);
845 rc = mm_camera_request_super_buf(my_obj, ch_id, num_buf_requested);
846 } else {
847 pthread_mutex_unlock(&g_intf_lock);
848 }
849 CDBG("%s :X rc = %d", __func__, rc);
850 return rc;
851 }
852
853 /*===========================================================================
854 * FUNCTION : mm_camera_intf_cancel_super_buf_request
855 *
856 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
857 * of matched frames from superbuf queue
858 *
859 * PARAMETERS :
860 * @camera_handle: camera handle
861 * @ch_id : channel handle
862 *
863 * RETURN : int32_t type of status
864 * 0 -- success
865 * -1 -- failure
866 *==========================================================================*/
mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,uint32_t ch_id)867 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,
868 uint32_t ch_id)
869 {
870 int32_t rc = -1;
871 mm_camera_obj_t * my_obj = NULL;
872
873 CDBG("%s :E camera_handler = %d,ch_id = %d",
874 __func__, camera_handle, ch_id);
875 pthread_mutex_lock(&g_intf_lock);
876 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
877
878 if(my_obj) {
879 pthread_mutex_lock(&my_obj->cam_lock);
880 pthread_mutex_unlock(&g_intf_lock);
881 rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
882 } else {
883 pthread_mutex_unlock(&g_intf_lock);
884 }
885 CDBG("%s :X rc = %d", __func__, rc);
886 return rc;
887 }
888
889 /*===========================================================================
890 * FUNCTION : mm_camera_intf_flush_super_buf_queue
891 *
892 * DESCRIPTION: flush out all frames in the superbuf queue
893 *
894 * PARAMETERS :
895 * @camera_handle: camera handle
896 * @ch_id : channel handle
897 * @frame_idx : frame index
898 *
899 * RETURN : int32_t type of status
900 * 0 -- success
901 * -1 -- failure
902 *==========================================================================*/
mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,uint32_t ch_id,uint32_t frame_idx)903 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,
904 uint32_t ch_id, uint32_t frame_idx)
905 {
906 int32_t rc = -1;
907 mm_camera_obj_t * my_obj = NULL;
908
909 CDBG("%s :E camera_handler = %d,ch_id = %d",
910 __func__, camera_handle, ch_id);
911 pthread_mutex_lock(&g_intf_lock);
912 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
913
914 if(my_obj) {
915 pthread_mutex_lock(&my_obj->cam_lock);
916 pthread_mutex_unlock(&g_intf_lock);
917 rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
918 } else {
919 pthread_mutex_unlock(&g_intf_lock);
920 }
921 CDBG("%s :X rc = %d", __func__, rc);
922 return rc;
923 }
924
925 /*===========================================================================
926 * FUNCTION : mm_camera_intf_configure_notify_mode
927 *
928 * DESCRIPTION: Configures channel notification mode
929 *
930 * PARAMETERS :
931 * @camera_handle: camera handle
932 * @ch_id : channel handle
933 * @notify_mode : notification mode
934 *
935 * RETURN : int32_t type of status
936 * 0 -- success
937 * -1 -- failure
938 *==========================================================================*/
mm_camera_intf_configure_notify_mode(uint32_t camera_handle,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)939 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle,
940 uint32_t ch_id,
941 mm_camera_super_buf_notify_mode_t notify_mode)
942 {
943 int32_t rc = -1;
944 mm_camera_obj_t * my_obj = NULL;
945
946 CDBG("%s :E camera_handler = %d,ch_id = %d",
947 __func__, camera_handle, ch_id);
948 pthread_mutex_lock(&g_intf_lock);
949 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
950
951 if(my_obj) {
952 pthread_mutex_lock(&my_obj->cam_lock);
953 pthread_mutex_unlock(&g_intf_lock);
954 rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
955 } else {
956 pthread_mutex_unlock(&g_intf_lock);
957 }
958 CDBG("%s :X rc = %d", __func__, rc);
959 return rc;
960 }
961
962 /*===========================================================================
963 * FUNCTION : mm_camera_intf_map_buf
964 *
965 * DESCRIPTION: mapping camera buffer via domain socket to server
966 *
967 * PARAMETERS :
968 * @camera_handle: camera handle
969 * @buf_type : type of buffer to be mapped. could be following values:
970 * CAM_MAPPING_BUF_TYPE_CAPABILITY
971 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
972 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
973 * @fd : file descriptor of the buffer
974 * @size : size of the buffer
975 *
976 * RETURN : int32_t type of status
977 * 0 -- success
978 * -1 -- failure
979 *==========================================================================*/
mm_camera_intf_map_buf(uint32_t camera_handle,uint8_t buf_type,int fd,uint32_t size)980 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle,
981 uint8_t buf_type,
982 int fd,
983 uint32_t size)
984 {
985 int32_t rc = -1;
986 mm_camera_obj_t * my_obj = NULL;
987
988 pthread_mutex_lock(&g_intf_lock);
989 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
990
991 if(my_obj) {
992 pthread_mutex_lock(&my_obj->cam_lock);
993 pthread_mutex_unlock(&g_intf_lock);
994 rc = mm_camera_map_buf(my_obj, buf_type, fd, size);
995 } else {
996 pthread_mutex_unlock(&g_intf_lock);
997 }
998 return rc;
999 }
1000
1001 /*===========================================================================
1002 * FUNCTION : mm_camera_intf_unmap_buf
1003 *
1004 * DESCRIPTION: unmapping camera buffer via domain socket to server
1005 *
1006 * PARAMETERS :
1007 * @camera_handle: camera handle
1008 * @buf_type : type of buffer to be unmapped. could be following values:
1009 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1010 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1011 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1012 *
1013 * RETURN : int32_t type of status
1014 * 0 -- success
1015 * -1 -- failure
1016 *==========================================================================*/
mm_camera_intf_unmap_buf(uint32_t camera_handle,uint8_t buf_type)1017 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle,
1018 uint8_t buf_type)
1019 {
1020 int32_t rc = -1;
1021 mm_camera_obj_t * my_obj = NULL;
1022
1023 pthread_mutex_lock(&g_intf_lock);
1024 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1025
1026 if(my_obj) {
1027 pthread_mutex_lock(&my_obj->cam_lock);
1028 pthread_mutex_unlock(&g_intf_lock);
1029 rc = mm_camera_unmap_buf(my_obj, buf_type);
1030 } else {
1031 pthread_mutex_unlock(&g_intf_lock);
1032 }
1033 return rc;
1034 }
1035
1036 /*===========================================================================
1037 * FUNCTION : mm_camera_intf_set_stream_parms
1038 *
1039 * DESCRIPTION: set parameters per stream
1040 *
1041 * PARAMETERS :
1042 * @camera_handle: camera handle
1043 * @ch_id : channel handle
1044 * @s_id : stream handle
1045 * @parms : ptr to a param struct to be set to server
1046 *
1047 * RETURN : int32_t type of status
1048 * 0 -- success
1049 * -1 -- failure
1050 * NOTE : Assume the parms struct buf is already mapped to server via
1051 * domain socket. Corresponding fields of parameters to be set
1052 * are already filled in by upper layer caller.
1053 *==========================================================================*/
mm_camera_intf_set_stream_parms(uint32_t camera_handle,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1054 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle,
1055 uint32_t ch_id,
1056 uint32_t s_id,
1057 cam_stream_parm_buffer_t *parms)
1058 {
1059 int32_t rc = -1;
1060 mm_camera_obj_t * my_obj = NULL;
1061
1062 pthread_mutex_lock(&g_intf_lock);
1063 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1064
1065 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
1066 __func__, camera_handle, ch_id, s_id);
1067
1068 if(my_obj) {
1069 pthread_mutex_lock(&my_obj->cam_lock);
1070 pthread_mutex_unlock(&g_intf_lock);
1071 rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
1072 }else{
1073 pthread_mutex_unlock(&g_intf_lock);
1074 }
1075 CDBG("%s :X rc = %d", __func__, rc);
1076 return rc;
1077 }
1078
1079 /*===========================================================================
1080 * FUNCTION : mm_camera_intf_get_stream_parms
1081 *
1082 * DESCRIPTION: get parameters per stream
1083 *
1084 * PARAMETERS :
1085 * @camera_handle: camera handle
1086 * @ch_id : channel handle
1087 * @s_id : stream handle
1088 * @parms : ptr to a param struct to be get from server
1089 *
1090 * RETURN : int32_t type of status
1091 * 0 -- success
1092 * -1 -- failure
1093 * NOTE : Assume the parms struct buf is already mapped to server via
1094 * domain socket. Parameters to be get from server are already
1095 * filled in by upper layer caller. After this call, corresponding
1096 * fields of requested parameters will be filled in by server with
1097 * detailed information.
1098 *==========================================================================*/
mm_camera_intf_get_stream_parms(uint32_t camera_handle,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1099 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle,
1100 uint32_t ch_id,
1101 uint32_t s_id,
1102 cam_stream_parm_buffer_t *parms)
1103 {
1104 int32_t rc = -1;
1105 mm_camera_obj_t * my_obj = NULL;
1106
1107 pthread_mutex_lock(&g_intf_lock);
1108 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1109
1110 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
1111 __func__, camera_handle, ch_id, s_id);
1112
1113 if(my_obj) {
1114 pthread_mutex_lock(&my_obj->cam_lock);
1115 pthread_mutex_unlock(&g_intf_lock);
1116 rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
1117 }else{
1118 pthread_mutex_unlock(&g_intf_lock);
1119 }
1120
1121 CDBG("%s :X rc = %d", __func__, rc);
1122 return rc;
1123 }
1124
1125 /*===========================================================================
1126 * FUNCTION : mm_camera_intf_map_stream_buf
1127 *
1128 * DESCRIPTION: mapping stream buffer via domain socket to server
1129 *
1130 * PARAMETERS :
1131 * @camera_handle: camera handle
1132 * @ch_id : channel handle
1133 * @s_id : stream handle
1134 * @buf_type : type of buffer to be mapped. could be following values:
1135 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1136 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1137 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1138 * @buf_idx : index of buffer within the stream buffers, only valid if
1139 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1140 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1141 * @plane_idx : plane index. If all planes share the same fd,
1142 * plane_idx = -1; otherwise, plean_idx is the
1143 * index to plane (0..num_of_planes)
1144 * @fd : file descriptor of the buffer
1145 * @size : size of the buffer
1146 *
1147 * RETURN : int32_t type of status
1148 * 0 -- success
1149 * -1 -- failure
1150 *==========================================================================*/
mm_camera_intf_map_stream_buf(uint32_t camera_handle,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)1151 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle,
1152 uint32_t ch_id,
1153 uint32_t stream_id,
1154 uint8_t buf_type,
1155 uint32_t buf_idx,
1156 int32_t plane_idx,
1157 int fd,
1158 uint32_t size)
1159 {
1160 int32_t rc = -1;
1161 mm_camera_obj_t * my_obj = NULL;
1162
1163 pthread_mutex_lock(&g_intf_lock);
1164 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1165
1166 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
1167 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
1168
1169 if(my_obj) {
1170 pthread_mutex_lock(&my_obj->cam_lock);
1171 pthread_mutex_unlock(&g_intf_lock);
1172 rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
1173 buf_type, buf_idx, plane_idx,
1174 fd, size);
1175 }else{
1176 pthread_mutex_unlock(&g_intf_lock);
1177 }
1178
1179 CDBG("%s :X rc = %d", __func__, rc);
1180 return rc;
1181 }
1182
1183 /*===========================================================================
1184 * FUNCTION : mm_camera_intf_unmap_stream_buf
1185 *
1186 * DESCRIPTION: unmapping stream buffer via domain socket to server
1187 *
1188 * PARAMETERS :
1189 * @camera_handle: camera handle
1190 * @ch_id : channel handle
1191 * @s_id : stream handle
1192 * @buf_type : type of buffer to be unmapped. could be following values:
1193 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1194 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1195 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1196 * @buf_idx : index of buffer within the stream buffers, only valid if
1197 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1198 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1199 * @plane_idx : plane index. If all planes share the same fd,
1200 * plane_idx = -1; otherwise, plean_idx is the
1201 * index to plane (0..num_of_planes)
1202 *
1203 * RETURN : int32_t type of status
1204 * 0 -- success
1205 * -1 -- failure
1206 *==========================================================================*/
mm_camera_intf_unmap_stream_buf(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id,uint8_t buf_type,uint32_t buf_idx,int32_t plane_idx)1207 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle,
1208 uint32_t ch_id,
1209 uint32_t stream_id,
1210 uint8_t buf_type,
1211 uint32_t buf_idx,
1212 int32_t plane_idx)
1213 {
1214 int32_t rc = -1;
1215 mm_camera_obj_t * my_obj = NULL;
1216
1217 pthread_mutex_lock(&g_intf_lock);
1218 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1219
1220 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
1221 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
1222
1223 if(my_obj) {
1224 pthread_mutex_lock(&my_obj->cam_lock);
1225 pthread_mutex_unlock(&g_intf_lock);
1226 rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
1227 buf_type, buf_idx, plane_idx);
1228 }else{
1229 pthread_mutex_unlock(&g_intf_lock);
1230 }
1231
1232 CDBG("%s :X rc = %d", __func__, rc);
1233 return rc;
1234 }
1235
1236 /*===========================================================================
1237 * FUNCTION : get_num_of_cameras
1238 *
1239 * DESCRIPTION: get number of cameras
1240 *
1241 * PARAMETERS :
1242 *
1243 * RETURN : number of cameras supported
1244 *==========================================================================*/
get_num_of_cameras()1245 uint8_t get_num_of_cameras()
1246 {
1247 int rc = 0;
1248 int dev_fd = 0;
1249 struct media_device_info mdev_info;
1250 int num_media_devices = 0;
1251 uint8_t num_cameras = 0;
1252
1253 CDBG("%s : E", __func__);
1254 /* lock the mutex */
1255 pthread_mutex_lock(&g_intf_lock);
1256 while (1) {
1257 char dev_name[32];
1258 int num_entities;
1259 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
1260 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
1261 if (dev_fd <= 0) {
1262 CDBG("Done discovering media devices\n");
1263 break;
1264 }
1265 num_media_devices++;
1266 memset(&mdev_info, 0, sizeof(mdev_info));
1267 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
1268 if (rc < 0) {
1269 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
1270 close(dev_fd);
1271 dev_fd = 0;
1272 num_cameras = 0;
1273 break;
1274 }
1275
1276 if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) {
1277 close(dev_fd);
1278 dev_fd = 0;
1279 continue;
1280 }
1281
1282 num_entities = 1;
1283 while (1) {
1284 struct media_entity_desc entity;
1285 memset(&entity, 0, sizeof(entity));
1286 entity.id = num_entities++;
1287 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
1288 if (rc < 0) {
1289 CDBG("Done enumerating media entities\n");
1290 rc = 0;
1291 break;
1292 }
1293 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
1294 strncpy(g_cam_ctrl.video_dev_name[num_cameras],
1295 entity.name, sizeof(entity.name));
1296 break;
1297 }
1298 }
1299
1300 CDBG("%s: dev_info[id=%d,name='%s']\n",
1301 __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
1302
1303 num_cameras++;
1304 close(dev_fd);
1305 dev_fd = 0;
1306 }
1307 g_cam_ctrl.num_cam = num_cameras;
1308
1309 /* unlock the mutex */
1310 pthread_mutex_unlock(&g_intf_lock);
1311 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
1312 return g_cam_ctrl.num_cam;
1313 }
1314
1315 /* camera ops v-table */
1316 static mm_camera_ops_t mm_camera_ops = {
1317 .query_capability = mm_camera_intf_query_capability,
1318 .register_event_notify = mm_camera_intf_register_event_notify,
1319 .close_camera = mm_camera_intf_close,
1320 .set_parms = mm_camera_intf_set_parms,
1321 .get_parms = mm_camera_intf_get_parms,
1322 .do_auto_focus = mm_camera_intf_do_auto_focus,
1323 .cancel_auto_focus = mm_camera_intf_cancel_auto_focus,
1324 .prepare_snapshot = mm_camera_intf_prepare_snapshot,
1325 .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,
1326 .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,
1327 .map_buf = mm_camera_intf_map_buf,
1328 .unmap_buf = mm_camera_intf_unmap_buf,
1329 .add_channel = mm_camera_intf_add_channel,
1330 .delete_channel = mm_camera_intf_del_channel,
1331 .get_bundle_info = mm_camera_intf_get_bundle_info,
1332 .add_stream = mm_camera_intf_add_stream,
1333 .delete_stream = mm_camera_intf_del_stream,
1334 .config_stream = mm_camera_intf_config_stream,
1335 .qbuf = mm_camera_intf_qbuf,
1336 .map_stream_buf = mm_camera_intf_map_stream_buf,
1337 .unmap_stream_buf = mm_camera_intf_unmap_stream_buf,
1338 .set_stream_parms = mm_camera_intf_set_stream_parms,
1339 .get_stream_parms = mm_camera_intf_get_stream_parms,
1340 .start_channel = mm_camera_intf_start_channel,
1341 .stop_channel = mm_camera_intf_stop_channel,
1342 .request_super_buf = mm_camera_intf_request_super_buf,
1343 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
1344 .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,
1345 .configure_notify_mode = mm_camera_intf_configure_notify_mode
1346 };
1347
1348 /*===========================================================================
1349 * FUNCTION : camera_open
1350 *
1351 * DESCRIPTION: open a camera by camera index
1352 *
1353 * PARAMETERS :
1354 * @camera_idx : camera index. should within range of 0 to num_of_cameras
1355 *
1356 * RETURN : ptr to a virtual table containing camera handle and operation table.
1357 * NULL if failed.
1358 *==========================================================================*/
camera_open(uint8_t camera_idx)1359 mm_camera_vtbl_t * camera_open(uint8_t camera_idx)
1360 {
1361 int32_t rc = 0;
1362 mm_camera_obj_t* cam_obj = NULL;
1363
1364 CDBG("%s: E camera_idx = %d\n", __func__, camera_idx);
1365 if (camera_idx >= g_cam_ctrl.num_cam) {
1366 CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
1367 return NULL;
1368 }
1369
1370 pthread_mutex_lock(&g_intf_lock);
1371 /* opened already */
1372 if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
1373 /* Add reference */
1374 g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
1375 pthread_mutex_unlock(&g_intf_lock);
1376 CDBG("%s: opened alreadyn", __func__);
1377 return &g_cam_ctrl.cam_obj[camera_idx]->vtbl;
1378 }
1379
1380 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
1381 if(NULL == cam_obj) {
1382 pthread_mutex_unlock(&g_intf_lock);
1383 CDBG("%s: no mem", __func__);
1384 return NULL;
1385 }
1386
1387 /* initialize camera obj */
1388 memset(cam_obj, 0, sizeof(mm_camera_obj_t));
1389 cam_obj->ref_count++;
1390 cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
1391 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
1392 cam_obj->vtbl.ops = &mm_camera_ops;
1393 pthread_mutex_init(&cam_obj->cam_lock, NULL);
1394
1395 rc = mm_camera_open(cam_obj);
1396 if(rc != 0) {
1397 CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
1398 pthread_mutex_destroy(&cam_obj->cam_lock);
1399 g_cam_ctrl.cam_obj[camera_idx] = NULL;
1400 free(cam_obj);
1401 cam_obj = NULL;
1402 pthread_mutex_unlock(&g_intf_lock);
1403 return NULL;
1404 }else{
1405 CDBG("%s: Open succeded\n", __func__);
1406 g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
1407 pthread_mutex_unlock(&g_intf_lock);
1408 return &cam_obj->vtbl;
1409 }
1410 }
1411