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