diff options
author | Andy Walls <awalls@md.metrocast.net> | 2011-03-26 23:20:37 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2011-05-20 08:26:54 -0400 |
commit | 2bfe2fa43eb2122f200e83df7428391f33537ff2 (patch) | |
tree | 40b2e5d293e2c913b2245f0342532c468c9a839f | |
parent | 834751d4365822f769d8af2fd37dc674997a313c (diff) |
[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 <jac1dlists@gmail.com>
Tested-by: Andy Walls <awalls@md.metrocast.net>
Signed-off-by: Andy Walls <awalls@md.metrocast.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r-- | drivers/media/video/cx18/Kconfig | 3 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-cards.c | 18 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-cards.h | 2 | ||||
-rw-r--r-- | 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 | |||
9 | select VIDEO_CS5345 | 9 | select VIDEO_CS5345 |
10 | select DVB_S5H1409 if !DVB_FE_CUSTOMISE | 10 | select DVB_S5H1409 if !DVB_FE_CUSTOMISE |
11 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE | 11 | select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMISE |
12 | select DVB_S5H1411 if !DVB_FE_CUSTOMISE | ||
13 | select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMISE | ||
14 | select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE | ||
12 | ---help--- | 15 | ---help--- |
13 | This is a video4linux driver for Conexant cx23418 based | 16 | This is a video4linux driver for Conexant cx23418 based |
14 | PCI combo video recorder devices. | 17 | 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 = { | |||
39 | .tv = { 0x61, 0x60, I2C_CLIENT_END }, | 39 | .tv = { 0x61, 0x60, I2C_CLIENT_END }, |
40 | }; | 40 | }; |
41 | 41 | ||
42 | /* | ||
43 | * usual i2c tuner addresses to probe with additional demod address for | ||
44 | * an NXP TDA8295 at 0x42 (N.B. it can possibly be at 0x4b or 0x4c too). | ||
45 | */ | ||
46 | static struct cx18_card_tuner_i2c cx18_i2c_nxp = { | ||
47 | .radio = { I2C_CLIENT_END }, | ||
48 | .demod = { 0x42, 0x43, I2C_CLIENT_END }, | ||
49 | .tv = { 0x61, 0x60, I2C_CLIENT_END }, | ||
50 | }; | ||
51 | |||
42 | /* Please add new PCI IDs to: http://pci-ids.ucw.cz/ | 52 | /* Please add new PCI IDs to: http://pci-ids.ucw.cz/ |
43 | This keeps the PCI ID database up to date. Note that the entries | 53 | This keeps the PCI ID database up to date. Note that the entries |
44 | must be added under vendor 0x4444 (Conexant) as subsystem IDs. | 54 | must be added under vendor 0x4444 (Conexant) as subsystem IDs. |
@@ -131,15 +141,15 @@ static const struct cx18_card cx18_card_hvr1600_s5h1411 = { | |||
131 | .tune_lane = 0, | 141 | .tune_lane = 0, |
132 | .initial_emrs = 0, | 142 | .initial_emrs = 0, |
133 | }, | 143 | }, |
134 | .gpio_init.initial_value = 0x3001, | 144 | .gpio_init.initial_value = 0x3801, |
135 | .gpio_init.direction = 0x3001, | 145 | .gpio_init.direction = 0x3801, |
136 | .gpio_i2c_slave_reset = { | 146 | .gpio_i2c_slave_reset = { |
137 | .active_lo_mask = 0x3001, | 147 | .active_lo_mask = 0x3801, |
138 | .msecs_asserted = 10, | 148 | .msecs_asserted = 10, |
139 | .msecs_recovery = 40, | 149 | .msecs_recovery = 40, |
140 | .ir_reset_mask = 0x0001, | 150 | .ir_reset_mask = 0x0001, |
141 | }, | 151 | }, |
142 | .i2c = &cx18_i2c_std, | 152 | .i2c = &cx18_i2c_nxp, |
143 | }; | 153 | }; |
144 | 154 | ||
145 | static const struct cx18_card cx18_card_hvr1600_samsung = { | 155 | 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 { | |||
109 | 109 | ||
110 | struct cx18_card_tuner_i2c { | 110 | struct cx18_card_tuner_i2c { |
111 | unsigned short radio[2];/* radio tuner i2c address to probe */ | 111 | unsigned short radio[2];/* radio tuner i2c address to probe */ |
112 | unsigned short demod[2];/* demodulator i2c address to probe */ | 112 | unsigned short demod[3];/* demodulator i2c address to probe */ |
113 | unsigned short tv[4]; /* tv tuner i2c addresses to probe */ | 113 | unsigned short tv[4]; /* tv tuner i2c addresses to probe */ |
114 | }; | 114 | }; |
115 | 115 | ||
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) | |||
423 | return; | 423 | return; |
424 | 424 | ||
425 | /* autodetect tuner standard */ | 425 | /* autodetect tuner standard */ |
426 | if (tv.tuner_formats & V4L2_STD_PAL) { | 426 | #define TVEEPROM_TUNER_FORMAT_ALL (V4L2_STD_B | V4L2_STD_GH | \ |
427 | V4L2_STD_MN | \ | ||
428 | V4L2_STD_PAL_I | \ | ||
429 | V4L2_STD_SECAM_L | V4L2_STD_SECAM_LC | \ | ||
430 | V4L2_STD_DK) | ||
431 | if ((tv.tuner_formats & TVEEPROM_TUNER_FORMAT_ALL) | ||
432 | == TVEEPROM_TUNER_FORMAT_ALL) { | ||
433 | CX18_DEBUG_INFO("Worldwide tuner detected\n"); | ||
434 | cx->std = V4L2_STD_ALL; | ||
435 | } else if (tv.tuner_formats & V4L2_STD_PAL) { | ||
427 | CX18_DEBUG_INFO("PAL tuner detected\n"); | 436 | CX18_DEBUG_INFO("PAL tuner detected\n"); |
428 | cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; | 437 | cx->std |= V4L2_STD_PAL_BG | V4L2_STD_PAL_H; |
429 | } else if (tv.tuner_formats & V4L2_STD_NTSC) { | 438 | } else if (tv.tuner_formats & V4L2_STD_NTSC) { |
@@ -1001,7 +1010,15 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, | |||
1001 | if (cx->card->hw_all & CX18_HW_TVEEPROM) { | 1010 | if (cx->card->hw_all & CX18_HW_TVEEPROM) { |
1002 | /* Based on the model number the cardtype may be changed. | 1011 | /* Based on the model number the cardtype may be changed. |
1003 | The PCI IDs are not always reliable. */ | 1012 | The PCI IDs are not always reliable. */ |
1013 | const struct cx18_card *orig_card = cx->card; | ||
1004 | cx18_process_eeprom(cx); | 1014 | cx18_process_eeprom(cx); |
1015 | |||
1016 | if (cx->card != orig_card) { | ||
1017 | /* Changed the cardtype; re-reset the I2C chips */ | ||
1018 | cx18_gpio_init(cx); | ||
1019 | cx18_call_hw(cx, CX18_HW_GPIO_RESET_CTRL, | ||
1020 | core, reset, (u32) CX18_GPIO_RESET_I2C); | ||
1021 | } | ||
1005 | } | 1022 | } |
1006 | if (cx->card->comment) | 1023 | if (cx->card->comment) |
1007 | CX18_INFO("%s", cx->card->comment); | 1024 | CX18_INFO("%s", cx->card->comment); |
@@ -1087,6 +1104,8 @@ static int __devinit cx18_probe(struct pci_dev *pci_dev, | |||
1087 | /* The tuner is fixed to the standard. The other inputs (e.g. S-Video) | 1104 | /* The tuner is fixed to the standard. The other inputs (e.g. S-Video) |
1088 | are not. */ | 1105 | are not. */ |
1089 | cx->tuner_std = cx->std; | 1106 | cx->tuner_std = cx->std; |
1107 | if (cx->std == V4L2_STD_ALL) | ||
1108 | cx->std = V4L2_STD_NTSC_M; | ||
1090 | 1109 | ||
1091 | retval = cx18_streams_setup(cx); | 1110 | retval = cx18_streams_setup(cx); |
1092 | if (retval) { | 1111 | if (retval) { |
@@ -1133,6 +1152,7 @@ int cx18_init_on_first_open(struct cx18 *cx) | |||
1133 | int fw_retry_count = 3; | 1152 | int fw_retry_count = 3; |
1134 | struct v4l2_frequency vf; | 1153 | struct v4l2_frequency vf; |
1135 | struct cx18_open_id fh; | 1154 | struct cx18_open_id fh; |
1155 | v4l2_std_id std; | ||
1136 | 1156 | ||
1137 | fh.cx = cx; | 1157 | fh.cx = cx; |
1138 | 1158 | ||
@@ -1220,7 +1240,8 @@ int cx18_init_on_first_open(struct cx18 *cx) | |||
1220 | /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code | 1240 | /* Let the VIDIOC_S_STD ioctl do all the work, keeps the code |
1221 | in one place. */ | 1241 | in one place. */ |
1222 | cx->std++; /* Force full standard initialization */ | 1242 | cx->std++; /* Force full standard initialization */ |
1223 | cx18_s_std(NULL, &fh, &cx->tuner_std); | 1243 | std = (cx->tuner_std == V4L2_STD_ALL) ? V4L2_STD_NTSC_M : cx->tuner_std; |
1244 | cx18_s_std(NULL, &fh, &std); | ||
1224 | cx18_s_frequency(NULL, &fh, &vf); | 1245 | cx18_s_frequency(NULL, &fh, &vf); |
1225 | return 0; | 1246 | return 0; |
1226 | } | 1247 | } |