aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2008-05-29 15:43:54 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-07-20 06:10:31 -0400
commit3f038d80039f60e4340eaedd13369e0d2c758b80 (patch)
tree994cafb1cb1900b97155b2d3233814632c856adc /drivers
parent539a7555b31e65e66fb84c881d07d2bf18c974d0 (diff)
V4L/DVB (8079): ivtv: Convert to video_ioctl2.
Based on an initial conversion patch from Douglas Landgraf. Signed-off-by: Douglas Schilling Landgraf <dougsland@gmail.com> Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.c196
-rw-r--r--drivers/media/video/ivtv/ivtv-controls.h8
-rw-r--r--drivers/media/video/ivtv/ivtv-driver.c10
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.c2089
-rw-r--r--drivers/media/video/ivtv/ivtv-ioctl.h9
-rw-r--r--drivers/media/video/ivtv/ivtv-streams.c3
6 files changed, 1228 insertions, 1087 deletions
diff --git a/drivers/media/video/ivtv/ivtv-controls.c b/drivers/media/video/ivtv/ivtv-controls.c
index c7e449f6397b..06723bac99c5 100644
--- a/drivers/media/video/ivtv/ivtv-controls.c
+++ b/drivers/media/video/ivtv/ivtv-controls.c
@@ -47,8 +47,10 @@ static const u32 *ctrl_classes[] = {
47 NULL 47 NULL
48}; 48};
49 49
50static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl) 50
51int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *qctrl)
51{ 52{
53 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
52 const char *name; 54 const char *name;
53 55
54 IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id); 56 IVTV_DEBUG_IOCTL("VIDIOC_QUERYCTRL(%08x)\n", qctrl->id);
@@ -87,17 +89,20 @@ static int ivtv_queryctrl(struct ivtv *itv, struct v4l2_queryctrl *qctrl)
87 return 0; 89 return 0;
88} 90}
89 91
90static int ivtv_querymenu(struct ivtv *itv, struct v4l2_querymenu *qmenu) 92int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *qmenu)
91{ 93{
94 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
92 struct v4l2_queryctrl qctrl; 95 struct v4l2_queryctrl qctrl;
93 96
97 IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n");
94 qctrl.id = qmenu->id; 98 qctrl.id = qmenu->id;
95 ivtv_queryctrl(itv, &qctrl); 99 ivtv_queryctrl(file, fh, &qctrl);
96 return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id)); 100 return v4l2_ctrl_query_menu(qmenu, &qctrl, cx2341x_ctrl_get_menu(qmenu->id));
97} 101}
98 102
99static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) 103int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl)
100{ 104{
105 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
101 s32 v = vctrl->value; 106 s32 v = vctrl->value;
102 107
103 IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v); 108 IVTV_DEBUG_IOCTL("VIDIOC_S_CTRL(%08x, %x)\n", vctrl->id, v);
@@ -125,8 +130,10 @@ static int ivtv_s_ctrl(struct ivtv *itv, struct v4l2_control *vctrl)
125 return 0; 130 return 0;
126} 131}
127 132
128static int ivtv_g_ctrl(struct ivtv *itv, struct v4l2_control *vctrl) 133int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *vctrl)
129{ 134{
135 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
136
130 IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id); 137 IVTV_DEBUG_IOCTL("VIDIOC_G_CTRL(%08x)\n", vctrl->id);
131 138
132 switch (vctrl->id) { 139 switch (vctrl->id) {
@@ -191,119 +198,96 @@ static int ivtv_setup_vbi_fmt(struct ivtv *itv, enum v4l2_mpeg_stream_vbi_fmt fm
191 return 0; 198 return 0;
192} 199}
193 200
194int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg) 201int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
195{ 202{
203 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
196 struct v4l2_control ctrl; 204 struct v4l2_control ctrl;
197 205
198 switch (cmd) { 206 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
199 case VIDIOC_QUERYMENU: 207 int i;
200 IVTV_DEBUG_IOCTL("VIDIOC_QUERYMENU\n"); 208 int err = 0;
201 return ivtv_querymenu(itv, arg); 209
202 210 for (i = 0; i < c->count; i++) {
203 case VIDIOC_QUERYCTRL: 211 ctrl.id = c->controls[i].id;
204 return ivtv_queryctrl(itv, arg); 212 ctrl.value = c->controls[i].value;
205 213 err = ivtv_g_ctrl(file, fh, &ctrl);
206 case VIDIOC_S_CTRL: 214 c->controls[i].value = ctrl.value;
207 return ivtv_s_ctrl(itv, arg); 215 if (err) {
208 216 c->error_idx = i;
209 case VIDIOC_G_CTRL: 217 break;
210 return ivtv_g_ctrl(itv, arg);
211
212 case VIDIOC_S_EXT_CTRLS:
213 {
214 struct v4l2_ext_controls *c = arg;
215
216 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
217 int i;
218 int err = 0;
219
220 for (i = 0; i < c->count; i++) {
221 ctrl.id = c->controls[i].id;
222 ctrl.value = c->controls[i].value;
223 err = ivtv_s_ctrl(itv, &ctrl);
224 c->controls[i].value = ctrl.value;
225 if (err) {
226 c->error_idx = i;
227 break;
228 }
229 }
230 return err;
231 }
232 IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
233 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
234 static u32 freqs[3] = { 44100, 48000, 32000 };
235 struct cx2341x_mpeg_params p = itv->params;
236 int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), arg, cmd);
237 unsigned idx;
238
239 if (err)
240 return err;
241
242 if (p.video_encoding != itv->params.video_encoding) {
243 int is_mpeg1 = p.video_encoding ==
244 V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
245 struct v4l2_format fmt;
246
247 /* fix videodecoder resolution */
248 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
249 fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1);
250 fmt.fmt.pix.height = itv->params.height;
251 itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt);
252 }
253 err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
254 if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt) {
255 err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt);
256 } 218 }
257 itv->params = p;
258 itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
259 idx = p.audio_properties & 0x03;
260 /* The audio clock of the digitizer must match the codec sample
261 rate otherwise you get some very strange effects. */
262 if (idx < sizeof(freqs))
263 ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]);
264 return err;
265 } 219 }
266 return -EINVAL; 220 return err;
267 } 221 }
222 IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n");
223 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
224 return cx2341x_ext_ctrls(&itv->params, 0, c, VIDIOC_G_EXT_CTRLS);
225 return -EINVAL;
226}
268 227
269 case VIDIOC_G_EXT_CTRLS: 228int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
270 { 229{
271 struct v4l2_ext_controls *c = arg; 230 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
272 231 struct v4l2_control ctrl;
273 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) { 232
274 int i; 233 if (c->ctrl_class == V4L2_CTRL_CLASS_USER) {
275 int err = 0; 234 int i;
276 235 int err = 0;
277 for (i = 0; i < c->count; i++) { 236
278 ctrl.id = c->controls[i].id; 237 for (i = 0; i < c->count; i++) {
279 ctrl.value = c->controls[i].value; 238 ctrl.id = c->controls[i].id;
280 err = ivtv_g_ctrl(itv, &ctrl); 239 ctrl.value = c->controls[i].value;
281 c->controls[i].value = ctrl.value; 240 err = ivtv_s_ctrl(file, fh, &ctrl);
282 if (err) { 241 c->controls[i].value = ctrl.value;
283 c->error_idx = i; 242 if (err) {
284 break; 243 c->error_idx = i;
285 } 244 break;
286 } 245 }
287 return err;
288 } 246 }
289 IVTV_DEBUG_IOCTL("VIDIOC_G_EXT_CTRLS\n"); 247 return err;
290 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
291 return cx2341x_ext_ctrls(&itv->params, 0, arg, cmd);
292 return -EINVAL;
293 } 248 }
249 IVTV_DEBUG_IOCTL("VIDIOC_S_EXT_CTRLS\n");
250 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) {
251 static u32 freqs[3] = { 44100, 48000, 32000 };
252 struct cx2341x_mpeg_params p = itv->params;
253 int err = cx2341x_ext_ctrls(&p, atomic_read(&itv->capturing), c, VIDIOC_S_EXT_CTRLS);
254 unsigned idx;
255
256 if (err)
257 return err;
294 258
295 case VIDIOC_TRY_EXT_CTRLS: 259 if (p.video_encoding != itv->params.video_encoding) {
296 { 260 int is_mpeg1 = p.video_encoding ==
297 struct v4l2_ext_controls *c = arg; 261 V4L2_MPEG_VIDEO_ENCODING_MPEG_1;
262 struct v4l2_format fmt;
298 263
299 IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n"); 264 /* fix videodecoder resolution */
300 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG) 265 fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
301 return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), arg, cmd); 266 fmt.fmt.pix.width = itv->params.width / (is_mpeg1 ? 2 : 1);
302 return -EINVAL; 267 fmt.fmt.pix.height = itv->params.height;
268 itv->video_dec_func(itv, VIDIOC_S_FMT, &fmt);
269 }
270 err = cx2341x_update(itv, ivtv_api_func, &itv->params, &p);
271 if (!err && itv->params.stream_vbi_fmt != p.stream_vbi_fmt)
272 err = ivtv_setup_vbi_fmt(itv, p.stream_vbi_fmt);
273 itv->params = p;
274 itv->dualwatch_stereo_mode = p.audio_properties & 0x0300;
275 idx = p.audio_properties & 0x03;
276 /* The audio clock of the digitizer must match the codec sample
277 rate otherwise you get some very strange effects. */
278 if (idx < sizeof(freqs))
279 ivtv_call_i2c_clients(itv, VIDIOC_INT_AUDIO_CLOCK_FREQ, &freqs[idx]);
280 return err;
303 } 281 }
282 return -EINVAL;
283}
304 284
305 default: 285int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *c)
306 return -EINVAL; 286{
307 } 287 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
308 return 0; 288
289 IVTV_DEBUG_IOCTL("VIDIOC_TRY_EXT_CTRLS\n");
290 if (c->ctrl_class == V4L2_CTRL_CLASS_MPEG)
291 return cx2341x_ext_ctrls(&itv->params, atomic_read(&itv->capturing), c, VIDIOC_TRY_EXT_CTRLS);
292 return -EINVAL;
309} 293}
diff --git a/drivers/media/video/ivtv/ivtv-controls.h b/drivers/media/video/ivtv/ivtv-controls.h
index bb8a6a5ed2bc..304204be6b0d 100644
--- a/drivers/media/video/ivtv/ivtv-controls.h
+++ b/drivers/media/video/ivtv/ivtv-controls.h
@@ -21,6 +21,12 @@
21#ifndef IVTV_CONTROLS_H 21#ifndef IVTV_CONTROLS_H
22#define IVTV_CONTROLS_H 22#define IVTV_CONTROLS_H
23 23
24int ivtv_control_ioctls(struct ivtv *itv, unsigned int cmd, void *arg); 24int ivtv_queryctrl(struct file *file, void *fh, struct v4l2_queryctrl *a);
25int ivtv_g_ctrl(struct file *file, void *fh, struct v4l2_control *a);
26int ivtv_s_ctrl(struct file *file, void *fh, struct v4l2_control *a);
27int ivtv_g_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
28int ivtv_s_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
29int ivtv_try_ext_ctrls(struct file *file, void *fh, struct v4l2_ext_controls *a);
30int ivtv_querymenu(struct file *file, void *fh, struct v4l2_querymenu *a);
25 31
26#endif 32#endif
diff --git a/drivers/media/video/ivtv/ivtv-driver.c b/drivers/media/video/ivtv/ivtv-driver.c
index 323dd68fa1c6..9e6a64903875 100644
--- a/drivers/media/video/ivtv/ivtv-driver.c
+++ b/drivers/media/video/ivtv/ivtv-driver.c
@@ -1262,9 +1262,13 @@ err:
1262int ivtv_init_on_first_open(struct ivtv *itv) 1262int ivtv_init_on_first_open(struct ivtv *itv)
1263{ 1263{
1264 struct v4l2_frequency vf; 1264 struct v4l2_frequency vf;
1265 /* Needed to call ioctls later */
1266 struct ivtv_open_id fh;
1265 int fw_retry_count = 3; 1267 int fw_retry_count = 3;
1266 int video_input; 1268 int video_input;
1267 1269
1270 fh.itv = itv;
1271
1268 if (test_bit(IVTV_F_I_FAILED, &itv->i_flags)) 1272 if (test_bit(IVTV_F_I_FAILED, &itv->i_flags))
1269 return -ENXIO; 1273 return -ENXIO;
1270 1274
@@ -1312,18 +1316,18 @@ int ivtv_init_on_first_open(struct ivtv *itv)
1312 1316
1313 video_input = itv->active_input; 1317 video_input = itv->active_input;
1314 itv->active_input++; /* Force update of input */ 1318 itv->active_input++; /* Force update of input */
1315 ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_INPUT, &video_input); 1319 ivtv_s_input(NULL, &fh, video_input);
1316 1320
1317 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code 1321 /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
1318 in one place. */ 1322 in one place. */
1319 itv->std++; /* Force full standard initialization */ 1323 itv->std++; /* Force full standard initialization */
1320 itv->std_out = itv->std; 1324 itv->std_out = itv->std;
1321 ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_FREQUENCY, &vf); 1325 ivtv_s_frequency(NULL, &fh, &vf);
1322 1326
1323 if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) { 1327 if (itv->card->v4l2_capabilities & V4L2_CAP_VIDEO_OUTPUT) {
1324 ivtv_init_mpeg_decoder(itv); 1328 ivtv_init_mpeg_decoder(itv);
1325 } 1329 }
1326 ivtv_v4l2_ioctls(itv, NULL, VIDIOC_S_STD, &itv->tuner_std); 1330 ivtv_s_std(NULL, &fh, &itv->tuner_std);
1327 1331
1328 /* On a cx23416 this seems to be able to enable DMA to the chip? */ 1332 /* On a cx23416 this seems to be able to enable DMA to the chip? */
1329 if (!itv->has_cx23415) 1333 if (!itv->has_cx23415)
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.c b/drivers/media/video/ivtv/ivtv-ioctl.c
index 26cc0f6699fd..49b297e788db 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.c
+++ b/drivers/media/video/ivtv/ivtv-ioctl.c
@@ -373,267 +373,172 @@ static int ivtv_itvc(struct ivtv *itv, unsigned int cmd, void *arg)
373 return 0; 373 return 0;
374} 374}
375 375
376static int ivtv_get_fmt(struct ivtv *itv, int streamtype, struct v4l2_format *fmt) 376static int ivtv_g_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
377{ 377{
378 switch (fmt->type) { 378 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
379 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 379 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
380 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
381 return -EINVAL;
382 fmt->fmt.pix.width = itv->main_rect.width;
383 fmt->fmt.pix.height = itv->main_rect.height;
384 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
385 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
386 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
387 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
388 case IVTV_YUV_MODE_INTERLACED:
389 fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
390 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
391 break;
392 case IVTV_YUV_MODE_PROGRESSIVE:
393 fmt->fmt.pix.field = V4L2_FIELD_NONE;
394 break;
395 default:
396 fmt->fmt.pix.field = V4L2_FIELD_ANY;
397 break;
398 }
399 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
400 fmt->fmt.pix.bytesperline = 720;
401 fmt->fmt.pix.width = itv->yuv_info.v4l2_src_w;
402 fmt->fmt.pix.height = itv->yuv_info.v4l2_src_h;
403 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
404 fmt->fmt.pix.sizeimage =
405 1080 * ((fmt->fmt.pix.height + 31) & ~31);
406 } else if (streamtype == IVTV_ENC_STREAM_TYPE_YUV) {
407 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
408 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
409 fmt->fmt.pix.sizeimage =
410 fmt->fmt.pix.height * fmt->fmt.pix.width +
411 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
412 } else {
413 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
414 fmt->fmt.pix.sizeimage = 128 * 1024;
415 }
416 break;
417
418 case V4L2_BUF_TYPE_VIDEO_CAPTURE:
419 fmt->fmt.pix.width = itv->params.width;
420 fmt->fmt.pix.height = itv->params.height;
421 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
422 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
423 if (streamtype == IVTV_ENC_STREAM_TYPE_YUV ||
424 streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
425 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
426 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
427 fmt->fmt.pix.sizeimage =
428 fmt->fmt.pix.height * fmt->fmt.pix.width +
429 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
430 } else {
431 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
432 fmt->fmt.pix.sizeimage = 128 * 1024;
433 }
434 break;
435
436 case V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY:
437 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
438 return -EINVAL;
439 fmt->fmt.win.chromakey = itv->osd_chroma_key;
440 fmt->fmt.win.global_alpha = itv->osd_global_alpha;
441 break;
442
443 case V4L2_BUF_TYPE_VBI_CAPTURE:
444 fmt->fmt.vbi.sampling_rate = 27000000;
445 fmt->fmt.vbi.offset = 248;
446 fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4;
447 fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
448 fmt->fmt.vbi.start[0] = itv->vbi.start[0];
449 fmt->fmt.vbi.start[1] = itv->vbi.start[1];
450 fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count;
451 break;
452
453 case V4L2_BUF_TYPE_SLICED_VBI_OUTPUT:
454 {
455 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
456 380
457 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) 381 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
458 return -EINVAL; 382 return -EINVAL;
459 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; 383 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
460 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved)); 384 if (itv->is_60hz) {
461 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines)); 385 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
462 if (itv->is_60hz) { 386 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
463 vbifmt->service_lines[0][21] = V4L2_SLICED_CAPTION_525; 387 } else {
464 vbifmt->service_lines[1][21] = V4L2_SLICED_CAPTION_525; 388 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
465 } else { 389 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
466 vbifmt->service_lines[0][23] = V4L2_SLICED_WSS_625;
467 vbifmt->service_lines[0][16] = V4L2_SLICED_VPS;
468 }
469 vbifmt->service_set = ivtv_get_service_set(vbifmt);
470 break;
471 } 390 }
391 vbifmt->service_set = ivtv_get_service_set(vbifmt);
392 return 0;
393}
472 394
473 case V4L2_BUF_TYPE_SLICED_VBI_CAPTURE: 395static int ivtv_g_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
474 { 396{
475 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 397 struct ivtv_open_id *id = fh;
476 398 struct ivtv *itv = id->itv;
477 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
478 memset(vbifmt->reserved, 0, sizeof(vbifmt->reserved));
479 memset(vbifmt->service_lines, 0, sizeof(vbifmt->service_lines));
480
481 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) {
482 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
483 V4L2_SLICED_VBI_525;
484 ivtv_expand_service_set(vbifmt, itv->is_50hz);
485 break;
486 }
487 399
488 itv->video_dec_func(itv, VIDIOC_G_FMT, fmt); 400 fmt->fmt.pix.width = itv->params.width;
489 vbifmt->service_set = ivtv_get_service_set(vbifmt); 401 fmt->fmt.pix.height = itv->params.height;
490 break; 402 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
491 } 403 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
492 case V4L2_BUF_TYPE_VBI_OUTPUT: 404 if (id->type == IVTV_ENC_STREAM_TYPE_YUV ||
493 case V4L2_BUF_TYPE_VIDEO_OVERLAY: 405 id->type == IVTV_DEC_STREAM_TYPE_YUV) {
494 default: 406 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
495 return -EINVAL; 407 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
408 fmt->fmt.pix.sizeimage =
409 fmt->fmt.pix.height * fmt->fmt.pix.width +
410 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
411 } else {
412 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
413 fmt->fmt.pix.sizeimage = 128 * 1024;
496 } 414 }
497 return 0; 415 return 0;
498} 416}
499 417
500static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype, 418static int ivtv_g_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
501 struct v4l2_format *fmt, int set_fmt)
502{ 419{
503 struct yuv_playback_info *yi = &itv->yuv_info; 420 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
504 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced; 421
505 u16 set; 422 fmt->fmt.vbi.sampling_rate = 27000000;
423 fmt->fmt.vbi.offset = 248;
424 fmt->fmt.vbi.samples_per_line = itv->vbi.raw_decoder_line_size - 4;
425 fmt->fmt.vbi.sample_format = V4L2_PIX_FMT_GREY;
426 fmt->fmt.vbi.start[0] = itv->vbi.start[0];
427 fmt->fmt.vbi.start[1] = itv->vbi.start[1];
428 fmt->fmt.vbi.count[0] = fmt->fmt.vbi.count[1] = itv->vbi.count;
429 return 0;
430}
506 431
507 if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT) { 432static int ivtv_g_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
508 struct v4l2_rect r; 433{
509 int field; 434 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
435 struct ivtv_open_id *id = fh;
436 struct ivtv *itv = id->itv;
510 437
511 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 438 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
512 return -EINVAL;
513 field = fmt->fmt.pix.field;
514 r.top = 0;
515 r.left = 0;
516 r.width = fmt->fmt.pix.width;
517 r.height = fmt->fmt.pix.height;
518 ivtv_get_fmt(itv, streamtype, fmt);
519 fmt->fmt.pix.width = r.width;
520 fmt->fmt.pix.height = r.height;
521 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
522 fmt->fmt.pix.field = field;
523 if (fmt->fmt.pix.width < 2)
524 fmt->fmt.pix.width = 2;
525 if (fmt->fmt.pix.width > 720)
526 fmt->fmt.pix.width = 720;
527 if (fmt->fmt.pix.height < 2)
528 fmt->fmt.pix.height = 2;
529 if (fmt->fmt.pix.height > 576)
530 fmt->fmt.pix.height = 576;
531 }
532 if (set_fmt && streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
533 /* Return now if we already have some frame data */
534 if (yi->stream_size)
535 return -EBUSY;
536 439
537 yi->v4l2_src_w = r.width; 440 if (id->type == IVTV_DEC_STREAM_TYPE_VBI) {
538 yi->v4l2_src_h = r.height; 441 vbifmt->service_set = itv->is_50hz ? V4L2_SLICED_VBI_625 :
442 V4L2_SLICED_VBI_525;
443 ivtv_expand_service_set(vbifmt, itv->is_50hz);
444 return 0;
445 }
539 446
540 switch (field) { 447 itv->video_dec_func(itv, VIDIOC_G_FMT, fmt);
541 case V4L2_FIELD_NONE: 448 vbifmt->service_set = ivtv_get_service_set(vbifmt);
542 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE; 449 return 0;
543 break; 450}
544 case V4L2_FIELD_ANY:
545 yi->lace_mode = IVTV_YUV_MODE_AUTO;
546 break;
547 case V4L2_FIELD_INTERLACED_BT:
548 yi->lace_mode =
549 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
550 break;
551 case V4L2_FIELD_INTERLACED_TB:
552 default:
553 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
554 break;
555 }
556 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
557 451
558 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags)) 452static int ivtv_g_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
559 itv->dma_data_req_size = 453{
560 1080 * ((yi->v4l2_src_h + 31) & ~31); 454 struct ivtv_open_id *id = fh;
455 struct ivtv *itv = id->itv;
561 456
562 /* Force update of yuv registers */ 457 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
563 yi->yuv_forced_update = 1; 458 return -EINVAL;
564 return 0; 459 fmt->fmt.pix.width = itv->main_rect.width;
460 fmt->fmt.pix.height = itv->main_rect.height;
461 fmt->fmt.pix.colorspace = V4L2_COLORSPACE_SMPTE170M;
462 fmt->fmt.pix.field = V4L2_FIELD_INTERLACED;
463 if (id->type == IVTV_DEC_STREAM_TYPE_YUV) {
464 switch (itv->yuv_info.lace_mode & IVTV_YUV_MODE_MASK) {
465 case IVTV_YUV_MODE_INTERLACED:
466 fmt->fmt.pix.field = (itv->yuv_info.lace_mode & IVTV_YUV_SYNC_MASK) ?
467 V4L2_FIELD_INTERLACED_BT : V4L2_FIELD_INTERLACED_TB;
468 break;
469 case IVTV_YUV_MODE_PROGRESSIVE:
470 fmt->fmt.pix.field = V4L2_FIELD_NONE;
471 break;
472 default:
473 fmt->fmt.pix.field = V4L2_FIELD_ANY;
474 break;
565 } 475 }
566 return 0; 476 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
477 fmt->fmt.pix.bytesperline = 720;
478 fmt->fmt.pix.width = itv->yuv_info.v4l2_src_w;
479 fmt->fmt.pix.height = itv->yuv_info.v4l2_src_h;
480 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
481 fmt->fmt.pix.sizeimage =
482 1080 * ((fmt->fmt.pix.height + 31) & ~31);
483 } else if (id->type == IVTV_ENC_STREAM_TYPE_YUV) {
484 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_HM12;
485 /* YUV size is (Y=(h*w) + UV=(h*(w/2))) */
486 fmt->fmt.pix.sizeimage =
487 fmt->fmt.pix.height * fmt->fmt.pix.width +
488 fmt->fmt.pix.height * (fmt->fmt.pix.width / 2);
489 } else {
490 fmt->fmt.pix.pixelformat = V4L2_PIX_FMT_MPEG;
491 fmt->fmt.pix.sizeimage = 128 * 1024;
567 } 492 }
493 return 0;
494}
568 495
569 if (fmt->type == V4L2_BUF_TYPE_VIDEO_OUTPUT_OVERLAY) { 496static int ivtv_g_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
570 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 497{
571 return -EINVAL; 498 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
572 if (set_fmt) {
573 itv->osd_chroma_key = fmt->fmt.win.chromakey;
574 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
575 ivtv_set_osd_alpha(itv);
576 }
577 return 0;
578 }
579 499
580 /* set window size */ 500 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
581 if (fmt->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 501 return -EINVAL;
582 struct cx2341x_mpeg_params *p = &itv->params; 502 fmt->fmt.win.chromakey = itv->osd_chroma_key;
583 int w = fmt->fmt.pix.width; 503 fmt->fmt.win.global_alpha = itv->osd_global_alpha;
584 int h = fmt->fmt.pix.height; 504 return 0;
585 505}
586 if (w > 720) w = 720;
587 else if (w < 1) w = 1;
588 if (h > (itv->is_50hz ? 576 : 480)) h = (itv->is_50hz ? 576 : 480);
589 else if (h < 2) h = 2;
590 ivtv_get_fmt(itv, streamtype, fmt);
591 fmt->fmt.pix.width = w;
592 fmt->fmt.pix.height = h;
593
594 if (!set_fmt || (p->width == w && p->height == h))
595 return 0;
596 if (atomic_read(&itv->capturing) > 0)
597 return -EBUSY;
598 506
599 p->width = w; 507static int ivtv_try_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
600 p->height = h; 508{
601 if (w != 720 || h != (itv->is_50hz ? 576 : 480)) 509 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
602 p->video_temporal_filter = 0; 510}
603 else
604 p->video_temporal_filter = 8;
605 if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
606 fmt->fmt.pix.width /= 2;
607 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
608 return ivtv_get_fmt(itv, streamtype, fmt);
609 }
610 511
611 /* set raw VBI format */ 512static int ivtv_try_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
612 if (fmt->type == V4L2_BUF_TYPE_VBI_CAPTURE) { 513{
613 if (set_fmt && atomic_read(&itv->capturing) > 0) { 514 struct ivtv_open_id *id = fh;
614 return -EBUSY; 515 struct ivtv *itv = id->itv;
615 } 516 int w = fmt->fmt.pix.width;
616 if (set_fmt) { 517 int h = fmt->fmt.pix.height;
617 itv->vbi.sliced_in->service_set = 0; 518
618 itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in); 519 w = min(w, 720);
619 } 520 w = max(w, 1);
620 return ivtv_get_fmt(itv, streamtype, fmt); 521 h = min(h, itv->is_50hz ? 576 : 480);
621 } 522 h = max(h, 2);
523 ivtv_g_fmt_vid_cap(file, fh, fmt);
524 fmt->fmt.pix.width = w;
525 fmt->fmt.pix.height = h;
526 return 0;
527}
622 528
623 /* set sliced VBI output 529static int ivtv_try_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
624 In principle the user could request that only certain 530{
625 VBI types are output and that the others are ignored. 531 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
626 I.e., suppress CC in the even fields or only output 532}
627 WSS and no VPS. Currently though there is no choice. */
628 if (fmt->type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT)
629 return ivtv_get_fmt(itv, streamtype, fmt);
630 533
631 /* any else but sliced VBI capture is an error */ 534static int ivtv_try_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
632 if (fmt->type != V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) 535{
633 return -EINVAL; 536 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
537 struct ivtv_open_id *id = fh;
538 struct ivtv *itv = id->itv;
634 539
635 if (streamtype == IVTV_DEC_STREAM_TYPE_VBI) 540 if (id->type == IVTV_DEC_STREAM_TYPE_VBI)
636 return ivtv_get_fmt(itv, streamtype, fmt); 541 return ivtv_g_fmt_sliced_vbi_cap(file, fh, fmt);
637 542
638 /* set sliced VBI capture format */ 543 /* set sliced VBI capture format */
639 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36; 544 vbifmt->io_size = sizeof(struct v4l2_sliced_vbi_data) * 36;
@@ -641,777 +546,997 @@ static int ivtv_try_or_set_fmt(struct ivtv *itv, int streamtype,
641 546
642 if (vbifmt->service_set) 547 if (vbifmt->service_set)
643 ivtv_expand_service_set(vbifmt, itv->is_50hz); 548 ivtv_expand_service_set(vbifmt, itv->is_50hz);
644 set = check_service_set(vbifmt, itv->is_50hz); 549 check_service_set(vbifmt, itv->is_50hz);
645 vbifmt->service_set = ivtv_get_service_set(vbifmt); 550 vbifmt->service_set = ivtv_get_service_set(vbifmt);
551 return 0;
552}
553
554static int ivtv_try_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
555{
556 struct ivtv_open_id *id = fh;
557 s32 w, h;
558 int field;
559 int ret;
560
561 w = fmt->fmt.pix.width;
562 h = fmt->fmt.pix.height;
563 field = fmt->fmt.pix.field;
564 ret = ivtv_g_fmt_vid_out(file, fh, fmt);
565 fmt->fmt.pix.width = w;
566 fmt->fmt.pix.height = h;
567 if (!ret && id->type == IVTV_DEC_STREAM_TYPE_YUV) {
568 fmt->fmt.pix.field = field;
569 if (fmt->fmt.pix.width < 2)
570 fmt->fmt.pix.width = 2;
571 if (fmt->fmt.pix.width > 720)
572 fmt->fmt.pix.width = 720;
573 if (fmt->fmt.pix.height < 2)
574 fmt->fmt.pix.height = 2;
575 if (fmt->fmt.pix.height > 576)
576 fmt->fmt.pix.height = 576;
577 }
578 return ret;
579}
646 580
647 if (!set_fmt) 581static int ivtv_try_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
582{
583 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
584
585 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
586 return -EINVAL;
587 return 0;
588}
589
590static int ivtv_s_fmt_sliced_vbi_out(struct file *file, void *fh, struct v4l2_format *fmt)
591{
592 return ivtv_g_fmt_sliced_vbi_out(file, fh, fmt);
593}
594
595static int ivtv_s_fmt_vid_cap(struct file *file, void *fh, struct v4l2_format *fmt)
596{
597 struct ivtv_open_id *id = fh;
598 struct ivtv *itv = id->itv;
599 struct cx2341x_mpeg_params *p = &itv->params;
600 int w = fmt->fmt.pix.width;
601 int h = fmt->fmt.pix.height;
602 int ret = ivtv_try_fmt_vid_cap(file, fh, fmt);
603
604 if (ret)
605 return ret;
606
607 if (p->width == w && p->height == h)
648 return 0; 608 return 0;
649 if (set == 0) 609
610 if (atomic_read(&itv->capturing) > 0)
611 return -EBUSY;
612
613 p->width = w;
614 p->height = h;
615 if (w != 720 || h != (itv->is_50hz ? 576 : 480))
616 p->video_temporal_filter = 0;
617 else
618 p->video_temporal_filter = 8;
619 if (p->video_encoding == V4L2_MPEG_VIDEO_ENCODING_MPEG_1)
620 fmt->fmt.pix.width /= 2;
621 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
622 return ivtv_g_fmt_vid_cap(file, fh, fmt);
623}
624
625static int ivtv_s_fmt_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
626{
627 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
628
629 itv->vbi.sliced_in->service_set = 0;
630 itv->video_dec_func(itv, VIDIOC_S_FMT, &itv->vbi.in);
631 return ivtv_g_fmt_vbi_cap(file, fh, fmt);
632}
633
634static int ivtv_s_fmt_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_format *fmt)
635{
636 struct v4l2_sliced_vbi_format *vbifmt = &fmt->fmt.sliced;
637 struct ivtv_open_id *id = fh;
638 struct ivtv *itv = id->itv;
639 int ret = ivtv_try_fmt_sliced_vbi_cap(file, fh, fmt);
640
641 if (ret || id->type == IVTV_DEC_STREAM_TYPE_VBI)
642 return ret;
643
644 if (check_service_set(vbifmt, itv->is_50hz) == 0)
650 return -EINVAL; 645 return -EINVAL;
651 if (atomic_read(&itv->capturing) > 0) { 646 if (atomic_read(&itv->capturing) > 0)
652 return -EBUSY; 647 return -EBUSY;
653 }
654 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt); 648 itv->video_dec_func(itv, VIDIOC_S_FMT, fmt);
655 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in)); 649 memcpy(itv->vbi.sliced_in, vbifmt, sizeof(*itv->vbi.sliced_in));
656 return 0; 650 return 0;
657} 651}
658 652
659static int ivtv_debug_ioctls(struct file *filp, unsigned int cmd, void *arg) 653static int ivtv_s_fmt_vid_out(struct file *file, void *fh, struct v4l2_format *fmt)
660{ 654{
661 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; 655 struct ivtv_open_id *id = fh;
662 struct ivtv *itv = id->itv; 656 struct ivtv *itv = id->itv;
663 struct v4l2_register *reg = arg; 657 struct yuv_playback_info *yi = &itv->yuv_info;
658 int ret = ivtv_try_fmt_vid_out(file, fh, fmt);
664 659
665 switch (cmd) { 660 if (ret)
666 /* ioctls to allow direct access to the encoder registers for testing */ 661 return ret;
667 case VIDIOC_DBG_G_REGISTER:
668 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
669 return ivtv_itvc(itv, cmd, arg);
670 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
671 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
672 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
673
674 case VIDIOC_DBG_S_REGISTER:
675 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
676 return ivtv_itvc(itv, cmd, arg);
677 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
678 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
679 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
680
681 case VIDIOC_G_CHIP_IDENT: {
682 struct v4l2_chip_ident *chip = arg;
683
684 chip->ident = V4L2_IDENT_NONE;
685 chip->revision = 0;
686 if (reg->match_type == V4L2_CHIP_MATCH_HOST) {
687 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
688 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
689 return 0;
690 }
691 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
692 return ivtv_i2c_id(itv, reg->match_chip, cmd, arg);
693 if (reg->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
694 return ivtv_call_i2c_client(itv, reg->match_chip, cmd, arg);
695 return -EINVAL;
696 }
697 662
698 case VIDIOC_INT_S_AUDIO_ROUTING: { 663 if (id->type != IVTV_DEC_STREAM_TYPE_YUV)
699 struct v4l2_routing *route = arg; 664 return 0;
700 665
701 ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route); 666 /* Return now if we already have some frame data */
702 break; 667 if (yi->stream_size)
703 } 668 return -EBUSY;
704 669
705 case VIDIOC_INT_RESET: { 670 yi->v4l2_src_w = fmt->fmt.pix.width;
706 u32 val = *(u32 *)arg; 671 yi->v4l2_src_h = fmt->fmt.pix.height;
707 672
708 if ((val == 0 && itv->options.newi2c) || (val & 0x01)) { 673 switch (fmt->fmt.pix.field) {
709 ivtv_reset_ir_gpio(itv); 674 case V4L2_FIELD_NONE:
710 } 675 yi->lace_mode = IVTV_YUV_MODE_PROGRESSIVE;
711 if (val & 0x02) {
712 itv->video_dec_func(itv, cmd, NULL);
713 }
714 break; 676 break;
715 } 677 case V4L2_FIELD_ANY:
716 678 yi->lace_mode = IVTV_YUV_MODE_AUTO;
679 break;
680 case V4L2_FIELD_INTERLACED_BT:
681 yi->lace_mode =
682 IVTV_YUV_MODE_INTERLACED|IVTV_YUV_SYNC_ODD;
683 break;
684 case V4L2_FIELD_INTERLACED_TB:
717 default: 685 default:
718 return -EINVAL; 686 yi->lace_mode = IVTV_YUV_MODE_INTERLACED;
687 break;
719 } 688 }
689 yi->lace_sync_field = (yi->lace_mode & IVTV_YUV_SYNC_MASK) == IVTV_YUV_SYNC_EVEN ? 0 : 1;
690
691 if (test_bit(IVTV_F_I_DEC_YUV, &itv->i_flags))
692 itv->dma_data_req_size =
693 1080 * ((yi->v4l2_src_h + 31) & ~31);
694
695 /* Force update of yuv registers */
696 yi->yuv_forced_update = 1;
720 return 0; 697 return 0;
721} 698}
722 699
723int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg) 700static int ivtv_s_fmt_vid_out_overlay(struct file *file, void *fh, struct v4l2_format *fmt)
724{ 701{
725 struct ivtv_open_id *id = NULL; 702 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
726 struct yuv_playback_info *yi = &itv->yuv_info; 703 int ret = ivtv_try_fmt_vid_out_overlay(file, fh, fmt);
727 u32 data[CX2341X_MBOX_MAX_DATA];
728 int streamtype = 0;
729 704
730 if (filp) { 705 if (ret == 0) {
731 id = (struct ivtv_open_id *)filp->private_data; 706 itv->osd_chroma_key = fmt->fmt.win.chromakey;
732 streamtype = id->type; 707 itv->osd_global_alpha = fmt->fmt.win.global_alpha;
708 ivtv_set_osd_alpha(itv);
733 } 709 }
710 return ret;
711}
734 712
735 switch (cmd) { 713static int ivtv_g_chip_ident(struct file *file, void *fh, struct v4l2_chip_ident *chip)
736 case VIDIOC_G_PRIORITY: 714{
737 { 715 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
738 enum v4l2_priority *p = arg;
739 716
740 *p = v4l2_prio_max(&itv->prio); 717 chip->ident = V4L2_IDENT_NONE;
741 break; 718 chip->revision = 0;
719 if (chip->match_type == V4L2_CHIP_MATCH_HOST) {
720 if (v4l2_chip_match_host(chip->match_type, chip->match_chip))
721 chip->ident = itv->has_cx23415 ? V4L2_IDENT_CX23415 : V4L2_IDENT_CX23416;
722 return 0;
742 } 723 }
724 if (chip->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
725 return ivtv_i2c_id(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip);
726 if (chip->match_type == V4L2_CHIP_MATCH_I2C_ADDR)
727 return ivtv_call_i2c_client(itv, chip->match_chip, VIDIOC_G_CHIP_IDENT, chip);
728 return -EINVAL;
729}
743 730
744 case VIDIOC_S_PRIORITY: 731static int ivtv_g_register(struct file *file, void *fh, struct v4l2_register *reg)
745 { 732{
746 enum v4l2_priority *prio = arg; 733 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
747 734
748 return v4l2_prio_change(&itv->prio, &id->prio, *prio); 735 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
749 } 736 return ivtv_itvc(itv, VIDIOC_DBG_G_REGISTER, reg);
737 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
738 return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg);
739 return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_G_REGISTER, reg);
740}
750 741
751 case VIDIOC_QUERYCAP:{ 742static int ivtv_s_register(struct file *file, void *fh, struct v4l2_register *reg)
752 struct v4l2_capability *vcap = arg; 743{
744 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
753 745
754 memset(vcap, 0, sizeof(*vcap)); 746 if (v4l2_chip_match_host(reg->match_type, reg->match_chip))
755 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver)); 747 return ivtv_itvc(itv, VIDIOC_DBG_S_REGISTER, reg);
756 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card)); 748 if (reg->match_type == V4L2_CHIP_MATCH_I2C_DRIVER)
757 strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info)); 749 return ivtv_i2c_id(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg);
758 vcap->version = IVTV_DRIVER_VERSION; /* version */ 750 return ivtv_call_i2c_client(itv, reg->match_chip, VIDIOC_DBG_S_REGISTER, reg);
759 vcap->capabilities = itv->v4l2_cap; /* capabilities */ 751}
760 752
761 /* reserved.. must set to 0! */ 753static int ivtv_g_priority(struct file *file, void *fh, enum v4l2_priority *p)
762 vcap->reserved[0] = vcap->reserved[1] = 754{
763 vcap->reserved[2] = vcap->reserved[3] = 0; 755 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
764 break;
765 }
766 756
767 case VIDIOC_ENUMAUDIO:{ 757 *p = v4l2_prio_max(&itv->prio);
768 struct v4l2_audio *vin = arg;
769 758
770 return ivtv_get_audio_input(itv, vin->index, vin); 759 return 0;
771 } 760}
772 761
773 case VIDIOC_G_AUDIO:{ 762static int ivtv_s_priority(struct file *file, void *fh, enum v4l2_priority prio)
774 struct v4l2_audio *vin = arg; 763{
764 struct ivtv_open_id *id = fh;
765 struct ivtv *itv = id->itv;
775 766
776 vin->index = itv->audio_input; 767 return v4l2_prio_change(&itv->prio, &id->prio, prio);
777 return ivtv_get_audio_input(itv, vin->index, vin); 768}
778 }
779 769
780 case VIDIOC_S_AUDIO:{ 770static int ivtv_querycap(struct file *file, void *fh, struct v4l2_capability *vcap)
781 struct v4l2_audio *vout = arg; 771{
772 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
773
774 memset(vcap, 0, sizeof(*vcap));
775 strlcpy(vcap->driver, IVTV_DRIVER_NAME, sizeof(vcap->driver));
776 strlcpy(vcap->card, itv->card_name, sizeof(vcap->card));
777 strlcpy(vcap->bus_info, pci_name(itv->dev), sizeof(vcap->bus_info));
778 vcap->version = IVTV_DRIVER_VERSION; /* version */
779 vcap->capabilities = itv->v4l2_cap; /* capabilities */
780 /* reserved.. must set to 0! */
781 vcap->reserved[0] = vcap->reserved[1] =
782 vcap->reserved[2] = vcap->reserved[3] = 0;
783 return 0;
784}
782 785
783 if (vout->index >= itv->nof_audio_inputs) 786static int ivtv_enumaudio(struct file *file, void *fh, struct v4l2_audio *vin)
784 return -EINVAL; 787{
785 itv->audio_input = vout->index; 788 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
786 ivtv_audio_set_io(itv);
787 break;
788 }
789 789
790 case VIDIOC_ENUMAUDOUT:{ 790 return ivtv_get_audio_input(itv, vin->index, vin);
791 struct v4l2_audioout *vin = arg; 791}
792 792
793 /* set it to defaults from our table */ 793static int ivtv_g_audio(struct file *file, void *fh, struct v4l2_audio *vin)
794 return ivtv_get_audio_output(itv, vin->index, vin); 794{
795 } 795 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
796 796
797 case VIDIOC_G_AUDOUT:{ 797 vin->index = itv->audio_input;
798 struct v4l2_audioout *vin = arg; 798 return ivtv_get_audio_input(itv, vin->index, vin);
799}
799 800
800 vin->index = 0; 801static int ivtv_s_audio(struct file *file, void *fh, struct v4l2_audio *vout)
801 return ivtv_get_audio_output(itv, vin->index, vin); 802{
802 } 803 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
803 804
804 case VIDIOC_S_AUDOUT:{ 805 if (vout->index >= itv->nof_audio_inputs)
805 struct v4l2_audioout *vout = arg; 806 return -EINVAL;
806 807
807 return ivtv_get_audio_output(itv, vout->index, vout); 808 itv->audio_input = vout->index;
808 } 809 ivtv_audio_set_io(itv);
809 810
810 case VIDIOC_ENUMINPUT:{ 811 return 0;
811 struct v4l2_input *vin = arg; 812}
812 813
813 /* set it to defaults from our table */ 814static int ivtv_enumaudout(struct file *file, void *fh, struct v4l2_audioout *vin)
814 return ivtv_get_input(itv, vin->index, vin); 815{
815 } 816 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
816 817
817 case VIDIOC_ENUMOUTPUT:{ 818 /* set it to defaults from our table */
818 struct v4l2_output *vout = arg; 819 return ivtv_get_audio_output(itv, vin->index, vin);
820}
819 821
820 return ivtv_get_output(itv, vout->index, vout); 822static int ivtv_g_audout(struct file *file, void *fh, struct v4l2_audioout *vin)
821 } 823{
824 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
822 825
823 case VIDIOC_TRY_FMT: 826 vin->index = 0;
824 case VIDIOC_S_FMT: { 827 return ivtv_get_audio_output(itv, vin->index, vin);
825 struct v4l2_format *fmt = arg; 828}
826 829
827 return ivtv_try_or_set_fmt(itv, id->type, fmt, cmd == VIDIOC_S_FMT); 830static int ivtv_s_audout(struct file *file, void *fh, struct v4l2_audioout *vout)
828 } 831{
832 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
829 833
830 case VIDIOC_G_FMT: { 834 return ivtv_get_audio_output(itv, vout->index, vout);
831 struct v4l2_format *fmt = arg; 835}
832 int type = fmt->type;
833 836
834 memset(fmt, 0, sizeof(*fmt)); 837static int ivtv_enum_input(struct file *file, void *fh, struct v4l2_input *vin)
835 fmt->type = type; 838{
836 return ivtv_get_fmt(itv, id->type, fmt); 839 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
837 }
838 840
839 case VIDIOC_CROPCAP: { 841 /* set it to defaults from our table */
840 struct v4l2_cropcap *cropcap = arg; 842 return ivtv_get_input(itv, vin->index, vin);
843}
841 844
842 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT) 845static int ivtv_enum_output(struct file *file, void *fh, struct v4l2_output *vout)
843 return -EINVAL; 846{
844 cropcap->bounds.top = cropcap->bounds.left = 0; 847 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
845 cropcap->bounds.width = 720; 848
846 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) { 849 return ivtv_get_output(itv, vout->index, vout);
847 cropcap->bounds.height = itv->is_50hz ? 576 : 480; 850}
848 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10; 851
849 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11; 852static int ivtv_cropcap(struct file *file, void *fh, struct v4l2_cropcap *cropcap)
850 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { 853{
851 if (yi->track_osd) { 854 struct ivtv_open_id *id = fh;
852 cropcap->bounds.width = yi->osd_full_w; 855 struct ivtv *itv = id->itv;
853 cropcap->bounds.height = yi->osd_full_h; 856 struct yuv_playback_info *yi = &itv->yuv_info;
854 } else { 857 int streamtype;
855 cropcap->bounds.width = 720; 858
856 cropcap->bounds.height = 859 streamtype = id->type;
857 itv->is_out_50hz ? 576 : 480; 860
858 } 861 if (cropcap->type != V4L2_BUF_TYPE_VIDEO_OUTPUT)
859 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; 862 return -EINVAL;
860 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; 863 cropcap->bounds.top = cropcap->bounds.left = 0;
864 cropcap->bounds.width = 720;
865 if (cropcap->type == V4L2_BUF_TYPE_VIDEO_CAPTURE) {
866 cropcap->bounds.height = itv->is_50hz ? 576 : 480;
867 cropcap->pixelaspect.numerator = itv->is_50hz ? 59 : 10;
868 cropcap->pixelaspect.denominator = itv->is_50hz ? 54 : 11;
869 } else if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
870 if (yi->track_osd) {
871 cropcap->bounds.width = yi->osd_full_w;
872 cropcap->bounds.height = yi->osd_full_h;
861 } else { 873 } else {
862 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480; 874 cropcap->bounds.width = 720;
863 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10; 875 cropcap->bounds.height =
864 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11; 876 itv->is_out_50hz ? 576 : 480;
865 } 877 }
866 cropcap->defrect = cropcap->bounds; 878 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
867 return 0; 879 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
880 } else {
881 cropcap->bounds.height = itv->is_out_50hz ? 576 : 480;
882 cropcap->pixelaspect.numerator = itv->is_out_50hz ? 59 : 10;
883 cropcap->pixelaspect.denominator = itv->is_out_50hz ? 54 : 11;
868 } 884 }
885 cropcap->defrect = cropcap->bounds;
886 return 0;
887}
888
889static int ivtv_s_crop(struct file *file, void *fh, struct v4l2_crop *crop)
890{
891 struct ivtv_open_id *id = fh;
892 struct ivtv *itv = id->itv;
893 struct yuv_playback_info *yi = &itv->yuv_info;
894 int streamtype;
869 895
870 case VIDIOC_S_CROP: { 896 streamtype = id->type;
871 struct v4l2_crop *crop = arg;
872 897
873 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 898 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
874 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { 899 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
875 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) { 900 /* Should be replaced */
876 yi->main_rect = crop->c; 901 /* v4l_printk_ioctl(VIDIOC_S_CROP); */
902 }
903
904 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
905 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
906 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) {
907 yi->main_rect = crop->c;
908 return 0;
909 } else {
910 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
911 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
912 itv->main_rect = crop->c;
877 return 0; 913 return 0;
878 } else {
879 if (!ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
880 crop->c.width, crop->c.height, crop->c.left, crop->c.top)) {
881 itv->main_rect = crop->c;
882 return 0;
883 }
884 } 914 }
885 return -EINVAL;
886 } 915 }
887 return -EINVAL; 916 return -EINVAL;
888 } 917 }
918 return -EINVAL;
919}
920
921static int ivtv_g_crop(struct file *file, void *fh, struct v4l2_crop *crop)
922{
923 struct ivtv_open_id *id = fh;
924 struct ivtv *itv = id->itv;
925 struct yuv_playback_info *yi = &itv->yuv_info;
926 int streamtype;
889 927
890 case VIDIOC_G_CROP: { 928 streamtype = id->type;
891 struct v4l2_crop *crop = arg;
892 929
893 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT && 930 if (crop->type == V4L2_BUF_TYPE_VIDEO_OUTPUT &&
894 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) { 931 (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) {
895 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV) 932 if (streamtype == IVTV_DEC_STREAM_TYPE_YUV)
896 crop->c = yi->main_rect; 933 crop->c = yi->main_rect;
897 else 934 else
898 crop->c = itv->main_rect; 935 crop->c = itv->main_rect;
899 return 0; 936 return 0;
937 }
938 return -EINVAL;
939}
940
941static int ivtv_enum_fmt_vid_cap(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
942{
943 static struct v4l2_fmtdesc formats[] = {
944 { 0, 0, 0,
945 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
946 { 0, 0, 0, 0 }
947 },
948 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
949 "MPEG", V4L2_PIX_FMT_MPEG,
950 { 0, 0, 0, 0 }
900 } 951 }
952 };
953 enum v4l2_buf_type type = fmt->type;
954
955 if (fmt->index > 1)
901 return -EINVAL; 956 return -EINVAL;
902 }
903 957
904 case VIDIOC_ENUM_FMT: { 958 *fmt = formats[fmt->index];
905 static struct v4l2_fmtdesc formats[] = { 959 fmt->type = type;
906 { 0, 0, 0, 960 return 0;
907 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12, 961}
908 { 0, 0, 0, 0 }
909 },
910 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
911 "MPEG", V4L2_PIX_FMT_MPEG,
912 { 0, 0, 0, 0 }
913 }
914 };
915 struct v4l2_fmtdesc *fmt = arg;
916 enum v4l2_buf_type type = fmt->type;
917 962
918 switch (type) { 963static int ivtv_enum_fmt_vid_out(struct file *file, void *fh, struct v4l2_fmtdesc *fmt)
919 case V4L2_BUF_TYPE_VIDEO_CAPTURE: 964{
920 break; 965 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
921 case V4L2_BUF_TYPE_VIDEO_OUTPUT: 966
922 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 967 static struct v4l2_fmtdesc formats[] = {
923 return -EINVAL; 968 { 0, 0, 0,
924 break; 969 "HM12 (YUV 4:2:0)", V4L2_PIX_FMT_HM12,
925 default: 970 { 0, 0, 0, 0 }
926 return -EINVAL; 971 },
972 { 1, 0, V4L2_FMT_FLAG_COMPRESSED,
973 "MPEG", V4L2_PIX_FMT_MPEG,
974 { 0, 0, 0, 0 }
927 } 975 }
928 if (fmt->index > 1) 976 };
929 return -EINVAL; 977 enum v4l2_buf_type type = fmt->type;
930 *fmt = formats[fmt->index]; 978
931 fmt->type = type; 979 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
980 return -EINVAL;
981
982 if (fmt->index > 1)
983 return -EINVAL;
984
985 *fmt = formats[fmt->index];
986 fmt->type = type;
987
988 return 0;
989}
990
991static int ivtv_g_input(struct file *file, void *fh, unsigned int *i)
992{
993 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
994
995 *i = itv->active_input;
996
997 return 0;
998}
999
1000int ivtv_s_input(struct file *file, void *fh, unsigned int inp)
1001{
1002 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1003
1004 if (inp < 0 || inp >= itv->nof_inputs)
1005 return -EINVAL;
1006
1007 if (inp == itv->active_input) {
1008 IVTV_DEBUG_INFO("Input unchanged\n");
932 return 0; 1009 return 0;
933 } 1010 }
934 1011
935 case VIDIOC_G_INPUT:{ 1012 if (atomic_read(&itv->capturing) > 0) {
936 *(int *)arg = itv->active_input; 1013 return -EBUSY;
937 break;
938 } 1014 }
939 1015
940 case VIDIOC_S_INPUT:{ 1016 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
941 int inp = *(int *)arg; 1017 itv->active_input, inp);
942 1018
943 if (inp < 0 || inp >= itv->nof_inputs) 1019 itv->active_input = inp;
944 return -EINVAL; 1020 /* Set the audio input to whatever is appropriate for the
1021 input type. */
1022 itv->audio_input = itv->card->video_inputs[inp].audio_index;
945 1023
946 if (inp == itv->active_input) { 1024 /* prevent others from messing with the streams until
947 IVTV_DEBUG_INFO("Input unchanged\n"); 1025 we're finished changing inputs. */
948 break; 1026 ivtv_mute(itv);
949 } 1027 ivtv_video_set_io(itv);
950 if (atomic_read(&itv->capturing) > 0) { 1028 ivtv_audio_set_io(itv);
951 return -EBUSY; 1029 ivtv_unmute(itv);
952 }
953 IVTV_DEBUG_INFO("Changing input from %d to %d\n",
954 itv->active_input, inp);
955 1030
956 itv->active_input = inp; 1031 return 0;
957 /* Set the audio input to whatever is appropriate for the 1032}
958 input type. */
959 itv->audio_input = itv->card->video_inputs[inp].audio_index;
960 1033
961 /* prevent others from messing with the streams until 1034static int ivtv_g_output(struct file *file, void *fh, unsigned int *i)
962 we're finished changing inputs. */ 1035{
963 ivtv_mute(itv); 1036 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
964 ivtv_video_set_io(itv);
965 ivtv_audio_set_io(itv);
966 ivtv_unmute(itv);
967 break;
968 }
969 1037
970 case VIDIOC_G_OUTPUT:{ 1038 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT))
971 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT)) 1039 return -EINVAL;
972 return -EINVAL;
973 *(int *)arg = itv->active_output;
974 break;
975 }
976 1040
977 case VIDIOC_S_OUTPUT:{ 1041 *i = itv->active_output;
978 int outp = *(int *)arg;
979 struct v4l2_routing route;
980 1042
981 if (outp >= itv->card->nof_outputs) 1043 return 0;
982 return -EINVAL; 1044}
983 1045
984 if (outp == itv->active_output) { 1046static int ivtv_s_output(struct file *file, void *fh, unsigned int outp)
985 IVTV_DEBUG_INFO("Output unchanged\n"); 1047{
986 break; 1048 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
987 } 1049 struct v4l2_routing route;
988 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
989 itv->active_output, outp);
990 1050
991 itv->active_output = outp; 1051 if (outp >= itv->card->nof_outputs)
992 route.input = SAA7127_INPUT_TYPE_NORMAL; 1052 return -EINVAL;
993 route.output = itv->card->video_outputs[outp].video_output; 1053
994 ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route); 1054 if (outp == itv->active_output) {
995 break; 1055 IVTV_DEBUG_INFO("Output unchanged\n");
1056 return 0;
996 } 1057 }
1058 IVTV_DEBUG_INFO("Changing output from %d to %d\n",
1059 itv->active_output, outp);
997 1060
998 case VIDIOC_G_FREQUENCY:{ 1061 itv->active_output = outp;
999 struct v4l2_frequency *vf = arg; 1062 route.input = SAA7127_INPUT_TYPE_NORMAL;
1063 route.output = itv->card->video_outputs[outp].video_output;
1064 ivtv_saa7127(itv, VIDIOC_INT_S_VIDEO_ROUTING, &route);
1000 1065
1001 if (vf->tuner != 0) 1066 return 0;
1002 return -EINVAL; 1067}
1003 ivtv_call_i2c_clients(itv, cmd, arg);
1004 break;
1005 }
1006 1068
1007 case VIDIOC_S_FREQUENCY:{ 1069static int ivtv_g_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1008 struct v4l2_frequency vf = *(struct v4l2_frequency *)arg; 1070{
1071 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1009 1072
1010 if (vf.tuner != 0) 1073 if (vf->tuner != 0)
1011 return -EINVAL; 1074 return -EINVAL;
1012 1075
1013 ivtv_mute(itv); 1076 ivtv_call_i2c_clients(itv, VIDIOC_G_FREQUENCY, vf);
1014 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf.frequency); 1077 return 0;
1015 ivtv_call_i2c_clients(itv, cmd, &vf); 1078}
1016 ivtv_unmute(itv);
1017 break;
1018 }
1019 1079
1020 case VIDIOC_ENUMSTD:{ 1080int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf)
1021 struct v4l2_standard *vs = arg; 1081{
1022 int idx = vs->index; 1082 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1023 1083
1024 if (idx < 0 || idx >= ARRAY_SIZE(enum_stds)) 1084 if (vf->tuner != 0)
1025 return -EINVAL; 1085 return -EINVAL;
1026 1086
1027 *vs = (enum_stds[idx].std & V4L2_STD_525_60) ? 1087 ivtv_mute(itv);
1028 ivtv_std_60hz : ivtv_std_50hz; 1088 IVTV_DEBUG_INFO("v4l2 ioctl: set frequency %d\n", vf->frequency);
1029 vs->index = idx; 1089 ivtv_call_i2c_clients(itv, VIDIOC_S_FREQUENCY, vf);
1030 vs->id = enum_stds[idx].std; 1090 ivtv_unmute(itv);
1031 strlcpy(vs->name, enum_stds[idx].name, sizeof(vs->name)); 1091 return 0;
1032 break; 1092}
1033 }
1034 1093
1035 case VIDIOC_G_STD:{ 1094static int ivtv_g_std(struct file *file, void *fh, v4l2_std_id *std)
1036 *(v4l2_std_id *) arg = itv->std; 1095{
1037 break; 1096 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1038 }
1039 1097
1040 case VIDIOC_S_STD: { 1098 *std = itv->std;
1041 v4l2_std_id std = *(v4l2_std_id *) arg; 1099 return 0;
1100}
1042 1101
1043 if ((std & V4L2_STD_ALL) == 0) 1102int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std)
1044 return -EINVAL; 1103{
1104 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1105 struct yuv_playback_info *yi = &itv->yuv_info;
1045 1106
1046 if (std == itv->std) 1107 if ((*std & V4L2_STD_ALL) == 0)
1047 break; 1108 return -EINVAL;
1048 1109
1049 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) || 1110 if (*std == itv->std)
1050 atomic_read(&itv->capturing) > 0 || 1111 return 0;
1051 atomic_read(&itv->decoding) > 0) {
1052 /* Switching standard would turn off the radio or mess
1053 with already running streams, prevent that by
1054 returning EBUSY. */
1055 return -EBUSY;
1056 }
1057 1112
1058 itv->std = std; 1113 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ||
1059 itv->is_60hz = (std & V4L2_STD_525_60) ? 1 : 0; 1114 atomic_read(&itv->capturing) > 0 ||
1060 itv->params.is_50hz = itv->is_50hz = !itv->is_60hz; 1115 atomic_read(&itv->decoding) > 0) {
1061 itv->params.width = 720; 1116 /* Switching standard would turn off the radio or mess
1062 itv->params.height = itv->is_50hz ? 576 : 480; 1117 with already running streams, prevent that by
1063 itv->vbi.count = itv->is_50hz ? 18 : 12; 1118 returning EBUSY. */
1064 itv->vbi.start[0] = itv->is_50hz ? 6 : 10; 1119 return -EBUSY;
1065 itv->vbi.start[1] = itv->is_50hz ? 318 : 273; 1120 }
1066 if (itv->hw_flags & IVTV_HW_CX25840) { 1121
1067 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284; 1122 itv->std = *std;
1068 } 1123 itv->is_60hz = (*std & V4L2_STD_525_60) ? 1 : 0;
1069 IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std); 1124 itv->params.is_50hz = itv->is_50hz = !itv->is_60hz;
1070 1125 itv->params.width = 720;
1071 /* Tuner */ 1126 itv->params.height = itv->is_50hz ? 576 : 480;
1072 ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std); 1127 itv->vbi.count = itv->is_50hz ? 18 : 12;
1073 1128 itv->vbi.start[0] = itv->is_50hz ? 6 : 10;
1074 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) { 1129 itv->vbi.start[1] = itv->is_50hz ? 318 : 273;
1075 /* set display standard */ 1130
1076 itv->std_out = std; 1131 if (itv->hw_flags & IVTV_HW_CX25840)
1077 itv->is_out_60hz = itv->is_60hz; 1132 itv->vbi.sliced_decoder_line_size = itv->is_60hz ? 272 : 284;
1078 itv->is_out_50hz = itv->is_50hz; 1133
1079 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out); 1134 IVTV_DEBUG_INFO("Switching standard to %llx.\n", (unsigned long long)itv->std);
1080 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz); 1135
1081 itv->main_rect.left = itv->main_rect.top = 0; 1136 /* Tuner */
1082 itv->main_rect.width = 720; 1137 ivtv_call_i2c_clients(itv, VIDIOC_S_STD, &itv->std);
1083 itv->main_rect.height = itv->params.height; 1138
1084 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4, 1139 if (itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT) {
1085 720, itv->main_rect.height, 0, 0); 1140 /* set display standard */
1086 yi->main_rect = itv->main_rect; 1141 itv->std_out = *std;
1087 if (!itv->osd_info) { 1142 itv->is_out_60hz = itv->is_60hz;
1088 yi->osd_full_w = 720; 1143 itv->is_out_50hz = itv->is_50hz;
1089 yi->osd_full_h = itv->is_out_50hz ? 576 : 480; 1144 ivtv_call_i2c_clients(itv, VIDIOC_INT_S_STD_OUTPUT, &itv->std_out);
1090 } 1145 ivtv_vapi(itv, CX2341X_DEC_SET_STANDARD, 1, itv->is_out_50hz);
1146 itv->main_rect.left = itv->main_rect.top = 0;
1147 itv->main_rect.width = 720;
1148 itv->main_rect.height = itv->params.height;
1149 ivtv_vapi(itv, CX2341X_OSD_SET_FRAMEBUFFER_WINDOW, 4,
1150 720, itv->main_rect.height, 0, 0);
1151 yi->main_rect = itv->main_rect;
1152 if (!itv->osd_info) {
1153 yi->osd_full_w = 720;
1154 yi->osd_full_h = itv->is_out_50hz ? 576 : 480;
1091 } 1155 }
1092 break;
1093 } 1156 }
1157 return 0;
1158}
1094 1159
1095 case VIDIOC_S_TUNER: { /* Setting tuner can only set audio mode */ 1160static int ivtv_s_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1096 struct v4l2_tuner *vt = arg; 1161{
1162 struct ivtv_open_id *id = fh;
1163 struct ivtv *itv = id->itv;
1097 1164
1098 if (vt->index != 0) 1165 if (vt->index != 0)
1099 return -EINVAL; 1166 return -EINVAL;
1100 1167
1101 ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt); 1168 ivtv_call_i2c_clients(itv, VIDIOC_S_TUNER, vt);
1102 break;
1103 }
1104 1169
1105 case VIDIOC_G_TUNER: { 1170 return 0;
1106 struct v4l2_tuner *vt = arg; 1171}
1107 1172
1108 if (vt->index != 0) 1173static int ivtv_g_tuner(struct file *file, void *fh, struct v4l2_tuner *vt)
1109 return -EINVAL; 1174{
1175 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1110 1176
1111 memset(vt, 0, sizeof(*vt)); 1177 if (vt->index != 0)
1112 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt); 1178 return -EINVAL;
1113 1179
1114 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) { 1180 memset(vt, 0, sizeof(*vt));
1115 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name)); 1181 ivtv_call_i2c_clients(itv, VIDIOC_G_TUNER, vt);
1116 vt->type = V4L2_TUNER_RADIO; 1182
1117 } else { 1183 if (test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags)) {
1118 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name)); 1184 strlcpy(vt->name, "ivtv Radio Tuner", sizeof(vt->name));
1119 vt->type = V4L2_TUNER_ANALOG_TV; 1185 vt->type = V4L2_TUNER_RADIO;
1120 } 1186 } else {
1121 break; 1187 strlcpy(vt->name, "ivtv TV Tuner", sizeof(vt->name));
1188 vt->type = V4L2_TUNER_ANALOG_TV;
1122 } 1189 }
1123 1190
1124 case VIDIOC_G_SLICED_VBI_CAP: { 1191 return 0;
1125 struct v4l2_sliced_vbi_cap *cap = arg; 1192}
1126 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525; 1193
1127 int f, l; 1194static int ivtv_g_sliced_vbi_cap(struct file *file, void *fh, struct v4l2_sliced_vbi_cap *cap)
1128 enum v4l2_buf_type type = cap->type; 1195{
1129 1196 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1130 memset(cap, 0, sizeof(*cap)); 1197 int set = itv->is_50hz ? V4L2_SLICED_VBI_625 : V4L2_SLICED_VBI_525;
1131 cap->type = type; 1198 int f, l;
1132 if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) { 1199 enum v4l2_buf_type type = cap->type;
1133 for (f = 0; f < 2; f++) { 1200
1134 for (l = 0; l < 24; l++) { 1201 memset(cap, 0, sizeof(*cap));
1135 if (valid_service_line(f, l, itv->is_50hz)) { 1202 cap->type = type;
1136 cap->service_lines[f][l] = set; 1203 if (type == V4L2_BUF_TYPE_SLICED_VBI_CAPTURE) {
1137 } 1204 for (f = 0; f < 2; f++) {
1138 } 1205 for (l = 0; l < 24; l++) {
1206 if (valid_service_line(f, l, itv->is_50hz))
1207 cap->service_lines[f][l] = set;
1139 } 1208 }
1140 return 0;
1141 } 1209 }
1142 if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) { 1210 return 0;
1143 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT)) 1211 }
1144 return -EINVAL; 1212 if (type == V4L2_BUF_TYPE_SLICED_VBI_OUTPUT) {
1145 if (itv->is_60hz) { 1213 if (!(itv->v4l2_cap & V4L2_CAP_SLICED_VBI_OUTPUT))
1146 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525; 1214 return -EINVAL;
1147 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525; 1215 if (itv->is_60hz) {
1148 } else { 1216 cap->service_lines[0][21] = V4L2_SLICED_CAPTION_525;
1149 cap->service_lines[0][23] = V4L2_SLICED_WSS_625; 1217 cap->service_lines[1][21] = V4L2_SLICED_CAPTION_525;
1150 cap->service_lines[0][16] = V4L2_SLICED_VPS; 1218 } else {
1151 } 1219 cap->service_lines[0][23] = V4L2_SLICED_WSS_625;
1152 return 0; 1220 cap->service_lines[0][16] = V4L2_SLICED_VPS;
1153 } 1221 }
1154 return -EINVAL; 1222 return 0;
1155 } 1223 }
1224 return -EINVAL;
1225}
1156 1226
1157 case VIDIOC_G_ENC_INDEX: { 1227static int ivtv_g_enc_index(struct file *file, void *fh, struct v4l2_enc_idx *idx)
1158 struct v4l2_enc_idx *idx = arg; 1228{
1159 struct v4l2_enc_idx_entry *e = idx->entry; 1229 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1160 int entries; 1230 struct v4l2_enc_idx_entry *e = idx->entry;
1161 int i; 1231 int entries;
1162 1232 int i;
1163 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) % 1233
1164 IVTV_MAX_PGM_INDEX; 1234 entries = (itv->pgm_info_write_idx + IVTV_MAX_PGM_INDEX - itv->pgm_info_read_idx) %
1165 if (entries > V4L2_ENC_IDX_ENTRIES) 1235 IVTV_MAX_PGM_INDEX;
1166 entries = V4L2_ENC_IDX_ENTRIES; 1236 if (entries > V4L2_ENC_IDX_ENTRIES)
1167 idx->entries = 0; 1237 entries = V4L2_ENC_IDX_ENTRIES;
1168 for (i = 0; i < entries; i++) { 1238 idx->entries = 0;
1169 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX]; 1239 for (i = 0; i < entries; i++) {
1170 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) { 1240 *e = itv->pgm_info[(itv->pgm_info_read_idx + i) % IVTV_MAX_PGM_INDEX];
1171 idx->entries++; 1241 if ((e->flags & V4L2_ENC_IDX_FRAME_MASK) <= V4L2_ENC_IDX_FRAME_B) {
1172 e++; 1242 idx->entries++;
1173 } 1243 e++;
1174 } 1244 }
1175 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1176 break;
1177 } 1245 }
1246 itv->pgm_info_read_idx = (itv->pgm_info_read_idx + idx->entries) % IVTV_MAX_PGM_INDEX;
1247 return 0;
1248}
1178 1249
1179 case VIDIOC_ENCODER_CMD: 1250static int ivtv_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1180 case VIDIOC_TRY_ENCODER_CMD: { 1251{
1181 struct v4l2_encoder_cmd *enc = arg; 1252 struct ivtv_open_id *id = fh;
1182 int try = cmd == VIDIOC_TRY_ENCODER_CMD; 1253 struct ivtv *itv = id->itv;
1183
1184 memset(&enc->raw, 0, sizeof(enc->raw));
1185 switch (enc->cmd) {
1186 case V4L2_ENC_CMD_START:
1187 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1188 enc->flags = 0;
1189 if (try)
1190 return 0;
1191 return ivtv_start_capture(id);
1192 1254
1193 case V4L2_ENC_CMD_STOP: 1255 memset(&enc->raw, 0, sizeof(enc->raw));
1194 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n"); 1256
1195 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END; 1257 switch (enc->cmd) {
1196 if (try) 1258 case V4L2_ENC_CMD_START:
1197 return 0; 1259 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1198 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END); 1260 enc->flags = 0;
1261 return ivtv_start_capture(id);
1262
1263 case V4L2_ENC_CMD_STOP:
1264 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1265 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1266 ivtv_stop_capture(id, enc->flags & V4L2_ENC_CMD_STOP_AT_GOP_END);
1267 return 0;
1268
1269 case V4L2_ENC_CMD_PAUSE:
1270 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1271 enc->flags = 0;
1272
1273 if (!atomic_read(&itv->capturing))
1274 return -EPERM;
1275 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1199 return 0; 1276 return 0;
1200 1277
1201 case V4L2_ENC_CMD_PAUSE: 1278 ivtv_mute(itv);
1202 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n"); 1279 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1203 enc->flags = 0; 1280 break;
1204 if (try)
1205 return 0;
1206 if (!atomic_read(&itv->capturing))
1207 return -EPERM;
1208 if (test_and_set_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1209 return 0;
1210 ivtv_mute(itv);
1211 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 0);
1212 break;
1213 1281
1214 case V4L2_ENC_CMD_RESUME: 1282 case V4L2_ENC_CMD_RESUME:
1215 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n"); 1283 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1216 enc->flags = 0; 1284 enc->flags = 0;
1217 if (try) 1285
1218 return 0; 1286 if (!atomic_read(&itv->capturing))
1219 if (!atomic_read(&itv->capturing)) 1287 return -EPERM;
1220 return -EPERM; 1288
1221 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags)) 1289 if (!test_and_clear_bit(IVTV_F_I_ENC_PAUSED, &itv->i_flags))
1222 return 0; 1290 return 0;
1223 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1); 1291
1224 ivtv_unmute(itv); 1292 ivtv_vapi(itv, CX2341X_ENC_PAUSE_ENCODER, 1, 1);
1225 break; 1293 ivtv_unmute(itv);
1226 default:
1227 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1228 return -EINVAL;
1229 }
1230 break; 1294 break;
1295 default:
1296 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1297 return -EINVAL;
1231 } 1298 }
1232 1299
1233 case VIDIOC_G_FBUF: { 1300 return 0;
1234 struct v4l2_framebuffer *fb = arg; 1301}
1235 int pixfmt;
1236 static u32 pixel_format[16] = {
1237 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1238 V4L2_PIX_FMT_RGB565,
1239 V4L2_PIX_FMT_RGB555,
1240 V4L2_PIX_FMT_RGB444,
1241 V4L2_PIX_FMT_RGB32,
1242 0,
1243 0,
1244 0,
1245 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1246 V4L2_PIX_FMT_YUV565,
1247 V4L2_PIX_FMT_YUV555,
1248 V4L2_PIX_FMT_YUV444,
1249 V4L2_PIX_FMT_YUV32,
1250 0,
1251 0,
1252 0,
1253 };
1254 1302
1255 memset(fb, 0, sizeof(*fb)); 1303static int ivtv_try_encoder_cmd(struct file *file, void *fh, struct v4l2_encoder_cmd *enc)
1256 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) 1304{
1257 return -EINVAL; 1305 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1258 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY | 1306
1259 V4L2_FBUF_CAP_GLOBAL_ALPHA; 1307 memset(&enc->raw, 0, sizeof(enc->raw));
1260 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); 1308
1261 data[0] |= (read_reg(0x2a00) >> 7) & 0x40; 1309 switch (enc->cmd) {
1262 pixfmt = (data[0] >> 3) & 0xf; 1310 case V4L2_ENC_CMD_START:
1263 fb->fmt.pixelformat = pixel_format[pixfmt]; 1311 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_START\n");
1264 fb->fmt.width = itv->osd_rect.width; 1312 enc->flags = 0;
1265 fb->fmt.height = itv->osd_rect.height; 1313 return 0;
1266 fb->base = (void *)itv->osd_video_pbase; 1314
1267 if (itv->osd_chroma_key_state) 1315 case V4L2_ENC_CMD_STOP:
1268 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY; 1316 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_STOP\n");
1269 if (itv->osd_global_alpha_state) 1317 enc->flags &= V4L2_ENC_CMD_STOP_AT_GOP_END;
1270 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA; 1318 return 0;
1271 pixfmt &= 7; 1319
1272 /* no local alpha for RGB565 or unknown formats */ 1320 case V4L2_ENC_CMD_PAUSE:
1273 if (pixfmt == 1 || pixfmt > 4) 1321 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_PAUSE\n");
1274 break; 1322 enc->flags = 0;
1323 return 0;
1324
1325 case V4L2_ENC_CMD_RESUME:
1326 IVTV_DEBUG_IOCTL("V4L2_ENC_CMD_RESUME\n");
1327 enc->flags = 0;
1328 return 0;
1329 default:
1330 IVTV_DEBUG_IOCTL("Unknown cmd %d\n", enc->cmd);
1331 return -EINVAL;
1332 }
1333}
1334
1335static int ivtv_g_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1336{
1337 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1338 u32 data[CX2341X_MBOX_MAX_DATA];
1339 struct yuv_playback_info *yi = &itv->yuv_info;
1340
1341 int pixfmt;
1342 static u32 pixel_format[16] = {
1343 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry RGB colormap */
1344 V4L2_PIX_FMT_RGB565,
1345 V4L2_PIX_FMT_RGB555,
1346 V4L2_PIX_FMT_RGB444,
1347 V4L2_PIX_FMT_RGB32,
1348 0,
1349 0,
1350 0,
1351 V4L2_PIX_FMT_PAL8, /* Uses a 256-entry YUV colormap */
1352 V4L2_PIX_FMT_YUV565,
1353 V4L2_PIX_FMT_YUV555,
1354 V4L2_PIX_FMT_YUV444,
1355 V4L2_PIX_FMT_YUV32,
1356 0,
1357 0,
1358 0,
1359 };
1360
1361 memset(fb, 0, sizeof(*fb));
1362
1363 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1364 return -EINVAL;
1365
1366 fb->capability = V4L2_FBUF_CAP_EXTERNOVERLAY | V4L2_FBUF_CAP_CHROMAKEY |
1367 V4L2_FBUF_CAP_GLOBAL_ALPHA;
1368
1369 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1370 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1371 pixfmt = (data[0] >> 3) & 0xf;
1372
1373 fb->fmt.pixelformat = pixel_format[pixfmt];
1374 fb->fmt.width = itv->osd_rect.width;
1375 fb->fmt.height = itv->osd_rect.height;
1376 fb->base = (void *)itv->osd_video_pbase;
1377
1378 if (itv->osd_chroma_key_state)
1379 fb->flags |= V4L2_FBUF_FLAG_CHROMAKEY;
1380
1381 if (itv->osd_global_alpha_state)
1382 fb->flags |= V4L2_FBUF_FLAG_GLOBAL_ALPHA;
1383
1384 pixfmt &= 7;
1385
1386 /* no local alpha for RGB565 or unknown formats */
1387 if (pixfmt == 1 || pixfmt > 4)
1388 return 0;
1389
1390 /* 16-bit formats have inverted local alpha */
1391 if (pixfmt == 2 || pixfmt == 3)
1392 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA;
1393 else
1394 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA;
1395
1396 if (itv->osd_local_alpha_state) {
1275 /* 16-bit formats have inverted local alpha */ 1397 /* 16-bit formats have inverted local alpha */
1276 if (pixfmt == 2 || pixfmt == 3) 1398 if (pixfmt == 2 || pixfmt == 3)
1277 fb->capability |= V4L2_FBUF_CAP_LOCAL_INV_ALPHA; 1399 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
1278 else 1400 else
1279 fb->capability |= V4L2_FBUF_CAP_LOCAL_ALPHA; 1401 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1280 if (itv->osd_local_alpha_state) {
1281 /* 16-bit formats have inverted local alpha */
1282 if (pixfmt == 2 || pixfmt == 3)
1283 fb->flags |= V4L2_FBUF_FLAG_LOCAL_INV_ALPHA;
1284 else
1285 fb->flags |= V4L2_FBUF_FLAG_LOCAL_ALPHA;
1286 }
1287 if (yi->track_osd)
1288 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1289 break;
1290 } 1402 }
1403 if (yi->track_osd)
1404 fb->flags |= V4L2_FBUF_FLAG_OVERLAY;
1291 1405
1292 case VIDIOC_S_FBUF: { 1406 return 0;
1293 struct v4l2_framebuffer *fb = arg; 1407}
1294 1408
1295 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) 1409static int ivtv_s_fbuf(struct file *file, void *fh, struct v4l2_framebuffer *fb)
1296 return -EINVAL; 1410{
1297 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0; 1411 struct ivtv_open_id *id = fh;
1298 itv->osd_local_alpha_state = 1412 struct ivtv *itv = id->itv;
1299 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0; 1413 struct yuv_playback_info *yi = &itv->yuv_info;
1300 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1301 ivtv_set_osd_alpha(itv);
1302 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
1303 break;
1304 }
1305 1414
1306 case VIDIOC_OVERLAY: { 1415 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1307 int *on = arg; 1416 return -EINVAL;
1308 1417
1309 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY)) 1418 itv->osd_global_alpha_state = (fb->flags & V4L2_FBUF_FLAG_GLOBAL_ALPHA) != 0;
1310 return -EINVAL; 1419 itv->osd_local_alpha_state =
1311 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, *on != 0); 1420 (fb->flags & (V4L2_FBUF_FLAG_LOCAL_ALPHA|V4L2_FBUF_FLAG_LOCAL_INV_ALPHA)) != 0;
1312 break; 1421 itv->osd_chroma_key_state = (fb->flags & V4L2_FBUF_FLAG_CHROMAKEY) != 0;
1313 } 1422 ivtv_set_osd_alpha(itv);
1423 yi->track_osd = (fb->flags & V4L2_FBUF_FLAG_OVERLAY) != 0;
1314 1424
1315 case VIDIOC_LOG_STATUS: 1425 return 0;
1316 { 1426}
1317 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1318 struct v4l2_input vidin;
1319 struct v4l2_audio audin;
1320 int i;
1321 1427
1322 IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num); 1428static int ivtv_overlay(struct file *file, void *fh, unsigned int on)
1323 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name); 1429{
1324 if (itv->hw_flags & IVTV_HW_TVEEPROM) { 1430 struct ivtv_open_id *id = fh;
1325 struct tveeprom tv; 1431 struct ivtv *itv = id->itv;
1326 1432
1327 ivtv_read_eeprom(itv, &tv); 1433 if (!(itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT_OVERLAY))
1328 } 1434 return -EINVAL;
1329 ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL); 1435
1330 ivtv_get_input(itv, itv->active_input, &vidin); 1436 ivtv_vapi(itv, CX2341X_OSD_SET_STATE, 1, on != 0);
1331 ivtv_get_audio_input(itv, itv->audio_input, &audin); 1437
1332 IVTV_INFO("Video Input: %s\n", vidin.name); 1438 return 0;
1333 IVTV_INFO("Audio Input: %s%s\n", audin.name, 1439}
1334 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : ""); 1440
1335 if (has_output) { 1441static int ivtv_log_status(struct file *file, void *fh)
1336 struct v4l2_output vidout; 1442{
1337 struct v4l2_audioout audout; 1443 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1338 int mode = itv->output_mode; 1444 u32 data[CX2341X_MBOX_MAX_DATA];
1339 static const char * const output_modes[5] = { 1445
1340 "None", 1446 int has_output = itv->v4l2_cap & V4L2_CAP_VIDEO_OUTPUT;
1341 "MPEG Streaming", 1447 struct v4l2_input vidin;
1342 "YUV Streaming", 1448 struct v4l2_audio audin;
1343 "YUV Frames", 1449 int i;
1344 "Passthrough", 1450
1345 }; 1451 IVTV_INFO("================= START STATUS CARD #%d =================\n", itv->num);
1346 static const char * const audio_modes[5] = { 1452 IVTV_INFO("Version: %s Card: %s\n", IVTV_VERSION, itv->card_name);
1347 "Stereo", 1453 if (itv->hw_flags & IVTV_HW_TVEEPROM) {
1348 "Left", 1454 struct tveeprom tv;
1349 "Right", 1455
1350 "Mono", 1456 ivtv_read_eeprom(itv, &tv);
1351 "Swapped" 1457 }
1352 }; 1458 ivtv_call_i2c_clients(itv, VIDIOC_LOG_STATUS, NULL);
1353 static const char * const alpha_mode[4] = { 1459 ivtv_get_input(itv, itv->active_input, &vidin);
1354 "None", 1460 ivtv_get_audio_input(itv, itv->audio_input, &audin);
1355 "Global", 1461 IVTV_INFO("Video Input: %s\n", vidin.name);
1356 "Local", 1462 IVTV_INFO("Audio Input: %s%s\n", audin.name,
1357 "Global and Local" 1463 (itv->dualwatch_stereo_mode & ~0x300) == 0x200 ? " (Bilingual)" : "");
1358 }; 1464 if (has_output) {
1359 static const char * const pixel_format[16] = { 1465 struct v4l2_output vidout;
1360 "ARGB Indexed", 1466 struct v4l2_audioout audout;
1361 "RGB 5:6:5", 1467 int mode = itv->output_mode;
1362 "ARGB 1:5:5:5", 1468 static const char * const output_modes[5] = {
1363 "ARGB 1:4:4:4", 1469 "None",
1364 "ARGB 8:8:8:8", 1470 "MPEG Streaming",
1365 "5", 1471 "YUV Streaming",
1366 "6", 1472 "YUV Frames",
1367 "7", 1473 "Passthrough",
1368 "AYUV Indexed", 1474 };
1369 "YUV 5:6:5", 1475 static const char * const audio_modes[5] = {
1370 "AYUV 1:5:5:5", 1476 "Stereo",
1371 "AYUV 1:4:4:4", 1477 "Left",
1372 "AYUV 8:8:8:8", 1478 "Right",
1373 "13", 1479 "Mono",
1374 "14", 1480 "Swapped"
1375 "15", 1481 };
1376 }; 1482 static const char * const alpha_mode[4] = {
1377 1483 "None",
1378 ivtv_get_output(itv, itv->active_output, &vidout); 1484 "Global",
1379 ivtv_get_audio_output(itv, 0, &audout); 1485 "Local",
1380 IVTV_INFO("Video Output: %s\n", vidout.name); 1486 "Global and Local"
1381 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name, 1487 };
1382 audio_modes[itv->audio_stereo_mode], 1488 static const char * const pixel_format[16] = {
1383 audio_modes[itv->audio_bilingual_mode]); 1489 "ARGB Indexed",
1384 if (mode < 0 || mode > OUT_PASSTHROUGH) 1490 "RGB 5:6:5",
1385 mode = OUT_NONE; 1491 "ARGB 1:5:5:5",
1386 IVTV_INFO("Output Mode: %s\n", output_modes[mode]); 1492 "ARGB 1:4:4:4",
1387 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0); 1493 "ARGB 8:8:8:8",
1388 data[0] |= (read_reg(0x2a00) >> 7) & 0x40; 1494 "5",
1389 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n", 1495 "6",
1390 data[0] & 1 ? "On" : "Off", 1496 "7",
1391 alpha_mode[(data[0] >> 1) & 0x3], 1497 "AYUV Indexed",
1392 pixel_format[(data[0] >> 3) & 0xf]); 1498 "YUV 5:6:5",
1393 } 1499 "AYUV 1:5:5:5",
1394 IVTV_INFO("Tuner: %s\n", 1500 "AYUV 1:4:4:4",
1395 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV"); 1501 "AYUV 8:8:8:8",
1396 cx2341x_log_status(&itv->params, itv->name); 1502 "13",
1397 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags); 1503 "14",
1398 for (i = 0; i < IVTV_MAX_STREAMS; i++) { 1504 "15",
1399 struct ivtv_stream *s = &itv->streams[i]; 1505 };
1400 1506
1401 if (s->v4l2dev == NULL || s->buffers == 0) 1507 ivtv_get_output(itv, itv->active_output, &vidout);
1402 continue; 1508 ivtv_get_audio_output(itv, 0, &audout);
1403 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags, 1509 IVTV_INFO("Video Output: %s\n", vidout.name);
1404 (s->buffers - s->q_free.buffers) * 100 / s->buffers, 1510 IVTV_INFO("Audio Output: %s (Stereo/Bilingual: %s/%s)\n", audout.name,
1405 (s->buffers * s->buf_size) / 1024, s->buffers); 1511 audio_modes[itv->audio_stereo_mode],
1406 } 1512 audio_modes[itv->audio_bilingual_mode]);
1407 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted); 1513 if (mode < 0 || mode > OUT_PASSTHROUGH)
1408 IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num); 1514 mode = OUT_NONE;
1409 break; 1515 IVTV_INFO("Output Mode: %s\n", output_modes[mode]);
1516 ivtv_vapi_result(itv, data, CX2341X_OSD_GET_STATE, 0);
1517 data[0] |= (read_reg(0x2a00) >> 7) & 0x40;
1518 IVTV_INFO("Overlay: %s, Alpha: %s, Pixel Format: %s\n",
1519 data[0] & 1 ? "On" : "Off",
1520 alpha_mode[(data[0] >> 1) & 0x3],
1521 pixel_format[(data[0] >> 3) & 0xf]);
1410 } 1522 }
1523 IVTV_INFO("Tuner: %s\n",
1524 test_bit(IVTV_F_I_RADIO_USER, &itv->i_flags) ? "Radio" : "TV");
1525 cx2341x_log_status(&itv->params, itv->name);
1526 IVTV_INFO("Status flags: 0x%08lx\n", itv->i_flags);
1527 for (i = 0; i < IVTV_MAX_STREAMS; i++) {
1528 struct ivtv_stream *s = &itv->streams[i];
1411 1529
1412 default: 1530 if (s->v4l2dev == NULL || s->buffers == 0)
1413 return -EINVAL; 1531 continue;
1532 IVTV_INFO("Stream %s: status 0x%04lx, %d%% of %d KiB (%d buffers) in use\n", s->name, s->s_flags,
1533 (s->buffers - s->q_free.buffers) * 100 / s->buffers,
1534 (s->buffers * s->buf_size) / 1024, s->buffers);
1414 } 1535 }
1536
1537 IVTV_INFO("Read MPG/VBI: %lld/%lld bytes\n", (long long)itv->mpg_data_received, (long long)itv->vbi_data_inserted);
1538 IVTV_INFO("================== END STATUS CARD #%d ==================\n", itv->num);
1539
1415 return 0; 1540 return 0;
1416} 1541}
1417 1542
@@ -1607,121 +1732,30 @@ static int ivtv_decoder_ioctls(struct file *filp, unsigned int cmd, void *arg)
1607 return 0; 1732 return 0;
1608} 1733}
1609 1734
1610static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp, 1735static int ivtv_default(struct file *file, void *fh, int cmd, void *arg)
1611 unsigned int cmd, void *arg)
1612{ 1736{
1613 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data; 1737 struct ivtv *itv = ((struct ivtv_open_id *)fh)->itv;
1614 struct ivtv *itv = id->itv;
1615 int ret;
1616 1738
1617 /* check priority */
1618 switch (cmd) { 1739 switch (cmd) {
1619 case VIDIOC_S_CTRL: 1740 case VIDIOC_INT_S_AUDIO_ROUTING: {
1620 case VIDIOC_S_STD: 1741 struct v4l2_routing *route = arg;
1621 case VIDIOC_S_INPUT:
1622 case VIDIOC_S_OUTPUT:
1623 case VIDIOC_S_TUNER:
1624 case VIDIOC_S_FREQUENCY:
1625 case VIDIOC_S_FMT:
1626 case VIDIOC_S_CROP:
1627 case VIDIOC_S_AUDIO:
1628 case VIDIOC_S_AUDOUT:
1629 case VIDIOC_S_EXT_CTRLS:
1630 case VIDIOC_S_FBUF:
1631 case VIDIOC_OVERLAY:
1632 ret = v4l2_prio_check(&itv->prio, &id->prio);
1633 if (ret)
1634 return ret;
1635 }
1636
1637 switch (cmd) {
1638 case VIDIOC_DBG_G_REGISTER:
1639 case VIDIOC_DBG_S_REGISTER:
1640 case VIDIOC_G_CHIP_IDENT:
1641 case VIDIOC_INT_S_AUDIO_ROUTING:
1642 case VIDIOC_INT_RESET:
1643 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1644 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1645 v4l_printk_ioctl(cmd);
1646 printk("\n");
1647 }
1648 return ivtv_debug_ioctls(filp, cmd, arg);
1649 1742
1650 case VIDIOC_G_PRIORITY: 1743 ivtv_i2c_hw(itv, itv->card->hw_audio, VIDIOC_INT_S_AUDIO_ROUTING, route);
1651 case VIDIOC_S_PRIORITY: 1744 break;
1652 case VIDIOC_QUERYCAP: 1745 }
1653 case VIDIOC_ENUMINPUT:
1654 case VIDIOC_G_INPUT:
1655 case VIDIOC_S_INPUT:
1656 case VIDIOC_ENUMOUTPUT:
1657 case VIDIOC_G_OUTPUT:
1658 case VIDIOC_S_OUTPUT:
1659 case VIDIOC_G_FMT:
1660 case VIDIOC_S_FMT:
1661 case VIDIOC_TRY_FMT:
1662 case VIDIOC_ENUM_FMT:
1663 case VIDIOC_CROPCAP:
1664 case VIDIOC_G_CROP:
1665 case VIDIOC_S_CROP:
1666 case VIDIOC_G_FREQUENCY:
1667 case VIDIOC_S_FREQUENCY:
1668 case VIDIOC_ENUMSTD:
1669 case VIDIOC_G_STD:
1670 case VIDIOC_S_STD:
1671 case VIDIOC_S_TUNER:
1672 case VIDIOC_G_TUNER:
1673 case VIDIOC_ENUMAUDIO:
1674 case VIDIOC_S_AUDIO:
1675 case VIDIOC_G_AUDIO:
1676 case VIDIOC_ENUMAUDOUT:
1677 case VIDIOC_S_AUDOUT:
1678 case VIDIOC_G_AUDOUT:
1679 case VIDIOC_G_SLICED_VBI_CAP:
1680 case VIDIOC_LOG_STATUS:
1681 case VIDIOC_G_ENC_INDEX:
1682 case VIDIOC_ENCODER_CMD:
1683 case VIDIOC_TRY_ENCODER_CMD:
1684 case VIDIOC_G_FBUF:
1685 case VIDIOC_S_FBUF:
1686 case VIDIOC_OVERLAY:
1687 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1688 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1689 v4l_printk_ioctl(cmd);
1690 printk("\n");
1691 }
1692 return ivtv_v4l2_ioctls(itv, filp, cmd, arg);
1693 1746
1694 case VIDIOC_QUERYMENU: 1747 case VIDIOC_INT_RESET: {
1695 case VIDIOC_QUERYCTRL: 1748 u32 val = *(u32 *)arg;
1696 case VIDIOC_S_CTRL:
1697 case VIDIOC_G_CTRL:
1698 case VIDIOC_S_EXT_CTRLS:
1699 case VIDIOC_G_EXT_CTRLS:
1700 case VIDIOC_TRY_EXT_CTRLS:
1701 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1702 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1703 v4l_printk_ioctl(cmd);
1704 printk("\n");
1705 }
1706 return ivtv_control_ioctls(itv, cmd, arg);
1707 1749
1708 case IVTV_IOC_DMA_FRAME: 1750 if ((val == 0 && itv->options.newi2c) || (val & 0x01))
1709 case VIDEO_GET_PTS: 1751 ivtv_reset_ir_gpio(itv);
1710 case VIDEO_GET_FRAME_COUNT: 1752 if (val & 0x02)
1711 case VIDEO_GET_EVENT: 1753 itv->video_dec_func(itv, cmd, NULL);
1712 case VIDEO_PLAY: 1754 break;
1713 case VIDEO_STOP: 1755 }
1714 case VIDEO_FREEZE:
1715 case VIDEO_CONTINUE:
1716 case VIDEO_COMMAND:
1717 case VIDEO_TRY_COMMAND:
1718 return ivtv_decoder_ioctls(filp, cmd, arg);
1719 1756
1720 case 0x00005401: /* Handle isatty() calls */
1721 return -EINVAL;
1722 default: 1757 default:
1723 return v4l_compat_translate_ioctl(inode, filp, cmd, arg, 1758 return -EINVAL;
1724 ivtv_v4l2_do_ioctl);
1725 } 1759 }
1726 return 0; 1760 return 0;
1727} 1761}
@@ -1729,7 +1763,10 @@ static int ivtv_v4l2_do_ioctl(struct inode *inode, struct file *filp,
1729static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp, 1763static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct file *filp,
1730 unsigned int cmd, unsigned long arg) 1764 unsigned int cmd, unsigned long arg)
1731{ 1765{
1732 /* Filter dvb ioctls that cannot be handled by video_usercopy */ 1766 struct ivtv_open_id *id = (struct ivtv_open_id *)filp->private_data;
1767 int ret;
1768
1769 /* Filter dvb ioctls that cannot be handled by the v4l ioctl framework */
1733 switch (cmd) { 1770 switch (cmd) {
1734 case VIDEO_SELECT_SOURCE: 1771 case VIDEO_SELECT_SOURCE:
1735 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n"); 1772 IVTV_DEBUG_IOCTL("VIDEO_SELECT_SOURCE\n");
@@ -1758,10 +1795,49 @@ static int ivtv_serialized_ioctl(struct ivtv *itv, struct inode *inode, struct f
1758 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode); 1795 ivtv_vapi(itv, CX2341X_DEC_SET_AUDIO_MODE, 2, itv->audio_bilingual_mode, itv->audio_stereo_mode);
1759 return 0; 1796 return 0;
1760 1797
1798 case IVTV_IOC_DMA_FRAME:
1799 case VIDEO_GET_PTS:
1800 case VIDEO_GET_FRAME_COUNT:
1801 case VIDEO_GET_EVENT:
1802 case VIDEO_PLAY:
1803 case VIDEO_STOP:
1804 case VIDEO_FREEZE:
1805 case VIDEO_CONTINUE:
1806 case VIDEO_COMMAND:
1807 case VIDEO_TRY_COMMAND:
1808 return ivtv_decoder_ioctls(filp, cmd, (void *)arg);
1809
1761 default: 1810 default:
1762 break; 1811 break;
1763 } 1812 }
1764 return video_usercopy(inode, filp, cmd, arg, ivtv_v4l2_do_ioctl); 1813
1814 /* check priority */
1815 switch (cmd) {
1816 case VIDIOC_S_CTRL:
1817 case VIDIOC_S_STD:
1818 case VIDIOC_S_INPUT:
1819 case VIDIOC_S_OUTPUT:
1820 case VIDIOC_S_TUNER:
1821 case VIDIOC_S_FREQUENCY:
1822 case VIDIOC_S_FMT:
1823 case VIDIOC_S_CROP:
1824 case VIDIOC_S_AUDIO:
1825 case VIDIOC_S_AUDOUT:
1826 case VIDIOC_S_EXT_CTRLS:
1827 case VIDIOC_S_FBUF:
1828 case VIDIOC_OVERLAY:
1829 ret = v4l2_prio_check(&itv->prio, &id->prio);
1830 if (ret)
1831 return ret;
1832 }
1833
1834 if (ivtv_debug & IVTV_DBGFLG_IOCTL) {
1835 printk(KERN_INFO "ivtv%d ioctl: ", itv->num);
1836 v4l_printk_ioctl(cmd);
1837 printk("\n");
1838 }
1839
1840 return video_ioctl2(inode, filp, cmd, arg);
1765} 1841}
1766 1842
1767int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, 1843int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
@@ -1776,3 +1852,70 @@ int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
1776 mutex_unlock(&itv->serialize_lock); 1852 mutex_unlock(&itv->serialize_lock);
1777 return res; 1853 return res;
1778} 1854}
1855
1856void ivtv_set_funcs(struct video_device *vdev)
1857{
1858 vdev->vidioc_querycap = ivtv_querycap;
1859 vdev->vidioc_g_priority = ivtv_g_priority;
1860 vdev->vidioc_s_priority = ivtv_s_priority;
1861 vdev->vidioc_s_audio = ivtv_s_audio;
1862 vdev->vidioc_g_audio = ivtv_g_audio;
1863 vdev->vidioc_enumaudio = ivtv_enumaudio;
1864 vdev->vidioc_s_audout = ivtv_s_audout;
1865 vdev->vidioc_g_audout = ivtv_g_audout;
1866 vdev->vidioc_enum_input = ivtv_enum_input;
1867 vdev->vidioc_enum_output = ivtv_enum_output;
1868 vdev->vidioc_enumaudout = ivtv_enumaudout;
1869 vdev->vidioc_cropcap = ivtv_cropcap;
1870 vdev->vidioc_s_crop = ivtv_s_crop;
1871 vdev->vidioc_g_crop = ivtv_g_crop;
1872 vdev->vidioc_g_input = ivtv_g_input;
1873 vdev->vidioc_s_input = ivtv_s_input;
1874 vdev->vidioc_g_output = ivtv_g_output;
1875 vdev->vidioc_s_output = ivtv_s_output;
1876 vdev->vidioc_g_frequency = ivtv_g_frequency;
1877 vdev->vidioc_s_frequency = ivtv_s_frequency;
1878 vdev->vidioc_s_tuner = ivtv_s_tuner;
1879 vdev->vidioc_g_tuner = ivtv_g_tuner;
1880 vdev->vidioc_g_enc_index = ivtv_g_enc_index;
1881 vdev->vidioc_g_fbuf = ivtv_g_fbuf;
1882 vdev->vidioc_s_fbuf = ivtv_s_fbuf;
1883 vdev->vidioc_g_std = ivtv_g_std;
1884 vdev->vidioc_s_std = ivtv_s_std;
1885 vdev->vidioc_overlay = ivtv_overlay;
1886 vdev->vidioc_log_status = ivtv_log_status;
1887 vdev->vidioc_enum_fmt_vid_cap = ivtv_enum_fmt_vid_cap;
1888 vdev->vidioc_encoder_cmd = ivtv_encoder_cmd;
1889 vdev->vidioc_try_encoder_cmd = ivtv_try_encoder_cmd;
1890 vdev->vidioc_enum_fmt_vid_out = ivtv_enum_fmt_vid_out;
1891 vdev->vidioc_g_fmt_vid_cap = ivtv_g_fmt_vid_cap;
1892 vdev->vidioc_g_fmt_vbi_cap = ivtv_g_fmt_vbi_cap;
1893 vdev->vidioc_g_fmt_sliced_vbi_cap = ivtv_g_fmt_sliced_vbi_cap;
1894 vdev->vidioc_g_fmt_vid_out = ivtv_g_fmt_vid_out;
1895 vdev->vidioc_g_fmt_vid_out_overlay = ivtv_g_fmt_vid_out_overlay;
1896 vdev->vidioc_g_fmt_sliced_vbi_out = ivtv_g_fmt_sliced_vbi_out;
1897 vdev->vidioc_s_fmt_vid_cap = ivtv_s_fmt_vid_cap;
1898 vdev->vidioc_s_fmt_vbi_cap = ivtv_s_fmt_vbi_cap;
1899 vdev->vidioc_s_fmt_sliced_vbi_cap = ivtv_s_fmt_sliced_vbi_cap;
1900 vdev->vidioc_s_fmt_vid_out = ivtv_s_fmt_vid_out;
1901 vdev->vidioc_s_fmt_vid_out_overlay = ivtv_s_fmt_vid_out_overlay;
1902 vdev->vidioc_s_fmt_sliced_vbi_out = ivtv_s_fmt_sliced_vbi_out;
1903 vdev->vidioc_try_fmt_vid_cap = ivtv_try_fmt_vid_cap;
1904 vdev->vidioc_try_fmt_vbi_cap = ivtv_try_fmt_vbi_cap;
1905 vdev->vidioc_try_fmt_sliced_vbi_cap = ivtv_try_fmt_sliced_vbi_cap;
1906 vdev->vidioc_try_fmt_vid_out = ivtv_try_fmt_vid_out;
1907 vdev->vidioc_try_fmt_vid_out_overlay = ivtv_try_fmt_vid_out_overlay;
1908 vdev->vidioc_try_fmt_sliced_vbi_out = ivtv_try_fmt_sliced_vbi_out;
1909 vdev->vidioc_g_sliced_vbi_cap = ivtv_g_sliced_vbi_cap;
1910 vdev->vidioc_g_chip_ident = ivtv_g_chip_ident;
1911 vdev->vidioc_g_register = ivtv_g_register;
1912 vdev->vidioc_s_register = ivtv_s_register;
1913 vdev->vidioc_default = ivtv_default;
1914 vdev->vidioc_queryctrl = ivtv_queryctrl;
1915 vdev->vidioc_querymenu = ivtv_querymenu;
1916 vdev->vidioc_g_ctrl = ivtv_g_ctrl;
1917 vdev->vidioc_s_ctrl = ivtv_s_ctrl;
1918 vdev->vidioc_g_ext_ctrls = ivtv_g_ext_ctrls;
1919 vdev->vidioc_s_ext_ctrls = ivtv_s_ext_ctrls;
1920 vdev->vidioc_try_ext_ctrls = ivtv_try_ext_ctrls;
1921}
diff --git a/drivers/media/video/ivtv/ivtv-ioctl.h b/drivers/media/video/ivtv/ivtv-ioctl.h
index 4e67f0ed1fc0..70188588b4f4 100644
--- a/drivers/media/video/ivtv/ivtv-ioctl.h
+++ b/drivers/media/video/ivtv/ivtv-ioctl.h
@@ -24,10 +24,13 @@
24u16 ivtv_service2vbi(int type); 24u16 ivtv_service2vbi(int type);
25void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal); 25void ivtv_expand_service_set(struct v4l2_sliced_vbi_format *fmt, int is_pal);
26u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt); 26u16 ivtv_get_service_set(struct v4l2_sliced_vbi_format *fmt);
27int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
28 unsigned long arg);
29int ivtv_v4l2_ioctls(struct ivtv *itv, struct file *filp, unsigned int cmd, void *arg);
30void ivtv_set_osd_alpha(struct ivtv *itv); 27void ivtv_set_osd_alpha(struct ivtv *itv);
31int ivtv_set_speed(struct ivtv *itv, int speed); 28int ivtv_set_speed(struct ivtv *itv, int speed);
29void ivtv_set_funcs(struct video_device *vdev);
30int ivtv_s_std(struct file *file, void *fh, v4l2_std_id *std);
31int ivtv_s_frequency(struct file *file, void *fh, struct v4l2_frequency *vf);
32int ivtv_s_input(struct file *file, void *fh, unsigned int inp);
33int ivtv_v4l2_ioctl(struct inode *inode, struct file *filp, unsigned int cmd,
34 unsigned long arg);
32 35
33#endif 36#endif
diff --git a/drivers/media/video/ivtv/ivtv-streams.c b/drivers/media/video/ivtv/ivtv-streams.c
index c854285a4371..f8883b487f4a 100644
--- a/drivers/media/video/ivtv/ivtv-streams.c
+++ b/drivers/media/video/ivtv/ivtv-streams.c
@@ -220,7 +220,8 @@ static int ivtv_prep_dev(struct ivtv *itv, int type)
220 s->v4l2dev->dev = &itv->dev->dev; 220 s->v4l2dev->dev = &itv->dev->dev;
221 s->v4l2dev->fops = ivtv_stream_info[type].fops; 221 s->v4l2dev->fops = ivtv_stream_info[type].fops;
222 s->v4l2dev->release = video_device_release; 222 s->v4l2dev->release = video_device_release;
223 223 s->v4l2dev->tvnorms = V4L2_STD_ALL;
224 ivtv_set_funcs(s->v4l2dev);
224 return 0; 225 return 0;
225} 226}
226 227