[PATCH] V4L: Add workaround for Hauppauge PVR150 with certain NTSC tuner models
authorHans Verkuil <hverkuil@xs4all.nl>
Thu, 1 Dec 2005 08:51:42 +0000 (00:51 -0800)
committerLinus Torvalds <torvalds@g5.osdl.org>
Thu, 1 Dec 2005 23:48:58 +0000 (15:48 -0800)
Add workaround for Hauppauge PVR150 hardware problem with tuner models 85, 99
and 112 (model numbers as reported by tveeprom).  The audio standard
autodetection does not always work correctly for these models.

Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
drivers/media/video/cx25840/cx25840-core.c
drivers/media/video/cx25840/cx25840.h
drivers/media/video/tveeprom.c
include/media/tveeprom.h

index 539db129a9f4a69352d3b54f0439243aa8a30c43..aea3f038cff6a1b5a8ce5aa8743893e8da6beb97 100644 (file)
@@ -208,8 +208,11 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw)
 
 static void input_change(struct i2c_client *client)
 {
+       struct cx25840_state *state = i2c_get_clientdata(client);
        v4l2_std_id std = cx25840_get_v4lstd(client);
 
+       /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC
+          instead of V4L2_STD_PAL. Someone needs to test this. */
        if (std & V4L2_STD_PAL) {
                /* Follow tuner change procedure for PAL */
                cx25840_write(client, 0x808, 0xff);
@@ -220,7 +223,32 @@ static void input_change(struct i2c_client *client)
                cx25840_write(client, 0x80b, 0x10);
        } else if (std & V4L2_STD_NTSC) {
                /* NTSC */
-               cx25840_write(client, 0x808, 0xf6);
+               if (state->cardtype == CARDTYPE_PVR150_WORKAROUND) {
+                       /* Certain Hauppauge PVR150 models have a hardware bug
+                          that causes audio to drop out. For these models the
+                          audio standard must be set explicitly.
+                          To be precise: it affects cards with tuner models
+                          85, 99 and 112 (model numbers from tveeprom). */
+                       if (std == V4L2_STD_NTSC_M_JP) {
+                               /* Japan uses EIAJ audio standard */
+                               cx25840_write(client, 0x808, 0x2f);
+                       } else {
+                               /* Others use the BTSC audio standard */
+                               cx25840_write(client, 0x808, 0x1f);
+                       }
+                       /* South Korea uses the A2-M (aka Zweiton M) audio
+                          standard, and should set 0x808 to 0x3f, but I don't
+                          know how to detect this. */
+               } else if (std == V4L2_STD_NTSC_M_JP) {
+                       /* Japan uses EIAJ audio standard */
+                       cx25840_write(client, 0x808, 0xf7);
+               } else {
+                       /* Others use the BTSC audio standard */
+                       cx25840_write(client, 0x808, 0xf6);
+               }
+               /* South Korea uses the A2-M (aka Zweiton M) audio standard,
+                  and should set 0x808 to 0xf8, but I don't know how to
+                  detect this. */
                cx25840_write(client, 0x80b, 0x00);
        }
 
@@ -241,7 +269,8 @@ static int set_input(struct i2c_client *client, enum cx25840_input input)
        case CX25840_TUNER:
                cx25840_dbg("now setting Tuner input\n");
 
-               if (state->cardtype == CARDTYPE_PVR150) {
+               if (state->cardtype == CARDTYPE_PVR150 ||
+                   state->cardtype == CARDTYPE_PVR150_WORKAROUND) {
                        /* CH_SEL_ADC2=1 */
                        cx25840_and_or(client, 0x102, ~0x2, 0x02);
                }
@@ -363,6 +392,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
        case CX25840_CID_CARDTYPE:
                switch (ctrl->value) {
                case CARDTYPE_PVR150:
+               case CARDTYPE_PVR150_WORKAROUND:
                case CARDTYPE_PG600:
                        state->cardtype = ctrl->value;
                        break;
index 5c3f0639fb779a4da987a9d6632cc7c5d59e0f62..4932ed1c9b199bcd74fe381d0c48dee2366e3817 100644 (file)
@@ -40,9 +40,16 @@ extern int cx25840_debug;
 
 #define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0)
 
+/* The CARDTYPE_PVR150_WORKAROUND cardtype activates a workaround for a
+   hardware bug that is present in PVR150 (and possible PVR500) cards that
+   have certain NTSC tuners (tveeprom model numbers 85, 99 and 112). The
+   audio autodetect fails on some channels for these models and the workaround
+   is to select the audio standard explicitly. Many thanks to Hauppauge for
+   providing this information. */
 enum cx25840_cardtype {
        CARDTYPE_PVR150,
-       CARDTYPE_PG600
+       CARDTYPE_PG600,
+       CARDTYPE_PVR150_WORKAROUND,
 };
 
 enum cx25840_input {
index f048fd44f0e2d9515daec9fb79bc1aef1ce0cf3f..3a986c2a0f7230f657a00188fcdbef2deea01363 100644 (file)
@@ -339,6 +339,7 @@ static int hasRadioTuner(int tunerType)
                case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
                case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
                case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
+               case 105:
                return 1;
        }
        return 0;
@@ -596,6 +597,8 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
                t_name2 = "unknown";
        }
 
+       tvee->tuner_hauppauge_model = tuner1;
+       tvee->tuner2_hauppauge_model = tuner2;
        tvee->tuner_formats = 0;
        tvee->tuner2_formats = 0;
        for (i = j = 0; i < 8; i++) {
index 97930081699fca2b4baf3cb547a293c73e70f39a..e9fc1a7854970aaccf6eb8252cbd3914c41bdfd9 100644 (file)
@@ -8,9 +8,11 @@ struct tveeprom {
 
        u32 tuner_type;
        u32 tuner_formats;
+       u32 tuner_hauppauge_model;
 
        u32 tuner2_type;
        u32 tuner2_formats;
+       u32 tuner2_hauppauge_model;
 
        u32 digitizer;
        u32 digitizer_formats;