Commit b7571f8d authored by Patrick Boettcher's avatar Patrick Boettcher Committed by Mauro Carvalho Chehab
Browse files

V4L/DVB: Complete rewrite of the DiB3000mc-driver



A complete rewrite of the DiB3000MC/P driver has been done. It is now much more
easy to maintain and to get improvements inside.

Additionally the tuning time has been reduced and the usage of the driver is
much more understandable now.

Signed-off-by: default avatarPatrick Boettcher <pboettcher@dibcom.fr>
Signed-off-by: default avatarFrancois KANOUNNIKOFF <fkanounnikoff@dibcom.fr>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@infradead.org>
parent 74340b0a
Loading
Loading
Loading
Loading
+117 −14
Original line number Diff line number Diff line
@@ -131,9 +131,6 @@ static int dibusb_i2c_xfer(struct i2c_adapter *adap,struct i2c_msg msg[],int num
	if (mutex_lock_interruptible(&d->i2c_mutex) < 0)
		return -EAGAIN;

	if (num > 2)
		warn("more than 2 i2c messages at a time is not handled yet. TODO.");

	for (i = 0; i < num; i++) {
		/* write/read request */
		if (i+1 < num && (msg[i+1].flags & I2C_M_RD)) {
@@ -168,31 +165,137 @@ int dibusb_read_eeprom_byte(struct dvb_usb_device *d, u8 offs, u8 *val)
}
EXPORT_SYMBOL(dibusb_read_eeprom_byte);

static const struct dib3000p_agc_config dib3000p_agc_panasonic_env57h1xd5 = {
	{ 0x51, 0x301d, 0x0, 0x1cc7, 0xdc29, 0x570a,
	0xbae1, 0x8ccd, 0x3b6d, 0x551d, 0xa, 0x951e }
/* 3000MC/P stuff */
// Config Adjacent channels  Perf -cal22
static struct dibx000_agc_config dib3000p_mt2060_agc_config = {
	.band_caps = BAND_VHF | BAND_UHF,
	.setup     = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0),

	.agc1_max = 48497,
	.agc1_min = 23593,
	.agc2_max = 46531,
	.agc2_min = 24904,

	.agc1_pt1 = 0x65,
	.agc1_pt2 = 0x69,

	.agc1_slope1 = 0x51,
	.agc1_slope2 = 0x27,

	.agc2_pt1 = 0,
	.agc2_pt2 = 0x33,

	.agc2_slope1 = 0x35,
	.agc2_slope2 = 0x37,
};

static const struct dib3000p_agc_config dib3000p_agc_microtune_mt2060 = {
	{ 0x196, 0x301d, 0x0, 0x1cc7, 0xffff, 0x5c29,
	0xa8f6, 0x5eb8, 0x65ff, 0x40ff,	0x8a, 0x1114 }
static struct dib3000mc_config stk3000p_dib3000p_config = {
	&dib3000p_mt2060_agc_config,

	.max_time     = 0x196,
	.ln_adc_level = 0x1cc7,

	.output_mpeg2_in_188_bytes = 1,
};

static struct mt2060_config stk3000p_mt2060_config = {
	.i2c_address = 0x60,
static struct dibx000_agc_config dib3000p_panasonic_agc_config = {
	.setup     = (0 << 15) | (0 << 14) | (1 << 13) | (1 << 12) | (29 << 0),

	.agc1_max = 56361,
	.agc1_min = 22282,
	.agc2_max = 43254,
	.agc2_min = 36045,

	.agc1_pt1 = 0x65,
	.agc1_pt2 = 0xff,

	.agc1_slope1 = 0x40,
	.agc1_slope2 = 0xff,

	.agc2_pt1 = 0,
	.agc2_pt2 = 0x8a,

	.agc2_slope1 = 0x11,
	.agc2_slope2 = 0x14,
};

static struct dib3000mc_config mod3000p_dib3000p_config = {
	&dib3000p_panasonic_agc_config,

	.max_time     = 0x51,
	.ln_adc_level = 0x1cc7,

	.output_mpeg2_in_188_bytes = 1,
};

int dibusb_dib3000mc_frontend_attach(struct dvb_usb_device *d)
{
	struct dib3000_config demod_cfg;
	if (dib3000mc_attach(&d->i2c_adap, 1, DEFAULT_DIB3000P_I2C_ADDRESS, 0, &mod3000p_dib3000p_config, &d->fe) == 0) {
		if (d->priv != NULL) {
			struct dibusb_state *st = d->priv;
			st->ops.pid_parse = dib3000mc_pid_parse;
			st->ops.pid_ctrl  = dib3000mc_pid_control;
		}
		return 0;
	}
	return -ENODEV;
}
EXPORT_SYMBOL(dibusb_dib3000mc_frontend_attach);

static struct mt2060_config stk3000p_mt2060_config = {
	0x60
};

int dibusb_dib3000mc_tuner_attach (struct dvb_usb_device *d)
{
	return -ENODEV;
	struct dibusb_state *st = d->priv;
	int ret;
	u8 a,b;
	u16 if1 = 1220;
	struct i2c_adapter *tun_i2c;

	// First IF calibration for Liteon Sticks
	if (d->udev->descriptor.idVendor == USB_VID_LITEON &&
		d->udev->descriptor.idProduct == USB_PID_LITEON_DVB_T_WARM) {

		dibusb_read_eeprom_byte(d,0x7E,&a);
		dibusb_read_eeprom_byte(d,0x7F,&b);

		if (a == 0x00)
			if1 += b;
		else if (a == 0x80)
			if1 -= b;
		else
			warn("LITE-ON DVB-T: Strange IF1 calibration :%2X %2X\n", a, b);

	} else if (d->udev->descriptor.idVendor  == USB_VID_DIBCOM &&
		   d->udev->descriptor.idProduct == USB_PID_DIBCOM_MOD3001_WARM) {
		u8 desc;
		dibusb_read_eeprom_byte(d, 7, &desc);
		if (desc == 2) {
			a = 127;
			do {
				dibusb_read_eeprom_byte(d, a, &desc);
				a--;
			} while (a > 7 && (desc == 0xff || desc == 0x00));
			if (desc & 0x80)
				if1 -= (0xff - desc);
			else
				if1 += desc;
		}
	}

	tun_i2c = dib3000mc_get_tuner_i2c_master(d->fe, 1);
	if ((ret = mt2060_attach(d->fe, tun_i2c, &stk3000p_mt2060_config, if1)) != 0) {
		/* not found - use panasonic pll parameters */
		if (dvb_pll_attach(d->fe, 0x60, tun_i2c, &dvb_pll_env57h1xd5) == NULL)
			return -ENOMEM;
	} else {
		st->mt2060_present = 1;
		/* set the correct parameters for the dib3000p */
		dib3000mc_set_config(d->fe, &stk3000p_dib3000p_config);
	}
	return 0;
}
EXPORT_SYMBOL(dibusb_dib3000mc_tuner_attach);

+4 −3
Original line number Diff line number Diff line
@@ -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;

+1 −0
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include "dvb-usb.h"

#include "dib3000.h"
#include "dib3000mc.h"
#include "mt2060.h"

/*
+4 −7
Original line number Diff line number Diff line
@@ -179,16 +179,15 @@ int dvb_usb_fe_init(struct dvb_usb_device* d)
		return 0;
	}

	d->props.frontend_attach(d);

	/* re-assign sleep and wakeup functions */
	if (d->fe != NULL) {
	if (d->props.frontend_attach(d) == 0 && 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;

		if (dvb_register_frontend(&d->dvb_adap, d->fe)) {
			err("Frontend registration failed.");
			dvb_frontend_detach(d->fe);
			if (d->fe->ops.release)
				d->fe->ops.release(d->fe);
			d->fe = NULL;
			return -ENODEV;
		}
@@ -203,9 +202,7 @@ int dvb_usb_fe_init(struct dvb_usb_device* d)

int dvb_usb_fe_exit(struct dvb_usb_device *d)
{
	if (d->fe != NULL) {
	if (d->fe != NULL)
		dvb_unregister_frontend(d->fe);
		dvb_frontend_detach(d->fe);
	}
	return 0;
}
+3 −1
Original line number Diff line number Diff line
@@ -12,7 +12,7 @@ obj-$(CONFIG_DVB_CX24110) += cx24110.o
obj-$(CONFIG_DVB_TDA8083) += tda8083.o
obj-$(CONFIG_DVB_L64781) += l64781.o
obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o
obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
obj-$(CONFIG_DVB_MT312) += mt312.o
obj-$(CONFIG_DVB_VES1820) += ves1820.o
obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
@@ -31,6 +31,8 @@ obj-$(CONFIG_DVB_BCM3510) += bcm3510.o
obj-$(CONFIG_DVB_S5H1420) += s5h1420.o
obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
obj-$(CONFIG_DVB_CX24123) += cx24123.o
obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
obj-$(CONFIG_DVB_ISL6421) += isl6421.o
obj-$(CONFIG_DVB_TDA10086) += tda10086.o
obj-$(CONFIG_DVB_TDA826X) += tda826x.o
obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
Loading