blob: 047624b9e2717f0ded7af8e2403e908ee60c3091 [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
684 case VIDIOC_INT_RESET:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300685 ivtv_reset_ir_gpio(itv);
686 break;
687
688 default:
689 return -EINVAL;
690 }
691 return 0;
692}
693
694int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
695{
696 struct ivtv_open_id *id = NULL;
697
698 if (filp) id = (struct ivtv_open_id *)filp->private_data;
699
700 switch (cmd) {
Hans Verkuild46c17d2007-03-10 17:59:15 -0300701 case VIDIOC_G_PRIORITY:
702 {
703 enum v4l2_priority *p = arg;
704
705 *p = v4l2_prio_max(&itv->prio);
706 break;
707 }
708
709 case VIDIOC_S_PRIORITY:
710 {
711 enum v4l2_priority *prio = arg;
712
713 return v4l2_prio_change(&itv->prio, &id->prio, *prio);
714 }
715
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300716 case VIDIOC_QUERYCAP:{
717 struct v4l2_capability *vcap = arg;
718
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300719 memset(vcap, 0, sizeof(*vcap));
720 strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */
721 strcpy(vcap->card, itv->card_name); /* card type */
722 strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */
723 vcap->version = IVTV_DRIVER_VERSION; /* version */
724 vcap->capabilities = itv->v4l2_cap; /* capabilities */
725
726 /* reserved.. must set to 0! */
727 vcap->reserved[0] = vcap->reserved[1] =
728 vcap->reserved[2] = vcap->reserved[3] = 0;
729 break;
730 }
731
732 case VIDIOC_ENUMAUDIO:{
733 struct v4l2_audio *vin = arg;
734
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300735 return ivtv_get_audio_input(itv, vin->index, vin);
736 }
737
738 case VIDIOC_G_AUDIO:{
739 struct v4l2_audio *vin = arg;
740
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300741 vin->index = itv->audio_input;
742 return ivtv_get_audio_input(itv, vin->index, vin);
743 }
744
745 case VIDIOC_S_AUDIO:{
746 struct v4l2_audio *vout = arg;
747
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300748 if (vout->index >= itv->nof_audio_inputs)
749 return -EINVAL;
750 itv->audio_input = vout->index;
751 ivtv_audio_set_io(itv);
752 break;
753 }
754
755 case VIDIOC_ENUMAUDOUT:{
756 struct v4l2_audioout *vin = arg;
757
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300758 /* set it to defaults from our table */
759 return ivtv_get_audio_output(itv, vin->index, vin);
760 }
761
762 case VIDIOC_G_AUDOUT:{
763 struct v4l2_audioout *vin = arg;
764
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300765 vin->index = 0;
766 return ivtv_get_audio_output(itv, vin->index, vin);
767 }
768
769 case VIDIOC_S_AUDOUT:{
770 struct v4l2_audioout *vout = arg;
771
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300772 return ivtv_get_audio_output(itv, vout->index, vout);
773 }
774
775 case VIDIOC_ENUMINPUT:{
776 struct v4l2_input *vin = arg;
777
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300778 /* set it to defaults from our table */
779 return ivtv_get_input(itv, vin->index, vin);
780 }
781
782 case VIDIOC_ENUMOUTPUT:{
783 struct v4l2_output *vout = arg;
784
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300785 return ivtv_get_output(itv, vout->index, vout);
786 }
787
788 case VIDIOC_TRY_FMT:
789 case VIDIOC_S_FMT: {
790 struct v4l2_format *fmt = arg;
791
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300792 return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT);
793 }
794
795 case VIDIOC_G_FMT: {
796 struct v4l2_format *fmt = arg;
797 int type = fmt->type;
798
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300799 memset(fmt, 0, sizeof(*fmt));
800 fmt->type = type;
801 return ivtv_get_fmt(itv, id->type, fmt);
802 }
803
Hans Verkuil987e00b2007-05-29 13:03:27 -0300804 case VIDIOC_CROPCAP: {
805 struct v4l2_cropcap *cropcap = arg;
806
807 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
808 cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
809 return -EINVAL;
810 cropcap->bounds.top = cropcap->bounds.left = 0;
811 cropcap->bounds.width = 720;
812 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
813 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
814 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
815 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
816 } else {
817 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
818 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
819 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
820 }
821 cropcap->defrect = cropcap->bounds;
822 return 0;
823 }
824
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300825 case VIDIOC_S_CROP: {
826 struct v4l2_crop *crop = arg;
827
Hans Verkuil987e00b2007-05-29 13:03:27 -0300828 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
829 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
830 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
831 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
832 itv->main_rect = crop->c;
833 return 0;
834 }
835 return -EINVAL;
836 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300837 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
838 return -EINVAL;
839 return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
840 }
841
842 case VIDIOC_G_CROP: {
843 struct v4l2_crop *crop = arg;
844
Hans Verkuil987e00b2007-05-29 13:03:27 -0300845 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
846 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
847 crop->c = itv->main_rect;
848 return 0;
849 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300850 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
851 return -EINVAL;
852 return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
853 }
854
855 case VIDIOC_ENUM_FMT: {
856 static struct v4l2_fmtdesc formats[] = {
857 { 0, 0, 0,
858 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12,
859 { 0, 0, 0, 0 }
860 },
861 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
862 "MPEG", V4L2_PIX_FMT_MPEG,
863 { 0, 0, 0, 0 }
864 }
865 };
866 struct v4l2_fmtdesc *fmt = arg;
867 enum v4l2_buf_type type = fmt->type;
868
869 switch (type) {
870 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
871 break;
872 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
873 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
874 return -EINVAL;
875 break;
876 default:
877 return -EINVAL;
878 }
879 if (fmt->index > 1)
880 return -EINVAL;
881 *fmt = formats[fmt->index];
882 fmt->type = type;
883 return 0;
884 }
885
886 case VIDIOC_G_INPUT:{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300887 *(int *)arg = itv->active_input;
888 break;
889 }
890
891 case VIDIOC_S_INPUT:{
892 int inp = *(int *)arg;
893
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300894 if (inp < 0 || inp >= itv->nof_inputs)
895 return -EINVAL;
896
897 if (inp == itv->active_input) {
898 IVTV_DEBUG_INFO("Input unchanged\n");
899 break;
900 }
901 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
902 itv->active_input, inp);
903
904 itv->active_input = inp;
905 /* Set the audio input to whatever is appropriate for the
906 input type. */
907 itv->audio_input = itv->card->video_inputs[inp].audio_index;
908
909 /* prevent others from messing with the streams until
910 we're finished changing inputs. */
911 ivtv_mute(itv);
912 ivtv_video_set_io(itv);
913 ivtv_audio_set_io(itv);
914 ivtv_unmute(itv);
915 break;
916 }
917
918 case VIDIOC_G_OUTPUT:{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300919 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
920 return -EINVAL;
921 *(int *)arg = itv->active_output;
922 break;
923 }
924
925 case VIDIOC_S_OUTPUT:{
926 int outp = *(int *)arg;
927 struct v4l2_routing route;
928
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300929 if (outp >= itv->card->nof_outputs)
930 return -EINVAL;
931
932 if (outp == itv->active_output) {
933 IVTV_DEBUG_INFO("Output unchanged\n");
934 break;
935 }
936 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
937 itv->active_output, outp);
938
939 itv->active_output = outp;
940 route.input = SAA7127_INPUT_TYPE_NORMAL;
941 route.output = itv->card->video_outputs[outp].video_output;
942 ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
943 break;
944 }
945
946 case VIDIOC_G_FREQUENCY:{
947 struct v4l2_frequency *vf = arg;
948
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300949 if (vf->tuner != 0)
950 return -EINVAL;
951 ivtv_call_i2c_clients(itv, cmd, arg);
952 break;
953 }
954
955 case VIDIOC_S_FREQUENCY:{
956 struct v4l2_frequency vf = *(struct v4l2_frequency *)arg;
957
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300958 if (vf.tuner != 0)
959 return -EINVAL;
960
961 ivtv_mute(itv);
962 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency);
963 ivtv_call_i2c_clients(itv, cmd, &vf);
964 ivtv_unmute(itv);
965 break;
966 }
967
968 case VIDIOC_ENUMSTD:{
969 struct v4l2_standard *vs = arg;
970 int idx = vs->index;
971
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300972 if (idx < 0 || idx >= ARRAY_SIZE(enum_stds))
973 return -EINVAL;
974
975 *vs = (enum_stds[idx].std & V4L2_STD_525_60) ?
976 ivtv_std_60hz : ivtv_std_50hz;
977 vs->index = idx;
978 vs->id = enum_stds[idx].std;
979 strcpy(vs->name, enum_stds[idx].name);
980 break;
981 }
982
983 case VIDIOC_G_STD:{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300984 *(v4l2_std_id *) arg = itv->std;
985 break;
986 }
987
988 case VIDIOC_S_STD: {
989 v4l2_std_id std = *(v4l2_std_id *) arg;
990
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300991 if ((std & V4L2_STD_ALL) == 0)
992 return -EINVAL;
993
994 if (std == itv->std)
995 break;
996
997 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
998 atomic_read(&itv->capturing) > 0 ||
999 atomic_read(&itv->decoding) > 0) {
1000 /* Switching standard would turn off the radio or mess
1001 with already running streams, prevent that by
1002 returning EBUSY. */
1003 return -EBUSY;
1004 }
1005
1006 itv->std = std;
1007 itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
1008 itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
1009 itv->params.width = 720;
1010 itv->params.height = itv->is_50hz ? 576 : 480;
1011 itv->vbi.count = itv->is_50hz ? 18 : 12;
1012 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1013 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1014 if (itv->hw_flags & IVTV_HW_CX25840) {
1015 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1016 }
Hans Verkuilc4385092007-06-07 09:04:03 -03001017 IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001018
1019 /* Tuner */
1020 ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
1021
1022 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1023 /* set display standard */
1024 itv->std_out = std;
1025 itv->is_out_60hz = itv->is_60hz;
1026 itv->is_out_50hz = itv->is_50hz;
1027 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
1028 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1029 itv->main_rect.left = itv->main_rect.top = 0;
1030 itv->main_rect.width = 720;
1031 itv->main_rect.height = itv->params.height;
1032 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1033 720, itv->main_rect.height, 0, 0);
1034 }
1035 break;
1036 }
1037
1038 case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */
1039 struct v4l2_tuner *vt = arg;
1040
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001041 if (vt->index != 0)
1042 return -EINVAL;
1043
1044 ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
1045 break;
1046 }
1047
1048 case VIDIOC_G_TUNER: {
1049 struct v4l2_tuner *vt = arg;
1050
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001051 if (vt->index != 0)
1052 return -EINVAL;
1053
1054 memset(vt, 0, sizeof(*vt));
1055 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
1056
1057 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1058 strcpy(vt->name, "ivtv Radio Tuner");
1059 vt->type = V4L2_TUNER_RADIO;
1060 } else {
1061 strcpy(vt->name, "ivtv TV Tuner");
1062 vt->type = V4L2_TUNER_ANALOG_TV;
1063 }
1064 break;
1065 }
1066
1067 case VIDIOC_G_SLICED_VBI_CAP: {
1068 struct v4l2_sliced_vbi_cap *cap = arg;
1069 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1070 int f, l;
1071 enum v4l2_buf_type type = cap->type;
1072
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001073 memset(cap, 0, sizeof(*cap));
1074 cap->type = type;
1075 if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1076 for (f = 0; f < 2; f++) {
1077 for (l = 0; l < 24; l++) {
1078 if (valid_service_line(f, l, itv->is_50hz)) {
1079 cap->service_lines[f][l] = set;
1080 }
1081 }
1082 }
1083 return 0;
1084 }
1085 if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
1086 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1087 return -EINVAL;
1088 if (itv->is_60hz) {
1089 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1090 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1091 } else {
1092 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1093 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1094 }
1095 return 0;
1096 }
1097 return -EINVAL;
1098 }
1099
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001100 case VIDIOC_G_ENC_INDEX: {
1101 struct v4l2_enc_idx *idx = arg;
1102 int i;
1103
1104 idx->entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1105 IVTV_MAX_PGM_INDEX;
1106 if (idx->entries > V4L2_ENC_IDX_ENTRIES)
1107 idx->entries = V4L2_ENC_IDX_ENTRIES;
1108 for (i = 0; i < idx->entries; i++) {
1109 idx->entry[i] = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1110 }
1111 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1112 break;
1113 }
1114
1115 case VIDIOC_ENCODER_CMD:
1116 case VIDIOC_TRY_ENCODER_CMD: {
1117 struct v4l2_encoder_cmd *enc = arg;
1118 int try = cmd == VIDIOC_TRY_ENCODER_CMD;
1119
Hans Verkuil25415cf2007-03-10 18:29:48 -03001120 memset(&enc->raw, 0, sizeof(enc->raw));
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001121 switch (enc->cmd) {
1122 case V4L2_ENC_CMD_START:
Hans Verkuil25415cf2007-03-10 18:29:48 -03001123 enc->flags = 0;
1124 if (try)
1125 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001126 return ivtv_start_capture(id);
1127
1128 case V4L2_ENC_CMD_STOP:
Hans Verkuil018ba852007-04-10 18:59:09 -03001129 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
Hans Verkuil25415cf2007-03-10 18:29:48 -03001130 if (try)
1131 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001132 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1133 return 0;
1134
1135 case V4L2_ENC_CMD_PAUSE:
Hans Verkuil25415cf2007-03-10 18:29:48 -03001136 enc->flags = 0;
1137 if (try)
1138 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001139 if (!atomic_read(&itv->capturing))
1140 return -EPERM;
1141 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1142 return 0;
1143 ivtv_mute(itv);
1144 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1145 break;
1146
1147 case V4L2_ENC_CMD_RESUME:
Hans Verkuil25415cf2007-03-10 18:29:48 -03001148 enc->flags = 0;
1149 if (try)
1150 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001151 if (!atomic_read(&itv->capturing))
1152 return -EPERM;
1153 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1154 return 0;
1155 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1156 ivtv_unmute(itv);
1157 break;
Hans Verkuil25415cf2007-03-10 18:29:48 -03001158 default:
1159 return -EINVAL;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001160 }
1161 break;
1162 }
1163
1164 case VIDIOC_G_FBUF: {
1165 struct v4l2_framebuffer *fb = arg;
1166
1167 memset(fb, 0, sizeof(*fb));
1168 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuilf5948bb2007-06-16 18:24:47 -03001169 return -EINVAL;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001170 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1171 V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA;
1172 fb->fmt.pixelformat = itv->osd_pixelformat;
1173 fb->fmt.width = itv->osd_rect.width;
1174 fb->fmt.height = itv->osd_rect.height;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001175 fb->base = (void *)itv->osd_video_pbase;
1176 if (itv->osd_global_alpha_state)
1177 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1178 if (itv->osd_local_alpha_state)
1179 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1180 if (itv->osd_color_key_state)
1181 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1182 break;
1183 }
1184
1185 case VIDIOC_S_FBUF: {
1186 struct v4l2_framebuffer *fb = arg;
1187
1188 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuilf5948bb2007-06-16 18:24:47 -03001189 return -EINVAL;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001190 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1191 itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0;
1192 itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1193 break;
1194 }
1195
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001196 case VIDIOC_LOG_STATUS:
1197 {
1198 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1199 struct v4l2_input vidin;
1200 struct v4l2_audio audin;
1201 int i;
1202
1203 IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num);
1204 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1205 struct tveeprom tv;
1206
1207 ivtv_read_eeprom(itv, &tv);
1208 }
1209 ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
1210 ivtv_get_input(itv, itv->active_input, &vidin);
1211 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1212 IVTV_INFO("Video Input: %s\n", vidin.name);
1213 IVTV_INFO("Audio Input: %s\n", audin.name);
1214 if (has_output) {
1215 struct v4l2_output vidout;
1216 struct v4l2_audioout audout;
1217 int mode = itv->output_mode;
1218 static const char * const output_modes[] = {
1219 "None",
1220 "MPEG Streaming",
1221 "YUV Streaming",
1222 "YUV Frames",
1223 "Passthrough",
1224 };
1225
1226 ivtv_get_output(itv, itv->active_output, &vidout);
1227 ivtv_get_audio_output(itv, 0, &audout);
1228 IVTV_INFO("Video Output: %s\n", vidout.name);
1229 IVTV_INFO("Audio Output: %s\n", audout.name);
1230 if (mode < 0 || mode > OUT_PASSTHROUGH)
1231 mode = OUT_NONE;
1232 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1233 }
1234 IVTV_INFO("Tuner: %s\n",
1235 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
1236 cx2341x_log_status(&itv->params, itv->name);
1237 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1238 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1239 struct ivtv_stream *s = &itv->streams[i];
1240
1241 if (s->v4l2dev == NULL || s->buffers == 0)
1242 continue;
1243 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1244 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1245 (s->buffers * s->buf_size) / 1024, s->buffers);
1246 }
Hans Verkuilc4385092007-06-07 09:04:03 -03001247 IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001248 IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
1249 break;
1250 }
1251
1252 default:
1253 return -EINVAL;
1254 }
1255 return 0;
1256}
1257
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001258static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001259{
1260 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1261 struct ivtv *itv = id->itv;
1262 int nonblocking = filp->f_flags & O_NONBLOCK;
1263 struct ivtv_stream *s = &itv->streams[id->type];
1264
1265 switch (cmd) {
1266 case IVTV_IOC_DMA_FRAME: {
1267 struct ivtv_dma_frame *args = arg;
1268
1269 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1270 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1271 return -EINVAL;
1272 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1273 return -EINVAL;
1274 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1275 return 0;
1276 if (ivtv_claim_stream(id, id->type)) {
1277 return -EBUSY;
1278 }
1279 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1280 ivtv_release_stream(s);
1281 return -EBUSY;
1282 }
1283 if (args->y_source == NULL)
1284 return 0;
1285 return ivtv_yuv_prep_frame(itv, args);
1286 }
1287
1288 case VIDEO_GET_PTS: {
1289 u32 data[CX2341X_MBOX_MAX_DATA];
1290 u64 *pts = arg;
1291
1292 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1293 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1294 *pts = s->dma_pts;
1295 break;
1296 }
1297 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1298 return -EINVAL;
1299
1300 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1301 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1302 (u64)itv->last_dec_timing[1];
1303 break;
1304 }
1305 *pts = 0;
1306 if (atomic_read(&itv->decoding)) {
1307 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1308 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1309 return -EIO;
1310 }
1311 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1312 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1313 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1314 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1315 }
1316 break;
1317 }
1318
1319 case VIDEO_GET_FRAME_COUNT: {
1320 u32 data[CX2341X_MBOX_MAX_DATA];
1321 u64 *frame = arg;
1322
1323 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1324 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1325 *frame = 0;
1326 break;
1327 }
1328 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1329 return -EINVAL;
1330
1331 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1332 *frame = itv->last_dec_timing[0];
1333 break;
1334 }
1335 *frame = 0;
1336 if (atomic_read(&itv->decoding)) {
1337 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1338 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1339 return -EIO;
1340 }
1341 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1342 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1343 *frame = data[0];
1344 }
1345 break;
1346 }
1347
1348 case VIDEO_PLAY: {
1349 struct video_command vc;
1350
1351 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1352 memset(&vc, 0, sizeof(vc));
1353 vc.cmd = VIDEO_CMD_PLAY;
1354 return ivtv_video_command(itv, id, &vc, 0);
1355 }
1356
1357 case VIDEO_STOP: {
1358 struct video_command vc;
1359
1360 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1361 memset(&vc, 0, sizeof(vc));
1362 vc.cmd = VIDEO_CMD_STOP;
1363 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1364 return ivtv_video_command(itv, id, &vc, 0);
1365 }
1366
1367 case VIDEO_FREEZE: {
1368 struct video_command vc;
1369
1370 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1371 memset(&vc, 0, sizeof(vc));
1372 vc.cmd = VIDEO_CMD_FREEZE;
1373 return ivtv_video_command(itv, id, &vc, 0);
1374 }
1375
1376 case VIDEO_CONTINUE: {
1377 struct video_command vc;
1378
1379 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1380 memset(&vc, 0, sizeof(vc));
1381 vc.cmd = VIDEO_CMD_CONTINUE;
1382 return ivtv_video_command(itv, id, &vc, 0);
1383 }
1384
1385 case VIDEO_COMMAND:
1386 case VIDEO_TRY_COMMAND: {
1387 struct video_command *vc = arg;
1388 int try = (cmd == VIDEO_TRY_COMMAND);
1389
1390 if (try)
1391 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND\n");
1392 else
1393 IVTV_DEBUG_IOCTL("VIDEO_COMMAND\n");
1394 return ivtv_video_command(itv, id, vc, try);
1395 }
1396
1397 case VIDEO_GET_EVENT: {
1398 struct video_event *ev = arg;
1399 DEFINE_WAIT(wait);
1400
1401 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1402 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1403 return -EINVAL;
1404 memset(ev, 0, sizeof(*ev));
1405 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1406
1407 while (1) {
1408 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1409 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1410 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1411 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001412 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1413 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1414 if (itv->output_mode == OUT_UDMA_YUV &&
1415 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1416 IVTV_YUV_MODE_PROGRESSIVE) {
1417 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1418 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001419 }
1420 if (ev->type)
1421 return 0;
1422 if (nonblocking)
1423 return -EAGAIN;
1424 /* wait for event */
1425 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
1426 if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)
1427 schedule();
1428 finish_wait(&itv->event_waitq, &wait);
1429 if (signal_pending(current)) {
1430 /* return if a signal was received */
1431 IVTV_DEBUG_INFO("User stopped wait for event\n");
1432 return -EINTR;
1433 }
1434 }
1435 break;
1436 }
1437
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001438 default:
1439 return -EINVAL;
1440 }
1441 return 0;
1442}
1443
1444static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
1445 unsigned int cmd, void *arg)
1446{
1447 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1448 struct ivtv *itv = id->itv;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001449 int ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001450
Hans Verkuild46c17d2007-03-10 17:59:15 -03001451 /* check priority */
1452 switch (cmd) {
1453 case VIDIOC_S_CTRL:
1454 case VIDIOC_S_STD:
1455 case VIDIOC_S_INPUT:
1456 case VIDIOC_S_OUTPUT:
1457 case VIDIOC_S_TUNER:
1458 case VIDIOC_S_FREQUENCY:
1459 case VIDIOC_S_FMT:
1460 case VIDIOC_S_CROP:
1461 case VIDIOC_S_AUDIO:
1462 case VIDIOC_S_AUDOUT:
1463 case VIDIOC_S_EXT_CTRLS:
1464 case VIDIOC_S_FBUF:
1465 ret = v4l2_prio_check(&itv->prio, &id->prio);
1466 if (ret)
1467 return ret;
1468 }
1469
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001470 switch (cmd) {
1471 case VIDIOC_DBG_G_REGISTER:
1472 case VIDIOC_DBG_S_REGISTER:
1473 case VIDIOC_G_CHIP_IDENT:
1474 case VIDIOC_INT_S_AUDIO_ROUTING:
1475 case VIDIOC_INT_RESET:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001476 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1477 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1478 v4l_printk_ioctl(cmd);
1479 }
1480 return ivtv_debug_ioctls(filp, cmd, arg);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001481
Hans Verkuild46c17d2007-03-10 17:59:15 -03001482 case VIDIOC_G_PRIORITY:
1483 case VIDIOC_S_PRIORITY:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001484 case VIDIOC_QUERYCAP:
1485 case VIDIOC_ENUMINPUT:
1486 case VIDIOC_G_INPUT:
1487 case VIDIOC_S_INPUT:
1488 case VIDIOC_ENUMOUTPUT:
1489 case VIDIOC_G_OUTPUT:
1490 case VIDIOC_S_OUTPUT:
1491 case VIDIOC_G_FMT:
1492 case VIDIOC_S_FMT:
1493 case VIDIOC_TRY_FMT:
1494 case VIDIOC_ENUM_FMT:
Hans Verkuil987e00b2007-05-29 13:03:27 -03001495 case VIDIOC_CROPCAP:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001496 case VIDIOC_G_CROP:
1497 case VIDIOC_S_CROP:
1498 case VIDIOC_G_FREQUENCY:
1499 case VIDIOC_S_FREQUENCY:
1500 case VIDIOC_ENUMSTD:
1501 case VIDIOC_G_STD:
1502 case VIDIOC_S_STD:
1503 case VIDIOC_S_TUNER:
1504 case VIDIOC_G_TUNER:
1505 case VIDIOC_ENUMAUDIO:
1506 case VIDIOC_S_AUDIO:
1507 case VIDIOC_G_AUDIO:
1508 case VIDIOC_ENUMAUDOUT:
1509 case VIDIOC_S_AUDOUT:
1510 case VIDIOC_G_AUDOUT:
1511 case VIDIOC_G_SLICED_VBI_CAP:
1512 case VIDIOC_LOG_STATUS:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001513 case VIDIOC_G_ENC_INDEX:
1514 case VIDIOC_ENCODER_CMD:
1515 case VIDIOC_TRY_ENCODER_CMD:
1516 case VIDIOC_G_FBUF:
1517 case VIDIOC_S_FBUF:
1518 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1519 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1520 v4l_printk_ioctl(cmd);
1521 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001522 return ivtv_v4l2_ioctls(itv, filp, cmd, arg);
1523
1524 case VIDIOC_QUERYMENU:
1525 case VIDIOC_QUERYCTRL:
1526 case VIDIOC_S_CTRL:
1527 case VIDIOC_G_CTRL:
1528 case VIDIOC_S_EXT_CTRLS:
1529 case VIDIOC_G_EXT_CTRLS:
1530 case VIDIOC_TRY_EXT_CTRLS:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001531 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1532 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1533 v4l_printk_ioctl(cmd);
1534 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001535 return ivtv_control_ioctls(itv, cmd, arg);
1536
1537 case IVTV_IOC_DMA_FRAME:
1538 case VIDEO_GET_PTS:
1539 case VIDEO_GET_FRAME_COUNT:
1540 case VIDEO_GET_EVENT:
1541 case VIDEO_PLAY:
1542 case VIDEO_STOP:
1543 case VIDEO_FREEZE:
1544 case VIDEO_CONTINUE:
1545 case VIDEO_COMMAND:
1546 case VIDEO_TRY_COMMAND:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001547 return ivtv_decoder_ioctls(filp, cmd, arg);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001548
1549 case 0x00005401: /* Handle isatty() calls */
1550 return -EINVAL;
1551 default:
1552 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
1553 ivtv_v4l2_do_ioctl);
1554 }
1555 return 0;
1556}
1557
1558int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1559 unsigned long arg)
1560{
1561 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1562 struct ivtv *itv = id->itv;
1563
1564 /* Filter dvb ioctls that cannot be handled by video_usercopy */
1565 switch (cmd) {
1566 case VIDEO_SELECT_SOURCE:
1567 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1568 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1569 return -EINVAL;
1570 return ivtv_passthrough_mode(itv, arg == VIDEO_SOURCE_DEMUX);
1571
1572 case AUDIO_SET_MUTE:
1573 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1574 itv->speed_mute_audio = arg;
1575 return 0;
1576
1577 case AUDIO_CHANNEL_SELECT:
1578 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1579 if (arg > AUDIO_STEREO_SWAPPED)
1580 return -EINVAL;
1581 itv->audio_stereo_mode = arg;
1582 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1583 return 0;
1584
1585 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1586 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1587 if (arg > AUDIO_STEREO_SWAPPED)
1588 return -EINVAL;
1589 itv->audio_bilingual_mode = arg;
1590 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1591 return 0;
1592
1593 default:
1594 break;
1595 }
1596 return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);
1597}