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