Hi tuner friends,

This patch is against an (earlier) GPLv2 version of the em-code, and
as such falls under GPLv2 or later.

- fixed xc3028_tuner_get_frequency
- changed filename[50] to *filename to save some space
- re added the bytecode stuf, (shows up in windows USB traces...)
- priv->frequency now contains the "exact" discrete pll frequency.

Btw, I hope we can leave this whole MPL vs GPL issue behind us, I
dearly like to see a good developer like Marcus inside the GNU/Linux
community. It would be a waste of talent to let him go.

Signed of by:  Henk Vergonet <[EMAIL PROTECTED]>


--- v4l-dvb-experimental-e9a7be188b2b/linux/drivers/media/tuners/xc3028-tuner.c 
2007-06-08 21:46:14.000000000 +0200
+++ 
../v4l-dvb-experimental-e9a7be188b2b/linux/drivers/media/tuners/xc3028-tuner.c  
    2007-07-28 15:27:29.000000000 +0200
@@ -100,9 +100,9 @@
 
 static int firmware_loader(struct v4l_dvb_tuner_ops *c, const struct firmware 
*fw,enum v4l2_tuner_type type);
 
-static struct _analogue_standards{
+static const struct _analogue_standards{
        v4l2_std_id standard;
-       u8 filename[50];
+       const char *filename;
 } xc3028_standards[]={
        {V4L2_STD_PAL_BG,"xc3028_BG_PAL_A2_A.i2c.fw"},
        {V4L2_STD_PAL_I,"xc3028_I_PAL_NICAM.i2c.fw"},
@@ -141,11 +141,11 @@
 
  */
 
-static struct _digital_standards {
+static const struct _digital_standards {
        unsigned int dvb:1;
        unsigned int atsc:1;
        int bandwidth;
-       char filename[50];
+       char *filename;
 } xc3028_dtv_standards[]={
        {1, 0, BANDWIDTH_8_MHZ /* 8mhz  */, "xc3028_DTV8_2633.i2c.fw"     },
        {1, 0, BANDWIDTH_7_MHZ /* 7mhz  */, "xc3028_DTV7_2633.i2c.fw"     },
@@ -155,13 +155,38 @@
        {0, 1, BANDWIDTH_6_MHZ,             "xc3028_DTV6_ATSC_2620.i2c.fw"},
 };
 
+/* good old byte code stuff definition */
+struct bcode{
+       int len;
+       char *txt;
+};
+
+static struct bcode xc3028_analogue_freq[]={
+       {0x04,"\xa0\x00\x00\x00"},
+       {0x0c,"\x1e\x1f\x13\x87\x18\x02\x93\x91\x44\x86\x96\x8c"}, /* ??? */
+       {0x02,"\x00\x8c"},
+       {0x04,"\x80\x02\x00\x00"},
+       {}
+};
+
+static struct bcode xc3028_dvbt_freq[]={
+       {0x04,"\xa0\x00\x00\x00"},
+       {0x0c, // "\x1e\x1c\xf2\x4d\xe0\x00\x0b\x61\x66\x06\x69\x13"},
+             "\x1e\x1a\x83\x25\xb4\x03\x6e\x01\x96\x86\xa8\x1c"},
+       {0x02,"\x00\x8c"},
+       {0x04,"\x80\x02\x00\x00"},
+       {}
+};
+
+
 static int xc3028_tuner_set_params(struct v4l_dvb_tuner_ops *c, struct 
dvb_int_frontend_parameters *params)
 {
        struct xc3028_priv *priv=(struct xc3028_priv *)c->priv;
        const struct firmware *fw = NULL;
        struct i2c_msg msg = { .addr = 0x61, .flags = 0 };
+       static struct bcode *xc3028_setfreq;
        unsigned char chanbuf[4];
-       unsigned long frequency=0;
+       unsigned long frequency=0, f_offset=0, f_scale = 1000;
        unsigned long value;
        int i;
 
@@ -171,9 +196,11 @@
        case V4L2_INT_TUNER_ATSC_TV:
        case V4L2_INT_TUNER_DVBT_TV:
        case V4L2_INT_TUNER_DVBC_TV:
+               xc3028_setfreq=xc3028_dvbt_freq;
                printk("DIGITAL TV REQUEST\n");
                break;
        case V4L2_INT_TUNER_ANALOG_TV:
+               xc3028_setfreq=xc3028_analogue_freq;
                printk("ANALOG TV REQUEST\n");
                break;
        case V4L2_INT_TUNER_RADIO:
@@ -219,13 +246,13 @@
                switch(params->u.ofdm.bandwidth){
                        case BANDWIDTH_AUTO:
                        case BANDWIDTH_8_MHZ:
-                               frequency=(unsigned long long)params->frequency 
- priv->xc3028_offset_8mhz;
+                               f_offset = priv->xc3028_offset_8mhz;
                                break;
                        case BANDWIDTH_7_MHZ:
-                               frequency=(unsigned long long)params->frequency 
- priv->xc3028_offset_7mhz;
+                               f_offset = priv->xc3028_offset_7mhz;
                                break;
                        case BANDWIDTH_6_MHZ:
-                               frequency=(unsigned long long)params->frequency 
- priv->xc3028_offset_6mhz;
+                               f_offset = priv->xc3028_offset_6mhz;
                                break;
                }
                break;
@@ -248,10 +275,10 @@
                                }
                        }
                }
-               frequency=(unsigned long long)params->frequency*1000/16*1000;
+               f_scale = 16 * 1000;
                break;
        case V4L2_INT_TUNER_RADIO:
-               frequency=(unsigned long long)params->frequency*1000/16;
+               f_scale = 16;
                break;
        case V4L2_INT_TUNER_DVBC_TV:
                printk("xc3028-tuner: dvb-c is currently not implemented\n");
@@ -260,18 +287,29 @@
                printk("xc3028-tuner: requested mode not implemented!\n");
        }
 
