1 /* Copyright (c) 2012-2014, The Linux Foundation. All rights reserved.
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 */
29
30 #include <pthread.h>
31 #include <errno.h>
32 #include <sys/ioctl.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <fcntl.h>
36 #include <poll.h>
37 #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 mm_camera_obj_t * my_obj = NULL;
406
407 CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
408
409 pthread_mutex_lock(&g_intf_lock);
410 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
411
412 if (my_obj){
413 /*do not decrement the ref_count yet since that will happen during close*/
414 if((my_obj->ref_count - 1) > 0) {
415 /* still have reference to obj, return here */
416 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
417 pthread_mutex_unlock(&g_intf_lock);
418 rc = 0;
419 } else {
420 /* need close camera here as no other reference*/
421 pthread_mutex_lock(&my_obj->cam_lock);
422 pthread_mutex_unlock(&g_intf_lock);
423
424 rc = mm_camera_close_fd(my_obj);
425 }
426 } else {
427 pthread_mutex_unlock(&g_intf_lock);
428 }
429
430 return rc;
431 }
432
433 /*===========================================================================
434 * FUNCTION : mm_camera_intf_add_channel
435 *
436 * DESCRIPTION: add a channel
437 *
438 * PARAMETERS :
439 * @camera_handle: camera handle
440 * @attr : bundle attribute of the channel if needed
441 * @channel_cb : callback function for bundle data notify
442 * @userdata : user data ptr
443 *
444 * RETURN : uint32_t type of channel handle
445 * 0 -- invalid channel handle, meaning the op failed
446 * >0 -- successfully added a channel with a valid handle
447 * NOTE : if no bundle data notify is needed, meaning each stream in the
448 * channel will have its own stream data notify callback, then
449 * attr, channel_cb, and userdata can be NULL. In this case,
450 * no matching logic will be performed in channel for the bundling.
451 *==========================================================================*/
mm_camera_intf_add_channel(uint32_t camera_handle,mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t channel_cb,void * userdata)452 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle,
453 mm_camera_channel_attr_t *attr,
454 mm_camera_buf_notify_t channel_cb,
455 void *userdata)
456 {
457 uint32_t ch_id = 0;
458 mm_camera_obj_t * my_obj = NULL;
459
460 CDBG("%s :E camera_handler = %d", __func__, camera_handle);
461 pthread_mutex_lock(&g_intf_lock);
462 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
463
464 if(my_obj) {
465 pthread_mutex_lock(&my_obj->cam_lock);
466 pthread_mutex_unlock(&g_intf_lock);
467 ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
468 } else {
469 pthread_mutex_unlock(&g_intf_lock);
470 }
471 CDBG("%s :X ch_id = %d", __func__, ch_id);
472 return ch_id;
473 }
474
475 /*===========================================================================
476 * FUNCTION : mm_camera_intf_del_channel
477 *
478 * DESCRIPTION: delete a channel by its handle
479 *
480 * PARAMETERS :
481 * @camera_handle: camera handle
482 * @ch_id : channel handle
483 *
484 * RETURN : int32_t type of status
485 * 0 -- success
486 * -1 -- failure
487 * NOTE : all streams in the channel should be stopped already before
488 * this channel can be deleted.
489 *==========================================================================*/
mm_camera_intf_del_channel(uint32_t camera_handle,uint32_t ch_id)490 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle,
491 uint32_t ch_id)
492 {
493 int32_t rc = -1;
494 mm_camera_obj_t * my_obj = NULL;
495
496 CDBG("%s :E ch_id = %d", __func__, ch_id);
497 pthread_mutex_lock(&g_intf_lock);
498 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
499
500 if(my_obj) {
501 pthread_mutex_lock(&my_obj->cam_lock);
502 pthread_mutex_unlock(&g_intf_lock);
503 rc = mm_camera_del_channel(my_obj, ch_id);
504 } else {
505 pthread_mutex_unlock(&g_intf_lock);
506 }
507 CDBG("%s :X", __func__);
508 return rc;
509 }
510
511 /*===========================================================================
512 * FUNCTION : mm_camera_intf_get_bundle_info
513 *
514 * DESCRIPTION: query bundle info of the channel
515 *
516 * PARAMETERS :
517 * @camera_handle: camera handle
518 * @ch_id : channel handle
519 * @bundle_info : bundle info to be filled in
520 *
521 * RETURN : int32_t type of status
522 * 0 -- success
523 * -1 -- failure
524 * NOTE : all streams in the channel should be stopped already before
525 * this channel can be deleted.
526 *==========================================================================*/
mm_camera_intf_get_bundle_info(uint32_t camera_handle,uint32_t ch_id,cam_bundle_config_t * bundle_info)527 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle,
528 uint32_t ch_id,
529 cam_bundle_config_t *bundle_info)
530 {
531 int32_t rc = -1;
532 mm_camera_obj_t * my_obj = NULL;
533
534 CDBG("%s :E ch_id = %d", __func__, ch_id);
535 pthread_mutex_lock(&g_intf_lock);
536 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
537
538 if(my_obj) {
539 pthread_mutex_lock(&my_obj->cam_lock);
540 pthread_mutex_unlock(&g_intf_lock);
541 rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
542 } else {
543 pthread_mutex_unlock(&g_intf_lock);
544 }
545 CDBG("%s :X", __func__);
546 return rc;
547 }
548
549 /*===========================================================================
550 * FUNCTION : mm_camera_intf_register_event_notify
551 *
552 * DESCRIPTION: register for event notify
553 *
554 * PARAMETERS :
555 * @camera_handle: camera handle
556 * @evt_cb : callback for event notify
557 * @user_data : user data ptr
558 *
559 * RETURN : int32_t type of status
560 * 0 -- success
561 * -1 -- failure
562 *==========================================================================*/
mm_camera_intf_register_event_notify(uint32_t camera_handle,mm_camera_event_notify_t evt_cb,void * user_data)563 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle,
564 mm_camera_event_notify_t evt_cb,
565 void * user_data)
566 {
567 int32_t rc = -1;
568 mm_camera_obj_t * my_obj = NULL;
569
570 CDBG("%s :E ", __func__);
571 pthread_mutex_lock(&g_intf_lock);
572 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
573
574 if(my_obj) {
575 pthread_mutex_lock(&my_obj->cam_lock);
576 pthread_mutex_unlock(&g_intf_lock);
577 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
578 } else {
579 pthread_mutex_unlock(&g_intf_lock);
580 }
581 CDBG("%s :E rc = %d", __func__, rc);
582 return rc;
583 }
584
585 /*===========================================================================
586 * FUNCTION : mm_camera_intf_qbuf
587 *
588 * DESCRIPTION: enqueue buffer back to kernel
589 *
590 * PARAMETERS :
591 * @camera_handle: camera handle
592 * @ch_id : channel handle
593 * @buf : buf ptr to be enqueued
594 *
595 * RETURN : int32_t type of status
596 * 0 -- success
597 * -1 -- failure
598 *==========================================================================*/
mm_camera_intf_qbuf(uint32_t camera_handle,uint32_t ch_id,mm_camera_buf_def_t * buf)599 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle,
600 uint32_t ch_id,
601 mm_camera_buf_def_t *buf)
602 {
603 int32_t rc = -1;
604 mm_camera_obj_t * my_obj = NULL;
605
606 pthread_mutex_lock(&g_intf_lock);
607 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
608
609 if(my_obj) {
610 pthread_mutex_lock(&my_obj->cam_lock);
611 pthread_mutex_unlock(&g_intf_lock);
612 rc = mm_camera_qbuf(my_obj, ch_id, buf);
613 } else {
614 pthread_mutex_unlock(&g_intf_lock);
615 }
616 CDBG("%s :X evt_type = %d",__func__,rc);
617 return rc;
618 }
619
620 /*===========================================================================
621 * FUNCTION : mm_camera_intf_add_stream
622 *
623 * DESCRIPTION: add a stream into a channel
624 *
625 * PARAMETERS :
626 * @camera_handle: camera handle
627 * @ch_id : channel handle
628 *
629 * RETURN : uint32_t type of stream handle
630 * 0 -- invalid stream handle, meaning the op failed
631 * >0 -- successfully added a stream with a valid handle
632 *==========================================================================*/
mm_camera_intf_add_stream(uint32_t camera_handle,uint32_t ch_id)633 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle,
634 uint32_t ch_id)
635 {
636 uint32_t stream_id = 0;
637 mm_camera_obj_t * my_obj = NULL;
638
639 CDBG("%s : E handle = %d ch_id = %d",
640 __func__, camera_handle, ch_id);
641
642 pthread_mutex_lock(&g_intf_lock);
643 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
644
645 if(my_obj) {
646 pthread_mutex_lock(&my_obj->cam_lock);
647 pthread_mutex_unlock(&g_intf_lock);
648 stream_id = mm_camera_add_stream(my_obj, ch_id);
649 } else {
650 pthread_mutex_unlock(&g_intf_lock);
651 }
652 CDBG("%s :X stream_id = %d", __func__, stream_id);
653 return stream_id;
654 }
655
656 /*===========================================================================
657 * FUNCTION : mm_camera_intf_del_stream
658 *
659 * DESCRIPTION: delete a stream by its handle
660 *
661 * PARAMETERS :
662 * @camera_handle: camera handle
663 * @ch_id : channel handle
664 * @stream_id : stream handle
665 *
666 * RETURN : int32_t type of status
667 * 0 -- success
668 * -1 -- failure
669 * NOTE : stream should be stopped already before it can be deleted.
670 *==========================================================================*/
mm_camera_intf_del_stream(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id)671 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle,
672 uint32_t ch_id,
673 uint32_t stream_id)
674 {
675 int32_t rc = -1;
676 mm_camera_obj_t * my_obj = NULL;
677
678 CDBG("%s : E handle = %d ch_id = %d stream_id = %d",
679 __func__, camera_handle, ch_id, stream_id);
680
681 pthread_mutex_lock(&g_intf_lock);
682 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
683
684 if(my_obj) {
685 pthread_mutex_lock(&my_obj->cam_lock);
686 pthread_mutex_unlock(&g_intf_lock);
687 rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
688 } else {
689 pthread_mutex_unlock(&g_intf_lock);
690 }
691 CDBG("%s :X rc = %d", __func__, rc);
692 return rc;
693 }
694
695 /*===========================================================================
696 * FUNCTION : mm_camera_intf_config_stream
697 *
698 * DESCRIPTION: configure a stream
699 *
700 * PARAMETERS :
701 * @camera_handle: camera handle
702 * @ch_id : channel handle
703 * @stream_id : stream handle
704 * @config : stream configuration
705 *
706 * RETURN : int32_t type of status
707 * 0 -- success
708 * -1 -- failure
709 *==========================================================================*/
mm_camera_intf_config_stream(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)710 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle,
711 uint32_t ch_id,
712 uint32_t stream_id,
713 mm_camera_stream_config_t *config)
714 {
715 int32_t rc = -1;
716 mm_camera_obj_t * my_obj = NULL;
717
718 CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",
719 __func__, camera_handle, ch_id, stream_id);
720
721 pthread_mutex_lock(&g_intf_lock);
722 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
723
724 CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
725
726 if(my_obj) {
727 pthread_mutex_lock(&my_obj->cam_lock);
728 pthread_mutex_unlock(&g_intf_lock);
729 rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
730 } else {
731 pthread_mutex_unlock(&g_intf_lock);
732 }
733 CDBG("%s :X rc = %d", __func__, rc);
734 return rc;
735 }
736
737 /*===========================================================================
738 * FUNCTION : mm_camera_intf_start_channel
739 *
740 * DESCRIPTION: start a channel, which will start all streams in the channel
741 *
742 * PARAMETERS :
743 * @camera_handle: camera handle
744 * @ch_id : channel handle
745 *
746 * RETURN : int32_t type of status
747 * 0 -- success
748 * -1 -- failure
749 *==========================================================================*/
mm_camera_intf_start_channel(uint32_t camera_handle,uint32_t ch_id)750 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle,
751 uint32_t ch_id)
752 {
753 int32_t rc = -1;
754 mm_camera_obj_t * my_obj = NULL;
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_start_channel(my_obj, ch_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_stop_channel
772 *
773 * DESCRIPTION: stop a channel, which will stop all streams in the channel
774 *
775 * PARAMETERS :
776 * @camera_handle: camera handle
777 * @ch_id : channel handle
778 *
779 * RETURN : int32_t type of status
780 * 0 -- success
781 * -1 -- failure
782 *==========================================================================*/
mm_camera_intf_stop_channel(uint32_t camera_handle,uint32_t ch_id)783 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle,
784 uint32_t ch_id)
785 {
786 int32_t rc = -1;
787 mm_camera_obj_t * my_obj = NULL;
788
789 pthread_mutex_lock(&g_intf_lock);
790 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
791
792 if(my_obj) {
793 pthread_mutex_lock(&my_obj->cam_lock);
794 pthread_mutex_unlock(&g_intf_lock);
795 rc = mm_camera_stop_channel(my_obj, ch_id);
796 } else {
797 pthread_mutex_unlock(&g_intf_lock);
798 }
799 CDBG("%s :X rc = %d", __func__, rc);
800 return rc;
801 }
802
803 /*===========================================================================
804 * FUNCTION : mm_camera_intf_request_super_buf
805 *
806 * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
807 * frames from superbuf queue
808 *
809 * PARAMETERS :
810 * @camera_handle: camera handle
811 * @ch_id : channel handle
812 * @num_buf_requested : number of matched frames needed
813 *
814 * RETURN : int32_t type of status
815 * 0 -- success
816 * -1 -- failure
817 *==========================================================================*/
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)818 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle,
819 uint32_t ch_id,
820 uint32_t num_buf_requested,
821 uint32_t num_retro_buf_requested)
822 {
823 int32_t rc = -1;
824 CDBG("%s :E camera_handler = %d,ch_id = %d",
825 __func__, camera_handle, ch_id);
826 mm_camera_obj_t * my_obj = NULL;
827
828 pthread_mutex_lock(&g_intf_lock);
829 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
830
831 if(my_obj) {
832 pthread_mutex_lock(&my_obj->cam_lock);
833 pthread_mutex_unlock(&g_intf_lock);
834 rc = mm_camera_request_super_buf (my_obj, ch_id,
835 num_buf_requested, num_retro_buf_requested);
836 } else {
837 pthread_mutex_unlock(&g_intf_lock);
838 }
839 CDBG("%s :X rc = %d", __func__, rc);
840 return rc;
841 }
842
843 /*===========================================================================
844 * FUNCTION : mm_camera_intf_cancel_super_buf_request
845 *
846 * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
847 * of matched frames from superbuf queue
848 *
849 * PARAMETERS :
850 * @camera_handle: camera handle
851 * @ch_id : channel handle
852 *
853 * RETURN : int32_t type of status
854 * 0 -- success
855 * -1 -- failure
856 *==========================================================================*/
mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,uint32_t ch_id)857 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,
858 uint32_t ch_id)
859 {
860 int32_t rc = -1;
861 mm_camera_obj_t * my_obj = NULL;
862
863 CDBG("%s :E camera_handler = %d,ch_id = %d",
864 __func__, camera_handle, ch_id);
865 pthread_mutex_lock(&g_intf_lock);
866 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
867
868 if(my_obj) {
869 pthread_mutex_lock(&my_obj->cam_lock);
870 pthread_mutex_unlock(&g_intf_lock);
871 rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
872 } else {
873 pthread_mutex_unlock(&g_intf_lock);
874 }
875 CDBG("%s :X rc = %d", __func__, rc);
876 return rc;
877 }
878
879 /*===========================================================================
880 * FUNCTION : mm_camera_intf_flush_super_buf_queue
881 *
882 * DESCRIPTION: flush out all frames in the superbuf queue
883 *
884 * PARAMETERS :
885 * @camera_handle: camera handle
886 * @ch_id : channel handle
887 * @frame_idx : frame index
888 *
889 * RETURN : int32_t type of status
890 * 0 -- success
891 * -1 -- failure
892 *==========================================================================*/
mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,uint32_t ch_id,uint32_t frame_idx)893 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,
894 uint32_t ch_id, uint32_t frame_idx)
895 {
896 int32_t rc = -1;
897 mm_camera_obj_t * my_obj = NULL;
898
899 CDBG("%s :E camera_handler = %d,ch_id = %d",
900 __func__, camera_handle, ch_id);
901 pthread_mutex_lock(&g_intf_lock);
902 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
903
904 if(my_obj) {
905 pthread_mutex_lock(&my_obj->cam_lock);
906 pthread_mutex_unlock(&g_intf_lock);
907 rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
908 } else {
909 pthread_mutex_unlock(&g_intf_lock);
910 }
911 CDBG("%s :X rc = %d", __func__, rc);
912 return rc;
913 }
914
915 /*===========================================================================
916 * FUNCTION : mm_camera_intf_start_zsl_snapshot
917 *
918 * DESCRIPTION: Starts zsl snapshot
919 *
920 * PARAMETERS :
921 * @camera_handle: camera handle
922 * @ch_id : channel handle
923 *
924 * RETURN : int32_t type of status
925 * 0 -- success
926 * -1 -- failure
927 *==========================================================================*/
mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle,uint32_t ch_id)928 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle,
929 uint32_t ch_id)
930 {
931 int32_t rc = -1;
932 mm_camera_obj_t * my_obj = NULL;
933
934 CDBG("%s :E camera_handler = %d,ch_id = %d",
935 __func__, camera_handle, ch_id);
936 pthread_mutex_lock(&g_intf_lock);
937 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
938
939 if(my_obj) {
940 pthread_mutex_lock(&my_obj->cam_lock);
941 pthread_mutex_unlock(&g_intf_lock);
942 rc = mm_camera_start_zsl_snapshot_ch(my_obj, ch_id);
943 } else {
944 pthread_mutex_unlock(&g_intf_lock);
945 }
946 CDBG("%s :X rc = %d", __func__, rc);
947 return rc;
948 }
949
950 /*===========================================================================
951 * FUNCTION : mm_camera_intf_stop_zsl_snapshot
952 *
953 * DESCRIPTION: Stops zsl snapshot
954 *
955 * PARAMETERS :
956 * @camera_handle: camera handle
957 * @ch_id : channel handle
958 *
959 * RETURN : int32_t type of status
960 * 0 -- success
961 * -1 -- failure
962 *==========================================================================*/
mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle,uint32_t ch_id)963 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle,
964 uint32_t ch_id)
965 {
966 int32_t rc = -1;
967 mm_camera_obj_t * my_obj = NULL;
968
969 CDBG("%s :E camera_handler = %d,ch_id = %d",
970 __func__, camera_handle, ch_id);
971 pthread_mutex_lock(&g_intf_lock);
972 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
973
974 if(my_obj) {
975 pthread_mutex_lock(&my_obj->cam_lock);
976 pthread_mutex_unlock(&g_intf_lock);
977 rc = mm_camera_stop_zsl_snapshot_ch(my_obj, ch_id);
978 } else {
979 pthread_mutex_unlock(&g_intf_lock);
980 }
981 CDBG("%s :X rc = %d", __func__, rc);
982 return rc;
983 }
984
985 /*===========================================================================
986 * FUNCTION : mm_camera_intf_configure_notify_mode
987 *
988 * DESCRIPTION: Configures channel notification mode
989 *
990 * PARAMETERS :
991 * @camera_handle: camera handle
992 * @ch_id : channel handle
993 * @notify_mode : notification mode
994 *
995 * RETURN : int32_t type of status
996 * 0 -- success
997 * -1 -- failure
998 *==========================================================================*/
mm_camera_intf_configure_notify_mode(uint32_t camera_handle,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)999 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle,
1000 uint32_t ch_id,
1001 mm_camera_super_buf_notify_mode_t notify_mode)
1002 {
1003 int32_t rc = -1;
1004 mm_camera_obj_t * my_obj = NULL;
1005
1006 CDBG("%s :E camera_handler = %d,ch_id = %d",
1007 __func__, camera_handle, ch_id);
1008 pthread_mutex_lock(&g_intf_lock);
1009 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1010
1011 if(my_obj) {
1012 pthread_mutex_lock(&my_obj->cam_lock);
1013 pthread_mutex_unlock(&g_intf_lock);
1014 rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
1015 } else {
1016 pthread_mutex_unlock(&g_intf_lock);
1017 }
1018 CDBG("%s :X rc = %d", __func__, rc);
1019 return rc;
1020 }
1021
1022 /*===========================================================================
1023 * FUNCTION : mm_camera_intf_map_buf
1024 *
1025 * DESCRIPTION: mapping camera buffer via domain socket to server
1026 *
1027 * PARAMETERS :
1028 * @camera_handle: camera handle
1029 * @buf_type : type of buffer to be mapped. could be following values:
1030 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1031 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1032 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1033 * @fd : file descriptor of the buffer
1034 * @size : size of the buffer
1035 *
1036 * RETURN : int32_t type of status
1037 * 0 -- success
1038 * -1 -- failure
1039 *==========================================================================*/
mm_camera_intf_map_buf(uint32_t camera_handle,uint8_t buf_type,int fd,uint32_t size)1040 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle,
1041 uint8_t buf_type,
1042 int fd,
1043 uint32_t size)
1044 {
1045 int32_t rc = -1;
1046 mm_camera_obj_t * my_obj = NULL;
1047
1048 pthread_mutex_lock(&g_intf_lock);
1049 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1050
1051 if(my_obj) {
1052 pthread_mutex_lock(&my_obj->cam_lock);
1053 pthread_mutex_unlock(&g_intf_lock);
1054 rc = mm_camera_map_buf(my_obj, buf_type, fd, size);
1055 } else {
1056 pthread_mutex_unlock(&g_intf_lock);
1057 }
1058 return rc;
1059 }
1060
1061 /*===========================================================================
1062 * FUNCTION : mm_camera_intf_unmap_buf
1063 *
1064 * DESCRIPTION: unmapping camera buffer via domain socket to server
1065 *
1066 * PARAMETERS :
1067 * @camera_handle: camera handle
1068 * @buf_type : type of buffer to be unmapped. could be following values:
1069 * CAM_MAPPING_BUF_TYPE_CAPABILITY
1070 * CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1071 * CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1072 *
1073 * RETURN : int32_t type of status
1074 * 0 -- success
1075 * -1 -- failure
1076 *==========================================================================*/
mm_camera_intf_unmap_buf(uint32_t camera_handle,uint8_t buf_type)1077 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle,
1078 uint8_t buf_type)
1079 {
1080 int32_t rc = -1;
1081 mm_camera_obj_t * my_obj = NULL;
1082
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_unmap_buf(my_obj, buf_type);
1090 } else {
1091 pthread_mutex_unlock(&g_intf_lock);
1092 }
1093 return rc;
1094 }
1095
1096 /*===========================================================================
1097 * FUNCTION : mm_camera_intf_set_stream_parms
1098 *
1099 * DESCRIPTION: set parameters per stream
1100 *
1101 * PARAMETERS :
1102 * @camera_handle: camera handle
1103 * @ch_id : channel handle
1104 * @s_id : stream handle
1105 * @parms : ptr to a param struct to be set to server
1106 *
1107 * RETURN : int32_t type of status
1108 * 0 -- success
1109 * -1 -- failure
1110 * NOTE : Assume the parms struct buf is already mapped to server via
1111 * domain socket. Corresponding fields of parameters to be set
1112 * are already filled in by upper layer caller.
1113 *==========================================================================*/
mm_camera_intf_set_stream_parms(uint32_t camera_handle,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1114 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle,
1115 uint32_t ch_id,
1116 uint32_t s_id,
1117 cam_stream_parm_buffer_t *parms)
1118 {
1119 int32_t rc = -1;
1120 mm_camera_obj_t * my_obj = NULL;
1121
1122 pthread_mutex_lock(&g_intf_lock);
1123 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1124
1125 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
1126 __func__, camera_handle, ch_id, s_id);
1127
1128 if(my_obj) {
1129 pthread_mutex_lock(&my_obj->cam_lock);
1130 pthread_mutex_unlock(&g_intf_lock);
1131 rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
1132 }else{
1133 pthread_mutex_unlock(&g_intf_lock);
1134 }
1135 CDBG("%s :X rc = %d", __func__, rc);
1136 return rc;
1137 }
1138
1139 /*===========================================================================
1140 * FUNCTION : mm_camera_intf_get_stream_parms
1141 *
1142 * DESCRIPTION: get parameters per stream
1143 *
1144 * PARAMETERS :
1145 * @camera_handle: camera handle
1146 * @ch_id : channel handle
1147 * @s_id : stream handle
1148 * @parms : ptr to a param struct to be get from server
1149 *
1150 * RETURN : int32_t type of status
1151 * 0 -- success
1152 * -1 -- failure
1153 * NOTE : Assume the parms struct buf is already mapped to server via
1154 * domain socket. Parameters to be get from server are already
1155 * filled in by upper layer caller. After this call, corresponding
1156 * fields of requested parameters will be filled in by server with
1157 * detailed information.
1158 *==========================================================================*/
mm_camera_intf_get_stream_parms(uint32_t camera_handle,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1159 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle,
1160 uint32_t ch_id,
1161 uint32_t s_id,
1162 cam_stream_parm_buffer_t *parms)
1163 {
1164 int32_t rc = -1;
1165 mm_camera_obj_t * my_obj = NULL;
1166
1167 pthread_mutex_lock(&g_intf_lock);
1168 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1169
1170 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
1171 __func__, camera_handle, ch_id, s_id);
1172
1173 if(my_obj) {
1174 pthread_mutex_lock(&my_obj->cam_lock);
1175 pthread_mutex_unlock(&g_intf_lock);
1176 rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
1177 }else{
1178 pthread_mutex_unlock(&g_intf_lock);
1179 }
1180
1181 CDBG("%s :X rc = %d", __func__, rc);
1182 return rc;
1183 }
1184
1185 /*===========================================================================
1186 * FUNCTION : mm_camera_intf_map_stream_buf
1187 *
1188 * DESCRIPTION: mapping stream buffer via domain socket to server
1189 *
1190 * PARAMETERS :
1191 * @camera_handle: camera handle
1192 * @ch_id : channel handle
1193 * @s_id : stream handle
1194 * @buf_type : type of buffer to be mapped. could be following values:
1195 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1196 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1197 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1198 * @buf_idx : index of buffer within the stream buffers, only valid if
1199 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1200 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1201 * @plane_idx : plane index. If all planes share the same fd,
1202 * plane_idx = -1; otherwise, plean_idx is the
1203 * index to plane (0..num_of_planes)
1204 * @fd : file descriptor of the buffer
1205 * @size : size of the buffer
1206 *
1207 * RETURN : int32_t type of status
1208 * 0 -- success
1209 * -1 -- failure
1210 *==========================================================================*/
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)1211 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle,
1212 uint32_t ch_id,
1213 uint32_t stream_id,
1214 uint8_t buf_type,
1215 uint32_t buf_idx,
1216 int32_t plane_idx,
1217 int fd,
1218 uint32_t size)
1219 {
1220 int32_t rc = -1;
1221 mm_camera_obj_t * my_obj = NULL;
1222
1223 pthread_mutex_lock(&g_intf_lock);
1224 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1225
1226 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
1227 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
1228
1229 if(my_obj) {
1230 pthread_mutex_lock(&my_obj->cam_lock);
1231 pthread_mutex_unlock(&g_intf_lock);
1232 rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
1233 buf_type, buf_idx, plane_idx,
1234 fd, size);
1235 }else{
1236 pthread_mutex_unlock(&g_intf_lock);
1237 }
1238
1239 CDBG("%s :X rc = %d", __func__, rc);
1240 return rc;
1241 }
1242
1243 /*===========================================================================
1244 * FUNCTION : mm_camera_intf_unmap_stream_buf
1245 *
1246 * DESCRIPTION: unmapping stream buffer via domain socket to server
1247 *
1248 * PARAMETERS :
1249 * @camera_handle: camera handle
1250 * @ch_id : channel handle
1251 * @s_id : stream handle
1252 * @buf_type : type of buffer to be unmapped. could be following values:
1253 * CAM_MAPPING_BUF_TYPE_STREAM_BUF
1254 * CAM_MAPPING_BUF_TYPE_STREAM_INFO
1255 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1256 * @buf_idx : index of buffer within the stream buffers, only valid if
1257 * buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1258 * CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1259 * @plane_idx : plane index. If all planes share the same fd,
1260 * plane_idx = -1; otherwise, plean_idx is the
1261 * index to plane (0..num_of_planes)
1262 *
1263 * RETURN : int32_t type of status
1264 * 0 -- success
1265 * -1 -- failure
1266 *==========================================================================*/
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)1267 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle,
1268 uint32_t ch_id,
1269 uint32_t stream_id,
1270 uint8_t buf_type,
1271 uint32_t buf_idx,
1272 int32_t plane_idx)
1273 {
1274 int32_t rc = -1;
1275 mm_camera_obj_t * my_obj = NULL;
1276
1277 pthread_mutex_lock(&g_intf_lock);
1278 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1279
1280 CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
1281 __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
1282
1283 if(my_obj) {
1284 pthread_mutex_lock(&my_obj->cam_lock);
1285 pthread_mutex_unlock(&g_intf_lock);
1286 rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
1287 buf_type, buf_idx, plane_idx);
1288 }else{
1289 pthread_mutex_unlock(&g_intf_lock);
1290 }
1291
1292 CDBG("%s :X rc = %d", __func__, rc);
1293 return rc;
1294 }
1295
1296 /*===========================================================================
1297 * FUNCTION : get_sensor_info
1298 *
1299 * DESCRIPTION: get sensor info like facing(back/front) and mount angle
1300 *
1301 * PARAMETERS :
1302 *
1303 * RETURN :
1304 *==========================================================================*/
get_sensor_info()1305 void get_sensor_info()
1306 {
1307 int rc = 0;
1308 int dev_fd = -1;
1309 struct media_device_info mdev_info;
1310 int num_media_devices = 0;
1311 uint8_t num_cameras = 0;
1312
1313 CDBG("%s : E", __func__);
1314 while (1) {
1315 char dev_name[32];
1316 int num_entities;
1317 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
1318 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
1319 if (dev_fd < 0) {
1320 CDBG("Done discovering media devices\n");
1321 break;
1322 }
1323 num_media_devices++;
1324 memset(&mdev_info, 0, sizeof(mdev_info));
1325 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
1326 if (rc < 0) {
1327 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
1328 close(dev_fd);
1329 dev_fd = -1;
1330 num_cameras = 0;
1331 break;
1332 }
1333
1334 if(strncmp(mdev_info.model, MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) {
1335 close(dev_fd);
1336 dev_fd = -1;
1337 continue;
1338 }
1339
1340 num_entities = 1;
1341 while (1) {
1342 struct media_entity_desc entity;
1343 unsigned long temp;
1344 unsigned int mount_angle;
1345 unsigned int facing;
1346
1347 memset(&entity, 0, sizeof(entity));
1348 entity.id = num_entities++;
1349 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
1350 if (rc < 0) {
1351 CDBG("Done enumerating media entities\n");
1352 rc = 0;
1353 break;
1354 }
1355 if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
1356 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) {
1357 temp = entity.flags >> 8;
1358 mount_angle = (temp & 0xFF) * 90;
1359 facing = (temp >> 8);
1360 ALOGD("index = %d flag = %x mount_angle = %d facing = %d\n"
1361 , num_cameras, (unsigned int)temp, (unsigned int)mount_angle,
1362 (unsigned int)facing);
1363 g_cam_ctrl.info[num_cameras].facing = facing;
1364 g_cam_ctrl.info[num_cameras].orientation = mount_angle;
1365 num_cameras++;
1366 continue;
1367 }
1368 }
1369
1370 CDBG("%s: dev_info[id=%d,name='%s']\n",
1371 __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
1372
1373 close(dev_fd);
1374 dev_fd = -1;
1375 }
1376
1377 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
1378 return;
1379 }
1380
1381 /*===========================================================================
1382 * FUNCTION : get_num_of_cameras
1383 *
1384 * DESCRIPTION: get number of cameras
1385 *
1386 * PARAMETERS :
1387 *
1388 * RETURN : number of cameras supported
1389 *==========================================================================*/
get_num_of_cameras()1390 uint8_t get_num_of_cameras()
1391 {
1392 int rc = 0;
1393 int dev_fd = 0;
1394 struct media_device_info mdev_info;
1395 int num_media_devices = 0;
1396 uint8_t num_cameras = 0;
1397 char subdev_name[32];
1398 int32_t sd_fd = 0;
1399 struct sensor_init_cfg_data cfg;
1400 char prop[PROPERTY_VALUE_MAX];
1401
1402 property_get("persist.camera.logs", prop, "0");
1403 gMmCameraIntfLogLevel = atoi(prop);
1404
1405 CDBG("%s : E", __func__);
1406
1407 int decrypt = property_get("vold.decrypt", prop, NULL);
1408 if (0 < decrypt) {
1409 if(strncmp(prop, "trigger_restart_min_framework", decrypt) == 0) {
1410 return 0;
1411 }
1412 }
1413
1414 /* lock the mutex */
1415 pthread_mutex_lock(&g_intf_lock);
1416
1417 while (1) {
1418 int32_t num_entities = 1;
1419 char dev_name[32];
1420
1421 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
1422 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
1423 if (dev_fd < 0) {
1424 CDBG("Done discovering media devices\n");
1425 break;
1426 }
1427 num_media_devices++;
1428 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
1429 if (rc < 0) {
1430 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
1431 close(dev_fd);
1432 dev_fd = -1;
1433 break;
1434 }
1435
1436 if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME,
1437 sizeof(mdev_info.model)) != 0) {
1438 close(dev_fd);
1439 dev_fd = -1;
1440 continue;
1441 }
1442
1443 while (1) {
1444 struct media_entity_desc entity;
1445 memset(&entity, 0, sizeof(entity));
1446 entity.id = num_entities++;
1447 CDBG_ERROR("entity id %d", entity.id);
1448 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
1449 if (rc < 0) {
1450 CDBG_ERROR("Done enumerating media entities");
1451 rc = 0;
1452 break;
1453 }
1454 CDBG_ERROR("entity name %s type %d group id %d",
1455 entity.name, entity.type, entity.group_id);
1456 if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
1457 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) {
1458 snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name);
1459 break;
1460 }
1461 }
1462 close(dev_fd);
1463 dev_fd = -1;
1464 }
1465
1466 /* Open sensor_init subdev */
1467 sd_fd = open(subdev_name, O_RDWR);
1468 if (sd_fd < 0) {
1469 CDBG_ERROR("Open sensor_init subdev failed");
1470 return FALSE;
1471 }
1472
1473 cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE;
1474 cfg.cfg.setting = NULL;
1475 if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
1476 CDBG_ERROR("failed");
1477 }
1478 close(sd_fd);
1479 dev_fd = -1;
1480
1481
1482 num_media_devices = 0;
1483 while (1) {
1484 char dev_name[32];
1485 int num_entities;
1486 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
1487 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
1488 if (dev_fd < 0) {
1489 CDBG("Done discovering media devices: %s\n", strerror(errno));
1490 break;
1491 }
1492 num_media_devices++;
1493 memset(&mdev_info, 0, sizeof(mdev_info));
1494 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
1495 if (rc < 0) {
1496 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
1497 close(dev_fd);
1498 dev_fd = -1;
1499 num_cameras = 0;
1500 break;
1501 }
1502
1503 if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) {
1504 close(dev_fd);
1505 dev_fd = -1;
1506 continue;
1507 }
1508
1509 num_entities = 1;
1510 while (1) {
1511 struct media_entity_desc entity;
1512 memset(&entity, 0, sizeof(entity));
1513 entity.id = num_entities++;
1514 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
1515 if (rc < 0) {
1516 CDBG("Done enumerating media entities\n");
1517 rc = 0;
1518 break;
1519 }
1520 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
1521 strncpy(g_cam_ctrl.video_dev_name[num_cameras],
1522 entity.name, sizeof(entity.name));
1523 break;
1524 }
1525 }
1526
1527 CDBG("%s: dev_info[id=%d,name='%s']\n",
1528 __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
1529
1530 num_cameras++;
1531 close(dev_fd);
1532 dev_fd = -1;
1533 }
1534 g_cam_ctrl.num_cam = num_cameras;
1535
1536 get_sensor_info();
1537 /* unlock the mutex */
1538 pthread_mutex_unlock(&g_intf_lock);
1539 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
1540 return g_cam_ctrl.num_cam;
1541 }
1542
1543 /*===========================================================================
1544 * FUNCTION : mm_camera_intf_process_advanced_capture
1545 *
1546 * DESCRIPTION: Configures channel advanced capture mode
1547 *
1548 * PARAMETERS :
1549 * @camera_handle: camera handle
1550 * @advanced_capture_type : advanced capture type
1551 * @ch_id : channel handle
1552 * @notify_mode : notification mode
1553 *
1554 * RETURN : int32_t type of status
1555 * 0 -- success
1556 * -1 -- failure
1557 *==========================================================================*/
mm_camera_intf_process_advanced_capture(uint32_t camera_handle,mm_camera_advanced_capture_t advanced_capture_type,uint32_t ch_id,int8_t start_flag)1558 static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle,
1559 mm_camera_advanced_capture_t advanced_capture_type,
1560 uint32_t ch_id,
1561 int8_t start_flag)
1562 {
1563 int32_t rc = -1;
1564 mm_camera_obj_t * my_obj = NULL;
1565
1566 CDBG("%s: E camera_handler = %d,ch_id = %d",
1567 __func__, camera_handle, ch_id);
1568 pthread_mutex_lock(&g_intf_lock);
1569 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1570
1571 if(my_obj) {
1572 pthread_mutex_lock(&my_obj->cam_lock);
1573 pthread_mutex_unlock(&g_intf_lock);
1574 rc = mm_camera_channel_advanced_capture(my_obj, advanced_capture_type, ch_id, start_flag);
1575 } else {
1576 pthread_mutex_unlock(&g_intf_lock);
1577 }
1578 CDBG("%s: X ", __func__);
1579 return rc;
1580 }
1581
get_cam_info(int camera_id)1582 struct camera_info *get_cam_info(int camera_id)
1583 {
1584 return &g_cam_ctrl.info[camera_id];
1585 }
1586
1587 /* camera ops v-table */
1588 static mm_camera_ops_t mm_camera_ops = {
1589 .query_capability = mm_camera_intf_query_capability,
1590 .register_event_notify = mm_camera_intf_register_event_notify,
1591 .close_camera = mm_camera_intf_close,
1592 .error_close_camera = mm_camera_intf_error_close,
1593 .set_parms = mm_camera_intf_set_parms,
1594 .get_parms = mm_camera_intf_get_parms,
1595 .do_auto_focus = mm_camera_intf_do_auto_focus,
1596 .cancel_auto_focus = mm_camera_intf_cancel_auto_focus,
1597 .prepare_snapshot = mm_camera_intf_prepare_snapshot,
1598 .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,
1599 .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,
1600 .map_buf = mm_camera_intf_map_buf,
1601 .unmap_buf = mm_camera_intf_unmap_buf,
1602 .add_channel = mm_camera_intf_add_channel,
1603 .delete_channel = mm_camera_intf_del_channel,
1604 .get_bundle_info = mm_camera_intf_get_bundle_info,
1605 .add_stream = mm_camera_intf_add_stream,
1606 .delete_stream = mm_camera_intf_del_stream,
1607 .config_stream = mm_camera_intf_config_stream,
1608 .qbuf = mm_camera_intf_qbuf,
1609 .map_stream_buf = mm_camera_intf_map_stream_buf,
1610 .unmap_stream_buf = mm_camera_intf_unmap_stream_buf,
1611 .set_stream_parms = mm_camera_intf_set_stream_parms,
1612 .get_stream_parms = mm_camera_intf_get_stream_parms,
1613 .start_channel = mm_camera_intf_start_channel,
1614 .stop_channel = mm_camera_intf_stop_channel,
1615 .request_super_buf = mm_camera_intf_request_super_buf,
1616 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
1617 .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,
1618 .configure_notify_mode = mm_camera_intf_configure_notify_mode,
1619 .process_advanced_capture = mm_camera_intf_process_advanced_capture
1620 };
1621
1622 /*===========================================================================
1623 * FUNCTION : camera_open
1624 *
1625 * DESCRIPTION: open a camera by camera index
1626 *
1627 * PARAMETERS :
1628 * @camera_idx : camera index. should within range of 0 to num_of_cameras
1629 *
1630 * RETURN : ptr to a virtual table containing camera handle and operation table.
1631 * NULL if failed.
1632 *==========================================================================*/
camera_open(uint8_t camera_idx)1633 mm_camera_vtbl_t * camera_open(uint8_t camera_idx)
1634 {
1635 int32_t rc = 0;
1636 mm_camera_obj_t* cam_obj = NULL;
1637
1638 CDBG("%s: E camera_idx = %d\n", __func__, camera_idx);
1639 if (camera_idx >= g_cam_ctrl.num_cam) {
1640 CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
1641 return NULL;
1642 }
1643
1644 pthread_mutex_lock(&g_intf_lock);
1645 /* opened already */
1646 if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
1647 /* Add reference */
1648 g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
1649 pthread_mutex_unlock(&g_intf_lock);
1650 CDBG("%s: opened alreadyn", __func__);
1651 return &g_cam_ctrl.cam_obj[camera_idx]->vtbl;
1652 }
1653
1654 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
1655 if(NULL == cam_obj) {
1656 pthread_mutex_unlock(&g_intf_lock);
1657 CDBG("%s: no mem", __func__);
1658 return NULL;
1659 }
1660
1661 /* initialize camera obj */
1662 memset(cam_obj, 0, sizeof(mm_camera_obj_t));
1663 cam_obj->ctrl_fd = -1;
1664 cam_obj->ds_fd = -1;
1665 cam_obj->ref_count++;
1666 cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
1667 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
1668 cam_obj->vtbl.ops = &mm_camera_ops;
1669 pthread_mutex_init(&cam_obj->cam_lock, NULL);
1670
1671 rc = mm_camera_open(cam_obj);
1672 if(rc != 0) {
1673 CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
1674 pthread_mutex_destroy(&cam_obj->cam_lock);
1675 g_cam_ctrl.cam_obj[camera_idx] = NULL;
1676 free(cam_obj);
1677 cam_obj = NULL;
1678 pthread_mutex_unlock(&g_intf_lock);
1679 return NULL;
1680 }else{
1681 CDBG("%s: Open succeded\n", __func__);
1682 g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
1683 pthread_mutex_unlock(&g_intf_lock);
1684 return &cam_obj->vtbl;
1685 }
1686 }
1687