1 /*
2 Copyright (c) 2011-2012, The Linux Foundation. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above
10 copyright notice, this list of conditions and the following
11 disclaimer in the documentation and/or other materials provided
12 with the distribution.
13 * Neither the name of The Linux Foundation nor the names of its
14 contributors may be used to endorse or promote products derived
15 from this software without specific prior written permission.
16
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
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 <semaphore.h>
39
40 #include "mm_camera_dbg.h"
41 #include "mm_camera_interface.h"
42 #include "mm_camera.h"
43
44 static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
45
46 static mm_camera_ctrl_t g_cam_ctrl = {{{0, {0, 0, 0, 0}, 0, 0}}, 0, {{0}}, {0}};
47
48 static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
49 static uint16_t g_handler_history_count = 0; /* history count for handler */
50
51 /* utility function to generate handler */
mm_camera_util_generate_handler(uint8_t index)52 uint32_t mm_camera_util_generate_handler(uint8_t index)
53 {
54 uint32_t handler = 0;
55 pthread_mutex_lock(&g_handler_lock);
56 g_handler_history_count++;
57 if (0 == g_handler_history_count) {
58 g_handler_history_count++;
59 }
60 handler = g_handler_history_count;
61 handler = (handler<<8) | index;
62 pthread_mutex_unlock(&g_handler_lock);
63 return handler;
64 }
65
mm_camera_util_get_index_by_handler(uint32_t handler)66 uint8_t mm_camera_util_get_index_by_handler(uint32_t handler)
67 {
68 return (handler&0x000000ff);
69 }
70
mm_camera_util_get_dev_name(uint32_t cam_handler)71 const char *mm_camera_util_get_dev_name(uint32_t cam_handler)
72 {
73 char *dev_name = NULL;
74 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler);
75 dev_name = g_cam_ctrl.camera[cam_idx].video_dev_name;
76 return dev_name;
77 }
78
mm_camera_util_get_camera_by_handler(uint32_t cam_handler)79 mm_camera_obj_t* mm_camera_util_get_camera_by_handler(uint32_t cam_handler)
80 {
81 mm_camera_obj_t *cam_obj = NULL;
82 uint8_t cam_idx = mm_camera_util_get_index_by_handler(cam_handler);
83
84 if ((NULL != g_cam_ctrl.cam_obj[cam_idx]) &&
85 (cam_handler == g_cam_ctrl.cam_obj[cam_idx]->my_hdl)) {
86 cam_obj = g_cam_ctrl.cam_obj[cam_idx];
87 }
88 return cam_obj;
89 }
90
mm_camera_intf_sync(uint32_t camera_handler)91 static int32_t mm_camera_intf_sync(uint32_t camera_handler)
92 {
93 int32_t rc = -1;
94 mm_camera_obj_t * my_obj = NULL;
95
96 CDBG("%s E: camera_handler = %d ",__func__,camera_handler);
97
98 pthread_mutex_lock(&g_intf_lock);
99 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
100
101 if(my_obj) {
102 pthread_mutex_lock(&my_obj->cam_lock);
103 pthread_mutex_unlock(&g_intf_lock);
104 rc = mm_camera_sync(my_obj);
105 } else {
106 pthread_mutex_unlock(&g_intf_lock);
107 }
108 CDBG("%s :X rc = %d",__func__,rc);
109 return rc;
110 }
111
112 /* check if the parm is supported */
mm_camera_intf_is_parm_supported(uint32_t camera_handler,mm_camera_parm_type_t parm_type,uint8_t * support_set_parm,uint8_t * support_get_parm)113 static int32_t mm_camera_intf_is_parm_supported(uint32_t camera_handler,
114 mm_camera_parm_type_t parm_type,
115 uint8_t *support_set_parm,
116 uint8_t *support_get_parm)
117 {
118 int32_t rc = -1;
119 mm_camera_obj_t * my_obj = NULL;
120
121 pthread_mutex_lock(&g_intf_lock);
122 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
123 *support_set_parm = 0;
124 *support_get_parm = 0;
125
126 if(my_obj) {
127 pthread_mutex_lock(&my_obj->cam_lock);
128 pthread_mutex_unlock(&g_intf_lock);
129 rc = mm_camera_is_parm_supported(my_obj, parm_type, support_set_parm, support_get_parm);
130 } else {
131 pthread_mutex_unlock(&g_intf_lock);
132 }
133 return rc;
134 }
135
136 /* set a parm�s current value */
mm_camera_intf_set_parm(uint32_t camera_handler,mm_camera_parm_type_t parm_type,void * p_value)137 static int32_t mm_camera_intf_set_parm(uint32_t camera_handler,
138 mm_camera_parm_type_t parm_type,
139 void* p_value)
140 {
141 int32_t rc = -1;
142 mm_camera_obj_t * my_obj = NULL;
143
144 pthread_mutex_lock(&g_intf_lock);
145 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
146
147 if(my_obj) {
148 pthread_mutex_lock(&my_obj->cam_lock);
149 pthread_mutex_unlock(&g_intf_lock);
150 rc = mm_camera_set_parm(my_obj, parm_type, p_value);
151 } else {
152 pthread_mutex_unlock(&g_intf_lock);
153 }
154 return rc;
155 }
156
157 /* get a parm�s current value */
mm_camera_intf_get_parm(uint32_t camera_handler,mm_camera_parm_type_t parm_type,void * p_value)158 static int32_t mm_camera_intf_get_parm(uint32_t camera_handler,
159 mm_camera_parm_type_t parm_type,
160 void* p_value)
161 {
162 int32_t rc = -1;
163 mm_camera_obj_t * my_obj = NULL;
164
165 pthread_mutex_lock(&g_intf_lock);
166 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
167
168 if(my_obj) {
169 pthread_mutex_lock(&my_obj->cam_lock);
170 pthread_mutex_unlock(&g_intf_lock);
171 rc = mm_camera_get_parm(my_obj, parm_type, p_value);
172 } else {
173 pthread_mutex_unlock(&g_intf_lock);
174 }
175 return rc;
176 }
177
mm_camera_intf_close(uint32_t camera_handler)178 static void mm_camera_intf_close(uint32_t camera_handler)
179 {
180 int32_t rc = -1;
181 uint8_t cam_idx = camera_handler & 0x00ff;
182 mm_camera_obj_t * my_obj = NULL;
183
184 CDBG("%s E: camera_handler = %d ",__func__,camera_handler);
185 pthread_mutex_lock(&g_intf_lock);
186 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
187
188 if (my_obj){
189 my_obj->ref_count--;
190
191 if(my_obj->ref_count > 0) {
192 /* still have reference to obj, return here */
193 CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
194 pthread_mutex_unlock(&g_intf_lock);
195 return;
196 }
197
198 /* need close camera here as no other reference
199 * first empty g_cam_ctrl's referent to cam_obj */
200 g_cam_ctrl.cam_obj[cam_idx] = NULL;
201
202 pthread_mutex_lock(&my_obj->cam_lock);
203 pthread_mutex_unlock(&g_intf_lock);
204
205 mm_camera_close(my_obj);
206
207 pthread_mutex_destroy(&my_obj->cam_lock);
208 free(my_obj);
209
210 } else {
211 pthread_mutex_unlock(&g_intf_lock);
212 }
213 }
214
mm_camera_intf_add_channel(uint32_t camera_handler)215 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handler)
216 {
217 uint32_t ch_id = 0;
218 mm_camera_obj_t * my_obj = NULL;
219
220 CDBG("%s :E camera_handler = %d",__func__,camera_handler);
221 pthread_mutex_lock(&g_intf_lock);
222 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
223
224 if(my_obj) {
225 pthread_mutex_lock(&my_obj->cam_lock);
226 pthread_mutex_unlock(&g_intf_lock);
227 ch_id = mm_camera_add_channel(my_obj);
228 } else {
229 pthread_mutex_unlock(&g_intf_lock);
230 }
231 CDBG("%s :X ch_id = %d",__func__,ch_id);
232 return ch_id;
233 }
234
mm_camera_intf_del_channel(uint32_t camera_handler,uint32_t ch_id)235 static void mm_camera_intf_del_channel(uint32_t camera_handler, uint32_t ch_id)
236 {
237 mm_camera_obj_t * my_obj = NULL;
238
239 CDBG("%s :E ch_id = %d",__func__,ch_id);
240 pthread_mutex_lock(&g_intf_lock);
241 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
242
243 if(my_obj) {
244 pthread_mutex_lock(&my_obj->cam_lock);
245 pthread_mutex_unlock(&g_intf_lock);
246 mm_camera_del_channel(my_obj, ch_id);
247 } else {
248 pthread_mutex_unlock(&g_intf_lock);
249 }
250 CDBG("%s :X",__func__);
251 }
252
mm_camera_intf_is_event_supported(uint32_t camera_handler,mm_camera_event_type_t evt_type)253 static uint8_t mm_camera_intf_is_event_supported(uint32_t camera_handler,
254 mm_camera_event_type_t evt_type)
255 {
256 switch(evt_type) {
257 case MM_CAMERA_EVT_TYPE_CH:
258 case MM_CAMERA_EVT_TYPE_CTRL:
259 case MM_CAMERA_EVT_TYPE_STATS:
260 case MM_CAMERA_EVT_TYPE_INFO:
261 return 1;
262 default:
263 return 0;
264 }
265 return 0;
266 }
267
mm_camera_intf_register_event_notify(uint32_t camera_handler,mm_camera_event_notify_t evt_cb,void * user_data,mm_camera_event_type_t evt_type)268 static int32_t mm_camera_intf_register_event_notify(
269 uint32_t camera_handler,
270 mm_camera_event_notify_t evt_cb,
271 void * user_data,
272 mm_camera_event_type_t evt_type)
273 {
274 int32_t rc = -1;
275 mm_camera_obj_t * my_obj = NULL;
276
277 CDBG("%s :E evt_type = %d",__func__,evt_type);
278 pthread_mutex_lock(&g_intf_lock);
279 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
280
281 if(my_obj) {
282 pthread_mutex_lock(&my_obj->cam_lock);
283 pthread_mutex_unlock(&g_intf_lock);
284 rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data, evt_type);
285 } else {
286 pthread_mutex_unlock(&g_intf_lock);
287 }
288 CDBG("%s :E rc = %d",__func__,rc);
289 return rc;
290 }
291
mm_camera_intf_query_2nd_sensor_info(uint32_t camera_handler)292 static mm_camera_2nd_sensor_t * mm_camera_intf_query_2nd_sensor_info(uint32_t camera_handler)
293 {
294 mm_camera_2nd_sensor_t *sensor_info = NULL;
295 mm_camera_obj_t * my_obj = NULL;
296
297 CDBG("%s :E camera_handler = %d",__func__,camera_handler);
298 pthread_mutex_lock(&g_intf_lock);
299 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
300
301 if(my_obj) {
302 pthread_mutex_lock(&my_obj->cam_lock);
303 pthread_mutex_unlock(&g_intf_lock);
304 sensor_info = mm_camera_query_2nd_sensor_info(my_obj);
305 } else {
306 pthread_mutex_unlock(&g_intf_lock);
307 }
308 CDBG("%s :X",__func__);
309 return sensor_info;
310 }
311
mm_camera_intf_qbuf(uint32_t camera_handler,uint32_t ch_id,mm_camera_buf_def_t * buf)312 static int32_t mm_camera_intf_qbuf(uint32_t camera_handler,
313 uint32_t ch_id,
314 mm_camera_buf_def_t *buf)
315 {
316 int32_t rc = -1;
317 mm_camera_obj_t * my_obj = NULL;
318
319 pthread_mutex_lock(&g_intf_lock);
320 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
321
322 if(my_obj) {
323 pthread_mutex_lock(&my_obj->cam_lock);
324 pthread_mutex_unlock(&g_intf_lock);
325 rc = mm_camera_qbuf(my_obj, ch_id, buf);
326 } else {
327 pthread_mutex_unlock(&g_intf_lock);
328 }
329 CDBG("%s :X evt_type = %d",__func__,rc);
330 return rc;
331 }
332
mm_camera_intf_add_stream(uint32_t camera_handler,uint32_t ch_id,mm_camera_buf_notify_t buf_cb,void * user_data,uint32_t ext_image_mode,uint32_t sensor_idx)333 static uint32_t mm_camera_intf_add_stream(
334 uint32_t camera_handler,
335 uint32_t ch_id,
336 mm_camera_buf_notify_t buf_cb, void *user_data,
337 uint32_t ext_image_mode, uint32_t sensor_idx)
338 {
339 uint32_t stream_id = 0;
340 mm_camera_obj_t * my_obj = NULL;
341
342 CDBG("%s : E handle = %d ch_id = %d",__func__,camera_handler,
343 ch_id);
344
345 pthread_mutex_lock(&g_intf_lock);
346 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
347
348 if(my_obj) {
349 pthread_mutex_lock(&my_obj->cam_lock);
350 pthread_mutex_unlock(&g_intf_lock);
351 stream_id = mm_camera_add_stream(my_obj, ch_id, buf_cb,
352 user_data, ext_image_mode, sensor_idx);
353 } else {
354 pthread_mutex_unlock(&g_intf_lock);
355 }
356 CDBG("%s :X stream_id = %d",__func__,stream_id);
357 return stream_id;
358 }
359
mm_camera_intf_del_stream(uint32_t camera_handler,uint32_t ch_id,uint32_t stream_id)360 static int32_t mm_camera_intf_del_stream(
361 uint32_t camera_handler,
362 uint32_t ch_id,
363 uint32_t stream_id)
364 {
365 int32_t rc = -1;
366 mm_camera_obj_t * my_obj = NULL;
367
368 CDBG("%s : E handle = %d ch_id = %d stream_id = %d",__func__,camera_handler,
369 ch_id,stream_id);
370
371 pthread_mutex_lock(&g_intf_lock);
372 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
373
374 if(my_obj) {
375 pthread_mutex_lock(&my_obj->cam_lock);
376 pthread_mutex_unlock(&g_intf_lock);
377 rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
378 } else {
379 pthread_mutex_unlock(&g_intf_lock);
380 }
381 CDBG("%s :X rc = %d",__func__,rc);
382 return rc;
383 }
384
mm_camera_intf_config_stream(uint32_t camera_handler,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)385 static int32_t mm_camera_intf_config_stream(
386 uint32_t camera_handler,
387 uint32_t ch_id,
388 uint32_t stream_id,
389 mm_camera_stream_config_t *config)
390 {
391 int32_t rc = -1;
392 mm_camera_obj_t * my_obj = NULL;
393
394 CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",__func__,
395 camera_handler,ch_id,stream_id);
396
397 pthread_mutex_lock(&g_intf_lock);
398 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
399
400 CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
401
402 if(my_obj) {
403 pthread_mutex_lock(&my_obj->cam_lock);
404 pthread_mutex_unlock(&g_intf_lock);
405 rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
406 } else {
407 pthread_mutex_unlock(&g_intf_lock);
408 }
409 CDBG("%s :X rc = %d",__func__,rc);
410 return rc;
411 }
412
mm_camera_intf_bundle_streams(uint32_t camera_handler,uint32_t ch_id,mm_camera_buf_notify_t super_frame_notify_cb,void * user_data,mm_camera_bundle_attr_t * attr,uint8_t num_streams,uint32_t * stream_ids)413 static int32_t mm_camera_intf_bundle_streams(
414 uint32_t camera_handler,
415 uint32_t ch_id,
416 mm_camera_buf_notify_t super_frame_notify_cb,
417 void *user_data,
418 mm_camera_bundle_attr_t *attr,
419 uint8_t num_streams,
420 uint32_t *stream_ids)
421 {
422 int32_t rc = -1;
423 mm_camera_obj_t * my_obj = NULL;
424
425 CDBG("%s :E handle = %d, ch_id = %d",__func__,
426 camera_handler,ch_id);
427
428 if (MM_CAMEAR_MAX_STRAEM_BUNDLE < num_streams) {
429 CDBG_ERROR("%s: number of streams (%d) exceeds max (%d)",
430 __func__, num_streams, MM_CAMEAR_MAX_STRAEM_BUNDLE);
431 return rc;
432 }
433
434 pthread_mutex_lock(&g_intf_lock);
435 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
436
437 if(my_obj) {
438 pthread_mutex_lock(&my_obj->cam_lock);
439 pthread_mutex_unlock(&g_intf_lock);
440 rc = mm_camera_bundle_streams(my_obj, ch_id,
441 super_frame_notify_cb,
442 user_data, attr,
443 num_streams, stream_ids);
444 } else {
445 pthread_mutex_unlock(&g_intf_lock);
446 }
447 CDBG("%s :X rc = %d",__func__,rc);
448 return rc;
449 }
450
mm_camera_intf_destroy_bundle(uint32_t camera_handler,uint32_t ch_id)451 static int32_t mm_camera_intf_destroy_bundle(uint32_t camera_handler,
452 uint32_t ch_id)
453 {
454 int32_t rc = -1;
455 mm_camera_obj_t * my_obj = NULL;
456
457 CDBG("%s :E handle = %d, ch_id = %d",__func__,
458 camera_handler,ch_id);
459 pthread_mutex_lock(&g_intf_lock);
460 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
461
462 if(my_obj) {
463 pthread_mutex_lock(&my_obj->cam_lock);
464 pthread_mutex_unlock(&g_intf_lock);
465 rc = mm_camera_destroy_bundle(my_obj, ch_id);
466 } else {
467 pthread_mutex_unlock(&g_intf_lock);
468 }
469 CDBG("%s :X rc = %d",__func__,rc);
470 return rc;
471 }
472
mm_camera_intf_start_streams(uint32_t camera_handler,uint32_t ch_id,uint8_t num_streams,uint32_t * stream_ids)473 static int32_t mm_camera_intf_start_streams(
474 uint32_t camera_handler,
475 uint32_t ch_id,
476 uint8_t num_streams,
477 uint32_t *stream_ids)
478 {
479 int32_t rc = -1;
480 mm_camera_obj_t * my_obj = NULL;
481
482 CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
483 __func__,camera_handler,ch_id,num_streams);
484 if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
485 CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
486 __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
487 return rc;
488 }
489
490 pthread_mutex_lock(&g_intf_lock);
491 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
492
493 if(my_obj) {
494 pthread_mutex_lock(&my_obj->cam_lock);
495 pthread_mutex_unlock(&g_intf_lock);
496 rc = mm_camera_start_streams(my_obj, ch_id, num_streams, stream_ids);
497 } else {
498 pthread_mutex_unlock(&g_intf_lock);
499 }
500 CDBG("%s :X rc = %d",__func__,rc);
501 return rc;
502 }
503
mm_camera_intf_stop_streams(uint32_t camera_handler,uint32_t ch_id,uint8_t num_streams,uint32_t * stream_ids)504 static int32_t mm_camera_intf_stop_streams(
505 uint32_t camera_handler,
506 uint32_t ch_id,
507 uint8_t num_streams,
508 uint32_t *stream_ids)
509 {
510 int32_t rc = -1;
511 mm_camera_obj_t * my_obj = NULL;
512
513 CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
514 __func__,camera_handler,ch_id,num_streams);
515
516 if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
517 CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
518 __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
519 return rc;
520 }
521
522 pthread_mutex_lock(&g_intf_lock);
523 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
524
525 if(my_obj) {
526 pthread_mutex_lock(&my_obj->cam_lock);
527 pthread_mutex_unlock(&g_intf_lock);
528 rc = mm_camera_stop_streams(my_obj, ch_id,
529 num_streams, stream_ids);
530 } else {
531 pthread_mutex_unlock(&g_intf_lock);
532 }
533 CDBG("%s :X rc = %d",__func__,rc);
534 return rc;
535 }
536
mm_camera_intf_async_teardown_streams(uint32_t camera_handler,uint32_t ch_id,uint8_t num_streams,uint32_t * stream_ids)537 static int32_t mm_camera_intf_async_teardown_streams(
538 uint32_t camera_handler,
539 uint32_t ch_id,
540 uint8_t num_streams,
541 uint32_t *stream_ids)
542 {
543 int32_t rc = -1;
544 mm_camera_obj_t * my_obj = NULL;
545
546 CDBG("%s :E camera_handler = %d,ch_id = %d, num_streams = %d",
547 __func__,camera_handler,ch_id,num_streams);
548
549 if (MM_CAMEAR_STRAEM_NUM_MAX < num_streams) {
550 CDBG_ERROR("%s: num of streams (%d) exceeds MAX (%d)",
551 __func__, num_streams, MM_CAMEAR_STRAEM_NUM_MAX);
552 return rc;
553 }
554
555 pthread_mutex_lock(&g_intf_lock);
556 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
557
558 if(my_obj) {
559 pthread_mutex_lock(&my_obj->cam_lock);
560 pthread_mutex_unlock(&g_intf_lock);
561 rc = mm_camera_async_teardown_streams(my_obj, ch_id,
562 num_streams, stream_ids);
563 } else {
564 pthread_mutex_unlock(&g_intf_lock);
565 }
566 CDBG("%s :X rc = %d",__func__,rc);
567 return rc;
568 }
569
mm_camera_intf_request_super_buf(uint32_t camera_handler,uint32_t ch_id)570 static int32_t mm_camera_intf_request_super_buf(
571 uint32_t camera_handler,
572 uint32_t ch_id)
573 {
574 int32_t rc = -1;
575 CDBG("%s :E camera_handler = %d,ch_id = %d",
576 __func__,camera_handler,ch_id);
577 mm_camera_obj_t * my_obj = NULL;
578
579 pthread_mutex_lock(&g_intf_lock);
580 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
581
582 if(my_obj) {
583 pthread_mutex_lock(&my_obj->cam_lock);
584 pthread_mutex_unlock(&g_intf_lock);
585 rc = mm_camera_request_super_buf(my_obj, ch_id);
586 } else {
587 pthread_mutex_unlock(&g_intf_lock);
588 }
589 CDBG("%s :X rc = %d",__func__,rc);
590 return rc;
591 }
592
mm_camera_intf_cancel_super_buf_request(uint32_t camera_handler,uint32_t ch_id)593 static int32_t mm_camera_intf_cancel_super_buf_request(
594 uint32_t camera_handler,
595 uint32_t ch_id)
596 {
597 int32_t rc = -1;
598 mm_camera_obj_t * my_obj = NULL;
599
600 CDBG("%s :E camera_handler = %d,ch_id = %d",
601 __func__,camera_handler,ch_id);
602 pthread_mutex_lock(&g_intf_lock);
603 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
604
605 if(my_obj) {
606 pthread_mutex_lock(&my_obj->cam_lock);
607 pthread_mutex_unlock(&g_intf_lock);
608 rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
609 } else {
610 pthread_mutex_unlock(&g_intf_lock);
611 }
612 CDBG("%s :X rc = %d",__func__,rc);
613 return rc;
614 }
615
mm_camera_intf_start_focus(uint32_t camera_handler,uint32_t ch_id,uint32_t sensor_idx,uint32_t focus_mode)616 static int32_t mm_camera_intf_start_focus(
617 uint32_t camera_handler,
618 uint32_t ch_id,
619 uint32_t sensor_idx,
620 uint32_t focus_mode)
621 {
622 int32_t rc = -1;
623 mm_camera_obj_t * my_obj = NULL;
624
625 CDBG("%s :E camera_handler = %d,ch_id = %d, focus_mode = %d",
626 __func__,camera_handler,ch_id,focus_mode);
627 pthread_mutex_lock(&g_intf_lock);
628 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
629
630 if(my_obj) {
631 pthread_mutex_lock(&my_obj->cam_lock);
632 pthread_mutex_unlock(&g_intf_lock);
633 rc = mm_camera_start_focus(my_obj, ch_id, sensor_idx, focus_mode);
634 } else {
635 pthread_mutex_unlock(&g_intf_lock);
636 }
637 CDBG("%s :X rc = %d",__func__,rc);
638 return rc;
639 }
640
mm_camera_intf_abort_focus(uint32_t camera_handler,uint32_t ch_id,uint32_t sensor_idx)641 static int32_t mm_camera_intf_abort_focus(
642 uint32_t camera_handler,
643 uint32_t ch_id,
644 uint32_t sensor_idx)
645 {
646 int32_t rc = -1;
647 mm_camera_obj_t * my_obj = NULL;
648
649 pthread_mutex_lock(&g_intf_lock);
650 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
651
652 if(my_obj) {
653 pthread_mutex_lock(&my_obj->cam_lock);
654 pthread_mutex_unlock(&g_intf_lock);
655 rc = mm_camera_abort_focus(my_obj, ch_id, sensor_idx);
656 } else {
657 pthread_mutex_unlock(&g_intf_lock);
658 }
659 CDBG("%s :X rc = %d",__func__,rc);
660 return rc;
661 }
662
mm_camera_intf_prepare_snapshot(uint32_t camera_handler,uint32_t ch_id,uint32_t sensor_idx)663 static int32_t mm_camera_intf_prepare_snapshot(
664 uint32_t camera_handler,
665 uint32_t ch_id,
666 uint32_t sensor_idx)
667 {
668 int32_t rc = -1;
669 mm_camera_obj_t * my_obj = NULL;
670
671 pthread_mutex_lock(&g_intf_lock);
672 my_obj = mm_camera_util_get_camera_by_handler(camera_handler);
673
674 if(my_obj) {
675 pthread_mutex_lock(&my_obj->cam_lock);
676 pthread_mutex_unlock(&g_intf_lock);
677 rc = mm_camera_prepare_snapshot(my_obj, ch_id, sensor_idx);
678 } else {
679 pthread_mutex_unlock(&g_intf_lock);
680 }
681 CDBG("%s :X rc = %d",__func__,rc);
682 return rc;
683 }
684
mm_camera_intf_set_stream_parm(uint32_t camera_handle,uint32_t ch_id,uint32_t s_id,mm_camera_stream_parm_t parm_type,void * p_value)685 static int32_t mm_camera_intf_set_stream_parm(
686 uint32_t camera_handle,
687 uint32_t ch_id,
688 uint32_t s_id,
689 mm_camera_stream_parm_t parm_type,
690 void* p_value)
691 {
692 int32_t rc = -1;
693 mm_camera_obj_t * my_obj = NULL;
694
695 pthread_mutex_lock(&g_intf_lock);
696 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
697
698 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__,
699 camera_handle,ch_id,s_id,parm_type);
700
701 if(my_obj) {
702 pthread_mutex_lock(&my_obj->cam_lock);
703 pthread_mutex_unlock(&g_intf_lock);
704 rc = mm_camera_set_stream_parm(my_obj,ch_id,s_id,
705 parm_type,
706 p_value);
707 }else{
708 pthread_mutex_unlock(&g_intf_lock);
709 }
710 CDBG("%s :X rc = %d",__func__,rc);
711 return rc;
712 }
713
mm_camera_intf_get_stream_parm(uint32_t camera_handle,uint32_t ch_id,uint32_t s_id,mm_camera_stream_parm_t parm_type,void * p_value)714 static int32_t mm_camera_intf_get_stream_parm(
715 uint32_t camera_handle,
716 uint32_t ch_id,
717 uint32_t s_id,
718 mm_camera_stream_parm_t parm_type,
719 void* p_value)
720 {
721 int32_t rc = -1;
722 mm_camera_obj_t * my_obj = NULL;
723
724 pthread_mutex_lock(&g_intf_lock);
725 my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
726
727 CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d,parm_type = %d",__func__,
728 camera_handle,ch_id,s_id,parm_type);
729
730 if(my_obj) {
731 pthread_mutex_lock(&my_obj->cam_lock);
732 pthread_mutex_unlock(&g_intf_lock);
733 rc = mm_camera_get_stream_parm(my_obj,ch_id,s_id,
734 parm_type,
735 p_value);
736 }else{
737 pthread_mutex_unlock(&g_intf_lock);
738 }
739
740 CDBG("%s :X rc = %d",__func__,rc);
741 return rc;
742 }
camera_query(uint8_t * num_cameras)743 mm_camera_info_t * camera_query(uint8_t *num_cameras)
744 {
745 int i = 0, rc = 0;
746 int dev_fd = 0;
747 struct media_device_info mdev_info;
748 int num_media_devices = 0;
749 if (!num_cameras) {
750 CDBG_ERROR("%s: num_cameras is NULL\n", __func__);
751 return NULL;
752 }
753
754 CDBG("%s : E",__func__);
755 /* lock the mutex */
756 pthread_mutex_lock(&g_intf_lock);
757 *num_cameras = 0;
758 while (1) {
759 char dev_name[32];
760 snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
761 dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
762 if (dev_fd < 0) {
763 CDBG("Done discovering media devices\n");
764 break;
765 }
766 num_media_devices++;
767 rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
768 if (rc < 0) {
769 CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
770 close(dev_fd);
771 break;
772 }
773
774 if(strncmp(mdev_info.model, QCAMERA_NAME, sizeof(mdev_info.model) != 0)) {
775 close(dev_fd);
776 continue;
777 }
778
779 char * mdev_cfg;
780 int cam_type = 0, mount_angle = 0, info_index = 0;
781 mdev_cfg = strtok(mdev_info.serial, "-");
782 while(mdev_cfg != NULL) {
783 if(info_index == 0) {
784 if(strcmp(mdev_cfg, QCAMERA_NAME))
785 break;
786 } else if(info_index == 1) {
787 mount_angle = atoi(mdev_cfg);
788 } else if(info_index == 2) {
789 cam_type = atoi(mdev_cfg);
790 }
791 mdev_cfg = strtok(NULL, "-");
792 info_index++;
793 }
794
795 if(info_index == 0) {
796 close(dev_fd);
797 continue;
798 }
799
800 int num_entities = 1;
801 while (1) {
802 struct media_entity_desc entity;
803 memset(&entity, 0, sizeof(entity));
804 entity.id = num_entities++;
805 rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
806 if (rc < 0) {
807 CDBG("Done enumerating media entities\n");
808 rc = 0;
809 break;
810 }
811 if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
812 strncpy(g_cam_ctrl.video_dev_name[*num_cameras],
813 entity.name, sizeof(entity.name));
814 g_cam_ctrl.camera[*num_cameras].video_dev_name =
815 &g_cam_ctrl.video_dev_name[*num_cameras][0];
816 break;
817 }
818 }
819
820 //g_cam_ctrl.camera[*num_cameras].camera_info.camera_id = *num_cameras;
821 g_cam_ctrl.camera[*num_cameras].camera_id = *num_cameras;
822
823 g_cam_ctrl.camera[*num_cameras].
824 camera_info.modes_supported = CAMERA_MODE_2D;
825
826 if(cam_type > 1) {
827 g_cam_ctrl.camera[*num_cameras].
828 camera_info.modes_supported |= CAMERA_MODE_3D;
829 }
830
831 g_cam_ctrl.camera[*num_cameras].camera_info.position =
832 (cam_type == 1) ? FRONT_CAMERA : BACK_CAMERA;
833
834 g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle =
835 mount_angle;
836
837 g_cam_ctrl.camera[*num_cameras].main_sensor_type = 0;
838
839 CDBG("%s: dev_info[id=%d,name='%s',pos=%d,modes=0x%x,sensor=%d mount_angle = %d]\n",
840 __func__, *num_cameras,
841 g_cam_ctrl.camera[*num_cameras].video_dev_name,
842 g_cam_ctrl.camera[*num_cameras].camera_info.position,
843 g_cam_ctrl.camera[*num_cameras].camera_info.modes_supported,
844 g_cam_ctrl.camera[*num_cameras].main_sensor_type,
845 g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle);
846
847 *num_cameras += 1;
848 if (dev_fd > 0) {
849 close(dev_fd);
850 }
851 }
852 *num_cameras = *num_cameras;
853 g_cam_ctrl.num_cam = *num_cameras;
854
855 /* unlock the mutex */
856 pthread_mutex_unlock(&g_intf_lock);
857 CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
858 if(rc == 0)
859 return &g_cam_ctrl.camera[0];
860 else
861 return NULL;
862 }
863
864 /* camera ops v-table */
865 static mm_camera_ops_t mm_camera_ops = {
866 .sync = mm_camera_intf_sync,
867 .is_event_supported = mm_camera_intf_is_event_supported,
868 .register_event_notify = mm_camera_intf_register_event_notify,
869 .qbuf = mm_camera_intf_qbuf,
870 .camera_close = mm_camera_intf_close,
871 .query_2nd_sensor_info = mm_camera_intf_query_2nd_sensor_info,
872 .is_parm_supported = mm_camera_intf_is_parm_supported,
873 .set_parm = mm_camera_intf_set_parm,
874 .get_parm = mm_camera_intf_get_parm,
875 .ch_acquire = mm_camera_intf_add_channel,
876 .ch_release = mm_camera_intf_del_channel,
877 .add_stream = mm_camera_intf_add_stream,
878 .del_stream = mm_camera_intf_del_stream,
879 .config_stream = mm_camera_intf_config_stream,
880 .init_stream_bundle = mm_camera_intf_bundle_streams,
881 .destroy_stream_bundle = mm_camera_intf_destroy_bundle,
882 .start_streams = mm_camera_intf_start_streams,
883 .stop_streams = mm_camera_intf_stop_streams,
884 .async_teardown_streams = mm_camera_intf_async_teardown_streams,
885 .request_super_buf = mm_camera_intf_request_super_buf,
886 .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
887 .start_focus = mm_camera_intf_start_focus,
888 .abort_focus = mm_camera_intf_abort_focus,
889 .prepare_snapshot = mm_camera_intf_prepare_snapshot,
890 .set_stream_parm = mm_camera_intf_set_stream_parm,
891 .get_stream_parm = mm_camera_intf_get_stream_parm
892 };
893
894 /* open camera. */
camera_open(uint8_t camera_idx,mm_camear_mem_vtbl_t * mem_vtbl)895 mm_camera_vtbl_t * camera_open(uint8_t camera_idx,
896 mm_camear_mem_vtbl_t *mem_vtbl)
897 {
898 int32_t rc = 0;
899 mm_camera_obj_t* cam_obj = NULL;
900
901 CDBG("%s: E camera_idx = %d\n", __func__,camera_idx);
902 if (MSM_MAX_CAMERA_SENSORS <= camera_idx) {
903 CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
904 return NULL;
905 }
906
907 pthread_mutex_lock(&g_intf_lock);
908 /* opened already */
909 if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
910 /* Add reference */
911 g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
912 pthread_mutex_unlock(&g_intf_lock);
913 CDBG("%s: opened alreadyn", __func__);
914 return &cam_obj->vtbl;
915 }
916
917 cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
918 if(NULL == cam_obj) {
919 pthread_mutex_unlock(&g_intf_lock);
920 CDBG("%s: no mem", __func__);
921 return NULL;
922 }
923
924 /* initialize camera obj */
925 memset(cam_obj, 0, sizeof(mm_camera_obj_t));
926 cam_obj->ctrl_fd = -1;
927 cam_obj->ds_fd = -1;
928 cam_obj->ref_count++;
929 cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
930 cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
931 cam_obj->vtbl.camera_info = &g_cam_ctrl.camera[camera_idx];
932 cam_obj->vtbl.ops = &mm_camera_ops;
933 cam_obj->mem_vtbl = mem_vtbl; /* save mem_vtbl */
934 pthread_mutex_init(&cam_obj->cam_lock, NULL);
935
936 rc = mm_camera_open(cam_obj);
937 if(rc != 0) {
938 CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
939 pthread_mutex_destroy(&cam_obj->cam_lock);
940 g_cam_ctrl.cam_obj[camera_idx] = NULL;
941 free(cam_obj);
942 cam_obj = NULL;
943 pthread_mutex_unlock(&g_intf_lock);
944 return NULL;
945 }else{
946 CDBG("%s: Open succeded\n", __func__);
947 g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
948 pthread_mutex_unlock(&g_intf_lock);
949 return &cam_obj->vtbl;
950 }
951 }
952