public inbox for linux-media@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/2] Fitipower fc0011 driver
       [not found] <20120321160237.02193470@milhouse>
@ 2012-03-21 15:56 ` Michael Büsch
  2012-03-21 19:12   ` Gianluca Gennari
  2012-03-21 15:56 ` [PATCH 2/2] Integrate Fitipower fc0011 into af903x Michael Büsch
  1 sibling, 1 reply; 4+ messages in thread
From: Michael Büsch @ 2012-03-21 15:56 UTC (permalink / raw)
  To: Hans-Frieder Vogt; +Cc: linux-media

[-- Attachment #1: Type: text/plain, Size: 16564 bytes --]

This adds the Fitipower fc0011 tuner driver.

Note: The '#if 0' statements will be removed on the final submission.

Signed-off-by: Michael Buesch <m@bues.ch>

---

Index: linux-source-3.2/drivers/media/common/tuners/Kconfig
===================================================================
--- linux-source-3.2.orig/drivers/media/common/tuners/Kconfig	2012-03-21 15:43:23.658828874 +0100
+++ linux-source-3.2/drivers/media/common/tuners/Kconfig	2012-03-21 15:43:27.442894007 +0100
@@ -204,6 +204,13 @@
 	help
 	  NXP TDA18212 silicon tuner driver.
 
+config MEDIA_TUNER_FC0011
+	tristate "Fitipower FC0011 silicon tuner"
+	depends on VIDEO_MEDIA && I2C
+	default m if MEDIA_TUNER_CUSTOMISE
+	help
+	  Fitipower FC0011 silicon tuner driver.
+
 config MEDIA_TUNER_FC0012
 	tristate "Fitipower FC0012 silicon tuner"
 	depends on VIDEO_MEDIA && I2C
Index: linux-source-3.2/drivers/media/common/tuners/Makefile
===================================================================
--- linux-source-3.2.orig/drivers/media/common/tuners/Makefile	2012-03-21 15:43:23.658828874 +0100
+++ linux-source-3.2/drivers/media/common/tuners/Makefile	2012-03-21 15:43:27.446894082 +0100
@@ -27,6 +27,7 @@
 obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
 obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
 obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
+obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o
 obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o
 
 ccflags-y += -Idrivers/media/dvb/dvb-core
Index: linux-source-3.2/drivers/media/common/tuners/fc0011.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-source-3.2/drivers/media/common/tuners/fc0011.c	2012-03-21 15:52:28.048214689 +0100
@@ -0,0 +1,501 @@
+/*
+ * Fitipower FC0011 tuner driver
+ *
+ * Copyright (C) 2012 Michael Buesch <m@bues.ch>
+ *
+ * Derived from FC0012 tuner driver:
+ * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include "fc0011.h"
+
+
+/* Tuner registers */
+enum {
+	FC11_REG_0,
+	FC11_REG_FA,		/* FA */
+	FC11_REG_FP,		/* FP */
+	FC11_REG_XINHI,		/* XIN high 8 bit */
+	FC11_REG_XINLO,		/* XIN low 8 bit */
+	FC11_REG_VCO,		/* VCO */
+	FC11_REG_VCOSEL,	/* VCO select */
+	FC11_REG_7,		/* Unknown tune reg 7 */
+	FC11_REG_8,		/* Unknown tune reg 8 */
+	FC11_REG_9,
+	FC11_REG_10,		/* Unknown tune reg 10 */
+	FC11_REG_11,		/* Unknown tune reg 11 */
+	FC11_REG_12,
+	FC11_REG_RCCAL,		/* RC calibrate */
+	FC11_REG_VCOCAL,	/* VCO calibrate */
+	FC11_REG_15,
+	FC11_REG_16,		/* Unknown tune reg 16 */
+	FC11_REG_17,
+
+	FC11_NR_REGS,		/* Number of registers */
+};
+
+enum FC11_REG_VCOSEL_bits {
+	FC11_VCOSEL_2		= 0x08, /* VCO select 2 */
+	FC11_VCOSEL_1		= 0x10, /* VCO select 1 */
+	FC11_VCOSEL_CLKOUT	= 0x20, /* Fix clock out */
+	FC11_VCOSEL_BW7M	= 0x40, /* 7MHz bw */
+	FC11_VCOSEL_BW6M	= 0x80, /* 6MHz bw */
+};
+
+enum FC11_REG_RCCAL_bits {
+	FC11_RCCAL_FORCE	= 0x10, /* force */
+};
+
+enum FC11_REG_VCOCAL_bits {
+	FC11_VCOCAL_RUN		= 0,	/* VCO calibration run */
+	FC11_VCOCAL_VALUEMASK	= 0x3F,	/* VCO calibration value mask */
+	FC11_VCOCAL_OK		= 0x40,	/* VCO calibration Ok */
+	FC11_VCOCAL_RESET	= 0x80, /* VCO calibration reset */
+};
+
+
+struct fc0011_priv {
+	struct i2c_adapter *i2c;
+	u8 addr;
+
+	u32 frequency;
+	u32 bandwidth;
+
+	int (*tuner_reset)(void *data);
+	void *tuner_reset_data;
+};
+
+
+static int fc0011_writereg(struct fc0011_priv *priv, u8 reg, u8 val)
+{
+	u8 buf[2] = { reg, val };
+	struct i2c_msg msg = { .addr = priv->addr,
+		.flags = 0, .buf = buf, .len = 2 };
+
+	msleep(1);
+	if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+		dev_err(&priv->i2c->dev,
+			"I2C write reg failed, reg: %02x, val: %02x\n",
+			reg, val);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int fc0011_readreg(struct fc0011_priv *priv, u8 reg, u8 *val)
+{
+	struct i2c_msg msg[2] = {
+		{ .addr = priv->addr,
+		  .flags = 0, .buf = &reg, .len = 1 },
+		{ .addr = priv->addr,
+		  .flags = I2C_M_RD, .buf = val, .len = 1 },
+	};
+
+	if (i2c_transfer(priv->i2c, msg, 2) != 2) {
+		dev_err(&priv->i2c->dev,
+			"I2C read failed, reg: %02x\n", reg);
+		return -EIO;
+	}
+
+	return 0;
+}
+
+static int fc0011_release(struct dvb_frontend *fe)
+{
+	kfree(fe->tuner_priv);
+	fe->tuner_priv = NULL;
+
+	return 0;
+}
+
+static int fc0011_init(struct dvb_frontend *fe)
+{
+	/* nothing to do here */
+	return 0;
+}
+
+static int fc0011_sleep(struct dvb_frontend *fe)
+{
+	/* nothing to do here */
+	return 0;
+}
+
+#if 0 //TODO 3.3
+static int fc0011_set_params(struct dvb_frontend *fe)
+#else
+static int fc0011_set_params(struct dvb_frontend *fe,
+        struct dvb_frontend_parameters *params)
+#endif
+{
+        struct fc0011_priv *priv = fe->tuner_priv;
+	int err;
+	unsigned int i;
+#if 0 //TODO 3.3
+	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
+	u32 freq = p->frequency / 1000;
+	u32 delsys = p->delivery_system;
+	u32 bandwidth = p->bandwidth_hz / 1000;
+#else
+	u32 freq = params->frequency / 1000;
+	u32 bandwidth = params->u.ofdm.bandwidth / 1000;
+#endif
+	u32 fvco, xin, xdiv, xdivr;
+	u16 frac;
+	u8 fa, fp, vco_sel, vco_cal;
+	u8 regs[FC11_NR_REGS] = { };
+
+	regs[FC11_REG_7] = 0x0F;
+	regs[FC11_REG_8] = 0x3E;
+	regs[FC11_REG_10] = 0xB8;
+	regs[FC11_REG_11] = 0x80;
+	regs[FC11_REG_RCCAL] = 0x04;
+	err = fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
+	err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
+	err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
+	err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
+	err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
+	if (err)
+		return -EIO;
+
+	/* Set VCO freq and VCO div */
+	if (freq < 54000) {
+		fvco = freq * 64;
+		regs[FC11_REG_VCO] = 0x82;
+	} else if (freq < 108000) {
+		fvco = freq * 32;
+		regs[FC11_REG_VCO] = 0x42;
+	} else if (freq < 216000) {
+		fvco = freq * 16;
+		regs[FC11_REG_VCO] = 0x22;
+	} else if (freq < 432000) {
+		fvco = freq * 8;
+		regs[FC11_REG_VCO] = 0x12;
+	} else {
+		fvco = freq * 4;
+		regs[FC11_REG_VCO] = 0x0A;
+	}
+
+	/* Calc XIN. The PLL reference frequency is 18 MHz. */
+	xdiv = fvco / 18000;
+	frac = fvco - xdiv * 18000;
+	frac = (frac << 15) / 18000;
+	if (frac >= 16384)
+		frac += 32786;
+	if (!frac)
+		xin = 0;
+	else if (frac < 511)
+		xin = 512;
+	else if (frac < 65026)
+		xin = frac;
+	else
+		xin = 65024;
+	regs[FC11_REG_XINHI] = xin >> 8;
+	regs[FC11_REG_XINLO] = xin;
+
+	/* Calc FP and FA */
+	xdivr = xdiv;
+	if (fvco - xdiv * 18000 >= 9000)
+		xdivr += 1; /* round */
+	fp = xdivr / 8;
+	fa = xdivr - fp * 8;
+	if (fa < 2) {
+		fp -= 1;
+		fa += 8;
+	}
+	if (fp > 0x1F) {
+		fp &= 0x1F;
+		fa &= 0xF;
+	}
+	if (fa >= fp) {
+		dev_warn(&priv->i2c->dev,
+			 "fa %02X >= fp %02X, but trying to continue\n",
+			 (unsigned int)(u8)fa, (unsigned int)(u8)fp);
+	}
+	regs[FC11_REG_FA] = fa;
+	regs[FC11_REG_FP] = fp;
+
+	/* Select bandwidth */
+	switch (bandwidth) {
+	case 8000:
+		break;
+	case 7000:
+		regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW7M;
+		break;
+	default:
+	case 6000:
+		regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW6M;
+		break;
+	}
+
+	/* Pre VCO select */
+	if (fvco < 2320000) {
+		vco_sel = 0;
+		regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+	} else if (fvco < 3080000) {
+		vco_sel = 1;
+		regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+		regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
+	} else {
+		vco_sel = 2;
+		regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+		regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
+	}
+
+	/* Fix for low freqs */
+	if (freq < 45000) {
+		regs[FC11_REG_FA] = 0x6;
+		regs[FC11_REG_FP] = 0x11;
+	}
+
+	/* Clock out fix */
+	regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_CLKOUT;
+
+	/* Write the cached registers */
+	for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++) {
+		err = fc0011_writereg(priv, i, regs[i]);
+		if (err)
+			return err;
+	}
+
+	/* VCO calibration */
+	err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RESET);
+	if (err)
+		return err;
+	err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
+	if (err)
+		return err;
+	/* Read calib val */
+	err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
+	if (err)
+		return err;
+	msleep(10);
+	err = fc0011_readreg(priv, FC11_REG_VCOCAL, &vco_cal);
+	if (err)
+		return err;
+	if (!(vco_cal & FC11_VCOCAL_OK)) {
+		/* Reset the tuner and try again */
+		err = priv->tuner_reset(priv->tuner_reset_data);
+		if (err)
+			return -EIO;
+		/* Reinit tuner config */
+		err = 0;
+		for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++)
+			err |= fc0011_writereg(priv, i, regs[i]);
+		err |= fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
+		err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
+		err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
+		err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
+		err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
+		if (err)
+			return -EIO;
+		/* VCO calibration */
+		err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RESET);
+		if (err)
+			return err;
+		err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
+		if (err)
+			return err;
+		/* Read calib val */
+		err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
+		if (err)
+			return err;
+		msleep(10);
+		err = fc0011_readreg(priv, FC11_REG_VCOCAL, &vco_cal);
+		if (err)
+			return err;
+	}
+	if (!(vco_cal & FC11_VCOCAL_OK)) {
+		dev_err(&priv->i2c->dev, "Failed to read VCO calibration value\n");
+		return -EIO;
+	}
+	vco_cal &= FC11_VCOCAL_VALUEMASK;
+
+	switch (vco_sel) {
+	case 0:
+		if (vco_cal < 8) {
+			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+			regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
+			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+					      regs[FC11_REG_VCOSEL]);
+			err |= fc0011_writereg(priv, FC11_REG_VCOCAL,
+					       FC11_VCOCAL_RESET);
+			err |= fc0011_writereg(priv, FC11_REG_VCOCAL,
+					       FC11_VCOCAL_RUN);
+			if (err)
+				return -EIO;
+		} else {
+			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+					      regs[FC11_REG_VCOSEL]);
+			if (err)
+				return err;
+		}
+		break;
+	case 1:
+		if (vco_cal < 5) {
+			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+			regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
+			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+					      regs[FC11_REG_VCOSEL]);
+			err |= fc0011_writereg(priv, FC11_REG_VCOCAL,
+					       FC11_VCOCAL_RESET);
+			err |= fc0011_writereg(priv, FC11_REG_VCOCAL,
+					       FC11_VCOCAL_RUN);
+			if (err)
+				return -EIO;
+		} else if (vco_cal <= 48) {
+			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+			regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
+			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+					      regs[FC11_REG_VCOSEL]);
+			if (err)
+				return err;
+		} else {
+			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+					      regs[FC11_REG_VCOSEL]);
+			err |= fc0011_writereg(priv, FC11_REG_VCOCAL,
+					       FC11_VCOCAL_RESET);
+			err |= fc0011_writereg(priv, FC11_REG_VCOCAL,
+					       FC11_VCOCAL_RUN);
+			if (err)
+				return -EIO;
+		}
+		break;
+	case 2:
+		if (vco_cal > 53) {
+			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+			regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
+			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+					      regs[FC11_REG_VCOSEL]);
+			err |= fc0011_writereg(priv, FC11_REG_VCOCAL,
+					       FC11_VCOCAL_RESET);
+			err |= fc0011_writereg(priv, FC11_REG_VCOCAL,
+					       FC11_VCOCAL_RUN);
+			if (err)
+				return -EIO;
+		} else {
+			regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
+			regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
+			err = fc0011_writereg(priv, FC11_REG_VCOSEL,
+					      regs[FC11_REG_VCOSEL]);
+			if (err)
+				return err;
+		}
+		break;
+	}
+	err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
+	if (err)
+		return err;
+	msleep(10);
+	err = fc0011_readreg(priv, FC11_REG_VCOCAL, &vco_cal);
+	if (err)
+		return err;
+	msleep(10);
+
+	err = fc0011_readreg(priv, FC11_REG_RCCAL, &regs[FC11_REG_RCCAL]);
+	if (err)
+		return err;
+	regs[FC11_REG_RCCAL] |= FC11_RCCAL_FORCE;
+	err = fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
+	if (err)
+		return err;
+	err = fc0011_writereg(priv, FC11_REG_16, 0xB);
+	if (err)
+		return err;
+
+	priv->frequency = freq * 1000;
+	priv->bandwidth = bandwidth * 1000;
+
+	return 0;
+}
+
+static int fc0011_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+        struct fc0011_priv *priv = fe->tuner_priv;
+
+        *frequency = priv->frequency;
+
+        return 0;
+}
+
+static int fc0011_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+        *frequency = 0;
+
+        return 0;
+}
+
+static int fc0011_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+        struct fc0011_priv *priv = fe->tuner_priv;
+
+        *bandwidth = priv->bandwidth;
+
+        return 0;
+}
+
+static const struct dvb_tuner_ops fc0011_tuner_ops = {
+	.info = {
+		.name		= "Fitipower FC0011",
+
+		.frequency_min	= 45000000,
+		.frequency_max	= 1000000000,
+        },
+
+	.release		= fc0011_release,
+
+	.init			= fc0011_init,
+	.sleep			= fc0011_sleep,
+
+	.set_params		= fc0011_set_params,
+
+	.get_frequency		= fc0011_get_frequency,
+	.get_if_frequency	= fc0011_get_if_frequency,
+	.get_bandwidth		= fc0011_get_bandwidth,
+};
+
+struct dvb_frontend * fc0011_attach(struct dvb_frontend *fe,
+				    struct i2c_adapter *i2c,
+				    u8 i2c_address,
+				    int (*tuner_reset)(void *),
+				    void *tuner_reset_data)
+{
+	struct fc0011_priv *priv;
+
+	priv = kzalloc(sizeof(struct fc0011_priv), GFP_KERNEL);
+	if (!priv)
+		return NULL;
+
+	priv->i2c = i2c;
+	priv->addr = i2c_address;
+	priv->tuner_reset = tuner_reset;
+	priv->tuner_reset_data = tuner_reset_data;
+
+	fe->tuner_priv = priv;
+	fe->ops.tuner_ops = fc0011_tuner_ops;
+
+	dev_info(&priv->i2c->dev, "Fitipower FC0011 tuner attached\n");
+
+	return fe;
+}
+EXPORT_SYMBOL(fc0011_attach);
+
+MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver");
+MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
+MODULE_LICENSE("GPL");
Index: linux-source-3.2/drivers/media/common/tuners/fc0011.h
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ linux-source-3.2/drivers/media/common/tuners/fc0011.h	2012-03-21 15:43:27.450894145 +0100
@@ -0,0 +1,26 @@
+#ifndef LINUX_FC0011_H_
+#define LINUX_FC0011_H_
+
+#include "dvb_frontend.h"
+
+#if defined(CONFIG_MEDIA_TUNER_FC0011) ||\
+    defined(CONFIG_MEDIA_TUNER_FC0011_MODULE)
+struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
+				   struct i2c_adapter *i2c,
+				   u8 i2c_address,
+				   int (*tuner_reset)(void *),
+				   void *tuner_reset_data);
+#else
+static inline
+struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
+				   struct i2c_adapter *i2c,
+				   u8 i2c_address,
+				   int (*tuner_reset)(void *),
+				   void *tuner_reset_data)
+{
+	dev_err(&i2c->dev, "fc0011 driver disabled in Kconfig\n");
+	return NULL;
+}
+#endif
+
+#endif /* LINUX_FC0011_H_ */


-- 
Greetings, Michael.

PGP encryption is encouraged / 908D8B0E

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 2/2] Integrate Fitipower fc0011 into af903x
       [not found] <20120321160237.02193470@milhouse>
  2012-03-21 15:56 ` [PATCH 1/2] Fitipower fc0011 driver Michael Büsch
