Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 41557e7c authored by Linus Torvalds's avatar Linus Torvalds
Browse files
* 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (26 commits)
  V4L/DVB (6548): pvrusb2: Fix oops on module removal
  V4L/DVB (6547): V4L: remove PCI from VIDEO_VIVI depends
  V4L/DVB (6532): Add the remaining addresses for tda9887
  V4L/DVB (6531): Fix a regression caused by commit 15396236
  V4L/DVB (6518): Fix tvp5150 default values
  V4L/DVB (6514): em28xx: Include linux/mm.h
  V4L/DVB (6506): saa7134-alsa: Fix mmap support
  V4L/DVB (6504): pvrusb2: Remove dead sysfs code
  V4L/DVB (6503): pvrusb2: Fix associativity logic error
  V4L/DVB (6501): stv0297: Signal strength fixes
  V4L/DVB (6500): tda10021: Fix reported signal strength
  V4L/DVB (6499): tda10021: Bit error counting fixed
  V4L/DVB (6498): ves1820: Change the acquisition range for clock recovery from 120 ppm to 240ppm
  V4L/DVB (6495): saa7146: saa7146_wait_for_debi_done fixes
  V4L/DVB (6479): use input functions, should depend on INPUT
  V4L/DVB (6478): ir-functions use input functions, should depend on INPUT
  V4L/DVB (6432): tuner: fix CONFIG_TUNER_TEA5761=m
  V4L/DVB (6407): planb: fix obvious interrupt handling bugs
  V4L/DVB (6406): saa7134: fix analog audio in on medion md8800 quadro
  V4L/DVB (6403): mt2131: replace comma with semicolon fix
  ...
parents b285e0b7 4f663bdc
Loading
Loading
Loading
Loading
+3 −0
Original line number Original line Diff line number Diff line
@@ -8,4 +8,7 @@
  7 -> Leadtek Winfast USB II                   (em2800)
  7 -> Leadtek Winfast USB II                   (em2800)
  8 -> Kworld USB2800                           (em2800)
  8 -> Kworld USB2800                           (em2800)
  9 -> Pinnacle Dazzle DVC 90                   (em2820/em2840) [2304:0207]
  9 -> Pinnacle Dazzle DVC 90                   (em2820/em2840) [2304:0207]
 10 -> Hauppauge WinTV HVR 900                  (em2880)
 11 -> Terratec Hybrid XS                       (em2880)
 12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
 12 -> Kworld PVR TV 2800 RF                    (em2820/em2840)
 13 -> Terratec Prodigy XS                      (em2880)
+1 −0
Original line number Original line Diff line number Diff line
@@ -151,6 +151,7 @@ config VIDEO_IR_I2C


config VIDEO_IR
config VIDEO_IR
	tristate
	tristate
	depends on INPUT
	select VIDEO_IR_I2C if I2C
	select VIDEO_IR_I2C if I2C


config VIDEO_TVEEPROM
config VIDEO_TVEEPROM
+58 −12
Original line number Original line Diff line number Diff line
@@ -59,43 +59,89 @@ void saa7146_setgpio(struct saa7146_dev *dev, int port, u32 data)
}
}


