blob: 2bb1e324785bb9d5c09a6b6058cb56420becdca4 [file] [log] [blame]
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001/*
2 ioctl system call
3 Copyright (C) 2003-2004 Kevin Thayer <nufan_wfk at yahoo.com>
4 Copyright (C) 2005-2007 Hans Verkuil <hverkuil@xs4all.nl>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include "ivtv-driver.h"
22#include "ivtv-version.h"
23#include "ivtv-mailbox.h"
24#include "ivtv-i2c.h"
25#include "ivtv-queue.h"
26#include "ivtv-fileops.h"
27#include "ivtv-vbi.h"
28#include "ivtv-audio.h"
29#include "ivtv-video.h"
30#include "ivtv-streams.h"
31#include "ivtv-yuv.h"
32#include "ivtv-ioctl.h"
33#include "ivtv-gpio.h"
34#include "ivtv-controls.h"
35#include "ivtv-cards.h"
36#include <media/saa7127.h>
37#include <media/tveeprom.h>
38#include <media/v4l2-chip-ident.h>
39#include <linux/dvb/audio.h>
40#include <linux/i2c-id.h>
41
42u16 service2vbi(int type)
43{
44 switch (type) {
45 case V4L2_SLICED_TELETEXT_B:
46 return IVTV_SLICED_TYPE_TELETEXT_B;
47 case V4L2_SLICED_CAPTION_525:
48 return IVTV_SLICED_TYPE_CAPTION_525;
49 case V4L2_SLICED_WSS_625:
50 return IVTV_SLICED_TYPE_WSS_625;
51 case V4L2_SLICED_VPS:
52 return IVTV_SLICED_TYPE_VPS;
53 default:
54 return 0;
55 }
56}
57
58static int valid_service_line(int field, int line, int is_pal)
59{
60 return (is_pal && line >= 6 && (line != 23 || field == 0)) ||
61 (!is_pal && line >= 10 && line < 22);
62}
63
64static u16 select_service_from_set(int field, int line, u16 set, int is_pal)
65{
66 u16 valid_set = (is_pal ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525);
67 int i;
68
69 set = set & valid_set;
70 if (set == 0 || !valid_service_line(field, line, is_pal)) {
71 return 0;
72 }
73 if (!is_pal) {
74 if (line == 21 && (set & V4L2_SLICED_CAPTION_525))
75 return V4L2_SLICED_CAPTION_525;
76 }
77 else {
78 if (line == 16 && field == 0 && (set & V4L2_SLICED_VPS))
79 return V4L2_SLICED_VPS;
80 if (line == 23 && field == 0 && (set & V4L2_SLICED_WSS_625))
81 return V4L2_SLICED_WSS_625;
82 if (line == 23)
83 return 0;
84 }
85 for (i = 0; i < 32; i++) {
86 if ((1 << i) & set)
87 return 1 << i;
88 }
89 return 0;
90}
91
92void expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
93{
94 u16 set = fmt->service_set;
95 int f, l;
96
97 fmt->service_set = 0;
98 for (f = 0; f < 2; f++) {
99 for (l = 0; l < 24; l++) {
100 fmt->service_lines[f][l] = select_service_from_set(f, l, set, is_pal);
101 }
102 }
103}
104
105static int check_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal)
106{
107 int f, l;
108 u16 set = 0;
109
110 for (f = 0; f < 2; f++) {
111 for (l = 0; l < 24; l++) {
112 fmt->service_lines[f][l] = select_service_from_set(f, l, fmt->service_lines[f][l], is_pal);
113 set |= fmt->service_lines[f][l];
114 }
115 }
116 return set != 0;
117}
118
119u16 get_service_set(struct v4l2_sliced_vbi_format *fmt)
120{
121 int f, l;
122 u16 set = 0;
123
124 for (f = 0; f < 2; f++) {
125 for (l = 0; l < 24; l++) {
126 set |= fmt->service_lines[f][l];
127 }
128 }
129 return set;
130}
131
132static const struct {
133 v4l2_std_id std;
134 char *name;
135} enum_stds[] = {
136 { V4L2_STD_PAL_BG | V4L2_STD_PAL_H, "PAL-BGH" },
137 { V4L2_STD_PAL_DK, "PAL-DK" },
138 { V4L2_STD_PAL_I, "PAL-I" },
139 { V4L2_STD_PAL_M, "PAL-M" },
140 { V4L2_STD_PAL_N, "PAL-N" },
141 { V4L2_STD_PAL_Nc, "PAL-Nc" },
142 { V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H, "SECAM-BGH" },
143 { V4L2_STD_SECAM_DK, "SECAM-DK" },
144 { V4L2_STD_SECAM_L, "SECAM-L" },
145 { V4L2_STD_SECAM_LC, "SECAM-L'" },
146 { V4L2_STD_NTSC_M, "NTSC-M" },
147 { V4L2_STD_NTSC_M_JP, "NTSC-J" },
148 { V4L2_STD_NTSC_M_KR, "NTSC-K" },
149};
150
151static const struct v4l2_standard ivtv_std_60hz =
152{
153 .frameperiod = {.numerator = 1001, .denominator = 30000},
154 .framelines = 525,
155};
156
157static const struct v4l2_standard ivtv_std_50hz =
158{
159 .frameperiod = {.numerator = 1, .denominator = 25},
160 .framelines = 625,
161};
162
163void ivtv_set_osd_alpha(struct ivtv *itv)
164{
165 ivtv_vapi(itv, CX2341X_OSD_SET_GLOBAL_ALPHA, 3,
166 itv->osd_global_alpha_state, itv->osd_global_alpha, !itv->osd_local_alpha_state);
167 ivtv_vapi(itv, CX2341X_OSD_SET_CHROMA_KEY, 2, itv->osd_color_key_state, itv->osd_color_key);
168}
169
170int ivtv_set_speed(struct ivtv *itv, int speed)
171{
172 u32 data[CX2341X_MBOX_MAX_DATA];
173 struct ivtv_stream *s;
174 int single_step = (speed == 1 || speed == -1);
175 DEFINE_WAIT(wait);
176
177 if (speed == 0) speed = 1000;
178
179 /* No change? */
180 if (speed == itv->speed && !single_step)
181 return 0;
182
183 s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
184
185 if (single_step && (speed < 0) == (itv->speed < 0)) {
186 /* Single step video and no need to change direction */
187 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
188 itv->speed = speed;
189 return 0;
190 }
191 if (single_step)
192 /* Need to change direction */
193 speed = speed < 0 ? -1000 : 1000;
194
195 data[0] = (speed > 1000 || speed < -1000) ? 0x80000000 : 0;
196 data[0] |= (speed > 1000 || speed < -1500) ? 0x40000000 : 0;
197 data[1] = (speed < 0);
198 data[2] = speed < 0 ? 3 : 7;
199 data[3] = itv->params.video_b_frames;
200 data[4] = (speed == 1500 || speed == 500) ? itv->speed_mute_audio : 0;
201 data[5] = 0;
202 data[6] = 0;
203
204 if (speed == 1500 || speed == -1500) data[0] |= 1;
205 else if (speed == 2000 || speed == -2000) data[0] |= 2;
206 else if (speed > -1000 && speed < 0) data[0] |= (-1000 / speed);
207 else if (speed < 1000 && speed > 0) data[0] |= (1000 / speed);
208
209 /* If not decoding, just change speed setting */
210 if (atomic_read(&itv->decoding) > 0) {
211 int got_sig = 0;
212
213 /* Stop all DMA and decoding activity */
214 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1, 0);
215
216 /* Wait for any DMA to finish */
217 prepare_to_wait(&itv->dma_waitq, &wait, TASK_INTERRUPTIBLE);
218 while (itv->i_flags & IVTV_F_I_DMA) {
219 got_sig = signal_pending(current);
220 if (got_sig)
221 break;
222 got_sig = 0;
223 schedule();
224 }
225 finish_wait(&itv->dma_waitq, &wait);
226 if (got_sig)
227 return -EINTR;
228
229 /* Change Speed safely */
230 ivtv_api(itv, CX2341X_DEC_SET_PLAYBACK_SPEED, 7, data);
231 IVTV_DEBUG_INFO("Setting Speed to 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x 0x%08x\n",
232 data[0], data[1], data[2], data[3], data[4], data[5], data[6]);
233 }
234 if (single_step) {
235 speed = (speed < 0) ? -1 : 1;
236 ivtv_vapi(itv, CX2341X_DEC_STEP_VIDEO, 1, 0);
237 }
238 itv->speed = speed;
239 return 0;
240}
241
242static int ivtv_validate_speed(int cur_speed, int new_speed)
243{
244 int fact = new_speed < 0 ? -1 : 1;
245 int s;
246
247 if (new_speed < 0) new_speed = -new_speed;
248 if (cur_speed < 0) cur_speed = -cur_speed;
249
250 if (cur_speed <= new_speed) {
251 if (new_speed > 1500) return fact * 2000;
252 if (new_speed > 1000) return fact * 1500;
253 }
254 else {
255 if (new_speed >= 2000) return fact * 2000;
256 if (new_speed >= 1500) return fact * 1500;
257 if (new_speed >= 1000) return fact * 1000;
258 }
259 if (new_speed == 0) return 1000;
260 if (new_speed == 1 || new_speed == 1000) return fact * new_speed;
261
262 s = new_speed;
263 new_speed = 1000 / new_speed;
264 if (1000 / cur_speed == new_speed)
265 new_speed += (cur_speed < s) ? -1 : 1;
266 if (new_speed > 60) return 1000 / (fact * 60);
267 return 1000 / (fact * new_speed);
268}
269
270static int ivtv_video_command(struct ivtv *itv, struct ivtv_open_id *id,
271 struct video_command *vc, int try)
272{
273 struct ivtv_stream *s = &itv->streams[IVTV_DEC_STREAM_TYPE_MPG];
274
275 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
276 return -EINVAL;
277
278 switch (vc->cmd) {
279 case VIDEO_CMD_PLAY: {
Hans Verkuil25415cf2007-03-10 18:29:48 -0300280 vc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300281 vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed);
282 if (vc->play.speed < 0)
283 vc->play.format = VIDEO_PLAY_FMT_GOP;
284 if (try) break;
285
286 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
287 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300288 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
289 /* forces ivtv_set_speed to be called */
290 itv->speed = 0;
291 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300292 return ivtv_start_decoding(id, vc->play.speed);
293 }
294
295 case VIDEO_CMD_STOP:
Hans Verkuil018ba852007-04-10 18:59:09 -0300296 vc->flags &= VIDEO_CMD_STOP_IMMEDIATELY|VIDEO_CMD_STOP_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300297 if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
298 vc->stop.pts = 0;
299 if (try) break;
300 if (atomic_read(&itv->decoding) == 0)
301 return 0;
302 if (itv->output_mode != OUT_MPG)
303 return -EBUSY;
304
305 itv->output_mode = OUT_NONE;
306 return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
307
308 case VIDEO_CMD_FREEZE:
Hans Verkuil018ba852007-04-10 18:59:09 -0300309 vc->flags &= VIDEO_CMD_FREEZE_TO_BLACK;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300310 if (try) break;
311 if (itv->output_mode != OUT_MPG)
312 return -EBUSY;
313 if (atomic_read(&itv->decoding) > 0) {
314 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
315 (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
Hans Verkuilac425142007-07-22 08:46:38 -0300316 set_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300317 }
318 break;
319
320 case VIDEO_CMD_CONTINUE:
Hans Verkuil25415cf2007-03-10 18:29:48 -0300321 vc->flags = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300322 if (try) break;
323 if (itv->output_mode != OUT_MPG)
324 return -EBUSY;
Hans Verkuilac425142007-07-22 08:46:38 -0300325 if (test_and_clear_bit(IVTV_F_I_DEC_PAUSED, &itv->i_flags)) {
326 int speed = itv->speed;
327 itv->speed = 0;
328 return ivtv_start_decoding(id, speed);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300329 }
330 break;
331
332 default:
333 return -EINVAL;
334 }
335 return 0;
336}
337
338static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
339{
340 struct v4l2_register *regs = arg;
341 unsigned long flags;
342 volatile u8 __iomem *reg_start;
343
344 if (!capable(CAP_SYS_ADMIN))
345 return -EPERM;
346 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
347 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
348 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
349 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
350 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
351 else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE)
352 reg_start = itv->enc_mem;
353 else
354 return -EINVAL;
355
356 spin_lock_irqsave(&ivtv_cards_lock, flags);
357 if (cmd == VIDIOC_DBG_G_REGISTER) {
358 regs->val = readl(regs->reg + reg_start);
359 } else {
360 writel(regs->val, regs->reg + reg_start);
361 }
362 spin_unlock_irqrestore(&ivtv_cards_lock, flags);
363 return 0;
364}
365
366static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fmt)
367{
368 switch (fmt->type) {
369 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
370 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
371 return -EINVAL;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300372 fmt->fmt.pix.width = itv->main_rect.width;
373 fmt->fmt.pix.height = itv->main_rect.height;
374 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
375 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
376 if (itv->output_mode == OUT_UDMA_YUV) {
377 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
378 case IVTV_YUV_MODE_INTERLACED:
379 fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
380 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
381 break;
382 case IVTV_YUV_MODE_PROGRESSIVE:
383 fmt->fmt.pix.field = V4L2_FIELD_NONE;
384 break;
385 default:
386 fmt->fmt.pix.field = V4L2_FIELD_ANY;
387 break;
388 }
389 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
390 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
391 fmt->fmt.pix.sizeimage =
392 fmt->fmt.pix.height * fmt->fmt.pix.width +
393 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
394 }
395 else if (itv->output_mode == OUT_YUV ||
396 streamtype == IVTV_ENC_STREAM_TYPE_YUV ||
397 streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
398 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
399 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
400 fmt->fmt.pix.sizeimage =
401 fmt->fmt.pix.height * fmt->fmt.pix.width +
402 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
403 } else {
404 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
405 fmt->fmt.pix.sizeimage = 128 * 1024;
406 }
407 break;
408
409 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300410 fmt->fmt.pix.width = itv->params.width;
411 fmt->fmt.pix.height = itv->params.height;
412 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
413 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
414 if (streamtype == IVTV_ENC_STREAM_TYPE_YUV ||
415 streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
416 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
417 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
418 fmt->fmt.pix.sizeimage =
419 fmt->fmt.pix.height * fmt->fmt.pix.width +
420 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
421 } else {
422 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
423 fmt->fmt.pix.sizeimage = 128 * 1024;
424 }
425 break;
426
427 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
428 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
429 return -EINVAL;
430 fmt->fmt.win.chromakey = itv->osd_color_key;
431 fmt->fmt.win.global_alpha = itv->osd_global_alpha;
432 break;
433
434 case V4L2_BUF_TYPE_VBI_CAPTURE:
435 fmt->fmt.vbi.sampling_rate = 27000000;
436 fmt->fmt.vbi.offset = 248;
437 fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4;
438 fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
439 fmt->fmt.vbi.start[0] = itv->vbi.start[0];
440 fmt->fmt.vbi.start[1] = itv->vbi.start[1];
441 fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count;
442 break;
443
444 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
445 {
446 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
447
448 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
449 return -EINVAL;
450 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
451 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
452 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
453 if (itv->is_60hz) {
454 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
455 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
456 } else {
457 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
458 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
459 }
460 vbifmt->service_set = get_service_set(vbifmt);
461 break;
462 }
463
464 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
465 {
466 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
467
468 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
469 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
470 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
471
472 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
473 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
474 V4L2_SLICED_VBI_525;
475 expand_service_set(vbifmt, itv->is_50hz);
476 break;
477 }
478
479 itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
480 vbifmt->service_set = get_service_set(vbifmt);
481 break;
482 }
483 case V4L2_BUF_TYPE_VBI_OUTPUT:
484 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
485 default:
486 return -EINVAL;
487 }
488 return 0;
489}
490
491static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
492 struct v4l2_format *fmt, int set_fmt)
493{
494 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
495 u16 set;
496
497 if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
498 struct v4l2_rect r;
499 int field;
500
501 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
502 return -EINVAL;
503 field = fmt->fmt.pix.field;
Hans Verkuilc74e83a2007-05-17 06:41:44 -0300504 r.top = 0;
505 r.left = 0;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300506 r.width = fmt->fmt.pix.width;
507 r.height = fmt->fmt.pix.height;
508 ivtv_get_fmt(itv, streamtype, fmt);
509 if (itv->output_mode != OUT_UDMA_YUV) {
510 /* TODO: would setting the rect also be valid for this mode? */
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300511 fmt->fmt.pix.width = r.width;
512 fmt->fmt.pix.height = r.height;
513 }
514 if (itv->output_mode == OUT_UDMA_YUV) {
515 /* TODO: add checks for validity */
516 fmt->fmt.pix.field = field;
517 }
518 if (set_fmt) {
519 if (itv->output_mode == OUT_UDMA_YUV) {
520 switch (field) {
521 case V4L2_FIELD_NONE:
522 itv->yuv_info.lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
523 break;
524 case V4L2_FIELD_ANY:
525 itv->yuv_info.lace_mode = IVTV_YUV_MODE_AUTO;
526 break;
527 case V4L2_FIELD_INTERLACED_BT:
528 itv->yuv_info.lace_mode =
529 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
530 break;
531 case V4L2_FIELD_INTERLACED_TB:
532 default:
533 itv->yuv_info.lace_mode = IVTV_YUV_MODE_INTERLACED;
534 break;
535 }
536 itv->yuv_info.lace_sync_field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
537
538 /* Force update of yuv registers */
539 itv->yuv_info.yuv_forced_update = 1;
540 return 0;
541 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300542 }
543 return 0;
544 }
545
546 if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) {
547 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
548 return -EINVAL;
549 if (set_fmt) {
550 itv->osd_color_key = fmt->fmt.win.chromakey;
551 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
552 ivtv_set_osd_alpha(itv);
553 }
554 return 0;
555 }
556
557 /* set window size */
558 if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
559 int w = fmt->fmt.pix.width;
560 int h = fmt->fmt.pix.height;
561
562 if (w > 720) w = 720;
563 else if (w < 1) w = 1;
564 if (h > (itv->is_50hz ? 576 : 480)) h = (itv->is_50hz ? 576 : 480);
565 else if (h < 2) h = 2;
566 ivtv_get_fmt(itv, streamtype, fmt);
567 fmt->fmt.pix.width = w;
568 fmt->fmt.pix.height = h;
569
570 if (!set_fmt || (itv->params.width == w && itv->params.height == h))
571 return 0;
572 if (atomic_read(&itv->capturing) > 0)
573 return -EBUSY;
574
575 itv->params.width = w;
576 itv->params.height = h;
577 if (w != 720 || h != (itv->is_50hz ? 576 : 480))
578 itv->params.video_temporal_filter = 0;
579 else
580 itv->params.video_temporal_filter = 8;
581 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
582 return ivtv_get_fmt(itv, streamtype, fmt);
583 }
584
585 /* set raw VBI format */
586 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) {
587 if (set_fmt && streamtype == IVTV_ENC_STREAM_TYPE_VBI &&
588 itv->vbi.sliced_in->service_set &&
589 atomic_read(&itv->capturing) > 0) {
590 return -EBUSY;
591 }
592 if (set_fmt) {
593 itv->vbi.sliced_in->service_set = 0;
594 itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
595 }
596 return ivtv_get_fmt(itv, streamtype, fmt);
597 }
598
599 /* set sliced VBI output
600 In principle the user could request that only certain
601 VBI types are output and that the others are ignored.
602 I.e., suppress CC in the even fields or only output
603 WSS and no VPS. Currently though there is no choice. */
604 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
605 return ivtv_get_fmt(itv, streamtype, fmt);
606
607 /* any else but sliced VBI capture is an error */
608 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
609 return -EINVAL;
610
611 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI)
612 return ivtv_get_fmt(itv, streamtype, fmt);
613
614 /* set sliced VBI capture format */
615 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
616 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
617
618 if (vbifmt->service_set)
619 expand_service_set(vbifmt, itv->is_50hz);
620 set = check_service_set(vbifmt, itv->is_50hz);
621 vbifmt->service_set = get_service_set(vbifmt);
622
623 if (!set_fmt)
624 return 0;
625 if (set == 0)
626 return -EINVAL;
627 if (atomic_read(&itv->capturing) > 0 && itv->vbi.sliced_in->service_set == 0) {
628 return -EBUSY;
629 }
630 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
631 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
632 return 0;
633}
634
Hans Verkuild4e7ee32007-03-10 18:19:12 -0300635static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300636{
637 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
638 struct ivtv *itv = id->itv;
639 struct v4l2_register *reg = arg;
640
641 switch (cmd) {
642 /* ioctls to allow direct access to the encoder registers for testing */
643 case VIDIOC_DBG_G_REGISTER:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300644 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
645 return ivtv_itvc(itv, cmd, arg);
646 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
647 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
648 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
649
650 case VIDIOC_DBG_S_REGISTER:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300651 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
652 return ivtv_itvc(itv, cmd, arg);
653 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
654 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
655 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
656
657 case VIDIOC_G_CHIP_IDENT: {
658 struct v4l2_chip_ident *chip = arg;
659
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300660 chip->ident = V4L2_IDENT_NONE;
661 chip->revision = 0;
662 if (reg->match_type == V4L2_CHIP_MATCH_HOST) {
663 if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) {
664 struct v4l2_chip_ident *chip = arg;
665
666 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
667 }
668 return 0;
669 }
670 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
671 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
672 if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
673 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
674 return -EINVAL;
675 }
676
677 case VIDIOC_INT_S_AUDIO_ROUTING: {
678 struct v4l2_routing *route = arg;
679
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300680 ivtv_audio_set_route(itv, route);
681 break;
682 }
683
Hans Verkuil2cc72092007-08-04 05:06:23 -0300684 case VIDIOC_INT_RESET: {
685 u32 val = *(u32 *)arg;
686
687 if ((val == 0 && itv->options.newi2c) || (val & 0x01)) {
688 ivtv_reset_ir_gpio(itv);
689 }
690 if (val & 0x02) {
691 itv->video_dec_func(itv, cmd, 0);
692 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300693 break;
Hans Verkuil2cc72092007-08-04 05:06:23 -0300694 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300695
696 default:
697 return -EINVAL;
698 }
699 return 0;
700}
701
702int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
703{
704 struct ivtv_open_id *id = NULL;
705
706 if (filp) id = (struct ivtv_open_id *)filp->private_data;
707
708 switch (cmd) {
Hans Verkuild46c17d2007-03-10 17:59:15 -0300709 case VIDIOC_G_PRIORITY:
710 {
711 enum v4l2_priority *p = arg;
712
713 *p = v4l2_prio_max(&itv->prio);
714 break;
715 }
716
717 case VIDIOC_S_PRIORITY:
718 {
719 enum v4l2_priority *prio = arg;
720
721 return v4l2_prio_change(&itv->prio, &id->prio, *prio);
722 }
723
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300724 case VIDIOC_QUERYCAP:{
725 struct v4l2_capability *vcap = arg;
726
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300727 memset(vcap, 0, sizeof(*vcap));
728 strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */
729 strcpy(vcap->card, itv->card_name); /* card type */
730 strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */
731 vcap->version = IVTV_DRIVER_VERSION; /* version */
732 vcap->capabilities = itv->v4l2_cap; /* capabilities */
733
734 /* reserved.. must set to 0! */
735 vcap->reserved[0] = vcap->reserved[1] =
736 vcap->reserved[2] = vcap->reserved[3] = 0;
737 break;
738 }
739
740 case VIDIOC_ENUMAUDIO:{
741 struct v4l2_audio *vin = arg;
742
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300743 return ivtv_get_audio_input(itv, vin->index, vin);
744 }
745
746 case VIDIOC_G_AUDIO:{
747 struct v4l2_audio *vin = arg;
748
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300749 vin->index = itv->audio_input;
750 return ivtv_get_audio_input(itv, vin->index, vin);
751 }
752
753 case VIDIOC_S_AUDIO:{
754 struct v4l2_audio *vout = arg;
755
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300756 if (vout->index >= itv->nof_audio_inputs)
757 return -EINVAL;
758 itv->audio_input = vout->index;
759 ivtv_audio_set_io(itv);
760 break;
761 }
762
763 case VIDIOC_ENUMAUDOUT:{
764 struct v4l2_audioout *vin = arg;
765
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300766 /* set it to defaults from our table */
767 return ivtv_get_audio_output(itv, vin->index, vin);
768 }
769
770 case VIDIOC_G_AUDOUT:{
771 struct v4l2_audioout *vin = arg;
772
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300773 vin->index = 0;
774 return ivtv_get_audio_output(itv, vin->index, vin);
775 }
776
777 case VIDIOC_S_AUDOUT:{
778 struct v4l2_audioout *vout = arg;
779
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300780 return ivtv_get_audio_output(itv, vout->index, vout);
781 }
782
783 case VIDIOC_ENUMINPUT:{
784 struct v4l2_input *vin = arg;
785
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300786 /* set it to defaults from our table */
787 return ivtv_get_input(itv, vin->index, vin);
788 }
789
790 case VIDIOC_ENUMOUTPUT:{
791 struct v4l2_output *vout = arg;
792
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300793 return ivtv_get_output(itv, vout->index, vout);
794 }
795
796 case VIDIOC_TRY_FMT:
797 case VIDIOC_S_FMT: {
798 struct v4l2_format *fmt = arg;
799
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300800 return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT);
801 }
802
803 case VIDIOC_G_FMT: {
804 struct v4l2_format *fmt = arg;
805 int type = fmt->type;
806
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300807 memset(fmt, 0, sizeof(*fmt));
808 fmt->type = type;
809 return ivtv_get_fmt(itv, id->type, fmt);
810 }
811
Hans Verkuil987e00b2007-05-29 13:03:27 -0300812 case VIDIOC_CROPCAP: {
813 struct v4l2_cropcap *cropcap = arg;
814
815 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
816 cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
817 return -EINVAL;
818 cropcap->bounds.top = cropcap->bounds.left = 0;
819 cropcap->bounds.width = 720;
820 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
821 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
822 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
823 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
824 } else {
825 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
826 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
827 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
828 }
829 cropcap->defrect = cropcap->bounds;
830 return 0;
831 }
832
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300833 case VIDIOC_S_CROP: {
834 struct v4l2_crop *crop = arg;
835
Hans Verkuil987e00b2007-05-29 13:03:27 -0300836 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
837 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
838 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
839 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
840 itv->main_rect = crop->c;
841 return 0;
842 }
843 return -EINVAL;
844 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300845 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
846 return -EINVAL;
847 return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
848 }
849
850 case VIDIOC_G_CROP: {
851 struct v4l2_crop *crop = arg;
852
Hans Verkuil987e00b2007-05-29 13:03:27 -0300853 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
854 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
855 crop->c = itv->main_rect;
856 return 0;
857 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300858 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
859 return -EINVAL;
860 return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
861 }
862
863 case VIDIOC_ENUM_FMT: {
864 static struct v4l2_fmtdesc formats[] = {
865 { 0, 0, 0,
866 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12,
867 { 0, 0, 0, 0 }
868 },
869 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
870 "MPEG", V4L2_PIX_FMT_MPEG,
871 { 0, 0, 0, 0 }
872 }
873 };
874 struct v4l2_fmtdesc *fmt = arg;
875 enum v4l2_buf_type type = fmt->type;
876
877 switch (type) {
878 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
879 break;
880 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
881 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
882 return -EINVAL;
883 break;
884 default:
885 return -EINVAL;
886 }
887 if (fmt->index > 1)
888 return -EINVAL;
889 *fmt = formats[fmt->index];
890 fmt->type = type;
891 return 0;
892 }
893
894 case VIDIOC_G_INPUT:{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300895 *(int *)arg = itv->active_input;
896 break;
897 }
898
899 case VIDIOC_S_INPUT:{
900 int inp = *(int *)arg;
901
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300902 if (inp < 0 || inp >= itv->nof_inputs)
903 return -EINVAL;
904
905 if (inp == itv->active_input) {
906 IVTV_DEBUG_INFO("Input unchanged\n");
907 break;
908 }
Hans Verkuil3562c432007-08-18 11:46:05 -0300909 if (atomic_read(&itv->capturing) > 0) {
910 return -EBUSY;
911 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300912 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
913 itv->active_input, inp);
914
915 itv->active_input = inp;
916 /* Set the audio input to whatever is appropriate for the
917 input type. */
918 itv->audio_input = itv->card->video_inputs[inp].audio_index;
919
920 /* prevent others from messing with the streams until
921 we're finished changing inputs. */
922 ivtv_mute(itv);
923 ivtv_video_set_io(itv);
924 ivtv_audio_set_io(itv);
925 ivtv_unmute(itv);
926 break;
927 }
928
929 case VIDIOC_G_OUTPUT:{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300930 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
931 return -EINVAL;
932 *(int *)arg = itv->active_output;
933 break;
934 }
935
936 case VIDIOC_S_OUTPUT:{
937 int outp = *(int *)arg;
938 struct v4l2_routing route;
939
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300940 if (outp >= itv->card->nof_outputs)
941 return -EINVAL;
942
943 if (outp == itv->active_output) {
944 IVTV_DEBUG_INFO("Output unchanged\n");
945 break;
946 }
947 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
948 itv->active_output, outp);
949
950 itv->active_output = outp;
951 route.input = SAA7127_INPUT_TYPE_NORMAL;
952 route.output = itv->card->video_outputs[outp].video_output;
953 ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
954 break;
955 }
956
957 case VIDIOC_G_FREQUENCY:{
958 struct v4l2_frequency *vf = arg;
959
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300960 if (vf->tuner != 0)
961 return -EINVAL;
962 ivtv_call_i2c_clients(itv, cmd, arg);
963 break;
964 }
965
966 case VIDIOC_S_FREQUENCY:{
967 struct v4l2_frequency vf = *(struct v4l2_frequency *)arg;
968
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300969 if (vf.tuner != 0)
970 return -EINVAL;
971
972 ivtv_mute(itv);
973 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency);
974 ivtv_call_i2c_clients(itv, cmd, &vf);
975 ivtv_unmute(itv);
976 break;
977 }
978
979 case VIDIOC_ENUMSTD:{
980 struct v4l2_standard *vs = arg;
981 int idx = vs->index;
982
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300983 if (idx < 0 || idx >= ARRAY_SIZE(enum_stds))
984 return -EINVAL;
985
986 *vs = (enum_stds[idx].std & V4L2_STD_525_60) ?
987 ivtv_std_60hz : ivtv_std_50hz;
988 vs->index = idx;
989 vs->id = enum_stds[idx].std;
990 strcpy(vs->name, enum_stds[idx].name);
991 break;
992 }
993
994 case VIDIOC_G_STD:{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300995 *(v4l2_std_id *) arg = itv->std;
996 break;
997 }
998
999 case VIDIOC_S_STD: {
1000 v4l2_std_id std = *(v4l2_std_id *) arg;
1001
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001002 if ((std & V4L2_STD_ALL) == 0)
1003 return -EINVAL;
1004
1005 if (std == itv->std)
1006 break;
1007
1008 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1009 atomic_read(&itv->capturing) > 0 ||
1010 atomic_read(&itv->decoding) > 0) {
1011 /* Switching standard would turn off the radio or mess
1012 with already running streams, prevent that by
1013 returning EBUSY. */
1014 return -EBUSY;
1015 }
1016
1017 itv->std = std;
1018 itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
1019 itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
1020 itv->params.width = 720;
1021 itv->params.height = itv->is_50hz ? 576 : 480;
1022 itv->vbi.count = itv->is_50hz ? 18 : 12;
1023 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1024 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1025 if (itv->hw_flags & IVTV_HW_CX25840) {
1026 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1027 }
Hans Verkuilc4385092007-06-07 09:04:03 -03001028 IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001029
1030 /* Tuner */
1031 ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
1032
1033 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1034 /* set display standard */
1035 itv->std_out = std;
1036 itv->is_out_60hz = itv->is_60hz;
1037 itv->is_out_50hz = itv->is_50hz;
1038 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
1039 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1040 itv->main_rect.left = itv->main_rect.top = 0;
1041 itv->main_rect.width = 720;
1042 itv->main_rect.height = itv->params.height;
1043 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1044 720, itv->main_rect.height, 0, 0);
1045 }
1046 break;
1047 }
1048
1049 case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */
1050 struct v4l2_tuner *vt = arg;
1051
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001052 if (vt->index != 0)
1053 return -EINVAL;
1054
1055 ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
1056 break;
1057 }
1058
1059 case VIDIOC_G_TUNER: {
1060 struct v4l2_tuner *vt = arg;
1061
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001062 if (vt->index != 0)
1063 return -EINVAL;
1064
1065 memset(vt, 0, sizeof(*vt));
1066 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
1067
1068 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1069 strcpy(vt->name, "ivtv Radio Tuner");
1070 vt->type = V4L2_TUNER_RADIO;
1071 } else {
1072 strcpy(vt->name, "ivtv TV Tuner");
1073 vt->type = V4L2_TUNER_ANALOG_TV;
1074 }
1075 break;
1076 }
1077
1078 case VIDIOC_G_SLICED_VBI_CAP: {
1079 struct v4l2_sliced_vbi_cap *cap = arg;
1080 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1081 int f, l;
1082 enum v4l2_buf_type type = cap->type;
1083
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001084 memset(cap, 0, sizeof(*cap));
1085 cap->type = type;
1086 if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1087 for (f = 0; f < 2; f++) {
1088 for (l = 0; l < 24; l++) {
1089 if (valid_service_line(f, l, itv->is_50hz)) {
1090 cap->service_lines[f][l] = set;
1091 }
1092 }
1093 }
1094 return 0;
1095 }
1096 if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
1097 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1098 return -EINVAL;
1099 if (itv->is_60hz) {
1100 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1101 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1102 } else {
1103 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1104 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1105 }
1106 return 0;
1107 }
1108 return -EINVAL;
1109 }
1110
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001111 case VIDIOC_G_ENC_INDEX: {
1112 struct v4l2_enc_idx *idx = arg;
Hans Verkuil5614b022007-08-23 17:48:41 -03001113 struct v4l2_enc_idx_entry *e = idx->entry;
1114 int entries;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001115 int i;
1116
Hans Verkuil5614b022007-08-23 17:48:41 -03001117 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001118 IVTV_MAX_PGM_INDEX;
Hans Verkuil5614b022007-08-23 17:48:41 -03001119 if (entries > V4L2_ENC_IDX_ENTRIES)
1120 entries = V4L2_ENC_IDX_ENTRIES;
1121 idx->entries = 0;
1122 for (i = 0; i < entries; i++) {
1123 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1124 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1125 idx->entries++;
1126 e++;
1127 }
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001128 }
1129 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1130 break;
1131 }
1132
1133 case VIDIOC_ENCODER_CMD:
1134 case VIDIOC_TRY_ENCODER_CMD: {
1135 struct v4l2_encoder_cmd *enc = arg;
1136 int try = cmd == VIDIOC_TRY_ENCODER_CMD;
1137
Hans Verkuil25415cf2007-03-10 18:29:48 -03001138 memset(&enc->raw, 0, sizeof(enc->raw));
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001139 switch (enc->cmd) {
1140 case V4L2_ENC_CMD_START:
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001141 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
Hans Verkuil25415cf2007-03-10 18:29:48 -03001142 enc->flags = 0;
1143 if (try)
1144 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001145 return ivtv_start_capture(id);
1146
1147 case V4L2_ENC_CMD_STOP:
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001148 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
Hans Verkuil018ba852007-04-10 18:59:09 -03001149 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
Hans Verkuil25415cf2007-03-10 18:29:48 -03001150 if (try)
1151 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001152 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1153 return 0;
1154
1155 case V4L2_ENC_CMD_PAUSE:
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001156 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
Hans Verkuil25415cf2007-03-10 18:29:48 -03001157 enc->flags = 0;
1158 if (try)
1159 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001160 if (!atomic_read(&itv->capturing))
1161 return -EPERM;
1162 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1163 return 0;
1164 ivtv_mute(itv);
1165 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1166 break;
1167
1168 case V4L2_ENC_CMD_RESUME:
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001169 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
Hans Verkuil25415cf2007-03-10 18:29:48 -03001170 enc->flags = 0;
1171 if (try)
1172 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001173 if (!atomic_read(&itv->capturing))
1174 return -EPERM;
1175 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1176 return 0;
1177 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1178 ivtv_unmute(itv);
1179 break;
Hans Verkuil25415cf2007-03-10 18:29:48 -03001180 default:
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001181 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
Hans Verkuil25415cf2007-03-10 18:29:48 -03001182 return -EINVAL;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001183 }
1184 break;
1185 }
1186
1187 case VIDIOC_G_FBUF: {
1188 struct v4l2_framebuffer *fb = arg;
1189
1190 memset(fb, 0, sizeof(*fb));
1191 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuilf5948bb2007-06-16 18:24:47 -03001192 return -EINVAL;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001193 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1194 V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA;
1195 fb->fmt.pixelformat = itv->osd_pixelformat;
1196 fb->fmt.width = itv->osd_rect.width;
1197 fb->fmt.height = itv->osd_rect.height;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001198 fb->base = (void *)itv->osd_video_pbase;
1199 if (itv->osd_global_alpha_state)
1200 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1201 if (itv->osd_local_alpha_state)
1202 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1203 if (itv->osd_color_key_state)
1204 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1205 break;
1206 }
1207
1208 case VIDIOC_S_FBUF: {
1209 struct v4l2_framebuffer *fb = arg;
1210
1211 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuilf5948bb2007-06-16 18:24:47 -03001212 return -EINVAL;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001213 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1214 itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0;
1215 itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
Hans Verkuilc3624f92007-07-31 07:15:56 -03001216 ivtv_set_osd_alpha(itv);
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001217 break;
1218 }
1219
Hans Verkuil7c03a442007-08-19 18:59:42 -03001220 case VIDIOC_OVERLAY: {
1221 int *on = arg;
1222
1223 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1224 return -EINVAL;
1225 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0);
1226 break;
1227 }
1228
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001229 case VIDIOC_LOG_STATUS:
1230 {
1231 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
Hans Verkuil7c03a442007-08-19 18:59:42 -03001232 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001233 struct v4l2_input vidin;
1234 struct v4l2_audio audin;
1235 int i;
1236
1237 IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num);
Hans Verkuil94104aa2007-08-04 04:56:00 -03001238 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001239 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1240 struct tveeprom tv;
1241
1242 ivtv_read_eeprom(itv, &tv);
1243 }
1244 ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
1245 ivtv_get_input(itv, itv->active_input, &vidin);
1246 ivtv_get_audio_input(itv, itv->audio_input, &audin);
Hans Verkuil7c03a442007-08-19 18:59:42 -03001247 IVTV_INFO("Video Input: %s\n", vidin.name);
1248 IVTV_INFO("Audio Input: %s%s\n", audin.name,
Hans Verkuil25e3f8f2007-08-19 15:03:05 -03001249 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001250 if (has_output) {
1251 struct v4l2_output vidout;
1252 struct v4l2_audioout audout;
1253 int mode = itv->output_mode;
1254 static const char * const output_modes[] = {
1255 "None",
1256 "MPEG Streaming",
1257 "YUV Streaming",
1258 "YUV Frames",
1259 "Passthrough",
1260 };
Hans Verkuil25e3f8f2007-08-19 15:03:05 -03001261 static const char * const audio_modes[] = {
1262 "Stereo",
1263 "Left",
1264 "Right",
1265 "Mono",
1266 "Swapped"
1267 };
Hans Verkuil7c03a442007-08-19 18:59:42 -03001268 static const char * const alpha_mode[] = {
1269 "None",
1270 "Global",
1271 "Local",
1272 "Global and Local"
1273 };
1274 static const char * const pixel_format[] = {
1275 "Indexed",
1276 "RGB 5:6:5",
1277 "ARGB 1:5:5:5",
1278 "ARGB 1:4:4:4",
1279 "ARGB 8:8:8:8",
1280 "5",
1281 "6",
1282 "7",
1283 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001284
1285 ivtv_get_output(itv, itv->active_output, &vidout);
1286 ivtv_get_audio_output(itv, 0, &audout);
1287 IVTV_INFO("Video Output: %s\n", vidout.name);
Hans Verkuil25e3f8f2007-08-19 15:03:05 -03001288 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1289 audio_modes[itv->audio_stereo_mode],
1290 audio_modes[itv->audio_bilingual_mode]);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001291 if (mode < 0 || mode > OUT_PASSTHROUGH)
1292 mode = OUT_NONE;
Hans Verkuil7c03a442007-08-19 18:59:42 -03001293 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1294 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1295 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1296 data[0] & 1 ? "On" : "Off",
1297 alpha_mode[(data[0] >> 1) & 0x3],
1298 pixel_format[(data[0] >> 3) & 0x7]);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001299 }
Hans Verkuil7c03a442007-08-19 18:59:42 -03001300 IVTV_INFO("Tuner: %s\n",
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001301 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
1302 cx2341x_log_status(&itv->params, itv->name);
Hans Verkuil7c03a442007-08-19 18:59:42 -03001303 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001304 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1305 struct ivtv_stream *s = &itv->streams[i];
1306
1307 if (s->v4l2dev == NULL || s->buffers == 0)
1308 continue;
1309 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1310 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1311 (s->buffers * s->buf_size) / 1024, s->buffers);
1312 }
Hans Verkuil7c03a442007-08-19 18:59:42 -03001313 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001314 IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
1315 break;
1316 }
1317
1318 default:
1319 return -EINVAL;
1320 }
1321 return 0;
1322}
1323
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001324static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001325{
1326 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1327 struct ivtv *itv = id->itv;
1328 int nonblocking = filp->f_flags & O_NONBLOCK;
1329 struct ivtv_stream *s = &itv->streams[id->type];
1330
1331 switch (cmd) {
1332 case IVTV_IOC_DMA_FRAME: {
1333 struct ivtv_dma_frame *args = arg;
1334
1335 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1336 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1337 return -EINVAL;
1338 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1339 return -EINVAL;
1340 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1341 return 0;
1342 if (ivtv_claim_stream(id, id->type)) {
1343 return -EBUSY;
1344 }
1345 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1346 ivtv_release_stream(s);
1347 return -EBUSY;
1348 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001349 /* Mark that this file handle started the UDMA_YUV mode */
1350 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001351 if (args->y_source == NULL)
1352 return 0;
1353 return ivtv_yuv_prep_frame(itv, args);
1354 }
1355
1356 case VIDEO_GET_PTS: {
1357 u32 data[CX2341X_MBOX_MAX_DATA];
1358 u64 *pts = arg;
1359
1360 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1361 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1362 *pts = s->dma_pts;
1363 break;
1364 }
1365 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1366 return -EINVAL;
1367
1368 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1369 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1370 (u64)itv->last_dec_timing[1];
1371 break;
1372 }
1373 *pts = 0;
1374 if (atomic_read(&itv->decoding)) {
1375 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1376 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1377 return -EIO;
1378 }
1379 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1380 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1381 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1382 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1383 }
1384 break;
1385 }
1386
1387 case VIDEO_GET_FRAME_COUNT: {
1388 u32 data[CX2341X_MBOX_MAX_DATA];
1389 u64 *frame = arg;
1390
1391 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1392 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1393 *frame = 0;
1394 break;
1395 }
1396 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1397 return -EINVAL;
1398
1399 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1400 *frame = itv->last_dec_timing[0];
1401 break;
1402 }
1403 *frame = 0;
1404 if (atomic_read(&itv->decoding)) {
1405 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1406 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1407 return -EIO;
1408 }
1409 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1410 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1411 *frame = data[0];
1412 }
1413 break;
1414 }
1415
1416 case VIDEO_PLAY: {
1417 struct video_command vc;
1418
1419 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1420 memset(&vc, 0, sizeof(vc));
1421 vc.cmd = VIDEO_CMD_PLAY;
1422 return ivtv_video_command(itv, id, &vc, 0);
1423 }
1424
1425 case VIDEO_STOP: {
1426 struct video_command vc;
1427
1428 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1429 memset(&vc, 0, sizeof(vc));
1430 vc.cmd = VIDEO_CMD_STOP;
1431 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1432 return ivtv_video_command(itv, id, &vc, 0);
1433 }
1434
1435 case VIDEO_FREEZE: {
1436 struct video_command vc;
1437
1438 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1439 memset(&vc, 0, sizeof(vc));
1440 vc.cmd = VIDEO_CMD_FREEZE;
1441 return ivtv_video_command(itv, id, &vc, 0);
1442 }
1443
1444 case VIDEO_CONTINUE: {
1445 struct video_command vc;
1446
1447 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1448 memset(&vc, 0, sizeof(vc));
1449 vc.cmd = VIDEO_CMD_CONTINUE;
1450 return ivtv_video_command(itv, id, &vc, 0);
1451 }
1452
1453 case VIDEO_COMMAND:
1454 case VIDEO_TRY_COMMAND: {
1455 struct video_command *vc = arg;
1456 int try = (cmd == VIDEO_TRY_COMMAND);
1457
1458 if (try)
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001459 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001460 else
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001461 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001462 return ivtv_video_command(itv, id, vc, try);
1463 }
1464
1465 case VIDEO_GET_EVENT: {
1466 struct video_event *ev = arg;
1467 DEFINE_WAIT(wait);
1468
1469 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1470 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1471 return -EINVAL;
1472 memset(ev, 0, sizeof(*ev));
1473 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1474
1475 while (1) {
1476 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1477 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1478 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1479 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001480 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1481 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1482 if (itv->output_mode == OUT_UDMA_YUV &&
1483 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1484 IVTV_YUV_MODE_PROGRESSIVE) {
1485 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1486 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001487 }
1488 if (ev->type)
1489 return 0;
1490 if (nonblocking)
1491 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001492 /* Wait for event. Note that serialize_lock is locked,
1493 so to allow other processes to access the driver while
1494 we are waiting unlock first and later lock again. */
1495 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001496 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
1497 if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)
1498 schedule();
1499 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001500 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001501 if (signal_pending(current)) {
1502 /* return if a signal was received */
1503 IVTV_DEBUG_INFO("User stopped wait for event\n");
1504 return -EINTR;
1505 }
1506 }
1507 break;
1508 }
1509
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001510 default:
1511 return -EINVAL;
1512 }
1513 return 0;
1514}
1515
1516static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
1517 unsigned int cmd, void *arg)
1518{
1519 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1520 struct ivtv *itv = id->itv;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001521 int ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001522
Hans Verkuild46c17d2007-03-10 17:59:15 -03001523 /* check priority */
1524 switch (cmd) {
1525 case VIDIOC_S_CTRL:
1526 case VIDIOC_S_STD:
1527 case VIDIOC_S_INPUT:
1528 case VIDIOC_S_OUTPUT:
1529 case VIDIOC_S_TUNER:
1530 case VIDIOC_S_FREQUENCY:
1531 case VIDIOC_S_FMT:
1532 case VIDIOC_S_CROP:
1533 case VIDIOC_S_AUDIO:
1534 case VIDIOC_S_AUDOUT:
1535 case VIDIOC_S_EXT_CTRLS:
1536 case VIDIOC_S_FBUF:
Hans Verkuil7c03a442007-08-19 18:59:42 -03001537 case VIDIOC_OVERLAY:
Hans Verkuild46c17d2007-03-10 17:59:15 -03001538 ret = v4l2_prio_check(&itv->prio, &id->prio);
1539 if (ret)
1540 return ret;
1541 }
1542
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001543 switch (cmd) {
1544 case VIDIOC_DBG_G_REGISTER:
1545 case VIDIOC_DBG_S_REGISTER:
1546 case VIDIOC_G_CHIP_IDENT:
1547 case VIDIOC_INT_S_AUDIO_ROUTING:
1548 case VIDIOC_INT_RESET:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001549 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1550 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1551 v4l_printk_ioctl(cmd);
1552 }
1553 return ivtv_debug_ioctls(filp, cmd, arg);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001554
Hans Verkuild46c17d2007-03-10 17:59:15 -03001555 case VIDIOC_G_PRIORITY:
1556 case VIDIOC_S_PRIORITY:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001557 case VIDIOC_QUERYCAP:
1558 case VIDIOC_ENUMINPUT:
1559 case VIDIOC_G_INPUT:
1560 case VIDIOC_S_INPUT:
1561 case VIDIOC_ENUMOUTPUT:
1562 case VIDIOC_G_OUTPUT:
1563 case VIDIOC_S_OUTPUT:
1564 case VIDIOC_G_FMT:
1565 case VIDIOC_S_FMT:
1566 case VIDIOC_TRY_FMT:
1567 case VIDIOC_ENUM_FMT:
Hans Verkuil987e00b2007-05-29 13:03:27 -03001568 case VIDIOC_CROPCAP:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001569 case VIDIOC_G_CROP:
1570 case VIDIOC_S_CROP:
1571 case VIDIOC_G_FREQUENCY:
1572 case VIDIOC_S_FREQUENCY:
1573 case VIDIOC_ENUMSTD:
1574 case VIDIOC_G_STD:
1575 case VIDIOC_S_STD:
1576 case VIDIOC_S_TUNER:
1577 case VIDIOC_G_TUNER:
1578 case VIDIOC_ENUMAUDIO:
1579 case VIDIOC_S_AUDIO:
1580 case VIDIOC_G_AUDIO:
1581 case VIDIOC_ENUMAUDOUT:
1582 case VIDIOC_S_AUDOUT:
1583 case VIDIOC_G_AUDOUT:
1584 case VIDIOC_G_SLICED_VBI_CAP:
1585 case VIDIOC_LOG_STATUS:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001586 case VIDIOC_G_ENC_INDEX:
1587 case VIDIOC_ENCODER_CMD:
1588 case VIDIOC_TRY_ENCODER_CMD:
1589 case VIDIOC_G_FBUF:
1590 case VIDIOC_S_FBUF:
Hans Verkuil7c03a442007-08-19 18:59:42 -03001591 case VIDIOC_OVERLAY:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001592 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1593 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1594 v4l_printk_ioctl(cmd);
1595 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001596 return ivtv_v4l2_ioctls(itv, filp, cmd, arg);
1597
1598 case VIDIOC_QUERYMENU:
1599 case VIDIOC_QUERYCTRL:
1600 case VIDIOC_S_CTRL:
1601 case VIDIOC_G_CTRL:
1602 case VIDIOC_S_EXT_CTRLS:
1603 case VIDIOC_G_EXT_CTRLS:
1604 case VIDIOC_TRY_EXT_CTRLS:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001605 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1606 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1607 v4l_printk_ioctl(cmd);
1608 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001609 return ivtv_control_ioctls(itv, cmd, arg);
1610
1611 case IVTV_IOC_DMA_FRAME:
1612 case VIDEO_GET_PTS:
1613 case VIDEO_GET_FRAME_COUNT:
1614 case VIDEO_GET_EVENT:
1615 case VIDEO_PLAY:
1616 case VIDEO_STOP:
1617 case VIDEO_FREEZE:
1618 case VIDEO_CONTINUE:
1619 case VIDEO_COMMAND:
1620 case VIDEO_TRY_COMMAND:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001621 return ivtv_decoder_ioctls(filp, cmd, arg);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001622
1623 case 0x00005401: /* Handle isatty() calls */
1624 return -EINVAL;
1625 default:
1626 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
1627 ivtv_v4l2_do_ioctl);
1628 }
1629 return 0;
1630}
1631
Hans Verkuilbaa40722007-08-19 07:10:55 -03001632static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
1633 unsigned int cmd, unsigned long arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001634{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001635 /* Filter dvb ioctls that cannot be handled by video_usercopy */
1636 switch (cmd) {
1637 case VIDEO_SELECT_SOURCE:
1638 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1639 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1640 return -EINVAL;
1641 return ivtv_passthrough_mode(itv, arg == VIDEO_SOURCE_DEMUX);
1642
1643 case AUDIO_SET_MUTE:
1644 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1645 itv->speed_mute_audio = arg;
1646 return 0;
1647
1648 case AUDIO_CHANNEL_SELECT:
1649 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1650 if (arg > AUDIO_STEREO_SWAPPED)
1651 return -EINVAL;
1652 itv->audio_stereo_mode = arg;
1653 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1654 return 0;
1655
1656 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1657 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1658 if (arg > AUDIO_STEREO_SWAPPED)
1659 return -EINVAL;
1660 itv->audio_bilingual_mode = arg;
1661 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1662 return 0;
1663
1664 default:
1665 break;
1666 }
1667 return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);
1668}
Hans Verkuilbaa40722007-08-19 07:10:55 -03001669
1670int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1671 unsigned long arg)
1672{
1673 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1674 struct ivtv *itv = id->itv;
1675 int res;
1676
1677 mutex_lock(&itv->serialize_lock);
1678 res = ivtv_serialized_ioctl(itv, inode, filp, cmd, arg);
1679 mutex_unlock(&itv->serialize_lock);
1680 return res;
1681}