aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-ioctl.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-04-27 11:31:25 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2007-04-27 14:43:50 -0400
commit1a0adaf37c30e89e44d1470ef604a930999a5826 (patch)
tree6e6d6e823f44abdb2ed3847e00406a75bc968cef /drivers/media/video/ivtv/ivtv-ioctl.c
parentac52ea3c3c04403d10acf0253180ec6f51977142 (diff)
V4L/DVB (5345): ivtv driver for Conexant cx23416/cx23415 MPEG encoder/decoder
It took three core maintainers, over four years of work, eight new i2c modules, eleven new V4L2 ioctls, three new DVB video ioctls, a Sliced VBI API, a new MPEG encoder API, an enhanced DVB video MPEG decoding API, major YUV/OSD contributions from Ian and John, web/wiki/svn/trac support from Axel Thimm, (hardware) support from Hauppauge, support and assistance from the v4l-dvb people and the many, many users of ivtv to finally make it possible to merge this driver into the kernel. Thank you all! Signed-off-by: Kevin Thayer <nufan_wfk@yahoo.com> Signed-off-by: Chris Kennedy <c@groovy.org> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: John P Harvey <john.p.harvey@btinternet.com> Signed-off-by: Ian Armstrong <ian@iarmst.demon.co.uk> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-ioctl.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c1555
1 files changed, 1555 insertions, 0 deletions
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
new file mode 100644
index 000000000000..448e8dd5b42f
--- /dev/null
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -0,0 +1,1555 @@
1/*
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: {
280 vc->play.speed = ivtv_validate_speed(itv->speed, vc->play.speed);
281 if (vc->play.speed < 0)
282 vc->play.format = VIDEO_PLAY_FMT_GOP;
283 if (try) break;
284
285 if (ivtv_set_output_mode(itv, OUT_MPG) != OUT_MPG)
286 return -EBUSY;
287 return ivtv_start_decoding(id, vc->play.speed);
288 }
289
290 case VIDEO_CMD_STOP:
291 if (vc->flags & VIDEO_CMD_STOP_IMMEDIATELY)
292 vc->stop.pts = 0;
293 if (try) break;
294 if (atomic_read(&itv->decoding) == 0)
295 return 0;
296 if (itv->output_mode != OUT_MPG)
297 return -EBUSY;
298
299 itv->output_mode = OUT_NONE;
300 return ivtv_stop_v4l2_decode_stream(s, vc->flags, vc->stop.pts);
301
302 case VIDEO_CMD_FREEZE:
303 if (try) break;
304 if (itv->output_mode != OUT_MPG)
305 return -EBUSY;
306 if (atomic_read(&itv->decoding) > 0) {
307 ivtv_vapi(itv, CX2341X_DEC_PAUSE_PLAYBACK, 1,
308 (vc->flags & VIDEO_CMD_FREEZE_TO_BLACK) ? 1 : 0);
309 }
310 break;
311
312 case VIDEO_CMD_CONTINUE:
313 if (try) break;
314 if (itv->output_mode != OUT_MPG)
315 return -EBUSY;
316 if (atomic_read(&itv->decoding) > 0) {
317 ivtv_vapi(itv, CX2341X_DEC_START_PLAYBACK, 2, 0, 0);
318 }
319 break;
320
321 default:
322 return -EINVAL;
323 }
324 return 0;
325}
326
327static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
328{
329 struct v4l2_register *regs = arg;
330 unsigned long flags;
331 volatile u8 __iomem *reg_start;
332
333 if (!capable(CAP_SYS_ADMIN))
334 return -EPERM;
335 if (regs->reg >= IVTV_REG_OFFSET && regs->reg < IVTV_REG_OFFSET + IVTV_REG_SIZE)
336 reg_start = itv->reg_mem - IVTV_REG_OFFSET;
337 else if (itv->has_cx23415 && regs->reg >= IVTV_DECODER_OFFSET &&
338 regs->reg < IVTV_DECODER_OFFSET + IVTV_DECODER_SIZE)
339 reg_start = itv->dec_mem - IVTV_DECODER_OFFSET;
340 else if (regs->reg >= 0 && regs->reg < IVTV_ENCODER_SIZE)
341 reg_start = itv->enc_mem;
342 else
343 return -EINVAL;
344
345 spin_lock_irqsave(&ivtv_cards_lock, flags);
346 if (cmd == VIDIOC_DBG_G_REGISTER) {
347 regs->val = readl(regs->reg + reg_start);
348 } else {
349 writel(regs->val, regs->reg + reg_start);
350 }
351 spin_unlock_irqrestore(&ivtv_cards_lock, flags);
352 return 0;
353}
354
355static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fmt)
356{
357 switch (fmt->type) {
358 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
359 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
360 return -EINVAL;
361 fmt->fmt.pix.left = itv->main_rect.left;
362 fmt->fmt.pix.top = itv->main_rect.top;
363 fmt->fmt.pix.width = itv->main_rect.width;
364 fmt->fmt.pix.height = itv->main_rect.height;
365 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
366 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
367 if (itv->output_mode == OUT_UDMA_YUV) {
368 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
369 case IVTV_YUV_MODE_INTERLACED:
370 fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
371 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
372 break;
373 case IVTV_YUV_MODE_PROGRESSIVE:
374 fmt->fmt.pix.field = V4L2_FIELD_NONE;
375 break;
376 default:
377 fmt->fmt.pix.field = V4L2_FIELD_ANY;
378 break;
379 }
380 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
381 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
382 fmt->fmt.pix.sizeimage =
383 fmt->fmt.pix.height * fmt->fmt.pix.width +
384 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
385 }
386 else if (itv->output_mode == OUT_YUV ||
387 streamtype == IVTV_ENC_STREAM_TYPE_YUV ||
388 streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
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 } else {
395 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
396 fmt->fmt.pix.sizeimage = 128 * 1024;
397 }
398 break;
399
400 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
401 fmt->fmt.pix.left = 0;
402 fmt->fmt.pix.top = 0;
403 fmt->fmt.pix.width = itv->params.width;
404 fmt->fmt.pix.height = itv->params.height;
405 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
406 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
407 if (streamtype == IVTV_ENC_STREAM_TYPE_YUV ||
408 streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
409 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
410 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
411 fmt->fmt.pix.sizeimage =
412 fmt->fmt.pix.height * fmt->fmt.pix.width +
413 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
414 } else {
415 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
416 fmt->fmt.pix.sizeimage = 128 * 1024;
417 }
418 break;
419
420 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
421 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
422 return -EINVAL;
423 fmt->fmt.win.chromakey = itv->osd_color_key;
424 fmt->fmt.win.global_alpha = itv->osd_global_alpha;
425 break;
426
427 case V4L2_BUF_TYPE_VBI_CAPTURE:
428 fmt->fmt.vbi.sampling_rate = 27000000;
429 fmt->fmt.vbi.offset = 248;
430 fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4;
431 fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
432 fmt->fmt.vbi.start[0] = itv->vbi.start[0];
433 fmt->fmt.vbi.start[1] = itv->vbi.start[1];
434 fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count;
435 break;
436
437 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
438 {
439 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
440
441 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
442 return -EINVAL;
443 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
444 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
445 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
446 if (itv->is_60hz) {
447 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
448 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
449 } else {
450 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
451 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
452 }
453 vbifmt->service_set = get_service_set(vbifmt);
454 break;
455 }
456
457 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE:
458 {
459 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
460
461 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
462 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
463 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
464
465 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
466 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
467 V4L2_SLICED_VBI_525;
468 expand_service_set(vbifmt, itv->is_50hz);
469 break;
470 }
471
472 itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
473 vbifmt->service_set = get_service_set(vbifmt);
474 break;
475 }
476 case V4L2_BUF_TYPE_VBI_OUTPUT:
477 case V4L2_BUF_TYPE_VIDEO_OVERLAY:
478 default:
479 return -EINVAL;
480 }
481 return 0;
482}
483
484static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
485 struct v4l2_format *fmt, int set_fmt)
486{
487 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
488 u16 set;
489
490 if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) {
491 struct v4l2_rect r;
492 int field;
493
494 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
495 return -EINVAL;
496 field = fmt->fmt.pix.field;
497 r.top = fmt->fmt.pix.top;
498 r.left = fmt->fmt.pix.left;
499 r.width = fmt->fmt.pix.width;
500 r.height = fmt->fmt.pix.height;
501 ivtv_get_fmt(itv, streamtype, fmt);
502 if (itv->output_mode != OUT_UDMA_YUV) {
503 /* TODO: would setting the rect also be valid for this mode? */
504 fmt->fmt.pix.top = r.top;
505 fmt->fmt.pix.left = r.left;
506 fmt->fmt.pix.width = r.width;
507 fmt->fmt.pix.height = r.height;
508 }
509 if (itv->output_mode == OUT_UDMA_YUV) {
510 /* TODO: add checks for validity */
511 fmt->fmt.pix.field = field;
512 }
513 if (set_fmt) {
514 if (itv->output_mode == OUT_UDMA_YUV) {
515 switch (field) {
516 case V4L2_FIELD_NONE:
517 itv->yuv_info.lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
518 break;
519 case V4L2_FIELD_ANY:
520 itv->yuv_info.lace_mode = IVTV_YUV_MODE_AUTO;
521 break;
522 case V4L2_FIELD_INTERLACED_BT:
523 itv->yuv_info.lace_mode =
524 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
525 break;
526 case V4L2_FIELD_INTERLACED_TB:
527 default:
528 itv->yuv_info.lace_mode = IVTV_YUV_MODE_INTERLACED;
529 break;
530 }
531 itv->yuv_info.lace_sync_field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
532
533 /* Force update of yuv registers */
534 itv->yuv_info.yuv_forced_update = 1;
535 return 0;
536 }
537 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
538 r.width, r.height, r.left, r.top))
539 itv->main_rect = r;
540 else
541 return -EINVAL;
542 }
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
635static int ivtv_internal_ioctls(struct file *filp, unsigned int cmd, void *arg)
636{
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:
644 IVTV_DEBUG_IOCTL("VIDIOC_DBG_G_REGISTER\n");
645 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
646 return ivtv_itvc(itv, cmd, arg);
647 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
648 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
649 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
650
651 case VIDIOC_DBG_S_REGISTER:
652 IVTV_DEBUG_IOCTL("VIDIOC_DBG_S_REGISTER\n");
653 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
654 return ivtv_itvc(itv, cmd, arg);
655 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
656 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
657 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
658
659 case VIDIOC_G_CHIP_IDENT: {
660 struct v4l2_chip_ident *chip = arg;
661
662 IVTV_DEBUG_IOCTL("VIDIOC_G_CHIP_IDENT\n");
663 chip->ident = V4L2_IDENT_NONE;
664 chip->revision = 0;
665 if (reg->match_type == V4L2_CHIP_MATCH_HOST) {
666 if (v4l2_chip_match_host(reg->match_type, reg->match_chip)) {
667 struct v4l2_chip_ident *chip = arg;
668
669 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
670 }
671 return 0;
672 }
673 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
674 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
675 if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
676 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
677 return -EINVAL;
678 }
679
680 case VIDIOC_INT_S_AUDIO_ROUTING: {
681 struct v4l2_routing *route = arg;
682
683 IVTV_DEBUG_IOCTL("VIDIOC_INT_S_AUDIO_ROUTING\n");
684 ivtv_audio_set_route(itv, route);
685 break;
686 }
687
688 case VIDIOC_INT_RESET:
689 IVTV_DEBUG_IOCTL("VIDIOC_INT_RESET\n");
690 ivtv_reset_ir_gpio(itv);
691 break;
692
693 default:
694 return -EINVAL;
695 }
696 return 0;
697}
698
699int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg)
700{
701 struct ivtv_open_id *id = NULL;
702
703 if (filp) id = (struct ivtv_open_id *)filp->private_data;
704
705 switch (cmd) {
706 case VIDIOC_QUERYCAP:{
707 struct v4l2_capability *vcap = arg;
708
709 IVTV_DEBUG_IOCTL("VIDIOC_QUERYCAP\n");
710
711 memset(vcap, 0, sizeof(*vcap));
712 strcpy(vcap->driver, IVTV_DRIVER_NAME); /* driver name */
713 strcpy(vcap->card, itv->card_name); /* card type */
714 strcpy(vcap->bus_info, pci_name(itv->dev)); /* bus info... */
715 vcap->version = IVTV_DRIVER_VERSION; /* version */
716 vcap->capabilities = itv->v4l2_cap; /* capabilities */
717
718 /* reserved.. must set to 0! */
719 vcap->reserved[0] = vcap->reserved[1] =
720 vcap->reserved[2] = vcap->reserved[3] = 0;
721 break;
722 }
723
724 case VIDIOC_ENUMAUDIO:{
725 struct v4l2_audio *vin = arg;
726
727 IVTV_DEBUG_IOCTL("VIDIOC_ENUMAUDIO\n");
728
729 return ivtv_get_audio_input(itv, vin->index, vin);
730 }
731
732 case VIDIOC_G_AUDIO:{
733 struct v4l2_audio *vin = arg;
734
735 IVTV_DEBUG_IOCTL("VIDIOC_G_AUDIO\n");
736 vin->index = itv->audio_input;
737 return ivtv_get_audio_input(itv, vin->index, vin);
738 }
739
740 case VIDIOC_S_AUDIO:{
741 struct v4l2_audio *vout = arg;
742
743 IVTV_DEBUG_IOCTL("VIDIOC_S_AUDIO\n");
744
745 if (vout->index >= itv->nof_audio_inputs)
746 return -EINVAL;
747 itv->audio_input = vout->index;
748 ivtv_audio_set_io(itv);
749 break;
750 }
751
752 case VIDIOC_ENUMAUDOUT:{
753 struct v4l2_audioout *vin = arg;
754
755 IVTV_DEBUG_IOCTL("VIDIOC_ENUMAUDOUT\n");
756
757 /* set it to defaults from our table */
758 return ivtv_get_audio_output(itv, vin->index, vin);
759 }
760
761 case VIDIOC_G_AUDOUT:{
762 struct v4l2_audioout *vin = arg;
763
764 IVTV_DEBUG_IOCTL("VIDIOC_G_AUDOUT\n");
765 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
772 IVTV_DEBUG_IOCTL("VIDIOC_S_AUDOUT\n");
773
774 return ivtv_get_audio_output(itv, vout->index, vout);
775 }
776
777 case VIDIOC_ENUMINPUT:{
778 struct v4l2_input *vin = arg;
779
780 IVTV_DEBUG_IOCTL("VIDIOC_ENUMINPUT\n");
781
782 /* set it to defaults from our table */
783 return ivtv_get_input(itv, vin->index, vin);
784 }
785
786 case VIDIOC_ENUMOUTPUT:{
787 struct v4l2_output *vout = arg;
788
789 IVTV_DEBUG_IOCTL("VIDIOC_ENUMOUTPUT\n");
790
791 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
798 if (cmd == VIDIOC_S_FMT) {
799 IVTV_DEBUG_IOCTL("VIDIOC_S_FMT\n");
800 } else {
801 IVTV_DEBUG_IOCTL("VIDIOC_TRY_FMT\n");
802 }
803 return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT);
804 }
805
806 case VIDIOC_G_FMT: {
807 struct v4l2_format *fmt = arg;
808 int type = fmt->type;
809
810 IVTV_DEBUG_IOCTL("VIDIOC_G_FMT\n");
811 memset(fmt, 0, sizeof(*fmt));
812 fmt->type = type;
813 return ivtv_get_fmt(itv, id->type, fmt);
814 }
815
816 case VIDIOC_S_CROP: {
817 struct v4l2_crop *crop = arg;
818
819 IVTV_DEBUG_IOCTL("VIDIOC_S_CROP\n");
820 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
821 return -EINVAL;
822 return itv->video_dec_func(itv, VIDIOC_S_CROP, arg);
823 }
824
825 case VIDIOC_G_CROP: {
826 struct v4l2_crop *crop = arg;
827
828 IVTV_DEBUG_IOCTL("VIDIOC_G_CROP\n");
829 if (crop->type != V4L2_BUF_TYPE_VIDEO_CAPTURE)
830 return -EINVAL;
831 return itv->video_dec_func(itv, VIDIOC_G_CROP, arg);
832 }
833
834 case VIDIOC_ENUM_FMT: {
835 static struct v4l2_fmtdesc formats[] = {
836 { 0, 0, 0,
837 "HM12 (YUV 4:1:1)", V4L2_PIX_FMT_HM12,
838 { 0, 0, 0, 0 }
839 },
840 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
841 "MPEG", V4L2_PIX_FMT_MPEG,
842 { 0, 0, 0, 0 }
843 }
844 };
845 struct v4l2_fmtdesc *fmt = arg;
846 enum v4l2_buf_type type = fmt->type;
847
848 switch (type) {
849 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
850 break;
851 case V4L2_BUF_TYPE_VIDEO_OUTPUT:
852 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
853 return -EINVAL;
854 break;
855 default:
856 return -EINVAL;
857 }
858 if (fmt->index > 1)
859 return -EINVAL;
860 *fmt = formats[fmt->index];
861 fmt->type = type;
862 return 0;
863 }
864
865 case VIDIOC_G_INPUT:{
866 IVTV_DEBUG_IOCTL("VIDIOC_G_INPUT\n");
867
868 *(int *)arg = itv->active_input;
869 break;
870 }
871
872 case VIDIOC_S_INPUT:{
873 int inp = *(int *)arg;
874
875 IVTV_DEBUG_IOCTL("VIDIOC_S_INPUT\n");
876
877 if (inp < 0 || inp >= itv->nof_inputs)
878 return -EINVAL;
879
880 if (inp == itv->active_input) {
881 IVTV_DEBUG_INFO("Input unchanged\n");
882 break;
883 }
884 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
885 itv->active_input, inp);
886
887 itv->active_input = inp;
888 /* Set the audio input to whatever is appropriate for the
889 input type. */
890 itv->audio_input = itv->card->video_inputs[inp].audio_index;
891
892 /* prevent others from messing with the streams until
893 we're finished changing inputs. */
894 ivtv_mute(itv);
895 ivtv_video_set_io(itv);
896 ivtv_audio_set_io(itv);
897 ivtv_unmute(itv);
898 break;
899 }
900
901 case VIDIOC_G_OUTPUT:{
902 IVTV_DEBUG_IOCTL("VIDIOC_G_OUTPUT\n");
903
904 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
905 return -EINVAL;
906 *(int *)arg = itv->active_output;
907 break;
908 }
909
910 case VIDIOC_S_OUTPUT:{
911 int outp = *(int *)arg;
912 struct v4l2_routing route;
913
914 IVTV_DEBUG_IOCTL("VIDIOC_S_OUTPUT\n");
915
916 if (outp >= itv->card->nof_outputs)
917 return -EINVAL;
918
919 if (outp == itv->active_output) {
920 IVTV_DEBUG_INFO("Output unchanged\n");
921 break;
922 }
923 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
924 itv->active_output, outp);
925
926 itv->active_output = outp;
927 route.input = SAA7127_INPUT_TYPE_NORMAL;
928 route.output = itv->card->video_outputs[outp].video_output;
929 ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
930 break;
931 }
932
933 case VIDIOC_G_FREQUENCY:{
934 struct v4l2_frequency *vf = arg;
935
936 IVTV_DEBUG_IOCTL("VIDIOC_G_FREQUENCY\n");
937
938 if (vf->tuner != 0)
939 return -EINVAL;
940 ivtv_call_i2c_clients(itv, cmd, arg);
941 break;
942 }
943
944 case VIDIOC_S_FREQUENCY:{
945 struct v4l2_frequency vf = *(struct v4l2_frequency *)arg;
946
947 IVTV_DEBUG_IOCTL("VIDIOC_S_FREQUENCY\n");
948
949 if (vf.tuner != 0)
950 return -EINVAL;
951
952 ivtv_mute(itv);
953 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency);
954 ivtv_call_i2c_clients(itv, cmd, &vf);
955 ivtv_unmute(itv);
956 break;
957 }
958
959 case VIDIOC_ENUMSTD:{
960 struct v4l2_standard *vs = arg;
961 int idx = vs->index;
962
963 IVTV_DEBUG_IOCTL("VIDIOC_ENUMSTD\n");
964
965 if (idx < 0 || idx >= ARRAY_SIZE(enum_stds))
966 return -EINVAL;
967
968 *vs = (enum_stds[idx].std & V4L2_STD_525_60) ?
969 ivtv_std_60hz : ivtv_std_50hz;
970 vs->index = idx;
971 vs->id = enum_stds[idx].std;
972 strcpy(vs->name, enum_stds[idx].name);
973 break;
974 }
975
976 case VIDIOC_G_STD:{
977 IVTV_DEBUG_IOCTL("VIDIOC_G_STD\n");
978 *(v4l2_std_id *) arg = itv->std;
979 break;
980 }
981
982 case VIDIOC_S_STD: {
983 v4l2_std_id std = *(v4l2_std_id *) arg;
984
985 IVTV_DEBUG_IOCTL("VIDIOC_S_STD\n");
986
987 if ((std & V4L2_STD_ALL) == 0)
988 return -EINVAL;
989
990 if (std == itv->std)
991 break;
992
993 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
994 atomic_read(&itv->capturing) > 0 ||
995 atomic_read(&itv->decoding) > 0) {
996 /* Switching standard would turn off the radio or mess
997 with already running streams, prevent that by
998 returning EBUSY. */
999 return -EBUSY;
1000 }
1001
1002 itv->std = std;
1003 itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0;
1004 itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
1005 itv->params.width = 720;
1006 itv->params.height = itv->is_50hz ? 576 : 480;
1007 itv->vbi.count = itv->is_50hz ? 18 : 12;
1008 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1009 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1010 if (itv->hw_flags & IVTV_HW_CX25840) {
1011 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1012 }
1013 IVTV_DEBUG_INFO("Switching standard to %llx.\n", itv->std);
1014
1015 /* Tuner */
1016 ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
1017
1018 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1019 /* set display standard */
1020 itv->std_out = std;
1021 itv->is_out_60hz = itv->is_60hz;
1022 itv->is_out_50hz = itv->is_50hz;
1023 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
1024 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1025 itv->main_rect.left = itv->main_rect.top = 0;
1026 itv->main_rect.width = 720;
1027 itv->main_rect.height = itv->params.height;
1028 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1029 720, itv->main_rect.height, 0, 0);
1030 }
1031 break;
1032 }
1033
1034 case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */
1035 struct v4l2_tuner *vt = arg;
1036
1037 IVTV_DEBUG_IOCTL("VIDIOC_S_TUNER\n");
1038
1039 if (vt->index != 0)
1040 return -EINVAL;
1041
1042 ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
1043 break;
1044 }
1045
1046 case VIDIOC_G_TUNER: {
1047 struct v4l2_tuner *vt = arg;
1048
1049 IVTV_DEBUG_IOCTL("VIDIOC_G_TUNER\n");
1050
1051 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
1073 IVTV_DEBUG_IOCTL("VIDIOC_G_SLICED_VBI_CAP\n");
1074 memset(cap, 0, sizeof(*cap));
1075 cap->type = type;
1076 if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1077 for (f = 0; f < 2; f++) {
1078 for (l = 0; l < 24; l++) {
1079 if (valid_service_line(f, l, itv->is_50hz)) {
1080 cap->service_lines[f][l] = set;
1081 }
1082 }
1083 }
1084 return 0;
1085 }
1086 if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
1087 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1088 return -EINVAL;
1089 if (itv->is_60hz) {
1090 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1091 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1092 } else {
1093 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1094 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1095 }
1096 return 0;
1097 }
1098 return -EINVAL;
1099 }
1100
1101 case VIDIOC_LOG_STATUS:
1102 {
1103 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1104 struct v4l2_input vidin;
1105 struct v4l2_audio audin;
1106 int i;
1107
1108 IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num);
1109 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1110 struct tveeprom tv;
1111
1112 ivtv_read_eeprom(itv, &tv);
1113 }
1114 ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
1115 ivtv_get_input(itv, itv->active_input, &vidin);
1116 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1117 IVTV_INFO("Video Input: %s\n", vidin.name);
1118 IVTV_INFO("Audio Input: %s\n", audin.name);
1119 if (has_output) {
1120 struct v4l2_output vidout;
1121 struct v4l2_audioout audout;
1122 int mode = itv->output_mode;
1123 static const char * const output_modes[] = {
1124 "None",
1125 "MPEG Streaming",
1126 "YUV Streaming",
1127 "YUV Frames",
1128 "Passthrough",
1129 };
1130
1131 ivtv_get_output(itv, itv->active_output, &vidout);
1132 ivtv_get_audio_output(itv, 0, &audout);
1133 IVTV_INFO("Video Output: %s\n", vidout.name);
1134 IVTV_INFO("Audio Output: %s\n", audout.name);
1135 if (mode < 0 || mode > OUT_PASSTHROUGH)
1136 mode = OUT_NONE;
1137 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1138 }
1139 IVTV_INFO("Tuner: %s\n",
1140 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
1141 cx2341x_log_status(&itv->params, itv->name);
1142 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1143 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1144 struct ivtv_stream *s = &itv->streams[i];
1145
1146 if (s->v4l2dev == NULL || s->buffers == 0)
1147 continue;
1148 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1149 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1150 (s->buffers * s->buf_size) / 1024, s->buffers);
1151 }
1152 IVTV_INFO("Read MPEG/VBI: %lld/%lld bytes\n", itv->mpg_data_received, itv->vbi_data_inserted);
1153 IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
1154 break;
1155 }
1156
1157 default:
1158 return -EINVAL;
1159 }
1160 return 0;
1161}
1162
1163static int ivtv_ivtv_ioctls(struct file *filp, unsigned int cmd, void *arg)
1164{
1165 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1166 struct ivtv *itv = id->itv;
1167 int nonblocking = filp->f_flags & O_NONBLOCK;
1168 struct ivtv_stream *s = &itv->streams[id->type];
1169
1170 switch (cmd) {
1171 case IVTV_IOC_DMA_FRAME: {
1172 struct ivtv_dma_frame *args = arg;
1173
1174 IVTV_DEBUG_IOCTL("IVTV_IOC_DMA_FRAME\n");
1175 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1176 return -EINVAL;
1177 if (args->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
1178 return -EINVAL;
1179 if (itv->output_mode == OUT_UDMA_YUV && args->y_source == NULL)
1180 return 0;
1181 if (ivtv_claim_stream(id, id->type)) {
1182 return -EBUSY;
1183 }
1184 if (ivtv_set_output_mode(itv, OUT_UDMA_YUV) != OUT_UDMA_YUV) {
1185 ivtv_release_stream(s);
1186 return -EBUSY;
1187 }
1188 if (args->y_source == NULL)
1189 return 0;
1190 return ivtv_yuv_prep_frame(itv, args);
1191 }
1192
1193 case VIDEO_GET_PTS: {
1194 u32 data[CX2341X_MBOX_MAX_DATA];
1195 u64 *pts = arg;
1196
1197 IVTV_DEBUG_IOCTL("VIDEO_GET_PTS\n");
1198 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1199 *pts = s->dma_pts;
1200 break;
1201 }
1202 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1203 return -EINVAL;
1204
1205 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1206 *pts = (u64) ((u64)itv->last_dec_timing[2] << 32) |
1207 (u64)itv->last_dec_timing[1];
1208 break;
1209 }
1210 *pts = 0;
1211 if (atomic_read(&itv->decoding)) {
1212 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1213 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1214 return -EIO;
1215 }
1216 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1217 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1218 *pts = (u64) ((u64) data[2] << 32) | (u64) data[1];
1219 /*timing->scr = (u64) (((u64) data[4] << 32) | (u64) (data[3]));*/
1220 }
1221 break;
1222 }
1223
1224 case VIDEO_GET_FRAME_COUNT: {
1225 u32 data[CX2341X_MBOX_MAX_DATA];
1226 u64 *frame = arg;
1227
1228 IVTV_DEBUG_IOCTL("VIDEO_GET_FRAME_COUNT\n");
1229 if (s->type < IVTV_DEC_STREAM_TYPE_MPG) {
1230 *frame = 0;
1231 break;
1232 }
1233 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1234 return -EINVAL;
1235
1236 if (test_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags)) {
1237 *frame = itv->last_dec_timing[0];
1238 break;
1239 }
1240 *frame = 0;
1241 if (atomic_read(&itv->decoding)) {
1242 if (ivtv_api(itv, CX2341X_DEC_GET_TIMING_INFO, 5, data)) {
1243 IVTV_DEBUG_WARN("GET_TIMING: couldn't read clock\n");
1244 return -EIO;
1245 }
1246 memcpy(itv->last_dec_timing, data, sizeof(itv->last_dec_timing));
1247 set_bit(IVTV_F_I_VALID_DEC_TIMINGS, &itv->i_flags);
1248 *frame = data[0];
1249 }
1250 break;
1251 }
1252
1253 case VIDEO_PLAY: {
1254 struct video_command vc;
1255
1256 IVTV_DEBUG_IOCTL("VIDEO_PLAY\n");
1257 memset(&vc, 0, sizeof(vc));
1258 vc.cmd = VIDEO_CMD_PLAY;
1259 return ivtv_video_command(itv, id, &vc, 0);
1260 }
1261
1262 case VIDEO_STOP: {
1263 struct video_command vc;
1264
1265 IVTV_DEBUG_IOCTL("VIDEO_STOP\n");
1266 memset(&vc, 0, sizeof(vc));
1267 vc.cmd = VIDEO_CMD_STOP;
1268 vc.flags = VIDEO_CMD_STOP_TO_BLACK | VIDEO_CMD_STOP_IMMEDIATELY;
1269 return ivtv_video_command(itv, id, &vc, 0);
1270 }
1271
1272 case VIDEO_FREEZE: {
1273 struct video_command vc;
1274
1275 IVTV_DEBUG_IOCTL("VIDEO_FREEZE\n");
1276 memset(&vc, 0, sizeof(vc));
1277 vc.cmd = VIDEO_CMD_FREEZE;
1278 return ivtv_video_command(itv, id, &vc, 0);
1279 }
1280
1281 case VIDEO_CONTINUE: {
1282 struct video_command vc;
1283
1284 IVTV_DEBUG_IOCTL("VIDEO_CONTINUE\n");
1285 memset(&vc, 0, sizeof(vc));
1286 vc.cmd = VIDEO_CMD_CONTINUE;
1287 return ivtv_video_command(itv, id, &vc, 0);
1288 }
1289
1290 case VIDEO_COMMAND:
1291 case VIDEO_TRY_COMMAND: {
1292 struct video_command *vc = arg;
1293 int try = (cmd == VIDEO_TRY_COMMAND);
1294
1295 if (try)
1296 IVTV_DEBUG_IOCTL("VIDEO_TRY_COMMAND\n");
1297 else
1298 IVTV_DEBUG_IOCTL("VIDEO_COMMAND\n");
1299 return ivtv_video_command(itv, id, vc, try);
1300 }
1301
1302 case VIDEO_GET_EVENT: {
1303 struct video_event *ev = arg;
1304 DEFINE_WAIT(wait);
1305
1306 IVTV_DEBUG_IOCTL("VIDEO_GET_EVENT\n");
1307 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1308 return -EINVAL;
1309 memset(ev, 0, sizeof(*ev));
1310 set_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1311
1312 while (1) {
1313 if (test_and_clear_bit(IVTV_F_I_EV_DEC_STOPPED, &itv->i_flags))
1314 ev->type = VIDEO_EVENT_DECODER_STOPPED;
1315 else if (test_and_clear_bit(IVTV_F_I_EV_VSYNC, &itv->i_flags)) {
1316 ev->type = VIDEO_EVENT_VSYNC;
1317 ev->timestamp = test_bit(IVTV_F_I_EV_VSYNC_FIELD, &itv->i_flags) ?
1318 1 : 0;
1319 clear_bit(IVTV_F_I_EV_VSYNC_ENABLED, &itv->i_flags);
1320 }
1321 if (ev->type)
1322 return 0;
1323 if (nonblocking)
1324 return -EAGAIN;
1325 /* wait for event */
1326 prepare_to_wait(&itv->event_waitq, &wait, TASK_INTERRUPTIBLE);
1327 if ((itv->i_flags & (IVTV_F_I_EV_DEC_STOPPED|IVTV_F_I_EV_VSYNC)) == 0)
1328 schedule();
1329 finish_wait(&itv->event_waitq, &wait);
1330 if (signal_pending(current)) {
1331 /* return if a signal was received */
1332 IVTV_DEBUG_INFO("User stopped wait for event\n");
1333 return -EINTR;
1334 }
1335 }
1336 break;
1337 }
1338
1339 case VIDIOC_G_ENC_INDEX: {
1340 struct v4l2_enc_idx *idx = arg;
1341 int i;
1342
1343 IVTV_DEBUG_IOCTL("VIDIOC_G_ENC_INDEX\n");
1344 idx->entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1345 IVTV_MAX_PGM_INDEX;
1346 if (idx->entries > V4L2_ENC_IDX_ENTRIES)
1347 idx->entries = V4L2_ENC_IDX_ENTRIES;
1348 for (i = 0; i < idx->entries; i++) {
1349 idx->entry[i] = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1350 }
1351 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1352 break;
1353 }
1354
1355 case VIDIOC_ENCODER_CMD:
1356 case VIDIOC_TRY_ENCODER_CMD: {
1357 struct v4l2_encoder_cmd *enc = arg;
1358 int try = cmd == VIDIOC_TRY_ENCODER_CMD;
1359
1360 if (try)
1361 IVTV_DEBUG_IOCTL("VIDIOC_TRY_ENCODER_CMD\n");
1362 else
1363 IVTV_DEBUG_IOCTL("VIDIOC_ENCODER_CMD\n");
1364 switch (enc->cmd) {
1365 case V4L2_ENC_CMD_START:
1366 return ivtv_start_capture(id);
1367
1368 case V4L2_ENC_CMD_STOP:
1369 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1370 return 0;
1371
1372 case V4L2_ENC_CMD_PAUSE:
1373 if (!atomic_read(&itv->capturing))
1374 return -EPERM;
1375 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1376 return 0;
1377 ivtv_mute(itv);
1378 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1379 break;
1380
1381 case V4L2_ENC_CMD_RESUME:
1382 if (!atomic_read(&itv->capturing))
1383 return -EPERM;
1384 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1385 return 0;
1386 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1387 ivtv_unmute(itv);
1388 break;
1389 }
1390 break;
1391 }
1392
1393 case VIDIOC_G_FBUF: {
1394 struct v4l2_framebuffer *fb = arg;
1395
1396 IVTV_DEBUG_IOCTL("VIDIOC_G_FBUF\n");
1397 memset(fb, 0, sizeof(*fb));
1398 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1399 break;
1400 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1401 V4L2_FBUF_CAP_LOCAL_ALPHA | V4L2_FBUF_CAP_GLOBAL_ALPHA;
1402 fb->fmt.pixelformat = itv->osd_pixelformat;
1403 fb->fmt.width = itv->osd_rect.width;
1404 fb->fmt.height = itv->osd_rect.height;
1405 fb->fmt.left = itv->osd_rect.left;
1406 fb->fmt.top = itv->osd_rect.top;
1407 fb->base = (void *)itv->osd_video_pbase;
1408 if (itv->osd_global_alpha_state)
1409 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1410 if (itv->osd_local_alpha_state)
1411 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1412 if (itv->osd_color_key_state)
1413 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1414 break;
1415 }
1416
1417 case VIDIOC_S_FBUF: {
1418 struct v4l2_framebuffer *fb = arg;
1419
1420 IVTV_DEBUG_IOCTL("VIDIOC_S_FBUF\n");
1421 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1422 break;
1423 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1424 itv->osd_local_alpha_state = (fb->flags & V4L2_FBUF_FLAG_LOCAL_ALPHA) != 0;
1425 itv->osd_color_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1426 break;
1427 }
1428
1429 default:
1430 return -EINVAL;
1431 }
1432 return 0;
1433}
1434
1435static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
1436 unsigned int cmd, void *arg)
1437{
1438 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1439 struct ivtv *itv = id->itv;
1440
1441 IVTV_DEBUG_IOCTL("v4l2 ioctl 0x%08x\n", cmd);
1442
1443 switch (cmd) {
1444 case VIDIOC_DBG_G_REGISTER:
1445 case VIDIOC_DBG_S_REGISTER:
1446 case VIDIOC_G_CHIP_IDENT:
1447 case VIDIOC_INT_S_AUDIO_ROUTING:
1448 case VIDIOC_INT_RESET:
1449 return ivtv_internal_ioctls(filp, cmd, arg);
1450
1451 case VIDIOC_QUERYCAP:
1452 case VIDIOC_ENUMINPUT:
1453 case VIDIOC_G_INPUT:
1454 case VIDIOC_S_INPUT:
1455 case VIDIOC_ENUMOUTPUT:
1456 case VIDIOC_G_OUTPUT:
1457 case VIDIOC_S_OUTPUT:
1458 case VIDIOC_G_FMT:
1459 case VIDIOC_S_FMT:
1460 case VIDIOC_TRY_FMT:
1461 case VIDIOC_ENUM_FMT:
1462 case VIDIOC_G_CROP:
1463 case VIDIOC_S_CROP:
1464 case VIDIOC_G_FREQUENCY:
1465 case VIDIOC_S_FREQUENCY:
1466 case VIDIOC_ENUMSTD:
1467 case VIDIOC_G_STD:
1468 case VIDIOC_S_STD:
1469 case VIDIOC_S_TUNER:
1470 case VIDIOC_G_TUNER:
1471 case VIDIOC_ENUMAUDIO:
1472 case VIDIOC_S_AUDIO:
1473 case VIDIOC_G_AUDIO:
1474 case VIDIOC_ENUMAUDOUT:
1475 case VIDIOC_S_AUDOUT:
1476 case VIDIOC_G_AUDOUT:
1477 case VIDIOC_G_SLICED_VBI_CAP:
1478 case VIDIOC_LOG_STATUS:
1479 return ivtv_v4l2_ioctls(itv, filp, cmd, arg);
1480
1481 case VIDIOC_QUERYMENU:
1482 case VIDIOC_QUERYCTRL:
1483 case VIDIOC_S_CTRL:
1484 case VIDIOC_G_CTRL:
1485 case VIDIOC_S_EXT_CTRLS:
1486 case VIDIOC_G_EXT_CTRLS:
1487 case VIDIOC_TRY_EXT_CTRLS:
1488 return ivtv_control_ioctls(itv, cmd, arg);
1489
1490 case IVTV_IOC_DMA_FRAME:
1491 case VIDEO_GET_PTS:
1492 case VIDEO_GET_FRAME_COUNT:
1493 case VIDEO_GET_EVENT:
1494 case VIDEO_PLAY:
1495 case VIDEO_STOP:
1496 case VIDEO_FREEZE:
1497 case VIDEO_CONTINUE:
1498 case VIDEO_COMMAND:
1499 case VIDEO_TRY_COMMAND:
1500 case VIDIOC_G_ENC_INDEX:
1501 case VIDIOC_ENCODER_CMD:
1502 case VIDIOC_TRY_ENCODER_CMD:
1503 case VIDIOC_G_FBUF:
1504 case VIDIOC_S_FBUF:
1505 return ivtv_ivtv_ioctls(filp, cmd, arg);
1506
1507 case 0x00005401: /* Handle isatty() calls */
1508 return -EINVAL;
1509 default:
1510 return v4l_compat_translate_ioctl(inode, filp, cmd, arg,
1511 ivtv_v4l2_do_ioctl);
1512 }
1513 return 0;
1514}
1515
1516int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1517 unsigned long arg)
1518{
1519 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1520 struct ivtv *itv = id->itv;
1521
1522 /* Filter dvb ioctls that cannot be handled by video_usercopy */
1523 switch (cmd) {
1524 case VIDEO_SELECT_SOURCE:
1525 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
1526 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
1527 return -EINVAL;
1528 return ivtv_passthrough_mode(itv, arg == VIDEO_SOURCE_DEMUX);
1529
1530 case AUDIO_SET_MUTE:
1531 IVTV_DEBUG_IOCTL("AUDIO_SET_MUTE\n");
1532 itv->speed_mute_audio = arg;
1533 return 0;
1534
1535 case AUDIO_CHANNEL_SELECT:
1536 IVTV_DEBUG_IOCTL("AUDIO_CHANNEL_SELECT\n");
1537 if (arg > AUDIO_STEREO_SWAPPED)
1538 return -EINVAL;
1539 itv->audio_stereo_mode = arg;
1540 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1541 return 0;
1542
1543 case AUDIO_BILINGUAL_CHANNEL_SELECT:
1544 IVTV_DEBUG_IOCTL("AUDIO_BILINGUAL_CHANNEL_SELECT\n");
1545 if (arg > AUDIO_STEREO_SWAPPED)
1546 return -EINVAL;
1547 itv->audio_bilingual_mode = arg;
1548 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1549 return 0;
1550
1551 default:
1552 break;
1553 }
1554 return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl);
1555}