/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
/* This DEBI code is based on the saa7146 Stradis driver by Nathan Laredo */
int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
static inline int saa7146_wait_for_debi_done_sleep(struct saa7146_dev *dev,
				unsigned long us1, unsigned long us2)
{
{
	unsigned long start;
	unsigned long timeout;
	int err;
	int err;


	/* wait for registers to be programmed */
	/* wait for registers to be programmed */
	start = jiffies;
	timeout = jiffies + usecs_to_jiffies(us1);
	while (1) {
	while (1) {
		err = time_after(jiffies, start + HZ/20);
		err = time_after(jiffies, timeout);
		if (saa7146_read(dev, MC2) & 2)
		if (saa7146_read(dev, MC2) & 2)
			break;
			break;
		if (err) {
		if (err) {
			DEB_S(("timed out while waiting for registers getting programmed\n"));
			printk(KERN_ERR "%s: %s timed out while waiting for "
					"registers getting programmed\n",
					dev->name, __FUNCTION__);
			return -ETIMEDOUT;
			return -ETIMEDOUT;
		}
		}
		if (nobusyloop)
		msleep(1);
		msleep(1);
	}
	}


	/* wait for transfer to complete */
	/* wait for transfer to complete */
	start = jiffies;
	timeout = jiffies + usecs_to_jiffies(us2);
	while (1) {
	while (1) {
		err = time_after(jiffies, start + HZ/4);
		err = time_after(jiffies, timeout);
		if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
		if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
			break;
			break;
		saa7146_read(dev, MC2);
		saa7146_read(dev, MC2);
		if (err) {
		if (err) {
			DEB_S(("timed out while waiting for transfer completion\n"));
			DEB_S(("%s: %s timed out while waiting for transfer "
				"completion\n",	dev->name, __FUNCTION__));
			return -ETIMEDOUT;
			return -ETIMEDOUT;
		}
		}
		if (nobusyloop)
		msleep(1);
		msleep(1);
	}
	}


	return 0;
	return 0;
}
}


static inline int saa7146_wait_for_debi_done_busyloop(struct saa7146_dev *dev,
				unsigned long us1, unsigned long us2)
{
	unsigned long loops;

	/* wait for registers to be programmed */
	loops = us1;
	while (1) {
		if (saa7146_read(dev, MC2) & 2)
			break;
		if (!loops--) {
			printk(KERN_ERR "%s: %s timed out while waiting for "
					"registers getting programmed\n",
					dev->name, __FUNCTION__);
			return -ETIMEDOUT;
		}
		udelay(1);
	}

	/* wait for transfer to complete */
	loops = us2 / 5;
	while (1) {
		if (!(saa7146_read(dev, PSR) & SPCI_DEBI_S))
			break;
		saa7146_read(dev, MC2);
		if (!loops--) {
			DEB_S(("%s: %s timed out while waiting for transfer "
				"completion\n", dev->name, __FUNCTION__));
			return -ETIMEDOUT;
		}
		udelay(5);
	}

	return 0;
}

int saa7146_wait_for_debi_done(struct saa7146_dev *dev, int nobusyloop)
{
	if (nobusyloop)
		return saa7146_wait_for_debi_done_sleep(dev, 50000, 250000);
	else
		return saa7146_wait_for_debi_done_busyloop(dev, 50000, 250000);
}

/****************************************************************************
/****************************************************************************
 * general helper functions
 * general helper functions
 ****************************************************************************/
 ****************************************************************************/
