summaryrefslogtreecommitdiff
path: root/linux/drivers/media/dvb/frontends
diff options
context:
space:
mode:
Diffstat (limited to 'linux/drivers/media/dvb/frontends')
-rw-r--r--linux/drivers/media/dvb/frontends/Kconfig162
-rw-r--r--linux/drivers/media/dvb/frontends/Makefile16
-rw-r--r--linux/drivers/media/dvb/frontends/au8522.c697
-rw-r--r--linux/drivers/media/dvb/frontends/au8522.h56
-rw-r--r--linux/drivers/media/dvb/frontends/bcm3510.c4
-rw-r--r--linux/drivers/media/dvb/frontends/bcm3510.h2
-rw-r--r--linux/drivers/media/dvb/frontends/bsbe1.h58
-rw-r--r--linux/drivers/media/dvb/frontends/bsru6.h2
-rw-r--r--linux/drivers/media/dvb/frontends/cx22700.c12
-rw-r--r--linux/drivers/media/dvb/frontends/cx22700.h2
-rw-r--r--linux/drivers/media/dvb/frontends/cx22702.c24
-rw-r--r--linux/drivers/media/dvb/frontends/cx22702.h2
-rw-r--r--linux/drivers/media/dvb/frontends/cx24110.c6
-rw-r--r--linux/drivers/media/dvb/frontends/cx24110.h2
-rw-r--r--linux/drivers/media/dvb/frontends/dib0070.h15
-rw-r--r--linux/drivers/media/dvb/frontends/dib3000.h2
-rw-r--r--linux/drivers/media/dvb/frontends/dib3000mc.h2
-rw-r--r--linux/drivers/media/dvb/frontends/dib7000p.c8
-rw-r--r--linux/drivers/media/dvb/frontends/dib7000p.h17
-rw-r--r--linux/drivers/media/dvb/frontends/drx397xD.c1583
-rw-r--r--linux/drivers/media/dvb/frontends/drx397xD.h130
-rw-r--r--linux/drivers/media/dvb/frontends/drx397xD_fw.h40
-rw-r--r--linux/drivers/media/dvb/frontends/dvb-pll.c47
-rw-r--r--linux/drivers/media/dvb/frontends/dvb-pll.h3
-rw-r--r--linux/drivers/media/dvb/frontends/isl6405.h2
-rw-r--r--linux/drivers/media/dvb/frontends/isl6421.h2
-rw-r--r--linux/drivers/media/dvb/frontends/itd1000.c408
-rw-r--r--linux/drivers/media/dvb/frontends/itd1000.h (renamed from linux/drivers/media/dvb/frontends/mt2060.h)21
-rw-r--r--linux/drivers/media/dvb/frontends/itd1000_priv.h88
-rw-r--r--linux/drivers/media/dvb/frontends/l64781.c2
-rw-r--r--linux/drivers/media/dvb/frontends/l64781.h2
-rw-r--r--linux/drivers/media/dvb/frontends/lgdt330x.c38
-rw-r--r--linux/drivers/media/dvb/frontends/lgdt330x.h2
-rw-r--r--linux/drivers/media/dvb/frontends/lnbp21.h2
-rw-r--r--linux/drivers/media/dvb/frontends/mt2060.c376
-rw-r--r--linux/drivers/media/dvb/frontends/mt2060_priv.h105
-rw-r--r--linux/drivers/media/dvb/frontends/mt2131.c315
-rw-r--r--linux/drivers/media/dvb/frontends/mt2131.h54
-rw-r--r--linux/drivers/media/dvb/frontends/mt2131_priv.h49
-rw-r--r--linux/drivers/media/dvb/frontends/mt2266.c352
-rw-r--r--linux/drivers/media/dvb/frontends/mt2266.h37
-rw-r--r--linux/drivers/media/dvb/frontends/mt312.c160
-rw-r--r--linux/drivers/media/dvb/frontends/mt312.h9
-rw-r--r--linux/drivers/media/dvb/frontends/mt312_priv.h5
-rw-r--r--linux/drivers/media/dvb/frontends/mt352.c8
-rw-r--r--linux/drivers/media/dvb/frontends/mt352.h2
-rw-r--r--linux/drivers/media/dvb/frontends/nxt200x.c26
-rw-r--r--linux/drivers/media/dvb/frontends/nxt200x.h2
-rw-r--r--linux/drivers/media/dvb/frontends/nxt6000.h2
-rw-r--r--linux/drivers/media/dvb/frontends/or51132.c16
-rw-r--r--linux/drivers/media/dvb/frontends/or51132.h2
-rw-r--r--linux/drivers/media/dvb/frontends/or51211.c6
-rw-r--r--linux/drivers/media/dvb/frontends/or51211.h2
-rw-r--r--linux/drivers/media/dvb/frontends/qt1010.c489
-rw-r--r--linux/drivers/media/dvb/frontends/qt1010.h53
-rw-r--r--linux/drivers/media/dvb/frontends/qt1010_priv.h105
-rw-r--r--linux/drivers/media/dvb/frontends/s5h1409.c49
-rw-r--r--linux/drivers/media/dvb/frontends/s5h1409.h2
-rw-r--r--linux/drivers/media/dvb/frontends/s5h1411.c887
-rw-r--r--linux/drivers/media/dvb/frontends/s5h1411.h90
-rw-r--r--linux/drivers/media/dvb/frontends/s5h1420.c542
-rw-r--r--linux/drivers/media/dvb/frontends/s5h1420.h64
-rw-r--r--linux/drivers/media/dvb/frontends/s5h1420_priv.h380
-rw-r--r--linux/drivers/media/dvb/frontends/sp8870.c26
-rw-r--r--linux/drivers/media/dvb/frontends/sp8870.h2
-rw-r--r--linux/drivers/media/dvb/frontends/sp887x.c18
-rw-r--r--linux/drivers/media/dvb/frontends/sp887x.h2
-rw-r--r--linux/drivers/media/dvb/frontends/stv0297.c14
-rw-r--r--linux/drivers/media/dvb/frontends/stv0297.h2
-rw-r--r--linux/drivers/media/dvb/frontends/stv0299.c85
-rw-r--r--linux/drivers/media/dvb/frontends/stv0299.h13
-rw-r--r--linux/drivers/media/dvb/frontends/tda10021.c4
-rw-r--r--linux/drivers/media/dvb/frontends/tda10023.c197
-rw-r--r--linux/drivers/media/dvb/frontends/tda1002x.h35
-rw-r--r--linux/drivers/media/dvb/frontends/tda10048.c846
-rw-r--r--linux/drivers/media/dvb/frontends/tda10048.h63
-rw-r--r--linux/drivers/media/dvb/frontends/tda1004x.c56
-rw-r--r--linux/drivers/media/dvb/frontends/tda1004x.h4
-rw-r--r--linux/drivers/media/dvb/frontends/tda10086.c145
-rw-r--r--linux/drivers/media/dvb/frontends/tda10086.h14
-rw-r--r--linux/drivers/media/dvb/frontends/tda18271-common.c734
-rw-r--r--linux/drivers/media/dvb/frontends/tda18271-fe.c1154
-rw-r--r--linux/drivers/media/dvb/frontends/tda18271-priv.h229
-rw-r--r--linux/drivers/media/dvb/frontends/tda18271-tables.c1313
-rw-r--r--linux/drivers/media/dvb/frontends/tda18271.h99
-rw-r--r--linux/drivers/media/dvb/frontends/tda8083.c4
-rw-r--r--linux/drivers/media/dvb/frontends/tda8083.h2
-rw-r--r--linux/drivers/media/dvb/frontends/tda826x.c23
-rw-r--r--linux/drivers/media/dvb/frontends/tda826x.h2
-rw-r--r--linux/drivers/media/dvb/frontends/tda827x.c853
-rw-r--r--linux/drivers/media/dvb/frontends/tda827x.h69
-rw-r--r--linux/drivers/media/dvb/frontends/tua6100.c2
-rw-r--r--linux/drivers/media/dvb/frontends/tua6100.h2
-rw-r--r--linux/drivers/media/dvb/frontends/ves1820.c4
-rw-r--r--linux/drivers/media/dvb/frontends/ves1820.h2
-rw-r--r--linux/drivers/media/dvb/frontends/ves1x93.c6
-rw-r--r--linux/drivers/media/dvb/frontends/ves1x93.h2
-rw-r--r--linux/drivers/media/dvb/frontends/xc5000.c983
-rw-r--r--linux/drivers/media/dvb/frontends/xc5000.h63
-rw-r--r--linux/drivers/media/dvb/frontends/xc5000_priv.h36
-rw-r--r--linux/drivers/media/dvb/frontends/zl10353.c6
-rw-r--r--linux/drivers/media/dvb/frontends/zl10353.h2
102 files changed, 6489 insertions, 8275 deletions
diff --git a/linux/drivers/media/dvb/frontends/Kconfig b/linux/drivers/media/dvb/frontends/Kconfig
index 0209644f2..fa7f0c563 100644
--- a/linux/drivers/media/dvb/frontends/Kconfig
+++ b/linux/drivers/media/dvb/frontends/Kconfig
@@ -15,22 +15,36 @@ config DVB_FE_CUSTOMISE
comment "DVB-S (satellite) frontends"
depends on DVB_CORE
-config DVB_STV0299
- tristate "ST STV0299 based"
+config DVB_CX24110
+ tristate "Conexant CX24110 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
-config DVB_CX24110
- tristate "Conexant CX24110 based"
+config DVB_CX24123
+ tristate "Conexant CX24123 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
-config DVB_CX24123
- tristate "Conexant CX24123 based"
+config DVB_MT312
+ tristate "Zarlink VP310/MT312/ZL10313 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_S5H1420
+ tristate "Samsung S5H1420 based"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S tuner module. Say Y when you want to support this frontend.
+
+config DVB_STV0299
+ tristate "ST STV0299 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
@@ -43,8 +57,8 @@ config DVB_TDA8083
help
A DVB-S tuner module. Say Y when you want to support this frontend.
-config DVB_MT312
- tristate "Zarlink VP310/MT312 based"
+config DVB_TDA10086
+ tristate "Philips TDA10086 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
@@ -57,26 +71,33 @@ config DVB_VES1X93
help
A DVB-S tuner module. Say Y when you want to support this frontend.
-config DVB_S5H1420
- tristate "Samsung S5H1420 based"
+config DVB_TUNER_ITD1000
+ tristate "Integrant ITD1000 Zero IF tuner for DVB-S/DSS"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
A DVB-S tuner module. Say Y when you want to support this frontend.
-config DVB_TDA10086
- tristate "Philips TDA10086 based"
+config DVB_TDA826X
+ tristate "Philips TDA826X silicon tuner"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
- A DVB-S tuner module. Say Y when you want to support this frontend.
+ A DVB-S silicon tuner module. Say Y when you want to support this tuner.
+
+config DVB_TUA6100
+ tristate "Infineon TUA6100 PLL"
+ depends on DVB_CORE && I2C
+ default m if DVB_FE_CUSTOMISE
+ help
+ A DVB-S PLL chip.
comment "DVB-T (terrestrial) frontends"
depends on DVB_CORE
config DVB_SP8870
tristate "Spase sp8870 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -89,7 +110,7 @@ config DVB_SP8870
config DVB_SP887X
tristate "Spase sp887x based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -114,6 +135,20 @@ config DVB_CX22702
help
A DVB-T tuner module. Say Y when you want to support this frontend.
+config DVB_DRX397XD
+ tristate "Micronas DRX3975D/DRX3977D based"
+ depends on DVB_CORE && I2C && HOTPLUG
+ default m if DVB_FE_CUSTOMISE
+ select FW_LOADER
+ help
+ A DVB-T tuner module. Say Y when you want to support this frontend.
+
+ TODO:
+ This driver needs external firmware. Please use the command
+ "<kerneldir>/Documentation/dvb/get_dvb_firmware drx397xD" to
+ download/extract them, and then copy them to /usr/lib/hotplug/firmware
+ or /lib/firmware (depending on configuration of firmware hotplug).
+
config DVB_L64781
tristate "LSI L64781"
depends on DVB_CORE && I2C
@@ -123,7 +158,7 @@ config DVB_L64781
config DVB_TDA1004X
tristate "Philips TDA10045H/TDA10046H based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -188,6 +223,14 @@ config DVB_DIB7000P
A DVB-T tuner module. Designed for mobile usage. Say Y when you want
to support this frontend.
+config DVB_TDA10048
+ tristate "Philips TDA10048HN based"
+ depends on DVB_CORE && I2C && HOTPLUG
+ default m if DVB_FE_CUSTOMISE
+ select FW_LOADER
+ help
+ A DVB-T tuner module. Say Y when you want to support this frontend.
+
comment "DVB-C (cable) frontends"
depends on DVB_CORE
@@ -224,7 +267,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
config DVB_NXT200X
tristate "NxtWave Communications NXT2002/NXT2004 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -239,7 +282,7 @@ config DVB_NXT200X
config DVB_OR51211
tristate "Oren OR51211 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -252,7 +295,7 @@ config DVB_OR51211
config DVB_OR51132
tristate "Oren OR51132 based"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -268,7 +311,7 @@ config DVB_OR51132
config DVB_BCM3510
tristate "Broadcom BCM3510"
- depends on DVB_CORE && I2C
+ depends on DVB_CORE && I2C && HOTPLUG
default m if DVB_FE_CUSTOMISE
select FW_LOADER
help
@@ -291,65 +334,32 @@ config DVB_S5H1409
An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
to support this frontend.
-comment "Tuners/PLL support"
- depends on DVB_CORE
-
-config DVB_PLL
- tristate "Generic I2C PLL based tuners"
- depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
- help
- This module drives a number of tuners based on PLL chips with a
- common I2C interface. Say Y when you want to support these tuners.
-
-config DVB_TDA826X
- tristate "Philips TDA826X silicon tuner"
+config DVB_AU8522
+ tristate "Auvitek AU8522 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
- A DVB-S silicon tuner module. Say Y when you want to support this tuner.
+ An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+ to support this frontend.
-config DVB_TDA827X
- tristate "Philips TDA827X silicon tuner"
+config DVB_S5H1411
+ tristate "Samsung S5H1411 based"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
- A DVB-T silicon tuner module. Say Y when you want to support this tuner.
+ An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
+ to support this frontend.
-config DVB_TDA18271
- tristate "NXP TDA18271 silicon tuner"
- depends on I2C
- default m if DVB_FE_CUSTOMISE
- help
- A silicon tuner module. Say Y when you want to support this tuner.
+comment "Digital terrestrial only tuners/PLL"
+ depends on DVB_CORE
-config DVB_TUNER_QT1010
- tristate "Quantek QT1010 silicon tuner"
+config DVB_PLL
+ tristate "Generic I2C PLL based tuners"
depends on DVB_CORE && I2C
default m if DVB_FE_CUSTOMISE
help
- A driver for the silicon tuner QT1010 from Quantek.
-
-config DVB_TUNER_MT2060
- tristate "Microtune MT2060 silicon IF tuner"
- depends on I2C
- default m if DVB_FE_CUSTOMISE
- help
- A driver for the silicon IF tuner MT2060 from Microtune.
-
-config DVB_TUNER_MT2266
- tristate "Microtune MT2266 silicon tuner"
- depends on I2C
- default m if DVB_FE_CUSTOMISE
- help
- A driver for the silicon baseband tuner MT2266 from Microtune.
-
-config DVB_TUNER_MT2131
- tristate "Microtune MT2131 silicon tuner"
- depends on I2C
- default m if DVB_FE_CUSTOMISE
- help
- A driver for the silicon baseband tuner MT2131 from Microtune.
+ This module drives a number of tuners based on PLL chips with a
+ common I2C interface. Say Y when you want to support these tuners.
config DVB_TUNER_DIB0070
tristate "DiBcom DiB0070 silicon base-band tuner"
@@ -360,16 +370,7 @@ config DVB_TUNER_DIB0070
This device is only used inside a SiP called togther with a
demodulator for now.
-config DVB_TUNER_XC5000
- tristate "Xceive XC5000 silicon tuner"
- depends on I2C
- default m if DVB_FE_CUSTOMISE
- help
- A driver for the silicon tuner XC5000 from Xceive.
- This device is only used inside a SiP called togther with a
- demodulator for now.
-
-comment "Miscellaneous devices"
+comment "SEC control devices for DVB-S"
depends on DVB_CORE
config DVB_LNBP21
@@ -393,11 +394,4 @@ config DVB_ISL6421
help
An SEC control chip.
-config DVB_TUA6100
- tristate "TUA6100 PLL"
- depends on DVB_CORE && I2C
- default m if DVB_FE_CUSTOMISE
- help
- A DVBS PLL chip.
-
endmenu
diff --git a/linux/drivers/media/dvb/frontends/Makefile b/linux/drivers/media/dvb/frontends/Makefile
index 23304b377..028da5561 100644
--- a/linux/drivers/media/dvb/frontends/Makefile
+++ b/linux/drivers/media/dvb/frontends/Makefile
@@ -3,9 +3,7 @@
#
EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core/
-EXTRA_CFLAGS += -Idrivers/media/video/
-
-tda18271-objs := tda18271-tables.o tda18271-common.o tda18271-fe.o
+EXTRA_CFLAGS += -Idrivers/media/common/tuners/
obj-$(CONFIG_DVB_PLL) += dvb-pll.o
obj-$(CONFIG_DVB_STV0299) += stv0299.o
@@ -27,6 +25,7 @@ obj-$(CONFIG_DVB_NXT6000) += nxt6000.o
obj-$(CONFIG_DVB_MT352) += mt352.o
obj-$(CONFIG_DVB_ZL10353) += zl10353.o
obj-$(CONFIG_DVB_CX22702) += cx22702.o
+obj-$(CONFIG_DVB_DRX397XD) += drx397xD.o
obj-$(CONFIG_DVB_TDA10021) += tda10021.o
obj-$(CONFIG_DVB_TDA10023) += tda10023.o
obj-$(CONFIG_DVB_STV0297) += stv0297.o
@@ -42,13 +41,10 @@ obj-$(CONFIG_DVB_ISL6405) += isl6405.o
obj-$(CONFIG_DVB_ISL6421) += isl6421.o
obj-$(CONFIG_DVB_TDA10086) += tda10086.o
obj-$(CONFIG_DVB_TDA826X) += tda826x.o
-obj-$(CONFIG_DVB_TDA827X) += tda827x.o
-obj-$(CONFIG_DVB_TDA18271) += tda18271.o
-obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
-obj-$(CONFIG_DVB_TUNER_MT2266) += mt2266.o
obj-$(CONFIG_DVB_TUNER_DIB0070) += dib0070.o
-obj-$(CONFIG_DVB_TUNER_QT1010) += qt1010.o
obj-$(CONFIG_DVB_TUA6100) += tua6100.o
-obj-$(CONFIG_DVB_TUNER_MT2131) += mt2131.o
obj-$(CONFIG_DVB_S5H1409) += s5h1409.o
-obj-$(CONFIG_DVB_TUNER_XC5000) += xc5000.o
+obj-$(CONFIG_DVB_TUNER_ITD1000) += itd1000.o
+obj-$(CONFIG_DVB_AU8522) += au8522.o
+obj-$(CONFIG_DVB_TDA10048) += tda10048.o
+obj-$(CONFIG_DVB_S5H1411) += s5h1411.o
diff --git a/linux/drivers/media/dvb/frontends/au8522.c b/linux/drivers/media/dvb/frontends/au8522.c
new file mode 100644
index 000000000..3e1b0d96f
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/au8522.c
@@ -0,0 +1,697 @@
+/*
+ Auvitek AU8522 QAM/8VSB demodulator driver
+
+ Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+
+ 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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "au8522.h"
+
+struct au8522_state {
+
+ struct i2c_adapter *i2c;
+
+ /* configuration settings */
+ const struct au8522_config *config;
+
+ struct dvb_frontend frontend;
+
+ u32 current_frequency;
+ fe_modulation_t current_modulation;
+
+};
+
+static int debug;
+
+#define dprintk(arg...) do { \
+ if (debug) \
+ printk(arg); \
+ } while (0)
+
+/* 16 bit registers, 8 bit values */
+static int au8522_writereg(struct au8522_state *state, u16 reg, u8 data)
+{
+ int ret;
+ u8 buf [] = { reg >> 8, reg & 0xff, data };
+
+ struct i2c_msg msg = { .addr = state->config->demod_address,
+ .flags = 0, .buf = buf, .len = 3 };
+
+ ret = i2c_transfer(state->i2c, &msg, 1);
+
+ if (ret != 1)
+ printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
+ "ret == %i)\n", __func__, reg, data, ret);
+
+ return (ret != 1) ? -1 : 0;
+}
+
+static u8 au8522_readreg(struct au8522_state *state, u16 reg)
+{
+ int ret;
+ u8 b0 [] = { reg >> 8, reg & 0xff };
+ u8 b1 [] = { 0 };
+
+ struct i2c_msg msg [] = {
+ { .addr = state->config->demod_address, .flags = 0,
+ .buf = b0, .len = 2 },
+ { .addr = state->config->demod_address, .flags = I2C_M_RD,
+ .buf = b1, .len = 1 } };
+
+ ret = i2c_transfer(state->i2c, msg, 2);
+
+ if (ret != 2)
+ printk(KERN_ERR "%s: readreg error (ret == %i)\n",
+ __func__, ret);
+ return b1[0];
+}
+
+static int au8522_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+
+ dprintk("%s(%d)\n", __func__, enable);
+
+ if (enable)
+ return au8522_writereg(state, 0x106, 1);
+ else
+ return au8522_writereg(state, 0x106, 0);
+}
+
+struct mse2snr_tab {
+ u16 val;
+ u16 data;
+};
+
+/* VSB SNR lookup table */
+static struct mse2snr_tab vsb_mse2snr_tab[] = {
+ { 0, 270 },
+ { 2, 250 },
+ { 3, 240 },
+ { 5, 230 },
+ { 7, 220 },
+ { 9, 210 },
+ { 12, 200 },
+ { 13, 195 },
+ { 15, 190 },
+ { 17, 185 },
+ { 19, 180 },
+ { 21, 175 },
+ { 24, 170 },
+ { 27, 165 },
+ { 31, 160 },
+ { 32, 158 },
+ { 33, 156 },
+ { 36, 152 },
+ { 37, 150 },
+ { 39, 148 },
+ { 40, 146 },
+ { 41, 144 },
+ { 43, 142 },
+ { 44, 140 },
+ { 48, 135 },
+ { 50, 130 },
+ { 43, 142 },
+ { 53, 125 },
+ { 56, 120 },
+ { 256, 115 },
+};
+
+/* QAM64 SNR lookup table */
+static struct mse2snr_tab qam64_mse2snr_tab[] = {
+ { 15, 0 },
+ { 16, 290 },
+ { 17, 288 },
+ { 18, 286 },
+ { 19, 284 },
+ { 20, 282 },
+ { 21, 281 },
+ { 22, 279 },
+ { 23, 277 },
+ { 24, 275 },
+ { 25, 273 },
+ { 26, 271 },
+ { 27, 269 },
+ { 28, 268 },
+ { 29, 266 },
+ { 30, 264 },
+ { 31, 262 },
+ { 32, 260 },
+ { 33, 259 },
+ { 34, 258 },
+ { 35, 256 },
+ { 36, 255 },
+ { 37, 254 },
+ { 38, 252 },
+ { 39, 251 },
+ { 40, 250 },
+ { 41, 249 },
+ { 42, 248 },
+ { 43, 246 },
+ { 44, 245 },
+ { 45, 244 },
+ { 46, 242 },
+ { 47, 241 },
+ { 48, 240 },
+ { 50, 239 },
+ { 51, 238 },
+ { 53, 237 },
+ { 54, 236 },
+ { 56, 235 },
+ { 57, 234 },
+ { 59, 233 },
+ { 60, 232 },
+ { 62, 231 },
+ { 63, 230 },
+ { 65, 229 },
+ { 67, 228 },
+ { 68, 227 },
+ { 70, 226 },
+ { 71, 225 },
+ { 73, 224 },
+ { 74, 223 },
+ { 76, 222 },
+ { 78, 221 },
+ { 80, 220 },
+ { 82, 219 },
+ { 85, 218 },
+ { 88, 217 },
+ { 90, 216 },
+ { 92, 215 },
+ { 93, 214 },
+ { 94, 212 },
+ { 95, 211 },
+ { 97, 210 },
+ { 99, 209 },
+ { 101, 208 },
+ { 102, 207 },
+ { 104, 206 },
+ { 107, 205 },
+ { 111, 204 },
+ { 114, 203 },
+ { 118, 202 },
+ { 122, 201 },
+ { 125, 200 },
+ { 128, 199 },
+ { 130, 198 },
+ { 132, 197 },
+ { 256, 190 },
+};
+
+/* QAM256 SNR lookup table */
+static struct mse2snr_tab qam256_mse2snr_tab[] = {
+ { 16, 0 },
+ { 17, 400 },
+ { 18, 398 },
+ { 19, 396 },
+ { 20, 394 },
+ { 21, 392 },
+ { 22, 390 },
+ { 23, 388 },
+ { 24, 386 },
+ { 25, 384 },
+ { 26, 382 },
+ { 27, 380 },
+ { 28, 379 },
+ { 29, 378 },
+ { 30, 377 },
+ { 31, 376 },
+ { 32, 375 },
+ { 33, 374 },
+ { 34, 373 },
+ { 35, 372 },
+ { 36, 371 },
+ { 37, 370 },
+ { 38, 362 },
+ { 39, 354 },
+ { 40, 346 },
+ { 41, 338 },
+ { 42, 330 },
+ { 43, 328 },
+ { 44, 326 },
+ { 45, 324 },
+ { 46, 322 },
+ { 47, 320 },
+ { 48, 319 },
+ { 49, 318 },
+ { 50, 317 },
+ { 51, 316 },
+ { 52, 315 },
+ { 53, 314 },
+ { 54, 313 },
+ { 55, 312 },
+ { 56, 311 },
+ { 57, 310 },
+ { 58, 308 },
+ { 59, 306 },
+ { 60, 304 },
+ { 61, 302 },
+ { 62, 300 },
+ { 63, 298 },
+ { 65, 295 },
+ { 68, 294 },
+ { 70, 293 },
+ { 73, 292 },
+ { 76, 291 },
+ { 78, 290 },
+ { 79, 289 },
+ { 81, 288 },
+ { 82, 287 },
+ { 83, 286 },
+ { 84, 285 },
+ { 85, 284 },
+ { 86, 283 },
+ { 88, 282 },
+ { 89, 281 },
+ { 256, 280 },
+};
+
+static int au8522_mse2snr_lookup(struct mse2snr_tab *tab, int sz, int mse,
+ u16 *snr)
+{
+ int i, ret = -EINVAL;
+ dprintk("%s()\n", __func__);
+
+ for (i = 0; i < sz; i++) {
+ if (mse < tab[i].val) {
+ *snr = tab[i].data;
+ ret = 0;
+ break;
+ }
+ }
+ dprintk("%s() snr=%d\n", __func__, *snr);
+ return ret;
+}
+
+/* VSB Modulation table */
+static struct {
+ u16 reg;
+ u16 data;
+} VSB_mod_tab[] = {
+ { 0x8090, 0x84 },
+ { 0x4092, 0x11 },
+ { 0x2005, 0x00 },
+ { 0x8091, 0x80 },
+ { 0x80a3, 0x0c },
+ { 0x80a4, 0xe8 },
+ { 0x8081, 0xc4 },
+ { 0x80a5, 0x40 },
+ { 0x80a7, 0x40 },
+ { 0x80a6, 0x67 },
+ { 0x8262, 0x20 },
+ { 0x821c, 0x30 },
+ { 0x80d8, 0x1a },
+ { 0x8227, 0xa0 },
+ { 0x8121, 0xff },
+ { 0x80a8, 0xf0 },
+ { 0x80a9, 0x05 },
+ { 0x80aa, 0x77 },
+ { 0x80ab, 0xf0 },
+ { 0x80ac, 0x05 },
+ { 0x80ad, 0x77 },
+ { 0x80ae, 0x41 },
+ { 0x80af, 0x66 },
+ { 0x821b, 0xcc },
+ { 0x821d, 0x80 },
+ { 0x80b5, 0xfb },
+ { 0x80b6, 0x8e },
+ { 0x80b7, 0x39 },
+ { 0x80a4, 0xe8 },
+ { 0x8231, 0x13 },
+};
+
+/* QAM Modulation table */
+static struct {
+ u16 reg;
+ u16 data;
+} QAM_mod_tab[] = {
+ { 0x80a3, 0x09 },
+ { 0x80a4, 0x00 },
+ { 0x8081, 0xc4 },
+ { 0x80a5, 0x40 },
+ { 0x80b5, 0xfb },
+ { 0x80b6, 0x8e },
+ { 0x80b7, 0x39 },
+ { 0x80aa, 0x77 },
+ { 0x80ad, 0x77 },
+ { 0x80a6, 0x67 },
+ { 0x8262, 0x20 },
+ { 0x821c, 0x30 },
+ { 0x80b8, 0x3e },
+ { 0x80b9, 0xf0 },
+ { 0x80ba, 0x01 },
+ { 0x80bb, 0x18 },
+ { 0x80bc, 0x50 },
+ { 0x80bd, 0x00 },
+ { 0x80be, 0xea },
+ { 0x80bf, 0xef },
+ { 0x80c0, 0xfc },
+ { 0x80c1, 0xbd },
+ { 0x80c2, 0x1f },
+ { 0x80c3, 0xfc },
+ { 0x80c4, 0xdd },
+ { 0x80c5, 0xaf },
+ { 0x80c6, 0x00 },
+ { 0x80c7, 0x38 },
+ { 0x80c8, 0x30 },
+ { 0x80c9, 0x05 },
+ { 0x80ca, 0x4a },
+ { 0x80cb, 0xd0 },
+ { 0x80cc, 0x01 },
+ { 0x80cd, 0xd9 },
+ { 0x80ce, 0x6f },
+ { 0x80cf, 0xf9 },
+ { 0x80d0, 0x70 },
+ { 0x80d1, 0xdf },
+ { 0x80d2, 0xf7 },
+ { 0x80d3, 0xc2 },
+ { 0x80d4, 0xdf },
+ { 0x80d5, 0x02 },
+ { 0x80d6, 0x9a },
+ { 0x80d7, 0xd0 },
+ { 0x8250, 0x0d },
+ { 0x8251, 0xcd },
+ { 0x8252, 0xe0 },
+ { 0x8253, 0x05 },
+ { 0x8254, 0xa7 },
+ { 0x8255, 0xff },
+ { 0x8256, 0xed },
+ { 0x8257, 0x5b },
+ { 0x8258, 0xae },
+ { 0x8259, 0xe6 },
+ { 0x825a, 0x3d },
+ { 0x825b, 0x0f },
+ { 0x825c, 0x0d },
+ { 0x825d, 0xea },
+ { 0x825e, 0xf2 },
+ { 0x825f, 0x51 },
+ { 0x8260, 0xf5 },
+ { 0x8261, 0x06 },
+ { 0x821a, 0x00 },
+ { 0x8546, 0x40 },
+ { 0x8210, 0x26 },
+ { 0x8211, 0xf6 },
+ { 0x8212, 0x84 },
+ { 0x8213, 0x02 },
+ { 0x8502, 0x01 },
+ { 0x8121, 0x04 },
+ { 0x8122, 0x04 },
+ { 0x852e, 0x10 },
+ { 0x80a4, 0xca },
+ { 0x80a7, 0x40 },
+ { 0x8526, 0x01 },
+};
+
+static int au8522_enable_modulation(struct dvb_frontend *fe,
+ fe_modulation_t m)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+ int i;
+
+ dprintk("%s(0x%08x)\n", __func__, m);
+
+ switch (m) {
+ case VSB_8:
+ dprintk("%s() VSB_8\n", __func__);
+ for (i = 0; i < ARRAY_SIZE(VSB_mod_tab); i++)
+ au8522_writereg(state,
+ VSB_mod_tab[i].reg,
+ VSB_mod_tab[i].data);
+ break;
+ case QAM_64:
+ case QAM_256:
+ dprintk("%s() QAM 64/256\n", __func__);
+ for (i = 0; i < ARRAY_SIZE(QAM_mod_tab); i++)
+ au8522_writereg(state,
+ QAM_mod_tab[i].reg,
+ QAM_mod_tab[i].data);
+ break;
+ default:
+ dprintk("%s() Invalid modulation\n", __func__);
+ return -EINVAL;
+ }
+
+ state->current_modulation = m;
+
+ return 0;
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+static int au8522_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+
+ dprintk("%s(frequency=%d)\n", __func__, p->frequency);
+
+ state->current_frequency = p->frequency;
+
+ au8522_enable_modulation(fe, p->u.vsb.modulation);
+
+ /* Allow the demod to settle */
+ msleep(100);
+
+ if (fe->ops.tuner_ops.set_params) {
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+ fe->ops.tuner_ops.set_params(fe, p);
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+
+ return 0;
+}
+
+/* Reset the demod hardware and reset all of the configuration registers
+ to a default state. */
+static int au8522_init(struct dvb_frontend *fe)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+ dprintk("%s()\n", __func__);
+
+ au8522_writereg(state, 0xa4, 1 << 5);
+
+ au8522_i2c_gate_ctrl(fe, 1);
+
+ return 0;
+}
+
+static int au8522_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+ u8 reg;
+ u32 tuner_status = 0;
+
+ *status = 0;
+
+ if (state->current_modulation == VSB_8) {
+ dprintk("%s() Checking VSB_8\n", __func__);
+ reg = au8522_readreg(state, 0x4088);
+ if (reg & 0x01)
+ *status |= FE_HAS_VITERBI;
+ if (reg & 0x02)
+ *status |= FE_HAS_LOCK | FE_HAS_SYNC;
+ } else {
+ dprintk("%s() Checking QAM\n", __func__);
+ reg = au8522_readreg(state, 0x4541);
+ if (reg & 0x80)
+ *status |= FE_HAS_VITERBI;
+ if (reg & 0x20)
+ *status |= FE_HAS_LOCK | FE_HAS_SYNC;
+ }
+
+ switch (state->config->status_mode) {
+ case AU8522_DEMODLOCKING:
+ dprintk("%s() DEMODLOCKING\n", __func__);
+ if (*status & FE_HAS_VITERBI)
+ *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+ break;
+ case AU8522_TUNERLOCKING:
+ /* Get the tuner status */
+ dprintk("%s() TUNERLOCKING\n", __func__);
+ if (fe->ops.tuner_ops.get_status) {
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ fe->ops.tuner_ops.get_status(fe, &tuner_status);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+ if (tuner_status)
+ *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+ break;
+ }
+
+ dprintk("%s() status 0x%08x\n", __func__, *status);
+
+ return 0;
+}
+
+static int au8522_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+ int ret = -EINVAL;
+
+ dprintk("%s()\n", __func__);
+
+ if (state->current_modulation == QAM_256)
+ ret = au8522_mse2snr_lookup(qam256_mse2snr_tab,
+ ARRAY_SIZE(qam256_mse2snr_tab),
+ au8522_readreg(state, 0x4522),
+ snr);
+ else if (state->current_modulation == QAM_64)
+ ret = au8522_mse2snr_lookup(qam64_mse2snr_tab,
+ ARRAY_SIZE(qam64_mse2snr_tab),
+ au8522_readreg(state, 0x4522),
+ snr);
+ else /* VSB_8 */
+ ret = au8522_mse2snr_lookup(vsb_mse2snr_tab,
+ ARRAY_SIZE(vsb_mse2snr_tab),
+ au8522_readreg(state, 0x4311),
+ snr);
+
+ return ret;
+}
+
+static int au8522_read_signal_strength(struct dvb_frontend *fe,
+ u16 *signal_strength)
+{
+ return au8522_read_snr(fe, signal_strength);
+}
+
+static int au8522_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+
+ if (state->current_modulation == VSB_8)
+ *ucblocks = au8522_readreg(state, 0x4087);
+ else
+ *ucblocks = au8522_readreg(state, 0x4543);
+
+ return 0;
+}
+
+static int au8522_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ return au8522_read_ucblocks(fe, ber);
+}
+
+static int au8522_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+
+ p->frequency = state->current_frequency;
+ p->u.vsb.modulation = state->current_modulation;
+
+ return 0;
+}
+
+static int au8522_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *tune)
+{
+ tune->min_delay_ms = 1000;
+ return 0;
+}
+
+static void au8522_release(struct dvb_frontend *fe)
+{
+ struct au8522_state *state = fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops au8522_ops;
+
+struct dvb_frontend *au8522_attach(const struct au8522_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct au8522_state *state = NULL;
+
+ /* allocate memory for the internal state */
+ state = kmalloc(sizeof(struct au8522_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+#if 0
+ /* check if the demod exists */
+ reg = au8522_readreg(state, 0x04);
+ if ((reg != 0x0066) && (reg != 0x007f))
+ goto error;
+#endif
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &au8522_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ if (au8522_init(&state->frontend) != 0) {
+ printk(KERN_ERR "%s: Failed to initialize correctly\n",
+ __func__);
+ goto error;
+ }
+
+ /* Note: Leaving the I2C gate open here. */
+ au8522_i2c_gate_ctrl(&state->frontend, 1);
+
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(au8522_attach);
+
+static struct dvb_frontend_ops au8522_ops = {
+
+ .info = {
+ .name = "Auvitek AU8522 QAM/8VSB Frontend",
+ .type = FE_ATSC,
+ .frequency_min = 54000000,
+ .frequency_max = 858000000,
+ .frequency_stepsize = 62500,
+ .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+ },
+
+ .init = au8522_init,
+ .i2c_gate_ctrl = au8522_i2c_gate_ctrl,
+ .set_frontend = au8522_set_frontend,
+ .get_frontend = au8522_get_frontend,
+ .get_tune_settings = au8522_get_tune_settings,
+ .read_status = au8522_read_status,
+ .read_ber = au8522_read_ber,
+ .read_signal_strength = au8522_read_signal_strength,
+ .read_snr = au8522_read_snr,
+ .read_ucblocks = au8522_read_ucblocks,
+ .release = au8522_release,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("Auvitek AU8522 QAM-B/ATSC Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/frontends/au8522.h b/linux/drivers/media/dvb/frontends/au8522.h
new file mode 100644
index 000000000..d7affa3cd
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/au8522.h
@@ -0,0 +1,56 @@
+/*
+ Auvitek AU8522 QAM/8VSB demodulator driver
+
+ Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+
+ 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 __AU8522_H__
+#define __AU8522_H__
+
+#include <linux/dvb/frontend.h>
+
+struct au8522_config {
+ /* the demodulator's i2c address */
+ u8 demod_address;
+
+ /* Return lock status based on tuner lock, or demod lock */
+#define AU8522_TUNERLOCKING 0
+#define AU8522_DEMODLOCKING 1
+ u8 status_mode;
+};
+
+#if defined(CONFIG_DVB_AU8522) || \
+ (defined(CONFIG_DVB_AU8522_MODULE) && defined(MODULE))
+extern struct dvb_frontend *au8522_attach(const struct au8522_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline
+struct dvb_frontend *au8522_attach(const struct au8522_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_AU8522 */
+
+#endif /* __AU8522_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/linux/drivers/media/dvb/frontends/bcm3510.c b/linux/drivers/media/dvb/frontends/bcm3510.c
index 0e2253dd6..ca9a55ae9 100644
--- a/linux/drivers/media/dvb/frontends/bcm3510.c
+++ b/linux/drivers/media/dvb/frontends/bcm3510.c
@@ -98,7 +98,7 @@ static int bcm3510_writebytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
deb_info("%s: i2c write error (addr %02x, reg %02x, err == %i)\n",
- __FUNCTION__, state->config->demod_address, reg, err);
+ __func__, state->config->demod_address, reg, err);
return -EREMOTEIO;
}
@@ -117,7 +117,7 @@ static int bcm3510_readbytes (struct bcm3510_state *state, u8 reg, u8 *buf, u8 l
if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
deb_info("%s: i2c read error (addr %02x, reg %02x, err == %i)\n",
- __FUNCTION__, state->config->demod_address, reg, err);
+ __func__, state->config->demod_address, reg, err);
return -EREMOTEIO;
}
deb_i2c("i2c rd %02x: ",reg);
diff --git a/linux/drivers/media/dvb/frontends/bcm3510.h b/linux/drivers/media/dvb/frontends/bcm3510.h
index 7e4f95e17..f4575c0cc 100644
--- a/linux/drivers/media/dvb/frontends/bcm3510.h
+++ b/linux/drivers/media/dvb/frontends/bcm3510.h
@@ -41,7 +41,7 @@ extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
static inline struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_BCM3510
diff --git a/linux/drivers/media/dvb/frontends/bsbe1.h b/linux/drivers/media/dvb/frontends/bsbe1.h
index d8f65738e..5e431ebd0 100644
--- a/linux/drivers/media/dvb/frontends/bsbe1.h
+++ b/linux/drivers/media/dvb/frontends/bsbe1.h
@@ -1,5 +1,5 @@
/*
- * bsbe1.h - ALPS BSBE1 tuner support (moved from av7110.c)
+ * bsbe1.h - ALPS BSBE1 tuner support
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
@@ -26,44 +26,24 @@
#define BSBE1_H
static u8 alps_bsbe1_inittab[] = {
- 0x01, 0x15,
- 0x02, 0x30,
- 0x03, 0x00,
+ 0x01, 0x15, /* XTAL = 4MHz, VCO = 352 MHz */
+ 0x02, 0x30, /* MCLK = 88 MHz */
+ 0x03, 0x00, /* ACR output 0 */
0x04, 0x7d, /* F22FR = 0x7d, F22 = f_VCO / 128 / 0x7d = 22 kHz */
- 0x05, 0x35, /* I2CT = 0, SCLT = 1, SDAT = 1 */
- 0x06, 0x40, /* DAC not used, set to high impendance mode */
- 0x07, 0x00, /* DAC LSB */
+ 0x05, 0x05, /* I2CT = 0, SCLT = 1, SDAT = 1 */
+ 0x06, 0x00, /* DAC output 0 */
0x08, 0x40, /* DiSEqC off, LNB power on OP2/LOCK pin on */
0x09, 0x00, /* FIFO */
- 0x0c, 0x51, /* OP1 ctl = Normal, OP1 val = 1 (LNB Power ON) */
- 0x0d, 0x82, /* DC offset compensation = ON, beta_agc1 = 2 */
- 0x0e, 0x23, /* alpha_tmg = 2, beta_tmg = 3 */
- 0x10, 0x3f, // AGC2 0x3d
- 0x11, 0x84,
- 0x12, 0xb9,
- 0x15, 0xc9, // lock detector threshold
- 0x16, 0x00,
- 0x17, 0x00,
- 0x18, 0x00,
- 0x19, 0x00,
- 0x1a, 0x00,
- 0x1f, 0x50,
- 0x20, 0x00,
- 0x21, 0x00,
- 0x22, 0x00,
- 0x23, 0x00,
- 0x28, 0x00, // out imp: normal out type: parallel FEC mode:0
- 0x29, 0x1e, // 1/2 threshold
- 0x2a, 0x14, // 2/3 threshold
- 0x2b, 0x0f, // 3/4 threshold
- 0x2c, 0x09, // 5/6 threshold
- 0x2d, 0x05, // 7/8 threshold
- 0x2e, 0x01,
- 0x31, 0x1f, // test all FECs
- 0x32, 0x19, // viterbi and synchro search
- 0x33, 0xfc, // rs control
- 0x34, 0x93, // error control
- 0x0f, 0x92,
+ 0x0c, 0x51, /* OP1/OP0 normal, val = 1 (LNB power on) */
+ 0x0d, 0x82, /* DC offset compensation = on, beta_agc1 = 2 */
+ 0x0f, 0x92, /* AGC1R */
+ 0x10, 0x34, /* AGC2O */
+ 0x11, 0x84, /* TLSR */
+ 0x12, 0xb9, /* CFD */
+ 0x15, 0xc9, /* lock detector threshold */
+ 0x28, 0x00, /* out imp: normal, type: parallel, FEC mode: QPSK */
+ 0x33, 0xfc, /* RS control */
+ 0x34, 0x93, /* count viterbi bit errors per 2E18 bytes */
0xff, 0xff
};
@@ -100,11 +80,11 @@ static int alps_bsbe1_tuner_set_params(struct dvb_frontend* fe, struct dvb_front
if ((params->frequency < 950000) || (params->frequency > 2150000))
return -EINVAL;
- div = (params->frequency + (125 - 1)) / 125; // round correctly
+ div = params->frequency / 1000;
data[0] = (div >> 8) & 0x7f;
data[1] = div & 0xff;
- data[2] = 0x80 | ((div & 0x18000) >> 10) | 4;
- data[3] = (params->frequency > 1530000) ? 0xE0 : 0xE4;
+ data[2] = 0x80 | ((div & 0x18000) >> 10) | 0x1;
+ data[3] = 0xe0;
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
diff --git a/linux/drivers/media/dvb/frontends/bsru6.h b/linux/drivers/media/dvb/frontends/bsru6.h
index e231cd84b..45a6dfd8e 100644
--- a/linux/drivers/media/dvb/frontends/bsru6.h
+++ b/linux/drivers/media/dvb/frontends/bsru6.h
@@ -133,7 +133,7 @@ static struct stv0299_config alps_bsru6_config = {
.mclk = 88000000UL,
.invert = 1,
.skip_reinit = 0,
- .lock_output = STV0229_LOCKOUTPUT_1,
+ .lock_output = STV0299_LOCKOUTPUT_1,
.volt13_op0_op1 = STV0299_VOLT13_OP1,
.min_delay_ms = 100,
.set_symbol_rate = alps_bsru6_set_symbol_rate,
diff --git a/linux/drivers/media/dvb/frontends/cx22700.c b/linux/drivers/media/dvb/frontends/cx22700.c
index 11a4968f1..ace5cb171 100644
--- a/linux/drivers/media/dvb/frontends/cx22700.c
+++ b/linux/drivers/media/dvb/frontends/cx22700.c
@@ -73,13 +73,13 @@ static int cx22700_writereg (struct cx22700_state* state, u8 reg, u8 data)
u8 buf [] = { reg, data };
struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
ret = i2c_transfer (state->i2c, &msg, 1);
if (ret != 1)
printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
- __FUNCTION__, reg, data, ret);
+ __func__, reg, data, ret);
return (ret != 1) ? -1 : 0;
}
@@ -92,7 +92,7 @@ static int cx22700_readreg (struct cx22700_state* state, u8 reg)
struct i2c_msg msg [] = { { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 },
{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 } };
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
ret = i2c_transfer (state->i2c, msg, 2);
@@ -105,7 +105,7 @@ static int cx22700_set_inversion (struct cx22700_state* state, int inversion)
{
u8 val;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
switch (inversion) {
case INVERSION_AUTO:
@@ -127,7 +127,7 @@ static int cx22700_set_tps (struct cx22700_state *state, struct dvb_ofdm_paramet
static const u8 fec_tab [6] = { 0, 1, 2, 0, 3, 4 };
u8 val;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
if (p->code_rate_HP < FEC_1_2 || p->code_rate_HP > FEC_7_8)
return -EINVAL;
@@ -191,7 +191,7 @@ static int cx22700_get_tps (struct cx22700_state* state, struct dvb_ofdm_paramet
FEC_5_6, FEC_7_8 };
u8 val;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
if (!(cx22700_readreg(state, 0x07) & 0x20)) /* tps valid? */
return -EAGAIN;
diff --git a/linux/drivers/media/dvb/frontends/cx22700.h b/linux/drivers/media/dvb/frontends/cx22700.h
index 7ac33690c..4757a930c 100644
--- a/linux/drivers/media/dvb/frontends/cx22700.h
+++ b/linux/drivers/media/dvb/frontends/cx22700.h
@@ -38,7 +38,7 @@ extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
static inline struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_CX22700
diff --git a/linux/drivers/media/dvb/frontends/cx22702.c b/linux/drivers/media/dvb/frontends/cx22702.c
index 406c4cfa8..cc1db4e37 100644
--- a/linux/drivers/media/dvb/frontends/cx22702.c
+++ b/linux/drivers/media/dvb/frontends/cx22702.c
@@ -90,7 +90,7 @@ static int cx22702_writereg (struct cx22702_state* state, u8 reg, u8 data)
if (ret != 1)
printk("%s: writereg error (reg == 0x%02x, val == 0x%02x, ret == %i)\n",
- __FUNCTION__, reg, data, ret);
+ __func__, reg, data, ret);
return (ret != 1) ? -1 : 0;
}
@@ -108,7 +108,7 @@ static u8 cx22702_readreg (struct cx22702_state* state, u8 reg)
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2)
- printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
+ printk("%s: readreg error (ret == %i)\n", __func__, ret);
return b1[0];
}
@@ -195,7 +195,7 @@ static int cx22702_get_tps (struct cx22702_state *state, struct dvb_ofdm_paramet
static int cx22702_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
{
struct cx22702_state* state = fe->demodulator_priv;
- dprintk ("%s(%d)\n", __FUNCTION__, enable);
+ dprintk ("%s(%d)\n", __func__, enable);
if (enable)
return cx22702_writereg (state, 0x0D, cx22702_readreg(state, 0x0D) & 0xfe);
else
@@ -228,7 +228,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
cx22702_writereg(state, 0x0C, cx22702_readreg(state, 0x0C) &0xcf );
break;
default:
- dprintk ("%s: invalid bandwidth\n",__FUNCTION__);
+ dprintk ("%s: invalid bandwidth\n",__func__);
return -EINVAL;
}
@@ -250,7 +250,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
cx22702_writereg(state, 0x0B, cx22702_readreg(state, 0x0B) & 0xfc );
cx22702_writereg(state, 0x0C, (cx22702_readreg(state, 0x0C) & 0xBF) | 0x40 );
cx22702_writereg(state, 0x00, 0x01); /* Begin aquisition */
- dprintk("%s: Autodetecting\n",__FUNCTION__);
+ dprintk("%s: Autodetecting\n",__func__);
return 0;
}
@@ -261,7 +261,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
case QAM_16: val = (val&0xe7)|0x08; break;
case QAM_64: val = (val&0xe7)|0x10; break;
default:
- dprintk ("%s: invalid constellation\n",__FUNCTION__);
+ dprintk ("%s: invalid constellation\n",__func__);
return -EINVAL;
}
switch(p->u.ofdm.hierarchy_information) {
@@ -270,7 +270,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
case HIERARCHY_2: val = (val&0xf8)|2; break;
case HIERARCHY_4: val = (val&0xf8)|3; break;
default:
- dprintk ("%s: invalid hierarchy\n",__FUNCTION__);
+ dprintk ("%s: invalid hierarchy\n",__func__);
return -EINVAL;
}
cx22702_writereg (state, 0x06, val);
@@ -284,7 +284,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
case FEC_5_6: val = (val&0xc7)|0x18; break;
case FEC_7_8: val = (val&0xc7)|0x20; break;
default:
- dprintk ("%s: invalid code_rate_HP\n",__FUNCTION__);
+ dprintk ("%s: invalid code_rate_HP\n",__func__);
return -EINVAL;
}
switch(p->u.ofdm.code_rate_LP) {
@@ -295,7 +295,7 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
case FEC_5_6: val = (val&0xf8)|3; break;
case FEC_7_8: val = (val&0xf8)|4; break;
default:
- dprintk ("%s: invalid code_rate_LP\n",__FUNCTION__);
+ dprintk ("%s: invalid code_rate_LP\n",__func__);
return -EINVAL;
}
cx22702_writereg (state, 0x07, val);
@@ -307,14 +307,14 @@ static int cx22702_set_tps (struct dvb_frontend* fe, struct dvb_frontend_paramet
case GUARD_INTERVAL_1_8: val = (val&0xf3)|0x08; break;
case GUARD_INTERVAL_1_4: val = (val&0xf3)|0x0c; break;
default:
- dprintk ("%s: invalid guard_interval\n",__FUNCTION__);
+ dprintk ("%s: invalid guard_interval\n",__func__);
return -EINVAL;
}
switch(p->u.ofdm.transmission_mode) {
case TRANSMISSION_MODE_2K: val = (val&0xfc); break;
case TRANSMISSION_MODE_8K: val = (val&0xfc)|1; break;
default:
- dprintk ("%s: invalid transmission_mode\n",__FUNCTION__);
+ dprintk ("%s: invalid transmission_mode\n",__func__);
return -EINVAL;
}
cx22702_writereg(state, 0x08, val);
@@ -360,7 +360,7 @@ static int cx22702_read_status(struct dvb_frontend* fe, fe_status_t* status)
reg23 = cx22702_readreg (state, 0x23);
dprintk ("%s: status demod=0x%02x agc=0x%02x\n"
- ,__FUNCTION__,reg0A,reg23);
+ ,__func__,reg0A,reg23);
if(reg0A & 0x10) {
*status |= FE_HAS_LOCK;
diff --git a/linux/drivers/media/dvb/frontends/cx22702.h b/linux/drivers/media/dvb/frontends/cx22702.h
index 9cd64da6e..8af766a31 100644
--- a/linux/drivers/media/dvb/frontends/cx22702.h
+++ b/linux/drivers/media/dvb/frontends/cx22702.h
@@ -48,7 +48,7 @@ extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_CX22702
diff --git a/linux/drivers/media/dvb/frontends/cx24110.c b/linux/drivers/media/dvb/frontends/cx24110.c
index b03d8283c..87ae29db0 100644
--- a/linux/drivers/media/dvb/frontends/cx24110.c
+++ b/linux/drivers/media/dvb/frontends/cx24110.c
@@ -121,7 +121,7 @@ static int cx24110_writereg (struct cx24110_state* state, int reg, int data)
if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
dprintk ("%s: writereg error (err == %i, reg == 0x%02x,"
- " data == 0x%02x)\n", __FUNCTION__, err, reg, data);
+ " data == 0x%02x)\n", __func__, err, reg, data);
return -EREMOTEIO;
}
@@ -247,7 +247,7 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
static const u32 bands[]={5000000UL,15000000UL,90999000UL/2};
int i;
- dprintk("cx24110 debug: entering %s(%d)\n",__FUNCTION__,srate);
+ dprintk("cx24110 debug: entering %s(%d)\n",__func__,srate);
if (srate>90999000UL/2)
srate=90999000UL/2;
if (srate<500000)
@@ -358,7 +358,7 @@ static int cx24110_initfe(struct dvb_frontend* fe)
/* fixme (low): error handling */
int i;
- dprintk("%s: init chip\n", __FUNCTION__);
+ dprintk("%s: init chip\n", __func__);
for(i = 0; i < ARRAY_SIZE(cx24110_regdata); i++) {
cx24110_writereg(state, cx24110_regdata[i].reg, cx24110_regdata[i].data);
diff --git a/linux/drivers/media/dvb/frontends/cx24110.h b/linux/drivers/media/dvb/frontends/cx24110.h
index 0ca3af4db..1792adb23 100644
--- a/linux/drivers/media/dvb/frontends/cx24110.h
+++ b/linux/drivers/media/dvb/frontends/cx24110.h
@@ -48,7 +48,7 @@ extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_CX24110
diff --git a/linux/drivers/media/dvb/frontends/dib0070.h b/linux/drivers/media/dvb/frontends/dib0070.h
index 786e37d33..3eedfdf50 100644
--- a/linux/drivers/media/dvb/frontends/dib0070.h
+++ b/linux/drivers/media/dvb/frontends/dib0070.h
@@ -37,7 +37,20 @@ struct dib0070_config {
u8 flip_chip;
};
-extern struct dvb_frontend * dib0070_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct dib0070_config *cfg);
+#if defined(CONFIG_DVB_TUNER_DIB0070) || (defined(CONFIG_DVB_TUNER_DIB0070_MODULE) && defined(MODULE))
+extern struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
+ struct dib0070_config *cfg);
+#else
+static inline struct dvb_frontend *dib0070_attach(struct dvb_frontend *fe,
+ struct i2c_adapter *i2c,
+ struct dib0070_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
extern void dib0070_ctrl_agc_filter(struct dvb_frontend *, uint8_t open);
extern u16 dib0070_wbd_offset(struct dvb_frontend *);
diff --git a/linux/drivers/media/dvb/frontends/dib3000.h b/linux/drivers/media/dvb/frontends/dib3000.h
index a6d3854a6..ba917359f 100644
--- a/linux/drivers/media/dvb/frontends/dib3000.h
+++ b/linux/drivers/media/dvb/frontends/dib3000.h
@@ -48,7 +48,7 @@ extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config
static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_DIB3000MB
diff --git a/linux/drivers/media/dvb/frontends/dib3000mc.h b/linux/drivers/media/dvb/frontends/dib3000mc.h
index 72d475760..4142ed7a4 100644
--- a/linux/drivers/media/dvb/frontends/dib3000mc.h
+++ b/linux/drivers/media/dvb/frontends/dib3000mc.h
@@ -44,7 +44,7 @@ extern struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i
#else
static inline struct dvb_frontend * dib3000mc_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib3000mc_config *cfg)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_DIB3000MC
diff --git a/linux/drivers/media/dvb/frontends/dib7000p.c b/linux/drivers/media/dvb/frontends/dib7000p.c
index 9b6702b70..c74d373b6 100644
--- a/linux/drivers/media/dvb/frontends/dib7000p.c
+++ b/linux/drivers/media/dvb/frontends/dib7000p.c
@@ -1194,7 +1194,7 @@ static int dib7000p_set_frontend(struct dvb_frontend* fe,
ret = dib7000p_tune(fe, fep);
/* make this a config parameter */
- dib7000p_set_output_mode(state, OUTMODE_MPEG2_FIFO);
+ dib7000p_set_output_mode(state, state->cfg.output_mode);
return ret;
}
@@ -1356,6 +1356,12 @@ struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr,
st->gpio_val = cfg->gpio_val;
st->gpio_dir = cfg->gpio_dir;
+ /* Ensure the output mode remains at the previous default if it's
+ * not specifically set by the caller.
+ */
+ if (st->cfg.output_mode != OUTMODE_MPEG2_SERIAL)
+ st->cfg.output_mode = OUTMODE_MPEG2_FIFO;
+
demod = &st->demod;
demod->demodulator_priv = st;
memcpy(&st->demod.ops, &dib7000p_ops, sizeof(struct dvb_frontend_ops));
diff --git a/linux/drivers/media/dvb/frontends/dib7000p.h b/linux/drivers/media/dvb/frontends/dib7000p.h
index eefcac8b5..07c4d12ed 100644
--- a/linux/drivers/media/dvb/frontends/dib7000p.h
+++ b/linux/drivers/media/dvb/frontends/dib7000p.h
@@ -31,11 +31,26 @@ struct dib7000p_config {
u8 spur_protect;
int (*agc_control) (struct dvb_frontend *, u8 before);
+
+ u8 output_mode;
};
#define DEFAULT_DIB7000P_I2C_ADDRESS 18
-extern struct dvb_frontend * dib7000p_attach(struct i2c_adapter *i2c_adap, u8 i2c_addr, struct dib7000p_config *cfg);
+#if defined(CONFIG_DVB_DIB7000P) || (defined(CONFIG_DVB_DIB7000P_MODULE) && defined(MODULE))
+extern struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr,
+ struct dib7000p_config *cfg);
+#else
+static inline struct dvb_frontend *dib7000p_attach(struct i2c_adapter *i2c_adap,
+ u8 i2c_addr,
+ struct dib7000p_config *cfg)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif
+
extern int dib7000p_i2c_enumeration(struct i2c_adapter *i2c, int no_of_demods, u8 default_addr, struct dib7000p_config cfg[]);
extern struct i2c_adapter * dib7000p_get_i2c_master(struct dvb_frontend *, enum dibx000_i2c_interface, int);
diff --git a/linux/drivers/media/dvb/frontends/drx397xD.c b/linux/drivers/media/dvb/frontends/drx397xD.c
new file mode 100644
index 000000000..327fff4b8
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/drx397xD.c
@@ -0,0 +1,1583 @@
+/*
+ * Driver for Micronas drx397xD demodulator
+ *
+ * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#define DEBUG /* uncomment if you want debugging output */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/device.h>
+#include <linux/delay.h>
+#include <linux/string.h>
+#include <linux/firmware.h>
+#include <asm/div64.h>
+
+#include "dvb_frontend.h"
+#include "drx397xD.h"
+#include "compat.h"
+
+static const char mod_name[] = "drx397xD";
+
+#define MAX_CLOCK_DRIFT 200 /* maximal 200 PPM allowed */
+
+#define F_SET_0D0h 1
+#define F_SET_0D4h 2
+
+typedef enum fw_ix {
+#define _FW_ENTRY(a, b) b
+#include "drx397xD_fw.h"
+} fw_ix_t;
+
+/* chip specifics */
+struct drx397xD_state {
+ struct i2c_adapter *i2c;
+ struct dvb_frontend frontend;
+ struct drx397xD_config config;
+ fw_ix_t chip_rev;
+ int flags;
+ u32 bandwidth_parm; /* internal bandwidth conversions */
+ u32 f_osc; /* w90: actual osc frequency [Hz] */
+};
+
+/*******************************************************************************
+ * Firmware
+ ******************************************************************************/
+
+static const char *blob_name[] = {
+#define _BLOB_ENTRY(a, b) a
+#include "drx397xD_fw.h"
+};
+
+typedef enum blob_ix {
+#define _BLOB_ENTRY(a, b) b
+#include "drx397xD_fw.h"
+} blob_ix_t;
+
+static struct {
+ const char *name;
+ const struct firmware *file;
+ rwlock_t lock;
+ int refcnt;
+ u8 *data[ARRAY_SIZE(blob_name)];
+} fw[] = {
+#define _FW_ENTRY(a, b) { \
+ .name = a, \
+ .file = 0, \
+ .lock = RW_LOCK_UNLOCKED, \
+ .refcnt = 0, \
+ .data = { } }
+#include "drx397xD_fw.h"
+};
+
+/* use only with writer lock aquired */
+static void _drx_release_fw(struct drx397xD_state *s, fw_ix_t ix)
+{
+ memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
+ if (fw[ix].file)
+ release_firmware(fw[ix].file);
+}
+
+static void drx_release_fw(struct drx397xD_state *s)
+{
+ fw_ix_t ix = s->chip_rev;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ write_lock(&fw[ix].lock);
+ if (fw[ix].refcnt) {
+ fw[ix].refcnt--;
+ if (fw[ix].refcnt == 0)
+ _drx_release_fw(s, ix);
+ }
+ write_unlock(&fw[ix].lock);
+}
+
+static int drx_load_fw(struct drx397xD_state *s, fw_ix_t ix)
+{
+ u8 *data;
+ size_t size, len;
+ int i = 0, j, rc = -EINVAL;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ if (ix < 0 || ix >= ARRAY_SIZE(fw))
+ return -EINVAL;
+ s->chip_rev = ix;
+
+ write_lock(&fw[ix].lock);
+ if (fw[ix].file) {
+ rc = 0;
+ goto exit_ok;
+ }
+ memset(&fw[ix].data[0], 0, sizeof(fw[0].data));
+
+ if (request_firmware(&fw[ix].file, fw[ix].name, &s->i2c->dev) != 0) {
+ printk(KERN_ERR "%s: Firmware \"%s\" not available\n",
+ mod_name, fw[ix].name);
+ rc = -ENOENT;
+ goto exit_err;
+ }
+
+ if (!fw[ix].file->data || fw[ix].file->size < 10)
+ goto exit_corrupt;
+
+ data = fw[ix].file->data;
+ size = fw[ix].file->size;
+
+ if (data[i++] != 2) /* check firmware version */
+ goto exit_corrupt;
+
+ do {
+ switch (data[i++]) {
+ case 0x00: /* bytecode */
+ if (i >= size)
+ break;
+ i += data[i];
+ case 0x01: /* reset */
+ case 0x02: /* sleep */
+ i++;
+ break;
+ case 0xfe: /* name */
+ len = strnlen(&data[i], size - i);
+ if (i + len + 1 >= size)
+ goto exit_corrupt;
+ if (data[i + len + 1] != 0)
+ goto exit_corrupt;
+ for (j = 0; j < ARRAY_SIZE(blob_name); j++) {
+ if (strcmp(blob_name[j], &data[i]) == 0) {
+ fw[ix].data[j] = &data[i + len + 1];
+ pr_debug("Loading %s\n", blob_name[j]);
+ }
+ }
+ i += len + 1;
+ break;
+ case 0xff: /* file terminator */
+ if (i == size) {
+ rc = 0;
+ goto exit_ok;
+ }
+ default:
+ goto exit_corrupt;
+ }
+ } while (i < size);
+ exit_corrupt:
+ printk(KERN_ERR "%s: Firmware is corrupt\n", mod_name);
+ exit_err:
+ _drx_release_fw(s, ix);
+ fw[ix].refcnt--;
+ exit_ok:
+ fw[ix].refcnt++;
+ write_unlock(&fw[ix].lock);
+ return rc;
+}
+
+/*******************************************************************************
+ * i2c bus IO
+ ******************************************************************************/
+
+static int write_fw(struct drx397xD_state *s, blob_ix_t ix)
+{
+ struct i2c_msg msg = {.addr = s->config.demod_address,.flags = 0 };
+ u8 *data;
+ int len, rc = 0, i = 0;
+
+ if (ix < 0 || ix >= ARRAY_SIZE(blob_name)) {
+ pr_debug("%s drx_fw_ix_t out of range\n", __FUNCTION__);
+ return -EINVAL;
+ }
+ pr_debug("%s %s\n", __FUNCTION__, blob_name[ix]);
+
+ read_lock(&fw[s->chip_rev].lock);
+ data = fw[s->chip_rev].data[ix];
+ if (!data) {
+ rc = -EINVAL;
+ goto exit_rc;
+ }
+
+ for (;;) {
+ switch (data[i++]) {
+ case 0: /* bytecode */
+ len = data[i++];
+ msg.len = len;
+ msg.buf = &data[i];
+ if (i2c_transfer(s->i2c, &msg, 1) != 1) {
+ rc = -EIO;
+ goto exit_rc;
+ }
+ i += len;
+ break;
+ case 1: /* reset */
+ case 2: /* sleep */
+ i++;
+ break;
+ default:
+ goto exit_rc;
+ }
+ }
+ exit_rc:
+ read_unlock(&fw[s->chip_rev].lock);
+ return 0;
+}
+
+/* Function is not endian safe, use the RD16 wrapper below */
+static int _read16(struct drx397xD_state *s, u32 i2c_adr)
+{
+ int rc;
+ u8 a[4];
+ u16 v;
+ struct i2c_msg msg[2] = {
+ {
+ .addr = s->config.demod_address,
+ .flags = 0,
+ .buf = a,
+ .len = sizeof(a)
+ }
+ , {
+ .addr = s->config.demod_address,
+ .flags = I2C_M_RD,
+ .buf = (u8 *) & v,
+ .len = sizeof(v)
+ }
+ };
+
+ *(u32 *) a = i2c_adr;
+
+ rc = i2c_transfer(s->i2c, msg, 2);
+ if (rc != 2)
+ return -EIO;
+
+ return le16_to_cpu(v);
+}
+
+/* Function is not endian safe, use the WR16.. wrappers below */
+static int _write16(struct drx397xD_state *s, u32 i2c_adr, u16 val)
+{
+ u8 a[6];
+ int rc;
+ struct i2c_msg msg = {
+ .addr = s->config.demod_address,
+ .flags = 0,
+ .buf = a,
+ .len = sizeof(a)
+ };
+
+ *(u32 *) a = i2c_adr;
+ *(u16 *) & a[4] = val;
+
+ rc = i2c_transfer(s->i2c, &msg, 1);
+ if (rc != 1)
+ return -EIO;
+ return 0;
+}
+
+#define WR16(ss,adr, val) \
+ _write16(ss, I2C_ADR_C0(adr), cpu_to_le16(val))
+#define WR16_E0(ss,adr, val) \
+ _write16(ss, I2C_ADR_E0(adr), cpu_to_le16(val))
+#define RD16(ss,adr) \
+ _read16(ss, I2C_ADR_C0(adr))
+
+#define EXIT_RC( cmd ) if ( (rc = (cmd)) < 0) goto exit_rc
+
+/*******************************************************************************
+ * Tuner callback
+ ******************************************************************************/
+
+static int PLL_Set(struct drx397xD_state *s,
+ struct dvb_frontend_parameters *fep, int *df_tuner)
+{
+ struct dvb_frontend *fe = &s->frontend;
+ u32 f_tuner, f = fep->frequency;
+ int rc;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ if ((f > s->frontend.ops.tuner_ops.info.frequency_max) ||
+ (f < s->frontend.ops.tuner_ops.info.frequency_min))
+ return -EINVAL;
+
+ *df_tuner = 0;
+ if (!s->frontend.ops.tuner_ops.set_params ||
+ !s->frontend.ops.tuner_ops.get_frequency)
+ return -ENOSYS;
+
+ rc = s->frontend.ops.tuner_ops.set_params(fe, fep);
+ if (rc < 0)
+ return rc;
+
+ rc = s->frontend.ops.tuner_ops.get_frequency(fe, &f_tuner);
+ if (rc < 0)
+ return rc;
+
+ *df_tuner = f_tuner - f;
+ pr_debug("%s requested %d [Hz] tuner %d [Hz]\n", __FUNCTION__, f,
+ f_tuner);
+
+ return 0;
+}
+
+/*******************************************************************************
+ * Demodulator helper functions
+ ******************************************************************************/
+
+static int SC_WaitForReady(struct drx397xD_state *s)
+{
+ int cnt = 1000;
+ int rc;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ while (cnt--) {
+ rc = RD16(s, 0x820043);
+ if (rc == 0)
+ return 0;
+ }
+ return -1;
+}
+
+static int SC_SendCommand(struct drx397xD_state *s, int cmd)
+{
+ int rc;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ WR16(s, 0x820043, cmd);
+ SC_WaitForReady(s);
+ rc = RD16(s, 0x820042);
+ if ((rc & 0xffff) == 0xffff)
+ return -1;
+ return 0;
+}
+
+static int HI_Command(struct drx397xD_state *s, u16 cmd)
+{
+ int rc, cnt = 1000;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ rc = WR16(s, 0x420032, cmd);
+ if (rc < 0)
+ return rc;
+
+ do {
+ rc = RD16(s, 0x420032);
+ if (rc == 0) {
+ rc = RD16(s, 0x420031);
+ return rc;
+ }
+ if (rc < 0)
+ return rc;
+ } while (--cnt);
+ return rc;
+}
+
+static int HI_CfgCommand(struct drx397xD_state *s)
+{
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ WR16(s, 0x420033, 0x3973);
+ WR16(s, 0x420034, s->config.w50); // code 4, log 4
+ WR16(s, 0x420035, s->config.w52); // code 15, log 9
+ WR16(s, 0x420036, s->config.demod_address << 1);
+ WR16(s, 0x420037, s->config.w56); // code (set_i2c ?? initX 1 ), log 1
+// WR16(s, 0x420033, 0x3973);
+ if ((s->config.w56 & 8) == 0)
+ return HI_Command(s, 3);
+ return WR16(s, 0x420032, 0x3);
+}
+
+static const u8 fastIncrDecLUT_15273[] = {
+ 0x0e, 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x12, 0x13, 0x14,
+ 0x15, 0x16, 0x17, 0x18, 0x1a, 0x1b, 0x1c, 0x1d, 0x1f
+};
+
+static const u8 slowIncrDecLUT_15272[] = {
+ 3, 4, 4, 5, 6
+};
+
+static int SetCfgIfAgc(struct drx397xD_state *s, struct drx397xD_CfgIfAgc *agc)
+{
+ u16 w06 = agc->w06;
+ u16 w08 = agc->w08;
+ u16 w0A = agc->w0A;
+ u16 w0C = agc->w0C;
+ int quot, rem, i, rc = -EINVAL;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ if (agc->w04 > 0x3ff)
+ goto exit_rc;
+
+ if (agc->d00 == 1) {
+ EXIT_RC(RD16(s, 0x0c20010));
+ rc &= ~0x10;
+ EXIT_RC(WR16(s, 0x0c20010, rc));
+ return WR16(s, 0x0c20030, agc->w04 & 0x7ff);
+ }
+
+ if (agc->d00 != 0)
+ goto exit_rc;
+ if (w0A < w08)
+ goto exit_rc;
+ if (w0A > 0x3ff)
+ goto exit_rc;
+ if (w0C > 0x3ff)
+ goto exit_rc;
+ if (w06 > 0x3ff)
+ goto exit_rc;
+
+ EXIT_RC(RD16(s, 0x0c20010));
+ rc |= 0x10;
+ EXIT_RC(WR16(s, 0x0c20010, rc));
+
+ EXIT_RC(WR16(s, 0x0c20025, (w06 >> 1) & 0x1ff));
+ EXIT_RC(WR16(s, 0x0c20031, (w0A - w08) >> 1));
+ EXIT_RC(WR16(s, 0x0c20032, ((w0A + w08) >> 1) - 0x1ff));
+
+ quot = w0C / 113;
+ rem = w0C % 113;
+ if (quot <= 8) {
+ quot = 8 - quot;
+ } else {
+ quot = 0;
+ rem += 113;
+ }
+
+ EXIT_RC(WR16(s, 0x0c20024, quot));
+
+ i = fastIncrDecLUT_15273[rem / 8];
+ EXIT_RC(WR16(s, 0x0c2002d, i));
+ EXIT_RC(WR16(s, 0x0c2002e, i));
+
+ i = slowIncrDecLUT_15272[rem / 28];
+ EXIT_RC(WR16(s, 0x0c2002b, i));
+ rc = WR16(s, 0x0c2002c, i);
+ exit_rc:
+ return rc;
+}
+
+static int SetCfgRfAgc(struct drx397xD_state *s, struct drx397xD_CfgRfAgc *agc)
+{
+ u16 w04 = agc->w04;
+ u16 w06 = agc->w06;
+ int rc = -1;
+
+ pr_debug("%s %d 0x%x 0x%x\n", __FUNCTION__, agc->d00, w04, w06);
+
+ if (w04 > 0x3ff)
+ goto exit_rc;
+
+ switch (agc->d00) {
+ case 1:
+ if (w04 == 0x3ff)
+ w04 = 0x400;
+
+ EXIT_RC(WR16(s, 0x0c20036, w04));
+ s->config.w9C &= ~2;
+ EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
+ EXIT_RC(RD16(s, 0x0c20010));
+ rc &= 0xbfdf;
+ EXIT_RC(WR16(s, 0x0c20010, rc));
+ EXIT_RC(RD16(s, 0x0c20013));
+ rc &= ~2;
+ break;
+ case 0:
+ // loc_8000659
+ s->config.w9C &= ~2;
+ EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
+ EXIT_RC(RD16(s, 0x0c20010));
+ rc &= 0xbfdf;
+ rc |= 0x4000;
+ EXIT_RC(WR16(s, 0x0c20010, rc));
+ EXIT_RC(WR16(s, 0x0c20051, (w06 >> 4) & 0x3f));
+ EXIT_RC(RD16(s, 0x0c20013));
+ rc &= ~2;
+ break;
+ default:
+ s->config.w9C |= 2;
+ EXIT_RC(WR16(s, 0x0c20015, s->config.w9C));
+ EXIT_RC(RD16(s, 0x0c20010));
+ rc &= 0xbfdf;
+ EXIT_RC(WR16(s, 0x0c20010, rc));
+
+ EXIT_RC(WR16(s, 0x0c20036, 0));
+
+ EXIT_RC(RD16(s, 0x0c20013));
+ rc |= 2;
+ }
+ rc = WR16(s, 0x0c20013, rc);
+ exit_rc:
+ return rc;
+}
+
+static int GetLockStatus(struct drx397xD_state *s, int *lockstat)
+{
+ int rc;
+
+ *lockstat = 0;
+
+ rc = RD16(s, 0x082004b);
+ if (rc < 0)
+ return rc;
+
+ if (s->config.d60 != 2)
+ return 0;
+
+ if ((rc & 7) == 7)
+ *lockstat |= 1;
+ if ((rc & 3) == 3)
+ *lockstat |= 2;
+ if (rc & 1)
+ *lockstat |= 4;
+ return 0;
+}
+
+static int CorrectSysClockDeviation(struct drx397xD_state *s)
+{
+ int rc = -EINVAL;
+ int lockstat;
+ u32 clk, clk_limit;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ if (s->config.d5C == 0) {
+ EXIT_RC(WR16(s, 0x08200e8, 0x010));
+ EXIT_RC(WR16(s, 0x08200e9, 0x113));
+ s->config.d5C = 1;
+ return rc;
+ }
+ if (s->config.d5C != 1)
+ goto exit_rc;
+
+ rc = RD16(s, 0x0820048);
+
+ rc = GetLockStatus(s, &lockstat);
+ if (rc < 0)
+ goto exit_rc;
+ if ((lockstat & 1) == 0)
+ goto exit_rc;
+
+ EXIT_RC(WR16(s, 0x0420033, 0x200));
+ EXIT_RC(WR16(s, 0x0420034, 0xc5));
+ EXIT_RC(WR16(s, 0x0420035, 0x10));
+ EXIT_RC(WR16(s, 0x0420036, 0x1));
+ EXIT_RC(WR16(s, 0x0420037, 0xa));
+ EXIT_RC(HI_Command(s, 6));
+ EXIT_RC(RD16(s, 0x0420040));
+ clk = rc;
+ EXIT_RC(RD16(s, 0x0420041));
+ clk |= rc << 16;
+
+ if (clk <= 0x26ffff)
+ goto exit_rc;
+ if (clk > 0x610000)
+ goto exit_rc;
+
+ if (!s->bandwidth_parm)
+ return -EINVAL;
+
+ /* round & convert to Hz */
+ clk = ((u64) (clk + 0x800000) * s->bandwidth_parm + (1 << 20)) >> 21;
+ clk_limit = s->config.f_osc * MAX_CLOCK_DRIFT / 1000;
+
+ if (clk - s->config.f_osc * 1000 + clk_limit <= 2 * clk_limit) {
+ s->f_osc = clk;
+ pr_debug("%s: osc %d %d [Hz]\n", __FUNCTION__,
+ s->config.f_osc * 1000, clk - s->config.f_osc * 1000);
+ }
+ rc = WR16(s, 0x08200e8, 0);
+ exit_rc:
+ return rc;
+}
+
+static int ConfigureMPEGOutput(struct drx397xD_state *s, int type)
+{
+ int rc, si, bp;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ si = s->config.wA0;
+ if (s->config.w98 == 0) {
+ si |= 1;
+ bp = 0;
+ } else {
+ si &= ~1;
+ bp = 0x200;
+ }
+ if (s->config.w9A == 0) {
+ si |= 0x80;
+ } else {
+ si &= ~0x80;
+ }
+
+ EXIT_RC(WR16(s, 0x2150045, 0));
+ EXIT_RC(WR16(s, 0x2150010, si));
+ EXIT_RC(WR16(s, 0x2150011, bp));
+ rc = WR16(s, 0x2150012, (type == 0 ? 0xfff : 0));
+ exit_rc:
+ return rc;
+}
+
+static int drx_tune(struct drx397xD_state *s,
+ struct dvb_frontend_parameters *fep)
+{
+ u16 v22 = 0;
+ u16 v1C = 0;
+ u16 v1A = 0;
+ u16 v18 = 0;
+ u32 edi = 0, ebx = 0, ebp = 0, edx = 0;
+ u16 v20 = 0, v1E = 0, v16 = 0, v14 = 0, v12 = 0, v10 = 0, v0E = 0;
+
+ int rc, df_tuner;
+ int a, b, c, d;
+ pr_debug("%s %d\n", __FUNCTION__, s->config.d60);
+
+ if (s->config.d60 != 2)
+ goto set_tuner;
+ rc = CorrectSysClockDeviation(s);
+ if (rc < 0)
+ goto set_tuner;
+
+ s->config.d60 = 1;
+ rc = ConfigureMPEGOutput(s, 0);
+ if (rc < 0)
+ goto set_tuner;
+#if 0
+
+ if (s->chip_rev != DRXD_FW_B1) {
+ rc = WR16(s, 0x2150000, 0);
+ if (rc < 0)
+ goto loc_800111A;
+ rc = WR16(s, 0x2110000, 0);
+ if (rc < 0)
+ goto loc_800111A;
+ rc = WR16(s, 0x0800000, 0);
+ if (rc < 0)
+ goto loc_800111A;
+ rc = WR16(s, 0x2800000, 0);
+ } else {
+ rc = WR16(s, 0x0800000, 0);
+ if (rc < 0)
+ goto loc_800111A;
+ rc = WR16(s, 0x2800000, 0);
+ if (rc < 0)
+ goto loc_800111A;
+ rc = WR16(s, 0x1000000, 0);
+ if (rc < 0)
+ goto loc_800111A;
+ rc = WR16(s, 0x1400000, 0);
+ if (rc < 0)
+ goto loc_800111A;
+ rc = WR16(s, 0x1800000, 0);
+ if (rc < 0)
+ goto loc_800111A;
+ rc = WR16(s, 0x1c00000, 0);
+ if (rc < 0)
+ goto loc_800111A;
+ rc = WR16(s, 0x2000000, 0);
+ }
+ loc_800111A:
+#endif
+ set_tuner:
+
+ rc = PLL_Set(s, fep, &df_tuner);
+ if (rc < 0) {
+ printk(KERN_ERR "Error in pll_set\n");
+ goto exit_rc;
+ }
+ msleep(200);
+
+ a = rc = RD16(s, 0x2150016);
+ if (rc < 0)
+ goto exit_rc;
+ b = rc = RD16(s, 0x2150010);
+ if (rc < 0)
+ goto exit_rc;
+ c = rc = RD16(s, 0x2150034);
+ if (rc < 0)
+ goto exit_rc;
+ d = rc = RD16(s, 0x2150035);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2150014, c);
+ rc = WR16(s, 0x2150015, d);
+ rc = WR16(s, 0x2150010, 0);
+ rc = WR16(s, 0x2150000, 2);
+ rc = WR16(s, 0x2150036, 0x0fff);
+ rc = WR16(s, 0x2150016, a);
+
+ rc = WR16(s, 0x2150010, 2);
+ rc = WR16(s, 0x2150007, 0);
+ rc = WR16(s, 0x2150000, 1);
+ rc = WR16(s, 0x2110000, 0);
+ rc = WR16(s, 0x0800000, 0);
+ rc = WR16(s, 0x2800000, 0);
+ rc = WR16(s, 0x2110010, 0x664);
+
+ rc = write_fw(s, DRXD_ResetECRAM);
+ rc = WR16(s, 0x2110000, 1);
+
+ rc = write_fw(s, DRXD_InitSC);
+ if (rc < 0)
+ goto exit_rc;
+
+ rc = SetCfgIfAgc(s, &s->config.ifagc);
+ if (rc < 0)
+ goto exit_rc;
+
+ rc = SetCfgRfAgc(s, &s->config.rfagc);
+ if (rc < 0)
+ goto exit_rc;
+
+ if (fep->u.ofdm.transmission_mode != TRANSMISSION_MODE_2K)
+ v22 = 1;
+ switch (fep->u.ofdm.transmission_mode) {
+ case TRANSMISSION_MODE_8K:
+ edi = 1;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+
+ rc = WR16(s, 0x2010010, 0);
+ if (rc < 0)
+ break;
+ v1C = 0x63;
+ v1A = 0x53;
+ v18 = 0x43;
+ break;
+ default:
+ edi = 0;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+
+ rc = WR16(s, 0x2010010, 1);
+ if (rc < 0)
+ break;
+
+ v1C = 0x61;
+ v1A = 0x47;
+ v18 = 0x41;
+ }
+
+ switch (fep->u.ofdm.guard_interval) {
+ case GUARD_INTERVAL_1_4:
+ edi |= 0x0c;
+ break;
+ case GUARD_INTERVAL_1_8:
+ edi |= 0x08;
+ break;
+ case GUARD_INTERVAL_1_16:
+ edi |= 0x04;
+ break;
+ case GUARD_INTERVAL_1_32:
+ break;
+ default:
+ v22 |= 2;
+ }
+
+ ebx = 0;
+ ebp = 0;
+ v20 = 0;
+ v1E = 0;
+ v16 = 0;
+ v14 = 0;
+ v12 = 0;
+ v10 = 0;
+ v0E = 0;
+
+ switch (fep->u.ofdm.hierarchy_information) {
+ case HIERARCHY_1:
+ edi |= 0x40;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x1c10047, 1);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010012, 1);
+ if (rc < 0)
+ goto exit_rc;
+ ebx = 0x19f;
+ ebp = 0x1fb;
+ v20 = 0x0c0;
+ v1E = 0x195;
+ v16 = 0x1d6;
+ v14 = 0x1ef;
+ v12 = 4;
+ v10 = 5;
+ v0E = 5;
+ break;
+ case HIERARCHY_2:
+ edi |= 0x80;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x1c10047, 2);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010012, 2);
+ if (rc < 0)
+ goto exit_rc;
+ ebx = 0x08f;
+ ebp = 0x12f;
+ v20 = 0x0c0;
+ v1E = 0x11e;
+ v16 = 0x1d6;
+ v14 = 0x15e;
+ v12 = 4;
+ v10 = 5;
+ v0E = 5;
+ break;
+ case HIERARCHY_4:
+ edi |= 0xc0;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x1c10047, 3);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010012, 3);
+ if (rc < 0)
+ goto exit_rc;
+ ebx = 0x14d;
+ ebp = 0x197;
+ v20 = 0x0c0;
+ v1E = 0x1ce;
+ v16 = 0x1d6;
+ v14 = 0x11a;
+ v12 = 4;
+ v10 = 6;
+ v0E = 5;
+ break;
+ default:
+ v22 |= 8;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x1c10047, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010012, 0);
+ if (rc < 0)
+ goto exit_rc;
+ // QPSK QAM16 QAM64
+ ebx = 0x19f; // 62
+ ebp = 0x1fb; // 15
+ v20 = 0x16a; // 62
+ v1E = 0x195; // 62
+ v16 = 0x1bb; // 15
+ v14 = 0x1ef; // 15
+ v12 = 5; // 16
+ v10 = 5; // 16
+ v0E = 5; // 16
+ }
+
+ switch (fep->u.ofdm.constellation) {
+ default:
+ v22 |= 4;
+ case QPSK:
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+
+ rc = WR16(s, 0x1c10046, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010011, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001a, 0x10);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001b, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001c, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10062, v20);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c1002a, v1C);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10015, v16);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10016, v12);
+ if (rc < 0)
+ goto exit_rc;
+ break;
+ case QAM_16:
+ edi |= 0x10;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+
+ rc = WR16(s, 0x1c10046, 1);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010011, 1);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001a, 0x10);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001b, 4);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001c, 0);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10062, v1E);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c1002a, v1A);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10015, v14);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10016, v10);
+ if (rc < 0)
+ goto exit_rc;
+ break;
+ case QAM_64:
+ edi |= 0x20;
+ rc = WR16(s, 0x1c10046, 2);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x2010011, 2);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001a, 0x20);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001b, 8);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x201001c, 2);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10062, ebx);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c1002a, v18);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10015, ebp);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x1c10016, v0E);
+ if (rc < 0)
+ goto exit_rc;
+ break;
+ }
+
+ if (s->config.s20d24 == 1) {
+ rc = WR16(s, 0x2010013, 0);
+ } else {
+ rc = WR16(s, 0x2010013, 1);
+ edi |= 0x1000;
+ }
+
+ switch (fep->u.ofdm.code_rate_HP) {
+ default:
+ v22 |= 0x10;
+ case FEC_1_2:
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x2090011, 0);
+ break;
+ case FEC_2_3:
+ edi |= 0x200;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x2090011, 1);
+ break;
+ case FEC_3_4:
+ edi |= 0x400;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x2090011, 2);
+ break;
+ case FEC_5_6: /* 5 */
+ edi |= 0x600;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x2090011, 3);
+ break;
+ case FEC_7_8: /* 7 */
+ edi |= 0x800;
+ if (s->chip_rev == DRXD_FW_B1)
+ break;
+ rc = WR16(s, 0x2090011, 4);
+ break;
+ };
+ if (rc < 0)
+ goto exit_rc;
+
+ switch (fep->u.ofdm.bandwidth) {
+ default:
+ rc = -EINVAL;
+ goto exit_rc;
+ case BANDWIDTH_8_MHZ: /* 0 */
+ case BANDWIDTH_AUTO:
+ rc = WR16(s, 0x0c2003f, 0x32);
+ s->bandwidth_parm = ebx = 0x8b8249; // 9142857
+ edx = 0;
+ break;
+ case BANDWIDTH_7_MHZ:
+ rc = WR16(s, 0x0c2003f, 0x3b);
+ s->bandwidth_parm = ebx = 0x7a1200; // 8000000
+ edx = 0x4807;
+ break;
+ case BANDWIDTH_6_MHZ:
+ rc = WR16(s, 0x0c2003f, 0x47);
+ s->bandwidth_parm = ebx = 0x68a1b6; // 6857142
+ edx = 0x0f07;
+ break;
+ };
+
+ if (rc < 0)
+ goto exit_rc;
+
+ rc = WR16(s, 0x08200ec, edx);
+ if (rc < 0)
+ goto exit_rc;
+
+ rc = RD16(s, 0x0820050);
+ if (rc < 0)
+ goto exit_rc;
+ rc = WR16(s, 0x0820050, rc);
+
+ {
+ /* Configure bandwidth specific factor */
+ ebx = div64_u64(((u64) (s->f_osc) << 21) + (ebx >> 1),
+ (u64)ebx) - 0x800000;
+ EXIT_RC(WR16(s, 0x0c50010, ebx & 0xffff));
+ EXIT_RC(WR16(s, 0x0c50011, ebx >> 16));
+
+ /* drx397xD oscillator calibration */
+ ebx = div64_u64(((u64) (s->config.f_if + df_tuner) << 28) +
+ (s->f_osc >> 1), (u64)s->f_osc);
+ }
+ ebx &= 0xfffffff;
+ if (fep->inversion == INVERSION_ON)
+ ebx = 0x10000000 - ebx;
+
+ EXIT_RC(WR16(s, 0x0c30010, ebx & 0xffff));
+ EXIT_RC(WR16(s, 0x0c30011, ebx >> 16));
+
+ EXIT_RC(WR16(s, 0x0800000, 1));
+ EXIT_RC(RD16(s, 0x0800000));
+
+#if 0
+ rc = WR16(s, 0x0810000, 1);
+ if (rc < 0)
+ goto exit_rc;
+#endif
+
+ EXIT_RC(SC_WaitForReady(s));
+ EXIT_RC(WR16(s, 0x0820042, 0));
+ EXIT_RC(WR16(s, 0x0820041, v22));
+ EXIT_RC(WR16(s, 0x0820040, edi));
+ EXIT_RC(SC_SendCommand(s, 3));
+
+ rc = RD16(s, 0x0800000);
+
+ SC_WaitForReady(s);
+ WR16(s, 0x0820042, 0);
+ WR16(s, 0x0820041, 1);
+ WR16(s, 0x0820040, 1);
+ SC_SendCommand(s, 1);
+
+// rc = WR16(s, 0x2150000, 1);
+// if (rc < 0) goto exit_rc;
+
+ rc = WR16(s, 0x2150000, 2);
+ rc = WR16(s, 0x2150016, a);
+ rc = WR16(s, 0x2150010, 4);
+ rc = WR16(s, 0x2150036, 0);
+ rc = WR16(s, 0x2150000, 1);
+ s->config.d60 = 2;
+ exit_rc:
+ return rc;
+}
+
+/*******************************************************************************
+ * DVB interface
+ ******************************************************************************/
+
+static int drx397x_init(struct dvb_frontend *fe)
+{
+ struct drx397xD_state *s = fe->demodulator_priv;
+ int rc;
+
+ pr_debug("%s\n", __FUNCTION__);
+
+ s->config.rfagc.d00 = 2; /* 0x7c */
+ s->config.rfagc.w04 = 0;
+ s->config.rfagc.w06 = 0x3ff;
+
+ s->config.ifagc.d00 = 0; /* 0x68 */
+ s->config.ifagc.w04 = 0;
+ s->config.ifagc.w06 = 140;
+ s->config.ifagc.w08 = 0;
+ s->config.ifagc.w0A = 0x3ff;
+ s->config.ifagc.w0C = 0x388;
+
+ /* for signal strenght calculations */
+ s->config.ss76 = 820;
+ s->config.ss78 = 2200;
+ s->config.ss7A = 150;
+
+ /* HI_CfgCommand */
+ s->config.w50 = 4;
+ s->config.w52 = 9; // 0xf;
+
+ s->config.f_if = 42800000; /* d14: intermediate frequency [Hz] */
+ s->config.f_osc = 48000; /* s66 : oscillator frequency [kHz] */
+ s->config.w92 = 12000; // 20000;
+
+ s->config.w9C = 0x000e;
+ s->config.w9E = 0x0000;
+
+ /* ConfigureMPEGOutput params */
+ s->config.wA0 = 4;
+ s->config.w98 = 1; // 0;
+ s->config.w9A = 1;
+
+ /* get chip revision */
+ rc = RD16(s, 0x2410019);
+ if (rc < 0)
+ return -ENODEV;
+
+ if (rc == 0) {
+ printk(KERN_INFO "%s: chip revision A2\n", mod_name);
+ rc = drx_load_fw(s, DRXD_FW_A2);
+ } else {
+
+ rc = (rc >> 12) - 3;
+ switch (rc) {
+ case 1:
+ s->flags |= F_SET_0D4h;
+ case 0:
+ case 4:
+ s->flags |= F_SET_0D0h;
+ break;
+ case 2:
+ case 5:
+ break;
+ case 3:
+ s->flags |= F_SET_0D4h;
+ break;
+ default:
+ return -ENODEV;
+ };
+ printk(KERN_INFO "%s: chip revision B1.%d\n", mod_name, rc);
+ rc = drx_load_fw(s, DRXD_FW_B1);
+ }
+ if (rc < 0)
+ goto error;
+
+ rc = WR16(s, 0x0420033, 0x3973);
+ if (rc < 0)
+ goto error;
+
+ rc = HI_Command(s, 2);
+
+ msleep(1);
+
+ if (s->chip_rev == DRXD_FW_A2) {
+ rc = WR16(s, 0x043012d, 0x47F);
+ if (rc < 0)
+ goto error;
+ }
+ rc = WR16_E0(s, 0x0400000, 0);
+ if (rc < 0)
+ goto error;
+
+ if (s->config.w92 > 20000 || s->config.w92 % 4000) {
+ printk(KERN_ERR "%s: invalid osc frequency\n", mod_name);
+ rc = -1;
+ goto error;
+ }
+
+ rc = WR16(s, 0x2410010, 1);
+ if (rc < 0)
+ goto error;
+ rc = WR16(s, 0x2410011, 0x15);
+ if (rc < 0)
+ goto error;
+ rc = WR16(s, 0x2410012, s->config.w92 / 4000);
+ if (rc < 0)
+ goto error;
+#ifdef ORIG_FW
+ rc = WR16(s, 0x2410015, 2);
+ if (rc < 0)
+ goto error;
+#endif
+ rc = WR16(s, 0x2410017, 0x3973);
+ if (rc < 0)
+ goto error;
+
+ s->f_osc = s->config.f_osc * 1000; /* initial estimator */
+#if 0
+ {
+ int deviation, val, edi;
+
+ /* osc_deviation(struct state *x, int deviation, int io)
+ *
+ * io == 0 : read_deviation from eeprom
+ * io != 0 : write deviation to eeprom
+ */
+ s->config.w64 = x->osc_deviation(x, 0, 0);
+ val = s->config.w64 * s->config.w66;
+ deviation = val / 1000000;
+
+ edi = 2;
+ if (val <= 0)
+ edi = -2;
+ val = val % 1000000;
+ if (edi * val > 1000000)
+ deviation += edi >> 1;
+ s->clk_if_corrected += deviation;
+ }
+#endif
+
+ s->config.w56 = 1;
+
+ rc = HI_CfgCommand(s);
+ if (rc < 0)
+ goto error;
+
+ rc = write_fw(s, DRXD_InitAtomicRead);
+ if (rc < 0)
+ goto error;
+
+ if (s->chip_rev == DRXD_FW_A2) {
+ rc = WR16(s, 0x2150013, 0);
+ if (rc < 0)
+ goto error;
+ }
+
+ rc = WR16_E0(s, 0x0400002, 0);
+ if (rc < 0)
+ goto error;
+ rc = WR16(s, 0x0400002, 0);
+ if (rc < 0)
+ goto error;
+
+ if (s->chip_rev == DRXD_FW_A2) {
+ rc = write_fw(s, DRXD_ResetCEFR);
+ if (rc < 0)
+ goto error;
+ }
+ rc = write_fw(s, DRXD_microcode);
+ if (rc < 0)
+ goto error;
+
+ s->config.w9C = 0x0e;
+ if (s->flags & F_SET_0D0h) {
+ s->config.w9C = 0;
+ rc = RD16(s, 0x0c20010);
+ if (rc < 0)
+ goto write_DRXD_InitFE_1;
+
+ rc &= ~0x1000;
+ rc = WR16(s, 0x0c20010, rc);
+ if (rc < 0)
+ goto write_DRXD_InitFE_1;
+
+ rc = RD16(s, 0x0c20011);
+ if (rc < 0)
+ goto write_DRXD_InitFE_1;
+
+ rc &= ~0x8;
+ rc = WR16(s, 0x0c20011, rc);
+ if (rc < 0)
+ goto write_DRXD_InitFE_1;
+
+ rc = WR16(s, 0x0c20012, 1);
+ }
+
+ write_DRXD_InitFE_1:
+
+ rc = write_fw(s, DRXD_InitFE_1);
+ if (rc < 0)
+ goto error;
+
+ rc = 1;
+ if (s->chip_rev == DRXD_FW_B1) {
+ if (s->flags & F_SET_0D0h)
+ rc = 0;
+ } else {
+ if (s->flags & F_SET_0D0h)
+ rc = 4;
+ }
+
+ rc = WR16(s, 0x0C20012, rc);
+ if (rc < 0)
+ goto error;
+
+ rc = WR16(s, 0x0C20013, s->config.w9E);
+ if (rc < 0)
+ goto error;
+ rc = WR16(s, 0x0C20015, s->config.w9C);
+ if (rc < 0)
+ goto error;
+
+ rc = write_fw(s, DRXD_InitFE_2);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitFT);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitCP);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitCE);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitEQ);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitEC);
+ if (rc < 0)
+ goto error;
+ rc = write_fw(s, DRXD_InitSC);
+ if (rc < 0)
+ goto error;
+
+ rc = SetCfgIfAgc(s, &s->config.ifagc);
+ if (rc < 0)
+ goto error;
+
+ rc = SetCfgRfAgc(s, &s->config.rfagc);
+ if (rc < 0)
+ goto error;
+
+#if 1
+ rc = ConfigureMPEGOutput(s, 1);
+ rc = WR16(s, 0x08201fe, 0x0017);
+ rc = WR16(s, 0x08201ff, 0x0101);
+
+ s->config.d5C = 0;
+#else
+ s->config.d5C = 0;
+ rc = CorrectSysClockDeviation(s);
+ if (rc < 0)
+ goto error;
+
+// rc = ConfigureWR16(s, 0x0420033, 0x200);
+
+ rc = WR16(s, 0x0800000, 0);
+ if (rc < 0)
+ goto error;
+
+ rc = WR16(s, 0x2800000, 0);
+#endif
+ s->config.d60 = 1;
+ s->config.d48 = 1;
+ error:
+ return rc;
+}
+
+static int drx397x_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ return 0;
+}
+
+static int drx397x_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *params)
+{
+ struct drx397xD_state *s = fe->demodulator_priv;
+
+ s->config.s20d24 = 1; // 0;
+ return drx_tune(s, params);
+}
+
+static int drx397x_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings
+ *fe_tune_settings)
+{
+ fe_tune_settings->min_delay_ms = 10000;
+ fe_tune_settings->step_size = 0;
+ fe_tune_settings->max_drift = 0;
+ return 0;
+}
+
+static int drx397x_read_status(struct dvb_frontend *fe, fe_status_t * status)
+{
+ struct drx397xD_state *s = fe->demodulator_priv;
+ int lockstat;
+
+ GetLockStatus(s, &lockstat);
+ /* TODO */
+// if (lockstat & 1)
+// CorrectSysClockDeviation(s);
+
+ *status = 0;
+ if (lockstat & 2) {
+ CorrectSysClockDeviation(s);
+ ConfigureMPEGOutput(s, 1);
+ *status = FE_HAS_LOCK | FE_HAS_SYNC | FE_HAS_VITERBI;
+ }
+ if (lockstat & 4) {
+ *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+ }
+
+ return 0;
+}
+
+static int drx397x_read_ber(struct dvb_frontend *fe, unsigned int *ber)
+{
+ *ber = 0;
+ return 0;
+}
+
+static int drx397x_read_snr(struct dvb_frontend *fe, u16 * snr)
+{
+ *snr = 0;
+ return 0;
+}
+
+static int drx397x_read_signal_strength(struct dvb_frontend *fe, u16 * strength)
+{
+ struct drx397xD_state *s = fe->demodulator_priv;
+ int rc;
+
+ if (s->config.ifagc.d00 == 2) {
+ *strength = 0xffff;
+ return 0;
+ }
+ rc = RD16(s, 0x0c20035);
+ if (rc < 0) {
+ *strength = 0;
+ return 0;
+ }
+ rc &= 0x3ff;
+ /* Signal strength is calculated using the following formula:
+ *
+ * a = 2200 * 150 / (2200 + 150);
+ * a = a * 3300 / (a + 820);
+ * b = 2200 * 3300 / (2200 + 820);
+ * c = (((b-a) * rc) >> 10 + a) << 4;
+ * strength = ~c & 0xffff;
+ *
+ * The following does the same but with less rounding errors:
+ */
+ *strength = ~(7720 + (rc * 30744 >> 10));
+ return 0;
+}
+
+static int drx397x_read_ucblocks(struct dvb_frontend *fe,
+ unsigned int *ucblocks)
+{
+ *ucblocks = 0;
+ return 0;
+}
+
+static int drx397x_sleep(struct dvb_frontend *fe)
+{
+ return 0;
+}
+
+static void drx397x_release(struct dvb_frontend *fe)
+{
+ struct drx397xD_state *s = fe->demodulator_priv;
+ printk(KERN_INFO "%s: release demodulator\n", mod_name);
+ if (s) {
+ drx_release_fw(s);
+ kfree(s);
+ }
+
+}
+
+static struct dvb_frontend_ops drx397x_ops = {
+
+ .info = {
+ .name = "Micronas DRX397xD DVB-T Frontend",
+ .type = FE_OFDM,
+ .frequency_min = 47125000,
+ .frequency_max = 855250000,
+ .frequency_stepsize = 166667,
+ .frequency_tolerance = 0,
+ .caps = /* 0x0C01B2EAE */
+ FE_CAN_FEC_1_2 | // = 0x2,
+ FE_CAN_FEC_2_3 | // = 0x4,
+ FE_CAN_FEC_3_4 | // = 0x8,
+ FE_CAN_FEC_5_6 | // = 0x20,
+ FE_CAN_FEC_7_8 | // = 0x80,
+ FE_CAN_FEC_AUTO | // = 0x200,
+ FE_CAN_QPSK | // = 0x400,
+ FE_CAN_QAM_16 | // = 0x800,
+ FE_CAN_QAM_64 | // = 0x2000,
+ FE_CAN_QAM_AUTO | // = 0x10000,
+ FE_CAN_TRANSMISSION_MODE_AUTO | // = 0x20000,
+ FE_CAN_GUARD_INTERVAL_AUTO | // = 0x80000,
+ FE_CAN_HIERARCHY_AUTO | // = 0x100000,
+ FE_CAN_RECOVER | // = 0x40000000,
+ FE_CAN_MUTE_TS // = 0x80000000
+ },
+
+ .release = drx397x_release,
+ .init = drx397x_init,
+ .sleep = drx397x_sleep,
+
+ .set_frontend = drx397x_set_frontend,
+ .get_tune_settings = drx397x_get_tune_settings,
+ .get_frontend = drx397x_get_frontend,
+
+ .read_status = drx397x_read_status,
+ .read_snr = drx397x_read_snr,
+ .read_signal_strength = drx397x_read_signal_strength,
+ .read_ber = drx397x_read_ber,
+ .read_ucblocks = drx397x_read_ucblocks,
+};
+
+struct dvb_frontend *drx397xD_attach(const struct drx397xD_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct drx397xD_state *s = NULL;
+
+ /* allocate memory for the internal state */
+ s = kzalloc(sizeof(struct drx397xD_state), GFP_KERNEL);
+ if (s == NULL)
+ goto error;
+
+ /* setup the state */
+ s->i2c = i2c;
+ memcpy(&s->config, config, sizeof(struct drx397xD_config));
+
+ /* check if the demod is there */
+ if (RD16(s, 0x2410019) < 0)
+ goto error;
+
+ /* create dvb_frontend */
+ memcpy(&s->frontend.ops, &drx397x_ops, sizeof(struct dvb_frontend_ops));
+ s->frontend.demodulator_priv = s;
+
+ return &s->frontend;
+ error:
+ kfree(s);
+ return NULL;
+}
+
+MODULE_DESCRIPTION("Micronas DRX397xD DVB-T Frontend");
+MODULE_AUTHOR("Henk Vergonet");
+MODULE_LICENSE("GPL");
+
+EXPORT_SYMBOL(drx397xD_attach);
diff --git a/linux/drivers/media/dvb/frontends/drx397xD.h b/linux/drivers/media/dvb/frontends/drx397xD.h
new file mode 100644
index 000000000..ddc7a0797
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/drx397xD.h
@@ -0,0 +1,130 @@
+/*
+ * Driver for Micronas DVB-T drx397xD demodulator
+ *
+ * Copyright (C) 2007 Henk vergonet <Henk.Vergonet@gmail.com>
+ *
+ * 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 _DRX397XD_H_INCLUDED
+#define _DRX397XD_H_INCLUDED
+
+#include <linux/dvb/frontend.h>
+
+#define DRX_F_STEPSIZE 166667
+#define DRX_F_OFFSET 36000000
+
+#define I2C_ADR_C0(x) \
+( (u32)cpu_to_le32( \
+ (u32)( \
+ (((u32)(x) & (u32)0x000000ffUL) ) | \
+ (((u32)(x) & (u32)0x0000ff00UL) << 16) | \
+ (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \
+ ( (u32)0x00c00000UL) \
+ )) \
+)
+
+#define I2C_ADR_E0(x) \
+( (u32)cpu_to_le32( \
+ (u32)( \
+ (((u32)(x) & (u32)0x000000ffUL) ) | \
+ (((u32)(x) & (u32)0x0000ff00UL) << 16) | \
+ (((u32)(x) & (u32)0x0fff0000UL) >> 8) | \
+ ( (u32)0x00e00000UL) \
+ )) \
+)
+
+struct drx397xD_CfgRfAgc /* 0x7c */
+{
+ int d00; /* 2 */
+ u16 w04;
+ u16 w06;
+};
+
+struct drx397xD_CfgIfAgc /* 0x68 */
+{
+ int d00; /* 0 */
+ u16 w04; /* 0 */
+ u16 w06;
+ u16 w08;
+ u16 w0A;
+ u16 w0C;
+};
+
+struct drx397xD_s20 {
+ int d04;
+ u32 d18;
+ u32 d1C;
+ u32 d20;
+ u32 d14;
+ u32 d24;
+ u32 d0C;
+ u32 d08;
+};
+
+struct drx397xD_config
+{
+ /* demodulator's I2C address */
+ u8 demod_address; /* 0x0f */
+
+ struct drx397xD_CfgIfAgc ifagc; /* 0x68 */
+ struct drx397xD_CfgRfAgc rfagc; /* 0x7c */
+ u32 s20d24;
+
+ /* HI_CfgCommand parameters */
+ u16 w50, w52, /* w54, */ w56;
+
+ int d5C;
+ int d60;
+ int d48;
+ int d28;
+
+ u32 f_if; /* d14: intermediate frequency [Hz] */
+ /* 36000000 on Cinergy 2400i DT */
+ /* 42800000 on Pinnacle Hybrid PRO 330e */
+
+ u16 f_osc; /* s66: 48000 oscillator frequency [kHz] */
+
+ u16 w92; /* 20000 */
+
+ u16 wA0;
+ u16 w98;
+ u16 w9A;
+
+ u16 w9C; /* 0xe0 */
+ u16 w9E; /* 0x00 */
+
+ /* used for signal strength calculations in
+ drx397x_read_signal_strength
+ */
+ u16 ss78; // 2200
+ u16 ss7A; // 150
+ u16 ss76; // 820
+};
+
+#if defined(CONFIG_DVB_DRX397XD) || (defined(CONFIG_DVB_DRX397XD_MODULE) && defined(MODULE))
+extern struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend* drx397xD_attach(const struct drx397xD_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_DRX397XD */
+
+#endif /* _DRX397XD_H_INCLUDED */
diff --git a/linux/drivers/media/dvb/frontends/drx397xD_fw.h b/linux/drivers/media/dvb/frontends/drx397xD_fw.h
new file mode 100644
index 000000000..01de02a81
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/drx397xD_fw.h
@@ -0,0 +1,40 @@
+/*
+ * Firmware definitions for Micronas drx397xD
+ *
+ * Copyright (C) 2007 Henk Vergonet <Henk.Vergonet@gmail.com>
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifdef _FW_ENTRY
+ _FW_ENTRY("drx397xD.A2.fw", DRXD_FW_A2 = 0 ),
+ _FW_ENTRY("drx397xD.B1.fw", DRXD_FW_B1 ),
+#undef _FW_ENTRY
+#endif /* _FW_ENTRY */
+
+#ifdef _BLOB_ENTRY
+ _BLOB_ENTRY("InitAtomicRead", DRXD_InitAtomicRead = 0 ),
+ _BLOB_ENTRY("InitCE", DRXD_InitCE ),
+ _BLOB_ENTRY("InitCP", DRXD_InitCP ),
+ _BLOB_ENTRY("InitEC", DRXD_InitEC ),
+ _BLOB_ENTRY("InitEQ", DRXD_InitEQ ),
+ _BLOB_ENTRY("InitFE_1", DRXD_InitFE_1 ),
+ _BLOB_ENTRY("InitFE_2", DRXD_InitFE_2 ),
+ _BLOB_ENTRY("InitFT", DRXD_InitFT ),
+ _BLOB_ENTRY("InitSC", DRXD_InitSC ),
+ _BLOB_ENTRY("ResetCEFR", DRXD_ResetCEFR ),
+ _BLOB_ENTRY("ResetECRAM", DRXD_ResetECRAM ),
+ _BLOB_ENTRY("microcode", DRXD_microcode ),
+#undef _BLOB_ENTRY
+#endif /* _BLOB_ENTRY */
diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.c b/linux/drivers/media/dvb/frontends/dvb-pll.c
index 93785eef2..bb3e35373 100644
--- a/linux/drivers/media/dvb/frontends/dvb-pll.c
+++ b/linux/drivers/media/dvb/frontends/dvb-pll.c
@@ -344,6 +344,52 @@ static struct dvb_pll_desc dvb_pll_opera1 = {
}
};
+static void samsung_dtos403ih102a_set(struct dvb_frontend *fe, u8 *buf,
+ const struct dvb_frontend_parameters *params)
+{
+ struct dvb_pll_priv *priv = fe->tuner_priv;
+ struct i2c_msg msg = {
+ .addr = priv->pll_i2c_address,
+ .flags = 0,
+ .buf = buf,
+ .len = 4
+ };
+ int result;
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ result = i2c_transfer(priv->i2c, &msg, 1);
+ if (result != 1)
+ printk(KERN_ERR "%s: i2c_transfer failed:%d",
+ __func__, result);
+
+ buf[2] = 0x9e;
+ buf[3] = 0x90;
+
+ return;
+}
+
+/* unknown pll used in Samsung DTOS403IH102A DVB-C tuner */
+static struct dvb_pll_desc dvb_pll_samsung_dtos403ih102a = {
+ .name = "Samsung DTOS403IH102A",
+ .min = 44250000,
+ .max = 858000000,
+ .iffreq = 36125000,
+ .count = 8,
+ .set = samsung_dtos403ih102a_set,
+ .entries = {
+ { 135000000, 62500, 0xbe, 0x01 },
+ { 177000000, 62500, 0xf6, 0x01 },
+ { 370000000, 62500, 0xbe, 0x02 },
+ { 450000000, 62500, 0xf6, 0x02 },
+ { 466000000, 62500, 0xfe, 0x02 },
+ { 538000000, 62500, 0xbe, 0x08 },
+ { 826000000, 62500, 0xf6, 0x08 },
+ { 999999999, 62500, 0xfe, 0x08 },
+ }
+};
+
/* ----------------------------------------------------------- */
static struct dvb_pll_desc *pll_list[] = {
@@ -361,6 +407,7 @@ static struct dvb_pll_desc *pll_list[] = {
[DVB_PLL_SAMSUNG_TBMV] = &dvb_pll_samsung_tbmv,
[DVB_PLL_PHILIPS_SD1878_TDA8261] = &dvb_pll_philips_sd1878_tda8261,
[DVB_PLL_OPERA1] = &dvb_pll_opera1,
+ [DVB_PLL_SAMSUNG_DTOS403IH102A] = &dvb_pll_samsung_dtos403ih102a,
};
/* ----------------------------------------------------------- */
diff --git a/linux/drivers/media/dvb/frontends/dvb-pll.h b/linux/drivers/media/dvb/frontends/dvb-pll.h
index 435146d9f..05239f579 100644
--- a/linux/drivers/media/dvb/frontends/dvb-pll.h
+++ b/linux/drivers/media/dvb/frontends/dvb-pll.h
@@ -22,6 +22,7 @@
#define DVB_PLL_SAMSUNG_TBMV 11
#define DVB_PLL_PHILIPS_SD1878_TDA8261 12
#define DVB_PLL_OPERA1 13
+#define DVB_PLL_SAMSUNG_DTOS403IH102A 14
/**
* Attach a dvb-pll to the supplied frontend structure.
@@ -43,7 +44,7 @@ static inline struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
unsigned int pll_desc_id)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif
diff --git a/linux/drivers/media/dvb/frontends/isl6405.h b/linux/drivers/media/dvb/frontends/isl6405.h
index 9d4001a22..1c793d375 100644
--- a/linux/drivers/media/dvb/frontends/isl6405.h
+++ b/linux/drivers/media/dvb/frontends/isl6405.h
@@ -66,7 +66,7 @@ static inline struct dvb_frontend *isl6405_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c, u8 i2c_addr,
u8 override_set, u8 override_clear)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif /* CONFIG_DVB_ISL6405 */
diff --git a/linux/drivers/media/dvb/frontends/isl6421.h b/linux/drivers/media/dvb/frontends/isl6421.h
index ea7f78a7d..47e4518a0 100644
--- a/linux/drivers/media/dvb/frontends/isl6421.h
+++ b/linux/drivers/media/dvb/frontends/isl6421.h
@@ -47,7 +47,7 @@ extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_a
static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
u8 override_set, u8 override_clear)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_ISL6421
diff --git a/linux/drivers/media/dvb/frontends/itd1000.c b/linux/drivers/media/dvb/frontends/itd1000.c
new file mode 100644
index 000000000..3e37beb14
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/itd1000.c
@@ -0,0 +1,408 @@
+/*
+ * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
+ *
+ * Copyright (c) 2007-8 Patrick Boettcher <pb@linuxtv.org>
+ *
+ * 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/moduleparam.h>
+#include <linux/delay.h>
+#include <linux/dvb/frontend.h>
+#include <linux/i2c.h>
+
+#include "dvb_frontend.h"
+
+#include "itd1000.h"
+#include "itd1000_priv.h"
+
+static int debug;
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
+
+#define deb(args...) do { \
+ if (debug) { \
+ printk(KERN_DEBUG "ITD1000: " args);\
+ printk("\n"); \
+ } \
+} while (0)
+
+#define warn(args...) do { \
+ printk(KERN_WARNING "ITD1000: " args); \
+ printk("\n"); \
+} while (0)
+
+#define info(args...) do { \
+ printk(KERN_INFO "ITD1000: " args); \
+ printk("\n"); \
+} while (0)
+
+/* don't write more than one byte with flexcop behind */
+static int itd1000_write_regs(struct itd1000_state *state, u8 reg, u8 v[], u8 len)
+{
+ u8 buf[1+len];
+ struct i2c_msg msg = {
+ .addr = state->cfg->i2c_address, .flags = 0, .buf = buf, .len = len+1
+ };
+ buf[0] = reg;
+ memcpy(&buf[1], v, len);
+
+ /* deb("wr %02x: %02x", reg, v[0]); */
+
+ if (i2c_transfer(state->i2c, &msg, 1) != 1) {
+ printk(KERN_WARNING "itd1000 I2C write failed\n");
+ return -EREMOTEIO;
+ }
+ return 0;
+}
+
+static int itd1000_read_reg(struct itd1000_state *state, u8 reg)
+{
+ u8 val;
+ struct i2c_msg msg[2] = {
+ { .addr = state->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 },
+ { .addr = state->cfg->i2c_address, .flags = I2C_M_RD, .buf = &val, .len = 1 },
+ };
+
+ /* ugly flexcop workaround */
+ itd1000_write_regs(state, (reg - 1) & 0xff, &state->shadow[(reg - 1) & 0xff], 1);
+
+ if (i2c_transfer(state->i2c, msg, 2) != 2) {
+ warn("itd1000 I2C read failed");
+ return -EREMOTEIO;
+ }
+ return val;
+}
+
+static inline int itd1000_write_reg(struct itd1000_state *state, u8 r, u8 v)
+{
+ int ret = itd1000_write_regs(state, r, &v, 1);
+ state->shadow[r] = v;
+ return ret;
+}
+
+#if 0
+static void reg_dump(struct itd1000_state *state)
+{
+ int i;
+ for (i = 0x65; i < 0x9c; i++)
+ printk(KERN_DEBUG "ITD: %02x: %02x\n", i, itd1000_read_reg(state, i));
+}
+#endif
+
+static struct {
+ u32 symbol_rate;
+ u8 pgaext : 4; /* PLLFH */
+ u8 bbgvmin : 4; /* BBGVMIN */
+} itd1000_lpf_pga[] = {
+ { 0, 0x8, 0x3 },
+ { 5200000, 0x8, 0x3 },
+ { 12200000, 0x4, 0x3 },
+ { 15400000, 0x2, 0x3 },
+ { 19800000, 0x2, 0x3 },
+ { 21500000, 0x2, 0x3 },
+ { 24500000, 0x2, 0x3 },
+ { 28400000, 0x2, 0x3 },
+ { 33400000, 0x2, 0x3 },
+ { 34400000, 0x1, 0x4 },
+ { 34400000, 0x1, 0x4 },
+ { 38400000, 0x1, 0x4 },
+ { 38400000, 0x1, 0x4 },
+ { 40400000, 0x1, 0x4 },
+ { 45400000, 0x1, 0x4 },
+};
+
+static void itd1000_set_lpf_bw(struct itd1000_state *state, u32 symbol_rate)
+{
+ u8 i;
+ u8 con1 = itd1000_read_reg(state, CON1) & 0xfd;
+ u8 pllfh = itd1000_read_reg(state, PLLFH) & 0x0f;
+ u8 bbgvmin = itd1000_read_reg(state, BBGVMIN) & 0xf0;
+ u8 bw = itd1000_read_reg(state, BW) & 0xf0;
+
+ deb("symbol_rate = %d", symbol_rate);
+
+ /* not sure what is that ? - starting to download the table */
+ itd1000_write_reg(state, CON1, con1 | (1 << 1));
+
+ for (i = 0; i < ARRAY_SIZE(itd1000_lpf_pga); i++)
+ if (symbol_rate < itd1000_lpf_pga[i].symbol_rate) {
+ deb("symrate: index: %d pgaext: %x, bbgvmin: %x", i, itd1000_lpf_pga[i].pgaext, itd1000_lpf_pga[i].bbgvmin);
+ itd1000_write_reg(state, PLLFH, pllfh | (itd1000_lpf_pga[i].pgaext << 4));
+ itd1000_write_reg(state, BBGVMIN, bbgvmin | (itd1000_lpf_pga[i].bbgvmin));
+ itd1000_write_reg(state, BW, bw | (i & 0x0f));
+ break;
+ }
+
+ itd1000_write_reg(state, CON1, con1 | (0 << 1));
+}
+
+static struct {
+ u8 vcorg;
+ u32 fmax_rg;
+} itd1000_vcorg[] = {
+ { 1, 920000 },
+ { 2, 971000 },
+ { 3, 1031000 },
+ { 4, 1091000 },
+ { 5, 1171000 },
+ { 6, 1281000 },
+ { 7, 1381000 },
+ { 8, 500000 }, /* this is intentional. */
+ { 9, 1451000 },
+ { 10, 1531000 },
+ { 11, 1631000 },
+ { 12, 1741000 },
+ { 13, 1891000 },
+ { 14, 2071000 },
+ { 15, 2250000 },
+};
+
+static void itd1000_set_vco(struct itd1000_state *state, u32 freq_khz)
+{
+ u8 i;
+ u8 gvbb_i2c = itd1000_read_reg(state, GVBB_I2C) & 0xbf;
+ u8 vco_chp1_i2c = itd1000_read_reg(state, VCO_CHP1_I2C) & 0x0f;
+ u8 adcout;
+
+ /* reserved bit again (reset ?) */
+ itd1000_write_reg(state, GVBB_I2C, gvbb_i2c | (1 << 6));
+
+ for (i = 0; i < ARRAY_SIZE(itd1000_vcorg); i++) {
+ if (freq_khz < itd1000_vcorg[i].fmax_rg) {
+ itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | (itd1000_vcorg[i].vcorg << 4));
+ msleep(1);
+
+ adcout = itd1000_read_reg(state, PLLLOCK) & 0x0f;
+
+ deb("VCO: %dkHz: %d -> ADCOUT: %d %02x", freq_khz, itd1000_vcorg[i].vcorg, adcout, vco_chp1_i2c);
+
+ if (adcout > 13) {
+ if (!(itd1000_vcorg[i].vcorg == 7 || itd1000_vcorg[i].vcorg == 15))
+ itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg + 1) << 4));
+ } else if (adcout < 2) {
+ if (!(itd1000_vcorg[i].vcorg == 1 || itd1000_vcorg[i].vcorg == 9))
+ itd1000_write_reg(state, VCO_CHP1_I2C, vco_chp1_i2c | ((itd1000_vcorg[i].vcorg - 1) << 4));
+ }
+ break;
+ }
+ }
+}
+
+static const struct {
+ u32 freq;
+ u8 values[10]; /* RFTR, RFST1 - RFST9 */
+} itd1000_fre_values[] = {
+ { 1075000, { 0x59, 0x1d, 0x1c, 0x17, 0x16, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+ { 1250000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+ { 1450000, { 0x89, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+ { 1650000, { 0x69, 0x1e, 0x1d, 0x17, 0x15, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+ { 1750000, { 0x69, 0x1e, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0c, 0x0b, 0x0a } },
+ { 1850000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } },
+ { 1900000, { 0x69, 0x1d, 0x17, 0x15, 0x14, 0x0f, 0x0e, 0x0d, 0x0b, 0x0a } },
+ { 1950000, { 0x69, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0d, 0x0b, 0x0a } },
+ { 2050000, { 0x69, 0x1e, 0x1d, 0x17, 0x16, 0x14, 0x13, 0x0e, 0x0b, 0x0a } },
+ { 2150000, { 0x69, 0x1d, 0x1c, 0x17, 0x15, 0x14, 0x13, 0x0f, 0x0e, 0x0b } }
+};
+
+
+#define FREF 16
+
+static void itd1000_set_lo(struct itd1000_state *state, u32 freq_khz)
+{
+ int i, j;
+ u32 plln, pllf;
+ u64 tmp;
+
+ plln = (freq_khz * 1000) / 2 / FREF;
+
+ /* Compute the factional part times 1000 */
+ tmp = plln % 1000000;
+ plln /= 1000000;
+
+ tmp *= 1048576;
+ do_div(tmp, 1000000);
+ pllf = (u32) tmp;
+
+ state->frequency = ((plln * 1000) + (pllf * 1000)/1048576) * 2*FREF;
+ deb("frequency: %dkHz (wanted) %dkHz (set), PLLF = %d, PLLN = %d", freq_khz, state->frequency, pllf, plln);
+
+ itd1000_write_reg(state, PLLNH, 0x80); /* PLLNH */;
+ itd1000_write_reg(state, PLLNL, plln & 0xff);
+ itd1000_write_reg(state, PLLFH, (itd1000_read_reg(state, PLLFH) & 0xf0) | ((pllf >> 16) & 0x0f));
+ itd1000_write_reg(state, PLLFM, (pllf >> 8) & 0xff);
+ itd1000_write_reg(state, PLLFL, (pllf >> 0) & 0xff);
+
+ for (i = 0; i < ARRAY_SIZE(itd1000_fre_values); i++) {
+ if (freq_khz <= itd1000_fre_values[i].freq) {
+ deb("fre_values: %d", i);
+ itd1000_write_reg(state, RFTR, itd1000_fre_values[i].values[0]);
+ for (j = 0; j < 9; j++)
+ itd1000_write_reg(state, RFST1+j, itd1000_fre_values[i].values[j+1]);
+ break;
+ }
+ }
+
+ itd1000_set_vco(state, freq_khz);
+}
+
+static int itd1000_set_parameters(struct dvb_frontend *fe, struct dvb_frontend_parameters *p)
+{
+ struct itd1000_state *state = fe->tuner_priv;
+ u8 pllcon1;
+
+ itd1000_set_lo(state, p->frequency);
+ itd1000_set_lpf_bw(state, p->u.qpsk.symbol_rate);
+
+ pllcon1 = itd1000_read_reg(state, PLLCON1) & 0x7f;
+ itd1000_write_reg(state, PLLCON1, pllcon1 | (1 << 7));
+ itd1000_write_reg(state, PLLCON1, pllcon1);
+
+ return 0;
+}
+
+static int itd1000_get_frequency(struct dvb_frontend *fe, u32 *frequency)
+{
+ struct itd1000_state *state = fe->tuner_priv;
+ *frequency = state->frequency;
+ return 0;
+}
+
+static int itd1000_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
+{
+ return 0;
+}
+
+static u8 itd1000_init_tab[][2] = {
+ { PLLCON1, 0x65 }, /* Register does not change */
+ { PLLNH, 0x80 }, /* Bits [7:6] do not change */
+ { RESERVED_0X6D, 0x3b },
+ { VCO_CHP2_I2C, 0x12 },
+ { 0x72, 0xf9 }, /* No such regsister defined */
+ { RESERVED_0X73, 0xff },
+ { RESERVED_0X74, 0xb2 },
+ { RESERVED_0X75, 0xc7 },
+ { EXTGVBBRF, 0xf0 },
+ { DIVAGCCK, 0x80 },
+ { BBTR, 0xa0 },
+ { RESERVED_0X7E, 0x4f },
+ { 0x82, 0x88 }, /* No such regsister defined */
+ { 0x83, 0x80 }, /* No such regsister defined */
+ { 0x84, 0x80 }, /* No such regsister defined */
+ { RESERVED_0X85, 0x74 },
+ { RESERVED_0X86, 0xff },
+ { RESERVED_0X88, 0x02 },
+ { RESERVED_0X89, 0x16 },
+ { RFST0, 0x1f },
+ { RESERVED_0X94, 0x66 },
+ { RESERVED_0X95, 0x66 },
+ { RESERVED_0X96, 0x77 },
+ { RESERVED_0X97, 0x99 },
+ { RESERVED_0X98, 0xff },
+ { RESERVED_0X99, 0xfc },
+ { RESERVED_0X9A, 0xba },
+ { RESERVED_0X9B, 0xaa },
+};
+
+static u8 itd1000_reinit_tab[][2] = {
+ { VCO_CHP1_I2C, 0x8a },
+ { BW, 0x87 },
+ { GVBB_I2C, 0x03 },
+ { BBGVMIN, 0x03 },
+ { CON1, 0x2e },
+};
+
+
+static int itd1000_init(struct dvb_frontend *fe)
+{
+ struct itd1000_state *state = fe->tuner_priv;
+ int i;
+
+ for (i = 0; i < ARRAY_SIZE(itd1000_init_tab); i++)
+ itd1000_write_reg(state, itd1000_init_tab[i][0], itd1000_init_tab[i][1]);
+
+ for (i = 0; i < ARRAY_SIZE(itd1000_reinit_tab); i++)
+ itd1000_write_reg(state, itd1000_reinit_tab[i][0], itd1000_reinit_tab[i][1]);
+
+ return 0;
+}
+
+static int itd1000_sleep(struct dvb_frontend *fe)
+{
+ return 0;
+}
+
+static int itd1000_release(struct dvb_frontend *fe)
+{
+ kfree(fe->tuner_priv);
+ fe->tuner_priv = NULL;
+ return 0;
+}
+
+static const struct dvb_tuner_ops itd1000_tuner_ops = {
+ .info = {
+ .name = "Integrant ITD1000",
+ .frequency_min = 950000,
+ .frequency_max = 2150000,
+ .frequency_step = 125, /* kHz for QPSK frontends */
+ },
+
+ .release = itd1000_release,
+
+ .init = itd1000_init,
+ .sleep = itd1000_sleep,
+
+ .set_params = itd1000_set_parameters,
+ .get_frequency = itd1000_get_frequency,
+ .get_bandwidth = itd1000_get_bandwidth
+};
+
+
+struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
+{
+ struct itd1000_state *state = NULL;
+ u8 i = 0;
+
+ state = kzalloc(sizeof(struct itd1000_state), GFP_KERNEL);
+ if (state == NULL)
+ return NULL;
+
+ state->cfg = cfg;
+ state->i2c = i2c;
+
+ i = itd1000_read_reg(state, 0);
+ if (i != 0) {
+ kfree(state);
+ return NULL;
+ }
+ info("successfully identified (ID: %d)", i);
+
+ memset(state->shadow, 0xff, sizeof(state->shadow));
+ for (i = 0x65; i < 0x9c; i++)
+ state->shadow[i] = itd1000_read_reg(state, i);
+
+ memcpy(&fe->ops.tuner_ops, &itd1000_tuner_ops, sizeof(struct dvb_tuner_ops));
+
+ fe->tuner_priv = state;
+
+ return fe;
+}
+EXPORT_SYMBOL(itd1000_attach);
+
+MODULE_AUTHOR("Patrick Boettcher <pb@linuxtv.org>");
+MODULE_DESCRIPTION("Integrant ITD1000 driver");
+MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/frontends/mt2060.h b/linux/drivers/media/dvb/frontends/itd1000.h
index 0a86eab3a..5e18df071 100644
--- a/linux/drivers/media/dvb/frontends/mt2060.h
+++ b/linux/drivers/media/dvb/frontends/itd1000.h
@@ -1,7 +1,7 @@
/*
- * Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
+ * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
*
- * Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
+ * Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org>
*
* 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
@@ -19,25 +19,24 @@
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
*/
-#ifndef MT2060_H
-#define MT2060_H
+#ifndef ITD1000_H
+#define ITD1000_H
struct dvb_frontend;
struct i2c_adapter;
-struct mt2060_config {
+struct itd1000_config {
u8 i2c_address;
- u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
};
-#if defined(CONFIG_DVB_TUNER_MT2060) || (defined(CONFIG_DVB_TUNER_MT2060_MODULE) && defined(MODULE))
-extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
+#if defined(CONFIG_DVB_TUNER_ITD1000) || (defined(CONFIG_DVB_TUNER_ITD1000_MODULE) && defined(MODULE))
+extern struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg);
#else
-static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
+static inline struct dvb_frontend *itd1000_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct itd1000_config *cfg)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif // CONFIG_DVB_TUNER_MT2060
+#endif
#endif
diff --git a/linux/drivers/media/dvb/frontends/itd1000_priv.h b/linux/drivers/media/dvb/frontends/itd1000_priv.h
new file mode 100644
index 000000000..8cdc54e57
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/itd1000_priv.h
@@ -0,0 +1,88 @@
+/*
+ * Driver for the Integrant ITD1000 "Zero-IF Tuner IC for Direct Broadcast Satellite"
+ *
+ * Copyright (c) 2007 Patrick Boettcher <pb@linuxtv.org>
+ *
+ * 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 ITD1000_PRIV_H
+#define ITD1000_PRIV_H
+
+struct itd1000_state {
+ struct itd1000_config *cfg;
+ struct i2c_adapter *i2c;
+
+ u32 frequency; /* contains the value resulting from the LO-setting */
+
+ /* ugly workaround for flexcop's incapable i2c-controller
+ * FIXME, if possible
+ */
+ u8 shadow[255];
+};
+
+enum itd1000_register {
+ VCO_CHP1 = 0x65,
+ VCO_CHP2,
+ PLLCON1,
+ PLLNH,
+ PLLNL,
+ PLLFH,
+ PLLFM,
+ PLLFL,
+ RESERVED_0X6D,
+ PLLLOCK,
+ VCO_CHP2_I2C,
+ VCO_CHP1_I2C,
+ BW,
+ RESERVED_0X73 = 0x73,
+ RESERVED_0X74,
+ RESERVED_0X75,
+ GVBB,
+ GVRF,
+ GVBB_I2C,
+ EXTGVBBRF,
+ DIVAGCCK,
+ BBTR,
+ RFTR,
+ BBGVMIN,
+ RESERVED_0X7E,
+ RESERVED_0X85 = 0x85,
+ RESERVED_0X86,
+ CON1,
+ RESERVED_0X88,
+ RESERVED_0X89,
+ RFST0,
+ RFST1,
+ RFST2,
+ RFST3,
+ RFST4,
+ RFST5,
+ RFST6,
+ RFST7,
+ RFST8,
+ RFST9,
+ RESERVED_0X94,
+ RESERVED_0X95,
+ RESERVED_0X96,
+ RESERVED_0X97,
+ RESERVED_0X98,
+ RESERVED_0X99,
+ RESERVED_0X9A,
+ RESERVED_0X9B,
+};
+
+#endif
diff --git a/linux/drivers/media/dvb/frontends/l64781.c b/linux/drivers/media/dvb/frontends/l64781.c
index 443d9045d..e1e70e9e0 100644
--- a/linux/drivers/media/dvb/frontends/l64781.c
+++ b/linux/drivers/media/dvb/frontends/l64781.c
@@ -57,7 +57,7 @@ static int l64781_writereg (struct l64781_state* state, u8 reg, u8 data)
if ((ret = i2c_transfer(state->i2c, &msg, 1)) != 1)
dprintk ("%s: write_reg error (reg == %02x) = %02x!\n",
- __FUNCTION__, reg, ret);
+ __func__, reg, ret);
return (ret != 1) ? -1 : 0;
}
diff --git a/linux/drivers/media/dvb/frontends/l64781.h b/linux/drivers/media/dvb/frontends/l64781.h
index cd15f76ff..1305a9e7f 100644
--- a/linux/drivers/media/dvb/frontends/l64781.h
+++ b/linux/drivers/media/dvb/frontends/l64781.h
@@ -38,7 +38,7 @@ extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
static inline struct dvb_frontend* l64781_attach(const struct l64781_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_L64781
diff --git a/linux/drivers/media/dvb/frontends/lgdt330x.c b/linux/drivers/media/dvb/frontends/lgdt330x.c
index 033b5a18d..3a3658238 100644
--- a/linux/drivers/media/dvb/frontends/lgdt330x.c
+++ b/linux/drivers/media/dvb/frontends/lgdt330x.c
@@ -89,7 +89,7 @@ static int i2c_write_demod_bytes (struct lgdt330x_state* state,
for (i=0; i<len-1; i+=2){
if ((err = i2c_transfer(state->i2c, &msg, 1)) != 1) {
- printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __FUNCTION__, msg.buf[0], msg.buf[1], err);
+ printk(KERN_WARNING "lgdt330x: %s error (addr %02x <- %02x, err = %i)\n", __func__, msg.buf[0], msg.buf[1], err);
if (err < 0)
return err;
else
@@ -118,7 +118,7 @@ static u8 i2c_read_demod_bytes (struct lgdt330x_state* state,
int ret;
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2) {
- printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __FUNCTION__, state->config->demod_address, reg, ret);
+ printk(KERN_WARNING "lgdt330x: %s: addr 0x%02x select 0x%02x error (ret == %i)\n", __func__, state->config->demod_address, reg, ret);
} else {
ret = 0;
}
@@ -257,7 +257,7 @@ static int lgdt330x_init(struct dvb_frontend* fe)
printk (KERN_WARNING "Only LGDT3302 and LGDT3303 are supported chips.\n");
err = -ENODEV;
}
- dprintk("%s entered as %s\n", __FUNCTION__, chip_name);
+ dprintk("%s entered as %s\n", __func__, chip_name);
if (err < 0)
return err;
return lgdt330x_SwReset(state);
@@ -335,7 +335,7 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe,
if (state->current_modulation != param->u.vsb.modulation) {
switch(param->u.vsb.modulation) {
case VSB_8:
- dprintk("%s: VSB_8 MODE\n", __FUNCTION__);
+ dprintk("%s: VSB_8 MODE\n", __func__);
/* Select VSB mode */
top_ctrl_cfg[1] = 0x03;
@@ -351,7 +351,7 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe,
break;
case QAM_64:
- dprintk("%s: QAM_64 MODE\n", __FUNCTION__);
+ dprintk("%s: QAM_64 MODE\n", __func__);
/* Select QAM_64 mode */
top_ctrl_cfg[1] = 0x00;
@@ -367,7 +367,7 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe,
break;
case QAM_256:
- dprintk("%s: QAM_256 MODE\n", __FUNCTION__);
+ dprintk("%s: QAM_256 MODE\n", __func__);
/* Select QAM_256 mode */
top_ctrl_cfg[1] = 0x01;
@@ -382,7 +382,7 @@ static int lgdt330x_set_parameters(struct dvb_frontend* fe,
}
break;
default:
- printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __FUNCTION__, param->u.vsb.modulation);
+ printk(KERN_WARNING "lgdt330x: %s: Modulation type(%d) UNSUPPORTED\n", __func__, param->u.vsb.modulation);
return -1;
}
/*
@@ -432,7 +432,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
/* AGC status register */
i2c_read_demod_bytes(state, AGC_STATUS, buf, 1);
- dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
+ dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]);
if ((buf[0] & 0x0c) == 0x8){
/* Test signal does not exist flag */
/* as well as the AGC lock flag. */
@@ -446,7 +446,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
*/
/* signal status */
i2c_read_demod_bytes(state, TOP_CONTROL, buf, sizeof(buf));
- dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __FUNCTION__, buf[0], buf[1], buf[2]);
+ dprintk("%s: TOP_CONTROL = 0x%02x, IRO_MASK = 0x%02x, IRQ_STATUS = 0x%02x\n", __func__, buf[0], buf[1], buf[2]);
#if 0
/* Alternative method to check for a signal */
@@ -468,7 +468,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
/* Carrier Recovery Lock Status Register */
i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
- dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
+ dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]);
switch (state->current_modulation) {
case QAM_256:
case QAM_64:
@@ -481,7 +481,7 @@ static int lgdt3302_read_status(struct dvb_frontend* fe, fe_status_t* status)
*status |= FE_HAS_CARRIER;
break;
default:
- printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
+ printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__);
}
return 0;
@@ -500,7 +500,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
if (err < 0)
return err;
- dprintk("%s: AGC_STATUS = 0x%02x\n", __FUNCTION__, buf[0]);
+ dprintk("%s: AGC_STATUS = 0x%02x\n", __func__, buf[0]);
if ((buf[0] & 0x21) == 0x01){
/* Test input signal does not exist flag */
/* as well as the AGC lock flag. */
@@ -509,7 +509,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
/* Carrier Recovery Lock Status Register */
i2c_read_demod_bytes(state, CARRIER_LOCK, buf, 1);
- dprintk("%s: CARRIER_LOCK = 0x%02x\n", __FUNCTION__, buf[0]);
+ dprintk("%s: CARRIER_LOCK = 0x%02x\n", __func__, buf[0]);
switch (state->current_modulation) {
case QAM_256:
case QAM_64:
@@ -540,7 +540,7 @@ static int lgdt3303_read_status(struct dvb_frontend* fe, fe_status_t* status)
}
break;
default:
- printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __FUNCTION__);
+ printk(KERN_WARNING "lgdt330x: %s: Modulation set to unsupported value\n", __func__);
}
return 0;
}
@@ -614,14 +614,14 @@ static int lgdt3302_read_snr(struct dvb_frontend* fe, u16* snr)
break;
default:
printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n",
- __FUNCTION__);
+ __func__);
return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
}
state->snr = calculate_snr(noise, c);
*snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
- dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __FUNCTION__, noise,
+ dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
return 0;
@@ -658,14 +658,14 @@ static int lgdt3303_read_snr(struct dvb_frontend* fe, u16* snr)
break;
default:
printk(KERN_ERR "lgdt330x: %s: Modulation set to unsupported value\n",
- __FUNCTION__);
+ __func__);
return -EREMOTEIO; /* return -EDRIVER_IS_GIBBERED; */
}
state->snr = calculate_snr(noise, c);
*snr = (state->snr) >> 16; /* Convert from 8.24 fixed-point to 8.8 */
- dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __FUNCTION__, noise,
+ dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
state->snr >> 24, (((state->snr >> 8) & 0xffff) * 100) >> 16);
return 0;
@@ -750,7 +750,7 @@ struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
error:
kfree(state);
- dprintk("%s: ERROR\n",__FUNCTION__);
+ dprintk("%s: ERROR\n",__func__);
return NULL;
}
diff --git a/linux/drivers/media/dvb/frontends/lgdt330x.h b/linux/drivers/media/dvb/frontends/lgdt330x.h
index 995059004..9012504f0 100644
--- a/linux/drivers/media/dvb/frontends/lgdt330x.h
+++ b/linux/drivers/media/dvb/frontends/lgdt330x.h
@@ -59,7 +59,7 @@ extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config
static inline struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_LGDT330X
diff --git a/linux/drivers/media/dvb/frontends/lnbp21.h b/linux/drivers/media/dvb/frontends/lnbp21.h
index 68906acf7..8fe094bd9 100644
--- a/linux/drivers/media/dvb/frontends/lnbp21.h
+++ b/linux/drivers/media/dvb/frontends/lnbp21.h
@@ -45,7 +45,7 @@ extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_ad
#else
static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_LNBP21
diff --git a/linux/drivers/media/dvb/frontends/mt2060.c b/linux/drivers/media/dvb/frontends/mt2060.c
deleted file mode 100644
index 355817754..000000000
--- a/linux/drivers/media/dvb/frontends/mt2060.c
+++ /dev/null
@@ -1,376 +0,0 @@
-/*
- * Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
- *
- * Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
- *
- * 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.=
- */
-
-/* In that file, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-#include "compat.h"
-
-#include "dvb_frontend.h"
-
-#include "mt2060.h"
-#include "mt2060_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2060: " args); printk("\n"); }} while (0)
-
-// Reads a single register
-static int mt2060_readreg(struct mt2060_priv *priv, u8 reg, u8 *val)
-{
- struct i2c_msg msg[2] = {
- { .addr = priv->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 },
- { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 },
- };
-
- if (i2c_transfer(priv->i2c, msg, 2) != 2) {
- printk(KERN_WARNING "mt2060 I2C read failed\n");
- return -EREMOTEIO;
- }
- return 0;
-}
-
-// Writes a single register
-static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val)
-{
- u8 buf[2] = { reg, val };
- struct i2c_msg msg = {
- .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
- };
-
- if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
- printk(KERN_WARNING "mt2060 I2C write failed\n");
- return -EREMOTEIO;
- }
- return 0;
-}
-
-// Writes a set of consecutive registers
-static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len)
-{
- struct i2c_msg msg = {
- .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
- };
- if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
- printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n",(int)len);
- return -EREMOTEIO;
- }
- return 0;
-}
-
-// Initialisation sequences
-// LNABAND=3, NUM1=0x3C, DIV1=0x74, NUM2=0x1080, DIV2=0x49
-static u8 mt2060_config1[] = {
- REG_LO1C1,
- 0x3F, 0x74, 0x00, 0x08, 0x93
-};
-
-// FMCG=2, GP2=0, GP1=0
-static u8 mt2060_config2[] = {
- REG_MISC_CTRL,
- 0x20, 0x1E, 0x30, 0xff, 0x80, 0xff, 0x00, 0x2c, 0x42
-};
-
-// VGAG=3, V1CSE=1
-#if 0
-static u8 mt2060_config3[] = {
- REG_VGAG,
- 0x33
-};
-#endif
-
-#ifdef MT2060_SPURCHECK
-/* The function below calculates the frequency offset between the output frequency if2
- and the closer cross modulation subcarrier between lo1 and lo2 up to the tenth harmonic */
-static int mt2060_spurcalc(u32 lo1,u32 lo2,u32 if2)
-{
- int I,J;
- int dia,diamin,diff;
- diamin=1000000;
- for (I = 1; I < 10; I++) {
- J = ((2*I*lo1)/lo2+1)/2;
- diff = I*(int)lo1-J*(int)lo2;
- if (diff < 0) diff=-diff;
- dia = (diff-(int)if2);
- if (dia < 0) dia=-dia;
- if (diamin > dia) diamin=dia;
- }
- return diamin;
-}
-
-#define BANDWIDTH 4000 // kHz
-
-/* Calculates the frequency offset to add to avoid spurs. Returns 0 if no offset is needed */
-static int mt2060_spurcheck(u32 lo1,u32 lo2,u32 if2)
-{
- u32 Spur,Sp1,Sp2;
- int I,J;
- I=0;
- J=1000;
-
- Spur=mt2060_spurcalc(lo1,lo2,if2);
- if (Spur < BANDWIDTH) {
- /* Potential spurs detected */
- dprintk("Spurs before : f_lo1: %d f_lo2: %d (kHz)",
- (int)lo1,(int)lo2);
- I=1000;
- Sp1 = mt2060_spurcalc(lo1+I,lo2+I,if2);
- Sp2 = mt2060_spurcalc(lo1-I,lo2-I,if2);
-
- if (Sp1 < Sp2) {
- J=-J; I=-I; Spur=Sp2;
- } else
- Spur=Sp1;
-
- while (Spur < BANDWIDTH) {
- I += J;
- Spur = mt2060_spurcalc(lo1+I,lo2+I,if2);
- }
- dprintk("Spurs after : f_lo1: %d f_lo2: %d (kHz)",
- (int)(lo1+I),(int)(lo2+I));
- }
- return I;
-}
-#endif
-
-#define IF2 36150 // IF2 frequency = 36.150 MHz
-#define FREF 16000 // Quartz oscillator 16 MHz
-
-static int mt2060_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
-{
- struct mt2060_priv *priv;
- int ret=0;
- int i=0;
- u32 freq;
- u8 lnaband;
- u32 f_lo1,f_lo2;
- u32 div1,num1,div2,num2;
- u8 b[8];
- u32 if1;
-
- priv = fe->tuner_priv;
-
- if1 = priv->if1_freq;
- b[0] = REG_LO1B1;
- b[1] = 0xFF;
-
- mt2060_writeregs(priv,b,2);
-
- freq = params->frequency / 1000; // Hz -> kHz
- priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
-
- f_lo1 = freq + if1 * 1000;
- f_lo1 = (f_lo1 / 250) * 250;
- f_lo2 = f_lo1 - freq - IF2;
- // From the Comtech datasheet, the step used is 50kHz. The tuner chip could be more precise
- f_lo2 = ((f_lo2 + 25) / 50) * 50;
- priv->frequency = (f_lo1 - f_lo2 - IF2) * 1000,
-
-#ifdef MT2060_SPURCHECK
- // LO-related spurs detection and correction
- num1 = mt2060_spurcheck(f_lo1,f_lo2,IF2);
- f_lo1 += num1;
- f_lo2 += num1;
-#endif
- //Frequency LO1 = 16MHz * (DIV1 + NUM1/64 )
- num1 = f_lo1 / (FREF / 64);
- div1 = num1 / 64;
- num1 &= 0x3f;
-
- // Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 )
- num2 = f_lo2 * 64 / (FREF / 128);
- div2 = num2 / 8192;
- num2 &= 0x1fff;
-
- if (freq <= 95000) lnaband = 0xB0; else
- if (freq <= 180000) lnaband = 0xA0; else
- if (freq <= 260000) lnaband = 0x90; else
- if (freq <= 335000) lnaband = 0x80; else
- if (freq <= 425000) lnaband = 0x70; else
- if (freq <= 480000) lnaband = 0x60; else
- if (freq <= 570000) lnaband = 0x50; else
- if (freq <= 645000) lnaband = 0x40; else
- if (freq <= 730000) lnaband = 0x30; else
- if (freq <= 810000) lnaband = 0x20; else lnaband = 0x10;
-
- b[0] = REG_LO1C1;
- b[1] = lnaband | ((num1 >>2) & 0x0F);
- b[2] = div1;
- b[3] = (num2 & 0x0F) | ((num1 & 3) << 4);
- b[4] = num2 >> 4;
- b[5] = ((num2 >>12) & 1) | (div2 << 1);
-
- dprintk("IF1: %dMHz",(int)if1);
- dprintk("PLL freq=%dkHz f_lo1=%dkHz f_lo2=%dkHz",(int)freq,(int)f_lo1,(int)f_lo2);
- dprintk("PLL div1=%d num1=%d div2=%d num2=%d",(int)div1,(int)num1,(int)div2,(int)num2);
- dprintk("PLL [1..5]: %2x %2x %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3],(int)b[4],(int)b[5]);
-
- mt2060_writeregs(priv,b,6);
-
- //Waits for pll lock or timeout
- i = 0;
- do {
- mt2060_readreg(priv,REG_LO_STATUS,b);
- if ((b[0] & 0x88)==0x88)
- break;
- msleep(4);
- i++;
- } while (i<10);
-
- return ret;
-}
-
-static void mt2060_calibrate(struct mt2060_priv *priv)
-{
- u8 b = 0;
- int i = 0;
-
- if (mt2060_writeregs(priv,mt2060_config1,sizeof(mt2060_config1)))
- return;
- if (mt2060_writeregs(priv,mt2060_config2,sizeof(mt2060_config2)))
- return;
-
- /* initialize the clock output */
- mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
-
- do {
- b |= (1 << 6); // FM1SS;
- mt2060_writereg(priv, REG_LO2C1,b);
- msleep(20);
-
- if (i == 0) {
- b |= (1 << 7); // FM1CA;
- mt2060_writereg(priv, REG_LO2C1,b);
- b &= ~(1 << 7); // FM1CA;
- msleep(20);
- }
-
- b &= ~(1 << 6); // FM1SS
- mt2060_writereg(priv, REG_LO2C1,b);
-
- msleep(20);
- i++;
- } while (i < 9);
-
- i = 0;
- while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
- msleep(20);
-
- if (i < 10) {
- mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
- dprintk("calibration was successful: %d", (int)priv->fmfreq);
- } else
- dprintk("FMCAL timed out");
-}
-
-static int mt2060_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
- struct mt2060_priv *priv = fe->tuner_priv;
- *frequency = priv->frequency;
- return 0;
-}
-
-static int mt2060_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
- struct mt2060_priv *priv = fe->tuner_priv;
- *bandwidth = priv->bandwidth;
- return 0;
-}
-
-static int mt2060_init(struct dvb_frontend *fe)
-{
- struct mt2060_priv *priv = fe->tuner_priv;
- return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x33);
-}
-
-static int mt2060_sleep(struct dvb_frontend *fe)
-{
- struct mt2060_priv *priv = fe->tuner_priv;
- return mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
-}
-
-static int mt2060_release(struct dvb_frontend *fe)
-{
- kfree(fe->tuner_priv);
- fe->tuner_priv = NULL;
- return 0;
-}
-
-static const struct dvb_tuner_ops mt2060_tuner_ops = {
- .info = {
- .name = "Microtune MT2060",
- .frequency_min = 48000000,
- .frequency_max = 860000000,
- .frequency_step = 50000,
- },
-
- .release = mt2060_release,
-
- .init = mt2060_init,
- .sleep = mt2060_sleep,
-
- .set_params = mt2060_set_params,
- .get_frequency = mt2060_get_frequency,
- .get_bandwidth = mt2060_get_bandwidth
-};
-
-/* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
-struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
-{
- struct mt2060_priv *priv = NULL;
- u8 id = 0;
-
- priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL);
- if (priv == NULL)
- return NULL;
-
- priv->cfg = cfg;
- priv->i2c = i2c;
- priv->if1_freq = if1;
-
- if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) {
- kfree(priv);
- return NULL;
- }
-
- if (id != PART_REV) {
- kfree(priv);
- return NULL;
- }
- printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1);
- memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops));
-
- fe->tuner_priv = priv;
-
- mt2060_calibrate(priv);
-
- return fe;
-}
-EXPORT_SYMBOL(mt2060_attach);
-
-MODULE_AUTHOR("Olivier DANET");
-MODULE_DESCRIPTION("Microtune MT2060 silicon tuner driver");
-MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/frontends/mt2060_priv.h b/linux/drivers/media/dvb/frontends/mt2060_priv.h
deleted file mode 100644
index 5eaccdefd..000000000
--- a/linux/drivers/media/dvb/frontends/mt2060_priv.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
- *
- * Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
- *
- * 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 MT2060_PRIV_H
-#define MT2060_PRIV_H
-
-// Uncomment the #define below to enable spurs checking. The results where quite unconvincing.
-// #define MT2060_SPURCHECK
-
-/* This driver is based on the information available in the datasheet of the
- "Comtech SDVBT-3K6M" tuner ( K1000737843.pdf ) which features the MT2060 register map :
-
- I2C Address : 0x60
-
- Reg.No | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | ( defaults )
- --------------------------------------------------------------------------------
- 00 | [ PART ] | [ REV ] | R = 0x63
- 01 | [ LNABAND ] | [ NUM1(5:2) ] | RW = 0x3F
- 02 | [ DIV1 ] | RW = 0x74
- 03 | FM1CA | FM1SS | [ NUM1(1:0) ] | [ NUM2(3:0) ] | RW = 0x00
- 04 | NUM2(11:4) ] | RW = 0x08
- 05 | [ DIV2 ] |NUM2(12)| RW = 0x93
- 06 | L1LK | [ TAD1 ] | L2LK | [ TAD2 ] | R
- 07 | [ FMF ] | R
- 08 | ? | FMCAL | ? | ? | ? | ? | ? | TEMP | R
- 09 | 0 | 0 | [ FMGC ] | 0 | GP02 | GP01 | 0 | RW = 0x20
- 0A | ??
- 0B | 0 | 0 | 1 | 1 | 0 | 0 | [ VGAG ] | RW = 0x30
- 0C | V1CSE | 1 | 1 | 1 | 1 | 1 | 1 | 1 | RW = 0xFF
- 0D | 1 | 0 | [ V1CS ] | RW = 0xB0
- 0E | ??
- 0F | ??
- 10 | ??
- 11 | [ LOTO ] | 0 | 0 | 1 | 0 | RW = 0x42
-
- PART : Part code : 6 for MT2060
- REV : Revision code : 3 for current revision
- LNABAND : Input frequency range : ( See code for details )
- NUM1 / DIV1 / NUM2 / DIV2 : Frequencies programming ( See code for details )
- FM1CA : Calibration Start Bit
- FM1SS : Calibration Single Step bit
- L1LK : LO1 Lock Detect
- TAD1 : Tune Line ADC ( ? )
- L2LK : LO2 Lock Detect
- TAD2 : Tune Line ADC ( ? )
- FMF : Estimated first IF Center frequency Offset ( ? )
- FM1CAL : Calibration done bit
- TEMP : On chip temperature sensor
- FMCG : Mixer 1 Cap Gain ( ? )
- GP01 / GP02 : Programmable digital outputs. Unconnected pins ?
- V1CSE : LO1 VCO Automatic Capacitor Select Enable ( ? )
- V1CS : LO1 Capacitor Selection Value ( ? )
- LOTO : LO Timeout ( ? )
- VGAG : Tuner Output gain
-*/
-
-#define I2C_ADDRESS 0x60
-
-#define REG_PART_REV 0
-#define REG_LO1C1 1
-#define REG_LO1C2 2
-#define REG_LO2C1 3
-#define REG_LO2C2 4
-#define REG_LO2C3 5
-#define REG_LO_STATUS 6
-#define REG_FM_FREQ 7
-#define REG_MISC_STAT 8
-#define REG_MISC_CTRL 9
-#define REG_RESERVED_A 0x0A
-#define REG_VGAG 0x0B
-#define REG_LO1B1 0x0C
-#define REG_LO1B2 0x0D
-#define REG_LOTO 0x11
-
-#define PART_REV 0x63 // The current driver works only with PART=6 and REV=3 chips
-
-struct mt2060_priv {
- struct mt2060_config *cfg;
- struct i2c_adapter *i2c;
-
- u32 frequency;
- u32 bandwidth;
- u16 if1_freq;
- u8 fmfreq;
-};
-
-#endif
diff --git a/linux/drivers/media/dvb/frontends/mt2131.c b/linux/drivers/media/dvb/frontends/mt2131.c
deleted file mode 100644
index 47e081c2e..000000000
--- a/linux/drivers/media/dvb/frontends/mt2131.c
+++ /dev/null
@@ -1,315 +0,0 @@
-/*
- * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
- *
- * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
- *
- * 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 "compat.h"
-
-#include "dvb_frontend.h"
-
-#include "mt2131.h"
-#include "mt2131_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(level,fmt, arg...) if (debug >= level) \
- printk(KERN_INFO "%s: " fmt, "mt2131", ## arg)
-
-static u8 mt2131_config1[] = {
- 0x01,
- 0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88,
- 0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
- 0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80,
- 0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00
-};
-
-static u8 mt2131_config2[] = {
- 0x10,
- 0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
-};
-
-static int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val)
-{
- struct i2c_msg msg[2] = {
- { .addr = priv->cfg->i2c_address, .flags = 0,
- .buf = &reg, .len = 1 },
- { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
- .buf = val, .len = 1 },
- };
-
- if (i2c_transfer(priv->i2c, msg, 2) != 2) {
- printk(KERN_WARNING "mt2131 I2C read failed\n");
- return -EREMOTEIO;
- }
- return 0;
-}
-
-static int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val)
-{
- u8 buf[2] = { reg, val };
- struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
- .buf = buf, .len = 2 };
-
- if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
- printk(KERN_WARNING "mt2131 I2C write failed\n");
- return -EREMOTEIO;
- }
- return 0;
-}
-
-static int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len)
-{
- struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
- .flags = 0, .buf = buf, .len = len };
-
- if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
- printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n",
- (int)len);
- return -EREMOTEIO;
- }
- return 0;
-}
-
-static int mt2131_set_params(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *params)
-{
- struct mt2131_priv *priv;
- int ret=0, i;
- u32 freq;
- u8 if_band_center;
- u32 f_lo1, f_lo2;
- u32 div1, num1, div2, num2;
- u8 b[8];
- u8 lockval = 0;
-
- priv = fe->tuner_priv;
- if (fe->ops.info.type == FE_OFDM)
- priv->bandwidth = params->u.ofdm.bandwidth;
- else
- priv->bandwidth = 0;
-
- freq = params->frequency / 1000; // Hz -> kHz
- dprintk(1, "%s() freq=%d\n", __FUNCTION__, freq);
-
- f_lo1 = freq + MT2131_IF1 * 1000;
- f_lo1 = (f_lo1 / 250) * 250;
- f_lo2 = f_lo1 - freq - MT2131_IF2;
-
- priv->frequency = (f_lo1 - f_lo2 - MT2131_IF2) * 1000;
-
- /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
- num1 = f_lo1 * 64 / (MT2131_FREF / 128);
- div1 = num1 / 8192;
- num1 &= 0x1fff;
-
- /* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */
- num2 = f_lo2 * 64 / (MT2131_FREF / 128);
- div2 = num2 / 8192;
- num2 &= 0x1fff;
-
- if (freq <= 82500) if_band_center = 0x00; else
- if (freq <= 137500) if_band_center = 0x01; else
- if (freq <= 192500) if_band_center = 0x02; else
- if (freq <= 247500) if_band_center = 0x03; else
- if (freq <= 302500) if_band_center = 0x04; else
- if (freq <= 357500) if_band_center = 0x05; else
- if (freq <= 412500) if_band_center = 0x06; else
- if (freq <= 467500) if_band_center = 0x07; else
- if (freq <= 522500) if_band_center = 0x08; else
- if (freq <= 577500) if_band_center = 0x09; else
- if (freq <= 632500) if_band_center = 0x0A; else
- if (freq <= 687500) if_band_center = 0x0B; else
- if (freq <= 742500) if_band_center = 0x0C; else
- if (freq <= 797500) if_band_center = 0x0D; else
- if (freq <= 852500) if_band_center = 0x0E; else
- if (freq <= 907500) if_band_center = 0x0F; else
- if (freq <= 962500) if_band_center = 0x10; else
- if (freq <= 1017500) if_band_center = 0x11; else
- if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13;
-
- b[0] = 1;
- b[1] = (num1 >> 5) & 0xFF;
- b[2] = (num1 & 0x1F);
- b[3] = div1;
- b[4] = (num2 >> 5) & 0xFF;
- b[5] = num2 & 0x1F;
- b[6] = div2;
-
- dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2);
- dprintk(1, "PLL freq=%dkHz band=%d\n", (int)freq, (int)if_band_center);
- dprintk(1, "PLL f_lo1=%dkHz f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2);
- dprintk(1, "PLL div1=%d num1=%d div2=%d num2=%d\n",
- (int)div1, (int)num1, (int)div2, (int)num2);
- dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n",
- (int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5],
- (int)b[6]);
-
- ret = mt2131_writeregs(priv,b,7);
- if (ret < 0)
- return ret;
-
- mt2131_writereg(priv, 0x0b, if_band_center);
-
- /* Wait for lock */
- i = 0;
- do {
- mt2131_readreg(priv, 0x08, &lockval);
- if ((lockval & 0x88) == 0x88)
- break;
- msleep(4);
- i++;
- } while (i < 10);
-
- return ret;
-}
-
-static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
- struct mt2131_priv *priv = fe->tuner_priv;
- dprintk(1, "%s()\n", __FUNCTION__);
- *frequency = priv->frequency;
- return 0;
-}
-
-static int mt2131_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
- struct mt2131_priv *priv = fe->tuner_priv;
- dprintk(1, "%s()\n", __FUNCTION__);
- *bandwidth = priv->bandwidth;
- return 0;
-}
-
-static int mt2131_get_status(struct dvb_frontend *fe, u32 *status)
-{
- struct mt2131_priv *priv = fe->tuner_priv;
- u8 lock_status = 0;
- u8 afc_status = 0;
-
- *status = 0;
-
- mt2131_readreg(priv, 0x08, &lock_status);
- if ((lock_status & 0x88) == 0x88)
- *status = TUNER_STATUS_LOCKED;
-
- mt2131_readreg(priv, 0x09, &afc_status);
- dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n",
- __FUNCTION__, lock_status, afc_status);
-
- return 0;
-}
-
-static int mt2131_init(struct dvb_frontend *fe)
-{
- struct mt2131_priv *priv = fe->tuner_priv;
- int ret;
- dprintk(1, "%s()\n", __FUNCTION__);
-
- if ((ret = mt2131_writeregs(priv, mt2131_config1,
- sizeof(mt2131_config1))) < 0)
- return ret;
-
- mt2131_writereg(priv, 0x0b, 0x09);
- mt2131_writereg(priv, 0x15, 0x47);
- mt2131_writereg(priv, 0x07, 0xf2);
- mt2131_writereg(priv, 0x0b, 0x01);
-
- if ((ret = mt2131_writeregs(priv, mt2131_config2,
- sizeof(mt2131_config2))) < 0)
- return ret;
-
- return ret;
-}
-
-static int mt2131_release(struct dvb_frontend *fe)
-{
- dprintk(1, "%s()\n", __FUNCTION__);
- kfree(fe->tuner_priv);
- fe->tuner_priv = NULL;
- return 0;
-}
-
-static const struct dvb_tuner_ops mt2131_tuner_ops = {
- .info = {
- .name = "Microtune MT2131",
- .frequency_min = 48000000,
- .frequency_max = 860000000,
- .frequency_step = 50000,
- },
-
- .release = mt2131_release,
- .init = mt2131_init,
-
- .set_params = mt2131_set_params,
- .get_frequency = mt2131_get_frequency,
- .get_bandwidth = mt2131_get_bandwidth,
- .get_status = mt2131_get_status
-};
-
-struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct mt2131_config *cfg, u16 if1)
-{
- struct mt2131_priv *priv = NULL;
- u8 id = 0;
-
- dprintk(1, "%s()\n", __FUNCTION__);
-
- priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL);
- if (priv == NULL)
- return NULL;
-
- priv->cfg = cfg;
- priv->bandwidth = 6000000; /* 6MHz */
- priv->i2c = i2c;
-
- if (mt2131_readreg(priv, 0, &id) != 0) {
- kfree(priv);
- return NULL;
- }
- if ( (id != 0x3E) && (id != 0x3F) ) {
- printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n",
- cfg->i2c_address);
- kfree(priv);
- return NULL;
- }
-
- printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n",
- cfg->i2c_address);
- memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops,
- sizeof(struct dvb_tuner_ops));
-
- fe->tuner_priv = priv;
- return fe;
-}
-EXPORT_SYMBOL(mt2131_attach);
-
-MODULE_AUTHOR("Steven Toth");
-MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
-MODULE_LICENSE("GPL");
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/linux/drivers/media/dvb/frontends/mt2131.h b/linux/drivers/media/dvb/frontends/mt2131.h
deleted file mode 100644
index 1e4ffe7dc..000000000
--- a/linux/drivers/media/dvb/frontends/mt2131.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
- *
- * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
- *
- * 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 __MT2131_H__
-#define __MT2131_H__
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct mt2131_config {
- u8 i2c_address;
- u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
-};
-
-#if defined(CONFIG_DVB_TUNER_MT2131) || (defined(CONFIG_DVB_TUNER_MT2131_MODULE) && defined(MODULE))
-extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct mt2131_config *cfg,
- u16 if1);
-#else
-static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct mt2131_config *cfg,
- u16 if1)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
- return NULL;
-}
-#endif /* CONFIG_DVB_TUNER_MT2131 */
-
-#endif /* __MT2131_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/linux/drivers/media/dvb/frontends/mt2131_priv.h b/linux/drivers/media/dvb/frontends/mt2131_priv.h
deleted file mode 100644
index e930759c2..000000000
--- a/linux/drivers/media/dvb/frontends/mt2131_priv.h
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
- *
- * Copyright (c) 2006 Steven Toth <stoth@hauppauge.com>
- *
- * 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 __MT2131_PRIV_H__
-#define __MT2131_PRIV_H__
-
-/* Regs */
-#define MT2131_PWR 0x07
-#define MT2131_UPC_1 0x0b
-#define MT2131_AGC_RL 0x10
-#define MT2131_MISC_2 0x15
-
-/* frequency values in KHz */
-#define MT2131_IF1 1220
-#define MT2131_IF2 44000
-#define MT2131_FREF 16000
-
-struct mt2131_priv {
- struct mt2131_config *cfg;
- struct i2c_adapter *i2c;
-
- u32 frequency;
- u32 bandwidth;
-};
-
-#endif /* __MT2131_PRIV_H__ */
-
-/*
- * Local variables:
- * c-basic-offset: 8
- */
diff --git a/linux/drivers/media/dvb/frontends/mt2266.c b/linux/drivers/media/dvb/frontends/mt2266.c
deleted file mode 100644
index 9927a1a55..000000000
--- a/linux/drivers/media/dvb/frontends/mt2266.c
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
- *
- * Copyright (c) 2007 Olivier DANET <odanet@caramail.com>
- *
- * 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.
- */
-
-#include <linux/module.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-#include "compat.h"
-
-#include "dvb_frontend.h"
-#include "mt2266.h"
-
-#define I2C_ADDRESS 0x60
-
-#define REG_PART_REV 0
-#define REG_TUNE 1
-#define REG_BAND 6
-#define REG_BANDWIDTH 8
-#define REG_LOCK 0x12
-
-#define PART_REV 0x85
-
-struct mt2266_priv {
- struct mt2266_config *cfg;
- struct i2c_adapter *i2c;
-
- u32 frequency;
- u32 bandwidth;
- u8 band;
-};
-
-#define MT2266_VHF 1
-#define MT2266_UHF 0
-
-/* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2266: " args); printk("\n"); }} while (0)
-
-// Reads a single register
-static int mt2266_readreg(struct mt2266_priv *priv, u8 reg, u8 *val)
-{
- struct i2c_msg msg[2] = {
- { .addr = priv->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 },
- { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 },
- };
- if (i2c_transfer(priv->i2c, msg, 2) != 2) {
- printk(KERN_WARNING "MT2266 I2C read failed\n");
- return -EREMOTEIO;
- }
- return 0;
-}
-
-// Writes a single register
-static int mt2266_writereg(struct mt2266_priv *priv, u8 reg, u8 val)
-{
- u8 buf[2] = { reg, val };
- struct i2c_msg msg = {
- .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
- };
- if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
- printk(KERN_WARNING "MT2266 I2C write failed\n");
- return -EREMOTEIO;
- }
- return 0;
-}
-
-// Writes a set of consecutive registers
-static int mt2266_writeregs(struct mt2266_priv *priv,u8 *buf, u8 len)
-{
- struct i2c_msg msg = {
- .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
- };
- if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
- printk(KERN_WARNING "MT2266 I2C write failed (len=%i)\n",(int)len);
- return -EREMOTEIO;
- }
- return 0;
-}
-
-// Initialisation sequences
-static u8 mt2266_init1[] = { REG_TUNE, 0x00, 0x00, 0x28,
- 0x00, 0x52, 0x99, 0x3f };
-
-static u8 mt2266_init2[] = {
- 0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 0xd4,
- 0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff,
- 0xff, 0x00, 0x77, 0x0f, 0x2d
-};
-
-static u8 mt2266_init_8mhz[] = { REG_BANDWIDTH, 0x22, 0x22, 0x22, 0x22,
- 0x22, 0x22, 0x22, 0x22 };
-
-static u8 mt2266_init_7mhz[] = { REG_BANDWIDTH, 0x32, 0x32, 0x32, 0x32,
- 0x32, 0x32, 0x32, 0x32 };
-
-static u8 mt2266_init_6mhz[] = { REG_BANDWIDTH, 0xa7, 0xa7, 0xa7, 0xa7,
- 0xa7, 0xa7, 0xa7, 0xa7 };
-
-static u8 mt2266_uhf[] = { 0x1d, 0xdc, 0x00, 0x0a, 0xd4, 0x03, 0x64, 0x64,
- 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14 };
-
-static u8 mt2266_vhf[] = { 0x1d, 0xfe, 0x00, 0x00, 0xb4, 0x03, 0xa5, 0xa5,
- 0xa5, 0xa5, 0x82, 0xaa, 0xf1, 0x17, 0x80, 0x1f };
-
-#define FREF 30000 // Quartz oscillator 30 MHz
-
-static int mt2266_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
-{
- struct mt2266_priv *priv;
- int ret=0;
- u32 freq;
- u32 tune;
- u8 lnaband;
- u8 b[10];
- int i;
- u8 band;
-
- priv = fe->tuner_priv;
-
- freq = params->frequency / 1000; // Hz -> kHz
- if (freq < 470000 && freq > 230000)
- return -EINVAL; /* Gap between VHF and UHF bands */
- priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
- priv->frequency = freq * 1000;
-
- tune = 2 * freq * (8192/16) / (FREF/16);
- band = (freq < 300000) ? MT2266_VHF : MT2266_UHF;
- if (band == MT2266_VHF)
- tune *= 2;
-
- switch (params->u.ofdm.bandwidth) {
- case BANDWIDTH_6_MHZ:
- mt2266_writeregs(priv, mt2266_init_6mhz,
- sizeof(mt2266_init_6mhz));
- break;
- case BANDWIDTH_7_MHZ:
- mt2266_writeregs(priv, mt2266_init_7mhz,
- sizeof(mt2266_init_7mhz));
- break;
- case BANDWIDTH_8_MHZ:
- default:
- mt2266_writeregs(priv, mt2266_init_8mhz,
- sizeof(mt2266_init_8mhz));
- break;
- }
-
- if (band == MT2266_VHF && priv->band == MT2266_UHF) {
- dprintk("Switch from UHF to VHF");
- mt2266_writereg(priv, 0x05, 0x04);
- mt2266_writereg(priv, 0x19, 0x61);
- mt2266_writeregs(priv, mt2266_vhf, sizeof(mt2266_vhf));
- } else if (band == MT2266_UHF && priv->band == MT2266_VHF) {
- dprintk("Switch from VHF to UHF");
- mt2266_writereg(priv, 0x05, 0x52);
- mt2266_writereg(priv, 0x19, 0x61);
- mt2266_writeregs(priv, mt2266_uhf, sizeof(mt2266_uhf));
- }
- msleep(10);
-
- if (freq <= 495000)
- lnaband = 0xEE;
- else if (freq <= 525000)
- lnaband = 0xDD;
- else if (freq <= 550000)
- lnaband = 0xCC;
- else if (freq <= 580000)
- lnaband = 0xBB;
- else if (freq <= 605000)
- lnaband = 0xAA;
- else if (freq <= 630000)
- lnaband = 0x99;
- else if (freq <= 655000)
- lnaband = 0x88;
- else if (freq <= 685000)
- lnaband = 0x77;
- else if (freq <= 710000)
- lnaband = 0x66;
- else if (freq <= 735000)
- lnaband = 0x55;
- else if (freq <= 765000)
- lnaband = 0x44;
- else if (freq <= 802000)
- lnaband = 0x33;
- else if (freq <= 840000)
- lnaband = 0x22;
- else
- lnaband = 0x11;
-
- b[0] = REG_TUNE;
- b[1] = (tune >> 8) & 0x1F;
- b[2] = tune & 0xFF;
- b[3] = tune >> 13;
- mt2266_writeregs(priv,b,4);
-
- dprintk("set_parms: tune=%d band=%d %s",
- (int) tune, (int) lnaband,
- (band == MT2266_UHF) ? "UHF" : "VHF");
- dprintk("set_parms: [1..3]: %2x %2x %2x",
- (int) b[1], (int) b[2], (int)b[3]);
-
- if (band == MT2266_UHF) {
- b[0] = 0x05;
- b[1] = (priv->band == MT2266_VHF) ? 0x52 : 0x62;
- b[2] = lnaband;
- mt2266_writeregs(priv, b, 3);
- }
-
- /* Wait for pll lock or timeout */
- i = 0;
- do {
- mt2266_readreg(priv,REG_LOCK,b);
- if (b[0] & 0x40)
- break;
- msleep(10);
- i++;
- } while (i<10);
- dprintk("Lock when i=%i",(int)i);
-
- if (band == MT2266_UHF && priv->band == MT2266_VHF)
- mt2266_writereg(priv, 0x05, 0x62);
-
- priv->band = band;
-
- return ret;
-}
-
-static void mt2266_calibrate(struct mt2266_priv *priv)
-{
- mt2266_writereg(priv, 0x11, 0x03);
- mt2266_writereg(priv, 0x11, 0x01);
- mt2266_writeregs(priv, mt2266_init1, sizeof(mt2266_init1));
- mt2266_writeregs(priv, mt2266_init2, sizeof(mt2266_init2));
- mt2266_writereg(priv, 0x33, 0x5e);
- mt2266_writereg(priv, 0x10, 0x10);
- mt2266_writereg(priv, 0x10, 0x00);
- mt2266_writeregs(priv, mt2266_init_8mhz, sizeof(mt2266_init_8mhz));
- msleep(25);
- mt2266_writereg(priv, 0x17, 0x6d);
- mt2266_writereg(priv, 0x1c, 0x00);
- msleep(75);
- mt2266_writereg(priv, 0x17, 0x6d);
- mt2266_writereg(priv, 0x1c, 0xff);
-}
-
-static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
- struct mt2266_priv *priv = fe->tuner_priv;
- *frequency = priv->frequency;
- return 0;
-}
-
-static int mt2266_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
- struct mt2266_priv *priv = fe->tuner_priv;
- *bandwidth = priv->bandwidth;
- return 0;
-}
-
-static int mt2266_init(struct dvb_frontend *fe)
-{
- int ret;
- struct mt2266_priv *priv = fe->tuner_priv;
- ret = mt2266_writereg(priv, 0x17, 0x6d);
- if (ret < 0)
- return ret;
- ret = mt2266_writereg(priv, 0x1c, 0xff);
- if (ret < 0)
- return ret;
- return 0;
-}
-
-static int mt2266_sleep(struct dvb_frontend *fe)
-{
- struct mt2266_priv *priv = fe->tuner_priv;
- mt2266_writereg(priv, 0x17, 0x6d);
- mt2266_writereg(priv, 0x1c, 0x00);
- return 0;
-}
-
-static int mt2266_release(struct dvb_frontend *fe)
-{
- kfree(fe->tuner_priv);
- fe->tuner_priv = NULL;
- return 0;
-}
-
-static const struct dvb_tuner_ops mt2266_tuner_ops = {
- .info = {
- .name = "Microtune MT2266",
- .frequency_min = 174000000,
- .frequency_max = 862000000,
- .frequency_step = 50000,
- },
- .release = mt2266_release,
- .init = mt2266_init,
- .sleep = mt2266_sleep,
- .set_params = mt2266_set_params,
- .get_frequency = mt2266_get_frequency,
- .get_bandwidth = mt2266_get_bandwidth
-};
-
-struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
-{
- struct mt2266_priv *priv = NULL;
- u8 id = 0;
-
- priv = kzalloc(sizeof(struct mt2266_priv), GFP_KERNEL);
- if (priv == NULL)
- return NULL;
-
- priv->cfg = cfg;
- priv->i2c = i2c;
- priv->band = MT2266_UHF;
-
- if (mt2266_readreg(priv, 0, &id)) {
- kfree(priv);
- return NULL;
- }
- if (id != PART_REV) {
- kfree(priv);
- return NULL;
- }
- printk(KERN_INFO "MT2266: successfully identified\n");
- memcpy(&fe->ops.tuner_ops, &mt2266_tuner_ops, sizeof(struct dvb_tuner_ops));
-
- fe->tuner_priv = priv;
- mt2266_calibrate(priv);
- return fe;
-}
-EXPORT_SYMBOL(mt2266_attach);
-
-MODULE_AUTHOR("Olivier DANET");
-MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver");
-MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/frontends/mt2266.h b/linux/drivers/media/dvb/frontends/mt2266.h
deleted file mode 100644
index f31dd613a..000000000
--- a/linux/drivers/media/dvb/frontends/mt2266.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
- *
- * Copyright (c) 2007 Olivier DANET <odanet@caramail.com>
- *
- * 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.
- */
-
-#ifndef MT2266_H
-#define MT2266_H
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct mt2266_config {
- u8 i2c_address;
-};
-
-#if defined(CONFIG_DVB_TUNER_MT2266) || (defined(CONFIG_DVB_TUNER_MT2266_MODULE) && defined(MODULE))
-extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg);
-#else
-static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
- return NULL;
-}
-#endif // CONFIG_DVB_TUNER_MT2266
-
-#endif
diff --git a/linux/drivers/media/dvb/frontends/mt312.c b/linux/drivers/media/dvb/frontends/mt312.c
index 1638301fb..5ac9b1592 100644
--- a/linux/drivers/media/dvb/frontends/mt312.c
+++ b/linux/drivers/media/dvb/frontends/mt312.c
@@ -1,7 +1,8 @@
/*
- Driver for Zarlink VP310/MT312 Satellite Channel Decoder
+ Driver for Zarlink VP310/MT312/ZL10313 Satellite Channel Decoder
Copyright (C) 2003 Andreas Oberritter <obi@linuxtv.org>
+ Copyright (C) 2008 Matthias Schwarzott <zzam@gentoo.org>
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
@@ -43,7 +44,8 @@ struct mt312_state {
struct dvb_frontend frontend;
u8 id;
- u8 frequency;
+ unsigned long xtal;
+ u8 freq_mult;
};
static int debug;
@@ -53,12 +55,11 @@ static int debug;
printk(KERN_DEBUG "mt312: " args); \
} while (0)
-#define MT312_SYS_CLK 90000000UL /* 90 MHz */
-#define MT312_LPOWER_SYS_CLK 60000000UL /* 60 MHz */
#define MT312_PLL_CLK 10000000UL /* 10 MHz */
+#define MT312_PLL_CLK_10_111 10111000UL /* 10.111 MHz */
static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
- void *buf, const size_t count)
+ u8 *buf, const size_t count)
{
int ret;
struct i2c_msg msg[2];
@@ -76,7 +77,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2) {
- printk(KERN_ERR "%s: ret == %d\n", __FUNCTION__, ret);
+ printk(KERN_ERR "%s: ret == %d\n", __func__, ret);
return -EREMOTEIO;
}
@@ -84,7 +85,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
int i;
dprintk("R(%d):", reg & 0x7f);
for (i = 0; i < count; i++)
- printk(" %02x", ((const u8 *) buf)[i]);
+ printk(" %02x", buf[i]);
printk("\n");
}
@@ -92,7 +93,7 @@ static int mt312_read(struct mt312_state *state, const enum mt312_reg_addr reg,
}
static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
- const void *src, const size_t count)
+ const u8 *src, const size_t count)
{
int ret;
u8 buf[count + 1];
@@ -102,7 +103,7 @@ static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
int i;
dprintk("W(%d):", reg & 0x7f);
for (i = 0; i < count; i++)
- printk(" %02x", ((const u8 *) src)[i]);
+ printk(" %02x", src[i]);
printk("\n");
}
@@ -117,7 +118,7 @@ static int mt312_write(struct mt312_state *state, const enum mt312_reg_addr reg,
ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 1) {
- dprintk("%s: ret == %d\n", __FUNCTION__, ret);
+ dprintk("%s: ret == %d\n", __func__, ret);
return -EREMOTEIO;
}
@@ -209,7 +210,7 @@ static int mt312_get_symbol_rate(struct mt312_state *state, u32 *sr)
dprintk("sym_rat_op=%d dec_ratio=%d\n",
sym_rat_op, dec_ratio);
dprintk("*sr(manual) = %lu\n",
- (((MT312_PLL_CLK * 8192) / (sym_rat_op + 8192)) *
+ (((state->xtal * 8192) / (sym_rat_op + 8192)) *
2) - dec_ratio);
}
@@ -242,7 +243,7 @@ static int mt312_initfe(struct dvb_frontend *fe)
/* wake up */
ret = mt312_writereg(state, CONFIG,
- (state->frequency == 60 ? 0x88 : 0x8c));
+ (state->freq_mult == 6 ? 0x88 : 0x8c));
if (ret < 0)
return ret;
@@ -265,12 +266,37 @@ static int mt312_initfe(struct dvb_frontend *fe)
return ret;
}
+ switch (state->id) {
+ case ID_ZL10313:
+ /* enable ADC */
+ ret = mt312_writereg(state, GPP_CTRL, 0x80);
+ if (ret < 0)
+ return ret;
+
+ /* configure ZL10313 for optimal ADC performance */
+ buf[0] = 0x80;
+ buf[1] = 0xB0;
+ ret = mt312_write(state, HW_CTRL, buf, 2);
+ if (ret < 0)
+ return ret;
+
+ /* enable MPEG output and ADCs */
+ ret = mt312_writereg(state, HW_CTRL, 0x00);
+ if (ret < 0)
+ return ret;
+
+ ret = mt312_writereg(state, MPEG_CTRL, 0x00);
+ if (ret < 0)
+ return ret;
+
+ break;
+ }
+
/* SYS_CLK */
- buf[0] = mt312_div((state->frequency == 60 ? MT312_LPOWER_SYS_CLK :
- MT312_SYS_CLK) * 2, 1000000);
+ buf[0] = mt312_div(state->xtal * state->freq_mult * 2, 1000000);
/* DISEQC_RATIO */
- buf[1] = mt312_div(MT312_PLL_CLK, 15000 * 4);
+ buf[1] = mt312_div(state->xtal, 22000 * 4);
ret = mt312_write(state, SYS_CLK, buf, sizeof(buf));
if (ret < 0)
@@ -280,7 +306,17 @@ static int mt312_initfe(struct dvb_frontend *fe)
if (ret < 0)
return ret;
- ret = mt312_writereg(state, OP_CTRL, 0x53);
+ /* different MOCLK polarity */
+ switch (state->id) {
+ case ID_ZL10313:
+ buf[0] = 0x33;
+ break;
+ default:
+ buf[0] = 0x53;
+ break;
+ }
+
+ ret = mt312_writereg(state, OP_CTRL, buf[0]);
if (ret < 0)
return ret;
@@ -323,6 +359,9 @@ static int mt312_send_master_cmd(struct dvb_frontend *fe,
if (ret < 0)
return ret;
+ /* is there a better way to wait for message to be transmitted */
+ msleep(100);
+
/* set DISEQC_MODE[2:0] to zero if a return message is expected */
if (c->msg[0] & 0x02) {
ret = mt312_writereg(state, DISEQC_MODE, (diseqc_mode & 0x40));
@@ -383,11 +422,16 @@ static int mt312_set_voltage(struct dvb_frontend *fe, const fe_sec_voltage_t v)
{
struct mt312_state *state = fe->demodulator_priv;
const u8 volt_tab[3] = { 0x00, 0x40, 0x00 };
+ u8 val;
if (v > SEC_VOLTAGE_OFF)
return -EINVAL;
- return mt312_writereg(state, DISEQC_MODE, volt_tab[v]);
+ val = volt_tab[v];
+ if (state->config->voltage_inverted)
+ val ^= 0x40;
+
+ return mt312_writereg(state, DISEQC_MODE, val);
}
static int mt312_read_status(struct dvb_frontend *fe, fe_status_t *s)
@@ -463,7 +507,7 @@ static int mt312_read_snr(struct dvb_frontend *fe, u16 *snr)
int ret;
u8 buf[2];
- ret = mt312_read(state, M_SNR_H, &buf, sizeof(buf));
+ ret = mt312_read(state, M_SNR_H, buf, sizeof(buf));
if (ret < 0)
return ret;
@@ -478,7 +522,7 @@ static int mt312_read_ucblocks(struct dvb_frontend *fe, u32 *ubc)
int ret;
u8 buf[2];
- ret = mt312_read(state, RS_UBC_H, &buf, sizeof(buf));
+ ret = mt312_read(state, RS_UBC_H, buf, sizeof(buf));
if (ret < 0)
return ret;
@@ -499,7 +543,7 @@ static int mt312_set_frontend(struct dvb_frontend *fe,
{ 0x00, 0x01, 0x02, 0x04, 0x3f, 0x08, 0x10, 0x20, 0x3f, 0x3f };
const u8 inv_tab[3] = { 0x00, 0x40, 0x80 };
- dprintk("%s: Freq %d\n", __FUNCTION__, p->frequency);
+ dprintk("%s: Freq %d\n", __func__, p->frequency);
if ((p->frequency < fe->ops.info.frequency_min)
|| (p->frequency > fe->ops.info.frequency_max))
@@ -532,17 +576,17 @@ static int mt312_set_frontend(struct dvb_frontend *fe,
return ret;
if (p->u.qpsk.symbol_rate >= 30000000) {
/* Note that 30MS/s should use 90MHz */
- if ((config_val & 0x0c) == 0x08) {
+ if (state->freq_mult == 6) {
/* We are running 60MHz */
- state->frequency = 90;
+ state->freq_mult = 9;
ret = mt312_initfe(fe);
if (ret < 0)
return ret;
}
} else {
- if ((config_val & 0x0c) == 0x0C) {
+ if (state->freq_mult == 9) {
/* We are running 90MHz */
- state->frequency = 60;
+ state->freq_mult = 6;
ret = mt312_initfe(fe);
if (ret < 0)
return ret;
@@ -551,6 +595,7 @@ static int mt312_set_frontend(struct dvb_frontend *fe,
break;
case ID_MT312:
+ case ID_ZL10313:
break;
default:
@@ -616,11 +661,29 @@ static int mt312_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
{
struct mt312_state *state = fe->demodulator_priv;
- if (enable) {
- return mt312_writereg(state, GPP_CTRL, 0x40);
- } else {
- return mt312_writereg(state, GPP_CTRL, 0x00);
+ u8 val = 0x00;
+ int ret;
+
+ switch (state->id) {
+ case ID_ZL10313:
+ ret = mt312_readreg(state, GPP_CTRL, &val);
+ if (ret < 0)
+ goto error;
+
+ /* preserve this bit to not accidently shutdown ADC */
+ val &= 0x80;
+ break;
}
+
+ if (enable)
+ val |= 0x40;
+ else
+ val &= ~0x40;
+
+ ret = mt312_writereg(state, GPP_CTRL, val);
+
+error:
+ return ret;
}
static int mt312_sleep(struct dvb_frontend *fe)
@@ -634,6 +697,18 @@ static int mt312_sleep(struct dvb_frontend *fe)
if (ret < 0)
return ret;
+ if (state->id == ID_ZL10313) {
+ /* reset ADC */
+ ret = mt312_writereg(state, GPP_CTRL, 0x00);
+ if (ret < 0)
+ return ret;
+
+ /* full shutdown of ADCs, mpeg bus tristated */
+ ret = mt312_writereg(state, HW_CTRL, 0x0d);
+ if (ret < 0)
+ return ret;
+ }
+
ret = mt312_readreg(state, CONFIG, &config);
if (ret < 0)
return ret;
@@ -661,15 +736,16 @@ static void mt312_release(struct dvb_frontend *fe)
kfree(state);
}
-static struct dvb_frontend_ops vp310_mt312_ops = {
+#define MT312_SYS_CLK 90000000UL /* 90 MHz */
+static struct dvb_frontend_ops mt312_ops = {
.info = {
.name = "Zarlink ???? DVB-S",
.type = FE_QPSK,
.frequency_min = 950000,
.frequency_max = 2150000,
- .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128,
- .symbol_rate_min = MT312_SYS_CLK / 128,
+ .frequency_stepsize = (MT312_PLL_CLK / 1000) / 128, /* FIXME: adjust freq to real used xtal */
+ .symbol_rate_min = MT312_SYS_CLK / 128, /* FIXME as above */
.symbol_rate_max = MT312_SYS_CLK / 2,
.caps =
FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 |
@@ -700,7 +776,7 @@ static struct dvb_frontend_ops vp310_mt312_ops = {
.set_voltage = mt312_set_voltage,
};
-struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
+struct dvb_frontend *mt312_attach(const struct mt312_config *config,
struct i2c_adapter *i2c)
{
struct mt312_state *state = NULL;
@@ -719,21 +795,28 @@ struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
goto error;
/* create dvb_frontend */
- memcpy(&state->frontend.ops, &vp310_mt312_ops,
+ memcpy(&state->frontend.ops, &mt312_ops,
sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
switch (state->id) {
case ID_VP310:
strcpy(state->frontend.ops.info.name, "Zarlink VP310 DVB-S");
- state->frequency = 90;
+ state->xtal = MT312_PLL_CLK;
+ state->freq_mult = 9;
break;
case ID_MT312:
strcpy(state->frontend.ops.info.name, "Zarlink MT312 DVB-S");
- state->frequency = 60;
+ state->xtal = MT312_PLL_CLK;
+ state->freq_mult = 6;
+ break;
+ case ID_ZL10313:
+ strcpy(state->frontend.ops.info.name, "Zarlink ZL10313 DVB-S");
+ state->xtal = MT312_PLL_CLK_10_111;
+ state->freq_mult = 9;
break;
default:
- printk(KERN_WARNING "Only Zarlink VP310/MT312"
+ printk(KERN_WARNING "Only Zarlink VP310/MT312/ZL10313"
" are supported chips.\n");
goto error;
}
@@ -744,12 +827,13 @@ error:
kfree(state);
return NULL;
}
-EXPORT_SYMBOL(vp310_mt312_attach);
+EXPORT_SYMBOL(mt312_attach);
module_param(debug, int, 0644);
MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-MODULE_DESCRIPTION("Zarlink VP310/MT312 DVB-S Demodulator driver");
+MODULE_DESCRIPTION("Zarlink VP310/MT312/ZL10313 DVB-S Demodulator driver");
MODULE_AUTHOR("Andreas Oberritter <obi@linuxtv.org>");
+MODULE_AUTHOR("Matthias Schwarzott <zzam@gentoo.org>");
MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/frontends/mt312.h b/linux/drivers/media/dvb/frontends/mt312.h
index f17cb93ba..29e3bb549 100644
--- a/linux/drivers/media/dvb/frontends/mt312.h
+++ b/linux/drivers/media/dvb/frontends/mt312.h
@@ -31,16 +31,19 @@
struct mt312_config {
/* the demodulator's i2c address */
u8 demod_address;
+
+ /* inverted voltage setting */
+ unsigned int voltage_inverted:1;
};
#if defined(CONFIG_DVB_MT312) || (defined(CONFIG_DVB_MT312_MODULE) && defined(MODULE))
-struct dvb_frontend *vp310_mt312_attach(const struct mt312_config *config,
+struct dvb_frontend *mt312_attach(const struct mt312_config *config,
struct i2c_adapter *i2c);
#else
-static inline struct dvb_frontend *vp310_mt312_attach(
+static inline struct dvb_frontend *mt312_attach(
const struct mt312_config *config, struct i2c_adapter *i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif /* CONFIG_DVB_MT312 */
diff --git a/linux/drivers/media/dvb/frontends/mt312_priv.h b/linux/drivers/media/dvb/frontends/mt312_priv.h
index 5e0b95b53..a3959f94d 100644
--- a/linux/drivers/media/dvb/frontends/mt312_priv.h
+++ b/linux/drivers/media/dvb/frontends/mt312_priv.h
@@ -110,6 +110,8 @@ enum mt312_reg_addr {
VIT_ERRPER_H = 83,
VIT_ERRPER_M = 84,
VIT_ERRPER_L = 85,
+ HW_CTRL = 84, /* ZL10313 only */
+ MPEG_CTRL = 85, /* ZL10313 only */
VIT_SETUP = 86,
VIT_REF0 = 87,
VIT_REF1 = 88,
@@ -156,7 +158,8 @@ enum mt312_reg_addr {
enum mt312_model_id {
ID_VP310 = 1,
- ID_MT312 = 3
+ ID_MT312 = 3,
+ ID_ZL10313 = 5,
};
#endif /* DVB_FRONTENDS_MT312_PRIV */
diff --git a/linux/drivers/media/dvb/frontends/mt352.c b/linux/drivers/media/dvb/frontends/mt352.c
index f9eb120c0..0bc03d9c7 100644
--- a/linux/drivers/media/dvb/frontends/mt352.c
+++ b/linux/drivers/media/dvb/frontends/mt352.c
@@ -96,7 +96,7 @@ static int mt352_read_register(struct mt352_state* state, u8 reg)
if (ret != 2) {
printk("%s: readreg error (reg=%d, ret==%i)\n",
- __FUNCTION__, reg, ret);
+ __func__, reg, ret);
return ret;
}
@@ -136,7 +136,7 @@ static void mt352_calc_nominal_rate(struct mt352_state* state,
value = 64 * bw * (1<<16) / (7 * 8);
value = value * 1000 / adc_clock;
dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
- __FUNCTION__, bw, adc_clock, value);
+ __func__, bw, adc_clock, value);
buf[0] = msb(value);
buf[1] = lsb(value);
}
@@ -162,7 +162,7 @@ static void mt352_calc_input_freq(struct mt352_state* state,
}
value = -16374 * ife / adc_clock;
dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
- __FUNCTION__, if2, ife, adc_clock, value, value & 0x3fff);
+ __func__, if2, ife, adc_clock, value, value & 0x3fff);
buf[0] = msb(value);
buf[1] = lsb(value);
}
@@ -522,7 +522,7 @@ static int mt352_init(struct dvb_frontend* fe)
static u8 mt352_reset_attach [] = { RESET, 0xC0 };
- dprintk("%s: hello\n",__FUNCTION__);
+ dprintk("%s: hello\n",__func__);
if ((mt352_read_register(state, CLOCK_CTL) & 0x10) == 0 ||
(mt352_read_register(state, CONFIG) & 0x20) == 0) {
diff --git a/linux/drivers/media/dvb/frontends/mt352.h b/linux/drivers/media/dvb/frontends/mt352.h
index e9964081f..595092f9f 100644
--- a/linux/drivers/media/dvb/frontends/mt352.h
+++ b/linux/drivers/media/dvb/frontends/mt352.h
@@ -58,7 +58,7 @@ extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
static inline struct dvb_frontend* mt352_attach(const struct mt352_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_MT352
diff --git a/linux/drivers/media/dvb/frontends/nxt200x.c b/linux/drivers/media/dvb/frontends/nxt200x.c
index 8808d781f..9172843dd 100644
--- a/linux/drivers/media/dvb/frontends/nxt200x.c
+++ b/linux/drivers/media/dvb/frontends/nxt200x.c
@@ -75,7 +75,7 @@ static int i2c_writebytes (struct nxt200x_state* state, u8 addr, u8 *buf, u8 len
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
- __FUNCTION__, addr, err);
+ __func__, addr, err);
return -EREMOTEIO;
}
return 0;
@@ -88,7 +88,7 @@ static u8 i2c_readbytes (struct nxt200x_state* state, u8 addr, u8* buf, u8 len)
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
- __FUNCTION__, addr, err);
+ __func__, addr, err);
return -EREMOTEIO;
}
return 0;
@@ -105,7 +105,7 @@ static int nxt200x_writebytes (struct nxt200x_state* state, u8 reg, u8 *buf, u8
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
printk (KERN_WARNING "nxt200x: %s: i2c write error (addr 0x%02x, err == %i)\n",
- __FUNCTION__, state->config->demod_address, err);
+ __func__, state->config->demod_address, err);
return -EREMOTEIO;
}
return 0;
@@ -122,7 +122,7 @@ static u8 nxt200x_readbytes (struct nxt200x_state* state, u8 reg, u8* buf, u8 le
if ((err = i2c_transfer (state->i2c, msg, 2)) != 2) {
printk (KERN_WARNING "nxt200x: %s: i2c read error (addr 0x%02x, err == %i)\n",
- __FUNCTION__, state->config->demod_address, err);
+ __func__, state->config->demod_address, err);
return -EREMOTEIO;
}
return 0;
@@ -147,7 +147,7 @@ static u16 nxt200x_crc(u16 crc, u8 c)
static int nxt200x_writereg_multibyte (struct nxt200x_state* state, u8 reg, u8* data, u8 len)
{
u8 attr, len2, buf;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
/* set mutli register register */
nxt200x_writebytes(state, 0x35, &reg, 1);
@@ -208,7 +208,7 @@ static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* d
{
int i;
u8 buf, len2, attr;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
/* set mutli register register */
nxt200x_writebytes(state, 0x35, &reg, 1);
@@ -255,7 +255,7 @@ static int nxt200x_readreg_multibyte (struct nxt200x_state* state, u8 reg, u8* d
static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
{
u8 buf, stopval, counter = 0;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
/* set correct stop value */
switch (state->demod_chip) {
@@ -288,7 +288,7 @@ static void nxt200x_microcontroller_stop (struct nxt200x_state* state)
static void nxt200x_microcontroller_start (struct nxt200x_state* state)
{
u8 buf;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
buf = 0x00;
nxt200x_writebytes(state, 0x22, &buf, 1);
@@ -298,7 +298,7 @@ static void nxt2004_microcontroller_init (struct nxt200x_state* state)
{
u8 buf[9];
u8 counter = 0;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
buf[0] = 0x00;
nxt200x_writebytes(state, 0x2b, buf, 1);
@@ -329,7 +329,7 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
{
u8 buf, count = 0;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
dprintk("Tuner Bytes: %02X %02X %02X %02X\n", data[1], data[2], data[3], data[4]);
@@ -388,7 +388,7 @@ static int nxt200x_writetuner (struct nxt200x_state* state, u8* data)
static void nxt200x_agc_reset(struct nxt200x_state* state)
{
u8 buf;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
switch (state->demod_chip) {
case NXT2002:
@@ -417,7 +417,7 @@ static int nxt2002_load_firmware (struct dvb_frontend* fe, const struct firmware
u8 buf[3], written = 0, chunkpos = 0;
u16 rambase, position, crc = 0;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
dprintk("Firmware is %zu bytes\n", fw->size);
/* Get the RAM base for this nxt2002 */
@@ -484,7 +484,7 @@ static int nxt2004_load_firmware (struct dvb_frontend* fe, const struct firmware
u8 buf[3];
u16 rambase, position, crc=0;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
dprintk("Firmware is %zu bytes\n", fw->size);
/* set rambase */
diff --git a/linux/drivers/media/dvb/frontends/nxt200x.h b/linux/drivers/media/dvb/frontends/nxt200x.h
index bb0ef58d7..f3c845837 100644
--- a/linux/drivers/media/dvb/frontends/nxt200x.h
+++ b/linux/drivers/media/dvb/frontends/nxt200x.h
@@ -49,7 +49,7 @@ extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
static inline struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_NXT200X
diff --git a/linux/drivers/media/dvb/frontends/nxt6000.h b/linux/drivers/media/dvb/frontends/nxt6000.h
index 13d225183..878eb38a0 100644
--- a/linux/drivers/media/dvb/frontends/nxt6000.h
+++ b/linux/drivers/media/dvb/frontends/nxt6000.h
@@ -40,7 +40,7 @@ extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
static inline struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_NXT6000
diff --git a/linux/drivers/media/dvb/frontends/or51132.c b/linux/drivers/media/dvb/frontends/or51132.c
index 1d2d28ce8..5ed32544d 100644
--- a/linux/drivers/media/dvb/frontends/or51132.c
+++ b/linux/drivers/media/dvb/frontends/or51132.c
@@ -91,7 +91,7 @@ static int or51132_writebuf(struct or51132_state *state, const u8 *buf, int len)
Less code and more efficient that loading a buffer on the stack with
the bytes to send and then calling or51132_writebuf() on that. */
#define or51132_writebytes(state, data...) \
- ({ const static u8 _data[] = {data}; \
+ ({ static const u8 _data[] = {data}; \
or51132_writebuf(state, _data, sizeof(_data)); })
/* Read data from demod into buffer. Returns 0 on success. */
@@ -126,13 +126,13 @@ static int or51132_readreg(struct or51132_state *state, u8 reg)
reg, err);
return -EREMOTEIO;
}
- return le16_to_cpup((u16*)buf);
+ return buf[0] | (buf[1] << 8);
}
static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware *fw)
{
struct or51132_state* state = fe->demodulator_priv;
- const static u8 run_buf[] = {0x7F,0x01};
+ static const u8 run_buf[] = {0x7F,0x01};
u8 rec_buf[8];
u32 firmwareAsize, firmwareBsize;
int i,ret;
@@ -140,9 +140,9 @@ static int or51132_load_firmware (struct dvb_frontend* fe, const struct firmware
dprintk("Firmware is %Zd bytes\n",fw->size);
/* Get size of firmware A and B */
- firmwareAsize = le32_to_cpu(*((u32*)fw->data));
+ firmwareAsize = le32_to_cpu(*((__le32*)fw->data));
dprintk("FirmwareA is %i bytes\n",firmwareAsize);
- firmwareBsize = le32_to_cpu(*((u32*)(fw->data+4)));
+ firmwareBsize = le32_to_cpu(*((__le32*)(fw->data+4)));
dprintk("FirmwareB is %i bytes\n",firmwareBsize);
/* Upload firmware */
@@ -419,7 +419,7 @@ static int or51132_read_status(struct dvb_frontend* fe, fe_status_t* status)
*status = 0;
return -EREMOTEIO;
}
- dprintk("%s: read_status %04x\n", __FUNCTION__, reg);
+ dprintk("%s: read_status %04x\n", __func__, reg);
if (reg & 0x0100) /* Receiver Lock */
*status = FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI|
@@ -504,14 +504,14 @@ start:
if (retry--) goto start;
return -EREMOTEIO;
}
- dprintk("%s: modulation %02x, NTSC rej O%s\n", __FUNCTION__,
+ dprintk("%s: modulation %02x, NTSC rej O%s\n", __func__,
reg&0xff, reg&0x1000?"n":"ff");
/* Calculate SNR using noise, c, and NTSC rejection correction */
state->snr = calculate_snr(noise, c) - usK;
*snr = (state->snr) >> 16;
- dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __FUNCTION__, noise,
+ dprintk("%s: noise = 0x%08x, snr = %d.%02d dB\n", __func__, noise,
state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
return 0;
diff --git a/linux/drivers/media/dvb/frontends/or51132.h b/linux/drivers/media/dvb/frontends/or51132.h
index add24f0a7..1b8e04d97 100644
--- a/linux/drivers/media/dvb/frontends/or51132.h
+++ b/linux/drivers/media/dvb/frontends/or51132.h
@@ -41,7 +41,7 @@ extern struct dvb_frontend* or51132_attach(const struct or51132_config* config,
static inline struct dvb_frontend* or51132_attach(const struct or51132_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_OR51132
diff --git a/linux/drivers/media/dvb/frontends/or51211.c b/linux/drivers/media/dvb/frontends/or51211.c
index 6a6b0d727..7eaa47655 100644
--- a/linux/drivers/media/dvb/frontends/or51211.c
+++ b/linux/drivers/media/dvb/frontends/or51211.c
@@ -307,19 +307,19 @@ static int or51211_read_snr(struct dvb_frontend* fe, u16* snr)
if (i2c_writebytes(state,state->config->demod_address,snd_buf,3)) {
printk(KERN_WARNING "%s: error writing snr reg\n",
- __FUNCTION__);
+ __func__);
return -1;
}
if (i2c_readbytes(state,state->config->demod_address,rec_buf,2)) {
printk(KERN_WARNING "%s: read_status read error\n",
- __FUNCTION__);
+ __func__);
return -1;
}
state->snr = calculate_snr(rec_buf[0], 89599047);
*snr = (state->snr) >> 16;
- dprintk("%s: noise = 0x%02x, snr = %d.%02d dB\n", __FUNCTION__, rec_buf[0],
+ dprintk("%s: noise = 0x%02x, snr = %d.%02d dB\n", __func__, rec_buf[0],
state->snr >> 24, (((state->snr>>8) & 0xffff) * 100) >> 16);
return 0;
diff --git a/linux/drivers/media/dvb/frontends/or51211.h b/linux/drivers/media/dvb/frontends/or51211.h
index 8aad8402d..3ce0508b8 100644
--- a/linux/drivers/media/dvb/frontends/or51211.h
+++ b/linux/drivers/media/dvb/frontends/or51211.h
@@ -44,7 +44,7 @@ extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
static inline struct dvb_frontend* or51211_attach(const struct or51211_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_OR51211
diff --git a/linux/drivers/media/dvb/frontends/qt1010.c b/linux/drivers/media/dvb/frontends/qt1010.c
deleted file mode 100644
index 4afed44ab..000000000
--- a/linux/drivers/media/dvb/frontends/qt1010.c
+++ /dev/null
@@ -1,489 +0,0 @@
-/*
- * Driver for Quantek QT1010 silicon tuner
- *
- * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- * Aapo Tahkola <aet@rasterburn.org>
- *
- * 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 "qt1010.h"
-#include "compat.h"
-#include "qt1010_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(args...) \
- do { \
- if (debug) printk(KERN_DEBUG "QT1010: " args); \
- } while (0)
-
-/* read single register */
-static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val)
-{
- struct i2c_msg msg[2] = {
- { .addr = priv->cfg->i2c_address,
- .flags = 0, .buf = &reg, .len = 1 },
- { .addr = priv->cfg->i2c_address,
- .flags = I2C_M_RD, .buf = val, .len = 1 },
- };
-
- if (i2c_transfer(priv->i2c, msg, 2) != 2) {
- printk(KERN_WARNING "qt1010 I2C read failed\n");
- return -EREMOTEIO;
- }
- return 0;
-}
-
-/* write single register */
-static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
-{
- u8 buf[2] = { reg, val };
- struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
- .flags = 0, .buf = buf, .len = 2 };
-
- if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
- printk(KERN_WARNING "qt1010 I2C write failed\n");
- return -EREMOTEIO;
- }
- return 0;
-}
-
-/* dump all registers */
-static void qt1010_dump_regs(struct qt1010_priv *priv)
-{
- char buf[52], buf2[4];
- u8 reg, val;
-
- for (reg = 0; ; reg++) {
- if (reg % 16 == 0) {
- if (reg)
- printk("%s\n", buf);
- sprintf(buf, "%02x: ", reg);
- }
- if (qt1010_readreg(priv, reg, &val) == 0)
- sprintf(buf2, "%02x ", val);
- else
- strcpy(buf2, "-- ");
- strcat(buf, buf2);
- if (reg == 0x2f)
- break;
- }
- printk("%s\n", buf);
-}
-
-static int qt1010_set_params(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *params)
-{
- struct qt1010_priv *priv;
- int err;
- u32 freq, div, mod1, mod2;
- u8 i, tmpval, reg05;
- qt1010_i2c_oper_t rd[48] = {
- { QT1010_WR, 0x01, 0x80 },
- { QT1010_WR, 0x02, 0x3f },
- { QT1010_WR, 0x05, 0xff }, /* 02 c write */
- { QT1010_WR, 0x06, 0x44 },
- { QT1010_WR, 0x07, 0xff }, /* 04 c write */
- { QT1010_WR, 0x08, 0x08 },
- { QT1010_WR, 0x09, 0xff }, /* 06 c write */
- { QT1010_WR, 0x0a, 0xff }, /* 07 c write */
- { QT1010_WR, 0x0b, 0xff }, /* 08 c write */
- { QT1010_WR, 0x0c, 0xe1 },
- { QT1010_WR, 0x1a, 0xff }, /* 10 c write */
- { QT1010_WR, 0x1b, 0x00 },
- { QT1010_WR, 0x1c, 0x89 },
- { QT1010_WR, 0x11, 0xff }, /* 13 c write */
- { QT1010_WR, 0x12, 0xff }, /* 14 c write */
- { QT1010_WR, 0x22, 0xff }, /* 15 c write */
- { QT1010_WR, 0x1e, 0x00 },
- { QT1010_WR, 0x1e, 0xd0 },
- { QT1010_RD, 0x22, 0xff }, /* 16 c read */
- { QT1010_WR, 0x1e, 0x00 },
- { QT1010_RD, 0x05, 0xff }, /* 20 c read */
- { QT1010_RD, 0x22, 0xff }, /* 21 c read */
- { QT1010_WR, 0x23, 0xd0 },
- { QT1010_WR, 0x1e, 0x00 },
- { QT1010_WR, 0x1e, 0xe0 },
- { QT1010_RD, 0x23, 0xff }, /* 25 c read */
- { QT1010_RD, 0x23, 0xff }, /* 26 c read */
- { QT1010_WR, 0x1e, 0x00 },
- { QT1010_WR, 0x24, 0xd0 },
- { QT1010_WR, 0x1e, 0x00 },
- { QT1010_WR, 0x1e, 0xf0 },
- { QT1010_RD, 0x24, 0xff }, /* 31 c read */
- { QT1010_WR, 0x1e, 0x00 },
- { QT1010_WR, 0x14, 0x7f },
- { QT1010_WR, 0x15, 0x7f },
- { QT1010_WR, 0x05, 0xff }, /* 35 c write */
- { QT1010_WR, 0x06, 0x00 },
- { QT1010_WR, 0x15, 0x1f },
- { QT1010_WR, 0x16, 0xff },
- { QT1010_WR, 0x18, 0xff },
- { QT1010_WR, 0x1f, 0xff }, /* 40 c write */
- { QT1010_WR, 0x20, 0xff }, /* 41 c write */
- { QT1010_WR, 0x21, 0x53 },
- { QT1010_WR, 0x25, 0xff }, /* 43 c write */
- { QT1010_WR, 0x26, 0x15 },
- { QT1010_WR, 0x00, 0xff }, /* 45 c write */
- { QT1010_WR, 0x02, 0x00 },
- { QT1010_WR, 0x01, 0x00 }
- };
-
-#define FREQ1 32000000 /* 32 MHz */
-#define FREQ2 4000000 /* 4 MHz Quartz oscillator in the stick? */
-
- priv = fe->tuner_priv;
- freq = params->frequency;
- div = (freq + QT1010_OFFSET) / QT1010_STEP;
- freq = (div * QT1010_STEP) - QT1010_OFFSET;
- mod1 = (freq + QT1010_OFFSET) % FREQ1;
- mod2 = (freq + QT1010_OFFSET) % FREQ2;
- priv->bandwidth =
- (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
- priv->frequency = freq;
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
- /* reg 05 base value */
- if (freq < 290000000) reg05 = 0x14; /* 290 MHz */
- else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */
- else if (freq < 802000000) reg05 = 0x54; /* 802 MHz */
- else reg05 = 0x74;
-
- /* 0x5 */
- rd[2].val = reg05;
-
- /* 07 - set frequency: 32 MHz scale */
- rd[4].val = (freq + QT1010_OFFSET) / FREQ1;
-
- /* 09 - changes every 8/24 MHz */
- if (mod1 < 8000000) rd[6].val = 0x1d;
- else rd[6].val = 0x1c;
-
- /* 0a - set frequency: 4 MHz scale (max 28 MHz) */
- if (mod1 < 1*FREQ2) rd[7].val = 0x09; /* +0 MHz */
- else if (mod1 < 2*FREQ2) rd[7].val = 0x08; /* +4 MHz */
- else if (mod1 < 3*FREQ2) rd[7].val = 0x0f; /* +8 MHz */
- else if (mod1 < 4*FREQ2) rd[7].val = 0x0e; /* +12 MHz */
- else if (mod1 < 5*FREQ2) rd[7].val = 0x0d; /* +16 MHz */
- else if (mod1 < 6*FREQ2) rd[7].val = 0x0c; /* +20 MHz */
- else if (mod1 < 7*FREQ2) rd[7].val = 0x0b; /* +24 MHz */
- else rd[7].val = 0x0a; /* +28 MHz */
-
- /* 0b - changes every 2/2 MHz */
- if (mod2 < 2000000) rd[8].val = 0x45;
- else rd[8].val = 0x44;
-
- /* 1a - set frequency: 125 kHz scale (max 3875 kHz)*/
- tmpval = 0x78; /* byte, overflows intentionally */
- rd[10].val = tmpval-((mod2/QT1010_STEP)*0x08);
-
- /* 11 */
- rd[13].val = 0xfd; /* TODO: correct value calculation */
-
- /* 12 */
- rd[14].val = 0x91; /* TODO: correct value calculation */
-
- /* 22 */
- if (freq < 450000000) rd[15].val = 0xd0; /* 450 MHz */
- else if (freq < 482000000) rd[15].val = 0xd1; /* 482 MHz */
- else if (freq < 514000000) rd[15].val = 0xd4; /* 514 MHz */
- else if (freq < 546000000) rd[15].val = 0xd7; /* 546 MHz */
- else if (freq < 610000000) rd[15].val = 0xda; /* 610 MHz */
- else rd[15].val = 0xd0;
-
- /* 05 */
- rd[35].val = (reg05 & 0xf0);
-
- /* 1f */
- if (mod1 < 8000000) tmpval = 0x00;
- else if (mod1 < 12000000) tmpval = 0x01;
- else if (mod1 < 16000000) tmpval = 0x02;
- else if (mod1 < 24000000) tmpval = 0x03;
- else if (mod1 < 28000000) tmpval = 0x04;
- else tmpval = 0x05;
- rd[40].val = (priv->reg1f_init_val + 0x0e + tmpval);
-
- /* 20 */
- if (mod1 < 8000000) tmpval = 0x00;
- else if (mod1 < 12000000) tmpval = 0x01;
- else if (mod1 < 20000000) tmpval = 0x02;
- else if (mod1 < 24000000) tmpval = 0x03;
- else if (mod1 < 28000000) tmpval = 0x04;
- else tmpval = 0x05;
- rd[41].val = (priv->reg20_init_val + 0x0d + tmpval);
-
- /* 25 */
- rd[43].val = priv->reg25_init_val;
-
- /* 00 */
- rd[45].val = 0x92; /* TODO: correct value calculation */
-
- dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \
- "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \
- "20:%02x 25:%02x 00:%02x", \
- freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \
- rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \
- rd[40].val, rd[41].val, rd[43].val, rd[45].val);
-
- for (i = 0; i < ARRAY_SIZE(rd); i++) {
- if (rd[i].oper == QT1010_WR) {
- err = qt1010_writereg(priv, rd[i].reg, rd[i].val);
- } else { /* read is required to proper locking */
- err = qt1010_readreg(priv, rd[i].reg, &tmpval);
- }
- if (err) return err;
- }
-
- if (debug)
- qt1010_dump_regs(priv);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
- return 0;
-}
-
-static int qt1010_init_meas1(struct qt1010_priv *priv,
- u8 oper, u8 reg, u8 reg_init_val, u8 *retval)
-{
- u8 i, val1, val2;
- int err;
-
- qt1010_i2c_oper_t i2c_data[] = {
- { QT1010_WR, reg, reg_init_val },
- { QT1010_WR, 0x1e, 0x00 },
- { QT1010_WR, 0x1e, oper },
- { QT1010_RD, reg, 0xff }
- };
-
- for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
- if (i2c_data[i].oper == QT1010_WR) {
- err = qt1010_writereg(priv, i2c_data[i].reg,
- i2c_data[i].val);
- } else {
- err = qt1010_readreg(priv, i2c_data[i].reg, &val2);
- }
- if (err) return err;
- }
-
- do {
- val1 = val2;
- err = qt1010_readreg(priv, reg, &val2);
- if (err) return err;
- dprintk("compare reg:%02x %02x %02x", reg, val1, val2);
- } while (val1 != val2);
- *retval = val1;
-
- return qt1010_writereg(priv, 0x1e, 0x00);
-}
-
-static u8 qt1010_init_meas2(struct qt1010_priv *priv,
- u8 reg_init_val, u8 *retval)
-{
- u8 i, val;
- int err;
- qt1010_i2c_oper_t i2c_data[] = {
- { QT1010_WR, 0x07, reg_init_val },
- { QT1010_WR, 0x22, 0xd0 },
- { QT1010_WR, 0x1e, 0x00 },
- { QT1010_WR, 0x1e, 0xd0 },
- { QT1010_RD, 0x22, 0xff },
- { QT1010_WR, 0x1e, 0x00 },
- { QT1010_WR, 0x22, 0xff }
- };
- for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
- if (i2c_data[i].oper == QT1010_WR) {
- err = qt1010_writereg(priv, i2c_data[i].reg,
- i2c_data[i].val);
- } else {
- err = qt1010_readreg(priv, i2c_data[i].reg, &val);
- }
- if (err) return err;
- }
- *retval = val;
- return 0;
-}
-
-static int qt1010_init(struct dvb_frontend *fe)
-{
- struct qt1010_priv *priv = fe->tuner_priv;
- struct dvb_frontend_parameters params;
- int err = 0;
- u8 i, tmpval, *valptr = NULL;
-
- qt1010_i2c_oper_t i2c_data[] = {
- { QT1010_WR, 0x01, 0x80 },
- { QT1010_WR, 0x0d, 0x84 },
- { QT1010_WR, 0x0e, 0xb7 },
- { QT1010_WR, 0x2a, 0x23 },
- { QT1010_WR, 0x2c, 0xdc },
- { QT1010_M1, 0x25, 0x40 }, /* get reg 25 init value */
- { QT1010_M1, 0x81, 0xff }, /* get reg 25 init value */
- { QT1010_WR, 0x2b, 0x70 },
- { QT1010_WR, 0x2a, 0x23 },
- { QT1010_M1, 0x26, 0x08 },
- { QT1010_M1, 0x82, 0xff },
- { QT1010_WR, 0x05, 0x14 },
- { QT1010_WR, 0x06, 0x44 },
- { QT1010_WR, 0x07, 0x28 },
- { QT1010_WR, 0x08, 0x0b },
- { QT1010_WR, 0x11, 0xfd },
- { QT1010_M1, 0x22, 0x0d },
- { QT1010_M1, 0xd0, 0xff },
- { QT1010_WR, 0x06, 0x40 },
- { QT1010_WR, 0x16, 0xf0 },
- { QT1010_WR, 0x02, 0x38 },
- { QT1010_WR, 0x03, 0x18 },
- { QT1010_WR, 0x20, 0xe0 },
- { QT1010_M1, 0x1f, 0x20 }, /* get reg 1f init value */
- { QT1010_M1, 0x84, 0xff }, /* get reg 1f init value */
- { QT1010_RD, 0x20, 0x20 }, /* get reg 20 init value */
- { QT1010_WR, 0x03, 0x19 },
- { QT1010_WR, 0x02, 0x3f },
- { QT1010_WR, 0x21, 0x53 },
- { QT1010_RD, 0x21, 0xff },
- { QT1010_WR, 0x11, 0xfd },
- { QT1010_WR, 0x05, 0x34 },
- { QT1010_WR, 0x06, 0x44 },
- { QT1010_WR, 0x08, 0x08 }
- };
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
- for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
- switch (i2c_data[i].oper) {
- case QT1010_WR:
- err = qt1010_writereg(priv, i2c_data[i].reg,
- i2c_data[i].val);
- break;
- case QT1010_RD:
- if (i2c_data[i].val == 0x20)
- valptr = &priv->reg20_init_val;
- else
- valptr = &tmpval;
- err = qt1010_readreg(priv, i2c_data[i].reg, valptr);
- break;
- case QT1010_M1:
- if (i2c_data[i].val == 0x25)
- valptr = &priv->reg25_init_val;
- else if (i2c_data[i].val == 0x1f)
- valptr = &priv->reg1f_init_val;
- else
- valptr = &tmpval;
- err = qt1010_init_meas1(priv, i2c_data[i+1].reg,
- i2c_data[i].reg,
- i2c_data[i].val, valptr);
- i++;
- break;
- }
- if (err) return err;
- }
-
- for (i = 0x31; i < 0x3a; i++) /* 0x31 - 0x39 */
- if ((err = qt1010_init_meas2(priv, i, &tmpval)))
- return err;
-
- params.frequency = 545000000; /* Sigmatek DVB-110 545000000 */
- /* MSI Megasky 580 GL861 533000000 */
- return qt1010_set_params(fe, &params);
-}
-
-static int qt1010_release(struct dvb_frontend *fe)
-{
- kfree(fe->tuner_priv);
- fe->tuner_priv = NULL;
- return 0;
-}
-
-static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
- struct qt1010_priv *priv = fe->tuner_priv;
- *frequency = priv->frequency;
- return 0;
-}
-
-static int qt1010_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
- struct qt1010_priv *priv = fe->tuner_priv;
- *bandwidth = priv->bandwidth;
- return 0;
-}
-
-static const struct dvb_tuner_ops qt1010_tuner_ops = {
- .info = {
- .name = "Quantek QT1010",
- .frequency_min = QT1010_MIN_FREQ,
- .frequency_max = QT1010_MAX_FREQ,
- .frequency_step = QT1010_STEP,
- },
-
- .release = qt1010_release,
- .init = qt1010_init,
- /* TODO: implement sleep */
-
- .set_params = qt1010_set_params,
- .get_frequency = qt1010_get_frequency,
- .get_bandwidth = qt1010_get_bandwidth
-};
-
-struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct qt1010_config *cfg)
-{
- struct qt1010_priv *priv = NULL;
- u8 id;
-
- priv = kzalloc(sizeof(struct qt1010_priv), GFP_KERNEL);
- if (priv == NULL)
- return NULL;
-
- priv->cfg = cfg;
- priv->i2c = i2c;
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
-
-#if 0
- qt1010_dump_regs(priv);
-#endif
-
- /* Try to detect tuner chip. Probably this is not correct register. */
- if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) {
- kfree(priv);
- return NULL;
- }
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
-
- printk(KERN_INFO "Quantek QT1010 successfully identified.\n");
- memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops,
- sizeof(struct dvb_tuner_ops));
-
- fe->tuner_priv = priv;
- return fe;
-}
-EXPORT_SYMBOL(qt1010_attach);
-
-MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver");
-MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
-MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
-MODULE_VERSION("0.1");
-MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/frontends/qt1010.h b/linux/drivers/media/dvb/frontends/qt1010.h
deleted file mode 100644
index 3ab4aa045..000000000
--- a/linux/drivers/media/dvb/frontends/qt1010.h
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Driver for Quantek QT1010 silicon tuner
- *
- * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- * Aapo Tahkola <aet@rasterburn.org>
- *
- * 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 QT1010_H
-#define QT1010_H
-
-#include "dvb_frontend.h"
-
-struct qt1010_config {
- u8 i2c_address;
-};
-
-/**
- * Attach a qt1010 tuner to the supplied frontend structure.
- *
- * @param fe frontend to attach to
- * @param i2c i2c adapter to use
- * @param cfg tuner hw based configuration
- * @return fe pointer on success, NULL on failure
- */
-#if defined(CONFIG_DVB_TUNER_QT1010) || (defined(CONFIG_DVB_TUNER_QT1010_MODULE) && defined(MODULE))
-extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct qt1010_config *cfg);
-#else
-static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct qt1010_config *cfg)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
- return NULL;
-}
-#endif // CONFIG_DVB_TUNER_QT1010
-
-#endif
diff --git a/linux/drivers/media/dvb/frontends/qt1010_priv.h b/linux/drivers/media/dvb/frontends/qt1010_priv.h
deleted file mode 100644
index 090cf475f..000000000
--- a/linux/drivers/media/dvb/frontends/qt1010_priv.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * Driver for Quantek QT1010 silicon tuner
- *
- * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
- * Aapo Tahkola <aet@rasterburn.org>
- *
- * 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 QT1010_PRIV_H
-#define QT1010_PRIV_H
-
-/*
-reg def meaning
-=== === =======
-00 00 ?
-01 a0 ? operation start/stop; start=80, stop=00
-02 00 ?
-03 19 ?
-04 00 ?
-05 00 ? maybe band selection
-06 00 ?
-07 2b set frequency: 32 MHz scale, n*32 MHz
-08 0b ?
-09 10 ? changes every 8/24 MHz; values 1d/1c
-0a 08 set frequency: 4 MHz scale, n*4 MHz
-0b 41 ? changes every 2/2 MHz; values 45/45
-0c e1 ?
-0d 94 ?
-0e b6 ?
-0f 2c ?
-10 10 ?
-11 f1 ? maybe device specified adjustment
-12 11 ? maybe device specified adjustment
-13 3f ?
-14 1f ?
-15 3f ?
-16 ff ?
-17 ff ?
-18 f7 ?
-19 80 ?
-1a d0 set frequency: 125 kHz scale, n*125 kHz
-1b 00 ?
-1c 89 ?
-1d 00 ?
-1e 00 ? looks like operation register; write cmd here, read result from 1f-26
-1f 20 ? chip initialization
-20 e0 ? chip initialization
-21 20 ?
-22 d0 ?
-23 d0 ?
-24 d0 ?
-25 40 ? chip initialization
-26 08 ?
-27 29 ?
-28 55 ?
-29 39 ?
-2a 13 ?
-2b 01 ?
-2c ea ?
-2d 00 ?
-2e 00 ? not used?
-2f 00 ? not used?
-*/
-
-#define QT1010_STEP 125000 /* 125 kHz used by Windows drivers,
- hw could be more precise but we don't
- know how to use */
-#define QT1010_MIN_FREQ 48000000 /* 48 MHz */
-#define QT1010_MAX_FREQ 860000000 /* 860 MHz */
-#define QT1010_OFFSET 1246000000 /* 1246 MHz */
-
-#define QT1010_WR 0
-#define QT1010_RD 1
-#define QT1010_M1 3
-
-typedef struct {
- u8 oper, reg, val;
-} qt1010_i2c_oper_t;
-
-struct qt1010_priv {
- struct qt1010_config *cfg;
- struct i2c_adapter *i2c;
-
- u8 reg1f_init_val;
- u8 reg20_init_val;
- u8 reg25_init_val;
-
- u32 frequency;
- u32 bandwidth;
-};
-
-#endif
diff --git a/linux/drivers/media/dvb/frontends/s5h1409.c b/linux/drivers/media/dvb/frontends/s5h1409.c
index 1ca250378..5ddb2dca3 100644
--- a/linux/drivers/media/dvb/frontends/s5h1409.c
+++ b/linux/drivers/media/dvb/frontends/s5h1409.c
@@ -26,7 +26,6 @@
#include <linux/slab.h>
#include <linux/delay.h>
#include "dvb_frontend.h"
-#include "dvb-pll.h"
#include "s5h1409.h"
struct s5h1409_state {
@@ -312,7 +311,7 @@ static int s5h1409_writereg(struct s5h1409_state* state, u8 reg, u16 data)
if (ret != 1)
printk("%s: writereg error (reg == 0x%02x, val == 0x%04x, "
- "ret == %i)\n", __FUNCTION__, reg, data, ret);
+ "ret == %i)\n", __func__, reg, data, ret);
return (ret != 1) ? -1 : 0;
}
@@ -332,7 +331,7 @@ static u16 s5h1409_readreg(struct s5h1409_state* state, u8 reg)
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2)
- printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
+ printk("%s: readreg error (ret == %i)\n", __func__, ret);
return (b1[0] << 8) | b1[1];
}
@@ -340,7 +339,7 @@ static int s5h1409_softreset(struct dvb_frontend* fe)
{
struct s5h1409_state* state = fe->demodulator_priv;
- dprintk("%s()\n", __FUNCTION__);
+ dprintk("%s()\n", __func__);
s5h1409_writereg(state, 0xf5, 0);
s5h1409_writereg(state, 0xf5, 1);
@@ -356,7 +355,7 @@ static int s5h1409_set_if_freq(struct dvb_frontend* fe, int KHz)
{
struct s5h1409_state* state = fe->demodulator_priv;
- dprintk("%s(%d KHz)\n", __FUNCTION__, KHz);
+ dprintk("%s(%d KHz)\n", __func__, KHz);
switch (KHz) {
case 4000:
@@ -381,7 +380,7 @@ static int s5h1409_set_spectralinversion(struct dvb_frontend* fe, int inverted)
{
struct s5h1409_state* state = fe->demodulator_priv;
- dprintk("%s(%d)\n", __FUNCTION__, inverted);
+ dprintk("%s(%d)\n", __func__, inverted);
if(inverted == 1)
return s5h1409_writereg(state, 0x1b, 0x1101); /* Inverted */
@@ -394,25 +393,25 @@ static int s5h1409_enable_modulation(struct dvb_frontend* fe,
{
struct s5h1409_state* state = fe->demodulator_priv;
- dprintk("%s(0x%08x)\n", __FUNCTION__, m);
+ dprintk("%s(0x%08x)\n", __func__, m);
switch(m) {
case VSB_8:
- dprintk("%s() VSB_8\n", __FUNCTION__);
+ dprintk("%s() VSB_8\n", __func__);
if (state->if_freq != S5H1409_VSB_IF_FREQ)
s5h1409_set_if_freq(fe, S5H1409_VSB_IF_FREQ);
s5h1409_writereg(state, 0xf4, 0);
break;
case QAM_64:
case QAM_256:
- dprintk("%s() QAM_AUTO (64/256)\n", __FUNCTION__);
+ dprintk("%s() QAM_AUTO (64/256)\n", __func__);
if (state->if_freq != S5H1409_QAM_IF_FREQ)
s5h1409_set_if_freq(fe, S5H1409_QAM_IF_FREQ);
s5h1409_writereg(state, 0xf4, 1);
s5h1409_writereg(state, 0x85, 0x110);
break;
default:
- dprintk("%s() Invalid modulation\n", __FUNCTION__);
+ dprintk("%s() Invalid modulation\n", __func__);
return -EINVAL;
}
@@ -426,7 +425,7 @@ static int s5h1409_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
{
struct s5h1409_state* state = fe->demodulator_priv;
- dprintk("%s(%d)\n", __FUNCTION__, enable);
+ dprintk("%s(%d)\n", __func__, enable);
if (enable)
return s5h1409_writereg(state, 0xf3, 1);
@@ -438,7 +437,7 @@ static int s5h1409_set_gpio(struct dvb_frontend* fe, int enable)
{
struct s5h1409_state* state = fe->demodulator_priv;
- dprintk("%s(%d)\n", __FUNCTION__, enable);
+ dprintk("%s(%d)\n", __func__, enable);
if (enable)
return s5h1409_writereg(state, 0xe3,
@@ -452,7 +451,7 @@ static int s5h1409_sleep(struct dvb_frontend* fe, int enable)
{
struct s5h1409_state* state = fe->demodulator_priv;
- dprintk("%s(%d)\n", __FUNCTION__, enable);
+ dprintk("%s(%d)\n", __func__, enable);
return s5h1409_writereg(state, 0xf2, enable);
}
@@ -461,7 +460,7 @@ static int s5h1409_register_reset(struct dvb_frontend* fe)
{
struct s5h1409_state* state = fe->demodulator_priv;
- dprintk("%s()\n", __FUNCTION__);
+ dprintk("%s()\n", __func__);
return s5h1409_writereg(state, 0xfa, 0);
}
@@ -534,7 +533,7 @@ static int s5h1409_set_frontend (struct dvb_frontend* fe,
{
struct s5h1409_state* state = fe->demodulator_priv;
- dprintk("%s(frequency=%d)\n", __FUNCTION__, p->frequency);
+ dprintk("%s(frequency=%d)\n", __func__, p->frequency);
s5h1409_softreset(fe);
@@ -565,7 +564,7 @@ static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode)
struct s5h1409_state *state = fe->demodulator_priv;
u16 val;
- dprintk("%s(%d)\n", __FUNCTION__, mode);
+ dprintk("%s(%d)\n", __func__, mode);
val = s5h1409_readreg(state, 0xac) & 0xcfff;
switch (mode) {
@@ -573,7 +572,7 @@ static int s5h1409_set_mpeg_timing(struct dvb_frontend *fe, int mode)
val |= 0x0000;
break;
case S5H1409_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK:
- dprintk("%s(%d) Mode1 or Defaulting\n", __FUNCTION__, mode);
+ dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode);
val |= 0x1000;
break;
case S5H1409_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK:
@@ -597,7 +596,7 @@ static int s5h1409_init (struct dvb_frontend* fe)
int i;
struct s5h1409_state* state = fe->demodulator_priv;
- dprintk("%s()\n", __FUNCTION__);
+ dprintk("%s()\n", __func__);
s5h1409_sleep(fe, 0);
s5h1409_register_reset(fe);
@@ -663,7 +662,7 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
break;
}
- dprintk("%s() status 0x%08x\n", __FUNCTION__, *status);
+ dprintk("%s() status 0x%08x\n", __func__, *status);
return 0;
}
@@ -671,7 +670,7 @@ static int s5h1409_read_status(struct dvb_frontend* fe, fe_status_t* status)
static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
{
int i, ret = -EINVAL;
- dprintk("%s()\n", __FUNCTION__);
+ dprintk("%s()\n", __func__);
for (i=0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
if (v < qam256_snr_tab[i].val) {
@@ -686,7 +685,7 @@ static int s5h1409_qam256_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
{
int i, ret = -EINVAL;
- dprintk("%s()\n", __FUNCTION__);
+ dprintk("%s()\n", __func__);
for (i=0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
if (v < qam64_snr_tab[i].val) {
@@ -701,7 +700,7 @@ static int s5h1409_qam64_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
{
int i, ret = -EINVAL;
- dprintk("%s()\n", __FUNCTION__);
+ dprintk("%s()\n", __func__);
for (i=0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
if (v > vsb_snr_tab[i].val) {
@@ -710,7 +709,7 @@ static int s5h1409_vsb_lookup_snr(struct dvb_frontend* fe, u16* snr, u16 v)
break;
}
}
- dprintk("%s() snr=%d\n", __FUNCTION__, *snr);
+ dprintk("%s() snr=%d\n", __func__, *snr);
return ret;
}
@@ -718,7 +717,7 @@ static int s5h1409_read_snr(struct dvb_frontend* fe, u16* snr)
{
struct s5h1409_state* state = fe->demodulator_priv;
u16 reg;
- dprintk("%s()\n", __FUNCTION__);
+ dprintk("%s()\n", __func__);
switch(state->current_modulation) {
case QAM_64:
@@ -812,7 +811,7 @@ struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
if (s5h1409_init(&state->frontend) != 0) {
printk(KERN_ERR "%s: Failed to initialize correctly\n",
- __FUNCTION__);
+ __func__);
goto error;
}
diff --git a/linux/drivers/media/dvb/frontends/s5h1409.h b/linux/drivers/media/dvb/frontends/s5h1409.h
index f0bb13fe8..59f433596 100644
--- a/linux/drivers/media/dvb/frontends/s5h1409.h
+++ b/linux/drivers/media/dvb/frontends/s5h1409.h
@@ -67,7 +67,7 @@ extern struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
static inline struct dvb_frontend* s5h1409_attach(const struct s5h1409_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif /* CONFIG_DVB_S5H1409 */
diff --git a/linux/drivers/media/dvb/frontends/s5h1411.c b/linux/drivers/media/dvb/frontends/s5h1411.c
new file mode 100644
index 000000000..cff360ce1
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/s5h1411.c
@@ -0,0 +1,887 @@
+/*
+ Samsung S5H1411 VSB/QAM demodulator driver
+
+ Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+
+ 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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "s5h1411.h"
+
+struct s5h1411_state {
+
+ struct i2c_adapter *i2c;
+
+ /* configuration settings */
+ const struct s5h1411_config *config;
+
+ struct dvb_frontend frontend;
+
+ fe_modulation_t current_modulation;
+
+ u32 current_frequency;
+ int if_freq;
+
+ u8 inversion;
+};
+
+static int debug;
+
+#define dprintk(arg...) do { \
+ if (debug) \
+ printk(arg); \
+ } while (0)
+
+/* Register values to initialise the demod, defaults to VSB */
+static struct init_tab {
+ u8 addr;
+ u8 reg;
+ u16 data;
+} init_tab[] = {
+ { S5H1411_I2C_TOP_ADDR, 0x00, 0x0071, },
+ { S5H1411_I2C_TOP_ADDR, 0x08, 0x0047, },
+ { S5H1411_I2C_TOP_ADDR, 0x1c, 0x0400, },
+ { S5H1411_I2C_TOP_ADDR, 0x1e, 0x0370, },
+ { S5H1411_I2C_TOP_ADDR, 0x1f, 0x342a, },
+ { S5H1411_I2C_TOP_ADDR, 0x24, 0x0231, },
+ { S5H1411_I2C_TOP_ADDR, 0x25, 0x1011, },
+ { S5H1411_I2C_TOP_ADDR, 0x26, 0x0f07, },
+ { S5H1411_I2C_TOP_ADDR, 0x27, 0x0f04, },
+ { S5H1411_I2C_TOP_ADDR, 0x28, 0x070f, },
+ { S5H1411_I2C_TOP_ADDR, 0x29, 0x2820, },
+ { S5H1411_I2C_TOP_ADDR, 0x2a, 0x102e, },
+ { S5H1411_I2C_TOP_ADDR, 0x2b, 0x0220, },
+ { S5H1411_I2C_TOP_ADDR, 0x2e, 0x0d0e, },
+ { S5H1411_I2C_TOP_ADDR, 0x2f, 0x1013, },
+ { S5H1411_I2C_TOP_ADDR, 0x31, 0x171b, },
+ { S5H1411_I2C_TOP_ADDR, 0x32, 0x0e0f, },
+ { S5H1411_I2C_TOP_ADDR, 0x33, 0x0f10, },
+ { S5H1411_I2C_TOP_ADDR, 0x34, 0x170e, },
+ { S5H1411_I2C_TOP_ADDR, 0x35, 0x4b10, },
+ { S5H1411_I2C_TOP_ADDR, 0x36, 0x0f17, },
+ { S5H1411_I2C_TOP_ADDR, 0x3c, 0x1577, },
+ { S5H1411_I2C_TOP_ADDR, 0x3d, 0x081a, },
+ { S5H1411_I2C_TOP_ADDR, 0x3e, 0x77ee, },
+ { S5H1411_I2C_TOP_ADDR, 0x40, 0x1e09, },
+ { S5H1411_I2C_TOP_ADDR, 0x41, 0x0f0c, },
+ { S5H1411_I2C_TOP_ADDR, 0x42, 0x1f10, },
+ { S5H1411_I2C_TOP_ADDR, 0x4d, 0x0509, },
+ { S5H1411_I2C_TOP_ADDR, 0x4e, 0x0a00, },
+ { S5H1411_I2C_TOP_ADDR, 0x50, 0x0000, },
+ { S5H1411_I2C_TOP_ADDR, 0x5b, 0x0000, },
+ { S5H1411_I2C_TOP_ADDR, 0x5c, 0x0008, },
+ { S5H1411_I2C_TOP_ADDR, 0x57, 0x1101, },
+ { S5H1411_I2C_TOP_ADDR, 0x65, 0x007c, },
+ { S5H1411_I2C_TOP_ADDR, 0x68, 0x0512, },
+ { S5H1411_I2C_TOP_ADDR, 0x69, 0x0258, },
+ { S5H1411_I2C_TOP_ADDR, 0x70, 0x0004, },
+ { S5H1411_I2C_TOP_ADDR, 0x71, 0x0007, },
+ { S5H1411_I2C_TOP_ADDR, 0x76, 0x00a9, },
+ { S5H1411_I2C_TOP_ADDR, 0x78, 0x3141, },
+ { S5H1411_I2C_TOP_ADDR, 0x7a, 0x3141, },
+ { S5H1411_I2C_TOP_ADDR, 0xb3, 0x8003, },
+ { S5H1411_I2C_TOP_ADDR, 0xb5, 0xafbb, },
+ { S5H1411_I2C_TOP_ADDR, 0xb5, 0xa6bb, },
+ { S5H1411_I2C_TOP_ADDR, 0xb6, 0x0609, },
+ { S5H1411_I2C_TOP_ADDR, 0xb7, 0x2f06, },
+ { S5H1411_I2C_TOP_ADDR, 0xb8, 0x003f, },
+ { S5H1411_I2C_TOP_ADDR, 0xb9, 0x2700, },
+ { S5H1411_I2C_TOP_ADDR, 0xba, 0xfac8, },
+ { S5H1411_I2C_TOP_ADDR, 0xbe, 0x1003, },
+ { S5H1411_I2C_TOP_ADDR, 0xbf, 0x103f, },
+ { S5H1411_I2C_TOP_ADDR, 0xce, 0x2000, },
+ { S5H1411_I2C_TOP_ADDR, 0xcf, 0x0800, },
+ { S5H1411_I2C_TOP_ADDR, 0xd0, 0x0800, },
+ { S5H1411_I2C_TOP_ADDR, 0xd1, 0x0400, },
+ { S5H1411_I2C_TOP_ADDR, 0xd2, 0x0800, },
+ { S5H1411_I2C_TOP_ADDR, 0xd3, 0x2000, },
+ { S5H1411_I2C_TOP_ADDR, 0xd4, 0x3000, },
+ { S5H1411_I2C_TOP_ADDR, 0xdb, 0x4a9b, },
+ { S5H1411_I2C_TOP_ADDR, 0xdc, 0x1000, },
+ { S5H1411_I2C_TOP_ADDR, 0xde, 0x0001, },
+ { S5H1411_I2C_TOP_ADDR, 0xdf, 0x0000, },
+ { S5H1411_I2C_TOP_ADDR, 0xe3, 0x0301, },
+ { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0000, },
+ { S5H1411_I2C_QAM_ADDR, 0xf3, 0x0001, },
+ { S5H1411_I2C_QAM_ADDR, 0x08, 0x0600, },
+ { S5H1411_I2C_QAM_ADDR, 0x18, 0x4201, },
+ { S5H1411_I2C_QAM_ADDR, 0x1e, 0x6476, },
+ { S5H1411_I2C_QAM_ADDR, 0x21, 0x0830, },
+ { S5H1411_I2C_QAM_ADDR, 0x0c, 0x5679, },
+ { S5H1411_I2C_QAM_ADDR, 0x0d, 0x579b, },
+ { S5H1411_I2C_QAM_ADDR, 0x24, 0x0102, },
+ { S5H1411_I2C_QAM_ADDR, 0x31, 0x7488, },
+ { S5H1411_I2C_QAM_ADDR, 0x32, 0x0a08, },
+ { S5H1411_I2C_QAM_ADDR, 0x3d, 0x8689, },
+ { S5H1411_I2C_QAM_ADDR, 0x49, 0x0048, },
+ { S5H1411_I2C_QAM_ADDR, 0x57, 0x2012, },
+ { S5H1411_I2C_QAM_ADDR, 0x5d, 0x7676, },
+ { S5H1411_I2C_QAM_ADDR, 0x04, 0x0400, },
+ { S5H1411_I2C_QAM_ADDR, 0x58, 0x00c0, },
+ { S5H1411_I2C_QAM_ADDR, 0x5b, 0x0100, },
+};
+
+/* VSB SNR lookup table */
+static struct vsb_snr_tab {
+ u16 val;
+ u16 data;
+} vsb_snr_tab[] = {
+ { 0x39f, 300, },
+ { 0x39b, 295, },
+ { 0x397, 290, },
+ { 0x394, 285, },
+ { 0x38f, 280, },
+ { 0x38b, 275, },
+ { 0x387, 270, },
+ { 0x382, 265, },
+ { 0x37d, 260, },
+ { 0x377, 255, },
+ { 0x370, 250, },
+ { 0x36a, 245, },
+ { 0x364, 240, },
+ { 0x35b, 235, },
+ { 0x353, 230, },
+ { 0x349, 225, },
+ { 0x340, 320, },
+ { 0x337, 215, },
+ { 0x327, 210, },
+ { 0x31b, 205, },
+ { 0x310, 200, },
+ { 0x302, 195, },
+ { 0x2f3, 190, },
+ { 0x2e4, 185, },
+ { 0x2d7, 180, },
+ { 0x2cd, 175, },
+ { 0x2bb, 170, },
+ { 0x2a9, 165, },
+ { 0x29e, 160, },
+ { 0x284, 155, },
+ { 0x27a, 150, },
+ { 0x260, 145, },
+ { 0x23a, 140, },
+ { 0x224, 135, },
+ { 0x213, 130, },
+ { 0x204, 125, },
+ { 0x1fe, 120, },
+ { 0, 0, },
+};
+
+/* QAM64 SNR lookup table */
+static struct qam64_snr_tab {
+ u16 val;
+ u16 data;
+} qam64_snr_tab[] = {
+ { 0x0001, 0, },
+ { 0x0af0, 300, },
+ { 0x0d80, 290, },
+ { 0x10a0, 280, },
+ { 0x14b5, 270, },
+ { 0x1590, 268, },
+ { 0x1680, 266, },
+ { 0x17b0, 264, },
+ { 0x18c0, 262, },
+ { 0x19b0, 260, },
+ { 0x1ad0, 258, },
+ { 0x1d00, 256, },
+ { 0x1da0, 254, },
+ { 0x1ef0, 252, },
+ { 0x2050, 250, },
+ { 0x20f0, 249, },
+ { 0x21d0, 248, },
+ { 0x22b0, 247, },
+ { 0x23a0, 246, },
+ { 0x2470, 245, },
+ { 0x24f0, 244, },
+ { 0x25a0, 243, },
+ { 0x26c0, 242, },
+ { 0x27b0, 241, },
+ { 0x28d0, 240, },
+ { 0x29b0, 239, },
+ { 0x2ad0, 238, },
+ { 0x2ba0, 237, },
+ { 0x2c80, 236, },
+ { 0x2d20, 235, },
+ { 0x2e00, 234, },
+ { 0x2f10, 233, },
+ { 0x3050, 232, },
+ { 0x3190, 231, },
+ { 0x3300, 230, },
+ { 0x3340, 229, },
+ { 0x3200, 228, },
+ { 0x3550, 227, },
+ { 0x3610, 226, },
+ { 0x3600, 225, },
+ { 0x3700, 224, },
+ { 0x3800, 223, },
+ { 0x3920, 222, },
+ { 0x3a20, 221, },
+ { 0x3b30, 220, },
+ { 0x3d00, 219, },
+ { 0x3e00, 218, },
+ { 0x4000, 217, },
+ { 0x4100, 216, },
+ { 0x4300, 215, },
+ { 0x4400, 214, },
+ { 0x4600, 213, },
+ { 0x4700, 212, },
+ { 0x4800, 211, },
+ { 0x4a00, 210, },
+ { 0x4b00, 209, },
+ { 0x4d00, 208, },
+ { 0x4f00, 207, },
+ { 0x5050, 206, },
+ { 0x5200, 205, },
+ { 0x53c0, 204, },
+ { 0x5450, 203, },
+ { 0x5650, 202, },
+ { 0x5820, 201, },
+ { 0x6000, 200, },
+ { 0xffff, 0, },
+};
+
+/* QAM256 SNR lookup table */
+static struct qam256_snr_tab {
+ u16 val;
+ u16 data;
+} qam256_snr_tab[] = {
+ { 0x0001, 0, },
+ { 0x0970, 400, },
+ { 0x0a90, 390, },
+ { 0x0b90, 380, },
+ { 0x0d90, 370, },
+ { 0x0ff0, 360, },
+ { 0x1240, 350, },
+ { 0x1345, 348, },
+ { 0x13c0, 346, },
+ { 0x14c0, 344, },
+ { 0x1500, 342, },
+ { 0x1610, 340, },
+ { 0x1700, 338, },
+ { 0x1800, 336, },
+ { 0x18b0, 334, },
+ { 0x1900, 332, },
+ { 0x1ab0, 330, },
+ { 0x1bc0, 328, },
+ { 0x1cb0, 326, },
+ { 0x1db0, 324, },
+ { 0x1eb0, 322, },
+ { 0x2030, 320, },
+ { 0x2200, 318, },
+ { 0x2280, 316, },
+ { 0x2410, 314, },
+ { 0x25b0, 312, },
+ { 0x27a0, 310, },
+ { 0x2840, 308, },
+ { 0x29d0, 306, },
+ { 0x2b10, 304, },
+ { 0x2d30, 302, },
+ { 0x2f20, 300, },
+ { 0x30c0, 298, },
+ { 0x3260, 297, },
+ { 0x32c0, 296, },
+ { 0x3300, 295, },
+ { 0x33b0, 294, },
+ { 0x34b0, 293, },
+ { 0x35a0, 292, },
+ { 0x3650, 291, },
+ { 0x3800, 290, },
+ { 0x3900, 289, },
+ { 0x3a50, 288, },
+ { 0x3b30, 287, },
+ { 0x3cb0, 286, },
+ { 0x3e20, 285, },
+ { 0x3fa0, 284, },
+ { 0x40a0, 283, },
+ { 0x41c0, 282, },
+ { 0x42f0, 281, },
+ { 0x44a0, 280, },
+ { 0x4600, 279, },
+ { 0x47b0, 278, },
+ { 0x4900, 277, },
+ { 0x4a00, 276, },
+ { 0x4ba0, 275, },
+ { 0x4d00, 274, },
+ { 0x4f00, 273, },
+ { 0x5000, 272, },
+ { 0x51f0, 272, },
+ { 0x53a0, 270, },
+ { 0x5520, 269, },
+ { 0x5700, 268, },
+ { 0x5800, 267, },
+ { 0x5a00, 266, },
+ { 0x5c00, 265, },
+ { 0x5d00, 264, },
+ { 0x5f00, 263, },
+ { 0x6000, 262, },
+ { 0x6200, 261, },
+ { 0x6400, 260, },
+ { 0xffff, 0, },
+};
+
+/* 8 bit registers, 16 bit values */
+static int s5h1411_writereg(struct s5h1411_state *state,
+ u8 addr, u8 reg, u16 data)
+{
+ int ret;
+ u8 buf [] = { reg, data >> 8, data & 0xff };
+
+ struct i2c_msg msg = { .addr = addr, .flags = 0, .buf = buf, .len = 3 };
+
+ ret = i2c_transfer(state->i2c, &msg, 1);
+
+ if (ret != 1)
+ printk(KERN_ERR "%s: writereg error 0x%02x 0x%02x 0x%04x, "
+ "ret == %i)\n", __func__, addr, reg, data, ret);
+
+ return (ret != 1) ? -1 : 0;
+}
+
+static u16 s5h1411_readreg(struct s5h1411_state *state, u8 addr, u8 reg)
+{
+ int ret;
+ u8 b0 [] = { reg };
+ u8 b1 [] = { 0, 0 };
+
+ struct i2c_msg msg [] = {
+ { .addr = addr, .flags = 0, .buf = b0, .len = 1 },
+ { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 } };
+
+ ret = i2c_transfer(state->i2c, msg, 2);
+
+ if (ret != 2)
+ printk(KERN_ERR "%s: readreg error (ret == %i)\n",
+ __func__, ret);
+ return (b1[0] << 8) | b1[1];
+}
+
+static int s5h1411_softreset(struct dvb_frontend *fe)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+ dprintk("%s()\n", __func__);
+
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 0);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf7, 1);
+ return 0;
+}
+
+static int s5h1411_set_if_freq(struct dvb_frontend *fe, int KHz)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+ dprintk("%s(%d KHz)\n", __func__, KHz);
+
+ switch (KHz) {
+ case 3250:
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x10d9);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x5342);
+ s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x10d9);
+ break;
+ case 3500:
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1225);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x1e96);
+ s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1225);
+ break;
+ case 4000:
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x14bc);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0xb53e);
+ s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x14bd);
+ break;
+ default:
+ dprintk("%s(%d KHz) Invalid, defaulting to 5380\n",
+ __func__, KHz);
+ /* no break, need to continue */
+ case 5380:
+ case 44000:
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x38, 0x1be4);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x39, 0x3655);
+ s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x2c, 0x1be4);
+ break;
+ }
+
+ state->if_freq = KHz;
+
+ return 0;
+}
+
+static int s5h1411_set_mpeg_timing(struct dvb_frontend *fe, int mode)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+ u16 val;
+
+ dprintk("%s(%d)\n", __func__, mode);
+
+ val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xbe) & 0xcfff;
+ switch (mode) {
+ case S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK:
+ val |= 0x0000;
+ break;
+ case S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK:
+ dprintk("%s(%d) Mode1 or Defaulting\n", __func__, mode);
+ val |= 0x1000;
+ break;
+ case S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK:
+ val |= 0x2000;
+ break;
+ case S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK:
+ val |= 0x3000;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ /* Configure MPEG Signal Timing charactistics */
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbe, val);
+}
+
+static int s5h1411_set_spectralinversion(struct dvb_frontend *fe, int inversion)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+ u16 val;
+
+ dprintk("%s(%d)\n", __func__, inversion);
+ val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x24) & ~0x1000;
+
+ if (inversion == 1)
+ val |= 0x1000; /* Inverted */
+ else
+ val |= 0x0000;
+
+ state->inversion = inversion;
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x24, val);
+}
+
+static int s5h1411_enable_modulation(struct dvb_frontend *fe,
+ fe_modulation_t m)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+ dprintk("%s(0x%08x)\n", __func__, m);
+
+ switch (m) {
+ case VSB_8:
+ dprintk("%s() VSB_8\n", __func__);
+ s5h1411_set_if_freq(fe, state->config->vsb_if);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x71);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x00);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0xf1);
+ break;
+ case QAM_64:
+ case QAM_256:
+ dprintk("%s() QAM_AUTO (64/256)\n", __func__);
+ s5h1411_set_if_freq(fe, state->config->qam_if);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0x00, 0x0171);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf6, 0x0001);
+ s5h1411_writereg(state, S5H1411_I2C_QAM_ADDR, 0x16, 0x1101);
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xcd, 0x00f0);
+ break;
+ default:
+ dprintk("%s() Invalid modulation\n", __func__);
+ return -EINVAL;
+ }
+
+ state->current_modulation = m;
+ s5h1411_softreset(fe);
+
+ return 0;
+}
+
+static int s5h1411_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+ dprintk("%s(%d)\n", __func__, enable);
+
+ if (enable)
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
+ else
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 0);
+}
+
+static int s5h1411_set_gpio(struct dvb_frontend *fe, int enable)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+ u16 val;
+
+ dprintk("%s(%d)\n", __func__, enable);
+
+ val = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xe0) & ~0x02;
+
+ if (enable)
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0,
+ val | 0x02);
+ else
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xe0, val);
+}
+
+static int s5h1411_sleep(struct dvb_frontend *fe, int enable)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+ dprintk("%s(%d)\n", __func__, enable);
+
+ if (enable)
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 1);
+ else {
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf4, 0);
+ s5h1411_softreset(fe);
+ }
+
+ return 0;
+}
+
+static int s5h1411_register_reset(struct dvb_frontend *fe)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+ dprintk("%s()\n", __func__);
+
+ return s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf3, 0);
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+static int s5h1411_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+ dprintk("%s(frequency=%d)\n", __func__, p->frequency);
+
+ s5h1411_softreset(fe);
+
+ state->current_frequency = p->frequency;
+
+ s5h1411_enable_modulation(fe, p->u.vsb.modulation);
+
+ /* Allow the demod to settle */
+ msleep(100);
+
+ if (fe->ops.tuner_ops.set_params) {
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ fe->ops.tuner_ops.set_params(fe, p);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+
+ return 0;
+}
+
+/* Reset the demod hardware and reset all of the configuration registers
+ to a default state. */
+static int s5h1411_init(struct dvb_frontend *fe)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+ int i;
+
+ dprintk("%s()\n", __func__);
+
+ s5h1411_sleep(fe, 0);
+ s5h1411_register_reset(fe);
+
+ for (i = 0; i < ARRAY_SIZE(init_tab); i++)
+ s5h1411_writereg(state, init_tab[i].addr,
+ init_tab[i].reg,
+ init_tab[i].data);
+
+ /* The datasheet says that after initialisation, VSB is default */
+ state->current_modulation = VSB_8;
+
+ if (state->config->output_mode == S5H1411_SERIAL_OUTPUT)
+ /* Serial */
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1101);
+ else
+ /* Parallel */
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xbd, 0x1001);
+
+ s5h1411_set_spectralinversion(fe, state->config->inversion);
+ s5h1411_set_if_freq(fe, state->config->vsb_if);
+ s5h1411_set_gpio(fe, state->config->gpio);
+ s5h1411_set_mpeg_timing(fe, state->config->mpeg_timing);
+ s5h1411_softreset(fe);
+
+ /* Note: Leaving the I2C gate closed. */
+ s5h1411_i2c_gate_ctrl(fe, 0);
+
+ return 0;
+}
+
+static int s5h1411_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+ u16 reg;
+ u32 tuner_status = 0;
+
+ *status = 0;
+
+ /* Get the demodulator status */
+ reg = (s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2) >> 15)
+ & 0x0001;
+ if (reg)
+ *status |= FE_HAS_LOCK | FE_HAS_CARRIER | FE_HAS_SIGNAL;
+
+ switch (state->current_modulation) {
+ case QAM_64:
+ case QAM_256:
+ reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf0);
+ if (reg & 0x100)
+ *status |= FE_HAS_VITERBI;
+ if (reg & 0x10)
+ *status |= FE_HAS_SYNC;
+ break;
+ case VSB_8:
+ reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x5e);
+ if (reg & 0x0001)
+ *status |= FE_HAS_SYNC;
+ reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf2);
+ if (reg & 0x1000)
+ *status |= FE_HAS_VITERBI;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ switch (state->config->status_mode) {
+ case S5H1411_DEMODLOCKING:
+ if (*status & FE_HAS_VITERBI)
+ *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+ break;
+ case S5H1411_TUNERLOCKING:
+ /* Get the tuner status */
+ if (fe->ops.tuner_ops.get_status) {
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ fe->ops.tuner_ops.get_status(fe, &tuner_status);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+ if (tuner_status)
+ *status |= FE_HAS_CARRIER | FE_HAS_SIGNAL;
+ break;
+ }
+
+ dprintk("%s() status 0x%08x\n", __func__, *status);
+
+ return 0;
+}
+
+static int s5h1411_qam256_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
+{
+ int i, ret = -EINVAL;
+ dprintk("%s()\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(qam256_snr_tab); i++) {
+ if (v < qam256_snr_tab[i].val) {
+ *snr = qam256_snr_tab[i].data;
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+
+static int s5h1411_qam64_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
+{
+ int i, ret = -EINVAL;
+ dprintk("%s()\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(qam64_snr_tab); i++) {
+ if (v < qam64_snr_tab[i].val) {
+ *snr = qam64_snr_tab[i].data;
+ ret = 0;
+ break;
+ }
+ }
+ return ret;
+}
+
+static int s5h1411_vsb_lookup_snr(struct dvb_frontend *fe, u16 *snr, u16 v)
+{
+ int i, ret = -EINVAL;
+ dprintk("%s()\n", __func__);
+
+ for (i = 0; i < ARRAY_SIZE(vsb_snr_tab); i++) {
+ if (v > vsb_snr_tab[i].val) {
+ *snr = vsb_snr_tab[i].data;
+ ret = 0;
+ break;
+ }
+ }
+ dprintk("%s() snr=%d\n", __func__, *snr);
+ return ret;
+}
+
+static int s5h1411_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+ u16 reg;
+ dprintk("%s()\n", __func__);
+
+ switch (state->current_modulation) {
+ case QAM_64:
+ reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1);
+ return s5h1411_qam64_lookup_snr(fe, snr, reg);
+ case QAM_256:
+ reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xf1);
+ return s5h1411_qam256_lookup_snr(fe, snr, reg);
+ case VSB_8:
+ reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR,
+ 0xf2) & 0x3ff;
+ return s5h1411_vsb_lookup_snr(fe, snr, reg);
+ default:
+ break;
+ }
+
+ return -EINVAL;
+}
+
+static int s5h1411_read_signal_strength(struct dvb_frontend *fe,
+ u16 *signal_strength)
+{
+ return s5h1411_read_snr(fe, signal_strength);
+}
+
+static int s5h1411_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+ *ucblocks = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0xc9);
+
+ return 0;
+}
+
+static int s5h1411_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ return s5h1411_read_ucblocks(fe, ber);
+}
+
+static int s5h1411_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+
+ p->frequency = state->current_frequency;
+ p->u.vsb.modulation = state->current_modulation;
+
+ return 0;
+}
+
+static int s5h1411_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *tune)
+{
+ tune->min_delay_ms = 1000;
+ return 0;
+}
+
+static void s5h1411_release(struct dvb_frontend *fe)
+{
+ struct s5h1411_state *state = fe->demodulator_priv;
+ kfree(state);
+}
+
+static struct dvb_frontend_ops s5h1411_ops;
+
+struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct s5h1411_state *state = NULL;
+ u16 reg;
+
+ /* allocate memory for the internal state */
+ state = kmalloc(sizeof(struct s5h1411_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+ state->current_modulation = VSB_8;
+ state->inversion = state->config->inversion;
+
+ /* check if the demod exists */
+ reg = s5h1411_readreg(state, S5H1411_I2C_TOP_ADDR, 0x05);
+ if (reg != 0x0066)
+ goto error;
+
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &s5h1411_ops,
+ sizeof(struct dvb_frontend_ops));
+
+ state->frontend.demodulator_priv = state;
+
+ if (s5h1411_init(&state->frontend) != 0) {
+ printk(KERN_ERR "%s: Failed to initialize correctly\n",
+ __func__);
+ goto error;
+ }
+
+ /* Note: Leaving the I2C gate open here. */
+ s5h1411_writereg(state, S5H1411_I2C_TOP_ADDR, 0xf5, 1);
+
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(s5h1411_attach);
+
+static struct dvb_frontend_ops s5h1411_ops = {
+
+ .info = {
+ .name = "Samsung S5H1411 QAM/8VSB Frontend",
+ .type = FE_ATSC,
+ .frequency_min = 54000000,
+ .frequency_max = 858000000,
+ .frequency_stepsize = 62500,
+ .caps = FE_CAN_QAM_64 | FE_CAN_QAM_256 | FE_CAN_8VSB
+ },
+
+ .init = s5h1411_init,
+ .i2c_gate_ctrl = s5h1411_i2c_gate_ctrl,
+ .set_frontend = s5h1411_set_frontend,
+ .get_frontend = s5h1411_get_frontend,
+ .get_tune_settings = s5h1411_get_tune_settings,
+ .read_status = s5h1411_read_status,
+ .read_ber = s5h1411_read_ber,
+ .read_signal_strength = s5h1411_read_signal_strength,
+ .read_snr = s5h1411_read_snr,
+ .read_ucblocks = s5h1411_read_ucblocks,
+ .release = s5h1411_release,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("Samsung S5H1411 QAM-B/ATSC Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/linux/drivers/media/dvb/frontends/s5h1411.h b/linux/drivers/media/dvb/frontends/s5h1411.h
new file mode 100644
index 000000000..1855f64ed
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/s5h1411.h
@@ -0,0 +1,90 @@
+/*
+ Samsung S5H1411 VSB/QAM demodulator driver
+
+ Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+
+ 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 __S5H1411_H__
+#define __S5H1411_H__
+
+#include <linux/dvb/frontend.h>
+
+#define S5H1411_I2C_TOP_ADDR (0x32 >> 1)
+#define S5H1411_I2C_QAM_ADDR (0x34 >> 1)
+
+struct s5h1411_config {
+
+ /* serial/parallel output */
+#define S5H1411_PARALLEL_OUTPUT 0
+#define S5H1411_SERIAL_OUTPUT 1
+ u8 output_mode;
+
+ /* GPIO Setting */
+#define S5H1411_GPIO_OFF 0
+#define S5H1411_GPIO_ON 1
+ u8 gpio;
+
+ /* MPEG signal timing */
+#define S5H1411_MPEGTIMING_CONTINOUS_INVERTING_CLOCK 0
+#define S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK 1
+#define S5H1411_MPEGTIMING_NONCONTINOUS_INVERTING_CLOCK 2
+#define S5H1411_MPEGTIMING_NONCONTINOUS_NONINVERTING_CLOCK 3
+ u16 mpeg_timing;
+
+ /* IF Freq for QAM and VSB in KHz */
+#define S5H1411_IF_2500 2500
+#define S5H1411_IF_3500 3500
+#define S5H1411_IF_4000 4000
+#define S5H1411_IF_5380 5380
+#define S5H1411_IF_44000 44000
+#define S5H1411_VSB_IF_DEFAULT S5H1411_IF_44000
+#define S5H1411_QAM_IF_DEFAULT S5H1411_IF_44000
+ u16 qam_if;
+ u16 vsb_if;
+
+ /* Spectral Inversion */
+#define S5H1411_INVERSION_OFF 0
+#define S5H1411_INVERSION_ON 1
+ u8 inversion;
+
+ /* Return lock status based on tuner lock, or demod lock */
+#define S5H1411_TUNERLOCKING 0
+#define S5H1411_DEMODLOCKING 1
+ u8 status_mode;
+};
+
+#if defined(CONFIG_DVB_S5H1411) || \
+ (defined(CONFIG_DVB_S5H1411_MODULE) && defined(MODULE))
+extern struct dvb_frontend *s5h1411_attach(const struct s5h1411_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *s5h1411_attach(
+ const struct s5h1411_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_S5H1411 */
+
+#endif /* __S5H1411_H__ */
+
+/*
+ * Local variables:
+ * c-basic-offset: 8
+ */
diff --git a/linux/drivers/media/dvb/frontends/s5h1420.c b/linux/drivers/media/dvb/frontends/s5h1420.c
index 7c64af91e..996f37704 100644
--- a/linux/drivers/media/dvb/frontends/s5h1420.c
+++ b/linux/drivers/media/dvb/frontends/s5h1420.c
@@ -1,24 +1,26 @@
/*
-Driver for Samsung S5H1420 QPSK Demodulator
-
-Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.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.
-
-*/
+ * Driver for
+ * Samsung S5H1420 and
+ * PnpNetwork PN1010 QPSK Demodulator
+ *
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org>
+ *
+ * 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/kernel.h>
#include <linux/module.h>
@@ -29,23 +31,35 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#include <linux/jiffies.h>
#include <asm/div64.h>
-#include "dvb_frontend.h"
-#include "s5h1420.h"
+#include <linux/i2c.h>
+#include "dvb_frontend.h"
+#include "s5h1420.h"
+#include "s5h1420_priv.h"
#define TONE_FREQ 22000
struct s5h1420_state {
struct i2c_adapter* i2c;
const struct s5h1420_config* config;
+
struct dvb_frontend frontend;
+ struct i2c_adapter tuner_i2c_adapter;
+
+ u8 CON_1_val;
u8 postlocked:1;
u32 fclk;
u32 tunedfreq;
fe_code_rate_t fec_inner;
u32 symbol_rate;
+
+ /* FIXME: ugly workaround for flexcop's incapable i2c-controller
+ * it does not support repeated-start, workaround: write addr-1
+ * and then read
+ */
+ u8 shadow[255];
};
static u32 s5h1420_getsymbolrate(struct s5h1420_state* state);
@@ -54,43 +68,65 @@ static int s5h1420_get_tune_settings(struct dvb_frontend* fe,
static int debug;
-#define dprintk if (debug) printk
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "enable debugging");
+
+#define dprintk(x...) do { \
+ if (debug) \
+ printk(KERN_DEBUG "S5H1420: " x); \
+} while (0)
+
+static u8 s5h1420_readreg(struct s5h1420_state *state, u8 reg)
+{
+ int ret;
+ u8 b[2];
+ struct i2c_msg msg[] = {
+ { .addr = state->config->demod_address, .flags = 0, .buf = b, .len = 2 },
+ { .addr = state->config->demod_address, .flags = 0, .buf = &reg, .len = 1 },
+ { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b, .len = 1 },
+ };
+
+ b[0] = (reg - 1) & 0xff;
+ b[1] = state->shadow[(reg - 1) & 0xff];
+
+ if (state->config->repeated_start_workaround) {
+ ret = i2c_transfer(state->i2c, msg, 3);
+ if (ret != 3)
+ return ret;
+ } else {
+ ret = i2c_transfer(state->i2c, &msg[1], 2);
+ if (ret != 2)
+ return ret;
+ }
+
+ /* dprintk("rd(%02x): %02x %02x\n", state->config->demod_address, reg, b[0]); */
+
+ return b[0];
+}
static int s5h1420_writereg (struct s5h1420_state* state, u8 reg, u8 data)
{
- u8 buf [] = { reg, data };
+ u8 buf[] = { reg, data };
struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
int err;
- if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
- dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
+ /* dprintk("wr(%02x): %02x %02x\n", state->config->demod_address, reg, data); */
+ err = i2c_transfer(state->i2c, &msg, 1);
+ if (err != 1) {
+ dprintk("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
return -EREMOTEIO;
}
+ state->shadow[reg] = data;
return 0;
}
-static u8 s5h1420_readreg (struct s5h1420_state* state, u8 reg)
-{
- int ret;
- u8 b0 [] = { reg };
- u8 b1 [] = { 0 };
- struct i2c_msg msg1 = { .addr = state->config->demod_address, .flags = 0, .buf = b0, .len = 1 };
- struct i2c_msg msg2 = { .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 1 };
-
- if ((ret = i2c_transfer (state->i2c, &msg1, 1)) != 1)
- return ret;
-
- if ((ret = i2c_transfer (state->i2c, &msg2, 1)) != 1)
- return ret;
-
- return b1[0];
-}
-
static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltage)
{
struct s5h1420_state* state = fe->demodulator_priv;
+ dprintk("enter %s\n", __func__);
+
switch(voltage) {
case SEC_VOLTAGE_13:
s5h1420_writereg(state, 0x3c,
@@ -106,6 +142,7 @@ static int s5h1420_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
break;
}
+ dprintk("leave %s\n", __func__);
return 0;
}
@@ -113,6 +150,7 @@ static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
{
struct s5h1420_state* state = fe->demodulator_priv;
+ dprintk("enter %s\n", __func__);
switch(tone) {
case SEC_TONE_ON:
s5h1420_writereg(state, 0x3b,
@@ -124,6 +162,7 @@ static int s5h1420_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
(s5h1420_readreg(state, 0x3b) & 0x74) | 0x01);
break;
}
+ dprintk("leave %s\n", __func__);
return 0;
}
@@ -137,6 +176,7 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe,
unsigned long timeout;
int result = 0;
+ dprintk("enter %s\n", __func__);
if (cmd->msg_len > 8)
return -EINVAL;
@@ -168,6 +208,7 @@ static int s5h1420_send_master_cmd (struct dvb_frontend* fe,
/* restore original settings */
s5h1420_writereg(state, 0x3b, val);
msleep(15);
+ dprintk("leave %s\n", __func__);
return result;
}
@@ -289,6 +330,8 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
struct s5h1420_state* state = fe->demodulator_priv;
u8 val;
+ dprintk("enter %s\n", __func__);
+
if (status == NULL)
return -EINVAL;
@@ -297,13 +340,13 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
/* fix for FEC 5/6 inversion issue - if it doesn't quite lock, invert
the inversion, wait a bit and check again */
- if (*status == (FE_HAS_SIGNAL|FE_HAS_CARRIER|FE_HAS_VITERBI)) {
- val = s5h1420_readreg(state, 0x32);
+ if (*status == (FE_HAS_SIGNAL | FE_HAS_CARRIER | FE_HAS_VITERBI)) {
+ val = s5h1420_readreg(state, Vit10);
if ((val & 0x07) == 0x03) {
if (val & 0x08)
- s5h1420_writereg(state, 0x31, 0x13);
+ s5h1420_writereg(state, Vit09, 0x13);
else
- s5h1420_writereg(state, 0x31, 0x1b);
+ s5h1420_writereg(state, Vit09, 0x1b);
/* wait a bit then update lock status */
mdelay(200);
@@ -312,68 +355,77 @@ static int s5h1420_read_status(struct dvb_frontend* fe, fe_status_t* status)
}
/* perform post lock setup */
- if ((*status & FE_HAS_LOCK) && (!state->postlocked)) {
+ if ((*status & FE_HAS_LOCK) && !state->postlocked) {
/* calculate the data rate */
u32 tmp = s5h1420_getsymbolrate(state);
- switch(s5h1420_readreg(state, 0x32) & 0x07) {
- case 0:
- tmp = (tmp * 2 * 1) / 2;
- break;
-
- case 1:
- tmp = (tmp * 2 * 2) / 3;
- break;
-
- case 2:
- tmp = (tmp * 2 * 3) / 4;
- break;
-
- case 3:
- tmp = (tmp * 2 * 5) / 6;
- break;
-
- case 4:
- tmp = (tmp * 2 * 6) / 7;
- break;
-
- case 5:
- tmp = (tmp * 2 * 7) / 8;
- break;
+ switch (s5h1420_readreg(state, Vit10) & 0x07) {
+ case 0: tmp = (tmp * 2 * 1) / 2; break;
+ case 1: tmp = (tmp * 2 * 2) / 3; break;
+ case 2: tmp = (tmp * 2 * 3) / 4; break;
+ case 3: tmp = (tmp * 2 * 5) / 6; break;
+ case 4: tmp = (tmp * 2 * 6) / 7; break;
+ case 5: tmp = (tmp * 2 * 7) / 8; break;
}
+
if (tmp == 0) {
- printk("s5h1420: avoided division by 0\n");
+ printk(KERN_ERR "s5h1420: avoided division by 0\n");
tmp = 1;
}
tmp = state->fclk / tmp;
+
/* set the MPEG_CLK_INTL for the calculated data rate */
- if (tmp < 4)
+ if (tmp < 2)
val = 0x00;
- else if (tmp < 8)
+ else if (tmp < 5)
val = 0x01;
- else if (tmp < 12)
+ else if (tmp < 9)
val = 0x02;
- else if (tmp < 16)
+ else if (tmp < 13)
val = 0x03;
- else if (tmp < 24)
+ else if (tmp < 17)
val = 0x04;
- else if (tmp < 32)
+ else if (tmp < 25)
val = 0x05;
- else
+ else if (tmp < 33)
val = 0x06;
- s5h1420_writereg(state, 0x22, val);
-
- /* DC freeze */
- s5h1420_writereg(state, 0x1f, s5h1420_readreg(state, 0x1f) | 0x01);
-
- /* kicker disable + remove DC offset */
- s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) & 0x6f);
+ else
+ val = 0x07;
+ dprintk("for MPEG_CLK_INTL %d %x\n", tmp, val);
+
+ s5h1420_writereg(state, FEC01, 0x18);
+ s5h1420_writereg(state, FEC01, 0x10);
+ s5h1420_writereg(state, FEC01, val);
+
+ /* Enable "MPEG_Out" */
+ val = s5h1420_readreg(state, Mpeg02);
+ s5h1420_writereg(state, Mpeg02, val | (1 << 6));
+
+ /* kicker disable */
+ val = s5h1420_readreg(state, QPSK01) & 0x7f;
+ s5h1420_writereg(state, QPSK01, val);
+
+ /* DC freeze TODO it was never activated by default or it can stay activated */
+#if 0
+ val = s5h1420_readreg(state, 0x1f);
+ s5h1420_writereg(state, 0x1f, val | 0x01);
+#endif
+
+ if (s5h1420_getsymbolrate(state) >= 20000000) {
+ s5h1420_writereg(state, Loop04, 0x8a);
+ s5h1420_writereg(state, Loop05, 0x6a);
+ } else {
+ s5h1420_writereg(state, Loop04, 0x58);
+ s5h1420_writereg(state, Loop05, 0x27);
+ }
/* post-lock processing has been done! */
state->postlocked = 1;
}
+ dprintk("leave %s\n", __func__);
+
return 0;
}
@@ -414,6 +466,7 @@ static int s5h1420_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
static void s5h1420_reset(struct s5h1420_state* state)
{
+ dprintk("%s\n", __func__);
s5h1420_writereg (state, 0x01, 0x08);
s5h1420_writereg (state, 0x01, 0x00);
udelay(10);
@@ -422,54 +475,79 @@ static void s5h1420_reset(struct s5h1420_state* state)
static void s5h1420_setsymbolrate(struct s5h1420_state* state,
struct dvb_frontend_parameters *p)
{
+ u8 v;
u64 val;
+ dprintk("enter %s\n", __func__);
+
val = ((u64) p->u.qpsk.symbol_rate / 1000ULL) * (1ULL<<24);
- if (p->u.qpsk.symbol_rate <= 21000000) {
+ if (p->u.qpsk.symbol_rate < 29000000)
val *= 2;
- }
do_div(val, (state->fclk / 1000));
- s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0x7f);
- s5h1420_writereg(state, 0x11, val >> 16);
- s5h1420_writereg(state, 0x12, val >> 8);
- s5h1420_writereg(state, 0x13, val & 0xff);
- s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x80);
+ dprintk("symbol rate register: %06llx\n", (unsigned long long)val);
+
+ v = s5h1420_readreg(state, Loop01);
+ s5h1420_writereg(state, Loop01, v & 0x7f);
+ s5h1420_writereg(state, Tnco01, val >> 16);
+ s5h1420_writereg(state, Tnco02, val >> 8);
+ s5h1420_writereg(state, Tnco03, val & 0xff);
+ s5h1420_writereg(state, Loop01, v | 0x80);
+ dprintk("leave %s\n", __func__);
}
static u32 s5h1420_getsymbolrate(struct s5h1420_state* state)
{
+#if 0
+ /* TODO getsymbolrate gives strange values - something is wrong with
+ * configuring the read
+ */
+
u64 val = 0;
+ u8 v;
int sampling = 2;
- if (s5h1420_readreg(state, 0x05) & 0x2)
- sampling = 1;
+ v = s5h1420_readreg(state, QPSK02);
+ s5h1420_writereg(state, QPSK02, v | 0x08);
+ val = s5h1420_readreg(state, Tnco01) << 16;
+ val |= s5h1420_readreg(state, Tnco02) << 8;
+ val |= s5h1420_readreg(state, Tnco03);
+ s5h1420_writereg(state, QPSK02, v & 0xf7);
- s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) | 0x08);
- val = s5h1420_readreg(state, 0x11) << 16;
- val |= s5h1420_readreg(state, 0x12) << 8;
- val |= s5h1420_readreg(state, 0x13);
- s5h1420_writereg(state, 0x06, s5h1420_readreg(state, 0x06) & 0xf7);
+ dprintk("get_symbolrate: raw: %x\n", val);
- val *= (state->fclk / 1000ULL);
- do_div(val, ((1<<24) * sampling));
+ val *= (state->fclk / 1000);
+ if (s5h1420_readreg(state, QPSK01) & 0x2)
+ do_div(val, 1 << 24);
+ else
+ do_div(val, 1 << 25);
+ dprintk("get_symbolrate: %d\n", (u32) (val * 1000ULL));
return (u32) (val * 1000ULL);
+#endif
+ return state->symbol_rate;
}
static void s5h1420_setfreqoffset(struct s5h1420_state* state, int freqoffset)
{
int val;
+ u8 v;
+
+ dprintk("enter %s\n", __func__);
/* remember freqoffset is in kHz, but the chip wants the offset in Hz, so
* divide fclk by 1000000 to get the correct value. */
val = -(int) ((freqoffset * (1<<24)) / (state->fclk / 1000000));
- s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) & 0xbf);
- s5h1420_writereg(state, 0x0e, val >> 16);
- s5h1420_writereg(state, 0x0f, val >> 8);
- s5h1420_writereg(state, 0x10, val & 0xff);
- s5h1420_writereg(state, 0x09, s5h1420_readreg(state, 0x09) | 0x40);
+ dprintk("phase rotator/freqoffset: %d %06x\n", freqoffset, val);
+
+ v = s5h1420_readreg(state, Loop01);
+ s5h1420_writereg(state, Loop01, v & 0xbf);
+ s5h1420_writereg(state, Pnco01, val >> 16);
+ s5h1420_writereg(state, Pnco02, val >> 8);
+ s5h1420_writereg(state, Pnco03, val & 0xff);
+ s5h1420_writereg(state, Loop01, v | 0x40);
+ dprintk("leave %s\n", __func__);
}
static int s5h1420_getfreqoffset(struct s5h1420_state* state)
@@ -496,52 +574,53 @@ static void s5h1420_setfec_inversion(struct s5h1420_state* state,
struct dvb_frontend_parameters *p)
{
u8 inversion = 0;
+ u8 vit08, vit09;
+
+ dprintk("enter %s\n", __func__);
- if (p->inversion == INVERSION_OFF) {
+ if (p->inversion == INVERSION_OFF)
inversion = state->config->invert ? 0x08 : 0;
- } else if (p->inversion == INVERSION_ON) {
+ else if (p->inversion == INVERSION_ON)
inversion = state->config->invert ? 0 : 0x08;
- }
if ((p->u.qpsk.fec_inner == FEC_AUTO) || (p->inversion == INVERSION_AUTO)) {
- s5h1420_writereg(state, 0x30, 0x3f);
- s5h1420_writereg(state, 0x31, 0x00 | inversion);
+ vit08 = 0x3f;
+ vit09 = 0;
} else {
switch(p->u.qpsk.fec_inner) {
case FEC_1_2:
- s5h1420_writereg(state, 0x30, 0x01);
- s5h1420_writereg(state, 0x31, 0x10 | inversion);
+ vit08 = 0x01; vit09 = 0x10;
break;
case FEC_2_3:
- s5h1420_writereg(state, 0x30, 0x02);
- s5h1420_writereg(state, 0x31, 0x11 | inversion);
+ vit08 = 0x02; vit09 = 0x11;
break;
case FEC_3_4:
- s5h1420_writereg(state, 0x30, 0x04);
- s5h1420_writereg(state, 0x31, 0x12 | inversion);
+ vit08 = 0x04; vit09 = 0x12;
break;
case FEC_5_6:
- s5h1420_writereg(state, 0x30, 0x08);
- s5h1420_writereg(state, 0x31, 0x13 | inversion);
+ vit08 = 0x08; vit09 = 0x13;
break;
case FEC_6_7:
- s5h1420_writereg(state, 0x30, 0x10);
- s5h1420_writereg(state, 0x31, 0x14 | inversion);
+ vit08 = 0x10; vit09 = 0x14;
break;
case FEC_7_8:
- s5h1420_writereg(state, 0x30, 0x20);
- s5h1420_writereg(state, 0x31, 0x15 | inversion);
+ vit08 = 0x20; vit09 = 0x15;
break;
default:
return;
}
}
+ vit09 |= inversion;
+ dprintk("fec: %02x %02x\n", vit08, vit09);
+ s5h1420_writereg(state, Vit08, vit08);
+ s5h1420_writereg(state, Vit09, vit09);
+ dprintk("leave %s\n", __func__);
}
static fe_code_rate_t s5h1420_getfec(struct s5h1420_state* state)
@@ -583,16 +662,19 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe,
struct s5h1420_state* state = fe->demodulator_priv;
int frequency_delta;
struct dvb_frontend_tune_settings fesettings;
+ uint8_t clock_settting;
+
+ dprintk("enter %s\n", __func__);
/* check if we should do a fast-tune */
memcpy(&fesettings.parameters, p, sizeof(struct dvb_frontend_parameters));
s5h1420_get_tune_settings(fe, &fesettings);
frequency_delta = p->frequency - state->tunedfreq;
if ((frequency_delta > -fesettings.max_drift) &&
- (frequency_delta < fesettings.max_drift) &&
- (frequency_delta != 0) &&
- (state->fec_inner == p->u.qpsk.fec_inner) &&
- (state->symbol_rate == p->u.qpsk.symbol_rate)) {
+ (frequency_delta < fesettings.max_drift) &&
+ (frequency_delta != 0) &&
+ (state->fec_inner == p->u.qpsk.fec_inner) &&
+ (state->symbol_rate == p->u.qpsk.symbol_rate)) {
if (fe->ops.tuner_ops.set_params) {
fe->ops.tuner_ops.set_params(fe, p);
@@ -606,54 +688,93 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe,
} else {
s5h1420_setfreqoffset(state, 0);
}
+ dprintk("simple tune\n");
return 0;
}
+ dprintk("tuning demod\n");
/* first of all, software reset */
s5h1420_reset(state);
/* set s5h1420 fclk PLL according to desired symbol rate */
- if (p->u.qpsk.symbol_rate > 28000000) {
- state->fclk = 88000000;
- s5h1420_writereg(state, 0x03, 0x50);
- s5h1420_writereg(state, 0x04, 0x40);
- s5h1420_writereg(state, 0x05, 0xae);
- } else if (p->u.qpsk.symbol_rate > 21000000) {
+ if (p->u.qpsk.symbol_rate > 33000000)
+ state->fclk = 80000000;
+ else if (p->u.qpsk.symbol_rate > 28500000)
state->fclk = 59000000;
- s5h1420_writereg(state, 0x03, 0x33);
- s5h1420_writereg(state, 0x04, 0x40);
- s5h1420_writereg(state, 0x05, 0xae);
- } else {
+ else if (p->u.qpsk.symbol_rate > 25000000)
+ state->fclk = 86000000;
+ else if (p->u.qpsk.symbol_rate > 1900000)
state->fclk = 88000000;
- s5h1420_writereg(state, 0x03, 0x50);
- s5h1420_writereg(state, 0x04, 0x40);
- s5h1420_writereg(state, 0x05, 0xac);
+ else
+ state->fclk = 44000000;
+
+ /* Clock */
+ switch (state->fclk) {
+ default:
+ case 88000000:
+ clock_settting = 80;
+ break;
+ case 86000000:
+ clock_settting = 78;
+ break;
+ case 80000000:
+ clock_settting = 72;
+ break;
+ case 59000000:
+ clock_settting = 51;
+ break;
+ case 44000000:
+ clock_settting = 36;
+ break;
}
+ dprintk("pll01: %d, ToneFreq: %d\n", state->fclk/1000000 - 8, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
+ s5h1420_writereg(state, PLL01, state->fclk/1000000 - 8);
+ s5h1420_writereg(state, PLL02, 0x40);
+ s5h1420_writereg(state, DiS01, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
- /* set misc registers */
- s5h1420_writereg(state, 0x02, 0x00);
- s5h1420_writereg(state, 0x06, 0x00);
- s5h1420_writereg(state, 0x07, 0xb0);
- s5h1420_writereg(state, 0x0a, 0xe7);
- s5h1420_writereg(state, 0x0b, 0x78);
- s5h1420_writereg(state, 0x0c, 0x48);
- s5h1420_writereg(state, 0x0d, 0x6b);
- s5h1420_writereg(state, 0x2e, 0x8e);
- s5h1420_writereg(state, 0x35, 0x33);
- s5h1420_writereg(state, 0x38, 0x01);
- s5h1420_writereg(state, 0x39, 0x7d);
- s5h1420_writereg(state, 0x3a, (state->fclk + (TONE_FREQ * 32) - 1) / (TONE_FREQ * 32));
- s5h1420_writereg(state, 0x3c, 0x00);
- s5h1420_writereg(state, 0x45, 0x61);
- s5h1420_writereg(state, 0x46, 0x1d);
+ /* TODO DC offset removal, config parameter ? */
+ if (p->u.qpsk.symbol_rate > 29000000)
+ s5h1420_writereg(state, QPSK01, 0xae | 0x10);
+ else
+ s5h1420_writereg(state, QPSK01, 0xac | 0x10);
- /* start QPSK */
- s5h1420_writereg(state, 0x05, s5h1420_readreg(state, 0x05) | 1);
+ /* set misc registers */
+ s5h1420_writereg(state, CON_1, 0x00);
+ s5h1420_writereg(state, QPSK02, 0x00);
+ s5h1420_writereg(state, Pre01, 0xb0);
+
+ s5h1420_writereg(state, Loop01, 0xF0);
+ s5h1420_writereg(state, Loop02, 0x2a); /* e7 for s5h1420 */
+ s5h1420_writereg(state, Loop03, 0x79); /* 78 for s5h1420 */
+ if (p->u.qpsk.symbol_rate > 20000000)
+ s5h1420_writereg(state, Loop04, 0x79);
+ else
+ s5h1420_writereg(state, Loop04, 0x58);
+ s5h1420_writereg(state, Loop05, 0x6b);
+
+ if (p->u.qpsk.symbol_rate >= 8000000)
+ s5h1420_writereg(state, Post01, (0 << 6) | 0x10);
+ else if (p->u.qpsk.symbol_rate >= 4000000)
+ s5h1420_writereg(state, Post01, (1 << 6) | 0x10);
+ else
+ s5h1420_writereg(state, Post01, (3 << 6) | 0x10);
+
+ s5h1420_writereg(state, Monitor12, 0x00); /* unfreeze DC compensation */
+
+ s5h1420_writereg(state, Sync01, 0x33);
+ s5h1420_writereg(state, Mpeg01, state->config->cdclk_polarity);
+ s5h1420_writereg(state, Mpeg02, 0x3d); /* Parallel output more, disabled -> enabled later */
+ s5h1420_writereg(state, Err01, 0x03); /* 0x1d for s5h1420 */
+
+ s5h1420_writereg(state, Vit06, 0x6e); /* 0x8e for s5h1420 */
+ s5h1420_writereg(state, DiS03, 0x00);
+ s5h1420_writereg(state, Rf01, 0x61); /* Tuner i2c address - for the gate controller */
/* set tuner PLL */
if (fe->ops.tuner_ops.set_params) {
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);
s5h1420_setfreqoffset(state, 0);
}
@@ -661,10 +782,15 @@ static int s5h1420_set_frontend(struct dvb_frontend* fe,
s5h1420_setsymbolrate(state, p);
s5h1420_setfec_inversion(state, p);
+ /* start QPSK */
+ s5h1420_writereg(state, QPSK01, s5h1420_readreg(state, QPSK01) | 1);
+
state->fec_inner = p->u.qpsk.fec_inner;
state->symbol_rate = p->u.qpsk.symbol_rate;
state->postlocked = 0;
state->tunedfreq = p->frequency;
+
+ dprintk("leave %s\n", __func__);
return 0;
}
@@ -717,11 +843,10 @@ static int s5h1420_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
{
struct s5h1420_state* state = fe->demodulator_priv;
- if (enable) {
- return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) | 1);
- } else {
- return s5h1420_writereg (state, 0x02, s5h1420_readreg(state,0x02) & 0xfe);
- }
+ if (enable)
+ return s5h1420_writereg(state, 0x02, state->CON_1_val | 1);
+ else
+ return s5h1420_writereg(state, 0x02, state->CON_1_val & 0xfe);
}
static int s5h1420_init (struct dvb_frontend* fe)
@@ -729,7 +854,8 @@ static int s5h1420_init (struct dvb_frontend* fe)
struct s5h1420_state* state = fe->demodulator_priv;
/* disable power down and do reset */
- s5h1420_writereg(state, 0x02, 0x10);
+ state->CON_1_val = 0x10;
+ s5h1420_writereg(state, 0x02, state->CON_1_val);
msleep(10);
s5h1420_reset(state);
@@ -739,26 +865,60 @@ static int s5h1420_init (struct dvb_frontend* fe)
static int s5h1420_sleep(struct dvb_frontend* fe)
{
struct s5h1420_state* state = fe->demodulator_priv;
-
- return s5h1420_writereg(state, 0x02, 0x12);
+ state->CON_1_val = 0x12;
+ return s5h1420_writereg(state, 0x02, state->CON_1_val);
}
static void s5h1420_release(struct dvb_frontend* fe)
{
struct s5h1420_state* state = fe->demodulator_priv;
+ i2c_del_adapter(&state->tuner_i2c_adapter);
kfree(state);
}
-static struct dvb_frontend_ops s5h1420_ops;
+static u32 s5h1420_tuner_i2c_func(struct i2c_adapter *adapter)
+{
+ return I2C_FUNC_I2C;
+}
+
+static int s5h1420_tuner_i2c_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
+{
+ struct s5h1420_state *state = i2c_get_adapdata(i2c_adap);
+ struct i2c_msg m[1 + num];
+ u8 tx_open[2] = { CON_1, state->CON_1_val | 1 }; /* repeater stops once there was a stop condition */
+
+ memset(m, 0, sizeof(struct i2c_msg) * (1 + num));
+
+ m[0].addr = state->config->demod_address;
+ m[0].buf = tx_open;
+ m[0].len = 2;
+
+ memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
-struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
- struct i2c_adapter* i2c)
+ return i2c_transfer(state->i2c, m, 1+num) == 1 + num ? num : -EIO;
+}
+
+static struct i2c_algorithm s5h1420_tuner_i2c_algo = {
+ .master_xfer = s5h1420_tuner_i2c_tuner_xfer,
+ .functionality = s5h1420_tuner_i2c_func,
+};
+
+struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe)
{
- struct s5h1420_state* state = NULL;
- u8 identity;
+ struct s5h1420_state *state = fe->demodulator_priv;
+ return &state->tuner_i2c_adapter;
+}
+EXPORT_SYMBOL(s5h1420_get_tuner_i2c_adapter);
+
+static struct dvb_frontend_ops s5h1420_ops;
+struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
+ struct i2c_adapter *i2c)
+{
/* allocate memory for the internal state */
- state = kmalloc(sizeof(struct s5h1420_state), GFP_KERNEL);
+ struct s5h1420_state *state = kzalloc(sizeof(struct s5h1420_state), GFP_KERNEL);
+ u8 i;
+
if (state == NULL)
goto error;
@@ -772,24 +932,42 @@ struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
state->symbol_rate = 0;
/* check if the demod is there + identify it */
- identity = s5h1420_readreg(state, 0x00);
- if (identity != 0x03)
+ i = s5h1420_readreg(state, ID01);
+ if (i != 0x03)
goto error;
+ memset(state->shadow, 0xff, sizeof(state->shadow));
+
+ for (i = 0; i < 0x50; i++)
+ state->shadow[i] = s5h1420_readreg(state, i);
+
/* create dvb_frontend */
memcpy(&state->frontend.ops, &s5h1420_ops, sizeof(struct dvb_frontend_ops));
state->frontend.demodulator_priv = state;
+
+ /* create tuner i2c adapter */
+ strncpy(state->tuner_i2c_adapter.name, "S5H1420-PN1010 tuner I2C bus", I2C_NAME_SIZE);
+ state->tuner_i2c_adapter.class = I2C_CLASS_TV_DIGITAL,
+ state->tuner_i2c_adapter.algo = &s5h1420_tuner_i2c_algo;
+ state->tuner_i2c_adapter.algo_data = NULL;
+ i2c_set_adapdata(&state->tuner_i2c_adapter, state);
+ if (i2c_add_adapter(&state->tuner_i2c_adapter) < 0) {
+ printk(KERN_ERR "S5H1420/PN1010: tuner i2c bus could not be initialized\n");
+ goto error;
+ }
+
return &state->frontend;
error:
kfree(state);
return NULL;
}
+EXPORT_SYMBOL(s5h1420_attach);
static struct dvb_frontend_ops s5h1420_ops = {
.info = {
- .name = "Samsung S5H1420 DVB-S",
+ .name = "Samsung S5H1420/PnpNetwork PN1010 DVB-S",
.type = FE_QPSK,
.frequency_min = 950000,
.frequency_max = 2150000,
@@ -826,10 +1004,6 @@ static struct dvb_frontend_ops s5h1420_ops = {
.set_voltage = s5h1420_set_voltage,
};
-module_param(debug, int, 0644);
-
-MODULE_DESCRIPTION("Samsung S5H1420 DVB-S Demodulator driver");
-MODULE_AUTHOR("Andrew de Quincey");
+MODULE_DESCRIPTION("Samsung S5H1420/PnpNetwork PN1010 DVB-S Demodulator driver");
+MODULE_AUTHOR("Andrew de Quincey, Patrick Boettcher");
MODULE_LICENSE("GPL");
-
-EXPORT_SYMBOL(s5h1420_attach);
diff --git a/linux/drivers/media/dvb/frontends/s5h1420.h b/linux/drivers/media/dvb/frontends/s5h1420.h
index 1555870f7..4c913f142 100644
--- a/linux/drivers/media/dvb/frontends/s5h1420.h
+++ b/linux/drivers/media/dvb/frontends/s5h1420.h
@@ -1,25 +1,26 @@
/*
- Driver for S5H1420 QPSK Demodulators
-
- Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.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.
-
-*/
-
+ * Driver for
+ * Samsung S5H1420 and
+ * PnpNetwork PN1010 QPSK Demodulator
+ *
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ * Copyright (C) 2005-8 Patrick Boettcher <pb@linuxtv.org>
+ *
+ * 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 S5H1420_H
#define S5H1420_H
@@ -31,17 +32,26 @@ struct s5h1420_config
u8 demod_address;
/* does the inversion require inversion? */
- u8 invert:1;
+ u8 invert : 1;
+
+ u8 repeated_start_workaround : 1;
+ u8 cdclk_polarity : 1; /* 1 == falling edge, 0 == raising edge */
};
#if defined(CONFIG_DVB_S5H1420) || (defined(CONFIG_DVB_S5H1420_MODULE) && defined(MODULE))
-extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
- struct i2c_adapter* i2c);
+extern struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
+ struct i2c_adapter *i2c);
+extern struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe);
#else
-static inline struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
- struct i2c_adapter* i2c)
+static inline struct dvb_frontend *s5h1420_attach(const struct s5h1420_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+
+static inline struct i2c_adapter *s5h1420_get_tuner_i2c_adapter(struct dvb_frontend *fe)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
return NULL;
}
#endif // CONFIG_DVB_S5H1420
diff --git a/linux/drivers/media/dvb/frontends/s5h1420_priv.h b/linux/drivers/media/dvb/frontends/s5h1420_priv.h
new file mode 100644
index 000000000..7962bbfb6
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/s5h1420_priv.h
@@ -0,0 +1,380 @@
+/*
+ * Driver for
+ * Samsung S5H1420 and
+ * PnpNetwork PN1010 QPSK Demodulator
+ *
+ * Copyright (C) 2005 Andrew de Quincey <adq_dvb@lidskialf.net>
+ * Copyright (C) 2005 Patrick Boettcher <pb@linuxtv.org>
+ *
+ * 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 S5H1420_PRIV
+#define S5H1420_PRIV
+
+#include <asm/types.h>
+
+enum s5h1420_register {
+ ID01 = 0x00,
+ CON_0 = 0x01,
+ CON_1 = 0x02,
+ PLL01 = 0x03,
+ PLL02 = 0x04,
+ QPSK01 = 0x05,
+ QPSK02 = 0x06,
+ Pre01 = 0x07,
+ Post01 = 0x08,
+ Loop01 = 0x09,
+ Loop02 = 0x0a,
+ Loop03 = 0x0b,
+ Loop04 = 0x0c,
+ Loop05 = 0x0d,
+ Pnco01 = 0x0e,
+ Pnco02 = 0x0f,
+ Pnco03 = 0x10,
+ Tnco01 = 0x11,
+ Tnco02 = 0x12,
+ Tnco03 = 0x13,
+ Monitor01 = 0x14,
+ Monitor02 = 0x15,
+ Monitor03 = 0x16,
+ Monitor04 = 0x17,
+ Monitor05 = 0x18,
+ Monitor06 = 0x19,
+ Monitor07 = 0x1a,
+ Monitor12 = 0x1f,
+
+ FEC01 = 0x22,
+ Soft01 = 0x23,
+ Soft02 = 0x24,
+ Soft03 = 0x25,
+ Soft04 = 0x26,
+ Soft05 = 0x27,
+ Soft06 = 0x28,
+ Vit01 = 0x29,
+ Vit02 = 0x2a,
+ Vit03 = 0x2b,
+ Vit04 = 0x2c,
+ Vit05 = 0x2d,
+ Vit06 = 0x2e,
+ Vit07 = 0x2f,
+ Vit08 = 0x30,
+ Vit09 = 0x31,
+ Vit10 = 0x32,
+ Vit11 = 0x33,
+ Vit12 = 0x34,
+ Sync01 = 0x35,
+ Sync02 = 0x36,
+ Rs01 = 0x37,
+ Mpeg01 = 0x38,
+ Mpeg02 = 0x39,
+ DiS01 = 0x3a,
+ DiS02 = 0x3b,
+ DiS03 = 0x3c,
+ DiS04 = 0x3d,
+ DiS05 = 0x3e,
+ DiS06 = 0x3f,
+ DiS07 = 0x40,
+ DiS08 = 0x41,
+ DiS09 = 0x42,
+ DiS10 = 0x43,
+ DiS11 = 0x44,
+ Rf01 = 0x45,
+ Err01 = 0x46,
+ Err02 = 0x47,
+ Err03 = 0x48,
+ Err04 = 0x49,
+};
+
+#if 0
+
+regsiter mapping follows
+
+/* ID01 */
+#define PN1010_ID 7, 0
+
+/* CON_0 */
+#define QPSK_ONLY 4, 4
+#define SOFT_RST 3, 3 /* System soft reset mode (active high) [1] Enable [0] Disable */
+#define CLK_MODE 2, 2
+#define BPSK_QPSK 1, 1
+#define DSS_DVB 0, 0 /* DSS/DVB mode selection [1] DSS [0] DVB */
+
+/* CON_1 */
+#define ADC_SPD 6, 6
+#define PLL_OEN 5, 5
+#define SER_SEL 4, 4
+#define XTAL_OEN 3, 3
+#define Q_TEST 2, 2
+#define PWR_DN 1, 1 /* Power down mode [1] Power down enable, [0] Power down disable */
+#define I2C_RPT 0, 0 /* I2C repeater control [1] I2C repeater enable, [0] I2C repeater disable.
+ * Note: The master should be set this bit to "1" in order to interface with the tuner.
+ * When the master is not communicated with the tuner, this bit should be set to "0" */
+
+/* PLL programming information
+ * Fout = ((M+8)*Fin)/((P+2)*2^S), Fin = 4 MHz */
+/* PLL01 */
+#define M 7, 0
+
+/* PLL02 */
+#define P 5, 0
+#define S 7, 6
+
+/* QPSK01 */
+#define KICK_EN 7, 7 /* [1] PLL Kicker enable [0] Disable */
+#define ROLL_OFF 6, 6
+#define SCALE_EN 5, 5
+#define DC_EN 4, 4 /* DC offset remove [1] Enable [0] Disable */
+#define VMODE 3, 3
+#define TGL_MSB 2, 2
+#define MODE_QPSK 1, 1 /* QPSK operation mode [1] 1 sampling/1 symbol [0] 2 sampling/1 symbol */
+#define Q_SRESET_N 0, 0 /* QPSK start signal [1] Start [0] Idle */
+
+/* QPSK02 */
+#define DUMP_ACC 3, 3 /* Dump phase loop filter & timing loop filter accumulator [0 and then 1]
+ * The read operation enabled, when user set DUMP_ACC "0" and then "1". */
+#define DC_WIN 2, 0 /* Window position from MSB (0 <= DC_WIN <= 7) */
+
+/* AGC Controls */
+/* Pre01 */
+#define PRE_TH 4, 0 /* PRE-AGC threshold */
+#define INV_PULSE 7, 7 /* PWM signal is reversed [1] PWM signal active low [0] PWM signal active high */
+
+/* Post01 */
+#define RRC_SCALE 7, 6
+#define POST_TH 5, 0 /* POST-AGC threshold */
+
+/* Loop Controls */
+/* Loop01 */
+#define WT_TNCO 7, 7 /* Write TNCO center frequency [0 and then 1] The write operation enabled, when user set WT_TNCO "0" and then "1" */
+#define WT_PNCO 6, 6 /* Write PNCO center frequency [0 and then 1] The write operation enabled, when user set WT_PNCO "0" and then "1" */
+
+/* Loop02 */
+#define LOOP_OUT 7, 7 /* Loop filter monitoring selection [1] Loop filter accumulator + NCO [0] Loop filter accumulator */
+#define KICK_VAL 6, 4 /* The value that gets injected into the accumulator when a "kick" is needed. */
+#define KICK_MUL 3, 0 /* The number of bits KICK_VAL is up-shifted (2^N) before it is injected into the accumulator. */
+
+/* Loop03 */
+#define IGA_PLF 7, 4 /* Phase loop, integral gain (2^IGA_PLF) in the acquisition mode */
+#define PGA_PLF 3, 0 /* Phase loop, proportional gain (2^PGA_PLF) in the acquisition mode (default +8 added) */
+
+/* Loop04 */
+#define IGT_PLF 7, 4 /* Integral gain in the tracking mode */
+#define PGT_PLF 3, 0 /* Phase loop, proportional gain in the tracking mode (default +8 added) */
+
+/* Loop 05 */
+#define IG_TLF 7, 4 /* Timing loop, integral gain */
+#define PG_TLF 3, 0 /* Timing loop, proportional gain (default +8 added) */
+
+/* NCO controls
+ * LOOP_OUT [1] Read PLF accumulator + PNCO, LOOP_OUT [0] Read PLF accumulator */
+/* Pnco01 */
+#define PNCO0 7, 0
+/* Pnco02 */
+#define PNCO1 7, 0
+/* Pnco03 */
+#define PNCO2 7, 0
+
+/* LOOP_OUT [1], Read TLF accumulator + TNCO, LOOP_OUT [0], Read TLF accumulator */
+/* Tnco01 */
+#define TNCO0 7, 0
+/* Tnco02 */
+#define TNCO1 7, 0
+/* Tnco03 */
+#define TNCO2 7, 0
+
+/* Monitor01 */
+#define A_SCL 3, 3
+#define TLOCK 1, 1 /* Timing loop lock (Symbol sync) [1] Timing loop has locked [0] Timing loop has not locked */
+#define PLOCK 0, 0 /* Phase loop lock (Carrier sync) [1] Phase loop has locked [0] Phase loop has not locked */
+
+/* Monitor02 */
+#define PRE_LEVEL 7, 0 /* PRE-AGC gain level */
+
+/* Monitor03 */
+#define POST_LEVEL 7, 0 /* POST-AGC gain level */
+
+/* Monitor04 */
+#define DC_I_LEVEL 7, 0 /* DC offset of I samples */
+
+/* Monitor05 */
+#define DC_Q_LEVEL 7, 0 /* DC offset of Q samples */
+
+/* Monitor06 */
+#define PLOCK_CNT 7, 0
+
+/* Monitor07 */
+#define TLOCK_CNT 7, 0
+
+/* Monitor12 */
+#define QPSK_OUT 6, 1 /* QPSK output monitoring */
+#define DC_FREEZE 0, 0 /* [1] Do not update DC_OFFSET */
+
+/* FEC Block */
+/* FEC01 */
+#define DERAND_BPAS 6, 6
+#define RS_BPAS 5, 5
+#define FEC_SRST_CNTL 4, 4
+#define FEC_SRESET 3, 3
+#define MPEG_CLK_INTL 2, 0
+ /* Tmp=(FMClk/FSR) x (1 / (2xCR)); FMClk: System Clock Frequency, FSR: Symbol Rate, CR: Code Rate
+ * 0: 1 < Tmp <= 2, 4: 13 < Tmp <= 17,
+ * 1: 2 < Tmp <= 5, 5: 17 < Tmp <= 25,
+ * 2: 5 < Tmp <= 9, 6: 25 < Tmp <= 33,
+ * 3: 9 < Tmp <= 13, 7: 33 < Tmp */
+
+/* Soft01 */
+#define ST_VAL_R12 2, 0
+#define STEP_R12 5, 3
+#define STEP_R23 5, 3
+#define STEP_R34 5, 3
+#define STEP_R56 5, 3
+#define STEP_R67 5, 3
+#define STEP_R78 5, 3
+/* Soft02 */
+#define ST_VAL_R23 7, 0
+/* Soft03 */
+#define ST_VAL_R34 7, 0
+/* Soft04 */
+#define ST_VAL_R56 7, 0
+/* Soft05 */
+#define ST_VAL_R67 7, 0
+/* Soft06 */
+#define ST_VAL_R78 7, 0
+
+/* Vit01 */
+#define RENORM_R12 7, 0
+/* Vit02 */
+#define RENORM_R23 7, 0
+/* Vit03 */
+#define RENORM_R34 7, 0
+/* Vit04 */
+#define RENORM_R56 7, 0
+/* Vit05 */
+#define RENORM_R67 7, 0
+/* Vit06 */
+#define RENORM_R78 7, 0
+/* Vit07 */
+#define RENORM_PRD 7, 0
+
+/* Vit08 */
+#define VIT_IN_SR78 7, 7
+#define VIT_IN_SR34 6, 6
+#define VIT_SR78 5, 5
+#define VIT_SR67 4, 4
+#define VIT_SR56 3, 3
+#define VIT_SR34 2, 2
+#define VIT_SR23 1, 1 /* .... */
+#define VIT_SR12 0, 0 /* Include CR 1/2 in search */
+
+/* Vit09 */
+#define PARM_FIX 4, 4 /* Parameter fix mode: [1] Known parameter [0] Unknown parameter */
+#define VIT_INV_SPECPARM_FIX 3, 3 /* Initial spectrum information */
+#define VIT_FR 2, 0 /* Start synchronization search at code rate as follows */
+ #define VIT_CR_12 0x00
+ #define VIT_CR_23 0x01
+ #define VIT_CR_34 0x02
+ #define VIT_CR_56 0x03
+ #define VIT_CR_67 0x04
+ #define VIT_CR_78 0x05
+
+/* Vit10 */
+#define INV_SPEC_STS 3, 3 /* Spectrum information monitoring [1] Inv spectrum [0] Not inv spectrum */
+#define VIT_CR 2, 0 /* Viterbi decoder current code rate [0] R=1/2 [1] R=2/3 [2] R=3/4 [3] R=5/6 [4] R=6/7 [5] R=7/8 */
+
+/* Vit11 */
+#define VIT_CER 7, 0
+
+/* Vit12 */
+#define RENORM_RAT 7, 0
+
+/* Sync01 */
+#define SYNC_MISS_TH 7, 4 /* Sync byte detector?s miss threshold */
+#define SYNC_HIT_TH 3, 0 /* Sync byte detector?s hit threshold This value should be greater than 2 */
+
+/* Sync02 */
+#define BYTE_SYNC 5, 5 /* [1] Acquire byte sync [0] Not acquire byte sync */
+#define SYNC_BYTE_STS 4, 2
+#define VIT_SRCH_STS 1, 1
+#define VIT_SYNC 0, 0 /* [1] Viterbi decoder is in sync [0] Viterbi decoder is out of sync */
+
+/* Rs01 */
+#define RS_ERR 3, 0
+#define PKT_ERR 4, 4
+
+/* Mpeg01 */
+#define ERR_POL 3, 3 /* Packet error polarity [1] Active low [0] Active high */
+#define SYNC_POL 2, 2 /* Sync polarity [1] Active low [0] Active high */
+#define VALID_POL 1, 1 /* Data valid polarity [1] Active low [0] Active high */
+#define CDCLK_POL 0, 0 /* CDCLK polarity [1] Falling edge event [0] Rising edge event */
+
+/* Mpeg02 */
+#define MPEG_OEN 6, 6
+#define DOUT_CONT 5, 5
+#define ERR_CONT 4, 4
+#define CLK_CONT 3, 3 /* Clock continuous mode [1] Continuous clock, [0] Clock is enable during payload data transfer */
+#define ENVELOPE 2, 2
+#define SER_PAR 1, 1 /* Serial / Parallel mode [1] Serial mode, [0] Parallel mode */
+#define DSS_SYNC 0, 0 /* DSS sync mode [1] Output sync, [0] No output sync */
+
+/* DiS01 */
+#define TONE_FREQ 7, 0 /* Tone frequency ratio ftone = fclk / (TONE_FREQ x 32) */
+
+/* DiS02 */
+#define RCV_EN 7, 7 /* DiSEqC receive enable mode [1] Receive enable [0] Receive disable */
+#define DIS_LENGTH 6, 4 /* Message length */
+#define DIS_RDY 3, 3 /* Data Transfer ready / finish [1] Ready [0] Finish */
+#define SWITCH_CON 2, 2 /* Satellite switch in tone burst mode [1] Satellite B [0] Satellite A */
+#define LNB_CON 1, 0 /* LNB control mode, [0] Continuous mode, [1] Tone burst mode, [2] DiSEqC mode, [3] Reserved */
+
+/* DiS03 */
+#define OLF_N 2, 2 /* [1] Disable [0] OLF (active low) */
+#define LNB_DN 1, 1 /* [1] LNB down [0] Disable (active high) */
+#define V18_13V 0, 0 /* 13V/18V select register (0=13V, 1=18V) */
+
+/* DiS04 .. DiS11*/
+#define LNB_MESGE0 7, 0
+#define LNB_MESGE1 7, 0
+#define LNB_MESGE2 7, 0
+#define LNB_MESGE3 7, 0
+#define LNB_MESGE4 7, 0
+#define LNB_MESGE5 7, 0
+#define LNB_MESGE6 7, 0
+#define LNB_MESGE7 7, 0
+
+/* Rf01 */
+#define SLAVE_ADDR 6, 0 /* RF tuner slave Address (SOC VERSION) */
+
+/* Err01 */
+#define ALARM_MODE 4, 4
+#define ERR_CNT_PRD 3, 2
+#define ERR_SRC 1, 0 /* Error monitoring source */
+ #define QPSK_BIT_ERRORS 0x0
+ #define VITERBI_BIT_ERRORS 0x1
+ #define VITERBI_BYTE_ERRORS 0x2
+ #define PACKET_ERRORS 0x3
+
+/* Err02 */
+#define ERR_CNT_L 7, 0 /* Error counter value register (LSB 8 bits) */
+
+/* Err03 */
+#define ERR_CNT_H 7, 0 /* Error counter value register (MSB 8 bits) */
+
+/* Err04 */
+#define PARITY_ERR 7, 0 /* Error flag for DiSEqC receive data */
+
+#endif
+
+#endif
diff --git a/linux/drivers/media/dvb/frontends/sp8870.c b/linux/drivers/media/dvb/frontends/sp8870.c
index f5b3bfc00..aa78aa14a 100644
--- a/linux/drivers/media/dvb/frontends/sp8870.c
+++ b/linux/drivers/media/dvb/frontends/sp8870.c
@@ -70,7 +70,7 @@ static int sp8870_writereg (struct sp8870_state* state, u16 reg, u16 data)
int err;
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
- dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
+ dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
return -EREMOTEIO;
}
@@ -88,7 +88,7 @@ static int sp8870_readreg (struct sp8870_state* state, u16 reg)
ret = i2c_transfer (state->i2c, msg, 2);
if (ret != 2) {
- dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
+ dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
return -1;
}
@@ -104,7 +104,7 @@ static int sp8870_firmware_upload (struct sp8870_state* state, const struct firm
int tx_len;
int err = 0;
- dprintk ("%s: ...\n", __FUNCTION__);
+ dprintk ("%s: ...\n", __func__);
if (fw->size < SP8870_FIRMWARE_SIZE + SP8870_FIRMWARE_OFFSET)
return -EINVAL;
@@ -131,14 +131,14 @@ static int sp8870_firmware_upload (struct sp8870_state* state, const struct firm
msg.buf = tx_buf;
msg.len = tx_len + 2;
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
- printk("%s: firmware upload failed!\n", __FUNCTION__);
- printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
+ printk("%s: firmware upload failed!\n", __func__);
+ printk ("%s: i2c error (err == %i)\n", __func__, err);
return err;
}
fw_pos += tx_len;
}
- dprintk ("%s: done!\n", __FUNCTION__);
+ dprintk ("%s: done!\n", __func__);
return 0;
};
@@ -310,7 +310,7 @@ static int sp8870_init (struct dvb_frontend* fe)
if (state->initialised) return 0;
state->initialised = 1;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
/* request the firmware, this will block until someone uploads it */
@@ -475,7 +475,7 @@ static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_par
int trials = 0;
int check_count = 0;
- dprintk("%s: frequency = %i\n", __FUNCTION__, p->frequency);
+ dprintk("%s: frequency = %i\n", __func__, p->frequency);
for (trials = 1; trials <= MAXTRIALS; trials++) {
@@ -487,7 +487,7 @@ static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_par
valid = sp8870_read_data_valid_signal(state);
if (valid) {
dprintk("%s: delay = %i usec\n",
- __FUNCTION__, check_count * 10);
+ __func__, check_count * 10);
break;
}
udelay(10);
@@ -497,20 +497,20 @@ static int sp8870_set_frontend (struct dvb_frontend* fe, struct dvb_frontend_par
}
if (!valid) {
- printk("%s: firmware crash!!!!!!\n", __FUNCTION__);
+ printk("%s: firmware crash!!!!!!\n", __func__);
return -EIO;
}
if (debug) {
if (valid) {
if (trials > 1) {
- printk("%s: firmware lockup!!!\n", __FUNCTION__);
- printk("%s: recovered after %i trial(s))\n", __FUNCTION__, trials - 1);
+ printk("%s: firmware lockup!!!\n", __func__);
+ printk("%s: recovered after %i trial(s))\n", __func__, trials - 1);
lockups++;
}
}
switches++;
- printk("%s: switches = %i lockups = %i\n", __FUNCTION__, switches, lockups);
+ printk("%s: switches = %i lockups = %i\n", __func__, switches, lockups);
}
return 0;
diff --git a/linux/drivers/media/dvb/frontends/sp8870.h b/linux/drivers/media/dvb/frontends/sp8870.h
index 909cefe71..a764a793c 100644
--- a/linux/drivers/media/dvb/frontends/sp8870.h
+++ b/linux/drivers/media/dvb/frontends/sp8870.h
@@ -42,7 +42,7 @@ extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
static inline struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_SP8870
diff --git a/linux/drivers/media/dvb/frontends/sp887x.c b/linux/drivers/media/dvb/frontends/sp887x.c
index 1aa2539f5..49f55877f 100644
--- a/linux/drivers/media/dvb/frontends/sp887x.c
+++ b/linux/drivers/media/dvb/frontends/sp887x.c
@@ -43,7 +43,7 @@ static int i2c_writebytes (struct sp887x_state* state, u8 *buf, u8 len)
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
printk ("%s: i2c write error (addr %02x, err == %i)\n",
- __FUNCTION__, state->config->demod_address, err);
+ __func__, state->config->demod_address, err);
return -EREMOTEIO;
}
@@ -65,7 +65,7 @@ static int sp887x_writereg (struct sp887x_state* state, u16 reg, u16 data)
{
printk("%s: writereg error "
"(reg %03x, data %03x, ret == %i)\n",
- __FUNCTION__, reg & 0xffff, data & 0xffff, ret);
+ __func__, reg & 0xffff, data & 0xffff, ret);
return ret;
}
}
@@ -82,7 +82,7 @@ static int sp887x_readreg (struct sp887x_state* state, u16 reg)
{ .addr = state->config->demod_address, .flags = I2C_M_RD, .buf = b1, .len = 2 }};
if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
- printk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
+ printk("%s: readreg error (ret == %i)\n", __func__, ret);
return -1;
}
@@ -91,7 +91,7 @@ static int sp887x_readreg (struct sp887x_state* state, u16 reg)
static void sp887x_microcontroller_stop (struct sp887x_state* state)
{
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
sp887x_writereg(state, 0xf08, 0x000);
sp887x_writereg(state, 0xf09, 0x000);
@@ -101,7 +101,7 @@ static void sp887x_microcontroller_stop (struct sp887x_state* state)
static void sp887x_microcontroller_start (struct sp887x_state* state)
{
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
sp887x_writereg(state, 0xf08, 0x000);
sp887x_writereg(state, 0xf09, 0x000);
@@ -112,7 +112,7 @@ static void sp887x_microcontroller_start (struct sp887x_state* state)
static void sp887x_setup_agc (struct sp887x_state* state)
{
/* setup AGC parameters */
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
sp887x_writereg(state, 0x33c, 0x054);
sp887x_writereg(state, 0x33b, 0x04c);
sp887x_writereg(state, 0x328, 0x000);
@@ -142,7 +142,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware
int fw_size = fw->size;
unsigned char *mem = fw->data;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
/* ignore the first 10 bytes, then we expect 0x4000 bytes of firmware */
if (fw_size < FW_SIZE+10)
@@ -155,7 +155,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware
sp887x_microcontroller_stop (state);
- printk ("%s: firmware upload... ", __FUNCTION__);
+ printk ("%s: firmware upload... ", __func__);
/* setup write pointer to -1 (end of memory) */
/* bit 0x8000 in address is set to enable 13bit mode */
@@ -181,7 +181,7 @@ static int sp887x_initial_setup (struct dvb_frontend* fe, const struct firmware
if ((err = i2c_writebytes (state, buf, c+2)) < 0) {
printk ("failed.\n");
- printk ("%s: i2c error (err == %i)\n", __FUNCTION__, err);
+ printk ("%s: i2c error (err == %i)\n", __func__, err);
return err;
}
}
diff --git a/linux/drivers/media/dvb/frontends/sp887x.h b/linux/drivers/media/dvb/frontends/sp887x.h
index 7ee78d7d9..04eff6e0e 100644
--- a/linux/drivers/media/dvb/frontends/sp887x.h
+++ b/linux/drivers/media/dvb/frontends/sp887x.h
@@ -24,7 +24,7 @@ extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
static inline struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_SP887X
diff --git a/linux/drivers/media/dvb/frontends/stv0297.c b/linux/drivers/media/dvb/frontends/stv0297.c
index cd8f74b57..1c5a0ae82 100644
--- a/linux/drivers/media/dvb/frontends/stv0297.c
+++ b/linux/drivers/media/dvb/frontends/stv0297.c
@@ -58,7 +58,7 @@ static int stv0297_writereg(struct stv0297_state *state, u8 reg, u8 data)
if (ret != 1)
dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
- "ret == %i)\n", __FUNCTION__, reg, data, ret);
+ "ret == %i)\n", __func__, reg, data, ret);
return (ret != 1) ? -1 : 0;
}
@@ -75,16 +75,16 @@ static int stv0297_readreg(struct stv0297_state *state, u8 reg)
// this device needs a STOP between the register and data
if (state->config->stop_during_read) {
if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
- dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
+ dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
return -1;
}
if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
- dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
+ dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
return -1;
}
} else {
if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
- dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg, ret);
+ dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg, ret);
return -1;
}
}
@@ -115,16 +115,16 @@ static int stv0297_readregs(struct stv0297_state *state, u8 reg1, u8 * b, u8 len
// this device needs a STOP between the register and data
if (state->config->stop_during_read) {
if ((ret = i2c_transfer(state->i2c, &msg[0], 1)) != 1) {
- dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
+ dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
return -1;
}
if ((ret = i2c_transfer(state->i2c, &msg[1], 1)) != 1) {
- dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
+ dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
return -1;
}
} else {
if ((ret = i2c_transfer(state->i2c, msg, 2)) != 2) {
- dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __FUNCTION__, reg1, ret);
+ dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n", __func__, reg1, ret);
return -1;
}
}
diff --git a/linux/drivers/media/dvb/frontends/stv0297.h b/linux/drivers/media/dvb/frontends/stv0297.h
index 69f4515df..3f8f9468f 100644
--- a/linux/drivers/media/dvb/frontends/stv0297.h
+++ b/linux/drivers/media/dvb/frontends/stv0297.h
@@ -49,7 +49,7 @@ extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
static inline struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_STV0297
diff --git a/linux/drivers/media/dvb/frontends/stv0299.c b/linux/drivers/media/dvb/frontends/stv0299.c
index 035dd7ba6..17556183e 100644
--- a/linux/drivers/media/dvb/frontends/stv0299.c
+++ b/linux/drivers/media/dvb/frontends/stv0299.c
@@ -86,7 +86,7 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
if (ret != 1)
dprintk("%s: writereg error (reg == 0x%02x, val == 0x%02x, "
- "ret == %i)\n", __FUNCTION__, reg, data, ret);
+ "ret == %i)\n", __func__, reg, data, ret);
return (ret != 1) ? -EREMOTEIO : 0;
}
@@ -113,7 +113,7 @@ static u8 stv0299_readreg (struct stv0299_state* state, u8 reg)
if (ret != 2)
dprintk("%s: readreg error (reg == 0x%02x, ret == %i)\n",
- __FUNCTION__, reg, ret);
+ __func__, reg, ret);
return b1[0];
}
@@ -127,14 +127,14 @@ static int stv0299_readregs (struct stv0299_state* state, u8 reg1, u8 *b, u8 len
ret = i2c_transfer (state->i2c, msg, 2);
if (ret != 2)
- dprintk("%s: readreg error (ret == %i)\n", __FUNCTION__, ret);
+ dprintk("%s: readreg error (ret == %i)\n", __func__, ret);
return ret == 2 ? 0 : ret;
}
static int stv0299_set_FEC (struct stv0299_state* state, fe_code_rate_t fec)
{
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
switch (fec) {
case FEC_AUTO:
@@ -174,7 +174,7 @@ static fe_code_rate_t stv0299_get_fec (struct stv0299_state* state)
FEC_7_8, FEC_1_2 };
u8 index;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
index = stv0299_readreg (state, 0x1b);
index &= 0x7;
@@ -189,11 +189,11 @@ static int stv0299_wait_diseqc_fifo (struct stv0299_state* state, int timeout)
{
unsigned long start = jiffies;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
while (stv0299_readreg(state, 0x0a) & 1) {
if (jiffies - start > timeout) {
- dprintk ("%s: timeout!!\n", __FUNCTION__);
+ dprintk ("%s: timeout!!\n", __func__);
return -ETIMEDOUT;
}
msleep(10);
@@ -206,11 +206,11 @@ static int stv0299_wait_diseqc_idle (struct stv0299_state* state, int timeout)
{
unsigned long start = jiffies;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
while ((stv0299_readreg(state, 0x0a) & 3) != 2 ) {
if (jiffies - start > timeout) {
- dprintk ("%s: timeout!!\n", __FUNCTION__);
+ dprintk ("%s: timeout!!\n", __func__);
return -ETIMEDOUT;
}
msleep(10);
@@ -245,7 +245,7 @@ static int stv0299_get_symbolrate (struct stv0299_state* state)
u8 sfr[3];
s8 rtf;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
stv0299_readregs (state, 0x1f, sfr, 3);
stv0299_readregs (state, 0x1a, (u8 *)&rtf, 1);
@@ -257,8 +257,8 @@ static int stv0299_get_symbolrate (struct stv0299_state* state)
offset = (s32) rtf * (srate / 4096L);
offset /= 128;
- dprintk ("%s : srate = %i\n", __FUNCTION__, srate);
- dprintk ("%s : ofset = %i\n", __FUNCTION__, offset);
+ dprintk ("%s : srate = %i\n", __func__, srate);
+ dprintk ("%s : ofset = %i\n", __func__, offset);
srate += offset;
@@ -276,7 +276,7 @@ static int stv0299_send_diseqc_msg (struct dvb_frontend* fe,
u8 val;
int i;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
if (stv0299_wait_diseqc_idle (state, 100) < 0)
return -ETIMEDOUT;
@@ -305,7 +305,7 @@ static int stv0299_send_diseqc_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t
struct stv0299_state* state = fe->demodulator_priv;
u8 val;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
if (stv0299_wait_diseqc_idle (state, 100) < 0)
return -ETIMEDOUT;
@@ -355,7 +355,7 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
u8 reg0x08;
u8 reg0x0c;
- dprintk("%s: %s\n", __FUNCTION__,
+ dprintk("%s: %s\n", __func__,
voltage == SEC_VOLTAGE_13 ? "SEC_VOLTAGE_13" :
voltage == SEC_VOLTAGE_18 ? "SEC_VOLTAGE_18" : "??");
@@ -366,26 +366,32 @@ static int stv0299_set_voltage (struct dvb_frontend* fe, fe_sec_voltage_t voltag
* H/V switching over OP0, OP1 and OP2 are LNB power enable bits
*/
reg0x0c &= 0x0f;
-
- if (voltage == SEC_VOLTAGE_OFF) {
- stv0299_writeregI (state, 0x0c, 0x00); /* LNB power off! */
- return stv0299_writeregI (state, 0x08, 0x00); /* LNB power off! */
- }
-
- stv0299_writeregI (state, 0x08, (reg0x08 & 0x3f) | (state->config->lock_output << 6));
+ reg0x08 = (reg0x08 & 0x3f) | (state->config->lock_output << 6);
switch (voltage) {
case SEC_VOLTAGE_13:
- if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0) reg0x0c |= 0x10;
- else reg0x0c |= 0x40;
-
- return stv0299_writeregI(state, 0x0c, reg0x0c);
-
+ if (state->config->volt13_op0_op1 == STV0299_VOLT13_OP0)
+ reg0x0c |= 0x10; /* OP1 off, OP0 on */
+ else
+ reg0x0c |= 0x40; /* OP1 on, OP0 off */
+ break;
case SEC_VOLTAGE_18:
- return stv0299_writeregI(state, 0x0c, reg0x0c | 0x50);
+ reg0x0c |= 0x50; /* OP1 on, OP0 on */
+ break;
+ case SEC_VOLTAGE_OFF:
+ /* LNB power off! */
+ reg0x08 = 0x00;
+ reg0x0c = 0x00;
+ break;
default:
return -EINVAL;
};
+
+ if (state->config->op0_off)
+ reg0x0c &= ~0x10;
+
+ stv0299_writeregI(state, 0x08, reg0x08);
+ return stv0299_writeregI(state, 0x0c, reg0x0c);
}
static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long cmd)
@@ -408,7 +414,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
cmd = cmd << 1;
if (debug_legacy_dish_switch)
- printk ("%s switch command: 0x%04lx\n",__FUNCTION__, cmd);
+ printk ("%s switch command: 0x%04lx\n",__func__, cmd);
do_gettimeofday (&nexttime);
if (debug_legacy_dish_switch)
@@ -433,7 +439,7 @@ static int stv0299_send_legacy_dish_cmd (struct dvb_frontend* fe, unsigned long
}
if (debug_legacy_dish_switch) {
printk ("%s(%d): switch delay (should be 32k followed by all 8k\n",
- __FUNCTION__, fe->dvb->num);
+ __func__, fe->dvb->num);
for (i = 1; i < 10; i++)
printk ("%d: %d\n", i, timeval_usec_diff(tv[i-1] , tv[i]));
}
@@ -445,11 +451,20 @@ static int stv0299_init (struct dvb_frontend* fe)
{
struct stv0299_state* state = fe->demodulator_priv;
int i;
+ u8 reg;
+ u8 val;
dprintk("stv0299: init chip\n");
- for (i=0; !(state->config->inittab[i] == 0xff && state->config->inittab[i+1] == 0xff); i+=2)
- stv0299_writeregI(state, state->config->inittab[i], state->config->inittab[i+1]);
+ for (i = 0; ; i += 2) {
+ reg = state->config->inittab[i];
+ val = state->config->inittab[i+1];
+ if (reg == 0xff && val == 0xff)
+ break;
+ if (reg == 0x0c && state->config->op0_off)
+ val &= ~0x10;
+ stv0299_writeregI(state, reg, val);
+ }
return 0;
}
@@ -461,7 +476,7 @@ static int stv0299_read_status(struct dvb_frontend* fe, fe_status_t* status)
u8 signal = 0xff - stv0299_readreg (state, 0x18);
u8 sync = stv0299_readreg (state, 0x1b);
- dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __FUNCTION__, sync);
+ dprintk ("%s : FE_READ_STATUS : VSTATUS: 0x%02x\n", __func__, sync);
*status = 0;
if (signal > 10)
@@ -499,7 +514,7 @@ static int stv0299_read_signal_strength(struct dvb_frontend* fe, u16* strength)
s32 signal = 0xffff - ((stv0299_readreg (state, 0x18) << 8)
| stv0299_readreg (state, 0x19));
- dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __FUNCTION__,
+ dprintk ("%s : FE_READ_SIGNAL_STRENGTH : AGC2I: 0x%02x%02x, signal=0x%04x\n", __func__,
stv0299_readreg (state, 0x18),
stv0299_readreg (state, 0x19), (int) signal);
@@ -536,7 +551,7 @@ static int stv0299_set_frontend(struct dvb_frontend* fe, struct dvb_frontend_par
struct stv0299_state* state = fe->demodulator_priv;
int invval = 0;
- dprintk ("%s : FE_SET_FRONTEND\n", __FUNCTION__);
+ dprintk ("%s : FE_SET_FRONTEND\n", __func__);
// set the inversion
if (p->inversion == INVERSION_OFF) invval = 0;
diff --git a/linux/drivers/media/dvb/frontends/stv0299.h b/linux/drivers/media/dvb/frontends/stv0299.h
index 33df94959..3282f4302 100644
--- a/linux/drivers/media/dvb/frontends/stv0299.h
+++ b/linux/drivers/media/dvb/frontends/stv0299.h
@@ -48,10 +48,10 @@
#include <linux/dvb/frontend.h>
#include "dvb_frontend.h"
-#define STV0229_LOCKOUTPUT_0 0
-#define STV0229_LOCKOUTPUT_1 1
-#define STV0229_LOCKOUTPUT_CF 2
-#define STV0229_LOCKOUTPUT_LK 3
+#define STV0299_LOCKOUTPUT_0 0
+#define STV0299_LOCKOUTPUT_1 1
+#define STV0299_LOCKOUTPUT_CF 2
+#define STV0299_LOCKOUTPUT_LK 3
#define STV0299_VOLT13_OP0 0
#define STV0299_VOLT13_OP1 1
@@ -82,6 +82,9 @@ struct stv0299_config
/* Is 13v controlled by OP0 or OP1? */
u8 volt13_op0_op1:1;
+ /* Turn-off OP0? */
+ u8 op0_off:1;
+
/* minimum delay before retuning */
int min_delay_ms;
@@ -96,7 +99,7 @@ extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
static inline struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_STV0299
diff --git a/linux/drivers/media/dvb/frontends/tda10021.c b/linux/drivers/media/dvb/frontends/tda10021.c
index 68a1103c9..c6f90f33a 100644
--- a/linux/drivers/media/dvb/frontends/tda10021.c
+++ b/linux/drivers/media/dvb/frontends/tda10021.c
@@ -79,7 +79,7 @@ static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
if (ret != 1)
printk("DVB: TDA10021(%d): %s, writereg error "
"(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
- state->frontend.dvb->num, __FUNCTION__, reg, data, ret);
+ state->frontend.dvb->num, __func__, reg, data, ret);
msleep(10);
return (ret != 1) ? -EREMOTEIO : 0;
@@ -97,7 +97,7 @@ static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
// 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);
+ __func__, ret);
return b1[0];
}
diff --git a/linux/drivers/media/dvb/frontends/tda10023.c b/linux/drivers/media/dvb/frontends/tda10023.c
index b565bc2d7..82d6cb5b8 100644
--- a/linux/drivers/media/dvb/frontends/tda10023.c
+++ b/linux/drivers/media/dvb/frontends/tda10023.c
@@ -38,17 +38,24 @@
#include "dvb_frontend.h"
#include "tda1002x.h"
+#define REG0_INIT_VAL 0x23
struct tda10023_state {
struct i2c_adapter* i2c;
/* configuration settings */
- const struct tda1002x_config* config;
+ const struct tda10023_config *config;
struct dvb_frontend frontend;
u8 pwm;
u8 reg0;
-};
+ /* clock settings */
+ u32 xtal;
+ u8 pll_m;
+ u8 pll_p;
+ u8 pll_n;
+ u32 sysclk;
+};
#if 0
#define dprintk(x...) printk(x)
@@ -58,59 +65,6 @@ struct tda10023_state {
static int verbose;
-#define XTAL 28920000UL
-#define PLL_M 8UL
-#define PLL_P 4UL
-#define PLL_N 1UL
-#define SYSCLK (XTAL*PLL_M/(PLL_N*PLL_P)) // -> 57840000
-
-static u8 tda10023_inittab[]={
- // reg mask val
- 0x2a,0xff,0x02, // PLL3, Bypass, Power Down
- 0xff,0x64,0x00, // Sleep 100ms
- 0x2a,0xff,0x03, // PLL3, Bypass, Power Down
- 0xff,0x64,0x00, // Sleep 100ms
- 0x28,0xff,PLL_M-1, // PLL1 M=8
- 0x29,0xff,((PLL_P-1)<<6)|(PLL_N-1), // PLL2
- 0x00,0xff,0x23, // GPR FSAMPLING=1
- 0x2a,0xff,0x08, // PLL3 PSACLK=1
- 0xff,0x64,0x00, // Sleep 100ms
- 0x1f,0xff,0x00, // RESET
- 0xff,0x64,0x00, // Sleep 100ms
- 0xe6,0x0c,0x04, // RSCFG_IND
- 0x10,0xc0,0x80, // DECDVBCFG1 PBER=1
-
- 0x0e,0xff,0x82, // GAIN1
- 0x03,0x08,0x08, // CLKCONF DYN=1
- 0x2e,0xbf,0x30, // AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1 PPWMTUN=0 PPWMIF=0
- 0x01,0xff,0x30, // AGCREF
- 0x1e,0x84,0x84, // CONTROL SACLK_ON=1
- 0x1b,0xff,0xc8, // ADC TWOS=1
- 0x3b,0xff,0xff, // IFMAX
- 0x3c,0xff,0x00, // IFMIN
- 0x34,0xff,0x00, // PWMREF
- 0x35,0xff,0xff, // TUNMAX
- 0x36,0xff,0x00, // TUNMIN
- 0x06,0xff,0x7f, // EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 // 0x77
- 0x1c,0x30,0x30, // EQCONF2 STEPALGO=SGNALGO=1
- 0x37,0xff,0xf6, // DELTAF_LSB
- 0x38,0xff,0xff, // DELTAF_MSB
- 0x02,0xff,0x93, // AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3
- 0x2d,0xff,0xf6, // SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2
- 0x04,0x10,0x00, // SWRAMP=1
- 0x12,0xff,0xa1, // INTP1 POCLKP=1 FEL=1 MFS=0
- 0x2b,0x01,0xa1, // INTS1
- 0x20,0xff,0x04, // INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=?
- 0x2c,0xff,0x0d, // INTP/S TRIP=0 TRIS=0
- 0xc4,0xff,0x00,
- 0xc3,0x30,0x00,
- 0xb5,0xff,0x19, // ERAGC_THD
- 0x00,0x03,0x01, // GPR, CLBS soft reset
- 0x00,0x03,0x03, // GPR, CLBS soft reset
- 0xff,0x64,0x00, // Sleep 100ms
- 0xff,0xff,0xff
-};
-
static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
{
u8 b0 [] = { reg };
@@ -122,7 +76,7 @@ static u8 tda10023_readreg (struct tda10023_state* state, u8 reg)
ret = i2c_transfer (state->i2c, msg, 2);
if (ret != 2)
printk("DVB: TDA10023: %s: readreg error (ret == %i)\n",
- __FUNCTION__, ret);
+ __func__, ret);
return b1[0];
}
@@ -136,7 +90,7 @@ static int tda10023_writereg (struct tda10023_state* state, u8 reg, u8 data)
if (ret != 1)
printk("DVB: TDA10023(%d): %s, writereg error "
"(reg == 0x%02x, val == 0x%02x, ret == %i)\n",
- state->frontend.dvb->num, __FUNCTION__, reg, data, ret);
+ state->frontend.dvb->num, __func__, reg, data, ret);
return (ret != 1) ? -EREMOTEIO : 0;
}
@@ -219,30 +173,34 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
s16 SFIL=0;
u16 NDEC = 0;
- if (sr < (u32)(SYSCLK/98.40)) {
+ /* avoid floating point operations multiplying syscloc and divider
+ by 10 */
+ u32 sysclk_x_10 = state->sysclk * 10;
+
+ if (sr < (u32)(sysclk_x_10/984)) {
NDEC=3;
SFIL=1;
- } else if (sr<(u32)(SYSCLK/64.0)) {
+ } else if (sr < (u32)(sysclk_x_10/640)) {
NDEC=3;
SFIL=0;
- } else if (sr<(u32)(SYSCLK/49.2)) {
+ } else if (sr < (u32)(sysclk_x_10/492)) {
NDEC=2;
SFIL=1;
- } else if (sr<(u32)(SYSCLK/32.0)) {
+ } else if (sr < (u32)(sysclk_x_10/320)) {
NDEC=2;
SFIL=0;
- } else if (sr<(u32)(SYSCLK/24.6)) {
+ } else if (sr < (u32)(sysclk_x_10/246)) {
NDEC=1;
SFIL=1;
- } else if (sr<(u32)(SYSCLK/16.0)) {
+ } else if (sr < (u32)(sysclk_x_10/160)) {
NDEC=1;
SFIL=0;
- } else if (sr<(u32)(SYSCLK/12.3)) {
+ } else if (sr < (u32)(sysclk_x_10/123)) {
NDEC=0;
SFIL=1;
}
- BDRI=SYSCLK*16;
+ BDRI = (state->sysclk)*16;
BDRI>>=NDEC;
BDRI +=sr/2;
BDRI /=sr;
@@ -255,11 +213,12 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
BDRX=1<<(24+NDEC);
BDRX*=sr;
- do_div(BDRX,SYSCLK); // BDRX/=SYSCLK;
+ do_div(BDRX, state->sysclk); /* BDRX/=SYSCLK; */
BDR=(s32)BDRX;
}
-// printk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",sr,BDR,BDRI,NDEC);
+ dprintk("Symbolrate %i, BDR %i BDRI %i, NDEC %i\n",
+ sr, BDR, BDRI, NDEC);
tda10023_writebit (state, 0x03, 0xc0, NDEC<<6);
tda10023_writereg (state, 0x0a, BDR&255);
tda10023_writereg (state, 0x0b, (BDR>>8)&255);
@@ -272,8 +231,63 @@ static int tda10023_set_symbolrate (struct tda10023_state* state, u32 sr)
static int tda10023_init (struct dvb_frontend *fe)
{
struct tda10023_state* state = fe->demodulator_priv;
+ u8 tda10023_inittab[] = {
+/* reg mask val */
+/* 000 */ 0x2a, 0xff, 0x02, /* PLL3, Bypass, Power Down */
+/* 003 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
+/* 006 */ 0x2a, 0xff, 0x03, /* PLL3, Bypass, Power Down */
+/* 009 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
+ /* PLL1 */
+/* 012 */ 0x28, 0xff, (state->pll_m-1),
+ /* PLL2 */
+/* 015 */ 0x29, 0xff, ((state->pll_p-1)<<6)|(state->pll_n-1),
+ /* GPR FSAMPLING=1 */
+/* 018 */ 0x00, 0xff, REG0_INIT_VAL,
+/* 021 */ 0x2a, 0xff, 0x08, /* PLL3 PSACLK=1 */
+/* 024 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
+/* 027 */ 0x1f, 0xff, 0x00, /* RESET */
+/* 030 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
+/* 033 */ 0xe6, 0x0c, 0x04, /* RSCFG_IND */
+/* 036 */ 0x10, 0xc0, 0x80, /* DECDVBCFG1 PBER=1 */
+
+/* 039 */ 0x0e, 0xff, 0x82, /* GAIN1 */
+/* 042 */ 0x03, 0x08, 0x08, /* CLKCONF DYN=1 */
+/* 045 */ 0x2e, 0xbf, 0x30, /* AGCCONF2 TRIAGC=0,POSAGC=ENAGCIF=1
+ PPWMTUN=0 PPWMIF=0 */
+/* 048 */ 0x01, 0xff, 0x30, /* AGCREF */
+/* 051 */ 0x1e, 0x84, 0x84, /* CONTROL SACLK_ON=1 */
+/* 054 */ 0x1b, 0xff, 0xc8, /* ADC TWOS=1 */
+/* 057 */ 0x3b, 0xff, 0xff, /* IFMAX */
+/* 060 */ 0x3c, 0xff, 0x00, /* IFMIN */
+/* 063 */ 0x34, 0xff, 0x00, /* PWMREF */
+/* 066 */ 0x35, 0xff, 0xff, /* TUNMAX */
+/* 069 */ 0x36, 0xff, 0x00, /* TUNMIN */
+/* 072 */ 0x06, 0xff, 0x7f, /* EQCONF1 POSI=7 ENADAPT=ENEQUAL=DFE=1 */
+/* 075 */ 0x1c, 0x30, 0x30, /* EQCONF2 STEPALGO=SGNALGO=1 */
+/* 078 */ 0x37, 0xff, 0xf6, /* DELTAF_LSB */
+/* 081 */ 0x38, 0xff, 0xff, /* DELTAF_MSB */
+/* 084 */ 0x02, 0xff, 0x93, /* AGCCONF1 IFS=1 KAGCIF=2 KAGCTUN=3 */
+/* 087 */ 0x2d, 0xff, 0xf6, /* SWEEP SWPOS=1 SWDYN=7 SWSTEP=1 SWLEN=2 */
+/* 090 */ 0x04, 0x10, 0x00, /* SWRAMP=1 */
+/* 093 */ 0x12, 0xff, 0xa1, /* INTP1 POCLKP=1 FEL=1 MFS=0 */
+/* 096 */ 0x2b, 0x01, 0xa1, /* INTS1 */
+/* 099 */ 0x20, 0xff, 0x04, /* INTP2 SWAPP=? MSBFIRSTP=? INTPSEL=? */
+/* 102 */ 0x2c, 0xff, 0x0d, /* INTP/S TRIP=0 TRIS=0 */
+/* 105 */ 0xc4, 0xff, 0x00,
+/* 108 */ 0xc3, 0x30, 0x00,
+/* 111 */ 0xb5, 0xff, 0x19, /* ERAGC_THD */
+/* 114 */ 0x00, 0x03, 0x01, /* GPR, CLBS soft reset */
+/* 117 */ 0x00, 0x03, 0x03, /* GPR, CLBS soft reset */
+/* 120 */ 0xff, 0x64, 0x00, /* Sleep 100ms */
+/* 123 */ 0xff, 0xff, 0xff
+};
+ dprintk("DVB: TDA10023(%d): init chip\n", fe->dvb->num);
- dprintk("DVB: TDA10023(%d): init chip\n", fe->adapter->num);
+ /* override default values if set in config */
+ if (state->config->deltaf) {
+ tda10023_inittab[80] = (state->config->deltaf & 0xff);
+ tda10023_inittab[83] = (state->config->deltaf >> 8);
+ }
tda10023_writetab(state, tda10023_inittab);
@@ -460,12 +474,11 @@ static void tda10023_release(struct dvb_frontend* fe)
static struct dvb_frontend_ops tda10023_ops;
-struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
- struct i2c_adapter* i2c,
+struct dvb_frontend *tda10023_attach(const struct tda10023_config *config,
+ struct i2c_adapter *i2c,
u8 pwm)
{
struct tda10023_state* state = NULL;
- int i;
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct tda10023_state), GFP_KERNEL);
@@ -474,22 +487,40 @@ struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
/* setup the state */
state->config = config;
state->i2c = i2c;
- memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
- state->pwm = pwm;
- for (i=0; i < ARRAY_SIZE(tda10023_inittab);i+=3) {
- if (tda10023_inittab[i] == 0x00) {
- state->reg0 = tda10023_inittab[i+2];
- break;
- }
- }
- // Wakeup if in standby
+ /* wakeup if in standby */
tda10023_writereg (state, 0x00, 0x33);
/* check if the demod is there */
if ((tda10023_readreg(state, 0x1a) & 0xf0) != 0x70) goto error;
/* create dvb_frontend */
memcpy(&state->frontend.ops, &tda10023_ops, sizeof(struct dvb_frontend_ops));
+ state->pwm = pwm;
+ state->reg0 = REG0_INIT_VAL;
+ if (state->config->xtal) {
+ state->xtal = state->config->xtal;
+ state->pll_m = state->config->pll_m;
+ state->pll_p = state->config->pll_p;
+ state->pll_n = state->config->pll_n;
+ } else {
+ /* set default values if not defined in config */
+ state->xtal = 28920000;
+ state->pll_m = 8;
+ state->pll_p = 4;
+ state->pll_n = 1;
+ }
+
+ /* calc sysclk */
+ state->sysclk = (state->xtal * state->pll_m / \
+ (state->pll_n * state->pll_p));
+
+ state->frontend.ops.info.symbol_rate_min = (state->sysclk/2)/64;
+ state->frontend.ops.info.symbol_rate_max = (state->sysclk/2)/4;
+
+ dprintk("DVB: TDA10023 %s: xtal:%d pll_m:%d pll_p:%d pll_n:%d\n",
+ __func__, state->xtal, state->pll_m, state->pll_p,
+ state->pll_n);
+
state->frontend.demodulator_priv = state;
return &state->frontend;
@@ -504,10 +535,10 @@ static struct dvb_frontend_ops tda10023_ops = {
.name = "Philips TDA10023 DVB-C",
.type = FE_QAM,
.frequency_stepsize = 62500,
- .frequency_min = 47000000,
+ .frequency_min = 47000000,
.frequency_max = 862000000,
- .symbol_rate_min = (SYSCLK/2)/64, /* SACLK/64 == (SYSCLK/2)/64 */
- .symbol_rate_max = (SYSCLK/2)/4, /* SACLK/4 */
+ .symbol_rate_min = 0, /* set in tda10023_attach */
+ .symbol_rate_max = 0, /* set in tda10023_attach */
#if 0
.frequency_tolerance = ???,
.symbol_rate_tolerance = ???, /* ppm */ /* == 8% (spec p. 5) */
diff --git a/linux/drivers/media/dvb/frontends/tda1002x.h b/linux/drivers/media/dvb/frontends/tda1002x.h
index e9094d812..4522b7ef5 100644
--- a/linux/drivers/media/dvb/frontends/tda1002x.h
+++ b/linux/drivers/media/dvb/frontends/tda1002x.h
@@ -26,11 +26,25 @@
#include <linux/dvb/frontend.h>
-struct tda1002x_config
-{
+struct tda1002x_config {
+ /* the demodulator's i2c address */
+ u8 demod_address;
+ u8 invert;
+};
+
+struct tda10023_config {
/* the demodulator's i2c address */
u8 demod_address;
u8 invert;
+
+ /* clock settings */
+ u32 xtal; /* defaults: 28920000 */
+ u8 pll_m; /* defaults: 8 */
+ u8 pll_p; /* defaults: 4 */
+ u8 pll_n; /* defaults: 1 */
+
+ /* input freq offset + baseband conversion type */
+ u16 deltaf;
};
#if defined(CONFIG_DVB_TDA10021) || (defined(CONFIG_DVB_TDA10021_MODULE) && defined(MODULE))
@@ -40,19 +54,22 @@ extern struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config
static inline struct dvb_frontend* tda10021_attach(const struct tda1002x_config* config,
struct i2c_adapter* i2c, u8 pwm)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_TDA10021
-#if defined(CONFIG_DVB_TDA10023) || (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
- struct i2c_adapter* i2c, u8 pwm);
+#if defined(CONFIG_DVB_TDA10023) || \
+ (defined(CONFIG_DVB_TDA10023_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda10023_attach(
+ const struct tda10023_config *config,
+ struct i2c_adapter *i2c, u8 pwm);
#else
-static inline struct dvb_frontend* tda10023_attach(const struct tda1002x_config* config,
- struct i2c_adapter* i2c, u8 pwm)
+static inline struct dvb_frontend *tda10023_attach(
+ const struct tda1002x_config *config,
+ struct i2c_adapter *i2c, u8 pwm)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_TDA10023
diff --git a/linux/drivers/media/dvb/frontends/tda10048.c b/linux/drivers/media/dvb/frontends/tda10048.c
new file mode 100644
index 000000000..f2d66234a
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/tda10048.c
@@ -0,0 +1,846 @@
+/*
+ NXP TDA10048HN DVB OFDM demodulator driver
+
+ Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+
+ 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/kernel.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/delay.h>
+#include "dvb_frontend.h"
+#include "dvb_math.h"
+#include "tda10048.h"
+
+#define TDA10048_DEFAULT_FIRMWARE "dvb-fe-tda10048-1.0.fw"
+#define TDA10048_DEFAULT_FIRMWARE_SIZE 24878
+
+/* Register name definitions */
+#define TDA10048_IDENTITY 0x00
+#define TDA10048_VERSION 0x01
+#define TDA10048_DSP_CODE_CPT 0x0C
+#define TDA10048_DSP_CODE_IN 0x0E
+#define TDA10048_IN_CONF1 0x10
+#define TDA10048_IN_CONF2 0x11
+#define TDA10048_IN_CONF3 0x12
+#define TDA10048_OUT_CONF1 0x14
+#define TDA10048_OUT_CONF2 0x15
+#define TDA10048_OUT_CONF3 0x16
+#define TDA10048_AUTO 0x18
+#define TDA10048_SYNC_STATUS 0x1A
+#define TDA10048_CONF_C4_1 0x1E
+#define TDA10048_CONF_C4_2 0x1F
+#define TDA10048_CODE_IN_RAM 0x20
+#define TDA10048_CHANNEL_INFO_1_R 0x22
+#define TDA10048_CHANNEL_INFO_2_R 0x23
+#define TDA10048_CHANNEL_INFO1 0x24
+#define TDA10048_CHANNEL_INFO2 0x25
+#define TDA10048_TIME_ERROR_R 0x26
+#define TDA10048_TIME_ERROR 0x27
+#define TDA10048_FREQ_ERROR_LSB_R 0x28
+#define TDA10048_FREQ_ERROR_MSB_R 0x29
+#define TDA10048_FREQ_ERROR_LSB 0x2A
+#define TDA10048_FREQ_ERROR_MSB 0x2B
+#define TDA10048_IT_SEL 0x30
+#define TDA10048_IT_STAT 0x32
+#define TDA10048_DSP_AD_LSB 0x3C
+#define TDA10048_DSP_AD_MSB 0x3D
+#define TDA10048_DSP_REF_LSB 0x3E
+#define TDA10048_DSP_REF_MSB 0x3F
+#define TDA10048_CONF_TRISTATE1 0x44
+#define TDA10048_CONF_TRISTATE2 0x45
+#define TDA10048_CONF_POLARITY 0x46
+#define TDA10048_GPIO_SP_DS0 0x48
+#define TDA10048_GPIO_SP_DS1 0x49
+#define TDA10048_GPIO_SP_DS2 0x4A
+#define TDA10048_GPIO_SP_DS3 0x4B
+#define TDA10048_GPIO_OUT_SEL 0x4C
+#define TDA10048_GPIO_SELECT 0x4D
+#define TDA10048_IC_MODE 0x4E
+#define TDA10048_CONF_XO 0x50
+#define TDA10048_CONF_PLL1 0x51
+#define TDA10048_CONF_PLL2 0x52
+#define TDA10048_CONF_PLL3 0x53
+#define TDA10048_CONF_ADC 0x54
+#define TDA10048_CONF_ADC_2 0x55
+#define TDA10048_CONF_C1_1 0x60
+#define TDA10048_CONF_C1_3 0x62
+#define TDA10048_AGC_CONF 0x70
+#define TDA10048_AGC_THRESHOLD_LSB 0x72
+#define TDA10048_AGC_THRESHOLD_MSB 0x73
+#define TDA10048_AGC_RENORM 0x74
+#define TDA10048_AGC_GAINS 0x76
+#define TDA10048_AGC_TUN_MIN 0x78
+#define TDA10048_AGC_TUN_MAX 0x79
+#define TDA10048_AGC_IF_MIN 0x7A
+#define TDA10048_AGC_IF_MAX 0x7B
+#define TDA10048_AGC_TUN_LEVEL 0x7E
+#define TDA10048_AGC_IF_LEVEL 0x7F
+#define TDA10048_DIG_AGC_LEVEL 0x81
+#define TDA10048_FREQ_PHY2_LSB 0x86
+#define TDA10048_FREQ_PHY2_MSB 0x87
+#define TDA10048_TIME_INVWREF_LSB 0x88
+#define TDA10048_TIME_INVWREF_MSB 0x89
+#define TDA10048_TIME_WREF_LSB 0x8A
+#define TDA10048_TIME_WREF_MID1 0x8B
+#define TDA10048_TIME_WREF_MID2 0x8C
+#define TDA10048_TIME_WREF_MSB 0x8D
+#define TDA10048_NP_OUT 0xA2
+#define TDA10048_CELL_ID_LSB 0xA4
+#define TDA10048_CELL_ID_MSB 0xA5
+#define TDA10048_EXTTPS_ODD 0xAA
+#define TDA10048_EXTTPS_EVEN 0xAB
+#define TDA10048_TPS_LENGTH 0xAC
+#define TDA10048_FREE_REG_1 0xB2
+#define TDA10048_FREE_REG_2 0xB3
+#define TDA10048_CONF_C3_1 0xC0
+#define TDA10048_CYBER_CTRL 0xC2
+#define TDA10048_CBER_NMAX_LSB 0xC4
+#define TDA10048_CBER_NMAX_MSB 0xC5
+#define TDA10048_CBER_LSB 0xC6
+#define TDA10048_CBER_MSB 0xC7
+#define TDA10048_VBER_LSB 0xC8
+#define TDA10048_VBER_MID 0xC9
+#define TDA10048_VBER_MSB 0xCA
+#define TDA10048_CYBER_LUT 0xCC
+#define TDA10048_UNCOR_CTRL 0xCD
+#define TDA10048_UNCOR_CPT_LSB 0xCE
+#define TDA10048_UNCOR_CPT_MSB 0xCF
+#define TDA10048_SOFT_IT_C3 0xD6
+#define TDA10048_CONF_TS2 0xE0
+#define TDA10048_CONF_TS1 0xE1
+
+static unsigned int debug;
+
+#define dprintk(level, fmt, arg...)\
+ do { if (debug >= level)\
+ printk(KERN_DEBUG "tda10048: " fmt, ## arg);\
+ } while (0)
+
+struct tda10048_state {
+
+ struct i2c_adapter *i2c;
+
+ /* configuration settings */
+ const struct tda10048_config *config;
+ struct dvb_frontend frontend;
+
+ int fwloaded;
+};
+
+static struct init_tab {
+ u8 reg;
+ u16 data;
+} init_tab[] = {
+ { TDA10048_CONF_PLL1, 0x08 },
+ { TDA10048_CONF_ADC_2, 0x00 },
+ { TDA10048_CONF_C4_1, 0x00 },
+ { TDA10048_CONF_PLL1, 0x0f },
+ { TDA10048_CONF_PLL2, 0x0a },
+ { TDA10048_CONF_PLL3, 0x43 },
+ { TDA10048_FREQ_PHY2_LSB, 0x02 },
+ { TDA10048_FREQ_PHY2_MSB, 0x0a },
+ { TDA10048_TIME_WREF_LSB, 0xbd },
+ { TDA10048_TIME_WREF_MID1, 0xe4 },
+ { TDA10048_TIME_WREF_MID2, 0xa8 },
+ { TDA10048_TIME_WREF_MSB, 0x02 },
+ { TDA10048_TIME_INVWREF_LSB, 0x04 },
+ { TDA10048_TIME_INVWREF_MSB, 0x06 },
+ { TDA10048_CONF_C4_1, 0x00 },
+ { TDA10048_CONF_C1_1, 0xa8 },
+ { TDA10048_AGC_CONF, 0x16 },
+ { TDA10048_CONF_C1_3, 0x0b },
+ { TDA10048_AGC_TUN_MIN, 0x00 },
+ { TDA10048_AGC_TUN_MAX, 0xff },
+ { TDA10048_AGC_IF_MIN, 0x00 },
+ { TDA10048_AGC_IF_MAX, 0xff },
+ { TDA10048_AGC_THRESHOLD_MSB, 0x00 },
+ { TDA10048_AGC_THRESHOLD_LSB, 0x70 },
+ { TDA10048_CYBER_CTRL, 0x38 },
+ { TDA10048_AGC_GAINS, 0x12 },
+ { TDA10048_CONF_XO, 0x00 },
+ { TDA10048_CONF_TS1, 0x07 },
+ { TDA10048_IC_MODE, 0x00 },
+ { TDA10048_CONF_TS2, 0xc0 },
+ { TDA10048_CONF_TRISTATE1, 0x21 },
+ { TDA10048_CONF_TRISTATE2, 0x00 },
+ { TDA10048_CONF_POLARITY, 0x00 },
+ { TDA10048_CONF_C4_2, 0x04 },
+ { TDA10048_CONF_ADC, 0x60 },
+ { TDA10048_CONF_ADC_2, 0x10 },
+ { TDA10048_CONF_ADC, 0x60 },
+ { TDA10048_CONF_ADC_2, 0x00 },
+ { TDA10048_CONF_C1_1, 0xa8 },
+ { TDA10048_UNCOR_CTRL, 0x00 },
+ { TDA10048_CONF_C4_2, 0x04 },
+};
+
+static int tda10048_writereg(struct tda10048_state *state, u8 reg, u8 data)
+{
+ int ret;
+ u8 buf [] = { reg, data };
+ struct i2c_msg msg = {
+ .addr = state->config->demod_address,
+ .flags = 0, .buf = buf, .len = 2 };
+
+ dprintk(2, "%s(reg = 0x%02x, data = 0x%02x)\n", __func__, reg, data);
+
+ ret = i2c_transfer(state->i2c, &msg, 1);
+
+ if (ret != 1)
+ printk("%s: writereg error (ret == %i)\n", __func__, ret);
+
+ return (ret != 1) ? -1 : 0;
+}
+
+static u8 tda10048_readreg(struct tda10048_state *state, u8 reg)
+{
+ int ret;
+ u8 b0 [] = { reg };
+ u8 b1 [] = { 0 };
+ struct i2c_msg msg [] = {
+ { .addr = state->config->demod_address,
+ .flags = 0, .buf = b0, .len = 1 },
+ { .addr = state->config->demod_address,
+ .flags = I2C_M_RD, .buf = b1, .len = 1 } };
+
+ dprintk(2, "%s(reg = 0x%02x)\n", __func__, reg);
+
+ ret = i2c_transfer(state->i2c, msg, 2);
+
+ if (ret != 2)
+ printk(KERN_ERR "%s: readreg error (ret == %i)\n",
+ __func__, ret);
+
+ return b1[0];
+}
+
+static int tda10048_writeregbulk(struct tda10048_state *state, u8 reg,
+ u8 *data, u16 len)
+{
+ int ret = -EREMOTEIO;
+ struct i2c_msg msg;
+ u8 *buf;
+
+ dprintk(2, "%s(%d, ?, len = %d)\n", __func__, reg, len);
+
+ buf = kmalloc(len + 1, GFP_KERNEL);
+ if (buf == NULL) {
+ ret = -ENOMEM;
+ goto error;
+ }
+
+ *buf = reg;
+ memcpy(buf + 1, data, len);
+
+ msg.addr = state->config->demod_address;
+ msg.flags = 0;
+ msg.buf = buf;
+ msg.len = len + 1;
+
+ dprintk(2, "%s(): write len = %d\n",
+ __func__, msg.len);
+
+ ret = i2c_transfer(state->i2c, &msg, 1);
+ if (ret != 1) {
+ printk(KERN_ERR "%s(): writereg error err %i\n",
+ __func__, ret);
+ ret = -EREMOTEIO;
+ }
+
+error:
+ kfree(buf);
+
+ return ret;
+}
+
+static int tda10048_firmware_upload(struct dvb_frontend *fe)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ const struct firmware *fw;
+ int ret;
+ int pos = 0;
+ int cnt;
+ u8 wlen = state->config->fwbulkwritelen;
+
+ if ((wlen != TDA10048_BULKWRITE_200) && (wlen != TDA10048_BULKWRITE_50))
+ wlen = TDA10048_BULKWRITE_200;
+
+ /* request the firmware, this will block and timeout */
+ printk(KERN_INFO "%s: waiting for firmware upload (%s)...\n",
+ __func__,
+ TDA10048_DEFAULT_FIRMWARE);
+
+ ret = request_firmware(&fw, TDA10048_DEFAULT_FIRMWARE,
+ &state->i2c->dev);
+ if (ret) {
+ printk(KERN_ERR "%s: Upload failed. (file not found?)\n",
+ __func__);
+ return -EIO;
+ } else {
+ printk(KERN_INFO "%s: firmware read %Zu bytes.\n",
+ __func__,
+ fw->size);
+ ret = 0;
+ }
+
+ if (fw->size != TDA10048_DEFAULT_FIRMWARE_SIZE) {
+ printk(KERN_ERR "%s: firmware incorrect size\n", __func__);
+ return -EIO;
+ } else {
+ printk(KERN_INFO "%s: firmware uploading\n", __func__);
+
+ /* Soft reset */
+ tda10048_writereg(state, TDA10048_CONF_TRISTATE1,
+ tda10048_readreg(state, TDA10048_CONF_TRISTATE1)
+ & 0xfe);
+ tda10048_writereg(state, TDA10048_CONF_TRISTATE1,
+ tda10048_readreg(state, TDA10048_CONF_TRISTATE1)
+ | 0x01);
+
+ /* Put the demod into host download mode */
+ tda10048_writereg(state, TDA10048_CONF_C4_1,
+ tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xf9);
+
+ /* Boot the DSP */
+ tda10048_writereg(state, TDA10048_CONF_C4_1,
+ tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x08);
+
+ /* Prepare for download */
+ tda10048_writereg(state, TDA10048_DSP_CODE_CPT, 0);
+
+ /* Download the firmware payload */
+ while (pos < fw->size) {
+
+ if ((fw->size - pos) > wlen)
+ cnt = wlen;
+ else
+ cnt = fw->size - pos;
+
+ tda10048_writeregbulk(state, TDA10048_DSP_CODE_IN,
+ &fw->data[pos], cnt);
+
+ pos += cnt;
+ }
+
+ ret = -EIO;
+ /* Wait up to 250ms for the DSP to boot */
+ for (cnt = 0; cnt < 250 ; cnt += 10) {
+
+ msleep(10);
+
+ if (tda10048_readreg(state, TDA10048_SYNC_STATUS)
+ & 0x40) {
+ ret = 0;
+ break;
+ }
+ }
+ }
+
+ release_firmware(fw);
+
+ if (ret == 0) {
+ printk(KERN_INFO "%s: firmware uploaded\n", __func__);
+ state->fwloaded = 1;
+ } else
+ printk(KERN_ERR "%s: firmware upload failed\n", __func__);
+
+ return ret;
+}
+
+static int tda10048_set_inversion(struct dvb_frontend *fe, int inversion)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+
+ dprintk(1, "%s(%d)\n", __func__, inversion);
+
+ if (inversion == TDA10048_INVERSION_ON)
+ tda10048_writereg(state, TDA10048_CONF_C1_1,
+ tda10048_readreg(state, TDA10048_CONF_C1_1) | 0x20);
+ else
+ tda10048_writereg(state, TDA10048_CONF_C1_1,
+ tda10048_readreg(state, TDA10048_CONF_C1_1) & 0xdf);
+
+ return 0;
+}
+
+/* Retrieve the demod settings */
+static int tda10048_get_tps(struct tda10048_state *state,
+ struct dvb_ofdm_parameters *p)
+{
+ u8 val;
+
+ /* Make sure the TPS regs are valid */
+ if (!(tda10048_readreg(state, TDA10048_AUTO) & 0x01))
+ return -EAGAIN;
+
+ val = tda10048_readreg(state, TDA10048_OUT_CONF2);
+ switch ((val & 0x60) >> 5) {
+ case 0: p->constellation = QPSK; break;
+ case 1: p->constellation = QAM_16; break;
+ case 2: p->constellation = QAM_64; break;
+ }
+ switch ((val & 0x18) >> 3) {
+ case 0: p->hierarchy_information = HIERARCHY_NONE; break;
+ case 1: p->hierarchy_information = HIERARCHY_1; break;
+ case 2: p->hierarchy_information = HIERARCHY_2; break;
+ case 3: p->hierarchy_information = HIERARCHY_4; break;
+ }
+ switch (val & 0x07) {
+ case 0: p->code_rate_HP = FEC_1_2; break;
+ case 1: p->code_rate_HP = FEC_2_3; break;
+ case 2: p->code_rate_HP = FEC_3_4; break;
+ case 3: p->code_rate_HP = FEC_5_6; break;
+ case 4: p->code_rate_HP = FEC_7_8; break;
+ }
+
+ val = tda10048_readreg(state, TDA10048_OUT_CONF3);
+ switch (val & 0x07) {
+ case 0: p->code_rate_LP = FEC_1_2; break;
+ case 1: p->code_rate_LP = FEC_2_3; break;
+ case 2: p->code_rate_LP = FEC_3_4; break;
+ case 3: p->code_rate_LP = FEC_5_6; break;
+ case 4: p->code_rate_LP = FEC_7_8; break;
+ }
+
+ val = tda10048_readreg(state, TDA10048_OUT_CONF1);
+ switch ((val & 0x0c) >> 2) {
+ case 0: p->guard_interval = GUARD_INTERVAL_1_32; break;
+ case 1: p->guard_interval = GUARD_INTERVAL_1_16; break;
+ case 2: p->guard_interval = GUARD_INTERVAL_1_8; break;
+ case 3: p->guard_interval = GUARD_INTERVAL_1_4; break;
+ }
+ switch (val & 0x02) {
+ case 0: p->transmission_mode = TRANSMISSION_MODE_2K; break;
+ case 1: p->transmission_mode = TRANSMISSION_MODE_8K; break;
+ }
+
+ return 0;
+}
+
+static int tda10048_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ dprintk(1, "%s(%d)\n", __func__, enable);
+
+ if (enable)
+ return tda10048_writereg(state, TDA10048_CONF_C4_1,
+ tda10048_readreg(state, TDA10048_CONF_C4_1) | 0x02);
+ else
+ return tda10048_writereg(state, TDA10048_CONF_C4_1,
+ tda10048_readreg(state, TDA10048_CONF_C4_1) & 0xfd);
+}
+
+static int tda10048_output_mode(struct dvb_frontend *fe, int serial)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ dprintk(1, "%s(%d)\n", __func__, serial);
+
+ /* Ensure pins are out of tri-state */
+ tda10048_writereg(state, TDA10048_CONF_TRISTATE1, 0x21);
+ tda10048_writereg(state, TDA10048_CONF_TRISTATE2, 0x00);
+
+ if (serial) {
+ tda10048_writereg(state, TDA10048_IC_MODE, 0x80 | 0x20);
+ tda10048_writereg(state, TDA10048_CONF_TS2, 0xc0);
+ } else {
+ tda10048_writereg(state, TDA10048_IC_MODE, 0x00);
+ tda10048_writereg(state, TDA10048_CONF_TS2, 0x01);
+ }
+
+ return 0;
+}
+
+/* Talk to the demod, set the FEC, GUARD, QAM settings etc */
+/* TODO: Support manual tuning with specific params */
+static int tda10048_set_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+
+ dprintk(1, "%s(frequency=%d)\n", __func__, p->frequency);
+
+ if (fe->ops.tuner_ops.set_params) {
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 1);
+
+ fe->ops.tuner_ops.set_params(fe, p);
+
+ if (fe->ops.i2c_gate_ctrl)
+ fe->ops.i2c_gate_ctrl(fe, 0);
+ }
+
+ /* Enable demod TPS auto detection and begin acquisition */
+ tda10048_writereg(state, TDA10048_AUTO, 0x57);
+
+ return 0;
+}
+
+/* Establish sane defaults and load firmware. */
+static int tda10048_init(struct dvb_frontend *fe)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ int ret = 0, i;
+
+ dprintk(1, "%s()\n", __func__);
+
+ /* Apply register defaults */
+ for (i = 0; i < ARRAY_SIZE(init_tab); i++)
+ tda10048_writereg(state, init_tab[i].reg, init_tab[i].data);
+
+ if (state->fwloaded == 0)
+ ret = tda10048_firmware_upload(fe);
+
+ /* Set either serial or parallel */
+ tda10048_output_mode(fe, state->config->output_mode);
+
+ /* set inversion */
+ tda10048_set_inversion(fe, state->config->inversion);
+
+ /* Ensure we leave the gate closed */
+ tda10048_i2c_gate_ctrl(fe, 0);
+
+ return ret;
+}
+
+static int tda10048_read_status(struct dvb_frontend *fe, fe_status_t *status)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ u8 reg;
+
+ *status = 0;
+
+ reg = tda10048_readreg(state, TDA10048_SYNC_STATUS);
+
+ dprintk(1, "%s() status =0x%02x\n", __func__, reg);
+
+ if (reg & 0x02)
+ *status |= FE_HAS_CARRIER;
+
+ if (reg & 0x04)
+ *status |= FE_HAS_SIGNAL;
+
+ if (reg & 0x08) {
+ *status |= FE_HAS_LOCK;
+ *status |= FE_HAS_VITERBI;
+ *status |= FE_HAS_SYNC;
+ }
+
+ return 0;
+}
+
+static int tda10048_read_ber(struct dvb_frontend *fe, u32 *ber)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+
+ dprintk(1, "%s()\n", __func__);
+
+ /* TODO: A reset may be required here */
+ *ber = tda10048_readreg(state, TDA10048_CBER_MSB) << 8 |
+ tda10048_readreg(state, TDA10048_CBER_LSB);
+
+ return 0;
+}
+
+static int tda10048_read_signal_strength(struct dvb_frontend *fe,
+ u16 *signal_strength)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ u8 v;
+
+ dprintk(1, "%s()\n", __func__);
+
+ *signal_strength = 65535;
+
+ v = tda10048_readreg(state, TDA10048_NP_OUT);
+ if (v > 0)
+ *signal_strength -= (v << 8) | v;
+
+ return 0;
+}
+
+/* SNR lookup table */
+static struct snr_tab {
+ u8 val;
+ u8 data;
+} snr_tab[] = {
+ { 0, 0 },
+ { 1, 246 },
+ { 2, 215 },
+ { 3, 198 },
+ { 4, 185 },
+ { 5, 176 },
+ { 6, 168 },
+ { 7, 161 },
+ { 8, 155 },
+ { 9, 150 },
+ { 10, 146 },
+ { 11, 141 },
+ { 12, 138 },
+ { 13, 134 },
+ { 14, 131 },
+ { 15, 128 },
+ { 16, 125 },
+ { 17, 122 },
+ { 18, 120 },
+ { 19, 118 },
+ { 20, 115 },
+ { 21, 113 },
+ { 22, 111 },
+ { 23, 109 },
+ { 24, 107 },
+ { 25, 106 },
+ { 26, 104 },
+ { 27, 102 },
+ { 28, 101 },
+ { 29, 99 },
+ { 30, 98 },
+ { 31, 96 },
+ { 32, 95 },
+ { 33, 94 },
+ { 34, 92 },
+ { 35, 91 },
+ { 36, 90 },
+ { 37, 89 },
+ { 38, 88 },
+ { 39, 86 },
+ { 40, 85 },
+ { 41, 84 },
+ { 42, 83 },
+ { 43, 82 },
+ { 44, 81 },
+ { 45, 80 },
+ { 46, 79 },
+ { 47, 78 },
+ { 48, 77 },
+ { 49, 76 },
+ { 50, 76 },
+ { 51, 75 },
+ { 52, 74 },
+ { 53, 73 },
+ { 54, 72 },
+ { 56, 71 },
+ { 57, 70 },
+ { 58, 69 },
+ { 60, 68 },
+ { 61, 67 },
+ { 63, 66 },
+ { 64, 65 },
+ { 66, 64 },
+ { 67, 63 },
+ { 68, 62 },
+ { 69, 62 },
+ { 70, 61 },
+ { 72, 60 },
+ { 74, 59 },
+ { 75, 58 },
+ { 77, 57 },
+ { 79, 56 },
+ { 81, 55 },
+ { 83, 54 },
+ { 85, 53 },
+ { 87, 52 },
+ { 89, 51 },
+ { 91, 50 },
+ { 93, 49 },
+ { 95, 48 },
+ { 97, 47 },
+ { 100, 46 },
+ { 102, 45 },
+ { 104, 44 },
+ { 107, 43 },
+ { 109, 42 },
+ { 112, 41 },
+ { 114, 40 },
+ { 117, 39 },
+ { 120, 38 },
+ { 123, 37 },
+ { 125, 36 },
+ { 128, 35 },
+ { 131, 34 },
+ { 134, 33 },
+ { 138, 32 },
+ { 141, 31 },
+ { 144, 30 },
+ { 147, 29 },
+ { 151, 28 },
+ { 154, 27 },
+ { 158, 26 },
+ { 162, 25 },
+ { 165, 24 },
+ { 169, 23 },
+ { 173, 22 },
+ { 177, 21 },
+ { 181, 20 },
+ { 186, 19 },
+ { 190, 18 },
+ { 194, 17 },
+ { 199, 16 },
+ { 204, 15 },
+ { 208, 14 },
+ { 213, 13 },
+ { 218, 12 },
+ { 223, 11 },
+ { 229, 10 },
+ { 234, 9 },
+ { 239, 8 },
+ { 245, 7 },
+ { 251, 6 },
+ { 255, 5 },
+};
+
+static int tda10048_read_snr(struct dvb_frontend *fe, u16 *snr)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ u8 v;
+ int i, ret = -EINVAL;
+
+ dprintk(1, "%s()\n", __func__);
+
+ v = tda10048_readreg(state, TDA10048_NP_OUT);
+ for (i = 0; i < ARRAY_SIZE(snr_tab); i++) {
+ if (v <= snr_tab[i].val) {
+ *snr = snr_tab[i].data;
+ ret = 0;
+ break;
+ }
+ }
+
+ return ret;
+}
+
+static int tda10048_read_ucblocks(struct dvb_frontend *fe, u32 *ucblocks)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+
+ dprintk(1, "%s()\n", __func__);
+#if 0
+ /* Reset and begin counting */
+ tda10048_writereg(state, TDA10048_UNCOR_CTRL, 0x01);
+ msleep(10);
+#endif
+
+ *ucblocks = tda10048_readreg(state, TDA10048_UNCOR_CPT_MSB) << 8 |
+ tda10048_readreg(state, TDA10048_UNCOR_CPT_LSB);
+
+ return 0;
+}
+
+static int tda10048_get_frontend(struct dvb_frontend *fe,
+ struct dvb_frontend_parameters *p)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+
+ dprintk(1, "%s()\n", __func__);
+
+ p->inversion = tda10048_readreg(state, TDA10048_CONF_C1_1)
+ & 0x20 ? INVERSION_ON : INVERSION_OFF;
+
+ return tda10048_get_tps(state, &p->u.ofdm);
+}
+
+static int tda10048_get_tune_settings(struct dvb_frontend *fe,
+ struct dvb_frontend_tune_settings *tune)
+{
+ tune->min_delay_ms = 1000;
+ return 0;
+}
+
+static void tda10048_release(struct dvb_frontend *fe)
+{
+ struct tda10048_state *state = fe->demodulator_priv;
+ dprintk(1, "%s()\n", __func__);
+ kfree(state);
+}
+
+static struct dvb_frontend_ops tda10048_ops;
+
+struct dvb_frontend *tda10048_attach(const struct tda10048_config *config,
+ struct i2c_adapter *i2c)
+{
+ struct tda10048_state *state = NULL;
+
+ dprintk(1, "%s()\n", __func__);
+
+ /* allocate memory for the internal state */
+ state = kmalloc(sizeof(struct tda10048_state), GFP_KERNEL);
+ if (state == NULL)
+ goto error;
+
+ /* setup the state */
+ state->config = config;
+ state->i2c = i2c;
+ state->fwloaded = 0;
+
+ /* check if the demod is present */
+ if (tda10048_readreg(state, TDA10048_IDENTITY) != 0x048)
+ goto error;
+
+ /* create dvb_frontend */
+ memcpy(&state->frontend.ops, &tda10048_ops,
+ sizeof(struct dvb_frontend_ops));
+ state->frontend.demodulator_priv = state;
+
+ /* Leave the gate closed */
+ tda10048_i2c_gate_ctrl(&state->frontend, 0);
+
+ return &state->frontend;
+
+error:
+ kfree(state);
+ return NULL;
+}
+EXPORT_SYMBOL(tda10048_attach);
+
+static struct dvb_frontend_ops tda10048_ops = {
+
+ .info = {
+ .name = "NXP TDA10048HN DVB-T",
+ .type = FE_OFDM,
+ .frequency_min = 177000000,
+ .frequency_max = 858000000,
+ .frequency_stepsize = 166666,
+ .caps = FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
+ FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
+ FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
+ FE_CAN_HIERARCHY_AUTO | FE_CAN_GUARD_INTERVAL_AUTO |
+ FE_CAN_TRANSMISSION_MODE_AUTO | FE_CAN_RECOVER
+ },
+
+ .release = tda10048_release,
+ .init = tda10048_init,
+ .i2c_gate_ctrl = tda10048_i2c_gate_ctrl,
+ .set_frontend = tda10048_set_frontend,
+ .get_frontend = tda10048_get_frontend,
+ .get_tune_settings = tda10048_get_tune_settings,
+ .read_status = tda10048_read_status,
+ .read_ber = tda10048_read_ber,
+ .read_signal_strength = tda10048_read_signal_strength,
+ .read_snr = tda10048_read_snr,
+ .read_ucblocks = tda10048_read_ucblocks,
+};
+
+module_param(debug, int, 0644);
+MODULE_PARM_DESC(debug, "Enable verbose debug messages");
+
+MODULE_DESCRIPTION("NXP TDA10048HN DVB-T Demodulator driver");
+MODULE_AUTHOR("Steven Toth");
+MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/frontends/tda10048.h b/linux/drivers/media/dvb/frontends/tda10048.h
new file mode 100644
index 000000000..2b5c78e62
--- /dev/null
+++ b/linux/drivers/media/dvb/frontends/tda10048.h
@@ -0,0 +1,63 @@
+/*
+ NXP TDA10048HN DVB OFDM demodulator driver
+
+ Copyright (C) 2008 Steven Toth <stoth@hauppauge.com>
+
+ 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 TDA10048_H
+#define TDA10048_H
+
+#include <linux/dvb/frontend.h>
+#include <linux/firmware.h>
+
+struct tda10048_config {
+
+ /* the demodulator's i2c address */
+ u8 demod_address;
+
+ /* serial/parallel output */
+#define TDA10048_PARALLEL_OUTPUT 0
+#define TDA10048_SERIAL_OUTPUT 1
+ u8 output_mode;
+
+#define TDA10048_BULKWRITE_200 200
+#define TDA10048_BULKWRITE_50 50
+ u8 fwbulkwritelen;
+
+ /* Spectral Inversion */
+#define TDA10048_INVERSION_OFF 0
+#define TDA10048_INVERSION_ON 1
+ u8 inversion;
+};
+
+#if defined(CONFIG_DVB_TDA10048) || \
+ (defined(CONFIG_DVB_TDA10048_MODULE) && defined(MODULE))
+extern struct dvb_frontend *tda10048_attach(
+ const struct tda10048_config *config,
+ struct i2c_adapter *i2c);
+#else
+static inline struct dvb_frontend *tda10048_attach(
+ const struct tda10048_config *config,
+ struct i2c_adapter *i2c)
+{
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
+ return NULL;
+}
+#endif /* CONFIG_DVB_TDA10048 */
+
+#endif /* TDA10048_H */
diff --git a/linux/drivers/media/dvb/frontends/tda1004x.c b/linux/drivers/media/dvb/frontends/tda1004x.c
index 8415a8a52..499738463 100644
--- a/linux/drivers/media/dvb/frontends/tda1004x.c
+++ b/linux/drivers/media/dvb/frontends/tda1004x.c
@@ -131,16 +131,16 @@ static int tda1004x_write_byteI(struct tda1004x_state *state, int reg, int data)
u8 buf[] = { reg, data };
struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
- dprintk("%s: reg=0x%x, data=0x%x\n", __FUNCTION__, reg, data);
+ dprintk("%s: reg=0x%x, data=0x%x\n", __func__, reg, data);
msg.addr = state->config->demod_address;
ret = i2c_transfer(state->i2c, &msg, 1);
if (ret != 1)
dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
- __FUNCTION__, reg, data, ret);
+ __func__, reg, data, ret);
- dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
+ dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
reg, data, ret);
return (ret != 1) ? -1 : 0;
}
@@ -153,19 +153,19 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
{ .flags = I2C_M_RD, .buf = b1, .len = 1 }};
- dprintk("%s: reg=0x%x\n", __FUNCTION__, reg);
+ dprintk("%s: reg=0x%x\n", __func__, reg);
msg[0].addr = state->config->demod_address;
msg[1].addr = state->config->demod_address;
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2) {
- dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg,
+ dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
ret);
return -1;
}
- dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __FUNCTION__,
+ dprintk("%s: success reg=0x%x, data=0x%x, ret=%i\n", __func__,
reg, b1[0], ret);
return b1[0];
}
@@ -173,7 +173,7 @@ static int tda1004x_read_byte(struct tda1004x_state *state, int reg)
static int tda1004x_write_mask(struct tda1004x_state *state, int reg, int mask, int data)
{
int val;
- dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __FUNCTION__, reg,
+ dprintk("%s: reg=0x%x, mask=0x%x, data=0x%x\n", __func__, reg,
mask, data);
// read a byte and check
@@ -194,7 +194,7 @@ static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned ch
int i;
int result;
- dprintk("%s: reg=0x%x, len=0x%x\n", __FUNCTION__, reg, len);
+ dprintk("%s: reg=0x%x, len=0x%x\n", __func__, reg, len);
result = 0;
for (i = 0; i < len; i++) {
@@ -209,7 +209,7 @@ static int tda1004x_write_buf(struct tda1004x_state *state, int reg, unsigned ch
static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
{
int result;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
result = tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 2);
msleep(20);
@@ -218,7 +218,7 @@ static int tda1004x_enable_tuner_i2c(struct tda1004x_state *state)
static int tda1004x_disable_tuner_i2c(struct tda1004x_state *state)
{
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
return tda1004x_write_mask(state, TDA1004X_CONFC4, 2, 0);
}
@@ -345,7 +345,7 @@ static int tda1004x_do_upload(struct tda1004x_state *state,
}
pos += tx_size;
- dprintk("%s: fw_pos=0x%x\n", __FUNCTION__, pos);
+ dprintk("%s: fw_pos=0x%x\n", __func__, pos);
}
// give the DSP a chance to settle 03/10/05 Hac
msleep(100);
@@ -444,10 +444,10 @@ static void tda10046_init_plls(struct dvb_frontend* fe)
tda1004x_write_byteI(state, TDA10046H_CONFPLL2, 0x03); // PLL M = 3
}
if (state->config->xtal_freq == TDA10046_XTAL_4M ) {
- dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __FUNCTION__);
+ dprintk("%s: setting up PLLs for a 4 MHz Xtal\n", __func__);
tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 0); // PLL P = N = 0
} else {
- dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __FUNCTION__);
+ dprintk("%s: setting up PLLs for a 16 MHz Xtal\n", __func__);
tda1004x_write_byteI(state, TDA10046H_CONFPLL3, 3); // PLL P = 0, N = 3
}
if(tda10046_clk53m)
@@ -488,7 +488,7 @@ static int tda10046_fwupload(struct dvb_frontend* fe)
if (state->config->xtal_freq == TDA10046_XTAL_4M) {
tda1004x_write_byteI(state, TDA1004X_CONFC4, 0);
} else {
- dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __FUNCTION__);
+ dprintk("%s: 16MHz Xtal, reducing I2C speed\n", __func__);
tda1004x_write_byteI(state, TDA1004X_CONFC4, 0x80);
}
tda1004x_write_mask(state, TDA10046H_CONF_TRISTATE1, 1, 0);
@@ -594,7 +594,7 @@ static int tda10045_init(struct dvb_frontend* fe)
{
struct tda1004x_state* state = fe->demodulator_priv;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
if (tda10045_fwupload(fe)) {
printk("tda1004x: firmware upload failed\n");
@@ -624,7 +624,7 @@ static int tda10045_init(struct dvb_frontend* fe)
static int tda10046_init(struct dvb_frontend* fe)
{
struct tda1004x_state* state = fe->demodulator_priv;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
if (tda10046_fwupload(fe)) {
printk("tda1004x: firmware upload failed\n");
@@ -686,7 +686,7 @@ static int tda1004x_set_fe(struct dvb_frontend* fe,
int tmp;
int inversion;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
if (state->demod_type == TDA1004X_DEMOD_TDA10046) {
// setup auto offset
@@ -881,7 +881,7 @@ static int tda1004x_get_fe(struct dvb_frontend* fe, struct dvb_frontend_paramete
{
struct tda1004x_state* state = fe->demodulator_priv;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
// inversion status
fe_params->inversion = INVERSION_OFF;
@@ -989,7 +989,7 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
int cber;
int vber;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
// read status
status = tda1004x_read_byte(state, TDA1004X_STATUS_CD);
@@ -1048,7 +1048,7 @@ static int tda1004x_read_status(struct dvb_frontend* fe, fe_status_t * fe_status
}
// success
- dprintk("%s: fe_status=0x%x\n", __FUNCTION__, *fe_status);
+ dprintk("%s: fe_status=0x%x\n", __func__, *fe_status);
return 0;
}
@@ -1058,7 +1058,7 @@ static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
int tmp;
int reg = 0;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
// determine the register to use
switch (state->demod_type) {
@@ -1077,7 +1077,7 @@ static int tda1004x_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
return -EIO;
*signal = (tmp << 8) | tmp;
- dprintk("%s: signal=0x%x\n", __FUNCTION__, *signal);
+ dprintk("%s: signal=0x%x\n", __func__, *signal);
return 0;
}
@@ -1086,7 +1086,7 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
struct tda1004x_state* state = fe->demodulator_priv;
int tmp;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
// read it
tmp = tda1004x_read_byte(state, TDA1004X_SNR);
@@ -1095,7 +1095,7 @@ static int tda1004x_read_snr(struct dvb_frontend* fe, u16 * snr)
tmp = 255 - tmp;
*snr = ((tmp << 8) | tmp);
- dprintk("%s: snr=0x%x\n", __FUNCTION__, *snr);
+ dprintk("%s: snr=0x%x\n", __func__, *snr);
return 0;
}
@@ -1106,7 +1106,7 @@ static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
int tmp2;
int counter;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
// read the UCBLOCKS and reset
counter = 0;
@@ -1132,7 +1132,7 @@ static int tda1004x_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
else
*ucblocks = 0xffffffff;
- dprintk("%s: ucblocks=0x%x\n", __FUNCTION__, *ucblocks);
+ dprintk("%s: ucblocks=0x%x\n", __func__, *ucblocks);
return 0;
}
@@ -1141,7 +1141,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
struct tda1004x_state* state = fe->demodulator_priv;
int tmp;
- dprintk("%s\n", __FUNCTION__);
+ dprintk("%s\n", __func__);
// read it in
tmp = tda1004x_read_byte(state, TDA1004X_CBER_LSB);
@@ -1155,7 +1155,7 @@ static int tda1004x_read_ber(struct dvb_frontend* fe, u32* ber)
// The address 0x20 should be read to cope with a TDA10046 bug
tda1004x_read_byte(state, TDA1004X_CBER_RESET);
- dprintk("%s: ber=0x%x\n", __FUNCTION__, *ber);
+ dprintk("%s: ber=0x%x\n", __func__, *ber);
return 0;
}
diff --git a/linux/drivers/media/dvb/frontends/tda1004x.h b/linux/drivers/media/dvb/frontends/tda1004x.h
index ebb2c5f5a..4e27ffb0f 100644
--- a/linux/drivers/media/dvb/frontends/tda1004x.h
+++ b/linux/drivers/media/dvb/frontends/tda1004x.h
@@ -127,13 +127,13 @@ extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config
static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_TDA1004X
diff --git a/linux/drivers/media/dvb/frontends/tda10086.c b/linux/drivers/media/dvb/frontends/tda10086.c
index a4b48bdf2..c749f96c2 100644
--- a/linux/drivers/media/dvb/frontends/tda10086.c
+++ b/linux/drivers/media/dvb/frontends/tda10086.c
@@ -61,7 +61,7 @@ static int tda10086_write_byte(struct tda10086_state *state, int reg, int data)
if (ret != 1)
dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
- __FUNCTION__, reg, data, ret);
+ __func__, reg, data, ret);
return (ret != 1) ? ret : 0;
}
@@ -79,7 +79,7 @@ static int tda10086_read_byte(struct tda10086_state *state, int reg)
ret = i2c_transfer(state->i2c, msg, 2);
if (ret != 2) {
- dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg,
+ dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg,
ret);
return ret;
}
@@ -91,16 +91,16 @@ static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask,
{
int val;
- // read a byte and check
+ /* read a byte and check */
val = tda10086_read_byte(state, reg);
if (val < 0)
return val;
- // mask if off
+ /* mask if off */
val = val & ~mask;
val |= data & 0xff;
- // write it out again
+ /* write it out again */
return tda10086_write_byte(state, reg, val);
}
@@ -109,62 +109,67 @@ static int tda10086_init(struct dvb_frontend* fe)
struct tda10086_state* state = fe->demodulator_priv;
u8 t22k_off = 0x80;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
if (state->config->diseqc_tone)
t22k_off = 0;
- // reset
+ /* reset */
tda10086_write_byte(state, 0x00, 0x00);
msleep(10);
- // misc setup
+ /* misc setup */
tda10086_write_byte(state, 0x01, 0x94);
- tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP
+ tda10086_write_byte(state, 0x02, 0x35); /* NOTE: TT drivers appear to disable CSWP */
tda10086_write_byte(state, 0x03, 0xe4);
tda10086_write_byte(state, 0x04, 0x43);
tda10086_write_byte(state, 0x0c, 0x0c);
- tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold
- tda10086_write_byte(state, 0x20, 0x89); // misc
- tda10086_write_byte(state, 0x30, 0x04); // acquisition period length
- tda10086_write_byte(state, 0x32, 0x00); // irq off
- tda10086_write_byte(state, 0x31, 0x56); // setup AFC
-
- // setup PLL (assumes 16Mhz XIN)
- tda10086_write_byte(state, 0x55, 0x2c); // misc PLL setup
- tda10086_write_byte(state, 0x3a, 0x0b); // M=12
- tda10086_write_byte(state, 0x3b, 0x01); // P=2
- tda10086_write_mask(state, 0x55, 0x20, 0x00); // powerup PLL
-
- // setup TS interface
+ tda10086_write_byte(state, 0x1b, 0xb0); /* noise threshold */
+ tda10086_write_byte(state, 0x20, 0x89); /* misc */
+ tda10086_write_byte(state, 0x30, 0x04); /* acquisition period length */
+ tda10086_write_byte(state, 0x32, 0x00); /* irq off */
+ tda10086_write_byte(state, 0x31, 0x56); /* setup AFC */
+
+ /* setup PLL (this assumes SACLK = 96MHz) */
+ tda10086_write_byte(state, 0x55, 0x2c); /* misc PLL setup */
+ if (state->config->xtal_freq == TDA10086_XTAL_16M) {
+ tda10086_write_byte(state, 0x3a, 0x0b); /* M=12 */
+ tda10086_write_byte(state, 0x3b, 0x01); /* P=2 */
+ } else {
+ tda10086_write_byte(state, 0x3a, 0x17); /* M=24 */
+ tda10086_write_byte(state, 0x3b, 0x00); /* P=1 */
+ }
+ tda10086_write_mask(state, 0x55, 0x20, 0x00); /* powerup PLL */
+
+ /* setup TS interface */
tda10086_write_byte(state, 0x11, 0x81);
tda10086_write_byte(state, 0x12, 0x81);
- tda10086_write_byte(state, 0x19, 0x40); // parallel mode A + MSBFIRST
- tda10086_write_byte(state, 0x56, 0x80); // powerdown WPLL - unused in the mode we use
- tda10086_write_byte(state, 0x57, 0x08); // bypass WPLL - unused in the mode we use
+ tda10086_write_byte(state, 0x19, 0x40); /* parallel mode A + MSBFIRST */
+ tda10086_write_byte(state, 0x56, 0x80); /* powerdown WPLL - unused in the mode we use */
+ tda10086_write_byte(state, 0x57, 0x08); /* bypass WPLL - unused in the mode we use */
tda10086_write_byte(state, 0x10, 0x2a);
- // setup ADC
- tda10086_write_byte(state, 0x58, 0x61); // ADC setup
- tda10086_write_mask(state, 0x58, 0x01, 0x00); // powerup ADC
+ /* setup ADC */
+ tda10086_write_byte(state, 0x58, 0x61); /* ADC setup */
+ tda10086_write_mask(state, 0x58, 0x01, 0x00); /* powerup ADC */
- // setup AGC
+ /* setup AGC */
tda10086_write_byte(state, 0x05, 0x0B);
tda10086_write_byte(state, 0x37, 0x63);
- tda10086_write_byte(state, 0x3f, 0x0a); // NOTE: flydvb varies it
+ tda10086_write_byte(state, 0x3f, 0x0a); /* NOTE: flydvb varies it */
tda10086_write_byte(state, 0x40, 0x64);
tda10086_write_byte(state, 0x41, 0x4f);
tda10086_write_byte(state, 0x42, 0x43);
- // setup viterbi
- tda10086_write_byte(state, 0x1a, 0x11); // VBER 10^6, DVB, QPSK
+ /* setup viterbi */
+ tda10086_write_byte(state, 0x1a, 0x11); /* VBER 10^6, DVB, QPSK */
- // setup carrier recovery
+ /* setup carrier recovery */
tda10086_write_byte(state, 0x3d, 0x80);
- // setup SEC
- tda10086_write_byte(state, 0x36, t22k_off); // all SEC off, 22k tone
- tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); // } tone frequency
- tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // }
+ /* setup SEC */
+ tda10086_write_byte(state, 0x36, t22k_off); /* all SEC off, 22k tone */
+ tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000)));
+ tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8);
return 0;
}
@@ -174,7 +179,7 @@ static void tda10086_diseqc_wait(struct tda10086_state *state)
unsigned long timeout = jiffies + msecs_to_jiffies(200);
while (!(tda10086_read_byte(state, 0x50) & 0x01)) {
if(time_after(jiffies, timeout)) {
- printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__);
+ printk("%s: diseqc queue not ready, command may be lost.\n", __func__);
break;
}
msleep(10);
@@ -186,7 +191,7 @@ static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
struct tda10086_state* state = fe->demodulator_priv;
u8 t22k_off = 0x80;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
if (state->config->diseqc_tone)
t22k_off = 0;
@@ -212,7 +217,7 @@ static int tda10086_send_master_cmd (struct dvb_frontend* fe,
u8 oldval;
u8 t22k_off = 0x80;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
if (state->config->diseqc_tone)
t22k_off = 0;
@@ -240,7 +245,7 @@ static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minic
u8 oldval = tda10086_read_byte(state, 0x36);
u8 t22k_off = 0x80;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
if (state->config->diseqc_tone)
t22k_off = 0;
@@ -267,7 +272,7 @@ static int tda10086_set_inversion(struct tda10086_state *state,
{
u8 invval = 0x80;
- dprintk ("%s %i %i\n", __FUNCTION__, fe_params->inversion, state->config->invert);
+ dprintk ("%s %i %i\n", __func__, fe_params->inversion, state->config->invert);
switch(fe_params->inversion) {
case INVERSION_OFF:
@@ -301,9 +306,9 @@ static int tda10086_set_symbol_rate(struct tda10086_state *state,
u32 bdri;
u32 symbol_rate = fe_params->u.qpsk.symbol_rate;
- dprintk ("%s %i\n", __FUNCTION__, symbol_rate);
+ dprintk ("%s %i\n", __func__, symbol_rate);
- // setup the decimation and anti-aliasing filters..
+ /* setup the decimation and anti-aliasing filters.. */
if (symbol_rate < (u32) (SACLK * 0.0137)) {
dfn=4;
afs=1;
@@ -340,13 +345,13 @@ static int tda10086_set_symbol_rate(struct tda10086_state *state,
byp=1;
}
- // calculate BDR
+ /* calculate BDR */
big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn);
big += ((SACLK/1000ULL)-1ULL);
do_div(big, (SACLK/1000ULL));
bdr = big & 0xfffff;
- // calculate BDRI
+ /* calculate BDRI */
tmp = (1<<dfn)*(symbol_rate/1000);
bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp;
@@ -367,7 +372,7 @@ static int tda10086_set_fec(struct tda10086_state *state,
{
u8 fecval;
- dprintk ("%s %i\n", __FUNCTION__, fe_params->u.qpsk.fec_inner);
+ dprintk ("%s %i\n", __func__, fe_params->u.qpsk.fec_inner);
switch(fe_params->u.qpsk.fec_inner) {
case FEC_1_2:
@@ -413,13 +418,13 @@ static int tda10086_set_frontend(struct dvb_frontend* fe,
u32 freq = 0;
int freqoff;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
- // modify parameters for tuning
+ /* modify parameters for tuning */
tda10086_write_byte(state, 0x02, 0x35);
state->has_lock = false;
- // set params
+ /* set params */
if (fe->ops.tuner_ops.set_params) {
fe->ops.tuner_ops.set_params(fe, fe_params);
if (fe->ops.i2c_gate_ctrl)
@@ -431,7 +436,7 @@ static int tda10086_set_frontend(struct dvb_frontend* fe,
fe->ops.i2c_gate_ctrl(fe, 0);
}
- // calcluate the frequency offset (in *Hz* not kHz)
+ /* calcluate the frequency offset (in *Hz* not kHz) */
freqoff = fe_params->frequency - freq;
freqoff = ((1<<16) * freqoff) / (SACLK/1000);
tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f));
@@ -444,7 +449,7 @@ static int tda10086_set_frontend(struct dvb_frontend* fe,
if ((ret = tda10086_set_fec(state, fe_params)) < 0)
return ret;
- // soft reset + disable TS output until lock
+ /* soft reset + disable TS output until lock */
tda10086_write_mask(state, 0x10, 0x40, 0x40);
tda10086_write_mask(state, 0x00, 0x01, 0x00);
@@ -460,13 +465,13 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
int tmp;
u64 tmp64;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
- // check for invalid symbol rate
+ /* check for invalid symbol rate */
if (fe_params->u.qpsk.symbol_rate < 500000)
return -EINVAL;
- // calculate the updated frequency (note: we convert from Hz->kHz)
+ /* calculate the updated frequency (note: we convert from Hz->kHz) */
tmp64 = tda10086_read_byte(state, 0x52);
tmp64 |= (tda10086_read_byte(state, 0x51) << 8);
if (tmp64 & 0x8000)
@@ -475,7 +480,7 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
do_div(tmp64, (1ULL<<15) * (1ULL<<1));
fe_params->frequency = (int) state->frequency + (int) tmp64;
- // the inversion
+ /* the inversion */
val = tda10086_read_byte(state, 0x0c);
if (val & 0x80) {
switch(val & 0x40) {
@@ -506,7 +511,7 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
}
}
- // calculate the updated symbol rate
+ /* calculate the updated symbol rate */
tmp = tda10086_read_byte(state, 0x1d);
if (tmp & 0x80)
tmp |= 0xffffff00;
@@ -514,7 +519,7 @@ static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_pa
tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000);
fe_params->u.qpsk.symbol_rate = state->symbol_rate + tmp;
- // the FEC
+ /* the FEC */
val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4;
switch(val) {
case 0x00:
@@ -551,7 +556,7 @@ static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
struct tda10086_state* state = fe->demodulator_priv;
u8 val;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
val = tda10086_read_byte(state, 0x0e);
*fe_status = 0;
@@ -567,7 +572,7 @@ static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
*fe_status |= FE_HAS_LOCK;
if (!state->has_lock) {
state->has_lock = true;
- // modify parameters for stable reception
+ /* modify parameters for stable reception */
tda10086_write_byte(state, 0x02, 0x00);
}
}
@@ -580,7 +585,7 @@ static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
struct tda10086_state* state = fe->demodulator_priv;
u8 _str;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
_str = 0xff - tda10086_read_byte(state, 0x43);
*signal = (_str << 8) | _str;
@@ -593,7 +598,7 @@ static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
struct tda10086_state* state = fe->demodulator_priv;
u8 _snr;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
_snr = 0xff - tda10086_read_byte(state, 0x1c);
*snr = (_snr << 8) | _snr;
@@ -605,12 +610,12 @@ static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
{
struct tda10086_state* state = fe->demodulator_priv;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
- // read it
+ /* read it */
*ucblocks = tda10086_read_byte(state, 0x18) & 0x7f;
- // reset counter
+ /* reset counter */
tda10086_write_byte(state, 0x18, 0x00);
tda10086_write_byte(state, 0x18, 0x80);
@@ -621,9 +626,9 @@ static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber)
{
struct tda10086_state* state = fe->demodulator_priv;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
- // read it
+ /* read it */
*ber = 0;
*ber |= tda10086_read_byte(state, 0x15);
*ber |= tda10086_read_byte(state, 0x16) << 8;
@@ -636,7 +641,7 @@ static int tda10086_sleep(struct dvb_frontend* fe)
{
struct tda10086_state* state = fe->demodulator_priv;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
tda10086_write_mask(state, 0x00, 0x08, 0x08);
@@ -647,7 +652,7 @@ static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
{
struct tda10086_state* state = fe->demodulator_priv;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
if (enable) {
tda10086_write_mask(state, 0x00, 0x10, 0x10);
@@ -738,7 +743,7 @@ struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
{
struct tda10086_state *state;
- dprintk ("%s\n", __FUNCTION__);
+ dprintk ("%s\n", __func__);
/* allocate memory for the internal state */
state = kmalloc(sizeof(struct tda10086_state), GFP_KERNEL);
diff --git a/linux/drivers/media/dvb/frontends/tda10086.h b/linux/drivers/media/dvb/frontends/tda10086.h
index eeceaeee7..61148c558 100644
--- a/linux/drivers/media/dvb/frontends/tda10086.h
+++ b/linux/drivers/media/dvb/frontends/tda10086.h
@@ -26,6 +26,11 @@
#include <linux/dvb/frontend.h>
#include <linux/firmware.h>
+enum tda10086_xtal {
+ TDA10086_XTAL_16M,
+ TDA10086_XTAL_4M
+};
+
struct tda10086_config
{
/* the demodulator's i2c address */
@@ -36,6 +41,9 @@ struct tda10086_config
/* do we need the diseqc signal with carrier? */
u8 diseqc_tone;
+
+ /* frequency of the reference xtal */
+ enum tda10086_xtal xtal_freq;
};
#if defined(CONFIG_DVB_TDA10086) || (defined(CONFIG_DVB_TDA10086_MODULE) && defined(MODULE))
@@ -45,9 +53,9 @@ extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config
static inline struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
-#endif // CONFIG_DVB_TDA10086
+#endif /* CONFIG_DVB_TDA10086 */
-#endif // TDA10086_H
+#endif /* TDA10086_H */
diff --git a/linux/drivers/media/dvb/frontends/tda18271-common.c b/linux/drivers/media/dvb/frontends/tda18271-common.c
deleted file mode 100644
index 43c0bec83..000000000
--- a/linux/drivers/media/dvb/frontends/tda18271-common.c
+++ /dev/null
@@ -1,734 +0,0 @@
-/*
- tda18271-common.c - driver for the Philips / NXP TDA18271 silicon tuner
-
- Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
-
- 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 "tda18271-priv.h"
-
-static int tda18271_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- enum tda18271_i2c_gate gate;
- int ret = 0;
-
- switch (priv->gate) {
- case TDA18271_GATE_DIGITAL:
- case TDA18271_GATE_ANALOG:
- gate = priv->gate;
- break;
- case TDA18271_GATE_AUTO:
- default:
- switch (priv->mode) {
- case TDA18271_DIGITAL:
- gate = TDA18271_GATE_DIGITAL;
- break;
- case TDA18271_ANALOG:
- default:
- gate = TDA18271_GATE_ANALOG;
- break;
- }
- }
-
- switch (gate) {
- case TDA18271_GATE_ANALOG:
- if (fe->ops.analog_ops.i2c_gate_ctrl)
- ret = fe->ops.analog_ops.i2c_gate_ctrl(fe, enable);
- break;
- case TDA18271_GATE_DIGITAL:
- if (fe->ops.i2c_gate_ctrl)
- ret = fe->ops.i2c_gate_ctrl(fe, enable);
- break;
- default:
- ret = -EINVAL;
- break;
- }
-
- return ret;
-};
-
-/*---------------------------------------------------------------------*/
-
-static void tda18271_dump_regs(struct dvb_frontend *fe, int extended)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
-
- tda_reg("=== TDA18271 REG DUMP ===\n");
- tda_reg("ID_BYTE = 0x%02x\n", 0xff & regs[R_ID]);
- tda_reg("THERMO_BYTE = 0x%02x\n", 0xff & regs[R_TM]);
- tda_reg("POWER_LEVEL_BYTE = 0x%02x\n", 0xff & regs[R_PL]);
- tda_reg("EASY_PROG_BYTE_1 = 0x%02x\n", 0xff & regs[R_EP1]);
- tda_reg("EASY_PROG_BYTE_2 = 0x%02x\n", 0xff & regs[R_EP2]);
- tda_reg("EASY_PROG_BYTE_3 = 0x%02x\n", 0xff & regs[R_EP3]);
- tda_reg("EASY_PROG_BYTE_4 = 0x%02x\n", 0xff & regs[R_EP4]);
- tda_reg("EASY_PROG_BYTE_5 = 0x%02x\n", 0xff & regs[R_EP5]);
- tda_reg("CAL_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_CPD]);
- tda_reg("CAL_DIV_BYTE_1 = 0x%02x\n", 0xff & regs[R_CD1]);
- tda_reg("CAL_DIV_BYTE_2 = 0x%02x\n", 0xff & regs[R_CD2]);
- tda_reg("CAL_DIV_BYTE_3 = 0x%02x\n", 0xff & regs[R_CD3]);
- tda_reg("MAIN_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_MPD]);
- tda_reg("MAIN_DIV_BYTE_1 = 0x%02x\n", 0xff & regs[R_MD1]);
- tda_reg("MAIN_DIV_BYTE_2 = 0x%02x\n", 0xff & regs[R_MD2]);
- tda_reg("MAIN_DIV_BYTE_3 = 0x%02x\n", 0xff & regs[R_MD3]);
-
- /* only dump extended regs if DBG_ADV is set */
- if (!(tda18271_debug & DBG_ADV))
- return;
-
- /* W indicates write-only registers.
- * Register dump for write-only registers shows last value written. */
-
- tda_reg("EXTENDED_BYTE_1 = 0x%02x\n", 0xff & regs[R_EB1]);
- tda_reg("EXTENDED_BYTE_2 = 0x%02x\n", 0xff & regs[R_EB2]);
- tda_reg("EXTENDED_BYTE_3 = 0x%02x\n", 0xff & regs[R_EB3]);
- tda_reg("EXTENDED_BYTE_4 = 0x%02x\n", 0xff & regs[R_EB4]);
- tda_reg("EXTENDED_BYTE_5 = 0x%02x\n", 0xff & regs[R_EB5]);
- tda_reg("EXTENDED_BYTE_6 = 0x%02x\n", 0xff & regs[R_EB6]);
- tda_reg("EXTENDED_BYTE_7 = 0x%02x\n", 0xff & regs[R_EB7]);
- tda_reg("EXTENDED_BYTE_8 = 0x%02x\n", 0xff & regs[R_EB8]);
- tda_reg("EXTENDED_BYTE_9 W = 0x%02x\n", 0xff & regs[R_EB9]);
- tda_reg("EXTENDED_BYTE_10 = 0x%02x\n", 0xff & regs[R_EB10]);
- tda_reg("EXTENDED_BYTE_11 = 0x%02x\n", 0xff & regs[R_EB11]);
- tda_reg("EXTENDED_BYTE_12 = 0x%02x\n", 0xff & regs[R_EB12]);
- tda_reg("EXTENDED_BYTE_13 = 0x%02x\n", 0xff & regs[R_EB13]);
- tda_reg("EXTENDED_BYTE_14 = 0x%02x\n", 0xff & regs[R_EB14]);
- tda_reg("EXTENDED_BYTE_15 = 0x%02x\n", 0xff & regs[R_EB15]);
- tda_reg("EXTENDED_BYTE_16 W = 0x%02x\n", 0xff & regs[R_EB16]);
- tda_reg("EXTENDED_BYTE_17 W = 0x%02x\n", 0xff & regs[R_EB17]);
- tda_reg("EXTENDED_BYTE_18 = 0x%02x\n", 0xff & regs[R_EB18]);
- tda_reg("EXTENDED_BYTE_19 W = 0x%02x\n", 0xff & regs[R_EB19]);
- tda_reg("EXTENDED_BYTE_20 W = 0x%02x\n", 0xff & regs[R_EB20]);
- tda_reg("EXTENDED_BYTE_21 = 0x%02x\n", 0xff & regs[R_EB21]);
- tda_reg("EXTENDED_BYTE_22 = 0x%02x\n", 0xff & regs[R_EB22]);
- tda_reg("EXTENDED_BYTE_23 = 0x%02x\n", 0xff & regs[R_EB23]);
-}
-
-int tda18271_read_regs(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- unsigned char buf = 0x00;
- int ret;
- struct i2c_msg msg[] = {
- { .addr = priv->i2c_props.addr, .flags = 0,
- .buf = &buf, .len = 1 },
- { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
- .buf = regs, .len = 16 }
- };
-
- tda18271_i2c_gate_ctrl(fe, 1);
-
- /* read all registers */
- ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
-
- tda18271_i2c_gate_ctrl(fe, 0);
-
- if (ret != 2)
- tda_err("ERROR: i2c_transfer returned: %d\n", ret);
-
- if (tda18271_debug & DBG_REG)
- tda18271_dump_regs(fe, 0);
-
- return (ret == 2 ? 0 : ret);
-}
-
-int tda18271_read_extended(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- unsigned char regdump[TDA18271_NUM_REGS];
- unsigned char buf = 0x00;
- int ret, i;
- struct i2c_msg msg[] = {
- { .addr = priv->i2c_props.addr, .flags = 0,
- .buf = &buf, .len = 1 },
- { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
- .buf = regdump, .len = TDA18271_NUM_REGS }
- };
-
- tda18271_i2c_gate_ctrl(fe, 1);
-
- /* read all registers */
- ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
-
- tda18271_i2c_gate_ctrl(fe, 0);
-
- if (ret != 2)
- tda_err("ERROR: i2c_transfer returned: %d\n", ret);
-
- for (i = 0; i < TDA18271_NUM_REGS; i++) {
- /* don't update write-only registers */
- if ((i != R_EB9) &&
- (i != R_EB16) &&
- (i != R_EB17) &&
- (i != R_EB19) &&
- (i != R_EB20))
- regs[i] = regdump[i];
- }
-
- if (tda18271_debug & DBG_REG)
- tda18271_dump_regs(fe, 1);
-
- return (ret == 2 ? 0 : ret);
-}
-
-int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- unsigned char buf[TDA18271_NUM_REGS + 1];
- struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0,
- .buf = buf, .len = len + 1 };
- int i, ret;
-
- BUG_ON((len == 0) || (idx + len > sizeof(buf)));
-
- buf[0] = idx;
- for (i = 1; i <= len; i++)
- buf[i] = regs[idx - 1 + i];
-
- tda18271_i2c_gate_ctrl(fe, 1);
-
- /* write registers */
- ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
-
- tda18271_i2c_gate_ctrl(fe, 0);
-
- if (ret != 1)
- tda_err("ERROR: i2c_transfer returned: %d\n", ret);
-
- return (ret == 1 ? 0 : ret);
-}
-
-/*---------------------------------------------------------------------*/
-
-int tda18271_charge_pump_source(struct dvb_frontend *fe,
- enum tda18271_pll pll, int force)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
-
- int r_cp = (pll == TDA18271_CAL_PLL) ? R_EB7 : R_EB4;
-
- regs[r_cp] &= ~0x20;
- regs[r_cp] |= ((force & 1) << 5);
- tda18271_write_regs(fe, r_cp, 1);
-
- return 0;
-}
-
-int tda18271_init_regs(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
-
- tda_dbg("initializing registers for device @ %d-%04x\n",
- i2c_adapter_id(priv->i2c_props.adap),
- priv->i2c_props.addr);
-
- /* initialize registers */
- switch (priv->id) {
- case TDA18271HDC1:
- regs[R_ID] = 0x83;
- break;
- case TDA18271HDC2:
- regs[R_ID] = 0x84;
- break;
- };
-
- regs[R_TM] = 0x08;
- regs[R_PL] = 0x80;
- regs[R_EP1] = 0xc6;
- regs[R_EP2] = 0xdf;
- regs[R_EP3] = 0x16;
- regs[R_EP4] = 0x60;
- regs[R_EP5] = 0x80;
- regs[R_CPD] = 0x80;
- regs[R_CD1] = 0x00;
- regs[R_CD2] = 0x00;
- regs[R_CD3] = 0x00;
- regs[R_MPD] = 0x00;
- regs[R_MD1] = 0x00;
- regs[R_MD2] = 0x00;
- regs[R_MD3] = 0x00;
-
- switch (priv->id) {
- case TDA18271HDC1:
- regs[R_EB1] = 0xff;
- break;
- case TDA18271HDC2:
- regs[R_EB1] = 0xfc;
- break;
- };
-
- regs[R_EB2] = 0x01;
- regs[R_EB3] = 0x84;
- regs[R_EB4] = 0x41;
- regs[R_EB5] = 0x01;
- regs[R_EB6] = 0x84;
- regs[R_EB7] = 0x40;
- regs[R_EB8] = 0x07;
- regs[R_EB9] = 0x00;
- regs[R_EB10] = 0x00;
- regs[R_EB11] = 0x96;
-
- switch (priv->id) {
- case TDA18271HDC1:
- regs[R_EB12] = 0x0f;
- break;
- case TDA18271HDC2:
- regs[R_EB12] = 0x33;
- break;
- };
-
- regs[R_EB13] = 0xc1;
- regs[R_EB14] = 0x00;
- regs[R_EB15] = 0x8f;
- regs[R_EB16] = 0x00;
- regs[R_EB17] = 0x00;
-
- switch (priv->id) {
- case TDA18271HDC1:
- regs[R_EB18] = 0x00;
- break;
- case TDA18271HDC2:
- regs[R_EB18] = 0x8c;
- break;
- };
-
- regs[R_EB19] = 0x00;
- regs[R_EB20] = 0x20;
-
- switch (priv->id) {
- case TDA18271HDC1:
- regs[R_EB21] = 0x33;
- break;
- case TDA18271HDC2:
- regs[R_EB21] = 0xb3;
- break;
- };
-
- regs[R_EB22] = 0x48;
- regs[R_EB23] = 0xb0;
-
- if (priv->small_i2c) {
- tda18271_write_regs(fe, 0x00, 0x10);
- tda18271_write_regs(fe, 0x10, 0x10);
- tda18271_write_regs(fe, 0x20, 0x07);
- } else
- tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
-
- /* setup agc1 gain */
- regs[R_EB17] = 0x00;
- tda18271_write_regs(fe, R_EB17, 1);
- regs[R_EB17] = 0x03;
- tda18271_write_regs(fe, R_EB17, 1);
- regs[R_EB17] = 0x43;
- tda18271_write_regs(fe, R_EB17, 1);
- regs[R_EB17] = 0x4c;
- tda18271_write_regs(fe, R_EB17, 1);
-
- /* setup agc2 gain */
- if ((priv->id) == TDA18271HDC1) {
- regs[R_EB20] = 0xa0;
- tda18271_write_regs(fe, R_EB20, 1);
- regs[R_EB20] = 0xa7;
- tda18271_write_regs(fe, R_EB20, 1);
- regs[R_EB20] = 0xe7;
- tda18271_write_regs(fe, R_EB20, 1);
- regs[R_EB20] = 0xec;
- tda18271_write_regs(fe, R_EB20, 1);
- }
-
- /* image rejection calibration */
-
- /* low-band */
- regs[R_EP3] = 0x1f;
- regs[R_EP4] = 0x66;
- regs[R_EP5] = 0x81;
- regs[R_CPD] = 0xcc;
- regs[R_CD1] = 0x6c;
- regs[R_CD2] = 0x00;
- regs[R_CD3] = 0x00;
- regs[R_MPD] = 0xcd;
- regs[R_MD1] = 0x77;
- regs[R_MD2] = 0x08;
- regs[R_MD3] = 0x00;
-
- tda18271_write_regs(fe, R_EP3, 11);
-
- if ((priv->id) == TDA18271HDC2) {
- /* main pll cp source on */
- tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1);
- msleep(1);
-
- /* main pll cp source off */
- tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0);
- }
-
- msleep(5); /* pll locking */
-
- /* launch detector */
-#if 0
- regs[R_EP1] = 0xc6; /* already set */
-#endif
- tda18271_write_regs(fe, R_EP1, 1);
- msleep(5); /* wanted low measurement */
-
-#if 0
- regs[R_EP3] = 0x1f; /* already set */
- regs[R_EP4] = 0x66; /* already set */
-#endif
- regs[R_EP5] = 0x85;
- regs[R_CPD] = 0xcb;
- regs[R_CD1] = 0x66;
- regs[R_CD2] = 0x70;
-#if 0
- regs[R_CD3] = 0x00; /* already set */
-#endif
-
- tda18271_write_regs(fe, R_EP3, 7);
- msleep(5); /* pll locking */
-
- /* launch optimization algorithm */
-#if 0
- regs[R_EP2] = 0xdf; /* already set */
-#endif
- tda18271_write_regs(fe, R_EP2, 1);
- msleep(30); /* image low optimization completion */
-
- /* mid-band */
-#if 0
- regs[R_EP3] = 0x1f; /* already set */
- regs[R_EP4] = 0x66; /* already set */
-#endif
- regs[R_EP5] = 0x82;
- regs[R_CPD] = 0xa8;
-#if 0
- regs[R_CD1] = 0x66; /* already set */
-#endif
- regs[R_CD2] = 0x00;
-#if 0
- regs[R_CD3] = 0x00; /* already set */
-#endif
- regs[R_MPD] = 0xa9;
- regs[R_MD1] = 0x73;
- regs[R_MD2] = 0x1a;
-#if 0
- regs[R_MD3] = 0x00; /* already set */
-#endif
-
- tda18271_write_regs(fe, R_EP3, 11);
- msleep(5); /* pll locking */
-
- /* launch detector */
-#if 0
- regs[R_EP1] = 0xc6; /* already set */
-#endif
- tda18271_write_regs(fe, R_EP1, 1);
- msleep(5); /* wanted mid measurement */
-
-#if 0
- regs[R_EP3] = 0x1f; /* already set */
- regs[R_EP4] = 0x66; /* already set */
-#endif
- regs[R_EP5] = 0x86;
- regs[R_CPD] = 0xa8;
- regs[R_CD1] = 0x66;
- regs[R_CD2] = 0xa0;
-#if 0
- regs[R_CD3] = 0x00; /* already set */
-#endif
-
- tda18271_write_regs(fe, R_EP3, 7);
- msleep(5); /* pll locking */
-
- /* launch optimization algorithm */
-#if 0
- regs[R_EP2] = 0xdf; /* already set */
-#endif
- tda18271_write_regs(fe, R_EP2, 1);
- msleep(30); /* image mid optimization completion */
-
- /* high-band */
-#if 0
- regs[R_EP3] = 0x1f; /* already set */
- regs[R_EP4] = 0x66; /* already set */
-#endif
- regs[R_EP5] = 0x83;
- regs[R_CPD] = 0x98;
- regs[R_CD1] = 0x65;
- regs[R_CD2] = 0x00;
-#if 0
- regs[R_CD3] = 0x00; /* already set */
-#endif
- regs[R_MPD] = 0x99;
- regs[R_MD1] = 0x71;
- regs[R_MD2] = 0xcd;
-#if 0
- regs[R_MD3] = 0x00; /* already set */
-#endif
-
- tda18271_write_regs(fe, R_EP3, 11);
- msleep(5); /* pll locking */
-
- /* launch detector */
-#if 0
- regs[R_EP1] = 0xc6; /* already set */
-#endif
- tda18271_write_regs(fe, R_EP1, 1);
- msleep(5); /* wanted high measurement */
-
-#if 0
- regs[R_EP3] = 0x1f; /* already set */
- regs[R_EP4] = 0x66; /* already set */
-#endif
- regs[R_EP5] = 0x87;
-#if 0
- regs[R_CPD] = 0x98; /* already set */
-#endif
- regs[R_CD1] = 0x65;
- regs[R_CD2] = 0x50;
-#if 0
- regs[R_CD3] = 0x00; /* already set */
-#endif
-
- tda18271_write_regs(fe, R_EP3, 7);
- msleep(5); /* pll locking */
-
- /* launch optimization algorithm */
-#if 0
- regs[R_EP2] = 0xdf; /* already set */
-#endif
- tda18271_write_regs(fe, R_EP2, 1);
- msleep(30); /* image high optimization completion */
-
- /* return to normal mode */
- regs[R_EP4] = 0x64;
- tda18271_write_regs(fe, R_EP4, 1);
-
- /* synchronize */
-#if 0
- regs[R_EP1] = 0xc6; /* already set */
-#endif
- tda18271_write_regs(fe, R_EP1, 1);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------*/
-
-/*
- * Standby modes, EP3 [7:5]
- *
- * | SM || SM_LT || SM_XT || mode description
- * |=====\\=======\\=======\\===================================
- * | 0 || 0 || 0 || normal mode
- * |-----||-------||-------||-----------------------------------
- * | || || || standby mode w/ slave tuner output
- * | 1 || 0 || 0 || & loop thru & xtal oscillator on
- * |-----||-------||-------||-----------------------------------
- * | 1 || 1 || 0 || standby mode w/ xtal oscillator on
- * |-----||-------||-------||-----------------------------------
- * | 1 || 1 || 1 || power off
- *
- */
-
-int tda18271_set_standby_mode(struct dvb_frontend *fe,
- int sm, int sm_lt, int sm_xt)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
-
- tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
-
- regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */
- regs[R_EP3] |= sm ? (1 << 7) : 0 |
- sm_lt ? (1 << 6) : 0 |
- sm_xt ? (1 << 5) : 0;
-
- tda18271_write_regs(fe, R_EP3, 1);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------*/
-
-int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq)
-{
- /* sets main post divider & divider bytes, but does not write them */
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u8 d, pd;
- u32 div;
-
- int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d);
- if (ret < 0)
- goto fail;
-
- regs[R_MPD] = (0x77 & pd);
-
- switch (priv->mode) {
- case TDA18271_ANALOG:
- regs[R_MPD] &= ~0x08;
- break;
- case TDA18271_DIGITAL:
- regs[R_MPD] |= 0x08;
- break;
- }
-
- div = ((d * (freq / 1000)) << 7) / 125;
-
- regs[R_MD1] = 0x7f & (div >> 16);
- regs[R_MD2] = 0xff & (div >> 8);
- regs[R_MD3] = 0xff & div;
-fail:
- return ret;
-}
-
-int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq)
-{
- /* sets cal post divider & divider bytes, but does not write them */
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u8 d, pd;
- u32 div;
-
- int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d);
- if (ret < 0)
- goto fail;
-
- regs[R_CPD] = pd;
-
- div = ((d * (freq / 1000)) << 7) / 125;
-
- regs[R_CD1] = 0x7f & (div >> 16);
- regs[R_CD2] = 0xff & (div >> 8);
- regs[R_CD3] = 0xff & div;
-fail:
- return ret;
-}
-
-/*---------------------------------------------------------------------*/
-
-int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq)
-{
- /* sets bp filter bits, but does not write them */
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u8 val;
-
- int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val);
- if (ret < 0)
- goto fail;
-
- regs[R_EP1] &= ~0x07; /* clear bp filter bits */
- regs[R_EP1] |= (0x07 & val);
-fail:
- return ret;
-}
-
-int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq)
-{
- /* sets K & M bits, but does not write them */
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u8 val;
-
- int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val);
- if (ret < 0)
- goto fail;
-
- regs[R_EB13] &= ~0x7c; /* clear k & m bits */
- regs[R_EB13] |= (0x7c & val);
-fail:
- return ret;
-}
-
-int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq)
-{
- /* sets rf band bits, but does not write them */
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u8 val;
-
- int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val);
- if (ret < 0)
- goto fail;
-
- regs[R_EP2] &= ~0xe0; /* clear rf band bits */
- regs[R_EP2] |= (0xe0 & (val << 5));
-fail:
- return ret;
-}
-
-int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq)
-{
- /* sets gain taper bits, but does not write them */
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u8 val;
-
- int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val);
- if (ret < 0)
- goto fail;
-
- regs[R_EP2] &= ~0x1f; /* clear gain taper bits */
- regs[R_EP2] |= (0x1f & val);
-fail:
- return ret;
-}
-
-int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq)
-{
- /* sets IR Meas bits, but does not write them */
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u8 val;
-
- int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val);
- if (ret < 0)
- goto fail;
-
- regs[R_EP5] &= ~0x07;
- regs[R_EP5] |= (0x07 & val);
-fail:
- return ret;
-}
-
-int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq)
-{
- /* sets rf cal byte (RFC_Cprog), but does not write it */
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u8 val;
-
- tda18271_lookup_map(fe, RF_CAL, freq, &val);
-
- regs[R_EB14] = val;
-
- return 0;
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/linux/drivers/media/dvb/frontends/tda18271-fe.c b/linux/drivers/media/dvb/frontends/tda18271-fe.c
deleted file mode 100644
index 355c37a42..000000000
--- a/linux/drivers/media/dvb/frontends/tda18271-fe.c
+++ /dev/null
@@ -1,1154 +0,0 @@
-/*
- tda18271-fe.c - driver for the Philips / NXP TDA18271 silicon tuner
-
- Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
-
- 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/delay.h>
-#include "compat.h"
-#include <linux/videodev2.h>
-#include "tda18271-priv.h"
-
-int tda18271_debug;
-module_param_named(debug, tda18271_debug, int, 0644);
-MODULE_PARM_DESC(debug, "set debug level "
- "(info=1, map=2, reg=4, adv=8, cal=16 (or-able))");
-
-static int tda18271_cal_on_startup;
-module_param_named(cal, tda18271_cal_on_startup, int, 0644);
-MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");
-
-static DEFINE_MUTEX(tda18271_list_mutex);
-static LIST_HEAD(hybrid_tuner_instance_list);
-
-/*---------------------------------------------------------------------*/
-
-static inline int charge_pump_source(struct dvb_frontend *fe, int force)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- return tda18271_charge_pump_source(fe,
- (priv->role == TDA18271_SLAVE) ?
- TDA18271_CAL_PLL :
- TDA18271_MAIN_PLL, force);
-}
-
-static int tda18271_channel_configuration(struct dvb_frontend *fe,
- struct tda18271_std_map_item *map,
- u32 freq, u32 bw)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u32 N;
-
- /* update TV broadcast parameters */
-
- /* set standard */
- regs[R_EP3] &= ~0x1f; /* clear std bits */
- regs[R_EP3] |= (map->agc_mode << 3) | map->std;
-
- /* set rfagc to high speed mode */
- regs[R_EP3] &= ~0x04;
-
- /* set cal mode to normal */
- regs[R_EP4] &= ~0x03;
-
- /* update IF output level & IF notch frequency */
- regs[R_EP4] &= ~0x1c; /* clear if level bits */
- regs[R_EP4] |= (map->if_lvl << 2);
-
- switch (priv->mode) {
- case TDA18271_ANALOG:
- regs[R_MPD] &= ~0x80; /* IF notch = 0 */
- break;
- case TDA18271_DIGITAL:
- regs[R_MPD] |= 0x80; /* IF notch = 1 */
- break;
- }
-
- /* update FM_RFn */
- regs[R_EP4] &= ~0x80;
- regs[R_EP4] |= map->fm_rfn << 7;
-
- /* update rf top / if top */
- regs[R_EB22] = 0x00;
- regs[R_EB22] |= map->rfagc_top;
- tda18271_write_regs(fe, R_EB22, 1);
-
- /* --------------------------------------------------------------- */
-
- /* disable Power Level Indicator */
- regs[R_EP1] |= 0x40;
-
- /* frequency dependent parameters */
-
- tda18271_calc_ir_measure(fe, &freq);
-
- tda18271_calc_bp_filter(fe, &freq);
-
- tda18271_calc_rf_band(fe, &freq);
-
- tda18271_calc_gain_taper(fe, &freq);
-
- /* --------------------------------------------------------------- */
-
- /* dual tuner and agc1 extra configuration */
-
- switch (priv->role) {
- case TDA18271_MASTER:
- regs[R_EB1] |= 0x04; /* main vco */
- break;
- case TDA18271_SLAVE:
- regs[R_EB1] &= ~0x04; /* cal vco */
- break;
- }
-
- /* agc1 always active */
- regs[R_EB1] &= ~0x02;
-
- /* agc1 has priority on agc2 */
- regs[R_EB1] &= ~0x01;
-
- tda18271_write_regs(fe, R_EB1, 1);
-
- /* --------------------------------------------------------------- */
-
- N = map->if_freq * 1000 + freq;
-
- switch (priv->role) {
- case TDA18271_MASTER:
- tda18271_calc_main_pll(fe, N);
- tda18271_write_regs(fe, R_MPD, 4);
- break;
- case TDA18271_SLAVE:
- tda18271_calc_cal_pll(fe, N);
- tda18271_write_regs(fe, R_CPD, 4);
-
- regs[R_MPD] = regs[R_CPD] & 0x7f;
- tda18271_write_regs(fe, R_MPD, 1);
- break;
- }
-
- tda18271_write_regs(fe, R_TM, 7);
-
- /* force charge pump source */
- charge_pump_source(fe, 1);
-
- msleep(1);
-
- /* return pll to normal operation */
- charge_pump_source(fe, 0);
-
- msleep(20);
-
- /* set rfagc to normal speed mode */
- if (map->fm_rfn)
- regs[R_EP3] &= ~0x04;
- else
- regs[R_EP3] |= 0x04;
- tda18271_write_regs(fe, R_EP3, 1);
-
- return 0;
-}
-
-static int tda18271_read_thermometer(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- int tm;
-
- /* switch thermometer on */
- regs[R_TM] |= 0x10;
- tda18271_write_regs(fe, R_TM, 1);
-
- /* read thermometer info */
- tda18271_read_regs(fe);
-
- if ((((regs[R_TM] & 0x0f) == 0x00) && ((regs[R_TM] & 0x20) == 0x20)) ||
- (((regs[R_TM] & 0x0f) == 0x08) && ((regs[R_TM] & 0x20) == 0x00))) {
-
- if ((regs[R_TM] & 0x20) == 0x20)
- regs[R_TM] &= ~0x20;
- else
- regs[R_TM] |= 0x20;
-
- tda18271_write_regs(fe, R_TM, 1);
-
- msleep(10); /* temperature sensing */
-
- /* read thermometer info */
- tda18271_read_regs(fe);
- }
-
- tm = tda18271_lookup_thermometer(fe);
-
- /* switch thermometer off */
- regs[R_TM] &= ~0x10;
- tda18271_write_regs(fe, R_TM, 1);
-
- /* set CAL mode to normal */
- regs[R_EP4] &= ~0x03;
- tda18271_write_regs(fe, R_EP4, 1);
-
- return tm;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
- u32 freq)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
- unsigned char *regs = priv->tda18271_regs;
- int tm_current, rfcal_comp, approx, i;
- u8 dc_over_dt, rf_tab;
-
- /* power up */
- tda18271_set_standby_mode(fe, 0, 0, 0);
-
- /* read die current temperature */
- tm_current = tda18271_read_thermometer(fe);
-
- /* frequency dependent parameters */
-
- tda18271_calc_rf_cal(fe, &freq);
- rf_tab = regs[R_EB14];
-
- i = tda18271_lookup_rf_band(fe, &freq, NULL);
- if (i < 0)
- return -EINVAL;
-
- if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
- approx = map[i].rf_a1 *
- (freq / 1000 - map[i].rf1) + map[i].rf_b1 + rf_tab;
- } else {
- approx = map[i].rf_a2 *
- (freq / 1000 - map[i].rf2) + map[i].rf_b2 + rf_tab;
- }
-
- if (approx < 0)
- approx = 0;
- if (approx > 255)
- approx = 255;
-
- tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
-
- /* calculate temperature compensation */
- rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal);
-
- regs[R_EB14] = approx + rfcal_comp;
- tda18271_write_regs(fe, R_EB14, 1);
-
- return 0;
-}
-
-static int tda18271_por(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
-
- /* power up detector 1 */
- regs[R_EB12] &= ~0x20;
- tda18271_write_regs(fe, R_EB12, 1);
-
- regs[R_EB18] &= ~0x80; /* turn agc1 loop on */
- regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */
- tda18271_write_regs(fe, R_EB18, 1);
-
- regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */
-
- /* POR mode */
- tda18271_set_standby_mode(fe, 1, 0, 0);
-
- /* disable 1.5 MHz low pass filter */
- regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */
- regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */
- tda18271_write_regs(fe, R_EB21, 3);
-
- return 0;
-}
-
-static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u32 N;
-
- /* set CAL mode to normal */
- regs[R_EP4] &= ~0x03;
- tda18271_write_regs(fe, R_EP4, 1);
-
- /* switch off agc1 */
- regs[R_EP3] |= 0x40; /* sm_lt = 1 */
-
- regs[R_EB18] |= 0x03; /* set agc1_gain to 15 dB */
- tda18271_write_regs(fe, R_EB18, 1);
-
- /* frequency dependent parameters */
-
- tda18271_calc_bp_filter(fe, &freq);
- tda18271_calc_gain_taper(fe, &freq);
- tda18271_calc_rf_band(fe, &freq);
- tda18271_calc_km(fe, &freq);
-
- tda18271_write_regs(fe, R_EP1, 3);
- tda18271_write_regs(fe, R_EB13, 1);
-
- /* main pll charge pump source */
- tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1);
-
- /* cal pll charge pump source */
- tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 1);
-
- /* force dcdc converter to 0 V */
- regs[R_EB14] = 0x00;
- tda18271_write_regs(fe, R_EB14, 1);
-
- /* disable plls lock */
- regs[R_EB20] &= ~0x20;
- tda18271_write_regs(fe, R_EB20, 1);
-
- /* set CAL mode to RF tracking filter calibration */
- regs[R_EP4] |= 0x03;
- tda18271_write_regs(fe, R_EP4, 2);
-
- /* --------------------------------------------------------------- */
-
- /* set the internal calibration signal */
- N = freq;
-
- tda18271_calc_cal_pll(fe, N);
- tda18271_write_regs(fe, R_CPD, 4);
-
- /* downconvert internal calibration */
- N += 1000000;
-
- tda18271_calc_main_pll(fe, N);
- tda18271_write_regs(fe, R_MPD, 4);
-
- msleep(5);
-
- tda18271_write_regs(fe, R_EP2, 1);
- tda18271_write_regs(fe, R_EP1, 1);
- tda18271_write_regs(fe, R_EP2, 1);
- tda18271_write_regs(fe, R_EP1, 1);
-
- /* --------------------------------------------------------------- */
-
- /* normal operation for the main pll */
- tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0);
-
- /* normal operation for the cal pll */
- tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 0);
-
- msleep(10); /* plls locking */
-
- /* launch the rf tracking filters calibration */
- regs[R_EB20] |= 0x20;
- tda18271_write_regs(fe, R_EB20, 1);
-
- msleep(60); /* calibration */
-
- /* --------------------------------------------------------------- */
-
- /* set CAL mode to normal */
- regs[R_EP4] &= ~0x03;
-
- /* switch on agc1 */
- regs[R_EP3] &= ~0x40; /* sm_lt = 0 */
-
- regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */
- tda18271_write_regs(fe, R_EB18, 1);
-
- tda18271_write_regs(fe, R_EP3, 2);
-
- /* synchronization */
- tda18271_write_regs(fe, R_EP1, 1);
-
- /* get calibration result */
- tda18271_read_extended(fe);
-
- return regs[R_EB14];
-}
-
-static int tda18271_powerscan(struct dvb_frontend *fe,
- u32 *freq_in, u32 *freq_out)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- int sgn, bcal, count, wait;
- u8 cid_target;
- u16 count_limit;
- u32 freq;
-
- freq = *freq_in;
-
- tda18271_calc_rf_band(fe, &freq);
- tda18271_calc_rf_cal(fe, &freq);
- tda18271_calc_gain_taper(fe, &freq);
- tda18271_lookup_cid_target(fe, &freq, &cid_target, &count_limit);
-
- tda18271_write_regs(fe, R_EP2, 1);
- tda18271_write_regs(fe, R_EB14, 1);
-
- /* downconvert frequency */
- freq += 1000000;
-
- tda18271_calc_main_pll(fe, freq);
- tda18271_write_regs(fe, R_MPD, 4);
-
- msleep(5); /* pll locking */
-
- /* detection mode */
- regs[R_EP4] &= ~0x03;
- regs[R_EP4] |= 0x01;
- tda18271_write_regs(fe, R_EP4, 1);
-
- /* launch power detection measurement */
- tda18271_write_regs(fe, R_EP2, 1);
-
- /* read power detection info, stored in EB10 */
- tda18271_read_extended(fe);
-
- /* algorithm initialization */
- sgn = 1;
- *freq_out = *freq_in;
- bcal = 0;
- count = 0;
- wait = false;
-
- while ((regs[R_EB10] & 0x3f) < cid_target) {
- /* downconvert updated freq to 1 MHz */
- freq = *freq_in + (sgn * count) + 1000000;
-
- tda18271_calc_main_pll(fe, freq);
- tda18271_write_regs(fe, R_MPD, 4);
-
- if (wait) {
- msleep(5); /* pll locking */
- wait = false;
- } else
- udelay(100); /* pll locking */
-
- /* launch power detection measurement */
- tda18271_write_regs(fe, R_EP2, 1);
-
- /* read power detection info, stored in EB10 */
- tda18271_read_extended(fe);
-
- count += 200;
-
- if (count <= count_limit)
- continue;
-
- if (sgn <= 0)
- break;
-
- sgn = -1 * sgn;
- count = 200;
- wait = true;
- }
-
- if ((regs[R_EB10] & 0x3f) >= cid_target) {
- bcal = 1;
- *freq_out = freq - 1000000;
- } else
- bcal = 0;
-
- tda_cal("bcal = %d, freq_in = %d, freq_out = %d (freq = %d)\n",
- bcal, *freq_in, *freq_out, freq);
-
- return bcal;
-}
-
-static int tda18271_powerscan_init(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
-
- /* set standard to digital */
- regs[R_EP3] &= ~0x1f; /* clear std bits */
- regs[R_EP3] |= 0x12;
-
- /* set cal mode to normal */
- regs[R_EP4] &= ~0x03;
-
- /* update IF output level & IF notch frequency */
- regs[R_EP4] &= ~0x1c; /* clear if level bits */
-
- tda18271_write_regs(fe, R_EP3, 2);
-
- regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */
- tda18271_write_regs(fe, R_EB18, 1);
-
- regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */
-
- /* 1.5 MHz low pass filter */
- regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */
- regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */
-
- tda18271_write_regs(fe, R_EB21, 3);
-
- return 0;
-}
-
-static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
- unsigned char *regs = priv->tda18271_regs;
- int bcal, rf, i;
-#define RF1 0
-#define RF2 1
-#define RF3 2
- u32 rf_default[3];
- u32 rf_freq[3];
- u8 prog_cal[3];
- u8 prog_tab[3];
-
- i = tda18271_lookup_rf_band(fe, &freq, NULL);
-
- if (i < 0)
- return i;
-
- rf_default[RF1] = 1000 * map[i].rf1_def;
- rf_default[RF2] = 1000 * map[i].rf2_def;
- rf_default[RF3] = 1000 * map[i].rf3_def;
-
- for (rf = RF1; rf <= RF3; rf++) {
- if (0 == rf_default[rf])
- return 0;
- tda_cal("freq = %d, rf = %d\n", freq, rf);
-
- /* look for optimized calibration frequency */
- bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]);
-
- tda18271_calc_rf_cal(fe, &rf_freq[rf]);
- prog_tab[rf] = regs[R_EB14];
-
- if (1 == bcal)
- prog_cal[rf] = tda18271_calibrate_rf(fe, rf_freq[rf]);
- else
- prog_cal[rf] = prog_tab[rf];
-
- switch (rf) {
- case RF1:
- map[i].rf_a1 = 0;
- map[i].rf_b1 = prog_cal[RF1] - prog_tab[RF1];
- map[i].rf1 = rf_freq[RF1] / 1000;
- break;
- case RF2:
- map[i].rf_a1 = (prog_cal[RF2] - prog_tab[RF2] -
- prog_cal[RF1] + prog_tab[RF1]) /
- ((rf_freq[RF2] - rf_freq[RF1]) / 1000);
- map[i].rf2 = rf_freq[RF2] / 1000;
- break;
- case RF3:
- map[i].rf_a2 = (prog_cal[RF3] - prog_tab[RF3] -
- prog_cal[RF2] + prog_tab[RF2]) /
- ((rf_freq[RF3] - rf_freq[RF2]) / 1000);
- map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2];
- map[i].rf3 = rf_freq[RF3] / 1000;
- break;
- default:
- BUG();
- }
- }
-
- return 0;
-}
-
-static int tda18271_calc_rf_filter_curve(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned int i;
-
- tda_info("tda18271: performing RF tracking filter calibration\n");
-
- /* wait for die temperature stabilization */
- msleep(200);
-
- tda18271_powerscan_init(fe);
-
- /* rf band calibration */
- for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++)
- tda18271_rf_tracking_filters_init(fe, 1000 *
- priv->rf_cal_state[i].rfmax);
-
- priv->tm_rfcal = tda18271_read_thermometer(fe);
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda18271c2_rf_cal_init(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
-
- /* test RF_CAL_OK to see if we need init */
- if ((regs[R_EP1] & 0x10) == 0)
- priv->cal_initialized = false;
-
- if (priv->cal_initialized)
- return 0;
-
- tda18271_calc_rf_filter_curve(fe);
-
- tda18271_por(fe);
-
- tda_info("tda18271: RF tracking filter calibration complete\n");
-
- priv->cal_initialized = true;
-
- return 0;
-}
-
-static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
- u32 freq, u32 bw)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- u32 N = 0;
-
- /* calculate bp filter */
- tda18271_calc_bp_filter(fe, &freq);
- tda18271_write_regs(fe, R_EP1, 1);
-
- regs[R_EB4] &= 0x07;
- regs[R_EB4] |= 0x60;
- tda18271_write_regs(fe, R_EB4, 1);
-
- regs[R_EB7] = 0x60;
- tda18271_write_regs(fe, R_EB7, 1);
-
- regs[R_EB14] = 0x00;
- tda18271_write_regs(fe, R_EB14, 1);
-
- regs[R_EB20] = 0xcc;
- tda18271_write_regs(fe, R_EB20, 1);
-
- /* set cal mode to RF tracking filter calibration */
- regs[R_EP4] |= 0x03;
-
- /* calculate cal pll */
-
- switch (priv->mode) {
- case TDA18271_ANALOG:
- N = freq - 1250000;
- break;
- case TDA18271_DIGITAL:
- N = freq + bw / 2;
- break;
- }
-
- tda18271_calc_cal_pll(fe, N);
-
- /* calculate main pll */
-
- switch (priv->mode) {
- case TDA18271_ANALOG:
- N = freq - 250000;
- break;
- case TDA18271_DIGITAL:
- N = freq + bw / 2 + 1000000;
- break;
- }
-
- tda18271_calc_main_pll(fe, N);
-
- tda18271_write_regs(fe, R_EP3, 11);
- msleep(5); /* RF tracking filter calibration initialization */
-
- /* search for K,M,CO for RF calibration */
- tda18271_calc_km(fe, &freq);
- tda18271_write_regs(fe, R_EB13, 1);
-
- /* search for rf band */
- tda18271_calc_rf_band(fe, &freq);
-
- /* search for gain taper */
- tda18271_calc_gain_taper(fe, &freq);
-
- tda18271_write_regs(fe, R_EP2, 1);
- tda18271_write_regs(fe, R_EP1, 1);
- tda18271_write_regs(fe, R_EP2, 1);
- tda18271_write_regs(fe, R_EP1, 1);
-
- regs[R_EB4] &= 0x07;
- regs[R_EB4] |= 0x40;
- tda18271_write_regs(fe, R_EB4, 1);
-
- regs[R_EB7] = 0x40;
- tda18271_write_regs(fe, R_EB7, 1);
- msleep(10); /* pll locking */
-
- regs[R_EB20] = 0xec;
- tda18271_write_regs(fe, R_EB20, 1);
- msleep(60); /* RF tracking filter calibration completion */
-
- regs[R_EP4] &= ~0x03; /* set cal mode to normal */
- tda18271_write_regs(fe, R_EP4, 1);
-
- tda18271_write_regs(fe, R_EP1, 1);
-
- /* RF tracking filter correction for VHF_Low band */
- if (0 == tda18271_calc_rf_cal(fe, &freq))
- tda18271_write_regs(fe, R_EB14, 1);
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda18271_ir_cal_init(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
-
- tda18271_read_regs(fe);
-
- /* test IR_CAL_OK to see if we need init */
- if ((regs[R_EP1] & 0x08) == 0)
- tda18271_init_regs(fe);
-
- return 0;
-}
-
-static int tda18271_init(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
-
- mutex_lock(&priv->lock);
-
- /* power up */
- tda18271_set_standby_mode(fe, 0, 0, 0);
-
- /* initialization */
- tda18271_ir_cal_init(fe);
-
- if (priv->id == TDA18271HDC2)
- tda18271c2_rf_cal_init(fe);
-
- mutex_unlock(&priv->lock);
-
- return 0;
-}
-
-static int tda18271_tune(struct dvb_frontend *fe,
- struct tda18271_std_map_item *map, u32 freq, u32 bw)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
-
- tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
- freq, map->if_freq, bw, map->agc_mode, map->std);
-
- tda18271_init(fe);
-
- mutex_lock(&priv->lock);
-
- switch (priv->id) {
- case TDA18271HDC1:
- tda18271c1_rf_tracking_filter_calibration(fe, freq, bw);
- break;
- case TDA18271HDC2:
- tda18271c2_rf_tracking_filters_correction(fe, freq);
- break;
- }
- tda18271_channel_configuration(fe, map, freq, bw);
-
- mutex_unlock(&priv->lock);
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda18271_set_params(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *params)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- struct tda18271_std_map *std_map = &priv->std;
- struct tda18271_std_map_item *map;
- int ret;
- u32 bw, freq = params->frequency;
-
- priv->mode = TDA18271_DIGITAL;
-
- if (fe->ops.info.type == FE_ATSC) {
- switch (params->u.vsb.modulation) {
- case VSB_8:
- case VSB_16:
- map = &std_map->atsc_6;
- break;
- case QAM_64:
- case QAM_256:
- map = &std_map->qam_6;
- break;
- default:
- tda_warn("modulation not set!\n");
- return -EINVAL;
- }
-#if 0 /* keep */
- /* userspace request is already center adjusted */
- freq += 1750000; /* Adjust to center (+1.75MHZ) */
-#endif
- bw = 6000000;
- } else if (fe->ops.info.type == FE_OFDM) {
- switch (params->u.ofdm.bandwidth) {
- case BANDWIDTH_6_MHZ:
- bw = 6000000;
- map = &std_map->dvbt_6;
- break;
- case BANDWIDTH_7_MHZ:
- bw = 7000000;
- map = &std_map->dvbt_7;
- break;
- case BANDWIDTH_8_MHZ:
- bw = 8000000;
- map = &std_map->dvbt_8;
- break;
- default:
- tda_warn("bandwidth not set!\n");
- return -EINVAL;
- }
- } else {
- tda_warn("modulation type not supported!\n");
- return -EINVAL;
- }
-
- /* When tuning digital, the analog demod must be tri-stated */
- if (fe->ops.analog_ops.standby)
- fe->ops.analog_ops.standby(fe);
-
- ret = tda18271_tune(fe, map, freq, bw);
-
- if (ret < 0)
- goto fail;
-
- priv->frequency = freq;
- priv->bandwidth = (fe->ops.info.type == FE_OFDM) ?
- params->u.ofdm.bandwidth : 0;
-fail:
- return ret;
-}
-
-static int tda18271_set_analog_params(struct dvb_frontend *fe,
- struct analog_parameters *params)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- struct tda18271_std_map *std_map = &priv->std;
- struct tda18271_std_map_item *map;
- char *mode;
- int ret;
- u32 freq = params->frequency * 62500;
-
- priv->mode = TDA18271_ANALOG;
-
- if (params->mode == V4L2_TUNER_RADIO) {
- freq = freq / 1000;
- map = &std_map->fm_radio;
- mode = "fm";
- } else if (params->std & V4L2_STD_MN) {
- map = &std_map->atv_mn;
- mode = "MN";
- } else if (params->std & V4L2_STD_B) {
- map = &std_map->atv_b;
- mode = "B";
- } else if (params->std & V4L2_STD_GH) {
- map = &std_map->atv_gh;
- mode = "GH";
- } else if (params->std & V4L2_STD_PAL_I) {
- map = &std_map->atv_i;
- mode = "I";
- } else if (params->std & V4L2_STD_DK) {
- map = &std_map->atv_dk;
- mode = "DK";
- } else if (params->std & V4L2_STD_SECAM_L) {
- map = &std_map->atv_l;
- mode = "L";
- } else if (params->std & V4L2_STD_SECAM_LC) {
- map = &std_map->atv_lc;
- mode = "L'";
- } else {
- map = &std_map->atv_i;
- mode = "xx";
- }
-
- tda_dbg("setting tda18271 to system %s\n", mode);
-
- ret = tda18271_tune(fe, map, freq, 0);
-
- if (ret < 0)
- goto fail;
-
- priv->frequency = freq;
- priv->bandwidth = 0;
-fail:
- return ret;
-}
-
-static int tda18271_sleep(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
-
- mutex_lock(&priv->lock);
-
- /* standby mode w/ slave tuner output
- * & loop thru & xtal oscillator on */
- tda18271_set_standby_mode(fe, 1, 0, 0);
-
- mutex_unlock(&priv->lock);
-
- return 0;
-}
-
-static int tda18271_release(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
-
- mutex_lock(&tda18271_list_mutex);
-
- if (priv)
- hybrid_tuner_release_state(priv);
-
- mutex_unlock(&tda18271_list_mutex);
-
- fe->tuner_priv = NULL;
-
- return 0;
-}
-
-static int tda18271_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- *frequency = priv->frequency;
- return 0;
-}
-
-static int tda18271_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- *bandwidth = priv->bandwidth;
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-#define tda18271_update_std(std_cfg, name) do { \
- if (map->std_cfg.if_freq + \
- map->std_cfg.agc_mode + map->std_cfg.std + \
- map->std_cfg.if_lvl + map->std_cfg.rfagc_top > 0) { \
- tda_dbg("Using custom std config for %s\n", name); \
- memcpy(&std->std_cfg, &map->std_cfg, \
- sizeof(struct tda18271_std_map_item)); \
- } } while (0)
-
-#define tda18271_dump_std_item(std_cfg, name) do { \
- tda_dbg("(%s) if_freq = %d, agc_mode = %d, std = %d, " \
- "if_lvl = %d, rfagc_top = 0x%02x\n", \
- name, std->std_cfg.if_freq, \
- std->std_cfg.agc_mode, std->std_cfg.std, \
- std->std_cfg.if_lvl, std->std_cfg.rfagc_top); \
- } while (0)
-
-static int tda18271_dump_std_map(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- struct tda18271_std_map *std = &priv->std;
-
- tda_dbg("========== STANDARD MAP SETTINGS ==========\n");
- tda18271_dump_std_item(fm_radio, " fm ");
- tda18271_dump_std_item(atv_b, "atv b ");
- tda18271_dump_std_item(atv_dk, "atv dk");
- tda18271_dump_std_item(atv_gh, "atv gh");
- tda18271_dump_std_item(atv_i, "atv i ");
- tda18271_dump_std_item(atv_l, "atv l ");
- tda18271_dump_std_item(atv_lc, "atv l'");
- tda18271_dump_std_item(atv_mn, "atv mn");
- tda18271_dump_std_item(atsc_6, "atsc 6");
- tda18271_dump_std_item(dvbt_6, "dvbt 6");
- tda18271_dump_std_item(dvbt_7, "dvbt 7");
- tda18271_dump_std_item(dvbt_8, "dvbt 8");
- tda18271_dump_std_item(qam_6, "qam 6 ");
- tda18271_dump_std_item(qam_8, "qam 8 ");
-
- return 0;
-}
-
-static int tda18271_update_std_map(struct dvb_frontend *fe,
- struct tda18271_std_map *map)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- struct tda18271_std_map *std = &priv->std;
-
- if (!map)
- return -EINVAL;
-
- tda18271_update_std(fm_radio, "fm");
- tda18271_update_std(atv_b, "atv b");
- tda18271_update_std(atv_dk, "atv dk");
- tda18271_update_std(atv_gh, "atv gh");
- tda18271_update_std(atv_i, "atv i");
- tda18271_update_std(atv_l, "atv l");
- tda18271_update_std(atv_lc, "atv l'");
- tda18271_update_std(atv_mn, "atv mn");
- tda18271_update_std(atsc_6, "atsc 6");
- tda18271_update_std(dvbt_6, "dvbt 6");
- tda18271_update_std(dvbt_7, "dvbt 7");
- tda18271_update_std(dvbt_8, "dvbt 8");
- tda18271_update_std(qam_6, "qam 6");
- tda18271_update_std(qam_8, "qam 8");
-
- return 0;
-}
-
-static int tda18271_get_id(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- char *name;
- int ret = 0;
-
- mutex_lock(&priv->lock);
- tda18271_read_regs(fe);
- mutex_unlock(&priv->lock);
-
- switch (regs[R_ID] & 0x7f) {
- case 3:
- name = "TDA18271HD/C1";
- priv->id = TDA18271HDC1;
- break;
- case 4:
- name = "TDA18271HD/C2";
- priv->id = TDA18271HDC2;
- break;
- default:
- name = "Unknown device";
- ret = -EINVAL;
- break;
- }
-
- tda_info("%s detected @ %d-%04x%s\n", name,
- i2c_adapter_id(priv->i2c_props.adap),
- priv->i2c_props.addr,
- (0 == ret) ? "" : ", device not supported.");
-
- return ret;
-}
-
-static struct dvb_tuner_ops tda18271_tuner_ops = {
- .info = {
- .name = "NXP TDA18271HD",
- .frequency_min = 45000000,
- .frequency_max = 864000000,
- .frequency_step = 62500
- },
- .init = tda18271_init,
- .sleep = tda18271_sleep,
- .set_params = tda18271_set_params,
- .set_analog_params = tda18271_set_analog_params,
- .release = tda18271_release,
- .get_frequency = tda18271_get_frequency,
- .get_bandwidth = tda18271_get_bandwidth,
-};
-
-struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
- struct i2c_adapter *i2c,
- struct tda18271_config *cfg)
-{
- struct tda18271_priv *priv = NULL;
- int instance;
-
- mutex_lock(&tda18271_list_mutex);
-
- instance = hybrid_tuner_request_state(struct tda18271_priv, priv,
- hybrid_tuner_instance_list,
- i2c, addr, "tda18271");
- switch (instance) {
- case 0:
- goto fail;
- break;
- case 1:
- /* new tuner instance */
- priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
- priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
- priv->cal_initialized = false;
- mutex_init(&priv->lock);
-
- fe->tuner_priv = priv;
-
- if (cfg)
- priv->small_i2c = cfg->small_i2c;
-
- if (tda18271_get_id(fe) < 0)
- goto fail;
-
- if (tda18271_assign_map_layout(fe) < 0)
- goto fail;
-
- mutex_lock(&priv->lock);
- tda18271_init_regs(fe);
-
- if ((tda18271_cal_on_startup) && (priv->id == TDA18271HDC2))
- tda18271c2_rf_cal_init(fe);
-
- mutex_unlock(&priv->lock);
- break;
- default:
- /* existing tuner instance */
- fe->tuner_priv = priv;
-
- /* allow dvb driver to override i2c gate setting */
- if ((cfg) && (cfg->gate != TDA18271_GATE_ANALOG))
- priv->gate = cfg->gate;
- break;
- }
-
- /* override default std map with values in config struct */
- if ((cfg) && (cfg->std_map))
- tda18271_update_std_map(fe, cfg->std_map);
-
- mutex_unlock(&tda18271_list_mutex);
-
- memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops,
- sizeof(struct dvb_tuner_ops));
-
- if (tda18271_debug & (DBG_MAP | DBG_ADV))
- tda18271_dump_std_map(fe);
-
- return fe;
-fail:
- mutex_unlock(&tda18271_list_mutex);
-
- tda18271_release(fe);
- return NULL;
-}
-EXPORT_SYMBOL_GPL(tda18271_attach);
-MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");
-MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
-MODULE_LICENSE("GPL");
-MODULE_VERSION("0.3");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/linux/drivers/media/dvb/frontends/tda18271-priv.h b/linux/drivers/media/dvb/frontends/tda18271-priv.h
deleted file mode 100644
index 808b89c40..000000000
--- a/linux/drivers/media/dvb/frontends/tda18271-priv.h
+++ /dev/null
@@ -1,229 +0,0 @@
-/*
- tda18271-priv.h - private header for the NXP TDA18271 silicon tuner
-
- Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
-
- 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 __TDA18271_PRIV_H__
-#define __TDA18271_PRIV_H__
-
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include "compat.h"
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
-#include <linux/mutex.h>
-#else
-#include <asm/semaphore.h>
-#endif
-#include "tuner-i2c.h"
-#include "tda18271.h"
-
-#define R_ID 0x00 /* ID byte */
-#define R_TM 0x01 /* Thermo byte */
-#define R_PL 0x02 /* Power level byte */
-#define R_EP1 0x03 /* Easy Prog byte 1 */
-#define R_EP2 0x04 /* Easy Prog byte 2 */
-#define R_EP3 0x05 /* Easy Prog byte 3 */
-#define R_EP4 0x06 /* Easy Prog byte 4 */
-#define R_EP5 0x07 /* Easy Prog byte 5 */
-#define R_CPD 0x08 /* Cal Post-Divider byte */
-#define R_CD1 0x09 /* Cal Divider byte 1 */
-#define R_CD2 0x0a /* Cal Divider byte 2 */
-#define R_CD3 0x0b /* Cal Divider byte 3 */
-#define R_MPD 0x0c /* Main Post-Divider byte */
-#define R_MD1 0x0d /* Main Divider byte 1 */
-#define R_MD2 0x0e /* Main Divider byte 2 */
-#define R_MD3 0x0f /* Main Divider byte 3 */
-#define R_EB1 0x10 /* Extended byte 1 */
-#define R_EB2 0x11 /* Extended byte 2 */
-#define R_EB3 0x12 /* Extended byte 3 */
-#define R_EB4 0x13 /* Extended byte 4 */
-#define R_EB5 0x14 /* Extended byte 5 */
-#define R_EB6 0x15 /* Extended byte 6 */
-#define R_EB7 0x16 /* Extended byte 7 */
-#define R_EB8 0x17 /* Extended byte 8 */
-#define R_EB9 0x18 /* Extended byte 9 */
-#define R_EB10 0x19 /* Extended byte 10 */
-#define R_EB11 0x1a /* Extended byte 11 */
-#define R_EB12 0x1b /* Extended byte 12 */
-#define R_EB13 0x1c /* Extended byte 13 */
-#define R_EB14 0x1d /* Extended byte 14 */
-#define R_EB15 0x1e /* Extended byte 15 */
-#define R_EB16 0x1f /* Extended byte 16 */
-#define R_EB17 0x20 /* Extended byte 17 */
-#define R_EB18 0x21 /* Extended byte 18 */
-#define R_EB19 0x22 /* Extended byte 19 */
-#define R_EB20 0x23 /* Extended byte 20 */
-#define R_EB21 0x24 /* Extended byte 21 */
-#define R_EB22 0x25 /* Extended byte 22 */
-#define R_EB23 0x26 /* Extended byte 23 */
-
-#define TDA18271_NUM_REGS 39
-
-/*---------------------------------------------------------------------*/
-
-struct tda18271_rf_tracking_filter_cal {
- u32 rfmax;
- u8 rfband;
- u32 rf1_def;
- u32 rf2_def;
- u32 rf3_def;
- u32 rf1;
- u32 rf2;
- u32 rf3;
- int rf_a1;
- int rf_b1;
- int rf_a2;
- int rf_b2;
-};
-
-enum tda18271_pll {
- TDA18271_MAIN_PLL,
- TDA18271_CAL_PLL,
-};
-
-enum tda18271_mode {
- TDA18271_ANALOG,
- TDA18271_DIGITAL,
-};
-
-struct tda18271_map_layout;
-
-enum tda18271_ver {
- TDA18271HDC1,
- TDA18271HDC2,
-};
-
-struct tda18271_priv {
- unsigned char tda18271_regs[TDA18271_NUM_REGS];
-
- struct list_head hybrid_tuner_instance_list;
- struct tuner_i2c_props i2c_props;
-
- enum tda18271_mode mode;
- enum tda18271_role role;
- enum tda18271_i2c_gate gate;
- enum tda18271_ver id;
-
- unsigned int tm_rfcal;
- unsigned int cal_initialized:1;
- unsigned int small_i2c:1;
-
- struct tda18271_map_layout *maps;
- struct tda18271_std_map std;
- struct tda18271_rf_tracking_filter_cal rf_cal_state[8];
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,16)
- struct mutex lock;
-#else
- struct semaphore lock;
-#endif
-
- u32 frequency;
- u32 bandwidth;
-};
-
-/*---------------------------------------------------------------------*/
-
-extern int tda18271_debug;
-
-#define DBG_INFO 1
-#define DBG_MAP 2
-#define DBG_REG 4
-#define DBG_ADV 8
-#define DBG_CAL 16
-
-#define tda_printk(kern, fmt, arg...) \
- printk(kern "%s: " fmt, __FUNCTION__, ##arg)
-
-#define dprintk(kern, lvl, fmt, arg...) do {\
- if (tda18271_debug & lvl) \
- tda_printk(kern, fmt, ##arg); } while (0)
-
-#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg)
-#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg)
-#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg)
-#define tda_dbg(fmt, arg...) dprintk(KERN_DEBUG, DBG_INFO, fmt, ##arg)
-#define tda_map(fmt, arg...) dprintk(KERN_DEBUG, DBG_MAP, fmt, ##arg)
-#define tda_reg(fmt, arg...) dprintk(KERN_DEBUG, DBG_REG, fmt, ##arg)
-#define tda_cal(fmt, arg...) dprintk(KERN_DEBUG, DBG_CAL, fmt, ##arg)
-
-/*---------------------------------------------------------------------*/
-
-enum tda18271_map_type {
- /* tda18271_pll_map */
- MAIN_PLL,
- CAL_PLL,
- /* tda18271_map */
- RF_CAL,
- RF_CAL_KMCO,
- RF_CAL_DC_OVER_DT,
- BP_FILTER,
- RF_BAND,
- GAIN_TAPER,
- IR_MEASURE,
-};
-
-extern int tda18271_lookup_pll_map(struct dvb_frontend *fe,
- enum tda18271_map_type map_type,
- u32 *freq, u8 *post_div, u8 *div);
-extern int tda18271_lookup_map(struct dvb_frontend *fe,
- enum tda18271_map_type map_type,
- u32 *freq, u8 *val);
-
-extern int tda18271_lookup_thermometer(struct dvb_frontend *fe);
-
-extern int tda18271_lookup_rf_band(struct dvb_frontend *fe,
- u32 *freq, u8 *rf_band);
-
-extern int tda18271_lookup_cid_target(struct dvb_frontend *fe,
- u32 *freq, u8 *cid_target,
- u16 *count_limit);
-
-extern int tda18271_assign_map_layout(struct dvb_frontend *fe);
-
-/*---------------------------------------------------------------------*/
-
-extern int tda18271_read_regs(struct dvb_frontend *fe);
-extern int tda18271_read_extended(struct dvb_frontend *fe);
-extern int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len);
-extern int tda18271_init_regs(struct dvb_frontend *fe);
-
-extern int tda18271_charge_pump_source(struct dvb_frontend *fe,
- enum tda18271_pll pll, int force);
-extern int tda18271_set_standby_mode(struct dvb_frontend *fe,
- int sm, int sm_lt, int sm_xt);
-
-extern int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq);
-extern int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq);
-
-extern int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq);
-extern int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq);
-extern int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq);
-extern int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq);
-extern int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq);
-extern int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq);
-
-#endif /* __TDA18271_PRIV_H__ */
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/linux/drivers/media/dvb/frontends/tda18271-tables.c b/linux/drivers/media/dvb/frontends/tda18271-tables.c
deleted file mode 100644
index 83e756196..000000000
--- a/linux/drivers/media/dvb/frontends/tda18271-tables.c
+++ /dev/null
@@ -1,1313 +0,0 @@
-/*
- tda18271-tables.c - driver for the Philips / NXP TDA18271 silicon tuner
-
- Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
-
- 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 "tda18271-priv.h"
-
-struct tda18271_pll_map {
- u32 lomax;
- u8 pd; /* post div */
- u8 d; /* div */
-};
-
-struct tda18271_map {
- u32 rfmax;
- u8 val;
-};
-
-/*---------------------------------------------------------------------*/
-
-static struct tda18271_pll_map tda18271c1_main_pll[] = {
- { .lomax = 32000, .pd = 0x5f, .d = 0xf0 },
- { .lomax = 35000, .pd = 0x5e, .d = 0xe0 },
- { .lomax = 37000, .pd = 0x5d, .d = 0xd0 },
- { .lomax = 41000, .pd = 0x5c, .d = 0xc0 },
- { .lomax = 44000, .pd = 0x5b, .d = 0xb0 },
- { .lomax = 49000, .pd = 0x5a, .d = 0xa0 },
- { .lomax = 54000, .pd = 0x59, .d = 0x90 },
- { .lomax = 61000, .pd = 0x58, .d = 0x80 },
- { .lomax = 65000, .pd = 0x4f, .d = 0x78 },
- { .lomax = 70000, .pd = 0x4e, .d = 0x70 },
- { .lomax = 75000, .pd = 0x4d, .d = 0x68 },
- { .lomax = 82000, .pd = 0x4c, .d = 0x60 },
- { .lomax = 89000, .pd = 0x4b, .d = 0x58 },
- { .lomax = 98000, .pd = 0x4a, .d = 0x50 },
- { .lomax = 109000, .pd = 0x49, .d = 0x48 },
- { .lomax = 123000, .pd = 0x48, .d = 0x40 },
- { .lomax = 131000, .pd = 0x3f, .d = 0x3c },
- { .lomax = 141000, .pd = 0x3e, .d = 0x38 },
- { .lomax = 151000, .pd = 0x3d, .d = 0x34 },
- { .lomax = 164000, .pd = 0x3c, .d = 0x30 },
- { .lomax = 179000, .pd = 0x3b, .d = 0x2c },
- { .lomax = 197000, .pd = 0x3a, .d = 0x28 },
- { .lomax = 219000, .pd = 0x39, .d = 0x24 },
- { .lomax = 246000, .pd = 0x38, .d = 0x20 },
- { .lomax = 263000, .pd = 0x2f, .d = 0x1e },
- { .lomax = 282000, .pd = 0x2e, .d = 0x1c },
- { .lomax = 303000, .pd = 0x2d, .d = 0x1a },
- { .lomax = 329000, .pd = 0x2c, .d = 0x18 },
- { .lomax = 359000, .pd = 0x2b, .d = 0x16 },
- { .lomax = 395000, .pd = 0x2a, .d = 0x14 },
- { .lomax = 438000, .pd = 0x29, .d = 0x12 },
- { .lomax = 493000, .pd = 0x28, .d = 0x10 },
- { .lomax = 526000, .pd = 0x1f, .d = 0x0f },
- { .lomax = 564000, .pd = 0x1e, .d = 0x0e },
- { .lomax = 607000, .pd = 0x1d, .d = 0x0d },
- { .lomax = 658000, .pd = 0x1c, .d = 0x0c },
- { .lomax = 718000, .pd = 0x1b, .d = 0x0b },
- { .lomax = 790000, .pd = 0x1a, .d = 0x0a },
- { .lomax = 877000, .pd = 0x19, .d = 0x09 },
- { .lomax = 987000, .pd = 0x18, .d = 0x08 },
- { .lomax = 0, .pd = 0x00, .d = 0x00 }, /* end */
-};
-
-static struct tda18271_pll_map tda18271c2_main_pll[] = {
- { .lomax = 33125, .pd = 0x57, .d = 0xf0 },
- { .lomax = 35500, .pd = 0x56, .d = 0xe0 },
- { .lomax = 38188, .pd = 0x55, .d = 0xd0 },
- { .lomax = 41375, .pd = 0x54, .d = 0xc0 },
- { .lomax = 45125, .pd = 0x53, .d = 0xb0 },
- { .lomax = 49688, .pd = 0x52, .d = 0xa0 },
- { .lomax = 55188, .pd = 0x51, .d = 0x90 },
- { .lomax = 62125, .pd = 0x50, .d = 0x80 },
- { .lomax = 66250, .pd = 0x47, .d = 0x78 },
- { .lomax = 71000, .pd = 0x46, .d = 0x70 },
- { .lomax = 76375, .pd = 0x45, .d = 0x68 },
- { .lomax = 82750, .pd = 0x44, .d = 0x60 },
- { .lomax = 90250, .pd = 0x43, .d = 0x58 },
- { .lomax = 99375, .pd = 0x42, .d = 0x50 },
- { .lomax = 110375, .pd = 0x41, .d = 0x48 },
- { .lomax = 124250, .pd = 0x40, .d = 0x40 },
- { .lomax = 132500, .pd = 0x37, .d = 0x3c },
- { .lomax = 142000, .pd = 0x36, .d = 0x38 },
- { .lomax = 152750, .pd = 0x35, .d = 0x34 },
- { .lomax = 165500, .pd = 0x34, .d = 0x30 },
- { .lomax = 180500, .pd = 0x33, .d = 0x2c },
- { .lomax = 198750, .pd = 0x32, .d = 0x28 },
- { .lomax = 220750, .pd = 0x31, .d = 0x24 },
- { .lomax = 248500, .pd = 0x30, .d = 0x20 },
- { .lomax = 265000, .pd = 0x27, .d = 0x1e },
- { .lomax = 284000, .pd = 0x26, .d = 0x1c },
- { .lomax = 305500, .pd = 0x25, .d = 0x1a },
- { .lomax = 331000, .pd = 0x24, .d = 0x18 },
- { .lomax = 361000, .pd = 0x23, .d = 0x16 },
- { .lomax = 397500, .pd = 0x22, .d = 0x14 },
- { .lomax = 441500, .pd = 0x21, .d = 0x12 },
- { .lomax = 497000, .pd = 0x20, .d = 0x10 },
- { .lomax = 530000, .pd = 0x17, .d = 0x0f },
- { .lomax = 568000, .pd = 0x16, .d = 0x0e },
- { .lomax = 611000, .pd = 0x15, .d = 0x0d },
- { .lomax = 662000, .pd = 0x14, .d = 0x0c },
- { .lomax = 722000, .pd = 0x13, .d = 0x0b },
- { .lomax = 795000, .pd = 0x12, .d = 0x0a },
- { .lomax = 883000, .pd = 0x11, .d = 0x09 },
- { .lomax = 994000, .pd = 0x10, .d = 0x08 },
- { .lomax = 0, .pd = 0x00, .d = 0x00 }, /* end */
-};
-
-static struct tda18271_pll_map tda18271c1_cal_pll[] = {
- { .lomax = 33000, .pd = 0xdd, .d = 0xd0 },
- { .lomax = 36000, .pd = 0xdc, .d = 0xc0 },
- { .lomax = 40000, .pd = 0xdb, .d = 0xb0 },
- { .lomax = 44000, .pd = 0xda, .d = 0xa0 },
- { .lomax = 49000, .pd = 0xd9, .d = 0x90 },
- { .lomax = 55000, .pd = 0xd8, .d = 0x80 },
- { .lomax = 63000, .pd = 0xd3, .d = 0x70 },
- { .lomax = 67000, .pd = 0xcd, .d = 0x68 },
- { .lomax = 73000, .pd = 0xcc, .d = 0x60 },
- { .lomax = 80000, .pd = 0xcb, .d = 0x58 },
- { .lomax = 88000, .pd = 0xca, .d = 0x50 },
- { .lomax = 98000, .pd = 0xc9, .d = 0x48 },
- { .lomax = 110000, .pd = 0xc8, .d = 0x40 },
- { .lomax = 126000, .pd = 0xc3, .d = 0x38 },
- { .lomax = 135000, .pd = 0xbd, .d = 0x34 },
- { .lomax = 147000, .pd = 0xbc, .d = 0x30 },
- { .lomax = 160000, .pd = 0xbb, .d = 0x2c },
- { .lomax = 176000, .pd = 0xba, .d = 0x28 },
- { .lomax = 196000, .pd = 0xb9, .d = 0x24 },
- { .lomax = 220000, .pd = 0xb8, .d = 0x20 },
- { .lomax = 252000, .pd = 0xb3, .d = 0x1c },
- { .lomax = 271000, .pd = 0xad, .d = 0x1a },
- { .lomax = 294000, .pd = 0xac, .d = 0x18 },
- { .lomax = 321000, .pd = 0xab, .d = 0x16 },
- { .lomax = 353000, .pd = 0xaa, .d = 0x14 },
- { .lomax = 392000, .pd = 0xa9, .d = 0x12 },
- { .lomax = 441000, .pd = 0xa8, .d = 0x10 },
- { .lomax = 505000, .pd = 0xa3, .d = 0x0e },
- { .lomax = 543000, .pd = 0x9d, .d = 0x0d },
- { .lomax = 589000, .pd = 0x9c, .d = 0x0c },
- { .lomax = 642000, .pd = 0x9b, .d = 0x0b },
- { .lomax = 707000, .pd = 0x9a, .d = 0x0a },
- { .lomax = 785000, .pd = 0x99, .d = 0x09 },
- { .lomax = 883000, .pd = 0x98, .d = 0x08 },
- { .lomax = 1010000, .pd = 0x93, .d = 0x07 },
- { .lomax = 0, .pd = 0x00, .d = 0x00 }, /* end */
-};
-
-static struct tda18271_pll_map tda18271c2_cal_pll[] = {
- { .lomax = 33813, .pd = 0xdd, .d = 0xd0 },
- { .lomax = 36625, .pd = 0xdc, .d = 0xc0 },
- { .lomax = 39938, .pd = 0xdb, .d = 0xb0 },
- { .lomax = 43938, .pd = 0xda, .d = 0xa0 },
- { .lomax = 48813, .pd = 0xd9, .d = 0x90 },
- { .lomax = 54938, .pd = 0xd8, .d = 0x80 },
- { .lomax = 62813, .pd = 0xd3, .d = 0x70 },
- { .lomax = 67625, .pd = 0xcd, .d = 0x68 },
- { .lomax = 73250, .pd = 0xcc, .d = 0x60 },
- { .lomax = 79875, .pd = 0xcb, .d = 0x58 },
- { .lomax = 87875, .pd = 0xca, .d = 0x50 },
- { .lomax = 97625, .pd = 0xc9, .d = 0x48 },
- { .lomax = 109875, .pd = 0xc8, .d = 0x40 },
- { .lomax = 125625, .pd = 0xc3, .d = 0x38 },
- { .lomax = 135250, .pd = 0xbd, .d = 0x34 },
- { .lomax = 146500, .pd = 0xbc, .d = 0x30 },
- { .lomax = 159750, .pd = 0xbb, .d = 0x2c },
- { .lomax = 175750, .pd = 0xba, .d = 0x28 },
- { .lomax = 195250, .pd = 0xb9, .d = 0x24 },
- { .lomax = 219750, .pd = 0xb8, .d = 0x20 },
- { .lomax = 251250, .pd = 0xb3, .d = 0x1c },
- { .lomax = 270500, .pd = 0xad, .d = 0x1a },
- { .lomax = 293000, .pd = 0xac, .d = 0x18 },
- { .lomax = 319500, .pd = 0xab, .d = 0x16 },
- { .lomax = 351500, .pd = 0xaa, .d = 0x14 },
- { .lomax = 390500, .pd = 0xa9, .d = 0x12 },
- { .lomax = 439500, .pd = 0xa8, .d = 0x10 },
- { .lomax = 502500, .pd = 0xa3, .d = 0x0e },
- { .lomax = 541000, .pd = 0x9d, .d = 0x0d },
- { .lomax = 586000, .pd = 0x9c, .d = 0x0c },
- { .lomax = 639000, .pd = 0x9b, .d = 0x0b },
- { .lomax = 703000, .pd = 0x9a, .d = 0x0a },
- { .lomax = 781000, .pd = 0x99, .d = 0x09 },
- { .lomax = 879000, .pd = 0x98, .d = 0x08 },
- { .lomax = 0, .pd = 0x00, .d = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271_bp_filter[] = {
- { .rfmax = 62000, .val = 0x00 },
- { .rfmax = 84000, .val = 0x01 },
- { .rfmax = 100000, .val = 0x02 },
- { .rfmax = 140000, .val = 0x03 },
- { .rfmax = 170000, .val = 0x04 },
- { .rfmax = 180000, .val = 0x05 },
- { .rfmax = 865000, .val = 0x06 },
- { .rfmax = 0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271c1_km[] = {
- { .rfmax = 61100, .val = 0x74 },
- { .rfmax = 350000, .val = 0x40 },
- { .rfmax = 720000, .val = 0x30 },
- { .rfmax = 865000, .val = 0x40 },
- { .rfmax = 0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271c2_km[] = {
- { .rfmax = 47900, .val = 0x38 },
- { .rfmax = 61100, .val = 0x44 },
- { .rfmax = 350000, .val = 0x30 },
- { .rfmax = 720000, .val = 0x24 },
- { .rfmax = 865000, .val = 0x3c },
- { .rfmax = 0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271_rf_band[] = {
- { .rfmax = 47900, .val = 0x00 },
- { .rfmax = 61100, .val = 0x01 },
-/* { .rfmax = 152600, .val = 0x02 }, */
- { .rfmax = 121200, .val = 0x02 },
- { .rfmax = 164700, .val = 0x03 },
- { .rfmax = 203500, .val = 0x04 },
- { .rfmax = 457800, .val = 0x05 },
- { .rfmax = 865000, .val = 0x06 },
- { .rfmax = 0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271_gain_taper[] = {
- { .rfmax = 45400, .val = 0x1f },
- { .rfmax = 45800, .val = 0x1e },
- { .rfmax = 46200, .val = 0x1d },
- { .rfmax = 46700, .val = 0x1c },
- { .rfmax = 47100, .val = 0x1b },
- { .rfmax = 47500, .val = 0x1a },
- { .rfmax = 47900, .val = 0x19 },
- { .rfmax = 49600, .val = 0x17 },
- { .rfmax = 51200, .val = 0x16 },
- { .rfmax = 52900, .val = 0x15 },
- { .rfmax = 54500, .val = 0x14 },
- { .rfmax = 56200, .val = 0x13 },
- { .rfmax = 57800, .val = 0x12 },
- { .rfmax = 59500, .val = 0x11 },
- { .rfmax = 61100, .val = 0x10 },
- { .rfmax = 67600, .val = 0x0d },
- { .rfmax = 74200, .val = 0x0c },
- { .rfmax = 80700, .val = 0x0b },
- { .rfmax = 87200, .val = 0x0a },
- { .rfmax = 93800, .val = 0x09 },
- { .rfmax = 100300, .val = 0x08 },
- { .rfmax = 106900, .val = 0x07 },
- { .rfmax = 113400, .val = 0x06 },
- { .rfmax = 119900, .val = 0x05 },
- { .rfmax = 126500, .val = 0x04 },
- { .rfmax = 133000, .val = 0x03 },
- { .rfmax = 139500, .val = 0x02 },
- { .rfmax = 146100, .val = 0x01 },
- { .rfmax = 152600, .val = 0x00 },
- { .rfmax = 154300, .val = 0x1f },
- { .rfmax = 156100, .val = 0x1e },
- { .rfmax = 157800, .val = 0x1d },
- { .rfmax = 159500, .val = 0x1c },
- { .rfmax = 161200, .val = 0x1b },
- { .rfmax = 163000, .val = 0x1a },
- { .rfmax = 164700, .val = 0x19 },
- { .rfmax = 170200, .val = 0x17 },
- { .rfmax = 175800, .val = 0x16 },
- { .rfmax = 181300, .val = 0x15 },
- { .rfmax = 186900, .val = 0x14 },
- { .rfmax = 192400, .val = 0x13 },
- { .rfmax = 198000, .val = 0x12 },
- { .rfmax = 203500, .val = 0x11 },
- { .rfmax = 216200, .val = 0x14 },
- { .rfmax = 228900, .val = 0x13 },
- { .rfmax = 241600, .val = 0x12 },
- { .rfmax = 254400, .val = 0x11 },
- { .rfmax = 267100, .val = 0x10 },
- { .rfmax = 279800, .val = 0x0f },
- { .rfmax = 292500, .val = 0x0e },
- { .rfmax = 305200, .val = 0x0d },
- { .rfmax = 317900, .val = 0x0c },
- { .rfmax = 330700, .val = 0x0b },
- { .rfmax = 343400, .val = 0x0a },
- { .rfmax = 356100, .val = 0x09 },
- { .rfmax = 368800, .val = 0x08 },
- { .rfmax = 381500, .val = 0x07 },
- { .rfmax = 394200, .val = 0x06 },
- { .rfmax = 406900, .val = 0x05 },
- { .rfmax = 419700, .val = 0x04 },
- { .rfmax = 432400, .val = 0x03 },
- { .rfmax = 445100, .val = 0x02 },
- { .rfmax = 457800, .val = 0x01 },
- { .rfmax = 476300, .val = 0x19 },
- { .rfmax = 494800, .val = 0x18 },
- { .rfmax = 513300, .val = 0x17 },
- { .rfmax = 531800, .val = 0x16 },
- { .rfmax = 550300, .val = 0x15 },
- { .rfmax = 568900, .val = 0x14 },
- { .rfmax = 587400, .val = 0x13 },
- { .rfmax = 605900, .val = 0x12 },
- { .rfmax = 624400, .val = 0x11 },
- { .rfmax = 642900, .val = 0x10 },
- { .rfmax = 661400, .val = 0x0f },
- { .rfmax = 679900, .val = 0x0e },
- { .rfmax = 698400, .val = 0x0d },
- { .rfmax = 716900, .val = 0x0c },
- { .rfmax = 735400, .val = 0x0b },
- { .rfmax = 753900, .val = 0x0a },
- { .rfmax = 772500, .val = 0x09 },
- { .rfmax = 791000, .val = 0x08 },
- { .rfmax = 809500, .val = 0x07 },
- { .rfmax = 828000, .val = 0x06 },
- { .rfmax = 846500, .val = 0x05 },
- { .rfmax = 865000, .val = 0x04 },
- { .rfmax = 0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271c1_rf_cal[] = {
- { .rfmax = 41000, .val = 0x1e },
- { .rfmax = 43000, .val = 0x30 },
- { .rfmax = 45000, .val = 0x43 },
- { .rfmax = 46000, .val = 0x4d },
- { .rfmax = 47000, .val = 0x54 },
- { .rfmax = 47900, .val = 0x64 },
- { .rfmax = 49100, .val = 0x20 },
- { .rfmax = 50000, .val = 0x22 },
- { .rfmax = 51000, .val = 0x2a },
- { .rfmax = 53000, .val = 0x32 },
- { .rfmax = 55000, .val = 0x35 },
- { .rfmax = 56000, .val = 0x3c },
- { .rfmax = 57000, .val = 0x3f },
- { .rfmax = 58000, .val = 0x48 },
- { .rfmax = 59000, .val = 0x4d },
- { .rfmax = 60000, .val = 0x58 },
- { .rfmax = 61100, .val = 0x5f },
- { .rfmax = 0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271c2_rf_cal[] = {
- { .rfmax = 41000, .val = 0x0f },
- { .rfmax = 43000, .val = 0x1c },
- { .rfmax = 45000, .val = 0x2f },
- { .rfmax = 46000, .val = 0x39 },
- { .rfmax = 47000, .val = 0x40 },
- { .rfmax = 47900, .val = 0x50 },
- { .rfmax = 49100, .val = 0x16 },
- { .rfmax = 50000, .val = 0x18 },
- { .rfmax = 51000, .val = 0x20 },
- { .rfmax = 53000, .val = 0x28 },
- { .rfmax = 55000, .val = 0x2b },
- { .rfmax = 56000, .val = 0x32 },
- { .rfmax = 57000, .val = 0x35 },
- { .rfmax = 58000, .val = 0x3e },
- { .rfmax = 59000, .val = 0x43 },
- { .rfmax = 60000, .val = 0x4e },
- { .rfmax = 61100, .val = 0x55 },
- { .rfmax = 63000, .val = 0x0f },
- { .rfmax = 64000, .val = 0x11 },
- { .rfmax = 65000, .val = 0x12 },
- { .rfmax = 66000, .val = 0x15 },
- { .rfmax = 67000, .val = 0x16 },
- { .rfmax = 68000, .val = 0x17 },
- { .rfmax = 70000, .val = 0x19 },
- { .rfmax = 71000, .val = 0x1c },
- { .rfmax = 72000, .val = 0x1d },
- { .rfmax = 73000, .val = 0x1f },
- { .rfmax = 74000, .val = 0x20 },
- { .rfmax = 75000, .val = 0x21 },
- { .rfmax = 76000, .val = 0x24 },
- { .rfmax = 77000, .val = 0x25 },
- { .rfmax = 78000, .val = 0x27 },
- { .rfmax = 80000, .val = 0x28 },
- { .rfmax = 81000, .val = 0x29 },
- { .rfmax = 82000, .val = 0x2d },
- { .rfmax = 83000, .val = 0x2e },
- { .rfmax = 84000, .val = 0x2f },
- { .rfmax = 85000, .val = 0x31 },
- { .rfmax = 86000, .val = 0x33 },
- { .rfmax = 87000, .val = 0x34 },
- { .rfmax = 88000, .val = 0x35 },
- { .rfmax = 89000, .val = 0x37 },
- { .rfmax = 90000, .val = 0x38 },
- { .rfmax = 91000, .val = 0x39 },
- { .rfmax = 93000, .val = 0x3c },
- { .rfmax = 94000, .val = 0x3e },
- { .rfmax = 95000, .val = 0x3f },
- { .rfmax = 96000, .val = 0x40 },
- { .rfmax = 97000, .val = 0x42 },
- { .rfmax = 99000, .val = 0x45 },
- { .rfmax = 100000, .val = 0x46 },
- { .rfmax = 102000, .val = 0x48 },
- { .rfmax = 103000, .val = 0x4a },
- { .rfmax = 105000, .val = 0x4d },
- { .rfmax = 106000, .val = 0x4e },
- { .rfmax = 107000, .val = 0x50 },
- { .rfmax = 108000, .val = 0x51 },
- { .rfmax = 110000, .val = 0x54 },
- { .rfmax = 111000, .val = 0x56 },
- { .rfmax = 112000, .val = 0x57 },
- { .rfmax = 113000, .val = 0x58 },
- { .rfmax = 114000, .val = 0x59 },
- { .rfmax = 115000, .val = 0x5c },
- { .rfmax = 116000, .val = 0x5d },
- { .rfmax = 117000, .val = 0x5f },
- { .rfmax = 119000, .val = 0x60 },
- { .rfmax = 120000, .val = 0x64 },
- { .rfmax = 121000, .val = 0x65 },
- { .rfmax = 122000, .val = 0x66 },
- { .rfmax = 123000, .val = 0x68 },
- { .rfmax = 124000, .val = 0x69 },
- { .rfmax = 125000, .val = 0x6c },
- { .rfmax = 126000, .val = 0x6d },
- { .rfmax = 127000, .val = 0x6e },
- { .rfmax = 128000, .val = 0x70 },
- { .rfmax = 129000, .val = 0x71 },
- { .rfmax = 130000, .val = 0x75 },
- { .rfmax = 131000, .val = 0x77 },
- { .rfmax = 132000, .val = 0x78 },
- { .rfmax = 133000, .val = 0x7b },
- { .rfmax = 134000, .val = 0x7e },
- { .rfmax = 135000, .val = 0x81 },
- { .rfmax = 136000, .val = 0x82 },
- { .rfmax = 137000, .val = 0x87 },
- { .rfmax = 138000, .val = 0x88 },
- { .rfmax = 139000, .val = 0x8d },
- { .rfmax = 140000, .val = 0x8e },
- { .rfmax = 141000, .val = 0x91 },
- { .rfmax = 142000, .val = 0x95 },
- { .rfmax = 143000, .val = 0x9a },
- { .rfmax = 144000, .val = 0x9d },
- { .rfmax = 145000, .val = 0xa1 },
- { .rfmax = 146000, .val = 0xa2 },
- { .rfmax = 147000, .val = 0xa4 },
- { .rfmax = 148000, .val = 0xa9 },
- { .rfmax = 149000, .val = 0xae },
- { .rfmax = 150000, .val = 0xb0 },
- { .rfmax = 151000, .val = 0xb1 },
- { .rfmax = 152000, .val = 0xb7 },
- { .rfmax = 153000, .val = 0xbd },
- { .rfmax = 154000, .val = 0x20 },
- { .rfmax = 155000, .val = 0x22 },
- { .rfmax = 156000, .val = 0x24 },
- { .rfmax = 157000, .val = 0x25 },
- { .rfmax = 158000, .val = 0x27 },
- { .rfmax = 159000, .val = 0x29 },
- { .rfmax = 160000, .val = 0x2c },
- { .rfmax = 161000, .val = 0x2d },
- { .rfmax = 163000, .val = 0x2e },
- { .rfmax = 164000, .val = 0x2f },
- { .rfmax = 165000, .val = 0x30 },
- { .rfmax = 166000, .val = 0x11 },
- { .rfmax = 167000, .val = 0x12 },
- { .rfmax = 168000, .val = 0x13 },
- { .rfmax = 169000, .val = 0x14 },
- { .rfmax = 170000, .val = 0x15 },
- { .rfmax = 172000, .val = 0x16 },
- { .rfmax = 173000, .val = 0x17 },
- { .rfmax = 174000, .val = 0x18 },
- { .rfmax = 175000, .val = 0x1a },
- { .rfmax = 176000, .val = 0x1b },
- { .rfmax = 178000, .val = 0x1d },
- { .rfmax = 179000, .val = 0x1e },
- { .rfmax = 180000, .val = 0x1f },
- { .rfmax = 181000, .val = 0x20 },
- { .rfmax = 182000, .val = 0x21 },
- { .rfmax = 183000, .val = 0x22 },
- { .rfmax = 184000, .val = 0x24 },
- { .rfmax = 185000, .val = 0x25 },
- { .rfmax = 186000, .val = 0x26 },
- { .rfmax = 187000, .val = 0x27 },
- { .rfmax = 188000, .val = 0x29 },
- { .rfmax = 189000, .val = 0x2a },
- { .rfmax = 190000, .val = 0x2c },
- { .rfmax = 191000, .val = 0x2d },
- { .rfmax = 192000, .val = 0x2e },
- { .rfmax = 193000, .val = 0x2f },
- { .rfmax = 194000, .val = 0x30 },
- { .rfmax = 195000, .val = 0x33 },
- { .rfmax = 196000, .val = 0x35 },
- { .rfmax = 198000, .val = 0x36 },
- { .rfmax = 200000, .val = 0x38 },
- { .rfmax = 201000, .val = 0x3c },
- { .rfmax = 202000, .val = 0x3d },
- { .rfmax = 203500, .val = 0x3e },
- { .rfmax = 206000, .val = 0x0e },
- { .rfmax = 208000, .val = 0x0f },
- { .rfmax = 212000, .val = 0x10 },
- { .rfmax = 216000, .val = 0x11 },
- { .rfmax = 217000, .val = 0x12 },
- { .rfmax = 218000, .val = 0x13 },
- { .rfmax = 220000, .val = 0x14 },
- { .rfmax = 222000, .val = 0x15 },
- { .rfmax = 225000, .val = 0x16 },
- { .rfmax = 228000, .val = 0x17 },
- { .rfmax = 231000, .val = 0x18 },
- { .rfmax = 234000, .val = 0x19 },
- { .rfmax = 235000, .val = 0x1a },
- { .rfmax = 236000, .val = 0x1b },
- { .rfmax = 237000, .val = 0x1c },
- { .rfmax = 240000, .val = 0x1d },
- { .rfmax = 242000, .val = 0x1f },
- { .rfmax = 247000, .val = 0x20 },
- { .rfmax = 249000, .val = 0x21 },
- { .rfmax = 252000, .val = 0x22 },
- { .rfmax = 253000, .val = 0x23 },
- { .rfmax = 254000, .val = 0x24 },
- { .rfmax = 256000, .val = 0x25 },
- { .rfmax = 259000, .val = 0x26 },
- { .rfmax = 262000, .val = 0x27 },
- { .rfmax = 264000, .val = 0x28 },
- { .rfmax = 267000, .val = 0x29 },
- { .rfmax = 269000, .val = 0x2a },
- { .rfmax = 271000, .val = 0x2b },
- { .rfmax = 273000, .val = 0x2c },
- { .rfmax = 275000, .val = 0x2d },
- { .rfmax = 277000, .val = 0x2e },
- { .rfmax = 279000, .val = 0x2f },
- { .rfmax = 282000, .val = 0x30 },
- { .rfmax = 284000, .val = 0x31 },
- { .rfmax = 286000, .val = 0x32 },
- { .rfmax = 287000, .val = 0x33 },
- { .rfmax = 290000, .val = 0x34 },
- { .rfmax = 293000, .val = 0x35 },
- { .rfmax = 295000, .val = 0x36 },
- { .rfmax = 297000, .val = 0x37 },
- { .rfmax = 300000, .val = 0x38 },
- { .rfmax = 303000, .val = 0x39 },
- { .rfmax = 305000, .val = 0x3a },
- { .rfmax = 306000, .val = 0x3b },
- { .rfmax = 307000, .val = 0x3c },
- { .rfmax = 310000, .val = 0x3d },
- { .rfmax = 312000, .val = 0x3e },
- { .rfmax = 315000, .val = 0x3f },
- { .rfmax = 318000, .val = 0x40 },
- { .rfmax = 320000, .val = 0x41 },
- { .rfmax = 323000, .val = 0x42 },
- { .rfmax = 324000, .val = 0x43 },
- { .rfmax = 325000, .val = 0x44 },
- { .rfmax = 327000, .val = 0x45 },
- { .rfmax = 331000, .val = 0x46 },
- { .rfmax = 334000, .val = 0x47 },
- { .rfmax = 337000, .val = 0x48 },
- { .rfmax = 339000, .val = 0x49 },
- { .rfmax = 340000, .val = 0x4a },
- { .rfmax = 341000, .val = 0x4b },
- { .rfmax = 343000, .val = 0x4c },
- { .rfmax = 345000, .val = 0x4d },
- { .rfmax = 349000, .val = 0x4e },
- { .rfmax = 352000, .val = 0x4f },
- { .rfmax = 353000, .val = 0x50 },
- { .rfmax = 355000, .val = 0x51 },
- { .rfmax = 357000, .val = 0x52 },
- { .rfmax = 359000, .val = 0x53 },
- { .rfmax = 361000, .val = 0x54 },
- { .rfmax = 362000, .val = 0x55 },
- { .rfmax = 364000, .val = 0x56 },
- { .rfmax = 368000, .val = 0x57 },
- { .rfmax = 370000, .val = 0x58 },
- { .rfmax = 372000, .val = 0x59 },
- { .rfmax = 375000, .val = 0x5a },
- { .rfmax = 376000, .val = 0x5b },
- { .rfmax = 377000, .val = 0x5c },
- { .rfmax = 379000, .val = 0x5d },
- { .rfmax = 382000, .val = 0x5e },
- { .rfmax = 384000, .val = 0x5f },
- { .rfmax = 385000, .val = 0x60 },
- { .rfmax = 386000, .val = 0x61 },
- { .rfmax = 388000, .val = 0x62 },
- { .rfmax = 390000, .val = 0x63 },
- { .rfmax = 393000, .val = 0x64 },
- { .rfmax = 394000, .val = 0x65 },
- { .rfmax = 396000, .val = 0x66 },
- { .rfmax = 397000, .val = 0x67 },
- { .rfmax = 398000, .val = 0x68 },
- { .rfmax = 400000, .val = 0x69 },
- { .rfmax = 402000, .val = 0x6a },
- { .rfmax = 403000, .val = 0x6b },
- { .rfmax = 407000, .val = 0x6c },
- { .rfmax = 408000, .val = 0x6d },
- { .rfmax = 409000, .val = 0x6e },
- { .rfmax = 410000, .val = 0x6f },
- { .rfmax = 411000, .val = 0x70 },
- { .rfmax = 412000, .val = 0x71 },
- { .rfmax = 413000, .val = 0x72 },
- { .rfmax = 414000, .val = 0x73 },
- { .rfmax = 417000, .val = 0x74 },
- { .rfmax = 418000, .val = 0x75 },
- { .rfmax = 420000, .val = 0x76 },
- { .rfmax = 422000, .val = 0x77 },
- { .rfmax = 423000, .val = 0x78 },
- { .rfmax = 424000, .val = 0x79 },
- { .rfmax = 427000, .val = 0x7a },
- { .rfmax = 428000, .val = 0x7b },
- { .rfmax = 429000, .val = 0x7d },
- { .rfmax = 432000, .val = 0x7f },
- { .rfmax = 434000, .val = 0x80 },
- { .rfmax = 435000, .val = 0x81 },
- { .rfmax = 436000, .val = 0x83 },
- { .rfmax = 437000, .val = 0x84 },
- { .rfmax = 438000, .val = 0x85 },
- { .rfmax = 439000, .val = 0x86 },
- { .rfmax = 440000, .val = 0x87 },
- { .rfmax = 441000, .val = 0x88 },
- { .rfmax = 442000, .val = 0x89 },
- { .rfmax = 445000, .val = 0x8a },
- { .rfmax = 446000, .val = 0x8b },
- { .rfmax = 447000, .val = 0x8c },
- { .rfmax = 448000, .val = 0x8e },
- { .rfmax = 449000, .val = 0x8f },
- { .rfmax = 450000, .val = 0x90 },
- { .rfmax = 452000, .val = 0x91 },
- { .rfmax = 453000, .val = 0x93 },
- { .rfmax = 454000, .val = 0x94 },
- { .rfmax = 456000, .val = 0x96 },
- { .rfmax = 457000, .val = 0x98 },
- { .rfmax = 461000, .val = 0x11 },
- { .rfmax = 468000, .val = 0x12 },
- { .rfmax = 472000, .val = 0x13 },
- { .rfmax = 473000, .val = 0x14 },
- { .rfmax = 474000, .val = 0x15 },
- { .rfmax = 481000, .val = 0x16 },
- { .rfmax = 486000, .val = 0x17 },
- { .rfmax = 491000, .val = 0x18 },
- { .rfmax = 498000, .val = 0x19 },
- { .rfmax = 499000, .val = 0x1a },
- { .rfmax = 501000, .val = 0x1b },
- { .rfmax = 506000, .val = 0x1c },
- { .rfmax = 511000, .val = 0x1d },
- { .rfmax = 516000, .val = 0x1e },
- { .rfmax = 520000, .val = 0x1f },
- { .rfmax = 521000, .val = 0x20 },
- { .rfmax = 525000, .val = 0x21 },
- { .rfmax = 529000, .val = 0x22 },
- { .rfmax = 533000, .val = 0x23 },
- { .rfmax = 539000, .val = 0x24 },
- { .rfmax = 541000, .val = 0x25 },
- { .rfmax = 547000, .val = 0x26 },
- { .rfmax = 549000, .val = 0x27 },
- { .rfmax = 551000, .val = 0x28 },
- { .rfmax = 556000, .val = 0x29 },
- { .rfmax = 561000, .val = 0x2a },
- { .rfmax = 563000, .val = 0x2b },
- { .rfmax = 565000, .val = 0x2c },
- { .rfmax = 569000, .val = 0x2d },
- { .rfmax = 571000, .val = 0x2e },
- { .rfmax = 577000, .val = 0x2f },
- { .rfmax = 580000, .val = 0x30 },
- { .rfmax = 582000, .val = 0x31 },
- { .rfmax = 584000, .val = 0x32 },
- { .rfmax = 588000, .val = 0x33 },
- { .rfmax = 591000, .val = 0x34 },
- { .rfmax = 596000, .val = 0x35 },
- { .rfmax = 598000, .val = 0x36 },
- { .rfmax = 603000, .val = 0x37 },
- { .rfmax = 604000, .val = 0x38 },
- { .rfmax = 606000, .val = 0x39 },
- { .rfmax = 612000, .val = 0x3a },
- { .rfmax = 615000, .val = 0x3b },
- { .rfmax = 617000, .val = 0x3c },
- { .rfmax = 621000, .val = 0x3d },
- { .rfmax = 622000, .val = 0x3e },
- { .rfmax = 625000, .val = 0x3f },
- { .rfmax = 632000, .val = 0x40 },
- { .rfmax = 633000, .val = 0x41 },
- { .rfmax = 634000, .val = 0x42 },
- { .rfmax = 642000, .val = 0x43 },
- { .rfmax = 643000, .val = 0x44 },
- { .rfmax = 647000, .val = 0x45 },
- { .rfmax = 650000, .val = 0x46 },
- { .rfmax = 652000, .val = 0x47 },
- { .rfmax = 657000, .val = 0x48 },
- { .rfmax = 661000, .val = 0x49 },
- { .rfmax = 662000, .val = 0x4a },
- { .rfmax = 665000, .val = 0x4b },
- { .rfmax = 667000, .val = 0x4c },
- { .rfmax = 670000, .val = 0x4d },
- { .rfmax = 673000, .val = 0x4e },
- { .rfmax = 676000, .val = 0x4f },
- { .rfmax = 677000, .val = 0x50 },
- { .rfmax = 681000, .val = 0x51 },
- { .rfmax = 683000, .val = 0x52 },
- { .rfmax = 686000, .val = 0x53 },
- { .rfmax = 688000, .val = 0x54 },
- { .rfmax = 689000, .val = 0x55 },
- { .rfmax = 691000, .val = 0x56 },
- { .rfmax = 695000, .val = 0x57 },
- { .rfmax = 698000, .val = 0x58 },
- { .rfmax = 703000, .val = 0x59 },
- { .rfmax = 704000, .val = 0x5a },
- { .rfmax = 705000, .val = 0x5b },
- { .rfmax = 707000, .val = 0x5c },
- { .rfmax = 710000, .val = 0x5d },
- { .rfmax = 712000, .val = 0x5e },
- { .rfmax = 717000, .val = 0x5f },
- { .rfmax = 718000, .val = 0x60 },
- { .rfmax = 721000, .val = 0x61 },
- { .rfmax = 722000, .val = 0x62 },
- { .rfmax = 723000, .val = 0x63 },
- { .rfmax = 725000, .val = 0x64 },
- { .rfmax = 727000, .val = 0x65 },
- { .rfmax = 730000, .val = 0x66 },
- { .rfmax = 732000, .val = 0x67 },
- { .rfmax = 735000, .val = 0x68 },
- { .rfmax = 740000, .val = 0x69 },
- { .rfmax = 741000, .val = 0x6a },
- { .rfmax = 742000, .val = 0x6b },
- { .rfmax = 743000, .val = 0x6c },
- { .rfmax = 745000, .val = 0x6d },
- { .rfmax = 747000, .val = 0x6e },
- { .rfmax = 748000, .val = 0x6f },
- { .rfmax = 750000, .val = 0x70 },
- { .rfmax = 752000, .val = 0x71 },
- { .rfmax = 754000, .val = 0x72 },
- { .rfmax = 757000, .val = 0x73 },
- { .rfmax = 758000, .val = 0x74 },
- { .rfmax = 760000, .val = 0x75 },
- { .rfmax = 763000, .val = 0x76 },
- { .rfmax = 764000, .val = 0x77 },
- { .rfmax = 766000, .val = 0x78 },
- { .rfmax = 767000, .val = 0x79 },
- { .rfmax = 768000, .val = 0x7a },
- { .rfmax = 773000, .val = 0x7b },
- { .rfmax = 774000, .val = 0x7c },
- { .rfmax = 776000, .val = 0x7d },
- { .rfmax = 777000, .val = 0x7e },
- { .rfmax = 778000, .val = 0x7f },
- { .rfmax = 779000, .val = 0x80 },
- { .rfmax = 781000, .val = 0x81 },
- { .rfmax = 783000, .val = 0x82 },
- { .rfmax = 784000, .val = 0x83 },
- { .rfmax = 785000, .val = 0x84 },
- { .rfmax = 786000, .val = 0x85 },
- { .rfmax = 793000, .val = 0x86 },
- { .rfmax = 794000, .val = 0x87 },
- { .rfmax = 795000, .val = 0x88 },
- { .rfmax = 797000, .val = 0x89 },
- { .rfmax = 799000, .val = 0x8a },
- { .rfmax = 801000, .val = 0x8b },
- { .rfmax = 802000, .val = 0x8c },
- { .rfmax = 803000, .val = 0x8d },
- { .rfmax = 804000, .val = 0x8e },
- { .rfmax = 810000, .val = 0x90 },
- { .rfmax = 811000, .val = 0x91 },
- { .rfmax = 812000, .val = 0x92 },
- { .rfmax = 814000, .val = 0x93 },
- { .rfmax = 816000, .val = 0x94 },
- { .rfmax = 817000, .val = 0x96 },
- { .rfmax = 818000, .val = 0x97 },
- { .rfmax = 820000, .val = 0x98 },
- { .rfmax = 821000, .val = 0x99 },
- { .rfmax = 822000, .val = 0x9a },
- { .rfmax = 828000, .val = 0x9b },
- { .rfmax = 829000, .val = 0x9d },
- { .rfmax = 830000, .val = 0x9f },
- { .rfmax = 831000, .val = 0xa0 },
- { .rfmax = 833000, .val = 0xa1 },
- { .rfmax = 835000, .val = 0xa2 },
- { .rfmax = 836000, .val = 0xa3 },
- { .rfmax = 837000, .val = 0xa4 },
- { .rfmax = 838000, .val = 0xa6 },
- { .rfmax = 840000, .val = 0xa8 },
- { .rfmax = 842000, .val = 0xa9 },
- { .rfmax = 845000, .val = 0xaa },
- { .rfmax = 846000, .val = 0xab },
- { .rfmax = 847000, .val = 0xad },
- { .rfmax = 848000, .val = 0xae },
- { .rfmax = 852000, .val = 0xaf },
- { .rfmax = 853000, .val = 0xb0 },
- { .rfmax = 858000, .val = 0xb1 },
- { .rfmax = 860000, .val = 0xb2 },
- { .rfmax = 861000, .val = 0xb3 },
- { .rfmax = 862000, .val = 0xb4 },
- { .rfmax = 863000, .val = 0xb6 },
- { .rfmax = 864000, .val = 0xb8 },
- { .rfmax = 865000, .val = 0xb9 },
- { .rfmax = 0, .val = 0x00 }, /* end */
-};
-
-static struct tda18271_map tda18271_ir_measure[] = {
- { .rfmax = 30000, .val = 4 },
- { .rfmax = 200000, .val = 5 },
- { .rfmax = 600000, .val = 6 },
- { .rfmax = 865000, .val = 7 },
- { .rfmax = 0, .val = 0 }, /* end */
-};
-
-static struct tda18271_map tda18271_rf_cal_dc_over_dt[] = {
- { .rfmax = 47900, .val = 0x00 },
- { .rfmax = 55000, .val = 0x00 },
- { .rfmax = 61100, .val = 0x0a },
- { .rfmax = 64000, .val = 0x0a },
- { .rfmax = 82000, .val = 0x14 },
- { .rfmax = 84000, .val = 0x19 },
- { .rfmax = 119000, .val = 0x1c },
- { .rfmax = 124000, .val = 0x20 },
- { .rfmax = 129000, .val = 0x2a },
- { .rfmax = 134000, .val = 0x32 },
- { .rfmax = 139000, .val = 0x39 },
- { .rfmax = 144000, .val = 0x3e },
- { .rfmax = 149000, .val = 0x3f },
- { .rfmax = 152600, .val = 0x40 },
- { .rfmax = 154000, .val = 0x40 },
- { .rfmax = 164700, .val = 0x41 },
- { .rfmax = 203500, .val = 0x32 },
- { .rfmax = 353000, .val = 0x19 },
- { .rfmax = 356000, .val = 0x1a },
- { .rfmax = 359000, .val = 0x1b },
- { .rfmax = 363000, .val = 0x1c },
- { .rfmax = 366000, .val = 0x1d },
- { .rfmax = 369000, .val = 0x1e },
- { .rfmax = 373000, .val = 0x1f },
- { .rfmax = 376000, .val = 0x20 },
- { .rfmax = 379000, .val = 0x21 },
- { .rfmax = 383000, .val = 0x22 },
- { .rfmax = 386000, .val = 0x23 },
- { .rfmax = 389000, .val = 0x24 },
- { .rfmax = 393000, .val = 0x25 },
- { .rfmax = 396000, .val = 0x26 },
- { .rfmax = 399000, .val = 0x27 },
- { .rfmax = 402000, .val = 0x28 },
- { .rfmax = 404000, .val = 0x29 },
- { .rfmax = 407000, .val = 0x2a },
- { .rfmax = 409000, .val = 0x2b },
- { .rfmax = 412000, .val = 0x2c },
- { .rfmax = 414000, .val = 0x2d },
- { .rfmax = 417000, .val = 0x2e },
- { .rfmax = 419000, .val = 0x2f },
- { .rfmax = 422000, .val = 0x30 },
- { .rfmax = 424000, .val = 0x31 },
- { .rfmax = 427000, .val = 0x32 },
- { .rfmax = 429000, .val = 0x33 },
- { .rfmax = 432000, .val = 0x34 },
- { .rfmax = 434000, .val = 0x35 },
- { .rfmax = 437000, .val = 0x36 },
- { .rfmax = 439000, .val = 0x37 },
- { .rfmax = 442000, .val = 0x38 },
- { .rfmax = 444000, .val = 0x39 },
- { .rfmax = 447000, .val = 0x3a },
- { .rfmax = 449000, .val = 0x3b },
- { .rfmax = 457800, .val = 0x3c },
- { .rfmax = 465000, .val = 0x0f },
- { .rfmax = 477000, .val = 0x12 },
- { .rfmax = 483000, .val = 0x14 },
- { .rfmax = 502000, .val = 0x19 },
- { .rfmax = 508000, .val = 0x1b },
- { .rfmax = 519000, .val = 0x1c },
- { .rfmax = 522000, .val = 0x1d },
- { .rfmax = 524000, .val = 0x1e },
- { .rfmax = 534000, .val = 0x1f },
- { .rfmax = 549000, .val = 0x20 },
- { .rfmax = 554000, .val = 0x22 },
- { .rfmax = 584000, .val = 0x24 },
- { .rfmax = 589000, .val = 0x26 },
- { .rfmax = 658000, .val = 0x27 },
- { .rfmax = 664000, .val = 0x2c },
- { .rfmax = 669000, .val = 0x2d },
- { .rfmax = 699000, .val = 0x2e },
- { .rfmax = 704000, .val = 0x30 },
- { .rfmax = 709000, .val = 0x31 },
- { .rfmax = 714000, .val = 0x32 },
- { .rfmax = 724000, .val = 0x33 },
- { .rfmax = 729000, .val = 0x36 },
- { .rfmax = 739000, .val = 0x38 },
- { .rfmax = 744000, .val = 0x39 },
- { .rfmax = 749000, .val = 0x3b },
- { .rfmax = 754000, .val = 0x3c },
- { .rfmax = 759000, .val = 0x3d },
- { .rfmax = 764000, .val = 0x3e },
- { .rfmax = 769000, .val = 0x3f },
- { .rfmax = 774000, .val = 0x40 },
- { .rfmax = 779000, .val = 0x41 },
- { .rfmax = 784000, .val = 0x43 },
- { .rfmax = 789000, .val = 0x46 },
- { .rfmax = 794000, .val = 0x48 },
- { .rfmax = 799000, .val = 0x4b },
- { .rfmax = 804000, .val = 0x4f },
- { .rfmax = 809000, .val = 0x54 },
- { .rfmax = 814000, .val = 0x59 },
- { .rfmax = 819000, .val = 0x5d },
- { .rfmax = 824000, .val = 0x61 },
- { .rfmax = 829000, .val = 0x68 },
- { .rfmax = 834000, .val = 0x6e },
- { .rfmax = 839000, .val = 0x75 },
- { .rfmax = 844000, .val = 0x7e },
- { .rfmax = 849000, .val = 0x82 },
- { .rfmax = 854000, .val = 0x84 },
- { .rfmax = 859000, .val = 0x8f },
- { .rfmax = 865000, .val = 0x9a },
- { .rfmax = 0, .val = 0x00 }, /* end */
-};
-
-/*---------------------------------------------------------------------*/
-
-struct tda18271_thermo_map {
- u8 d;
- u8 r0;
- u8 r1;
-};
-
-static struct tda18271_thermo_map tda18271_thermometer[] = {
- { .d = 0x00, .r0 = 60, .r1 = 92 },
- { .d = 0x01, .r0 = 62, .r1 = 94 },
- { .d = 0x02, .r0 = 66, .r1 = 98 },
- { .d = 0x03, .r0 = 64, .r1 = 96 },
- { .d = 0x04, .r0 = 74, .r1 = 106 },
- { .d = 0x05, .r0 = 72, .r1 = 104 },
- { .d = 0x06, .r0 = 68, .r1 = 100 },
- { .d = 0x07, .r0 = 70, .r1 = 102 },
- { .d = 0x08, .r0 = 90, .r1 = 122 },
- { .d = 0x09, .r0 = 88, .r1 = 120 },
- { .d = 0x0a, .r0 = 84, .r1 = 116 },
- { .d = 0x0b, .r0 = 86, .r1 = 118 },
- { .d = 0x0c, .r0 = 76, .r1 = 108 },
- { .d = 0x0d, .r0 = 78, .r1 = 110 },
- { .d = 0x0e, .r0 = 82, .r1 = 114 },
- { .d = 0x0f, .r0 = 80, .r1 = 112 },
- { .d = 0x00, .r0 = 0, .r1 = 0 }, /* end */
-};
-
-int tda18271_lookup_thermometer(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- unsigned char *regs = priv->tda18271_regs;
- int val, i = 0;
-
- while (tda18271_thermometer[i].d < (regs[R_TM] & 0x0f)) {
- if (tda18271_thermometer[i + 1].d == 0)
- break;
- i++;
- }
-
- if ((regs[R_TM] & 0x20) == 0x20)
- val = tda18271_thermometer[i].r1;
- else
- val = tda18271_thermometer[i].r0;
-
- tda_map("(%d) tm = %d\n", i, val);
-
- return val;
-}
-
-/*---------------------------------------------------------------------*/
-
-struct tda18271_cid_target_map {
- u32 rfmax;
- u8 target;
- u16 limit;
-};
-
-static struct tda18271_cid_target_map tda18271_cid_target[] = {
- { .rfmax = 46000, .target = 0x04, .limit = 1800 },
- { .rfmax = 52200, .target = 0x0a, .limit = 1500 },
- { .rfmax = 79100, .target = 0x01, .limit = 4000 },
- { .rfmax = 136800, .target = 0x18, .limit = 4000 },
- { .rfmax = 156700, .target = 0x18, .limit = 4000 },
- { .rfmax = 156700, .target = 0x18, .limit = 4000 },
- { .rfmax = 186250, .target = 0x0a, .limit = 4000 },
- { .rfmax = 230000, .target = 0x0a, .limit = 4000 },
- { .rfmax = 345000, .target = 0x18, .limit = 4000 },
- { .rfmax = 426000, .target = 0x0e, .limit = 4000 },
- { .rfmax = 489500, .target = 0x1e, .limit = 4000 },
- { .rfmax = 697500, .target = 0x32, .limit = 4000 },
- { .rfmax = 842000, .target = 0x3a, .limit = 4000 },
- { .rfmax = 0, .target = 0x00, .limit = 0 }, /* end */
-};
-
-int tda18271_lookup_cid_target(struct dvb_frontend *fe,
- u32 *freq, u8 *cid_target, u16 *count_limit)
-{
- int i = 0;
-
- while ((tda18271_cid_target[i].rfmax * 1000) < *freq) {
- if (tda18271_cid_target[i + 1].rfmax == 0)
- break;
- i++;
- }
- *cid_target = tda18271_cid_target[i].target;
- *count_limit = tda18271_cid_target[i].limit;
-
- tda_map("(%d) cid_target = %02x, count_limit = %d\n", i,
- tda18271_cid_target[i].target, tda18271_cid_target[i].limit);
-
- return 0;
-}
-
-/*---------------------------------------------------------------------*/
-
-static struct tda18271_rf_tracking_filter_cal tda18271_rf_band_template[] = {
- { .rfmax = 47900, .rfband = 0x00,
- .rf1_def = 46000, .rf2_def = 0, .rf3_def = 0 },
- { .rfmax = 61100, .rfband = 0x01,
- .rf1_def = 52200, .rf2_def = 0, .rf3_def = 0 },
- { .rfmax = 152600, .rfband = 0x02,
- .rf1_def = 70100, .rf2_def = 136800, .rf3_def = 0 },
- { .rfmax = 164700, .rfband = 0x03,
- .rf1_def = 156700, .rf2_def = 0, .rf3_def = 0 },
- { .rfmax = 203500, .rfband = 0x04,
- .rf1_def = 186250, .rf2_def = 0, .rf3_def = 0 },
- { .rfmax = 457800, .rfband = 0x05,
- .rf1_def = 230000, .rf2_def = 345000, .rf3_def = 426000 },
- { .rfmax = 865000, .rfband = 0x06,
- .rf1_def = 489500, .rf2_def = 697500, .rf3_def = 842000 },
- { .rfmax = 0, .rfband = 0x00,
- .rf1_def = 0, .rf2_def = 0, .rf3_def = 0 }, /* end */
-};
-
-int tda18271_lookup_rf_band(struct dvb_frontend *fe, u32 *freq, u8 *rf_band)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
- int i = 0;
-
- while ((map[i].rfmax * 1000) < *freq) {
- if (tda18271_debug & DBG_ADV)
- tda_map("(%d) rfmax = %d < freq = %d, "
- "rf1_def = %d, rf2_def = %d, rf3_def = %d, "
- "rf1 = %d, rf2 = %d, rf3 = %d, "
- "rf_a1 = %d, rf_a2 = %d, "
- "rf_b1 = %d, rf_b2 = %d\n",
- i, map[i].rfmax * 1000, *freq,
- map[i].rf1_def, map[i].rf2_def, map[i].rf3_def,
- map[i].rf1, map[i].rf2, map[i].rf3,
- map[i].rf_a1, map[i].rf_a2,
- map[i].rf_b1, map[i].rf_b2);
- if (map[i].rfmax == 0)
- return -EINVAL;
- i++;
- }
- if (rf_band)
- *rf_band = map[i].rfband;
-
- tda_map("(%d) rf_band = %02x\n", i, map[i].rfband);
-
- return i;
-}
-
-/*---------------------------------------------------------------------*/
-
-struct tda18271_map_layout {
- struct tda18271_pll_map *main_pll;
- struct tda18271_pll_map *cal_pll;
-
- struct tda18271_map *rf_cal;
- struct tda18271_map *rf_cal_kmco;
- struct tda18271_map *rf_cal_dc_over_dt;
-
- struct tda18271_map *bp_filter;
- struct tda18271_map *rf_band;
- struct tda18271_map *gain_taper;
- struct tda18271_map *ir_measure;
-};
-
-/*---------------------------------------------------------------------*/
-
-int tda18271_lookup_pll_map(struct dvb_frontend *fe,
- enum tda18271_map_type map_type,
- u32 *freq, u8 *post_div, u8 *div)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- struct tda18271_pll_map *map = NULL;
- unsigned int i = 0;
- char *map_name;
- int ret = 0;
-
- BUG_ON(!priv->maps);
-
- switch (map_type) {
- case MAIN_PLL:
- map = priv->maps->main_pll;
- map_name = "main_pll";
- break;
- case CAL_PLL:
- map = priv->maps->cal_pll;
- map_name = "cal_pll";
- break;
- default:
- /* we should never get here */
- map_name = "undefined";
- break;
- }
-
- if (!map) {
- tda_warn("%s map is not set!\n", map_name);
- ret = -EINVAL;
- goto fail;
- }
-
- while ((map[i].lomax * 1000) < *freq) {
- if (map[i + 1].lomax == 0) {
- tda_map("%s: frequency (%d) out of range\n",
- map_name, *freq);
- ret = -ERANGE;
- break;
- }
- i++;
- }
- *post_div = map[i].pd;
- *div = map[i].d;
-
- tda_map("(%d) %s: post div = 0x%02x, div = 0x%02x\n",
- i, map_name, *post_div, *div);
-fail:
- return ret;
-}
-
-int tda18271_lookup_map(struct dvb_frontend *fe,
- enum tda18271_map_type map_type,
- u32 *freq, u8 *val)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- struct tda18271_map *map = NULL;
- unsigned int i = 0;
- char *map_name;
- int ret = 0;
-
- BUG_ON(!priv->maps);
-
- switch (map_type) {
- case BP_FILTER:
- map = priv->maps->bp_filter;
- map_name = "bp_filter";
- break;
- case RF_CAL_KMCO:
- map = priv->maps->rf_cal_kmco;
- map_name = "km";
- break;
- case RF_BAND:
- map = priv->maps->rf_band;
- map_name = "rf_band";
- break;
- case GAIN_TAPER:
- map = priv->maps->gain_taper;
- map_name = "gain_taper";
- break;
- case RF_CAL:
- map = priv->maps->rf_cal;
- map_name = "rf_cal";
- break;
- case IR_MEASURE:
- map = priv->maps->ir_measure;
- map_name = "ir_measure";
- break;
- case RF_CAL_DC_OVER_DT:
- map = priv->maps->rf_cal_dc_over_dt;
- map_name = "rf_cal_dc_over_dt";
- break;
- default:
- /* we should never get here */
- map_name = "undefined";
- break;
- }
-
- if (!map) {
- tda_warn("%s map is not set!\n", map_name);
- ret = -EINVAL;
- goto fail;
- }
-
- while ((map[i].rfmax * 1000) < *freq) {
- if (map[i + 1].rfmax == 0) {
- tda_map("%s: frequency (%d) out of range\n",
- map_name, *freq);
- ret = -ERANGE;
- break;
- }
- i++;
- }
- *val = map[i].val;
-
- tda_map("(%d) %s: 0x%02x\n", i, map_name, *val);
-fail:
- return ret;
-}
-
-/*---------------------------------------------------------------------*/
-
-static struct tda18271_std_map tda18271c1_std_map = {
- .fm_radio = { .if_freq = 1250, .fm_rfn = 1, .agc_mode = 3, .std = 0,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x18 */
- .atv_b = { .if_freq = 6750, .fm_rfn = 0, .agc_mode = 1, .std = 6,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
- .atv_dk = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
- .atv_gh = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
- .atv_i = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
- .atv_l = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
- .atv_lc = { .if_freq = 1250, .fm_rfn = 0, .agc_mode = 1, .std = 7,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
- .atv_mn = { .if_freq = 5750, .fm_rfn = 0, .agc_mode = 1, .std = 5,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0d */
- .atsc_6 = { .if_freq = 3250, .fm_rfn = 0, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
- .dvbt_6 = { .if_freq = 3300, .fm_rfn = 0, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
- .dvbt_7 = { .if_freq = 3800, .fm_rfn = 0, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
- .dvbt_8 = { .if_freq = 4300, .fm_rfn = 0, .agc_mode = 3, .std = 6,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1e */
- .qam_6 = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
- .qam_8 = { .if_freq = 5000, .fm_rfn = 0, .agc_mode = 3, .std = 7,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1f */
-};
-
-static struct tda18271_std_map tda18271c2_std_map = {
- .fm_radio = { .if_freq = 1250, .fm_rfn = 1, .agc_mode = 3, .std = 0,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x18 */
- .atv_b = { .if_freq = 6000, .fm_rfn = 0, .agc_mode = 1, .std = 5,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0d */
- .atv_dk = { .if_freq = 6900, .fm_rfn = 0, .agc_mode = 1, .std = 6,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
- .atv_gh = { .if_freq = 7100, .fm_rfn = 0, .agc_mode = 1, .std = 6,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
- .atv_i = { .if_freq = 7250, .fm_rfn = 0, .agc_mode = 1, .std = 6,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
- .atv_l = { .if_freq = 6900, .fm_rfn = 0, .agc_mode = 1, .std = 6,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
- .atv_lc = { .if_freq = 1250, .fm_rfn = 0, .agc_mode = 1, .std = 6,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
- .atv_mn = { .if_freq = 5400, .fm_rfn = 0, .agc_mode = 1, .std = 4,
- .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0c */
- .atsc_6 = { .if_freq = 3250, .fm_rfn = 0, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
- .dvbt_6 = { .if_freq = 3300, .fm_rfn = 0, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
- .dvbt_7 = { .if_freq = 3500, .fm_rfn = 0, .agc_mode = 3, .std = 4,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
- .dvbt_8 = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
- .qam_6 = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
- .qam_8 = { .if_freq = 5000, .fm_rfn = 0, .agc_mode = 3, .std = 7,
- .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1f */
-};
-
-/*---------------------------------------------------------------------*/
-
-static struct tda18271_map_layout tda18271c1_map_layout = {
- .main_pll = tda18271c1_main_pll,
- .cal_pll = tda18271c1_cal_pll,
-
- .rf_cal = tda18271c1_rf_cal,
- .rf_cal_kmco = tda18271c1_km,
-
- .bp_filter = tda18271_bp_filter,
- .rf_band = tda18271_rf_band,
- .gain_taper = tda18271_gain_taper,
- .ir_measure = tda18271_ir_measure,
-};
-
-static struct tda18271_map_layout tda18271c2_map_layout = {
- .main_pll = tda18271c2_main_pll,
- .cal_pll = tda18271c2_cal_pll,
-
- .rf_cal = tda18271c2_rf_cal,
- .rf_cal_kmco = tda18271c2_km,
-
- .rf_cal_dc_over_dt = tda18271_rf_cal_dc_over_dt,
-
- .bp_filter = tda18271_bp_filter,
- .rf_band = tda18271_rf_band,
- .gain_taper = tda18271_gain_taper,
- .ir_measure = tda18271_ir_measure,
-};
-
-int tda18271_assign_map_layout(struct dvb_frontend *fe)
-{
- struct tda18271_priv *priv = fe->tuner_priv;
- int ret = 0;
-
- switch (priv->id) {
- case TDA18271HDC1:
- priv->maps = &tda18271c1_map_layout;
- memcpy(&priv->std, &tda18271c1_std_map,
- sizeof(struct tda18271_std_map));
- break;
- case TDA18271HDC2:
- priv->maps = &tda18271c2_map_layout;
- memcpy(&priv->std, &tda18271c2_std_map,
- sizeof(struct tda18271_std_map));
- break;
- default:
- ret = -EINVAL;
- break;
- }
- memcpy(priv->rf_cal_state, &tda18271_rf_band_template,
- sizeof(tda18271_rf_band_template));
-
- return ret;
-}
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/linux/drivers/media/dvb/frontends/tda18271.h b/linux/drivers/media/dvb/frontends/tda18271.h
deleted file mode 100644
index b547318c9..000000000
--- a/linux/drivers/media/dvb/frontends/tda18271.h
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- tda18271.h - header for the Philips / NXP TDA18271 silicon tuner
-
- Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
-
- 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 __TDA18271_H__
-#define __TDA18271_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-struct tda18271_std_map_item {
- u16 if_freq;
-
- /* EP3[4:3] */
- unsigned int agc_mode:2;
- /* EP3[2:0] */
- unsigned int std:3;
- /* EP4[7] */
- unsigned int fm_rfn:1;
- /* EP4[4:2] */
- unsigned int if_lvl:3;
- /* EB22[6:0] */
- unsigned int rfagc_top:7;
-};
-
-struct tda18271_std_map {
- struct tda18271_std_map_item fm_radio;
- struct tda18271_std_map_item atv_b;
- struct tda18271_std_map_item atv_dk;
- struct tda18271_std_map_item atv_gh;
- struct tda18271_std_map_item atv_i;
- struct tda18271_std_map_item atv_l;
- struct tda18271_std_map_item atv_lc;
- struct tda18271_std_map_item atv_mn;
- struct tda18271_std_map_item atsc_6;
- struct tda18271_std_map_item dvbt_6;
- struct tda18271_std_map_item dvbt_7;
- struct tda18271_std_map_item dvbt_8;
- struct tda18271_std_map_item qam_6;
- struct tda18271_std_map_item qam_8;
-};
-
-enum tda18271_role {
- TDA18271_MASTER = 0,
- TDA18271_SLAVE,
-};
-
-enum tda18271_i2c_gate {
- TDA18271_GATE_AUTO = 0,
- TDA18271_GATE_ANALOG,
- TDA18271_GATE_DIGITAL,
-};
-
-struct tda18271_config {
- /* override default if freq / std settings (optional) */
- struct tda18271_std_map *std_map;
-
- /* master / slave tuner: master uses main pll, slave uses cal pll */
- enum tda18271_role role;
-
- /* use i2c gate provided by analog or digital demod */
- enum tda18271_i2c_gate gate;
-
- /* some i2c providers cant write all 39 registers at once */
- unsigned int small_i2c:1;
-};
-
-#if defined(CONFIG_DVB_TDA18271) || (defined(CONFIG_DVB_TDA18271_MODULE) && defined(MODULE))
-extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
- struct i2c_adapter *i2c,
- struct tda18271_config *cfg);
-#else
-static inline struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe,
- u8 addr,
- struct i2c_adapter *i2c,
- struct tda18271_config *cfg)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
- return NULL;
-}
-#endif
-
-#endif /* __TDA18271_H__ */
diff --git a/linux/drivers/media/dvb/frontends/tda8083.c b/linux/drivers/media/dvb/frontends/tda8083.c
index 011b74f79..5b843b2e6 100644
--- a/linux/drivers/media/dvb/frontends/tda8083.c
+++ b/linux/drivers/media/dvb/frontends/tda8083.c
@@ -68,7 +68,7 @@ static int tda8083_writereg (struct tda8083_state* state, u8 reg, u8 data)
if (ret != 1)
dprintk ("%s: writereg error (reg %02x, ret == %i)\n",
- __FUNCTION__, reg, ret);
+ __func__, reg, ret);
return (ret != 1) ? -1 : 0;
}
@@ -83,7 +83,7 @@ static int tda8083_readregs (struct tda8083_state* state, u8 reg1, u8 *b, u8 len
if (ret != 2)
dprintk ("%s: readreg error (reg %02x, ret == %i)\n",
- __FUNCTION__, reg1, ret);
+ __func__, reg1, ret);
return ret == 2 ? 0 : -1;
}
diff --git a/linux/drivers/media/dvb/frontends/tda8083.h b/linux/drivers/media/dvb/frontends/tda8083.h
index 2d3307999..5a03c14a1 100644
--- a/linux/drivers/media/dvb/frontends/tda8083.h
+++ b/linux/drivers/media/dvb/frontends/tda8083.h
@@ -42,7 +42,7 @@ extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_TDA8083
diff --git a/linux/drivers/media/dvb/frontends/tda826x.c b/linux/drivers/media/dvb/frontends/tda826x.c
index 71c486b4e..596fc4275 100644
--- a/linux/drivers/media/dvb/frontends/tda826x.c
+++ b/linux/drivers/media/dvb/frontends/tda826x.c
@@ -55,7 +55,7 @@ static int tda826x_sleep(struct dvb_frontend *fe)
u8 buf [] = { 0x00, 0x8d };
struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 };
- dprintk("%s:\n", __FUNCTION__);
+ dprintk("%s:\n", __func__);
if (!priv->has_loopthrough)
buf[1] = 0xad;
@@ -63,7 +63,7 @@ static int tda826x_sleep(struct dvb_frontend *fe)
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
- dprintk("%s: i2c error\n", __FUNCTION__);
+ dprintk("%s: i2c error\n", __func__);
}
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -76,13 +76,24 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param
struct tda826x_priv *priv = fe->tuner_priv;
int ret;
u32 div;
+ u32 ksyms;
+ u32 bandwidth;
u8 buf [11];
struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 };
- dprintk("%s:\n", __FUNCTION__);
+ dprintk("%s:\n", __func__);
div = (params->frequency + (1000-1)) / 1000;
+ /* BW = ((1 + RO) * SR/2 + 5) * 1.3 [SR in MSPS, BW in MHz] */
+ /* with R0 = 0.35 and some transformations: */
+ ksyms = params->u.qpsk.symbol_rate / 1000;
+ bandwidth = (878 * ksyms + 6500000) / 1000000 + 1;
+ if (bandwidth < 5)
+ bandwidth = 5;
+ else if (bandwidth > 36)
+ bandwidth = 36;
+
buf[0] = 0x00; // subaddress
buf[1] = 0x09; // powerdown RSSI + the magic value 1
if (!priv->has_loopthrough)
@@ -90,7 +101,7 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param
buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
buf[3] = div >> 7;
buf[4] = div << 1;
- buf[5] = 0x77; // baseband cut-off 19 MHz
+ buf[5] = ((bandwidth - 5) << 3) | 7; /* baseband cut-off */
buf[6] = 0xfe; // baseband gain 9 db + no RF attenuation
buf[7] = 0x83; // charge pumps at high, tests off
buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
@@ -100,7 +111,7 @@ static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_param
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
- dprintk("%s: i2c error\n", __FUNCTION__);
+ dprintk("%s: i2c error\n", __func__);
}
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
@@ -139,7 +150,7 @@ struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2
};
int ret;
- dprintk("%s:\n", __FUNCTION__);
+ dprintk("%s:\n", __func__);
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
diff --git a/linux/drivers/media/dvb/frontends/tda826x.h b/linux/drivers/media/dvb/frontends/tda826x.h
index ad9981195..89e97926a 100644
--- a/linux/drivers/media/dvb/frontends/tda826x.h
+++ b/linux/drivers/media/dvb/frontends/tda826x.h
@@ -45,7 +45,7 @@ static inline struct dvb_frontend* tda826x_attach(struct dvb_frontend *fe,
struct i2c_adapter *i2c,
int has_loopthrough)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_TDA826X
diff --git a/linux/drivers/media/dvb/frontends/tda827x.c b/linux/drivers/media/dvb/frontends/tda827x.c
deleted file mode 100644
index 2d39f9be5..000000000
--- a/linux/drivers/media/dvb/frontends/tda827x.c
+++ /dev/null
@@ -1,853 +0,0 @@
-/*
- *
- * (c) 2005 Hartmut Hackmann
- * (c) 2007 Michael Krufky
- *
- * 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 <asm/types.h>
-#include "compat.h"
-#include <linux/dvb/frontend.h>
-#include <linux/videodev2.h>
-
-#include "tda827x.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
-
-#define dprintk(args...) \
- do { \
- if (debug) printk(KERN_DEBUG "tda827x: " args); \
- } while (0)
-
-struct tda827x_priv {
- int i2c_addr;
- struct i2c_adapter *i2c_adap;
- struct tda827x_config *cfg;
-
- unsigned int sgIF;
- unsigned char lpsel;
-
- u32 frequency;
- u32 bandwidth;
-};
-
-static void tda827x_set_std(struct dvb_frontend *fe,
- struct analog_parameters *params)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- char *mode;
-
- priv->lpsel = 0;
- if (params->std & V4L2_STD_MN) {
- priv->sgIF = 92;
- priv->lpsel = 1;
- mode = "MN";
- } else if (params->std & V4L2_STD_B) {
- priv->sgIF = 108;
- mode = "B";
- } else if (params->std & V4L2_STD_GH) {
- priv->sgIF = 124;
- mode = "GH";
- } else if (params->std & V4L2_STD_PAL_I) {
- priv->sgIF = 124;
- mode = "I";
- } else if (params->std & V4L2_STD_DK) {
- priv->sgIF = 124;
- mode = "DK";
- } else if (params->std & V4L2_STD_SECAM_L) {
- priv->sgIF = 124;
- mode = "L";
- } else if (params->std & V4L2_STD_SECAM_LC) {
- priv->sgIF = 20;
- mode = "LC";
- } else {
- priv->sgIF = 124;
- mode = "xx";
- }
-
- if (params->mode == V4L2_TUNER_RADIO)
- priv->sgIF = 88; /* if frequency is 5.5 MHz */
-
- dprintk("setting tda827x to system %s\n", mode);
-}
-
-
-/* ------------------------------------------------------------------ */
-
-struct tda827x_data {
- u32 lomax;
- u8 spd;
- u8 bs;
- u8 bp;
- u8 cp;
- u8 gc3;
- u8 div1p5;
-};
-
-static const struct tda827x_data tda827x_table[] = {
- { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
- { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
- { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
- { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
- { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
- { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
- { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
- { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
- { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
- { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
- { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
- { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
- { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
- { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
- { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
- { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
- { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
- { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
-};
-
-static int tda827xo_set_params(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *params)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- u8 buf[14];
-
- struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
- .buf = buf, .len = sizeof(buf) };
- int i, tuner_freq, if_freq;
- u32 N;
-
- dprintk("%s:\n", __func__);
- switch (params->u.ofdm.bandwidth) {
- case BANDWIDTH_6_MHZ:
- if_freq = 4000000;
- break;
- case BANDWIDTH_7_MHZ:
- if_freq = 4500000;
- break;
- default: /* 8 MHz or Auto */
- if_freq = 5000000;
- break;
- }
- tuner_freq = params->frequency + if_freq;
-
- i = 0;
- while (tda827x_table[i].lomax < tuner_freq) {
- if (tda827x_table[i + 1].lomax == 0)
- break;
- i++;
- }
-
- N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2);
- buf[0] = 0;
- buf[1] = (N>>8) | 0x40;
- buf[2] = N & 0xff;
- buf[3] = 0;
- buf[4] = 0x52;
- buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) +
- (tda827x_table[i].bs << 3) +
- tda827x_table[i].bp;
- buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f;
- buf[7] = 0xbf;
- buf[8] = 0x2a;
- buf[9] = 0x05;
- buf[10] = 0xff;
- buf[11] = 0x00;
- buf[12] = 0x00;
- buf[13] = 0x40;
-
- msg.len = 14;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
- printk("%s: could not write to tuner at addr: 0x%02x\n",
- __func__, priv->i2c_addr << 1);
- return -EIO;
- }
- msleep(500);
- /* correct CP value */
- buf[0] = 0x30;
- buf[1] = 0x50 + tda827x_table[i].cp;
- msg.len = 2;
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- priv->frequency = tuner_freq - if_freq; // FIXME
- priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
-
- return 0;
-}
-
-static int tda827xo_sleep(struct dvb_frontend *fe)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- static u8 buf[] = { 0x30, 0xd0 };
- struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
- .buf = buf, .len = sizeof(buf) };
-
- dprintk("%s:\n", __func__);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- if (priv->cfg && priv->cfg->sleep)
- priv->cfg->sleep(fe);
-
- return 0;
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda827xo_set_analog_params(struct dvb_frontend *fe,
- struct analog_parameters *params)
-{
- unsigned char tuner_reg[8];
- unsigned char reg2[2];
- u32 N;
- int i;
- struct tda827x_priv *priv = fe->tuner_priv;
- struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 };
- unsigned int freq = params->frequency;
-
- tda827x_set_std(fe, params);
-
- if (params->mode == V4L2_TUNER_RADIO)
- freq = freq / 1000;
-
- N = freq + priv->sgIF;
-
- i = 0;
- while (tda827x_table[i].lomax < N * 62500) {
- if (tda827x_table[i + 1].lomax == 0)
- break;
- i++;
- }
-
- N = N << tda827x_table[i].spd;
-
- tuner_reg[0] = 0;
- tuner_reg[1] = (unsigned char)(N>>8);
- tuner_reg[2] = (unsigned char) N;
- tuner_reg[3] = 0x40;
- tuner_reg[4] = 0x52 + (priv->lpsel << 5);
- tuner_reg[5] = (tda827x_table[i].spd << 6) +
- (tda827x_table[i].div1p5 << 5) +
- (tda827x_table[i].bs << 3) + tda827x_table[i].bp;
- tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4);
- tuner_reg[7] = 0x8f;
-
- msg.buf = tuner_reg;
- msg.len = 8;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- msg.buf = reg2;
- msg.len = 2;
- reg2[0] = 0x80;
- reg2[1] = 0;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- reg2[0] = 0x60;
- reg2[1] = 0xbf;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- reg2[0] = 0x30;
- reg2[1] = tuner_reg[4] + 0x80;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- msleep(1);
- reg2[0] = 0x30;
- reg2[1] = tuner_reg[4] + 4;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- msleep(1);
- reg2[0] = 0x30;
- reg2[1] = tuner_reg[4];
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- msleep(550);
- reg2[0] = 0x30;
- reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- reg2[0] = 0x60;
- reg2[1] = 0x3f;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- reg2[0] = 0x80;
- reg2[1] = 0x08; /* Vsync en */
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- priv->frequency = freq * 62500;
-
- return 0;
-}
-
-static void tda827xo_agcf(struct dvb_frontend *fe)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- unsigned char data[] = { 0x80, 0x0c };
- struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
- .buf = data, .len = 2};
-
- i2c_transfer(priv->i2c_adap, &msg, 1);
-}
-
-/* ------------------------------------------------------------------ */
-
-struct tda827xa_data {
- u32 lomax;
- u8 svco;
- u8 spd;
- u8 scr;
- u8 sbs;
- u8 gc3;
-};
-
-static const struct tda827xa_data tda827xa_dvbt[] = {
- { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
- { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
- { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
- { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
- { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
- { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
- { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
- { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
- { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
- { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
- { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
- { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
- { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
- { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
- { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
- { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
- { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
- { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
- { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
- { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
- { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
- { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
- { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
- { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
- { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
- { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
- { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
-};
-
-static struct tda827xa_data tda827xa_analog[] = {
- { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
- { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
- { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
- { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
- { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
- { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
- { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
- { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
- { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
- { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
- { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},
- { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},
- { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
- { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
- { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
- { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
- { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
- { .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
- { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
- { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
- { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
- { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
- { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
- { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
- { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
- { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
-};
-
-static int tda827xa_sleep(struct dvb_frontend *fe)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- static u8 buf[] = { 0x30, 0x90 };
- struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
- .buf = buf, .len = sizeof(buf) };
-
- dprintk("%s:\n", __func__);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
-
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 0);
-
- if (priv->cfg && priv->cfg->sleep)
- priv->cfg->sleep(fe);
-
- return 0;
-}
-
-static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
- struct analog_parameters *params)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- unsigned char buf[] = {0x22, 0x01};
- int arg;
- int gp_func;
- struct i2c_msg msg = { .addr = priv->cfg->switch_addr, .flags = 0,
- .buf = buf, .len = sizeof(buf) };
-
- if (NULL == priv->cfg) {
- dprintk("tda827x_config not defined, cannot set LNA gain!\n");
- return;
- }
- if (priv->cfg->config) {
- if (high)
- dprintk("setting LNA to high gain\n");
- else
- dprintk("setting LNA to low gain\n");
- }
- switch (priv->cfg->config) {
- case 0: /* no LNA */
- break;
- case 1: /* switch is GPIO 0 of tda8290 */
- case 2:
- if (params == NULL) {
- gp_func = 0;
- arg = 0;
- } else {
- /* turn Vsync on */
- gp_func = 1;
- if (params->std & V4L2_STD_MN)
- arg = 1;
- else
- arg = 0;
- }
- if (priv->cfg->tuner_callback)
- priv->cfg->tuner_callback(priv->i2c_adap->algo_data,
- gp_func, arg);
- buf[1] = high ? 0 : 1;
- if (priv->cfg->config == 2)
- buf[1] = high ? 1 : 0;
- i2c_transfer(priv->i2c_adap, &msg, 1);
- break;
- case 3: /* switch with GPIO of saa713x */
- if (priv->cfg->tuner_callback)
- priv->cfg->tuner_callback(priv->i2c_adap->algo_data, 0, high);
- break;
- }
-}
-
-static int tda827xa_set_params(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *params)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- u8 buf[11];
-
- struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
- .buf = buf, .len = sizeof(buf) };
-
- int i, tuner_freq, if_freq;
- u32 N;
-
- dprintk("%s:\n", __func__);
-
- tda827xa_lna_gain(fe, 1, NULL);
- msleep(20);
-
- switch (params->u.ofdm.bandwidth) {
- case BANDWIDTH_6_MHZ:
- if_freq = 4000000;
- break;
- case BANDWIDTH_7_MHZ:
- if_freq = 4500000;
- break;
- default: /* 8 MHz or Auto */
- if_freq = 5000000;
- break;
- }
- tuner_freq = params->frequency + if_freq;
-
- i = 0;
- while (tda827xa_dvbt[i].lomax < tuner_freq) {
- if(tda827xa_dvbt[i + 1].lomax == 0)
- break;
- i++;
- }
-
- N = ((tuner_freq + 31250) / 62500) << tda827xa_dvbt[i].spd;
- buf[0] = 0; // subaddress
- buf[1] = N >> 8;
- buf[2] = N & 0xff;
- buf[3] = 0;
- buf[4] = 0x16;
- buf[5] = (tda827xa_dvbt[i].spd << 5) + (tda827xa_dvbt[i].svco << 3) +
- tda827xa_dvbt[i].sbs;
- buf[6] = 0x4b + (tda827xa_dvbt[i].gc3 << 4);
- buf[7] = 0x1c;
- buf[8] = 0x06;
- buf[9] = 0x24;
- buf[10] = 0x00;
- msg.len = 11;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
- printk("%s: could not write to tuner at addr: 0x%02x\n",
- __func__, priv->i2c_addr << 1);
- return -EIO;
- }
- buf[0] = 0x90;
- buf[1] = 0xff;
- buf[2] = 0x60;
- buf[3] = 0x00;
- buf[4] = 0x59; // lpsel, for 6MHz + 2
- msg.len = 5;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- buf[0] = 0xa0;
- buf[1] = 0x40;
- msg.len = 2;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- msleep(11);
- msg.flags = I2C_M_RD;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
- msg.flags = 0;
-
- buf[1] >>= 4;
- dprintk("tda8275a AGC2 gain is: %d\n", buf[1]);
- if ((buf[1]) < 2) {
- tda827xa_lna_gain(fe, 0, NULL);
- buf[0] = 0x60;
- buf[1] = 0x0c;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
- }
-
- buf[0] = 0xc0;
- buf[1] = 0x99; // lpsel, for 6MHz + 2
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- buf[0] = 0x60;
- buf[1] = 0x3c;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- /* correct CP value */
- buf[0] = 0x30;
- buf[1] = 0x10 + tda827xa_dvbt[i].scr;
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- msleep(163);
- buf[0] = 0xc0;
- buf[1] = 0x39; // lpsel, for 6MHz + 2
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- msleep(3);
- /* freeze AGC1 */
- buf[0] = 0x50;
- buf[1] = 0x4f + (tda827xa_dvbt[i].gc3 << 4);
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- priv->frequency = tuner_freq - if_freq; // FIXME
- priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
-
- return 0;
-}
-
-
-static int tda827xa_set_analog_params(struct dvb_frontend *fe,
- struct analog_parameters *params)
-{
- unsigned char tuner_reg[11];
- u32 N;
- int i;
- struct tda827x_priv *priv = fe->tuner_priv;
- struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
- .buf = tuner_reg, .len = sizeof(tuner_reg) };
- unsigned int freq = params->frequency;
-
- tda827x_set_std(fe, params);
-
- tda827xa_lna_gain(fe, 1, params);
- msleep(10);
-
- if (params->mode == V4L2_TUNER_RADIO)
- freq = freq / 1000;
-
- N = freq + priv->sgIF;
-
- i = 0;
- while (tda827xa_analog[i].lomax < N * 62500) {
- if (tda827xa_analog[i + 1].lomax == 0)
- break;
- i++;
- }
-
- N = N << tda827xa_analog[i].spd;
-
- tuner_reg[0] = 0;
- tuner_reg[1] = (unsigned char)(N>>8);
- tuner_reg[2] = (unsigned char) N;
- tuner_reg[3] = 0;
- tuner_reg[4] = 0x16;
- tuner_reg[5] = (tda827xa_analog[i].spd << 5) +
- (tda827xa_analog[i].svco << 3) +
- tda827xa_analog[i].sbs;
- tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
- tuner_reg[7] = 0x1c;
- tuner_reg[8] = 4;
- tuner_reg[9] = 0x20;
- tuner_reg[10] = 0x00;
- msg.len = 11;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- tuner_reg[0] = 0x90;
- tuner_reg[1] = 0xff;
- tuner_reg[2] = 0xe0;
- tuner_reg[3] = 0;
- tuner_reg[4] = 0x99 + (priv->lpsel << 1);
- msg.len = 5;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- tuner_reg[0] = 0xa0;
- tuner_reg[1] = 0xc0;
- msg.len = 2;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- tuner_reg[0] = 0x30;
- tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- msg.flags = I2C_M_RD;
- i2c_transfer(priv->i2c_adap, &msg, 1);
- msg.flags = 0;
- tuner_reg[1] >>= 4;
- dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
- if (tuner_reg[1] < 1)
- tda827xa_lna_gain(fe, 0, params);
-
- msleep(100);
- tuner_reg[0] = 0x60;
- tuner_reg[1] = 0x3c;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- msleep(163);
- tuner_reg[0] = 0x50;
- tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- tuner_reg[0] = 0x80;
- tuner_reg[1] = 0x28;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- tuner_reg[0] = 0xb0;
- tuner_reg[1] = 0x01;
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- tuner_reg[0] = 0xc0;
- tuner_reg[1] = 0x19 + (priv->lpsel << 1);
- i2c_transfer(priv->i2c_adap, &msg, 1);
-
- priv->frequency = freq * 62500;
-
- return 0;
-}
-
-static void tda827xa_agcf(struct dvb_frontend *fe)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- unsigned char data[] = {0x80, 0x2c};
- struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
- .buf = data, .len = 2};
- i2c_transfer(priv->i2c_adap, &msg, 1);
-}
-
-/* ------------------------------------------------------------------ */
-
-static int tda827x_release(struct dvb_frontend *fe)
-{
- kfree(fe->tuner_priv);
- fe->tuner_priv = NULL;
- return 0;
-}
-
-static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- *frequency = priv->frequency;
- return 0;
-}
-
-static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- *bandwidth = priv->bandwidth;
- return 0;
-}
-
-static int tda827x_init(struct dvb_frontend *fe)
-{
- struct tda827x_priv *priv = fe->tuner_priv;
- dprintk("%s:\n", __func__);
- if (priv->cfg && priv->cfg->init)
- priv->cfg->init(fe);
-
- return 0;
-}
-
-static int tda827x_probe_version(struct dvb_frontend *fe);
-
-static int tda827x_initial_init(struct dvb_frontend *fe)
-{
- int ret;
- ret = tda827x_probe_version(fe);
- if (ret)
- return ret;
- return fe->ops.tuner_ops.init(fe);
-}
-
-static int tda827x_initial_sleep(struct dvb_frontend *fe)
-{
- int ret;
- ret = tda827x_probe_version(fe);
- if (ret)
- return ret;
- return fe->ops.tuner_ops.sleep(fe);
-}
-
-static struct dvb_tuner_ops tda827xo_tuner_ops = {
- .info = {
- .name = "Philips TDA827X",
- .frequency_min = 55000000,
- .frequency_max = 860000000,
- .frequency_step = 250000
- },
- .release = tda827x_release,
- .init = tda827x_initial_init,
- .sleep = tda827x_initial_sleep,
- .set_params = tda827xo_set_params,
- .set_analog_params = tda827xo_set_analog_params,
- .get_frequency = tda827x_get_frequency,
- .get_bandwidth = tda827x_get_bandwidth,
-};
-
-static struct dvb_tuner_ops tda827xa_tuner_ops = {
- .info = {
- .name = "Philips TDA827XA",
- .frequency_min = 44000000,
- .frequency_max = 906000000,
- .frequency_step = 62500
- },
- .release = tda827x_release,
- .init = tda827x_init,
- .sleep = tda827xa_sleep,
- .set_params = tda827xa_set_params,
- .set_analog_params = tda827xa_set_analog_params,
- .get_frequency = tda827x_get_frequency,
- .get_bandwidth = tda827x_get_bandwidth,
-};
-
-static int tda827x_probe_version(struct dvb_frontend *fe)
-{ u8 data;
- struct tda827x_priv *priv = fe->tuner_priv;
- struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
- .buf = &data, .len = 1 };
- if (fe->ops.i2c_gate_ctrl)
- fe->ops.i2c_gate_ctrl(fe, 1);
- if (i2c_transfer(priv->i2c_adap, &msg, 1) != 1) {
- printk("%s: could not read from tuner at addr: 0x%02x\n",
- __func__, msg.addr << 1);
- return -EIO;
- }
- if ((data & 0x3c) == 0) {
- dprintk("tda827x tuner found\n");
- fe->ops.tuner_ops.init = tda827x_init;
- fe->ops.tuner_ops.sleep = tda827xo_sleep;
- if (priv->cfg)
- priv->cfg->agcf = tda827xo_agcf;
- } else {
- dprintk("tda827xa tuner found\n");
- memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
- if (priv->cfg)
- priv->cfg->agcf = tda827xa_agcf;
- }
- return 0;
-}
-
-struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
- struct i2c_adapter *i2c,
- struct tda827x_config *cfg)
-{
- struct tda827x_priv *priv = NULL;
-
- dprintk("%s:\n", __func__);
- priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
- if (priv == NULL)
- return NULL;
-
- priv->i2c_addr = addr;
- priv->i2c_adap = i2c;
- priv->cfg = cfg;
- memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
- fe->tuner_priv = priv;
-
- dprintk("type set to %s\n", fe->ops.tuner_ops.info.name);
-
- return fe;
-}
-EXPORT_SYMBOL_GPL(tda827x_attach);
-
-MODULE_DESCRIPTION("DVB TDA827x driver");
-MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
-MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
-MODULE_LICENSE("GPL");
-
-/*
- * Overrides for Emacs so that we follow Linus's tabbing style.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-basic-offset: 8
- * End:
- */
diff --git a/linux/drivers/media/dvb/frontends/tda827x.h b/linux/drivers/media/dvb/frontends/tda827x.h
deleted file mode 100644
index cd3032f98..000000000
--- a/linux/drivers/media/dvb/frontends/tda827x.h
+++ /dev/null
@@ -1,69 +0,0 @@
- /*
- DVB Driver for Philips tda827x / tda827xa Silicon tuners
-
- (c) 2005 Hartmut Hackmann
- (c) 2007 Michael Krufky
-
- 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 __DVB_TDA827X_H__
-#define __DVB_TDA827X_H__
-
-#include <linux/i2c.h>
-#include "dvb_frontend.h"
-
-struct tda827x_config
-{
- /* saa7134 - provided callbacks */
- int (*init) (struct dvb_frontend *fe);
- int (*sleep) (struct dvb_frontend *fe);
-
- /* interface to tda829x driver */
- unsigned int config;
- int switch_addr;
- int (*tuner_callback) (void *dev, int command, int arg);
-
- void (*agcf)(struct dvb_frontend *fe);
-};
-
-
-/**
- * Attach a tda827x tuner to the supplied frontend structure.
- *
- * @param fe Frontend to attach to.
- * @param addr i2c address of the tuner.
- * @param i2c i2c adapter to use.
- * @param cfg optional callback function pointers.
- * @return FE pointer on success, NULL on failure.
- */
-#if defined(CONFIG_DVB_TDA827X) || (defined(CONFIG_DVB_TDA827X_MODULE) && defined(MODULE))
-extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr,
- struct i2c_adapter *i2c,
- struct tda827x_config *cfg);
-#else
-static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe,
- int addr,
- struct i2c_adapter *i2c,
- struct tda827x_config *cfg)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
- return NULL;
-}
-#endif // CONFIG_DVB_TDA827X
-
-#endif // __DVB_TDA827X_H__
diff --git a/linux/drivers/media/dvb/frontends/tua6100.c b/linux/drivers/media/dvb/frontends/tua6100.c
index 34e7c93f3..dfa7fa150 100644
--- a/linux/drivers/media/dvb/frontends/tua6100.c
+++ b/linux/drivers/media/dvb/frontends/tua6100.c
@@ -59,7 +59,7 @@ static int tua6100_sleep(struct dvb_frontend *fe)
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 1);
if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
- printk("%s: i2c error\n", __FUNCTION__);
+ printk("%s: i2c error\n", __func__);
}
if (fe->ops.i2c_gate_ctrl)
fe->ops.i2c_gate_ctrl(fe, 0);
diff --git a/linux/drivers/media/dvb/frontends/tua6100.h b/linux/drivers/media/dvb/frontends/tua6100.h
index 03a665e7d..f83dbd5e4 100644
--- a/linux/drivers/media/dvb/frontends/tua6100.h
+++ b/linux/drivers/media/dvb/frontends/tua6100.h
@@ -39,7 +39,7 @@ extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, st
#else
static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_TUA6100
diff --git a/linux/drivers/media/dvb/frontends/ves1820.c b/linux/drivers/media/dvb/frontends/ves1820.c
index 8791701c8..a184597f1 100644
--- a/linux/drivers/media/dvb/frontends/ves1820.c
+++ b/linux/drivers/media/dvb/frontends/ves1820.c
@@ -66,7 +66,7 @@ static int ves1820_writereg(struct ves1820_state *state, u8 reg, u8 data)
if (ret != 1)
printk("ves1820: %s(): writereg error (reg == 0x%02x, "
- "val == 0x%02x, ret == %i)\n", __FUNCTION__, reg, data, ret);
+ "val == 0x%02x, ret == %i)\n", __func__, reg, data, ret);
return (ret != 1) ? -EREMOTEIO : 0;
}
@@ -85,7 +85,7 @@ static u8 ves1820_readreg(struct ves1820_state *state, u8 reg)
if (ret != 2)
printk("ves1820: %s(): readreg error (reg == 0x%02x, "
- "ret == %i)\n", __FUNCTION__, reg, ret);
+ "ret == %i)\n", __func__, reg, ret);
return b1[0];
}
diff --git a/linux/drivers/media/dvb/frontends/ves1820.h b/linux/drivers/media/dvb/frontends/ves1820.h
index e4a2a3240..e902ed634 100644
--- a/linux/drivers/media/dvb/frontends/ves1820.h
+++ b/linux/drivers/media/dvb/frontends/ves1820.h
@@ -48,7 +48,7 @@ extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
static inline struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
struct i2c_adapter* i2c, u8 pwm)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_VES1820
diff --git a/linux/drivers/media/dvb/frontends/ves1x93.c b/linux/drivers/media/dvb/frontends/ves1x93.c
index c041c81f9..bd558960b 100644
--- a/linux/drivers/media/dvb/frontends/ves1x93.c
+++ b/linux/drivers/media/dvb/frontends/ves1x93.c
@@ -98,7 +98,7 @@ static int ves1x93_writereg (struct ves1x93_state* state, u8 reg, u8 data)
int err;
if ((err = i2c_transfer (state->i2c, &msg, 1)) != 1) {
- dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __FUNCTION__, err, reg, data);
+ dprintk ("%s: writereg error (err == %i, reg == 0x%02x, data == 0x%02x)\n", __func__, err, reg, data);
return -EREMOTEIO;
}
@@ -179,7 +179,7 @@ static int ves1x93_set_symbolrate (struct ves1x93_state* state, u32 srate)
u32 tmp;
u32 FIN;
- dprintk("%s: srate == %d\n", __FUNCTION__, (unsigned int) srate);
+ dprintk("%s: srate == %d\n", __func__, (unsigned int) srate);
if (srate > state->config->xin/2)
srate = state->config->xin/2;
@@ -266,7 +266,7 @@ static int ves1x93_init (struct dvb_frontend* fe)
int i;
int val;
- dprintk("%s: init chip\n", __FUNCTION__);
+ dprintk("%s: init chip\n", __func__);
for (i = 0; i < state->tab_size; i++) {
if (state->init_1x93_wtab[i]) {
diff --git a/linux/drivers/media/dvb/frontends/ves1x93.h b/linux/drivers/media/dvb/frontends/ves1x93.h
index d507f8966..8a5a49e80 100644
--- a/linux/drivers/media/dvb/frontends/ves1x93.h
+++ b/linux/drivers/media/dvb/frontends/ves1x93.h
@@ -47,7 +47,7 @@ extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
static inline struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
struct i2c_adapter* i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif // CONFIG_DVB_VES1X93
diff --git a/linux/drivers/media/dvb/frontends/xc5000.c b/linux/drivers/media/dvb/frontends/xc5000.c
deleted file mode 100644
index e50924d97..000000000
--- a/linux/drivers/media/dvb/frontends/xc5000.c
+++ /dev/null
@@ -1,983 +0,0 @@
-/*
- * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
- *
- * Copyright (c) 2007 Xceive Corporation
- * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
- *
- * 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/moduleparam.h>
-#include <linux/videodev2.h>
-#include <linux/delay.h>
-#include <linux/dvb/frontend.h>
-#include <linux/i2c.h>
-
-#include "dvb_frontend.h"
-
-#include "xc5000.h"
-#include "xc5000_priv.h"
-
-static int debug;
-module_param(debug, int, 0644);
-MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
-
-#define dprintk(level,fmt, arg...) if (debug >= level) \
- printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
-
-#define XC5000_DEFAULT_FIRMWARE "dvb-fe-xc5000-1.1.fw"
-#define XC5000_DEFAULT_FIRMWARE_SIZE 12332
-
-/* Misc Defines */
-#define MAX_TV_STANDARD 23
-#define XC_MAX_I2C_WRITE_LENGTH 64
-
-/* Signal Types */
-#define XC_RF_MODE_AIR 0
-#define XC_RF_MODE_CABLE 1
-
-/* Result codes */
-#define XC_RESULT_SUCCESS 0
-#define XC_RESULT_RESET_FAILURE 1
-#define XC_RESULT_I2C_WRITE_FAILURE 2
-#define XC_RESULT_I2C_READ_FAILURE 3
-#define XC_RESULT_OUT_OF_RANGE 5
-
-/* Product id */
-#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
-#define XC_PRODUCT_ID_FW_LOADED 0x1388
-
-/* Registers */
-#define XREG_INIT 0x00
-#define XREG_VIDEO_MODE 0x01
-#define XREG_AUDIO_MODE 0x02
-#define XREG_RF_FREQ 0x03
-#define XREG_D_CODE 0x04
-#define XREG_IF_OUT 0x05
-#define XREG_SEEK_MODE 0x07
-#define XREG_POWER_DOWN 0x0A
-#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
-#define XREG_SMOOTHEDCVBS 0x0E
-#define XREG_XTALFREQ 0x0F
-#define XREG_FINERFFREQ 0x10
-#define XREG_DDIMODE 0x11
-
-#define XREG_ADC_ENV 0x00
-#define XREG_QUALITY 0x01
-#define XREG_FRAME_LINES 0x02
-#define XREG_HSYNC_FREQ 0x03
-#define XREG_LOCK 0x04
-#define XREG_FREQ_ERROR 0x05
-#define XREG_SNR 0x06
-#define XREG_VERSION 0x07
-#define XREG_PRODUCT_ID 0x08
-#define XREG_BUSY 0x09
-
-/*
- Basic firmware description. This will remain with
- the driver for documentation purposes.
-
- This represents an I2C firmware file encoded as a
- string of unsigned char. Format is as follows:
-
- char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
- char[1 ]=len0_LSB -> length of first write transaction
- char[2 ]=data0 -> first byte to be sent
- char[3 ]=data1
- char[4 ]=data2
- char[ ]=...
- char[M ]=dataN -> last byte to be sent
- char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
- char[M+2]=len1_LSB -> length of second write transaction
- char[M+3]=data0
- char[M+4]=data1
- ...
- etc.
-
- The [len] value should be interpreted as follows:
-
- len= len_MSB _ len_LSB
- len=1111_1111_1111_1111 : End of I2C_SEQUENCE
- len=0000_0000_0000_0000 : Reset command: Do hardware reset
- len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
- len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
-
- For the RESET and WAIT commands, the two following bytes will contain
- immediately the length of the following transaction.
-
-*/
-typedef struct {
- char *Name;
- u16 AudioMode;
- u16 VideoMode;
-} XC_TV_STANDARD;
-
-/* Tuner standards */
-#define MN_NTSC_PAL_BTSC 0
-#define MN_NTSC_PAL_A2 1
-#define MN_NTSC_PAL_EIAJ 2
-#define MN_NTSC_PAL_Mono 3
-#define BG_PAL_A2 4
-#define BG_PAL_NICAM 5
-#define BG_PAL_MONO 6
-#define I_PAL_NICAM 7
-#define I_PAL_NICAM_MONO 8
-#define DK_PAL_A2 9
-#define DK_PAL_NICAM 10
-#define DK_PAL_MONO 11
-#define DK_SECAM_A2DK1 12
-#define DK_SECAM_A2LDK3 13
-#define DK_SECAM_A2MONO 14
-#define L_SECAM_NICAM 15
-#define LC_SECAM_NICAM 16
-#define DTV6 17
-#define DTV8 18
-#define DTV7_8 19
-#define DTV7 20
-#define FM_Radio_INPUT2 21
-#define FM_Radio_INPUT1 22
-
-static XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
- {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
- {"M/N-NTSC/PAL-A2", 0x0600, 0x8020},
- {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
- {"M/N-NTSC/PAL-Mono", 0x0478, 0x8020},
- {"B/G-PAL-A2", 0x0A00, 0x8049},
- {"B/G-PAL-NICAM", 0x0C04, 0x8049},
- {"B/G-PAL-MONO", 0x0878, 0x8059},
- {"I-PAL-NICAM", 0x1080, 0x8009},
- {"I-PAL-NICAM-MONO", 0x0E78, 0x8009},
- {"D/K-PAL-A2", 0x1600, 0x8009},
- {"D/K-PAL-NICAM", 0x0E80, 0x8009},
- {"D/K-PAL-MONO", 0x1478, 0x8009},
- {"D/K-SECAM-A2 DK1", 0x1200, 0x8009},
- {"D/K-SECAM-A2 L/DK3",0x0E00, 0x8009},
- {"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
- {"L-SECAM-NICAM", 0x8E82, 0x0009},
- {"L'-SECAM-NICAM", 0x8E82, 0x4009},
- {"DTV6", 0x00C0, 0x8002},
- {"DTV8", 0x00C0, 0x800B},
- {"DTV7/8", 0x00C0, 0x801B},
- {"DTV7", 0x00C0, 0x8007},
- {"FM Radio-INPUT2", 0x9802, 0x9002},
- {"FM Radio-INPUT1", 0x0208, 0x9002}
-};
-
-static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len);
-static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len);
-static void xc5000_TunerReset(struct dvb_frontend *fe);
-
-static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
-{
- return xc5000_writeregs(priv, buf, len)
- ? XC_RESULT_I2C_WRITE_FAILURE : XC_RESULT_SUCCESS;
-}
-
-static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
-{
- return xc5000_readregs(priv, buf, len)
- ? XC_RESULT_I2C_READ_FAILURE : XC_RESULT_SUCCESS;
-}
-
-static int xc_reset(struct dvb_frontend *fe)
-{
- xc5000_TunerReset(fe);
- return XC_RESULT_SUCCESS;
-}
-
-static void xc_wait(int wait_ms)
-{
- msleep(wait_ms);
-}
-
-static void xc5000_TunerReset(struct dvb_frontend *fe)
-{
- struct xc5000_priv *priv = fe->tuner_priv;
- int ret;
-
- dprintk(1, "%s()\n", __FUNCTION__);
-
- if (priv->cfg->tuner_callback) {
- ret = priv->cfg->tuner_callback(priv->cfg->priv,
- XC5000_TUNER_RESET, 0);
- if (ret)
- printk(KERN_ERR "xc5000: reset failed\n");
- } else
- printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
-}
-
-static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
-{
- u8 buf[4];
- int WatchDogTimer = 5;
- int result;
-
- buf[0] = (regAddr >> 8) & 0xFF;
- buf[1] = regAddr & 0xFF;
- buf[2] = (i2cData >> 8) & 0xFF;
- buf[3] = i2cData & 0xFF;
- result = xc_send_i2c_data(priv, buf, 4);
- if (result == XC_RESULT_SUCCESS) {
- /* wait for busy flag to clear */
- while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) {
- buf[0] = 0;
- buf[1] = XREG_BUSY;
-
- result = xc_send_i2c_data(priv, buf, 2);
- if (result == XC_RESULT_SUCCESS) {
- result = xc_read_i2c_data(priv, buf, 2);
- if (result == XC_RESULT_SUCCESS) {
- if ((buf[0] == 0) && (buf[1] == 0)) {
- /* busy flag cleared */
- break;
- } else {
- xc_wait(100); /* wait 5 ms */
- WatchDogTimer--;
- }
- }
- }
- }
- }
- if (WatchDogTimer < 0)
- result = XC_RESULT_I2C_WRITE_FAILURE;
-
- return result;
-}
-
-static int xc_read_reg(struct xc5000_priv *priv, u16 regAddr, u16 *i2cData)
-{
- u8 buf[2];
- int result;
-
- buf[0] = (regAddr >> 8) & 0xFF;
- buf[1] = regAddr & 0xFF;
- result = xc_send_i2c_data(priv, buf, 2);
- if (result != XC_RESULT_SUCCESS)
- return result;
-
- result = xc_read_i2c_data(priv, buf, 2);
- if (result != XC_RESULT_SUCCESS)
- return result;
-
- *i2cData = buf[0] * 256 + buf[1];
- return result;
-}
-
-static int xc_load_i2c_sequence(struct dvb_frontend *fe, u8 i2c_sequence[])
-{
- struct xc5000_priv *priv = fe->tuner_priv;
-
- int i, nbytes_to_send, result;
- unsigned int len, pos, index;
- u8 buf[XC_MAX_I2C_WRITE_LENGTH];
-
- index=0;
- while ((i2c_sequence[index]!=0xFF) || (i2c_sequence[index+1]!=0xFF)) {
- len = i2c_sequence[index]* 256 + i2c_sequence[index+1];
- if (len == 0x0000) {
- /* RESET command */
- result = xc_reset(fe);
- index += 2;
- if (result != XC_RESULT_SUCCESS)
- return result;
- } else if (len & 0x8000) {
- /* WAIT command */
- xc_wait(len & 0x7FFF);
- index += 2;
- } else {
- /* Send i2c data whilst ensuring individual transactions
- * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
- */
- index += 2;
- buf[0] = i2c_sequence[index];
- buf[1] = i2c_sequence[index + 1];
- pos = 2;
- while (pos < len) {
- if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2) {
- nbytes_to_send = XC_MAX_I2C_WRITE_LENGTH;
- } else {
- nbytes_to_send = (len - pos + 2);
- }
- for (i=2; i<nbytes_to_send; i++) {
- buf[i] = i2c_sequence[index + pos + i - 2];
- }
- result = xc_send_i2c_data(priv, buf, nbytes_to_send);
-
- if (result != XC_RESULT_SUCCESS)
- return result;
-
- pos += nbytes_to_send - 2;
- }
- index += len;
- }
- }
- return XC_RESULT_SUCCESS;
-}
-
-static int xc_initialize(struct xc5000_priv *priv)
-{
- dprintk(1, "%s()\n", __FUNCTION__);
- return xc_write_reg(priv, XREG_INIT, 0);
-}
-
-static int xc_SetTVStandard(struct xc5000_priv *priv,
- u16 VideoMode, u16 AudioMode)
-{
- int ret;
- dprintk(1, "%s(0x%04x,0x%04x)\n", __FUNCTION__, VideoMode, AudioMode);
- dprintk(1, "%s() Standard = %s\n",
- __FUNCTION__,
- XC5000_Standard[priv->video_standard].Name);
-
- ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
- if (ret == XC_RESULT_SUCCESS)
- ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
-
- return ret;
-}
-
-static int xc_shutdown(struct xc5000_priv *priv)
-{
- return 0;
- /* Fixme: cannot bring tuner back alive once shutdown
- * without reloading the driver modules.
- * return xc_write_reg(priv, XREG_POWER_DOWN, 0);
- */
-}
-
-static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
-{
- dprintk(1, "%s(%d) Source = %s\n", __FUNCTION__, rf_mode,
- rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
-
- if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE))
- {
- rf_mode = XC_RF_MODE_CABLE;
- printk(KERN_ERR
- "%s(), Invalid mode, defaulting to CABLE",
- __FUNCTION__);
- }
- return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
-}
-
-static const struct dvb_tuner_ops xc5000_tuner_ops;
-
-static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
-{
- u16 freq_code;
-
- dprintk(1, "%s(%u)\n", __FUNCTION__, freq_hz);
-
- if ((freq_hz > xc5000_tuner_ops.info.frequency_max) ||
- (freq_hz < xc5000_tuner_ops.info.frequency_min))
- return XC_RESULT_OUT_OF_RANGE;
-
- freq_code = (u16)(freq_hz / 15625);
-
- return xc_write_reg(priv, XREG_RF_FREQ, freq_code);
-}
-
-#if 0
-/* We'll probably need these for analog support */
-static int xc_FineTune_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
-{
- u16 freq_code = (u16)(freq_hz / 15625);
-
- if ((freq_hz > xc5000_tuner_ops.info.frequency_max) ||
- (freq_hz < xc5000_tuner_ops.info.frequency_min))
- return XC_RESULT_OUT_OF_RANGE;
-
- return xc_write_reg(priv, XREG_FINERFFREQ, freq_code);
-}
-
-static int xc_set_Xtal_frequency(struct xc5000_priv *priv, u32 xtalFreqInKHz)
-{
- u16 xtalRatio = (32000 * 0x8000)/xtalFreqInKHz;
- return xc_write_reg(priv, XREG_XTALFREQ, xtalRatio);
-}
-#endif
-
-static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz)
-{
- u32 freq_code = (freq_khz * 1024)/1000;
- dprintk(1, "%s(freq_khz = %d) freq_code = 0x%x\n",
- __FUNCTION__, freq_khz, freq_code);
-
- return xc_write_reg(priv, XREG_IF_OUT, freq_code);
-}
-
-
-static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope)
-{
- return xc_read_reg(priv, XREG_ADC_ENV, adc_envelope);
-}
-
-static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
-{
- int result;
- u16 regData;
- u32 tmp;
-
- result = xc_read_reg(priv, XREG_FREQ_ERROR, &regData);
- if (result)
- return result;
-
- tmp = (u32)regData;
- (*freq_error_hz) = (tmp * 15625) / 1000;
- return result;
-}
-
-static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status)
-{
- return xc_read_reg(priv, XREG_LOCK, lock_status);
-}
-
-static int xc_get_version(struct xc5000_priv *priv,
- u8 *hw_majorversion, u8 *hw_minorversion,
- u8 *fw_majorversion, u8 *fw_minorversion)
-{
- u16 data;
- int result;
-
- result = xc_read_reg(priv, XREG_VERSION, &data);
- if (result)
- return result;
-
- (*hw_majorversion) = (data >> 12) & 0x0F;
- (*hw_minorversion) = (data >> 8) & 0x0F;
- (*fw_majorversion) = (data >> 4) & 0x0F;
- (*fw_minorversion) = data & 0x0F;
-
- return 0;
-}
-
-static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
-{
- u16 regData;
- int result;
-
- result = xc_read_reg(priv, XREG_HSYNC_FREQ, &regData);
- if (result)
- return result;
-
- (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
- return result;
-}
-
-static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines)
-{
- return xc_read_reg(priv, XREG_FRAME_LINES, frame_lines);
-}
-
-static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
-{
- return xc_read_reg(priv, XREG_QUALITY, quality);
-}
-
-static u16 WaitForLock(struct xc5000_priv *priv)
-{
- u16 lockState = 0;
- int watchDogCount = 40;
-
- while ((lockState == 0) && (watchDogCount > 0)) {
- xc_get_lock_status(priv, &lockState);
- if (lockState != 1) {
- xc_wait(5);
- watchDogCount--;
- }
- }
- return lockState;
-}
-
-static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz)
-{
- int found = 0;
-
- dprintk(1, "%s(%u)\n", __FUNCTION__, freq_hz);
-
- if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
- return 0;
-
- if (WaitForLock(priv) == 1)
- found = 1;
-
- return found;
-}
-
-static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
-{
- u8 buf[2] = { reg >> 8, reg & 0xff };
- u8 bval[2] = { 0, 0 };
- struct i2c_msg msg[2] = {
- { .addr = priv->cfg->i2c_address,
- .flags = 0, .buf = &buf[0], .len = 2 },
- { .addr = priv->cfg->i2c_address,
- .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
- };
-
- if (i2c_transfer(priv->i2c, msg, 2) != 2) {
- printk(KERN_WARNING "xc5000: I2C read failed\n");
- return -EREMOTEIO;
- }
-
- *val = (bval[0] << 8) | bval[1];
- return 0;
-}
-
-static int xc5000_writeregs(struct xc5000_priv *priv, u8 *buf, u8 len)
-{
- struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
- .flags = 0, .buf = buf, .len = len };
-
- if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
- printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n",
- (int)len);
- return -EREMOTEIO;
- }
- return 0;
-}
-
-static int xc5000_readregs(struct xc5000_priv *priv, u8 *buf, u8 len)
-{
- struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
- .flags = I2C_M_RD, .buf = buf, .len = len };
-
- if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
- printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n",(int)len);
- return -EREMOTEIO;
- }
- return 0;
-}
-
-static int xc5000_fwupload(struct dvb_frontend* fe)
-{
- struct xc5000_priv *priv = fe->tuner_priv;
- const struct firmware *fw;
- int ret;
-
- /* request the firmware, this will block and timeout */
- printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
- XC5000_DEFAULT_FIRMWARE);
-
- ret = request_firmware(&fw, XC5000_DEFAULT_FIRMWARE, &priv->i2c->dev);
- if (ret) {
- printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
- ret = XC_RESULT_RESET_FAILURE;
- goto out;
- } else {
- printk(KERN_INFO "xc5000: firmware read %Zu bytes.\n",
- fw->size);
- ret = XC_RESULT_SUCCESS;
- }
-
- if (fw->size != XC5000_DEFAULT_FIRMWARE_SIZE) {
- printk(KERN_ERR "xc5000: firmware incorrect size\n");
- ret = XC_RESULT_RESET_FAILURE;
- } else {
- printk(KERN_INFO "xc5000: firmware upload\n");
- ret = xc_load_i2c_sequence(fe, fw->data );
- }
-
-out:
- release_firmware(fw);
- return ret;
-}
-
-static void xc_debug_dump(struct xc5000_priv *priv)
-{
- u16 adc_envelope;
- u32 freq_error_hz = 0;
- u16 lock_status;
- u32 hsync_freq_hz = 0;
- u16 frame_lines;
- u16 quality;
- u8 hw_majorversion = 0, hw_minorversion = 0;
- u8 fw_majorversion = 0, fw_minorversion = 0;
-
- /* Wait for stats to stabilize.
- * Frame Lines needs two frame times after initial lock
- * before it is valid.
- */
- xc_wait(100);
-
- xc_get_ADC_Envelope(priv, &adc_envelope);
- dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
-
- xc_get_frequency_error(priv, &freq_error_hz);
- dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
-
- xc_get_lock_status(priv, &lock_status);
- dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
- lock_status);
-
- xc_get_version(priv, &hw_majorversion, &hw_minorversion,
- &fw_majorversion, &fw_minorversion);
- dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
- hw_majorversion, hw_minorversion,
- fw_majorversion, fw_minorversion);
-
- xc_get_hsync_freq(priv, &hsync_freq_hz);
- dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
-
- xc_get_frame_lines(priv, &frame_lines);
- dprintk(1, "*** Frame lines = %d\n", frame_lines);
-
- xc_get_quality(priv, &quality);
- dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
-}
-
-static int xc5000_set_params(struct dvb_frontend *fe,
- struct dvb_frontend_parameters *params)
-{
- struct xc5000_priv *priv = fe->tuner_priv;
- int ret;
-
- dprintk(1, "%s() frequency=%d (Hz)\n", __FUNCTION__, params->frequency);
-
- switch(params->u.vsb.modulation) {
- case VSB_8:
- case VSB_16:
- dprintk(1, "%s() VSB modulation\n", __FUNCTION__);
- priv->rf_mode = XC_RF_MODE_AIR;
- priv->freq_hz = params->frequency - 1750000;
- priv->bandwidth = BANDWIDTH_6_MHZ;
- priv->video_standard = DTV6;
- break;
- case QAM_64:
- case QAM_256:
- case QAM_AUTO:
- dprintk(1, "%s() QAM modulation\n", __FUNCTION__);
- priv->rf_mode = XC_RF_MODE_CABLE;
- priv->freq_hz = params->frequency - 1750000;
- priv->bandwidth = BANDWIDTH_6_MHZ;
- priv->video_standard = DTV6;
- break;
- default:
- return -EINVAL;
- }
-
- dprintk(1, "%s() frequency=%d (compensated)\n",
- __FUNCTION__, priv->freq_hz);
-
- ret = xc_SetSignalSource(priv, priv->rf_mode);
- if (ret != XC_RESULT_SUCCESS) {
- printk(KERN_ERR
- "xc5000: xc_SetSignalSource(%d) failed\n",
- priv->rf_mode);
- return -EREMOTEIO;
- }
-
- ret = xc_SetTVStandard(priv,
- XC5000_Standard[priv->video_standard].VideoMode,
- XC5000_Standard[priv->video_standard].AudioMode);
- if (ret != XC_RESULT_SUCCESS) {
- printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
- return -EREMOTEIO;
- }
-
- ret = xc_set_IF_frequency(priv, priv->cfg->if_khz);
- if (ret != XC_RESULT_SUCCESS) {
- printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
- priv->cfg->if_khz);
- return -EIO;
- }
-
- xc_tune_channel(priv, priv->freq_hz);
-
- if (debug)
- xc_debug_dump(priv);
-
- return 0;
-}
-
-static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe);
-
-static int xc5000_set_analog_params(struct dvb_frontend *fe,
- struct analog_parameters *params)
-{
- struct xc5000_priv *priv = fe->tuner_priv;
- int ret;
-
- if(priv->fwloaded == 0)
- xc_load_fw_and_init_tuner(fe);
-
- dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
- __FUNCTION__, params->frequency);
-
- priv->rf_mode = XC_RF_MODE_CABLE; /* Fix me: it could be air. */
-
- /* params->frequency is in units of 62.5khz */
- priv->freq_hz = params->frequency * 62500;
-
- /* FIX ME: Some video standards may have several possible audio
- standards. We simply default to one of them here.
- */
- if(params->std & V4L2_STD_MN) {
- /* default to BTSC audio standard */
- priv->video_standard = MN_NTSC_PAL_BTSC;
- goto tune_channel;
- }
-
- if(params->std & V4L2_STD_PAL_BG) {
- /* default to NICAM audio standard */
- priv->video_standard = BG_PAL_NICAM;
- goto tune_channel;
- }
-
- if(params->std & V4L2_STD_PAL_I) {
- /* default to NICAM audio standard */
- priv->video_standard = I_PAL_NICAM;
- goto tune_channel;
- }
-
- if(params->std & V4L2_STD_PAL_DK) {
- /* default to NICAM audio standard */
- priv->video_standard = DK_PAL_NICAM;
- goto tune_channel;
- }
-
- if(params->std & V4L2_STD_SECAM_DK) {
- /* default to A2 DK1 audio standard */
- priv->video_standard = DK_SECAM_A2DK1;
- goto tune_channel;
- }
-
- if(params->std & V4L2_STD_SECAM_L) {
- priv->video_standard = L_SECAM_NICAM;
- goto tune_channel;
- }
-
- if(params->std & V4L2_STD_SECAM_LC) {
- priv->video_standard = LC_SECAM_NICAM;
- goto tune_channel;
- }
-
-tune_channel:
- ret = xc_SetSignalSource(priv, priv->rf_mode);
- if (ret != XC_RESULT_SUCCESS) {
- printk(KERN_ERR
- "xc5000: xc_SetSignalSource(%d) failed\n",
- priv->rf_mode);
- return -EREMOTEIO;
- }
-
- ret = xc_SetTVStandard(priv,
- XC5000_Standard[priv->video_standard].VideoMode,
- XC5000_Standard[priv->video_standard].AudioMode);
- if (ret != XC_RESULT_SUCCESS) {
- printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
- return -EREMOTEIO;
- }
-
- xc_tune_channel(priv, priv->freq_hz);
-
- if (debug)
- xc_debug_dump(priv);
-
- return 0;
-}
-
-static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
-{
- struct xc5000_priv *priv = fe->tuner_priv;
- dprintk(1, "%s()\n", __FUNCTION__);
- *freq = priv->freq_hz;
- return 0;
-}
-
-static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
-{
- struct xc5000_priv *priv = fe->tuner_priv;
- dprintk(1, "%s()\n", __FUNCTION__);
-
- *bw = priv->bandwidth;
- return 0;
-}
-
-static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
-{
- struct xc5000_priv *priv = fe->tuner_priv;
- u16 lock_status = 0;
-
- xc_get_lock_status(priv, &lock_status);
-
- dprintk(1, "%s() lock_status = 0x%08x\n", __FUNCTION__, lock_status);
-
- *status = lock_status;
-
- return 0;
-}
-
-static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe)
-{
- struct xc5000_priv *priv = fe->tuner_priv;
- int ret = 0;
-
- if (priv->fwloaded == 0) {
- ret = xc5000_fwupload(fe);
- if (ret != XC_RESULT_SUCCESS)
- return ret;
- priv->fwloaded = 1;
- }
-
- /* Start the tuner self-calibration process */
- ret |= xc_initialize(priv);
-
- /* Wait for calibration to complete.
- * We could continue but XC5000 will clock stretch subsequent
- * I2C transactions until calibration is complete. This way we
- * don't have to rely on clock stretching working.
- */
- xc_wait( 100 );
-
- /* Default to "CABLE" mode */
- ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
-
- return ret;
-}
-
-static int xc5000_sleep(struct dvb_frontend *fe)
-{
- struct xc5000_priv *priv = fe->tuner_priv;
- int ret;
-
- dprintk(1, "%s()\n", __FUNCTION__);
-
- /* On Pinnacle PCTV HD 800i, the tuner cannot be reinitialized
- * once shutdown without reloading the driver. Maybe I am not
- * doing something right.
- *
- */
-
- ret = xc_shutdown(priv);
- if(ret != XC_RESULT_SUCCESS) {
- printk(KERN_ERR
- "xc5000: %s() unable to shutdown tuner\n",
- __FUNCTION__);
- return -EREMOTEIO;
- }
- else {
- /* priv->fwloaded = 0; */
- return XC_RESULT_SUCCESS;
- }
-}
-
-static int xc5000_init(struct dvb_frontend *fe)
-{
- struct xc5000_priv *priv = fe->tuner_priv;
- dprintk(1, "%s()\n", __FUNCTION__);
-
- if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
- printk(KERN_ERR "xc5000: Unable to initialise tuner\n");
- return -EREMOTEIO;
- }
-
- if (debug)
- xc_debug_dump(priv);
-
- return 0;
-}
-
-static int xc5000_release(struct dvb_frontend *fe)
-{
- dprintk(1, "%s()\n", __FUNCTION__);
- kfree(fe->tuner_priv);
- fe->tuner_priv = NULL;
- return 0;
-}
-
-static const struct dvb_tuner_ops xc5000_tuner_ops = {
- .info = {
- .name = "Xceive XC5000",
- .frequency_min = 1000000,
- .frequency_max = 1023000000,
- .frequency_step = 50000,
- },
-
- .release = xc5000_release,
- .init = xc5000_init,
- .sleep = xc5000_sleep,
-
- .set_params = xc5000_set_params,
- .set_analog_params = xc5000_set_analog_params,
- .get_frequency = xc5000_get_frequency,
- .get_bandwidth = xc5000_get_bandwidth,
- .get_status = xc5000_get_status
-};
-
-struct dvb_frontend * xc5000_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct xc5000_config *cfg)
-{
- struct xc5000_priv *priv = NULL;
- u16 id = 0;
-
- dprintk(1, "%s()\n", __FUNCTION__);
-
- priv = kzalloc(sizeof(struct xc5000_priv), GFP_KERNEL);
- if (priv == NULL)
- return NULL;
-
- priv->cfg = cfg;
- priv->bandwidth = BANDWIDTH_6_MHZ;
- priv->i2c = i2c;
-
- /* Check if firmware has been loaded. It is possible that another
- instance of the driver has loaded the firmware.
- */
- if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != 0) {
- kfree(priv);
- return NULL;
- }
-
- switch(id) {
- case XC_PRODUCT_ID_FW_LOADED:
- printk(KERN_INFO
- "xc5000: Successfully identified at address 0x%02x\n",
- cfg->i2c_address);
- printk(KERN_INFO
- "xc5000: Firmware has been loaded previously\n");
- priv->fwloaded = 1;
- break;
- case XC_PRODUCT_ID_FW_NOT_LOADED:
- printk(KERN_INFO
- "xc5000: Successfully identified at address 0x%02x\n",
- cfg->i2c_address);
- printk(KERN_INFO
- "xc5000: Firmware has not been loaded previously\n");
- priv->fwloaded = 0;
- break;
- default:
- printk(KERN_ERR
- "xc5000: Device not found at addr 0x%02x (0x%x)\n",
- cfg->i2c_address, id);
- kfree(priv);
- return NULL;
- }
-
- memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
- sizeof(struct dvb_tuner_ops));
-
- fe->tuner_priv = priv;
-
- return fe;
-}
-EXPORT_SYMBOL(xc5000_attach);
-
-MODULE_AUTHOR("Steven Toth");
-MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver");
-MODULE_LICENSE("GPL");
diff --git a/linux/drivers/media/dvb/frontends/xc5000.h b/linux/drivers/media/dvb/frontends/xc5000.h
deleted file mode 100644
index 32a5f1c86..000000000
--- a/linux/drivers/media/dvb/frontends/xc5000.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
- *
- * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
- *
- * 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 __XC5000_H__
-#define __XC5000_H__
-
-#include <linux/firmware.h>
-
-struct dvb_frontend;
-struct i2c_adapter;
-
-struct xc5000_config {
- u8 i2c_address;
- u32 if_khz;
-
- /* For each bridge framework, when it attaches either analog or digital,
- * it has to store a reference back to its _core equivalent structure,
- * so that it can service the hardware by steering gpio's etc.
- * Each bridge implementation is different so cast priv accordingly.
- * The xc5000 driver cares not for this value, other than ensuring
- * it's passed back to a bridge during tuner_callback().
- */
- void *priv;
- int (*tuner_callback) (void *priv, int command, int arg);
-};
-
-/* xc5000 callback command */
-#define XC5000_TUNER_RESET 0
-
-#if defined(CONFIG_DVB_TUNER_XC5000) || \
- (defined(CONFIG_DVB_TUNER_XC5000_MODULE) && defined(MODULE))
-extern struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct xc5000_config *cfg);
-#else
-static inline struct dvb_frontend* xc5000_attach(struct dvb_frontend *fe,
- struct i2c_adapter *i2c,
- struct xc5000_config *cfg)
-{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
- return NULL;
-}
-#endif // CONFIG_DVB_TUNER_XC5000
-
-#endif // __XC5000_H__
diff --git a/linux/drivers/media/dvb/frontends/xc5000_priv.h b/linux/drivers/media/dvb/frontends/xc5000_priv.h
deleted file mode 100644
index 13b2d1934..000000000
--- a/linux/drivers/media/dvb/frontends/xc5000_priv.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*
- * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
- *
- * Copyright (c) 2007 Steven Toth <stoth@hauppauge.com>
- *
- * 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 XC5000_PRIV_H
-#define XC5000_PRIV_H
-
-struct xc5000_priv {
- struct xc5000_config *cfg;
- struct i2c_adapter *i2c;
-
- u32 freq_hz;
- u32 bandwidth;
- u8 video_standard;
- u8 rf_mode;
- u8 fwloaded;
-};
-
-#endif
diff --git a/linux/drivers/media/dvb/frontends/zl10353.c b/linux/drivers/media/dvb/frontends/zl10353.c
index 1ae9f0ef1..11160a3ee 100644
--- a/linux/drivers/media/dvb/frontends/zl10353.c
+++ b/linux/drivers/media/dvb/frontends/zl10353.c
@@ -91,7 +91,7 @@ static int zl10353_read_register(struct zl10353_state *state, u8 reg)
if (ret != 2) {
printk("%s: readreg error (reg=%d, ret==%i)\n",
- __FUNCTION__, reg, ret);
+ __func__, reg, ret);
return ret;
}
@@ -157,7 +157,7 @@ static void zl10353_calc_nominal_rate(struct dvb_frontend *fe,
*nominal_rate = value;
dprintk("%s: bw %d, adc_clock %d => 0x%x\n",
- __FUNCTION__, bw, adc_clock, *nominal_rate);
+ __func__, bw, adc_clock, *nominal_rate);
}
static void zl10353_calc_input_freq(struct dvb_frontend *fe,
@@ -186,7 +186,7 @@ static void zl10353_calc_input_freq(struct dvb_frontend *fe,
*input_freq = -value;
dprintk("%s: if2 %d, ife %d, adc_clock %d => %d / 0x%x\n",
- __FUNCTION__, if2, ife, adc_clock, -(int)value, *input_freq);
+ __func__, if2, ife, adc_clock, -(int)value, *input_freq);
}
static int zl10353_sleep(struct dvb_frontend *fe)
diff --git a/linux/drivers/media/dvb/frontends/zl10353.h b/linux/drivers/media/dvb/frontends/zl10353.h
index fc734c22b..fdbb88ff7 100644
--- a/linux/drivers/media/dvb/frontends/zl10353.h
+++ b/linux/drivers/media/dvb/frontends/zl10353.h
@@ -47,7 +47,7 @@ extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
static inline struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
struct i2c_adapter *i2c)
{
- printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
+ printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
return NULL;
}
#endif /* CONFIG_DVB_ZL10353 */