diff options
Diffstat (limited to 'linux')
-rw-r--r-- | linux/drivers/media/video/tea5767.c | 38 | ||||
-rw-r--r-- | linux/drivers/media/video/tuner-core.c | 16 |
2 files changed, 50 insertions, 4 deletions
diff --git a/linux/drivers/media/video/tea5767.c b/linux/drivers/media/video/tea5767.c index c3154c740..c77e4f5ae 100644 --- a/linux/drivers/media/video/tea5767.c +++ b/linux/drivers/media/video/tea5767.c @@ -2,10 +2,13 @@ * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview * I2C address is allways 0xC0. * - * $Id: tea5767.c,v 1.9 2005/06/19 20:05:12 mchehab Exp $ + * $Id: tea5767.c,v 1.10 2005/06/19 23:52:22 mchehab Exp $ * * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@brturbo.com.br) * This code is placed under the terms of the GNU General Public License + * + * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa + * from their contributions on DScaler. */ #include <linux/module.h> @@ -297,10 +300,43 @@ static int tea5767_stereo(struct i2c_client *c) return ( (buffer[2] & TEA5767_STEREO_MASK) ? V4L2_TUNER_SUB_STEREO: 0); } +int tea_detection(struct i2c_client *c) +{ + unsigned char buffer[7]= { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + int rc; + struct tuner *t = i2c_get_clientdata(c); + + if (5 != (rc = i2c_master_recv(c,buffer,5))) { + tuner_warn ( "it is not a TEA5767. Received %i chars.\n",rc ); + return EINVAL; + } + + /* If all bytes are the same then it's a TV tuner and not a tea5767 chip. */ + if (buffer[0] == buffer[1] && buffer[0] == buffer[2] && + buffer[0] == buffer[3] && buffer[0] == buffer[4]) { + tuner_warn ( "All bytes are equal. It is not a TEA5767\n" ); + return EINVAL; + } + + /* Status bytes: + Byte 4: bit 3:1 : CI (Chip Identification) == 0 + bit 0 : internally set to 0 + Byte 5: bit 7:0 : == 0 */ + + if (!((buffer[3] & 0x0f) == 0x00) && (buffer[4] == 0x00)) { + tuner_warn ( "Chip ID is not zero. It is not a TEA5767\n" ); + return EINVAL; + } + tuner_warn ( "TEA5767 detected.\n" ); + return 0; +} + int tea5767_tuner_init(struct i2c_client *c) { struct tuner *t = i2c_get_clientdata(c); + if (tea_detection(c)==EINVAL) return EINVAL; + tuner_info("type set to %d (%s)\n", t->type, TEA5767_TUNER_NAME); strlcpy(c->name, TEA5767_TUNER_NAME, sizeof(c->name)); diff --git a/linux/drivers/media/video/tuner-core.c b/linux/drivers/media/video/tuner-core.c index e360a5c02..bda1fbbda 100644 --- a/linux/drivers/media/video/tuner-core.c +++ b/linux/drivers/media/video/tuner-core.c @@ -1,5 +1,5 @@ /* - * $Id: tuner-core.c,v 1.25 2005/06/19 20:05:12 mchehab Exp $ + * $Id: tuner-core.c,v 1.26 2005/06/19 23:52:22 mchehab Exp $ * * i2c tv tuner chip device driver * core core, i.e. kernel interfaces, registering and so on @@ -144,7 +144,6 @@ static void set_type(struct i2c_client *c, unsigned int type) struct tuner *t = i2c_get_clientdata(c); unsigned char buffer[4]; - tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type); /* sanity check */ if (type == UNSET || type == TUNER_ABSENT) return; @@ -171,7 +170,7 @@ static void set_type(struct i2c_client *c, unsigned int type) tda8290_init(c); break; case TUNER_TEA5767: - tea5767_tuner_init(c); + if (tea5767_tuner_init(c)==EINVAL) t->type=TUNER_ABSENT; break; case TUNER_PHILIPS_FMD1216ME_MK3: buffer[0] = 0x0b; @@ -186,9 +185,20 @@ static void set_type(struct i2c_client *c, unsigned int type) default_tuner_init(c); break; default: + /* TEA5767 autodetection code */ + if ( c->addr==0x60 ) { + if (tea5767_tuner_init(c)!=EINVAL) { + t->type = TUNER_TEA5767; + if (first_tuner == 0x60) + first_tuner++; + break; + } + } + default_tuner_init(c); break; } + tuner_dbg ("I2C addr 0x%02x with type %d\n",c->addr<<1,type); } #define CHECK_ADDR(tp,cmd,tun) if (client->addr!=tp) { \ |