Commit f95006f8 authored by Hans Verkuil's avatar Hans Verkuil Committed by Linus Torvalds

[PATCH] V4L: Add workaround for Hauppauge PVR150 with certain NTSC tuner models

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: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 0fe22865
...@@ -208,8 +208,11 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw) ...@@ -208,8 +208,11 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw)
static void input_change(struct i2c_client *client) static void input_change(struct i2c_client *client)
{ {
struct cx25840_state *state = i2c_get_clientdata(client);
v4l2_std_id std = cx25840_get_v4lstd(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) { if (std & V4L2_STD_PAL) {
/* Follow tuner change procedure for PAL */ /* Follow tuner change procedure for PAL */
cx25840_write(client, 0x808, 0xff); cx25840_write(client, 0x808, 0xff);
...@@ -220,7 +223,32 @@ static void input_change(struct i2c_client *client) ...@@ -220,7 +223,32 @@ static void input_change(struct i2c_client *client)
cx25840_write(client, 0x80b, 0x10); cx25840_write(client, 0x80b, 0x10);
} else if (std & V4L2_STD_NTSC) { } else if (std & V4L2_STD_NTSC) {
/* NTSC */ /* NTSC */
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); 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); cx25840_write(client, 0x80b, 0x00);
} }
...@@ -241,7 +269,8 @@ static int set_input(struct i2c_client *client, enum cx25840_input input) ...@@ -241,7 +269,8 @@ static int set_input(struct i2c_client *client, enum cx25840_input input)
case CX25840_TUNER: case CX25840_TUNER:
cx25840_dbg("now setting Tuner input\n"); 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 */ /* CH_SEL_ADC2=1 */
cx25840_and_or(client, 0x102, ~0x2, 0x02); cx25840_and_or(client, 0x102, ~0x2, 0x02);
} }
...@@ -363,6 +392,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) ...@@ -363,6 +392,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl)
case CX25840_CID_CARDTYPE: case CX25840_CID_CARDTYPE:
switch (ctrl->value) { switch (ctrl->value) {
case CARDTYPE_PVR150: case CARDTYPE_PVR150:
case CARDTYPE_PVR150_WORKAROUND:
case CARDTYPE_PG600: case CARDTYPE_PG600:
state->cardtype = ctrl->value; state->cardtype = ctrl->value;
break; break;
......
...@@ -40,9 +40,16 @@ extern int cx25840_debug; ...@@ -40,9 +40,16 @@ extern int cx25840_debug;
#define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) #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 { enum cx25840_cardtype {
CARDTYPE_PVR150, CARDTYPE_PVR150,
CARDTYPE_PG600 CARDTYPE_PG600,
CARDTYPE_PVR150_WORKAROUND,
}; };
enum cx25840_input { enum cx25840_input {
......
...@@ -339,6 +339,7 @@ static int hasRadioTuner(int tunerType) ...@@ -339,6 +339,7 @@ static int hasRadioTuner(int tunerType)
case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM: case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM:
case 89: //PNPEnv_TUNER_TCL_MFPE05_2: case 89: //PNPEnv_TUNER_TCL_MFPE05_2:
case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4: case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4:
case 105:
return 1; return 1;
} }
return 0; return 0;
...@@ -596,6 +597,8 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, ...@@ -596,6 +597,8 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee,
t_name2 = "unknown"; t_name2 = "unknown";
} }
tvee->tuner_hauppauge_model = tuner1;
tvee->tuner2_hauppauge_model = tuner2;
tvee->tuner_formats = 0; tvee->tuner_formats = 0;
tvee->tuner2_formats = 0; tvee->tuner2_formats = 0;
for (i = j = 0; i < 8; i++) { for (i = j = 0; i < 8; i++) {
......
...@@ -8,9 +8,11 @@ struct tveeprom { ...@@ -8,9 +8,11 @@ struct tveeprom {
u32 tuner_type; u32 tuner_type;
u32 tuner_formats; u32 tuner_formats;
u32 tuner_hauppauge_model;
u32 tuner2_type; u32 tuner2_type;
u32 tuner2_formats; u32 tuner2_formats;
u32 tuner2_hauppauge_model;
u32 digitizer; u32 digitizer;
u32 digitizer_formats; u32 digitizer_formats;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment