libv4l2: Add support for exynos5430 devices
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos.git] / libv4l2 / exynos_v4l2.c
1 /*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 /*!
18 * \file exynos_v4l2.c
19 * \brief source file for libv4l2
20 * \author Jinsung Yang (jsgood.yang@samsung.com)
21 * \author Sangwoo Park (sw5771.park@samsung.com)
22 * \date 2012/01/17
23 *
24 * <b>Revision History: </b>
25 * - 2012/01/17: Jinsung Yang (jsgood.yang@samsung.com) \n
26 * Initial version
27 *
28 */
29
30 #include <stdio.h>
31 #include <errno.h>
32 #include <stdarg.h>
33 #include <fcntl.h>
34 #include <string.h>
35 #include <sys/types.h>
36 #include <sys/ioctl.h>
37 #include <sys/stat.h>
38
39 #include "exynos_v4l2.h"
40
41 //#define LOG_NDEBUG 0
42 #define LOG_TAG "libexynosv4l2"
43 #include <utils/Log.h>
44 #include "Exynos_log.h"
45
46 #define VIDEODEV_MINOR_MAX 69
47
48 //#define EXYNOS_V4L2_TRACE 0
49 #ifdef EXYNOS_V4L2_TRACE
50 #define Exynos_v4l2_In() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s In , Line: %d", __FUNCTION__, __LINE__)
51 #define Exynos_v4l2_Out() Exynos_Log(EXYNOS_DEV_LOG_DEBUG, LOG_TAG, "%s Out , Line: %d", __FUNCTION__, __LINE__)
52 #else
53 #define Exynos_v4l2_In() ((void *)0)
54 #define Exynos_v4l2_Out() ((void *)0)
55 #endif
56
57 static bool __v4l2_check_buf_type(enum v4l2_buf_type type)
58 {
59 bool supported;
60
61 switch (type) {
62 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
63 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
64 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
65 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
66 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
67 supported = true;
68 break;
69
70 default:
71 supported = (type >= V4L2_BUF_TYPE_PRIVATE) ? true : false;
72 break;
73 }
74
75 return supported;
76 }
77
78 static int __v4l2_open(const char *filename, int oflag, va_list ap)
79 {
80 mode_t mode = 0;
81 int fd;
82
83 if (oflag & O_CREAT)
84 mode = va_arg(ap, int);
85
86 fd = open(filename, oflag, mode);
87
88 return fd;
89 }
90
91 int exynos_v4l2_open(const char *filename, int oflag, ...)
92 {
93 va_list ap;
94 int fd;
95
96 Exynos_v4l2_In();
97
98 va_start(ap, oflag);
99 fd = __v4l2_open(filename, oflag, ap);
100 va_end(ap);
101
102 Exynos_v4l2_Out();
103
104 return fd;
105 }
106
107 int exynos_v4l2_open_devname(const char *devname, int oflag, ...)
108 {
109 bool found = false;
110 int fd = -1;
111 struct stat s;
112 va_list ap;
113 FILE *stream_fd;
114 char filename[64], name[64];
115 int minor, size, i = 0;
116
117 Exynos_v4l2_In();
118
119 do {
120 if (i > VIDEODEV_MINOR_MAX)
121 break;
122
123 /* video device node */
124 snprintf(filename, sizeof(filename), "/dev/video%d", i++);
125
126 /* if the node is video device */
127 if ((lstat(filename, &s) == 0) && S_ISCHR(s.st_mode) &&
128 ((int)((unsigned short)(s.st_rdev) >> 8) == 81)) {
129 minor = (int)((unsigned short)(s.st_rdev & 0x3f));
130 ALOGD("try node: %s, minor: %d", filename, minor);
131 /* open sysfs entry */
132 snprintf(filename, sizeof(filename), "/sys/class/video4linux/video%d/name", minor);
133 if (S_ISLNK(s.st_mode)) {
134 ALOGE("symbolic link detected");
135 return -1;
136 }
137 stream_fd = fopen(filename, "r");
138 if (stream_fd == NULL) {
139 ALOGE("failed to open sysfs entry for videodev");
140 continue; /* try next */
141 }
142
143 /* read sysfs entry for device name */
144 size = (int)fgets(name, sizeof(name), stream_fd);
145 fclose(stream_fd);
146
147 /* check read size */
148 if (size == 0) {
149 ALOGE("failed to read sysfs entry for videodev");
150 } else {
151 /* matched */
152 if (strncmp(name, devname, strlen(devname)) == 0) {
153 ALOGI("node found for device %s: /dev/video%d", devname, minor);
154 found = true;
155 }
156 }
157 }
158 } while (found == false);
159
160 if (found) {
161 snprintf(filename, sizeof(filename), "/dev/video%d", minor);
162 va_start(ap, oflag);
163 fd = __v4l2_open(filename, oflag, ap);
164 va_end(ap);
165
166 if (fd > 0)
167 ALOGI("open video device %s", filename);
168 else
169 ALOGE("failed to open video device %s", filename);
170 } else {
171 ALOGE("no video device found");
172 }
173
174 Exynos_v4l2_Out();
175
176 return fd;
177 }
178
179 int exynos_v4l2_close(int fd)
180 {
181 int ret = -1;
182
183 Exynos_v4l2_In();
184
185 if (fd < 0)
186 ALOGE("%s: invalid fd: %d", __func__, fd);
187 else
188 ret = close(fd);
189
190 Exynos_v4l2_Out();
191
192 return ret;
193 }
194
195 bool exynos_v4l2_enuminput(int fd, int index, char *input_name_buf)
196 {
197 int ret = -1;
198 struct v4l2_input input;
199
200 Exynos_v4l2_In();
201
202 if (fd < 0) {
203 ALOGE("%s: invalid fd: %d", __func__, fd);
204 return NULL;
205 }
206
207 input.index = index;
208 ret = ioctl(fd, VIDIOC_ENUMINPUT, &input, 32);
209 if (ret) {
210 ALOGE("%s: no matching index founds", __func__);
211 return false;
212 }
213
214 ALOGI("Name of input channel[%d] is %s", input.index, input.name);
215
216 strncpy(input_name_buf, (const char *)input.name, 32);
217
218 Exynos_v4l2_Out();
219
220 return true;
221 }
222
223 int exynos_v4l2_s_input(int fd, int index)
224 {
225 int ret = -1;
226 struct v4l2_input input;
227
228 Exynos_v4l2_In();
229
230 if (fd < 0) {
231 ALOGE("%s: invalid fd: %d", __func__, fd);
232 return ret;
233 }
234
235 input.index = index;
236
237 ret = ioctl(fd, VIDIOC_S_INPUT, &input);
238 if (ret){
239 ALOGE("failed to ioctl: VIDIOC_S_INPUT (%d - %s)", errno, strerror(errno));
240 return ret;
241 }
242
243 Exynos_v4l2_Out();
244
245 return ret;
246 }
247
248 bool exynos_v4l2_querycap(int fd, unsigned int need_caps)
249 {
250 struct v4l2_capability cap;
251 int ret;
252
253 Exynos_v4l2_In();
254
255 if (fd < 0) {
256 ALOGE("%s: invalid fd: %d", __func__, fd);
257 return false;
258 }
259
260 if (!(need_caps & V4L2_CAP_VIDEO_CAPTURE) &&
261 !(need_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) &&
262 !(need_caps & V4L2_CAP_VIDEO_OUTPUT) &&
263 !(need_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) &&
264 !(need_caps & V4L2_CAP_VIDEO_OVERLAY)) {
265 ALOGE("%s: unsupported capabilities", __func__);
266 return false;
267 }
268
269 memset(&cap, 0, sizeof(cap));
270
271 ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
272 if (ret) {
273 ALOGE("failed to ioctl: VIDIOC_QUERYCAP (%d - %s)", errno, strerror(errno));
274 return false;
275 }
276
277 if ((need_caps & cap.capabilities) != need_caps) {
278 ALOGE("%s: unsupported capabilities", __func__);
279 return false;
280 }
281
282 Exynos_v4l2_Out();
283
284 return true;
285 }
286
287 bool exynos_v4l2_enum_fmt(int fd, enum v4l2_buf_type type, unsigned int fmt)
288 {
289 struct v4l2_fmtdesc fmtdesc;
290 int found = 0;
291
292 Exynos_v4l2_In();
293
294 fmtdesc.type = type;
295 fmtdesc.index = 0;
296
297 while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
298 if (fmtdesc.pixelformat == fmt) {
299 ALOGE("Passed fmt = %#x found pixel format[%d]: %s", fmt, fmtdesc.index, fmtdesc.description);
300 found = 1;
301 break;
302 }
303
304 fmtdesc.index++;
305 }
306
307 if (!found) {
308 ALOGE("%s: unsupported pixel format", __func__);
309 return false;
310 }
311
312 Exynos_v4l2_Out();
313
314 return true;
315 }
316
317 int exynos_v4l2_g_fmt(int fd, struct v4l2_format *fmt)
318 {
319 int ret = -1;
320
321 Exynos_v4l2_In();
322
323 if (fd < 0) {
324 ALOGE("%s: invalid fd: %d", __func__, fd);
325 return ret;
326 }
327
328 if (!fmt) {
329 ALOGE("%s: fmt is NULL", __func__);
330 return ret;
331 }
332
333 if (__v4l2_check_buf_type(fmt->type) == false) {
334 ALOGE("%s: unsupported buffer type", __func__);
335 return ret;
336 }
337
338 ret = ioctl(fd, VIDIOC_G_FMT, fmt);
339 if (ret) {
340 ALOGE("failed to ioctl: VIDIOC_G_FMT (%d - %s)", errno, strerror(errno));
341 return ret;
342 }
343
344 Exynos_v4l2_Out();
345
346 return ret;
347 }
348
349 static int __v4l2_s_fmt(int fd, unsigned int request, struct v4l2_format *fmt)
350 {
351 int ret = -1;
352
353 Exynos_v4l2_In();
354
355 if (fd < 0) {
356 ALOGE("%s: invalid fd: %d", __func__, fd);
357 return ret;
358 }
359
360 if (!fmt) {
361 ALOGE("%s: fmt is NULL", __func__);
362 return ret;
363 }
364
365 if (__v4l2_check_buf_type(fmt->type) == false) {
366 ALOGE("%s: unsupported buffer type", __func__);
367 return ret;
368 } else {
369 ret = ioctl(fd, request, fmt);
370 if (ret) {
371 if (request == VIDIOC_TRY_FMT)
372 ALOGE("failed to ioctl: VIDIOC_TRY_FMT (%d - %s)", errno, strerror(errno));
373 else
374 ALOGE("failed to ioctl: VIDIOC_S_FMT (%d - %s)", errno, strerror(errno));
375
376 return ret;
377 }
378 }
379
380 Exynos_v4l2_Out();
381
382 return ret;
383 }
384
385 int exynos_v4l2_try_fmt(int fd, struct v4l2_format *fmt)
386 {
387 return __v4l2_s_fmt(fd, VIDIOC_TRY_FMT, fmt);
388 }
389
390 int exynos_v4l2_s_fmt(int fd, struct v4l2_format *fmt)
391 {
392 return __v4l2_s_fmt(fd, VIDIOC_S_FMT, fmt);
393 }
394
395 int exynos_v4l2_reqbufs(int fd, struct v4l2_requestbuffers *req)
396 {
397 int ret = -1;
398 unsigned int count;
399
400 Exynos_v4l2_In();
401
402 if (fd < 0) {
403 ALOGE("%s: invalid fd: %d", __func__, fd);
404 return ret;
405 }
406
407 if (!req) {
408 ALOGE("%s: req is NULL", __func__);
409 return ret;
410 }
411
412 if ((req->memory != V4L2_MEMORY_MMAP) &&
413 (req->memory != V4L2_MEMORY_USERPTR) &&
414 (req->memory != V4L2_MEMORY_DMABUF)) {
415 ALOGE("%s: unsupported memory type", __func__);
416 return ret;
417 }
418
419 if (__v4l2_check_buf_type(req->type) == false) {
420 ALOGE("%s: unsupported buffer type", __func__);
421 return ret;
422 }
423
424 count = req->count;
425
426 ret = ioctl(fd, VIDIOC_REQBUFS, req);
427 if (ret) {
428 ALOGE("failed to ioctl: VIDIOC_REQBUFS (%d - %s)", ret, strerror(errno));
429 return ret;
430 }
431
432 if (count != req->count) {
433 ALOGW("number of buffers had been changed: %d => %d", count, req->count);
434 }
435
436 Exynos_v4l2_Out();
437
438 return ret;
439 }
440
441 int exynos_v4l2_querybuf(int fd, struct v4l2_buffer *buf)
442 {
443 int ret = -1;
444
445 Exynos_v4l2_In();
446
447 if (fd < 0) {
448 ALOGE("%s: invalid fd: %d", __func__, fd);
449 return ret;
450 }
451
452 if (!buf) {
453 ALOGE("%s: buf is NULL", __func__);
454 return ret;
455 }
456
457 if ((buf->memory != V4L2_MEMORY_MMAP) &&
458 (buf->memory != V4L2_MEMORY_DMABUF)) {
459 ALOGE("%s: unsupported memory type", __func__);
460 return ret;
461 }
462
463 if (__v4l2_check_buf_type(buf->type) == false) {
464 ALOGE("%s: unsupported buffer type", __func__);
465 return ret;
466 }
467
468 ret = ioctl(fd, VIDIOC_QUERYBUF, buf);
469 if (ret) {
470 ALOGE("failed to ioctl: VIDIOC_QUERYBUF (%d - %s)", errno, strerror(errno));
471 return ret;
472 }
473
474 Exynos_v4l2_Out();
475
476 return ret;
477 }
478
479 int exynos_v4l2_qbuf(int fd, struct v4l2_buffer *buf)
480 {
481 int ret = -1;
482
483 Exynos_v4l2_In();
484
485 if (fd < 0) {
486 ALOGE("%s: invalid fd: %d", __func__, fd);
487 return ret;
488 }
489
490 if (!buf) {
491 ALOGE("%s: buf is NULL", __func__);
492 return ret;
493 }
494
495 if ((buf->memory != V4L2_MEMORY_MMAP) &&
496 (buf->memory != V4L2_MEMORY_USERPTR) &&
497 (buf->memory != V4L2_MEMORY_DMABUF)) {
498 ALOGE("%s: unsupported memory type", __func__);
499 return ret;
500 }
501
502 if (__v4l2_check_buf_type(buf->type) == false) {
503 ALOGE("%s: unsupported buffer type", __func__);
504 return ret;
505 }
506
507 ret = ioctl(fd, VIDIOC_QBUF, buf);
508 if (ret) {
509 ALOGE("failed to ioctl: VIDIOC_QBUF (%d - %s)", errno, strerror(errno));
510 return ret;
511 }
512
513 Exynos_v4l2_Out();
514
515 return ret;
516 }
517
518 int exynos_v4l2_dqbuf(int fd, struct v4l2_buffer *buf)
519 {
520 int ret = -1;
521
522 Exynos_v4l2_In();
523
524 if (fd < 0) {
525 ALOGE("%s: invalid fd: %d", __func__, fd);
526 return ret;
527 }
528
529 if (!buf) {
530 ALOGE("%s: buf is NULL", __func__);
531 return ret;
532 }
533
534 if ((buf->memory != V4L2_MEMORY_MMAP) &&
535 (buf->memory != V4L2_MEMORY_USERPTR) &&
536 (buf->memory != V4L2_MEMORY_DMABUF)) {
537 ALOGE("%s: unsupported memory type", __func__);
538 return ret;
539 }
540
541 if (__v4l2_check_buf_type(buf->type) == false) {
542 ALOGE("%s: unsupported buffer type", __func__);
543 return ret;
544 }
545
546 ret = ioctl(fd, VIDIOC_DQBUF, buf);
547 if (ret) {
548 if (errno == EAGAIN)
549 return -errno;
550
551 ALOGW("failed to ioctl: VIDIOC_DQBUF (%d - %s)", errno, strerror(errno));
552 return ret;
553 }
554
555 Exynos_v4l2_Out();
556
557 return ret;
558 }
559
560 int exynos_v4l2_streamon(int fd, enum v4l2_buf_type type)
561 {
562 int ret = -1;
563
564 Exynos_v4l2_In();
565
566 if (fd < 0) {
567 ALOGE("%s: invalid fd: %d", __func__, fd);
568 return ret;
569 }
570
571 if (__v4l2_check_buf_type(type) == false) {
572 ALOGE("%s: unsupported buffer type", __func__);
573 return ret;
574 }
575
576 ret = ioctl(fd, VIDIOC_STREAMON, &type);
577 if (ret) {
578 ALOGE("failed to ioctl: VIDIOC_STREAMON (%d - %s)", errno, strerror(errno));
579 return ret;
580 }
581
582 Exynos_v4l2_Out();
583
584 return ret;
585 }
586
587 int exynos_v4l2_streamoff(int fd, enum v4l2_buf_type type)
588 {
589 int ret = -1;
590
591 Exynos_v4l2_In();
592
593 if (fd < 0) {
594 ALOGE("%s: invalid fd: %d", __func__, fd);
595 return ret;
596 }
597
598 if (__v4l2_check_buf_type(type) == false) {
599 ALOGE("%s: unsupported buffer type", __func__);
600 return ret;
601 }
602
603 ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
604 if (ret) {
605 ALOGE("failed to ioctl: VIDIOC_STREAMOFF (%d - %s)", errno, strerror(errno));
606 return ret;
607 }
608
609 Exynos_v4l2_Out();
610
611 return ret;
612 }
613
614 int exynos_v4l2_cropcap(int fd, struct v4l2_cropcap *crop)
615 {
616 int ret = -1;
617
618 Exynos_v4l2_In();
619
620 if (fd < 0) {
621 ALOGE("%s: invalid fd: %d", __func__, fd);
622 return ret;
623 }
624
625 if (!crop) {
626 ALOGE("%s: crop is NULL", __func__);
627 return ret;
628 }
629
630 if (__v4l2_check_buf_type(crop->type) == false) {
631 ALOGE("%s: unsupported buffer type", __func__);
632 return ret;
633 }
634
635 ret = ioctl(fd, VIDIOC_CROPCAP, crop);
636 if (ret) {
637 ALOGE("failed to ioctl: VIDIOC_CROPCAP (%d - %s)", errno, strerror(errno));
638 return ret;
639 }
640
641 Exynos_v4l2_Out();
642
643 return ret;
644 }
645
646 int exynos_v4l2_g_crop(int fd, struct v4l2_crop *crop)
647 {
648 int ret = -1;
649
650 Exynos_v4l2_In();
651
652 if (fd < 0) {
653 ALOGE("%s: invalid fd: %d", __func__, fd);
654 return ret;
655 }
656
657 if (!crop) {
658 ALOGE("%s: crop is NULL", __func__);
659 return ret;
660 }
661
662 if (__v4l2_check_buf_type(crop->type) == false) {
663 ALOGE("%s: unsupported buffer type", __func__);
664 return ret;
665 }
666
667 ret = ioctl(fd, VIDIOC_G_CROP, crop);
668 if (ret) {
669 ALOGE("failed to ioctl: VIDIOC_G_CROP (%d - %s)", errno, strerror(errno));
670 return ret;
671 }
672
673 Exynos_v4l2_Out();
674
675 return ret;
676 }
677
678 int exynos_v4l2_s_crop(int fd, struct v4l2_crop *crop)
679 {
680 int ret = -1;
681
682 Exynos_v4l2_In();
683
684 if (fd < 0) {
685 ALOGE("%s: invalid fd: %d", __func__, fd);
686 return ret;
687 }
688
689 if (!crop) {
690 ALOGE("%s: crop is NULL", __func__);
691 return ret;
692 }
693
694 if (__v4l2_check_buf_type(crop->type) == false) {
695 ALOGE("%s: unsupported buffer type", __func__);
696 return ret;
697 }
698
699 ret = ioctl(fd, VIDIOC_S_CROP, crop);
700 if (ret) {
701 ALOGE("failed to ioctl: VIDIOC_S_CROP (%d - %s)", errno, strerror(errno));
702 return ret;
703 }
704
705 Exynos_v4l2_Out();
706
707 return ret;
708 }
709
710 int exynos_v4l2_g_ctrl(int fd, unsigned int id, int *value)
711 {
712 int ret = -1;
713 struct v4l2_control ctrl;
714
715 Exynos_v4l2_In();
716
717 ctrl.id = id;
718
719 if (fd < 0) {
720 ALOGE("%s: invalid fd: %d", __func__, fd);
721 return ret;
722 }
723
724 ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl);
725 if (ret) {
726 ALOGE("failed to ioctl: VIDIOC_G_CTRL (%d - %s)", errno, strerror(errno));
727 return ret;
728 }
729
730 *value = ctrl.value;
731
732 Exynos_v4l2_Out();
733
734 return ret;
735 }
736
737 int exynos_v4l2_s_ctrl(int fd, unsigned int id, int value)
738 {
739 int ret = -1;
740 struct v4l2_control ctrl;
741
742 Exynos_v4l2_In();
743
744 ctrl.id = id;
745 ctrl.value = value;
746
747 if (fd < 0) {
748 ALOGE("%s: invalid fd: %d", __func__, fd);
749 return ret;
750 }
751
752 ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
753 if (ret) {
754 ALOGE("failed to ioctl: VIDIOC_S_CTRL (%d)", errno);
755 return ret;
756 }
757
758 Exynos_v4l2_Out();
759
760 return ret;
761 }
762
763 int exynos_v4l2_g_parm(int fd, struct v4l2_streamparm *streamparm)
764 {
765 int ret = -1;
766
767 Exynos_v4l2_In();
768
769 if (fd < 0) {
770 ALOGE("%s: invalid fd: %d", __func__, fd);
771 return ret;
772 }
773
774 if (__v4l2_check_buf_type(streamparm->type) == false) {
775 ALOGE("%s: unsupported buffer type", __func__);
776 return ret;
777 }
778
779 ret = ioctl(fd, VIDIOC_G_PARM, streamparm);
780 if (ret) {
781 ALOGE("failed to ioctl: VIDIOC_G_PARM (%d - %s)", errno, strerror(errno));
782 return ret;
783 }
784
785 Exynos_v4l2_Out();
786
787 return ret;
788 }
789
790 int exynos_v4l2_s_parm(int fd, struct v4l2_streamparm *streamparm)
791 {
792 int ret = -1;
793
794 Exynos_v4l2_In();
795
796 if (fd < 0) {
797 ALOGE("%s: invalid fd: %d", __func__, fd);
798 return ret;
799 }
800
801 if (__v4l2_check_buf_type(streamparm->type) == false) {
802 ALOGE("%s: unsupported buffer type", __func__);
803 return ret;
804 }
805
806 ret = ioctl(fd, VIDIOC_S_PARM, streamparm);
807 if (ret) {
808 ALOGE("failed to ioctl: VIDIOC_S_PARM (%d - %s)", errno, strerror(errno));
809 return ret;
810 }
811
812 Exynos_v4l2_Out();
813
814 return ret;
815 }
816
817 int exynos_v4l2_g_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl)
818 {
819 int ret = -1;
820
821 Exynos_v4l2_In();
822
823 if (fd < 0) {
824 ALOGE("%s: invalid fd: %d", __func__, fd);
825 return ret;
826 }
827
828 if (ctrl == NULL) {
829 ALOGE("%s: ctrl is NULL", __func__);
830 return ret;
831 }
832
833 ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, ctrl);
834 if (ret)
835 ALOGE("failed to ioctl: VIDIOC_G_EXT_CTRLS (%d - %s)", errno, strerror(errno));
836
837 Exynos_v4l2_Out();
838
839 return ret;
840 }
841
842 int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl)
843 {
844 int ret = -1;
845
846 Exynos_v4l2_In();
847
848 if (fd < 0) {
849 ALOGE("%s: invalid fd: %d", __func__, fd);
850 return ret;
851 }
852
853 if (ctrl == NULL) {
854 ALOGE("%s: ctrl is NULL", __func__);
855 return ret;
856 }
857
858 ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, ctrl);
859 if (ret)
860 ALOGE("failed to ioctl: VIDIOC_S_EXT_CTRLS (%d - %s)", errno, strerror(errno));
861
862 Exynos_v4l2_Out();
863
864 return ret;
865 }