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