This commit was manufactured by cvs2svn to create tag
[linux-2.6.git] / drivers / media / video / tuner.c
index ec6eb43..bac17a3 100644 (file)
@@ -1,9 +1,4 @@
-/*
- * $Id: tuner.c,v 1.31 2004/11/10 11:07:24 kraxel Exp $
- */
-
 #include <linux/module.h>
-#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/string.h>
 #include <media/tuner.h>
 #include <media/audiochip.h>
 
-#define UNSET (-1U)
-
-/* standard i2c insmod options */
+/* Addresses to scan */
 static unsigned short normal_i2c[] = {I2C_CLIENT_END};
 static unsigned short normal_i2c_range[] = {0x60,0x6f,I2C_CLIENT_END};
 I2C_CLIENT_INSMOD;
 
-/* insmod options used at init time => read/only */
+#define UNSET (-1U)
+
+/* insmod options */
+static unsigned int debug =  0;
 static unsigned int type  =  UNSET;
 static unsigned int addr  =  0;
-module_param(type, int, 0444);
-module_param(addr, int, 0444);
-
-/* insmod options used at runtime => read/write */
-static unsigned int debug         = 0;
-static unsigned int tv_antenna    = 1;
-static unsigned int radio_antenna = 0;
-static unsigned int optimize_vco  = 1;
-module_param(debug,             int, 0644);
-module_param(tv_antenna,        int, 0644);
-module_param(radio_antenna,     int, 0644);
-module_param(optimize_vco,      int, 0644);
-
 static unsigned int tv_range[2]    = { 44, 958 };
 static unsigned int radio_range[2] = { 65, 108 };
+static unsigned int tv_antenna = 1;
+static unsigned int radio_antenna = 0;
+MODULE_PARM(debug,"i");
+MODULE_PARM(type,"i");
+MODULE_PARM(addr,"i");
+MODULE_PARM(tv_range,"2i");
+MODULE_PARM(radio_range,"2i");
+MODULE_PARM(tv_antenna,"i");
+MODULE_PARM(radio_antenna,"i");
 
-module_param_array(tv_range,    int, NULL, 0644);
-module_param_array(radio_range, int, NULL, 0644);
+#define optimize_vco 1
 
 MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
 MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
@@ -61,10 +52,10 @@ struct tuner {
        unsigned int freq;            /* keep track of the current settings */
        v4l2_std_id  std;
        int          using_v4l2;
-
+       
        unsigned int radio;
        unsigned int input;
-
+       
        // only for MT2032
        unsigned int xogc;
        unsigned int radio_if2;
@@ -80,11 +71,11 @@ static struct i2c_client client_template;
 
 /* tv standard selection for Temic 4046 FM5
    this value takes the low bits of control byte 2
-   from datasheet Rev.01, Feb.00
+   from datasheet Rev.01, Feb.00 
      standard     BG      I       L       L2      D
      picture IF   38.9    38.9    38.9    33.95   38.9
      sound 1      33.4    32.9    32.4    40.45   32.4
-     sound 2      33.16
+     sound 2      33.16   
      NICAM        33.05   32.348  33.05           33.05
  */
 #define TEMIC_SET_PAL_I         0x05
@@ -106,7 +97,7 @@ static struct i2c_client client_template;
 #define PHILIPS_SET_PAL_I      0x01 /* Bit 2 always zero !*/
 #define PHILIPS_SET_PAL_BGDK   0x09
 #define PHILIPS_SET_PAL_L2     0x0a
-#define PHILIPS_SET_PAL_L      0x0b
+#define PHILIPS_SET_PAL_L      0x0b    
 
 /* system switching for Philips FI1216MF MK2
    from datasheet "1996 Jul 09",
@@ -124,22 +115,21 @@ static struct i2c_client client_template;
 
 /* ---------------------------------------------------------------------- */
 
-struct tunertype
+struct tunertype 
 {
        char *name;
        unsigned char Vendor;
        unsigned char Type;
-
+  
        unsigned short thresh1;  /*  band switch VHF_LO <=> VHF_HI  */
        unsigned short thresh2;  /*  band switch VHF_HI <=> UHF     */
        unsigned char VHF_L;
        unsigned char VHF_H;
        unsigned char UHF;
-       unsigned char config;
-       unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL,
-                                  732  =16*45.75 NTSCi,
-                                  940  =16*58.75 NTSC-Japan
-                                  704  =16*44    ATSC */
+       unsigned char config; 
+       unsigned short IFPCoff; /* 622.4=16*38.90 MHz PAL, 
+                                  732  =16*45.75 NTSCi, 
+                                  940  =58.75 NTSC-Japan */
 };
 
 /*
@@ -180,7 +170,7 @@ static struct tunertype tuners[] = {
         { "Alps TSBC5", Alps, PAL, /* untested - data sheet guess. Only IF differs. */
          16*133.25,16*351.25,0x01,0x02,0x08,0x8e,608},
        { "Temic PAL_BG (4006FH5)", TEMIC, PAL,
-         16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623},
+         16*170.00,16*450.00,0xa0,0x90,0x30,0x8e,623}, 
        { "Alps TSCH6",Alps,NTSC,
          16*137.25,16*385.25,0x14,0x12,0x11,0x8e,732},
 
