1 /*
2 Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
3
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are
6 met:
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
17 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
18 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
20 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
21 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
24 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
26 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 IF 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
50 static pthread_mutex_t g_mutex = PTHREAD_MUTEX_INITIALIZER;
51
52 static mm_camera_ctrl_t g_cam_ctrl;
53
mm_camera_util_opcode_2_ch_type(mm_camera_obj_t * my_obj,mm_camera_ops_type_t opcode)54 static 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
mm_camera_util_get_dev_name(mm_camera_obj_t * my_obj)73 const 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 */
mm_camera_cfg_query_camera_info(int8_t camera_id)81 static 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 */
mm_camera_cfg_is_parm_supported(mm_camera_t * camera,mm_camera_parm_type_t parm_type)88 static 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 */
mm_camera_cfg_is_ch_supported(mm_camera_t * camera,mm_camera_channel_type_t ch_type)108 static 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 parm�s current value */
mm_camera_cfg_set_parm(mm_camera_t * camera,mm_camera_parm_type_t parm_type,void * p_value)125 static 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 parm�s current value */
mm_camera_cfg_get_parm(mm_camera_t * camera,mm_camera_parm_type_t parm_type,void * p_value)146 static 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
mm_camera_cfg_request_buf(mm_camera_t * camera,mm_camera_reg_buf_t * buf)166 static 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
mm_camera_cfg_enqueue_buf(mm_camera_t * camera,mm_camera_reg_buf_t * buf)184 static 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
mm_camera_cfg_prepare_buf(mm_camera_t * camera,mm_camera_reg_buf_t * buf)202 static 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 }
mm_camera_cfg_unprepare_buf(mm_camera_t * camera,mm_camera_channel_type_t ch_type)219 static 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
237 static 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
mm_camera_ops_is_op_supported(mm_camera_t * camera,mm_camera_ops_type_t opcode)248 static 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
mm_camera_ops_action(mm_camera_t * camera,uint8_t start,mm_camera_ops_type_t opcode,void * val)311 static 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. */
mm_camera_ops_open(mm_camera_t * camera,mm_camera_op_mode_type_t op_mode)328 static 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 }
368 end:
369 pthread_mutex_unlock(&g_mutex);
370 CDBG("%s: END, rc=%d\n", __func__, rc);
371 return rc;
372 }
373
mm_camera_ops_close(mm_camera_t * camera)374 static 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
mm_camera_ops_ch_acquire(mm_camera_t * camera,mm_camera_channel_type_t ch_type)397 static 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 }
mm_camera_ops_ch_release(mm_camera_t * camera,mm_camera_channel_type_t ch_type)413 static 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
mm_camera_ops_ch_attr(mm_camera_t * camera,mm_camera_channel_type_t ch_type,mm_camera_channel_attr_t * attr)426 static 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
mm_camera_ops_sendmsg(mm_camera_t * camera,void * msg,uint32_t buf_size,int sendfd)444 static 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
462 static 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
mm_camera_notify_is_event_supported(mm_camera_t * camera,mm_camera_event_type_t evt_type)473 static 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
mm_camera_notify_register_event_cb(mm_camera_t * camera,mm_camera_event_notify_t evt_cb,void * user_data,mm_camera_event_type_t evt_type)488 static 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
mm_camera_register_buf_notify(mm_camera_t * camera,mm_camera_channel_type_t ch_type,mm_camera_buf_notify_t buf_cb,mm_camera_register_buf_cb_type_t cb_type,uint32_t cb_count,void * user_data)508 static 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 *)®);
531 pthread_mutex_unlock(&my_obj->mutex);
532 }
533 return rc;
534 }
mm_camera_buf_done(mm_camera_t * camera,mm_camera_ch_data_buf_t * bufs)535 static 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
549 static 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
mm_camera_jpeg_is_jpeg_supported(mm_camera_t * camera)556 static uint8_t mm_camera_jpeg_is_jpeg_supported (mm_camera_t * camera)
557 {
558 return FALSE;
559 }
mm_camera_jpeg_set_parm(mm_camera_t * camera,mm_camera_jpeg_parm_type_t parm_type,void * p_value)560 static 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 }
mm_camera_jpeg_get_parm(mm_camera_t * camera,mm_camera_jpeg_parm_type_t parm_type,void * p_value)566 static 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 }
mm_camera_jpeg_register_event_cb(mm_camera_t * camera,mm_camera_jpeg_cb_t * evt_cb,void * user_data)572 static 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 }
mm_camera_jpeg_encode(mm_camera_t * camera,uint8_t start,mm_camera_jpeg_encode_t * data)578 static 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
584 static 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
mm_camera_query(uint8_t * num_cameras)592 extern 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;
695 end:
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
get_camera_by_id(int cam_id)706 static 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*/
cam_config_is_parm_supported(int cam_id,mm_camera_parm_type_t parm_type)718 uint8_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
cam_config_is_ch_supported(int cam_id,mm_camera_channel_type_t ch_type)730 uint8_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 parm�s current value */
cam_config_set_parm(int cam_id,mm_camera_parm_type_t parm_type,void * p_value)744 int32_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 parm�s current value */
cam_config_get_parm(int cam_id,mm_camera_parm_type_t parm_type,void * p_value)758 int32_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
cam_config_request_buf(int cam_id,mm_camera_reg_buf_t * buf)771 int32_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
cam_config_enqueue_buf(int cam_id,mm_camera_reg_buf_t * buf)782 int32_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
cam_config_prepare_buf(int cam_id,mm_camera_reg_buf_t * buf)793 int32_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 }
cam_config_unprepare_buf(int cam_id,mm_camera_channel_type_t ch_type)803 int32_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*/
cam_ops_is_op_supported(int cam_id,mm_camera_ops_type_t opcode)814 uint8_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 */
cam_ops_action(int cam_id,uint8_t start,mm_camera_ops_type_t opcode,void * val)824 int32_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
cam_ops_open(int cam_id,mm_camera_op_mode_type_t op_mode)835 int32_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
cam_ops_close(int cam_id)845 void 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
cam_ops_ch_acquire(int cam_id,mm_camera_channel_type_t ch_type)853 int32_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
cam_ops_ch_release(int cam_id,mm_camera_channel_type_t ch_type)863 void 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
cam_ops_ch_set_attr(int cam_id,mm_camera_channel_type_t ch_type,mm_camera_channel_attr_t * attr)871 int32_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
cam_ops_sendmsg(int cam_id,void * msg,uint32_t buf_size,int sendfd)882 int32_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*/
cam_evt_is_event_supported(int cam_id,mm_camera_event_type_t evt_type)893 uint8_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
cam_evt_register_event_notify(int cam_id,mm_camera_event_notify_t evt_cb,void * user_data,mm_camera_event_type_t evt_type)903 int32_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
cam_evt_register_buf_notify(int cam_id,mm_camera_channel_type_t ch_type,mm_camera_buf_notify_t buf_cb,mm_camera_register_buf_cb_type_t cb_type,uint32_t cb_count,void * user_data)917 int32_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
cam_evt_buf_done(int cam_id,mm_camera_ch_data_buf_t * bufs)934 int32_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*/
cam_jpeg_is_jpeg_supported(int cam_id)945 uint8_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
cam_jpeg_set_parm(int cam_id,mm_camera_jpeg_parm_type_t parm_type,void * p_value)955 int32_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
cam_jpeg_get_parm(int cam_id,mm_camera_jpeg_parm_type_t parm_type,void * p_value)966 int32_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 }
cam_jpeg_register_event_cb(int cam_id,mm_camera_jpeg_cb_t * evt_cb,void * user_data)976 int32_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 }
cam_jpeg_encode(int cam_id,uint8_t start,mm_camera_jpeg_encode_t * data)986 int32_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