diff options
author | Mauro Carvalho Chehab <mchehab@brturbo.com.br> | 2005-07-15 06:56:28 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-07-15 12:54:50 -0400 |
commit | c5287ba132ff742e595d42c28b66cbba19522c4e (patch) | |
tree | 26a33ea2e756586d9696c050449c0d5f1666e908 | |
parent | 1eb29128c644581fa51f822545921394ad4f719f (diff) |
[PATCH] v4l: bug fixes for tuner, cx88 and tea5767
- In CX88 code, some cards needs to have audio reprogramed after changing
video channel;
- Tuner autodetection code seems not to work on some cards. Now,
no_autodetect insmod option allows disabling autodetection code;
- Minor fixes in tea5767 to reduce integer trunc;
- There are some new Pixelview Ultra Pro cards that doesn't use TEA5767
for radio. As autodetection is capable of checking for tea, radio tuners
and addresses removed.
- CX88 version number incremented.
Signed-off-by: Mauro Carvalho Chehab <mchehab@brturbo.com.br>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r-- | drivers/media/video/cx88/cx88-cards.c | 8 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-dvb.c | 2 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88-video.c | 7 | ||||
-rw-r--r-- | drivers/media/video/cx88/cx88.h | 6 | ||||
-rw-r--r-- | drivers/media/video/tea5767.c | 34 | ||||
-rw-r--r-- | drivers/media/video/tuner-core.c | 33 |
6 files changed, 53 insertions, 37 deletions
diff --git a/drivers/media/video/cx88/cx88-cards.c b/drivers/media/video/cx88/cx88-cards.c index b0b47c3cde3c..3d0c784b376f 100644 --- a/drivers/media/video/cx88/cx88-cards.c +++ b/drivers/media/video/cx88/cx88-cards.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cx88-cards.c,v 1.85 2005/07/04 19:35:05 mkrufky Exp $ | 2 | * $Id: cx88-cards.c,v 1.86 2005/07/14 03:06:43 mchehab Exp $ |
3 | * | 3 | * |
4 | * device driver for Conexant 2388x based TV cards | 4 | * device driver for Conexant 2388x based TV cards |
5 | * card-specific stuff. | 5 | * card-specific stuff. |
@@ -682,9 +682,9 @@ struct cx88_board cx88_boards[] = { | |||
682 | .name = "PixelView PlayTV Ultra Pro (Stereo)", | 682 | .name = "PixelView PlayTV Ultra Pro (Stereo)", |
683 | /* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */ | 683 | /* May be also TUNER_YMEC_TVF_5533MF for NTSC/M or PAL/M */ |
684 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, | 684 | .tuner_type = TUNER_PHILIPS_FM1216ME_MK3, |
685 | .radio_type = TUNER_TEA5767, | 685 | .radio_type = UNSET, |
686 | .tuner_addr = 0xc2>>1, | 686 | .tuner_addr = ADDR_UNSET, |
687 | .radio_addr = 0xc0>>1, | 687 | .radio_addr = ADDR_UNSET, |
688 | .input = {{ | 688 | .input = {{ |
689 | .type = CX88_VMUX_TELEVISION, | 689 | .type = CX88_VMUX_TELEVISION, |
690 | .vmux = 0, | 690 | .vmux = 0, |
diff --git a/drivers/media/video/cx88/cx88-dvb.c b/drivers/media/video/cx88/cx88-dvb.c index 8db68f2d1351..00ca40a129b9 100644 --- a/drivers/media/video/cx88/cx88-dvb.c +++ b/drivers/media/video/cx88/cx88-dvb.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cx88-dvb.c,v 1.41 2005/07/04 19:35:05 mkrufky Exp $ | 2 | * $Id: cx88-dvb.c,v 1.42 2005/07/12 15:44:55 mkrufky Exp $ |
3 | * | 3 | * |
4 | * device driver for Conexant 2388x based TV cards | 4 | * device driver for Conexant 2388x based TV cards |
5 | * MPEG Transport Stream (DVB) routines | 5 | * MPEG Transport Stream (DVB) routines |
diff --git a/drivers/media/video/cx88/cx88-video.c b/drivers/media/video/cx88/cx88-video.c index c44a079d08c0..5588a3aeecb4 100644 --- a/drivers/media/video/cx88/cx88-video.c +++ b/drivers/media/video/cx88/cx88-video.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cx88-video.c,v 1.79 2005/07/07 14:17:47 mchehab Exp $ | 2 | * $Id: cx88-video.c,v 1.80 2005/07/13 08:49:08 mchehab Exp $ |
3 | * | 3 | * |
4 | * device driver for Conexant 2388x based TV cards | 4 | * device driver for Conexant 2388x based TV cards |
5 | * video4linux video interface | 5 | * video4linux video interface |
@@ -1346,6 +1346,11 @@ static int video_do_ioctl(struct inode *inode, struct file *file, | |||
1346 | dev->freq = f->frequency; | 1346 | dev->freq = f->frequency; |
1347 | cx88_newstation(core); | 1347 | cx88_newstation(core); |
1348 | cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f); | 1348 | cx88_call_i2c_clients(dev->core,VIDIOC_S_FREQUENCY,f); |
1349 | |||
1350 | /* When changing channels it is required to reset TVAUDIO */ | ||
1351 | msleep (10); | ||
1352 | cx88_set_tvaudio(core); | ||
1353 | |||
1349 | up(&dev->lock); | 1354 | up(&dev->lock); |
1350 | return 0; | 1355 | return 0; |
1351 | } | 1356 | } |
diff --git a/drivers/media/video/cx88/cx88.h b/drivers/media/video/cx88/cx88.h index 307beae04f2a..b008f7db6dfd 100644 --- a/drivers/media/video/cx88/cx88.h +++ b/drivers/media/video/cx88/cx88.h | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: cx88.h,v 1.68 2005/07/07 14:17:47 mchehab Exp $ | 2 | * $Id: cx88.h,v 1.69 2005/07/13 17:25:25 mchehab Exp $ |
3 | * | 3 | * |
4 | * v4l2 device driver for cx2388x based TV cards | 4 | * v4l2 device driver for cx2388x based TV cards |
5 | * | 5 | * |
@@ -35,8 +35,8 @@ | |||
35 | #include "btcx-risc.h" | 35 | #include "btcx-risc.h" |
36 | #include "cx88-reg.h" | 36 | #include "cx88-reg.h" |
37 | 37 | ||
38 | #include <linux/version.h> | 38 | #include <linux/utsname.h> |
39 | #define CX88_VERSION_CODE KERNEL_VERSION(0,0,4) | 39 | #define CX88_VERSION_CODE KERNEL_VERSION(0,0,5) |
40 | 40 | ||
41 | #ifndef TRUE | 41 | #ifndef TRUE |
42 | # define TRUE (1==1) | 42 | # define TRUE (1==1) |
diff --git a/drivers/media/video/tea5767.c b/drivers/media/video/tea5767.c index b53c748caf2a..4d27ac1b7fb8 100644 --- a/drivers/media/video/tea5767.c +++ b/drivers/media/video/tea5767.c | |||
@@ -2,7 +2,7 @@ | |||
2 | * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview | 2 | * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview |
3 | * I2C address is allways 0xC0. | 3 | * I2C address is allways 0xC0. |
4 | * | 4 | * |
5 | * $Id: tea5767.c,v 1.18 2005/07/07 03:02:55 mchehab Exp $ | 5 | * $Id: tea5767.c,v 1.21 2005/07/14 03:06:43 mchehab Exp $ |
6 | * | 6 | * |
7 | * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) | 7 | * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) |
8 | * This code is placed under the terms of the GNU General Public License | 8 | * This code is placed under the terms of the GNU General Public License |
@@ -153,17 +153,17 @@ static void tea5767_status_dump(unsigned char *buffer) | |||
153 | 153 | ||
154 | switch (TEA5767_HIGH_LO_32768) { | 154 | switch (TEA5767_HIGH_LO_32768) { |
155 | case TEA5767_HIGH_LO_13MHz: | 155 | case TEA5767_HIGH_LO_13MHz: |
156 | frq = 1000 * (div * 50 - 700 - 225) / 4; /* Freq in KHz */ | 156 | frq = (div * 50000 - 700000 - 225000) / 4; /* Freq in KHz */ |
157 | break; | 157 | break; |
158 | case TEA5767_LOW_LO_13MHz: | 158 | case TEA5767_LOW_LO_13MHz: |
159 | frq = 1000 * (div * 50 + 700 + 225) / 4; /* Freq in KHz */ | 159 | frq = (div * 50000 + 700000 + 225000) / 4; /* Freq in KHz */ |
160 | break; | 160 | break; |
161 | case TEA5767_LOW_LO_32768: | 161 | case TEA5767_LOW_LO_32768: |
162 | frq = 1000 * (div * 32768 / 1000 + 700 + 225) / 4; /* Freq in KHz */ | 162 | frq = (div * 32768 + 700000 + 225000) / 4; /* Freq in KHz */ |
163 | break; | 163 | break; |
164 | case TEA5767_HIGH_LO_32768: | 164 | case TEA5767_HIGH_LO_32768: |
165 | default: | 165 | default: |
166 | frq = 1000 * (div * 32768 / 1000 - 700 - 225) / 4; /* Freq in KHz */ | 166 | frq = (div * 32768 - 700000 - 225000) / 4; /* Freq in KHz */ |
167 | break; | 167 | break; |
168 | } | 168 | } |
169 | buffer[0] = (div >> 8) & 0x3f; | 169 | buffer[0] = (div >> 8) & 0x3f; |
@@ -196,7 +196,7 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq) | |||
196 | unsigned div; | 196 | unsigned div; |
197 | int rc; | 197 | int rc; |
198 | 198 | ||
199 | tuner_dbg (PREFIX "radio freq counter %d\n", frq); | 199 | tuner_dbg (PREFIX "radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000); |
200 | 200 | ||
201 | /* Rounds freq to next decimal value - for 62.5 KHz step */ | 201 | /* Rounds freq to next decimal value - for 62.5 KHz step */ |
202 | /* frq = 20*(frq/16)+radio_frq[frq%16]; */ | 202 | /* frq = 20*(frq/16)+radio_frq[frq%16]; */ |
@@ -224,19 +224,19 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq) | |||
224 | tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n"); | 224 | tuner_dbg ("TEA5767 radio HIGH LO inject xtal @ 13 MHz\n"); |
225 | buffer[2] |= TEA5767_HIGH_LO_INJECT; | 225 | buffer[2] |= TEA5767_HIGH_LO_INJECT; |
226 | buffer[4] |= TEA5767_PLLREF_ENABLE; | 226 | buffer[4] |= TEA5767_PLLREF_ENABLE; |
227 | div = (frq * 4 / 16 + 700 + 225 + 25) / 50; | 227 | div = (frq * 4000 / 16 + 700000 + 225000 + 25000) / 50000; |
228 | break; | 228 | break; |
229 | case TEA5767_LOW_LO_13MHz: | 229 | case TEA5767_LOW_LO_13MHz: |
230 | tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n"); | 230 | tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 13 MHz\n"); |
231 | 231 | ||
232 | buffer[4] |= TEA5767_PLLREF_ENABLE; | 232 | buffer[4] |= TEA5767_PLLREF_ENABLE; |
233 | div = (frq * 4 / 16 - 700 - 225 + 25) / 50; | 233 | div = (frq * 4000 / 16 - 700000 - 225000 + 25000) / 50000; |
234 | break; | 234 | break; |
235 | case TEA5767_LOW_LO_32768: | 235 | case TEA5767_LOW_LO_32768: |
236 | tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n"); | 236 | tuner_dbg ("TEA5767 radio LOW LO inject xtal @ 32,768 MHz\n"); |
237 | buffer[3] |= TEA5767_XTAL_32768; | 237 | buffer[3] |= TEA5767_XTAL_32768; |
238 | /* const 700=4000*175 Khz - to adjust freq to right value */ | 238 | /* const 700=4000*175 Khz - to adjust freq to right value */ |
239 | div = (1000 * (frq * 4 / 16 - 700 - 225) + 16384) >> 15; | 239 | div = ((frq * 4000 / 16 - 700000 - 225000) + 16384) >> 15; |
240 | break; | 240 | break; |
241 | case TEA5767_HIGH_LO_32768: | 241 | case TEA5767_HIGH_LO_32768: |
242 | default: | 242 | default: |
@@ -244,17 +244,21 @@ static void set_radio_freq(struct i2c_client *c, unsigned int frq) | |||
244 | 244 | ||
245 | buffer[2] |= TEA5767_HIGH_LO_INJECT; | 245 | buffer[2] |= TEA5767_HIGH_LO_INJECT; |
246 | buffer[3] |= TEA5767_XTAL_32768; | 246 | buffer[3] |= TEA5767_XTAL_32768; |
247 | div = (1000 * (frq * 4 / 16 + 700 + 225) + 16384) >> 15; | 247 | div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15; |
248 | break; | 248 | break; |
249 | } | 249 | } |
250 | buffer[0] = (div >> 8) & 0x3f; | 250 | buffer[0] = (div >> 8) & 0x3f; |
251 | buffer[1] = div & 0xff; | 251 | buffer[1] = div & 0xff; |
252 | 252 | ||
253 | if (tuner_debug) | ||
254 | tea5767_status_dump(buffer); | ||
255 | |||
256 | if (5 != (rc = i2c_master_send(c, buffer, 5))) | 253 | if (5 != (rc = i2c_master_send(c, buffer, 5))) |
257 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | 254 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); |
255 | |||
256 | if (tuner_debug) { | ||
257 | if (5 != (rc = i2c_master_recv(c, buffer, 5))) | ||
258 | tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc); | ||
259 | else | ||
260 | tea5767_status_dump(buffer); | ||
261 | } | ||
258 | } | 262 | } |
259 | 263 | ||
260 | static int tea5767_signal(struct i2c_client *c) | 264 | static int tea5767_signal(struct i2c_client *c) |
@@ -294,7 +298,7 @@ int tea5767_autodetection(struct i2c_client *c) | |||
294 | struct tuner *t = i2c_get_clientdata(c); | 298 | struct tuner *t = i2c_get_clientdata(c); |
295 | 299 | ||
296 | if (5 != (rc = i2c_master_recv(c, buffer, 5))) { | 300 | if (5 != (rc = i2c_master_recv(c, buffer, 5))) { |
297 | tuner_warn("it is not a TEA5767. Received %i chars.\n", rc); | 301 | tuner_warn("It is not a TEA5767. Received %i bytes.\n", rc); |
298 | return EINVAL; | 302 | return EINVAL; |
299 | } | 303 | } |
300 | 304 | ||
@@ -310,11 +314,11 @@ int tea5767_autodetection(struct i2c_client *c) | |||
310 | * bit 0 : internally set to 0 | 314 | * bit 0 : internally set to 0 |
311 | * Byte 5: bit 7:0 : == 0 | 315 | * Byte 5: bit 7:0 : == 0 |
312 | */ | 316 | */ |
313 | |||
314 | if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) { | 317 | if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) { |
315 | tuner_warn("Chip ID is not zero. It is not a TEA5767\n"); | 318 | tuner_warn("Chip ID is not zero. It is not a TEA5767\n"); |
316 | return EINVAL; | 319 | return EINVAL; |
317 | } | 320 | } |
321 | |||
318 | tuner_warn("TEA5767 detected.\n"); | 322 | tuner_warn("TEA5767 detected.\n"); |
319 | return 0; | 323 | return 0; |
320 | } | 324 | } |
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c index de190630babb..b25a9c08ac02 100644 --- a/drivers/media/video/tuner-core.c +++ b/drivers/media/video/tuner-core.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | * $Id: tuner-core.c,v 1.55 2005/07/08 13:20:33 mchehab Exp $ | 2 | * $Id: tuner-core.c,v 1.58 2005/07/14 03:06:43 mchehab Exp $ |
3 | * | 3 | * |
4 | * i2c tv tuner chip device driver | 4 | * i2c tv tuner chip device driver |
5 | * core core, i.e. kernel interfaces, registering and so on | 5 | * core core, i.e. kernel interfaces, registering and so on |
@@ -39,6 +39,9 @@ I2C_CLIENT_INSMOD; | |||
39 | static unsigned int addr = 0; | 39 | static unsigned int addr = 0; |
40 | module_param(addr, int, 0444); | 40 | module_param(addr, int, 0444); |
41 | 41 | ||
42 | static unsigned int no_autodetect = 0; | ||
43 | module_param(no_autodetect, int, 0444); | ||
44 | |||
42 | /* insmod options used at runtime => read/write */ | 45 | /* insmod options used at runtime => read/write */ |
43 | unsigned int tuner_debug = 0; | 46 | unsigned int tuner_debug = 0; |
44 | module_param(tuner_debug, int, 0644); | 47 | module_param(tuner_debug, int, 0644); |
@@ -318,17 +321,19 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) | |||
318 | tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); | 321 | tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); |
319 | 322 | ||
320 | /* TEA5767 autodetection code - only for addr = 0xc0 */ | 323 | /* TEA5767 autodetection code - only for addr = 0xc0 */ |
321 | if (addr == 0x60) { | 324 | if (!no_autodetect) { |
322 | if (tea5767_autodetection(&t->i2c) != EINVAL) { | 325 | if (addr == 0x60) { |
323 | t->type = TUNER_TEA5767; | 326 | if (tea5767_autodetection(&t->i2c) != EINVAL) { |
324 | t->mode_mask = T_RADIO; | 327 | t->type = TUNER_TEA5767; |
325 | t->mode = T_STANDBY; | 328 | t->mode_mask = T_RADIO; |
326 | t->freq = 87.5 * 16; /* Sets freq to FM range */ | 329 | t->mode = T_STANDBY; |
327 | default_mode_mask &= ~T_RADIO; | 330 | t->freq = 87.5 * 16; /* Sets freq to FM range */ |
328 | 331 | default_mode_mask &= ~T_RADIO; | |
329 | i2c_attach_client (&t->i2c); | 332 | |
330 | set_type(&t->i2c,t->type, t->mode_mask); | 333 | i2c_attach_client (&t->i2c); |
331 | return 0; | 334 | set_type(&t->i2c,t->type, t->mode_mask); |
335 | return 0; | ||
336 | } | ||
332 | } | 337 | } |
333 | } | 338 | } |
334 | 339 | ||
@@ -631,7 +636,9 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg) | |||
631 | break; | 636 | break; |
632 | } | 637 | } |
633 | default: | 638 | default: |
634 | tuner_dbg("Unimplemented IOCTL 0x%08x called to tuner.\n", cmd); | 639 | tuner_dbg("Unimplemented IOCTL 0x%08x(dir=%d,tp=0x%02x,nr=%d,sz=%d)\n", |
640 | cmd, _IOC_DIR(cmd), _IOC_TYPE(cmd), | ||
641 | _IOC_NR(cmd), _IOC_SIZE(cmd)); | ||
635 | break; | 642 | break; |
636 | } | 643 | } |
637 | 644 | ||