@@ -254,16 +244,10 @@ static struct tunertype tuners[] = {
        { "Panasonic VP27s/ENGE4324D", Panasonic, NTSC,
          16*160.00,16*454.00,0x01,0x02,0x08,0xce,940},
         { "LG NTSC (TAPE series)", LGINNOTEK, NTSC,
-          16*160.00,16*442.00,0x01,0x02,0x04,0x8e,732 },
+          16*170.00, 16*450.00, 0x01,0x02,0x04,0x8e,732 },
 
         { "Tenna TNF 8831 BGFF)", Philips, PAL,
           16*161.25,16*463.25,0xa0,0x90,0x30,0x8e,623},
-       { "Microtune 4042 FI5 ATSC/NTSC dual in", Microtune, NTSC,
-         16*162.00,16*457.00,0xa2,0x94,0x31,0x8e,732},
-        { "TCL 2002N", TCL, NTSC,
-          16*172.00,16*448.00,0x01,0x02,0x08,0x8e,732},
-       { "Philips PAL/SECAM_D (FM 1256 I-H3)", Philips, PAL,
-         16*160.00,16*442.00,0x01,0x02,0x04,0x8e,623 },
 
 };
 #define TUNERS ARRAY_SIZE(tuners)
@@ -432,7 +416,7 @@ static int mt2032_compute_freq(unsigned int rfin,
        if(rfin >400*1000*1000)
                 buf[6]=0xe4;
         else
-                buf[6]=0xf4; // set PKEN per rev 1.2
+                buf[6]=0xf4; // set PKEN per rev 1.2 
        buf[7]=8+xogc;
        buf[8]=0xc3; //reserved
        buf[9]=0x4e; //reserved
@@ -453,10 +437,10 @@ static int mt2032_check_lo_lock(struct i2c_client *c)
                i2c_master_recv(c,buf,1);
                dprintk("mt2032 Reg.E=0x%02x\n",buf[0]);
                lock=buf[0] &0x06;
-
+               
                if (lock==6)
                        break;
-
+               
                dprintk("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
                udelay(1000);
        }
@@ -478,7 +462,7 @@ static int mt2032_optimize_vco(struct i2c_client *c,int sel,int lock)
        if(tad1 ==1) return lock;
 
        if(tad1==2) {
-               if(sel==0)
+               if(sel==0) 
                        return lock;
                else sel--;
        }
@@ -531,13 +515,13 @@ static void mt2032_set_if_freq(struct i2c_client *c, unsigned int rfin,
        // wait for PLLs to lock (per manual), retry LINT if not.
        for(lint_try=0; lint_try<2; lint_try++) {
                lock=mt2032_check_lo_lock(c);
-
+               
                if(optimize_vco)
                        lock=mt2032_optimize_vco(c,sel,lock);
                if(lock==6) break;
-
-               printk("mt2032: re-init PLLs by LINT\n");
-               buf[0]=7;
+               
+               printk("mt2032: re-init PLLs by LINT\n"); 
+               buf[0]=7; 
                buf[1]=0x80 +8+t->xogc; // set LINT to re-init PLLs
                i2c_master_send(c,buf,2);
                mdelay(10);
@@ -662,46 +646,46 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
        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: ");
@@ -709,7 +693,7 @@ static void mt2050_set_if_freq(struct i2c_client *c,unsigned int freq, unsigned
                        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);
@@ -719,7 +703,7 @@ 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->std & V4L2_STD_525_60) {
                // NTSC
                 if2 = 45750*1000;
@@ -735,7 +719,7 @@ 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);
        mt2050_set_antenna(c, radio_antenna);
 }
@@ -745,19 +729,19 @@ 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;
@@ -770,7 +754,7 @@ static int microtune_init(struct i2c_client *c)
        char *name;
         unsigned char buf[21];
        int company_code;
-
+       
        memset(buf,0,sizeof(buf));
        t->tv_freq    = NULL;
        t->radio_freq = NULL;
@@ -839,17 +823,13 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
         unsigned char buffer[4];
        int rc;
 
-       tun = &tuners[t->type];
-       if (freq < tun->thresh1) {
+       tun=&tuners[t->type];
+       if (freq < tun->thresh1) 
                config = tun->VHF_L;
-               dprintk("tv: VHF lowrange\n");
-       } else if (freq < tun->thresh2) {
+       else if (freq < tun->thresh2) 
                config = tun->VHF_H;
-               dprintk("tv: VHF high range\n");
-       } else {
+       else
                config = tun->UHF;
-               dprintk("tv: UHF range\n");
-       }
 
 
        /* tv norm specific stuff for multi-norm tuners */
@@ -902,17 +882,13 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
                /* 0x02 -> NTSC antenna input 1 */
                /* 0x03 -> NTSC antenna input 2 */
                config &= ~0x03;
-               if (!(t->std & V4L2_STD_ATSC))
+               if (t->std & V4L2_STD_ATSC)
                        config |= 2;
                /* FIXME: input */
                break;
-
-       case TUNER_MICROTUNE_4042FI5:
-               /* Set the charge pump for fast tuning */
-               tun->config |= 0x40;
-               break;
        }
 
+       
        /*
         * Philips FI1216MK2 remark from specification :
         * for channel selection involving band switching, and to ensure
@@ -945,37 +921,6 @@ static void default_set_tv_freq(struct i2c_client *c, unsigned int freq)
         if (4 != (rc = i2c_master_send(c,buffer,4)))
                 printk("tuner: i2c i/o error: rc == %d (should be 4)\n",rc);
 
-       if (t->type == TUNER_MICROTUNE_4042FI5) {
-               // FIXME - this may also work for other tuners
-               unsigned long timeout = jiffies + msecs_to_jiffies(1);
-               u8 status_byte = 0;
-
-               /* Wait until the PLL locks */
-               for (;;) {
-                       if (time_after(jiffies,timeout))
-                               return;
-                       if (1 != (rc = i2c_master_recv(c,&status_byte,1))) {
-                               dprintk("tuner: i2c i/o read error: rc == %d (should be 1)\n",rc);
-                               break;
-                       }
-                       /* bit 6 is PLL locked indicator */
-                       if (status_byte & 0x40)
-                               break;
-                       udelay(10);
-               }
-
-               /* Set the charge pump for optimized phase noise figure */
-               tun->config &= ~0x40;
-               buffer[0] = (div>>8) & 0x7f;
-               buffer[1] = div      & 0xff;
-               buffer[2] = tun->config;
-               buffer[3] = config;
-               dprintk("tuner: tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
-                       buffer[0],buffer[1],buffer[2],buffer[3]);
-
-               if (4 != (rc = i2c_master_send(c,buffer,4)))
-                       dprintk("tuner: i2c i/o error: rc == %d (should be 4)\n",rc);
-       }
 }
 
 static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