+       /* This prevents GCC from complaining about undefined __udivdi3
+       * gcc does not like mixed 64,32 bits divides, we'll use div_ll_X_l_rem
+       * instead.
+       */
+       {
+               long unused;
+               frequency = params->frequency - f_offset;
+               frequency = div_ll_X_l_rem((u64)frequency * 1000, f_scale, 
&unused);
 
-       value=(frequency+(TUNING_GRANULARITY/2))/TUNING_GRANULARITY;
+               value=(frequency+(TUNING_GRANULARITY/2))/TUNING_GRANULARITY;
+
+               priv->frequency = div_ll_X_l_rem((u64)value * f_scale * 
TUNING_GRANULARITY , 1000, &unused) + f_offset;
+       }
        chanbuf[0]=0;
        chanbuf[1]=0;
        chanbuf[2]=value>>8;
        chanbuf[3]=value&0xff;
 
-       priv->frequency = params->frequency;
-
-       msg.buf = "\x80\x02\x00\x00";
-       msg.len = 4;
-       i2c_transfer(priv->i2c,&msg,1);
+       for(i=0;xc3028_setfreq[i].txt;i++){
+               msg.buf = xc3028_setfreq[i].txt;
+               msg.len = xc3028_setfreq[i].len;
+               i2c_transfer(priv->i2c,&msg,1);
+       }
        msg.buf = chanbuf;
        msg.len = 4;
        i2c_transfer(priv->i2c,&msg,1);
@@ -567,7 +605,8 @@
 int xc3028_tuner_get_frequency(struct v4l_dvb_tuner_ops *dev, u32 *frequency)
 {
        struct xc3028_priv *priv = dev->priv;
-       return priv->frequency;
+       *frequency = priv->frequency;
+       return 0;
 }
 
 int xc3028_tuner_get_bandwidth(struct v4l_dvb_tuner_ops *dev, u32 *status)
@@ -581,7 +620,7 @@
                .name           = "Xceive XC3028",
                .frequency_min  =  48000000,
                .frequency_max  = 860000000,
-               .frequency_step =     50000,
+               .frequency_step = TUNING_GRANULARITY,
        },
 
        .release       = xc3028_release,
_______________________________________________
Em28xx mailing list
[email protected]
http://mcentral.de/mailman/listinfo/em28xx

Reply via email to