+1 −1
Original line number Original line Diff line number Diff line
@@ -116,7 +116,7 @@ static int mt2131_set_params(struct dvb_frontend *fe,
	f_lo1 = (f_lo1 / 250) * 250;
	f_lo1 = (f_lo1 / 250) * 250;
	f_lo2 = f_lo1 - freq - MT2131_IF2;
	f_lo2 = f_lo1 - freq - MT2131_IF2;


	priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000,
	priv->frequency =  (f_lo1 - f_lo2 - MT2131_IF2) * 1000;


	/* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
	/* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
	num1 = f_lo1 * 64 / (MT2131_FREF / 128);
	num1 = f_lo1 * 64 / (MT2131_FREF / 128);
+86 −10
Original line number Original line Diff line number Diff line
@@ -42,6 +42,9 @@ struct s5h1409_state {
	fe_modulation_t current_modulation;
	fe_modulation_t current_modulation;


	u32 current_frequency;
	u32 current_frequency;

	u32 is_qam_locked;
	u32 qam_state;
};
};


static int debug = 0;
static int debug = 0;
@@ -94,6 +97,7 @@ static struct init_tab {
	{ 0xac, 0x1003, },
	{ 0xac, 0x1003, },
	{ 0xad, 0x103f, },
	{ 0xad, 0x103f, },
	{ 0xe2, 0x0100, },
	{ 0xe2, 0x0100, },
	{ 0xe3, 0x0000, },
	{ 0x28, 0x1010, },
	{ 0x28, 0x1010, },
	{ 0xb1, 0x000e, },
	{ 0xb1, 0x000e, },
};
};
@@ -335,6 +339,8 @@ static int s5h1409_softreset(struct dvb_frontend* fe)


	s5h1409_writereg(state, 0xf5, 0);
	s5h1409_writereg(state, 0xf5, 0);
	s5h1409_writereg(state, 0xf5, 1);
	s5h1409_writereg(state, 0xf5, 1);
	state->is_qam_locked = 0;
	state->qam_state = 0;
	return 0;
	return 0;
}
}


@@ -349,6 +355,11 @@ static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz)
		s5h1409_writereg(state, 0x87, 0x01be);
		s5h1409_writereg(state, 0x87, 0x01be);
		s5h1409_writereg(state, 0x88, 0x0436);
		s5h1409_writereg(state, 0x88, 0x0436);
		s5h1409_writereg(state, 0x89, 0x054d);
		s5h1409_writereg(state, 0x89, 0x054d);
	} else
	if (KHz == 4000) {
		s5h1409_writereg(state, 0x87, 0x014b);
		s5h1409_writereg(state, 0x88, 0x0cb5);
		s5h1409_writereg(state, 0x89, 0x03e2);
	} else {
	} else {
		printk("%s() Invalid arg = %d KHz\n", __FUNCTION__, KHz);
		printk("%s() Invalid arg = %d KHz\n", __FUNCTION__, KHz);
		ret = -1;
		ret = -1;
@@ -361,7 +372,7 @@ static int s5h1409_set_spectralinversion(struct dvb_frontend* fe, int inverted)
{
{
	struct s5h1409_state* state = fe->demodulator_priv;
	struct s5h1409_state* state = fe->demodulator_priv;


	dprintk("%s()\n", __FUNCTION__);
	dprintk("%s(%d)\n", __FUNCTION__, inverted);


	if(inverted == 1)
	if(inverted == 1)
		return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
		return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
@@ -382,14 +393,10 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe,
		s5h1409_writereg(state, 0xf4, 0);
		s5h1409_writereg(state, 0xf4, 0);
		break;
		break;
	case QAM_64:
	case QAM_64:
		dprintk("%s() QAM_64\n", __FUNCTION__);
		s5h1409_writereg(state, 0xf4, 1);
		s5h1409_writereg(state, 0x85, 0x100);
		break;
	case QAM_256:
	case QAM_256:
		dprintk("%s() QAM_256\n", __FUNCTION__);
		dprintk("%s() QAM_AUTO (64/256)\n", __FUNCTION__);
		s5h1409_writereg(state, 0xf4, 1);
		s5h1409_writereg(state, 0xf4, 1);
		s5h1409_writereg(state, 0x85, 0x101);
		s5h1409_writereg(state, 0x85, 0x110);
		break;
		break;
	default:
	default:
		dprintk("%s() Invalid modulation\n", __FUNCTION__);
		dprintk("%s() Invalid modulation\n", __FUNCTION__);
@@ -423,7 +430,7 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable)
	if (enable)
	if (enable)
		return s5h1409_writereg(state, 0xe3, 0x1100);
		return s5h1409_writereg(state, 0xe3, 0x1100);
	else
	else
		return s5h1409_writereg(state, 0xe3, 0);
		return s5h1409_writereg(state, 0xe3, 0x1000);
}
}


static int s5h1409_sleep(struct dvb_frontend* fe, int enable)
static int s5h1409_sleep(struct dvb_frontend* fe, int enable)
@@ -444,6 +451,66 @@ static int s5h1409_register_reset(struct dvb_frontend* fe)
	return s5h1409_writereg(state, 0xfa, 0);
	return s5h1409_writereg(state, 0xfa, 0);
}
}


static void s5h1409_set_qam_amhum_mode(struct dvb_frontend *fe)
{
	struct s5h1409_state *state = fe->demodulator_priv;
	u16 reg;

	if (state->is_qam_locked)
		return;

	/* QAM EQ lock check */
	reg = s5h1409_readreg(state, 0xf0);

	if ((reg >> 13) & 0x1) {

		state->is_qam_locked = 1;
		reg &= 0xff;

		s5h1409_writereg(state, 0x96, 0x00c);
		if ((reg < 0x38) || (reg > 0x68) ) {
			s5h1409_writereg(state, 0x93, 0x3332);
			s5h1409_writereg(state, 0x9e, 0x2c37);
		} else {
			s5h1409_writereg(state, 0x93, 0x3130);
			s5h1409_writereg(state, 0x9e, 0x2836);
		}

	} else {
		s5h1409_writereg(state, 0x96, 0x0008);
		s5h1409_writereg(state, 0x93, 0x3332);
		s5h1409_writereg(state, 0x9e, 0x2c37);
	}
}

