ADDED THE FIMC1 STUFF FOR NOTHING
[exynos_camera.git] / exynos_v4l2.c
1 /*
2  * Copyright (C) 2013 Paul Kocialkowski
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <fcntl.h>
19 #include <unistd.h>
20 #include <errno.h>
21 #include <malloc.h>
22 #include <poll.h>
23 #include <sys/stat.h>
24 #include <sys/types.h>
25 #include <sys/time.h>
26 #include <sys/mman.h>
27 #include <sys/ioctl.h>
28
29 #include <asm/types.h>
30 #include <linux/videodev2.h>
31
32 #define LOG_TAG "exynos_v4l2"
33 #include <utils/Log.h>
34
35 #include "exynos_camera.h"
36
37 /*
38  * Utils
39  */
40
41 int exynos_v4l2_find_index(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
42 {
43         int index;
44         int i;
45
46         if (exynos_camera == NULL || exynos_camera->config == NULL ||
47                 exynos_camera->config->v4l2_nodes == NULL)
48                 return -EINVAL;
49
50         if (exynos_v4l2_id > exynos_camera->config->v4l2_nodes_count)
51                 return -1;
52
53         index = -1;
54         for (i=0 ; i < exynos_camera->config->v4l2_nodes_count ; i++) {
55                 if (exynos_camera->config->v4l2_nodes[i].id == exynos_v4l2_id &&
56                         exynos_camera->config->v4l2_nodes[i].node != NULL) {
57                         index = i;
58                 }
59         }
60
61         return index;
62 }
63
64 int exynos_v4l2_find_fd(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
65 {
66         int index;
67
68         if (exynos_camera == NULL)
69                 return -EINVAL;
70
71         index = exynos_v4l2_find_index(exynos_camera, exynos_v4l2_id);
72         if (index < 0)
73                 return -1;
74
75         return exynos_camera->v4l2_fds[index];
76 }
77
78 /*
79  * File ops
80  */
81
82 int exynos_v4l2_open(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
83 {
84         char *node;
85         int index;
86         int fd;
87
88         if (exynos_camera == NULL || exynos_camera->config == NULL ||
89                 exynos_camera->config->v4l2_nodes == NULL)
90                 return -EINVAL;
91
92         index = exynos_v4l2_find_index(exynos_camera, exynos_v4l2_id);
93         if (index < 0) {
94                 LOGE("%s: Unable to find v4l2 node #%d", __func__, exynos_v4l2_id);
95                 return -1;
96         }
97
98         node = exynos_camera->config->v4l2_nodes[index].node;
99         fd = open(node, O_RDWR);
100         if (fd < 0) {
101                 LOGE("%s: Unable to open v4l2 node #%d", __func__, exynos_v4l2_id);
102                 return -1;
103         }
104
105         exynos_camera->v4l2_fds[index] = fd;
106
107         return 0;
108 }
109
110 void exynos_v4l2_close(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
111 {
112         int index;
113
114         if (exynos_camera == NULL || exynos_camera->config == NULL ||
115                 exynos_camera->config->v4l2_nodes == NULL)
116                 return;
117
118         index = exynos_v4l2_find_index(exynos_camera, exynos_v4l2_id);
119         if (index < 0) {
120                 LOGE("%s: Unable to find v4l2 node #%d", __func__, exynos_v4l2_id);
121                 return;
122         }
123
124         if (exynos_camera->v4l2_fds[index] > 0)
125                 close(exynos_camera->v4l2_fds[index]);
126
127         exynos_camera->v4l2_fds[index] = -1;
128 }
129
130 int exynos_v4l2_ioctl(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
131         int request, void *data)
132 {
133         int fd;
134
135         if (exynos_camera == NULL)
136                 return -EINVAL;
137
138         fd = exynos_v4l2_find_fd(exynos_camera, exynos_v4l2_id);
139         if (fd < 0) {
140                 LOGE("%s: Unable to find v4l2 fd #%d", __func__, exynos_v4l2_id);
141                 return -1;
142         }
143
144         return ioctl(fd, request, data);
145 }
146
147 int exynos_v4l2_poll(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
148 {
149         struct pollfd events;
150         int fd;
151         int rc;
152
153         if (exynos_camera == NULL)
154                 return -EINVAL;
155
156         fd = exynos_v4l2_find_fd(exynos_camera, exynos_v4l2_id);
157         if (fd < 0) {
158                 LOGE("%s: Unable to find v4l2 fd #%d", __func__, exynos_v4l2_id);
159                 return -1;
160         }
161
162         memset(&events, 0, sizeof(events));
163         events.fd = fd;
164         events.events = POLLIN | POLLERR;
165
166         rc = poll(&events, 1, 1000);
167         if (rc < 0 || events.revents & POLLERR) {
168                 LOGE("%s: poll failed", __func__);
169                 return -1;
170         }
171
172         return rc;
173 }
174
175 /*
176  * VIDIOC
177  */
178
179 int exynos_v4l2_qbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
180         int type, int memory, int index)
181 {
182         struct v4l2_buffer buffer;
183         int rc;
184
185         if (exynos_camera == NULL || index < 0)
186                 return -EINVAL;
187
188         buffer.type = type;
189         buffer.memory = memory;
190         buffer.index = index;
191
192         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QBUF, &buffer);
193         if (rc < 0) {
194                 LOGE("%s: ioctl failed", __func__);
195                 return -1;
196         }
197
198         return 0;
199 }
200
201 int exynos_v4l2_qbuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
202         int index)
203 {
204         return exynos_v4l2_qbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
205                 V4L2_MEMORY_MMAP, index);
206 }
207
208 int exynos_v4l2_qbuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
209         int index)
210 {
211         return exynos_v4l2_qbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
212                 V4L2_MEMORY_USERPTR, index);
213 }
214
215 int exynos_v4l2_dqbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
216         int type, int memory)
217 {
218         struct v4l2_buffer buffer;
219         int rc;
220
221         if (exynos_camera == NULL)
222                 return -EINVAL;
223
224         memset(&buffer, 0, sizeof(buffer));
225         buffer.type = type;
226         buffer.memory = memory;
227
228         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_DQBUF, &buffer);
229         if (rc < 0) {
230                 LOGE("%s: ioctl failed", __func__);
231                 return -1;
232         }
233
234         return buffer.index;
235 }
236
237 int exynos_v4l2_dqbuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
238 {
239         return exynos_v4l2_dqbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
240                 V4L2_MEMORY_MMAP);
241 }
242
243 int exynos_v4l2_dqbuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
244 {
245         return exynos_v4l2_dqbuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
246                 V4L2_MEMORY_USERPTR);
247 }
248
249 int exynos_v4l2_reqbufs(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
250         int type, int memory, int count)
251 {
252         struct v4l2_requestbuffers requestbuffers;
253         int rc;
254
255         if (exynos_camera == NULL || count < 0)
256                 return -EINVAL;
257
258         requestbuffers.type = type;
259         requestbuffers.count = count;
260         requestbuffers.memory = memory;
261
262         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_REQBUFS, &requestbuffers);
263         if (rc < 0) {
264                 LOGE("%s: ioctl failed", __func__);
265                 return -1;
266         }
267
268         return requestbuffers.count;
269 }
270
271 int exynos_v4l2_reqbufs_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
272         int count)
273 {
274         return exynos_v4l2_reqbufs(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
275                 V4L2_MEMORY_MMAP, count);
276 }
277
278 int exynos_v4l2_reqbufs_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
279         int count)
280 {
281         return exynos_v4l2_reqbufs(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
282                 V4L2_MEMORY_USERPTR, count);
283 }
284
285 int exynos_v4l2_querybuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
286         int type, int memory, int index)
287 {
288         struct v4l2_buffer buffer;
289         int rc;
290
291         if (exynos_camera == NULL)
292                 return -EINVAL;
293
294         memset(&buffer, 0, sizeof(buffer));
295         buffer.type = type;
296         buffer.memory = memory;
297         buffer.index = index;
298
299         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QUERYBUF, &buffer);
300         if (rc < 0) {
301                 LOGE("%s: ioctl failed", __func__);
302                 return -1;
303         }
304
305         return buffer.length;
306 }
307
308 int exynos_v4l2_querybuf_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
309         int index)
310 {
311         return exynos_v4l2_querybuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
312                 V4L2_MEMORY_MMAP, index);
313 }
314
315 int exynos_v4l2_querybuf_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
316         int index)
317 {
318         return exynos_v4l2_querybuf(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
319                 V4L2_MEMORY_USERPTR, index);
320 }
321
322 int exynos_v4l2_querycap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
323         int flags)
324 {
325         struct v4l2_capability cap;
326         int rc;
327
328         if (exynos_camera == NULL)
329                 return -EINVAL;
330
331         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_QUERYCAP, &cap);
332         if (rc < 0) {
333                 LOGE("%s: ioctl failed", __func__);
334                 return -1;
335         }
336
337         if (!(cap.capabilities & flags))
338                 return -1;
339
340         return 0;
341 }
342
343 int exynos_v4l2_querycap_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
344 {
345         return exynos_v4l2_querycap(exynos_camera, exynos_v4l2_id, V4L2_CAP_VIDEO_CAPTURE);
346 }
347
348 int exynos_v4l2_querycap_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
349 {
350         return exynos_v4l2_querycap(exynos_camera, exynos_v4l2_id, V4L2_CAP_VIDEO_OUTPUT);
351 }
352
353 int exynos_v4l2_streamon(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
354         int type)
355 {
356         enum v4l2_buf_type buf_type;
357         int rc;
358
359         if (exynos_camera == NULL)
360                 return -EINVAL;
361
362         buf_type = type;
363
364         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_STREAMON, &buf_type);
365         if (rc < 0) {
366                 LOGE("%s: ioctl failed", __func__);
367                 return -1;
368         }
369
370         return 0;
371 }
372
373 int exynos_v4l2_streamon_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
374 {
375         return exynos_v4l2_streamon(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE);
376 }
377
378 int exynos_v4l2_streamon_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
379 {
380         return exynos_v4l2_streamon(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT);
381 }
382
383 int exynos_v4l2_streamoff(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
384         int type)
385 {
386         enum v4l2_buf_type buf_type;
387         int rc;
388
389         if (exynos_camera == NULL)
390                 return -EINVAL;
391
392         buf_type = type;
393
394         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_STREAMOFF, &buf_type);
395         if (rc < 0) {
396                 LOGE("%s: ioctl failed", __func__);
397                 return -1;
398         }
399
400         return 0;
401 }
402
403 int exynos_v4l2_streamoff_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
404 {
405         return exynos_v4l2_streamoff(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE);
406 }
407
408 int exynos_v4l2_streamoff_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id)
409 {
410         return exynos_v4l2_streamoff(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT);
411 }
412
413 int exynos_v4l2_g_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
414         int type, int *width, int *height, int *fmt)
415 {
416         struct v4l2_format format;
417         int rc;
418
419         if (exynos_camera == NULL)
420                 return -EINVAL;
421
422         format.type = type;
423         format.fmt.pix.field = V4L2_FIELD_NONE;
424
425         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_FMT, &format);
426         if (rc < 0) {
427                 LOGE("%s: ioctl failed", __func__);
428                 return -1;
429         }
430
431         if (width != NULL)
432                 *width = format.fmt.pix.width;
433         if (height != NULL)
434                 *height = format.fmt.pix.height;
435         if (fmt != NULL)
436                 *fmt = format.fmt.pix.pixelformat;
437
438         return 0;
439 }
440
441 int exynos_v4l2_g_fmt_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
442         int *width, int *height, int *fmt)
443 {
444         return exynos_v4l2_g_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
445                 width, height, fmt);
446 }
447
448 int exynos_v4l2_g_fmt_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
449         int *width, int *height, int *fmt)
450 {
451         return exynos_v4l2_g_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
452                 width, height, fmt);
453 }
454
455 int exynos_v4l2_s_fmt_pix(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
456         int type, int width, int height, int fmt)
457 {
458         struct v4l2_format format;
459         int rc;
460
461         if (exynos_camera == NULL)
462                 return -EINVAL;
463
464         memset(&format, 0, sizeof(format));
465         format.type = type;
466         format.fmt.pix.width = width;
467         format.fmt.pix.height = height;
468         format.fmt.pix.pixelformat = fmt;
469         format.fmt.pix.field = V4L2_FIELD_NONE;
470
471         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FMT, &format);
472         if (rc < 0) {
473                 LOGE("%s: ioctl failed", __func__);
474                 return -1;
475         }
476
477         return 0;
478 }
479
480 int exynos_v4l2_s_fmt_pix_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
481         int width, int height, int fmt)
482 {
483         return exynos_v4l2_s_fmt_pix(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
484                 width, height, fmt);
485 }
486
487 int exynos_v4l2_s_fmt_pix_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
488         int width, int height, int fmt)
489 {
490         return exynos_v4l2_s_fmt_pix(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
491                 width, height, fmt);
492 }
493
494 int exynos_v4l2_s_fmt_win(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
495         int left, int top, int width, int height)
496 {
497         struct v4l2_format format;
498         int rc;
499
500         if (exynos_camera == NULL)
501                 return -EINVAL;
502
503         memset(&format, 0, sizeof(format));
504         format.type = V4L2_BUF_TYPE_VIDEO_OVERLAY;
505         format.fmt.win.w.left = left;
506         format.fmt.win.w.top = top;
507         format.fmt.win.w.width = width;
508         format.fmt.win.w.height = height;
509
510
511         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FMT, &format);
512         if (rc < 0) {
513                 LOGE("%s: ioctl failed", __func__);
514                 return -1;
515         }
516
517         return 0;
518 }
519
520 int exynos_v4l2_enum_fmt(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
521         int type, int fmt)
522 {
523         struct v4l2_fmtdesc fmtdesc;
524         int rc;
525
526         if (exynos_camera == NULL)
527                 return -EINVAL;
528
529         fmtdesc.type = type;
530         fmtdesc.index = 0;
531
532         do {
533                 rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_ENUM_FMT, &fmtdesc);
534                 if (rc < 0) {
535                         LOGE("%s: ioctl failed", __func__);
536                         return -1;
537                 }
538
539                 if (fmtdesc.pixelformat == (unsigned int) fmt)
540                         return 0;
541
542                 fmtdesc.index++;
543         } while (rc >= 0);
544
545         return -1;
546 }
547
548 int exynos_v4l2_enum_fmt_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
549         int fmt)
550 {
551         return exynos_v4l2_enum_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
552                 fmt);
553 }
554
555 int exynos_v4l2_enum_fmt_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
556         int fmt)
557 {
558         return exynos_v4l2_enum_fmt(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
559                 fmt);
560 }
561
562 int exynos_v4l2_enum_input(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
563         int id)
564 {
565         struct v4l2_input input;
566         int rc;
567
568         if (exynos_camera == NULL || id < 0)
569                 return -EINVAL;
570
571         input.index = id;
572
573         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_ENUMINPUT, &input);
574         if (rc < 0) {
575                 LOGE("%s: ioctl failed", __func__);
576                 return -1;
577         }
578
579         if (input.name[0] == '\0')
580                 return -1;
581
582         return 0;
583 }
584
585 int exynos_v4l2_s_input(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
586         int id)
587 {
588         struct v4l2_input input;
589         int rc;
590
591         if (exynos_camera == NULL || id < 0)
592                 return -EINVAL;
593
594         input.index = id;
595
596         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_INPUT, &input);
597         if (rc < 0) {
598                 LOGE("%s: ioctl failed", __func__);
599                 return -1;
600         }
601
602         return 0;
603 }
604
605 int exynos_v4l2_g_ext_ctrls(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
606         struct v4l2_ext_control *control, int count)
607 {
608         struct v4l2_ext_controls controls;
609         int rc;
610
611         if (exynos_camera == NULL || control == NULL)
612                 return -EINVAL;
613
614         memset(&controls, 0, sizeof(controls));
615         controls.ctrl_class = V4L2_CTRL_CLASS_CAMERA;
616         controls.count = count;
617         controls.controls = control;
618
619         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_EXT_CTRLS, &controls);
620         if (rc < 0) {
621                 LOGE("%s: ioctl failed", __func__);
622                 return -1;
623         }
624
625         return 0;
626 }
627
628 int exynos_v4l2_s_ctrl(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
629         int id, int value)
630 {
631         struct v4l2_control control;
632         int rc;
633
634         if (exynos_camera == NULL)
635                 return -EINVAL;
636
637         control.id = id;
638         control.value = value;
639
640         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_CTRL, &control);
641         if (rc < 0) {
642                 LOGE("%s: ioctl failed", __func__);
643                 return -1;
644         }
645
646         return control.value;
647 }
648
649 int exynos_v4l2_s_parm(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
650         int type, struct v4l2_streamparm *streamparm)
651 {
652         int rc;
653
654         if (exynos_camera == NULL || streamparm == NULL)
655                 return -EINVAL;
656
657         streamparm->type = type;
658
659         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_PARM, streamparm);
660         if (rc < 0) {
661                 LOGE("%s: ioctl failed", __func__);
662                 return -1;
663         }
664
665         return 0;
666 }
667
668 int exynos_v4l2_s_parm_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
669         struct v4l2_streamparm *streamparm)
670 {
671         return exynos_v4l2_s_parm(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
672                 streamparm);
673 }
674
675 int exynos_v4l2_s_parm_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
676         struct v4l2_streamparm *streamparm)
677 {
678         return exynos_v4l2_s_parm(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
679                 streamparm);
680 }
681
682 int exynos_v4l2_s_crop(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
683         int type, int left, int top, int width, int height)
684 {
685         struct v4l2_crop crop;
686         int rc;
687
688         if (exynos_camera == NULL)
689                 return -EINVAL;
690
691         crop.type = type;
692         crop.c.left = left;
693         crop.c.top = top;
694         crop.c.width = width;
695         crop.c.height = height;
696
697         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_CROP, &crop);
698         if (rc < 0) {
699                 LOGE("%s: ioctl failed", __func__);
700                 return -1;
701         }
702
703         return 0;
704 }
705
706 int exynos_v4l2_s_crop_cap(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
707         int left, int top, int width, int height)
708 {
709         return exynos_v4l2_s_crop(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_CAPTURE,
710                 left, top, width, height);
711 }
712
713 int exynos_v4l2_s_crop_out(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
714         int left, int top, int width, int height)
715 {
716         return exynos_v4l2_s_crop(exynos_camera, exynos_v4l2_id, V4L2_BUF_TYPE_VIDEO_OUTPUT,
717                 left, top, width, height);
718 }
719
720 int exynos_v4l2_g_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
721         void **base, int *width, int *height, int *fmt)
722 {
723         struct v4l2_framebuffer framebuffer;
724         int rc;
725
726         if (exynos_camera == NULL)
727                 return -EINVAL;
728
729         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_G_FBUF, &framebuffer);
730         if (rc < 0) {
731                 LOGE("%s: ioctl failed", __func__);
732                 return -1;
733         }
734
735         if (base != NULL)
736                 *base = framebuffer.base;
737         if (width != NULL)
738                 *width = framebuffer.fmt.width;
739         if (height != NULL)
740                 *height = framebuffer.fmt.height;
741         if (fmt != NULL)
742                 *fmt = framebuffer.fmt.pixelformat;
743
744         return 0;
745 }
746
747 int exynos_v4l2_s_fbuf(struct exynos_camera *exynos_camera, int exynos_v4l2_id,
748         void *base, int width, int height, int fmt)
749 {
750         struct v4l2_framebuffer framebuffer;
751         int rc;
752
753         if (exynos_camera == NULL)
754                 return -EINVAL;
755
756         memset(&framebuffer, 0, sizeof(framebuffer));
757         framebuffer.base = base;
758         framebuffer.fmt.width = width;
759         framebuffer.fmt.height = height;
760         framebuffer.fmt.pixelformat = fmt;
761
762         rc = exynos_v4l2_ioctl(exynos_camera, exynos_v4l2_id, VIDIOC_S_FBUF, &framebuffer);
763         if (rc < 0) {
764                 LOGE("%s: ioctl failed", __func__);
765                 return -1;
766         }
767
768         return 0;
769 }