diff --git a/drivers/media/common/tuners/mt2063.c b/drivers/media/common/tuners/mt2063.c index c89af3cd5eba..7bbf25da3efe 100644 --- a/drivers/media/common/tuners/mt2063.c +++ b/drivers/media/common/tuners/mt2063.c @@ -350,7 +350,7 @@ static int MT2063_Sleep(struct dvb_frontend *fe) /* * ToDo: Add code here to implement a OS blocking */ - msleep(10); + msleep(100); return 0; } diff --git a/drivers/media/dvb/dvb-usb/az6007.c b/drivers/media/dvb/dvb-usb/az6007.c index cd5dd4cecd0b..5873759f5db4 100644 --- a/drivers/media/dvb/dvb-usb/az6007.c +++ b/drivers/media/dvb/dvb-usb/az6007.c @@ -8,6 +8,10 @@ #include "mt2063.h" #include "dvb_ca_en50221.h" +/* HACK: Should be moved to the right place */ +#define USB_PID_AZUREWAVE_6007 0xccd +#define USB_PID_TERRATEC_H7 0x10b4 + /* debug */ int dvb_usb_az6007_debug; module_param_named(debug,dvb_usb_az6007_debug, int, 0644); @@ -28,29 +32,38 @@ struct az6007_device_state { struct dvb_ca_en50221 ca; struct mutex ca_mutex; u8 power_state; + + /* Due to DRX-K - probably need changes */ + int (*gate_ctrl)(struct dvb_frontend *, int); + struct semaphore pll_mutex; + bool dont_attach_fe1; }; -struct drxk3913_config az6007_drxk3913_config_DVBT = { - .demod_address = 0x52, - .min_delay_ms = 100, - .standard = MTTUNEA_DVBT, - .set_tuner = mt2063_setTune, - .tuner_getlocked = mt2063_lockStatus, - .tuner_MT2063_Open = tuner_MT2063_Open, - .tuner_MT2063_SoftwareShutdown = tuner_MT2063_SoftwareShutdown, - .tuner_MT2063_ClearPowerMaskBits = tuner_MT2063_ClearPowerMaskBits, +struct drxk_config terratec_h7_drxk = { + .adr = 0x29, + .single_master = 1, + .no_i2c_bridge = 1, + .microcode_name = "dvb-usb-terratec-h5-drxk.fw", }; -struct drxk3913_config az6007_drxk3913_config_DVBC = { - .demod_address = 0x52, - .min_delay_ms = 100, - .standard = MTTUNEA_DVBC, - .set_tuner = mt2063_setTune, - .tuner_getlocked = mt2063_lockStatus, - .tuner_MT2063_Open = tuner_MT2063_Open, - .tuner_MT2063_SoftwareShutdown = tuner_MT2063_SoftwareShutdown, - .tuner_MT2063_ClearPowerMaskBits = tuner_MT2063_ClearPowerMaskBits, -}; +static int drxk_gate_ctrl(struct dvb_frontend *fe, int enable) +{ + struct dvb_usb_adapter *adap = fe->sec_priv; + struct az6007_device_state *st = adap->priv; + int status; + + if (!adap || !st) + return -EINVAL; + + if (enable) { + down(&st->pll_mutex); + status = st->gate_ctrl(fe, 1); + } else { + status = st->gate_ctrl(fe, 0); + up(&st->pll_mutex); + } + return status; +} struct mt2063_config az6007_mt2063_config = { .tuner_address = 0xc0, @@ -87,7 +100,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, { int ret; -#if 0 +#if 0 int i=0, cyc=0, rem=0; cyc = blen/64; rem = blen%64; @@ -96,7 +109,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index); debug_dump(b,blen,deb_xfer); - + #if 0 if (blen>64) { @@ -110,7 +123,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, 5000)) != 64) { warn("usb out operation failed. (%d)",ret); return -EIO; - } + } } if (rem>0) @@ -127,7 +140,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, } } else -#endif +#endif { if ((ret = usb_control_msg(d->udev, usb_sndctrlpipe(d->udev,0), @@ -139,7 +152,7 @@ static int az6007_usb_out_op(struct dvb_usb_device *d, u8 req, u16 value, return -EIO; } } - + return 0; } @@ -149,9 +162,9 @@ static int az6007_streaming_ctrl(struct dvb_usb_adapter *adap, int onoff) } /* keys for the enclosed remote control */ -static struct dvb_usb_rc_key az6007_rc_keys[] = { - { 0x00, 0x01, KEY_1 }, - { 0x00, 0x02, KEY_2 }, +struct rc_map_table rc_map_az6007_table[] = { + { 0x0001, KEY_1 }, + { 0x0002, KEY_2 }, }; /* remote control stuff (does not work with my box) */ @@ -163,7 +176,7 @@ static int az6007_rc_query(struct dvb_usb_device *d, u32 *event, int *state) int i; /* remove the following return to enabled remote querying */ - + az6007_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10); @@ -257,7 +270,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) int blen; info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev); - + //reset demodulator req = 0xC0; value = 1;//high @@ -268,7 +281,7 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) err("az6007_frontend_reset failed 1 !!!"); return -EIO; } - + req = 0xC0; value = 0;//low index = 3; @@ -290,11 +303,11 @@ static int az6007_frontend_reset(struct dvb_usb_adapter *adap) err("az6007_frontend_reset failed 3 !!!"); return -EIO; } - + msleep_interruptible(200); - + info("reset az6007 frontend\n"); - + return 0; } @@ -350,38 +363,55 @@ static int az6007_frontend_tsbypass(struct dvb_usb_adapter *adap,int onoff) static int az6007_frontend_attach(struct dvb_usb_adapter *adap) { + struct az6007_device_state *st = adap->priv; + + int result; + az6007_frontend_poweron(adap); az6007_frontend_reset(adap); info("az6007_frontend_attach\n"); - if (az6007_type == 0) - { - info("az6007_drxk3913_config_DVBT\n"); - adap->fe = drxk3913_attach(&az6007_drxk3913_config_DVBT, &adap->dev->i2c_adap); + adap->fe = dvb_attach(drxk_attach, &terratec_h7_drxk, + &adap->dev->i2c_adap, &adap->fe2); + if (!adap->fe) { + result = -EINVAL; + goto out_free; } - else - { - info("az6007_drxk3913_config_DVBC\n"); - adap->fe = drxk3913_attach(&az6007_drxk3913_config_DVBC, &adap->dev->i2c_adap); + + /* FIXME: do we need a pll semaphore? */ + adap->fe->sec_priv = adap; + sema_init(&st->pll_mutex, 1); + st->gate_ctrl = adap->fe->ops.i2c_gate_ctrl; + adap->fe->ops.i2c_gate_ctrl = drxk_gate_ctrl; + adap->fe2->id = 1; + + /* Attach mt2063 to DVB-C frontend */ + if (adap->fe->ops.i2c_gate_ctrl) + adap->fe->ops.i2c_gate_ctrl(adap->fe, 1); + if (!dvb_attach(mt2063_attach, adap->fe, &az6007_mt2063_config, + &adap->dev->i2c_adap)) { + result = -EINVAL; + + goto out_free; } - if (adap->fe) { - if (mt2063_attach(adap->fe, &az6007_mt2063_config, &adap->dev->i2c_adap)) { - info("found STB6100 DVB-C/DVB-T frontend @0x%02x\n",az6007_mt2063_config.tuner_address); - - //vp6027_ci_init(adap); - } else { - adap->fe = NULL; - } - } - else - { - adap->fe = NULL; - err("no front-end attached\n"); - } - //az6007_frontend_tsbypass(adap,0); - + if (adap->fe->ops.i2c_gate_ctrl) + adap->fe->ops.i2c_gate_ctrl(adap->fe, 0); + + /* Hack - needed due to drxk */ + adap->fe2->tuner_priv = adap->fe->tuner_priv; + memcpy(&adap->fe2->ops.tuner_ops, + &adap->fe->ops.tuner_ops, + sizeof(adap->fe->ops.tuner_ops)); return 0; + +out_free: + if (adap->fe) + dvb_frontend_detach(adap->fe); + adap->fe = NULL; + adap->fe2 = NULL; + + return result; } static struct dvb_usb_device_properties az6007_properties; @@ -403,7 +433,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num int length; u8 req; u8 data[512]; - + if (mutex_lock_interruptible(&d->i2c_mutex) < 0) return -EAGAIN; if (num > 2) @@ -442,7 +472,7 @@ static int az6007_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num //printk("Tuner Tuner ReadDATA len=%d ", len); for (j=0; j