aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/cx88/cx88-blackbird.c
diff options
context:
space:
mode:
authorJelle Foks <jelle@foks.8m.com>2007-05-21 13:36:01 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:03:47 -0500
commitf9e54e0c84da869ad9bc372fb4eab26d558dbfc2 (patch)
tree874fa207ad3777aba200d6207f068e49493b0b3a /drivers/media/video/cx88/cx88-blackbird.c
parent4bfae52b69360a966f41ba3308e57a6df41ff8e1 (diff)
V4L/DVB (6828): cx88-blackbird: audio improvements
This patch should fix the 'muted audio' and 'raspy audio' problem for mpeg2 streams out of cx88-blackbird devices. Especially mythtv users would find that the audio would often sound bad (aliased, or 'raspy'), mainly related to channel changes, many (all?) other users would find that there was no audio at all in the mpeg data from the encoder chip, unless the audio was manually unmuted. The patch includes the following modifications: Don't actually start the mpeg2 encoder until the device is read from by the application. Wait until the audio is stable for at least 400ms before starting the mpeg encoder. Mute/Unmute the audio when starting/stopping the mpeg encoder. Stop the mpeg encoder when changing parameters and when changing tuner frequency. Add a variable 'mpeg_active' to struct cx8802_dev to allow tracking of whether or not the mpeg2 encoder is active. Load the firmware on cx88-blackbird driver load. Signed-off-by: Jelle Foks <jelle@foks.8m.com> Signed-off-by: Michael Krufky <mkrufky@linuxtv.org> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/cx88/cx88-blackbird.c')
-rw-r--r--drivers/media/video/cx88/cx88-blackbird.c89
1 files changed, 69 insertions, 20 deletions
diff --git a/drivers/media/video/cx88/cx88-blackbird.c b/drivers/media/video/cx88/cx88-blackbird.c
index f802b5653569..7ce37f46b753 100644
--- a/drivers/media/video/cx88/cx88-blackbird.c
+++ b/drivers/media/video/cx88/cx88-blackbird.c
@@ -536,6 +536,9 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
536 dprintk(1,"Initialize codec\n"); 536 dprintk(1,"Initialize codec\n");
537 retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */ 537 retval = blackbird_api_cmd(dev, CX2341X_ENC_PING_FW, 0, 0); /* ping */
538 if (retval < 0) { 538 if (retval < 0) {
539
540 dev->mpeg_active = 0;
541
539 /* ping was not successful, reset and upload firmware */ 542 /* ping was not successful, reset and upload firmware */
540 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */ 543 cx_write(MO_SRST_IO, 0); /* SYS_RSTO=0 */
541 msleep(1); 544 msleep(1);
@@ -572,38 +575,80 @@ static int blackbird_initialize_codec(struct cx8802_dev *dev)
572 blackbird_codec_settings(dev); 575 blackbird_codec_settings(dev);
573 msleep(1); 576 msleep(1);
574 577
575 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xef, 0xef);
576 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0xf0, 0xf0);
577 blackbird_api_cmd(dev, IVTV_API_ASSIGN_NUM_VSYNC_LINES, 4, 0, 0x180, 0x180); */
578 blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0, 578 blackbird_api_cmd(dev, CX2341X_ENC_SET_NUM_VSYNC_LINES, 2, 0,
579 BLACKBIRD_FIELD1_SAA7115, 579 BLACKBIRD_FIELD1_SAA7115,
580 BLACKBIRD_FIELD2_SAA7115 580 BLACKBIRD_FIELD2_SAA7115
581 ); 581 );
582 582
583 /* blackbird_api_cmd(dev, IVTV_API_ASSIGN_PLACEHOLDER, 12, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); */
584 blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0, 583 blackbird_api_cmd(dev, CX2341X_ENC_SET_PLACEHOLDER, 12, 0,
585 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA, 584 BLACKBIRD_CUSTOM_EXTENSION_USR_DATA,
586 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0); 585 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
587 586
588 /* initialize the video input */
589 blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
590
591 msleep(1); 587 msleep(1);
588 return 0;
589}
590
591static int blackbird_start_codec(struct file *file, void *priv)
592{
593 struct cx8802_dev *dev = ((struct cx8802_fh *)priv)->dev;
594 struct cx88_core *core = dev->core;
595 /* start capturing to the host interface */
596 u32 reg;
597
598 int i;
599 int lastchange = -1;
600 int lastval = 0;
601
602 for (i=0; (i < 10) && (i < (lastchange + 4)); i++)
603 {
604 reg = cx_read(AUD_STATUS);
605
606 dprintk(1,"AUD_STATUS:%dL: 0x%x\n", i, reg);
607 if ((reg & 0x0F) != lastval)
608 {
609 lastval = reg & 0x0F;
610 lastchange = i;
611 }
612 msleep(100);
613 }
614
615 /* unmute audio source */
616 cx_clear(AUD_VOL_CTL, (1 << 6));
592 617
593 blackbird_api_cmd(dev, CX2341X_ENC_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE); 618 blackbird_api_cmd(dev, CX2341X_ENC_MUTE_VIDEO, 1, 0, BLACKBIRD_UNMUTE);
594 msleep(1); 619 msleep(1);
595 blackbird_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE); 620 blackbird_api_cmd(dev, CX2341X_ENC_MUTE_AUDIO, 1, 0, BLACKBIRD_UNMUTE);
596 msleep(1); 621 msleep(1);
597 622
623 blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0,0);
624
625 /* initialize the video input */
626 blackbird_api_cmd(dev, CX2341X_ENC_INITIALIZE_INPUT, 0, 0);
627
598 /* start capturing to the host interface */ 628 /* start capturing to the host interface */
599 /* blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, 0, 0x13); */
600 blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0, 629 blackbird_api_cmd(dev, CX2341X_ENC_START_CAPTURE, 2, 0,
601 BLACKBIRD_MPEG_CAPTURE, 630 BLACKBIRD_MPEG_CAPTURE,
602 BLACKBIRD_RAW_BITS_NONE 631 BLACKBIRD_RAW_BITS_NONE
603 ); 632 );
604 msleep(10); 633 msleep(10);
605 634
606 blackbird_api_cmd(dev, CX2341X_ENC_REFRESH_INPUT, 0,0); 635 dev->mpeg_active = 1;
636 return 0;
637}
638
639static int blackbird_stop_codec(struct cx8802_dev *dev)
640{
641 struct cx88_core *core = dev->core;
642
643 blackbird_api_cmd(dev, CX2341X_ENC_STOP_CAPTURE, 3, 0,
644 BLACKBIRD_END_NOW,
645 BLACKBIRD_MPEG_CAPTURE,
646 BLACKBIRD_RAW_BITS_NONE
647 );
648 /* mute audio source */
649 cx_set(AUD_VOL_CTL, (1 << 6));
650
651 dev->mpeg_active = 0;
607 return 0; 652 return 0;
608} 653}
609 654
@@ -833,6 +878,10 @@ static int vidioc_s_ext_ctrls (struct file *file, void *priv,
833 878
834 if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG) 879 if (f->ctrl_class != V4L2_CTRL_CLASS_MPEG)
835 return -EINVAL; 880 return -EINVAL;
881
882 if (dev->mpeg_active)
883 blackbird_stop_codec(dev);
884
836 p = dev->params; 885 p = dev->params;
837 err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS); 886 err = cx2341x_ext_ctrls(&p, 0, f, VIDIOC_S_EXT_CTRLS);
838 if (!err) { 887 if (!err) {
@@ -864,10 +913,9 @@ static int vidioc_s_frequency (struct file *file, void *priv,
864 struct cx8802_dev *dev = fh->dev; 913 struct cx8802_dev *dev = fh->dev;
865 struct cx88_core *core = dev->core; 914 struct cx88_core *core = dev->core;
866 915
867 blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, 916 if (dev->mpeg_active)
868 BLACKBIRD_END_NOW, 917 blackbird_stop_codec(dev);
869 BLACKBIRD_MPEG_CAPTURE, 918
870 BLACKBIRD_RAW_BITS_NONE);
871 cx88_set_freq (core,f); 919 cx88_set_freq (core,f);
872 blackbird_initialize_codec(dev); 920 blackbird_initialize_codec(dev);
873 cx88_set_scale(dev->core, dev->width, dev->height, 921 cx88_set_scale(dev->core, dev->width, dev->height,
@@ -1073,15 +1121,11 @@ static int mpeg_open(struct inode *inode, struct file *file)
1073static int mpeg_release(struct inode *inode, struct file *file) 1121static int mpeg_release(struct inode *inode, struct file *file)
1074{ 1122{
1075 struct cx8802_fh *fh = file->private_data; 1123 struct cx8802_fh *fh = file->private_data;
1076 struct cx8802_dev *dev = NULL; 1124 struct cx8802_dev *dev = fh->dev;
1077 struct cx8802_driver *drv = NULL; 1125 struct cx8802_driver *drv = NULL;
1078 1126
1079 /* blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, BLACKBIRD_END_NOW, 0, 0x13); */ 1127 if (dev->mpeg_active)
1080 blackbird_api_cmd(fh->dev, CX2341X_ENC_STOP_CAPTURE, 3, 0, 1128 blackbird_stop_codec(dev);
1081 BLACKBIRD_END_NOW,
1082 BLACKBIRD_MPEG_CAPTURE,
1083 BLACKBIRD_RAW_BITS_NONE
1084 );
1085 1129
1086 cx8802_cancel_buffers(fh->dev); 1130 cx8802_cancel_buffers(fh->dev);
1087 /* stop mpeg capture */ 1131 /* stop mpeg capture */
@@ -1107,6 +1151,10 @@ static ssize_t
1107mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos) 1151mpeg_read(struct file *file, char __user *data, size_t count, loff_t *ppos)
1108{ 1152{
1109 struct cx8802_fh *fh = file->private_data; 1153 struct cx8802_fh *fh = file->private_data;
1154 struct cx8802_dev *dev = fh->dev;
1155
1156 if (!dev->mpeg_active)
1157 blackbird_start_codec(file, fh);
1110 1158
1111 return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0, 1159 return videobuf_read_stream(&fh->mpegq, data, count, ppos, 0,
1112 file->f_flags & O_NONBLOCK); 1160 file->f_flags & O_NONBLOCK);
@@ -1282,6 +1330,7 @@ static int cx8802_blackbird_probe(struct cx8802_driver *drv)
1282 core->name); 1330 core->name);
1283 host_setup(dev->core); 1331 host_setup(dev->core);
1284 1332
1333 blackbird_initialize_codec(dev);
1285 blackbird_register_video(dev); 1334 blackbird_register_video(dev);
1286 1335
1287 /* initial device configuration: needed ? */ 1336 /* initial device configuration: needed ? */