Commit | Line | Data |
---|---|---|
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 | ||
46 | static 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 | ||
67 | static 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 | ||
80 | int 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 | ||
92 | int 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 | ||
156 | int 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 | ||
168 | bool 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 | ||
192 | int 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 | ||
213 | bool 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 | ||
248 | bool 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 | ||
274 | int 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 | ||
302 | static 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 | ||
334 | int exynos_v4l2_try_fmt(int fd, struct v4l2_format *fmt) | |
335 | { | |
336 | return __v4l2_s_fmt(fd, VIDIOC_TRY_FMT, fmt); | |
337 | } | |
338 | ||
339 | int exynos_v4l2_s_fmt(int fd, struct v4l2_format *fmt) | |
340 | { | |
341 | return __v4l2_s_fmt(fd, VIDIOC_S_FMT, fmt); | |
342 | } | |
343 | ||
344 | int 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 | ||
384 | int 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 | ||
417 | int 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 | ||
450 | int 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 | ||
483 | int 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 | ||
506 | int 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 | ||
529 | int 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 | ||
557 | int 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 | ||
585 | int 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 | ||
613 | int 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 | ||
636 | int 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 | ||
658 | int 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 | ||
681 | int 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 | ||
704 | int 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 | ||
725 | int 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 | } |