Commit 2bfe2fa4 authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab

[media] cx18: Make RF analog TV work for newer HVR-1600 models with silicon tuners

A previous changes which added the newer model HVR-1600's and DTV support for
them, neglected to add RF analog TV for them.  Fix RF analog TV for the newer
HVR-1600's which have a worldwide analog tuner assembly with a TDA18271 tuner
and TDA8295 demodulator.

Thanks go to Jeff Campbell and Mike Bradley for reproting the problem, and
also to Mike Bradley for doing a lot of the legwork to figure out the tuner
reset GPIO line, the demodulator I2C address, and that the GPIOs have to be
reinitialized after a cardtype switch.
Reported-by: default avatarJeff Campbell <jac1dlists@gmail.com>
Tested-by: default avatarAndy Walls <awalls@md.metrocast.net>
Signed-off-by: default avatarAndy Walls <awalls@md.metrocast.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 834751d4
...@@ -9,6 +9,9 @@ config VIDEO_CX18 ...@@ -9,6 +9,9 @@ config VIDEO_CX18
select VIDEO_CS5345 select VIDEO_CS5345
select DVB_S5H1409 if !DVB_FE_CUSTOMISE select DVB_S5H1409 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE
select DVB_S5H1411 if !DVB_FE_CUSTOMISE
select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE
select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
---help--- ---help---
This is a video4linux driver for Conexant cx23418 based This is a video4linux driver for Conexant cx23418 based
PCI combo video recorder devices. PCI combo video recorder devices.
......
...@@ -39,6 +39,16 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = { ...@@ -39,6 +39,16 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = {
.tv = { 0x61, 0x60, I2C_CLIENT_END }, .tv = { 0x61, 0x60, I2C_CLIENT_END },
}; };
/*
* usual i2c tuner addresses to probe with additional demod address for
* an NXP TDA8295 at 0x42 (N.B. it can possibly be at 0x4b or 0x4c too).
*/
static struct cx18_card_tuner_i2c cx18_i2c_nxp = {
.radio = { I2C_CLIENT_END },
.demod = { 0x42, 0x43, I2C_CLIENT_END },
.tv = { 0x61, 0x60, I2C_CLIENT_END },
};
/* Please add new PCI IDs to: http://pci-ids.ucw.cz/ /* Please add new PCI IDs to: http://pci-ids.ucw.cz/
This keeps the PCI ID database up to date. Note that the entries This keeps the PCI ID database up to date. Note that the entries
must be added under vendor 0x4444 (Conexant) as subsystem IDs. must be added under vendor 0x4444 (Conexant) as subsystem IDs.
...@@ -131,15 +141,15 @@ static const struct cx18_card cx18_card_hvr1600_s5h1411 = { ...@@ -131,15 +141,15 @@ static const struct cx18_card cx18_card_hvr1600_s5h1411 = {
.tune_lane = 0, .tune_lane = 0,
.initial_emrs = 0, .initial_emrs = 0,
}, },
.gpio_init.initial_value = 0x3001, .gpio_init.initial_value = 0x3801,
.gpio_init.direction = 0x3001, .gpio_init.direction = 0x3801,
.gpio_i2c_slave_reset = { .gpio_i2c_slave_reset = {
.active_lo_mask = 0x3001, .active_lo_mask = 0x3801,
.msecs_asserted = 10, .msecs_asserted = 10,
.msecs_recovery = 40, .msecs_recovery = 40,
.ir_reset_mask = 0x0001, .ir_reset_mask = 0x0001,
}, },
.i2c = &cx18_i2c_std, .i2c = &cx18_i2c_nxp,
}; };
static const struct cx18_card cx18_card_hvr1600_samsung = { static const struct cx18_card cx18_card_hvr1600_samsung = {
......
...@@ -109,7 +109,7 @@ struct cx18_card_tuner { ...@@ -109,7 +109,7 @@ struct cx18_card_tuner {
struct cx18_card_tuner_i2c { struct cx18_card_tuner_i2c {
unsigned short radio[2];/* radio tuner i2c address to probe */ unsigned short radio[2];/* radio tuner i2c address to probe */
unsigned short demod[2];/* demodulator i2c address to probe */ unsigned short demod[3];/* demodulator i2c address to probe */
unsigned short tv[4]; /* tv tuner i2c addresses to probe */ unsigned short tv[4]; /* tv tuner i2c addresses to probe */
}; };
......
...@@ -423,7 +423,16 @@ static void cx18_process_eeprom(struct cx18 *cx) ...@@ -423,7 +423,16 @@ static void cx18_process_eeprom(struct cx18 *cx)
return; return;
/* autodetect tuner standard */ /* autodetect tuner standard */
if (tv.tuner_formats & V4L2_STD_PAL) { #define TVEEPROM_TUNER_FORMAT_ALL (V4L2_STD_B | V4L2_STD_GH | \
V4L2_STD_MN | \
V4L2_STD_PAL_I | \
V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC | \
V4L2_STD_DK)
if ((tv.tuner_formats & TVEEPROM_TUNER_FORMAT_ALL)
== TVEEPROM_TUNER_FORMAT_ALL) {
CX18_DEBUG_INFO("Worldwide tuner detected\n");
cx->std = V4L2_STD_ALL;
} else if (tv.tuner_formats & V4L2_STD_PAL) {
CX18_DEBUG_INFO("PAL tuner detected\n"); CX18_DEBUG_INFO("PAL tuner detected\n");
cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H;
} else if (tv.tuner_formats & V4L2_STD_NTSC) { } else if (tv.tuner_formats & V4L2_STD_NTSC) {
...@@ -1001,7 +1010,15 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, ...@@ -1001,7 +1010,15 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
if (cx->card->hw_all & CX18_HW_TVEEPROM) { if (cx->card->hw_all & CX18_HW_TVEEPROM) {
/* Based on the model number the cardtype may be changed. /* Based on the model number the cardtype may be changed.
The PCI IDs are not always reliable. */ The PCI IDs are not always reliable. */
const struct cx18_card *orig_card = cx->card;
cx18_process_eeprom(cx); cx18_process_eeprom(cx);
if (cx->card != orig_card) {
/* Changed the cardtype; re-reset the I2C chips */
cx18_gpio_init(cx);
cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL,
core, reset, (u32) CX18_GPIO_RESET_I2C);
}
} }
if (cx->card->comment) if (cx->card->comment)
CX18_INFO("%s", cx->card->comment); CX18_INFO("%s", cx->card->comment);
...@@ -1087,6 +1104,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, ...@@ -1087,6 +1104,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev,
/* The tuner is fixed to the standard. The other inputs (e.g. S-Video) /* The tuner is fixed to the standard. The other inputs (e.g. S-Video)
are not. */ are not. */
cx->tuner_std = cx->std; cx->tuner_std = cx->std;
if (cx->std == V4L2_STD_ALL)
cx->std = V4L2_STD_NTSC_M;
retval = cx18_streams_setup(cx); retval = cx18_streams_setup(cx);
if (retval) { if (retval) {
...@@ -1133,6 +1152,7 @@ int cx18_init_on_first_open(struct cx18 *cx) ...@@ -1133,6 +1152,7 @@ int cx18_init_on_first_open(struct cx18 *cx)
int fw_retry_count = 3; int fw_retry_count = 3;
struct v4l2_frequency vf; struct v4l2_frequency vf;
struct cx18_open_id fh; struct cx18_open_id fh;
v4l2_std_id std;
fh.cx = cx; fh.cx = cx;
...@@ -1220,7 +1240,8 @@ int cx18_init_on_first_open(struct cx18 *cx) ...@@ -1220,7 +1240,8 @@ int cx18_init_on_first_open(struct cx18 *cx)
/* Let the VIDIOC_S_STD ioctl do all the work, keeps the code /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code
in one place. */ in one place. */
cx->std++; /* Force full standard initialization */ cx->std++; /* Force full standard initialization */
cx18_s_std(NULL, &fh, &cx->tuner_std); std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std;
cx18_s_std(NULL, &fh, &std);
cx18_s_frequency(NULL, &fh, &vf); cx18_s_frequency(NULL, &fh, &vf);
return 0; return 0;
} }
......
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