
From: Gerd Knorr <kraxel@bytesex.org>

This is a i2c tuner module update.  Changes:

* adds support for more tunes (mt2050, atsc, ...)

* some reorganization, uses function pointers to branch to different
  functions for different tuner types.



---

 drivers/media/video/tuner.c |  539 ++++++++++++++++++++++++++++++--------------
 include/media/tuner.h       |    6 
 2 files changed, 382 insertions(+), 163 deletions(-)

diff -puN drivers/media/video/tuner.c~v4l-07-tuner-update drivers/media/video/tuner.c
--- 25/drivers/media/video/tuner.c~v4l-07-tuner-update	2004-01-15 08:27:45.000000000 -0800
+++ 25-akpm/drivers/media/video/tuner.c	2004-01-15 08:27:45.000000000 -0800
@@ -45,18 +45,21 @@ MODULE_LICENSE("GPL");
 static int this_adap;
 #define dprintk     if (debug) printk
 
-struct tuner
-{
+struct tuner {
 	unsigned int type;            /* chip type */
 	unsigned int freq;            /* keep track of the current settings */
 	unsigned int std;
 	
 	unsigned int radio;
 	unsigned int mode;            /* current norm for multi-norm tuners */
+	unsigned int input;
 	
 	// only for MT2032
 	unsigned int xogc;
 	unsigned int radio_if2;
+
+	void (*tv_freq)(struct i2c_client *c, unsigned int freq);
+	void (*radio_freq)(struct i2c_client *c, unsigned int freq);
 };
 
 static struct i2c_driver driver;
@@ -207,7 +210,7 @@ static struct tunertype tuners[] = {
 
 	{ "Samsung PAL TCPM9091PD27", Samsung, PAL,  /* from sourceforge v3tv */
           16*169,16*464,0xA0,0x90,0x30,0x8e,623},
-	{ "MT2032 universal", Microtune,PAL|NTSC,
+	{ "MT20xx universal", Microtune,PAL|NTSC,
                0,0,0,0,0,0,0},
 	{ "Temic PAL_BG (4106 FH5)", TEMIC, PAL,
           16*141.00, 16*464.00, 0xa0,0x90,0x30,0x8e,623},
@@ -225,6 +228,12 @@ static struct tunertype tuners[] = {
 
 	{ "HITACHI V7-J180AT", HITACHI, NTSC,
 	  16*170.00, 16*450.00, 0x01,0x02,0x00,0x8e,940 },
+	{ "Philips PAL_MK (FI1216 MK)", Philips, PAL,
+	  16*140.25,16*463.25,0x01,0xc2,0xcf,0x8e,623},
+	{ "Philips 1236D ATSC/NTSC daul in",Philips,ATSC,
+	  16*157.25,16*454.00,0xa0,0x90,0x30,0x8e,732},
+        { "Philips NTSC MK3 (FM1236MK3 or FM1236/F)", Philips, NTSC,
+          16*160.00,16*442.00,0x01,0x02,0x04,0x8,732},
 };
 #define TUNERS ARRAY_SIZE(tuners)
 
@@ -279,86 +288,19 @@ static int tuner_mode (struct i2c_client
 }
 #endif
 
-// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
-static int mt2032_init(struct i2c_client *c)
-{
-        unsigned char buf[21];
-        int ret,xogc,xok=0;
-	struct tuner *t = i2c_get_clientdata(c);
-
-        buf[0]=0;
-        ret=i2c_master_send(c,buf,1);
-        i2c_master_recv(c,buf,21);
-
-        printk("MT2032: Companycode=%02x%02x Part=%02x Revision=%02x\n",
-                buf[0x11],buf[0x12],buf[0x13],buf[0x14]);
-
-        if(debug) {
-                int i;
-                printk("MT2032 hexdump:\n");
-                for(i=0;i<21;i++) {
-                        printk(" %02x",buf[i]);
-                        if(((i+1)%8)==0) printk(" ");
-                        if(((i+1)%16)==0) printk("\n ");
-                }
-                printk("\n ");
-        }
-	// Look for MT2032 id:
-	// part= 0x04(MT2032), 0x06(MT2030), 0x07(MT2040)
-        if((buf[0x11] != 0x4d) || (buf[0x12] != 0x54) || (buf[0x13] != 0x04)) {
-                printk("not a MT2032.\n");
-                return 0;
-        }
-
-
-        // Initialize Registers per spec.
-        buf[1]=2; // Index to register 2
-        buf[2]=0xff;
-        buf[3]=0x0f;
-        buf[4]=0x1f;
-        ret=i2c_master_send(c,buf+1,4);
-
-        buf[5]=6; // Index register 6
-        buf[6]=0xe4;
-        buf[7]=0x8f;
-        buf[8]=0xc3;
-        buf[9]=0x4e;
-        buf[10]=0xec;
-        ret=i2c_master_send(c,buf+5,6);
-
-        buf[12]=13;  // Index register 13
-        buf[13]=0x32;
-        ret=i2c_master_send(c,buf+12,2);
-
-        // Adjust XOGC (register 7), wait for XOK
-        xogc=7;
-        do {
-		dprintk("mt2032: xogc = 0x%02x\n",xogc&0x07);
-                mdelay(10);
-                buf[0]=0x0e;
-                i2c_master_send(c,buf,1);
-                i2c_master_recv(c,buf,1);
-                xok=buf[0]&0x01;
-                dprintk("mt2032: xok = 0x%02x\n",xok);
-                if (xok == 1) break;
-
-                xogc--;
-                dprintk("mt2032: xogc = 0x%02x\n",xogc&0x07);
-                if (xogc == 3) {
-                        xogc=4; // min. 4 per spec
-                        break;
-                }
-                buf[0]=0x07;
-                buf[1]=0x88 + xogc;
-                ret=i2c_master_send(c,buf,2);
-                if (ret!=2)
-                        printk("mt2032_init failed with %d\n",ret);
-        } while (xok != 1 );
-	t->xogc=xogc;
-
-        return(1);
-}
+/* ---------------------------------------------------------------------- */
 
+#define MT2032 0x04
+#define MT2030 0x06
+#define MT2040 0x07
+#define MT2050 0x42
+
+static char *microtune_part[] = {
+	[ MT2030 ] = "MT2030",
+	[ MT2032 ] = "MT2032",
+	[ MT2040 ] = "MT2040",
+	[ MT2050 ] = "MT2050",
+};
 
 // IsSpurInBand()?
 static int mt2032_spurcheck(int f1, int f2, int spectrum_from,int spectrum_to)
@@ -583,13 +525,13 @@ static void mt2032_set_if_freq(struct i2
 }
 
 
-static void mt2032_set_tv_freq(struct i2c_client *c,
-			       unsigned int freq, unsigned int norm)
+static void mt2032_set_tv_freq(struct i2c_client *c, unsigned int freq)
 {
+	struct tuner *t = i2c_get_clientdata(c);
 	int if2,from,to;
 
 	// signal bandwidth and picture carrier
-	if (norm==VIDEO_MODE_NTSC) {
+	if (t->mode == VIDEO_MODE_NTSC) {
 		from=40750*1000;
 		to=46750*1000;
 		if2=45750*1000; 
@@ -604,36 +546,248 @@ static void mt2032_set_tv_freq(struct i2
 			   1090*1000*1000, if2, from, to);
 }
 
+static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+	int if2 = t->radio_if2;
 
-// Set tuner frequency,  freq in Units of 62.5kHz = 1/16MHz
-static void set_tv_freq(struct i2c_client *c, unsigned int freq)
+	// per Manual for FM tuning: first if center freq. 1085 MHz
+        mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
+			   1085*1000*1000,if2,if2,if2);
+}
+
+// Initalization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
+static int mt2032_init(struct i2c_client *c)
 {
-	u8 config;
-	u16 div;
-	struct tunertype *tun;
 	struct tuner *t = i2c_get_clientdata(c);
-        unsigned char buffer[4];
-	int rc;
+        unsigned char buf[21];
+        int ret,xogc,xok=0;
 
-	if (t->type == UNSET) {
-		printk("tuner: tuner type not set\n");
-		return;
-	}
-	if (t->type == TUNER_MT2032) {
-		mt2032_set_tv_freq(c,freq,t->mode);
-		return;
+	// Initialize Registers per spec.
+        buf[1]=2; // Index to register 2
+        buf[2]=0xff;
+        buf[3]=0x0f;
+        buf[4]=0x1f;
+        ret=i2c_master_send(c,buf+1,4);
+
+        buf[5]=6; // Index register 6
+        buf[6]=0xe4;
+        buf[7]=0x8f;
+        buf[8]=0xc3;
+        buf[9]=0x4e;
+        buf[10]=0xec;
+        ret=i2c_master_send(c,buf+5,6);
+
+        buf[12]=13;  // Index register 13
+        buf[13]=0x32;
+        ret=i2c_master_send(c,buf+12,2);
+
+        // Adjust XOGC (register 7), wait for XOK
+        xogc=7;
+        do {
+		dprintk("mt2032: xogc = 0x%02x\n",xogc&0x07);
+                mdelay(10);
+                buf[0]=0x0e;
+                i2c_master_send(c,buf,1);
+                i2c_master_recv(c,buf,1);
+                xok=buf[0]&0x01;
+                dprintk("mt2032: xok = 0x%02x\n",xok);
+                if (xok == 1) break;
+
+                xogc--;
+                dprintk("mt2032: xogc = 0x%02x\n",xogc&0x07);
+                if (xogc == 3) {
+                        xogc=4; // min. 4 per spec
+                        break;
+                }
+                buf[0]=0x07;
+                buf[1]=0x88 + xogc;
+                ret=i2c_master_send(c,buf,2);
+                if (ret!=2)
+                        printk("mt2032_init failed with %d\n",ret);
+        } while (xok != 1 );
+	t->xogc=xogc;
+
+	t->tv_freq    = mt2032_set_tv_freq;
+	t->radio_freq = mt2032_set_radio_freq;
+        return(1);
+}
+
+static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned int if2)
+{
+	unsigned int if1=1218*1000*1000;
+	unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b;
+	int ret;
+	unsigned char buf[6];
+	
+	dprintk("mt2050_set_if_freq freq=%d\n",freq);
+	
+	f_lo1=freq+if1;
+	f_lo1=(f_lo1/1000000)*1000000;
+	
+	f_lo2=f_lo1-freq-if2;
+	f_lo2=(f_lo2/50000)*50000;
+	
+	lo1=f_lo1/4000000;
+	lo2=f_lo2/4000000;
+	
+	f_lo1_modulo= f_lo1-(lo1*4000000);
+	f_lo2_modulo= f_lo2-(lo2*4000000);
+	
+	num1=4*f_lo1_modulo/4000000;
+	num2=4096*(f_lo2_modulo/1000)/4000;
+	
+	// todo spurchecks
+	
+	div1a=(lo1/12)-1;
+	div1b=lo1-(div1a+1)*12;
+	
+	div2a=(lo2/8)-1;
+	div2b=lo2-(div2a+1)*8;
+	
+	dprintk("lo1 lo2 = %d %d\n", lo1, lo2);
+        dprintk("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",num1,num2,div1a,div1b,div2a,div2b);
+	
+	
+	buf[0]=1;
+	buf[1]= 4*div1b + num1;
+	if(freq<275*1000*1000) buf[1] = buf[1]|0x80;
+	
+	buf[2]=div1a;
+	buf[3]=32*div2b + num2/256;
+	buf[4]=num2-(num2/256)*256;
+	buf[5]=div2a;
+	if(num2!=0) buf[5]=buf[5]|0x40;
+	
+	if(debug) {
+		int i;
+		printk("bufs is: ");
+		for(i=0;i<6;i++)
+			printk("%x ",buf[i]);
+		printk("\n");
 	}
+	
+	ret=i2c_master_send(c,buf,6);
+        if (ret!=6)
+                printk("mt2050_set_if_freq failed with %d\n",ret);
+}
 
-	if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
-		/* FIXME: better do that chip-specific, but
-		   right now we don't have that in the config
-		   struct and this way is still better than no
-		   check at all */
-		printk("tuner: TV freq (%d.%02d) out of range (%d-%d)\n",
-		       freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
-		return;
+static void mt2050_set_tv_freq(struct i2c_client *c, unsigned int freq)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+	unsigned int if2;
+	
+	if (t->mode == VIDEO_MODE_NTSC) {
+                if2=45750*1000;
+        } else {
+                // Pal
+                if2=38900*1000;
+        }
+	mt2050_set_if_freq(c,freq*62500,if2);
+}
+
+static void mt2050_set_radio_freq(struct i2c_client *c, unsigned int freq)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+	int if2 = t->radio_if2;
+	
+	mt2050_set_if_freq(c, freq*62500, if2);
+}
+
+static int mt2050_init(struct i2c_client *c)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+	unsigned char buf[2];
+	int ret;
+	
+	buf[0]=6;
+	buf[1]=0x10;
+	ret=i2c_master_send(c,buf,2); //  power
+	
+	buf[0]=0x0f;
+	buf[1]=0x0f;
+	ret=i2c_master_send(c,buf,2); // m1lo
+	
+	buf[0]=0x0d;
+	ret=i2c_master_send(c,buf,1);
+	i2c_master_recv(c,buf,1);
+	
+	dprintk("mt2050: sro is %x\n",buf[0]);
+	t->tv_freq    = mt2050_set_tv_freq;
+	t->radio_freq = mt2050_set_radio_freq;
+	return 0;
+}
+
+static int microtune_init(struct i2c_client *c)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+	char *name;
+        unsigned char buf[21];
+	int company_code;
+	
+        buf[0] = 0;
+	t->tv_freq = NULL;
+	t->radio_freq = NULL;
+	name = "unknown";
+
+        i2c_master_send(c,buf,1);
+        i2c_master_recv(c,buf,21);
+        if(debug) {
+                int i;
+                printk(KERN_DEBUG "tuner: MT2032 hexdump:\n");
+                for(i=0;i<21;i++) {
+                        printk(" %02x",buf[i]);
+                        if(((i+1)%8)==0) printk(" ");
+                        if(((i+1)%16)==0) printk("\n ");
+                }
+                printk("\n ");
+        }
+	company_code = buf[0x11] << 8 | buf[0x12];
+        printk("tuner: microtune: companycode=%04x part=%02x rev=%02x\n",
+	       company_code,buf[0x13],buf[0x14]);
+	switch (company_code) {
+	case 0x3cbf:
+	case 0x3dbf:
+	case 0x4d54:
+	case 0x8e81:
+	case 0x8e91:
+		/* ok (?) */
+		break;
+	default:
+		printk("tuner: microtune: unknown companycode\n");
+		return 0;
 	}
 
+	if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
+	    NULL != microtune_part[buf[0x13]])
+		name = microtune_part[buf[0x13]];
+	switch (buf[0x13]) {
+	case MT2032:
+		mt2032_init(c);
+		break;
+	case MT2050:
+		mt2050_init(c);
+		break;
+	default:
+		printk("tuner: microtune %s found, not (yet?) supported, sorry :-/\n",
+		       name);
+                return 0;
+        }
+	printk("tuner: microtune %s found, OK\n",name);
+	return 0;
+}
+
+/* ---------------------------------------------------------------------- */
+
+static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+	u8 config;
+	u16 div;
+	struct tunertype *tun;
+        unsigned char buffer[4];
+	int rc;
+
 	tun=&tuners[t->type];
 	if (freq < tun->thresh1) 
 		config = tun->VHF_L;
