The patch number 11625 was added via Mauro Carvalho Chehab <mche...@redhat.com>
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        Linux Media Mailing List <linux-me...@vger.kernel.org>

------

From: Mauro Carvalho Chehab  <mche...@redhat.com>
merge: http://linuxtv.org/hg/~awalls/v4l-dvb


Signed-off-by: Mauro Carvalho Chehab <mche...@redhat.com>


---

 linux/drivers/media/video/cx18/cx18-audio.c       |   44 ++++++-
 linux/drivers/media/video/cx18/cx18-av-firmware.c |   82 +++++++++++++-
 linux/drivers/media/video/cx18/cx18-controls.c    |    6 -
 linux/drivers/media/video/cx18/cx18-fileops.c     |    7 +
 4 files changed, 126 insertions(+), 13 deletions(-)

diff -r e6593df11736 -r 0471fb0f32a3 linux/drivers/media/video/cx18/cx18-audio.c
--- a/linux/drivers/media/video/cx18/cx18-audio.c       Tue Apr 28 19:24:32 
2009 -0300
+++ b/linux/drivers/media/video/cx18/cx18-audio.c       Tue Apr 28 19:41:55 
2009 -0300
@@ -26,14 +26,18 @@
 #include "cx18-cards.h"
 #include "cx18-audio.h"
 
-#define CX18_AUDIO_ENABLE 0xc72014
+#define CX18_AUDIO_ENABLE    0xc72014
+#define CX18_AI1_MUX_MASK    0x30
+#define CX18_AI1_MUX_I2S1    0x00
+#define CX18_AI1_MUX_I2S2    0x10
+#define CX18_AI1_MUX_843_I2S 0x20
 
 /* Selects the audio input and output according to the current
    settings. */
 int cx18_audio_set_io(struct cx18 *cx)
 {
        const struct cx18_card_audio_input *in;
-       u32 val;
+       u32 u, v;
        int err;
 
        /* Determine which input to use */
@@ -52,9 +56,37 @@ int cx18_audio_set_io(struct cx18 *cx)
                return err;
 
        /* FIXME - this internal mux should be abstracted to a subdev */
-       val = cx18_read_reg(cx, CX18_AUDIO_ENABLE) & ~0x30;
-       val |= (in->audio_input > CX18_AV_AUDIO_SERIAL2) ? 0x20 :
-                                       (in->audio_input << 4);
-       cx18_write_reg_expect(cx, val | 0xb00, CX18_AUDIO_ENABLE, val, 0x30);
+       u = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
+       v = u & ~CX18_AI1_MUX_MASK;
+       switch (in->audio_input) {
+       case CX18_AV_AUDIO_SERIAL1:
+               v |= CX18_AI1_MUX_I2S1;
+               break;
+       case CX18_AV_AUDIO_SERIAL2:
+               v |= CX18_AI1_MUX_I2S2;
+               break;
+       default:
+               v |= CX18_AI1_MUX_843_I2S;
+               break;
+       }
+       if (v == u) {
+               /* force a toggle of some AI1 MUX control bits */
+               u &= ~CX18_AI1_MUX_MASK;
+               switch (in->audio_input) {
+               case CX18_AV_AUDIO_SERIAL1:
+                       u |= CX18_AI1_MUX_843_I2S;
+                       break;
+               case CX18_AV_AUDIO_SERIAL2:
+                       u |= CX18_AI1_MUX_843_I2S;
+                       break;
+               default:
+                       u |= CX18_AI1_MUX_I2S1;
+                       break;
+               }
+               cx18_write_reg_expect(cx, u | 0xb00, CX18_AUDIO_ENABLE,
+                                     u, CX18_AI1_MUX_MASK);
+       }
+       cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+                             v, CX18_AI1_MUX_MASK);
        return 0;
 }
