blob: 0dde82f67e26379ddee0c4c62f7531df42dc6378 [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) {
Hans Verkuilea115d52007-08-20 16:26:40 -0300587 if (set_fmt && atomic_read(&itv->capturing) > 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300588 return -EBUSY;
589 }
590 if (set_fmt) {
591 itv->vbi.sliced_in->service_set = 0;
592 itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
593 }
594 return ivtv_get_fmt(itv, streamtype, fmt);
595 }
596
597 /* set sliced VBI output
598 In principle the user could request that only certain
599 VBI types are output and that the others are ignored.
600 I.e., suppress CC in the even fields or only output
601 WSS and no VPS. Currently though there is no choice. */
602 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
603 return ivtv_get_fmt(itv, streamtype, fmt);
604
605 /* any else but sliced VBI capture is an error */
606 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE)
607 return -EINVAL;
608
609 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI)
610 return ivtv_get_fmt(itv, streamtype, fmt);
611
612 /* set sliced VBI capture format */
613 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
614 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
615
616 if (vbifmt->service_set)
617 expand_service_set(vbifmt, itv->is_50hz);
618 set = check_service_set(vbifmt, itv->is_50hz);
619 vbifmt->service_set = get_service_set(vbifmt);
620
621 if (!set_fmt)
622 return 0;
623 if (set == 0)
624 return -EINVAL;
Hans Verkuilea115d52007-08-20 16:26:40 -0300625 if (atomic_read(&itv->capturing) > 0) {
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300626 return -EBUSY;
627 }
628 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
629 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
630 return 0;
631}
632
Hans Verkuild4e7ee32007-03-10 18:19:12 -0300633static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300634{
635 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
636 struct ivtv *itv = id->itv;
637 struct v4l2_register *reg = arg;
638
639 switch (cmd) {
640 /* ioctls to allow direct access to the encoder registers for testing */
641 case VIDIOC_DBG_G_REGISTER:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300642 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
643 return ivtv_itvc(itv, cmd, arg);
644 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
645 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
646 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
647
648 case VIDIOC_DBG_S_REGISTER:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300649 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
650 return ivtv_itvc(itv, cmd, arg);
651 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
652 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
653 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
654
655 case VIDIOC_G_CHIP_IDENT: {
656 struct v4l2_chip_ident *chip = arg;
657
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300658 chip->ident = V4L2_IDENT_NONE;
659 chip->revision = 0;
660 if (reg->match_type == V4L2_CHIP_MATCH_HOST) {
661 if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) {
662 struct v4l2_chip_ident *chip = arg;
663
664 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
665 }
666 return 0;
667 }
668 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
669 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
670 if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
671 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
672 return -EINVAL;
673 }
674
675 case VIDIOC_INT_S_AUDIO_ROUTING: {
676 struct v4l2_routing *route = arg;
677
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300678 ivtv_audio_set_route(itv, route);
679 break;
680 }
681
Hans Verkuil2cc72092007-08-04 05:06:23 -0300682 case VIDIOC_INT_RESET: {
683 u32 val = *(u32 *)arg;
684
685 if ((val == 0 && itv->options.newi2c) || (val & 0x01)) {
686 ivtv_reset_ir_gpio(itv);
687 }
688 if (val & 0x02) {
689 itv->video_dec_func(itv, cmd, 0);
690 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300691 break;
Hans Verkuil2cc72092007-08-04 05:06:23 -0300692 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300693
694 default:
695 return -EINVAL;
696 }
697 return 0;
698}
699
700int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
701{
702 struct ivtv_open_id *id = NULL;
703
704 if (filp) id = (struct ivtv_open_id *)filp->private_data;
705
706 switch (cmd) {
Hans Verkuild46c17d2007-03-10 17:59:15 -0300707 case VIDIOC_G_PRIORITY:
708 {
709 enum v4l2_priority *p = arg;
710
711 *p = v4l2_prio_max(&itv->prio);
712 break;
713 }
714
715 case VIDIOC_S_PRIORITY:
716 {
717 enum v4l2_priority *prio = arg;
718
719 return v4l2_prio_change(&itv->prio, &id->prio, *prio);
720 }
721
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300722 case VIDIOC_QUERYCAP:{
723 struct v4l2_capability *vcap = arg;
724
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300725 memset(vcap, 0, sizeof(*vcap));
726 strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */
727 strcpy(vcap->card, itv->card_name); /* card type */
728 strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */
729 vcap->version = IVTV_DRIVER_VERSION; /* version */
730 vcap->capabilities = itv->v4l2_cap; /* capabilities */
731
732 /* reserved.. must set to 0! */
733 vcap->reserved[0] = vcap->reserved[1] =
734 vcap->reserved[2] = vcap->reserved[3] = 0;
735 break;
736 }
737
738 case VIDIOC_ENUMAUDIO:{
739 struct v4l2_audio *vin = arg;
740
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300741 return ivtv_get_audio_input(itv, vin->index, vin);
742 }
743
744 case VIDIOC_G_AUDIO:{
745 struct v4l2_audio *vin = arg;
746
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300747 vin->index = itv->audio_input;
748 return ivtv_get_audio_input(itv, vin->index, vin);
749 }
750
751 case VIDIOC_S_AUDIO:{
752 struct v4l2_audio *vout = arg;
753
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300754 if (vout->index >= itv->nof_audio_inputs)
755 return -EINVAL;
756 itv->audio_input = vout->index;
757 ivtv_audio_set_io(itv);
758 break;
759 }
760
761 case VIDIOC_ENUMAUDOUT:{
762 struct v4l2_audioout *vin = arg;
763
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300764 /* set it to defaults from our table */
765 return ivtv_get_audio_output(itv, vin->index, vin);
766 }
767
768 case VIDIOC_G_AUDOUT:{
769 struct v4l2_audioout *vin = arg;
770
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300771 vin->index = 0;
772 return ivtv_get_audio_output(itv, vin->index, vin);
773 }
774
775 case VIDIOC_S_AUDOUT:{
776 struct v4l2_audioout *vout = arg;
777
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300778 return ivtv_get_audio_output(itv, vout->index, vout);
779 }
780
781 case VIDIOC_ENUMINPUT:{
782 struct v4l2_input *vin = arg;
783
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300784 /* set it to defaults from our table */
785 return ivtv_get_input(itv, vin->index, vin);
786 }
787
788 case VIDIOC_ENUMOUTPUT:{
789 struct v4l2_output *vout = arg;
790
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300791 return ivtv_get_output(itv, vout->index, vout);
792 }
793
794 case VIDIOC_TRY_FMT:
795 case VIDIOC_S_FMT: {
796 struct v4l2_format *fmt = arg;
797
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300798 return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT);
799 }
800
801 case VIDIOC_G_FMT: {
802 struct v4l2_format *fmt = arg;
803 int type = fmt->type;
804
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300805 memset(fmt, 0, sizeof(*fmt));
806 fmt->type = type;
807 return ivtv_get_fmt(itv, id->type, fmt);
808 }
809
Hans Verkuil987e00b2007-05-29 13:03:27 -0300810 case VIDIOC_CROPCAP: {
811 struct v4l2_cropcap *cropcap = arg;
812
813 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_CAPTURE &&
814 cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
815 return -EINVAL;
816 cropcap->bounds.top = cropcap->bounds.left = 0;
817 cropcap->bounds.width = 720;
818 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
819 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
820 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
821 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
822 } else {
823 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
824 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
825 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
826 }
827 cropcap->defrect = cropcap->bounds;
828 return 0;
829 }
830
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300831 case VIDIOC_S_CROP: {
832 struct v4l2_crop *crop = arg;
833
Hans Verkuil987e00b2007-05-29 13:03:27 -0300834 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
835 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
836 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
837 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
838 itv->main_rect = crop->c;
839 return 0;
840 }
841 return -EINVAL;
842 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300843 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
844 return -EINVAL;
845 return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
846 }
847
848 case VIDIOC_G_CROP: {
849 struct v4l2_crop *crop = arg;
850
Hans Verkuil987e00b2007-05-29 13:03:27 -0300851 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
852 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
853 crop->c = itv->main_rect;
854 return 0;
855 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300856 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
857 return -EINVAL;
858 return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
859 }
860
861 case VIDIOC_ENUM_FMT: {
862 static struct v4l2_fmtdesc formats[] = {
863 { 0, 0, 0,
864 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12,
865 { 0, 0, 0, 0 }
866 },
867 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
868 "MPEG", V4L2_PIX_FMT_MPEG,
869 { 0, 0, 0, 0 }
870 }
871 };
872 struct v4l2_fmtdesc *fmt = arg;
873 enum v4l2_buf_type type = fmt->type;
874
875 switch (type) {
876 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
877 break;
878 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
879 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
880 return -EINVAL;
881 break;
882 default:
883 return -EINVAL;
884 }
885 if (fmt->index > 1)
886 return -EINVAL;
887 *fmt = formats[fmt->index];
888 fmt->type = type;
889 return 0;
890 }
891
892 case VIDIOC_G_INPUT:{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300893 *(int *)arg = itv->active_input;
894 break;
895 }
896
897 case VIDIOC_S_INPUT:{
898 int inp = *(int *)arg;
899
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300900 if (inp < 0 || inp >= itv->nof_inputs)
901 return -EINVAL;
902
903 if (inp == itv->active_input) {
904 IVTV_DEBUG_INFO("Input unchanged\n");
905 break;
906 }
Hans Verkuil3562c432007-08-18 11:46:05 -0300907 if (atomic_read(&itv->capturing) > 0) {
908 return -EBUSY;
909 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300910 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
911 itv->active_input, inp);
912
913 itv->active_input = inp;
914 /* Set the audio input to whatever is appropriate for the
915 input type. */
916 itv->audio_input = itv->card->video_inputs[inp].audio_index;
917
918 /* prevent others from messing with the streams until
919 we're finished changing inputs. */
920 ivtv_mute(itv);
921 ivtv_video_set_io(itv);
922 ivtv_audio_set_io(itv);
923 ivtv_unmute(itv);
924 break;
925 }
926
927 case VIDIOC_G_OUTPUT:{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300928 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
929 return -EINVAL;
930 *(int *)arg = itv->active_output;
931 break;
932 }
933
934 case VIDIOC_S_OUTPUT:{
935 int outp = *(int *)arg;
936 struct v4l2_routing route;
937
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300938 if (outp >= itv->card->nof_outputs)
939 return -EINVAL;
940
941 if (outp == itv->active_output) {
942 IVTV_DEBUG_INFO("Output unchanged\n");
943 break;
944 }
945 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
946 itv->active_output, outp);
947
948 itv->active_output = outp;
949 route.input = SAA7127_INPUT_TYPE_NORMAL;
950 route.output = itv->card->video_outputs[outp].video_output;
951 ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
952 break;
953 }
954
955 case VIDIOC_G_FREQUENCY:{
956 struct v4l2_frequency *vf = arg;
957
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300958 if (vf->tuner != 0)
959 return -EINVAL;
960 ivtv_call_i2c_clients(itv, cmd, arg);
961 break;
962 }
963
964 case VIDIOC_S_FREQUENCY:{
965 struct v4l2_frequency vf = *(struct v4l2_frequency *)arg;
966
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300967 if (vf.tuner != 0)
968 return -EINVAL;
969
970 ivtv_mute(itv);
971 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency);
972 ivtv_call_i2c_clients(itv, cmd, &vf);
973 ivtv_unmute(itv);
974 break;
975 }
976
977 case VIDIOC_ENUMSTD:{
978 struct v4l2_standard *vs = arg;
979 int idx = vs->index;
980
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300981 if (idx < 0 || idx >= ARRAY_SIZE(enum_stds))
982 return -EINVAL;
983
984 *vs = (enum_stds[idx].std & V4L2_STD_525_60) ?
985 ivtv_std_60hz : ivtv_std_50hz;
986 vs->index = idx;
987 vs->id = enum_stds[idx].std;
988 strcpy(vs->name, enum_stds[idx].name);
989 break;
990 }
991
992 case VIDIOC_G_STD:{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -0300993 *(v4l2_std_id *) arg = itv->std;
994 break;
995 }
996
997 case VIDIOC_S_STD: {
998 v4l2_std_id std = *(v4l2_std_id *) arg;
999
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001000 if ((std & V4L2_STD_ALL) == 0)
1001 return -EINVAL;
1002
1003 if (std == itv->std)
1004 break;
1005
1006 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1007 atomic_read(&itv->capturing) > 0 ||
1008 atomic_read(&itv->decoding) > 0) {
1009 /* Switching standard would turn off the radio or mess
1010 with already running streams, prevent that by
1011 returning EBUSY. */
1012 return -EBUSY;
1013 }
1014
1015 itv->std = std;
1016 itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
1017 itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
1018 itv->params.width = 720;
1019 itv->params.height = itv->is_50hz ? 576 : 480;
1020 itv->vbi.count = itv->is_50hz ? 18 : 12;
1021 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1022 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1023 if (itv->hw_flags & IVTV_HW_CX25840) {
1024 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1025 }
Hans Verkuilc4385092007-06-07 09:04:03 -03001026 IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001027
1028 /* Tuner */
1029 ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
1030
1031 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1032 /* set display standard */
1033 itv->std_out = std;
1034 itv->is_out_60hz = itv->is_60hz;
1035 itv->is_out_50hz = itv->is_50hz;
1036 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
1037 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1038 itv->main_rect.left = itv->main_rect.top = 0;
1039 itv->main_rect.width = 720;
1040 itv->main_rect.height = itv->params.height;
1041 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1042 720, itv->main_rect.height, 0, 0);
1043 }
1044 break;
1045 }
1046
1047 case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */
1048 struct v4l2_tuner *vt = arg;
1049
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001050 if (vt->index != 0)
1051 return -EINVAL;
1052
1053 ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
1054 break;
1055 }
1056
1057 case VIDIOC_G_TUNER: {
1058 struct v4l2_tuner *vt = arg;
1059
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001060 if (vt->index != 0)
1061 return -EINVAL;
1062
1063 memset(vt, 0, sizeof(*vt));
1064 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
1065
1066 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1067 strcpy(vt->name, "ivtv Radio Tuner");
1068 vt->type = V4L2_TUNER_RADIO;
1069 } else {
1070 strcpy(vt->name, "ivtv TV Tuner");
1071 vt->type = V4L2_TUNER_ANALOG_TV;
1072 }
1073 break;
1074 }
1075
1076 case VIDIOC_G_SLICED_VBI_CAP: {
1077 struct v4l2_sliced_vbi_cap *cap = arg;
1078 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1079 int f, l;
1080 enum v4l2_buf_type type = cap->type;
1081
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001082 memset(cap, 0, sizeof(*cap));
1083 cap->type = type;
1084 if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1085 for (f = 0; f < 2; f++) {
1086 for (l = 0; l < 24; l++) {
1087 if (valid_service_line(f, l, itv->is_50hz)) {
1088 cap->service_lines[f][l] = set;
1089 }
1090 }
1091 }
1092 return 0;
1093 }
1094 if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
1095 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1096 return -EINVAL;
1097 if (itv->is_60hz) {
1098 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1099 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1100 } else {
1101 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1102 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1103 }
1104 return 0;
1105 }
1106 return -EINVAL;
1107 }
1108
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001109 case VIDIOC_G_ENC_INDEX: {
1110 struct v4l2_enc_idx *idx = arg;
Hans Verkuil5614b022007-08-23 17:48:41 -03001111 struct v4l2_enc_idx_entry *e = idx->entry;
1112 int entries;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001113 int i;
1114
Hans Verkuil5614b022007-08-23 17:48:41 -03001115 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001116 IVTV_MAX_PGM_INDEX;
Hans Verkuil5614b022007-08-23 17:48:41 -03001117 if (entries > V4L2_ENC_IDX_ENTRIES)
1118 entries = V4L2_ENC_IDX_ENTRIES;
1119 idx->entries = 0;
1120 for (i = 0; i < entries; i++) {
1121 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1122 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1123 idx->entries++;
1124 e++;
1125 }
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001126 }
1127 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1128 break;
1129 }
1130
1131 case VIDIOC_ENCODER_CMD:
1132 case VIDIOC_TRY_ENCODER_CMD: {
1133 struct v4l2_encoder_cmd *enc = arg;
1134 int try = cmd == VIDIOC_TRY_ENCODER_CMD;
1135
Hans Verkuil25415cf2007-03-10 18:29:48 -03001136 memset(&enc->raw, 0, sizeof(enc->raw));
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001137 switch (enc->cmd) {
1138 case V4L2_ENC_CMD_START:
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001139 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
Hans Verkuil25415cf2007-03-10 18:29:48 -03001140 enc->flags = 0;
1141 if (try)
1142 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001143 return ivtv_start_capture(id);
1144
1145 case V4L2_ENC_CMD_STOP:
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001146 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
Hans Verkuil018ba852007-04-10 18:59:09 -03001147 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
Hans Verkuil25415cf2007-03-10 18:29:48 -03001148 if (try)
1149 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001150 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1151 return 0;
1152
1153 case V4L2_ENC_CMD_PAUSE:
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001154 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
Hans Verkuil25415cf2007-03-10 18:29:48 -03001155 enc->flags = 0;
1156 if (try)
1157 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001158 if (!atomic_read(&itv->capturing))
1159 return -EPERM;
1160 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1161 return 0;
1162 ivtv_mute(itv);
1163 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1164 break;
1165
1166 case V4L2_ENC_CMD_RESUME:
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001167 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
Hans Verkuil25415cf2007-03-10 18:29:48 -03001168 enc->flags = 0;
1169 if (try)
1170 return 0;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001171 if (!atomic_read(&itv->capturing))
1172 return -EPERM;
1173 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1174 return 0;
1175 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1176 ivtv_unmute(itv);
1177 break;
Hans Verkuil25415cf2007-03-10 18:29:48 -03001178 default:
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001179 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
Hans Verkuil25415cf2007-03-10 18:29:48 -03001180 return -EINVAL;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001181 }
1182 break;
1183 }
1184
1185 case VIDIOC_G_FBUF: {
1186 struct v4l2_framebuffer *fb = arg;
1187
1188 memset(fb, 0, sizeof(*fb));
1189 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuilf5948bb2007-06-16 18:24:47 -03001190 return -EINVAL;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001191 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1192 V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA;
1193 fb->fmt.pixelformat = itv->osd_pixelformat;
1194 fb->fmt.width = itv->osd_rect.width;
1195 fb->fmt.height = itv->osd_rect.height;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001196 fb->base = (void *)itv->osd_video_pbase;
1197 if (itv->osd_global_alpha_state)
1198 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1199 if (itv->osd_local_alpha_state)
1200 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1201 if (itv->osd_color_key_state)
1202 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1203 break;
1204 }
1205
1206 case VIDIOC_S_FBUF: {
1207 struct v4l2_framebuffer *fb = arg;
1208
1209 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
Hans Verkuilf5948bb2007-06-16 18:24:47 -03001210 return -EINVAL;
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001211 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1212 itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0;
1213 itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
Hans Verkuilc3624f92007-07-31 07:15:56 -03001214 ivtv_set_osd_alpha(itv);
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001215 break;
1216 }
1217
Hans Verkuil7c03a442007-08-19 18:59:42 -03001218 case VIDIOC_OVERLAY: {
1219 int *on = arg;
1220
1221 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1222 return -EINVAL;
1223 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0);
1224 break;
1225 }
1226
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001227 case VIDIOC_LOG_STATUS:
1228 {
1229 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
Hans Verkuil7c03a442007-08-19 18:59:42 -03001230 u32 data[CX2341X_MBOX_MAX_DATA];
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001231 struct v4l2_input vidin;
1232 struct v4l2_audio audin;
1233 int i;
1234
1235 IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num);
Hans Verkuil94104aa2007-08-04 04:56:00 -03001236 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001237 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1238 struct tveeprom tv;
1239
1240 ivtv_read_eeprom(itv, &tv);
1241 }
1242 ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
1243 ivtv_get_input(itv, itv->active_input, &vidin);
1244 ivtv_get_audio_input(itv, itv->audio_input, &audin);
Hans Verkuil7c03a442007-08-19 18:59:42 -03001245 IVTV_INFO("Video Input: %s\n", vidin.name);
1246 IVTV_INFO("Audio Input: %s%s\n", audin.name,
Hans Verkuil25e3f8f2007-08-19 15:03:05 -03001247 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001248 if (has_output) {
1249 struct v4l2_output vidout;
1250 struct v4l2_audioout audout;
1251 int mode = itv->output_mode;
1252 static const char * const output_modes[] = {
1253 "None",
1254 "MPEG Streaming",
1255 "YUV Streaming",
1256 "YUV Frames",
1257 "Passthrough",
1258 };
Hans Verkuil25e3f8f2007-08-19 15:03:05 -03001259 static const char * const audio_modes[] = {
1260 "Stereo",
1261 "Left",
1262 "Right",
1263 "Mono",
1264 "Swapped"
1265 };
Hans Verkuil7c03a442007-08-19 18:59:42 -03001266 static const char * const alpha_mode[] = {
1267 "None",
1268 "Global",
1269 "Local",
1270 "Global and Local"
1271 };
1272 static const char * const pixel_format[] = {
1273 "Indexed",
1274 "RGB 5:6:5",
1275 "ARGB 1:5:5:5",
1276 "ARGB 1:4:4:4",
1277 "ARGB 8:8:8:8",
1278 "5",
1279 "6",
1280 "7",
1281 };
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001282
1283 ivtv_get_output(itv, itv->active_output, &vidout);
1284 ivtv_get_audio_output(itv, 0, &audout);
1285 IVTV_INFO("Video Output: %s\n", vidout.name);
Hans Verkuil25e3f8f2007-08-19 15:03:05 -03001286 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1287 audio_modes[itv->audio_stereo_mode],
1288 audio_modes[itv->audio_bilingual_mode]);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001289 if (mode < 0 || mode > OUT_PASSTHROUGH)
1290 mode = OUT_NONE;
Hans Verkuil7c03a442007-08-19 18:59:42 -03001291 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1292 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1293 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1294 data[0] & 1 ? "On" : "Off",
1295 alpha_mode[(data[0] >> 1) & 0x3],
1296 pixel_format[(data[0] >> 3) & 0x7]);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001297 }
Hans Verkuil7c03a442007-08-19 18:59:42 -03001298 IVTV_INFO("Tuner: %s\n",
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001299 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
1300 cx2341x_log_status(&itv->params, itv->name);
Hans Verkuil7c03a442007-08-19 18:59:42 -03001301 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001302 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1303 struct ivtv_stream *s = &itv->streams[i];
1304
1305 if (s->v4l2dev == NULL || s->buffers == 0)
1306 continue;
1307 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1308 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1309 (s->buffers * s->buf_size) / 1024, s->buffers);
1310 }
Hans Verkuil7c03a442007-08-19 18:59:42 -03001311 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 -03001312 IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
1313 break;
1314 }
1315
1316 default:
1317 return -EINVAL;
1318 }
1319 return 0;
1320}
1321
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001322static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001323{
1324 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1325 struct ivtv *itv = id->itv;
1326 int nonblocking = filp->f_flags & O_NONBLOCK;
1327 struct ivtv_stream *s = &itv->streams[id->type];
1328
1329 switch (cmd) {
1330 case IVTV_IOC_DMA_FRAME: {
1331 struct ivtv_dma_frame *args = arg;
1332
1333 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1334 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1335 return -EINVAL;
1336 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1337 return -EINVAL;
1338 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1339 return 0;
1340 if (ivtv_claim_stream(id, id->type)) {
1341 return -EBUSY;
1342 }
1343 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1344 ivtv_release_stream(s);
1345 return -EBUSY;
1346 }
Hans Verkuilad8ff0f2007-08-20 16:01:58 -03001347 /* Mark that this file handle started the UDMA_YUV mode */
1348 id->yuv_frames = 1;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001349 if (args->y_source == NULL)
1350 return 0;
1351 return ivtv_yuv_prep_frame(itv, args);
1352 }
1353
1354 case VIDEO_GET_PTS: {
1355 u32 data[CX2341X_MBOX_MAX_DATA];
1356 u64 *pts = arg;
1357
1358 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1359 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1360 *pts = s->dma_pts;
1361 break;
1362 }
1363 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1364 return -EINVAL;
1365
1366 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1367 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1368 (u64)itv->last_dec_timing[1];
1369 break;
1370 }
1371 *pts = 0;
1372 if (atomic_read(&itv->decoding)) {
1373 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1374 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1375 return -EIO;
1376 }
1377 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1378 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1379 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1380 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1381 }
1382 break;
1383 }
1384
1385 case VIDEO_GET_FRAME_COUNT: {
1386 u32 data[CX2341X_MBOX_MAX_DATA];
1387 u64 *frame = arg;
1388
1389 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1390 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1391 *frame = 0;
1392 break;
1393 }
1394 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1395 return -EINVAL;
1396
1397 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1398 *frame = itv->last_dec_timing[0];
1399 break;
1400 }
1401 *frame = 0;
1402 if (atomic_read(&itv->decoding)) {
1403 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1404 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1405 return -EIO;
1406 }
1407 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1408 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1409 *frame = data[0];
1410 }
1411 break;
1412 }
1413
1414 case VIDEO_PLAY: {
1415 struct video_command vc;
1416
1417 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1418 memset(&vc, 0, sizeof(vc));
1419 vc.cmd = VIDEO_CMD_PLAY;
1420 return ivtv_video_command(itv, id, &vc, 0);
1421 }
1422
1423 case VIDEO_STOP: {
1424 struct video_command vc;
1425
1426 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1427 memset(&vc, 0, sizeof(vc));
1428 vc.cmd = VIDEO_CMD_STOP;
1429 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1430 return ivtv_video_command(itv, id, &vc, 0);
1431 }
1432
1433 case VIDEO_FREEZE: {
1434 struct video_command vc;
1435
1436 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1437 memset(&vc, 0, sizeof(vc));
1438 vc.cmd = VIDEO_CMD_FREEZE;
1439 return ivtv_video_command(itv, id, &vc, 0);
1440 }
1441
1442 case VIDEO_CONTINUE: {
1443 struct video_command vc;
1444
1445 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1446 memset(&vc, 0, sizeof(vc));
1447 vc.cmd = VIDEO_CMD_CONTINUE;
1448 return ivtv_video_command(itv, id, &vc, 0);
1449 }
1450
1451 case VIDEO_COMMAND:
1452 case VIDEO_TRY_COMMAND: {
1453 struct video_command *vc = arg;
1454 int try = (cmd == VIDEO_TRY_COMMAND);
1455
1456 if (try)
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001457 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001458 else
Hans Verkuil1aa32c22007-08-19 06:08:58 -03001459 IVTV_DEBUG_IOCTL("VIDEO_COMMAND %d\n", vc->cmd);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001460 return ivtv_video_command(itv, id, vc, try);
1461 }
1462
1463 case VIDEO_GET_EVENT: {
1464 struct video_event *ev = arg;
1465 DEFINE_WAIT(wait);
1466
1467 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1468 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1469 return -EINVAL;
1470 memset(ev, 0, sizeof(*ev));
1471 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1472
1473 while (1) {
1474 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1475 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1476 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1477 ev->type = VIDEO_EVENT_VSYNC;
Hans Verkuil037c86c2007-03-10 06:30:19 -03001478 ev->u.vsync_field = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1479 VIDEO_VSYNC_FIELD_ODD : VIDEO_VSYNC_FIELD_EVEN;
1480 if (itv->output_mode == OUT_UDMA_YUV &&
1481 (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) ==
1482 IVTV_YUV_MODE_PROGRESSIVE) {
1483 ev->u.vsync_field = VIDEO_VSYNC_FIELD_PROGRESSIVE;
1484 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001485 }
1486 if (ev->type)
1487 return 0;
1488 if (nonblocking)
1489 return -EAGAIN;
Hans Verkuilbaa40722007-08-19 07:10:55 -03001490 /* Wait for event. Note that serialize_lock is locked,
1491 so to allow other processes to access the driver while
1492 we are waiting unlock first and later lock again. */
1493 mutex_unlock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001494 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
1495 if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)
1496 schedule();
1497 finish_wait(&itv->event_waitq, &wait);
Hans Verkuilbaa40722007-08-19 07:10:55 -03001498 mutex_lock(&itv->serialize_lock);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001499 if (signal_pending(current)) {
1500 /* return if a signal was received */
1501 IVTV_DEBUG_INFO("User stopped wait for event\n");
1502 return -EINTR;
1503 }
1504 }
1505 break;
1506 }
1507
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001508 default:
1509 return -EINVAL;
1510 }
1511 return 0;
1512}
1513
1514static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
1515 unsigned int cmd, void *arg)
1516{
1517 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1518 struct ivtv *itv = id->itv;
Hans Verkuild46c17d2007-03-10 17:59:15 -03001519 int ret;
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001520
Hans Verkuild46c17d2007-03-10 17:59:15 -03001521 /* check priority */
1522 switch (cmd) {
1523 case VIDIOC_S_CTRL:
1524 case VIDIOC_S_STD:
1525 case VIDIOC_S_INPUT:
1526 case VIDIOC_S_OUTPUT:
1527 case VIDIOC_S_TUNER:
1528 case VIDIOC_S_FREQUENCY:
1529 case VIDIOC_S_FMT:
1530 case VIDIOC_S_CROP:
1531 case VIDIOC_S_AUDIO:
1532 case VIDIOC_S_AUDOUT:
1533 case VIDIOC_S_EXT_CTRLS:
1534 case VIDIOC_S_FBUF:
Hans Verkuil7c03a442007-08-19 18:59:42 -03001535 case VIDIOC_OVERLAY:
Hans Verkuild46c17d2007-03-10 17:59:15 -03001536 ret = v4l2_prio_check(&itv->prio, &id->prio);
1537 if (ret)
1538 return ret;
1539 }
1540
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001541 switch (cmd) {
1542 case VIDIOC_DBG_G_REGISTER:
1543 case VIDIOC_DBG_S_REGISTER:
1544 case VIDIOC_G_CHIP_IDENT:
1545 case VIDIOC_INT_S_AUDIO_ROUTING:
1546 case VIDIOC_INT_RESET:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001547 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1548 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1549 v4l_printk_ioctl(cmd);
1550 }
1551 return ivtv_debug_ioctls(filp, cmd, arg);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001552
Hans Verkuild46c17d2007-03-10 17:59:15 -03001553 case VIDIOC_G_PRIORITY:
1554 case VIDIOC_S_PRIORITY:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001555 case VIDIOC_QUERYCAP:
1556 case VIDIOC_ENUMINPUT:
1557 case VIDIOC_G_INPUT:
1558 case VIDIOC_S_INPUT:
1559 case VIDIOC_ENUMOUTPUT:
1560 case VIDIOC_G_OUTPUT:
1561 case VIDIOC_S_OUTPUT:
1562 case VIDIOC_G_FMT:
1563 case VIDIOC_S_FMT:
1564 case VIDIOC_TRY_FMT:
1565 case VIDIOC_ENUM_FMT:
Hans Verkuil987e00b2007-05-29 13:03:27 -03001566 case VIDIOC_CROPCAP:
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001567 case VIDIOC_G_CROP:
1568 case VIDIOC_S_CROP:
1569 case VIDIOC_G_FREQUENCY:
1570 case VIDIOC_S_FREQUENCY:
1571 case VIDIOC_ENUMSTD:
1572 case VIDIOC_G_STD:
1573 case VIDIOC_S_STD:
1574 case VIDIOC_S_TUNER:
1575 case VIDIOC_G_TUNER:
1576 case VIDIOC_ENUMAUDIO:
1577 case VIDIOC_S_AUDIO:
1578 case VIDIOC_G_AUDIO:
1579 case VIDIOC_ENUMAUDOUT:
1580 case VIDIOC_S_AUDOUT:
1581 case VIDIOC_G_AUDOUT:
1582 case VIDIOC_G_SLICED_VBI_CAP:
1583 case VIDIOC_LOG_STATUS:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001584 case VIDIOC_G_ENC_INDEX:
1585 case VIDIOC_ENCODER_CMD:
1586 case VIDIOC_TRY_ENCODER_CMD:
1587 case VIDIOC_G_FBUF:
1588 case VIDIOC_S_FBUF:
Hans Verkuil7c03a442007-08-19 18:59:42 -03001589 case VIDIOC_OVERLAY:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001590 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1591 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1592 v4l_printk_ioctl(cmd);
1593 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001594 return ivtv_v4l2_ioctls(itv, filp, cmd, arg);
1595
1596 case VIDIOC_QUERYMENU:
1597 case VIDIOC_QUERYCTRL:
1598 case VIDIOC_S_CTRL:
1599 case VIDIOC_G_CTRL:
1600 case VIDIOC_S_EXT_CTRLS:
1601 case VIDIOC_G_EXT_CTRLS:
1602 case VIDIOC_TRY_EXT_CTRLS:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001603 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1604 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1605 v4l_printk_ioctl(cmd);
1606 }
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001607 return ivtv_control_ioctls(itv, cmd, arg);
1608
1609 case IVTV_IOC_DMA_FRAME:
1610 case VIDEO_GET_PTS:
1611 case VIDEO_GET_FRAME_COUNT:
1612 case VIDEO_GET_EVENT:
1613 case VIDEO_PLAY:
1614 case VIDEO_STOP:
1615 case VIDEO_FREEZE:
1616 case VIDEO_CONTINUE:
1617 case VIDEO_COMMAND:
1618 case VIDEO_TRY_COMMAND:
Hans Verkuild4e7ee32007-03-10 18:19:12 -03001619 return ivtv_decoder_ioctls(filp, cmd, arg);
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001620
1621 case 0x00005401: /* Handle isatty() calls */
1622 return -EINVAL;
1623 default:
1624 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
1625 ivtv_v4l2_do_ioctl);
1626 }
1627 return 0;
1628}
1629
Hans Verkuilbaa40722007-08-19 07:10:55 -03001630static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
1631 unsigned int cmd, unsigned long arg)
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001632{
Hans Verkuil1a0adaf2007-04-27 12:31:25 -03001633 /* Filter dvb ioctls that cannot be handled by video_usercopy */
1634 switch (cmd) {
1635 case VIDEO_SELECT_SOURCE:
1636 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1637 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1638 return -EINVAL;
1639 return ivtv_passthrough_mode(itv, arg == VIDEO_SOURCE_DEMUX);
1640
1641 case AUDIO_SET_MUTE:
1642 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1643 itv->speed_mute_audio = arg;
1644 return 0;
1645
1646 case AUDIO_CHANNEL_SELECT:
1647 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1648 if (arg > AUDIO_STEREO_SWAPPED)
1649 return -EINVAL;
1650 itv->audio_stereo_mode = arg;
1651 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1652 return 0;
1653
1654 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1655 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1656 if (arg > AUDIO_STEREO_SWAPPED)
1657 return -EINVAL;
1658 itv->audio_bilingual_mode = arg;
1659 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1660 return 0;
1661
1662 default:
1663 break;
1664 }
1665 return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);
1666}
Hans Verkuilbaa40722007-08-19 07:10:55 -03001667
1668int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1669 unsigned long arg)
1670{
1671 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1672 struct ivtv *itv = id->itv;
1673 int res;
1674
1675 mutex_lock(&itv->serialize_lock);
1676 res = ivtv_serialized_ioctl(itv, inode, filp, cmd, arg);
1677 mutex_unlock(&itv->serialize_lock);
1678 return res;
1679}