1/*
2Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, are permitted provided that the following conditions are
6met:
7    * Redistributions of source code must retain the above copyright
8      notice, this list of conditions and the following disclaimer.
9    * Redistributions in binary form must reproduce the above
10      copyright notice, this list of conditions and the following
11      disclaimer in the documentation and/or other materials provided
12      with the distribution.
13    * Neither the name of Code Aurora Forum, Inc. nor the names of its
14      contributors may be used to endorse or promote products derived
15      from this software without specific prior written permission.
16
17THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*/
29
30#include <pthread.h>
31#include "mm_camera_dbg.h"
32#include <errno.h>
33#include <sys/ioctl.h>
34#include <sys/types.h>
35#include <sys/stat.h>
36#include <fcntl.h>
37#include <stddef.h>
38#include <poll.h>
39#include <linux/media.h>
40
41#include "mm_camera_interface2.h"
42#include "mm_camera.h"
43
44#define SET_PARM_BIT32(parm, parm_arr) \
45    (parm_arr[parm/32] |= (1<<(parm%32)))
46
47#define GET_PARM_BIT32(parm, parm_arr) \
48    ((parm_arr[parm/32]>>(parm%32))& 0x1)
49
50static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
51
52static mm_camera_ctrl_t g_cam_ctrl;
53
54static int mm_camera_util_opcode_2_ch_type(mm_camera_obj_t *my_obj,
55                                        mm_camera_ops_type_t opcode)
56{
57    switch(opcode) {
58    case MM_CAMERA_OPS_PREVIEW:
59        return MM_CAMERA_CH_PREVIEW;
60    case MM_CAMERA_OPS_ZSL:
61    case MM_CAMERA_OPS_SNAPSHOT:
62        return MM_CAMERA_CH_SNAPSHOT;
63    case MM_CAMERA_OPS_PREPARE_SNAPSHOT:
64        return MM_CAMERA_CH_SNAPSHOT;
65    case MM_CAMERA_OPS_RAW:
66        return MM_CAMERA_CH_RAW;
67    default:
68        break;
69    }
70    return -1;
71}
72
73const char *mm_camera_util_get_dev_name(mm_camera_obj_t * my_obj)
74{
75    CDBG("%s: Returning %s at index :%d\n",
76        __func__,g_cam_ctrl.camera[my_obj->my_id].video_dev_name,my_obj->my_id);
77    return g_cam_ctrl.camera[my_obj->my_id].video_dev_name;
78}
79
80/* used for querying the camera_info of the given camera_id */
81static const camera_info_t * mm_camera_cfg_query_camera_info (int8_t camera_id)
82{
83    if(camera_id >= MSM_MAX_CAMERA_SENSORS)
84        return NULL;
85    return &g_cam_ctrl.camera[camera_id].camera_info;
86}
87/* check if the parm is supported */
88static uint8_t mm_camera_cfg_is_parm_supported (mm_camera_t * camera,
89                                                mm_camera_parm_type_t parm_type)
90{
91    int is_parm_supported = 0;
92    mm_camera_obj_t * my_obj = NULL;
93
94    pthread_mutex_lock(&g_mutex);
95    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
96    pthread_mutex_unlock(&g_mutex);
97    if(my_obj) {
98        pthread_mutex_lock(&my_obj->mutex);
99        is_parm_supported = GET_PARM_BIT32(parm_type,
100                                           my_obj->properties.parm);
101        pthread_mutex_unlock(&my_obj->mutex);
102    }
103
104    return is_parm_supported;
105}
106
107/* check if the channel is supported */
108static uint8_t mm_camera_cfg_is_ch_supported (mm_camera_t * camera,
109                                  mm_camera_channel_type_t ch_type)
110{
111    switch(ch_type) {
112    case MM_CAMERA_CH_PREVIEW:
113    case MM_CAMERA_CH_VIDEO:
114    case MM_CAMERA_CH_SNAPSHOT:
115    case MM_CAMERA_CH_RAW:
116        return TRUE;
117    case MM_CAMERA_CH_MAX:
118    default:
119        return FALSE;
120    }
121    return FALSE;
122}
123
124/* set a parms current value */
125static int32_t mm_camera_cfg_set_parm (mm_camera_t * camera,
126                                       mm_camera_parm_type_t parm_type,
127                                       void *p_value)
128{
129    int32_t rc = -MM_CAMERA_E_GENERAL;
130    uint32_t tmp;
131    mm_camera_obj_t * my_obj = NULL;
132    mm_camera_parm_t parm = {.parm_type = parm_type, .p_value = p_value};
133
134    pthread_mutex_lock(&g_mutex);
135    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
136    pthread_mutex_unlock(&g_mutex);
137    if(my_obj) {
138        pthread_mutex_lock(&my_obj->mutex);
139        rc = mm_camera_set_parm(my_obj, &parm);
140        pthread_mutex_unlock(&my_obj->mutex);
141    }
142    return rc;
143}
144
145/* get a parms current value */
146static int32_t mm_camera_cfg_get_parm (mm_camera_t * camera,
147                                       mm_camera_parm_type_t parm_type,
148                                       void* p_value)
149{
150    int32_t rc = -MM_CAMERA_E_GENERAL;
151    uint32_t tmp;
152    mm_camera_obj_t * my_obj = NULL;
153    mm_camera_parm_t parm = {.parm_type = parm_type, .p_value = p_value};
154
155    pthread_mutex_lock(&g_mutex);
156    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
157    pthread_mutex_unlock(&g_mutex);
158    if(my_obj) {
159        pthread_mutex_lock(&my_obj->mutex);
160        rc =  mm_camera_get_parm(my_obj, &parm);
161        pthread_mutex_unlock(&my_obj->mutex);
162    }
163    return rc;
164}
165
166static int32_t mm_camera_cfg_request_buf(mm_camera_t * camera,
167                                         mm_camera_reg_buf_t *buf)
168{
169    int32_t rc = -MM_CAMERA_E_GENERAL;
170    uint32_t tmp;
171    mm_camera_obj_t * my_obj = NULL;
172
173    pthread_mutex_lock(&g_mutex);
174    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
175    pthread_mutex_unlock(&g_mutex);
176    if(my_obj) {
177        pthread_mutex_lock(&my_obj->mutex);
178        rc =  mm_camera_request_buf(my_obj, buf);
179        pthread_mutex_unlock(&my_obj->mutex);
180    }
181    return rc;
182}
183
184static int32_t mm_camera_cfg_enqueue_buf(mm_camera_t * camera,
185                                         mm_camera_reg_buf_t *buf)
186{
187    int32_t rc = -MM_CAMERA_E_GENERAL;
188    uint32_t tmp;
189    mm_camera_obj_t * my_obj = NULL;
190
191    pthread_mutex_lock(&g_mutex);
192    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
193    pthread_mutex_unlock(&g_mutex);
194    if(my_obj) {
195        pthread_mutex_lock(&my_obj->mutex);
196        rc =  mm_camera_enqueue_buf(my_obj, buf);
197        pthread_mutex_unlock(&my_obj->mutex);
198    }
199    return rc;
200}
201
202static int32_t mm_camera_cfg_prepare_buf(mm_camera_t * camera,
203                                         mm_camera_reg_buf_t *buf)
204{
205    int32_t rc = -MM_CAMERA_E_GENERAL;
206    uint32_t tmp;
207    mm_camera_obj_t * my_obj = NULL;
208
209    pthread_mutex_lock(&g_mutex);
210    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
211    pthread_mutex_unlock(&g_mutex);
212    if(my_obj) {
213        pthread_mutex_lock(&my_obj->mutex);
214        rc =  mm_camera_prepare_buf(my_obj, buf);
215        pthread_mutex_unlock(&my_obj->mutex);
216    }
217    return rc;
218}
219static int32_t mm_camera_cfg_unprepare_buf(mm_camera_t * camera,
220                                           mm_camera_channel_type_t ch_type)
221{
222    int32_t rc = -MM_CAMERA_E_GENERAL;
223    uint32_t tmp;
224    mm_camera_obj_t * my_obj = NULL;
225
226    pthread_mutex_lock(&g_mutex);
227    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
228    pthread_mutex_unlock(&g_mutex);
229    if(my_obj) {
230        pthread_mutex_lock(&my_obj->mutex);
231        rc =  mm_camera_unprepare_buf(my_obj,ch_type);
232        pthread_mutex_unlock(&my_obj->mutex);
233    }
234    return rc;
235}
236
237static mm_camera_config_t mm_camera_cfg = {
238  .is_parm_supported = mm_camera_cfg_is_parm_supported,
239  .is_ch_supported = mm_camera_cfg_is_ch_supported,
240  .set_parm = mm_camera_cfg_set_parm,
241  .get_parm = mm_camera_cfg_get_parm,
242  .request_buf = mm_camera_cfg_request_buf,
243  .enqueue_buf = mm_camera_cfg_enqueue_buf,
244  .prepare_buf = mm_camera_cfg_prepare_buf,
245  .unprepare_buf = mm_camera_cfg_unprepare_buf
246};
247
248static uint8_t mm_camera_ops_is_op_supported (mm_camera_t * camera,
249                                              mm_camera_ops_type_t opcode)
250{
251    uint8_t is_ops_supported;
252    mm_camera_obj_t * my_obj = NULL;
253    int index = 0;
254    mm_camera_legacy_ops_type_t legacy_opcode = CAMERA_OPS_MAX;
255
256    /* Temp: We will be translating our new opcode
257       to legacy ops type. This is just a hack to
258       temporarily unblock APT team. New design is
259       under discussion */
260    switch (opcode) {
261    case MM_CAMERA_OPS_PREVIEW:
262        legacy_opcode = CAMERA_OPS_STREAMING_PREVIEW;
263        break;
264    case MM_CAMERA_OPS_VIDEO:
265        legacy_opcode = CAMERA_OPS_STREAMING_VIDEO;
266        break;
267    case MM_CAMERA_OPS_PREPARE_SNAPSHOT:
268        legacy_opcode = CAMERA_OPS_PREPARE_SNAPSHOT;
269        break;
270    case MM_CAMERA_OPS_SNAPSHOT:
271        legacy_opcode = CAMERA_OPS_SNAPSHOT;
272        break;
273    case MM_CAMERA_OPS_RAW:
274        legacy_opcode = CAMERA_OPS_RAW_CAPTURE;
275        break;
276    case MM_CAMERA_OPS_ZSL:
277        legacy_opcode = CAMERA_OPS_STREAMING_ZSL;
278        break;
279    case MM_CAMERA_OPS_FOCUS:
280        legacy_opcode = CAMERA_OPS_FOCUS;
281        break;
282    case MM_CAMERA_OPS_GET_BUFFERED_FRAME:
283      legacy_opcode = CAMERA_OPS_LOCAL;
284      is_ops_supported = TRUE;
285      CDBG("MM_CAMERA_OPS_GET_BUFFERED_FRAME not handled");
286      break;
287    default:
288      CDBG_ERROR("%s: case %d not handled", __func__, opcode);
289      legacy_opcode = CAMERA_OPS_LOCAL;
290      is_ops_supported = FALSE;
291      break;
292    }
293    if (legacy_opcode != CAMERA_OPS_LOCAL) {
294    pthread_mutex_lock(&g_mutex);
295    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
296    pthread_mutex_unlock(&g_mutex);
297    if(my_obj) {
298        pthread_mutex_lock(&my_obj->mutex);
299        index = legacy_opcode/32;  /* 32 bits */
300        is_ops_supported = ((my_obj->properties.ops[index] &
301            (1<<legacy_opcode)) != 0);
302        pthread_mutex_unlock(&my_obj->mutex);
303      } else {
304        is_ops_supported = FALSE;
305      }
306    }
307
308    return is_ops_supported;
309}
310
311static int32_t mm_camera_ops_action (mm_camera_t * camera, uint8_t start,
312                                    mm_camera_ops_type_t opcode, void *val)
313{
314    int32_t rc = -MM_CAMERA_E_GENERAL;
315    mm_camera_obj_t * my_obj = NULL;
316    pthread_mutex_lock(&g_mutex);
317    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
318    pthread_mutex_unlock(&g_mutex);
319    if(my_obj) {
320        pthread_mutex_lock(&my_obj->mutex);
321        rc = mm_camera_action(my_obj, start, opcode, val);
322        pthread_mutex_unlock(&my_obj->mutex);
323    }
324    return rc;
325}
326
327/* open uses flags to optionally disable jpeg/vpe interface. */
328static int32_t mm_camera_ops_open (mm_camera_t * camera,
329                                   mm_camera_op_mode_type_t op_mode)
330{
331    int8_t camera_id = camera->camera_info.camera_id;
332    int32_t rc = MM_CAMERA_OK;
333
334    CDBG("%s: BEGIN\n", __func__);
335    pthread_mutex_lock(&g_mutex);
336    /* not first open */
337    if(g_cam_ctrl.cam_obj[camera_id]) {
338        g_cam_ctrl.cam_obj[camera_id]->ref_count++;
339    CDBG("%s:  opened alreadyn", __func__);
340        goto end;
341    }
342    g_cam_ctrl.cam_obj[camera_id] =
343    (mm_camera_obj_t *)malloc(sizeof(mm_camera_obj_t));
344    if(!g_cam_ctrl.cam_obj[camera_id]) {
345        rc = -MM_CAMERA_E_NO_MEMORY;
346     CDBG("%s:  no mem", __func__);
347       goto end;
348    }
349    memset(g_cam_ctrl.cam_obj[camera_id], 0,
350                 sizeof(mm_camera_obj_t));
351    //g_cam_ctrl.cam_obj[camera_id]->ctrl_fd = -1;
352    g_cam_ctrl.cam_obj[camera_id]->ref_count++;
353    g_cam_ctrl.cam_obj[camera_id]->my_id=camera_id;
354
355    pthread_mutex_init(&g_cam_ctrl.cam_obj[camera_id]->mutex, NULL);
356    rc = mm_camera_open(g_cam_ctrl.cam_obj[camera_id], op_mode);
357    if(rc < 0) {
358        CDBG("%s: open failed, rc = %d\n", __func__, rc);
359        pthread_mutex_destroy(&g_cam_ctrl.cam_obj[camera_id]->mutex);
360        g_cam_ctrl.cam_obj[camera_id]->ref_count--;
361        free(g_cam_ctrl.cam_obj[camera_id]);
362        g_cam_ctrl.cam_obj[camera_id]=NULL;
363    CDBG("%s: mm_camera_open err = %d", __func__, rc);
364        goto end;
365    }else{
366        CDBG("%s: open succeded\n", __func__);
367    }
368end:
369    pthread_mutex_unlock(&g_mutex);
370    CDBG("%s: END, rc=%d\n", __func__, rc);
371    return rc;
372}
373
374static void mm_camera_ops_close (mm_camera_t * camera)
375{
376    mm_camera_obj_t * my_obj;
377    int i;
378    int8_t camera_id = camera->camera_info.camera_id;
379
380    pthread_mutex_lock(&g_mutex);
381    my_obj = g_cam_ctrl.cam_obj[camera_id];
382    if(my_obj) {
383      my_obj->ref_count--;
384      if(my_obj->ref_count > 0) {
385        CDBG("%s: ref_count=%d\n", __func__, my_obj->ref_count);
386      } else {
387        mm_camera_poll_thread_release(my_obj, MM_CAMERA_CH_MAX);
388        (void)mm_camera_close(g_cam_ctrl.cam_obj[camera_id]);
389        pthread_mutex_destroy(&my_obj->mutex);
390        free(my_obj);
391        g_cam_ctrl.cam_obj[camera_id] = NULL;
392      }
393    }
394    pthread_mutex_unlock(&g_mutex);
395}
396
397static int32_t mm_camera_ops_ch_acquire(mm_camera_t * camera,
398                                        mm_camera_channel_type_t ch_type)
399{
400    int32_t rc = -MM_CAMERA_E_GENERAL;
401    mm_camera_obj_t * my_obj = NULL;
402    pthread_mutex_lock(&g_mutex);
403    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
404    pthread_mutex_unlock(&g_mutex);
405    if(my_obj) {
406        pthread_mutex_lock(&my_obj->mutex);
407        rc = mm_camera_ch_acquire(my_obj, ch_type);
408        pthread_mutex_unlock(&my_obj->mutex);
409    }
410    return rc;
411
412}
413static void mm_camera_ops_ch_release(mm_camera_t * camera, mm_camera_channel_type_t ch_type)
414{
415    mm_camera_obj_t * my_obj = NULL;
416    pthread_mutex_lock(&g_mutex);
417    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
418    pthread_mutex_unlock(&g_mutex);
419    if(my_obj) {
420        pthread_mutex_lock(&my_obj->mutex);
421        mm_camera_ch_release(my_obj, ch_type);
422        pthread_mutex_unlock(&my_obj->mutex);
423    }
424}
425
426static int32_t mm_camera_ops_ch_attr(mm_camera_t * camera,
427                                     mm_camera_channel_type_t ch_type,
428                                     mm_camera_channel_attr_t *attr)
429{
430    mm_camera_obj_t * my_obj = NULL;
431    int32_t rc = -MM_CAMERA_E_GENERAL;
432    pthread_mutex_lock(&g_mutex);
433    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
434    pthread_mutex_unlock(&g_mutex);
435    if(my_obj) {
436        pthread_mutex_lock(&my_obj->mutex);
437        rc = mm_camera_ch_fn(my_obj, ch_type, MM_CAMERA_STATE_EVT_ATTR,
438                            (void *)attr);
439        pthread_mutex_unlock(&my_obj->mutex);
440    }
441    return rc;
442}
443
444static int32_t mm_camera_ops_sendmsg(mm_camera_t * camera,
445                                     void *msg,
446                                     uint32_t buf_size,
447                                     int sendfd)
448{
449    int32_t rc = -MM_CAMERA_E_GENERAL;
450    mm_camera_obj_t * my_obj = NULL;
451    pthread_mutex_lock(&g_mutex);
452    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
453    pthread_mutex_unlock(&g_mutex);
454    if(my_obj) {
455        pthread_mutex_lock(&my_obj->mutex);
456        rc = mm_camera_sendmsg(my_obj, msg, buf_size, sendfd);
457        pthread_mutex_unlock(&my_obj->mutex);
458    }
459    return rc;
460}
461
462static mm_camera_ops_t mm_camera_ops = {
463  .is_op_supported = mm_camera_ops_is_op_supported,
464    .action = mm_camera_ops_action,
465    .open = mm_camera_ops_open,
466    .close = mm_camera_ops_close,
467    .ch_acquire = mm_camera_ops_ch_acquire,
468    .ch_release = mm_camera_ops_ch_release,
469    .ch_set_attr = mm_camera_ops_ch_attr,
470    .sendmsg = mm_camera_ops_sendmsg
471};
472
473static uint8_t mm_camera_notify_is_event_supported(mm_camera_t * camera,
474                                mm_camera_event_type_t evt_type)
475{
476  switch(evt_type) {
477  case MM_CAMERA_EVT_TYPE_CH:
478  case MM_CAMERA_EVT_TYPE_CTRL:
479  case MM_CAMERA_EVT_TYPE_STATS:
480  case MM_CAMERA_EVT_TYPE_INFO:
481    return 1;
482  default:
483    return 0;
484  }
485  return 0;
486}
487
488static int32_t mm_camera_notify_register_event_cb(mm_camera_t * camera,
489                                   mm_camera_event_notify_t evt_cb,
490                                    void * user_data,
491                                   mm_camera_event_type_t evt_type)
492{
493  mm_camera_obj_t * my_obj = NULL;
494  mm_camera_buf_cb_t reg ;
495  int rc = -1;
496
497  pthread_mutex_lock(&g_mutex);
498  my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
499  pthread_mutex_unlock(&g_mutex);
500  if(my_obj) {
501      pthread_mutex_lock(&my_obj->mutex);
502      rc = mm_camera_reg_event(my_obj, evt_cb, user_data, evt_type);
503      pthread_mutex_unlock(&my_obj->mutex);
504  }
505  return rc;
506}
507
508static int32_t mm_camera_register_buf_notify (
509          mm_camera_t * camera,
510          mm_camera_channel_type_t ch_type,
511          mm_camera_buf_notify_t  buf_cb,
512          mm_camera_register_buf_cb_type_t cb_type,
513          uint32_t cb_count,
514          void * user_data)
515{
516    mm_camera_obj_t * my_obj = NULL;
517    mm_camera_buf_cb_t reg ;
518    int rc = -1;
519
520    reg.cb = buf_cb;
521    reg.user_data = user_data;
522    reg.cb_type=cb_type;
523    reg.cb_count=cb_count;
524    pthread_mutex_lock(&g_mutex);
525    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
526    pthread_mutex_unlock(&g_mutex);
527    if(my_obj) {
528        pthread_mutex_lock(&my_obj->mutex);
529        rc = mm_camera_ch_fn(my_obj,ch_type,
530                            MM_CAMERA_STATE_EVT_REG_BUF_CB, (void *)&reg);
531        pthread_mutex_unlock(&my_obj->mutex);
532    }
533    return rc;
534}
535static int32_t mm_camera_buf_done(mm_camera_t * camera, mm_camera_ch_data_buf_t * bufs)
536{
537    mm_camera_obj_t * my_obj = NULL;
538    int rc = -1;
539    my_obj = g_cam_ctrl.cam_obj[camera->camera_info.camera_id];
540    if(my_obj) {
541        /*pthread_mutex_lock(&my_obj->mutex);*/
542        rc = mm_camera_ch_fn(my_obj, bufs->type,
543                 MM_CAMERA_STATE_EVT_QBUF,   (void *)bufs);
544        /*pthread_mutex_unlock(&my_obj->mutex);*/
545    }
546    return rc;
547}
548
549static mm_camera_notify_t mm_camera_notify = {
550    .is_event_supported = mm_camera_notify_is_event_supported,
551    .register_event_notify = mm_camera_notify_register_event_cb,
552    .register_buf_notify = mm_camera_register_buf_notify,
553    .buf_done = mm_camera_buf_done
554};
555
556static uint8_t mm_camera_jpeg_is_jpeg_supported (mm_camera_t * camera)
557{
558    return FALSE;
559}
560static int32_t mm_camera_jpeg_set_parm (mm_camera_t * camera,
561                    mm_camera_jpeg_parm_type_t parm_type,
562                    void* p_value)
563{
564    return -1;
565}
566static int32_t mm_camera_jpeg_get_parm (mm_camera_t * camera,
567                    mm_camera_jpeg_parm_type_t parm_type,
568                    void* p_value)
569{
570    return -1;
571}
572static int32_t mm_camera_jpeg_register_event_cb(mm_camera_t * camera,
573                    mm_camera_jpeg_cb_t * evt_cb,
574                    void * user_data)
575{
576    return -1;
577}
578static int32_t mm_camera_jpeg_encode (mm_camera_t * camera, uint8_t start,
579                    mm_camera_jpeg_encode_t *data)
580{
581    return -1;
582}
583
584static mm_camera_jpeg_t mm_camera_jpeg =  {
585    .is_jpeg_supported = mm_camera_jpeg_is_jpeg_supported,
586    .set_parm = mm_camera_jpeg_set_parm,
587    .get_parm = mm_camera_jpeg_get_parm,
588    .register_event_cb = mm_camera_jpeg_register_event_cb,
589    .encode = mm_camera_jpeg_encode,
590};
591
592extern mm_camera_t * mm_camera_query (uint8_t *num_cameras)
593{
594    int i = 0, rc = MM_CAMERA_OK;
595    int dev_fd = 0;
596    struct media_device_info mdev_info;
597    int num_media_devices = 0;
598    if (!num_cameras)
599      return NULL;
600    /* lock the mutex */
601    pthread_mutex_lock(&g_mutex);
602    *num_cameras = 0;
603    while (1) {
604      char dev_name[32];
605      snprintf(dev_name, sizeof(dev_name), "/dev/media%d", num_media_devices);
606      dev_fd = open(dev_name, O_RDWR | O_NONBLOCK);
607      if (dev_fd < 0) {
608        CDBG("Done discovering media devices\n");
609        break;
610      }
611      num_media_devices++;
612      rc = ioctl(dev_fd, MEDIA_IOC_DEVICE_INFO, &mdev_info);
613      if (rc < 0) {
614        CDBG_ERROR("Error: ioctl media_dev failed: %s\n", strerror(errno));
615        close(dev_fd);
616        break;
617      }
618
619      if(strncmp(mdev_info.model, QCAMERA_NAME, sizeof(mdev_info.model) != 0)) {
620        close(dev_fd);
621        continue;
622      }
623
624      char * mdev_cfg;
625      int cam_type = 0, mount_angle = 0, info_index = 0;
626      mdev_cfg = strtok(mdev_info.serial, "-");
627      while(mdev_cfg != NULL) {
628          if(info_index == 0) {
629              if(strcmp(mdev_cfg, QCAMERA_NAME))
630                  break;
631          } else if(info_index == 1) {
632              mount_angle = atoi(mdev_cfg);
633          } else if(info_index == 2) {
634              cam_type = atoi(mdev_cfg);
635          }
636          mdev_cfg = strtok(NULL, "-");
637          info_index++;
638      }
639
640      if(info_index == 0) {
641          close(dev_fd);
642          continue;
643      }
644
645      int num_entities = 1;
646      while (1) {
647        struct media_entity_desc entity;
648        memset(&entity, 0, sizeof(entity));
649        entity.id = num_entities++;
650        rc = ioctl(dev_fd, MEDIA_IOC_ENUM_ENTITIES, &entity);
651        if (rc < 0) {
652            CDBG("Done enumerating media entities\n");
653            rc = 0;
654            break;
655        }
656        if(entity.type == MEDIA_ENT_T_DEVNODE_V4L && entity.group_id == QCAMERA_VNODE_GROUP_ID) {
657             strncpy(g_cam_ctrl.camera[*num_cameras].video_dev_name,
658                     entity.name, sizeof(entity.name));
659             break;
660        }
661      }
662
663      g_cam_ctrl.camera[*num_cameras].camera_info.camera_id = *num_cameras;
664
665      g_cam_ctrl.camera[*num_cameras].
666          camera_info.modes_supported = CAMERA_MODE_2D;
667      if(cam_type > 1)
668        g_cam_ctrl.camera[*num_cameras].
669          camera_info.modes_supported |= CAMERA_MODE_3D;
670
671      g_cam_ctrl.camera[*num_cameras].camera_info.position =
672        (cam_type == 1) ? FRONT_CAMERA : BACK_CAMERA;
673      g_cam_ctrl.camera[*num_cameras].camera_info.sensor_mount_angle =
674          mount_angle;
675      g_cam_ctrl.camera[*num_cameras].sensor_type = 0;
676      g_cam_ctrl.camera[*num_cameras].cfg = &mm_camera_cfg;
677      g_cam_ctrl.camera[*num_cameras].ops = &mm_camera_ops;
678      g_cam_ctrl.camera[*num_cameras].evt = &mm_camera_notify;
679      g_cam_ctrl.camera[*num_cameras].jpeg_ops = NULL;
680
681      CDBG("%s: dev_info[id=%d,name='%s',pos=%d,modes=0x%x,sensor=%d]\n",
682        __func__, *num_cameras,
683        g_cam_ctrl.camera[*num_cameras].video_dev_name,
684        g_cam_ctrl.camera[*num_cameras].camera_info.position,
685        g_cam_ctrl.camera[*num_cameras].camera_info.modes_supported,
686        g_cam_ctrl.camera[*num_cameras].sensor_type);
687
688      *num_cameras+=1;
689      if (dev_fd > 0) {
690          close(dev_fd);
691      }
692    }
693    *num_cameras = *num_cameras;
694    g_cam_ctrl.num_cam = *num_cameras;
695end:
696    /* unlock the mutex */
697    pthread_mutex_unlock(&g_mutex);
698    CDBG("%s: num_cameras=%d\n", __func__, g_cam_ctrl.num_cam);
699    if(rc == 0)
700        return &g_cam_ctrl.camera[0];
701    else
702        return NULL;
703}
704
705
706static mm_camera_t * get_camera_by_id( int cam_id)
707{
708  mm_camera_t * mm_cam;
709  if( cam_id < 0 || cam_id >= g_cam_ctrl.num_cam) {
710     mm_cam = NULL;
711  } else {
712    mm_cam = & g_cam_ctrl.camera[cam_id];
713  }
714  return mm_cam;
715}
716
717/*configure methods*/
718uint8_t cam_config_is_parm_supported(
719  int cam_id,
720  mm_camera_parm_type_t parm_type)
721{
722  uint8_t rc = 0;
723  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
724  if (mm_cam && mm_cam->cfg) {
725    rc = mm_cam->cfg->is_parm_supported(mm_cam, parm_type);
726  }
727  return rc;
728}
729
730uint8_t cam_config_is_ch_supported(
731  int cam_id,
732  mm_camera_channel_type_t ch_type)
733{
734  uint8_t rc = 0;
735  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
736  if (mm_cam) {
737    rc = mm_cam->cfg->is_ch_supported(mm_cam, ch_type);
738  }
739  return rc;
740
741}
742
743/* set a parms current value */
744int32_t cam_config_set_parm(
745  int cam_id,
746  mm_camera_parm_type_t parm_type,
747  void* p_value)
748{
749  int32_t rc = -1;
750  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
751  if (mm_cam) {
752    rc = mm_cam->cfg->set_parm(mm_cam, parm_type, p_value);
753  }
754  return rc;
755}
756
757/* get a parms current value */
758int32_t cam_config_get_parm(
759  int cam_id,
760  mm_camera_parm_type_t parm_type,
761  void* p_value)
762{
763  int32_t rc = -1;
764  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
765  if (mm_cam) {
766    rc = mm_cam->cfg->get_parm(mm_cam, parm_type, p_value);
767  }
768  return rc;
769}
770
771int32_t cam_config_request_buf(int cam_id, mm_camera_reg_buf_t *buf)
772{
773
774  int32_t rc = -1;
775  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
776  if (mm_cam) {
777    rc = mm_cam->cfg->request_buf(mm_cam, buf);
778  }
779  return rc;
780}
781
782int32_t cam_config_enqueue_buf(int cam_id, mm_camera_reg_buf_t *buf)
783{
784
785  int32_t rc = -1;
786  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
787  if (mm_cam) {
788    rc = mm_cam->cfg->enqueue_buf(mm_cam, buf);
789  }
790  return rc;
791}
792
793int32_t cam_config_prepare_buf(int cam_id, mm_camera_reg_buf_t *buf)
794{
795
796  int32_t rc = -1;
797  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
798  if (mm_cam) {
799    rc = mm_cam->cfg->prepare_buf(mm_cam, buf);
800  }
801  return rc;
802}
803int32_t cam_config_unprepare_buf(int cam_id, mm_camera_channel_type_t ch_type)
804{
805  int32_t rc = -1;
806  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
807  if (mm_cam) {
808    rc = mm_cam->cfg->unprepare_buf(mm_cam, ch_type);
809  }
810  return rc;
811}
812
813/*operation methods*/
814uint8_t cam_ops_is_op_supported(int cam_id, mm_camera_ops_type_t opcode)
815{
816  uint8_t rc = 0;
817  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
818  if (mm_cam) {
819    rc = mm_cam->ops->is_op_supported(mm_cam, opcode);
820  }
821  return rc;
822}
823/* val is reserved for some action such as MM_CAMERA_OPS_FOCUS */
824int32_t cam_ops_action(int cam_id, uint8_t start,
825  mm_camera_ops_type_t opcode, void *val)
826{
827  int32_t rc = -1;
828  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
829  if (mm_cam) {
830    rc = mm_cam->ops->action(mm_cam, start, opcode, val);
831  }
832  return rc;
833}
834
835int32_t cam_ops_open(int cam_id, mm_camera_op_mode_type_t op_mode)
836{
837  int32_t rc = -1;
838  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
839  if (mm_cam) {
840    rc = mm_cam->ops->open(mm_cam, op_mode);
841  }
842  return rc;
843}
844
845void cam_ops_close(int cam_id)
846{
847  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
848  if (mm_cam) {
849    mm_cam->ops->close(mm_cam);
850  }
851}
852
853int32_t cam_ops_ch_acquire(int cam_id, mm_camera_channel_type_t ch_type)
854{
855  int32_t rc = -1;
856  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
857  if (mm_cam) {
858    rc = mm_cam->ops->ch_acquire(mm_cam, ch_type);
859  }
860  return rc;
861}
862
863void cam_ops_ch_release(int cam_id, mm_camera_channel_type_t ch_type)
864{
865  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
866  if (mm_cam) {
867    mm_cam->ops->ch_release(mm_cam, ch_type);
868  }
869}
870
871int32_t cam_ops_ch_set_attr(int cam_id, mm_camera_channel_type_t ch_type,
872  mm_camera_channel_attr_t *attr)
873{
874  int32_t rc = -1;
875  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
876  if (mm_cam) {
877    rc = mm_cam->ops->ch_set_attr(mm_cam, ch_type, attr);
878  }
879  return rc;
880}
881
882int32_t cam_ops_sendmsg(int cam_id, void *msg, uint32_t buf_size, int sendfd)
883{
884    int32_t rc = -1;
885    mm_camera_t * mm_cam = get_camera_by_id(cam_id);
886    if (mm_cam) {
887      rc = mm_cam->ops->sendmsg(mm_cam, msg, buf_size, sendfd);
888    }
889    return rc;
890}
891
892/*call-back notify methods*/
893uint8_t cam_evt_is_event_supported(int cam_id, mm_camera_event_type_t evt_type)
894{
895  uint8_t rc = 0;
896  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
897  if (mm_cam) {
898    rc = mm_cam->evt->is_event_supported(mm_cam, evt_type);
899  }
900  return rc;
901}
902
903int32_t cam_evt_register_event_notify(int cam_id,
904  mm_camera_event_notify_t evt_cb,
905  void * user_data,
906  mm_camera_event_type_t evt_type)
907{
908  int32_t rc = -1;
909  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
910  if (mm_cam) {
911    rc = mm_cam->evt->register_event_notify(
912      mm_cam, evt_cb, user_data, evt_type);
913  }
914  return rc;
915}
916
917int32_t cam_evt_register_buf_notify(int cam_id,
918  mm_camera_channel_type_t ch_type,
919  mm_camera_buf_notify_t buf_cb,
920  mm_camera_register_buf_cb_type_t cb_type,
921  uint32_t cb_count,
922  void * user_data)
923{
924  int32_t rc = -1;
925  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
926  if (mm_cam) {
927    rc = mm_cam->evt->register_buf_notify(
928      mm_cam, ch_type, buf_cb, cb_type,
929      cb_count, user_data);
930  }
931  return rc;
932}
933
934int32_t cam_evt_buf_done(int cam_id, mm_camera_ch_data_buf_t *bufs)
935{
936  int32_t rc = -1;
937  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
938  if (mm_cam) {
939    rc = mm_cam->evt->buf_done(mm_cam, bufs);
940  }
941  return rc;
942}
943
944/*camera JPEG methods*/
945uint8_t cam_jpeg_is_jpeg_supported(int cam_id)
946{
947  uint8_t rc = 0;
948  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
949  if (mm_cam) {
950    rc = mm_cam->jpeg_ops->is_jpeg_supported(mm_cam);
951  }
952  return rc;
953}
954
955int32_t cam_jpeg_set_parm(int cam_id, mm_camera_jpeg_parm_type_t parm_type,
956  void* p_value)
957{
958  int32_t rc = -1;
959  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
960  if (mm_cam) {
961    rc = mm_cam->jpeg_ops->set_parm(mm_cam, parm_type, p_value);
962  }
963  return rc;
964}
965
966int32_t cam_jpeg_get_parm(int cam_id, mm_camera_jpeg_parm_type_t parm_type,
967  void* p_value)
968{
969  int32_t rc = -1;
970  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
971  if (mm_cam) {
972    rc = mm_cam->jpeg_ops->get_parm(mm_cam, parm_type, p_value);
973  }
974  return rc;
975}
976int32_t cam_jpeg_register_event_cb(int cam_id, mm_camera_jpeg_cb_t * evt_cb,
977  void * user_data)
978{
979  int32_t rc = -1;
980  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
981  if (mm_cam) {
982    rc = mm_cam->jpeg_ops->register_event_cb(mm_cam, evt_cb, user_data);
983  }
984  return rc;
985}
986int32_t cam_jpeg_encode(int cam_id, uint8_t start,
987  mm_camera_jpeg_encode_t *data)
988{
989  int32_t rc = -1;
990  mm_camera_t * mm_cam = get_camera_by_id(cam_id);
991  if (mm_cam) {
992    rc = mm_cam->jpeg_ops->encode(mm_cam, start, data);
993  }
994  return rc;
995}
996
997