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