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