#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);
struct dvb_ca_en50221 ca;
struct mutex ca_mutex;
u8 power_state;
-};
-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,
+ /* 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_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,
+struct drxk_config terratec_h7_drxk = {
+ .adr = 0x29,
+ .single_master = 1,
+ .no_i2c_bridge = 1,
+ .microcode_name = "dvb-usb-terratec-h5-drxk.fw",
};
+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,
.refclock = 36125000,
{
int ret;
-#if 0
+#if 0
int i=0, cyc=0, rem=0;
cyc = blen/64;
rem = blen%64;
deb_xfer("out: req. %02x, val: %04x, ind: %04x, buffer: ",req,value,index);
debug_dump(b,blen,deb_xfer);
-
+
#if 0
if (blen>64)
{
5000)) != 64) {
warn("usb out operation failed. (%d)",ret);
return -EIO;
- }
+ }
}
if (rem>0)
}
}
else
-#endif
+#endif
{
if ((ret = usb_control_msg(d->udev,
usb_sndctrlpipe(d->udev,0),
return -EIO;
}
}
-
+
return 0;
}
}
/* 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) */
int i;
/* remove the following return to enabled remote querying */
-
+
az6007_usb_in_op(d,READ_REMOTE_REQ,0,0,key,10);
int blen;
info("az6007_frontend_reset adap=%p adap->dev=%p\n", adap, adap->dev);
-
+
//reset demodulator
req = 0xC0;
value = 1;//high
err("az6007_frontend_reset failed 1 !!!");
return -EIO;
}
-
+
req = 0xC0;
value = 0;//low
index = 3;
err("az6007_frontend_reset failed 3 !!!");
return -EIO;
}
-
+
msleep_interruptible(200);
-
+
info("reset az6007 frontend\n");
-
+
return 0;
}
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);
- }
- 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");
+
+ /* 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;
}
- //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;
int length;
u8 req;
u8 data[512];
-
+
if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
return -EAGAIN;
if (num > 2)
//printk("Tuner Tuner ReadDATA len=%d ", len);
for (j=0; j<len; j++)
{
- msg[1].buf[j] = data[j+5];
+ msg[1].buf[j] = data[j+5];
//printk("data[%d]=%02x ", j, data[j+5]);
}
//printk("\n");
value = msg[0].addr | (1<<8);
length = msg[0].len - 1;
len = msg[0].len - 1;
- //printk("Demodulator WriteDATA len=%d ", len);
+ //printk("Demodulator WriteDATA len=%d ", len);
for(j=0;j<len;j++)
{
data[j] = msg[0].buf[j+1];
//printk("data[%d]=%02x ", j, data[j]);
}
- //printk("\n");
+ //printk("\n");
ret = az6007_usb_out_op(d,req,value,index,data,length);
}
else //read
//printk("Demodulator ReadDATA len=%d ", len);
for (j=0; j<len; j++)
{
- msg[0].buf[j] = data[j+5];
+ msg[0].buf[j] = data[j+5];
//printk("data[%d]=%02x ", j, data[j+5]);
}
//printk("\n");
static int az6007_usb_probe(struct usb_interface *intf,
const struct usb_device_id *id)
{
- az6007_led_on_off(intf, 0);
-
+ az6007_led_on_off(intf, 0);
+
return dvb_usb_device_init(intf, &az6007_properties,
- THIS_MODULE, NULL, adapter_nr);
+ THIS_MODULE, NULL, adapter_nr);
}
static struct usb_device_id az6007_usb_table [] = {
//.power_ctrl = az6007_power_ctrl,
.read_mac_address = az6007_read_mac_addr,
- .rc_key_map = az6007_rc_keys,
- .rc_key_map_size = ARRAY_SIZE(az6007_rc_keys),
- .rc_interval = 400,
- .rc_query = az6007_rc_query,
+ .rc.legacy = {
+ .rc_map_table = rc_map_az6007_table,
+ .rc_map_size = ARRAY_SIZE(rc_map_az6007_table),
+ .rc_interval = 400,
+ .rc_query = az6007_rc_query,
+ },
.i2c_algo = &az6007_i2c_algo,
.num_device_descs = 2,
.cold_ids = { &az6007_usb_table[1], NULL },
.warm_ids = { NULL },
},
- { NULL },
+ { NULL },
}
};
-
+
/* usb specific object needed to register this driver with the usb subsystem */
static struct usb_driver az6007_usb_driver = {
.name = "dvb_usb_az6007",