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