[EMAIL PROTECTED] schrieb:
> Hello, i compiled the v4l-dvb driver with the patch posted at
> http://www.mail-archive.com/[email protected]/msg21957.html,
>
> I have following dmesg.
>
> dvb-usb: found a 'MSI DIGI VOX mini II DVB-T USB2.0' in warm state.
> PM: Adding info for No Bus:i2c-3
> dvb-usb: This USB2.0 device cannot be run on a USB1.1 port. (it lacks a
> hardware PID filter)
Actually, the m9206 does have a pid filter - it was just disabled for
MSI DIGI VOX mini II. I just enabled it and checked that it works for
usb 1.1. Try the attached patch instead of my original one.
> PM: Removing info for No Bus:i2c-3
> dvb-usb: MSI DIGI VOX mini II DVB-T USB2.0 error while loading driver (-19)
> usbcore: registered new interface driver dvb_usb_m920x
>
>
> any idea what is my problem.
Regards,
Pierre
diff -r 3556fab363b5 linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
--- a/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h Sat Feb 24 09:05:23 2007 -0200
+++ b/linux/drivers/media/dvb/dvb-usb/dvb-usb-ids.h Tue Feb 13 18:32:45 2007 +0100
@@ -37,6 +37,7 @@
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
#define USB_VID_UNIWILL 0x1584
#define USB_VID_WIDEVIEW 0x14aa
+#define USB_VID_ANUBIS_ELECTRONIC 0x10fd
/* Product IDs */
#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -139,6 +140,7 @@
#define USB_PID_GENPIX_8PSK_COLD 0x0200
#define USB_PID_GENPIX_8PSK_WARM 0x0201
#define USB_PID_SIGMATEK_DVB_110 0x6610
+#define USB_PID_ANUBIS_ELECTRONIC_MSI_DIGI_VOX_MINI_II 0x1513
#endif
diff -r 3556fab363b5 linux/drivers/media/dvb/dvb-usb/m920x.c
--- a/linux/drivers/media/dvb/dvb-usb/m920x.c Sat Feb 24 09:05:23 2007 -0200
+++ b/linux/drivers/media/dvb/dvb-usb/m920x.c Thu Mar 01 14:50:25 2007 +0100
@@ -14,6 +14,8 @@
#include "mt352.h"
#include "mt352_priv.h"
#include "qt1010.h"
+#include "tda1004x.h"
+#include "tda827x.h"
/* debug */
static int dvb_usb_m920x_debug;
@@ -44,14 +46,25 @@ static inline int m9206_read(struct usb_
{
int ret;
+ deb_rc("m9206_read(..., %x, %x, %x, %p, %x)\n",
+ request, value, index, data, size);
+
ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
request, USB_TYPE_VENDOR | USB_DIR_IN,
value, index, data, size, 2000);
- if (ret < 0)
- return ret;
-
- if (ret != size)
+ if (ret < 0) {
+ printk(KERN_INFO "m9206_read = error: %d\n", ret);
+ return ret;
+ }
+
+ if (ret != size) {
+ deb_rc("m9206_read = no data\n");
return -EIO;
+ }
+
+
+ deb_rc("m9206_read = %x\n",
+ ((unsigned char*)data)[0]);
return 0;
}
@@ -60,10 +73,17 @@ static inline int m9206_write(struct usb
u16 value, u16 index)
{
int ret;
+
+ deb_rc("m9206_write(..., %x, %x, %x)=...\n",
+ request, value, index);
ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
request, USB_TYPE_VENDOR | USB_DIR_OUT,
value, index, NULL, 0, 2000);
+
+ deb_rc("m9206_write...=%d\n",
+ ret);
+
return ret;
}
@@ -145,51 +165,72 @@ static int m9206_i2c_xfer(struct i2c_ada
{
struct dvb_usb_device *d = i2c_get_adapdata(adap);
struct m9206_state *m = d->priv;
- int i;
+ int i, j;
int ret = 0;
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
- if (num > 2)
- return -EINVAL;
+/*
+sequences found in logs:
+[index value]
+0x80 write addr
+(0x00 out byte)*
+0x40 out byte
+
+0x80 write addr
+(0x00 out byte)*
+0x80 read addr
+(0x21 in byte)*
+0x60 in byte
+
+this sequence works:
+0x80 read addr
+(0x21 in byte)*
+0x60 in byte
+
+_my guess_:
+0x80: begin i2c transfer using address. value=address<<1|(reading?1:0)
+0x00: write byte
+0x21: read byte, more to follow
+0x40: write last byte of message sequence
+0x60: read last byte of message sequence
+ */
+
for (i = 0; i < num; i++) {
- if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].addr, 0x80)) != 0)
- goto unlock;
-
- if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[0], 0x0)) != 0)
- goto unlock;
-
- if (i + 1 < num && msg[i + 1].flags & I2C_M_RD) {
- int i2c_i;
-
- for (i2c_i = 0; i2c_i < M9206_I2C_MAX; i2c_i++)
- if (msg[i].addr == m->i2c_r[i2c_i].addr)
- break;
-
- if (i2c_i >= M9206_I2C_MAX) {
- deb_rc("No magic for i2c addr!\n");
- ret = -EINVAL;
+ if (msg[i].flags & I2C_M_RD) {
+
+ if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].addr | 0x01, 0x80)) != 0)
goto unlock;
+
+ for(j = 0; j < msg[i].len; j++) {
+ if (j + 1 == msg[i].len && i + 1== num) {
+ if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x60, &msg[i].buf[j], msg[i].len)) != 0)
+ goto unlock;
+ } else {
+ if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x21, &msg[i].buf[j], msg[i].len)) != 0)
+ goto unlock;
+ }
}
- if ((ret = m9206_write(d->udev, M9206_I2C, m->i2c_r[i2c_i].magic, 0x80)) != 0)
+ } else {
+ if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].addr, 0x80)) != 0)
goto unlock;
-
- if ((ret = m9206_read(d->udev, M9206_I2C, 0x0, 0x60, msg[i + 1].buf, msg[i + 1].len)) != 0)
- goto unlock;
-
- i++;
- } else {
- if (msg[i].len != 2)
- return -EINVAL;
-
- if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[1], 0x40)) != 0)
- goto unlock;
- }
- }
- ret = i;
+
+ for(j = 0; j < msg[i].len; j++) {
+ if (j + 1 == msg[i].len && i + 1== num) {
+ if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[j], 0x40)) != 0)
+ goto unlock;
+
+ } else {
+ if ((ret = m9206_write(d->udev, M9206_I2C, msg[i].buf[j], 0x0)) != 0)
+ goto unlock;
+ }
+ }
+ }
+ }
+ ret = num;
unlock:
mutex_unlock(&d->i2c_mutex);
@@ -331,6 +372,7 @@ static int m9206_firmware_download(struc
i += size;
}
if (i != fw->size) {
+ deb_rc("bad firmware file!\n");
ret = -EINVAL;
goto done;
}
@@ -426,8 +468,75 @@ static int megasky_qt1010_tuner_attach(s
return 0;
}
+static struct tda1004x_config digivox_tda10046_config = {
+ /* the demodulator's i2c address */
+ .demod_address = 0x10,
+
+ /* does the "inversion" need inverted? */
+ .invert = 0,
+
+ /* Does the OCLK signal need inverted? */
+ .invert_oclk = 0,
+
+ /* Xtal frequency, 4 or 16MHz*/
+ .xtal_freq = TDA10046_XTAL_16M,
+
+ /* IF frequency */
+ .if_freq = TDA10046_FREQ_045,/*currently doing our own*/
+
+ /* AGC configuration */
+/* .agc_config = TDA10046_AGC_DIGIVOX,*/
+
+ /* setting of GPIO1 and 3 */
+/* .gpio_config;*/
+
+ /* slave address and configuration of the tuner */
+/* .tuner_address;*/
+/* .tuner_config;*/
+/* .antenna_switch;*/
+
+ /* if the board uses another I2c Bridge (tda8290), its address */
+/* .i2c_gate;*/
+
+ /* request firmware for device */
+ /* set this to NULL if the card has a firmware EEPROM */
+ .request_firmware = NULL,/*uses firmware EEPROM - TODO: invalid revision*/
+};
+
+static int digivox_tda10046_frontend_attach(struct dvb_usb_adapter *adap)
+{
+ struct m9206_state *m = adap->dev->priv;
+
+ deb_rc("digivox_tda10046_frontend_attach!\n");
+
+ m->i2c_r[M9206_I2C_DEMOD].addr = digivox_tda10046_config.demod_address;
+ m->i2c_r[M9206_I2C_DEMOD].magic = 0x11;
+
+ if ((adap->fe = dvb_attach(tda10046_attach, &digivox_tda10046_config, &adap->dev->i2c_adap)) == NULL)
+ return -EIO;
+
+ return 0;
+}
+
+static struct tda827x_config digivox_tda8275_config = {
+};
+
+static int digivox_tda8275_tuner_attach(struct dvb_usb_adapter *adap)
+{
+ struct m9206_state *m = adap->dev->priv;
+
+ m->i2c_r[M9206_I2C_TUNER].addr = 0xc0;
+ m->i2c_r[M9206_I2C_TUNER].magic = 0xc1;
+
+ if (dvb_attach(tda827x_attach, adap->fe, 0xc0, &adap->dev->i2c_adap,
+ &digivox_tda8275_config) == NULL)
+ return -ENODEV;
+ return 0;
+}
+
/* DVB USB Driver stuff */
static struct dvb_usb_device_properties megasky_properties;
+static struct dvb_usb_device_properties digivox_properties;
static int m920x_probe(struct usb_interface *intf,
const struct usb_device_id *id)
@@ -454,12 +563,30 @@ static int m920x_probe(struct usb_interf
if ((ret = m9206_rc_init(d->udev)) != 0)
return ret;
+ } else if ((ret = dvb_usb_device_init(intf, &digivox_properties, THIS_MODULE, &d)) == 0) {
+ deb_rc("probed!\n");
+
+ alt = usb_altnum_to_altsetting(intf, 1);
+ if (alt == NULL) {
+ deb_rc("not alt found!\n");
+ return -ENODEV;
+ }
+
+ ret = usb_set_interface(d->udev, alt->desc.bInterfaceNumber,
+ alt->desc.bAlternateSetting);
+ if (ret < 0)
+ return ret;
+
+ if ((ret = m9206_rc_init(d->udev)) != 0)
+ return ret;
}
return ret;
}
static struct usb_device_id m920x_table [] = {
{ USB_DEVICE(USB_VID_MSI, USB_PID_MSI_MEGASKY580) },
+ { USB_DEVICE(USB_VID_ANUBIS_ELECTRONIC,
+ USB_PID_ANUBIS_ELECTRONIC_MSI_DIGI_VOX_MINI_II) },
{ } /* Terminating entry */
};
MODULE_DEVICE_TABLE (usb, m920x_table);
@@ -509,6 +636,55 @@ static struct dvb_usb_device_properties
{ "MSI Mega Sky 580 DVB-T USB2.0",
{ &m920x_table[0], NULL },
{ NULL },
+ }
+ }
+};
+
+static struct dvb_usb_device_properties digivox_properties = {
+ .caps = DVB_USB_IS_AN_I2C_ADAPTER,
+
+ .usb_ctrl = DEVICE_SPECIFIC,
+ .firmware = "dvb-usb-digivox-02.fw",
+ .download_firmware = m9206_firmware_download,
+
+/* .rc_interval = 100,
+ .rc_key_map = digivox_rc_keys,
+ .rc_key_map_size = ARRAY_SIZE(digivox_rc_keys),
+ .rc_query = m9206_rc_query,*/
+
+ .size_of_priv = sizeof(struct m9206_state),
+
+ .identify_state = megasky_identify_state,
+ .num_adapters = 1,
+ .adapter = {{
+ .caps = DVB_USB_ADAP_HAS_PID_FILTER |
+ DVB_USB_ADAP_PID_FILTER_CAN_BE_TURNED_OFF,
+
+ .pid_filter_count = 8,
+ .pid_filter = m9206_pid_filter,
+ .pid_filter_ctrl = m9206_pid_filter_ctrl,
+
+ .frontend_attach = digivox_tda10046_frontend_attach,
+ .tuner_attach = digivox_tda8275_tuner_attach,
+
+ .stream = {
+ .type = USB_BULK,
+ .count = 8,
+ .endpoint = 0x81,
+ .u = {
+ .bulk = {
+ .buffersize = 0x4000,
+ }
+ }
+ },
+ }},
+ .i2c_algo = &m9206_i2c_algo,
+
+ .num_device_descs = 1,
+ .devices = {
+ { "MSI DIGI VOX mini II DVB-T USB2.0",
+ { &m920x_table[1], NULL },
+ { NULL },
},
}
};
diff -r 3556fab363b5 linux/drivers/media/dvb/frontends/tda1004x.c
--- a/linux/drivers/media/dvb/frontends/tda1004x.c Sat Feb 24 09:05:23 2007 -0200
+++ b/linux/drivers/media/dvb/frontends/tda1004x.c Sun Feb 25 00:25:56 2007 +0100
@@ -256,6 +256,16 @@ static int tda10046h_set_bandwidth(struc
static int tda10046h_set_bandwidth(struct tda1004x_state *state,
fe_bandwidth_t bandwidth)
{
+#if 1
+ static u8 digivox_vhf[] = { 0x79, 0x16, 0x1c, 0x21, 0xc2 };
+ static u8 digivox_uhf[] = { 0x5b, 0x02, 0xd0, 0x2d, 0x03 };
+
+ tda1004x_write_buf(state, TDA10046H_TIME_WREF1, digivox_uhf,
+ sizeof(digivox_uhf));
+/*for vhf: 0x09, 0xd9*/
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_MSB, 0x0b);
+ tda1004x_write_byteI(state, TDA10046H_FREQ_PHY2_LSB, 0xb2);
+#else
static u8 bandwidth_6mhz_53M[] = { 0x7b, 0x2e, 0x11, 0xf0, 0xd2 };
static u8 bandwidth_7mhz_53M[] = { 0x6a, 0x02, 0x6a, 0x43, 0x9f };
static u8 bandwidth_8mhz_53M[] = { 0x5c, 0x32, 0xc2, 0x96, 0x6d };
@@ -313,6 +323,7 @@ static int tda10046h_set_bandwidth(struc
default:
return -EINVAL;
}
+#endif
return 0;
}
@@ -359,8 +370,10 @@ static int tda1004x_check_upload_ok(stru
u8 data1, data2;
unsigned long timeout;
+ dprintk("%s\n", __FUNCTION__);
+
if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
- timeout = jiffies + 2 * HZ;
+ timeout = jiffies + 4 * HZ;
while(!(tda1004x_read_byte(state, TDA1004X_STATUS_CD) & 0x20)) {
if (time_after(jiffies, timeout)) {
printk(KERN_ERR "tda1004x: timeout waiting for DSP ready\n");
@@ -436,7 +449,12 @@ static void tda10046_init_plls(struct dv
else
tda10046_clk53m = 1;
+#if 1
tda1004x_write_byteI(state, TDA10046H_CONFPLL1, 0xf0);
+ printk(KERN_INFO "tda1004x: setting up plls for 52MHz sampling clock\n");
+ tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x07); // PLL M = 7
+#endif
+#if 0
if(tda10046_clk53m) {
printk(KERN_INFO "tda1004x: setting up plls for 53MHz sampling clock\n");
tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x08); // PLL M = 8
@@ -444,6 +462,7 @@ static void tda10046_init_plls(struct dv
printk(KERN_INFO "tda1004x: setting up plls for 48MHz sampling clock\n");
tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3
}
+#endif
if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
@@ -632,6 +651,12 @@ static int tda10046_init(struct dvb_fron
return -EIO;
}
+/*from windows driver*/
+ tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x00);
+ tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE2, 0x2f);
+ tda1004x_write_byteI(state, TDA10046H_GPIO_OUT_SEL, 0xcf);
+/*from windows driver*/
+
// tda setup
tda1004x_write_mask(state, TDA1004X_CONFC4, 0x20, 0); // disable DSP watchdog timer
tda1004x_write_byteI(state, TDA1004X_AUTO, 0x87); // 100 ppm crystal, select HP stream
@@ -656,9 +681,19 @@ static int tda10046_init(struct dvb_fron
tda1004x_write_byteI(state, TDA10046H_AGC_RENORM, 0x08); // Gain Renormalize
tda1004x_write_mask(state, TDA10046H_CONF_POLARITY, 0xf0, 0x60); // set AGC polarities
break;
- }
+ case TDA10046_AGC_DIGIVOX:
+ tda1004x_write_byteI(state, TDA10046H_AGC_CONF, 0x0a); // AGC setup
+ tda1004x_write_byteI(state, TDA10046H_AGC_THR, 0x70); // set AGC threshold
+ tda1004x_write_byteI(state, TDA10046H_CONF_POLARITY, 0x24); // set AGC polarities
+ break;
+ }
+#if 1
+ tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x34);
+ tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0xa1);
+#else
tda1004x_write_byteI(state, TDA1004X_CONFADC2, 0x38);
tda1004x_write_byteI(state, TDA10046H_CONF_TRISTATE1, 0x79); // Turn IF AGC output on
+#endif
tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MIN, 0); // }
tda1004x_write_byteI(state, TDA10046H_AGC_TUN_MAX, 0xff); // } AGC min/max values
tda1004x_write_byteI(state, TDA10046H_AGC_IF_MIN, 0); // }
diff -r 3556fab363b5 linux/drivers/media/dvb/frontends/tda1004x.h
--- a/linux/drivers/media/dvb/frontends/tda1004x.h Sat Feb 24 09:05:23 2007 -0200
+++ b/linux/drivers/media/dvb/frontends/tda1004x.h Sat Feb 24 17:35:15 2007 +0100
@@ -36,6 +36,7 @@ enum tda10046_agc {
TDA10046_AGC_IFO_AUTO_NEG, /* IF AGC only, automatic, negtive */
TDA10046_AGC_IFO_AUTO_POS, /* IF AGC only, automatic, positive */
TDA10046_AGC_TDA827X, /* IF AGC only, special setup for tda827x */
+ TDA10046_AGC_DIGIVOX, /* setup for msi digivox mini ii*/
};
/* Many (hybrid) boards use GPIO 1 and 3
diff -r 3556fab363b5 linux/drivers/media/dvb/frontends/tda827x.c
--- a/linux/drivers/media/dvb/frontends/tda827x.c Sat Feb 24 09:05:23 2007 -0200
+++ b/linux/drivers/media/dvb/frontends/tda827x.c Sun Feb 25 00:22:41 2007 +0100
@@ -214,7 +214,7 @@ static int tda827xa_set_params(struct dv
struct dvb_frontend_parameters *params)
{
struct tda827x_priv *priv = fe->tuner_priv;
- u8 buf[10];
+ u8 buf[14];
struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
.buf = buf, .len = sizeof(buf) };
@@ -237,7 +237,12 @@ static int tda827xa_set_params(struct dv
if_freq = 5000000;
break;
}
+#if 1
+ if_freq = 4750000;//uhf -- 4500000 for vhf
+#endif
tuner_freq = params->frequency + if_freq;
+
+ dprintk(KERN_INFO "tda827xa: request to tune to %d\n", params->frequency);
i = 0;
while (tda827xa_dvbt[i].lomax < tuner_freq) {
@@ -257,9 +262,12 @@ static int tda827xa_set_params(struct dv
buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
buf[7] = 0x1c;
buf[8] = 0x06;
- buf[9] = 0x24;
- buf[10] = 0x00;
- msg.len = 11;
+ buf[9] = 0x26;
+ buf[10] = 0xff;
+ buf[11] = 0x60;
+ buf[12] = 0x00;
+ buf[13] = 0x59; // lpsel, for 6MHz + 2
+ msg.len = 14;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
@@ -267,15 +275,6 @@ static int tda827xa_set_params(struct dv
__FUNCTION__, priv->i2c_addr << 1);
return -EIO;
}
- buf[0] = 0x90;
- buf[1] = 0xff;
- buf[2] = 0x60;
- buf[3] = 0x00;
- buf[4] = 0x59; // lpsel, for 6MHz + 2
- msg.len = 5;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
buf[0] = 0xa0;
buf[1] = 0x40;
_______________________________________________
linux-dvb mailing list
[email protected]
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linux-dvb