@@ -988,18 +933,14 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
 
        tun=&tuners[t->type];
        div = freq + (int)(16*10.7);
+        buffer[0] = (div>>8) & 0x7f;
+        buffer[1] = div      & 0xff;
        buffer[2] = tun->config;
-
        switch (t->type) {
        case TUNER_PHILIPS_FM1216ME_MK3:
        case TUNER_PHILIPS_FM1236_MK3:
                buffer[3] = 0x19;
                break;
-       case TUNER_PHILIPS_FM1256_IH3:
-               div = (20 * freq)/16 + 333 * 2;
-               buffer[2] = 0x80;
-               buffer[3] = 0x19;
-               break;
        case TUNER_LG_PAL_FM:
                buffer[3] = 0xa5;
                break;
@@ -1007,8 +948,6 @@ static void default_set_radio_freq(struct i2c_client *c, unsigned int freq)
                buffer[3] = 0xa4;
                break;
        }
-        buffer[0] = (div>>8) & 0x7f;
-        buffer[1] = div      & 0xff;
 
        dprintk("tuner: radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
                buffer[0],buffer[1],buffer[2],buffer[3]);
@@ -1085,7 +1024,7 @@ static void set_type(struct i2c_client *c, unsigned int type, char *source)
 {
        struct tuner *t = i2c_get_clientdata(c);
 
-       if (t->type != UNSET && t->type != TUNER_ABSENT) {
+       if (t->type != UNSET) {
                if (t->type != type)
                        printk("tuner: type already set to %d, "
                               "ignoring request for %d\n", t->type, type);
@@ -1110,8 +1049,8 @@ static void set_type(struct i2c_client *c, unsigned int type, char *source)
        }
 }
 
-static char pal[] = "-";
-module_param_string(pal, pal, 0644, sizeof(pal));
+static char *pal = "-";
+MODULE_PARM(pal,"s");
 
 static int tuner_fixup_std(struct tuner *t)
 {
@@ -1152,7 +1091,7 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
        if (this_adap > 0)
                return -1;
        this_adap++;
-
+       
         client_template.adapter = adap;
         client_template.addr = addr;
 
@@ -1254,7 +1193,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                        break;
                }
                 break;
-
+               
        /* --- v4l ioctls --- */
        /* take care: bttv does userspace copying, we'll get a
           kernel pointer here... */
@@ -1349,25 +1288,7 @@ tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
                /* nothing */
                break;
        }
-
-       return 0;
-}
-
-static int tuner_suspend(struct device * dev, u32 state, u32 level)
-{
-       dprintk("tuner: suspend\n");
-       /* FIXME: power down ??? */
-       return 0;
-}
-
-static int tuner_resume(struct device * dev, u32 level)
-{
-       struct i2c_client *c = container_of(dev, struct i2c_client, dev);
-       struct tuner *t = i2c_get_clientdata(c);
-
-       dprintk("tuner: resume\n");
-       if (t->freq)
-               set_freq(c,t->freq);
+       
        return 0;
 }
 
@@ -1381,10 +1302,6 @@ static struct i2c_driver driver = {
         .attach_adapter = tuner_probe,
         .detach_client  = tuner_detach,
         .command        = tuner_command,
-       .driver = {
-               .suspend = tuner_suspend,
-               .resume  = tuner_resume,
-       },
 };
 static struct i2c_client client_template =
 {