static void s5h1409_set_qam_interleave_mode(struct dvb_frontend *fe)
{
	struct s5h1409_state *state = fe->demodulator_priv;
	u16 reg, reg1, reg2;

	reg = s5h1409_readreg(state, 0xf1);

	/* Master lock */
	if ((reg >> 15) & 0x1) {
		if (state->qam_state != 2) {
			state->qam_state = 2;
			reg1 = s5h1409_readreg(state, 0xb2);
			reg2 = s5h1409_readreg(state, 0xad);

			s5h1409_writereg(state, 0x96, 0x20);
			s5h1409_writereg(state, 0xad,
				( ((reg1 & 0xf000) >> 4) | (reg2 & 0xf0ff)) );
			s5h1409_writereg(state, 0xab, 0x1100);
		}
	} else {
		if (state->qam_state != 1) {
			state->qam_state = 1;
			s5h1409_writereg(state, 0x96, 0x08);
			s5h1409_writereg(state, 0xab, 0x1101);
		}
	}
}

/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
static int s5h1409_set_frontend (struct dvb_frontend* fe,
static int s5h1409_set_frontend (struct dvb_frontend* fe,
				 struct dvb_frontend_parameters *p)
				 struct dvb_frontend_parameters *p)
@@ -458,12 +525,21 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe,


	s5h1409_enable_modulation(fe, p->u.vsb.modulation);
	s5h1409_enable_modulation(fe, p->u.vsb.modulation);


	/* Allow the demod to settle */
	msleep(100);

	if (fe->ops.tuner_ops.set_params) {
	if (fe->ops.tuner_ops.set_params) {
		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 1);
		fe->ops.tuner_ops.set_params(fe, p);
		fe->ops.tuner_ops.set_params(fe, p);
		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
		if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0);
	}
	}


	/* Optimize the demod for QAM */
	if (p->u.vsb.modulation != VSB_8) {
		s5h1409_set_qam_amhum_mode(fe);
		s5h1409_set_qam_interleave_mode(fe);
	}

	return 0;
	return 0;
}
}


@@ -495,8 +571,8 @@ static int s5h1409_init (struct dvb_frontend* fe)
	s5h1409_set_gpio(fe, state->config->gpio);
	s5h1409_set_gpio(fe, state->config->gpio);
	s5h1409_softreset(fe);
	s5h1409_softreset(fe);


	/* Note: Leaving the I2C gate open here. */
	/* Note: Leaving the I2C gate closed. */
	s5h1409_i2c_gate_ctrl(fe, 1);
	s5h1409_i2c_gate_ctrl(fe, 0);


	return 0;
	return 0;
}
}
Loading