@@ -700,6 +854,20 @@ static void set_tv_freq(struct i2c_clien
 			break;
 		}
 		break;
+
+	case TUNER_PHILIPS_ATSC:
+		/* 0x00 -> ATSC antenna input 1 */
+		/* 0x01 -> ATSC antenna input 2 */
+		/* 0x02 -> NTSC antenna input 1 */
+		/* 0x03 -> NTSC antenna input 2 */
+		
+		config &= ~0x03;
+#ifdef VIDEO_MODE_ATSC
+		if (VIDEO_MODE_ATSC != t->mode)
+			config |= 2;
+#endif
+		/* FIXME: input */
+		break;
 	}
 
 	
@@ -737,17 +905,7 @@ static void set_tv_freq(struct i2c_clien
 
 }
 
-static void mt2032_set_radio_freq(struct i2c_client *c, unsigned int freq)
-{
-	struct tuner *t = i2c_get_clientdata(c);
-	int if2 = t->radio_if2;
-
-	// per Manual for FM tuning: first if center freq. 1085 MHz
-        mt2032_set_if_freq(c, freq*62500 /* freq*1000*1000/16 */,
-			   1085*1000*1000,if2,if2,if2);
-}
-
-static void set_radio_freq(struct i2c_client *c, unsigned int freq)
+static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
 {
 	struct tunertype *tun;
 	struct tuner *t = i2c_get_clientdata(c);
@@ -755,22 +913,6 @@ static void set_radio_freq(struct i2c_cl
 	unsigned div;
 	int rc;
 
-	if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
-		printk("tuner: radio freq (%d.%02d) out of range (%d-%d)\n",
-		       freq/16,freq%16*100/16,
-		       radio_range[0],radio_range[1]);
-		return;
-	}
-	if (t->type == UNSET) {
-		printk("tuner: tuner type not set\n");
-		return;
-	}
-
-        if (t->type == TUNER_MT2032) {
-                mt2032_set_radio_freq(c,freq);
-		return;
-	}
-
 	tun=&tuners[t->type];
 	div = freq + (int)(16*10.7);
         buffer[0] = (div>>8) & 0x7f;
@@ -778,6 +920,7 @@ static void set_radio_freq(struct i2c_cl
 	buffer[2] = tun->config;
 	switch (t->type) {
 	case TUNER_PHILIPS_FM1216ME_MK3:
+	case TUNER_PHILIPS_FM1236_MK3:
 		buffer[3] = 0x19;
 		break;
 	default:
@@ -794,6 +937,80 @@ static void set_radio_freq(struct i2c_cl
 
 /* ---------------------------------------------------------------------- */
 
+// Set tuner frequency,  freq in Units of 62.5kHz = 1/16MHz
+static void set_tv_freq(struct i2c_client *c, unsigned int freq)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+
+	if (t->type == UNSET) {
+		printk("tuner: tuner type not set\n");
+		return;
+	}
+	if (NULL == t->tv_freq) {
+		printk("tuner: Huh? tv_set is NULL?\n");
+		return;
+	}
+	if (freq < tv_range[0]*16 || freq > tv_range[1]*16) {
+		/* FIXME: better do that chip-specific, but
+		   right now we don't have that in the config
+		   struct and this way is still better than no
+		   check at all */
+		printk("tuner: TV freq (%d.%02d) out of range (%d-%d)\n",
+		       freq/16,freq%16*100/16,tv_range[0],tv_range[1]);
+		return;
+	}
+	t->tv_freq(c,freq);
+}
+
+static void set_radio_freq(struct i2c_client *c, unsigned int freq)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+
+	if (t->type == UNSET) {
+		printk("tuner: tuner type not set\n");
+		return;
+	}
+	if (NULL == t->radio_freq) {
+		printk("tuner: no radio tuning for this one, sorry.\n");
+		return;
+	}
+	if (freq < radio_range[0]*16 || freq > radio_range[1]*16) {
+		printk("tuner: radio freq (%d.%02d) out of range (%d-%d)\n",
+		       freq/16,freq%16*100/16,
+		       radio_range[0],radio_range[1]);
+		return;
+	}
+	t->radio_freq(c,freq);
+}
+
+static void set_type(struct i2c_client *c, unsigned int type)
+{
+	struct tuner *t = i2c_get_clientdata(c);
+
+	if (t->type != UNSET) {
+		printk("tuner: type already set (%d)\n",t->type);
+		return;
+	}
+	if (type >= TUNERS)
+		return;
+
+	t->type = type;
+	printk("tuner: type set to %d (%s)\n", t->type,tuners[t->type].name);
+	strlcpy(c->name, tuners[t->type].name, sizeof(c->name));
+
+	switch (t->type) {
+	case TUNER_MT2032:
+		microtune_init(c);
+		break;
+	default:
+		t->tv_freq    = default_set_tv_freq;
+		t->radio_freq = default_set_radio_freq;
+		break;
+	}
+}
+
+/* ---------------------------------------------------------------------- */
+
 static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
 {
 	struct tuner *t;
@@ -821,15 +1038,12 @@ static int tuner_attach(struct i2c_adapt
 	t->type       = UNSET;
 	t->radio_if2  = 10700*1000; // 10.7MHz - FM radio
 
+        i2c_attach_client(client);
 	if (type < TUNERS) {
-		t->type = type;
-		printk("tuner(bttv): type forced to %d (%s) [insmod]\n",t->type,tuners[t->type].name);
-		strlcpy(client->name, tuners[t->type].name, I2C_NAME_SIZE);
+		printk("tuner: type forced to %d (%s) [insmod]\n",
+		       t->type,tuners[t->type].name);
+		set_type(client,type);
 	}
-        i2c_attach_client(client);
-        if (t->type == TUNER_MT2032)
-                 mt2032_init(client);
-
 	return 0;
 }
 
@@ -841,8 +1055,19 @@ static int tuner_probe(struct i2c_adapte
 	}
 	this_adap = 0;
 
+#ifdef I2C_ADAP_CLASS_TV_ANALOG
 	if (adap->class & I2C_ADAP_CLASS_TV_ANALOG)
 		return i2c_probe(adap, &addr_data, tuner_attach);
+#else
+	switch (adap->id) {
+	case I2C_ALGO_BIT | I2C_HW_B_BT848:
+	case I2C_ALGO_BIT | I2C_HW_B_RIVA:
+	case I2C_ALGO_SAA7134:
+	case I2C_ALGO_SAA7146:
+		return i2c_probe(adap, &addr_data, tuner_attach);
+		break;
+	}
+#endif
 	return 0;
 }
 
@@ -866,21 +1091,13 @@ tuner_command(struct i2c_client *client,
 
 	/* --- configuration --- */
 	case TUNER_SET_TYPE:
-		if (t->type != UNSET) {
-			printk("tuner: type already set (%d)\n",t->type);
-			return 0;
-		}
-		if (*iarg >= TUNERS)
-			return 0;
-		t->type = *iarg;
-		printk("tuner: type set to %d (%s)\n",
-                        t->type,tuners[t->type].name);
-		strlcpy(client->name, tuners[t->type].name, I2C_NAME_SIZE);
-		if (t->type == TUNER_MT2032)
-                        mt2032_init(client);
+		set_type(client,*iarg);
 		break;
 	case AUDC_SET_RADIO:
-		t->radio = 1;
+		if (!t->radio) {
+			set_tv_freq(client,400 * 16);
+			t->radio = 1;
+		}
 		break;
 	case AUDC_CONFIG_PINNACLE:
 		switch (*iarg) {
@@ -913,12 +1130,12 @@ tuner_command(struct i2c_client *client,
 		unsigned long *v = arg;
 
 		if (t->radio) {
-			dprintk("tuner: radio freq set to %d.%02d\n",
-				(*iarg)/16,(*iarg)%16*100/16);
+			dprintk("tuner: radio freq set to %lu.%02lu\n",
+				(*v)/16,(*v)%16*100/16);
 			set_radio_freq(client,*v);
 		} else {
-			dprintk("tuner: tv freq set to %d.%02d\n",
-				(*iarg)/16,(*iarg)%16*100/16);
+			dprintk("tuner: tv freq set to %lu.%02lu\n",
+				(*v)/16,(*v)%16*100/16);
 			set_tv_freq(client,*v);
 		}
 		t->freq = *v;
@@ -960,9 +1177,9 @@ static struct i2c_driver driver = {
 };
 static struct i2c_client client_template =
 {
-	.flags  = I2C_CLIENT_ALLOW_USE,
-	.driver = &driver,
-	.name   = "(tuner unset)",
+	I2C_DEVNAME("(tuner unset)"),
+	.flags      = I2C_CLIENT_ALLOW_USE,
+        .driver     = &driver,
 };
 
 static int tuner_init_module(void)
diff -puN include/media/tuner.h~v4l-07-tuner-update include/media/tuner.h
--- 25/include/media/tuner.h~v4l-07-tuner-update	2004-01-15 08:27:45.000000000 -0800
+++ 25-akpm/include/media/tuner.h	2004-01-15 08:27:45.000000000 -0800
@@ -65,14 +65,16 @@
 #define TUNER_PHILIPS_FM1216ME_MK3  38
 #define TUNER_LG_NTSC_NEW_TAPC   39
 #define TUNER_HITACHI_NTSC       40
-
-
+#define TUNER_PHILIPS_PAL_MK     41
+#define TUNER_PHILIPS_ATSC       42
+#define TUNER_PHILIPS_FM1236_MK3  43
 
 #define NOTUNER 0
 #define PAL     1	/* PAL_BG */
 #define PAL_I   2
 #define NTSC    3
 #define SECAM   4
+#define ATSC    5
 
 #define NoTuner 0
 #define Philips 1

_
