V4L/DVB (5544): Budget-av: Make inversion setting configurable, add KNC ONE V1.0 card

Make the inversion setting configurable. The KNC ONE V1.0 uses
non inverted setting for the inversion and add the KNC ONE V1.0 card.

Signed-off-by: Hartmut Birr <e9hack@googlemail.com>
Signed-off-by: Oliver Endriss <o.endriss@gmx.de>
Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 304f1f9..1105368 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -53,9 +53,6 @@
 static int verbose;
 
 #define XIN 57840000UL
-#define DISABLE_INVERSION(reg0)		do { reg0 |= 0x20; } while (0)
-#define ENABLE_INVERSION(reg0)		do { reg0 &= ~0x20; } while (0)
-#define HAS_INVERSION(reg0)		(!(reg0 & 0x20))
 
 #define FIN (XIN >> 4)
 
@@ -97,7 +94,8 @@
 	int ret;
 
 	ret = i2c_transfer (state->i2c, msg, 2);
-	if (ret != 2)
+	// Don't print an error message if the id is read.
+	if (ret != 2 && reg != 0x1a)
 		printk("DVB: TDA10021: %s: readreg error (ret == %i)\n",
 				__FUNCTION__, ret);
 	return b1[0];
@@ -136,10 +134,10 @@
 {
 	reg0 |= state->reg0 & 0x63;
 
-	if (INVERSION_ON == inversion)
-		ENABLE_INVERSION(reg0);
-	else if (INVERSION_OFF == inversion)
-		DISABLE_INVERSION(reg0);
+	if ((INVERSION_ON == inversion) ^ (state->config->invert == 0))
+		reg0 &= ~0x20;
+	else
+		reg0 |= 0x20;
 
 	_tda10021_writereg (state, 0x00, reg0 & 0xfe);
 	_tda10021_writereg (state, 0x00, reg0 | 0x01);
@@ -248,6 +246,9 @@
 	if (qam < 0 || qam > 5)
 		return -EINVAL;
 
+	if (p->inversion != INVERSION_ON && p->inversion != INVERSION_OFF)
+		return -EINVAL;
+
 	//printk("tda10021: set frequency to %d qam=%d symrate=%d\n", p->frequency,qam,p->u.qam.symbol_rate);
 
 	if (fe->ops.tuner_ops.set_params) {
@@ -356,7 +357,7 @@
 		       -((s32)p->u.qam.symbol_rate * afc) >> 10);
 	}
 
-	p->inversion = HAS_INVERSION(state->reg0) ? INVERSION_ON : INVERSION_OFF;
+	p->inversion = ((state->reg0 & 0x20) == 0x20) ^ (state->config->invert != 0) ? INVERSION_ON : INVERSION_OFF;
 	p->u.qam.modulation = ((state->reg0 >> 2) & 7) + QAM_16;
 
 	p->u.qam.fec_inner = FEC_NONE;
@@ -403,6 +404,7 @@
 				     u8 pwm)
 {
 	struct tda10021_state* state = NULL;
+	u8 id;
 
 	/* allocate memory for the internal state */
 	state = kmalloc(sizeof(struct tda10021_state), GFP_KERNEL);
@@ -415,7 +417,11 @@
 	state->reg0 = tda10021_inittab[0];
 
 	/* check if the demod is there */
-	if ((tda10021_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
+	id = tda10021_readreg(state, 0x1a);
+	if ((id & 0xf0) != 0x70) goto error;
+
+	printk("TDA10021: i2c-addr = 0x%02x, id = 0x%02x\n",
+	       state->config->demod_address, id);
 
 	/* create dvb_frontend */
 	memcpy(&state->frontend.ops, &tda10021_ops, sizeof(struct dvb_frontend_ops));
diff --git a/drivers/media/dvb/frontends/tda1002x.h b/drivers/media/dvb/frontends/tda1002x.h
index 4849359..e9094d8 100644
--- a/drivers/media/dvb/frontends/tda1002x.h
+++ b/drivers/media/dvb/frontends/tda1002x.h
@@ -30,6 +30,7 @@
 {
 	/* the demodulator's i2c address */
 	u8 demod_address;
+	u8 invert;
 };
 
 #if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
diff --git a/drivers/media/dvb/ttpci/budget-av.c b/drivers/media/dvb/ttpci/budget-av.c
index 5680aa5..0e817d6 100644
--- a/drivers/media/dvb/ttpci/budget-av.c
+++ b/drivers/media/dvb/ttpci/budget-av.c
@@ -659,10 +659,12 @@
 
 static struct tda1002x_config philips_cu1216_config = {
 	.demod_address = 0x0c,
+	.invert = 1,
 };
 
 static struct tda1002x_config philips_cu1216_config_altaddress = {
 	.demod_address = 0x0d,
+	.invert = 0,
 };
 
 static int philips_tu1216_tuner_init(struct dvb_frontend *fe)