@ 2012-03-21 15:56 ` Michael Büsch
  1 sibling, 0 replies; 4+ messages in thread
From: Michael Büsch @ 2012-03-21 15:56 UTC (permalink / raw)
  To: Hans-Frieder Vogt; +Cc: linux-media

[-- Attachment #1: Type: text/plain, Size: 5282 bytes --]

This adds fc0011 support to the af903x driver.

Signed-off-by: Michael Buesch <m@bues.ch>

---


Index: linux-source-3.2/drivers/media/dvb/dvb-usb/Kconfig
===================================================================
--- linux-source-3.2.orig/drivers/media/dvb/dvb-usb/Kconfig	2012-03-20 22:48:14.025859279 +0100
+++ linux-source-3.2/drivers/media/dvb/dvb-usb/Kconfig	2012-03-21 15:31:43.266801632 +0100
@@ -342,6 +342,7 @@
 config DVB_USB_AF903X
 	tristate "Afatech AF903X DVB-T USB2.0 support"
 	depends on DVB_USB && EXPERIMENTAL
+	select MEDIA_TUNER_FC0011   if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_FC0012   if !MEDIA_TUNER_CUSTOMISE
 	select MEDIA_TUNER_MXL5007T if !MEDIA_TUNER_CUSTOMISE
 	help
Index: linux-source-3.2/drivers/media/dvb/dvb-usb/af903x-devices.c
===================================================================
--- linux-source-3.2.orig/drivers/media/dvb/dvb-usb/af903x-devices.c	2012-03-20 22:48:14.025859279 +0100
+++ linux-source-3.2/drivers/media/dvb/dvb-usb/af903x-devices.c	2012-03-21 15:31:43.270801692 +0100
@@ -260,6 +260,7 @@
 }
 
 extern struct tuner_desc tuner_af9007;
+extern struct tuner_desc tuner_fc0011;
 extern struct tuner_desc tuner_fc0012;
 extern struct tuner_desc tuner_mxl5007t;
 
@@ -273,6 +274,9 @@
 	case TUNER_AF9007:
 		ctx->tuner_desc = &tuner_af9007;
 		break;
+	case TUNER_FC0011:
+		ctx->tuner_desc = &tuner_fc0011;
+		break;
 	case TUNER_FC0012:
 		ctx->tuner_desc = &tuner_fc0012;
 		break;
Index: linux-source-3.2/drivers/media/dvb/dvb-usb/af903x-fe.c
===================================================================
--- linux-source-3.2.orig/drivers/media/dvb/dvb-usb/af903x-fe.c	2012-03-20 22:48:14.025859279 +0100
+++ linux-source-3.2/drivers/media/dvb/dvb-usb/af903x-fe.c	2012-03-21 15:37:04.968319280 +0100
@@ -28,6 +28,7 @@
 #include "af903x-fe.h"
 #include "af903x-fe-priv.h"
 #include "dvb_frontend.h"
+#include "fc0011.h"
 #include "fc0012.h"
 #include "mxl5007t.h"
 
@@ -1967,6 +1968,8 @@
 	}
 };
 
+extern int af903x_fc0011_reset(void *_ctx);
+
 static struct dvb_frontend_ops af903x_ops;
 struct dvb_frontend *af903x_fe_attach(struct i2c_adapter *i2c_adap, int id,
 	struct af903x_dev_ctx *ctx)
@@ -1990,6 +1993,13 @@
 	switch(ctx->tuner_desc->tunerId) {
 	case TUNER_AF9007:
 		break;
+	case TUNER_FC0011:
+		ret = dvb_attach(fc0011_attach, frontend, i2c_adap,
+			id == 0 ? ctx->tuner_desc->tuner_addr :
+			ctx->tuner_desc->tuner_addr + 1,
+			af903x_fc0011_reset, ctx)
+			== NULL ?  -ENODEV : 0;
+		break;
 	case TUNER_FC0012:
 		ret = dvb_attach(fc0012_attach, frontend, i2c_adap,
 			id == 0 ? ctx->tuner_desc->tuner_addr :
Index: linux-source-3.2/drivers/media/dvb/dvb-usb/af903x-tuners.c
===================================================================
--- linux-source-3.2.orig/drivers/media/dvb/dvb-usb/af903x-tuners.c	2012-03-20 22:48:14.025859279 +0100
+++ linux-source-3.2/drivers/media/dvb/dvb-usb/af903x-tuners.c	2012-03-21 15:42:42.214115654 +0100
@@ -189,6 +189,69 @@
 	{0xf1e6, 0x00},
 };
 
+static u16 fc0011_script_sets[] = {
+	0x38,
+};
+
+static struct af903x_val_set fc0011_scripts[] = {
+	{0x0046, 0x28}, /* TUNER_ID */
+	{0x0057, 0x00},
+	{0x0058, 0x01},
+	{0x005f, 0x00},
+	{0x0060, 0x00},
+	{0x0068, 0xa5},
+	{0x006e, 0x01},
+	{0x0071, 0x0A},
+	{0x0072, 0x02},
+	{0x0074, 0x01},
+	{0x0079, 0x01},
+	{0x0093, 0x00},
+	{0x0094, 0x00},
+	{0x0095, 0x00},
+	{0x0096, 0x00},
+	{0x009b, 0x2D},
+	{0x009c, 0x60},
+	{0x009d, 0x23},
+	{0x00a4, 0x50},
+	{0x00ad, 0x50},
+	{0x00b3, 0x01},
+	{0x00b7, 0x88},
+	{0x00b8, 0xa6},
+	{0x00c3, 0x01},
+	{0x00c4, 0x01},
+	{0x00c7, 0x69},
+	{0xF007, 0x00},
+	{0xF00A, 0x1B},
+	{0xF00B, 0x1B},
+	{0xF00C, 0x1B},
+	{0xF00D, 0x1B},
+	{0xF00E, 0xFF},
+	{0xF00F, 0x01},
+	{0xF010, 0x00},
+	{0xF011, 0x02},
+	{0xF012, 0xFF},
+	{0xF013, 0x01},
+	{0xF014, 0x00},
+	{0xF015, 0x02},
+	{0xF01B, 0xEF},
+	{0xF01C, 0x01},
+	{0xF01D, 0x0f},
+	{0xF01E, 0x02},
+	{0xF01F, 0x6E},
+	{0xF020, 0x00},
+	{0xF025, 0xDE},
+	{0xF026, 0x00},
+	{0xF027, 0x0A},
+	{0xF028, 0x03},
+	{0xF029, 0x6E},
+	{0xF02A, 0x00},
+	{0xF047, 0x00},
+	{0xF054, 0x0},
+	{0xF055, 0x0},
+	{0xF077, 0x01},
+	{0xF1E6, 0x00},
+};
+
 static int af903x_fc0012_init(struct af903x_dev_ctx *ctx, int chip)
 {
 	int ret;
@@ -338,6 +401,43 @@
 	TUNER_FC0012,
 };
 
+int af903x_fc0011_reset(void *_ctx)
+{
+	struct af903x_dev_ctx *ctx = _ctx;
+	struct usb_device *udev = ctx->udev;
+	int ret;
+
+	ret = af9035_wr_reg(udev, 0, PRO_LINK, GPIOT3_ON, 1);
+	if (ret < 0)
+		return ret;
+	ret = af9035_wr_reg(udev, 0, PRO_LINK, GPIOT3_EN, 1);
+	if (ret < 0)
+		return ret;
+	ret = af9035_wr_reg(udev, 0, PRO_LINK, GPIOT3_O, 1);
+	if (ret < 0)
+		return ret;
+	msleep(10);
+	ret = af9035_wr_reg(udev, 0, PRO_LINK, GPIOT3_O, 0);
+	if (ret < 0)
+		return ret;
+	msleep(10);
+
+	return 0;
+}
+
+struct tuner_desc tuner_fc0011 = {
+	af903x_fc0012_init,
+	af903x_fc0012_sleep,
+	af903x_fc0012_set,
+	fc0011_scripts,
+	fc0011_script_sets,
+	0xc0,
+	1,
+	0,
+	true,
+	TUNER_FC0011,
+};
+
 static u16 mxl5007t_script_sets[] = {
 	0x1e
 };


-- 
Greetings, Michael.

PGP encryption is encouraged / 908D8B0E

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] Fitipower fc0011 driver
  2012-03-21 15:56 ` [PATCH 1/2] Fitipower fc0011 driver Michael Büsch
