aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx18
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-02-06 16:33:43 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:39 -0400
commitdcc0ef88209a26719241bcb7741f05f1b9ecc30e (patch)
tree2c1f352821c648c42b775b7fff5cf86366a0e2ba /drivers/media/video/cx18
parentc1994084d6ad7d1a411219727fc135a18c40f9c8 (diff)
V4L/DVB (10442): cx18: Fixes for enforcing when Encoder Raw VBI params can be set
The Encoder will only allow the Raw VBI parameters, along with a number of other API parameters, to take effect when no analog captures are in progress. These parameters must be set before the first analog capture starts, be it MPEG, VBI, YUV, etc., and cannot be changed until the last one stops. It is not obvious to me what capture channel API parameters are shared and which ones must be set per capture channel, so set them all for every analog capture channel start up. This fixes the driver so that VBI capture can be started up after the MPEG capture is going. Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/cx18')
-rw-r--r--drivers/media/video/cx18/cx18-ioctl.c20
-rw-r--r--drivers/media/video/cx18/cx18-streams.c79
2 files changed, 71 insertions, 28 deletions
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c
index a454ede568a5..0f0cd560226c 100644
--- a/drivers/media/video/cx18/cx18-ioctl.c
+++ b/drivers/media/video/cx18/cx18-ioctl.c
@@ -42,13 +42,6 @@
42#include <media/v4l2-chip-ident.h> 42#include <media/v4l2-chip-ident.h>
43#include <linux/i2c-id.h> 43#include <linux/i2c-id.h>
44 44
45static int cx18_vbi_streaming(struct cx18 *cx)
46{
47 struct cx18_stream *s_vbi = &cx->streams[CX18_ENC_STREAM_TYPE_VBI];
48 return (s_vbi->handle != CX18_INVALID_TASK_HANDLE) &&
49 test_bit(CX18_F_S_STREAMING, &s_vbi->s_flags);
50}
51
52u16 cx18_service2vbi(int type) 45u16 cx18_service2vbi(int type)
53{ 46{
54 switch (type) { 47 switch (type) {
@@ -312,7 +305,11 @@ static int cx18_s_fmt_vbi_cap(struct file *file, void *fh,
312 if (ret) 305 if (ret)
313 return ret; 306 return ret;
314 307
315 if (!cx18_raw_vbi(cx) && cx18_vbi_streaming(cx)) 308 /*
309 * Changing the Encoder's Raw VBI parameters won't have any effect
310 * if any analog capture is ongoing
311 */
312 if (!cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
316 return -EBUSY; 313 return -EBUSY;
317 314
318 /* 315 /*
@@ -345,8 +342,13 @@ static int cx18_s_fmt_sliced_vbi_cap(struct file *file, void *fh,
345 342
346 cx18_try_fmt_sliced_vbi_cap(file, fh, fmt); 343 cx18_try_fmt_sliced_vbi_cap(file, fh, fmt);
347 344
348 if (cx18_raw_vbi(cx) && cx18_vbi_streaming(cx)) 345 /*
346 * Changing the Encoder's Raw VBI parameters won't have any effect
347 * if any analog capture is ongoing
348 */
349 if (cx18_raw_vbi(cx) && atomic_read(&cx->ana_capturing) > 0)
349 return -EBUSY; 350 return -EBUSY;
351
350 /* 352 /*
351 * Set the service_lines requested in the digitizer/slicer registers. 353 * Set the service_lines requested in the digitizer/slicer registers.
352 * Note, cx18_av_vbi() wipes some "impossible" service lines in the 354 * Note, cx18_av_vbi() wipes some "impossible" service lines in the
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c
index a89f7f840d95..f074fdb29b8e 100644
--- a/drivers/media/video/cx18/cx18-streams.c
+++ b/drivers/media/video/cx18/cx18-streams.c
@@ -349,6 +349,14 @@ static void cx18_vbi_setup(struct cx18_stream *s)
349 /* setup VBI registers */ 349 /* setup VBI registers */
350 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in); 350 cx18_av_cmd(cx, VIDIOC_S_FMT, &cx->vbi.in);
351 351
352 /*
353 * Send the CX18_CPU_SET_RAW_VBI_PARAM API command to setup Encoder Raw
354 * VBI when the first analog capture channel starts, as once it starts
355 * (e.g. MPEG), we can't effect any change in the Encoder Raw VBI setup
356 * (i.e. for the VBI capture channels). We also send it for each
357 * analog capture channel anyway just to make sure we get the proper
358 * behavior
359 */
352 if (raw) { 360 if (raw) {
353 lines = cx->vbi.count * 2; 361 lines = cx->vbi.count * 2;
354 } else { 362 } else {
@@ -410,8 +418,7 @@ static void cx18_vbi_setup(struct cx18_stream *s)
410 CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n", 418 CX18_DEBUG_INFO("Setup VBI h: %d lines %x bpl %d fr %d %x %x\n",
411 data[0], data[1], data[2], data[3], data[4], data[5]); 419 data[0], data[1], data[2], data[3], data[4], data[5]);
412 420
413 if (s->type == CX18_ENC_STREAM_TYPE_VBI) 421 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
414 cx18_api(cx, CX18_CPU_SET_RAW_VBI_PARAM, 6, data);
415} 422}
416 423
417struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s, 424struct cx18_queue *cx18_stream_put_buf_fw(struct cx18_stream *s,
@@ -460,8 +467,8 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
460 u32 data[MAX_MB_ARGUMENTS]; 467 u32 data[MAX_MB_ARGUMENTS];
461 struct cx18 *cx = s->cx; 468 struct cx18 *cx = s->cx;
462 struct cx18_buffer *buf; 469 struct cx18_buffer *buf;
463 int ts = 0;
464 int captype = 0; 470 int captype = 0;
471 struct cx18_api_func_private priv;
465 472
466 if (s->video_dev == NULL && s->dvb.enabled == 0) 473 if (s->video_dev == NULL && s->dvb.enabled == 0)
467 return -EINVAL; 474 return -EINVAL;
@@ -479,7 +486,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
479 486
480 case CX18_ENC_STREAM_TYPE_TS: 487 case CX18_ENC_STREAM_TYPE_TS:
481 captype = CAPTURE_CHANNEL_TYPE_TS; 488 captype = CAPTURE_CHANNEL_TYPE_TS;
482 ts = 1;
483 break; 489 break;
484 case CX18_ENC_STREAM_TYPE_YUV: 490 case CX18_ENC_STREAM_TYPE_YUV:
485 captype = CAPTURE_CHANNEL_TYPE_YUV; 491 captype = CAPTURE_CHANNEL_TYPE_YUV;
@@ -488,8 +494,16 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
488 captype = CAPTURE_CHANNEL_TYPE_PCM; 494 captype = CAPTURE_CHANNEL_TYPE_PCM;
489 break; 495 break;
490 case CX18_ENC_STREAM_TYPE_VBI: 496 case CX18_ENC_STREAM_TYPE_VBI:
497#ifdef CX18_ENCODER_PARSES_SLICED
491 captype = cx18_raw_vbi(cx) ? 498 captype = cx18_raw_vbi(cx) ?
492 CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI; 499 CAPTURE_CHANNEL_TYPE_VBI : CAPTURE_CHANNEL_TYPE_SLICED_VBI;
500#else
501 /*
502 * Currently we set things up so that Sliced VBI from the
503 * digitizer is handled as Raw VBI by the encoder
504 */
505 captype = CAPTURE_CHANNEL_TYPE_VBI;
506#endif
493 cx->vbi.frame = 0; 507 cx->vbi.frame = 0;
494 cx->vbi.inserted_frame = 0; 508 cx->vbi.inserted_frame = 0;
495 memset(cx->vbi.sliced_mpeg_size, 509 memset(cx->vbi.sliced_mpeg_size,
@@ -499,10 +513,6 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
499 return -EINVAL; 513 return -EINVAL;
500 } 514 }
501 515
502 /* mute/unmute video */
503 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2,
504 s->handle, !!test_bit(CX18_F_I_RADIO_USER, &cx->i_flags));
505
506 /* Clear Streamoff flags in case left from last capture */ 516 /* Clear Streamoff flags in case left from last capture */
507 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags); 517 clear_bit(CX18_F_S_STREAMOFF, &s->s_flags);
508 518
@@ -510,31 +520,62 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
510 s->handle = data[0]; 520 s->handle = data[0];
511 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype); 521 cx18_vapi(cx, CX18_CPU_SET_CHANNEL_TYPE, 2, s->handle, captype);
512 522
513 if (atomic_read(&cx->ana_capturing) == 0 && !ts) { 523 /*
514 struct cx18_api_func_private priv; 524 * For everything but CAPTURE_CHANNEL_TYPE_TS, play it safe and
515 525 * set up all the parameters, as it is not obvious which parameters the
516 /* Stuff from Windows, we don't know what it is */ 526 * firmware shares across capture channel types and which it does not.
527 *
528 * Some of the cx18_vapi() calls below apply to only certain capture
529 * channel types. We're hoping there's no harm in calling most of them
530 * anyway, as long as the values are all consistent. Setting some
531 * shared parameters will have no effect once an analog capture channel
532 * has started streaming.
533 */
534 if (captype != CAPTURE_CHANNEL_TYPE_TS) {
517 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0); 535 cx18_vapi(cx, CX18_CPU_SET_VER_CROP_LINE, 2, s->handle, 0);
518 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1); 536 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 3, 1);
519 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0); 537 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 8, 0);
520 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1); 538 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 3, s->handle, 4, 1);
521 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, s->handle, 12);
522 539
540 /*
541 * Audio related reset according to
542 * Documentation/video4linux/cx2341x/fw-encoder-api.txt
543 */
544 if (atomic_read(&cx->ana_capturing) == 0)
545 cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2,
546 s->handle, 12);
547
548 /*
549 * Number of lines for Field 1 & Field 2 according to
550 * Documentation/video4linux/cx2341x/fw-encoder-api.txt
551 * FIXME - currently we set this to 0 & 0 but things seem OK
552 */
523 cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3, 553 cx18_vapi(cx, CX18_CPU_SET_CAPTURE_LINE_NO, 3,
524 s->handle, cx->digitizer, cx->digitizer); 554 s->handle, cx->digitizer, cx->digitizer);
525 555
526 /* Setup VBI */
527 if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE) 556 if (cx->v4l2_cap & V4L2_CAP_VBI_CAPTURE)
528 cx18_vbi_setup(s); 557 cx18_vbi_setup(s);
529 558
530 /* assign program index info. 559 /*
531 Mask 7: select I/P/B, Num_req: 400 max */ 560 * assign program index info.
561 * Mask 7: select I/P/B, Num_req: 400 max
562 * FIXME - currently we have this hardcoded as disabled
563 */
532 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0); 564 cx18_vapi_result(cx, data, CX18_CPU_SET_INDEXTABLE, 1, 0);
533 565
534 /* Setup API for Stream */ 566 /* Call out to the common CX2341x API setup for user controls */
535 priv.cx = cx; 567 priv.cx = cx;
536 priv.s = s; 568 priv.s = s;
537 cx2341x_update(&priv, cx18_api_func, NULL, &cx->params); 569 cx2341x_update(&priv, cx18_api_func, NULL, &cx->params);
570
571 /*
572 * When starting a capture and we're set for radio,
573 * ensure the video is muted, despite the user control.
574 */
575 if (!cx->params.video_mute &&
576 test_bit(CX18_F_I_RADIO_USER, &cx->i_flags))
577 cx18_vapi(cx, CX18_CPU_SET_VIDEO_MUTE, 2, s->handle,
578 (cx->params.video_mute_yuv << 8) | 1);
538 } 579 }
539 580
540 if (atomic_read(&cx->tot_capturing) == 0) { 581 if (atomic_read(&cx->tot_capturing) == 0) {
@@ -578,7 +619,7 @@ int cx18_start_v4l2_encode_stream(struct cx18_stream *s)
578 } 619 }
579 620
580 /* you're live! sit back and await interrupts :) */ 621 /* you're live! sit back and await interrupts :) */
581 if (!ts) 622 if (captype != CAPTURE_CHANNEL_TYPE_TS)
582 atomic_inc(&cx->ana_capturing); 623 atomic_inc(&cx->ana_capturing);
583 atomic_inc(&cx->tot_capturing); 624 atomic_inc(&cx->tot_capturing);
584 return 0; 625 return 0;