Initialize Tizen 2.3
[adaptation/xorg/driver/xserver-xorg-video-emulfb.git] / src / xv / fbdev_v4l2.c
1 /**************************************************************************
2
3 xserver-xorg-video-emulfb
4
5 Copyright 2010 - 2011 Samsung Electronics co., Ltd. All Rights Reserved.
6
7 Contact: Boram Park <boram1288.park@samsung.com>
8
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
16
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
19 of the Software.
20
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
28
29 **************************************************************************/
30
31 #include <stdio.h>
32 #include <string.h>
33 #include <sys/ioctl.h>
34 #include <errno.h>
35
36 #include "xf86.h"
37
38 #include "fbdev_v4l2.h"
39 #include "fbdev_util.h"
40
41 typedef struct _CapInfo
42 {
43         int   value;
44         char *name;
45 } CapInfo;
46
47 static CapInfo cap_infos [] =
48 {
49         {V4L2_CAP_VIDEO_CAPTURE,        "VIDEO_CAPTURE"},
50         {V4L2_CAP_VIDEO_OUTPUT,         "VIDEO_OUTPUT"},
51         {V4L2_CAP_VIDEO_OVERLAY,        "VIDEO_OVERLAY"},
52         {V4L2_CAP_VBI_CAPTURE,          "VBI_CAPTURE"},
53         {V4L2_CAP_VBI_OUTPUT,           "VBI_OUTPUT"},
54         {V4L2_CAP_SLICED_VBI_CAPTURE,   "SLICED_VBI_CAPTURE"},
55         {V4L2_CAP_SLICED_VBI_OUTPUT,    "SLICED_VBI_OUTPUT"},
56         {V4L2_CAP_RDS_CAPTURE,          "RDS_CAPTURE"},
57         {V4L2_CAP_VIDEO_OUTPUT_OVERLAY, "VIDEO_OUTPUT_OVERLAY"},
58         {V4L2_CAP_HW_FREQ_SEEK,         "HW_FREQ_SEEK"},
59         {V4L2_CAP_RDS_OUTPUT,           "RDS_OUTPUT"},
60         {V4L2_CAP_TUNER,                "TUNER"},
61         {V4L2_CAP_AUDIO,                "AUDIO"},
62         {V4L2_CAP_RADIO,                "RADIO"},
63         {V4L2_CAP_MODULATOR,            "MODULATOR"},
64         {V4L2_CAP_READWRITE,            "READWRITE"},
65         {V4L2_CAP_ASYNCIO,              "ASYNCIO"},
66         {V4L2_CAP_STREAMING,            "STREAMING"}
67 };
68
69 static Bool _fbdev_v4l2_ioctl (int fd, int cmd, void *data, char *debug)
70 {
71         int retry = 0;
72         int ret;
73
74 try_again:
75         ret = ioctl (fd, cmd, data);
76         if (ret < 0)
77         {
78                 if (errno == EINTR || errno == EAGAIN)
79                 {
80                         if (retry < 100)
81                         {
82                                 retry++;
83                                 goto try_again;
84                         }
85                 }
86
87                 return FALSE;
88         }
89
90         return TRUE;
91 }
92
93 Bool fbdev_v4l2_querycap (int fd, int capabilities)
94 {
95         struct v4l2_capability cap;
96         int ret;
97
98         CLEAR (cap);
99         ret = ioctl (fd, VIDIOC_QUERYCAP, &cap);
100         if (ret < 0)
101         {
102                 xf86DrvMsg (0, X_ERROR, "[QUERYCAP] failed. (%s)\n", strerror(errno));
103                 return FALSE;
104         }
105
106         if (~(cap.capabilities) & capabilities)
107         {
108                 int unsupport = ~(cap.capabilities) & capabilities;
109                 int i;
110
111                 for (i = 0; i < sizeof (cap_infos) / sizeof (CapInfo); i++)
112                         if (unsupport & cap_infos[i].value)
113                                 xf86DrvMsg (0, X_ERROR, "[QUERYCAP] %s not support.\n", cap_infos[i].name);
114
115                 return FALSE;
116         }
117
118         return TRUE;
119 }
120
121 Bool fbdev_v4l2_cropcap (int fd, FBDevV4l2BufType type, struct v4l2_rect *crop)
122 {
123         struct v4l2_cropcap cropcap;
124         int ret;
125
126         CLEAR(cropcap);
127         cropcap.type = type;
128         ret = ioctl (fd, VIDIOC_CROPCAP, &cropcap);
129         if (ret < 0)
130         {
131                 xf86DrvMsg (0, X_ERROR, "[CROPCAP] failed. (%s)\n", strerror(errno));
132                 return FALSE;
133         }
134
135         /* check if crop_rect si valid */
136         if ((crop->left < cropcap.bounds.left) &&
137                 (crop->top < cropcap.bounds.top) &&
138                 (crop->width > cropcap.bounds.width) &&
139                 (crop->height > cropcap.bounds.height))
140         {
141                 xf86DrvMsg (0, X_ERROR, "(%d,%d %dx%d) is out of bound(%d,%d %dx%d)\n",
142                             crop->left, crop->top, crop->width, crop->height,
143                             cropcap.bounds.left, cropcap.bounds.top,
144                             cropcap.bounds.width, cropcap.bounds.height);
145                 return FALSE;
146         }
147
148         return TRUE;
149 }
150
151 Bool fbdev_v4l2_enum_std (int fd, struct v4l2_standard *std, v4l2_std_id std_id)
152 {
153         std->index = 0;
154
155         while (0 == ioctl (fd, VIDIOC_ENUMSTD, std))
156         {
157                 /* return TRUE if std_id found */
158                 if (std->id & std_id)
159                 {
160                         xf86DrvMsg (0, X_ERROR, "[ENUMSTD] name(%s). (%s)\n", std->name, strerror(errno));
161                         return TRUE;
162                 }
163
164                 std->index++;
165         }
166
167         return FALSE;
168 }
169
170 Bool fbdev_v4l2_enum_output (int fd, struct v4l2_output *output, FBDevV4l2BufType type)
171 {
172         output->index = 0;
173
174         while (0 == ioctl (fd, VIDIOC_ENUMOUTPUT, output))
175         {
176                 /* return TRUE if type found */
177                 if (output->type & type)
178                 {
179                         xf86DrvMsg (0, X_ERROR, "[ENUMOUTPUT] index(%d) type(0x%08x) name(%s). (%s)\n",
180                                     output->index,output->type,output->name, strerror(errno));
181                         return TRUE;
182                 }
183
184                 output->index++;
185         }
186
187         return FALSE;
188 }
189
190 Bool fbdev_v4l2_enum_fmt (int fd, struct v4l2_fmtdesc *desc, FBDevV4l2BufType type)
191 {
192         desc->index = 0;
193
194         while (0 == ioctl (fd, VIDIOC_ENUM_FMT, desc))
195         {
196                 /* return TRUE if type found */
197                 if (desc->type & type)
198                 {
199                         xf86DrvMsg (0, X_ERROR, "[ENUM_FMT] index(%d) type(0x%08x) desc(%s) pxlfmt(0x%08x). (%s)\n",
200                                     desc->index, desc->type, desc->description, desc->pixelformat, strerror(errno));
201                         return TRUE;
202                 }
203
204                 desc->index++;
205         }
206
207         return FALSE;
208 }
209
210 Bool fbdev_v4l2_g_std (int fd, v4l2_std_id *std_id)
211 {
212         int ret;
213
214         ret = ioctl (fd, VIDIOC_G_STD, std_id);
215         if (ret < 0)
216         {
217                 xf86DrvMsg (0, X_ERROR, "[G_STD] failed. (%s)\n", strerror(errno));
218                 return FALSE;
219         }
220
221         return TRUE;
222 }
223
224 Bool fbdev_v4l2_s_std (int fd, v4l2_std_id std_id)
225 {
226         int ret;
227
228         ret = ioctl (fd, VIDIOC_S_STD, &std_id);
229         if (ret < 0)
230         {
231                 xf86DrvMsg (0, X_ERROR, "[S_STD] failed. (%s)\n", strerror(errno));
232                 return FALSE;
233         }
234
235         return TRUE;
236 }
237
238 Bool fbdev_v4l2_g_output (int fd, int *index)
239 {
240         int ret;
241
242         ret = ioctl (fd, VIDIOC_G_OUTPUT, index);
243         if (ret < 0)
244         {
245                 xf86DrvMsg (0, X_ERROR, "[G_OUTPUT] failed. (%s)\n", strerror(errno));
246                 return FALSE;
247         }
248
249         return TRUE;
250 }
251
252 Bool fbdev_v4l2_s_output (int fd, int index)
253 {
254         int ret;
255
256         ret = ioctl (fd, VIDIOC_S_OUTPUT, &index);
257         if (ret < 0)
258         {
259                 xf86DrvMsg (0, X_ERROR, "[S_OUTPUT] failed. (%s)\n", strerror(errno));
260                 return FALSE;
261         }
262
263         return TRUE;
264 }
265
266 Bool fbdev_v4l2_try_fmt (int fd, struct v4l2_format *format)
267 {
268         int ret;
269
270         ret = ioctl (fd, VIDIOC_TRY_FMT, format);
271         if (ret < 0)
272                 return FALSE;
273
274         return TRUE;
275 }
276
277 Bool fbdev_v4l2_g_fmt (int fd, struct v4l2_format *format)
278 {
279         int ret;
280
281         ret = ioctl (fd, VIDIOC_G_FMT, format);
282         if (ret < 0)
283         {
284                 xf86DrvMsg (0, X_ERROR, "[G_FMT] failed. (%s)\n", strerror(errno));
285                 return FALSE;
286         }
287
288         return TRUE;
289 }
290
291 Bool fbdev_v4l2_s_fmt (int fd, struct v4l2_format *format)
292 {
293         int ret;
294
295         ret = ioctl (fd, VIDIOC_S_FMT, format);
296         if (ret < 0)
297         {
298                 xf86DrvMsg (0, X_ERROR, "[S_FMT] failed. (%s)\n", strerror(errno));
299                 return FALSE;
300         }
301
302         return TRUE;
303 }
304
305 Bool fbdev_v4l2_g_parm (int fd, struct v4l2_streamparm *parm)
306 {
307         int ret;
308
309         ret = ioctl (fd, VIDIOC_G_PARM, parm);
310         if (ret < 0)
311         {
312                 xf86DrvMsg (0, X_ERROR, "[G_PARM] failed. (%s)\n", strerror(errno));
313                 return FALSE;
314         }
315
316         return TRUE;
317 }
318
319 Bool fbdev_v4l2_s_parm (int fd, struct v4l2_streamparm *parm)
320 {
321         int ret;
322
323         ret = ioctl (fd, VIDIOC_S_PARM, parm);
324         if (ret < 0)
325         {
326                 xf86DrvMsg (0, X_ERROR, "[S_PARM] failed. (%s)\n", strerror(errno));
327                 return FALSE;
328         }
329
330         return TRUE;
331 }
332
333 Bool fbdev_v4l2_g_fbuf (int fd, struct v4l2_framebuffer *frame)
334 {
335         int ret;
336
337         ret = ioctl (fd, VIDIOC_G_FBUF, frame);
338         if (ret < 0)
339         {
340                 xf86DrvMsg (0, X_ERROR, "[G_FBUF] failed. (%s)\n", strerror(errno));
341                 return FALSE;
342         }
343
344         return TRUE;
345 }
346
347 Bool fbdev_v4l2_s_fbuf (int fd, struct v4l2_framebuffer *frame)
348 {
349         int ret;
350
351         ret = ioctl (fd, VIDIOC_S_FBUF, frame);
352         if (ret < 0)
353         {
354                 xf86DrvMsg (0, X_ERROR, "[S_FBUF] failed. (%s)\n", strerror(errno));
355                 return FALSE;
356         }
357
358         return TRUE;
359 }
360
361 Bool fbdev_v4l2_g_crop (int fd, struct v4l2_crop *crop)
362 {
363         int ret;
364
365         ret = ioctl (fd, VIDIOC_G_CROP, crop);
366         if (ret < 0)
367         {
368                 xf86DrvMsg (0, X_ERROR, "[G_CROP] failed. (%s)\n", strerror(errno));
369                 return FALSE;
370         }
371
372         return TRUE;
373 }
374
375 Bool fbdev_v4l2_s_crop (int fd, struct v4l2_crop *crop)
376 {
377         int ret;
378
379         ret = ioctl (fd, VIDIOC_S_CROP, crop);
380         if (ret < 0)
381         {
382                 xf86DrvMsg (0, X_ERROR, "[S_CROP] failed. (%s)\n", strerror(errno));
383                 return FALSE;
384         }
385
386         return TRUE;
387 }
388
389 Bool fbdev_v4l2_g_ctrl (int fd, struct v4l2_control *ctrl)
390 {
391         int ret;
392
393         ret = ioctl (fd, VIDIOC_G_CTRL, ctrl);
394         if (ret < 0)
395         {
396                 xf86DrvMsg (0, X_ERROR, "[G_CTRL] failed. (%s)\n", strerror(errno));
397                 return FALSE;
398         }
399
400         return TRUE;
401 }
402
403 Bool fbdev_v4l2_s_ctrl (int fd, struct v4l2_control *ctrl)
404 {
405         int ret;
406
407         ret = ioctl (fd, VIDIOC_S_CTRL, ctrl);
408         if (ret < 0)
409         {
410                 xf86DrvMsg (0, X_ERROR, "[S_CTRL] failed. (%s)\n", strerror(errno));
411                 return FALSE;
412         }
413
414         return TRUE;
415 }
416
417 Bool fbdev_v4l2_streamon (int fd, FBDevV4l2BufType type)
418 {
419         if (!_fbdev_v4l2_ioctl (fd, VIDIOC_STREAMON, (void*)&type, "STREAMON"))
420         {
421                 xf86DrvMsg (0, X_ERROR, "[STREAMON] failed. (%s)\n", strerror(errno));
422                 return FALSE;
423         }
424
425         return TRUE;
426 }
427
428 Bool fbdev_v4l2_streamoff (int fd, FBDevV4l2BufType type)
429 {
430         if (!_fbdev_v4l2_ioctl (fd, VIDIOC_STREAMOFF, (void*)&type, "STREAMOFF"))
431         {
432                 xf86DrvMsg (0, X_ERROR, "[STREAMOFF] failed. (%s)\n", strerror(errno));
433                 return FALSE;
434         }
435
436         return TRUE;
437 }
438
439
440 Bool fbdev_v4l2_start_overlay (int fd)
441 {
442         int start = 1;
443
444         if (!_fbdev_v4l2_ioctl (fd, VIDIOC_OVERLAY, (void*)&start, "OVERLAY (start)"))
445         {
446                 xf86DrvMsg (0, X_ERROR, "[OVERLAY] (start) failed. (%s)\n", strerror(errno));
447                 return FALSE;
448         }
449
450         return TRUE;
451 }
452
453 Bool fbdev_v4l2_stop_overlay (int fd)
454 {
455         int stop = 0;
456
457         if (!_fbdev_v4l2_ioctl (fd, VIDIOC_OVERLAY, (void*)&stop, "OVERLAY (stop)"))
458         {
459                 xf86DrvMsg (0, X_ERROR, "[OVERLAY] (stop) failed. (%s)\n", strerror(errno));
460                 return FALSE;
461         }
462
463         return TRUE;
464 }
465
466 Bool fbdev_v4l2_reqbuf (int fd, struct v4l2_requestbuffers *req)
467 {
468         if (!_fbdev_v4l2_ioctl (fd, VIDIOC_REQBUFS, (void*)req, "REQBUFS"))
469         {
470                 xf86DrvMsg (0, X_ERROR, "[REQBUFS] failed. (%s)\n", strerror(errno));
471                 return FALSE;
472         }
473
474         return TRUE;
475 }
476
477 Bool fbdev_v4l2_querybuf (int fd, struct v4l2_buffer *set_buf)
478 {
479         if (!_fbdev_v4l2_ioctl (fd, VIDIOC_QUERYBUF, (void*)set_buf, "QUERYBUF"))
480         {
481                 xf86DrvMsg (0, X_ERROR, "[QUERYBUF] failed. (%s)\n", strerror(errno));
482                 return FALSE;
483         }
484
485         return TRUE;
486 }
487
488
489 Bool fbdev_v4l2_queue (int fd, struct v4l2_buffer *buf)
490 {
491         if (!_fbdev_v4l2_ioctl (fd, VIDIOC_QBUF, (void*)buf, "QBUF"))
492         {
493                 xf86DrvMsg (0, X_ERROR, "[QBUF] failed. (%s)\n", strerror(errno));
494
495                 return FALSE;
496         }
497
498         return TRUE;
499 }
500
501 Bool fbdev_v4l2_dequeue (int fd, struct v4l2_buffer *buf)
502 {
503         if (!_fbdev_v4l2_ioctl (fd, VIDIOC_DQBUF, (void*)buf, "DQBUF"))
504         {
505                 xf86DrvMsg (0, X_ERROR, "[DQBUF] failed. (%s)\n", strerror(errno));
506
507                 return FALSE;
508         }
509
510         return TRUE;
511 }