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