aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Walls <awalls@radix.net>2009-01-03 12:21:30 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:42:25 -0400
commit31230c5f6f3a3e549f16857b7af45f5e08ca6f30 (patch)
treef85d51e5b8be166301a9c5f72962b6819f8d8c5b
parent0d82fe801d7c6d8cb8987e66b570f6decde9e235 (diff)
V4L/DVB (10277): cx18, cx2341x: Fix bugs in cx18 AC3 control and comply with V4L2 spec
Fix bugs in the cx18 AC3 control implementation that would have affected ivtv and other drivers via the cx2341x module. Bring AC3 controls behavior into comliance with V4L2 specification. Thanks to Hans Verkuil for reviewing the previous patch and pointing out the problems. Reported-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Andy Walls <awalls@radix.net> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/cx18/cx18-driver.c3
-rw-r--r--drivers/media/video/cx2341x.c46
-rw-r--r--include/media/cx2341x.h1
3 files changed, 36 insertions, 14 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c
index f9df3cc5aa3d..7e455fdcf774 100644
--- a/drivers/media/video/cx18/cx18-driver.c
+++ b/drivers/media/video/cx18/cx18-driver.c
@@ -587,8 +587,7 @@ static int __devinit cx18_init_struct1(struct cx18 *cx)
587 (cx->params.video_temporal_filter_mode << 1) | 587 (cx->params.video_temporal_filter_mode << 1) |
588 (cx->params.video_median_filter_type << 2); 588 (cx->params.video_median_filter_type << 2);
589 cx->params.port = CX2341X_PORT_MEMORY; 589 cx->params.port = CX2341X_PORT_MEMORY;
590 cx->params.capabilities = CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_AC3 | 590 cx->params.capabilities = CX2341X_CAP_HAS_TS | CX2341X_CAP_HAS_AC3;
591 CX2341X_CAP_HAS_LPCM;
592 init_waitqueue_head(&cx->cap_w); 591 init_waitqueue_head(&cx->cap_w);
593 init_waitqueue_head(&cx->mb_apu_waitq); 592 init_waitqueue_head(&cx->mb_apu_waitq);
594 init_waitqueue_head(&cx->mb_cpu_waitq); 593 init_waitqueue_head(&cx->mb_cpu_waitq);
diff --git a/drivers/media/video/cx2341x.c b/drivers/media/video/cx2341x.c
index 0acfacfa9436..6f4821616f75 100644
--- a/drivers/media/video/cx2341x.c
+++ b/drivers/media/video/cx2341x.c
@@ -263,10 +263,10 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
263 case V4L2_CID_MPEG_AUDIO_ENCODING: 263 case V4L2_CID_MPEG_AUDIO_ENCODING:
264 if (busy) 264 if (busy)
265 return -EBUSY; 265 return -EBUSY;
266 if (params->capabilities & CX2341X_CAP_HAS_AC3 && 266 if (params->capabilities & CX2341X_CAP_HAS_AC3)
267 ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 && 267 if (ctrl->value != V4L2_MPEG_AUDIO_ENCODING_LAYER_2 &&
268 ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3) 268 ctrl->value != V4L2_MPEG_AUDIO_ENCODING_AC3)
269 return -EINVAL; 269 return -ERANGE;
270 params->audio_encoding = ctrl->value; 270 params->audio_encoding = ctrl->value;
271 break; 271 break;
272 case V4L2_CID_MPEG_AUDIO_L2_BITRATE: 272 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
@@ -277,6 +277,8 @@ static int cx2341x_set_ctrl(struct cx2341x_mpeg_params *params, int busy,
277 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: 277 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
278 if (busy) 278 if (busy)
279 return -EBUSY; 279 return -EBUSY;
280 if (!(params->capabilities & CX2341X_CAP_HAS_AC3))
281 return -EINVAL;
280 params->audio_ac3_bitrate = ctrl->value; 282 params->audio_ac3_bitrate = ctrl->value;
281 break; 283 break;
282 case V4L2_CID_MPEG_AUDIO_MODE: 284 case V4L2_CID_MPEG_AUDIO_MODE:
@@ -498,11 +500,18 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
498 500
499 switch (qctrl->id) { 501 switch (qctrl->id) {
500 case V4L2_CID_MPEG_AUDIO_ENCODING: 502 case V4L2_CID_MPEG_AUDIO_ENCODING:
501 if (params->capabilities & CX2341X_CAP_HAS_AC3) 503 if (params->capabilities & CX2341X_CAP_HAS_AC3) {
504 /*
505 * The state of L2 & AC3 bitrate controls can change
506 * when this control changes, but v4l2_ctrl_query_fill()
507 * already sets V4L2_CTRL_FLAG_UPDATE for
508 * V4L2_CID_MPEG_AUDIO_ENCODING, so we don't here.
509 */
502 return v4l2_ctrl_query_fill(qctrl, 510 return v4l2_ctrl_query_fill(qctrl,
503 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 511 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
504 V4L2_MPEG_AUDIO_ENCODING_AC3, 1, 512 V4L2_MPEG_AUDIO_ENCODING_AC3, 1,
505 default_params.audio_encoding); 513 default_params.audio_encoding);
514 }
506 515
507 return v4l2_ctrl_query_fill(qctrl, 516 return v4l2_ctrl_query_fill(qctrl,
508 V4L2_MPEG_AUDIO_ENCODING_LAYER_2, 517 V4L2_MPEG_AUDIO_ENCODING_LAYER_2,
@@ -510,20 +519,35 @@ int cx2341x_ctrl_query(const struct cx2341x_mpeg_params *params,
510 default_params.audio_encoding); 519 default_params.audio_encoding);
511 520
512 case V4L2_CID_MPEG_AUDIO_L2_BITRATE: 521 case V4L2_CID_MPEG_AUDIO_L2_BITRATE:
513 return v4l2_ctrl_query_fill(qctrl, 522 err = v4l2_ctrl_query_fill(qctrl,
514 V4L2_MPEG_AUDIO_L2_BITRATE_192K, 523 V4L2_MPEG_AUDIO_L2_BITRATE_192K,
515 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1, 524 V4L2_MPEG_AUDIO_L2_BITRATE_384K, 1,
516 default_params.audio_l2_bitrate); 525 default_params.audio_l2_bitrate);
526 if (err)
527 return err;
528 if (params->capabilities & CX2341X_CAP_HAS_AC3 &&
529 params->audio_encoding != V4L2_MPEG_AUDIO_ENCODING_LAYER_2)
530 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
531 return 0;
517 532
518 case V4L2_CID_MPEG_AUDIO_L1_BITRATE: 533 case V4L2_CID_MPEG_AUDIO_L1_BITRATE:
519 case V4L2_CID_MPEG_AUDIO_L3_BITRATE: 534 case V4L2_CID_MPEG_AUDIO_L3_BITRATE:
520 return -EINVAL; 535 return -EINVAL;
521 536
522 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE: 537 case V4L2_CID_MPEG_AUDIO_AC3_BITRATE:
523 return v4l2_ctrl_query_fill(qctrl, 538 err = v4l2_ctrl_query_fill(qctrl,
524 V4L2_MPEG_AUDIO_AC3_BITRATE_48K, 539 V4L2_MPEG_AUDIO_AC3_BITRATE_48K,
525 V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1, 540 V4L2_MPEG_AUDIO_AC3_BITRATE_448K, 1,
526 default_params.audio_ac3_bitrate); 541 default_params.audio_ac3_bitrate);
542 if (err)
543 return err;
544 if (params->capabilities & CX2341X_CAP_HAS_AC3) {
545 if (params->audio_encoding !=
546 V4L2_MPEG_AUDIO_ENCODING_AC3)
547 qctrl->flags |= V4L2_CTRL_FLAG_INACTIVE;
548 } else
549 qctrl->flags |= V4L2_CTRL_FLAG_DISABLED;
550 return 0;
527 551
528 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION: 552 case V4L2_CID_MPEG_AUDIO_MODE_EXTENSION:
529 err = v4l2_ctrl_query_fill_std(qctrl); 553 err = v4l2_ctrl_query_fill_std(qctrl);
@@ -771,9 +795,9 @@ const char **cx2341x_ctrl_get_menu(const struct cx2341x_mpeg_params *p, u32 id)
771EXPORT_SYMBOL(cx2341x_ctrl_get_menu); 795EXPORT_SYMBOL(cx2341x_ctrl_get_menu);
772 796
773/* definitions for audio properties bits 29-28 */ 797/* definitions for audio properties bits 29-28 */
774#define CX2341X_AUDIO_ENCDING_METHOD_MPEG 0 798#define CX2341X_AUDIO_ENCODING_METHOD_MPEG 0
775#define CX2341X_AUDIO_ENCDING_METHOD_AC3 1 799#define CX2341X_AUDIO_ENCODING_METHOD_AC3 1
776#define CX2341X_AUDIO_ENCDING_METHOD_LPCM 2 800#define CX2341X_AUDIO_ENCODING_METHOD_LPCM 2
777 801
778static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params) 802static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
779{ 803{
@@ -791,7 +815,7 @@ static void cx2341x_calc_audio_properties(struct cx2341x_mpeg_params *params)
791 /* Not sure if this MPEG Layer II setting is required */ 815 /* Not sure if this MPEG Layer II setting is required */
792 ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) | 816 ((3 - V4L2_MPEG_AUDIO_ENCODING_LAYER_2) << 2) |
793 (params->audio_ac3_bitrate << 4) | 817 (params->audio_ac3_bitrate << 4) |
794 (CX2341X_AUDIO_ENCDING_METHOD_AC3 << 28); 818 (CX2341X_AUDIO_ENCODING_METHOD_AC3 << 28);
795 } else { 819 } else {
796 /* Assuming MPEG Layer II */ 820 /* Assuming MPEG Layer II */
797 params->audio_properties |= 821 params->audio_properties |=
diff --git a/include/media/cx2341x.h b/include/media/cx2341x.h
index 2601bc71c51d..9ebe8558b9b6 100644
--- a/include/media/cx2341x.h
+++ b/include/media/cx2341x.h
@@ -29,7 +29,6 @@ enum cx2341x_cap {
29 CX2341X_CAP_HAS_SLICED_VBI = 1 << 0, 29 CX2341X_CAP_HAS_SLICED_VBI = 1 << 0,
30 CX2341X_CAP_HAS_TS = 1 << 1, 30 CX2341X_CAP_HAS_TS = 1 << 1,
31 CX2341X_CAP_HAS_AC3 = 1 << 2, 31 CX2341X_CAP_HAS_AC3 = 1 << 2,
32 CX2341X_CAP_HAS_LPCM = 1 << 3,
33}; 32};
34 33
35struct cx2341x_mpeg_params { 34struct cx2341x_mpeg_params {