summaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/dvb-usb
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/media/dvb/dvb-usb')
-rw-r--r--drivers/media/dvb/dvb-usb/Kconfig10
-rw-r--r--drivers/media/dvb/dvb-usb/Makefile3
-rw-r--r--drivers/media/dvb/dvb-usb/cxusb.c48
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-common.c9
-rw-r--r--drivers/media/dvb/dvb-usb/dibusb-mb.c7
-rw-r--r--drivers/media/dvb/dvb-usb/digitv.c15
-rw-r--r--drivers/media/dvb/dvb-usb/dtt200u-fe.c8
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-dvb.c17
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-i2c.c24
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb-ids.h4
-rw-r--r--drivers/media/dvb/dvb-usb/dvb-usb.h6
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk-fe.c272
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.c256
-rw-r--r--drivers/media/dvb/dvb-usb/gp8psk.h79
-rw-r--r--drivers/media/dvb/dvb-usb/umt-010.c2
-rw-r--r--drivers/media/dvb/dvb-usb/vp702x-fe.c7
-rw-r--r--drivers/media/dvb/dvb-usb/vp7045-fe.c9
17 files changed, 705 insertions, 71 deletions
diff --git a/drivers/media/dvb/dvb-usb/Kconfig b/drivers/media/dvb/dvb-usb/Kconfig
index e388fb1567d6..3bc6722a6443 100644
--- a/drivers/media/dvb/dvb-usb/Kconfig
+++ b/drivers/media/dvb/dvb-usb/Kconfig
@@ -88,6 +88,7 @@ config DVB_USB_CXUSB
select DVB_CX22702
select DVB_LGDT330X
select DVB_MT352
+ select DVB_ZL10353
help
Say Y here to support the Conexant USB2.0 hybrid reference design.
Currently, only DVB and ATSC modes are supported, analog mode
@@ -130,6 +131,15 @@ config DVB_USB_VP702X
DVB-S USB2.0 receivers.
+config DVB_USB_GP8PSK
+ tristate "GENPIX 8PSK->USB module support"
+ depends on DVB_USB
+ help
+ Say Y here to support the
+ GENPIX 8psk module
+
+ DVB-S USB2.0 receivers.
+
config DVB_USB_NOVA_T_USB2
tristate "Hauppauge WinTV-NOVA-T usb2 DVB-T USB2.0 support"
depends on DVB_USB
diff --git a/drivers/media/dvb/dvb-usb/Makefile b/drivers/media/dvb/dvb-usb/Makefile
index 2dc9aad9681e..9643f56c7fe9 100644
--- a/drivers/media/dvb/dvb-usb/Makefile
+++ b/drivers/media/dvb/dvb-usb/Makefile
@@ -7,6 +7,9 @@ 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-gp8psk-objs = gp8psk.o gp8psk-fe.o
+obj-$(CONFIG_DVB_USB_GP8PSK) += dvb-usb-gp8psk.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/cxusb.c b/drivers/media/dvb/dvb-usb/cxusb.c
index 1f0d3e995c8d..ae23bdde42a8 100644
--- a/drivers/media/dvb/dvb-usb/cxusb.c
+++ b/drivers/media/dvb/dvb-usb/cxusb.c
@@ -27,8 +27,10 @@
#include "cx22702.h"
#include "lgdt330x.h"
+#include "lg_h06xf.h"
#include "mt352.h"
#include "mt352_priv.h"
+#include "zl10353.h"
/* debug */
int dvb_usb_cxusb_debug;
@@ -322,32 +324,37 @@ static int cxusb_mt352_demod_init(struct dvb_frontend* fe)
return 0;
}
+static int cxusb_lgh064f_tuner_set_params(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct dvb_usb_device *d = fe->dvb->priv;
+ return lg_h06xf_pll_set(fe, &d->i2c_adap, fep);
+}
+
static struct cx22702_config cxusb_cx22702_config = {
.demod_address = 0x63,
.output_mode = CX22702_PARALLEL_OUTPUT,
-
- .pll_init = dvb_usb_pll_init_i2c,
- .pll_set = dvb_usb_pll_set_i2c,
};
static struct lgdt330x_config cxusb_lgdt3303_config = {
.demod_address = 0x0e,
.demod_chip = LGDT3303,
- .pll_set = dvb_usb_pll_set_i2c,
};
static struct mt352_config cxusb_dee1601_config = {
.demod_address = 0x0f,
.demod_init = cxusb_dee1601_demod_init,
- .pll_set = dvb_usb_pll_set,
};
-struct mt352_config cxusb_mt352_config = {
+static struct zl10353_config cxusb_zl10353_dee1601_config = {
+ .demod_address = 0x0f,
+};
+
+static struct mt352_config cxusb_mt352_config = {
/* used in both lgz201 and th7579 */
.demod_address = 0x0f,
.demod_init = cxusb_mt352_demod_init,
- .pll_set = dvb_usb_pll_set,
};
/* Callbacks for DVB USB */
@@ -357,17 +364,10 @@ static int cxusb_fmd1216me_tuner_attach(struct dvb_usb_device *d)
d->pll_addr = 0x61;
memcpy(d->pll_init, bpll, 4);
d->pll_desc = &dvb_pll_fmd1216me;
- return 0;
-}
-static int cxusb_lgh064f_tuner_attach(struct dvb_usb_device *d)
-{
- u8 bpll[4] = { 0x00, 0x00, 0x18, 0x50 };
- /* bpll[2] : unset bit 3, set bits 4&5
- bpll[3] : 0x50 - digital, 0x20 - analog */
- d->pll_addr = 0x61;
- memcpy(d->pll_init, bpll, 4);
- d->pll_desc = &dvb_pll_tdvs_tua6034;
+ d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
+ d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
+
return 0;
}
@@ -375,6 +375,7 @@ static int cxusb_dee1601_tuner_attach(struct dvb_usb_device *d)
{
d->pll_addr = 0x61;
d->pll_desc = &dvb_pll_thomson_dtt7579;
+ d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
return 0;
}
@@ -382,6 +383,7 @@ static int cxusb_lgz201_tuner_attach(struct dvb_usb_device *d)
{
d->pll_addr = 0x61;
d->pll_desc = &dvb_pll_lg_z201;
+ d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
return 0;
}
@@ -389,6 +391,13 @@ static int cxusb_dtt7579_tuner_attach(struct dvb_usb_device *d)
{
d->pll_addr = 0x60;
d->pll_desc = &dvb_pll_thomson_dtt7579;
+ d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
+ return 0;
+}
+
+static int cxusb_lgdt3303_tuner_attach(struct dvb_usb_device *d)
+{
+ d->fe->ops.tuner_ops.set_params = cxusb_lgh064f_tuner_set_params;
return 0;
}
@@ -439,7 +448,8 @@ static int cxusb_dee1601_frontend_attach(struct dvb_usb_device *d)
cxusb_ctrl_msg(d,CMD_DIGITAL, NULL, 0, NULL, 0);
- if ((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL)
+ if (((d->fe = mt352_attach(&cxusb_dee1601_config, &d->i2c_adap)) != NULL) ||
+ ((d->fe = zl10353_attach(&cxusb_zl10353_dee1601_config, &d->i2c_adap)) != NULL))
return 0;
return -EIO;
@@ -555,7 +565,7 @@ static struct dvb_usb_properties cxusb_bluebird_lgh064f_properties = {
.streaming_ctrl = cxusb_streaming_ctrl,
.power_ctrl = cxusb_bluebird_power_ctrl,
.frontend_attach = cxusb_lgdt3303_frontend_attach,
- .tuner_attach = cxusb_lgh064f_tuner_attach,
+ .tuner_attach = cxusb_lgdt3303_tuner_attach,
.i2c_algo = &cxusb_i2c_algo,
diff --git a/drivers/media/dvb/dvb-usb/dibusb-common.c b/drivers/media/dvb/dvb-usb/dibusb-common.c
index 2d52b76671d3..abd75b4a350d 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-common.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-common.c
@@ -173,11 +173,10 @@ int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
struct dib3000_config demod_cfg;
struct dibusb_state *st = d->priv;
- demod_cfg.pll_set = dvb_usb_pll_set_i2c;
- demod_cfg.pll_init = dvb_usb_pll_init_i2c;
-
for (demod_cfg.demod_address = 0x8; demod_cfg.demod_address < 0xd; demod_cfg.demod_address++)
if ((d->fe = dib3000mc_attach(&demod_cfg,&d->i2c_adap,&st->ops)) != NULL) {
+ d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
+ d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
return 0;
}
@@ -190,6 +189,10 @@ int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
{
d->pll_addr = 0x60;
d->pll_desc = &dvb_pll_env57h1xd5;
+
+ d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
+ d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
+
return 0;
}
EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);
diff --git a/drivers/media/dvb/dvb-usb/dibusb-mb.c b/drivers/media/dvb/dvb-usb/dibusb-mb.c
index dd5a13195886..f4c45f386ebc 100644
--- a/drivers/media/dvb/dvb-usb/dibusb-mb.c
+++ b/drivers/media/dvb/dvb-usb/dibusb-mb.c
@@ -20,11 +20,12 @@ static int dibusb_dib3000mb_frontend_attach(struct dvb_usb_device *d)
struct dibusb_state *st = d->priv;
demod_cfg.demod_address = 0x8;
- demod_cfg.pll_set = dvb_usb_pll_set_i2c;
- demod_cfg.pll_init = dvb_usb_pll_init_i2c;
- if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL)
+ if ((d->fe = dib3000mb_attach(&demod_cfg,&d->i2c_adap,&st->ops)) == NULL) {
+ d->fe->ops.tuner_ops.init = dvb_usb_tuner_init_i2c;
+ d->fe->ops.tuner_ops.set_params = dvb_usb_tuner_set_params_i2c;
return -ENODEV;
+ }
d->tuner_pass_ctrl = st->ops.tuner_pass_ctrl;
diff --git a/drivers/media/dvb/dvb-usb/digitv.c b/drivers/media/dvb/dvb-usb/digitv.c
index 91136c00ce9d..c14d9efb48fd 100644
--- a/drivers/media/dvb/dvb-usb/digitv.c
+++ b/drivers/media/dvb/dvb-usb/digitv.c
@@ -112,27 +112,30 @@ static int digitv_mt352_demod_init(struct dvb_frontend *fe)
static struct mt352_config digitv_mt352_config = {
.demod_init = digitv_mt352_demod_init,
- .pll_set = dvb_usb_pll_set,
};
-static int digitv_nxt6000_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+static int digitv_nxt6000_tuner_set_params(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);
+ dvb_usb_tuner_calc_regs(fe,fep,b, 5);
return digitv_ctrl_msg(d,USB_WRITE_TUNER,0,&b[1],4,NULL,0);
}
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 ||
- (d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL)
+ if ((d->fe = mt352_attach(&digitv_mt352_config, &d->i2c_adap)) != NULL) {
+ d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
return 0;
+ }
+ if ((d->fe = nxt6000_attach(&digitv_nxt6000_config, &d->i2c_adap)) != NULL) {
+ d->fe->ops.tuner_ops.set_params = digitv_nxt6000_tuner_set_params;
+ return 0;
+ }
return -EIO;
}
diff --git a/drivers/media/dvb/dvb-usb/dtt200u-fe.c b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
index cd21ddbfd054..17413adec7a1 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u-fe.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u-fe.c
@@ -18,7 +18,6 @@ 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,16 +162,13 @@ 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 = &state->ops;
+ memcpy(&state->frontend.ops,&dtt200u_fe_ops,sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
- goto success;
+ return &state->frontend;
error:
return NULL;
-success:
- return &state->frontend;
}
static struct dvb_frontend_ops dtt200u_fe_ops = {
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
index 6fa92100248b..ec631708c394 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-dvb.c
@@ -82,7 +82,7 @@ int dvb_usb_dvb_init(struct dvb_usb_device *d)
int ret;
if ((ret = dvb_register_adapter(&d->dvb_adap, d->desc->name,
- d->owner)) < 0) {
+ d->owner, &d->udev->dev)) < 0) {
deb_info("dvb_register_adapter failed: error %d", ret);
goto err;
}
@@ -121,16 +121,15 @@ int dvb_usb_dvb_init(struct dvb_usb_device *d)
dvb_net_init(&d->dvb_adap, &d->dvb_net, &d->demux.dmx);
- goto success;
+ d->state |= DVB_USB_STATE_DVB;
+ return 0;
+
err_dmx_dev:
dvb_dmx_release(&d->demux);
err_dmx:
dvb_unregister_adapter(&d->dvb_adap);
err:
return ret;
-success:
- d->state |= DVB_USB_STATE_DVB;
- return 0;
}
int dvb_usb_dvb_exit(struct dvb_usb_device *d)
@@ -184,13 +183,13 @@ int dvb_usb_fe_init(struct dvb_usb_device* d)
/* re-assign sleep and wakeup functions */
if (d->fe != NULL) {
- d->fe_init = d->fe->ops->init; d->fe->ops->init = dvb_usb_fe_wakeup;
- d->fe_sleep = d->fe->ops->sleep; d->fe->ops->sleep = dvb_usb_fe_sleep;
+ d->fe_init = d->fe->ops.init; d->fe->ops.init = dvb_usb_fe_wakeup;
+ d->fe_sleep = d->fe->ops.sleep; d->fe->ops.sleep = dvb_usb_fe_sleep;
if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
err("Frontend registration failed.");
- if (d->fe->ops->release)
- d->fe->ops->release(d->fe);
+ if (d->fe->ops.release)
+ d->fe->ops.release(d->fe);
d->fe = NULL;
return -ENODEV;
}
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
index 9b254532af4d..6b611a725093 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-i2c.c
@@ -46,7 +46,7 @@ int dvb_usb_i2c_exit(struct dvb_usb_device *d)
return 0;
}
-int dvb_usb_pll_init_i2c(struct dvb_frontend *fe)
+int dvb_usb_tuner_init_i2c(struct dvb_frontend *fe)
{
struct dvb_usb_device *d = fe->dvb->priv;
struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = d->pll_init, .len = 4 };
@@ -63,6 +63,8 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe)
deb_pll("pll-buf: %x %x %x %x\n",d->pll_init[0],d->pll_init[1],
d->pll_init[2],d->pll_init[3]);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
err("tuner i2c write failed for pll_init.");
ret = -EREMOTEIO;
@@ -73,38 +75,42 @@ int dvb_usb_pll_init_i2c(struct dvb_frontend *fe)
d->tuner_pass_ctrl(fe,0,d->pll_addr);
return ret;
}
-EXPORT_SYMBOL(dvb_usb_pll_init_i2c);
+EXPORT_SYMBOL(dvb_usb_tuner_init_i2c);
-int dvb_usb_pll_set(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 b[5])
+int dvb_usb_tuner_calc_regs(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep, u8 *b, int buf_len)
{
struct dvb_usb_device *d = fe->dvb->priv;
+ if (buf_len != 5)
+ return -EINVAL;
if (d->pll_desc == NULL)
return 0;
deb_pll("pll addr: %x, freq: %d %p\n",d->pll_addr,fep->frequency,d->pll_desc);
- b[0] = d->pll_addr << 1;
+ b[0] = d->pll_addr;
dvb_pll_configure(d->pll_desc,&b[1],fep->frequency,fep->u.ofdm.bandwidth);
deb_pll("pll-buf: %x %x %x %x %x\n",b[0],b[1],b[2],b[3],b[4]);
- return 0;
+ return 5;
}
-EXPORT_SYMBOL(dvb_usb_pll_set);
+EXPORT_SYMBOL(dvb_usb_tuner_calc_regs);
-int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
+int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters *fep)
{
struct dvb_usb_device *d = fe->dvb->priv;
int ret = 0;
u8 b[5];
struct i2c_msg msg = { .addr = d->pll_addr, .flags = 0, .buf = &b[1], .len = 4 };
- dvb_usb_pll_set(fe,fep,b);
+ dvb_usb_tuner_calc_regs(fe,fep,b,5);
if (d->tuner_pass_ctrl)
d->tuner_pass_ctrl(fe,1,d->pll_addr);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
if (i2c_transfer (&d->i2c_adap, &msg, 1) != 1) {
err("tuner i2c write failed for pll_set.");
ret = -EREMOTEIO;
@@ -116,4 +122,4 @@ int dvb_usb_pll_set_i2c(struct dvb_frontend *fe, struct dvb_frontend_parameters
return ret;
}
-EXPORT_SYMBOL(dvb_usb_pll_set_i2c);
+EXPORT_SYMBOL(dvb_usb_tuner_set_params_i2c);
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
index cb239049b098..95698918bc11 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb-ids.h
@@ -31,6 +31,7 @@
#define USB_VID_VISIONPLUS 0x13d3
#define USB_VID_TWINHAN 0x1822
#define USB_VID_ULTIMA_ELECTRONIC 0x05d8
+#define USB_VID_GENPIX 0x09c0
/* Product IDs */
#define USB_PID_ADSTECH_USB2_COLD 0xa333
@@ -104,5 +105,6 @@
#define USB_PID_KYE_DVB_T_WARM 0x701f
#define USB_PID_PCTV_200E 0x020e
#define USB_PID_PCTV_400E 0x020f
-
+#define USB_PID_GENPIX_8PSK_COLD 0x0200
+#define USB_PID_GENPIX_8PSK_WARM 0x0201
#endif
diff --git a/drivers/media/dvb/dvb-usb/dvb-usb.h b/drivers/media/dvb/dvb-usb/dvb-usb.h
index fead958a57e3..4cf9f89c51bf 100644
--- a/drivers/media/dvb/dvb-usb/dvb-usb.h
+++ b/drivers/media/dvb/dvb-usb/dvb-usb.h
@@ -330,9 +330,9 @@ extern int dvb_usb_generic_write(struct dvb_usb_device *, u8 *, u16);
extern int dvb_usb_nec_rc_key_to_event(struct dvb_usb_device *, u8[], u32 *, int *);
/* commonly used pll init and set functions */
-extern int dvb_usb_pll_init_i2c(struct dvb_frontend *);
-extern int dvb_usb_pll_set(struct dvb_frontend *, struct dvb_frontend_parameters *, u8[]);
-extern int dvb_usb_pll_set_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *);
+extern int dvb_usb_tuner_init_i2c(struct dvb_frontend *);
+extern int dvb_usb_tuner_calc_regs(struct dvb_frontend *, struct dvb_frontend_parameters *, u8 *buf, int buf_len);
+extern int dvb_usb_tuner_set_params_i2c(struct dvb_frontend *, struct dvb_frontend_parameters *);
/* commonly used firmware download types and function */
struct hexline {
diff --git a/drivers/media/dvb/dvb-usb/gp8psk-fe.c b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
new file mode 100644
index 000000000000..6ccbdc9cd772
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk-fe.c
@@ -0,0 +1,272 @@
+/* DVB USB compliant Linux driver for the
+ * - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ * 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 "gp8psk.h"
+
+struct gp8psk_fe_state {
+ struct dvb_frontend fe;
+
+ struct dvb_usb_device *d;
+
+ u16 snr;
+
+ unsigned long next_snr_check;
+};
+
+static int gp8psk_fe_read_status(struct dvb_frontend* fe, fe_status_t *status)
+{
+ struct gp8psk_fe_state *st = fe->demodulator_priv;
+ u8 lock;
+
+ if (gp8psk_usb_in_op(st->d, GET_SIGNAL_LOCK, 0, 0, &lock,1))
+ return -EINVAL;
+
+ if (lock)
+ *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI | FE_HAS_SIGNAL | FE_HAS_CARRIER;
+ else
+ *status = 0;
+
+ return 0;
+}
+
+/* not supported by this Frontend */
+static int gp8psk_fe_read_ber(struct dvb_frontend* fe, u32 *ber)
+{
+ (void) fe;
+ *ber = 0;
+ return 0;
+}
+
+/* not supported by this Frontend */
+static int gp8psk_fe_read_unc_blocks(struct dvb_frontend* fe, u32 *unc)
+{
+ (void) fe;
+ *unc = 0;
+ return 0;
+}
+
+static int gp8psk_fe_read_snr(struct dvb_frontend* fe, u16 *snr)
+{
+ struct gp8psk_fe_state *st = fe->demodulator_priv;
+ u8 buf[2];
+
+ if (time_after(jiffies,st->next_snr_check)) {
+ gp8psk_usb_in_op(st->d,GET_SIGNAL_STRENGTH,0,0,buf,2);
+ *snr = (int)(buf[1]) << 8 | buf[0];
+ /* snr is reported in dBu*256 */
+ /* snr / 38.4 ~= 100% strength */
+ /* snr * 17 returns 100% strength as 65535 */
+ if (*snr <= 3855)
+ *snr = (*snr<<4) + *snr; // snr * 17
+ else
+ *snr = 65535;
+ st->next_snr_check = jiffies + (10*HZ)/1000;
+ } else {
+ *snr = st->snr;
+ }
+ return 0;
+}
+
+static int gp8psk_fe_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
+{
+ return gp8psk_fe_read_snr(fe, strength);
+}
+
+static int gp8psk_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
+{
+ tune->min_delay_ms = 800;
+ return 0;
+}
+
+static int gp8psk_fe_set_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fep)
+{
+ struct gp8psk_fe_state *state = fe->demodulator_priv;
+ u8 cmd[10];
+ u32 freq = fep->frequency * 1000;
+
+ cmd[4] = freq & 0xff;
+ cmd[5] = (freq >> 8) & 0xff;
+ cmd[6] = (freq >> 16) & 0xff;
+ cmd[7] = (freq >> 24) & 0xff;
+
+ switch(fe->ops.info.type) {
+ case FE_QPSK:
+ cmd[0] = fep->u.qpsk.symbol_rate & 0xff;
+ cmd[1] = (fep->u.qpsk.symbol_rate >> 8) & 0xff;
+ cmd[2] = (fep->u.qpsk.symbol_rate >> 16) & 0xff;
+ cmd[3] = (fep->u.qpsk.symbol_rate >> 24) & 0xff;
+ cmd[8] = ADV_MOD_DVB_QPSK;
+ cmd[9] = 0x03; /*ADV_MOD_FEC_XXX*/
+ break;
+ default:
+ // other modes are unsuported right now
+ cmd[0] = 0;
+ cmd[1] = 0;
+ cmd[2] = 0;
+ cmd[3] = 0;
+ cmd[8] = 0;
+ cmd[9] = 0;
+ break;
+ }
+
+ gp8psk_usb_out_op(state->d,TUNE_8PSK,0,0,cmd,10);
+
+ state->next_snr_check = jiffies;
+
+ return 0;
+}
+
+static int gp8psk_fe_get_frontend(struct dvb_frontend* fe,
+ struct dvb_frontend_parameters *fep)
+{
+ return 0;
+}
+
+
+static int gp8psk_fe_send_diseqc_msg (struct dvb_frontend* fe,
+ struct dvb_diseqc_master_cmd *m)
+{
+ struct gp8psk_fe_state *st = fe->demodulator_priv;
+
+ deb_fe("%s\n",__FUNCTION__);
+
+ if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, m->msg[0], 0,
+ m->msg, m->msg_len)) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int gp8psk_fe_send_diseqc_burst (struct dvb_frontend* fe,
+ fe_sec_mini_cmd_t burst)
+{
+ struct gp8psk_fe_state *st = fe->demodulator_priv;
+ u8 cmd;
+
+ deb_fe("%s\n",__FUNCTION__);
+
+ /* These commands are certainly wrong */
+ cmd = (burst == SEC_MINI_A) ? 0x00 : 0x01;
+
+ if (gp8psk_usb_out_op(st->d,SEND_DISEQC_COMMAND, cmd, 0,
+ &cmd, 0)) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int gp8psk_fe_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
+{
+ struct gp8psk_fe_state* state = fe->demodulator_priv;
+
+ if (gp8psk_usb_out_op(state->d,SET_22KHZ_TONE,
+ (tone == SEC_TONE_ON), 0, NULL, 0)) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int gp8psk_fe_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
+{
+ struct gp8psk_fe_state* state = fe->demodulator_priv;
+
+ if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE,
+ voltage == SEC_VOLTAGE_18, 0, NULL, 0)) {
+ return -EINVAL;
+ }
+ return 0;
+}
+
+static int gp8psk_fe_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long sw_cmd)
+{
+ struct gp8psk_fe_state* state = fe->demodulator_priv;
+ u8 cmd = sw_cmd & 0x7f;
+
+ if (gp8psk_usb_out_op(state->d,SET_DN_SWITCH, cmd, 0,
+ NULL, 0)) {
+ return -EINVAL;
+ }
+ if (gp8psk_usb_out_op(state->d,SET_LNB_VOLTAGE, !!(sw_cmd & 0x80),
+ 0, NULL, 0)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void gp8psk_fe_release(struct dvb_frontend* fe)
+{
+ struct gp8psk_fe_state *state = fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops gp8psk_fe_ops;
+
+struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d)
+{
+ struct gp8psk_fe_state *s = kzalloc(sizeof(struct gp8psk_fe_state), GFP_KERNEL);
+ if (s == NULL)
+ goto error;
+
+ s->d = d;
+ memcpy(&s->fe.ops, &gp8psk_fe_ops, sizeof(struct dvb_frontend_ops));
+ s->fe.demodulator_priv = s;
+
+ goto success;
+error:
+ return NULL;
+success:
+ return &s->fe;
+}
+
+
+static struct dvb_frontend_ops gp8psk_fe_ops = {
+ .info = {
+ .name = "Genpix 8psk-USB DVB-S",
+ .type = FE_QPSK,
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_stepsize = 100,
+ .symbol_rate_min = 1000000,
+ .symbol_rate_max = 45000000,
+ .symbol_rate_tolerance = 500, /* ppm */
+ .caps = FE_CAN_INVERSION_AUTO |
+ 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_FEC_AUTO |
+ FE_CAN_QPSK
+ },
+
+ .release = gp8psk_fe_release,
+
+ .init = NULL,
+ .sleep = NULL,
+
+ .set_frontend = gp8psk_fe_set_frontend,
+ .get_frontend = gp8psk_fe_get_frontend,
+ .get_tune_settings = gp8psk_fe_get_tune_settings,
+
+ .read_status = gp8psk_fe_read_status,
+ .read_ber = gp8psk_fe_read_ber,
+ .read_signal_strength = gp8psk_fe_read_signal_strength,
+ .read_snr = gp8psk_fe_read_snr,
+ .read_ucblocks = gp8psk_fe_read_unc_blocks,
+
+ .diseqc_send_master_cmd = gp8psk_fe_send_diseqc_msg,
+ .diseqc_send_burst = gp8psk_fe_send_diseqc_burst,
+ .set_tone = gp8psk_fe_set_tone,
+ .set_voltage = gp8psk_fe_set_voltage,
+ .dishnetwork_send_legacy_command = gp8psk_fe_send_legacy_dish_cmd,
+};
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.c b/drivers/media/dvb/dvb-usb/gp8psk.c
new file mode 100644
index 000000000000..9a98f3fdae31
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk.c
@@ -0,0 +1,256 @@
+/* DVB USB compliant Linux driver for the
+ * - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ * 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 "gp8psk.h"
+
+/* debug */
+static char bcm4500_firmware[] = "dvb-usb-gp8psk-02.fw";
+int dvb_usb_gp8psk_debug;
+module_param_named(debug,dvb_usb_gp8psk_debug, int, 0644);
+MODULE_PARM_DESC(debug, "set debugging level (1=info,xfer=2,rc=4 (or-able))." DVB_USB_DEBUG_STATUS);
+
+int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen)
+{
+ int ret = 0,try = 0;
+
+ if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
+ return ret;
+
+ 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);
+
+ mutex_unlock(&d->usb_mutex);
+
+ return ret;
+}
+
+int gp8psk_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value,
+ u16 index, u8 *b, int blen)
+{
+ int ret;
+
+ deb_xfer("out: req. %x, val: %x, ind: %x, buffer: ",req,value,index);
+ debug_dump(b,blen,deb_xfer);
+
+ if ((ret = mutex_lock_interruptible(&d->usb_mutex)))
+ return ret;
+
+ 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.");
+ ret = -EIO;
+ } else
+ ret = 0;
+ mutex_unlock(&d->usb_mutex);
+
+ return ret;
+}
+
+static int gp8psk_load_bcm4500fw(struct dvb_usb_device *d)
+{
+ int ret;
+ const struct firmware *fw = NULL;
+ u8 *ptr, *buf;
+ if ((ret = request_firmware(&fw, bcm4500_firmware,
+ &d->udev->dev)) != 0) {
+ err("did not find the bcm4500 firmware file. (%s) "
+ "Please see linux/Documentation/dvb/ for more details on firmware-problems. (%d)",
+ bcm4500_firmware,ret);
+ return ret;
+ }
+
+ ret = -EINVAL;
+
+ if (gp8psk_usb_out_op(d, LOAD_BCM4500,1,0,NULL, 0))
+ goto out_rel_fw;
+
+ info("downloaidng bcm4500 firmware from file '%s'",bcm4500_firmware);
+
+ ptr = fw->data;
+ buf = kmalloc(512, GFP_KERNEL | GFP_DMA);
+
+ while (ptr[0] != 0xff) {
+ u16 buflen = ptr[0] + 4;
+ if (ptr + buflen >= fw->data + fw->size) {
+ err("failed to load bcm4500 firmware.");
+ goto out_free;
+ }
+ memcpy(buf, ptr, buflen);
+ if (dvb_usb_generic_write(d, buf, buflen)) {
+ err("failed to load bcm4500 firmware.");
+ goto out_free;
+ }
+ ptr += buflen;
+ }
+
+ ret = 0;
+
+out_free:
+ kfree(buf);
+out_rel_fw:
+ release_firmware(fw);
+
+ return ret;
+}
+
+static int gp8psk_power_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ u8 status, buf;
+ if (onoff) {
+ gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
+ if (! (status & 0x01)) /* started */
+ if (gp8psk_usb_in_op(d, BOOT_8PSK, 1, 0, &buf, 1))
+ return -EINVAL;
+
+ if (! (status & 0x02)) /* BCM4500 firmware loaded */
+ if(gp8psk_load_bcm4500fw(d))
+ return EINVAL;
+
+ if (! (status & 0x04)) /* LNB Power */
+ if (gp8psk_usb_in_op(d, START_INTERSIL, 1, 0,
+ &buf, 1))
+ return EINVAL;
+
+ /* Set DVB mode */
+ if(gp8psk_usb_out_op(d, SET_DVB_MODE, 1, 0, NULL, 0))
+ return -EINVAL;
+ gp8psk_usb_in_op(d, GET_8PSK_CONFIG,0,0,&status,1);
+ } else {
+ /* Turn off LNB power */
+ if (gp8psk_usb_in_op(d, START_INTERSIL, 0, 0, &buf, 1))
+ return EINVAL;
+ /* Turn off 8psk power */
+ if (gp8psk_usb_in_op(d, BOOT_8PSK, 0, 0, &buf, 1))
+ return -EINVAL;
+
+ }
+ return 0;
+}
+
+
+static int gp8psk_streaming_ctrl(struct dvb_usb_device *d, int onoff)
+{
+ return gp8psk_usb_out_op(d, ARM_TRANSFER, onoff, 0 , NULL, 0);
+}
+
+static int gp8psk_frontend_attach(struct dvb_usb_device *d)
+{
+ d->fe = gp8psk_fe_attach(d);
+
+ return 0;
+}
+
+static struct dvb_usb_properties gp8psk_properties;
+
+static int gp8psk_usb_probe(struct usb_interface *intf,
+ const struct usb_device_id *id)
+{
+ return dvb_usb_device_init(intf,&gp8psk_properties,THIS_MODULE,NULL);
+}
+
+static struct usb_device_id gp8psk_usb_table [] = {
+ { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_COLD) },
+ { USB_DEVICE(USB_VID_GENPIX, USB_PID_GENPIX_8PSK_WARM) },
+ { 0 },
+};
+MODULE_DEVICE_TABLE(usb, gp8psk_usb_table);
+
+static struct dvb_usb_properties gp8psk_properties = {
+ .caps = 0,
+
+ .usb_ctrl = CYPRESS_FX2,
+ .firmware = "dvb-usb-gp8psk-01.fw",
+
+ .streaming_ctrl = gp8psk_streaming_ctrl,
+ .power_ctrl = gp8psk_power_ctrl,
+ .frontend_attach = gp8psk_frontend_attach,
+
+ .generic_bulk_ctrl_endpoint = 0x01,
+ /* parameter for the MPEG2-data transfer */
+ .urb = {
+ .type = DVB_USB_BULK,
+ .count = 7,
+ .endpoint = 0x82,
+ .u = {
+ .bulk = {
+ .buffersize = 8192,
+ }
+ }
+ },
+
+ .num_device_descs = 1,
+ .devices = {
+ { .name = "Genpix 8PSK-USB DVB-S USB2.0 receiver",
+ .cold_ids = { &gp8psk_usb_table[0], NULL },
+ .warm_ids = { &gp8psk_usb_table[1], NULL },
+ },
+ { 0 },
+ }
+};
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver gp8psk_usb_driver = {
+ .name = "dvb_usb_gp8psk",
+ .probe = gp8psk_usb_probe,
+ .disconnect = dvb_usb_device_exit,
+ .id_table = gp8psk_usb_table,
+};
+
+/* module stuff */
+static int __init gp8psk_usb_module_init(void)
+{
+ int result;
+ if ((result = usb_register(&gp8psk_usb_driver))) {
+ err("usb_register failed. (%d)",result);
+ return result;
+ }
+
+ return 0;
+}
+
+static void __exit gp8psk_usb_module_exit(void)
+{
+ /* deregister this driver from the USB subsystem */
+ usb_deregister(&gp8psk_usb_driver);
+}
+
+module_init(gp8psk_usb_module_init);
+module_exit(gp8psk_usb_module_exit);
+
+MODULE_AUTHOR("Alan Nisota <alannisota@gamil.com>");
+MODULE_DESCRIPTION("Driver for Genpix 8psk-USB DVB-S USB2.0");
+MODULE_VERSION("1.0");
+MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/dvb-usb/gp8psk.h b/drivers/media/dvb/dvb-usb/gp8psk.h
new file mode 100644
index 000000000000..3eba7061011c
--- /dev/null
+++ b/drivers/media/dvb/dvb-usb/gp8psk.h
@@ -0,0 +1,79 @@
+/* DVB USB compliant Linux driver for the
+ * - GENPIX 8pks/qpsk USB2.0 DVB-S module
+ *
+ * Copyright (C) 2006 Alan Nisota (alannisota@gmail.com)
+ *
+ * Thanks to GENPIX for the sample code used to implement this module.
+ *
+ * This module is based off the vp7045 and vp702x modules
+ *
+ * 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
+ */
+#ifndef _DVB_USB_GP8PSK_H_
+#define _DVB_USB_GP8PSK_H_
+
+#define DVB_USB_LOG_PREFIX "gp8psk"
+#include "dvb-usb.h"
+
+extern int dvb_usb_gp8psk_debug;
+#define deb_info(args...) dprintk(dvb_usb_gp8psk_debug,0x01,args)
+#define deb_xfer(args...) dprintk(dvb_usb_gp8psk_debug,0x02,args)
+#define deb_rc(args...) dprintk(dvb_usb_gp8psk_debug,0x04,args)
+#define deb_fe(args...) dprintk(dvb_usb_gp8psk_debug,0x08,args)
+/* gp8psk commands */
+
+/* Twinhan Vendor requests */
+#define TH_COMMAND_IN 0xC0
+#define TH_COMMAND_OUT 0xC1
+
+/* command bytes */
+#define GET_8PSK_CONFIG 0x80
+#define SET_8PSK_CONFIG 0x81
+#define ARM_TRANSFER 0x85
+#define TUNE_8PSK 0x86
+#define GET_SIGNAL_STRENGTH 0x87
+#define LOAD_BCM4500 0x88
+#define BOOT_8PSK 0x89
+#define START_INTERSIL 0x8A
+#define SET_LNB_VOLTAGE 0x8B
+#define SET_22KHZ_TONE 0x8C
+#define SEND_DISEQC_COMMAND 0x8D
+#define SET_DVB_MODE 0x8E
+#define SET_DN_SWITCH 0x8F
+#define GET_SIGNAL_LOCK 0x90
+
+/* Satellite modulation modes */
+#define ADV_MOD_DVB_QPSK 0 /* DVB-S QPSK */
+#define ADV_MOD_TURBO_QPSK 1 /* Turbo QPSK */
+#define ADV_MOD_TURBO_8PSK 2 /* Turbo 8PSK (also used for Trellis 8PSK) */
+#define ADV_MOD_TURBO_16QAM 3 /* Turbo 16QAM (also used for Trellis 8PSK) */
+
+#define ADV_MOD_DCII_C_QPSK 4 /* Digicipher II Combo */
+#define ADV_MOD_DCII_I_QPSK 5 /* Digicipher II I-stream */
+#define ADV_MOD_DCII_Q_QPSK 6 /* Digicipher II Q-stream */
+#define ADV_MOD_DCII_C_OQPSK 7 /* Digicipher II offset QPSK */
+#define ADV_MOD_DSS_QPSK 8 /* DSS (DIRECTV) QPSK */
+#define ADV_MOD_DVB_BPSK 9 /* DVB-S BPSK */
+
+#define GET_USB_SPEED 0x07
+ #define USB_SPEED_LOW 0
+ #define USB_SPEED_FULL 1
+ #define USB_SPEED_HIGH 2
+
+#define RESET_FX2 0x13
+
+#define FW_VERSION_READ 0x0B
+#define VENDOR_STRING_READ 0x0C
+#define PRODUCT_STRING_READ 0x0D
+#define FW_BCD_VERSION_READ 0x14
+
+extern struct dvb_frontend * gp8psk_fe_attach(struct dvb_usb_device *d);
+extern int gp8psk_usb_in_op(struct dvb_usb_device *d, u8 req, u16 value, u16 index, u8 *b, int blen);
+extern int gp8psk_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/umt-010.c b/drivers/media/dvb/dvb-usb/umt-010.c
index 14f1911c79bb..97d74da0dad8 100644
--- a/drivers/media/dvb/dvb-usb/umt-010.c
+++ b/drivers/media/dvb/dvb-usb/umt-010.c
@@ -57,7 +57,6 @@ static int umt_mt352_frontend_attach(struct dvb_usb_device *d)
memset(&umt_config,0,sizeof(struct mt352_config));
umt_config.demod_init = umt_mt352_demod_init;
umt_config.demod_address = 0xf;
- umt_config.pll_set = dvb_usb_pll_set;
d->fe = mt352_attach(&umt_config, &d->i2c_adap);
@@ -68,6 +67,7 @@ static int umt_tuner_attach (struct dvb_usb_device *d)
{
d->pll_addr = 0x61;
d->pll_desc = &dvb_pll_tua6034;
+ d->fe->ops.tuner_ops.calc_regs = dvb_usb_tuner_calc_regs;
return 0;
}
diff --git a/drivers/media/dvb/dvb-usb/vp702x-fe.c b/drivers/media/dvb/dvb-usb/vp702x-fe.c
index 2a89f8c5da99..d4da494132ec 100644
--- a/drivers/media/dvb/dvb-usb/vp702x-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp702x-fe.c
@@ -287,17 +287,16 @@ struct dvb_frontend * vp702x_fe_attach(struct dvb_usb_device *d)
goto error;
s->d = d;
- s->fe.ops = &vp702x_fe_ops;
+
+ memcpy(&s->fe.ops,&vp702x_fe_ops,sizeof(struct dvb_frontend_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;
+ return &s->fe;
error:
return NULL;
-success:
- return &s->fe;
}
diff --git a/drivers/media/dvb/dvb-usb/vp7045-fe.c b/drivers/media/dvb/dvb-usb/vp7045-fe.c
index 9999336aeeb6..8452eef90322 100644
--- a/drivers/media/dvb/dvb-usb/vp7045-fe.c
+++ b/drivers/media/dvb/dvb-usb/vp7045-fe.c
@@ -23,8 +23,6 @@
struct vp7045_fe_state {
struct dvb_frontend fe;
- struct dvb_frontend_ops ops;
-
struct dvb_usb_device *d;
};
@@ -151,15 +149,12 @@ struct dvb_frontend * vp7045_fe_attach(struct dvb_usb_device *d)
goto error;
s->d = d;
- memcpy(&s->ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
- s->fe.ops = &s->ops;
+ memcpy(&s->fe.ops, &vp7045_fe_ops, sizeof(struct dvb_frontend_ops));
s->fe.demodulator_priv = s;
- goto success;
+ return &s->fe;
error:
return NULL;
-success:
- return &s->fe;
}