aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/tuners
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2012-06-14 15:35:59 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-08-13 22:40:28 -0400
commitccae7af2bf07dfef69cc2eb6ebc9e1ff15addfbd (patch)
treef33391cf2efe9038c13b88ca4049317728a7ebf0 /drivers/media/tuners
parent3785bc170f79ef04129731582b468c28e1326d6d (diff)
[media] common: move media/common/tuners to media/tuners
Move the tuners one level up, as the "common" directory will be used by drivers that are shared between more than one driver. Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/tuners')
-rw-r--r--drivers/media/tuners/Kconfig243
-rw-r--r--drivers/media/tuners/Makefile37
-rw-r--r--drivers/media/tuners/fc0011.c524
-rw-r--r--drivers/media/tuners/fc0011.h41
-rw-r--r--drivers/media/tuners/fc0012-priv.h43
-rw-r--r--drivers/media/tuners/fc0012.c467
-rw-r--r--drivers/media/tuners/fc0012.h44
-rw-r--r--drivers/media/tuners/fc0013-priv.h44
-rw-r--r--drivers/media/tuners/fc0013.c634
-rw-r--r--drivers/media/tuners/fc0013.h57
-rw-r--r--drivers/media/tuners/fc001x-common.h39
-rw-r--r--drivers/media/tuners/max2165.c433
-rw-r--r--drivers/media/tuners/max2165.h48
-rw-r--r--drivers/media/tuners/max2165_priv.h60
-rw-r--r--drivers/media/tuners/mc44s803.c372
-rw-r--r--drivers/media/tuners/mc44s803.h46
-rw-r--r--drivers/media/tuners/mc44s803_priv.h208
-rw-r--r--drivers/media/tuners/mt2060.c403
-rw-r--r--drivers/media/tuners/mt2060.h43
-rw-r--r--drivers/media/tuners/mt2060_priv.h104
-rw-r--r--drivers/media/tuners/mt2063.c2307
-rw-r--r--drivers/media/tuners/mt2063.h32
-rw-r--r--drivers/media/tuners/mt20xx.c670
-rw-r--r--drivers/media/tuners/mt20xx.h37
-rw-r--r--drivers/media/tuners/mt2131.c301
-rw-r--r--drivers/media/tuners/mt2131.h54
-rw-r--r--drivers/media/tuners/mt2131_priv.h48
-rw-r--r--drivers/media/tuners/mt2266.c353
-rw-r--r--drivers/media/tuners/mt2266.h37
-rw-r--r--drivers/media/tuners/mxl5005s.c4109
-rw-r--r--drivers/media/tuners/mxl5005s.h135
-rw-r--r--drivers/media/tuners/mxl5007t.c928
-rw-r--r--drivers/media/tuners/mxl5007t.h104
-rw-r--r--drivers/media/tuners/qt1010.c480
-rw-r--r--drivers/media/tuners/qt1010.h53
-rw-r--r--drivers/media/tuners/qt1010_priv.h104
-rw-r--r--drivers/media/tuners/tda18212.c319
-rw-r--r--drivers/media/tuners/tda18212.h52
-rw-r--r--drivers/media/tuners/tda18218.c342
-rw-r--r--drivers/media/tuners/tda18218.h45
-rw-r--r--drivers/media/tuners/tda18218_priv.h108
-rw-r--r--drivers/media/tuners/tda18271-common.c703
-rw-r--r--drivers/media/tuners/tda18271-fe.c1345
-rw-r--r--drivers/media/tuners/tda18271-maps.c1317
-rw-r--r--drivers/media/tuners/tda18271-priv.h236
-rw-r--r--drivers/media/tuners/tda18271.h134
-rw-r--r--drivers/media/tuners/tda827x.c917
-rw-r--r--drivers/media/tuners/tda827x.h68
-rw-r--r--drivers/media/tuners/tda8290.c874
-rw-r--r--drivers/media/tuners/tda8290.h56
-rw-r--r--drivers/media/tuners/tda9887.c717
-rw-r--r--drivers/media/tuners/tda9887.h38
-rw-r--r--drivers/media/tuners/tea5761.c348
-rw-r--r--drivers/media/tuners/tea5761.h47
-rw-r--r--drivers/media/tuners/tea5767.c475
-rw-r--r--drivers/media/tuners/tea5767.h66
-rw-r--r--drivers/media/tuners/tua9001.c215
-rw-r--r--drivers/media/tuners/tua9001.h46
-rw-r--r--drivers/media/tuners/tua9001_priv.h34
-rw-r--r--drivers/media/tuners/tuner-i2c.h182
-rw-r--r--drivers/media/tuners/tuner-simple.c1155
-rw-r--r--drivers/media/tuners/tuner-simple.h39
-rw-r--r--drivers/media/tuners/tuner-types.c1883
-rw-r--r--drivers/media/tuners/tuner-xc2028-types.h141
-rw-r--r--drivers/media/tuners/tuner-xc2028.c1509
-rw-r--r--drivers/media/tuners/tuner-xc2028.h72
-rw-r--r--drivers/media/tuners/xc4000.c1757
-rw-r--r--drivers/media/tuners/xc4000.h67
-rw-r--r--drivers/media/tuners/xc5000.c1366
-rw-r--r--drivers/media/tuners/xc5000.h74
70 files changed, 30389 insertions, 0 deletions
diff --git a/drivers/media/tuners/Kconfig b/drivers/media/tuners/Kconfig
new file mode 100644
index 000000000000..94c6ff7a5da3
--- /dev/null
+++ b/drivers/media/tuners/Kconfig
@@ -0,0 +1,243 @@
1config MEDIA_ATTACH
2 bool "Load and attach frontend and tuner driver modules as needed"
3 depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
4 depends on MODULES
5 default y if !EXPERT
6 help
7 Remove the static dependency of DVB card drivers on all
8 frontend modules for all possible card variants. Instead,
9 allow the card drivers to only load the frontend modules
10 they require.
11
12 Also, tuner module will automatically load a tuner driver
13 when needed, for analog mode.
14
15 This saves several KBytes of memory.
16
17 Note: You will need module-init-tools v3.2 or later for this feature.
18
19 If unsure say Y.
20
21config MEDIA_TUNER
22 tristate
23 depends on (MEDIA_ANALOG_TV_SUPPORT || MEDIA_RADIO_SUPPORT) && I2C
24 default y
25 select MEDIA_TUNER_XC2028 if !MEDIA_TUNER_CUSTOMISE
26 select MEDIA_TUNER_XC5000 if !MEDIA_TUNER_CUSTOMISE
27 select MEDIA_TUNER_XC4000 if !MEDIA_TUNER_CUSTOMISE
28 select MEDIA_TUNER_MT20XX if !MEDIA_TUNER_CUSTOMISE
29 select MEDIA_TUNER_TDA8290 if !MEDIA_TUNER_CUSTOMISE
30 select MEDIA_TUNER_TEA5761 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT && EXPERIMENTAL
31 select MEDIA_TUNER_TEA5767 if !MEDIA_TUNER_CUSTOMISE && MEDIA_RADIO_SUPPORT
32 select MEDIA_TUNER_SIMPLE if !MEDIA_TUNER_CUSTOMISE
33 select MEDIA_TUNER_TDA9887 if !MEDIA_TUNER_CUSTOMISE
34 select MEDIA_TUNER_MC44S803 if !MEDIA_TUNER_CUSTOMISE
35
36config MEDIA_TUNER_CUSTOMISE
37 bool "Customize analog and hybrid tuner modules to build"
38 depends on MEDIA_TUNER
39 default y if EXPERT
40 help
41 This allows the user to deselect tuner drivers unnecessary
42 for their hardware from the build. Use this option with care
43 as deselecting tuner drivers which are in fact necessary will
44 result in V4L/DVB devices which cannot be tuned due to lack of
45 driver support
46
47 If unsure say N.
48
49menu "Customize TV tuners"
50 visible if MEDIA_TUNER_CUSTOMISE
51 depends on MEDIA_ANALOG_TV_SUPPORT || MEDIA_DIGITAL_TV_SUPPORT || MEDIA_RADIO_SUPPORT
52
53config MEDIA_TUNER_SIMPLE
54 tristate "Simple tuner support"
55 depends on MEDIA_SUPPORT && I2C
56 select MEDIA_TUNER_TDA9887
57 default m if MEDIA_TUNER_CUSTOMISE
58 help
59 Say Y here to include support for various simple tuners.
60
61config MEDIA_TUNER_TDA8290
62 tristate "TDA 8290/8295 + 8275(a)/18271 tuner combo"
63 depends on MEDIA_SUPPORT && I2C
64 select MEDIA_TUNER_TDA827X
65 select MEDIA_TUNER_TDA18271
66 default m if MEDIA_TUNER_CUSTOMISE
67 help
68 Say Y here to include support for Philips TDA8290+8275(a) tuner.
69
70config MEDIA_TUNER_TDA827X
71 tristate "Philips TDA827X silicon tuner"
72 depends on MEDIA_SUPPORT && I2C
73 default m if MEDIA_TUNER_CUSTOMISE
74 help
75 A DVB-T silicon tuner module. Say Y when you want to support this tuner.
76
77config MEDIA_TUNER_TDA18271
78 tristate "NXP TDA18271 silicon tuner"
79 depends on MEDIA_SUPPORT && I2C
80 default m if MEDIA_TUNER_CUSTOMISE
81 help
82 A silicon tuner module. Say Y when you want to support this tuner.
83
84config MEDIA_TUNER_TDA9887
85 tristate "TDA 9885/6/7 analog IF demodulator"
86 depends on MEDIA_SUPPORT && I2C
87 default m if MEDIA_TUNER_CUSTOMISE
88 help
89 Say Y here to include support for Philips TDA9885/6/7
90 analog IF demodulator.
91
92config MEDIA_TUNER_TEA5761
93 tristate "TEA 5761 radio tuner (EXPERIMENTAL)"
94 depends on MEDIA_SUPPORT && I2C
95 depends on EXPERIMENTAL
96 default m if MEDIA_TUNER_CUSTOMISE
97 help
98 Say Y here to include support for the Philips TEA5761 radio tuner.
99
100config MEDIA_TUNER_TEA5767
101 tristate "TEA 5767 radio tuner"
102 depends on MEDIA_SUPPORT && I2C
103 default m if MEDIA_TUNER_CUSTOMISE
104 help
105 Say Y here to include support for the Philips TEA5767 radio tuner.
106
107config MEDIA_TUNER_MT20XX
108 tristate "Microtune 2032 / 2050 tuners"
109 depends on MEDIA_SUPPORT && I2C
110 default m if MEDIA_TUNER_CUSTOMISE
111 help
112 Say Y here to include support for the MT2032 / MT2050 tuner.
113
114config MEDIA_TUNER_MT2060
115 tristate "Microtune MT2060 silicon IF tuner"
116 depends on MEDIA_SUPPORT && I2C
117 default m if MEDIA_TUNER_CUSTOMISE
118 help
119 A driver for the silicon IF tuner MT2060 from Microtune.
120
121config MEDIA_TUNER_MT2063
122 tristate "Microtune MT2063 silicon IF tuner"
123 depends on MEDIA_SUPPORT && I2C
124 default m if MEDIA_TUNER_CUSTOMISE
125 help
126 A driver for the silicon IF tuner MT2063 from Microtune.
127
128config MEDIA_TUNER_MT2266
129 tristate "Microtune MT2266 silicon tuner"
130 depends on MEDIA_SUPPORT && I2C
131 default m if MEDIA_TUNER_CUSTOMISE
132 help
133 A driver for the silicon baseband tuner MT2266 from Microtune.
134
135config MEDIA_TUNER_MT2131
136 tristate "Microtune MT2131 silicon tuner"
137 depends on MEDIA_SUPPORT && I2C
138 default m if MEDIA_TUNER_CUSTOMISE
139 help
140 A driver for the silicon baseband tuner MT2131 from Microtune.
141
142config MEDIA_TUNER_QT1010
143 tristate "Quantek QT1010 silicon tuner"
144 depends on MEDIA_SUPPORT && I2C
145 default m if MEDIA_TUNER_CUSTOMISE
146 help
147 A driver for the silicon tuner QT1010 from Quantek.
148
149config MEDIA_TUNER_XC2028
150 tristate "XCeive xc2028/xc3028 tuners"
151 depends on MEDIA_SUPPORT && I2C
152 default m if MEDIA_TUNER_CUSTOMISE
153 help
154 Say Y here to include support for the xc2028/xc3028 tuners.
155
156config MEDIA_TUNER_XC5000
157 tristate "Xceive XC5000 silicon tuner"
158 depends on MEDIA_SUPPORT && I2C
159 default m if MEDIA_TUNER_CUSTOMISE
160 help
161 A driver for the silicon tuner XC5000 from Xceive.
162 This device is only used inside a SiP called together with a
163 demodulator for now.
164
165config MEDIA_TUNER_XC4000
166 tristate "Xceive XC4000 silicon tuner"
167 depends on MEDIA_SUPPORT && I2C
168 default m if MEDIA_TUNER_CUSTOMISE
169 help
170 A driver for the silicon tuner XC4000 from Xceive.
171 This device is only used inside a SiP called together with a
172 demodulator for now.
173
174config MEDIA_TUNER_MXL5005S
175 tristate "MaxLinear MSL5005S silicon tuner"
176 depends on MEDIA_SUPPORT && I2C
177 default m if MEDIA_TUNER_CUSTOMISE
178 help
179 A driver for the silicon tuner MXL5005S from MaxLinear.
180
181config MEDIA_TUNER_MXL5007T
182 tristate "MaxLinear MxL5007T silicon tuner"
183 depends on MEDIA_SUPPORT && I2C
184 default m if MEDIA_TUNER_CUSTOMISE
185 help
186 A driver for the silicon tuner MxL5007T from MaxLinear.
187
188config MEDIA_TUNER_MC44S803
189 tristate "Freescale MC44S803 Low Power CMOS Broadband tuners"
190 depends on MEDIA_SUPPORT && I2C
191 default m if MEDIA_TUNER_CUSTOMISE
192 help
193 Say Y here to support the Freescale MC44S803 based tuners
194
195config MEDIA_TUNER_MAX2165
196 tristate "Maxim MAX2165 silicon tuner"
197 depends on MEDIA_SUPPORT && I2C
198 default m if MEDIA_TUNER_CUSTOMISE
199 help
200 A driver for the silicon tuner MAX2165 from Maxim.
201
202config MEDIA_TUNER_TDA18218
203 tristate "NXP TDA18218 silicon tuner"
204 depends on MEDIA_SUPPORT && I2C
205 default m if MEDIA_TUNER_CUSTOMISE
206 help
207 NXP TDA18218 silicon tuner driver.
208
209config MEDIA_TUNER_FC0011
210 tristate "Fitipower FC0011 silicon tuner"
211 depends on MEDIA_SUPPORT && I2C
212 default m if MEDIA_TUNER_CUSTOMISE
213 help
214 Fitipower FC0011 silicon tuner driver.
215
216config MEDIA_TUNER_FC0012
217 tristate "Fitipower FC0012 silicon tuner"
218 depends on MEDIA_SUPPORT && I2C
219 default m if MEDIA_TUNER_CUSTOMISE
220 help
221 Fitipower FC0012 silicon tuner driver.
222
223config MEDIA_TUNER_FC0013
224 tristate "Fitipower FC0013 silicon tuner"
225 depends on MEDIA_SUPPORT && I2C
226 default m if MEDIA_TUNER_CUSTOMISE
227 help
228 Fitipower FC0013 silicon tuner driver.
229
230config MEDIA_TUNER_TDA18212
231 tristate "NXP TDA18212 silicon tuner"
232 depends on MEDIA_SUPPORT && I2C
233 default m if MEDIA_TUNER_CUSTOMISE
234 help
235 NXP TDA18212 silicon tuner driver.
236
237config MEDIA_TUNER_TUA9001
238 tristate "Infineon TUA 9001 silicon tuner"
239 depends on MEDIA_SUPPORT && I2C
240 default m if MEDIA_TUNER_CUSTOMISE
241 help
242 Infineon TUA 9001 silicon tuner driver.
243endmenu
diff --git a/drivers/media/tuners/Makefile b/drivers/media/tuners/Makefile
new file mode 100644
index 000000000000..112aeee90202
--- /dev/null
+++ b/drivers/media/tuners/Makefile
@@ -0,0 +1,37 @@
1#
2# Makefile for common V4L/DVB tuners
3#
4
5tda18271-objs := tda18271-maps.o tda18271-common.o tda18271-fe.o
6
7obj-$(CONFIG_MEDIA_TUNER_XC2028) += tuner-xc2028.o
8obj-$(CONFIG_MEDIA_TUNER_SIMPLE) += tuner-simple.o
9# tuner-types will be merged into tuner-simple, in the future
10obj-$(CONFIG_MEDIA_TUNER_SIMPLE) += tuner-types.o
11obj-$(CONFIG_MEDIA_TUNER_MT20XX) += mt20xx.o
12obj-$(CONFIG_MEDIA_TUNER_TDA8290) += tda8290.o
13obj-$(CONFIG_MEDIA_TUNER_TEA5767) += tea5767.o
14obj-$(CONFIG_MEDIA_TUNER_TEA5761) += tea5761.o
15obj-$(CONFIG_MEDIA_TUNER_TDA9887) += tda9887.o
16obj-$(CONFIG_MEDIA_TUNER_TDA827X) += tda827x.o
17obj-$(CONFIG_MEDIA_TUNER_TDA18271) += tda18271.o
18obj-$(CONFIG_MEDIA_TUNER_XC5000) += xc5000.o
19obj-$(CONFIG_MEDIA_TUNER_XC4000) += xc4000.o
20obj-$(CONFIG_MEDIA_TUNER_MT2060) += mt2060.o
21obj-$(CONFIG_MEDIA_TUNER_MT2063) += mt2063.o
22obj-$(CONFIG_MEDIA_TUNER_MT2266) += mt2266.o
23obj-$(CONFIG_MEDIA_TUNER_QT1010) += qt1010.o
24obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
25obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
26obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
27obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
28obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
29obj-$(CONFIG_MEDIA_TUNER_TDA18218) += tda18218.o
30obj-$(CONFIG_MEDIA_TUNER_TDA18212) += tda18212.o
31obj-$(CONFIG_MEDIA_TUNER_TUA9001) += tua9001.o
32obj-$(CONFIG_MEDIA_TUNER_FC0011) += fc0011.o
33obj-$(CONFIG_MEDIA_TUNER_FC0012) += fc0012.o
34obj-$(CONFIG_MEDIA_TUNER_FC0013) += fc0013.o
35
36ccflags-y += -I$(srctree)/drivers/media/dvb-core
37ccflags-y += -I$(srctree)/drivers/media/dvb-frontends
diff --git a/drivers/media/tuners/fc0011.c b/drivers/media/tuners/fc0011.c
new file mode 100644
index 000000000000..e4882546c283
--- /dev/null
+++ b/drivers/media/tuners/fc0011.c
@@ -0,0 +1,524 @@
1/*
2 * Fitipower FC0011 tuner driver
3 *
4 * Copyright (C) 2012 Michael Buesch <m@bues.ch>
5 *
6 * Derived from FC0012 tuner driver:
7 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include "fc0011.h"
25
26
27/* Tuner registers */
28enum {
29 FC11_REG_0,
30 FC11_REG_FA, /* FA */
31 FC11_REG_FP, /* FP */
32 FC11_REG_XINHI, /* XIN high 8 bit */
33 FC11_REG_XINLO, /* XIN low 8 bit */
34 FC11_REG_VCO, /* VCO */
35 FC11_REG_VCOSEL, /* VCO select */
36 FC11_REG_7, /* Unknown tuner reg 7 */
37 FC11_REG_8, /* Unknown tuner reg 8 */
38 FC11_REG_9,
39 FC11_REG_10, /* Unknown tuner reg 10 */
40 FC11_REG_11, /* Unknown tuner reg 11 */
41 FC11_REG_12,
42 FC11_REG_RCCAL, /* RC calibrate */
43 FC11_REG_VCOCAL, /* VCO calibrate */
44 FC11_REG_15,
45 FC11_REG_16, /* Unknown tuner reg 16 */
46 FC11_REG_17,
47
48 FC11_NR_REGS, /* Number of registers */
49};
50
51enum FC11_REG_VCOSEL_bits {
52 FC11_VCOSEL_2 = 0x08, /* VCO select 2 */
53 FC11_VCOSEL_1 = 0x10, /* VCO select 1 */
54 FC11_VCOSEL_CLKOUT = 0x20, /* Fix clock out */
55 FC11_VCOSEL_BW7M = 0x40, /* 7MHz bw */
56 FC11_VCOSEL_BW6M = 0x80, /* 6MHz bw */
57};
58
59enum FC11_REG_RCCAL_bits {
60 FC11_RCCAL_FORCE = 0x10, /* force */
61};
62
63enum FC11_REG_VCOCAL_bits {
64 FC11_VCOCAL_RUN = 0, /* VCO calibration run */
65 FC11_VCOCAL_VALUEMASK = 0x3F, /* VCO calibration value mask */
66 FC11_VCOCAL_OK = 0x40, /* VCO calibration Ok */
67 FC11_VCOCAL_RESET = 0x80, /* VCO calibration reset */
68};
69
70
71struct fc0011_priv {
72 struct i2c_adapter *i2c;
73 u8 addr;
74
75 u32 frequency;
76 u32 bandwidth;
77};
78
79
80static int fc0011_writereg(struct fc0011_priv *priv, u8 reg, u8 val)
81{
82 u8 buf[2] = { reg, val };
83 struct i2c_msg msg = { .addr = priv->addr,
84 .flags = 0, .buf = buf, .len = 2 };
85
86 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
87 dev_err(&priv->i2c->dev,
88 "I2C write reg failed, reg: %02x, val: %02x\n",
89 reg, val);
90 return -EIO;
91 }
92
93 return 0;
94}
95
96static int fc0011_readreg(struct fc0011_priv *priv, u8 reg, u8 *val)
97{
98 u8 dummy;
99 struct i2c_msg msg[2] = {
100 { .addr = priv->addr,
101 .flags = 0, .buf = &reg, .len = 1 },
102 { .addr = priv->addr,
103 .flags = I2C_M_RD, .buf = val ? : &dummy, .len = 1 },
104 };
105
106 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
107 dev_err(&priv->i2c->dev,
108 "I2C read failed, reg: %02x\n", reg);
109 return -EIO;
110 }
111
112 return 0;
113}
114
115static int fc0011_release(struct dvb_frontend *fe)
116{
117 kfree(fe->tuner_priv);
118 fe->tuner_priv = NULL;
119
120 return 0;
121}
122
123static int fc0011_init(struct dvb_frontend *fe)
124{
125 struct fc0011_priv *priv = fe->tuner_priv;
126 int err;
127
128 if (WARN_ON(!fe->callback))
129 return -EINVAL;
130
131 err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
132 FC0011_FE_CALLBACK_POWER, priv->addr);
133 if (err) {
134 dev_err(&priv->i2c->dev, "Power-on callback failed\n");
135 return err;
136 }
137 err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
138 FC0011_FE_CALLBACK_RESET, priv->addr);
139 if (err) {
140 dev_err(&priv->i2c->dev, "Reset callback failed\n");
141 return err;
142 }
143
144 return 0;
145}
146
147/* Initiate VCO calibration */
148static int fc0011_vcocal_trigger(struct fc0011_priv *priv)
149{
150 int err;
151
152 err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RESET);
153 if (err)
154 return err;
155 err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
156 if (err)
157 return err;
158
159 return 0;
160}
161
162/* Read VCO calibration value */
163static int fc0011_vcocal_read(struct fc0011_priv *priv, u8 *value)
164{
165 int err;
166
167 err = fc0011_writereg(priv, FC11_REG_VCOCAL, FC11_VCOCAL_RUN);
168 if (err)
169 return err;
170 usleep_range(10000, 20000);
171 err = fc0011_readreg(priv, FC11_REG_VCOCAL, value);
172 if (err)
173 return err;
174
175 return 0;
176}
177
178static int fc0011_set_params(struct dvb_frontend *fe)
179{
180 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
181 struct fc0011_priv *priv = fe->tuner_priv;
182 int err;
183 unsigned int i, vco_retries;
184 u32 freq = p->frequency / 1000;
185 u32 bandwidth = p->bandwidth_hz / 1000;
186 u32 fvco, xin, xdiv, xdivr;
187 u16 frac;
188 u8 fa, fp, vco_sel, vco_cal;
189 u8 regs[FC11_NR_REGS] = { };
190
191 regs[FC11_REG_7] = 0x0F;
192 regs[FC11_REG_8] = 0x3E;
193 regs[FC11_REG_10] = 0xB8;
194 regs[FC11_REG_11] = 0x80;
195 regs[FC11_REG_RCCAL] = 0x04;
196 err = fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
197 err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
198 err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
199 err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
200 err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
201 if (err)
202 return -EIO;
203
204 /* Set VCO freq and VCO div */
205 if (freq < 54000) {
206 fvco = freq * 64;
207 regs[FC11_REG_VCO] = 0x82;
208 } else if (freq < 108000) {
209 fvco = freq * 32;
210 regs[FC11_REG_VCO] = 0x42;
211 } else if (freq < 216000) {
212 fvco = freq * 16;
213 regs[FC11_REG_VCO] = 0x22;
214 } else if (freq < 432000) {
215 fvco = freq * 8;
216 regs[FC11_REG_VCO] = 0x12;
217 } else {
218 fvco = freq * 4;
219 regs[FC11_REG_VCO] = 0x0A;
220 }
221
222 /* Calc XIN. The PLL reference frequency is 18 MHz. */
223 xdiv = fvco / 18000;
224 frac = fvco - xdiv * 18000;
225 frac = (frac << 15) / 18000;
226 if (frac >= 16384)
227 frac += 32786;
228 if (!frac)
229 xin = 0;
230 else if (frac < 511)
231 xin = 512;
232 else if (frac < 65026)
233 xin = frac;
234 else
235 xin = 65024;
236 regs[FC11_REG_XINHI] = xin >> 8;
237 regs[FC11_REG_XINLO] = xin;
238
239 /* Calc FP and FA */
240 xdivr = xdiv;
241 if (fvco - xdiv * 18000 >= 9000)
242 xdivr += 1; /* round */
243 fp = xdivr / 8;
244 fa = xdivr - fp * 8;
245 if (fa < 2) {
246 fp -= 1;
247 fa += 8;
248 }
249 if (fp > 0x1F) {
250 fp &= 0x1F;
251 fa &= 0xF;
252 }
253 if (fa >= fp) {
254 dev_warn(&priv->i2c->dev,
255 "fa %02X >= fp %02X, but trying to continue\n",
256 (unsigned int)(u8)fa, (unsigned int)(u8)fp);
257 }
258 regs[FC11_REG_FA] = fa;
259 regs[FC11_REG_FP] = fp;
260
261 /* Select bandwidth */
262 switch (bandwidth) {
263 case 8000:
264 break;
265 case 7000:
266 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW7M;
267 break;
268 default:
269 dev_warn(&priv->i2c->dev, "Unsupported bandwidth %u kHz. "
270 "Using 6000 kHz.\n",
271 bandwidth);
272 bandwidth = 6000;
273 /* fallthrough */
274 case 6000:
275 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_BW6M;
276 break;
277 }
278
279 /* Pre VCO select */
280 if (fvco < 2320000) {
281 vco_sel = 0;
282 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
283 } else if (fvco < 3080000) {
284 vco_sel = 1;
285 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
286 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
287 } else {
288 vco_sel = 2;
289 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
290 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
291 }
292
293 /* Fix for low freqs */
294 if (freq < 45000) {
295 regs[FC11_REG_FA] = 0x6;
296 regs[FC11_REG_FP] = 0x11;
297 }
298
299 /* Clock out fix */
300 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_CLKOUT;
301
302 /* Write the cached registers */
303 for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++) {
304 err = fc0011_writereg(priv, i, regs[i]);
305 if (err)
306 return err;
307 }
308
309 /* VCO calibration */
310 err = fc0011_vcocal_trigger(priv);
311 if (err)
312 return err;
313 err = fc0011_vcocal_read(priv, &vco_cal);
314 if (err)
315 return err;
316 vco_retries = 0;
317 while (!(vco_cal & FC11_VCOCAL_OK) && vco_retries < 3) {
318 /* Reset the tuner and try again */
319 err = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
320 FC0011_FE_CALLBACK_RESET, priv->addr);
321 if (err) {
322 dev_err(&priv->i2c->dev, "Failed to reset tuner\n");
323 return err;
324 }
325 /* Reinit tuner config */
326 err = 0;
327 for (i = FC11_REG_FA; i <= FC11_REG_VCOSEL; i++)
328 err |= fc0011_writereg(priv, i, regs[i]);
329 err |= fc0011_writereg(priv, FC11_REG_7, regs[FC11_REG_7]);
330 err |= fc0011_writereg(priv, FC11_REG_8, regs[FC11_REG_8]);
331 err |= fc0011_writereg(priv, FC11_REG_10, regs[FC11_REG_10]);
332 err |= fc0011_writereg(priv, FC11_REG_11, regs[FC11_REG_11]);
333 err |= fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
334 if (err)
335 return -EIO;
336 /* VCO calibration */
337 err = fc0011_vcocal_trigger(priv);
338 if (err)
339 return err;
340 err = fc0011_vcocal_read(priv, &vco_cal);
341 if (err)
342 return err;
343 vco_retries++;
344 }
345 if (!(vco_cal & FC11_VCOCAL_OK)) {
346 dev_err(&priv->i2c->dev,
347 "Failed to read VCO calibration value (got %02X)\n",
348 (unsigned int)vco_cal);
349 return -EIO;
350 }
351 vco_cal &= FC11_VCOCAL_VALUEMASK;
352
353 switch (vco_sel) {
354 case 0:
355 if (vco_cal < 8) {
356 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
357 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
358 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
359 regs[FC11_REG_VCOSEL]);
360 if (err)
361 return err;
362 err = fc0011_vcocal_trigger(priv);
363 if (err)
364 return err;
365 } else {
366 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
367 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
368 regs[FC11_REG_VCOSEL]);
369 if (err)
370 return err;
371 }
372 break;
373 case 1:
374 if (vco_cal < 5) {
375 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
376 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
377 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
378 regs[FC11_REG_VCOSEL]);
379 if (err)
380 return err;
381 err = fc0011_vcocal_trigger(priv);
382 if (err)
383 return err;
384 } else if (vco_cal <= 48) {
385 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
386 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
387 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
388 regs[FC11_REG_VCOSEL]);
389 if (err)
390 return err;
391 } else {
392 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
393 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
394 regs[FC11_REG_VCOSEL]);
395 if (err)
396 return err;
397 err = fc0011_vcocal_trigger(priv);
398 if (err)
399 return err;
400 }
401 break;
402 case 2:
403 if (vco_cal > 53) {
404 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
405 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_1;
406 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
407 regs[FC11_REG_VCOSEL]);
408 if (err)
409 return err;
410 err = fc0011_vcocal_trigger(priv);
411 if (err)
412 return err;
413 } else {
414 regs[FC11_REG_VCOSEL] &= ~(FC11_VCOSEL_1 | FC11_VCOSEL_2);
415 regs[FC11_REG_VCOSEL] |= FC11_VCOSEL_2;
416 err = fc0011_writereg(priv, FC11_REG_VCOSEL,
417 regs[FC11_REG_VCOSEL]);
418 if (err)
419 return err;
420 }
421 break;
422 }
423 err = fc0011_vcocal_read(priv, NULL);
424 if (err)
425 return err;
426 usleep_range(10000, 50000);
427
428 err = fc0011_readreg(priv, FC11_REG_RCCAL, &regs[FC11_REG_RCCAL]);
429 if (err)
430 return err;
431 regs[FC11_REG_RCCAL] |= FC11_RCCAL_FORCE;
432 err = fc0011_writereg(priv, FC11_REG_RCCAL, regs[FC11_REG_RCCAL]);
433 if (err)
434 return err;
435 err = fc0011_writereg(priv, FC11_REG_16, 0xB);
436 if (err)
437 return err;
438
439 dev_dbg(&priv->i2c->dev, "Tuned to "
440 "fa=%02X fp=%02X xin=%02X%02X vco=%02X vcosel=%02X "
441 "vcocal=%02X(%u) bw=%u\n",
442 (unsigned int)regs[FC11_REG_FA],
443 (unsigned int)regs[FC11_REG_FP],
444 (unsigned int)regs[FC11_REG_XINHI],
445 (unsigned int)regs[FC11_REG_XINLO],
446 (unsigned int)regs[FC11_REG_VCO],
447 (unsigned int)regs[FC11_REG_VCOSEL],
448 (unsigned int)vco_cal, vco_retries,
449 (unsigned int)bandwidth);
450
451 priv->frequency = p->frequency;
452 priv->bandwidth = p->bandwidth_hz;
453
454 return 0;
455}
456
457static int fc0011_get_frequency(struct dvb_frontend *fe, u32 *frequency)
458{
459 struct fc0011_priv *priv = fe->tuner_priv;
460
461 *frequency = priv->frequency;
462
463 return 0;
464}
465
466static int fc0011_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
467{
468 *frequency = 0;
469
470 return 0;
471}
472
473static int fc0011_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
474{
475 struct fc0011_priv *priv = fe->tuner_priv;
476
477 *bandwidth = priv->bandwidth;
478
479 return 0;
480}
481
482static const struct dvb_tuner_ops fc0011_tuner_ops = {
483 .info = {
484 .name = "Fitipower FC0011",
485
486 .frequency_min = 45000000,
487 .frequency_max = 1000000000,
488 },
489
490 .release = fc0011_release,
491 .init = fc0011_init,
492
493 .set_params = fc0011_set_params,
494
495 .get_frequency = fc0011_get_frequency,
496 .get_if_frequency = fc0011_get_if_frequency,
497 .get_bandwidth = fc0011_get_bandwidth,
498};
499
500struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
501 struct i2c_adapter *i2c,
502 const struct fc0011_config *config)
503{
504 struct fc0011_priv *priv;
505
506 priv = kzalloc(sizeof(struct fc0011_priv), GFP_KERNEL);
507 if (!priv)
508 return NULL;
509
510 priv->i2c = i2c;
511 priv->addr = config->i2c_address;
512
513 fe->tuner_priv = priv;
514 fe->ops.tuner_ops = fc0011_tuner_ops;
515
516 dev_info(&priv->i2c->dev, "Fitipower FC0011 tuner attached\n");
517
518 return fe;
519}
520EXPORT_SYMBOL(fc0011_attach);
521
522MODULE_DESCRIPTION("Fitipower FC0011 silicon tuner driver");
523MODULE_AUTHOR("Michael Buesch <m@bues.ch>");
524MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/fc0011.h b/drivers/media/tuners/fc0011.h
new file mode 100644
index 000000000000..0ee581f122d2
--- /dev/null
+++ b/drivers/media/tuners/fc0011.h
@@ -0,0 +1,41 @@
1#ifndef LINUX_FC0011_H_
2#define LINUX_FC0011_H_
3
4#include "dvb_frontend.h"
5
6
7/** struct fc0011_config - fc0011 hardware config
8 *
9 * @i2c_address: I2C bus address.
10 */
11struct fc0011_config {
12 u8 i2c_address;
13};
14
15/** enum fc0011_fe_callback_commands - Frontend callbacks
16 *
17 * @FC0011_FE_CALLBACK_POWER: Power on tuner hardware.
18 * @FC0011_FE_CALLBACK_RESET: Request a tuner reset.
19 */
20enum fc0011_fe_callback_commands {
21 FC0011_FE_CALLBACK_POWER,
22 FC0011_FE_CALLBACK_RESET,
23};
24
25#if defined(CONFIG_MEDIA_TUNER_FC0011) ||\
26 defined(CONFIG_MEDIA_TUNER_FC0011_MODULE)
27struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
28 struct i2c_adapter *i2c,
29 const struct fc0011_config *config);
30#else
31static inline
32struct dvb_frontend *fc0011_attach(struct dvb_frontend *fe,
33 struct i2c_adapter *i2c,
34 const struct fc0011_config *config)
35{
36 dev_err(&i2c->dev, "fc0011 driver disabled in Kconfig\n");
37 return NULL;
38}
39#endif
40
41#endif /* LINUX_FC0011_H_ */
diff --git a/drivers/media/tuners/fc0012-priv.h b/drivers/media/tuners/fc0012-priv.h
new file mode 100644
index 000000000000..4577c917e616
--- /dev/null
+++ b/drivers/media/tuners/fc0012-priv.h
@@ -0,0 +1,43 @@
1/*
2 * Fitipower FC0012 tuner driver - private includes
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _FC0012_PRIV_H_
22#define _FC0012_PRIV_H_
23
24#define LOG_PREFIX "fc0012"
25
26#undef err
27#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
28#undef info
29#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
30#undef warn
31#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
32
33struct fc0012_priv {
34 struct i2c_adapter *i2c;
35 u8 addr;
36 u8 dual_master;
37 u8 xtal_freq;
38
39 u32 frequency;
40 u32 bandwidth;
41};
42
43#endif
diff --git a/drivers/media/tuners/fc0012.c b/drivers/media/tuners/fc0012.c
new file mode 100644
index 000000000000..308135abd54c
--- /dev/null
+++ b/drivers/media/tuners/fc0012.c
@@ -0,0 +1,467 @@
1/*
2 * Fitipower FC0012 tuner driver
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "fc0012.h"
22#include "fc0012-priv.h"
23
24static int fc0012_writereg(struct fc0012_priv *priv, u8 reg, u8 val)
25{
26 u8 buf[2] = {reg, val};
27 struct i2c_msg msg = {
28 .addr = priv->addr, .flags = 0, .buf = buf, .len = 2
29 };
30
31 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
32 err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
33 return -EREMOTEIO;
34 }
35 return 0;
36}
37
38static int fc0012_readreg(struct fc0012_priv *priv, u8 reg, u8 *val)
39{
40 struct i2c_msg msg[2] = {
41 { .addr = priv->addr, .flags = 0, .buf = &reg, .len = 1 },
42 { .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
43 };
44
45 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
46 err("I2C read reg failed, reg: %02x", reg);
47 return -EREMOTEIO;
48 }
49 return 0;
50}
51
52static int fc0012_release(struct dvb_frontend *fe)
53{
54 kfree(fe->tuner_priv);
55 fe->tuner_priv = NULL;
56 return 0;
57}
58
59static int fc0012_init(struct dvb_frontend *fe)
60{
61 struct fc0012_priv *priv = fe->tuner_priv;
62 int i, ret = 0;
63 unsigned char reg[] = {
64 0x00, /* dummy reg. 0 */
65 0x05, /* reg. 0x01 */
66 0x10, /* reg. 0x02 */
67 0x00, /* reg. 0x03 */
68 0x00, /* reg. 0x04 */
69 0x0f, /* reg. 0x05: may also be 0x0a */
70 0x00, /* reg. 0x06: divider 2, VCO slow */
71 0x00, /* reg. 0x07: may also be 0x0f */
72 0xff, /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
73 Loop Bw 1/8 */
74 0x6e, /* reg. 0x09: Disable LoopThrough, Enable LoopThrough: 0x6f */
75 0xb8, /* reg. 0x0a: Disable LO Test Buffer */
76 0x82, /* reg. 0x0b: Output Clock is same as clock frequency,
77 may also be 0x83 */
78 0xfc, /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
79 0x02, /* reg. 0x0d: AGC Not Forcing & LNA Forcing, 0x02 for DVB-T */
80 0x00, /* reg. 0x0e */
81 0x00, /* reg. 0x0f */
82 0x00, /* reg. 0x10: may also be 0x0d */
83 0x00, /* reg. 0x11 */
84 0x1f, /* reg. 0x12: Set to maximum gain */
85 0x08, /* reg. 0x13: Set to Middle Gain: 0x08,
86 Low Gain: 0x00, High Gain: 0x10, enable IX2: 0x80 */
87 0x00, /* reg. 0x14 */
88 0x04, /* reg. 0x15: Enable LNA COMPS */
89 };
90
91 switch (priv->xtal_freq) {
92 case FC_XTAL_27_MHZ:
93 case FC_XTAL_28_8_MHZ:
94 reg[0x07] |= 0x20;
95 break;
96 case FC_XTAL_36_MHZ:
97 default:
98 break;
99 }
100
101 if (priv->dual_master)
102 reg[0x0c] |= 0x02;
103
104 if (fe->ops.i2c_gate_ctrl)
105 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
106
107 for (i = 1; i < sizeof(reg); i++) {
108 ret = fc0012_writereg(priv, i, reg[i]);
109 if (ret)
110 break;
111 }
112
113 if (fe->ops.i2c_gate_ctrl)
114 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
115
116 if (ret)
117 err("fc0012_writereg failed: %d", ret);
118
119 return ret;
120}
121
122static int fc0012_sleep(struct dvb_frontend *fe)
123{
124 /* nothing to do here */
125 return 0;
126}
127
128static int fc0012_set_params(struct dvb_frontend *fe)
129{
130 struct fc0012_priv *priv = fe->tuner_priv;
131 int i, ret = 0;
132 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
133 u32 freq = p->frequency / 1000;
134 u32 delsys = p->delivery_system;
135 unsigned char reg[7], am, pm, multi, tmp;
136 unsigned long f_vco;
137 unsigned short xtal_freq_khz_2, xin, xdiv;
138 int vco_select = false;
139
140 if (fe->callback) {
141 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
142 FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
143 if (ret)
144 goto exit;
145 }
146
147 switch (priv->xtal_freq) {
148 case FC_XTAL_27_MHZ:
149 xtal_freq_khz_2 = 27000 / 2;
150 break;
151 case FC_XTAL_36_MHZ:
152 xtal_freq_khz_2 = 36000 / 2;
153 break;
154 case FC_XTAL_28_8_MHZ:
155 default:
156 xtal_freq_khz_2 = 28800 / 2;
157 break;
158 }
159
160 /* select frequency divider and the frequency of VCO */
161 if (freq < 37084) { /* freq * 96 < 3560000 */
162 multi = 96;
163 reg[5] = 0x82;
164 reg[6] = 0x00;
165 } else if (freq < 55625) { /* freq * 64 < 3560000 */
166 multi = 64;
167 reg[5] = 0x82;
168 reg[6] = 0x02;
169 } else if (freq < 74167) { /* freq * 48 < 3560000 */
170 multi = 48;
171 reg[5] = 0x42;
172 reg[6] = 0x00;
173 } else if (freq < 111250) { /* freq * 32 < 3560000 */
174 multi = 32;
175 reg[5] = 0x42;
176 reg[6] = 0x02;
177 } else if (freq < 148334) { /* freq * 24 < 3560000 */
178 multi = 24;
179 reg[5] = 0x22;
180 reg[6] = 0x00;
181 } else if (freq < 222500) { /* freq * 16 < 3560000 */
182 multi = 16;
183 reg[5] = 0x22;
184 reg[6] = 0x02;
185 } else if (freq < 296667) { /* freq * 12 < 3560000 */
186 multi = 12;
187 reg[5] = 0x12;
188 reg[6] = 0x00;
189 } else if (freq < 445000) { /* freq * 8 < 3560000 */
190 multi = 8;
191 reg[5] = 0x12;
192 reg[6] = 0x02;
193 } else if (freq < 593334) { /* freq * 6 < 3560000 */
194 multi = 6;
195 reg[5] = 0x0a;
196 reg[6] = 0x00;
197 } else {
198 multi = 4;
199 reg[5] = 0x0a;
200 reg[6] = 0x02;
201 }
202
203 f_vco = freq * multi;
204
205 if (f_vco >= 3060000) {
206 reg[6] |= 0x08;
207 vco_select = true;
208 }
209
210 if (freq >= 45000) {
211 /* From divided value (XDIV) determined the FA and FP value */
212 xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
213 if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
214 xdiv++;
215
216 pm = (unsigned char)(xdiv / 8);
217 am = (unsigned char)(xdiv - (8 * pm));
218
219 if (am < 2) {
220 reg[1] = am + 8;
221 reg[2] = pm - 1;
222 } else {
223 reg[1] = am;
224 reg[2] = pm;
225 }
226 } else {
227 /* fix for frequency less than 45 MHz */
228 reg[1] = 0x06;
229 reg[2] = 0x11;
230 }
231
232 /* fix clock out */
233 reg[6] |= 0x20;
234
235 /* From VCO frequency determines the XIN ( fractional part of Delta
236 Sigma PLL) and divided value (XDIV) */
237 xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
238 xin = (xin << 15) / xtal_freq_khz_2;
239 if (xin >= 16384)
240 xin += 32768;
241
242 reg[3] = xin >> 8; /* xin with 9 bit resolution */
243 reg[4] = xin & 0xff;
244
245 if (delsys == SYS_DVBT) {
246 reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
247 switch (p->bandwidth_hz) {
248 case 6000000:
249 reg[6] |= 0x80;
250 break;
251 case 7000000:
252 reg[6] |= 0x40;
253 break;
254 case 8000000:
255 default:
256 break;
257 }
258 } else {
259 err("%s: modulation type not supported!", __func__);
260 return -EINVAL;
261 }
262
263 /* modified for Realtek demod */
264 reg[5] |= 0x07;
265
266 if (fe->ops.i2c_gate_ctrl)
267 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
268
269 for (i = 1; i <= 6; i++) {
270 ret = fc0012_writereg(priv, i, reg[i]);
271 if (ret)
272 goto exit;
273 }
274
275 /* VCO Calibration */
276 ret = fc0012_writereg(priv, 0x0e, 0x80);
277 if (!ret)
278 ret = fc0012_writereg(priv, 0x0e, 0x00);
279
280 /* VCO Re-Calibration if needed */
281 if (!ret)
282 ret = fc0012_writereg(priv, 0x0e, 0x00);
283
284 if (!ret) {
285 msleep(10);
286 ret = fc0012_readreg(priv, 0x0e, &tmp);
287 }
288 if (ret)
289 goto exit;
290
291 /* vco selection */
292 tmp &= 0x3f;
293
294 if (vco_select) {
295 if (tmp > 0x3c) {
296 reg[6] &= ~0x08;
297 ret = fc0012_writereg(priv, 0x06, reg[6]);
298 if (!ret)
299 ret = fc0012_writereg(priv, 0x0e, 0x80);
300 if (!ret)
301 ret = fc0012_writereg(priv, 0x0e, 0x00);
302 }
303 } else {
304 if (tmp < 0x02) {
305 reg[6] |= 0x08;
306 ret = fc0012_writereg(priv, 0x06, reg[6]);
307 if (!ret)
308 ret = fc0012_writereg(priv, 0x0e, 0x80);
309 if (!ret)
310 ret = fc0012_writereg(priv, 0x0e, 0x00);
311 }
312 }
313
314 priv->frequency = p->frequency;
315 priv->bandwidth = p->bandwidth_hz;
316
317exit:
318 if (fe->ops.i2c_gate_ctrl)
319 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
320 if (ret)
321 warn("%s: failed: %d", __func__, ret);
322 return ret;
323}
324
325static int fc0012_get_frequency(struct dvb_frontend *fe, u32 *frequency)
326{
327 struct fc0012_priv *priv = fe->tuner_priv;
328 *frequency = priv->frequency;
329 return 0;
330}
331
332static int fc0012_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
333{
334 /* CHECK: always ? */
335 *frequency = 0;
336 return 0;
337}
338
339static int fc0012_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
340{
341 struct fc0012_priv *priv = fe->tuner_priv;
342 *bandwidth = priv->bandwidth;
343 return 0;
344}
345
346#define INPUT_ADC_LEVEL -8
347
348static int fc0012_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
349{
350 struct fc0012_priv *priv = fe->tuner_priv;
351 int ret;
352 unsigned char tmp;
353 int int_temp, lna_gain, int_lna, tot_agc_gain, power;
354 const int fc0012_lna_gain_table[] = {
355 /* low gain */
356 -63, -58, -99, -73,
357 -63, -65, -54, -60,
358 /* middle gain */
359 71, 70, 68, 67,
360 65, 63, 61, 58,
361 /* high gain */
362 197, 191, 188, 186,
363 184, 182, 181, 179,
364 };
365
366 if (fe->ops.i2c_gate_ctrl)
367 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
368
369 ret = fc0012_writereg(priv, 0x12, 0x00);
370 if (ret)
371 goto err;
372
373 ret = fc0012_readreg(priv, 0x12, &tmp);
374 if (ret)
375 goto err;
376 int_temp = tmp;
377
378 ret = fc0012_readreg(priv, 0x13, &tmp);
379 if (ret)
380 goto err;
381 lna_gain = tmp & 0x1f;
382
383 if (fe->ops.i2c_gate_ctrl)
384 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
385
386 if (lna_gain < ARRAY_SIZE(fc0012_lna_gain_table)) {
387 int_lna = fc0012_lna_gain_table[lna_gain];
388 tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
389 (int_temp & 0x1f)) * 2;
390 power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
391
392 if (power >= 45)
393 *strength = 255; /* 100% */
394 else if (power < -95)
395 *strength = 0;
396 else
397 *strength = (power + 95) * 255 / 140;
398
399 *strength |= *strength << 8;
400 } else {
401 ret = -1;
402 }
403
404 goto exit;
405
406err:
407 if (fe->ops.i2c_gate_ctrl)
408 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
409exit:
410 if (ret)
411 warn("%s: failed: %d", __func__, ret);
412 return ret;
413}
414
415static const struct dvb_tuner_ops fc0012_tuner_ops = {
416 .info = {
417 .name = "Fitipower FC0012",
418
419 .frequency_min = 37000000, /* estimate */
420 .frequency_max = 862000000, /* estimate */
421 .frequency_step = 0,
422 },
423
424 .release = fc0012_release,
425
426 .init = fc0012_init,
427 .sleep = fc0012_sleep,
428
429 .set_params = fc0012_set_params,
430
431 .get_frequency = fc0012_get_frequency,
432 .get_if_frequency = fc0012_get_if_frequency,
433 .get_bandwidth = fc0012_get_bandwidth,
434
435 .get_rf_strength = fc0012_get_rf_strength,
436};
437
438struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
439 struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
440 enum fc001x_xtal_freq xtal_freq)
441{
442 struct fc0012_priv *priv = NULL;
443
444 priv = kzalloc(sizeof(struct fc0012_priv), GFP_KERNEL);
445 if (priv == NULL)
446 return NULL;
447
448 priv->i2c = i2c;
449 priv->dual_master = dual_master;
450 priv->addr = i2c_address;
451 priv->xtal_freq = xtal_freq;
452
453 info("Fitipower FC0012 successfully attached.");
454
455 fe->tuner_priv = priv;
456
457 memcpy(&fe->ops.tuner_ops, &fc0012_tuner_ops,
458 sizeof(struct dvb_tuner_ops));
459
460 return fe;
461}
462EXPORT_SYMBOL(fc0012_attach);
463
464MODULE_DESCRIPTION("Fitipower FC0012 silicon tuner driver");
465MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
466MODULE_LICENSE("GPL");
467MODULE_VERSION("0.6");
diff --git a/drivers/media/tuners/fc0012.h b/drivers/media/tuners/fc0012.h
new file mode 100644
index 000000000000..4dbd5efe8845
--- /dev/null
+++ b/drivers/media/tuners/fc0012.h
@@ -0,0 +1,44 @@
1/*
2 * Fitipower FC0012 tuner driver - include
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _FC0012_H_
22#define _FC0012_H_
23
24#include "dvb_frontend.h"
25#include "fc001x-common.h"
26
27#if defined(CONFIG_MEDIA_TUNER_FC0012) || \
28 (defined(CONFIG_MEDIA_TUNER_FC0012_MODULE) && defined(MODULE))
29extern struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
30 struct i2c_adapter *i2c,
31 u8 i2c_address, int dual_master,
32 enum fc001x_xtal_freq xtal_freq);
33#else
34static inline struct dvb_frontend *fc0012_attach(struct dvb_frontend *fe,
35 struct i2c_adapter *i2c,
36 u8 i2c_address, int dual_master,
37 enum fc001x_xtal_freq xtal_freq)
38{
39 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
40 return NULL;
41}
42#endif
43
44#endif
diff --git a/drivers/media/tuners/fc0013-priv.h b/drivers/media/tuners/fc0013-priv.h
new file mode 100644
index 000000000000..bfd49dedea22
--- /dev/null
+++ b/drivers/media/tuners/fc0013-priv.h
@@ -0,0 +1,44 @@
1/*
2 * Fitipower FC0013 tuner driver
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef _FC0013_PRIV_H_
23#define _FC0013_PRIV_H_
24
25#define LOG_PREFIX "fc0013"
26
27#undef err
28#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
29#undef info
30#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
31#undef warn
32#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
33
34struct fc0013_priv {
35 struct i2c_adapter *i2c;
36 u8 addr;
37 u8 dual_master;
38 u8 xtal_freq;
39
40 u32 frequency;
41 u32 bandwidth;
42};
43
44#endif
diff --git a/drivers/media/tuners/fc0013.c b/drivers/media/tuners/fc0013.c
new file mode 100644
index 000000000000..bd8f0f1e8f3b
--- /dev/null
+++ b/drivers/media/tuners/fc0013.c
@@ -0,0 +1,634 @@
1/*
2 * Fitipower FC0013 tuner driver
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
5 * partially based on driver code from Fitipower
6 * Copyright (C) 2010 Fitipower Integrated Technology Inc
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 *
22 */
23
24#include "fc0013.h"
25#include "fc0013-priv.h"
26
27static int fc0013_writereg(struct fc0013_priv *priv, u8 reg, u8 val)
28{
29 u8 buf[2] = {reg, val};
30 struct i2c_msg msg = {
31 .addr = priv->addr, .flags = 0, .buf = buf, .len = 2
32 };
33
34 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
35 err("I2C write reg failed, reg: %02x, val: %02x", reg, val);
36 return -EREMOTEIO;
37 }
38 return 0;
39}
40
41static int fc0013_readreg(struct fc0013_priv *priv, u8 reg, u8 *val)
42{
43 struct i2c_msg msg[2] = {
44 { .addr = priv->addr, .flags = 0, .buf = &reg, .len = 1 },
45 { .addr = priv->addr, .flags = I2C_M_RD, .buf = val, .len = 1 },
46 };
47
48 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
49 err("I2C read reg failed, reg: %02x", reg);
50 return -EREMOTEIO;
51 }
52 return 0;
53}
54
55static int fc0013_release(struct dvb_frontend *fe)
56{
57 kfree(fe->tuner_priv);
58 fe->tuner_priv = NULL;
59 return 0;
60}
61
62static int fc0013_init(struct dvb_frontend *fe)
63{
64 struct fc0013_priv *priv = fe->tuner_priv;
65 int i, ret = 0;
66 unsigned char reg[] = {
67 0x00, /* reg. 0x00: dummy */
68 0x09, /* reg. 0x01 */
69 0x16, /* reg. 0x02 */
70 0x00, /* reg. 0x03 */
71 0x00, /* reg. 0x04 */
72 0x17, /* reg. 0x05 */
73 0x02, /* reg. 0x06 */
74 0x0a, /* reg. 0x07: CHECK */
75 0xff, /* reg. 0x08: AGC Clock divide by 256, AGC gain 1/256,
76 Loop Bw 1/8 */
77 0x6f, /* reg. 0x09: enable LoopThrough */
78 0xb8, /* reg. 0x0a: Disable LO Test Buffer */
79 0x82, /* reg. 0x0b: CHECK */
80 0xfc, /* reg. 0x0c: depending on AGC Up-Down mode, may need 0xf8 */
81 0x01, /* reg. 0x0d: AGC Not Forcing & LNA Forcing, may need 0x02 */
82 0x00, /* reg. 0x0e */
83 0x00, /* reg. 0x0f */
84 0x00, /* reg. 0x10 */
85 0x00, /* reg. 0x11 */
86 0x00, /* reg. 0x12 */
87 0x00, /* reg. 0x13 */
88 0x50, /* reg. 0x14: DVB-t High Gain, UHF.
89 Middle Gain: 0x48, Low Gain: 0x40 */
90 0x01, /* reg. 0x15 */
91 };
92
93 switch (priv->xtal_freq) {
94 case FC_XTAL_27_MHZ:
95 case FC_XTAL_28_8_MHZ:
96 reg[0x07] |= 0x20;
97 break;
98 case FC_XTAL_36_MHZ:
99 default:
100 break;
101 }
102
103 if (priv->dual_master)
104 reg[0x0c] |= 0x02;
105
106 if (fe->ops.i2c_gate_ctrl)
107 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
108
109 for (i = 1; i < sizeof(reg); i++) {
110 ret = fc0013_writereg(priv, i, reg[i]);
111 if (ret)
112 break;
113 }
114
115 if (fe->ops.i2c_gate_ctrl)
116 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
117
118 if (ret)
119 err("fc0013_writereg failed: %d", ret);
120
121 return ret;
122}
123
124static int fc0013_sleep(struct dvb_frontend *fe)
125{
126 /* nothing to do here */
127 return 0;
128}
129
130int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
131{
132 struct fc0013_priv *priv = fe->tuner_priv;
133 int ret;
134 u8 rc_cal;
135 int val;
136
137 if (fe->ops.i2c_gate_ctrl)
138 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
139
140 /* push rc_cal value, get rc_cal value */
141 ret = fc0013_writereg(priv, 0x10, 0x00);
142 if (ret)
143 goto error_out;
144
145 /* get rc_cal value */
146 ret = fc0013_readreg(priv, 0x10, &rc_cal);
147 if (ret)
148 goto error_out;
149
150 rc_cal &= 0x0f;
151
152 val = (int)rc_cal + rc_val;
153
154 /* forcing rc_cal */
155 ret = fc0013_writereg(priv, 0x0d, 0x11);
156 if (ret)
157 goto error_out;
158
159 /* modify rc_cal value */
160 if (val > 15)
161 ret = fc0013_writereg(priv, 0x10, 0x0f);
162 else if (val < 0)
163 ret = fc0013_writereg(priv, 0x10, 0x00);
164 else
165 ret = fc0013_writereg(priv, 0x10, (u8)val);
166
167error_out:
168 if (fe->ops.i2c_gate_ctrl)
169 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
170
171 return ret;
172}
173EXPORT_SYMBOL(fc0013_rc_cal_add);
174
175int fc0013_rc_cal_reset(struct dvb_frontend *fe)
176{
177 struct fc0013_priv *priv = fe->tuner_priv;
178 int ret;
179
180 if (fe->ops.i2c_gate_ctrl)
181 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
182
183 ret = fc0013_writereg(priv, 0x0d, 0x01);
184 if (!ret)
185 ret = fc0013_writereg(priv, 0x10, 0x00);
186
187 if (fe->ops.i2c_gate_ctrl)
188 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
189
190 return ret;
191}
192EXPORT_SYMBOL(fc0013_rc_cal_reset);
193
194static int fc0013_set_vhf_track(struct fc0013_priv *priv, u32 freq)
195{
196 int ret;
197 u8 tmp;
198
199 ret = fc0013_readreg(priv, 0x1d, &tmp);
200 if (ret)
201 goto error_out;
202 tmp &= 0xe3;
203 if (freq <= 177500) { /* VHF Track: 7 */
204 ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
205 } else if (freq <= 184500) { /* VHF Track: 6 */
206 ret = fc0013_writereg(priv, 0x1d, tmp | 0x18);
207 } else if (freq <= 191500) { /* VHF Track: 5 */
208 ret = fc0013_writereg(priv, 0x1d, tmp | 0x14);
209 } else if (freq <= 198500) { /* VHF Track: 4 */
210 ret = fc0013_writereg(priv, 0x1d, tmp | 0x10);
211 } else if (freq <= 205500) { /* VHF Track: 3 */
212 ret = fc0013_writereg(priv, 0x1d, tmp | 0x0c);
213 } else if (freq <= 219500) { /* VHF Track: 2 */
214 ret = fc0013_writereg(priv, 0x1d, tmp | 0x08);
215 } else if (freq < 300000) { /* VHF Track: 1 */
216 ret = fc0013_writereg(priv, 0x1d, tmp | 0x04);
217 } else { /* UHF and GPS */
218 ret = fc0013_writereg(priv, 0x1d, tmp | 0x1c);
219 }
220 if (ret)
221 goto error_out;
222error_out:
223 return ret;
224}
225
226static int fc0013_set_params(struct dvb_frontend *fe)
227{
228 struct fc0013_priv *priv = fe->tuner_priv;
229 int i, ret = 0;
230 struct dtv_frontend_properties *p = &fe->dtv_property_cache;
231 u32 freq = p->frequency / 1000;
232 u32 delsys = p->delivery_system;
233 unsigned char reg[7], am, pm, multi, tmp;
234 unsigned long f_vco;
235 unsigned short xtal_freq_khz_2, xin, xdiv;
236 int vco_select = false;
237
238 if (fe->callback) {
239 ret = fe->callback(priv->i2c, DVB_FRONTEND_COMPONENT_TUNER,
240 FC_FE_CALLBACK_VHF_ENABLE, (freq > 300000 ? 0 : 1));
241 if (ret)
242 goto exit;
243 }
244
245 switch (priv->xtal_freq) {
246 case FC_XTAL_27_MHZ:
247 xtal_freq_khz_2 = 27000 / 2;
248 break;
249 case FC_XTAL_36_MHZ:
250 xtal_freq_khz_2 = 36000 / 2;
251 break;
252 case FC_XTAL_28_8_MHZ:
253 default:
254 xtal_freq_khz_2 = 28800 / 2;
255 break;
256 }
257
258 if (fe->ops.i2c_gate_ctrl)
259 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
260
261 /* set VHF track */
262 ret = fc0013_set_vhf_track(priv, freq);
263 if (ret)
264 goto exit;
265
266 if (freq < 300000) {
267 /* enable VHF filter */
268 ret = fc0013_readreg(priv, 0x07, &tmp);
269 if (ret)
270 goto exit;
271 ret = fc0013_writereg(priv, 0x07, tmp | 0x10);
272 if (ret)
273 goto exit;
274
275 /* disable UHF & disable GPS */
276 ret = fc0013_readreg(priv, 0x14, &tmp);
277 if (ret)
278 goto exit;
279 ret = fc0013_writereg(priv, 0x14, tmp & 0x1f);
280 if (ret)
281 goto exit;
282 } else if (freq <= 862000) {
283 /* disable VHF filter */
284 ret = fc0013_readreg(priv, 0x07, &tmp);
285 if (ret)
286 goto exit;
287 ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
288 if (ret)
289 goto exit;
290
291 /* enable UHF & disable GPS */
292 ret = fc0013_readreg(priv, 0x14, &tmp);
293 if (ret)
294 goto exit;
295 ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x40);
296 if (ret)
297 goto exit;
298 } else {
299 /* disable VHF filter */
300 ret = fc0013_readreg(priv, 0x07, &tmp);
301 if (ret)
302 goto exit;
303 ret = fc0013_writereg(priv, 0x07, tmp & 0xef);
304 if (ret)
305 goto exit;
306
307 /* disable UHF & enable GPS */
308 ret = fc0013_readreg(priv, 0x14, &tmp);
309 if (ret)
310 goto exit;
311 ret = fc0013_writereg(priv, 0x14, (tmp & 0x1f) | 0x20);
312 if (ret)
313 goto exit;
314 }
315
316 /* select frequency divider and the frequency of VCO */
317 if (freq < 37084) { /* freq * 96 < 3560000 */
318 multi = 96;
319 reg[5] = 0x82;
320 reg[6] = 0x00;
321 } else if (freq < 55625) { /* freq * 64 < 3560000 */
322 multi = 64;
323 reg[5] = 0x02;
324 reg[6] = 0x02;
325 } else if (freq < 74167) { /* freq * 48 < 3560000 */
326 multi = 48;
327 reg[5] = 0x42;
328 reg[6] = 0x00;
329 } else if (freq < 111250) { /* freq * 32 < 3560000 */
330 multi = 32;
331 reg[5] = 0x82;
332 reg[6] = 0x02;
333 } else if (freq < 148334) { /* freq * 24 < 3560000 */
334 multi = 24;
335 reg[5] = 0x22;
336 reg[6] = 0x00;
337 } else if (freq < 222500) { /* freq * 16 < 3560000 */
338 multi = 16;
339 reg[5] = 0x42;
340 reg[6] = 0x02;
341 } else if (freq < 296667) { /* freq * 12 < 3560000 */
342 multi = 12;
343 reg[5] = 0x12;
344 reg[6] = 0x00;
345 } else if (freq < 445000) { /* freq * 8 < 3560000 */
346 multi = 8;
347 reg[5] = 0x22;
348 reg[6] = 0x02;
349 } else if (freq < 593334) { /* freq * 6 < 3560000 */
350 multi = 6;
351 reg[5] = 0x0a;
352 reg[6] = 0x00;
353 } else if (freq < 950000) { /* freq * 4 < 3800000 */
354 multi = 4;
355 reg[5] = 0x12;
356 reg[6] = 0x02;
357 } else {
358 multi = 2;
359 reg[5] = 0x0a;
360 reg[6] = 0x02;
361 }
362
363 f_vco = freq * multi;
364
365 if (f_vco >= 3060000) {
366 reg[6] |= 0x08;
367 vco_select = true;
368 }
369
370 if (freq >= 45000) {
371 /* From divided value (XDIV) determined the FA and FP value */
372 xdiv = (unsigned short)(f_vco / xtal_freq_khz_2);
373 if ((f_vco - xdiv * xtal_freq_khz_2) >= (xtal_freq_khz_2 / 2))
374 xdiv++;
375
376 pm = (unsigned char)(xdiv / 8);
377 am = (unsigned char)(xdiv - (8 * pm));
378
379 if (am < 2) {
380 reg[1] = am + 8;
381 reg[2] = pm - 1;
382 } else {
383 reg[1] = am;
384 reg[2] = pm;
385 }
386 } else {
387 /* fix for frequency less than 45 MHz */
388 reg[1] = 0x06;
389 reg[2] = 0x11;
390 }
391
392 /* fix clock out */
393 reg[6] |= 0x20;
394
395 /* From VCO frequency determines the XIN ( fractional part of Delta
396 Sigma PLL) and divided value (XDIV) */
397 xin = (unsigned short)(f_vco - (f_vco / xtal_freq_khz_2) * xtal_freq_khz_2);
398 xin = (xin << 15) / xtal_freq_khz_2;
399 if (xin >= 16384)
400 xin += 32768;
401
402 reg[3] = xin >> 8;
403 reg[4] = xin & 0xff;
404
405 if (delsys == SYS_DVBT) {
406 reg[6] &= 0x3f; /* bits 6 and 7 describe the bandwidth */
407 switch (p->bandwidth_hz) {
408 case 6000000:
409 reg[6] |= 0x80;
410 break;
411 case 7000000:
412 reg[6] |= 0x40;
413 break;
414 case 8000000:
415 default:
416 break;
417 }
418 } else {
419 err("%s: modulation type not supported!", __func__);
420 return -EINVAL;
421 }
422
423 /* modified for Realtek demod */
424 reg[5] |= 0x07;
425
426 for (i = 1; i <= 6; i++) {
427 ret = fc0013_writereg(priv, i, reg[i]);
428 if (ret)
429 goto exit;
430 }
431
432 ret = fc0013_readreg(priv, 0x11, &tmp);
433 if (ret)
434 goto exit;
435 if (multi == 64)
436 ret = fc0013_writereg(priv, 0x11, tmp | 0x04);
437 else
438 ret = fc0013_writereg(priv, 0x11, tmp & 0xfb);
439 if (ret)
440 goto exit;
441
442 /* VCO Calibration */
443 ret = fc0013_writereg(priv, 0x0e, 0x80);
444 if (!ret)
445 ret = fc0013_writereg(priv, 0x0e, 0x00);
446
447 /* VCO Re-Calibration if needed */
448 if (!ret)
449 ret = fc0013_writereg(priv, 0x0e, 0x00);
450
451 if (!ret) {
452 msleep(10);
453 ret = fc0013_readreg(priv, 0x0e, &tmp);
454 }
455 if (ret)
456 goto exit;
457
458 /* vco selection */
459 tmp &= 0x3f;
460
461 if (vco_select) {
462 if (tmp > 0x3c) {
463 reg[6] &= ~0x08;
464 ret = fc0013_writereg(priv, 0x06, reg[6]);
465 if (!ret)
466 ret = fc0013_writereg(priv, 0x0e, 0x80);
467 if (!ret)
468 ret = fc0013_writereg(priv, 0x0e, 0x00);
469 }
470 } else {
471 if (tmp < 0x02) {
472 reg[6] |= 0x08;
473 ret = fc0013_writereg(priv, 0x06, reg[6]);
474 if (!ret)
475 ret = fc0013_writereg(priv, 0x0e, 0x80);
476 if (!ret)
477 ret = fc0013_writereg(priv, 0x0e, 0x00);
478 }
479 }
480
481 priv->frequency = p->frequency;
482 priv->bandwidth = p->bandwidth_hz;
483
484exit:
485 if (fe->ops.i2c_gate_ctrl)
486 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
487 if (ret)
488 warn("%s: failed: %d", __func__, ret);
489 return ret;
490}
491
492static int fc0013_get_frequency(struct dvb_frontend *fe, u32 *frequency)
493{
494 struct fc0013_priv *priv = fe->tuner_priv;
495 *frequency = priv->frequency;
496 return 0;
497}
498
499static int fc0013_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
500{
501 /* always ? */
502 *frequency = 0;
503 return 0;
504}
505
506static int fc0013_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
507{
508 struct fc0013_priv *priv = fe->tuner_priv;
509 *bandwidth = priv->bandwidth;
510 return 0;
511}
512
513#define INPUT_ADC_LEVEL -8
514
515static int fc0013_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
516{
517 struct fc0013_priv *priv = fe->tuner_priv;
518 int ret;
519 unsigned char tmp;
520 int int_temp, lna_gain, int_lna, tot_agc_gain, power;
521 const int fc0013_lna_gain_table[] = {
522 /* low gain */
523 -63, -58, -99, -73,
524 -63, -65, -54, -60,
525 /* middle gain */
526 71, 70, 68, 67,
527 65, 63, 61, 58,
528 /* high gain */
529 197, 191, 188, 186,
530 184, 182, 181, 179,
531 };
532
533 if (fe->ops.i2c_gate_ctrl)
534 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
535
536 ret = fc0013_writereg(priv, 0x13, 0x00);
537 if (ret)
538 goto err;
539
540 ret = fc0013_readreg(priv, 0x13, &tmp);
541 if (ret)
542 goto err;
543 int_temp = tmp;
544
545 ret = fc0013_readreg(priv, 0x14, &tmp);
546 if (ret)
547 goto err;
548 lna_gain = tmp & 0x1f;
549
550 if (fe->ops.i2c_gate_ctrl)
551 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
552
553 if (lna_gain < ARRAY_SIZE(fc0013_lna_gain_table)) {
554 int_lna = fc0013_lna_gain_table[lna_gain];
555 tot_agc_gain = (abs((int_temp >> 5) - 7) - 2 +
556 (int_temp & 0x1f)) * 2;
557 power = INPUT_ADC_LEVEL - tot_agc_gain - int_lna / 10;
558
559 if (power >= 45)
560 *strength = 255; /* 100% */
561 else if (power < -95)
562 *strength = 0;
563 else
564 *strength = (power + 95) * 255 / 140;
565
566 *strength |= *strength << 8;
567 } else {
568 ret = -1;
569 }
570
571 goto exit;
572
573err:
574 if (fe->ops.i2c_gate_ctrl)
575 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
576exit:
577 if (ret)
578 warn("%s: failed: %d", __func__, ret);
579 return ret;
580}
581
582static const struct dvb_tuner_ops fc0013_tuner_ops = {
583 .info = {
584 .name = "Fitipower FC0013",
585
586 .frequency_min = 37000000, /* estimate */
587 .frequency_max = 1680000000, /* CHECK */
588 .frequency_step = 0,
589 },
590
591 .release = fc0013_release,
592
593 .init = fc0013_init,
594 .sleep = fc0013_sleep,
595
596 .set_params = fc0013_set_params,
597
598 .get_frequency = fc0013_get_frequency,
599 .get_if_frequency = fc0013_get_if_frequency,
600 .get_bandwidth = fc0013_get_bandwidth,
601
602 .get_rf_strength = fc0013_get_rf_strength,
603};
604
605struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
606 struct i2c_adapter *i2c, u8 i2c_address, int dual_master,
607 enum fc001x_xtal_freq xtal_freq)
608{
609 struct fc0013_priv *priv = NULL;
610
611 priv = kzalloc(sizeof(struct fc0013_priv), GFP_KERNEL);
612 if (priv == NULL)
613 return NULL;
614
615 priv->i2c = i2c;
616 priv->dual_master = dual_master;
617 priv->addr = i2c_address;
618 priv->xtal_freq = xtal_freq;
619
620 info("Fitipower FC0013 successfully attached.");
621
622 fe->tuner_priv = priv;
623
624 memcpy(&fe->ops.tuner_ops, &fc0013_tuner_ops,
625 sizeof(struct dvb_tuner_ops));
626
627 return fe;
628}
629EXPORT_SYMBOL(fc0013_attach);
630
631MODULE_DESCRIPTION("Fitipower FC0013 silicon tuner driver");
632MODULE_AUTHOR("Hans-Frieder Vogt <hfvogt@gmx.net>");
633MODULE_LICENSE("GPL");
634MODULE_VERSION("0.2");
diff --git a/drivers/media/tuners/fc0013.h b/drivers/media/tuners/fc0013.h
new file mode 100644
index 000000000000..594efd64aeec
--- /dev/null
+++ b/drivers/media/tuners/fc0013.h
@@ -0,0 +1,57 @@
1/*
2 * Fitipower FC0013 tuner driver
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 *
20 */
21
22#ifndef _FC0013_H_
23#define _FC0013_H_
24
25#include "dvb_frontend.h"
26#include "fc001x-common.h"
27
28#if defined(CONFIG_MEDIA_TUNER_FC0013) || \
29 (defined(CONFIG_MEDIA_TUNER_FC0013_MODULE) && defined(MODULE))
30extern struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
31 struct i2c_adapter *i2c,
32 u8 i2c_address, int dual_master,
33 enum fc001x_xtal_freq xtal_freq);
34extern int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val);
35extern int fc0013_rc_cal_reset(struct dvb_frontend *fe);
36#else
37static inline struct dvb_frontend *fc0013_attach(struct dvb_frontend *fe,
38 struct i2c_adapter *i2c,
39 u8 i2c_address, int dual_master,
40 enum fc001x_xtal_freq xtal_freq)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
43 return NULL;
44}
45
46static inline int fc0013_rc_cal_add(struct dvb_frontend *fe, int rc_val)
47{
48 return 0;
49}
50
51static inline int fc0013_rc_cal_reset(struct dvb_frontend *fe)
52{
53 return 0;
54}
55#endif
56
57#endif
diff --git a/drivers/media/tuners/fc001x-common.h b/drivers/media/tuners/fc001x-common.h
new file mode 100644
index 000000000000..718818156934
--- /dev/null
+++ b/drivers/media/tuners/fc001x-common.h
@@ -0,0 +1,39 @@
1/*
2 * Fitipower FC0012 & FC0013 tuner driver - common defines
3 *
4 * Copyright (C) 2012 Hans-Frieder Vogt <hfvogt@gmx.net>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef _FC001X_COMMON_H_
22#define _FC001X_COMMON_H_
23
24enum fc001x_xtal_freq {
25 FC_XTAL_27_MHZ, /* 27000000 */
26 FC_XTAL_28_8_MHZ, /* 28800000 */
27 FC_XTAL_36_MHZ, /* 36000000 */
28};
29
30/*
31 * enum fc001x_fe_callback_commands - Frontend callbacks
32 *
33 * @FC_FE_CALLBACK_VHF_ENABLE: enable VHF or UHF
34 */
35enum fc001x_fe_callback_commands {
36 FC_FE_CALLBACK_VHF_ENABLE,
37};
38
39#endif
diff --git a/drivers/media/tuners/max2165.c b/drivers/media/tuners/max2165.c
new file mode 100644
index 000000000000..ba84936aafd6
--- /dev/null
+++ b/drivers/media/tuners/max2165.c
@@ -0,0 +1,433 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/videodev2.h>
25#include <linux/delay.h>
26#include <linux/dvb/frontend.h>
27#include <linux/i2c.h>
28#include <linux/slab.h>
29
30#include "dvb_frontend.h"
31
32#include "max2165.h"
33#include "max2165_priv.h"
34#include "tuner-i2c.h"
35
36#define dprintk(args...) \
37 do { \
38 if (debug) \
39 printk(KERN_DEBUG "max2165: " args); \
40 } while (0)
41
42static int debug;
43module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
45
46static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
47{
48 int ret;
49 u8 buf[] = { reg, data };
50 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
51
52 msg.addr = priv->config->i2c_address;
53
54 if (debug >= 2)
55 dprintk("%s: reg=0x%02X, data=0x%02X\n", __func__, reg, data);
56
57 ret = i2c_transfer(priv->i2c, &msg, 1);
58
59 if (ret != 1)
60 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
61 __func__, reg, data, ret);
62
63 return (ret != 1) ? -EIO : 0;
64}
65
66static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
67{
68 int ret;
69 u8 dev_addr = priv->config->i2c_address;
70
71 u8 b0[] = { reg };
72 u8 b1[] = { 0 };
73 struct i2c_msg msg[] = {
74 { .addr = dev_addr, .flags = 0, .buf = b0, .len = 1 },
75 { .addr = dev_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 },
76 };
77
78 ret = i2c_transfer(priv->i2c, msg, 2);
79 if (ret != 2) {
80 dprintk("%s: error reg=0x%x, ret=%i\n", __func__, reg, ret);
81 return -EIO;
82 }
83
84 *p_data = b1[0];
85 if (debug >= 2)
86 dprintk("%s: reg=0x%02X, data=0x%02X\n",
87 __func__, reg, b1[0]);
88 return 0;
89}
90
91static int max2165_mask_write_reg(struct max2165_priv *priv, u8 reg,
92 u8 mask, u8 data)
93{
94 int ret;
95 u8 v;
96
97 data &= mask;
98 ret = max2165_read_reg(priv, reg, &v);
99 if (ret != 0)
100 return ret;
101 v &= ~mask;
102 v |= data;
103 ret = max2165_write_reg(priv, reg, v);
104
105 return ret;
106}
107
108static int max2165_read_rom_table(struct max2165_priv *priv)
109{
110 u8 dat[3];
111 int i;
112
113 for (i = 0; i < 3; i++) {
114 max2165_write_reg(priv, REG_ROM_TABLE_ADDR, i + 1);
115 max2165_read_reg(priv, REG_ROM_TABLE_DATA, &dat[i]);
116 }
117
118 priv->tf_ntch_low_cfg = dat[0] >> 4;
119 priv->tf_ntch_hi_cfg = dat[0] & 0x0F;
120 priv->tf_balun_low_ref = dat[1] & 0x0F;
121 priv->tf_balun_hi_ref = dat[1] >> 4;
122 priv->bb_filter_7mhz_cfg = dat[2] & 0x0F;
123 priv->bb_filter_8mhz_cfg = dat[2] >> 4;
124
125 dprintk("tf_ntch_low_cfg = 0x%X\n", priv->tf_ntch_low_cfg);
126 dprintk("tf_ntch_hi_cfg = 0x%X\n", priv->tf_ntch_hi_cfg);
127 dprintk("tf_balun_low_ref = 0x%X\n", priv->tf_balun_low_ref);
128 dprintk("tf_balun_hi_ref = 0x%X\n", priv->tf_balun_hi_ref);
129 dprintk("bb_filter_7mhz_cfg = 0x%X\n", priv->bb_filter_7mhz_cfg);
130 dprintk("bb_filter_8mhz_cfg = 0x%X\n", priv->bb_filter_8mhz_cfg);
131
132 return 0;
133}
134
135static int max2165_set_osc(struct max2165_priv *priv, u8 osc /*MHz*/)
136{
137 u8 v;
138
139 v = (osc / 2);
140 if (v == 2)
141 v = 0x7;
142 else
143 v -= 8;
144
145 max2165_mask_write_reg(priv, REG_PLL_CFG, 0x07, v);
146
147 return 0;
148}
149
150static int max2165_set_bandwidth(struct max2165_priv *priv, u32 bw)
151{
152 u8 val;
153
154 if (bw == 8000000)
155 val = priv->bb_filter_8mhz_cfg;
156 else
157 val = priv->bb_filter_7mhz_cfg;
158
159 max2165_mask_write_reg(priv, REG_BASEBAND_CTRL, 0xF0, val << 4);
160
161 return 0;
162}
163
164int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
165{
166 u32 remainder;
167 u32 q, f = 0;
168 int i;
169
170 if (0 == divisor)
171 return -EINVAL;
172
173 q = dividend / divisor;
174 remainder = dividend - q * divisor;
175
176 for (i = 0; i < 31; i++) {
177 remainder <<= 1;
178 if (remainder >= divisor) {
179 f += 1;
180 remainder -= divisor;
181 }
182 f <<= 1;
183 }
184
185 *quotient = q;
186 *fraction = f;
187
188 return 0;
189}
190
191static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
192{
193 u8 tf;
194 u8 tf_ntch;
195 u32 t;
196 u32 quotient, fraction;
197 int ret;
198
199 /* Set PLL divider according to RF frequency */
200 ret = fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
201 &quotient, &fraction);
202 if (ret != 0)
203 return ret;
204
205 /* 20-bit fraction */
206 fraction >>= 12;
207
208 max2165_write_reg(priv, REG_NDIV_INT, quotient);
209 max2165_mask_write_reg(priv, REG_NDIV_FRAC2, 0x0F, fraction >> 16);
210 max2165_write_reg(priv, REG_NDIV_FRAC1, fraction >> 8);
211 max2165_write_reg(priv, REG_NDIV_FRAC0, fraction);
212
213 /* Norch Filter */
214 tf_ntch = (freq < 725000000) ?
215 priv->tf_ntch_low_cfg : priv->tf_ntch_hi_cfg;
216
217 /* Tracking filter balun */
218 t = priv->tf_balun_low_ref;
219 t += (priv->tf_balun_hi_ref - priv->tf_balun_low_ref)
220 * (freq / 1000 - 470000) / (780000 - 470000);
221
222 tf = t;
223 dprintk("tf = %X\n", tf);
224 tf |= tf_ntch << 4;
225
226 max2165_write_reg(priv, REG_TRACK_FILTER, tf);
227
228 return 0;
229}
230
231static void max2165_debug_status(struct max2165_priv *priv)
232{
233 u8 status, autotune;
234 u8 auto_vco_success, auto_vco_active;
235 u8 pll_locked;
236 u8 dc_offset_low, dc_offset_hi;
237 u8 signal_lv_over_threshold;
238 u8 vco, vco_sub_band, adc;
239
240 max2165_read_reg(priv, REG_STATUS, &status);
241 max2165_read_reg(priv, REG_AUTOTUNE, &autotune);
242
243 auto_vco_success = (status >> 6) & 0x01;
244 auto_vco_active = (status >> 5) & 0x01;
245 pll_locked = (status >> 4) & 0x01;
246 dc_offset_low = (status >> 3) & 0x01;
247 dc_offset_hi = (status >> 2) & 0x01;
248 signal_lv_over_threshold = status & 0x01;
249
250 vco = autotune >> 6;
251 vco_sub_band = (autotune >> 3) & 0x7;
252 adc = autotune & 0x7;
253
254 dprintk("auto VCO active: %d, auto VCO success: %d\n",
255 auto_vco_active, auto_vco_success);
256 dprintk("PLL locked: %d\n", pll_locked);
257 dprintk("DC offset low: %d, DC offset high: %d\n",
258 dc_offset_low, dc_offset_hi);
259 dprintk("Signal lvl over threshold: %d\n", signal_lv_over_threshold);
260 dprintk("VCO: %d, VCO Sub-band: %d, ADC: %d\n", vco, vco_sub_band, adc);
261}
262
263static int max2165_set_params(struct dvb_frontend *fe)
264{
265 struct max2165_priv *priv = fe->tuner_priv;
266 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
267 int ret;
268
269 switch (c->bandwidth_hz) {
270 case 7000000:
271 case 8000000:
272 priv->frequency = c->frequency;
273 break;
274 default:
275 printk(KERN_INFO "MAX2165: bandwidth %d Hz not supported.\n",
276 c->bandwidth_hz);
277 return -EINVAL;
278 }
279
280 dprintk("%s() frequency=%d\n", __func__, c->frequency);
281
282 if (fe->ops.i2c_gate_ctrl)
283 fe->ops.i2c_gate_ctrl(fe, 1);
284 max2165_set_bandwidth(priv, c->bandwidth_hz);
285 ret = max2165_set_rf(priv, priv->frequency);
286 mdelay(50);
287 max2165_debug_status(priv);
288 if (fe->ops.i2c_gate_ctrl)
289 fe->ops.i2c_gate_ctrl(fe, 0);
290
291 if (ret != 0)
292 return -EREMOTEIO;
293
294 return 0;
295}
296
297static int max2165_get_frequency(struct dvb_frontend *fe, u32 *freq)
298{
299 struct max2165_priv *priv = fe->tuner_priv;
300 dprintk("%s()\n", __func__);
301 *freq = priv->frequency;
302 return 0;
303}
304
305static int max2165_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
306{
307 struct max2165_priv *priv = fe->tuner_priv;
308 dprintk("%s()\n", __func__);
309
310 *bw = priv->bandwidth;
311 return 0;
312}
313
314static int max2165_get_status(struct dvb_frontend *fe, u32 *status)
315{
316 struct max2165_priv *priv = fe->tuner_priv;
317 u16 lock_status = 0;
318
319 dprintk("%s()\n", __func__);
320
321 if (fe->ops.i2c_gate_ctrl)
322 fe->ops.i2c_gate_ctrl(fe, 1);
323
324 max2165_debug_status(priv);
325 *status = lock_status;
326
327 if (fe->ops.i2c_gate_ctrl)
328 fe->ops.i2c_gate_ctrl(fe, 0);
329
330 return 0;
331}
332
333static int max2165_sleep(struct dvb_frontend *fe)
334{
335 dprintk("%s()\n", __func__);
336 return 0;
337}
338
339static int max2165_init(struct dvb_frontend *fe)
340{
341 struct max2165_priv *priv = fe->tuner_priv;
342 dprintk("%s()\n", __func__);
343
344 if (fe->ops.i2c_gate_ctrl)
345 fe->ops.i2c_gate_ctrl(fe, 1);
346
347 /* Setup initial values */
348 /* Fractional Mode on */
349 max2165_write_reg(priv, REG_NDIV_FRAC2, 0x18);
350 /* LNA on */
351 max2165_write_reg(priv, REG_LNA, 0x01);
352 max2165_write_reg(priv, REG_PLL_CFG, 0x7A);
353 max2165_write_reg(priv, REG_TEST, 0x08);
354 max2165_write_reg(priv, REG_SHUTDOWN, 0x40);
355 max2165_write_reg(priv, REG_VCO_CTRL, 0x84);
356 max2165_write_reg(priv, REG_BASEBAND_CTRL, 0xC3);
357 max2165_write_reg(priv, REG_DC_OFFSET_CTRL, 0x75);
358 max2165_write_reg(priv, REG_DC_OFFSET_DAC, 0x00);
359 max2165_write_reg(priv, REG_ROM_TABLE_ADDR, 0x00);
360
361 max2165_set_osc(priv, priv->config->osc_clk);
362
363 max2165_read_rom_table(priv);
364
365 max2165_set_bandwidth(priv, 8000000);
366
367 if (fe->ops.i2c_gate_ctrl)
368 fe->ops.i2c_gate_ctrl(fe, 0);
369
370 return 0;
371}
372
373static int max2165_release(struct dvb_frontend *fe)
374{
375 struct max2165_priv *priv = fe->tuner_priv;
376 dprintk("%s()\n", __func__);
377
378 kfree(priv);
379 fe->tuner_priv = NULL;
380
381 return 0;
382}
383
384static const struct dvb_tuner_ops max2165_tuner_ops = {
385 .info = {
386 .name = "Maxim MAX2165",
387 .frequency_min = 470000000,
388 .frequency_max = 780000000,
389 .frequency_step = 50000,
390 },
391
392 .release = max2165_release,
393 .init = max2165_init,
394 .sleep = max2165_sleep,
395
396 .set_params = max2165_set_params,
397 .set_analog_params = NULL,
398 .get_frequency = max2165_get_frequency,
399 .get_bandwidth = max2165_get_bandwidth,
400 .get_status = max2165_get_status
401};
402
403struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
404 struct i2c_adapter *i2c,
405 struct max2165_config *cfg)
406{
407 struct max2165_priv *priv = NULL;
408
409 dprintk("%s(%d-%04x)\n", __func__,
410 i2c ? i2c_adapter_id(i2c) : -1,
411 cfg ? cfg->i2c_address : -1);
412
413 priv = kzalloc(sizeof(struct max2165_priv), GFP_KERNEL);
414 if (priv == NULL)
415 return NULL;
416
417 memcpy(&fe->ops.tuner_ops, &max2165_tuner_ops,
418 sizeof(struct dvb_tuner_ops));
419
420 priv->config = cfg;
421 priv->i2c = i2c;
422 fe->tuner_priv = priv;
423
424 max2165_init(fe);
425 max2165_debug_status(priv);
426
427 return fe;
428}
429EXPORT_SYMBOL(max2165_attach);
430
431MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
432MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver");
433MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/max2165.h b/drivers/media/tuners/max2165.h
new file mode 100644
index 000000000000..c063c36a93d3
--- /dev/null
+++ b/drivers/media/tuners/max2165.h
@@ -0,0 +1,48 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __MAX2165_H__
23#define __MAX2165_H__
24
25struct dvb_frontend;
26struct i2c_adapter;
27
28struct max2165_config {
29 u8 i2c_address;
30 u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */
31};
32
33#if defined(CONFIG_MEDIA_TUNER_MAX2165) || \
34 (defined(CONFIG_MEDIA_TUNER_MAX2165_MODULE) && defined(MODULE))
35extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
36 struct i2c_adapter *i2c,
37 struct max2165_config *cfg);
38#else
39static inline struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
40 struct i2c_adapter *i2c,
41 struct max2165_config *cfg)
42{
43 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
44 return NULL;
45}
46#endif
47
48#endif
diff --git a/drivers/media/tuners/max2165_priv.h b/drivers/media/tuners/max2165_priv.h
new file mode 100644
index 000000000000..91bbe021a08d
--- /dev/null
+++ b/drivers/media/tuners/max2165_priv.h
@@ -0,0 +1,60 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __MAX2165_PRIV_H__
23#define __MAX2165_PRIV_H__
24
25#define REG_NDIV_INT 0x00
26#define REG_NDIV_FRAC2 0x01
27#define REG_NDIV_FRAC1 0x02
28#define REG_NDIV_FRAC0 0x03
29#define REG_TRACK_FILTER 0x04
30#define REG_LNA 0x05
31#define REG_PLL_CFG 0x06
32#define REG_TEST 0x07
33#define REG_SHUTDOWN 0x08
34#define REG_VCO_CTRL 0x09
35#define REG_BASEBAND_CTRL 0x0A
36#define REG_DC_OFFSET_CTRL 0x0B
37#define REG_DC_OFFSET_DAC 0x0C
38#define REG_ROM_TABLE_ADDR 0x0D
39
40/* Read Only Registers */
41#define REG_ROM_TABLE_DATA 0x10
42#define REG_STATUS 0x11
43#define REG_AUTOTUNE 0x12
44
45struct max2165_priv {
46 struct max2165_config *config;
47 struct i2c_adapter *i2c;
48
49 u32 frequency;
50 u32 bandwidth;
51
52 u8 tf_ntch_low_cfg;
53 u8 tf_ntch_hi_cfg;
54 u8 tf_balun_low_ref;
55 u8 tf_balun_hi_ref;
56 u8 bb_filter_7mhz_cfg;
57 u8 bb_filter_8mhz_cfg;
58};
59
60#endif
diff --git a/drivers/media/tuners/mc44s803.c b/drivers/media/tuners/mc44s803.c
new file mode 100644
index 000000000000..5ddce7e326f7
--- /dev/null
+++ b/drivers/media/tuners/mc44s803.c
@@ -0,0 +1,372 @@
1/*
2 * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
3 *
4 * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/dvb/frontend.h>
25#include <linux/i2c.h>
26#include <linux/slab.h>
27
28#include "dvb_frontend.h"
29
30#include "mc44s803.h"
31#include "mc44s803_priv.h"
32
33#define mc_printk(level, format, arg...) \
34 printk(level "mc44s803: " format , ## arg)
35
36/* Writes a single register */
37static int mc44s803_writereg(struct mc44s803_priv *priv, u32 val)
38{
39 u8 buf[3];
40 struct i2c_msg msg = {
41 .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 3
42 };
43
44 buf[0] = (val & 0xff0000) >> 16;
45 buf[1] = (val & 0xff00) >> 8;
46 buf[2] = (val & 0xff);
47
48 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
49 mc_printk(KERN_WARNING, "I2C write failed\n");
50 return -EREMOTEIO;
51 }
52 return 0;
53}
54
55/* Reads a single register */
56static int mc44s803_readreg(struct mc44s803_priv *priv, u8 reg, u32 *val)
57{
58 u32 wval;
59 u8 buf[3];
60 int ret;
61 struct i2c_msg msg[] = {
62 { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
63 .buf = buf, .len = 3 },
64 };
65
66 wval = MC44S803_REG_SM(MC44S803_REG_DATAREG, MC44S803_ADDR) |
67 MC44S803_REG_SM(reg, MC44S803_D);
68
69 ret = mc44s803_writereg(priv, wval);
70 if (ret)
71 return ret;
72
73 if (i2c_transfer(priv->i2c, msg, 1) != 1) {
74 mc_printk(KERN_WARNING, "I2C read failed\n");
75 return -EREMOTEIO;
76 }
77
78 *val = (buf[0] << 16) | (buf[1] << 8) | buf[2];
79
80 return 0;
81}
82
83static int mc44s803_release(struct dvb_frontend *fe)
84{
85 struct mc44s803_priv *priv = fe->tuner_priv;
86
87 fe->tuner_priv = NULL;
88 kfree(priv);
89
90 return 0;
91}
92
93static int mc44s803_init(struct dvb_frontend *fe)
94{
95 struct mc44s803_priv *priv = fe->tuner_priv;
96 u32 val;
97 int err;
98
99 if (fe->ops.i2c_gate_ctrl)
100 fe->ops.i2c_gate_ctrl(fe, 1);
101
102/* Reset chip */
103 val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR) |
104 MC44S803_REG_SM(1, MC44S803_RS);
105
106 err = mc44s803_writereg(priv, val);
107 if (err)
108 goto exit;
109
110 val = MC44S803_REG_SM(MC44S803_REG_RESET, MC44S803_ADDR);
111
112 err = mc44s803_writereg(priv, val);
113 if (err)
114 goto exit;
115
116/* Power Up and Start Osc */
117
118 val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
119 MC44S803_REG_SM(0xC0, MC44S803_REFOSC) |
120 MC44S803_REG_SM(1, MC44S803_OSCSEL);
121
122 err = mc44s803_writereg(priv, val);
123 if (err)
124 goto exit;
125
126 val = MC44S803_REG_SM(MC44S803_REG_POWER, MC44S803_ADDR) |
127 MC44S803_REG_SM(0x200, MC44S803_POWER);
128
129 err = mc44s803_writereg(priv, val);
130 if (err)
131 goto exit;
132
133 msleep(10);
134
135 val = MC44S803_REG_SM(MC44S803_REG_REFOSC, MC44S803_ADDR) |
136 MC44S803_REG_SM(0x40, MC44S803_REFOSC) |
137 MC44S803_REG_SM(1, MC44S803_OSCSEL);
138
139 err = mc44s803_writereg(priv, val);
140 if (err)
141 goto exit;
142
143 msleep(20);
144
145/* Setup Mixer */
146
147 val = MC44S803_REG_SM(MC44S803_REG_MIXER, MC44S803_ADDR) |
148 MC44S803_REG_SM(1, MC44S803_TRI_STATE) |
149 MC44S803_REG_SM(0x7F, MC44S803_MIXER_RES);
150
151 err = mc44s803_writereg(priv, val);
152 if (err)
153 goto exit;
154
155/* Setup Cirquit Adjust */
156
157 val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
158 MC44S803_REG_SM(1, MC44S803_G1) |
159 MC44S803_REG_SM(1, MC44S803_G3) |
160 MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
161 MC44S803_REG_SM(1, MC44S803_G6) |
162 MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
163 MC44S803_REG_SM(0x3, MC44S803_LP) |
164 MC44S803_REG_SM(1, MC44S803_CLRF) |
165 MC44S803_REG_SM(1, MC44S803_CLIF);
166
167 err = mc44s803_writereg(priv, val);
168 if (err)
169 goto exit;
170
171 val = MC44S803_REG_SM(MC44S803_REG_CIRCADJ, MC44S803_ADDR) |
172 MC44S803_REG_SM(1, MC44S803_G1) |
173 MC44S803_REG_SM(1, MC44S803_G3) |
174 MC44S803_REG_SM(0x3, MC44S803_CIRCADJ_RES) |
175 MC44S803_REG_SM(1, MC44S803_G6) |
176 MC44S803_REG_SM(priv->cfg->dig_out, MC44S803_S1) |
177 MC44S803_REG_SM(0x3, MC44S803_LP);
178
179 err = mc44s803_writereg(priv, val);
180 if (err)
181 goto exit;
182
183/* Setup Digtune */
184
185 val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
186 MC44S803_REG_SM(3, MC44S803_XOD);
187
188 err = mc44s803_writereg(priv, val);
189 if (err)
190 goto exit;
191
192/* Setup AGC */
193
194 val = MC44S803_REG_SM(MC44S803_REG_LNAAGC, MC44S803_ADDR) |
195 MC44S803_REG_SM(1, MC44S803_AT1) |
196 MC44S803_REG_SM(1, MC44S803_AT2) |
197 MC44S803_REG_SM(1, MC44S803_AGC_AN_DIG) |
198 MC44S803_REG_SM(1, MC44S803_AGC_READ_EN) |
199 MC44S803_REG_SM(1, MC44S803_LNA0);
200
201 err = mc44s803_writereg(priv, val);
202 if (err)
203 goto exit;
204
205 if (fe->ops.i2c_gate_ctrl)
206 fe->ops.i2c_gate_ctrl(fe, 0);
207 return 0;
208
209exit:
210 if (fe->ops.i2c_gate_ctrl)
211 fe->ops.i2c_gate_ctrl(fe, 0);
212
213 mc_printk(KERN_WARNING, "I/O Error\n");
214 return err;
215}
216
217static int mc44s803_set_params(struct dvb_frontend *fe)
218{
219 struct mc44s803_priv *priv = fe->tuner_priv;
220 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
221 u32 r1, r2, n1, n2, lo1, lo2, freq, val;
222 int err;
223
224 priv->frequency = c->frequency;
225
226 r1 = MC44S803_OSC / 1000000;
227 r2 = MC44S803_OSC / 100000;
228
229 n1 = (c->frequency + MC44S803_IF1 + 500000) / 1000000;
230 freq = MC44S803_OSC / r1 * n1;
231 lo1 = ((60 * n1) + (r1 / 2)) / r1;
232 freq = freq - c->frequency;
233
234 n2 = (freq - MC44S803_IF2 + 50000) / 100000;
235 lo2 = ((60 * n2) + (r2 / 2)) / r2;
236
237 if (fe->ops.i2c_gate_ctrl)
238 fe->ops.i2c_gate_ctrl(fe, 1);
239
240 val = MC44S803_REG_SM(MC44S803_REG_REFDIV, MC44S803_ADDR) |
241 MC44S803_REG_SM(r1-1, MC44S803_R1) |
242 MC44S803_REG_SM(r2-1, MC44S803_R2) |
243 MC44S803_REG_SM(1, MC44S803_REFBUF_EN);
244
245 err = mc44s803_writereg(priv, val);
246 if (err)
247 goto exit;
248
249 val = MC44S803_REG_SM(MC44S803_REG_LO1, MC44S803_ADDR) |
250 MC44S803_REG_SM(n1-2, MC44S803_LO1);
251
252 err = mc44s803_writereg(priv, val);
253 if (err)
254 goto exit;
255
256 val = MC44S803_REG_SM(MC44S803_REG_LO2, MC44S803_ADDR) |
257 MC44S803_REG_SM(n2-2, MC44S803_LO2);
258
259 err = mc44s803_writereg(priv, val);
260 if (err)
261 goto exit;
262
263 val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
264 MC44S803_REG_SM(1, MC44S803_DA) |
265 MC44S803_REG_SM(lo1, MC44S803_LO_REF) |
266 MC44S803_REG_SM(1, MC44S803_AT);
267
268 err = mc44s803_writereg(priv, val);
269 if (err)
270 goto exit;
271
272 val = MC44S803_REG_SM(MC44S803_REG_DIGTUNE, MC44S803_ADDR) |
273 MC44S803_REG_SM(2, MC44S803_DA) |
274 MC44S803_REG_SM(lo2, MC44S803_LO_REF) |
275 MC44S803_REG_SM(1, MC44S803_AT);
276
277 err = mc44s803_writereg(priv, val);
278 if (err)
279 goto exit;
280
281 if (fe->ops.i2c_gate_ctrl)
282 fe->ops.i2c_gate_ctrl(fe, 0);
283
284 return 0;
285
286exit:
287 if (fe->ops.i2c_gate_ctrl)
288 fe->ops.i2c_gate_ctrl(fe, 0);
289
290 mc_printk(KERN_WARNING, "I/O Error\n");
291 return err;
292}
293
294static int mc44s803_get_frequency(struct dvb_frontend *fe, u32 *frequency)
295{
296 struct mc44s803_priv *priv = fe->tuner_priv;
297 *frequency = priv->frequency;
298 return 0;
299}
300
301static const struct dvb_tuner_ops mc44s803_tuner_ops = {
302 .info = {
303 .name = "Freescale MC44S803",
304 .frequency_min = 48000000,
305 .frequency_max = 1000000000,
306 .frequency_step = 100000,
307 },
308
309 .release = mc44s803_release,
310 .init = mc44s803_init,
311 .set_params = mc44s803_set_params,
312 .get_frequency = mc44s803_get_frequency
313};
314
315/* This functions tries to identify a MC44S803 tuner by reading the ID
316 register. This is hasty. */
317struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
318 struct i2c_adapter *i2c, struct mc44s803_config *cfg)
319{
320 struct mc44s803_priv *priv;
321 u32 reg;
322 u8 id;
323 int ret;
324
325 reg = 0;
326
327 priv = kzalloc(sizeof(struct mc44s803_priv), GFP_KERNEL);
328 if (priv == NULL)
329 return NULL;
330
331 priv->cfg = cfg;
332 priv->i2c = i2c;
333 priv->fe = fe;
334
335 if (fe->ops.i2c_gate_ctrl)
336 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
337
338 ret = mc44s803_readreg(priv, MC44S803_REG_ID, &reg);
339 if (ret)
340 goto error;
341
342 id = MC44S803_REG_MS(reg, MC44S803_ID);
343
344 if (id != 0x14) {
345 mc_printk(KERN_ERR, "unsupported ID "
346 "(%x should be 0x14)\n", id);
347 goto error;
348 }
349
350 mc_printk(KERN_INFO, "successfully identified (ID = %x)\n", id);
351 memcpy(&fe->ops.tuner_ops, &mc44s803_tuner_ops,
352 sizeof(struct dvb_tuner_ops));
353
354 fe->tuner_priv = priv;
355
356 if (fe->ops.i2c_gate_ctrl)
357 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
358
359 return fe;
360
361error:
362 if (fe->ops.i2c_gate_ctrl)
363 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
364
365 kfree(priv);
366 return NULL;
367}
368EXPORT_SYMBOL(mc44s803_attach);
369
370MODULE_AUTHOR("Jochen Friedrich");
371MODULE_DESCRIPTION("Freescale MC44S803 silicon tuner driver");
372MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/mc44s803.h b/drivers/media/tuners/mc44s803.h
new file mode 100644
index 000000000000..34f3892d3f6d
--- /dev/null
+++ b/drivers/media/tuners/mc44s803.h
@@ -0,0 +1,46 @@
1/*
2 * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
3 *
4 * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef MC44S803_H
23#define MC44S803_H
24
25struct dvb_frontend;
26struct i2c_adapter;
27
28struct mc44s803_config {
29 u8 i2c_address;
30 u8 dig_out;
31};
32
33#if defined(CONFIG_MEDIA_TUNER_MC44S803) || \
34 (defined(CONFIG_MEDIA_TUNER_MC44S803_MODULE) && defined(MODULE))
35extern struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
36 struct i2c_adapter *i2c, struct mc44s803_config *cfg);
37#else
38static inline struct dvb_frontend *mc44s803_attach(struct dvb_frontend *fe,
39 struct i2c_adapter *i2c, struct mc44s803_config *cfg)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44#endif /* CONFIG_MEDIA_TUNER_MC44S803 */
45
46#endif
diff --git a/drivers/media/tuners/mc44s803_priv.h b/drivers/media/tuners/mc44s803_priv.h
new file mode 100644
index 000000000000..14a92780906d
--- /dev/null
+++ b/drivers/media/tuners/mc44s803_priv.h
@@ -0,0 +1,208 @@
1/*
2 * Driver for Freescale MC44S803 Low Power CMOS Broadband Tuner
3 *
4 * Copyright (c) 2009 Jochen Friedrich <jochen@scram.de>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef MC44S803_PRIV_H
23#define MC44S803_PRIV_H
24
25/* This driver is based on the information available in the datasheet
26 http://www.freescale.com/files/rf_if/doc/data_sheet/MC44S803.pdf
27
28 SPI or I2C Address : 0xc0-0xc6
29
30 Reg.No | Function
31 -------------------------------------------
32 00 | Power Down
33 01 | Reference Oszillator
34 02 | Reference Dividers
35 03 | Mixer and Reference Buffer
36 04 | Reset/Serial Out
37 05 | LO 1
38 06 | LO 2
39 07 | Circuit Adjust
40 08 | Test
41 09 | Digital Tune
42 0A | LNA AGC
43 0B | Data Register Address
44 0C | Regulator Test
45 0D | VCO Test
46 0E | LNA Gain/Input Power
47 0F | ID Bits
48
49*/
50
51#define MC44S803_OSC 26000000 /* 26 MHz */
52#define MC44S803_IF1 1086000000 /* 1086 MHz */
53#define MC44S803_IF2 36125000 /* 36.125 MHz */
54
55#define MC44S803_REG_POWER 0
56#define MC44S803_REG_REFOSC 1
57#define MC44S803_REG_REFDIV 2
58#define MC44S803_REG_MIXER 3
59#define MC44S803_REG_RESET 4
60#define MC44S803_REG_LO1 5
61#define MC44S803_REG_LO2 6
62#define MC44S803_REG_CIRCADJ 7
63#define MC44S803_REG_TEST 8
64#define MC44S803_REG_DIGTUNE 9
65#define MC44S803_REG_LNAAGC 0x0A
66#define MC44S803_REG_DATAREG 0x0B
67#define MC44S803_REG_REGTEST 0x0C
68#define MC44S803_REG_VCOTEST 0x0D
69#define MC44S803_REG_LNAGAIN 0x0E
70#define MC44S803_REG_ID 0x0F
71
72/* Register definitions */
73#define MC44S803_ADDR 0x0F
74#define MC44S803_ADDR_S 0
75/* REG_POWER */
76#define MC44S803_POWER 0xFFFFF0
77#define MC44S803_POWER_S 4
78/* REG_REFOSC */
79#define MC44S803_REFOSC 0x1FF0
80#define MC44S803_REFOSC_S 4
81#define MC44S803_OSCSEL 0x2000
82#define MC44S803_OSCSEL_S 13
83/* REG_REFDIV */
84#define MC44S803_R2 0x1FF0
85#define MC44S803_R2_S 4
86#define MC44S803_REFBUF_EN 0x2000
87#define MC44S803_REFBUF_EN_S 13
88#define MC44S803_R1 0x7C000
89#define MC44S803_R1_S 14
90/* REG_MIXER */
91#define MC44S803_R3 0x70
92#define MC44S803_R3_S 4
93#define MC44S803_MUX3 0x80
94#define MC44S803_MUX3_S 7
95#define MC44S803_MUX4 0x100
96#define MC44S803_MUX4_S 8
97#define MC44S803_OSC_SCR 0x200
98#define MC44S803_OSC_SCR_S 9
99#define MC44S803_TRI_STATE 0x400
100#define MC44S803_TRI_STATE_S 10
101#define MC44S803_BUF_GAIN 0x800
102#define MC44S803_BUF_GAIN_S 11
103#define MC44S803_BUF_IO 0x1000
104#define MC44S803_BUF_IO_S 12
105#define MC44S803_MIXER_RES 0xFE000
106#define MC44S803_MIXER_RES_S 13
107/* REG_RESET */
108#define MC44S803_RS 0x10
109#define MC44S803_RS_S 4
110#define MC44S803_SO 0x20
111#define MC44S803_SO_S 5
112/* REG_LO1 */
113#define MC44S803_LO1 0xFFF0
114#define MC44S803_LO1_S 4
115/* REG_LO2 */
116#define MC44S803_LO2 0x7FFF0
117#define MC44S803_LO2_S 4
118/* REG_CIRCADJ */
119#define MC44S803_G1 0x20
120#define MC44S803_G1_S 5
121#define MC44S803_G3 0x80
122#define MC44S803_G3_S 7
123#define MC44S803_CIRCADJ_RES 0x300
124#define MC44S803_CIRCADJ_RES_S 8
125#define MC44S803_G6 0x400
126#define MC44S803_G6_S 10
127#define MC44S803_G7 0x800
128#define MC44S803_G7_S 11
129#define MC44S803_S1 0x1000
130#define MC44S803_S1_S 12
131#define MC44S803_LP 0x7E000
132#define MC44S803_LP_S 13
133#define MC44S803_CLRF 0x80000
134#define MC44S803_CLRF_S 19
135#define MC44S803_CLIF 0x100000
136#define MC44S803_CLIF_S 20
137/* REG_TEST */
138/* REG_DIGTUNE */
139#define MC44S803_DA 0xF0
140#define MC44S803_DA_S 4
141#define MC44S803_XOD 0x300
142#define MC44S803_XOD_S 8
143#define MC44S803_RST 0x10000
144#define MC44S803_RST_S 16
145#define MC44S803_LO_REF 0x1FFF00
146#define MC44S803_LO_REF_S 8
147#define MC44S803_AT 0x200000
148#define MC44S803_AT_S 21
149#define MC44S803_MT 0x400000
150#define MC44S803_MT_S 22
151/* REG_LNAAGC */
152#define MC44S803_G 0x3F0
153#define MC44S803_G_S 4
154#define MC44S803_AT1 0x400
155#define MC44S803_AT1_S 10
156#define MC44S803_AT2 0x800
157#define MC44S803_AT2_S 11
158#define MC44S803_HL_GR_EN 0x8000
159#define MC44S803_HL_GR_EN_S 15
160#define MC44S803_AGC_AN_DIG 0x10000
161#define MC44S803_AGC_AN_DIG_S 16
162#define MC44S803_ATTEN_EN 0x20000
163#define MC44S803_ATTEN_EN_S 17
164#define MC44S803_AGC_READ_EN 0x40000
165#define MC44S803_AGC_READ_EN_S 18
166#define MC44S803_LNA0 0x80000
167#define MC44S803_LNA0_S 19
168#define MC44S803_AGC_SEL 0x100000
169#define MC44S803_AGC_SEL_S 20
170#define MC44S803_AT0 0x200000
171#define MC44S803_AT0_S 21
172#define MC44S803_B 0xC00000
173#define MC44S803_B_S 22
174/* REG_DATAREG */
175#define MC44S803_D 0xF0
176#define MC44S803_D_S 4
177/* REG_REGTEST */
178/* REG_VCOTEST */
179/* REG_LNAGAIN */
180#define MC44S803_IF_PWR 0x700
181#define MC44S803_IF_PWR_S 8
182#define MC44S803_RF_PWR 0x3800
183#define MC44S803_RF_PWR_S 11
184#define MC44S803_LNA_GAIN 0xFC000
185#define MC44S803_LNA_GAIN_S 14
186/* REG_ID */
187#define MC44S803_ID 0x3E00
188#define MC44S803_ID_S 9
189
190/* Some macros to read/write fields */
191
192/* First shift, then mask */
193#define MC44S803_REG_SM(_val, _reg) \
194 (((_val) << _reg##_S) & (_reg))
195
196/* First mask, then shift */
197#define MC44S803_REG_MS(_val, _reg) \
198 (((_val) & (_reg)) >> _reg##_S)
199
200struct mc44s803_priv {
201 struct mc44s803_config *cfg;
202 struct i2c_adapter *i2c;
203 struct dvb_frontend *fe;
204
205 u32 frequency;
206};
207
208#endif
diff --git a/drivers/media/tuners/mt2060.c b/drivers/media/tuners/mt2060.c
new file mode 100644
index 000000000000..13381de58a84
--- /dev/null
+++ b/drivers/media/tuners/mt2060.c
@@ -0,0 +1,403 @@
1/*
2 * Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
3 *
4 * Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22/* In that file, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
23
24#include <linux/module.h>
25#include <linux/delay.h>
26#include <linux/dvb/frontend.h>
27#include <linux/i2c.h>
28#include <linux/slab.h>
29
30#include "dvb_frontend.h"
31
32#include "mt2060.h"
33#include "mt2060_priv.h"
34
35static int debug;
36module_param(debug, int, 0644);
37MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
38
39#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2060: " args); printk("\n"); }} while (0)
40
41// Reads a single register
42static int mt2060_readreg(struct mt2060_priv *priv, u8 reg, u8 *val)
43{
44 struct i2c_msg msg[2] = {
45 { .addr = priv->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 },
46 { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 },
47 };
48
49 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
50 printk(KERN_WARNING "mt2060 I2C read failed\n");
51 return -EREMOTEIO;
52 }
53 return 0;
54}
55
56// Writes a single register
57static int mt2060_writereg(struct mt2060_priv *priv, u8 reg, u8 val)
58{
59 u8 buf[2] = { reg, val };
60 struct i2c_msg msg = {
61 .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
62 };
63
64 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
65 printk(KERN_WARNING "mt2060 I2C write failed\n");
66 return -EREMOTEIO;
67 }
68 return 0;
69}
70
71// Writes a set of consecutive registers
72static int mt2060_writeregs(struct mt2060_priv *priv,u8 *buf, u8 len)
73{
74 struct i2c_msg msg = {
75 .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
76 };
77 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
78 printk(KERN_WARNING "mt2060 I2C write failed (len=%i)\n",(int)len);
79 return -EREMOTEIO;
80 }
81 return 0;
82}
83
84// Initialisation sequences
85// LNABAND=3, NUM1=0x3C, DIV1=0x74, NUM2=0x1080, DIV2=0x49
86static u8 mt2060_config1[] = {
87 REG_LO1C1,
88 0x3F, 0x74, 0x00, 0x08, 0x93
89};
90
91// FMCG=2, GP2=0, GP1=0
92static u8 mt2060_config2[] = {
93 REG_MISC_CTRL,
94 0x20, 0x1E, 0x30, 0xff, 0x80, 0xff, 0x00, 0x2c, 0x42
95};
96
97// VGAG=3, V1CSE=1
98
99#ifdef MT2060_SPURCHECK
100/* The function below calculates the frequency offset between the output frequency if2
101 and the closer cross modulation subcarrier between lo1 and lo2 up to the tenth harmonic */
102static int mt2060_spurcalc(u32 lo1,u32 lo2,u32 if2)
103{
104 int I,J;
105 int dia,diamin,diff;
106 diamin=1000000;
107 for (I = 1; I < 10; I++) {
108 J = ((2*I*lo1)/lo2+1)/2;
109 diff = I*(int)lo1-J*(int)lo2;
110 if (diff < 0) diff=-diff;
111 dia = (diff-(int)if2);
112 if (dia < 0) dia=-dia;
113 if (diamin > dia) diamin=dia;
114 }
115 return diamin;
116}
117
118#define BANDWIDTH 4000 // kHz
119
120/* Calculates the frequency offset to add to avoid spurs. Returns 0 if no offset is needed */
121static int mt2060_spurcheck(u32 lo1,u32 lo2,u32 if2)
122{
123 u32 Spur,Sp1,Sp2;
124 int I,J;
125 I=0;
126 J=1000;
127
128 Spur=mt2060_spurcalc(lo1,lo2,if2);
129 if (Spur < BANDWIDTH) {
130 /* Potential spurs detected */
131 dprintk("Spurs before : f_lo1: %d f_lo2: %d (kHz)",
132 (int)lo1,(int)lo2);
133 I=1000;
134 Sp1 = mt2060_spurcalc(lo1+I,lo2+I,if2);
135 Sp2 = mt2060_spurcalc(lo1-I,lo2-I,if2);
136
137 if (Sp1 < Sp2) {
138 J=-J; I=-I; Spur=Sp2;
139 } else
140 Spur=Sp1;
141
142 while (Spur < BANDWIDTH) {
143 I += J;
144 Spur = mt2060_spurcalc(lo1+I,lo2+I,if2);
145 }
146 dprintk("Spurs after : f_lo1: %d f_lo2: %d (kHz)",
147 (int)(lo1+I),(int)(lo2+I));
148 }
149 return I;
150}
151#endif
152
153#define IF2 36150 // IF2 frequency = 36.150 MHz
154#define FREF 16000 // Quartz oscillator 16 MHz
155
156static int mt2060_set_params(struct dvb_frontend *fe)
157{
158 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
159 struct mt2060_priv *priv;
160 int ret=0;
161 int i=0;
162 u32 freq;
163 u8 lnaband;
164 u32 f_lo1,f_lo2;
165 u32 div1,num1,div2,num2;
166 u8 b[8];
167 u32 if1;
168
169 priv = fe->tuner_priv;
170
171 if1 = priv->if1_freq;
172 b[0] = REG_LO1B1;
173 b[1] = 0xFF;
174
175 if (fe->ops.i2c_gate_ctrl)
176 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
177
178 mt2060_writeregs(priv,b,2);
179
180 freq = c->frequency / 1000; /* Hz -> kHz */
181
182 f_lo1 = freq + if1 * 1000;
183 f_lo1 = (f_lo1 / 250) * 250;
184 f_lo2 = f_lo1 - freq - IF2;
185 // From the Comtech datasheet, the step used is 50kHz. The tuner chip could be more precise
186 f_lo2 = ((f_lo2 + 25) / 50) * 50;
187 priv->frequency = (f_lo1 - f_lo2 - IF2) * 1000,
188
189#ifdef MT2060_SPURCHECK
190 // LO-related spurs detection and correction
191 num1 = mt2060_spurcheck(f_lo1,f_lo2,IF2);
192 f_lo1 += num1;
193 f_lo2 += num1;
194#endif
195 //Frequency LO1 = 16MHz * (DIV1 + NUM1/64 )
196 num1 = f_lo1 / (FREF / 64);
197 div1 = num1 / 64;
198 num1 &= 0x3f;
199
200 // Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 )
201 num2 = f_lo2 * 64 / (FREF / 128);
202 div2 = num2 / 8192;
203 num2 &= 0x1fff;
204
205 if (freq <= 95000) lnaband = 0xB0; else
206 if (freq <= 180000) lnaband = 0xA0; else
207 if (freq <= 260000) lnaband = 0x90; else
208 if (freq <= 335000) lnaband = 0x80; else
209 if (freq <= 425000) lnaband = 0x70; else
210 if (freq <= 480000) lnaband = 0x60; else
211 if (freq <= 570000) lnaband = 0x50; else
212 if (freq <= 645000) lnaband = 0x40; else
213 if (freq <= 730000) lnaband = 0x30; else
214 if (freq <= 810000) lnaband = 0x20; else lnaband = 0x10;
215
216 b[0] = REG_LO1C1;
217 b[1] = lnaband | ((num1 >>2) & 0x0F);
218 b[2] = div1;
219 b[3] = (num2 & 0x0F) | ((num1 & 3) << 4);
220 b[4] = num2 >> 4;
221 b[5] = ((num2 >>12) & 1) | (div2 << 1);
222
223 dprintk("IF1: %dMHz",(int)if1);
224 dprintk("PLL freq=%dkHz f_lo1=%dkHz f_lo2=%dkHz",(int)freq,(int)f_lo1,(int)f_lo2);
225 dprintk("PLL div1=%d num1=%d div2=%d num2=%d",(int)div1,(int)num1,(int)div2,(int)num2);
226 dprintk("PLL [1..5]: %2x %2x %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3],(int)b[4],(int)b[5]);
227
228 mt2060_writeregs(priv,b,6);
229
230 //Waits for pll lock or timeout
231 i = 0;
232 do {
233 mt2060_readreg(priv,REG_LO_STATUS,b);
234 if ((b[0] & 0x88)==0x88)
235 break;
236 msleep(4);
237 i++;
238 } while (i<10);
239
240 if (fe->ops.i2c_gate_ctrl)
241 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
242
243 return ret;
244}
245
246static void mt2060_calibrate(struct mt2060_priv *priv)
247{
248 u8 b = 0;
249 int i = 0;
250
251 if (mt2060_writeregs(priv,mt2060_config1,sizeof(mt2060_config1)))
252 return;
253 if (mt2060_writeregs(priv,mt2060_config2,sizeof(mt2060_config2)))
254 return;
255
256 /* initialize the clock output */
257 mt2060_writereg(priv, REG_VGAG, (priv->cfg->clock_out << 6) | 0x30);
258
259 do {
260 b |= (1 << 6); // FM1SS;
261 mt2060_writereg(priv, REG_LO2C1,b);
262 msleep(20);
263
264 if (i == 0) {
265 b |= (1 << 7); // FM1CA;
266 mt2060_writereg(priv, REG_LO2C1,b);
267 b &= ~(1 << 7); // FM1CA;
268 msleep(20);
269 }
270
271 b &= ~(1 << 6); // FM1SS
272 mt2060_writereg(priv, REG_LO2C1,b);
273
274 msleep(20);
275 i++;
276 } while (i < 9);
277
278 i = 0;
279 while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
280 msleep(20);
281
282 if (i <= 10) {
283 mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
284 dprintk("calibration was successful: %d", (int)priv->fmfreq);
285 } else
286 dprintk("FMCAL timed out");
287}
288
289static int mt2060_get_frequency(struct dvb_frontend *fe, u32 *frequency)
290{
291 struct mt2060_priv *priv = fe->tuner_priv;
292 *frequency = priv->frequency;
293 return 0;
294}
295
296static int mt2060_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
297{
298 *frequency = IF2 * 1000;
299 return 0;
300}
301
302static int mt2060_init(struct dvb_frontend *fe)
303{
304 struct mt2060_priv *priv = fe->tuner_priv;
305 int ret;
306
307 if (fe->ops.i2c_gate_ctrl)
308 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
309
310 ret = mt2060_writereg(priv, REG_VGAG,
311 (priv->cfg->clock_out << 6) | 0x33);
312
313 if (fe->ops.i2c_gate_ctrl)
314 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
315
316 return ret;
317}
318
319static int mt2060_sleep(struct dvb_frontend *fe)
320{
321 struct mt2060_priv *priv = fe->tuner_priv;
322 int ret;
323
324 if (fe->ops.i2c_gate_ctrl)
325 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
326
327 ret = mt2060_writereg(priv, REG_VGAG,
328 (priv->cfg->clock_out << 6) | 0x30);
329
330 if (fe->ops.i2c_gate_ctrl)
331 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
332
333 return ret;
334}
335
336static int mt2060_release(struct dvb_frontend *fe)
337{
338 kfree(fe->tuner_priv);
339 fe->tuner_priv = NULL;
340 return 0;
341}
342
343static const struct dvb_tuner_ops mt2060_tuner_ops = {
344 .info = {
345 .name = "Microtune MT2060",
346 .frequency_min = 48000000,
347 .frequency_max = 860000000,
348 .frequency_step = 50000,
349 },
350
351 .release = mt2060_release,
352
353 .init = mt2060_init,
354 .sleep = mt2060_sleep,
355
356 .set_params = mt2060_set_params,
357 .get_frequency = mt2060_get_frequency,
358 .get_if_frequency = mt2060_get_if_frequency,
359};
360
361/* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
362struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
363{
364 struct mt2060_priv *priv = NULL;
365 u8 id = 0;
366
367 priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL);
368 if (priv == NULL)
369 return NULL;
370
371 priv->cfg = cfg;
372 priv->i2c = i2c;
373 priv->if1_freq = if1;
374
375 if (fe->ops.i2c_gate_ctrl)
376 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
377
378 if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) {
379 kfree(priv);
380 return NULL;
381 }
382
383 if (id != PART_REV) {
384 kfree(priv);
385 return NULL;
386 }
387 printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1);
388 memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops));
389
390 fe->tuner_priv = priv;
391
392 mt2060_calibrate(priv);
393
394 if (fe->ops.i2c_gate_ctrl)
395 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
396
397 return fe;
398}
399EXPORT_SYMBOL(mt2060_attach);
400
401MODULE_AUTHOR("Olivier DANET");
402MODULE_DESCRIPTION("Microtune MT2060 silicon tuner driver");
403MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/mt2060.h b/drivers/media/tuners/mt2060.h
new file mode 100644
index 000000000000..cb60caffb6b6
--- /dev/null
+++ b/drivers/media/tuners/mt2060.h
@@ -0,0 +1,43 @@
1/*
2 * Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
3 *
4 * Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef MT2060_H
23#define MT2060_H
24
25struct dvb_frontend;
26struct i2c_adapter;
27
28struct mt2060_config {
29 u8 i2c_address;
30 u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
31};
32
33#if defined(CONFIG_MEDIA_TUNER_MT2060) || (defined(CONFIG_MEDIA_TUNER_MT2060_MODULE) && defined(MODULE))
34extern struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
35#else
36static inline struct dvb_frontend * mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
37{
38 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
39 return NULL;
40}
41#endif // CONFIG_MEDIA_TUNER_MT2060
42
43#endif
diff --git a/drivers/media/tuners/mt2060_priv.h b/drivers/media/tuners/mt2060_priv.h
new file mode 100644
index 000000000000..2b60de6c707d
--- /dev/null
+++ b/drivers/media/tuners/mt2060_priv.h
@@ -0,0 +1,104 @@
1/*
2 * Driver for Microtune MT2060 "Single chip dual conversion broadband tuner"
3 *
4 * Copyright (c) 2006 Olivier DANET <odanet@caramail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.=
20 */
21
22#ifndef MT2060_PRIV_H
23#define MT2060_PRIV_H
24
25// Uncomment the #define below to enable spurs checking. The results where quite unconvincing.
26// #define MT2060_SPURCHECK
27
28/* This driver is based on the information available in the datasheet of the
29 "Comtech SDVBT-3K6M" tuner ( K1000737843.pdf ) which features the MT2060 register map :
30
31 I2C Address : 0x60
32
33 Reg.No | B7 | B6 | B5 | B4 | B3 | B2 | B1 | B0 | ( defaults )
34 --------------------------------------------------------------------------------
35 00 | [ PART ] | [ REV ] | R = 0x63
36 01 | [ LNABAND ] | [ NUM1(5:2) ] | RW = 0x3F
37 02 | [ DIV1 ] | RW = 0x74
38 03 | FM1CA | FM1SS | [ NUM1(1:0) ] | [ NUM2(3:0) ] | RW = 0x00
39 04 | NUM2(11:4) ] | RW = 0x08
40 05 | [ DIV2 ] |NUM2(12)| RW = 0x93
41 06 | L1LK | [ TAD1 ] | L2LK | [ TAD2 ] | R
42 07 | [ FMF ] | R
43 08 | ? | FMCAL | ? | ? | ? | ? | ? | TEMP | R
44 09 | 0 | 0 | [ FMGC ] | 0 | GP02 | GP01 | 0 | RW = 0x20
45 0A | ??
46 0B | 0 | 0 | 1 | 1 | 0 | 0 | [ VGAG ] | RW = 0x30
47 0C | V1CSE | 1 | 1 | 1 | 1 | 1 | 1 | 1 | RW = 0xFF
48 0D | 1 | 0 | [ V1CS ] | RW = 0xB0
49 0E | ??
50 0F | ??
51 10 | ??
52 11 | [ LOTO ] | 0 | 0 | 1 | 0 | RW = 0x42
53
54 PART : Part code : 6 for MT2060
55 REV : Revision code : 3 for current revision
56 LNABAND : Input frequency range : ( See code for details )
57 NUM1 / DIV1 / NUM2 / DIV2 : Frequencies programming ( See code for details )
58 FM1CA : Calibration Start Bit
59 FM1SS : Calibration Single Step bit
60 L1LK : LO1 Lock Detect
61 TAD1 : Tune Line ADC ( ? )
62 L2LK : LO2 Lock Detect
63 TAD2 : Tune Line ADC ( ? )
64 FMF : Estimated first IF Center frequency Offset ( ? )
65 FM1CAL : Calibration done bit
66 TEMP : On chip temperature sensor
67 FMCG : Mixer 1 Cap Gain ( ? )
68 GP01 / GP02 : Programmable digital outputs. Unconnected pins ?
69 V1CSE : LO1 VCO Automatic Capacitor Select Enable ( ? )
70 V1CS : LO1 Capacitor Selection Value ( ? )
71 LOTO : LO Timeout ( ? )
72 VGAG : Tuner Output gain
73*/
74
75#define I2C_ADDRESS 0x60
76
77#define REG_PART_REV 0
78#define REG_LO1C1 1
79#define REG_LO1C2 2
80#define REG_LO2C1 3
81#define REG_LO2C2 4
82#define REG_LO2C3 5
83#define REG_LO_STATUS 6
84#define REG_FM_FREQ 7
85#define REG_MISC_STAT 8
86#define REG_MISC_CTRL 9
87#define REG_RESERVED_A 0x0A
88#define REG_VGAG 0x0B
89#define REG_LO1B1 0x0C
90#define REG_LO1B2 0x0D
91#define REG_LOTO 0x11
92
93#define PART_REV 0x63 // The current driver works only with PART=6 and REV=3 chips
94
95struct mt2060_priv {
96 struct mt2060_config *cfg;
97 struct i2c_adapter *i2c;
98
99 u32 frequency;
100 u16 if1_freq;
101 u8 fmfreq;
102};
103
104#endif
diff --git a/drivers/media/tuners/mt2063.c b/drivers/media/tuners/mt2063.c
new file mode 100644
index 000000000000..0ed9091ff48e
--- /dev/null
+++ b/drivers/media/tuners/mt2063.c
@@ -0,0 +1,2307 @@
1/*
2 * Driver for mt2063 Micronas tuner
3 *
4 * Copyright (c) 2011 Mauro Carvalho Chehab <mchehab@redhat.com>
5 *
6 * This driver came from a driver originally written by:
7 * Henry Wang <Henry.wang@AzureWave.com>
8 * Made publicly available by Terratec, at:
9 * http://linux.terratec.de/files/TERRATEC_H7/20110323_TERRATEC_H7_Linux.tar.gz
10 * The original driver's license is GPL, as declared with MODULE_LICENSE()
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation under version 2 of the License.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 */
21
22#include <linux/init.h>
23#include <linux/kernel.h>
24#include <linux/module.h>
25#include <linux/string.h>
26#include <linux/videodev2.h>
27
28#include "mt2063.h"
29
30static unsigned int debug;
31module_param(debug, int, 0644);
32MODULE_PARM_DESC(debug, "Set Verbosity level");
33
34#define dprintk(level, fmt, arg...) do { \
35if (debug >= level) \
36 printk(KERN_DEBUG "mt2063 %s: " fmt, __func__, ## arg); \
37} while (0)
38
39
40/* positive error codes used internally */
41
42/* Info: Unavoidable LO-related spur may be present in the output */
43#define MT2063_SPUR_PRESENT_ERR (0x00800000)
44
45/* Info: Mask of bits used for # of LO-related spurs that were avoided during tuning */
46#define MT2063_SPUR_CNT_MASK (0x001f0000)
47#define MT2063_SPUR_SHIFT (16)
48
49/* Info: Upconverter frequency is out of range (may be reason for MT_UPC_UNLOCK) */
50#define MT2063_UPC_RANGE (0x04000000)
51
52/* Info: Downconverter frequency is out of range (may be reason for MT_DPC_UNLOCK) */
53#define MT2063_DNC_RANGE (0x08000000)
54
55/*
56 * Constant defining the version of the following structure
57 * and therefore the API for this code.
58 *
59 * When compiling the tuner driver, the preprocessor will
60 * check against this version number to make sure that
61 * it matches the version that the tuner driver knows about.
62 */
63
64/* DECT Frequency Avoidance */
65#define MT2063_DECT_AVOID_US_FREQS 0x00000001
66
67#define MT2063_DECT_AVOID_EURO_FREQS 0x00000002
68
69#define MT2063_EXCLUDE_US_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_US_FREQS) != 0)
70
71#define MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(s) (((s) & MT2063_DECT_AVOID_EURO_FREQS) != 0)
72
73enum MT2063_DECT_Avoid_Type {
74 MT2063_NO_DECT_AVOIDANCE = 0, /* Do not create DECT exclusion zones. */
75 MT2063_AVOID_US_DECT = MT2063_DECT_AVOID_US_FREQS, /* Avoid US DECT frequencies. */
76 MT2063_AVOID_EURO_DECT = MT2063_DECT_AVOID_EURO_FREQS, /* Avoid European DECT frequencies. */
77 MT2063_AVOID_BOTH /* Avoid both regions. Not typically used. */
78};
79
80#define MT2063_MAX_ZONES 48
81
82struct MT2063_ExclZone_t {
83 u32 min_;
84 u32 max_;
85 struct MT2063_ExclZone_t *next_;
86};
87
88/*
89 * Structure of data needed for Spur Avoidance
90 */
91struct MT2063_AvoidSpursData_t {
92 u32 f_ref;
93 u32 f_in;
94 u32 f_LO1;
95 u32 f_if1_Center;
96 u32 f_if1_Request;
97 u32 f_if1_bw;
98 u32 f_LO2;
99 u32 f_out;
100 u32 f_out_bw;
101 u32 f_LO1_Step;
102 u32 f_LO2_Step;
103 u32 f_LO1_FracN_Avoid;
104 u32 f_LO2_FracN_Avoid;
105 u32 f_zif_bw;
106 u32 f_min_LO_Separation;
107 u32 maxH1;
108 u32 maxH2;
109 enum MT2063_DECT_Avoid_Type avoidDECT;
110 u32 bSpurPresent;
111 u32 bSpurAvoided;
112 u32 nSpursFound;
113 u32 nZones;
114 struct MT2063_ExclZone_t *freeZones;
115 struct MT2063_ExclZone_t *usedZones;
116 struct MT2063_ExclZone_t MT2063_ExclZones[MT2063_MAX_ZONES];
117};
118
119/*
120 * Parameter for function MT2063_SetPowerMask that specifies the power down
121 * of various sections of the MT2063.
122 */
123enum MT2063_Mask_Bits {
124 MT2063_REG_SD = 0x0040, /* Shutdown regulator */
125 MT2063_SRO_SD = 0x0020, /* Shutdown SRO */
126 MT2063_AFC_SD = 0x0010, /* Shutdown AFC A/D */
127 MT2063_PD_SD = 0x0002, /* Enable power detector shutdown */
128 MT2063_PDADC_SD = 0x0001, /* Enable power detector A/D shutdown */
129 MT2063_VCO_SD = 0x8000, /* Enable VCO shutdown */
130 MT2063_LTX_SD = 0x4000, /* Enable LTX shutdown */
131 MT2063_LT1_SD = 0x2000, /* Enable LT1 shutdown */
132 MT2063_LNA_SD = 0x1000, /* Enable LNA shutdown */
133 MT2063_UPC_SD = 0x0800, /* Enable upconverter shutdown */
134 MT2063_DNC_SD = 0x0400, /* Enable downconverter shutdown */
135 MT2063_VGA_SD = 0x0200, /* Enable VGA shutdown */
136 MT2063_AMP_SD = 0x0100, /* Enable AMP shutdown */
137 MT2063_ALL_SD = 0xFF73, /* All shutdown bits for this tuner */
138 MT2063_NONE_SD = 0x0000 /* No shutdown bits */
139};
140
141/*
142 * Possible values for MT2063_DNC_OUTPUT
143 */
144enum MT2063_DNC_Output_Enable {
145 MT2063_DNC_NONE = 0,
146 MT2063_DNC_1,
147 MT2063_DNC_2,
148 MT2063_DNC_BOTH
149};
150
151/*
152 * Two-wire serial bus subaddresses of the tuner registers.
153 * Also known as the tuner's register addresses.
154 */
155enum MT2063_Register_Offsets {
156 MT2063_REG_PART_REV = 0, /* 0x00: Part/Rev Code */
157 MT2063_REG_LO1CQ_1, /* 0x01: LO1C Queued Byte 1 */
158 MT2063_REG_LO1CQ_2, /* 0x02: LO1C Queued Byte 2 */
159 MT2063_REG_LO2CQ_1, /* 0x03: LO2C Queued Byte 1 */
160 MT2063_REG_LO2CQ_2, /* 0x04: LO2C Queued Byte 2 */
161 MT2063_REG_LO2CQ_3, /* 0x05: LO2C Queued Byte 3 */
162 MT2063_REG_RSVD_06, /* 0x06: Reserved */
163 MT2063_REG_LO_STATUS, /* 0x07: LO Status */
164 MT2063_REG_FIFFC, /* 0x08: FIFF Center */
165 MT2063_REG_CLEARTUNE, /* 0x09: ClearTune Filter */
166 MT2063_REG_ADC_OUT, /* 0x0A: ADC_OUT */
167 MT2063_REG_LO1C_1, /* 0x0B: LO1C Byte 1 */
168 MT2063_REG_LO1C_2, /* 0x0C: LO1C Byte 2 */
169 MT2063_REG_LO2C_1, /* 0x0D: LO2C Byte 1 */
170 MT2063_REG_LO2C_2, /* 0x0E: LO2C Byte 2 */
171 MT2063_REG_LO2C_3, /* 0x0F: LO2C Byte 3 */
172 MT2063_REG_RSVD_10, /* 0x10: Reserved */
173 MT2063_REG_PWR_1, /* 0x11: PWR Byte 1 */
174 MT2063_REG_PWR_2, /* 0x12: PWR Byte 2 */
175 MT2063_REG_TEMP_STATUS, /* 0x13: Temp Status */
176 MT2063_REG_XO_STATUS, /* 0x14: Crystal Status */
177 MT2063_REG_RF_STATUS, /* 0x15: RF Attn Status */
178 MT2063_REG_FIF_STATUS, /* 0x16: FIF Attn Status */
179 MT2063_REG_LNA_OV, /* 0x17: LNA Attn Override */
180 MT2063_REG_RF_OV, /* 0x18: RF Attn Override */
181 MT2063_REG_FIF_OV, /* 0x19: FIF Attn Override */
182 MT2063_REG_LNA_TGT, /* 0x1A: Reserved */
183 MT2063_REG_PD1_TGT, /* 0x1B: Pwr Det 1 Target */
184 MT2063_REG_PD2_TGT, /* 0x1C: Pwr Det 2 Target */
185 MT2063_REG_RSVD_1D, /* 0x1D: Reserved */
186 MT2063_REG_RSVD_1E, /* 0x1E: Reserved */
187 MT2063_REG_RSVD_1F, /* 0x1F: Reserved */
188 MT2063_REG_RSVD_20, /* 0x20: Reserved */
189 MT2063_REG_BYP_CTRL, /* 0x21: Bypass Control */
190 MT2063_REG_RSVD_22, /* 0x22: Reserved */
191 MT2063_REG_RSVD_23, /* 0x23: Reserved */
192 MT2063_REG_RSVD_24, /* 0x24: Reserved */
193 MT2063_REG_RSVD_25, /* 0x25: Reserved */
194 MT2063_REG_RSVD_26, /* 0x26: Reserved */
195 MT2063_REG_RSVD_27, /* 0x27: Reserved */
196 MT2063_REG_FIFF_CTRL, /* 0x28: FIFF Control */
197 MT2063_REG_FIFF_OFFSET, /* 0x29: FIFF Offset */
198 MT2063_REG_CTUNE_CTRL, /* 0x2A: Reserved */
199 MT2063_REG_CTUNE_OV, /* 0x2B: Reserved */
200 MT2063_REG_CTRL_2C, /* 0x2C: Reserved */
201 MT2063_REG_FIFF_CTRL2, /* 0x2D: Fiff Control */
202 MT2063_REG_RSVD_2E, /* 0x2E: Reserved */
203 MT2063_REG_DNC_GAIN, /* 0x2F: DNC Control */
204 MT2063_REG_VGA_GAIN, /* 0x30: VGA Gain Ctrl */
205 MT2063_REG_RSVD_31, /* 0x31: Reserved */
206 MT2063_REG_TEMP_SEL, /* 0x32: Temperature Selection */
207 MT2063_REG_RSVD_33, /* 0x33: Reserved */
208 MT2063_REG_RSVD_34, /* 0x34: Reserved */
209 MT2063_REG_RSVD_35, /* 0x35: Reserved */
210 MT2063_REG_RSVD_36, /* 0x36: Reserved */
211 MT2063_REG_RSVD_37, /* 0x37: Reserved */
212 MT2063_REG_RSVD_38, /* 0x38: Reserved */
213 MT2063_REG_RSVD_39, /* 0x39: Reserved */
214 MT2063_REG_RSVD_3A, /* 0x3A: Reserved */
215 MT2063_REG_RSVD_3B, /* 0x3B: Reserved */
216 MT2063_REG_RSVD_3C, /* 0x3C: Reserved */
217 MT2063_REG_END_REGS
218};
219
220struct mt2063_state {
221 struct i2c_adapter *i2c;
222
223 bool init;
224
225 const struct mt2063_config *config;
226 struct dvb_tuner_ops ops;
227 struct dvb_frontend *frontend;
228 struct tuner_state status;
229
230 u32 frequency;
231 u32 srate;
232 u32 bandwidth;
233 u32 reference;
234
235 u32 tuner_id;
236 struct MT2063_AvoidSpursData_t AS_Data;
237 u32 f_IF1_actual;
238 u32 rcvr_mode;
239 u32 ctfilt_sw;
240 u32 CTFiltMax[31];
241 u32 num_regs;
242 u8 reg[MT2063_REG_END_REGS];
243};
244
245/*
246 * mt2063_write - Write data into the I2C bus
247 */
248static u32 mt2063_write(struct mt2063_state *state, u8 reg, u8 *data, u32 len)
249{
250 struct dvb_frontend *fe = state->frontend;
251 int ret;
252 u8 buf[60];
253 struct i2c_msg msg = {
254 .addr = state->config->tuner_address,
255 .flags = 0,
256 .buf = buf,
257 .len = len + 1
258 };
259
260 dprintk(2, "\n");
261
262 msg.buf[0] = reg;
263 memcpy(msg.buf + 1, data, len);
264
265 if (fe->ops.i2c_gate_ctrl)
266 fe->ops.i2c_gate_ctrl(fe, 1);
267 ret = i2c_transfer(state->i2c, &msg, 1);
268 if (fe->ops.i2c_gate_ctrl)
269 fe->ops.i2c_gate_ctrl(fe, 0);
270
271 if (ret < 0)
272 printk(KERN_ERR "%s error ret=%d\n", __func__, ret);
273
274 return ret;
275}
276
277/*
278 * mt2063_write - Write register data into the I2C bus, caching the value
279 */
280static u32 mt2063_setreg(struct mt2063_state *state, u8 reg, u8 val)
281{
282 u32 status;
283
284 dprintk(2, "\n");
285
286 if (reg >= MT2063_REG_END_REGS)
287 return -ERANGE;
288
289 status = mt2063_write(state, reg, &val, 1);
290 if (status < 0)
291 return status;
292
293 state->reg[reg] = val;
294
295 return 0;
296}
297
298/*
299 * mt2063_read - Read data from the I2C bus
300 */
301static u32 mt2063_read(struct mt2063_state *state,
302 u8 subAddress, u8 *pData, u32 cnt)
303{
304 u32 status = 0; /* Status to be returned */
305 struct dvb_frontend *fe = state->frontend;
306 u32 i = 0;
307
308 dprintk(2, "addr 0x%02x, cnt %d\n", subAddress, cnt);
309
310 if (fe->ops.i2c_gate_ctrl)
311 fe->ops.i2c_gate_ctrl(fe, 1);
312
313 for (i = 0; i < cnt; i++) {
314 u8 b0[] = { subAddress + i };
315 struct i2c_msg msg[] = {
316 {
317 .addr = state->config->tuner_address,
318 .flags = 0,
319 .buf = b0,
320 .len = 1
321 }, {
322 .addr = state->config->tuner_address,
323 .flags = I2C_M_RD,
324 .buf = pData + i,
325 .len = 1
326 }
327 };
328
329 status = i2c_transfer(state->i2c, msg, 2);
330 dprintk(2, "addr 0x%02x, ret = %d, val = 0x%02x\n",
331 subAddress + i, status, *(pData + i));
332 if (status < 0)
333 break;
334 }
335 if (fe->ops.i2c_gate_ctrl)
336 fe->ops.i2c_gate_ctrl(fe, 0);
337
338 if (status < 0)
339 printk(KERN_ERR "Can't read from address 0x%02x,\n",
340 subAddress + i);
341
342 return status;
343}
344
345/*
346 * FIXME: Is this really needed?
347 */
348static int MT2063_Sleep(struct dvb_frontend *fe)
349{
350 /*
351 * ToDo: Add code here to implement a OS blocking
352 */
353 msleep(100);
354
355 return 0;
356}
357
358/*
359 * Microtune spur avoidance
360 */
361
362/* Implement ceiling, floor functions. */
363#define ceil(n, d) (((n) < 0) ? (-((-(n))/(d))) : (n)/(d) + ((n)%(d) != 0))
364#define floor(n, d) (((n) < 0) ? (-((-(n))/(d))) - ((n)%(d) != 0) : (n)/(d))
365
366struct MT2063_FIFZone_t {
367 s32 min_;
368 s32 max_;
369};
370
371static struct MT2063_ExclZone_t *InsertNode(struct MT2063_AvoidSpursData_t
372 *pAS_Info,
373 struct MT2063_ExclZone_t *pPrevNode)
374{
375 struct MT2063_ExclZone_t *pNode;
376
377 dprintk(2, "\n");
378
379 /* Check for a node in the free list */
380 if (pAS_Info->freeZones != NULL) {
381 /* Use one from the free list */
382 pNode = pAS_Info->freeZones;
383 pAS_Info->freeZones = pNode->next_;
384 } else {
385 /* Grab a node from the array */
386 pNode = &pAS_Info->MT2063_ExclZones[pAS_Info->nZones];
387 }
388
389 if (pPrevNode != NULL) {
390 pNode->next_ = pPrevNode->next_;
391 pPrevNode->next_ = pNode;
392 } else { /* insert at the beginning of the list */
393
394 pNode->next_ = pAS_Info->usedZones;
395 pAS_Info->usedZones = pNode;
396 }
397
398 pAS_Info->nZones++;
399 return pNode;
400}
401
402static struct MT2063_ExclZone_t *RemoveNode(struct MT2063_AvoidSpursData_t
403 *pAS_Info,
404 struct MT2063_ExclZone_t *pPrevNode,
405 struct MT2063_ExclZone_t
406 *pNodeToRemove)
407{
408 struct MT2063_ExclZone_t *pNext = pNodeToRemove->next_;
409
410 dprintk(2, "\n");
411
412 /* Make previous node point to the subsequent node */
413 if (pPrevNode != NULL)
414 pPrevNode->next_ = pNext;
415
416 /* Add pNodeToRemove to the beginning of the freeZones */
417 pNodeToRemove->next_ = pAS_Info->freeZones;
418 pAS_Info->freeZones = pNodeToRemove;
419
420 /* Decrement node count */
421 pAS_Info->nZones--;
422
423 return pNext;
424}
425
426/*
427 * MT_AddExclZone()
428 *
429 * Add (and merge) an exclusion zone into the list.
430 * If the range (f_min, f_max) is totally outside the
431 * 1st IF BW, ignore the entry.
432 * If the range (f_min, f_max) is negative, ignore the entry.
433 */
434static void MT2063_AddExclZone(struct MT2063_AvoidSpursData_t *pAS_Info,
435 u32 f_min, u32 f_max)
436{
437 struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
438 struct MT2063_ExclZone_t *pPrev = NULL;
439 struct MT2063_ExclZone_t *pNext = NULL;
440
441 dprintk(2, "\n");
442
443 /* Check to see if this overlaps the 1st IF filter */
444 if ((f_max > (pAS_Info->f_if1_Center - (pAS_Info->f_if1_bw / 2)))
445 && (f_min < (pAS_Info->f_if1_Center + (pAS_Info->f_if1_bw / 2)))
446 && (f_min < f_max)) {
447 /*
448 * 1 2 3 4 5 6
449 *
450 * New entry: |---| |--| |--| |-| |---| |--|
451 * or or or or or
452 * Existing: |--| |--| |--| |---| |-| |--|
453 */
454
455 /* Check for our place in the list */
456 while ((pNode != NULL) && (pNode->max_ < f_min)) {
457 pPrev = pNode;
458 pNode = pNode->next_;
459 }
460
461 if ((pNode != NULL) && (pNode->min_ < f_max)) {
462 /* Combine me with pNode */
463 if (f_min < pNode->min_)
464 pNode->min_ = f_min;
465 if (f_max > pNode->max_)
466 pNode->max_ = f_max;
467 } else {
468 pNode = InsertNode(pAS_Info, pPrev);
469 pNode->min_ = f_min;
470 pNode->max_ = f_max;
471 }
472
473 /* Look for merging possibilities */
474 pNext = pNode->next_;
475 while ((pNext != NULL) && (pNext->min_ < pNode->max_)) {
476 if (pNext->max_ > pNode->max_)
477 pNode->max_ = pNext->max_;
478 /* Remove pNext, return ptr to pNext->next */
479 pNext = RemoveNode(pAS_Info, pNode, pNext);
480 }
481 }
482}
483
484/*
485 * Reset all exclusion zones.
486 * Add zones to protect the PLL FracN regions near zero
487 */
488static void MT2063_ResetExclZones(struct MT2063_AvoidSpursData_t *pAS_Info)
489{
490 u32 center;
491
492 dprintk(2, "\n");
493
494 pAS_Info->nZones = 0; /* this clears the used list */
495 pAS_Info->usedZones = NULL; /* reset ptr */
496 pAS_Info->freeZones = NULL; /* reset ptr */
497
498 center =
499 pAS_Info->f_ref *
500 ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 +
501 pAS_Info->f_in) / pAS_Info->f_ref) - pAS_Info->f_in;
502 while (center <
503 pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
504 pAS_Info->f_LO1_FracN_Avoid) {
505 /* Exclude LO1 FracN */
506 MT2063_AddExclZone(pAS_Info,
507 center - pAS_Info->f_LO1_FracN_Avoid,
508 center - 1);
509 MT2063_AddExclZone(pAS_Info, center + 1,
510 center + pAS_Info->f_LO1_FracN_Avoid);
511 center += pAS_Info->f_ref;
512 }
513
514 center =
515 pAS_Info->f_ref *
516 ((pAS_Info->f_if1_Center - pAS_Info->f_if1_bw / 2 -
517 pAS_Info->f_out) / pAS_Info->f_ref) + pAS_Info->f_out;
518 while (center <
519 pAS_Info->f_if1_Center + pAS_Info->f_if1_bw / 2 +
520 pAS_Info->f_LO2_FracN_Avoid) {
521 /* Exclude LO2 FracN */
522 MT2063_AddExclZone(pAS_Info,
523 center - pAS_Info->f_LO2_FracN_Avoid,
524 center - 1);
525 MT2063_AddExclZone(pAS_Info, center + 1,
526 center + pAS_Info->f_LO2_FracN_Avoid);
527 center += pAS_Info->f_ref;
528 }
529
530 if (MT2063_EXCLUDE_US_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
531 /* Exclude LO1 values that conflict with DECT channels */
532 MT2063_AddExclZone(pAS_Info, 1920836000 - pAS_Info->f_in, 1922236000 - pAS_Info->f_in); /* Ctr = 1921.536 */
533 MT2063_AddExclZone(pAS_Info, 1922564000 - pAS_Info->f_in, 1923964000 - pAS_Info->f_in); /* Ctr = 1923.264 */
534 MT2063_AddExclZone(pAS_Info, 1924292000 - pAS_Info->f_in, 1925692000 - pAS_Info->f_in); /* Ctr = 1924.992 */
535 MT2063_AddExclZone(pAS_Info, 1926020000 - pAS_Info->f_in, 1927420000 - pAS_Info->f_in); /* Ctr = 1926.720 */
536 MT2063_AddExclZone(pAS_Info, 1927748000 - pAS_Info->f_in, 1929148000 - pAS_Info->f_in); /* Ctr = 1928.448 */
537 }
538
539 if (MT2063_EXCLUDE_EURO_DECT_FREQUENCIES(pAS_Info->avoidDECT)) {
540 MT2063_AddExclZone(pAS_Info, 1896644000 - pAS_Info->f_in, 1898044000 - pAS_Info->f_in); /* Ctr = 1897.344 */
541 MT2063_AddExclZone(pAS_Info, 1894916000 - pAS_Info->f_in, 1896316000 - pAS_Info->f_in); /* Ctr = 1895.616 */
542 MT2063_AddExclZone(pAS_Info, 1893188000 - pAS_Info->f_in, 1894588000 - pAS_Info->f_in); /* Ctr = 1893.888 */
543 MT2063_AddExclZone(pAS_Info, 1891460000 - pAS_Info->f_in, 1892860000 - pAS_Info->f_in); /* Ctr = 1892.16 */
544 MT2063_AddExclZone(pAS_Info, 1889732000 - pAS_Info->f_in, 1891132000 - pAS_Info->f_in); /* Ctr = 1890.432 */
545 MT2063_AddExclZone(pAS_Info, 1888004000 - pAS_Info->f_in, 1889404000 - pAS_Info->f_in); /* Ctr = 1888.704 */
546 MT2063_AddExclZone(pAS_Info, 1886276000 - pAS_Info->f_in, 1887676000 - pAS_Info->f_in); /* Ctr = 1886.976 */
547 MT2063_AddExclZone(pAS_Info, 1884548000 - pAS_Info->f_in, 1885948000 - pAS_Info->f_in); /* Ctr = 1885.248 */
548 MT2063_AddExclZone(pAS_Info, 1882820000 - pAS_Info->f_in, 1884220000 - pAS_Info->f_in); /* Ctr = 1883.52 */
549 MT2063_AddExclZone(pAS_Info, 1881092000 - pAS_Info->f_in, 1882492000 - pAS_Info->f_in); /* Ctr = 1881.792 */
550 }
551}
552
553/*
554 * MT_ChooseFirstIF - Choose the best available 1st IF
555 * If f_Desired is not excluded, choose that first.
556 * Otherwise, return the value closest to f_Center that is
557 * not excluded
558 */
559static u32 MT2063_ChooseFirstIF(struct MT2063_AvoidSpursData_t *pAS_Info)
560{
561 /*
562 * Update "f_Desired" to be the nearest "combinational-multiple" of
563 * "f_LO1_Step".
564 * The resulting number, F_LO1 must be a multiple of f_LO1_Step.
565 * And F_LO1 is the arithmetic sum of f_in + f_Center.
566 * Neither f_in, nor f_Center must be a multiple of f_LO1_Step.
567 * However, the sum must be.
568 */
569 const u32 f_Desired =
570 pAS_Info->f_LO1_Step *
571 ((pAS_Info->f_if1_Request + pAS_Info->f_in +
572 pAS_Info->f_LO1_Step / 2) / pAS_Info->f_LO1_Step) -
573 pAS_Info->f_in;
574 const u32 f_Step =
575 (pAS_Info->f_LO1_Step >
576 pAS_Info->f_LO2_Step) ? pAS_Info->f_LO1_Step : pAS_Info->
577 f_LO2_Step;
578 u32 f_Center;
579 s32 i;
580 s32 j = 0;
581 u32 bDesiredExcluded = 0;
582 u32 bZeroExcluded = 0;
583 s32 tmpMin, tmpMax;
584 s32 bestDiff;
585 struct MT2063_ExclZone_t *pNode = pAS_Info->usedZones;
586 struct MT2063_FIFZone_t zones[MT2063_MAX_ZONES];
587
588 dprintk(2, "\n");
589
590 if (pAS_Info->nZones == 0)
591 return f_Desired;
592
593 /*
594 * f_Center needs to be an integer multiple of f_Step away
595 * from f_Desired
596 */
597 if (pAS_Info->f_if1_Center > f_Desired)
598 f_Center =
599 f_Desired +
600 f_Step *
601 ((pAS_Info->f_if1_Center - f_Desired +
602 f_Step / 2) / f_Step);
603 else
604 f_Center =
605 f_Desired -
606 f_Step *
607 ((f_Desired - pAS_Info->f_if1_Center +
608 f_Step / 2) / f_Step);
609
610 /*
611 * Take MT_ExclZones, center around f_Center and change the
612 * resolution to f_Step
613 */
614 while (pNode != NULL) {
615 /* floor function */
616 tmpMin =
617 floor((s32) (pNode->min_ - f_Center), (s32) f_Step);
618
619 /* ceil function */
620 tmpMax =
621 ceil((s32) (pNode->max_ - f_Center), (s32) f_Step);
622
623 if ((pNode->min_ < f_Desired) && (pNode->max_ > f_Desired))
624 bDesiredExcluded = 1;
625
626 if ((tmpMin < 0) && (tmpMax > 0))
627 bZeroExcluded = 1;
628
629 /* See if this zone overlaps the previous */
630 if ((j > 0) && (tmpMin < zones[j - 1].max_))
631 zones[j - 1].max_ = tmpMax;
632 else {
633 /* Add new zone */
634 zones[j].min_ = tmpMin;
635 zones[j].max_ = tmpMax;
636 j++;
637 }
638 pNode = pNode->next_;
639 }
640
641 /*
642 * If the desired is okay, return with it
643 */
644 if (bDesiredExcluded == 0)
645 return f_Desired;
646
647 /*
648 * If the desired is excluded and the center is okay, return with it
649 */
650 if (bZeroExcluded == 0)
651 return f_Center;
652
653 /* Find the value closest to 0 (f_Center) */
654 bestDiff = zones[0].min_;
655 for (i = 0; i < j; i++) {
656 if (abs(zones[i].min_) < abs(bestDiff))
657 bestDiff = zones[i].min_;
658 if (abs(zones[i].max_) < abs(bestDiff))
659 bestDiff = zones[i].max_;
660 }
661
662 if (bestDiff < 0)
663 return f_Center - ((u32) (-bestDiff) * f_Step);
664
665 return f_Center + (bestDiff * f_Step);
666}
667
668/**
669 * gcd() - Uses Euclid's algorithm
670 *
671 * @u, @v: Unsigned values whose GCD is desired.
672 *
673 * Returns THE greatest common divisor of u and v, if either value is 0,
674 * the other value is returned as the result.
675 */
676static u32 MT2063_gcd(u32 u, u32 v)
677{
678 u32 r;
679
680 while (v != 0) {
681 r = u % v;
682 u = v;
683 v = r;
684 }
685
686 return u;
687}
688
689/**
690 * IsSpurInBand() - Checks to see if a spur will be present within the IF's
691 * bandwidth. (fIFOut +/- fIFBW, -fIFOut +/- fIFBW)
692 *
693 * ma mb mc md
694 * <--+-+-+-------------------+-------------------+-+-+-->
695 * | ^ 0 ^ |
696 * ^ b=-fIFOut+fIFBW/2 -b=+fIFOut-fIFBW/2 ^
697 * a=-fIFOut-fIFBW/2 -a=+fIFOut+fIFBW/2
698 *
699 * Note that some equations are doubled to prevent round-off
700 * problems when calculating fIFBW/2
701 *
702 * @pAS_Info: Avoid Spurs information block
703 * @fm: If spur, amount f_IF1 has to move negative
704 * @fp: If spur, amount f_IF1 has to move positive
705 *
706 * Returns 1 if an LO spur would be present, otherwise 0.
707 */
708static u32 IsSpurInBand(struct MT2063_AvoidSpursData_t *pAS_Info,
709 u32 *fm, u32 * fp)
710{
711 /*
712 ** Calculate LO frequency settings.
713 */
714 u32 n, n0;
715 const u32 f_LO1 = pAS_Info->f_LO1;
716 const u32 f_LO2 = pAS_Info->f_LO2;
717 const u32 d = pAS_Info->f_out + pAS_Info->f_out_bw / 2;
718 const u32 c = d - pAS_Info->f_out_bw;
719 const u32 f = pAS_Info->f_zif_bw / 2;
720 const u32 f_Scale = (f_LO1 / (UINT_MAX / 2 / pAS_Info->maxH1)) + 1;
721 s32 f_nsLO1, f_nsLO2;
722 s32 f_Spur;
723 u32 ma, mb, mc, md, me, mf;
724 u32 lo_gcd, gd_Scale, gc_Scale, gf_Scale, hgds, hgfs, hgcs;
725
726 dprintk(2, "\n");
727
728 *fm = 0;
729
730 /*
731 ** For each edge (d, c & f), calculate a scale, based on the gcd
732 ** of f_LO1, f_LO2 and the edge value. Use the larger of this
733 ** gcd-based scale factor or f_Scale.
734 */
735 lo_gcd = MT2063_gcd(f_LO1, f_LO2);
736 gd_Scale = max((u32) MT2063_gcd(lo_gcd, d), f_Scale);
737 hgds = gd_Scale / 2;
738 gc_Scale = max((u32) MT2063_gcd(lo_gcd, c), f_Scale);
739 hgcs = gc_Scale / 2;
740 gf_Scale = max((u32) MT2063_gcd(lo_gcd, f), f_Scale);
741 hgfs = gf_Scale / 2;
742
743 n0 = DIV_ROUND_UP(f_LO2 - d, f_LO1 - f_LO2);
744
745 /* Check out all multiples of LO1 from n0 to m_maxLOSpurHarmonic */
746 for (n = n0; n <= pAS_Info->maxH1; ++n) {
747 md = (n * ((f_LO1 + hgds) / gd_Scale) -
748 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
749
750 /* If # fLO2 harmonics > m_maxLOSpurHarmonic, then no spurs present */
751 if (md >= pAS_Info->maxH1)
752 break;
753
754 ma = (n * ((f_LO1 + hgds) / gd_Scale) +
755 ((d + hgds) / gd_Scale)) / ((f_LO2 + hgds) / gd_Scale);
756
757 /* If no spurs between +/- (f_out + f_IFBW/2), then try next harmonic */
758 if (md == ma)
759 continue;
760
761 mc = (n * ((f_LO1 + hgcs) / gc_Scale) -
762 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
763 if (mc != md) {
764 f_nsLO1 = (s32) (n * (f_LO1 / gc_Scale));
765 f_nsLO2 = (s32) (mc * (f_LO2 / gc_Scale));
766 f_Spur =
767 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
768 n * (f_LO1 % gc_Scale) - mc * (f_LO2 % gc_Scale);
769
770 *fp = ((f_Spur - (s32) c) / (mc - n)) + 1;
771 *fm = (((s32) d - f_Spur) / (mc - n)) + 1;
772 return 1;
773 }
774
775 /* Location of Zero-IF-spur to be checked */
776 me = (n * ((f_LO1 + hgfs) / gf_Scale) +
777 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
778 mf = (n * ((f_LO1 + hgfs) / gf_Scale) -
779 ((f + hgfs) / gf_Scale)) / ((f_LO2 + hgfs) / gf_Scale);
780 if (me != mf) {
781 f_nsLO1 = n * (f_LO1 / gf_Scale);
782 f_nsLO2 = me * (f_LO2 / gf_Scale);
783 f_Spur =
784 (gf_Scale * (f_nsLO1 - f_nsLO2)) +
785 n * (f_LO1 % gf_Scale) - me * (f_LO2 % gf_Scale);
786
787 *fp = ((f_Spur + (s32) f) / (me - n)) + 1;
788 *fm = (((s32) f - f_Spur) / (me - n)) + 1;
789 return 1;
790 }
791
792 mb = (n * ((f_LO1 + hgcs) / gc_Scale) +
793 ((c + hgcs) / gc_Scale)) / ((f_LO2 + hgcs) / gc_Scale);
794 if (ma != mb) {
795 f_nsLO1 = n * (f_LO1 / gc_Scale);
796 f_nsLO2 = ma * (f_LO2 / gc_Scale);
797 f_Spur =
798 (gc_Scale * (f_nsLO1 - f_nsLO2)) +
799 n * (f_LO1 % gc_Scale) - ma * (f_LO2 % gc_Scale);
800
801 *fp = (((s32) d + f_Spur) / (ma - n)) + 1;
802 *fm = (-(f_Spur + (s32) c) / (ma - n)) + 1;
803 return 1;
804 }
805 }
806
807 /* No spurs found */
808 return 0;
809}
810
811/*
812 * MT_AvoidSpurs() - Main entry point to avoid spurs.
813 * Checks for existing spurs in present LO1, LO2 freqs
814 * and if present, chooses spur-free LO1, LO2 combination
815 * that tunes the same input/output frequencies.
816 */
817static u32 MT2063_AvoidSpurs(struct MT2063_AvoidSpursData_t *pAS_Info)
818{
819 u32 status = 0;
820 u32 fm, fp; /* restricted range on LO's */
821 pAS_Info->bSpurAvoided = 0;
822 pAS_Info->nSpursFound = 0;
823
824 dprintk(2, "\n");
825
826 if (pAS_Info->maxH1 == 0)
827 return 0;
828
829 /*
830 * Avoid LO Generated Spurs
831 *
832 * Make sure that have no LO-related spurs within the IF output
833 * bandwidth.
834 *
835 * If there is an LO spur in this band, start at the current IF1 frequency
836 * and work out until we find a spur-free frequency or run up against the
837 * 1st IF SAW band edge. Use temporary copies of fLO1 and fLO2 so that they
838 * will be unchanged if a spur-free setting is not found.
839 */
840 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
841 if (pAS_Info->bSpurPresent) {
842 u32 zfIF1 = pAS_Info->f_LO1 - pAS_Info->f_in; /* current attempt at a 1st IF */
843 u32 zfLO1 = pAS_Info->f_LO1; /* current attempt at an LO1 freq */
844 u32 zfLO2 = pAS_Info->f_LO2; /* current attempt at an LO2 freq */
845 u32 delta_IF1;
846 u32 new_IF1;
847
848 /*
849 ** Spur was found, attempt to find a spur-free 1st IF
850 */
851 do {
852 pAS_Info->nSpursFound++;
853
854 /* Raise f_IF1_upper, if needed */
855 MT2063_AddExclZone(pAS_Info, zfIF1 - fm, zfIF1 + fp);
856
857 /* Choose next IF1 that is closest to f_IF1_CENTER */
858 new_IF1 = MT2063_ChooseFirstIF(pAS_Info);
859
860 if (new_IF1 > zfIF1) {
861 pAS_Info->f_LO1 += (new_IF1 - zfIF1);
862 pAS_Info->f_LO2 += (new_IF1 - zfIF1);
863 } else {
864 pAS_Info->f_LO1 -= (zfIF1 - new_IF1);
865 pAS_Info->f_LO2 -= (zfIF1 - new_IF1);
866 }
867 zfIF1 = new_IF1;
868
869 if (zfIF1 > pAS_Info->f_if1_Center)
870 delta_IF1 = zfIF1 - pAS_Info->f_if1_Center;
871 else
872 delta_IF1 = pAS_Info->f_if1_Center - zfIF1;
873
874 pAS_Info->bSpurPresent = IsSpurInBand(pAS_Info, &fm, &fp);
875 /*
876 * Continue while the new 1st IF is still within the 1st IF bandwidth
877 * and there is a spur in the band (again)
878 */
879 } while ((2 * delta_IF1 + pAS_Info->f_out_bw <= pAS_Info->f_if1_bw) && pAS_Info->bSpurPresent);
880
881 /*
882 * Use the LO-spur free values found. If the search went all
883 * the way to the 1st IF band edge and always found spurs, just
884 * leave the original choice. It's as "good" as any other.
885 */
886 if (pAS_Info->bSpurPresent == 1) {
887 status |= MT2063_SPUR_PRESENT_ERR;
888 pAS_Info->f_LO1 = zfLO1;
889 pAS_Info->f_LO2 = zfLO2;
890 } else
891 pAS_Info->bSpurAvoided = 1;
892 }
893
894 status |=
895 ((pAS_Info->
896 nSpursFound << MT2063_SPUR_SHIFT) & MT2063_SPUR_CNT_MASK);
897
898 return status;
899}
900
901/*
902 * Constants used by the tuning algorithm
903 */
904#define MT2063_REF_FREQ (16000000UL) /* Reference oscillator Frequency (in Hz) */
905#define MT2063_IF1_BW (22000000UL) /* The IF1 filter bandwidth (in Hz) */
906#define MT2063_TUNE_STEP_SIZE (50000UL) /* Tune in steps of 50 kHz */
907#define MT2063_SPUR_STEP_HZ (250000UL) /* Step size (in Hz) to move IF1 when avoiding spurs */
908#define MT2063_ZIF_BW (2000000UL) /* Zero-IF spur-free bandwidth (in Hz) */
909#define MT2063_MAX_HARMONICS_1 (15UL) /* Highest intra-tuner LO Spur Harmonic to be avoided */
910#define MT2063_MAX_HARMONICS_2 (5UL) /* Highest inter-tuner LO Spur Harmonic to be avoided */
911#define MT2063_MIN_LO_SEP (1000000UL) /* Minimum inter-tuner LO frequency separation */
912#define MT2063_LO1_FRACN_AVOID (0UL) /* LO1 FracN numerator avoid region (in Hz) */
913#define MT2063_LO2_FRACN_AVOID (199999UL) /* LO2 FracN numerator avoid region (in Hz) */
914#define MT2063_MIN_FIN_FREQ (44000000UL) /* Minimum input frequency (in Hz) */
915#define MT2063_MAX_FIN_FREQ (1100000000UL) /* Maximum input frequency (in Hz) */
916#define MT2063_MIN_FOUT_FREQ (36000000UL) /* Minimum output frequency (in Hz) */
917#define MT2063_MAX_FOUT_FREQ (57000000UL) /* Maximum output frequency (in Hz) */
918#define MT2063_MIN_DNC_FREQ (1293000000UL) /* Minimum LO2 frequency (in Hz) */
919#define MT2063_MAX_DNC_FREQ (1614000000UL) /* Maximum LO2 frequency (in Hz) */
920#define MT2063_MIN_UPC_FREQ (1396000000UL) /* Minimum LO1 frequency (in Hz) */
921#define MT2063_MAX_UPC_FREQ (2750000000UL) /* Maximum LO1 frequency (in Hz) */
922
923/*
924 * Define the supported Part/Rev codes for the MT2063
925 */
926#define MT2063_B0 (0x9B)
927#define MT2063_B1 (0x9C)
928#define MT2063_B2 (0x9D)
929#define MT2063_B3 (0x9E)
930
931/**
932 * mt2063_lockStatus - Checks to see if LO1 and LO2 are locked
933 *
934 * @state: struct mt2063_state pointer
935 *
936 * This function returns 0, if no lock, 1 if locked and a value < 1 if error
937 */
938static unsigned int mt2063_lockStatus(struct mt2063_state *state)
939{
940 const u32 nMaxWait = 100; /* wait a maximum of 100 msec */
941 const u32 nPollRate = 2; /* poll status bits every 2 ms */
942 const u32 nMaxLoops = nMaxWait / nPollRate;
943 const u8 LO1LK = 0x80;
944 u8 LO2LK = 0x08;
945 u32 status;
946 u32 nDelays = 0;
947
948 dprintk(2, "\n");
949
950 /* LO2 Lock bit was in a different place for B0 version */
951 if (state->tuner_id == MT2063_B0)
952 LO2LK = 0x40;
953
954 do {
955 status = mt2063_read(state, MT2063_REG_LO_STATUS,
956 &state->reg[MT2063_REG_LO_STATUS], 1);
957
958 if (status < 0)
959 return status;
960
961 if ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) ==
962 (LO1LK | LO2LK)) {
963 return TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO;
964 }
965 msleep(nPollRate); /* Wait between retries */
966 } while (++nDelays < nMaxLoops);
967
968 /*
969 * Got no lock or partial lock
970 */
971 return 0;
972}
973
974/*
975 * Constants for setting receiver modes.
976 * (6 modes defined at this time, enumerated by mt2063_delivery_sys)
977 * (DNC1GC & DNC2GC are the values, which are used, when the specific
978 * DNC Output is selected, the other is always off)
979 *
980 * enum mt2063_delivery_sys
981 * -------------+----------------------------------------------
982 * Mode 0 : | MT2063_CABLE_QAM
983 * Mode 1 : | MT2063_CABLE_ANALOG
984 * Mode 2 : | MT2063_OFFAIR_COFDM
985 * Mode 3 : | MT2063_OFFAIR_COFDM_SAWLESS
986 * Mode 4 : | MT2063_OFFAIR_ANALOG
987 * Mode 5 : | MT2063_OFFAIR_8VSB
988 * --------------+----------------------------------------------
989 *
990 * |<---------- Mode -------------->|
991 * Reg Field | 0 | 1 | 2 | 3 | 4 | 5 |
992 * ------------+-----+-----+-----+-----+-----+-----+
993 * RFAGCen | OFF | OFF | OFF | OFF | OFF | OFF
994 * LNARin | 0 | 0 | 3 | 3 | 3 | 3
995 * FIFFQen | 1 | 1 | 1 | 1 | 1 | 1
996 * FIFFq | 0 | 0 | 0 | 0 | 0 | 0
997 * DNC1gc | 0 | 0 | 0 | 0 | 0 | 0
998 * DNC2gc | 0 | 0 | 0 | 0 | 0 | 0
999 * GCU Auto | 1 | 1 | 1 | 1 | 1 | 1
1000 * LNA max Atn | 31 | 31 | 31 | 31 | 31 | 31
1001 * LNA Target | 44 | 43 | 43 | 43 | 43 | 43
1002 * ign RF Ovl | 0 | 0 | 0 | 0 | 0 | 0
1003 * RF max Atn | 31 | 31 | 31 | 31 | 31 | 31
1004 * PD1 Target | 36 | 36 | 38 | 38 | 36 | 38
1005 * ign FIF Ovl | 0 | 0 | 0 | 0 | 0 | 0
1006 * FIF max Atn | 5 | 5 | 5 | 5 | 5 | 5
1007 * PD2 Target | 40 | 33 | 42 | 42 | 33 | 42
1008 */
1009
1010enum mt2063_delivery_sys {
1011 MT2063_CABLE_QAM = 0,
1012 MT2063_CABLE_ANALOG,
1013 MT2063_OFFAIR_COFDM,
1014 MT2063_OFFAIR_COFDM_SAWLESS,
1015 MT2063_OFFAIR_ANALOG,
1016 MT2063_OFFAIR_8VSB,
1017 MT2063_NUM_RCVR_MODES
1018};
1019
1020static const char *mt2063_mode_name[] = {
1021 [MT2063_CABLE_QAM] = "digital cable",
1022 [MT2063_CABLE_ANALOG] = "analog cable",
1023 [MT2063_OFFAIR_COFDM] = "digital offair",
1024 [MT2063_OFFAIR_COFDM_SAWLESS] = "digital offair without SAW",
1025 [MT2063_OFFAIR_ANALOG] = "analog offair",
1026 [MT2063_OFFAIR_8VSB] = "analog offair 8vsb",
1027};
1028
1029static const u8 RFAGCEN[] = { 0, 0, 0, 0, 0, 0 };
1030static const u8 LNARIN[] = { 0, 0, 3, 3, 3, 3 };
1031static const u8 FIFFQEN[] = { 1, 1, 1, 1, 1, 1 };
1032static const u8 FIFFQ[] = { 0, 0, 0, 0, 0, 0 };
1033static const u8 DNC1GC[] = { 0, 0, 0, 0, 0, 0 };
1034static const u8 DNC2GC[] = { 0, 0, 0, 0, 0, 0 };
1035static const u8 ACLNAMAX[] = { 31, 31, 31, 31, 31, 31 };
1036static const u8 LNATGT[] = { 44, 43, 43, 43, 43, 43 };
1037static const u8 RFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1038static const u8 ACRFMAX[] = { 31, 31, 31, 31, 31, 31 };
1039static const u8 PD1TGT[] = { 36, 36, 38, 38, 36, 38 };
1040static const u8 FIFOVDIS[] = { 0, 0, 0, 0, 0, 0 };
1041static const u8 ACFIFMAX[] = { 29, 29, 29, 29, 29, 29 };
1042static const u8 PD2TGT[] = { 40, 33, 38, 42, 30, 38 };
1043
1044/*
1045 * mt2063_set_dnc_output_enable()
1046 */
1047static u32 mt2063_get_dnc_output_enable(struct mt2063_state *state,
1048 enum MT2063_DNC_Output_Enable *pValue)
1049{
1050 dprintk(2, "\n");
1051
1052 if ((state->reg[MT2063_REG_DNC_GAIN] & 0x03) == 0x03) { /* if DNC1 is off */
1053 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */
1054 *pValue = MT2063_DNC_NONE;
1055 else
1056 *pValue = MT2063_DNC_2;
1057 } else { /* DNC1 is on */
1058 if ((state->reg[MT2063_REG_VGA_GAIN] & 0x03) == 0x03) /* if DNC2 is off */
1059 *pValue = MT2063_DNC_1;
1060 else
1061 *pValue = MT2063_DNC_BOTH;
1062 }
1063 return 0;
1064}
1065
1066/*
1067 * mt2063_set_dnc_output_enable()
1068 */
1069static u32 mt2063_set_dnc_output_enable(struct mt2063_state *state,
1070 enum MT2063_DNC_Output_Enable nValue)
1071{
1072 u32 status = 0; /* Status to be returned */
1073 u8 val = 0;
1074
1075 dprintk(2, "\n");
1076
1077 /* selects, which DNC output is used */
1078 switch (nValue) {
1079 case MT2063_DNC_NONE:
1080 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03; /* Set DNC1GC=3 */
1081 if (state->reg[MT2063_REG_DNC_GAIN] !=
1082 val)
1083 status |=
1084 mt2063_setreg(state,
1085 MT2063_REG_DNC_GAIN,
1086 val);
1087
1088 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03; /* Set DNC2GC=3 */
1089 if (state->reg[MT2063_REG_VGA_GAIN] !=
1090 val)
1091 status |=
1092 mt2063_setreg(state,
1093 MT2063_REG_VGA_GAIN,
1094 val);
1095
1096 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
1097 if (state->reg[MT2063_REG_RSVD_20] !=
1098 val)
1099 status |=
1100 mt2063_setreg(state,
1101 MT2063_REG_RSVD_20,
1102 val);
1103
1104 break;
1105 case MT2063_DNC_1:
1106 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03); /* Set DNC1GC=x */
1107 if (state->reg[MT2063_REG_DNC_GAIN] !=
1108 val)
1109 status |=
1110 mt2063_setreg(state,
1111 MT2063_REG_DNC_GAIN,
1112 val);
1113
1114 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | 0x03; /* Set DNC2GC=3 */
1115 if (state->reg[MT2063_REG_VGA_GAIN] !=
1116 val)
1117 status |=
1118 mt2063_setreg(state,
1119 MT2063_REG_VGA_GAIN,
1120 val);
1121
1122 val = (state->reg[MT2063_REG_RSVD_20] & ~0x40); /* Set PD2MUX=0 */
1123 if (state->reg[MT2063_REG_RSVD_20] !=
1124 val)
1125 status |=
1126 mt2063_setreg(state,
1127 MT2063_REG_RSVD_20,
1128 val);
1129
1130 break;
1131 case MT2063_DNC_2:
1132 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | 0x03; /* Set DNC1GC=3 */
1133 if (state->reg[MT2063_REG_DNC_GAIN] !=
1134 val)
1135 status |=
1136 mt2063_setreg(state,
1137 MT2063_REG_DNC_GAIN,
1138 val);
1139
1140 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03); /* Set DNC2GC=x */
1141 if (state->reg[MT2063_REG_VGA_GAIN] !=
1142 val)
1143 status |=
1144 mt2063_setreg(state,
1145 MT2063_REG_VGA_GAIN,
1146 val);
1147
1148 val = (state->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */
1149 if (state->reg[MT2063_REG_RSVD_20] !=
1150 val)
1151 status |=
1152 mt2063_setreg(state,
1153 MT2063_REG_RSVD_20,
1154 val);
1155
1156 break;
1157 case MT2063_DNC_BOTH:
1158 val = (state->reg[MT2063_REG_DNC_GAIN] & 0xFC) | (DNC1GC[state->rcvr_mode] & 0x03); /* Set DNC1GC=x */
1159 if (state->reg[MT2063_REG_DNC_GAIN] !=
1160 val)
1161 status |=
1162 mt2063_setreg(state,
1163 MT2063_REG_DNC_GAIN,
1164 val);
1165
1166 val = (state->reg[MT2063_REG_VGA_GAIN] & 0xFC) | (DNC2GC[state->rcvr_mode] & 0x03); /* Set DNC2GC=x */
1167 if (state->reg[MT2063_REG_VGA_GAIN] !=
1168 val)
1169 status |=
1170 mt2063_setreg(state,
1171 MT2063_REG_VGA_GAIN,
1172 val);
1173
1174 val = (state->reg[MT2063_REG_RSVD_20] | 0x40); /* Set PD2MUX=1 */
1175 if (state->reg[MT2063_REG_RSVD_20] !=
1176 val)
1177 status |=
1178 mt2063_setreg(state,
1179 MT2063_REG_RSVD_20,
1180 val);
1181
1182 break;
1183 default:
1184 break;
1185 }
1186
1187 return status;
1188}
1189
1190/*
1191 * MT2063_SetReceiverMode() - Set the MT2063 receiver mode, according with
1192 * the selected enum mt2063_delivery_sys type.
1193 *
1194 * (DNC1GC & DNC2GC are the values, which are used, when the specific
1195 * DNC Output is selected, the other is always off)
1196 *
1197 * @state: ptr to mt2063_state structure
1198 * @Mode: desired reciever delivery system
1199 *
1200 * Note: Register cache must be valid for it to work
1201 */
1202
1203static u32 MT2063_SetReceiverMode(struct mt2063_state *state,
1204 enum mt2063_delivery_sys Mode)
1205{
1206 u32 status = 0; /* Status to be returned */
1207 u8 val;
1208 u32 longval;
1209
1210 dprintk(2, "\n");
1211
1212 if (Mode >= MT2063_NUM_RCVR_MODES)
1213 status = -ERANGE;
1214
1215 /* RFAGCen */
1216 if (status >= 0) {
1217 val =
1218 (state->
1219 reg[MT2063_REG_PD1_TGT] & (u8) ~0x40) | (RFAGCEN[Mode]
1220 ? 0x40 :
1221 0x00);
1222 if (state->reg[MT2063_REG_PD1_TGT] != val)
1223 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1224 }
1225
1226 /* LNARin */
1227 if (status >= 0) {
1228 u8 val = (state->reg[MT2063_REG_CTRL_2C] & (u8) ~0x03) |
1229 (LNARIN[Mode] & 0x03);
1230 if (state->reg[MT2063_REG_CTRL_2C] != val)
1231 status |= mt2063_setreg(state, MT2063_REG_CTRL_2C, val);
1232 }
1233
1234 /* FIFFQEN and FIFFQ */
1235 if (status >= 0) {
1236 val =
1237 (state->
1238 reg[MT2063_REG_FIFF_CTRL2] & (u8) ~0xF0) |
1239 (FIFFQEN[Mode] << 7) | (FIFFQ[Mode] << 4);
1240 if (state->reg[MT2063_REG_FIFF_CTRL2] != val) {
1241 status |=
1242 mt2063_setreg(state, MT2063_REG_FIFF_CTRL2, val);
1243 /* trigger FIFF calibration, needed after changing FIFFQ */
1244 val =
1245 (state->reg[MT2063_REG_FIFF_CTRL] | (u8) 0x01);
1246 status |=
1247 mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1248 val =
1249 (state->
1250 reg[MT2063_REG_FIFF_CTRL] & (u8) ~0x01);
1251 status |=
1252 mt2063_setreg(state, MT2063_REG_FIFF_CTRL, val);
1253 }
1254 }
1255
1256 /* DNC1GC & DNC2GC */
1257 status |= mt2063_get_dnc_output_enable(state, &longval);
1258 status |= mt2063_set_dnc_output_enable(state, longval);
1259
1260 /* acLNAmax */
1261 if (status >= 0) {
1262 u8 val = (state->reg[MT2063_REG_LNA_OV] & (u8) ~0x1F) |
1263 (ACLNAMAX[Mode] & 0x1F);
1264 if (state->reg[MT2063_REG_LNA_OV] != val)
1265 status |= mt2063_setreg(state, MT2063_REG_LNA_OV, val);
1266 }
1267
1268 /* LNATGT */
1269 if (status >= 0) {
1270 u8 val = (state->reg[MT2063_REG_LNA_TGT] & (u8) ~0x3F) |
1271 (LNATGT[Mode] & 0x3F);
1272 if (state->reg[MT2063_REG_LNA_TGT] != val)
1273 status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1274 }
1275
1276 /* ACRF */
1277 if (status >= 0) {
1278 u8 val = (state->reg[MT2063_REG_RF_OV] & (u8) ~0x1F) |
1279 (ACRFMAX[Mode] & 0x1F);
1280 if (state->reg[MT2063_REG_RF_OV] != val)
1281 status |= mt2063_setreg(state, MT2063_REG_RF_OV, val);
1282 }
1283
1284 /* PD1TGT */
1285 if (status >= 0) {
1286 u8 val = (state->reg[MT2063_REG_PD1_TGT] & (u8) ~0x3F) |
1287 (PD1TGT[Mode] & 0x3F);
1288 if (state->reg[MT2063_REG_PD1_TGT] != val)
1289 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1290 }
1291
1292 /* FIFATN */
1293 if (status >= 0) {
1294 u8 val = ACFIFMAX[Mode];
1295 if (state->reg[MT2063_REG_PART_REV] != MT2063_B3 && val > 5)
1296 val = 5;
1297 val = (state->reg[MT2063_REG_FIF_OV] & (u8) ~0x1F) |
1298 (val & 0x1F);
1299 if (state->reg[MT2063_REG_FIF_OV] != val)
1300 status |= mt2063_setreg(state, MT2063_REG_FIF_OV, val);
1301 }
1302
1303 /* PD2TGT */
1304 if (status >= 0) {
1305 u8 val = (state->reg[MT2063_REG_PD2_TGT] & (u8) ~0x3F) |
1306 (PD2TGT[Mode] & 0x3F);
1307 if (state->reg[MT2063_REG_PD2_TGT] != val)
1308 status |= mt2063_setreg(state, MT2063_REG_PD2_TGT, val);
1309 }
1310
1311 /* Ignore ATN Overload */
1312 if (status >= 0) {
1313 val = (state->reg[MT2063_REG_LNA_TGT] & (u8) ~0x80) |
1314 (RFOVDIS[Mode] ? 0x80 : 0x00);
1315 if (state->reg[MT2063_REG_LNA_TGT] != val)
1316 status |= mt2063_setreg(state, MT2063_REG_LNA_TGT, val);
1317 }
1318
1319 /* Ignore FIF Overload */
1320 if (status >= 0) {
1321 val = (state->reg[MT2063_REG_PD1_TGT] & (u8) ~0x80) |
1322 (FIFOVDIS[Mode] ? 0x80 : 0x00);
1323 if (state->reg[MT2063_REG_PD1_TGT] != val)
1324 status |= mt2063_setreg(state, MT2063_REG_PD1_TGT, val);
1325 }
1326
1327 if (status >= 0) {
1328 state->rcvr_mode = Mode;
1329 dprintk(1, "mt2063 mode changed to %s\n",
1330 mt2063_mode_name[state->rcvr_mode]);
1331 }
1332
1333 return status;
1334}
1335
1336/*
1337 * MT2063_ClearPowerMaskBits () - Clears the power-down mask bits for various
1338 * sections of the MT2063
1339 *
1340 * @Bits: Mask bits to be cleared.
1341 *
1342 * See definition of MT2063_Mask_Bits type for description
1343 * of each of the power bits.
1344 */
1345static u32 MT2063_ClearPowerMaskBits(struct mt2063_state *state,
1346 enum MT2063_Mask_Bits Bits)
1347{
1348 u32 status = 0;
1349
1350 dprintk(2, "\n");
1351 Bits = (enum MT2063_Mask_Bits)(Bits & MT2063_ALL_SD); /* Only valid bits for this tuner */
1352 if ((Bits & 0xFF00) != 0) {
1353 state->reg[MT2063_REG_PWR_2] &= ~(u8) (Bits >> 8);
1354 status |=
1355 mt2063_write(state,
1356 MT2063_REG_PWR_2,
1357 &state->reg[MT2063_REG_PWR_2], 1);
1358 }
1359 if ((Bits & 0xFF) != 0) {
1360 state->reg[MT2063_REG_PWR_1] &= ~(u8) (Bits & 0xFF);
1361 status |=
1362 mt2063_write(state,
1363 MT2063_REG_PWR_1,
1364 &state->reg[MT2063_REG_PWR_1], 1);
1365 }
1366
1367 return status;
1368}
1369
1370/*
1371 * MT2063_SoftwareShutdown() - Enables or disables software shutdown function.
1372 * When Shutdown is 1, any section whose power
1373 * mask is set will be shutdown.
1374 */
1375static u32 MT2063_SoftwareShutdown(struct mt2063_state *state, u8 Shutdown)
1376{
1377 u32 status;
1378
1379 dprintk(2, "\n");
1380 if (Shutdown == 1)
1381 state->reg[MT2063_REG_PWR_1] |= 0x04;
1382 else
1383 state->reg[MT2063_REG_PWR_1] &= ~0x04;
1384
1385 status = mt2063_write(state,
1386 MT2063_REG_PWR_1,
1387 &state->reg[MT2063_REG_PWR_1], 1);
1388
1389 if (Shutdown != 1) {
1390 state->reg[MT2063_REG_BYP_CTRL] =
1391 (state->reg[MT2063_REG_BYP_CTRL] & 0x9F) | 0x40;
1392 status |=
1393 mt2063_write(state,
1394 MT2063_REG_BYP_CTRL,
1395 &state->reg[MT2063_REG_BYP_CTRL],
1396 1);
1397 state->reg[MT2063_REG_BYP_CTRL] =
1398 (state->reg[MT2063_REG_BYP_CTRL] & 0x9F);
1399 status |=
1400 mt2063_write(state,
1401 MT2063_REG_BYP_CTRL,
1402 &state->reg[MT2063_REG_BYP_CTRL],
1403 1);
1404 }
1405
1406 return status;
1407}
1408
1409static u32 MT2063_Round_fLO(u32 f_LO, u32 f_LO_Step, u32 f_ref)
1410{
1411 return f_ref * (f_LO / f_ref)
1412 + f_LO_Step * (((f_LO % f_ref) + (f_LO_Step / 2)) / f_LO_Step);
1413}
1414
1415/**
1416 * fLO_FractionalTerm() - Calculates the portion contributed by FracN / denom.
1417 * This function preserves maximum precision without
1418 * risk of overflow. It accurately calculates
1419 * f_ref * num / denom to within 1 HZ with fixed math.
1420 *
1421 * @num : Fractional portion of the multiplier
1422 * @denom: denominator portion of the ratio
1423 * @f_Ref: SRO frequency.
1424 *
1425 * This calculation handles f_ref as two separate 14-bit fields.
1426 * Therefore, a maximum value of 2^28-1 may safely be used for f_ref.
1427 * This is the genesis of the magic number "14" and the magic mask value of
1428 * 0x03FFF.
1429 *
1430 * This routine successfully handles denom values up to and including 2^18.
1431 * Returns: f_ref * num / denom
1432 */
1433static u32 MT2063_fLO_FractionalTerm(u32 f_ref, u32 num, u32 denom)
1434{
1435 u32 t1 = (f_ref >> 14) * num;
1436 u32 term1 = t1 / denom;
1437 u32 loss = t1 % denom;
1438 u32 term2 =
1439 (((f_ref & 0x00003FFF) * num + (loss << 14)) + (denom / 2)) / denom;
1440 return (term1 << 14) + term2;
1441}
1442
1443/*
1444 * CalcLO1Mult()- Calculates Integer divider value and the numerator
1445 * value for a FracN PLL.
1446 *
1447 * This function assumes that the f_LO and f_Ref are
1448 * evenly divisible by f_LO_Step.
1449 *
1450 * @Div: OUTPUT: Whole number portion of the multiplier
1451 * @FracN: OUTPUT: Fractional portion of the multiplier
1452 * @f_LO: desired LO frequency.
1453 * @f_LO_Step: Minimum step size for the LO (in Hz).
1454 * @f_Ref: SRO frequency.
1455 * @f_Avoid: Range of PLL frequencies to avoid near integer multiples
1456 * of f_Ref (in Hz).
1457 *
1458 * Returns: Recalculated LO frequency.
1459 */
1460static u32 MT2063_CalcLO1Mult(u32 *Div,
1461 u32 *FracN,
1462 u32 f_LO,
1463 u32 f_LO_Step, u32 f_Ref)
1464{
1465 /* Calculate the whole number portion of the divider */
1466 *Div = f_LO / f_Ref;
1467
1468 /* Calculate the numerator value (round to nearest f_LO_Step) */
1469 *FracN =
1470 (64 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1471 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1472
1473 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN, 64);
1474}
1475
1476/**
1477 * CalcLO2Mult() - Calculates Integer divider value and the numerator
1478 * value for a FracN PLL.
1479 *
1480 * This function assumes that the f_LO and f_Ref are
1481 * evenly divisible by f_LO_Step.
1482 *
1483 * @Div: OUTPUT: Whole number portion of the multiplier
1484 * @FracN: OUTPUT: Fractional portion of the multiplier
1485 * @f_LO: desired LO frequency.
1486 * @f_LO_Step: Minimum step size for the LO (in Hz).
1487 * @f_Ref: SRO frequency.
1488 * @f_Avoid: Range of PLL frequencies to avoid near
1489 * integer multiples of f_Ref (in Hz).
1490 *
1491 * Returns: Recalculated LO frequency.
1492 */
1493static u32 MT2063_CalcLO2Mult(u32 *Div,
1494 u32 *FracN,
1495 u32 f_LO,
1496 u32 f_LO_Step, u32 f_Ref)
1497{
1498 /* Calculate the whole number portion of the divider */
1499 *Div = f_LO / f_Ref;
1500
1501 /* Calculate the numerator value (round to nearest f_LO_Step) */
1502 *FracN =
1503 (8191 * (((f_LO % f_Ref) + (f_LO_Step / 2)) / f_LO_Step) +
1504 (f_Ref / f_LO_Step / 2)) / (f_Ref / f_LO_Step);
1505
1506 return (f_Ref * (*Div)) + MT2063_fLO_FractionalTerm(f_Ref, *FracN,
1507 8191);
1508}
1509
1510/*
1511 * FindClearTuneFilter() - Calculate the corrrect ClearTune filter to be
1512 * used for a given input frequency.
1513 *
1514 * @state: ptr to tuner data structure
1515 * @f_in: RF input center frequency (in Hz).
1516 *
1517 * Returns: ClearTune filter number (0-31)
1518 */
1519static u32 FindClearTuneFilter(struct mt2063_state *state, u32 f_in)
1520{
1521 u32 RFBand;
1522 u32 idx; /* index loop */
1523
1524 /*
1525 ** Find RF Band setting
1526 */
1527 RFBand = 31; /* def when f_in > all */
1528 for (idx = 0; idx < 31; ++idx) {
1529 if (state->CTFiltMax[idx] >= f_in) {
1530 RFBand = idx;
1531 break;
1532 }
1533 }
1534 return RFBand;
1535}
1536
1537/*
1538 * MT2063_Tune() - Change the tuner's tuned frequency to RFin.
1539 */
1540static u32 MT2063_Tune(struct mt2063_state *state, u32 f_in)
1541{ /* RF input center frequency */
1542
1543 u32 status = 0;
1544 u32 LO1; /* 1st LO register value */
1545 u32 Num1; /* Numerator for LO1 reg. value */
1546 u32 f_IF1; /* 1st IF requested */
1547 u32 LO2; /* 2nd LO register value */
1548 u32 Num2; /* Numerator for LO2 reg. value */
1549 u32 ofLO1, ofLO2; /* last time's LO frequencies */
1550 u8 fiffc = 0x80; /* FIFF center freq from tuner */
1551 u32 fiffof; /* Offset from FIFF center freq */
1552 const u8 LO1LK = 0x80; /* Mask for LO1 Lock bit */
1553 u8 LO2LK = 0x08; /* Mask for LO2 Lock bit */
1554 u8 val;
1555 u32 RFBand;
1556
1557 dprintk(2, "\n");
1558 /* Check the input and output frequency ranges */
1559 if ((f_in < MT2063_MIN_FIN_FREQ) || (f_in > MT2063_MAX_FIN_FREQ))
1560 return -EINVAL;
1561
1562 if ((state->AS_Data.f_out < MT2063_MIN_FOUT_FREQ)
1563 || (state->AS_Data.f_out > MT2063_MAX_FOUT_FREQ))
1564 return -EINVAL;
1565
1566 /*
1567 * Save original LO1 and LO2 register values
1568 */
1569 ofLO1 = state->AS_Data.f_LO1;
1570 ofLO2 = state->AS_Data.f_LO2;
1571
1572 /*
1573 * Find and set RF Band setting
1574 */
1575 if (state->ctfilt_sw == 1) {
1576 val = (state->reg[MT2063_REG_CTUNE_CTRL] | 0x08);
1577 if (state->reg[MT2063_REG_CTUNE_CTRL] != val) {
1578 status |=
1579 mt2063_setreg(state, MT2063_REG_CTUNE_CTRL, val);
1580 }
1581 val = state->reg[MT2063_REG_CTUNE_OV];
1582 RFBand = FindClearTuneFilter(state, f_in);
1583 state->reg[MT2063_REG_CTUNE_OV] =
1584 (u8) ((state->reg[MT2063_REG_CTUNE_OV] & ~0x1F)
1585 | RFBand);
1586 if (state->reg[MT2063_REG_CTUNE_OV] != val) {
1587 status |=
1588 mt2063_setreg(state, MT2063_REG_CTUNE_OV, val);
1589 }
1590 }
1591
1592 /*
1593 * Read the FIFF Center Frequency from the tuner
1594 */
1595 if (status >= 0) {
1596 status |=
1597 mt2063_read(state,
1598 MT2063_REG_FIFFC,
1599 &state->reg[MT2063_REG_FIFFC], 1);
1600 fiffc = state->reg[MT2063_REG_FIFFC];
1601 }
1602 /*
1603 * Assign in the requested values
1604 */
1605 state->AS_Data.f_in = f_in;
1606 /* Request a 1st IF such that LO1 is on a step size */
1607 state->AS_Data.f_if1_Request =
1608 MT2063_Round_fLO(state->AS_Data.f_if1_Request + f_in,
1609 state->AS_Data.f_LO1_Step,
1610 state->AS_Data.f_ref) - f_in;
1611
1612 /*
1613 * Calculate frequency settings. f_IF1_FREQ + f_in is the
1614 * desired LO1 frequency
1615 */
1616 MT2063_ResetExclZones(&state->AS_Data);
1617
1618 f_IF1 = MT2063_ChooseFirstIF(&state->AS_Data);
1619
1620 state->AS_Data.f_LO1 =
1621 MT2063_Round_fLO(f_IF1 + f_in, state->AS_Data.f_LO1_Step,
1622 state->AS_Data.f_ref);
1623
1624 state->AS_Data.f_LO2 =
1625 MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1626 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1627
1628 /*
1629 * Check for any LO spurs in the output bandwidth and adjust
1630 * the LO settings to avoid them if needed
1631 */
1632 status |= MT2063_AvoidSpurs(&state->AS_Data);
1633 /*
1634 * MT_AvoidSpurs spurs may have changed the LO1 & LO2 values.
1635 * Recalculate the LO frequencies and the values to be placed
1636 * in the tuning registers.
1637 */
1638 state->AS_Data.f_LO1 =
1639 MT2063_CalcLO1Mult(&LO1, &Num1, state->AS_Data.f_LO1,
1640 state->AS_Data.f_LO1_Step, state->AS_Data.f_ref);
1641 state->AS_Data.f_LO2 =
1642 MT2063_Round_fLO(state->AS_Data.f_LO1 - state->AS_Data.f_out - f_in,
1643 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1644 state->AS_Data.f_LO2 =
1645 MT2063_CalcLO2Mult(&LO2, &Num2, state->AS_Data.f_LO2,
1646 state->AS_Data.f_LO2_Step, state->AS_Data.f_ref);
1647
1648 /*
1649 * Check the upconverter and downconverter frequency ranges
1650 */
1651 if ((state->AS_Data.f_LO1 < MT2063_MIN_UPC_FREQ)
1652 || (state->AS_Data.f_LO1 > MT2063_MAX_UPC_FREQ))
1653 status |= MT2063_UPC_RANGE;
1654 if ((state->AS_Data.f_LO2 < MT2063_MIN_DNC_FREQ)
1655 || (state->AS_Data.f_LO2 > MT2063_MAX_DNC_FREQ))
1656 status |= MT2063_DNC_RANGE;
1657 /* LO2 Lock bit was in a different place for B0 version */
1658 if (state->tuner_id == MT2063_B0)
1659 LO2LK = 0x40;
1660
1661 /*
1662 * If we have the same LO frequencies and we're already locked,
1663 * then skip re-programming the LO registers.
1664 */
1665 if ((ofLO1 != state->AS_Data.f_LO1)
1666 || (ofLO2 != state->AS_Data.f_LO2)
1667 || ((state->reg[MT2063_REG_LO_STATUS] & (LO1LK | LO2LK)) !=
1668 (LO1LK | LO2LK))) {
1669 /*
1670 * Calculate the FIFFOF register value
1671 *
1672 * IF1_Actual
1673 * FIFFOF = ------------ - 8 * FIFFC - 4992
1674 * f_ref/64
1675 */
1676 fiffof =
1677 (state->AS_Data.f_LO1 -
1678 f_in) / (state->AS_Data.f_ref / 64) - 8 * (u32) fiffc -
1679 4992;
1680 if (fiffof > 0xFF)
1681 fiffof = 0xFF;
1682
1683 /*
1684 * Place all of the calculated values into the local tuner
1685 * register fields.
1686 */
1687 if (status >= 0) {
1688 state->reg[MT2063_REG_LO1CQ_1] = (u8) (LO1 & 0xFF); /* DIV1q */
1689 state->reg[MT2063_REG_LO1CQ_2] = (u8) (Num1 & 0x3F); /* NUM1q */
1690 state->reg[MT2063_REG_LO2CQ_1] = (u8) (((LO2 & 0x7F) << 1) /* DIV2q */
1691 |(Num2 >> 12)); /* NUM2q (hi) */
1692 state->reg[MT2063_REG_LO2CQ_2] = (u8) ((Num2 & 0x0FF0) >> 4); /* NUM2q (mid) */
1693 state->reg[MT2063_REG_LO2CQ_3] = (u8) (0xE0 | (Num2 & 0x000F)); /* NUM2q (lo) */
1694
1695 /*
1696 * Now write out the computed register values
1697 * IMPORTANT: There is a required order for writing
1698 * (0x05 must follow all the others).
1699 */
1700 status |= mt2063_write(state, MT2063_REG_LO1CQ_1, &state->reg[MT2063_REG_LO1CQ_1], 5); /* 0x01 - 0x05 */
1701 if (state->tuner_id == MT2063_B0) {
1702 /* Re-write the one-shot bits to trigger the tune operation */
1703 status |= mt2063_write(state, MT2063_REG_LO2CQ_3, &state->reg[MT2063_REG_LO2CQ_3], 1); /* 0x05 */
1704 }
1705 /* Write out the FIFF offset only if it's changing */
1706 if (state->reg[MT2063_REG_FIFF_OFFSET] !=
1707 (u8) fiffof) {
1708 state->reg[MT2063_REG_FIFF_OFFSET] =
1709 (u8) fiffof;
1710 status |=
1711 mt2063_write(state,
1712 MT2063_REG_FIFF_OFFSET,
1713 &state->
1714 reg[MT2063_REG_FIFF_OFFSET],
1715 1);
1716 }
1717 }
1718
1719 /*
1720 * Check for LO's locking
1721 */
1722
1723 if (status < 0)
1724 return status;
1725
1726 status = mt2063_lockStatus(state);
1727 if (status < 0)
1728 return status;
1729 if (!status)
1730 return -EINVAL; /* Couldn't lock */
1731
1732 /*
1733 * If we locked OK, assign calculated data to mt2063_state structure
1734 */
1735 state->f_IF1_actual = state->AS_Data.f_LO1 - f_in;
1736 }
1737
1738 return status;
1739}
1740
1741static const u8 MT2063B0_defaults[] = {
1742 /* Reg, Value */
1743 0x19, 0x05,
1744 0x1B, 0x1D,
1745 0x1C, 0x1F,
1746 0x1D, 0x0F,
1747 0x1E, 0x3F,
1748 0x1F, 0x0F,
1749 0x20, 0x3F,
1750 0x22, 0x21,
1751 0x23, 0x3F,
1752 0x24, 0x20,
1753 0x25, 0x3F,
1754 0x27, 0xEE,
1755 0x2C, 0x27, /* bit at 0x20 is cleared below */
1756 0x30, 0x03,
1757 0x2C, 0x07, /* bit at 0x20 is cleared here */
1758 0x2D, 0x87,
1759 0x2E, 0xAA,
1760 0x28, 0xE1, /* Set the FIFCrst bit here */
1761 0x28, 0xE0, /* Clear the FIFCrst bit here */
1762 0x00
1763};
1764
1765/* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
1766static const u8 MT2063B1_defaults[] = {
1767 /* Reg, Value */
1768 0x05, 0xF0,
1769 0x11, 0x10, /* New Enable AFCsd */
1770 0x19, 0x05,
1771 0x1A, 0x6C,
1772 0x1B, 0x24,
1773 0x1C, 0x28,
1774 0x1D, 0x8F,
1775 0x1E, 0x14,
1776 0x1F, 0x8F,
1777 0x20, 0x57,
1778 0x22, 0x21, /* New - ver 1.03 */
1779 0x23, 0x3C, /* New - ver 1.10 */
1780 0x24, 0x20, /* New - ver 1.03 */
1781 0x2C, 0x24, /* bit at 0x20 is cleared below */
1782 0x2D, 0x87, /* FIFFQ=0 */
1783 0x2F, 0xF3,
1784 0x30, 0x0C, /* New - ver 1.11 */
1785 0x31, 0x1B, /* New - ver 1.11 */
1786 0x2C, 0x04, /* bit at 0x20 is cleared here */
1787 0x28, 0xE1, /* Set the FIFCrst bit here */
1788 0x28, 0xE0, /* Clear the FIFCrst bit here */
1789 0x00
1790};
1791
1792/* writing 0x05 0xf0 sw-resets all registers, so we write only needed changes */
1793static const u8 MT2063B3_defaults[] = {
1794 /* Reg, Value */
1795 0x05, 0xF0,
1796 0x19, 0x3D,
1797 0x2C, 0x24, /* bit at 0x20 is cleared below */
1798 0x2C, 0x04, /* bit at 0x20 is cleared here */
1799 0x28, 0xE1, /* Set the FIFCrst bit here */
1800 0x28, 0xE0, /* Clear the FIFCrst bit here */
1801 0x00
1802};
1803
1804static int mt2063_init(struct dvb_frontend *fe)
1805{
1806 u32 status;
1807 struct mt2063_state *state = fe->tuner_priv;
1808 u8 all_resets = 0xF0; /* reset/load bits */
1809 const u8 *def = NULL;
1810 char *step;
1811 u32 FCRUN;
1812 s32 maxReads;
1813 u32 fcu_osc;
1814 u32 i;
1815
1816 dprintk(2, "\n");
1817
1818 state->rcvr_mode = MT2063_CABLE_QAM;
1819
1820 /* Read the Part/Rev code from the tuner */
1821 status = mt2063_read(state, MT2063_REG_PART_REV,
1822 &state->reg[MT2063_REG_PART_REV], 1);
1823 if (status < 0) {
1824 printk(KERN_ERR "Can't read mt2063 part ID\n");
1825 return status;
1826 }
1827
1828 /* Check the part/rev code */
1829 switch (state->reg[MT2063_REG_PART_REV]) {
1830 case MT2063_B0:
1831 step = "B0";
1832 break;
1833 case MT2063_B1:
1834 step = "B1";
1835 break;
1836 case MT2063_B2:
1837 step = "B2";
1838 break;
1839 case MT2063_B3:
1840 step = "B3";
1841 break;
1842 default:
1843 printk(KERN_ERR "mt2063: Unknown mt2063 device ID (0x%02x)\n",
1844 state->reg[MT2063_REG_PART_REV]);
1845 return -ENODEV; /* Wrong tuner Part/Rev code */
1846 }
1847
1848 /* Check the 2nd byte of the Part/Rev code from the tuner */
1849 status = mt2063_read(state, MT2063_REG_RSVD_3B,
1850 &state->reg[MT2063_REG_RSVD_3B], 1);
1851
1852 /* b7 != 0 ==> NOT MT2063 */
1853 if (status < 0 || ((state->reg[MT2063_REG_RSVD_3B] & 0x80) != 0x00)) {
1854 printk(KERN_ERR "mt2063: Unknown part ID (0x%02x%02x)\n",
1855 state->reg[MT2063_REG_PART_REV],
1856 state->reg[MT2063_REG_RSVD_3B]);
1857 return -ENODEV; /* Wrong tuner Part/Rev code */
1858 }
1859
1860 printk(KERN_INFO "mt2063: detected a mt2063 %s\n", step);
1861
1862 /* Reset the tuner */
1863 status = mt2063_write(state, MT2063_REG_LO2CQ_3, &all_resets, 1);
1864 if (status < 0)
1865 return status;
1866
1867 /* change all of the default values that vary from the HW reset values */
1868 /* def = (state->reg[PART_REV] == MT2063_B0) ? MT2063B0_defaults : MT2063B1_defaults; */
1869 switch (state->reg[MT2063_REG_PART_REV]) {
1870 case MT2063_B3:
1871 def = MT2063B3_defaults;
1872 break;
1873
1874 case MT2063_B1:
1875 def = MT2063B1_defaults;
1876 break;
1877
1878 case MT2063_B0:
1879 def = MT2063B0_defaults;
1880 break;
1881
1882 default:
1883 return -ENODEV;
1884 break;
1885 }
1886
1887 while (status >= 0 && *def) {
1888 u8 reg = *def++;
1889 u8 val = *def++;
1890 status = mt2063_write(state, reg, &val, 1);
1891 }
1892 if (status < 0)
1893 return status;
1894
1895 /* Wait for FIFF location to complete. */
1896 FCRUN = 1;
1897 maxReads = 10;
1898 while (status >= 0 && (FCRUN != 0) && (maxReads-- > 0)) {
1899 msleep(2);
1900 status = mt2063_read(state,
1901 MT2063_REG_XO_STATUS,
1902 &state->
1903 reg[MT2063_REG_XO_STATUS], 1);
1904 FCRUN = (state->reg[MT2063_REG_XO_STATUS] & 0x40) >> 6;
1905 }
1906
1907 if (FCRUN != 0 || status < 0)
1908 return -ENODEV;
1909
1910 status = mt2063_read(state,
1911 MT2063_REG_FIFFC,
1912 &state->reg[MT2063_REG_FIFFC], 1);
1913 if (status < 0)
1914 return status;
1915
1916 /* Read back all the registers from the tuner */
1917 status = mt2063_read(state,
1918 MT2063_REG_PART_REV,
1919 state->reg, MT2063_REG_END_REGS);
1920 if (status < 0)
1921 return status;
1922
1923 /* Initialize the tuner state. */
1924 state->tuner_id = state->reg[MT2063_REG_PART_REV];
1925 state->AS_Data.f_ref = MT2063_REF_FREQ;
1926 state->AS_Data.f_if1_Center = (state->AS_Data.f_ref / 8) *
1927 ((u32) state->reg[MT2063_REG_FIFFC] + 640);
1928 state->AS_Data.f_if1_bw = MT2063_IF1_BW;
1929 state->AS_Data.f_out = 43750000UL;
1930 state->AS_Data.f_out_bw = 6750000UL;
1931 state->AS_Data.f_zif_bw = MT2063_ZIF_BW;
1932 state->AS_Data.f_LO1_Step = state->AS_Data.f_ref / 64;
1933 state->AS_Data.f_LO2_Step = MT2063_TUNE_STEP_SIZE;
1934 state->AS_Data.maxH1 = MT2063_MAX_HARMONICS_1;
1935 state->AS_Data.maxH2 = MT2063_MAX_HARMONICS_2;
1936 state->AS_Data.f_min_LO_Separation = MT2063_MIN_LO_SEP;
1937 state->AS_Data.f_if1_Request = state->AS_Data.f_if1_Center;
1938 state->AS_Data.f_LO1 = 2181000000UL;
1939 state->AS_Data.f_LO2 = 1486249786UL;
1940 state->f_IF1_actual = state->AS_Data.f_if1_Center;
1941 state->AS_Data.f_in = state->AS_Data.f_LO1 - state->f_IF1_actual;
1942 state->AS_Data.f_LO1_FracN_Avoid = MT2063_LO1_FRACN_AVOID;
1943 state->AS_Data.f_LO2_FracN_Avoid = MT2063_LO2_FRACN_AVOID;
1944 state->num_regs = MT2063_REG_END_REGS;
1945 state->AS_Data.avoidDECT = MT2063_AVOID_BOTH;
1946 state->ctfilt_sw = 0;
1947
1948 state->CTFiltMax[0] = 69230000;
1949 state->CTFiltMax[1] = 105770000;
1950 state->CTFiltMax[2] = 140350000;
1951 state->CTFiltMax[3] = 177110000;
1952 state->CTFiltMax[4] = 212860000;
1953 state->CTFiltMax[5] = 241130000;
1954 state->CTFiltMax[6] = 274370000;
1955 state->CTFiltMax[7] = 309820000;
1956 state->CTFiltMax[8] = 342450000;
1957 state->CTFiltMax[9] = 378870000;
1958 state->CTFiltMax[10] = 416210000;
1959 state->CTFiltMax[11] = 456500000;
1960 state->CTFiltMax[12] = 495790000;
1961 state->CTFiltMax[13] = 534530000;
1962 state->CTFiltMax[14] = 572610000;
1963 state->CTFiltMax[15] = 598970000;
1964 state->CTFiltMax[16] = 635910000;
1965 state->CTFiltMax[17] = 672130000;
1966 state->CTFiltMax[18] = 714840000;
1967 state->CTFiltMax[19] = 739660000;
1968 state->CTFiltMax[20] = 770410000;
1969 state->CTFiltMax[21] = 814660000;
1970 state->CTFiltMax[22] = 846950000;
1971 state->CTFiltMax[23] = 867820000;
1972 state->CTFiltMax[24] = 915980000;
1973 state->CTFiltMax[25] = 947450000;
1974 state->CTFiltMax[26] = 983110000;
1975 state->CTFiltMax[27] = 1021630000;
1976 state->CTFiltMax[28] = 1061870000;
1977 state->CTFiltMax[29] = 1098330000;
1978 state->CTFiltMax[30] = 1138990000;
1979
1980 /*
1981 ** Fetch the FCU osc value and use it and the fRef value to
1982 ** scale all of the Band Max values
1983 */
1984
1985 state->reg[MT2063_REG_CTUNE_CTRL] = 0x0A;
1986 status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
1987 &state->reg[MT2063_REG_CTUNE_CTRL], 1);
1988 if (status < 0)
1989 return status;
1990
1991 /* Read the ClearTune filter calibration value */
1992 status = mt2063_read(state, MT2063_REG_FIFFC,
1993 &state->reg[MT2063_REG_FIFFC], 1);
1994 if (status < 0)
1995 return status;
1996
1997 fcu_osc = state->reg[MT2063_REG_FIFFC];
1998
1999 state->reg[MT2063_REG_CTUNE_CTRL] = 0x00;
2000 status = mt2063_write(state, MT2063_REG_CTUNE_CTRL,
2001 &state->reg[MT2063_REG_CTUNE_CTRL], 1);
2002 if (status < 0)
2003 return status;
2004
2005 /* Adjust each of the values in the ClearTune filter cross-over table */
2006 for (i = 0; i < 31; i++)
2007 state->CTFiltMax[i] = (state->CTFiltMax[i] / 768) * (fcu_osc + 640);
2008
2009 status = MT2063_SoftwareShutdown(state, 1);
2010 if (status < 0)
2011 return status;
2012 status = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2013 if (status < 0)
2014 return status;
2015
2016 state->init = true;
2017
2018 return 0;
2019}
2020
2021static int mt2063_get_status(struct dvb_frontend *fe, u32 *tuner_status)
2022{
2023 struct mt2063_state *state = fe->tuner_priv;
2024 int status;
2025
2026 dprintk(2, "\n");
2027
2028 if (!state->init)
2029 return -ENODEV;
2030
2031 *tuner_status = 0;
2032 status = mt2063_lockStatus(state);
2033 if (status < 0)
2034 return status;
2035 if (status)
2036 *tuner_status = TUNER_STATUS_LOCKED;
2037
2038 dprintk(1, "Tuner status: %d", *tuner_status);
2039
2040 return 0;
2041}
2042
2043static int mt2063_release(struct dvb_frontend *fe)
2044{
2045 struct mt2063_state *state = fe->tuner_priv;
2046
2047 dprintk(2, "\n");
2048
2049 fe->tuner_priv = NULL;
2050 kfree(state);
2051
2052 return 0;
2053}
2054
2055static int mt2063_set_analog_params(struct dvb_frontend *fe,
2056 struct analog_parameters *params)
2057{
2058 struct mt2063_state *state = fe->tuner_priv;
2059 s32 pict_car;
2060 s32 pict2chanb_vsb;
2061 s32 ch_bw;
2062 s32 if_mid;
2063 s32 rcvr_mode;
2064 int status;
2065
2066 dprintk(2, "\n");
2067
2068 if (!state->init) {
2069 status = mt2063_init(fe);
2070 if (status < 0)
2071 return status;
2072 }
2073
2074 switch (params->mode) {
2075 case V4L2_TUNER_RADIO:
2076 pict_car = 38900000;
2077 ch_bw = 8000000;
2078 pict2chanb_vsb = -(ch_bw / 2);
2079 rcvr_mode = MT2063_OFFAIR_ANALOG;
2080 break;
2081 case V4L2_TUNER_ANALOG_TV:
2082 rcvr_mode = MT2063_CABLE_ANALOG;
2083 if (params->std & ~V4L2_STD_MN) {
2084 pict_car = 38900000;
2085 ch_bw = 6000000;
2086 pict2chanb_vsb = -1250000;
2087 } else if (params->std & V4L2_STD_PAL_G) {
2088 pict_car = 38900000;
2089 ch_bw = 7000000;
2090 pict2chanb_vsb = -1250000;
2091 } else { /* PAL/SECAM standards */
2092 pict_car = 38900000;
2093 ch_bw = 8000000;
2094 pict2chanb_vsb = -1250000;
2095 }
2096 break;
2097 default:
2098 return -EINVAL;
2099 }
2100 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2101
2102 state->AS_Data.f_LO2_Step = 125000; /* FIXME: probably 5000 for FM */
2103 state->AS_Data.f_out = if_mid;
2104 state->AS_Data.f_out_bw = ch_bw + 750000;
2105 status = MT2063_SetReceiverMode(state, rcvr_mode);
2106 if (status < 0)
2107 return status;
2108
2109 dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2110 params->frequency, ch_bw, pict2chanb_vsb);
2111
2112 status = MT2063_Tune(state, (params->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2113 if (status < 0)
2114 return status;
2115
2116 state->frequency = params->frequency;
2117 return 0;
2118}
2119
2120/*
2121 * As defined on EN 300 429, the DVB-C roll-off factor is 0.15.
2122 * So, the amount of the needed bandwith is given by:
2123 * Bw = Symbol_rate * (1 + 0.15)
2124 * As such, the maximum symbol rate supported by 6 MHz is given by:
2125 * max_symbol_rate = 6 MHz / 1.15 = 5217391 Bauds
2126 */
2127#define MAX_SYMBOL_RATE_6MHz 5217391
2128
2129static int mt2063_set_params(struct dvb_frontend *fe)
2130{
2131 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
2132 struct mt2063_state *state = fe->tuner_priv;
2133 int status;
2134 s32 pict_car;
2135 s32 pict2chanb_vsb;
2136 s32 ch_bw;
2137 s32 if_mid;
2138 s32 rcvr_mode;
2139
2140 if (!state->init) {
2141 status = mt2063_init(fe);
2142 if (status < 0)
2143 return status;
2144 }
2145
2146 dprintk(2, "\n");
2147
2148 if (c->bandwidth_hz == 0)
2149 return -EINVAL;
2150 if (c->bandwidth_hz <= 6000000)
2151 ch_bw = 6000000;
2152 else if (c->bandwidth_hz <= 7000000)
2153 ch_bw = 7000000;
2154 else
2155 ch_bw = 8000000;
2156
2157 switch (c->delivery_system) {
2158 case SYS_DVBT:
2159 rcvr_mode = MT2063_OFFAIR_COFDM;
2160 pict_car = 36125000;
2161 pict2chanb_vsb = -(ch_bw / 2);
2162 break;
2163 case SYS_DVBC_ANNEX_A:
2164 case SYS_DVBC_ANNEX_C:
2165 rcvr_mode = MT2063_CABLE_QAM;
2166 pict_car = 36125000;
2167 pict2chanb_vsb = -(ch_bw / 2);
2168 break;
2169 default:
2170 return -EINVAL;
2171 }
2172 if_mid = pict_car - (pict2chanb_vsb + (ch_bw / 2));
2173
2174 state->AS_Data.f_LO2_Step = 125000; /* FIXME: probably 5000 for FM */
2175 state->AS_Data.f_out = if_mid;
2176 state->AS_Data.f_out_bw = ch_bw + 750000;
2177 status = MT2063_SetReceiverMode(state, rcvr_mode);
2178 if (status < 0)
2179 return status;
2180
2181 dprintk(1, "Tuning to frequency: %d, bandwidth %d, foffset %d\n",
2182 c->frequency, ch_bw, pict2chanb_vsb);
2183
2184 status = MT2063_Tune(state, (c->frequency + (pict2chanb_vsb + (ch_bw / 2))));
2185
2186 if (status < 0)
2187 return status;
2188
2189 state->frequency = c->frequency;
2190 return 0;
2191}
2192
2193static int mt2063_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
2194{
2195 struct mt2063_state *state = fe->tuner_priv;
2196
2197 dprintk(2, "\n");
2198
2199 if (!state->init)
2200 return -ENODEV;
2201
2202 *freq = state->AS_Data.f_out;
2203
2204 dprintk(1, "IF frequency: %d\n", *freq);
2205
2206 return 0;
2207}
2208
2209static int mt2063_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
2210{
2211 struct mt2063_state *state = fe->tuner_priv;
2212
2213 dprintk(2, "\n");
2214
2215 if (!state->init)
2216 return -ENODEV;
2217
2218 *bw = state->AS_Data.f_out_bw - 750000;
2219
2220 dprintk(1, "bandwidth: %d\n", *bw);
2221
2222 return 0;
2223}
2224
2225static struct dvb_tuner_ops mt2063_ops = {
2226 .info = {
2227 .name = "MT2063 Silicon Tuner",
2228 .frequency_min = 45000000,
2229 .frequency_max = 865000000,
2230 .frequency_step = 0,
2231 },
2232
2233 .init = mt2063_init,
2234 .sleep = MT2063_Sleep,
2235 .get_status = mt2063_get_status,
2236 .set_analog_params = mt2063_set_analog_params,
2237 .set_params = mt2063_set_params,
2238 .get_if_frequency = mt2063_get_if_frequency,
2239 .get_bandwidth = mt2063_get_bandwidth,
2240 .release = mt2063_release,
2241};
2242
2243struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
2244 struct mt2063_config *config,
2245 struct i2c_adapter *i2c)
2246{
2247 struct mt2063_state *state = NULL;
2248
2249 dprintk(2, "\n");
2250
2251 state = kzalloc(sizeof(struct mt2063_state), GFP_KERNEL);
2252 if (state == NULL)
2253 goto error;
2254
2255 state->config = config;
2256 state->i2c = i2c;
2257 state->frontend = fe;
2258 state->reference = config->refclock / 1000; /* kHz */
2259 fe->tuner_priv = state;
2260 fe->ops.tuner_ops = mt2063_ops;
2261
2262 printk(KERN_INFO "%s: Attaching MT2063\n", __func__);
2263 return fe;
2264
2265error:
2266 kfree(state);
2267 return NULL;
2268}
2269EXPORT_SYMBOL_GPL(mt2063_attach);
2270
2271/*
2272 * Ancillary routines visible outside mt2063
2273 * FIXME: Remove them in favor of using standard tuner callbacks
2274 */
2275unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe)
2276{
2277 struct mt2063_state *state = fe->tuner_priv;
2278 int err = 0;
2279
2280 dprintk(2, "\n");
2281
2282 err = MT2063_SoftwareShutdown(state, 1);
2283 if (err < 0)
2284 printk(KERN_ERR "%s: Couldn't shutdown\n", __func__);
2285
2286 return err;
2287}
2288EXPORT_SYMBOL_GPL(tuner_MT2063_SoftwareShutdown);
2289
2290unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe)
2291{
2292 struct mt2063_state *state = fe->tuner_priv;
2293 int err = 0;
2294
2295 dprintk(2, "\n");
2296
2297 err = MT2063_ClearPowerMaskBits(state, MT2063_ALL_SD);
2298 if (err < 0)
2299 printk(KERN_ERR "%s: Invalid parameter\n", __func__);
2300
2301 return err;
2302}
2303EXPORT_SYMBOL_GPL(tuner_MT2063_ClearPowerMaskBits);
2304
2305MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@redhat.com>");
2306MODULE_DESCRIPTION("MT2063 Silicon tuner");
2307MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/mt2063.h b/drivers/media/tuners/mt2063.h
new file mode 100644
index 000000000000..3f5cfd93713f
--- /dev/null
+++ b/drivers/media/tuners/mt2063.h
@@ -0,0 +1,32 @@
1#ifndef __MT2063_H__
2#define __MT2063_H__
3
4#include "dvb_frontend.h"
5
6struct mt2063_config {
7 u8 tuner_address;
8 u32 refclock;
9};
10
11#if defined(CONFIG_MEDIA_TUNER_MT2063) || (defined(CONFIG_MEDIA_TUNER_MT2063_MODULE) && defined(MODULE))
12struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
13 struct mt2063_config *config,
14 struct i2c_adapter *i2c);
15
16#else
17
18static inline struct dvb_frontend *mt2063_attach(struct dvb_frontend *fe,
19 struct mt2063_config *config,
20 struct i2c_adapter *i2c)
21{
22 printk(KERN_WARNING "%s: Driver disabled by Kconfig\n", __func__);
23 return NULL;
24}
25
26/* FIXME: Should use the standard DVB attachment interfaces */
27unsigned int tuner_MT2063_SoftwareShutdown(struct dvb_frontend *fe);
28unsigned int tuner_MT2063_ClearPowerMaskBits(struct dvb_frontend *fe);
29
30#endif /* CONFIG_DVB_MT2063 */
31
32#endif /* __MT2063_H__ */
diff --git a/drivers/media/tuners/mt20xx.c b/drivers/media/tuners/mt20xx.c
new file mode 100644
index 000000000000..0e74e97e0d1a
--- /dev/null
+++ b/drivers/media/tuners/mt20xx.c
@@ -0,0 +1,670 @@
1/*
2 * i2c tv tuner chip device driver
3 * controls microtune tuners, mt2032 + mt2050 at the moment.
4 *
5 * This "mt20xx" module was split apart from the original "tuner" module.
6 */
7#include <linux/delay.h>
8#include <linux/i2c.h>
9#include <linux/slab.h>
10#include <linux/videodev2.h>
11#include "tuner-i2c.h"
12#include "mt20xx.h"
13
14static int debug;
15module_param(debug, int, 0644);
16MODULE_PARM_DESC(debug, "enable verbose debug messages");
17
18/* ---------------------------------------------------------------------- */
19
20static unsigned int optimize_vco = 1;
21module_param(optimize_vco, int, 0644);
22
23static unsigned int tv_antenna = 1;
24module_param(tv_antenna, int, 0644);
25
26static unsigned int radio_antenna;
27module_param(radio_antenna, int, 0644);
28
29/* ---------------------------------------------------------------------- */
30
31#define MT2032 0x04
32#define MT2030 0x06
33#define MT2040 0x07
34#define MT2050 0x42
35
36static char *microtune_part[] = {
37 [ MT2030 ] = "MT2030",
38 [ MT2032 ] = "MT2032",
39 [ MT2040 ] = "MT2040",
40 [ MT2050 ] = "MT2050",
41};
42
43struct microtune_priv {
44 struct tuner_i2c_props i2c_props;
45
46 unsigned int xogc;
47 //unsigned int radio_if2;
48
49 u32 frequency;
50};
51
52static int microtune_release(struct dvb_frontend *fe)
53{
54 kfree(fe->tuner_priv);
55 fe->tuner_priv = NULL;
56
57 return 0;
58}
59
60static int microtune_get_frequency(struct dvb_frontend *fe, u32 *frequency)
61{
62 struct microtune_priv *priv = fe->tuner_priv;
63 *frequency = priv->frequency;
64 return 0;
65}
66
67// IsSpurInBand()?
68static int mt2032_spurcheck(struct dvb_frontend *fe,
69 int f1, int f2, int spectrum_from,int spectrum_to)
70{
71 struct microtune_priv *priv = fe->tuner_priv;
72 int n1=1,n2,f;
73
74 f1=f1/1000; //scale to kHz to avoid 32bit overflows
75 f2=f2/1000;
76 spectrum_from/=1000;
77 spectrum_to/=1000;
78
79 tuner_dbg("spurcheck f1=%d f2=%d from=%d to=%d\n",
80 f1,f2,spectrum_from,spectrum_to);
81
82 do {
83 n2=-n1;
84 f=n1*(f1-f2);
85 do {
86 n2--;
87 f=f-f2;
88 tuner_dbg("spurtest n1=%d n2=%d ftest=%d\n",n1,n2,f);
89
90 if( (f>spectrum_from) && (f<spectrum_to))
91 tuner_dbg("mt2032 spurcheck triggered: %d\n",n1);
92 } while ( (f>(f2-spectrum_to)) || (n2>-5));
93 n1++;
94 } while (n1<5);
95
96 return 1;
97}
98
99static int mt2032_compute_freq(struct dvb_frontend *fe,
100 unsigned int rfin,
101 unsigned int if1, unsigned int if2,
102 unsigned int spectrum_from,
103 unsigned int spectrum_to,
104 unsigned char *buf,
105 int *ret_sel,
106 unsigned int xogc) //all in Hz
107{
108 struct microtune_priv *priv = fe->tuner_priv;
109 unsigned int fref,lo1,lo1n,lo1a,s,sel,lo1freq, desired_lo1,
110 desired_lo2,lo2,lo2n,lo2a,lo2num,lo2freq;
111
112 fref= 5250 *1000; //5.25MHz
113 desired_lo1=rfin+if1;
114
115 lo1=(2*(desired_lo1/1000)+(fref/1000)) / (2*fref/1000);
116 lo1n=lo1/8;
117 lo1a=lo1-(lo1n*8);
118
119 s=rfin/1000/1000+1090;
120
121 if(optimize_vco) {
122 if(s>1890) sel=0;
123 else if(s>1720) sel=1;
124 else if(s>1530) sel=2;
125 else if(s>1370) sel=3;
126 else sel=4; // >1090
127 }
128 else {
129 if(s>1790) sel=0; // <1958
130 else if(s>1617) sel=1;
131 else if(s>1449) sel=2;
132 else if(s>1291) sel=3;
133 else sel=4; // >1090
134 }
135 *ret_sel=sel;
136
137 lo1freq=(lo1a+8*lo1n)*fref;
138
139 tuner_dbg("mt2032: rfin=%d lo1=%d lo1n=%d lo1a=%d sel=%d, lo1freq=%d\n",
140 rfin,lo1,lo1n,lo1a,sel,lo1freq);
141
142 desired_lo2=lo1freq-rfin-if2;
143 lo2=(desired_lo2)/fref;
144 lo2n=lo2/8;
145 lo2a=lo2-(lo2n*8);
146 lo2num=((desired_lo2/1000)%(fref/1000))* 3780/(fref/1000); //scale to fit in 32bit arith
147 lo2freq=(lo2a+8*lo2n)*fref + lo2num*(fref/1000)/3780*1000;
148
149 tuner_dbg("mt2032: rfin=%d lo2=%d lo2n=%d lo2a=%d num=%d lo2freq=%d\n",
150 rfin,lo2,lo2n,lo2a,lo2num,lo2freq);
151
152 if (lo1a > 7 || lo1n < 17 || lo1n > 48 || lo2a > 7 || lo2n < 17 ||
153 lo2n > 30) {
154 tuner_info("mt2032: frequency parameters out of range: %d %d %d %d\n",
155 lo1a, lo1n, lo2a,lo2n);
156 return(-1);
157 }
158
159 mt2032_spurcheck(fe, lo1freq, desired_lo2, spectrum_from, spectrum_to);
160 // should recalculate lo1 (one step up/down)
161
162 // set up MT2032 register map for transfer over i2c
163 buf[0]=lo1n-1;
164 buf[1]=lo1a | (sel<<4);
165 buf[2]=0x86; // LOGC
166 buf[3]=0x0f; //reserved
167 buf[4]=0x1f;
168 buf[5]=(lo2n-1) | (lo2a<<5);
169 if(rfin >400*1000*1000)
170 buf[6]=0xe4;
171 else
172 buf[6]=0xf4; // set PKEN per rev 1.2
173 buf[7]=8+xogc;
174 buf[8]=0xc3; //reserved
175 buf[9]=0x4e; //reserved
176 buf[10]=0xec; //reserved
177 buf[11]=(lo2num&0xff);
178 buf[12]=(lo2num>>8) |0x80; // Lo2RST
179
180 return 0;
181}
182
183static int mt2032_check_lo_lock(struct dvb_frontend *fe)
184{
185 struct microtune_priv *priv = fe->tuner_priv;
186 int try,lock=0;
187 unsigned char buf[2];
188
189 for(try=0;try<10;try++) {
190 buf[0]=0x0e;
191 tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
192 tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
193 tuner_dbg("mt2032 Reg.E=0x%02x\n",buf[0]);
194 lock=buf[0] &0x06;
195
196 if (lock==6)
197 break;
198
199 tuner_dbg("mt2032: pll wait 1ms for lock (0x%2x)\n",buf[0]);
200 udelay(1000);
201 }
202 return lock;
203}
204
205static int mt2032_optimize_vco(struct dvb_frontend *fe,int sel,int lock)
206{
207 struct microtune_priv *priv = fe->tuner_priv;
208 unsigned char buf[2];
209 int tad1;
210
211 buf[0]=0x0f;
212 tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
213 tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
214 tuner_dbg("mt2032 Reg.F=0x%02x\n",buf[0]);
215 tad1=buf[0]&0x07;
216
217 if(tad1 ==0) return lock;
218 if(tad1 ==1) return lock;
219
220 if(tad1==2) {
221 if(sel==0)
222 return lock;
223 else sel--;
224 }
225 else {
226 if(sel<4)
227 sel++;
228 else
229 return lock;
230 }
231
232 tuner_dbg("mt2032 optimize_vco: sel=%d\n",sel);
233
234 buf[0]=0x0f;
235 buf[1]=sel;
236 tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
237 lock=mt2032_check_lo_lock(fe);
238 return lock;
239}
240
241
242static void mt2032_set_if_freq(struct dvb_frontend *fe, unsigned int rfin,
243 unsigned int if1, unsigned int if2,
244 unsigned int from, unsigned int to)
245{
246 unsigned char buf[21];
247 int lint_try,ret,sel,lock=0;
248 struct microtune_priv *priv = fe->tuner_priv;
249
250 tuner_dbg("mt2032_set_if_freq rfin=%d if1=%d if2=%d from=%d to=%d\n",
251 rfin,if1,if2,from,to);
252
253 buf[0]=0;
254 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
255 tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
256
257 buf[0]=0;
258 ret=mt2032_compute_freq(fe,rfin,if1,if2,from,to,&buf[1],&sel,priv->xogc);
259 if (ret<0)
260 return;
261
262 // send only the relevant registers per Rev. 1.2
263 buf[0]=0;
264 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,4);
265 buf[5]=5;
266 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,4);
267 buf[11]=11;
268 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+11,3);
269 if(ret!=3)
270 tuner_warn("i2c i/o error: rc == %d (should be 3)\n",ret);
271
272 // wait for PLLs to lock (per manual), retry LINT if not.
273 for(lint_try=0; lint_try<2; lint_try++) {
274 lock=mt2032_check_lo_lock(fe);
275
276 if(optimize_vco)
277 lock=mt2032_optimize_vco(fe,sel,lock);
278 if(lock==6) break;
279
280 tuner_dbg("mt2032: re-init PLLs by LINT\n");
281 buf[0]=7;
282 buf[1]=0x80 +8+priv->xogc; // set LINT to re-init PLLs
283 tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
284 mdelay(10);
285 buf[1]=8+priv->xogc;
286 tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
287 }
288
289 if (lock!=6)
290 tuner_warn("MT2032 Fatal Error: PLLs didn't lock.\n");
291
292 buf[0]=2;
293 buf[1]=0x20; // LOGC for optimal phase noise
294 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
295 if (ret!=2)
296 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
297}
298
299
300static int mt2032_set_tv_freq(struct dvb_frontend *fe,
301 struct analog_parameters *params)
302{
303 int if2,from,to;
304
305 // signal bandwidth and picture carrier
306 if (params->std & V4L2_STD_525_60) {
307 // NTSC
308 from = 40750*1000;
309 to = 46750*1000;
310 if2 = 45750*1000;
311 } else {
312 // PAL
313 from = 32900*1000;
314 to = 39900*1000;
315 if2 = 38900*1000;
316 }
317
318 mt2032_set_if_freq(fe, params->frequency*62500,
319 1090*1000*1000, if2, from, to);
320
321 return 0;
322}
323
324static int mt2032_set_radio_freq(struct dvb_frontend *fe,
325 struct analog_parameters *params)
326{
327 struct microtune_priv *priv = fe->tuner_priv;
328 int if2;
329
330 if (params->std & V4L2_STD_525_60) {
331 tuner_dbg("pinnacle ntsc\n");
332 if2 = 41300 * 1000;
333 } else {
334 tuner_dbg("pinnacle pal\n");
335 if2 = 33300 * 1000;
336 }
337
338 // per Manual for FM tuning: first if center freq. 1085 MHz
339 mt2032_set_if_freq(fe, params->frequency * 125 / 2,
340 1085*1000*1000,if2,if2,if2);
341
342 return 0;
343}
344
345static int mt2032_set_params(struct dvb_frontend *fe,
346 struct analog_parameters *params)
347{
348 struct microtune_priv *priv = fe->tuner_priv;
349 int ret = -EINVAL;
350
351 switch (params->mode) {
352 case V4L2_TUNER_RADIO:
353 ret = mt2032_set_radio_freq(fe, params);
354 priv->frequency = params->frequency * 125 / 2;
355 break;
356 case V4L2_TUNER_ANALOG_TV:
357 case V4L2_TUNER_DIGITAL_TV:
358 ret = mt2032_set_tv_freq(fe, params);
359 priv->frequency = params->frequency * 62500;
360 break;
361 }
362
363 return ret;
364}
365
366static struct dvb_tuner_ops mt2032_tuner_ops = {
367 .set_analog_params = mt2032_set_params,
368 .release = microtune_release,
369 .get_frequency = microtune_get_frequency,
370};
371
372// Initialization as described in "MT203x Programming Procedures", Rev 1.2, Feb.2001
373static int mt2032_init(struct dvb_frontend *fe)
374{
375 struct microtune_priv *priv = fe->tuner_priv;
376 unsigned char buf[21];
377 int ret,xogc,xok=0;
378
379 // Initialize Registers per spec.
380 buf[1]=2; // Index to register 2
381 buf[2]=0xff;
382 buf[3]=0x0f;
383 buf[4]=0x1f;
384 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+1,4);
385
386 buf[5]=6; // Index register 6
387 buf[6]=0xe4;
388 buf[7]=0x8f;
389 buf[8]=0xc3;
390 buf[9]=0x4e;
391 buf[10]=0xec;
392 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+5,6);
393
394 buf[12]=13; // Index register 13
395 buf[13]=0x32;
396 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf+12,2);
397
398 // Adjust XOGC (register 7), wait for XOK
399 xogc=7;
400 do {
401 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
402 mdelay(10);
403 buf[0]=0x0e;
404 tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
405 tuner_i2c_xfer_recv(&priv->i2c_props,buf,1);
406 xok=buf[0]&0x01;
407 tuner_dbg("mt2032: xok = 0x%02x\n",xok);
408 if (xok == 1) break;
409
410 xogc--;
411 tuner_dbg("mt2032: xogc = 0x%02x\n",xogc&0x07);
412 if (xogc == 3) {
413 xogc=4; // min. 4 per spec
414 break;
415 }
416 buf[0]=0x07;
417 buf[1]=0x88 + xogc;
418 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,2);
419 if (ret!=2)
420 tuner_warn("i2c i/o error: rc == %d (should be 2)\n",ret);
421 } while (xok != 1 );
422 priv->xogc=xogc;
423
424 memcpy(&fe->ops.tuner_ops, &mt2032_tuner_ops, sizeof(struct dvb_tuner_ops));
425
426 return(1);
427}
428
429static void mt2050_set_antenna(struct dvb_frontend *fe, unsigned char antenna)
430{
431 struct microtune_priv *priv = fe->tuner_priv;
432 unsigned char buf[2];
433
434 buf[0] = 6;
435 buf[1] = antenna ? 0x11 : 0x10;
436 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
437 tuner_dbg("mt2050: enabled antenna connector %d\n", antenna);
438}
439
440static void mt2050_set_if_freq(struct dvb_frontend *fe,unsigned int freq, unsigned int if2)
441{
442 struct microtune_priv *priv = fe->tuner_priv;
443 unsigned int if1=1218*1000*1000;
444 unsigned int f_lo1,f_lo2,lo1,lo2,f_lo1_modulo,f_lo2_modulo,num1,num2,div1a,div1b,div2a,div2b;
445 int ret;
446 unsigned char buf[6];
447
448 tuner_dbg("mt2050_set_if_freq freq=%d if1=%d if2=%d\n",
449 freq,if1,if2);
450
451 f_lo1=freq+if1;
452 f_lo1=(f_lo1/1000000)*1000000;
453
454 f_lo2=f_lo1-freq-if2;
455 f_lo2=(f_lo2/50000)*50000;
456
457 lo1=f_lo1/4000000;
458 lo2=f_lo2/4000000;
459
460 f_lo1_modulo= f_lo1-(lo1*4000000);
461 f_lo2_modulo= f_lo2-(lo2*4000000);
462
463 num1=4*f_lo1_modulo/4000000;
464 num2=4096*(f_lo2_modulo/1000)/4000;
465
466 // todo spurchecks
467
468 div1a=(lo1/12)-1;
469 div1b=lo1-(div1a+1)*12;
470
471 div2a=(lo2/8)-1;
472 div2b=lo2-(div2a+1)*8;
473
474 if (debug > 1) {
475 tuner_dbg("lo1 lo2 = %d %d\n", lo1, lo2);
476 tuner_dbg("num1 num2 div1a div1b div2a div2b= %x %x %x %x %x %x\n",
477 num1,num2,div1a,div1b,div2a,div2b);
478 }
479
480 buf[0]=1;
481 buf[1]= 4*div1b + num1;
482 if(freq<275*1000*1000) buf[1] = buf[1]|0x80;
483
484 buf[2]=div1a;
485 buf[3]=32*div2b + num2/256;
486 buf[4]=num2-(num2/256)*256;
487 buf[5]=div2a;
488 if(num2!=0) buf[5]=buf[5]|0x40;
489
490 if (debug > 1) {
491 int i;
492 tuner_dbg("bufs is: ");
493 for(i=0;i<6;i++)
494 printk("%x ",buf[i]);
495 printk("\n");
496 }
497
498 ret=tuner_i2c_xfer_send(&priv->i2c_props,buf,6);
499 if (ret!=6)
500 tuner_warn("i2c i/o error: rc == %d (should be 6)\n",ret);
501}
502
503static int mt2050_set_tv_freq(struct dvb_frontend *fe,
504 struct analog_parameters *params)
505{
506 unsigned int if2;
507
508 if (params->std & V4L2_STD_525_60) {
509 // NTSC
510 if2 = 45750*1000;
511 } else {
512 // PAL
513 if2 = 38900*1000;
514 }
515 if (V4L2_TUNER_DIGITAL_TV == params->mode) {
516 // DVB (pinnacle 300i)
517 if2 = 36150*1000;
518 }
519 mt2050_set_if_freq(fe, params->frequency*62500, if2);
520 mt2050_set_antenna(fe, tv_antenna);
521
522 return 0;
523}
524
525static int mt2050_set_radio_freq(struct dvb_frontend *fe,
526 struct analog_parameters *params)
527{
528 struct microtune_priv *priv = fe->tuner_priv;
529 int if2;
530
531 if (params->std & V4L2_STD_525_60) {
532 tuner_dbg("pinnacle ntsc\n");
533 if2 = 41300 * 1000;
534 } else {
535 tuner_dbg("pinnacle pal\n");
536 if2 = 33300 * 1000;
537 }
538
539 mt2050_set_if_freq(fe, params->frequency * 125 / 2, if2);
540 mt2050_set_antenna(fe, radio_antenna);
541
542 return 0;
543}
544
545static int mt2050_set_params(struct dvb_frontend *fe,
546 struct analog_parameters *params)
547{
548 struct microtune_priv *priv = fe->tuner_priv;
549 int ret = -EINVAL;
550
551 switch (params->mode) {
552 case V4L2_TUNER_RADIO:
553 ret = mt2050_set_radio_freq(fe, params);
554 priv->frequency = params->frequency * 125 / 2;
555 break;
556 case V4L2_TUNER_ANALOG_TV:
557 case V4L2_TUNER_DIGITAL_TV:
558 ret = mt2050_set_tv_freq(fe, params);
559 priv->frequency = params->frequency * 62500;
560 break;
561 }
562
563 return ret;
564}
565
566static struct dvb_tuner_ops mt2050_tuner_ops = {
567 .set_analog_params = mt2050_set_params,
568 .release = microtune_release,
569 .get_frequency = microtune_get_frequency,
570};
571
572static int mt2050_init(struct dvb_frontend *fe)
573{
574 struct microtune_priv *priv = fe->tuner_priv;
575 unsigned char buf[2];
576
577 buf[0] = 6;
578 buf[1] = 0x10;
579 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); /* power */
580
581 buf[0] = 0x0f;
582 buf[1] = 0x0f;
583 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2); /* m1lo */
584
585 buf[0] = 0x0d;
586 tuner_i2c_xfer_send(&priv->i2c_props, buf, 1);
587 tuner_i2c_xfer_recv(&priv->i2c_props, buf, 1);
588
589 tuner_dbg("mt2050: sro is %x\n", buf[0]);
590
591 memcpy(&fe->ops.tuner_ops, &mt2050_tuner_ops, sizeof(struct dvb_tuner_ops));
592
593 return 0;
594}
595
596struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
597 struct i2c_adapter* i2c_adap,
598 u8 i2c_addr)
599{
600 struct microtune_priv *priv = NULL;
601 char *name;
602 unsigned char buf[21];
603 int company_code;
604
605 priv = kzalloc(sizeof(struct microtune_priv), GFP_KERNEL);
606 if (priv == NULL)
607 return NULL;
608 fe->tuner_priv = priv;
609
610 priv->i2c_props.addr = i2c_addr;
611 priv->i2c_props.adap = i2c_adap;
612 priv->i2c_props.name = "mt20xx";
613
614 //priv->radio_if2 = 10700 * 1000; /* 10.7MHz - FM radio */
615
616 memset(buf,0,sizeof(buf));
617
618 name = "unknown";
619
620 tuner_i2c_xfer_send(&priv->i2c_props,buf,1);
621 tuner_i2c_xfer_recv(&priv->i2c_props,buf,21);
622 if (debug) {
623 int i;
624 tuner_dbg("MT20xx hexdump:");
625 for(i=0;i<21;i++) {
626 printk(" %02x",buf[i]);
627 if(((i+1)%8)==0) printk(" ");
628 }
629 printk("\n");
630 }
631 company_code = buf[0x11] << 8 | buf[0x12];
632 tuner_info("microtune: companycode=%04x part=%02x rev=%02x\n",
633 company_code,buf[0x13],buf[0x14]);
634
635
636 if (buf[0x13] < ARRAY_SIZE(microtune_part) &&
637 NULL != microtune_part[buf[0x13]])
638 name = microtune_part[buf[0x13]];
639 switch (buf[0x13]) {
640 case MT2032:
641 mt2032_init(fe);
642 break;
643 case MT2050:
644 mt2050_init(fe);
645 break;
646 default:
647 tuner_info("microtune %s found, not (yet?) supported, sorry :-/\n",
648 name);
649 return NULL;
650 }
651
652 strlcpy(fe->ops.tuner_ops.info.name, name,
653 sizeof(fe->ops.tuner_ops.info.name));
654 tuner_info("microtune %s found, OK\n",name);
655 return fe;
656}
657
658EXPORT_SYMBOL_GPL(microtune_attach);
659
660MODULE_DESCRIPTION("Microtune tuner driver");
661MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
662MODULE_LICENSE("GPL");
663
664/*
665 * Overrides for Emacs so that we follow Linus's tabbing style.
666 * ---------------------------------------------------------------------------
667 * Local variables:
668 * c-basic-offset: 8
669 * End:
670 */
diff --git a/drivers/media/tuners/mt20xx.h b/drivers/media/tuners/mt20xx.h
new file mode 100644
index 000000000000..259553a24903
--- /dev/null
+++ b/drivers/media/tuners/mt20xx.h
@@ -0,0 +1,37 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __MT20XX_H__
18#define __MT20XX_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23#if defined(CONFIG_MEDIA_TUNER_MT20XX) || (defined(CONFIG_MEDIA_TUNER_MT20XX_MODULE) && defined(MODULE))
24extern struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
25 struct i2c_adapter* i2c_adap,
26 u8 i2c_addr);
27#else
28static inline struct dvb_frontend *microtune_attach(struct dvb_frontend *fe,
29 struct i2c_adapter* i2c_adap,
30 u8 i2c_addr)
31{
32 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
33 return NULL;
34}
35#endif
36
37#endif /* __MT20XX_H__ */
diff --git a/drivers/media/tuners/mt2131.c b/drivers/media/tuners/mt2131.c
new file mode 100644
index 000000000000..f83b0c1ea6c8
--- /dev/null
+++ b/drivers/media/tuners/mt2131.c
@@ -0,0 +1,301 @@
1/*
2 * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/delay.h>
24#include <linux/dvb/frontend.h>
25#include <linux/i2c.h>
26#include <linux/slab.h>
27
28#include "dvb_frontend.h"
29
30#include "mt2131.h"
31#include "mt2131_priv.h"
32
33static int debug;
34module_param(debug, int, 0644);
35MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
36
37#define dprintk(level,fmt, arg...) if (debug >= level) \
38 printk(KERN_INFO "%s: " fmt, "mt2131", ## arg)
39
40static u8 mt2131_config1[] = {
41 0x01,
42 0x50, 0x00, 0x50, 0x80, 0x00, 0x49, 0xfa, 0x88,
43 0x08, 0x77, 0x41, 0x04, 0x00, 0x00, 0x00, 0x32,
44 0x7f, 0xda, 0x4c, 0x00, 0x10, 0xaa, 0x78, 0x80,
45 0xff, 0x68, 0xa0, 0xff, 0xdd, 0x00, 0x00
46};
47
48static u8 mt2131_config2[] = {
49 0x10,
50 0x7f, 0xc8, 0x0a, 0x5f, 0x00, 0x04
51};
52
53static int mt2131_readreg(struct mt2131_priv *priv, u8 reg, u8 *val)
54{
55 struct i2c_msg msg[2] = {
56 { .addr = priv->cfg->i2c_address, .flags = 0,
57 .buf = &reg, .len = 1 },
58 { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD,
59 .buf = val, .len = 1 },
60 };
61
62 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
63 printk(KERN_WARNING "mt2131 I2C read failed\n");
64 return -EREMOTEIO;
65 }
66 return 0;
67}
68
69static int mt2131_writereg(struct mt2131_priv *priv, u8 reg, u8 val)
70{
71 u8 buf[2] = { reg, val };
72 struct i2c_msg msg = { .addr = priv->cfg->i2c_address, .flags = 0,
73 .buf = buf, .len = 2 };
74
75 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
76 printk(KERN_WARNING "mt2131 I2C write failed\n");
77 return -EREMOTEIO;
78 }
79 return 0;
80}
81
82static int mt2131_writeregs(struct mt2131_priv *priv,u8 *buf, u8 len)
83{
84 struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
85 .flags = 0, .buf = buf, .len = len };
86
87 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
88 printk(KERN_WARNING "mt2131 I2C write failed (len=%i)\n",
89 (int)len);
90 return -EREMOTEIO;
91 }
92 return 0;
93}
94
95static int mt2131_set_params(struct dvb_frontend *fe)
96{
97 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
98 struct mt2131_priv *priv;
99 int ret=0, i;
100 u32 freq;
101 u8 if_band_center;
102 u32 f_lo1, f_lo2;
103 u32 div1, num1, div2, num2;
104 u8 b[8];
105 u8 lockval = 0;
106
107 priv = fe->tuner_priv;
108
109 freq = c->frequency / 1000; /* Hz -> kHz */
110 dprintk(1, "%s() freq=%d\n", __func__, freq);
111
112 f_lo1 = freq + MT2131_IF1 * 1000;
113 f_lo1 = (f_lo1 / 250) * 250;
114 f_lo2 = f_lo1 - freq - MT2131_IF2;
115
116 priv->frequency = (f_lo1 - f_lo2 - MT2131_IF2) * 1000;
117
118 /* Frequency LO1 = 16MHz * (DIV1 + NUM1/8192 ) */
119 num1 = f_lo1 * 64 / (MT2131_FREF / 128);
120 div1 = num1 / 8192;
121 num1 &= 0x1fff;
122
123 /* Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 ) */
124 num2 = f_lo2 * 64 / (MT2131_FREF / 128);
125 div2 = num2 / 8192;
126 num2 &= 0x1fff;
127
128 if (freq <= 82500) if_band_center = 0x00; else
129 if (freq <= 137500) if_band_center = 0x01; else
130 if (freq <= 192500) if_band_center = 0x02; else
131 if (freq <= 247500) if_band_center = 0x03; else
132 if (freq <= 302500) if_band_center = 0x04; else
133 if (freq <= 357500) if_band_center = 0x05; else
134 if (freq <= 412500) if_band_center = 0x06; else
135 if (freq <= 467500) if_band_center = 0x07; else
136 if (freq <= 522500) if_band_center = 0x08; else
137 if (freq <= 577500) if_band_center = 0x09; else
138 if (freq <= 632500) if_band_center = 0x0A; else
139 if (freq <= 687500) if_band_center = 0x0B; else
140 if (freq <= 742500) if_band_center = 0x0C; else
141 if (freq <= 797500) if_band_center = 0x0D; else
142 if (freq <= 852500) if_band_center = 0x0E; else
143 if (freq <= 907500) if_band_center = 0x0F; else
144 if (freq <= 962500) if_band_center = 0x10; else
145 if (freq <= 1017500) if_band_center = 0x11; else
146 if (freq <= 1072500) if_band_center = 0x12; else if_band_center = 0x13;
147
148 b[0] = 1;
149 b[1] = (num1 >> 5) & 0xFF;
150 b[2] = (num1 & 0x1F);
151 b[3] = div1;
152 b[4] = (num2 >> 5) & 0xFF;
153 b[5] = num2 & 0x1F;
154 b[6] = div2;
155
156 dprintk(1, "IF1: %dMHz IF2: %dMHz\n", MT2131_IF1, MT2131_IF2);
157 dprintk(1, "PLL freq=%dkHz band=%d\n", (int)freq, (int)if_band_center);
158 dprintk(1, "PLL f_lo1=%dkHz f_lo2=%dkHz\n", (int)f_lo1, (int)f_lo2);
159 dprintk(1, "PLL div1=%d num1=%d div2=%d num2=%d\n",
160 (int)div1, (int)num1, (int)div2, (int)num2);
161 dprintk(1, "PLL [1..6]: %2x %2x %2x %2x %2x %2x\n",
162 (int)b[1], (int)b[2], (int)b[3], (int)b[4], (int)b[5],
163 (int)b[6]);
164
165 ret = mt2131_writeregs(priv,b,7);
166 if (ret < 0)
167 return ret;
168
169 mt2131_writereg(priv, 0x0b, if_band_center);
170
171 /* Wait for lock */
172 i = 0;
173 do {
174 mt2131_readreg(priv, 0x08, &lockval);
175 if ((lockval & 0x88) == 0x88)
176 break;
177 msleep(4);
178 i++;
179 } while (i < 10);
180
181 return ret;
182}
183
184static int mt2131_get_frequency(struct dvb_frontend *fe, u32 *frequency)
185{
186 struct mt2131_priv *priv = fe->tuner_priv;
187 dprintk(1, "%s()\n", __func__);
188 *frequency = priv->frequency;
189 return 0;
190}
191
192static int mt2131_get_status(struct dvb_frontend *fe, u32 *status)
193{
194 struct mt2131_priv *priv = fe->tuner_priv;
195 u8 lock_status = 0;
196 u8 afc_status = 0;
197
198 *status = 0;
199
200 mt2131_readreg(priv, 0x08, &lock_status);
201 if ((lock_status & 0x88) == 0x88)
202 *status = TUNER_STATUS_LOCKED;
203
204 mt2131_readreg(priv, 0x09, &afc_status);
205 dprintk(1, "%s() - LO Status = 0x%x, AFC Status = 0x%x\n",
206 __func__, lock_status, afc_status);
207
208 return 0;
209}
210
211static int mt2131_init(struct dvb_frontend *fe)
212{
213 struct mt2131_priv *priv = fe->tuner_priv;
214 int ret;
215 dprintk(1, "%s()\n", __func__);
216
217 if ((ret = mt2131_writeregs(priv, mt2131_config1,
218 sizeof(mt2131_config1))) < 0)
219 return ret;
220
221 mt2131_writereg(priv, 0x0b, 0x09);
222 mt2131_writereg(priv, 0x15, 0x47);
223 mt2131_writereg(priv, 0x07, 0xf2);
224 mt2131_writereg(priv, 0x0b, 0x01);
225
226 if ((ret = mt2131_writeregs(priv, mt2131_config2,
227 sizeof(mt2131_config2))) < 0)
228 return ret;
229
230 return ret;
231}
232
233static int mt2131_release(struct dvb_frontend *fe)
234{
235 dprintk(1, "%s()\n", __func__);
236 kfree(fe->tuner_priv);
237 fe->tuner_priv = NULL;
238 return 0;
239}
240
241static const struct dvb_tuner_ops mt2131_tuner_ops = {
242 .info = {
243 .name = "Microtune MT2131",
244 .frequency_min = 48000000,
245 .frequency_max = 860000000,
246 .frequency_step = 50000,
247 },
248
249 .release = mt2131_release,
250 .init = mt2131_init,
251
252 .set_params = mt2131_set_params,
253 .get_frequency = mt2131_get_frequency,
254 .get_status = mt2131_get_status
255};
256
257struct dvb_frontend * mt2131_attach(struct dvb_frontend *fe,
258 struct i2c_adapter *i2c,
259 struct mt2131_config *cfg, u16 if1)
260{
261 struct mt2131_priv *priv = NULL;
262 u8 id = 0;
263
264 dprintk(1, "%s()\n", __func__);
265
266 priv = kzalloc(sizeof(struct mt2131_priv), GFP_KERNEL);
267 if (priv == NULL)
268 return NULL;
269
270 priv->cfg = cfg;
271 priv->i2c = i2c;
272
273 if (mt2131_readreg(priv, 0, &id) != 0) {
274 kfree(priv);
275 return NULL;
276 }
277 if ( (id != 0x3E) && (id != 0x3F) ) {
278 printk(KERN_ERR "MT2131: Device not found at addr 0x%02x\n",
279 cfg->i2c_address);
280 kfree(priv);
281 return NULL;
282 }
283
284 printk(KERN_INFO "MT2131: successfully identified at address 0x%02x\n",
285 cfg->i2c_address);
286 memcpy(&fe->ops.tuner_ops, &mt2131_tuner_ops,
287 sizeof(struct dvb_tuner_ops));
288
289 fe->tuner_priv = priv;
290 return fe;
291}
292EXPORT_SYMBOL(mt2131_attach);
293
294MODULE_AUTHOR("Steven Toth");
295MODULE_DESCRIPTION("Microtune MT2131 silicon tuner driver");
296MODULE_LICENSE("GPL");
297
298/*
299 * Local variables:
300 * c-basic-offset: 8
301 */
diff --git a/drivers/media/tuners/mt2131.h b/drivers/media/tuners/mt2131.h
new file mode 100644
index 000000000000..6632de640df0
--- /dev/null
+++ b/drivers/media/tuners/mt2131.h
@@ -0,0 +1,54 @@
1/*
2 * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __MT2131_H__
23#define __MT2131_H__
24
25struct dvb_frontend;
26struct i2c_adapter;
27
28struct mt2131_config {
29 u8 i2c_address;
30 u8 clock_out; /* 0 = off, 1 = CLK/4, 2 = CLK/2, 3 = CLK/1 */
31};
32
33#if defined(CONFIG_MEDIA_TUNER_MT2131) || (defined(CONFIG_MEDIA_TUNER_MT2131_MODULE) && defined(MODULE))
34extern struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
35 struct i2c_adapter *i2c,
36 struct mt2131_config *cfg,
37 u16 if1);
38#else
39static inline struct dvb_frontend* mt2131_attach(struct dvb_frontend *fe,
40 struct i2c_adapter *i2c,
41 struct mt2131_config *cfg,
42 u16 if1)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
45 return NULL;
46}
47#endif /* CONFIG_MEDIA_TUNER_MT2131 */
48
49#endif /* __MT2131_H__ */
50
51/*
52 * Local variables:
53 * c-basic-offset: 8
54 */
diff --git a/drivers/media/tuners/mt2131_priv.h b/drivers/media/tuners/mt2131_priv.h
new file mode 100644
index 000000000000..62aeedf5c550
--- /dev/null
+++ b/drivers/media/tuners/mt2131_priv.h
@@ -0,0 +1,48 @@
1/*
2 * Driver for Microtune MT2131 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2006 Steven Toth <stoth@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __MT2131_PRIV_H__
23#define __MT2131_PRIV_H__
24
25/* Regs */
26#define MT2131_PWR 0x07
27#define MT2131_UPC_1 0x0b
28#define MT2131_AGC_RL 0x10
29#define MT2131_MISC_2 0x15
30
31/* frequency values in KHz */
32#define MT2131_IF1 1220
33#define MT2131_IF2 44000
34#define MT2131_FREF 16000
35
36struct mt2131_priv {
37 struct mt2131_config *cfg;
38 struct i2c_adapter *i2c;
39
40 u32 frequency;
41};
42
43#endif /* __MT2131_PRIV_H__ */
44
45/*
46 * Local variables:
47 * c-basic-offset: 8
48 */
diff --git a/drivers/media/tuners/mt2266.c b/drivers/media/tuners/mt2266.c
new file mode 100644
index 000000000000..bca4d75e42d4
--- /dev/null
+++ b/drivers/media/tuners/mt2266.c
@@ -0,0 +1,353 @@
1/*
2 * Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
3 *
4 * Copyright (c) 2007 Olivier DANET <odanet@caramail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#include <linux/module.h>
18#include <linux/delay.h>
19#include <linux/dvb/frontend.h>
20#include <linux/i2c.h>
21#include <linux/slab.h>
22
23#include "dvb_frontend.h"
24#include "mt2266.h"
25
26#define I2C_ADDRESS 0x60
27
28#define REG_PART_REV 0
29#define REG_TUNE 1
30#define REG_BAND 6
31#define REG_BANDWIDTH 8
32#define REG_LOCK 0x12
33
34#define PART_REV 0x85
35
36struct mt2266_priv {
37 struct mt2266_config *cfg;
38 struct i2c_adapter *i2c;
39
40 u32 frequency;
41 u32 bandwidth;
42 u8 band;
43};
44
45#define MT2266_VHF 1
46#define MT2266_UHF 0
47
48/* Here, frequencies are expressed in kiloHertz to avoid 32 bits overflows */
49
50static int debug;
51module_param(debug, int, 0644);
52MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
53
54#define dprintk(args...) do { if (debug) {printk(KERN_DEBUG "MT2266: " args); printk("\n"); }} while (0)
55
56// Reads a single register
57static int mt2266_readreg(struct mt2266_priv *priv, u8 reg, u8 *val)
58{
59 struct i2c_msg msg[2] = {
60 { .addr = priv->cfg->i2c_address, .flags = 0, .buf = &reg, .len = 1 },
61 { .addr = priv->cfg->i2c_address, .flags = I2C_M_RD, .buf = val, .len = 1 },
62 };
63 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
64 printk(KERN_WARNING "MT2266 I2C read failed\n");
65 return -EREMOTEIO;
66 }
67 return 0;
68}
69
70// Writes a single register
71static int mt2266_writereg(struct mt2266_priv *priv, u8 reg, u8 val)
72{
73 u8 buf[2] = { reg, val };
74 struct i2c_msg msg = {
75 .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = 2
76 };
77 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
78 printk(KERN_WARNING "MT2266 I2C write failed\n");
79 return -EREMOTEIO;
80 }
81 return 0;
82}
83
84// Writes a set of consecutive registers
85static int mt2266_writeregs(struct mt2266_priv *priv,u8 *buf, u8 len)
86{
87 struct i2c_msg msg = {
88 .addr = priv->cfg->i2c_address, .flags = 0, .buf = buf, .len = len
89 };
90 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
91 printk(KERN_WARNING "MT2266 I2C write failed (len=%i)\n",(int)len);
92 return -EREMOTEIO;
93 }
94 return 0;
95}
96
97// Initialisation sequences
98static u8 mt2266_init1[] = { REG_TUNE, 0x00, 0x00, 0x28,
99 0x00, 0x52, 0x99, 0x3f };
100
101static u8 mt2266_init2[] = {
102 0x17, 0x6d, 0x71, 0x61, 0xc0, 0xbf, 0xff, 0xdc, 0x00, 0x0a, 0xd4,
103 0x03, 0x64, 0x64, 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14,
104 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x7f, 0x5e, 0x3f, 0xff, 0xff,
105 0xff, 0x00, 0x77, 0x0f, 0x2d
106};
107
108static u8 mt2266_init_8mhz[] = { REG_BANDWIDTH, 0x22, 0x22, 0x22, 0x22,
109 0x22, 0x22, 0x22, 0x22 };
110
111static u8 mt2266_init_7mhz[] = { REG_BANDWIDTH, 0x32, 0x32, 0x32, 0x32,
112 0x32, 0x32, 0x32, 0x32 };
113
114static u8 mt2266_init_6mhz[] = { REG_BANDWIDTH, 0xa7, 0xa7, 0xa7, 0xa7,
115 0xa7, 0xa7, 0xa7, 0xa7 };
116
117static u8 mt2266_uhf[] = { 0x1d, 0xdc, 0x00, 0x0a, 0xd4, 0x03, 0x64, 0x64,
118 0x64, 0x64, 0x22, 0xaa, 0xf2, 0x1e, 0x80, 0x14 };
119
120static u8 mt2266_vhf[] = { 0x1d, 0xfe, 0x00, 0x00, 0xb4, 0x03, 0xa5, 0xa5,
121 0xa5, 0xa5, 0x82, 0xaa, 0xf1, 0x17, 0x80, 0x1f };
122
123#define FREF 30000 // Quartz oscillator 30 MHz
124
125static int mt2266_set_params(struct dvb_frontend *fe)
126{
127 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
128 struct mt2266_priv *priv;
129 int ret=0;
130 u32 freq;
131 u32 tune;
132 u8 lnaband;
133 u8 b[10];
134 int i;
135 u8 band;
136
137 priv = fe->tuner_priv;
138
139 freq = priv->frequency / 1000; /* Hz -> kHz */
140 if (freq < 470000 && freq > 230000)
141 return -EINVAL; /* Gap between VHF and UHF bands */
142
143 priv->frequency = c->frequency;
144 tune = 2 * freq * (8192/16) / (FREF/16);
145 band = (freq < 300000) ? MT2266_VHF : MT2266_UHF;
146 if (band == MT2266_VHF)
147 tune *= 2;
148
149 switch (c->bandwidth_hz) {
150 case 6000000:
151 mt2266_writeregs(priv, mt2266_init_6mhz,
152 sizeof(mt2266_init_6mhz));
153 break;
154 case 8000000:
155 mt2266_writeregs(priv, mt2266_init_8mhz,
156 sizeof(mt2266_init_8mhz));
157 break;
158 case 7000000:
159 default:
160 mt2266_writeregs(priv, mt2266_init_7mhz,
161 sizeof(mt2266_init_7mhz));
162 break;
163 }
164 priv->bandwidth = c->bandwidth_hz;
165
166 if (band == MT2266_VHF && priv->band == MT2266_UHF) {
167 dprintk("Switch from UHF to VHF");
168 mt2266_writereg(priv, 0x05, 0x04);
169 mt2266_writereg(priv, 0x19, 0x61);
170 mt2266_writeregs(priv, mt2266_vhf, sizeof(mt2266_vhf));
171 } else if (band == MT2266_UHF && priv->band == MT2266_VHF) {
172 dprintk("Switch from VHF to UHF");
173 mt2266_writereg(priv, 0x05, 0x52);
174 mt2266_writereg(priv, 0x19, 0x61);
175 mt2266_writeregs(priv, mt2266_uhf, sizeof(mt2266_uhf));
176 }
177 msleep(10);
178
179 if (freq <= 495000)
180 lnaband = 0xEE;
181 else if (freq <= 525000)
182 lnaband = 0xDD;
183 else if (freq <= 550000)
184 lnaband = 0xCC;
185 else if (freq <= 580000)
186 lnaband = 0xBB;
187 else if (freq <= 605000)
188 lnaband = 0xAA;
189 else if (freq <= 630000)
190 lnaband = 0x99;
191 else if (freq <= 655000)
192 lnaband = 0x88;
193 else if (freq <= 685000)
194 lnaband = 0x77;
195 else if (freq <= 710000)
196 lnaband = 0x66;
197 else if (freq <= 735000)
198 lnaband = 0x55;
199 else if (freq <= 765000)
200 lnaband = 0x44;
201 else if (freq <= 802000)
202 lnaband = 0x33;
203 else if (freq <= 840000)
204 lnaband = 0x22;
205 else
206 lnaband = 0x11;
207
208 b[0] = REG_TUNE;
209 b[1] = (tune >> 8) & 0x1F;
210 b[2] = tune & 0xFF;
211 b[3] = tune >> 13;
212 mt2266_writeregs(priv,b,4);
213
214 dprintk("set_parms: tune=%d band=%d %s",
215 (int) tune, (int) lnaband,
216 (band == MT2266_UHF) ? "UHF" : "VHF");
217 dprintk("set_parms: [1..3]: %2x %2x %2x",
218 (int) b[1], (int) b[2], (int)b[3]);
219
220 if (band == MT2266_UHF) {
221 b[0] = 0x05;
222 b[1] = (priv->band == MT2266_VHF) ? 0x52 : 0x62;
223 b[2] = lnaband;
224 mt2266_writeregs(priv, b, 3);
225 }
226
227 /* Wait for pll lock or timeout */
228 i = 0;
229 do {
230 mt2266_readreg(priv,REG_LOCK,b);
231 if (b[0] & 0x40)
232 break;
233 msleep(10);
234 i++;
235 } while (i<10);
236 dprintk("Lock when i=%i",(int)i);
237
238 if (band == MT2266_UHF && priv->band == MT2266_VHF)
239 mt2266_writereg(priv, 0x05, 0x62);
240
241 priv->band = band;
242
243 return ret;
244}
245
246static void mt2266_calibrate(struct mt2266_priv *priv)
247{
248 mt2266_writereg(priv, 0x11, 0x03);
249 mt2266_writereg(priv, 0x11, 0x01);
250 mt2266_writeregs(priv, mt2266_init1, sizeof(mt2266_init1));
251 mt2266_writeregs(priv, mt2266_init2, sizeof(mt2266_init2));
252 mt2266_writereg(priv, 0x33, 0x5e);
253 mt2266_writereg(priv, 0x10, 0x10);
254 mt2266_writereg(priv, 0x10, 0x00);
255 mt2266_writeregs(priv, mt2266_init_8mhz, sizeof(mt2266_init_8mhz));
256 msleep(25);
257 mt2266_writereg(priv, 0x17, 0x6d);
258 mt2266_writereg(priv, 0x1c, 0x00);
259 msleep(75);
260 mt2266_writereg(priv, 0x17, 0x6d);
261 mt2266_writereg(priv, 0x1c, 0xff);
262}
263
264static int mt2266_get_frequency(struct dvb_frontend *fe, u32 *frequency)
265{
266 struct mt2266_priv *priv = fe->tuner_priv;
267 *frequency = priv->frequency;
268 return 0;
269}
270
271static int mt2266_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
272{
273 struct mt2266_priv *priv = fe->tuner_priv;
274 *bandwidth = priv->bandwidth;
275 return 0;
276}
277
278static int mt2266_init(struct dvb_frontend *fe)
279{
280 int ret;
281 struct mt2266_priv *priv = fe->tuner_priv;
282 ret = mt2266_writereg(priv, 0x17, 0x6d);
283 if (ret < 0)
284 return ret;
285 ret = mt2266_writereg(priv, 0x1c, 0xff);
286 if (ret < 0)
287 return ret;
288 return 0;
289}
290
291static int mt2266_sleep(struct dvb_frontend *fe)
292{
293 struct mt2266_priv *priv = fe->tuner_priv;
294 mt2266_writereg(priv, 0x17, 0x6d);
295 mt2266_writereg(priv, 0x1c, 0x00);
296 return 0;
297}
298
299static int mt2266_release(struct dvb_frontend *fe)
300{
301 kfree(fe->tuner_priv);
302 fe->tuner_priv = NULL;
303 return 0;
304}
305
306static const struct dvb_tuner_ops mt2266_tuner_ops = {
307 .info = {
308 .name = "Microtune MT2266",
309 .frequency_min = 174000000,
310 .frequency_max = 862000000,
311 .frequency_step = 50000,
312 },
313 .release = mt2266_release,
314 .init = mt2266_init,
315 .sleep = mt2266_sleep,
316 .set_params = mt2266_set_params,
317 .get_frequency = mt2266_get_frequency,
318 .get_bandwidth = mt2266_get_bandwidth
319};
320
321struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
322{
323 struct mt2266_priv *priv = NULL;
324 u8 id = 0;
325
326 priv = kzalloc(sizeof(struct mt2266_priv), GFP_KERNEL);
327 if (priv == NULL)
328 return NULL;
329
330 priv->cfg = cfg;
331 priv->i2c = i2c;
332 priv->band = MT2266_UHF;
333
334 if (mt2266_readreg(priv, 0, &id)) {
335 kfree(priv);
336 return NULL;
337 }
338 if (id != PART_REV) {
339 kfree(priv);
340 return NULL;
341 }
342 printk(KERN_INFO "MT2266: successfully identified\n");
343 memcpy(&fe->ops.tuner_ops, &mt2266_tuner_ops, sizeof(struct dvb_tuner_ops));
344
345 fe->tuner_priv = priv;
346 mt2266_calibrate(priv);
347 return fe;
348}
349EXPORT_SYMBOL(mt2266_attach);
350
351MODULE_AUTHOR("Olivier DANET");
352MODULE_DESCRIPTION("Microtune MT2266 silicon tuner driver");
353MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/mt2266.h b/drivers/media/tuners/mt2266.h
new file mode 100644
index 000000000000..4d083882d044
--- /dev/null
+++ b/drivers/media/tuners/mt2266.h
@@ -0,0 +1,37 @@
1/*
2 * Driver for Microtune MT2266 "Direct conversion low power broadband tuner"
3 *
4 * Copyright (c) 2007 Olivier DANET <odanet@caramail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 */
16
17#ifndef MT2266_H
18#define MT2266_H
19
20struct dvb_frontend;
21struct i2c_adapter;
22
23struct mt2266_config {
24 u8 i2c_address;
25};
26
27#if defined(CONFIG_MEDIA_TUNER_MT2266) || (defined(CONFIG_MEDIA_TUNER_MT2266_MODULE) && defined(MODULE))
28extern struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg);
29#else
30static inline struct dvb_frontend * mt2266_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2266_config *cfg)
31{
32 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
33 return NULL;
34}
35#endif // CONFIG_MEDIA_TUNER_MT2266
36
37#endif
diff --git a/drivers/media/tuners/mxl5005s.c b/drivers/media/tuners/mxl5005s.c
new file mode 100644
index 000000000000..6133315fb0e3
--- /dev/null
+++ b/drivers/media/tuners/mxl5005s.c
@@ -0,0 +1,4109 @@
1/*
2 MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
3
4 Copyright (C) 2008 MaxLinear
5 Copyright (C) 2006 Steven Toth <stoth@linuxtv.org>
6 Functions:
7 mxl5005s_reset()
8 mxl5005s_writereg()
9 mxl5005s_writeregs()
10 mxl5005s_init()
11 mxl5005s_reconfigure()
12 mxl5005s_AssignTunerMode()
13 mxl5005s_set_params()
14 mxl5005s_get_frequency()
15 mxl5005s_get_bandwidth()
16 mxl5005s_release()
17 mxl5005s_attach()
18
19 Copyright (C) 2008 Realtek
20 Copyright (C) 2008 Jan Hoogenraad
21 Functions:
22 mxl5005s_SetRfFreqHz()
23
24 This program is free software; you can redistribute it and/or modify
25 it under the terms of the GNU General Public License as published by
26 the Free Software Foundation; either version 2 of the License, or
27 (at your option) any later version.
28
29 This program is distributed in the hope that it will be useful,
30 but WITHOUT ANY WARRANTY; without even the implied warranty of
31 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
32 GNU General Public License for more details.
33
34 You should have received a copy of the GNU General Public License
35 along with this program; if not, write to the Free Software
36 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
37
38*/
39
40/*
41 History of this driver (Steven Toth):
42 I was given a public release of a linux driver that included
43 support for the MaxLinear MXL5005S silicon tuner. Analysis of
44 the tuner driver showed clearly three things.
45
46 1. The tuner driver didn't support the LinuxTV tuner API
47 so the code Realtek added had to be removed.
48
49 2. A significant amount of the driver is reference driver code
50 from MaxLinear, I felt it was important to identify and
51 preserve this.
52
53 3. New code has to be added to interface correctly with the
54 LinuxTV API, as a regular kernel module.
55
56 Other than the reference driver enum's, I've clearly marked
57 sections of the code and retained the copyright of the
58 respective owners.
59*/
60#include <linux/kernel.h>
61#include <linux/init.h>
62#include <linux/module.h>
63#include <linux/string.h>
64#include <linux/slab.h>
65#include <linux/delay.h>
66#include "dvb_frontend.h"
67#include "mxl5005s.h"
68
69static int debug;
70
71#define dprintk(level, arg...) do { \
72 if (level <= debug) \
73 printk(arg); \
74 } while (0)
75
76#define TUNER_REGS_NUM 104
77#define INITCTRL_NUM 40
78
79#ifdef _MXL_PRODUCTION
80#define CHCTRL_NUM 39
81#else
82#define CHCTRL_NUM 36
83#endif
84
85#define MXLCTRL_NUM 189
86#define MASTER_CONTROL_ADDR 9
87
88/* Enumeration of Master Control Register State */
89enum master_control_state {
90 MC_LOAD_START = 1,
91 MC_POWER_DOWN,
92 MC_SYNTH_RESET,
93 MC_SEQ_OFF
94};
95
96/* Enumeration of MXL5005 Tuner Modulation Type */
97enum {
98 MXL_DEFAULT_MODULATION = 0,
99 MXL_DVBT,
100 MXL_ATSC,
101 MXL_QAM,
102 MXL_ANALOG_CABLE,
103 MXL_ANALOG_OTA
104};
105
106/* MXL5005 Tuner Register Struct */
107struct TunerReg {
108 u16 Reg_Num; /* Tuner Register Address */
109 u16 Reg_Val; /* Current sw programmed value waiting to be written */
110};
111
112enum {
113 /* Initialization Control Names */
114 DN_IQTN_AMP_CUT = 1, /* 1 */
115 BB_MODE, /* 2 */
116 BB_BUF, /* 3 */
117 BB_BUF_OA, /* 4 */
118 BB_ALPF_BANDSELECT, /* 5 */
119 BB_IQSWAP, /* 6 */
120 BB_DLPF_BANDSEL, /* 7 */
121 RFSYN_CHP_GAIN, /* 8 */
122 RFSYN_EN_CHP_HIGAIN, /* 9 */
123 AGC_IF, /* 10 */
124 AGC_RF, /* 11 */
125 IF_DIVVAL, /* 12 */
126 IF_VCO_BIAS, /* 13 */
127 CHCAL_INT_MOD_IF, /* 14 */
128 CHCAL_FRAC_MOD_IF, /* 15 */
129 DRV_RES_SEL, /* 16 */
130 I_DRIVER, /* 17 */
131 EN_AAF, /* 18 */
132 EN_3P, /* 19 */
133 EN_AUX_3P, /* 20 */
134 SEL_AAF_BAND, /* 21 */
135 SEQ_ENCLK16_CLK_OUT, /* 22 */
136 SEQ_SEL4_16B, /* 23 */
137 XTAL_CAPSELECT, /* 24 */
138 IF_SEL_DBL, /* 25 */
139 RFSYN_R_DIV, /* 26 */
140 SEQ_EXTSYNTHCALIF, /* 27 */
141 SEQ_EXTDCCAL, /* 28 */
142 AGC_EN_RSSI, /* 29 */
143 RFA_ENCLKRFAGC, /* 30 */
144 RFA_RSSI_REFH, /* 31 */
145 RFA_RSSI_REF, /* 32 */
146 RFA_RSSI_REFL, /* 33 */
147 RFA_FLR, /* 34 */
148 RFA_CEIL, /* 35 */
149 SEQ_EXTIQFSMPULSE, /* 36 */
150 OVERRIDE_1, /* 37 */
151 BB_INITSTATE_DLPF_TUNE, /* 38 */
152 TG_R_DIV, /* 39 */
153 EN_CHP_LIN_B, /* 40 */
154
155 /* Channel Change Control Names */
156 DN_POLY = 51, /* 51 */
157 DN_RFGAIN, /* 52 */
158 DN_CAP_RFLPF, /* 53 */
159 DN_EN_VHFUHFBAR, /* 54 */
160 DN_GAIN_ADJUST, /* 55 */
161 DN_IQTNBUF_AMP, /* 56 */
162 DN_IQTNGNBFBIAS_BST, /* 57 */
163 RFSYN_EN_OUTMUX, /* 58 */
164 RFSYN_SEL_VCO_OUT, /* 59 */
165 RFSYN_SEL_VCO_HI, /* 60 */
166 RFSYN_SEL_DIVM, /* 61 */
167 RFSYN_RF_DIV_BIAS, /* 62 */
168 DN_SEL_FREQ, /* 63 */
169 RFSYN_VCO_BIAS, /* 64 */
170 CHCAL_INT_MOD_RF, /* 65 */
171 CHCAL_FRAC_MOD_RF, /* 66 */
172 RFSYN_LPF_R, /* 67 */
173 CHCAL_EN_INT_RF, /* 68 */
174 TG_LO_DIVVAL, /* 69 */
175 TG_LO_SELVAL, /* 70 */
176 TG_DIV_VAL, /* 71 */
177 TG_VCO_BIAS, /* 72 */
178 SEQ_EXTPOWERUP, /* 73 */
179 OVERRIDE_2, /* 74 */
180 OVERRIDE_3, /* 75 */
181 OVERRIDE_4, /* 76 */
182 SEQ_FSM_PULSE, /* 77 */
183 GPIO_4B, /* 78 */
184 GPIO_3B, /* 79 */
185 GPIO_4, /* 80 */
186 GPIO_3, /* 81 */
187 GPIO_1B, /* 82 */
188 DAC_A_ENABLE, /* 83 */
189 DAC_B_ENABLE, /* 84 */
190 DAC_DIN_A, /* 85 */
191 DAC_DIN_B, /* 86 */
192#ifdef _MXL_PRODUCTION
193 RFSYN_EN_DIV, /* 87 */
194 RFSYN_DIVM, /* 88 */
195 DN_BYPASS_AGC_I2C /* 89 */
196#endif
197};
198
199/*
200 * The following context is source code provided by MaxLinear.
201 * MaxLinear source code - Common_MXL.h (?)
202 */
203
204/* Constants */
205#define MXL5005S_REG_WRITING_TABLE_LEN_MAX 104
206#define MXL5005S_LATCH_BYTE 0xfe
207
208/* Register address, MSB, and LSB */
209#define MXL5005S_BB_IQSWAP_ADDR 59
210#define MXL5005S_BB_IQSWAP_MSB 0
211#define MXL5005S_BB_IQSWAP_LSB 0
212
213#define MXL5005S_BB_DLPF_BANDSEL_ADDR 53
214#define MXL5005S_BB_DLPF_BANDSEL_MSB 4
215#define MXL5005S_BB_DLPF_BANDSEL_LSB 3
216
217/* Standard modes */
218enum {
219 MXL5005S_STANDARD_DVBT,
220 MXL5005S_STANDARD_ATSC,
221};
222#define MXL5005S_STANDARD_MODE_NUM 2
223
224/* Bandwidth modes */
225enum {
226 MXL5005S_BANDWIDTH_6MHZ = 6000000,
227 MXL5005S_BANDWIDTH_7MHZ = 7000000,
228 MXL5005S_BANDWIDTH_8MHZ = 8000000,
229};
230#define MXL5005S_BANDWIDTH_MODE_NUM 3
231
232/* MXL5005 Tuner Control Struct */
233struct TunerControl {
234 u16 Ctrl_Num; /* Control Number */
235 u16 size; /* Number of bits to represent Value */
236 u16 addr[25]; /* Array of Tuner Register Address for each bit pos */
237 u16 bit[25]; /* Array of bit pos in Reg Addr for each bit pos */
238 u16 val[25]; /* Binary representation of Value */
239};
240
241/* MXL5005 Tuner Struct */
242struct mxl5005s_state {
243 u8 Mode; /* 0: Analog Mode ; 1: Digital Mode */
244 u8 IF_Mode; /* for Analog Mode, 0: zero IF; 1: low IF */
245 u32 Chan_Bandwidth; /* filter channel bandwidth (6, 7, 8) */
246 u32 IF_OUT; /* Desired IF Out Frequency */
247 u16 IF_OUT_LOAD; /* IF Out Load Resistor (200/300 Ohms) */
248 u32 RF_IN; /* RF Input Frequency */
249 u32 Fxtal; /* XTAL Frequency */
250 u8 AGC_Mode; /* AGC Mode 0: Dual AGC; 1: Single AGC */
251 u16 TOP; /* Value: take over point */
252 u8 CLOCK_OUT; /* 0: turn off clk out; 1: turn on clock out */
253 u8 DIV_OUT; /* 4MHz or 16MHz */
254 u8 CAPSELECT; /* 0: disable On-Chip pulling cap; 1: enable */
255 u8 EN_RSSI; /* 0: disable RSSI; 1: enable RSSI */
256
257 /* Modulation Type; */
258 /* 0 - Default; 1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
259 u8 Mod_Type;
260
261 /* Tracking Filter Type */
262 /* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */
263 u8 TF_Type;
264
265 /* Calculated Settings */
266 u32 RF_LO; /* Synth RF LO Frequency */
267 u32 IF_LO; /* Synth IF LO Frequency */
268 u32 TG_LO; /* Synth TG_LO Frequency */
269
270 /* Pointers to ControlName Arrays */
271 u16 Init_Ctrl_Num; /* Number of INIT Control Names */
272 struct TunerControl
273 Init_Ctrl[INITCTRL_NUM]; /* INIT Control Names Array Pointer */
274
275 u16 CH_Ctrl_Num; /* Number of CH Control Names */
276 struct TunerControl
277 CH_Ctrl[CHCTRL_NUM]; /* CH Control Name Array Pointer */
278
279 u16 MXL_Ctrl_Num; /* Number of MXL Control Names */
280 struct TunerControl
281 MXL_Ctrl[MXLCTRL_NUM]; /* MXL Control Name Array Pointer */
282
283 /* Pointer to Tuner Register Array */
284 u16 TunerRegs_Num; /* Number of Tuner Registers */
285 struct TunerReg
286 TunerRegs[TUNER_REGS_NUM]; /* Tuner Register Array Pointer */
287
288 /* Linux driver framework specific */
289 struct mxl5005s_config *config;
290 struct dvb_frontend *frontend;
291 struct i2c_adapter *i2c;
292
293 /* Cache values */
294 u32 current_mode;
295
296};
297
298static u16 MXL_GetMasterControl(u8 *MasterReg, int state);
299static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value);
300static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value);
301static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
302 u8 bitVal);
303static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum,
304 u8 *RegVal, int *count);
305static u32 MXL_Ceiling(u32 value, u32 resolution);
306static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal);
307static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
308 u32 value, u16 controlGroup);
309static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val);
310static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
311 u8 *RegVal, int *count);
312static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq);
313static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe);
314static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe);
315static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
316 u8 *RegVal, int *count);
317static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
318 u8 *datatable, u8 len);
319static u16 MXL_IFSynthInit(struct dvb_frontend *fe);
320static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type,
321 u32 bandwidth);
322static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
323 u32 bandwidth);
324
325/* ----------------------------------------------------------------
326 * Begin: Custom code salvaged from the Realtek driver.
327 * Copyright (C) 2008 Realtek
328 * Copyright (C) 2008 Jan Hoogenraad
329 * This code is placed under the terms of the GNU General Public License
330 *
331 * Released by Realtek under GPLv2.
332 * Thanks to Realtek for a lot of support we received !
333 *
334 * Revision: 080314 - original version
335 */
336
337static int mxl5005s_SetRfFreqHz(struct dvb_frontend *fe, unsigned long RfFreqHz)
338{
339 struct mxl5005s_state *state = fe->tuner_priv;
340 unsigned char AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
341 unsigned char ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
342 int TableLen;
343
344 u32 IfDivval = 0;
345 unsigned char MasterControlByte;
346
347 dprintk(1, "%s() freq=%ld\n", __func__, RfFreqHz);
348
349 /* Set MxL5005S tuner RF frequency according to example code. */
350
351 /* Tuner RF frequency setting stage 0 */
352 MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
353 AddrTable[0] = MASTER_CONTROL_ADDR;
354 ByteTable[0] |= state->config->AgcMasterByte;
355
356 mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
357
358 /* Tuner RF frequency setting stage 1 */
359 MXL_TuneRF(fe, RfFreqHz);
360
361 MXL_ControlRead(fe, IF_DIVVAL, &IfDivval);
362
363 MXL_ControlWrite(fe, SEQ_FSM_PULSE, 0);
364 MXL_ControlWrite(fe, SEQ_EXTPOWERUP, 1);
365 MXL_ControlWrite(fe, IF_DIVVAL, 8);
366 MXL_GetCHRegister(fe, AddrTable, ByteTable, &TableLen);
367
368 MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START);
369 AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
370 ByteTable[TableLen] = MasterControlByte |
371 state->config->AgcMasterByte;
372 TableLen += 1;
373
374 mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
375
376 /* Wait 30 ms. */
377 msleep(150);
378
379 /* Tuner RF frequency setting stage 2 */
380 MXL_ControlWrite(fe, SEQ_FSM_PULSE, 1);
381 MXL_ControlWrite(fe, IF_DIVVAL, IfDivval);
382 MXL_GetCHRegister_ZeroIF(fe, AddrTable, ByteTable, &TableLen);
383
384 MXL_GetMasterControl(&MasterControlByte, MC_LOAD_START);
385 AddrTable[TableLen] = MASTER_CONTROL_ADDR ;
386 ByteTable[TableLen] = MasterControlByte |
387 state->config->AgcMasterByte ;
388 TableLen += 1;
389
390 mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
391
392 msleep(100);
393
394 return 0;
395}
396/* End: Custom code taken from the Realtek driver */
397
398/* ----------------------------------------------------------------
399 * Begin: Reference driver code found in the Realtek driver.
400 * Copyright (C) 2008 MaxLinear
401 */
402static u16 MXL5005_RegisterInit(struct dvb_frontend *fe)
403{
404 struct mxl5005s_state *state = fe->tuner_priv;
405 state->TunerRegs_Num = TUNER_REGS_NUM ;
406
407 state->TunerRegs[0].Reg_Num = 9 ;
408 state->TunerRegs[0].Reg_Val = 0x40 ;
409
410 state->TunerRegs[1].Reg_Num = 11 ;
411 state->TunerRegs[1].Reg_Val = 0x19 ;
412
413 state->TunerRegs[2].Reg_Num = 12 ;
414 state->TunerRegs[2].Reg_Val = 0x60 ;
415
416 state->TunerRegs[3].Reg_Num = 13 ;
417 state->TunerRegs[3].Reg_Val = 0x00 ;
418
419 state->TunerRegs[4].Reg_Num = 14 ;
420 state->TunerRegs[4].Reg_Val = 0x00 ;
421
422 state->TunerRegs[5].Reg_Num = 15 ;
423 state->TunerRegs[5].Reg_Val = 0xC0 ;
424
425 state->TunerRegs[6].Reg_Num = 16 ;
426 state->TunerRegs[6].Reg_Val = 0x00 ;
427
428 state->TunerRegs[7].Reg_Num = 17 ;
429 state->TunerRegs[7].Reg_Val = 0x00 ;
430
431 state->TunerRegs[8].Reg_Num = 18 ;
432 state->TunerRegs[8].Reg_Val = 0x00 ;
433
434 state->TunerRegs[9].Reg_Num = 19 ;
435 state->TunerRegs[9].Reg_Val = 0x34 ;
436
437 state->TunerRegs[10].Reg_Num = 21 ;
438 state->TunerRegs[10].Reg_Val = 0x00 ;
439
440 state->TunerRegs[11].Reg_Num = 22 ;
441 state->TunerRegs[11].Reg_Val = 0x6B ;
442
443 state->TunerRegs[12].Reg_Num = 23 ;
444 state->TunerRegs[12].Reg_Val = 0x35 ;
445
446 state->TunerRegs[13].Reg_Num = 24 ;
447 state->TunerRegs[13].Reg_Val = 0x70 ;
448
449 state->TunerRegs[14].Reg_Num = 25 ;
450 state->TunerRegs[14].Reg_Val = 0x3E ;
451
452 state->TunerRegs[15].Reg_Num = 26 ;
453 state->TunerRegs[15].Reg_Val = 0x82 ;
454
455 state->TunerRegs[16].Reg_Num = 31 ;
456 state->TunerRegs[16].Reg_Val = 0x00 ;
457
458 state->TunerRegs[17].Reg_Num = 32 ;
459 state->TunerRegs[17].Reg_Val = 0x40 ;
460
461 state->TunerRegs[18].Reg_Num = 33 ;
462 state->TunerRegs[18].Reg_Val = 0x53 ;
463
464 state->TunerRegs[19].Reg_Num = 34 ;
465 state->TunerRegs[19].Reg_Val = 0x81 ;
466
467 state->TunerRegs[20].Reg_Num = 35 ;
468 state->TunerRegs[20].Reg_Val = 0xC9 ;
469
470 state->TunerRegs[21].Reg_Num = 36 ;
471 state->TunerRegs[21].Reg_Val = 0x01 ;
472
473 state->TunerRegs[22].Reg_Num = 37 ;
474 state->TunerRegs[22].Reg_Val = 0x00 ;
475
476 state->TunerRegs[23].Reg_Num = 41 ;
477 state->TunerRegs[23].Reg_Val = 0x00 ;
478
479 state->TunerRegs[24].Reg_Num = 42 ;
480 state->TunerRegs[24].Reg_Val = 0xF8 ;
481
482 state->TunerRegs[25].Reg_Num = 43 ;
483 state->TunerRegs[25].Reg_Val = 0x43 ;
484
485 state->TunerRegs[26].Reg_Num = 44 ;
486 state->TunerRegs[26].Reg_Val = 0x20 ;
487
488 state->TunerRegs[27].Reg_Num = 45 ;
489 state->TunerRegs[27].Reg_Val = 0x80 ;
490
491 state->TunerRegs[28].Reg_Num = 46 ;
492 state->TunerRegs[28].Reg_Val = 0x88 ;
493
494 state->TunerRegs[29].Reg_Num = 47 ;
495 state->TunerRegs[29].Reg_Val = 0x86 ;
496
497 state->TunerRegs[30].Reg_Num = 48 ;
498 state->TunerRegs[30].Reg_Val = 0x00 ;
499
500 state->TunerRegs[31].Reg_Num = 49 ;
501 state->TunerRegs[31].Reg_Val = 0x00 ;
502
503 state->TunerRegs[32].Reg_Num = 53 ;
504 state->TunerRegs[32].Reg_Val = 0x94 ;
505
506 state->TunerRegs[33].Reg_Num = 54 ;
507 state->TunerRegs[33].Reg_Val = 0xFA ;
508
509 state->TunerRegs[34].Reg_Num = 55 ;
510 state->TunerRegs[34].Reg_Val = 0x92 ;
511
512 state->TunerRegs[35].Reg_Num = 56 ;
513 state->TunerRegs[35].Reg_Val = 0x80 ;
514
515 state->TunerRegs[36].Reg_Num = 57 ;
516 state->TunerRegs[36].Reg_Val = 0x41 ;
517
518 state->TunerRegs[37].Reg_Num = 58 ;
519 state->TunerRegs[37].Reg_Val = 0xDB ;
520
521 state->TunerRegs[38].Reg_Num = 59 ;
522 state->TunerRegs[38].Reg_Val = 0x00 ;
523
524 state->TunerRegs[39].Reg_Num = 60 ;
525 state->TunerRegs[39].Reg_Val = 0x00 ;
526
527 state->TunerRegs[40].Reg_Num = 61 ;
528 state->TunerRegs[40].Reg_Val = 0x00 ;
529
530 state->TunerRegs[41].Reg_Num = 62 ;
531 state->TunerRegs[41].Reg_Val = 0x00 ;
532
533 state->TunerRegs[42].Reg_Num = 65 ;
534 state->TunerRegs[42].Reg_Val = 0xF8 ;
535
536 state->TunerRegs[43].Reg_Num = 66 ;
537 state->TunerRegs[43].Reg_Val = 0xE4 ;
538
539 state->TunerRegs[44].Reg_Num = 67 ;
540 state->TunerRegs[44].Reg_Val = 0x90 ;
541
542 state->TunerRegs[45].Reg_Num = 68 ;
543 state->TunerRegs[45].Reg_Val = 0xC0 ;
544
545 state->TunerRegs[46].Reg_Num = 69 ;
546 state->TunerRegs[46].Reg_Val = 0x01 ;
547
548 state->TunerRegs[47].Reg_Num = 70 ;
549 state->TunerRegs[47].Reg_Val = 0x50 ;
550
551 state->TunerRegs[48].Reg_Num = 71 ;
552 state->TunerRegs[48].Reg_Val = 0x06 ;
553
554 state->TunerRegs[49].Reg_Num = 72 ;
555 state->TunerRegs[49].Reg_Val = 0x00 ;
556
557 state->TunerRegs[50].Reg_Num = 73 ;
558 state->TunerRegs[50].Reg_Val = 0x20 ;
559
560 state->TunerRegs[51].Reg_Num = 76 ;
561 state->TunerRegs[51].Reg_Val = 0xBB ;
562
563 state->TunerRegs[52].Reg_Num = 77 ;
564 state->TunerRegs[52].Reg_Val = 0x13 ;
565
566 state->TunerRegs[53].Reg_Num = 81 ;
567 state->TunerRegs[53].Reg_Val = 0x04 ;
568
569 state->TunerRegs[54].Reg_Num = 82 ;
570 state->TunerRegs[54].Reg_Val = 0x75 ;
571
572 state->TunerRegs[55].Reg_Num = 83 ;
573 state->TunerRegs[55].Reg_Val = 0x00 ;
574
575 state->TunerRegs[56].Reg_Num = 84 ;
576 state->TunerRegs[56].Reg_Val = 0x00 ;
577
578 state->TunerRegs[57].Reg_Num = 85 ;
579 state->TunerRegs[57].Reg_Val = 0x00 ;
580
581 state->TunerRegs[58].Reg_Num = 91 ;
582 state->TunerRegs[58].Reg_Val = 0x70 ;
583
584 state->TunerRegs[59].Reg_Num = 92 ;
585 state->TunerRegs[59].Reg_Val = 0x00 ;
586
587 state->TunerRegs[60].Reg_Num = 93 ;
588 state->TunerRegs[60].Reg_Val = 0x00 ;
589
590 state->TunerRegs[61].Reg_Num = 94 ;
591 state->TunerRegs[61].Reg_Val = 0x00 ;
592
593 state->TunerRegs[62].Reg_Num = 95 ;
594 state->TunerRegs[62].Reg_Val = 0x0C ;
595
596 state->TunerRegs[63].Reg_Num = 96 ;
597 state->TunerRegs[63].Reg_Val = 0x00 ;
598
599 state->TunerRegs[64].Reg_Num = 97 ;
600 state->TunerRegs[64].Reg_Val = 0x00 ;
601
602 state->TunerRegs[65].Reg_Num = 98 ;
603 state->TunerRegs[65].Reg_Val = 0xE2 ;
604
605 state->TunerRegs[66].Reg_Num = 99 ;
606 state->TunerRegs[66].Reg_Val = 0x00 ;
607
608 state->TunerRegs[67].Reg_Num = 100 ;
609 state->TunerRegs[67].Reg_Val = 0x00 ;
610
611 state->TunerRegs[68].Reg_Num = 101 ;
612 state->TunerRegs[68].Reg_Val = 0x12 ;
613
614 state->TunerRegs[69].Reg_Num = 102 ;
615 state->TunerRegs[69].Reg_Val = 0x80 ;
616
617 state->TunerRegs[70].Reg_Num = 103 ;
618 state->TunerRegs[70].Reg_Val = 0x32 ;
619
620 state->TunerRegs[71].Reg_Num = 104 ;
621 state->TunerRegs[71].Reg_Val = 0xB4 ;
622
623 state->TunerRegs[72].Reg_Num = 105 ;
624 state->TunerRegs[72].Reg_Val = 0x60 ;
625
626 state->TunerRegs[73].Reg_Num = 106 ;
627 state->TunerRegs[73].Reg_Val = 0x83 ;
628
629 state->TunerRegs[74].Reg_Num = 107 ;
630 state->TunerRegs[74].Reg_Val = 0x84 ;
631
632 state->TunerRegs[75].Reg_Num = 108 ;
633 state->TunerRegs[75].Reg_Val = 0x9C ;
634
635 state->TunerRegs[76].Reg_Num = 109 ;
636 state->TunerRegs[76].Reg_Val = 0x02 ;
637
638 state->TunerRegs[77].Reg_Num = 110 ;
639 state->TunerRegs[77].Reg_Val = 0x81 ;
640
641 state->TunerRegs[78].Reg_Num = 111 ;
642 state->TunerRegs[78].Reg_Val = 0xC0 ;
643
644 state->TunerRegs[79].Reg_Num = 112 ;
645 state->TunerRegs[79].Reg_Val = 0x10 ;
646
647 state->TunerRegs[80].Reg_Num = 131 ;
648 state->TunerRegs[80].Reg_Val = 0x8A ;
649
650 state->TunerRegs[81].Reg_Num = 132 ;
651 state->TunerRegs[81].Reg_Val = 0x10 ;
652
653 state->TunerRegs[82].Reg_Num = 133 ;
654 state->TunerRegs[82].Reg_Val = 0x24 ;
655
656 state->TunerRegs[83].Reg_Num = 134 ;
657 state->TunerRegs[83].Reg_Val = 0x00 ;
658
659 state->TunerRegs[84].Reg_Num = 135 ;
660 state->TunerRegs[84].Reg_Val = 0x00 ;
661
662 state->TunerRegs[85].Reg_Num = 136 ;
663 state->TunerRegs[85].Reg_Val = 0x7E ;
664
665 state->TunerRegs[86].Reg_Num = 137 ;
666 state->TunerRegs[86].Reg_Val = 0x40 ;
667
668 state->TunerRegs[87].Reg_Num = 138 ;
669 state->TunerRegs[87].Reg_Val = 0x38 ;
670
671 state->TunerRegs[88].Reg_Num = 146 ;
672 state->TunerRegs[88].Reg_Val = 0xF6 ;
673
674 state->TunerRegs[89].Reg_Num = 147 ;
675 state->TunerRegs[89].Reg_Val = 0x1A ;
676
677 state->TunerRegs[90].Reg_Num = 148 ;
678 state->TunerRegs[90].Reg_Val = 0x62 ;
679
680 state->TunerRegs[91].Reg_Num = 149 ;
681 state->TunerRegs[91].Reg_Val = 0x33 ;
682
683 state->TunerRegs[92].Reg_Num = 150 ;
684 state->TunerRegs[92].Reg_Val = 0x80 ;
685
686 state->TunerRegs[93].Reg_Num = 156 ;
687 state->TunerRegs[93].Reg_Val = 0x56 ;
688
689 state->TunerRegs[94].Reg_Num = 157 ;
690 state->TunerRegs[94].Reg_Val = 0x17 ;
691
692 state->TunerRegs[95].Reg_Num = 158 ;
693 state->TunerRegs[95].Reg_Val = 0xA9 ;
694
695 state->TunerRegs[96].Reg_Num = 159 ;
696 state->TunerRegs[96].Reg_Val = 0x00 ;
697
698 state->TunerRegs[97].Reg_Num = 160 ;
699 state->TunerRegs[97].Reg_Val = 0x00 ;
700
701 state->TunerRegs[98].Reg_Num = 161 ;
702 state->TunerRegs[98].Reg_Val = 0x00 ;
703
704 state->TunerRegs[99].Reg_Num = 162 ;
705 state->TunerRegs[99].Reg_Val = 0x40 ;
706
707 state->TunerRegs[100].Reg_Num = 166 ;
708 state->TunerRegs[100].Reg_Val = 0xAE ;
709
710 state->TunerRegs[101].Reg_Num = 167 ;
711 state->TunerRegs[101].Reg_Val = 0x1B ;
712
713 state->TunerRegs[102].Reg_Num = 168 ;
714 state->TunerRegs[102].Reg_Val = 0xF2 ;
715
716 state->TunerRegs[103].Reg_Num = 195 ;
717 state->TunerRegs[103].Reg_Val = 0x00 ;
718
719 return 0 ;
720}
721
722static u16 MXL5005_ControlInit(struct dvb_frontend *fe)
723{
724 struct mxl5005s_state *state = fe->tuner_priv;
725 state->Init_Ctrl_Num = INITCTRL_NUM;
726
727 state->Init_Ctrl[0].Ctrl_Num = DN_IQTN_AMP_CUT ;
728 state->Init_Ctrl[0].size = 1 ;
729 state->Init_Ctrl[0].addr[0] = 73;
730 state->Init_Ctrl[0].bit[0] = 7;
731 state->Init_Ctrl[0].val[0] = 0;
732
733 state->Init_Ctrl[1].Ctrl_Num = BB_MODE ;
734 state->Init_Ctrl[1].size = 1 ;
735 state->Init_Ctrl[1].addr[0] = 53;
736 state->Init_Ctrl[1].bit[0] = 2;
737 state->Init_Ctrl[1].val[0] = 1;
738
739 state->Init_Ctrl[2].Ctrl_Num = BB_BUF ;
740 state->Init_Ctrl[2].size = 2 ;
741 state->Init_Ctrl[2].addr[0] = 53;
742 state->Init_Ctrl[2].bit[0] = 1;
743 state->Init_Ctrl[2].val[0] = 0;
744 state->Init_Ctrl[2].addr[1] = 57;
745 state->Init_Ctrl[2].bit[1] = 0;
746 state->Init_Ctrl[2].val[1] = 1;
747
748 state->Init_Ctrl[3].Ctrl_Num = BB_BUF_OA ;
749 state->Init_Ctrl[3].size = 1 ;
750 state->Init_Ctrl[3].addr[0] = 53;
751 state->Init_Ctrl[3].bit[0] = 0;
752 state->Init_Ctrl[3].val[0] = 0;
753
754 state->Init_Ctrl[4].Ctrl_Num = BB_ALPF_BANDSELECT ;
755 state->Init_Ctrl[4].size = 3 ;
756 state->Init_Ctrl[4].addr[0] = 53;
757 state->Init_Ctrl[4].bit[0] = 5;
758 state->Init_Ctrl[4].val[0] = 0;
759 state->Init_Ctrl[4].addr[1] = 53;
760 state->Init_Ctrl[4].bit[1] = 6;
761 state->Init_Ctrl[4].val[1] = 0;
762 state->Init_Ctrl[4].addr[2] = 53;
763 state->Init_Ctrl[4].bit[2] = 7;
764 state->Init_Ctrl[4].val[2] = 1;
765
766 state->Init_Ctrl[5].Ctrl_Num = BB_IQSWAP ;
767 state->Init_Ctrl[5].size = 1 ;
768 state->Init_Ctrl[5].addr[0] = 59;
769 state->Init_Ctrl[5].bit[0] = 0;
770 state->Init_Ctrl[5].val[0] = 0;
771
772 state->Init_Ctrl[6].Ctrl_Num = BB_DLPF_BANDSEL ;
773 state->Init_Ctrl[6].size = 2 ;
774 state->Init_Ctrl[6].addr[0] = 53;
775 state->Init_Ctrl[6].bit[0] = 3;
776 state->Init_Ctrl[6].val[0] = 0;
777 state->Init_Ctrl[6].addr[1] = 53;
778 state->Init_Ctrl[6].bit[1] = 4;
779 state->Init_Ctrl[6].val[1] = 1;
780
781 state->Init_Ctrl[7].Ctrl_Num = RFSYN_CHP_GAIN ;
782 state->Init_Ctrl[7].size = 4 ;
783 state->Init_Ctrl[7].addr[0] = 22;
784 state->Init_Ctrl[7].bit[0] = 4;
785 state->Init_Ctrl[7].val[0] = 0;
786 state->Init_Ctrl[7].addr[1] = 22;
787 state->Init_Ctrl[7].bit[1] = 5;
788 state->Init_Ctrl[7].val[1] = 1;
789 state->Init_Ctrl[7].addr[2] = 22;
790 state->Init_Ctrl[7].bit[2] = 6;
791 state->Init_Ctrl[7].val[2] = 1;
792 state->Init_Ctrl[7].addr[3] = 22;
793 state->Init_Ctrl[7].bit[3] = 7;
794 state->Init_Ctrl[7].val[3] = 0;
795
796 state->Init_Ctrl[8].Ctrl_Num = RFSYN_EN_CHP_HIGAIN ;
797 state->Init_Ctrl[8].size = 1 ;
798 state->Init_Ctrl[8].addr[0] = 22;
799 state->Init_Ctrl[8].bit[0] = 2;
800 state->Init_Ctrl[8].val[0] = 0;
801
802 state->Init_Ctrl[9].Ctrl_Num = AGC_IF ;
803 state->Init_Ctrl[9].size = 4 ;
804 state->Init_Ctrl[9].addr[0] = 76;
805 state->Init_Ctrl[9].bit[0] = 0;
806 state->Init_Ctrl[9].val[0] = 1;
807 state->Init_Ctrl[9].addr[1] = 76;
808 state->Init_Ctrl[9].bit[1] = 1;
809 state->Init_Ctrl[9].val[1] = 1;
810 state->Init_Ctrl[9].addr[2] = 76;
811 state->Init_Ctrl[9].bit[2] = 2;
812 state->Init_Ctrl[9].val[2] = 0;
813 state->Init_Ctrl[9].addr[3] = 76;
814 state->Init_Ctrl[9].bit[3] = 3;
815 state->Init_Ctrl[9].val[3] = 1;
816
817 state->Init_Ctrl[10].Ctrl_Num = AGC_RF ;
818 state->Init_Ctrl[10].size = 4 ;
819 state->Init_Ctrl[10].addr[0] = 76;
820 state->Init_Ctrl[10].bit[0] = 4;
821 state->Init_Ctrl[10].val[0] = 1;
822 state->Init_Ctrl[10].addr[1] = 76;
823 state->Init_Ctrl[10].bit[1] = 5;
824 state->Init_Ctrl[10].val[1] = 1;
825 state->Init_Ctrl[10].addr[2] = 76;
826 state->Init_Ctrl[10].bit[2] = 6;
827 state->Init_Ctrl[10].val[2] = 0;
828 state->Init_Ctrl[10].addr[3] = 76;
829 state->Init_Ctrl[10].bit[3] = 7;
830 state->Init_Ctrl[10].val[3] = 1;
831
832 state->Init_Ctrl[11].Ctrl_Num = IF_DIVVAL ;
833 state->Init_Ctrl[11].size = 5 ;
834 state->Init_Ctrl[11].addr[0] = 43;
835 state->Init_Ctrl[11].bit[0] = 3;
836 state->Init_Ctrl[11].val[0] = 0;
837 state->Init_Ctrl[11].addr[1] = 43;
838 state->Init_Ctrl[11].bit[1] = 4;
839 state->Init_Ctrl[11].val[1] = 0;
840 state->Init_Ctrl[11].addr[2] = 43;
841 state->Init_Ctrl[11].bit[2] = 5;
842 state->Init_Ctrl[11].val[2] = 0;
843 state->Init_Ctrl[11].addr[3] = 43;
844 state->Init_Ctrl[11].bit[3] = 6;
845 state->Init_Ctrl[11].val[3] = 1;
846 state->Init_Ctrl[11].addr[4] = 43;
847 state->Init_Ctrl[11].bit[4] = 7;
848 state->Init_Ctrl[11].val[4] = 0;
849
850 state->Init_Ctrl[12].Ctrl_Num = IF_VCO_BIAS ;
851 state->Init_Ctrl[12].size = 6 ;
852 state->Init_Ctrl[12].addr[0] = 44;
853 state->Init_Ctrl[12].bit[0] = 2;
854 state->Init_Ctrl[12].val[0] = 0;
855 state->Init_Ctrl[12].addr[1] = 44;
856 state->Init_Ctrl[12].bit[1] = 3;
857 state->Init_Ctrl[12].val[1] = 0;
858 state->Init_Ctrl[12].addr[2] = 44;
859 state->Init_Ctrl[12].bit[2] = 4;
860 state->Init_Ctrl[12].val[2] = 0;
861 state->Init_Ctrl[12].addr[3] = 44;
862 state->Init_Ctrl[12].bit[3] = 5;
863 state->Init_Ctrl[12].val[3] = 1;
864 state->Init_Ctrl[12].addr[4] = 44;
865 state->Init_Ctrl[12].bit[4] = 6;
866 state->Init_Ctrl[12].val[4] = 0;
867 state->Init_Ctrl[12].addr[5] = 44;
868 state->Init_Ctrl[12].bit[5] = 7;
869 state->Init_Ctrl[12].val[5] = 0;
870
871 state->Init_Ctrl[13].Ctrl_Num = CHCAL_INT_MOD_IF ;
872 state->Init_Ctrl[13].size = 7 ;
873 state->Init_Ctrl[13].addr[0] = 11;
874 state->Init_Ctrl[13].bit[0] = 0;
875 state->Init_Ctrl[13].val[0] = 1;
876 state->Init_Ctrl[13].addr[1] = 11;
877 state->Init_Ctrl[13].bit[1] = 1;
878 state->Init_Ctrl[13].val[1] = 0;
879 state->Init_Ctrl[13].addr[2] = 11;
880 state->Init_Ctrl[13].bit[2] = 2;
881 state->Init_Ctrl[13].val[2] = 0;
882 state->Init_Ctrl[13].addr[3] = 11;
883 state->Init_Ctrl[13].bit[3] = 3;
884 state->Init_Ctrl[13].val[3] = 1;
885 state->Init_Ctrl[13].addr[4] = 11;
886 state->Init_Ctrl[13].bit[4] = 4;
887 state->Init_Ctrl[13].val[4] = 1;
888 state->Init_Ctrl[13].addr[5] = 11;
889 state->Init_Ctrl[13].bit[5] = 5;
890 state->Init_Ctrl[13].val[5] = 0;
891 state->Init_Ctrl[13].addr[6] = 11;
892 state->Init_Ctrl[13].bit[6] = 6;
893 state->Init_Ctrl[13].val[6] = 0;
894
895 state->Init_Ctrl[14].Ctrl_Num = CHCAL_FRAC_MOD_IF ;
896 state->Init_Ctrl[14].size = 16 ;
897 state->Init_Ctrl[14].addr[0] = 13;
898 state->Init_Ctrl[14].bit[0] = 0;
899 state->Init_Ctrl[14].val[0] = 0;
900 state->Init_Ctrl[14].addr[1] = 13;
901 state->Init_Ctrl[14].bit[1] = 1;
902 state->Init_Ctrl[14].val[1] = 0;
903 state->Init_Ctrl[14].addr[2] = 13;
904 state->Init_Ctrl[14].bit[2] = 2;
905 state->Init_Ctrl[14].val[2] = 0;
906 state->Init_Ctrl[14].addr[3] = 13;
907 state->Init_Ctrl[14].bit[3] = 3;
908 state->Init_Ctrl[14].val[3] = 0;
909 state->Init_Ctrl[14].addr[4] = 13;
910 state->Init_Ctrl[14].bit[4] = 4;
911 state->Init_Ctrl[14].val[4] = 0;
912 state->Init_Ctrl[14].addr[5] = 13;
913 state->Init_Ctrl[14].bit[5] = 5;
914 state->Init_Ctrl[14].val[5] = 0;
915 state->Init_Ctrl[14].addr[6] = 13;
916 state->Init_Ctrl[14].bit[6] = 6;
917 state->Init_Ctrl[14].val[6] = 0;
918 state->Init_Ctrl[14].addr[7] = 13;
919 state->Init_Ctrl[14].bit[7] = 7;
920 state->Init_Ctrl[14].val[7] = 0;
921 state->Init_Ctrl[14].addr[8] = 12;
922 state->Init_Ctrl[14].bit[8] = 0;
923 state->Init_Ctrl[14].val[8] = 0;
924 state->Init_Ctrl[14].addr[9] = 12;
925 state->Init_Ctrl[14].bit[9] = 1;
926 state->Init_Ctrl[14].val[9] = 0;
927 state->Init_Ctrl[14].addr[10] = 12;
928 state->Init_Ctrl[14].bit[10] = 2;
929 state->Init_Ctrl[14].val[10] = 0;
930 state->Init_Ctrl[14].addr[11] = 12;
931 state->Init_Ctrl[14].bit[11] = 3;
932 state->Init_Ctrl[14].val[11] = 0;
933 state->Init_Ctrl[14].addr[12] = 12;
934 state->Init_Ctrl[14].bit[12] = 4;
935 state->Init_Ctrl[14].val[12] = 0;
936 state->Init_Ctrl[14].addr[13] = 12;
937 state->Init_Ctrl[14].bit[13] = 5;
938 state->Init_Ctrl[14].val[13] = 1;
939 state->Init_Ctrl[14].addr[14] = 12;
940 state->Init_Ctrl[14].bit[14] = 6;
941 state->Init_Ctrl[14].val[14] = 1;
942 state->Init_Ctrl[14].addr[15] = 12;
943 state->Init_Ctrl[14].bit[15] = 7;
944 state->Init_Ctrl[14].val[15] = 0;
945
946 state->Init_Ctrl[15].Ctrl_Num = DRV_RES_SEL ;
947 state->Init_Ctrl[15].size = 3 ;
948 state->Init_Ctrl[15].addr[0] = 147;
949 state->Init_Ctrl[15].bit[0] = 2;
950 state->Init_Ctrl[15].val[0] = 0;
951 state->Init_Ctrl[15].addr[1] = 147;
952 state->Init_Ctrl[15].bit[1] = 3;
953 state->Init_Ctrl[15].val[1] = 1;
954 state->Init_Ctrl[15].addr[2] = 147;
955 state->Init_Ctrl[15].bit[2] = 4;
956 state->Init_Ctrl[15].val[2] = 1;
957
958 state->Init_Ctrl[16].Ctrl_Num = I_DRIVER ;
959 state->Init_Ctrl[16].size = 2 ;
960 state->Init_Ctrl[16].addr[0] = 147;
961 state->Init_Ctrl[16].bit[0] = 0;
962 state->Init_Ctrl[16].val[0] = 0;
963 state->Init_Ctrl[16].addr[1] = 147;
964 state->Init_Ctrl[16].bit[1] = 1;
965 state->Init_Ctrl[16].val[1] = 1;
966
967 state->Init_Ctrl[17].Ctrl_Num = EN_AAF ;
968 state->Init_Ctrl[17].size = 1 ;
969 state->Init_Ctrl[17].addr[0] = 147;
970 state->Init_Ctrl[17].bit[0] = 7;
971 state->Init_Ctrl[17].val[0] = 0;
972
973 state->Init_Ctrl[18].Ctrl_Num = EN_3P ;
974 state->Init_Ctrl[18].size = 1 ;
975 state->Init_Ctrl[18].addr[0] = 147;
976 state->Init_Ctrl[18].bit[0] = 6;
977 state->Init_Ctrl[18].val[0] = 0;
978
979 state->Init_Ctrl[19].Ctrl_Num = EN_AUX_3P ;
980 state->Init_Ctrl[19].size = 1 ;
981 state->Init_Ctrl[19].addr[0] = 156;
982 state->Init_Ctrl[19].bit[0] = 0;
983 state->Init_Ctrl[19].val[0] = 0;
984
985 state->Init_Ctrl[20].Ctrl_Num = SEL_AAF_BAND ;
986 state->Init_Ctrl[20].size = 1 ;
987 state->Init_Ctrl[20].addr[0] = 147;
988 state->Init_Ctrl[20].bit[0] = 5;
989 state->Init_Ctrl[20].val[0] = 0;
990
991 state->Init_Ctrl[21].Ctrl_Num = SEQ_ENCLK16_CLK_OUT ;
992 state->Init_Ctrl[21].size = 1 ;
993 state->Init_Ctrl[21].addr[0] = 137;
994 state->Init_Ctrl[21].bit[0] = 4;
995 state->Init_Ctrl[21].val[0] = 0;
996
997 state->Init_Ctrl[22].Ctrl_Num = SEQ_SEL4_16B ;
998 state->Init_Ctrl[22].size = 1 ;
999 state->Init_Ctrl[22].addr[0] = 137;
1000 state->Init_Ctrl[22].bit[0] = 7;
1001 state->Init_Ctrl[22].val[0] = 0;
1002
1003 state->Init_Ctrl[23].Ctrl_Num = XTAL_CAPSELECT ;
1004 state->Init_Ctrl[23].size = 1 ;
1005 state->Init_Ctrl[23].addr[0] = 91;
1006 state->Init_Ctrl[23].bit[0] = 5;
1007 state->Init_Ctrl[23].val[0] = 1;
1008
1009 state->Init_Ctrl[24].Ctrl_Num = IF_SEL_DBL ;
1010 state->Init_Ctrl[24].size = 1 ;
1011 state->Init_Ctrl[24].addr[0] = 43;
1012 state->Init_Ctrl[24].bit[0] = 0;
1013 state->Init_Ctrl[24].val[0] = 1;
1014
1015 state->Init_Ctrl[25].Ctrl_Num = RFSYN_R_DIV ;
1016 state->Init_Ctrl[25].size = 2 ;
1017 state->Init_Ctrl[25].addr[0] = 22;
1018 state->Init_Ctrl[25].bit[0] = 0;
1019 state->Init_Ctrl[25].val[0] = 1;
1020 state->Init_Ctrl[25].addr[1] = 22;
1021 state->Init_Ctrl[25].bit[1] = 1;
1022 state->Init_Ctrl[25].val[1] = 1;
1023
1024 state->Init_Ctrl[26].Ctrl_Num = SEQ_EXTSYNTHCALIF ;
1025 state->Init_Ctrl[26].size = 1 ;
1026 state->Init_Ctrl[26].addr[0] = 134;
1027 state->Init_Ctrl[26].bit[0] = 2;
1028 state->Init_Ctrl[26].val[0] = 0;
1029
1030 state->Init_Ctrl[27].Ctrl_Num = SEQ_EXTDCCAL ;
1031 state->Init_Ctrl[27].size = 1 ;
1032 state->Init_Ctrl[27].addr[0] = 137;
1033 state->Init_Ctrl[27].bit[0] = 3;
1034 state->Init_Ctrl[27].val[0] = 0;
1035
1036 state->Init_Ctrl[28].Ctrl_Num = AGC_EN_RSSI ;
1037 state->Init_Ctrl[28].size = 1 ;
1038 state->Init_Ctrl[28].addr[0] = 77;
1039 state->Init_Ctrl[28].bit[0] = 7;
1040 state->Init_Ctrl[28].val[0] = 0;
1041
1042 state->Init_Ctrl[29].Ctrl_Num = RFA_ENCLKRFAGC ;
1043 state->Init_Ctrl[29].size = 1 ;
1044 state->Init_Ctrl[29].addr[0] = 166;
1045 state->Init_Ctrl[29].bit[0] = 7;
1046 state->Init_Ctrl[29].val[0] = 1;
1047
1048 state->Init_Ctrl[30].Ctrl_Num = RFA_RSSI_REFH ;
1049 state->Init_Ctrl[30].size = 3 ;
1050 state->Init_Ctrl[30].addr[0] = 166;
1051 state->Init_Ctrl[30].bit[0] = 0;
1052 state->Init_Ctrl[30].val[0] = 0;
1053 state->Init_Ctrl[30].addr[1] = 166;
1054 state->Init_Ctrl[30].bit[1] = 1;
1055 state->Init_Ctrl[30].val[1] = 1;
1056 state->Init_Ctrl[30].addr[2] = 166;
1057 state->Init_Ctrl[30].bit[2] = 2;
1058 state->Init_Ctrl[30].val[2] = 1;
1059
1060 state->Init_Ctrl[31].Ctrl_Num = RFA_RSSI_REF ;
1061 state->Init_Ctrl[31].size = 3 ;
1062 state->Init_Ctrl[31].addr[0] = 166;
1063 state->Init_Ctrl[31].bit[0] = 3;
1064 state->Init_Ctrl[31].val[0] = 1;
1065 state->Init_Ctrl[31].addr[1] = 166;
1066 state->Init_Ctrl[31].bit[1] = 4;
1067 state->Init_Ctrl[31].val[1] = 0;
1068 state->Init_Ctrl[31].addr[2] = 166;
1069 state->Init_Ctrl[31].bit[2] = 5;
1070 state->Init_Ctrl[31].val[2] = 1;
1071
1072 state->Init_Ctrl[32].Ctrl_Num = RFA_RSSI_REFL ;
1073 state->Init_Ctrl[32].size = 3 ;
1074 state->Init_Ctrl[32].addr[0] = 167;
1075 state->Init_Ctrl[32].bit[0] = 0;
1076 state->Init_Ctrl[32].val[0] = 1;
1077 state->Init_Ctrl[32].addr[1] = 167;
1078 state->Init_Ctrl[32].bit[1] = 1;
1079 state->Init_Ctrl[32].val[1] = 1;
1080 state->Init_Ctrl[32].addr[2] = 167;
1081 state->Init_Ctrl[32].bit[2] = 2;
1082 state->Init_Ctrl[32].val[2] = 0;
1083
1084 state->Init_Ctrl[33].Ctrl_Num = RFA_FLR ;
1085 state->Init_Ctrl[33].size = 4 ;
1086 state->Init_Ctrl[33].addr[0] = 168;
1087 state->Init_Ctrl[33].bit[0] = 0;
1088 state->Init_Ctrl[33].val[0] = 0;
1089 state->Init_Ctrl[33].addr[1] = 168;
1090 state->Init_Ctrl[33].bit[1] = 1;
1091 state->Init_Ctrl[33].val[1] = 1;
1092 state->Init_Ctrl[33].addr[2] = 168;
1093 state->Init_Ctrl[33].bit[2] = 2;
1094 state->Init_Ctrl[33].val[2] = 0;
1095 state->Init_Ctrl[33].addr[3] = 168;
1096 state->Init_Ctrl[33].bit[3] = 3;
1097 state->Init_Ctrl[33].val[3] = 0;
1098
1099 state->Init_Ctrl[34].Ctrl_Num = RFA_CEIL ;
1100 state->Init_Ctrl[34].size = 4 ;
1101 state->Init_Ctrl[34].addr[0] = 168;
1102 state->Init_Ctrl[34].bit[0] = 4;
1103 state->Init_Ctrl[34].val[0] = 1;
1104 state->Init_Ctrl[34].addr[1] = 168;
1105 state->Init_Ctrl[34].bit[1] = 5;
1106 state->Init_Ctrl[34].val[1] = 1;
1107 state->Init_Ctrl[34].addr[2] = 168;
1108 state->Init_Ctrl[34].bit[2] = 6;
1109 state->Init_Ctrl[34].val[2] = 1;
1110 state->Init_Ctrl[34].addr[3] = 168;
1111 state->Init_Ctrl[34].bit[3] = 7;
1112 state->Init_Ctrl[34].val[3] = 1;
1113
1114 state->Init_Ctrl[35].Ctrl_Num = SEQ_EXTIQFSMPULSE ;
1115 state->Init_Ctrl[35].size = 1 ;
1116 state->Init_Ctrl[35].addr[0] = 135;
1117 state->Init_Ctrl[35].bit[0] = 0;
1118 state->Init_Ctrl[35].val[0] = 0;
1119
1120 state->Init_Ctrl[36].Ctrl_Num = OVERRIDE_1 ;
1121 state->Init_Ctrl[36].size = 1 ;
1122 state->Init_Ctrl[36].addr[0] = 56;
1123 state->Init_Ctrl[36].bit[0] = 3;
1124 state->Init_Ctrl[36].val[0] = 0;
1125
1126 state->Init_Ctrl[37].Ctrl_Num = BB_INITSTATE_DLPF_TUNE ;
1127 state->Init_Ctrl[37].size = 7 ;
1128 state->Init_Ctrl[37].addr[0] = 59;
1129 state->Init_Ctrl[37].bit[0] = 1;
1130 state->Init_Ctrl[37].val[0] = 0;
1131 state->Init_Ctrl[37].addr[1] = 59;
1132 state->Init_Ctrl[37].bit[1] = 2;
1133 state->Init_Ctrl[37].val[1] = 0;
1134 state->Init_Ctrl[37].addr[2] = 59;
1135 state->Init_Ctrl[37].bit[2] = 3;
1136 state->Init_Ctrl[37].val[2] = 0;
1137 state->Init_Ctrl[37].addr[3] = 59;
1138 state->Init_Ctrl[37].bit[3] = 4;
1139 state->Init_Ctrl[37].val[3] = 0;
1140 state->Init_Ctrl[37].addr[4] = 59;
1141 state->Init_Ctrl[37].bit[4] = 5;
1142 state->Init_Ctrl[37].val[4] = 0;
1143 state->Init_Ctrl[37].addr[5] = 59;
1144 state->Init_Ctrl[37].bit[5] = 6;
1145 state->Init_Ctrl[37].val[5] = 0;
1146 state->Init_Ctrl[37].addr[6] = 59;
1147 state->Init_Ctrl[37].bit[6] = 7;
1148 state->Init_Ctrl[37].val[6] = 0;
1149
1150 state->Init_Ctrl[38].Ctrl_Num = TG_R_DIV ;
1151 state->Init_Ctrl[38].size = 6 ;
1152 state->Init_Ctrl[38].addr[0] = 32;
1153 state->Init_Ctrl[38].bit[0] = 2;
1154 state->Init_Ctrl[38].val[0] = 0;
1155 state->Init_Ctrl[38].addr[1] = 32;
1156 state->Init_Ctrl[38].bit[1] = 3;
1157 state->Init_Ctrl[38].val[1] = 0;
1158 state->Init_Ctrl[38].addr[2] = 32;
1159 state->Init_Ctrl[38].bit[2] = 4;
1160 state->Init_Ctrl[38].val[2] = 0;
1161 state->Init_Ctrl[38].addr[3] = 32;
1162 state->Init_Ctrl[38].bit[3] = 5;
1163 state->Init_Ctrl[38].val[3] = 0;
1164 state->Init_Ctrl[38].addr[4] = 32;
1165 state->Init_Ctrl[38].bit[4] = 6;
1166 state->Init_Ctrl[38].val[4] = 1;
1167 state->Init_Ctrl[38].addr[5] = 32;
1168 state->Init_Ctrl[38].bit[5] = 7;
1169 state->Init_Ctrl[38].val[5] = 0;
1170
1171 state->Init_Ctrl[39].Ctrl_Num = EN_CHP_LIN_B ;
1172 state->Init_Ctrl[39].size = 1 ;
1173 state->Init_Ctrl[39].addr[0] = 25;
1174 state->Init_Ctrl[39].bit[0] = 3;
1175 state->Init_Ctrl[39].val[0] = 1;
1176
1177
1178 state->CH_Ctrl_Num = CHCTRL_NUM ;
1179
1180 state->CH_Ctrl[0].Ctrl_Num = DN_POLY ;
1181 state->CH_Ctrl[0].size = 2 ;
1182 state->CH_Ctrl[0].addr[0] = 68;
1183 state->CH_Ctrl[0].bit[0] = 6;
1184 state->CH_Ctrl[0].val[0] = 1;
1185 state->CH_Ctrl[0].addr[1] = 68;
1186 state->CH_Ctrl[0].bit[1] = 7;
1187 state->CH_Ctrl[0].val[1] = 1;
1188
1189 state->CH_Ctrl[1].Ctrl_Num = DN_RFGAIN ;
1190 state->CH_Ctrl[1].size = 2 ;
1191 state->CH_Ctrl[1].addr[0] = 70;
1192 state->CH_Ctrl[1].bit[0] = 6;
1193 state->CH_Ctrl[1].val[0] = 1;
1194 state->CH_Ctrl[1].addr[1] = 70;
1195 state->CH_Ctrl[1].bit[1] = 7;
1196 state->CH_Ctrl[1].val[1] = 0;
1197
1198 state->CH_Ctrl[2].Ctrl_Num = DN_CAP_RFLPF ;
1199 state->CH_Ctrl[2].size = 9 ;
1200 state->CH_Ctrl[2].addr[0] = 69;
1201 state->CH_Ctrl[2].bit[0] = 5;
1202 state->CH_Ctrl[2].val[0] = 0;
1203 state->CH_Ctrl[2].addr[1] = 69;
1204 state->CH_Ctrl[2].bit[1] = 6;
1205 state->CH_Ctrl[2].val[1] = 0;
1206 state->CH_Ctrl[2].addr[2] = 69;
1207 state->CH_Ctrl[2].bit[2] = 7;
1208 state->CH_Ctrl[2].val[2] = 0;
1209 state->CH_Ctrl[2].addr[3] = 68;
1210 state->CH_Ctrl[2].bit[3] = 0;
1211 state->CH_Ctrl[2].val[3] = 0;
1212 state->CH_Ctrl[2].addr[4] = 68;
1213 state->CH_Ctrl[2].bit[4] = 1;
1214 state->CH_Ctrl[2].val[4] = 0;
1215 state->CH_Ctrl[2].addr[5] = 68;
1216 state->CH_Ctrl[2].bit[5] = 2;
1217 state->CH_Ctrl[2].val[5] = 0;
1218 state->CH_Ctrl[2].addr[6] = 68;
1219 state->CH_Ctrl[2].bit[6] = 3;
1220 state->CH_Ctrl[2].val[6] = 0;
1221 state->CH_Ctrl[2].addr[7] = 68;
1222 state->CH_Ctrl[2].bit[7] = 4;
1223 state->CH_Ctrl[2].val[7] = 0;
1224 state->CH_Ctrl[2].addr[8] = 68;
1225 state->CH_Ctrl[2].bit[8] = 5;
1226 state->CH_Ctrl[2].val[8] = 0;
1227
1228 state->CH_Ctrl[3].Ctrl_Num = DN_EN_VHFUHFBAR ;
1229 state->CH_Ctrl[3].size = 1 ;
1230 state->CH_Ctrl[3].addr[0] = 70;
1231 state->CH_Ctrl[3].bit[0] = 5;
1232 state->CH_Ctrl[3].val[0] = 0;
1233
1234 state->CH_Ctrl[4].Ctrl_Num = DN_GAIN_ADJUST ;
1235 state->CH_Ctrl[4].size = 3 ;
1236 state->CH_Ctrl[4].addr[0] = 73;
1237 state->CH_Ctrl[4].bit[0] = 4;
1238 state->CH_Ctrl[4].val[0] = 0;
1239 state->CH_Ctrl[4].addr[1] = 73;
1240 state->CH_Ctrl[4].bit[1] = 5;
1241 state->CH_Ctrl[4].val[1] = 1;
1242 state->CH_Ctrl[4].addr[2] = 73;
1243 state->CH_Ctrl[4].bit[2] = 6;
1244 state->CH_Ctrl[4].val[2] = 0;
1245
1246 state->CH_Ctrl[5].Ctrl_Num = DN_IQTNBUF_AMP ;
1247 state->CH_Ctrl[5].size = 4 ;
1248 state->CH_Ctrl[5].addr[0] = 70;
1249 state->CH_Ctrl[5].bit[0] = 0;
1250 state->CH_Ctrl[5].val[0] = 0;
1251 state->CH_Ctrl[5].addr[1] = 70;
1252 state->CH_Ctrl[5].bit[1] = 1;
1253 state->CH_Ctrl[5].val[1] = 0;
1254 state->CH_Ctrl[5].addr[2] = 70;
1255 state->CH_Ctrl[5].bit[2] = 2;
1256 state->CH_Ctrl[5].val[2] = 0;
1257 state->CH_Ctrl[5].addr[3] = 70;
1258 state->CH_Ctrl[5].bit[3] = 3;
1259 state->CH_Ctrl[5].val[3] = 0;
1260
1261 state->CH_Ctrl[6].Ctrl_Num = DN_IQTNGNBFBIAS_BST ;
1262 state->CH_Ctrl[6].size = 1 ;
1263 state->CH_Ctrl[6].addr[0] = 70;
1264 state->CH_Ctrl[6].bit[0] = 4;
1265 state->CH_Ctrl[6].val[0] = 1;
1266
1267 state->CH_Ctrl[7].Ctrl_Num = RFSYN_EN_OUTMUX ;
1268 state->CH_Ctrl[7].size = 1 ;
1269 state->CH_Ctrl[7].addr[0] = 111;
1270 state->CH_Ctrl[7].bit[0] = 4;
1271 state->CH_Ctrl[7].val[0] = 0;
1272
1273 state->CH_Ctrl[8].Ctrl_Num = RFSYN_SEL_VCO_OUT ;
1274 state->CH_Ctrl[8].size = 1 ;
1275 state->CH_Ctrl[8].addr[0] = 111;
1276 state->CH_Ctrl[8].bit[0] = 7;
1277 state->CH_Ctrl[8].val[0] = 1;
1278
1279 state->CH_Ctrl[9].Ctrl_Num = RFSYN_SEL_VCO_HI ;
1280 state->CH_Ctrl[9].size = 1 ;
1281 state->CH_Ctrl[9].addr[0] = 111;
1282 state->CH_Ctrl[9].bit[0] = 6;
1283 state->CH_Ctrl[9].val[0] = 1;
1284
1285 state->CH_Ctrl[10].Ctrl_Num = RFSYN_SEL_DIVM ;
1286 state->CH_Ctrl[10].size = 1 ;
1287 state->CH_Ctrl[10].addr[0] = 111;
1288 state->CH_Ctrl[10].bit[0] = 5;
1289 state->CH_Ctrl[10].val[0] = 0;
1290
1291 state->CH_Ctrl[11].Ctrl_Num = RFSYN_RF_DIV_BIAS ;
1292 state->CH_Ctrl[11].size = 2 ;
1293 state->CH_Ctrl[11].addr[0] = 110;
1294 state->CH_Ctrl[11].bit[0] = 0;
1295 state->CH_Ctrl[11].val[0] = 1;
1296 state->CH_Ctrl[11].addr[1] = 110;
1297 state->CH_Ctrl[11].bit[1] = 1;
1298 state->CH_Ctrl[11].val[1] = 0;
1299
1300 state->CH_Ctrl[12].Ctrl_Num = DN_SEL_FREQ ;
1301 state->CH_Ctrl[12].size = 3 ;
1302 state->CH_Ctrl[12].addr[0] = 69;
1303 state->CH_Ctrl[12].bit[0] = 2;
1304 state->CH_Ctrl[12].val[0] = 0;
1305 state->CH_Ctrl[12].addr[1] = 69;
1306 state->CH_Ctrl[12].bit[1] = 3;
1307 state->CH_Ctrl[12].val[1] = 0;
1308 state->CH_Ctrl[12].addr[2] = 69;
1309 state->CH_Ctrl[12].bit[2] = 4;
1310 state->CH_Ctrl[12].val[2] = 0;
1311
1312 state->CH_Ctrl[13].Ctrl_Num = RFSYN_VCO_BIAS ;
1313 state->CH_Ctrl[13].size = 6 ;
1314 state->CH_Ctrl[13].addr[0] = 110;
1315 state->CH_Ctrl[13].bit[0] = 2;
1316 state->CH_Ctrl[13].val[0] = 0;
1317 state->CH_Ctrl[13].addr[1] = 110;
1318 state->CH_Ctrl[13].bit[1] = 3;
1319 state->CH_Ctrl[13].val[1] = 0;
1320 state->CH_Ctrl[13].addr[2] = 110;
1321 state->CH_Ctrl[13].bit[2] = 4;
1322 state->CH_Ctrl[13].val[2] = 0;
1323 state->CH_Ctrl[13].addr[3] = 110;
1324 state->CH_Ctrl[13].bit[3] = 5;
1325 state->CH_Ctrl[13].val[3] = 0;
1326 state->CH_Ctrl[13].addr[4] = 110;
1327 state->CH_Ctrl[13].bit[4] = 6;
1328 state->CH_Ctrl[13].val[4] = 0;
1329 state->CH_Ctrl[13].addr[5] = 110;
1330 state->CH_Ctrl[13].bit[5] = 7;
1331 state->CH_Ctrl[13].val[5] = 1;
1332
1333 state->CH_Ctrl[14].Ctrl_Num = CHCAL_INT_MOD_RF ;
1334 state->CH_Ctrl[14].size = 7 ;
1335 state->CH_Ctrl[14].addr[0] = 14;
1336 state->CH_Ctrl[14].bit[0] = 0;
1337 state->CH_Ctrl[14].val[0] = 0;
1338 state->CH_Ctrl[14].addr[1] = 14;
1339 state->CH_Ctrl[14].bit[1] = 1;
1340 state->CH_Ctrl[14].val[1] = 0;
1341 state->CH_Ctrl[14].addr[2] = 14;
1342 state->CH_Ctrl[14].bit[2] = 2;
1343 state->CH_Ctrl[14].val[2] = 0;
1344 state->CH_Ctrl[14].addr[3] = 14;
1345 state->CH_Ctrl[14].bit[3] = 3;
1346 state->CH_Ctrl[14].val[3] = 0;
1347 state->CH_Ctrl[14].addr[4] = 14;
1348 state->CH_Ctrl[14].bit[4] = 4;
1349 state->CH_Ctrl[14].val[4] = 0;
1350 state->CH_Ctrl[14].addr[5] = 14;
1351 state->CH_Ctrl[14].bit[5] = 5;
1352 state->CH_Ctrl[14].val[5] = 0;
1353 state->CH_Ctrl[14].addr[6] = 14;
1354 state->CH_Ctrl[14].bit[6] = 6;
1355 state->CH_Ctrl[14].val[6] = 0;
1356
1357 state->CH_Ctrl[15].Ctrl_Num = CHCAL_FRAC_MOD_RF ;
1358 state->CH_Ctrl[15].size = 18 ;
1359 state->CH_Ctrl[15].addr[0] = 17;
1360 state->CH_Ctrl[15].bit[0] = 6;
1361 state->CH_Ctrl[15].val[0] = 0;
1362 state->CH_Ctrl[15].addr[1] = 17;
1363 state->CH_Ctrl[15].bit[1] = 7;
1364 state->CH_Ctrl[15].val[1] = 0;
1365 state->CH_Ctrl[15].addr[2] = 16;
1366 state->CH_Ctrl[15].bit[2] = 0;
1367 state->CH_Ctrl[15].val[2] = 0;
1368 state->CH_Ctrl[15].addr[3] = 16;
1369 state->CH_Ctrl[15].bit[3] = 1;
1370 state->CH_Ctrl[15].val[3] = 0;
1371 state->CH_Ctrl[15].addr[4] = 16;
1372 state->CH_Ctrl[15].bit[4] = 2;
1373 state->CH_Ctrl[15].val[4] = 0;
1374 state->CH_Ctrl[15].addr[5] = 16;
1375 state->CH_Ctrl[15].bit[5] = 3;
1376 state->CH_Ctrl[15].val[5] = 0;
1377 state->CH_Ctrl[15].addr[6] = 16;
1378 state->CH_Ctrl[15].bit[6] = 4;
1379 state->CH_Ctrl[15].val[6] = 0;
1380 state->CH_Ctrl[15].addr[7] = 16;
1381 state->CH_Ctrl[15].bit[7] = 5;
1382 state->CH_Ctrl[15].val[7] = 0;
1383 state->CH_Ctrl[15].addr[8] = 16;
1384 state->CH_Ctrl[15].bit[8] = 6;
1385 state->CH_Ctrl[15].val[8] = 0;
1386 state->CH_Ctrl[15].addr[9] = 16;
1387 state->CH_Ctrl[15].bit[9] = 7;
1388 state->CH_Ctrl[15].val[9] = 0;
1389 state->CH_Ctrl[15].addr[10] = 15;
1390 state->CH_Ctrl[15].bit[10] = 0;
1391 state->CH_Ctrl[15].val[10] = 0;
1392 state->CH_Ctrl[15].addr[11] = 15;
1393 state->CH_Ctrl[15].bit[11] = 1;
1394 state->CH_Ctrl[15].val[11] = 0;
1395 state->CH_Ctrl[15].addr[12] = 15;
1396 state->CH_Ctrl[15].bit[12] = 2;
1397 state->CH_Ctrl[15].val[12] = 0;
1398 state->CH_Ctrl[15].addr[13] = 15;
1399 state->CH_Ctrl[15].bit[13] = 3;
1400 state->CH_Ctrl[15].val[13] = 0;
1401 state->CH_Ctrl[15].addr[14] = 15;
1402 state->CH_Ctrl[15].bit[14] = 4;
1403 state->CH_Ctrl[15].val[14] = 0;
1404 state->CH_Ctrl[15].addr[15] = 15;
1405 state->CH_Ctrl[15].bit[15] = 5;
1406 state->CH_Ctrl[15].val[15] = 0;
1407 state->CH_Ctrl[15].addr[16] = 15;
1408 state->CH_Ctrl[15].bit[16] = 6;
1409 state->CH_Ctrl[15].val[16] = 1;
1410 state->CH_Ctrl[15].addr[17] = 15;
1411 state->CH_Ctrl[15].bit[17] = 7;
1412 state->CH_Ctrl[15].val[17] = 1;
1413
1414 state->CH_Ctrl[16].Ctrl_Num = RFSYN_LPF_R ;
1415 state->CH_Ctrl[16].size = 5 ;
1416 state->CH_Ctrl[16].addr[0] = 112;
1417 state->CH_Ctrl[16].bit[0] = 0;
1418 state->CH_Ctrl[16].val[0] = 0;
1419 state->CH_Ctrl[16].addr[1] = 112;
1420 state->CH_Ctrl[16].bit[1] = 1;
1421 state->CH_Ctrl[16].val[1] = 0;
1422 state->CH_Ctrl[16].addr[2] = 112;
1423 state->CH_Ctrl[16].bit[2] = 2;
1424 state->CH_Ctrl[16].val[2] = 0;
1425 state->CH_Ctrl[16].addr[3] = 112;
1426 state->CH_Ctrl[16].bit[3] = 3;
1427 state->CH_Ctrl[16].val[3] = 0;
1428 state->CH_Ctrl[16].addr[4] = 112;
1429 state->CH_Ctrl[16].bit[4] = 4;
1430 state->CH_Ctrl[16].val[4] = 1;
1431
1432 state->CH_Ctrl[17].Ctrl_Num = CHCAL_EN_INT_RF ;
1433 state->CH_Ctrl[17].size = 1 ;
1434 state->CH_Ctrl[17].addr[0] = 14;
1435 state->CH_Ctrl[17].bit[0] = 7;
1436 state->CH_Ctrl[17].val[0] = 0;
1437
1438 state->CH_Ctrl[18].Ctrl_Num = TG_LO_DIVVAL ;
1439 state->CH_Ctrl[18].size = 4 ;
1440 state->CH_Ctrl[18].addr[0] = 107;
1441 state->CH_Ctrl[18].bit[0] = 3;
1442 state->CH_Ctrl[18].val[0] = 0;
1443 state->CH_Ctrl[18].addr[1] = 107;
1444 state->CH_Ctrl[18].bit[1] = 4;
1445 state->CH_Ctrl[18].val[1] = 0;
1446 state->CH_Ctrl[18].addr[2] = 107;
1447 state->CH_Ctrl[18].bit[2] = 5;
1448 state->CH_Ctrl[18].val[2] = 0;
1449 state->CH_Ctrl[18].addr[3] = 107;
1450 state->CH_Ctrl[18].bit[3] = 6;
1451 state->CH_Ctrl[18].val[3] = 0;
1452
1453 state->CH_Ctrl[19].Ctrl_Num = TG_LO_SELVAL ;
1454 state->CH_Ctrl[19].size = 3 ;
1455 state->CH_Ctrl[19].addr[0] = 107;
1456 state->CH_Ctrl[19].bit[0] = 7;
1457 state->CH_Ctrl[19].val[0] = 1;
1458 state->CH_Ctrl[19].addr[1] = 106;
1459 state->CH_Ctrl[19].bit[1] = 0;
1460 state->CH_Ctrl[19].val[1] = 1;
1461 state->CH_Ctrl[19].addr[2] = 106;
1462 state->CH_Ctrl[19].bit[2] = 1;
1463 state->CH_Ctrl[19].val[2] = 1;
1464
1465 state->CH_Ctrl[20].Ctrl_Num = TG_DIV_VAL ;
1466 state->CH_Ctrl[20].size = 11 ;
1467 state->CH_Ctrl[20].addr[0] = 109;
1468 state->CH_Ctrl[20].bit[0] = 2;
1469 state->CH_Ctrl[20].val[0] = 0;
1470 state->CH_Ctrl[20].addr[1] = 109;
1471 state->CH_Ctrl[20].bit[1] = 3;
1472 state->CH_Ctrl[20].val[1] = 0;
1473 state->CH_Ctrl[20].addr[2] = 109;
1474 state->CH_Ctrl[20].bit[2] = 4;
1475 state->CH_Ctrl[20].val[2] = 0;
1476 state->CH_Ctrl[20].addr[3] = 109;
1477 state->CH_Ctrl[20].bit[3] = 5;
1478 state->CH_Ctrl[20].val[3] = 0;
1479 state->CH_Ctrl[20].addr[4] = 109;
1480 state->CH_Ctrl[20].bit[4] = 6;
1481 state->CH_Ctrl[20].val[4] = 0;
1482 state->CH_Ctrl[20].addr[5] = 109;
1483 state->CH_Ctrl[20].bit[5] = 7;
1484 state->CH_Ctrl[20].val[5] = 0;
1485 state->CH_Ctrl[20].addr[6] = 108;
1486 state->CH_Ctrl[20].bit[6] = 0;
1487 state->CH_Ctrl[20].val[6] = 0;
1488 state->CH_Ctrl[20].addr[7] = 108;
1489 state->CH_Ctrl[20].bit[7] = 1;
1490 state->CH_Ctrl[20].val[7] = 0;
1491 state->CH_Ctrl[20].addr[8] = 108;
1492 state->CH_Ctrl[20].bit[8] = 2;
1493 state->CH_Ctrl[20].val[8] = 1;
1494 state->CH_Ctrl[20].addr[9] = 108;
1495 state->CH_Ctrl[20].bit[9] = 3;
1496 state->CH_Ctrl[20].val[9] = 1;
1497 state->CH_Ctrl[20].addr[10] = 108;
1498 state->CH_Ctrl[20].bit[10] = 4;
1499 state->CH_Ctrl[20].val[10] = 1;
1500
1501 state->CH_Ctrl[21].Ctrl_Num = TG_VCO_BIAS ;
1502 state->CH_Ctrl[21].size = 6 ;
1503 state->CH_Ctrl[21].addr[0] = 106;
1504 state->CH_Ctrl[21].bit[0] = 2;
1505 state->CH_Ctrl[21].val[0] = 0;
1506 state->CH_Ctrl[21].addr[1] = 106;
1507 state->CH_Ctrl[21].bit[1] = 3;
1508 state->CH_Ctrl[21].val[1] = 0;
1509 state->CH_Ctrl[21].addr[2] = 106;
1510 state->CH_Ctrl[21].bit[2] = 4;
1511 state->CH_Ctrl[21].val[2] = 0;
1512 state->CH_Ctrl[21].addr[3] = 106;
1513 state->CH_Ctrl[21].bit[3] = 5;
1514 state->CH_Ctrl[21].val[3] = 0;
1515 state->CH_Ctrl[21].addr[4] = 106;
1516 state->CH_Ctrl[21].bit[4] = 6;
1517 state->CH_Ctrl[21].val[4] = 0;
1518 state->CH_Ctrl[21].addr[5] = 106;
1519 state->CH_Ctrl[21].bit[5] = 7;
1520 state->CH_Ctrl[21].val[5] = 1;
1521
1522 state->CH_Ctrl[22].Ctrl_Num = SEQ_EXTPOWERUP ;
1523 state->CH_Ctrl[22].size = 1 ;
1524 state->CH_Ctrl[22].addr[0] = 138;
1525 state->CH_Ctrl[22].bit[0] = 4;
1526 state->CH_Ctrl[22].val[0] = 1;
1527
1528 state->CH_Ctrl[23].Ctrl_Num = OVERRIDE_2 ;
1529 state->CH_Ctrl[23].size = 1 ;
1530 state->CH_Ctrl[23].addr[0] = 17;
1531 state->CH_Ctrl[23].bit[0] = 5;
1532 state->CH_Ctrl[23].val[0] = 0;
1533
1534 state->CH_Ctrl[24].Ctrl_Num = OVERRIDE_3 ;
1535 state->CH_Ctrl[24].size = 1 ;
1536 state->CH_Ctrl[24].addr[0] = 111;
1537 state->CH_Ctrl[24].bit[0] = 3;
1538 state->CH_Ctrl[24].val[0] = 0;
1539
1540 state->CH_Ctrl[25].Ctrl_Num = OVERRIDE_4 ;
1541 state->CH_Ctrl[25].size = 1 ;
1542 state->CH_Ctrl[25].addr[0] = 112;
1543 state->CH_Ctrl[25].bit[0] = 7;
1544 state->CH_Ctrl[25].val[0] = 0;
1545
1546 state->CH_Ctrl[26].Ctrl_Num = SEQ_FSM_PULSE ;
1547 state->CH_Ctrl[26].size = 1 ;
1548 state->CH_Ctrl[26].addr[0] = 136;
1549 state->CH_Ctrl[26].bit[0] = 7;
1550 state->CH_Ctrl[26].val[0] = 0;
1551
1552 state->CH_Ctrl[27].Ctrl_Num = GPIO_4B ;
1553 state->CH_Ctrl[27].size = 1 ;
1554 state->CH_Ctrl[27].addr[0] = 149;
1555 state->CH_Ctrl[27].bit[0] = 7;
1556 state->CH_Ctrl[27].val[0] = 0;
1557
1558 state->CH_Ctrl[28].Ctrl_Num = GPIO_3B ;
1559 state->CH_Ctrl[28].size = 1 ;
1560 state->CH_Ctrl[28].addr[0] = 149;
1561 state->CH_Ctrl[28].bit[0] = 6;
1562 state->CH_Ctrl[28].val[0] = 0;
1563
1564 state->CH_Ctrl[29].Ctrl_Num = GPIO_4 ;
1565 state->CH_Ctrl[29].size = 1 ;
1566 state->CH_Ctrl[29].addr[0] = 149;
1567 state->CH_Ctrl[29].bit[0] = 5;
1568 state->CH_Ctrl[29].val[0] = 1;
1569
1570 state->CH_Ctrl[30].Ctrl_Num = GPIO_3 ;
1571 state->CH_Ctrl[30].size = 1 ;
1572 state->CH_Ctrl[30].addr[0] = 149;
1573 state->CH_Ctrl[30].bit[0] = 4;
1574 state->CH_Ctrl[30].val[0] = 1;
1575
1576 state->CH_Ctrl[31].Ctrl_Num = GPIO_1B ;
1577 state->CH_Ctrl[31].size = 1 ;
1578 state->CH_Ctrl[31].addr[0] = 149;
1579 state->CH_Ctrl[31].bit[0] = 3;
1580 state->CH_Ctrl[31].val[0] = 0;
1581
1582 state->CH_Ctrl[32].Ctrl_Num = DAC_A_ENABLE ;
1583 state->CH_Ctrl[32].size = 1 ;
1584 state->CH_Ctrl[32].addr[0] = 93;
1585 state->CH_Ctrl[32].bit[0] = 1;
1586 state->CH_Ctrl[32].val[0] = 0;
1587
1588 state->CH_Ctrl[33].Ctrl_Num = DAC_B_ENABLE ;
1589 state->CH_Ctrl[33].size = 1 ;
1590 state->CH_Ctrl[33].addr[0] = 93;
1591 state->CH_Ctrl[33].bit[0] = 0;
1592 state->CH_Ctrl[33].val[0] = 0;
1593
1594 state->CH_Ctrl[34].Ctrl_Num = DAC_DIN_A ;
1595 state->CH_Ctrl[34].size = 6 ;
1596 state->CH_Ctrl[34].addr[0] = 92;
1597 state->CH_Ctrl[34].bit[0] = 2;
1598 state->CH_Ctrl[34].val[0] = 0;
1599 state->CH_Ctrl[34].addr[1] = 92;
1600 state->CH_Ctrl[34].bit[1] = 3;
1601 state->CH_Ctrl[34].val[1] = 0;
1602 state->CH_Ctrl[34].addr[2] = 92;
1603 state->CH_Ctrl[34].bit[2] = 4;
1604 state->CH_Ctrl[34].val[2] = 0;
1605 state->CH_Ctrl[34].addr[3] = 92;
1606 state->CH_Ctrl[34].bit[3] = 5;
1607 state->CH_Ctrl[34].val[3] = 0;
1608 state->CH_Ctrl[34].addr[4] = 92;
1609 state->CH_Ctrl[34].bit[4] = 6;
1610 state->CH_Ctrl[34].val[4] = 0;
1611 state->CH_Ctrl[34].addr[5] = 92;
1612 state->CH_Ctrl[34].bit[5] = 7;
1613 state->CH_Ctrl[34].val[5] = 0;
1614
1615 state->CH_Ctrl[35].Ctrl_Num = DAC_DIN_B ;
1616 state->CH_Ctrl[35].size = 6 ;
1617 state->CH_Ctrl[35].addr[0] = 93;
1618 state->CH_Ctrl[35].bit[0] = 2;
1619 state->CH_Ctrl[35].val[0] = 0;
1620 state->CH_Ctrl[35].addr[1] = 93;
1621 state->CH_Ctrl[35].bit[1] = 3;
1622 state->CH_Ctrl[35].val[1] = 0;
1623 state->CH_Ctrl[35].addr[2] = 93;
1624 state->CH_Ctrl[35].bit[2] = 4;
1625 state->CH_Ctrl[35].val[2] = 0;
1626 state->CH_Ctrl[35].addr[3] = 93;
1627 state->CH_Ctrl[35].bit[3] = 5;
1628 state->CH_Ctrl[35].val[3] = 0;
1629 state->CH_Ctrl[35].addr[4] = 93;
1630 state->CH_Ctrl[35].bit[4] = 6;
1631 state->CH_Ctrl[35].val[4] = 0;
1632 state->CH_Ctrl[35].addr[5] = 93;
1633 state->CH_Ctrl[35].bit[5] = 7;
1634 state->CH_Ctrl[35].val[5] = 0;
1635
1636#ifdef _MXL_PRODUCTION
1637 state->CH_Ctrl[36].Ctrl_Num = RFSYN_EN_DIV ;
1638 state->CH_Ctrl[36].size = 1 ;
1639 state->CH_Ctrl[36].addr[0] = 109;
1640 state->CH_Ctrl[36].bit[0] = 1;
1641 state->CH_Ctrl[36].val[0] = 1;
1642
1643 state->CH_Ctrl[37].Ctrl_Num = RFSYN_DIVM ;
1644 state->CH_Ctrl[37].size = 2 ;
1645 state->CH_Ctrl[37].addr[0] = 112;
1646 state->CH_Ctrl[37].bit[0] = 5;
1647 state->CH_Ctrl[37].val[0] = 0;
1648 state->CH_Ctrl[37].addr[1] = 112;
1649 state->CH_Ctrl[37].bit[1] = 6;
1650 state->CH_Ctrl[37].val[1] = 0;
1651
1652 state->CH_Ctrl[38].Ctrl_Num = DN_BYPASS_AGC_I2C ;
1653 state->CH_Ctrl[38].size = 1 ;
1654 state->CH_Ctrl[38].addr[0] = 65;
1655 state->CH_Ctrl[38].bit[0] = 1;
1656 state->CH_Ctrl[38].val[0] = 0;
1657#endif
1658
1659 return 0 ;
1660}
1661
1662static void InitTunerControls(struct dvb_frontend *fe)
1663{
1664 MXL5005_RegisterInit(fe);
1665 MXL5005_ControlInit(fe);
1666#ifdef _MXL_INTERNAL
1667 MXL5005_MXLControlInit(fe);
1668#endif
1669}
1670
1671static u16 MXL5005_TunerConfig(struct dvb_frontend *fe,
1672 u8 Mode, /* 0: Analog Mode ; 1: Digital Mode */
1673 u8 IF_mode, /* for Analog Mode, 0: zero IF; 1: low IF */
1674 u32 Bandwidth, /* filter channel bandwidth (6, 7, 8) */
1675 u32 IF_out, /* Desired IF Out Frequency */
1676 u32 Fxtal, /* XTAL Frequency */
1677 u8 AGC_Mode, /* AGC Mode - Dual AGC: 0, Single AGC: 1 */
1678 u16 TOP, /* 0: Dual AGC; Value: take over point */
1679 u16 IF_OUT_LOAD, /* IF Out Load Resistor (200 / 300 Ohms) */
1680 u8 CLOCK_OUT, /* 0: turn off clk out; 1: turn on clock out */
1681 u8 DIV_OUT, /* 0: Div-1; 1: Div-4 */
1682 u8 CAPSELECT, /* 0: disable On-Chip pulling cap; 1: enable */
1683 u8 EN_RSSI, /* 0: disable RSSI; 1: enable RSSI */
1684
1685 /* Modulation Type; */
1686 /* 0 - Default; 1 - DVB-T; 2 - ATSC; 3 - QAM; 4 - Analog Cable */
1687 u8 Mod_Type,
1688
1689 /* Tracking Filter */
1690 /* 0 - Default; 1 - Off; 2 - Type C; 3 - Type C-H */
1691 u8 TF_Type
1692 )
1693{
1694 struct mxl5005s_state *state = fe->tuner_priv;
1695 u16 status = 0;
1696
1697 state->Mode = Mode;
1698 state->IF_Mode = IF_mode;
1699 state->Chan_Bandwidth = Bandwidth;
1700 state->IF_OUT = IF_out;
1701 state->Fxtal = Fxtal;
1702 state->AGC_Mode = AGC_Mode;
1703 state->TOP = TOP;
1704 state->IF_OUT_LOAD = IF_OUT_LOAD;
1705 state->CLOCK_OUT = CLOCK_OUT;
1706 state->DIV_OUT = DIV_OUT;
1707 state->CAPSELECT = CAPSELECT;
1708 state->EN_RSSI = EN_RSSI;
1709 state->Mod_Type = Mod_Type;
1710 state->TF_Type = TF_Type;
1711
1712 /* Initialize all the controls and registers */
1713 InitTunerControls(fe);
1714
1715 /* Synthesizer LO frequency calculation */
1716 MXL_SynthIFLO_Calc(fe);
1717
1718 return status;
1719}
1720
1721static void MXL_SynthIFLO_Calc(struct dvb_frontend *fe)
1722{
1723 struct mxl5005s_state *state = fe->tuner_priv;
1724 if (state->Mode == 1) /* Digital Mode */
1725 state->IF_LO = state->IF_OUT;
1726 else /* Analog Mode */ {
1727 if (state->IF_Mode == 0) /* Analog Zero IF mode */
1728 state->IF_LO = state->IF_OUT + 400000;
1729 else /* Analog Low IF mode */
1730 state->IF_LO = state->IF_OUT + state->Chan_Bandwidth/2;
1731 }
1732}
1733
1734static void MXL_SynthRFTGLO_Calc(struct dvb_frontend *fe)
1735{
1736 struct mxl5005s_state *state = fe->tuner_priv;
1737
1738 if (state->Mode == 1) /* Digital Mode */ {
1739 /* remove 20.48MHz setting for 2.6.10 */
1740 state->RF_LO = state->RF_IN;
1741 /* change for 2.6.6 */
1742 state->TG_LO = state->RF_IN - 750000;
1743 } else /* Analog Mode */ {
1744 if (state->IF_Mode == 0) /* Analog Zero IF mode */ {
1745 state->RF_LO = state->RF_IN - 400000;
1746 state->TG_LO = state->RF_IN - 1750000;
1747 } else /* Analog Low IF mode */ {
1748 state->RF_LO = state->RF_IN - state->Chan_Bandwidth/2;
1749 state->TG_LO = state->RF_IN -
1750 state->Chan_Bandwidth + 500000;
1751 }
1752 }
1753}
1754
1755static u16 MXL_OverwriteICDefault(struct dvb_frontend *fe)
1756{
1757 u16 status = 0;
1758
1759 status += MXL_ControlWrite(fe, OVERRIDE_1, 1);
1760 status += MXL_ControlWrite(fe, OVERRIDE_2, 1);
1761 status += MXL_ControlWrite(fe, OVERRIDE_3, 1);
1762 status += MXL_ControlWrite(fe, OVERRIDE_4, 1);
1763
1764 return status;
1765}
1766
1767static u16 MXL_BlockInit(struct dvb_frontend *fe)
1768{
1769 struct mxl5005s_state *state = fe->tuner_priv;
1770 u16 status = 0;
1771
1772 status += MXL_OverwriteICDefault(fe);
1773
1774 /* Downconverter Control Dig Ana */
1775 status += MXL_ControlWrite(fe, DN_IQTN_AMP_CUT, state->Mode ? 1 : 0);
1776
1777 /* Filter Control Dig Ana */
1778 status += MXL_ControlWrite(fe, BB_MODE, state->Mode ? 0 : 1);
1779 status += MXL_ControlWrite(fe, BB_BUF, state->Mode ? 3 : 2);
1780 status += MXL_ControlWrite(fe, BB_BUF_OA, state->Mode ? 1 : 0);
1781 status += MXL_ControlWrite(fe, BB_IQSWAP, state->Mode ? 0 : 1);
1782 status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 0);
1783
1784 /* Initialize Low-Pass Filter */
1785 if (state->Mode) { /* Digital Mode */
1786 switch (state->Chan_Bandwidth) {
1787 case 8000000:
1788 status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 0);
1789 break;
1790 case 7000000:
1791 status += MXL_ControlWrite(fe, BB_DLPF_BANDSEL, 2);
1792 break;
1793 case 6000000:
1794 status += MXL_ControlWrite(fe,
1795 BB_DLPF_BANDSEL, 3);
1796 break;
1797 }
1798 } else { /* Analog Mode */
1799 switch (state->Chan_Bandwidth) {
1800 case 8000000: /* Low Zero */
1801 status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
1802 (state->IF_Mode ? 0 : 3));
1803 break;
1804 case 7000000:
1805 status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
1806 (state->IF_Mode ? 1 : 4));
1807 break;
1808 case 6000000:
1809 status += MXL_ControlWrite(fe, BB_ALPF_BANDSELECT,
1810 (state->IF_Mode ? 2 : 5));
1811 break;
1812 }
1813 }
1814
1815 /* Charge Pump Control Dig Ana */
1816 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, state->Mode ? 5 : 8);
1817 status += MXL_ControlWrite(fe,
1818 RFSYN_EN_CHP_HIGAIN, state->Mode ? 1 : 1);
1819 status += MXL_ControlWrite(fe, EN_CHP_LIN_B, state->Mode ? 0 : 0);
1820
1821 /* AGC TOP Control */
1822 if (state->AGC_Mode == 0) /* Dual AGC */ {
1823 status += MXL_ControlWrite(fe, AGC_IF, 15);
1824 status += MXL_ControlWrite(fe, AGC_RF, 15);
1825 } else /* Single AGC Mode Dig Ana */
1826 status += MXL_ControlWrite(fe, AGC_RF, state->Mode ? 15 : 12);
1827
1828 if (state->TOP == 55) /* TOP == 5.5 */
1829 status += MXL_ControlWrite(fe, AGC_IF, 0x0);
1830
1831 if (state->TOP == 72) /* TOP == 7.2 */
1832 status += MXL_ControlWrite(fe, AGC_IF, 0x1);
1833
1834 if (state->TOP == 92) /* TOP == 9.2 */
1835 status += MXL_ControlWrite(fe, AGC_IF, 0x2);
1836
1837 if (state->TOP == 110) /* TOP == 11.0 */
1838 status += MXL_ControlWrite(fe, AGC_IF, 0x3);
1839
1840 if (state->TOP == 129) /* TOP == 12.9 */
1841 status += MXL_ControlWrite(fe, AGC_IF, 0x4);
1842
1843 if (state->TOP == 147) /* TOP == 14.7 */
1844 status += MXL_ControlWrite(fe, AGC_IF, 0x5);
1845
1846 if (state->TOP == 168) /* TOP == 16.8 */
1847 status += MXL_ControlWrite(fe, AGC_IF, 0x6);
1848
1849 if (state->TOP == 194) /* TOP == 19.4 */
1850 status += MXL_ControlWrite(fe, AGC_IF, 0x7);
1851
1852 if (state->TOP == 212) /* TOP == 21.2 */
1853 status += MXL_ControlWrite(fe, AGC_IF, 0x9);
1854
1855 if (state->TOP == 232) /* TOP == 23.2 */
1856 status += MXL_ControlWrite(fe, AGC_IF, 0xA);
1857
1858 if (state->TOP == 252) /* TOP == 25.2 */
1859 status += MXL_ControlWrite(fe, AGC_IF, 0xB);
1860
1861 if (state->TOP == 271) /* TOP == 27.1 */
1862 status += MXL_ControlWrite(fe, AGC_IF, 0xC);
1863
1864 if (state->TOP == 292) /* TOP == 29.2 */
1865 status += MXL_ControlWrite(fe, AGC_IF, 0xD);
1866
1867 if (state->TOP == 317) /* TOP == 31.7 */
1868 status += MXL_ControlWrite(fe, AGC_IF, 0xE);
1869
1870 if (state->TOP == 349) /* TOP == 34.9 */
1871 status += MXL_ControlWrite(fe, AGC_IF, 0xF);
1872
1873 /* IF Synthesizer Control */
1874 status += MXL_IFSynthInit(fe);
1875
1876 /* IF UpConverter Control */
1877 if (state->IF_OUT_LOAD == 200) {
1878 status += MXL_ControlWrite(fe, DRV_RES_SEL, 6);
1879 status += MXL_ControlWrite(fe, I_DRIVER, 2);
1880 }
1881 if (state->IF_OUT_LOAD == 300) {
1882 status += MXL_ControlWrite(fe, DRV_RES_SEL, 4);
1883 status += MXL_ControlWrite(fe, I_DRIVER, 1);
1884 }
1885
1886 /* Anti-Alias Filtering Control
1887 * initialise Anti-Aliasing Filter
1888 */
1889 if (state->Mode) { /* Digital Mode */
1890 if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 6280000UL) {
1891 status += MXL_ControlWrite(fe, EN_AAF, 1);
1892 status += MXL_ControlWrite(fe, EN_3P, 1);
1893 status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
1894 status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
1895 }
1896 if ((state->IF_OUT == 36125000UL) ||
1897 (state->IF_OUT == 36150000UL)) {
1898 status += MXL_ControlWrite(fe, EN_AAF, 1);
1899 status += MXL_ControlWrite(fe, EN_3P, 1);
1900 status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
1901 status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1);
1902 }
1903 if (state->IF_OUT > 36150000UL) {
1904 status += MXL_ControlWrite(fe, EN_AAF, 0);
1905 status += MXL_ControlWrite(fe, EN_3P, 1);
1906 status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
1907 status += MXL_ControlWrite(fe, SEL_AAF_BAND, 1);
1908 }
1909 } else { /* Analog Mode */
1910 if (state->IF_OUT >= 4000000UL && state->IF_OUT <= 5000000UL) {
1911 status += MXL_ControlWrite(fe, EN_AAF, 1);
1912 status += MXL_ControlWrite(fe, EN_3P, 1);
1913 status += MXL_ControlWrite(fe, EN_AUX_3P, 1);
1914 status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
1915 }
1916 if (state->IF_OUT > 5000000UL) {
1917 status += MXL_ControlWrite(fe, EN_AAF, 0);
1918 status += MXL_ControlWrite(fe, EN_3P, 0);
1919 status += MXL_ControlWrite(fe, EN_AUX_3P, 0);
1920 status += MXL_ControlWrite(fe, SEL_AAF_BAND, 0);
1921 }
1922 }
1923
1924 /* Demod Clock Out */
1925 if (state->CLOCK_OUT)
1926 status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 1);
1927 else
1928 status += MXL_ControlWrite(fe, SEQ_ENCLK16_CLK_OUT, 0);
1929
1930 if (state->DIV_OUT == 1)
1931 status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 1);
1932 if (state->DIV_OUT == 0)
1933 status += MXL_ControlWrite(fe, SEQ_SEL4_16B, 0);
1934
1935 /* Crystal Control */
1936 if (state->CAPSELECT)
1937 status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 1);
1938 else
1939 status += MXL_ControlWrite(fe, XTAL_CAPSELECT, 0);
1940
1941 if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL)
1942 status += MXL_ControlWrite(fe, IF_SEL_DBL, 1);
1943 if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL)
1944 status += MXL_ControlWrite(fe, IF_SEL_DBL, 0);
1945
1946 if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL)
1947 status += MXL_ControlWrite(fe, RFSYN_R_DIV, 3);
1948 if (state->Fxtal > 22000000UL && state->Fxtal <= 32000000UL)
1949 status += MXL_ControlWrite(fe, RFSYN_R_DIV, 0);
1950
1951 /* Misc Controls */
1952 if (state->Mode == 0 && state->IF_Mode == 1) /* Analog LowIF mode */
1953 status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 0);
1954 else
1955 status += MXL_ControlWrite(fe, SEQ_EXTIQFSMPULSE, 1);
1956
1957 /* status += MXL_ControlRead(fe, IF_DIVVAL, &IF_DIVVAL_Val); */
1958
1959 /* Set TG_R_DIV */
1960 status += MXL_ControlWrite(fe, TG_R_DIV,
1961 MXL_Ceiling(state->Fxtal, 1000000));
1962
1963 /* Apply Default value to BB_INITSTATE_DLPF_TUNE */
1964
1965 /* RSSI Control */
1966 if (state->EN_RSSI) {
1967 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
1968 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
1969 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
1970 status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
1971
1972 /* RSSI reference point */
1973 status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2);
1974 status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 3);
1975 status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
1976
1977 /* TOP point */
1978 status += MXL_ControlWrite(fe, RFA_FLR, 0);
1979 status += MXL_ControlWrite(fe, RFA_CEIL, 12);
1980 }
1981
1982 /* Modulation type bit settings
1983 * Override the control values preset
1984 */
1985 if (state->Mod_Type == MXL_DVBT) /* DVB-T Mode */ {
1986 state->AGC_Mode = 1; /* Single AGC Mode */
1987
1988 /* Enable RSSI */
1989 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
1990 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
1991 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
1992 status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
1993
1994 /* RSSI reference point */
1995 status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
1996 status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
1997 status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
1998
1999 /* TOP point */
2000 status += MXL_ControlWrite(fe, RFA_FLR, 2);
2001 status += MXL_ControlWrite(fe, RFA_CEIL, 13);
2002 if (state->IF_OUT <= 6280000UL) /* Low IF */
2003 status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
2004 else /* High IF */
2005 status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
2006
2007 }
2008 if (state->Mod_Type == MXL_ATSC) /* ATSC Mode */ {
2009 state->AGC_Mode = 1; /* Single AGC Mode */
2010
2011 /* Enable RSSI */
2012 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
2013 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
2014 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
2015 status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
2016
2017 /* RSSI reference point */
2018 status += MXL_ControlWrite(fe, RFA_RSSI_REF, 2);
2019 status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 4);
2020 status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 1);
2021
2022 /* TOP point */
2023 status += MXL_ControlWrite(fe, RFA_FLR, 2);
2024 status += MXL_ControlWrite(fe, RFA_CEIL, 13);
2025 status += MXL_ControlWrite(fe, BB_INITSTATE_DLPF_TUNE, 1);
2026 /* Low Zero */
2027 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5);
2028
2029 if (state->IF_OUT <= 6280000UL) /* Low IF */
2030 status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
2031 else /* High IF */
2032 status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
2033 }
2034 if (state->Mod_Type == MXL_QAM) /* QAM Mode */ {
2035 state->Mode = MXL_DIGITAL_MODE;
2036
2037 /* state->AGC_Mode = 1; */ /* Single AGC Mode */
2038
2039 /* Disable RSSI */ /* change here for v2.6.5 */
2040 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
2041 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
2042 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
2043 status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
2044
2045 /* RSSI reference point */
2046 status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
2047 status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
2048 status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
2049 /* change here for v2.6.5 */
2050 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
2051
2052 if (state->IF_OUT <= 6280000UL) /* Low IF */
2053 status += MXL_ControlWrite(fe, BB_IQSWAP, 0);
2054 else /* High IF */
2055 status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
2056 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
2057
2058 }
2059 if (state->Mod_Type == MXL_ANALOG_CABLE) {
2060 /* Analog Cable Mode */
2061 /* state->Mode = MXL_DIGITAL_MODE; */
2062
2063 state->AGC_Mode = 1; /* Single AGC Mode */
2064
2065 /* Disable RSSI */
2066 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
2067 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
2068 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
2069 status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
2070 /* change for 2.6.3 */
2071 status += MXL_ControlWrite(fe, AGC_IF, 1);
2072 status += MXL_ControlWrite(fe, AGC_RF, 15);
2073 status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
2074 }
2075
2076 if (state->Mod_Type == MXL_ANALOG_OTA) {
2077 /* Analog OTA Terrestrial mode add for 2.6.7 */
2078 /* state->Mode = MXL_ANALOG_MODE; */
2079
2080 /* Enable RSSI */
2081 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
2082 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
2083 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
2084 status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
2085
2086 /* RSSI reference point */
2087 status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
2088 status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
2089 status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
2090 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
2091 status += MXL_ControlWrite(fe, BB_IQSWAP, 1);
2092 }
2093
2094 /* RSSI disable */
2095 if (state->EN_RSSI == 0) {
2096 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
2097 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
2098 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
2099 status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
2100 }
2101
2102 return status;
2103}
2104
2105static u16 MXL_IFSynthInit(struct dvb_frontend *fe)
2106{
2107 struct mxl5005s_state *state = fe->tuner_priv;
2108 u16 status = 0 ;
2109 u32 Fref = 0 ;
2110 u32 Kdbl, intModVal ;
2111 u32 fracModVal ;
2112 Kdbl = 2 ;
2113
2114 if (state->Fxtal >= 12000000UL && state->Fxtal <= 16000000UL)
2115 Kdbl = 2 ;
2116 if (state->Fxtal > 16000000UL && state->Fxtal <= 32000000UL)
2117 Kdbl = 1 ;
2118
2119 /* IF Synthesizer Control */
2120 if (state->Mode == 0 && state->IF_Mode == 1) /* Analog Low IF mode */ {
2121 if (state->IF_LO == 41000000UL) {
2122 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
2123 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
2124 Fref = 328000000UL ;
2125 }
2126 if (state->IF_LO == 47000000UL) {
2127 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
2128 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2129 Fref = 376000000UL ;
2130 }
2131 if (state->IF_LO == 54000000UL) {
2132 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10);
2133 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
2134 Fref = 324000000UL ;
2135 }
2136 if (state->IF_LO == 60000000UL) {
2137 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10);
2138 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2139 Fref = 360000000UL ;
2140 }
2141 if (state->IF_LO == 39250000UL) {
2142 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
2143 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
2144 Fref = 314000000UL ;
2145 }
2146 if (state->IF_LO == 39650000UL) {
2147 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
2148 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
2149 Fref = 317200000UL ;
2150 }
2151 if (state->IF_LO == 40150000UL) {
2152 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
2153 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
2154 Fref = 321200000UL ;
2155 }
2156 if (state->IF_LO == 40650000UL) {
2157 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
2158 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
2159 Fref = 325200000UL ;
2160 }
2161 }
2162
2163 if (state->Mode || (state->Mode == 0 && state->IF_Mode == 0)) {
2164 if (state->IF_LO == 57000000UL) {
2165 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10);
2166 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2167 Fref = 342000000UL ;
2168 }
2169 if (state->IF_LO == 44000000UL) {
2170 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
2171 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2172 Fref = 352000000UL ;
2173 }
2174 if (state->IF_LO == 43750000UL) {
2175 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
2176 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2177 Fref = 350000000UL ;
2178 }
2179 if (state->IF_LO == 36650000UL) {
2180 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
2181 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2182 Fref = 366500000UL ;
2183 }
2184 if (state->IF_LO == 36150000UL) {
2185 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
2186 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2187 Fref = 361500000UL ;
2188 }
2189 if (state->IF_LO == 36000000UL) {
2190 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
2191 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2192 Fref = 360000000UL ;
2193 }
2194 if (state->IF_LO == 35250000UL) {
2195 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
2196 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2197 Fref = 352500000UL ;
2198 }
2199 if (state->IF_LO == 34750000UL) {
2200 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
2201 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2202 Fref = 347500000UL ;
2203 }
2204 if (state->IF_LO == 6280000UL) {
2205 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07);
2206 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2207 Fref = 376800000UL ;
2208 }
2209 if (state->IF_LO == 5000000UL) {
2210 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x09);
2211 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2212 Fref = 360000000UL ;
2213 }
2214 if (state->IF_LO == 4500000UL) {
2215 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x06);
2216 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2217 Fref = 360000000UL ;
2218 }
2219 if (state->IF_LO == 4570000UL) {
2220 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x06);
2221 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2222 Fref = 365600000UL ;
2223 }
2224 if (state->IF_LO == 4000000UL) {
2225 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x05);
2226 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2227 Fref = 360000000UL ;
2228 }
2229 if (state->IF_LO == 57400000UL) {
2230 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x10);
2231 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2232 Fref = 344400000UL ;
2233 }
2234 if (state->IF_LO == 44400000UL) {
2235 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
2236 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2237 Fref = 355200000UL ;
2238 }
2239 if (state->IF_LO == 44150000UL) {
2240 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x08);
2241 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2242 Fref = 353200000UL ;
2243 }
2244 if (state->IF_LO == 37050000UL) {
2245 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
2246 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2247 Fref = 370500000UL ;
2248 }
2249 if (state->IF_LO == 36550000UL) {
2250 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
2251 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2252 Fref = 365500000UL ;
2253 }
2254 if (state->IF_LO == 36125000UL) {
2255 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x04);
2256 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2257 Fref = 361250000UL ;
2258 }
2259 if (state->IF_LO == 6000000UL) {
2260 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07);
2261 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2262 Fref = 360000000UL ;
2263 }
2264 if (state->IF_LO == 5400000UL) {
2265 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07);
2266 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
2267 Fref = 324000000UL ;
2268 }
2269 if (state->IF_LO == 5380000UL) {
2270 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x07);
2271 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x0C);
2272 Fref = 322800000UL ;
2273 }
2274 if (state->IF_LO == 5200000UL) {
2275 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x09);
2276 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2277 Fref = 374400000UL ;
2278 }
2279 if (state->IF_LO == 4900000UL) {
2280 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x09);
2281 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2282 Fref = 352800000UL ;
2283 }
2284 if (state->IF_LO == 4400000UL) {
2285 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x06);
2286 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2287 Fref = 352000000UL ;
2288 }
2289 if (state->IF_LO == 4063000UL) /* add for 2.6.8 */ {
2290 status += MXL_ControlWrite(fe, IF_DIVVAL, 0x05);
2291 status += MXL_ControlWrite(fe, IF_VCO_BIAS, 0x08);
2292 Fref = 365670000UL ;
2293 }
2294 }
2295 /* CHCAL_INT_MOD_IF */
2296 /* CHCAL_FRAC_MOD_IF */
2297 intModVal = Fref / (state->Fxtal * Kdbl/2);
2298 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_IF, intModVal);
2299
2300 fracModVal = (2<<15)*(Fref/1000 - (state->Fxtal/1000 * Kdbl/2) *
2301 intModVal);
2302
2303 fracModVal = fracModVal / ((state->Fxtal * Kdbl/2)/1000);
2304 status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_IF, fracModVal);
2305
2306 return status ;
2307}
2308
2309static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
2310{
2311 struct mxl5005s_state *state = fe->tuner_priv;
2312 u16 status = 0;
2313 u32 divider_val, E3, E4, E5, E5A;
2314 u32 Fmax, Fmin, FmaxBin, FminBin;
2315 u32 Kdbl_RF = 2;
2316 u32 tg_divval;
2317 u32 tg_lo;
2318
2319 u32 Fref_TG;
2320 u32 Fvco;
2321
2322 state->RF_IN = RF_Freq;
2323
2324 MXL_SynthRFTGLO_Calc(fe);
2325
2326 if (state->Fxtal >= 12000000UL && state->Fxtal <= 22000000UL)
2327 Kdbl_RF = 2;
2328 if (state->Fxtal > 22000000 && state->Fxtal <= 32000000)
2329 Kdbl_RF = 1;
2330
2331 /* Downconverter Controls
2332 * Look-Up Table Implementation for:
2333 * DN_POLY
2334 * DN_RFGAIN
2335 * DN_CAP_RFLPF
2336 * DN_EN_VHFUHFBAR
2337 * DN_GAIN_ADJUST
2338 * Change the boundary reference from RF_IN to RF_LO
2339 */
2340 if (state->RF_LO < 40000000UL)
2341 return -1;
2342
2343 if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) {
2344 status += MXL_ControlWrite(fe, DN_POLY, 2);
2345 status += MXL_ControlWrite(fe, DN_RFGAIN, 3);
2346 status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 423);
2347 status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1);
2348 status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 1);
2349 }
2350 if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) {
2351 status += MXL_ControlWrite(fe, DN_POLY, 3);
2352 status += MXL_ControlWrite(fe, DN_RFGAIN, 3);
2353 status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 222);
2354 status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1);
2355 status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 1);
2356 }
2357 if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) {
2358 status += MXL_ControlWrite(fe, DN_POLY, 3);
2359 status += MXL_ControlWrite(fe, DN_RFGAIN, 3);
2360 status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 147);
2361 status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1);
2362 status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 2);
2363 }
2364 if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) {
2365 status += MXL_ControlWrite(fe, DN_POLY, 3);
2366 status += MXL_ControlWrite(fe, DN_RFGAIN, 3);
2367 status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 9);
2368 status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1);
2369 status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 2);
2370 }
2371 if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) {
2372 status += MXL_ControlWrite(fe, DN_POLY, 3);
2373 status += MXL_ControlWrite(fe, DN_RFGAIN, 3);
2374 status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 0);
2375 status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 1);
2376 status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 3);
2377 }
2378 if (state->RF_LO > 300000000UL && state->RF_LO <= 650000000UL) {
2379 status += MXL_ControlWrite(fe, DN_POLY, 3);
2380 status += MXL_ControlWrite(fe, DN_RFGAIN, 1);
2381 status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 0);
2382 status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 0);
2383 status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 3);
2384 }
2385 if (state->RF_LO > 650000000UL && state->RF_LO <= 900000000UL) {
2386 status += MXL_ControlWrite(fe, DN_POLY, 3);
2387 status += MXL_ControlWrite(fe, DN_RFGAIN, 2);
2388 status += MXL_ControlWrite(fe, DN_CAP_RFLPF, 0);
2389 status += MXL_ControlWrite(fe, DN_EN_VHFUHFBAR, 0);
2390 status += MXL_ControlWrite(fe, DN_GAIN_ADJUST, 3);
2391 }
2392 if (state->RF_LO > 900000000UL)
2393 return -1;
2394
2395 /* DN_IQTNBUF_AMP */
2396 /* DN_IQTNGNBFBIAS_BST */
2397 if (state->RF_LO >= 40000000UL && state->RF_LO <= 75000000UL) {
2398 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2399 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2400 }
2401 if (state->RF_LO > 75000000UL && state->RF_LO <= 100000000UL) {
2402 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2403 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2404 }
2405 if (state->RF_LO > 100000000UL && state->RF_LO <= 150000000UL) {
2406 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2407 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2408 }
2409 if (state->RF_LO > 150000000UL && state->RF_LO <= 200000000UL) {
2410 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2411 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2412 }
2413 if (state->RF_LO > 200000000UL && state->RF_LO <= 300000000UL) {
2414 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2415 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2416 }
2417 if (state->RF_LO > 300000000UL && state->RF_LO <= 400000000UL) {
2418 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2419 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2420 }
2421 if (state->RF_LO > 400000000UL && state->RF_LO <= 450000000UL) {
2422 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2423 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2424 }
2425 if (state->RF_LO > 450000000UL && state->RF_LO <= 500000000UL) {
2426 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2427 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2428 }
2429 if (state->RF_LO > 500000000UL && state->RF_LO <= 550000000UL) {
2430 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2431 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2432 }
2433 if (state->RF_LO > 550000000UL && state->RF_LO <= 600000000UL) {
2434 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2435 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2436 }
2437 if (state->RF_LO > 600000000UL && state->RF_LO <= 650000000UL) {
2438 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2439 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2440 }
2441 if (state->RF_LO > 650000000UL && state->RF_LO <= 700000000UL) {
2442 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2443 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2444 }
2445 if (state->RF_LO > 700000000UL && state->RF_LO <= 750000000UL) {
2446 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2447 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2448 }
2449 if (state->RF_LO > 750000000UL && state->RF_LO <= 800000000UL) {
2450 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 1);
2451 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 0);
2452 }
2453 if (state->RF_LO > 800000000UL && state->RF_LO <= 850000000UL) {
2454 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 10);
2455 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 1);
2456 }
2457 if (state->RF_LO > 850000000UL && state->RF_LO <= 900000000UL) {
2458 status += MXL_ControlWrite(fe, DN_IQTNBUF_AMP, 10);
2459 status += MXL_ControlWrite(fe, DN_IQTNGNBFBIAS_BST, 1);
2460 }
2461
2462 /*
2463 * Set RF Synth and LO Path Control
2464 *
2465 * Look-Up table implementation for:
2466 * RFSYN_EN_OUTMUX
2467 * RFSYN_SEL_VCO_OUT
2468 * RFSYN_SEL_VCO_HI
2469 * RFSYN_SEL_DIVM
2470 * RFSYN_RF_DIV_BIAS
2471 * DN_SEL_FREQ
2472 *
2473 * Set divider_val, Fmax, Fmix to use in Equations
2474 */
2475 FminBin = 28000000UL ;
2476 FmaxBin = 42500000UL ;
2477 if (state->RF_LO >= 40000000UL && state->RF_LO <= FmaxBin) {
2478 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1);
2479 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0);
2480 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
2481 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
2482 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
2483 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1);
2484 divider_val = 64 ;
2485 Fmax = FmaxBin ;
2486 Fmin = FminBin ;
2487 }
2488 FminBin = 42500000UL ;
2489 FmaxBin = 56000000UL ;
2490 if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
2491 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1);
2492 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0);
2493 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
2494 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
2495 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
2496 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1);
2497 divider_val = 64 ;
2498 Fmax = FmaxBin ;
2499 Fmin = FminBin ;
2500 }
2501 FminBin = 56000000UL ;
2502 FmaxBin = 85000000UL ;
2503 if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
2504 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
2505 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
2506 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
2507 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
2508 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
2509 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1);
2510 divider_val = 32 ;
2511 Fmax = FmaxBin ;
2512 Fmin = FminBin ;
2513 }
2514 FminBin = 85000000UL ;
2515 FmaxBin = 112000000UL ;
2516 if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
2517 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
2518 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
2519 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
2520 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
2521 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
2522 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 1);
2523 divider_val = 32 ;
2524 Fmax = FmaxBin ;
2525 Fmin = FminBin ;
2526 }
2527 FminBin = 112000000UL ;
2528 FmaxBin = 170000000UL ;
2529 if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
2530 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
2531 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
2532 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
2533 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
2534 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
2535 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 2);
2536 divider_val = 16 ;
2537 Fmax = FmaxBin ;
2538 Fmin = FminBin ;
2539 }
2540 FminBin = 170000000UL ;
2541 FmaxBin = 225000000UL ;
2542 if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
2543 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
2544 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
2545 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
2546 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
2547 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
2548 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 2);
2549 divider_val = 16 ;
2550 Fmax = FmaxBin ;
2551 Fmin = FminBin ;
2552 }
2553 FminBin = 225000000UL ;
2554 FmaxBin = 300000000UL ;
2555 if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
2556 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
2557 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
2558 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
2559 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
2560 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
2561 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 4);
2562 divider_val = 8 ;
2563 Fmax = 340000000UL ;
2564 Fmin = FminBin ;
2565 }
2566 FminBin = 300000000UL ;
2567 FmaxBin = 340000000UL ;
2568 if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
2569 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1);
2570 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0);
2571 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
2572 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
2573 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
2574 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
2575 divider_val = 8 ;
2576 Fmax = FmaxBin ;
2577 Fmin = 225000000UL ;
2578 }
2579 FminBin = 340000000UL ;
2580 FmaxBin = 450000000UL ;
2581 if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
2582 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 1);
2583 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 0);
2584 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
2585 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
2586 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 2);
2587 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
2588 divider_val = 8 ;
2589 Fmax = FmaxBin ;
2590 Fmin = FminBin ;
2591 }
2592 FminBin = 450000000UL ;
2593 FmaxBin = 680000000UL ;
2594 if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
2595 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
2596 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
2597 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
2598 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 1);
2599 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
2600 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
2601 divider_val = 4 ;
2602 Fmax = FmaxBin ;
2603 Fmin = FminBin ;
2604 }
2605 FminBin = 680000000UL ;
2606 FmaxBin = 900000000UL ;
2607 if (state->RF_LO > FminBin && state->RF_LO <= FmaxBin) {
2608 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
2609 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
2610 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
2611 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 1);
2612 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
2613 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
2614 divider_val = 4 ;
2615 Fmax = FmaxBin ;
2616 Fmin = FminBin ;
2617 }
2618
2619 /* CHCAL_INT_MOD_RF
2620 * CHCAL_FRAC_MOD_RF
2621 * RFSYN_LPF_R
2622 * CHCAL_EN_INT_RF
2623 */
2624 /* Equation E3 RFSYN_VCO_BIAS */
2625 E3 = (((Fmax-state->RF_LO)/1000)*32)/((Fmax-Fmin)/1000) + 8 ;
2626 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, E3);
2627
2628 /* Equation E4 CHCAL_INT_MOD_RF */
2629 E4 = (state->RF_LO*divider_val/1000)/(2*state->Fxtal*Kdbl_RF/1000);
2630 MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, E4);
2631
2632 /* Equation E5 CHCAL_FRAC_MOD_RF CHCAL_EN_INT_RF */
2633 E5 = ((2<<17)*(state->RF_LO/10000*divider_val -
2634 (E4*(2*state->Fxtal*Kdbl_RF)/10000))) /
2635 (2*state->Fxtal*Kdbl_RF/10000);
2636
2637 status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5);
2638
2639 /* Equation E5A RFSYN_LPF_R */
2640 E5A = (((Fmax - state->RF_LO)/1000)*4/((Fmax-Fmin)/1000)) + 1 ;
2641 status += MXL_ControlWrite(fe, RFSYN_LPF_R, E5A);
2642
2643 /* Euqation E5B CHCAL_EN_INIT_RF */
2644 status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, ((E5 == 0) ? 1 : 0));
2645 /*if (E5 == 0)
2646 * status += MXL_ControlWrite(fe, CHCAL_EN_INT_RF, 1);
2647 *else
2648 * status += MXL_ControlWrite(fe, CHCAL_FRAC_MOD_RF, E5);
2649 */
2650
2651 /*
2652 * Set TG Synth
2653 *
2654 * Look-Up table implementation for:
2655 * TG_LO_DIVVAL
2656 * TG_LO_SELVAL
2657 *
2658 * Set divider_val, Fmax, Fmix to use in Equations
2659 */
2660 if (state->TG_LO < 33000000UL)
2661 return -1;
2662
2663 FminBin = 33000000UL ;
2664 FmaxBin = 50000000UL ;
2665 if (state->TG_LO >= FminBin && state->TG_LO <= FmaxBin) {
2666 status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x6);
2667 status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x0);
2668 divider_val = 36 ;
2669 Fmax = FmaxBin ;
2670 Fmin = FminBin ;
2671 }
2672 FminBin = 50000000UL ;
2673 FmaxBin = 67000000UL ;
2674 if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
2675 status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x1);
2676 status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x0);
2677 divider_val = 24 ;
2678 Fmax = FmaxBin ;
2679 Fmin = FminBin ;
2680 }
2681 FminBin = 67000000UL ;
2682 FmaxBin = 100000000UL ;
2683 if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
2684 status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0xC);
2685 status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x2);
2686 divider_val = 18 ;
2687 Fmax = FmaxBin ;
2688 Fmin = FminBin ;
2689 }
2690 FminBin = 100000000UL ;
2691 FmaxBin = 150000000UL ;
2692 if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
2693 status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x8);
2694 status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x2);
2695 divider_val = 12 ;
2696 Fmax = FmaxBin ;
2697 Fmin = FminBin ;
2698 }
2699 FminBin = 150000000UL ;
2700 FmaxBin = 200000000UL ;
2701 if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
2702 status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x0);
2703 status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x2);
2704 divider_val = 8 ;
2705 Fmax = FmaxBin ;
2706 Fmin = FminBin ;
2707 }
2708 FminBin = 200000000UL ;
2709 FmaxBin = 300000000UL ;
2710 if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
2711 status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x8);
2712 status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x3);
2713 divider_val = 6 ;
2714 Fmax = FmaxBin ;
2715 Fmin = FminBin ;
2716 }
2717 FminBin = 300000000UL ;
2718 FmaxBin = 400000000UL ;
2719 if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
2720 status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x0);
2721 status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x3);
2722 divider_val = 4 ;
2723 Fmax = FmaxBin ;
2724 Fmin = FminBin ;
2725 }
2726 FminBin = 400000000UL ;
2727 FmaxBin = 600000000UL ;
2728 if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
2729 status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x8);
2730 status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x7);
2731 divider_val = 3 ;
2732 Fmax = FmaxBin ;
2733 Fmin = FminBin ;
2734 }
2735 FminBin = 600000000UL ;
2736 FmaxBin = 900000000UL ;
2737 if (state->TG_LO > FminBin && state->TG_LO <= FmaxBin) {
2738 status += MXL_ControlWrite(fe, TG_LO_DIVVAL, 0x0);
2739 status += MXL_ControlWrite(fe, TG_LO_SELVAL, 0x7);
2740 divider_val = 2 ;
2741 Fmax = FmaxBin ;
2742 Fmin = FminBin ;
2743 }
2744
2745 /* TG_DIV_VAL */
2746 tg_divval = (state->TG_LO*divider_val/100000) *
2747 (MXL_Ceiling(state->Fxtal, 1000000) * 100) /
2748 (state->Fxtal/1000);
2749
2750 status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval);
2751
2752 if (state->TG_LO > 600000000UL)
2753 status += MXL_ControlWrite(fe, TG_DIV_VAL, tg_divval + 1);
2754
2755 Fmax = 1800000000UL ;
2756 Fmin = 1200000000UL ;
2757
2758 /* prevent overflow of 32 bit unsigned integer, use
2759 * following equation. Edit for v2.6.4
2760 */
2761 /* Fref_TF = Fref_TG * 1000 */
2762 Fref_TG = (state->Fxtal/1000) / MXL_Ceiling(state->Fxtal, 1000000);
2763
2764 /* Fvco = Fvco/10 */
2765 Fvco = (state->TG_LO/10000) * divider_val * Fref_TG;
2766
2767 tg_lo = (((Fmax/10 - Fvco)/100)*32) / ((Fmax-Fmin)/1000)+8;
2768
2769 /* below equation is same as above but much harder to debug.
2770 *
2771 * static u32 MXL_GetXtalInt(u32 Xtal_Freq)
2772 * {
2773 * if ((Xtal_Freq % 1000000) == 0)
2774 * return (Xtal_Freq / 10000);
2775 * else
2776 * return (((Xtal_Freq / 1000000) + 1)*100);
2777 * }
2778 *
2779 * u32 Xtal_Int = MXL_GetXtalInt(state->Fxtal);
2780 * tg_lo = ( ((Fmax/10000 * Xtal_Int)/100) -
2781 * ((state->TG_LO/10000)*divider_val *
2782 * (state->Fxtal/10000)/100) )*32/((Fmax-Fmin)/10000 *
2783 * Xtal_Int/100) + 8;
2784 */
2785
2786 status += MXL_ControlWrite(fe, TG_VCO_BIAS , tg_lo);
2787
2788 /* add for 2.6.5 Special setting for QAM */
2789 if (state->Mod_Type == MXL_QAM) {
2790 if (state->config->qam_gain != 0)
2791 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN,
2792 state->config->qam_gain);
2793 else if (state->RF_IN < 680000000)
2794 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
2795 else
2796 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
2797 }
2798
2799 /* Off Chip Tracking Filter Control */
2800 if (state->TF_Type == MXL_TF_OFF) {
2801 /* Tracking Filter Off State; turn off all the banks */
2802 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
2803 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
2804 status += MXL_SetGPIO(fe, 3, 1); /* Bank1 Off */
2805 status += MXL_SetGPIO(fe, 1, 1); /* Bank2 Off */
2806 status += MXL_SetGPIO(fe, 4, 1); /* Bank3 Off */
2807 }
2808
2809 if (state->TF_Type == MXL_TF_C) /* Tracking Filter type C */ {
2810 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
2811 status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
2812
2813 if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) {
2814 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
2815 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
2816 status += MXL_SetGPIO(fe, 3, 0);
2817 status += MXL_SetGPIO(fe, 1, 1);
2818 status += MXL_SetGPIO(fe, 4, 1);
2819 }
2820 if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) {
2821 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
2822 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
2823 status += MXL_SetGPIO(fe, 3, 1);
2824 status += MXL_SetGPIO(fe, 1, 0);
2825 status += MXL_SetGPIO(fe, 4, 1);
2826 }
2827 if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) {
2828 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
2829 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
2830 status += MXL_SetGPIO(fe, 3, 1);
2831 status += MXL_SetGPIO(fe, 1, 0);
2832 status += MXL_SetGPIO(fe, 4, 0);
2833 }
2834 if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) {
2835 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
2836 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
2837 status += MXL_SetGPIO(fe, 3, 1);
2838 status += MXL_SetGPIO(fe, 1, 1);
2839 status += MXL_SetGPIO(fe, 4, 0);
2840 }
2841 if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) {
2842 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
2843 status += MXL_ControlWrite(fe, DAC_DIN_B, 29);
2844 status += MXL_SetGPIO(fe, 3, 1);
2845 status += MXL_SetGPIO(fe, 1, 1);
2846 status += MXL_SetGPIO(fe, 4, 0);
2847 }
2848 if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) {
2849 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
2850 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
2851 status += MXL_SetGPIO(fe, 3, 1);
2852 status += MXL_SetGPIO(fe, 1, 1);
2853 status += MXL_SetGPIO(fe, 4, 0);
2854 }
2855 if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) {
2856 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
2857 status += MXL_ControlWrite(fe, DAC_DIN_B, 16);
2858 status += MXL_SetGPIO(fe, 3, 1);
2859 status += MXL_SetGPIO(fe, 1, 1);
2860 status += MXL_SetGPIO(fe, 4, 1);
2861 }
2862 if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) {
2863 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
2864 status += MXL_ControlWrite(fe, DAC_DIN_B, 7);
2865 status += MXL_SetGPIO(fe, 3, 1);
2866 status += MXL_SetGPIO(fe, 1, 1);
2867 status += MXL_SetGPIO(fe, 4, 1);
2868 }
2869 if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) {
2870 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
2871 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
2872 status += MXL_SetGPIO(fe, 3, 1);
2873 status += MXL_SetGPIO(fe, 1, 1);
2874 status += MXL_SetGPIO(fe, 4, 1);
2875 }
2876 }
2877
2878 if (state->TF_Type == MXL_TF_C_H) {
2879
2880 /* Tracking Filter type C-H for Hauppauge only */
2881 status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
2882
2883 if (state->RF_IN >= 43000000 && state->RF_IN < 150000000) {
2884 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
2885 status += MXL_SetGPIO(fe, 4, 0);
2886 status += MXL_SetGPIO(fe, 3, 1);
2887 status += MXL_SetGPIO(fe, 1, 1);
2888 }
2889 if (state->RF_IN >= 150000000 && state->RF_IN < 280000000) {
2890 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
2891 status += MXL_SetGPIO(fe, 4, 1);
2892 status += MXL_SetGPIO(fe, 3, 0);
2893 status += MXL_SetGPIO(fe, 1, 1);
2894 }
2895 if (state->RF_IN >= 280000000 && state->RF_IN < 360000000) {
2896 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
2897 status += MXL_SetGPIO(fe, 4, 1);
2898 status += MXL_SetGPIO(fe, 3, 0);
2899 status += MXL_SetGPIO(fe, 1, 0);
2900 }
2901 if (state->RF_IN >= 360000000 && state->RF_IN < 560000000) {
2902 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
2903 status += MXL_SetGPIO(fe, 4, 1);
2904 status += MXL_SetGPIO(fe, 3, 1);
2905 status += MXL_SetGPIO(fe, 1, 0);
2906 }
2907 if (state->RF_IN >= 560000000 && state->RF_IN < 580000000) {
2908 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
2909 status += MXL_SetGPIO(fe, 4, 1);
2910 status += MXL_SetGPIO(fe, 3, 1);
2911 status += MXL_SetGPIO(fe, 1, 0);
2912 }
2913 if (state->RF_IN >= 580000000 && state->RF_IN < 630000000) {
2914 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
2915 status += MXL_SetGPIO(fe, 4, 1);
2916 status += MXL_SetGPIO(fe, 3, 1);
2917 status += MXL_SetGPIO(fe, 1, 0);
2918 }
2919 if (state->RF_IN >= 630000000 && state->RF_IN < 700000000) {
2920 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
2921 status += MXL_SetGPIO(fe, 4, 1);
2922 status += MXL_SetGPIO(fe, 3, 1);
2923 status += MXL_SetGPIO(fe, 1, 1);
2924 }
2925 if (state->RF_IN >= 700000000 && state->RF_IN < 760000000) {
2926 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
2927 status += MXL_SetGPIO(fe, 4, 1);
2928 status += MXL_SetGPIO(fe, 3, 1);
2929 status += MXL_SetGPIO(fe, 1, 1);
2930 }
2931 if (state->RF_IN >= 760000000 && state->RF_IN <= 900000000) {
2932 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
2933 status += MXL_SetGPIO(fe, 4, 1);
2934 status += MXL_SetGPIO(fe, 3, 1);
2935 status += MXL_SetGPIO(fe, 1, 1);
2936 }
2937 }
2938
2939 if (state->TF_Type == MXL_TF_D) { /* Tracking Filter type D */
2940
2941 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
2942
2943 if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
2944 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
2945 status += MXL_SetGPIO(fe, 4, 0);
2946 status += MXL_SetGPIO(fe, 1, 1);
2947 status += MXL_SetGPIO(fe, 3, 1);
2948 }
2949 if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
2950 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
2951 status += MXL_SetGPIO(fe, 4, 0);
2952 status += MXL_SetGPIO(fe, 1, 0);
2953 status += MXL_SetGPIO(fe, 3, 1);
2954 }
2955 if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) {
2956 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
2957 status += MXL_SetGPIO(fe, 4, 1);
2958 status += MXL_SetGPIO(fe, 1, 0);
2959 status += MXL_SetGPIO(fe, 3, 1);
2960 }
2961 if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) {
2962 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
2963 status += MXL_SetGPIO(fe, 4, 1);
2964 status += MXL_SetGPIO(fe, 1, 0);
2965 status += MXL_SetGPIO(fe, 3, 0);
2966 }
2967 if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) {
2968 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
2969 status += MXL_SetGPIO(fe, 4, 1);
2970 status += MXL_SetGPIO(fe, 1, 1);
2971 status += MXL_SetGPIO(fe, 3, 0);
2972 }
2973 if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
2974 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
2975 status += MXL_SetGPIO(fe, 4, 1);
2976 status += MXL_SetGPIO(fe, 1, 1);
2977 status += MXL_SetGPIO(fe, 3, 0);
2978 }
2979 if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) {
2980 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
2981 status += MXL_SetGPIO(fe, 4, 1);
2982 status += MXL_SetGPIO(fe, 1, 1);
2983 status += MXL_SetGPIO(fe, 3, 1);
2984 }
2985 }
2986
2987 if (state->TF_Type == MXL_TF_D_L) {
2988
2989 /* Tracking Filter type D-L for Lumanate ONLY change 2.6.3 */
2990 status += MXL_ControlWrite(fe, DAC_DIN_A, 0);
2991
2992 /* if UHF and terrestrial => Turn off Tracking Filter */
2993 if (state->RF_IN >= 471000000 &&
2994 (state->RF_IN - 471000000)%6000000 != 0) {
2995 /* Turn off all the banks */
2996 status += MXL_SetGPIO(fe, 3, 1);
2997 status += MXL_SetGPIO(fe, 1, 1);
2998 status += MXL_SetGPIO(fe, 4, 1);
2999 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
3000 status += MXL_ControlWrite(fe, AGC_IF, 10);
3001 } else {
3002 /* if VHF or cable => Turn on Tracking Filter */
3003 if (state->RF_IN >= 43000000 &&
3004 state->RF_IN < 140000000) {
3005
3006 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
3007 status += MXL_SetGPIO(fe, 4, 1);
3008 status += MXL_SetGPIO(fe, 1, 1);
3009 status += MXL_SetGPIO(fe, 3, 0);
3010 }
3011 if (state->RF_IN >= 140000000 &&
3012 state->RF_IN < 240000000) {
3013 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
3014 status += MXL_SetGPIO(fe, 4, 1);
3015 status += MXL_SetGPIO(fe, 1, 0);
3016 status += MXL_SetGPIO(fe, 3, 0);
3017 }
3018 if (state->RF_IN >= 240000000 &&
3019 state->RF_IN < 340000000) {
3020 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
3021 status += MXL_SetGPIO(fe, 4, 0);
3022 status += MXL_SetGPIO(fe, 1, 1);
3023 status += MXL_SetGPIO(fe, 3, 0);
3024 }
3025 if (state->RF_IN >= 340000000 &&
3026 state->RF_IN < 430000000) {
3027 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
3028 status += MXL_SetGPIO(fe, 4, 0);
3029 status += MXL_SetGPIO(fe, 1, 0);
3030 status += MXL_SetGPIO(fe, 3, 1);
3031 }
3032 if (state->RF_IN >= 430000000 &&
3033 state->RF_IN < 470000000) {
3034 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
3035 status += MXL_SetGPIO(fe, 4, 1);
3036 status += MXL_SetGPIO(fe, 1, 0);
3037 status += MXL_SetGPIO(fe, 3, 1);
3038 }
3039 if (state->RF_IN >= 470000000 &&
3040 state->RF_IN < 570000000) {
3041 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
3042 status += MXL_SetGPIO(fe, 4, 0);
3043 status += MXL_SetGPIO(fe, 1, 0);
3044 status += MXL_SetGPIO(fe, 3, 1);
3045 }
3046 if (state->RF_IN >= 570000000 &&
3047 state->RF_IN < 620000000) {
3048 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 0);
3049 status += MXL_SetGPIO(fe, 4, 0);
3050 status += MXL_SetGPIO(fe, 1, 1);
3051 status += MXL_SetGPIO(fe, 3, 1);
3052 }
3053 if (state->RF_IN >= 620000000 &&
3054 state->RF_IN < 760000000) {
3055 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
3056 status += MXL_SetGPIO(fe, 4, 0);
3057 status += MXL_SetGPIO(fe, 1, 1);
3058 status += MXL_SetGPIO(fe, 3, 1);
3059 }
3060 if (state->RF_IN >= 760000000 &&
3061 state->RF_IN <= 900000000) {
3062 status += MXL_ControlWrite(fe, DAC_A_ENABLE, 1);
3063 status += MXL_SetGPIO(fe, 4, 1);
3064 status += MXL_SetGPIO(fe, 1, 1);
3065 status += MXL_SetGPIO(fe, 3, 1);
3066 }
3067 }
3068 }
3069
3070 if (state->TF_Type == MXL_TF_E) /* Tracking Filter type E */ {
3071
3072 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
3073
3074 if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
3075 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3076 status += MXL_SetGPIO(fe, 4, 0);
3077 status += MXL_SetGPIO(fe, 1, 1);
3078 status += MXL_SetGPIO(fe, 3, 1);
3079 }
3080 if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
3081 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3082 status += MXL_SetGPIO(fe, 4, 0);
3083 status += MXL_SetGPIO(fe, 1, 0);
3084 status += MXL_SetGPIO(fe, 3, 1);
3085 }
3086 if (state->RF_IN >= 250000000 && state->RF_IN < 310000000) {
3087 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3088 status += MXL_SetGPIO(fe, 4, 1);
3089 status += MXL_SetGPIO(fe, 1, 0);
3090 status += MXL_SetGPIO(fe, 3, 1);
3091 }
3092 if (state->RF_IN >= 310000000 && state->RF_IN < 360000000) {
3093 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3094 status += MXL_SetGPIO(fe, 4, 1);
3095 status += MXL_SetGPIO(fe, 1, 0);
3096 status += MXL_SetGPIO(fe, 3, 0);
3097 }
3098 if (state->RF_IN >= 360000000 && state->RF_IN < 470000000) {
3099 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3100 status += MXL_SetGPIO(fe, 4, 1);
3101 status += MXL_SetGPIO(fe, 1, 1);
3102 status += MXL_SetGPIO(fe, 3, 0);
3103 }
3104 if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
3105 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3106 status += MXL_SetGPIO(fe, 4, 1);
3107 status += MXL_SetGPIO(fe, 1, 1);
3108 status += MXL_SetGPIO(fe, 3, 0);
3109 }
3110 if (state->RF_IN >= 640000000 && state->RF_IN <= 900000000) {
3111 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3112 status += MXL_SetGPIO(fe, 4, 1);
3113 status += MXL_SetGPIO(fe, 1, 1);
3114 status += MXL_SetGPIO(fe, 3, 1);
3115 }
3116 }
3117
3118 if (state->TF_Type == MXL_TF_F) {
3119
3120 /* Tracking Filter type F */
3121 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
3122
3123 if (state->RF_IN >= 43000000 && state->RF_IN < 160000000) {
3124 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3125 status += MXL_SetGPIO(fe, 4, 0);
3126 status += MXL_SetGPIO(fe, 1, 1);
3127 status += MXL_SetGPIO(fe, 3, 1);
3128 }
3129 if (state->RF_IN >= 160000000 && state->RF_IN < 210000000) {
3130 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3131 status += MXL_SetGPIO(fe, 4, 0);
3132 status += MXL_SetGPIO(fe, 1, 0);
3133 status += MXL_SetGPIO(fe, 3, 1);
3134 }
3135 if (state->RF_IN >= 210000000 && state->RF_IN < 300000000) {
3136 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3137 status += MXL_SetGPIO(fe, 4, 1);
3138 status += MXL_SetGPIO(fe, 1, 0);
3139 status += MXL_SetGPIO(fe, 3, 1);
3140 }
3141 if (state->RF_IN >= 300000000 && state->RF_IN < 390000000) {
3142 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3143 status += MXL_SetGPIO(fe, 4, 1);
3144 status += MXL_SetGPIO(fe, 1, 0);
3145 status += MXL_SetGPIO(fe, 3, 0);
3146 }
3147 if (state->RF_IN >= 390000000 && state->RF_IN < 515000000) {
3148 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3149 status += MXL_SetGPIO(fe, 4, 1);
3150 status += MXL_SetGPIO(fe, 1, 1);
3151 status += MXL_SetGPIO(fe, 3, 0);
3152 }
3153 if (state->RF_IN >= 515000000 && state->RF_IN < 650000000) {
3154 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3155 status += MXL_SetGPIO(fe, 4, 1);
3156 status += MXL_SetGPIO(fe, 1, 1);
3157 status += MXL_SetGPIO(fe, 3, 0);
3158 }
3159 if (state->RF_IN >= 650000000 && state->RF_IN <= 900000000) {
3160 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3161 status += MXL_SetGPIO(fe, 4, 1);
3162 status += MXL_SetGPIO(fe, 1, 1);
3163 status += MXL_SetGPIO(fe, 3, 1);
3164 }
3165 }
3166
3167 if (state->TF_Type == MXL_TF_E_2) {
3168
3169 /* Tracking Filter type E_2 */
3170 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
3171
3172 if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
3173 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3174 status += MXL_SetGPIO(fe, 4, 0);
3175 status += MXL_SetGPIO(fe, 1, 1);
3176 status += MXL_SetGPIO(fe, 3, 1);
3177 }
3178 if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
3179 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3180 status += MXL_SetGPIO(fe, 4, 0);
3181 status += MXL_SetGPIO(fe, 1, 0);
3182 status += MXL_SetGPIO(fe, 3, 1);
3183 }
3184 if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) {
3185 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3186 status += MXL_SetGPIO(fe, 4, 1);
3187 status += MXL_SetGPIO(fe, 1, 0);
3188 status += MXL_SetGPIO(fe, 3, 1);
3189 }
3190 if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
3191 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3192 status += MXL_SetGPIO(fe, 4, 1);
3193 status += MXL_SetGPIO(fe, 1, 0);
3194 status += MXL_SetGPIO(fe, 3, 0);
3195 }
3196 if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) {
3197 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3198 status += MXL_SetGPIO(fe, 4, 1);
3199 status += MXL_SetGPIO(fe, 1, 1);
3200 status += MXL_SetGPIO(fe, 3, 0);
3201 }
3202 if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) {
3203 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3204 status += MXL_SetGPIO(fe, 4, 1);
3205 status += MXL_SetGPIO(fe, 1, 1);
3206 status += MXL_SetGPIO(fe, 3, 0);
3207 }
3208 if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) {
3209 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3210 status += MXL_SetGPIO(fe, 4, 1);
3211 status += MXL_SetGPIO(fe, 1, 1);
3212 status += MXL_SetGPIO(fe, 3, 1);
3213 }
3214 }
3215
3216 if (state->TF_Type == MXL_TF_G) {
3217
3218 /* Tracking Filter type G add for v2.6.8 */
3219 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
3220
3221 if (state->RF_IN >= 50000000 && state->RF_IN < 190000000) {
3222
3223 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3224 status += MXL_SetGPIO(fe, 4, 0);
3225 status += MXL_SetGPIO(fe, 1, 1);
3226 status += MXL_SetGPIO(fe, 3, 1);
3227 }
3228 if (state->RF_IN >= 190000000 && state->RF_IN < 280000000) {
3229 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3230 status += MXL_SetGPIO(fe, 4, 0);
3231 status += MXL_SetGPIO(fe, 1, 0);
3232 status += MXL_SetGPIO(fe, 3, 1);
3233 }
3234 if (state->RF_IN >= 280000000 && state->RF_IN < 350000000) {
3235 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3236 status += MXL_SetGPIO(fe, 4, 1);
3237 status += MXL_SetGPIO(fe, 1, 0);
3238 status += MXL_SetGPIO(fe, 3, 1);
3239 }
3240 if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
3241 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3242 status += MXL_SetGPIO(fe, 4, 1);
3243 status += MXL_SetGPIO(fe, 1, 0);
3244 status += MXL_SetGPIO(fe, 3, 0);
3245 }
3246 if (state->RF_IN >= 400000000 && state->RF_IN < 470000000) {
3247 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3248 status += MXL_SetGPIO(fe, 4, 1);
3249 status += MXL_SetGPIO(fe, 1, 0);
3250 status += MXL_SetGPIO(fe, 3, 1);
3251 }
3252 if (state->RF_IN >= 470000000 && state->RF_IN < 640000000) {
3253 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3254 status += MXL_SetGPIO(fe, 4, 1);
3255 status += MXL_SetGPIO(fe, 1, 1);
3256 status += MXL_SetGPIO(fe, 3, 0);
3257 }
3258 if (state->RF_IN >= 640000000 && state->RF_IN < 820000000) {
3259 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3260 status += MXL_SetGPIO(fe, 4, 1);
3261 status += MXL_SetGPIO(fe, 1, 1);
3262 status += MXL_SetGPIO(fe, 3, 0);
3263 }
3264 if (state->RF_IN >= 820000000 && state->RF_IN <= 900000000) {
3265 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3266 status += MXL_SetGPIO(fe, 4, 1);
3267 status += MXL_SetGPIO(fe, 1, 1);
3268 status += MXL_SetGPIO(fe, 3, 1);
3269 }
3270 }
3271
3272 if (state->TF_Type == MXL_TF_E_NA) {
3273
3274 /* Tracking Filter type E-NA for Empia ONLY change for 2.6.8 */
3275 status += MXL_ControlWrite(fe, DAC_DIN_B, 0);
3276
3277 /* if UHF and terrestrial=> Turn off Tracking Filter */
3278 if (state->RF_IN >= 471000000 &&
3279 (state->RF_IN - 471000000)%6000000 != 0) {
3280
3281 /* Turn off all the banks */
3282 status += MXL_SetGPIO(fe, 3, 1);
3283 status += MXL_SetGPIO(fe, 1, 1);
3284 status += MXL_SetGPIO(fe, 4, 1);
3285 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3286
3287 /* 2.6.12 Turn on RSSI */
3288 status += MXL_ControlWrite(fe, SEQ_EXTSYNTHCALIF, 1);
3289 status += MXL_ControlWrite(fe, SEQ_EXTDCCAL, 1);
3290 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 1);
3291 status += MXL_ControlWrite(fe, RFA_ENCLKRFAGC, 1);
3292
3293 /* RSSI reference point */
3294 status += MXL_ControlWrite(fe, RFA_RSSI_REFH, 5);
3295 status += MXL_ControlWrite(fe, RFA_RSSI_REF, 3);
3296 status += MXL_ControlWrite(fe, RFA_RSSI_REFL, 2);
3297
3298 /* following parameter is from analog OTA mode,
3299 * can be change to seek better performance */
3300 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
3301 } else {
3302 /* if VHF or Cable => Turn on Tracking Filter */
3303
3304 /* 2.6.12 Turn off RSSI */
3305 status += MXL_ControlWrite(fe, AGC_EN_RSSI, 0);
3306
3307 /* change back from above condition */
3308 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 5);
3309
3310
3311 if (state->RF_IN >= 43000000 && state->RF_IN < 174000000) {
3312
3313 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3314 status += MXL_SetGPIO(fe, 4, 0);
3315 status += MXL_SetGPIO(fe, 1, 1);
3316 status += MXL_SetGPIO(fe, 3, 1);
3317 }
3318 if (state->RF_IN >= 174000000 && state->RF_IN < 250000000) {
3319 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3320 status += MXL_SetGPIO(fe, 4, 0);
3321 status += MXL_SetGPIO(fe, 1, 0);
3322 status += MXL_SetGPIO(fe, 3, 1);
3323 }
3324 if (state->RF_IN >= 250000000 && state->RF_IN < 350000000) {
3325 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3326 status += MXL_SetGPIO(fe, 4, 1);
3327 status += MXL_SetGPIO(fe, 1, 0);
3328 status += MXL_SetGPIO(fe, 3, 1);
3329 }
3330 if (state->RF_IN >= 350000000 && state->RF_IN < 400000000) {
3331 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3332 status += MXL_SetGPIO(fe, 4, 1);
3333 status += MXL_SetGPIO(fe, 1, 0);
3334 status += MXL_SetGPIO(fe, 3, 0);
3335 }
3336 if (state->RF_IN >= 400000000 && state->RF_IN < 570000000) {
3337 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 0);
3338 status += MXL_SetGPIO(fe, 4, 1);
3339 status += MXL_SetGPIO(fe, 1, 1);
3340 status += MXL_SetGPIO(fe, 3, 0);
3341 }
3342 if (state->RF_IN >= 570000000 && state->RF_IN < 770000000) {
3343 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3344 status += MXL_SetGPIO(fe, 4, 1);
3345 status += MXL_SetGPIO(fe, 1, 1);
3346 status += MXL_SetGPIO(fe, 3, 0);
3347 }
3348 if (state->RF_IN >= 770000000 && state->RF_IN <= 900000000) {
3349 status += MXL_ControlWrite(fe, DAC_B_ENABLE, 1);
3350 status += MXL_SetGPIO(fe, 4, 1);
3351 status += MXL_SetGPIO(fe, 1, 1);
3352 status += MXL_SetGPIO(fe, 3, 1);
3353 }
3354 }
3355 }
3356 return status ;
3357}
3358
3359static u16 MXL_SetGPIO(struct dvb_frontend *fe, u8 GPIO_Num, u8 GPIO_Val)
3360{
3361 u16 status = 0;
3362
3363 if (GPIO_Num == 1)
3364 status += MXL_ControlWrite(fe, GPIO_1B, GPIO_Val ? 0 : 1);
3365
3366 /* GPIO2 is not available */
3367
3368 if (GPIO_Num == 3) {
3369 if (GPIO_Val == 1) {
3370 status += MXL_ControlWrite(fe, GPIO_3, 0);
3371 status += MXL_ControlWrite(fe, GPIO_3B, 0);
3372 }
3373 if (GPIO_Val == 0) {
3374 status += MXL_ControlWrite(fe, GPIO_3, 1);
3375 status += MXL_ControlWrite(fe, GPIO_3B, 1);
3376 }
3377 if (GPIO_Val == 3) { /* tri-state */
3378 status += MXL_ControlWrite(fe, GPIO_3, 0);
3379 status += MXL_ControlWrite(fe, GPIO_3B, 1);
3380 }
3381 }
3382 if (GPIO_Num == 4) {
3383 if (GPIO_Val == 1) {
3384 status += MXL_ControlWrite(fe, GPIO_4, 0);
3385 status += MXL_ControlWrite(fe, GPIO_4B, 0);
3386 }
3387 if (GPIO_Val == 0) {
3388 status += MXL_ControlWrite(fe, GPIO_4, 1);
3389 status += MXL_ControlWrite(fe, GPIO_4B, 1);
3390 }
3391 if (GPIO_Val == 3) { /* tri-state */
3392 status += MXL_ControlWrite(fe, GPIO_4, 0);
3393 status += MXL_ControlWrite(fe, GPIO_4B, 1);
3394 }
3395 }
3396
3397 return status;
3398}
3399
3400static u16 MXL_ControlWrite(struct dvb_frontend *fe, u16 ControlNum, u32 value)
3401{
3402 u16 status = 0;
3403
3404 /* Will write ALL Matching Control Name */
3405 /* Write Matching INIT Control */
3406 status += MXL_ControlWrite_Group(fe, ControlNum, value, 1);
3407 /* Write Matching CH Control */
3408 status += MXL_ControlWrite_Group(fe, ControlNum, value, 2);
3409#ifdef _MXL_INTERNAL
3410 /* Write Matching MXL Control */
3411 status += MXL_ControlWrite_Group(fe, ControlNum, value, 3);
3412#endif
3413 return status;
3414}
3415
3416static u16 MXL_ControlWrite_Group(struct dvb_frontend *fe, u16 controlNum,
3417 u32 value, u16 controlGroup)
3418{
3419 struct mxl5005s_state *state = fe->tuner_priv;
3420 u16 i, j, k;
3421 u32 highLimit;
3422 u32 ctrlVal;
3423
3424 if (controlGroup == 1) /* Initial Control */ {
3425
3426 for (i = 0; i < state->Init_Ctrl_Num; i++) {
3427
3428 if (controlNum == state->Init_Ctrl[i].Ctrl_Num) {
3429
3430 highLimit = 1 << state->Init_Ctrl[i].size;
3431 if (value < highLimit) {
3432 for (j = 0; j < state->Init_Ctrl[i].size; j++) {
3433 state->Init_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
3434 MXL_RegWriteBit(fe, (u8)(state->Init_Ctrl[i].addr[j]),
3435 (u8)(state->Init_Ctrl[i].bit[j]),
3436 (u8)((value>>j) & 0x01));
3437 }
3438 ctrlVal = 0;
3439 for (k = 0; k < state->Init_Ctrl[i].size; k++)
3440 ctrlVal += state->Init_Ctrl[i].val[k] * (1 << k);
3441 } else
3442 return -1;
3443 }
3444 }
3445 }
3446 if (controlGroup == 2) /* Chan change Control */ {
3447
3448 for (i = 0; i < state->CH_Ctrl_Num; i++) {
3449
3450 if (controlNum == state->CH_Ctrl[i].Ctrl_Num) {
3451
3452 highLimit = 1 << state->CH_Ctrl[i].size;
3453 if (value < highLimit) {
3454 for (j = 0; j < state->CH_Ctrl[i].size; j++) {
3455 state->CH_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
3456 MXL_RegWriteBit(fe, (u8)(state->CH_Ctrl[i].addr[j]),
3457 (u8)(state->CH_Ctrl[i].bit[j]),
3458 (u8)((value>>j) & 0x01));
3459 }
3460 ctrlVal = 0;
3461 for (k = 0; k < state->CH_Ctrl[i].size; k++)
3462 ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
3463 } else
3464 return -1;
3465 }
3466 }
3467 }
3468#ifdef _MXL_INTERNAL
3469 if (controlGroup == 3) /* Maxlinear Control */ {
3470
3471 for (i = 0; i < state->MXL_Ctrl_Num; i++) {
3472
3473 if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) {
3474
3475 highLimit = (1 << state->MXL_Ctrl[i].size);
3476 if (value < highLimit) {
3477 for (j = 0; j < state->MXL_Ctrl[i].size; j++) {
3478 state->MXL_Ctrl[i].val[j] = (u8)((value >> j) & 0x01);
3479 MXL_RegWriteBit(fe, (u8)(state->MXL_Ctrl[i].addr[j]),
3480 (u8)(state->MXL_Ctrl[i].bit[j]),
3481 (u8)((value>>j) & 0x01));
3482 }
3483 ctrlVal = 0;
3484 for (k = 0; k < state->MXL_Ctrl[i].size; k++)
3485 ctrlVal += state->
3486 MXL_Ctrl[i].val[k] *
3487 (1 << k);
3488 } else
3489 return -1;
3490 }
3491 }
3492 }
3493#endif
3494 return 0 ; /* successful return */
3495}
3496
3497static u16 MXL_RegRead(struct dvb_frontend *fe, u8 RegNum, u8 *RegVal)
3498{
3499 struct mxl5005s_state *state = fe->tuner_priv;
3500 int i ;
3501
3502 for (i = 0; i < 104; i++) {
3503 if (RegNum == state->TunerRegs[i].Reg_Num) {
3504 *RegVal = (u8)(state->TunerRegs[i].Reg_Val);
3505 return 0;
3506 }
3507 }
3508
3509 return 1;
3510}
3511
3512static u16 MXL_ControlRead(struct dvb_frontend *fe, u16 controlNum, u32 *value)
3513{
3514 struct mxl5005s_state *state = fe->tuner_priv;
3515 u32 ctrlVal ;
3516 u16 i, k ;
3517
3518 for (i = 0; i < state->Init_Ctrl_Num ; i++) {
3519
3520 if (controlNum == state->Init_Ctrl[i].Ctrl_Num) {
3521
3522 ctrlVal = 0;
3523 for (k = 0; k < state->Init_Ctrl[i].size; k++)
3524 ctrlVal += state->Init_Ctrl[i].val[k] * (1<<k);
3525 *value = ctrlVal;
3526 return 0;
3527 }
3528 }
3529
3530 for (i = 0; i < state->CH_Ctrl_Num ; i++) {
3531
3532 if (controlNum == state->CH_Ctrl[i].Ctrl_Num) {
3533
3534 ctrlVal = 0;
3535 for (k = 0; k < state->CH_Ctrl[i].size; k++)
3536 ctrlVal += state->CH_Ctrl[i].val[k] * (1 << k);
3537 *value = ctrlVal;
3538 return 0;
3539
3540 }
3541 }
3542
3543#ifdef _MXL_INTERNAL
3544 for (i = 0; i < state->MXL_Ctrl_Num ; i++) {
3545
3546 if (controlNum == state->MXL_Ctrl[i].Ctrl_Num) {
3547
3548 ctrlVal = 0;
3549 for (k = 0; k < state->MXL_Ctrl[i].size; k++)
3550 ctrlVal += state->MXL_Ctrl[i].val[k] * (1<<k);
3551 *value = ctrlVal;
3552 return 0;
3553
3554 }
3555 }
3556#endif
3557 return 1;
3558}
3559
3560static void MXL_RegWriteBit(struct dvb_frontend *fe, u8 address, u8 bit,
3561 u8 bitVal)
3562{
3563 struct mxl5005s_state *state = fe->tuner_priv;
3564 int i ;
3565
3566 const u8 AND_MAP[8] = {
3567 0xFE, 0xFD, 0xFB, 0xF7,
3568 0xEF, 0xDF, 0xBF, 0x7F } ;
3569
3570 const u8 OR_MAP[8] = {
3571 0x01, 0x02, 0x04, 0x08,
3572 0x10, 0x20, 0x40, 0x80 } ;
3573
3574 for (i = 0; i < state->TunerRegs_Num; i++) {
3575 if (state->TunerRegs[i].Reg_Num == address) {
3576 if (bitVal)
3577 state->TunerRegs[i].Reg_Val |= OR_MAP[bit];
3578 else
3579 state->TunerRegs[i].Reg_Val &= AND_MAP[bit];
3580 break ;
3581 }
3582 }
3583}
3584
3585static u32 MXL_Ceiling(u32 value, u32 resolution)
3586{
3587 return value / resolution + (value % resolution > 0 ? 1 : 0);
3588}
3589
3590/* Retrieve the Initialzation Registers */
3591static u16 MXL_GetInitRegister(struct dvb_frontend *fe, u8 *RegNum,
3592 u8 *RegVal, int *count)
3593{
3594 u16 status = 0;
3595 int i ;
3596
3597 u8 RegAddr[] = {
3598 11, 12, 13, 22, 32, 43, 44, 53, 56, 59, 73,
3599 76, 77, 91, 134, 135, 137, 147,
3600 156, 166, 167, 168, 25 };
3601
3602 *count = ARRAY_SIZE(RegAddr);
3603
3604 status += MXL_BlockInit(fe);
3605
3606 for (i = 0 ; i < *count; i++) {
3607 RegNum[i] = RegAddr[i];
3608 status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
3609 }
3610
3611 return status;
3612}
3613
3614static u16 MXL_GetCHRegister(struct dvb_frontend *fe, u8 *RegNum, u8 *RegVal,
3615 int *count)
3616{
3617 u16 status = 0;
3618 int i ;
3619
3620/* add 77, 166, 167, 168 register for 2.6.12 */
3621#ifdef _MXL_PRODUCTION
3622 u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 65, 68, 69, 70, 73, 92, 93, 106,
3623 107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
3624#else
3625 u8 RegAddr[] = {14, 15, 16, 17, 22, 43, 68, 69, 70, 73, 92, 93, 106,
3626 107, 108, 109, 110, 111, 112, 136, 138, 149, 77, 166, 167, 168 } ;
3627 /*
3628 u8 RegAddr[171];
3629 for (i = 0; i <= 170; i++)
3630 RegAddr[i] = i;
3631 */
3632#endif
3633
3634 *count = ARRAY_SIZE(RegAddr);
3635
3636 for (i = 0 ; i < *count; i++) {
3637 RegNum[i] = RegAddr[i];
3638 status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
3639 }
3640
3641 return status;
3642}
3643
3644static u16 MXL_GetCHRegister_ZeroIF(struct dvb_frontend *fe, u8 *RegNum,
3645 u8 *RegVal, int *count)
3646{
3647 u16 status = 0;
3648 int i;
3649
3650 u8 RegAddr[] = {43, 136};
3651
3652 *count = ARRAY_SIZE(RegAddr);
3653
3654 for (i = 0; i < *count; i++) {
3655 RegNum[i] = RegAddr[i];
3656 status += MXL_RegRead(fe, RegNum[i], &RegVal[i]);
3657 }
3658
3659 return status;
3660}
3661
3662static u16 MXL_GetMasterControl(u8 *MasterReg, int state)
3663{
3664 if (state == 1) /* Load_Start */
3665 *MasterReg = 0xF3;
3666 if (state == 2) /* Power_Down */
3667 *MasterReg = 0x41;
3668 if (state == 3) /* Synth_Reset */
3669 *MasterReg = 0xB1;
3670 if (state == 4) /* Seq_Off */
3671 *MasterReg = 0xF1;
3672
3673 return 0;
3674}
3675
3676#ifdef _MXL_PRODUCTION
3677static u16 MXL_VCORange_Test(struct dvb_frontend *fe, int VCO_Range)
3678{
3679 struct mxl5005s_state *state = fe->tuner_priv;
3680 u16 status = 0 ;
3681
3682 if (VCO_Range == 1) {
3683 status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
3684 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
3685 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
3686 status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
3687 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
3688 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
3689 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
3690 if (state->Mode == 0 && state->IF_Mode == 1) {
3691 /* Analog Low IF Mode */
3692 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
3693 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
3694 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
3695 status += MXL_ControlWrite(fe,
3696 CHCAL_FRAC_MOD_RF, 180224);
3697 }
3698 if (state->Mode == 0 && state->IF_Mode == 0) {
3699 /* Analog Zero IF Mode */
3700 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
3701 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
3702 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
3703 status += MXL_ControlWrite(fe,
3704 CHCAL_FRAC_MOD_RF, 222822);
3705 }
3706 if (state->Mode == 1) /* Digital Mode */ {
3707 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
3708 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
3709 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 56);
3710 status += MXL_ControlWrite(fe,
3711 CHCAL_FRAC_MOD_RF, 229376);
3712 }
3713 }
3714
3715 if (VCO_Range == 2) {
3716 status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
3717 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
3718 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
3719 status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
3720 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
3721 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
3722 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
3723 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
3724 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
3725 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41);
3726 if (state->Mode == 0 && state->IF_Mode == 1) {
3727 /* Analog Low IF Mode */
3728 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
3729 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
3730 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
3731 status += MXL_ControlWrite(fe,
3732 CHCAL_FRAC_MOD_RF, 206438);
3733 }
3734 if (state->Mode == 0 && state->IF_Mode == 0) {
3735 /* Analog Zero IF Mode */
3736 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
3737 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
3738 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
3739 status += MXL_ControlWrite(fe,
3740 CHCAL_FRAC_MOD_RF, 206438);
3741 }
3742 if (state->Mode == 1) /* Digital Mode */ {
3743 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 1);
3744 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
3745 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 41);
3746 status += MXL_ControlWrite(fe,
3747 CHCAL_FRAC_MOD_RF, 16384);
3748 }
3749 }
3750
3751 if (VCO_Range == 3) {
3752 status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
3753 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
3754 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
3755 status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
3756 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
3757 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
3758 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
3759 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
3760 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
3761 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
3762 if (state->Mode == 0 && state->IF_Mode == 1) {
3763 /* Analog Low IF Mode */
3764 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
3765 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
3766 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44);
3767 status += MXL_ControlWrite(fe,
3768 CHCAL_FRAC_MOD_RF, 173670);
3769 }
3770 if (state->Mode == 0 && state->IF_Mode == 0) {
3771 /* Analog Zero IF Mode */
3772 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
3773 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
3774 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 44);
3775 status += MXL_ControlWrite(fe,
3776 CHCAL_FRAC_MOD_RF, 173670);
3777 }
3778 if (state->Mode == 1) /* Digital Mode */ {
3779 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
3780 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 8);
3781 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 42);
3782 status += MXL_ControlWrite(fe,
3783 CHCAL_FRAC_MOD_RF, 245760);
3784 }
3785 }
3786
3787 if (VCO_Range == 4) {
3788 status += MXL_ControlWrite(fe, RFSYN_EN_DIV, 1);
3789 status += MXL_ControlWrite(fe, RFSYN_EN_OUTMUX, 0);
3790 status += MXL_ControlWrite(fe, RFSYN_SEL_DIVM, 0);
3791 status += MXL_ControlWrite(fe, RFSYN_DIVM, 1);
3792 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_OUT, 1);
3793 status += MXL_ControlWrite(fe, RFSYN_RF_DIV_BIAS, 1);
3794 status += MXL_ControlWrite(fe, DN_SEL_FREQ, 0);
3795 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
3796 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
3797 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
3798 if (state->Mode == 0 && state->IF_Mode == 1) {
3799 /* Analog Low IF Mode */
3800 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
3801 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
3802 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
3803 status += MXL_ControlWrite(fe,
3804 CHCAL_FRAC_MOD_RF, 206438);
3805 }
3806 if (state->Mode == 0 && state->IF_Mode == 0) {
3807 /* Analog Zero IF Mode */
3808 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
3809 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
3810 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
3811 status += MXL_ControlWrite(fe,
3812 CHCAL_FRAC_MOD_RF, 206438);
3813 }
3814 if (state->Mode == 1) /* Digital Mode */ {
3815 status += MXL_ControlWrite(fe, RFSYN_SEL_VCO_HI, 0);
3816 status += MXL_ControlWrite(fe, RFSYN_VCO_BIAS, 40);
3817 status += MXL_ControlWrite(fe, CHCAL_INT_MOD_RF, 27);
3818 status += MXL_ControlWrite(fe,
3819 CHCAL_FRAC_MOD_RF, 212992);
3820 }
3821 }
3822
3823 return status;
3824}
3825
3826static u16 MXL_Hystersis_Test(struct dvb_frontend *fe, int Hystersis)
3827{
3828 struct mxl5005s_state *state = fe->tuner_priv;
3829 u16 status = 0;
3830
3831 if (Hystersis == 1)
3832 status += MXL_ControlWrite(fe, DN_BYPASS_AGC_I2C, 1);
3833
3834 return status;
3835}
3836#endif
3837/* End: Reference driver code found in the Realtek driver that
3838 * is copyright MaxLinear */
3839
3840/* ----------------------------------------------------------------
3841 * Begin: Everything after here is new code to adapt the
3842 * proprietary Realtek driver into a Linux API tuner.
3843 * Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
3844 */
3845static int mxl5005s_reset(struct dvb_frontend *fe)
3846{
3847 struct mxl5005s_state *state = fe->tuner_priv;
3848 int ret = 0;
3849
3850 u8 buf[2] = { 0xff, 0x00 };
3851 struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
3852 .buf = buf, .len = 2 };
3853
3854 dprintk(2, "%s()\n", __func__);
3855
3856 if (fe->ops.i2c_gate_ctrl)
3857 fe->ops.i2c_gate_ctrl(fe, 1);
3858
3859 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
3860 printk(KERN_WARNING "mxl5005s I2C reset failed\n");
3861 ret = -EREMOTEIO;
3862 }
3863
3864 if (fe->ops.i2c_gate_ctrl)
3865 fe->ops.i2c_gate_ctrl(fe, 0);
3866
3867 return ret;
3868}
3869
3870/* Write a single byte to a single reg, latch the value if required by
3871 * following the transaction with the latch byte.
3872 */
3873static int mxl5005s_writereg(struct dvb_frontend *fe, u8 reg, u8 val, int latch)
3874{
3875 struct mxl5005s_state *state = fe->tuner_priv;
3876 u8 buf[3] = { reg, val, MXL5005S_LATCH_BYTE };
3877 struct i2c_msg msg = { .addr = state->config->i2c_address, .flags = 0,
3878 .buf = buf, .len = 3 };
3879
3880 if (latch == 0)
3881 msg.len = 2;
3882
3883 dprintk(2, "%s(0x%x, 0x%x, 0x%x)\n", __func__, reg, val, msg.addr);
3884
3885 if (i2c_transfer(state->i2c, &msg, 1) != 1) {
3886 printk(KERN_WARNING "mxl5005s I2C write failed\n");
3887 return -EREMOTEIO;
3888 }
3889 return 0;
3890}
3891
3892static int mxl5005s_writeregs(struct dvb_frontend *fe, u8 *addrtable,
3893 u8 *datatable, u8 len)
3894{
3895 int ret = 0, i;
3896
3897 if (fe->ops.i2c_gate_ctrl)
3898 fe->ops.i2c_gate_ctrl(fe, 1);
3899
3900 for (i = 0 ; i < len-1; i++) {
3901 ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 0);
3902 if (ret < 0)
3903 break;
3904 }
3905
3906 ret = mxl5005s_writereg(fe, addrtable[i], datatable[i], 1);
3907
3908 if (fe->ops.i2c_gate_ctrl)
3909 fe->ops.i2c_gate_ctrl(fe, 0);
3910
3911 return ret;
3912}
3913
3914static int mxl5005s_init(struct dvb_frontend *fe)
3915{
3916 struct mxl5005s_state *state = fe->tuner_priv;
3917
3918 dprintk(1, "%s()\n", __func__);
3919 state->current_mode = MXL_QAM;
3920 return mxl5005s_reconfigure(fe, MXL_QAM, MXL5005S_BANDWIDTH_6MHZ);
3921}
3922
3923static int mxl5005s_reconfigure(struct dvb_frontend *fe, u32 mod_type,
3924 u32 bandwidth)
3925{
3926 struct mxl5005s_state *state = fe->tuner_priv;
3927
3928 u8 AddrTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
3929 u8 ByteTable[MXL5005S_REG_WRITING_TABLE_LEN_MAX];
3930 int TableLen;
3931
3932 dprintk(1, "%s(type=%d, bw=%d)\n", __func__, mod_type, bandwidth);
3933
3934 mxl5005s_reset(fe);
3935
3936 /* Tuner initialization stage 0 */
3937 MXL_GetMasterControl(ByteTable, MC_SYNTH_RESET);
3938 AddrTable[0] = MASTER_CONTROL_ADDR;
3939 ByteTable[0] |= state->config->AgcMasterByte;
3940
3941 mxl5005s_writeregs(fe, AddrTable, ByteTable, 1);
3942
3943 mxl5005s_AssignTunerMode(fe, mod_type, bandwidth);
3944
3945 /* Tuner initialization stage 1 */
3946 MXL_GetInitRegister(fe, AddrTable, ByteTable, &TableLen);
3947
3948 mxl5005s_writeregs(fe, AddrTable, ByteTable, TableLen);
3949
3950 return 0;
3951}
3952
3953static int mxl5005s_AssignTunerMode(struct dvb_frontend *fe, u32 mod_type,
3954 u32 bandwidth)
3955{
3956 struct mxl5005s_state *state = fe->tuner_priv;
3957 struct mxl5005s_config *c = state->config;
3958
3959 InitTunerControls(fe);
3960
3961 /* Set MxL5005S parameters. */
3962 MXL5005_TunerConfig(
3963 fe,
3964 c->mod_mode,
3965 c->if_mode,
3966 bandwidth,
3967 c->if_freq,
3968 c->xtal_freq,
3969 c->agc_mode,
3970 c->top,
3971 c->output_load,
3972 c->clock_out,
3973 c->div_out,
3974 c->cap_select,
3975 c->rssi_enable,
3976 mod_type,
3977 c->tracking_filter);
3978
3979 return 0;
3980}
3981
3982static int mxl5005s_set_params(struct dvb_frontend *fe)
3983{
3984 struct mxl5005s_state *state = fe->tuner_priv;
3985 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
3986 u32 delsys = c->delivery_system;
3987 u32 bw = c->bandwidth_hz;
3988 u32 req_mode, req_bw = 0;
3989 int ret;
3990
3991 dprintk(1, "%s()\n", __func__);
3992
3993 switch (delsys) {
3994 case SYS_ATSC:
3995 req_mode = MXL_ATSC;
3996 req_bw = MXL5005S_BANDWIDTH_6MHZ;
3997 break;
3998 case SYS_DVBC_ANNEX_B:
3999 req_mode = MXL_QAM;
4000 req_bw = MXL5005S_BANDWIDTH_6MHZ;
4001 break;
4002 default: /* Assume DVB-T */
4003 req_mode = MXL_DVBT;
4004 switch (bw) {
4005 case 6000000:
4006 req_bw = MXL5005S_BANDWIDTH_6MHZ;
4007 break;
4008 case 7000000:
4009 req_bw = MXL5005S_BANDWIDTH_7MHZ;
4010 break;
4011 case 8000000:
4012 case 0:
4013 req_bw = MXL5005S_BANDWIDTH_8MHZ;
4014 break;
4015 default:
4016 return -EINVAL;
4017 }
4018 }
4019
4020 /* Change tuner for new modulation type if reqd */
4021 if (req_mode != state->current_mode ||
4022 req_bw != state->Chan_Bandwidth) {
4023 state->current_mode = req_mode;
4024 ret = mxl5005s_reconfigure(fe, req_mode, req_bw);
4025
4026 } else
4027 ret = 0;
4028
4029 if (ret == 0) {
4030 dprintk(1, "%s() freq=%d\n", __func__, c->frequency);
4031 ret = mxl5005s_SetRfFreqHz(fe, c->frequency);
4032 }
4033
4034 return ret;
4035}
4036
4037static int mxl5005s_get_frequency(struct dvb_frontend *fe, u32 *frequency)
4038{
4039 struct mxl5005s_state *state = fe->tuner_priv;
4040 dprintk(1, "%s()\n", __func__);
4041
4042 *frequency = state->RF_IN;
4043
4044 return 0;
4045}
4046
4047static int mxl5005s_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
4048{
4049 struct mxl5005s_state *state = fe->tuner_priv;
4050 dprintk(1, "%s()\n", __func__);
4051
4052 *bandwidth = state->Chan_Bandwidth;
4053
4054 return 0;
4055}
4056
4057static int mxl5005s_release(struct dvb_frontend *fe)
4058{
4059 dprintk(1, "%s()\n", __func__);
4060 kfree(fe->tuner_priv);
4061 fe->tuner_priv = NULL;
4062 return 0;
4063}
4064
4065static const struct dvb_tuner_ops mxl5005s_tuner_ops = {
4066 .info = {
4067 .name = "MaxLinear MXL5005S",
4068 .frequency_min = 48000000,
4069 .frequency_max = 860000000,
4070 .frequency_step = 50000,
4071 },
4072
4073 .release = mxl5005s_release,
4074 .init = mxl5005s_init,
4075
4076 .set_params = mxl5005s_set_params,
4077 .get_frequency = mxl5005s_get_frequency,
4078 .get_bandwidth = mxl5005s_get_bandwidth,
4079};
4080
4081struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
4082 struct i2c_adapter *i2c,
4083 struct mxl5005s_config *config)
4084{
4085 struct mxl5005s_state *state = NULL;
4086 dprintk(1, "%s()\n", __func__);
4087
4088 state = kzalloc(sizeof(struct mxl5005s_state), GFP_KERNEL);
4089 if (state == NULL)
4090 return NULL;
4091
4092 state->frontend = fe;
4093 state->config = config;
4094 state->i2c = i2c;
4095
4096 printk(KERN_INFO "MXL5005S: Attached at address 0x%02x\n",
4097 config->i2c_address);
4098
4099 memcpy(&fe->ops.tuner_ops, &mxl5005s_tuner_ops,
4100 sizeof(struct dvb_tuner_ops));
4101
4102 fe->tuner_priv = state;
4103 return fe;
4104}
4105EXPORT_SYMBOL(mxl5005s_attach);
4106
4107MODULE_DESCRIPTION("MaxLinear MXL5005S silicon tuner driver");
4108MODULE_AUTHOR("Steven Toth");
4109MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/mxl5005s.h b/drivers/media/tuners/mxl5005s.h
new file mode 100644
index 000000000000..fc8a1ffc53b4
--- /dev/null
+++ b/drivers/media/tuners/mxl5005s.h
@@ -0,0 +1,135 @@
1/*
2 MaxLinear MXL5005S VSB/QAM/DVBT tuner driver
3
4 Copyright (C) 2008 MaxLinear
5 Copyright (C) 2008 Steven Toth <stoth@linuxtv.org>
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20
21*/
22
23#ifndef __MXL5005S_H
24#define __MXL5005S_H
25
26#include <linux/i2c.h>
27#include "dvb_frontend.h"
28
29struct mxl5005s_config {
30
31 /* 7 bit i2c address */
32 u8 i2c_address;
33
34#define IF_FREQ_4570000HZ 4570000
35#define IF_FREQ_4571429HZ 4571429
36#define IF_FREQ_5380000HZ 5380000
37#define IF_FREQ_36000000HZ 36000000
38#define IF_FREQ_36125000HZ 36125000
39#define IF_FREQ_36166667HZ 36166667
40#define IF_FREQ_44000000HZ 44000000
41 u32 if_freq;
42
43#define CRYSTAL_FREQ_4000000HZ 4000000
44#define CRYSTAL_FREQ_16000000HZ 16000000
45#define CRYSTAL_FREQ_25000000HZ 25000000
46#define CRYSTAL_FREQ_28800000HZ 28800000
47 u32 xtal_freq;
48
49#define MXL_DUAL_AGC 0
50#define MXL_SINGLE_AGC 1
51 u8 agc_mode;
52
53#define MXL_TF_DEFAULT 0
54#define MXL_TF_OFF 1
55#define MXL_TF_C 2
56#define MXL_TF_C_H 3
57#define MXL_TF_D 4
58#define MXL_TF_D_L 5
59#define MXL_TF_E 6
60#define MXL_TF_F 7
61#define MXL_TF_E_2 8
62#define MXL_TF_E_NA 9
63#define MXL_TF_G 10
64 u8 tracking_filter;
65
66#define MXL_RSSI_DISABLE 0
67#define MXL_RSSI_ENABLE 1
68 u8 rssi_enable;
69
70#define MXL_CAP_SEL_DISABLE 0
71#define MXL_CAP_SEL_ENABLE 1
72 u8 cap_select;
73
74#define MXL_DIV_OUT_1 0
75#define MXL_DIV_OUT_4 1
76 u8 div_out;
77
78#define MXL_CLOCK_OUT_DISABLE 0
79#define MXL_CLOCK_OUT_ENABLE 1
80 u8 clock_out;
81
82#define MXL5005S_IF_OUTPUT_LOAD_200_OHM 200
83#define MXL5005S_IF_OUTPUT_LOAD_300_OHM 300
84 u32 output_load;
85
86#define MXL5005S_TOP_5P5 55
87#define MXL5005S_TOP_7P2 72
88#define MXL5005S_TOP_9P2 92
89#define MXL5005S_TOP_11P0 110
90#define MXL5005S_TOP_12P9 129
91#define MXL5005S_TOP_14P7 147
92#define MXL5005S_TOP_16P8 168
93#define MXL5005S_TOP_19P4 194
94#define MXL5005S_TOP_21P2 212
95#define MXL5005S_TOP_23P2 232
96#define MXL5005S_TOP_25P2 252
97#define MXL5005S_TOP_27P1 271
98#define MXL5005S_TOP_29P2 292
99#define MXL5005S_TOP_31P7 317
100#define MXL5005S_TOP_34P9 349
101 u32 top;
102
103#define MXL_ANALOG_MODE 0
104#define MXL_DIGITAL_MODE 1
105 u8 mod_mode;
106
107#define MXL_ZERO_IF 0
108#define MXL_LOW_IF 1
109 u8 if_mode;
110
111 /* Some boards need to override the built-in logic for determining
112 the gain when in QAM mode (the HVR-1600 is one such case) */
113 u8 qam_gain;
114
115 /* Stuff I don't know what to do with */
116 u8 AgcMasterByte;
117};
118
119#if defined(CONFIG_MEDIA_TUNER_MXL5005S) || \
120 (defined(CONFIG_MEDIA_TUNER_MXL5005S_MODULE) && defined(MODULE))
121extern struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
122 struct i2c_adapter *i2c,
123 struct mxl5005s_config *config);
124#else
125static inline struct dvb_frontend *mxl5005s_attach(struct dvb_frontend *fe,
126 struct i2c_adapter *i2c,
127 struct mxl5005s_config *config)
128{
129 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
130 return NULL;
131}
132#endif /* CONFIG_DVB_TUNER_MXL5005S */
133
134#endif /* __MXL5005S_H */
135
diff --git a/drivers/media/tuners/mxl5007t.c b/drivers/media/tuners/mxl5007t.c
new file mode 100644
index 000000000000..69e453ef0a1a
--- /dev/null
+++ b/drivers/media/tuners/mxl5007t.c
@@ -0,0 +1,928 @@
1/*
2 * mxl5007t.c - driver for the MaxLinear MxL5007T silicon tuner
3 *
4 * Copyright (C) 2008, 2009 Michael Krufky <mkrufky@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/i2c.h>
22#include <linux/types.h>
23#include <linux/videodev2.h>
24#include "tuner-i2c.h"
25#include "mxl5007t.h"
26
27static DEFINE_MUTEX(mxl5007t_list_mutex);
28static LIST_HEAD(hybrid_tuner_instance_list);
29
30static int mxl5007t_debug;
31module_param_named(debug, mxl5007t_debug, int, 0644);
32MODULE_PARM_DESC(debug, "set debug level");
33
34/* ------------------------------------------------------------------------- */
35
36#define mxl_printk(kern, fmt, arg...) \
37 printk(kern "%s: " fmt "\n", __func__, ##arg)
38
39#define mxl_err(fmt, arg...) \
40 mxl_printk(KERN_ERR, "%d: " fmt, __LINE__, ##arg)
41
42#define mxl_warn(fmt, arg...) \
43 mxl_printk(KERN_WARNING, fmt, ##arg)
44
45#define mxl_info(fmt, arg...) \
46 mxl_printk(KERN_INFO, fmt, ##arg)
47
48#define mxl_debug(fmt, arg...) \
49({ \
50 if (mxl5007t_debug) \
51 mxl_printk(KERN_DEBUG, fmt, ##arg); \
52})
53
54#define mxl_fail(ret) \
55({ \
56 int __ret; \
57 __ret = (ret < 0); \
58 if (__ret) \
59 mxl_printk(KERN_ERR, "error %d on line %d", \
60 ret, __LINE__); \
61 __ret; \
62})
63
64/* ------------------------------------------------------------------------- */
65
66#define MHz 1000000
67
68enum mxl5007t_mode {
69 MxL_MODE_ISDBT = 0,
70 MxL_MODE_DVBT = 1,
71 MxL_MODE_ATSC = 2,
72 MxL_MODE_CABLE = 0x10,
73};
74
75enum mxl5007t_chip_version {
76 MxL_UNKNOWN_ID = 0x00,
77 MxL_5007_V1_F1 = 0x11,
78 MxL_5007_V1_F2 = 0x12,
79 MxL_5007_V4 = 0x14,
80 MxL_5007_V2_100_F1 = 0x21,
81 MxL_5007_V2_100_F2 = 0x22,
82 MxL_5007_V2_200_F1 = 0x23,
83 MxL_5007_V2_200_F2 = 0x24,
84};
85
86struct reg_pair_t {
87 u8 reg;
88 u8 val;
89};
90
91/* ------------------------------------------------------------------------- */
92
93static struct reg_pair_t init_tab[] = {
94 { 0x02, 0x06 },
95 { 0x03, 0x48 },
96 { 0x05, 0x04 },
97 { 0x06, 0x10 },
98 { 0x2e, 0x15 }, /* OVERRIDE */
99 { 0x30, 0x10 }, /* OVERRIDE */
100 { 0x45, 0x58 }, /* OVERRIDE */
101 { 0x48, 0x19 }, /* OVERRIDE */
102 { 0x52, 0x03 }, /* OVERRIDE */
103 { 0x53, 0x44 }, /* OVERRIDE */
104 { 0x6a, 0x4b }, /* OVERRIDE */
105 { 0x76, 0x00 }, /* OVERRIDE */
106 { 0x78, 0x18 }, /* OVERRIDE */
107 { 0x7a, 0x17 }, /* OVERRIDE */
108 { 0x85, 0x06 }, /* OVERRIDE */
109 { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
110 { 0, 0 }
111};
112
113static struct reg_pair_t init_tab_cable[] = {
114 { 0x02, 0x06 },
115 { 0x03, 0x48 },
116 { 0x05, 0x04 },
117 { 0x06, 0x10 },
118 { 0x09, 0x3f },
119 { 0x0a, 0x3f },
120 { 0x0b, 0x3f },
121 { 0x2e, 0x15 }, /* OVERRIDE */
122 { 0x30, 0x10 }, /* OVERRIDE */
123 { 0x45, 0x58 }, /* OVERRIDE */
124 { 0x48, 0x19 }, /* OVERRIDE */
125 { 0x52, 0x03 }, /* OVERRIDE */
126 { 0x53, 0x44 }, /* OVERRIDE */
127 { 0x6a, 0x4b }, /* OVERRIDE */
128 { 0x76, 0x00 }, /* OVERRIDE */
129 { 0x78, 0x18 }, /* OVERRIDE */
130 { 0x7a, 0x17 }, /* OVERRIDE */
131 { 0x85, 0x06 }, /* OVERRIDE */
132 { 0x01, 0x01 }, /* TOP_MASTER_ENABLE */
133 { 0, 0 }
134};
135
136/* ------------------------------------------------------------------------- */
137
138static struct reg_pair_t reg_pair_rftune[] = {
139 { 0x0f, 0x00 }, /* abort tune */
140 { 0x0c, 0x15 },
141 { 0x0d, 0x40 },
142 { 0x0e, 0x0e },
143 { 0x1f, 0x87 }, /* OVERRIDE */
144 { 0x20, 0x1f }, /* OVERRIDE */
145 { 0x21, 0x87 }, /* OVERRIDE */
146 { 0x22, 0x1f }, /* OVERRIDE */
147 { 0x80, 0x01 }, /* freq dependent */
148 { 0x0f, 0x01 }, /* start tune */
149 { 0, 0 }
150};
151
152/* ------------------------------------------------------------------------- */
153
154struct mxl5007t_state {
155 struct list_head hybrid_tuner_instance_list;
156 struct tuner_i2c_props i2c_props;
157
158 struct mutex lock;
159
160 struct mxl5007t_config *config;
161
162 enum mxl5007t_chip_version chip_id;
163
164 struct reg_pair_t tab_init[ARRAY_SIZE(init_tab)];
165 struct reg_pair_t tab_init_cable[ARRAY_SIZE(init_tab_cable)];
166 struct reg_pair_t tab_rftune[ARRAY_SIZE(reg_pair_rftune)];
167
168 enum mxl5007t_if_freq if_freq;
169
170 u32 frequency;
171 u32 bandwidth;
172};
173
174/* ------------------------------------------------------------------------- */
175
176/* called by _init and _rftun to manipulate the register arrays */
177
178static void set_reg_bits(struct reg_pair_t *reg_pair, u8 reg, u8 mask, u8 val)
179{
180 unsigned int i = 0;
181
182 while (reg_pair[i].reg || reg_pair[i].val) {
183 if (reg_pair[i].reg == reg) {
184 reg_pair[i].val &= ~mask;
185 reg_pair[i].val |= val;
186 }
187 i++;
188
189 }
190 return;
191}
192
193static void copy_reg_bits(struct reg_pair_t *reg_pair1,
194 struct reg_pair_t *reg_pair2)
195{
196 unsigned int i, j;
197
198 i = j = 0;
199
200 while (reg_pair1[i].reg || reg_pair1[i].val) {
201 while (reg_pair2[j].reg || reg_pair2[j].val) {
202 if (reg_pair1[i].reg != reg_pair2[j].reg) {
203 j++;
204 continue;
205 }
206 reg_pair2[j].val = reg_pair1[i].val;
207 break;
208 }
209 i++;
210 }
211 return;
212}
213
214/* ------------------------------------------------------------------------- */
215
216static void mxl5007t_set_mode_bits(struct mxl5007t_state *state,
217 enum mxl5007t_mode mode,
218 s32 if_diff_out_level)
219{
220 switch (mode) {
221 case MxL_MODE_ATSC:
222 set_reg_bits(state->tab_init, 0x06, 0x1f, 0x12);
223 break;
224 case MxL_MODE_DVBT:
225 set_reg_bits(state->tab_init, 0x06, 0x1f, 0x11);
226 break;
227 case MxL_MODE_ISDBT:
228 set_reg_bits(state->tab_init, 0x06, 0x1f, 0x10);
229 break;
230 case MxL_MODE_CABLE:
231 set_reg_bits(state->tab_init_cable, 0x09, 0xff, 0xc1);
232 set_reg_bits(state->tab_init_cable, 0x0a, 0xff,
233 8 - if_diff_out_level);
234 set_reg_bits(state->tab_init_cable, 0x0b, 0xff, 0x17);
235 break;
236 default:
237 mxl_fail(-EINVAL);
238 }
239 return;
240}
241
242static void mxl5007t_set_if_freq_bits(struct mxl5007t_state *state,
243 enum mxl5007t_if_freq if_freq,
244 int invert_if)
245{
246 u8 val;
247
248 switch (if_freq) {
249 case MxL_IF_4_MHZ:
250 val = 0x00;
251 break;
252 case MxL_IF_4_5_MHZ:
253 val = 0x02;
254 break;
255 case MxL_IF_4_57_MHZ:
256 val = 0x03;
257 break;
258 case MxL_IF_5_MHZ:
259 val = 0x04;
260 break;
261 case MxL_IF_5_38_MHZ:
262 val = 0x05;
263 break;
264 case MxL_IF_6_MHZ:
265 val = 0x06;
266 break;
267 case MxL_IF_6_28_MHZ:
268 val = 0x07;
269 break;
270 case MxL_IF_9_1915_MHZ:
271 val = 0x08;
272 break;
273 case MxL_IF_35_25_MHZ:
274 val = 0x09;
275 break;
276 case MxL_IF_36_15_MHZ:
277 val = 0x0a;
278 break;
279 case MxL_IF_44_MHZ:
280 val = 0x0b;
281 break;
282 default:
283 mxl_fail(-EINVAL);
284 return;
285 }
286 set_reg_bits(state->tab_init, 0x02, 0x0f, val);
287
288 /* set inverted IF or normal IF */
289 set_reg_bits(state->tab_init, 0x02, 0x10, invert_if ? 0x10 : 0x00);
290
291 state->if_freq = if_freq;
292
293 return;
294}
295
296static void mxl5007t_set_xtal_freq_bits(struct mxl5007t_state *state,
297 enum mxl5007t_xtal_freq xtal_freq)
298{
299 switch (xtal_freq) {
300 case MxL_XTAL_16_MHZ:
301 /* select xtal freq & ref freq */
302 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x00);
303 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x00);
304 break;
305 case MxL_XTAL_20_MHZ:
306 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x10);
307 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x01);
308 break;
309 case MxL_XTAL_20_25_MHZ:
310 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x20);
311 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x02);
312 break;
313 case MxL_XTAL_20_48_MHZ:
314 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x30);
315 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x03);
316 break;
317 case MxL_XTAL_24_MHZ:
318 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x40);
319 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x04);
320 break;
321 case MxL_XTAL_25_MHZ:
322 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x50);
323 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x05);
324 break;
325 case MxL_XTAL_25_14_MHZ:
326 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x60);
327 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x06);
328 break;
329 case MxL_XTAL_27_MHZ:
330 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x70);
331 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x07);
332 break;
333 case MxL_XTAL_28_8_MHZ:
334 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x80);
335 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x08);
336 break;
337 case MxL_XTAL_32_MHZ:
338 set_reg_bits(state->tab_init, 0x03, 0xf0, 0x90);
339 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x09);
340 break;
341 case MxL_XTAL_40_MHZ:
342 set_reg_bits(state->tab_init, 0x03, 0xf0, 0xa0);
343 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0a);
344 break;
345 case MxL_XTAL_44_MHZ:
346 set_reg_bits(state->tab_init, 0x03, 0xf0, 0xb0);
347 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0b);
348 break;
349 case MxL_XTAL_48_MHZ:
350 set_reg_bits(state->tab_init, 0x03, 0xf0, 0xc0);
351 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0c);
352 break;
353 case MxL_XTAL_49_3811_MHZ:
354 set_reg_bits(state->tab_init, 0x03, 0xf0, 0xd0);
355 set_reg_bits(state->tab_init, 0x05, 0x0f, 0x0d);
356 break;
357 default:
358 mxl_fail(-EINVAL);
359 return;
360 }
361
362 return;
363}
364
365static struct reg_pair_t *mxl5007t_calc_init_regs(struct mxl5007t_state *state,
366 enum mxl5007t_mode mode)
367{
368 struct mxl5007t_config *cfg = state->config;
369
370 memcpy(&state->tab_init, &init_tab, sizeof(init_tab));
371 memcpy(&state->tab_init_cable, &init_tab_cable, sizeof(init_tab_cable));
372
373 mxl5007t_set_mode_bits(state, mode, cfg->if_diff_out_level);
374 mxl5007t_set_if_freq_bits(state, cfg->if_freq_hz, cfg->invert_if);
375 mxl5007t_set_xtal_freq_bits(state, cfg->xtal_freq_hz);
376
377 set_reg_bits(state->tab_init, 0x04, 0x01, cfg->loop_thru_enable);
378 set_reg_bits(state->tab_init, 0x03, 0x08, cfg->clk_out_enable << 3);
379 set_reg_bits(state->tab_init, 0x03, 0x07, cfg->clk_out_amp);
380
381 if (mode >= MxL_MODE_CABLE) {
382 copy_reg_bits(state->tab_init, state->tab_init_cable);
383 return state->tab_init_cable;
384 } else
385 return state->tab_init;
386}
387
388/* ------------------------------------------------------------------------- */
389
390enum mxl5007t_bw_mhz {
391 MxL_BW_6MHz = 6,
392 MxL_BW_7MHz = 7,
393 MxL_BW_8MHz = 8,
394};
395
396static void mxl5007t_set_bw_bits(struct mxl5007t_state *state,
397 enum mxl5007t_bw_mhz bw)
398{
399 u8 val;
400
401 switch (bw) {
402 case MxL_BW_6MHz:
403 val = 0x15; /* set DIG_MODEINDEX, DIG_MODEINDEX_A,
404 * and DIG_MODEINDEX_CSF */
405 break;
406 case MxL_BW_7MHz:
407 val = 0x2a;
408 break;
409 case MxL_BW_8MHz:
410 val = 0x3f;
411 break;
412 default:
413 mxl_fail(-EINVAL);
414 return;
415 }
416 set_reg_bits(state->tab_rftune, 0x0c, 0x3f, val);
417
418 return;
419}
420
421static struct
422reg_pair_t *mxl5007t_calc_rf_tune_regs(struct mxl5007t_state *state,
423 u32 rf_freq, enum mxl5007t_bw_mhz bw)
424{
425 u32 dig_rf_freq = 0;
426 u32 temp;
427 u32 frac_divider = 1000000;
428 unsigned int i;
429
430 memcpy(&state->tab_rftune, &reg_pair_rftune, sizeof(reg_pair_rftune));
431
432 mxl5007t_set_bw_bits(state, bw);
433
434 /* Convert RF frequency into 16 bits =>
435 * 10 bit integer (MHz) + 6 bit fraction */
436 dig_rf_freq = rf_freq / MHz;
437
438 temp = rf_freq % MHz;
439
440 for (i = 0; i < 6; i++) {
441 dig_rf_freq <<= 1;
442 frac_divider /= 2;
443 if (temp > frac_divider) {
444 temp -= frac_divider;
445 dig_rf_freq++;
446 }
447 }
448
449 /* add to have shift center point by 7.8124 kHz */
450 if (temp > 7812)
451 dig_rf_freq++;
452
453 set_reg_bits(state->tab_rftune, 0x0d, 0xff, (u8) dig_rf_freq);
454 set_reg_bits(state->tab_rftune, 0x0e, 0xff, (u8) (dig_rf_freq >> 8));
455
456 if (rf_freq >= 333000000)
457 set_reg_bits(state->tab_rftune, 0x80, 0x40, 0x40);
458
459 return state->tab_rftune;
460}
461
462/* ------------------------------------------------------------------------- */
463
464static int mxl5007t_write_reg(struct mxl5007t_state *state, u8 reg, u8 val)
465{
466 u8 buf[] = { reg, val };
467 struct i2c_msg msg = { .addr = state->i2c_props.addr, .flags = 0,
468 .buf = buf, .len = 2 };
469 int ret;
470
471 ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
472 if (ret != 1) {
473 mxl_err("failed!");
474 return -EREMOTEIO;
475 }
476 return 0;
477}
478
479static int mxl5007t_write_regs(struct mxl5007t_state *state,
480 struct reg_pair_t *reg_pair)
481{
482 unsigned int i = 0;
483 int ret = 0;
484
485 while ((ret == 0) && (reg_pair[i].reg || reg_pair[i].val)) {
486 ret = mxl5007t_write_reg(state,
487 reg_pair[i].reg, reg_pair[i].val);
488 i++;
489 }
490 return ret;
491}
492
493static int mxl5007t_read_reg(struct mxl5007t_state *state, u8 reg, u8 *val)
494{
495 u8 buf[2] = { 0xfb, reg };
496 struct i2c_msg msg[] = {
497 { .addr = state->i2c_props.addr, .flags = 0,
498 .buf = buf, .len = 2 },
499 { .addr = state->i2c_props.addr, .flags = I2C_M_RD,
500 .buf = val, .len = 1 },
501 };
502 int ret;
503
504 ret = i2c_transfer(state->i2c_props.adap, msg, 2);
505 if (ret != 2) {
506 mxl_err("failed!");
507 return -EREMOTEIO;
508 }
509 return 0;
510}
511
512static int mxl5007t_soft_reset(struct mxl5007t_state *state)
513{
514 u8 d = 0xff;
515 struct i2c_msg msg = {
516 .addr = state->i2c_props.addr, .flags = 0,
517 .buf = &d, .len = 1
518 };
519 int ret = i2c_transfer(state->i2c_props.adap, &msg, 1);
520
521 if (ret != 1) {
522 mxl_err("failed!");
523 return -EREMOTEIO;
524 }
525 return 0;
526}
527
528static int mxl5007t_tuner_init(struct mxl5007t_state *state,
529 enum mxl5007t_mode mode)
530{
531 struct reg_pair_t *init_regs;
532 int ret;
533
534 ret = mxl5007t_soft_reset(state);
535 if (mxl_fail(ret))
536 goto fail;
537
538 /* calculate initialization reg array */
539 init_regs = mxl5007t_calc_init_regs(state, mode);
540
541 ret = mxl5007t_write_regs(state, init_regs);
542 if (mxl_fail(ret))
543 goto fail;
544 mdelay(1);
545fail:
546 return ret;
547}
548
549static int mxl5007t_tuner_rf_tune(struct mxl5007t_state *state, u32 rf_freq_hz,
550 enum mxl5007t_bw_mhz bw)
551{
552 struct reg_pair_t *rf_tune_regs;
553 int ret;
554
555 /* calculate channel change reg array */
556 rf_tune_regs = mxl5007t_calc_rf_tune_regs(state, rf_freq_hz, bw);
557
558 ret = mxl5007t_write_regs(state, rf_tune_regs);
559 if (mxl_fail(ret))
560 goto fail;
561 msleep(3);
562fail:
563 return ret;
564}
565
566/* ------------------------------------------------------------------------- */
567
568static int mxl5007t_synth_lock_status(struct mxl5007t_state *state,
569 int *rf_locked, int *ref_locked)
570{
571 u8 d;
572 int ret;
573
574 *rf_locked = 0;
575 *ref_locked = 0;
576
577 ret = mxl5007t_read_reg(state, 0xd8, &d);
578 if (mxl_fail(ret))
579 goto fail;
580
581 if ((d & 0x0c) == 0x0c)
582 *rf_locked = 1;
583
584 if ((d & 0x03) == 0x03)
585 *ref_locked = 1;
586fail:
587 return ret;
588}
589
590/* ------------------------------------------------------------------------- */
591
592static int mxl5007t_get_status(struct dvb_frontend *fe, u32 *status)
593{
594 struct mxl5007t_state *state = fe->tuner_priv;
595 int rf_locked, ref_locked, ret;
596
597 *status = 0;
598
599 if (fe->ops.i2c_gate_ctrl)
600 fe->ops.i2c_gate_ctrl(fe, 1);
601
602 ret = mxl5007t_synth_lock_status(state, &rf_locked, &ref_locked);
603 if (mxl_fail(ret))
604 goto fail;
605 mxl_debug("%s%s", rf_locked ? "rf locked " : "",
606 ref_locked ? "ref locked" : "");
607
608 if ((rf_locked) || (ref_locked))
609 *status |= TUNER_STATUS_LOCKED;
610fail:
611 if (fe->ops.i2c_gate_ctrl)
612 fe->ops.i2c_gate_ctrl(fe, 0);
613
614 return ret;
615}
616
617/* ------------------------------------------------------------------------- */
618
619static int mxl5007t_set_params(struct dvb_frontend *fe)
620{
621 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
622 u32 delsys = c->delivery_system;
623 struct mxl5007t_state *state = fe->tuner_priv;
624 enum mxl5007t_bw_mhz bw;
625 enum mxl5007t_mode mode;
626 int ret;
627 u32 freq = c->frequency;
628
629 switch (delsys) {
630 case SYS_ATSC:
631 mode = MxL_MODE_ATSC;
632 bw = MxL_BW_6MHz;
633 break;
634 case SYS_DVBC_ANNEX_B:
635 mode = MxL_MODE_CABLE;
636 bw = MxL_BW_6MHz;
637 break;
638 case SYS_DVBT:
639 case SYS_DVBT2:
640 mode = MxL_MODE_DVBT;
641 switch (c->bandwidth_hz) {
642 case 6000000:
643 bw = MxL_BW_6MHz;
644 break;
645 case 7000000:
646 bw = MxL_BW_7MHz;
647 break;
648 case 8000000:
649 bw = MxL_BW_8MHz;
650 break;
651 default:
652 return -EINVAL;
653 }
654 break;
655 default:
656 mxl_err("modulation type not supported!");
657 return -EINVAL;
658 }
659
660 if (fe->ops.i2c_gate_ctrl)
661 fe->ops.i2c_gate_ctrl(fe, 1);
662
663 mutex_lock(&state->lock);
664
665 ret = mxl5007t_tuner_init(state, mode);
666 if (mxl_fail(ret))
667 goto fail;
668
669 ret = mxl5007t_tuner_rf_tune(state, freq, bw);
670 if (mxl_fail(ret))
671 goto fail;
672
673 state->frequency = freq;
674 state->bandwidth = c->bandwidth_hz;
675fail:
676 mutex_unlock(&state->lock);
677
678 if (fe->ops.i2c_gate_ctrl)
679 fe->ops.i2c_gate_ctrl(fe, 0);
680
681 return ret;
682}
683
684/* ------------------------------------------------------------------------- */
685
686static int mxl5007t_init(struct dvb_frontend *fe)
687{
688 struct mxl5007t_state *state = fe->tuner_priv;
689 int ret;
690
691 if (fe->ops.i2c_gate_ctrl)
692 fe->ops.i2c_gate_ctrl(fe, 1);
693
694 /* wake from standby */
695 ret = mxl5007t_write_reg(state, 0x01, 0x01);
696 mxl_fail(ret);
697
698 if (fe->ops.i2c_gate_ctrl)
699 fe->ops.i2c_gate_ctrl(fe, 0);
700
701 return ret;
702}
703
704static int mxl5007t_sleep(struct dvb_frontend *fe)
705{
706 struct mxl5007t_state *state = fe->tuner_priv;
707 int ret;
708
709 if (fe->ops.i2c_gate_ctrl)
710 fe->ops.i2c_gate_ctrl(fe, 1);
711
712 /* enter standby mode */
713 ret = mxl5007t_write_reg(state, 0x01, 0x00);
714 mxl_fail(ret);
715 ret = mxl5007t_write_reg(state, 0x0f, 0x00);
716 mxl_fail(ret);
717
718 if (fe->ops.i2c_gate_ctrl)
719 fe->ops.i2c_gate_ctrl(fe, 0);
720
721 return ret;
722}
723
724/* ------------------------------------------------------------------------- */
725
726static int mxl5007t_get_frequency(struct dvb_frontend *fe, u32 *frequency)
727{
728 struct mxl5007t_state *state = fe->tuner_priv;
729 *frequency = state->frequency;
730 return 0;
731}
732
733static int mxl5007t_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
734{
735 struct mxl5007t_state *state = fe->tuner_priv;
736 *bandwidth = state->bandwidth;
737 return 0;
738}
739
740static int mxl5007t_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
741{
742 struct mxl5007t_state *state = fe->tuner_priv;
743
744 *frequency = 0;
745
746 switch (state->if_freq) {
747 case MxL_IF_4_MHZ:
748 *frequency = 4000000;
749 break;
750 case MxL_IF_4_5_MHZ:
751 *frequency = 4500000;
752 break;
753 case MxL_IF_4_57_MHZ:
754 *frequency = 4570000;
755 break;
756 case MxL_IF_5_MHZ:
757 *frequency = 5000000;
758 break;
759 case MxL_IF_5_38_MHZ:
760 *frequency = 5380000;
761 break;
762 case MxL_IF_6_MHZ:
763 *frequency = 6000000;
764 break;
765 case MxL_IF_6_28_MHZ:
766 *frequency = 6280000;
767 break;
768 case MxL_IF_9_1915_MHZ:
769 *frequency = 9191500;
770 break;
771 case MxL_IF_35_25_MHZ:
772 *frequency = 35250000;
773 break;
774 case MxL_IF_36_15_MHZ:
775 *frequency = 36150000;
776 break;
777 case MxL_IF_44_MHZ:
778 *frequency = 44000000;
779 break;
780 }
781 return 0;
782}
783
784static int mxl5007t_release(struct dvb_frontend *fe)
785{
786 struct mxl5007t_state *state = fe->tuner_priv;
787
788 mutex_lock(&mxl5007t_list_mutex);
789
790 if (state)
791 hybrid_tuner_release_state(state);
792
793 mutex_unlock(&mxl5007t_list_mutex);
794
795 fe->tuner_priv = NULL;
796
797 return 0;
798}
799
800/* ------------------------------------------------------------------------- */
801
802static struct dvb_tuner_ops mxl5007t_tuner_ops = {
803 .info = {
804 .name = "MaxLinear MxL5007T",
805 },
806 .init = mxl5007t_init,
807 .sleep = mxl5007t_sleep,
808 .set_params = mxl5007t_set_params,
809 .get_status = mxl5007t_get_status,
810 .get_frequency = mxl5007t_get_frequency,
811 .get_bandwidth = mxl5007t_get_bandwidth,
812 .release = mxl5007t_release,
813 .get_if_frequency = mxl5007t_get_if_frequency,
814};
815
816static int mxl5007t_get_chip_id(struct mxl5007t_state *state)
817{
818 char *name;
819 int ret;
820 u8 id;
821
822 ret = mxl5007t_read_reg(state, 0xd9, &id);
823 if (mxl_fail(ret))
824 goto fail;
825
826 switch (id) {
827 case MxL_5007_V1_F1:
828 name = "MxL5007.v1.f1";
829 break;
830 case MxL_5007_V1_F2:
831 name = "MxL5007.v1.f2";
832 break;
833 case MxL_5007_V2_100_F1:
834 name = "MxL5007.v2.100.f1";
835 break;
836 case MxL_5007_V2_100_F2:
837 name = "MxL5007.v2.100.f2";
838 break;
839 case MxL_5007_V2_200_F1:
840 name = "MxL5007.v2.200.f1";
841 break;
842 case MxL_5007_V2_200_F2:
843 name = "MxL5007.v2.200.f2";
844 break;
845 case MxL_5007_V4:
846 name = "MxL5007T.v4";
847 break;
848 default:
849 name = "MxL5007T";
850 printk(KERN_WARNING "%s: unknown rev (%02x)\n", __func__, id);
851 id = MxL_UNKNOWN_ID;
852 }
853 state->chip_id = id;
854 mxl_info("%s detected @ %d-%04x", name,
855 i2c_adapter_id(state->i2c_props.adap),
856 state->i2c_props.addr);
857 return 0;
858fail:
859 mxl_warn("unable to identify device @ %d-%04x",
860 i2c_adapter_id(state->i2c_props.adap),
861 state->i2c_props.addr);
862
863 state->chip_id = MxL_UNKNOWN_ID;
864 return ret;
865}
866
867struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
868 struct i2c_adapter *i2c, u8 addr,
869 struct mxl5007t_config *cfg)
870{
871 struct mxl5007t_state *state = NULL;
872 int instance, ret;
873
874 mutex_lock(&mxl5007t_list_mutex);
875 instance = hybrid_tuner_request_state(struct mxl5007t_state, state,
876 hybrid_tuner_instance_list,
877 i2c, addr, "mxl5007t");
878 switch (instance) {
879 case 0:
880 goto fail;
881 case 1:
882 /* new tuner instance */
883 state->config = cfg;
884
885 mutex_init(&state->lock);
886
887 if (fe->ops.i2c_gate_ctrl)
888 fe->ops.i2c_gate_ctrl(fe, 1);
889
890 ret = mxl5007t_get_chip_id(state);
891
892 if (fe->ops.i2c_gate_ctrl)
893 fe->ops.i2c_gate_ctrl(fe, 0);
894
895 /* check return value of mxl5007t_get_chip_id */
896 if (mxl_fail(ret))
897 goto fail;
898 break;
899 default:
900 /* existing tuner instance */
901 break;
902 }
903 fe->tuner_priv = state;
904 mutex_unlock(&mxl5007t_list_mutex);
905
906 memcpy(&fe->ops.tuner_ops, &mxl5007t_tuner_ops,
907 sizeof(struct dvb_tuner_ops));
908
909 return fe;
910fail:
911 mutex_unlock(&mxl5007t_list_mutex);
912
913 mxl5007t_release(fe);
914 return NULL;
915}
916EXPORT_SYMBOL_GPL(mxl5007t_attach);
917MODULE_DESCRIPTION("MaxLinear MxL5007T Silicon IC tuner driver");
918MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
919MODULE_LICENSE("GPL");
920MODULE_VERSION("0.2");
921
922/*
923 * Overrides for Emacs so that we follow Linus's tabbing style.
924 * ---------------------------------------------------------------------------
925 * Local variables:
926 * c-basic-offset: 8
927 * End:
928 */
diff --git a/drivers/media/tuners/mxl5007t.h b/drivers/media/tuners/mxl5007t.h
new file mode 100644
index 000000000000..aa3eea0b5262
--- /dev/null
+++ b/drivers/media/tuners/mxl5007t.h
@@ -0,0 +1,104 @@
1/*
2 * mxl5007t.h - driver for the MaxLinear MxL5007T silicon tuner
3 *
4 * Copyright (C) 2008 Michael Krufky <mkrufky@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef __MXL5007T_H__
22#define __MXL5007T_H__
23
24#include "dvb_frontend.h"
25
26/* ------------------------------------------------------------------------- */
27
28enum mxl5007t_if_freq {
29 MxL_IF_4_MHZ, /* 4000000 */
30 MxL_IF_4_5_MHZ, /* 4500000 */
31 MxL_IF_4_57_MHZ, /* 4570000 */
32 MxL_IF_5_MHZ, /* 5000000 */
33 MxL_IF_5_38_MHZ, /* 5380000 */
34 MxL_IF_6_MHZ, /* 6000000 */
35 MxL_IF_6_28_MHZ, /* 6280000 */
36 MxL_IF_9_1915_MHZ, /* 9191500 */
37 MxL_IF_35_25_MHZ, /* 35250000 */
38 MxL_IF_36_15_MHZ, /* 36150000 */
39 MxL_IF_44_MHZ, /* 44000000 */
40};
41
42enum mxl5007t_xtal_freq {
43 MxL_XTAL_16_MHZ, /* 16000000 */
44 MxL_XTAL_20_MHZ, /* 20000000 */
45 MxL_XTAL_20_25_MHZ, /* 20250000 */
46 MxL_XTAL_20_48_MHZ, /* 20480000 */
47 MxL_XTAL_24_MHZ, /* 24000000 */
48 MxL_XTAL_25_MHZ, /* 25000000 */
49 MxL_XTAL_25_14_MHZ, /* 25140000 */
50 MxL_XTAL_27_MHZ, /* 27000000 */
51 MxL_XTAL_28_8_MHZ, /* 28800000 */
52 MxL_XTAL_32_MHZ, /* 32000000 */
53 MxL_XTAL_40_MHZ, /* 40000000 */
54 MxL_XTAL_44_MHZ, /* 44000000 */
55 MxL_XTAL_48_MHZ, /* 48000000 */
56 MxL_XTAL_49_3811_MHZ, /* 49381100 */
57};
58
59enum mxl5007t_clkout_amp {
60 MxL_CLKOUT_AMP_0_94V = 0,
61 MxL_CLKOUT_AMP_0_53V = 1,
62 MxL_CLKOUT_AMP_0_37V = 2,
63 MxL_CLKOUT_AMP_0_28V = 3,
64 MxL_CLKOUT_AMP_0_23V = 4,
65 MxL_CLKOUT_AMP_0_20V = 5,
66 MxL_CLKOUT_AMP_0_17V = 6,
67 MxL_CLKOUT_AMP_0_15V = 7,
68};
69
70struct mxl5007t_config {
71 s32 if_diff_out_level;
72 enum mxl5007t_clkout_amp clk_out_amp;
73 enum mxl5007t_xtal_freq xtal_freq_hz;
74 enum mxl5007t_if_freq if_freq_hz;
75 unsigned int invert_if:1;
76 unsigned int loop_thru_enable:1;
77 unsigned int clk_out_enable:1;
78};
79
80#if defined(CONFIG_MEDIA_TUNER_MXL5007T) || (defined(CONFIG_MEDIA_TUNER_MXL5007T_MODULE) && defined(MODULE))
81extern struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
82 struct i2c_adapter *i2c, u8 addr,
83 struct mxl5007t_config *cfg);
84#else
85static inline struct dvb_frontend *mxl5007t_attach(struct dvb_frontend *fe,
86 struct i2c_adapter *i2c,
87 u8 addr,
88 struct mxl5007t_config *cfg)
89{
90 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
91 return NULL;
92}
93#endif
94
95#endif /* __MXL5007T_H__ */
96
97/*
98 * Overrides for Emacs so that we follow Linus's tabbing style.
99 * ---------------------------------------------------------------------------
100 * Local variables:
101 * c-basic-offset: 8
102 * End:
103 */
104
diff --git a/drivers/media/tuners/qt1010.c b/drivers/media/tuners/qt1010.c
new file mode 100644
index 000000000000..bdc39e11030e
--- /dev/null
+++ b/drivers/media/tuners/qt1010.c
@@ -0,0 +1,480 @@
1/*
2 * Driver for Quantek QT1010 silicon tuner
3 *
4 * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
5 * Aapo Tahkola <aet@rasterburn.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21#include "qt1010.h"
22#include "qt1010_priv.h"
23
24static int debug;
25module_param(debug, int, 0644);
26MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
27
28#define dprintk(args...) \
29 do { \
30 if (debug) printk(KERN_DEBUG "QT1010: " args); \
31 } while (0)
32
33/* read single register */
34static int qt1010_readreg(struct qt1010_priv *priv, u8 reg, u8 *val)
35{
36 struct i2c_msg msg[2] = {
37 { .addr = priv->cfg->i2c_address,
38 .flags = 0, .buf = &reg, .len = 1 },
39 { .addr = priv->cfg->i2c_address,
40 .flags = I2C_M_RD, .buf = val, .len = 1 },
41 };
42
43 if (i2c_transfer(priv->i2c, msg, 2) != 2) {
44 printk(KERN_WARNING "qt1010 I2C read failed\n");
45 return -EREMOTEIO;
46 }
47 return 0;
48}
49
50/* write single register */
51static int qt1010_writereg(struct qt1010_priv *priv, u8 reg, u8 val)
52{
53 u8 buf[2] = { reg, val };
54 struct i2c_msg msg = { .addr = priv->cfg->i2c_address,
55 .flags = 0, .buf = buf, .len = 2 };
56
57 if (i2c_transfer(priv->i2c, &msg, 1) != 1) {
58 printk(KERN_WARNING "qt1010 I2C write failed\n");
59 return -EREMOTEIO;
60 }
61 return 0;
62}
63
64/* dump all registers */
65static void qt1010_dump_regs(struct qt1010_priv *priv)
66{
67 u8 reg, val;
68
69 for (reg = 0; ; reg++) {
70 if (reg % 16 == 0) {
71 if (reg)
72 printk(KERN_CONT "\n");
73 printk(KERN_DEBUG "%02x:", reg);
74 }
75 if (qt1010_readreg(priv, reg, &val) == 0)
76 printk(KERN_CONT " %02x", val);
77 else
78 printk(KERN_CONT " --");
79 if (reg == 0x2f)
80 break;
81 }
82 printk(KERN_CONT "\n");
83}
84
85static int qt1010_set_params(struct dvb_frontend *fe)
86{
87 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
88 struct qt1010_priv *priv;
89 int err;
90 u32 freq, div, mod1, mod2;
91 u8 i, tmpval, reg05;
92 qt1010_i2c_oper_t rd[48] = {
93 { QT1010_WR, 0x01, 0x80 },
94 { QT1010_WR, 0x02, 0x3f },
95 { QT1010_WR, 0x05, 0xff }, /* 02 c write */
96 { QT1010_WR, 0x06, 0x44 },
97 { QT1010_WR, 0x07, 0xff }, /* 04 c write */
98 { QT1010_WR, 0x08, 0x08 },
99 { QT1010_WR, 0x09, 0xff }, /* 06 c write */
100 { QT1010_WR, 0x0a, 0xff }, /* 07 c write */
101 { QT1010_WR, 0x0b, 0xff }, /* 08 c write */
102 { QT1010_WR, 0x0c, 0xe1 },
103 { QT1010_WR, 0x1a, 0xff }, /* 10 c write */
104 { QT1010_WR, 0x1b, 0x00 },
105 { QT1010_WR, 0x1c, 0x89 },
106 { QT1010_WR, 0x11, 0xff }, /* 13 c write */
107 { QT1010_WR, 0x12, 0xff }, /* 14 c write */
108 { QT1010_WR, 0x22, 0xff }, /* 15 c write */
109 { QT1010_WR, 0x1e, 0x00 },
110 { QT1010_WR, 0x1e, 0xd0 },
111 { QT1010_RD, 0x22, 0xff }, /* 16 c read */
112 { QT1010_WR, 0x1e, 0x00 },
113 { QT1010_RD, 0x05, 0xff }, /* 20 c read */
114 { QT1010_RD, 0x22, 0xff }, /* 21 c read */
115 { QT1010_WR, 0x23, 0xd0 },
116 { QT1010_WR, 0x1e, 0x00 },
117 { QT1010_WR, 0x1e, 0xe0 },
118 { QT1010_RD, 0x23, 0xff }, /* 25 c read */
119 { QT1010_RD, 0x23, 0xff }, /* 26 c read */
120 { QT1010_WR, 0x1e, 0x00 },
121 { QT1010_WR, 0x24, 0xd0 },
122 { QT1010_WR, 0x1e, 0x00 },
123 { QT1010_WR, 0x1e, 0xf0 },
124 { QT1010_RD, 0x24, 0xff }, /* 31 c read */
125 { QT1010_WR, 0x1e, 0x00 },
126 { QT1010_WR, 0x14, 0x7f },
127 { QT1010_WR, 0x15, 0x7f },
128 { QT1010_WR, 0x05, 0xff }, /* 35 c write */
129 { QT1010_WR, 0x06, 0x00 },
130 { QT1010_WR, 0x15, 0x1f },
131 { QT1010_WR, 0x16, 0xff },
132 { QT1010_WR, 0x18, 0xff },
133 { QT1010_WR, 0x1f, 0xff }, /* 40 c write */
134 { QT1010_WR, 0x20, 0xff }, /* 41 c write */
135 { QT1010_WR, 0x21, 0x53 },
136 { QT1010_WR, 0x25, 0xff }, /* 43 c write */
137 { QT1010_WR, 0x26, 0x15 },
138 { QT1010_WR, 0x00, 0xff }, /* 45 c write */
139 { QT1010_WR, 0x02, 0x00 },
140 { QT1010_WR, 0x01, 0x00 }
141 };
142
143#define FREQ1 32000000 /* 32 MHz */
144#define FREQ2 4000000 /* 4 MHz Quartz oscillator in the stick? */
145
146 priv = fe->tuner_priv;
147 freq = c->frequency;
148 div = (freq + QT1010_OFFSET) / QT1010_STEP;
149 freq = (div * QT1010_STEP) - QT1010_OFFSET;
150 mod1 = (freq + QT1010_OFFSET) % FREQ1;
151 mod2 = (freq + QT1010_OFFSET) % FREQ2;
152 priv->frequency = freq;
153
154 if (fe->ops.i2c_gate_ctrl)
155 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
156
157 /* reg 05 base value */
158 if (freq < 290000000) reg05 = 0x14; /* 290 MHz */
159 else if (freq < 610000000) reg05 = 0x34; /* 610 MHz */
160 else if (freq < 802000000) reg05 = 0x54; /* 802 MHz */
161 else reg05 = 0x74;
162
163 /* 0x5 */
164 rd[2].val = reg05;
165
166 /* 07 - set frequency: 32 MHz scale */
167 rd[4].val = (freq + QT1010_OFFSET) / FREQ1;
168
169 /* 09 - changes every 8/24 MHz */
170 if (mod1 < 8000000) rd[6].val = 0x1d;
171 else rd[6].val = 0x1c;
172
173 /* 0a - set frequency: 4 MHz scale (max 28 MHz) */
174 if (mod1 < 1*FREQ2) rd[7].val = 0x09; /* +0 MHz */
175 else if (mod1 < 2*FREQ2) rd[7].val = 0x08; /* +4 MHz */
176 else if (mod1 < 3*FREQ2) rd[7].val = 0x0f; /* +8 MHz */
177 else if (mod1 < 4*FREQ2) rd[7].val = 0x0e; /* +12 MHz */
178 else if (mod1 < 5*FREQ2) rd[7].val = 0x0d; /* +16 MHz */
179 else if (mod1 < 6*FREQ2) rd[7].val = 0x0c; /* +20 MHz */
180 else if (mod1 < 7*FREQ2) rd[7].val = 0x0b; /* +24 MHz */
181 else rd[7].val = 0x0a; /* +28 MHz */
182
183 /* 0b - changes every 2/2 MHz */
184 if (mod2 < 2000000) rd[8].val = 0x45;
185 else rd[8].val = 0x44;
186
187 /* 1a - set frequency: 125 kHz scale (max 3875 kHz)*/
188 tmpval = 0x78; /* byte, overflows intentionally */
189 rd[10].val = tmpval-((mod2/QT1010_STEP)*0x08);
190
191 /* 11 */
192 rd[13].val = 0xfd; /* TODO: correct value calculation */
193
194 /* 12 */
195 rd[14].val = 0x91; /* TODO: correct value calculation */
196
197 /* 22 */
198 if (freq < 450000000) rd[15].val = 0xd0; /* 450 MHz */
199 else if (freq < 482000000) rd[15].val = 0xd1; /* 482 MHz */
200 else if (freq < 514000000) rd[15].val = 0xd4; /* 514 MHz */
201 else if (freq < 546000000) rd[15].val = 0xd7; /* 546 MHz */
202 else if (freq < 610000000) rd[15].val = 0xda; /* 610 MHz */
203 else rd[15].val = 0xd0;
204
205 /* 05 */
206 rd[35].val = (reg05 & 0xf0);
207
208 /* 1f */
209 if (mod1 < 8000000) tmpval = 0x00;
210 else if (mod1 < 12000000) tmpval = 0x01;
211 else if (mod1 < 16000000) tmpval = 0x02;
212 else if (mod1 < 24000000) tmpval = 0x03;
213 else if (mod1 < 28000000) tmpval = 0x04;
214 else tmpval = 0x05;
215 rd[40].val = (priv->reg1f_init_val + 0x0e + tmpval);
216
217 /* 20 */
218 if (mod1 < 8000000) tmpval = 0x00;
219 else if (mod1 < 12000000) tmpval = 0x01;
220 else if (mod1 < 20000000) tmpval = 0x02;
221 else if (mod1 < 24000000) tmpval = 0x03;
222 else if (mod1 < 28000000) tmpval = 0x04;
223 else tmpval = 0x05;
224 rd[41].val = (priv->reg20_init_val + 0x0d + tmpval);
225
226 /* 25 */
227 rd[43].val = priv->reg25_init_val;
228
229 /* 00 */
230 rd[45].val = 0x92; /* TODO: correct value calculation */
231
232 dprintk("freq:%u 05:%02x 07:%02x 09:%02x 0a:%02x 0b:%02x " \
233 "1a:%02x 11:%02x 12:%02x 22:%02x 05:%02x 1f:%02x " \
234 "20:%02x 25:%02x 00:%02x", \
235 freq, rd[2].val, rd[4].val, rd[6].val, rd[7].val, rd[8].val, \
236 rd[10].val, rd[13].val, rd[14].val, rd[15].val, rd[35].val, \
237 rd[40].val, rd[41].val, rd[43].val, rd[45].val);
238
239 for (i = 0; i < ARRAY_SIZE(rd); i++) {
240 if (rd[i].oper == QT1010_WR) {
241 err = qt1010_writereg(priv, rd[i].reg, rd[i].val);
242 } else { /* read is required to proper locking */
243 err = qt1010_readreg(priv, rd[i].reg, &tmpval);
244 }
245 if (err) return err;
246 }
247
248 if (debug)
249 qt1010_dump_regs(priv);
250
251 if (fe->ops.i2c_gate_ctrl)
252 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
253
254 return 0;
255}
256
257static int qt1010_init_meas1(struct qt1010_priv *priv,
258 u8 oper, u8 reg, u8 reg_init_val, u8 *retval)
259{
260 u8 i, val1, val2;
261 int err;
262
263 qt1010_i2c_oper_t i2c_data[] = {
264 { QT1010_WR, reg, reg_init_val },
265 { QT1010_WR, 0x1e, 0x00 },
266 { QT1010_WR, 0x1e, oper },
267 { QT1010_RD, reg, 0xff }
268 };
269
270 for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
271 if (i2c_data[i].oper == QT1010_WR) {
272 err = qt1010_writereg(priv, i2c_data[i].reg,
273 i2c_data[i].val);
274 } else {
275 err = qt1010_readreg(priv, i2c_data[i].reg, &val2);
276 }
277 if (err) return err;
278 }
279
280 do {
281 val1 = val2;
282 err = qt1010_readreg(priv, reg, &val2);
283 if (err) return err;
284 dprintk("compare reg:%02x %02x %02x", reg, val1, val2);
285 } while (val1 != val2);
286 *retval = val1;
287
288 return qt1010_writereg(priv, 0x1e, 0x00);
289}
290
291static int qt1010_init_meas2(struct qt1010_priv *priv,
292 u8 reg_init_val, u8 *retval)
293{
294 u8 i, val;
295 int err;
296 qt1010_i2c_oper_t i2c_data[] = {
297 { QT1010_WR, 0x07, reg_init_val },
298 { QT1010_WR, 0x22, 0xd0 },
299 { QT1010_WR, 0x1e, 0x00 },
300 { QT1010_WR, 0x1e, 0xd0 },
301 { QT1010_RD, 0x22, 0xff },
302 { QT1010_WR, 0x1e, 0x00 },
303 { QT1010_WR, 0x22, 0xff }
304 };
305 for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
306 if (i2c_data[i].oper == QT1010_WR) {
307 err = qt1010_writereg(priv, i2c_data[i].reg,
308 i2c_data[i].val);
309 } else {
310 err = qt1010_readreg(priv, i2c_data[i].reg, &val);
311 }
312 if (err) return err;
313 }
314 *retval = val;
315 return 0;
316}
317
318static int qt1010_init(struct dvb_frontend *fe)
319{
320 struct qt1010_priv *priv = fe->tuner_priv;
321 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
322 int err = 0;
323 u8 i, tmpval, *valptr = NULL;
324
325 qt1010_i2c_oper_t i2c_data[] = {
326 { QT1010_WR, 0x01, 0x80 },
327 { QT1010_WR, 0x0d, 0x84 },
328 { QT1010_WR, 0x0e, 0xb7 },
329 { QT1010_WR, 0x2a, 0x23 },
330 { QT1010_WR, 0x2c, 0xdc },
331 { QT1010_M1, 0x25, 0x40 }, /* get reg 25 init value */
332 { QT1010_M1, 0x81, 0xff }, /* get reg 25 init value */
333 { QT1010_WR, 0x2b, 0x70 },
334 { QT1010_WR, 0x2a, 0x23 },
335 { QT1010_M1, 0x26, 0x08 },
336 { QT1010_M1, 0x82, 0xff },
337 { QT1010_WR, 0x05, 0x14 },
338 { QT1010_WR, 0x06, 0x44 },
339 { QT1010_WR, 0x07, 0x28 },
340 { QT1010_WR, 0x08, 0x0b },
341 { QT1010_WR, 0x11, 0xfd },
342 { QT1010_M1, 0x22, 0x0d },
343 { QT1010_M1, 0xd0, 0xff },
344 { QT1010_WR, 0x06, 0x40 },
345 { QT1010_WR, 0x16, 0xf0 },
346 { QT1010_WR, 0x02, 0x38 },
347 { QT1010_WR, 0x03, 0x18 },
348 { QT1010_WR, 0x20, 0xe0 },
349 { QT1010_M1, 0x1f, 0x20 }, /* get reg 1f init value */
350 { QT1010_M1, 0x84, 0xff }, /* get reg 1f init value */
351 { QT1010_RD, 0x20, 0x20 }, /* get reg 20 init value */
352 { QT1010_WR, 0x03, 0x19 },
353 { QT1010_WR, 0x02, 0x3f },
354 { QT1010_WR, 0x21, 0x53 },
355 { QT1010_RD, 0x21, 0xff },
356 { QT1010_WR, 0x11, 0xfd },
357 { QT1010_WR, 0x05, 0x34 },
358 { QT1010_WR, 0x06, 0x44 },
359 { QT1010_WR, 0x08, 0x08 }
360 };
361
362 if (fe->ops.i2c_gate_ctrl)
363 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
364
365 for (i = 0; i < ARRAY_SIZE(i2c_data); i++) {
366 switch (i2c_data[i].oper) {
367 case QT1010_WR:
368 err = qt1010_writereg(priv, i2c_data[i].reg,
369 i2c_data[i].val);
370 break;
371 case QT1010_RD:
372 if (i2c_data[i].val == 0x20)
373 valptr = &priv->reg20_init_val;
374 else
375 valptr = &tmpval;
376 err = qt1010_readreg(priv, i2c_data[i].reg, valptr);
377 break;
378 case QT1010_M1:
379 if (i2c_data[i].val == 0x25)
380 valptr = &priv->reg25_init_val;
381 else if (i2c_data[i].val == 0x1f)
382 valptr = &priv->reg1f_init_val;
383 else
384 valptr = &tmpval;
385 err = qt1010_init_meas1(priv, i2c_data[i+1].reg,
386 i2c_data[i].reg,
387 i2c_data[i].val, valptr);
388 i++;
389 break;
390 }
391 if (err) return err;
392 }
393
394 for (i = 0x31; i < 0x3a; i++) /* 0x31 - 0x39 */
395 if ((err = qt1010_init_meas2(priv, i, &tmpval)))
396 return err;
397
398 c->frequency = 545000000; /* Sigmatek DVB-110 545000000 */
399 /* MSI Megasky 580 GL861 533000000 */
400 return qt1010_set_params(fe);
401}
402
403static int qt1010_release(struct dvb_frontend *fe)
404{
405 kfree(fe->tuner_priv);
406 fe->tuner_priv = NULL;
407 return 0;
408}
409
410static int qt1010_get_frequency(struct dvb_frontend *fe, u32 *frequency)
411{
412 struct qt1010_priv *priv = fe->tuner_priv;
413 *frequency = priv->frequency;
414 return 0;
415}
416
417static int qt1010_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
418{
419 *frequency = 36125000;
420 return 0;
421}
422
423static const struct dvb_tuner_ops qt1010_tuner_ops = {
424 .info = {
425 .name = "Quantek QT1010",
426 .frequency_min = QT1010_MIN_FREQ,
427 .frequency_max = QT1010_MAX_FREQ,
428 .frequency_step = QT1010_STEP,
429 },
430
431 .release = qt1010_release,
432 .init = qt1010_init,
433 /* TODO: implement sleep */
434
435 .set_params = qt1010_set_params,
436 .get_frequency = qt1010_get_frequency,
437 .get_if_frequency = qt1010_get_if_frequency,
438};
439
440struct dvb_frontend * qt1010_attach(struct dvb_frontend *fe,
441 struct i2c_adapter *i2c,
442 struct qt1010_config *cfg)
443{
444 struct qt1010_priv *priv = NULL;
445 u8 id;
446
447 priv = kzalloc(sizeof(struct qt1010_priv), GFP_KERNEL);
448 if (priv == NULL)
449 return NULL;
450
451 priv->cfg = cfg;
452 priv->i2c = i2c;
453
454 if (fe->ops.i2c_gate_ctrl)
455 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c_gate */
456
457
458 /* Try to detect tuner chip. Probably this is not correct register. */
459 if (qt1010_readreg(priv, 0x29, &id) != 0 || (id != 0x39)) {
460 kfree(priv);
461 return NULL;
462 }
463
464 if (fe->ops.i2c_gate_ctrl)
465 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c_gate */
466
467 printk(KERN_INFO "Quantek QT1010 successfully identified.\n");
468 memcpy(&fe->ops.tuner_ops, &qt1010_tuner_ops,
469 sizeof(struct dvb_tuner_ops));
470
471 fe->tuner_priv = priv;
472 return fe;
473}
474EXPORT_SYMBOL(qt1010_attach);
475
476MODULE_DESCRIPTION("Quantek QT1010 silicon tuner driver");
477MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
478MODULE_AUTHOR("Aapo Tahkola <aet@rasterburn.org>");
479MODULE_VERSION("0.1");
480MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/qt1010.h b/drivers/media/tuners/qt1010.h
new file mode 100644
index 000000000000..807fb7b6146b
--- /dev/null
+++ b/drivers/media/tuners/qt1010.h
@@ -0,0 +1,53 @@
1/*
2 * Driver for Quantek QT1010 silicon tuner
3 *
4 * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
5 * Aapo Tahkola <aet@rasterburn.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef QT1010_H
23#define QT1010_H
24
25#include "dvb_frontend.h"
26
27struct qt1010_config {
28 u8 i2c_address;
29};
30
31/**
32 * Attach a qt1010 tuner to the supplied frontend structure.
33 *
34 * @param fe frontend to attach to
35 * @param i2c i2c adapter to use
36 * @param cfg tuner hw based configuration
37 * @return fe pointer on success, NULL on failure
38 */
39#if defined(CONFIG_MEDIA_TUNER_QT1010) || (defined(CONFIG_MEDIA_TUNER_QT1010_MODULE) && defined(MODULE))
40extern struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
41 struct i2c_adapter *i2c,
42 struct qt1010_config *cfg);
43#else
44static inline struct dvb_frontend *qt1010_attach(struct dvb_frontend *fe,
45 struct i2c_adapter *i2c,
46 struct qt1010_config *cfg)
47{
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
49 return NULL;
50}
51#endif // CONFIG_MEDIA_TUNER_QT1010
52
53#endif
diff --git a/drivers/media/tuners/qt1010_priv.h b/drivers/media/tuners/qt1010_priv.h
new file mode 100644
index 000000000000..2c42d3f01636
--- /dev/null
+++ b/drivers/media/tuners/qt1010_priv.h
@@ -0,0 +1,104 @@
1/*
2 * Driver for Quantek QT1010 silicon tuner
3 *
4 * Copyright (C) 2006 Antti Palosaari <crope@iki.fi>
5 * Aapo Tahkola <aet@rasterburn.org>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef QT1010_PRIV_H
23#define QT1010_PRIV_H
24
25/*
26reg def meaning
27=== === =======
2800 00 ?
2901 a0 ? operation start/stop; start=80, stop=00
3002 00 ?
3103 19 ?
3204 00 ?
3305 00 ? maybe band selection
3406 00 ?
3507 2b set frequency: 32 MHz scale, n*32 MHz
3608 0b ?
3709 10 ? changes every 8/24 MHz; values 1d/1c
380a 08 set frequency: 4 MHz scale, n*4 MHz
390b 41 ? changes every 2/2 MHz; values 45/45
400c e1 ?
410d 94 ?
420e b6 ?
430f 2c ?
4410 10 ?
4511 f1 ? maybe device specified adjustment
4612 11 ? maybe device specified adjustment
4713 3f ?
4814 1f ?
4915 3f ?
5016 ff ?
5117 ff ?
5218 f7 ?
5319 80 ?
541a d0 set frequency: 125 kHz scale, n*125 kHz
551b 00 ?
561c 89 ?
571d 00 ?
581e 00 ? looks like operation register; write cmd here, read result from 1f-26
591f 20 ? chip initialization
6020 e0 ? chip initialization
6121 20 ?
6222 d0 ?
6323 d0 ?
6424 d0 ?
6525 40 ? chip initialization
6626 08 ?
6727 29 ?
6828 55 ?
6929 39 ?
702a 13 ?
712b 01 ?
722c ea ?
732d 00 ?
742e 00 ? not used?
752f 00 ? not used?
76*/
77
78#define QT1010_STEP 125000 /* 125 kHz used by Windows drivers,
79 hw could be more precise but we don't
80 know how to use */
81#define QT1010_MIN_FREQ 48000000 /* 48 MHz */
82#define QT1010_MAX_FREQ 860000000 /* 860 MHz */
83#define QT1010_OFFSET 1246000000 /* 1246 MHz */
84
85#define QT1010_WR 0
86#define QT1010_RD 1
87#define QT1010_M1 3
88
89typedef struct {
90 u8 oper, reg, val;
91} qt1010_i2c_oper_t;
92
93struct qt1010_priv {
94 struct qt1010_config *cfg;
95 struct i2c_adapter *i2c;
96
97 u8 reg1f_init_val;
98 u8 reg20_init_val;
99 u8 reg25_init_val;
100
101 u32 frequency;
102};
103
104#endif
diff --git a/drivers/media/tuners/tda18212.c b/drivers/media/tuners/tda18212.c
new file mode 100644
index 000000000000..5d9f02842501
--- /dev/null
+++ b/drivers/media/tuners/tda18212.c
@@ -0,0 +1,319 @@
1/*
2 * NXP TDA18212HN silicon tuner driver
3 *
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include "tda18212.h"
22
23struct tda18212_priv {
24 struct tda18212_config *cfg;
25 struct i2c_adapter *i2c;
26
27 u32 if_frequency;
28};
29
30/* write multiple registers */
31static int tda18212_wr_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
32 int len)
33{
34 int ret;
35 u8 buf[len+1];
36 struct i2c_msg msg[1] = {
37 {
38 .addr = priv->cfg->i2c_address,
39 .flags = 0,
40 .len = sizeof(buf),
41 .buf = buf,
42 }
43 };
44
45 buf[0] = reg;
46 memcpy(&buf[1], val, len);
47
48 ret = i2c_transfer(priv->i2c, msg, 1);
49 if (ret == 1) {
50 ret = 0;
51 } else {
52 dev_warn(&priv->i2c->dev, "%s: i2c wr failed=%d reg=%02x " \
53 "len=%d\n", KBUILD_MODNAME, ret, reg, len);
54 ret = -EREMOTEIO;
55 }
56 return ret;
57}
58
59/* read multiple registers */
60static int tda18212_rd_regs(struct tda18212_priv *priv, u8 reg, u8 *val,
61 int len)
62{
63 int ret;
64 u8 buf[len];
65 struct i2c_msg msg[2] = {
66 {
67 .addr = priv->cfg->i2c_address,
68 .flags = 0,
69 .len = 1,
70 .buf = &reg,
71 }, {
72 .addr = priv->cfg->i2c_address,
73 .flags = I2C_M_RD,
74 .len = sizeof(buf),
75 .buf = buf,
76 }
77 };
78
79 ret = i2c_transfer(priv->i2c, msg, 2);
80 if (ret == 2) {
81 memcpy(val, buf, len);
82 ret = 0;
83 } else {
84 dev_warn(&priv->i2c->dev, "%s: i2c rd failed=%d reg=%02x " \
85 "len=%d\n", KBUILD_MODNAME, ret, reg, len);
86 ret = -EREMOTEIO;
87 }
88
89 return ret;
90}
91
92/* write single register */
93static int tda18212_wr_reg(struct tda18212_priv *priv, u8 reg, u8 val)
94{
95 return tda18212_wr_regs(priv, reg, &val, 1);
96}
97
98/* read single register */
99static int tda18212_rd_reg(struct tda18212_priv *priv, u8 reg, u8 *val)
100{
101 return tda18212_rd_regs(priv, reg, val, 1);
102}
103
104#if 0 /* keep, useful when developing driver */
105static void tda18212_dump_regs(struct tda18212_priv *priv)
106{
107 int i;
108 u8 buf[256];
109
110 #define TDA18212_RD_LEN 32
111 for (i = 0; i < sizeof(buf); i += TDA18212_RD_LEN)
112 tda18212_rd_regs(priv, i, &buf[i], TDA18212_RD_LEN);
113
114 print_hex_dump(KERN_INFO, "", DUMP_PREFIX_OFFSET, 32, 1, buf,
115 sizeof(buf), true);
116
117 return;
118}
119#endif
120
121static int tda18212_set_params(struct dvb_frontend *fe)
122{
123 struct tda18212_priv *priv = fe->tuner_priv;
124 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
125 int ret, i;
126 u32 if_khz;
127 u8 buf[9];
128 #define DVBT_6 0
129 #define DVBT_7 1
130 #define DVBT_8 2
131 #define DVBT2_6 3
132 #define DVBT2_7 4
133 #define DVBT2_8 5
134 #define DVBC_6 6
135 #define DVBC_8 7
136 static const u8 bw_params[][3] = {
137 /* reg: 0f 13 23 */
138 [DVBT_6] = { 0xb3, 0x20, 0x03 },
139 [DVBT_7] = { 0xb3, 0x31, 0x01 },
140 [DVBT_8] = { 0xb3, 0x22, 0x01 },
141 [DVBT2_6] = { 0xbc, 0x20, 0x03 },
142 [DVBT2_7] = { 0xbc, 0x72, 0x03 },
143 [DVBT2_8] = { 0xbc, 0x22, 0x01 },
144 [DVBC_6] = { 0x92, 0x50, 0x03 },
145 [DVBC_8] = { 0x92, 0x53, 0x03 },
146 };
147
148 dev_dbg(&priv->i2c->dev,
149 "%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
150 __func__, c->delivery_system, c->frequency,
151 c->bandwidth_hz);
152
153 if (fe->ops.i2c_gate_ctrl)
154 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
155
156 switch (c->delivery_system) {
157 case SYS_DVBT:
158 switch (c->bandwidth_hz) {
159 case 6000000:
160 if_khz = priv->cfg->if_dvbt_6;
161 i = DVBT_6;
162 break;
163 case 7000000:
164 if_khz = priv->cfg->if_dvbt_7;
165 i = DVBT_7;
166 break;
167 case 8000000:
168 if_khz = priv->cfg->if_dvbt_8;
169 i = DVBT_8;
170 break;
171 default:
172 ret = -EINVAL;
173 goto error;
174 }
175 break;
176 case SYS_DVBT2:
177 switch (c->bandwidth_hz) {
178 case 6000000:
179 if_khz = priv->cfg->if_dvbt2_6;
180 i = DVBT2_6;
181 break;
182 case 7000000:
183 if_khz = priv->cfg->if_dvbt2_7;
184 i = DVBT2_7;
185 break;
186 case 8000000:
187 if_khz = priv->cfg->if_dvbt2_8;
188 i = DVBT2_8;
189 break;
190 default:
191 ret = -EINVAL;
192 goto error;
193 }
194 break;
195 case SYS_DVBC_ANNEX_A:
196 case SYS_DVBC_ANNEX_C:
197 if_khz = priv->cfg->if_dvbc;
198 i = DVBC_8;
199 break;
200 default:
201 ret = -EINVAL;
202 goto error;
203 }
204
205 ret = tda18212_wr_reg(priv, 0x23, bw_params[i][2]);
206 if (ret)
207 goto error;
208
209 ret = tda18212_wr_reg(priv, 0x06, 0x00);
210 if (ret)
211 goto error;
212
213 ret = tda18212_wr_reg(priv, 0x0f, bw_params[i][0]);
214 if (ret)
215 goto error;
216
217 buf[0] = 0x02;
218 buf[1] = bw_params[i][1];
219 buf[2] = 0x03; /* default value */
220 buf[3] = DIV_ROUND_CLOSEST(if_khz, 50);
221 buf[4] = ((c->frequency / 1000) >> 16) & 0xff;
222 buf[5] = ((c->frequency / 1000) >> 8) & 0xff;
223 buf[6] = ((c->frequency / 1000) >> 0) & 0xff;
224 buf[7] = 0xc1;
225 buf[8] = 0x01;
226 ret = tda18212_wr_regs(priv, 0x12, buf, sizeof(buf));
227 if (ret)
228 goto error;
229
230 /* actual IF rounded as it is on register */
231 priv->if_frequency = buf[3] * 50 * 1000;
232
233exit:
234 if (fe->ops.i2c_gate_ctrl)
235 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
236
237 return ret;
238
239error:
240 dev_dbg(&priv->i2c->dev, "%s: failed=%d\n", __func__, ret);
241 goto exit;
242}
243
244static int tda18212_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
245{
246 struct tda18212_priv *priv = fe->tuner_priv;
247
248 *frequency = priv->if_frequency;
249
250 return 0;
251}
252
253static int tda18212_release(struct dvb_frontend *fe)
254{
255 kfree(fe->tuner_priv);
256 fe->tuner_priv = NULL;
257 return 0;
258}
259
260static const struct dvb_tuner_ops tda18212_tuner_ops = {
261 .info = {
262 .name = "NXP TDA18212",
263
264 .frequency_min = 48000000,
265 .frequency_max = 864000000,
266 .frequency_step = 1000,
267 },
268
269 .release = tda18212_release,
270
271 .set_params = tda18212_set_params,
272 .get_if_frequency = tda18212_get_if_frequency,
273};
274
275struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
276 struct i2c_adapter *i2c, struct tda18212_config *cfg)
277{
278 struct tda18212_priv *priv = NULL;
279 int ret;
280 u8 uninitialized_var(val);
281
282 priv = kzalloc(sizeof(struct tda18212_priv), GFP_KERNEL);
283 if (priv == NULL)
284 return NULL;
285
286 priv->cfg = cfg;
287 priv->i2c = i2c;
288 fe->tuner_priv = priv;
289
290 if (fe->ops.i2c_gate_ctrl)
291 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
292
293 /* check if the tuner is there */
294 ret = tda18212_rd_reg(priv, 0x00, &val);
295
296 if (fe->ops.i2c_gate_ctrl)
297 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
298
299 dev_dbg(&priv->i2c->dev, "%s: ret=%d chip id=%02x\n", __func__, ret,
300 val);
301 if (ret || val != 0xc7) {
302 kfree(priv);
303 return NULL;
304 }
305
306 dev_info(&priv->i2c->dev,
307 "%s: NXP TDA18212HN successfully identified\n",
308 KBUILD_MODNAME);
309
310 memcpy(&fe->ops.tuner_ops, &tda18212_tuner_ops,
311 sizeof(struct dvb_tuner_ops));
312
313 return fe;
314}
315EXPORT_SYMBOL(tda18212_attach);
316
317MODULE_DESCRIPTION("NXP TDA18212HN silicon tuner driver");
318MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
319MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tda18212.h b/drivers/media/tuners/tda18212.h
new file mode 100644
index 000000000000..9bd5da4aabb7
--- /dev/null
+++ b/drivers/media/tuners/tda18212.h
@@ -0,0 +1,52 @@
1/*
2 * NXP TDA18212HN silicon tuner driver
3 *
4 * Copyright (C) 2011 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef TDA18212_H
22#define TDA18212_H
23
24#include "dvb_frontend.h"
25
26struct tda18212_config {
27 u8 i2c_address;
28
29 u16 if_dvbt_6;
30 u16 if_dvbt_7;
31 u16 if_dvbt_8;
32 u16 if_dvbt2_5;
33 u16 if_dvbt2_6;
34 u16 if_dvbt2_7;
35 u16 if_dvbt2_8;
36 u16 if_dvbc;
37};
38
39#if defined(CONFIG_MEDIA_TUNER_TDA18212) || \
40 (defined(CONFIG_MEDIA_TUNER_TDA18212_MODULE) && defined(MODULE))
41extern struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
42 struct i2c_adapter *i2c, struct tda18212_config *cfg);
43#else
44static inline struct dvb_frontend *tda18212_attach(struct dvb_frontend *fe,
45 struct i2c_adapter *i2c, struct tda18212_config *cfg)
46{
47 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
48 return NULL;
49}
50#endif
51
52#endif
diff --git a/drivers/media/tuners/tda18218.c b/drivers/media/tuners/tda18218.c
new file mode 100644
index 000000000000..8a6f9ca788f0
--- /dev/null
+++ b/drivers/media/tuners/tda18218.c
@@ -0,0 +1,342 @@
1/*
2 * NXP TDA18218HN silicon tuner driver
3 *
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include "tda18218.h"
22#include "tda18218_priv.h"
23
24static int debug;
25module_param(debug, int, 0644);
26MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
27
28/* write multiple registers */
29static int tda18218_wr_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
30{
31 int ret = 0;
32 u8 buf[1+len], quotient, remainder, i, msg_len, msg_len_max;
33 struct i2c_msg msg[1] = {
34 {
35 .addr = priv->cfg->i2c_address,
36 .flags = 0,
37 .buf = buf,
38 }
39 };
40
41 msg_len_max = priv->cfg->i2c_wr_max - 1;
42 quotient = len / msg_len_max;
43 remainder = len % msg_len_max;
44 msg_len = msg_len_max;
45 for (i = 0; (i <= quotient && remainder); i++) {
46 if (i == quotient) /* set len of the last msg */
47 msg_len = remainder;
48
49 msg[0].len = msg_len + 1;
50 buf[0] = reg + i * msg_len_max;
51 memcpy(&buf[1], &val[i * msg_len_max], msg_len);
52
53 ret = i2c_transfer(priv->i2c, msg, 1);
54 if (ret != 1)
55 break;
56 }
57
58 if (ret == 1) {
59 ret = 0;
60 } else {
61 warn("i2c wr failed ret:%d reg:%02x len:%d", ret, reg, len);
62 ret = -EREMOTEIO;
63 }
64
65 return ret;
66}
67
68/* read multiple registers */
69static int tda18218_rd_regs(struct tda18218_priv *priv, u8 reg, u8 *val, u8 len)
70{
71 int ret;
72 u8 buf[reg+len]; /* we must start read always from reg 0x00 */
73 struct i2c_msg msg[2] = {
74 {
75 .addr = priv->cfg->i2c_address,
76 .flags = 0,
77 .len = 1,
78 .buf = "\x00",
79 }, {
80 .addr = priv->cfg->i2c_address,
81 .flags = I2C_M_RD,
82 .len = sizeof(buf),
83 .buf = buf,
84 }
85 };
86
87 ret = i2c_transfer(priv->i2c, msg, 2);
88 if (ret == 2) {
89 memcpy(val, &buf[reg], len);
90 ret = 0;
91 } else {
92 warn("i2c rd failed ret:%d reg:%02x len:%d", ret, reg, len);
93 ret = -EREMOTEIO;
94 }
95
96 return ret;
97}
98
99/* write single register */
100static int tda18218_wr_reg(struct tda18218_priv *priv, u8 reg, u8 val)
101{
102 return tda18218_wr_regs(priv, reg, &val, 1);
103}
104
105/* read single register */
106
107static int tda18218_rd_reg(struct tda18218_priv *priv, u8 reg, u8 *val)
108{
109 return tda18218_rd_regs(priv, reg, val, 1);
110}
111
112static int tda18218_set_params(struct dvb_frontend *fe)
113{
114 struct tda18218_priv *priv = fe->tuner_priv;
115 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
116 u32 bw = c->bandwidth_hz;
117 int ret;
118 u8 buf[3], i, BP_Filter, LP_Fc;
119 u32 LO_Frac;
120 /* TODO: find out correct AGC algorithm */
121 u8 agc[][2] = {
122 { R20_AGC11, 0x60 },
123 { R23_AGC21, 0x02 },
124 { R20_AGC11, 0xa0 },
125 { R23_AGC21, 0x09 },
126 { R20_AGC11, 0xe0 },
127 { R23_AGC21, 0x0c },
128 { R20_AGC11, 0x40 },
129 { R23_AGC21, 0x01 },
130 { R20_AGC11, 0x80 },
131 { R23_AGC21, 0x08 },
132 { R20_AGC11, 0xc0 },
133 { R23_AGC21, 0x0b },
134 { R24_AGC22, 0x1c },
135 { R24_AGC22, 0x0c },
136 };
137
138 if (fe->ops.i2c_gate_ctrl)
139 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
140
141 /* low-pass filter cut-off frequency */
142 if (bw <= 6000000) {
143 LP_Fc = 0;
144 priv->if_frequency = 3000000;
145 } else if (bw <= 7000000) {
146 LP_Fc = 1;
147 priv->if_frequency = 3500000;
148 } else {
149 LP_Fc = 2;
150 priv->if_frequency = 4000000;
151 }
152
153 LO_Frac = c->frequency + priv->if_frequency;
154
155 /* band-pass filter */
156 if (LO_Frac < 188000000)
157 BP_Filter = 3;
158 else if (LO_Frac < 253000000)
159 BP_Filter = 4;
160 else if (LO_Frac < 343000000)
161 BP_Filter = 5;
162 else
163 BP_Filter = 6;
164
165 buf[0] = (priv->regs[R1A_IF1] & ~7) | BP_Filter; /* BP_Filter */
166 buf[1] = (priv->regs[R1B_IF2] & ~3) | LP_Fc; /* LP_Fc */
167 buf[2] = priv->regs[R1C_AGC2B];
168 ret = tda18218_wr_regs(priv, R1A_IF1, buf, 3);
169 if (ret)
170 goto error;
171
172 buf[0] = (LO_Frac / 1000) >> 12; /* LO_Frac_0 */
173 buf[1] = (LO_Frac / 1000) >> 4; /* LO_Frac_1 */
174 buf[2] = (LO_Frac / 1000) << 4 |
175 (priv->regs[R0C_MD5] & 0x0f); /* LO_Frac_2 */
176 ret = tda18218_wr_regs(priv, R0A_MD3, buf, 3);
177 if (ret)
178 goto error;
179
180 buf[0] = priv->regs[R0F_MD8] | (1 << 6); /* Freq_prog_Start */
181 ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
182 if (ret)
183 goto error;
184
185 buf[0] = priv->regs[R0F_MD8] & ~(1 << 6); /* Freq_prog_Start */
186 ret = tda18218_wr_regs(priv, R0F_MD8, buf, 1);
187 if (ret)
188 goto error;
189
190 /* trigger AGC */
191 for (i = 0; i < ARRAY_SIZE(agc); i++) {
192 ret = tda18218_wr_reg(priv, agc[i][0], agc[i][1]);
193 if (ret)
194 goto error;
195 }
196
197error:
198 if (fe->ops.i2c_gate_ctrl)
199 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
200
201 if (ret)
202 dbg("%s: failed ret:%d", __func__, ret);
203
204 return ret;
205}
206
207static int tda18218_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
208{
209 struct tda18218_priv *priv = fe->tuner_priv;
210 *frequency = priv->if_frequency;
211 dbg("%s: if=%d", __func__, *frequency);
212 return 0;
213}
214
215static int tda18218_sleep(struct dvb_frontend *fe)
216{
217 struct tda18218_priv *priv = fe->tuner_priv;
218 int ret;
219
220 if (fe->ops.i2c_gate_ctrl)
221 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
222
223 /* standby */
224 ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
225
226 if (fe->ops.i2c_gate_ctrl)
227 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
228
229 if (ret)
230 dbg("%s: failed ret:%d", __func__, ret);
231
232 return ret;
233}
234
235static int tda18218_init(struct dvb_frontend *fe)
236{
237 struct tda18218_priv *priv = fe->tuner_priv;
238 int ret;
239
240 /* TODO: calibrations */
241
242 if (fe->ops.i2c_gate_ctrl)
243 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
244
245 ret = tda18218_wr_regs(priv, R00_ID, priv->regs, TDA18218_NUM_REGS);
246
247 if (fe->ops.i2c_gate_ctrl)
248 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
249
250 if (ret)
251 dbg("%s: failed ret:%d", __func__, ret);
252
253 return ret;
254}
255
256static int tda18218_release(struct dvb_frontend *fe)
257{
258 kfree(fe->tuner_priv);
259 fe->tuner_priv = NULL;
260 return 0;
261}
262
263static const struct dvb_tuner_ops tda18218_tuner_ops = {
264 .info = {
265 .name = "NXP TDA18218",
266
267 .frequency_min = 174000000,
268 .frequency_max = 864000000,
269 .frequency_step = 1000,
270 },
271
272 .release = tda18218_release,
273 .init = tda18218_init,
274 .sleep = tda18218_sleep,
275
276 .set_params = tda18218_set_params,
277
278 .get_if_frequency = tda18218_get_if_frequency,
279};
280
281struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
282 struct i2c_adapter *i2c, struct tda18218_config *cfg)
283{
284 struct tda18218_priv *priv = NULL;
285 u8 uninitialized_var(val);
286 int ret;
287 /* chip default registers values */
288 static u8 def_regs[] = {
289 0xc0, 0x88, 0x00, 0x8e, 0x03, 0x00, 0x00, 0xd0, 0x00, 0x40,
290 0x00, 0x00, 0x07, 0xff, 0x84, 0x09, 0x00, 0x13, 0x00, 0x00,
291 0x01, 0x84, 0x09, 0xf0, 0x19, 0x0a, 0x8e, 0x69, 0x98, 0x01,
292 0x00, 0x58, 0x10, 0x40, 0x8c, 0x00, 0x0c, 0x48, 0x85, 0xc9,
293 0xa7, 0x00, 0x00, 0x00, 0x30, 0x81, 0x80, 0x00, 0x39, 0x00,
294 0x8a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xf6, 0xf6
295 };
296
297 priv = kzalloc(sizeof(struct tda18218_priv), GFP_KERNEL);
298 if (priv == NULL)
299 return NULL;
300
301 priv->cfg = cfg;
302 priv->i2c = i2c;
303 fe->tuner_priv = priv;
304
305 if (fe->ops.i2c_gate_ctrl)
306 fe->ops.i2c_gate_ctrl(fe, 1); /* open I2C-gate */
307
308 /* check if the tuner is there */
309 ret = tda18218_rd_reg(priv, R00_ID, &val);
310 dbg("%s: ret:%d chip ID:%02x", __func__, ret, val);
311 if (ret || val != def_regs[R00_ID]) {
312 kfree(priv);
313 return NULL;
314 }
315
316 info("NXP TDA18218HN successfully identified.");
317
318 memcpy(&fe->ops.tuner_ops, &tda18218_tuner_ops,
319 sizeof(struct dvb_tuner_ops));
320 memcpy(priv->regs, def_regs, sizeof(def_regs));
321
322 /* loop-through enabled chip default register values */
323 if (priv->cfg->loop_through) {
324 priv->regs[R17_PD1] = 0xb0;
325 priv->regs[R18_PD2] = 0x59;
326 }
327
328 /* standby */
329 ret = tda18218_wr_reg(priv, R17_PD1, priv->regs[R17_PD1] | (1 << 0));
330 if (ret)
331 dbg("%s: failed ret:%d", __func__, ret);
332
333 if (fe->ops.i2c_gate_ctrl)
334 fe->ops.i2c_gate_ctrl(fe, 0); /* close I2C-gate */
335
336 return fe;
337}
338EXPORT_SYMBOL(tda18218_attach);
339
340MODULE_DESCRIPTION("NXP TDA18218HN silicon tuner driver");
341MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
342MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tda18218.h b/drivers/media/tuners/tda18218.h
new file mode 100644
index 000000000000..b4180d180029
--- /dev/null
+++ b/drivers/media/tuners/tda18218.h
@@ -0,0 +1,45 @@
1/*
2 * NXP TDA18218HN silicon tuner driver
3 *
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef TDA18218_H
22#define TDA18218_H
23
24#include "dvb_frontend.h"
25
26struct tda18218_config {
27 u8 i2c_address;
28 u8 i2c_wr_max;
29 u8 loop_through:1;
30};
31
32#if defined(CONFIG_MEDIA_TUNER_TDA18218) || \
33 (defined(CONFIG_MEDIA_TUNER_TDA18218_MODULE) && defined(MODULE))
34extern struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
35 struct i2c_adapter *i2c, struct tda18218_config *cfg);
36#else
37static inline struct dvb_frontend *tda18218_attach(struct dvb_frontend *fe,
38 struct i2c_adapter *i2c, struct tda18218_config *cfg)
39{
40 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
41 return NULL;
42}
43#endif
44
45#endif
diff --git a/drivers/media/tuners/tda18218_priv.h b/drivers/media/tuners/tda18218_priv.h
new file mode 100644
index 000000000000..dc52b72e1407
--- /dev/null
+++ b/drivers/media/tuners/tda18218_priv.h
@@ -0,0 +1,108 @@
1/*
2 * NXP TDA18218HN silicon tuner driver
3 *
4 * Copyright (C) 2010 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#ifndef TDA18218_PRIV_H
22#define TDA18218_PRIV_H
23
24#define LOG_PREFIX "tda18218"
25
26#undef dbg
27#define dbg(f, arg...) \
28 if (debug) \
29 printk(KERN_DEBUG LOG_PREFIX": " f "\n" , ## arg)
30#undef err
31#define err(f, arg...) printk(KERN_ERR LOG_PREFIX": " f "\n" , ## arg)
32#undef info
33#define info(f, arg...) printk(KERN_INFO LOG_PREFIX": " f "\n" , ## arg)
34#undef warn
35#define warn(f, arg...) printk(KERN_WARNING LOG_PREFIX": " f "\n" , ## arg)
36
37#define R00_ID 0x00 /* ID byte */
38#define R01_R1 0x01 /* Read byte 1 */
39#define R02_R2 0x02 /* Read byte 2 */
40#define R03_R3 0x03 /* Read byte 3 */
41#define R04_R4 0x04 /* Read byte 4 */
42#define R05_R5 0x05 /* Read byte 5 */
43#define R06_R6 0x06 /* Read byte 6 */
44#define R07_MD1 0x07 /* Main divider byte 1 */
45#define R08_PSM1 0x08 /* PSM byte 1 */
46#define R09_MD2 0x09 /* Main divider byte 2 */
47#define R0A_MD3 0x0a /* Main divider byte 1 */
48#define R0B_MD4 0x0b /* Main divider byte 4 */
49#define R0C_MD5 0x0c /* Main divider byte 5 */
50#define R0D_MD6 0x0d /* Main divider byte 6 */
51#define R0E_MD7 0x0e /* Main divider byte 7 */
52#define R0F_MD8 0x0f /* Main divider byte 8 */
53#define R10_CD1 0x10 /* Call divider byte 1 */
54#define R11_CD2 0x11 /* Call divider byte 2 */
55#define R12_CD3 0x12 /* Call divider byte 3 */
56#define R13_CD4 0x13 /* Call divider byte 4 */
57#define R14_CD5 0x14 /* Call divider byte 5 */
58#define R15_CD6 0x15 /* Call divider byte 6 */
59#define R16_CD7 0x16 /* Call divider byte 7 */
60#define R17_PD1 0x17 /* Power-down byte 1 */
61#define R18_PD2 0x18 /* Power-down byte 2 */
62#define R19_XTOUT 0x19 /* XTOUT byte */
63#define R1A_IF1 0x1a /* IF byte 1 */
64#define R1B_IF2 0x1b /* IF byte 2 */
65#define R1C_AGC2B 0x1c /* AGC2b byte */
66#define R1D_PSM2 0x1d /* PSM byte 2 */
67#define R1E_PSM3 0x1e /* PSM byte 3 */
68#define R1F_PSM4 0x1f /* PSM byte 4 */
69#define R20_AGC11 0x20 /* AGC1 byte 1 */
70#define R21_AGC12 0x21 /* AGC1 byte 2 */
71#define R22_AGC13 0x22 /* AGC1 byte 3 */
72#define R23_AGC21 0x23 /* AGC2 byte 1 */
73#define R24_AGC22 0x24 /* AGC2 byte 2 */
74#define R25_AAGC 0x25 /* Analog AGC byte */
75#define R26_RC 0x26 /* RC byte */
76#define R27_RSSI 0x27 /* RSSI byte */
77#define R28_IRCAL1 0x28 /* IR CAL byte 1 */
78#define R29_IRCAL2 0x29 /* IR CAL byte 2 */
79#define R2A_IRCAL3 0x2a /* IR CAL byte 3 */
80#define R2B_IRCAL4 0x2b /* IR CAL byte 4 */
81#define R2C_RFCAL1 0x2c /* RF CAL byte 1 */
82#define R2D_RFCAL2 0x2d /* RF CAL byte 2 */
83#define R2E_RFCAL3 0x2e /* RF CAL byte 3 */
84#define R2F_RFCAL4 0x2f /* RF CAL byte 4 */
85#define R30_RFCAL5 0x30 /* RF CAL byte 5 */
86#define R31_RFCAL6 0x31 /* RF CAL byte 6 */
87#define R32_RFCAL7 0x32 /* RF CAL byte 7 */
88#define R33_RFCAL8 0x33 /* RF CAL byte 8 */
89#define R34_RFCAL9 0x34 /* RF CAL byte 9 */
90#define R35_RFCAL10 0x35 /* RF CAL byte 10 */
91#define R36_RFCALRAM1 0x36 /* RF CAL RAM byte 1 */
92#define R37_RFCALRAM2 0x37 /* RF CAL RAM byte 2 */
93#define R38_MARGIN 0x38 /* Margin byte */
94#define R39_FMAX1 0x39 /* Fmax byte 1 */
95#define R3A_FMAX2 0x3a /* Fmax byte 2 */
96
97#define TDA18218_NUM_REGS 59
98
99struct tda18218_priv {
100 struct tda18218_config *cfg;
101 struct i2c_adapter *i2c;
102
103 u32 if_frequency;
104
105 u8 regs[TDA18218_NUM_REGS];
106};
107
108#endif
diff --git a/drivers/media/tuners/tda18271-common.c b/drivers/media/tuners/tda18271-common.c
new file mode 100644
index 000000000000..39c645787b62
--- /dev/null
+++ b/drivers/media/tuners/tda18271-common.c
@@ -0,0 +1,703 @@
1/*
2 tda18271-common.c - driver for the Philips / NXP TDA18271 silicon tuner
3
4 Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include "tda18271-priv.h"
22
23static int tda18271_i2c_gate_ctrl(struct dvb_frontend *fe, int enable)
24{
25 struct tda18271_priv *priv = fe->tuner_priv;
26 enum tda18271_i2c_gate gate;
27 int ret = 0;
28
29 switch (priv->gate) {
30 case TDA18271_GATE_DIGITAL:
31 case TDA18271_GATE_ANALOG:
32 gate = priv->gate;
33 break;
34 case TDA18271_GATE_AUTO:
35 default:
36 switch (priv->mode) {
37 case TDA18271_DIGITAL:
38 gate = TDA18271_GATE_DIGITAL;
39 break;
40 case TDA18271_ANALOG:
41 default:
42 gate = TDA18271_GATE_ANALOG;
43 break;
44 }
45 }
46
47 switch (gate) {
48 case TDA18271_GATE_ANALOG:
49 if (fe->ops.analog_ops.i2c_gate_ctrl)
50 ret = fe->ops.analog_ops.i2c_gate_ctrl(fe, enable);
51 break;
52 case TDA18271_GATE_DIGITAL:
53 if (fe->ops.i2c_gate_ctrl)
54 ret = fe->ops.i2c_gate_ctrl(fe, enable);
55 break;
56 default:
57 ret = -EINVAL;
58 break;
59 }
60
61 return ret;
62};
63
64/*---------------------------------------------------------------------*/
65
66static void tda18271_dump_regs(struct dvb_frontend *fe, int extended)
67{
68 struct tda18271_priv *priv = fe->tuner_priv;
69 unsigned char *regs = priv->tda18271_regs;
70
71 tda_reg("=== TDA18271 REG DUMP ===\n");
72 tda_reg("ID_BYTE = 0x%02x\n", 0xff & regs[R_ID]);
73 tda_reg("THERMO_BYTE = 0x%02x\n", 0xff & regs[R_TM]);
74 tda_reg("POWER_LEVEL_BYTE = 0x%02x\n", 0xff & regs[R_PL]);
75 tda_reg("EASY_PROG_BYTE_1 = 0x%02x\n", 0xff & regs[R_EP1]);
76 tda_reg("EASY_PROG_BYTE_2 = 0x%02x\n", 0xff & regs[R_EP2]);
77 tda_reg("EASY_PROG_BYTE_3 = 0x%02x\n", 0xff & regs[R_EP3]);
78 tda_reg("EASY_PROG_BYTE_4 = 0x%02x\n", 0xff & regs[R_EP4]);
79 tda_reg("EASY_PROG_BYTE_5 = 0x%02x\n", 0xff & regs[R_EP5]);
80 tda_reg("CAL_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_CPD]);
81 tda_reg("CAL_DIV_BYTE_1 = 0x%02x\n", 0xff & regs[R_CD1]);
82 tda_reg("CAL_DIV_BYTE_2 = 0x%02x\n", 0xff & regs[R_CD2]);
83 tda_reg("CAL_DIV_BYTE_3 = 0x%02x\n", 0xff & regs[R_CD3]);
84 tda_reg("MAIN_POST_DIV_BYTE = 0x%02x\n", 0xff & regs[R_MPD]);
85 tda_reg("MAIN_DIV_BYTE_1 = 0x%02x\n", 0xff & regs[R_MD1]);
86 tda_reg("MAIN_DIV_BYTE_2 = 0x%02x\n", 0xff & regs[R_MD2]);
87 tda_reg("MAIN_DIV_BYTE_3 = 0x%02x\n", 0xff & regs[R_MD3]);
88
89 /* only dump extended regs if DBG_ADV is set */
90 if (!(tda18271_debug & DBG_ADV))
91 return;
92
93 /* W indicates write-only registers.
94 * Register dump for write-only registers shows last value written. */
95
96 tda_reg("EXTENDED_BYTE_1 = 0x%02x\n", 0xff & regs[R_EB1]);
97 tda_reg("EXTENDED_BYTE_2 = 0x%02x\n", 0xff & regs[R_EB2]);
98 tda_reg("EXTENDED_BYTE_3 = 0x%02x\n", 0xff & regs[R_EB3]);
99 tda_reg("EXTENDED_BYTE_4 = 0x%02x\n", 0xff & regs[R_EB4]);
100 tda_reg("EXTENDED_BYTE_5 = 0x%02x\n", 0xff & regs[R_EB5]);
101 tda_reg("EXTENDED_BYTE_6 = 0x%02x\n", 0xff & regs[R_EB6]);
102 tda_reg("EXTENDED_BYTE_7 = 0x%02x\n", 0xff & regs[R_EB7]);
103 tda_reg("EXTENDED_BYTE_8 = 0x%02x\n", 0xff & regs[R_EB8]);
104 tda_reg("EXTENDED_BYTE_9 W = 0x%02x\n", 0xff & regs[R_EB9]);
105 tda_reg("EXTENDED_BYTE_10 = 0x%02x\n", 0xff & regs[R_EB10]);
106 tda_reg("EXTENDED_BYTE_11 = 0x%02x\n", 0xff & regs[R_EB11]);
107 tda_reg("EXTENDED_BYTE_12 = 0x%02x\n", 0xff & regs[R_EB12]);
108 tda_reg("EXTENDED_BYTE_13 = 0x%02x\n", 0xff & regs[R_EB13]);
109 tda_reg("EXTENDED_BYTE_14 = 0x%02x\n", 0xff & regs[R_EB14]);
110 tda_reg("EXTENDED_BYTE_15 = 0x%02x\n", 0xff & regs[R_EB15]);
111 tda_reg("EXTENDED_BYTE_16 W = 0x%02x\n", 0xff & regs[R_EB16]);
112 tda_reg("EXTENDED_BYTE_17 W = 0x%02x\n", 0xff & regs[R_EB17]);
113 tda_reg("EXTENDED_BYTE_18 = 0x%02x\n", 0xff & regs[R_EB18]);
114 tda_reg("EXTENDED_BYTE_19 W = 0x%02x\n", 0xff & regs[R_EB19]);
115 tda_reg("EXTENDED_BYTE_20 W = 0x%02x\n", 0xff & regs[R_EB20]);
116 tda_reg("EXTENDED_BYTE_21 = 0x%02x\n", 0xff & regs[R_EB21]);
117 tda_reg("EXTENDED_BYTE_22 = 0x%02x\n", 0xff & regs[R_EB22]);
118 tda_reg("EXTENDED_BYTE_23 = 0x%02x\n", 0xff & regs[R_EB23]);
119}
120
121int tda18271_read_regs(struct dvb_frontend *fe)
122{
123 struct tda18271_priv *priv = fe->tuner_priv;
124 unsigned char *regs = priv->tda18271_regs;
125 unsigned char buf = 0x00;
126 int ret;
127 struct i2c_msg msg[] = {
128 { .addr = priv->i2c_props.addr, .flags = 0,
129 .buf = &buf, .len = 1 },
130 { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
131 .buf = regs, .len = 16 }
132 };
133
134 tda18271_i2c_gate_ctrl(fe, 1);
135
136 /* read all registers */
137 ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
138
139 tda18271_i2c_gate_ctrl(fe, 0);
140
141 if (ret != 2)
142 tda_err("ERROR: i2c_transfer returned: %d\n", ret);
143
144 if (tda18271_debug & DBG_REG)
145 tda18271_dump_regs(fe, 0);
146
147 return (ret == 2 ? 0 : ret);
148}
149
150int tda18271_read_extended(struct dvb_frontend *fe)
151{
152 struct tda18271_priv *priv = fe->tuner_priv;
153 unsigned char *regs = priv->tda18271_regs;
154 unsigned char regdump[TDA18271_NUM_REGS];
155 unsigned char buf = 0x00;
156 int ret, i;
157 struct i2c_msg msg[] = {
158 { .addr = priv->i2c_props.addr, .flags = 0,
159 .buf = &buf, .len = 1 },
160 { .addr = priv->i2c_props.addr, .flags = I2C_M_RD,
161 .buf = regdump, .len = TDA18271_NUM_REGS }
162 };
163
164 tda18271_i2c_gate_ctrl(fe, 1);
165
166 /* read all registers */
167 ret = i2c_transfer(priv->i2c_props.adap, msg, 2);
168
169 tda18271_i2c_gate_ctrl(fe, 0);
170
171 if (ret != 2)
172 tda_err("ERROR: i2c_transfer returned: %d\n", ret);
173
174 for (i = 0; i < TDA18271_NUM_REGS; i++) {
175 /* don't update write-only registers */
176 if ((i != R_EB9) &&
177 (i != R_EB16) &&
178 (i != R_EB17) &&
179 (i != R_EB19) &&
180 (i != R_EB20))
181 regs[i] = regdump[i];
182 }
183
184 if (tda18271_debug & DBG_REG)
185 tda18271_dump_regs(fe, 1);
186
187 return (ret == 2 ? 0 : ret);
188}
189
190int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len)
191{
192 struct tda18271_priv *priv = fe->tuner_priv;
193 unsigned char *regs = priv->tda18271_regs;
194 unsigned char buf[TDA18271_NUM_REGS + 1];
195 struct i2c_msg msg = { .addr = priv->i2c_props.addr, .flags = 0,
196 .buf = buf };
197 int i, ret = 1, max;
198
199 BUG_ON((len == 0) || (idx + len > sizeof(buf)));
200
201
202 switch (priv->small_i2c) {
203 case TDA18271_03_BYTE_CHUNK_INIT:
204 max = 3;
205 break;
206 case TDA18271_08_BYTE_CHUNK_INIT:
207 max = 8;
208 break;
209 case TDA18271_16_BYTE_CHUNK_INIT:
210 max = 16;
211 break;
212 case TDA18271_39_BYTE_CHUNK_INIT:
213 default:
214 max = 39;
215 }
216
217 tda18271_i2c_gate_ctrl(fe, 1);
218 while (len) {
219 if (max > len)
220 max = len;
221
222 buf[0] = idx;
223 for (i = 1; i <= max; i++)
224 buf[i] = regs[idx - 1 + i];
225
226 msg.len = max + 1;
227
228 /* write registers */
229 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
230 if (ret != 1)
231 break;
232
233 idx += max;
234 len -= max;
235 }
236 tda18271_i2c_gate_ctrl(fe, 0);
237
238 if (ret != 1)
239 tda_err("ERROR: idx = 0x%x, len = %d, "
240 "i2c_transfer returned: %d\n", idx, max, ret);
241
242 return (ret == 1 ? 0 : ret);
243}
244
245/*---------------------------------------------------------------------*/
246
247int tda18271_charge_pump_source(struct dvb_frontend *fe,
248 enum tda18271_pll pll, int force)
249{
250 struct tda18271_priv *priv = fe->tuner_priv;
251 unsigned char *regs = priv->tda18271_regs;
252
253 int r_cp = (pll == TDA18271_CAL_PLL) ? R_EB7 : R_EB4;
254
255 regs[r_cp] &= ~0x20;
256 regs[r_cp] |= ((force & 1) << 5);
257
258 return tda18271_write_regs(fe, r_cp, 1);
259}
260
261int tda18271_init_regs(struct dvb_frontend *fe)
262{
263 struct tda18271_priv *priv = fe->tuner_priv;
264 unsigned char *regs = priv->tda18271_regs;
265
266 tda_dbg("initializing registers for device @ %d-%04x\n",
267 i2c_adapter_id(priv->i2c_props.adap),
268 priv->i2c_props.addr);
269
270 /* initialize registers */
271 switch (priv->id) {
272 case TDA18271HDC1:
273 regs[R_ID] = 0x83;
274 break;
275 case TDA18271HDC2:
276 regs[R_ID] = 0x84;
277 break;
278 };
279
280 regs[R_TM] = 0x08;
281 regs[R_PL] = 0x80;
282 regs[R_EP1] = 0xc6;
283 regs[R_EP2] = 0xdf;
284 regs[R_EP3] = 0x16;
285 regs[R_EP4] = 0x60;
286 regs[R_EP5] = 0x80;
287 regs[R_CPD] = 0x80;
288 regs[R_CD1] = 0x00;
289 regs[R_CD2] = 0x00;
290 regs[R_CD3] = 0x00;
291 regs[R_MPD] = 0x00;
292 regs[R_MD1] = 0x00;
293 regs[R_MD2] = 0x00;
294 regs[R_MD3] = 0x00;
295
296 switch (priv->id) {
297 case TDA18271HDC1:
298 regs[R_EB1] = 0xff;
299 break;
300 case TDA18271HDC2:
301 regs[R_EB1] = 0xfc;
302 break;
303 };
304
305 regs[R_EB2] = 0x01;
306 regs[R_EB3] = 0x84;
307 regs[R_EB4] = 0x41;
308 regs[R_EB5] = 0x01;
309 regs[R_EB6] = 0x84;
310 regs[R_EB7] = 0x40;
311 regs[R_EB8] = 0x07;
312 regs[R_EB9] = 0x00;
313 regs[R_EB10] = 0x00;
314 regs[R_EB11] = 0x96;
315
316 switch (priv->id) {
317 case TDA18271HDC1:
318 regs[R_EB12] = 0x0f;
319 break;
320 case TDA18271HDC2:
321 regs[R_EB12] = 0x33;
322 break;
323 };
324
325 regs[R_EB13] = 0xc1;
326 regs[R_EB14] = 0x00;
327 regs[R_EB15] = 0x8f;
328 regs[R_EB16] = 0x00;
329 regs[R_EB17] = 0x00;
330
331 switch (priv->id) {
332 case TDA18271HDC1:
333 regs[R_EB18] = 0x00;
334 break;
335 case TDA18271HDC2:
336 regs[R_EB18] = 0x8c;
337 break;
338 };
339
340 regs[R_EB19] = 0x00;
341 regs[R_EB20] = 0x20;
342
343 switch (priv->id) {
344 case TDA18271HDC1:
345 regs[R_EB21] = 0x33;
346 break;
347 case TDA18271HDC2:
348 regs[R_EB21] = 0xb3;
349 break;
350 };
351
352 regs[R_EB22] = 0x48;
353 regs[R_EB23] = 0xb0;
354
355 tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
356
357 /* setup agc1 gain */
358 regs[R_EB17] = 0x00;
359 tda18271_write_regs(fe, R_EB17, 1);
360 regs[R_EB17] = 0x03;
361 tda18271_write_regs(fe, R_EB17, 1);
362 regs[R_EB17] = 0x43;
363 tda18271_write_regs(fe, R_EB17, 1);
364 regs[R_EB17] = 0x4c;
365 tda18271_write_regs(fe, R_EB17, 1);
366
367 /* setup agc2 gain */
368 if ((priv->id) == TDA18271HDC1) {
369 regs[R_EB20] = 0xa0;
370 tda18271_write_regs(fe, R_EB20, 1);
371 regs[R_EB20] = 0xa7;
372 tda18271_write_regs(fe, R_EB20, 1);
373 regs[R_EB20] = 0xe7;
374 tda18271_write_regs(fe, R_EB20, 1);
375 regs[R_EB20] = 0xec;
376 tda18271_write_regs(fe, R_EB20, 1);
377 }
378
379 /* image rejection calibration */
380
381 /* low-band */
382 regs[R_EP3] = 0x1f;
383 regs[R_EP4] = 0x66;
384 regs[R_EP5] = 0x81;
385 regs[R_CPD] = 0xcc;
386 regs[R_CD1] = 0x6c;
387 regs[R_CD2] = 0x00;
388 regs[R_CD3] = 0x00;
389 regs[R_MPD] = 0xcd;
390 regs[R_MD1] = 0x77;
391 regs[R_MD2] = 0x08;
392 regs[R_MD3] = 0x00;
393
394 tda18271_write_regs(fe, R_EP3, 11);
395
396 if ((priv->id) == TDA18271HDC2) {
397 /* main pll cp source on */
398 tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1);
399 msleep(1);
400
401 /* main pll cp source off */
402 tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0);
403 }
404
405 msleep(5); /* pll locking */
406
407 /* launch detector */
408 tda18271_write_regs(fe, R_EP1, 1);
409 msleep(5); /* wanted low measurement */
410
411 regs[R_EP5] = 0x85;
412 regs[R_CPD] = 0xcb;
413 regs[R_CD1] = 0x66;
414 regs[R_CD2] = 0x70;
415
416 tda18271_write_regs(fe, R_EP3, 7);
417 msleep(5); /* pll locking */
418
419 /* launch optimization algorithm */
420 tda18271_write_regs(fe, R_EP2, 1);
421 msleep(30); /* image low optimization completion */
422
423 /* mid-band */
424 regs[R_EP5] = 0x82;
425 regs[R_CPD] = 0xa8;
426 regs[R_CD2] = 0x00;
427 regs[R_MPD] = 0xa9;
428 regs[R_MD1] = 0x73;
429 regs[R_MD2] = 0x1a;
430
431 tda18271_write_regs(fe, R_EP3, 11);
432 msleep(5); /* pll locking */
433
434 /* launch detector */
435 tda18271_write_regs(fe, R_EP1, 1);
436 msleep(5); /* wanted mid measurement */
437
438 regs[R_EP5] = 0x86;
439 regs[R_CPD] = 0xa8;
440 regs[R_CD1] = 0x66;
441 regs[R_CD2] = 0xa0;
442
443 tda18271_write_regs(fe, R_EP3, 7);
444 msleep(5); /* pll locking */
445
446 /* launch optimization algorithm */
447 tda18271_write_regs(fe, R_EP2, 1);
448 msleep(30); /* image mid optimization completion */
449
450 /* high-band */
451 regs[R_EP5] = 0x83;
452 regs[R_CPD] = 0x98;
453 regs[R_CD1] = 0x65;
454 regs[R_CD2] = 0x00;
455 regs[R_MPD] = 0x99;
456 regs[R_MD1] = 0x71;
457 regs[R_MD2] = 0xcd;
458
459 tda18271_write_regs(fe, R_EP3, 11);
460 msleep(5); /* pll locking */
461
462 /* launch detector */
463 tda18271_write_regs(fe, R_EP1, 1);
464 msleep(5); /* wanted high measurement */
465
466 regs[R_EP5] = 0x87;
467 regs[R_CD1] = 0x65;
468 regs[R_CD2] = 0x50;
469
470 tda18271_write_regs(fe, R_EP3, 7);
471 msleep(5); /* pll locking */
472
473 /* launch optimization algorithm */
474 tda18271_write_regs(fe, R_EP2, 1);
475 msleep(30); /* image high optimization completion */
476
477 /* return to normal mode */
478 regs[R_EP4] = 0x64;
479 tda18271_write_regs(fe, R_EP4, 1);
480
481 /* synchronize */
482 tda18271_write_regs(fe, R_EP1, 1);
483
484 return 0;
485}
486
487/*---------------------------------------------------------------------*/
488
489/*
490 * Standby modes, EP3 [7:5]
491 *
492 * | SM || SM_LT || SM_XT || mode description
493 * |=====\\=======\\=======\\===================================
494 * | 0 || 0 || 0 || normal mode
495 * |-----||-------||-------||-----------------------------------
496 * | || || || standby mode w/ slave tuner output
497 * | 1 || 0 || 0 || & loop thru & xtal oscillator on
498 * |-----||-------||-------||-----------------------------------
499 * | 1 || 1 || 0 || standby mode w/ xtal oscillator on
500 * |-----||-------||-------||-----------------------------------
501 * | 1 || 1 || 1 || power off
502 *
503 */
504
505int tda18271_set_standby_mode(struct dvb_frontend *fe,
506 int sm, int sm_lt, int sm_xt)
507{
508 struct tda18271_priv *priv = fe->tuner_priv;
509 unsigned char *regs = priv->tda18271_regs;
510
511 if (tda18271_debug & DBG_ADV)
512 tda_dbg("sm = %d, sm_lt = %d, sm_xt = %d\n", sm, sm_lt, sm_xt);
513
514 regs[R_EP3] &= ~0xe0; /* clear sm, sm_lt, sm_xt */
515 regs[R_EP3] |= (sm ? (1 << 7) : 0) |
516 (sm_lt ? (1 << 6) : 0) |
517 (sm_xt ? (1 << 5) : 0);
518
519 return tda18271_write_regs(fe, R_EP3, 1);
520}
521
522/*---------------------------------------------------------------------*/
523
524int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq)
525{
526 /* sets main post divider & divider bytes, but does not write them */
527 struct tda18271_priv *priv = fe->tuner_priv;
528 unsigned char *regs = priv->tda18271_regs;
529 u8 d, pd;
530 u32 div;
531
532 int ret = tda18271_lookup_pll_map(fe, MAIN_PLL, &freq, &pd, &d);
533 if (tda_fail(ret))
534 goto fail;
535
536 regs[R_MPD] = (0x7f & pd);
537
538 div = ((d * (freq / 1000)) << 7) / 125;
539
540 regs[R_MD1] = 0x7f & (div >> 16);
541 regs[R_MD2] = 0xff & (div >> 8);
542 regs[R_MD3] = 0xff & div;
543fail:
544 return ret;
545}
546
547int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq)
548{
549 /* sets cal post divider & divider bytes, but does not write them */
550 struct tda18271_priv *priv = fe->tuner_priv;
551 unsigned char *regs = priv->tda18271_regs;
552 u8 d, pd;
553 u32 div;
554
555 int ret = tda18271_lookup_pll_map(fe, CAL_PLL, &freq, &pd, &d);
556 if (tda_fail(ret))
557 goto fail;
558
559 regs[R_CPD] = pd;
560
561 div = ((d * (freq / 1000)) << 7) / 125;
562
563 regs[R_CD1] = 0x7f & (div >> 16);
564 regs[R_CD2] = 0xff & (div >> 8);
565 regs[R_CD3] = 0xff & div;
566fail:
567 return ret;
568}
569
570/*---------------------------------------------------------------------*/
571
572int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq)
573{
574 /* sets bp filter bits, but does not write them */
575 struct tda18271_priv *priv = fe->tuner_priv;
576 unsigned char *regs = priv->tda18271_regs;
577 u8 val;
578
579 int ret = tda18271_lookup_map(fe, BP_FILTER, freq, &val);
580 if (tda_fail(ret))
581 goto fail;
582
583 regs[R_EP1] &= ~0x07; /* clear bp filter bits */
584 regs[R_EP1] |= (0x07 & val);
585fail:
586 return ret;
587}
588
589int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq)
590{
591 /* sets K & M bits, but does not write them */
592 struct tda18271_priv *priv = fe->tuner_priv;
593 unsigned char *regs = priv->tda18271_regs;
594 u8 val;
595
596 int ret = tda18271_lookup_map(fe, RF_CAL_KMCO, freq, &val);
597 if (tda_fail(ret))
598 goto fail;
599
600 regs[R_EB13] &= ~0x7c; /* clear k & m bits */
601 regs[R_EB13] |= (0x7c & val);
602fail:
603 return ret;
604}
605
606int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq)
607{
608 /* sets rf band bits, but does not write them */
609 struct tda18271_priv *priv = fe->tuner_priv;
610 unsigned char *regs = priv->tda18271_regs;
611 u8 val;
612
613 int ret = tda18271_lookup_map(fe, RF_BAND, freq, &val);
614 if (tda_fail(ret))
615 goto fail;
616
617 regs[R_EP2] &= ~0xe0; /* clear rf band bits */
618 regs[R_EP2] |= (0xe0 & (val << 5));
619fail:
620 return ret;
621}
622
623int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq)
624{
625 /* sets gain taper bits, but does not write them */
626 struct tda18271_priv *priv = fe->tuner_priv;
627 unsigned char *regs = priv->tda18271_regs;
628 u8 val;
629
630 int ret = tda18271_lookup_map(fe, GAIN_TAPER, freq, &val);
631 if (tda_fail(ret))
632 goto fail;
633
634 regs[R_EP2] &= ~0x1f; /* clear gain taper bits */
635 regs[R_EP2] |= (0x1f & val);
636fail:
637 return ret;
638}
639
640int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq)
641{
642 /* sets IR Meas bits, but does not write them */
643 struct tda18271_priv *priv = fe->tuner_priv;
644 unsigned char *regs = priv->tda18271_regs;
645 u8 val;
646
647 int ret = tda18271_lookup_map(fe, IR_MEASURE, freq, &val);
648 if (tda_fail(ret))
649 goto fail;
650
651 regs[R_EP5] &= ~0x07;
652 regs[R_EP5] |= (0x07 & val);
653fail:
654 return ret;
655}
656
657int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq)
658{
659 /* sets rf cal byte (RFC_Cprog), but does not write it */
660 struct tda18271_priv *priv = fe->tuner_priv;
661 unsigned char *regs = priv->tda18271_regs;
662 u8 val;
663
664 int ret = tda18271_lookup_map(fe, RF_CAL, freq, &val);
665 /* The TDA18271HD/C1 rf_cal map lookup is expected to go out of range
666 * for frequencies above 61.1 MHz. In these cases, the internal RF
667 * tracking filters calibration mechanism is used.
668 *
669 * There is no need to warn the user about this.
670 */
671 if (ret < 0)
672 goto fail;
673
674 regs[R_EB14] = val;
675fail:
676 return ret;
677}
678
679int _tda_printk(struct tda18271_priv *state, const char *level,
680 const char *func, const char *fmt, ...)
681{
682 struct va_format vaf;
683 va_list args;
684 int rtn;
685
686 va_start(args, fmt);
687
688 vaf.fmt = fmt;
689 vaf.va = &args;
690
691 if (state)
692 rtn = printk("%s%s: [%d-%04x|%c] %pV",
693 level, func, i2c_adapter_id(state->i2c_props.adap),
694 state->i2c_props.addr,
695 (state->role == TDA18271_MASTER) ? 'M' : 'S',
696 &vaf);
697 else
698 rtn = printk("%s%s: %pV", level, func, &vaf);
699
700 va_end(args);
701
702 return rtn;
703}
diff --git a/drivers/media/tuners/tda18271-fe.c b/drivers/media/tuners/tda18271-fe.c
new file mode 100644
index 000000000000..2e67f4459904
--- /dev/null
+++ b/drivers/media/tuners/tda18271-fe.c
@@ -0,0 +1,1345 @@
1/*
2 tda18271-fe.c - driver for the Philips / NXP TDA18271 silicon tuner
3
4 Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include <linux/delay.h>
22#include <linux/videodev2.h>
23#include "tda18271-priv.h"
24
25int tda18271_debug;
26module_param_named(debug, tda18271_debug, int, 0644);
27MODULE_PARM_DESC(debug, "set debug level "
28 "(info=1, map=2, reg=4, adv=8, cal=16 (or-able))");
29
30static int tda18271_cal_on_startup = -1;
31module_param_named(cal, tda18271_cal_on_startup, int, 0644);
32MODULE_PARM_DESC(cal, "perform RF tracking filter calibration on startup");
33
34static DEFINE_MUTEX(tda18271_list_mutex);
35static LIST_HEAD(hybrid_tuner_instance_list);
36
37/*---------------------------------------------------------------------*/
38
39static int tda18271_toggle_output(struct dvb_frontend *fe, int standby)
40{
41 struct tda18271_priv *priv = fe->tuner_priv;
42
43 int ret = tda18271_set_standby_mode(fe, standby ? 1 : 0,
44 priv->output_opt & TDA18271_OUTPUT_LT_OFF ? 1 : 0,
45 priv->output_opt & TDA18271_OUTPUT_XT_OFF ? 1 : 0);
46
47 if (tda_fail(ret))
48 goto fail;
49
50 tda_dbg("%s mode: xtal oscillator %s, slave tuner loop thru %s\n",
51 standby ? "standby" : "active",
52 priv->output_opt & TDA18271_OUTPUT_XT_OFF ? "off" : "on",
53 priv->output_opt & TDA18271_OUTPUT_LT_OFF ? "off" : "on");
54fail:
55 return ret;
56}
57
58/*---------------------------------------------------------------------*/
59
60static inline int charge_pump_source(struct dvb_frontend *fe, int force)
61{
62 struct tda18271_priv *priv = fe->tuner_priv;
63 return tda18271_charge_pump_source(fe,
64 (priv->role == TDA18271_SLAVE) ?
65 TDA18271_CAL_PLL :
66 TDA18271_MAIN_PLL, force);
67}
68
69static inline void tda18271_set_if_notch(struct dvb_frontend *fe)
70{
71 struct tda18271_priv *priv = fe->tuner_priv;
72 unsigned char *regs = priv->tda18271_regs;
73
74 switch (priv->mode) {
75 case TDA18271_ANALOG:
76 regs[R_MPD] &= ~0x80; /* IF notch = 0 */
77 break;
78 case TDA18271_DIGITAL:
79 regs[R_MPD] |= 0x80; /* IF notch = 1 */
80 break;
81 }
82}
83
84static int tda18271_channel_configuration(struct dvb_frontend *fe,
85 struct tda18271_std_map_item *map,
86 u32 freq, u32 bw)
87{
88 struct tda18271_priv *priv = fe->tuner_priv;
89 unsigned char *regs = priv->tda18271_regs;
90 int ret;
91 u32 N;
92
93 /* update TV broadcast parameters */
94
95 /* set standard */
96 regs[R_EP3] &= ~0x1f; /* clear std bits */
97 regs[R_EP3] |= (map->agc_mode << 3) | map->std;
98
99 if (priv->id == TDA18271HDC2) {
100 /* set rfagc to high speed mode */
101 regs[R_EP3] &= ~0x04;
102 }
103
104 /* set cal mode to normal */
105 regs[R_EP4] &= ~0x03;
106
107 /* update IF output level */
108 regs[R_EP4] &= ~0x1c; /* clear if level bits */
109 regs[R_EP4] |= (map->if_lvl << 2);
110
111 /* update FM_RFn */
112 regs[R_EP4] &= ~0x80;
113 regs[R_EP4] |= map->fm_rfn << 7;
114
115 /* update rf top / if top */
116 regs[R_EB22] = 0x00;
117 regs[R_EB22] |= map->rfagc_top;
118 ret = tda18271_write_regs(fe, R_EB22, 1);
119 if (tda_fail(ret))
120 goto fail;
121
122 /* --------------------------------------------------------------- */
123
124 /* disable Power Level Indicator */
125 regs[R_EP1] |= 0x40;
126
127 /* make sure thermometer is off */
128 regs[R_TM] &= ~0x10;
129
130 /* frequency dependent parameters */
131
132 tda18271_calc_ir_measure(fe, &freq);
133
134 tda18271_calc_bp_filter(fe, &freq);
135
136 tda18271_calc_rf_band(fe, &freq);
137
138 tda18271_calc_gain_taper(fe, &freq);
139
140 /* --------------------------------------------------------------- */
141
142 /* dual tuner and agc1 extra configuration */
143
144 switch (priv->role) {
145 case TDA18271_MASTER:
146 regs[R_EB1] |= 0x04; /* main vco */
147 break;
148 case TDA18271_SLAVE:
149 regs[R_EB1] &= ~0x04; /* cal vco */
150 break;
151 }
152
153 /* agc1 always active */
154 regs[R_EB1] &= ~0x02;
155
156 /* agc1 has priority on agc2 */
157 regs[R_EB1] &= ~0x01;
158
159 ret = tda18271_write_regs(fe, R_EB1, 1);
160 if (tda_fail(ret))
161 goto fail;
162
163 /* --------------------------------------------------------------- */
164
165 N = map->if_freq * 1000 + freq;
166
167 switch (priv->role) {
168 case TDA18271_MASTER:
169 tda18271_calc_main_pll(fe, N);
170 tda18271_set_if_notch(fe);
171 tda18271_write_regs(fe, R_MPD, 4);
172 break;
173 case TDA18271_SLAVE:
174 tda18271_calc_cal_pll(fe, N);
175 tda18271_write_regs(fe, R_CPD, 4);
176
177 regs[R_MPD] = regs[R_CPD] & 0x7f;
178 tda18271_set_if_notch(fe);
179 tda18271_write_regs(fe, R_MPD, 1);
180 break;
181 }
182
183 ret = tda18271_write_regs(fe, R_TM, 7);
184 if (tda_fail(ret))
185 goto fail;
186
187 /* force charge pump source */
188 charge_pump_source(fe, 1);
189
190 msleep(1);
191
192 /* return pll to normal operation */
193 charge_pump_source(fe, 0);
194
195 msleep(20);
196
197 if (priv->id == TDA18271HDC2) {
198 /* set rfagc to normal speed mode */
199 if (map->fm_rfn)
200 regs[R_EP3] &= ~0x04;
201 else
202 regs[R_EP3] |= 0x04;
203 ret = tda18271_write_regs(fe, R_EP3, 1);
204 }
205fail:
206 return ret;
207}
208
209static int tda18271_read_thermometer(struct dvb_frontend *fe)
210{
211 struct tda18271_priv *priv = fe->tuner_priv;
212 unsigned char *regs = priv->tda18271_regs;
213 int tm;
214
215 /* switch thermometer on */
216 regs[R_TM] |= 0x10;
217 tda18271_write_regs(fe, R_TM, 1);
218
219 /* read thermometer info */
220 tda18271_read_regs(fe);
221
222 if ((((regs[R_TM] & 0x0f) == 0x00) && ((regs[R_TM] & 0x20) == 0x20)) ||
223 (((regs[R_TM] & 0x0f) == 0x08) && ((regs[R_TM] & 0x20) == 0x00))) {
224
225 if ((regs[R_TM] & 0x20) == 0x20)
226 regs[R_TM] &= ~0x20;
227 else
228 regs[R_TM] |= 0x20;
229
230 tda18271_write_regs(fe, R_TM, 1);
231
232 msleep(10); /* temperature sensing */
233
234 /* read thermometer info */
235 tda18271_read_regs(fe);
236 }
237
238 tm = tda18271_lookup_thermometer(fe);
239
240 /* switch thermometer off */
241 regs[R_TM] &= ~0x10;
242 tda18271_write_regs(fe, R_TM, 1);
243
244 /* set CAL mode to normal */
245 regs[R_EP4] &= ~0x03;
246 tda18271_write_regs(fe, R_EP4, 1);
247
248 return tm;
249}
250
251/* ------------------------------------------------------------------ */
252
253static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
254 u32 freq)
255{
256 struct tda18271_priv *priv = fe->tuner_priv;
257 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
258 unsigned char *regs = priv->tda18271_regs;
259 int i, ret;
260 u8 tm_current, dc_over_dt, rf_tab;
261 s32 rfcal_comp, approx;
262
263 /* power up */
264 ret = tda18271_set_standby_mode(fe, 0, 0, 0);
265 if (tda_fail(ret))
266 goto fail;
267
268 /* read die current temperature */
269 tm_current = tda18271_read_thermometer(fe);
270
271 /* frequency dependent parameters */
272
273 tda18271_calc_rf_cal(fe, &freq);
274 rf_tab = regs[R_EB14];
275
276 i = tda18271_lookup_rf_band(fe, &freq, NULL);
277 if (tda_fail(i))
278 return i;
279
280 if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
281 approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) +
282 map[i].rf_b1 + rf_tab;
283 } else {
284 approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) +
285 map[i].rf_b2 + rf_tab;
286 }
287
288 if (approx < 0)
289 approx = 0;
290 if (approx > 255)
291 approx = 255;
292
293 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
294
295 /* calculate temperature compensation */
296 rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000;
297
298 regs[R_EB14] = (unsigned char)(approx + rfcal_comp);
299 ret = tda18271_write_regs(fe, R_EB14, 1);
300fail:
301 return ret;
302}
303
304static int tda18271_por(struct dvb_frontend *fe)
305{
306 struct tda18271_priv *priv = fe->tuner_priv;
307 unsigned char *regs = priv->tda18271_regs;
308 int ret;
309
310 /* power up detector 1 */
311 regs[R_EB12] &= ~0x20;
312 ret = tda18271_write_regs(fe, R_EB12, 1);
313 if (tda_fail(ret))
314 goto fail;
315
316 regs[R_EB18] &= ~0x80; /* turn agc1 loop on */
317 regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */
318 ret = tda18271_write_regs(fe, R_EB18, 1);
319 if (tda_fail(ret))
320 goto fail;
321
322 regs[R_EB21] |= 0x03; /* set agc2_gain to -6 dB */
323
324 /* POR mode */
325 ret = tda18271_set_standby_mode(fe, 1, 0, 0);
326 if (tda_fail(ret))
327 goto fail;
328
329 /* disable 1.5 MHz low pass filter */
330 regs[R_EB23] &= ~0x04; /* forcelp_fc2_en = 0 */
331 regs[R_EB23] &= ~0x02; /* XXX: lp_fc[2] = 0 */
332 ret = tda18271_write_regs(fe, R_EB21, 3);
333fail:
334 return ret;
335}
336
337static int tda18271_calibrate_rf(struct dvb_frontend *fe, u32 freq)
338{
339 struct tda18271_priv *priv = fe->tuner_priv;
340 unsigned char *regs = priv->tda18271_regs;
341 u32 N;
342
343 /* set CAL mode to normal */
344 regs[R_EP4] &= ~0x03;
345 tda18271_write_regs(fe, R_EP4, 1);
346
347 /* switch off agc1 */
348 regs[R_EP3] |= 0x40; /* sm_lt = 1 */
349
350 regs[R_EB18] |= 0x03; /* set agc1_gain to 15 dB */
351 tda18271_write_regs(fe, R_EB18, 1);
352
353 /* frequency dependent parameters */
354
355 tda18271_calc_bp_filter(fe, &freq);
356 tda18271_calc_gain_taper(fe, &freq);
357 tda18271_calc_rf_band(fe, &freq);
358 tda18271_calc_km(fe, &freq);
359
360 tda18271_write_regs(fe, R_EP1, 3);
361 tda18271_write_regs(fe, R_EB13, 1);
362
363 /* main pll charge pump source */
364 tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 1);
365
366 /* cal pll charge pump source */
367 tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 1);
368
369 /* force dcdc converter to 0 V */
370 regs[R_EB14] = 0x00;
371 tda18271_write_regs(fe, R_EB14, 1);
372
373 /* disable plls lock */
374 regs[R_EB20] &= ~0x20;
375 tda18271_write_regs(fe, R_EB20, 1);
376
377 /* set CAL mode to RF tracking filter calibration */
378 regs[R_EP4] |= 0x03;
379 tda18271_write_regs(fe, R_EP4, 2);
380
381 /* --------------------------------------------------------------- */
382
383 /* set the internal calibration signal */
384 N = freq;
385
386 tda18271_calc_cal_pll(fe, N);
387 tda18271_write_regs(fe, R_CPD, 4);
388
389 /* downconvert internal calibration */
390 N += 1000000;
391
392 tda18271_calc_main_pll(fe, N);
393 tda18271_write_regs(fe, R_MPD, 4);
394
395 msleep(5);
396
397 tda18271_write_regs(fe, R_EP2, 1);
398 tda18271_write_regs(fe, R_EP1, 1);
399 tda18271_write_regs(fe, R_EP2, 1);
400 tda18271_write_regs(fe, R_EP1, 1);
401
402 /* --------------------------------------------------------------- */
403
404 /* normal operation for the main pll */
405 tda18271_charge_pump_source(fe, TDA18271_MAIN_PLL, 0);
406
407 /* normal operation for the cal pll */
408 tda18271_charge_pump_source(fe, TDA18271_CAL_PLL, 0);
409
410 msleep(10); /* plls locking */
411
412 /* launch the rf tracking filters calibration */
413 regs[R_EB20] |= 0x20;
414 tda18271_write_regs(fe, R_EB20, 1);
415
416 msleep(60); /* calibration */
417
418 /* --------------------------------------------------------------- */
419
420 /* set CAL mode to normal */
421 regs[R_EP4] &= ~0x03;
422
423 /* switch on agc1 */
424 regs[R_EP3] &= ~0x40; /* sm_lt = 0 */
425
426 regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */
427 tda18271_write_regs(fe, R_EB18, 1);
428
429 tda18271_write_regs(fe, R_EP3, 2);
430
431 /* synchronization */
432 tda18271_write_regs(fe, R_EP1, 1);
433
434 /* get calibration result */
435 tda18271_read_extended(fe);
436
437 return regs[R_EB14];
438}
439
440static int tda18271_powerscan(struct dvb_frontend *fe,
441 u32 *freq_in, u32 *freq_out)
442{
443 struct tda18271_priv *priv = fe->tuner_priv;
444 unsigned char *regs = priv->tda18271_regs;
445 int sgn, bcal, count, wait, ret;
446 u8 cid_target;
447 u16 count_limit;
448 u32 freq;
449
450 freq = *freq_in;
451
452 tda18271_calc_rf_band(fe, &freq);
453 tda18271_calc_rf_cal(fe, &freq);
454 tda18271_calc_gain_taper(fe, &freq);
455 tda18271_lookup_cid_target(fe, &freq, &cid_target, &count_limit);
456
457 tda18271_write_regs(fe, R_EP2, 1);
458 tda18271_write_regs(fe, R_EB14, 1);
459
460 /* downconvert frequency */
461 freq += 1000000;
462
463 tda18271_calc_main_pll(fe, freq);
464 tda18271_write_regs(fe, R_MPD, 4);
465
466 msleep(5); /* pll locking */
467
468 /* detection mode */
469 regs[R_EP4] &= ~0x03;
470 regs[R_EP4] |= 0x01;
471 tda18271_write_regs(fe, R_EP4, 1);
472
473 /* launch power detection measurement */
474 tda18271_write_regs(fe, R_EP2, 1);
475
476 /* read power detection info, stored in EB10 */
477 ret = tda18271_read_extended(fe);
478 if (tda_fail(ret))
479 return ret;
480
481 /* algorithm initialization */
482 sgn = 1;
483 *freq_out = *freq_in;
484 bcal = 0;
485 count = 0;
486 wait = false;
487
488 while ((regs[R_EB10] & 0x3f) < cid_target) {
489 /* downconvert updated freq to 1 MHz */
490 freq = *freq_in + (sgn * count) + 1000000;
491
492 tda18271_calc_main_pll(fe, freq);
493 tda18271_write_regs(fe, R_MPD, 4);
494
495 if (wait) {
496 msleep(5); /* pll locking */
497 wait = false;
498 } else
499 udelay(100); /* pll locking */
500
501 /* launch power detection measurement */
502 tda18271_write_regs(fe, R_EP2, 1);
503
504 /* read power detection info, stored in EB10 */
505 ret = tda18271_read_extended(fe);
506 if (tda_fail(ret))
507 return ret;
508
509 count += 200;
510
511 if (count <= count_limit)
512 continue;
513
514 if (sgn <= 0)
515 break;
516
517 sgn = -1 * sgn;
518 count = 200;
519 wait = true;
520 }
521
522 if ((regs[R_EB10] & 0x3f) >= cid_target) {
523 bcal = 1;
524 *freq_out = freq - 1000000;
525 } else
526 bcal = 0;
527
528 tda_cal("bcal = %d, freq_in = %d, freq_out = %d (freq = %d)\n",
529 bcal, *freq_in, *freq_out, freq);
530
531 return bcal;
532}
533
534static int tda18271_powerscan_init(struct dvb_frontend *fe)
535{
536 struct tda18271_priv *priv = fe->tuner_priv;
537 unsigned char *regs = priv->tda18271_regs;
538 int ret;
539
540 /* set standard to digital */
541 regs[R_EP3] &= ~0x1f; /* clear std bits */
542 regs[R_EP3] |= 0x12;
543
544 /* set cal mode to normal */
545 regs[R_EP4] &= ~0x03;
546
547 /* update IF output level */
548 regs[R_EP4] &= ~0x1c; /* clear if level bits */
549
550 ret = tda18271_write_regs(fe, R_EP3, 2);
551 if (tda_fail(ret))
552 goto fail;
553
554 regs[R_EB18] &= ~0x03; /* set agc1_gain to 6 dB */
555 ret = tda18271_write_regs(fe, R_EB18, 1);
556 if (tda_fail(ret))
557 goto fail;
558
559 regs[R_EB21] &= ~0x03; /* set agc2_gain to -15 dB */
560
561 /* 1.5 MHz low pass filter */
562 regs[R_EB23] |= 0x04; /* forcelp_fc2_en = 1 */
563 regs[R_EB23] |= 0x02; /* lp_fc[2] = 1 */
564
565 ret = tda18271_write_regs(fe, R_EB21, 3);
566fail:
567 return ret;
568}
569
570static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
571{
572 struct tda18271_priv *priv = fe->tuner_priv;
573 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
574 unsigned char *regs = priv->tda18271_regs;
575 int bcal, rf, i;
576 s32 divisor, dividend;
577#define RF1 0
578#define RF2 1
579#define RF3 2
580 u32 rf_default[3];
581 u32 rf_freq[3];
582 s32 prog_cal[3];
583 s32 prog_tab[3];
584
585 i = tda18271_lookup_rf_band(fe, &freq, NULL);
586
587 if (tda_fail(i))
588 return i;
589
590 rf_default[RF1] = 1000 * map[i].rf1_def;
591 rf_default[RF2] = 1000 * map[i].rf2_def;
592 rf_default[RF3] = 1000 * map[i].rf3_def;
593
594 for (rf = RF1; rf <= RF3; rf++) {
595 if (0 == rf_default[rf])
596 return 0;
597 tda_cal("freq = %d, rf = %d\n", freq, rf);
598
599 /* look for optimized calibration frequency */
600 bcal = tda18271_powerscan(fe, &rf_default[rf], &rf_freq[rf]);
601 if (tda_fail(bcal))
602 return bcal;
603
604 tda18271_calc_rf_cal(fe, &rf_freq[rf]);
605 prog_tab[rf] = (s32)regs[R_EB14];
606
607 if (1 == bcal)
608 prog_cal[rf] =
609 (s32)tda18271_calibrate_rf(fe, rf_freq[rf]);
610 else
611 prog_cal[rf] = prog_tab[rf];
612
613 switch (rf) {
614 case RF1:
615 map[i].rf_a1 = 0;
616 map[i].rf_b1 = (prog_cal[RF1] - prog_tab[RF1]);
617 map[i].rf1 = rf_freq[RF1] / 1000;
618 break;
619 case RF2:
620 dividend = (prog_cal[RF2] - prog_tab[RF2] -
621 prog_cal[RF1] + prog_tab[RF1]);
622 divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;
623 map[i].rf_a1 = (dividend / divisor);
624 map[i].rf2 = rf_freq[RF2] / 1000;
625 break;
626 case RF3:
627 dividend = (prog_cal[RF3] - prog_tab[RF3] -
628 prog_cal[RF2] + prog_tab[RF2]);
629 divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;
630 map[i].rf_a2 = (dividend / divisor);
631 map[i].rf_b2 = (prog_cal[RF2] - prog_tab[RF2]);
632 map[i].rf3 = rf_freq[RF3] / 1000;
633 break;
634 default:
635 BUG();
636 }
637 }
638
639 return 0;
640}
641
642static int tda18271_calc_rf_filter_curve(struct dvb_frontend *fe)
643{
644 struct tda18271_priv *priv = fe->tuner_priv;
645 unsigned int i;
646 int ret;
647
648 tda_info("tda18271: performing RF tracking filter calibration\n");
649
650 /* wait for die temperature stabilization */
651 msleep(200);
652
653 ret = tda18271_powerscan_init(fe);
654 if (tda_fail(ret))
655 goto fail;
656
657 /* rf band calibration */
658 for (i = 0; priv->rf_cal_state[i].rfmax != 0; i++) {
659 ret =
660 tda18271_rf_tracking_filters_init(fe, 1000 *
661 priv->rf_cal_state[i].rfmax);
662 if (tda_fail(ret))
663 goto fail;
664 }
665
666 priv->tm_rfcal = tda18271_read_thermometer(fe);
667fail:
668 return ret;
669}
670
671/* ------------------------------------------------------------------ */
672
673static int tda18271c2_rf_cal_init(struct dvb_frontend *fe)
674{
675 struct tda18271_priv *priv = fe->tuner_priv;
676 unsigned char *regs = priv->tda18271_regs;
677 int ret;
678
679 /* test RF_CAL_OK to see if we need init */
680 if ((regs[R_EP1] & 0x10) == 0)
681 priv->cal_initialized = false;
682
683 if (priv->cal_initialized)
684 return 0;
685
686 ret = tda18271_calc_rf_filter_curve(fe);
687 if (tda_fail(ret))
688 goto fail;
689
690 ret = tda18271_por(fe);
691 if (tda_fail(ret))
692 goto fail;
693
694 tda_info("tda18271: RF tracking filter calibration complete\n");
695
696 priv->cal_initialized = true;
697 goto end;
698fail:
699 tda_info("tda18271: RF tracking filter calibration failed!\n");
700end:
701 return ret;
702}
703
704static int tda18271c1_rf_tracking_filter_calibration(struct dvb_frontend *fe,
705 u32 freq, u32 bw)
706{
707 struct tda18271_priv *priv = fe->tuner_priv;
708 unsigned char *regs = priv->tda18271_regs;
709 int ret;
710 u32 N = 0;
711
712 /* calculate bp filter */
713 tda18271_calc_bp_filter(fe, &freq);
714 tda18271_write_regs(fe, R_EP1, 1);
715
716 regs[R_EB4] &= 0x07;
717 regs[R_EB4] |= 0x60;
718 tda18271_write_regs(fe, R_EB4, 1);
719
720 regs[R_EB7] = 0x60;
721 tda18271_write_regs(fe, R_EB7, 1);
722
723 regs[R_EB14] = 0x00;
724 tda18271_write_regs(fe, R_EB14, 1);
725
726 regs[R_EB20] = 0xcc;
727 tda18271_write_regs(fe, R_EB20, 1);
728
729 /* set cal mode to RF tracking filter calibration */
730 regs[R_EP4] |= 0x03;
731
732 /* calculate cal pll */
733
734 switch (priv->mode) {
735 case TDA18271_ANALOG:
736 N = freq - 1250000;
737 break;
738 case TDA18271_DIGITAL:
739 N = freq + bw / 2;
740 break;
741 }
742
743 tda18271_calc_cal_pll(fe, N);
744
745 /* calculate main pll */
746
747 switch (priv->mode) {
748 case TDA18271_ANALOG:
749 N = freq - 250000;
750 break;
751 case TDA18271_DIGITAL:
752 N = freq + bw / 2 + 1000000;
753 break;
754 }
755
756 tda18271_calc_main_pll(fe, N);
757
758 ret = tda18271_write_regs(fe, R_EP3, 11);
759 if (tda_fail(ret))
760 return ret;
761
762 msleep(5); /* RF tracking filter calibration initialization */
763
764 /* search for K,M,CO for RF calibration */
765 tda18271_calc_km(fe, &freq);
766 tda18271_write_regs(fe, R_EB13, 1);
767
768 /* search for rf band */
769 tda18271_calc_rf_band(fe, &freq);
770
771 /* search for gain taper */
772 tda18271_calc_gain_taper(fe, &freq);
773
774 tda18271_write_regs(fe, R_EP2, 1);
775 tda18271_write_regs(fe, R_EP1, 1);
776 tda18271_write_regs(fe, R_EP2, 1);
777 tda18271_write_regs(fe, R_EP1, 1);
778
779 regs[R_EB4] &= 0x07;
780 regs[R_EB4] |= 0x40;
781 tda18271_write_regs(fe, R_EB4, 1);
782
783 regs[R_EB7] = 0x40;
784 tda18271_write_regs(fe, R_EB7, 1);
785 msleep(10); /* pll locking */
786
787 regs[R_EB20] = 0xec;
788 tda18271_write_regs(fe, R_EB20, 1);
789 msleep(60); /* RF tracking filter calibration completion */
790
791 regs[R_EP4] &= ~0x03; /* set cal mode to normal */
792 tda18271_write_regs(fe, R_EP4, 1);
793
794 tda18271_write_regs(fe, R_EP1, 1);
795
796 /* RF tracking filter correction for VHF_Low band */
797 if (0 == tda18271_calc_rf_cal(fe, &freq))
798 tda18271_write_regs(fe, R_EB14, 1);
799
800 return 0;
801}
802
803/* ------------------------------------------------------------------ */
804
805static int tda18271_ir_cal_init(struct dvb_frontend *fe)
806{
807 struct tda18271_priv *priv = fe->tuner_priv;
808 unsigned char *regs = priv->tda18271_regs;
809 int ret;
810
811 ret = tda18271_read_regs(fe);
812 if (tda_fail(ret))
813 goto fail;
814
815 /* test IR_CAL_OK to see if we need init */
816 if ((regs[R_EP1] & 0x08) == 0)
817 ret = tda18271_init_regs(fe);
818fail:
819 return ret;
820}
821
822static int tda18271_init(struct dvb_frontend *fe)
823{
824 struct tda18271_priv *priv = fe->tuner_priv;
825 int ret;
826
827 mutex_lock(&priv->lock);
828
829 /* full power up */
830 ret = tda18271_set_standby_mode(fe, 0, 0, 0);
831 if (tda_fail(ret))
832 goto fail;
833
834 /* initialization */
835 ret = tda18271_ir_cal_init(fe);
836 if (tda_fail(ret))
837 goto fail;
838
839 if (priv->id == TDA18271HDC2)
840 tda18271c2_rf_cal_init(fe);
841fail:
842 mutex_unlock(&priv->lock);
843
844 return ret;
845}
846
847static int tda18271_sleep(struct dvb_frontend *fe)
848{
849 struct tda18271_priv *priv = fe->tuner_priv;
850 int ret;
851
852 mutex_lock(&priv->lock);
853
854 /* enter standby mode, with required output features enabled */
855 ret = tda18271_toggle_output(fe, 1);
856
857 mutex_unlock(&priv->lock);
858
859 return ret;
860}
861
862/* ------------------------------------------------------------------ */
863
864static int tda18271_agc(struct dvb_frontend *fe)
865{
866 struct tda18271_priv *priv = fe->tuner_priv;
867 int ret = 0;
868
869 switch (priv->config) {
870 case 0:
871 /* no external agc configuration required */
872 if (tda18271_debug & DBG_ADV)
873 tda_dbg("no agc configuration provided\n");
874 break;
875 case 3:
876 /* switch with GPIO of saa713x */
877 tda_dbg("invoking callback\n");
878 if (fe->callback)
879 ret = fe->callback(priv->i2c_props.adap->algo_data,
880 DVB_FRONTEND_COMPONENT_TUNER,
881 TDA18271_CALLBACK_CMD_AGC_ENABLE,
882 priv->mode);
883 break;
884 case 1:
885 case 2:
886 default:
887 /* n/a - currently not supported */
888 tda_err("unsupported configuration: %d\n", priv->config);
889 ret = -EINVAL;
890 break;
891 }
892 return ret;
893}
894
895static int tda18271_tune(struct dvb_frontend *fe,
896 struct tda18271_std_map_item *map, u32 freq, u32 bw)
897{
898 struct tda18271_priv *priv = fe->tuner_priv;
899 int ret;
900
901 tda_dbg("freq = %d, ifc = %d, bw = %d, agc_mode = %d, std = %d\n",
902 freq, map->if_freq, bw, map->agc_mode, map->std);
903
904 ret = tda18271_agc(fe);
905 if (tda_fail(ret))
906 tda_warn("failed to configure agc\n");
907
908 ret = tda18271_init(fe);
909 if (tda_fail(ret))
910 goto fail;
911
912 mutex_lock(&priv->lock);
913
914 switch (priv->id) {
915 case TDA18271HDC1:
916 tda18271c1_rf_tracking_filter_calibration(fe, freq, bw);
917 break;
918 case TDA18271HDC2:
919 tda18271c2_rf_tracking_filters_correction(fe, freq);
920 break;
921 }
922 ret = tda18271_channel_configuration(fe, map, freq, bw);
923
924 mutex_unlock(&priv->lock);
925fail:
926 return ret;
927}
928
929/* ------------------------------------------------------------------ */
930
931static int tda18271_set_params(struct dvb_frontend *fe)
932{
933 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
934 u32 delsys = c->delivery_system;
935 u32 bw = c->bandwidth_hz;
936 u32 freq = c->frequency;
937 struct tda18271_priv *priv = fe->tuner_priv;
938 struct tda18271_std_map *std_map = &priv->std;
939 struct tda18271_std_map_item *map;
940 int ret;
941
942 priv->mode = TDA18271_DIGITAL;
943
944 switch (delsys) {
945 case SYS_ATSC:
946 map = &std_map->atsc_6;
947 bw = 6000000;
948 break;
949 case SYS_ISDBT:
950 case SYS_DVBT:
951 case SYS_DVBT2:
952 if (bw <= 6000000) {
953 map = &std_map->dvbt_6;
954 } else if (bw <= 7000000) {
955 map = &std_map->dvbt_7;
956 } else {
957 map = &std_map->dvbt_8;
958 }
959 break;
960 case SYS_DVBC_ANNEX_B:
961 bw = 6000000;
962 /* falltrough */
963 case SYS_DVBC_ANNEX_A:
964 case SYS_DVBC_ANNEX_C:
965 if (bw <= 6000000) {
966 map = &std_map->qam_6;
967 } else if (bw <= 7000000) {
968 map = &std_map->qam_7;
969 } else {
970 map = &std_map->qam_8;
971 }
972 break;
973 default:
974 tda_warn("modulation type not supported!\n");
975 return -EINVAL;
976 }
977
978 /* When tuning digital, the analog demod must be tri-stated */
979 if (fe->ops.analog_ops.standby)
980 fe->ops.analog_ops.standby(fe);
981
982 ret = tda18271_tune(fe, map, freq, bw);
983
984 if (tda_fail(ret))
985 goto fail;
986
987 priv->if_freq = map->if_freq;
988 priv->frequency = freq;
989 priv->bandwidth = bw;
990fail:
991 return ret;
992}
993
994static int tda18271_set_analog_params(struct dvb_frontend *fe,
995 struct analog_parameters *params)
996{
997 struct tda18271_priv *priv = fe->tuner_priv;
998 struct tda18271_std_map *std_map = &priv->std;
999 struct tda18271_std_map_item *map;
1000 char *mode;
1001 int ret;
1002 u32 freq = params->frequency * 125 *
1003 ((params->mode == V4L2_TUNER_RADIO) ? 1 : 1000) / 2;
1004
1005 priv->mode = TDA18271_ANALOG;
1006
1007 if (params->mode == V4L2_TUNER_RADIO) {
1008 map = &std_map->fm_radio;
1009 mode = "fm";
1010 } else if (params->std & V4L2_STD_MN) {
1011 map = &std_map->atv_mn;
1012 mode = "MN";
1013 } else if (params->std & V4L2_STD_B) {
1014 map = &std_map->atv_b;
1015 mode = "B";
1016 } else if (params->std & V4L2_STD_GH) {
1017 map = &std_map->atv_gh;
1018 mode = "GH";
1019 } else if (params->std & V4L2_STD_PAL_I) {
1020 map = &std_map->atv_i;
1021 mode = "I";
1022 } else if (params->std & V4L2_STD_DK) {
1023 map = &std_map->atv_dk;
1024 mode = "DK";
1025 } else if (params->std & V4L2_STD_SECAM_L) {
1026 map = &std_map->atv_l;
1027 mode = "L";
1028 } else if (params->std & V4L2_STD_SECAM_LC) {
1029 map = &std_map->atv_lc;
1030 mode = "L'";
1031 } else {
1032 map = &std_map->atv_i;
1033 mode = "xx";
1034 }
1035
1036 tda_dbg("setting tda18271 to system %s\n", mode);
1037
1038 ret = tda18271_tune(fe, map, freq, 0);
1039
1040 if (tda_fail(ret))
1041 goto fail;
1042
1043 priv->if_freq = map->if_freq;
1044 priv->frequency = freq;
1045 priv->bandwidth = 0;
1046fail:
1047 return ret;
1048}
1049
1050static int tda18271_release(struct dvb_frontend *fe)
1051{
1052 struct tda18271_priv *priv = fe->tuner_priv;
1053
1054 mutex_lock(&tda18271_list_mutex);
1055
1056 if (priv)
1057 hybrid_tuner_release_state(priv);
1058
1059 mutex_unlock(&tda18271_list_mutex);
1060
1061 fe->tuner_priv = NULL;
1062
1063 return 0;
1064}
1065
1066static int tda18271_get_frequency(struct dvb_frontend *fe, u32 *frequency)
1067{
1068 struct tda18271_priv *priv = fe->tuner_priv;
1069 *frequency = priv->frequency;
1070 return 0;
1071}
1072
1073static int tda18271_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
1074{
1075 struct tda18271_priv *priv = fe->tuner_priv;
1076 *bandwidth = priv->bandwidth;
1077 return 0;
1078}
1079
1080static int tda18271_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
1081{
1082 struct tda18271_priv *priv = fe->tuner_priv;
1083 *frequency = (u32)priv->if_freq * 1000;
1084 return 0;
1085}
1086
1087/* ------------------------------------------------------------------ */
1088
1089#define tda18271_update_std(std_cfg, name) do { \
1090 if (map->std_cfg.if_freq + \
1091 map->std_cfg.agc_mode + map->std_cfg.std + \
1092 map->std_cfg.if_lvl + map->std_cfg.rfagc_top > 0) { \
1093 tda_dbg("Using custom std config for %s\n", name); \
1094 memcpy(&std->std_cfg, &map->std_cfg, \
1095 sizeof(struct tda18271_std_map_item)); \
1096 } } while (0)
1097
1098#define tda18271_dump_std_item(std_cfg, name) do { \
1099 tda_dbg("(%s) if_freq = %d, agc_mode = %d, std = %d, " \
1100 "if_lvl = %d, rfagc_top = 0x%02x\n", \
1101 name, std->std_cfg.if_freq, \
1102 std->std_cfg.agc_mode, std->std_cfg.std, \
1103 std->std_cfg.if_lvl, std->std_cfg.rfagc_top); \
1104 } while (0)
1105
1106static int tda18271_dump_std_map(struct dvb_frontend *fe)
1107{
1108 struct tda18271_priv *priv = fe->tuner_priv;
1109 struct tda18271_std_map *std = &priv->std;
1110
1111 tda_dbg("========== STANDARD MAP SETTINGS ==========\n");
1112 tda18271_dump_std_item(fm_radio, " fm ");
1113 tda18271_dump_std_item(atv_b, "atv b ");
1114 tda18271_dump_std_item(atv_dk, "atv dk");
1115 tda18271_dump_std_item(atv_gh, "atv gh");
1116 tda18271_dump_std_item(atv_i, "atv i ");
1117 tda18271_dump_std_item(atv_l, "atv l ");
1118 tda18271_dump_std_item(atv_lc, "atv l'");
1119 tda18271_dump_std_item(atv_mn, "atv mn");
1120 tda18271_dump_std_item(atsc_6, "atsc 6");
1121 tda18271_dump_std_item(dvbt_6, "dvbt 6");
1122 tda18271_dump_std_item(dvbt_7, "dvbt 7");
1123 tda18271_dump_std_item(dvbt_8, "dvbt 8");
1124 tda18271_dump_std_item(qam_6, "qam 6 ");
1125 tda18271_dump_std_item(qam_8, "qam 8 ");
1126
1127 return 0;
1128}
1129
1130static int tda18271_update_std_map(struct dvb_frontend *fe,
1131 struct tda18271_std_map *map)
1132{
1133 struct tda18271_priv *priv = fe->tuner_priv;
1134 struct tda18271_std_map *std = &priv->std;
1135
1136 if (!map)
1137 return -EINVAL;
1138
1139 tda18271_update_std(fm_radio, "fm");
1140 tda18271_update_std(atv_b, "atv b");
1141 tda18271_update_std(atv_dk, "atv dk");
1142 tda18271_update_std(atv_gh, "atv gh");
1143 tda18271_update_std(atv_i, "atv i");
1144 tda18271_update_std(atv_l, "atv l");
1145 tda18271_update_std(atv_lc, "atv l'");
1146 tda18271_update_std(atv_mn, "atv mn");
1147 tda18271_update_std(atsc_6, "atsc 6");
1148 tda18271_update_std(dvbt_6, "dvbt 6");
1149 tda18271_update_std(dvbt_7, "dvbt 7");
1150 tda18271_update_std(dvbt_8, "dvbt 8");
1151 tda18271_update_std(qam_6, "qam 6");
1152 tda18271_update_std(qam_8, "qam 8");
1153
1154 return 0;
1155}
1156
1157static int tda18271_get_id(struct dvb_frontend *fe)
1158{
1159 struct tda18271_priv *priv = fe->tuner_priv;
1160 unsigned char *regs = priv->tda18271_regs;
1161 char *name;
1162
1163 mutex_lock(&priv->lock);
1164 tda18271_read_regs(fe);
1165 mutex_unlock(&priv->lock);
1166
1167 switch (regs[R_ID] & 0x7f) {
1168 case 3:
1169 name = "TDA18271HD/C1";
1170 priv->id = TDA18271HDC1;
1171 break;
1172 case 4:
1173 name = "TDA18271HD/C2";
1174 priv->id = TDA18271HDC2;
1175 break;
1176 default:
1177 tda_info("Unknown device (%i) detected @ %d-%04x, device not supported.\n",
1178 regs[R_ID], i2c_adapter_id(priv->i2c_props.adap),
1179 priv->i2c_props.addr);
1180 return -EINVAL;
1181 }
1182
1183 tda_info("%s detected @ %d-%04x\n", name,
1184 i2c_adapter_id(priv->i2c_props.adap), priv->i2c_props.addr);
1185
1186 return 0;
1187}
1188
1189static int tda18271_setup_configuration(struct dvb_frontend *fe,
1190 struct tda18271_config *cfg)
1191{
1192 struct tda18271_priv *priv = fe->tuner_priv;
1193
1194 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
1195 priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
1196 priv->config = (cfg) ? cfg->config : 0;
1197 priv->small_i2c = (cfg) ?
1198 cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT;
1199 priv->output_opt = (cfg) ?
1200 cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
1201
1202 return 0;
1203}
1204
1205static inline int tda18271_need_cal_on_startup(struct tda18271_config *cfg)
1206{
1207 /* tda18271_cal_on_startup == -1 when cal module option is unset */
1208 return ((tda18271_cal_on_startup == -1) ?
1209 /* honor configuration setting */
1210 ((cfg) && (cfg->rf_cal_on_startup)) :
1211 /* module option overrides configuration setting */
1212 (tda18271_cal_on_startup)) ? 1 : 0;
1213}
1214
1215static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)
1216{
1217 struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg;
1218
1219 tda18271_setup_configuration(fe, cfg);
1220
1221 if (tda18271_need_cal_on_startup(cfg))
1222 tda18271_init(fe);
1223
1224 /* override default std map with values in config struct */
1225 if ((cfg) && (cfg->std_map))
1226 tda18271_update_std_map(fe, cfg->std_map);
1227
1228 return 0;
1229}
1230
1231static const struct dvb_tuner_ops tda18271_tuner_ops = {
1232 .info = {
1233 .name = "NXP TDA18271HD",
1234 .frequency_min = 45000000,
1235 .frequency_max = 864000000,
1236 .frequency_step = 62500
1237 },
1238 .init = tda18271_init,
1239 .sleep = tda18271_sleep,
1240 .set_params = tda18271_set_params,
1241 .set_analog_params = tda18271_set_analog_params,
1242 .release = tda18271_release,
1243 .set_config = tda18271_set_config,
1244 .get_frequency = tda18271_get_frequency,
1245 .get_bandwidth = tda18271_get_bandwidth,
1246 .get_if_frequency = tda18271_get_if_frequency,
1247};
1248
1249struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1250 struct i2c_adapter *i2c,
1251 struct tda18271_config *cfg)
1252{
1253 struct tda18271_priv *priv = NULL;
1254 int instance, ret;
1255
1256 mutex_lock(&tda18271_list_mutex);
1257
1258 instance = hybrid_tuner_request_state(struct tda18271_priv, priv,
1259 hybrid_tuner_instance_list,
1260 i2c, addr, "tda18271");
1261 switch (instance) {
1262 case 0:
1263 goto fail;
1264 case 1:
1265 /* new tuner instance */
1266 fe->tuner_priv = priv;
1267
1268 tda18271_setup_configuration(fe, cfg);
1269
1270 priv->cal_initialized = false;
1271 mutex_init(&priv->lock);
1272
1273 ret = tda18271_get_id(fe);
1274 if (tda_fail(ret))
1275 goto fail;
1276
1277 ret = tda18271_assign_map_layout(fe);
1278 if (tda_fail(ret))
1279 goto fail;
1280
1281 mutex_lock(&priv->lock);
1282 tda18271_init_regs(fe);
1283
1284 if ((tda18271_need_cal_on_startup(cfg)) &&
1285 (priv->id == TDA18271HDC2))
1286 tda18271c2_rf_cal_init(fe);
1287
1288 mutex_unlock(&priv->lock);
1289 break;
1290 default:
1291 /* existing tuner instance */
1292 fe->tuner_priv = priv;
1293
1294 /* allow dvb driver to override configuration settings */
1295 if (cfg) {
1296 if (cfg->gate != TDA18271_GATE_ANALOG)
1297 priv->gate = cfg->gate;
1298 if (cfg->role)
1299 priv->role = cfg->role;
1300 if (cfg->config)
1301 priv->config = cfg->config;
1302 if (cfg->small_i2c)
1303 priv->small_i2c = cfg->small_i2c;
1304 if (cfg->output_opt)
1305 priv->output_opt = cfg->output_opt;
1306 if (cfg->std_map)
1307 tda18271_update_std_map(fe, cfg->std_map);
1308 }
1309 if (tda18271_need_cal_on_startup(cfg))
1310 tda18271_init(fe);
1311 break;
1312 }
1313
1314 /* override default std map with values in config struct */
1315 if ((cfg) && (cfg->std_map))
1316 tda18271_update_std_map(fe, cfg->std_map);
1317
1318 mutex_unlock(&tda18271_list_mutex);
1319
1320 memcpy(&fe->ops.tuner_ops, &tda18271_tuner_ops,
1321 sizeof(struct dvb_tuner_ops));
1322
1323 if (tda18271_debug & (DBG_MAP | DBG_ADV))
1324 tda18271_dump_std_map(fe);
1325
1326 return fe;
1327fail:
1328 mutex_unlock(&tda18271_list_mutex);
1329
1330 tda18271_release(fe);
1331 return NULL;
1332}
1333EXPORT_SYMBOL_GPL(tda18271_attach);
1334MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");
1335MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
1336MODULE_LICENSE("GPL");
1337MODULE_VERSION("0.4");
1338
1339/*
1340 * Overrides for Emacs so that we follow Linus's tabbing style.
1341 * ---------------------------------------------------------------------------
1342 * Local variables:
1343 * c-basic-offset: 8
1344 * End:
1345 */
diff --git a/drivers/media/tuners/tda18271-maps.c b/drivers/media/tuners/tda18271-maps.c
new file mode 100644
index 000000000000..fb881c667c94
--- /dev/null
+++ b/drivers/media/tuners/tda18271-maps.c
@@ -0,0 +1,1317 @@
1/*
2 tda18271-maps.c - driver for the Philips / NXP TDA18271 silicon tuner
3
4 Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#include "tda18271-priv.h"
22
23struct tda18271_pll_map {
24 u32 lomax;
25 u8 pd; /* post div */
26 u8 d; /* div */
27};
28
29struct tda18271_map {
30 u32 rfmax;
31 u8 val;
32};
33
34/*---------------------------------------------------------------------*/
35
36static struct tda18271_pll_map tda18271c1_main_pll[] = {
37 { .lomax = 32000, .pd = 0x5f, .d = 0xf0 },
38 { .lomax = 35000, .pd = 0x5e, .d = 0xe0 },
39 { .lomax = 37000, .pd = 0x5d, .d = 0xd0 },
40 { .lomax = 41000, .pd = 0x5c, .d = 0xc0 },
41 { .lomax = 44000, .pd = 0x5b, .d = 0xb0 },
42 { .lomax = 49000, .pd = 0x5a, .d = 0xa0 },
43 { .lomax = 54000, .pd = 0x59, .d = 0x90 },
44 { .lomax = 61000, .pd = 0x58, .d = 0x80 },
45 { .lomax = 65000, .pd = 0x4f, .d = 0x78 },
46 { .lomax = 70000, .pd = 0x4e, .d = 0x70 },
47 { .lomax = 75000, .pd = 0x4d, .d = 0x68 },
48 { .lomax = 82000, .pd = 0x4c, .d = 0x60 },
49 { .lomax = 89000, .pd = 0x4b, .d = 0x58 },
50 { .lomax = 98000, .pd = 0x4a, .d = 0x50 },
51 { .lomax = 109000, .pd = 0x49, .d = 0x48 },
52 { .lomax = 123000, .pd = 0x48, .d = 0x40 },
53 { .lomax = 131000, .pd = 0x3f, .d = 0x3c },
54 { .lomax = 141000, .pd = 0x3e, .d = 0x38 },
55 { .lomax = 151000, .pd = 0x3d, .d = 0x34 },
56 { .lomax = 164000, .pd = 0x3c, .d = 0x30 },
57 { .lomax = 179000, .pd = 0x3b, .d = 0x2c },
58 { .lomax = 197000, .pd = 0x3a, .d = 0x28 },
59 { .lomax = 219000, .pd = 0x39, .d = 0x24 },
60 { .lomax = 246000, .pd = 0x38, .d = 0x20 },
61 { .lomax = 263000, .pd = 0x2f, .d = 0x1e },
62 { .lomax = 282000, .pd = 0x2e, .d = 0x1c },
63 { .lomax = 303000, .pd = 0x2d, .d = 0x1a },
64 { .lomax = 329000, .pd = 0x2c, .d = 0x18 },
65 { .lomax = 359000, .pd = 0x2b, .d = 0x16 },
66 { .lomax = 395000, .pd = 0x2a, .d = 0x14 },
67 { .lomax = 438000, .pd = 0x29, .d = 0x12 },
68 { .lomax = 493000, .pd = 0x28, .d = 0x10 },
69 { .lomax = 526000, .pd = 0x1f, .d = 0x0f },
70 { .lomax = 564000, .pd = 0x1e, .d = 0x0e },
71 { .lomax = 607000, .pd = 0x1d, .d = 0x0d },
72 { .lomax = 658000, .pd = 0x1c, .d = 0x0c },
73 { .lomax = 718000, .pd = 0x1b, .d = 0x0b },
74 { .lomax = 790000, .pd = 0x1a, .d = 0x0a },
75 { .lomax = 877000, .pd = 0x19, .d = 0x09 },
76 { .lomax = 987000, .pd = 0x18, .d = 0x08 },
77 { .lomax = 0, .pd = 0x00, .d = 0x00 }, /* end */
78};
79
80static struct tda18271_pll_map tda18271c2_main_pll[] = {
81 { .lomax = 33125, .pd = 0x57, .d = 0xf0 },
82 { .lomax = 35500, .pd = 0x56, .d = 0xe0 },
83 { .lomax = 38188, .pd = 0x55, .d = 0xd0 },
84 { .lomax = 41375, .pd = 0x54, .d = 0xc0 },
85 { .lomax = 45125, .pd = 0x53, .d = 0xb0 },
86 { .lomax = 49688, .pd = 0x52, .d = 0xa0 },
87 { .lomax = 55188, .pd = 0x51, .d = 0x90 },
88 { .lomax = 62125, .pd = 0x50, .d = 0x80 },
89 { .lomax = 66250, .pd = 0x47, .d = 0x78 },
90 { .lomax = 71000, .pd = 0x46, .d = 0x70 },
91 { .lomax = 76375, .pd = 0x45, .d = 0x68 },
92 { .lomax = 82750, .pd = 0x44, .d = 0x60 },
93 { .lomax = 90250, .pd = 0x43, .d = 0x58 },
94 { .lomax = 99375, .pd = 0x42, .d = 0x50 },
95 { .lomax = 110375, .pd = 0x41, .d = 0x48 },
96 { .lomax = 124250, .pd = 0x40, .d = 0x40 },
97 { .lomax = 132500, .pd = 0x37, .d = 0x3c },
98 { .lomax = 142000, .pd = 0x36, .d = 0x38 },
99 { .lomax = 152750, .pd = 0x35, .d = 0x34 },
100 { .lomax = 165500, .pd = 0x34, .d = 0x30 },
101 { .lomax = 180500, .pd = 0x33, .d = 0x2c },
102 { .lomax = 198750, .pd = 0x32, .d = 0x28 },
103 { .lomax = 220750, .pd = 0x31, .d = 0x24 },
104 { .lomax = 248500, .pd = 0x30, .d = 0x20 },
105 { .lomax = 265000, .pd = 0x27, .d = 0x1e },
106 { .lomax = 284000, .pd = 0x26, .d = 0x1c },
107 { .lomax = 305500, .pd = 0x25, .d = 0x1a },
108 { .lomax = 331000, .pd = 0x24, .d = 0x18 },
109 { .lomax = 361000, .pd = 0x23, .d = 0x16 },
110 { .lomax = 397500, .pd = 0x22, .d = 0x14 },
111 { .lomax = 441500, .pd = 0x21, .d = 0x12 },
112 { .lomax = 497000, .pd = 0x20, .d = 0x10 },
113 { .lomax = 530000, .pd = 0x17, .d = 0x0f },
114 { .lomax = 568000, .pd = 0x16, .d = 0x0e },
115 { .lomax = 611000, .pd = 0x15, .d = 0x0d },
116 { .lomax = 662000, .pd = 0x14, .d = 0x0c },
117 { .lomax = 722000, .pd = 0x13, .d = 0x0b },
118 { .lomax = 795000, .pd = 0x12, .d = 0x0a },
119 { .lomax = 883000, .pd = 0x11, .d = 0x09 },
120 { .lomax = 994000, .pd = 0x10, .d = 0x08 },
121 { .lomax = 0, .pd = 0x00, .d = 0x00 }, /* end */
122};
123
124static struct tda18271_pll_map tda18271c1_cal_pll[] = {
125 { .lomax = 33000, .pd = 0xdd, .d = 0xd0 },
126 { .lomax = 36000, .pd = 0xdc, .d = 0xc0 },
127 { .lomax = 40000, .pd = 0xdb, .d = 0xb0 },
128 { .lomax = 44000, .pd = 0xda, .d = 0xa0 },
129 { .lomax = 49000, .pd = 0xd9, .d = 0x90 },
130 { .lomax = 55000, .pd = 0xd8, .d = 0x80 },
131 { .lomax = 63000, .pd = 0xd3, .d = 0x70 },
132 { .lomax = 67000, .pd = 0xcd, .d = 0x68 },
133 { .lomax = 73000, .pd = 0xcc, .d = 0x60 },
134 { .lomax = 80000, .pd = 0xcb, .d = 0x58 },
135 { .lomax = 88000, .pd = 0xca, .d = 0x50 },
136 { .lomax = 98000, .pd = 0xc9, .d = 0x48 },
137 { .lomax = 110000, .pd = 0xc8, .d = 0x40 },
138 { .lomax = 126000, .pd = 0xc3, .d = 0x38 },
139 { .lomax = 135000, .pd = 0xbd, .d = 0x34 },
140 { .lomax = 147000, .pd = 0xbc, .d = 0x30 },
141 { .lomax = 160000, .pd = 0xbb, .d = 0x2c },
142 { .lomax = 176000, .pd = 0xba, .d = 0x28 },
143 { .lomax = 196000, .pd = 0xb9, .d = 0x24 },
144 { .lomax = 220000, .pd = 0xb8, .d = 0x20 },
145 { .lomax = 252000, .pd = 0xb3, .d = 0x1c },
146 { .lomax = 271000, .pd = 0xad, .d = 0x1a },
147 { .lomax = 294000, .pd = 0xac, .d = 0x18 },
148 { .lomax = 321000, .pd = 0xab, .d = 0x16 },
149 { .lomax = 353000, .pd = 0xaa, .d = 0x14 },
150 { .lomax = 392000, .pd = 0xa9, .d = 0x12 },
151 { .lomax = 441000, .pd = 0xa8, .d = 0x10 },
152 { .lomax = 505000, .pd = 0xa3, .d = 0x0e },
153 { .lomax = 543000, .pd = 0x9d, .d = 0x0d },
154 { .lomax = 589000, .pd = 0x9c, .d = 0x0c },
155 { .lomax = 642000, .pd = 0x9b, .d = 0x0b },
156 { .lomax = 707000, .pd = 0x9a, .d = 0x0a },
157 { .lomax = 785000, .pd = 0x99, .d = 0x09 },
158 { .lomax = 883000, .pd = 0x98, .d = 0x08 },
159 { .lomax = 1010000, .pd = 0x93, .d = 0x07 },
160 { .lomax = 0, .pd = 0x00, .d = 0x00 }, /* end */
161};
162
163static struct tda18271_pll_map tda18271c2_cal_pll[] = {
164 { .lomax = 33813, .pd = 0xdd, .d = 0xd0 },
165 { .lomax = 36625, .pd = 0xdc, .d = 0xc0 },
166 { .lomax = 39938, .pd = 0xdb, .d = 0xb0 },
167 { .lomax = 43938, .pd = 0xda, .d = 0xa0 },
168 { .lomax = 48813, .pd = 0xd9, .d = 0x90 },
169 { .lomax = 54938, .pd = 0xd8, .d = 0x80 },
170 { .lomax = 62813, .pd = 0xd3, .d = 0x70 },
171 { .lomax = 67625, .pd = 0xcd, .d = 0x68 },
172 { .lomax = 73250, .pd = 0xcc, .d = 0x60 },
173 { .lomax = 79875, .pd = 0xcb, .d = 0x58 },
174 { .lomax = 87875, .pd = 0xca, .d = 0x50 },
175 { .lomax = 97625, .pd = 0xc9, .d = 0x48 },
176 { .lomax = 109875, .pd = 0xc8, .d = 0x40 },
177 { .lomax = 125625, .pd = 0xc3, .d = 0x38 },
178 { .lomax = 135250, .pd = 0xbd, .d = 0x34 },
179 { .lomax = 146500, .pd = 0xbc, .d = 0x30 },
180 { .lomax = 159750, .pd = 0xbb, .d = 0x2c },
181 { .lomax = 175750, .pd = 0xba, .d = 0x28 },
182 { .lomax = 195250, .pd = 0xb9, .d = 0x24 },
183 { .lomax = 219750, .pd = 0xb8, .d = 0x20 },
184 { .lomax = 251250, .pd = 0xb3, .d = 0x1c },
185 { .lomax = 270500, .pd = 0xad, .d = 0x1a },
186 { .lomax = 293000, .pd = 0xac, .d = 0x18 },
187 { .lomax = 319500, .pd = 0xab, .d = 0x16 },
188 { .lomax = 351500, .pd = 0xaa, .d = 0x14 },
189 { .lomax = 390500, .pd = 0xa9, .d = 0x12 },
190 { .lomax = 439500, .pd = 0xa8, .d = 0x10 },
191 { .lomax = 502500, .pd = 0xa3, .d = 0x0e },
192 { .lomax = 541000, .pd = 0x9d, .d = 0x0d },
193 { .lomax = 586000, .pd = 0x9c, .d = 0x0c },
194 { .lomax = 639000, .pd = 0x9b, .d = 0x0b },
195 { .lomax = 703000, .pd = 0x9a, .d = 0x0a },
196 { .lomax = 781000, .pd = 0x99, .d = 0x09 },
197 { .lomax = 879000, .pd = 0x98, .d = 0x08 },
198 { .lomax = 0, .pd = 0x00, .d = 0x00 }, /* end */
199};
200
201static struct tda18271_map tda18271_bp_filter[] = {
202 { .rfmax = 62000, .val = 0x00 },
203 { .rfmax = 84000, .val = 0x01 },
204 { .rfmax = 100000, .val = 0x02 },
205 { .rfmax = 140000, .val = 0x03 },
206 { .rfmax = 170000, .val = 0x04 },
207 { .rfmax = 180000, .val = 0x05 },
208 { .rfmax = 865000, .val = 0x06 },
209 { .rfmax = 0, .val = 0x00 }, /* end */
210};
211
212static struct tda18271_map tda18271c1_km[] = {
213 { .rfmax = 61100, .val = 0x74 },
214 { .rfmax = 350000, .val = 0x40 },
215 { .rfmax = 720000, .val = 0x30 },
216 { .rfmax = 865000, .val = 0x40 },
217 { .rfmax = 0, .val = 0x00 }, /* end */
218};
219
220static struct tda18271_map tda18271c2_km[] = {
221 { .rfmax = 47900, .val = 0x38 },
222 { .rfmax = 61100, .val = 0x44 },
223 { .rfmax = 350000, .val = 0x30 },
224 { .rfmax = 720000, .val = 0x24 },
225 { .rfmax = 865000, .val = 0x3c },
226 { .rfmax = 0, .val = 0x00 }, /* end */
227};
228
229static struct tda18271_map tda18271_rf_band[] = {
230 { .rfmax = 47900, .val = 0x00 },
231 { .rfmax = 61100, .val = 0x01 },
232 { .rfmax = 152600, .val = 0x02 },
233 { .rfmax = 164700, .val = 0x03 },
234 { .rfmax = 203500, .val = 0x04 },
235 { .rfmax = 457800, .val = 0x05 },
236 { .rfmax = 865000, .val = 0x06 },
237 { .rfmax = 0, .val = 0x00 }, /* end */
238};
239
240static struct tda18271_map tda18271_gain_taper[] = {
241 { .rfmax = 45400, .val = 0x1f },
242 { .rfmax = 45800, .val = 0x1e },
243 { .rfmax = 46200, .val = 0x1d },
244 { .rfmax = 46700, .val = 0x1c },
245 { .rfmax = 47100, .val = 0x1b },
246 { .rfmax = 47500, .val = 0x1a },
247 { .rfmax = 47900, .val = 0x19 },
248 { .rfmax = 49600, .val = 0x17 },
249 { .rfmax = 51200, .val = 0x16 },
250 { .rfmax = 52900, .val = 0x15 },
251 { .rfmax = 54500, .val = 0x14 },
252 { .rfmax = 56200, .val = 0x13 },
253 { .rfmax = 57800, .val = 0x12 },
254 { .rfmax = 59500, .val = 0x11 },
255 { .rfmax = 61100, .val = 0x10 },
256 { .rfmax = 67600, .val = 0x0d },
257 { .rfmax = 74200, .val = 0x0c },
258 { .rfmax = 80700, .val = 0x0b },
259 { .rfmax = 87200, .val = 0x0a },
260 { .rfmax = 93800, .val = 0x09 },
261 { .rfmax = 100300, .val = 0x08 },
262 { .rfmax = 106900, .val = 0x07 },
263 { .rfmax = 113400, .val = 0x06 },
264 { .rfmax = 119900, .val = 0x05 },
265 { .rfmax = 126500, .val = 0x04 },
266 { .rfmax = 133000, .val = 0x03 },
267 { .rfmax = 139500, .val = 0x02 },
268 { .rfmax = 146100, .val = 0x01 },
269 { .rfmax = 152600, .val = 0x00 },
270 { .rfmax = 154300, .val = 0x1f },
271 { .rfmax = 156100, .val = 0x1e },
272 { .rfmax = 157800, .val = 0x1d },
273 { .rfmax = 159500, .val = 0x1c },
274 { .rfmax = 161200, .val = 0x1b },
275 { .rfmax = 163000, .val = 0x1a },
276 { .rfmax = 164700, .val = 0x19 },
277 { .rfmax = 170200, .val = 0x17 },
278 { .rfmax = 175800, .val = 0x16 },
279 { .rfmax = 181300, .val = 0x15 },
280 { .rfmax = 186900, .val = 0x14 },
281 { .rfmax = 192400, .val = 0x13 },
282 { .rfmax = 198000, .val = 0x12 },
283 { .rfmax = 203500, .val = 0x11 },
284 { .rfmax = 216200, .val = 0x14 },
285 { .rfmax = 228900, .val = 0x13 },
286 { .rfmax = 241600, .val = 0x12 },
287 { .rfmax = 254400, .val = 0x11 },
288 { .rfmax = 267100, .val = 0x10 },
289 { .rfmax = 279800, .val = 0x0f },
290 { .rfmax = 292500, .val = 0x0e },
291 { .rfmax = 305200, .val = 0x0d },
292 { .rfmax = 317900, .val = 0x0c },
293 { .rfmax = 330700, .val = 0x0b },
294 { .rfmax = 343400, .val = 0x0a },
295 { .rfmax = 356100, .val = 0x09 },
296 { .rfmax = 368800, .val = 0x08 },
297 { .rfmax = 381500, .val = 0x07 },
298 { .rfmax = 394200, .val = 0x06 },
299 { .rfmax = 406900, .val = 0x05 },
300 { .rfmax = 419700, .val = 0x04 },
301 { .rfmax = 432400, .val = 0x03 },
302 { .rfmax = 445100, .val = 0x02 },
303 { .rfmax = 457800, .val = 0x01 },
304 { .rfmax = 476300, .val = 0x19 },
305 { .rfmax = 494800, .val = 0x18 },
306 { .rfmax = 513300, .val = 0x17 },
307 { .rfmax = 531800, .val = 0x16 },
308 { .rfmax = 550300, .val = 0x15 },
309 { .rfmax = 568900, .val = 0x14 },
310 { .rfmax = 587400, .val = 0x13 },
311 { .rfmax = 605900, .val = 0x12 },
312 { .rfmax = 624400, .val = 0x11 },
313 { .rfmax = 642900, .val = 0x10 },
314 { .rfmax = 661400, .val = 0x0f },
315 { .rfmax = 679900, .val = 0x0e },
316 { .rfmax = 698400, .val = 0x0d },
317 { .rfmax = 716900, .val = 0x0c },
318 { .rfmax = 735400, .val = 0x0b },
319 { .rfmax = 753900, .val = 0x0a },
320 { .rfmax = 772500, .val = 0x09 },
321 { .rfmax = 791000, .val = 0x08 },
322 { .rfmax = 809500, .val = 0x07 },
323 { .rfmax = 828000, .val = 0x06 },
324 { .rfmax = 846500, .val = 0x05 },
325 { .rfmax = 865000, .val = 0x04 },
326 { .rfmax = 0, .val = 0x00 }, /* end */
327};
328
329static struct tda18271_map tda18271c1_rf_cal[] = {
330 { .rfmax = 41000, .val = 0x1e },
331 { .rfmax = 43000, .val = 0x30 },
332 { .rfmax = 45000, .val = 0x43 },
333 { .rfmax = 46000, .val = 0x4d },
334 { .rfmax = 47000, .val = 0x54 },
335 { .rfmax = 47900, .val = 0x64 },
336 { .rfmax = 49100, .val = 0x20 },
337 { .rfmax = 50000, .val = 0x22 },
338 { .rfmax = 51000, .val = 0x2a },
339 { .rfmax = 53000, .val = 0x32 },
340 { .rfmax = 55000, .val = 0x35 },
341 { .rfmax = 56000, .val = 0x3c },
342 { .rfmax = 57000, .val = 0x3f },
343 { .rfmax = 58000, .val = 0x48 },
344 { .rfmax = 59000, .val = 0x4d },
345 { .rfmax = 60000, .val = 0x58 },
346 { .rfmax = 61100, .val = 0x5f },
347 { .rfmax = 0, .val = 0x00 }, /* end */
348};
349
350static struct tda18271_map tda18271c2_rf_cal[] = {
351 { .rfmax = 41000, .val = 0x0f },
352 { .rfmax = 43000, .val = 0x1c },
353 { .rfmax = 45000, .val = 0x2f },
354 { .rfmax = 46000, .val = 0x39 },
355 { .rfmax = 47000, .val = 0x40 },
356 { .rfmax = 47900, .val = 0x50 },
357 { .rfmax = 49100, .val = 0x16 },
358 { .rfmax = 50000, .val = 0x18 },
359 { .rfmax = 51000, .val = 0x20 },
360 { .rfmax = 53000, .val = 0x28 },
361 { .rfmax = 55000, .val = 0x2b },
362 { .rfmax = 56000, .val = 0x32 },
363 { .rfmax = 57000, .val = 0x35 },
364 { .rfmax = 58000, .val = 0x3e },
365 { .rfmax = 59000, .val = 0x43 },
366 { .rfmax = 60000, .val = 0x4e },
367 { .rfmax = 61100, .val = 0x55 },
368 { .rfmax = 63000, .val = 0x0f },
369 { .rfmax = 64000, .val = 0x11 },
370 { .rfmax = 65000, .val = 0x12 },
371 { .rfmax = 66000, .val = 0x15 },
372 { .rfmax = 67000, .val = 0x16 },
373 { .rfmax = 68000, .val = 0x17 },
374 { .rfmax = 70000, .val = 0x19 },
375 { .rfmax = 71000, .val = 0x1c },
376 { .rfmax = 72000, .val = 0x1d },
377 { .rfmax = 73000, .val = 0x1f },
378 { .rfmax = 74000, .val = 0x20 },
379 { .rfmax = 75000, .val = 0x21 },
380 { .rfmax = 76000, .val = 0x24 },
381 { .rfmax = 77000, .val = 0x25 },
382 { .rfmax = 78000, .val = 0x27 },
383 { .rfmax = 80000, .val = 0x28 },
384 { .rfmax = 81000, .val = 0x29 },
385 { .rfmax = 82000, .val = 0x2d },
386 { .rfmax = 83000, .val = 0x2e },
387 { .rfmax = 84000, .val = 0x2f },
388 { .rfmax = 85000, .val = 0x31 },
389 { .rfmax = 86000, .val = 0x33 },
390 { .rfmax = 87000, .val = 0x34 },
391 { .rfmax = 88000, .val = 0x35 },
392 { .rfmax = 89000, .val = 0x37 },
393 { .rfmax = 90000, .val = 0x38 },
394 { .rfmax = 91000, .val = 0x39 },
395 { .rfmax = 93000, .val = 0x3c },
396 { .rfmax = 94000, .val = 0x3e },
397 { .rfmax = 95000, .val = 0x3f },
398 { .rfmax = 96000, .val = 0x40 },
399 { .rfmax = 97000, .val = 0x42 },
400 { .rfmax = 99000, .val = 0x45 },
401 { .rfmax = 100000, .val = 0x46 },
402 { .rfmax = 102000, .val = 0x48 },
403 { .rfmax = 103000, .val = 0x4a },
404 { .rfmax = 105000, .val = 0x4d },
405 { .rfmax = 106000, .val = 0x4e },
406 { .rfmax = 107000, .val = 0x50 },
407 { .rfmax = 108000, .val = 0x51 },
408 { .rfmax = 110000, .val = 0x54 },
409 { .rfmax = 111000, .val = 0x56 },
410 { .rfmax = 112000, .val = 0x57 },
411 { .rfmax = 113000, .val = 0x58 },
412 { .rfmax = 114000, .val = 0x59 },
413 { .rfmax = 115000, .val = 0x5c },
414 { .rfmax = 116000, .val = 0x5d },
415 { .rfmax = 117000, .val = 0x5f },
416 { .rfmax = 119000, .val = 0x60 },
417 { .rfmax = 120000, .val = 0x64 },
418 { .rfmax = 121000, .val = 0x65 },
419 { .rfmax = 122000, .val = 0x66 },
420 { .rfmax = 123000, .val = 0x68 },
421 { .rfmax = 124000, .val = 0x69 },
422 { .rfmax = 125000, .val = 0x6c },
423 { .rfmax = 126000, .val = 0x6d },
424 { .rfmax = 127000, .val = 0x6e },
425 { .rfmax = 128000, .val = 0x70 },
426 { .rfmax = 129000, .val = 0x71 },
427 { .rfmax = 130000, .val = 0x75 },
428 { .rfmax = 131000, .val = 0x77 },
429 { .rfmax = 132000, .val = 0x78 },
430 { .rfmax = 133000, .val = 0x7b },
431 { .rfmax = 134000, .val = 0x7e },
432 { .rfmax = 135000, .val = 0x81 },
433 { .rfmax = 136000, .val = 0x82 },
434 { .rfmax = 137000, .val = 0x87 },
435 { .rfmax = 138000, .val = 0x88 },
436 { .rfmax = 139000, .val = 0x8d },
437 { .rfmax = 140000, .val = 0x8e },
438 { .rfmax = 141000, .val = 0x91 },
439 { .rfmax = 142000, .val = 0x95 },
440 { .rfmax = 143000, .val = 0x9a },
441 { .rfmax = 144000, .val = 0x9d },
442 { .rfmax = 145000, .val = 0xa1 },
443 { .rfmax = 146000, .val = 0xa2 },
444 { .rfmax = 147000, .val = 0xa4 },
445 { .rfmax = 148000, .val = 0xa9 },
446 { .rfmax = 149000, .val = 0xae },
447 { .rfmax = 150000, .val = 0xb0 },
448 { .rfmax = 151000, .val = 0xb1 },
449 { .rfmax = 152000, .val = 0xb7 },
450 { .rfmax = 152600, .val = 0xbd },
451 { .rfmax = 154000, .val = 0x20 },
452 { .rfmax = 155000, .val = 0x22 },
453 { .rfmax = 156000, .val = 0x24 },
454 { .rfmax = 157000, .val = 0x25 },
455 { .rfmax = 158000, .val = 0x27 },
456 { .rfmax = 159000, .val = 0x29 },
457 { .rfmax = 160000, .val = 0x2c },
458 { .rfmax = 161000, .val = 0x2d },
459 { .rfmax = 163000, .val = 0x2e },
460 { .rfmax = 164000, .val = 0x2f },
461 { .rfmax = 164700, .val = 0x30 },
462 { .rfmax = 166000, .val = 0x11 },
463 { .rfmax = 167000, .val = 0x12 },
464 { .rfmax = 168000, .val = 0x13 },
465 { .rfmax = 169000, .val = 0x14 },
466 { .rfmax = 170000, .val = 0x15 },
467 { .rfmax = 172000, .val = 0x16 },
468 { .rfmax = 173000, .val = 0x17 },
469 { .rfmax = 174000, .val = 0x18 },
470 { .rfmax = 175000, .val = 0x1a },
471 { .rfmax = 176000, .val = 0x1b },
472 { .rfmax = 178000, .val = 0x1d },
473 { .rfmax = 179000, .val = 0x1e },
474 { .rfmax = 180000, .val = 0x1f },
475 { .rfmax = 181000, .val = 0x20 },
476 { .rfmax = 182000, .val = 0x21 },
477 { .rfmax = 183000, .val = 0x22 },
478 { .rfmax = 184000, .val = 0x24 },
479 { .rfmax = 185000, .val = 0x25 },
480 { .rfmax = 186000, .val = 0x26 },
481 { .rfmax = 187000, .val = 0x27 },
482 { .rfmax = 188000, .val = 0x29 },
483 { .rfmax = 189000, .val = 0x2a },
484 { .rfmax = 190000, .val = 0x2c },
485 { .rfmax = 191000, .val = 0x2d },
486 { .rfmax = 192000, .val = 0x2e },
487 { .rfmax = 193000, .val = 0x2f },
488 { .rfmax = 194000, .val = 0x30 },
489 { .rfmax = 195000, .val = 0x33 },
490 { .rfmax = 196000, .val = 0x35 },
491 { .rfmax = 198000, .val = 0x36 },
492 { .rfmax = 200000, .val = 0x38 },
493 { .rfmax = 201000, .val = 0x3c },
494 { .rfmax = 202000, .val = 0x3d },
495 { .rfmax = 203500, .val = 0x3e },
496 { .rfmax = 206000, .val = 0x0e },
497 { .rfmax = 208000, .val = 0x0f },
498 { .rfmax = 212000, .val = 0x10 },
499 { .rfmax = 216000, .val = 0x11 },
500 { .rfmax = 217000, .val = 0x12 },
501 { .rfmax = 218000, .val = 0x13 },
502 { .rfmax = 220000, .val = 0x14 },
503 { .rfmax = 222000, .val = 0x15 },
504 { .rfmax = 225000, .val = 0x16 },
505 { .rfmax = 228000, .val = 0x17 },
506 { .rfmax = 231000, .val = 0x18 },
507 { .rfmax = 234000, .val = 0x19 },
508 { .rfmax = 235000, .val = 0x1a },
509 { .rfmax = 236000, .val = 0x1b },
510 { .rfmax = 237000, .val = 0x1c },
511 { .rfmax = 240000, .val = 0x1d },
512 { .rfmax = 242000, .val = 0x1e },
513 { .rfmax = 244000, .val = 0x1f },
514 { .rfmax = 247000, .val = 0x20 },
515 { .rfmax = 249000, .val = 0x21 },
516 { .rfmax = 252000, .val = 0x22 },
517 { .rfmax = 253000, .val = 0x23 },
518 { .rfmax = 254000, .val = 0x24 },
519 { .rfmax = 256000, .val = 0x25 },
520 { .rfmax = 259000, .val = 0x26 },
521 { .rfmax = 262000, .val = 0x27 },
522 { .rfmax = 264000, .val = 0x28 },
523 { .rfmax = 267000, .val = 0x29 },
524 { .rfmax = 269000, .val = 0x2a },
525 { .rfmax = 271000, .val = 0x2b },
526 { .rfmax = 273000, .val = 0x2c },
527 { .rfmax = 275000, .val = 0x2d },
528 { .rfmax = 277000, .val = 0x2e },
529 { .rfmax = 279000, .val = 0x2f },
530 { .rfmax = 282000, .val = 0x30 },
531 { .rfmax = 284000, .val = 0x31 },
532 { .rfmax = 286000, .val = 0x32 },
533 { .rfmax = 287000, .val = 0x33 },
534 { .rfmax = 290000, .val = 0x34 },
535 { .rfmax = 293000, .val = 0x35 },
536 { .rfmax = 295000, .val = 0x36 },
537 { .rfmax = 297000, .val = 0x37 },
538 { .rfmax = 300000, .val = 0x38 },
539 { .rfmax = 303000, .val = 0x39 },
540 { .rfmax = 305000, .val = 0x3a },
541 { .rfmax = 306000, .val = 0x3b },
542 { .rfmax = 307000, .val = 0x3c },
543 { .rfmax = 310000, .val = 0x3d },
544 { .rfmax = 312000, .val = 0x3e },
545 { .rfmax = 315000, .val = 0x3f },
546 { .rfmax = 318000, .val = 0x40 },
547 { .rfmax = 320000, .val = 0x41 },
548 { .rfmax = 323000, .val = 0x42 },
549 { .rfmax = 324000, .val = 0x43 },
550 { .rfmax = 325000, .val = 0x44 },
551 { .rfmax = 327000, .val = 0x45 },
552 { .rfmax = 331000, .val = 0x46 },
553 { .rfmax = 334000, .val = 0x47 },
554 { .rfmax = 337000, .val = 0x48 },
555 { .rfmax = 339000, .val = 0x49 },
556 { .rfmax = 340000, .val = 0x4a },
557 { .rfmax = 341000, .val = 0x4b },
558 { .rfmax = 343000, .val = 0x4c },
559 { .rfmax = 345000, .val = 0x4d },
560 { .rfmax = 349000, .val = 0x4e },
561 { .rfmax = 352000, .val = 0x4f },
562 { .rfmax = 353000, .val = 0x50 },
563 { .rfmax = 355000, .val = 0x51 },
564 { .rfmax = 357000, .val = 0x52 },
565 { .rfmax = 359000, .val = 0x53 },
566 { .rfmax = 361000, .val = 0x54 },
567 { .rfmax = 362000, .val = 0x55 },
568 { .rfmax = 364000, .val = 0x56 },
569 { .rfmax = 368000, .val = 0x57 },
570 { .rfmax = 370000, .val = 0x58 },
571 { .rfmax = 372000, .val = 0x59 },
572 { .rfmax = 375000, .val = 0x5a },
573 { .rfmax = 376000, .val = 0x5b },
574 { .rfmax = 377000, .val = 0x5c },
575 { .rfmax = 379000, .val = 0x5d },
576 { .rfmax = 382000, .val = 0x5e },
577 { .rfmax = 384000, .val = 0x5f },
578 { .rfmax = 385000, .val = 0x60 },
579 { .rfmax = 386000, .val = 0x61 },
580 { .rfmax = 388000, .val = 0x62 },
581 { .rfmax = 390000, .val = 0x63 },
582 { .rfmax = 393000, .val = 0x64 },
583 { .rfmax = 394000, .val = 0x65 },
584 { .rfmax = 396000, .val = 0x66 },
585 { .rfmax = 397000, .val = 0x67 },
586 { .rfmax = 398000, .val = 0x68 },
587 { .rfmax = 400000, .val = 0x69 },
588 { .rfmax = 402000, .val = 0x6a },
589 { .rfmax = 403000, .val = 0x6b },
590 { .rfmax = 407000, .val = 0x6c },
591 { .rfmax = 408000, .val = 0x6d },
592 { .rfmax = 409000, .val = 0x6e },
593 { .rfmax = 410000, .val = 0x6f },
594 { .rfmax = 411000, .val = 0x70 },
595 { .rfmax = 412000, .val = 0x71 },
596 { .rfmax = 413000, .val = 0x72 },
597 { .rfmax = 414000, .val = 0x73 },
598 { .rfmax = 417000, .val = 0x74 },
599 { .rfmax = 418000, .val = 0x75 },
600 { .rfmax = 420000, .val = 0x76 },
601 { .rfmax = 422000, .val = 0x77 },
602 { .rfmax = 423000, .val = 0x78 },
603 { .rfmax = 424000, .val = 0x79 },
604 { .rfmax = 427000, .val = 0x7a },
605 { .rfmax = 428000, .val = 0x7b },
606 { .rfmax = 429000, .val = 0x7d },
607 { .rfmax = 432000, .val = 0x7f },
608 { .rfmax = 434000, .val = 0x80 },
609 { .rfmax = 435000, .val = 0x81 },
610 { .rfmax = 436000, .val = 0x83 },
611 { .rfmax = 437000, .val = 0x84 },
612 { .rfmax = 438000, .val = 0x85 },
613 { .rfmax = 439000, .val = 0x86 },
614 { .rfmax = 440000, .val = 0x87 },
615 { .rfmax = 441000, .val = 0x88 },
616 { .rfmax = 442000, .val = 0x89 },
617 { .rfmax = 445000, .val = 0x8a },
618 { .rfmax = 446000, .val = 0x8b },
619 { .rfmax = 447000, .val = 0x8c },
620 { .rfmax = 448000, .val = 0x8e },
621 { .rfmax = 449000, .val = 0x8f },
622 { .rfmax = 450000, .val = 0x90 },
623 { .rfmax = 452000, .val = 0x91 },
624 { .rfmax = 453000, .val = 0x93 },
625 { .rfmax = 454000, .val = 0x94 },
626 { .rfmax = 456000, .val = 0x96 },
627 { .rfmax = 457800, .val = 0x98 },
628 { .rfmax = 461000, .val = 0x11 },
629 { .rfmax = 468000, .val = 0x12 },
630 { .rfmax = 472000, .val = 0x13 },
631 { .rfmax = 473000, .val = 0x14 },
632 { .rfmax = 474000, .val = 0x15 },
633 { .rfmax = 481000, .val = 0x16 },
634 { .rfmax = 486000, .val = 0x17 },
635 { .rfmax = 491000, .val = 0x18 },
636 { .rfmax = 498000, .val = 0x19 },
637 { .rfmax = 499000, .val = 0x1a },
638 { .rfmax = 501000, .val = 0x1b },
639 { .rfmax = 506000, .val = 0x1c },
640 { .rfmax = 511000, .val = 0x1d },
641 { .rfmax = 516000, .val = 0x1e },
642 { .rfmax = 520000, .val = 0x1f },
643 { .rfmax = 521000, .val = 0x20 },
644 { .rfmax = 525000, .val = 0x21 },
645 { .rfmax = 529000, .val = 0x22 },
646 { .rfmax = 533000, .val = 0x23 },
647 { .rfmax = 539000, .val = 0x24 },
648 { .rfmax = 541000, .val = 0x25 },
649 { .rfmax = 547000, .val = 0x26 },
650 { .rfmax = 549000, .val = 0x27 },
651 { .rfmax = 551000, .val = 0x28 },
652 { .rfmax = 556000, .val = 0x29 },
653 { .rfmax = 561000, .val = 0x2a },
654 { .rfmax = 563000, .val = 0x2b },
655 { .rfmax = 565000, .val = 0x2c },
656 { .rfmax = 569000, .val = 0x2d },
657 { .rfmax = 571000, .val = 0x2e },
658 { .rfmax = 577000, .val = 0x2f },
659 { .rfmax = 580000, .val = 0x30 },
660 { .rfmax = 582000, .val = 0x31 },
661 { .rfmax = 584000, .val = 0x32 },
662 { .rfmax = 588000, .val = 0x33 },
663 { .rfmax = 591000, .val = 0x34 },
664 { .rfmax = 596000, .val = 0x35 },
665 { .rfmax = 598000, .val = 0x36 },
666 { .rfmax = 603000, .val = 0x37 },
667 { .rfmax = 604000, .val = 0x38 },
668 { .rfmax = 606000, .val = 0x39 },
669 { .rfmax = 612000, .val = 0x3a },
670 { .rfmax = 615000, .val = 0x3b },
671 { .rfmax = 617000, .val = 0x3c },
672 { .rfmax = 621000, .val = 0x3d },
673 { .rfmax = 622000, .val = 0x3e },
674 { .rfmax = 625000, .val = 0x3f },
675 { .rfmax = 632000, .val = 0x40 },
676 { .rfmax = 633000, .val = 0x41 },
677 { .rfmax = 634000, .val = 0x42 },
678 { .rfmax = 642000, .val = 0x43 },
679 { .rfmax = 643000, .val = 0x44 },
680 { .rfmax = 647000, .val = 0x45 },
681 { .rfmax = 650000, .val = 0x46 },
682 { .rfmax = 652000, .val = 0x47 },
683 { .rfmax = 657000, .val = 0x48 },
684 { .rfmax = 661000, .val = 0x49 },
685 { .rfmax = 662000, .val = 0x4a },
686 { .rfmax = 665000, .val = 0x4b },
687 { .rfmax = 667000, .val = 0x4c },
688 { .rfmax = 670000, .val = 0x4d },
689 { .rfmax = 673000, .val = 0x4e },
690 { .rfmax = 676000, .val = 0x4f },
691 { .rfmax = 677000, .val = 0x50 },
692 { .rfmax = 681000, .val = 0x51 },
693 { .rfmax = 683000, .val = 0x52 },
694 { .rfmax = 686000, .val = 0x53 },
695 { .rfmax = 688000, .val = 0x54 },
696 { .rfmax = 689000, .val = 0x55 },
697 { .rfmax = 691000, .val = 0x56 },
698 { .rfmax = 695000, .val = 0x57 },
699 { .rfmax = 698000, .val = 0x58 },
700 { .rfmax = 703000, .val = 0x59 },
701 { .rfmax = 704000, .val = 0x5a },
702 { .rfmax = 705000, .val = 0x5b },
703 { .rfmax = 707000, .val = 0x5c },
704 { .rfmax = 710000, .val = 0x5d },
705 { .rfmax = 712000, .val = 0x5e },
706 { .rfmax = 717000, .val = 0x5f },
707 { .rfmax = 718000, .val = 0x60 },
708 { .rfmax = 721000, .val = 0x61 },
709 { .rfmax = 722000, .val = 0x62 },
710 { .rfmax = 723000, .val = 0x63 },
711 { .rfmax = 725000, .val = 0x64 },
712 { .rfmax = 727000, .val = 0x65 },
713 { .rfmax = 730000, .val = 0x66 },
714 { .rfmax = 732000, .val = 0x67 },
715 { .rfmax = 735000, .val = 0x68 },
716 { .rfmax = 740000, .val = 0x69 },
717 { .rfmax = 741000, .val = 0x6a },
718 { .rfmax = 742000, .val = 0x6b },
719 { .rfmax = 743000, .val = 0x6c },
720 { .rfmax = 745000, .val = 0x6d },
721 { .rfmax = 747000, .val = 0x6e },
722 { .rfmax = 748000, .val = 0x6f },
723 { .rfmax = 750000, .val = 0x70 },
724 { .rfmax = 752000, .val = 0x71 },
725 { .rfmax = 754000, .val = 0x72 },
726 { .rfmax = 757000, .val = 0x73 },
727 { .rfmax = 758000, .val = 0x74 },
728 { .rfmax = 760000, .val = 0x75 },
729 { .rfmax = 763000, .val = 0x76 },
730 { .rfmax = 764000, .val = 0x77 },
731 { .rfmax = 766000, .val = 0x78 },
732 { .rfmax = 767000, .val = 0x79 },
733 { .rfmax = 768000, .val = 0x7a },
734 { .rfmax = 773000, .val = 0x7b },
735 { .rfmax = 774000, .val = 0x7c },
736 { .rfmax = 776000, .val = 0x7d },
737 { .rfmax = 777000, .val = 0x7e },
738 { .rfmax = 778000, .val = 0x7f },
739 { .rfmax = 779000, .val = 0x80 },
740 { .rfmax = 781000, .val = 0x81 },
741 { .rfmax = 783000, .val = 0x82 },
742 { .rfmax = 784000, .val = 0x83 },
743 { .rfmax = 785000, .val = 0x84 },
744 { .rfmax = 786000, .val = 0x85 },
745 { .rfmax = 793000, .val = 0x86 },
746 { .rfmax = 794000, .val = 0x87 },
747 { .rfmax = 795000, .val = 0x88 },
748 { .rfmax = 797000, .val = 0x89 },
749 { .rfmax = 799000, .val = 0x8a },
750 { .rfmax = 801000, .val = 0x8b },
751 { .rfmax = 802000, .val = 0x8c },
752 { .rfmax = 803000, .val = 0x8d },
753 { .rfmax = 804000, .val = 0x8e },
754 { .rfmax = 810000, .val = 0x90 },
755 { .rfmax = 811000, .val = 0x91 },
756 { .rfmax = 812000, .val = 0x92 },
757 { .rfmax = 814000, .val = 0x93 },
758 { .rfmax = 816000, .val = 0x94 },
759 { .rfmax = 817000, .val = 0x96 },
760 { .rfmax = 818000, .val = 0x97 },
761 { .rfmax = 820000, .val = 0x98 },
762 { .rfmax = 821000, .val = 0x99 },
763 { .rfmax = 822000, .val = 0x9a },
764 { .rfmax = 828000, .val = 0x9b },
765 { .rfmax = 829000, .val = 0x9d },
766 { .rfmax = 830000, .val = 0x9f },
767 { .rfmax = 831000, .val = 0xa0 },
768 { .rfmax = 833000, .val = 0xa1 },
769 { .rfmax = 835000, .val = 0xa2 },
770 { .rfmax = 836000, .val = 0xa3 },
771 { .rfmax = 837000, .val = 0xa4 },
772 { .rfmax = 838000, .val = 0xa6 },
773 { .rfmax = 840000, .val = 0xa8 },
774 { .rfmax = 842000, .val = 0xa9 },
775 { .rfmax = 845000, .val = 0xaa },
776 { .rfmax = 846000, .val = 0xab },
777 { .rfmax = 847000, .val = 0xad },
778 { .rfmax = 848000, .val = 0xae },
779 { .rfmax = 852000, .val = 0xaf },
780 { .rfmax = 853000, .val = 0xb0 },
781 { .rfmax = 858000, .val = 0xb1 },
782 { .rfmax = 860000, .val = 0xb2 },
783 { .rfmax = 861000, .val = 0xb3 },
784 { .rfmax = 862000, .val = 0xb4 },
785 { .rfmax = 863000, .val = 0xb6 },
786 { .rfmax = 864000, .val = 0xb8 },
787 { .rfmax = 865000, .val = 0xb9 },
788 { .rfmax = 0, .val = 0x00 }, /* end */
789};
790
791static struct tda18271_map tda18271_ir_measure[] = {
792 { .rfmax = 30000, .val = 4 },
793 { .rfmax = 200000, .val = 5 },
794 { .rfmax = 600000, .val = 6 },
795 { .rfmax = 865000, .val = 7 },
796 { .rfmax = 0, .val = 0 }, /* end */
797};
798
799static struct tda18271_map tda18271_rf_cal_dc_over_dt[] = {
800 { .rfmax = 47900, .val = 0x00 },
801 { .rfmax = 55000, .val = 0x00 },
802 { .rfmax = 61100, .val = 0x0a },
803 { .rfmax = 64000, .val = 0x0a },
804 { .rfmax = 82000, .val = 0x14 },
805 { .rfmax = 84000, .val = 0x19 },
806 { .rfmax = 119000, .val = 0x1c },
807 { .rfmax = 124000, .val = 0x20 },
808 { .rfmax = 129000, .val = 0x2a },
809 { .rfmax = 134000, .val = 0x32 },
810 { .rfmax = 139000, .val = 0x39 },
811 { .rfmax = 144000, .val = 0x3e },
812 { .rfmax = 149000, .val = 0x3f },
813 { .rfmax = 152600, .val = 0x40 },
814 { .rfmax = 154000, .val = 0x40 },
815 { .rfmax = 164700, .val = 0x41 },
816 { .rfmax = 203500, .val = 0x32 },
817 { .rfmax = 353000, .val = 0x19 },
818 { .rfmax = 356000, .val = 0x1a },
819 { .rfmax = 359000, .val = 0x1b },
820 { .rfmax = 363000, .val = 0x1c },
821 { .rfmax = 366000, .val = 0x1d },
822 { .rfmax = 369000, .val = 0x1e },
823 { .rfmax = 373000, .val = 0x1f },
824 { .rfmax = 376000, .val = 0x20 },
825 { .rfmax = 379000, .val = 0x21 },
826 { .rfmax = 383000, .val = 0x22 },
827 { .rfmax = 386000, .val = 0x23 },
828 { .rfmax = 389000, .val = 0x24 },
829 { .rfmax = 393000, .val = 0x25 },
830 { .rfmax = 396000, .val = 0x26 },
831 { .rfmax = 399000, .val = 0x27 },
832 { .rfmax = 402000, .val = 0x28 },
833 { .rfmax = 404000, .val = 0x29 },
834 { .rfmax = 407000, .val = 0x2a },
835 { .rfmax = 409000, .val = 0x2b },
836 { .rfmax = 412000, .val = 0x2c },
837 { .rfmax = 414000, .val = 0x2d },
838 { .rfmax = 417000, .val = 0x2e },
839 { .rfmax = 419000, .val = 0x2f },
840 { .rfmax = 422000, .val = 0x30 },
841 { .rfmax = 424000, .val = 0x31 },
842 { .rfmax = 427000, .val = 0x32 },
843 { .rfmax = 429000, .val = 0x33 },
844 { .rfmax = 432000, .val = 0x34 },
845 { .rfmax = 434000, .val = 0x35 },
846 { .rfmax = 437000, .val = 0x36 },
847 { .rfmax = 439000, .val = 0x37 },
848 { .rfmax = 442000, .val = 0x38 },
849 { .rfmax = 444000, .val = 0x39 },
850 { .rfmax = 447000, .val = 0x3a },
851 { .rfmax = 449000, .val = 0x3b },
852 { .rfmax = 457800, .val = 0x3c },
853 { .rfmax = 465000, .val = 0x0f },
854 { .rfmax = 477000, .val = 0x12 },
855 { .rfmax = 483000, .val = 0x14 },
856 { .rfmax = 502000, .val = 0x19 },
857 { .rfmax = 508000, .val = 0x1b },
858 { .rfmax = 519000, .val = 0x1c },
859 { .rfmax = 522000, .val = 0x1d },
860 { .rfmax = 524000, .val = 0x1e },
861 { .rfmax = 534000, .val = 0x1f },
862 { .rfmax = 549000, .val = 0x20 },
863 { .rfmax = 554000, .val = 0x22 },
864 { .rfmax = 584000, .val = 0x24 },
865 { .rfmax = 589000, .val = 0x26 },
866 { .rfmax = 658000, .val = 0x27 },
867 { .rfmax = 664000, .val = 0x2c },
868 { .rfmax = 669000, .val = 0x2d },
869 { .rfmax = 699000, .val = 0x2e },
870 { .rfmax = 704000, .val = 0x30 },
871 { .rfmax = 709000, .val = 0x31 },
872 { .rfmax = 714000, .val = 0x32 },
873 { .rfmax = 724000, .val = 0x33 },
874 { .rfmax = 729000, .val = 0x36 },
875 { .rfmax = 739000, .val = 0x38 },
876 { .rfmax = 744000, .val = 0x39 },
877 { .rfmax = 749000, .val = 0x3b },
878 { .rfmax = 754000, .val = 0x3c },
879 { .rfmax = 759000, .val = 0x3d },
880 { .rfmax = 764000, .val = 0x3e },
881 { .rfmax = 769000, .val = 0x3f },
882 { .rfmax = 774000, .val = 0x40 },
883 { .rfmax = 779000, .val = 0x41 },
884 { .rfmax = 784000, .val = 0x43 },
885 { .rfmax = 789000, .val = 0x46 },
886 { .rfmax = 794000, .val = 0x48 },
887 { .rfmax = 799000, .val = 0x4b },
888 { .rfmax = 804000, .val = 0x4f },
889 { .rfmax = 809000, .val = 0x54 },
890 { .rfmax = 814000, .val = 0x59 },
891 { .rfmax = 819000, .val = 0x5d },
892 { .rfmax = 824000, .val = 0x61 },
893 { .rfmax = 829000, .val = 0x68 },
894 { .rfmax = 834000, .val = 0x6e },
895 { .rfmax = 839000, .val = 0x75 },
896 { .rfmax = 844000, .val = 0x7e },
897 { .rfmax = 849000, .val = 0x82 },
898 { .rfmax = 854000, .val = 0x84 },
899 { .rfmax = 859000, .val = 0x8f },
900 { .rfmax = 865000, .val = 0x9a },
901 { .rfmax = 0, .val = 0x00 }, /* end */
902};
903
904/*---------------------------------------------------------------------*/
905
906struct tda18271_thermo_map {
907 u8 d;
908 u8 r0;
909 u8 r1;
910};
911
912static struct tda18271_thermo_map tda18271_thermometer[] = {
913 { .d = 0x00, .r0 = 60, .r1 = 92 },
914 { .d = 0x01, .r0 = 62, .r1 = 94 },
915 { .d = 0x02, .r0 = 66, .r1 = 98 },
916 { .d = 0x03, .r0 = 64, .r1 = 96 },
917 { .d = 0x04, .r0 = 74, .r1 = 106 },
918 { .d = 0x05, .r0 = 72, .r1 = 104 },
919 { .d = 0x06, .r0 = 68, .r1 = 100 },
920 { .d = 0x07, .r0 = 70, .r1 = 102 },
921 { .d = 0x08, .r0 = 90, .r1 = 122 },
922 { .d = 0x09, .r0 = 88, .r1 = 120 },
923 { .d = 0x0a, .r0 = 84, .r1 = 116 },
924 { .d = 0x0b, .r0 = 86, .r1 = 118 },
925 { .d = 0x0c, .r0 = 76, .r1 = 108 },
926 { .d = 0x0d, .r0 = 78, .r1 = 110 },
927 { .d = 0x0e, .r0 = 82, .r1 = 114 },
928 { .d = 0x0f, .r0 = 80, .r1 = 112 },
929 { .d = 0x00, .r0 = 0, .r1 = 0 }, /* end */
930};
931
932int tda18271_lookup_thermometer(struct dvb_frontend *fe)
933{
934 struct tda18271_priv *priv = fe->tuner_priv;
935 unsigned char *regs = priv->tda18271_regs;
936 int val, i = 0;
937
938 while (tda18271_thermometer[i].d < (regs[R_TM] & 0x0f)) {
939 if (tda18271_thermometer[i + 1].d == 0)
940 break;
941 i++;
942 }
943
944 if ((regs[R_TM] & 0x20) == 0x20)
945 val = tda18271_thermometer[i].r1;
946 else
947 val = tda18271_thermometer[i].r0;
948
949 tda_map("(%d) tm = %d\n", i, val);
950
951 return val;
952}
953
954/*---------------------------------------------------------------------*/
955
956struct tda18271_cid_target_map {
957 u32 rfmax;
958 u8 target;
959 u16 limit;
960};
961
962static struct tda18271_cid_target_map tda18271_cid_target[] = {
963 { .rfmax = 46000, .target = 0x04, .limit = 1800 },
964 { .rfmax = 52200, .target = 0x0a, .limit = 1500 },
965 { .rfmax = 70100, .target = 0x01, .limit = 4000 },
966 { .rfmax = 136800, .target = 0x18, .limit = 4000 },
967 { .rfmax = 156700, .target = 0x18, .limit = 4000 },
968 { .rfmax = 186250, .target = 0x0a, .limit = 4000 },
969 { .rfmax = 230000, .target = 0x0a, .limit = 4000 },
970 { .rfmax = 345000, .target = 0x18, .limit = 4000 },
971 { .rfmax = 426000, .target = 0x0e, .limit = 4000 },
972 { .rfmax = 489500, .target = 0x1e, .limit = 4000 },
973 { .rfmax = 697500, .target = 0x32, .limit = 4000 },
974 { .rfmax = 842000, .target = 0x3a, .limit = 4000 },
975 { .rfmax = 0, .target = 0x00, .limit = 0 }, /* end */
976};
977
978int tda18271_lookup_cid_target(struct dvb_frontend *fe,
979 u32 *freq, u8 *cid_target, u16 *count_limit)
980{
981 struct tda18271_priv *priv = fe->tuner_priv;
982 int i = 0;
983
984 while ((tda18271_cid_target[i].rfmax * 1000) < *freq) {
985 if (tda18271_cid_target[i + 1].rfmax == 0)
986 break;
987 i++;
988 }
989 *cid_target = tda18271_cid_target[i].target;
990 *count_limit = tda18271_cid_target[i].limit;
991
992 tda_map("(%d) cid_target = %02x, count_limit = %d\n", i,
993 tda18271_cid_target[i].target, tda18271_cid_target[i].limit);
994
995 return 0;
996}
997
998/*---------------------------------------------------------------------*/
999
1000static struct tda18271_rf_tracking_filter_cal tda18271_rf_band_template[] = {
1001 { .rfmax = 47900, .rfband = 0x00,
1002 .rf1_def = 46000, .rf2_def = 0, .rf3_def = 0 },
1003 { .rfmax = 61100, .rfband = 0x01,
1004 .rf1_def = 52200, .rf2_def = 0, .rf3_def = 0 },
1005 { .rfmax = 152600, .rfband = 0x02,
1006 .rf1_def = 70100, .rf2_def = 136800, .rf3_def = 0 },
1007 { .rfmax = 164700, .rfband = 0x03,
1008 .rf1_def = 156700, .rf2_def = 0, .rf3_def = 0 },
1009 { .rfmax = 203500, .rfband = 0x04,
1010 .rf1_def = 186250, .rf2_def = 0, .rf3_def = 0 },
1011 { .rfmax = 457800, .rfband = 0x05,
1012 .rf1_def = 230000, .rf2_def = 345000, .rf3_def = 426000 },
1013 { .rfmax = 865000, .rfband = 0x06,
1014 .rf1_def = 489500, .rf2_def = 697500, .rf3_def = 842000 },
1015 { .rfmax = 0, .rfband = 0x00,
1016 .rf1_def = 0, .rf2_def = 0, .rf3_def = 0 }, /* end */
1017};
1018
1019int tda18271_lookup_rf_band(struct dvb_frontend *fe, u32 *freq, u8 *rf_band)
1020{
1021 struct tda18271_priv *priv = fe->tuner_priv;
1022 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
1023 int i = 0;
1024
1025 while ((map[i].rfmax * 1000) < *freq) {
1026 if (tda18271_debug & DBG_ADV)
1027 tda_map("(%d) rfmax = %d < freq = %d, "
1028 "rf1_def = %d, rf2_def = %d, rf3_def = %d, "
1029 "rf1 = %d, rf2 = %d, rf3 = %d, "
1030 "rf_a1 = %d, rf_a2 = %d, "
1031 "rf_b1 = %d, rf_b2 = %d\n",
1032 i, map[i].rfmax * 1000, *freq,
1033 map[i].rf1_def, map[i].rf2_def, map[i].rf3_def,
1034 map[i].rf1, map[i].rf2, map[i].rf3,
1035 map[i].rf_a1, map[i].rf_a2,
1036 map[i].rf_b1, map[i].rf_b2);
1037 if (map[i].rfmax == 0)
1038 return -EINVAL;
1039 i++;
1040 }
1041 if (rf_band)
1042 *rf_band = map[i].rfband;
1043
1044 tda_map("(%d) rf_band = %02x\n", i, map[i].rfband);
1045
1046 return i;
1047}
1048
1049/*---------------------------------------------------------------------*/
1050
1051struct tda18271_map_layout {
1052 struct tda18271_pll_map *main_pll;
1053 struct tda18271_pll_map *cal_pll;
1054
1055 struct tda18271_map *rf_cal;
1056 struct tda18271_map *rf_cal_kmco;
1057 struct tda18271_map *rf_cal_dc_over_dt;
1058
1059 struct tda18271_map *bp_filter;
1060 struct tda18271_map *rf_band;
1061 struct tda18271_map *gain_taper;
1062 struct tda18271_map *ir_measure;
1063};
1064
1065/*---------------------------------------------------------------------*/
1066
1067int tda18271_lookup_pll_map(struct dvb_frontend *fe,
1068 enum tda18271_map_type map_type,
1069 u32 *freq, u8 *post_div, u8 *div)
1070{
1071 struct tda18271_priv *priv = fe->tuner_priv;
1072 struct tda18271_pll_map *map = NULL;
1073 unsigned int i = 0;
1074 char *map_name;
1075 int ret = 0;
1076
1077 BUG_ON(!priv->maps);
1078
1079 switch (map_type) {
1080 case MAIN_PLL:
1081 map = priv->maps->main_pll;
1082 map_name = "main_pll";
1083 break;
1084 case CAL_PLL:
1085 map = priv->maps->cal_pll;
1086 map_name = "cal_pll";
1087 break;
1088 default:
1089 /* we should never get here */
1090 map_name = "undefined";
1091 break;
1092 }
1093
1094 if (!map) {
1095 tda_warn("%s map is not set!\n", map_name);
1096 ret = -EINVAL;
1097 goto fail;
1098 }
1099
1100 while ((map[i].lomax * 1000) < *freq) {
1101 if (map[i + 1].lomax == 0) {
1102 tda_map("%s: frequency (%d) out of range\n",
1103 map_name, *freq);
1104 ret = -ERANGE;
1105 break;
1106 }
1107 i++;
1108 }
1109 *post_div = map[i].pd;
1110 *div = map[i].d;
1111
1112 tda_map("(%d) %s: post div = 0x%02x, div = 0x%02x\n",
1113 i, map_name, *post_div, *div);
1114fail:
1115 return ret;
1116}
1117
1118int tda18271_lookup_map(struct dvb_frontend *fe,
1119 enum tda18271_map_type map_type,
1120 u32 *freq, u8 *val)
1121{
1122 struct tda18271_priv *priv = fe->tuner_priv;
1123 struct tda18271_map *map = NULL;
1124 unsigned int i = 0;
1125 char *map_name;
1126 int ret = 0;
1127
1128 BUG_ON(!priv->maps);
1129
1130 switch (map_type) {
1131 case BP_FILTER:
1132 map = priv->maps->bp_filter;
1133 map_name = "bp_filter";
1134 break;
1135 case RF_CAL_KMCO:
1136 map = priv->maps->rf_cal_kmco;
1137 map_name = "km";
1138 break;
1139 case RF_BAND:
1140 map = priv->maps->rf_band;
1141 map_name = "rf_band";
1142 break;
1143 case GAIN_TAPER:
1144 map = priv->maps->gain_taper;
1145 map_name = "gain_taper";
1146 break;
1147 case RF_CAL:
1148 map = priv->maps->rf_cal;
1149 map_name = "rf_cal";
1150 break;
1151 case IR_MEASURE:
1152 map = priv->maps->ir_measure;
1153 map_name = "ir_measure";
1154 break;
1155 case RF_CAL_DC_OVER_DT:
1156 map = priv->maps->rf_cal_dc_over_dt;
1157 map_name = "rf_cal_dc_over_dt";
1158 break;
1159 default:
1160 /* we should never get here */
1161 map_name = "undefined";
1162 break;
1163 }
1164
1165 if (!map) {
1166 tda_warn("%s map is not set!\n", map_name);
1167 ret = -EINVAL;
1168 goto fail;
1169 }
1170
1171 while ((map[i].rfmax * 1000) < *freq) {
1172 if (map[i + 1].rfmax == 0) {
1173 tda_map("%s: frequency (%d) out of range\n",
1174 map_name, *freq);
1175 ret = -ERANGE;
1176 break;
1177 }
1178 i++;
1179 }
1180 *val = map[i].val;
1181
1182 tda_map("(%d) %s: 0x%02x\n", i, map_name, *val);
1183fail:
1184 return ret;
1185}
1186
1187/*---------------------------------------------------------------------*/
1188
1189static struct tda18271_std_map tda18271c1_std_map = {
1190 .fm_radio = { .if_freq = 1250, .fm_rfn = 1, .agc_mode = 3, .std = 0,
1191 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x18 */
1192 .atv_b = { .if_freq = 6750, .fm_rfn = 0, .agc_mode = 1, .std = 6,
1193 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
1194 .atv_dk = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
1195 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
1196 .atv_gh = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
1197 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
1198 .atv_i = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
1199 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
1200 .atv_l = { .if_freq = 7750, .fm_rfn = 0, .agc_mode = 1, .std = 7,
1201 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
1202 .atv_lc = { .if_freq = 1250, .fm_rfn = 0, .agc_mode = 1, .std = 7,
1203 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0f */
1204 .atv_mn = { .if_freq = 5750, .fm_rfn = 0, .agc_mode = 1, .std = 5,
1205 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0d */
1206 .atsc_6 = { .if_freq = 3250, .fm_rfn = 0, .agc_mode = 3, .std = 4,
1207 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
1208 .dvbt_6 = { .if_freq = 3300, .fm_rfn = 0, .agc_mode = 3, .std = 4,
1209 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
1210 .dvbt_7 = { .if_freq = 3800, .fm_rfn = 0, .agc_mode = 3, .std = 5,
1211 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
1212 .dvbt_8 = { .if_freq = 4300, .fm_rfn = 0, .agc_mode = 3, .std = 6,
1213 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1e */
1214 .qam_6 = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
1215 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
1216 .qam_7 = { .if_freq = 4500, .fm_rfn = 0, .agc_mode = 3, .std = 6,
1217 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1e */
1218 .qam_8 = { .if_freq = 5000, .fm_rfn = 0, .agc_mode = 3, .std = 7,
1219 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1f */
1220};
1221
1222static struct tda18271_std_map tda18271c2_std_map = {
1223 .fm_radio = { .if_freq = 1250, .fm_rfn = 1, .agc_mode = 3, .std = 0,
1224 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x18 */
1225 .atv_b = { .if_freq = 6000, .fm_rfn = 0, .agc_mode = 1, .std = 5,
1226 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0d */
1227 .atv_dk = { .if_freq = 6900, .fm_rfn = 0, .agc_mode = 1, .std = 6,
1228 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
1229 .atv_gh = { .if_freq = 7100, .fm_rfn = 0, .agc_mode = 1, .std = 6,
1230 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
1231 .atv_i = { .if_freq = 7250, .fm_rfn = 0, .agc_mode = 1, .std = 6,
1232 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
1233 .atv_l = { .if_freq = 6900, .fm_rfn = 0, .agc_mode = 1, .std = 6,
1234 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
1235 .atv_lc = { .if_freq = 1250, .fm_rfn = 0, .agc_mode = 1, .std = 6,
1236 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0e */
1237 .atv_mn = { .if_freq = 5400, .fm_rfn = 0, .agc_mode = 1, .std = 4,
1238 .if_lvl = 0, .rfagc_top = 0x2c, }, /* EP3[4:0] 0x0c */
1239 .atsc_6 = { .if_freq = 3250, .fm_rfn = 0, .agc_mode = 3, .std = 4,
1240 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
1241 .dvbt_6 = { .if_freq = 3300, .fm_rfn = 0, .agc_mode = 3, .std = 4,
1242 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
1243 .dvbt_7 = { .if_freq = 3500, .fm_rfn = 0, .agc_mode = 3, .std = 4,
1244 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1c */
1245 .dvbt_8 = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
1246 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
1247 .qam_6 = { .if_freq = 4000, .fm_rfn = 0, .agc_mode = 3, .std = 5,
1248 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1d */
1249 .qam_7 = { .if_freq = 4500, .fm_rfn = 0, .agc_mode = 3, .std = 6,
1250 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1e */
1251 .qam_8 = { .if_freq = 5000, .fm_rfn = 0, .agc_mode = 3, .std = 7,
1252 .if_lvl = 1, .rfagc_top = 0x37, }, /* EP3[4:0] 0x1f */
1253};
1254
1255/*---------------------------------------------------------------------*/
1256
1257static struct tda18271_map_layout tda18271c1_map_layout = {
1258 .main_pll = tda18271c1_main_pll,
1259 .cal_pll = tda18271c1_cal_pll,
1260
1261 .rf_cal = tda18271c1_rf_cal,
1262 .rf_cal_kmco = tda18271c1_km,
1263
1264 .bp_filter = tda18271_bp_filter,
1265 .rf_band = tda18271_rf_band,
1266 .gain_taper = tda18271_gain_taper,
1267 .ir_measure = tda18271_ir_measure,
1268};
1269
1270static struct tda18271_map_layout tda18271c2_map_layout = {
1271 .main_pll = tda18271c2_main_pll,
1272 .cal_pll = tda18271c2_cal_pll,
1273
1274 .rf_cal = tda18271c2_rf_cal,
1275 .rf_cal_kmco = tda18271c2_km,
1276
1277 .rf_cal_dc_over_dt = tda18271_rf_cal_dc_over_dt,
1278
1279 .bp_filter = tda18271_bp_filter,
1280 .rf_band = tda18271_rf_band,
1281 .gain_taper = tda18271_gain_taper,
1282 .ir_measure = tda18271_ir_measure,
1283};
1284
1285int tda18271_assign_map_layout(struct dvb_frontend *fe)
1286{
1287 struct tda18271_priv *priv = fe->tuner_priv;
1288 int ret = 0;
1289
1290 switch (priv->id) {
1291 case TDA18271HDC1:
1292 priv->maps = &tda18271c1_map_layout;
1293 memcpy(&priv->std, &tda18271c1_std_map,
1294 sizeof(struct tda18271_std_map));
1295 break;
1296 case TDA18271HDC2:
1297 priv->maps = &tda18271c2_map_layout;
1298 memcpy(&priv->std, &tda18271c2_std_map,
1299 sizeof(struct tda18271_std_map));
1300 break;
1301 default:
1302 ret = -EINVAL;
1303 break;
1304 }
1305 memcpy(priv->rf_cal_state, &tda18271_rf_band_template,
1306 sizeof(tda18271_rf_band_template));
1307
1308 return ret;
1309}
1310
1311/*
1312 * Overrides for Emacs so that we follow Linus's tabbing style.
1313 * ---------------------------------------------------------------------------
1314 * Local variables:
1315 * c-basic-offset: 8
1316 * End:
1317 */
diff --git a/drivers/media/tuners/tda18271-priv.h b/drivers/media/tuners/tda18271-priv.h
new file mode 100644
index 000000000000..454c152ccaa0
--- /dev/null
+++ b/drivers/media/tuners/tda18271-priv.h
@@ -0,0 +1,236 @@
1/*
2 tda18271-priv.h - private header for the NXP TDA18271 silicon tuner
3
4 Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef __TDA18271_PRIV_H__
22#define __TDA18271_PRIV_H__
23
24#include <linux/kernel.h>
25#include <linux/types.h>
26#include <linux/mutex.h>
27#include "tuner-i2c.h"
28#include "tda18271.h"
29
30#define R_ID 0x00 /* ID byte */
31#define R_TM 0x01 /* Thermo byte */
32#define R_PL 0x02 /* Power level byte */
33#define R_EP1 0x03 /* Easy Prog byte 1 */
34#define R_EP2 0x04 /* Easy Prog byte 2 */
35#define R_EP3 0x05 /* Easy Prog byte 3 */
36#define R_EP4 0x06 /* Easy Prog byte 4 */
37#define R_EP5 0x07 /* Easy Prog byte 5 */
38#define R_CPD 0x08 /* Cal Post-Divider byte */
39#define R_CD1 0x09 /* Cal Divider byte 1 */
40#define R_CD2 0x0a /* Cal Divider byte 2 */
41#define R_CD3 0x0b /* Cal Divider byte 3 */
42#define R_MPD 0x0c /* Main Post-Divider byte */
43#define R_MD1 0x0d /* Main Divider byte 1 */
44#define R_MD2 0x0e /* Main Divider byte 2 */
45#define R_MD3 0x0f /* Main Divider byte 3 */
46#define R_EB1 0x10 /* Extended byte 1 */
47#define R_EB2 0x11 /* Extended byte 2 */
48#define R_EB3 0x12 /* Extended byte 3 */
49#define R_EB4 0x13 /* Extended byte 4 */
50#define R_EB5 0x14 /* Extended byte 5 */
51#define R_EB6 0x15 /* Extended byte 6 */
52#define R_EB7 0x16 /* Extended byte 7 */
53#define R_EB8 0x17 /* Extended byte 8 */
54#define R_EB9 0x18 /* Extended byte 9 */
55#define R_EB10 0x19 /* Extended byte 10 */
56#define R_EB11 0x1a /* Extended byte 11 */
57#define R_EB12 0x1b /* Extended byte 12 */
58#define R_EB13 0x1c /* Extended byte 13 */
59#define R_EB14 0x1d /* Extended byte 14 */
60#define R_EB15 0x1e /* Extended byte 15 */
61#define R_EB16 0x1f /* Extended byte 16 */
62#define R_EB17 0x20 /* Extended byte 17 */
63#define R_EB18 0x21 /* Extended byte 18 */
64#define R_EB19 0x22 /* Extended byte 19 */
65#define R_EB20 0x23 /* Extended byte 20 */
66#define R_EB21 0x24 /* Extended byte 21 */
67#define R_EB22 0x25 /* Extended byte 22 */
68#define R_EB23 0x26 /* Extended byte 23 */
69
70#define TDA18271_NUM_REGS 39
71
72/*---------------------------------------------------------------------*/
73
74struct tda18271_rf_tracking_filter_cal {
75 u32 rfmax;
76 u8 rfband;
77 u32 rf1_def;
78 u32 rf2_def;
79 u32 rf3_def;
80 u32 rf1;
81 u32 rf2;
82 u32 rf3;
83 s32 rf_a1;
84 s32 rf_b1;
85 s32 rf_a2;
86 s32 rf_b2;
87};
88
89enum tda18271_pll {
90 TDA18271_MAIN_PLL,
91 TDA18271_CAL_PLL,
92};
93
94struct tda18271_map_layout;
95
96enum tda18271_ver {
97 TDA18271HDC1,
98 TDA18271HDC2,
99};
100
101struct tda18271_priv {
102 unsigned char tda18271_regs[TDA18271_NUM_REGS];
103
104 struct list_head hybrid_tuner_instance_list;
105 struct tuner_i2c_props i2c_props;
106
107 enum tda18271_mode mode;
108 enum tda18271_role role;
109 enum tda18271_i2c_gate gate;
110 enum tda18271_ver id;
111 enum tda18271_output_options output_opt;
112 enum tda18271_small_i2c small_i2c;
113
114 unsigned int config; /* interface to saa713x / tda829x */
115 unsigned int cal_initialized:1;
116
117 u8 tm_rfcal;
118
119 struct tda18271_map_layout *maps;
120 struct tda18271_std_map std;
121 struct tda18271_rf_tracking_filter_cal rf_cal_state[8];
122
123 struct mutex lock;
124
125 u16 if_freq;
126
127 u32 frequency;
128 u32 bandwidth;
129};
130
131/*---------------------------------------------------------------------*/
132
133extern int tda18271_debug;
134
135#define DBG_INFO 1
136#define DBG_MAP 2
137#define DBG_REG 4
138#define DBG_ADV 8
139#define DBG_CAL 16
140
141__attribute__((format(printf, 4, 5)))
142int _tda_printk(struct tda18271_priv *state, const char *level,
143 const char *func, const char *fmt, ...);
144
145#define tda_printk(st, lvl, fmt, arg...) \
146 _tda_printk(st, lvl, __func__, fmt, ##arg)
147
148#define tda_dprintk(st, lvl, fmt, arg...) \
149do { \
150 if (tda18271_debug & lvl) \
151 tda_printk(st, KERN_DEBUG, fmt, ##arg); \
152} while (0)
153
154#define tda_info(fmt, arg...) pr_info(fmt, ##arg)
155#define tda_warn(fmt, arg...) tda_printk(priv, KERN_WARNING, fmt, ##arg)
156#define tda_err(fmt, arg...) tda_printk(priv, KERN_ERR, fmt, ##arg)
157#define tda_dbg(fmt, arg...) tda_dprintk(priv, DBG_INFO, fmt, ##arg)
158#define tda_map(fmt, arg...) tda_dprintk(priv, DBG_MAP, fmt, ##arg)
159#define tda_reg(fmt, arg...) tda_dprintk(priv, DBG_REG, fmt, ##arg)
160#define tda_cal(fmt, arg...) tda_dprintk(priv, DBG_CAL, fmt, ##arg)
161
162#define tda_fail(ret) \
163({ \
164 int __ret; \
165 __ret = (ret < 0); \
166 if (__ret) \
167 tda_printk(priv, KERN_ERR, \
168 "error %d on line %d\n", ret, __LINE__); \
169 __ret; \
170})
171
172/*---------------------------------------------------------------------*/
173
174enum tda18271_map_type {
175 /* tda18271_pll_map */
176 MAIN_PLL,
177 CAL_PLL,
178 /* tda18271_map */
179 RF_CAL,
180 RF_CAL_KMCO,
181 RF_CAL_DC_OVER_DT,
182 BP_FILTER,
183 RF_BAND,
184 GAIN_TAPER,
185 IR_MEASURE,
186};
187
188extern int tda18271_lookup_pll_map(struct dvb_frontend *fe,
189 enum tda18271_map_type map_type,
190 u32 *freq, u8 *post_div, u8 *div);
191extern int tda18271_lookup_map(struct dvb_frontend *fe,
192 enum tda18271_map_type map_type,
193 u32 *freq, u8 *val);
194
195extern int tda18271_lookup_thermometer(struct dvb_frontend *fe);
196
197extern int tda18271_lookup_rf_band(struct dvb_frontend *fe,
198 u32 *freq, u8 *rf_band);
199
200extern int tda18271_lookup_cid_target(struct dvb_frontend *fe,
201 u32 *freq, u8 *cid_target,
202 u16 *count_limit);
203
204extern int tda18271_assign_map_layout(struct dvb_frontend *fe);
205
206/*---------------------------------------------------------------------*/
207
208extern int tda18271_read_regs(struct dvb_frontend *fe);
209extern int tda18271_read_extended(struct dvb_frontend *fe);
210extern int tda18271_write_regs(struct dvb_frontend *fe, int idx, int len);
211extern int tda18271_init_regs(struct dvb_frontend *fe);
212
213extern int tda18271_charge_pump_source(struct dvb_frontend *fe,
214 enum tda18271_pll pll, int force);
215extern int tda18271_set_standby_mode(struct dvb_frontend *fe,
216 int sm, int sm_lt, int sm_xt);
217
218extern int tda18271_calc_main_pll(struct dvb_frontend *fe, u32 freq);
219extern int tda18271_calc_cal_pll(struct dvb_frontend *fe, u32 freq);
220
221extern int tda18271_calc_bp_filter(struct dvb_frontend *fe, u32 *freq);
222extern int tda18271_calc_km(struct dvb_frontend *fe, u32 *freq);
223extern int tda18271_calc_rf_band(struct dvb_frontend *fe, u32 *freq);
224extern int tda18271_calc_gain_taper(struct dvb_frontend *fe, u32 *freq);
225extern int tda18271_calc_ir_measure(struct dvb_frontend *fe, u32 *freq);
226extern int tda18271_calc_rf_cal(struct dvb_frontend *fe, u32 *freq);
227
228#endif /* __TDA18271_PRIV_H__ */
229
230/*
231 * Overrides for Emacs so that we follow Linus's tabbing style.
232 * ---------------------------------------------------------------------------
233 * Local variables:
234 * c-basic-offset: 8
235 * End:
236 */
diff --git a/drivers/media/tuners/tda18271.h b/drivers/media/tuners/tda18271.h
new file mode 100644
index 000000000000..640bae4e6a5a
--- /dev/null
+++ b/drivers/media/tuners/tda18271.h
@@ -0,0 +1,134 @@
1/*
2 tda18271.h - header for the Philips / NXP TDA18271 silicon tuner
3
4 Copyright (C) 2007, 2008 Michael Krufky <mkrufky@linuxtv.org>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef __TDA18271_H__
22#define __TDA18271_H__
23
24#include <linux/i2c.h>
25#include "dvb_frontend.h"
26
27struct tda18271_std_map_item {
28 u16 if_freq;
29
30 /* EP3[4:3] */
31 unsigned int agc_mode:2;
32 /* EP3[2:0] */
33 unsigned int std:3;
34 /* EP4[7] */
35 unsigned int fm_rfn:1;
36 /* EP4[4:2] */
37 unsigned int if_lvl:3;
38 /* EB22[6:0] */
39 unsigned int rfagc_top:7;
40};
41
42struct tda18271_std_map {
43 struct tda18271_std_map_item fm_radio;
44 struct tda18271_std_map_item atv_b;
45 struct tda18271_std_map_item atv_dk;
46 struct tda18271_std_map_item atv_gh;
47 struct tda18271_std_map_item atv_i;
48 struct tda18271_std_map_item atv_l;
49 struct tda18271_std_map_item atv_lc;
50 struct tda18271_std_map_item atv_mn;
51 struct tda18271_std_map_item atsc_6;
52 struct tda18271_std_map_item dvbt_6;
53 struct tda18271_std_map_item dvbt_7;
54 struct tda18271_std_map_item dvbt_8;
55 struct tda18271_std_map_item qam_6;
56 struct tda18271_std_map_item qam_7;
57 struct tda18271_std_map_item qam_8;
58};
59
60enum tda18271_role {
61 TDA18271_MASTER = 0,
62 TDA18271_SLAVE,
63};
64
65enum tda18271_i2c_gate {
66 TDA18271_GATE_AUTO = 0,
67 TDA18271_GATE_ANALOG,
68 TDA18271_GATE_DIGITAL,
69};
70
71enum tda18271_output_options {
72 /* slave tuner output & loop thru & xtal oscillator always on */
73 TDA18271_OUTPUT_LT_XT_ON = 0,
74
75 /* slave tuner output loop thru off */
76 TDA18271_OUTPUT_LT_OFF = 1,
77
78 /* xtal oscillator off */
79 TDA18271_OUTPUT_XT_OFF = 2,
80};
81
82enum tda18271_small_i2c {
83 TDA18271_39_BYTE_CHUNK_INIT = 0,
84 TDA18271_16_BYTE_CHUNK_INIT = 16,
85 TDA18271_08_BYTE_CHUNK_INIT = 8,
86 TDA18271_03_BYTE_CHUNK_INIT = 3,
87};
88
89struct tda18271_config {
90 /* override default if freq / std settings (optional) */
91 struct tda18271_std_map *std_map;
92
93 /* master / slave tuner: master uses main pll, slave uses cal pll */
94 enum tda18271_role role;
95
96 /* use i2c gate provided by analog or digital demod */
97 enum tda18271_i2c_gate gate;
98
99 /* output options that can be disabled */
100 enum tda18271_output_options output_opt;
101
102 /* some i2c providers can't write all 39 registers at once */
103 enum tda18271_small_i2c small_i2c;
104
105 /* force rf tracking filter calibration on startup */
106 unsigned int rf_cal_on_startup:1;
107
108 /* interface to saa713x / tda829x */
109 unsigned int config;
110};
111
112#define TDA18271_CALLBACK_CMD_AGC_ENABLE 0
113
114enum tda18271_mode {
115 TDA18271_ANALOG = 0,
116 TDA18271_DIGITAL,
117};
118
119#if defined(CONFIG_MEDIA_TUNER_TDA18271) || (defined(CONFIG_MEDIA_TUNER_TDA18271_MODULE) && defined(MODULE))
120extern struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
121 struct i2c_adapter *i2c,
122 struct tda18271_config *cfg);
123#else
124static inline struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe,
125 u8 addr,
126 struct i2c_adapter *i2c,
127 struct tda18271_config *cfg)
128{
129 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
130 return NULL;
131}
132#endif
133
134#endif /* __TDA18271_H__ */
diff --git a/drivers/media/tuners/tda827x.c b/drivers/media/tuners/tda827x.c
new file mode 100644
index 000000000000..a0d176267470
--- /dev/null
+++ b/drivers/media/tuners/tda827x.c
@@ -0,0 +1,917 @@
1/*
2 *
3 * (c) 2005 Hartmut Hackmann
4 * (c) 2007 Michael Krufky
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19 */
20
21#include <linux/module.h>
22#include <linux/slab.h>
23#include <asm/types.h>
24#include <linux/dvb/frontend.h>
25#include <linux/videodev2.h>
26
27#include "tda827x.h"
28
29static int debug;
30module_param(debug, int, 0644);
31MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
32
33#define dprintk(args...) \
34 do { \
35 if (debug) printk(KERN_DEBUG "tda827x: " args); \
36 } while (0)
37
38struct tda827x_priv {
39 int i2c_addr;
40 struct i2c_adapter *i2c_adap;
41 struct tda827x_config *cfg;
42
43 unsigned int sgIF;
44 unsigned char lpsel;
45
46 u32 frequency;
47 u32 bandwidth;
48};
49
50static void tda827x_set_std(struct dvb_frontend *fe,
51 struct analog_parameters *params)
52{
53 struct tda827x_priv *priv = fe->tuner_priv;
54 char *mode;
55
56 priv->lpsel = 0;
57 if (params->std & V4L2_STD_MN) {
58 priv->sgIF = 92;
59 priv->lpsel = 1;
60 mode = "MN";
61 } else if (params->std & V4L2_STD_B) {
62 priv->sgIF = 108;
63 mode = "B";
64 } else if (params->std & V4L2_STD_GH) {
65 priv->sgIF = 124;
66 mode = "GH";
67 } else if (params->std & V4L2_STD_PAL_I) {
68 priv->sgIF = 124;
69 mode = "I";
70 } else if (params->std & V4L2_STD_DK) {
71 priv->sgIF = 124;
72 mode = "DK";
73 } else if (params->std & V4L2_STD_SECAM_L) {
74 priv->sgIF = 124;
75 mode = "L";
76 } else if (params->std & V4L2_STD_SECAM_LC) {
77 priv->sgIF = 20;
78 mode = "LC";
79 } else {
80 priv->sgIF = 124;
81 mode = "xx";
82 }
83
84 if (params->mode == V4L2_TUNER_RADIO) {
85 priv->sgIF = 88; /* if frequency is 5.5 MHz */
86 dprintk("setting tda827x to radio FM\n");
87 } else
88 dprintk("setting tda827x to system %s\n", mode);
89}
90
91
92/* ------------------------------------------------------------------ */
93
94struct tda827x_data {
95 u32 lomax;
96 u8 spd;
97 u8 bs;
98 u8 bp;
99 u8 cp;
100 u8 gc3;
101 u8 div1p5;
102};
103
104static const struct tda827x_data tda827x_table[] = {
105 { .lomax = 62000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
106 { .lomax = 66000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 1},
107 { .lomax = 76000000, .spd = 3, .bs = 1, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
108 { .lomax = 84000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 3, .div1p5 = 0},
109 { .lomax = 93000000, .spd = 3, .bs = 2, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
110 { .lomax = 98000000, .spd = 3, .bs = 3, .bp = 0, .cp = 0, .gc3 = 1, .div1p5 = 0},
111 { .lomax = 109000000, .spd = 3, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
112 { .lomax = 123000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
113 { .lomax = 133000000, .spd = 2, .bs = 3, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 1},
114 { .lomax = 151000000, .spd = 2, .bs = 1, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
115 { .lomax = 154000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 1, .div1p5 = 0},
116 { .lomax = 181000000, .spd = 2, .bs = 2, .bp = 1, .cp = 0, .gc3 = 0, .div1p5 = 0},
117 { .lomax = 185000000, .spd = 2, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
118 { .lomax = 217000000, .spd = 2, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
119 { .lomax = 244000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
120 { .lomax = 265000000, .spd = 1, .bs = 3, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 1},
121 { .lomax = 302000000, .spd = 1, .bs = 1, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
122 { .lomax = 324000000, .spd = 1, .bs = 2, .bp = 2, .cp = 0, .gc3 = 1, .div1p5 = 0},
123 { .lomax = 370000000, .spd = 1, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
124 { .lomax = 454000000, .spd = 1, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
125 { .lomax = 493000000, .spd = 0, .bs = 2, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
126 { .lomax = 530000000, .spd = 0, .bs = 3, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 1},
127 { .lomax = 554000000, .spd = 0, .bs = 1, .bp = 3, .cp = 0, .gc3 = 1, .div1p5 = 0},
128 { .lomax = 604000000, .spd = 0, .bs = 1, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
129 { .lomax = 696000000, .spd = 0, .bs = 2, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
130 { .lomax = 740000000, .spd = 0, .bs = 2, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
131 { .lomax = 820000000, .spd = 0, .bs = 3, .bp = 4, .cp = 0, .gc3 = 0, .div1p5 = 0},
132 { .lomax = 865000000, .spd = 0, .bs = 3, .bp = 4, .cp = 1, .gc3 = 0, .div1p5 = 0},
133 { .lomax = 0, .spd = 0, .bs = 0, .bp = 0, .cp = 0, .gc3 = 0, .div1p5 = 0}
134};
135
136static int tuner_transfer(struct dvb_frontend *fe,
137 struct i2c_msg *msg,
138 const int size)
139{
140 int rc;
141 struct tda827x_priv *priv = fe->tuner_priv;
142
143 if (fe->ops.i2c_gate_ctrl)
144 fe->ops.i2c_gate_ctrl(fe, 1);
145 rc = i2c_transfer(priv->i2c_adap, msg, size);
146 if (fe->ops.i2c_gate_ctrl)
147 fe->ops.i2c_gate_ctrl(fe, 0);
148
149 if (rc >= 0 && rc != size)
150 return -EIO;
151
152 return rc;
153}
154
155static int tda827xo_set_params(struct dvb_frontend *fe)
156{
157 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
158 struct tda827x_priv *priv = fe->tuner_priv;
159 u8 buf[14];
160 int rc;
161
162 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
163 .buf = buf, .len = sizeof(buf) };
164 int i, tuner_freq, if_freq;
165 u32 N;
166
167 dprintk("%s:\n", __func__);
168 if (c->bandwidth_hz == 0) {
169 if_freq = 5000000;
170 } else if (c->bandwidth_hz <= 6000000) {
171 if_freq = 4000000;
172 } else if (c->bandwidth_hz <= 7000000) {
173 if_freq = 4500000;
174 } else { /* 8 MHz */
175 if_freq = 5000000;
176 }
177 tuner_freq = c->frequency;
178
179 i = 0;
180 while (tda827x_table[i].lomax < tuner_freq) {
181 if (tda827x_table[i + 1].lomax == 0)
182 break;
183 i++;
184 }
185
186 tuner_freq += if_freq;
187
188 N = ((tuner_freq + 125000) / 250000) << (tda827x_table[i].spd + 2);
189 buf[0] = 0;
190 buf[1] = (N>>8) | 0x40;
191 buf[2] = N & 0xff;
192 buf[3] = 0;
193 buf[4] = 0x52;
194 buf[5] = (tda827x_table[i].spd << 6) + (tda827x_table[i].div1p5 << 5) +
195 (tda827x_table[i].bs << 3) +
196 tda827x_table[i].bp;
197 buf[6] = (tda827x_table[i].gc3 << 4) + 0x8f;
198 buf[7] = 0xbf;
199 buf[8] = 0x2a;
200 buf[9] = 0x05;
201 buf[10] = 0xff;
202 buf[11] = 0x00;
203 buf[12] = 0x00;
204 buf[13] = 0x40;
205
206 msg.len = 14;
207 rc = tuner_transfer(fe, &msg, 1);
208 if (rc < 0)
209 goto err;
210
211 msleep(500);
212 /* correct CP value */
213 buf[0] = 0x30;
214 buf[1] = 0x50 + tda827x_table[i].cp;
215 msg.len = 2;
216
217 rc = tuner_transfer(fe, &msg, 1);
218 if (rc < 0)
219 goto err;
220
221 priv->frequency = c->frequency;
222 priv->bandwidth = c->bandwidth_hz;
223
224 return 0;
225
226err:
227 printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
228 __func__, priv->i2c_addr << 1);
229 return rc;
230}
231
232static int tda827xo_sleep(struct dvb_frontend *fe)
233{
234 struct tda827x_priv *priv = fe->tuner_priv;
235 static u8 buf[] = { 0x30, 0xd0 };
236 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
237 .buf = buf, .len = sizeof(buf) };
238
239 dprintk("%s:\n", __func__);
240 tuner_transfer(fe, &msg, 1);
241
242 if (priv->cfg && priv->cfg->sleep)
243 priv->cfg->sleep(fe);
244
245 return 0;
246}
247
248/* ------------------------------------------------------------------ */
249
250static int tda827xo_set_analog_params(struct dvb_frontend *fe,
251 struct analog_parameters *params)
252{
253 unsigned char tuner_reg[8];
254 unsigned char reg2[2];
255 u32 N;
256 int i;
257 struct tda827x_priv *priv = fe->tuner_priv;
258 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0 };
259 unsigned int freq = params->frequency;
260
261 tda827x_set_std(fe, params);
262
263 if (params->mode == V4L2_TUNER_RADIO)
264 freq = freq / 1000;
265
266 N = freq + priv->sgIF;
267
268 i = 0;
269 while (tda827x_table[i].lomax < N * 62500) {
270 if (tda827x_table[i + 1].lomax == 0)
271 break;
272 i++;
273 }
274
275 N = N << tda827x_table[i].spd;
276
277 tuner_reg[0] = 0;
278 tuner_reg[1] = (unsigned char)(N>>8);
279 tuner_reg[2] = (unsigned char) N;
280 tuner_reg[3] = 0x40;
281 tuner_reg[4] = 0x52 + (priv->lpsel << 5);
282 tuner_reg[5] = (tda827x_table[i].spd << 6) +
283 (tda827x_table[i].div1p5 << 5) +
284 (tda827x_table[i].bs << 3) + tda827x_table[i].bp;
285 tuner_reg[6] = 0x8f + (tda827x_table[i].gc3 << 4);
286 tuner_reg[7] = 0x8f;
287
288 msg.buf = tuner_reg;
289 msg.len = 8;
290 tuner_transfer(fe, &msg, 1);
291
292 msg.buf = reg2;
293 msg.len = 2;
294 reg2[0] = 0x80;
295 reg2[1] = 0;
296 tuner_transfer(fe, &msg, 1);
297
298 reg2[0] = 0x60;
299 reg2[1] = 0xbf;
300 tuner_transfer(fe, &msg, 1);
301
302 reg2[0] = 0x30;
303 reg2[1] = tuner_reg[4] + 0x80;
304 tuner_transfer(fe, &msg, 1);
305
306 msleep(1);
307 reg2[0] = 0x30;
308 reg2[1] = tuner_reg[4] + 4;
309 tuner_transfer(fe, &msg, 1);
310
311 msleep(1);
312 reg2[0] = 0x30;
313 reg2[1] = tuner_reg[4];
314 tuner_transfer(fe, &msg, 1);
315
316 msleep(550);
317 reg2[0] = 0x30;
318 reg2[1] = (tuner_reg[4] & 0xfc) + tda827x_table[i].cp;
319 tuner_transfer(fe, &msg, 1);
320
321 reg2[0] = 0x60;
322 reg2[1] = 0x3f;
323 tuner_transfer(fe, &msg, 1);
324
325 reg2[0] = 0x80;
326 reg2[1] = 0x08; /* Vsync en */
327 tuner_transfer(fe, &msg, 1);
328
329 priv->frequency = params->frequency;
330
331 return 0;
332}
333
334static void tda827xo_agcf(struct dvb_frontend *fe)
335{
336 struct tda827x_priv *priv = fe->tuner_priv;
337 unsigned char data[] = { 0x80, 0x0c };
338 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
339 .buf = data, .len = 2};
340
341 tuner_transfer(fe, &msg, 1);
342}
343
344/* ------------------------------------------------------------------ */
345
346struct tda827xa_data {
347 u32 lomax;
348 u8 svco;
349 u8 spd;
350 u8 scr;
351 u8 sbs;
352 u8 gc3;
353};
354
355static struct tda827xa_data tda827xa_dvbt[] = {
356 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 1},
357 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
358 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
359 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 1},
360 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
361 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
362 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
363 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
364 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
365 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
366 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
367 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
368 { .lomax = 290000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
369 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
370 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
371 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 1},
372 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
373 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
374 { .lomax = 550000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
375 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
376 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
377 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
378 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
379 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
380 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
381 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
382 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
383};
384
385static struct tda827xa_data tda827xa_dvbc[] = {
386 { .lomax = 50125000, .svco = 2, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
387 { .lomax = 58500000, .svco = 3, .spd = 4, .scr = 2, .sbs = 0, .gc3 = 3},
388 { .lomax = 69250000, .svco = 0, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
389 { .lomax = 83625000, .svco = 1, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
390 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 2, .sbs = 0, .gc3 = 3},
391 { .lomax = 100250000, .svco = 2, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
392 { .lomax = 117000000, .svco = 3, .spd = 3, .scr = 2, .sbs = 1, .gc3 = 1},
393 { .lomax = 138500000, .svco = 0, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
394 { .lomax = 167250000, .svco = 1, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
395 { .lomax = 187000000, .svco = 2, .spd = 2, .scr = 2, .sbs = 1, .gc3 = 1},
396 { .lomax = 200500000, .svco = 2, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 1},
397 { .lomax = 234000000, .svco = 3, .spd = 2, .scr = 2, .sbs = 2, .gc3 = 3},
398 { .lomax = 277000000, .svco = 0, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 3},
399 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 2, .sbs = 2, .gc3 = 1},
400 { .lomax = 334500000, .svco = 1, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
401 { .lomax = 401000000, .svco = 2, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 3},
402 { .lomax = 468000000, .svco = 3, .spd = 1, .scr = 2, .sbs = 3, .gc3 = 1},
403 { .lomax = 535000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
404 { .lomax = 554000000, .svco = 0, .spd = 0, .scr = 2, .sbs = 3, .gc3 = 1},
405 { .lomax = 638000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
406 { .lomax = 669000000, .svco = 1, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
407 { .lomax = 720000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
408 { .lomax = 802000000, .svco = 2, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
409 { .lomax = 835000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
410 { .lomax = 885000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 1},
411 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 1},
412 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
413};
414
415static struct tda827xa_data tda827xa_analog[] = {
416 { .lomax = 56875000, .svco = 3, .spd = 4, .scr = 0, .sbs = 0, .gc3 = 3},
417 { .lomax = 67250000, .svco = 0, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
418 { .lomax = 81250000, .svco = 1, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
419 { .lomax = 97500000, .svco = 2, .spd = 3, .scr = 0, .sbs = 0, .gc3 = 3},
420 { .lomax = 113750000, .svco = 3, .spd = 3, .scr = 0, .sbs = 1, .gc3 = 1},
421 { .lomax = 134500000, .svco = 0, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
422 { .lomax = 154000000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
423 { .lomax = 162500000, .svco = 1, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
424 { .lomax = 183000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 1, .gc3 = 1},
425 { .lomax = 195000000, .svco = 2, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 1},
426 { .lomax = 227500000, .svco = 3, .spd = 2, .scr = 0, .sbs = 2, .gc3 = 3},
427 { .lomax = 269000000, .svco = 0, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 3},
428 { .lomax = 325000000, .svco = 1, .spd = 1, .scr = 0, .sbs = 2, .gc3 = 1},
429 { .lomax = 390000000, .svco = 2, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
430 { .lomax = 455000000, .svco = 3, .spd = 1, .scr = 0, .sbs = 3, .gc3 = 3},
431 { .lomax = 520000000, .svco = 0, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
432 { .lomax = 538000000, .svco = 0, .spd = 0, .scr = 1, .sbs = 3, .gc3 = 1},
433 { .lomax = 554000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 3, .gc3 = 1},
434 { .lomax = 620000000, .svco = 1, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
435 { .lomax = 650000000, .svco = 1, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
436 { .lomax = 700000000, .svco = 2, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
437 { .lomax = 780000000, .svco = 2, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
438 { .lomax = 820000000, .svco = 3, .spd = 0, .scr = 0, .sbs = 4, .gc3 = 0},
439 { .lomax = 870000000, .svco = 3, .spd = 0, .scr = 1, .sbs = 4, .gc3 = 0},
440 { .lomax = 911000000, .svco = 3, .spd = 0, .scr = 2, .sbs = 4, .gc3 = 0},
441 { .lomax = 0, .svco = 0, .spd = 0, .scr = 0, .sbs = 0, .gc3 = 0}
442};
443
444static int tda827xa_sleep(struct dvb_frontend *fe)
445{
446 struct tda827x_priv *priv = fe->tuner_priv;
447 static u8 buf[] = { 0x30, 0x90 };
448 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
449 .buf = buf, .len = sizeof(buf) };
450
451 dprintk("%s:\n", __func__);
452
453 tuner_transfer(fe, &msg, 1);
454
455 if (priv->cfg && priv->cfg->sleep)
456 priv->cfg->sleep(fe);
457
458 return 0;
459}
460
461static void tda827xa_lna_gain(struct dvb_frontend *fe, int high,
462 struct analog_parameters *params)
463{
464 struct tda827x_priv *priv = fe->tuner_priv;
465 unsigned char buf[] = {0x22, 0x01};
466 int arg;
467 int gp_func;
468 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = sizeof(buf) };
469
470 if (NULL == priv->cfg) {
471 dprintk("tda827x_config not defined, cannot set LNA gain!\n");
472 return;
473 }
474 msg.addr = priv->cfg->switch_addr;
475 if (priv->cfg->config) {
476 if (high)
477 dprintk("setting LNA to high gain\n");
478 else
479 dprintk("setting LNA to low gain\n");
480 }
481 switch (priv->cfg->config) {
482 case 0: /* no LNA */
483 break;
484 case 1: /* switch is GPIO 0 of tda8290 */
485 case 2:
486 if (params == NULL) {
487 gp_func = 0;
488 arg = 0;
489 } else {
490 /* turn Vsync on */
491 gp_func = 1;
492 if (params->std & V4L2_STD_MN)
493 arg = 1;
494 else
495 arg = 0;
496 }
497 if (fe->callback)
498 fe->callback(priv->i2c_adap->algo_data,
499 DVB_FRONTEND_COMPONENT_TUNER,
500 gp_func, arg);
501 buf[1] = high ? 0 : 1;
502 if (priv->cfg->config == 2)
503 buf[1] = high ? 1 : 0;
504 tuner_transfer(fe, &msg, 1);
505 break;
506 case 3: /* switch with GPIO of saa713x */
507 if (fe->callback)
508 fe->callback(priv->i2c_adap->algo_data,
509 DVB_FRONTEND_COMPONENT_TUNER, 0, high);
510 break;
511 }
512}
513
514static int tda827xa_set_params(struct dvb_frontend *fe)
515{
516 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
517 struct tda827x_priv *priv = fe->tuner_priv;
518 struct tda827xa_data *frequency_map = tda827xa_dvbt;
519 u8 buf[11];
520
521 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
522 .buf = buf, .len = sizeof(buf) };
523
524 int i, tuner_freq, if_freq, rc;
525 u32 N;
526
527 dprintk("%s:\n", __func__);
528
529 tda827xa_lna_gain(fe, 1, NULL);
530 msleep(20);
531
532 if (c->bandwidth_hz == 0) {
533 if_freq = 5000000;
534 } else if (c->bandwidth_hz <= 6000000) {
535 if_freq = 4000000;
536 } else if (c->bandwidth_hz <= 7000000) {
537 if_freq = 4500000;
538 } else { /* 8 MHz */
539 if_freq = 5000000;
540 }
541 tuner_freq = c->frequency;
542
543 switch (c->delivery_system) {
544 case SYS_DVBC_ANNEX_A:
545 case SYS_DVBC_ANNEX_C:
546 dprintk("%s select tda827xa_dvbc\n", __func__);
547 frequency_map = tda827xa_dvbc;
548 break;
549 default:
550 break;
551 }
552
553 i = 0;
554 while (frequency_map[i].lomax < tuner_freq) {
555 if (frequency_map[i + 1].lomax == 0)
556 break;
557 i++;
558 }
559
560 tuner_freq += if_freq;
561
562 N = ((tuner_freq + 31250) / 62500) << frequency_map[i].spd;
563 buf[0] = 0; // subaddress
564 buf[1] = N >> 8;
565 buf[2] = N & 0xff;
566 buf[3] = 0;
567 buf[4] = 0x16;
568 buf[5] = (frequency_map[i].spd << 5) + (frequency_map[i].svco << 3) +
569 frequency_map[i].sbs;
570 buf[6] = 0x4b + (frequency_map[i].gc3 << 4);
571 buf[7] = 0x1c;
572 buf[8] = 0x06;
573 buf[9] = 0x24;
574 buf[10] = 0x00;
575 msg.len = 11;
576 rc = tuner_transfer(fe, &msg, 1);
577 if (rc < 0)
578 goto err;
579
580 buf[0] = 0x90;
581 buf[1] = 0xff;
582 buf[2] = 0x60;
583 buf[3] = 0x00;
584 buf[4] = 0x59; // lpsel, for 6MHz + 2
585 msg.len = 5;
586 rc = tuner_transfer(fe, &msg, 1);
587 if (rc < 0)
588 goto err;
589
590 buf[0] = 0xa0;
591 buf[1] = 0x40;
592 msg.len = 2;
593 rc = tuner_transfer(fe, &msg, 1);
594 if (rc < 0)
595 goto err;
596
597 msleep(11);
598 msg.flags = I2C_M_RD;
599 rc = tuner_transfer(fe, &msg, 1);
600 if (rc < 0)
601 goto err;
602 msg.flags = 0;
603
604 buf[1] >>= 4;
605 dprintk("tda8275a AGC2 gain is: %d\n", buf[1]);
606 if ((buf[1]) < 2) {
607 tda827xa_lna_gain(fe, 0, NULL);
608 buf[0] = 0x60;
609 buf[1] = 0x0c;
610 rc = tuner_transfer(fe, &msg, 1);
611 if (rc < 0)
612 goto err;
613 }
614
615 buf[0] = 0xc0;
616 buf[1] = 0x99; // lpsel, for 6MHz + 2
617 rc = tuner_transfer(fe, &msg, 1);
618 if (rc < 0)
619 goto err;
620
621 buf[0] = 0x60;
622 buf[1] = 0x3c;
623 rc = tuner_transfer(fe, &msg, 1);
624 if (rc < 0)
625 goto err;
626
627 /* correct CP value */
628 buf[0] = 0x30;
629 buf[1] = 0x10 + frequency_map[i].scr;
630 rc = tuner_transfer(fe, &msg, 1);
631 if (rc < 0)
632 goto err;
633
634 msleep(163);
635 buf[0] = 0xc0;
636 buf[1] = 0x39; // lpsel, for 6MHz + 2
637 rc = tuner_transfer(fe, &msg, 1);
638 if (rc < 0)
639 goto err;
640
641 msleep(3);
642 /* freeze AGC1 */
643 buf[0] = 0x50;
644 buf[1] = 0x4f + (frequency_map[i].gc3 << 4);
645 rc = tuner_transfer(fe, &msg, 1);
646 if (rc < 0)
647 goto err;
648
649 priv->frequency = c->frequency;
650 priv->bandwidth = c->bandwidth_hz;
651
652 return 0;
653
654err:
655 printk(KERN_ERR "%s: could not write to tuner at addr: 0x%02x\n",
656 __func__, priv->i2c_addr << 1);
657 return rc;
658}
659
660
661static int tda827xa_set_analog_params(struct dvb_frontend *fe,
662 struct analog_parameters *params)
663{
664 unsigned char tuner_reg[11];
665 u32 N;
666 int i;
667 struct tda827x_priv *priv = fe->tuner_priv;
668 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = 0,
669 .buf = tuner_reg, .len = sizeof(tuner_reg) };
670 unsigned int freq = params->frequency;
671
672 tda827x_set_std(fe, params);
673
674 tda827xa_lna_gain(fe, 1, params);
675 msleep(10);
676
677 if (params->mode == V4L2_TUNER_RADIO)
678 freq = freq / 1000;
679
680 N = freq + priv->sgIF;
681
682 i = 0;
683 while (tda827xa_analog[i].lomax < N * 62500) {
684 if (tda827xa_analog[i + 1].lomax == 0)
685 break;
686 i++;
687 }
688
689 N = N << tda827xa_analog[i].spd;
690
691 tuner_reg[0] = 0;
692 tuner_reg[1] = (unsigned char)(N>>8);
693 tuner_reg[2] = (unsigned char) N;
694 tuner_reg[3] = 0;
695 tuner_reg[4] = 0x16;
696 tuner_reg[5] = (tda827xa_analog[i].spd << 5) +
697 (tda827xa_analog[i].svco << 3) +
698 tda827xa_analog[i].sbs;
699 tuner_reg[6] = 0x8b + (tda827xa_analog[i].gc3 << 4);
700 tuner_reg[7] = 0x1c;
701 tuner_reg[8] = 4;
702 tuner_reg[9] = 0x20;
703 tuner_reg[10] = 0x00;
704 msg.len = 11;
705 tuner_transfer(fe, &msg, 1);
706
707 tuner_reg[0] = 0x90;
708 tuner_reg[1] = 0xff;
709 tuner_reg[2] = 0xe0;
710 tuner_reg[3] = 0;
711 tuner_reg[4] = 0x99 + (priv->lpsel << 1);
712 msg.len = 5;
713 tuner_transfer(fe, &msg, 1);
714
715 tuner_reg[0] = 0xa0;
716 tuner_reg[1] = 0xc0;
717 msg.len = 2;
718 tuner_transfer(fe, &msg, 1);
719
720 tuner_reg[0] = 0x30;
721 tuner_reg[1] = 0x10 + tda827xa_analog[i].scr;
722 tuner_transfer(fe, &msg, 1);
723
724 msg.flags = I2C_M_RD;
725 tuner_transfer(fe, &msg, 1);
726 msg.flags = 0;
727 tuner_reg[1] >>= 4;
728 dprintk("AGC2 gain is: %d\n", tuner_reg[1]);
729 if (tuner_reg[1] < 1)
730 tda827xa_lna_gain(fe, 0, params);
731
732 msleep(100);
733 tuner_reg[0] = 0x60;
734 tuner_reg[1] = 0x3c;
735 tuner_transfer(fe, &msg, 1);
736
737 msleep(163);
738 tuner_reg[0] = 0x50;
739 tuner_reg[1] = 0x8f + (tda827xa_analog[i].gc3 << 4);
740 tuner_transfer(fe, &msg, 1);
741
742 tuner_reg[0] = 0x80;
743 tuner_reg[1] = 0x28;
744 tuner_transfer(fe, &msg, 1);
745
746 tuner_reg[0] = 0xb0;
747 tuner_reg[1] = 0x01;
748 tuner_transfer(fe, &msg, 1);
749
750 tuner_reg[0] = 0xc0;
751 tuner_reg[1] = 0x19 + (priv->lpsel << 1);
752 tuner_transfer(fe, &msg, 1);
753
754 priv->frequency = params->frequency;
755
756 return 0;
757}
758
759static void tda827xa_agcf(struct dvb_frontend *fe)
760{
761 struct tda827x_priv *priv = fe->tuner_priv;
762 unsigned char data[] = {0x80, 0x2c};
763 struct i2c_msg msg = {.addr = priv->i2c_addr, .flags = 0,
764 .buf = data, .len = 2};
765 tuner_transfer(fe, &msg, 1);
766}
767
768/* ------------------------------------------------------------------ */
769
770static int tda827x_release(struct dvb_frontend *fe)
771{
772 kfree(fe->tuner_priv);
773 fe->tuner_priv = NULL;
774 return 0;
775}
776
777static int tda827x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
778{
779 struct tda827x_priv *priv = fe->tuner_priv;
780 *frequency = priv->frequency;
781 return 0;
782}
783
784static int tda827x_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
785{
786 struct tda827x_priv *priv = fe->tuner_priv;
787 *bandwidth = priv->bandwidth;
788 return 0;
789}
790
791static int tda827x_init(struct dvb_frontend *fe)
792{
793 struct tda827x_priv *priv = fe->tuner_priv;
794 dprintk("%s:\n", __func__);
795 if (priv->cfg && priv->cfg->init)
796 priv->cfg->init(fe);
797
798 return 0;
799}
800
801static int tda827x_probe_version(struct dvb_frontend *fe);
802
803static int tda827x_initial_init(struct dvb_frontend *fe)
804{
805 int ret;
806 ret = tda827x_probe_version(fe);
807 if (ret)
808 return ret;
809 return fe->ops.tuner_ops.init(fe);
810}
811
812static int tda827x_initial_sleep(struct dvb_frontend *fe)
813{
814 int ret;
815 ret = tda827x_probe_version(fe);
816 if (ret)
817 return ret;
818 return fe->ops.tuner_ops.sleep(fe);
819}
820
821static struct dvb_tuner_ops tda827xo_tuner_ops = {
822 .info = {
823 .name = "Philips TDA827X",
824 .frequency_min = 55000000,
825 .frequency_max = 860000000,
826 .frequency_step = 250000
827 },
828 .release = tda827x_release,
829 .init = tda827x_initial_init,
830 .sleep = tda827x_initial_sleep,
831 .set_params = tda827xo_set_params,
832 .set_analog_params = tda827xo_set_analog_params,
833 .get_frequency = tda827x_get_frequency,
834 .get_bandwidth = tda827x_get_bandwidth,
835};
836
837static struct dvb_tuner_ops tda827xa_tuner_ops = {
838 .info = {
839 .name = "Philips TDA827XA",
840 .frequency_min = 44000000,
841 .frequency_max = 906000000,
842 .frequency_step = 62500
843 },
844 .release = tda827x_release,
845 .init = tda827x_init,
846 .sleep = tda827xa_sleep,
847 .set_params = tda827xa_set_params,
848 .set_analog_params = tda827xa_set_analog_params,
849 .get_frequency = tda827x_get_frequency,
850 .get_bandwidth = tda827x_get_bandwidth,
851};
852
853static int tda827x_probe_version(struct dvb_frontend *fe)
854{
855 u8 data;
856 int rc;
857 struct tda827x_priv *priv = fe->tuner_priv;
858 struct i2c_msg msg = { .addr = priv->i2c_addr, .flags = I2C_M_RD,
859 .buf = &data, .len = 1 };
860
861 rc = tuner_transfer(fe, &msg, 1);
862
863 if (rc < 0) {
864 printk("%s: could not read from tuner at addr: 0x%02x\n",
865 __func__, msg.addr << 1);
866 return rc;
867 }
868 if ((data & 0x3c) == 0) {
869 dprintk("tda827x tuner found\n");
870 fe->ops.tuner_ops.init = tda827x_init;
871 fe->ops.tuner_ops.sleep = tda827xo_sleep;
872 if (priv->cfg)
873 priv->cfg->agcf = tda827xo_agcf;
874 } else {
875 dprintk("tda827xa tuner found\n");
876 memcpy(&fe->ops.tuner_ops, &tda827xa_tuner_ops, sizeof(struct dvb_tuner_ops));
877 if (priv->cfg)
878 priv->cfg->agcf = tda827xa_agcf;
879 }
880 return 0;
881}
882
883struct dvb_frontend *tda827x_attach(struct dvb_frontend *fe, int addr,
884 struct i2c_adapter *i2c,
885 struct tda827x_config *cfg)
886{
887 struct tda827x_priv *priv = NULL;
888
889 dprintk("%s:\n", __func__);
890 priv = kzalloc(sizeof(struct tda827x_priv), GFP_KERNEL);
891 if (priv == NULL)
892 return NULL;
893
894 priv->i2c_addr = addr;
895 priv->i2c_adap = i2c;
896 priv->cfg = cfg;
897 memcpy(&fe->ops.tuner_ops, &tda827xo_tuner_ops, sizeof(struct dvb_tuner_ops));
898 fe->tuner_priv = priv;
899
900 dprintk("type set to %s\n", fe->ops.tuner_ops.info.name);
901
902 return fe;
903}
904EXPORT_SYMBOL_GPL(tda827x_attach);
905
906MODULE_DESCRIPTION("DVB TDA827x driver");
907MODULE_AUTHOR("Hartmut Hackmann <hartmut.hackmann@t-online.de>");
908MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
909MODULE_LICENSE("GPL");
910
911/*
912 * Overrides for Emacs so that we follow Linus's tabbing style.
913 * ---------------------------------------------------------------------------
914 * Local variables:
915 * c-basic-offset: 8
916 * End:
917 */
diff --git a/drivers/media/tuners/tda827x.h b/drivers/media/tuners/tda827x.h
new file mode 100644
index 000000000000..7d72ce0a0c2d
--- /dev/null
+++ b/drivers/media/tuners/tda827x.h
@@ -0,0 +1,68 @@
1 /*
2 DVB Driver for Philips tda827x / tda827xa Silicon tuners
3
4 (c) 2005 Hartmut Hackmann
5 (c) 2007 Michael Krufky
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21
22 */
23
24#ifndef __DVB_TDA827X_H__
25#define __DVB_TDA827X_H__
26
27#include <linux/i2c.h>
28#include "dvb_frontend.h"
29
30struct tda827x_config
31{
32 /* saa7134 - provided callbacks */
33 int (*init) (struct dvb_frontend *fe);
34 int (*sleep) (struct dvb_frontend *fe);
35
36 /* interface to tda829x driver */
37 unsigned int config;
38 int switch_addr;
39
40 void (*agcf)(struct dvb_frontend *fe);
41};
42
43
44/**
45 * Attach a tda827x tuner to the supplied frontend structure.
46 *
47 * @param fe Frontend to attach to.
48 * @param addr i2c address of the tuner.
49 * @param i2c i2c adapter to use.
50 * @param cfg optional callback function pointers.
51 * @return FE pointer on success, NULL on failure.
52 */
53#if defined(CONFIG_MEDIA_TUNER_TDA827X) || (defined(CONFIG_MEDIA_TUNER_TDA827X_MODULE) && defined(MODULE))
54extern struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe, int addr,
55 struct i2c_adapter *i2c,
56 struct tda827x_config *cfg);
57#else
58static inline struct dvb_frontend* tda827x_attach(struct dvb_frontend *fe,
59 int addr,
60 struct i2c_adapter *i2c,
61 struct tda827x_config *cfg)
62{
63 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
64 return NULL;
65}
66#endif // CONFIG_MEDIA_TUNER_TDA827X
67
68#endif // __DVB_TDA827X_H__
diff --git a/drivers/media/tuners/tda8290.c b/drivers/media/tuners/tda8290.c
new file mode 100644
index 000000000000..8c4852114eeb
--- /dev/null
+++ b/drivers/media/tuners/tda8290.c
@@ -0,0 +1,874 @@
1/*
2
3 i2c tv tuner chip device driver
4 controls the philips tda8290+75 tuner chip combo.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19
20 This "tda8290" module was split apart from the original "tuner" module.
21*/
22
23#include <linux/i2c.h>
24#include <linux/slab.h>
25#include <linux/delay.h>
26#include <linux/videodev2.h>
27#include "tuner-i2c.h"
28#include "tda8290.h"
29#include "tda827x.h"
30#include "tda18271.h"
31
32static int debug;
33module_param(debug, int, 0644);
34MODULE_PARM_DESC(debug, "enable verbose debug messages");
35
36static int deemphasis_50;
37module_param(deemphasis_50, int, 0644);
38MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
39
40/* ---------------------------------------------------------------------- */
41
42struct tda8290_priv {
43 struct tuner_i2c_props i2c_props;
44
45 unsigned char tda8290_easy_mode;
46
47 unsigned char tda827x_addr;
48
49 unsigned char ver;
50#define TDA8290 1
51#define TDA8295 2
52#define TDA8275 4
53#define TDA8275A 8
54#define TDA18271 16
55
56 struct tda827x_config cfg;
57};
58
59/*---------------------------------------------------------------------*/
60
61static int tda8290_i2c_bridge(struct dvb_frontend *fe, int close)
62{
63 struct tda8290_priv *priv = fe->analog_demod_priv;
64
65 unsigned char enable[2] = { 0x21, 0xC0 };
66 unsigned char disable[2] = { 0x21, 0x00 };
67 unsigned char *msg;
68
69 if (close) {
70 msg = enable;
71 tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
72 /* let the bridge stabilize */
73 msleep(20);
74 } else {
75 msg = disable;
76 tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
77 }
78
79 return 0;
80}
81
82static int tda8295_i2c_bridge(struct dvb_frontend *fe, int close)
83{
84 struct tda8290_priv *priv = fe->analog_demod_priv;
85
86 unsigned char enable[2] = { 0x45, 0xc1 };
87 unsigned char disable[2] = { 0x46, 0x00 };
88 unsigned char buf[3] = { 0x45, 0x01, 0x00 };
89 unsigned char *msg;
90
91 if (close) {
92 msg = enable;
93 tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
94 /* let the bridge stabilize */
95 msleep(20);
96 } else {
97 msg = disable;
98 tuner_i2c_xfer_send_recv(&priv->i2c_props, msg, 1, &msg[1], 1);
99
100 buf[2] = msg[1];
101 buf[2] &= ~0x04;
102 tuner_i2c_xfer_send(&priv->i2c_props, buf, 3);
103 msleep(5);
104
105 msg[1] |= 0x04;
106 tuner_i2c_xfer_send(&priv->i2c_props, msg, 2);
107 }
108
109 return 0;
110}
111
112/*---------------------------------------------------------------------*/
113
114static void set_audio(struct dvb_frontend *fe,
115 struct analog_parameters *params)
116{
117 struct tda8290_priv *priv = fe->analog_demod_priv;
118 char* mode;
119
120 if (params->std & V4L2_STD_MN) {
121 priv->tda8290_easy_mode = 0x01;
122 mode = "MN";
123 } else if (params->std & V4L2_STD_B) {
124 priv->tda8290_easy_mode = 0x02;
125 mode = "B";
126 } else if (params->std & V4L2_STD_GH) {
127 priv->tda8290_easy_mode = 0x04;
128 mode = "GH";
129 } else if (params->std & V4L2_STD_PAL_I) {
130 priv->tda8290_easy_mode = 0x08;
131 mode = "I";
132 } else if (params->std & V4L2_STD_DK) {
133 priv->tda8290_easy_mode = 0x10;
134 mode = "DK";
135 } else if (params->std & V4L2_STD_SECAM_L) {
136 priv->tda8290_easy_mode = 0x20;
137 mode = "L";
138 } else if (params->std & V4L2_STD_SECAM_LC) {
139 priv->tda8290_easy_mode = 0x40;
140 mode = "LC";
141 } else {
142 priv->tda8290_easy_mode = 0x10;
143 mode = "xx";
144 }
145
146 if (params->mode == V4L2_TUNER_RADIO) {
147 /* Set TDA8295 to FM radio; Start TDA8290 with MN values */
148 priv->tda8290_easy_mode = (priv->ver & TDA8295) ? 0x80 : 0x01;
149 tuner_dbg("setting to radio FM\n");
150 } else {
151 tuner_dbg("setting tda829x to system %s\n", mode);
152 }
153}
154
155static struct {
156 unsigned char seq[2];
157} fm_mode[] = {
158 { { 0x01, 0x81} }, /* Put device into expert mode */
159 { { 0x03, 0x48} }, /* Disable NOTCH and VIDEO filters */
160 { { 0x04, 0x04} }, /* Disable color carrier filter (SSIF) */
161 { { 0x05, 0x04} }, /* ADC headroom */
162 { { 0x06, 0x10} }, /* group delay flat */
163
164 { { 0x07, 0x00} }, /* use the same radio DTO values as a tda8295 */
165 { { 0x08, 0x00} },
166 { { 0x09, 0x80} },
167 { { 0x0a, 0xda} },
168 { { 0x0b, 0x4b} },
169 { { 0x0c, 0x68} },
170
171 { { 0x0d, 0x00} }, /* PLL off, no video carrier detect */
172 { { 0x14, 0x00} }, /* disable auto mute if no video */
173};
174
175static void tda8290_set_params(struct dvb_frontend *fe,
176 struct analog_parameters *params)
177{
178 struct tda8290_priv *priv = fe->analog_demod_priv;
179
180 unsigned char soft_reset[] = { 0x00, 0x00 };
181 unsigned char easy_mode[] = { 0x01, priv->tda8290_easy_mode };
182 unsigned char expert_mode[] = { 0x01, 0x80 };
183 unsigned char agc_out_on[] = { 0x02, 0x00 };
184 unsigned char gainset_off[] = { 0x28, 0x14 };
185 unsigned char if_agc_spd[] = { 0x0f, 0x88 };
186 unsigned char adc_head_6[] = { 0x05, 0x04 };
187 unsigned char adc_head_9[] = { 0x05, 0x02 };
188 unsigned char adc_head_12[] = { 0x05, 0x01 };
189 unsigned char pll_bw_nom[] = { 0x0d, 0x47 };
190 unsigned char pll_bw_low[] = { 0x0d, 0x27 };
191 unsigned char gainset_2[] = { 0x28, 0x64 };
192 unsigned char agc_rst_on[] = { 0x0e, 0x0b };
193 unsigned char agc_rst_off[] = { 0x0e, 0x09 };
194 unsigned char if_agc_set[] = { 0x0f, 0x81 };
195 unsigned char addr_adc_sat = 0x1a;
196 unsigned char addr_agc_stat = 0x1d;
197 unsigned char addr_pll_stat = 0x1b;
198 unsigned char adc_sat, agc_stat,
199 pll_stat;
200 int i;
201
202 set_audio(fe, params);
203
204 if (priv->cfg.config)
205 tuner_dbg("tda827xa config is 0x%02x\n", priv->cfg.config);
206 tuner_i2c_xfer_send(&priv->i2c_props, easy_mode, 2);
207 tuner_i2c_xfer_send(&priv->i2c_props, agc_out_on, 2);
208 tuner_i2c_xfer_send(&priv->i2c_props, soft_reset, 2);
209 msleep(1);
210
211 if (params->mode == V4L2_TUNER_RADIO) {
212 unsigned char deemphasis[] = { 0x13, 1 };
213
214 /* FIXME: allow using a different deemphasis */
215
216 if (deemphasis_50)
217 deemphasis[1] = 2;
218
219 for (i = 0; i < ARRAY_SIZE(fm_mode); i++)
220 tuner_i2c_xfer_send(&priv->i2c_props, fm_mode[i].seq, 2);
221
222 tuner_i2c_xfer_send(&priv->i2c_props, deemphasis, 2);
223 } else {
224 expert_mode[1] = priv->tda8290_easy_mode + 0x80;
225 tuner_i2c_xfer_send(&priv->i2c_props, expert_mode, 2);
226 tuner_i2c_xfer_send(&priv->i2c_props, gainset_off, 2);
227 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_spd, 2);
228 if (priv->tda8290_easy_mode & 0x60)
229 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_9, 2);
230 else
231 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_6, 2);
232 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_nom, 2);
233 }
234
235
236 tda8290_i2c_bridge(fe, 1);
237
238 if (fe->ops.tuner_ops.set_analog_params)
239 fe->ops.tuner_ops.set_analog_params(fe, params);
240
241 for (i = 0; i < 3; i++) {
242 tuner_i2c_xfer_send_recv(&priv->i2c_props,
243 &addr_pll_stat, 1, &pll_stat, 1);
244 if (pll_stat & 0x80) {
245 tuner_i2c_xfer_send_recv(&priv->i2c_props,
246 &addr_adc_sat, 1,
247 &adc_sat, 1);
248 tuner_i2c_xfer_send_recv(&priv->i2c_props,
249 &addr_agc_stat, 1,
250 &agc_stat, 1);
251 tuner_dbg("tda8290 is locked, AGC: %d\n", agc_stat);
252 break;
253 } else {
254 tuner_dbg("tda8290 not locked, no signal?\n");
255 msleep(100);
256 }
257 }
258 /* adjust headroom resp. gain */
259 if ((agc_stat > 115) || (!(pll_stat & 0x80) && (adc_sat < 20))) {
260 tuner_dbg("adjust gain, step 1. Agc: %d, ADC stat: %d, lock: %d\n",
261 agc_stat, adc_sat, pll_stat & 0x80);
262 tuner_i2c_xfer_send(&priv->i2c_props, gainset_2, 2);
263 msleep(100);
264 tuner_i2c_xfer_send_recv(&priv->i2c_props,
265 &addr_agc_stat, 1, &agc_stat, 1);
266 tuner_i2c_xfer_send_recv(&priv->i2c_props,
267 &addr_pll_stat, 1, &pll_stat, 1);
268 if ((agc_stat > 115) || !(pll_stat & 0x80)) {
269 tuner_dbg("adjust gain, step 2. Agc: %d, lock: %d\n",
270 agc_stat, pll_stat & 0x80);
271 if (priv->cfg.agcf)
272 priv->cfg.agcf(fe);
273 msleep(100);
274 tuner_i2c_xfer_send_recv(&priv->i2c_props,
275 &addr_agc_stat, 1,
276 &agc_stat, 1);
277 tuner_i2c_xfer_send_recv(&priv->i2c_props,
278 &addr_pll_stat, 1,
279 &pll_stat, 1);
280 if((agc_stat > 115) || !(pll_stat & 0x80)) {
281 tuner_dbg("adjust gain, step 3. Agc: %d\n", agc_stat);
282 tuner_i2c_xfer_send(&priv->i2c_props, adc_head_12, 2);
283 tuner_i2c_xfer_send(&priv->i2c_props, pll_bw_low, 2);
284 msleep(100);
285 }
286 }
287 }
288
289 /* l/ l' deadlock? */
290 if(priv->tda8290_easy_mode & 0x60) {
291 tuner_i2c_xfer_send_recv(&priv->i2c_props,
292 &addr_adc_sat, 1,
293 &adc_sat, 1);
294 tuner_i2c_xfer_send_recv(&priv->i2c_props,
295 &addr_pll_stat, 1,
296 &pll_stat, 1);
297 if ((adc_sat > 20) || !(pll_stat & 0x80)) {
298 tuner_dbg("trying to resolve SECAM L deadlock\n");
299 tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_on, 2);
300 msleep(40);
301 tuner_i2c_xfer_send(&priv->i2c_props, agc_rst_off, 2);
302 }
303 }
304
305 tda8290_i2c_bridge(fe, 0);
306 tuner_i2c_xfer_send(&priv->i2c_props, if_agc_set, 2);
307}
308
309/*---------------------------------------------------------------------*/
310
311static void tda8295_power(struct dvb_frontend *fe, int enable)
312{
313 struct tda8290_priv *priv = fe->analog_demod_priv;
314 unsigned char buf[] = { 0x30, 0x00 }; /* clb_stdbt */
315
316 tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
317
318 if (enable)
319 buf[1] = 0x01;
320 else
321 buf[1] = 0x03;
322
323 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
324}
325
326static void tda8295_set_easy_mode(struct dvb_frontend *fe, int enable)
327{
328 struct tda8290_priv *priv = fe->analog_demod_priv;
329 unsigned char buf[] = { 0x01, 0x00 };
330
331 tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
332
333 if (enable)
334 buf[1] = 0x01; /* rising edge sets regs 0x02 - 0x23 */
335 else
336 buf[1] = 0x00; /* reset active bit */
337
338 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
339}
340
341static void tda8295_set_video_std(struct dvb_frontend *fe)
342{
343 struct tda8290_priv *priv = fe->analog_demod_priv;
344 unsigned char buf[] = { 0x00, priv->tda8290_easy_mode };
345
346 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
347
348 tda8295_set_easy_mode(fe, 1);
349 msleep(20);
350 tda8295_set_easy_mode(fe, 0);
351}
352
353/*---------------------------------------------------------------------*/
354
355static void tda8295_agc1_out(struct dvb_frontend *fe, int enable)
356{
357 struct tda8290_priv *priv = fe->analog_demod_priv;
358 unsigned char buf[] = { 0x02, 0x00 }; /* DIV_FUNC */
359
360 tuner_i2c_xfer_send_recv(&priv->i2c_props, &buf[0], 1, &buf[1], 1);
361
362 if (enable)
363 buf[1] &= ~0x40;
364 else
365 buf[1] |= 0x40;
366
367 tuner_i2c_xfer_send(&priv->i2c_props, buf, 2);
368}
369
370static void tda8295_agc2_out(struct dvb_frontend *fe, int enable)
371{
372 struct tda8290_priv *priv = fe->analog_demod_priv;
373 unsigned char set_gpio_cf[] = { 0x44, 0x00 };
374 unsigned char set_gpio_val[] = { 0x46, 0x00 };
375
376 tuner_i2c_xfer_send_recv(&priv->i2c_props,
377 &set_gpio_cf[0], 1, &set_gpio_cf[1], 1);
378 tuner_i2c_xfer_send_recv(&priv->i2c_props,
379 &set_gpio_val[0], 1, &set_gpio_val[1], 1);
380
381 set_gpio_cf[1] &= 0xf0; /* clear GPIO_0 bits 3-0 */
382
383 if (enable) {
384 set_gpio_cf[1] |= 0x01; /* config GPIO_0 as Open Drain Out */
385 set_gpio_val[1] &= 0xfe; /* set GPIO_0 pin low */
386 }
387 tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_cf, 2);
388 tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_val, 2);
389}
390
391static int tda8295_has_signal(struct dvb_frontend *fe)
392{
393 struct tda8290_priv *priv = fe->analog_demod_priv;
394
395 unsigned char hvpll_stat = 0x26;
396 unsigned char ret;
397
398 tuner_i2c_xfer_send_recv(&priv->i2c_props, &hvpll_stat, 1, &ret, 1);
399 return (ret & 0x01) ? 65535 : 0;
400}
401
402/*---------------------------------------------------------------------*/
403
404static void tda8295_set_params(struct dvb_frontend *fe,
405 struct analog_parameters *params)
406{
407 struct tda8290_priv *priv = fe->analog_demod_priv;
408
409 unsigned char blanking_mode[] = { 0x1d, 0x00 };
410
411 set_audio(fe, params);
412
413 tuner_dbg("%s: freq = %d\n", __func__, params->frequency);
414
415 tda8295_power(fe, 1);
416 tda8295_agc1_out(fe, 1);
417
418 tuner_i2c_xfer_send_recv(&priv->i2c_props,
419 &blanking_mode[0], 1, &blanking_mode[1], 1);
420
421 tda8295_set_video_std(fe);
422
423 blanking_mode[1] = 0x03;
424 tuner_i2c_xfer_send(&priv->i2c_props, blanking_mode, 2);
425 msleep(20);
426
427 tda8295_i2c_bridge(fe, 1);
428
429 if (fe->ops.tuner_ops.set_analog_params)
430 fe->ops.tuner_ops.set_analog_params(fe, params);
431
432 if (priv->cfg.agcf)
433 priv->cfg.agcf(fe);
434
435 if (tda8295_has_signal(fe))
436 tuner_dbg("tda8295 is locked\n");
437 else
438 tuner_dbg("tda8295 not locked, no signal?\n");
439
440 tda8295_i2c_bridge(fe, 0);
441}
442
443/*---------------------------------------------------------------------*/
444
445static int tda8290_has_signal(struct dvb_frontend *fe)
446{
447 struct tda8290_priv *priv = fe->analog_demod_priv;
448
449 unsigned char i2c_get_afc[1] = { 0x1B };
450 unsigned char afc = 0;
451
452 tuner_i2c_xfer_send_recv(&priv->i2c_props,
453 i2c_get_afc, ARRAY_SIZE(i2c_get_afc), &afc, 1);
454 return (afc & 0x80)? 65535:0;
455}
456
457/*---------------------------------------------------------------------*/
458
459static void tda8290_standby(struct dvb_frontend *fe)
460{
461 struct tda8290_priv *priv = fe->analog_demod_priv;
462
463 unsigned char cb1[] = { 0x30, 0xD0 };
464 unsigned char tda8290_standby[] = { 0x00, 0x02 };
465 unsigned char tda8290_agc_tri[] = { 0x02, 0x20 };
466 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0, .buf=cb1, .len = 2};
467
468 tda8290_i2c_bridge(fe, 1);
469 if (priv->ver & TDA8275A)
470 cb1[1] = 0x90;
471 i2c_transfer(priv->i2c_props.adap, &msg, 1);
472 tda8290_i2c_bridge(fe, 0);
473 tuner_i2c_xfer_send(&priv->i2c_props, tda8290_agc_tri, 2);
474 tuner_i2c_xfer_send(&priv->i2c_props, tda8290_standby, 2);
475}
476
477static void tda8295_standby(struct dvb_frontend *fe)
478{
479 tda8295_agc1_out(fe, 0); /* Put AGC in tri-state */
480
481 tda8295_power(fe, 0);
482}
483
484static void tda8290_init_if(struct dvb_frontend *fe)
485{
486 struct tda8290_priv *priv = fe->analog_demod_priv;
487
488 unsigned char set_VS[] = { 0x30, 0x6F };
489 unsigned char set_GP00_CF[] = { 0x20, 0x01 };
490 unsigned char set_GP01_CF[] = { 0x20, 0x0B };
491
492 if ((priv->cfg.config == 1) || (priv->cfg.config == 2))
493 tuner_i2c_xfer_send(&priv->i2c_props, set_GP00_CF, 2);
494 else
495 tuner_i2c_xfer_send(&priv->i2c_props, set_GP01_CF, 2);
496 tuner_i2c_xfer_send(&priv->i2c_props, set_VS, 2);
497}
498
499static void tda8295_init_if(struct dvb_frontend *fe)
500{
501 struct tda8290_priv *priv = fe->analog_demod_priv;
502
503 static unsigned char set_adc_ctl[] = { 0x33, 0x14 };
504 static unsigned char set_adc_ctl2[] = { 0x34, 0x00 };
505 static unsigned char set_pll_reg6[] = { 0x3e, 0x63 };
506 static unsigned char set_pll_reg0[] = { 0x38, 0x23 };
507 static unsigned char set_pll_reg7[] = { 0x3f, 0x01 };
508 static unsigned char set_pll_reg10[] = { 0x42, 0x61 };
509 static unsigned char set_gpio_reg0[] = { 0x44, 0x0b };
510
511 tda8295_power(fe, 1);
512
513 tda8295_set_easy_mode(fe, 0);
514 tda8295_set_video_std(fe);
515
516 tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl, 2);
517 tuner_i2c_xfer_send(&priv->i2c_props, set_adc_ctl2, 2);
518 tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg6, 2);
519 tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg0, 2);
520 tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg7, 2);
521 tuner_i2c_xfer_send(&priv->i2c_props, set_pll_reg10, 2);
522 tuner_i2c_xfer_send(&priv->i2c_props, set_gpio_reg0, 2);
523
524 tda8295_agc1_out(fe, 0);
525 tda8295_agc2_out(fe, 0);
526}
527
528static void tda8290_init_tuner(struct dvb_frontend *fe)
529{
530 struct tda8290_priv *priv = fe->analog_demod_priv;
531 unsigned char tda8275_init[] = { 0x00, 0x00, 0x00, 0x40, 0xdC, 0x04, 0xAf,
532 0x3F, 0x2A, 0x04, 0xFF, 0x00, 0x00, 0x40 };
533 unsigned char tda8275a_init[] = { 0x00, 0x00, 0x00, 0x00, 0xdC, 0x05, 0x8b,
534 0x0c, 0x04, 0x20, 0xFF, 0x00, 0x00, 0x4b };
535 struct i2c_msg msg = {.addr = priv->tda827x_addr, .flags=0,
536 .buf=tda8275_init, .len = 14};
537 if (priv->ver & TDA8275A)
538 msg.buf = tda8275a_init;
539
540 tda8290_i2c_bridge(fe, 1);
541 i2c_transfer(priv->i2c_props.adap, &msg, 1);
542 tda8290_i2c_bridge(fe, 0);
543}
544
545/*---------------------------------------------------------------------*/
546
547static void tda829x_release(struct dvb_frontend *fe)
548{
549 struct tda8290_priv *priv = fe->analog_demod_priv;
550
551 /* only try to release the tuner if we've
552 * attached it from within this module */
553 if (priv->ver & (TDA18271 | TDA8275 | TDA8275A))
554 if (fe->ops.tuner_ops.release)
555 fe->ops.tuner_ops.release(fe);
556
557 kfree(fe->analog_demod_priv);
558 fe->analog_demod_priv = NULL;
559}
560
561static struct tda18271_config tda829x_tda18271_config = {
562 .gate = TDA18271_GATE_ANALOG,
563};
564
565static int tda829x_find_tuner(struct dvb_frontend *fe)
566{
567 struct tda8290_priv *priv = fe->analog_demod_priv;
568 struct analog_demod_ops *analog_ops = &fe->ops.analog_ops;
569 int i, ret, tuners_found;
570 u32 tuner_addrs;
571 u8 data;
572 struct i2c_msg msg = { .flags = I2C_M_RD, .buf = &data, .len = 1 };
573
574 if (!analog_ops->i2c_gate_ctrl) {
575 printk(KERN_ERR "tda8290: no gate control were provided!\n");
576
577 return -EINVAL;
578 }
579
580 analog_ops->i2c_gate_ctrl(fe, 1);
581
582 /* probe for tuner chip */
583 tuners_found = 0;
584 tuner_addrs = 0;
585 for (i = 0x60; i <= 0x63; i++) {
586 msg.addr = i;
587 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
588 if (ret == 1) {
589 tuners_found++;
590 tuner_addrs = (tuner_addrs << 8) + i;
591 }
592 }
593 /* if there is more than one tuner, we expect the right one is
594 behind the bridge and we choose the highest address that doesn't
595 give a response now
596 */
597
598 analog_ops->i2c_gate_ctrl(fe, 0);
599
600 if (tuners_found > 1)
601 for (i = 0; i < tuners_found; i++) {
602 msg.addr = tuner_addrs & 0xff;
603 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
604 if (ret == 1)
605 tuner_addrs = tuner_addrs >> 8;
606 else
607 break;
608 }
609
610 if (tuner_addrs == 0) {
611 tuner_addrs = 0x60;
612 tuner_info("could not clearly identify tuner address, "
613 "defaulting to %x\n", tuner_addrs);
614 } else {
615 tuner_addrs = tuner_addrs & 0xff;
616 tuner_info("setting tuner address to %x\n", tuner_addrs);
617 }
618 priv->tda827x_addr = tuner_addrs;
619 msg.addr = tuner_addrs;
620
621 analog_ops->i2c_gate_ctrl(fe, 1);
622 ret = i2c_transfer(priv->i2c_props.adap, &msg, 1);
623
624 if (ret != 1) {
625 tuner_warn("tuner access failed!\n");
626 analog_ops->i2c_gate_ctrl(fe, 0);
627 return -EREMOTEIO;
628 }
629
630 if ((data == 0x83) || (data == 0x84)) {
631 priv->ver |= TDA18271;
632 tda829x_tda18271_config.config = priv->cfg.config;
633 dvb_attach(tda18271_attach, fe, priv->tda827x_addr,
634 priv->i2c_props.adap, &tda829x_tda18271_config);
635 } else {
636 if ((data & 0x3c) == 0)
637 priv->ver |= TDA8275;
638 else
639 priv->ver |= TDA8275A;
640
641 dvb_attach(tda827x_attach, fe, priv->tda827x_addr,
642 priv->i2c_props.adap, &priv->cfg);
643 priv->cfg.switch_addr = priv->i2c_props.addr;
644 }
645 if (fe->ops.tuner_ops.init)
646 fe->ops.tuner_ops.init(fe);
647
648 if (fe->ops.tuner_ops.sleep)
649 fe->ops.tuner_ops.sleep(fe);
650
651 analog_ops->i2c_gate_ctrl(fe, 0);
652
653 return 0;
654}
655
656static int tda8290_probe(struct tuner_i2c_props *i2c_props)
657{
658#define TDA8290_ID 0x89
659 u8 reg = 0x1f, id;
660 struct i2c_msg msg_read[] = {
661 { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = &reg },
662 { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id },
663 };
664
665 /* detect tda8290 */
666 if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
667 printk(KERN_WARNING "%s: couldn't read register 0x%02x\n",
668 __func__, reg);
669 return -ENODEV;
670 }
671
672 if (id == TDA8290_ID) {
673 if (debug)
674 printk(KERN_DEBUG "%s: tda8290 detected @ %d-%04x\n",
675 __func__, i2c_adapter_id(i2c_props->adap),
676 i2c_props->addr);
677 return 0;
678 }
679 return -ENODEV;
680}
681
682static int tda8295_probe(struct tuner_i2c_props *i2c_props)
683{
684#define TDA8295_ID 0x8a
685#define TDA8295C2_ID 0x8b
686 u8 reg = 0x2f, id;
687 struct i2c_msg msg_read[] = {
688 { .addr = i2c_props->addr, .flags = 0, .len = 1, .buf = &reg },
689 { .addr = i2c_props->addr, .flags = I2C_M_RD, .len = 1, .buf = &id },
690 };
691
692 /* detect tda8295 */
693 if (i2c_transfer(i2c_props->adap, msg_read, 2) != 2) {
694 printk(KERN_WARNING "%s: couldn't read register 0x%02x\n",
695 __func__, reg);
696 return -ENODEV;
697 }
698
699 if ((id & 0xfe) == TDA8295_ID) {
700 if (debug)
701 printk(KERN_DEBUG "%s: %s detected @ %d-%04x\n",
702 __func__, (id == TDA8295_ID) ?
703 "tda8295c1" : "tda8295c2",
704 i2c_adapter_id(i2c_props->adap),
705 i2c_props->addr);
706 return 0;
707 }
708
709 return -ENODEV;
710}
711
712static struct analog_demod_ops tda8290_ops = {
713 .set_params = tda8290_set_params,
714 .has_signal = tda8290_has_signal,
715 .standby = tda8290_standby,
716 .release = tda829x_release,
717 .i2c_gate_ctrl = tda8290_i2c_bridge,
718};
719
720static struct analog_demod_ops tda8295_ops = {
721 .set_params = tda8295_set_params,
722 .has_signal = tda8295_has_signal,
723 .standby = tda8295_standby,
724 .release = tda829x_release,
725 .i2c_gate_ctrl = tda8295_i2c_bridge,
726};
727
728struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
729 struct i2c_adapter *i2c_adap, u8 i2c_addr,
730 struct tda829x_config *cfg)
731{
732 struct tda8290_priv *priv = NULL;
733 char *name;
734
735 priv = kzalloc(sizeof(struct tda8290_priv), GFP_KERNEL);
736 if (priv == NULL)
737 return NULL;
738 fe->analog_demod_priv = priv;
739
740 priv->i2c_props.addr = i2c_addr;
741 priv->i2c_props.adap = i2c_adap;
742 priv->i2c_props.name = "tda829x";
743 if (cfg)
744 priv->cfg.config = cfg->lna_cfg;
745
746 if (tda8290_probe(&priv->i2c_props) == 0) {
747 priv->ver = TDA8290;
748 memcpy(&fe->ops.analog_ops, &tda8290_ops,
749 sizeof(struct analog_demod_ops));
750 }
751
752 if (tda8295_probe(&priv->i2c_props) == 0) {
753 priv->ver = TDA8295;
754 memcpy(&fe->ops.analog_ops, &tda8295_ops,
755 sizeof(struct analog_demod_ops));
756 }
757
758 if (!(cfg) || (TDA829X_PROBE_TUNER == cfg->probe_tuner)) {
759 tda8295_power(fe, 1);
760 if (tda829x_find_tuner(fe) < 0)
761 goto fail;
762 }
763
764 switch (priv->ver) {
765 case TDA8290:
766 name = "tda8290";
767 break;
768 case TDA8295:
769 name = "tda8295";
770 break;
771 case TDA8290 | TDA8275:
772 name = "tda8290+75";
773 break;
774 case TDA8295 | TDA8275:
775 name = "tda8295+75";
776 break;
777 case TDA8290 | TDA8275A:
778 name = "tda8290+75a";
779 break;
780 case TDA8295 | TDA8275A:
781 name = "tda8295+75a";
782 break;
783 case TDA8290 | TDA18271:
784 name = "tda8290+18271";
785 break;
786 case TDA8295 | TDA18271:
787 name = "tda8295+18271";
788 break;
789 default:
790 goto fail;
791 }
792 tuner_info("type set to %s\n", name);
793
794 fe->ops.analog_ops.info.name = name;
795
796 if (priv->ver & TDA8290) {
797 if (priv->ver & (TDA8275 | TDA8275A))
798 tda8290_init_tuner(fe);
799 tda8290_init_if(fe);
800 } else if (priv->ver & TDA8295)
801 tda8295_init_if(fe);
802
803 return fe;
804
805fail:
806 memset(&fe->ops.analog_ops, 0, sizeof(struct analog_demod_ops));
807
808 tda829x_release(fe);
809 return NULL;
810}
811EXPORT_SYMBOL_GPL(tda829x_attach);
812
813int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
814{
815 struct tuner_i2c_props i2c_props = {
816 .adap = i2c_adap,
817 .addr = i2c_addr,
818 };
819
820 unsigned char soft_reset[] = { 0x00, 0x00 };
821 unsigned char easy_mode_b[] = { 0x01, 0x02 };
822 unsigned char easy_mode_g[] = { 0x01, 0x04 };
823 unsigned char restore_9886[] = { 0x00, 0xd6, 0x30 };
824 unsigned char addr_dto_lsb = 0x07;
825 unsigned char data;
826#define PROBE_BUFFER_SIZE 8
827 unsigned char buf[PROBE_BUFFER_SIZE];
828 int i;
829
830 /* rule out tda9887, which would return the same byte repeatedly */
831 tuner_i2c_xfer_send_recv(&i2c_props,
832 soft_reset, 1, buf, PROBE_BUFFER_SIZE);
833 for (i = 1; i < PROBE_BUFFER_SIZE; i++) {
834 if (buf[i] != buf[0])
835 break;
836 }
837
838 /* all bytes are equal, not a tda829x - probably a tda9887 */
839 if (i == PROBE_BUFFER_SIZE)
840 return -ENODEV;
841
842 if ((tda8290_probe(&i2c_props) == 0) ||
843 (tda8295_probe(&i2c_props) == 0))
844 return 0;
845
846 /* fall back to old probing method */
847 tuner_i2c_xfer_send(&i2c_props, easy_mode_b, 2);
848 tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
849 tuner_i2c_xfer_send_recv(&i2c_props, &addr_dto_lsb, 1, &data, 1);
850 if (data == 0) {
851 tuner_i2c_xfer_send(&i2c_props, easy_mode_g, 2);
852 tuner_i2c_xfer_send(&i2c_props, soft_reset, 2);
853 tuner_i2c_xfer_send_recv(&i2c_props,
854 &addr_dto_lsb, 1, &data, 1);
855 if (data == 0x7b) {
856 return 0;
857 }
858 }
859 tuner_i2c_xfer_send(&i2c_props, restore_9886, 3);
860 return -ENODEV;
861}
862EXPORT_SYMBOL_GPL(tda829x_probe);
863
864MODULE_DESCRIPTION("Philips/NXP TDA8290/TDA8295 analog IF demodulator driver");
865MODULE_AUTHOR("Gerd Knorr, Hartmut Hackmann, Michael Krufky");
866MODULE_LICENSE("GPL");
867
868/*
869 * Overrides for Emacs so that we follow Linus's tabbing style.
870 * ---------------------------------------------------------------------------
871 * Local variables:
872 * c-basic-offset: 8
873 * End:
874 */
diff --git a/drivers/media/tuners/tda8290.h b/drivers/media/tuners/tda8290.h
new file mode 100644
index 000000000000..7e288b26fcc3
--- /dev/null
+++ b/drivers/media/tuners/tda8290.h
@@ -0,0 +1,56 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TDA8290_H__
18#define __TDA8290_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23struct tda829x_config {
24 unsigned int lna_cfg;
25
26 unsigned int probe_tuner:1;
27#define TDA829X_PROBE_TUNER 0
28#define TDA829X_DONT_PROBE 1
29};
30
31#if defined(CONFIG_MEDIA_TUNER_TDA8290) || (defined(CONFIG_MEDIA_TUNER_TDA8290_MODULE) && defined(MODULE))
32extern int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr);
33
34extern struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
35 struct i2c_adapter *i2c_adap,
36 u8 i2c_addr,
37 struct tda829x_config *cfg);
38#else
39static inline int tda829x_probe(struct i2c_adapter *i2c_adap, u8 i2c_addr)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return -EINVAL;
43}
44
45static inline struct dvb_frontend *tda829x_attach(struct dvb_frontend *fe,
46 struct i2c_adapter *i2c_adap,
47 u8 i2c_addr,
48 struct tda829x_config *cfg)
49{
50 printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
51 __func__);
52 return NULL;
53}
54#endif
55
56#endif /* __TDA8290_H__ */
diff --git a/drivers/media/tuners/tda9887.c b/drivers/media/tuners/tda9887.c
new file mode 100644
index 000000000000..cdb645d57438
--- /dev/null
+++ b/drivers/media/tuners/tda9887.c
@@ -0,0 +1,717 @@
1#include <linux/module.h>
2#include <linux/kernel.h>
3#include <linux/i2c.h>
4#include <linux/types.h>
5#include <linux/init.h>
6#include <linux/errno.h>
7#include <linux/delay.h>
8#include <linux/videodev2.h>
9#include <media/v4l2-common.h>
10#include <media/tuner.h>
11#include "tuner-i2c.h"
12#include "tda9887.h"
13
14
15/* Chips:
16 TDA9885 (PAL, NTSC)
17 TDA9886 (PAL, SECAM, NTSC)
18 TDA9887 (PAL, SECAM, NTSC, FM Radio)
19
20 Used as part of several tuners
21*/
22
23static int debug;
24module_param(debug, int, 0644);
25MODULE_PARM_DESC(debug, "enable verbose debug messages");
26
27static DEFINE_MUTEX(tda9887_list_mutex);
28static LIST_HEAD(hybrid_tuner_instance_list);
29
30struct tda9887_priv {
31 struct tuner_i2c_props i2c_props;
32 struct list_head hybrid_tuner_instance_list;
33
34 unsigned char data[4];
35 unsigned int config;
36 unsigned int mode;
37 unsigned int audmode;
38 v4l2_std_id std;
39
40 bool standby;
41};
42
43/* ---------------------------------------------------------------------- */
44
45#define UNSET (-1U)
46
47struct tvnorm {
48 v4l2_std_id std;
49 char *name;
50 unsigned char b;
51 unsigned char c;
52 unsigned char e;
53};
54
55/* ---------------------------------------------------------------------- */
56
57//
58// TDA defines
59//
60
61//// first reg (b)
62#define cVideoTrapBypassOFF 0x00 // bit b0
63#define cVideoTrapBypassON 0x01 // bit b0
64
65#define cAutoMuteFmInactive 0x00 // bit b1
66#define cAutoMuteFmActive 0x02 // bit b1
67
68#define cIntercarrier 0x00 // bit b2
69#define cQSS 0x04 // bit b2
70
71#define cPositiveAmTV 0x00 // bit b3:4
72#define cFmRadio 0x08 // bit b3:4
73#define cNegativeFmTV 0x10 // bit b3:4
74
75
76#define cForcedMuteAudioON 0x20 // bit b5
77#define cForcedMuteAudioOFF 0x00 // bit b5
78
79#define cOutputPort1Active 0x00 // bit b6
80#define cOutputPort1Inactive 0x40 // bit b6
81
82#define cOutputPort2Active 0x00 // bit b7
83#define cOutputPort2Inactive 0x80 // bit b7
84
85
86//// second reg (c)
87#define cDeemphasisOFF 0x00 // bit c5
88#define cDeemphasisON 0x20 // bit c5
89
90#define cDeemphasis75 0x00 // bit c6
91#define cDeemphasis50 0x40 // bit c6
92
93#define cAudioGain0 0x00 // bit c7
94#define cAudioGain6 0x80 // bit c7
95
96#define cTopMask 0x1f // bit c0:4
97#define cTopDefault 0x10 // bit c0:4
98
99//// third reg (e)
100#define cAudioIF_4_5 0x00 // bit e0:1
101#define cAudioIF_5_5 0x01 // bit e0:1
102#define cAudioIF_6_0 0x02 // bit e0:1
103#define cAudioIF_6_5 0x03 // bit e0:1
104
105
106#define cVideoIFMask 0x1c // bit e2:4
107/* Video IF selection in TV Mode (bit B3=0) */
108#define cVideoIF_58_75 0x00 // bit e2:4
109#define cVideoIF_45_75 0x04 // bit e2:4
110#define cVideoIF_38_90 0x08 // bit e2:4
111#define cVideoIF_38_00 0x0C // bit e2:4
112#define cVideoIF_33_90 0x10 // bit e2:4
113#define cVideoIF_33_40 0x14 // bit e2:4
114#define cRadioIF_45_75 0x18 // bit e2:4
115#define cRadioIF_38_90 0x1C // bit e2:4
116
117/* IF1 selection in Radio Mode (bit B3=1) */
118#define cRadioIF_33_30 0x00 // bit e2,4 (also 0x10,0x14)
119#define cRadioIF_41_30 0x04 // bit e2,4
120
121/* Output of AFC pin in radio mode when bit E7=1 */
122#define cRadioAGC_SIF 0x00 // bit e3
123#define cRadioAGC_FM 0x08 // bit e3
124
125#define cTunerGainNormal 0x00 // bit e5
126#define cTunerGainLow 0x20 // bit e5
127
128#define cGating_18 0x00 // bit e6
129#define cGating_36 0x40 // bit e6
130
131#define cAgcOutON 0x80 // bit e7
132#define cAgcOutOFF 0x00 // bit e7
133
134/* ---------------------------------------------------------------------- */
135
136static struct tvnorm tvnorms[] = {
137 {
138 .std = V4L2_STD_PAL_BG | V4L2_STD_PAL_H | V4L2_STD_PAL_N,
139 .name = "PAL-BGHN",
140 .b = ( cNegativeFmTV |
141 cQSS ),
142 .c = ( cDeemphasisON |
143 cDeemphasis50 |
144 cTopDefault),
145 .e = ( cGating_36 |
146 cAudioIF_5_5 |
147 cVideoIF_38_90 ),
148 },{
149 .std = V4L2_STD_PAL_I,
150 .name = "PAL-I",
151 .b = ( cNegativeFmTV |
152 cQSS ),
153 .c = ( cDeemphasisON |
154 cDeemphasis50 |
155 cTopDefault),
156 .e = ( cGating_36 |
157 cAudioIF_6_0 |
158 cVideoIF_38_90 ),
159 },{
160 .std = V4L2_STD_PAL_DK,
161 .name = "PAL-DK",
162 .b = ( cNegativeFmTV |
163 cQSS ),
164 .c = ( cDeemphasisON |
165 cDeemphasis50 |
166 cTopDefault),
167 .e = ( cGating_36 |
168 cAudioIF_6_5 |
169 cVideoIF_38_90 ),
170 },{
171 .std = V4L2_STD_PAL_M | V4L2_STD_PAL_Nc,
172 .name = "PAL-M/Nc",
173 .b = ( cNegativeFmTV |
174 cQSS ),
175 .c = ( cDeemphasisON |
176 cDeemphasis75 |
177 cTopDefault),
178 .e = ( cGating_36 |
179 cAudioIF_4_5 |
180 cVideoIF_45_75 ),
181 },{
182 .std = V4L2_STD_SECAM_B | V4L2_STD_SECAM_G | V4L2_STD_SECAM_H,
183 .name = "SECAM-BGH",
184 .b = ( cNegativeFmTV |
185 cQSS ),
186 .c = ( cTopDefault),
187 .e = ( cAudioIF_5_5 |
188 cVideoIF_38_90 ),
189 },{
190 .std = V4L2_STD_SECAM_L,
191 .name = "SECAM-L",
192 .b = ( cPositiveAmTV |
193 cQSS ),
194 .c = ( cTopDefault),
195 .e = ( cGating_36 |
196 cAudioIF_6_5 |
197 cVideoIF_38_90 ),
198 },{
199 .std = V4L2_STD_SECAM_LC,
200 .name = "SECAM-L'",
201 .b = ( cOutputPort2Inactive |
202 cPositiveAmTV |
203 cQSS ),
204 .c = ( cTopDefault),
205 .e = ( cGating_36 |
206 cAudioIF_6_5 |
207 cVideoIF_33_90 ),
208 },{
209 .std = V4L2_STD_SECAM_DK,
210 .name = "SECAM-DK",
211 .b = ( cNegativeFmTV |
212 cQSS ),
213 .c = ( cDeemphasisON |
214 cDeemphasis50 |
215 cTopDefault),
216 .e = ( cGating_36 |
217 cAudioIF_6_5 |
218 cVideoIF_38_90 ),
219 },{
220 .std = V4L2_STD_NTSC_M | V4L2_STD_NTSC_M_KR,
221 .name = "NTSC-M",
222 .b = ( cNegativeFmTV |
223 cQSS ),
224 .c = ( cDeemphasisON |
225 cDeemphasis75 |
226 cTopDefault),
227 .e = ( cGating_36 |
228 cAudioIF_4_5 |
229 cVideoIF_45_75 ),
230 },{
231 .std = V4L2_STD_NTSC_M_JP,
232 .name = "NTSC-M-JP",
233 .b = ( cNegativeFmTV |
234 cQSS ),
235 .c = ( cDeemphasisON |
236 cDeemphasis50 |
237 cTopDefault),
238 .e = ( cGating_36 |
239 cAudioIF_4_5 |
240 cVideoIF_58_75 ),
241 }
242};
243
244static struct tvnorm radio_stereo = {
245 .name = "Radio Stereo",
246 .b = ( cFmRadio |
247 cQSS ),
248 .c = ( cDeemphasisOFF |
249 cAudioGain6 |
250 cTopDefault),
251 .e = ( cTunerGainLow |
252 cAudioIF_5_5 |
253 cRadioIF_38_90 ),
254};
255
256static struct tvnorm radio_mono = {
257 .name = "Radio Mono",
258 .b = ( cFmRadio |
259 cQSS ),
260 .c = ( cDeemphasisON |
261 cDeemphasis75 |
262 cTopDefault),
263 .e = ( cTunerGainLow |
264 cAudioIF_5_5 |
265 cRadioIF_38_90 ),
266};
267
268/* ---------------------------------------------------------------------- */
269
270static void dump_read_message(struct dvb_frontend *fe, unsigned char *buf)
271{
272 struct tda9887_priv *priv = fe->analog_demod_priv;
273
274 static char *afc[16] = {
275 "- 12.5 kHz",
276 "- 37.5 kHz",
277 "- 62.5 kHz",
278 "- 87.5 kHz",
279 "-112.5 kHz",
280 "-137.5 kHz",
281 "-162.5 kHz",
282 "-187.5 kHz [min]",
283 "+187.5 kHz [max]",
284 "+162.5 kHz",
285 "+137.5 kHz",
286 "+112.5 kHz",
287 "+ 87.5 kHz",
288 "+ 62.5 kHz",
289 "+ 37.5 kHz",
290 "+ 12.5 kHz",
291 };
292 tuner_info("read: 0x%2x\n", buf[0]);
293 tuner_info(" after power on : %s\n", (buf[0] & 0x01) ? "yes" : "no");
294 tuner_info(" afc : %s\n", afc[(buf[0] >> 1) & 0x0f]);
295 tuner_info(" fmif level : %s\n", (buf[0] & 0x20) ? "high" : "low");
296 tuner_info(" afc window : %s\n", (buf[0] & 0x40) ? "in" : "out");
297 tuner_info(" vfi level : %s\n", (buf[0] & 0x80) ? "high" : "low");
298}
299
300static void dump_write_message(struct dvb_frontend *fe, unsigned char *buf)
301{
302 struct tda9887_priv *priv = fe->analog_demod_priv;
303
304 static char *sound[4] = {
305 "AM/TV",
306 "FM/radio",
307 "FM/TV",
308 "FM/radio"
309 };
310 static char *adjust[32] = {
311 "-16", "-15", "-14", "-13", "-12", "-11", "-10", "-9",
312 "-8", "-7", "-6", "-5", "-4", "-3", "-2", "-1",
313 "0", "+1", "+2", "+3", "+4", "+5", "+6", "+7",
314 "+8", "+9", "+10", "+11", "+12", "+13", "+14", "+15"
315 };
316 static char *deemph[4] = {
317 "no", "no", "75", "50"
318 };
319 static char *carrier[4] = {
320 "4.5 MHz",
321 "5.5 MHz",
322 "6.0 MHz",
323 "6.5 MHz / AM"
324 };
325 static char *vif[8] = {
326 "58.75 MHz",
327 "45.75 MHz",
328 "38.9 MHz",
329 "38.0 MHz",
330 "33.9 MHz",
331 "33.4 MHz",
332 "45.75 MHz + pin13",
333 "38.9 MHz + pin13",
334 };
335 static char *rif[4] = {
336 "44 MHz",
337 "52 MHz",
338 "52 MHz",
339 "44 MHz",
340 };
341
342 tuner_info("write: byte B 0x%02x\n", buf[1]);
343 tuner_info(" B0 video mode : %s\n",
344 (buf[1] & 0x01) ? "video trap" : "sound trap");
345 tuner_info(" B1 auto mute fm : %s\n",
346 (buf[1] & 0x02) ? "yes" : "no");
347 tuner_info(" B2 carrier mode : %s\n",
348 (buf[1] & 0x04) ? "QSS" : "Intercarrier");
349 tuner_info(" B3-4 tv sound/radio : %s\n",
350 sound[(buf[1] & 0x18) >> 3]);
351 tuner_info(" B5 force mute audio: %s\n",
352 (buf[1] & 0x20) ? "yes" : "no");
353 tuner_info(" B6 output port 1 : %s\n",
354 (buf[1] & 0x40) ? "high (inactive)" : "low (active)");
355 tuner_info(" B7 output port 2 : %s\n",
356 (buf[1] & 0x80) ? "high (inactive)" : "low (active)");
357
358 tuner_info("write: byte C 0x%02x\n", buf[2]);
359 tuner_info(" C0-4 top adjustment : %s dB\n",
360 adjust[buf[2] & 0x1f]);
361 tuner_info(" C5-6 de-emphasis : %s\n",
362 deemph[(buf[2] & 0x60) >> 5]);
363 tuner_info(" C7 audio gain : %s\n",
364 (buf[2] & 0x80) ? "-6" : "0");
365
366 tuner_info("write: byte E 0x%02x\n", buf[3]);
367 tuner_info(" E0-1 sound carrier : %s\n",
368 carrier[(buf[3] & 0x03)]);
369 tuner_info(" E6 l pll gating : %s\n",
370 (buf[3] & 0x40) ? "36" : "13");
371
372 if (buf[1] & 0x08) {
373 /* radio */
374 tuner_info(" E2-4 video if : %s\n",
375 rif[(buf[3] & 0x0c) >> 2]);
376 tuner_info(" E7 vif agc output : %s\n",
377 (buf[3] & 0x80)
378 ? ((buf[3] & 0x10) ? "fm-agc radio" :
379 "sif-agc radio")
380 : "fm radio carrier afc");
381 } else {
382 /* video */
383 tuner_info(" E2-4 video if : %s\n",
384 vif[(buf[3] & 0x1c) >> 2]);
385 tuner_info(" E5 tuner gain : %s\n",
386 (buf[3] & 0x80)
387 ? ((buf[3] & 0x20) ? "external" : "normal")
388 : ((buf[3] & 0x20) ? "minimum" : "normal"));
389 tuner_info(" E7 vif agc output : %s\n",
390 (buf[3] & 0x80) ? ((buf[3] & 0x20)
391 ? "pin3 port, pin22 vif agc out"
392 : "pin22 port, pin3 vif acg ext in")
393 : "pin3+pin22 port");
394 }
395 tuner_info("--\n");
396}
397
398/* ---------------------------------------------------------------------- */
399
400static int tda9887_set_tvnorm(struct dvb_frontend *fe)
401{
402 struct tda9887_priv *priv = fe->analog_demod_priv;
403 struct tvnorm *norm = NULL;
404 char *buf = priv->data;
405 int i;
406
407 if (priv->mode == V4L2_TUNER_RADIO) {
408 if (priv->audmode == V4L2_TUNER_MODE_MONO)
409 norm = &radio_mono;
410 else
411 norm = &radio_stereo;
412 } else {
413 for (i = 0; i < ARRAY_SIZE(tvnorms); i++) {
414 if (tvnorms[i].std & priv->std) {
415 norm = tvnorms+i;
416 break;
417 }
418 }
419 }
420 if (NULL == norm) {
421 tuner_dbg("Unsupported tvnorm entry - audio muted\n");
422 return -1;
423 }
424
425 tuner_dbg("configure for: %s\n", norm->name);
426 buf[1] = norm->b;
427 buf[2] = norm->c;
428 buf[3] = norm->e;
429 return 0;
430}
431
432static unsigned int port1 = UNSET;
433static unsigned int port2 = UNSET;
434static unsigned int qss = UNSET;
435static unsigned int adjust = UNSET;
436
437module_param(port1, int, 0644);
438module_param(port2, int, 0644);
439module_param(qss, int, 0644);
440module_param(adjust, int, 0644);
441
442static int tda9887_set_insmod(struct dvb_frontend *fe)
443{
444 struct tda9887_priv *priv = fe->analog_demod_priv;
445 char *buf = priv->data;
446
447 if (UNSET != port1) {
448 if (port1)
449 buf[1] |= cOutputPort1Inactive;
450 else
451 buf[1] &= ~cOutputPort1Inactive;
452 }
453 if (UNSET != port2) {
454 if (port2)
455 buf[1] |= cOutputPort2Inactive;
456 else
457 buf[1] &= ~cOutputPort2Inactive;
458 }
459
460 if (UNSET != qss) {
461 if (qss)
462 buf[1] |= cQSS;
463 else
464 buf[1] &= ~cQSS;
465 }
466
467 if (adjust < 0x20) {
468 buf[2] &= ~cTopMask;
469 buf[2] |= adjust;
470 }
471 return 0;
472}
473
474static int tda9887_do_config(struct dvb_frontend *fe)
475{
476 struct tda9887_priv *priv = fe->analog_demod_priv;
477 char *buf = priv->data;
478
479 if (priv->config & TDA9887_PORT1_ACTIVE)
480 buf[1] &= ~cOutputPort1Inactive;
481 if (priv->config & TDA9887_PORT1_INACTIVE)
482 buf[1] |= cOutputPort1Inactive;
483 if (priv->config & TDA9887_PORT2_ACTIVE)
484 buf[1] &= ~cOutputPort2Inactive;
485 if (priv->config & TDA9887_PORT2_INACTIVE)
486 buf[1] |= cOutputPort2Inactive;
487
488 if (priv->config & TDA9887_QSS)
489 buf[1] |= cQSS;
490 if (priv->config & TDA9887_INTERCARRIER)
491 buf[1] &= ~cQSS;
492
493 if (priv->config & TDA9887_AUTOMUTE)
494 buf[1] |= cAutoMuteFmActive;
495 if (priv->config & TDA9887_DEEMPHASIS_MASK) {
496 buf[2] &= ~0x60;
497 switch (priv->config & TDA9887_DEEMPHASIS_MASK) {
498 case TDA9887_DEEMPHASIS_NONE:
499 buf[2] |= cDeemphasisOFF;
500 break;
501 case TDA9887_DEEMPHASIS_50:
502 buf[2] |= cDeemphasisON | cDeemphasis50;
503 break;
504 case TDA9887_DEEMPHASIS_75:
505 buf[2] |= cDeemphasisON | cDeemphasis75;
506 break;
507 }
508 }
509 if (priv->config & TDA9887_TOP_SET) {
510 buf[2] &= ~cTopMask;
511 buf[2] |= (priv->config >> 8) & cTopMask;
512 }
513 if ((priv->config & TDA9887_INTERCARRIER_NTSC) &&
514 (priv->std & V4L2_STD_NTSC))
515 buf[1] &= ~cQSS;
516 if (priv->config & TDA9887_GATING_18)
517 buf[3] &= ~cGating_36;
518
519 if (priv->mode == V4L2_TUNER_RADIO) {
520 if (priv->config & TDA9887_RIF_41_3) {
521 buf[3] &= ~cVideoIFMask;
522 buf[3] |= cRadioIF_41_30;
523 }
524 if (priv->config & TDA9887_GAIN_NORMAL)
525 buf[3] &= ~cTunerGainLow;
526 }
527
528 return 0;
529}
530
531/* ---------------------------------------------------------------------- */
532
533static int tda9887_status(struct dvb_frontend *fe)
534{
535 struct tda9887_priv *priv = fe->analog_demod_priv;
536 unsigned char buf[1];
537 int rc;
538
539 memset(buf,0,sizeof(buf));
540 if (1 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props,buf,1)))
541 tuner_info("i2c i/o error: rc == %d (should be 1)\n", rc);
542 dump_read_message(fe, buf);
543 return 0;
544}
545
546static void tda9887_configure(struct dvb_frontend *fe)
547{
548 struct tda9887_priv *priv = fe->analog_demod_priv;
549 int rc;
550
551 memset(priv->data,0,sizeof(priv->data));
552 tda9887_set_tvnorm(fe);
553
554 /* A note on the port settings:
555 These settings tend to depend on the specifics of the board.
556 By default they are set to inactive (bit value 1) by this driver,
557 overwriting any changes made by the tvnorm. This means that it
558 is the responsibility of the module using the tda9887 to set
559 these values in case of changes in the tvnorm.
560 In many cases port 2 should be made active (0) when selecting
561 SECAM-L, and port 2 should remain inactive (1) for SECAM-L'.
562
563 For the other standards the tda9887 application note says that
564 the ports should be set to active (0), but, again, that may
565 differ depending on the precise hardware configuration.
566 */
567 priv->data[1] |= cOutputPort1Inactive;
568 priv->data[1] |= cOutputPort2Inactive;
569
570 tda9887_do_config(fe);
571 tda9887_set_insmod(fe);
572
573 if (priv->standby)
574 priv->data[1] |= cForcedMuteAudioON;
575
576 tuner_dbg("writing: b=0x%02x c=0x%02x e=0x%02x\n",
577 priv->data[1], priv->data[2], priv->data[3]);
578 if (debug > 1)
579 dump_write_message(fe, priv->data);
580
581 if (4 != (rc = tuner_i2c_xfer_send(&priv->i2c_props,priv->data,4)))
582 tuner_info("i2c i/o error: rc == %d (should be 4)\n", rc);
583
584 if (debug > 2) {
585 msleep_interruptible(1000);
586 tda9887_status(fe);
587 }
588}
589
590/* ---------------------------------------------------------------------- */
591
592static void tda9887_tuner_status(struct dvb_frontend *fe)
593{
594 struct tda9887_priv *priv = fe->analog_demod_priv;
595 tuner_info("Data bytes: b=0x%02x c=0x%02x e=0x%02x\n",
596 priv->data[1], priv->data[2], priv->data[3]);
597}
598
599static int tda9887_get_afc(struct dvb_frontend *fe)
600{
601 struct tda9887_priv *priv = fe->analog_demod_priv;
602 static int AFC_BITS_2_kHz[] = {
603 -12500, -37500, -62500, -97500,
604 -112500, -137500, -162500, -187500,
605 187500, 162500, 137500, 112500,
606 97500 , 62500, 37500 , 12500
607 };
608 int afc=0;
609 __u8 reg = 0;
610
611 if (1 == tuner_i2c_xfer_recv(&priv->i2c_props,&reg,1))
612 afc = AFC_BITS_2_kHz[(reg>>1)&0x0f];
613
614 return afc;
615}
616
617static void tda9887_standby(struct dvb_frontend *fe)
618{
619 struct tda9887_priv *priv = fe->analog_demod_priv;
620
621 priv->standby = true;
622
623 tda9887_configure(fe);
624}
625
626static void tda9887_set_params(struct dvb_frontend *fe,
627 struct analog_parameters *params)
628{
629 struct tda9887_priv *priv = fe->analog_demod_priv;
630
631 priv->standby = false;
632 priv->mode = params->mode;
633 priv->audmode = params->audmode;
634 priv->std = params->std;
635 tda9887_configure(fe);
636}
637
638static int tda9887_set_config(struct dvb_frontend *fe, void *priv_cfg)
639{
640 struct tda9887_priv *priv = fe->analog_demod_priv;
641
642 priv->config = *(unsigned int *)priv_cfg;
643 tda9887_configure(fe);
644
645 return 0;
646}
647
648static void tda9887_release(struct dvb_frontend *fe)
649{
650 struct tda9887_priv *priv = fe->analog_demod_priv;
651
652 mutex_lock(&tda9887_list_mutex);
653
654 if (priv)
655 hybrid_tuner_release_state(priv);
656
657 mutex_unlock(&tda9887_list_mutex);
658
659 fe->analog_demod_priv = NULL;
660}
661
662static struct analog_demod_ops tda9887_ops = {
663 .info = {
664 .name = "tda9887",
665 },
666 .set_params = tda9887_set_params,
667 .standby = tda9887_standby,
668 .tuner_status = tda9887_tuner_status,
669 .get_afc = tda9887_get_afc,
670 .release = tda9887_release,
671 .set_config = tda9887_set_config,
672};
673
674struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
675 struct i2c_adapter *i2c_adap,
676 u8 i2c_addr)
677{
678 struct tda9887_priv *priv = NULL;
679 int instance;
680
681 mutex_lock(&tda9887_list_mutex);
682
683 instance = hybrid_tuner_request_state(struct tda9887_priv, priv,
684 hybrid_tuner_instance_list,
685 i2c_adap, i2c_addr, "tda9887");
686 switch (instance) {
687 case 0:
688 mutex_unlock(&tda9887_list_mutex);
689 return NULL;
690 case 1:
691 fe->analog_demod_priv = priv;
692 priv->standby = true;
693 tuner_info("tda988[5/6/7] found\n");
694 break;
695 default:
696 fe->analog_demod_priv = priv;
697 break;
698 }
699
700 mutex_unlock(&tda9887_list_mutex);
701
702 memcpy(&fe->ops.analog_ops, &tda9887_ops,
703 sizeof(struct analog_demod_ops));
704
705 return fe;
706}
707EXPORT_SYMBOL_GPL(tda9887_attach);
708
709MODULE_LICENSE("GPL");
710
711/*
712 * Overrides for Emacs so that we follow Linus's tabbing style.
713 * ---------------------------------------------------------------------------
714 * Local variables:
715 * c-basic-offset: 8
716 * End:
717 */
diff --git a/drivers/media/tuners/tda9887.h b/drivers/media/tuners/tda9887.h
new file mode 100644
index 000000000000..acc419e8c4fc
--- /dev/null
+++ b/drivers/media/tuners/tda9887.h
@@ -0,0 +1,38 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TDA9887_H__
18#define __TDA9887_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23/* ------------------------------------------------------------------------ */
24#if defined(CONFIG_MEDIA_TUNER_TDA9887) || (defined(CONFIG_MEDIA_TUNER_TDA9887_MODULE) && defined(MODULE))
25extern struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
26 struct i2c_adapter *i2c_adap,
27 u8 i2c_addr);
28#else
29static inline struct dvb_frontend *tda9887_attach(struct dvb_frontend *fe,
30 struct i2c_adapter *i2c_adap,
31 u8 i2c_addr)
32{
33 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
34 return NULL;
35}
36#endif
37
38#endif /* __TDA9887_H__ */
diff --git a/drivers/media/tuners/tea5761.c b/drivers/media/tuners/tea5761.c
new file mode 100644
index 000000000000..bf78cb9fc52c
--- /dev/null
+++ b/drivers/media/tuners/tea5761.c
@@ -0,0 +1,348 @@
1/*
2 * For Philips TEA5761 FM Chip
3 * I2C address is allways 0x20 (0x10 at 7-bit mode).
4 *
5 * Copyright (c) 2005-2007 Mauro Carvalho Chehab (mchehab@infradead.org)
6 * This code is placed under the terms of the GNUv2 General Public License
7 *
8 */
9
10#include <linux/i2c.h>
11#include <linux/slab.h>
12#include <linux/delay.h>
13#include <linux/videodev2.h>
14#include <media/tuner.h>
15#include "tuner-i2c.h"
16#include "tea5761.h"
17
18static int debug;
19module_param(debug, int, 0644);
20MODULE_PARM_DESC(debug, "enable verbose debug messages");
21
22struct tea5761_priv {
23 struct tuner_i2c_props i2c_props;
24
25 u32 frequency;
26 bool standby;
27};
28
29/*****************************************************************************/
30
31/***************************
32 * TEA5761HN I2C registers *
33 ***************************/
34
35/* INTREG - Read: bytes 0 and 1 / Write: byte 0 */
36
37 /* first byte for reading */
38#define TEA5761_INTREG_IFFLAG 0x10
39#define TEA5761_INTREG_LEVFLAG 0x8
40#define TEA5761_INTREG_FRRFLAG 0x2
41#define TEA5761_INTREG_BLFLAG 0x1
42
43 /* second byte for reading / byte for writing */
44#define TEA5761_INTREG_IFMSK 0x10
45#define TEA5761_INTREG_LEVMSK 0x8
46#define TEA5761_INTREG_FRMSK 0x2
47#define TEA5761_INTREG_BLMSK 0x1
48
49/* FRQSET - Read: bytes 2 and 3 / Write: byte 1 and 2 */
50
51 /* First byte */
52#define TEA5761_FRQSET_SEARCH_UP 0x80 /* 1=Station search from botton to up */
53#define TEA5761_FRQSET_SEARCH_MODE 0x40 /* 1=Search mode */
54
55 /* Bits 0-5 for divider MSB */
56
57 /* Second byte */
58 /* Bits 0-7 for divider LSB */
59
60/* TNCTRL - Read: bytes 4 and 5 / Write: Bytes 3 and 4 */
61
62 /* first byte */
63
64#define TEA5761_TNCTRL_PUPD_0 0x40 /* Power UP/Power Down MSB */
65#define TEA5761_TNCTRL_BLIM 0X20 /* 1= Japan Frequencies, 0= European frequencies */
66#define TEA5761_TNCTRL_SWPM 0x10 /* 1= software port is FRRFLAG */
67#define TEA5761_TNCTRL_IFCTC 0x08 /* 1= IF count time 15.02 ms, 0= IF count time 2.02 ms */
68#define TEA5761_TNCTRL_AFM 0x04
69#define TEA5761_TNCTRL_SMUTE 0x02 /* 1= Soft mute */
70#define TEA5761_TNCTRL_SNC 0x01
71
72 /* second byte */
73
74#define TEA5761_TNCTRL_MU 0x80 /* 1=Hard mute */
75#define TEA5761_TNCTRL_SSL_1 0x40
76#define TEA5761_TNCTRL_SSL_0 0x20
77#define TEA5761_TNCTRL_HLSI 0x10
78#define TEA5761_TNCTRL_MST 0x08 /* 1 = mono */
79#define TEA5761_TNCTRL_SWP 0x04
80#define TEA5761_TNCTRL_DTC 0x02 /* 1 = deemphasis 50 us, 0 = deemphasis 75 us */
81#define TEA5761_TNCTRL_AHLSI 0x01
82
83/* FRQCHECK - Read: bytes 6 and 7 */
84 /* First byte */
85
86 /* Bits 0-5 for divider MSB */
87
88 /* Second byte */
89 /* Bits 0-7 for divider LSB */
90
91/* TUNCHECK - Read: bytes 8 and 9 */
92
93 /* First byte */
94#define TEA5761_TUNCHECK_IF_MASK 0x7e /* IF count */
95#define TEA5761_TUNCHECK_TUNTO 0x01
96
97 /* Second byte */
98#define TEA5761_TUNCHECK_LEV_MASK 0xf0 /* Level Count */
99#define TEA5761_TUNCHECK_LD 0x08
100#define TEA5761_TUNCHECK_STEREO 0x04
101
102/* TESTREG - Read: bytes 10 and 11 / Write: bytes 5 and 6 */
103
104 /* All zero = no test mode */
105
106/* MANID - Read: bytes 12 and 13 */
107
108 /* First byte - should be 0x10 */
109#define TEA5767_MANID_VERSION_MASK 0xf0 /* Version = 1 */
110#define TEA5767_MANID_ID_MSB_MASK 0x0f /* Manufacurer ID - should be 0 */
111
112 /* Second byte - Should be 0x2b */
113
114#define TEA5767_MANID_ID_LSB_MASK 0xfe /* Manufacturer ID - should be 0x15 */
115#define TEA5767_MANID_IDAV 0x01 /* 1 = Chip has ID, 0 = Chip has no ID */
116
117/* Chip ID - Read: bytes 14 and 15 */
118
119 /* First byte - should be 0x57 */
120
121 /* Second byte - should be 0x61 */
122
123/*****************************************************************************/
124
125#define FREQ_OFFSET 0 /* for TEA5767, it is 700 to give the right freq */
126static void tea5761_status_dump(unsigned char *buffer)
127{
128 unsigned int div, frq;
129
130 div = ((buffer[2] & 0x3f) << 8) | buffer[3];
131
132 frq = 1000 * (div * 32768 / 1000 + FREQ_OFFSET + 225) / 4; /* Freq in KHz */
133
134 printk(KERN_INFO "tea5761: Frequency %d.%03d KHz (divider = 0x%04x)\n",
135 frq / 1000, frq % 1000, div);
136}
137
138/* Freq should be specifyed at 62.5 Hz */
139static int __set_radio_freq(struct dvb_frontend *fe,
140 unsigned int freq,
141 bool mono)
142{
143 struct tea5761_priv *priv = fe->tuner_priv;
144 unsigned int frq = freq;
145 unsigned char buffer[7] = {0, 0, 0, 0, 0, 0, 0 };
146 unsigned div;
147 int rc;
148
149 tuner_dbg("radio freq counter %d\n", frq);
150
151 if (priv->standby) {
152 tuner_dbg("TEA5761 set to standby mode\n");
153 buffer[5] |= TEA5761_TNCTRL_MU;
154 } else {
155 buffer[4] |= TEA5761_TNCTRL_PUPD_0;
156 }
157
158
159 if (mono) {
160 tuner_dbg("TEA5761 set to mono\n");
161 buffer[5] |= TEA5761_TNCTRL_MST;
162 } else {
163 tuner_dbg("TEA5761 set to stereo\n");
164 }
165
166 div = (1000 * (frq * 4 / 16 + 700 + 225) ) >> 15;
167 buffer[1] = (div >> 8) & 0x3f;
168 buffer[2] = div & 0xff;
169
170 if (debug)
171 tea5761_status_dump(buffer);
172
173 if (7 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 7)))
174 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
175
176 priv->frequency = frq * 125 / 2;
177
178 return 0;
179}
180
181static int set_radio_freq(struct dvb_frontend *fe,
182 struct analog_parameters *params)
183{
184 struct tea5761_priv *priv = fe->analog_demod_priv;
185
186 priv->standby = false;
187
188 return __set_radio_freq(fe, params->frequency,
189 params->audmode == V4L2_TUNER_MODE_MONO);
190}
191
192static int set_radio_sleep(struct dvb_frontend *fe)
193{
194 struct tea5761_priv *priv = fe->analog_demod_priv;
195
196 priv->standby = true;
197
198 return __set_radio_freq(fe, priv->frequency, false);
199}
200
201static int tea5761_read_status(struct dvb_frontend *fe, char *buffer)
202{
203 struct tea5761_priv *priv = fe->tuner_priv;
204 int rc;
205
206 memset(buffer, 0, 16);
207 if (16 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 16))) {
208 tuner_warn("i2c i/o error: rc == %d (should be 16)\n", rc);
209 return -EREMOTEIO;
210 }
211
212 return 0;
213}
214
215static inline int tea5761_signal(struct dvb_frontend *fe, const char *buffer)
216{
217 struct tea5761_priv *priv = fe->tuner_priv;
218
219 int signal = ((buffer[9] & TEA5761_TUNCHECK_LEV_MASK) << (13 - 4));
220
221 tuner_dbg("Signal strength: %d\n", signal);
222
223 return signal;
224}
225
226static inline int tea5761_stereo(struct dvb_frontend *fe, const char *buffer)
227{
228 struct tea5761_priv *priv = fe->tuner_priv;
229
230 int stereo = buffer[9] & TEA5761_TUNCHECK_STEREO;
231
232 tuner_dbg("Radio ST GET = %02x\n", stereo);
233
234 return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
235}
236
237static int tea5761_get_status(struct dvb_frontend *fe, u32 *status)
238{
239 unsigned char buffer[16];
240
241 *status = 0;
242
243 if (0 == tea5761_read_status(fe, buffer)) {
244 if (tea5761_signal(fe, buffer))
245 *status = TUNER_STATUS_LOCKED;
246 if (tea5761_stereo(fe, buffer))
247 *status |= TUNER_STATUS_STEREO;
248 }
249
250 return 0;
251}
252
253static int tea5761_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
254{
255 unsigned char buffer[16];
256
257 *strength = 0;
258
259 if (0 == tea5761_read_status(fe, buffer))
260 *strength = tea5761_signal(fe, buffer);
261
262 return 0;
263}
264
265int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
266{
267 unsigned char buffer[16];
268 int rc;
269 struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
270
271 if (16 != (rc = tuner_i2c_xfer_recv(&i2c, buffer, 16))) {
272 printk(KERN_WARNING "it is not a TEA5761. Received %i chars.\n", rc);
273 return -EINVAL;
274 }
275
276 if ((buffer[13] != 0x2b) || (buffer[14] != 0x57) || (buffer[15] != 0x061)) {
277 printk(KERN_WARNING "Manufacturer ID= 0x%02x, Chip ID = %02x%02x."
278 " It is not a TEA5761\n",
279 buffer[13], buffer[14], buffer[15]);
280 return -EINVAL;
281 }
282 printk(KERN_WARNING "tea5761: TEA%02x%02x detected. "
283 "Manufacturer ID= 0x%02x\n",
284 buffer[14], buffer[15], buffer[13]);
285
286 return 0;
287}
288
289static int tea5761_release(struct dvb_frontend *fe)
290{
291 kfree(fe->tuner_priv);
292 fe->tuner_priv = NULL;
293
294 return 0;
295}
296
297static int tea5761_get_frequency(struct dvb_frontend *fe, u32 *frequency)
298{
299 struct tea5761_priv *priv = fe->tuner_priv;
300 *frequency = priv->frequency;
301 return 0;
302}
303
304static struct dvb_tuner_ops tea5761_tuner_ops = {
305 .info = {
306 .name = "tea5761", // Philips TEA5761HN FM Radio
307 },
308 .set_analog_params = set_radio_freq,
309 .sleep = set_radio_sleep,
310 .release = tea5761_release,
311 .get_frequency = tea5761_get_frequency,
312 .get_status = tea5761_get_status,
313 .get_rf_strength = tea5761_get_rf_strength,
314};
315
316struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
317 struct i2c_adapter* i2c_adap,
318 u8 i2c_addr)
319{
320 struct tea5761_priv *priv = NULL;
321
322 if (tea5761_autodetection(i2c_adap, i2c_addr) != 0)
323 return NULL;
324
325 priv = kzalloc(sizeof(struct tea5761_priv), GFP_KERNEL);
326 if (priv == NULL)
327 return NULL;
328 fe->tuner_priv = priv;
329
330 priv->i2c_props.addr = i2c_addr;
331 priv->i2c_props.adap = i2c_adap;
332 priv->i2c_props.name = "tea5761";
333
334 memcpy(&fe->ops.tuner_ops, &tea5761_tuner_ops,
335 sizeof(struct dvb_tuner_ops));
336
337 tuner_info("type set to %s\n", "Philips TEA5761HN FM Radio");
338
339 return fe;
340}
341
342
343EXPORT_SYMBOL_GPL(tea5761_attach);
344EXPORT_SYMBOL_GPL(tea5761_autodetection);
345
346MODULE_DESCRIPTION("Philips TEA5761 FM tuner driver");
347MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
348MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tea5761.h b/drivers/media/tuners/tea5761.h
new file mode 100644
index 000000000000..2e2ff82c95a4
--- /dev/null
+++ b/drivers/media/tuners/tea5761.h
@@ -0,0 +1,47 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TEA5761_H__
18#define __TEA5761_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23#if defined(CONFIG_MEDIA_TUNER_TEA5761) || (defined(CONFIG_MEDIA_TUNER_TEA5761_MODULE) && defined(MODULE))
24extern int tea5761_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
25
26extern struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
27 struct i2c_adapter* i2c_adap,
28 u8 i2c_addr);
29#else
30static inline int tea5761_autodetection(struct i2c_adapter* i2c_adap,
31 u8 i2c_addr)
32{
33 printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
34 __func__);
35 return -EINVAL;
36}
37
38static inline struct dvb_frontend *tea5761_attach(struct dvb_frontend *fe,
39 struct i2c_adapter* i2c_adap,
40 u8 i2c_addr)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
43 return NULL;
44}
45#endif
46
47#endif /* __TEA5761_H__ */
diff --git a/drivers/media/tuners/tea5767.c b/drivers/media/tuners/tea5767.c
new file mode 100644
index 000000000000..36e85d81acb2
--- /dev/null
+++ b/drivers/media/tuners/tea5767.c
@@ -0,0 +1,475 @@
1/*
2 * For Philips TEA5767 FM Chip used on some TV Cards like Prolink Pixelview
3 * I2C address is allways 0xC0.
4 *
5 *
6 * Copyright (c) 2005 Mauro Carvalho Chehab (mchehab@infradead.org)
7 * This code is placed under the terms of the GNU General Public License
8 *
9 * tea5767 autodetection thanks to Torsten Seeboth and Atsushi Nakagawa
10 * from their contributions on DScaler.
11 */
12
13#include <linux/i2c.h>
14#include <linux/slab.h>
15#include <linux/delay.h>
16#include <linux/videodev2.h>
17#include "tuner-i2c.h"
18#include "tea5767.h"
19
20static int debug;
21module_param(debug, int, 0644);
22MODULE_PARM_DESC(debug, "enable verbose debug messages");
23
24/*****************************************************************************/
25
26struct tea5767_priv {
27 struct tuner_i2c_props i2c_props;
28 u32 frequency;
29 struct tea5767_ctrl ctrl;
30};
31
32/*****************************************************************************/
33
34/******************************
35 * Write mode register values *
36 ******************************/
37
38/* First register */
39#define TEA5767_MUTE 0x80 /* Mutes output */
40#define TEA5767_SEARCH 0x40 /* Activates station search */
41/* Bits 0-5 for divider MSB */
42
43/* Second register */
44/* Bits 0-7 for divider LSB */
45
46/* Third register */
47
48/* Station search from botton to up */
49#define TEA5767_SEARCH_UP 0x80
50
51/* Searches with ADC output = 10 */
52#define TEA5767_SRCH_HIGH_LVL 0x60
53
54/* Searches with ADC output = 10 */
55#define TEA5767_SRCH_MID_LVL 0x40
56
57/* Searches with ADC output = 5 */
58#define TEA5767_SRCH_LOW_LVL 0x20
59
60/* if on, div=4*(Frf+Fif)/Fref otherwise, div=4*(Frf-Fif)/Freq) */
61#define TEA5767_HIGH_LO_INJECT 0x10
62
63/* Disable stereo */
64#define TEA5767_MONO 0x08
65
66/* Disable right channel and turns to mono */
67#define TEA5767_MUTE_RIGHT 0x04
68
69/* Disable left channel and turns to mono */
70#define TEA5767_MUTE_LEFT 0x02
71
72#define TEA5767_PORT1_HIGH 0x01
73
74/* Fourth register */
75#define TEA5767_PORT2_HIGH 0x80
76/* Chips stops working. Only I2C bus remains on */
77#define TEA5767_STDBY 0x40
78
79/* Japan freq (76-108 MHz. If disabled, 87.5-108 MHz */
80#define TEA5767_JAPAN_BAND 0x20
81
82/* Unselected means 32.768 KHz freq as reference. Otherwise Xtal at 13 MHz */
83#define TEA5767_XTAL_32768 0x10
84
85/* Cuts weak signals */
86#define TEA5767_SOFT_MUTE 0x08
87
88/* Activates high cut control */
89#define TEA5767_HIGH_CUT_CTRL 0x04
90
91/* Activates stereo noise control */
92#define TEA5767_ST_NOISE_CTL 0x02
93
94/* If activate PORT 1 indicates SEARCH or else it is used as PORT1 */
95#define TEA5767_SRCH_IND 0x01
96
97/* Fifth register */
98
99/* By activating, it will use Xtal at 13 MHz as reference for divider */
100#define TEA5767_PLLREF_ENABLE 0x80
101
102/* By activating, deemphasis=50, or else, deemphasis of 50us */
103#define TEA5767_DEEMPH_75 0X40
104
105/*****************************
106 * Read mode register values *
107 *****************************/
108
109/* First register */
110#define TEA5767_READY_FLAG_MASK 0x80
111#define TEA5767_BAND_LIMIT_MASK 0X40
112/* Bits 0-5 for divider MSB after search or preset */
113
114/* Second register */
115/* Bits 0-7 for divider LSB after search or preset */
116
117/* Third register */
118#define TEA5767_STEREO_MASK 0x80
119#define TEA5767_IF_CNTR_MASK 0x7f
120
121/* Fourth register */
122#define TEA5767_ADC_LEVEL_MASK 0xf0
123
124/* should be 0 */
125#define TEA5767_CHIP_ID_MASK 0x0f
126
127/* Fifth register */
128/* Reserved for future extensions */
129#define TEA5767_RESERVED_MASK 0xff
130
131/*****************************************************************************/
132
133static void tea5767_status_dump(struct tea5767_priv *priv,
134 unsigned char *buffer)
135{
136 unsigned int div, frq;
137
138 if (TEA5767_READY_FLAG_MASK & buffer[0])
139 tuner_info("Ready Flag ON\n");
140 else
141 tuner_info("Ready Flag OFF\n");
142
143 if (TEA5767_BAND_LIMIT_MASK & buffer[0])
144 tuner_info("Tuner at band limit\n");
145 else
146 tuner_info("Tuner not at band limit\n");
147
148 div = ((buffer[0] & 0x3f) << 8) | buffer[1];
149
150 switch (priv->ctrl.xtal_freq) {
151 case TEA5767_HIGH_LO_13MHz:
152 frq = (div * 50000 - 700000 - 225000) / 4; /* Freq in KHz */
153 break;
154 case TEA5767_LOW_LO_13MHz:
155 frq = (div * 50000 + 700000 + 225000) / 4; /* Freq in KHz */
156 break;
157 case TEA5767_LOW_LO_32768:
158 frq = (div * 32768 + 700000 + 225000) / 4; /* Freq in KHz */
159 break;
160 case TEA5767_HIGH_LO_32768:
161 default:
162 frq = (div * 32768 - 700000 - 225000) / 4; /* Freq in KHz */
163 break;
164 }
165 buffer[0] = (div >> 8) & 0x3f;
166 buffer[1] = div & 0xff;
167
168 tuner_info("Frequency %d.%03d KHz (divider = 0x%04x)\n",
169 frq / 1000, frq % 1000, div);
170
171 if (TEA5767_STEREO_MASK & buffer[2])
172 tuner_info("Stereo\n");
173 else
174 tuner_info("Mono\n");
175
176 tuner_info("IF Counter = %d\n", buffer[2] & TEA5767_IF_CNTR_MASK);
177
178 tuner_info("ADC Level = %d\n",
179 (buffer[3] & TEA5767_ADC_LEVEL_MASK) >> 4);
180
181 tuner_info("Chip ID = %d\n", (buffer[3] & TEA5767_CHIP_ID_MASK));
182
183 tuner_info("Reserved = 0x%02x\n",
184 (buffer[4] & TEA5767_RESERVED_MASK));
185}
186
187/* Freq should be specifyed at 62.5 Hz */
188static int set_radio_freq(struct dvb_frontend *fe,
189 struct analog_parameters *params)
190{
191 struct tea5767_priv *priv = fe->tuner_priv;
192 unsigned int frq = params->frequency;
193 unsigned char buffer[5];
194 unsigned div;
195 int rc;
196
197 tuner_dbg("radio freq = %d.%03d MHz\n", frq/16000,(frq/16)%1000);
198
199 buffer[2] = 0;
200
201 if (priv->ctrl.port1)
202 buffer[2] |= TEA5767_PORT1_HIGH;
203
204 if (params->audmode == V4L2_TUNER_MODE_MONO) {
205 tuner_dbg("TEA5767 set to mono\n");
206 buffer[2] |= TEA5767_MONO;
207 } else {
208 tuner_dbg("TEA5767 set to stereo\n");
209 }
210
211
212 buffer[3] = 0;
213
214 if (priv->ctrl.port2)
215 buffer[3] |= TEA5767_PORT2_HIGH;
216
217 if (priv->ctrl.high_cut)
218 buffer[3] |= TEA5767_HIGH_CUT_CTRL;
219
220 if (priv->ctrl.st_noise)
221 buffer[3] |= TEA5767_ST_NOISE_CTL;
222
223 if (priv->ctrl.soft_mute)
224 buffer[3] |= TEA5767_SOFT_MUTE;
225
226 if (priv->ctrl.japan_band)
227 buffer[3] |= TEA5767_JAPAN_BAND;
228
229 buffer[4] = 0;
230
231 if (priv->ctrl.deemph_75)
232 buffer[4] |= TEA5767_DEEMPH_75;
233
234 if (priv->ctrl.pllref)
235 buffer[4] |= TEA5767_PLLREF_ENABLE;
236
237
238 /* Rounds freq to next decimal value - for 62.5 KHz step */
239 /* frq = 20*(frq/16)+radio_frq[frq%16]; */
240
241 switch (priv->ctrl.xtal_freq) {
242 case TEA5767_HIGH_LO_13MHz:
243 tuner_dbg("radio HIGH LO inject xtal @ 13 MHz\n");
244 buffer[2] |= TEA5767_HIGH_LO_INJECT;
245 div = (frq * (4000 / 16) + 700000 + 225000 + 25000) / 50000;
246 break;
247 case TEA5767_LOW_LO_13MHz:
248 tuner_dbg("radio LOW LO inject xtal @ 13 MHz\n");
249
250 div = (frq * (4000 / 16) - 700000 - 225000 + 25000) / 50000;
251 break;
252 case TEA5767_LOW_LO_32768:
253 tuner_dbg("radio LOW LO inject xtal @ 32,768 MHz\n");
254 buffer[3] |= TEA5767_XTAL_32768;
255 /* const 700=4000*175 Khz - to adjust freq to right value */
256 div = ((frq * (4000 / 16) - 700000 - 225000) + 16384) >> 15;
257 break;
258 case TEA5767_HIGH_LO_32768:
259 default:
260 tuner_dbg("radio HIGH LO inject xtal @ 32,768 MHz\n");
261
262 buffer[2] |= TEA5767_HIGH_LO_INJECT;
263 buffer[3] |= TEA5767_XTAL_32768;
264 div = ((frq * (4000 / 16) + 700000 + 225000) + 16384) >> 15;
265 break;
266 }
267 buffer[0] = (div >> 8) & 0x3f;
268 buffer[1] = div & 0xff;
269
270 if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
271 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
272
273 if (debug) {
274 if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5)))
275 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
276 else
277 tea5767_status_dump(priv, buffer);
278 }
279
280 priv->frequency = frq * 125 / 2;
281
282 return 0;
283}
284
285static int tea5767_read_status(struct dvb_frontend *fe, char *buffer)
286{
287 struct tea5767_priv *priv = fe->tuner_priv;
288 int rc;
289
290 memset(buffer, 0, 5);
291 if (5 != (rc = tuner_i2c_xfer_recv(&priv->i2c_props, buffer, 5))) {
292 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
293 return -EREMOTEIO;
294 }
295
296 return 0;
297}
298
299static inline int tea5767_signal(struct dvb_frontend *fe, const char *buffer)
300{
301 struct tea5767_priv *priv = fe->tuner_priv;
302
303 int signal = ((buffer[3] & TEA5767_ADC_LEVEL_MASK) << 8);
304
305 tuner_dbg("Signal strength: %d\n", signal);
306
307 return signal;
308}
309
310static inline int tea5767_stereo(struct dvb_frontend *fe, const char *buffer)
311{
312 struct tea5767_priv *priv = fe->tuner_priv;
313
314 int stereo = buffer[2] & TEA5767_STEREO_MASK;
315
316 tuner_dbg("Radio ST GET = %02x\n", stereo);
317
318 return (stereo ? V4L2_TUNER_SUB_STEREO : 0);
319}
320
321static int tea5767_get_status(struct dvb_frontend *fe, u32 *status)
322{
323 unsigned char buffer[5];
324
325 *status = 0;
326
327 if (0 == tea5767_read_status(fe, buffer)) {
328 if (tea5767_signal(fe, buffer))
329 *status = TUNER_STATUS_LOCKED;
330 if (tea5767_stereo(fe, buffer))
331 *status |= TUNER_STATUS_STEREO;
332 }
333
334 return 0;
335}
336
337static int tea5767_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
338{
339 unsigned char buffer[5];
340
341 *strength = 0;
342
343 if (0 == tea5767_read_status(fe, buffer))
344 *strength = tea5767_signal(fe, buffer);
345
346 return 0;
347}
348
349static int tea5767_standby(struct dvb_frontend *fe)
350{
351 unsigned char buffer[5];
352 struct tea5767_priv *priv = fe->tuner_priv;
353 unsigned div, rc;
354
355 div = (87500 * 4 + 700 + 225 + 25) / 50; /* Set frequency to 87.5 MHz */
356 buffer[0] = (div >> 8) & 0x3f;
357 buffer[1] = div & 0xff;
358 buffer[2] = TEA5767_PORT1_HIGH;
359 buffer[3] = TEA5767_PORT2_HIGH | TEA5767_HIGH_CUT_CTRL |
360 TEA5767_ST_NOISE_CTL | TEA5767_JAPAN_BAND | TEA5767_STDBY;
361 buffer[4] = 0;
362
363 if (5 != (rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 5)))
364 tuner_warn("i2c i/o error: rc == %d (should be 5)\n", rc);
365
366 return 0;
367}
368
369int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr)
370{
371 struct tuner_i2c_props i2c = { .adap = i2c_adap, .addr = i2c_addr };
372 unsigned char buffer[7] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
373 int rc;
374
375 if ((rc = tuner_i2c_xfer_recv(&i2c, buffer, 7))< 5) {
376 printk(KERN_WARNING "It is not a TEA5767. Received %i bytes.\n", rc);
377 return -EINVAL;
378 }
379
380 /* If all bytes are the same then it's a TV tuner and not a tea5767 */
381 if (buffer[0] == buffer[1] && buffer[0] == buffer[2] &&
382 buffer[0] == buffer[3] && buffer[0] == buffer[4]) {
383 printk(KERN_WARNING "All bytes are equal. It is not a TEA5767\n");
384 return -EINVAL;
385 }
386
387 /* Status bytes:
388 * Byte 4: bit 3:1 : CI (Chip Identification) == 0
389 * bit 0 : internally set to 0
390 * Byte 5: bit 7:0 : == 0
391 */
392 if (((buffer[3] & 0x0f) != 0x00) || (buffer[4] != 0x00)) {
393 printk(KERN_WARNING "Chip ID is not zero. It is not a TEA5767\n");
394 return -EINVAL;
395 }
396
397
398 return 0;
399}
400
401static int tea5767_release(struct dvb_frontend *fe)
402{
403 kfree(fe->tuner_priv);
404 fe->tuner_priv = NULL;
405
406 return 0;
407}
408
409static int tea5767_get_frequency(struct dvb_frontend *fe, u32 *frequency)
410{
411 struct tea5767_priv *priv = fe->tuner_priv;
412 *frequency = priv->frequency;
413
414 return 0;
415}
416
417static int tea5767_set_config (struct dvb_frontend *fe, void *priv_cfg)
418{
419 struct tea5767_priv *priv = fe->tuner_priv;
420
421 memcpy(&priv->ctrl, priv_cfg, sizeof(priv->ctrl));
422
423 return 0;
424}
425
426static struct dvb_tuner_ops tea5767_tuner_ops = {
427 .info = {
428 .name = "tea5767", // Philips TEA5767HN FM Radio
429 },
430
431 .set_analog_params = set_radio_freq,
432 .set_config = tea5767_set_config,
433 .sleep = tea5767_standby,
434 .release = tea5767_release,
435 .get_frequency = tea5767_get_frequency,
436 .get_status = tea5767_get_status,
437 .get_rf_strength = tea5767_get_rf_strength,
438};
439
440struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
441 struct i2c_adapter* i2c_adap,
442 u8 i2c_addr)
443{
444 struct tea5767_priv *priv = NULL;
445
446 priv = kzalloc(sizeof(struct tea5767_priv), GFP_KERNEL);
447 if (priv == NULL)
448 return NULL;
449 fe->tuner_priv = priv;
450
451 priv->i2c_props.addr = i2c_addr;
452 priv->i2c_props.adap = i2c_adap;
453 priv->i2c_props.name = "tea5767";
454
455 priv->ctrl.xtal_freq = TEA5767_HIGH_LO_32768;
456 priv->ctrl.port1 = 1;
457 priv->ctrl.port2 = 1;
458 priv->ctrl.high_cut = 1;
459 priv->ctrl.st_noise = 1;
460 priv->ctrl.japan_band = 1;
461
462 memcpy(&fe->ops.tuner_ops, &tea5767_tuner_ops,
463 sizeof(struct dvb_tuner_ops));
464
465 tuner_info("type set to %s\n", "Philips TEA5767HN FM Radio");
466
467 return fe;
468}
469
470EXPORT_SYMBOL_GPL(tea5767_attach);
471EXPORT_SYMBOL_GPL(tea5767_autodetection);
472
473MODULE_DESCRIPTION("Philips TEA5767 FM tuner driver");
474MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
475MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tea5767.h b/drivers/media/tuners/tea5767.h
new file mode 100644
index 000000000000..d30ab1b483de
--- /dev/null
+++ b/drivers/media/tuners/tea5767.h
@@ -0,0 +1,66 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TEA5767_H__
18#define __TEA5767_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23enum tea5767_xtal {
24 TEA5767_LOW_LO_32768 = 0,
25 TEA5767_HIGH_LO_32768 = 1,
26 TEA5767_LOW_LO_13MHz = 2,
27 TEA5767_HIGH_LO_13MHz = 3,
28};
29
30struct tea5767_ctrl {
31 unsigned int port1:1;
32 unsigned int port2:1;
33 unsigned int high_cut:1;
34 unsigned int st_noise:1;
35 unsigned int soft_mute:1;
36 unsigned int japan_band:1;
37 unsigned int deemph_75:1;
38 unsigned int pllref:1;
39 enum tea5767_xtal xtal_freq;
40};
41
42#if defined(CONFIG_MEDIA_TUNER_TEA5767) || (defined(CONFIG_MEDIA_TUNER_TEA5767_MODULE) && defined(MODULE))
43extern int tea5767_autodetection(struct i2c_adapter* i2c_adap, u8 i2c_addr);
44
45extern struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
46 struct i2c_adapter* i2c_adap,
47 u8 i2c_addr);
48#else
49static inline int tea5767_autodetection(struct i2c_adapter* i2c_adap,
50 u8 i2c_addr)
51{
52 printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
53 __func__);
54 return -EINVAL;
55}
56
57static inline struct dvb_frontend *tea5767_attach(struct dvb_frontend *fe,
58 struct i2c_adapter* i2c_adap,
59 u8 i2c_addr)
60{
61 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
62 return NULL;
63}
64#endif
65
66#endif /* __TEA5767_H__ */
diff --git a/drivers/media/tuners/tua9001.c b/drivers/media/tuners/tua9001.c
new file mode 100644
index 000000000000..de2607084672
--- /dev/null
+++ b/drivers/media/tuners/tua9001.c
@@ -0,0 +1,215 @@
1/*
2 * Infineon TUA 9001 silicon tuner driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#include "tua9001.h"
22#include "tua9001_priv.h"
23
24/* write register */
25static int tua9001_wr_reg(struct tua9001_priv *priv, u8 reg, u16 val)
26{
27 int ret;
28 u8 buf[3] = { reg, (val >> 8) & 0xff, (val >> 0) & 0xff };
29 struct i2c_msg msg[1] = {
30 {
31 .addr = priv->cfg->i2c_addr,
32 .flags = 0,
33 .len = sizeof(buf),
34 .buf = buf,
35 }
36 };
37
38 ret = i2c_transfer(priv->i2c, msg, 1);
39 if (ret == 1) {
40 ret = 0;
41 } else {
42 printk(KERN_WARNING "%s: I2C wr failed=%d reg=%02x\n",
43 __func__, ret, reg);
44 ret = -EREMOTEIO;
45 }
46
47 return ret;
48}
49
50static int tua9001_release(struct dvb_frontend *fe)
51{
52 kfree(fe->tuner_priv);
53 fe->tuner_priv = NULL;
54
55 return 0;
56}
57
58static int tua9001_init(struct dvb_frontend *fe)
59{
60 struct tua9001_priv *priv = fe->tuner_priv;
61 int ret = 0;
62 u8 i;
63 struct reg_val data[] = {
64 { 0x1e, 0x6512 },
65 { 0x25, 0xb888 },
66 { 0x39, 0x5460 },
67 { 0x3b, 0x00c0 },
68 { 0x3a, 0xf000 },
69 { 0x08, 0x0000 },
70 { 0x32, 0x0030 },
71 { 0x41, 0x703a },
72 { 0x40, 0x1c78 },
73 { 0x2c, 0x1c00 },
74 { 0x36, 0xc013 },
75 { 0x37, 0x6f18 },
76 { 0x27, 0x0008 },
77 { 0x2a, 0x0001 },
78 { 0x34, 0x0a40 },
79 };
80
81 if (fe->ops.i2c_gate_ctrl)
82 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
83
84 for (i = 0; i < ARRAY_SIZE(data); i++) {
85 ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
86 if (ret)
87 break;
88 }
89
90 if (fe->ops.i2c_gate_ctrl)
91 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
92
93 if (ret < 0)
94 pr_debug("%s: failed=%d\n", __func__, ret);
95
96 return ret;
97}
98
99static int tua9001_set_params(struct dvb_frontend *fe)
100{
101 struct tua9001_priv *priv = fe->tuner_priv;
102 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
103 int ret, i;
104 u16 val;
105 u32 frequency;
106 struct reg_val data[2];
107
108 pr_debug("%s: delivery_system=%d frequency=%d bandwidth_hz=%d\n",
109 __func__, c->delivery_system, c->frequency,
110 c->bandwidth_hz);
111
112 switch (c->delivery_system) {
113 case SYS_DVBT:
114 switch (c->bandwidth_hz) {
115 case 8000000:
116 val = 0x0000;
117 break;
118 case 7000000:
119 val = 0x1000;
120 break;
121 case 6000000:
122 val = 0x2000;
123 break;
124 case 5000000:
125 val = 0x3000;
126 break;
127 default:
128 ret = -EINVAL;
129 goto err;
130 }
131 break;
132 default:
133 ret = -EINVAL;
134 goto err;
135 }
136
137 data[0].reg = 0x04;
138 data[0].val = val;
139
140 frequency = (c->frequency - 150000000);
141 frequency /= 100;
142 frequency *= 48;
143 frequency /= 10000;
144
145 data[1].reg = 0x1f;
146 data[1].val = frequency;
147
148 if (fe->ops.i2c_gate_ctrl)
149 fe->ops.i2c_gate_ctrl(fe, 1); /* open i2c-gate */
150
151 for (i = 0; i < ARRAY_SIZE(data); i++) {
152 ret = tua9001_wr_reg(priv, data[i].reg, data[i].val);
153 if (ret < 0)
154 break;
155 }
156
157 if (fe->ops.i2c_gate_ctrl)
158 fe->ops.i2c_gate_ctrl(fe, 0); /* close i2c-gate */
159
160err:
161 if (ret < 0)
162 pr_debug("%s: failed=%d\n", __func__, ret);
163
164 return ret;
165}
166
167static int tua9001_get_if_frequency(struct dvb_frontend *fe, u32 *frequency)
168{
169 *frequency = 0; /* Zero-IF */
170
171 return 0;
172}
173
174static const struct dvb_tuner_ops tua9001_tuner_ops = {
175 .info = {
176 .name = "Infineon TUA 9001",
177
178 .frequency_min = 170000000,
179 .frequency_max = 862000000,
180 .frequency_step = 0,
181 },
182
183 .release = tua9001_release,
184
185 .init = tua9001_init,
186 .set_params = tua9001_set_params,
187
188 .get_if_frequency = tua9001_get_if_frequency,
189};
190
191struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
192 struct i2c_adapter *i2c, struct tua9001_config *cfg)
193{
194 struct tua9001_priv *priv = NULL;
195
196 priv = kzalloc(sizeof(struct tua9001_priv), GFP_KERNEL);
197 if (priv == NULL)
198 return NULL;
199
200 priv->cfg = cfg;
201 priv->i2c = i2c;
202
203 printk(KERN_INFO "Infineon TUA 9001 successfully attached.");
204
205 memcpy(&fe->ops.tuner_ops, &tua9001_tuner_ops,
206 sizeof(struct dvb_tuner_ops));
207
208 fe->tuner_priv = priv;
209 return fe;
210}
211EXPORT_SYMBOL(tua9001_attach);
212
213MODULE_DESCRIPTION("Infineon TUA 9001 silicon tuner driver");
214MODULE_AUTHOR("Antti Palosaari <crope@iki.fi>");
215MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tua9001.h b/drivers/media/tuners/tua9001.h
new file mode 100644
index 000000000000..38d6ae76b1d6
--- /dev/null
+++ b/drivers/media/tuners/tua9001.h
@@ -0,0 +1,46 @@
1/*
2 * Infineon TUA 9001 silicon tuner driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef TUA9001_H
22#define TUA9001_H
23
24#include "dvb_frontend.h"
25
26struct tua9001_config {
27 /*
28 * I2C address
29 */
30 u8 i2c_addr;
31};
32
33#if defined(CONFIG_MEDIA_TUNER_TUA9001) || \
34 (defined(CONFIG_MEDIA_TUNER_TUA9001_MODULE) && defined(MODULE))
35extern struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
36 struct i2c_adapter *i2c, struct tua9001_config *cfg);
37#else
38static inline struct dvb_frontend *tua9001_attach(struct dvb_frontend *fe,
39 struct i2c_adapter *i2c, struct tua9001_config *cfg)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
42 return NULL;
43}
44#endif
45
46#endif
diff --git a/drivers/media/tuners/tua9001_priv.h b/drivers/media/tuners/tua9001_priv.h
new file mode 100644
index 000000000000..73cc1ce0575c
--- /dev/null
+++ b/drivers/media/tuners/tua9001_priv.h
@@ -0,0 +1,34 @@
1/*
2 * Infineon TUA 9001 silicon tuner driver
3 *
4 * Copyright (C) 2009 Antti Palosaari <crope@iki.fi>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License along
17 * with this program; if not, write to the Free Software Foundation, Inc.,
18 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
19 */
20
21#ifndef TUA9001_PRIV_H
22#define TUA9001_PRIV_H
23
24struct reg_val {
25 u8 reg;
26 u16 val;
27};
28
29struct tua9001_priv {
30 struct tua9001_config *cfg;
31 struct i2c_adapter *i2c;
32};
33
34#endif
diff --git a/drivers/media/tuners/tuner-i2c.h b/drivers/media/tuners/tuner-i2c.h
new file mode 100644
index 000000000000..18f005634c67
--- /dev/null
+++ b/drivers/media/tuners/tuner-i2c.h
@@ -0,0 +1,182 @@
1/*
2 tuner-i2c.h - i2c interface for different tuners
3
4 Copyright (C) 2007 Michael Krufky (mkrufky@linuxtv.org)
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19*/
20
21#ifndef __TUNER_I2C_H__
22#define __TUNER_I2C_H__
23
24#include <linux/i2c.h>
25#include <linux/slab.h>
26
27struct tuner_i2c_props {
28 u8 addr;
29 struct i2c_adapter *adap;
30
31 /* used for tuner instance management */
32 int count;
33 char *name;
34};
35
36static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len)
37{
38 struct i2c_msg msg = { .addr = props->addr, .flags = 0,
39 .buf = buf, .len = len };
40 int ret = i2c_transfer(props->adap, &msg, 1);
41
42 return (ret == 1) ? len : ret;
43}
44
45static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props, char *buf, int len)
46{
47 struct i2c_msg msg = { .addr = props->addr, .flags = I2C_M_RD,
48 .buf = buf, .len = len };
49 int ret = i2c_transfer(props->adap, &msg, 1);
50
51 return (ret == 1) ? len : ret;
52}
53
54static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props,
55 char *obuf, int olen,
56 char *ibuf, int ilen)
57{
58 struct i2c_msg msg[2] = { { .addr = props->addr, .flags = 0,
59 .buf = obuf, .len = olen },
60 { .addr = props->addr, .flags = I2C_M_RD,
61 .buf = ibuf, .len = ilen } };
62 int ret = i2c_transfer(props->adap, msg, 2);
63
64 return (ret == 2) ? ilen : ret;
65}
66
67/* Callers must declare as a global for the module:
68 *
69 * static LIST_HEAD(hybrid_tuner_instance_list);
70 *
71 * hybrid_tuner_instance_list should be the third argument
72 * passed into hybrid_tuner_request_state().
73 *
74 * state structure must contain the following:
75 *
76 * struct list_head hybrid_tuner_instance_list;
77 * struct tuner_i2c_props i2c_props;
78 *
79 * hybrid_tuner_instance_list (both within state structure and globally)
80 * is only required if the driver is using hybrid_tuner_request_state
81 * and hybrid_tuner_release_state to manage state sharing between
82 * multiple instances of hybrid tuners.
83 */
84
85#define tuner_printk(kernlvl, i2cprops, fmt, arg...) do { \
86 printk(kernlvl "%s %d-%04x: " fmt, i2cprops.name, \
87 i2cprops.adap ? \
88 i2c_adapter_id(i2cprops.adap) : -1, \
89 i2cprops.addr, ##arg); \
90 } while (0)
91
92/* TO DO: convert all callers of these macros to pass in
93 * struct tuner_i2c_props, then remove the macro wrappers */
94
95#define __tuner_warn(i2cprops, fmt, arg...) do { \
96 tuner_printk(KERN_WARNING, i2cprops, fmt, ##arg); \
97 } while (0)
98
99#define __tuner_info(i2cprops, fmt, arg...) do { \
100 tuner_printk(KERN_INFO, i2cprops, fmt, ##arg); \
101 } while (0)
102
103#define __tuner_err(i2cprops, fmt, arg...) do { \
104 tuner_printk(KERN_ERR, i2cprops, fmt, ##arg); \
105 } while (0)
106
107#define __tuner_dbg(i2cprops, fmt, arg...) do { \
108 if ((debug)) \
109 tuner_printk(KERN_DEBUG, i2cprops, fmt, ##arg); \
110 } while (0)
111
112#define tuner_warn(fmt, arg...) __tuner_warn(priv->i2c_props, fmt, ##arg)
113#define tuner_info(fmt, arg...) __tuner_info(priv->i2c_props, fmt, ##arg)
114#define tuner_err(fmt, arg...) __tuner_err(priv->i2c_props, fmt, ##arg)
115#define tuner_dbg(fmt, arg...) __tuner_dbg(priv->i2c_props, fmt, ##arg)
116
117/****************************************************************************/
118
119/* The return value of hybrid_tuner_request_state indicates the number of
120 * instances using this tuner object.
121 *
122 * 0 - no instances, indicates an error - kzalloc must have failed
123 *
124 * 1 - one instance, indicates that the tuner object was created successfully
125 *
126 * 2 (or more) instances, indicates that an existing tuner object was found
127 */
128
129#define hybrid_tuner_request_state(type, state, list, i2cadap, i2caddr, devname)\
130({ \
131 int __ret = 0; \
132 list_for_each_entry(state, &list, hybrid_tuner_instance_list) { \
133 if (((i2cadap) && (state->i2c_props.adap)) && \
134 ((i2c_adapter_id(state->i2c_props.adap) == \
135 i2c_adapter_id(i2cadap)) && \
136 (i2caddr == state->i2c_props.addr))) { \
137 __tuner_info(state->i2c_props, \
138 "attaching existing instance\n"); \
139 state->i2c_props.count++; \
140 __ret = state->i2c_props.count; \
141 break; \
142 } \
143 } \
144 if (0 == __ret) { \
145 state = kzalloc(sizeof(type), GFP_KERNEL); \
146 if (NULL == state) \
147 goto __fail; \
148 state->i2c_props.addr = i2caddr; \
149 state->i2c_props.adap = i2cadap; \
150 state->i2c_props.name = devname; \
151 __tuner_info(state->i2c_props, \
152 "creating new instance\n"); \
153 list_add_tail(&state->hybrid_tuner_instance_list, &list);\
154 state->i2c_props.count++; \
155 __ret = state->i2c_props.count; \
156 } \
157__fail: \
158 __ret; \
159})
160
161#define hybrid_tuner_release_state(state) \
162({ \
163 int __ret; \
164 state->i2c_props.count--; \
165 __ret = state->i2c_props.count; \
166 if (!state->i2c_props.count) { \
167 __tuner_info(state->i2c_props, "destroying instance\n");\
168 list_del(&state->hybrid_tuner_instance_list); \
169 kfree(state); \
170 } \
171 __ret; \
172})
173
174#define hybrid_tuner_report_instance_count(state) \
175({ \
176 int __ret = 0; \
177 if (state) \
178 __ret = state->i2c_props.count; \
179 __ret; \
180})
181
182#endif /* __TUNER_I2C_H__ */
diff --git a/drivers/media/tuners/tuner-simple.c b/drivers/media/tuners/tuner-simple.c
new file mode 100644
index 000000000000..39e7e583c8c0
--- /dev/null
+++ b/drivers/media/tuners/tuner-simple.c
@@ -0,0 +1,1155 @@
1/*
2 * i2c tv tuner chip device driver
3 * controls all those simple 4-control-bytes style tuners.
4 *
5 * This "tuner-simple" module was split apart from the original "tuner" module.
6 */
7#include <linux/delay.h>
8#include <linux/i2c.h>
9#include <linux/videodev2.h>
10#include <media/tuner.h>
11#include <media/v4l2-common.h>
12#include <media/tuner-types.h>
13#include "tuner-i2c.h"
14#include "tuner-simple.h"
15
16static int debug;
17module_param(debug, int, 0644);
18MODULE_PARM_DESC(debug, "enable verbose debug messages");
19
20#define TUNER_SIMPLE_MAX 64
21static unsigned int simple_devcount;
22
23static int offset;
24module_param(offset, int, 0664);
25MODULE_PARM_DESC(offset, "Allows to specify an offset for tuner");
26
27static unsigned int atv_input[TUNER_SIMPLE_MAX] = \
28 { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 };
29static unsigned int dtv_input[TUNER_SIMPLE_MAX] = \
30 { [0 ... (TUNER_SIMPLE_MAX-1)] = 0 };
31module_param_array(atv_input, int, NULL, 0644);
32module_param_array(dtv_input, int, NULL, 0644);
33MODULE_PARM_DESC(atv_input, "specify atv rf input, 0 for autoselect");
34MODULE_PARM_DESC(dtv_input, "specify dtv rf input, 0 for autoselect");
35
36/* ---------------------------------------------------------------------- */
37
38/* tv standard selection for Temic 4046 FM5
39 this value takes the low bits of control byte 2
40 from datasheet Rev.01, Feb.00
41 standard BG I L L2 D
42 picture IF 38.9 38.9 38.9 33.95 38.9
43 sound 1 33.4 32.9 32.4 40.45 32.4
44 sound 2 33.16
45 NICAM 33.05 32.348 33.05 33.05
46 */
47#define TEMIC_SET_PAL_I 0x05
48#define TEMIC_SET_PAL_DK 0x09
49#define TEMIC_SET_PAL_L 0x0a /* SECAM ? */
50#define TEMIC_SET_PAL_L2 0x0b /* change IF ! */
51#define TEMIC_SET_PAL_BG 0x0c
52
53/* tv tuner system standard selection for Philips FQ1216ME
54 this value takes the low bits of control byte 2
55 from datasheet "1999 Nov 16" (supersedes "1999 Mar 23")
56 standard BG DK I L L`
57 picture carrier 38.90 38.90 38.90 38.90 33.95
58 colour 34.47 34.47 34.47 34.47 38.38
59 sound 1 33.40 32.40 32.90 32.40 40.45
60 sound 2 33.16 - - - -
61 NICAM 33.05 33.05 32.35 33.05 39.80
62 */
63#define PHILIPS_SET_PAL_I 0x01 /* Bit 2 always zero !*/
64#define PHILIPS_SET_PAL_BGDK 0x09
65#define PHILIPS_SET_PAL_L2 0x0a
66#define PHILIPS_SET_PAL_L 0x0b
67
68/* system switching for Philips FI1216MF MK2
69 from datasheet "1996 Jul 09",
70 standard BG L L'
71 picture carrier 38.90 38.90 33.95
72 colour 34.47 34.37 38.38
73 sound 1 33.40 32.40 40.45
74 sound 2 33.16 - -
75 NICAM 33.05 33.05 39.80
76 */
77#define PHILIPS_MF_SET_STD_BG 0x01 /* Bit 2 must be zero, Bit 3 is system output */
78#define PHILIPS_MF_SET_STD_L 0x03 /* Used on Secam France */
79#define PHILIPS_MF_SET_STD_LC 0x02 /* Used on SECAM L' */
80
81/* Control byte */
82
83#define TUNER_RATIO_MASK 0x06 /* Bit cb1:cb2 */
84#define TUNER_RATIO_SELECT_50 0x00
85#define TUNER_RATIO_SELECT_32 0x02
86#define TUNER_RATIO_SELECT_166 0x04
87#define TUNER_RATIO_SELECT_62 0x06
88
89#define TUNER_CHARGE_PUMP 0x40 /* Bit cb6 */
90
91/* Status byte */
92
93#define TUNER_POR 0x80
94#define TUNER_FL 0x40
95#define TUNER_MODE 0x38
96#define TUNER_AFC 0x07
97#define TUNER_SIGNAL 0x07
98#define TUNER_STEREO 0x10
99
100#define TUNER_PLL_LOCKED 0x40
101#define TUNER_STEREO_MK3 0x04
102
103static DEFINE_MUTEX(tuner_simple_list_mutex);
104static LIST_HEAD(hybrid_tuner_instance_list);
105
106struct tuner_simple_priv {
107 unsigned int nr;
108 u16 last_div;
109
110 struct tuner_i2c_props i2c_props;
111 struct list_head hybrid_tuner_instance_list;
112
113 unsigned int type;
114 struct tunertype *tun;
115
116 u32 frequency;
117 u32 bandwidth;
118};
119
120/* ---------------------------------------------------------------------- */
121
122static int tuner_read_status(struct dvb_frontend *fe)
123{
124 struct tuner_simple_priv *priv = fe->tuner_priv;
125 unsigned char byte;
126
127 if (1 != tuner_i2c_xfer_recv(&priv->i2c_props, &byte, 1))
128 return 0;
129
130 return byte;
131}
132
133static inline int tuner_signal(const int status)
134{
135 return (status & TUNER_SIGNAL) << 13;
136}
137
138static inline int tuner_stereo(const int type, const int status)
139{
140 switch (type) {
141 case TUNER_PHILIPS_FM1216ME_MK3:
142 case TUNER_PHILIPS_FM1236_MK3:
143 case TUNER_PHILIPS_FM1256_IH3:
144 case TUNER_LG_NTSC_TAPE:
145 case TUNER_TCL_MF02GIP_5N:
146 return ((status & TUNER_SIGNAL) == TUNER_STEREO_MK3);
147 case TUNER_PHILIPS_FM1216MK5:
148 return status | TUNER_STEREO;
149 default:
150 return status & TUNER_STEREO;
151 }
152}
153
154static inline int tuner_islocked(const int status)
155{
156 return (status & TUNER_FL);
157}
158
159static inline int tuner_afcstatus(const int status)
160{
161 return (status & TUNER_AFC) - 2;
162}
163
164
165static int simple_get_status(struct dvb_frontend *fe, u32 *status)
166{
167 struct tuner_simple_priv *priv = fe->tuner_priv;
168 int tuner_status;
169
170 if (priv->i2c_props.adap == NULL)
171 return -EINVAL;
172
173 tuner_status = tuner_read_status(fe);
174
175 *status = 0;
176
177 if (tuner_islocked(tuner_status))
178 *status = TUNER_STATUS_LOCKED;
179 if (tuner_stereo(priv->type, tuner_status))
180 *status |= TUNER_STATUS_STEREO;
181
182 tuner_dbg("AFC Status: %d\n", tuner_afcstatus(tuner_status));
183
184 return 0;
185}
186
187static int simple_get_rf_strength(struct dvb_frontend *fe, u16 *strength)
188{
189 struct tuner_simple_priv *priv = fe->tuner_priv;
190 int signal;
191
192 if (priv->i2c_props.adap == NULL)
193 return -EINVAL;
194
195 signal = tuner_signal(tuner_read_status(fe));
196
197 *strength = signal;
198
199 tuner_dbg("Signal strength: %d\n", signal);
200
201 return 0;
202}
203
204/* ---------------------------------------------------------------------- */
205
206static inline char *tuner_param_name(enum param_type type)
207{
208 char *name;
209
210 switch (type) {
211 case TUNER_PARAM_TYPE_RADIO:
212 name = "radio";
213 break;
214 case TUNER_PARAM_TYPE_PAL:
215 name = "pal";
216 break;
217 case TUNER_PARAM_TYPE_SECAM:
218 name = "secam";
219 break;
220 case TUNER_PARAM_TYPE_NTSC:
221 name = "ntsc";
222 break;
223 case TUNER_PARAM_TYPE_DIGITAL:
224 name = "digital";
225 break;
226 default:
227 name = "unknown";
228 break;
229 }
230 return name;
231}
232
233static struct tuner_params *simple_tuner_params(struct dvb_frontend *fe,
234 enum param_type desired_type)
235{
236 struct tuner_simple_priv *priv = fe->tuner_priv;
237 struct tunertype *tun = priv->tun;
238 int i;
239
240 for (i = 0; i < tun->count; i++)
241 if (desired_type == tun->params[i].type)
242 break;
243
244 /* use default tuner params if desired_type not available */
245 if (i == tun->count) {
246 tuner_dbg("desired params (%s) undefined for tuner %d\n",
247 tuner_param_name(desired_type), priv->type);
248 i = 0;
249 }
250
251 tuner_dbg("using tuner params #%d (%s)\n", i,
252 tuner_param_name(tun->params[i].type));
253
254 return &tun->params[i];
255}
256
257static int simple_config_lookup(struct dvb_frontend *fe,
258 struct tuner_params *t_params,
259 unsigned *frequency, u8 *config, u8 *cb)
260{
261 struct tuner_simple_priv *priv = fe->tuner_priv;
262 int i;
263
264 for (i = 0; i < t_params->count; i++) {
265 if (*frequency > t_params->ranges[i].limit)
266 continue;
267 break;
268 }
269 if (i == t_params->count) {
270 tuner_dbg("frequency out of range (%d > %d)\n",
271 *frequency, t_params->ranges[i - 1].limit);
272 *frequency = t_params->ranges[--i].limit;
273 }
274 *config = t_params->ranges[i].config;
275 *cb = t_params->ranges[i].cb;
276
277 tuner_dbg("freq = %d.%02d (%d), range = %d, "
278 "config = 0x%02x, cb = 0x%02x\n",
279 *frequency / 16, *frequency % 16 * 100 / 16, *frequency,
280 i, *config, *cb);
281
282 return i;
283}
284
285/* ---------------------------------------------------------------------- */
286
287static void simple_set_rf_input(struct dvb_frontend *fe,
288 u8 *config, u8 *cb, unsigned int rf)
289{
290 struct tuner_simple_priv *priv = fe->tuner_priv;
291
292 switch (priv->type) {
293 case TUNER_PHILIPS_TUV1236D:
294 switch (rf) {
295 case 1:
296 *cb |= 0x08;
297 break;
298 default:
299 *cb &= ~0x08;
300 break;
301 }
302 break;
303 case TUNER_PHILIPS_FCV1236D:
304 switch (rf) {
305 case 1:
306 *cb |= 0x01;
307 break;
308 default:
309 *cb &= ~0x01;
310 break;
311 }
312 break;
313 default:
314 break;
315 }
316}
317
318static int simple_std_setup(struct dvb_frontend *fe,
319 struct analog_parameters *params,
320 u8 *config, u8 *cb)
321{
322 struct tuner_simple_priv *priv = fe->tuner_priv;
323 int rc;
324
325 /* tv norm specific stuff for multi-norm tuners */
326 switch (priv->type) {
327 case TUNER_PHILIPS_SECAM: /* FI1216MF */
328 /* 0x01 -> ??? no change ??? */
329 /* 0x02 -> PAL BDGHI / SECAM L */
330 /* 0x04 -> ??? PAL others / SECAM others ??? */
331 *cb &= ~0x03;
332 if (params->std & V4L2_STD_SECAM_L)
333 /* also valid for V4L2_STD_SECAM */
334 *cb |= PHILIPS_MF_SET_STD_L;
335 else if (params->std & V4L2_STD_SECAM_LC)
336 *cb |= PHILIPS_MF_SET_STD_LC;
337 else /* V4L2_STD_B|V4L2_STD_GH */
338 *cb |= PHILIPS_MF_SET_STD_BG;
339 break;
340
341 case TUNER_TEMIC_4046FM5:
342 *cb &= ~0x0f;
343
344 if (params->std & V4L2_STD_PAL_BG) {
345 *cb |= TEMIC_SET_PAL_BG;
346
347 } else if (params->std & V4L2_STD_PAL_I) {
348 *cb |= TEMIC_SET_PAL_I;
349
350 } else if (params->std & V4L2_STD_PAL_DK) {
351 *cb |= TEMIC_SET_PAL_DK;
352
353 } else if (params->std & V4L2_STD_SECAM_L) {
354 *cb |= TEMIC_SET_PAL_L;
355
356 }
357 break;
358
359 case TUNER_PHILIPS_FQ1216ME:
360 *cb &= ~0x0f;
361
362 if (params->std & (V4L2_STD_PAL_BG|V4L2_STD_PAL_DK)) {
363 *cb |= PHILIPS_SET_PAL_BGDK;
364
365 } else if (params->std & V4L2_STD_PAL_I) {
366 *cb |= PHILIPS_SET_PAL_I;
367
368 } else if (params->std & V4L2_STD_SECAM_L) {
369 *cb |= PHILIPS_SET_PAL_L;
370
371 }
372 break;
373
374 case TUNER_PHILIPS_FCV1236D:
375 /* 0x00 -> ATSC antenna input 1 */
376 /* 0x01 -> ATSC antenna input 2 */
377 /* 0x02 -> NTSC antenna input 1 */
378 /* 0x03 -> NTSC antenna input 2 */
379 *cb &= ~0x03;
380 if (!(params->std & V4L2_STD_ATSC))
381 *cb |= 2;
382 break;
383
384 case TUNER_MICROTUNE_4042FI5:
385 /* Set the charge pump for fast tuning */
386 *config |= TUNER_CHARGE_PUMP;
387 break;
388
389 case TUNER_PHILIPS_TUV1236D:
390 {
391 struct tuner_i2c_props i2c = priv->i2c_props;
392 /* 0x40 -> ATSC antenna input 1 */
393 /* 0x48 -> ATSC antenna input 2 */
394 /* 0x00 -> NTSC antenna input 1 */
395 /* 0x08 -> NTSC antenna input 2 */
396 u8 buffer[4] = { 0x14, 0x00, 0x17, 0x00};
397 *cb &= ~0x40;
398 if (params->std & V4L2_STD_ATSC) {
399 *cb |= 0x40;
400 buffer[1] = 0x04;
401 }
402 /* set to the correct mode (analog or digital) */
403 i2c.addr = 0x0a;
404 rc = tuner_i2c_xfer_send(&i2c, &buffer[0], 2);
405 if (2 != rc)
406 tuner_warn("i2c i/o error: rc == %d "
407 "(should be 2)\n", rc);
408 rc = tuner_i2c_xfer_send(&i2c, &buffer[2], 2);
409 if (2 != rc)
410 tuner_warn("i2c i/o error: rc == %d "
411 "(should be 2)\n", rc);
412 break;
413 }
414 }
415 if (atv_input[priv->nr])
416 simple_set_rf_input(fe, config, cb, atv_input[priv->nr]);
417
418 return 0;
419}
420
421static int simple_set_aux_byte(struct dvb_frontend *fe, u8 config, u8 aux)
422{
423 struct tuner_simple_priv *priv = fe->tuner_priv;
424 int rc;
425 u8 buffer[2];
426
427 buffer[0] = (config & ~0x38) | 0x18;
428 buffer[1] = aux;
429
430 tuner_dbg("setting aux byte: 0x%02x 0x%02x\n", buffer[0], buffer[1]);
431
432 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 2);
433 if (2 != rc)
434 tuner_warn("i2c i/o error: rc == %d (should be 2)\n", rc);
435
436 return rc == 2 ? 0 : rc;
437}
438
439static int simple_post_tune(struct dvb_frontend *fe, u8 *buffer,
440 u16 div, u8 config, u8 cb)
441{
442 struct tuner_simple_priv *priv = fe->tuner_priv;
443 int rc;
444
445 switch (priv->type) {
446 case TUNER_LG_TDVS_H06XF:
447 simple_set_aux_byte(fe, config, 0x20);
448 break;
449 case TUNER_PHILIPS_FQ1216LME_MK3:
450 simple_set_aux_byte(fe, config, 0x60); /* External AGC */
451 break;
452 case TUNER_MICROTUNE_4042FI5:
453 {
454 /* FIXME - this may also work for other tuners */
455 unsigned long timeout = jiffies + msecs_to_jiffies(1);
456 u8 status_byte = 0;
457
458 /* Wait until the PLL locks */
459 for (;;) {
460 if (time_after(jiffies, timeout))
461 return 0;
462 rc = tuner_i2c_xfer_recv(&priv->i2c_props,
463 &status_byte, 1);
464 if (1 != rc) {
465 tuner_warn("i2c i/o read error: rc == %d "
466 "(should be 1)\n", rc);
467 break;
468 }
469 if (status_byte & TUNER_PLL_LOCKED)
470 break;
471 udelay(10);
472 }
473
474 /* Set the charge pump for optimized phase noise figure */
475 config &= ~TUNER_CHARGE_PUMP;
476 buffer[0] = (div>>8) & 0x7f;
477 buffer[1] = div & 0xff;
478 buffer[2] = config;
479 buffer[3] = cb;
480 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
481 buffer[0], buffer[1], buffer[2], buffer[3]);
482
483 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
484 if (4 != rc)
485 tuner_warn("i2c i/o error: rc == %d "
486 "(should be 4)\n", rc);
487 break;
488 }
489 }
490
491 return 0;
492}
493
494static int simple_radio_bandswitch(struct dvb_frontend *fe, u8 *buffer)
495{
496 struct tuner_simple_priv *priv = fe->tuner_priv;
497
498 switch (priv->type) {
499 case TUNER_TENA_9533_DI:
500 case TUNER_YMEC_TVF_5533MF:
501 tuner_dbg("This tuner doesn't have FM. "
502 "Most cards have a TEA5767 for FM\n");
503 return 0;
504 case TUNER_PHILIPS_FM1216ME_MK3:
505 case TUNER_PHILIPS_FM1236_MK3:
506 case TUNER_PHILIPS_FMD1216ME_MK3:
507 case TUNER_PHILIPS_FMD1216MEX_MK3:
508 case TUNER_LG_NTSC_TAPE:
509 case TUNER_PHILIPS_FM1256_IH3:
510 case TUNER_TCL_MF02GIP_5N:
511 buffer[3] = 0x19;
512 break;
513 case TUNER_PHILIPS_FM1216MK5:
514 buffer[2] = 0x88;
515 buffer[3] = 0x09;
516 break;
517 case TUNER_TNF_5335MF:
518 buffer[3] = 0x11;
519 break;
520 case TUNER_LG_PAL_FM:
521 buffer[3] = 0xa5;
522 break;
523 case TUNER_THOMSON_DTT761X:
524 buffer[3] = 0x39;
525 break;
526 case TUNER_PHILIPS_FQ1216LME_MK3:
527 case TUNER_PHILIPS_FQ1236_MK5:
528 tuner_err("This tuner doesn't have FM\n");
529 /* Set the low band for sanity, since it covers 88-108 MHz */
530 buffer[3] = 0x01;
531 break;
532 case TUNER_MICROTUNE_4049FM5:
533 default:
534 buffer[3] = 0xa4;
535 break;
536 }
537
538 return 0;
539}
540
541/* ---------------------------------------------------------------------- */
542
543static int simple_set_tv_freq(struct dvb_frontend *fe,
544 struct analog_parameters *params)
545{
546 struct tuner_simple_priv *priv = fe->tuner_priv;
547 u8 config, cb;
548 u16 div;
549 u8 buffer[4];
550 int rc, IFPCoff, i;
551 enum param_type desired_type;
552 struct tuner_params *t_params;
553
554 /* IFPCoff = Video Intermediate Frequency - Vif:
555 940 =16*58.75 NTSC/J (Japan)
556 732 =16*45.75 M/N STD
557 704 =16*44 ATSC (at DVB code)
558 632 =16*39.50 I U.K.
559 622.4=16*38.90 B/G D/K I, L STD
560 592 =16*37.00 D China
561 590 =16.36.875 B Australia
562 543.2=16*33.95 L' STD
563 171.2=16*10.70 FM Radio (at set_radio_freq)
564 */
565
566 if (params->std == V4L2_STD_NTSC_M_JP) {
567 IFPCoff = 940;
568 desired_type = TUNER_PARAM_TYPE_NTSC;
569 } else if ((params->std & V4L2_STD_MN) &&
570 !(params->std & ~V4L2_STD_MN)) {
571 IFPCoff = 732;
572 desired_type = TUNER_PARAM_TYPE_NTSC;
573 } else if (params->std == V4L2_STD_SECAM_LC) {
574 IFPCoff = 543;
575 desired_type = TUNER_PARAM_TYPE_SECAM;
576 } else {
577 IFPCoff = 623;
578 desired_type = TUNER_PARAM_TYPE_PAL;
579 }
580
581 t_params = simple_tuner_params(fe, desired_type);
582
583 i = simple_config_lookup(fe, t_params, &params->frequency,
584 &config, &cb);
585
586 div = params->frequency + IFPCoff + offset;
587
588 tuner_dbg("Freq= %d.%02d MHz, V_IF=%d.%02d MHz, "
589 "Offset=%d.%02d MHz, div=%0d\n",
590 params->frequency / 16, params->frequency % 16 * 100 / 16,
591 IFPCoff / 16, IFPCoff % 16 * 100 / 16,
592 offset / 16, offset % 16 * 100 / 16, div);
593
594 /* tv norm specific stuff for multi-norm tuners */
595 simple_std_setup(fe, params, &config, &cb);
596
597 if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
598 buffer[0] = config;
599 buffer[1] = cb;
600 buffer[2] = (div>>8) & 0x7f;
601 buffer[3] = div & 0xff;
602 } else {
603 buffer[0] = (div>>8) & 0x7f;
604 buffer[1] = div & 0xff;
605 buffer[2] = config;
606 buffer[3] = cb;
607 }
608 priv->last_div = div;
609 if (t_params->has_tda9887) {
610 struct v4l2_priv_tun_config tda9887_cfg;
611 int tda_config = 0;
612 int is_secam_l = (params->std & (V4L2_STD_SECAM_L |
613 V4L2_STD_SECAM_LC)) &&
614 !(params->std & ~(V4L2_STD_SECAM_L |
615 V4L2_STD_SECAM_LC));
616
617 tda9887_cfg.tuner = TUNER_TDA9887;
618 tda9887_cfg.priv = &tda_config;
619
620 if (params->std == V4L2_STD_SECAM_LC) {
621 if (t_params->port1_active ^ t_params->port1_invert_for_secam_lc)
622 tda_config |= TDA9887_PORT1_ACTIVE;
623 if (t_params->port2_active ^ t_params->port2_invert_for_secam_lc)
624 tda_config |= TDA9887_PORT2_ACTIVE;
625 } else {
626 if (t_params->port1_active)
627 tda_config |= TDA9887_PORT1_ACTIVE;
628 if (t_params->port2_active)
629 tda_config |= TDA9887_PORT2_ACTIVE;
630 }
631 if (t_params->intercarrier_mode)
632 tda_config |= TDA9887_INTERCARRIER;
633 if (is_secam_l) {
634 if (i == 0 && t_params->default_top_secam_low)
635 tda_config |= TDA9887_TOP(t_params->default_top_secam_low);
636 else if (i == 1 && t_params->default_top_secam_mid)
637 tda_config |= TDA9887_TOP(t_params->default_top_secam_mid);
638 else if (t_params->default_top_secam_high)
639 tda_config |= TDA9887_TOP(t_params->default_top_secam_high);
640 } else {
641 if (i == 0 && t_params->default_top_low)
642 tda_config |= TDA9887_TOP(t_params->default_top_low);
643 else if (i == 1 && t_params->default_top_mid)
644 tda_config |= TDA9887_TOP(t_params->default_top_mid);
645 else if (t_params->default_top_high)
646 tda_config |= TDA9887_TOP(t_params->default_top_high);
647 }
648 if (t_params->default_pll_gating_18)
649 tda_config |= TDA9887_GATING_18;
650 i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
651 &tda9887_cfg);
652 }
653 tuner_dbg("tv 0x%02x 0x%02x 0x%02x 0x%02x\n",
654 buffer[0], buffer[1], buffer[2], buffer[3]);
655
656 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
657 if (4 != rc)
658 tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
659
660 simple_post_tune(fe, &buffer[0], div, config, cb);
661
662 return 0;
663}
664
665static int simple_set_radio_freq(struct dvb_frontend *fe,
666 struct analog_parameters *params)
667{
668 struct tunertype *tun;
669 struct tuner_simple_priv *priv = fe->tuner_priv;
670 u8 buffer[4];
671 u16 div;
672 int rc, j;
673 struct tuner_params *t_params;
674 unsigned int freq = params->frequency;
675
676 tun = priv->tun;
677
678 for (j = tun->count-1; j > 0; j--)
679 if (tun->params[j].type == TUNER_PARAM_TYPE_RADIO)
680 break;
681 /* default t_params (j=0) will be used if desired type wasn't found */
682 t_params = &tun->params[j];
683
684 /* Select Radio 1st IF used */
685 switch (t_params->radio_if) {
686 case 0: /* 10.7 MHz */
687 freq += (unsigned int)(10.7*16000);
688 break;
689 case 1: /* 33.3 MHz */
690 freq += (unsigned int)(33.3*16000);
691 break;
692 case 2: /* 41.3 MHz */
693 freq += (unsigned int)(41.3*16000);
694 break;
695 default:
696 tuner_warn("Unsupported radio_if value %d\n",
697 t_params->radio_if);
698 return 0;
699 }
700
701 buffer[2] = (t_params->ranges[0].config & ~TUNER_RATIO_MASK) |
702 TUNER_RATIO_SELECT_50; /* 50 kHz step */
703
704 /* Bandswitch byte */
705 simple_radio_bandswitch(fe, &buffer[0]);
706
707 /* Convert from 1/16 kHz V4L steps to 1/20 MHz (=50 kHz) PLL steps
708 freq * (1 Mhz / 16000 V4L steps) * (20 PLL steps / 1 MHz) =
709 freq * (1/800) */
710 div = (freq + 400) / 800;
711
712 if (t_params->cb_first_if_lower_freq && div < priv->last_div) {
713 buffer[0] = buffer[2];
714 buffer[1] = buffer[3];
715 buffer[2] = (div>>8) & 0x7f;
716 buffer[3] = div & 0xff;
717 } else {
718 buffer[0] = (div>>8) & 0x7f;
719 buffer[1] = div & 0xff;
720 }
721
722 tuner_dbg("radio 0x%02x 0x%02x 0x%02x 0x%02x\n",
723 buffer[0], buffer[1], buffer[2], buffer[3]);
724 priv->last_div = div;
725
726 if (t_params->has_tda9887) {
727 int config = 0;
728 struct v4l2_priv_tun_config tda9887_cfg;
729
730 tda9887_cfg.tuner = TUNER_TDA9887;
731 tda9887_cfg.priv = &config;
732
733 if (t_params->port1_active &&
734 !t_params->port1_fm_high_sensitivity)
735 config |= TDA9887_PORT1_ACTIVE;
736 if (t_params->port2_active &&
737 !t_params->port2_fm_high_sensitivity)
738 config |= TDA9887_PORT2_ACTIVE;
739 if (t_params->intercarrier_mode)
740 config |= TDA9887_INTERCARRIER;
741/* if (t_params->port1_set_for_fm_mono)
742 config &= ~TDA9887_PORT1_ACTIVE;*/
743 if (t_params->fm_gain_normal)
744 config |= TDA9887_GAIN_NORMAL;
745 if (t_params->radio_if == 2)
746 config |= TDA9887_RIF_41_3;
747 i2c_clients_command(priv->i2c_props.adap, TUNER_SET_CONFIG,
748 &tda9887_cfg);
749 }
750 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
751 if (4 != rc)
752 tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
753
754 /* Write AUX byte */
755 switch (priv->type) {
756 case TUNER_PHILIPS_FM1216ME_MK3:
757 buffer[2] = 0x98;
758 buffer[3] = 0x20; /* set TOP AGC */
759 rc = tuner_i2c_xfer_send(&priv->i2c_props, buffer, 4);
760 if (4 != rc)
761 tuner_warn("i2c i/o error: rc == %d (should be 4)\n", rc);
762 break;
763 }
764
765 return 0;
766}
767
768static int simple_set_params(struct dvb_frontend *fe,
769 struct analog_parameters *params)
770{
771 struct tuner_simple_priv *priv = fe->tuner_priv;
772 int ret = -EINVAL;
773
774 if (priv->i2c_props.adap == NULL)
775 return -EINVAL;
776
777 switch (params->mode) {
778 case V4L2_TUNER_RADIO:
779 ret = simple_set_radio_freq(fe, params);
780 priv->frequency = params->frequency * 125 / 2;
781 break;
782 case V4L2_TUNER_ANALOG_TV:
783 case V4L2_TUNER_DIGITAL_TV:
784 ret = simple_set_tv_freq(fe, params);
785 priv->frequency = params->frequency * 62500;
786 break;
787 }
788 priv->bandwidth = 0;
789
790 return ret;
791}
792
793static void simple_set_dvb(struct dvb_frontend *fe, u8 *buf,
794 const u32 delsys,
795 const u32 frequency,
796 const u32 bandwidth)
797{
798 struct tuner_simple_priv *priv = fe->tuner_priv;
799
800 switch (priv->type) {
801 case TUNER_PHILIPS_FMD1216ME_MK3:
802 case TUNER_PHILIPS_FMD1216MEX_MK3:
803 if (bandwidth == 8000000 &&
804 frequency >= 158870000)
805 buf[3] |= 0x08;
806 break;
807 case TUNER_PHILIPS_TD1316:
808 /* determine band */
809 buf[3] |= (frequency < 161000000) ? 1 :
810 (frequency < 444000000) ? 2 : 4;
811
812 /* setup PLL filter */
813 if (bandwidth == 8000000)
814 buf[3] |= 1 << 3;
815 break;
816 case TUNER_PHILIPS_TUV1236D:
817 case TUNER_PHILIPS_FCV1236D:
818 {
819 unsigned int new_rf;
820
821 if (dtv_input[priv->nr])
822 new_rf = dtv_input[priv->nr];
823 else
824 switch (delsys) {
825 case SYS_DVBC_ANNEX_B:
826 new_rf = 1;
827 break;
828 case SYS_ATSC:
829 default:
830 new_rf = 0;
831 break;
832 }
833 simple_set_rf_input(fe, &buf[2], &buf[3], new_rf);
834 break;
835 }
836 default:
837 break;
838 }
839}
840
841static u32 simple_dvb_configure(struct dvb_frontend *fe, u8 *buf,
842 const u32 delsys,
843 const u32 freq,
844 const u32 bw)
845{
846 /* This function returns the tuned frequency on success, 0 on error */
847 struct tuner_simple_priv *priv = fe->tuner_priv;
848 struct tunertype *tun = priv->tun;
849 static struct tuner_params *t_params;
850 u8 config, cb;
851 u32 div;
852 int ret;
853 u32 frequency = freq / 62500;
854
855 if (!tun->stepsize) {
856 /* tuner-core was loaded before the digital tuner was
857 * configured and somehow picked the wrong tuner type */
858 tuner_err("attempt to treat tuner %d (%s) as digital tuner "
859 "without stepsize defined.\n",
860 priv->type, priv->tun->name);
861 return 0; /* failure */
862 }
863
864 t_params = simple_tuner_params(fe, TUNER_PARAM_TYPE_DIGITAL);
865 ret = simple_config_lookup(fe, t_params, &frequency, &config, &cb);
866 if (ret < 0)
867 return 0; /* failure */
868
869 div = ((frequency + t_params->iffreq) * 62500 + offset +
870 tun->stepsize/2) / tun->stepsize;
871
872 buf[0] = div >> 8;
873 buf[1] = div & 0xff;
874 buf[2] = config;
875 buf[3] = cb;
876
877 simple_set_dvb(fe, buf, delsys, freq, bw);
878
879 tuner_dbg("%s: div=%d | buf=0x%02x,0x%02x,0x%02x,0x%02x\n",
880 tun->name, div, buf[0], buf[1], buf[2], buf[3]);
881
882 /* calculate the frequency we set it to */
883 return (div * tun->stepsize) - t_params->iffreq;
884}
885
886static int simple_dvb_calc_regs(struct dvb_frontend *fe,
887 u8 *buf, int buf_len)
888{
889 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
890 u32 delsys = c->delivery_system;
891 u32 bw = c->bandwidth_hz;
892 struct tuner_simple_priv *priv = fe->tuner_priv;
893 u32 frequency;
894
895 if (buf_len < 5)
896 return -EINVAL;
897
898 frequency = simple_dvb_configure(fe, buf+1, delsys, c->frequency, bw);
899 if (frequency == 0)
900 return -EINVAL;
901
902 buf[0] = priv->i2c_props.addr;
903
904 priv->frequency = frequency;
905 priv->bandwidth = c->bandwidth_hz;
906
907 return 5;
908}
909
910static int simple_dvb_set_params(struct dvb_frontend *fe)
911{
912 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
913 u32 delsys = c->delivery_system;
914 u32 bw = c->bandwidth_hz;
915 u32 freq = c->frequency;
916 struct tuner_simple_priv *priv = fe->tuner_priv;
917 u32 frequency;
918 u32 prev_freq, prev_bw;
919 int ret;
920 u8 buf[5];
921
922 if (priv->i2c_props.adap == NULL)
923 return -EINVAL;
924
925 prev_freq = priv->frequency;
926 prev_bw = priv->bandwidth;
927
928 frequency = simple_dvb_configure(fe, buf+1, delsys, freq, bw);
929 if (frequency == 0)
930 return -EINVAL;
931
932 buf[0] = priv->i2c_props.addr;
933
934 priv->frequency = frequency;
935 priv->bandwidth = bw;
936
937 /* put analog demod in standby when tuning digital */
938 if (fe->ops.analog_ops.standby)
939 fe->ops.analog_ops.standby(fe);
940
941 if (fe->ops.i2c_gate_ctrl)
942 fe->ops.i2c_gate_ctrl(fe, 1);
943
944 /* buf[0] contains the i2c address, but *
945 * we already have it in i2c_props.addr */
946 ret = tuner_i2c_xfer_send(&priv->i2c_props, buf+1, 4);
947 if (ret != 4)
948 goto fail;
949
950 return 0;
951fail:
952 /* calc_regs sets frequency and bandwidth. if we failed, unset them */
953 priv->frequency = prev_freq;
954 priv->bandwidth = prev_bw;
955
956 return ret;
957}
958
959static int simple_init(struct dvb_frontend *fe)
960{
961 struct tuner_simple_priv *priv = fe->tuner_priv;
962
963 if (priv->i2c_props.adap == NULL)
964 return -EINVAL;
965
966 if (priv->tun->initdata) {
967 int ret;
968
969 if (fe->ops.i2c_gate_ctrl)
970 fe->ops.i2c_gate_ctrl(fe, 1);
971
972 ret = tuner_i2c_xfer_send(&priv->i2c_props,
973 priv->tun->initdata + 1,
974 priv->tun->initdata[0]);
975 if (ret != priv->tun->initdata[0])
976 return ret;
977 }
978
979 return 0;
980}
981
982static int simple_sleep(struct dvb_frontend *fe)
983{
984 struct tuner_simple_priv *priv = fe->tuner_priv;
985
986 if (priv->i2c_props.adap == NULL)
987 return -EINVAL;
988
989 if (priv->tun->sleepdata) {
990 int ret;
991
992 if (fe->ops.i2c_gate_ctrl)
993 fe->ops.i2c_gate_ctrl(fe, 1);
994
995 ret = tuner_i2c_xfer_send(&priv->i2c_props,
996 priv->tun->sleepdata + 1,
997 priv->tun->sleepdata[0]);
998 if (ret != priv->tun->sleepdata[0])
999 return ret;
1000 }
1001
1002 return 0;
1003}
1004
1005static int simple_release(struct dvb_frontend *fe)
1006{
1007 struct tuner_simple_priv *priv = fe->tuner_priv;
1008
1009 mutex_lock(&tuner_simple_list_mutex);
1010
1011 if (priv)
1012 hybrid_tuner_release_state(priv);
1013
1014 mutex_unlock(&tuner_simple_list_mutex);
1015
1016 fe->tuner_priv = NULL;
1017
1018 return 0;
1019}
1020
1021static int simple_get_frequency(struct dvb_frontend *fe, u32 *frequency)
1022{
1023 struct tuner_simple_priv *priv = fe->tuner_priv;
1024 *frequency = priv->frequency;
1025 return 0;
1026}
1027
1028static int simple_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
1029{
1030 struct tuner_simple_priv *priv = fe->tuner_priv;
1031 *bandwidth = priv->bandwidth;
1032 return 0;
1033}
1034
1035static struct dvb_tuner_ops simple_tuner_ops = {
1036 .init = simple_init,
1037 .sleep = simple_sleep,
1038 .set_analog_params = simple_set_params,
1039 .set_params = simple_dvb_set_params,
1040 .calc_regs = simple_dvb_calc_regs,
1041 .release = simple_release,
1042 .get_frequency = simple_get_frequency,
1043 .get_bandwidth = simple_get_bandwidth,
1044 .get_status = simple_get_status,
1045 .get_rf_strength = simple_get_rf_strength,
1046};
1047
1048struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
1049 struct i2c_adapter *i2c_adap,
1050 u8 i2c_addr,
1051 unsigned int type)
1052{
1053 struct tuner_simple_priv *priv = NULL;
1054 int instance;
1055
1056 if (type >= tuner_count) {
1057 printk(KERN_WARNING "%s: invalid tuner type: %d (max: %d)\n",
1058 __func__, type, tuner_count-1);
1059 return NULL;
1060 }
1061
1062 /* If i2c_adap is set, check that the tuner is at the correct address.
1063 * Otherwise, if i2c_adap is NULL, the tuner will be programmed directly
1064 * by the digital demod via calc_regs.
1065 */
1066 if (i2c_adap != NULL) {
1067 u8 b[1];
1068 struct i2c_msg msg = {
1069 .addr = i2c_addr, .flags = I2C_M_RD,
1070 .buf = b, .len = 1,
1071 };
1072
1073 if (fe->ops.i2c_gate_ctrl)
1074 fe->ops.i2c_gate_ctrl(fe, 1);
1075
1076 if (1 != i2c_transfer(i2c_adap, &msg, 1))
1077 printk(KERN_WARNING "tuner-simple %d-%04x: "
1078 "unable to probe %s, proceeding anyway.",
1079 i2c_adapter_id(i2c_adap), i2c_addr,
1080 tuners[type].name);
1081
1082 if (fe->ops.i2c_gate_ctrl)
1083 fe->ops.i2c_gate_ctrl(fe, 0);
1084 }
1085
1086 mutex_lock(&tuner_simple_list_mutex);
1087
1088 instance = hybrid_tuner_request_state(struct tuner_simple_priv, priv,
1089 hybrid_tuner_instance_list,
1090 i2c_adap, i2c_addr,
1091 "tuner-simple");
1092 switch (instance) {
1093 case 0:
1094 mutex_unlock(&tuner_simple_list_mutex);
1095 return NULL;
1096 case 1:
1097 fe->tuner_priv = priv;
1098
1099 priv->type = type;
1100 priv->tun = &tuners[type];
1101 priv->nr = simple_devcount++;
1102 break;
1103 default:
1104 fe->tuner_priv = priv;
1105 break;
1106 }
1107
1108 mutex_unlock(&tuner_simple_list_mutex);
1109
1110 memcpy(&fe->ops.tuner_ops, &simple_tuner_ops,
1111 sizeof(struct dvb_tuner_ops));
1112
1113 if (type != priv->type)
1114 tuner_warn("couldn't set type to %d. Using %d (%s) instead\n",
1115 type, priv->type, priv->tun->name);
1116 else
1117 tuner_info("type set to %d (%s)\n",
1118 priv->type, priv->tun->name);
1119
1120 if ((debug) || ((atv_input[priv->nr] > 0) ||
1121 (dtv_input[priv->nr] > 0))) {
1122 if (0 == atv_input[priv->nr])
1123 tuner_info("tuner %d atv rf input will be "
1124 "autoselected\n", priv->nr);
1125 else
1126 tuner_info("tuner %d atv rf input will be "
1127 "set to input %d (insmod option)\n",
1128 priv->nr, atv_input[priv->nr]);
1129 if (0 == dtv_input[priv->nr])
1130 tuner_info("tuner %d dtv rf input will be "
1131 "autoselected\n", priv->nr);
1132 else
1133 tuner_info("tuner %d dtv rf input will be "
1134 "set to input %d (insmod option)\n",
1135 priv->nr, dtv_input[priv->nr]);
1136 }
1137
1138 strlcpy(fe->ops.tuner_ops.info.name, priv->tun->name,
1139 sizeof(fe->ops.tuner_ops.info.name));
1140
1141 return fe;
1142}
1143EXPORT_SYMBOL_GPL(simple_tuner_attach);
1144
1145MODULE_DESCRIPTION("Simple 4-control-bytes style tuner driver");
1146MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
1147MODULE_LICENSE("GPL");
1148
1149/*
1150 * Overrides for Emacs so that we follow Linus's tabbing style.
1151 * ---------------------------------------------------------------------------
1152 * Local variables:
1153 * c-basic-offset: 8
1154 * End:
1155 */
diff --git a/drivers/media/tuners/tuner-simple.h b/drivers/media/tuners/tuner-simple.h
new file mode 100644
index 000000000000..381fa5d35a9b
--- /dev/null
+++ b/drivers/media/tuners/tuner-simple.h
@@ -0,0 +1,39 @@
1/*
2 This program is free software; you can redistribute it and/or modify
3 it under the terms of the GNU General Public License as published by
4 the Free Software Foundation; either version 2 of the License, or
5 (at your option) any later version.
6
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
11
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
15*/
16
17#ifndef __TUNER_SIMPLE_H__
18#define __TUNER_SIMPLE_H__
19
20#include <linux/i2c.h>
21#include "dvb_frontend.h"
22
23#if defined(CONFIG_MEDIA_TUNER_SIMPLE) || (defined(CONFIG_MEDIA_TUNER_SIMPLE_MODULE) && defined(MODULE))
24extern struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
25 struct i2c_adapter *i2c_adap,
26 u8 i2c_addr,
27 unsigned int type);
28#else
29static inline struct dvb_frontend *simple_tuner_attach(struct dvb_frontend *fe,
30 struct i2c_adapter *i2c_adap,
31 u8 i2c_addr,
32 unsigned int type)
33{
34 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
35 return NULL;
36}
37#endif
38
39#endif /* __TUNER_SIMPLE_H__ */
diff --git a/drivers/media/tuners/tuner-types.c b/drivers/media/tuners/tuner-types.c
new file mode 100644
index 000000000000..2da4440c16ee
--- /dev/null
+++ b/drivers/media/tuners/tuner-types.c
@@ -0,0 +1,1883 @@
1/*
2 *
3 * i2c tv tuner chip device type database.
4 *
5 */
6
7#include <linux/i2c.h>
8#include <linux/module.h>
9#include <media/tuner.h>
10#include <media/tuner-types.h>
11
12/* ---------------------------------------------------------------------- */
13
14/*
15 * The floats in the tuner struct are computed at compile time
16 * by gcc and cast back to integers. Thus we don't violate the
17 * "no float in kernel" rule.
18 *
19 * A tuner_range may be referenced by multiple tuner_params structs.
20 * There are many duplicates in here. Reusing tuner_range structs,
21 * rather than defining new ones for each tuner, will cut down on
22 * memory usage, and is preferred when possible.
23 *
24 * Each tuner_params array may contain one or more elements, one
25 * for each video standard.
26 *
27 * FIXME: tuner_params struct contains an element, tda988x. We must
28 * set this for all tuners that contain a tda988x chip, and then we
29 * can remove this setting from the various card structs.
30 *
31 * FIXME: Right now, all tuners are using the first tuner_params[]
32 * array element for analog mode. In the future, we will be merging
33 * similar tuner definitions together, such that each tuner definition
34 * will have a tuner_params struct for each available video standard.
35 * At that point, the tuner_params[] array element will be chosen
36 * based on the video standard in use.
37 */
38
39/* The following was taken from dvb-pll.c: */
40
41/* Set AGC TOP value to 103 dBuV:
42 * 0x80 = Control Byte
43 * 0x40 = 250 uA charge pump (irrelevant)
44 * 0x18 = Aux Byte to follow
45 * 0x06 = 64.5 kHz divider (irrelevant)
46 * 0x01 = Disable Vt (aka sleep)
47 *
48 * 0x00 = AGC Time constant 2s Iagc = 300 nA (vs 0x80 = 9 nA)
49 * 0x50 = AGC Take over point = 103 dBuV
50 */
51static u8 tua603x_agc103[] = { 2, 0x80|0x40|0x18|0x06|0x01, 0x00|0x50 };
52
53/* 0x04 = 166.67 kHz divider
54 *
55 * 0x80 = AGC Time constant 50ms Iagc = 9 uA
56 * 0x20 = AGC Take over point = 112 dBuV
57 */
58static u8 tua603x_agc112[] = { 2, 0x80|0x40|0x18|0x04|0x01, 0x80|0x20 };
59
60/* 0-9 */
61/* ------------ TUNER_TEMIC_PAL - TEMIC PAL ------------ */
62
63static struct tuner_range tuner_temic_pal_ranges[] = {
64 { 16 * 140.25 /*MHz*/, 0x8e, 0x02, },
65 { 16 * 463.25 /*MHz*/, 0x8e, 0x04, },
66 { 16 * 999.99 , 0x8e, 0x01, },
67};
68
69static struct tuner_params tuner_temic_pal_params[] = {
70 {
71 .type = TUNER_PARAM_TYPE_PAL,
72 .ranges = tuner_temic_pal_ranges,
73 .count = ARRAY_SIZE(tuner_temic_pal_ranges),
74 },
75};
76
77/* ------------ TUNER_PHILIPS_PAL_I - Philips PAL_I ------------ */
78
79static struct tuner_range tuner_philips_pal_i_ranges[] = {
80 { 16 * 140.25 /*MHz*/, 0x8e, 0xa0, },
81 { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
82 { 16 * 999.99 , 0x8e, 0x30, },
83};
84
85static struct tuner_params tuner_philips_pal_i_params[] = {
86 {
87 .type = TUNER_PARAM_TYPE_PAL,
88 .ranges = tuner_philips_pal_i_ranges,
89 .count = ARRAY_SIZE(tuner_philips_pal_i_ranges),
90 },
91};
92
93/* ------------ TUNER_PHILIPS_NTSC - Philips NTSC ------------ */
94
95static struct tuner_range tuner_philips_ntsc_ranges[] = {
96 { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
97 { 16 * 451.25 /*MHz*/, 0x8e, 0x90, },
98 { 16 * 999.99 , 0x8e, 0x30, },
99};
100
101static struct tuner_params tuner_philips_ntsc_params[] = {
102 {
103 .type = TUNER_PARAM_TYPE_NTSC,
104 .ranges = tuner_philips_ntsc_ranges,
105 .count = ARRAY_SIZE(tuner_philips_ntsc_ranges),
106 .cb_first_if_lower_freq = 1,
107 },
108};
109
110/* ------------ TUNER_PHILIPS_SECAM - Philips SECAM ------------ */
111
112static struct tuner_range tuner_philips_secam_ranges[] = {
113 { 16 * 168.25 /*MHz*/, 0x8e, 0xa7, },
114 { 16 * 447.25 /*MHz*/, 0x8e, 0x97, },
115 { 16 * 999.99 , 0x8e, 0x37, },
116};
117
118static struct tuner_params tuner_philips_secam_params[] = {
119 {
120 .type = TUNER_PARAM_TYPE_SECAM,
121 .ranges = tuner_philips_secam_ranges,
122 .count = ARRAY_SIZE(tuner_philips_secam_ranges),
123 .cb_first_if_lower_freq = 1,
124 },
125};
126
127/* ------------ TUNER_PHILIPS_PAL - Philips PAL ------------ */
128
129static struct tuner_range tuner_philips_pal_ranges[] = {
130 { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, },
131 { 16 * 447.25 /*MHz*/, 0x8e, 0x90, },
132 { 16 * 999.99 , 0x8e, 0x30, },
133};
134
135static struct tuner_params tuner_philips_pal_params[] = {
136 {
137 .type = TUNER_PARAM_TYPE_PAL,
138 .ranges = tuner_philips_pal_ranges,
139 .count = ARRAY_SIZE(tuner_philips_pal_ranges),
140 .cb_first_if_lower_freq = 1,
141 },
142};
143
144/* ------------ TUNER_TEMIC_NTSC - TEMIC NTSC ------------ */
145
146static struct tuner_range tuner_temic_ntsc_ranges[] = {
147 { 16 * 157.25 /*MHz*/, 0x8e, 0x02, },
148 { 16 * 463.25 /*MHz*/, 0x8e, 0x04, },
149 { 16 * 999.99 , 0x8e, 0x01, },
150};
151
152static struct tuner_params tuner_temic_ntsc_params[] = {
153 {
154 .type = TUNER_PARAM_TYPE_NTSC,
155 .ranges = tuner_temic_ntsc_ranges,
156 .count = ARRAY_SIZE(tuner_temic_ntsc_ranges),
157 },
158};
159
160/* ------------ TUNER_TEMIC_PAL_I - TEMIC PAL_I ------------ */
161
162static struct tuner_range tuner_temic_pal_i_ranges[] = {
163 { 16 * 170.00 /*MHz*/, 0x8e, 0x02, },
164 { 16 * 450.00 /*MHz*/, 0x8e, 0x04, },
165 { 16 * 999.99 , 0x8e, 0x01, },
166};
167
168static struct tuner_params tuner_temic_pal_i_params[] = {
169 {
170 .type = TUNER_PARAM_TYPE_PAL,
171 .ranges = tuner_temic_pal_i_ranges,
172 .count = ARRAY_SIZE(tuner_temic_pal_i_ranges),
173 },
174};
175
176/* ------------ TUNER_TEMIC_4036FY5_NTSC - TEMIC NTSC ------------ */
177
178static struct tuner_range tuner_temic_4036fy5_ntsc_ranges[] = {
179 { 16 * 157.25 /*MHz*/, 0x8e, 0xa0, },
180 { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
181 { 16 * 999.99 , 0x8e, 0x30, },
182};
183
184static struct tuner_params tuner_temic_4036fy5_ntsc_params[] = {
185 {
186 .type = TUNER_PARAM_TYPE_NTSC,
187 .ranges = tuner_temic_4036fy5_ntsc_ranges,
188 .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_ranges),
189 },
190};
191
192/* ------------ TUNER_ALPS_TSBH1_NTSC - TEMIC NTSC ------------ */
193
194static struct tuner_range tuner_alps_tsb_1_ranges[] = {
195 { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
196 { 16 * 385.25 /*MHz*/, 0x8e, 0x02, },
197 { 16 * 999.99 , 0x8e, 0x08, },
198};
199
200static struct tuner_params tuner_alps_tsbh1_ntsc_params[] = {
201 {
202 .type = TUNER_PARAM_TYPE_NTSC,
203 .ranges = tuner_alps_tsb_1_ranges,
204 .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges),
205 },
206};
207
208/* 10-19 */
209/* ------------ TUNER_ALPS_TSBE1_PAL - TEMIC PAL ------------ */
210
211static struct tuner_params tuner_alps_tsb_1_params[] = {
212 {
213 .type = TUNER_PARAM_TYPE_PAL,
214 .ranges = tuner_alps_tsb_1_ranges,
215 .count = ARRAY_SIZE(tuner_alps_tsb_1_ranges),
216 },
217};
218
219/* ------------ TUNER_ALPS_TSBB5_PAL_I - Alps PAL_I ------------ */
220
221static struct tuner_range tuner_alps_tsb_5_pal_ranges[] = {
222 { 16 * 133.25 /*MHz*/, 0x8e, 0x01, },
223 { 16 * 351.25 /*MHz*/, 0x8e, 0x02, },
224 { 16 * 999.99 , 0x8e, 0x08, },
225};
226
227static struct tuner_params tuner_alps_tsbb5_params[] = {
228 {
229 .type = TUNER_PARAM_TYPE_PAL,
230 .ranges = tuner_alps_tsb_5_pal_ranges,
231 .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
232 },
233};
234
235/* ------------ TUNER_ALPS_TSBE5_PAL - Alps PAL ------------ */
236
237static struct tuner_params tuner_alps_tsbe5_params[] = {
238 {
239 .type = TUNER_PARAM_TYPE_PAL,
240 .ranges = tuner_alps_tsb_5_pal_ranges,
241 .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
242 },
243};
244
245/* ------------ TUNER_ALPS_TSBC5_PAL - Alps PAL ------------ */
246
247static struct tuner_params tuner_alps_tsbc5_params[] = {
248 {
249 .type = TUNER_PARAM_TYPE_PAL,
250 .ranges = tuner_alps_tsb_5_pal_ranges,
251 .count = ARRAY_SIZE(tuner_alps_tsb_5_pal_ranges),
252 },
253};
254
255/* ------------ TUNER_TEMIC_4006FH5_PAL - TEMIC PAL ------------ */
256
257static struct tuner_range tuner_lg_pal_ranges[] = {
258 { 16 * 170.00 /*MHz*/, 0x8e, 0xa0, },
259 { 16 * 450.00 /*MHz*/, 0x8e, 0x90, },
260 { 16 * 999.99 , 0x8e, 0x30, },
261};
262
263static struct tuner_params tuner_temic_4006fh5_params[] = {
264 {
265 .type = TUNER_PARAM_TYPE_PAL,
266 .ranges = tuner_lg_pal_ranges,
267 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
268 },
269};
270
271/* ------------ TUNER_ALPS_TSHC6_NTSC - Alps NTSC ------------ */
272
273static struct tuner_range tuner_alps_tshc6_ntsc_ranges[] = {
274 { 16 * 137.25 /*MHz*/, 0x8e, 0x14, },
275 { 16 * 385.25 /*MHz*/, 0x8e, 0x12, },
276 { 16 * 999.99 , 0x8e, 0x11, },
277};
278
279static struct tuner_params tuner_alps_tshc6_params[] = {
280 {
281 .type = TUNER_PARAM_TYPE_NTSC,
282 .ranges = tuner_alps_tshc6_ntsc_ranges,
283 .count = ARRAY_SIZE(tuner_alps_tshc6_ntsc_ranges),
284 },
285};
286
287/* ------------ TUNER_TEMIC_PAL_DK - TEMIC PAL ------------ */
288
289static struct tuner_range tuner_temic_pal_dk_ranges[] = {
290 { 16 * 168.25 /*MHz*/, 0x8e, 0xa0, },
291 { 16 * 456.25 /*MHz*/, 0x8e, 0x90, },
292 { 16 * 999.99 , 0x8e, 0x30, },
293};
294
295static struct tuner_params tuner_temic_pal_dk_params[] = {
296 {
297 .type = TUNER_PARAM_TYPE_PAL,
298 .ranges = tuner_temic_pal_dk_ranges,
299 .count = ARRAY_SIZE(tuner_temic_pal_dk_ranges),
300 },
301};
302
303/* ------------ TUNER_PHILIPS_NTSC_M - Philips NTSC ------------ */
304
305static struct tuner_range tuner_philips_ntsc_m_ranges[] = {
306 { 16 * 160.00 /*MHz*/, 0x8e, 0xa0, },
307 { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
308 { 16 * 999.99 , 0x8e, 0x30, },
309};
310
311static struct tuner_params tuner_philips_ntsc_m_params[] = {
312 {
313 .type = TUNER_PARAM_TYPE_NTSC,
314 .ranges = tuner_philips_ntsc_m_ranges,
315 .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges),
316 },
317};
318
319/* ------------ TUNER_TEMIC_4066FY5_PAL_I - TEMIC PAL_I ------------ */
320
321static struct tuner_range tuner_temic_40x6f_5_pal_ranges[] = {
322 { 16 * 169.00 /*MHz*/, 0x8e, 0xa0, },
323 { 16 * 454.00 /*MHz*/, 0x8e, 0x90, },
324 { 16 * 999.99 , 0x8e, 0x30, },
325};
326
327static struct tuner_params tuner_temic_4066fy5_pal_i_params[] = {
328 {
329 .type = TUNER_PARAM_TYPE_PAL,
330 .ranges = tuner_temic_40x6f_5_pal_ranges,
331 .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
332 },
333};
334
335/* ------------ TUNER_TEMIC_4006FN5_MULTI_PAL - TEMIC PAL ------------ */
336
337static struct tuner_params tuner_temic_4006fn5_multi_params[] = {
338 {
339 .type = TUNER_PARAM_TYPE_PAL,
340 .ranges = tuner_temic_40x6f_5_pal_ranges,
341 .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
342 },
343};
344
345/* 20-29 */
346/* ------------ TUNER_TEMIC_4009FR5_PAL - TEMIC PAL ------------ */
347
348static struct tuner_range tuner_temic_4009f_5_pal_ranges[] = {
349 { 16 * 141.00 /*MHz*/, 0x8e, 0xa0, },
350 { 16 * 464.00 /*MHz*/, 0x8e, 0x90, },
351 { 16 * 999.99 , 0x8e, 0x30, },
352};
353
354static struct tuner_params tuner_temic_4009f_5_params[] = {
355 {
356 .type = TUNER_PARAM_TYPE_PAL,
357 .ranges = tuner_temic_4009f_5_pal_ranges,
358 .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
359 },
360};
361
362/* ------------ TUNER_TEMIC_4039FR5_NTSC - TEMIC NTSC ------------ */
363
364static struct tuner_range tuner_temic_4x3x_f_5_ntsc_ranges[] = {
365 { 16 * 158.00 /*MHz*/, 0x8e, 0xa0, },
366 { 16 * 453.00 /*MHz*/, 0x8e, 0x90, },
367 { 16 * 999.99 , 0x8e, 0x30, },
368};
369
370static struct tuner_params tuner_temic_4039fr5_params[] = {
371 {
372 .type = TUNER_PARAM_TYPE_NTSC,
373 .ranges = tuner_temic_4x3x_f_5_ntsc_ranges,
374 .count = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges),
375 },
376};
377
378/* ------------ TUNER_TEMIC_4046FM5 - TEMIC PAL ------------ */
379
380static struct tuner_params tuner_temic_4046fm5_params[] = {
381 {
382 .type = TUNER_PARAM_TYPE_PAL,
383 .ranges = tuner_temic_40x6f_5_pal_ranges,
384 .count = ARRAY_SIZE(tuner_temic_40x6f_5_pal_ranges),
385 },
386};
387
388/* ------------ TUNER_PHILIPS_PAL_DK - Philips PAL ------------ */
389
390static struct tuner_params tuner_philips_pal_dk_params[] = {
391 {
392 .type = TUNER_PARAM_TYPE_PAL,
393 .ranges = tuner_lg_pal_ranges,
394 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
395 },
396};
397
398/* ------------ TUNER_PHILIPS_FQ1216ME - Philips PAL ------------ */
399
400static struct tuner_params tuner_philips_fq1216me_params[] = {
401 {
402 .type = TUNER_PARAM_TYPE_PAL,
403 .ranges = tuner_lg_pal_ranges,
404 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
405 .has_tda9887 = 1,
406 .port1_active = 1,
407 .port2_active = 1,
408 .port2_invert_for_secam_lc = 1,
409 },
410};
411
412/* ------------ TUNER_LG_PAL_I_FM - LGINNOTEK PAL_I ------------ */
413
414static struct tuner_params tuner_lg_pal_i_fm_params[] = {
415 {
416 .type = TUNER_PARAM_TYPE_PAL,
417 .ranges = tuner_lg_pal_ranges,
418 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
419 },
420};
421
422/* ------------ TUNER_LG_PAL_I - LGINNOTEK PAL_I ------------ */
423
424static struct tuner_params tuner_lg_pal_i_params[] = {
425 {
426 .type = TUNER_PARAM_TYPE_PAL,
427 .ranges = tuner_lg_pal_ranges,
428 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
429 },
430};
431
432/* ------------ TUNER_LG_NTSC_FM - LGINNOTEK NTSC ------------ */
433
434static struct tuner_range tuner_lg_ntsc_fm_ranges[] = {
435 { 16 * 210.00 /*MHz*/, 0x8e, 0xa0, },
436 { 16 * 497.00 /*MHz*/, 0x8e, 0x90, },
437 { 16 * 999.99 , 0x8e, 0x30, },
438};
439
440static struct tuner_params tuner_lg_ntsc_fm_params[] = {
441 {
442 .type = TUNER_PARAM_TYPE_NTSC,
443 .ranges = tuner_lg_ntsc_fm_ranges,
444 .count = ARRAY_SIZE(tuner_lg_ntsc_fm_ranges),
445 },
446};
447
448/* ------------ TUNER_LG_PAL_FM - LGINNOTEK PAL ------------ */
449
450static struct tuner_params tuner_lg_pal_fm_params[] = {
451 {
452 .type = TUNER_PARAM_TYPE_PAL,
453 .ranges = tuner_lg_pal_ranges,
454 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
455 },
456};
457
458/* ------------ TUNER_LG_PAL - LGINNOTEK PAL ------------ */
459
460static struct tuner_params tuner_lg_pal_params[] = {
461 {
462 .type = TUNER_PARAM_TYPE_PAL,
463 .ranges = tuner_lg_pal_ranges,
464 .count = ARRAY_SIZE(tuner_lg_pal_ranges),
465 },
466};
467
468/* 30-39 */
469/* ------------ TUNER_TEMIC_4009FN5_MULTI_PAL_FM - TEMIC PAL ------------ */
470
471static struct tuner_params tuner_temic_4009_fn5_multi_pal_fm_params[] = {
472 {
473 .type = TUNER_PARAM_TYPE_PAL,
474 .ranges = tuner_temic_4009f_5_pal_ranges,
475 .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
476 },
477};
478
479/* ------------ TUNER_SHARP_2U5JF5540_NTSC - SHARP NTSC ------------ */
480
481static struct tuner_range tuner_sharp_2u5jf5540_ntsc_ranges[] = {
482 { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
483 { 16 * 317.25 /*MHz*/, 0x8e, 0x02, },
484 { 16 * 999.99 , 0x8e, 0x08, },
485};
486
487static struct tuner_params tuner_sharp_2u5jf5540_params[] = {
488 {
489 .type = TUNER_PARAM_TYPE_NTSC,
490 .ranges = tuner_sharp_2u5jf5540_ntsc_ranges,
491 .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_ntsc_ranges),
492 },
493};
494
495/* ------------ TUNER_Samsung_PAL_TCPM9091PD27 - Samsung PAL ------------ */
496
497static struct tuner_range tuner_samsung_pal_tcpm9091pd27_ranges[] = {
498 { 16 * 169 /*MHz*/, 0x8e, 0xa0, },
499 { 16 * 464 /*MHz*/, 0x8e, 0x90, },
500 { 16 * 999.99 , 0x8e, 0x30, },
501};
502
503static struct tuner_params tuner_samsung_pal_tcpm9091pd27_params[] = {
504 {
505 .type = TUNER_PARAM_TYPE_PAL,
506 .ranges = tuner_samsung_pal_tcpm9091pd27_ranges,
507 .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_ranges),
508 },
509};
510
511/* ------------ TUNER_TEMIC_4106FH5 - TEMIC PAL ------------ */
512
513static struct tuner_params tuner_temic_4106fh5_params[] = {
514 {
515 .type = TUNER_PARAM_TYPE_PAL,
516 .ranges = tuner_temic_4009f_5_pal_ranges,
517 .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
518 },
519};
520
521/* ------------ TUNER_TEMIC_4012FY5 - TEMIC PAL ------------ */
522
523static struct tuner_params tuner_temic_4012fy5_params[] = {
524 {
525 .type = TUNER_PARAM_TYPE_PAL,
526 .ranges = tuner_temic_pal_ranges,
527 .count = ARRAY_SIZE(tuner_temic_pal_ranges),
528 },
529};
530
531/* ------------ TUNER_TEMIC_4136FY5 - TEMIC NTSC ------------ */
532
533static struct tuner_params tuner_temic_4136_fy5_params[] = {
534 {
535 .type = TUNER_PARAM_TYPE_NTSC,
536 .ranges = tuner_temic_4x3x_f_5_ntsc_ranges,
537 .count = ARRAY_SIZE(tuner_temic_4x3x_f_5_ntsc_ranges),
538 },
539};
540
541/* ------------ TUNER_LG_PAL_NEW_TAPC - LGINNOTEK PAL ------------ */
542
543static struct tuner_range tuner_lg_new_tapc_ranges[] = {
544 { 16 * 170.00 /*MHz*/, 0x8e, 0x01, },
545 { 16 * 450.00 /*MHz*/, 0x8e, 0x02, },
546 { 16 * 999.99 , 0x8e, 0x08, },
547};
548
549static struct tuner_params tuner_lg_pal_new_tapc_params[] = {
550 {
551 .type = TUNER_PARAM_TYPE_PAL,
552 .ranges = tuner_lg_new_tapc_ranges,
553 .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
554 },
555};
556
557/* ------------ TUNER_PHILIPS_FM1216ME_MK3 - Philips PAL ------------ */
558
559static struct tuner_range tuner_fm1216me_mk3_pal_ranges[] = {
560 { 16 * 158.00 /*MHz*/, 0x8e, 0x01, },
561 { 16 * 442.00 /*MHz*/, 0x8e, 0x02, },
562 { 16 * 999.99 , 0x8e, 0x04, },
563};
564
565static struct tuner_params tuner_fm1216me_mk3_params[] = {
566 {
567 .type = TUNER_PARAM_TYPE_PAL,
568 .ranges = tuner_fm1216me_mk3_pal_ranges,
569 .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
570 .cb_first_if_lower_freq = 1,
571 .has_tda9887 = 1,
572 .port1_active = 1,
573 .port2_active = 1,
574 .port2_invert_for_secam_lc = 1,
575 .port1_fm_high_sensitivity = 1,
576 .default_top_mid = -2,
577 .default_top_secam_mid = -2,
578 .default_top_secam_high = -2,
579 },
580};
581
582/* ------------ TUNER_PHILIPS_FM1216MK5 - Philips PAL ------------ */
583
584static struct tuner_range tuner_fm1216mk5_pal_ranges[] = {
585 { 16 * 158.00 /*MHz*/, 0xce, 0x01, },
586 { 16 * 441.00 /*MHz*/, 0xce, 0x02, },
587 { 16 * 864.00 , 0xce, 0x04, },
588};
589
590static struct tuner_params tuner_fm1216mk5_params[] = {
591 {
592 .type = TUNER_PARAM_TYPE_PAL,
593 .ranges = tuner_fm1216mk5_pal_ranges,
594 .count = ARRAY_SIZE(tuner_fm1216mk5_pal_ranges),
595 .cb_first_if_lower_freq = 1,
596 .has_tda9887 = 1,
597 .port1_active = 1,
598 .port2_active = 1,
599 .port2_invert_for_secam_lc = 1,
600 .port1_fm_high_sensitivity = 1,
601 .default_top_mid = -2,
602 .default_top_secam_mid = -2,
603 .default_top_secam_high = -2,
604 },
605};
606
607/* ------------ TUNER_LG_NTSC_NEW_TAPC - LGINNOTEK NTSC ------------ */
608
609static struct tuner_params tuner_lg_ntsc_new_tapc_params[] = {
610 {
611 .type = TUNER_PARAM_TYPE_NTSC,
612 .ranges = tuner_lg_new_tapc_ranges,
613 .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
614 },
615};
616
617/* 40-49 */
618/* ------------ TUNER_HITACHI_NTSC - HITACHI NTSC ------------ */
619
620static struct tuner_params tuner_hitachi_ntsc_params[] = {
621 {
622 .type = TUNER_PARAM_TYPE_NTSC,
623 .ranges = tuner_lg_new_tapc_ranges,
624 .count = ARRAY_SIZE(tuner_lg_new_tapc_ranges),
625 },
626};
627
628/* ------------ TUNER_PHILIPS_PAL_MK - Philips PAL ------------ */
629
630static struct tuner_range tuner_philips_pal_mk_pal_ranges[] = {
631 { 16 * 140.25 /*MHz*/, 0x8e, 0x01, },
632 { 16 * 463.25 /*MHz*/, 0x8e, 0xc2, },
633 { 16 * 999.99 , 0x8e, 0xcf, },
634};
635
636static struct tuner_params tuner_philips_pal_mk_params[] = {
637 {
638 .type = TUNER_PARAM_TYPE_PAL,
639 .ranges = tuner_philips_pal_mk_pal_ranges,
640 .count = ARRAY_SIZE(tuner_philips_pal_mk_pal_ranges),
641 },
642};
643
644/* ---- TUNER_PHILIPS_FCV1236D - Philips FCV1236D (ATSC/NTSC) ---- */
645
646static struct tuner_range tuner_philips_fcv1236d_ntsc_ranges[] = {
647 { 16 * 157.25 /*MHz*/, 0x8e, 0xa2, },
648 { 16 * 451.25 /*MHz*/, 0x8e, 0x92, },
649 { 16 * 999.99 , 0x8e, 0x32, },
650};
651
652static struct tuner_range tuner_philips_fcv1236d_atsc_ranges[] = {
653 { 16 * 159.00 /*MHz*/, 0x8e, 0xa0, },
654 { 16 * 453.00 /*MHz*/, 0x8e, 0x90, },
655 { 16 * 999.99 , 0x8e, 0x30, },
656};
657
658static struct tuner_params tuner_philips_fcv1236d_params[] = {
659 {
660 .type = TUNER_PARAM_TYPE_NTSC,
661 .ranges = tuner_philips_fcv1236d_ntsc_ranges,
662 .count = ARRAY_SIZE(tuner_philips_fcv1236d_ntsc_ranges),
663 },
664 {
665 .type = TUNER_PARAM_TYPE_DIGITAL,
666 .ranges = tuner_philips_fcv1236d_atsc_ranges,
667 .count = ARRAY_SIZE(tuner_philips_fcv1236d_atsc_ranges),
668 .iffreq = 16 * 44.00,
669 },
670};
671
672/* ------------ TUNER_PHILIPS_FM1236_MK3 - Philips NTSC ------------ */
673
674static struct tuner_range tuner_fm1236_mk3_ntsc_ranges[] = {
675 { 16 * 160.00 /*MHz*/, 0x8e, 0x01, },
676 { 16 * 442.00 /*MHz*/, 0x8e, 0x02, },
677 { 16 * 999.99 , 0x8e, 0x04, },
678};
679
680static struct tuner_params tuner_fm1236_mk3_params[] = {
681 {
682 .type = TUNER_PARAM_TYPE_NTSC,
683 .ranges = tuner_fm1236_mk3_ntsc_ranges,
684 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
685 .cb_first_if_lower_freq = 1,
686 .has_tda9887 = 1,
687 .port1_active = 1,
688 .port2_active = 1,
689 .port1_fm_high_sensitivity = 1,
690 },
691};
692
693/* ------------ TUNER_PHILIPS_4IN1 - Philips NTSC ------------ */
694
695static struct tuner_params tuner_philips_4in1_params[] = {
696 {
697 .type = TUNER_PARAM_TYPE_NTSC,
698 .ranges = tuner_fm1236_mk3_ntsc_ranges,
699 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
700 },
701};
702
703/* ------------ TUNER_MICROTUNE_4049FM5 - Microtune PAL ------------ */
704
705static struct tuner_params tuner_microtune_4049_fm5_params[] = {
706 {
707 .type = TUNER_PARAM_TYPE_PAL,
708 .ranges = tuner_temic_4009f_5_pal_ranges,
709 .count = ARRAY_SIZE(tuner_temic_4009f_5_pal_ranges),
710 .has_tda9887 = 1,
711 .port1_invert_for_secam_lc = 1,
712 .default_pll_gating_18 = 1,
713 .fm_gain_normal=1,
714 .radio_if = 1, /* 33.3 MHz */
715 },
716};
717
718/* ------------ TUNER_PANASONIC_VP27 - Panasonic NTSC ------------ */
719
720static struct tuner_range tuner_panasonic_vp27_ntsc_ranges[] = {
721 { 16 * 160.00 /*MHz*/, 0xce, 0x01, },
722 { 16 * 454.00 /*MHz*/, 0xce, 0x02, },
723 { 16 * 999.99 , 0xce, 0x08, },
724};
725
726static struct tuner_params tuner_panasonic_vp27_params[] = {
727 {
728 .type = TUNER_PARAM_TYPE_NTSC,
729 .ranges = tuner_panasonic_vp27_ntsc_ranges,
730 .count = ARRAY_SIZE(tuner_panasonic_vp27_ntsc_ranges),
731 .has_tda9887 = 1,
732 .intercarrier_mode = 1,
733 .default_top_low = -3,
734 .default_top_mid = -3,
735 .default_top_high = -3,
736 },
737};
738
739/* ------------ TUNER_TNF_8831BGFF - Philips PAL ------------ */
740
741static struct tuner_range tuner_tnf_8831bgff_pal_ranges[] = {
742 { 16 * 161.25 /*MHz*/, 0x8e, 0xa0, },
743 { 16 * 463.25 /*MHz*/, 0x8e, 0x90, },
744 { 16 * 999.99 , 0x8e, 0x30, },
745};
746
747static struct tuner_params tuner_tnf_8831bgff_params[] = {
748 {
749 .type = TUNER_PARAM_TYPE_PAL,
750 .ranges = tuner_tnf_8831bgff_pal_ranges,
751 .count = ARRAY_SIZE(tuner_tnf_8831bgff_pal_ranges),
752 },
753};
754
755/* ------------ TUNER_MICROTUNE_4042FI5 - Microtune NTSC ------------ */
756
757static struct tuner_range tuner_microtune_4042fi5_ntsc_ranges[] = {
758 { 16 * 162.00 /*MHz*/, 0x8e, 0xa2, },
759 { 16 * 457.00 /*MHz*/, 0x8e, 0x94, },
760 { 16 * 999.99 , 0x8e, 0x31, },
761};
762
763static struct tuner_range tuner_microtune_4042fi5_atsc_ranges[] = {
764 { 16 * 162.00 /*MHz*/, 0x8e, 0xa1, },
765 { 16 * 457.00 /*MHz*/, 0x8e, 0x91, },
766 { 16 * 999.99 , 0x8e, 0x31, },
767};
768
769static struct tuner_params tuner_microtune_4042fi5_params[] = {
770 {
771 .type = TUNER_PARAM_TYPE_NTSC,
772 .ranges = tuner_microtune_4042fi5_ntsc_ranges,
773 .count = ARRAY_SIZE(tuner_microtune_4042fi5_ntsc_ranges),
774 },
775 {
776 .type = TUNER_PARAM_TYPE_DIGITAL,
777 .ranges = tuner_microtune_4042fi5_atsc_ranges,
778 .count = ARRAY_SIZE(tuner_microtune_4042fi5_atsc_ranges),
779 .iffreq = 16 * 44.00 /*MHz*/,
780 },
781};
782
783/* 50-59 */
784/* ------------ TUNER_TCL_2002N - TCL NTSC ------------ */
785
786static struct tuner_range tuner_tcl_2002n_ntsc_ranges[] = {
787 { 16 * 172.00 /*MHz*/, 0x8e, 0x01, },
788 { 16 * 448.00 /*MHz*/, 0x8e, 0x02, },
789 { 16 * 999.99 , 0x8e, 0x08, },
790};
791
792static struct tuner_params tuner_tcl_2002n_params[] = {
793 {
794 .type = TUNER_PARAM_TYPE_NTSC,
795 .ranges = tuner_tcl_2002n_ntsc_ranges,
796 .count = ARRAY_SIZE(tuner_tcl_2002n_ntsc_ranges),
797 .cb_first_if_lower_freq = 1,
798 },
799};
800
801/* ------------ TUNER_PHILIPS_FM1256_IH3 - Philips PAL ------------ */
802
803static struct tuner_params tuner_philips_fm1256_ih3_params[] = {
804 {
805 .type = TUNER_PARAM_TYPE_PAL,
806 .ranges = tuner_fm1236_mk3_ntsc_ranges,
807 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
808 .radio_if = 1, /* 33.3 MHz */
809 },
810};
811
812/* ------------ TUNER_THOMSON_DTT7610 - THOMSON ATSC ------------ */
813
814/* single range used for both ntsc and atsc */
815static struct tuner_range tuner_thomson_dtt7610_ntsc_ranges[] = {
816 { 16 * 157.25 /*MHz*/, 0x8e, 0x39, },
817 { 16 * 454.00 /*MHz*/, 0x8e, 0x3a, },
818 { 16 * 999.99 , 0x8e, 0x3c, },
819};
820
821static struct tuner_params tuner_thomson_dtt7610_params[] = {
822 {
823 .type = TUNER_PARAM_TYPE_NTSC,
824 .ranges = tuner_thomson_dtt7610_ntsc_ranges,
825 .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges),
826 },
827 {
828 .type = TUNER_PARAM_TYPE_DIGITAL,
829 .ranges = tuner_thomson_dtt7610_ntsc_ranges,
830 .count = ARRAY_SIZE(tuner_thomson_dtt7610_ntsc_ranges),
831 .iffreq = 16 * 44.00 /*MHz*/,
832 },
833};
834
835/* ------------ TUNER_PHILIPS_FQ1286 - Philips NTSC ------------ */
836
837static struct tuner_range tuner_philips_fq1286_ntsc_ranges[] = {
838 { 16 * 160.00 /*MHz*/, 0x8e, 0x41, },
839 { 16 * 454.00 /*MHz*/, 0x8e, 0x42, },
840 { 16 * 999.99 , 0x8e, 0x04, },
841};
842
843static struct tuner_params tuner_philips_fq1286_params[] = {
844 {
845 .type = TUNER_PARAM_TYPE_NTSC,
846 .ranges = tuner_philips_fq1286_ntsc_ranges,
847 .count = ARRAY_SIZE(tuner_philips_fq1286_ntsc_ranges),
848 },
849};
850
851/* ------------ TUNER_TCL_2002MB - TCL PAL ------------ */
852
853static struct tuner_range tuner_tcl_2002mb_pal_ranges[] = {
854 { 16 * 170.00 /*MHz*/, 0xce, 0x01, },
855 { 16 * 450.00 /*MHz*/, 0xce, 0x02, },
856 { 16 * 999.99 , 0xce, 0x08, },
857};
858
859static struct tuner_params tuner_tcl_2002mb_params[] = {
860 {
861 .type = TUNER_PARAM_TYPE_PAL,
862 .ranges = tuner_tcl_2002mb_pal_ranges,
863 .count = ARRAY_SIZE(tuner_tcl_2002mb_pal_ranges),
864 },
865};
866
867/* ------------ TUNER_PHILIPS_FQ1216AME_MK4 - Philips PAL ------------ */
868
869static struct tuner_range tuner_philips_fq12_6a___mk4_pal_ranges[] = {
870 { 16 * 160.00 /*MHz*/, 0xce, 0x01, },
871 { 16 * 442.00 /*MHz*/, 0xce, 0x02, },
872 { 16 * 999.99 , 0xce, 0x04, },
873};
874
875static struct tuner_params tuner_philips_fq1216ame_mk4_params[] = {
876 {
877 .type = TUNER_PARAM_TYPE_PAL,
878 .ranges = tuner_philips_fq12_6a___mk4_pal_ranges,
879 .count = ARRAY_SIZE(tuner_philips_fq12_6a___mk4_pal_ranges),
880 .has_tda9887 = 1,
881 .port1_active = 1,
882 .port2_invert_for_secam_lc = 1,
883 .default_top_mid = -2,
884 .default_top_secam_low = -2,
885 .default_top_secam_mid = -2,
886 .default_top_secam_high = -2,
887 },
888};
889
890/* ------------ TUNER_PHILIPS_FQ1236A_MK4 - Philips NTSC ------------ */
891
892static struct tuner_params tuner_philips_fq1236a_mk4_params[] = {
893 {
894 .type = TUNER_PARAM_TYPE_NTSC,
895 .ranges = tuner_fm1236_mk3_ntsc_ranges,
896 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
897 },
898};
899
900/* ------------ TUNER_YMEC_TVF_8531MF - Philips NTSC ------------ */
901
902static struct tuner_params tuner_ymec_tvf_8531mf_params[] = {
903 {
904 .type = TUNER_PARAM_TYPE_NTSC,
905 .ranges = tuner_philips_ntsc_m_ranges,
906 .count = ARRAY_SIZE(tuner_philips_ntsc_m_ranges),
907 },
908};
909
910/* ------------ TUNER_YMEC_TVF_5533MF - Philips NTSC ------------ */
911
912static struct tuner_range tuner_ymec_tvf_5533mf_ntsc_ranges[] = {
913 { 16 * 160.00 /*MHz*/, 0x8e, 0x01, },
914 { 16 * 454.00 /*MHz*/, 0x8e, 0x02, },
915 { 16 * 999.99 , 0x8e, 0x04, },
916};
917
918static struct tuner_params tuner_ymec_tvf_5533mf_params[] = {
919 {
920 .type = TUNER_PARAM_TYPE_NTSC,
921 .ranges = tuner_ymec_tvf_5533mf_ntsc_ranges,
922 .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_ntsc_ranges),
923 },
924};
925
926/* 60-69 */
927/* ------------ TUNER_THOMSON_DTT761X - THOMSON ATSC ------------ */
928/* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
929
930static struct tuner_range tuner_thomson_dtt761x_ntsc_ranges[] = {
931 { 16 * 145.25 /*MHz*/, 0x8e, 0x39, },
932 { 16 * 415.25 /*MHz*/, 0x8e, 0x3a, },
933 { 16 * 999.99 , 0x8e, 0x3c, },
934};
935
936static struct tuner_range tuner_thomson_dtt761x_atsc_ranges[] = {
937 { 16 * 147.00 /*MHz*/, 0x8e, 0x39, },
938 { 16 * 417.00 /*MHz*/, 0x8e, 0x3a, },
939 { 16 * 999.99 , 0x8e, 0x3c, },
940};
941
942static struct tuner_params tuner_thomson_dtt761x_params[] = {
943 {
944 .type = TUNER_PARAM_TYPE_NTSC,
945 .ranges = tuner_thomson_dtt761x_ntsc_ranges,
946 .count = ARRAY_SIZE(tuner_thomson_dtt761x_ntsc_ranges),
947 .has_tda9887 = 1,
948 .fm_gain_normal = 1,
949 .radio_if = 2, /* 41.3 MHz */
950 },
951 {
952 .type = TUNER_PARAM_TYPE_DIGITAL,
953 .ranges = tuner_thomson_dtt761x_atsc_ranges,
954 .count = ARRAY_SIZE(tuner_thomson_dtt761x_atsc_ranges),
955 .iffreq = 16 * 44.00, /*MHz*/
956 },
957};
958
959/* ------------ TUNER_TENA_9533_DI - Philips PAL ------------ */
960
961static struct tuner_range tuner_tena_9533_di_pal_ranges[] = {
962 { 16 * 160.25 /*MHz*/, 0x8e, 0x01, },
963 { 16 * 464.25 /*MHz*/, 0x8e, 0x02, },
964 { 16 * 999.99 , 0x8e, 0x04, },
965};
966
967static struct tuner_params tuner_tena_9533_di_params[] = {
968 {
969 .type = TUNER_PARAM_TYPE_PAL,
970 .ranges = tuner_tena_9533_di_pal_ranges,
971 .count = ARRAY_SIZE(tuner_tena_9533_di_pal_ranges),
972 },
973};
974
975/* ------------ TUNER_TENA_TNF_5337 - Tena tnf5337MFD STD M/N ------------ */
976
977static struct tuner_range tuner_tena_tnf_5337_ntsc_ranges[] = {
978 { 16 * 166.25 /*MHz*/, 0x86, 0x01, },
979 { 16 * 466.25 /*MHz*/, 0x86, 0x02, },
980 { 16 * 999.99 , 0x86, 0x08, },
981};
982
983static struct tuner_params tuner_tena_tnf_5337_params[] = {
984 {
985 .type = TUNER_PARAM_TYPE_NTSC,
986 .ranges = tuner_tena_tnf_5337_ntsc_ranges,
987 .count = ARRAY_SIZE(tuner_tena_tnf_5337_ntsc_ranges),
988 },
989};
990
991/* ------------ TUNER_PHILIPS_FMD1216ME(X)_MK3 - Philips PAL ------------ */
992
993static struct tuner_range tuner_philips_fmd1216me_mk3_pal_ranges[] = {
994 { 16 * 160.00 /*MHz*/, 0x86, 0x51, },
995 { 16 * 442.00 /*MHz*/, 0x86, 0x52, },
996 { 16 * 999.99 , 0x86, 0x54, },
997};
998
999static struct tuner_range tuner_philips_fmd1216me_mk3_dvb_ranges[] = {
1000 { 16 * 143.87 /*MHz*/, 0xbc, 0x41 },
1001 { 16 * 158.87 /*MHz*/, 0xf4, 0x41 },
1002 { 16 * 329.87 /*MHz*/, 0xbc, 0x42 },
1003 { 16 * 441.87 /*MHz*/, 0xf4, 0x42 },
1004 { 16 * 625.87 /*MHz*/, 0xbc, 0x44 },
1005 { 16 * 803.87 /*MHz*/, 0xf4, 0x44 },
1006 { 16 * 999.99 , 0xfc, 0x44 },
1007};
1008
1009static struct tuner_params tuner_philips_fmd1216me_mk3_params[] = {
1010 {
1011 .type = TUNER_PARAM_TYPE_PAL,
1012 .ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
1013 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
1014 .has_tda9887 = 1,
1015 .port1_active = 1,
1016 .port2_active = 1,
1017 .port2_fm_high_sensitivity = 1,
1018 .port2_invert_for_secam_lc = 1,
1019 .port1_set_for_fm_mono = 1,
1020 },
1021 {
1022 .type = TUNER_PARAM_TYPE_DIGITAL,
1023 .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges,
1024 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges),
1025 .iffreq = 16 * 36.125, /*MHz*/
1026 },
1027};
1028
1029static struct tuner_params tuner_philips_fmd1216mex_mk3_params[] = {
1030 {
1031 .type = TUNER_PARAM_TYPE_PAL,
1032 .ranges = tuner_philips_fmd1216me_mk3_pal_ranges,
1033 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_pal_ranges),
1034 .has_tda9887 = 1,
1035 .port1_active = 1,
1036 .port2_active = 1,
1037 .port2_fm_high_sensitivity = 1,
1038 .port2_invert_for_secam_lc = 1,
1039 .port1_set_for_fm_mono = 1,
1040 .radio_if = 1,
1041 .fm_gain_normal = 1,
1042 },
1043 {
1044 .type = TUNER_PARAM_TYPE_DIGITAL,
1045 .ranges = tuner_philips_fmd1216me_mk3_dvb_ranges,
1046 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_dvb_ranges),
1047 .iffreq = 16 * 36.125, /*MHz*/
1048 },
1049};
1050
1051/* ------ TUNER_LG_TDVS_H06XF - LG INNOTEK / INFINEON ATSC ----- */
1052
1053static struct tuner_range tuner_tua6034_ntsc_ranges[] = {
1054 { 16 * 165.00 /*MHz*/, 0x8e, 0x01 },
1055 { 16 * 450.00 /*MHz*/, 0x8e, 0x02 },
1056 { 16 * 999.99 , 0x8e, 0x04 },
1057};
1058
1059static struct tuner_range tuner_tua6034_atsc_ranges[] = {
1060 { 16 * 165.00 /*MHz*/, 0xce, 0x01 },
1061 { 16 * 450.00 /*MHz*/, 0xce, 0x02 },
1062 { 16 * 999.99 , 0xce, 0x04 },
1063};
1064
1065static struct tuner_params tuner_lg_tdvs_h06xf_params[] = {
1066 {
1067 .type = TUNER_PARAM_TYPE_NTSC,
1068 .ranges = tuner_tua6034_ntsc_ranges,
1069 .count = ARRAY_SIZE(tuner_tua6034_ntsc_ranges),
1070 },
1071 {
1072 .type = TUNER_PARAM_TYPE_DIGITAL,
1073 .ranges = tuner_tua6034_atsc_ranges,
1074 .count = ARRAY_SIZE(tuner_tua6034_atsc_ranges),
1075 .iffreq = 16 * 44.00,
1076 },
1077};
1078
1079/* ------------ TUNER_YMEC_TVF66T5_B_DFF - Philips PAL ------------ */
1080
1081static struct tuner_range tuner_ymec_tvf66t5_b_dff_pal_ranges[] = {
1082 { 16 * 160.25 /*MHz*/, 0x8e, 0x01, },
1083 { 16 * 464.25 /*MHz*/, 0x8e, 0x02, },
1084 { 16 * 999.99 , 0x8e, 0x08, },
1085};
1086
1087static struct tuner_params tuner_ymec_tvf66t5_b_dff_params[] = {
1088 {
1089 .type = TUNER_PARAM_TYPE_PAL,
1090 .ranges = tuner_ymec_tvf66t5_b_dff_pal_ranges,
1091 .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_pal_ranges),
1092 },
1093};
1094
1095/* ------------ TUNER_LG_NTSC_TALN_MINI - LGINNOTEK NTSC ------------ */
1096
1097static struct tuner_range tuner_lg_taln_ntsc_ranges[] = {
1098 { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
1099 { 16 * 373.25 /*MHz*/, 0x8e, 0x02, },
1100 { 16 * 999.99 , 0x8e, 0x08, },
1101};
1102
1103static struct tuner_range tuner_lg_taln_pal_secam_ranges[] = {
1104 { 16 * 150.00 /*MHz*/, 0x8e, 0x01, },
1105 { 16 * 425.00 /*MHz*/, 0x8e, 0x02, },
1106 { 16 * 999.99 , 0x8e, 0x08, },
1107};
1108
1109static struct tuner_params tuner_lg_taln_params[] = {
1110 {
1111 .type = TUNER_PARAM_TYPE_NTSC,
1112 .ranges = tuner_lg_taln_ntsc_ranges,
1113 .count = ARRAY_SIZE(tuner_lg_taln_ntsc_ranges),
1114 },{
1115 .type = TUNER_PARAM_TYPE_PAL,
1116 .ranges = tuner_lg_taln_pal_secam_ranges,
1117 .count = ARRAY_SIZE(tuner_lg_taln_pal_secam_ranges),
1118 },
1119};
1120
1121/* ------------ TUNER_PHILIPS_TD1316 - Philips PAL ------------ */
1122
1123static struct tuner_range tuner_philips_td1316_pal_ranges[] = {
1124 { 16 * 160.00 /*MHz*/, 0xc8, 0xa1, },
1125 { 16 * 442.00 /*MHz*/, 0xc8, 0xa2, },
1126 { 16 * 999.99 , 0xc8, 0xa4, },
1127};
1128
1129static struct tuner_range tuner_philips_td1316_dvb_ranges[] = {
1130 { 16 * 93.834 /*MHz*/, 0xca, 0x60, },
1131 { 16 * 123.834 /*MHz*/, 0xca, 0xa0, },
1132 { 16 * 163.834 /*MHz*/, 0xca, 0xc0, },
1133 { 16 * 253.834 /*MHz*/, 0xca, 0x60, },
1134 { 16 * 383.834 /*MHz*/, 0xca, 0xa0, },
1135 { 16 * 443.834 /*MHz*/, 0xca, 0xc0, },
1136 { 16 * 583.834 /*MHz*/, 0xca, 0x60, },
1137 { 16 * 793.834 /*MHz*/, 0xca, 0xa0, },
1138 { 16 * 999.999 , 0xca, 0xe0, },
1139};
1140
1141static struct tuner_params tuner_philips_td1316_params[] = {
1142 {
1143 .type = TUNER_PARAM_TYPE_PAL,
1144 .ranges = tuner_philips_td1316_pal_ranges,
1145 .count = ARRAY_SIZE(tuner_philips_td1316_pal_ranges),
1146 },
1147 {
1148 .type = TUNER_PARAM_TYPE_DIGITAL,
1149 .ranges = tuner_philips_td1316_dvb_ranges,
1150 .count = ARRAY_SIZE(tuner_philips_td1316_dvb_ranges),
1151 .iffreq = 16 * 36.166667 /*MHz*/,
1152 },
1153};
1154
1155/* ------------ TUNER_PHILIPS_TUV1236D - Philips ATSC ------------ */
1156
1157static struct tuner_range tuner_tuv1236d_ntsc_ranges[] = {
1158 { 16 * 157.25 /*MHz*/, 0xce, 0x01, },
1159 { 16 * 454.00 /*MHz*/, 0xce, 0x02, },
1160 { 16 * 999.99 , 0xce, 0x04, },
1161};
1162
1163static struct tuner_range tuner_tuv1236d_atsc_ranges[] = {
1164 { 16 * 157.25 /*MHz*/, 0xc6, 0x41, },
1165 { 16 * 454.00 /*MHz*/, 0xc6, 0x42, },
1166 { 16 * 999.99 , 0xc6, 0x44, },
1167};
1168
1169static struct tuner_params tuner_tuv1236d_params[] = {
1170 {
1171 .type = TUNER_PARAM_TYPE_NTSC,
1172 .ranges = tuner_tuv1236d_ntsc_ranges,
1173 .count = ARRAY_SIZE(tuner_tuv1236d_ntsc_ranges),
1174 },
1175 {
1176 .type = TUNER_PARAM_TYPE_DIGITAL,
1177 .ranges = tuner_tuv1236d_atsc_ranges,
1178 .count = ARRAY_SIZE(tuner_tuv1236d_atsc_ranges),
1179 .iffreq = 16 * 44.00,
1180 },
1181};
1182
1183/* ------------ TUNER_TNF_xxx5 - Texas Instruments--------- */
1184/* This is known to work with Tenna TVF58t5-MFF and TVF5835 MFF
1185 * but it is expected to work also with other Tenna/Ymec
1186 * models based on TI SN 761677 chip on both PAL and NTSC
1187 */
1188
1189static struct tuner_range tuner_tnf_5335_d_if_pal_ranges[] = {
1190 { 16 * 168.25 /*MHz*/, 0x8e, 0x01, },
1191 { 16 * 471.25 /*MHz*/, 0x8e, 0x02, },
1192 { 16 * 999.99 , 0x8e, 0x08, },
1193};
1194
1195static struct tuner_range tuner_tnf_5335mf_ntsc_ranges[] = {
1196 { 16 * 169.25 /*MHz*/, 0x8e, 0x01, },
1197 { 16 * 469.25 /*MHz*/, 0x8e, 0x02, },
1198 { 16 * 999.99 , 0x8e, 0x08, },
1199};
1200
1201static struct tuner_params tuner_tnf_5335mf_params[] = {
1202 {
1203 .type = TUNER_PARAM_TYPE_NTSC,
1204 .ranges = tuner_tnf_5335mf_ntsc_ranges,
1205 .count = ARRAY_SIZE(tuner_tnf_5335mf_ntsc_ranges),
1206 },
1207 {
1208 .type = TUNER_PARAM_TYPE_PAL,
1209 .ranges = tuner_tnf_5335_d_if_pal_ranges,
1210 .count = ARRAY_SIZE(tuner_tnf_5335_d_if_pal_ranges),
1211 },
1212};
1213
1214/* 70-79 */
1215/* ------------ TUNER_SAMSUNG_TCPN_2121P30A - Samsung NTSC ------------ */
1216
1217/* '+ 4' turns on the Low Noise Amplifier */
1218static struct tuner_range tuner_samsung_tcpn_2121p30a_ntsc_ranges[] = {
1219 { 16 * 130.00 /*MHz*/, 0xce, 0x01 + 4, },
1220 { 16 * 364.50 /*MHz*/, 0xce, 0x02 + 4, },
1221 { 16 * 999.99 , 0xce, 0x08 + 4, },
1222};
1223
1224static struct tuner_params tuner_samsung_tcpn_2121p30a_params[] = {
1225 {
1226 .type = TUNER_PARAM_TYPE_NTSC,
1227 .ranges = tuner_samsung_tcpn_2121p30a_ntsc_ranges,
1228 .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_ntsc_ranges),
1229 },
1230};
1231
1232/* ------------ TUNER_THOMSON_FE6600 - DViCO Hybrid PAL ------------ */
1233
1234static struct tuner_range tuner_thomson_fe6600_pal_ranges[] = {
1235 { 16 * 160.00 /*MHz*/, 0xfe, 0x11, },
1236 { 16 * 442.00 /*MHz*/, 0xf6, 0x12, },
1237 { 16 * 999.99 , 0xf6, 0x18, },
1238};
1239
1240static struct tuner_range tuner_thomson_fe6600_dvb_ranges[] = {
1241 { 16 * 250.00 /*MHz*/, 0xb4, 0x12, },
1242 { 16 * 455.00 /*MHz*/, 0xfe, 0x11, },
1243 { 16 * 775.50 /*MHz*/, 0xbc, 0x18, },
1244 { 16 * 999.99 , 0xf4, 0x18, },
1245};
1246
1247static struct tuner_params tuner_thomson_fe6600_params[] = {
1248 {
1249 .type = TUNER_PARAM_TYPE_PAL,
1250 .ranges = tuner_thomson_fe6600_pal_ranges,
1251 .count = ARRAY_SIZE(tuner_thomson_fe6600_pal_ranges),
1252 },
1253 {
1254 .type = TUNER_PARAM_TYPE_DIGITAL,
1255 .ranges = tuner_thomson_fe6600_dvb_ranges,
1256 .count = ARRAY_SIZE(tuner_thomson_fe6600_dvb_ranges),
1257 .iffreq = 16 * 36.125 /*MHz*/,
1258 },
1259};
1260
1261/* ------------ TUNER_SAMSUNG_TCPG_6121P30A - Samsung PAL ------------ */
1262
1263/* '+ 4' turns on the Low Noise Amplifier */
1264static struct tuner_range tuner_samsung_tcpg_6121p30a_pal_ranges[] = {
1265 { 16 * 146.25 /*MHz*/, 0xce, 0x01 + 4, },
1266 { 16 * 428.50 /*MHz*/, 0xce, 0x02 + 4, },
1267 { 16 * 999.99 , 0xce, 0x08 + 4, },
1268};
1269
1270static struct tuner_params tuner_samsung_tcpg_6121p30a_params[] = {
1271 {
1272 .type = TUNER_PARAM_TYPE_PAL,
1273 .ranges = tuner_samsung_tcpg_6121p30a_pal_ranges,
1274 .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_pal_ranges),
1275 .has_tda9887 = 1,
1276 .port1_active = 1,
1277 .port2_active = 1,
1278 .port2_invert_for_secam_lc = 1,
1279 },
1280};
1281
1282/* ------------ TUNER_TCL_MF02GIP-5N-E - TCL MF02GIP-5N ------------ */
1283
1284static struct tuner_range tuner_tcl_mf02gip_5n_ntsc_ranges[] = {
1285 { 16 * 172.00 /*MHz*/, 0x8e, 0x01, },
1286 { 16 * 448.00 /*MHz*/, 0x8e, 0x02, },
1287 { 16 * 999.99 , 0x8e, 0x04, },
1288};
1289
1290static struct tuner_params tuner_tcl_mf02gip_5n_params[] = {
1291 {
1292 .type = TUNER_PARAM_TYPE_NTSC,
1293 .ranges = tuner_tcl_mf02gip_5n_ntsc_ranges,
1294 .count = ARRAY_SIZE(tuner_tcl_mf02gip_5n_ntsc_ranges),
1295 .cb_first_if_lower_freq = 1,
1296 },
1297};
1298
1299/* 80-89 */
1300/* --------- TUNER_PHILIPS_FQ1216LME_MK3 -- active loopthrough, no FM ------- */
1301
1302static struct tuner_params tuner_fq1216lme_mk3_params[] = {
1303 {
1304 .type = TUNER_PARAM_TYPE_PAL,
1305 .ranges = tuner_fm1216me_mk3_pal_ranges,
1306 .count = ARRAY_SIZE(tuner_fm1216me_mk3_pal_ranges),
1307 .cb_first_if_lower_freq = 1, /* not specified, but safe to do */
1308 .has_tda9887 = 1, /* TDA9886 */
1309 .port1_active = 1,
1310 .port2_active = 1,
1311 .port2_invert_for_secam_lc = 1,
1312 .default_top_low = 4,
1313 .default_top_mid = 4,
1314 .default_top_high = 4,
1315 .default_top_secam_low = 4,
1316 .default_top_secam_mid = 4,
1317 .default_top_secam_high = 4,
1318 },
1319};
1320
1321/* ----- TUNER_PARTSNIC_PTI_5NF05 - Partsnic (Daewoo) PTI-5NF05 NTSC ----- */
1322
1323static struct tuner_range tuner_partsnic_pti_5nf05_ranges[] = {
1324 /* The datasheet specified channel ranges and the bandswitch byte */
1325 /* The control byte value of 0x8e is just a guess */
1326 { 16 * 133.25 /*MHz*/, 0x8e, 0x01, }, /* Channels 2 - B */
1327 { 16 * 367.25 /*MHz*/, 0x8e, 0x02, }, /* Channels C - W+11 */
1328 { 16 * 999.99 , 0x8e, 0x08, }, /* Channels W+12 - 69 */
1329};
1330
1331static struct tuner_params tuner_partsnic_pti_5nf05_params[] = {
1332 {
1333 .type = TUNER_PARAM_TYPE_NTSC,
1334 .ranges = tuner_partsnic_pti_5nf05_ranges,
1335 .count = ARRAY_SIZE(tuner_partsnic_pti_5nf05_ranges),
1336 .cb_first_if_lower_freq = 1, /* not specified but safe to do */
1337 },
1338};
1339
1340/* --------- TUNER_PHILIPS_CU1216L - DVB-C NIM ------------------------- */
1341
1342static struct tuner_range tuner_cu1216l_ranges[] = {
1343 { 16 * 160.25 /*MHz*/, 0xce, 0x01 },
1344 { 16 * 444.25 /*MHz*/, 0xce, 0x02 },
1345 { 16 * 999.99 , 0xce, 0x04 },
1346};
1347
1348static struct tuner_params tuner_philips_cu1216l_params[] = {
1349 {
1350 .type = TUNER_PARAM_TYPE_DIGITAL,
1351 .ranges = tuner_cu1216l_ranges,
1352 .count = ARRAY_SIZE(tuner_cu1216l_ranges),
1353 .iffreq = 16 * 36.125, /*MHz*/
1354 },
1355};
1356
1357/* ---------------------- TUNER_SONY_BTF_PXN01Z ------------------------ */
1358
1359static struct tuner_range tuner_sony_btf_pxn01z_ranges[] = {
1360 { 16 * 137.25 /*MHz*/, 0x8e, 0x01, },
1361 { 16 * 367.25 /*MHz*/, 0x8e, 0x02, },
1362 { 16 * 999.99 , 0x8e, 0x04, },
1363};
1364
1365static struct tuner_params tuner_sony_btf_pxn01z_params[] = {
1366 {
1367 .type = TUNER_PARAM_TYPE_NTSC,
1368 .ranges = tuner_sony_btf_pxn01z_ranges,
1369 .count = ARRAY_SIZE(tuner_sony_btf_pxn01z_ranges),
1370 },
1371};
1372
1373/* ------------ TUNER_PHILIPS_FQ1236_MK5 - Philips NTSC ------------ */
1374
1375static struct tuner_params tuner_philips_fq1236_mk5_params[] = {
1376 {
1377 .type = TUNER_PARAM_TYPE_NTSC,
1378 .ranges = tuner_fm1236_mk3_ntsc_ranges,
1379 .count = ARRAY_SIZE(tuner_fm1236_mk3_ntsc_ranges),
1380 .has_tda9887 = 1, /* TDA9885, no FM radio */
1381 },
1382};
1383
1384/* --------------------------------------------------------------------- */
1385
1386struct tunertype tuners[] = {
1387 /* 0-9 */
1388 [TUNER_TEMIC_PAL] = { /* TEMIC PAL */
1389 .name = "Temic PAL (4002 FH5)",
1390 .params = tuner_temic_pal_params,
1391 .count = ARRAY_SIZE(tuner_temic_pal_params),
1392 },
1393 [TUNER_PHILIPS_PAL_I] = { /* Philips PAL_I */
1394 .name = "Philips PAL_I (FI1246 and compatibles)",
1395 .params = tuner_philips_pal_i_params,
1396 .count = ARRAY_SIZE(tuner_philips_pal_i_params),
1397 },
1398 [TUNER_PHILIPS_NTSC] = { /* Philips NTSC */
1399 .name = "Philips NTSC (FI1236,FM1236 and compatibles)",
1400 .params = tuner_philips_ntsc_params,
1401 .count = ARRAY_SIZE(tuner_philips_ntsc_params),
1402 },
1403 [TUNER_PHILIPS_SECAM] = { /* Philips SECAM */
1404 .name = "Philips (SECAM+PAL_BG) (FI1216MF, FM1216MF, FR1216MF)",
1405 .params = tuner_philips_secam_params,
1406 .count = ARRAY_SIZE(tuner_philips_secam_params),
1407 },
1408 [TUNER_ABSENT] = { /* Tuner Absent */
1409 .name = "NoTuner",
1410 },
1411 [TUNER_PHILIPS_PAL] = { /* Philips PAL */
1412 .name = "Philips PAL_BG (FI1216 and compatibles)",
1413 .params = tuner_philips_pal_params,
1414 .count = ARRAY_SIZE(tuner_philips_pal_params),
1415 },
1416 [TUNER_TEMIC_NTSC] = { /* TEMIC NTSC */
1417 .name = "Temic NTSC (4032 FY5)",
1418 .params = tuner_temic_ntsc_params,
1419 .count = ARRAY_SIZE(tuner_temic_ntsc_params),
1420 },
1421 [TUNER_TEMIC_PAL_I] = { /* TEMIC PAL_I */
1422 .name = "Temic PAL_I (4062 FY5)",
1423 .params = tuner_temic_pal_i_params,
1424 .count = ARRAY_SIZE(tuner_temic_pal_i_params),
1425 },
1426 [TUNER_TEMIC_4036FY5_NTSC] = { /* TEMIC NTSC */
1427 .name = "Temic NTSC (4036 FY5)",
1428 .params = tuner_temic_4036fy5_ntsc_params,
1429 .count = ARRAY_SIZE(tuner_temic_4036fy5_ntsc_params),
1430 },
1431 [TUNER_ALPS_TSBH1_NTSC] = { /* TEMIC NTSC */
1432 .name = "Alps HSBH1",
1433 .params = tuner_alps_tsbh1_ntsc_params,
1434 .count = ARRAY_SIZE(tuner_alps_tsbh1_ntsc_params),
1435 },
1436
1437 /* 10-19 */
1438 [TUNER_ALPS_TSBE1_PAL] = { /* TEMIC PAL */
1439 .name = "Alps TSBE1",
1440 .params = tuner_alps_tsb_1_params,
1441 .count = ARRAY_SIZE(tuner_alps_tsb_1_params),
1442 },
1443 [TUNER_ALPS_TSBB5_PAL_I] = { /* Alps PAL_I */
1444 .name = "Alps TSBB5",
1445 .params = tuner_alps_tsbb5_params,
1446 .count = ARRAY_SIZE(tuner_alps_tsbb5_params),
1447 },
1448 [TUNER_ALPS_TSBE5_PAL] = { /* Alps PAL */
1449 .name = "Alps TSBE5",
1450 .params = tuner_alps_tsbe5_params,
1451 .count = ARRAY_SIZE(tuner_alps_tsbe5_params),
1452 },
1453 [TUNER_ALPS_TSBC5_PAL] = { /* Alps PAL */
1454 .name = "Alps TSBC5",
1455 .params = tuner_alps_tsbc5_params,
1456 .count = ARRAY_SIZE(tuner_alps_tsbc5_params),
1457 },
1458 [TUNER_TEMIC_4006FH5_PAL] = { /* TEMIC PAL */
1459 .name = "Temic PAL_BG (4006FH5)",
1460 .params = tuner_temic_4006fh5_params,
1461 .count = ARRAY_SIZE(tuner_temic_4006fh5_params),
1462 },
1463 [TUNER_ALPS_TSHC6_NTSC] = { /* Alps NTSC */
1464 .name = "Alps TSCH6",
1465 .params = tuner_alps_tshc6_params,
1466 .count = ARRAY_SIZE(tuner_alps_tshc6_params),
1467 },
1468 [TUNER_TEMIC_PAL_DK] = { /* TEMIC PAL */
1469 .name = "Temic PAL_DK (4016 FY5)",
1470 .params = tuner_temic_pal_dk_params,
1471 .count = ARRAY_SIZE(tuner_temic_pal_dk_params),
1472 },
1473 [TUNER_PHILIPS_NTSC_M] = { /* Philips NTSC */
1474 .name = "Philips NTSC_M (MK2)",
1475 .params = tuner_philips_ntsc_m_params,
1476 .count = ARRAY_SIZE(tuner_philips_ntsc_m_params),
1477 },
1478 [TUNER_TEMIC_4066FY5_PAL_I] = { /* TEMIC PAL_I */
1479 .name = "Temic PAL_I (4066 FY5)",
1480 .params = tuner_temic_4066fy5_pal_i_params,
1481 .count = ARRAY_SIZE(tuner_temic_4066fy5_pal_i_params),
1482 },
1483 [TUNER_TEMIC_4006FN5_MULTI_PAL] = { /* TEMIC PAL */
1484 .name = "Temic PAL* auto (4006 FN5)",
1485 .params = tuner_temic_4006fn5_multi_params,
1486 .count = ARRAY_SIZE(tuner_temic_4006fn5_multi_params),
1487 },
1488
1489 /* 20-29 */
1490 [TUNER_TEMIC_4009FR5_PAL] = { /* TEMIC PAL */
1491 .name = "Temic PAL_BG (4009 FR5) or PAL_I (4069 FR5)",
1492 .params = tuner_temic_4009f_5_params,
1493 .count = ARRAY_SIZE(tuner_temic_4009f_5_params),
1494 },
1495 [TUNER_TEMIC_4039FR5_NTSC] = { /* TEMIC NTSC */
1496 .name = "Temic NTSC (4039 FR5)",
1497 .params = tuner_temic_4039fr5_params,
1498 .count = ARRAY_SIZE(tuner_temic_4039fr5_params),
1499 },
1500 [TUNER_TEMIC_4046FM5] = { /* TEMIC PAL */
1501 .name = "Temic PAL/SECAM multi (4046 FM5)",
1502 .params = tuner_temic_4046fm5_params,
1503 .count = ARRAY_SIZE(tuner_temic_4046fm5_params),
1504 },
1505 [TUNER_PHILIPS_PAL_DK] = { /* Philips PAL */
1506 .name = "Philips PAL_DK (FI1256 and compatibles)",
1507 .params = tuner_philips_pal_dk_params,
1508 .count = ARRAY_SIZE(tuner_philips_pal_dk_params),
1509 },
1510 [TUNER_PHILIPS_FQ1216ME] = { /* Philips PAL */
1511 .name = "Philips PAL/SECAM multi (FQ1216ME)",
1512 .params = tuner_philips_fq1216me_params,
1513 .count = ARRAY_SIZE(tuner_philips_fq1216me_params),
1514 },
1515 [TUNER_LG_PAL_I_FM] = { /* LGINNOTEK PAL_I */
1516 .name = "LG PAL_I+FM (TAPC-I001D)",
1517 .params = tuner_lg_pal_i_fm_params,
1518 .count = ARRAY_SIZE(tuner_lg_pal_i_fm_params),
1519 },
1520 [TUNER_LG_PAL_I] = { /* LGINNOTEK PAL_I */
1521 .name = "LG PAL_I (TAPC-I701D)",
1522 .params = tuner_lg_pal_i_params,
1523 .count = ARRAY_SIZE(tuner_lg_pal_i_params),
1524 },
1525 [TUNER_LG_NTSC_FM] = { /* LGINNOTEK NTSC */
1526 .name = "LG NTSC+FM (TPI8NSR01F)",
1527 .params = tuner_lg_ntsc_fm_params,
1528 .count = ARRAY_SIZE(tuner_lg_ntsc_fm_params),
1529 },
1530 [TUNER_LG_PAL_FM] = { /* LGINNOTEK PAL */
1531 .name = "LG PAL_BG+FM (TPI8PSB01D)",
1532 .params = tuner_lg_pal_fm_params,
1533 .count = ARRAY_SIZE(tuner_lg_pal_fm_params),
1534 },
1535 [TUNER_LG_PAL] = { /* LGINNOTEK PAL */
1536 .name = "LG PAL_BG (TPI8PSB11D)",
1537 .params = tuner_lg_pal_params,
1538 .count = ARRAY_SIZE(tuner_lg_pal_params),
1539 },
1540
1541 /* 30-39 */
1542 [TUNER_TEMIC_4009FN5_MULTI_PAL_FM] = { /* TEMIC PAL */
1543 .name = "Temic PAL* auto + FM (4009 FN5)",
1544 .params = tuner_temic_4009_fn5_multi_pal_fm_params,
1545 .count = ARRAY_SIZE(tuner_temic_4009_fn5_multi_pal_fm_params),
1546 },
1547 [TUNER_SHARP_2U5JF5540_NTSC] = { /* SHARP NTSC */
1548 .name = "SHARP NTSC_JP (2U5JF5540)",
1549 .params = tuner_sharp_2u5jf5540_params,
1550 .count = ARRAY_SIZE(tuner_sharp_2u5jf5540_params),
1551 },
1552 [TUNER_Samsung_PAL_TCPM9091PD27] = { /* Samsung PAL */
1553 .name = "Samsung PAL TCPM9091PD27",
1554 .params = tuner_samsung_pal_tcpm9091pd27_params,
1555 .count = ARRAY_SIZE(tuner_samsung_pal_tcpm9091pd27_params),
1556 },
1557 [TUNER_MT2032] = { /* Microtune PAL|NTSC */
1558 .name = "MT20xx universal",
1559 /* see mt20xx.c for details */ },
1560 [TUNER_TEMIC_4106FH5] = { /* TEMIC PAL */
1561 .name = "Temic PAL_BG (4106 FH5)",
1562 .params = tuner_temic_4106fh5_params,
1563 .count = ARRAY_SIZE(tuner_temic_4106fh5_params),
1564 },
1565 [TUNER_TEMIC_4012FY5] = { /* TEMIC PAL */
1566 .name = "Temic PAL_DK/SECAM_L (4012 FY5)",
1567 .params = tuner_temic_4012fy5_params,
1568 .count = ARRAY_SIZE(tuner_temic_4012fy5_params),
1569 },
1570 [TUNER_TEMIC_4136FY5] = { /* TEMIC NTSC */
1571 .name = "Temic NTSC (4136 FY5)",
1572 .params = tuner_temic_4136_fy5_params,
1573 .count = ARRAY_SIZE(tuner_temic_4136_fy5_params),
1574 },
1575 [TUNER_LG_PAL_NEW_TAPC] = { /* LGINNOTEK PAL */
1576 .name = "LG PAL (newer TAPC series)",
1577 .params = tuner_lg_pal_new_tapc_params,
1578 .count = ARRAY_SIZE(tuner_lg_pal_new_tapc_params),
1579 },
1580 [TUNER_PHILIPS_FM1216ME_MK3] = { /* Philips PAL */
1581 .name = "Philips PAL/SECAM multi (FM1216ME MK3)",
1582 .params = tuner_fm1216me_mk3_params,
1583 .count = ARRAY_SIZE(tuner_fm1216me_mk3_params),
1584 },
1585 [TUNER_LG_NTSC_NEW_TAPC] = { /* LGINNOTEK NTSC */
1586 .name = "LG NTSC (newer TAPC series)",
1587 .params = tuner_lg_ntsc_new_tapc_params,
1588 .count = ARRAY_SIZE(tuner_lg_ntsc_new_tapc_params),
1589 },
1590
1591 /* 40-49 */
1592 [TUNER_HITACHI_NTSC] = { /* HITACHI NTSC */
1593 .name = "HITACHI V7-J180AT",
1594 .params = tuner_hitachi_ntsc_params,
1595 .count = ARRAY_SIZE(tuner_hitachi_ntsc_params),
1596 },
1597 [TUNER_PHILIPS_PAL_MK] = { /* Philips PAL */
1598 .name = "Philips PAL_MK (FI1216 MK)",
1599 .params = tuner_philips_pal_mk_params,
1600 .count = ARRAY_SIZE(tuner_philips_pal_mk_params),
1601 },
1602 [TUNER_PHILIPS_FCV1236D] = { /* Philips ATSC */
1603 .name = "Philips FCV1236D ATSC/NTSC dual in",
1604 .params = tuner_philips_fcv1236d_params,
1605 .count = ARRAY_SIZE(tuner_philips_fcv1236d_params),
1606 .min = 16 * 53.00,
1607 .max = 16 * 803.00,
1608 .stepsize = 62500,
1609 },
1610 [TUNER_PHILIPS_FM1236_MK3] = { /* Philips NTSC */
1611 .name = "Philips NTSC MK3 (FM1236MK3 or FM1236/F)",
1612 .params = tuner_fm1236_mk3_params,
1613 .count = ARRAY_SIZE(tuner_fm1236_mk3_params),
1614 },
1615 [TUNER_PHILIPS_4IN1] = { /* Philips NTSC */
1616 .name = "Philips 4 in 1 (ATI TV Wonder Pro/Conexant)",
1617 .params = tuner_philips_4in1_params,
1618 .count = ARRAY_SIZE(tuner_philips_4in1_params),
1619 },
1620 [TUNER_MICROTUNE_4049FM5] = { /* Microtune PAL */
1621 .name = "Microtune 4049 FM5",
1622 .params = tuner_microtune_4049_fm5_params,
1623 .count = ARRAY_SIZE(tuner_microtune_4049_fm5_params),
1624 },
1625 [TUNER_PANASONIC_VP27] = { /* Panasonic NTSC */
1626 .name = "Panasonic VP27s/ENGE4324D",
1627 .params = tuner_panasonic_vp27_params,
1628 .count = ARRAY_SIZE(tuner_panasonic_vp27_params),
1629 },
1630 [TUNER_LG_NTSC_TAPE] = { /* LGINNOTEK NTSC */
1631 .name = "LG NTSC (TAPE series)",
1632 .params = tuner_fm1236_mk3_params,
1633 .count = ARRAY_SIZE(tuner_fm1236_mk3_params),
1634 },
1635 [TUNER_TNF_8831BGFF] = { /* Philips PAL */
1636 .name = "Tenna TNF 8831 BGFF)",
1637 .params = tuner_tnf_8831bgff_params,
1638 .count = ARRAY_SIZE(tuner_tnf_8831bgff_params),
1639 },
1640 [TUNER_MICROTUNE_4042FI5] = { /* Microtune NTSC */
1641 .name = "Microtune 4042 FI5 ATSC/NTSC dual in",
1642 .params = tuner_microtune_4042fi5_params,
1643 .count = ARRAY_SIZE(tuner_microtune_4042fi5_params),
1644 .min = 16 * 57.00,
1645 .max = 16 * 858.00,
1646 .stepsize = 62500,
1647 },
1648
1649 /* 50-59 */
1650 [TUNER_TCL_2002N] = { /* TCL NTSC */
1651 .name = "TCL 2002N",
1652 .params = tuner_tcl_2002n_params,
1653 .count = ARRAY_SIZE(tuner_tcl_2002n_params),
1654 },
1655 [TUNER_PHILIPS_FM1256_IH3] = { /* Philips PAL */
1656 .name = "Philips PAL/SECAM_D (FM 1256 I-H3)",
1657 .params = tuner_philips_fm1256_ih3_params,
1658 .count = ARRAY_SIZE(tuner_philips_fm1256_ih3_params),
1659 },
1660 [TUNER_THOMSON_DTT7610] = { /* THOMSON ATSC */
1661 .name = "Thomson DTT 7610 (ATSC/NTSC)",
1662 .params = tuner_thomson_dtt7610_params,
1663 .count = ARRAY_SIZE(tuner_thomson_dtt7610_params),
1664 .min = 16 * 44.00,
1665 .max = 16 * 958.00,
1666 .stepsize = 62500,
1667 },
1668 [TUNER_PHILIPS_FQ1286] = { /* Philips NTSC */
1669 .name = "Philips FQ1286",
1670 .params = tuner_philips_fq1286_params,
1671 .count = ARRAY_SIZE(tuner_philips_fq1286_params),
1672 },
1673 [TUNER_PHILIPS_TDA8290] = { /* Philips PAL|NTSC */
1674 .name = "Philips/NXP TDA 8290/8295 + 8275/8275A/18271",
1675 /* see tda8290.c for details */ },
1676 [TUNER_TCL_2002MB] = { /* TCL PAL */
1677 .name = "TCL 2002MB",
1678 .params = tuner_tcl_2002mb_params,
1679 .count = ARRAY_SIZE(tuner_tcl_2002mb_params),
1680 },
1681 [TUNER_PHILIPS_FQ1216AME_MK4] = { /* Philips PAL */
1682 .name = "Philips PAL/SECAM multi (FQ1216AME MK4)",
1683 .params = tuner_philips_fq1216ame_mk4_params,
1684 .count = ARRAY_SIZE(tuner_philips_fq1216ame_mk4_params),
1685 },
1686 [TUNER_PHILIPS_FQ1236A_MK4] = { /* Philips NTSC */
1687 .name = "Philips FQ1236A MK4",
1688 .params = tuner_philips_fq1236a_mk4_params,
1689 .count = ARRAY_SIZE(tuner_philips_fq1236a_mk4_params),
1690 },
1691 [TUNER_YMEC_TVF_8531MF] = { /* Philips NTSC */
1692 .name = "Ymec TVision TVF-8531MF/8831MF/8731MF",
1693 .params = tuner_ymec_tvf_8531mf_params,
1694 .count = ARRAY_SIZE(tuner_ymec_tvf_8531mf_params),
1695 },
1696 [TUNER_YMEC_TVF_5533MF] = { /* Philips NTSC */
1697 .name = "Ymec TVision TVF-5533MF",
1698 .params = tuner_ymec_tvf_5533mf_params,
1699 .count = ARRAY_SIZE(tuner_ymec_tvf_5533mf_params),
1700 },
1701
1702 /* 60-69 */
1703 [TUNER_THOMSON_DTT761X] = { /* THOMSON ATSC */
1704 /* DTT 7611 7611A 7612 7613 7613A 7614 7615 7615A */
1705 .name = "Thomson DTT 761X (ATSC/NTSC)",
1706 .params = tuner_thomson_dtt761x_params,
1707 .count = ARRAY_SIZE(tuner_thomson_dtt761x_params),
1708 .min = 16 * 57.00,
1709 .max = 16 * 863.00,
1710 .stepsize = 62500,
1711 .initdata = tua603x_agc103,
1712 },
1713 [TUNER_TENA_9533_DI] = { /* Philips PAL */
1714 .name = "Tena TNF9533-D/IF/TNF9533-B/DF",
1715 .params = tuner_tena_9533_di_params,
1716 .count = ARRAY_SIZE(tuner_tena_9533_di_params),
1717 },
1718 [TUNER_TEA5767] = { /* Philips RADIO */
1719 .name = "Philips TEA5767HN FM Radio",
1720 /* see tea5767.c for details */
1721 },
1722 [TUNER_PHILIPS_FMD1216ME_MK3] = { /* Philips PAL */
1723 .name = "Philips FMD1216ME MK3 Hybrid Tuner",
1724 .params = tuner_philips_fmd1216me_mk3_params,
1725 .count = ARRAY_SIZE(tuner_philips_fmd1216me_mk3_params),
1726 .min = 16 * 50.87,
1727 .max = 16 * 858.00,
1728 .stepsize = 166667,
1729 .initdata = tua603x_agc112,
1730 .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
1731 },
1732 [TUNER_LG_TDVS_H06XF] = { /* LGINNOTEK ATSC */
1733 .name = "LG TDVS-H06xF", /* H061F, H062F & H064F */
1734 .params = tuner_lg_tdvs_h06xf_params,
1735 .count = ARRAY_SIZE(tuner_lg_tdvs_h06xf_params),
1736 .min = 16 * 54.00,
1737 .max = 16 * 863.00,
1738 .stepsize = 62500,
1739 .initdata = tua603x_agc103,
1740 },
1741 [TUNER_YMEC_TVF66T5_B_DFF] = { /* Philips PAL */
1742 .name = "Ymec TVF66T5-B/DFF",
1743 .params = tuner_ymec_tvf66t5_b_dff_params,
1744 .count = ARRAY_SIZE(tuner_ymec_tvf66t5_b_dff_params),
1745 },
1746 [TUNER_LG_TALN] = { /* LGINNOTEK NTSC / PAL / SECAM */
1747 .name = "LG TALN series",
1748 .params = tuner_lg_taln_params,
1749 .count = ARRAY_SIZE(tuner_lg_taln_params),
1750 },
1751 [TUNER_PHILIPS_TD1316] = { /* Philips PAL */
1752 .name = "Philips TD1316 Hybrid Tuner",
1753 .params = tuner_philips_td1316_params,
1754 .count = ARRAY_SIZE(tuner_philips_td1316_params),
1755 .min = 16 * 87.00,
1756 .max = 16 * 895.00,
1757 .stepsize = 166667,
1758 },
1759 [TUNER_PHILIPS_TUV1236D] = { /* Philips ATSC */
1760 .name = "Philips TUV1236D ATSC/NTSC dual in",
1761 .params = tuner_tuv1236d_params,
1762 .count = ARRAY_SIZE(tuner_tuv1236d_params),
1763 .min = 16 * 54.00,
1764 .max = 16 * 864.00,
1765 .stepsize = 62500,
1766 },
1767 [TUNER_TNF_5335MF] = { /* Tenna PAL/NTSC */
1768 .name = "Tena TNF 5335 and similar models",
1769 .params = tuner_tnf_5335mf_params,
1770 .count = ARRAY_SIZE(tuner_tnf_5335mf_params),
1771 },
1772
1773 /* 70-79 */
1774 [TUNER_SAMSUNG_TCPN_2121P30A] = { /* Samsung NTSC */
1775 .name = "Samsung TCPN 2121P30A",
1776 .params = tuner_samsung_tcpn_2121p30a_params,
1777 .count = ARRAY_SIZE(tuner_samsung_tcpn_2121p30a_params),
1778 },
1779 [TUNER_XC2028] = { /* Xceive 2028 */
1780 .name = "Xceive xc2028/xc3028 tuner",
1781 /* see tuner-xc2028.c for details */
1782 },
1783 [TUNER_THOMSON_FE6600] = { /* Thomson PAL / DVB-T */
1784 .name = "Thomson FE6600",
1785 .params = tuner_thomson_fe6600_params,
1786 .count = ARRAY_SIZE(tuner_thomson_fe6600_params),
1787 .min = 16 * 44.25,
1788 .max = 16 * 858.00,
1789 .stepsize = 166667,
1790 },
1791 [TUNER_SAMSUNG_TCPG_6121P30A] = { /* Samsung PAL */
1792 .name = "Samsung TCPG 6121P30A",
1793 .params = tuner_samsung_tcpg_6121p30a_params,
1794 .count = ARRAY_SIZE(tuner_samsung_tcpg_6121p30a_params),
1795 },
1796 [TUNER_TDA9887] = { /* Philips TDA 9887 IF PLL Demodulator.
1797 This chip is part of some modern tuners */
1798 .name = "Philips TDA988[5,6,7] IF PLL Demodulator",
1799 /* see tda9887.c for details */
1800 },
1801 [TUNER_TEA5761] = { /* Philips RADIO */
1802 .name = "Philips TEA5761 FM Radio",
1803 /* see tea5767.c for details */
1804 },
1805 [TUNER_XC5000] = { /* Xceive 5000 */
1806 .name = "Xceive 5000 tuner",
1807 /* see xc5000.c for details */
1808 },
1809 [TUNER_XC4000] = { /* Xceive 4000 */
1810 .name = "Xceive 4000 tuner",
1811 /* see xc4000.c for details */
1812 },
1813 [TUNER_TCL_MF02GIP_5N] = { /* TCL tuner MF02GIP-5N-E */
1814 .name = "TCL tuner MF02GIP-5N-E",
1815 .params = tuner_tcl_mf02gip_5n_params,
1816 .count = ARRAY_SIZE(tuner_tcl_mf02gip_5n_params),
1817 },
1818 [TUNER_PHILIPS_FMD1216MEX_MK3] = { /* Philips PAL */
1819 .name = "Philips FMD1216MEX MK3 Hybrid Tuner",
1820 .params = tuner_philips_fmd1216mex_mk3_params,
1821 .count = ARRAY_SIZE(tuner_philips_fmd1216mex_mk3_params),
1822 .min = 16 * 50.87,
1823 .max = 16 * 858.00,
1824 .stepsize = 166667,
1825 .initdata = tua603x_agc112,
1826 .sleepdata = (u8[]){ 4, 0x9c, 0x60, 0x85, 0x54 },
1827 },
1828 [TUNER_PHILIPS_FM1216MK5] = { /* Philips PAL */
1829 .name = "Philips PAL/SECAM multi (FM1216 MK5)",
1830 .params = tuner_fm1216mk5_params,
1831 .count = ARRAY_SIZE(tuner_fm1216mk5_params),
1832 },
1833
1834 /* 80-89 */
1835 [TUNER_PHILIPS_FQ1216LME_MK3] = { /* PAL/SECAM, Loop-thru, no FM */
1836 .name = "Philips FQ1216LME MK3 PAL/SECAM w/active loopthrough",
1837 .params = tuner_fq1216lme_mk3_params,
1838 .count = ARRAY_SIZE(tuner_fq1216lme_mk3_params),
1839 },
1840
1841 [TUNER_PARTSNIC_PTI_5NF05] = {
1842 .name = "Partsnic (Daewoo) PTI-5NF05",
1843 .params = tuner_partsnic_pti_5nf05_params,
1844 .count = ARRAY_SIZE(tuner_partsnic_pti_5nf05_params),
1845 },
1846 [TUNER_PHILIPS_CU1216L] = {
1847 .name = "Philips CU1216L",
1848 .params = tuner_philips_cu1216l_params,
1849 .count = ARRAY_SIZE(tuner_philips_cu1216l_params),
1850 .stepsize = 62500,
1851 },
1852 [TUNER_NXP_TDA18271] = {
1853 .name = "NXP TDA18271",
1854 /* see tda18271-fe.c for details */
1855 },
1856 [TUNER_SONY_BTF_PXN01Z] = {
1857 .name = "Sony BTF-Pxn01Z",
1858 .params = tuner_sony_btf_pxn01z_params,
1859 .count = ARRAY_SIZE(tuner_sony_btf_pxn01z_params),
1860 },
1861 [TUNER_PHILIPS_FQ1236_MK5] = { /* NTSC, TDA9885, no FM radio */
1862 .name = "Philips FQ1236 MK5",
1863 .params = tuner_philips_fq1236_mk5_params,
1864 .count = ARRAY_SIZE(tuner_philips_fq1236_mk5_params),
1865 },
1866 [TUNER_TENA_TNF_5337] = { /* Tena 5337 MFD */
1867 .name = "Tena TNF5337 MFD",
1868 .params = tuner_tena_tnf_5337_params,
1869 .count = ARRAY_SIZE(tuner_tena_tnf_5337_params),
1870 },
1871 [TUNER_XC5000C] = { /* Xceive 5000C */
1872 .name = "Xceive 5000C tuner",
1873 /* see xc5000.c for details */
1874 },
1875};
1876EXPORT_SYMBOL(tuners);
1877
1878unsigned const int tuner_count = ARRAY_SIZE(tuners);
1879EXPORT_SYMBOL(tuner_count);
1880
1881MODULE_DESCRIPTION("Simple tuner device type database");
1882MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
1883MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/tuner-xc2028-types.h b/drivers/media/tuners/tuner-xc2028-types.h
new file mode 100644
index 000000000000..74dc46a71f64
--- /dev/null
+++ b/drivers/media/tuners/tuner-xc2028-types.h
@@ -0,0 +1,141 @@
1/* tuner-xc2028_types
2 *
3 * This file includes internal tipes to be used inside tuner-xc2028.
4 * Shouldn't be included outside tuner-xc2028
5 *
6 * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
7 * This code is placed under the terms of the GNU General Public License v2
8 */
9
10/* xc3028 firmware types */
11
12/* BASE firmware should be loaded before any other firmware */
13#define BASE (1<<0)
14#define BASE_TYPES (BASE|F8MHZ|MTS|FM|INPUT1|INPUT2|INIT1)
15
16/* F8MHZ marks BASE firmwares for 8 MHz Bandwidth */
17#define F8MHZ (1<<1)
18
19/* Multichannel Television Sound (MTS)
20 Those firmwares are capable of using xc2038 DSP to decode audio and
21 produce a baseband audio output on some pins of the chip.
22 There are MTS firmwares for the most used video standards. It should be
23 required to use MTS firmwares, depending on the way audio is routed into
24 the bridge chip
25 */
26#define MTS (1<<2)
27
28/* FIXME: I have no idea what's the difference between
29 D2620 and D2633 firmwares
30 */
31#define D2620 (1<<3)
32#define D2633 (1<<4)
33
34/* DTV firmwares for 6, 7 and 8 MHz
35 DTV6 - 6MHz - ATSC/DVB-C/DVB-T/ISDB-T/DOCSIS
36 DTV8 - 8MHz - DVB-C/DVB-T
37 */
38#define DTV6 (1 << 5)
39#define QAM (1 << 6)
40#define DTV7 (1<<7)
41#define DTV78 (1<<8)
42#define DTV8 (1<<9)
43
44#define DTV_TYPES (D2620|D2633|DTV6|QAM|DTV7|DTV78|DTV8|ATSC)
45
46/* There's a FM | BASE firmware + FM specific firmware (std=0) */
47#define FM (1<<10)
48
49#define STD_SPECIFIC_TYPES (MTS|FM|LCD|NOGD)
50
51/* Applies only for FM firmware
52 Makes it use RF input 1 (pin #2) instead of input 2 (pin #4)
53 */
54#define INPUT1 (1<<11)
55
56
57/* LCD firmwares exist only for MTS STD/MN (PAL or NTSC/M)
58 and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr)
59 There are variants both with and without NOGD
60 Those firmwares produce better result with LCD displays
61 */
62#define LCD (1<<12)
63
64/* NOGD firmwares exist only for MTS STD/MN (PAL or NTSC/M)
65 and for non-MTS STD/MN (PAL, NTSC/M or NTSC/Kr)
66 The NOGD firmwares don't have group delay compensation filter
67 */
68#define NOGD (1<<13)
69
70/* Old firmwares were broken into init0 and init1 */
71#define INIT1 (1<<14)
72
73/* SCODE firmware selects particular behaviours */
74#define MONO (1 << 15)
75#define ATSC (1 << 16)
76#define IF (1 << 17)
77#define LG60 (1 << 18)
78#define ATI638 (1 << 19)
79#define OREN538 (1 << 20)
80#define OREN36 (1 << 21)
81#define TOYOTA388 (1 << 22)
82#define TOYOTA794 (1 << 23)
83#define DIBCOM52 (1 << 24)
84#define ZARLINK456 (1 << 25)
85#define CHINA (1 << 26)
86#define F6MHZ (1 << 27)
87#define INPUT2 (1 << 28)
88#define SCODE (1 << 29)
89
90/* This flag identifies that the scode table has a new format */
91#define HAS_IF (1 << 30)
92
93/* There are different scode tables for MTS and non-MTS.
94 The MTS firmwares support mono only
95 */
96#define SCODE_TYPES (SCODE | MTS)
97
98
99/* Newer types not defined on videodev2.h.
100 The original idea were to move all those types to videodev2.h, but
101 it seemed overkill, since, with the exception of SECAM/K3, the other
102 types seem to be autodetected.
103 It is not clear where secam/k3 is used, nor we have a feedback of this
104 working or being autodetected by the standard secam firmware.
105 */
106
107#define V4L2_STD_SECAM_K3 (0x04000000)
108
109/* Audio types */
110
111#define V4L2_STD_A2_A (1LL<<32)
112#define V4L2_STD_A2_B (1LL<<33)
113#define V4L2_STD_NICAM_A (1LL<<34)
114#define V4L2_STD_NICAM_B (1LL<<35)
115#define V4L2_STD_AM (1LL<<36)
116#define V4L2_STD_BTSC (1LL<<37)
117#define V4L2_STD_EIAJ (1LL<<38)
118
119#define V4L2_STD_A2 (V4L2_STD_A2_A | V4L2_STD_A2_B)
120#define V4L2_STD_NICAM (V4L2_STD_NICAM_A | V4L2_STD_NICAM_B)
121
122/* To preserve backward compatibilty,
123 (std & V4L2_STD_AUDIO) = 0 means that ALL audio stds are supported
124 */
125
126#define V4L2_STD_AUDIO (V4L2_STD_A2 | \
127 V4L2_STD_NICAM | \
128 V4L2_STD_AM | \
129 V4L2_STD_BTSC | \
130 V4L2_STD_EIAJ)
131
132/* Used standards with audio restrictions */
133
134#define V4L2_STD_PAL_BG_A2_A (V4L2_STD_PAL_BG | V4L2_STD_A2_A)
135#define V4L2_STD_PAL_BG_A2_B (V4L2_STD_PAL_BG | V4L2_STD_A2_B)
136#define V4L2_STD_PAL_BG_NICAM_A (V4L2_STD_PAL_BG | V4L2_STD_NICAM_A)
137#define V4L2_STD_PAL_BG_NICAM_B (V4L2_STD_PAL_BG | V4L2_STD_NICAM_B)
138#define V4L2_STD_PAL_DK_A2 (V4L2_STD_PAL_DK | V4L2_STD_A2)
139#define V4L2_STD_PAL_DK_NICAM (V4L2_STD_PAL_DK | V4L2_STD_NICAM)
140#define V4L2_STD_SECAM_L_NICAM (V4L2_STD_SECAM_L | V4L2_STD_NICAM)
141#define V4L2_STD_SECAM_L_AM (V4L2_STD_SECAM_L | V4L2_STD_AM)
diff --git a/drivers/media/tuners/tuner-xc2028.c b/drivers/media/tuners/tuner-xc2028.c
new file mode 100644
index 000000000000..7bcb6b0ff1df
--- /dev/null
+++ b/drivers/media/tuners/tuner-xc2028.c
@@ -0,0 +1,1509 @@
1/* tuner-xc2028
2 *
3 * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
4 *
5 * Copyright (c) 2007 Michel Ludwig (michel.ludwig@gmail.com)
6 * - frontend interface
7 *
8 * This code is placed under the terms of the GNU General Public License v2
9 */
10
11#include <linux/i2c.h>
12#include <asm/div64.h>
13#include <linux/firmware.h>
14#include <linux/videodev2.h>
15#include <linux/delay.h>
16#include <media/tuner.h>
17#include <linux/mutex.h>
18#include <linux/slab.h>
19#include <asm/unaligned.h>
20#include "tuner-i2c.h"
21#include "tuner-xc2028.h"
22#include "tuner-xc2028-types.h"
23
24#include <linux/dvb/frontend.h>
25#include "dvb_frontend.h"
26
27/* Registers (Write-only) */
28#define XREG_INIT 0x00
29#define XREG_RF_FREQ 0x02
30#define XREG_POWER_DOWN 0x08
31
32/* Registers (Read-only) */
33#define XREG_FREQ_ERROR 0x01
34#define XREG_LOCK 0x02
35#define XREG_VERSION 0x04
36#define XREG_PRODUCT_ID 0x08
37#define XREG_HSYNC_FREQ 0x10
38#define XREG_FRAME_LINES 0x20
39#define XREG_SNR 0x40
40
41#define XREG_ADC_ENV 0x0100
42
43static int debug;
44module_param(debug, int, 0644);
45MODULE_PARM_DESC(debug, "enable verbose debug messages");
46
47static int no_poweroff;
48module_param(no_poweroff, int, 0644);
49MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
50 "1 keep device energized and with tuner ready all the times.\n"
51 " Faster, but consumes more power and keeps the device hotter\n");
52
53static char audio_std[8];
54module_param_string(audio_std, audio_std, sizeof(audio_std), 0);
55MODULE_PARM_DESC(audio_std,
56 "Audio standard. XC3028 audio decoder explicitly "
57 "needs to know what audio\n"
58 "standard is needed for some video standards with audio A2 or NICAM.\n"
59 "The valid values are:\n"
60 "A2\n"
61 "A2/A\n"
62 "A2/B\n"
63 "NICAM\n"
64 "NICAM/A\n"
65 "NICAM/B\n");
66
67static char firmware_name[30];
68module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
69MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the "
70 "default firmware name\n");
71
72static LIST_HEAD(hybrid_tuner_instance_list);
73static DEFINE_MUTEX(xc2028_list_mutex);
74
75/* struct for storing firmware table */
76struct firmware_description {
77 unsigned int type;
78 v4l2_std_id id;
79 __u16 int_freq;
80 unsigned char *ptr;
81 unsigned int size;
82};
83
84struct firmware_properties {
85 unsigned int type;
86 v4l2_std_id id;
87 v4l2_std_id std_req;
88 __u16 int_freq;
89 unsigned int scode_table;
90 int scode_nr;
91};
92
93enum xc2028_state {
94 XC2028_NO_FIRMWARE = 0,
95 XC2028_WAITING_FIRMWARE,
96 XC2028_ACTIVE,
97 XC2028_SLEEP,
98 XC2028_NODEV,
99};
100
101struct xc2028_data {
102 struct list_head hybrid_tuner_instance_list;
103 struct tuner_i2c_props i2c_props;
104 __u32 frequency;
105
106 enum xc2028_state state;
107 const char *fname;
108
109 struct firmware_description *firm;
110 int firm_size;
111 __u16 firm_version;
112
113 __u16 hwmodel;
114 __u16 hwvers;
115
116 struct xc2028_ctrl ctrl;
117
118 struct firmware_properties cur_fw;
119
120 struct mutex lock;
121};
122
123#define i2c_send(priv, buf, size) ({ \
124 int _rc; \
125 _rc = tuner_i2c_xfer_send(&priv->i2c_props, buf, size); \
126 if (size != _rc) \
127 tuner_info("i2c output error: rc = %d (should be %d)\n",\
128 _rc, (int)size); \
129 if (priv->ctrl.msleep) \
130 msleep(priv->ctrl.msleep); \
131 _rc; \
132})
133
134#define i2c_rcv(priv, buf, size) ({ \
135 int _rc; \
136 _rc = tuner_i2c_xfer_recv(&priv->i2c_props, buf, size); \
137 if (size != _rc) \
138 tuner_err("i2c input error: rc = %d (should be %d)\n", \
139 _rc, (int)size); \
140 _rc; \
141})
142
143#define i2c_send_recv(priv, obuf, osize, ibuf, isize) ({ \
144 int _rc; \
145 _rc = tuner_i2c_xfer_send_recv(&priv->i2c_props, obuf, osize, \
146 ibuf, isize); \
147 if (isize != _rc) \
148 tuner_err("i2c input error: rc = %d (should be %d)\n", \
149 _rc, (int)isize); \
150 if (priv->ctrl.msleep) \
151 msleep(priv->ctrl.msleep); \
152 _rc; \
153})
154
155#define send_seq(priv, data...) ({ \
156 static u8 _val[] = data; \
157 int _rc; \
158 if (sizeof(_val) != \
159 (_rc = tuner_i2c_xfer_send(&priv->i2c_props, \
160 _val, sizeof(_val)))) { \
161 tuner_err("Error on line %d: %d\n", __LINE__, _rc); \
162 } else if (priv->ctrl.msleep) \
163 msleep(priv->ctrl.msleep); \
164 _rc; \
165})
166
167static int xc2028_get_reg(struct xc2028_data *priv, u16 reg, u16 *val)
168{
169 unsigned char buf[2];
170 unsigned char ibuf[2];
171
172 tuner_dbg("%s %04x called\n", __func__, reg);
173
174 buf[0] = reg >> 8;
175 buf[1] = (unsigned char) reg;
176
177 if (i2c_send_recv(priv, buf, 2, ibuf, 2) != 2)
178 return -EIO;
179
180 *val = (ibuf[1]) | (ibuf[0] << 8);
181 return 0;
182}
183
184#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
185static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
186{
187 if (type & BASE)
188 printk("BASE ");
189 if (type & INIT1)
190 printk("INIT1 ");
191 if (type & F8MHZ)
192 printk("F8MHZ ");
193 if (type & MTS)
194 printk("MTS ");
195 if (type & D2620)
196 printk("D2620 ");
197 if (type & D2633)
198 printk("D2633 ");
199 if (type & DTV6)
200 printk("DTV6 ");
201 if (type & QAM)
202 printk("QAM ");
203 if (type & DTV7)
204 printk("DTV7 ");
205 if (type & DTV78)
206 printk("DTV78 ");
207 if (type & DTV8)
208 printk("DTV8 ");
209 if (type & FM)
210 printk("FM ");
211 if (type & INPUT1)
212 printk("INPUT1 ");
213 if (type & LCD)
214 printk("LCD ");
215 if (type & NOGD)
216 printk("NOGD ");
217 if (type & MONO)
218 printk("MONO ");
219 if (type & ATSC)
220 printk("ATSC ");
221 if (type & IF)
222 printk("IF ");
223 if (type & LG60)
224 printk("LG60 ");
225 if (type & ATI638)
226 printk("ATI638 ");
227 if (type & OREN538)
228 printk("OREN538 ");
229 if (type & OREN36)
230 printk("OREN36 ");
231 if (type & TOYOTA388)
232 printk("TOYOTA388 ");
233 if (type & TOYOTA794)
234 printk("TOYOTA794 ");
235 if (type & DIBCOM52)
236 printk("DIBCOM52 ");
237 if (type & ZARLINK456)
238 printk("ZARLINK456 ");
239 if (type & CHINA)
240 printk("CHINA ");
241 if (type & F6MHZ)
242 printk("F6MHZ ");
243 if (type & INPUT2)
244 printk("INPUT2 ");
245 if (type & SCODE)
246 printk("SCODE ");
247 if (type & HAS_IF)
248 printk("HAS_IF_%d ", int_freq);
249}
250
251static v4l2_std_id parse_audio_std_option(void)
252{
253 if (strcasecmp(audio_std, "A2") == 0)
254 return V4L2_STD_A2;
255 if (strcasecmp(audio_std, "A2/A") == 0)
256 return V4L2_STD_A2_A;
257 if (strcasecmp(audio_std, "A2/B") == 0)
258 return V4L2_STD_A2_B;
259 if (strcasecmp(audio_std, "NICAM") == 0)
260 return V4L2_STD_NICAM;
261 if (strcasecmp(audio_std, "NICAM/A") == 0)
262 return V4L2_STD_NICAM_A;
263 if (strcasecmp(audio_std, "NICAM/B") == 0)
264 return V4L2_STD_NICAM_B;
265
266 return 0;
267}
268
269static int check_device_status(struct xc2028_data *priv)
270{
271 switch (priv->state) {
272 case XC2028_NO_FIRMWARE:
273 case XC2028_WAITING_FIRMWARE:
274 return -EAGAIN;
275 case XC2028_ACTIVE:
276 case XC2028_SLEEP:
277 return 0;
278 case XC2028_NODEV:
279 return -ENODEV;
280 }
281 return 0;
282}
283
284static void free_firmware(struct xc2028_data *priv)
285{
286 int i;
287 tuner_dbg("%s called\n", __func__);
288
289 if (!priv->firm)
290 return;
291
292 for (i = 0; i < priv->firm_size; i++)
293 kfree(priv->firm[i].ptr);
294
295 kfree(priv->firm);
296
297 priv->firm = NULL;
298 priv->firm_size = 0;
299 priv->state = XC2028_NO_FIRMWARE;
300
301 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
302}
303
304static int load_all_firmwares(struct dvb_frontend *fe,
305 const struct firmware *fw)
306{
307 struct xc2028_data *priv = fe->tuner_priv;
308 const unsigned char *p, *endp;
309 int rc = 0;
310 int n, n_array;
311 char name[33];
312
313 tuner_dbg("%s called\n", __func__);
314
315 p = fw->data;
316 endp = p + fw->size;
317
318 if (fw->size < sizeof(name) - 1 + 2 + 2) {
319 tuner_err("Error: firmware file %s has invalid size!\n",
320 priv->fname);
321 goto corrupt;
322 }
323
324 memcpy(name, p, sizeof(name) - 1);
325 name[sizeof(name) - 1] = 0;
326 p += sizeof(name) - 1;
327
328 priv->firm_version = get_unaligned_le16(p);
329 p += 2;
330
331 n_array = get_unaligned_le16(p);
332 p += 2;
333
334 tuner_info("Loading %d firmware images from %s, type: %s, ver %d.%d\n",
335 n_array, priv->fname, name,
336 priv->firm_version >> 8, priv->firm_version & 0xff);
337
338 priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL);
339 if (priv->firm == NULL) {
340 tuner_err("Not enough memory to load firmware file.\n");
341 rc = -ENOMEM;
342 goto err;
343 }
344 priv->firm_size = n_array;
345
346 n = -1;
347 while (p < endp) {
348 __u32 type, size;
349 v4l2_std_id id;
350 __u16 int_freq = 0;
351
352 n++;
353 if (n >= n_array) {
354 tuner_err("More firmware images in file than "
355 "were expected!\n");
356 goto corrupt;
357 }
358
359 /* Checks if there's enough bytes to read */
360 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
361 goto header;
362
363 type = get_unaligned_le32(p);
364 p += sizeof(type);
365
366 id = get_unaligned_le64(p);
367 p += sizeof(id);
368
369 if (type & HAS_IF) {
370 int_freq = get_unaligned_le16(p);
371 p += sizeof(int_freq);
372 if (endp - p < sizeof(size))
373 goto header;
374 }
375
376 size = get_unaligned_le32(p);
377 p += sizeof(size);
378
379 if (!size || size > endp - p) {
380 tuner_err("Firmware type ");
381 dump_firm_type(type);
382 printk("(%x), id %llx is corrupted "
383 "(size=%d, expected %d)\n",
384 type, (unsigned long long)id,
385 (unsigned)(endp - p), size);
386 goto corrupt;
387 }
388
389 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
390 if (priv->firm[n].ptr == NULL) {
391 tuner_err("Not enough memory to load firmware file.\n");
392 rc = -ENOMEM;
393 goto err;
394 }
395 tuner_dbg("Reading firmware type ");
396 if (debug) {
397 dump_firm_type_and_int_freq(type, int_freq);
398 printk("(%x), id %llx, size=%d.\n",
399 type, (unsigned long long)id, size);
400 }
401
402 memcpy(priv->firm[n].ptr, p, size);
403 priv->firm[n].type = type;
404 priv->firm[n].id = id;
405 priv->firm[n].size = size;
406 priv->firm[n].int_freq = int_freq;
407
408 p += size;
409 }
410
411 if (n + 1 != priv->firm_size) {
412 tuner_err("Firmware file is incomplete!\n");
413 goto corrupt;
414 }
415
416 goto done;
417
418header:
419 tuner_err("Firmware header is incomplete!\n");
420corrupt:
421 rc = -EINVAL;
422 tuner_err("Error: firmware file is corrupted!\n");
423
424err:
425 tuner_info("Releasing partially loaded firmware file.\n");
426 free_firmware(priv);
427
428done:
429 if (rc == 0)
430 tuner_dbg("Firmware files loaded.\n");
431 else
432 priv->state = XC2028_NODEV;
433
434 return rc;
435}
436
437static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
438 v4l2_std_id *id)
439{
440 struct xc2028_data *priv = fe->tuner_priv;
441 int i, best_i = -1, best_nr_matches = 0;
442 unsigned int type_mask = 0;
443
444 tuner_dbg("%s called, want type=", __func__);
445 if (debug) {
446 dump_firm_type(type);
447 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
448 }
449
450 if (!priv->firm) {
451 tuner_err("Error! firmware not loaded\n");
452 return -EINVAL;
453 }
454
455 if (((type & ~SCODE) == 0) && (*id == 0))
456 *id = V4L2_STD_PAL;
457
458 if (type & BASE)
459 type_mask = BASE_TYPES;
460 else if (type & SCODE) {
461 type &= SCODE_TYPES;
462 type_mask = SCODE_TYPES & ~HAS_IF;
463 } else if (type & DTV_TYPES)
464 type_mask = DTV_TYPES;
465 else if (type & STD_SPECIFIC_TYPES)
466 type_mask = STD_SPECIFIC_TYPES;
467
468 type &= type_mask;
469
470 if (!(type & SCODE))
471 type_mask = ~0;
472
473 /* Seek for exact match */
474 for (i = 0; i < priv->firm_size; i++) {
475 if ((type == (priv->firm[i].type & type_mask)) &&
476 (*id == priv->firm[i].id))
477 goto found;
478 }
479
480 /* Seek for generic video standard match */
481 for (i = 0; i < priv->firm_size; i++) {
482 v4l2_std_id match_mask;
483 int nr_matches;
484
485 if (type != (priv->firm[i].type & type_mask))
486 continue;
487
488 match_mask = *id & priv->firm[i].id;
489 if (!match_mask)
490 continue;
491
492 if ((*id & match_mask) == *id)
493 goto found; /* Supports all the requested standards */
494
495 nr_matches = hweight64(match_mask);
496 if (nr_matches > best_nr_matches) {
497 best_nr_matches = nr_matches;
498 best_i = i;
499 }
500 }
501
502 if (best_nr_matches > 0) {
503 tuner_dbg("Selecting best matching firmware (%d bits) for "
504 "type=", best_nr_matches);
505 dump_firm_type(type);
506 printk("(%x), id %016llx:\n", type, (unsigned long long)*id);
507 i = best_i;
508 goto found;
509 }
510
511 /*FIXME: Would make sense to seek for type "hint" match ? */
512
513 i = -ENOENT;
514 goto ret;
515
516found:
517 *id = priv->firm[i].id;
518
519ret:
520 tuner_dbg("%s firmware for type=", (i < 0) ? "Can't find" : "Found");
521 if (debug) {
522 dump_firm_type(type);
523 printk("(%x), id %016llx.\n", type, (unsigned long long)*id);
524 }
525 return i;
526}
527
528static inline int do_tuner_callback(struct dvb_frontend *fe, int cmd, int arg)
529{
530 struct xc2028_data *priv = fe->tuner_priv;
531
532 /* analog side (tuner-core) uses i2c_adap->algo_data.
533 * digital side is not guaranteed to have algo_data defined.
534 *
535 * digital side will always have fe->dvb defined.
536 * analog side (tuner-core) doesn't (yet) define fe->dvb.
537 */
538
539 return (!fe->callback) ? -EINVAL :
540 fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
541 fe->dvb->priv : priv->i2c_props.adap->algo_data,
542 DVB_FRONTEND_COMPONENT_TUNER, cmd, arg);
543}
544
545static int load_firmware(struct dvb_frontend *fe, unsigned int type,
546 v4l2_std_id *id)
547{
548 struct xc2028_data *priv = fe->tuner_priv;
549 int pos, rc;
550 unsigned char *p, *endp, buf[priv->ctrl.max_len];
551
552 tuner_dbg("%s called\n", __func__);
553
554 pos = seek_firmware(fe, type, id);
555 if (pos < 0)
556 return pos;
557
558 tuner_info("Loading firmware for type=");
559 dump_firm_type(priv->firm[pos].type);
560 printk("(%x), id %016llx.\n", priv->firm[pos].type,
561 (unsigned long long)*id);
562
563 p = priv->firm[pos].ptr;
564 endp = p + priv->firm[pos].size;
565
566 while (p < endp) {
567 __u16 size;
568
569 /* Checks if there's enough bytes to read */
570 if (p + sizeof(size) > endp) {
571 tuner_err("Firmware chunk size is wrong\n");
572 return -EINVAL;
573 }
574
575 size = le16_to_cpu(*(__u16 *) p);
576 p += sizeof(size);
577
578 if (size == 0xffff)
579 return 0;
580
581 if (!size) {
582 /* Special callback command received */
583 rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0);
584 if (rc < 0) {
585 tuner_err("Error at RESET code %d\n",
586 (*p) & 0x7f);
587 return -EINVAL;
588 }
589 continue;
590 }
591 if (size >= 0xff00) {
592 switch (size) {
593 case 0xff00:
594 rc = do_tuner_callback(fe, XC2028_RESET_CLK, 0);
595 if (rc < 0) {
596 tuner_err("Error at RESET code %d\n",
597 (*p) & 0x7f);
598 return -EINVAL;
599 }
600 break;
601 default:
602 tuner_info("Invalid RESET code %d\n",
603 size & 0x7f);
604 return -EINVAL;
605
606 }
607 continue;
608 }
609
610 /* Checks for a sleep command */
611 if (size & 0x8000) {
612 msleep(size & 0x7fff);
613 continue;
614 }
615
616 if ((size + p > endp)) {
617 tuner_err("missing bytes: need %d, have %d\n",
618 size, (int)(endp - p));
619 return -EINVAL;
620 }
621
622 buf[0] = *p;
623 p++;
624 size--;
625
626 /* Sends message chunks */
627 while (size > 0) {
628 int len = (size < priv->ctrl.max_len - 1) ?
629 size : priv->ctrl.max_len - 1;
630
631 memcpy(buf + 1, p, len);
632
633 rc = i2c_send(priv, buf, len + 1);
634 if (rc < 0) {
635 tuner_err("%d returned from send\n", rc);
636 return -EINVAL;
637 }
638
639 p += len;
640 size -= len;
641 }
642
643 /* silently fail if the frontend doesn't support I2C flush */
644 rc = do_tuner_callback(fe, XC2028_I2C_FLUSH, 0);
645 if ((rc < 0) && (rc != -EINVAL)) {
646 tuner_err("error executing flush: %d\n", rc);
647 return rc;
648 }
649 }
650 return 0;
651}
652
653static int load_scode(struct dvb_frontend *fe, unsigned int type,
654 v4l2_std_id *id, __u16 int_freq, int scode)
655{
656 struct xc2028_data *priv = fe->tuner_priv;
657 int pos, rc;
658 unsigned char *p;
659
660 tuner_dbg("%s called\n", __func__);
661
662 if (!int_freq) {
663 pos = seek_firmware(fe, type, id);
664 if (pos < 0)
665 return pos;
666 } else {
667 for (pos = 0; pos < priv->firm_size; pos++) {
668 if ((priv->firm[pos].int_freq == int_freq) &&
669 (priv->firm[pos].type & HAS_IF))
670 break;
671 }
672 if (pos == priv->firm_size)
673 return -ENOENT;
674 }
675
676 p = priv->firm[pos].ptr;
677
678 if (priv->firm[pos].type & HAS_IF) {
679 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
680 return -EINVAL;
681 p += 12 * scode;
682 } else {
683 /* 16 SCODE entries per file; each SCODE entry is 12 bytes and
684 * has a 2-byte size header in the firmware format. */
685 if (priv->firm[pos].size != 14 * 16 || scode >= 16 ||
686 le16_to_cpu(*(__u16 *)(p + 14 * scode)) != 12)
687 return -EINVAL;
688 p += 14 * scode + 2;
689 }
690
691 tuner_info("Loading SCODE for type=");
692 dump_firm_type_and_int_freq(priv->firm[pos].type,
693 priv->firm[pos].int_freq);
694 printk("(%x), id %016llx.\n", priv->firm[pos].type,
695 (unsigned long long)*id);
696
697 if (priv->firm_version < 0x0202)
698 rc = send_seq(priv, {0x20, 0x00, 0x00, 0x00});
699 else
700 rc = send_seq(priv, {0xa0, 0x00, 0x00, 0x00});
701 if (rc < 0)
702 return -EIO;
703
704 rc = i2c_send(priv, p, 12);
705 if (rc < 0)
706 return -EIO;
707
708 rc = send_seq(priv, {0x00, 0x8c});
709 if (rc < 0)
710 return -EIO;
711
712 return 0;
713}
714
715static int check_firmware(struct dvb_frontend *fe, unsigned int type,
716 v4l2_std_id std, __u16 int_freq)
717{
718 struct xc2028_data *priv = fe->tuner_priv;
719 struct firmware_properties new_fw;
720 int rc, retry_count = 0;
721 u16 version, hwmodel;
722 v4l2_std_id std0;
723
724 tuner_dbg("%s called\n", __func__);
725
726 rc = check_device_status(priv);
727 if (rc < 0)
728 return rc;
729
730 if (priv->ctrl.mts && !(type & FM))
731 type |= MTS;
732
733retry:
734 new_fw.type = type;
735 new_fw.id = std;
736 new_fw.std_req = std;
737 new_fw.scode_table = SCODE | priv->ctrl.scode_table;
738 new_fw.scode_nr = 0;
739 new_fw.int_freq = int_freq;
740
741 tuner_dbg("checking firmware, user requested type=");
742 if (debug) {
743 dump_firm_type(new_fw.type);
744 printk("(%x), id %016llx, ", new_fw.type,
745 (unsigned long long)new_fw.std_req);
746 if (!int_freq) {
747 printk("scode_tbl ");
748 dump_firm_type(priv->ctrl.scode_table);
749 printk("(%x), ", priv->ctrl.scode_table);
750 } else
751 printk("int_freq %d, ", new_fw.int_freq);
752 printk("scode_nr %d\n", new_fw.scode_nr);
753 }
754
755 /*
756 * No need to reload base firmware if it matches and if the tuner
757 * is not at sleep mode
758 */
759 if ((priv->state == XC2028_ACTIVE) &&
760 (((BASE | new_fw.type) & BASE_TYPES) ==
761 (priv->cur_fw.type & BASE_TYPES))) {
762 tuner_dbg("BASE firmware not changed.\n");
763 goto skip_base;
764 }
765
766 /* Updating BASE - forget about all currently loaded firmware */
767 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
768
769 /* Reset is needed before loading firmware */
770 rc = do_tuner_callback(fe, XC2028_TUNER_RESET, 0);
771 if (rc < 0)
772 goto fail;
773
774 /* BASE firmwares are all std0 */
775 std0 = 0;
776 rc = load_firmware(fe, BASE | new_fw.type, &std0);
777 if (rc < 0) {
778 tuner_err("Error %d while loading base firmware\n",
779 rc);
780 goto fail;
781 }
782
783 /* Load INIT1, if needed */
784 tuner_dbg("Load init1 firmware, if exists\n");
785
786 rc = load_firmware(fe, BASE | INIT1 | new_fw.type, &std0);
787 if (rc == -ENOENT)
788 rc = load_firmware(fe, (BASE | INIT1 | new_fw.type) & ~F8MHZ,
789 &std0);
790 if (rc < 0 && rc != -ENOENT) {
791 tuner_err("Error %d while loading init1 firmware\n",
792 rc);
793 goto fail;
794 }
795
796skip_base:
797 /*
798 * No need to reload standard specific firmware if base firmware
799 * was not reloaded and requested video standards have not changed.
800 */
801 if (priv->cur_fw.type == (BASE | new_fw.type) &&
802 priv->cur_fw.std_req == std) {
803 tuner_dbg("Std-specific firmware already loaded.\n");
804 goto skip_std_specific;
805 }
806
807 /* Reloading std-specific firmware forces a SCODE update */
808 priv->cur_fw.scode_table = 0;
809
810 rc = load_firmware(fe, new_fw.type, &new_fw.id);
811 if (rc == -ENOENT)
812 rc = load_firmware(fe, new_fw.type & ~F8MHZ, &new_fw.id);
813
814 if (rc < 0)
815 goto fail;
816
817skip_std_specific:
818 if (priv->cur_fw.scode_table == new_fw.scode_table &&
819 priv->cur_fw.scode_nr == new_fw.scode_nr) {
820 tuner_dbg("SCODE firmware already loaded.\n");
821 goto check_device;
822 }
823
824 if (new_fw.type & FM)
825 goto check_device;
826
827 /* Load SCODE firmware, if exists */
828 tuner_dbg("Trying to load scode %d\n", new_fw.scode_nr);
829
830 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
831 new_fw.int_freq, new_fw.scode_nr);
832
833check_device:
834 if (xc2028_get_reg(priv, 0x0004, &version) < 0 ||
835 xc2028_get_reg(priv, 0x0008, &hwmodel) < 0) {
836 tuner_err("Unable to read tuner registers.\n");
837 goto fail;
838 }
839
840 tuner_dbg("Device is Xceive %d version %d.%d, "
841 "firmware version %d.%d\n",
842 hwmodel, (version & 0xf000) >> 12, (version & 0xf00) >> 8,
843 (version & 0xf0) >> 4, version & 0xf);
844
845
846 if (priv->ctrl.read_not_reliable)
847 goto read_not_reliable;
848
849 /* Check firmware version against what we downloaded. */
850 if (priv->firm_version != ((version & 0xf0) << 4 | (version & 0x0f))) {
851 if (!priv->ctrl.read_not_reliable) {
852 tuner_err("Incorrect readback of firmware version.\n");
853 goto fail;
854 } else {
855 tuner_err("Returned an incorrect version. However, "
856 "read is not reliable enough. Ignoring it.\n");
857 hwmodel = 3028;
858 }
859 }
860
861 /* Check that the tuner hardware model remains consistent over time. */
862 if (priv->hwmodel == 0 && (hwmodel == 2028 || hwmodel == 3028)) {
863 priv->hwmodel = hwmodel;
864 priv->hwvers = version & 0xff00;
865 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
866 priv->hwvers != (version & 0xff00)) {
867 tuner_err("Read invalid device hardware information - tuner "
868 "hung?\n");
869 goto fail;
870 }
871
872read_not_reliable:
873 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
874
875 /*
876 * By setting BASE in cur_fw.type only after successfully loading all
877 * firmwares, we can:
878 * 1. Identify that BASE firmware with type=0 has been loaded;
879 * 2. Tell whether BASE firmware was just changed the next time through.
880 */
881 priv->cur_fw.type |= BASE;
882 priv->state = XC2028_ACTIVE;
883
884 return 0;
885
886fail:
887 priv->state = XC2028_SLEEP;
888
889 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
890 if (retry_count < 8) {
891 msleep(50);
892 retry_count++;
893 tuner_dbg("Retrying firmware load\n");
894 goto retry;
895 }
896
897 if (rc == -ENOENT)
898 rc = -EINVAL;
899 return rc;
900}
901
902static int xc2028_signal(struct dvb_frontend *fe, u16 *strength)
903{
904 struct xc2028_data *priv = fe->tuner_priv;
905 u16 frq_lock, signal = 0;
906 int rc, i;
907
908 tuner_dbg("%s called\n", __func__);
909
910 rc = check_device_status(priv);
911 if (rc < 0)
912 return rc;
913
914 mutex_lock(&priv->lock);
915
916 /* Sync Lock Indicator */
917 for (i = 0; i < 3; i++) {
918 rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
919 if (rc < 0)
920 goto ret;
921
922 if (frq_lock)
923 break;
924 msleep(6);
925 }
926
927 /* Frequency didn't lock */
928 if (frq_lock == 2)
929 goto ret;
930
931 /* Get SNR of the video signal */
932 rc = xc2028_get_reg(priv, XREG_SNR, &signal);
933 if (rc < 0)
934 goto ret;
935
936 /* Signal level is 3 bits only */
937
938 signal = ((1 << 12) - 1) | ((signal & 0x07) << 12);
939
940ret:
941 mutex_unlock(&priv->lock);
942
943 *strength = signal;
944
945 tuner_dbg("signal strength is %d\n", signal);
946
947 return rc;
948}
949
950static int xc2028_get_afc(struct dvb_frontend *fe, s32 *afc)
951{
952 struct xc2028_data *priv = fe->tuner_priv;
953 int i, rc;
954 u16 frq_lock = 0;
955 s16 afc_reg = 0;
956
957 rc = check_device_status(priv);
958 if (rc < 0)
959 return rc;
960
961 mutex_lock(&priv->lock);
962
963 /* Sync Lock Indicator */
964 for (i = 0; i < 3; i++) {
965 rc = xc2028_get_reg(priv, XREG_LOCK, &frq_lock);
966 if (rc < 0)
967 goto ret;
968
969 if (frq_lock)
970 break;
971 msleep(6);
972 }
973
974 /* Frequency didn't lock */
975 if (frq_lock == 2)
976 goto ret;
977
978 /* Get AFC */
979 rc = xc2028_get_reg(priv, XREG_FREQ_ERROR, &afc_reg);
980 if (rc < 0)
981 goto ret;
982
983 *afc = afc_reg * 15625; /* Hz */
984
985 tuner_dbg("AFC is %d Hz\n", *afc);
986
987ret:
988 mutex_unlock(&priv->lock);
989
990 return rc;
991}
992
993#define DIV 15625
994
995static int generic_set_freq(struct dvb_frontend *fe, u32 freq /* in HZ */,
996 enum v4l2_tuner_type new_type,
997 unsigned int type,
998 v4l2_std_id std,
999 u16 int_freq)
1000{
1001 struct xc2028_data *priv = fe->tuner_priv;
1002 int rc = -EINVAL;
1003 unsigned char buf[4];
1004 u32 div, offset = 0;
1005
1006 tuner_dbg("%s called\n", __func__);
1007
1008 mutex_lock(&priv->lock);
1009
1010 tuner_dbg("should set frequency %d kHz\n", freq / 1000);
1011
1012 if (check_firmware(fe, type, std, int_freq) < 0)
1013 goto ret;
1014
1015 /* On some cases xc2028 can disable video output, if
1016 * very weak signals are received. By sending a soft
1017 * reset, this is re-enabled. So, it is better to always
1018 * send a soft reset before changing channels, to be sure
1019 * that xc2028 will be in a safe state.
1020 * Maybe this might also be needed for DTV.
1021 */
1022 switch (new_type) {
1023 case V4L2_TUNER_ANALOG_TV:
1024 rc = send_seq(priv, {0x00, 0x00});
1025
1026 /* Analog mode requires offset = 0 */
1027 break;
1028 case V4L2_TUNER_RADIO:
1029 /* Radio mode requires offset = 0 */
1030 break;
1031 case V4L2_TUNER_DIGITAL_TV:
1032 /*
1033 * Digital modes require an offset to adjust to the
1034 * proper frequency. The offset depends on what
1035 * firmware version is used.
1036 */
1037
1038 /*
1039 * Adjust to the center frequency. This is calculated by the
1040 * formula: offset = 1.25MHz - BW/2
1041 * For DTV 7/8, the firmware uses BW = 8000, so it needs a
1042 * further adjustment to get the frequency center on VHF
1043 */
1044
1045 /*
1046 * The firmware DTV78 used to work fine in UHF band (8 MHz
1047 * bandwidth) but not at all in VHF band (7 MHz bandwidth).
1048 * The real problem was connected to the formula used to
1049 * calculate the center frequency offset in VHF band.
1050 * In fact, removing the 500KHz adjustment fixed the problem.
1051 * This is coherent to what was implemented for the DTV7
1052 * firmware.
1053 * In the end, now the center frequency is the same for all 3
1054 * firmwares (DTV7, DTV8, DTV78) and doesn't depend on channel
1055 * bandwidth.
1056 */
1057
1058 if (priv->cur_fw.type & DTV6)
1059 offset = 1750000;
1060 else /* DTV7 or DTV8 or DTV78 */
1061 offset = 2750000;
1062
1063 /*
1064 * xc3028 additional "magic"
1065 * Depending on the firmware version, it needs some adjustments
1066 * to properly centralize the frequency. This seems to be
1067 * needed to compensate the SCODE table adjustments made by
1068 * newer firmwares
1069 */
1070
1071 /*
1072 * The proper adjustment would be to do it at s-code table.
1073 * However, this didn't work, as reported by
1074 * Robert Lowery <rglowery@exemail.com.au>
1075 */
1076
1077#if 0
1078 /*
1079 * Still need tests for XC3028L (firmware 3.2 or upper)
1080 * So, for now, let's just comment the per-firmware
1081 * version of this change. Reports with xc3028l working
1082 * with and without the lines bellow are welcome
1083 */
1084
1085 if (priv->firm_version < 0x0302) {
1086 if (priv->cur_fw.type & DTV7)
1087 offset += 500000;
1088 } else {
1089 if (priv->cur_fw.type & DTV7)
1090 offset -= 300000;
1091 else if (type != ATSC) /* DVB @6MHz, DTV 8 and DTV 7/8 */
1092 offset += 200000;
1093 }
1094#endif
1095 }
1096
1097 div = (freq - offset + DIV / 2) / DIV;
1098
1099 /* CMD= Set frequency */
1100 if (priv->firm_version < 0x0202)
1101 rc = send_seq(priv, {0x00, XREG_RF_FREQ, 0x00, 0x00});
1102 else
1103 rc = send_seq(priv, {0x80, XREG_RF_FREQ, 0x00, 0x00});
1104 if (rc < 0)
1105 goto ret;
1106
1107 /* Return code shouldn't be checked.
1108 The reset CLK is needed only with tm6000.
1109 Driver should work fine even if this fails.
1110 */
1111 if (priv->ctrl.msleep)
1112 msleep(priv->ctrl.msleep);
1113 do_tuner_callback(fe, XC2028_RESET_CLK, 1);
1114
1115 msleep(10);
1116
1117 buf[0] = 0xff & (div >> 24);
1118 buf[1] = 0xff & (div >> 16);
1119 buf[2] = 0xff & (div >> 8);
1120 buf[3] = 0xff & (div);
1121
1122 rc = i2c_send(priv, buf, sizeof(buf));
1123 if (rc < 0)
1124 goto ret;
1125 msleep(100);
1126
1127 priv->frequency = freq;
1128
1129 tuner_dbg("divisor= %*ph (freq=%d.%03d)\n", 4, buf,
1130 freq / 1000000, (freq % 1000000) / 1000);
1131
1132 rc = 0;
1133
1134ret:
1135 mutex_unlock(&priv->lock);
1136
1137 return rc;
1138}
1139
1140static int xc2028_set_analog_freq(struct dvb_frontend *fe,
1141 struct analog_parameters *p)
1142{
1143 struct xc2028_data *priv = fe->tuner_priv;
1144 unsigned int type=0;
1145
1146 tuner_dbg("%s called\n", __func__);
1147
1148 if (p->mode == V4L2_TUNER_RADIO) {
1149 type |= FM;
1150 if (priv->ctrl.input1)
1151 type |= INPUT1;
1152 return generic_set_freq(fe, (625l * p->frequency) / 10,
1153 V4L2_TUNER_RADIO, type, 0, 0);
1154 }
1155
1156 /* if std is not defined, choose one */
1157 if (!p->std)
1158 p->std = V4L2_STD_MN;
1159
1160 /* PAL/M, PAL/N, PAL/Nc and NTSC variants should use 6MHz firmware */
1161 if (!(p->std & V4L2_STD_MN))
1162 type |= F8MHZ;
1163
1164 /* Add audio hack to std mask */
1165 p->std |= parse_audio_std_option();
1166
1167 return generic_set_freq(fe, 62500l * p->frequency,
1168 V4L2_TUNER_ANALOG_TV, type, p->std, 0);
1169}
1170
1171static int xc2028_set_params(struct dvb_frontend *fe)
1172{
1173 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1174 u32 delsys = c->delivery_system;
1175 u32 bw = c->bandwidth_hz;
1176 struct xc2028_data *priv = fe->tuner_priv;
1177 int rc;
1178 unsigned int type = 0;
1179 u16 demod = 0;
1180
1181 tuner_dbg("%s called\n", __func__);
1182
1183 rc = check_device_status(priv);
1184 if (rc < 0)
1185 return rc;
1186
1187 switch (delsys) {
1188 case SYS_DVBT:
1189 case SYS_DVBT2:
1190 /*
1191 * The only countries with 6MHz seem to be Taiwan/Uruguay.
1192 * Both seem to require QAM firmware for OFDM decoding
1193 * Tested in Taiwan by Terry Wu <terrywu2009@gmail.com>
1194 */
1195 if (bw <= 6000000)
1196 type |= QAM;
1197
1198 switch (priv->ctrl.type) {
1199 case XC2028_D2633:
1200 type |= D2633;
1201 break;
1202 case XC2028_D2620:
1203 type |= D2620;
1204 break;
1205 case XC2028_AUTO:
1206 default:
1207 /* Zarlink seems to need D2633 */
1208 if (priv->ctrl.demod == XC3028_FE_ZARLINK456)
1209 type |= D2633;
1210 else
1211 type |= D2620;
1212 }
1213 break;
1214 case SYS_ATSC:
1215 /* The only ATSC firmware (at least on v2.7) is D2633 */
1216 type |= ATSC | D2633;
1217 break;
1218 /* DVB-S and pure QAM (FE_QAM) are not supported */
1219 default:
1220 return -EINVAL;
1221 }
1222
1223 if (bw <= 6000000) {
1224 type |= DTV6;
1225 priv->ctrl.vhfbw7 = 0;
1226 priv->ctrl.uhfbw8 = 0;
1227 } else if (bw <= 7000000) {
1228 if (c->frequency < 470000000)
1229 priv->ctrl.vhfbw7 = 1;
1230 else
1231 priv->ctrl.uhfbw8 = 0;
1232 type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV7;
1233 type |= F8MHZ;
1234 } else {
1235 if (c->frequency < 470000000)
1236 priv->ctrl.vhfbw7 = 0;
1237 else
1238 priv->ctrl.uhfbw8 = 1;
1239 type |= (priv->ctrl.vhfbw7 && priv->ctrl.uhfbw8) ? DTV78 : DTV8;
1240 type |= F8MHZ;
1241 }
1242
1243 /* All S-code tables need a 200kHz shift */
1244 if (priv->ctrl.demod) {
1245 demod = priv->ctrl.demod;
1246
1247 /*
1248 * Newer firmwares require a 200 kHz offset only for ATSC
1249 */
1250 if (type == ATSC || priv->firm_version < 0x0302)
1251 demod += 200;
1252 /*
1253 * The DTV7 S-code table needs a 700 kHz shift.
1254 *
1255 * DTV7 is only used in Australia. Germany or Italy may also
1256 * use this firmware after initialization, but a tune to a UHF
1257 * channel should then cause DTV78 to be used.
1258 *
1259 * Unfortunately, on real-field tests, the s-code offset
1260 * didn't work as expected, as reported by
1261 * Robert Lowery <rglowery@exemail.com.au>
1262 */
1263 }
1264
1265 return generic_set_freq(fe, c->frequency,
1266 V4L2_TUNER_DIGITAL_TV, type, 0, demod);
1267}
1268
1269static int xc2028_sleep(struct dvb_frontend *fe)
1270{
1271 struct xc2028_data *priv = fe->tuner_priv;
1272 int rc;
1273
1274 rc = check_device_status(priv);
1275 if (rc < 0)
1276 return rc;
1277
1278 /* Avoid firmware reload on slow devices or if PM disabled */
1279 if (no_poweroff || priv->ctrl.disable_power_mgmt)
1280 return 0;
1281
1282 tuner_dbg("Putting xc2028/3028 into poweroff mode.\n");
1283 if (debug > 1) {
1284 tuner_dbg("Printing sleep stack trace:\n");
1285 dump_stack();
1286 }
1287
1288 mutex_lock(&priv->lock);
1289
1290 if (priv->firm_version < 0x0202)
1291 rc = send_seq(priv, {0x00, XREG_POWER_DOWN, 0x00, 0x00});
1292 else
1293 rc = send_seq(priv, {0x80, XREG_POWER_DOWN, 0x00, 0x00});
1294
1295 priv->state = XC2028_SLEEP;
1296
1297 mutex_unlock(&priv->lock);
1298
1299 return rc;
1300}
1301
1302static int xc2028_dvb_release(struct dvb_frontend *fe)
1303{
1304 struct xc2028_data *priv = fe->tuner_priv;
1305
1306 tuner_dbg("%s called\n", __func__);
1307
1308 mutex_lock(&xc2028_list_mutex);
1309
1310 /* only perform final cleanup if this is the last instance */
1311 if (hybrid_tuner_report_instance_count(priv) == 1) {
1312 free_firmware(priv);
1313 kfree(priv->ctrl.fname);
1314 priv->ctrl.fname = NULL;
1315 }
1316
1317 if (priv)
1318 hybrid_tuner_release_state(priv);
1319
1320 mutex_unlock(&xc2028_list_mutex);
1321
1322 fe->tuner_priv = NULL;
1323
1324 return 0;
1325}
1326
1327static int xc2028_get_frequency(struct dvb_frontend *fe, u32 *frequency)
1328{
1329 struct xc2028_data *priv = fe->tuner_priv;
1330 int rc;
1331
1332 tuner_dbg("%s called\n", __func__);
1333
1334 rc = check_device_status(priv);
1335 if (rc < 0)
1336 return rc;
1337
1338 *frequency = priv->frequency;
1339
1340 return 0;
1341}
1342
1343static void load_firmware_cb(const struct firmware *fw,
1344 void *context)
1345{
1346 struct dvb_frontend *fe = context;
1347 struct xc2028_data *priv = fe->tuner_priv;
1348 int rc;
1349
1350 tuner_dbg("request_firmware_nowait(): %s\n", fw ? "OK" : "error");
1351 if (!fw) {
1352 tuner_err("Could not load firmware %s.\n", priv->fname);
1353 priv->state = XC2028_NODEV;
1354 return;
1355 }
1356
1357 rc = load_all_firmwares(fe, fw);
1358
1359 release_firmware(fw);
1360
1361 if (rc < 0)
1362 return;
1363 priv->state = XC2028_SLEEP;
1364}
1365
1366static int xc2028_set_config(struct dvb_frontend *fe, void *priv_cfg)
1367{
1368 struct xc2028_data *priv = fe->tuner_priv;
1369 struct xc2028_ctrl *p = priv_cfg;
1370 int rc = 0;
1371
1372 tuner_dbg("%s called\n", __func__);
1373
1374 mutex_lock(&priv->lock);
1375
1376 /*
1377 * Copy the config data.
1378 * For the firmware name, keep a local copy of the string,
1379 * in order to avoid troubles during device release.
1380 */
1381 if (priv->ctrl.fname)
1382 kfree(priv->ctrl.fname);
1383 memcpy(&priv->ctrl, p, sizeof(priv->ctrl));
1384 if (p->fname) {
1385 priv->ctrl.fname = kstrdup(p->fname, GFP_KERNEL);
1386 if (priv->ctrl.fname == NULL)
1387 rc = -ENOMEM;
1388 }
1389
1390 /*
1391 * If firmware name changed, frees firmware. As free_firmware will
1392 * reset the status to NO_FIRMWARE, this forces a new request_firmware
1393 */
1394 if (!firmware_name[0] && p->fname &&
1395 priv->fname && strcmp(p->fname, priv->fname))
1396 free_firmware(priv);
1397
1398 if (priv->ctrl.max_len < 9)
1399 priv->ctrl.max_len = 13;
1400
1401 if (priv->state == XC2028_NO_FIRMWARE) {
1402 if (!firmware_name[0])
1403 priv->fname = priv->ctrl.fname;
1404 else
1405 priv->fname = firmware_name;
1406
1407 rc = request_firmware_nowait(THIS_MODULE, 1,
1408 priv->fname,
1409 priv->i2c_props.adap->dev.parent,
1410 GFP_KERNEL,
1411 fe, load_firmware_cb);
1412 if (rc < 0) {
1413 tuner_err("Failed to request firmware %s\n",
1414 priv->fname);
1415 priv->state = XC2028_NODEV;
1416 } else
1417 priv->state = XC2028_WAITING_FIRMWARE;
1418 }
1419 mutex_unlock(&priv->lock);
1420
1421 return rc;
1422}
1423
1424static const struct dvb_tuner_ops xc2028_dvb_tuner_ops = {
1425 .info = {
1426 .name = "Xceive XC3028",
1427 .frequency_min = 42000000,
1428 .frequency_max = 864000000,
1429 .frequency_step = 50000,
1430 },
1431
1432 .set_config = xc2028_set_config,
1433 .set_analog_params = xc2028_set_analog_freq,
1434 .release = xc2028_dvb_release,
1435 .get_frequency = xc2028_get_frequency,
1436 .get_rf_strength = xc2028_signal,
1437 .get_afc = xc2028_get_afc,
1438 .set_params = xc2028_set_params,
1439 .sleep = xc2028_sleep,
1440};
1441
1442struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
1443 struct xc2028_config *cfg)
1444{
1445 struct xc2028_data *priv;
1446 int instance;
1447
1448 if (debug)
1449 printk(KERN_DEBUG "xc2028: Xcv2028/3028 init called!\n");
1450
1451 if (NULL == cfg)
1452 return NULL;
1453
1454 if (!fe) {
1455 printk(KERN_ERR "xc2028: No frontend!\n");
1456 return NULL;
1457 }
1458
1459 mutex_lock(&xc2028_list_mutex);
1460
1461 instance = hybrid_tuner_request_state(struct xc2028_data, priv,
1462 hybrid_tuner_instance_list,
1463 cfg->i2c_adap, cfg->i2c_addr,
1464 "xc2028");
1465 switch (instance) {
1466 case 0:
1467 /* memory allocation failure */
1468 goto fail;
1469 break;
1470 case 1:
1471 /* new tuner instance */
1472 priv->ctrl.max_len = 13;
1473
1474 mutex_init(&priv->lock);
1475
1476 fe->tuner_priv = priv;
1477 break;
1478 case 2:
1479 /* existing tuner instance */
1480 fe->tuner_priv = priv;
1481 break;
1482 }
1483
1484 memcpy(&fe->ops.tuner_ops, &xc2028_dvb_tuner_ops,
1485 sizeof(xc2028_dvb_tuner_ops));
1486
1487 tuner_info("type set to %s\n", "XCeive xc2028/xc3028 tuner");
1488
1489 if (cfg->ctrl)
1490 xc2028_set_config(fe, cfg->ctrl);
1491
1492 mutex_unlock(&xc2028_list_mutex);
1493
1494 return fe;
1495fail:
1496 mutex_unlock(&xc2028_list_mutex);
1497
1498 xc2028_dvb_release(fe);
1499 return NULL;
1500}
1501
1502EXPORT_SYMBOL(xc2028_attach);
1503
1504MODULE_DESCRIPTION("Xceive xc2028/xc3028 tuner driver");
1505MODULE_AUTHOR("Michel Ludwig <michel.ludwig@gmail.com>");
1506MODULE_AUTHOR("Mauro Carvalho Chehab <mchehab@infradead.org>");
1507MODULE_LICENSE("GPL");
1508MODULE_FIRMWARE(XC2028_DEFAULT_FIRMWARE);
1509MODULE_FIRMWARE(XC3028L_DEFAULT_FIRMWARE);
diff --git a/drivers/media/tuners/tuner-xc2028.h b/drivers/media/tuners/tuner-xc2028.h
new file mode 100644
index 000000000000..9ebfb2d0ff14
--- /dev/null
+++ b/drivers/media/tuners/tuner-xc2028.h
@@ -0,0 +1,72 @@
1/* tuner-xc2028
2 *
3 * Copyright (c) 2007-2008 Mauro Carvalho Chehab (mchehab@infradead.org)
4 * This code is placed under the terms of the GNU General Public License v2
5 */
6
7#ifndef __TUNER_XC2028_H__
8#define __TUNER_XC2028_H__
9
10#include "dvb_frontend.h"
11
12#define XC2028_DEFAULT_FIRMWARE "xc3028-v27.fw"
13#define XC3028L_DEFAULT_FIRMWARE "xc3028L-v36.fw"
14
15/* Dmoduler IF (kHz) */
16#define XC3028_FE_DEFAULT 0 /* Don't load SCODE */
17#define XC3028_FE_LG60 6000
18#define XC3028_FE_ATI638 6380
19#define XC3028_FE_OREN538 5380
20#define XC3028_FE_OREN36 3600
21#define XC3028_FE_TOYOTA388 3880
22#define XC3028_FE_TOYOTA794 7940
23#define XC3028_FE_DIBCOM52 5200
24#define XC3028_FE_ZARLINK456 4560
25#define XC3028_FE_CHINA 5200
26
27enum firmware_type {
28 XC2028_AUTO = 0, /* By default, auto-detects */
29 XC2028_D2633,
30 XC2028_D2620,
31};
32
33struct xc2028_ctrl {
34 char *fname;
35 int max_len;
36 int msleep;
37 unsigned int scode_table;
38 unsigned int mts :1;
39 unsigned int input1:1;
40 unsigned int vhfbw7:1;
41 unsigned int uhfbw8:1;
42 unsigned int disable_power_mgmt:1;
43 unsigned int read_not_reliable:1;
44 unsigned int demod;
45 enum firmware_type type:2;
46};
47
48struct xc2028_config {
49 struct i2c_adapter *i2c_adap;
50 u8 i2c_addr;
51 struct xc2028_ctrl *ctrl;
52};
53
54/* xc2028 commands for callback */
55#define XC2028_TUNER_RESET 0
56#define XC2028_RESET_CLK 1
57#define XC2028_I2C_FLUSH 2
58
59#if defined(CONFIG_MEDIA_TUNER_XC2028) || (defined(CONFIG_MEDIA_TUNER_XC2028_MODULE) && defined(MODULE))
60extern struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
61 struct xc2028_config *cfg);
62#else
63static inline struct dvb_frontend *xc2028_attach(struct dvb_frontend *fe,
64 struct xc2028_config *cfg)
65{
66 printk(KERN_INFO "%s: not probed - driver disabled by Kconfig\n",
67 __func__);
68 return NULL;
69}
70#endif
71
72#endif /* __TUNER_XC2028_H__ */
diff --git a/drivers/media/tuners/xc4000.c b/drivers/media/tuners/xc4000.c
new file mode 100644
index 000000000000..4937712278f6
--- /dev/null
+++ b/drivers/media/tuners/xc4000.c
@@ -0,0 +1,1757 @@
1/*
2 * Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2007 Xceive Corporation
5 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
6 * Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
7 * Copyright (c) 2009 Davide Ferri <d.ferri@zero11.it>
8 * Copyright (c) 2010 Istvan Varga <istvan_v@mailbox.hu>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/module.h>
26#include <linux/moduleparam.h>
27#include <linux/videodev2.h>
28#include <linux/delay.h>
29#include <linux/dvb/frontend.h>
30#include <linux/i2c.h>
31#include <linux/mutex.h>
32#include <asm/unaligned.h>
33
34#include "dvb_frontend.h"
35
36#include "xc4000.h"
37#include "tuner-i2c.h"
38#include "tuner-xc2028-types.h"
39
40static int debug;
41module_param(debug, int, 0644);
42MODULE_PARM_DESC(debug, "Debugging level (0 to 2, default: 0 (off)).");
43
44static int no_poweroff;
45module_param(no_poweroff, int, 0644);
46MODULE_PARM_DESC(no_poweroff, "Power management (1: disabled, 2: enabled, "
47 "0 (default): use device-specific default mode).");
48
49static int audio_std;
50module_param(audio_std, int, 0644);
51MODULE_PARM_DESC(audio_std, "Audio standard. XC4000 audio decoder explicitly "
52 "needs to know what audio standard is needed for some video standards "
53 "with audio A2 or NICAM. The valid settings are a sum of:\n"
54 " 1: use NICAM/B or A2/B instead of NICAM/A or A2/A\n"
55 " 2: use A2 instead of NICAM or BTSC\n"
56 " 4: use SECAM/K3 instead of K1\n"
57 " 8: use PAL-D/K audio for SECAM-D/K\n"
58 "16: use FM radio input 1 instead of input 2\n"
59 "32: use mono audio (the lower three bits are ignored)");
60
61static char firmware_name[30];
62module_param_string(firmware_name, firmware_name, sizeof(firmware_name), 0);
63MODULE_PARM_DESC(firmware_name, "Firmware file name. Allows overriding the "
64 "default firmware name.");
65
66static DEFINE_MUTEX(xc4000_list_mutex);
67static LIST_HEAD(hybrid_tuner_instance_list);
68
69#define dprintk(level, fmt, arg...) if (debug >= level) \
70 printk(KERN_INFO "%s: " fmt, "xc4000", ## arg)
71
72/* struct for storing firmware table */
73struct firmware_description {
74 unsigned int type;
75 v4l2_std_id id;
76 __u16 int_freq;
77 unsigned char *ptr;
78 unsigned int size;
79};
80
81struct firmware_properties {
82 unsigned int type;
83 v4l2_std_id id;
84 v4l2_std_id std_req;
85 __u16 int_freq;
86 unsigned int scode_table;
87 int scode_nr;
88};
89
90struct xc4000_priv {
91 struct tuner_i2c_props i2c_props;
92 struct list_head hybrid_tuner_instance_list;
93 struct firmware_description *firm;
94 int firm_size;
95 u32 if_khz;
96 u32 freq_hz;
97 u32 bandwidth;
98 u8 video_standard;
99 u8 rf_mode;
100 u8 default_pm;
101 u8 dvb_amplitude;
102 u8 set_smoothedcvbs;
103 u8 ignore_i2c_write_errors;
104 __u16 firm_version;
105 struct firmware_properties cur_fw;
106 __u16 hwmodel;
107 __u16 hwvers;
108 struct mutex lock;
109};
110
111#define XC4000_AUDIO_STD_B 1
112#define XC4000_AUDIO_STD_A2 2
113#define XC4000_AUDIO_STD_K3 4
114#define XC4000_AUDIO_STD_L 8
115#define XC4000_AUDIO_STD_INPUT1 16
116#define XC4000_AUDIO_STD_MONO 32
117
118#define XC4000_DEFAULT_FIRMWARE "dvb-fe-xc4000-1.4.fw"
119
120/* Misc Defines */
121#define MAX_TV_STANDARD 24
122#define XC_MAX_I2C_WRITE_LENGTH 64
123#define XC_POWERED_DOWN 0x80000000U
124
125/* Signal Types */
126#define XC_RF_MODE_AIR 0
127#define XC_RF_MODE_CABLE 1
128
129/* Product id */
130#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
131#define XC_PRODUCT_ID_XC4000 0x0FA0
132#define XC_PRODUCT_ID_XC4100 0x1004
133
134/* Registers (Write-only) */
135#define XREG_INIT 0x00
136#define XREG_VIDEO_MODE 0x01
137#define XREG_AUDIO_MODE 0x02
138#define XREG_RF_FREQ 0x03
139#define XREG_D_CODE 0x04
140#define XREG_DIRECTSITTING_MODE 0x05
141#define XREG_SEEK_MODE 0x06
142#define XREG_POWER_DOWN 0x08
143#define XREG_SIGNALSOURCE 0x0A
144#define XREG_SMOOTHEDCVBS 0x0E
145#define XREG_AMPLITUDE 0x10
146
147/* Registers (Read-only) */
148#define XREG_ADC_ENV 0x00
149#define XREG_QUALITY 0x01
150#define XREG_FRAME_LINES 0x02
151#define XREG_HSYNC_FREQ 0x03
152#define XREG_LOCK 0x04
153#define XREG_FREQ_ERROR 0x05
154#define XREG_SNR 0x06
155#define XREG_VERSION 0x07
156#define XREG_PRODUCT_ID 0x08
157#define XREG_SIGNAL_LEVEL 0x0A
158#define XREG_NOISE_LEVEL 0x0B
159
160/*
161 Basic firmware description. This will remain with
162 the driver for documentation purposes.
163
164 This represents an I2C firmware file encoded as a
165 string of unsigned char. Format is as follows:
166
167 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
168 char[1 ]=len0_LSB -> length of first write transaction
169 char[2 ]=data0 -> first byte to be sent
170 char[3 ]=data1
171 char[4 ]=data2
172 char[ ]=...
173 char[M ]=dataN -> last byte to be sent
174 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
175 char[M+2]=len1_LSB -> length of second write transaction
176 char[M+3]=data0
177 char[M+4]=data1
178 ...
179 etc.
180
181 The [len] value should be interpreted as follows:
182
183 len= len_MSB _ len_LSB
184 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
185 len=0000_0000_0000_0000 : Reset command: Do hardware reset
186 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
187 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
188
189 For the RESET and WAIT commands, the two following bytes will contain
190 immediately the length of the following transaction.
191*/
192
193struct XC_TV_STANDARD {
194 const char *Name;
195 u16 audio_mode;
196 u16 video_mode;
197 u16 int_freq;
198};
199
200/* Tuner standards */
201#define XC4000_MN_NTSC_PAL_BTSC 0
202#define XC4000_MN_NTSC_PAL_A2 1
203#define XC4000_MN_NTSC_PAL_EIAJ 2
204#define XC4000_MN_NTSC_PAL_Mono 3
205#define XC4000_BG_PAL_A2 4
206#define XC4000_BG_PAL_NICAM 5
207#define XC4000_BG_PAL_MONO 6
208#define XC4000_I_PAL_NICAM 7
209#define XC4000_I_PAL_NICAM_MONO 8
210#define XC4000_DK_PAL_A2 9
211#define XC4000_DK_PAL_NICAM 10
212#define XC4000_DK_PAL_MONO 11
213#define XC4000_DK_SECAM_A2DK1 12
214#define XC4000_DK_SECAM_A2LDK3 13
215#define XC4000_DK_SECAM_A2MONO 14
216#define XC4000_DK_SECAM_NICAM 15
217#define XC4000_L_SECAM_NICAM 16
218#define XC4000_LC_SECAM_NICAM 17
219#define XC4000_DTV6 18
220#define XC4000_DTV8 19
221#define XC4000_DTV7_8 20
222#define XC4000_DTV7 21
223#define XC4000_FM_Radio_INPUT2 22
224#define XC4000_FM_Radio_INPUT1 23
225
226static struct XC_TV_STANDARD xc4000_standard[MAX_TV_STANDARD] = {
227 {"M/N-NTSC/PAL-BTSC", 0x0000, 0x80A0, 4500},
228 {"M/N-NTSC/PAL-A2", 0x0000, 0x80A0, 4600},
229 {"M/N-NTSC/PAL-EIAJ", 0x0040, 0x80A0, 4500},
230 {"M/N-NTSC/PAL-Mono", 0x0078, 0x80A0, 4500},
231 {"B/G-PAL-A2", 0x0000, 0x8159, 5640},
232 {"B/G-PAL-NICAM", 0x0004, 0x8159, 5740},
233 {"B/G-PAL-MONO", 0x0078, 0x8159, 5500},
234 {"I-PAL-NICAM", 0x0080, 0x8049, 6240},
235 {"I-PAL-NICAM-MONO", 0x0078, 0x8049, 6000},
236 {"D/K-PAL-A2", 0x0000, 0x8049, 6380},
237 {"D/K-PAL-NICAM", 0x0080, 0x8049, 6200},
238 {"D/K-PAL-MONO", 0x0078, 0x8049, 6500},
239 {"D/K-SECAM-A2 DK1", 0x0000, 0x8049, 6340},
240 {"D/K-SECAM-A2 L/DK3", 0x0000, 0x8049, 6000},
241 {"D/K-SECAM-A2 MONO", 0x0078, 0x8049, 6500},
242 {"D/K-SECAM-NICAM", 0x0080, 0x8049, 6200},
243 {"L-SECAM-NICAM", 0x8080, 0x0009, 6200},
244 {"L'-SECAM-NICAM", 0x8080, 0x4009, 6200},
245 {"DTV6", 0x00C0, 0x8002, 0},
246 {"DTV8", 0x00C0, 0x800B, 0},
247 {"DTV7/8", 0x00C0, 0x801B, 0},
248 {"DTV7", 0x00C0, 0x8007, 0},
249 {"FM Radio-INPUT2", 0x0008, 0x9800, 10700},
250 {"FM Radio-INPUT1", 0x0008, 0x9000, 10700}
251};
252
253static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val);
254static int xc4000_tuner_reset(struct dvb_frontend *fe);
255static void xc_debug_dump(struct xc4000_priv *priv);
256
257static int xc_send_i2c_data(struct xc4000_priv *priv, u8 *buf, int len)
258{
259 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
260 .flags = 0, .buf = buf, .len = len };
261 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
262 if (priv->ignore_i2c_write_errors == 0) {
263 printk(KERN_ERR "xc4000: I2C write failed (len=%i)\n",
264 len);
265 if (len == 4) {
266 printk(KERN_ERR "bytes %*ph\n", 4, buf);
267 }
268 return -EREMOTEIO;
269 }
270 }
271 return 0;
272}
273
274static int xc4000_tuner_reset(struct dvb_frontend *fe)
275{
276 struct xc4000_priv *priv = fe->tuner_priv;
277 int ret;
278
279 dprintk(1, "%s()\n", __func__);
280
281 if (fe->callback) {
282 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
283 fe->dvb->priv :
284 priv->i2c_props.adap->algo_data,
285 DVB_FRONTEND_COMPONENT_TUNER,
286 XC4000_TUNER_RESET, 0);
287 if (ret) {
288 printk(KERN_ERR "xc4000: reset failed\n");
289 return -EREMOTEIO;
290 }
291 } else {
292 printk(KERN_ERR "xc4000: no tuner reset callback function, "
293 "fatal\n");
294 return -EINVAL;
295 }
296 return 0;
297}
298
299static int xc_write_reg(struct xc4000_priv *priv, u16 regAddr, u16 i2cData)
300{
301 u8 buf[4];
302 int result;
303
304 buf[0] = (regAddr >> 8) & 0xFF;
305 buf[1] = regAddr & 0xFF;
306 buf[2] = (i2cData >> 8) & 0xFF;
307 buf[3] = i2cData & 0xFF;
308 result = xc_send_i2c_data(priv, buf, 4);
309
310 return result;
311}
312
313static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
314{
315 struct xc4000_priv *priv = fe->tuner_priv;
316
317 int i, nbytes_to_send, result;
318 unsigned int len, pos, index;
319 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
320
321 index = 0;
322 while ((i2c_sequence[index] != 0xFF) ||
323 (i2c_sequence[index + 1] != 0xFF)) {
324 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
325 if (len == 0x0000) {
326 /* RESET command */
327 /* NOTE: this is ignored, as the reset callback was */
328 /* already called by check_firmware() */
329 index += 2;
330 } else if (len & 0x8000) {
331 /* WAIT command */
332 msleep(len & 0x7FFF);
333 index += 2;
334 } else {
335 /* Send i2c data whilst ensuring individual transactions
336 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
337 */
338 index += 2;
339 buf[0] = i2c_sequence[index];
340 buf[1] = i2c_sequence[index + 1];
341 pos = 2;
342 while (pos < len) {
343 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
344 nbytes_to_send =
345 XC_MAX_I2C_WRITE_LENGTH;
346 else
347 nbytes_to_send = (len - pos + 2);
348 for (i = 2; i < nbytes_to_send; i++) {
349 buf[i] = i2c_sequence[index + pos +
350 i - 2];
351 }
352 result = xc_send_i2c_data(priv, buf,
353 nbytes_to_send);
354
355 if (result != 0)
356 return result;
357
358 pos += nbytes_to_send - 2;
359 }
360 index += len;
361 }
362 }
363 return 0;
364}
365
366static int xc_set_tv_standard(struct xc4000_priv *priv,
367 u16 video_mode, u16 audio_mode)
368{
369 int ret;
370 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, video_mode, audio_mode);
371 dprintk(1, "%s() Standard = %s\n",
372 __func__,
373 xc4000_standard[priv->video_standard].Name);
374
375 /* Don't complain when the request fails because of i2c stretching */
376 priv->ignore_i2c_write_errors = 1;
377
378 ret = xc_write_reg(priv, XREG_VIDEO_MODE, video_mode);
379 if (ret == 0)
380 ret = xc_write_reg(priv, XREG_AUDIO_MODE, audio_mode);
381
382 priv->ignore_i2c_write_errors = 0;
383
384 return ret;
385}
386
387static int xc_set_signal_source(struct xc4000_priv *priv, u16 rf_mode)
388{
389 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
390 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
391
392 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
393 rf_mode = XC_RF_MODE_CABLE;
394 printk(KERN_ERR
395 "%s(), Invalid mode, defaulting to CABLE",
396 __func__);
397 }
398 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
399}
400
401static const struct dvb_tuner_ops xc4000_tuner_ops;
402
403static int xc_set_rf_frequency(struct xc4000_priv *priv, u32 freq_hz)
404{
405 u16 freq_code;
406
407 dprintk(1, "%s(%u)\n", __func__, freq_hz);
408
409 if ((freq_hz > xc4000_tuner_ops.info.frequency_max) ||
410 (freq_hz < xc4000_tuner_ops.info.frequency_min))
411 return -EINVAL;
412
413 freq_code = (u16)(freq_hz / 15625);
414
415 /* WAS: Starting in firmware version 1.1.44, Xceive recommends using the
416 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
417 only be used for fast scanning for channel lock) */
418 /* WAS: XREG_FINERFREQ */
419 return xc_write_reg(priv, XREG_RF_FREQ, freq_code);
420}
421
422static int xc_get_adc_envelope(struct xc4000_priv *priv, u16 *adc_envelope)
423{
424 return xc4000_readreg(priv, XREG_ADC_ENV, adc_envelope);
425}
426
427static int xc_get_frequency_error(struct xc4000_priv *priv, u32 *freq_error_hz)
428{
429 int result;
430 u16 regData;
431 u32 tmp;
432
433 result = xc4000_readreg(priv, XREG_FREQ_ERROR, &regData);
434 if (result != 0)
435 return result;
436
437 tmp = (u32)regData & 0xFFFFU;
438 tmp = (tmp < 0x8000U ? tmp : 0x10000U - tmp);
439 (*freq_error_hz) = tmp * 15625;
440 return result;
441}
442
443static int xc_get_lock_status(struct xc4000_priv *priv, u16 *lock_status)
444{
445 return xc4000_readreg(priv, XREG_LOCK, lock_status);
446}
447
448static int xc_get_version(struct xc4000_priv *priv,
449 u8 *hw_majorversion, u8 *hw_minorversion,
450 u8 *fw_majorversion, u8 *fw_minorversion)
451{
452 u16 data;
453 int result;
454
455 result = xc4000_readreg(priv, XREG_VERSION, &data);
456 if (result != 0)
457 return result;
458
459 (*hw_majorversion) = (data >> 12) & 0x0F;
460 (*hw_minorversion) = (data >> 8) & 0x0F;
461 (*fw_majorversion) = (data >> 4) & 0x0F;
462 (*fw_minorversion) = data & 0x0F;
463
464 return 0;
465}
466
467static int xc_get_hsync_freq(struct xc4000_priv *priv, u32 *hsync_freq_hz)
468{
469 u16 regData;
470 int result;
471
472 result = xc4000_readreg(priv, XREG_HSYNC_FREQ, &regData);
473 if (result != 0)
474 return result;
475
476 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
477 return result;
478}
479
480static int xc_get_frame_lines(struct xc4000_priv *priv, u16 *frame_lines)
481{
482 return xc4000_readreg(priv, XREG_FRAME_LINES, frame_lines);
483}
484
485static int xc_get_quality(struct xc4000_priv *priv, u16 *quality)
486{
487 return xc4000_readreg(priv, XREG_QUALITY, quality);
488}
489
490static int xc_get_signal_level(struct xc4000_priv *priv, u16 *signal)
491{
492 return xc4000_readreg(priv, XREG_SIGNAL_LEVEL, signal);
493}
494
495static int xc_get_noise_level(struct xc4000_priv *priv, u16 *noise)
496{
497 return xc4000_readreg(priv, XREG_NOISE_LEVEL, noise);
498}
499
500static u16 xc_wait_for_lock(struct xc4000_priv *priv)
501{
502 u16 lock_state = 0;
503 int watchdog_count = 40;
504
505 while ((lock_state == 0) && (watchdog_count > 0)) {
506 xc_get_lock_status(priv, &lock_state);
507 if (lock_state != 1) {
508 msleep(5);
509 watchdog_count--;
510 }
511 }
512 return lock_state;
513}
514
515static int xc_tune_channel(struct xc4000_priv *priv, u32 freq_hz)
516{
517 int found = 1;
518 int result;
519
520 dprintk(1, "%s(%u)\n", __func__, freq_hz);
521
522 /* Don't complain when the request fails because of i2c stretching */
523 priv->ignore_i2c_write_errors = 1;
524 result = xc_set_rf_frequency(priv, freq_hz);
525 priv->ignore_i2c_write_errors = 0;
526
527 if (result != 0)
528 return 0;
529
530 /* wait for lock only in analog TV mode */
531 if ((priv->cur_fw.type & (FM | DTV6 | DTV7 | DTV78 | DTV8)) == 0) {
532 if (xc_wait_for_lock(priv) != 1)
533 found = 0;
534 }
535
536 /* Wait for stats to stabilize.
537 * Frame Lines needs two frame times after initial lock
538 * before it is valid.
539 */
540 msleep(debug ? 100 : 10);
541
542 if (debug)
543 xc_debug_dump(priv);
544
545 return found;
546}
547
548static int xc4000_readreg(struct xc4000_priv *priv, u16 reg, u16 *val)
549{
550 u8 buf[2] = { reg >> 8, reg & 0xff };
551 u8 bval[2] = { 0, 0 };
552 struct i2c_msg msg[2] = {
553 { .addr = priv->i2c_props.addr,
554 .flags = 0, .buf = &buf[0], .len = 2 },
555 { .addr = priv->i2c_props.addr,
556 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
557 };
558
559 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
560 printk(KERN_ERR "xc4000: I2C read failed\n");
561 return -EREMOTEIO;
562 }
563
564 *val = (bval[0] << 8) | bval[1];
565 return 0;
566}
567
568#define dump_firm_type(t) dump_firm_type_and_int_freq(t, 0)
569static void dump_firm_type_and_int_freq(unsigned int type, u16 int_freq)
570{
571 if (type & BASE)
572 printk(KERN_CONT "BASE ");
573 if (type & INIT1)
574 printk(KERN_CONT "INIT1 ");
575 if (type & F8MHZ)
576 printk(KERN_CONT "F8MHZ ");
577 if (type & MTS)
578 printk(KERN_CONT "MTS ");
579 if (type & D2620)
580 printk(KERN_CONT "D2620 ");
581 if (type & D2633)
582 printk(KERN_CONT "D2633 ");
583 if (type & DTV6)
584 printk(KERN_CONT "DTV6 ");
585 if (type & QAM)
586 printk(KERN_CONT "QAM ");
587 if (type & DTV7)
588 printk(KERN_CONT "DTV7 ");
589 if (type & DTV78)
590 printk(KERN_CONT "DTV78 ");
591 if (type & DTV8)
592 printk(KERN_CONT "DTV8 ");
593 if (type & FM)
594 printk(KERN_CONT "FM ");
595 if (type & INPUT1)
596 printk(KERN_CONT "INPUT1 ");
597 if (type & LCD)
598 printk(KERN_CONT "LCD ");
599 if (type & NOGD)
600 printk(KERN_CONT "NOGD ");
601 if (type & MONO)
602 printk(KERN_CONT "MONO ");
603 if (type & ATSC)
604 printk(KERN_CONT "ATSC ");
605 if (type & IF)
606 printk(KERN_CONT "IF ");
607 if (type & LG60)
608 printk(KERN_CONT "LG60 ");
609 if (type & ATI638)
610 printk(KERN_CONT "ATI638 ");
611 if (type & OREN538)
612 printk(KERN_CONT "OREN538 ");
613 if (type & OREN36)
614 printk(KERN_CONT "OREN36 ");
615 if (type & TOYOTA388)
616 printk(KERN_CONT "TOYOTA388 ");
617 if (type & TOYOTA794)
618 printk(KERN_CONT "TOYOTA794 ");
619 if (type & DIBCOM52)
620 printk(KERN_CONT "DIBCOM52 ");
621 if (type & ZARLINK456)
622 printk(KERN_CONT "ZARLINK456 ");
623 if (type & CHINA)
624 printk(KERN_CONT "CHINA ");
625 if (type & F6MHZ)
626 printk(KERN_CONT "F6MHZ ");
627 if (type & INPUT2)
628 printk(KERN_CONT "INPUT2 ");
629 if (type & SCODE)
630 printk(KERN_CONT "SCODE ");
631 if (type & HAS_IF)
632 printk(KERN_CONT "HAS_IF_%d ", int_freq);
633}
634
635static int seek_firmware(struct dvb_frontend *fe, unsigned int type,
636 v4l2_std_id *id)
637{
638 struct xc4000_priv *priv = fe->tuner_priv;
639 int i, best_i = -1;
640 unsigned int best_nr_diffs = 255U;
641
642 if (!priv->firm) {
643 printk(KERN_ERR "Error! firmware not loaded\n");
644 return -EINVAL;
645 }
646
647 if (((type & ~SCODE) == 0) && (*id == 0))
648 *id = V4L2_STD_PAL;
649
650 /* Seek for generic video standard match */
651 for (i = 0; i < priv->firm_size; i++) {
652 v4l2_std_id id_diff_mask =
653 (priv->firm[i].id ^ (*id)) & (*id);
654 unsigned int type_diff_mask =
655 (priv->firm[i].type ^ type)
656 & (BASE_TYPES | DTV_TYPES | LCD | NOGD | MONO | SCODE);
657 unsigned int nr_diffs;
658
659 if (type_diff_mask
660 & (BASE | INIT1 | FM | DTV6 | DTV7 | DTV78 | DTV8 | SCODE))
661 continue;
662
663 nr_diffs = hweight64(id_diff_mask) + hweight32(type_diff_mask);
664 if (!nr_diffs) /* Supports all the requested standards */
665 goto found;
666
667 if (nr_diffs < best_nr_diffs) {
668 best_nr_diffs = nr_diffs;
669 best_i = i;
670 }
671 }
672
673 /* FIXME: Would make sense to seek for type "hint" match ? */
674 if (best_i < 0) {
675 i = -ENOENT;
676 goto ret;
677 }
678
679 if (best_nr_diffs > 0U) {
680 printk(KERN_WARNING
681 "Selecting best matching firmware (%u bits differ) for "
682 "type=(%x), id %016llx:\n",
683 best_nr_diffs, type, (unsigned long long)*id);
684 i = best_i;
685 }
686
687found:
688 *id = priv->firm[i].id;
689
690ret:
691 if (debug) {
692 printk(KERN_DEBUG "%s firmware for type=",
693 (i < 0) ? "Can't find" : "Found");
694 dump_firm_type(type);
695 printk(KERN_DEBUG "(%x), id %016llx.\n", type, (unsigned long long)*id);
696 }
697 return i;
698}
699
700static int load_firmware(struct dvb_frontend *fe, unsigned int type,
701 v4l2_std_id *id)
702{
703 struct xc4000_priv *priv = fe->tuner_priv;
704 int pos, rc;
705 unsigned char *p;
706
707 pos = seek_firmware(fe, type, id);
708 if (pos < 0)
709 return pos;
710
711 p = priv->firm[pos].ptr;
712
713 /* Don't complain when the request fails because of i2c stretching */
714 priv->ignore_i2c_write_errors = 1;
715
716 rc = xc_load_i2c_sequence(fe, p);
717
718 priv->ignore_i2c_write_errors = 0;
719
720 return rc;
721}
722
723static int xc4000_fwupload(struct dvb_frontend *fe)
724{
725 struct xc4000_priv *priv = fe->tuner_priv;
726 const struct firmware *fw = NULL;
727 const unsigned char *p, *endp;
728 int rc = 0;
729 int n, n_array;
730 char name[33];
731 const char *fname;
732
733 if (firmware_name[0] != '\0')
734 fname = firmware_name;
735 else
736 fname = XC4000_DEFAULT_FIRMWARE;
737
738 dprintk(1, "Reading firmware %s\n", fname);
739 rc = request_firmware(&fw, fname, priv->i2c_props.adap->dev.parent);
740 if (rc < 0) {
741 if (rc == -ENOENT)
742 printk(KERN_ERR "Error: firmware %s not found.\n", fname);
743 else
744 printk(KERN_ERR "Error %d while requesting firmware %s\n",
745 rc, fname);
746
747 return rc;
748 }
749 p = fw->data;
750 endp = p + fw->size;
751
752 if (fw->size < sizeof(name) - 1 + 2 + 2) {
753 printk(KERN_ERR "Error: firmware file %s has invalid size!\n",
754 fname);
755 goto corrupt;
756 }
757
758 memcpy(name, p, sizeof(name) - 1);
759 name[sizeof(name) - 1] = '\0';
760 p += sizeof(name) - 1;
761
762 priv->firm_version = get_unaligned_le16(p);
763 p += 2;
764
765 n_array = get_unaligned_le16(p);
766 p += 2;
767
768 dprintk(1, "Loading %d firmware images from %s, type: %s, ver %d.%d\n",
769 n_array, fname, name,
770 priv->firm_version >> 8, priv->firm_version & 0xff);
771
772 priv->firm = kcalloc(n_array, sizeof(*priv->firm), GFP_KERNEL);
773 if (priv->firm == NULL) {
774 printk(KERN_ERR "Not enough memory to load firmware file.\n");
775 rc = -ENOMEM;
776 goto done;
777 }
778 priv->firm_size = n_array;
779
780 n = -1;
781 while (p < endp) {
782 __u32 type, size;
783 v4l2_std_id id;
784 __u16 int_freq = 0;
785
786 n++;
787 if (n >= n_array) {
788 printk(KERN_ERR "More firmware images in file than "
789 "were expected!\n");
790 goto corrupt;
791 }
792
793 /* Checks if there's enough bytes to read */
794 if (endp - p < sizeof(type) + sizeof(id) + sizeof(size))
795 goto header;
796
797 type = get_unaligned_le32(p);
798 p += sizeof(type);
799
800 id = get_unaligned_le64(p);
801 p += sizeof(id);
802
803 if (type & HAS_IF) {
804 int_freq = get_unaligned_le16(p);
805 p += sizeof(int_freq);
806 if (endp - p < sizeof(size))
807 goto header;
808 }
809
810 size = get_unaligned_le32(p);
811 p += sizeof(size);
812
813 if (!size || size > endp - p) {
814 printk(KERN_ERR "Firmware type (%x), id %llx is corrupted (size=%d, expected %d)\n",
815 type, (unsigned long long)id,
816 (unsigned)(endp - p), size);
817 goto corrupt;
818 }
819
820 priv->firm[n].ptr = kzalloc(size, GFP_KERNEL);
821 if (priv->firm[n].ptr == NULL) {
822 printk(KERN_ERR "Not enough memory to load firmware file.\n");
823 rc = -ENOMEM;
824 goto done;
825 }
826
827 if (debug) {
828 printk(KERN_DEBUG "Reading firmware type ");
829 dump_firm_type_and_int_freq(type, int_freq);
830 printk(KERN_DEBUG "(%x), id %llx, size=%d.\n",
831 type, (unsigned long long)id, size);
832 }
833
834 memcpy(priv->firm[n].ptr, p, size);
835 priv->firm[n].type = type;
836 priv->firm[n].id = id;
837 priv->firm[n].size = size;
838 priv->firm[n].int_freq = int_freq;
839
840 p += size;
841 }
842
843 if (n + 1 != priv->firm_size) {
844 printk(KERN_ERR "Firmware file is incomplete!\n");
845 goto corrupt;
846 }
847
848 goto done;
849
850header:
851 printk(KERN_ERR "Firmware header is incomplete!\n");
852corrupt:
853 rc = -EINVAL;
854 printk(KERN_ERR "Error: firmware file is corrupted!\n");
855
856done:
857 release_firmware(fw);
858 if (rc == 0)
859 dprintk(1, "Firmware files loaded.\n");
860
861 return rc;
862}
863
864static int load_scode(struct dvb_frontend *fe, unsigned int type,
865 v4l2_std_id *id, __u16 int_freq, int scode)
866{
867 struct xc4000_priv *priv = fe->tuner_priv;
868 int pos, rc;
869 unsigned char *p;
870 u8 scode_buf[13];
871 u8 indirect_mode[5];
872
873 dprintk(1, "%s called int_freq=%d\n", __func__, int_freq);
874
875 if (!int_freq) {
876 pos = seek_firmware(fe, type, id);
877 if (pos < 0)
878 return pos;
879 } else {
880 for (pos = 0; pos < priv->firm_size; pos++) {
881 if ((priv->firm[pos].int_freq == int_freq) &&
882 (priv->firm[pos].type & HAS_IF))
883 break;
884 }
885 if (pos == priv->firm_size)
886 return -ENOENT;
887 }
888
889 p = priv->firm[pos].ptr;
890
891 if (priv->firm[pos].size != 12 * 16 || scode >= 16)
892 return -EINVAL;
893 p += 12 * scode;
894
895 if (debug) {
896 tuner_info("Loading SCODE for type=");
897 dump_firm_type_and_int_freq(priv->firm[pos].type,
898 priv->firm[pos].int_freq);
899 printk(KERN_CONT "(%x), id %016llx.\n", priv->firm[pos].type,
900 (unsigned long long)*id);
901 }
902
903 scode_buf[0] = 0x00;
904 memcpy(&scode_buf[1], p, 12);
905
906 /* Enter direct-mode */
907 rc = xc_write_reg(priv, XREG_DIRECTSITTING_MODE, 0);
908 if (rc < 0) {
909 printk(KERN_ERR "failed to put device into direct mode!\n");
910 return -EIO;
911 }
912
913 rc = xc_send_i2c_data(priv, scode_buf, 13);
914 if (rc != 0) {
915 /* Even if the send failed, make sure we set back to indirect
916 mode */
917 printk(KERN_ERR "Failed to set scode %d\n", rc);
918 }
919
920 /* Switch back to indirect-mode */
921 memset(indirect_mode, 0, sizeof(indirect_mode));
922 indirect_mode[4] = 0x88;
923 xc_send_i2c_data(priv, indirect_mode, sizeof(indirect_mode));
924 msleep(10);
925
926 return 0;
927}
928
929static int check_firmware(struct dvb_frontend *fe, unsigned int type,
930 v4l2_std_id std, __u16 int_freq)
931{
932 struct xc4000_priv *priv = fe->tuner_priv;
933 struct firmware_properties new_fw;
934 int rc = 0, is_retry = 0;
935 u16 hwmodel;
936 v4l2_std_id std0;
937 u8 hw_major, hw_minor, fw_major, fw_minor;
938
939 dprintk(1, "%s called\n", __func__);
940
941 if (!priv->firm) {
942 rc = xc4000_fwupload(fe);
943 if (rc < 0)
944 return rc;
945 }
946
947retry:
948 new_fw.type = type;
949 new_fw.id = std;
950 new_fw.std_req = std;
951 new_fw.scode_table = SCODE;
952 new_fw.scode_nr = 0;
953 new_fw.int_freq = int_freq;
954
955 dprintk(1, "checking firmware, user requested type=");
956 if (debug) {
957 dump_firm_type(new_fw.type);
958 printk(KERN_CONT "(%x), id %016llx, ", new_fw.type,
959 (unsigned long long)new_fw.std_req);
960 if (!int_freq)
961 printk(KERN_CONT "scode_tbl ");
962 else
963 printk(KERN_CONT "int_freq %d, ", new_fw.int_freq);
964 printk(KERN_CONT "scode_nr %d\n", new_fw.scode_nr);
965 }
966
967 /* No need to reload base firmware if it matches */
968 if (priv->cur_fw.type & BASE) {
969 dprintk(1, "BASE firmware not changed.\n");
970 goto skip_base;
971 }
972
973 /* Updating BASE - forget about all currently loaded firmware */
974 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
975
976 /* Reset is needed before loading firmware */
977 rc = xc4000_tuner_reset(fe);
978 if (rc < 0)
979 goto fail;
980
981 /* BASE firmwares are all std0 */
982 std0 = 0;
983 rc = load_firmware(fe, BASE, &std0);
984 if (rc < 0) {
985 printk(KERN_ERR "Error %d while loading base firmware\n", rc);
986 goto fail;
987 }
988
989 /* Load INIT1, if needed */
990 dprintk(1, "Load init1 firmware, if exists\n");
991
992 rc = load_firmware(fe, BASE | INIT1, &std0);
993 if (rc == -ENOENT)
994 rc = load_firmware(fe, BASE | INIT1, &std0);
995 if (rc < 0 && rc != -ENOENT) {
996 tuner_err("Error %d while loading init1 firmware\n",
997 rc);
998 goto fail;
999 }
1000
1001skip_base:
1002 /*
1003 * No need to reload standard specific firmware if base firmware
1004 * was not reloaded and requested video standards have not changed.
1005 */
1006 if (priv->cur_fw.type == (BASE | new_fw.type) &&
1007 priv->cur_fw.std_req == std) {
1008 dprintk(1, "Std-specific firmware already loaded.\n");
1009 goto skip_std_specific;
1010 }
1011
1012 /* Reloading std-specific firmware forces a SCODE update */
1013 priv->cur_fw.scode_table = 0;
1014
1015 /* Load the standard firmware */
1016 rc = load_firmware(fe, new_fw.type, &new_fw.id);
1017
1018 if (rc < 0)
1019 goto fail;
1020
1021skip_std_specific:
1022 if (priv->cur_fw.scode_table == new_fw.scode_table &&
1023 priv->cur_fw.scode_nr == new_fw.scode_nr) {
1024 dprintk(1, "SCODE firmware already loaded.\n");
1025 goto check_device;
1026 }
1027
1028 /* Load SCODE firmware, if exists */
1029 rc = load_scode(fe, new_fw.type | new_fw.scode_table, &new_fw.id,
1030 new_fw.int_freq, new_fw.scode_nr);
1031 if (rc != 0)
1032 dprintk(1, "load scode failed %d\n", rc);
1033
1034check_device:
1035 rc = xc4000_readreg(priv, XREG_PRODUCT_ID, &hwmodel);
1036
1037 if (xc_get_version(priv, &hw_major, &hw_minor, &fw_major,
1038 &fw_minor) != 0) {
1039 printk(KERN_ERR "Unable to read tuner registers.\n");
1040 goto fail;
1041 }
1042
1043 dprintk(1, "Device is Xceive %d version %d.%d, "
1044 "firmware version %d.%d\n",
1045 hwmodel, hw_major, hw_minor, fw_major, fw_minor);
1046
1047 /* Check firmware version against what we downloaded. */
1048 if (priv->firm_version != ((fw_major << 8) | fw_minor)) {
1049 printk(KERN_WARNING
1050 "Incorrect readback of firmware version %d.%d.\n",
1051 fw_major, fw_minor);
1052 goto fail;
1053 }
1054
1055 /* Check that the tuner hardware model remains consistent over time. */
1056 if (priv->hwmodel == 0 &&
1057 (hwmodel == XC_PRODUCT_ID_XC4000 ||
1058 hwmodel == XC_PRODUCT_ID_XC4100)) {
1059 priv->hwmodel = hwmodel;
1060 priv->hwvers = (hw_major << 8) | hw_minor;
1061 } else if (priv->hwmodel == 0 || priv->hwmodel != hwmodel ||
1062 priv->hwvers != ((hw_major << 8) | hw_minor)) {
1063 printk(KERN_WARNING
1064 "Read invalid device hardware information - tuner "
1065 "hung?\n");
1066 goto fail;
1067 }
1068
1069 memcpy(&priv->cur_fw, &new_fw, sizeof(priv->cur_fw));
1070
1071 /*
1072 * By setting BASE in cur_fw.type only after successfully loading all
1073 * firmwares, we can:
1074 * 1. Identify that BASE firmware with type=0 has been loaded;
1075 * 2. Tell whether BASE firmware was just changed the next time through.
1076 */
1077 priv->cur_fw.type |= BASE;
1078
1079 return 0;
1080
1081fail:
1082 memset(&priv->cur_fw, 0, sizeof(priv->cur_fw));
1083 if (!is_retry) {
1084 msleep(50);
1085 is_retry = 1;
1086 dprintk(1, "Retrying firmware load\n");
1087 goto retry;
1088 }
1089
1090 if (rc == -ENOENT)
1091 rc = -EINVAL;
1092 return rc;
1093}
1094
1095static void xc_debug_dump(struct xc4000_priv *priv)
1096{
1097 u16 adc_envelope;
1098 u32 freq_error_hz = 0;
1099 u16 lock_status;
1100 u32 hsync_freq_hz = 0;
1101 u16 frame_lines;
1102 u16 quality;
1103 u16 signal = 0;
1104 u16 noise = 0;
1105 u8 hw_majorversion = 0, hw_minorversion = 0;
1106 u8 fw_majorversion = 0, fw_minorversion = 0;
1107
1108 xc_get_adc_envelope(priv, &adc_envelope);
1109 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
1110
1111 xc_get_frequency_error(priv, &freq_error_hz);
1112 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
1113
1114 xc_get_lock_status(priv, &lock_status);
1115 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
1116 lock_status);
1117
1118 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
1119 &fw_majorversion, &fw_minorversion);
1120 dprintk(1, "*** HW: V%02x.%02x, FW: V%02x.%02x\n",
1121 hw_majorversion, hw_minorversion,
1122 fw_majorversion, fw_minorversion);
1123
1124 if (priv->video_standard < XC4000_DTV6) {
1125 xc_get_hsync_freq(priv, &hsync_freq_hz);
1126 dprintk(1, "*** Horizontal sync frequency = %d Hz\n",
1127 hsync_freq_hz);
1128
1129 xc_get_frame_lines(priv, &frame_lines);
1130 dprintk(1, "*** Frame lines = %d\n", frame_lines);
1131 }
1132
1133 xc_get_quality(priv, &quality);
1134 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality);
1135
1136 xc_get_signal_level(priv, &signal);
1137 dprintk(1, "*** Signal level = -%ddB (%d)\n", signal >> 8, signal);
1138
1139 xc_get_noise_level(priv, &noise);
1140 dprintk(1, "*** Noise level = %ddB (%d)\n", noise >> 8, noise);
1141}
1142
1143static int xc4000_set_params(struct dvb_frontend *fe)
1144{
1145 struct dtv_frontend_properties *c = &fe->dtv_property_cache;
1146 u32 delsys = c->delivery_system;
1147 u32 bw = c->bandwidth_hz;
1148 struct xc4000_priv *priv = fe->tuner_priv;
1149 unsigned int type;
1150 int ret = -EREMOTEIO;
1151
1152 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, c->frequency);
1153
1154 mutex_lock(&priv->lock);
1155
1156 switch (delsys) {
1157 case SYS_ATSC:
1158 dprintk(1, "%s() VSB modulation\n", __func__);
1159 priv->rf_mode = XC_RF_MODE_AIR;
1160 priv->freq_hz = c->frequency - 1750000;
1161 priv->video_standard = XC4000_DTV6;
1162 type = DTV6;
1163 break;
1164 case SYS_DVBC_ANNEX_B:
1165 dprintk(1, "%s() QAM modulation\n", __func__);
1166 priv->rf_mode = XC_RF_MODE_CABLE;
1167 priv->freq_hz = c->frequency - 1750000;
1168 priv->video_standard = XC4000_DTV6;
1169 type = DTV6;
1170 break;
1171 case SYS_DVBT:
1172 case SYS_DVBT2:
1173 dprintk(1, "%s() OFDM\n", __func__);
1174 if (bw == 0) {
1175 if (c->frequency < 400000000) {
1176 priv->freq_hz = c->frequency - 2250000;
1177 } else {
1178 priv->freq_hz = c->frequency - 2750000;
1179 }
1180 priv->video_standard = XC4000_DTV7_8;
1181 type = DTV78;
1182 } else if (bw <= 6000000) {
1183 priv->video_standard = XC4000_DTV6;
1184 priv->freq_hz = c->frequency - 1750000;
1185 type = DTV6;
1186 } else if (bw <= 7000000) {
1187 priv->video_standard = XC4000_DTV7;
1188 priv->freq_hz = c->frequency - 2250000;
1189 type = DTV7;
1190 } else {
1191 priv->video_standard = XC4000_DTV8;
1192 priv->freq_hz = c->frequency - 2750000;
1193 type = DTV8;
1194 }
1195 priv->rf_mode = XC_RF_MODE_AIR;
1196 break;
1197 default:
1198 printk(KERN_ERR "xc4000 delivery system not supported!\n");
1199 ret = -EINVAL;
1200 goto fail;
1201 }
1202
1203 dprintk(1, "%s() frequency=%d (compensated)\n",
1204 __func__, priv->freq_hz);
1205
1206 /* Make sure the correct firmware type is loaded */
1207 if (check_firmware(fe, type, 0, priv->if_khz) != 0)
1208 goto fail;
1209
1210 priv->bandwidth = c->bandwidth_hz;
1211
1212 ret = xc_set_signal_source(priv, priv->rf_mode);
1213 if (ret != 0) {
1214 printk(KERN_ERR "xc4000: xc_set_signal_source(%d) failed\n",
1215 priv->rf_mode);
1216 goto fail;
1217 } else {
1218 u16 video_mode, audio_mode;
1219 video_mode = xc4000_standard[priv->video_standard].video_mode;
1220 audio_mode = xc4000_standard[priv->video_standard].audio_mode;
1221 if (type == DTV6 && priv->firm_version != 0x0102)
1222 video_mode |= 0x0001;
1223 ret = xc_set_tv_standard(priv, video_mode, audio_mode);
1224 if (ret != 0) {
1225 printk(KERN_ERR "xc4000: xc_set_tv_standard failed\n");
1226 /* DJH - do not return when it fails... */
1227 /* goto fail; */
1228 }
1229 }
1230
1231 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1232 ret = 0;
1233 if (priv->dvb_amplitude != 0) {
1234 if (xc_write_reg(priv, XREG_AMPLITUDE,
1235 (priv->firm_version != 0x0102 ||
1236 priv->dvb_amplitude != 134 ?
1237 priv->dvb_amplitude : 132)) != 0)
1238 ret = -EREMOTEIO;
1239 }
1240 if (priv->set_smoothedcvbs != 0) {
1241 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1242 ret = -EREMOTEIO;
1243 }
1244 if (ret != 0) {
1245 printk(KERN_ERR "xc4000: setting registers failed\n");
1246 /* goto fail; */
1247 }
1248
1249 xc_tune_channel(priv, priv->freq_hz);
1250
1251 ret = 0;
1252
1253fail:
1254 mutex_unlock(&priv->lock);
1255
1256 return ret;
1257}
1258
1259static int xc4000_set_analog_params(struct dvb_frontend *fe,
1260 struct analog_parameters *params)
1261{
1262 struct xc4000_priv *priv = fe->tuner_priv;
1263 unsigned int type = 0;
1264 int ret = -EREMOTEIO;
1265
1266 if (params->mode == V4L2_TUNER_RADIO) {
1267 dprintk(1, "%s() frequency=%d (in units of 62.5Hz)\n",
1268 __func__, params->frequency);
1269
1270 mutex_lock(&priv->lock);
1271
1272 params->std = 0;
1273 priv->freq_hz = params->frequency * 125L / 2;
1274
1275 if (audio_std & XC4000_AUDIO_STD_INPUT1) {
1276 priv->video_standard = XC4000_FM_Radio_INPUT1;
1277 type = FM | INPUT1;
1278 } else {
1279 priv->video_standard = XC4000_FM_Radio_INPUT2;
1280 type = FM | INPUT2;
1281 }
1282
1283 goto tune_channel;
1284 }
1285
1286 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
1287 __func__, params->frequency);
1288
1289 mutex_lock(&priv->lock);
1290
1291 /* params->frequency is in units of 62.5khz */
1292 priv->freq_hz = params->frequency * 62500;
1293
1294 params->std &= V4L2_STD_ALL;
1295 /* if std is not defined, choose one */
1296 if (!params->std)
1297 params->std = V4L2_STD_PAL_BG;
1298
1299 if (audio_std & XC4000_AUDIO_STD_MONO)
1300 type = MONO;
1301
1302 if (params->std & V4L2_STD_MN) {
1303 params->std = V4L2_STD_MN;
1304 if (audio_std & XC4000_AUDIO_STD_MONO) {
1305 priv->video_standard = XC4000_MN_NTSC_PAL_Mono;
1306 } else if (audio_std & XC4000_AUDIO_STD_A2) {
1307 params->std |= V4L2_STD_A2;
1308 priv->video_standard = XC4000_MN_NTSC_PAL_A2;
1309 } else {
1310 params->std |= V4L2_STD_BTSC;
1311 priv->video_standard = XC4000_MN_NTSC_PAL_BTSC;
1312 }
1313 goto tune_channel;
1314 }
1315
1316 if (params->std & V4L2_STD_PAL_BG) {
1317 params->std = V4L2_STD_PAL_BG;
1318 if (audio_std & XC4000_AUDIO_STD_MONO) {
1319 priv->video_standard = XC4000_BG_PAL_MONO;
1320 } else if (!(audio_std & XC4000_AUDIO_STD_A2)) {
1321 if (!(audio_std & XC4000_AUDIO_STD_B)) {
1322 params->std |= V4L2_STD_NICAM_A;
1323 priv->video_standard = XC4000_BG_PAL_NICAM;
1324 } else {
1325 params->std |= V4L2_STD_NICAM_B;
1326 priv->video_standard = XC4000_BG_PAL_NICAM;
1327 }
1328 } else {
1329 if (!(audio_std & XC4000_AUDIO_STD_B)) {
1330 params->std |= V4L2_STD_A2_A;
1331 priv->video_standard = XC4000_BG_PAL_A2;
1332 } else {
1333 params->std |= V4L2_STD_A2_B;
1334 priv->video_standard = XC4000_BG_PAL_A2;
1335 }
1336 }
1337 goto tune_channel;
1338 }
1339
1340 if (params->std & V4L2_STD_PAL_I) {
1341 /* default to NICAM audio standard */
1342 params->std = V4L2_STD_PAL_I | V4L2_STD_NICAM;
1343 if (audio_std & XC4000_AUDIO_STD_MONO)
1344 priv->video_standard = XC4000_I_PAL_NICAM_MONO;
1345 else
1346 priv->video_standard = XC4000_I_PAL_NICAM;
1347 goto tune_channel;
1348 }
1349
1350 if (params->std & V4L2_STD_PAL_DK) {
1351 params->std = V4L2_STD_PAL_DK;
1352 if (audio_std & XC4000_AUDIO_STD_MONO) {
1353 priv->video_standard = XC4000_DK_PAL_MONO;
1354 } else if (audio_std & XC4000_AUDIO_STD_A2) {
1355 params->std |= V4L2_STD_A2;
1356 priv->video_standard = XC4000_DK_PAL_A2;
1357 } else {
1358 params->std |= V4L2_STD_NICAM;
1359 priv->video_standard = XC4000_DK_PAL_NICAM;
1360 }
1361 goto tune_channel;
1362 }
1363
1364 if (params->std & V4L2_STD_SECAM_DK) {
1365 /* default to A2 audio standard */
1366 params->std = V4L2_STD_SECAM_DK | V4L2_STD_A2;
1367 if (audio_std & XC4000_AUDIO_STD_L) {
1368 type = 0;
1369 priv->video_standard = XC4000_DK_SECAM_NICAM;
1370 } else if (audio_std & XC4000_AUDIO_STD_MONO) {
1371 priv->video_standard = XC4000_DK_SECAM_A2MONO;
1372 } else if (audio_std & XC4000_AUDIO_STD_K3) {
1373 params->std |= V4L2_STD_SECAM_K3;
1374 priv->video_standard = XC4000_DK_SECAM_A2LDK3;
1375 } else {
1376 priv->video_standard = XC4000_DK_SECAM_A2DK1;
1377 }
1378 goto tune_channel;
1379 }
1380
1381 if (params->std & V4L2_STD_SECAM_L) {
1382 /* default to NICAM audio standard */
1383 type = 0;
1384 params->std = V4L2_STD_SECAM_L | V4L2_STD_NICAM;
1385 priv->video_standard = XC4000_L_SECAM_NICAM;
1386 goto tune_channel;
1387 }
1388
1389 if (params->std & V4L2_STD_SECAM_LC) {
1390 /* default to NICAM audio standard */
1391 type = 0;
1392 params->std = V4L2_STD_SECAM_LC | V4L2_STD_NICAM;
1393 priv->video_standard = XC4000_LC_SECAM_NICAM;
1394 goto tune_channel;
1395 }
1396
1397tune_channel:
1398 /* FIXME: it could be air. */
1399 priv->rf_mode = XC_RF_MODE_CABLE;
1400
1401 if (check_firmware(fe, type, params->std,
1402 xc4000_standard[priv->video_standard].int_freq) != 0)
1403 goto fail;
1404
1405 ret = xc_set_signal_source(priv, priv->rf_mode);
1406 if (ret != 0) {
1407 printk(KERN_ERR
1408 "xc4000: xc_set_signal_source(%d) failed\n",
1409 priv->rf_mode);
1410 goto fail;
1411 } else {
1412 u16 video_mode, audio_mode;
1413 video_mode = xc4000_standard[priv->video_standard].video_mode;
1414 audio_mode = xc4000_standard[priv->video_standard].audio_mode;
1415 if (priv->video_standard < XC4000_BG_PAL_A2) {
1416 if (type & NOGD)
1417 video_mode &= 0xFF7F;
1418 } else if (priv->video_standard < XC4000_I_PAL_NICAM) {
1419 if (priv->firm_version == 0x0102)
1420 video_mode &= 0xFEFF;
1421 if (audio_std & XC4000_AUDIO_STD_B)
1422 video_mode |= 0x0080;
1423 }
1424 ret = xc_set_tv_standard(priv, video_mode, audio_mode);
1425 if (ret != 0) {
1426 printk(KERN_ERR "xc4000: xc_set_tv_standard failed\n");
1427 goto fail;
1428 }
1429 }
1430
1431 if (xc_write_reg(priv, XREG_D_CODE, 0) == 0)
1432 ret = 0;
1433 if (xc_write_reg(priv, XREG_AMPLITUDE, 1) != 0)
1434 ret = -EREMOTEIO;
1435 if (priv->set_smoothedcvbs != 0) {
1436 if (xc_write_reg(priv, XREG_SMOOTHEDCVBS, 1) != 0)
1437 ret = -EREMOTEIO;
1438 }
1439 if (ret != 0) {
1440 printk(KERN_ERR "xc4000: setting registers failed\n");
1441 goto fail;
1442 }
1443
1444 xc_tune_channel(priv, priv->freq_hz);
1445
1446 ret = 0;
1447
1448fail:
1449 mutex_unlock(&priv->lock);
1450
1451 return ret;
1452}
1453
1454static int xc4000_get_signal(struct dvb_frontend *fe, u16 *strength)
1455{
1456 struct xc4000_priv *priv = fe->tuner_priv;
1457 u16 value = 0;
1458 int rc;
1459
1460 mutex_lock(&priv->lock);
1461 rc = xc4000_readreg(priv, XREG_SIGNAL_LEVEL, &value);
1462 mutex_unlock(&priv->lock);
1463
1464 if (rc < 0)
1465 goto ret;
1466
1467 /* Informations from real testing of DVB-T and radio part,
1468 coeficient for one dB is 0xff.
1469 */
1470 tuner_dbg("Signal strength: -%ddB (%05d)\n", value >> 8, value);
1471
1472 /* all known digital modes */
1473 if ((priv->video_standard == XC4000_DTV6) ||
1474 (priv->video_standard == XC4000_DTV7) ||
1475 (priv->video_standard == XC4000_DTV7_8) ||
1476 (priv->video_standard == XC4000_DTV8))
1477 goto digital;
1478
1479 /* Analog mode has NOISE LEVEL important, signal
1480 depends only on gain of antenna and amplifiers,
1481 but it doesn't tell anything about real quality
1482 of reception.
1483 */
1484 mutex_lock(&priv->lock);
1485 rc = xc4000_readreg(priv, XREG_NOISE_LEVEL, &value);
1486 mutex_unlock(&priv->lock);
1487
1488 tuner_dbg("Noise level: %ddB (%05d)\n", value >> 8, value);
1489
1490 /* highest noise level: 32dB */
1491 if (value >= 0x2000) {
1492 value = 0;
1493 } else {
1494 value = ~value << 3;
1495 }
1496
1497 goto ret;
1498
1499 /* Digital mode has SIGNAL LEVEL important and real
1500 noise level is stored in demodulator registers.
1501 */
1502digital:
1503 /* best signal: -50dB */
1504 if (value <= 0x3200) {
1505 value = 0xffff;
1506 /* minimum: -114dB - should be 0x7200 but real zero is 0x713A */
1507 } else if (value >= 0x713A) {
1508 value = 0;
1509 } else {
1510 value = ~(value - 0x3200) << 2;
1511 }
1512
1513ret:
1514 *strength = value;
1515
1516 return rc;
1517}
1518
1519static int xc4000_get_frequency(struct dvb_frontend *fe, u32 *freq)
1520{
1521 struct xc4000_priv *priv = fe->tuner_priv;
1522
1523 *freq = priv->freq_hz;
1524
1525 if (debug) {
1526 mutex_lock(&priv->lock);
1527 if ((priv->cur_fw.type
1528 & (BASE | FM | DTV6 | DTV7 | DTV78 | DTV8)) == BASE) {
1529 u16 snr = 0;
1530 if (xc4000_readreg(priv, XREG_SNR, &snr) == 0) {
1531 mutex_unlock(&priv->lock);
1532 dprintk(1, "%s() freq = %u, SNR = %d\n",
1533 __func__, *freq, snr);
1534 return 0;
1535 }
1536 }
1537 mutex_unlock(&priv->lock);
1538 }
1539
1540 dprintk(1, "%s()\n", __func__);
1541
1542 return 0;
1543}
1544
1545static int xc4000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
1546{
1547 struct xc4000_priv *priv = fe->tuner_priv;
1548 dprintk(1, "%s()\n", __func__);
1549
1550 *bw = priv->bandwidth;
1551 return 0;
1552}
1553
1554static int xc4000_get_status(struct dvb_frontend *fe, u32 *status)
1555{
1556 struct xc4000_priv *priv = fe->tuner_priv;
1557 u16 lock_status = 0;
1558
1559 mutex_lock(&priv->lock);
1560
1561 if (priv->cur_fw.type & BASE)
1562 xc_get_lock_status(priv, &lock_status);
1563
1564 *status = (lock_status == 1 ?
1565 TUNER_STATUS_LOCKED | TUNER_STATUS_STEREO : 0);
1566 if (priv->cur_fw.type & (DTV6 | DTV7 | DTV78 | DTV8))
1567 *status &= (~TUNER_STATUS_STEREO);
1568
1569 mutex_unlock(&priv->lock);
1570
1571 dprintk(2, "%s() lock_status = %d\n", __func__, lock_status);
1572
1573 return 0;
1574}
1575
1576static int xc4000_sleep(struct dvb_frontend *fe)
1577{
1578 struct xc4000_priv *priv = fe->tuner_priv;
1579 int ret = 0;
1580
1581 dprintk(1, "%s()\n", __func__);
1582
1583 mutex_lock(&priv->lock);
1584
1585 /* Avoid firmware reload on slow devices */
1586 if ((no_poweroff == 2 ||
1587 (no_poweroff == 0 && priv->default_pm != 0)) &&
1588 (priv->cur_fw.type & BASE) != 0) {
1589 /* force reset and firmware reload */
1590 priv->cur_fw.type = XC_POWERED_DOWN;
1591
1592 if (xc_write_reg(priv, XREG_POWER_DOWN, 0) != 0) {
1593 printk(KERN_ERR
1594 "xc4000: %s() unable to shutdown tuner\n",
1595 __func__);
1596 ret = -EREMOTEIO;
1597 }
1598 msleep(20);
1599 }
1600
1601 mutex_unlock(&priv->lock);
1602
1603 return ret;
1604}
1605
1606static int xc4000_init(struct dvb_frontend *fe)
1607{
1608 dprintk(1, "%s()\n", __func__);
1609
1610 return 0;
1611}
1612
1613static int xc4000_release(struct dvb_frontend *fe)
1614{
1615 struct xc4000_priv *priv = fe->tuner_priv;
1616
1617 dprintk(1, "%s()\n", __func__);
1618
1619 mutex_lock(&xc4000_list_mutex);
1620
1621 if (priv)
1622 hybrid_tuner_release_state(priv);
1623
1624 mutex_unlock(&xc4000_list_mutex);
1625
1626 fe->tuner_priv = NULL;
1627
1628 return 0;
1629}
1630
1631static const struct dvb_tuner_ops xc4000_tuner_ops = {
1632 .info = {
1633 .name = "Xceive XC4000",
1634 .frequency_min = 1000000,
1635 .frequency_max = 1023000000,
1636 .frequency_step = 50000,
1637 },
1638
1639 .release = xc4000_release,
1640 .init = xc4000_init,
1641 .sleep = xc4000_sleep,
1642
1643 .set_params = xc4000_set_params,
1644 .set_analog_params = xc4000_set_analog_params,
1645 .get_frequency = xc4000_get_frequency,
1646 .get_rf_strength = xc4000_get_signal,
1647 .get_bandwidth = xc4000_get_bandwidth,
1648 .get_status = xc4000_get_status
1649};
1650
1651struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
1652 struct i2c_adapter *i2c,
1653 struct xc4000_config *cfg)
1654{
1655 struct xc4000_priv *priv = NULL;
1656 int instance;
1657 u16 id = 0;
1658
1659 dprintk(1, "%s(%d-%04x)\n", __func__,
1660 i2c ? i2c_adapter_id(i2c) : -1,
1661 cfg ? cfg->i2c_address : -1);
1662
1663 mutex_lock(&xc4000_list_mutex);
1664
1665 instance = hybrid_tuner_request_state(struct xc4000_priv, priv,
1666 hybrid_tuner_instance_list,
1667 i2c, cfg->i2c_address, "xc4000");
1668 switch (instance) {
1669 case 0:
1670 goto fail;
1671 break;
1672 case 1:
1673 /* new tuner instance */
1674 priv->bandwidth = 6000000;
1675 /* set default configuration */
1676 priv->if_khz = 4560;
1677 priv->default_pm = 0;
1678 priv->dvb_amplitude = 134;
1679 priv->set_smoothedcvbs = 1;
1680 mutex_init(&priv->lock);
1681 fe->tuner_priv = priv;
1682 break;
1683 default:
1684 /* existing tuner instance */
1685 fe->tuner_priv = priv;
1686 break;
1687 }
1688
1689 if (cfg->if_khz != 0) {
1690 /* copy configuration if provided by the caller */
1691 priv->if_khz = cfg->if_khz;
1692 priv->default_pm = cfg->default_pm;
1693 priv->dvb_amplitude = cfg->dvb_amplitude;
1694 priv->set_smoothedcvbs = cfg->set_smoothedcvbs;
1695 }
1696
1697 /* Check if firmware has been loaded. It is possible that another
1698 instance of the driver has loaded the firmware.
1699 */
1700
1701 if (instance == 1) {
1702 if (xc4000_readreg(priv, XREG_PRODUCT_ID, &id) != 0)
1703 goto fail;
1704 } else {
1705 id = ((priv->cur_fw.type & BASE) != 0 ?
1706 priv->hwmodel : XC_PRODUCT_ID_FW_NOT_LOADED);
1707 }
1708
1709 switch (id) {
1710 case XC_PRODUCT_ID_XC4000:
1711 case XC_PRODUCT_ID_XC4100:
1712 printk(KERN_INFO
1713 "xc4000: Successfully identified at address 0x%02x\n",
1714 cfg->i2c_address);
1715 printk(KERN_INFO
1716 "xc4000: Firmware has been loaded previously\n");
1717 break;
1718 case XC_PRODUCT_ID_FW_NOT_LOADED:
1719 printk(KERN_INFO
1720 "xc4000: Successfully identified at address 0x%02x\n",
1721 cfg->i2c_address);
1722 printk(KERN_INFO
1723 "xc4000: Firmware has not been loaded previously\n");
1724 break;
1725 default:
1726 printk(KERN_ERR
1727 "xc4000: Device not found at addr 0x%02x (0x%x)\n",
1728 cfg->i2c_address, id);
1729 goto fail;
1730 }
1731
1732 mutex_unlock(&xc4000_list_mutex);
1733
1734 memcpy(&fe->ops.tuner_ops, &xc4000_tuner_ops,
1735 sizeof(struct dvb_tuner_ops));
1736
1737 if (instance == 1) {
1738 int ret;
1739 mutex_lock(&priv->lock);
1740 ret = xc4000_fwupload(fe);
1741 mutex_unlock(&priv->lock);
1742 if (ret != 0)
1743 goto fail2;
1744 }
1745
1746 return fe;
1747fail:
1748 mutex_unlock(&xc4000_list_mutex);
1749fail2:
1750 xc4000_release(fe);
1751 return NULL;
1752}
1753EXPORT_SYMBOL(xc4000_attach);
1754
1755MODULE_AUTHOR("Steven Toth, Davide Ferri");
1756MODULE_DESCRIPTION("Xceive xc4000 silicon tuner driver");
1757MODULE_LICENSE("GPL");
diff --git a/drivers/media/tuners/xc4000.h b/drivers/media/tuners/xc4000.h
new file mode 100644
index 000000000000..e6a44d151cbd
--- /dev/null
+++ b/drivers/media/tuners/xc4000.h
@@ -0,0 +1,67 @@
1/*
2 * Driver for Xceive XC4000 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __XC4000_H__
23#define __XC4000_H__
24
25#include <linux/firmware.h>
26
27struct dvb_frontend;
28struct i2c_adapter;
29
30struct xc4000_config {
31 u8 i2c_address;
32 /* if non-zero, power management is enabled by default */
33 u8 default_pm;
34 /* value to be written to XREG_AMPLITUDE in DVB-T mode (0: no write) */
35 u8 dvb_amplitude;
36 /* if non-zero, register 0x0E is set to filter analog TV video output */
37 u8 set_smoothedcvbs;
38 /* IF for DVB-T */
39 u32 if_khz;
40};
41
42/* xc4000 callback command */
43#define XC4000_TUNER_RESET 0
44
45/* For each bridge framework, when it attaches either analog or digital,
46 * it has to store a reference back to its _core equivalent structure,
47 * so that it can service the hardware by steering gpio's etc.
48 * Each bridge implementation is different so cast devptr accordingly.
49 * The xc4000 driver cares not for this value, other than ensuring
50 * it's passed back to a bridge during tuner_callback().
51 */
52
53#if defined(CONFIG_MEDIA_TUNER_XC4000) || (defined(CONFIG_MEDIA_TUNER_XC4000_MODULE) && defined(MODULE))
54extern struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
55 struct i2c_adapter *i2c,
56 struct xc4000_config *cfg);
57#else
58static inline struct dvb_frontend *xc4000_attach(struct dvb_frontend *fe,
59 struct i2c_adapter *i2c,
60 struct xc4000_config *cfg)
61{
62 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
63 return NULL;
64}
65#endif
66
67#endif
diff --git a/drivers/media/tuners/xc5000.c b/drivers/media/tuners/xc5000.c
new file mode 100644
index 000000000000..dc93cf338f36
--- /dev/null
+++ b/drivers/media/tuners/xc5000.c
@@ -0,0 +1,1366 @@
1/*
2 * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2007 Xceive Corporation
5 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
6 * Copyright (c) 2009 Devin Heitmueller <dheitmueller@kernellabs.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 *
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
22 */
23
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/videodev2.h>
27#include <linux/delay.h>
28#include <linux/dvb/frontend.h>
29#include <linux/i2c.h>
30
31#include "dvb_frontend.h"
32
33#include "xc5000.h"
34#include "tuner-i2c.h"
35
36static int debug;
37module_param(debug, int, 0644);
38MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
39
40static int no_poweroff;
41module_param(no_poweroff, int, 0644);
42MODULE_PARM_DESC(no_poweroff, "0 (default) powers device off when not used.\n"
43 "\t\t1 keep device energized and with tuner ready all the times.\n"
44 "\t\tFaster, but consumes more power and keeps the device hotter");
45
46static DEFINE_MUTEX(xc5000_list_mutex);
47static LIST_HEAD(hybrid_tuner_instance_list);
48
49#define dprintk(level, fmt, arg...) if (debug >= level) \
50 printk(KERN_INFO "%s: " fmt, "xc5000", ## arg)
51
52struct xc5000_priv {
53 struct tuner_i2c_props i2c_props;
54 struct list_head hybrid_tuner_instance_list;
55
56 u32 if_khz;
57 u16 xtal_khz;
58 u32 freq_hz;
59 u32 bandwidth;
60 u8 video_standard;
61 u8 rf_mode;
62 u8 radio_input;
63
64 int chip_id;
65 u16 pll_register_no;
66 u8 init_status_supported;
67 u8 fw_checksum_supported;
68};
69
70/* Misc Defines */
71#define MAX_TV_STANDARD 24
72#define XC_MAX_I2C_WRITE_LENGTH 64
73
74/* Signal Types */
75#define XC_RF_MODE_AIR 0
76#define XC_RF_MODE_CABLE 1
77
78/* Result codes */
79#define XC_RESULT_SUCCESS 0
80#define XC_RESULT_RESET_FAILURE 1
81#define XC_RESULT_I2C_WRITE_FAILURE 2
82#define XC_RESULT_I2C_READ_FAILURE 3
83#define XC_RESULT_OUT_OF_RANGE 5
84
85/* Product id */
86#define XC_PRODUCT_ID_FW_NOT_LOADED 0x2000
87#define XC_PRODUCT_ID_FW_LOADED 0x1388
88
89/* Registers */
90#define XREG_INIT 0x00
91#define XREG_VIDEO_MODE 0x01
92#define XREG_AUDIO_MODE 0x02
93#define XREG_RF_FREQ 0x03
94#define XREG_D_CODE 0x04
95#define XREG_IF_OUT 0x05
96#define XREG_SEEK_MODE 0x07
97#define XREG_POWER_DOWN 0x0A /* Obsolete */
98/* Set the output amplitude - SIF for analog, DTVP/DTVN for digital */
99#define XREG_OUTPUT_AMP 0x0B
100#define XREG_SIGNALSOURCE 0x0D /* 0=Air, 1=Cable */
101#define XREG_SMOOTHEDCVBS 0x0E
102#define XREG_XTALFREQ 0x0F
103#define XREG_FINERFREQ 0x10
104#define XREG_DDIMODE 0x11
105
106#define XREG_ADC_ENV 0x00
107#define XREG_QUALITY 0x01
108#define XREG_FRAME_LINES 0x02
109#define XREG_HSYNC_FREQ 0x03
110#define XREG_LOCK 0x04
111#define XREG_FREQ_ERROR 0x05
112#define XREG_SNR 0x06
113#define XREG_VERSION 0x07
114#define XREG_PRODUCT_ID 0x08
115#define XREG_BUSY 0x09
116#define XREG_BUILD 0x0D
117#define XREG_TOTALGAIN 0x0F
118#define XREG_FW_CHECKSUM 0x12
119#define XREG_INIT_STATUS 0x13
120
121/*
122 Basic firmware description. This will remain with
123 the driver for documentation purposes.
124
125 This represents an I2C firmware file encoded as a
126 string of unsigned char. Format is as follows:
127
128 char[0 ]=len0_MSB -> len = len_MSB * 256 + len_LSB
129 char[1 ]=len0_LSB -> length of first write transaction
130 char[2 ]=data0 -> first byte to be sent
131 char[3 ]=data1
132 char[4 ]=data2
133 char[ ]=...
134 char[M ]=dataN -> last byte to be sent
135 char[M+1]=len1_MSB -> len = len_MSB * 256 + len_LSB
136 char[M+2]=len1_LSB -> length of second write transaction
137 char[M+3]=data0
138 char[M+4]=data1
139 ...
140 etc.
141
142 The [len] value should be interpreted as follows:
143
144 len= len_MSB _ len_LSB
145 len=1111_1111_1111_1111 : End of I2C_SEQUENCE
146 len=0000_0000_0000_0000 : Reset command: Do hardware reset
147 len=0NNN_NNNN_NNNN_NNNN : Normal transaction: number of bytes = {1:32767)
148 len=1WWW_WWWW_WWWW_WWWW : Wait command: wait for {1:32767} ms
149
150 For the RESET and WAIT commands, the two following bytes will contain
151 immediately the length of the following transaction.
152
153*/
154struct XC_TV_STANDARD {
155 char *Name;
156 u16 AudioMode;
157 u16 VideoMode;
158};
159
160/* Tuner standards */
161#define MN_NTSC_PAL_BTSC 0
162#define MN_NTSC_PAL_A2 1
163#define MN_NTSC_PAL_EIAJ 2
164#define MN_NTSC_PAL_Mono 3
165#define BG_PAL_A2 4
166#define BG_PAL_NICAM 5
167#define BG_PAL_MONO 6
168#define I_PAL_NICAM 7
169#define I_PAL_NICAM_MONO 8
170#define DK_PAL_A2 9
171#define DK_PAL_NICAM 10
172#define DK_PAL_MONO 11
173#define DK_SECAM_A2DK1 12
174#define DK_SECAM_A2LDK3 13
175#define DK_SECAM_A2MONO 14
176#define L_SECAM_NICAM 15
177#define LC_SECAM_NICAM 16
178#define DTV6 17
179#define DTV8 18
180#define DTV7_8 19
181#define DTV7 20
182#define FM_Radio_INPUT2 21
183#define FM_Radio_INPUT1 22
184#define FM_Radio_INPUT1_MONO 23
185
186static struct XC_TV_STANDARD XC5000_Standard[MAX_TV_STANDARD] = {
187 {"M/N-NTSC/PAL-BTSC", 0x0400, 0x8020},
188 {"M/N-NTSC/PAL-A2", 0x0600, 0x8020},
189 {"M/N-NTSC/PAL-EIAJ", 0x0440, 0x8020},
190 {"M/N-NTSC/PAL-Mono", 0x0478, 0x8020},
191 {"B/G-PAL-A2", 0x0A00, 0x8049},
192 {"B/G-PAL-NICAM", 0x0C04, 0x8049},
193 {"B/G-PAL-MONO", 0x0878, 0x8059},
194 {"I-PAL-NICAM", 0x1080, 0x8009},
195 {"I-PAL-NICAM-MONO", 0x0E78, 0x8009},
196 {"D/K-PAL-A2", 0x1600, 0x8009},
197 {"D/K-PAL-NICAM", 0x0E80, 0x8009},
198 {"D/K-PAL-MONO", 0x1478, 0x8009},
199 {"D/K-SECAM-A2 DK1", 0x1200, 0x8009},
200 {"D/K-SECAM-A2 L/DK3", 0x0E00, 0x8009},
201 {"D/K-SECAM-A2 MONO", 0x1478, 0x8009},
202 {"L-SECAM-NICAM", 0x8E82, 0x0009},
203 {"L'-SECAM-NICAM", 0x8E82, 0x4009},
204 {"DTV6", 0x00C0, 0x8002},
205 {"DTV8", 0x00C0, 0x800B},
206 {"DTV7/8", 0x00C0, 0x801B},
207 {"DTV7", 0x00C0, 0x8007},
208 {"FM Radio-INPUT2", 0x9802, 0x9002},
209 {"FM Radio-INPUT1", 0x0208, 0x9002},
210 {"FM Radio-INPUT1_MONO", 0x0278, 0x9002}
211};
212
213
214struct xc5000_fw_cfg {
215 char *name;
216 u16 size;
217 u16 pll_reg;
218 u8 init_status_supported;
219 u8 fw_checksum_supported;
220};
221
222#define XC5000A_FIRMWARE "dvb-fe-xc5000-1.6.114.fw"
223static const struct xc5000_fw_cfg xc5000a_1_6_114 = {
224 .name = XC5000A_FIRMWARE,
225 .size = 12401,
226 .pll_reg = 0x806c,
227};
228
229#define XC5000C_FIRMWARE "dvb-fe-xc5000c-4.1.30.7.fw"
230static const struct xc5000_fw_cfg xc5000c_41_024_5 = {
231 .name = XC5000C_FIRMWARE,
232 .size = 16497,
233 .pll_reg = 0x13,
234 .init_status_supported = 1,
235 .fw_checksum_supported = 1,
236};
237
238static inline const struct xc5000_fw_cfg *xc5000_assign_firmware(int chip_id)
239{
240 switch (chip_id) {
241 default:
242 case XC5000A:
243 return &xc5000a_1_6_114;
244 case XC5000C:
245 return &xc5000c_41_024_5;
246 }
247}
248
249static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force);
250static int xc5000_is_firmware_loaded(struct dvb_frontend *fe);
251static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val);
252static int xc5000_TunerReset(struct dvb_frontend *fe);
253
254static int xc_send_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
255{
256 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
257 .flags = 0, .buf = buf, .len = len };
258
259 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
260 printk(KERN_ERR "xc5000: I2C write failed (len=%i)\n", len);
261 return XC_RESULT_I2C_WRITE_FAILURE;
262 }
263 return XC_RESULT_SUCCESS;
264}
265
266#if 0
267/* This routine is never used because the only time we read data from the
268 i2c bus is when we read registers, and we want that to be an atomic i2c
269 transaction in case we are on a multi-master bus */
270static int xc_read_i2c_data(struct xc5000_priv *priv, u8 *buf, int len)
271{
272 struct i2c_msg msg = { .addr = priv->i2c_props.addr,
273 .flags = I2C_M_RD, .buf = buf, .len = len };
274
275 if (i2c_transfer(priv->i2c_props.adap, &msg, 1) != 1) {
276 printk(KERN_ERR "xc5000 I2C read failed (len=%i)\n", len);
277 return -EREMOTEIO;
278 }
279 return 0;
280}
281#endif
282
283static int xc5000_readreg(struct xc5000_priv *priv, u16 reg, u16 *val)
284{
285 u8 buf[2] = { reg >> 8, reg & 0xff };
286 u8 bval[2] = { 0, 0 };
287 struct i2c_msg msg[2] = {
288 { .addr = priv->i2c_props.addr,
289 .flags = 0, .buf = &buf[0], .len = 2 },
290 { .addr = priv->i2c_props.addr,
291 .flags = I2C_M_RD, .buf = &bval[0], .len = 2 },
292 };
293
294 if (i2c_transfer(priv->i2c_props.adap, msg, 2) != 2) {
295 printk(KERN_WARNING "xc5000: I2C read failed\n");
296 return -EREMOTEIO;
297 }
298
299 *val = (bval[0] << 8) | bval[1];
300 return XC_RESULT_SUCCESS;
301}
302
303static void xc_wait(int wait_ms)
304{
305 msleep(wait_ms);
306}
307
308static int xc5000_TunerReset(struct dvb_frontend *fe)
309{
310 struct xc5000_priv *priv = fe->tuner_priv;
311 int ret;
312
313 dprintk(1, "%s()\n", __func__);
314
315 if (fe->callback) {
316 ret = fe->callback(((fe->dvb) && (fe->dvb->priv)) ?
317 fe->dvb->priv :
318 priv->i2c_props.adap->algo_data,
319 DVB_FRONTEND_COMPONENT_TUNER,
320 XC5000_TUNER_RESET, 0);
321 if (ret) {
322 printk(KERN_ERR "xc5000: reset failed\n");
323 return XC_RESULT_RESET_FAILURE;
324 }
325 } else {
326 printk(KERN_ERR "xc5000: no tuner reset callback function, fatal\n");
327 return XC_RESULT_RESET_FAILURE;
328 }
329 return XC_RESULT_SUCCESS;
330}
331
332static int xc_write_reg(struct xc5000_priv *priv, u16 regAddr, u16 i2cData)
333{
334 u8 buf[4];
335 int WatchDogTimer = 100;
336 int result;
337
338 buf[0] = (regAddr >> 8) & 0xFF;
339 buf[1] = regAddr & 0xFF;
340 buf[2] = (i2cData >> 8) & 0xFF;
341 buf[3] = i2cData & 0xFF;
342 result = xc_send_i2c_data(priv, buf, 4);
343 if (result == XC_RESULT_SUCCESS) {
344 /* wait for busy flag to clear */
345 while ((WatchDogTimer > 0) && (result == XC_RESULT_SUCCESS)) {
346 result = xc5000_readreg(priv, XREG_BUSY, (u16 *)buf);
347 if (result == XC_RESULT_SUCCESS) {
348 if ((buf[0] == 0) && (buf[1] == 0)) {
349 /* busy flag cleared */
350 break;
351 } else {
352 xc_wait(5); /* wait 5 ms */
353 WatchDogTimer--;
354 }
355 }
356 }
357 }
358 if (WatchDogTimer <= 0)
359 result = XC_RESULT_I2C_WRITE_FAILURE;
360
361 return result;
362}
363
364static int xc_load_i2c_sequence(struct dvb_frontend *fe, const u8 *i2c_sequence)
365{
366 struct xc5000_priv *priv = fe->tuner_priv;
367
368 int i, nbytes_to_send, result;
369 unsigned int len, pos, index;
370 u8 buf[XC_MAX_I2C_WRITE_LENGTH];
371
372 index = 0;
373 while ((i2c_sequence[index] != 0xFF) ||
374 (i2c_sequence[index + 1] != 0xFF)) {
375 len = i2c_sequence[index] * 256 + i2c_sequence[index+1];
376 if (len == 0x0000) {
377 /* RESET command */
378 result = xc5000_TunerReset(fe);
379 index += 2;
380 if (result != XC_RESULT_SUCCESS)
381 return result;
382 } else if (len & 0x8000) {
383 /* WAIT command */
384 xc_wait(len & 0x7FFF);
385 index += 2;
386 } else {
387 /* Send i2c data whilst ensuring individual transactions
388 * do not exceed XC_MAX_I2C_WRITE_LENGTH bytes.
389 */
390 index += 2;
391 buf[0] = i2c_sequence[index];
392 buf[1] = i2c_sequence[index + 1];
393 pos = 2;
394 while (pos < len) {
395 if ((len - pos) > XC_MAX_I2C_WRITE_LENGTH - 2)
396 nbytes_to_send =
397 XC_MAX_I2C_WRITE_LENGTH;
398 else
399 nbytes_to_send = (len - pos + 2);
400 for (i = 2; i < nbytes_to_send; i++) {
401 buf[i] = i2c_sequence[index + pos +
402 i - 2];
403 }
404 result = xc_send_i2c_data(priv, buf,
405 nbytes_to_send);
406
407 if (result != XC_RESULT_SUCCESS)
408 return result;
409
410 pos += nbytes_to_send - 2;
411 }
412 index += len;
413 }
414 }
415 return XC_RESULT_SUCCESS;
416}
417
418static int xc_initialize(struct xc5000_priv *priv)
419{
420 dprintk(1, "%s()\n", __func__);
421 return xc_write_reg(priv, XREG_INIT, 0);
422}
423
424static int xc_SetTVStandard(struct xc5000_priv *priv,
425 u16 VideoMode, u16 AudioMode)
426{
427 int ret;
428 dprintk(1, "%s(0x%04x,0x%04x)\n", __func__, VideoMode, AudioMode);
429 dprintk(1, "%s() Standard = %s\n",
430 __func__,
431 XC5000_Standard[priv->video_standard].Name);
432
433 ret = xc_write_reg(priv, XREG_VIDEO_MODE, VideoMode);
434 if (ret == XC_RESULT_SUCCESS)
435 ret = xc_write_reg(priv, XREG_AUDIO_MODE, AudioMode);
436
437 return ret;
438}
439
440static int xc_SetSignalSource(struct xc5000_priv *priv, u16 rf_mode)
441{
442 dprintk(1, "%s(%d) Source = %s\n", __func__, rf_mode,
443 rf_mode == XC_RF_MODE_AIR ? "ANTENNA" : "CABLE");
444
445 if ((rf_mode != XC_RF_MODE_AIR) && (rf_mode != XC_RF_MODE_CABLE)) {
446 rf_mode = XC_RF_MODE_CABLE;
447 printk(KERN_ERR
448 "%s(), Invalid mode, defaulting to CABLE",
449 __func__);
450 }
451 return xc_write_reg(priv, XREG_SIGNALSOURCE, rf_mode);
452}
453
454static const struct dvb_tuner_ops xc5000_tuner_ops;
455
456static int xc_set_RF_frequency(struct xc5000_priv *priv, u32 freq_hz)
457{
458 u16 freq_code;
459
460 dprintk(1, "%s(%u)\n", __func__, freq_hz);
461
462 if ((freq_hz > xc5000_tuner_ops.info.frequency_max) ||
463 (freq_hz < xc5000_tuner_ops.info.frequency_min))
464 return XC_RESULT_OUT_OF_RANGE;
465
466 freq_code = (u16)(freq_hz / 15625);
467
468 /* Starting in firmware version 1.1.44, Xceive recommends using the
469 FINERFREQ for all normal tuning (the doc indicates reg 0x03 should
470 only be used for fast scanning for channel lock) */
471 return xc_write_reg(priv, XREG_FINERFREQ, freq_code);
472}
473
474
475static int xc_set_IF_frequency(struct xc5000_priv *priv, u32 freq_khz)
476{
477 u32 freq_code = (freq_khz * 1024)/1000;
478 dprintk(1, "%s(freq_khz = %d) freq_code = 0x%x\n",
479 __func__, freq_khz, freq_code);
480
481 return xc_write_reg(priv, XREG_IF_OUT, freq_code);
482}
483
484
485static int xc_get_ADC_Envelope(struct xc5000_priv *priv, u16 *adc_envelope)
486{
487 return xc5000_readreg(priv, XREG_ADC_ENV, adc_envelope);
488}
489
490static int xc_get_frequency_error(struct xc5000_priv *priv, u32 *freq_error_hz)
491{
492 int result;
493 u16 regData;
494 u32 tmp;
495
496 result = xc5000_readreg(priv, XREG_FREQ_ERROR, &regData);
497 if (result != XC_RESULT_SUCCESS)
498 return result;
499
500 tmp = (u32)regData;
501 (*freq_error_hz) = (tmp * 15625) / 1000;
502 return result;
503}
504
505static int xc_get_lock_status(struct xc5000_priv *priv, u16 *lock_status)
506{
507 return xc5000_readreg(priv, XREG_LOCK, lock_status);
508}
509
510static int xc_get_version(struct xc5000_priv *priv,
511 u8 *hw_majorversion, u8 *hw_minorversion,
512 u8 *fw_majorversion, u8 *fw_minorversion)
513{
514 u16 data;
515 int result;
516
517 result = xc5000_readreg(priv, XREG_VERSION, &data);
518 if (result != XC_RESULT_SUCCESS)
519 return result;
520
521 (*hw_majorversion) = (data >> 12) & 0x0F;
522 (*hw_minorversion) = (data >> 8) & 0x0F;
523 (*fw_majorversion) = (data >> 4) & 0x0F;
524 (*fw_minorversion) = data & 0x0F;
525
526 return 0;
527}
528
529static int xc_get_buildversion(struct xc5000_priv *priv, u16 *buildrev)
530{
531 return xc5000_readreg(priv, XREG_BUILD, buildrev);
532}
533
534static int xc_get_hsync_freq(struct xc5000_priv *priv, u32 *hsync_freq_hz)
535{
536 u16 regData;
537 int result;
538
539 result = xc5000_readreg(priv, XREG_HSYNC_FREQ, &regData);
540 if (result != XC_RESULT_SUCCESS)
541 return result;
542
543 (*hsync_freq_hz) = ((regData & 0x0fff) * 763)/100;
544 return result;
545}
546
547static int xc_get_frame_lines(struct xc5000_priv *priv, u16 *frame_lines)
548{
549 return xc5000_readreg(priv, XREG_FRAME_LINES, frame_lines);
550}
551
552static int xc_get_quality(struct xc5000_priv *priv, u16 *quality)
553{
554 return xc5000_readreg(priv, XREG_QUALITY, quality);
555}
556
557static int xc_get_analogsnr(struct xc5000_priv *priv, u16 *snr)
558{
559 return xc5000_readreg(priv, XREG_SNR, snr);
560}
561
562static int xc_get_totalgain(struct xc5000_priv *priv, u16 *totalgain)
563{
564 return xc5000_readreg(priv, XREG_TOTALGAIN, totalgain);
565}
566
567static u16 WaitForLock(struct xc5000_priv *priv)
568{
569 u16 lockState = 0;
570 int watchDogCount = 40;
571
572 while ((lockState == 0) && (watchDogCount > 0)) {
573 xc_get_lock_status(priv, &lockState);
574 if (lockState != 1) {
575 xc_wait(5);
576 watchDogCount--;
577 }
578 }
579 return lockState;
580}
581
582#define XC_TUNE_ANALOG 0
583#define XC_TUNE_DIGITAL 1
584static int xc_tune_channel(struct xc5000_priv *priv, u32 freq_hz, int mode)
585{
586 int found = 0;
587
588 dprintk(1, "%s(%u)\n", __func__, freq_hz);
589
590 if (xc_set_RF_frequency(priv, freq_hz) != XC_RESULT_SUCCESS)
591 return 0;
592
593 if (mode == XC_TUNE_ANALOG) {
594 if (WaitForLock(priv) == 1)
595 found = 1;
596 }
597
598 return found;
599}
600
601static int xc_set_xtal(struct dvb_frontend *fe)
602{
603 struct xc5000_priv *priv = fe->tuner_priv;
604 int ret = XC_RESULT_SUCCESS;
605
606 switch (priv->chip_id) {
607 default:
608 case XC5000A:
609 /* 32.000 MHz xtal is default */
610 break;
611 case XC5000C:
612 switch (priv->xtal_khz) {
613 default:
614 case 32000:
615 /* 32.000 MHz xtal is default */
616 break;
617 case 31875:
618 /* 31.875 MHz xtal configuration */
619 ret = xc_write_reg(priv, 0x000f, 0x8081);
620 break;
621 }
622 break;
623 }
624 return ret;
625}
626
627static int xc5000_fwupload(struct dvb_frontend *fe)
628{
629 struct xc5000_priv *priv = fe->tuner_priv;
630 const struct firmware *fw;
631 int ret;
632 const struct xc5000_fw_cfg *desired_fw =
633 xc5000_assign_firmware(priv->chip_id);
634 priv->pll_register_no = desired_fw->pll_reg;
635 priv->init_status_supported = desired_fw->init_status_supported;
636 priv->fw_checksum_supported = desired_fw->fw_checksum_supported;
637
638 /* request the firmware, this will block and timeout */
639 printk(KERN_INFO "xc5000: waiting for firmware upload (%s)...\n",
640 desired_fw->name);
641
642 ret = request_firmware(&fw, desired_fw->name,
643 priv->i2c_props.adap->dev.parent);
644 if (ret) {
645 printk(KERN_ERR "xc5000: Upload failed. (file not found?)\n");
646 ret = XC_RESULT_RESET_FAILURE;
647 goto out;
648 } else {
649 printk(KERN_DEBUG "xc5000: firmware read %Zu bytes.\n",
650 fw->size);
651 ret = XC_RESULT_SUCCESS;
652 }
653
654 if (fw->size != desired_fw->size) {
655 printk(KERN_ERR "xc5000: firmware incorrect size\n");
656 ret = XC_RESULT_RESET_FAILURE;
657 } else {
658 printk(KERN_INFO "xc5000: firmware uploading...\n");
659 ret = xc_load_i2c_sequence(fe, fw->data);
660 if (XC_RESULT_SUCCESS == ret)
661 ret = xc_set_xtal(fe);
662 if (XC_RESULT_SUCCESS == ret)
663 printk(KERN_INFO "xc5000: firmware upload complete...\n");
664 else
665 printk(KERN_ERR "xc5000: firmware upload failed...\n");
666 }
667
668out:
669 release_firmware(fw);
670 return ret;
671}
672
673static void xc_debug_dump(struct xc5000_priv *priv)
674{
675 u16 adc_envelope;
676 u32 freq_error_hz = 0;
677 u16 lock_status;
678 u32 hsync_freq_hz = 0;
679 u16 frame_lines;
680 u16 quality;
681 u16 snr;
682 u16 totalgain;
683 u8 hw_majorversion = 0, hw_minorversion = 0;
684 u8 fw_majorversion = 0, fw_minorversion = 0;
685 u16 fw_buildversion = 0;
686 u16 regval;
687
688 /* Wait for stats to stabilize.
689 * Frame Lines needs two frame times after initial lock
690 * before it is valid.
691 */
692 xc_wait(100);
693
694 xc_get_ADC_Envelope(priv, &adc_envelope);
695 dprintk(1, "*** ADC envelope (0-1023) = %d\n", adc_envelope);
696
697 xc_get_frequency_error(priv, &freq_error_hz);
698 dprintk(1, "*** Frequency error = %d Hz\n", freq_error_hz);
699
700 xc_get_lock_status(priv, &lock_status);
701 dprintk(1, "*** Lock status (0-Wait, 1-Locked, 2-No-signal) = %d\n",
702 lock_status);
703
704 xc_get_version(priv, &hw_majorversion, &hw_minorversion,
705 &fw_majorversion, &fw_minorversion);
706 xc_get_buildversion(priv, &fw_buildversion);
707 dprintk(1, "*** HW: V%d.%d, FW: V %d.%d.%d\n",
708 hw_majorversion, hw_minorversion,
709 fw_majorversion, fw_minorversion, fw_buildversion);
710
711 xc_get_hsync_freq(priv, &hsync_freq_hz);
712 dprintk(1, "*** Horizontal sync frequency = %d Hz\n", hsync_freq_hz);
713
714 xc_get_frame_lines(priv, &frame_lines);
715 dprintk(1, "*** Frame lines = %d\n", frame_lines);
716
717 xc_get_quality(priv, &quality);
718 dprintk(1, "*** Quality (0:<8dB, 7:>56dB) = %d\n", quality & 0x07);
719
720 xc_get_analogsnr(priv, &snr);
721 dprintk(1, "*** Unweighted analog SNR = %d dB\n", snr & 0x3f);
722
723 xc_get_totalgain(priv, &totalgain);
724 dprintk(1, "*** Total gain = %d.%d dB\n", totalgain / 256,
725 (totalgain % 256) * 100 / 256);
726
727 if (priv->pll_register_no) {
728 xc5000_readreg(priv, priv->pll_register_no, &regval);
729 dprintk(1, "*** PLL lock status = 0x%04x\n", regval);
730 }
731}
732
733static int xc5000_set_params(struct dvb_frontend *fe)
734{
735 int ret, b;
736 struct xc5000_priv *priv = fe->tuner_priv;
737 u32 bw = fe->dtv_property_cache.bandwidth_hz;
738 u32 freq = fe->dtv_property_cache.frequency;
739 u32 delsys = fe->dtv_property_cache.delivery_system;
740
741 if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
742 dprintk(1, "Unable to load firmware and init tuner\n");
743 return -EINVAL;
744 }
745
746 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, freq);
747
748 switch (delsys) {
749 case SYS_ATSC:
750 dprintk(1, "%s() VSB modulation\n", __func__);
751 priv->rf_mode = XC_RF_MODE_AIR;
752 priv->freq_hz = freq - 1750000;
753 priv->video_standard = DTV6;
754 break;
755 case SYS_DVBC_ANNEX_B:
756 dprintk(1, "%s() QAM modulation\n", __func__);
757 priv->rf_mode = XC_RF_MODE_CABLE;
758 priv->freq_hz = freq - 1750000;
759 priv->video_standard = DTV6;
760 break;
761 case SYS_ISDBT:
762 /* All ISDB-T are currently for 6 MHz bw */
763 if (!bw)
764 bw = 6000000;
765 /* fall to OFDM handling */
766 case SYS_DMBTH:
767 case SYS_DVBT:
768 case SYS_DVBT2:
769 dprintk(1, "%s() OFDM\n", __func__);
770 switch (bw) {
771 case 6000000:
772 priv->video_standard = DTV6;
773 priv->freq_hz = freq - 1750000;
774 break;
775 case 7000000:
776 priv->video_standard = DTV7;
777 priv->freq_hz = freq - 2250000;
778 break;
779 case 8000000:
780 priv->video_standard = DTV8;
781 priv->freq_hz = freq - 2750000;
782 break;
783 default:
784 printk(KERN_ERR "xc5000 bandwidth not set!\n");
785 return -EINVAL;
786 }
787 priv->rf_mode = XC_RF_MODE_AIR;
788 case SYS_DVBC_ANNEX_A:
789 case SYS_DVBC_ANNEX_C:
790 dprintk(1, "%s() QAM modulation\n", __func__);
791 priv->rf_mode = XC_RF_MODE_CABLE;
792 if (bw <= 6000000) {
793 priv->video_standard = DTV6;
794 priv->freq_hz = freq - 1750000;
795 b = 6;
796 } else if (bw <= 7000000) {
797 priv->video_standard = DTV7;
798 priv->freq_hz = freq - 2250000;
799 b = 7;
800 } else {
801 priv->video_standard = DTV7_8;
802 priv->freq_hz = freq - 2750000;
803 b = 8;
804 }
805 dprintk(1, "%s() Bandwidth %dMHz (%d)\n", __func__,
806 b, bw);
807 break;
808 default:
809 printk(KERN_ERR "xc5000: delivery system is not supported!\n");
810 return -EINVAL;
811 }
812
813 dprintk(1, "%s() frequency=%d (compensated to %d)\n",
814 __func__, freq, priv->freq_hz);
815
816 ret = xc_SetSignalSource(priv, priv->rf_mode);
817 if (ret != XC_RESULT_SUCCESS) {
818 printk(KERN_ERR
819 "xc5000: xc_SetSignalSource(%d) failed\n",
820 priv->rf_mode);
821 return -EREMOTEIO;
822 }
823
824 ret = xc_SetTVStandard(priv,
825 XC5000_Standard[priv->video_standard].VideoMode,
826 XC5000_Standard[priv->video_standard].AudioMode);
827 if (ret != XC_RESULT_SUCCESS) {
828 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
829 return -EREMOTEIO;
830 }
831
832 ret = xc_set_IF_frequency(priv, priv->if_khz);
833 if (ret != XC_RESULT_SUCCESS) {
834 printk(KERN_ERR "xc5000: xc_Set_IF_frequency(%d) failed\n",
835 priv->if_khz);
836 return -EIO;
837 }
838
839 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x8a);
840
841 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_DIGITAL);
842
843 if (debug)
844 xc_debug_dump(priv);
845
846 priv->bandwidth = bw;
847
848 return 0;
849}
850
851static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
852{
853 struct xc5000_priv *priv = fe->tuner_priv;
854 int ret;
855 u16 id;
856
857 ret = xc5000_readreg(priv, XREG_PRODUCT_ID, &id);
858 if (ret == XC_RESULT_SUCCESS) {
859 if (id == XC_PRODUCT_ID_FW_NOT_LOADED)
860 ret = XC_RESULT_RESET_FAILURE;
861 else
862 ret = XC_RESULT_SUCCESS;
863 }
864
865 dprintk(1, "%s() returns %s id = 0x%x\n", __func__,
866 ret == XC_RESULT_SUCCESS ? "True" : "False", id);
867 return ret;
868}
869
870static int xc5000_set_tv_freq(struct dvb_frontend *fe,
871 struct analog_parameters *params)
872{
873 struct xc5000_priv *priv = fe->tuner_priv;
874 u16 pll_lock_status;
875 int ret;
876
877 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
878 __func__, params->frequency);
879
880 /* Fix me: it could be air. */
881 priv->rf_mode = params->mode;
882 if (params->mode > XC_RF_MODE_CABLE)
883 priv->rf_mode = XC_RF_MODE_CABLE;
884
885 /* params->frequency is in units of 62.5khz */
886 priv->freq_hz = params->frequency * 62500;
887
888 /* FIX ME: Some video standards may have several possible audio
889 standards. We simply default to one of them here.
890 */
891 if (params->std & V4L2_STD_MN) {
892 /* default to BTSC audio standard */
893 priv->video_standard = MN_NTSC_PAL_BTSC;
894 goto tune_channel;
895 }
896
897 if (params->std & V4L2_STD_PAL_BG) {
898 /* default to NICAM audio standard */
899 priv->video_standard = BG_PAL_NICAM;
900 goto tune_channel;
901 }
902
903 if (params->std & V4L2_STD_PAL_I) {
904 /* default to NICAM audio standard */
905 priv->video_standard = I_PAL_NICAM;
906 goto tune_channel;
907 }
908
909 if (params->std & V4L2_STD_PAL_DK) {
910 /* default to NICAM audio standard */
911 priv->video_standard = DK_PAL_NICAM;
912 goto tune_channel;
913 }
914
915 if (params->std & V4L2_STD_SECAM_DK) {
916 /* default to A2 DK1 audio standard */
917 priv->video_standard = DK_SECAM_A2DK1;
918 goto tune_channel;
919 }
920
921 if (params->std & V4L2_STD_SECAM_L) {
922 priv->video_standard = L_SECAM_NICAM;
923 goto tune_channel;
924 }
925
926 if (params->std & V4L2_STD_SECAM_LC) {
927 priv->video_standard = LC_SECAM_NICAM;
928 goto tune_channel;
929 }
930
931tune_channel:
932 ret = xc_SetSignalSource(priv, priv->rf_mode);
933 if (ret != XC_RESULT_SUCCESS) {
934 printk(KERN_ERR
935 "xc5000: xc_SetSignalSource(%d) failed\n",
936 priv->rf_mode);
937 return -EREMOTEIO;
938 }
939
940 ret = xc_SetTVStandard(priv,
941 XC5000_Standard[priv->video_standard].VideoMode,
942 XC5000_Standard[priv->video_standard].AudioMode);
943 if (ret != XC_RESULT_SUCCESS) {
944 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
945 return -EREMOTEIO;
946 }
947
948 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
949
950 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
951
952 if (debug)
953 xc_debug_dump(priv);
954
955 if (priv->pll_register_no != 0) {
956 msleep(20);
957 xc5000_readreg(priv, priv->pll_register_no, &pll_lock_status);
958 if (pll_lock_status > 63) {
959 /* PLL is unlocked, force reload of the firmware */
960 dprintk(1, "xc5000: PLL not locked (0x%x). Reloading...\n",
961 pll_lock_status);
962 if (xc_load_fw_and_init_tuner(fe, 1) != XC_RESULT_SUCCESS) {
963 printk(KERN_ERR "xc5000: Unable to reload fw\n");
964 return -EREMOTEIO;
965 }
966 goto tune_channel;
967 }
968 }
969
970 return 0;
971}
972
973static int xc5000_set_radio_freq(struct dvb_frontend *fe,
974 struct analog_parameters *params)
975{
976 struct xc5000_priv *priv = fe->tuner_priv;
977 int ret = -EINVAL;
978 u8 radio_input;
979
980 dprintk(1, "%s() frequency=%d (in units of khz)\n",
981 __func__, params->frequency);
982
983 if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) {
984 dprintk(1, "%s() radio input not configured\n", __func__);
985 return -EINVAL;
986 }
987
988 if (priv->radio_input == XC5000_RADIO_FM1)
989 radio_input = FM_Radio_INPUT1;
990 else if (priv->radio_input == XC5000_RADIO_FM2)
991 radio_input = FM_Radio_INPUT2;
992 else if (priv->radio_input == XC5000_RADIO_FM1_MONO)
993 radio_input = FM_Radio_INPUT1_MONO;
994 else {
995 dprintk(1, "%s() unknown radio input %d\n", __func__,
996 priv->radio_input);
997 return -EINVAL;
998 }
999
1000 priv->freq_hz = params->frequency * 125 / 2;
1001
1002 priv->rf_mode = XC_RF_MODE_AIR;
1003
1004 ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode,
1005 XC5000_Standard[radio_input].AudioMode);
1006
1007 if (ret != XC_RESULT_SUCCESS) {
1008 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
1009 return -EREMOTEIO;
1010 }
1011
1012 ret = xc_SetSignalSource(priv, priv->rf_mode);
1013 if (ret != XC_RESULT_SUCCESS) {
1014 printk(KERN_ERR
1015 "xc5000: xc_SetSignalSource(%d) failed\n",
1016 priv->rf_mode);
1017 return -EREMOTEIO;
1018 }
1019
1020 if ((priv->radio_input == XC5000_RADIO_FM1) ||
1021 (priv->radio_input == XC5000_RADIO_FM2))
1022 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x09);
1023 else if (priv->radio_input == XC5000_RADIO_FM1_MONO)
1024 xc_write_reg(priv, XREG_OUTPUT_AMP, 0x06);
1025
1026 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
1027
1028 return 0;
1029}
1030
1031static int xc5000_set_analog_params(struct dvb_frontend *fe,
1032 struct analog_parameters *params)
1033{
1034 struct xc5000_priv *priv = fe->tuner_priv;
1035 int ret = -EINVAL;
1036
1037 if (priv->i2c_props.adap == NULL)
1038 return -EINVAL;
1039
1040 if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
1041 dprintk(1, "Unable to load firmware and init tuner\n");
1042 return -EINVAL;
1043 }
1044
1045 switch (params->mode) {
1046 case V4L2_TUNER_RADIO:
1047 ret = xc5000_set_radio_freq(fe, params);
1048 break;
1049 case V4L2_TUNER_ANALOG_TV:
1050 case V4L2_TUNER_DIGITAL_TV:
1051 ret = xc5000_set_tv_freq(fe, params);
1052 break;
1053 }
1054
1055 return ret;
1056}
1057
1058
1059static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
1060{
1061 struct xc5000_priv *priv = fe->tuner_priv;
1062 dprintk(1, "%s()\n", __func__);
1063 *freq = priv->freq_hz;
1064 return 0;
1065}
1066
1067static int xc5000_get_if_frequency(struct dvb_frontend *fe, u32 *freq)
1068{
1069 struct xc5000_priv *priv = fe->tuner_priv;
1070 dprintk(1, "%s()\n", __func__);
1071 *freq = priv->if_khz * 1000;
1072 return 0;
1073}
1074
1075static int xc5000_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
1076{
1077 struct xc5000_priv *priv = fe->tuner_priv;
1078 dprintk(1, "%s()\n", __func__);
1079
1080 *bw = priv->bandwidth;
1081 return 0;
1082}
1083
1084static int xc5000_get_status(struct dvb_frontend *fe, u32 *status)
1085{
1086 struct xc5000_priv *priv = fe->tuner_priv;
1087 u16 lock_status = 0;
1088
1089 xc_get_lock_status(priv, &lock_status);
1090
1091 dprintk(1, "%s() lock_status = 0x%08x\n", __func__, lock_status);
1092
1093 *status = lock_status;
1094
1095 return 0;
1096}
1097
1098static int xc_load_fw_and_init_tuner(struct dvb_frontend *fe, int force)
1099{
1100 struct xc5000_priv *priv = fe->tuner_priv;
1101 int ret = XC_RESULT_SUCCESS;
1102 u16 pll_lock_status;
1103 u16 fw_ck;
1104
1105 if (force || xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
1106
1107fw_retry:
1108
1109 ret = xc5000_fwupload(fe);
1110 if (ret != XC_RESULT_SUCCESS)
1111 return ret;
1112
1113 msleep(20);
1114
1115 if (priv->fw_checksum_supported) {
1116 if (xc5000_readreg(priv, XREG_FW_CHECKSUM, &fw_ck)
1117 != XC_RESULT_SUCCESS) {
1118 dprintk(1, "%s() FW checksum reading failed.\n",
1119 __func__);
1120 goto fw_retry;
1121 }
1122
1123 if (fw_ck == 0) {
1124 dprintk(1, "%s() FW checksum failed = 0x%04x\n",
1125 __func__, fw_ck);
1126 goto fw_retry;
1127 }
1128 }
1129
1130 /* Start the tuner self-calibration process */
1131 ret |= xc_initialize(priv);
1132
1133 if (ret != XC_RESULT_SUCCESS)
1134 goto fw_retry;
1135
1136 /* Wait for calibration to complete.
1137 * We could continue but XC5000 will clock stretch subsequent
1138 * I2C transactions until calibration is complete. This way we
1139 * don't have to rely on clock stretching working.
1140 */
1141 xc_wait(100);
1142
1143 if (priv->init_status_supported) {
1144 if (xc5000_readreg(priv, XREG_INIT_STATUS, &fw_ck) != XC_RESULT_SUCCESS) {
1145 dprintk(1, "%s() FW failed reading init status.\n",
1146 __func__);
1147 goto fw_retry;
1148 }
1149
1150 if (fw_ck == 0) {
1151 dprintk(1, "%s() FW init status failed = 0x%04x\n", __func__, fw_ck);
1152 goto fw_retry;
1153 }
1154 }
1155
1156 if (priv->pll_register_no) {
1157 xc5000_readreg(priv, priv->pll_register_no,
1158 &pll_lock_status);
1159 if (pll_lock_status > 63) {
1160 /* PLL is unlocked, force reload of the firmware */
1161 printk(KERN_ERR "xc5000: PLL not running after fwload.\n");
1162 goto fw_retry;
1163 }
1164 }
1165
1166 /* Default to "CABLE" mode */
1167 ret |= xc_write_reg(priv, XREG_SIGNALSOURCE, XC_RF_MODE_CABLE);
1168 }
1169
1170 return ret;
1171}
1172
1173static int xc5000_sleep(struct dvb_frontend *fe)
1174{
1175 int ret;
1176
1177 dprintk(1, "%s()\n", __func__);
1178
1179 /* Avoid firmware reload on slow devices */
1180 if (no_poweroff)
1181 return 0;
1182
1183 /* According to Xceive technical support, the "powerdown" register
1184 was removed in newer versions of the firmware. The "supported"
1185 way to sleep the tuner is to pull the reset pin low for 10ms */
1186 ret = xc5000_TunerReset(fe);
1187 if (ret != XC_RESULT_SUCCESS) {
1188 printk(KERN_ERR
1189 "xc5000: %s() unable to shutdown tuner\n",
1190 __func__);
1191 return -EREMOTEIO;
1192 } else
1193 return XC_RESULT_SUCCESS;
1194}
1195
1196static int xc5000_init(struct dvb_frontend *fe)
1197{
1198 struct xc5000_priv *priv = fe->tuner_priv;
1199 dprintk(1, "%s()\n", __func__);
1200
1201 if (xc_load_fw_and_init_tuner(fe, 0) != XC_RESULT_SUCCESS) {
1202 printk(KERN_ERR "xc5000: Unable to initialise tuner\n");
1203 return -EREMOTEIO;
1204 }
1205
1206 if (debug)
1207 xc_debug_dump(priv);
1208
1209 return 0;
1210}
1211
1212static int xc5000_release(struct dvb_frontend *fe)
1213{
1214 struct xc5000_priv *priv = fe->tuner_priv;
1215
1216 dprintk(1, "%s()\n", __func__);
1217
1218 mutex_lock(&xc5000_list_mutex);
1219
1220 if (priv)
1221 hybrid_tuner_release_state(priv);
1222
1223 mutex_unlock(&xc5000_list_mutex);
1224
1225 fe->tuner_priv = NULL;
1226
1227 return 0;
1228}
1229
1230static int xc5000_set_config(struct dvb_frontend *fe, void *priv_cfg)
1231{
1232 struct xc5000_priv *priv = fe->tuner_priv;
1233 struct xc5000_config *p = priv_cfg;
1234
1235 dprintk(1, "%s()\n", __func__);
1236
1237 if (p->if_khz)
1238 priv->if_khz = p->if_khz;
1239
1240 if (p->radio_input)
1241 priv->radio_input = p->radio_input;
1242
1243 return 0;
1244}
1245
1246
1247static const struct dvb_tuner_ops xc5000_tuner_ops = {
1248 .info = {
1249 .name = "Xceive XC5000",
1250 .frequency_min = 1000000,
1251 .frequency_max = 1023000000,
1252 .frequency_step = 50000,
1253 },
1254
1255 .release = xc5000_release,
1256 .init = xc5000_init,
1257 .sleep = xc5000_sleep,
1258
1259 .set_config = xc5000_set_config,
1260 .set_params = xc5000_set_params,
1261 .set_analog_params = xc5000_set_analog_params,
1262 .get_frequency = xc5000_get_frequency,
1263 .get_if_frequency = xc5000_get_if_frequency,
1264 .get_bandwidth = xc5000_get_bandwidth,
1265 .get_status = xc5000_get_status
1266};
1267
1268struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
1269 struct i2c_adapter *i2c,
1270 const struct xc5000_config *cfg)
1271{
1272 struct xc5000_priv *priv = NULL;
1273 int instance;
1274 u16 id = 0;
1275
1276 dprintk(1, "%s(%d-%04x)\n", __func__,
1277 i2c ? i2c_adapter_id(i2c) : -1,
1278 cfg ? cfg->i2c_address : -1);
1279
1280 mutex_lock(&xc5000_list_mutex);
1281
1282 instance = hybrid_tuner_request_state(struct xc5000_priv, priv,
1283 hybrid_tuner_instance_list,
1284 i2c, cfg->i2c_address, "xc5000");
1285 switch (instance) {
1286 case 0:
1287 goto fail;
1288 break;
1289 case 1:
1290 /* new tuner instance */
1291 priv->bandwidth = 6000000;
1292 fe->tuner_priv = priv;
1293 break;
1294 default:
1295 /* existing tuner instance */
1296 fe->tuner_priv = priv;
1297 break;
1298 }
1299
1300 if (priv->if_khz == 0) {
1301 /* If the IF hasn't been set yet, use the value provided by
1302 the caller (occurs in hybrid devices where the analog
1303 call to xc5000_attach occurs before the digital side) */
1304 priv->if_khz = cfg->if_khz;
1305 }
1306
1307 if (priv->xtal_khz == 0)
1308 priv->xtal_khz = cfg->xtal_khz;
1309
1310 if (priv->radio_input == 0)
1311 priv->radio_input = cfg->radio_input;
1312
1313 /* don't override chip id if it's already been set
1314 unless explicitly specified */
1315 if ((priv->chip_id == 0) || (cfg->chip_id))
1316 /* use default chip id if none specified, set to 0 so
1317 it can be overridden if this is a hybrid driver */
1318 priv->chip_id = (cfg->chip_id) ? cfg->chip_id : 0;
1319
1320 /* Check if firmware has been loaded. It is possible that another
1321 instance of the driver has loaded the firmware.
1322 */
1323 if (xc5000_readreg(priv, XREG_PRODUCT_ID, &id) != XC_RESULT_SUCCESS)
1324 goto fail;
1325
1326 switch (id) {
1327 case XC_PRODUCT_ID_FW_LOADED:
1328 printk(KERN_INFO
1329 "xc5000: Successfully identified at address 0x%02x\n",
1330 cfg->i2c_address);
1331 printk(KERN_INFO
1332 "xc5000: Firmware has been loaded previously\n");
1333 break;
1334 case XC_PRODUCT_ID_FW_NOT_LOADED:
1335 printk(KERN_INFO
1336 "xc5000: Successfully identified at address 0x%02x\n",
1337 cfg->i2c_address);
1338 printk(KERN_INFO
1339 "xc5000: Firmware has not been loaded previously\n");
1340 break;
1341 default:
1342 printk(KERN_ERR
1343 "xc5000: Device not found at addr 0x%02x (0x%x)\n",
1344 cfg->i2c_address, id);
1345 goto fail;
1346 }
1347
1348 mutex_unlock(&xc5000_list_mutex);
1349
1350 memcpy(&fe->ops.tuner_ops, &xc5000_tuner_ops,
1351 sizeof(struct dvb_tuner_ops));
1352
1353 return fe;
1354fail:
1355 mutex_unlock(&xc5000_list_mutex);
1356
1357 xc5000_release(fe);
1358 return NULL;
1359}
1360EXPORT_SYMBOL(xc5000_attach);
1361
1362MODULE_AUTHOR("Steven Toth");
1363MODULE_DESCRIPTION("Xceive xc5000 silicon tuner driver");
1364MODULE_LICENSE("GPL");
1365MODULE_FIRMWARE(XC5000A_FIRMWARE);
1366MODULE_FIRMWARE(XC5000C_FIRMWARE);
diff --git a/drivers/media/tuners/xc5000.h b/drivers/media/tuners/xc5000.h
new file mode 100644
index 000000000000..b1a547494625
--- /dev/null
+++ b/drivers/media/tuners/xc5000.h
@@ -0,0 +1,74 @@
1/*
2 * Driver for Xceive XC5000 "QAM/8VSB single chip tuner"
3 *
4 * Copyright (c) 2007 Steven Toth <stoth@linuxtv.org>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __XC5000_H__
23#define __XC5000_H__
24
25#include <linux/firmware.h>
26
27struct dvb_frontend;
28struct i2c_adapter;
29
30#define XC5000A 1
31#define XC5000C 2
32
33struct xc5000_config {
34 u8 i2c_address;
35 u32 if_khz;
36 u8 radio_input;
37 u16 xtal_khz;
38
39 int chip_id;
40};
41
42/* xc5000 callback command */
43#define XC5000_TUNER_RESET 0
44
45/* Possible Radio inputs */
46#define XC5000_RADIO_NOT_CONFIGURED 0
47#define XC5000_RADIO_FM1 1
48#define XC5000_RADIO_FM2 2
49#define XC5000_RADIO_FM1_MONO 3
50
51/* For each bridge framework, when it attaches either analog or digital,
52 * it has to store a reference back to its _core equivalent structure,
53 * so that it can service the hardware by steering gpio's etc.
54 * Each bridge implementation is different so cast devptr accordingly.
55 * The xc5000 driver cares not for this value, other than ensuring
56 * it's passed back to a bridge during tuner_callback().
57 */
58
59#if defined(CONFIG_MEDIA_TUNER_XC5000) || \
60 (defined(CONFIG_MEDIA_TUNER_XC5000_MODULE) && defined(MODULE))
61extern struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
62 struct i2c_adapter *i2c,
63 const struct xc5000_config *cfg);
64#else
65static inline struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
66 struct i2c_adapter *i2c,
67 const struct xc5000_config *cfg)
68{
69 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
70 return NULL;
71}
72#endif
73
74#endif