The patch number 10454 was added via Mauro Carvalho Chehab <mche...@redhat.com>
to http://linuxtv.org/hg/v4l-dvb master development tree.

Kernel patches in this development tree may be modified to be backward
compatible with older kernels. Compatibility modifications will be
removed before inclusion into the mainstream Kernel

If anyone has any objections, please let us know by sending a message to:
        Linux Media Mailing List <linux-me...@vger.kernel.org>

------

From: Mauro Carvalho Chehab  <mche...@redhat.com>
merge: http://linuxtv.org/hg/~anttip/mc44s803/


Signed-off-by: Mauro Carvalho Chehab <mche...@redhat.com>


---

 linux/drivers/media/common/tuners/Kconfig         |    8 
 linux/drivers/media/common/tuners/Makefile        |    1 
 linux/drivers/media/common/tuners/mc44s803.c      |  371 ++++++++++++++
 linux/drivers/media/common/tuners/mc44s803.h      |   46 +
 linux/drivers/media/common/tuners/mc44s803_priv.h |  208 +++++++
 linux/drivers/media/dvb/dvb-usb/Kconfig           |    1 
 linux/drivers/media/dvb/dvb-usb/af9015.c          |   40 +
 7 files changed, 662 insertions(+), 13 deletions(-)

diff -r 18c79168ec6c -r 40d6f7e3a34e linux/drivers/media/common/tuners/Kconfig
--- a/linux/drivers/media/common/tuners/Kconfig Mon Feb 09 15:38:11 2009 -0200
+++ b/linux/drivers/media/common/tuners/Kconfig Mon Feb 09 15:44:51 2009 -0200
@@ -29,6 +29,7 @@ config MEDIA_TUNER
        select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMIZE
        select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMIZE
        select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMIZE
+       select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMIZE
 
 menuconfig MEDIA_TUNER_CUSTOMIZE
        bool "Customize analog and hybrid tuner modules to build"
@@ -164,4 +165,11 @@ config MEDIA_TUNER_MXL5007T
        help
          A driver for the silicon tuner MxL5007T from MaxLinear.
 
+config MEDIA_TUNER_MC44S803
+       tristate "Freescale MC44S803 Low Power CMOS Broadband tuners"
+       depends on VIDEO_MEDIA && I2C
+       default m if DVB_FE_CUSTOMISE
+       help
+         Say Y here to support the Freescale MC44S803 based tuners
+
 endif # MEDIA_TUNER_CUSTOMIZE
diff -r 18c79168ec6c -r 40d6f7e3a34e linux/drivers/media/common/tuners/Makefile
--- a/linux/drivers/media/common/tuners/Makefile        Mon Feb 09 15:38:11 
2009 -0200
+++ b/linux/drivers/media/common/tuners/Makefile        Mon Feb 09 15:44:51 
2009 -0200
@@ -22,6 +22,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt21
 obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
 obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
 obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
+obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
 
 EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
 EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff -r 18c79168ec6c -r 40d6f7e3a34e 
linux/drivers/media/common/tuners/mc44s803.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/linux/drivers/media/common/tuners/mc44s803.c      Mon Feb 09 15:44:51 
2009 -0200
@@ -0,0 +1,371 @@
+/*
+ *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ *  Copyright (c) 2009 Jochen Friedrich <joc...@scram.de>
+ *
+ *  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 <linux/module.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "mc44s803.h"
+#include "mc44s803_priv.h"
+
+#define mc_printk(level, format, arg...)       \
+       printk(level "mc44s803: " format , ## arg)
+
+/* Writes a single register */
+static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val)
+{
+       u8 buf[3];
+       struct i2c_msg msg = {
+               .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3
+       };
+
+       buf[0] = (val & 0xff0000) >> 16;
+       buf[1] = (val & 0xff00) >> 8;
+       buf[2] = (val & 0xff);
+
+       if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
+               mc_printk(KERN_WARNING, "I2C write failed\n");
+               return -EREMOTEIO;
+       }
+       return 0;
+}
+
+/* Reads a single register */
+static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val)
+{
+       u32 wval;
+       u8 buf[3];
+       int ret;
+       struct i2c_msg msg[] = {
+               { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
+                 .buf = buf, .len = 3 },
+       };
+
+       wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) |
+              MC44S803_REG_SM(reg, MC44S803_D);
+
+       ret = mc44s803_writereg(priv, wval);
+       if (ret)
+               return ret;
+
+       if (i2c_transfer(priv->i2c, msg, 1) != 1) {
+               mc_printk(KERN_WARNING, "I2C read failed\n");
+               return -EREMOTEIO;
+       }
+
+       *val = (buf[0] << 16) | (buf[1] << 8) | buf[2];
+
+       return 0;
+}
+
+static int mc44s803_release(struct dvb_frontend *fe)
+{
+       struct mc44s803_priv *priv = fe->tuner_priv;
+
+       fe->tuner_priv = NULL;
+       kfree(priv);
+
+       return 0;
+}
+
+static int mc44s803_init(struct dvb_frontend *fe)
+{
+       struct mc44s803_priv *priv = fe->tuner_priv;
+       u32 val;
+       int err;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+/* Reset chip */
+       val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_RS);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+/* Power Up and Start Osc */
+
+       val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+             MC44S803_REG_SM(0xC0, MC44S803_REFOSC) |
+             MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) |
+             MC44S803_REG_SM(0x200, MC44S803_POWER);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       msleep(10);
+
+       val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
+             MC44S803_REG_SM(0x40, MC44S803_REFOSC) |
+             MC44S803_REG_SM(1, MC44S803_OSCSEL);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       msleep(20);
+
+/* Setup Mixer */
+
+       val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_TRI_STATE) |
+             MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+/* Setup Cirquit Adjust */
+
+       val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_G1) |
+             MC44S803_REG_SM(1, MC44S803_G3) |
+             MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+             MC44S803_REG_SM(1, MC44S803_G6) |
+             MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+             MC44S803_REG_SM(0x3, MC44S803_LP) |
+             MC44S803_REG_SM(1, MC44S803_CLRF) |
+             MC44S803_REG_SM(1, MC44S803_CLIF);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_G1) |
+             MC44S803_REG_SM(1, MC44S803_G3) |
+             MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
+             MC44S803_REG_SM(1, MC44S803_G6) |
+             MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
+             MC44S803_REG_SM(0x3, MC44S803_LP);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+/* Setup Digtune */
+
+       val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+             MC44S803_REG_SM(3, MC44S803_XOD);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+/* Setup AGC */
+
+       val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_AT1) |
+             MC44S803_REG_SM(1, MC44S803_AT2) |
+             MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) |
+             MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) |
+             MC44S803_REG_SM(1, MC44S803_LNA0);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+       return 0;
+
+exit:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       mc_printk(KERN_WARNING, "I/O Error\n");
+       return err;
+}
+
+static int mc44s803_set_params(struct dvb_frontend *fe,
+                              struct dvb_frontend_parameters *params)
+{
+       struct mc44s803_priv *priv = fe->tuner_priv;
+       u32 r1, r2, n1, n2, lo1, lo2, freq, val;
+       int err;
+
+       priv->frequency = params->frequency;
+
+       r1 = MC44S803_OSC / 1000000;
+       r2 = MC44S803_OSC /  100000;
+
+       n1 = (params->frequency + MC44S803_IF1 + 500000) / 1000000;
+       freq = MC44S803_OSC / r1 * n1;
+       lo1 = ((60 * n1) + (r1 / 2)) / r1;
+       freq = freq - params->frequency;
+
+       n2 = (freq - MC44S803_IF2 + 50000) / 100000;
+       lo2 = ((60 * n2) + (r2 / 2)) / r2;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1);
+
+       val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) |
+             MC44S803_REG_SM(r1-1, MC44S803_R1) |
+             MC44S803_REG_SM(r2-1, MC44S803_R2) |
+             MC44S803_REG_SM(1, MC44S803_REFBUF_EN);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) |
+             MC44S803_REG_SM(n1-2, MC44S803_LO1);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) |
+             MC44S803_REG_SM(n2-2, MC44S803_LO2);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+             MC44S803_REG_SM(1, MC44S803_DA) |
+             MC44S803_REG_SM(lo1, MC44S803_LO_REF) |
+             MC44S803_REG_SM(1, MC44S803_AT);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
+             MC44S803_REG_SM(2, MC44S803_DA) |
+             MC44S803_REG_SM(lo2, MC44S803_LO_REF) |
+             MC44S803_REG_SM(1, MC44S803_AT);
+
+       err = mc44s803_writereg(priv, val);
+       if (err)
+               goto exit;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       return 0;
+
+exit:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0);
+
+       mc_printk(KERN_WARNING, "I/O Error\n");
+       return err;
+}
+
+static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+       struct mc44s803_priv *priv = fe->tuner_priv;
+       *frequency = priv->frequency;
+       return 0;
+}
+
+static const struct dvb_tuner_ops mc44s803_tuner_ops = {
+       .info = {
+               .name           = "Freescale MC44S803",
+               .frequency_min  =   48000000,
+               .frequency_max  = 1000000000,
+               .frequency_step =     100000,
+       },
+
+       .release       = mc44s803_release,
+       .init          = mc44s803_init,
+       .set_params    = mc44s803_set_params,
+       .get_frequency = mc44s803_get_frequency
+};
+
+/* This functions tries to identify a MC44S803 tuner by reading the ID
+   register. This is hasty. */
+struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+        struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+       struct mc44s803_priv *priv;
+       u32 reg;
+       u8 id;
+       int ret;
+
+       reg = 0;
+
+       priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL);
+       if (priv == NULL)
+               return NULL;
+
+       priv->cfg = cfg;
+       priv->i2c = i2c;
+       priv->fe  = fe;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
+
+       ret = mc44s803_readreg(priv, MC44S803_REG_ID, &reg);
+       if (ret)
+               goto error;
+
+       id = MC44S803_REG_MS(reg, MC44S803_ID);
+
+       if (id != 0x14) {
+               mc_printk(KERN_ERR, "unsupported ID "
+                      "(%x should be 0x14)\n", id);
+               goto error;
+       }
+
+       mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id);
+       memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops,
+              sizeof(struct dvb_tuner_ops));
+
+       fe->tuner_priv = priv;
+
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       return fe;
+
+error:
+       if (fe->ops.i2c_gate_ctrl)
+               fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
+
+       kfree(priv);
+       return NULL;
+}
+EXPORT_SYMBOL(mc44s803_attach);
+
+MODULE_AUTHOR("Jochen Friedrich");
+MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver");
+MODULE_LICENSE("GPL");
diff -r 18c79168ec6c -r 40d6f7e3a34e 
linux/drivers/media/common/tuners/mc44s803.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/linux/drivers/media/common/tuners/mc44s803.h      Mon Feb 09 15:44:51 
2009 -0200
@@ -0,0 +1,46 @@
+/*
+ *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ *  Copyright (c) 2009 Jochen Friedrich <joc...@scram.de>
+ *
+ *  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.=
+ */
+
+#ifndef MC44S803_H
+#define MC44S803_H
+
+struct dvb_frontend;
+struct i2c_adapter;
+
+struct mc44s803_config {
+       u8 i2c_address;
+       u8 dig_out;
+};
+
+#if defined(CONFIG_MEDIA_TUNER_MC44S803) || \
+    (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE))
+extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+        struct i2c_adapter *i2c, struct mc44s803_config *cfg);
+#else
+static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
+        struct i2c_adapter *i2c, struct mc44s803_config *cfg)
+{
+       printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+       return NULL;
+}
+#endif /* CONFIG_MEDIA_TUNER_MC44S803 */
+
+#endif
diff -r 18c79168ec6c -r 40d6f7e3a34e 
linux/drivers/media/common/tuners/mc44s803_priv.h
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/linux/drivers/media/common/tuners/mc44s803_priv.h Mon Feb 09 15:44:51 
2009 -0200
@@ -0,0 +1,208 @@
+/*
+ *  Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
+ *
+ *  Copyright (c) 2009 Jochen Friedrich <joc...@scram.de>
+ *
+ *  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.=
+ */
+
+#ifndef MC44S803_PRIV_H
+#define MC44S803_PRIV_H
+
+/* This driver is based on the information available in the datasheet
+   http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf
+
+   SPI or I2C Address : 0xc0-0xc6
+
+   Reg.No | Function
+   -------------------------------------------
+       00 | Power Down
+       01 | Reference Oszillator
+       02 | Reference Dividers
+       03 | Mixer and Reference Buffer
+       04 | Reset/Serial Out
+       05 | LO 1
+       06 | LO 2
+       07 | Circuit Adjust
+       08 | Test
+       09 | Digital Tune
+       0A | LNA AGC
+       0B | Data Register Address
+       0C | Regulator Test
+       0D | VCO Test
+       0E | LNA Gain/Input Power
+       0F | ID Bits
+
+*/
+
+#define MC44S803_OSC 26000000  /* 26 MHz */
+#define MC44S803_IF1 1086000000 /* 1086 MHz */
+#define MC44S803_IF2 36125000  /* 36.125 MHz */
+
+#define MC44S803_REG_POWER     0
+#define MC44S803_REG_REFOSC    1
+#define MC44S803_REG_REFDIV    2
+#define MC44S803_REG_MIXER     3
+#define MC44S803_REG_RESET     4
+#define MC44S803_REG_LO1       5
+#define MC44S803_REG_LO2       6
+#define MC44S803_REG_CIRCADJ   7
+#define MC44S803_REG_TEST      8
+#define MC44S803_REG_DIGTUNE   9
+#define MC44S803_REG_LNAAGC    0x0A
+#define MC44S803_REG_DATAREG   0x0B
+#define MC44S803_REG_REGTEST   0x0C
+#define MC44S803_REG_VCOTEST   0x0D
+#define MC44S803_REG_LNAGAIN   0x0E
+#define MC44S803_REG_ID                0x0F
+
+/* Register definitions */
+#define MC44S803_ADDR          0x0F
+#define MC44S803_ADDR_S                0
+/* REG_POWER */
+#define MC44S803_POWER         0xFFFFF0
+#define MC44S803_POWER_S       4
+/* REG_REFOSC */
+#define MC44S803_REFOSC                0x1FF0
+#define MC44S803_REFOSC_S      4
+#define MC44S803_OSCSEL                0x2000
+#define MC44S803_OSCSEL_S      13
+/* REG_REFDIV */
+#define MC44S803_R2            0x1FF0
+#define MC44S803_R2_S          4
+#define MC44S803_REFBUF_EN     0x2000
+#define MC44S803_REFBUF_EN_S   13
+#define MC44S803_R1            0x7C000
+#define MC44S803_R1_S          14
+/* REG_MIXER */
+#define MC44S803_R3            0x70
+#define MC44S803_R3_S          4
+#define MC44S803_MUX3          0x80
+#define MC44S803_MUX3_S                7
+#define MC44S803_MUX4          0x100
+#define MC44S803_MUX4_S                8
+#define MC44S803_OSC_SCR       0x200
+#define MC44S803_OSC_SCR_S     9
+#define MC44S803_TRI_STATE     0x400
+#define MC44S803_TRI_STATE_S   10
+#define MC44S803_BUF_GAIN      0x800
+#define MC44S803_BUF_GAIN_S    11
+#define MC44S803_BUF_IO                0x1000
+#define MC44S803_BUF_IO_S      12
+#define MC44S803_MIXER_RES     0xFE000
+#define MC44S803_MIXER_RES_S   13
+/* REG_RESET */
+#define MC44S803_RS            0x10
+#define MC44S803_RS_S          4
+#define MC44S803_SO            0x20
+#define MC44S803_SO_S          5
+/* REG_LO1 */
+#define MC44S803_LO1           0xFFF0
+#define MC44S803_LO1_S         4
+/* REG_LO2 */
+#define MC44S803_LO2           0x7FFF0
+#define MC44S803_LO2_S         4
+/* REG_CIRCADJ */
+#define MC44S803_G1            0x20
+#define MC44S803_G1_S          5
+#define MC44S803_G3            0x80
+#define MC44S803_G3_S          7
+#define MC44S803_CIRCADJ_RES   0x300
+#define MC44S803_CIRCADJ_RES_S 8
+#define MC44S803_G6            0x400
+#define MC44S803_G6_S          10
+#define MC44S803_G7            0x800
+#define MC44S803_G7_S          11
+#define MC44S803_S1            0x1000
+#define MC44S803_S1_S          12
+#define MC44S803_LP            0x7E000
+#define MC44S803_LP_S          13
+#define MC44S803_CLRF          0x80000
+#define MC44S803_CLRF_S                19
+#define MC44S803_CLIF          0x100000
+#define MC44S803_CLIF_S                20
+/* REG_TEST */
+/* REG_DIGTUNE */
+#define MC44S803_DA            0xF0
+#define MC44S803_DA_S          4
+#define MC44S803_XOD           0x300
+#define MC44S803_XOD_S         8
+#define MC44S803_RST           0x10000
+#define MC44S803_RST_S         16
+#define MC44S803_LO_REF                0x1FFF00
+#define MC44S803_LO_REF_S      8
+#define MC44S803_AT            0x200000
+#define MC44S803_AT_S          21
+#define MC44S803_MT            0x400000
+#define MC44S803_MT_S          22
+/* REG_LNAAGC */
+#define MC44S803_G             0x3F0
+#define MC44S803_G_S           4
+#define MC44S803_AT1           0x400
+#define MC44S803_AT1_S         10
+#define MC44S803_AT2           0x800
+#define MC44S803_AT2_S         11
+#define MC44S803_HL_GR_EN      0x8000
+#define MC44S803_HL_GR_EN_S    15
+#define MC44S803_AGC_AN_DIG    0x10000
+#define MC44S803_AGC_AN_DIG_S  16
+#define MC44S803_ATTEN_EN      0x20000
+#define MC44S803_ATTEN_EN_S    17
+#define MC44S803_AGC_READ_EN   0x40000
+#define MC44S803_AGC_READ_EN_S 18
+#define MC44S803_LNA0          0x80000
+#define MC44S803_LNA0_S                19
+#define MC44S803_AGC_SEL       0x100000
+#define MC44S803_AGC_SEL_S     20
+#define MC44S803_AT0           0x200000
+#define MC44S803_AT0_S         21
+#define MC44S803_B             0xC00000
+#define MC44S803_B_S           22
+/* REG_DATAREG */
+#define MC44S803_D             0xF0
+#define MC44S803_D_S           4
+/* REG_REGTEST */
+/* REG_VCOTEST */
+/* REG_LNAGAIN */
+#define MC44S803_IF_PWR                0x700
+#define MC44S803_IF_PWR_S      8
+#define MC44S803_RF_PWR                0x3800
+#define MC44S803_RF_PWR_S      11
+#define MC44S803_LNA_GAIN      0xFC000
+#define MC44S803_LNA_GAIN_S    14
+/* REG_ID */
+#define MC44S803_ID            0x3E00
+#define MC44S803_ID_S          9
+
+/* Some macros to read/write fields */
+
+/* First shift, then mask */
+#define MC44S803_REG_SM(_val, _reg)                                    \
+       (((_val) << _reg##_S) & (_reg))
+
+/* First mask, then shift */
+#define MC44S803_REG_MS(_val, _reg)                                    \
+       (((_val) & (_reg)) >> _reg##_S)
+
+struct mc44s803_priv {
+       struct mc44s803_config *cfg;
+       struct i2c_adapter *i2c;
+       struct dvb_frontend *fe;
+
+       u32 frequency;
+};
+
+#endif
diff -r 18c79168ec6c -r 40d6f7e3a34e linux/drivers/media/dvb/dvb-usb/Kconfig
--- a/linux/drivers/media/dvb/dvb-usb/Kconfig   Mon Feb 09 15:38:11 2009 -0200
+++ b/linux/drivers/media/dvb/dvb-usb/Kconfig   Mon Feb 09 15:44:51 2009 -0200
@@ -297,5 +297,6 @@ config DVB_USB_AF9015
        select MEDIA_TUNER_QT1010   if !MEDIA_TUNER_CUSTOMIZE
        select MEDIA_TUNER_TDA18271 if !MEDIA_TUNER_CUSTOMIZE
        select MEDIA_TUNER_MXL5005S if !MEDIA_TUNER_CUSTOMIZE
+       select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
        help
          Say Y here to support the Afatech AF9015 based DVB-T USB2.0 receiver
diff -r 18c79168ec6c -r 40d6f7e3a34e linux/drivers/media/dvb/dvb-usb/af9015.c
--- a/linux/drivers/media/dvb/dvb-usb/af9015.c  Mon Feb 09 15:38:11 2009 -0200
+++ b/linux/drivers/media/dvb/dvb-usb/af9015.c  Mon Feb 09 15:44:51 2009 -0200
@@ -27,9 +27,7 @@
 #include "qt1010.h"
 #include "tda18271.h"
 #include "mxl5005s.h"
-#if 0 /* keep */
-#include "mc44s80x.h"
-#endif
+#include "mc44s803.h"
 
 static int dvb_usb_af9015_debug;
 module_param_named(debug, dvb_usb_af9015_debug, int, 0644);
@@ -280,6 +278,21 @@ Due to that the only way to select corre
                        req.data = &msg[i+1].buf[0];
                        ret = af9015_ctrl_msg(d, &req);
                        i += 2;
+               } else if (msg[i].flags & I2C_M_RD) {
+                       ret = -EINVAL;
+                       if (msg[i].addr ==
+                               af9015_af9013_config[0].demod_address)
+                               goto error;
+                       else
+                               req.cmd = READ_I2C;
+                       req.i2c_addr = msg[i].addr;
+                       req.addr = addr;
+                       req.mbox = mbox;
+                       req.addr_len = addr_len;
+                       req.data_len = msg[i].len;
+                       req.data = &msg[i].buf[0];
+                       ret = af9015_ctrl_msg(d, &req);
+                       i += 1;
                } else {
                        if (msg[i].addr ==
                                af9015_af9013_config[0].demod_address)
@@ -942,7 +955,6 @@ static int af9015_read_config(struct usb
                switch (val) {
                case AF9013_TUNER_ENV77H11D5:
                case AF9013_TUNER_MT2060:
-               case AF9013_TUNER_MC44S803:
                case AF9013_TUNER_QT1010:
                case AF9013_TUNER_UNKNOWN:
                case AF9013_TUNER_MT2060_2:
@@ -954,6 +966,10 @@ static int af9015_read_config(struct usb
                case AF9013_TUNER_MXL5005D:
                case AF9013_TUNER_MXL5005R:
                        af9015_af9013_config[i].rf_spec_inv = 0;
+                       break;
+               case AF9013_TUNER_MC44S803:
+                       af9015_af9013_config[i].gpio[1] = AF9013_GPIO_LO;
+                       af9015_af9013_config[i].rf_spec_inv = 1;
                        break;
                default:
                        warn("tuner id:%d not supported, please report!", val);
@@ -1140,6 +1156,11 @@ static struct mxl5005s_config af9015_mxl
        .mod_mode        = MXL_DIGITAL_MODE,
        .if_mode         = MXL_ZERO_IF,
        .AgcMasterByte   = 0x00,
+};
+
+static struct mc44s803_config af9015_mc44s803_config = {
+       .i2c_address = 0xc0,
+       .dig_out = 1,
 };
 
 static int af9015_tuner_attach(struct dvb_usb_adapter *adap)
@@ -1186,15 +1207,8 @@ static int af9015_tuner_attach(struct dv
                        DVB_PLL_TDA665X) == NULL ? -ENODEV : 0;
                break;
        case AF9013_TUNER_MC44S803:
-#if 0 /* keep */
-               ret = dvb_attach(mc44s80x_attach, adap->fe, i2c_adap)
-                       == NULL ? -ENODEV : 0;
-#else
-               ret = -ENODEV;
-               info("Freescale MC44S803 tuner found but no driver for that" \
-                       "tuner. Look at the Linuxtv.org for tuner driver" \
-                       "status.");
-#endif
+               ret = dvb_attach(mc44s803_attach, adap->fe, i2c_adap,
+                       &af9015_mc44s803_config) == NULL ? -ENODEV : 0;
                break;
        case AF9013_TUNER_UNKNOWN:
        default:


---

Patch is available at: 
http://linuxtv.org/hg/v4l-dvb/rev/40d6f7e3a34e3b03271c2b8a9828eab9b4894b2f

_______________________________________________
linuxtv-commits mailing list
linuxtv-commits@linuxtv.org
http://www.linuxtv.org/cgi-bin/mailman/listinfo/linuxtv-commits

Reply via email to