diff options
-rw-r--r-- | drivers/media/video/cx25840/cx25840-core.c | 34 | ||||
-rw-r--r-- | drivers/media/video/cx25840/cx25840.h | 9 | ||||
-rw-r--r-- | drivers/media/video/tveeprom.c | 3 | ||||
-rw-r--r-- | include/media/tveeprom.h | 2 |
4 files changed, 45 insertions, 3 deletions
diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 539db129a9f4..aea3f038cff6 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c | |||
@@ -208,8 +208,11 @@ static void cx25840_initialize(struct i2c_client *client, int loadfw) | |||
208 | 208 | ||
209 | static void input_change(struct i2c_client *client) | 209 | static void input_change(struct i2c_client *client) |
210 | { | 210 | { |
211 | struct cx25840_state *state = i2c_get_clientdata(client); | ||
211 | v4l2_std_id std = cx25840_get_v4lstd(client); | 212 | v4l2_std_id std = cx25840_get_v4lstd(client); |
212 | 213 | ||
214 | /* Note: perhaps V4L2_STD_PAL_M should be handled as V4L2_STD_NTSC | ||
215 | instead of V4L2_STD_PAL. Someone needs to test this. */ | ||
213 | if (std & V4L2_STD_PAL) { | 216 | if (std & V4L2_STD_PAL) { |
214 | /* Follow tuner change procedure for PAL */ | 217 | /* Follow tuner change procedure for PAL */ |
215 | cx25840_write(client, 0x808, 0xff); | 218 | cx25840_write(client, 0x808, 0xff); |
@@ -220,7 +223,32 @@ static void input_change(struct i2c_client *client) | |||
220 | cx25840_write(client, 0x80b, 0x10); | 223 | cx25840_write(client, 0x80b, 0x10); |
221 | } else if (std & V4L2_STD_NTSC) { | 224 | } else if (std & V4L2_STD_NTSC) { |
222 | /* NTSC */ | 225 | /* NTSC */ |
223 | cx25840_write(client, 0x808, 0xf6); | 226 | if (state->cardtype == CARDTYPE_PVR150_WORKAROUND) { |
227 | /* Certain Hauppauge PVR150 models have a hardware bug | ||
228 | that causes audio to drop out. For these models the | ||
229 | audio standard must be set explicitly. | ||
230 | To be precise: it affects cards with tuner models | ||
231 | 85, 99 and 112 (model numbers from tveeprom). */ | ||
232 | if (std == V4L2_STD_NTSC_M_JP) { | ||
233 | /* Japan uses EIAJ audio standard */ | ||
234 | cx25840_write(client, 0x808, 0x2f); | ||
235 | } else { | ||
236 | /* Others use the BTSC audio standard */ | ||
237 | cx25840_write(client, 0x808, 0x1f); | ||
238 | } | ||
239 | /* South Korea uses the A2-M (aka Zweiton M) audio | ||
240 | standard, and should set 0x808 to 0x3f, but I don't | ||
241 | know how to detect this. */ | ||
242 | } else if (std == V4L2_STD_NTSC_M_JP) { | ||
243 | /* Japan uses EIAJ audio standard */ | ||
244 | cx25840_write(client, 0x808, 0xf7); | ||
245 | } else { | ||
246 | /* Others use the BTSC audio standard */ | ||
247 | cx25840_write(client, 0x808, 0xf6); | ||
248 | } | ||
249 | /* South Korea uses the A2-M (aka Zweiton M) audio standard, | ||
250 | and should set 0x808 to 0xf8, but I don't know how to | ||
251 | detect this. */ | ||
224 | cx25840_write(client, 0x80b, 0x00); | 252 | cx25840_write(client, 0x80b, 0x00); |
225 | } | 253 | } |
226 | 254 | ||
@@ -241,7 +269,8 @@ static int set_input(struct i2c_client *client, enum cx25840_input input) | |||
241 | case CX25840_TUNER: | 269 | case CX25840_TUNER: |
242 | cx25840_dbg("now setting Tuner input\n"); | 270 | cx25840_dbg("now setting Tuner input\n"); |
243 | 271 | ||
244 | if (state->cardtype == CARDTYPE_PVR150) { | 272 | if (state->cardtype == CARDTYPE_PVR150 || |
273 | state->cardtype == CARDTYPE_PVR150_WORKAROUND) { | ||
245 | /* CH_SEL_ADC2=1 */ | 274 | /* CH_SEL_ADC2=1 */ |
246 | cx25840_and_or(client, 0x102, ~0x2, 0x02); | 275 | cx25840_and_or(client, 0x102, ~0x2, 0x02); |
247 | } | 276 | } |
@@ -363,6 +392,7 @@ static int set_v4lctrl(struct i2c_client *client, struct v4l2_control *ctrl) | |||
363 | case CX25840_CID_CARDTYPE: | 392 | case CX25840_CID_CARDTYPE: |
364 | switch (ctrl->value) { | 393 | switch (ctrl->value) { |
365 | case CARDTYPE_PVR150: | 394 | case CARDTYPE_PVR150: |
395 | case CARDTYPE_PVR150_WORKAROUND: | ||
366 | case CARDTYPE_PG600: | 396 | case CARDTYPE_PG600: |
367 | state->cardtype = ctrl->value; | 397 | state->cardtype = ctrl->value; |
368 | break; | 398 | break; |
diff --git a/drivers/media/video/cx25840/cx25840.h b/drivers/media/video/cx25840/cx25840.h index 5c3f0639fb77..4932ed1c9b19 100644 --- a/drivers/media/video/cx25840/cx25840.h +++ b/drivers/media/video/cx25840/cx25840.h | |||
@@ -40,9 +40,16 @@ extern int cx25840_debug; | |||
40 | 40 | ||
41 | #define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) | 41 | #define CX25840_CID_CARDTYPE (V4L2_CID_PRIVATE_BASE+0) |
42 | 42 | ||
43 | /* The CARDTYPE_PVR150_WORKAROUND cardtype activates a workaround for a | ||
44 | hardware bug that is present in PVR150 (and possible PVR500) cards that | ||
45 | have certain NTSC tuners (tveeprom model numbers 85, 99 and 112). The | ||
46 | audio autodetect fails on some channels for these models and the workaround | ||
47 | is to select the audio standard explicitly. Many thanks to Hauppauge for | ||
48 | providing this information. */ | ||
43 | enum cx25840_cardtype { | 49 | enum cx25840_cardtype { |
44 | CARDTYPE_PVR150, | 50 | CARDTYPE_PVR150, |
45 | CARDTYPE_PG600 | 51 | CARDTYPE_PG600, |
52 | CARDTYPE_PVR150_WORKAROUND, | ||
46 | }; | 53 | }; |
47 | 54 | ||
48 | enum cx25840_input { | 55 | enum cx25840_input { |
diff --git a/drivers/media/video/tveeprom.c b/drivers/media/video/tveeprom.c index f048fd44f0e2..3a986c2a0f72 100644 --- a/drivers/media/video/tveeprom.c +++ b/drivers/media/video/tveeprom.c | |||
@@ -339,6 +339,7 @@ static int hasRadioTuner(int tunerType) | |||
339 | case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM: | 339 | case 78: //PNPEnv_TUNER_TDA8275C1_8290_FM: |
340 | case 89: //PNPEnv_TUNER_TCL_MFPE05_2: | 340 | case 89: //PNPEnv_TUNER_TCL_MFPE05_2: |
341 | case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4: | 341 | case 92: //PNPEnv_TUNER_PHILIPS_FQ1236A_MK4: |
342 | case 105: | ||
342 | return 1; | 343 | return 1; |
343 | } | 344 | } |
344 | return 0; | 345 | return 0; |
@@ -596,6 +597,8 @@ void tveeprom_hauppauge_analog(struct i2c_client *c, struct tveeprom *tvee, | |||
596 | t_name2 = "unknown"; | 597 | t_name2 = "unknown"; |
597 | } | 598 | } |
598 | 599 | ||
600 | tvee->tuner_hauppauge_model = tuner1; | ||
601 | tvee->tuner2_hauppauge_model = tuner2; | ||
599 | tvee->tuner_formats = 0; | 602 | tvee->tuner_formats = 0; |
600 | tvee->tuner2_formats = 0; | 603 | tvee->tuner2_formats = 0; |
601 | for (i = j = 0; i < 8; i++) { | 604 | for (i = j = 0; i < 8; i++) { |
diff --git a/include/media/tveeprom.h b/include/media/tveeprom.h index 97930081699f..e9fc1a785497 100644 --- a/include/media/tveeprom.h +++ b/include/media/tveeprom.h | |||
@@ -8,9 +8,11 @@ struct tveeprom { | |||
8 | 8 | ||
9 | u32 tuner_type; | 9 | u32 tuner_type; |
10 | u32 tuner_formats; | 10 | u32 tuner_formats; |
11 | u32 tuner_hauppauge_model; | ||
11 | 12 | ||
12 | u32 tuner2_type; | 13 | u32 tuner2_type; |
13 | u32 tuner2_formats; | 14 | u32 tuner2_formats; |
15 | u32 tuner2_hauppauge_model; | ||
14 | 16 | ||
15 | u32 digitizer; | 17 | u32 digitizer; |
16 | u32 digitizer_formats; | 18 | u32 digitizer_formats; |