libv4l2: LOG* -> ALOG*
[GitHub/LineageOS/android_hardware_samsung_slsi_exynos5.git] / libv4l2 / exynos_v4l2.c
CommitLineData
e5931c34
JC
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 <stdarg.h>
32#include <fcntl.h>
33#include <string.h>
34#include <sys/types.h>
35#include <sys/ioctl.h>
36#include <sys/stat.h>
37
38#include "exynos_v4l2.h"
39
40//#define LOG_NDEBUG 0
41#define LOG_TAG "libexynosv4l2"
42#include <utils/Log.h>
43
44#define VIDEODEV_MINOR_MAX 63
45
46static bool __v4l2_check_buf_type(enum v4l2_buf_type type)
47{
48 bool supported;
49
50 switch (type) {
51 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
52 case V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE:
53 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
54 case V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE:
55 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
56 supported = true;
57 break;
58
59 default:
60 supported = (type >= V4L2_BUF_TYPE_PRIVATE) ? true : false;
61 break;
62 }
63
64 return supported;
65}
66
67static int __v4l2_open(const char *filename, int oflag, va_list ap)
68{
69 mode_t mode = 0;
70 int fd;
71
72 if (oflag & O_CREAT)
73 mode = va_arg(ap, int);
74
75 fd = open(filename, oflag, mode);
76
77 return fd;
78}
79
80int exynos_v4l2_open(const char *filename, int oflag, ...)
81{
82 va_list ap;
83 int fd;
84
85 va_start(ap, oflag);
86 fd = __v4l2_open(filename, oflag, ap);
87 va_end(ap);
88
89 return fd;
90}
91
92int exynos_v4l2_open_devname(const char *devname, int oflag, ...)
93{
94 bool found = false;
95 int fd = -1;
96 struct stat s;
97 va_list ap;
98 FILE *stream_fd;
99 char filename[64], name[64];
100 int minor, size, i = 0;
101
102 do {
103 if (i > VIDEODEV_MINOR_MAX)
104 break;
105
106 /* video device node */
107 sprintf(filename, "/dev/video%d", i++);
108
109 /* if the node is video device */
110 if ((lstat(filename, &s) == 0) && S_ISCHR(s.st_mode) &&
111 ((int)((unsigned short)(s.st_rdev) >> 8) == 81)) {
112 minor = (int)((unsigned short)(s.st_rdev & 0x3f));
7642c64b 113 ALOGD("try node: %s, minor: %d", filename, minor);
e5931c34
JC
114 /* open sysfs entry */
115 sprintf(filename, "/sys/class/video4linux/video%d/name", minor);
116 stream_fd = fopen(filename, "r");
117 if (stream_fd < 0) {
7642c64b 118 ALOGE("failed to open sysfs entry for videodev");
e5931c34
JC
119 continue; /* try next */
120 }
121
122 /* read sysfs entry for device name */
123 size = (int)fgets(name, sizeof(name), stream_fd);
124 fclose(stream_fd);
125
126 /* check read size */
127 if (size == 0) {
7642c64b 128 ALOGE("failed to read sysfs entry for videodev");
e5931c34
JC
129 } else {
130 /* matched */
131 if (strncmp(name, devname, strlen(devname)) == 0) {
7642c64b 132 ALOGI("node found for device %s: /dev/video%d", devname, minor);
e5931c34
JC
133 found = true;
134 }
135 }
136 }
137 } while (found == false);
138
139 if (found) {
140 sprintf(filename, "/dev/video%d", minor);
141 va_start(ap, oflag);
142 fd = __v4l2_open(filename, oflag, ap);
143 va_end(ap);
144
145 if (fd > 0)
7642c64b 146 ALOGI("open video device %s", filename);
e5931c34 147 else
7642c64b 148 ALOGE("failed to open video device %s", filename);
e5931c34 149 } else {
7642c64b 150 ALOGE("no video device found");
e5931c34
JC
151 }
152
153 return fd;
154}
155
156int exynos_v4l2_close(int fd)
157{
158 int ret = -1;
159
160 if (fd < 0)
7642c64b 161 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
162 else
163 ret = close(fd);
164
165 return ret;
166}
167
168bool exynos_v4l2_enuminput(int fd, int index, char *input_name_buf)
169{
170 int ret = -1;
171 struct v4l2_input input;
172
173 if (fd < 0) {
7642c64b 174 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
175 return NULL;
176 }
177
178 input.index = index;
179 ret = ioctl(fd, VIDIOC_ENUMINPUT, &input);
180 if (ret) {
7642c64b 181 ALOGE("%s: no matching index founds", __func__);
e5931c34
JC
182 return false;
183 }
184
7642c64b 185 ALOGI("Name of input channel[%d] is %s", input.index, input.name);
e5931c34
JC
186
187 strcpy(input_name_buf, (const char *)input.name);
188
189 return true;
190}
191
192int exynos_v4l2_s_input(int fd, int index)
193{
194 int ret = -1;
195 struct v4l2_input input;
196
197 if (fd < 0) {
7642c64b 198 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
199 return ret;
200 }
201
202 input.index = index;
203
204 ret = ioctl(fd, VIDIOC_S_INPUT, &input);
205 if (ret){
7642c64b 206 ALOGE("failed to ioctl: VIDIOC_S_INPUT (%d)", ret);
e5931c34
JC
207 return ret;
208 }
209
210 return ret;
211}
212
213bool exynos_v4l2_querycap(int fd, unsigned int need_caps)
214{
215 struct v4l2_capability cap;
216 int ret;
217
218 if (fd < 0) {
7642c64b 219 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
220 return false;
221 }
222
223 if (!(need_caps & V4L2_CAP_VIDEO_CAPTURE) &&
224 !(need_caps & V4L2_CAP_VIDEO_CAPTURE_MPLANE) &&
225 !(need_caps & V4L2_CAP_VIDEO_OUTPUT) &&
226 !(need_caps & V4L2_CAP_VIDEO_OUTPUT_MPLANE) &&
227 !(need_caps & V4L2_CAP_VIDEO_OVERLAY)) {
7642c64b 228 ALOGE("%s: unsupported capabilities", __func__);
e5931c34
JC
229 return false;
230 }
231
232 memset(&cap, 0, sizeof(cap));
233
234 ret = ioctl(fd, VIDIOC_QUERYCAP, &cap);
235 if (ret) {
7642c64b 236 ALOGE("failed to ioctl: VIDIOC_QUERYCAP (%d)", ret);
e5931c34
JC
237 return false;
238 }
239
240 if ((need_caps & cap.capabilities) != need_caps) {
7642c64b 241 ALOGE("%s: unsupported capabilities", __func__);
e5931c34
JC
242 return false;
243 }
244
245 return true;
246}
247
248bool exynos_v4l2_enum_fmt(int fd, enum v4l2_buf_type type, unsigned int fmt)
249{
250 struct v4l2_fmtdesc fmtdesc;
251 int found = 0;
252
253 fmtdesc.type = type;
254 fmtdesc.index = 0;
255
256 while (ioctl(fd, VIDIOC_ENUM_FMT, &fmtdesc) == 0) {
257 if (fmtdesc.pixelformat == fmt) {
7642c64b 258 ALOGE("Passed fmt = %#x found pixel format[%d]: %s", fmt, fmtdesc.index, fmtdesc.description);
e5931c34
JC
259 found = 1;
260 break;
261 }
262
263 fmtdesc.index++;
264 }
265
266 if (!found) {
7642c64b 267 ALOGE("%s: unsupported pixel format", __func__);
e5931c34
JC
268 return false;
269 }
270
271 return true;
272}
273
274int exynos_v4l2_g_fmt(int fd, struct v4l2_format *fmt)
275{
276 int ret = -1;
277
278 if (fd < 0) {
7642c64b 279 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
280 return ret;
281 }
282
283 if (!fmt) {
7642c64b 284 ALOGE("%s: fmt is NULL", __func__);
e5931c34
JC
285 return ret;
286 }
287
288 if (__v4l2_check_buf_type(fmt->type) == false) {
7642c64b 289 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
290 return ret;
291 }
292
293 ret = ioctl(fd, VIDIOC_G_FMT, fmt);
294 if (ret) {
7642c64b 295 ALOGE("failed to ioctl: VIDIOC_G_FMT");
e5931c34
JC
296 return ret;
297 }
298
299 return ret;
300}
301
302static int __v4l2_s_fmt(int fd, unsigned int request, struct v4l2_format *fmt)
303{
304 int ret = -1;
305
306 if (fd < 0) {
7642c64b 307 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
308 return ret;
309 }
310
311 if (!fmt) {
7642c64b 312 ALOGE("%s: fmt is NULL", __func__);
e5931c34
JC
313 return ret;
314 }
315
316 if (__v4l2_check_buf_type(fmt->type) == false) {
7642c64b 317 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
318 return ret;
319 } else {
320 ret = ioctl(fd, request, fmt);
321 if (ret) {
322 if (request == VIDIOC_TRY_FMT)
7642c64b 323 ALOGE("failed to ioctl: VIDIOC_TRY_FMT (%d)", ret);
e5931c34 324 else
7642c64b 325 ALOGE("failed to ioctl: VIDIOC_S_FMT (%d)", ret);
e5931c34
JC
326
327 return ret;
328 }
329 }
330
331 return ret;
332}
333
334int exynos_v4l2_try_fmt(int fd, struct v4l2_format *fmt)
335{
336 return __v4l2_s_fmt(fd, VIDIOC_TRY_FMT, fmt);
337}
338
339int exynos_v4l2_s_fmt(int fd, struct v4l2_format *fmt)
340{
341 return __v4l2_s_fmt(fd, VIDIOC_S_FMT, fmt);
342}
343
344int exynos_v4l2_reqbufs(int fd, struct v4l2_requestbuffers *req)
345{
346 int ret = -1;
347 unsigned int count;
348
349 if (fd < 0) {
7642c64b 350 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
351 return ret;
352 }
353
354 if (!req) {
7642c64b 355 ALOGE("%s: req is NULL", __func__);
e5931c34
JC
356 return ret;
357 }
358
359 if ((req->memory != V4L2_MEMORY_MMAP) && (req->memory != V4L2_MEMORY_USERPTR)) {
7642c64b 360 ALOGE("%s: unsupported memory type", __func__);
e5931c34
JC
361 return ret;
362 }
363
364 if (__v4l2_check_buf_type(req->type) == false) {
7642c64b 365 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
366 return ret;
367 }
368
369 count = req->count;
370
371 ret = ioctl(fd, VIDIOC_REQBUFS, req);
372 if (ret) {
7642c64b 373 ALOGE("failed to ioctl: VIDIOC_REQBUFS (%d)", ret);
e5931c34
JC
374 return ret;
375 }
376
377 if (count != req->count) {
7642c64b 378 ALOGW("number of buffers had been changed: %d => %d", count, req->count);
e5931c34
JC
379 }
380
381 return ret;
382}
383
384int exynos_v4l2_querybuf(int fd, struct v4l2_buffer *buf)
385{
386 int ret = -1;
387
388 if (fd < 0) {
7642c64b 389 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
390 return ret;
391 }
392
393 if (!buf) {
7642c64b 394 ALOGE("%s: buf is NULL", __func__);
e5931c34
JC
395 return ret;
396 }
397
398 if (buf->memory != V4L2_MEMORY_MMAP) {
7642c64b 399 ALOGE("%s: unsupported memory type", __func__);
e5931c34
JC
400 return ret;
401 }
402
403 if (__v4l2_check_buf_type(buf->type) == false) {
7642c64b 404 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
405 return ret;
406 }
407
408 ret = ioctl(fd, VIDIOC_QUERYBUF, buf);
409 if (ret) {
7642c64b 410 ALOGE("failed to ioctl: VIDIOC_QUERYBUF (%d)", ret);
e5931c34
JC
411 return ret;
412 }
413
414 return ret;
415}
416
417int exynos_v4l2_qbuf(int fd, struct v4l2_buffer *buf)
418{
419 int ret = -1;
420
421 if (fd < 0) {
7642c64b 422 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
423 return ret;
424 }
425
426 if (!buf) {
7642c64b 427 ALOGE("%s: buf is NULL", __func__);
e5931c34
JC
428 return ret;
429 }
430
431 if ((buf->memory != V4L2_MEMORY_MMAP) && (buf->memory != V4L2_MEMORY_USERPTR)) {
7642c64b 432 ALOGE("%s: unsupported memory type", __func__);
e5931c34
JC
433 return ret;
434 }
435
436 if (__v4l2_check_buf_type(buf->type) == false) {
7642c64b 437 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
438 return ret;
439 }
440
441 ret = ioctl(fd, VIDIOC_QBUF, buf);
442 if (ret) {
7642c64b 443 ALOGE("failed to ioctl: VIDIOC_QBUF (%d)", ret);
e5931c34
JC
444 return ret;
445 }
446
447 return ret;
448}
449
450int exynos_v4l2_dqbuf(int fd, struct v4l2_buffer *buf)
451{
452 int ret = -1;
453
454 if (fd < 0) {
7642c64b 455 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
456 return ret;
457 }
458
459 if (!buf) {
7642c64b 460 ALOGE("%s: buf is NULL", __func__);
e5931c34
JC
461 return ret;
462 }
463
464 if ((buf->memory != V4L2_MEMORY_MMAP) && (buf->memory != V4L2_MEMORY_USERPTR)) {
7642c64b 465 ALOGE("%s: unsupported memory type", __func__);
e5931c34
JC
466 return ret;
467 }
468
469 if (__v4l2_check_buf_type(buf->type) == false) {
7642c64b 470 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
471 return ret;
472 }
473
474 ret = ioctl(fd, VIDIOC_DQBUF, buf);
475 if (ret) {
7642c64b 476 ALOGE("failed to ioctl: VIDIOC_DQBUF (%d)", ret);
e5931c34
JC
477 return ret;
478 }
479
480 return ret;
481}
482
483int exynos_v4l2_streamon(int fd, enum v4l2_buf_type type)
484{
485 int ret = -1;
486
487 if (fd < 0) {
7642c64b 488 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
489 return ret;
490 }
491
492 if (__v4l2_check_buf_type(type) == false) {
7642c64b 493 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
494 return ret;
495 }
496
497 ret = ioctl(fd, VIDIOC_STREAMON, &type);
498 if (ret) {
7642c64b 499 ALOGE("failed to ioctl: VIDIOC_STREAMON (%d)", ret);
e5931c34
JC
500 return ret;
501 }
502
503 return ret;
504}
505
506int exynos_v4l2_streamoff(int fd, enum v4l2_buf_type type)
507{
508 int ret = -1;
509
510 if (fd < 0) {
7642c64b 511 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
512 return ret;
513 }
514
515 if (__v4l2_check_buf_type(type) == false) {
7642c64b 516 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
517 return ret;
518 }
519
520 ret = ioctl(fd, VIDIOC_STREAMOFF, &type);
521 if (ret) {
7642c64b 522 ALOGE("failed to ioctl: VIDIOC_STREAMOFF (%d)", ret);
e5931c34
JC
523 return ret;
524 }
525
526 return ret;
527}
528
529int exynos_v4l2_cropcap(int fd, struct v4l2_cropcap *crop)
530{
531 int ret = -1;
532
533 if (fd < 0) {
7642c64b 534 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
535 return ret;
536 }
537
538 if (!crop) {
7642c64b 539 ALOGE("%s: crop is NULL", __func__);
e5931c34
JC
540 return ret;
541 }
542
543 if (__v4l2_check_buf_type(crop->type) == false) {
7642c64b 544 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
545 return ret;
546 }
547
548 ret = ioctl(fd, VIDIOC_CROPCAP, crop);
549 if (ret) {
7642c64b 550 ALOGE("failed to ioctl: VIDIOC_CROPCAP (%d)", ret);
e5931c34
JC
551 return ret;
552 }
553
554 return ret;
555}
556
557int exynos_v4l2_g_crop(int fd, struct v4l2_crop *crop)
558{
559 int ret = -1;
560
561 if (fd < 0) {
7642c64b 562 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
563 return ret;
564 }
565
566 if (!crop) {
7642c64b 567 ALOGE("%s: crop is NULL", __func__);
e5931c34
JC
568 return ret;
569 }
570
571 if (__v4l2_check_buf_type(crop->type) == false) {
7642c64b 572 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
573 return ret;
574 }
575
576 ret = ioctl(fd, VIDIOC_G_CROP, crop);
577 if (ret) {
7642c64b 578 ALOGE("failed to ioctl: VIDIOC_G_CROP (%d)", ret);
e5931c34
JC
579 return ret;
580 }
581
582 return ret;
583}
584
585int exynos_v4l2_s_crop(int fd, struct v4l2_crop *crop)
586{
587 int ret = -1;
588
589 if (fd < 0) {
7642c64b 590 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
591 return ret;
592 }
593
594 if (!crop) {
7642c64b 595 ALOGE("%s: crop is NULL", __func__);
e5931c34
JC
596 return ret;
597 }
598
599 if (__v4l2_check_buf_type(crop->type) == false) {
7642c64b 600 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
601 return ret;
602 }
603
604 ret = ioctl(fd, VIDIOC_S_CROP, crop);
605 if (ret) {
7642c64b 606 ALOGE("failed to ioctl: VIDIOC_S_CROP (%d)", ret);
e5931c34
JC
607 return ret;
608 }
609
610 return ret;
611}
612
613int exynos_v4l2_g_ctrl(int fd, unsigned int id, int *value)
614{
615 int ret = -1;
616 struct v4l2_control ctrl;
617
618 ctrl.id = id;
619
620 if (fd < 0) {
7642c64b 621 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
622 return ret;
623 }
624
625 ret = ioctl(fd, VIDIOC_G_CTRL, &ctrl);
626 if (ret) {
7642c64b 627 ALOGE("failed to ioctl: VIDIOC_G_CTRL (%d)", ret);
e5931c34
JC
628 return ret;
629 }
630
631 *value = ctrl.value;
632
633 return ret;
634}
635
636int exynos_v4l2_s_ctrl(int fd, unsigned int id, int value)
637{
638 int ret = -1;
639 struct v4l2_control ctrl;
640
641 ctrl.id = id;
642 ctrl.value = value;
643
644 if (fd < 0) {
7642c64b 645 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
646 return ret;
647 }
648
649 ret = ioctl(fd, VIDIOC_S_CTRL, &ctrl);
650 if (ret) {
7642c64b 651 ALOGE("failed to ioctl: VIDIOC_S_CTRL (%d)", ret);
e5931c34
JC
652 return ret;
653 }
654
655 return ret;
656}
657
658int exynos_v4l2_g_parm(int fd, struct v4l2_streamparm *streamparm)
659{
660 int ret = -1;
661
662 if (fd < 0) {
7642c64b 663 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
664 return ret;
665 }
666
667 if (__v4l2_check_buf_type(streamparm->type) == false) {
7642c64b 668 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
669 return ret;
670 }
671
672 ret = ioctl(fd, VIDIOC_G_PARM, streamparm);
673 if (ret) {
7642c64b 674 ALOGE("failed to ioctl: VIDIOC_G_PARM (%d)", ret);
e5931c34
JC
675 return ret;
676 }
677
678 return ret;
679}
680
681int exynos_v4l2_s_parm(int fd, struct v4l2_streamparm *streamparm)
682{
683 int ret = -1;
684
685 if (fd < 0) {
7642c64b 686 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
687 return ret;
688 }
689
690 if (__v4l2_check_buf_type(streamparm->type) == false) {
7642c64b 691 ALOGE("%s: unsupported buffer type", __func__);
e5931c34
JC
692 return ret;
693 }
694
695 ret = ioctl(fd, VIDIOC_S_PARM, streamparm);
696 if (ret) {
7642c64b 697 ALOGE("failed to ioctl: VIDIOC_S_PARM (%d)", ret);
e5931c34
JC
698 return ret;
699 }
700
701 return ret;
702}
703
704int exynos_v4l2_g_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl)
705{
706 int ret = -1;
707
708 if (fd < 0) {
7642c64b 709 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
710 return ret;
711 }
712
713 if (ctrl == NULL) {
7642c64b 714 ALOGE("%s: ctrl is NULL", __func__);
e5931c34
JC
715 return ret;
716 }
717
718 ret = ioctl(fd, VIDIOC_G_EXT_CTRLS, ctrl);
719 if (ret)
7642c64b 720 ALOGE("failed to ioctl: VIDIOC_G_EXT_CTRLS (%d)", ret);
e5931c34
JC
721
722 return ret;
723}
724
725int exynos_v4l2_s_ext_ctrl(int fd, struct v4l2_ext_controls *ctrl)
726{
727 int ret = -1;
728
729 if (fd < 0) {
7642c64b 730 ALOGE("%s: invalid fd: %d", __func__, fd);
e5931c34
JC
731 return ret;
732 }
733
734 if (ctrl == NULL) {
7642c64b 735 ALOGE("%s: ctrl is NULL", __func__);
e5931c34
JC
736 return ret;
737 }
738
739 ret = ioctl(fd, VIDIOC_S_EXT_CTRLS, ctrl);
740 if (ret)
7642c64b 741 ALOGE("failed to ioctl: VIDIOC_S_EXT_CTRLS (%d)", ret);
e5931c34
JC
742
743 return ret;
744}