From 2bfe2fa43eb2122f200e83df7428391f33537ff2 Mon Sep 17 00:00:00 2001 From: Andy Walls Date: Sun, 27 Mar 2011 00:20:37 -0300 Subject: [PATCH] [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: Jeff Campbell Tested-by: Andy Walls Signed-off-by: Andy Walls Signed-off-by: Mauro Carvalho Chehab --- drivers/media/video/cx18/Kconfig | 3 +++ drivers/media/video/cx18/cx18-cards.c | 18 ++++++++++++++---- drivers/media/video/cx18/cx18-cards.h | 2 +- drivers/media/video/cx18/cx18-driver.c | 25 +++++++++++++++++++++++-- 4 files changed, 41 insertions(+), 7 deletions(-) diff --git a/drivers/media/video/cx18/Kconfig b/drivers/media/video/cx18/Kconfig index d9d2f6ad6ffb..d788ad6f5c48 100644 --- a/drivers/media/video/cx18/Kconfig +++ b/drivers/media/video/cx18/Kconfig @@ -9,6 +9,9 @@ config VIDEO_CX18 select VIDEO_CS5345 select DVB_S5H1409 if !DVB_FE_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--- This is a video4linux driver for Conexant cx23418 based PCI combo video recorder devices. diff --git a/drivers/media/video/cx18/cx18-cards.c b/drivers/media/video/cx18/cx18-cards.c index 68ad1963f421..c07c849b1aaf 100644 --- a/drivers/media/video/cx18/cx18-cards.c +++ b/drivers/media/video/cx18/cx18-cards.c @@ -39,6 +39,16 @@ static struct cx18_card_tuner_i2c cx18_i2c_std = { .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/ This keeps the PCI ID database up to date. Note that the entries must be added under vendor 0x4444 (Conexant) as subsystem IDs. @@ -131,15 +141,15 @@ static const struct cx18_card cx18_card_hvr1600_s5h1411 = { .tune_lane = 0, .initial_emrs = 0, }, - .gpio_init.initial_value = 0x3001, - .gpio_init.direction = 0x3001, + .gpio_init.initial_value = 0x3801, + .gpio_init.direction = 0x3801, .gpio_i2c_slave_reset = { - .active_lo_mask = 0x3001, + .active_lo_mask = 0x3801, .msecs_asserted = 10, .msecs_recovery = 40, .ir_reset_mask = 0x0001, }, - .i2c = &cx18_i2c_std, + .i2c = &cx18_i2c_nxp, }; static const struct cx18_card cx18_card_hvr1600_samsung = { diff --git a/drivers/media/video/cx18/cx18-cards.h b/drivers/media/video/cx18/cx18-cards.h index 3e750068f275..add7391ecaba 100644 --- a/drivers/media/video/cx18/cx18-cards.h +++ b/drivers/media/video/cx18/cx18-cards.h @@ -109,7 +109,7 @@ struct cx18_card_tuner { struct cx18_card_tuner_i2c { 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 */ }; diff --git a/drivers/media/video/cx18/cx18-driver.c b/drivers/media/video/cx18/cx18-driver.c index 841ea4ef6200..9e2f870f4258 100644 --- a/drivers/media/video/cx18/cx18-driver.c +++ b/drivers/media/video/cx18/cx18-driver.c @@ -423,7 +423,16 @@ static void cx18_process_eeprom(struct cx18 *cx) return; /* 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"); cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; } else if (tv.tuner_formats & V4L2_STD_NTSC) { @@ -1001,7 +1010,15 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, if (cx->card->hw_all & CX18_HW_TVEEPROM) { /* Based on the model number the cardtype may be changed. The PCI IDs are not always reliable. */ + const struct cx18_card *orig_card = cx->card; 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) CX18_INFO("%s", cx->card->comment); @@ -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) are not. */ cx->tuner_std = cx->std; + if (cx->std == V4L2_STD_ALL) + cx->std = V4L2_STD_NTSC_M; retval = cx18_streams_setup(cx); if (retval) { @@ -1133,6 +1152,7 @@ int cx18_init_on_first_open(struct cx18 *cx) int fw_retry_count = 3; struct v4l2_frequency vf; struct cx18_open_id fh; + v4l2_std_id std; fh.cx = 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 in one place. */ 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); return 0; } -- 2.39.5