diff options
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r-- | drivers/media/dvb/dvb-usb/Kconfig | 23 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/Makefile | 3 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/a800.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/cxusb.c | 66 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/cxusb.h | 27 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dibusb-mb.c | 20 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dibusb-mc.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/digitv.c | 40 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dtt200u-fe.c | 4 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dtt200u.c | 21 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb-usb-ids.h | 10 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb-usb-init.c | 20 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/dvb-usb.h | 4 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/nova-t-usb2.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/umt-010.c | 2 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/vp702x-fe.c | 339 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/vp702x.c | 290 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/vp702x.h | 109 | ||||
-rw-r--r-- | drivers/media/dvb/dvb-usb/vp7045.c | 7 |
19 files changed, 872 insertions, 119 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig index 612e5b087b1c..54e2b29076b1 100644 --- a/drivers/media/dvb/dvb-usb/Kconfig +++ b/drivers/media/dvb/dvb-usb/Kconfig @@ -93,13 +93,30 @@ config DVB_USB_DIGITV Say Y here to support the Nebula Electronics uDigitV USB2.0 DVB-T receiver. config DVB_USB_VP7045 - tristate "TwinhanDTV Alpha/MagicBoxII and DNTV tinyUSB2 DVB-T USB2.0 support" + tristate "TwinhanDTV Alpha/MagicBoxII, DNTV tinyUSB2, Beetle USB2.0 support" depends on DVB_USB help Say Y here to support the + TwinhanDTV Alpha (stick) (VP-7045), - TwinhanDTV MagicBox II (VP-7046) and - DigitalNow TinyUSB 2 DVB-t DVB-T USB2.0 receivers. + TwinhanDTV MagicBox II (VP-7046), + DigitalNow TinyUSB 2 DVB-t, + DigitalRise USB 2.0 Ter (Beetle) and + TYPHOON DVB-T USB DRIVE + + DVB-T USB2.0 receivers. + +config DVB_USB_VP702X + tristate "TwinhanDTV StarBox and clones DVB-S USB2.0 support" + depends on DVB_USB + help + Say Y here to support the + + TwinhanDTV StarBox, + DigitalRise USB Starbox and + TYPHOON DVB-S USB 2.0 BOX + + DVB-S USB2.0 receivers. config DVB_USB_NOVA_T_USB2 tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support" diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile index 746d87ed6f32..2dc9aad9681e 100644 --- a/drivers/media/dvb/dvb-usb/Makefile +++ b/drivers/media/dvb/dvb-usb/Makefile @@ -4,6 +4,9 @@ obj-$(CONFIG_DVB_USB) += dvb-usb.o dvb-usb-vp7045-objs = vp7045.o vp7045-fe.o obj-$(CONFIG_DVB_USB_VP7045) += dvb-usb-vp7045.o +dvb-usb-vp702x-objs = vp702x.o vp702x-fe.o +obj-$(CONFIG_DVB_USB_VP702X) += dvb-usb-vp702x.o + dvb-usb-dtt200u-objs = dtt200u.o dtt200u-fe.o obj-$(CONFIG_DVB_USB_DTT200U) += dvb-usb-dtt200u.o diff --git a/drivers/media/dvb/dvb-usb/a800.c b/drivers/media/dvb/dvb-usb/a800.c index f2fcc2f1f846..e55322ef76b3 100644 --- a/drivers/media/dvb/dvb-usb/a800.c +++ b/drivers/media/dvb/dvb-usb/a800.c @@ -90,7 +90,7 @@ static struct dvb_usb_properties a800_properties; static int a800_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE); + return dvb_usb_device_init(intf,&a800_properties,THIS_MODULE,NULL); } /* do not change the order of the ID table */ diff --git a/drivers/media/dvb/dvb-usb/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c index 9e96a188f1e9..3fe383f4bb4c 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.c +++ b/drivers/media/dvb/dvb-usb/cxusb.c @@ -48,35 +48,26 @@ static int cxusb_ctrl_msg(struct dvb_usb_device *d, return 0; } -/* I2C */ -static void cxusb_set_i2c_path(struct dvb_usb_device *d, enum cxusb_i2c_pathes path) +/* GPIO */ +static void cxusb_gpio_tuner(struct dvb_usb_device *d, int onoff) { struct cxusb_state *st = d->priv; u8 o[2],i; - if (path == st->cur_i2c_path) + if (st->gpio_write_state[GPIO_TUNER] == onoff) return; - o[0] = IOCTL_SET_I2C_PATH; - switch (path) { - case PATH_CX22702: - o[1] = 0; - break; - case PATH_TUNER_OTHER: - o[1] = 1; - break; - default: - err("unkown i2c path"); - return; - } - cxusb_ctrl_msg(d,CMD_IOCTL,o,2,&i,1); + o[0] = GPIO_TUNER; + o[1] = onoff; + cxusb_ctrl_msg(d,CMD_GPIO_WRITE,o,2,&i,1); if (i != 0x01) - deb_info("i2c_path setting failed.\n"); + deb_info("gpio_write failed.\n"); - st->cur_i2c_path = path; + st->gpio_write_state[GPIO_TUNER] = onoff; } +/* I2C */ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) { struct dvb_usb_device *d = i2c_get_adapdata(adap); @@ -92,10 +83,10 @@ static int cxusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num) switch (msg[i].addr) { case 0x63: - cxusb_set_i2c_path(d,PATH_CX22702); + cxusb_gpio_tuner(d,0); break; default: - cxusb_set_i2c_path(d,PATH_TUNER_OTHER); + cxusb_gpio_tuner(d,1); break; } @@ -147,16 +138,20 @@ static struct i2c_algorithm cxusb_i2c_algo = { static int cxusb_power_ctrl(struct dvb_usb_device *d, int onoff) { - return 0; + u8 b = 0; + if (onoff) + return cxusb_ctrl_msg(d, CMD_POWER_ON, &b, 1, NULL, 0); + else + return cxusb_ctrl_msg(d, CMD_POWER_OFF, &b, 1, NULL, 0); } static int cxusb_streaming_ctrl(struct dvb_usb_device *d, int onoff) { u8 buf[2] = { 0x03, 0x00 }; if (onoff) - cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0); + cxusb_ctrl_msg(d,CMD_STREAMING_ON, buf, 2, NULL, 0); else - cxusb_ctrl_msg(d,0x37, NULL, 0, NULL, 0); + cxusb_ctrl_msg(d,CMD_STREAMING_OFF, NULL, 0, NULL, 0); return 0; } @@ -182,22 +177,11 @@ static int cxusb_tuner_attach(struct dvb_usb_device *d) static int cxusb_frontend_attach(struct dvb_usb_device *d) { - u8 buf[2] = { 0x03, 0x00 }; - u8 b = 0; - - if (usb_set_interface(d->udev,0,0) < 0) - err("set interface to alts=0 failed"); - - cxusb_ctrl_msg(d,0xde,&b,0,NULL,0); - cxusb_set_i2c_path(d,PATH_TUNER_OTHER); - cxusb_ctrl_msg(d,CMD_POWER_OFF, NULL, 0, &b, 1); - + u8 b; if (usb_set_interface(d->udev,0,6) < 0) err("set interface failed"); - cxusb_ctrl_msg(d,0x36, buf, 2, NULL, 0); - cxusb_set_i2c_path(d,PATH_CX22702); - cxusb_ctrl_msg(d,CMD_POWER_ON, NULL, 0, &b, 1); + cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, &b, 1); if ((d->fe = cx22702_attach(&cxusb_cx22702_config, &d->i2c_adap)) != NULL) return 0; @@ -211,7 +195,7 @@ static struct dvb_usb_properties cxusb_properties; static int cxusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE); + return dvb_usb_device_init(intf,&cxusb_properties,THIS_MODULE,NULL); } static struct usb_device_id cxusb_table [] = { @@ -237,14 +221,12 @@ static struct dvb_usb_properties cxusb_properties = { .generic_bulk_ctrl_endpoint = 0x01, /* parameter for the MPEG2-data transfer */ .urb = { - .type = DVB_USB_ISOC, + .type = DVB_USB_BULK, .count = 5, .endpoint = 0x02, .u = { - .isoc = { - .framesperurb = 32, - .framesize = 940, - .interval = 5, + .bulk = { + .buffersize = 8192, } } }, diff --git a/drivers/media/dvb/dvb-usb/cxusb.h b/drivers/media/dvb/dvb-usb/cxusb.h index 1d79016e3195..135c2a81f581 100644 --- a/drivers/media/dvb/dvb-usb/cxusb.h +++ b/drivers/media/dvb/dvb-usb/cxusb.h @@ -1,30 +1,31 @@ #ifndef _DVB_USB_CXUSB_H_ #define _DVB_USB_CXUSB_H_ -#define DVB_USB_LOG_PREFIX "digitv" +#define DVB_USB_LOG_PREFIX "cxusb" #include "dvb-usb.h" extern int dvb_usb_cxusb_debug; #define deb_info(args...) dprintk(dvb_usb_cxusb_debug,0x01,args) /* usb commands - some of it are guesses, don't have a reference yet */ -#define CMD_I2C_WRITE 0x08 -#define CMD_I2C_READ 0x09 +#define CMD_I2C_WRITE 0x08 +#define CMD_I2C_READ 0x09 -#define CMD_IOCTL 0x0e -#define IOCTL_SET_I2C_PATH 0x02 +#define CMD_GPIO_READ 0x0d +#define CMD_GPIO_WRITE 0x0e +#define GPIO_TUNER 0x02 -#define CMD_POWER_OFF 0x50 -#define CMD_POWER_ON 0x51 +#define CMD_POWER_OFF 0xdc +#define CMD_POWER_ON 0xde -enum cxusb_i2c_pathes { - PATH_UNDEF = 0x00, - PATH_CX22702 = 0x01, - PATH_TUNER_OTHER = 0x02, -}; +#define CMD_STREAMING_ON 0x36 +#define CMD_STREAMING_OFF 0x37 + +#define CMD_ANALOG 0x50 +#define CMD_DIGITAL 0x51 struct cxusb_state { - enum cxusb_i2c_pathes cur_i2c_path; + u8 gpio_write_state[3]; }; #endif diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c index 828b5182e16c..0058505634a0 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mb.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c @@ -86,9 +86,9 @@ static struct dvb_usb_properties dibusb2_0b_properties; static int dibusb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE) == 0 || - dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE) == 0 || - dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE) == 0) + if (dvb_usb_device_init(intf,&dibusb1_1_properties,THIS_MODULE,NULL) == 0 || + dvb_usb_device_init(intf,&dibusb1_1_an2235_properties,THIS_MODULE,NULL) == 0 || + dvb_usb_device_init(intf,&dibusb2_0b_properties,THIS_MODULE,NULL) == 0) return 0; return -EINVAL; @@ -126,10 +126,12 @@ static struct usb_device_id dibusb_dib3000mb_table [] = { /* 25 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_COLD) }, /* 26 */ { USB_DEVICE(USB_VID_KYE, USB_PID_KYE_DVB_T_WARM) }, +/* 27 */ { USB_DEVICE(USB_VID_KWORLD, USB_PID_KWORLD_VSTREAM_COLD) }, + // #define DVB_USB_DIBUSB_MB_FAULTY_USB_IDs #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs -/* 27 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, +/* 28 */ { USB_DEVICE(USB_VID_ANCHOR, USB_PID_ULTIMA_TVBOX_ANCHOR_COLD) }, #endif { } /* Terminating entry */ }; @@ -262,7 +264,7 @@ static struct dvb_usb_properties dibusb1_1_an2235_properties = { }, #ifdef DVB_USB_DIBUSB_MB_FAULTY_USB_IDs { "Artec T1 USB1.1 TVBOX with AN2235 (faulty USB IDs)", - { &dibusb_dib3000mb_table[27], NULL }, + { &dibusb_dib3000mb_table[28], NULL }, { NULL }, }, #endif @@ -306,12 +308,16 @@ static struct dvb_usb_properties dibusb2_0b_properties = { } }, - .num_device_descs = 1, + .num_device_descs = 2, .devices = { - { "KWorld/ADSTech Instant DVB-T USB 2.0", + { "KWorld/ADSTech Instant DVB-T USB2.0", { &dibusb_dib3000mb_table[23], NULL }, { &dibusb_dib3000mb_table[24], NULL }, }, + { "KWorld Xpert DVB-T USB2.0", + { &dibusb_dib3000mb_table[27], NULL }, + { NULL } + }, } }; diff --git a/drivers/media/dvb/dvb-usb/dibusb-mc.c b/drivers/media/dvb/dvb-usb/dibusb-mc.c index e9dac430f37d..6a0912eab396 100644 --- a/drivers/media/dvb/dvb-usb/dibusb-mc.c +++ b/drivers/media/dvb/dvb-usb/dibusb-mc.c @@ -20,7 +20,7 @@ static struct dvb_usb_properties dibusb_mc_properties; static int dibusb_mc_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE); + return dvb_usb_device_init(intf,&dibusb_mc_properties,THIS_MODULE,NULL); } /* do not change the order of the ID table */ diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c index f70e0be0920a..74545f82eff1 100644 --- a/drivers/media/dvb/dvb-usb/digitv.c +++ b/drivers/media/dvb/dvb-usb/digitv.c @@ -111,31 +111,28 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe) } static struct mt352_config digitv_mt352_config = { - .demod_address = 0x0, /* ignored by the digitv anyway */ .demod_init = digitv_mt352_demod_init, .pll_set = dvb_usb_pll_set, }; -static struct nxt6000_config digitv_nxt6000_config = { - .demod_address = 0x0, /* ignored by the digitv anyway */ - .clock_inversion = 0x0, +static int digitv_nxt6000_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep) +{ + struct dvb_usb_device *d = fe->dvb->priv; + u8 b[5]; + dvb_usb_pll_set(fe,fep,b); + return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0); +} - .pll_init = NULL, - .pll_set = NULL, +static struct nxt6000_config digitv_nxt6000_config = { + .clock_inversion = 1, + .pll_set = digitv_nxt6000_pll_set, }; static int digitv_frontend_attach(struct dvb_usb_device *d) { - if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL) + if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL || + (d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) return 0; - if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) { - - warn("nxt6000 support is not done yet, in fact you are one of the first " - "person who wants to use this device in Linux. Please report to " - "linux-dvb@linuxtv.org"); - - return 0; - } return -EIO; } @@ -173,7 +170,18 @@ static struct dvb_usb_properties digitv_properties; static int digitv_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE); + struct dvb_usb_device *d; + int ret; + if ((ret = dvb_usb_device_init(intf,&digitv_properties,THIS_MODULE,&d)) == 0) { + u8 b[4] = { 0 }; + + b[0] = 1; + digitv_ctrl_msg(d,USB_WRITE_REMOTE_TYPE,0,b,4,NULL,0); + + b[0] = 0; + digitv_ctrl_msg(d,USB_WRITE_REMOTE,0,b,4,NULL,0); + } + return ret; } static struct usb_device_id digitv_table [] = { diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c index b032523b07bc..0a94ec22aeb8 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c +++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c @@ -18,6 +18,7 @@ struct dtt200u_fe_state { struct dvb_frontend_parameters fep; struct dvb_frontend frontend; + struct dvb_frontend_ops ops; }; static int dtt200u_fe_read_status(struct dvb_frontend* fe, fe_status_t *stat) @@ -163,8 +164,9 @@ struct dvb_frontend* dtt200u_fe_attach(struct dvb_usb_device *d) deb_info("attaching frontend dtt200u\n"); state->d = d; + memcpy(&state->ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops)); - state->frontend.ops = &dtt200u_fe_ops; + state->frontend.ops = &state->ops; state->frontend.demodulator_priv = state; goto success; diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c index 47dba6e45968..5aa12ebab34f 100644 --- a/drivers/media/dvb/dvb-usb/dtt200u.c +++ b/drivers/media/dvb/dvb-usb/dtt200u.c @@ -98,20 +98,19 @@ static struct dvb_usb_properties wt220u_properties; static int dtt200u_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE) == 0 || - dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE) == 0) + if (dvb_usb_device_init(intf,&dtt200u_properties,THIS_MODULE,NULL) == 0 || + dvb_usb_device_init(intf,&wt220u_properties,THIS_MODULE,NULL) == 0) return 0; return -ENODEV; } static struct usb_device_id dtt200u_usb_table [] = { -// { USB_DEVICE(0x04b4,0x8613) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) }, - { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) }, - { 0 }, + { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_COLD) }, + { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_DTT200U_WARM) }, + { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_COLD) }, + { USB_DEVICE(USB_VID_WIDEVIEW, USB_PID_WT220U_WARM) }, + { 0 }, }; MODULE_DEVICE_TABLE(usb, dtt200u_usb_table); @@ -189,7 +188,7 @@ static struct dvb_usb_properties wt220u_properties = { .num_device_descs = 1, .devices = { - { .name = "WideView WT-220U PenType Receiver (and clones)", + { .name = "WideView WT-220U PenType Receiver (Typhoon/Freecom)", .cold_ids = { &dtt200u_usb_table[2], NULL }, .warm_ids = { &dtt200u_usb_table[3], NULL }, }, @@ -201,9 +200,9 @@ static struct dvb_usb_properties wt220u_properties = { static struct usb_driver dtt200u_usb_driver = { .owner = THIS_MODULE, .name = "dvb_usb_dtt200u", - .probe = dtt200u_usb_probe, + .probe = dtt200u_usb_probe, .disconnect = dvb_usb_device_exit, - .id_table = dtt200u_usb_table, + .id_table = dtt200u_usb_table, }; /* module stuff */ diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h index 794d513a8480..0818996bf150 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h @@ -24,8 +24,10 @@ #define USB_VID_HANFTEK 0x15f4 #define USB_VID_HAUPPAUGE 0x2040 #define USB_VID_HYPER_PALTEK 0x1025 +#define USB_VID_KWORLD 0xeb2a #define USB_VID_KYE 0x0458 #define USB_VID_MEDION 0x1660 +#define USB_VID_PINNACLE 0x2304 #define USB_VID_VISIONPLUS 0x13d3 #define USB_VID_TWINHAN 0x1822 #define USB_VID_ULTIMA_ELECTRONIC 0x05d8 @@ -52,12 +54,14 @@ #define USB_PID_KWORLD_VSTREAM_WARM 0x17df #define USB_PID_TWINHAN_VP7041_COLD 0x3201 #define USB_PID_TWINHAN_VP7041_WARM 0x3202 +#define USB_PID_TWINHAN_VP7020_COLD 0x3203 +#define USB_PID_TWINHAN_VP7020_WARM 0x3204 #define USB_PID_TWINHAN_VP7045_COLD 0x3205 #define USB_PID_TWINHAN_VP7045_WARM 0x3206 -#define USB_PID_DNTV_TINYUSB2_COLD 0x3223 -#define USB_PID_DNTV_TINYUSB2_WARM 0x3224 #define USB_PID_TWINHAN_VP7021_COLD 0x3207 #define USB_PID_TWINHAN_VP7021_WARM 0x3208 +#define USB_PID_DNTV_TINYUSB2_COLD 0x3223 +#define USB_PID_DNTV_TINYUSB2_WARM 0x3224 #define USB_PID_ULTIMA_TVBOX_COLD 0x8105 #define USB_PID_ULTIMA_TVBOX_WARM 0x8106 #define USB_PID_ULTIMA_TVBOX_AN2235_COLD 0x8107 @@ -85,5 +89,7 @@ #define USB_PID_MEDION_MD95700 0x0932 #define USB_PID_KYE_DVB_T_COLD 0x701e #define USB_PID_KYE_DVB_T_WARM 0x701f +#define USB_PID_PCTV_200E 0x020e +#define USB_PID_PCTV_400E 0x020f #endif diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-init.c b/drivers/media/dvb/dvb-usb/dvb-usb-init.c index 65f0c095abc9..a902059812a2 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb-init.c +++ b/drivers/media/dvb/dvb-usb/dvb-usb-init.c @@ -128,7 +128,9 @@ static struct dvb_usb_device_description * dvb_usb_find_device(struct usb_device /* * USB */ -int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *props, struct module *owner) + +int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties + *props, struct module *owner,struct dvb_usb_device **du) { struct usb_device *udev = interface_to_usbdev(intf); struct dvb_usb_device *d = NULL; @@ -170,6 +172,9 @@ int dvb_usb_device_init(struct usb_interface *intf, struct dvb_usb_properties *p usb_set_intfdata(intf, d); + if (du != NULL) + *du = d; + ret = dvb_usb_init(d); } @@ -196,19 +201,6 @@ void dvb_usb_device_exit(struct usb_interface *intf) } EXPORT_SYMBOL(dvb_usb_device_exit); -/* module stuff */ -static int __init dvb_usb_module_init(void) -{ - return 0; -} - -static void __exit dvb_usb_module_exit(void) -{ -} - -module_init (dvb_usb_module_init); -module_exit (dvb_usb_module_exit); - MODULE_VERSION("0.3"); MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); MODULE_DESCRIPTION("A library module containing commonly used USB and DVB function USB DVB devices"); diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h index a80567caf508..0e4f1035b0dd 100644 --- a/drivers/media/dvb/dvb-usb/dvb-usb.h +++ b/drivers/media/dvb/dvb-usb/dvb-usb.h @@ -127,7 +127,7 @@ struct dvb_usb_device; * helper functions. * * @urb: describes the kind of USB transfer used for MPEG2-TS-streaming. - * Currently only BULK is implemented + * (BULK or ISOC) * * @num_device_descs: number of struct dvb_usb_device_description in @devices * @devices: array of struct dvb_usb_device_description compatibles with these @@ -310,7 +310,7 @@ struct dvb_usb_device { void *priv; }; -extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *); +extern int dvb_usb_device_init(struct usb_interface *, struct dvb_usb_properties *, struct module *, struct dvb_usb_device **); extern void dvb_usb_device_exit(struct usb_interface *); /* the generic read/write method for device control */ diff --git a/drivers/media/dvb/dvb-usb/nova-t-usb2.c b/drivers/media/dvb/dvb-usb/nova-t-usb2.c index 258a92bfbcc7..1841a66427bf 100644 --- a/drivers/media/dvb/dvb-usb/nova-t-usb2.c +++ b/drivers/media/dvb/dvb-usb/nova-t-usb2.c @@ -144,7 +144,7 @@ static struct dvb_usb_properties nova_t_properties; static int nova_t_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE); + return dvb_usb_device_init(intf,&nova_t_properties,THIS_MODULE,NULL); } /* do not change the order of the ID table */ diff --git a/drivers/media/dvb/dvb-usb/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c index 2112ac3cf5e2..6fd67657c269 100644 --- a/drivers/media/dvb/dvb-usb/umt-010.c +++ b/drivers/media/dvb/dvb-usb/umt-010.c @@ -77,7 +77,7 @@ static struct dvb_usb_properties umt_properties; static int umt_probe(struct usb_interface *intf, const struct usb_device_id *id) { - if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE) == 0) + if (dvb_usb_device_init(intf,&umt_properties,THIS_MODULE,NULL) == 0) return 0; return -EINVAL; } diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c new file mode 100644 index 000000000000..f20d8dbd0be8 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c @@ -0,0 +1,339 @@ +/* DVB frontend part of the Linux driver for the TwinhanDTV StarBox USB2.0 + * DVB-S receiver. + * + * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de> + * Metzler Brothers Systementwicklung GbR + * + * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de> + * + * Thanks to Twinhan who kindly provided hardware and information. + * + * This file can be removed soon, after the DST-driver is rewritten to provice + * the frontend-controlling separately. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + * + */ +#include "vp702x.h" + +struct vp702x_fe_state { + struct dvb_frontend fe; + struct dvb_usb_device *d; + + fe_sec_voltage_t voltage; + fe_sec_tone_mode_t tone_mode; + + u8 lnb_buf[8]; + + u8 lock; + u8 sig; + u8 snr; + + unsigned long next_status_check; + unsigned long status_check_interval; +}; + +static int vp702x_fe_refresh_state(struct vp702x_fe_state *st) +{ + u8 buf[10]; + if (time_after(jiffies,st->next_status_check)) { + vp702x_usb_in_op(st->d,READ_STATUS,0,0,buf,10); + + st->lock = buf[4]; + vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x11,0,&st->snr,1); + vp702x_usb_in_op(st->d,READ_TUNER_REG_REQ,0x15,0,&st->sig,1); + + st->next_status_check = jiffies + (st->status_check_interval*HZ)/1000; + } + return 0; +} + +static u8 vp702x_chksum(u8 *buf,int f, int count) +{ + u8 s = 0; + int i; + for (i = f; i < f+count; i++) + s += buf[i]; + return ~s+1; +} + +static int vp702x_fe_read_status(struct dvb_frontend* fe, fe_status_t *status) +{ + struct vp702x_fe_state *st = fe->demodulator_priv; + vp702x_fe_refresh_state(st); + deb_fe("%s\n",__FUNCTION__); + + if (st->lock == 0) + *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER; + else + *status = 0; + + deb_fe("real state: %x\n",*status); + *status = 0x1f; + + if (*status & FE_HAS_LOCK) + st->status_check_interval = 1000; + else + st->status_check_interval = 250; + return 0; +} + +/* not supported by this Frontend */ +static int vp702x_fe_read_ber(struct dvb_frontend* fe, u32 *ber) +{ + struct vp702x_fe_state *st = fe->demodulator_priv; + vp702x_fe_refresh_state(st); + *ber = 0; + return 0; +} + +/* not supported by this Frontend */ +static int vp702x_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) +{ + struct vp702x_fe_state *st = fe->demodulator_priv; + vp702x_fe_refresh_state(st); + *unc = 0; + return 0; +} + +static int vp702x_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength) +{ + struct vp702x_fe_state *st = fe->demodulator_priv; + vp702x_fe_refresh_state(st); + + *strength = (st->sig << 8) | st->sig; + return 0; +} + +static int vp702x_fe_read_snr(struct dvb_frontend* fe, u16 *snr) +{ + u8 _snr; + struct vp702x_fe_state *st = fe->demodulator_priv; + vp702x_fe_refresh_state(st); + + _snr = (st->snr & 0x1f) * 0xff / 0x1f; + *snr = (_snr << 8) | _snr; + return 0; +} + +static int vp702x_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) +{ + deb_fe("%s\n",__FUNCTION__); + tune->min_delay_ms = 2000; + return 0; +} + +static int vp702x_fe_set_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + struct vp702x_fe_state *st = fe->demodulator_priv; + u32 freq = fep->frequency/1000; + /*CalFrequency*/ +/* u16 frequencyRef[16] = { 2, 4, 8, 16, 32, 64, 128, 256, 24, 5, 10, 20, 40, 80, 160, 320 }; */ + u64 sr; + u8 cmd[8] = { 0 },ibuf[10]; + + cmd[0] = (freq >> 8) & 0x7f; + cmd[1] = freq & 0xff; + cmd[2] = 1; /* divrate == 4 -> frequencyRef[1] -> 1 here */ + + sr = (u64) (fep->u.qpsk.symbol_rate/1000) << 20; + do_div(sr,88000); + cmd[3] = (sr >> 12) & 0xff; + cmd[4] = (sr >> 4) & 0xff; + cmd[5] = (sr << 4) & 0xf0; + + deb_fe("setting frontend to: %u -> %u (%x) LNB-based GHz, symbolrate: %d -> %Lu (%Lx)\n", + fep->frequency,freq,freq, fep->u.qpsk.symbol_rate, sr, sr); + +/* if (fep->inversion == INVERSION_ON) + cmd[6] |= 0x80; */ + + if (st->voltage == SEC_VOLTAGE_18) + cmd[6] |= 0x40; + +/* if (fep->u.qpsk.symbol_rate > 8000000) + cmd[6] |= 0x20; + + if (fep->frequency < 1531000) + cmd[6] |= 0x04; + + if (st->tone_mode == SEC_TONE_ON) + cmd[6] |= 0x01;*/ + + cmd[7] = vp702x_chksum(cmd,0,7); + + st->status_check_interval = 250; + st->next_status_check = jiffies; + + vp702x_usb_in_op(st->d, RESET_TUNER, 0, 0, NULL, 0); + msleep(30); + vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100); + + if (ibuf[2] == 0 && ibuf[3] == 0) + deb_fe("tuning failed.\n"); + else + deb_fe("tuning succeeded.\n"); + + return 0; +} + +static int vp702x_fe_get_frontend(struct dvb_frontend* fe, + struct dvb_frontend_parameters *fep) +{ + deb_fe("%s\n",__FUNCTION__); + return 0; +} + +static int vp702x_fe_send_diseqc_msg (struct dvb_frontend* fe, + struct dvb_diseqc_master_cmd *m) +{ + struct vp702x_fe_state *st = fe->demodulator_priv; + u8 cmd[8],ibuf[10]; + memset(cmd,0,8); + + deb_fe("%s\n",__FUNCTION__); + + if (m->msg_len > 4) + return -EINVAL; + + cmd[1] = SET_DISEQC_CMD; + cmd[2] = m->msg_len; + memcpy(&cmd[3], m->msg, m->msg_len); + cmd[7] = vp702x_chksum(cmd,0,7); + + vp702x_usb_inout_op(st->d,cmd,8,ibuf,10,100); + + if (ibuf[2] == 0 && ibuf[3] == 0) + deb_fe("diseqc cmd failed.\n"); + else + deb_fe("diseqc cmd succeeded.\n"); + + return 0; +} + +static int vp702x_fe_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t burst) +{ + deb_fe("%s\n",__FUNCTION__); + return 0; +} + +static int vp702x_fe_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone) +{ + struct vp702x_fe_state *st = fe->demodulator_priv; + u8 ibuf[10]; + deb_fe("%s\n",__FUNCTION__); + + st->tone_mode = tone; + + if (tone == SEC_TONE_ON) + st->lnb_buf[2] = 0x02; + else + st->lnb_buf[2] = 0x00; + + st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7); + + vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100); + if (ibuf[2] == 0 && ibuf[3] == 0) + deb_fe("set_tone cmd failed.\n"); + else + deb_fe("set_tone cmd succeeded.\n"); + + return 0; +} + +static int vp702x_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t + voltage) +{ + struct vp702x_fe_state *st = fe->demodulator_priv; + u8 ibuf[10]; + deb_fe("%s\n",__FUNCTION__); + + st->voltage = voltage; + + if (voltage != SEC_VOLTAGE_OFF) + st->lnb_buf[4] = 0x01; + else + st->lnb_buf[4] = 0x00; + + st->lnb_buf[7] = vp702x_chksum(st->lnb_buf,0,7); + + vp702x_usb_inout_op(st->d,st->lnb_buf,8,ibuf,10,100); + if (ibuf[2] == 0 && ibuf[3] == 0) + deb_fe("set_voltage cmd failed.\n"); + else + deb_fe("set_voltage cmd succeeded.\n"); + + return 0; +} + +static void vp702x_fe_release(struct dvb_frontend* fe) +{ + struct vp702x_fe_state *st = fe->demodulator_priv; + kfree(st); +} + +static struct dvb_frontend_ops vp702x_fe_ops; + +struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d) +{ + struct vp702x_fe_state *s = kmalloc(sizeof(struct vp702x_fe_state), GFP_KERNEL); + if (s == NULL) + goto error; + memset(s,0,sizeof(struct vp702x_fe_state)); + + s->d = d; + s->fe.ops = &vp702x_fe_ops; + s->fe.demodulator_priv = s; + + s->lnb_buf[1] = SET_LNB_POWER; + s->lnb_buf[3] = 0xff; /* 0=tone burst, 2=data burst, ff=off */ + + goto success; +error: + return NULL; +success: + return &s->fe; +} + + +static struct dvb_frontend_ops vp702x_fe_ops = { + .info = { + .name = "Twinhan DST-like frontend (VP7021/VP7020) DVB-S", + .type = FE_QPSK, + .frequency_min = 950000, + .frequency_max = 2150000, + .frequency_stepsize = 1000, /* kHz for QPSK frontends */ + .frequency_tolerance = 0, + .symbol_rate_min = 1000000, + .symbol_rate_max = 45000000, + .symbol_rate_tolerance = 500, /* ppm */ + .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | + FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | + FE_CAN_QPSK | + FE_CAN_FEC_AUTO + }, + .release = vp702x_fe_release, + + .init = NULL, + .sleep = NULL, + + .set_frontend = vp702x_fe_set_frontend, + .get_frontend = vp702x_fe_get_frontend, + .get_tune_settings = vp702x_fe_get_tune_settings, + + .read_status = vp702x_fe_read_status, + .read_ber = vp702x_fe_read_ber, + .read_signal_strength = vp702x_fe_read_signal_strength, + .read_snr = vp702x_fe_read_snr, + .read_ucblocks = vp702x_fe_read_unc_blocks, + + .diseqc_send_master_cmd = vp702x_fe_send_diseqc_msg, + .diseqc_send_burst = vp702x_fe_send_diseqc_burst, + .set_tone = vp702x_fe_set_tone, + .set_voltage = vp702x_fe_set_voltage, +}; diff --git a/drivers/media/dvb/dvb-usb/vp702x.c b/drivers/media/dvb/dvb-usb/vp702x.c new file mode 100644 index 000000000000..de13c04e8e64 --- /dev/null +++ b/drivers/media/dvb/dvb-usb/vp702x.c @@ -0,0 +1,290 @@ +/* DVB USB compliant Linux driver for the TwinhanDTV StarBox USB2.0 DVB-S + * receiver. + * + * Copyright (C) 2005 Ralph Metzler <rjkm@metzlerbros.de> + * Metzler Brothers Systementwicklung GbR + * + * Copyright (C) 2005 Patrick Boettcher <patrick.boettcher@desy.de> + * + * Thanks to Twinhan who kindly provided hardware and information. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation, version 2. + * + * see Documentation/dvb/README.dvb-usb for more information + */ +#include "vp702x.h" + +/* debug */ +int dvb_usb_vp702x_debug; +module_param_named(debug,dvb_usb_vp702x_debug, int, 0644); +MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS); + +struct vp702x_state { + u8 pid_table[17]; /* [16] controls the pid_table state */ +}; + +/* check for mutex FIXME */ +int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) +{ + int ret = 0,try = 0; + + while (ret >= 0 && ret != blen && try < 3) { + ret = usb_control_msg(d->udev, + usb_rcvctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_IN, + value,index,b,blen, + 2000); + deb_info("reading number %d (ret: %d)\n",try,ret); + try++; + } + + if (ret < 0 || ret != blen) { + warn("usb in operation failed."); + ret = -EIO; + } else + ret = 0; + + deb_xfer("in: req. %x, val: %x, ind: %x, buffer: ",req,value,index); + debug_dump(b,blen,deb_xfer); + + return ret; +} + +int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen) +{ + deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index); + debug_dump(b,blen,deb_xfer); + + if (usb_control_msg(d->udev, + usb_sndctrlpipe(d->udev,0), + req, + USB_TYPE_VENDOR | USB_DIR_OUT, + value,index,b,blen, + 2000) != blen) { + warn("usb out operation failed."); + return -EIO; + } else + return 0; +} + +int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec) +{ + int ret; + + if ((ret = down_interruptible(&d->usb_sem))) + return ret; + + if ((ret = vp702x_usb_out_op(d,REQUEST_OUT,0,0,o,olen)) < 0) + goto unlock; + msleep(msec); + ret = vp702x_usb_in_op(d,REQUEST_IN,0,0,i,ilen); + +unlock: + up(&d->usb_sem); + + return ret; +} + +int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec) +{ + u8 bout[olen+2]; + u8 bin[ilen+1]; + int ret = 0; + + bout[0] = 0x00; + bout[1] = cmd; + memcpy(&bout[2],o,olen); + + ret = vp702x_usb_inout_op(d, bout, olen+2, bin, ilen+1,msec); + + if (ret == 0) + memcpy(i,&bin[1],ilen); + + return ret; +} + +static int vp702x_pid_filter(struct dvb_usb_device *d, int index, u16 pid, int onoff) +{ + struct vp702x_state *st = d->priv; + u8 buf[9]; + + if (onoff) { + st->pid_table[16] |= 1 << index; + st->pid_table[index*2] = (pid >> 8) & 0xff; + st->pid_table[index*2+1] = pid & 0xff; + } else { + st->pid_table[16] &= ~(1 << index); + st->pid_table[index*2] = st->pid_table[index*2+1] = 0; + } + + return vp702x_usb_inout_cmd(d,SET_PID_FILTER,st->pid_table,17,buf,9,10); +} + +static int vp702x_power_ctrl(struct dvb_usb_device *d, int onoff) +{ + vp702x_usb_in_op(d,RESET_TUNER,0,0,NULL,0); + + vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0); + return vp702x_usb_in_op(d,SET_TUNER_POWER_REQ,0,onoff,NULL,0); +} + +/* keys for the enclosed remote control */ +static struct dvb_usb_rc_key vp702x_rc_keys[] = { + { 0x00, 0x01, KEY_1 }, + { 0x00, 0x02, KEY_2 }, +}; + +/* remote control stuff (does not work with my box) */ +static int vp702x_rc_query(struct dvb_usb_device *d, u32 *event, int *state) +{ + u8 key[10]; + int i; + +/* remove the following return to enabled remote querying */ + return 0; + + vp702x_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); + + deb_rc("remote query key: %x %d\n",key[1],key[1]); + + if (key[1] == 0x44) { + *state = REMOTE_NO_KEY_PRESSED; + return 0; + } + + for (i = 0; i < ARRAY_SIZE(vp702x_rc_keys); i++) + if (vp702x_rc_keys[i].custom == key[1]) { + *state = REMOTE_KEY_PRESSED; + *event = vp702x_rc_keys[i].event; + break; + } + return 0; +} + +static int vp702x_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) +{ + u8 macb[9]; + if (vp702x_usb_inout_cmd(d, GET_MAC_ADDRESS, NULL, 0, macb, 9, 10)) + return -EIO; + memcpy(mac,&macb[3],6); + return 0; +} + +static int vp702x_frontend_attach(struct dvb_usb_device *d) +{ + u8 buf[9] = { 0 }; + + if (vp702x_usb_inout_cmd(d, GET_SYSTEM_STRING, NULL, 0, buf, 9, 10)) + return -EIO; + + buf[8] = '\0'; + info("system string: %s",&buf[1]); + + d->fe = vp702x_fe_attach(d); + return 0; +} + +static struct dvb_usb_properties vp702x_properties; + +static int vp702x_usb_probe(struct usb_interface *intf, + const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + + usb_clear_halt(udev,usb_sndctrlpipe(udev,0)); + usb_clear_halt(udev,usb_rcvctrlpipe(udev,0)); + + return dvb_usb_device_init(intf,&vp702x_properties,THIS_MODULE,NULL); +} + +static struct usb_device_id vp702x_usb_table [] = { + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_COLD) }, + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7021_WARM) }, + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_COLD) }, + { USB_DEVICE(USB_VID_VISIONPLUS, USB_PID_TWINHAN_VP7020_WARM) }, + { 0 }, +}; +MODULE_DEVICE_TABLE(usb, vp702x_usb_table); + +static struct dvb_usb_properties vp702x_properties = { + .caps = DVB_USB_HAS_PID_FILTER | DVB_USB_NEED_PID_FILTERING, + .pid_filter_count = 8, /* !!! */ + + .usb_ctrl = CYPRESS_FX2, + .firmware = "dvb-usb-vp702x-01.fw", + + .pid_filter = vp702x_pid_filter, + .power_ctrl = vp702x_power_ctrl, + .frontend_attach = vp702x_frontend_attach, + .read_mac_address = vp702x_read_mac_addr, + + .rc_key_map = vp702x_rc_keys, + .rc_key_map_size = ARRAY_SIZE(vp702x_rc_keys), + .rc_interval = 400, + .rc_query = vp702x_rc_query, + + .size_of_priv = sizeof(struct vp702x_state), + + /* parameter for the MPEG2-data transfer */ + .urb = { + .type = DVB_USB_BULK, + .count = 7, + .endpoint = 0x02, + .u = { + .bulk = { + .buffersize = 4096, + } + } + }, + + .num_device_descs = 2, + .devices = { + { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7021)", + .cold_ids = { &vp702x_usb_table[0], NULL }, + .warm_ids = { &vp702x_usb_table[1], NULL }, + }, + { .name = "TwinhanDTV StarBox DVB-S USB2.0 (VP7020)", + .cold_ids = { &vp702x_usb_table[2], NULL }, + .warm_ids = { &vp702x_usb_table[3], NULL }, + }, + { 0 }, + } +}; + +/* usb specific object needed to register this driver with the usb subsystem */ +static struct usb_driver vp702x_usb_driver = { + .owner = THIS_MODULE, + .name = "dvb-usb-vp702x", + .probe = vp702x_usb_probe, + .disconnect = dvb_usb_device_exit, + .id_table = vp702x_usb_table, +}; + +/* module stuff */ +static int __init vp702x_usb_module_init(void) +{ + int result; + if ((result = usb_register(&vp702x_usb_driver))) { + err("usb_register failed. (%d)",result); + return result; + } + + return 0; +} + +static void __exit vp702x_usb_module_exit(void) +{ + /* deregister this driver from the USB subsystem */ + usb_deregister(&vp702x_usb_driver); +} + +module_init(vp702x_usb_module_init); +module_exit(vp702x_usb_module_exit); + +MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de>"); +MODULE_DESCRIPTION("Driver for Twinhan StarBox DVB-S USB2.0 and clones"); +MODULE_VERSION("1.0-alpha"); +MODULE_LICENSE("GPL"); diff --git a/drivers/media/dvb/dvb-usb/vp702x.h b/drivers/media/dvb/dvb-usb/vp702x.h new file mode 100644 index 000000000000..4a3e8c7eca2b --- /dev/null +++ b/drivers/media/dvb/dvb-usb/vp702x.h @@ -0,0 +1,109 @@ +#ifndef _DVB_USB_VP7021_H_ +#define _DVB_USB_VP7021_H_ + +#define DVB_USB_LOG_PREFIX "vp702x" +#include "dvb-usb.h" + +extern int dvb_usb_vp702x_debug; +#define deb_info(args...) dprintk(dvb_usb_vp702x_debug,0x01,args) +#define deb_xfer(args...) dprintk(dvb_usb_vp702x_debug,0x02,args) +#define deb_rc(args...) dprintk(dvb_usb_vp702x_debug,0x04,args) +#define deb_fe(args...) dprintk(dvb_usb_vp702x_debug,0x08,args) + +/* commands are read and written with USB control messages */ + +/* consecutive read/write operation */ +#define REQUEST_OUT 0xB2 +#define REQUEST_IN 0xB3 + +/* the out-buffer of these consecutive operations contain sub-commands when b[0] = 0 + * request: 0xB2; i: 0; v: 0; b[0] = 0, b[1] = subcmd, additional buffer + * the returning buffer looks as follows + * request: 0xB3; i: 0; v: 0; b[0] = 0xB3, additional buffer */ + +#define GET_TUNER_STATUS 0x05 +/* additional in buffer: + * 0 1 2 3 4 5 6 7 8 + * N/A N/A 0x05 signal-quality N/A N/A signal-strength lock==0 N/A */ + +#define GET_SYSTEM_STRING 0x06 +/* additional in buffer: + * 0 1 2 3 4 5 6 7 8 + * N/A 'U' 'S' 'B' '7' '0' '2' 'X' N/A */ + +#define SET_DISEQC_CMD 0x08 +/* additional out buffer: + * 0 1 2 3 4 + * len X1 X2 X3 X4 + * additional in buffer: + * 0 1 2 + * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */ + +#define SET_LNB_POWER 0x09 +/* additional out buffer: + * 0 1 2 + * 0x00 0xff 1 = on, 0 = off + * additional in buffer: + * 0 1 2 + * N/A 0 0 b[1] == b[2] == 0 -> success otherwise not */ + +#define GET_MAC_ADDRESS 0x0A +/* #define GET_MAC_ADDRESS 0x0B */ +/* additional in buffer: + * 0 1 2 3 4 5 6 7 8 + * N/A N/A 0x0A or 0x0B MAC0 MAC1 MAC2 MAC3 MAC4 MAC5 */ + +#define SET_PID_FILTER 0x11 +/* additional in buffer: + * 0 1 ... 14 15 16 + * PID0_MSB PID0_LSB ... PID7_MSB PID7_LSB PID_active (bits) */ + +/* request: 0xB2; i: 0; v: 0; + * b[0] != 0 -> tune and lock a channel + * 0 1 2 3 4 5 6 7 + * freq0 freq1 divstep srate0 srate1 srate2 flag chksum + */ + + +/* one direction requests */ +#define READ_REMOTE_REQ 0xB4 +/* IN i: 0; v: 0; b[0] == request, b[1] == key */ + +#define READ_PID_NUMBER_REQ 0xB5 +/* IN i: 0; v: 0; b[0] == request, b[1] == 0, b[2] = pid number */ + +#define WRITE_EEPROM_REQ 0xB6 +/* OUT i: offset; v: value to write; no extra buffer */ + +#define READ_EEPROM_REQ 0xB7 +/* IN i: bufferlen; v: offset; buffer with bufferlen bytes */ + +#define READ_STATUS 0xB8 +/* IN i: 0; v: 0; bufferlen 10 */ + +#define READ_TUNER_REG_REQ 0xB9 +/* IN i: 0; v: register; b[0] = value */ + +#define READ_FX2_REG_REQ 0xBA +/* IN i: offset; v: 0; b[0] = value */ + +#define WRITE_FX2_REG_REQ 0xBB +/* OUT i: offset; v: value to write; 1 byte extra buffer */ + +#define SET_TUNER_POWER_REQ 0xBC +/* IN i: 0 = power off, 1 = power on */ + +#define WRITE_TUNER_REG_REQ 0xBD +/* IN i: register, v: value to write, no extra buffer */ + +#define RESET_TUNER 0xBE +/* IN i: 0, v: 0, no extra buffer */ + +extern struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d); + +extern int vp702x_usb_inout_op(struct dvb_usb_device *d, u8 *o, int olen, u8 *i, int ilen, int msec); +extern int vp702x_usb_inout_cmd(struct dvb_usb_device *d, u8 cmd, u8 *o, int olen, u8 *i, int ilen, int msec); +extern int vp702x_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); +extern int vp702x_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen); + +#endif diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c index 9ac95f54f9fc..0f57abeb6d6b 100644 --- a/drivers/media/dvb/dvb-usb/vp7045.c +++ b/drivers/media/dvb/dvb-usb/vp7045.c @@ -164,7 +164,6 @@ static int vp7045_read_eeprom(struct dvb_usb_device *d,u8 *buf, int len, int off return 0; } - static int vp7045_read_mac_addr(struct dvb_usb_device *d,u8 mac[6]) { return vp7045_read_eeprom(d,mac, 6, MAC_0_ADDR); @@ -199,7 +198,7 @@ static struct dvb_usb_properties vp7045_properties; static int vp7045_usb_probe(struct usb_interface *intf, const struct usb_device_id *id) { - return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE); + return dvb_usb_device_init(intf,&vp7045_properties,THIS_MODULE,NULL); } static struct usb_device_id vp7045_usb_table [] = { @@ -256,9 +255,9 @@ static struct dvb_usb_properties vp7045_properties = { static struct usb_driver vp7045_usb_driver = { .owner = THIS_MODULE, .name = "dvb_usb_vp7045", - .probe = vp7045_usb_probe, + .probe = vp7045_usb_probe, .disconnect = dvb_usb_device_exit, - .id_table = vp7045_usb_table, + .id_table = vp7045_usb_table, }; /* module stuff */ |