1 /* Copyright (c) 2012-2015, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #include <pthread.h>
31 #include <errno.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <poll.h>
37 #include <linux/media.h>
38 #include <signal.h>
39 #include <media/msm_cam_sensor.h>
40 #include <cutils/properties.h>
41 #include <stdlib.h>
42
43 #include "mm_camera_dbg.h"
44 #include "mm_camera_interface.h"
45 #include "mm_camera_sock.h"
46 #include "mm_camera.h"
47
48 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
49
50 static mm_camera_ctrl_t g_cam_ctrl = {0, {{0}}, {0}, {{0}}};
51
52 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
53 static uint16_t g_handler_history_count = 0; /* history count for handler */
54 volatile uint32_t gMmCameraIntfLogLevel = 1;
55
56 /*===========================================================================
57 * FUNCTION : mm_camera_util_generate_handler
58 *
59 * DESCRIPTION: utility function to generate handler for camera/channel/stream
60 *
61 * PARAMETERS :
62 * @index: index of the object to have handler
63 *
64 * RETURN : uint32_t type of handle that uniquely identify the object
65 *==========================================================================*/
mm_camera_util_generate_handler(uint8_t index)66 uint32_t mm_camera_util_generate_handler(uint8_t index)
67 {
68 uint32_t handler = 0;
69 pthread_mutex_lock(&g_handler_lock);
70 g_handler_history_count++;
71 if (0 == g_handler_history_count) {
72 g_handler_history_count++;
73 }
74 handler = g_handler_history_count;
75 handler = (handler<<8) | index;
76 pthread_mutex_unlock(&g_handler_lock);
77 return handler;
78 }
79
80 /*===========================================================================
81 * FUNCTION : mm_camera_util_get_index_by_handler
82 *
83 * DESCRIPTION: utility function to get index from handle
84 *
85 * PARAMETERS :
86 * @handler: object handle
87 *
88 * RETURN : uint8_t type of index derived from handle
89 *==========================================================================*/
mm_camera_util_get_index_by_handler(uint32_t handler)90 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
91 {
92 return (handler&0x000000ff);
93 }
94
95 /*===========================================================================
96 * FUNCTION : mm_camera_util_get_dev_name
97 *
98 * DESCRIPTION: utility function to get device name from camera handle
99 *
100 * PARAMETERS :
101 * @cam_handle: camera handle
102 *
103 * RETURN : char ptr to the device name stored in global variable
104 * NOTE : caller should not free the char ptr
105 *==========================================================================*/
mm_camera_util_get_dev_name(uint32_t cam_handle)106 const char *mm_camera_util_get_dev_name(uint32_t cam_handle)
107 {
108 char *dev_name = NULL;
109 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
110 if(cam_idx < MM_CAMERA_MAX_NUM_SENSORS) {
111 dev_name = g_cam_ctrl.video_dev_name[cam_idx];
112 }
113 return dev_name;
114 }
115
116 /*===========================================================================
117 * FUNCTION : mm_camera_util_get_camera_by_handler
118 *
119 * DESCRIPTION: utility function to get camera object from camera handle
120 *
121 * PARAMETERS :
122 * @cam_handle: camera handle
123 *
124 * RETURN : ptr to the camera object stored in global variable
125 * NOTE : caller should not free the camera object ptr
126 *==========================================================================*/
mm_camera_util_get_camera_by_handler(uint32_t cam_handle)127 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handle)
128 {
129 mm_camera_obj_t *cam_obj = NULL;
130 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handle);
131
132 if (cam_idx < MM_CAMERA_MAX_NUM_SENSORS &&
133 (NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
134 (cam_handle == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
135 cam_obj = g_cam_ctrl.cam_obj[cam_idx];
136 }
137 return cam_obj;
138 }
139
140 /*===========================================================================
141 * FUNCTION : mm_camera_intf_query_capability
142 *
143 * DESCRIPTION: query camera capability
144 *
145 * PARAMETERS :
146 * @camera_handle: camera handle
147 *
148 * RETURN : int32_t type of status
149 * 0 -- success
150 * -1 -- failure
151 *==========================================================================*/
mm_camera_intf_query_capability(uint32_t camera_handle)152 static int32_t mm_camera_intf_query_capability(uint32_t camera_handle)
153 {
154 int32_t rc = -1;
155 mm_camera_obj_t * my_obj = NULL;
156
157 CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
158
159 pthread_mutex_lock(&g_intf_lock);
160 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
161
162 if(my_obj) {
163 pthread_mutex_lock(&my_obj->cam_lock);
164 pthread_mutex_unlock(&g_intf_lock);
165 rc = mm_camera_query_capability(my_obj);
166 } else {
167 pthread_mutex_unlock(&g_intf_lock);
168 }
169 CDBG("%s :X rc = %d", __func__, rc);
170 return rc;
171 }
172
173 /*===========================================================================
174 * FUNCTION : mm_camera_intf_set_parms
175 *
176 * DESCRIPTION: set parameters per camera
177 *
178 * PARAMETERS :
179 * @camera_handle: camera handle
180 * @parms : ptr to a param struct to be set to server
181 *
182 * RETURN : int32_t type of status
183 * 0 -- success
184 * -1 -- failure
185 * NOTE : Assume the parms struct buf is already mapped to server via
186 * domain socket. Corresponding fields of parameters to be set
187 * are already filled in by upper layer caller.
188 *==========================================================================*/
mm_camera_intf_set_parms(uint32_t camera_handle,parm_buffer_t * parms)189 static int32_t mm_camera_intf_set_parms(uint32_t camera_handle,
190 parm_buffer_t *parms)
191 {
192 int32_t rc = -1;
193 mm_camera_obj_t * my_obj = NULL;
194
195 pthread_mutex_lock(&g_intf_lock);
196 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
197
198 if(my_obj) {
199 pthread_mutex_lock(&my_obj->cam_lock);
200 pthread_mutex_unlock(&g_intf_lock);
201 rc = mm_camera_set_parms(my_obj, parms);
202 } else {
203 pthread_mutex_unlock(&g_intf_lock);
204 }
205 return rc;
206 }
207
208 /*===========================================================================
209 * FUNCTION : mm_camera_intf_get_parms
210 *
211 * DESCRIPTION: get parameters per camera
212 *
213 * PARAMETERS :
214 * @camera_handle: camera handle
215 * @parms : ptr to a param struct to be get from server
216 *
217 * RETURN : int32_t type of status
218 * 0 -- success
219 * -1 -- failure
220 * NOTE : Assume the parms struct buf is already mapped to server via
221 * domain socket. Parameters to be get from server are already
222 * filled in by upper layer caller. After this call, corresponding
223 * fields of requested parameters will be filled in by server with
224 * detailed information.
225 *==========================================================================*/
mm_camera_intf_get_parms(uint32_t camera_handle,parm_buffer_t * parms)226 static int32_t mm_camera_intf_get_parms(uint32_t camera_handle,
227 parm_buffer_t *parms)
228 {
229 int32_t rc = -1;
230 mm_camera_obj_t * my_obj = NULL;
231
232 pthread_mutex_lock(&g_intf_lock);
233 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
234
235 if(my_obj) {
236 pthread_mutex_lock(&my_obj->cam_lock);
237 pthread_mutex_unlock(&g_intf_lock);
238 rc = mm_camera_get_parms(my_obj, parms);
239 } else {
240 pthread_mutex_unlock(&g_intf_lock);
241 }
242 return rc;
243 }
244
245 /*===========================================================================
246 * FUNCTION : mm_camera_intf_do_auto_focus
247 *
248 * DESCRIPTION: performing auto focus
249 *
250 * PARAMETERS :
251 * @camera_handle: camera handle
252 *
253 * RETURN : int32_t type of status
254 * 0 -- success
255 * -1 -- failure
256 * NOTE : if this call success, we will always assume there will
257 * be an auto_focus event following up.
258 *==========================================================================*/
mm_camera_intf_do_auto_focus(uint32_t camera_handle)259 static int32_t mm_camera_intf_do_auto_focus(uint32_t camera_handle)
260 {
261 int32_t rc = -1;
262 mm_camera_obj_t * my_obj = NULL;
263
264 pthread_mutex_lock(&g_intf_lock);
265 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
266
267 if(my_obj) {
268 pthread_mutex_lock(&my_obj->cam_lock);
269 pthread_mutex_unlock(&g_intf_lock);
270 rc = mm_camera_do_auto_focus(my_obj);
271 } else {
272 pthread_mutex_unlock(&g_intf_lock);
273 }
274 return rc;
275 }
276
277 /*===========================================================================
278 * FUNCTION : mm_camera_intf_cancel_auto_focus
279 *
280 * DESCRIPTION: cancel auto focus
281 *
282 * PARAMETERS :
283 * @camera_handle: camera handle
284 *
285 * RETURN : int32_t type of status
286 * 0 -- success
287 * -1 -- failure
288 *==========================================================================*/
mm_camera_intf_cancel_auto_focus(uint32_t camera_handle)289 static int32_t mm_camera_intf_cancel_auto_focus(uint32_t camera_handle)
290 {
291 int32_t rc = -1;
292 mm_camera_obj_t * my_obj = NULL;
293
294 pthread_mutex_lock(&g_intf_lock);
295 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
296
297 if(my_obj) {
298 pthread_mutex_lock(&my_obj->cam_lock);
299 pthread_mutex_unlock(&g_intf_lock);
300 rc = mm_camera_cancel_auto_focus(my_obj);
301 } else {
302 pthread_mutex_unlock(&g_intf_lock);
303 }
304 return rc;
305 }
306
307 /*===========================================================================
308 * FUNCTION : mm_camera_intf_prepare_snapshot
309 *
310 * DESCRIPTION: prepare hardware for snapshot
311 *
312 * PARAMETERS :
313 * @camera_handle: camera handle
314 * @do_af_flag : flag indicating if AF is needed
315 *
316 * RETURN : int32_t type of status
317 * 0 -- success
318 * -1 -- failure
319 *==========================================================================*/
mm_camera_intf_prepare_snapshot(uint32_t camera_handle,int32_t do_af_flag)320 static int32_t mm_camera_intf_prepare_snapshot(uint32_t camera_handle,
321 int32_t do_af_flag)
322 {
323 int32_t rc = -1;
324 mm_camera_obj_t * my_obj = NULL;
325
326 pthread_mutex_lock(&g_intf_lock);
327 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
328
329 if(my_obj) {
330 pthread_mutex_lock(&my_obj->cam_lock);
331 pthread_mutex_unlock(&g_intf_lock);
332 rc = mm_camera_prepare_snapshot(my_obj, do_af_flag);
333 } else {
334 pthread_mutex_unlock(&g_intf_lock);
335 }
336 return rc;
337 }
338
339 /*===========================================================================
340 * FUNCTION : mm_camera_intf_close
341 *
342 * DESCRIPTION: close a camera by its handle
343 *
344 * PARAMETERS :
345 * @camera_handle: camera handle
346 *
347 * RETURN : int32_t type of status
348 * 0 -- success
349 * -1 -- failure
350 *==========================================================================*/
mm_camera_intf_close(uint32_t camera_handle)351 static int32_t mm_camera_intf_close(uint32_t camera_handle)
352 {
353 int32_t rc = -1;
354 uint8_t cam_idx = camera_handle & 0x00ff;
355 mm_camera_obj_t * my_obj = NULL;
356
357 CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
358
359 pthread_mutex_lock(&g_intf_lock);
360 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
361
362 if (my_obj){
363 my_obj->ref_count--;
364
365 if(my_obj->ref_count > 0) {
366 /* still have reference to obj, return here */
367 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
368 pthread_mutex_unlock(&g_intf_lock);
369 rc = 0;
370 } else {
371 /* need close camera here as no other reference
372 * first empty g_cam_ctrl's referent to cam_obj */
373 g_cam_ctrl.cam_obj[cam_idx] = NULL;
374
375 pthread_mutex_lock(&my_obj->cam_lock);
376 pthread_mutex_unlock(&g_intf_lock);
377
378 rc = mm_camera_close(my_obj);
379
380 pthread_mutex_destroy(&my_obj->cam_lock);
381 free(my_obj);
382 }
383 } else {
384 pthread_mutex_unlock(&g_intf_lock);
385 }
386
387 return rc;
388 }
389
390 /*===========================================================================
391 * FUNCTION : mm_camera_intf_error_close
392 *
393 * DESCRIPTION: close the daemon after an unrecoverable error
394 *
395 * PARAMETERS :
396 * @camera_handle: camera handle
397 *
398 * RETURN : int32_t type of status
399 * 0 -- success
400 * -1 -- failure
401 *==========================================================================*/
mm_camera_intf_error_close(uint32_t camera_handle)402 static int32_t mm_camera_intf_error_close(uint32_t camera_handle)
403 {
404 int32_t rc = -1;
405 uint8_t cam_idx = camera_handle & 0x00ff;
406 mm_camera_obj_t * my_obj = NULL;
407
408 CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
409
410 pthread_mutex_lock(&g_intf_lock);
411 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
412
413 if (my_obj){
414 /*do not decrement the ref_count yet since that will happen during close*/
415 if((my_obj->ref_count - 1) > 0) {
416 /* still have reference to obj, return here */
417 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
418 pthread_mutex_unlock(&g_intf_lock);
419 rc = 0;
420 } else {
421 /* need close camera here as no other reference*/
422 pthread_mutex_lock(&my_obj->cam_lock);
423 pthread_mutex_unlock(&g_intf_lock);
424
425 rc = mm_camera_close_fd(my_obj);
426 }
427 } else {
428 pthread_mutex_unlock(&g_intf_lock);
429 }
430
431 return rc;
432 }
433
434 /*===========================================================================
435 * FUNCTION : mm_camera_intf_add_channel
436 *
437 * DESCRIPTION: add a channel
438 *
439 * PARAMETERS :
440 * @camera_handle: camera handle
441 * @attr : bundle attribute of the channel if needed
442 * @channel_cb : callback function for bundle data notify
443 * @userdata : user data ptr
444 *
445 * RETURN : uint32_t type of channel handle
446 * 0 -- invalid channel handle, meaning the op failed
447 * >0 -- successfully added a channel with a valid handle
448 * NOTE : if no bundle data notify is needed, meaning each stream in the
449 * channel will have its own stream data notify callback, then
450 * attr, channel_cb, and userdata can be NULL. In this case,
451 * no matching logic will be performed in channel for the bundling.
452 *==========================================================================*/
mm_camera_intf_add_channel(uint32_t camera_handle,mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t channel_cb,void * userdata)453 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle,
454 mm_camera_channel_attr_t *attr,
455 mm_camera_buf_notify_t channel_cb,
456 void *userdata)
457 {
458 uint32_t ch_id = 0;
459 mm_camera_obj_t * my_obj = NULL;
460
461 CDBG("%s :E camera_handler = %d", __func__, camera_handle);
462 pthread_mutex_lock(&g_intf_lock);
463 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
464
465 if(my_obj) {
466 pthread_mutex_lock(&my_obj->cam_lock);
467 pthread_mutex_unlock(&g_intf_lock);
468 ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
469 } else {
470 pthread_mutex_unlock(&g_intf_lock);
471 }
472 CDBG("%s :X ch_id = %d", __func__, ch_id);
473 return ch_id;
474 }
475
476 /*===========================================================================
477 * FUNCTION : mm_camera_intf_del_channel
478 *
479 * DESCRIPTION: delete a channel by its handle
480 *
481 * PARAMETERS :
482 * @camera_handle: camera handle
483 * @ch_id : channel handle
484 *
485 * RETURN : int32_t type of status
486 * 0 -- success
487 * -1 -- failure
488 * NOTE : all streams in the channel should be stopped already before
489 * this channel can be deleted.
490 *==========================================================================*/
mm_camera_intf_del_channel(uint32_t camera_handle,uint32_t ch_id)491 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle,
492 uint32_t ch_id)
493 {
494 int32_t rc = -1;
495 mm_camera_obj_t * my_obj = NULL;
496
497 CDBG("%s :E ch_id = %d", __func__, ch_id);
498 pthread_mutex_lock(&g_intf_lock);
499 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
500
501 if(my_obj) {
502 pthread_mutex_lock(&my_obj->cam_lock);
503 pthread_mutex_unlock(&g_intf_lock);
504 rc = mm_camera_del_channel(my_obj, ch_id);
505 } else {
506 pthread_mutex_unlock(&g_intf_lock);
507 }
508 CDBG("%s :X", __func__);
509 return rc;
510 }
511
512 /*===========================================================================
513 * FUNCTION : mm_camera_intf_get_bundle_info
514 *
515 * DESCRIPTION: query bundle info of the channel
516 *
517 * PARAMETERS :
518 * @camera_handle: camera handle
519 * @ch_id : channel handle
520 * @bundle_info : bundle info to be filled in
521 *
522 * RETURN : int32_t type of status
523 * 0 -- success
524 * -1 -- failure
525 * NOTE : all streams in the channel should be stopped already before
526 * this channel can be deleted.
527 *==========================================================================*/
mm_camera_intf_get_bundle_info(uint32_t camera_handle,uint32_t ch_id,cam_bundle_config_t * bundle_info)528 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle,
529 uint32_t ch_id,
530 cam_bundle_config_t *bundle_info)
531 {
532 int32_t rc = -1;
533 mm_camera_obj_t * my_obj = NULL;
534
535 CDBG("%s :E ch_id = %d", __func__, ch_id);
536 pthread_mutex_lock(&g_intf_lock);
537 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
538
539 if(my_obj) {
540 pthread_mutex_lock(&my_obj->cam_lock);
541 pthread_mutex_unlock(&g_intf_lock);
542 rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
543 } else {
544 pthread_mutex_unlock(&g_intf_lock);
545 }
546 CDBG("%s :X", __func__);
547 return rc;
548 }
549
550 /*===========================================================================
551 * FUNCTION : mm_camera_intf_register_event_notify
552 *
553 * DESCRIPTION: register for event notify
554 *
555 * PARAMETERS :
556 * @camera_handle: camera handle
557 * @evt_cb : callback for event notify
558 * @user_data : user data ptr
559 *
560 * RETURN : int32_t type of status
561 * 0 -- success
562 * -1 -- failure
563 *==========================================================================*/
mm_camera_intf_register_event_notify(uint32_t camera_handle,mm_camera_event_notify_t evt_cb,void * user_data)564 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle,
565 mm_camera_event_notify_t evt_cb,
566 void * user_data)
567 {
568 int32_t rc = -1;
569 mm_camera_obj_t * my_obj = NULL;
570
571 CDBG("%s :E ", __func__);
572 pthread_mutex_lock(&g_intf_lock);
573 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
574
575 if(my_obj) {
576 pthread_mutex_lock(&my_obj->cam_lock);
577 pthread_mutex_unlock(&g_intf_lock);
578 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
579 } else {
580 pthread_mutex_unlock(&g_intf_lock);
581 }
582 CDBG("%s :E rc = %d", __func__, rc);
583 return rc;
584 }
585
586 /*===========================================================================
587 * FUNCTION : mm_camera_intf_qbuf
588 *
589 * DESCRIPTION: enqueue buffer back to kernel
590 *
591 * PARAMETERS :
592 * @camera_handle: camera handle
593 * @ch_id : channel handle
594 * @buf : buf ptr to be enqueued
595 *
596 * RETURN : int32_t type of status
597 * 0 -- success
598 * -1 -- failure
599 *==========================================================================*/
mm_camera_intf_qbuf(uint32_t camera_handle,uint32_t ch_id,mm_camera_buf_def_t * buf)600 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle,
601 uint32_t ch_id,
602 mm_camera_buf_def_t *buf)
603 {
604 int32_t rc = -1;
605 mm_camera_obj_t * my_obj = NULL;
606
607 pthread_mutex_lock(&g_intf_lock);
608 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
609
610 if(my_obj) {
611 pthread_mutex_lock(&my_obj->cam_lock);
612 pthread_mutex_unlock(&g_intf_lock);
613 rc = mm_camera_qbuf(my_obj, ch_id, buf);
614 } else {
615 pthread_mutex_unlock(&g_intf_lock);
616 }
617 CDBG("%s :X evt_type = %d",__func__,rc);
618 return rc;
619 }
620
621 /*===========================================================================
622 * FUNCTION : mm_camera_intf_get_queued_buf_count
623 *
624 * DESCRIPTION: returns the queued buffer count
625 *
626 * PARAMETERS :
627 * @camera_handle: camera handle
628 * @ch_id : channel handle
629 * @stream_id : stream id
630 *
631 * RETURN : int32_t - queued buffer count
632 *
633 *==========================================================================*/
mm_camera_intf_get_queued_buf_count(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id)634 static int32_t mm_camera_intf_get_queued_buf_count(uint32_t camera_handle,
635 uint32_t ch_id, uint32_t stream_id)
636 {
637 int32_t rc = -1;
638 mm_camera_obj_t * my_obj = NULL;
639
640 pthread_mutex_lock(&g_intf_lock);
641 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
642
643 if(my_obj) {
644 pthread_mutex_lock(&my_obj->cam_lock);
645 pthread_mutex_unlock(&g_intf_lock);
646 rc = mm_camera_get_queued_buf_count(my_obj, ch_id, stream_id);
647 } else {
648 pthread_mutex_unlock(&g_intf_lock);
649 }
650 CDBG("%s :X queued buffer count = %d",__func__,rc);
651 return rc;
652 }
653
654 /*===========================================================================
655 * FUNCTION : mm_camera_intf_link_stream
656 *
657 * DESCRIPTION: link a stream into a new channel
658 *
659 * PARAMETERS :
660 * @camera_handle: camera handle
661 * @ch_id : channel handle
662 * @stream_id : stream id
663 * @linked_ch_id : channel in which the stream will be linked
664 *
665 * RETURN : int32_t type of stream handle
666 * 0 -- invalid stream handle, meaning the op failed
667 * >0 -- successfully linked a stream with a valid handle
668 *==========================================================================*/
mm_camera_intf_link_stream(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id,uint32_t linked_ch_id)669 static int32_t mm_camera_intf_link_stream(uint32_t camera_handle,
670 uint32_t ch_id,
671 uint32_t stream_id,
672 uint32_t linked_ch_id)
673 {
674 uint32_t id = 0;
675 mm_camera_obj_t * my_obj = NULL;
676
677 CDBG("%s : E handle = %u ch_id = %u",
678 __func__, camera_handle, ch_id);
679
680 pthread_mutex_lock(&g_intf_lock);
681 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
682
683 if(my_obj) {
684 pthread_mutex_lock(&my_obj->cam_lock);
685 pthread_mutex_unlock(&g_intf_lock);
686 id = mm_camera_link_stream(my_obj, ch_id, stream_id, linked_ch_id);
687 } else {
688 pthread_mutex_unlock(&g_intf_lock);
689 }
690
691 CDBG("%s :X stream_id = %u", __func__, stream_id);
692 return (int32_t)id;
693 }
694
695 /*===========================================================================
696 * FUNCTION : mm_camera_intf_add_stream
697 *
698 * DESCRIPTION: add a stream into a channel
699 *
700 * PARAMETERS :
701 * @camera_handle: camera handle
702 * @ch_id : channel handle
703 *
704 * RETURN : uint32_t type of stream handle
705 * 0 -- invalid stream handle, meaning the op failed
706 * >0 -- successfully added a stream with a valid handle
707 *==========================================================================*/
mm_camera_intf_add_stream(uint32_t camera_handle,uint32_t ch_id)708 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle,
709 uint32_t ch_id)
710 {
711 uint32_t stream_id = 0;
712 mm_camera_obj_t * my_obj = NULL;
713
714 CDBG("%s : E handle = %d ch_id = %d",
715 __func__, camera_handle, ch_id);
716
717 pthread_mutex_lock(&g_intf_lock);
718 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
719
720 if(my_obj) {
721 pthread_mutex_lock(&my_obj->cam_lock);
722 pthread_mutex_unlock(&g_intf_lock);
723 stream_id = mm_camera_add_stream(my_obj, ch_id);
724 } else {
725 pthread_mutex_unlock(&g_intf_lock);
726 }
727 CDBG("%s :X stream_id = %d", __func__, stream_id);
728 return stream_id;
729 }
730
731 /*===========================================================================
732 * FUNCTION : mm_camera_intf_del_stream
733 *
734 * DESCRIPTION: delete a stream by its handle
735 *
736 * PARAMETERS :
737 * @camera_handle: camera handle
738 * @ch_id : channel handle
739 * @stream_id : stream handle
740 *
741 * RETURN : int32_t type of status
742 * 0 -- success
743 * -1 -- failure
744 * NOTE : stream should be stopped already before it can be deleted.
745 *==========================================================================*/
mm_camera_intf_del_stream(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id)746 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle,
747 uint32_t ch_id,
748 uint32_t stream_id)
749 {
750 int32_t rc = -1;
751 mm_camera_obj_t * my_obj = NULL;
752
753 CDBG("%s : E handle = %d ch_id = %d stream_id = %d",
754 __func__, camera_handle, ch_id, stream_id);
755
756 pthread_mutex_lock(&g_intf_lock);
757 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
758
759 if(my_obj) {
760 pthread_mutex_lock(&my_obj->cam_lock);
761 pthread_mutex_unlock(&g_intf_lock);
762 rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
763 } else {
764 pthread_mutex_unlock(&g_intf_lock);
765 }
766 CDBG("%s :X rc = %d", __func__, rc);
767 return rc;
768 }
769
770 /*===========================================================================
771 * FUNCTION : mm_camera_intf_config_stream
772 *
773 * DESCRIPTION: configure a stream
774 *
775 * PARAMETERS :
776 * @camera_handle: camera handle
777 * @ch_id : channel handle
778 * @stream_id : stream handle
779 * @config : stream configuration
780 *
781 * RETURN : int32_t type of status
782 * 0 -- success
783 * -1 -- failure
784 *==========================================================================*/
mm_camera_intf_config_stream(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)785 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle,
786 uint32_t ch_id,
787 uint32_t stream_id,
788 mm_camera_stream_config_t *config)
789 {
790 int32_t rc = -1;
791 mm_camera_obj_t * my_obj = NULL;
792
793 CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",
794 __func__, camera_handle, ch_id, stream_id);
795
796 pthread_mutex_lock(&g_intf_lock);
797 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
798
799 CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
800
801 if(my_obj) {
802 pthread_mutex_lock(&my_obj->cam_lock);
803 pthread_mutex_unlock(&g_intf_lock);
804 rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
805 } else {
806 pthread_mutex_unlock(&g_intf_lock);
807 }
808 CDBG("%s :X rc = %d", __func__, rc);
809 return rc;
810 }
811
812 /*===========================================================================
813 * FUNCTION : mm_camera_intf_start_channel
814 *
815 * DESCRIPTION: start a channel, which will start all streams in the channel
816 *
817 * PARAMETERS :
818 * @camera_handle: camera handle
819 * @ch_id : channel handle
820 *
821 * RETURN : int32_t type of status
822 * 0 -- success
823 * -1 -- failure
824 *==========================================================================*/
mm_camera_intf_start_channel(uint32_t camera_handle,uint32_t ch_id)825 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle,
826 uint32_t ch_id)
827 {
828 int32_t rc = -1;
829 mm_camera_obj_t * my_obj = NULL;
830
831 pthread_mutex_lock(&g_intf_lock);
832 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
833
834 if(my_obj) {
835 pthread_mutex_lock(&my_obj->cam_lock);
836 pthread_mutex_unlock(&g_intf_lock);
837 rc = mm_camera_start_channel(my_obj, ch_id);
838 } else {
839 pthread_mutex_unlock(&g_intf_lock);
840 }
841 CDBG("%s :X rc = %d", __func__, rc);
842 return rc;
843 }
844
845 /*===========================================================================
846 * FUNCTION : mm_camera_intf_stop_channel
847 *
848 * DESCRIPTION: stop a channel, which will stop all streams in the channel
849 *
850 * PARAMETERS :
851 * @camera_handle: camera handle
852 * @ch_id : channel handle
853 *
854 * RETURN : int32_t type of status
855 * 0 -- success
856 * -1 -- failure
857 *==========================================================================*/
mm_camera_intf_stop_channel(uint32_t camera_handle,uint32_t ch_id)858 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle,
859 uint32_t ch_id)
860 {
861 int32_t rc = -1;
862 mm_camera_obj_t * my_obj = NULL;
863
864 pthread_mutex_lock(&g_intf_lock);
865 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
866
867 if(my_obj) {
868 pthread_mutex_lock(&my_obj->cam_lock);
869 pthread_mutex_unlock(&g_intf_lock);
870 rc = mm_camera_stop_channel(my_obj, ch_id);
871 } else {
872 pthread_mutex_unlock(&g_intf_lock);
873 }
874 CDBG("%s :X rc = %d", __func__, rc);
875 return rc;
876 }
877
878 /*===========================================================================
879 * FUNCTION : mm_camera_intf_request_super_buf
880 *
881 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
882 * frames from superbuf queue
883 *
884 * PARAMETERS :
885 * @camera_handle: camera handle
886 * @ch_id : channel handle
887 * @num_buf_requested : number of matched frames needed
888 *
889 * RETURN : int32_t type of status
890 * 0 -- success
891 * -1 -- failure
892 *==========================================================================*/
mm_camera_intf_request_super_buf(uint32_t camera_handle,uint32_t ch_id,uint32_t num_buf_requested,uint32_t num_retro_buf_requested)893 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle,
894 uint32_t ch_id,
895 uint32_t num_buf_requested,
896 uint32_t num_retro_buf_requested)
897 {
898 int32_t rc = -1;
899 CDBG("%s :E camera_handler = %d,ch_id = %d",
900 __func__, camera_handle, ch_id);
901 mm_camera_obj_t * my_obj = NULL;
902
903 pthread_mutex_lock(&g_intf_lock);
904 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
905
906 if(my_obj) {
907 pthread_mutex_lock(&my_obj->cam_lock);
908 pthread_mutex_unlock(&g_intf_lock);
909 rc = mm_camera_request_super_buf (my_obj, ch_id,
910 num_buf_requested, num_retro_buf_requested);
911 } else {
912 pthread_mutex_unlock(&g_intf_lock);
913 }
914 CDBG("%s :X rc = %d", __func__, rc);
915 return rc;
916 }
917
918 /*===========================================================================
919 * FUNCTION : mm_camera_intf_cancel_super_buf_request
920 *
921 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
922 * of matched frames from superbuf queue
923 *
924 * PARAMETERS :
925 * @camera_handle: camera handle
926 * @ch_id : channel handle
927 *
928 * RETURN : int32_t type of status
929 * 0 -- success
930 * -1 -- failure
931 *==========================================================================*/
mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,uint32_t ch_id)932 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,
933 uint32_t ch_id)
934 {
935 int32_t rc = -1;
936 mm_camera_obj_t * my_obj = NULL;
937
938 CDBG("%s :E camera_handler = %d,ch_id = %d",
939 __func__, camera_handle, ch_id);
940 pthread_mutex_lock(&g_intf_lock);
941 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
942
943 if(my_obj) {
944 pthread_mutex_lock(&my_obj->cam_lock);
945 pthread_mutex_unlock(&g_intf_lock);
946 rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
947 } else {
948 pthread_mutex_unlock(&g_intf_lock);
949 }
950 CDBG("%s :X rc = %d", __func__, rc);
951 return rc;
952 }
953
954 /*===========================================================================
955 * FUNCTION : mm_camera_intf_flush_super_buf_queue
956 *
957 * DESCRIPTION: flush out all frames in the superbuf queue
958 *
959 * PARAMETERS :
960 * @camera_handle: camera handle
961 * @ch_id : channel handle
962 * @frame_idx : frame index
963 *
964 * RETURN : int32_t type of status
965 * 0 -- success
966 * -1 -- failure
967 *==========================================================================*/
mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,uint32_t ch_id,uint32_t frame_idx)968 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,
969 uint32_t ch_id, uint32_t frame_idx)
970 {
971 int32_t rc = -1;
972 mm_camera_obj_t * my_obj = NULL;
973
974 CDBG("%s :E camera_handler = %d,ch_id = %d",
975 __func__, camera_handle, ch_id);
976 pthread_mutex_lock(&g_intf_lock);
977 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
978
979 if(my_obj) {
980 pthread_mutex_lock(&my_obj->cam_lock);
981 pthread_mutex_unlock(&g_intf_lock);
982 rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
983 } else {
984 pthread_mutex_unlock(&g_intf_lock);
985 }
986 CDBG("%s :X rc = %d", __func__, rc);
987 return rc;
988 }
989
990 /*===========================================================================
991 * FUNCTION : mm_camera_intf_start_zsl_snapshot
992 *
993 * DESCRIPTION: Starts zsl snapshot
994 *
995 * PARAMETERS :
996 * @camera_handle: camera handle
997 * @ch_id : channel handle
998 *
999 * RETURN : int32_t type of status
1000 * 0 -- success
1001 * -1 -- failure
1002 *==========================================================================*/
mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle,uint32_t ch_id)1003 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle,
1004 uint32_t ch_id)
1005 {
1006 int32_t rc = -1;
1007 mm_camera_obj_t * my_obj = NULL;
1008
1009 CDBG("%s :E camera_handler = %d,ch_id = %d",
1010 __func__, camera_handle, ch_id);
1011 pthread_mutex_lock(&g_intf_lock);
1012 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1013
1014 if(my_obj) {
1015 pthread_mutex_lock(&my_obj->cam_lock);
1016 pthread_mutex_unlock(&g_intf_lock);
1017 rc = mm_camera_start_zsl_snapshot_ch(my_obj, ch_id);
1018 } else {
1019 pthread_mutex_unlock(&g_intf_lock);
1020 }
1021 CDBG("%s :X rc = %d", __func__, rc);
1022 return rc;
1023 }
1024
1025 /*===========================================================================
1026 * FUNCTION : mm_camera_intf_stop_zsl_snapshot
1027 *
1028 * DESCRIPTION: Stops zsl snapshot
1029 *
1030 * PARAMETERS :
1031 * @camera_handle: camera handle
1032 * @ch_id : channel handle
1033 *
1034 * RETURN : int32_t type of status
1035 * 0 -- success
1036 * -1 -- failure
1037 *==========================================================================*/
mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle,uint32_t ch_id)1038 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle,
1039 uint32_t ch_id)
1040 {
1041 int32_t rc = -1;
1042 mm_camera_obj_t * my_obj = NULL;
1043
1044 CDBG("%s :E camera_handler = %d,ch_id = %d",
1045 __func__, camera_handle, ch_id);
1046 pthread_mutex_lock(&g_intf_lock);
1047 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1048
1049 if(my_obj) {
1050 pthread_mutex_lock(&my_obj->cam_lock);
1051 pthread_mutex_unlock(&g_intf_lock);
1052 rc = mm_camera_stop_zsl_snapshot_ch(my_obj, ch_id);
1053 } else {
1054 pthread_mutex_unlock(&g_intf_lock);
1055 }
1056 CDBG("%s :X rc = %d", __func__, rc);
1057 return rc;
1058 }
1059
1060 /*===========================================================================
1061 * FUNCTION : mm_camera_intf_configure_notify_mode
1062 *
1063 * DESCRIPTION: Configures channel notification mode
1064 *
1065 * PARAMETERS :
1066 * @camera_handle: camera handle
1067 * @ch_id : channel handle
1068 * @notify_mode : notification mode
1069 *
1070 * RETURN : int32_t type of status
1071 * 0 -- success
1072 * -1 -- failure
1073 *==========================================================================*/
mm_camera_intf_configure_notify_mode(uint32_t camera_handle,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)1074 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle,
1075 uint32_t ch_id,
1076 mm_camera_super_buf_notify_mode_t notify_mode)
1077 {
1078 int32_t rc = -1;
1079 mm_camera_obj_t * my_obj = NULL;
1080
1081 CDBG("%s :E camera_handler = %d,ch_id = %d",
1082 __func__, camera_handle, ch_id);
1083 pthread_mutex_lock(&g_intf_lock);
1084 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1085
1086 if(my_obj) {
1087 pthread_mutex_lock(&my_obj->cam_lock);
1088 pthread_mutex_unlock(&g_intf_lock);
1089 rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
1090 } else {
1091 pthread_mutex_unlock(&g_intf_lock);
1092 }
1093 CDBG("%s :X rc = %d", __func__, rc);
1094 return rc;
1095 }
1096
1097 /*===========================================================================
1098 * FUNCTION : mm_camera_intf_map_buf
1099 *
1100 * DESCRIPTION: mapping camera buffer via domain socket to server
1101 *
1102 * PARAMETERS :
1103 * @camera_handle: camera handle
1104 * @buf_type : type of buffer to be mapped. could be following values:
1105 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1106 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1107 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1108 * @fd : file descriptor of the buffer
1109 * @size : size of the buffer
1110 *
1111 * RETURN : int32_t type of status
1112 * 0 -- success
1113 * -1 -- failure
1114 *==========================================================================*/
mm_camera_intf_map_buf(uint32_t camera_handle,uint8_t buf_type,int fd,size_t size)1115 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle,
1116 uint8_t buf_type,
1117 int fd,
1118 size_t size)
1119 {
1120 int32_t rc = -1;
1121 mm_camera_obj_t * my_obj = NULL;
1122
1123 pthread_mutex_lock(&g_intf_lock);
1124 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1125
1126 if(my_obj) {
1127 pthread_mutex_lock(&my_obj->cam_lock);
1128 pthread_mutex_unlock(&g_intf_lock);
1129 rc = mm_camera_map_buf(my_obj, buf_type, fd, size);
1130 } else {
1131 pthread_mutex_unlock(&g_intf_lock);
1132 }
1133 return rc;
1134 }
1135
1136 /*===========================================================================
1137 * FUNCTION : mm_camera_intf_unmap_buf
1138 *
1139 * DESCRIPTION: unmapping camera buffer via domain socket to server
1140 *
1141 * PARAMETERS :
1142 * @camera_handle: camera handle
1143 * @buf_type : type of buffer to be unmapped. could be following values:
1144 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1145 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1146 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1147 *
1148 * RETURN : int32_t type of status
1149 * 0 -- success
1150 * -1 -- failure
1151 *==========================================================================*/
mm_camera_intf_unmap_buf(uint32_t camera_handle,uint8_t buf_type)1152 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle,
1153 uint8_t buf_type)
1154 {
1155 int32_t rc = -1;
1156 mm_camera_obj_t * my_obj = NULL;
1157
1158 pthread_mutex_lock(&g_intf_lock);
1159 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1160
1161 if(my_obj) {
1162 pthread_mutex_lock(&my_obj->cam_lock);
1163 pthread_mutex_unlock(&g_intf_lock);
1164 rc = mm_camera_unmap_buf(my_obj, buf_type);
1165 } else {
1166 pthread_mutex_unlock(&g_intf_lock);
1167 }
1168 return rc;
1169 }
1170
1171 /*===========================================================================
1172 * FUNCTION : mm_camera_intf_set_stream_parms
1173 *
1174 * DESCRIPTION: set parameters per stream
1175 *
1176 * PARAMETERS :
1177 * @camera_handle: camera handle
1178 * @ch_id : channel handle
1179 * @s_id : stream handle
1180 * @parms : ptr to a param struct to be set to server
1181 *
1182 * RETURN : int32_t type of status
1183 * 0 -- success
1184 * -1 -- failure
1185 * NOTE : Assume the parms struct buf is already mapped to server via
1186 * domain socket. Corresponding fields of parameters to be set
1187 * are already filled in by upper layer caller.
1188 *==========================================================================*/
mm_camera_intf_set_stream_parms(uint32_t camera_handle,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1189 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle,
1190 uint32_t ch_id,
1191 uint32_t s_id,
1192 cam_stream_parm_buffer_t *parms)
1193 {
1194 int32_t rc = -1;
1195 mm_camera_obj_t * my_obj = NULL;
1196
1197 pthread_mutex_lock(&g_intf_lock);
1198 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1199
1200 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
1201 __func__, camera_handle, ch_id, s_id);
1202
1203 if(my_obj) {
1204 pthread_mutex_lock(&my_obj->cam_lock);
1205 pthread_mutex_unlock(&g_intf_lock);
1206 rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
1207 }else{
1208 pthread_mutex_unlock(&g_intf_lock);
1209 }
1210 CDBG("%s :X rc = %d", __func__, rc);
1211 return rc;
1212 }
1213
1214 /*===========================================================================
1215 * FUNCTION : mm_camera_intf_get_stream_parms
1216 *
1217 * DESCRIPTION: get parameters per stream
1218 *
1219 * PARAMETERS :
1220 * @camera_handle: camera handle
1221 * @ch_id : channel handle
1222 * @s_id : stream handle
1223 * @parms : ptr to a param struct to be get from server
1224 *
1225 * RETURN : int32_t type of status
1226 * 0 -- success
1227 * -1 -- failure
1228 * NOTE : Assume the parms struct buf is already mapped to server via
1229 * domain socket. Parameters to be get from server are already
1230 * filled in by upper layer caller. After this call, corresponding
1231 * fields of requested parameters will be filled in by server with
1232 * detailed information.
1233 *==========================================================================*/
mm_camera_intf_get_stream_parms(uint32_t camera_handle,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1234 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle,
1235 uint32_t ch_id,
1236 uint32_t s_id,
1237 cam_stream_parm_buffer_t *parms)
1238 {
1239 int32_t rc = -1;
1240 mm_camera_obj_t * my_obj = NULL;
1241
1242 pthread_mutex_lock(&g_intf_lock);
1243 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1244
1245 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
1246 __func__, camera_handle, ch_id, s_id);
1247
1248 if(my_obj) {
1249 pthread_mutex_lock(&my_obj->cam_lock);
1250 pthread_mutex_unlock(&g_intf_lock);
1251 rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
1252 }else{
1253 pthread_mutex_unlock(&g_intf_lock);
1254 }
1255
1256 CDBG("%s :X rc = %d", __func__, rc);
1257 return rc;
1258 }
1259
1260 /*===========================================================================
1261 * FUNCTION : mm_camera_intf_map_stream_buf
1262 *
1263 * DESCRIPTION: mapping stream buffer via domain socket to server
1264 *
1265 * PARAMETERS :
1266 * @camera_handle: camera handle
1267 * @ch_id : channel handle
1268 * @s_id : stream handle
1269 * @buf_type : type of buffer to be mapped. could be following values:
1270 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1271 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1272 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1273 * @buf_idx : index of buffer within the stream buffers, only valid if
1274 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1275 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1276 * @plane_idx : plane index. If all planes share the same fd,
1277 * plane_idx = -1; otherwise, plean_idx is the
1278 * index to plane (0..num_of_planes)
1279 * @fd : file descriptor of the buffer
1280 * @size : size of the buffer
1281 *
1282 * RETURN : int32_t type of status
1283 * 0 -- success
1284 * -1 -- failure
1285 *==========================================================================*/
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,size_t size)1286 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle,
1287 uint32_t ch_id,
1288 uint32_t stream_id,
1289 uint8_t buf_type,
1290 uint32_t buf_idx,
1291 int32_t plane_idx,
1292 int fd,
1293 size_t size)
1294 {
1295 int32_t rc = -1;
1296 mm_camera_obj_t * my_obj = NULL;
1297
1298 pthread_mutex_lock(&g_intf_lock);
1299 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1300
1301 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
1302 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
1303
1304 if(my_obj) {
1305 pthread_mutex_lock(&my_obj->cam_lock);
1306 pthread_mutex_unlock(&g_intf_lock);
1307 rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
1308 buf_type, buf_idx, plane_idx,
1309 fd, size);
1310 }else{
1311 pthread_mutex_unlock(&g_intf_lock);
1312 }
1313
1314 CDBG("%s :X rc = %d", __func__, rc);
1315 return rc;
1316 }
1317
1318 /*===========================================================================
1319 * FUNCTION : mm_camera_intf_unmap_stream_buf
1320 *
1321 * DESCRIPTION: unmapping stream buffer via domain socket to server
1322 *
1323 * PARAMETERS :
1324 * @camera_handle: camera handle
1325 * @ch_id : channel handle
1326 * @s_id : stream handle
1327 * @buf_type : type of buffer to be unmapped. could be following values:
1328 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1329 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1330 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1331 * @buf_idx : index of buffer within the stream buffers, only valid if
1332 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1333 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1334 * @plane_idx : plane index. If all planes share the same fd,
1335 * plane_idx = -1; otherwise, plean_idx is the
1336 * index to plane (0..num_of_planes)
1337 *
1338 * RETURN : int32_t type of status
1339 * 0 -- success
1340 * -1 -- failure
1341 *==========================================================================*/
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)1342 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle,
1343 uint32_t ch_id,
1344 uint32_t stream_id,
1345 uint8_t buf_type,
1346 uint32_t buf_idx,
1347 int32_t plane_idx)
1348 {
1349 int32_t rc = -1;
1350 mm_camera_obj_t * my_obj = NULL;
1351
1352 pthread_mutex_lock(&g_intf_lock);
1353 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1354
1355 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
1356 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
1357
1358 if(my_obj) {
1359 pthread_mutex_lock(&my_obj->cam_lock);
1360 pthread_mutex_unlock(&g_intf_lock);
1361 rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
1362 buf_type, buf_idx, plane_idx);
1363 }else{
1364 pthread_mutex_unlock(&g_intf_lock);
1365 }
1366
1367 CDBG("%s :X rc = %d", __func__, rc);
1368 return rc;
1369 }
1370
1371 /*===========================================================================
1372 * FUNCTION : get_sensor_info
1373 *
1374 * DESCRIPTION: get sensor info like facing(back/front) and mount angle
1375 *
1376 * PARAMETERS :
1377 *
1378 * RETURN :
1379 *==========================================================================*/
get_sensor_info()1380 void get_sensor_info()
1381 {
1382 int rc = 0;
1383 int dev_fd = -1;
1384 struct media_device_info mdev_info;
1385 int num_media_devices = 0;
1386 size_t num_cameras = 0;
1387
1388 CDBG("%s : E", __func__);
1389 while (1) {
1390 char dev_name[32];
1391 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
1392 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
1393 if (dev_fd < 0) {
1394 CDBG("Done discovering media devices\n");
1395 break;
1396 }
1397 num_media_devices++;
1398 memset(&mdev_info, 0, sizeof(mdev_info));
1399 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
1400 if (rc < 0) {
1401 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
1402 close(dev_fd);
1403 dev_fd = -1;
1404 num_cameras = 0;
1405 break;
1406 }
1407
1408 if(strncmp(mdev_info.model, MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) {
1409 close(dev_fd);
1410 dev_fd = -1;
1411 continue;
1412 }
1413
1414 unsigned int num_entities = 1;
1415 while (1) {
1416 struct media_entity_desc entity;
1417 uint32_t temp;
1418 uint32_t mount_angle;
1419 uint32_t facing;
1420
1421 memset(&entity, 0, sizeof(entity));
1422 entity.id = num_entities++;
1423 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
1424 if (rc < 0) {
1425 CDBG("Done enumerating media entities\n");
1426 rc = 0;
1427 break;
1428 }
1429 if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
1430 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) {
1431 temp = entity.flags >> 8;
1432 mount_angle = (temp & 0xFF) * 90;
1433 facing = (temp >> 8);
1434 ALOGD("index = %u flag = %x mount_angle = %u facing = %u\n",
1435 (unsigned int)num_cameras, (unsigned int)temp,
1436 (unsigned int)mount_angle, (unsigned int)facing);
1437 g_cam_ctrl.info[num_cameras].facing = (int)facing;
1438 g_cam_ctrl.info[num_cameras].orientation = (int)mount_angle;
1439 num_cameras++;
1440 continue;
1441 }
1442 }
1443
1444 CDBG("%s: dev_info[id=%zu,name='%s']\n",
1445 __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
1446
1447 close(dev_fd);
1448 dev_fd = -1;
1449 }
1450
1451 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
1452 return;
1453 }
1454
1455 /*===========================================================================
1456 * FUNCTION : sort_camera_info
1457 *
1458 * DESCRIPTION: sort camera info to keep back cameras idx is smaller than front cameras idx
1459 *
1460 * PARAMETERS : number of cameras
1461 *
1462 * RETURN :
1463 *==========================================================================*/
sort_camera_info(int num_cam)1464 void sort_camera_info(int num_cam)
1465 {
1466 int idx = 0, i;
1467 struct camera_info temp_info[MM_CAMERA_MAX_NUM_SENSORS];
1468 char temp_dev_name[MM_CAMERA_MAX_NUM_SENSORS][MM_CAMERA_DEV_NAME_LEN];
1469 memset(temp_info, 0, sizeof(temp_info));
1470 memset(temp_dev_name, 0, sizeof(temp_dev_name));
1471
1472 /* firstly save the back cameras info*/
1473 for (i = 0; i < num_cam; i++) {
1474 if (g_cam_ctrl.info[i].facing == CAMERA_FACING_BACK) {
1475 temp_info[idx] = g_cam_ctrl.info[i];
1476 memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
1477 MM_CAMERA_DEV_NAME_LEN);
1478 }
1479 }
1480
1481 /* then save the front cameras info*/
1482 for (i = 0; i < num_cam; i++) {
1483 if (g_cam_ctrl.info[i].facing == CAMERA_FACING_FRONT) {
1484 temp_info[idx] = g_cam_ctrl.info[i];
1485 memcpy(temp_dev_name[idx++],g_cam_ctrl.video_dev_name[i],
1486 MM_CAMERA_DEV_NAME_LEN);
1487 }
1488 }
1489
1490 if (idx == num_cam) {
1491 memcpy(g_cam_ctrl.info, temp_info, sizeof(temp_info));
1492 memcpy(g_cam_ctrl.video_dev_name, temp_dev_name, sizeof(temp_dev_name));
1493 } else {
1494 ALOGE("%s: Failed to sort all cameras!", __func__);
1495 ALOGE("%s: Number of cameras %d sorted %d", __func__, num_cam, idx);
1496 }
1497 return;
1498 }
1499
1500 /*===========================================================================
1501 * FUNCTION : get_num_of_cameras
1502 *
1503 * DESCRIPTION: get number of cameras
1504 *
1505 * PARAMETERS :
1506 *
1507 * RETURN : number of cameras supported
1508 *==========================================================================*/
get_num_of_cameras()1509 uint8_t get_num_of_cameras()
1510 {
1511 int rc = 0;
1512 int dev_fd = -1;
1513 struct media_device_info mdev_info;
1514 int num_media_devices = 0;
1515 int8_t num_cameras = 0;
1516 char subdev_name[32];
1517 int32_t sd_fd = -1;
1518 struct sensor_init_cfg_data cfg;
1519 char prop[PROPERTY_VALUE_MAX];
1520 uint32_t globalLogLevel = 0;
1521
1522 property_get("persist.camera.hal.debug", prop, "0");
1523 int val = atoi(prop);
1524 if (0 <= val) {
1525 gMmCameraIntfLogLevel = (uint32_t)val;
1526 }
1527 property_get("persist.camera.global.debug", prop, "0");
1528 val = atoi(prop);
1529 if (0 <= val) {
1530 globalLogLevel = (uint32_t)val;
1531 }
1532
1533 /* Highest log level among hal.logs and global.logs is selected */
1534 if (gMmCameraIntfLogLevel < globalLogLevel)
1535 gMmCameraIntfLogLevel = globalLogLevel;
1536
1537 CDBG("%s : E", __func__);
1538
1539 property_get("vold.decrypt", prop, "0");
1540 int decrypt = atoi(prop);
1541 if (decrypt == 1)
1542 return 0;
1543
1544 /* lock the mutex */
1545 pthread_mutex_lock(&g_intf_lock);
1546
1547 while (1) {
1548 uint32_t num_entities = 1U;
1549 char dev_name[32];
1550
1551 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
1552 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
1553 if (dev_fd < 0) {
1554 CDBG("Done discovering media devices\n");
1555 break;
1556 }
1557 num_media_devices++;
1558 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
1559 if (rc < 0) {
1560 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
1561 close(dev_fd);
1562 dev_fd = -1;
1563 break;
1564 }
1565
1566 if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME,
1567 sizeof(mdev_info.model)) != 0) {
1568 close(dev_fd);
1569 dev_fd = -1;
1570 continue;
1571 }
1572
1573 while (1) {
1574 struct media_entity_desc entity;
1575 memset(&entity, 0, sizeof(entity));
1576 entity.id = num_entities++;
1577 CDBG("entity id %d", entity.id);
1578 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
1579 if (rc < 0) {
1580 CDBG("Done enumerating media entities");
1581 rc = 0;
1582 break;
1583 }
1584 CDBG("entity name %s type %d group id %d",
1585 entity.name, entity.type, entity.group_id);
1586 if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
1587 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) {
1588 snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name);
1589 break;
1590 }
1591 }
1592 close(dev_fd);
1593 dev_fd = -1;
1594 }
1595
1596 /* Open sensor_init subdev */
1597 sd_fd = open(subdev_name, O_RDWR);
1598 if (sd_fd < 0) {
1599 CDBG_ERROR("Open sensor_init subdev failed");
1600 return FALSE;
1601 }
1602
1603 cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE;
1604 cfg.cfg.setting = NULL;
1605 if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
1606 CDBG_ERROR("failed");
1607 }
1608 close(sd_fd);
1609 dev_fd = -1;
1610
1611
1612 num_media_devices = 0;
1613 while (1) {
1614 uint32_t num_entities = 1U;
1615 char dev_name[32];
1616
1617 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
1618 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
1619 if (dev_fd < 0) {
1620 CDBG("Done discovering media devices: %s\n", strerror(errno));
1621 break;
1622 }
1623 num_media_devices++;
1624 memset(&mdev_info, 0, sizeof(mdev_info));
1625 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
1626 if (rc < 0) {
1627 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
1628 close(dev_fd);
1629 dev_fd = -1;
1630 num_cameras = 0;
1631 break;
1632 }
1633
1634 if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) {
1635 close(dev_fd);
1636 dev_fd = -1;
1637 continue;
1638 }
1639
1640 while (1) {
1641 struct media_entity_desc entity;
1642 memset(&entity, 0, sizeof(entity));
1643 entity.id = num_entities++;
1644 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
1645 if (rc < 0) {
1646 CDBG("Done enumerating media entities\n");
1647 rc = 0;
1648 break;
1649 }
1650 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
1651 strlcpy(g_cam_ctrl.video_dev_name[num_cameras],
1652 entity.name, sizeof(entity.name));
1653 break;
1654 }
1655 }
1656
1657 CDBG("%s: dev_info[id=%d,name='%s']\n",
1658 __func__, (int)num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
1659
1660 num_cameras++;
1661 close(dev_fd);
1662 dev_fd = -1;
1663 }
1664 g_cam_ctrl.num_cam = num_cameras;
1665
1666 get_sensor_info();
1667 sort_camera_info(g_cam_ctrl.num_cam);
1668 /* unlock the mutex */
1669 pthread_mutex_unlock(&g_intf_lock);
1670 CDBG("%s: num_cameras=%d\n", __func__, (int)g_cam_ctrl.num_cam);
1671 return(uint8_t)g_cam_ctrl.num_cam;
1672 }
1673
1674 /*===========================================================================
1675 * FUNCTION : mm_camera_intf_process_advanced_capture
1676 *
1677 * DESCRIPTION: Configures channel advanced capture mode
1678 *
1679 * PARAMETERS :
1680 * @camera_handle: camera handle
1681 * @type : advanced capture type
1682 * @ch_id : channel handle
1683 * @trigger : 1 for start and 0 for cancel/stop
1684 * @value : input capture configaration
1685 *
1686 * RETURN : int32_t type of status
1687 * 0 -- success
1688 * -1 -- failure
1689 *==========================================================================*/
mm_camera_intf_process_advanced_capture(uint32_t camera_handle,uint32_t ch_id,mm_camera_advanced_capture_t type,int8_t trigger,void * in_value)1690 static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle,
1691 uint32_t ch_id, mm_camera_advanced_capture_t type,
1692 int8_t trigger, void *in_value)
1693 {
1694 int32_t rc = -1;
1695 mm_camera_obj_t * my_obj = NULL;
1696
1697 CDBG("%s: E camera_handler = %d,ch_id = %d",
1698 __func__, camera_handle, ch_id);
1699 pthread_mutex_lock(&g_intf_lock);
1700 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1701
1702 if(my_obj) {
1703 pthread_mutex_lock(&my_obj->cam_lock);
1704 pthread_mutex_unlock(&g_intf_lock);
1705 rc = mm_camera_channel_advanced_capture(my_obj, ch_id, type,
1706 (uint32_t)trigger, in_value);
1707 } else {
1708 pthread_mutex_unlock(&g_intf_lock);
1709 }
1710 CDBG("%s: X ", __func__);
1711 return rc;
1712 }
1713
get_cam_info(uint32_t camera_id)1714 struct camera_info *get_cam_info(uint32_t camera_id)
1715 {
1716 return &g_cam_ctrl.info[camera_id];
1717 }
1718
1719 /* camera ops v-table */
1720 static mm_camera_ops_t mm_camera_ops = {
1721 .query_capability = mm_camera_intf_query_capability,
1722 .register_event_notify = mm_camera_intf_register_event_notify,
1723 .close_camera = mm_camera_intf_close,
1724 .error_close_camera = mm_camera_intf_error_close,
1725 .set_parms = mm_camera_intf_set_parms,
1726 .get_parms = mm_camera_intf_get_parms,
1727 .do_auto_focus = mm_camera_intf_do_auto_focus,
1728 .cancel_auto_focus = mm_camera_intf_cancel_auto_focus,
1729 .prepare_snapshot = mm_camera_intf_prepare_snapshot,
1730 .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,
1731 .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,
1732 .map_buf = mm_camera_intf_map_buf,
1733 .unmap_buf = mm_camera_intf_unmap_buf,
1734 .add_channel = mm_camera_intf_add_channel,
1735 .delete_channel = mm_camera_intf_del_channel,
1736 .get_bundle_info = mm_camera_intf_get_bundle_info,
1737 .add_stream = mm_camera_intf_add_stream,
1738 .link_stream = mm_camera_intf_link_stream,
1739 .delete_stream = mm_camera_intf_del_stream,
1740 .config_stream = mm_camera_intf_config_stream,
1741 .qbuf = mm_camera_intf_qbuf,
1742 .get_queued_buf_count = mm_camera_intf_get_queued_buf_count,
1743 .map_stream_buf = mm_camera_intf_map_stream_buf,
1744 .unmap_stream_buf = mm_camera_intf_unmap_stream_buf,
1745 .set_stream_parms = mm_camera_intf_set_stream_parms,
1746 .get_stream_parms = mm_camera_intf_get_stream_parms,
1747 .start_channel = mm_camera_intf_start_channel,
1748 .stop_channel = mm_camera_intf_stop_channel,
1749 .request_super_buf = mm_camera_intf_request_super_buf,
1750 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
1751 .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,
1752 .configure_notify_mode = mm_camera_intf_configure_notify_mode,
1753 .process_advanced_capture = mm_camera_intf_process_advanced_capture
1754 };
1755
1756 /*===========================================================================
1757 * FUNCTION : camera_open
1758 *
1759 * DESCRIPTION: open a camera by camera index
1760 *
1761 * PARAMETERS :
1762 * @camera_idx : camera index. should within range of 0 to num_of_cameras
1763 * @camera_vtbl : ptr to a virtual table containing camera handle and operation table.
1764 *
1765 * RETURN : int32_t type of status
1766 * 0 -- success
1767 * non-zero error code -- failure
1768 *==========================================================================*/
camera_open(uint8_t camera_idx,mm_camera_vtbl_t ** camera_vtbl)1769 int32_t camera_open(uint8_t camera_idx, mm_camera_vtbl_t **camera_vtbl)
1770 {
1771 int32_t rc = 0;
1772 mm_camera_obj_t *cam_obj = NULL;
1773
1774 CDBG("%s: E camera_idx = %d\n", __func__, camera_idx);
1775 if (camera_idx >= g_cam_ctrl.num_cam) {
1776 CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
1777 return -EINVAL;
1778 }
1779
1780 pthread_mutex_lock(&g_intf_lock);
1781 /* opened already */
1782 if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
1783 /* Add reference */
1784 g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
1785 pthread_mutex_unlock(&g_intf_lock);
1786 CDBG("%s: opened alreadyn", __func__);
1787 *camera_vtbl = &g_cam_ctrl.cam_obj[camera_idx]->vtbl;
1788 return rc;
1789 }
1790
1791 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
1792 if(NULL == cam_obj) {
1793 pthread_mutex_unlock(&g_intf_lock);
1794 CDBG_ERROR("%s: no mem", __func__);
1795 return -EINVAL;
1796 }
1797
1798 /* initialize camera obj */
1799 memset(cam_obj, 0, sizeof(mm_camera_obj_t));
1800 cam_obj->ctrl_fd = -1;
1801 cam_obj->ds_fd = -1;
1802 cam_obj->ref_count++;
1803 cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
1804 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
1805 cam_obj->vtbl.ops = &mm_camera_ops;
1806 pthread_mutex_init(&cam_obj->cam_lock, NULL);
1807 /* unlock global interface lock, if not, in dual camera use case,
1808 * current open will block operation of another opened camera obj*/
1809 pthread_mutex_lock(&cam_obj->cam_lock);
1810 pthread_mutex_unlock(&g_intf_lock);
1811
1812 rc = mm_camera_open(cam_obj);
1813
1814 pthread_mutex_lock(&g_intf_lock);
1815 if (rc != 0) {
1816 CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
1817 pthread_mutex_destroy(&cam_obj->cam_lock);
1818 g_cam_ctrl.cam_obj[camera_idx] = NULL;
1819 free(cam_obj);
1820 cam_obj = NULL;
1821 pthread_mutex_unlock(&g_intf_lock);
1822 *camera_vtbl = NULL;
1823 return rc;
1824 } else {
1825 CDBG("%s: Open succeded\n", __func__);
1826 g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
1827 pthread_mutex_unlock(&g_intf_lock);
1828 *camera_vtbl = &cam_obj->vtbl;
1829 return 0;
1830 }
1831 }
1832