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