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
49static pthread_mutex_t g_intf_lock = PTHREAD_MUTEX_INITIALIZER;
50
51static mm_camera_ctrl_t g_cam_ctrl;
52
53static pthread_mutex_t g_handler_lock = PTHREAD_MUTEX_INITIALIZER;
54static 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 *==========================================================================*/
69uint32_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 *==========================================================================*/
93uint8_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 *==========================================================================*/
109const 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 *==========================================================================*/
130mm_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 *==========================================================================*/
155static 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 *==========================================================================*/
192static 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 *==========================================================================*/
229static 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 *==========================================================================*/
262static 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 *==========================================================================*/
292static 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 *==========================================================================*/
323static 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 *==========================================================================*/
354static 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 *==========================================================================*/
384static 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 *==========================================================================*/
440static 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 *==========================================================================*/
478static 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 *==========================================================================*/
515static 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 *==========================================================================*/
551static 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 *==========================================================================*/
587static 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 *==========================================================================*/
621static 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 *==========================================================================*/
656static 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 *==========================================================================*/
695static 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 *==========================================================================*/
733static 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 *==========================================================================*/
772static 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 *==========================================================================*/
812static 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 *==========================================================================*/
845static 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 *==========================================================================*/
880static 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 *==========================================================================*/
916static 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 *==========================================================================*/
952static 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 *==========================================================================*/
987static 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 *==========================================================================*/
1022static 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 *==========================================================================*/
1058static 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 *==========================================================================*/
1099static 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
1120static 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 *==========================================================================*/
1155static 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 *==========================================================================*/
1192static 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 *==========================================================================*/
1237static 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 *==========================================================================*/
1289static 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 *==========================================================================*/
1335static 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 *==========================================================================*/
1384static 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 *==========================================================================*/
1427static 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 *==========================================================================*/
1460static 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 *==========================================================================*/
1488void 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 *==========================================================================*/
1580void 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 *==========================================================================*/
1704uint8_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 *==========================================================================*/
1871static 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 *==========================================================================*/
1912static 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
1936struct 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
1942uint8_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 */
1948static 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 *==========================================================================*/
2002int32_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