diff -r e6593df11736 -r 0471fb0f32a3 
linux/drivers/media/video/cx18/cx18-av-firmware.c
--- a/linux/drivers/media/video/cx18/cx18-av-firmware.c Tue Apr 28 19:24:32 
2009 -0300
+++ b/linux/drivers/media/video/cx18/cx18-av-firmware.c Tue Apr 28 19:41:55 
2009 -0300
@@ -24,15 +24,63 @@
 #include "cx18-io.h"
 #include <linux/firmware.h>
 
-#define CX18_AUDIO_ENABLE 0xc72014
+#define CX18_AUDIO_ENABLE    0xc72014
+#define CX18_AI1_MUX_MASK    0x30
+#define CX18_AI1_MUX_I2S1    0x00
+#define CX18_AI1_MUX_I2S2    0x10
+#define CX18_AI1_MUX_843_I2S 0x20
+#define CX18_AI1_MUX_INVALID 0x30
+
 #define FWFILE "v4l-cx23418-dig.fw"
+
+static int cx18_av_verifyfw(struct cx18 *cx, const struct firmware *fw)
+{
+       struct v4l2_subdev *sd = &cx->av_state.sd;
+       int ret = 0;
+       const u8 *data;
+       u32 size;
+       int addr;
+       u32 expected, dl_control;
+
+       /* Ensure we put the 8051 in reset and enable firmware upload mode */
+       dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+       do {
+               dl_control &= 0x00ffffff;
+               dl_control |= 0x0f000000;
+               cx18_av_write4_noretry(cx, CXADEC_DL_CTL, dl_control);
+               dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+       } while ((dl_control & 0xff000000) != 0x0f000000);
+
+       /* Read and auto increment until at address 0x0000 */
+       while (dl_control & 0x3fff)
+               dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+
+       data = fw->data;
+       size = fw->size;
+       for (addr = 0; addr < size; addr++) {
+               dl_control &= 0xffff3fff; /* ignore top 2 bits of address */
+               expected = 0x0f000000 | ((u32)data[addr] << 16) | addr;
+               if (expected != dl_control) {
+                       CX18_ERR_DEV(sd, "verification of %s firmware load "
+                                    "failed: expected %#010x got %#010x\n",
+                                    FWFILE, expected, dl_control);
+                       ret = -EIO;
+                       break;
+               }
+               dl_control = cx18_av_read4(cx, CXADEC_DL_CTL);
+       }
+       if (ret == 0)
+               CX18_INFO_DEV(sd, "verified load of %s firmware (%d bytes)\n",
+                             FWFILE, size);
+       return ret;
+}
 
 int cx18_av_loadfw(struct cx18 *cx)
 {
        struct v4l2_subdev *sd = &cx->av_state.sd;
        const struct firmware *fw = NULL;
        u32 size;
-       u32 v;
+       u32 u, v;
        const u8 *ptr;
        int i;
        int retries1 = 0;
@@ -95,6 +143,12 @@ int cx18_av_loadfw(struct cx18 *cx)
        }
 
        cx18_av_write4_expect(cx, CXADEC_DL_CTL,
+                               0x03000000 | fw->size, 0x03000000, 0x13000000);
+
+       CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
+
+       if (cx18_av_verifyfw(cx, fw) == 0)
+               cx18_av_write4_expect(cx, CXADEC_DL_CTL,
                                0x13000000 | fw->size, 0x13000000, 0x13000000);
 
        /* Output to the 416 */
@@ -135,6 +189,28 @@ int cx18_av_loadfw(struct cx18 *cx)
                cx18_write_reg_expect(cx, v & 0xFFFFFBFF, CX18_AUDIO_ENABLE,
                                      0, 0x400);
 
+       /* Toggle the AI1 MUX */
+       v = cx18_read_reg(cx, CX18_AUDIO_ENABLE);
+       u = v & CX18_AI1_MUX_MASK;
+       v &= ~CX18_AI1_MUX_MASK;
+       if (u == CX18_AI1_MUX_843_I2S || u == CX18_AI1_MUX_INVALID) {
+               /* Switch to I2S1 */
+               v |= CX18_AI1_MUX_I2S1;
+               cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+                                     v, CX18_AI1_MUX_MASK);
+               /* Switch back to the A/V decoder core I2S output */
+               v = (v & ~CX18_AI1_MUX_MASK) | CX18_AI1_MUX_843_I2S;
+       } else {
+               /* Switch to the A/V decoder core I2S output */
+               v |= CX18_AI1_MUX_843_I2S;
+               cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+                                     v, CX18_AI1_MUX_MASK);
+               /* Switch back to I2S1 or I2S2 */
+               v = (v & ~CX18_AI1_MUX_MASK) | u;
+       }
+       cx18_write_reg_expect(cx, v | 0xb00, CX18_AUDIO_ENABLE,
+                             v, CX18_AI1_MUX_MASK);
+
        /* Enable WW auto audio standard detection */
        v = cx18_av_read4(cx, CXADEC_STD_DET_CTL);
        v |= 0xFF;   /* Auto by default */
@@ -143,7 +219,5 @@ int cx18_av_loadfw(struct cx18 *cx)
        cx18_av_write4_expect(cx, CXADEC_STD_DET_CTL, v, v, 0x3F00FFFF);
 
        release_firmware(fw);
-
-       CX18_INFO_DEV(sd, "loaded %s firmware (%d bytes)\n", FWFILE, size);
        return 0;
 }
diff -r e6593df11736 -r 0471fb0f32a3 
linux/drivers/media/video/cx18/cx18-controls.c
--- a/linux/drivers/media/video/cx18/cx18-controls.c    Tue Apr 28 19:24:32 
2009 -0300
+++ b/linux/drivers/media/video/cx18/cx18-controls.c    Tue Apr 28 19:41:55 
2009 -0300
@@ -176,8 +176,10 @@ static int cx18_setup_vbi_fmt(struct cx1
                return -EBUSY;
 
        if (fmt != V4L2_MPEG_STREAM_VBI_FMT_IVTV ||
-           type != V4L2_MPEG_STREAM_TYPE_MPEG2_PS) {
-               /* We don't do VBI insertion aside from IVTV format in a PS */
+           !(type == V4L2_MPEG_STREAM_TYPE_MPEG2_PS ||
+             type == V4L2_MPEG_STREAM_TYPE_MPEG2_DVD ||
+             type == V4L2_MPEG_STREAM_TYPE_MPEG2_SVCD)) {
+               /* Only IVTV fmt VBI insertion & only MPEG-2 PS type streams */
                cx->vbi.insert_mpeg = V4L2_MPEG_STREAM_VBI_FMT_NONE;
                CX18_DEBUG_INFO("disabled insertion of sliced VBI data into "
                                "the MPEG stream\n");
diff -r e6593df11736 -r 0471fb0f32a3 
linux/drivers/media/video/cx18/cx18-fileops.c
--- a/linux/drivers/media/video/cx18/cx18-fileops.c     Tue Apr 28 19:24:32 
2009 -0300
+++ b/linux/drivers/media/video/cx18/cx18-fileops.c     Tue Apr 28 19:41:55 
2009 -0300
@@ -301,8 +301,13 @@ static size_t cx18_copy_buf_to_user(stru
                 * an MPEG-2 Program Pack start code, and provide only
                 * up to that point to the user, so it's easy to insert VBI data
                 * the next time around.
+                *
+                * This will not work for an MPEG-2 TS and has only been
+                * verified by analysis to work for an MPEG-2 PS.  Helen Buus
+                * pointed out this works for the CX23416 MPEG-2 DVD compatible
+                * stream, and research indicates both the MPEG 2 SVCD and DVD
+                * stream types use an MPEG-2 PS container.
                 */
-               /* FIXME - This only works for an MPEG-2 PS, not a TS */
                /*
                 * An MPEG-2 Program Stream (PS) is a series of
                 * MPEG-2 Program Packs terminated by an


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/0471fb0f32a3a438a907c9971cd54e03bf7e8438

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to