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_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     mm_camera_obj_t * my_obj = NULL;
406 
407     CDBG("%s E: camera_handler = %d ", __func__, camera_handle);
408 
409     pthread_mutex_lock(&g_intf_lock);
410     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
411 
412     if (my_obj){
413         /*do not decrement the ref_count yet since that will happen during close*/
414         if((my_obj->ref_count - 1) > 0) {
415             /* still have reference to obj, return here */
416             CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
417             pthread_mutex_unlock(&g_intf_lock);
418             rc = 0;
419         } else {
420             /* need close camera here as no other reference*/
421             pthread_mutex_lock(&my_obj->cam_lock);
422             pthread_mutex_unlock(&g_intf_lock);
423 
424             rc = mm_camera_close_fd(my_obj);
425         }
426     } else {
427         pthread_mutex_unlock(&g_intf_lock);
428     }
429 
430     return rc;
431 }
432 
433 /*===========================================================================
434  * FUNCTION   : mm_camera_intf_add_channel
435  *
436  * DESCRIPTION: add a channel
437  *
438  * PARAMETERS :
439  *   @camera_handle: camera handle
440  *   @attr         : bundle attribute of the channel if needed
441  *   @channel_cb   : callback function for bundle data notify
442  *   @userdata     : user data ptr
443  *
444  * RETURN     : uint32_t type of channel handle
445  *              0  -- invalid channel handle, meaning the op failed
446  *              >0 -- successfully added a channel with a valid handle
447  * NOTE       : if no bundle data notify is needed, meaning each stream in the
448  *              channel will have its own stream data notify callback, then
449  *              attr, channel_cb, and userdata can be NULL. In this case,
450  *              no matching logic will be performed in channel for the bundling.
451  *==========================================================================*/
mm_camera_intf_add_channel(uint32_t camera_handle,mm_camera_channel_attr_t * attr,mm_camera_buf_notify_t channel_cb,void * userdata)452 static uint32_t mm_camera_intf_add_channel(uint32_t camera_handle,
453                                            mm_camera_channel_attr_t *attr,
454                                            mm_camera_buf_notify_t channel_cb,
455                                            void *userdata)
456 {
457     uint32_t ch_id = 0;
458     mm_camera_obj_t * my_obj = NULL;
459 
460     CDBG("%s :E camera_handler = %d", __func__, camera_handle);
461     pthread_mutex_lock(&g_intf_lock);
462     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
463 
464     if(my_obj) {
465         pthread_mutex_lock(&my_obj->cam_lock);
466         pthread_mutex_unlock(&g_intf_lock);
467         ch_id = mm_camera_add_channel(my_obj, attr, channel_cb, userdata);
468     } else {
469         pthread_mutex_unlock(&g_intf_lock);
470     }
471     CDBG("%s :X ch_id = %d", __func__, ch_id);
472     return ch_id;
473 }
474 
475 /*===========================================================================
476  * FUNCTION   : mm_camera_intf_del_channel
477  *
478  * DESCRIPTION: delete a channel by its handle
479  *
480  * PARAMETERS :
481  *   @camera_handle: camera handle
482  *   @ch_id        : channel handle
483  *
484  * RETURN     : int32_t type of status
485  *              0  -- success
486  *              -1 -- failure
487  * NOTE       : all streams in the channel should be stopped already before
488  *              this channel can be deleted.
489  *==========================================================================*/
mm_camera_intf_del_channel(uint32_t camera_handle,uint32_t ch_id)490 static int32_t mm_camera_intf_del_channel(uint32_t camera_handle,
491                                           uint32_t ch_id)
492 {
493     int32_t rc = -1;
494     mm_camera_obj_t * my_obj = NULL;
495 
496     CDBG("%s :E ch_id = %d", __func__, ch_id);
497     pthread_mutex_lock(&g_intf_lock);
498     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
499 
500     if(my_obj) {
501         pthread_mutex_lock(&my_obj->cam_lock);
502         pthread_mutex_unlock(&g_intf_lock);
503         rc = mm_camera_del_channel(my_obj, ch_id);
504     } else {
505         pthread_mutex_unlock(&g_intf_lock);
506     }
507     CDBG("%s :X", __func__);
508     return rc;
509 }
510 
511 /*===========================================================================
512  * FUNCTION   : mm_camera_intf_get_bundle_info
513  *
514  * DESCRIPTION: query bundle info of the channel
515  *
516  * PARAMETERS :
517  *   @camera_handle: camera handle
518  *   @ch_id        : channel handle
519  *   @bundle_info  : bundle info to be filled in
520  *
521  * RETURN     : int32_t type of status
522  *              0  -- success
523  *              -1 -- failure
524  * NOTE       : all streams in the channel should be stopped already before
525  *              this channel can be deleted.
526  *==========================================================================*/
mm_camera_intf_get_bundle_info(uint32_t camera_handle,uint32_t ch_id,cam_bundle_config_t * bundle_info)527 static int32_t mm_camera_intf_get_bundle_info(uint32_t camera_handle,
528                                               uint32_t ch_id,
529                                               cam_bundle_config_t *bundle_info)
530 {
531     int32_t rc = -1;
532     mm_camera_obj_t * my_obj = NULL;
533 
534     CDBG("%s :E ch_id = %d", __func__, ch_id);
535     pthread_mutex_lock(&g_intf_lock);
536     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
537 
538     if(my_obj) {
539         pthread_mutex_lock(&my_obj->cam_lock);
540         pthread_mutex_unlock(&g_intf_lock);
541         rc = mm_camera_get_bundle_info(my_obj, ch_id, bundle_info);
542     } else {
543         pthread_mutex_unlock(&g_intf_lock);
544     }
545     CDBG("%s :X", __func__);
546     return rc;
547 }
548 
549 /*===========================================================================
550  * FUNCTION   : mm_camera_intf_register_event_notify
551  *
552  * DESCRIPTION: register for event notify
553  *
554  * PARAMETERS :
555  *   @camera_handle: camera handle
556  *   @evt_cb       : callback for event notify
557  *   @user_data    : user data ptr
558  *
559  * RETURN     : int32_t type of status
560  *              0  -- success
561  *              -1 -- failure
562  *==========================================================================*/
mm_camera_intf_register_event_notify(uint32_t camera_handle,mm_camera_event_notify_t evt_cb,void * user_data)563 static int32_t mm_camera_intf_register_event_notify(uint32_t camera_handle,
564                                                     mm_camera_event_notify_t evt_cb,
565                                                     void * user_data)
566 {
567     int32_t rc = -1;
568     mm_camera_obj_t * my_obj = NULL;
569 
570     CDBG("%s :E ", __func__);
571     pthread_mutex_lock(&g_intf_lock);
572     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
573 
574     if(my_obj) {
575         pthread_mutex_lock(&my_obj->cam_lock);
576         pthread_mutex_unlock(&g_intf_lock);
577         rc = mm_camera_register_event_notify(my_obj, evt_cb, user_data);
578     } else {
579         pthread_mutex_unlock(&g_intf_lock);
580     }
581     CDBG("%s :E rc = %d", __func__, rc);
582     return rc;
583 }
584 
585 /*===========================================================================
586  * FUNCTION   : mm_camera_intf_qbuf
587  *
588  * DESCRIPTION: enqueue buffer back to kernel
589  *
590  * PARAMETERS :
591  *   @camera_handle: camera handle
592  *   @ch_id        : channel handle
593  *   @buf          : buf ptr to be enqueued
594  *
595  * RETURN     : int32_t type of status
596  *              0  -- success
597  *              -1 -- failure
598  *==========================================================================*/
mm_camera_intf_qbuf(uint32_t camera_handle,uint32_t ch_id,mm_camera_buf_def_t * buf)599 static int32_t mm_camera_intf_qbuf(uint32_t camera_handle,
600                                     uint32_t ch_id,
601                                     mm_camera_buf_def_t *buf)
602 {
603     int32_t rc = -1;
604     mm_camera_obj_t * my_obj = NULL;
605 
606     pthread_mutex_lock(&g_intf_lock);
607     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
608 
609     if(my_obj) {
610         pthread_mutex_lock(&my_obj->cam_lock);
611         pthread_mutex_unlock(&g_intf_lock);
612         rc = mm_camera_qbuf(my_obj, ch_id, buf);
613     } else {
614         pthread_mutex_unlock(&g_intf_lock);
615     }
616     CDBG("%s :X evt_type = %d",__func__,rc);
617     return rc;
618 }
619 
620 /*===========================================================================
621  * FUNCTION   : mm_camera_intf_add_stream
622  *
623  * DESCRIPTION: add a stream into a channel
624  *
625  * PARAMETERS :
626  *   @camera_handle: camera handle
627  *   @ch_id        : channel handle
628  *
629  * RETURN     : uint32_t type of stream handle
630  *              0  -- invalid stream handle, meaning the op failed
631  *              >0 -- successfully added a stream with a valid handle
632  *==========================================================================*/
mm_camera_intf_add_stream(uint32_t camera_handle,uint32_t ch_id)633 static uint32_t mm_camera_intf_add_stream(uint32_t camera_handle,
634                                           uint32_t ch_id)
635 {
636     uint32_t stream_id = 0;
637     mm_camera_obj_t * my_obj = NULL;
638 
639     CDBG("%s : E handle = %d ch_id = %d",
640          __func__, camera_handle, ch_id);
641 
642     pthread_mutex_lock(&g_intf_lock);
643     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
644 
645     if(my_obj) {
646         pthread_mutex_lock(&my_obj->cam_lock);
647         pthread_mutex_unlock(&g_intf_lock);
648         stream_id = mm_camera_add_stream(my_obj, ch_id);
649     } else {
650         pthread_mutex_unlock(&g_intf_lock);
651     }
652     CDBG("%s :X stream_id = %d", __func__, stream_id);
653     return stream_id;
654 }
655 
656 /*===========================================================================
657  * FUNCTION   : mm_camera_intf_del_stream
658  *
659  * DESCRIPTION: delete a stream by its handle
660  *
661  * PARAMETERS :
662  *   @camera_handle: camera handle
663  *   @ch_id        : channel handle
664  *   @stream_id    : stream handle
665  *
666  * RETURN     : int32_t type of status
667  *              0  -- success
668  *              -1 -- failure
669  * NOTE       : stream should be stopped already before it can be deleted.
670  *==========================================================================*/
mm_camera_intf_del_stream(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id)671 static int32_t mm_camera_intf_del_stream(uint32_t camera_handle,
672                                          uint32_t ch_id,
673                                          uint32_t stream_id)
674 {
675     int32_t rc = -1;
676     mm_camera_obj_t * my_obj = NULL;
677 
678     CDBG("%s : E handle = %d ch_id = %d stream_id = %d",
679          __func__, camera_handle, ch_id, stream_id);
680 
681     pthread_mutex_lock(&g_intf_lock);
682     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
683 
684     if(my_obj) {
685         pthread_mutex_lock(&my_obj->cam_lock);
686         pthread_mutex_unlock(&g_intf_lock);
687         rc = mm_camera_del_stream(my_obj, ch_id, stream_id);
688     } else {
689         pthread_mutex_unlock(&g_intf_lock);
690     }
691     CDBG("%s :X rc = %d", __func__, rc);
692     return rc;
693 }
694 
695 /*===========================================================================
696  * FUNCTION   : mm_camera_intf_config_stream
697  *
698  * DESCRIPTION: configure a stream
699  *
700  * PARAMETERS :
701  *   @camera_handle: camera handle
702  *   @ch_id        : channel handle
703  *   @stream_id    : stream handle
704  *   @config       : stream configuration
705  *
706  * RETURN     : int32_t type of status
707  *              0  -- success
708  *              -1 -- failure
709  *==========================================================================*/
mm_camera_intf_config_stream(uint32_t camera_handle,uint32_t ch_id,uint32_t stream_id,mm_camera_stream_config_t * config)710 static int32_t mm_camera_intf_config_stream(uint32_t camera_handle,
711                                             uint32_t ch_id,
712                                             uint32_t stream_id,
713                                             mm_camera_stream_config_t *config)
714 {
715     int32_t rc = -1;
716     mm_camera_obj_t * my_obj = NULL;
717 
718     CDBG("%s :E handle = %d, ch_id = %d,stream_id = %d",
719          __func__, camera_handle, ch_id, stream_id);
720 
721     pthread_mutex_lock(&g_intf_lock);
722     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
723 
724     CDBG("%s :mm_camera_intf_config_stream stream_id = %d",__func__,stream_id);
725 
726     if(my_obj) {
727         pthread_mutex_lock(&my_obj->cam_lock);
728         pthread_mutex_unlock(&g_intf_lock);
729         rc = mm_camera_config_stream(my_obj, ch_id, stream_id, config);
730     } else {
731         pthread_mutex_unlock(&g_intf_lock);
732     }
733     CDBG("%s :X rc = %d", __func__, rc);
734     return rc;
735 }
736 
737 /*===========================================================================
738  * FUNCTION   : mm_camera_intf_start_channel
739  *
740  * DESCRIPTION: start a channel, which will start all streams in the channel
741  *
742  * PARAMETERS :
743  *   @camera_handle: camera handle
744  *   @ch_id        : channel handle
745  *
746  * RETURN     : int32_t type of status
747  *              0  -- success
748  *              -1 -- failure
749  *==========================================================================*/
mm_camera_intf_start_channel(uint32_t camera_handle,uint32_t ch_id)750 static int32_t mm_camera_intf_start_channel(uint32_t camera_handle,
751                                             uint32_t ch_id)
752 {
753     int32_t rc = -1;
754     mm_camera_obj_t * my_obj = NULL;
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_start_channel(my_obj, ch_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_stop_channel
772  *
773  * DESCRIPTION: stop a channel, which will stop all streams in the channel
774  *
775  * PARAMETERS :
776  *   @camera_handle: camera handle
777  *   @ch_id        : channel handle
778  *
779  * RETURN     : int32_t type of status
780  *              0  -- success
781  *              -1 -- failure
782  *==========================================================================*/
mm_camera_intf_stop_channel(uint32_t camera_handle,uint32_t ch_id)783 static int32_t mm_camera_intf_stop_channel(uint32_t camera_handle,
784                                            uint32_t ch_id)
785 {
786     int32_t rc = -1;
787     mm_camera_obj_t * my_obj = NULL;
788 
789     pthread_mutex_lock(&g_intf_lock);
790     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
791 
792     if(my_obj) {
793         pthread_mutex_lock(&my_obj->cam_lock);
794         pthread_mutex_unlock(&g_intf_lock);
795         rc = mm_camera_stop_channel(my_obj, ch_id);
796     } else {
797         pthread_mutex_unlock(&g_intf_lock);
798     }
799     CDBG("%s :X rc = %d", __func__, rc);
800     return rc;
801 }
802 
803 /*===========================================================================
804  * FUNCTION   : mm_camera_intf_request_super_buf
805  *
806  * DESCRIPTION: for burst mode in bundle, reuqest certain amount of matched
807  *              frames from superbuf queue
808  *
809  * PARAMETERS :
810  *   @camera_handle: camera handle
811  *   @ch_id        : channel handle
812  *   @num_buf_requested : number of matched frames needed
813  *
814  * RETURN     : int32_t type of status
815  *              0  -- success
816  *              -1 -- failure
817  *==========================================================================*/
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)818 static int32_t mm_camera_intf_request_super_buf(uint32_t camera_handle,
819                                                 uint32_t ch_id,
820                                                 uint32_t num_buf_requested,
821                                                 uint32_t num_retro_buf_requested)
822 {
823     int32_t rc = -1;
824     CDBG("%s :E camera_handler = %d,ch_id = %d",
825          __func__, camera_handle, ch_id);
826     mm_camera_obj_t * my_obj = NULL;
827 
828     pthread_mutex_lock(&g_intf_lock);
829     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
830 
831     if(my_obj) {
832         pthread_mutex_lock(&my_obj->cam_lock);
833         pthread_mutex_unlock(&g_intf_lock);
834         rc = mm_camera_request_super_buf (my_obj, ch_id,
835           num_buf_requested, num_retro_buf_requested);
836     } else {
837         pthread_mutex_unlock(&g_intf_lock);
838     }
839     CDBG("%s :X rc = %d", __func__, rc);
840     return rc;
841 }
842 
843 /*===========================================================================
844  * FUNCTION   : mm_camera_intf_cancel_super_buf_request
845  *
846  * DESCRIPTION: for burst mode in bundle, cancel the reuqest for certain amount
847  *              of matched frames from superbuf queue
848  *
849  * PARAMETERS :
850  *   @camera_handle: camera handle
851  *   @ch_id        : channel handle
852  *
853  * RETURN     : int32_t type of status
854  *              0  -- success
855  *              -1 -- failure
856  *==========================================================================*/
mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,uint32_t ch_id)857 static int32_t mm_camera_intf_cancel_super_buf_request(uint32_t camera_handle,
858                                                        uint32_t ch_id)
859 {
860     int32_t rc = -1;
861     mm_camera_obj_t * my_obj = NULL;
862 
863     CDBG("%s :E camera_handler = %d,ch_id = %d",
864          __func__, camera_handle, ch_id);
865     pthread_mutex_lock(&g_intf_lock);
866     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
867 
868     if(my_obj) {
869         pthread_mutex_lock(&my_obj->cam_lock);
870         pthread_mutex_unlock(&g_intf_lock);
871         rc = mm_camera_cancel_super_buf_request(my_obj, ch_id);
872     } else {
873         pthread_mutex_unlock(&g_intf_lock);
874     }
875     CDBG("%s :X rc = %d", __func__, rc);
876     return rc;
877 }
878 
879 /*===========================================================================
880  * FUNCTION   : mm_camera_intf_flush_super_buf_queue
881  *
882  * DESCRIPTION: flush out all frames in the superbuf queue
883  *
884  * PARAMETERS :
885  *   @camera_handle: camera handle
886  *   @ch_id        : channel handle
887  *   @frame_idx    : frame index
888  *
889  * RETURN     : int32_t type of status
890  *              0  -- success
891  *              -1 -- failure
892  *==========================================================================*/
mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,uint32_t ch_id,uint32_t frame_idx)893 static int32_t mm_camera_intf_flush_super_buf_queue(uint32_t camera_handle,
894                                                     uint32_t ch_id, uint32_t frame_idx)
895 {
896     int32_t rc = -1;
897     mm_camera_obj_t * my_obj = NULL;
898 
899     CDBG("%s :E camera_handler = %d,ch_id = %d",
900          __func__, camera_handle, ch_id);
901     pthread_mutex_lock(&g_intf_lock);
902     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
903 
904     if(my_obj) {
905         pthread_mutex_lock(&my_obj->cam_lock);
906         pthread_mutex_unlock(&g_intf_lock);
907         rc = mm_camera_flush_super_buf_queue(my_obj, ch_id, frame_idx);
908     } else {
909         pthread_mutex_unlock(&g_intf_lock);
910     }
911     CDBG("%s :X rc = %d", __func__, rc);
912     return rc;
913 }
914 
915 /*===========================================================================
916  * FUNCTION   : mm_camera_intf_start_zsl_snapshot
917  *
918  * DESCRIPTION: Starts zsl snapshot
919  *
920  * PARAMETERS :
921  *   @camera_handle: camera handle
922  *   @ch_id        : channel handle
923  *
924  * RETURN     : int32_t type of status
925  *              0  -- success
926  *              -1 -- failure
927  *==========================================================================*/
mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle,uint32_t ch_id)928 static int32_t mm_camera_intf_start_zsl_snapshot(uint32_t camera_handle,
929         uint32_t ch_id)
930 {
931     int32_t rc = -1;
932     mm_camera_obj_t * my_obj = NULL;
933 
934     CDBG("%s :E camera_handler = %d,ch_id = %d",
935          __func__, camera_handle, ch_id);
936     pthread_mutex_lock(&g_intf_lock);
937     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
938 
939     if(my_obj) {
940         pthread_mutex_lock(&my_obj->cam_lock);
941         pthread_mutex_unlock(&g_intf_lock);
942         rc = mm_camera_start_zsl_snapshot_ch(my_obj, ch_id);
943     } else {
944         pthread_mutex_unlock(&g_intf_lock);
945     }
946     CDBG("%s :X rc = %d", __func__, rc);
947     return rc;
948 }
949 
950 /*===========================================================================
951  * FUNCTION   : mm_camera_intf_stop_zsl_snapshot
952  *
953  * DESCRIPTION: Stops zsl snapshot
954  *
955  * PARAMETERS :
956  *   @camera_handle: camera handle
957  *   @ch_id        : channel handle
958  *
959  * RETURN     : int32_t type of status
960  *              0  -- success
961  *              -1 -- failure
962  *==========================================================================*/
mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle,uint32_t ch_id)963 static int32_t mm_camera_intf_stop_zsl_snapshot(uint32_t camera_handle,
964         uint32_t ch_id)
965 {
966     int32_t rc = -1;
967     mm_camera_obj_t * my_obj = NULL;
968 
969     CDBG("%s :E camera_handler = %d,ch_id = %d",
970          __func__, camera_handle, ch_id);
971     pthread_mutex_lock(&g_intf_lock);
972     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
973 
974     if(my_obj) {
975         pthread_mutex_lock(&my_obj->cam_lock);
976         pthread_mutex_unlock(&g_intf_lock);
977         rc = mm_camera_stop_zsl_snapshot_ch(my_obj, ch_id);
978     } else {
979         pthread_mutex_unlock(&g_intf_lock);
980     }
981     CDBG("%s :X rc = %d", __func__, rc);
982     return rc;
983 }
984 
985 /*===========================================================================
986  * FUNCTION   : mm_camera_intf_configure_notify_mode
987  *
988  * DESCRIPTION: Configures channel notification mode
989  *
990  * PARAMETERS :
991  *   @camera_handle: camera handle
992  *   @ch_id        : channel handle
993  *   @notify_mode  : notification mode
994  *
995  * RETURN     : int32_t type of status
996  *              0  -- success
997  *              -1 -- failure
998  *==========================================================================*/
mm_camera_intf_configure_notify_mode(uint32_t camera_handle,uint32_t ch_id,mm_camera_super_buf_notify_mode_t notify_mode)999 static int32_t mm_camera_intf_configure_notify_mode(uint32_t camera_handle,
1000                                                     uint32_t ch_id,
1001                                                     mm_camera_super_buf_notify_mode_t notify_mode)
1002 {
1003     int32_t rc = -1;
1004     mm_camera_obj_t * my_obj = NULL;
1005 
1006     CDBG("%s :E camera_handler = %d,ch_id = %d",
1007          __func__, camera_handle, ch_id);
1008     pthread_mutex_lock(&g_intf_lock);
1009     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1010 
1011     if(my_obj) {
1012         pthread_mutex_lock(&my_obj->cam_lock);
1013         pthread_mutex_unlock(&g_intf_lock);
1014         rc = mm_camera_config_channel_notify(my_obj, ch_id, notify_mode);
1015     } else {
1016         pthread_mutex_unlock(&g_intf_lock);
1017     }
1018     CDBG("%s :X rc = %d", __func__, rc);
1019     return rc;
1020 }
1021 
1022 /*===========================================================================
1023  * FUNCTION   : mm_camera_intf_map_buf
1024  *
1025  * DESCRIPTION: mapping camera buffer via domain socket to server
1026  *
1027  * PARAMETERS :
1028  *   @camera_handle: camera handle
1029  *   @buf_type     : type of buffer to be mapped. could be following values:
1030  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1031  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1032  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1033  *   @fd           : file descriptor of the buffer
1034  *   @size         : size of the buffer
1035  *
1036  * RETURN     : int32_t type of status
1037  *              0  -- success
1038  *              -1 -- failure
1039  *==========================================================================*/
mm_camera_intf_map_buf(uint32_t camera_handle,uint8_t buf_type,int fd,uint32_t size)1040 static int32_t mm_camera_intf_map_buf(uint32_t camera_handle,
1041                                       uint8_t buf_type,
1042                                       int fd,
1043                                       uint32_t size)
1044 {
1045     int32_t rc = -1;
1046     mm_camera_obj_t * my_obj = NULL;
1047 
1048     pthread_mutex_lock(&g_intf_lock);
1049     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1050 
1051     if(my_obj) {
1052         pthread_mutex_lock(&my_obj->cam_lock);
1053         pthread_mutex_unlock(&g_intf_lock);
1054         rc = mm_camera_map_buf(my_obj, buf_type, fd, size);
1055     } else {
1056         pthread_mutex_unlock(&g_intf_lock);
1057     }
1058     return rc;
1059 }
1060 
1061 /*===========================================================================
1062  * FUNCTION   : mm_camera_intf_unmap_buf
1063  *
1064  * DESCRIPTION: unmapping camera buffer via domain socket to server
1065  *
1066  * PARAMETERS :
1067  *   @camera_handle: camera handle
1068  *   @buf_type     : type of buffer to be unmapped. could be following values:
1069  *                   CAM_MAPPING_BUF_TYPE_CAPABILITY
1070  *                   CAM_MAPPING_BUF_TYPE_SETPARM_BUF
1071  *                   CAM_MAPPING_BUF_TYPE_GETPARM_BUF
1072  *
1073  * RETURN     : int32_t type of status
1074  *              0  -- success
1075  *              -1 -- failure
1076  *==========================================================================*/
mm_camera_intf_unmap_buf(uint32_t camera_handle,uint8_t buf_type)1077 static int32_t mm_camera_intf_unmap_buf(uint32_t camera_handle,
1078                                         uint8_t buf_type)
1079 {
1080     int32_t rc = -1;
1081     mm_camera_obj_t * my_obj = NULL;
1082 
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_unmap_buf(my_obj, buf_type);
1090     } else {
1091         pthread_mutex_unlock(&g_intf_lock);
1092     }
1093     return rc;
1094 }
1095 
1096 /*===========================================================================
1097  * FUNCTION   : mm_camera_intf_set_stream_parms
1098  *
1099  * DESCRIPTION: set 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 set to 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. Corresponding fields of parameters to be set
1112  *              are already filled in by upper layer caller.
1113  *==========================================================================*/
mm_camera_intf_set_stream_parms(uint32_t camera_handle,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1114 static int32_t mm_camera_intf_set_stream_parms(uint32_t camera_handle,
1115                                                uint32_t ch_id,
1116                                                uint32_t s_id,
1117                                                cam_stream_parm_buffer_t *parms)
1118 {
1119     int32_t rc = -1;
1120     mm_camera_obj_t * my_obj = NULL;
1121 
1122     pthread_mutex_lock(&g_intf_lock);
1123     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1124 
1125     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
1126          __func__, camera_handle, ch_id, s_id);
1127 
1128     if(my_obj) {
1129         pthread_mutex_lock(&my_obj->cam_lock);
1130         pthread_mutex_unlock(&g_intf_lock);
1131         rc = mm_camera_set_stream_parms(my_obj, ch_id, s_id, parms);
1132     }else{
1133         pthread_mutex_unlock(&g_intf_lock);
1134     }
1135     CDBG("%s :X rc = %d", __func__, rc);
1136     return rc;
1137 }
1138 
1139 /*===========================================================================
1140  * FUNCTION   : mm_camera_intf_get_stream_parms
1141  *
1142  * DESCRIPTION: get parameters per stream
1143  *
1144  * PARAMETERS :
1145  *   @camera_handle: camera handle
1146  *   @ch_id        : channel handle
1147  *   @s_id         : stream handle
1148  *   @parms        : ptr to a param struct to be get from server
1149  *
1150  * RETURN     : int32_t type of status
1151  *              0  -- success
1152  *              -1 -- failure
1153  * NOTE       : Assume the parms struct buf is already mapped to server via
1154  *              domain socket. Parameters to be get from server are already
1155  *              filled in by upper layer caller. After this call, corresponding
1156  *              fields of requested parameters will be filled in by server with
1157  *              detailed information.
1158  *==========================================================================*/
mm_camera_intf_get_stream_parms(uint32_t camera_handle,uint32_t ch_id,uint32_t s_id,cam_stream_parm_buffer_t * parms)1159 static int32_t mm_camera_intf_get_stream_parms(uint32_t camera_handle,
1160                                                uint32_t ch_id,
1161                                                uint32_t s_id,
1162                                                cam_stream_parm_buffer_t *parms)
1163 {
1164     int32_t rc = -1;
1165     mm_camera_obj_t * my_obj = NULL;
1166 
1167     pthread_mutex_lock(&g_intf_lock);
1168     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1169 
1170     CDBG("%s :E camera_handle = %d,ch_id = %d,s_id = %d",
1171          __func__, camera_handle, ch_id, s_id);
1172 
1173     if(my_obj) {
1174         pthread_mutex_lock(&my_obj->cam_lock);
1175         pthread_mutex_unlock(&g_intf_lock);
1176         rc = mm_camera_get_stream_parms(my_obj, ch_id, s_id, parms);
1177     }else{
1178         pthread_mutex_unlock(&g_intf_lock);
1179     }
1180 
1181     CDBG("%s :X rc = %d", __func__, rc);
1182     return rc;
1183 }
1184 
1185 /*===========================================================================
1186  * FUNCTION   : mm_camera_intf_map_stream_buf
1187  *
1188  * DESCRIPTION: mapping stream buffer via domain socket to server
1189  *
1190  * PARAMETERS :
1191  *   @camera_handle: camera handle
1192  *   @ch_id        : channel handle
1193  *   @s_id         : stream handle
1194  *   @buf_type     : type of buffer to be mapped. could be following values:
1195  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1196  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1197  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1198  *   @buf_idx      : index of buffer within the stream buffers, only valid if
1199  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1200  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1201  *   @plane_idx    : plane index. If all planes share the same fd,
1202  *                   plane_idx = -1; otherwise, plean_idx is the
1203  *                   index to plane (0..num_of_planes)
1204  *   @fd           : file descriptor of the buffer
1205  *   @size         : size of the buffer
1206  *
1207  * RETURN     : int32_t type of status
1208  *              0  -- success
1209  *              -1 -- failure
1210  *==========================================================================*/
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)1211 static int32_t mm_camera_intf_map_stream_buf(uint32_t camera_handle,
1212                                              uint32_t ch_id,
1213                                              uint32_t stream_id,
1214                                              uint8_t buf_type,
1215                                              uint32_t buf_idx,
1216                                              int32_t plane_idx,
1217                                              int fd,
1218                                              uint32_t size)
1219 {
1220     int32_t rc = -1;
1221     mm_camera_obj_t * my_obj = NULL;
1222 
1223     pthread_mutex_lock(&g_intf_lock);
1224     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1225 
1226     CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
1227          __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
1228 
1229     if(my_obj) {
1230         pthread_mutex_lock(&my_obj->cam_lock);
1231         pthread_mutex_unlock(&g_intf_lock);
1232         rc = mm_camera_map_stream_buf(my_obj, ch_id, stream_id,
1233                                       buf_type, buf_idx, plane_idx,
1234                                       fd, size);
1235     }else{
1236         pthread_mutex_unlock(&g_intf_lock);
1237     }
1238 
1239     CDBG("%s :X rc = %d", __func__, rc);
1240     return rc;
1241 }
1242 
1243 /*===========================================================================
1244  * FUNCTION   : mm_camera_intf_unmap_stream_buf
1245  *
1246  * DESCRIPTION: unmapping stream buffer via domain socket to server
1247  *
1248  * PARAMETERS :
1249  *   @camera_handle: camera handle
1250  *   @ch_id        : channel handle
1251  *   @s_id         : stream handle
1252  *   @buf_type     : type of buffer to be unmapped. could be following values:
1253  *                   CAM_MAPPING_BUF_TYPE_STREAM_BUF
1254  *                   CAM_MAPPING_BUF_TYPE_STREAM_INFO
1255  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1256  *   @buf_idx      : index of buffer within the stream buffers, only valid if
1257  *                   buf_type is CAM_MAPPING_BUF_TYPE_STREAM_BUF or
1258  *                   CAM_MAPPING_BUF_TYPE_OFFLINE_INPUT_BUF
1259  *   @plane_idx    : plane index. If all planes share the same fd,
1260  *                   plane_idx = -1; otherwise, plean_idx is the
1261  *                   index to plane (0..num_of_planes)
1262  *
1263  * RETURN     : int32_t type of status
1264  *              0  -- success
1265  *              -1 -- failure
1266  *==========================================================================*/
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)1267 static int32_t mm_camera_intf_unmap_stream_buf(uint32_t camera_handle,
1268                                                uint32_t ch_id,
1269                                                uint32_t stream_id,
1270                                                uint8_t buf_type,
1271                                                uint32_t buf_idx,
1272                                                int32_t plane_idx)
1273 {
1274     int32_t rc = -1;
1275     mm_camera_obj_t * my_obj = NULL;
1276 
1277     pthread_mutex_lock(&g_intf_lock);
1278     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1279 
1280     CDBG("%s :E camera_handle = %d, ch_id = %d, s_id = %d, buf_idx = %d, plane_idx = %d",
1281          __func__, camera_handle, ch_id, stream_id, buf_idx, plane_idx);
1282 
1283     if(my_obj) {
1284         pthread_mutex_lock(&my_obj->cam_lock);
1285         pthread_mutex_unlock(&g_intf_lock);
1286         rc = mm_camera_unmap_stream_buf(my_obj, ch_id, stream_id,
1287                                         buf_type, buf_idx, plane_idx);
1288     }else{
1289         pthread_mutex_unlock(&g_intf_lock);
1290     }
1291 
1292     CDBG("%s :X rc = %d", __func__, rc);
1293     return rc;
1294 }
1295 
1296 /*===========================================================================
1297  * FUNCTION   : get_sensor_info
1298  *
1299  * DESCRIPTION: get sensor info like facing(back/front) and mount angle
1300  *
1301  * PARAMETERS :
1302  *
1303  * RETURN     :
1304  *==========================================================================*/
get_sensor_info()1305 void get_sensor_info()
1306 {
1307     int rc = 0;
1308     int dev_fd = -1;
1309     struct media_device_info mdev_info;
1310     int num_media_devices = 0;
1311     uint8_t num_cameras = 0;
1312 
1313     CDBG("%s : E", __func__);
1314     while (1) {
1315         char dev_name[32];
1316         int num_entities;
1317         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
1318         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
1319         if (dev_fd < 0) {
1320             CDBG("Done discovering media devices\n");
1321             break;
1322         }
1323         num_media_devices++;
1324         memset(&mdev_info, 0, sizeof(mdev_info));
1325         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
1326         if (rc < 0) {
1327             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
1328             close(dev_fd);
1329             dev_fd = -1;
1330             num_cameras = 0;
1331             break;
1332         }
1333 
1334         if(strncmp(mdev_info.model,  MSM_CONFIGURATION_NAME, sizeof(mdev_info.model)) != 0) {
1335             close(dev_fd);
1336             dev_fd = -1;
1337             continue;
1338         }
1339 
1340         num_entities = 1;
1341         while (1) {
1342             struct media_entity_desc entity;
1343             unsigned long temp;
1344             unsigned int mount_angle;
1345             unsigned int facing;
1346 
1347             memset(&entity, 0, sizeof(entity));
1348             entity.id = num_entities++;
1349             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
1350             if (rc < 0) {
1351                 CDBG("Done enumerating media entities\n");
1352                 rc = 0;
1353                 break;
1354             }
1355             if(entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
1356                 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR) {
1357                 temp = entity.flags >> 8;
1358                 mount_angle = (temp & 0xFF) * 90;
1359                 facing = (temp >> 8);
1360                 ALOGD("index = %d flag = %x mount_angle = %d facing = %d\n"
1361                     , num_cameras, (unsigned int)temp, (unsigned int)mount_angle,
1362                     (unsigned int)facing);
1363                 g_cam_ctrl.info[num_cameras].facing = facing;
1364                 g_cam_ctrl.info[num_cameras].orientation = mount_angle;
1365                 num_cameras++;
1366                 continue;
1367             }
1368         }
1369 
1370         CDBG("%s: dev_info[id=%d,name='%s']\n",
1371             __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
1372 
1373         close(dev_fd);
1374         dev_fd = -1;
1375     }
1376 
1377     CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
1378     return;
1379 }
1380 
1381 /*===========================================================================
1382  * FUNCTION   : get_num_of_cameras
1383  *
1384  * DESCRIPTION: get number of cameras
1385  *
1386  * PARAMETERS :
1387  *
1388  * RETURN     : number of cameras supported
1389  *==========================================================================*/
get_num_of_cameras()1390 uint8_t get_num_of_cameras()
1391 {
1392     int rc = 0;
1393     int dev_fd = 0;
1394     struct media_device_info mdev_info;
1395     int num_media_devices = 0;
1396     uint8_t num_cameras = 0;
1397     char subdev_name[32];
1398     int32_t sd_fd = 0;
1399     struct sensor_init_cfg_data cfg;
1400     char prop[PROPERTY_VALUE_MAX];
1401 
1402     property_get("persist.camera.logs", prop, "0");
1403     gMmCameraIntfLogLevel = atoi(prop);
1404 
1405     CDBG("%s : E", __func__);
1406 
1407     int decrypt = property_get("vold.decrypt", prop, NULL);
1408     if (0 < decrypt) {
1409         if(strncmp(prop, "trigger_restart_min_framework", decrypt) == 0) {
1410             return 0;
1411         }
1412     }
1413 
1414     /* lock the mutex */
1415     pthread_mutex_lock(&g_intf_lock);
1416 
1417     while (1) {
1418         int32_t num_entities = 1;
1419         char dev_name[32];
1420 
1421         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
1422         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
1423         if (dev_fd < 0) {
1424             CDBG("Done discovering media devices\n");
1425             break;
1426         }
1427         num_media_devices++;
1428         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
1429         if (rc < 0) {
1430             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
1431             close(dev_fd);
1432             dev_fd = -1;
1433             break;
1434         }
1435 
1436         if (strncmp(mdev_info.model, MSM_CONFIGURATION_NAME,
1437           sizeof(mdev_info.model)) != 0) {
1438             close(dev_fd);
1439             dev_fd = -1;
1440             continue;
1441         }
1442 
1443         while (1) {
1444             struct media_entity_desc entity;
1445             memset(&entity, 0, sizeof(entity));
1446             entity.id = num_entities++;
1447             CDBG_ERROR("entity id %d", entity.id);
1448             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
1449             if (rc < 0) {
1450                 CDBG_ERROR("Done enumerating media entities");
1451                 rc = 0;
1452                 break;
1453             }
1454             CDBG_ERROR("entity name %s type %d group id %d",
1455                 entity.name, entity.type, entity.group_id);
1456             if (entity.type == MEDIA_ENT_T_V4L2_SUBDEV &&
1457                 entity.group_id == MSM_CAMERA_SUBDEV_SENSOR_INIT) {
1458                 snprintf(subdev_name, sizeof(dev_name), "/dev/%s", entity.name);
1459                 break;
1460             }
1461         }
1462         close(dev_fd);
1463         dev_fd = -1;
1464     }
1465 
1466     /* Open sensor_init subdev */
1467     sd_fd = open(subdev_name, O_RDWR);
1468     if (sd_fd < 0) {
1469         CDBG_ERROR("Open sensor_init subdev failed");
1470         return FALSE;
1471     }
1472 
1473     cfg.cfgtype = CFG_SINIT_PROBE_WAIT_DONE;
1474     cfg.cfg.setting = NULL;
1475     if (ioctl(sd_fd, VIDIOC_MSM_SENSOR_INIT_CFG, &cfg) < 0) {
1476         CDBG_ERROR("failed");
1477     }
1478     close(sd_fd);
1479     dev_fd = -1;
1480 
1481 
1482     num_media_devices = 0;
1483     while (1) {
1484         char dev_name[32];
1485         int num_entities;
1486         snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
1487         dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
1488         if (dev_fd < 0) {
1489             CDBG("Done discovering media devices: %s\n", strerror(errno));
1490             break;
1491         }
1492         num_media_devices++;
1493         memset(&mdev_info, 0, sizeof(mdev_info));
1494         rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
1495         if (rc < 0) {
1496             CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
1497             close(dev_fd);
1498             dev_fd = -1;
1499             num_cameras = 0;
1500             break;
1501         }
1502 
1503         if(strncmp(mdev_info.model, MSM_CAMERA_NAME, sizeof(mdev_info.model)) != 0) {
1504             close(dev_fd);
1505             dev_fd = -1;
1506             continue;
1507         }
1508 
1509         num_entities = 1;
1510         while (1) {
1511             struct media_entity_desc entity;
1512             memset(&entity, 0, sizeof(entity));
1513             entity.id = num_entities++;
1514             rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
1515             if (rc < 0) {
1516                 CDBG("Done enumerating media entities\n");
1517                 rc = 0;
1518                 break;
1519             }
1520             if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
1521                 strncpy(g_cam_ctrl.video_dev_name[num_cameras],
1522                      entity.name, sizeof(entity.name));
1523                 break;
1524             }
1525         }
1526 
1527         CDBG("%s: dev_info[id=%d,name='%s']\n",
1528             __func__, num_cameras, g_cam_ctrl.video_dev_name[num_cameras]);
1529 
1530         num_cameras++;
1531         close(dev_fd);
1532         dev_fd = -1;
1533     }
1534     g_cam_ctrl.num_cam = num_cameras;
1535 
1536     get_sensor_info();
1537     /* unlock the mutex */
1538     pthread_mutex_unlock(&g_intf_lock);
1539     CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
1540     return g_cam_ctrl.num_cam;
1541 }
1542 
1543 /*===========================================================================
1544  * FUNCTION   : mm_camera_intf_process_advanced_capture
1545  *
1546  * DESCRIPTION: Configures channel advanced capture mode
1547  *
1548  * PARAMETERS :
1549  *   @camera_handle: camera handle
1550  *   @advanced_capture_type : advanced capture type
1551  *   @ch_id        : channel handle
1552  *   @notify_mode  : notification mode
1553  *
1554  * RETURN     : int32_t type of status
1555  *              0  -- success
1556  *              -1 -- failure
1557  *==========================================================================*/
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)1558 static int32_t mm_camera_intf_process_advanced_capture(uint32_t camera_handle,
1559     mm_camera_advanced_capture_t advanced_capture_type,
1560     uint32_t ch_id,
1561     int8_t start_flag)
1562 {
1563     int32_t rc = -1;
1564     mm_camera_obj_t * my_obj = NULL;
1565 
1566     CDBG("%s: E camera_handler = %d,ch_id = %d",
1567          __func__, camera_handle, ch_id);
1568     pthread_mutex_lock(&g_intf_lock);
1569     my_obj = mm_camera_util_get_camera_by_handler(camera_handle);
1570 
1571     if(my_obj) {
1572         pthread_mutex_lock(&my_obj->cam_lock);
1573         pthread_mutex_unlock(&g_intf_lock);
1574         rc = mm_camera_channel_advanced_capture(my_obj, advanced_capture_type, ch_id, start_flag);
1575     } else {
1576         pthread_mutex_unlock(&g_intf_lock);
1577     }
1578     CDBG("%s: X ", __func__);
1579     return rc;
1580 }
1581 
get_cam_info(int camera_id)1582 struct camera_info *get_cam_info(int camera_id)
1583 {
1584     return &g_cam_ctrl.info[camera_id];
1585 }
1586 
1587 /* camera ops v-table */
1588 static mm_camera_ops_t mm_camera_ops = {
1589     .query_capability = mm_camera_intf_query_capability,
1590     .register_event_notify = mm_camera_intf_register_event_notify,
1591     .close_camera = mm_camera_intf_close,
1592     .error_close_camera = mm_camera_intf_error_close,
1593     .set_parms = mm_camera_intf_set_parms,
1594     .get_parms = mm_camera_intf_get_parms,
1595     .do_auto_focus = mm_camera_intf_do_auto_focus,
1596     .cancel_auto_focus = mm_camera_intf_cancel_auto_focus,
1597     .prepare_snapshot = mm_camera_intf_prepare_snapshot,
1598     .start_zsl_snapshot = mm_camera_intf_start_zsl_snapshot,
1599     .stop_zsl_snapshot = mm_camera_intf_stop_zsl_snapshot,
1600     .map_buf = mm_camera_intf_map_buf,
1601     .unmap_buf = mm_camera_intf_unmap_buf,
1602     .add_channel = mm_camera_intf_add_channel,
1603     .delete_channel = mm_camera_intf_del_channel,
1604     .get_bundle_info = mm_camera_intf_get_bundle_info,
1605     .add_stream = mm_camera_intf_add_stream,
1606     .delete_stream = mm_camera_intf_del_stream,
1607     .config_stream = mm_camera_intf_config_stream,
1608     .qbuf = mm_camera_intf_qbuf,
1609     .map_stream_buf = mm_camera_intf_map_stream_buf,
1610     .unmap_stream_buf = mm_camera_intf_unmap_stream_buf,
1611     .set_stream_parms = mm_camera_intf_set_stream_parms,
1612     .get_stream_parms = mm_camera_intf_get_stream_parms,
1613     .start_channel = mm_camera_intf_start_channel,
1614     .stop_channel = mm_camera_intf_stop_channel,
1615     .request_super_buf = mm_camera_intf_request_super_buf,
1616     .cancel_super_buf_request = mm_camera_intf_cancel_super_buf_request,
1617     .flush_super_buf_queue = mm_camera_intf_flush_super_buf_queue,
1618     .configure_notify_mode = mm_camera_intf_configure_notify_mode,
1619     .process_advanced_capture = mm_camera_intf_process_advanced_capture
1620 };
1621 
1622 /*===========================================================================
1623  * FUNCTION   : camera_open
1624  *
1625  * DESCRIPTION: open a camera by camera index
1626  *
1627  * PARAMETERS :
1628  *   @camera_idx : camera index. should within range of 0 to num_of_cameras
1629  *
1630  * RETURN     : ptr to a virtual table containing camera handle and operation table.
1631  *              NULL if failed.
1632  *==========================================================================*/
camera_open(uint8_t camera_idx)1633 mm_camera_vtbl_t * camera_open(uint8_t camera_idx)
1634 {
1635     int32_t rc = 0;
1636     mm_camera_obj_t* cam_obj = NULL;
1637 
1638     CDBG("%s: E camera_idx = %d\n", __func__, camera_idx);
1639     if (camera_idx >= g_cam_ctrl.num_cam) {
1640         CDBG_ERROR("%s: Invalid camera_idx (%d)", __func__, camera_idx);
1641         return NULL;
1642     }
1643 
1644     pthread_mutex_lock(&g_intf_lock);
1645     /* opened already */
1646     if(NULL != g_cam_ctrl.cam_obj[camera_idx]) {
1647         /* Add reference */
1648         g_cam_ctrl.cam_obj[camera_idx]->ref_count++;
1649         pthread_mutex_unlock(&g_intf_lock);
1650         CDBG("%s:  opened alreadyn", __func__);
1651         return &g_cam_ctrl.cam_obj[camera_idx]->vtbl;
1652     }
1653 
1654     cam_obj = (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
1655     if(NULL == cam_obj) {
1656         pthread_mutex_unlock(&g_intf_lock);
1657         CDBG("%s:  no mem", __func__);
1658         return NULL;
1659     }
1660 
1661     /* initialize camera obj */
1662     memset(cam_obj, 0, sizeof(mm_camera_obj_t));
1663     cam_obj->ctrl_fd = -1;
1664     cam_obj->ds_fd = -1;
1665     cam_obj->ref_count++;
1666     cam_obj->my_hdl = mm_camera_util_generate_handler(camera_idx);
1667     cam_obj->vtbl.camera_handle = cam_obj->my_hdl; /* set handler */
1668     cam_obj->vtbl.ops = &mm_camera_ops;
1669     pthread_mutex_init(&cam_obj->cam_lock, NULL);
1670 
1671     rc = mm_camera_open(cam_obj);
1672     if(rc != 0) {
1673         CDBG_ERROR("%s: mm_camera_open err = %d", __func__, rc);
1674         pthread_mutex_destroy(&cam_obj->cam_lock);
1675         g_cam_ctrl.cam_obj[camera_idx] = NULL;
1676         free(cam_obj);
1677         cam_obj = NULL;
1678         pthread_mutex_unlock(&g_intf_lock);
1679         return NULL;
1680     }else{
1681         CDBG("%s: Open succeded\n", __func__);
1682         g_cam_ctrl.cam_obj[camera_idx] = cam_obj;
1683         pthread_mutex_unlock(&g_intf_lock);
1684         return &cam_obj->vtbl;
1685     }
1686 }
1687