@ 2012-03-21 19:12   ` Gianluca Gennari
  2012-03-21 20:09     ` Michael Büsch
  0 siblings, 1 reply; 4+ messages in thread
From: Gianluca Gennari @ 2012-03-21 19:12 UTC (permalink / raw)
  To: Michael Büsch; +Cc: Hans-Frieder Vogt, linux-media

Il 21/03/2012 16:56, Michael Büsch ha scritto:
> This adds the Fitipower fc0011 tuner driver.
> 
> Note: The '#if 0' statements will be removed on the final submission.
> 
> Signed-off-by: Michael Buesch <m@bues.ch>
> 
> ---

......

> +
> +#if 0 //TODO 3.3
> +static int fc0011_set_params(struct dvb_frontend *fe)
> +#else
> +static int fc0011_set_params(struct dvb_frontend *fe,
> +        struct dvb_frontend_parameters *params)
> +#endif
> +{
> +        struct fc0011_priv *priv = fe->tuner_priv;
> +	int err;
> +	unsigned int i;
> +#if 0 //TODO 3.3
> +	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
> +	u32 freq = p->frequency / 1000;
> +	u32 delsys = p->delivery_system;

The "delsys" variable is unused, you can delete it.

BTW, I only compiled the driver, as I don't have the hardware to test it.

Regards,
Gianluca


> +	u32 bandwidth = p->bandwidth_hz / 1000;
> +#else
> +	u32 freq = params->frequency / 1000;
> +	u32 bandwidth = params->u.ofdm.bandwidth / 1000;
> +#endif

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/2] Fitipower fc0011 driver
  2012-03-21 19:12   ` Gianluca Gennari
@ 2012-03-21 20:09     ` Michael Büsch
  0 siblings, 0 replies; 4+ messages in thread
From: Michael Büsch @ 2012-03-21 20:09 UTC (permalink / raw)
  To: gennarone; +Cc: Hans-Frieder Vogt, linux-media

[-- Attachment #1: Type: text/plain, Size: 426 bytes --]

On Wed, 21 Mar 2012 20:12:03 +0100
Gianluca Gennari <gennarone@gmail.com> wrote:

> > +#if 0 //TODO 3.3
> > +	struct dtv_frontend_properties *p = &fe->dtv_property_cache;
> > +	u32 freq = p->frequency / 1000;
> > +	u32 delsys = p->delivery_system;
> 
> The "delsys" variable is unused, you can delete it.

Thanks for your review. I fixed this.

-- 
Greetings, Michael.

PGP encryption is encouraged / 908D8B0E

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 836 bytes --]

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2012-03-21 20:09 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <20120321160237.02193470@milhouse>
2012-03-21 15:56 ` [PATCH 1/2] Fitipower fc0011 driver Michael Büsch
2012-03-21 19:12   ` Gianluca Gennari
2012-03-21 20:09     ` Michael Büsch
2012-03-21 15:56 ` [PATCH 2/2] Integrate Fitipower fc0011 into af903x Michael Büsch

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox