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