aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/dvb/frontends
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-09-30 12:39:15 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-09-30 12:39:15 -0400
commit5ffd1a6aaacc25be8cd0770a51ec6d46add3a276 (patch)
tree5b076c44f8b7ff88dba9a554d7748c6f083c9071 /drivers/media/dvb/frontends
parent0cd43f83d381c4246a08cd775834833d6fd64805 (diff)
parent8dd86eebc5315910ebfd9f30f1674254308be4b3 (diff)
Merge master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb
* master.kernel.org:/pub/scm/linux/kernel/git/mchehab/v4l-dvb: (180 commits) V4L/DVB (4641): Trivial: use lowercase letters in hex subsystem ids V4L/DVB (4639): Cx88: add autodetection for alternate revision of Leadtek PVR V4L/DVB (4638): Basic DVB-T and analog TV support for the HVR1300. V4L/DVB (4637): Add a default method for VIDIOC_G_PARM V4L/DVB (4635): Extend bttv and saa7134 to check for both AGP and PCI PCI failure case V4L/DVB (4634): Zr36120: implement pcipci checks V4L/DVB (4632): Zoran: Implement pcipci failure check V4L/DVB (4631): Av7110: remove V4L2_CAP_VBI_CAPTURE flag V4L/DVB (4630): Av7110: FW_LOADER depemdency fixed V4L/DVB (4629): Saa7134: add card support for Proteus Pro 2309 V4L/DVB (4628): Fix VIDIOC_ENUMSTD ioctl in videodev.c V4L/DVB (4627): Vivi crashes with mplayer V4L/DVB (4626): On saa7111/7113, LUMA_CTRL need a different value V4L/DVB (4624): Tvaudio: Replaced kernel_thread() with kthread_run() V4L/DVB (4622): Copy-paste bug in videodev.c V4L/DVB (4620): Fix AGC configuration for MOD3000P-based boards V4L/DVB (4619): Fixes some I2C dependencies on V4L devices V4L/DVB (4617): Problem with dibusb-mb.c USB IDs V4L/DVB (4616): [PATCH] Nebula DigiTV USB RC support V4L/DVB (4614): Export symbol saa7134_tvaudio_setmute from saa7134 for saa7134-alsa ...
Diffstat (limited to 'drivers/media/dvb/frontends')
-rw-r--r--drivers/media/dvb/frontends/Kconfig71
-rw-r--r--drivers/media/dvb/frontends/Makefile8
-rw-r--r--drivers/media/dvb/frontends/bcm3510.h9
-rw-r--r--drivers/media/dvb/frontends/cx22700.h9
-rw-r--r--drivers/media/dvb/frontends/cx22702.c4
-rw-r--r--drivers/media/dvb/frontends/cx22702.h9
-rw-r--r--drivers/media/dvb/frontends/cx24110.c17
-rw-r--r--drivers/media/dvb/frontends/cx24110.h19
-rw-r--r--drivers/media/dvb/frontends/cx24123.c98
-rw-r--r--drivers/media/dvb/frontends/cx24123.h12
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.c83
-rw-r--r--drivers/media/dvb/frontends/dib3000-common.h135
-rw-r--r--drivers/media/dvb/frontends/dib3000.h11
-rw-r--r--drivers/media/dvb/frontends/dib3000mb.c76
-rw-r--r--drivers/media/dvb/frontends/dib3000mb_priv.h93
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.c1432
-rw-r--r--drivers/media/dvb/frontends/dib3000mc.h58
-rw-r--r--drivers/media/dvb/frontends/dib3000mc_priv.h428
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.c152
-rw-r--r--drivers/media/dvb/frontends/dibx000_common.h166
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.c11
-rw-r--r--drivers/media/dvb/frontends/dvb-pll.h4
-rw-r--r--drivers/media/dvb/frontends/isl6421.c30
-rw-r--r--drivers/media/dvb/frontends/isl6421.h11
-rw-r--r--drivers/media/dvb/frontends/l64781.h10
-rw-r--r--drivers/media/dvb/frontends/lgdt330x.h9
-rw-r--r--drivers/media/dvb/frontends/lnbp21.c30
-rw-r--r--drivers/media/dvb/frontends/lnbp21.h12
-rw-r--r--drivers/media/dvb/frontends/mt2060.c367
-rw-r--r--drivers/media/dvb/frontends/mt2060.h35
-rw-r--r--drivers/media/dvb/frontends/mt2060_priv.h105
-rw-r--r--drivers/media/dvb/frontends/mt312.h10
-rw-r--r--drivers/media/dvb/frontends/mt352.c16
-rw-r--r--drivers/media/dvb/frontends/mt352.h16
-rw-r--r--drivers/media/dvb/frontends/nxt200x.h9
-rw-r--r--drivers/media/dvb/frontends/nxt6000.h9
-rw-r--r--drivers/media/dvb/frontends/or51132.h9
-rw-r--r--drivers/media/dvb/frontends/or51211.h9
-rw-r--r--drivers/media/dvb/frontends/s5h1420.h9
-rw-r--r--drivers/media/dvb/frontends/sp8870.h9
-rw-r--r--drivers/media/dvb/frontends/sp887x.h9
-rw-r--r--drivers/media/dvb/frontends/stv0297.h9
-rw-r--r--drivers/media/dvb/frontends/stv0299.c9
-rw-r--r--drivers/media/dvb/frontends/stv0299.h19
-rw-r--r--drivers/media/dvb/frontends/tda10021.c63
-rw-r--r--drivers/media/dvb/frontends/tda10021.h19
-rw-r--r--drivers/media/dvb/frontends/tda1004x.c10
-rw-r--r--drivers/media/dvb/frontends/tda1004x.h25
-rw-r--r--drivers/media/dvb/frontends/tda10086.c740
-rw-r--r--drivers/media/dvb/frontends/tda10086.h41
-rw-r--r--drivers/media/dvb/frontends/tda8083.h9
-rw-r--r--drivers/media/dvb/frontends/tda826x.c173
-rw-r--r--drivers/media/dvb/frontends/tda826x.h40
-rw-r--r--drivers/media/dvb/frontends/tua6100.c205
-rw-r--r--drivers/media/dvb/frontends/tua6100.h47
-rw-r--r--drivers/media/dvb/frontends/ves1820.h9
-rw-r--r--drivers/media/dvb/frontends/ves1x93.h9
-rw-r--r--drivers/media/dvb/frontends/zl10353.c11
-rw-r--r--drivers/media/dvb/frontends/zl10353.h14
59 files changed, 3547 insertions, 1524 deletions
diff --git a/drivers/media/dvb/frontends/Kconfig b/drivers/media/dvb/frontends/Kconfig
index db978555b1eb..080fa257a0bc 100644
--- a/drivers/media/dvb/frontends/Kconfig
+++ b/drivers/media/dvb/frontends/Kconfig
@@ -1,48 +1,73 @@
1menu "Customise DVB Frontends" 1menu "Customise DVB Frontends"
2 depends on DVB_CORE 2 depends on DVB_CORE
3 3
4config DVB_FE_CUSTOMISE
5 bool "Customise the frontend modules to build"
6 default N
7 help
8 This allows the user to deselect frontend drivers unnecessary
9 for their hardware from the build. Use this option with care
10 as deselecting frontends which are in fact necessary will result
11 in DVB devices which cannot be tuned due to lack of driver support.
12
13 If unsure say N.
14
4comment "DVB-S (satellite) frontends" 15comment "DVB-S (satellite) frontends"
5 depends on DVB_CORE 16 depends on DVB_CORE
6 17
7config DVB_STV0299 18config DVB_STV0299
8 tristate "ST STV0299 based" 19 tristate "ST STV0299 based"
9 depends on DVB_CORE && I2C 20 depends on DVB_CORE && I2C
21 default m if DVB_FE_CUSTOMISE
10 help 22 help
11 A DVB-S tuner module. Say Y when you want to support this frontend. 23 A DVB-S tuner module. Say Y when you want to support this frontend.
12 24
13config DVB_CX24110 25config DVB_CX24110
14 tristate "Conexant CX24110 based" 26 tristate "Conexant CX24110 based"
15 depends on DVB_CORE && I2C 27 depends on DVB_CORE && I2C
28 default m if DVB_FE_CUSTOMISE
16 help 29 help
17 A DVB-S tuner module. Say Y when you want to support this frontend. 30 A DVB-S tuner module. Say Y when you want to support this frontend.
18 31
19config DVB_CX24123 32config DVB_CX24123
20 tristate "Conexant CX24123 based" 33 tristate "Conexant CX24123 based"
21 depends on DVB_CORE && I2C 34 depends on DVB_CORE && I2C
35 default m if DVB_FE_CUSTOMISE
22 help 36 help
23 A DVB-S tuner module. Say Y when you want to support this frontend. 37 A DVB-S tuner module. Say Y when you want to support this frontend.
24 38
25config DVB_TDA8083 39config DVB_TDA8083
26 tristate "Philips TDA8083 based" 40 tristate "Philips TDA8083 based"
27 depends on DVB_CORE && I2C 41 depends on DVB_CORE && I2C
42 default m if DVB_FE_CUSTOMISE
28 help 43 help
29 A DVB-S tuner module. Say Y when you want to support this frontend. 44 A DVB-S tuner module. Say Y when you want to support this frontend.
30 45
31config DVB_MT312 46config DVB_MT312
32 tristate "Zarlink VP310/MT312 based" 47 tristate "Zarlink VP310/MT312 based"
33 depends on DVB_CORE && I2C 48 depends on DVB_CORE && I2C
49 default m if DVB_FE_CUSTOMISE
34 help 50 help
35 A DVB-S tuner module. Say Y when you want to support this frontend. 51 A DVB-S tuner module. Say Y when you want to support this frontend.
36 52
37config DVB_VES1X93 53config DVB_VES1X93
38 tristate "VLSI VES1893 or VES1993 based" 54 tristate "VLSI VES1893 or VES1993 based"
39 depends on DVB_CORE && I2C 55 depends on DVB_CORE && I2C
56 default m if DVB_FE_CUSTOMISE
40 help 57 help
41 A DVB-S tuner module. Say Y when you want to support this frontend. 58 A DVB-S tuner module. Say Y when you want to support this frontend.
42 59
43config DVB_S5H1420 60config DVB_S5H1420
44 tristate "Samsung S5H1420 based" 61 tristate "Samsung S5H1420 based"
45 depends on DVB_CORE && I2C 62 depends on DVB_CORE && I2C
63 default m if DVB_FE_CUSTOMISE
64 help
65 A DVB-S tuner module. Say Y when you want to support this frontend.
66
67config DVB_TDA10086
68 tristate "Philips TDA10086 based"
69 depends on DVB_CORE && I2C
70 default m if DVB_FE_CUSTOMISE
46 help 71 help
47 A DVB-S tuner module. Say Y when you want to support this frontend. 72 A DVB-S tuner module. Say Y when you want to support this frontend.
48 73
@@ -52,6 +77,7 @@ comment "DVB-T (terrestrial) frontends"
52config DVB_SP8870 77config DVB_SP8870
53 tristate "Spase sp8870 based" 78 tristate "Spase sp8870 based"
54 depends on DVB_CORE && I2C 79 depends on DVB_CORE && I2C
80 default m if DVB_FE_CUSTOMISE
55 select FW_LOADER 81 select FW_LOADER
56 help 82 help
57 A DVB-T tuner module. Say Y when you want to support this frontend. 83 A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -64,6 +90,7 @@ config DVB_SP8870
64config DVB_SP887X 90config DVB_SP887X
65 tristate "Spase sp887x based" 91 tristate "Spase sp887x based"
66 depends on DVB_CORE && I2C 92 depends on DVB_CORE && I2C
93 default m if DVB_FE_CUSTOMISE
67 select FW_LOADER 94 select FW_LOADER
68 help 95 help
69 A DVB-T tuner module. Say Y when you want to support this frontend. 96 A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -76,24 +103,28 @@ config DVB_SP887X
76config DVB_CX22700 103config DVB_CX22700
77 tristate "Conexant CX22700 based" 104 tristate "Conexant CX22700 based"
78 depends on DVB_CORE && I2C 105 depends on DVB_CORE && I2C
106 default m if DVB_FE_CUSTOMISE
79 help 107 help
80 A DVB-T tuner module. Say Y when you want to support this frontend. 108 A DVB-T tuner module. Say Y when you want to support this frontend.
81 109
82config DVB_CX22702 110config DVB_CX22702
83 tristate "Conexant cx22702 demodulator (OFDM)" 111 tristate "Conexant cx22702 demodulator (OFDM)"
84 depends on DVB_CORE && I2C 112 depends on DVB_CORE && I2C
113 default m if DVB_FE_CUSTOMISE
85 help 114 help
86 A DVB-T tuner module. Say Y when you want to support this frontend. 115 A DVB-T tuner module. Say Y when you want to support this frontend.
87 116
88config DVB_L64781 117config DVB_L64781
89 tristate "LSI L64781" 118 tristate "LSI L64781"
90 depends on DVB_CORE && I2C 119 depends on DVB_CORE && I2C
120 default m if DVB_FE_CUSTOMISE
91 help 121 help
92 A DVB-T tuner module. Say Y when you want to support this frontend. 122 A DVB-T tuner module. Say Y when you want to support this frontend.
93 123
94config DVB_TDA1004X 124config DVB_TDA1004X
95 tristate "Philips TDA10045H/TDA10046H based" 125 tristate "Philips TDA10045H/TDA10046H based"
96 depends on DVB_CORE && I2C 126 depends on DVB_CORE && I2C
127 default m if DVB_FE_CUSTOMISE
97 select FW_LOADER 128 select FW_LOADER
98 help 129 help
99 A DVB-T tuner module. Say Y when you want to support this frontend. 130 A DVB-T tuner module. Say Y when you want to support this frontend.
@@ -107,24 +138,28 @@ config DVB_TDA1004X
107config DVB_NXT6000 138config DVB_NXT6000
108 tristate "NxtWave Communications NXT6000 based" 139 tristate "NxtWave Communications NXT6000 based"
109 depends on DVB_CORE && I2C 140 depends on DVB_CORE && I2C
141 default m if DVB_FE_CUSTOMISE
110 help 142 help
111 A DVB-T tuner module. Say Y when you want to support this frontend. 143 A DVB-T tuner module. Say Y when you want to support this frontend.
112 144
113config DVB_MT352 145config DVB_MT352
114 tristate "Zarlink MT352 based" 146 tristate "Zarlink MT352 based"
115 depends on DVB_CORE && I2C 147 depends on DVB_CORE && I2C
148 default m if DVB_FE_CUSTOMISE
116 help 149 help
117 A DVB-T tuner module. Say Y when you want to support this frontend. 150 A DVB-T tuner module. Say Y when you want to support this frontend.
118 151
119config DVB_ZL10353 152config DVB_ZL10353
120 tristate "Zarlink ZL10353 based" 153 tristate "Zarlink ZL10353 based"
121 depends on DVB_CORE && I2C 154 depends on DVB_CORE && I2C
155 default m if DVB_FE_CUSTOMISE
122 help 156 help
123 A DVB-T tuner module. Say Y when you want to support this frontend. 157 A DVB-T tuner module. Say Y when you want to support this frontend.
124 158
125config DVB_DIB3000MB 159config DVB_DIB3000MB
126 tristate "DiBcom 3000M-B" 160 tristate "DiBcom 3000M-B"
127 depends on DVB_CORE && I2C 161 depends on DVB_CORE && I2C
162 default m if DVB_FE_CUSTOMISE
128 help 163 help
129 A DVB-T tuner module. Designed for mobile usage. Say Y when you want 164 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
130 to support this frontend. 165 to support this frontend.
@@ -132,6 +167,7 @@ config DVB_DIB3000MB
132config DVB_DIB3000MC 167config DVB_DIB3000MC
133 tristate "DiBcom 3000P/M-C" 168 tristate "DiBcom 3000P/M-C"
134 depends on DVB_CORE && I2C 169 depends on DVB_CORE && I2C
170 default m if DVB_FE_CUSTOMISE
135 help 171 help
136 A DVB-T tuner module. Designed for mobile usage. Say Y when you want 172 A DVB-T tuner module. Designed for mobile usage. Say Y when you want
137 to support this frontend. 173 to support this frontend.
@@ -142,18 +178,21 @@ comment "DVB-C (cable) frontends"
142config DVB_VES1820 178config DVB_VES1820
143 tristate "VLSI VES1820 based" 179 tristate "VLSI VES1820 based"
144 depends on DVB_CORE && I2C 180 depends on DVB_CORE && I2C
181 default m if DVB_FE_CUSTOMISE
145 help 182 help
146 A DVB-C tuner module. Say Y when you want to support this frontend. 183 A DVB-C tuner module. Say Y when you want to support this frontend.
147 184
148config DVB_TDA10021 185config DVB_TDA10021
149 tristate "Philips TDA10021 based" 186 tristate "Philips TDA10021 based"
150 depends on DVB_CORE && I2C 187 depends on DVB_CORE && I2C
188 default m if DVB_FE_CUSTOMISE
151 help 189 help
152 A DVB-C tuner module. Say Y when you want to support this frontend. 190 A DVB-C tuner module. Say Y when you want to support this frontend.
153 191
154config DVB_STV0297 192config DVB_STV0297
155 tristate "ST STV0297 based" 193 tristate "ST STV0297 based"
156 depends on DVB_CORE && I2C 194 depends on DVB_CORE && I2C
195 default m if DVB_FE_CUSTOMISE
157 help 196 help
158 A DVB-C tuner module. Say Y when you want to support this frontend. 197 A DVB-C tuner module. Say Y when you want to support this frontend.
159 198
@@ -163,6 +202,7 @@ comment "ATSC (North American/Korean Terrestrial/Cable DTV) frontends"
163config DVB_NXT200X 202config DVB_NXT200X
164 tristate "NxtWave Communications NXT2002/NXT2004 based" 203 tristate "NxtWave Communications NXT2002/NXT2004 based"
165 depends on DVB_CORE && I2C 204 depends on DVB_CORE && I2C
205 default m if DVB_FE_CUSTOMISE
166 select FW_LOADER 206 select FW_LOADER
167 help 207 help
168 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 208 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
@@ -177,6 +217,7 @@ config DVB_NXT200X
177config DVB_OR51211 217config DVB_OR51211
178 tristate "Oren OR51211 based" 218 tristate "Oren OR51211 based"
179 depends on DVB_CORE && I2C 219 depends on DVB_CORE && I2C
220 default m if DVB_FE_CUSTOMISE
180 select FW_LOADER 221 select FW_LOADER
181 help 222 help
182 An ATSC 8VSB tuner module. Say Y when you want to support this frontend. 223 An ATSC 8VSB tuner module. Say Y when you want to support this frontend.
@@ -189,6 +230,7 @@ config DVB_OR51211
189config DVB_OR51132 230config DVB_OR51132
190 tristate "Oren OR51132 based" 231 tristate "Oren OR51132 based"
191 depends on DVB_CORE && I2C 232 depends on DVB_CORE && I2C
233 default m if DVB_FE_CUSTOMISE
192 select FW_LOADER 234 select FW_LOADER
193 help 235 help
194 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 236 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
@@ -204,6 +246,7 @@ config DVB_OR51132
204config DVB_BCM3510 246config DVB_BCM3510
205 tristate "Broadcom BCM3510" 247 tristate "Broadcom BCM3510"
206 depends on DVB_CORE && I2C 248 depends on DVB_CORE && I2C
249 default m if DVB_FE_CUSTOMISE
207 select FW_LOADER 250 select FW_LOADER
208 help 251 help
209 An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to 252 An ATSC 8VSB/16VSB and QAM64/256 tuner module. Say Y when you want to
@@ -212,28 +255,52 @@ config DVB_BCM3510
212config DVB_LGDT330X 255config DVB_LGDT330X
213 tristate "LG Electronics LGDT3302/LGDT3303 based" 256 tristate "LG Electronics LGDT3302/LGDT3303 based"
214 depends on DVB_CORE && I2C 257 depends on DVB_CORE && I2C
258 default m if DVB_FE_CUSTOMISE
215 help 259 help
216 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want 260 An ATSC 8VSB and QAM64/256 tuner module. Say Y when you want
217 to support this frontend. 261 to support this frontend.
218 262
219 263comment "Tuners/PLL support"
220comment "Miscellaneous devices"
221 depends on DVB_CORE 264 depends on DVB_CORE
222 265
223config DVB_PLL 266config DVB_PLL
224 tristate 267 tristate
225 depends on DVB_CORE && I2C 268 depends on DVB_CORE && I2C
226 269
270config DVB_TDA826X
271 tristate "Philips TDA826X silicon tuner"
272 depends on DVB_CORE && I2C
273 default m if DVB_FE_CUSTOMISE
274 help
275 A DVB-S silicon tuner module. Say Y when you want to support this tuner.
276
277config DVB_TUNER_MT2060
278 tristate "Microtune MT2060 silicon IF tuner"
279 help
280 A driver for the silicon IF tuner MT2060 from Microtune.
281
282comment "Miscellaneous devices"
283 depends on DVB_CORE
284
227config DVB_LNBP21 285config DVB_LNBP21
228 tristate "LNBP21 SEC controller" 286 tristate "LNBP21 SEC controller"
229 depends on DVB_CORE && I2C 287 depends on DVB_CORE && I2C
288 default m if DVB_FE_CUSTOMISE
230 help 289 help
231 An SEC control chip. 290 An SEC control chip.
232 291
233config DVB_ISL6421 292config DVB_ISL6421
234 tristate "ISL6421 SEC controller" 293 tristate "ISL6421 SEC controller"
235 depends on DVB_CORE && I2C 294 depends on DVB_CORE && I2C
295 default m if DVB_FE_CUSTOMISE
236 help 296 help
237 An SEC control chip. 297 An SEC control chip.
238 298
299config DVB_TUA6100
300 tristate "TUA6100 PLL"
301 depends on DVB_CORE && I2C
302 default m if DVB_FE_CUSTOMISE
303 help
304 A DVBS PLL chip.
305
239endmenu 306endmenu
diff --git a/drivers/media/dvb/frontends/Makefile b/drivers/media/dvb/frontends/Makefile
index 0e4880b6db14..dce9cf0c75c0 100644
--- a/drivers/media/dvb/frontends/Makefile
+++ b/drivers/media/dvb/frontends/Makefile
@@ -11,8 +11,8 @@ obj-$(CONFIG_DVB_CX22700) += cx22700.o
11obj-$(CONFIG_DVB_CX24110) += cx24110.o 11obj-$(CONFIG_DVB_CX24110) += cx24110.o
12obj-$(CONFIG_DVB_TDA8083) += tda8083.o 12obj-$(CONFIG_DVB_TDA8083) += tda8083.o
13obj-$(CONFIG_DVB_L64781) += l64781.o 13obj-$(CONFIG_DVB_L64781) += l64781.o
14obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o dib3000-common.o 14obj-$(CONFIG_DVB_DIB3000MB) += dib3000mb.o
15obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dib3000-common.o 15obj-$(CONFIG_DVB_DIB3000MC) += dib3000mc.o dibx000_common.o
16obj-$(CONFIG_DVB_MT312) += mt312.o 16obj-$(CONFIG_DVB_MT312) += mt312.o
17obj-$(CONFIG_DVB_VES1820) += ves1820.o 17obj-$(CONFIG_DVB_VES1820) += ves1820.o
18obj-$(CONFIG_DVB_VES1X93) += ves1x93.o 18obj-$(CONFIG_DVB_VES1X93) += ves1x93.o
@@ -33,3 +33,7 @@ obj-$(CONFIG_DVB_LGDT330X) += lgdt330x.o
33obj-$(CONFIG_DVB_CX24123) += cx24123.o 33obj-$(CONFIG_DVB_CX24123) += cx24123.o
34obj-$(CONFIG_DVB_LNBP21) += lnbp21.o 34obj-$(CONFIG_DVB_LNBP21) += lnbp21.o
35obj-$(CONFIG_DVB_ISL6421) += isl6421.o 35obj-$(CONFIG_DVB_ISL6421) += isl6421.o
36obj-$(CONFIG_DVB_TDA10086) += tda10086.o
37obj-$(CONFIG_DVB_TDA826X) += tda826x.o
38obj-$(CONFIG_DVB_TUNER_MT2060) += mt2060.o
39obj-$(CONFIG_DVB_TUA6100) += tua6100.o
diff --git a/drivers/media/dvb/frontends/bcm3510.h b/drivers/media/dvb/frontends/bcm3510.h
index 80f5d0953d02..6dfa839a7022 100644
--- a/drivers/media/dvb/frontends/bcm3510.h
+++ b/drivers/media/dvb/frontends/bcm3510.h
@@ -34,7 +34,16 @@ struct bcm3510_config
34 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); 34 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
35}; 35};
36 36
37#if defined(CONFIG_DVB_BCM3510) || defined(CONFIG_DVB_BCM3510_MODULE)
37extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config, 38extern struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
38 struct i2c_adapter* i2c); 39 struct i2c_adapter* i2c);
40#else
41static inline struct dvb_frontend* bcm3510_attach(const struct bcm3510_config* config,
42 struct i2c_adapter* i2c)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
45 return NULL;
46}
47#endif // CONFIG_DVB_BCM3510
39 48
40#endif 49#endif
diff --git a/drivers/media/dvb/frontends/cx22700.h b/drivers/media/dvb/frontends/cx22700.h
index dcd8979c1a15..10286cc29fb4 100644
--- a/drivers/media/dvb/frontends/cx22700.h
+++ b/drivers/media/dvb/frontends/cx22700.h
@@ -31,7 +31,16 @@ struct cx22700_config
31 u8 demod_address; 31 u8 demod_address;
32}; 32};
33 33
34#if defined(CONFIG_DVB_CX22700) || defined(CONFIG_DVB_CX22700_MODULE)
34extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config, 35extern struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
35 struct i2c_adapter* i2c); 36 struct i2c_adapter* i2c);
37#else
38static inline struct dvb_frontend* cx22700_attach(const struct cx22700_config* config,
39 struct i2c_adapter* i2c)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
42 return NULL;
43}
44#endif // CONFIG_DVB_CX22700
36 45
37#endif // CX22700_H 46#endif // CX22700_H
diff --git a/drivers/media/dvb/frontends/cx22702.c b/drivers/media/dvb/frontends/cx22702.c
index 4106d46c957f..335219ebce2d 100644
--- a/drivers/media/dvb/frontends/cx22702.c
+++ b/drivers/media/dvb/frontends/cx22702.c
@@ -399,7 +399,9 @@ static int cx22702_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
399{ 399{
400 struct cx22702_state* state = fe->demodulator_priv; 400 struct cx22702_state* state = fe->demodulator_priv;
401 401
402 *signal_strength = cx22702_readreg (state, 0x23); 402 u16 rs_ber = 0;
403 rs_ber = cx22702_readreg (state, 0x23);
404 *signal_strength = (rs_ber << 8) | rs_ber;
403 405
404 return 0; 406 return 0;
405} 407}
diff --git a/drivers/media/dvb/frontends/cx22702.h b/drivers/media/dvb/frontends/cx22702.h
index 7f2f241e5d44..bc217ddf02c0 100644
--- a/drivers/media/dvb/frontends/cx22702.h
+++ b/drivers/media/dvb/frontends/cx22702.h
@@ -41,7 +41,16 @@ struct cx22702_config
41 u8 output_mode; 41 u8 output_mode;
42}; 42};
43 43
44#if defined(CONFIG_DVB_CX22702) || defined(CONFIG_DVB_CX22702_MODULE)
44extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config, 45extern struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
45 struct i2c_adapter* i2c); 46 struct i2c_adapter* i2c);
47#else
48static inline struct dvb_frontend* cx22702_attach(const struct cx22702_config* config,
49 struct i2c_adapter* i2c)
50{
51 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
52 return NULL;
53}
54#endif // CONFIG_DVB_CX22702
46 55
47#endif // CX22702_H 56#endif // CX22702_H
diff --git a/drivers/media/dvb/frontends/cx24110.c b/drivers/media/dvb/frontends/cx24110.c
index ce3c7398bac9..ae96395217a2 100644
--- a/drivers/media/dvb/frontends/cx24110.c
+++ b/drivers/media/dvb/frontends/cx24110.c
@@ -1,4 +1,4 @@
1/* 1 /*
2 cx24110 - Single Chip Satellite Channel Receiver driver module 2 cx24110 - Single Chip Satellite Channel Receiver driver module
3 3
4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on 4 Copyright (C) 2002 Peter Hettkamp <peter.hettkamp@htp-tel.de> based on
@@ -311,16 +311,17 @@ static int cx24110_set_symbolrate (struct cx24110_state* state, u32 srate)
311 311
312} 312}
313 313
314int cx24110_pll_write (struct dvb_frontend* fe, u32 data) 314static int _cx24110_pll_write (struct dvb_frontend* fe, u8 *buf, int len)
315{ 315{
316 struct cx24110_state *state = fe->demodulator_priv; 316 struct cx24110_state *state = fe->demodulator_priv;
317 317
318 if (len != 3)
319 return -EINVAL;
320
318/* tuner data is 21 bits long, must be left-aligned in data */ 321/* tuner data is 21 bits long, must be left-aligned in data */
319/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */ 322/* tuner cx24108 is written through a dedicated 3wire interface on the demod chip */
320/* FIXME (low): add error handling, avoid infinite loops if HW fails... */ 323/* FIXME (low): add error handling, avoid infinite loops if HW fails... */
321 324
322 dprintk("cx24110 debug: cx24108_write(%8.8x)\n",data);
323
324 cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */ 325 cx24110_writereg(state,0x6d,0x30); /* auto mode at 62kHz */
325 cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */ 326 cx24110_writereg(state,0x70,0x15); /* auto mode 21 bits */
326 327
@@ -329,19 +330,19 @@ int cx24110_pll_write (struct dvb_frontend* fe, u32 data)
329 cx24110_writereg(state,0x72,0); 330 cx24110_writereg(state,0x72,0);
330 331
331 /* write the topmost 8 bits */ 332 /* write the topmost 8 bits */
332 cx24110_writereg(state,0x72,(data>>24)&0xff); 333 cx24110_writereg(state,0x72,buf[0]);
333 334
334 /* wait for the send to be completed */ 335 /* wait for the send to be completed */
335 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) 336 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
336 ; 337 ;
337 338
338 /* send another 8 bytes */ 339 /* send another 8 bytes */
339 cx24110_writereg(state,0x72,(data>>16)&0xff); 340 cx24110_writereg(state,0x72,buf[1]);
340 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) 341 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
341 ; 342 ;
342 343
343 /* and the topmost 5 bits of this byte */ 344 /* and the topmost 5 bits of this byte */
344 cx24110_writereg(state,0x72,(data>>8)&0xff); 345 cx24110_writereg(state,0x72,buf[2]);
345 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80) 346 while ((cx24110_readreg(state,0x6d)&0xc0)==0x80)
346 ; 347 ;
347 348
@@ -642,6 +643,7 @@ static struct dvb_frontend_ops cx24110_ops = {
642 .release = cx24110_release, 643 .release = cx24110_release,
643 644
644 .init = cx24110_initfe, 645 .init = cx24110_initfe,
646 .write = _cx24110_pll_write,
645 .set_frontend = cx24110_set_frontend, 647 .set_frontend = cx24110_set_frontend,
646 .get_frontend = cx24110_get_frontend, 648 .get_frontend = cx24110_get_frontend,
647 .read_status = cx24110_read_status, 649 .read_status = cx24110_read_status,
@@ -664,4 +666,3 @@ MODULE_AUTHOR("Peter Hettkamp");
664MODULE_LICENSE("GPL"); 666MODULE_LICENSE("GPL");
665 667
666EXPORT_SYMBOL(cx24110_attach); 668EXPORT_SYMBOL(cx24110_attach);
667EXPORT_SYMBOL(cx24110_pll_write);
diff --git a/drivers/media/dvb/frontends/cx24110.h b/drivers/media/dvb/frontends/cx24110.h
index b354a64e0e74..c9d5ae250ebb 100644
--- a/drivers/media/dvb/frontends/cx24110.h
+++ b/drivers/media/dvb/frontends/cx24110.h
@@ -33,9 +33,24 @@ struct cx24110_config
33 u8 demod_address; 33 u8 demod_address;
34}; 34};
35 35
36static inline int cx24110_pll_write(struct dvb_frontend *fe, u32 val) {
37 int r = 0;
38 u8 buf[] = {(u8) (val>>24), (u8) (val>>16), (u8) (val>>8)};
39 if (fe->ops.write)
40 r = fe->ops.write(fe, buf, 3);
41 return r;
42}
43
44#if defined(CONFIG_DVB_CX24110) || defined(CONFIG_DVB_CX24110_MODULE)
36extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config, 45extern struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
37 struct i2c_adapter* i2c); 46 struct i2c_adapter* i2c);
38 47#else
39extern int cx24110_pll_write(struct dvb_frontend* fe, u32 data); 48static inline struct dvb_frontend* cx24110_attach(const struct cx24110_config* config,
49 struct i2c_adapter* i2c)
50{
51 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
52 return NULL;
53}
54#endif // CONFIG_DVB_CX24110
40 55
41#endif // CX24110_H 56#endif // CX24110_H
diff --git a/drivers/media/dvb/frontends/cx24123.c b/drivers/media/dvb/frontends/cx24123.c
index 274a87b7a5d5..62d69a6ea699 100644
--- a/drivers/media/dvb/frontends/cx24123.c
+++ b/drivers/media/dvb/frontends/cx24123.c
@@ -45,9 +45,6 @@ struct cx24123_state
45 45
46 struct dvb_frontend frontend; 46 struct dvb_frontend frontend;
47 47
48 u32 lastber;
49 u16 snr;
50
51 /* Some PLL specifics for tuning */ 48 /* Some PLL specifics for tuning */
52 u32 VCAarg; 49 u32 VCAarg;
53 u32 VGAarg; 50 u32 VGAarg;
@@ -194,7 +191,7 @@ static struct {
194 {0x06, 0x31}, /* MPEG (default) */ 191 {0x06, 0x31}, /* MPEG (default) */
195 {0x0b, 0x00}, /* Freq search start point (default) */ 192 {0x0b, 0x00}, /* Freq search start point (default) */
196 {0x0c, 0x00}, /* Demodulator sample gain (default) */ 193 {0x0c, 0x00}, /* Demodulator sample gain (default) */
197 {0x0d, 0x02}, /* Frequency search range = Fsymbol / 4 (default) */ 194 {0x0d, 0x7f}, /* Force driver to shift until the maximum (+-10 MHz) */
198 {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */ 195 {0x0e, 0x03}, /* Default non-inverted, FEC 3/4 (default) */
199 {0x0f, 0xfe}, /* FEC search mask (all supported codes) */ 196 {0x0f, 0xfe}, /* FEC search mask (all supported codes) */
200 {0x10, 0x01}, /* Default search inversion, no repeat (default) */ 197 {0x10, 0x01}, /* Default search inversion, no repeat (default) */
@@ -223,8 +220,9 @@ static struct {
223 {0x44, 0x00}, /* Constellation (default) */ 220 {0x44, 0x00}, /* Constellation (default) */
224 {0x45, 0x00}, /* Symbol count (default) */ 221 {0x45, 0x00}, /* Symbol count (default) */
225 {0x46, 0x0d}, /* Symbol rate estimator on (default) */ 222 {0x46, 0x0d}, /* Symbol rate estimator on (default) */
226 {0x56, 0x41}, /* Various (default) */ 223 {0x56, 0xc1}, /* Error Counter = Viterbi BER */
227 {0x57, 0xff}, /* Error Counter Window (default) */ 224 {0x57, 0xff}, /* Error Counter Window (default) */
225 {0x5c, 0x20}, /* Acquisition AFC Expiration window (default is 0x10) */
228 {0x67, 0x83}, /* Non-DCII symbol clock */ 226 {0x67, 0x83}, /* Non-DCII symbol clock */
229}; 227};
230 228
@@ -321,6 +319,12 @@ static int cx24123_set_fec(struct cx24123_state* state, fe_code_rate_t fec)
321 if ( (fec < FEC_NONE) || (fec > FEC_AUTO) ) 319 if ( (fec < FEC_NONE) || (fec > FEC_AUTO) )
322 fec = FEC_AUTO; 320 fec = FEC_AUTO;
323 321
322 /* Set the soft decision threshold */
323 if(fec == FEC_1_2)
324 cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) | 0x01);
325 else
326 cx24123_writereg(state, 0x43, cx24123_readreg(state, 0x43) & ~0x01);
327
324 switch (fec) { 328 switch (fec) {
325 case FEC_1_2: 329 case FEC_1_2:
326 dprintk("%s: set FEC to 1/2\n",__FUNCTION__); 330 dprintk("%s: set FEC to 1/2\n",__FUNCTION__);
@@ -657,6 +661,10 @@ static int cx24123_initfe(struct dvb_frontend* fe)
657 for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++) 661 for (i = 0; i < sizeof(cx24123_regdata) / sizeof(cx24123_regdata[0]); i++)
658 cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data); 662 cx24123_writereg(state, cx24123_regdata[i].reg, cx24123_regdata[i].data);
659 663
664 /* Set the LNB polarity */
665 if(state->config->lnb_polarity)
666 cx24123_writereg(state, 0x32, cx24123_readreg(state, 0x32) | 0x02);
667
660 return 0; 668 return 0;
661} 669}
662 670
@@ -674,6 +682,9 @@ static int cx24123_set_voltage(struct dvb_frontend* fe, fe_sec_voltage_t voltage
674 case SEC_VOLTAGE_18: 682 case SEC_VOLTAGE_18:
675 dprintk("%s: setting voltage 18V\n", __FUNCTION__); 683 dprintk("%s: setting voltage 18V\n", __FUNCTION__);
676 return cx24123_writereg(state, 0x29, val | 0x80); 684 return cx24123_writereg(state, 0x29, val | 0x80);
685 case SEC_VOLTAGE_OFF:
686 /* already handled in cx88-dvb */
687 return 0;
677 default: 688 default:
678 return -EINVAL; 689 return -EINVAL;
679 }; 690 };
@@ -776,13 +787,15 @@ static int cx24123_read_status(struct dvb_frontend* fe, fe_status_t* status)
776 if (lock & 0x01) 787 if (lock & 0x01)
777 *status |= FE_HAS_SIGNAL; 788 *status |= FE_HAS_SIGNAL;
778 if (sync & 0x02) 789 if (sync & 0x02)
779 *status |= FE_HAS_CARRIER; 790 *status |= FE_HAS_CARRIER; /* Phase locked */
780 if (sync & 0x04) 791 if (sync & 0x04)
781 *status |= FE_HAS_VITERBI; 792 *status |= FE_HAS_VITERBI;
793
794 /* Reed-Solomon Status */
782 if (sync & 0x08) 795 if (sync & 0x08)
783 *status |= FE_HAS_SYNC; 796 *status |= FE_HAS_SYNC;
784 if (sync & 0x80) 797 if (sync & 0x80)
785 *status |= FE_HAS_LOCK; 798 *status |= FE_HAS_LOCK; /*Full Sync */
786 799
787 return 0; 800 return 0;
788} 801}
@@ -795,29 +808,13 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
795{ 808{
796 struct cx24123_state *state = fe->demodulator_priv; 809 struct cx24123_state *state = fe->demodulator_priv;
797 810
798 state->lastber = 811 /* The true bit error rate is this value divided by
799 ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) | 812 the window size (set as 256 * 255) */
813 *ber = ((cx24123_readreg(state, 0x1c) & 0x3f) << 16) |
800 (cx24123_readreg(state, 0x1d) << 8 | 814 (cx24123_readreg(state, 0x1d) << 8 |
801 cx24123_readreg(state, 0x1e)); 815 cx24123_readreg(state, 0x1e));
802
803 /* Do the signal quality processing here, it's derived from the BER. */
804 /* Scale the BER from a 24bit to a SNR 16 bit where higher = better */
805 if (state->lastber < 5000)
806 state->snr = 655*100;
807 else if ( (state->lastber >= 5000) && (state->lastber < 55000) )
808 state->snr = 655*90;
809 else if ( (state->lastber >= 55000) && (state->lastber < 150000) )
810 state->snr = 655*80;
811 else if ( (state->lastber >= 150000) && (state->lastber < 250000) )
812 state->snr = 655*70;
813 else if ( (state->lastber >= 250000) && (state->lastber < 450000) )
814 state->snr = 655*65;
815 else
816 state->snr = 0;
817
818 dprintk("%s: BER = %d, S/N index = %d\n",__FUNCTION__,state->lastber, state->snr);
819 816
820 *ber = state->lastber; 817 dprintk("%s: BER = %d\n",__FUNCTION__,*ber);
821 818
822 return 0; 819 return 0;
823} 820}
@@ -825,6 +822,7 @@ static int cx24123_read_ber(struct dvb_frontend* fe, u32* ber)
825static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength) 822static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_strength)
826{ 823{
827 struct cx24123_state *state = fe->demodulator_priv; 824 struct cx24123_state *state = fe->demodulator_priv;
825
828 *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */ 826 *signal_strength = cx24123_readreg(state, 0x3b) << 8; /* larger = better */
829 827
830 dprintk("%s: Signal strength = %d\n",__FUNCTION__,*signal_strength); 828 dprintk("%s: Signal strength = %d\n",__FUNCTION__,*signal_strength);
@@ -835,19 +833,13 @@ static int cx24123_read_signal_strength(struct dvb_frontend* fe, u16* signal_str
835static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr) 833static int cx24123_read_snr(struct dvb_frontend* fe, u16* snr)
836{ 834{
837 struct cx24123_state *state = fe->demodulator_priv; 835 struct cx24123_state *state = fe->demodulator_priv;
838 *snr = state->snr;
839
840 dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr);
841 836
842 return 0; 837 /* Inverted raw Es/N0 count, totally bogus but better than the
843} 838 BER threshold. */
839 *snr = 65535 - (((u16)cx24123_readreg(state, 0x18) << 8) |
840 (u16)cx24123_readreg(state, 0x19));
844 841
845static int cx24123_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks) 842 dprintk("%s: read S/N index = %d\n",__FUNCTION__,*snr);
846{
847 struct cx24123_state *state = fe->demodulator_priv;
848 *ucblocks = state->lastber;
849
850 dprintk("%s: ucblocks (ber) = %d\n",__FUNCTION__,*ucblocks);
851 843
852 return 0; 844 return 0;
853} 845}
@@ -922,6 +914,29 @@ static int cx24123_set_tone(struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
922 return 0; 914 return 0;
923} 915}
924 916
917static int cx24123_tune(struct dvb_frontend* fe,
918 struct dvb_frontend_parameters* params,
919 unsigned int mode_flags,
920 int *delay,
921 fe_status_t *status)
922{
923 int retval = 0;
924
925 if (params != NULL)
926 retval = cx24123_set_frontend(fe, params);
927
928 if (!(mode_flags & FE_TUNE_MODE_ONESHOT))
929 cx24123_read_status(fe, status);
930 *delay = HZ/10;
931
932 return retval;
933}
934
935static int cx24123_get_algo(struct dvb_frontend *fe)
936{
937 return 1; //FE_ALGO_HW
938}
939
925static void cx24123_release(struct dvb_frontend* fe) 940static void cx24123_release(struct dvb_frontend* fe)
926{ 941{
927 struct cx24123_state* state = fe->demodulator_priv; 942 struct cx24123_state* state = fe->demodulator_priv;
@@ -949,8 +964,6 @@ struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
949 /* setup the state */ 964 /* setup the state */
950 state->config = config; 965 state->config = config;
951 state->i2c = i2c; 966 state->i2c = i2c;
952 state->lastber = 0;
953 state->snr = 0;
954 state->VCAarg = 0; 967 state->VCAarg = 0;
955 state->VGAarg = 0; 968 state->VGAarg = 0;
956 state->bandselectarg = 0; 969 state->bandselectarg = 0;
@@ -1003,11 +1016,12 @@ static struct dvb_frontend_ops cx24123_ops = {
1003 .read_ber = cx24123_read_ber, 1016 .read_ber = cx24123_read_ber,
1004 .read_signal_strength = cx24123_read_signal_strength, 1017 .read_signal_strength = cx24123_read_signal_strength,
1005 .read_snr = cx24123_read_snr, 1018 .read_snr = cx24123_read_snr,
1006 .read_ucblocks = cx24123_read_ucblocks,
1007 .diseqc_send_master_cmd = cx24123_send_diseqc_msg, 1019 .diseqc_send_master_cmd = cx24123_send_diseqc_msg,
1008 .diseqc_send_burst = cx24123_diseqc_send_burst, 1020 .diseqc_send_burst = cx24123_diseqc_send_burst,
1009 .set_tone = cx24123_set_tone, 1021 .set_tone = cx24123_set_tone,
1010 .set_voltage = cx24123_set_voltage, 1022 .set_voltage = cx24123_set_voltage,
1023 .tune = cx24123_tune,
1024 .get_frontend_algo = cx24123_get_algo,
1011}; 1025};
1012 1026
1013module_param(debug, int, 0644); 1027module_param(debug, int, 0644);
diff --git a/drivers/media/dvb/frontends/cx24123.h b/drivers/media/dvb/frontends/cx24123.h
index 9606f825935c..57a1dae1dc40 100644
--- a/drivers/media/dvb/frontends/cx24123.h
+++ b/drivers/media/dvb/frontends/cx24123.h
@@ -30,9 +30,21 @@ struct cx24123_config
30 30
31 /* Need to set device param for start_dma */ 31 /* Need to set device param for start_dma */
32 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 32 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
33
34 /* 0 = LNB voltage normal, 1 = LNB voltage inverted */
35 int lnb_polarity;
33}; 36};
34 37
38#if defined(CONFIG_DVB_CX24123) || defined(CONFIG_DVB_CX24123_MODULE)
35extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config, 39extern struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
36 struct i2c_adapter* i2c); 40 struct i2c_adapter* i2c);
41#else
42static inline struct dvb_frontend* cx24123_attach(const struct cx24123_config* config,
43 struct i2c_adapter* i2c)
44{
45 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
46 return NULL;
47}
48#endif // CONFIG_DVB_CX24123
37 49
38#endif /* CX24123_H */ 50#endif /* CX24123_H */
diff --git a/drivers/media/dvb/frontends/dib3000-common.c b/drivers/media/dvb/frontends/dib3000-common.c
deleted file mode 100644
index 1a4f1f7c228a..000000000000
--- a/drivers/media/dvb/frontends/dib3000-common.c
+++ /dev/null
@@ -1,83 +0,0 @@
1#include "dib3000-common.h"
2
3#ifdef CONFIG_DVB_DIBCOM_DEBUG
4static int debug;
5module_param(debug, int, 0644);
6MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
7#endif
8#define deb_info(args...) dprintk(0x01,args)
9#define deb_i2c(args...) dprintk(0x02,args)
10#define deb_srch(args...) dprintk(0x04,args)
11
12
13int dib3000_read_reg(struct dib3000_state *state, u16 reg)
14{
15 u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
16 u8 rb[2];
17 struct i2c_msg msg[] = {
18 { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
19 { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
20 };
21
22 if (i2c_transfer(state->i2c, msg, 2) != 2)
23 deb_i2c("i2c read error\n");
24
25 deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
26 (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
27
28 return (rb[0] << 8) | rb[1];
29}
30
31int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
32{
33 u8 b[] = {
34 (reg >> 8) & 0xff, reg & 0xff,
35 (val >> 8) & 0xff, val & 0xff,
36 };
37 struct i2c_msg msg[] = {
38 { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
39 };
40 deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
41
42 return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
43}
44
45int dib3000_search_status(u16 irq,u16 lock)
46{
47 if (irq & 0x02) {
48 if (lock & 0x01) {
49 deb_srch("auto search succeeded\n");
50 return 1; // auto search succeeded
51 } else {
52 deb_srch("auto search not successful\n");
53 return 0; // auto search failed
54 }
55 } else if (irq & 0x01) {
56 deb_srch("auto search failed\n");
57 return 0; // auto search failed
58 }
59 return -1; // try again
60}
61
62/* for auto search */
63u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
64 { /* fft */
65 { /* gua */
66 { 0, 1 }, /* 0 0 { 0,1 } */
67 { 3, 9 }, /* 0 1 { 0,1 } */
68 },
69 {
70 { 2, 5 }, /* 1 0 { 0,1 } */
71 { 6, 11 }, /* 1 1 { 0,1 } */
72 }
73 };
74
75MODULE_AUTHOR("Patrick Boettcher <patrick.boettcher@desy.de");
76MODULE_DESCRIPTION("Common functions for the dib3000mb/dib3000mc dvb frontend drivers");
77MODULE_LICENSE("GPL");
78
79EXPORT_SYMBOL(dib3000_seq);
80
81EXPORT_SYMBOL(dib3000_read_reg);
82EXPORT_SYMBOL(dib3000_write_reg);
83EXPORT_SYMBOL(dib3000_search_status);
diff --git a/drivers/media/dvb/frontends/dib3000-common.h b/drivers/media/dvb/frontends/dib3000-common.h
deleted file mode 100644
index be1c0d3e1389..000000000000
--- a/drivers/media/dvb/frontends/dib3000-common.h
+++ /dev/null
@@ -1,135 +0,0 @@
1/*
2 * .h-files for the common use of the frontend drivers made by DiBcom
3 * DiBcom 3000M-B/C, 3000P
4 *
5 * DiBcom (http://www.dibcom.fr/)
6 *
7 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
8 *
9 * based on GPL code from DibCom, which has
10 *
11 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr)
12 *
13 * This program is free software; you can redistribute it and/or
14 * modify it under the terms of the GNU General Public License as
15 * published by the Free Software Foundation, version 2.
16 *
17 * Acknowledgements
18 *
19 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
20 * sources, on which this driver (and the dvb-dibusb) are based.
21 *
22 * see Documentation/dvb/README.dibusb for more information
23 *
24 */
25
26#ifndef DIB3000_COMMON_H
27#define DIB3000_COMMON_H
28
29#include "dvb_frontend.h"
30#include "dib3000.h"
31
32/* info and err, taken from usb.h, if there is anything available like by default. */
33#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg)
34#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg)
35#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
36
37/* frontend state */
38struct dib3000_state {
39 struct i2c_adapter* i2c;
40
41/* configuration settings */
42 struct dib3000_config config;
43
44 struct dvb_frontend frontend;
45 int timing_offset;
46 int timing_offset_comp_done;
47
48 fe_bandwidth_t last_tuned_bw;
49 u32 last_tuned_freq;
50};
51
52/* commonly used methods by the dib3000mb/mc/p frontend */
53extern int dib3000_read_reg(struct dib3000_state *state, u16 reg);
54extern int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val);
55
56extern int dib3000_search_status(u16 irq,u16 lock);
57
58/* handy shortcuts */
59#define rd(reg) dib3000_read_reg(state,reg)
60
61#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
62 { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
63
64#define wr_foreach(a,v) { int i; \
65 if (sizeof(a) != sizeof(v)) \
66 err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
67 for (i=0; i < sizeof(a)/sizeof(u16); i++) \
68 wr(a[i],v[i]); \
69 }
70
71#define set_or(reg,val) wr(reg,rd(reg) | val)
72
73#define set_and(reg,val) wr(reg,rd(reg) & val)
74
75
76/* debug */
77
78#ifdef CONFIG_DVB_DIBCOM_DEBUG
79#define dprintk(level,args...) \
80 do { if ((debug & level)) { printk(args); } } while (0)
81#else
82#define dprintk(args...) do { } while (0)
83#endif
84
85/* mask for enabling a specific pid for the pid_filter */
86#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
87
88/* common values for tuning */
89#define DIB3000_ALPHA_0 ( 0)
90#define DIB3000_ALPHA_1 ( 1)
91#define DIB3000_ALPHA_2 ( 2)
92#define DIB3000_ALPHA_4 ( 4)
93
94#define DIB3000_CONSTELLATION_QPSK ( 0)
95#define DIB3000_CONSTELLATION_16QAM ( 1)
96#define DIB3000_CONSTELLATION_64QAM ( 2)
97
98#define DIB3000_GUARD_TIME_1_32 ( 0)
99#define DIB3000_GUARD_TIME_1_16 ( 1)
100#define DIB3000_GUARD_TIME_1_8 ( 2)
101#define DIB3000_GUARD_TIME_1_4 ( 3)
102
103#define DIB3000_TRANSMISSION_MODE_2K ( 0)
104#define DIB3000_TRANSMISSION_MODE_8K ( 1)
105
106#define DIB3000_SELECT_LP ( 0)
107#define DIB3000_SELECT_HP ( 1)
108
109#define DIB3000_FEC_1_2 ( 1)
110#define DIB3000_FEC_2_3 ( 2)
111#define DIB3000_FEC_3_4 ( 3)
112#define DIB3000_FEC_5_6 ( 5)
113#define DIB3000_FEC_7_8 ( 7)
114
115#define DIB3000_HRCH_OFF ( 0)
116#define DIB3000_HRCH_ON ( 1)
117
118#define DIB3000_DDS_INVERSION_OFF ( 0)
119#define DIB3000_DDS_INVERSION_ON ( 1)
120
121#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8))
122#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
123
124/* for auto search */
125extern u16 dib3000_seq[2][2][2];
126
127#define DIB3000_REG_MANUFACTOR_ID ( 1025)
128#define DIB3000_I2C_ID_DIBCOM (0x01b3)
129
130#define DIB3000_REG_DEVICE_ID ( 1026)
131#define DIB3000MB_DEVICE_ID (0x3000)
132#define DIB3000MC_DEVICE_ID (0x3001)
133#define DIB3000P_DEVICE_ID (0x3002)
134
135#endif // DIB3000_COMMON_H
diff --git a/drivers/media/dvb/frontends/dib3000.h b/drivers/media/dvb/frontends/dib3000.h
index ec927628d273..0caac3f0f279 100644
--- a/drivers/media/dvb/frontends/dib3000.h
+++ b/drivers/media/dvb/frontends/dib3000.h
@@ -41,9 +41,16 @@ struct dib_fe_xfer_ops
41 int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl); 41 int (*tuner_pass_ctrl)(struct dvb_frontend *fe, int onoff, u8 pll_ctrl);
42}; 42};
43 43
44#if defined(CONFIG_DVB_DIB3000MB) || defined(CONFIG_DVB_DIB3000MB_MODULE)
44extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config, 45extern struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
45 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops); 46 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
47#else
48static inline struct dvb_frontend* dib3000mb_attach(const struct dib3000_config* config,
49 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
50{
51 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
52 return NULL;
53}
54#endif // CONFIG_DVB_DIB3000MB
46 55
47extern struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
48 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops);
49#endif // DIB3000_H 56#endif // DIB3000_H
diff --git a/drivers/media/dvb/frontends/dib3000mb.c b/drivers/media/dvb/frontends/dib3000mb.c
index 5302e11883a2..adbabfdb04a9 100644
--- a/drivers/media/dvb/frontends/dib3000mb.c
+++ b/drivers/media/dvb/frontends/dib3000mb.c
@@ -29,9 +29,10 @@
29#include <linux/string.h> 29#include <linux/string.h>
30#include <linux/slab.h> 30#include <linux/slab.h>
31 31
32#include "dib3000-common.h" 32#include "dvb_frontend.h"
33#include "dib3000mb_priv.h" 33
34#include "dib3000.h" 34#include "dib3000.h"
35#include "dib3000mb_priv.h"
35 36
36/* Version information */ 37/* Version information */
37#define DRIVER_VERSION "0.1" 38#define DRIVER_VERSION "0.1"
@@ -44,10 +45,81 @@ module_param(debug, int, 0644);
44MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able))."); 45MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe (|-able)).");
45#endif 46#endif
46#define deb_info(args...) dprintk(0x01,args) 47#define deb_info(args...) dprintk(0x01,args)
48#define deb_i2c(args...) dprintk(0x02,args)
49#define deb_srch(args...) dprintk(0x04,args)
50#define deb_info(args...) dprintk(0x01,args)
47#define deb_xfer(args...) dprintk(0x02,args) 51#define deb_xfer(args...) dprintk(0x02,args)
48#define deb_setf(args...) dprintk(0x04,args) 52#define deb_setf(args...) dprintk(0x04,args)
49#define deb_getf(args...) dprintk(0x08,args) 53#define deb_getf(args...) dprintk(0x08,args)
50 54
55#ifdef CONFIG_DVB_DIBCOM_DEBUG
56static int debug;
57module_param(debug, int, 0644);
58MODULE_PARM_DESC(debug, "set debugging level (1=info,2=i2c,4=srch (|-able)).");
59#endif
60
61static int dib3000_read_reg(struct dib3000_state *state, u16 reg)
62{
63 u8 wb[] = { ((reg >> 8) | 0x80) & 0xff, reg & 0xff };
64 u8 rb[2];
65 struct i2c_msg msg[] = {
66 { .addr = state->config.demod_address, .flags = 0, .buf = wb, .len = 2 },
67 { .addr = state->config.demod_address, .flags = I2C_M_RD, .buf = rb, .len = 2 },
68 };
69
70 if (i2c_transfer(state->i2c, msg, 2) != 2)
71 deb_i2c("i2c read error\n");
72
73 deb_i2c("reading i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,
74 (rb[0] << 8) | rb[1],(rb[0] << 8) | rb[1]);
75
76 return (rb[0] << 8) | rb[1];
77}
78
79static int dib3000_write_reg(struct dib3000_state *state, u16 reg, u16 val)
80{
81 u8 b[] = {
82 (reg >> 8) & 0xff, reg & 0xff,
83 (val >> 8) & 0xff, val & 0xff,
84 };
85 struct i2c_msg msg[] = {
86 { .addr = state->config.demod_address, .flags = 0, .buf = b, .len = 4 }
87 };
88 deb_i2c("writing i2c bus (reg: %5d 0x%04x, val: %5d 0x%04x)\n",reg,reg,val,val);
89
90 return i2c_transfer(state->i2c,msg, 1) != 1 ? -EREMOTEIO : 0;
91}
92
93static int dib3000_search_status(u16 irq,u16 lock)
94{
95 if (irq & 0x02) {
96 if (lock & 0x01) {
97 deb_srch("auto search succeeded\n");
98 return 1; // auto search succeeded
99 } else {
100 deb_srch("auto search not successful\n");
101 return 0; // auto search failed
102 }
103 } else if (irq & 0x01) {
104 deb_srch("auto search failed\n");
105 return 0; // auto search failed
106 }
107 return -1; // try again
108}
109
110/* for auto search */
111static u16 dib3000_seq[2][2][2] = /* fft,gua, inv */
112 { /* fft */
113 { /* gua */
114 { 0, 1 }, /* 0 0 { 0,1 } */
115 { 3, 9 }, /* 0 1 { 0,1 } */
116 },
117 {
118 { 2, 5 }, /* 1 0 { 0,1 } */
119 { 6, 11 }, /* 1 1 { 0,1 } */
120 }
121 };
122
51static int dib3000mb_get_frontend(struct dvb_frontend* fe, 123static int dib3000mb_get_frontend(struct dvb_frontend* fe,
52 struct dvb_frontend_parameters *fep); 124 struct dvb_frontend_parameters *fep);
53 125
diff --git a/drivers/media/dvb/frontends/dib3000mb_priv.h b/drivers/media/dvb/frontends/dib3000mb_priv.h
index 999b19047816..1a12747fdc91 100644
--- a/drivers/media/dvb/frontends/dib3000mb_priv.h
+++ b/drivers/media/dvb/frontends/dib3000mb_priv.h
@@ -13,6 +13,99 @@
13#ifndef __DIB3000MB_PRIV_H_INCLUDED__ 13#ifndef __DIB3000MB_PRIV_H_INCLUDED__
14#define __DIB3000MB_PRIV_H_INCLUDED__ 14#define __DIB3000MB_PRIV_H_INCLUDED__
15 15
16/* info and err, taken from usb.h, if there is anything available like by default. */
17#define err(format, arg...) printk(KERN_ERR "dib3000: " format "\n" , ## arg)
18#define info(format, arg...) printk(KERN_INFO "dib3000: " format "\n" , ## arg)
19#define warn(format, arg...) printk(KERN_WARNING "dib3000: " format "\n" , ## arg)
20
21/* handy shortcuts */
22#define rd(reg) dib3000_read_reg(state,reg)
23
24#define wr(reg,val) if (dib3000_write_reg(state,reg,val)) \
25 { err("while sending 0x%04x to 0x%04x.",val,reg); return -EREMOTEIO; }
26
27#define wr_foreach(a,v) { int i; \
28 if (sizeof(a) != sizeof(v)) \
29 err("sizeof: %zu %zu is different",sizeof(a),sizeof(v));\
30 for (i=0; i < sizeof(a)/sizeof(u16); i++) \
31 wr(a[i],v[i]); \
32 }
33
34#define set_or(reg,val) wr(reg,rd(reg) | val)
35
36#define set_and(reg,val) wr(reg,rd(reg) & val)
37
38/* debug */
39
40#ifdef CONFIG_DVB_DIBCOM_DEBUG
41#define dprintk(level,args...) \
42 do { if ((debug & level)) { printk(args); } } while (0)
43#else
44#define dprintk(args...) do { } while (0)
45#endif
46
47/* mask for enabling a specific pid for the pid_filter */
48#define DIB3000_ACTIVATE_PID_FILTERING (0x2000)
49
50/* common values for tuning */
51#define DIB3000_ALPHA_0 ( 0)
52#define DIB3000_ALPHA_1 ( 1)
53#define DIB3000_ALPHA_2 ( 2)
54#define DIB3000_ALPHA_4 ( 4)
55
56#define DIB3000_CONSTELLATION_QPSK ( 0)
57#define DIB3000_CONSTELLATION_16QAM ( 1)
58#define DIB3000_CONSTELLATION_64QAM ( 2)
59
60#define DIB3000_GUARD_TIME_1_32 ( 0)
61#define DIB3000_GUARD_TIME_1_16 ( 1)
62#define DIB3000_GUARD_TIME_1_8 ( 2)
63#define DIB3000_GUARD_TIME_1_4 ( 3)
64
65#define DIB3000_TRANSMISSION_MODE_2K ( 0)
66#define DIB3000_TRANSMISSION_MODE_8K ( 1)
67
68#define DIB3000_SELECT_LP ( 0)
69#define DIB3000_SELECT_HP ( 1)
70
71#define DIB3000_FEC_1_2 ( 1)
72#define DIB3000_FEC_2_3 ( 2)
73#define DIB3000_FEC_3_4 ( 3)
74#define DIB3000_FEC_5_6 ( 5)
75#define DIB3000_FEC_7_8 ( 7)
76
77#define DIB3000_HRCH_OFF ( 0)
78#define DIB3000_HRCH_ON ( 1)
79
80#define DIB3000_DDS_INVERSION_OFF ( 0)
81#define DIB3000_DDS_INVERSION_ON ( 1)
82
83#define DIB3000_TUNER_WRITE_ENABLE(a) (0xffff & (a << 8))
84#define DIB3000_TUNER_WRITE_DISABLE(a) (0xffff & ((a << 8) | (1 << 7)))
85
86#define DIB3000_REG_MANUFACTOR_ID ( 1025)
87#define DIB3000_I2C_ID_DIBCOM (0x01b3)
88
89#define DIB3000_REG_DEVICE_ID ( 1026)
90#define DIB3000MB_DEVICE_ID (0x3000)
91#define DIB3000MC_DEVICE_ID (0x3001)
92#define DIB3000P_DEVICE_ID (0x3002)
93
94/* frontend state */
95struct dib3000_state {
96 struct i2c_adapter* i2c;
97
98/* configuration settings */
99 struct dib3000_config config;
100
101 struct dvb_frontend frontend;
102 int timing_offset;
103 int timing_offset_comp_done;
104
105 fe_bandwidth_t last_tuned_bw;
106 u32 last_tuned_freq;
107};
108
16/* register addresses and some of their default values */ 109/* register addresses and some of their default values */
17 110
18/* restart subsystems */ 111/* restart subsystems */
diff --git a/drivers/media/dvb/frontends/dib3000mc.c b/drivers/media/dvb/frontends/dib3000mc.c
index 98673474a140..cc28417fa33a 100644
--- a/drivers/media/dvb/frontends/dib3000mc.c
+++ b/drivers/media/dvb/frontends/dib3000mc.c
@@ -1,913 +1,921 @@
1/* 1/*
2 * Frontend driver for mobile DVB-T demodulator DiBcom 3000P/M-C 2 * Driver for DiBcom DiB3000MC/P-demodulator.
3 * DiBcom (http://www.dibcom.fr/)
4 * 3 *
4 * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de) 5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher@desy.de)
6 * 6 *
7 * based on GPL code from DiBCom, which has 7 * This code is partially based on the previous dib3000mc.c .
8 * 8 *
9 * Copyright (C) 2004 Amaury Demol for DiBcom (ademol@dibcom.fr) 9 * This program is free software; you can redistribute it and/or
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License as 10 * modify it under the terms of the GNU General Public License as
13 * published by the Free Software Foundation, version 2. 11 * published by the Free Software Foundation, version 2.
14 *
15 * Acknowledgements
16 *
17 * Amaury Demol (ademol@dibcom.fr) from DiBcom for providing specs and driver
18 * sources, on which this driver (and the dvb-dibusb) are based.
19 *
20 * see Documentation/dvb/README.dibusb for more information
21 *
22 */ 12 */
13
23#include <linux/kernel.h> 14#include <linux/kernel.h>
24#include <linux/module.h> 15#include <linux/i2c.h>
25#include <linux/moduleparam.h> 16//#include <linux/init.h>
26#include <linux/init.h> 17//#include <linux/delay.h>
27#include <linux/delay.h> 18//#include <linux/string.h>
28#include <linux/string.h> 19//#include <linux/slab.h>
29#include <linux/slab.h> 20
30 21#include "dvb_frontend.h"
31#include "dib3000-common.h" 22
32#include "dib3000mc_priv.h" 23#include "dib3000mc.h"
33#include "dib3000.h" 24
34
35/* Version information */
36#define DRIVER_VERSION "0.1"
37#define DRIVER_DESC "DiBcom 3000M-C DVB-T demodulator"
38#define DRIVER_AUTHOR "Patrick Boettcher, patrick.boettcher@desy.de"
39
40#ifdef CONFIG_DVB_DIBCOM_DEBUG
41static int debug; 25static int debug;
42module_param(debug, int, 0644); 26module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "set debugging level (1=info,2=xfer,4=setfe,8=getfe,16=stat (|-able))."); 27MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
44#endif
45#define deb_info(args...) dprintk(0x01,args)
46#define deb_xfer(args...) dprintk(0x02,args)
47#define deb_setf(args...) dprintk(0x04,args)
48#define deb_getf(args...) dprintk(0x08,args)
49#define deb_stat(args...) dprintk(0x10,args)
50
51static int dib3000mc_set_impulse_noise(struct dib3000_state * state, int mode,
52 fe_transmit_mode_t transmission_mode, fe_bandwidth_t bandwidth)
53{
54 switch (transmission_mode) {
55 case TRANSMISSION_MODE_2K:
56 wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[0]);
57 break;
58 case TRANSMISSION_MODE_8K:
59 wr_foreach(dib3000mc_reg_fft,dib3000mc_fft_modes[1]);
60 break;
61 default:
62 break;
63 }
64 28
65 switch (bandwidth) { 29#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiB3000MC/P:"); printk(args); } } while (0)
66/* case BANDWIDTH_5_MHZ: 30
67 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[0]); 31struct dib3000mc_state {
68 break; */ 32 struct dvb_frontend demod;
69 case BANDWIDTH_6_MHZ: 33 struct dib3000mc_config *cfg;
70 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[1]); 34
71 break; 35 u8 i2c_addr;
72 case BANDWIDTH_7_MHZ: 36 struct i2c_adapter *i2c_adap;
73 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[2]); 37
74 break; 38 struct dibx000_i2c_master i2c_master;
75 case BANDWIDTH_8_MHZ: 39
76 wr_foreach(dib3000mc_reg_impulse_noise,dib3000mc_impluse_noise[3]); 40 fe_bandwidth_t current_bandwidth;
77 break; 41
78 default: 42 u16 dev_id;
79 break; 43};
44
45static u16 dib3000mc_read_word(struct dib3000mc_state *state, u16 reg)
46{
47 u8 wb[2] = { (reg >> 8) | 0x80, reg & 0xff };
48 u8 rb[2];
49 struct i2c_msg msg[2] = {
50 { .addr = state->i2c_addr >> 1, .flags = 0, .buf = wb, .len = 2 },
51 { .addr = state->i2c_addr >> 1, .flags = I2C_M_RD, .buf = rb, .len = 2 },
52 };
53
54 if (i2c_transfer(state->i2c_adap, msg, 2) != 2)
55 dprintk("i2c read error on %d\n",reg);
56
57 return (rb[0] << 8) | rb[1];
58}
59
60static int dib3000mc_write_word(struct dib3000mc_state *state, u16 reg, u16 val)
61{
62 u8 b[4] = {
63 (reg >> 8) & 0xff, reg & 0xff,
64 (val >> 8) & 0xff, val & 0xff,
65 };
66 struct i2c_msg msg = {
67 .addr = state->i2c_addr >> 1, .flags = 0, .buf = b, .len = 4
68 };
69 return i2c_transfer(state->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
70}
71
72
73static int dib3000mc_identify(struct dib3000mc_state *state)
74{
75 u16 value;
76 if ((value = dib3000mc_read_word(state, 1025)) != 0x01b3) {
77 dprintk("-E- DiB3000MC/P: wrong Vendor ID (read=0x%x)\n",value);
78 return -EREMOTEIO;
80 } 79 }
81 80
82 switch (mode) { 81 value = dib3000mc_read_word(state, 1026);
83 case 0: /* no impulse */ /* fall through */ 82 if (value != 0x3001 && value != 0x3002) {
84 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[0]); 83 dprintk("-E- DiB3000MC/P: wrong Device ID (%x)\n",value);
85 break; 84 return -EREMOTEIO;
86 case 1: /* new algo */
87 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[1]);
88 set_or(DIB3000MC_REG_IMP_NOISE_55,DIB3000MC_IMP_NEW_ALGO(0)); /* gives 1<<10 */
89 break;
90 default: /* old algo */
91 wr_foreach(dib3000mc_reg_imp_noise_ctl,dib3000mc_imp_noise_ctl[3]);
92 break;
93 } 85 }
86 state->dev_id = value;
87
88 dprintk("-I- found DiB3000MC/P: %x\n",state->dev_id);
89
94 return 0; 90 return 0;
95} 91}
96 92
97static int dib3000mc_set_timing(struct dib3000_state *state, int upd_offset, 93static int dib3000mc_set_timing(struct dib3000mc_state *state, s16 nfft, u8 bw, u8 update_offset)
98 fe_transmit_mode_t fft, fe_bandwidth_t bw)
99{ 94{
100 u16 timf_msb,timf_lsb; 95/*
101 s32 tim_offset,tim_sgn; 96 u32 timf_msb, timf_lsb, i;
102 u64 comp1,comp2,comp=0; 97 int tim_sgn ;
103 98 LUInt comp1, comp2, comp ;
104 switch (bw) { 99// u32 tim_offset ;
105 case BANDWIDTH_8_MHZ: comp = DIB3000MC_CLOCK_REF*8; break; 100 comp = 27700 * BW_INDEX_TO_KHZ(bw) / 1000;
106 case BANDWIDTH_7_MHZ: comp = DIB3000MC_CLOCK_REF*7; break; 101 timf_msb = (comp >> 16) & 0x00FF;
107 case BANDWIDTH_6_MHZ: comp = DIB3000MC_CLOCK_REF*6; break; 102 timf_lsb = comp & 0xFFFF;
108 default: err("unknown bandwidth (%d)",bw); break;
109 }
110 timf_msb = (comp >> 16) & 0xff;
111 timf_lsb = (comp & 0xffff);
112 103
113 // Update the timing offset ; 104 // Update the timing offset ;
114 if (upd_offset > 0) { 105 if (update_offset) {
115 if (!state->timing_offset_comp_done) { 106 if (state->timing_offset_comp_done == 0) {
116 msleep(200); 107 usleep(200000);
117 state->timing_offset_comp_done = 1; 108 state->timing_offset_comp_done = 1;
118 } 109 }
119 tim_offset = rd(DIB3000MC_REG_TIMING_OFFS_MSB); 110 tim_offset = dib3000mc_read_word(state, 416);
120 if ((tim_offset & 0x2000) == 0x2000) 111 if ((tim_offset & 0x2000) == 0x2000)
121 tim_offset |= 0xC000; 112 tim_offset |= 0xC000; // PB: This only works if tim_offset is s16 - weird
122 if (fft == TRANSMISSION_MODE_2K) 113
123 tim_offset <<= 2; 114 if (nfft == 0)
115 tim_offset = tim_offset << 2; // PB: Do not store the offset for different things in one variable
124 state->timing_offset += tim_offset; 116 state->timing_offset += tim_offset;
125 } 117 }
126
127 tim_offset = state->timing_offset; 118 tim_offset = state->timing_offset;
119
128 if (tim_offset < 0) { 120 if (tim_offset < 0) {
129 tim_sgn = 1; 121 tim_sgn = 1;
130 tim_offset = -tim_offset; 122 tim_offset = -tim_offset;
131 } else 123 } else
132 tim_sgn = 0; 124 tim_sgn = 0;
133 125
134 comp1 = (u32)tim_offset * (u32)timf_lsb ; 126 comp1 = tim_offset * timf_lsb;
135 comp2 = (u32)tim_offset * (u32)timf_msb ; 127 comp2 = tim_offset * timf_msb;
136 comp = ((comp1 >> 16) + comp2) >> 7; 128 comp = ((comp1 >> 16) + comp2) >> 7;
137 129
138 if (tim_sgn == 0) 130 if (tim_sgn == 0)
139 comp = (u32)(timf_msb << 16) + (u32) timf_lsb + comp; 131 comp = timf_msb * (1<<16) + timf_lsb + comp;
140 else 132 else
141 comp = (u32)(timf_msb << 16) + (u32) timf_lsb - comp ; 133 comp = timf_msb * (1<<16) + timf_lsb - comp;
134
135 timf_msb = (comp>>16)&0xFF ;
136 timf_lsb = comp&0xFFFF;
137*/
138 u32 timf = 1384402 * (BW_INDEX_TO_KHZ(bw) / 1000);
142 139
143 timf_msb = (comp >> 16) & 0xff; 140 dib3000mc_write_word(state, 23, timf >> 16);
144 timf_lsb = comp & 0xffff; 141 dib3000mc_write_word(state, 24, timf & 0xffff);
145 142
146 wr(DIB3000MC_REG_TIMING_FREQ_MSB,timf_msb);
147 wr(DIB3000MC_REG_TIMING_FREQ_LSB,timf_lsb);
148 return 0; 143 return 0;
149} 144}
150 145
151static int dib3000mc_init_auto_scan(struct dib3000_state *state, fe_bandwidth_t bw, int boost) 146static int dib3000mc_setup_pwm3_state(struct dib3000mc_state *state)
152{ 147{
153 if (boost) { 148 if (state->cfg->pwm3_inversion) {
154 wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_ON); 149 dib3000mc_write_word(state, 51, (2 << 14) | (0 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
150 dib3000mc_write_word(state, 52, (0 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (1 << 2) | (2 << 0));
155 } else { 151 } else {
156 wr(DIB3000MC_REG_SCAN_BOOST,DIB3000MC_SCAN_BOOST_OFF); 152 dib3000mc_write_word(state, 51, (2 << 14) | (4 << 10) | (7 << 6) | (2 << 2) | (2 << 0));
157 } 153 dib3000mc_write_word(state, 52, (1 << 8) | (5 << 5) | (1 << 4) | (1 << 3) | (0 << 2) | (2 << 0));
158 switch (bw) {
159 case BANDWIDTH_8_MHZ:
160 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz);
161 break;
162 case BANDWIDTH_7_MHZ:
163 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_7mhz);
164 break;
165 case BANDWIDTH_6_MHZ:
166 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_6mhz);
167 break;
168/* case BANDWIDTH_5_MHZ:
169 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_5mhz);
170 break;*/
171 case BANDWIDTH_AUTO:
172 return -EOPNOTSUPP;
173 default:
174 err("unknown bandwidth value (%d).",bw);
175 return -EINVAL;
176 }
177 if (boost) {
178 u32 timeout = (rd(DIB3000MC_REG_BW_TIMOUT_MSB) << 16) +
179 rd(DIB3000MC_REG_BW_TIMOUT_LSB);
180 timeout *= 85; timeout >>= 7;
181 wr(DIB3000MC_REG_BW_TIMOUT_MSB,(timeout >> 16) & 0xffff);
182 wr(DIB3000MC_REG_BW_TIMOUT_LSB,timeout & 0xffff);
183 } 154 }
155
156 if (state->cfg->use_pwm3)
157 dib3000mc_write_word(state, 245, (1 << 3) | (1 << 0));
158 else
159 dib3000mc_write_word(state, 245, 0);
160
161 dib3000mc_write_word(state, 1040, 0x3);
184 return 0; 162 return 0;
185} 163}
186 164
187static int dib3000mc_set_adp_cfg(struct dib3000_state *state, fe_modulation_t con) 165static int dib3000mc_set_output_mode(struct dib3000mc_state *state, int mode)
188{ 166{
189 switch (con) { 167 int ret = 0;
190 case QAM_64: 168 u16 fifo_threshold = 1792;
191 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[2]); 169 u16 outreg = 0;
192 break; 170 u16 outmode = 0;
193 case QAM_16: 171 u16 elecout = 1;
194 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[1]); 172 u16 smo_reg = dib3000mc_read_word(state, 206) & 0x0010; /* keep the pid_parse bit */
195 break; 173
196 case QPSK: 174 dprintk("-I- Setting output mode for demod %p to %d\n",
197 wr_foreach(dib3000mc_reg_adp_cfg,dib3000mc_adp_cfg[0]); 175 &state->demod, mode);
198 break; 176
199 case QAM_AUTO: 177 switch (mode) {
178 case OUTMODE_HIGH_Z: // disable
179 elecout = 0;
180 break;
181 case OUTMODE_MPEG2_PAR_GATED_CLK: // STBs with parallel gated clock
182 outmode = 0;
183 break;
184 case OUTMODE_MPEG2_PAR_CONT_CLK: // STBs with parallel continues clock
185 outmode = 1;
186 break;
187 case OUTMODE_MPEG2_SERIAL: // STBs with serial input
188 outmode = 2;
189 break;
190 case OUTMODE_MPEG2_FIFO: // e.g. USB feeding
191 elecout = 3;
192 /*ADDR @ 206 :
193 P_smo_error_discard [1;6:6] = 0
194 P_smo_rs_discard [1;5:5] = 0
195 P_smo_pid_parse [1;4:4] = 0
196 P_smo_fifo_flush [1;3:3] = 0
197 P_smo_mode [2;2:1] = 11
198 P_smo_ovf_prot [1;0:0] = 0
199 */
200 smo_reg |= 3 << 1;
201 fifo_threshold = 512;
202 outmode = 5;
203 break;
204 case OUTMODE_DIVERSITY:
205 outmode = 4;
206 elecout = 1;
200 break; 207 break;
201 default: 208 default:
202 warn("unkown constellation."); 209 dprintk("Unhandled output_mode passed to be set for demod %p\n",&state->demod);
210 outmode = 0;
203 break; 211 break;
204 } 212 }
205 return 0; 213
214 if ((state->cfg->output_mpeg2_in_188_bytes))
215 smo_reg |= (1 << 5); // P_smo_rs_discard [1;5:5] = 1
216
217 outreg = dib3000mc_read_word(state, 244) & 0x07FF;
218 outreg |= (outmode << 11);
219 ret |= dib3000mc_write_word(state, 244, outreg);
220 ret |= dib3000mc_write_word(state, 206, smo_reg); /*smo_ mode*/
221 ret |= dib3000mc_write_word(state, 207, fifo_threshold); /* synchronous fread */
222 ret |= dib3000mc_write_word(state, 1040, elecout); /* P_out_cfg */
223 return ret;
206} 224}
207 225
208static int dib3000mc_set_general_cfg(struct dib3000_state *state, struct dvb_frontend_parameters *fep, int *auto_val) 226static int dib3000mc_set_bandwidth(struct dvb_frontend *demod, u8 bw)
209{ 227{
210 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm; 228 struct dib3000mc_state *state = demod->demodulator_priv;
211 fe_code_rate_t fe_cr = FEC_NONE; 229 u16 bw_cfg[6] = { 0 };
212 u8 fft=0, guard=0, qam=0, alpha=0, sel_hp=0, cr=0, hrch=0; 230 u16 imp_bw_cfg[3] = { 0 };
213 int seq; 231 u16 reg;
214 232
215 switch (ofdm->transmission_mode) { 233/* settings here are for 27.7MHz */
216 case TRANSMISSION_MODE_2K: fft = DIB3000_TRANSMISSION_MODE_2K; break; 234 switch (bw) {
217 case TRANSMISSION_MODE_8K: fft = DIB3000_TRANSMISSION_MODE_8K; break; 235 case BANDWIDTH_8_MHZ:
218 case TRANSMISSION_MODE_AUTO: break; 236 bw_cfg[0] = 0x0019; bw_cfg[1] = 0x5c30; bw_cfg[2] = 0x0054; bw_cfg[3] = 0x88a0; bw_cfg[4] = 0x01a6; bw_cfg[5] = 0xab20;
219 default: return -EINVAL; 237 imp_bw_cfg[0] = 0x04db; imp_bw_cfg[1] = 0x00db; imp_bw_cfg[2] = 0x00b7;
220 } 238 break;
221 switch (ofdm->guard_interval) {
222 case GUARD_INTERVAL_1_32: guard = DIB3000_GUARD_TIME_1_32; break;
223 case GUARD_INTERVAL_1_16: guard = DIB3000_GUARD_TIME_1_16; break;
224 case GUARD_INTERVAL_1_8: guard = DIB3000_GUARD_TIME_1_8; break;
225 case GUARD_INTERVAL_1_4: guard = DIB3000_GUARD_TIME_1_4; break;
226 case GUARD_INTERVAL_AUTO: break;
227 default: return -EINVAL;
228 }
229 switch (ofdm->constellation) {
230 case QPSK: qam = DIB3000_CONSTELLATION_QPSK; break;
231 case QAM_16: qam = DIB3000_CONSTELLATION_16QAM; break;
232 case QAM_64: qam = DIB3000_CONSTELLATION_64QAM; break;
233 case QAM_AUTO: break;
234 default: return -EINVAL;
235 }
236 switch (ofdm->hierarchy_information) {
237 case HIERARCHY_NONE: /* fall through */
238 case HIERARCHY_1: alpha = DIB3000_ALPHA_1; break;
239 case HIERARCHY_2: alpha = DIB3000_ALPHA_2; break;
240 case HIERARCHY_4: alpha = DIB3000_ALPHA_4; break;
241 case HIERARCHY_AUTO: break;
242 default: return -EINVAL;
243 }
244 if (ofdm->hierarchy_information == HIERARCHY_NONE) {
245 hrch = DIB3000_HRCH_OFF;
246 sel_hp = DIB3000_SELECT_HP;
247 fe_cr = ofdm->code_rate_HP;
248 } else if (ofdm->hierarchy_information != HIERARCHY_AUTO) {
249 hrch = DIB3000_HRCH_ON;
250 sel_hp = DIB3000_SELECT_LP;
251 fe_cr = ofdm->code_rate_LP;
252 }
253 switch (fe_cr) {
254 case FEC_1_2: cr = DIB3000_FEC_1_2; break;
255 case FEC_2_3: cr = DIB3000_FEC_2_3; break;
256 case FEC_3_4: cr = DIB3000_FEC_3_4; break;
257 case FEC_5_6: cr = DIB3000_FEC_5_6; break;
258 case FEC_7_8: cr = DIB3000_FEC_7_8; break;
259 case FEC_NONE: break;
260 case FEC_AUTO: break;
261 default: return -EINVAL;
262 }
263 239
264 wr(DIB3000MC_REG_DEMOD_PARM,DIB3000MC_DEMOD_PARM(alpha,qam,guard,fft)); 240 case BANDWIDTH_7_MHZ:
265 wr(DIB3000MC_REG_HRCH_PARM,DIB3000MC_HRCH_PARM(sel_hp,cr,hrch)); 241 bw_cfg[0] = 0x001c; bw_cfg[1] = 0xfba5; bw_cfg[2] = 0x0060; bw_cfg[3] = 0x9c25; bw_cfg[4] = 0x01e3; bw_cfg[5] = 0x0cb7;
242 imp_bw_cfg[0] = 0x04c0; imp_bw_cfg[1] = 0x00c0; imp_bw_cfg[2] = 0x00a0;
243 break;
266 244
267 switch (fep->inversion) { 245 case BANDWIDTH_6_MHZ:
268 case INVERSION_OFF: 246 bw_cfg[0] = 0x0021; bw_cfg[1] = 0xd040; bw_cfg[2] = 0x0070; bw_cfg[3] = 0xb62b; bw_cfg[4] = 0x0233; bw_cfg[5] = 0x8ed5;
269 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF); 247 imp_bw_cfg[0] = 0x04a5; imp_bw_cfg[1] = 0x00a5; imp_bw_cfg[2] = 0x0089;
270 break; 248 break;
271 case INVERSION_AUTO: /* fall through */ 249
272 case INVERSION_ON: 250 case 255 /* BANDWIDTH_5_MHZ */:
273 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_ON); 251 bw_cfg[0] = 0x0028; bw_cfg[1] = 0x9380; bw_cfg[2] = 0x0087; bw_cfg[3] = 0x4100; bw_cfg[4] = 0x02a4; bw_cfg[5] = 0x4500;
252 imp_bw_cfg[0] = 0x0489; imp_bw_cfg[1] = 0x0089; imp_bw_cfg[2] = 0x0072;
274 break; 253 break;
275 default: 254
276 return -EINVAL; 255 default: return -EINVAL;
277 } 256 }
278 257
279 seq = dib3000_seq 258 for (reg = 6; reg < 12; reg++)
280 [ofdm->transmission_mode == TRANSMISSION_MODE_AUTO] 259 dib3000mc_write_word(state, reg, bw_cfg[reg - 6]);
281 [ofdm->guard_interval == GUARD_INTERVAL_AUTO] 260 dib3000mc_write_word(state, 12, 0x0000);
282 [fep->inversion == INVERSION_AUTO]; 261 dib3000mc_write_word(state, 13, 0x03e8);
283 262 dib3000mc_write_word(state, 14, 0x0000);
284 deb_setf("seq? %d\n", seq); 263 dib3000mc_write_word(state, 15, 0x03f2);
285 wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS(seq,1)); 264 dib3000mc_write_word(state, 16, 0x0001);
286 *auto_val = ofdm->constellation == QAM_AUTO || 265 dib3000mc_write_word(state, 17, 0xb0d0);
287 ofdm->hierarchy_information == HIERARCHY_AUTO || 266 // P_sec_len
288 ofdm->guard_interval == GUARD_INTERVAL_AUTO || 267 dib3000mc_write_word(state, 18, 0x0393);
289 ofdm->transmission_mode == TRANSMISSION_MODE_AUTO || 268 dib3000mc_write_word(state, 19, 0x8700);
290 fe_cr == FEC_AUTO ||
291 fep->inversion == INVERSION_AUTO;
292 return 0;
293}
294 269
295static int dib3000mc_get_frontend(struct dvb_frontend* fe, 270 for (reg = 55; reg < 58; reg++)
296 struct dvb_frontend_parameters *fep) 271 dib3000mc_write_word(state, reg, imp_bw_cfg[reg - 55]);
297{
298 struct dib3000_state* state = fe->demodulator_priv;
299 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
300 fe_code_rate_t *cr;
301 u16 tps_val,cr_val;
302 int inv_test1,inv_test2;
303 u32 dds_val, threshold = 0x1000000;
304
305 if (!(rd(DIB3000MC_REG_LOCK_507) & DIB3000MC_LOCK_507))
306 return 0;
307
308 dds_val = (rd(DIB3000MC_REG_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_DDS_FREQ_LSB);
309 deb_getf("DDS_FREQ: %6x\n",dds_val);
310 if (dds_val < threshold)
311 inv_test1 = 0;
312 else if (dds_val == threshold)
313 inv_test1 = 1;
314 else
315 inv_test1 = 2;
316
317 dds_val = (rd(DIB3000MC_REG_SET_DDS_FREQ_MSB) << 16) + rd(DIB3000MC_REG_SET_DDS_FREQ_LSB);
318 deb_getf("DDS_SET_FREQ: %6x\n",dds_val);
319 if (dds_val < threshold)
320 inv_test2 = 0;
321 else if (dds_val == threshold)
322 inv_test2 = 1;
323 else
324 inv_test2 = 2;
325 272
326 fep->inversion = 273 // Timing configuration
327 ((inv_test2 == 2) && (inv_test1==1 || inv_test1==0)) || 274 dib3000mc_set_timing(state, 0, bw, 0);
328 ((inv_test2 == 0) && (inv_test1==1 || inv_test1==2)) ?
329 INVERSION_ON : INVERSION_OFF;
330 275
331 deb_getf("inversion %d %d, %d\n", inv_test2, inv_test1, fep->inversion); 276 return 0;
277}
332 278
333 fep->frequency = state->last_tuned_freq; 279static u16 impulse_noise_val[29] =
334 fep->u.ofdm.bandwidth= state->last_tuned_bw;
335 280
336 tps_val = rd(DIB3000MC_REG_TUNING_PARM); 281{
282 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c, 0x3ffe, 0x7f3,
283 0x2d94, 0x76, 0x53d, 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3, 0x3feb, 0x7d2,
284 0x365e, 0x76, 0x48c, 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0000, 0xd
285};
337 286
338 switch (DIB3000MC_TP_QAM(tps_val)) { 287static void dib3000mc_set_impulse_noise(struct dib3000mc_state *state, u8 mode, s16 nfft)
339 case DIB3000_CONSTELLATION_QPSK: 288{
340 deb_getf("QPSK "); 289 u16 i;
341 ofdm->constellation = QPSK; 290 for (i = 58; i < 87; i++)
342 break; 291 dib3000mc_write_word(state, i, impulse_noise_val[i-58]);
343 case DIB3000_CONSTELLATION_16QAM: 292
344 deb_getf("QAM16 "); 293 if (nfft == 1) {
345 ofdm->constellation = QAM_16; 294 dib3000mc_write_word(state, 58, 0x3b);
346 break; 295 dib3000mc_write_word(state, 84, 0x00);
347 case DIB3000_CONSTELLATION_64QAM: 296 dib3000mc_write_word(state, 85, 0x8200);
348 deb_getf("QAM64 ");
349 ofdm->constellation = QAM_64;
350 break;
351 default:
352 err("Unexpected constellation returned by TPS (%d)", tps_val);
353 break;
354 } 297 }
355 298
356 if (DIB3000MC_TP_HRCH(tps_val)) { 299 dib3000mc_write_word(state, 34, 0x1294);
357 deb_getf("HRCH ON "); 300 dib3000mc_write_word(state, 35, 0x1ff8);
358 cr = &ofdm->code_rate_LP; 301 if (mode == 1)
359 ofdm->code_rate_HP = FEC_NONE; 302 dib3000mc_write_word(state, 55, dib3000mc_read_word(state, 55) | (1 << 10));
360 switch (DIB3000MC_TP_ALPHA(tps_val)) { 303}
361 case DIB3000_ALPHA_0: 304
362 deb_getf("HIERARCHY_NONE "); 305static int dib3000mc_init(struct dvb_frontend *demod)
363 ofdm->hierarchy_information = HIERARCHY_NONE; 306{
364 break; 307 struct dib3000mc_state *state = demod->demodulator_priv;
365 case DIB3000_ALPHA_1: 308 struct dibx000_agc_config *agc = state->cfg->agc;
366 deb_getf("HIERARCHY_1 "); 309
367 ofdm->hierarchy_information = HIERARCHY_1; 310 // Restart Configuration
368 break; 311 dib3000mc_write_word(state, 1027, 0x8000);
369 case DIB3000_ALPHA_2: 312 dib3000mc_write_word(state, 1027, 0x0000);
370 deb_getf("HIERARCHY_2 "); 313
371 ofdm->hierarchy_information = HIERARCHY_2; 314 // power up the demod + mobility configuration
372 break; 315 dib3000mc_write_word(state, 140, 0x0000);
373 case DIB3000_ALPHA_4: 316 dib3000mc_write_word(state, 1031, 0);
374 deb_getf("HIERARCHY_4 "); 317
375 ofdm->hierarchy_information = HIERARCHY_4; 318 if (state->cfg->mobile_mode) {
376 break; 319 dib3000mc_write_word(state, 139, 0x0000);
377 default: 320 dib3000mc_write_word(state, 141, 0x0000);
378 err("Unexpected ALPHA value returned by TPS (%d)", tps_val); 321 dib3000mc_write_word(state, 175, 0x0002);
379 break; 322 dib3000mc_write_word(state, 1032, 0x0000);
380 }
381 cr_val = DIB3000MC_TP_FEC_CR_LP(tps_val);
382 } else { 323 } else {
383 deb_getf("HRCH OFF "); 324 dib3000mc_write_word(state, 139, 0x0001);
384 cr = &ofdm->code_rate_HP; 325 dib3000mc_write_word(state, 141, 0x0000);
385 ofdm->code_rate_LP = FEC_NONE; 326 dib3000mc_write_word(state, 175, 0x0000);
386 ofdm->hierarchy_information = HIERARCHY_NONE; 327 dib3000mc_write_word(state, 1032, 0x012C);
387 cr_val = DIB3000MC_TP_FEC_CR_HP(tps_val);
388 } 328 }
329 dib3000mc_write_word(state, 1033, 0);
389 330
390 switch (cr_val) { 331 // P_clk_cfg
391 case DIB3000_FEC_1_2: 332 dib3000mc_write_word(state, 1037, 12592);
392 deb_getf("FEC_1_2 ");
393 *cr = FEC_1_2;
394 break;
395 case DIB3000_FEC_2_3:
396 deb_getf("FEC_2_3 ");
397 *cr = FEC_2_3;
398 break;
399 case DIB3000_FEC_3_4:
400 deb_getf("FEC_3_4 ");
401 *cr = FEC_3_4;
402 break;
403 case DIB3000_FEC_5_6:
404 deb_getf("FEC_5_6 ");
405 *cr = FEC_4_5;
406 break;
407 case DIB3000_FEC_7_8:
408 deb_getf("FEC_7_8 ");
409 *cr = FEC_7_8;
410 break;
411 default:
412 err("Unexpected FEC returned by TPS (%d)", tps_val);
413 break;
414 }
415 333
416 switch (DIB3000MC_TP_GUARD(tps_val)) { 334 // other configurations
417 case DIB3000_GUARD_TIME_1_32:
418 deb_getf("GUARD_INTERVAL_1_32 ");
419 ofdm->guard_interval = GUARD_INTERVAL_1_32;
420 break;
421 case DIB3000_GUARD_TIME_1_16:
422 deb_getf("GUARD_INTERVAL_1_16 ");
423 ofdm->guard_interval = GUARD_INTERVAL_1_16;
424 break;
425 case DIB3000_GUARD_TIME_1_8:
426 deb_getf("GUARD_INTERVAL_1_8 ");
427 ofdm->guard_interval = GUARD_INTERVAL_1_8;
428 break;
429 case DIB3000_GUARD_TIME_1_4:
430 deb_getf("GUARD_INTERVAL_1_4 ");
431 ofdm->guard_interval = GUARD_INTERVAL_1_4;
432 break;
433 default:
434 err("Unexpected Guard Time returned by TPS (%d)", tps_val);
435 break;
436 }
437 335
438 switch (DIB3000MC_TP_FFT(tps_val)) { 336 // P_ctrl_sfreq
439 case DIB3000_TRANSMISSION_MODE_2K: 337 dib3000mc_write_word(state, 33, (5 << 0));
440 deb_getf("TRANSMISSION_MODE_2K "); 338 dib3000mc_write_word(state, 88, (1 << 10) | (0x10 << 0));
441 ofdm->transmission_mode = TRANSMISSION_MODE_2K; 339
442 break; 340 // Phase noise control
443 case DIB3000_TRANSMISSION_MODE_8K: 341 // P_fft_phacor_inh, P_fft_phacor_cpe, P_fft_powrange
444 deb_getf("TRANSMISSION_MODE_8K "); 342 dib3000mc_write_word(state, 99, (1 << 9) | (0x20 << 0));
445 ofdm->transmission_mode = TRANSMISSION_MODE_8K; 343
446 break; 344 if (state->cfg->phase_noise_mode == 0)
447 default: 345 dib3000mc_write_word(state, 111, 0x00);
448 err("unexpected transmission mode return by TPS (%d)", tps_val); 346 else
449 break; 347 dib3000mc_write_word(state, 111, 0x02);
450 } 348
451 deb_getf("\n"); 349 // P_agc_global
350 dib3000mc_write_word(state, 50, 0x8000);
351
352 // agc setup misc
353 dib3000mc_setup_pwm3_state(state);
354
355 // P_agc_counter_lock
356 dib3000mc_write_word(state, 53, 0x87);
357 // P_agc_counter_unlock
358 dib3000mc_write_word(state, 54, 0x87);
359
360 /* agc */
361 dib3000mc_write_word(state, 36, state->cfg->max_time);
362 dib3000mc_write_word(state, 37, agc->setup);
363 dib3000mc_write_word(state, 38, state->cfg->pwm3_value);
364 dib3000mc_write_word(state, 39, state->cfg->ln_adc_level);
365
366 // set_agc_loop_Bw
367 dib3000mc_write_word(state, 40, 0x0179);
368 dib3000mc_write_word(state, 41, 0x03f0);
369
370 dib3000mc_write_word(state, 42, agc->agc1_max);
371 dib3000mc_write_word(state, 43, agc->agc1_min);
372 dib3000mc_write_word(state, 44, agc->agc2_max);
373 dib3000mc_write_word(state, 45, agc->agc2_min);
374 dib3000mc_write_word(state, 46, (agc->agc1_pt1 << 8) | agc->agc1_pt2);
375 dib3000mc_write_word(state, 47, (agc->agc1_slope1 << 8) | agc->agc1_slope2);
376 dib3000mc_write_word(state, 48, (agc->agc2_pt1 << 8) | agc->agc2_pt2);
377 dib3000mc_write_word(state, 49, (agc->agc2_slope1 << 8) | agc->agc2_slope2);
378
379// Begin: TimeOut registers
380 // P_pha3_thres
381 dib3000mc_write_word(state, 110, 3277);
382 // P_timf_alpha = 6, P_corm_alpha = 6, P_corm_thres = 0x80
383 dib3000mc_write_word(state, 26, 0x6680);
384 // lock_mask0
385 dib3000mc_write_word(state, 1, 4);
386 // lock_mask1
387 dib3000mc_write_word(state, 2, 4);
388 // lock_mask2
389 dib3000mc_write_word(state, 3, 0x1000);
390 // P_search_maxtrial=1
391 dib3000mc_write_word(state, 5, 1);
392
393 dib3000mc_set_bandwidth(&state->demod, BANDWIDTH_8_MHZ);
394
395 // div_lock_mask
396 dib3000mc_write_word(state, 4, 0x814);
397
398 dib3000mc_write_word(state, 21, (1 << 9) | 0x164);
399 dib3000mc_write_word(state, 22, 0x463d);
400
401 // Spurious rm cfg
402 // P_cspu_regul, P_cspu_win_cut
403 dib3000mc_write_word(state, 120, 0x200f);
404 // P_adp_selec_monit
405 dib3000mc_write_word(state, 134, 0);
406
407 // Fec cfg
408 dib3000mc_write_word(state, 195, 0x10);
409
410 // diversity register: P_dvsy_sync_wait..
411 dib3000mc_write_word(state, 180, 0x2FF0);
412
413 // Impulse noise configuration
414 dib3000mc_set_impulse_noise(state, 0, 1);
415
416 // output mode set-up
417 dib3000mc_set_output_mode(state, OUTMODE_HIGH_Z);
418
419 /* close the i2c-gate */
420 dib3000mc_write_word(state, 769, (1 << 7) );
452 421
453 return 0; 422 return 0;
454} 423}
455 424
456static int dib3000mc_set_frontend(struct dvb_frontend* fe, 425static int dib3000mc_sleep(struct dvb_frontend *demod)
457 struct dvb_frontend_parameters *fep, int tuner)
458{ 426{
459 struct dib3000_state* state = fe->demodulator_priv; 427 struct dib3000mc_state *state = demod->demodulator_priv;
460 struct dvb_ofdm_parameters *ofdm = &fep->u.ofdm;
461 int search_state,auto_val;
462 u16 val;
463 428
464 if (tuner && fe->ops.tuner_ops.set_params) { /* initial call from dvb */ 429 dib3000mc_write_word(state, 1037, dib3000mc_read_word(state, 1037) | 0x0003);
465 fe->ops.tuner_ops.set_params(fe, fep); 430 dib3000mc_write_word(state, 1031, 0xFFFF);
466 if (fe->ops.i2c_gate_ctrl) fe->ops.i2c_gate_ctrl(fe, 0); 431 dib3000mc_write_word(state, 1032, 0xFFFF);
467 432 dib3000mc_write_word(state, 1033, 0xFFF4); // **** Bin2
468 state->last_tuned_freq = fep->frequency;
469 // if (!scanboost) {
470 dib3000mc_set_timing(state,0,ofdm->transmission_mode,ofdm->bandwidth);
471 dib3000mc_init_auto_scan(state, ofdm->bandwidth, 0);
472 state->last_tuned_bw = ofdm->bandwidth;
473
474 wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth);
475 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_AGC);
476 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
477
478 /* Default cfg isi offset adp */
479 wr_foreach(dib3000mc_reg_offset,dib3000mc_offset[0]);
480
481 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT | DIB3000MC_ISI_INHIBIT);
482 dib3000mc_set_adp_cfg(state,ofdm->constellation);
483 wr(DIB3000MC_REG_UNK_133,DIB3000MC_UNK_133);
484
485 wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general);
486 /* power smoothing */
487 if (ofdm->bandwidth != BANDWIDTH_8_MHZ) {
488 wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[0]);
489 } else {
490 wr_foreach(dib3000mc_reg_bw,dib3000mc_bw[3]);
491 }
492 auto_val = 0;
493 dib3000mc_set_general_cfg(state,fep,&auto_val);
494 dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
495
496 val = rd(DIB3000MC_REG_DEMOD_PARM);
497 wr(DIB3000MC_REG_DEMOD_PARM,val|DIB3000MC_DEMOD_RST_DEMOD_ON);
498 wr(DIB3000MC_REG_DEMOD_PARM,val);
499 // }
500 msleep(70);
501
502 /* something has to be auto searched */
503 if (auto_val) {
504 int as_count=0;
505
506 deb_setf("autosearch enabled.\n");
507
508 val = rd(DIB3000MC_REG_DEMOD_PARM);
509 wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
510 wr(DIB3000MC_REG_DEMOD_PARM,val);
511
512 while ((search_state = dib3000_search_status(
513 rd(DIB3000MC_REG_AS_IRQ),1)) < 0 && as_count++ < 100)
514 msleep(10);
515
516 deb_info("search_state after autosearch %d after %d checks\n",search_state,as_count);
517
518 if (search_state == 1) {
519 struct dvb_frontend_parameters feps;
520 if (dib3000mc_get_frontend(fe, &feps) == 0) {
521 deb_setf("reading tuning data from frontend succeeded.\n");
522 return dib3000mc_set_frontend(fe, &feps, 0);
523 }
524 }
525 } else {
526 dib3000mc_set_impulse_noise(state,0,ofdm->transmission_mode,ofdm->bandwidth);
527 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE);
528 dib3000mc_set_adp_cfg(state,ofdm->constellation);
529
530 /* set_offset_cfg */
531 wr_foreach(dib3000mc_reg_offset,
532 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]);
533 }
534 } else { /* second call, after autosearch (fka: set_WithKnownParams) */
535// dib3000mc_set_timing(state,1,ofdm->transmission_mode,ofdm->bandwidth);
536
537 auto_val = 0;
538 dib3000mc_set_general_cfg(state,fep,&auto_val);
539 if (auto_val)
540 deb_info("auto_val is true, even though an auto search was already performed.\n");
541
542 dib3000mc_set_impulse_noise(state,0,ofdm->constellation,ofdm->bandwidth);
543
544 val = rd(DIB3000MC_REG_DEMOD_PARM);
545 wr(DIB3000MC_REG_DEMOD_PARM,val | DIB3000MC_DEMOD_RST_AUTO_SRCH_ON);
546 wr(DIB3000MC_REG_DEMOD_PARM,val);
547 433
548 msleep(30); 434 return 0;
435}
549 436
550 wr(DIB3000MC_REG_ISI,DIB3000MC_ISI_DEFAULT|DIB3000MC_ISI_ACTIVATE); 437static void dib3000mc_set_adp_cfg(struct dib3000mc_state *state, s16 qam)
551 dib3000mc_set_adp_cfg(state,ofdm->constellation); 438{
552 wr_foreach(dib3000mc_reg_offset, 439 u16 cfg[4] = { 0 },reg;
553 dib3000mc_offset[(ofdm->transmission_mode == TRANSMISSION_MODE_8K)+1]); 440 switch (qam) {
441 case 0:
442 cfg[0] = 0x099a; cfg[1] = 0x7fae; cfg[2] = 0x0333; cfg[3] = 0x7ff0;
443 break;
444 case 1:
445 cfg[0] = 0x023d; cfg[1] = 0x7fdf; cfg[2] = 0x00a4; cfg[3] = 0x7ff0;
446 break;
447 case 2:
448 cfg[0] = 0x0148; cfg[1] = 0x7ff0; cfg[2] = 0x00a4; cfg[3] = 0x7ff8;
449 break;
554 } 450 }
555 return 0; 451 for (reg = 129; reg < 133; reg++)
452 dib3000mc_write_word(state, reg, cfg[reg - 129]);
556} 453}
557 454
558static int dib3000mc_fe_init(struct dvb_frontend* fe, int mobile_mode) 455static void dib3000mc_set_channel_cfg(struct dib3000mc_state *state, struct dibx000_ofdm_channel *chan, u16 seq)
559{ 456{
560 struct dib3000_state *state = fe->demodulator_priv; 457 u16 tmp;
561 deb_info("init start\n");
562
563 state->timing_offset = 0;
564 state->timing_offset_comp_done = 0;
565 458
566 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_CONFIG); 459 dib3000mc_set_timing(state, chan->nfft, chan->Bw, 0);
567 wr(DIB3000MC_REG_RESTART,DIB3000MC_RESTART_OFF);
568 wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_UP);
569 wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_PUP_MOBILE);
570 wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_UP);
571 wr(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_INIT);
572 460
573 wr(DIB3000MC_REG_RST_UNC,DIB3000MC_RST_UNC_OFF); 461// if (boost)
574 wr(DIB3000MC_REG_UNK_19,DIB3000MC_UNK_19); 462// dib3000mc_write_word(state, 100, (11 << 6) + 6);
463// else
464 dib3000mc_write_word(state, 100, (16 << 6) + 9);
575 465
576 wr(33,5); 466 dib3000mc_write_word(state, 1027, 0x0800);
577 wr(36,81); 467 dib3000mc_write_word(state, 1027, 0x0000);
578 wr(DIB3000MC_REG_UNK_88,DIB3000MC_UNK_88);
579 468
580 wr(DIB3000MC_REG_UNK_99,DIB3000MC_UNK_99); 469 //Default cfg isi offset adp
581 wr(DIB3000MC_REG_UNK_111,DIB3000MC_UNK_111_PH_N_MODE_0); /* phase noise algo off */ 470 dib3000mc_write_word(state, 26, 0x6680);
471 dib3000mc_write_word(state, 29, 0x1273);
472 dib3000mc_write_word(state, 33, 5);
473 dib3000mc_set_adp_cfg(state, 1);
474 dib3000mc_write_word(state, 133, 15564);
582 475
583 /* mobile mode - portable reception */ 476 dib3000mc_write_word(state, 12 , 0x0);
584 wr_foreach(dib3000mc_reg_mobile_mode,dib3000mc_mobile_mode[1]); 477 dib3000mc_write_word(state, 13 , 0x3e8);
478 dib3000mc_write_word(state, 14 , 0x0);
479 dib3000mc_write_word(state, 15 , 0x3f2);
585 480
586/* TUNER_PANASONIC_ENV57H12D5: */ 481 dib3000mc_write_word(state, 93,0);
587 wr_foreach(dib3000mc_reg_agc_bandwidth,dib3000mc_agc_bandwidth); 482 dib3000mc_write_word(state, 94,0);
588 wr_foreach(dib3000mc_reg_agc_bandwidth_general,dib3000mc_agc_bandwidth_general); 483 dib3000mc_write_word(state, 95,0);
589 wr_foreach(dib3000mc_reg_agc,dib3000mc_agc_tuner[1]); 484 dib3000mc_write_word(state, 96,0);
485 dib3000mc_write_word(state, 97,0);
486 dib3000mc_write_word(state, 98,0);
590 487
591 wr(DIB3000MC_REG_UNK_110,DIB3000MC_UNK_110); 488 dib3000mc_set_impulse_noise(state, 0, chan->nfft);
592 wr(26,0x6680);
593 wr(DIB3000MC_REG_UNK_1,DIB3000MC_UNK_1);
594 wr(DIB3000MC_REG_UNK_2,DIB3000MC_UNK_2);
595 wr(DIB3000MC_REG_UNK_3,DIB3000MC_UNK_3);
596 wr(DIB3000MC_REG_SEQ_TPS,DIB3000MC_SEQ_TPS_DEFAULT);
597 489
598 wr_foreach(dib3000mc_reg_bandwidth,dib3000mc_bandwidth_8mhz); 490 tmp = ((chan->nfft & 0x1) << 7) | (chan->guard << 5) | (chan->nqam << 3) | chan->vit_alpha;
599 wr_foreach(dib3000mc_reg_bandwidth_general,dib3000mc_bandwidth_general); 491 dib3000mc_write_word(state, 0, tmp);
600 492
601 wr(DIB3000MC_REG_UNK_4,DIB3000MC_UNK_4); 493 dib3000mc_write_word(state, 5, seq);
602 494
603 wr(DIB3000MC_REG_SET_DDS_FREQ_MSB,DIB3000MC_DDS_FREQ_MSB_INV_OFF); 495 tmp = (chan->vit_hrch << 4) | (chan->vit_select_hp);
604 wr(DIB3000MC_REG_SET_DDS_FREQ_LSB,DIB3000MC_DDS_FREQ_LSB); 496 if (!chan->vit_hrch || (chan->vit_hrch && chan->vit_select_hp))
497 tmp |= chan->vit_code_rate_hp << 1;
498 else
499 tmp |= chan->vit_code_rate_lp << 1;
500 dib3000mc_write_word(state, 181, tmp);
605 501
606 dib3000mc_set_timing(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ); 502 // diversity synchro delay
607// wr_foreach(dib3000mc_reg_timing_freq,dib3000mc_timing_freq[3]); 503 tmp = dib3000mc_read_word(state, 180) & 0x000f;
504 tmp |= ((chan->nfft == 0) ? 64 : 256) * ((1 << (chan->guard)) * 3 / 2) << 4; // add 50% SFN margin
505 dib3000mc_write_word(state, 180, tmp);
608 506
609 wr(DIB3000MC_REG_UNK_120,DIB3000MC_UNK_120); 507 // restart demod
610 wr(DIB3000MC_REG_UNK_134,DIB3000MC_UNK_134); 508 tmp = dib3000mc_read_word(state, 0);
611 wr(DIB3000MC_REG_FEC_CFG,DIB3000MC_FEC_CFG); 509 dib3000mc_write_word(state, 0, tmp | (1 << 9));
510 dib3000mc_write_word(state, 0, tmp);
612 511
613 wr(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF); 512 msleep(30);
614 513
615 dib3000mc_set_impulse_noise(state,0,TRANSMISSION_MODE_8K,BANDWIDTH_8_MHZ); 514 dib3000mc_set_impulse_noise(state, state->cfg->impulse_noise_mode, chan->nfft);
515}
616 516
617/* output mode control, just the MPEG2_SLAVE */ 517static int dib3000mc_autosearch_start(struct dvb_frontend *demod, struct dibx000_ofdm_channel *chan)
618// set_or(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE); 518{
619 wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_SLAVE); 519 struct dib3000mc_state *state = demod->demodulator_priv;
620 wr(DIB3000MC_REG_SMO_MODE,DIB3000MC_SMO_MODE_SLAVE); 520 u16 reg;
621 wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_SLAVE); 521// u32 val;
622 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_SLAVE); 522 struct dibx000_ofdm_channel fchan;
623 523
624/* MPEG2_PARALLEL_CONTINUOUS_CLOCK 524 INIT_OFDM_CHANNEL(&fchan);
625 wr(DIB3000MC_REG_OUTMODE, 525 fchan = *chan;
626 DIB3000MC_SET_OUTMODE(DIB3000MC_OM_PAR_CONT_CLK,
627 rd(DIB3000MC_REG_OUTMODE)));
628 526
629 wr(DIB3000MC_REG_SMO_MODE,
630 DIB3000MC_SMO_MODE_DEFAULT |
631 DIB3000MC_SMO_MODE_188);
632 527
633 wr(DIB3000MC_REG_FIFO_THRESHOLD,DIB3000MC_FIFO_THRESHOLD_DEFAULT); 528 /* a channel for autosearch */
634 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON); 529 reg = 0;
635*/ 530 if (chan->nfft == -1 && chan->guard == -1) reg = 7;
531 if (chan->nfft == -1 && chan->guard != -1) reg = 2;
532 if (chan->nfft != -1 && chan->guard == -1) reg = 3;
636 533
637/* diversity */ 534 fchan.nfft = 1; fchan.guard = 0; fchan.nqam = 2;
638 wr(DIB3000MC_REG_DIVERSITY1,DIB3000MC_DIVERSITY1_DEFAULT); 535 fchan.vit_alpha = 1; fchan.vit_code_rate_hp = 2; fchan.vit_code_rate_lp = 2;
639 wr(DIB3000MC_REG_DIVERSITY2,DIB3000MC_DIVERSITY2_DEFAULT); 536 fchan.vit_hrch = 0; fchan.vit_select_hp = 1;
640 537
641 set_and(DIB3000MC_REG_DIVERSITY3,DIB3000MC_DIVERSITY3_IN_OFF); 538 dib3000mc_set_channel_cfg(state, &fchan, reg);
642 539
643 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_DIV_IN_OFF); 540 reg = dib3000mc_read_word(state, 0);
541 dib3000mc_write_word(state, 0, reg | (1 << 8));
542 dib3000mc_write_word(state, 0, reg);
644 543
645 deb_info("init end\n");
646 return 0; 544 return 0;
647} 545}
648static int dib3000mc_read_status(struct dvb_frontend* fe, fe_status_t *stat) 546
547static int dib3000mc_autosearch_is_irq(struct dvb_frontend *demod)
649{ 548{
650 struct dib3000_state* state = fe->demodulator_priv; 549 struct dib3000mc_state *state = demod->demodulator_priv;
651 u16 lock = rd(DIB3000MC_REG_LOCKING); 550 u16 irq_pending = dib3000mc_read_word(state, 511);
652 551
653 *stat = 0; 552 if (irq_pending & 0x1) // failed
654 if (DIB3000MC_AGC_LOCK(lock)) 553 return 1;
655 *stat |= FE_HAS_SIGNAL;
656 if (DIB3000MC_CARRIER_LOCK(lock))
657 *stat |= FE_HAS_CARRIER;
658 if (DIB3000MC_TPS_LOCK(lock))
659 *stat |= FE_HAS_VITERBI;
660 if (DIB3000MC_MPEG_SYNC_LOCK(lock))
661 *stat |= (FE_HAS_SYNC | FE_HAS_LOCK);
662 554
663 deb_stat("actual status is %2x fifo_level: %x,244: %x, 206: %x, 207: %x, 1040: %x\n",*stat,rd(510),rd(244),rd(206),rd(207),rd(1040)); 555 if (irq_pending & 0x2) // succeeded
556 return 2;
664 557
665 return 0; 558 return 0; // still pending
666} 559}
667 560
668static int dib3000mc_read_ber(struct dvb_frontend* fe, u32 *ber) 561static int dib3000mc_tune(struct dvb_frontend *demod, struct dibx000_ofdm_channel *ch)
669{ 562{
670 struct dib3000_state* state = fe->demodulator_priv; 563 struct dib3000mc_state *state = demod->demodulator_priv;
671 *ber = ((rd(DIB3000MC_REG_BER_MSB) << 16) | rd(DIB3000MC_REG_BER_LSB)); 564
565 // ** configure demod **
566 dib3000mc_set_channel_cfg(state, ch, 0);
567
568 // activates isi
569 dib3000mc_write_word(state, 29, 0x1073);
570
571 dib3000mc_set_adp_cfg(state, (u8)ch->nqam);
572
573 if (ch->nfft == 1) {
574 dib3000mc_write_word(state, 26, 38528);
575 dib3000mc_write_word(state, 33, 8);
576 } else {
577 dib3000mc_write_word(state, 26, 30336);
578 dib3000mc_write_word(state, 33, 6);
579 }
580
581 // if (lock)
582 // dib3000mc_set_timing(state, ch->nfft, ch->Bw, 1);
583
672 return 0; 584 return 0;
673} 585}
674 586
675static int dib3000mc_read_unc_blocks(struct dvb_frontend* fe, u32 *unc) 587static int dib3000mc_demod_output_mode(struct dvb_frontend *demod, int mode)
676{ 588{
677 struct dib3000_state* state = fe->demodulator_priv; 589 struct dib3000mc_state *state = demod->demodulator_priv;
678 590 return dib3000mc_set_output_mode(state, mode);
679 *unc = rd(DIB3000MC_REG_PACKET_ERRORS);
680 return 0;
681} 591}
682 592
683/* see dib3000mb.c for calculation comments */ 593static int dib3000mc_i2c_enumeration(struct dvb_frontend *demod[], int no_of_demods, u8 default_addr)
684static int dib3000mc_read_signal_strength(struct dvb_frontend* fe, u16 *strength)
685{ 594{
686 struct dib3000_state* state = fe->demodulator_priv; 595 struct dib3000mc_state *st;
687 u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB); 596 int k,ret=0;
688 *strength = (((val >> 6) & 0xff) << 8) + (val & 0x3f); 597 u8 new_addr;
598
599 static u8 DIB3000MC_I2C_ADDRESS[] = {20,22,24,26};
600
601 for (k = no_of_demods-1; k >= 0; k--) {
602 st = demod[k]->demodulator_priv;
603
604 /* designated i2c address */
605 new_addr = DIB3000MC_I2C_ADDRESS[k];
606
607 st->i2c_addr = new_addr;
608 if (dib3000mc_identify(st) != 0) {
609 st->i2c_addr = default_addr;
610 if (dib3000mc_identify(st) != 0) {
611 dprintk("-E- DiB3000P/MC #%d: not identified\n", k);
612 return -EINVAL;
613 }
614 }
615
616 /* turn on div_out */
617 dib3000mc_demod_output_mode(demod[k], OUTMODE_MPEG2_PAR_CONT_CLK);
618
619 // set new i2c address and force divstr (Bit 1) to value 0 (Bit 0)
620 ret |= dib3000mc_write_word(st, 1024, (new_addr << 3) | 0x1);
621 st->i2c_addr = new_addr;
622 }
623
624 for (k = 0; k < no_of_demods; k++) {
625 st = demod[k]->demodulator_priv;
626
627 ret |= dib3000mc_write_word(st, 1024, st->i2c_addr << 3);
689 628
690 deb_stat("signal: mantisse = %d, exponent = %d\n",(*strength >> 8) & 0xff, *strength & 0xff); 629 /* turn off data output */
630 dib3000mc_demod_output_mode(demod[k],OUTMODE_HIGH_Z);
631 dib3000mc_write_word(st, 769, (1 << 7) );
632
633 }
691 return 0; 634 return 0;
692} 635}
693 636
694/* see dib3000mb.c for calculation comments */ 637struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating)
695static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
696{ 638{
697 struct dib3000_state* state = fe->demodulator_priv; 639 struct dib3000mc_state *st = demod->demodulator_priv;
698 u16 val = rd(DIB3000MC_REG_SIGNAL_NOISE_LSB), 640 return dibx000_get_i2c_adapter(&st->i2c_master, DIBX000_I2C_INTERFACE_TUNER, gating);
699 val2 = rd(DIB3000MC_REG_SIGNAL_NOISE_MSB); 641}
700 u16 sig,noise;
701 642
702 sig = (((val >> 6) & 0xff) << 8) + (val & 0x3f); 643EXPORT_SYMBOL(dib3000mc_get_tuner_i2c_master);
703 noise = (((val >> 4) & 0xff) << 8) + ((val & 0xf) << 2) + ((val2 >> 14) & 0x3); 644
704 if (noise == 0) 645static int dib3000mc_get_frontend(struct dvb_frontend* fe,
705 *snr = 0xffff; 646 struct dvb_frontend_parameters *fep)
706 else 647{
707 *snr = (u16) sig/noise; 648 struct dib3000mc_state *state = fe->demodulator_priv;
649 u16 tps = dib3000mc_read_word(state,458);
650
651 fep->inversion = INVERSION_AUTO;
652
653 fep->u.ofdm.bandwidth = state->current_bandwidth;
654
655 switch ((tps >> 8) & 0x1) {
656 case 0: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_2K; break;
657 case 1: fep->u.ofdm.transmission_mode = TRANSMISSION_MODE_8K; break;
658 }
659
660 switch (tps & 0x3) {
661 case 0: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_32; break;
662 case 1: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_16; break;
663 case 2: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_8; break;
664 case 3: fep->u.ofdm.guard_interval = GUARD_INTERVAL_1_4; break;
665 }
666
667 switch ((tps >> 13) & 0x3) {
668 case 0: fep->u.ofdm.constellation = QPSK; break;
669 case 1: fep->u.ofdm.constellation = QAM_16; break;
670 case 2:
671 default: fep->u.ofdm.constellation = QAM_64; break;
672 }
673
674 /* as long as the frontend_param structure is fixed for hierarchical transmission I refuse to use it */
675 /* (tps >> 12) & 0x1 == hrch is used, (tps >> 9) & 0x7 == alpha */
676
677 fep->u.ofdm.hierarchy_information = HIERARCHY_NONE;
678 switch ((tps >> 5) & 0x7) {
679 case 1: fep->u.ofdm.code_rate_HP = FEC_1_2; break;
680 case 2: fep->u.ofdm.code_rate_HP = FEC_2_3; break;
681 case 3: fep->u.ofdm.code_rate_HP = FEC_3_4; break;
682 case 5: fep->u.ofdm.code_rate_HP = FEC_5_6; break;
683 case 7:
684 default: fep->u.ofdm.code_rate_HP = FEC_7_8; break;
685
686 }
687
688 switch ((tps >> 2) & 0x7) {
689 case 1: fep->u.ofdm.code_rate_LP = FEC_1_2; break;
690 case 2: fep->u.ofdm.code_rate_LP = FEC_2_3; break;
691 case 3: fep->u.ofdm.code_rate_LP = FEC_3_4; break;
692 case 5: fep->u.ofdm.code_rate_LP = FEC_5_6; break;
693 case 7:
694 default: fep->u.ofdm.code_rate_LP = FEC_7_8; break;
695 }
708 696
709 deb_stat("signal: mantisse = %d, exponent = %d\n",(sig >> 8) & 0xff, sig & 0xff);
710 deb_stat("noise: mantisse = %d, exponent = %d\n",(noise >> 8) & 0xff, noise & 0xff);
711 deb_stat("snr: %d\n",*snr);
712 return 0; 697 return 0;
713} 698}
714 699
715static int dib3000mc_sleep(struct dvb_frontend* fe) 700static int dib3000mc_set_frontend(struct dvb_frontend* fe,
701 struct dvb_frontend_parameters *fep)
716{ 702{
717 struct dib3000_state* state = fe->demodulator_priv; 703 struct dib3000mc_state *state = fe->demodulator_priv;
704 struct dibx000_ofdm_channel ch;
718 705
719 set_or(DIB3000MC_REG_CLK_CFG_7,DIB3000MC_CLK_CFG_7_PWR_DOWN); 706 INIT_OFDM_CHANNEL(&ch);
720 wr(DIB3000MC_REG_CLK_CFG_1,DIB3000MC_CLK_CFG_1_POWER_DOWN); 707 FEP2DIB(fep,&ch);
721 wr(DIB3000MC_REG_CLK_CFG_2,DIB3000MC_CLK_CFG_2_POWER_DOWN); 708
722 wr(DIB3000MC_REG_CLK_CFG_3,DIB3000MC_CLK_CFG_3_POWER_DOWN); 709 state->current_bandwidth = fep->u.ofdm.bandwidth;
723 return 0; 710 dib3000mc_set_bandwidth(fe, fep->u.ofdm.bandwidth);
711
712 if (fe->ops.tuner_ops.set_params) {
713 fe->ops.tuner_ops.set_params(fe, fep);
714 msleep(100);
715 }
716
717 if (fep->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ||
718 fep->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ||
719 fep->u.ofdm.constellation == QAM_AUTO ||
720 fep->u.ofdm.code_rate_HP == FEC_AUTO) {
721 int i = 100, found;
722
723 dib3000mc_autosearch_start(fe, &ch);
724 do {
725 msleep(1);
726 found = dib3000mc_autosearch_is_irq(fe);
727 } while (found == 0 && i--);
728
729 dprintk("autosearch returns: %d\n",found);
730 if (found == 0 || found == 1)
731 return 0; // no channel found
732
733 dib3000mc_get_frontend(fe, fep);
734 FEP2DIB(fep,&ch);
735 }
736
737 /* make this a config parameter */
738 dib3000mc_set_output_mode(state, OUTMODE_MPEG2_FIFO);
739
740 return dib3000mc_tune(fe, &ch);
724} 741}
725 742
726static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune) 743static int dib3000mc_read_status(struct dvb_frontend *fe, fe_status_t *stat)
727{ 744{
728 tune->min_delay_ms = 1000; 745 struct dib3000mc_state *state = fe->demodulator_priv;
746 u16 lock = dib3000mc_read_word(state, 509);
747
748 *stat = 0;
749
750 if (lock & 0x8000)
751 *stat |= FE_HAS_SIGNAL;
752 if (lock & 0x3000)
753 *stat |= FE_HAS_CARRIER;
754 if (lock & 0x0100)
755 *stat |= FE_HAS_VITERBI;
756 if (lock & 0x0010)
757 *stat |= FE_HAS_SYNC;
758 if (lock & 0x0008)
759 *stat |= FE_HAS_LOCK;
760
729 return 0; 761 return 0;
730} 762}
731 763
732static int dib3000mc_fe_init_nonmobile(struct dvb_frontend* fe) 764static int dib3000mc_read_ber(struct dvb_frontend *fe, u32 *ber)
733{ 765{
734 return dib3000mc_fe_init(fe, 0); 766 struct dib3000mc_state *state = fe->demodulator_priv;
767 *ber = (dib3000mc_read_word(state, 500) << 16) | dib3000mc_read_word(state, 501);
768 return 0;
735} 769}
736 770
737static int dib3000mc_set_frontend_and_tuner(struct dvb_frontend* fe, struct dvb_frontend_parameters *fep) 771static int dib3000mc_read_unc_blocks(struct dvb_frontend *fe, u32 *unc)
738{ 772{
739 return dib3000mc_set_frontend(fe, fep, 1); 773 struct dib3000mc_state *state = fe->demodulator_priv;
774 *unc = dib3000mc_read_word(state, 508);
775 return 0;
740} 776}
741 777
742static void dib3000mc_release(struct dvb_frontend* fe) 778static int dib3000mc_read_signal_strength(struct dvb_frontend *fe, u16 *strength)
743{ 779{
744 struct dib3000_state *state = fe->demodulator_priv; 780 struct dib3000mc_state *state = fe->demodulator_priv;
745 kfree(state); 781 u16 val = dib3000mc_read_word(state, 392);
782 *strength = 65535 - val;
783 return 0;
746} 784}
747 785
748/* pid filter and transfer stuff */ 786static int dib3000mc_read_snr(struct dvb_frontend* fe, u16 *snr)
749static int dib3000mc_pid_control(struct dvb_frontend *fe,int index, int pid,int onoff)
750{ 787{
751 struct dib3000_state *state = fe->demodulator_priv; 788 *snr = 0x0000;
752 pid = (onoff ? pid | DIB3000_ACTIVATE_PID_FILTERING : 0);
753 wr(index+DIB3000MC_REG_FIRST_PID,pid);
754 return 0; 789 return 0;
755} 790}
756 791
757static int dib3000mc_fifo_control(struct dvb_frontend *fe, int onoff) 792static int dib3000mc_fe_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings *tune)
758{ 793{
759 struct dib3000_state *state = fe->demodulator_priv; 794 tune->min_delay_ms = 1000;
760 u16 tmp = rd(DIB3000MC_REG_SMO_MODE);
761
762 deb_xfer("%s fifo\n",onoff ? "enabling" : "disabling");
763
764 if (onoff) {
765 deb_xfer("%d %x\n",tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
766 wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_FIFO_UNFLUSH);
767 } else {
768 deb_xfer("%d %x\n",tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
769 wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_FIFO_FLUSH);
770 }
771 return 0; 795 return 0;
772} 796}
773 797
774static int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff) 798static void dib3000mc_release(struct dvb_frontend *fe)
775{ 799{
776 struct dib3000_state *state = fe->demodulator_priv; 800 struct dib3000mc_state *state = fe->demodulator_priv;
777 u16 tmp = rd(DIB3000MC_REG_SMO_MODE); 801 dibx000_exit_i2c_master(&state->i2c_master);
778 802 kfree(state);
779 deb_xfer("%s pid parsing\n",onoff ? "enabling" : "disabling");
780
781 if (onoff) {
782 wr(DIB3000MC_REG_SMO_MODE,tmp | DIB3000MC_SMO_MODE_PID_PARSE);
783 } else {
784 wr(DIB3000MC_REG_SMO_MODE,tmp & DIB3000MC_SMO_MODE_NO_PID_PARSE);
785 }
786 return 0;
787} 803}
788 804
789static int dib3000mc_tuner_pass_ctrl(struct dvb_frontend *fe, int onoff, u8 pll_addr) 805int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff)
790{ 806{
791 struct dib3000_state *state = fe->demodulator_priv; 807 struct dib3000mc_state *state = fe->demodulator_priv;
792 if (onoff) { 808 dib3000mc_write_word(state, 212 + index, onoff ? (1 << 13) | pid : 0);
793 wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_ENABLE(pll_addr));
794 } else {
795 wr(DIB3000MC_REG_TUNER, DIB3000_TUNER_WRITE_DISABLE(pll_addr));
796 }
797 return 0; 809 return 0;
798} 810}
811EXPORT_SYMBOL(dib3000mc_pid_control);
799 812
800static int dib3000mc_demod_init(struct dib3000_state *state) 813int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff)
801{ 814{
802 u16 default_addr = 0x0a; 815 struct dib3000mc_state *state = fe->demodulator_priv;
803 /* first init */ 816 u16 tmp = dib3000mc_read_word(state, 206) & ~(1 << 4);
804 if (state->config.demod_address != default_addr) { 817 tmp |= (onoff << 4);
805 deb_info("initializing the demod the first time. Setting demod addr to 0x%x\n",default_addr); 818 return dib3000mc_write_word(state, 206, tmp);
806 wr(DIB3000MC_REG_ELEC_OUT,DIB3000MC_ELEC_OUT_DIV_OUT_ON);
807 wr(DIB3000MC_REG_OUTMODE,DIB3000MC_OM_PAR_CONT_CLK);
808
809 wr(DIB3000MC_REG_RST_I2C_ADDR,
810 DIB3000MC_DEMOD_ADDR(default_addr) |
811 DIB3000MC_DEMOD_ADDR_ON);
812
813 state->config.demod_address = default_addr;
814
815 wr(DIB3000MC_REG_RST_I2C_ADDR,
816 DIB3000MC_DEMOD_ADDR(default_addr));
817 } else
818 deb_info("demod is already initialized. Demod addr: 0x%x\n",state->config.demod_address);
819 return 0;
820} 819}
820EXPORT_SYMBOL(dib3000mc_pid_parse);
821 821
822void dib3000mc_set_config(struct dvb_frontend *fe, struct dib3000mc_config *cfg)
823{
824 struct dib3000mc_state *state = fe->demodulator_priv;
825 state->cfg = cfg;
826}
827EXPORT_SYMBOL(dib3000mc_set_config);
822 828
823static struct dvb_frontend_ops dib3000mc_ops; 829static struct dvb_frontend_ops dib3000mc_ops;
824 830
825struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config, 831int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr, u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[])
826 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
827{ 832{
828 struct dib3000_state* state = NULL; 833 struct dib3000mc_state *st;
829 u16 devid; 834 int k, num=0;
830 835
831 /* allocate memory for the internal state */ 836 if (no_of_demods < 1)
832 state = kzalloc(sizeof(struct dib3000_state), GFP_KERNEL); 837 return -EINVAL;
833 if (state == NULL)
834 goto error;
835 838
836 /* setup the state */ 839 for (k = 0; k < no_of_demods; k++) {
837 state->i2c = i2c; 840 st = kzalloc(sizeof(struct dib3000mc_state), GFP_KERNEL);
838 memcpy(&state->config,config,sizeof(struct dib3000_config)); 841 if (st == NULL)
842 goto error;
839 843
840 /* check for the correct demod */ 844 num++;
841 if (rd(DIB3000_REG_MANUFACTOR_ID) != DIB3000_I2C_ID_DIBCOM)
842 goto error;
843 845
844 devid = rd(DIB3000_REG_DEVICE_ID); 846 st->cfg = &cfg[k];
845 if (devid != DIB3000MC_DEVICE_ID && devid != DIB3000P_DEVICE_ID) 847 // st->gpio_val = cfg[k].gpio_val;
846 goto error; 848 // st->gpio_dir = cfg[k].gpio_dir;
849 st->i2c_adap = i2c_adap;
847 850
848 switch (devid) { 851 demod[k] = &st->demod;
849 case DIB3000MC_DEVICE_ID: 852 demod[k]->demodulator_priv = st;
850 info("Found a DiBcom 3000M-C, interesting..."); 853 memcpy(&st->demod.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops));
851 break;
852 case DIB3000P_DEVICE_ID:
853 info("Found a DiBcom 3000P.");
854 break;
855 }
856 854
857 /* create dvb_frontend */ 855// INIT_COMPONENT_REGISTER_ACCESS(&st->register_access, 12, 16, dib7000p_register_read, dib7000p_register_write, st);
858 memcpy(&state->frontend.ops, &dib3000mc_ops, sizeof(struct dvb_frontend_ops)); 856// demod[k]->register_access = &st->register_access;
859 state->frontend.demodulator_priv = state; 857 }
860 858
861 /* set the xfer operations */ 859 if (do_i2c_enum) {
862 xfer_ops->pid_parse = dib3000mc_pid_parse; 860 if (dib3000mc_i2c_enumeration(demod,no_of_demods,default_addr) != 0)
863 xfer_ops->fifo_ctrl = dib3000mc_fifo_control; 861 goto error;
864 xfer_ops->pid_ctrl = dib3000mc_pid_control; 862 } else {
865 xfer_ops->tuner_pass_ctrl = dib3000mc_tuner_pass_ctrl; 863 st = demod[0]->demodulator_priv;
864 st->i2c_addr = default_addr;
865 if (dib3000mc_identify(st) != 0)
866 goto error;
867 }
866 868
867 dib3000mc_demod_init(state); 869 for (k = 0; k < num; k++) {
870 st = demod[k]->demodulator_priv;
871 dibx000_init_i2c_master(&st->i2c_master, DIB3000MC, st->i2c_adap, st->i2c_addr);
872 }
868 873
869 return &state->frontend; 874 return 0;
870 875
871error: 876error:
872 kfree(state); 877 for (k = 0; k < num; k++) {
873 return NULL; 878 kfree(demod[k]->demodulator_priv);
879 demod[k] = NULL;
880 }
881 return -EINVAL;
874} 882}
883
875EXPORT_SYMBOL(dib3000mc_attach); 884EXPORT_SYMBOL(dib3000mc_attach);
876 885
877static struct dvb_frontend_ops dib3000mc_ops = { 886static struct dvb_frontend_ops dib3000mc_ops = {
878
879 .info = { 887 .info = {
880 .name = "DiBcom 3000P/M-C DVB-T", 888 .name = "DiBcom 3000MC/P",
881 .type = FE_OFDM, 889 .type = FE_OFDM,
882 .frequency_min = 44250000, 890 .frequency_min = 44250000,
883 .frequency_max = 867250000, 891 .frequency_max = 867250000,
884 .frequency_stepsize = 62500, 892 .frequency_stepsize = 62500,
885 .caps = FE_CAN_INVERSION_AUTO | 893 .caps = FE_CAN_INVERSION_AUTO |
886 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 | 894 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
887 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO | 895 FE_CAN_FEC_5_6 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
888 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO | 896 FE_CAN_QPSK | FE_CAN_QAM_16 | FE_CAN_QAM_64 | FE_CAN_QAM_AUTO |
889 FE_CAN_TRANSMISSION_MODE_AUTO | 897 FE_CAN_TRANSMISSION_MODE_AUTO |
890 FE_CAN_GUARD_INTERVAL_AUTO | 898 FE_CAN_GUARD_INTERVAL_AUTO |
891 FE_CAN_RECOVER | 899 FE_CAN_RECOVER |
892 FE_CAN_HIERARCHY_AUTO, 900 FE_CAN_HIERARCHY_AUTO,
893 }, 901 },
894 902
895 .release = dib3000mc_release, 903 .release = dib3000mc_release,
896 904
897 .init = dib3000mc_fe_init_nonmobile, 905 .init = dib3000mc_init,
898 .sleep = dib3000mc_sleep, 906 .sleep = dib3000mc_sleep,
899 907
900 .set_frontend = dib3000mc_set_frontend_and_tuner, 908 .set_frontend = dib3000mc_set_frontend,
901 .get_frontend = dib3000mc_get_frontend, 909 .get_tune_settings = dib3000mc_fe_get_tune_settings,
902 .get_tune_settings = dib3000mc_fe_get_tune_settings, 910 .get_frontend = dib3000mc_get_frontend,
903 911
904 .read_status = dib3000mc_read_status, 912 .read_status = dib3000mc_read_status,
905 .read_ber = dib3000mc_read_ber, 913 .read_ber = dib3000mc_read_ber,
906 .read_signal_strength = dib3000mc_read_signal_strength, 914 .read_signal_strength = dib3000mc_read_signal_strength,
907 .read_snr = dib3000mc_read_snr, 915 .read_snr = dib3000mc_read_snr,
908 .read_ucblocks = dib3000mc_read_unc_blocks, 916 .read_ucblocks = dib3000mc_read_unc_blocks,
909}; 917};
910 918
911MODULE_AUTHOR(DRIVER_AUTHOR); 919MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
912MODULE_DESCRIPTION(DRIVER_DESC); 920MODULE_DESCRIPTION("Driver for the DiBcom 3000MC/P COFDM demodulator");
913MODULE_LICENSE("GPL"); 921MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dib3000mc.h b/drivers/media/dvb/frontends/dib3000mc.h
new file mode 100644
index 000000000000..fd0b2e755993
--- /dev/null
+++ b/drivers/media/dvb/frontends/dib3000mc.h
@@ -0,0 +1,58 @@
1/*
2 * Driver for DiBcom DiB3000MC/P-demodulator.
3 *
4 * Copyright (C) 2004-6 DiBcom (http://www.dibcom.fr/)
5 * Copyright (C) 2004-5 Patrick Boettcher (patrick.boettcher\@desy.de)
6 *
7 * This code is partially based on the previous dib3000mc.c .
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License as
11 * published by the Free Software Foundation, version 2.
12 */
13#ifndef DIB3000MC_H
14#define DIB3000MC_H
15
16#include "dibx000_common.h"
17
18struct dib3000mc_config {
19 struct dibx000_agc_config *agc;
20
21 u8 phase_noise_mode;
22 u8 impulse_noise_mode;
23
24 u8 pwm3_inversion;
25 u8 use_pwm3;
26 u16 pwm3_value;
27
28 u16 max_time;
29 u16 ln_adc_level;
30
31 u8 mobile_mode;
32
33 u8 output_mpeg2_in_188_bytes;
34};
35
36#define DEFAULT_DIB3000MC_I2C_ADDRESS 16
37#define DEFAULT_DIB3000P_I2C_ADDRESS 24
38
39#if defined(CONFIG_DVB_DIB3000MC) || defined(CONFIG_DVB_DIB3000MC_MODULE)
40extern int dib3000mc_attach(struct i2c_adapter *i2c_adap, int no_of_demods, u8 default_addr,
41 u8 do_i2c_enum, struct dib3000mc_config cfg[], struct dvb_frontend *demod[]);
42#else
43static inline struct dvb_frontend* dib3000mc_attach(const struct dib3000_config* config,
44 struct i2c_adapter* i2c, struct dib_fe_xfer_ops *xfer_ops)
45{
46 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
47 return NULL;
48}
49#endif // CONFIG_DVB_DIB3000MC
50
51extern struct i2c_adapter * dib3000mc_get_tuner_i2c_master(struct dvb_frontend *demod, int gating);
52
53extern int dib3000mc_pid_control(struct dvb_frontend *fe, int index, int pid,int onoff);
54extern int dib3000mc_pid_parse(struct dvb_frontend *fe, int onoff);
55
56extern void dib3000mc_set_config(struct dvb_frontend *, struct dib3000mc_config *);
57
58#endif
diff --git a/drivers/media/dvb/frontends/dib3000mc_priv.h b/drivers/media/dvb/frontends/dib3000mc_priv.h
deleted file mode 100644
index 2930aac7591b..000000000000
--- a/drivers/media/dvb/frontends/dib3000mc_priv.h
+++ /dev/null
@@ -1,428 +0,0 @@
1/*
2 * dib3000mc_priv.h
3 *
4 * Copyright (C) 2004 Patrick Boettcher (patrick.boettcher@desy.de)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License as
8 * published by the Free Software Foundation, version 2.
9 *
10 * for more information see dib3000mc.c .
11 */
12
13#ifndef __DIB3000MC_PRIV_H__
14#define __DIB3000MC_PRIV_H__
15
16/*
17 * Demodulator parameters
18 * reg: 0 1 1 1 11 11 111
19 * | | | | | |
20 * | | | | | +-- alpha (000=0, 001=1, 010=2, 100=4)
21 * | | | | +----- constellation (00=QPSK, 01=16QAM, 10=64QAM)
22 * | | | +-------- guard (00=1/32, 01=1/16, 10=1/8, 11=1/4)
23 * | | +----------- transmission mode (0=2k, 1=8k)
24 * | |
25 * | +-------------- restart autosearch for parameters
26 * +---------------- restart the demodulator
27 * reg: 181 1 111 1
28 * | | |
29 * | | +- FEC applies for HP or LP (0=LP, 1=HP)
30 * | +---- FEC rate (001=1/2, 010=2/3, 011=3/4, 101=5/6, 111=7/8)
31 * +------- hierarchy on (0=no, 1=yes)
32 */
33
34/* demodulator tuning parameter and restart options */
35#define DIB3000MC_REG_DEMOD_PARM ( 0)
36#define DIB3000MC_DEMOD_PARM(a,c,g,t) ( \
37 (0x7 & a) | \
38 ((0x3 & c) << 3) | \
39 ((0x3 & g) << 5) | \
40 ((0x1 & t) << 7) )
41#define DIB3000MC_DEMOD_RST_AUTO_SRCH_ON (1 << 8)
42#define DIB3000MC_DEMOD_RST_AUTO_SRCH_OFF (0 << 8)
43#define DIB3000MC_DEMOD_RST_DEMOD_ON (1 << 9)
44#define DIB3000MC_DEMOD_RST_DEMOD_OFF (0 << 9)
45
46/* register for hierarchy parameters */
47#define DIB3000MC_REG_HRCH_PARM ( 181)
48#define DIB3000MC_HRCH_PARM(s,f,h) ( \
49 (0x1 & s) | \
50 ((0x7 & f) << 1) | \
51 ((0x1 & h) << 4) )
52
53/* timeout ??? */
54#define DIB3000MC_REG_UNK_1 ( 1)
55#define DIB3000MC_UNK_1 ( 0x04)
56
57/* timeout ??? */
58#define DIB3000MC_REG_UNK_2 ( 2)
59#define DIB3000MC_UNK_2 ( 0x04)
60
61/* timeout ??? */
62#define DIB3000MC_REG_UNK_3 ( 3)
63#define DIB3000MC_UNK_3 (0x1000)
64
65#define DIB3000MC_REG_UNK_4 ( 4)
66#define DIB3000MC_UNK_4 (0x0814)
67
68/* timeout ??? */
69#define DIB3000MC_REG_SEQ_TPS ( 5)
70#define DIB3000MC_SEQ_TPS_DEFAULT ( 1)
71#define DIB3000MC_SEQ_TPS(s,t) ( \
72 ((s & 0x0f) << 4) | \
73 ((t & 0x01) << 8) )
74#define DIB3000MC_IS_TPS(v) ((v << 8) & 0x1)
75#define DIB3000MC_IS_AS(v) ((v >> 4) & 0xf)
76
77/* parameters for the bandwidth */
78#define DIB3000MC_REG_BW_TIMOUT_MSB ( 6)
79#define DIB3000MC_REG_BW_TIMOUT_LSB ( 7)
80
81static u16 dib3000mc_reg_bandwidth[] = { 6,7,8,9,10,11,16,17 };
82
83/*static u16 dib3000mc_bandwidth_5mhz[] =
84 { 0x28, 0x9380, 0x87, 0x4100, 0x2a4, 0x4500, 0x1, 0xb0d0 };*/
85
86static u16 dib3000mc_bandwidth_6mhz[] =
87 { 0x21, 0xd040, 0x70, 0xb62b, 0x233, 0x8ed5, 0x1, 0xb0d0 };
88
89static u16 dib3000mc_bandwidth_7mhz[] =
90 { 0x1c, 0xfba5, 0x60, 0x9c25, 0x1e3, 0x0cb7, 0x1, 0xb0d0 };
91
92static u16 dib3000mc_bandwidth_8mhz[] =
93 { 0x19, 0x5c30, 0x54, 0x88a0, 0x1a6, 0xab20, 0x1, 0xb0d0 };
94
95static u16 dib3000mc_reg_bandwidth_general[] = { 12,13,14,15 };
96static u16 dib3000mc_bandwidth_general[] = { 0x0000, 0x03e8, 0x0000, 0x03f2 };
97
98/* lock mask */
99#define DIB3000MC_REG_LOCK_MASK ( 15)
100#define DIB3000MC_ACTIVATE_LOCK_MASK (0x0800)
101
102/* reset the uncorrected packet count (??? do it 5 times) */
103#define DIB3000MC_REG_RST_UNC ( 18)
104#define DIB3000MC_RST_UNC_ON ( 1)
105#define DIB3000MC_RST_UNC_OFF ( 0)
106
107#define DIB3000MC_REG_UNK_19 ( 19)
108#define DIB3000MC_UNK_19 ( 0)
109
110/* DDS frequency value (IF position) and inversion bit */
111#define DIB3000MC_REG_INVERSION ( 21)
112#define DIB3000MC_REG_SET_DDS_FREQ_MSB ( 21)
113#define DIB3000MC_DDS_FREQ_MSB_INV_OFF (0x0164)
114#define DIB3000MC_DDS_FREQ_MSB_INV_ON (0x0364)
115
116#define DIB3000MC_REG_SET_DDS_FREQ_LSB ( 22)
117#define DIB3000MC_DDS_FREQ_LSB (0x463d)
118
119/* timing frequencies setting */
120#define DIB3000MC_REG_TIMING_FREQ_MSB ( 23)
121#define DIB3000MC_REG_TIMING_FREQ_LSB ( 24)
122#define DIB3000MC_CLOCK_REF (0x151fd1)
123
124//static u16 dib3000mc_reg_timing_freq[] = { 23,24 };
125
126//static u16 dib3000mc_timing_freq[][2] = {
127// { 0x69, 0x9f18 }, /* 5 MHz */
128// { 0x7e ,0xbee9 }, /* 6 MHz */
129// { 0x93 ,0xdebb }, /* 7 MHz */
130// { 0xa8 ,0xfe8c }, /* 8 MHz */
131//};
132
133/* timeout ??? */
134static u16 dib3000mc_reg_offset[] = { 26,33 };
135
136static u16 dib3000mc_offset[][2] = {
137 { 26240, 5 }, /* default */
138 { 30336, 6 }, /* 8K */
139 { 38528, 8 }, /* 2K */
140};
141
142#define DIB3000MC_REG_ISI ( 29)
143#define DIB3000MC_ISI_DEFAULT (0x1073)
144#define DIB3000MC_ISI_ACTIVATE (0x0000)
145#define DIB3000MC_ISI_INHIBIT (0x0200)
146
147/* impulse noise control */
148static u16 dib3000mc_reg_imp_noise_ctl[] = { 34,35 };
149
150static u16 dib3000mc_imp_noise_ctl[][2] = {
151 { 0x1294, 0x1ff8 }, /* mode 0 */
152 { 0x1294, 0x1ff8 }, /* mode 1 */
153 { 0x1294, 0x1ff8 }, /* mode 2 */
154 { 0x1294, 0x1ff8 }, /* mode 3 */
155 { 0x1294, 0x1ff8 }, /* mode 4 */
156};
157
158/* AGC registers */
159static u16 dib3000mc_reg_agc[] = {
160 36,37,38,39,42,43,44,45,46,47,48,49
161};
162
163static u16 dib3000mc_agc_tuner[][12] = {
164 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xcf5c, 0x6666,
165 0xbae1, 0xa148, 0x3b5e, 0x3c1c, 0x001a, 0x2019
166 }, /* TUNER_PANASONIC_ENV77H04D5, */
167
168 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xdc29, 0x570a,
169 0xbae1, 0x8ccd, 0x3b6d, 0x551d, 0x000a, 0x951e
170 }, /* TUNER_PANASONIC_ENV57H13D5, TUNER_PANASONIC_ENV57H12D5 */
171
172 { 0x0051, 0x301d, 0x0000, 0x1cc7, 0xffff, 0xffff,
173 0xffff, 0x0000, 0xfdfd, 0x4040, 0x00fd, 0x4040
174 }, /* TUNER_SAMSUNG_DTOS333IH102, TUNER_RFAGCIN_UNKNOWN */
175
176 { 0x0196, 0x301d, 0x0000, 0x1cc7, 0xbd71, 0x5c29,
177 0xb5c3, 0x6148, 0x6569, 0x5127, 0x0033, 0x3537
178 }, /* TUNER_PROVIDER_X */
179 /* TODO TUNER_PANASONIC_ENV57H10D8, TUNER_PANASONIC_ENV57H11D8 */
180};
181
182/* AGC loop bandwidth */
183static u16 dib3000mc_reg_agc_bandwidth[] = { 40,41 };
184static u16 dib3000mc_agc_bandwidth[] = { 0x119,0x330 };
185
186static u16 dib3000mc_reg_agc_bandwidth_general[] = { 50,51,52,53,54 };
187static u16 dib3000mc_agc_bandwidth_general[] =
188 { 0x8000, 0x91ca, 0x01ba, 0x0087, 0x0087 };
189
190#define DIB3000MC_REG_IMP_NOISE_55 ( 55)
191#define DIB3000MC_IMP_NEW_ALGO(w) (w | (1<<10))
192
193/* Impulse noise params */
194static u16 dib3000mc_reg_impulse_noise[] = { 55,56,57 };
195static u16 dib3000mc_impluse_noise[][3] = {
196 { 0x489, 0x89, 0x72 }, /* 5 MHz */
197 { 0x4a5, 0xa5, 0x89 }, /* 6 MHz */
198 { 0x4c0, 0xc0, 0xa0 }, /* 7 MHz */
199 { 0x4db, 0xdb, 0xb7 }, /* 8 Mhz */
200};
201
202static u16 dib3000mc_reg_fft[] = {
203 58,59,60,61,62,63,64,65,66,67,68,69,
204 70,71,72,73,74,75,76,77,78,79,80,81,
205 82,83,84,85,86
206};
207
208static u16 dib3000mc_fft_modes[][29] = {
209 { 0x38, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c,
210 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d,
211 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3,
212 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c,
213 0x3ffe, 0x5b3, 0x3feb, 0x76, 0x0, 0xd
214 }, /* fft mode 0 */
215 { 0x3b, 0x6d9, 0x3f28, 0x7a7, 0x3a74, 0x196, 0x32a, 0x48c,
216 0x3ffe, 0x7f3, 0x2d94, 0x76, 0x53d,
217 0x3ff8, 0x7e3, 0x3320, 0x76, 0x5b3,
218 0x3feb, 0x7d2, 0x365e, 0x76, 0x48c,
219 0x3ffe, 0x5b3, 0x3feb, 0x0, 0x8200, 0xd
220 }, /* fft mode 1 */
221};
222
223#define DIB3000MC_REG_UNK_88 ( 88)
224#define DIB3000MC_UNK_88 (0x0410)
225
226static u16 dib3000mc_reg_bw[] = { 93,94,95,96,97,98 };
227static u16 dib3000mc_bw[][6] = {
228 { 0,0,0,0,0,0 }, /* 5 MHz */
229 { 0,0,0,0,0,0 }, /* 6 MHz */
230 { 0,0,0,0,0,0 }, /* 7 MHz */
231 { 0x20, 0x21, 0x20, 0x23, 0x20, 0x27 }, /* 8 MHz */
232};
233
234
235/* phase noise control */
236#define DIB3000MC_REG_UNK_99 ( 99)
237#define DIB3000MC_UNK_99 (0x0220)
238
239#define DIB3000MC_REG_SCAN_BOOST ( 100)
240#define DIB3000MC_SCAN_BOOST_ON ((11 << 6) + 6)
241#define DIB3000MC_SCAN_BOOST_OFF ((16 << 6) + 9)
242
243/* timeout ??? */
244#define DIB3000MC_REG_UNK_110 ( 110)
245#define DIB3000MC_UNK_110 ( 3277)
246
247#define DIB3000MC_REG_UNK_111 ( 111)
248#define DIB3000MC_UNK_111_PH_N_MODE_0 ( 0)
249#define DIB3000MC_UNK_111_PH_N_MODE_1 (1 << 1)
250
251/* superious rm config */
252#define DIB3000MC_REG_UNK_120 ( 120)
253#define DIB3000MC_UNK_120 ( 8207)
254
255#define DIB3000MC_REG_UNK_133 ( 133)
256#define DIB3000MC_UNK_133 ( 15564)
257
258#define DIB3000MC_REG_UNK_134 ( 134)
259#define DIB3000MC_UNK_134 ( 0)
260
261/* adapter config for constellation */
262static u16 dib3000mc_reg_adp_cfg[] = { 129, 130, 131, 132 };
263
264static u16 dib3000mc_adp_cfg[][4] = {
265 { 0x99a, 0x7fae, 0x333, 0x7ff0 }, /* QPSK */
266 { 0x23d, 0x7fdf, 0x0a4, 0x7ff0 }, /* 16-QAM */
267 { 0x148, 0x7ff0, 0x0a4, 0x7ff8 }, /* 64-QAM */
268};
269
270static u16 dib3000mc_reg_mobile_mode[] = { 139, 140, 141, 175, 1032 };
271
272static u16 dib3000mc_mobile_mode[][5] = {
273 { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* fixed */
274 { 0x01, 0x0, 0x0, 0x00, 0x12c }, /* portable */
275 { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* mobile */
276 { 0x00, 0x0, 0x0, 0x02, 0x000 }, /* auto */
277};
278
279#define DIB3000MC_REG_DIVERSITY1 ( 177)
280#define DIB3000MC_DIVERSITY1_DEFAULT ( 1)
281
282#define DIB3000MC_REG_DIVERSITY2 ( 178)
283#define DIB3000MC_DIVERSITY2_DEFAULT ( 1)
284
285#define DIB3000MC_REG_DIVERSITY3 ( 180)
286#define DIB3000MC_DIVERSITY3_IN_OFF (0xfff0)
287#define DIB3000MC_DIVERSITY3_IN_ON (0xfff6)
288
289#define DIB3000MC_REG_FEC_CFG ( 195)
290#define DIB3000MC_FEC_CFG ( 0x10)
291
292/*
293 * reg 206, output mode
294 * 1111 1111
295 * |||| ||||
296 * |||| |||+- unk
297 * |||| ||+-- unk
298 * |||| |+--- unk (on by default)
299 * |||| +---- fifo_ctrl (1 = inhibit (flushed), 0 = active (unflushed))
300 * |||+------ pid_parse (1 = enabled, 0 = disabled)
301 * ||+------- outp_188 (1 = TS packet size 188, 0 = packet size 204)
302 * |+-------- unk
303 * +--------- unk
304 */
305
306#define DIB3000MC_REG_SMO_MODE ( 206)
307#define DIB3000MC_SMO_MODE_DEFAULT (1 << 2)
308#define DIB3000MC_SMO_MODE_FIFO_FLUSH (1 << 3)
309#define DIB3000MC_SMO_MODE_FIFO_UNFLUSH (0xfff7)
310#define DIB3000MC_SMO_MODE_PID_PARSE (1 << 4)
311#define DIB3000MC_SMO_MODE_NO_PID_PARSE (0xffef)
312#define DIB3000MC_SMO_MODE_188 (1 << 5)
313#define DIB3000MC_SMO_MODE_SLAVE (DIB3000MC_SMO_MODE_DEFAULT | \
314 DIB3000MC_SMO_MODE_188 | DIB3000MC_SMO_MODE_PID_PARSE | (1<<1))
315
316#define DIB3000MC_REG_FIFO_THRESHOLD ( 207)
317#define DIB3000MC_FIFO_THRESHOLD_DEFAULT ( 1792)
318#define DIB3000MC_FIFO_THRESHOLD_SLAVE ( 512)
319/*
320 * pidfilter
321 * it is not a hardware pidfilter but a filter which drops all pids
322 * except the ones set. When connected to USB1.1 bandwidth this is important.
323 * DiB3000P/M-C can filter up to 32 PIDs
324 */
325#define DIB3000MC_REG_FIRST_PID ( 212)
326#define DIB3000MC_NUM_PIDS ( 32)
327
328#define DIB3000MC_REG_OUTMODE ( 244)
329#define DIB3000MC_OM_PARALLEL_GATED_CLK ( 0)
330#define DIB3000MC_OM_PAR_CONT_CLK (1 << 11)
331#define DIB3000MC_OM_SERIAL (2 << 11)
332#define DIB3000MC_OM_DIVOUT_ON (4 << 11)
333#define DIB3000MC_OM_SLAVE (DIB3000MC_OM_DIVOUT_ON | DIB3000MC_OM_PAR_CONT_CLK)
334
335#define DIB3000MC_REG_RF_POWER ( 392)
336
337#define DIB3000MC_REG_FFT_POSITION ( 407)
338
339#define DIB3000MC_REG_DDS_FREQ_MSB ( 414)
340#define DIB3000MC_REG_DDS_FREQ_LSB ( 415)
341
342#define DIB3000MC_REG_TIMING_OFFS_MSB ( 416)
343#define DIB3000MC_REG_TIMING_OFFS_LSB ( 417)
344
345#define DIB3000MC_REG_TUNING_PARM ( 458)
346#define DIB3000MC_TP_QAM(v) ((v >> 13) & 0x03)
347#define DIB3000MC_TP_HRCH(v) ((v >> 12) & 0x01)
348#define DIB3000MC_TP_ALPHA(v) ((v >> 9) & 0x07)
349#define DIB3000MC_TP_FFT(v) ((v >> 8) & 0x01)
350#define DIB3000MC_TP_FEC_CR_HP(v) ((v >> 5) & 0x07)
351#define DIB3000MC_TP_FEC_CR_LP(v) ((v >> 2) & 0x07)
352#define DIB3000MC_TP_GUARD(v) (v & 0x03)
353
354#define DIB3000MC_REG_SIGNAL_NOISE_MSB ( 483)
355#define DIB3000MC_REG_SIGNAL_NOISE_LSB ( 484)
356
357#define DIB3000MC_REG_MER ( 485)
358
359#define DIB3000MC_REG_BER_MSB ( 500)
360#define DIB3000MC_REG_BER_LSB ( 501)
361
362#define DIB3000MC_REG_PACKET_ERRORS ( 503)
363
364#define DIB3000MC_REG_PACKET_ERROR_COUNT ( 506)
365
366#define DIB3000MC_REG_LOCK_507 ( 507)
367#define DIB3000MC_LOCK_507 (0x0002) // ? name correct ?
368
369#define DIB3000MC_REG_LOCKING ( 509)
370#define DIB3000MC_AGC_LOCK(v) (v & 0x8000)
371#define DIB3000MC_CARRIER_LOCK(v) (v & 0x2000)
372#define DIB3000MC_MPEG_SYNC_LOCK(v) (v & 0x0080)
373#define DIB3000MC_MPEG_DATA_LOCK(v) (v & 0x0040)
374#define DIB3000MC_TPS_LOCK(v) (v & 0x0004)
375
376#define DIB3000MC_REG_AS_IRQ ( 511)
377#define DIB3000MC_AS_IRQ_SUCCESS (1 << 1)
378#define DIB3000MC_AS_IRQ_FAIL ( 1)
379
380#define DIB3000MC_REG_TUNER ( 769)
381
382#define DIB3000MC_REG_RST_I2C_ADDR ( 1024)
383#define DIB3000MC_DEMOD_ADDR_ON ( 1)
384#define DIB3000MC_DEMOD_ADDR(a) ((a << 4) & 0x03F0)
385
386#define DIB3000MC_REG_RESTART ( 1027)
387#define DIB3000MC_RESTART_OFF (0x0000)
388#define DIB3000MC_RESTART_AGC (0x0800)
389#define DIB3000MC_RESTART_CONFIG (0x8000)
390
391#define DIB3000MC_REG_RESTART_VIT ( 1028)
392#define DIB3000MC_RESTART_VIT_OFF ( 0)
393#define DIB3000MC_RESTART_VIT_ON ( 1)
394
395#define DIB3000MC_REG_CLK_CFG_1 ( 1031)
396#define DIB3000MC_CLK_CFG_1_POWER_UP ( 0)
397#define DIB3000MC_CLK_CFG_1_POWER_DOWN (0xffff)
398
399#define DIB3000MC_REG_CLK_CFG_2 ( 1032)
400#define DIB3000MC_CLK_CFG_2_PUP_FIXED (0x012c)
401#define DIB3000MC_CLK_CFG_2_PUP_PORT (0x0104)
402#define DIB3000MC_CLK_CFG_2_PUP_MOBILE (0x0000)
403#define DIB3000MC_CLK_CFG_2_POWER_DOWN (0xffff)
404
405#define DIB3000MC_REG_CLK_CFG_3 ( 1033)
406#define DIB3000MC_CLK_CFG_3_POWER_UP ( 0)
407#define DIB3000MC_CLK_CFG_3_POWER_DOWN (0xfff5)
408
409#define DIB3000MC_REG_CLK_CFG_7 ( 1037)
410#define DIB3000MC_CLK_CFG_7_INIT ( 12592)
411#define DIB3000MC_CLK_CFG_7_POWER_UP (~0x0003)
412#define DIB3000MC_CLK_CFG_7_PWR_DOWN (0x0003)
413#define DIB3000MC_CLK_CFG_7_DIV_IN_OFF (1 << 8)
414
415/* was commented out ??? */
416#define DIB3000MC_REG_CLK_CFG_8 ( 1038)
417#define DIB3000MC_CLK_CFG_8_POWER_UP (0x160c)
418
419#define DIB3000MC_REG_CLK_CFG_9 ( 1039)
420#define DIB3000MC_CLK_CFG_9_POWER_UP ( 0)
421
422/* also clock ??? */
423#define DIB3000MC_REG_ELEC_OUT ( 1040)
424#define DIB3000MC_ELEC_OUT_HIGH_Z ( 0)
425#define DIB3000MC_ELEC_OUT_DIV_OUT_ON ( 1)
426#define DIB3000MC_ELEC_OUT_SLAVE ( 3)
427
428#endif
diff --git a/drivers/media/dvb/frontends/dibx000_common.c b/drivers/media/dvb/frontends/dibx000_common.c
new file mode 100644
index 000000000000..a18c8f45a2ee
--- /dev/null
+++ b/drivers/media/dvb/frontends/dibx000_common.c
@@ -0,0 +1,152 @@
1#include <linux/i2c.h>
2
3#include "dibx000_common.h"
4
5static int debug;
6module_param(debug, int, 0644);
7MODULE_PARM_DESC(debug, "turn on debugging (default: 0)");
8
9#define dprintk(args...) do { if (debug) { printk(KERN_DEBUG "DiBX000: "); printk(args); } } while (0)
10
11static int dibx000_write_word(struct dibx000_i2c_master *mst, u16 reg, u16 val)
12{
13 u8 b[4] = {
14 (reg >> 8) & 0xff, reg & 0xff,
15 (val >> 8) & 0xff, val & 0xff,
16 };
17 struct i2c_msg msg = {
18 .addr = mst->i2c_addr, .flags = 0, .buf = b, .len = 4
19 };
20 return i2c_transfer(mst->i2c_adap, &msg, 1) != 1 ? -EREMOTEIO : 0;
21}
22
23
24static int dibx000_i2c_select_interface(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf)
25{
26 if (mst->device_rev > DIB3000MC && mst->selected_interface != intf) {
27 dprintk("selecting interface: %d\n",intf);
28 mst->selected_interface = intf;
29 return dibx000_write_word(mst, mst->base_reg + 4, intf);
30 }
31 return 0;
32}
33
34static int dibx000_i2c_gate_ctrl(struct dibx000_i2c_master *mst, u8 tx[4], u8 addr, int onoff)
35{
36 u16 val;
37
38
39 if (onoff)
40 val = addr << 8; // bit 7 = use master or not, if 0, the gate is open
41 else
42 val = 1 << 7;
43
44 if (mst->device_rev > DIB7000)
45 val <<= 1;
46
47 tx[0] = (((mst->base_reg + 1) >> 8) & 0xff);
48 tx[1] = ( (mst->base_reg + 1) & 0xff);
49 tx[2] = val >> 8;
50 tx[3] = val & 0xff;
51
52 return 0;
53}
54
55static u32 dibx000_i2c_func(struct i2c_adapter *adapter)
56{
57 return I2C_FUNC_I2C;
58}
59
60static int dibx000_i2c_gated_tuner_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg msg[], int num)
61{
62 struct dibx000_i2c_master *mst = i2c_get_adapdata(i2c_adap);
63 struct i2c_msg m[2 + num];
64 u8 tx_open[4], tx_close[4];
65
66 memset(m,0, sizeof(struct i2c_msg) * (2 + num));
67
68 dibx000_i2c_select_interface(mst, DIBX000_I2C_INTERFACE_TUNER);
69
70 dibx000_i2c_gate_ctrl(mst, tx_open, msg[0].addr, 1);
71 m[0].addr = mst->i2c_addr;
72 m[0].buf = tx_open;
73 m[0].len = 4;
74
75 memcpy(&m[1], msg, sizeof(struct i2c_msg) * num);
76
77 dibx000_i2c_gate_ctrl(mst, tx_close, 0, 0);
78 m[num+1].addr = mst->i2c_addr;
79 m[num+1].buf = tx_close;
80 m[num+1].len = 4;
81
82 return i2c_transfer(mst->i2c_adap, m, 2+num) == 2 + num ? num : -EIO;
83}
84
85static struct i2c_algorithm dibx000_i2c_gated_tuner_algo = {
86 .master_xfer = dibx000_i2c_gated_tuner_xfer,
87 .functionality = dibx000_i2c_func,
88};
89
90struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating)
91{
92 struct i2c_adapter *i2c = NULL;
93
94 switch (intf) {
95 case DIBX000_I2C_INTERFACE_TUNER:
96 if (gating)
97 i2c = &mst->gated_tuner_i2c_adap;
98 break;
99 default:
100 printk(KERN_ERR "DiBX000: incorrect I2C interface selected\n");
101 break;
102 }
103
104 return i2c;
105}
106EXPORT_SYMBOL(dibx000_get_i2c_adapter);
107
108static int i2c_adapter_init(struct i2c_adapter *i2c_adap, struct i2c_algorithm *algo, const char name[I2C_NAME_SIZE], struct dibx000_i2c_master *mst)
109{
110 strncpy(i2c_adap->name, name, I2C_NAME_SIZE);
111 i2c_adap->class = I2C_CLASS_TV_DIGITAL,
112 i2c_adap->algo = algo;
113 i2c_adap->algo_data = NULL;
114 i2c_set_adapdata(i2c_adap, mst);
115 if (i2c_add_adapter(i2c_adap) < 0)
116 return -ENODEV;
117 return 0;
118}
119
120int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr)
121{
122 u8 tx[4];
123 struct i2c_msg m = { .addr = i2c_addr >> 1, .buf = tx, .len = 4 };
124
125 mst->device_rev = device_rev;
126 mst->i2c_adap = i2c_adap;
127 mst->i2c_addr = i2c_addr >> 1;
128
129 if (device_rev == DIB7000P)
130 mst->base_reg = 1024;
131 else
132 mst->base_reg = 768;
133
134 if (i2c_adapter_init(&mst->gated_tuner_i2c_adap, &dibx000_i2c_gated_tuner_algo, "DiBX000 tuner I2C bus", mst) != 0)
135 printk(KERN_ERR "DiBX000: could not initialize the tuner i2c_adapter\n");
136
137 /* initialize the i2c-master by closing the gate */
138 dibx000_i2c_gate_ctrl(mst, tx, 0, 0);
139
140 return i2c_transfer(i2c_adap, &m, 1) == 1;
141}
142EXPORT_SYMBOL(dibx000_init_i2c_master);
143
144void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst)
145{
146 i2c_del_adapter(&mst->gated_tuner_i2c_adap);
147}
148EXPORT_SYMBOL(dibx000_exit_i2c_master);
149
150MODULE_AUTHOR("Patrick Boettcher <pboettcher@dibcom.fr>");
151MODULE_DESCRIPTION("Common function the DiBcom demodulator family");
152MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/dibx000_common.h b/drivers/media/dvb/frontends/dibx000_common.h
new file mode 100644
index 000000000000..bb0c65f8aee8
--- /dev/null
+++ b/drivers/media/dvb/frontends/dibx000_common.h
@@ -0,0 +1,166 @@
1#ifndef DIBX000_COMMON_H
2#define DIBX000_COMMON_H
3
4enum dibx000_i2c_interface {
5 DIBX000_I2C_INTERFACE_TUNER = 0,
6 DIBX000_I2C_INTERFACE_GPIO_1_2 = 1,
7 DIBX000_I2C_INTERFACE_GPIO_3_4 = 2
8};
9
10struct dibx000_i2c_master {
11#define DIB3000MC 1
12#define DIB7000 2
13#define DIB7000P 11
14#define DIB7000MC 12
15 u16 device_rev;
16
17 enum dibx000_i2c_interface selected_interface;
18
19// struct i2c_adapter tuner_i2c_adap;
20 struct i2c_adapter gated_tuner_i2c_adap;
21
22 struct i2c_adapter *i2c_adap;
23 u8 i2c_addr;
24
25 u16 base_reg;
26};
27
28extern int dibx000_init_i2c_master(struct dibx000_i2c_master *mst, u16 device_rev, struct i2c_adapter *i2c_adap, u8 i2c_addr);
29extern struct i2c_adapter * dibx000_get_i2c_adapter(struct dibx000_i2c_master *mst, enum dibx000_i2c_interface intf, int gating);
30extern void dibx000_exit_i2c_master(struct dibx000_i2c_master *mst);
31
32#define BAND_LBAND 0x01
33#define BAND_UHF 0x02
34#define BAND_VHF 0x04
35
36struct dibx000_agc_config {
37 /* defines the capabilities of this AGC-setting - using the BAND_-defines*/
38 u8 band_caps;
39
40 u16 setup;
41
42 u16 inv_gain;
43 u16 time_stabiliz;
44
45 u8 alpha_level;
46 u16 thlock;
47
48 u8 wbd_inv;
49 u16 wbd_ref;
50 u8 wbd_sel;
51 u8 wbd_alpha;
52
53 u16 agc1_max;
54 u16 agc1_min;
55 u16 agc2_max;
56 u16 agc2_min;
57
58 u8 agc1_pt1;
59 u8 agc1_pt2;
60 u8 agc1_pt3;
61
62 u8 agc1_slope1;
63 u8 agc1_slope2;
64
65 u8 agc2_pt1;
66 u8 agc2_pt2;
67
68 u8 agc2_slope1;
69 u8 agc2_slope2;
70
71 u8 alpha_mant;
72 u8 alpha_exp;
73
74 u8 beta_mant;
75 u8 beta_exp;
76
77 u8 perform_agc_softsplit;
78
79 struct {
80 u16 min;
81 u16 max;
82 u16 min_thres;
83 u16 max_thres;
84 } split;
85};
86
87struct dibx000_bandwidth_config {
88 u32 internal;
89 u32 sampling;
90
91 u8 pll_prediv;
92 u8 pll_ratio;
93 u8 pll_range;
94 u8 pll_reset;
95 u8 pll_bypass;
96
97 u8 enable_refdiv;
98 u8 bypclk_div;
99 u8 IO_CLK_en_core;
100 u8 ADClkSrc;
101 u8 modulo;
102
103 u16 sad_cfg;
104
105 u32 ifreq;
106 u32 timf;
107};
108
109enum dibx000_adc_states {
110 DIBX000_SLOW_ADC_ON = 0,
111 DIBX000_SLOW_ADC_OFF,
112 DIBX000_ADC_ON,
113 DIBX000_ADC_OFF,
114 DIBX000_VBG_ENABLE,
115 DIBX000_VBG_DISABLE,
116};
117
118#define BW_INDEX_TO_KHZ(v) ( (v) == BANDWIDTH_8_MHZ ? 8000 : \
119 (v) == BANDWIDTH_7_MHZ ? 7000 : \
120 (v) == BANDWIDTH_6_MHZ ? 6000 : 8000 )
121
122/* Chip output mode. */
123#define OUTMODE_HIGH_Z 0
124#define OUTMODE_MPEG2_PAR_GATED_CLK 1
125#define OUTMODE_MPEG2_PAR_CONT_CLK 2
126#define OUTMODE_MPEG2_SERIAL 7
127#define OUTMODE_DIVERSITY 4
128#define OUTMODE_MPEG2_FIFO 5
129
130/* I hope I can get rid of the following kludge in the near future */
131struct dibx000_ofdm_channel {
132 u8 Bw;
133 s16 nfft;
134 s16 guard;
135 s16 nqam;
136 s16 vit_hrch;
137 s16 vit_select_hp;
138 s16 vit_alpha;
139 s16 vit_code_rate_hp;
140 s16 vit_code_rate_lp;
141};
142
143#define FEP2DIB(fep,ch) \
144 (ch)->Bw = (fep)->u.ofdm.bandwidth; \
145 (ch)->nfft = (fep)->u.ofdm.transmission_mode == TRANSMISSION_MODE_AUTO ? -1 : (fep)->u.ofdm.transmission_mode; \
146 (ch)->guard = (fep)->u.ofdm.guard_interval == GUARD_INTERVAL_AUTO ? -1 : (fep)->u.ofdm.guard_interval; \
147 (ch)->nqam = (fep)->u.ofdm.constellation == QAM_AUTO ? -1 : (fep)->u.ofdm.constellation == QAM_64 ? 2 : (fep)->u.ofdm.constellation; \
148 (ch)->vit_hrch = 0; /* linux-dvb is not prepared for HIERARCHICAL TRANSMISSION */ \
149 (ch)->vit_select_hp = 1; \
150 (ch)->vit_alpha = 1; \
151 (ch)->vit_code_rate_hp = (fep)->u.ofdm.code_rate_HP == FEC_AUTO ? -1 : (fep)->u.ofdm.code_rate_HP; \
152 (ch)->vit_code_rate_lp = (fep)->u.ofdm.code_rate_LP == FEC_AUTO ? -1 : (fep)->u.ofdm.code_rate_LP;
153
154#define INIT_OFDM_CHANNEL(ch) do {\
155 (ch)->Bw = 0; \
156 (ch)->nfft = -1; \
157 (ch)->guard = -1; \
158 (ch)->nqam = -1; \
159 (ch)->vit_hrch = -1; \
160 (ch)->vit_select_hp = -1; \
161 (ch)->vit_alpha = -1; \
162 (ch)->vit_code_rate_hp = -1; \
163 (ch)->vit_code_rate_lp = -1; \
164} while (0)
165
166#endif
diff --git a/drivers/media/dvb/frontends/dvb-pll.c b/drivers/media/dvb/frontends/dvb-pll.c
index 2be33f27c69f..b7e7108ee5b3 100644
--- a/drivers/media/dvb/frontends/dvb-pll.c
+++ b/drivers/media/dvb/frontends/dvb-pll.c
@@ -493,6 +493,9 @@ static int dvb_pll_sleep(struct dvb_frontend *fe)
493 int i; 493 int i;
494 int result; 494 int result;
495 495
496 if (priv->i2c == NULL)
497 return -EINVAL;
498
496 for (i = 0; i < priv->pll_desc->count; i++) { 499 for (i = 0; i < priv->pll_desc->count; i++) {
497 if (priv->pll_desc->entries[i].limit == 0) 500 if (priv->pll_desc->entries[i].limit == 0)
498 break; 501 break;
@@ -611,7 +614,7 @@ static struct dvb_tuner_ops dvb_pll_tuner_ops = {
611 .get_bandwidth = dvb_pll_get_bandwidth, 614 .get_bandwidth = dvb_pll_get_bandwidth,
612}; 615};
613 616
614int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc) 617struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc)
615{ 618{
616 u8 b1 [] = { 0 }; 619 u8 b1 [] = { 0 };
617 struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 }; 620 struct i2c_msg msg = { .addr = pll_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 };
@@ -624,14 +627,14 @@ int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2
624 627
625 ret = i2c_transfer (i2c, &msg, 1); 628 ret = i2c_transfer (i2c, &msg, 1);
626 if (ret != 1) 629 if (ret != 1)
627 return -1; 630 return NULL;
628 if (fe->ops.i2c_gate_ctrl) 631 if (fe->ops.i2c_gate_ctrl)
629 fe->ops.i2c_gate_ctrl(fe, 0); 632 fe->ops.i2c_gate_ctrl(fe, 0);
630 } 633 }
631 634
632 priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL); 635 priv = kzalloc(sizeof(struct dvb_pll_priv), GFP_KERNEL);
633 if (priv == NULL) 636 if (priv == NULL)
634 return -ENOMEM; 637 return NULL;
635 638
636 priv->pll_i2c_address = pll_addr; 639 priv->pll_i2c_address = pll_addr;
637 priv->i2c = i2c; 640 priv->i2c = i2c;
@@ -643,7 +646,7 @@ int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2
643 fe->ops.tuner_ops.info.frequency_min = desc->max; 646 fe->ops.tuner_ops.info.frequency_min = desc->max;
644 647
645 fe->tuner_priv = priv; 648 fe->tuner_priv = priv;
646 return 0; 649 return fe;
647} 650}
648EXPORT_SYMBOL(dvb_pll_attach); 651EXPORT_SYMBOL(dvb_pll_attach);
649 652
diff --git a/drivers/media/dvb/frontends/dvb-pll.h b/drivers/media/dvb/frontends/dvb-pll.h
index 66361cd18807..ed5ac5a361ae 100644
--- a/drivers/media/dvb/frontends/dvb-pll.h
+++ b/drivers/media/dvb/frontends/dvb-pll.h
@@ -57,8 +57,8 @@ extern int dvb_pll_configure(struct dvb_pll_desc *desc, u8 *buf,
57 * @param pll_addr i2c address of the PLL (if used). 57 * @param pll_addr i2c address of the PLL (if used).
58 * @param i2c i2c adapter to use (set to NULL if not used). 58 * @param i2c i2c adapter to use (set to NULL if not used).
59 * @param desc dvb_pll_desc to use. 59 * @param desc dvb_pll_desc to use.
60 * @return 0 on success, nonzero on failure. 60 * @return Frontend pointer on success, NULL on failure
61 */ 61 */
62extern int dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc); 62extern struct dvb_frontend *dvb_pll_attach(struct dvb_frontend *fe, int pll_addr, struct i2c_adapter *i2c, struct dvb_pll_desc *desc);
63 63
64#endif 64#endif
diff --git a/drivers/media/dvb/frontends/isl6421.c b/drivers/media/dvb/frontends/isl6421.c
index 58c34db31071..ef319369ec26 100644
--- a/drivers/media/dvb/frontends/isl6421.c
+++ b/drivers/media/dvb/frontends/isl6421.c
@@ -42,12 +42,11 @@ struct isl6421 {
42 u8 override_and; 42 u8 override_and;
43 struct i2c_adapter *i2c; 43 struct i2c_adapter *i2c;
44 u8 i2c_addr; 44 u8 i2c_addr;
45 void (*release_chain)(struct dvb_frontend* fe);
46}; 45};
47 46
48static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 47static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
49{ 48{
50 struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; 49 struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
51 struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, 50 struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
52 .buf = &isl6421->config, 51 .buf = &isl6421->config,
53 .len = sizeof(isl6421->config) }; 52 .len = sizeof(isl6421->config) };
@@ -75,7 +74,7 @@ static int isl6421_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage
75 74
76static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) 75static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
77{ 76{
78 struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv; 77 struct isl6421 *isl6421 = (struct isl6421 *) fe->sec_priv;
79 struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0, 78 struct i2c_msg msg = { .addr = isl6421->i2c_addr, .flags = 0,
80 .buf = &isl6421->config, 79 .buf = &isl6421->config,
81 .len = sizeof(isl6421->config) }; 80 .len = sizeof(isl6421->config) };
@@ -93,31 +92,26 @@ static int isl6421_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
93 92
94static void isl6421_release(struct dvb_frontend *fe) 93static void isl6421_release(struct dvb_frontend *fe)
95{ 94{
96 struct isl6421 *isl6421 = (struct isl6421 *) fe->misc_priv;
97
98 /* power off */ 95 /* power off */
99 isl6421_set_voltage(fe, SEC_VOLTAGE_OFF); 96 isl6421_set_voltage(fe, SEC_VOLTAGE_OFF);
100 97
101 /* free data & call next release routine */ 98 /* free */
102 fe->ops.release = isl6421->release_chain; 99 kfree(fe->sec_priv);
103 kfree(fe->misc_priv); 100 fe->sec_priv = NULL;
104 fe->misc_priv = NULL;
105 if (fe->ops.release)
106 fe->ops.release(fe);
107} 101}
108 102
109int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, 103struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
110 u8 override_set, u8 override_clear) 104 u8 override_set, u8 override_clear)
111{ 105{
112 struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL); 106 struct isl6421 *isl6421 = kmalloc(sizeof(struct isl6421), GFP_KERNEL);
113 if (!isl6421) 107 if (!isl6421)
114 return -ENOMEM; 108 return NULL;
115 109
116 /* default configuration */ 110 /* default configuration */
117 isl6421->config = ISL6421_ISEL1; 111 isl6421->config = ISL6421_ISEL1;
118 isl6421->i2c = i2c; 112 isl6421->i2c = i2c;
119 isl6421->i2c_addr = i2c_addr; 113 isl6421->i2c_addr = i2c_addr;
120 fe->misc_priv = isl6421; 114 fe->sec_priv = isl6421;
121 115
122 /* bits which should be forced to '1' */ 116 /* bits which should be forced to '1' */
123 isl6421->override_or = override_set; 117 isl6421->override_or = override_set;
@@ -128,19 +122,17 @@ int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr
128 /* detect if it is present or not */ 122 /* detect if it is present or not */
129 if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) { 123 if (isl6421_set_voltage(fe, SEC_VOLTAGE_OFF)) {
130 kfree(isl6421); 124 kfree(isl6421);
131 fe->misc_priv = NULL; 125 return NULL;
132 return -EIO;
133 } 126 }
134 127
135 /* install release callback */ 128 /* install release callback */
136 isl6421->release_chain = fe->ops.release; 129 fe->ops.release_sec = isl6421_release;
137 fe->ops.release = isl6421_release;
138 130
139 /* override frontend ops */ 131 /* override frontend ops */
140 fe->ops.set_voltage = isl6421_set_voltage; 132 fe->ops.set_voltage = isl6421_set_voltage;
141 fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage; 133 fe->ops.enable_high_lnb_voltage = isl6421_enable_high_lnb_voltage;
142 134
143 return 0; 135 return fe;
144} 136}
145EXPORT_SYMBOL(isl6421_attach); 137EXPORT_SYMBOL(isl6421_attach);
146 138
diff --git a/drivers/media/dvb/frontends/isl6421.h b/drivers/media/dvb/frontends/isl6421.h
index 675f80a19b99..1916e3eb2df3 100644
--- a/drivers/media/dvb/frontends/isl6421.h
+++ b/drivers/media/dvb/frontends/isl6421.h
@@ -39,8 +39,17 @@
39#define ISL6421_ISEL1 0x20 39#define ISL6421_ISEL1 0x20
40#define ISL6421_DCL 0x40 40#define ISL6421_DCL 0x40
41 41
42#if defined(CONFIG_DVB_ISL6421) || defined(CONFIG_DVB_ISL6421_MODULE)
42/* override_set and override_clear control which system register bits (above) to always set & clear */ 43/* override_set and override_clear control which system register bits (above) to always set & clear */
43extern int isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr, 44extern struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
44 u8 override_set, u8 override_clear); 45 u8 override_set, u8 override_clear);
46#else
47static inline struct dvb_frontend *isl6421_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 i2c_addr,
48 u8 override_set, u8 override_clear)
49{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
51 return NULL;
52}
53#endif // CONFIG_DVB_ISL6421
45 54
46#endif 55#endif
diff --git a/drivers/media/dvb/frontends/l64781.h b/drivers/media/dvb/frontends/l64781.h
index 83b8bc210274..21ba4a230760 100644
--- a/drivers/media/dvb/frontends/l64781.h
+++ b/drivers/media/dvb/frontends/l64781.h
@@ -31,8 +31,16 @@ struct l64781_config
31 u8 demod_address; 31 u8 demod_address;
32}; 32};
33 33
34 34#if defined(CONFIG_DVB_L64781) || defined(CONFIG_DVB_L64781_MODULE)
35extern struct dvb_frontend* l64781_attach(const struct l64781_config* config, 35extern struct dvb_frontend* l64781_attach(const struct l64781_config* config,
36 struct i2c_adapter* i2c); 36 struct i2c_adapter* i2c);
37#else
38static inline struct dvb_frontend* l64781_attach(const struct l64781_config* config,
39 struct i2c_adapter* i2c)
40{
41 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
42 return NULL;
43}
44#endif // CONFIG_DVB_L64781
37 45
38#endif // L64781_H 46#endif // L64781_H
diff --git a/drivers/media/dvb/frontends/lgdt330x.h b/drivers/media/dvb/frontends/lgdt330x.h
index bad903c6f0f8..3f96b485584c 100644
--- a/drivers/media/dvb/frontends/lgdt330x.h
+++ b/drivers/media/dvb/frontends/lgdt330x.h
@@ -52,8 +52,17 @@ struct lgdt330x_config
52 int clock_polarity_flip; 52 int clock_polarity_flip;
53}; 53};
54 54
55#if defined(CONFIG_DVB_LGDT330X) || defined(CONFIG_DVB_LGDT330X_MODULE)
55extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config, 56extern struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
56 struct i2c_adapter* i2c); 57 struct i2c_adapter* i2c);
58#else
59static inline struct dvb_frontend* lgdt330x_attach(const struct lgdt330x_config* config,
60 struct i2c_adapter* i2c)
61{
62 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
63 return NULL;
64}
65#endif // CONFIG_DVB_LGDT330X
57 66
58#endif /* LGDT330X_H */ 67#endif /* LGDT330X_H */
59 68
diff --git a/drivers/media/dvb/frontends/lnbp21.c b/drivers/media/dvb/frontends/lnbp21.c
index e933edc8dd29..2d2f58c26226 100644
--- a/drivers/media/dvb/frontends/lnbp21.c
+++ b/drivers/media/dvb/frontends/lnbp21.c
@@ -40,12 +40,11 @@ struct lnbp21 {
40 u8 override_or; 40 u8 override_or;
41 u8 override_and; 41 u8 override_and;
42 struct i2c_adapter *i2c; 42 struct i2c_adapter *i2c;
43 void (*release_chain)(struct dvb_frontend* fe);
44}; 43};
45 44
46static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage) 45static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
47{ 46{
48 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; 47 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
49 struct i2c_msg msg = { .addr = 0x08, .flags = 0, 48 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
50 .buf = &lnbp21->config, 49 .buf = &lnbp21->config,
51 .len = sizeof(lnbp21->config) }; 50 .len = sizeof(lnbp21->config) };
@@ -73,7 +72,7 @@ static int lnbp21_set_voltage(struct dvb_frontend *fe, fe_sec_voltage_t voltage)
73 72
74static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg) 73static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
75{ 74{
76 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv; 75 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->sec_priv;
77 struct i2c_msg msg = { .addr = 0x08, .flags = 0, 76 struct i2c_msg msg = { .addr = 0x08, .flags = 0,
78 .buf = &lnbp21->config, 77 .buf = &lnbp21->config,
79 .len = sizeof(lnbp21->config) }; 78 .len = sizeof(lnbp21->config) };
@@ -91,29 +90,24 @@ static int lnbp21_enable_high_lnb_voltage(struct dvb_frontend *fe, long arg)
91 90
92static void lnbp21_release(struct dvb_frontend *fe) 91static void lnbp21_release(struct dvb_frontend *fe)
93{ 92{
94 struct lnbp21 *lnbp21 = (struct lnbp21 *) fe->misc_priv;
95
96 /* LNBP power off */ 93 /* LNBP power off */
97 lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF); 94 lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF);
98 95
99 /* free data & call next release routine */ 96 /* free data */
100 fe->ops.release = lnbp21->release_chain; 97 kfree(fe->sec_priv);
101 kfree(fe->misc_priv); 98 fe->sec_priv = NULL;
102 fe->misc_priv = NULL;
103 if (fe->ops.release)
104 fe->ops.release(fe);
105} 99}
106 100
107int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear) 101struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
108{ 102{
109 struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL); 103 struct lnbp21 *lnbp21 = kmalloc(sizeof(struct lnbp21), GFP_KERNEL);
110 if (!lnbp21) 104 if (!lnbp21)
111 return -ENOMEM; 105 return NULL;
112 106
113 /* default configuration */ 107 /* default configuration */
114 lnbp21->config = LNBP21_ISEL; 108 lnbp21->config = LNBP21_ISEL;
115 lnbp21->i2c = i2c; 109 lnbp21->i2c = i2c;
116 fe->misc_priv = lnbp21; 110 fe->sec_priv = lnbp21;
117 111
118 /* bits which should be forced to '1' */ 112 /* bits which should be forced to '1' */
119 lnbp21->override_or = override_set; 113 lnbp21->override_or = override_set;
@@ -124,19 +118,17 @@ int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_
124 /* detect if it is present or not */ 118 /* detect if it is present or not */
125 if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) { 119 if (lnbp21_set_voltage(fe, SEC_VOLTAGE_OFF)) {
126 kfree(lnbp21); 120 kfree(lnbp21);
127 fe->misc_priv = NULL; 121 return NULL;
128 return -EIO;
129 } 122 }
130 123
131 /* install release callback */ 124 /* install release callback */
132 lnbp21->release_chain = fe->ops.release; 125 fe->ops.release_sec = lnbp21_release;
133 fe->ops.release = lnbp21_release;
134 126
135 /* override frontend ops */ 127 /* override frontend ops */
136 fe->ops.set_voltage = lnbp21_set_voltage; 128 fe->ops.set_voltage = lnbp21_set_voltage;
137 fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage; 129 fe->ops.enable_high_lnb_voltage = lnbp21_enable_high_lnb_voltage;
138 130
139 return 0; 131 return fe;
140} 132}
141EXPORT_SYMBOL(lnbp21_attach); 133EXPORT_SYMBOL(lnbp21_attach);
142 134
diff --git a/drivers/media/dvb/frontends/lnbp21.h b/drivers/media/dvb/frontends/lnbp21.h
index 047a4ab68c01..1fe1dd179312 100644
--- a/drivers/media/dvb/frontends/lnbp21.h
+++ b/drivers/media/dvb/frontends/lnbp21.h
@@ -39,7 +39,15 @@
39 39
40#include <linux/dvb/frontend.h> 40#include <linux/dvb/frontend.h>
41 41
42#if defined(CONFIG_DVB_LNBP21) || defined(CONFIG_DVB_LNBP21_MODULE)
42/* override_set and override_clear control which system register bits (above) to always set & clear */ 43/* override_set and override_clear control which system register bits (above) to always set & clear */
43extern int lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear); 44extern struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear);
45#else
46static inline struct dvb_frontend *lnbp21_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, u8 override_set, u8 override_clear)
47{
48 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
49 return NULL;
50}
51#endif // CONFIG_DVB_LNBP21
44 52
45#endif 53#endif // _LNBP21_H
diff --git a/drivers/media/dvb/frontends/mt2060.c b/drivers/media/dvb/frontends/mt2060.c
new file mode 100644
index 000000000000..508ec1b6d1fb
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt2060.c
@@ -0,0 +1,367 @@
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/moduleparam.h>
26#include <linux/delay.h>
27#include <linux/dvb/frontend.h>
28#include <linux/i2c.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, struct dvb_frontend_parameters *params)
157{
158 struct mt2060_priv *priv;
159 int ret=0;
160 int i=0;
161 u32 freq;
162 u8 lnaband;
163 u32 f_lo1,f_lo2;
164 u32 div1,num1,div2,num2;
165 u8 b[8];
166 u32 if1;
167
168 priv = fe->tuner_priv;
169
170 if1 = priv->if1_freq;
171 b[0] = REG_LO1B1;
172 b[1] = 0xFF;
173
174 mt2060_writeregs(priv,b,2);
175
176 freq = params->frequency / 1000; // Hz -> kHz
177 priv->bandwidth = (fe->ops.info.type == FE_OFDM) ? params->u.ofdm.bandwidth : 0;
178
179 f_lo1 = freq + if1 * 1000;
180 f_lo1 = (f_lo1 / 250) * 250;
181 f_lo2 = f_lo1 - freq - IF2;
182 // From the Comtech datasheet, the step used is 50kHz. The tuner chip could be more precise
183 f_lo2 = ((f_lo2 + 25) / 50) * 50;
184 priv->frequency = (f_lo1 - f_lo2 - IF2) * 1000,
185
186#ifdef MT2060_SPURCHECK
187 // LO-related spurs detection and correction
188 num1 = mt2060_spurcheck(f_lo1,f_lo2,IF2);
189 f_lo1 += num1;
190 f_lo2 += num1;
191#endif
192 //Frequency LO1 = 16MHz * (DIV1 + NUM1/64 )
193 num1 = f_lo1 / (FREF / 64);
194 div1 = num1 / 64;
195 num1 &= 0x3f;
196
197 // Frequency LO2 = 16MHz * (DIV2 + NUM2/8192 )
198 num2 = f_lo2 * 64 / (FREF / 128);
199 div2 = num2 / 8192;
200 num2 &= 0x1fff;
201
202 if (freq <= 95000) lnaband = 0xB0; else
203 if (freq <= 180000) lnaband = 0xA0; else
204 if (freq <= 260000) lnaband = 0x90; else
205 if (freq <= 335000) lnaband = 0x80; else
206 if (freq <= 425000) lnaband = 0x70; else
207 if (freq <= 480000) lnaband = 0x60; else
208 if (freq <= 570000) lnaband = 0x50; else
209 if (freq <= 645000) lnaband = 0x40; else
210 if (freq <= 730000) lnaband = 0x30; else
211 if (freq <= 810000) lnaband = 0x20; else lnaband = 0x10;
212
213 b[0] = REG_LO1C1;
214 b[1] = lnaband | ((num1 >>2) & 0x0F);
215 b[2] = div1;
216 b[3] = (num2 & 0x0F) | ((num1 & 3) << 4);
217 b[4] = num2 >> 4;
218 b[5] = ((num2 >>12) & 1) | (div2 << 1);
219
220 dprintk("IF1: %dMHz",(int)if1);
221 dprintk("PLL freq=%dkHz f_lo1=%dkHz f_lo2=%dkHz",(int)freq,(int)f_lo1,(int)f_lo2);
222 dprintk("PLL div1=%d num1=%d div2=%d num2=%d",(int)div1,(int)num1,(int)div2,(int)num2);
223 dprintk("PLL [1..5]: %2x %2x %2x %2x %2x",(int)b[1],(int)b[2],(int)b[3],(int)b[4],(int)b[5]);
224
225 mt2060_writeregs(priv,b,6);
226
227 //Waits for pll lock or timeout
228 i = 0;
229 do {
230 mt2060_readreg(priv,REG_LO_STATUS,b);
231 if ((b[0] & 0x88)==0x88)
232 break;
233 msleep(4);
234 i++;
235 } while (i<10);
236
237 return ret;
238}
239
240static void mt2060_calibrate(struct mt2060_priv *priv)
241{
242 u8 b = 0;
243 int i = 0;
244
245 if (mt2060_writeregs(priv,mt2060_config1,sizeof(mt2060_config1)))
246 return;
247 if (mt2060_writeregs(priv,mt2060_config2,sizeof(mt2060_config2)))
248 return;
249
250 do {
251 b |= (1 << 6); // FM1SS;
252 mt2060_writereg(priv, REG_LO2C1,b);
253 msleep(20);
254
255 if (i == 0) {
256 b |= (1 << 7); // FM1CA;
257 mt2060_writereg(priv, REG_LO2C1,b);
258 b &= ~(1 << 7); // FM1CA;
259 msleep(20);
260 }
261
262 b &= ~(1 << 6); // FM1SS
263 mt2060_writereg(priv, REG_LO2C1,b);
264
265 msleep(20);
266 i++;
267 } while (i < 9);
268
269 i = 0;
270 while (i++ < 10 && mt2060_readreg(priv, REG_MISC_STAT, &b) == 0 && (b & (1 << 6)) == 0)
271 msleep(20);
272
273 if (i < 10) {
274 mt2060_readreg(priv, REG_FM_FREQ, &priv->fmfreq); // now find out, what is fmreq used for :)
275 dprintk("calibration was successful: %d", (int)priv->fmfreq);
276 } else
277 dprintk("FMCAL timed out");
278}
279
280static int mt2060_get_frequency(struct dvb_frontend *fe, u32 *frequency)
281{
282 struct mt2060_priv *priv = fe->tuner_priv;
283 *frequency = priv->frequency;
284 return 0;
285}
286
287static int mt2060_get_bandwidth(struct dvb_frontend *fe, u32 *bandwidth)
288{
289 struct mt2060_priv *priv = fe->tuner_priv;
290 *bandwidth = priv->bandwidth;
291 return 0;
292}
293
294static int mt2060_init(struct dvb_frontend *fe)
295{
296 struct mt2060_priv *priv = fe->tuner_priv;
297 return mt2060_writereg(priv, REG_VGAG,0x33);
298}
299
300static int mt2060_sleep(struct dvb_frontend *fe)
301{
302 struct mt2060_priv *priv = fe->tuner_priv;
303 return mt2060_writereg(priv, REG_VGAG,0x30);
304}
305
306static int mt2060_release(struct dvb_frontend *fe)
307{
308 kfree(fe->tuner_priv);
309 fe->tuner_priv = NULL;
310 return 0;
311}
312
313static const struct dvb_tuner_ops mt2060_tuner_ops = {
314 .info = {
315 .name = "Microtune MT2060",
316 .frequency_min = 48000000,
317 .frequency_max = 860000000,
318 .frequency_step = 50000,
319 },
320
321 .release = mt2060_release,
322
323 .init = mt2060_init,
324 .sleep = mt2060_sleep,
325
326 .set_params = mt2060_set_params,
327 .get_frequency = mt2060_get_frequency,
328 .get_bandwidth = mt2060_get_bandwidth
329};
330
331/* This functions tries to identify a MT2060 tuner by reading the PART/REV register. This is hasty. */
332int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1)
333{
334 struct mt2060_priv *priv = NULL;
335 u8 id = 0;
336
337 priv = kzalloc(sizeof(struct mt2060_priv), GFP_KERNEL);
338 if (priv == NULL)
339 return -ENOMEM;
340
341 priv->cfg = cfg;
342 priv->i2c = i2c;
343 priv->if1_freq = if1;
344
345 if (mt2060_readreg(priv,REG_PART_REV,&id) != 0) {
346 kfree(priv);
347 return -ENODEV;
348 }
349
350 if (id != PART_REV) {
351 kfree(priv);
352 return -ENODEV;
353 }
354 printk(KERN_INFO "MT2060: successfully identified (IF1 = %d)\n", if1);
355 memcpy(&fe->ops.tuner_ops, &mt2060_tuner_ops, sizeof(struct dvb_tuner_ops));
356
357 fe->tuner_priv = priv;
358
359 mt2060_calibrate(priv);
360
361 return 0;
362}
363EXPORT_SYMBOL(mt2060_attach);
364
365MODULE_AUTHOR("Olivier DANET");
366MODULE_DESCRIPTION("Microtune MT2060 silicon tuner driver");
367MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/mt2060.h b/drivers/media/dvb/frontends/mt2060.h
new file mode 100644
index 000000000000..c58b03e82345
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt2060.h
@@ -0,0 +1,35 @@
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 /* Shall we add settings for the discrete outputs ? */
31};
32
33extern int mt2060_attach(struct dvb_frontend *fe, struct i2c_adapter *i2c, struct mt2060_config *cfg, u16 if1);
34
35#endif
diff --git a/drivers/media/dvb/frontends/mt2060_priv.h b/drivers/media/dvb/frontends/mt2060_priv.h
new file mode 100644
index 000000000000..5eaccdefd0b0
--- /dev/null
+++ b/drivers/media/dvb/frontends/mt2060_priv.h
@@ -0,0 +1,105 @@
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 u32 bandwidth;
101 u16 if1_freq;
102 u8 fmfreq;
103};
104
105#endif
diff --git a/drivers/media/dvb/frontends/mt312.h b/drivers/media/dvb/frontends/mt312.h
index 666a1bd1c244..7112fb4d58ac 100644
--- a/drivers/media/dvb/frontends/mt312.h
+++ b/drivers/media/dvb/frontends/mt312.h
@@ -34,8 +34,16 @@ struct mt312_config
34 u8 demod_address; 34 u8 demod_address;
35}; 35};
36 36
37#if defined(CONFIG_DVB_MT312) || defined(CONFIG_DVB_MT312_MODULE)
37struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config, 38struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
38 struct i2c_adapter* i2c); 39 struct i2c_adapter* i2c);
39 40#else
41static inline struct dvb_frontend* vp310_mt312_attach(const struct mt312_config* config,
42 struct i2c_adapter* i2c)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
45 return NULL;
46}
47#endif // CONFIG_DVB_MT312
40 48
41#endif // MT312_H 49#endif // MT312_H
diff --git a/drivers/media/dvb/frontends/mt352.c b/drivers/media/dvb/frontends/mt352.c
index 5de7376c94ce..87e31ca7e108 100644
--- a/drivers/media/dvb/frontends/mt352.c
+++ b/drivers/media/dvb/frontends/mt352.c
@@ -70,7 +70,7 @@ static int mt352_single_write(struct dvb_frontend *fe, u8 reg, u8 val)
70 return 0; 70 return 0;
71} 71}
72 72
73int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen) 73static int _mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen)
74{ 74{
75 int err,i; 75 int err,i;
76 for (i=0; i < ilen-1; i++) 76 for (i=0; i < ilen-1; i++)
@@ -107,7 +107,7 @@ static int mt352_sleep(struct dvb_frontend* fe)
107{ 107{
108 static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 }; 108 static u8 mt352_softdown[] = { CLOCK_CTL, 0x20, 0x08 };
109 109
110 mt352_write(fe, mt352_softdown, sizeof(mt352_softdown)); 110 _mt352_write(fe, mt352_softdown, sizeof(mt352_softdown));
111 return 0; 111 return 0;
112} 112}
113 113
@@ -293,14 +293,14 @@ static int mt352_set_parameters(struct dvb_frontend* fe,
293 fe->ops.i2c_gate_ctrl(fe, 0); 293 fe->ops.i2c_gate_ctrl(fe, 0);
294 } 294 }
295 295
296 mt352_write(fe, buf, 8); 296 _mt352_write(fe, buf, 8);
297 mt352_write(fe, fsm_go, 2); 297 _mt352_write(fe, fsm_go, 2);
298 } else { 298 } else {
299 if (fe->ops.tuner_ops.calc_regs) { 299 if (fe->ops.tuner_ops.calc_regs) {
300 fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5); 300 fe->ops.tuner_ops.calc_regs(fe, param, buf+8, 5);
301 buf[8] <<= 1; 301 buf[8] <<= 1;
302 mt352_write(fe, buf, sizeof(buf)); 302 _mt352_write(fe, buf, sizeof(buf));
303 mt352_write(fe, tuner_go, 2); 303 _mt352_write(fe, tuner_go, 2);
304 } 304 }
305 } 305 }
306 306
@@ -522,7 +522,7 @@ static int mt352_init(struct dvb_frontend* fe)
522 (mt352_read_register(state, CONFIG) & 0x20) == 0) { 522 (mt352_read_register(state, CONFIG) & 0x20) == 0) {
523 523
524 /* Do a "hard" reset */ 524 /* Do a "hard" reset */
525 mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach)); 525 _mt352_write(fe, mt352_reset_attach, sizeof(mt352_reset_attach));
526 return state->config.demod_init(fe); 526 return state->config.demod_init(fe);
527 } 527 }
528 528
@@ -585,6 +585,7 @@ static struct dvb_frontend_ops mt352_ops = {
585 585
586 .init = mt352_init, 586 .init = mt352_init,
587 .sleep = mt352_sleep, 587 .sleep = mt352_sleep,
588 .write = _mt352_write,
588 589
589 .set_frontend = mt352_set_parameters, 590 .set_frontend = mt352_set_parameters,
590 .get_frontend = mt352_get_parameters, 591 .get_frontend = mt352_get_parameters,
@@ -605,4 +606,3 @@ MODULE_AUTHOR("Holger Waechtler, Daniel Mack, Antonio Mancuso");
605MODULE_LICENSE("GPL"); 606MODULE_LICENSE("GPL");
606 607
607EXPORT_SYMBOL(mt352_attach); 608EXPORT_SYMBOL(mt352_attach);
608EXPORT_SYMBOL(mt352_write);
diff --git a/drivers/media/dvb/frontends/mt352.h b/drivers/media/dvb/frontends/mt352.h
index 9e7ff4b8fe5f..0035c2e2d7c2 100644
--- a/drivers/media/dvb/frontends/mt352.h
+++ b/drivers/media/dvb/frontends/mt352.h
@@ -51,9 +51,23 @@ struct mt352_config
51 int (*demod_init)(struct dvb_frontend* fe); 51 int (*demod_init)(struct dvb_frontend* fe);
52}; 52};
53 53
54#if defined(CONFIG_DVB_MT352) || defined(CONFIG_DVB_MT352_MODULE)
54extern struct dvb_frontend* mt352_attach(const struct mt352_config* config, 55extern struct dvb_frontend* mt352_attach(const struct mt352_config* config,
55 struct i2c_adapter* i2c); 56 struct i2c_adapter* i2c);
57#else
58static inline struct dvb_frontend* mt352_attach(const struct mt352_config* config,
59 struct i2c_adapter* i2c)
60{
61 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
62 return NULL;
63}
64#endif // CONFIG_DVB_MT352
56 65
57extern int mt352_write(struct dvb_frontend* fe, u8* ibuf, int ilen); 66static inline int mt352_write(struct dvb_frontend *fe, u8 *buf, int len) {
67 int r = 0;
68 if (fe->ops.write)
69 r = fe->ops.write(fe, buf, len);
70 return r;
71}
58 72
59#endif // MT352_H 73#endif // MT352_H
diff --git a/drivers/media/dvb/frontends/nxt200x.h b/drivers/media/dvb/frontends/nxt200x.h
index 34d61735845b..2eb220e98062 100644
--- a/drivers/media/dvb/frontends/nxt200x.h
+++ b/drivers/media/dvb/frontends/nxt200x.h
@@ -45,8 +45,17 @@ struct nxt200x_config
45 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 45 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
46}; 46};
47 47
48#if defined(CONFIG_DVB_NXT200X) || defined(CONFIG_DVB_NXT200X_MODULE)
48extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config, 49extern struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
49 struct i2c_adapter* i2c); 50 struct i2c_adapter* i2c);
51#else
52static inline struct dvb_frontend* nxt200x_attach(const struct nxt200x_config* config,
53 struct i2c_adapter* i2c)
54{
55 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
56 return NULL;
57}
58#endif // CONFIG_DVB_NXT200X
50 59
51#endif /* NXT200X_H */ 60#endif /* NXT200X_H */
52 61
diff --git a/drivers/media/dvb/frontends/nxt6000.h b/drivers/media/dvb/frontends/nxt6000.h
index 117031d11708..9397393a6bd1 100644
--- a/drivers/media/dvb/frontends/nxt6000.h
+++ b/drivers/media/dvb/frontends/nxt6000.h
@@ -33,7 +33,16 @@ struct nxt6000_config
33 u8 clock_inversion:1; 33 u8 clock_inversion:1;
34}; 34};
35 35
36#if defined(CONFIG_DVB_NXT6000) || defined(CONFIG_DVB_NXT6000_MODULE)
36extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config, 37extern struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
37 struct i2c_adapter* i2c); 38 struct i2c_adapter* i2c);
39#else
40static inline struct dvb_frontend* nxt6000_attach(const struct nxt6000_config* config,
41 struct i2c_adapter* i2c)
42{
43 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
44 return NULL;
45}
46#endif // CONFIG_DVB_NXT6000
38 47
39#endif // NXT6000_H 48#endif // NXT6000_H
diff --git a/drivers/media/dvb/frontends/or51132.h b/drivers/media/dvb/frontends/or51132.h
index 89658883abf5..9718be4fb835 100644
--- a/drivers/media/dvb/frontends/or51132.h
+++ b/drivers/media/dvb/frontends/or51132.h
@@ -34,8 +34,17 @@ struct or51132_config
34 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured); 34 int (*set_ts_params)(struct dvb_frontend* fe, int is_punctured);
35}; 35};
36 36
37#if defined(CONFIG_DVB_OR51132) || defined(CONFIG_DVB_OR51132_MODULE)
37extern struct dvb_frontend* or51132_attach(const struct or51132_config* config, 38extern struct dvb_frontend* or51132_attach(const struct or51132_config* config,
38 struct i2c_adapter* i2c); 39 struct i2c_adapter* i2c);
40#else
41static inline struct dvb_frontend* or51132_attach(const struct or51132_config* config,
42 struct i2c_adapter* i2c)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
45 return NULL;
46}
47#endif // CONFIG_DVB_OR51132
39 48
40#endif // OR51132_H 49#endif // OR51132_H
41 50
diff --git a/drivers/media/dvb/frontends/or51211.h b/drivers/media/dvb/frontends/or51211.h
index 13a5a3afbf8b..10a5419f9e00 100644
--- a/drivers/media/dvb/frontends/or51211.h
+++ b/drivers/media/dvb/frontends/or51211.h
@@ -37,8 +37,17 @@ struct or51211_config
37 void (*sleep)(struct dvb_frontend * fe); 37 void (*sleep)(struct dvb_frontend * fe);
38}; 38};
39 39
40#if defined(CONFIG_DVB_OR51211) || defined(CONFIG_DVB_OR51211_MODULE)
40extern struct dvb_frontend* or51211_attach(const struct or51211_config* config, 41extern struct dvb_frontend* or51211_attach(const struct or51211_config* config,
41 struct i2c_adapter* i2c); 42 struct i2c_adapter* i2c);
43#else
44static inline struct dvb_frontend* or51211_attach(const struct or51211_config* config,
45 struct i2c_adapter* i2c)
46{
47 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
48 return NULL;
49}
50#endif // CONFIG_DVB_OR51211
42 51
43#endif // OR51211_H 52#endif // OR51211_H
44 53
diff --git a/drivers/media/dvb/frontends/s5h1420.h b/drivers/media/dvb/frontends/s5h1420.h
index 4e39015fa67e..efc54d7f3c55 100644
--- a/drivers/media/dvb/frontends/s5h1420.h
+++ b/drivers/media/dvb/frontends/s5h1420.h
@@ -34,7 +34,16 @@ struct s5h1420_config
34 u8 invert:1; 34 u8 invert:1;
35}; 35};
36 36
37#if defined(CONFIG_DVB_S5H1420) || defined(CONFIG_DVB_S5H1420_MODULE)
37extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config, 38extern struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
38 struct i2c_adapter* i2c); 39 struct i2c_adapter* i2c);
40#else
41static inline struct dvb_frontend* s5h1420_attach(const struct s5h1420_config* config,
42 struct i2c_adapter* i2c)
43{
44 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
45 return NULL;
46}
47#endif // CONFIG_DVB_S5H1420
39 48
40#endif // S5H1420_H 49#endif // S5H1420_H
diff --git a/drivers/media/dvb/frontends/sp8870.h b/drivers/media/dvb/frontends/sp8870.h
index 93afbb969d6b..4cf27d3b10f2 100644
--- a/drivers/media/dvb/frontends/sp8870.h
+++ b/drivers/media/dvb/frontends/sp8870.h
@@ -35,7 +35,16 @@ struct sp8870_config
35 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); 35 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
36}; 36};
37 37
38#if defined(CONFIG_DVB_SP8870) || defined(CONFIG_DVB_SP8870_MODULE)
38extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config, 39extern struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
39 struct i2c_adapter* i2c); 40 struct i2c_adapter* i2c);
41#else
42static inline struct dvb_frontend* sp8870_attach(const struct sp8870_config* config,
43 struct i2c_adapter* i2c)
44{
45 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
46 return NULL;
47}
48#endif // CONFIG_DVB_SP8870
40 49
41#endif // SP8870_H 50#endif // SP8870_H
diff --git a/drivers/media/dvb/frontends/sp887x.h b/drivers/media/dvb/frontends/sp887x.h
index c44b0ebdf1e2..cab7ea644dfa 100644
--- a/drivers/media/dvb/frontends/sp887x.h
+++ b/drivers/media/dvb/frontends/sp887x.h
@@ -17,7 +17,16 @@ struct sp887x_config
17 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); 17 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
18}; 18};
19 19
20#if defined(CONFIG_DVB_SP887X) || defined(CONFIG_DVB_SP887X_MODULE)
20extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config, 21extern struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
21 struct i2c_adapter* i2c); 22 struct i2c_adapter* i2c);
23#else
24static inline struct dvb_frontend* sp887x_attach(const struct sp887x_config* config,
25 struct i2c_adapter* i2c)
26{
27 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
28 return NULL;
29}
30#endif // CONFIG_DVB_SP887X
22 31
23#endif // SP887X_H 32#endif // SP887X_H
diff --git a/drivers/media/dvb/frontends/stv0297.h b/drivers/media/dvb/frontends/stv0297.h
index 1da5384fb985..760b80db43a5 100644
--- a/drivers/media/dvb/frontends/stv0297.h
+++ b/drivers/media/dvb/frontends/stv0297.h
@@ -42,7 +42,16 @@ struct stv0297_config
42 u8 stop_during_read:1; 42 u8 stop_during_read:1;
43}; 43};
44 44
45#if defined(CONFIG_DVB_STV0297) || defined(CONFIG_DVB_STV0297_MODULE)
45extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config, 46extern struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
46 struct i2c_adapter* i2c); 47 struct i2c_adapter* i2c);
48#else
49static inline struct dvb_frontend* stv0297_attach(const struct stv0297_config* config,
50 struct i2c_adapter* i2c)
51{
52 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
53 return NULL;
54}
55#endif // CONFIG_DVB_STV0297
47 56
48#endif // STV0297_H 57#endif // STV0297_H
diff --git a/drivers/media/dvb/frontends/stv0299.c b/drivers/media/dvb/frontends/stv0299.c
index 96648a75440d..93483769eca8 100644
--- a/drivers/media/dvb/frontends/stv0299.c
+++ b/drivers/media/dvb/frontends/stv0299.c
@@ -92,11 +92,14 @@ static int stv0299_writeregI (struct stv0299_state* state, u8 reg, u8 data)
92 return (ret != 1) ? -EREMOTEIO : 0; 92 return (ret != 1) ? -EREMOTEIO : 0;
93} 93}
94 94
95int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data) 95int stv0299_write(struct dvb_frontend* fe, u8 *buf, int len)
96{ 96{
97 struct stv0299_state* state = fe->demodulator_priv; 97 struct stv0299_state* state = fe->demodulator_priv;
98 98
99 return stv0299_writeregI(state, reg, data); 99 if (len != 2)
100 return -EINVAL;
101
102 return stv0299_writeregI(state, buf[0], buf[1]);
100} 103}
101 104
102static u8 stv0299_readreg (struct stv0299_state* state, u8 reg) 105static u8 stv0299_readreg (struct stv0299_state* state, u8 reg)
@@ -694,6 +697,7 @@ static struct dvb_frontend_ops stv0299_ops = {
694 697
695 .init = stv0299_init, 698 .init = stv0299_init,
696 .sleep = stv0299_sleep, 699 .sleep = stv0299_sleep,
700 .write = stv0299_write,
697 .i2c_gate_ctrl = stv0299_i2c_gate_ctrl, 701 .i2c_gate_ctrl = stv0299_i2c_gate_ctrl,
698 702
699 .set_frontend = stv0299_set_frontend, 703 .set_frontend = stv0299_set_frontend,
@@ -724,5 +728,4 @@ MODULE_AUTHOR("Ralph Metzler, Holger Waechtler, Peter Schildmann, Felix Domke, "
724 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly"); 728 "Andreas Oberritter, Andrew de Quincey, Kenneth Aafly");
725MODULE_LICENSE("GPL"); 729MODULE_LICENSE("GPL");
726 730
727EXPORT_SYMBOL(stv0299_writereg);
728EXPORT_SYMBOL(stv0299_attach); 731EXPORT_SYMBOL(stv0299_attach);
diff --git a/drivers/media/dvb/frontends/stv0299.h b/drivers/media/dvb/frontends/stv0299.h
index 1504828e4232..7ef25207081d 100644
--- a/drivers/media/dvb/frontends/stv0299.h
+++ b/drivers/media/dvb/frontends/stv0299.h
@@ -89,9 +89,24 @@ struct stv0299_config
89 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio); 89 int (*set_symbol_rate)(struct dvb_frontend* fe, u32 srate, u32 ratio);
90}; 90};
91 91
92extern int stv0299_writereg (struct dvb_frontend* fe, u8 reg, u8 data); 92#if defined(CONFIG_DVB_STV0299) || defined(CONFIG_DVB_STV0299_MODULE)
93
94extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config, 93extern struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
95 struct i2c_adapter* i2c); 94 struct i2c_adapter* i2c);
95#else
96static inline struct dvb_frontend* stv0299_attach(const struct stv0299_config* config,
97 struct i2c_adapter* i2c)
98{
99 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
100 return NULL;
101}
102#endif // CONFIG_DVB_STV0299
103
104static inline int stv0299_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
105 int r = 0;
106 u8 buf[] = {reg, val};
107 if (fe->ops.write)
108 r = fe->ops.write(fe, buf, 2);
109 return r;
110}
96 111
97#endif // STV0299_H 112#endif // STV0299_H
diff --git a/drivers/media/dvb/frontends/tda10021.c b/drivers/media/dvb/frontends/tda10021.c
index 9cbd164aa281..dca89171be1f 100644
--- a/drivers/media/dvb/frontends/tda10021.c
+++ b/drivers/media/dvb/frontends/tda10021.c
@@ -72,7 +72,7 @@ static u8 tda10021_inittab[0x40]=
72 0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00, 72 0x04, 0x2d, 0x2f, 0xff, 0x00, 0x00, 0x00, 0x00,
73}; 73};
74 74
75static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data) 75static int _tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
76{ 76{
77 u8 buf[] = { reg, data }; 77 u8 buf[] = { reg, data };
78 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 }; 78 struct i2c_msg msg = { .addr = state->config->demod_address, .flags = 0, .buf = buf, .len = 2 };
@@ -88,14 +88,6 @@ static int tda10021_writereg (struct tda10021_state* state, u8 reg, u8 data)
88 return (ret != 1) ? -EREMOTEIO : 0; 88 return (ret != 1) ? -EREMOTEIO : 0;
89} 89}
90 90
91int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data)
92{
93 struct tda10021_state* state = fe->demodulator_priv;
94
95 return tda10021_writereg(state, reg, data);
96}
97EXPORT_SYMBOL(tda10021_write_byte);
98
99static u8 tda10021_readreg (struct tda10021_state* state, u8 reg) 91static u8 tda10021_readreg (struct tda10021_state* state, u8 reg)
100{ 92{
101 u8 b0 [] = { reg }; 93 u8 b0 [] = { reg };
@@ -149,8 +141,8 @@ static int tda10021_setup_reg0 (struct tda10021_state* state, u8 reg0,
149 else if (INVERSION_OFF == inversion) 141 else if (INVERSION_OFF == inversion)
150 DISABLE_INVERSION(reg0); 142 DISABLE_INVERSION(reg0);
151 143
152 tda10021_writereg (state, 0x00, reg0 & 0xfe); 144 _tda10021_writereg (state, 0x00, reg0 & 0xfe);
153 tda10021_writereg (state, 0x00, reg0 | 0x01); 145 _tda10021_writereg (state, 0x00, reg0 | 0x01);
154 146
155 state->reg0 = reg0; 147 state->reg0 = reg0;
156 return 0; 148 return 0;
@@ -198,17 +190,27 @@ static int tda10021_set_symbolrate (struct tda10021_state* state, u32 symbolrate
198 190
199 NDEC = (NDEC << 6) | tda10021_inittab[0x03]; 191 NDEC = (NDEC << 6) | tda10021_inittab[0x03];
200 192
201 tda10021_writereg (state, 0x03, NDEC); 193 _tda10021_writereg (state, 0x03, NDEC);
202 tda10021_writereg (state, 0x0a, BDR&0xff); 194 _tda10021_writereg (state, 0x0a, BDR&0xff);
203 tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff); 195 _tda10021_writereg (state, 0x0b, (BDR>> 8)&0xff);
204 tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f); 196 _tda10021_writereg (state, 0x0c, (BDR>>16)&0x3f);
205 197
206 tda10021_writereg (state, 0x0d, BDRI); 198 _tda10021_writereg (state, 0x0d, BDRI);
207 tda10021_writereg (state, 0x0e, SFIL); 199 _tda10021_writereg (state, 0x0e, SFIL);
208 200
209 return 0; 201 return 0;
210} 202}
211 203
204int tda10021_write(struct dvb_frontend* fe, u8 *buf, int len)
205{
206 struct tda10021_state* state = fe->demodulator_priv;
207
208 if (len != 2)
209 return -EINVAL;
210
211 return _tda10021_writereg(state, buf[0], buf[1]);
212}
213
212static int tda10021_init (struct dvb_frontend *fe) 214static int tda10021_init (struct dvb_frontend *fe)
213{ 215{
214 struct tda10021_state* state = fe->demodulator_priv; 216 struct tda10021_state* state = fe->demodulator_priv;
@@ -216,12 +218,12 @@ static int tda10021_init (struct dvb_frontend *fe)
216 218
217 dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num); 219 dprintk("DVB: TDA10021(%d): init chip\n", fe->adapter->num);
218 220
219 //tda10021_writereg (fe, 0, 0); 221 //_tda10021_writereg (fe, 0, 0);
220 222
221 for (i=0; i<tda10021_inittab_size; i++) 223 for (i=0; i<tda10021_inittab_size; i++)
222 tda10021_writereg (state, i, tda10021_inittab[i]); 224 _tda10021_writereg (state, i, tda10021_inittab[i]);
223 225
224 tda10021_writereg (state, 0x34, state->pwm); 226 _tda10021_writereg (state, 0x34, state->pwm);
225 227
226 //Comment by markus 228 //Comment by markus
227 //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0) 229 //0x2A[3-0] == PDIV -> P multiplaying factor (P=PDIV+1)(default 0)
@@ -230,7 +232,7 @@ static int tda10021_init (struct dvb_frontend *fe)
230 //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0) 232 //0x2A[6] == POLAXIN -> Polarity of the input reference clock (default 0)
231 233
232 //Activate PLL 234 //Activate PLL
233 tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef); 235 _tda10021_writereg(state, 0x2a, tda10021_inittab[0x2a] & 0xef);
234 return 0; 236 return 0;
235} 237}
236 238
@@ -264,12 +266,12 @@ static int tda10021_set_parameters (struct dvb_frontend *fe,
264 } 266 }
265 267
266 tda10021_set_symbolrate (state, p->u.qam.symbol_rate); 268 tda10021_set_symbolrate (state, p->u.qam.symbol_rate);
267 tda10021_writereg (state, 0x34, state->pwm); 269 _tda10021_writereg (state, 0x34, state->pwm);
268 270
269 tda10021_writereg (state, 0x01, reg0x01[qam]); 271 _tda10021_writereg (state, 0x01, reg0x01[qam]);
270 tda10021_writereg (state, 0x05, reg0x05[qam]); 272 _tda10021_writereg (state, 0x05, reg0x05[qam]);
271 tda10021_writereg (state, 0x08, reg0x08[qam]); 273 _tda10021_writereg (state, 0x08, reg0x08[qam]);
272 tda10021_writereg (state, 0x09, reg0x09[qam]); 274 _tda10021_writereg (state, 0x09, reg0x09[qam]);
273 275
274 tda10021_setup_reg0 (state, reg0x00[qam], p->inversion); 276 tda10021_setup_reg0 (state, reg0x00[qam], p->inversion);
275 277
@@ -342,8 +344,8 @@ static int tda10021_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
342 *ucblocks = 0xffffffff; 344 *ucblocks = 0xffffffff;
343 345
344 /* reset uncorrected block counter */ 346 /* reset uncorrected block counter */
345 tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf); 347 _tda10021_writereg (state, 0x10, tda10021_inittab[0x10] & 0xdf);
346 tda10021_writereg (state, 0x10, tda10021_inittab[0x10]); 348 _tda10021_writereg (state, 0x10, tda10021_inittab[0x10]);
347 349
348 return 0; 350 return 0;
349} 351}
@@ -392,8 +394,8 @@ static int tda10021_sleep(struct dvb_frontend* fe)
392{ 394{
393 struct tda10021_state* state = fe->demodulator_priv; 395 struct tda10021_state* state = fe->demodulator_priv;
394 396
395 tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */ 397 _tda10021_writereg (state, 0x1b, 0x02); /* pdown ADC */
396 tda10021_writereg (state, 0x00, 0x80); /* standby */ 398 _tda10021_writereg (state, 0x00, 0x80); /* standby */
397 399
398 return 0; 400 return 0;
399} 401}
@@ -459,6 +461,7 @@ static struct dvb_frontend_ops tda10021_ops = {
459 461
460 .init = tda10021_init, 462 .init = tda10021_init,
461 .sleep = tda10021_sleep, 463 .sleep = tda10021_sleep,
464 .write = tda10021_write,
462 .i2c_gate_ctrl = tda10021_i2c_gate_ctrl, 465 .i2c_gate_ctrl = tda10021_i2c_gate_ctrl,
463 466
464 .set_frontend = tda10021_set_parameters, 467 .set_frontend = tda10021_set_parameters,
diff --git a/drivers/media/dvb/frontends/tda10021.h b/drivers/media/dvb/frontends/tda10021.h
index b1df4259bee9..d68ae20c8412 100644
--- a/drivers/media/dvb/frontends/tda10021.h
+++ b/drivers/media/dvb/frontends/tda10021.h
@@ -32,9 +32,24 @@ struct tda10021_config
32 u8 demod_address; 32 u8 demod_address;
33}; 33};
34 34
35#if defined(CONFIG_DVB_TDA10021) || defined(CONFIG_DVB_TDA10021_MODULE)
35extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config, 36extern struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
36 struct i2c_adapter* i2c, u8 pwm); 37 struct i2c_adapter* i2c, u8 pwm);
37 38#else
38extern int tda10021_write_byte(struct dvb_frontend* fe, int reg, int data); 39static inline struct dvb_frontend* tda10021_attach(const struct tda10021_config* config,
40 struct i2c_adapter* i2c, u8 pwm)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
43 return NULL;
44}
45#endif // CONFIG_DVB_TDA10021
46
47static inline int tda10021_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
48 int r = 0;
49 u8 buf[] = {reg, val};
50 if (fe->ops.write)
51 r = fe->ops.write(fe, buf, 2);
52 return r;
53}
39 54
40#endif // TDA10021_H 55#endif // TDA10021_H
diff --git a/drivers/media/dvb/frontends/tda1004x.c b/drivers/media/dvb/frontends/tda1004x.c
index 59a2ed614fca..11e0dca9a2d7 100644
--- a/drivers/media/dvb/frontends/tda1004x.c
+++ b/drivers/media/dvb/frontends/tda1004x.c
@@ -579,11 +579,14 @@ static int tda1004x_decode_fec(int tdafec)
579 return -1; 579 return -1;
580} 580}
581 581
582int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data) 582int tda1004x_write(struct dvb_frontend* fe, u8 *buf, int len)
583{ 583{
584 struct tda1004x_state* state = fe->demodulator_priv; 584 struct tda1004x_state* state = fe->demodulator_priv;
585 585
586 return tda1004x_write_byteI(state, reg, data); 586 if (len != 2)
587 return -EINVAL;
588
589 return tda1004x_write_byteI(state, buf[0], buf[1]);
587} 590}
588 591
589static int tda10045_init(struct dvb_frontend* fe) 592static int tda10045_init(struct dvb_frontend* fe)
@@ -1216,6 +1219,7 @@ static struct dvb_frontend_ops tda10045_ops = {
1216 1219
1217 .init = tda10045_init, 1220 .init = tda10045_init,
1218 .sleep = tda1004x_sleep, 1221 .sleep = tda1004x_sleep,
1222 .write = tda1004x_write,
1219 .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, 1223 .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
1220 1224
1221 .set_frontend = tda1004x_set_fe, 1225 .set_frontend = tda1004x_set_fe,
@@ -1274,6 +1278,7 @@ static struct dvb_frontend_ops tda10046_ops = {
1274 1278
1275 .init = tda10046_init, 1279 .init = tda10046_init,
1276 .sleep = tda1004x_sleep, 1280 .sleep = tda1004x_sleep,
1281 .write = tda1004x_write,
1277 .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl, 1282 .i2c_gate_ctrl = tda1004x_i2c_gate_ctrl,
1278 1283
1279 .set_frontend = tda1004x_set_fe, 1284 .set_frontend = tda1004x_set_fe,
@@ -1323,4 +1328,3 @@ MODULE_LICENSE("GPL");
1323 1328
1324EXPORT_SYMBOL(tda10045_attach); 1329EXPORT_SYMBOL(tda10045_attach);
1325EXPORT_SYMBOL(tda10046_attach); 1330EXPORT_SYMBOL(tda10046_attach);
1326EXPORT_SYMBOL(tda1004x_write_byte);
diff --git a/drivers/media/dvb/frontends/tda1004x.h b/drivers/media/dvb/frontends/tda1004x.h
index b877b23ed734..e28fca05734c 100644
--- a/drivers/media/dvb/frontends/tda1004x.h
+++ b/drivers/media/dvb/frontends/tda1004x.h
@@ -71,12 +71,33 @@ struct tda1004x_config
71 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name); 71 int (*request_firmware)(struct dvb_frontend* fe, const struct firmware **fw, char* name);
72}; 72};
73 73
74#if defined(CONFIG_DVB_TDA1004X) || defined(CONFIG_DVB_TDA1004X_MODULE)
74extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config, 75extern struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
75 struct i2c_adapter* i2c); 76 struct i2c_adapter* i2c);
76 77
77extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config, 78extern struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
78 struct i2c_adapter* i2c); 79 struct i2c_adapter* i2c);
79 80#else
80extern int tda1004x_write_byte(struct dvb_frontend* fe, int reg, int data); 81static inline struct dvb_frontend* tda10045_attach(const struct tda1004x_config* config,
82 struct i2c_adapter* i2c)
83{
84 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
85 return NULL;
86}
87static inline struct dvb_frontend* tda10046_attach(const struct tda1004x_config* config,
88 struct i2c_adapter* i2c)
89{
90 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
91 return NULL;
92}
93#endif // CONFIG_DVB_TDA1004X
94
95static inline int tda1004x_writereg(struct dvb_frontend *fe, u8 reg, u8 val) {
96 int r = 0;
97 u8 buf[] = {reg, val};
98 if (fe->ops.write)
99 r = fe->ops.write(fe, buf, 2);
100 return r;
101}
81 102
82#endif // TDA1004X_H 103#endif // TDA1004X_H
diff --git a/drivers/media/dvb/frontends/tda10086.c b/drivers/media/dvb/frontends/tda10086.c
new file mode 100644
index 000000000000..7456b0b9976b
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10086.c
@@ -0,0 +1,740 @@
1 /*
2 Driver for Philips tda10086 DVBS Demodulator
3
4 (c) 2006 Andrew de Quincey
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
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/moduleparam.h>
26#include <linux/device.h>
27#include <linux/jiffies.h>
28#include <linux/string.h>
29#include <linux/slab.h>
30
31#include "dvb_frontend.h"
32#include "tda10086.h"
33
34#define SACLK 96000000
35
36struct tda10086_state {
37 struct i2c_adapter* i2c;
38 const struct tda10086_config* config;
39 struct dvb_frontend frontend;
40
41 /* private demod data */
42 u32 frequency;
43 u32 symbol_rate;
44};
45
46static int debug = 0;
47#define dprintk(args...) \
48 do { \
49 if (debug) printk(KERN_DEBUG "tda10086: " args); \
50 } while (0)
51
52static int tda10086_write_byte(struct tda10086_state *state, int reg, int data)
53{
54 int ret;
55 u8 b0[] = { reg, data };
56 struct i2c_msg msg = { .flags = 0, .buf = b0, .len = 2 };
57
58 msg.addr = state->config->demod_address;
59 ret = i2c_transfer(state->i2c, &msg, 1);
60
61 if (ret != 1)
62 dprintk("%s: error reg=0x%x, data=0x%x, ret=%i\n",
63 __FUNCTION__, reg, data, ret);
64
65 return (ret != 1) ? ret : 0;
66}
67
68static int tda10086_read_byte(struct tda10086_state *state, int reg)
69{
70 int ret;
71 u8 b0[] = { reg };
72 u8 b1[] = { 0 };
73 struct i2c_msg msg[] = {{ .flags = 0, .buf = b0, .len = 1 },
74 { .flags = I2C_M_RD, .buf = b1, .len = 1 }};
75
76 msg[0].addr = state->config->demod_address;
77 msg[1].addr = state->config->demod_address;
78 ret = i2c_transfer(state->i2c, msg, 2);
79
80 if (ret != 2) {
81 dprintk("%s: error reg=0x%x, ret=%i\n", __FUNCTION__, reg,
82 ret);
83 return ret;
84 }
85
86 return b1[0];
87}
88
89static int tda10086_write_mask(struct tda10086_state *state, int reg, int mask, int data)
90{
91 int val;
92
93 // read a byte and check
94 val = tda10086_read_byte(state, reg);
95 if (val < 0)
96 return val;
97
98 // mask if off
99 val = val & ~mask;
100 val |= data & 0xff;
101
102 // write it out again
103 return tda10086_write_byte(state, reg, val);
104}
105
106static int tda10086_init(struct dvb_frontend* fe)
107{
108 struct tda10086_state* state = fe->demodulator_priv;
109
110 dprintk ("%s\n", __FUNCTION__);
111
112 // reset
113 tda10086_write_byte(state, 0x00, 0x00);
114 msleep(10);
115
116 // misc setup
117 tda10086_write_byte(state, 0x01, 0x94);
118 tda10086_write_byte(state, 0x02, 0x35); // NOTE: TT drivers appear to disable CSWP
119 tda10086_write_byte(state, 0x03, 0x64);
120 tda10086_write_byte(state, 0x04, 0x43);
121 tda10086_write_byte(state, 0x0c, 0x0c);
122 tda10086_write_byte(state, 0x1b, 0xb0); // noise threshold
123 tda10086_write_byte(state, 0x20, 0x89); // misc
124 tda10086_write_byte(state, 0x30, 0x04); // acquisition period length
125 tda10086_write_byte(state, 0x32, 0x00); // irq off
126 tda10086_write_byte(state, 0x31, 0x56); // setup AFC
127
128 // setup PLL (assumes 16Mhz XIN)
129 tda10086_write_byte(state, 0x55, 0x2c); // misc PLL setup
130 tda10086_write_byte(state, 0x3a, 0x0b); // M=12
131 tda10086_write_byte(state, 0x3b, 0x01); // P=2
132 tda10086_write_mask(state, 0x55, 0x20, 0x00); // powerup PLL
133
134 // setup TS interface
135 tda10086_write_byte(state, 0x11, 0x81);
136 tda10086_write_byte(state, 0x12, 0x81);
137 tda10086_write_byte(state, 0x19, 0x40); // parallel mode A + MSBFIRST
138 tda10086_write_byte(state, 0x56, 0x80); // powerdown WPLL - unused in the mode we use
139 tda10086_write_byte(state, 0x57, 0x08); // bypass WPLL - unused in the mode we use
140 tda10086_write_byte(state, 0x10, 0x2a);
141
142 // setup ADC
143 tda10086_write_byte(state, 0x58, 0x61); // ADC setup
144 tda10086_write_mask(state, 0x58, 0x01, 0x00); // powerup ADC
145
146 // setup AGC
147 tda10086_write_byte(state, 0x05, 0x0B);
148 tda10086_write_byte(state, 0x37, 0x63);
149 tda10086_write_byte(state, 0x3f, 0x03); // NOTE: flydvb uses 0x0a and varies it
150 tda10086_write_byte(state, 0x40, 0x64);
151 tda10086_write_byte(state, 0x41, 0x4f);
152 tda10086_write_byte(state, 0x42, 0x43);
153
154 // setup viterbi
155 tda10086_write_byte(state, 0x1a, 0x11); // VBER 10^6, DVB, QPSK
156
157 // setup carrier recovery
158 tda10086_write_byte(state, 0x3d, 0x80);
159
160 // setup SEC
161 tda10086_write_byte(state, 0x36, 0x00); // all SEC off
162 tda10086_write_byte(state, 0x34, (((1<<19) * (22000/1000)) / (SACLK/1000))); // } tone frequency
163 tda10086_write_byte(state, 0x35, (((1<<19) * (22000/1000)) / (SACLK/1000)) >> 8); // }
164
165 return 0;
166}
167
168static void tda10086_diseqc_wait(struct tda10086_state *state)
169{
170 unsigned long timeout = jiffies + msecs_to_jiffies(200);
171 while (!(tda10086_read_byte(state, 0x50) & 0x01)) {
172 if(time_after(jiffies, timeout)) {
173 printk("%s: diseqc queue not ready, command may be lost.\n", __FUNCTION__);
174 break;
175 }
176 msleep(10);
177 }
178}
179
180static int tda10086_set_tone (struct dvb_frontend* fe, fe_sec_tone_mode_t tone)
181{
182 struct tda10086_state* state = fe->demodulator_priv;
183
184 dprintk ("%s\n", __FUNCTION__);
185
186 switch(tone) {
187 case SEC_TONE_OFF:
188 tda10086_write_byte(state, 0x36, 0x00);
189 break;
190
191 case SEC_TONE_ON:
192 tda10086_write_byte(state, 0x36, 0x01);
193 break;
194 }
195
196 return 0;
197}
198
199static int tda10086_send_master_cmd (struct dvb_frontend* fe,
200 struct dvb_diseqc_master_cmd* cmd)
201{
202 struct tda10086_state* state = fe->demodulator_priv;
203 int i;
204 u8 oldval;
205
206 dprintk ("%s\n", __FUNCTION__);
207
208 if (cmd->msg_len > 6)
209 return -EINVAL;
210 oldval = tda10086_read_byte(state, 0x36);
211
212 for(i=0; i< cmd->msg_len; i++) {
213 tda10086_write_byte(state, 0x48+i, cmd->msg[i]);
214 }
215 tda10086_write_byte(state, 0x36, 0x08 | ((cmd->msg_len + 1) << 4));
216
217 tda10086_diseqc_wait(state);
218
219 tda10086_write_byte(state, 0x36, oldval);
220
221 return 0;
222}
223
224static int tda10086_send_burst (struct dvb_frontend* fe, fe_sec_mini_cmd_t minicmd)
225{
226 struct tda10086_state* state = fe->demodulator_priv;
227 u8 oldval = tda10086_read_byte(state, 0x36);
228
229 dprintk ("%s\n", __FUNCTION__);
230
231 switch(minicmd) {
232 case SEC_MINI_A:
233 tda10086_write_byte(state, 0x36, 0x04);
234 break;
235
236 case SEC_MINI_B:
237 tda10086_write_byte(state, 0x36, 0x06);
238 break;
239 }
240
241 tda10086_diseqc_wait(state);
242
243 tda10086_write_byte(state, 0x36, oldval);
244
245 return 0;
246}
247
248static int tda10086_set_inversion(struct tda10086_state *state,
249 struct dvb_frontend_parameters *fe_params)
250{
251 u8 invval = 0x80;
252
253 dprintk ("%s %i %i\n", __FUNCTION__, fe_params->inversion, state->config->invert);
254
255 switch(fe_params->inversion) {
256 case INVERSION_OFF:
257 if (state->config->invert)
258 invval = 0x40;
259 break;
260 case INVERSION_ON:
261 if (!state->config->invert)
262 invval = 0x40;
263 break;
264 case INVERSION_AUTO:
265 invval = 0x00;
266 break;
267 }
268 tda10086_write_mask(state, 0x0c, 0xc0, invval);
269
270 return 0;
271}
272
273static int tda10086_set_symbol_rate(struct tda10086_state *state,
274 struct dvb_frontend_parameters *fe_params)
275{
276 u8 dfn = 0;
277 u8 afs = 0;
278 u8 byp = 0;
279 u8 reg37 = 0x43;
280 u8 reg42 = 0x43;
281 u64 big;
282 u32 tmp;
283 u32 bdr;
284 u32 bdri;
285 u32 symbol_rate = fe_params->u.qpsk.symbol_rate;
286
287 dprintk ("%s %i\n", __FUNCTION__, symbol_rate);
288
289 // setup the decimation and anti-aliasing filters..
290 if (symbol_rate < (u32) (SACLK * 0.0137)) {
291 dfn=4;
292 afs=1;
293 } else if (symbol_rate < (u32) (SACLK * 0.0208)) {
294 dfn=4;
295 afs=0;
296 } else if (symbol_rate < (u32) (SACLK * 0.0270)) {
297 dfn=3;
298 afs=1;
299 } else if (symbol_rate < (u32) (SACLK * 0.0416)) {
300 dfn=3;
301 afs=0;
302 } else if (symbol_rate < (u32) (SACLK * 0.0550)) {
303 dfn=2;
304 afs=1;
305 } else if (symbol_rate < (u32) (SACLK * 0.0833)) {
306 dfn=2;
307 afs=0;
308 } else if (symbol_rate < (u32) (SACLK * 0.1100)) {
309 dfn=1;
310 afs=1;
311 } else if (symbol_rate < (u32) (SACLK * 0.1666)) {
312 dfn=1;
313 afs=0;
314 } else if (symbol_rate < (u32) (SACLK * 0.2200)) {
315 dfn=0;
316 afs=1;
317 } else if (symbol_rate < (u32) (SACLK * 0.3333)) {
318 dfn=0;
319 afs=0;
320 } else {
321 reg37 = 0x63;
322 reg42 = 0x4f;
323 byp=1;
324 }
325
326 // calculate BDR
327 big = (1ULL<<21) * ((u64) symbol_rate/1000ULL) * (1ULL<<dfn);
328 big += ((SACLK/1000ULL)-1ULL);
329 do_div(big, (SACLK/1000ULL));
330 bdr = big & 0xfffff;
331
332 // calculate BDRI
333 tmp = (1<<dfn)*(symbol_rate/1000);
334 bdri = ((32 * (SACLK/1000)) + (tmp-1)) / tmp;
335
336 tda10086_write_byte(state, 0x21, (afs << 7) | dfn);
337 tda10086_write_mask(state, 0x20, 0x08, byp << 3);
338 tda10086_write_byte(state, 0x06, bdr);
339 tda10086_write_byte(state, 0x07, bdr >> 8);
340 tda10086_write_byte(state, 0x08, bdr >> 16);
341 tda10086_write_byte(state, 0x09, bdri);
342 tda10086_write_byte(state, 0x37, reg37);
343 tda10086_write_byte(state, 0x42, reg42);
344
345 return 0;
346}
347
348static int tda10086_set_fec(struct tda10086_state *state,
349 struct dvb_frontend_parameters *fe_params)
350{
351 u8 fecval;
352
353 dprintk ("%s %i\n", __FUNCTION__, fe_params->u.qpsk.fec_inner);
354
355 switch(fe_params->u.qpsk.fec_inner) {
356 case FEC_1_2:
357 fecval = 0x00;
358 break;
359 case FEC_2_3:
360 fecval = 0x01;
361 break;
362 case FEC_3_4:
363 fecval = 0x02;
364 break;
365 case FEC_4_5:
366 fecval = 0x03;
367 break;
368 case FEC_5_6:
369 fecval = 0x04;
370 break;
371 case FEC_6_7:
372 fecval = 0x05;
373 break;
374 case FEC_7_8:
375 fecval = 0x06;
376 break;
377 case FEC_8_9:
378 fecval = 0x07;
379 break;
380 case FEC_AUTO:
381 fecval = 0x08;
382 break;
383 default:
384 return -1;
385 }
386 tda10086_write_byte(state, 0x0d, fecval);
387
388 return 0;
389}
390
391static int tda10086_set_frontend(struct dvb_frontend* fe,
392 struct dvb_frontend_parameters *fe_params)
393{
394 struct tda10086_state *state = fe->demodulator_priv;
395 int ret;
396 u32 freq = 0;
397 int freqoff;
398
399 dprintk ("%s\n", __FUNCTION__);
400
401 // set params
402 if (fe->ops.tuner_ops.set_params) {
403 fe->ops.tuner_ops.set_params(fe, fe_params);
404 if (fe->ops.i2c_gate_ctrl)
405 fe->ops.i2c_gate_ctrl(fe, 0);
406
407 if (fe->ops.tuner_ops.get_frequency)
408 fe->ops.tuner_ops.get_frequency(fe, &freq);
409 if (fe->ops.i2c_gate_ctrl)
410 fe->ops.i2c_gate_ctrl(fe, 0);
411 }
412
413 // calcluate the frequency offset (in *Hz* not kHz)
414 freqoff = fe_params->frequency - freq;
415 freqoff = ((1<<16) * freqoff) / (SACLK/1000);
416 tda10086_write_byte(state, 0x3d, 0x80 | ((freqoff >> 8) & 0x7f));
417 tda10086_write_byte(state, 0x3e, freqoff);
418
419 if ((ret = tda10086_set_inversion(state, fe_params)) < 0)
420 return ret;
421 if ((ret = tda10086_set_symbol_rate(state, fe_params)) < 0)
422 return ret;
423 if ((ret = tda10086_set_fec(state, fe_params)) < 0)
424 return ret;
425
426 // soft reset + disable TS output until lock
427 tda10086_write_mask(state, 0x10, 0x40, 0x40);
428 tda10086_write_mask(state, 0x00, 0x01, 0x00);
429
430 state->symbol_rate = fe_params->u.qpsk.symbol_rate;
431 state->frequency = fe_params->frequency;
432 return 0;
433}
434
435static int tda10086_get_frontend(struct dvb_frontend* fe, struct dvb_frontend_parameters *fe_params)
436{
437 struct tda10086_state* state = fe->demodulator_priv;
438 u8 val;
439 int tmp;
440 u64 tmp64;
441
442 dprintk ("%s\n", __FUNCTION__);
443
444 // calculate the updated frequency (note: we convert from Hz->kHz)
445 tmp64 = tda10086_read_byte(state, 0x52);
446 tmp64 |= (tda10086_read_byte(state, 0x51) << 8);
447 if (tmp64 & 0x8000)
448 tmp64 |= 0xffffffffffff0000ULL;
449 tmp64 = (tmp64 * (SACLK/1000ULL));
450 do_div(tmp64, (1ULL<<15) * (1ULL<<1));
451 fe_params->frequency = (int) state->frequency + (int) tmp64;
452
453 // the inversion
454 val = tda10086_read_byte(state, 0x0c);
455 if (val & 0x80) {
456 switch(val & 0x40) {
457 case 0x00:
458 fe_params->inversion = INVERSION_OFF;
459 if (state->config->invert)
460 fe_params->inversion = INVERSION_ON;
461 break;
462 default:
463 fe_params->inversion = INVERSION_ON;
464 if (state->config->invert)
465 fe_params->inversion = INVERSION_OFF;
466 break;
467 }
468 } else {
469 tda10086_read_byte(state, 0x0f);
470 switch(val & 0x02) {
471 case 0x00:
472 fe_params->inversion = INVERSION_OFF;
473 if (state->config->invert)
474 fe_params->inversion = INVERSION_ON;
475 break;
476 default:
477 fe_params->inversion = INVERSION_ON;
478 if (state->config->invert)
479 fe_params->inversion = INVERSION_OFF;
480 break;
481 }
482 }
483
484 // calculate the updated symbol rate
485 tmp = tda10086_read_byte(state, 0x1d);
486 if (tmp & 0x80)
487 tmp |= 0xffffff00;
488 tmp = (tmp * 480 * (1<<1)) / 128;
489 tmp = ((state->symbol_rate/1000) * tmp) / (1000000/1000);
490 fe_params->u.qpsk.symbol_rate = state->symbol_rate + tmp;
491
492 // the FEC
493 val = (tda10086_read_byte(state, 0x0d) & 0x70) >> 4;
494 switch(val) {
495 case 0x00:
496 fe_params->u.qpsk.fec_inner = FEC_1_2;
497 break;
498 case 0x01:
499 fe_params->u.qpsk.fec_inner = FEC_2_3;
500 break;
501 case 0x02:
502 fe_params->u.qpsk.fec_inner = FEC_3_4;
503 break;
504 case 0x03:
505 fe_params->u.qpsk.fec_inner = FEC_4_5;
506 break;
507 case 0x04:
508 fe_params->u.qpsk.fec_inner = FEC_5_6;
509 break;
510 case 0x05:
511 fe_params->u.qpsk.fec_inner = FEC_6_7;
512 break;
513 case 0x06:
514 fe_params->u.qpsk.fec_inner = FEC_7_8;
515 break;
516 case 0x07:
517 fe_params->u.qpsk.fec_inner = FEC_8_9;
518 break;
519 }
520
521 return 0;
522}
523
524static int tda10086_read_status(struct dvb_frontend* fe, fe_status_t *fe_status)
525{
526 struct tda10086_state* state = fe->demodulator_priv;
527 u8 val;
528
529 dprintk ("%s\n", __FUNCTION__);
530
531 val = tda10086_read_byte(state, 0x0e);
532 *fe_status = 0;
533 if (val & 0x01)
534 *fe_status |= FE_HAS_SIGNAL;
535 if (val & 0x02)
536 *fe_status |= FE_HAS_CARRIER;
537 if (val & 0x04)
538 *fe_status |= FE_HAS_VITERBI;
539 if (val & 0x08)
540 *fe_status |= FE_HAS_SYNC;
541 if (val & 0x10)
542 *fe_status |= FE_HAS_LOCK;
543
544 return 0;
545}
546
547static int tda10086_read_signal_strength(struct dvb_frontend* fe, u16 * signal)
548{
549 struct tda10086_state* state = fe->demodulator_priv;
550 u8 _str;
551
552 dprintk ("%s\n", __FUNCTION__);
553
554 _str = tda10086_read_byte(state, 0x43);
555 *signal = (_str << 8) | _str;
556
557 return 0;
558}
559
560static int tda10086_read_snr(struct dvb_frontend* fe, u16 * snr)
561{
562 struct tda10086_state* state = fe->demodulator_priv;
563 u8 _snr;
564
565 dprintk ("%s\n", __FUNCTION__);
566
567 _snr = tda10086_read_byte(state, 0x1c);
568 *snr = (_snr << 8) | _snr;
569
570 return 0;
571}
572
573static int tda10086_read_ucblocks(struct dvb_frontend* fe, u32* ucblocks)
574{
575 struct tda10086_state* state = fe->demodulator_priv;
576
577 dprintk ("%s\n", __FUNCTION__);
578
579 // read it
580 *ucblocks = tda10086_read_byte(state, 0x18) & 0x7f;
581
582 // reset counter
583 tda10086_write_byte(state, 0x18, 0x00);
584 tda10086_write_byte(state, 0x18, 0x80);
585
586 return 0;
587}
588
589static int tda10086_read_ber(struct dvb_frontend* fe, u32* ber)
590{
591 struct tda10086_state* state = fe->demodulator_priv;
592
593 dprintk ("%s\n", __FUNCTION__);
594
595 // read it
596 *ber = 0;
597 *ber |= tda10086_read_byte(state, 0x15);
598 *ber |= tda10086_read_byte(state, 0x16) << 8;
599 *ber |= (tda10086_read_byte(state, 0x17) & 0xf) << 16;
600
601 return 0;
602}
603
604static int tda10086_sleep(struct dvb_frontend* fe)
605{
606 struct tda10086_state* state = fe->demodulator_priv;
607
608 dprintk ("%s\n", __FUNCTION__);
609
610 tda10086_write_mask(state, 0x00, 0x08, 0x08);
611
612 return 0;
613}
614
615static int tda10086_i2c_gate_ctrl(struct dvb_frontend* fe, int enable)
616{
617 struct tda10086_state* state = fe->demodulator_priv;
618
619 dprintk ("%s\n", __FUNCTION__);
620
621 if (enable) {
622 tda10086_write_mask(state, 0x00, 0x10, 0x10);
623 } else {
624 tda10086_write_mask(state, 0x00, 0x10, 0x00);
625 }
626
627 return 0;
628}
629
630static int tda10086_get_tune_settings(struct dvb_frontend* fe, struct dvb_frontend_tune_settings* fesettings)
631{
632 if (fesettings->parameters.u.qpsk.symbol_rate > 20000000) {
633 fesettings->min_delay_ms = 50;
634 fesettings->step_size = 2000;
635 fesettings->max_drift = 8000;
636 } else if (fesettings->parameters.u.qpsk.symbol_rate > 12000000) {
637 fesettings->min_delay_ms = 100;
638 fesettings->step_size = 1500;
639 fesettings->max_drift = 9000;
640 } else if (fesettings->parameters.u.qpsk.symbol_rate > 8000000) {
641 fesettings->min_delay_ms = 100;
642 fesettings->step_size = 1000;
643 fesettings->max_drift = 8000;
644 } else if (fesettings->parameters.u.qpsk.symbol_rate > 4000000) {
645 fesettings->min_delay_ms = 100;
646 fesettings->step_size = 500;
647 fesettings->max_drift = 7000;
648 } else if (fesettings->parameters.u.qpsk.symbol_rate > 2000000) {
649 fesettings->min_delay_ms = 200;
650 fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
651 fesettings->max_drift = 14 * fesettings->step_size;
652 } else {
653 fesettings->min_delay_ms = 200;
654 fesettings->step_size = (fesettings->parameters.u.qpsk.symbol_rate / 8000);
655 fesettings->max_drift = 18 * fesettings->step_size;
656 }
657
658 return 0;
659}
660
661static void tda10086_release(struct dvb_frontend* fe)
662{
663 struct tda10086_state *state = fe->demodulator_priv;
664 tda10086_sleep(fe);
665 kfree(state);
666}
667
668static struct dvb_frontend_ops tda10086_ops = {
669
670 .info = {
671 .name = "Philips TDA10086 DVB-S",
672 .type = FE_QPSK,
673 .frequency_min = 950000,
674 .frequency_max = 2150000,
675 .frequency_stepsize = 125, /* kHz for QPSK frontends */
676 .symbol_rate_min = 1000000,
677 .symbol_rate_max = 45000000,
678 .caps = FE_CAN_INVERSION_AUTO |
679 FE_CAN_FEC_1_2 | FE_CAN_FEC_2_3 | FE_CAN_FEC_3_4 |
680 FE_CAN_FEC_5_6 | FE_CAN_FEC_6_7 | FE_CAN_FEC_7_8 | FE_CAN_FEC_AUTO |
681 FE_CAN_QPSK
682 },
683
684 .release = tda10086_release,
685
686 .init = tda10086_init,
687 .sleep = tda10086_sleep,
688 .i2c_gate_ctrl = tda10086_i2c_gate_ctrl,
689
690 .set_frontend = tda10086_set_frontend,
691 .get_frontend = tda10086_get_frontend,
692 .get_tune_settings = tda10086_get_tune_settings,
693
694 .read_status = tda10086_read_status,
695 .read_ber = tda10086_read_ber,
696 .read_signal_strength = tda10086_read_signal_strength,
697 .read_snr = tda10086_read_snr,
698 .read_ucblocks = tda10086_read_ucblocks,
699
700 .diseqc_send_master_cmd = tda10086_send_master_cmd,
701 .diseqc_send_burst = tda10086_send_burst,
702 .set_tone = tda10086_set_tone,
703};
704
705struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
706 struct i2c_adapter* i2c)
707{
708 struct tda10086_state *state;
709
710 dprintk ("%s\n", __FUNCTION__);
711
712 /* allocate memory for the internal state */
713 state = kmalloc(sizeof(struct tda10086_state), GFP_KERNEL);
714 if (!state)
715 return NULL;
716
717 /* setup the state */
718 state->config = config;
719 state->i2c = i2c;
720
721 /* check if the demod is there */
722 if (tda10086_read_byte(state, 0x1e) != 0xe1) {
723 kfree(state);
724 return NULL;
725 }
726
727 /* create dvb_frontend */
728 memcpy(&state->frontend.ops, &tda10086_ops, sizeof(struct dvb_frontend_ops));
729 state->frontend.demodulator_priv = state;
730 return &state->frontend;
731}
732
733module_param(debug, int, 0644);
734MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
735
736MODULE_DESCRIPTION("Philips TDA10086 DVB-S Demodulator");
737MODULE_AUTHOR("Andrew de Quincey");
738MODULE_LICENSE("GPL");
739
740EXPORT_SYMBOL(tda10086_attach);
diff --git a/drivers/media/dvb/frontends/tda10086.h b/drivers/media/dvb/frontends/tda10086.h
new file mode 100644
index 000000000000..e8061db11123
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda10086.h
@@ -0,0 +1,41 @@
1 /*
2 Driver for Philips tda10086 DVBS Frontend
3
4 (c) 2006 Andrew de Quincey
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
23#ifndef TDA10086_H
24#define TDA10086_H
25
26#include <linux/dvb/frontend.h>
27#include <linux/firmware.h>
28
29struct tda10086_config
30{
31 /* the demodulator's i2c address */
32 u8 demod_address;
33
34 /* does the "inversion" need inverted? */
35 u8 invert;
36};
37
38extern struct dvb_frontend* tda10086_attach(const struct tda10086_config* config,
39 struct i2c_adapter* i2c);
40
41#endif // TDA10086_H
diff --git a/drivers/media/dvb/frontends/tda8083.h b/drivers/media/dvb/frontends/tda8083.h
index e7a48f61ea2c..aae15bdce6eb 100644
--- a/drivers/media/dvb/frontends/tda8083.h
+++ b/drivers/media/dvb/frontends/tda8083.h
@@ -35,7 +35,16 @@ struct tda8083_config
35 u8 demod_address; 35 u8 demod_address;
36}; 36};
37 37
38#if defined(CONFIG_DVB_TDA8083) || defined(CONFIG_DVB_TDA8083_MODULE)
38extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config, 39extern struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
39 struct i2c_adapter* i2c); 40 struct i2c_adapter* i2c);
41#else
42static inline struct dvb_frontend* tda8083_attach(const struct tda8083_config* config,
43 struct i2c_adapter* i2c)
44{
45 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
46 return NULL;
47}
48#endif // CONFIG_DVB_TDA8083
40 49
41#endif // TDA8083_H 50#endif // TDA8083_H
diff --git a/drivers/media/dvb/frontends/tda826x.c b/drivers/media/dvb/frontends/tda826x.c
new file mode 100644
index 000000000000..eeab26bd36ed
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda826x.c
@@ -0,0 +1,173 @@
1 /*
2 Driver for Philips tda8262/tda8263 DVBS Silicon tuners
3
4 (c) 2006 Andrew de Quincey
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
23#include <linux/module.h>
24#include <linux/dvb/frontend.h>
25#include <asm/types.h>
26
27#include "tda826x.h"
28
29static int debug = 0;
30#define dprintk(args...) \
31 do { \
32 if (debug) printk(KERN_DEBUG "tda826x: " args); \
33 } while (0)
34
35struct tda826x_priv {
36 /* i2c details */
37 int i2c_address;
38 struct i2c_adapter *i2c;
39 u8 has_loopthrough:1;
40 u32 frequency;
41};
42
43static int tda826x_release(struct dvb_frontend *fe)
44{
45 if (fe->tuner_priv)
46 kfree(fe->tuner_priv);
47 fe->tuner_priv = NULL;
48 return 0;
49}
50
51static int tda826x_sleep(struct dvb_frontend *fe)
52{
53 struct tda826x_priv *priv = fe->tuner_priv;
54 int ret;
55 u8 buf [] = { 0x00, 0x8d };
56 struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 2 };
57
58 dprintk("%s:\n", __FUNCTION__);
59
60 if (!priv->has_loopthrough)
61 buf[1] = 0xad;
62
63 if (fe->ops.i2c_gate_ctrl)
64 fe->ops.i2c_gate_ctrl(fe, 1);
65 if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
66 dprintk("%s: i2c error\n", __FUNCTION__);
67 }
68 if (fe->ops.i2c_gate_ctrl)
69 fe->ops.i2c_gate_ctrl(fe, 0);
70
71 return (ret == 1) ? 0 : ret;
72}
73
74static int tda826x_set_params(struct dvb_frontend *fe, struct dvb_frontend_parameters *params)
75{
76 struct tda826x_priv *priv = fe->tuner_priv;
77 int ret;
78 u32 div;
79 u8 buf [11];
80 struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = buf, .len = 11 };
81
82 dprintk("%s:\n", __FUNCTION__);
83
84 div = (params->frequency + (1000-1)) / 1000;
85
86 buf[0] = 0x00; // subaddress
87 buf[1] = 0x09; // powerdown RSSI + the magic value 1
88 if (!priv->has_loopthrough)
89 buf[1] |= 0x20; // power down loopthrough if not needed
90 buf[2] = (1<<5) | 0x0b; // 1Mhz + 0.45 VCO
91 buf[3] = div >> 7;
92 buf[4] = div << 1;
93 buf[5] = 0xff; // basedband filter to max
94 buf[6] = 0xfe; // gains at max + no RF attenuation
95 buf[7] = 0x83; // charge pumps at high, tests off
96 buf[8] = 0x80; // recommended value 4 for AMPVCO + disable ports.
97 buf[9] = 0x1a; // normal caltime + recommended values for SELTH + SELVTL
98 buf[10] = 0xd4; // recommended value 13 for BBIAS + unknown bit set on
99
100 if (fe->ops.i2c_gate_ctrl)
101 fe->ops.i2c_gate_ctrl(fe, 1);
102 if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
103 dprintk("%s: i2c error\n", __FUNCTION__);
104 }
105 if (fe->ops.i2c_gate_ctrl)
106 fe->ops.i2c_gate_ctrl(fe, 0);
107
108 priv->frequency = div * 1000;
109
110 return (ret == 1) ? 0 : ret;
111}
112
113static int tda826x_get_frequency(struct dvb_frontend *fe, u32 *frequency)
114{
115 struct tda826x_priv *priv = fe->tuner_priv;
116 *frequency = priv->frequency;
117 return 0;
118}
119
120static struct dvb_tuner_ops tda826x_tuner_ops = {
121 .info = {
122 .name = "Philips TDA826X",
123 .frequency_min = 950000,
124 .frequency_min = 2175000
125 },
126 .release = tda826x_release,
127 .sleep = tda826x_sleep,
128 .set_params = tda826x_set_params,
129 .get_frequency = tda826x_get_frequency,
130};
131
132struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough)
133{
134 struct tda826x_priv *priv = NULL;
135 u8 b1 [] = { 0, 0 };
136 struct i2c_msg msg = { .addr = addr, .flags = I2C_M_RD, .buf = b1, .len = 2 };
137 int ret;
138
139 dprintk("%s:\n", __FUNCTION__);
140
141 if (fe->ops.i2c_gate_ctrl)
142 fe->ops.i2c_gate_ctrl(fe, 1);
143 ret = i2c_transfer (i2c, &msg, 1);
144 if (fe->ops.i2c_gate_ctrl)
145 fe->ops.i2c_gate_ctrl(fe, 0);
146
147 if (ret != 1)
148 return NULL;
149 if (!(b1[1] & 0x80))
150 return NULL;
151
152 priv = kzalloc(sizeof(struct tda826x_priv), GFP_KERNEL);
153 if (priv == NULL)
154 return NULL;
155
156 priv->i2c_address = addr;
157 priv->i2c = i2c;
158 priv->has_loopthrough = has_loopthrough;
159
160 memcpy(&fe->ops.tuner_ops, &tda826x_tuner_ops, sizeof(struct dvb_tuner_ops));
161
162 fe->tuner_priv = priv;
163
164 return fe;
165}
166EXPORT_SYMBOL(tda826x_attach);
167
168module_param(debug, int, 0644);
169MODULE_PARM_DESC(debug, "Turn on/off frontend debugging (default:off).");
170
171MODULE_DESCRIPTION("DVB TDA826x driver");
172MODULE_AUTHOR("Andrew de Quincey");
173MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tda826x.h b/drivers/media/dvb/frontends/tda826x.h
new file mode 100644
index 000000000000..3307607632b0
--- /dev/null
+++ b/drivers/media/dvb/frontends/tda826x.h
@@ -0,0 +1,40 @@
1 /*
2 Driver for Philips tda8262/tda8263 DVBS Silicon tuners
3
4 (c) 2006 Andrew de Quincey
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
23#ifndef __DVB_TDA826X_H__
24#define __DVB_TDA826X_H__
25
26#include <linux/i2c.h>
27#include "dvb_frontend.h"
28
29/**
30 * Attach a tda826x tuner to the supplied frontend structure.
31 *
32 * @param fe Frontend to attach to.
33 * @param addr i2c address of the tuner.
34 * @param i2c i2c adapter to use.
35 * @param has_loopthrough Set to 1 if the card has a loopthrough RF connector.
36 * @return FE pointer on success, NULL on failure.
37 */
38extern struct dvb_frontend *tda826x_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c, int has_loopthrough);
39
40#endif
diff --git a/drivers/media/dvb/frontends/tua6100.c b/drivers/media/dvb/frontends/tua6100.c
new file mode 100644
index 000000000000..88554393a9bf
--- /dev/null
+++ b/drivers/media/dvb/frontends/tua6100.c
@@ -0,0 +1,205 @@
1/**
2 * Driver for Infineon tua6100 pll.
3 *
4 * (c) 2006 Andrew de Quincey
5 *
6 * Based on code found in budget-av.c, which has the following:
7 * Compiled from various sources by Michael Hunold <michael@mihu.de>
8 *
9 * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
10 * Andrew de Quincey <adq_dvb@lidskialf.net>
11 *
12 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
13 *
14 * Copyright (C) 1999-2002 Ralph Metzler
15 * & Marcus Metzler for convergence integrated media GmbH
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#include <linux/module.h>
32#include <linux/dvb/frontend.h>
33#include <asm/types.h>
34
35#include "tua6100.h"
36
37struct tua6100_priv {
38 /* i2c details */
39 int i2c_address;
40 struct i2c_adapter *i2c;
41 u32 frequency;
42};
43
44static int tua6100_release(struct dvb_frontend *fe)
45{
46 if (fe->tuner_priv)
47 kfree(fe->tuner_priv);
48 fe->tuner_priv = NULL;
49 return 0;
50}
51
52static int tua6100_sleep(struct dvb_frontend *fe)
53{
54 struct tua6100_priv *priv = fe->tuner_priv;
55 int ret;
56 u8 reg0[] = { 0x00, 0x00 };
57 struct i2c_msg msg = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 };
58
59 if (fe->ops.i2c_gate_ctrl)
60 fe->ops.i2c_gate_ctrl(fe, 1);
61 if ((ret = i2c_transfer (priv->i2c, &msg, 1)) != 1) {
62 printk("%s: i2c error\n", __FUNCTION__);
63 }
64 if (fe->ops.i2c_gate_ctrl)
65 fe->ops.i2c_gate_ctrl(fe, 0);
66
67 return (ret == 1) ? 0 : ret;
68}
69
70static int tua6100_set_params(struct dvb_frontend *fe,
71 struct dvb_frontend_parameters *params)
72{
73 struct tua6100_priv *priv = fe->tuner_priv;
74 u32 div;
75 u32 prediv;
76 u8 reg0[] = { 0x00, 0x00 };
77 u8 reg1[] = { 0x01, 0x00, 0x00, 0x00 };
78 u8 reg2[] = { 0x02, 0x00, 0x00 };
79 struct i2c_msg msg0 = { .addr = priv->i2c_address, .flags = 0, .buf = reg0, .len = 2 };
80 struct i2c_msg msg1 = { .addr = priv->i2c_address, .flags = 0, .buf = reg1, .len = 4 };
81 struct i2c_msg msg2 = { .addr = priv->i2c_address, .flags = 0, .buf = reg2, .len = 3 };
82
83#define _R 4
84#define _P 32
85#define _ri 4000000
86
87 // setup register 0
88 if (params->frequency < 2000000) {
89 reg0[1] = 0x03;
90 } else {
91 reg0[1] = 0x07;
92 }
93
94 // setup register 1
95 if (params->frequency < 1630000) {
96 reg1[1] = 0x2c;
97 } else {
98 reg1[1] = 0x0c;
99 }
100 if (_P == 64)
101 reg1[1] |= 0x40;
102 if (params->frequency >= 1525000)
103 reg1[1] |= 0x80;
104
105 // register 2
106 reg2[1] = (_R >> 8) & 0x03;
107 reg2[2] = _R;
108 if (params->frequency < 1455000) {
109 reg2[1] |= 0x1c;
110 } else if (params->frequency < 1630000) {
111 reg2[1] |= 0x0c;
112 } else {
113 reg2[1] |= 0x1c;
114 }
115
116 // The N divisor ratio (note: params->frequency is in kHz, but we need it in Hz)
117 prediv = (params->frequency * _R) / (_ri / 1000);
118 div = prediv / _P;
119 reg1[1] |= (div >> 9) & 0x03;
120 reg1[2] = div >> 1;
121 reg1[3] = (div << 7);
122 priv->frequency = ((div * _P) * (_ri / 1000)) / _R;
123
124 // Finally, calculate and store the value for A
125 reg1[3] |= (prediv - (div*_P)) & 0x7f;
126
127#undef _R
128#undef _P
129#undef _ri
130
131 if (fe->ops.i2c_gate_ctrl)
132 fe->ops.i2c_gate_ctrl(fe, 1);
133 if (i2c_transfer(priv->i2c, &msg0, 1) != 1)
134 return -EIO;
135
136 if (fe->ops.i2c_gate_ctrl)
137 fe->ops.i2c_gate_ctrl(fe, 1);
138 if (i2c_transfer(priv->i2c, &msg2, 1) != 1)
139 return -EIO;
140
141 if (fe->ops.i2c_gate_ctrl)
142 fe->ops.i2c_gate_ctrl(fe, 1);
143 if (i2c_transfer(priv->i2c, &msg1, 1) != 1)
144 return -EIO;
145
146 if (fe->ops.i2c_gate_ctrl)
147 fe->ops.i2c_gate_ctrl(fe, 0);
148
149 return 0;
150}
151
152static int tua6100_get_frequency(struct dvb_frontend *fe, u32 *frequency)
153{
154 struct tua6100_priv *priv = fe->tuner_priv;
155 *frequency = priv->frequency;
156 return 0;
157}
158
159static struct dvb_tuner_ops tua6100_tuner_ops = {
160 .info = {
161 .name = "Infineon TUA6100",
162 .frequency_min = 950000,
163 .frequency_max = 2150000,
164 .frequency_step = 1000,
165 },
166 .release = tua6100_release,
167 .sleep = tua6100_sleep,
168 .set_params = tua6100_set_params,
169 .get_frequency = tua6100_get_frequency,
170};
171
172struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
173{
174 struct tua6100_priv *priv = NULL;
175 u8 b1 [] = { 0x80 };
176 u8 b2 [] = { 0x00 };
177 struct i2c_msg msg [] = { { .addr = addr, .flags = 0, .buf = b1, .len = 1 },
178 { .addr = addr, .flags = I2C_M_RD, .buf = b2, .len = 1 } };
179 int ret;
180
181 if (fe->ops.i2c_gate_ctrl)
182 fe->ops.i2c_gate_ctrl(fe, 1);
183 ret = i2c_transfer (i2c, msg, 2);
184 if (fe->ops.i2c_gate_ctrl)
185 fe->ops.i2c_gate_ctrl(fe, 0);
186
187 if (ret != 2)
188 return NULL;
189
190 priv = kzalloc(sizeof(struct tua6100_priv), GFP_KERNEL);
191 if (priv == NULL)
192 return NULL;
193
194 priv->i2c_address = addr;
195 priv->i2c = i2c;
196
197 memcpy(&fe->ops.tuner_ops, &tua6100_tuner_ops, sizeof(struct dvb_tuner_ops));
198 fe->tuner_priv = priv;
199 return fe;
200}
201EXPORT_SYMBOL(tua6100_attach);
202
203MODULE_DESCRIPTION("DVB tua6100 driver");
204MODULE_AUTHOR("Andrew de Quincey");
205MODULE_LICENSE("GPL");
diff --git a/drivers/media/dvb/frontends/tua6100.h b/drivers/media/dvb/frontends/tua6100.h
new file mode 100644
index 000000000000..8f98033ffa7b
--- /dev/null
+++ b/drivers/media/dvb/frontends/tua6100.h
@@ -0,0 +1,47 @@
1/**
2 * Driver for Infineon tua6100 PLL.
3 *
4 * (c) 2006 Andrew de Quincey
5 *
6 * Based on code found in budget-av.c, which has the following:
7 * Compiled from various sources by Michael Hunold <michael@mihu.de>
8 *
9 * CI interface support (c) 2004 Olivier Gournet <ogournet@anevia.com> &
10 * Andrew de Quincey <adq_dvb@lidskialf.net>
11 *
12 * Copyright (C) 2002 Ralph Metzler <rjkm@metzlerbros.de>
13 *
14 * Copyright (C) 1999-2002 Ralph Metzler
15 * & Marcus Metzler for convergence integrated media GmbH
16 * This program is free software; you can redistribute it and/or modify
17 * it under the terms of the GNU General Public License as published by
18 * the Free Software Foundation; either version 2 of the License, or
19 * (at your option) any later version.
20 *
21 * This program is distributed in the hope that it will be useful,
22 * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 * GNU General Public License for more details.
25 *
26 * You should have received a copy of the GNU General Public License
27 * along with this program; if not, write to the Free Software
28 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
29 */
30
31#ifndef __DVB_TUA6100_H__
32#define __DVB_TUA6100_H__
33
34#include <linux/i2c.h>
35#include "dvb_frontend.h"
36
37#if defined(CONFIG_DVB_TUA6100) || defined(CONFIG_DVB_TUA6100_MODULE)
38extern struct dvb_frontend *tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c);
39#else
40static inline struct dvb_frontend* tua6100_attach(struct dvb_frontend *fe, int addr, struct i2c_adapter *i2c)
41{
42 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
43 return NULL;
44}
45#endif // CONFIG_DVB_TUA6100
46
47#endif
diff --git a/drivers/media/dvb/frontends/ves1820.h b/drivers/media/dvb/frontends/ves1820.h
index 520f09522fbb..f0c9dded39d7 100644
--- a/drivers/media/dvb/frontends/ves1820.h
+++ b/drivers/media/dvb/frontends/ves1820.h
@@ -41,7 +41,16 @@ struct ves1820_config
41 u8 selagc:1; 41 u8 selagc:1;
42}; 42};
43 43
44#if defined(CONFIG_DVB_VES1820) || defined(CONFIG_DVB_VES1820_MODULE)
44extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config, 45extern struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
45 struct i2c_adapter* i2c, u8 pwm); 46 struct i2c_adapter* i2c, u8 pwm);
47#else
48static inline struct dvb_frontend* ves1820_attach(const struct ves1820_config* config,
49 struct i2c_adapter* i2c, u8 pwm)
50{
51 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
52 return NULL;
53}
54#endif // CONFIG_DVB_VES1820
46 55
47#endif // VES1820_H 56#endif // VES1820_H
diff --git a/drivers/media/dvb/frontends/ves1x93.h b/drivers/media/dvb/frontends/ves1x93.h
index ba88ae0855c9..395fed39b286 100644
--- a/drivers/media/dvb/frontends/ves1x93.h
+++ b/drivers/media/dvb/frontends/ves1x93.h
@@ -40,7 +40,16 @@ struct ves1x93_config
40 u8 invert_pwm:1; 40 u8 invert_pwm:1;
41}; 41};
42 42
43#if defined(CONFIG_DVB_VES1X93) || defined(CONFIG_DVB_VES1X93_MODULE)
43extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config, 44extern struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
44 struct i2c_adapter* i2c); 45 struct i2c_adapter* i2c);
46#else
47static inline struct dvb_frontend* ves1x93_attach(const struct ves1x93_config* config,
48 struct i2c_adapter* i2c)
49{
50 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
51 return NULL;
52}
53#endif // CONFIG_DVB_VES1X93
45 54
46#endif // VES1X93_H 55#endif // VES1X93_H
diff --git a/drivers/media/dvb/frontends/zl10353.c b/drivers/media/dvb/frontends/zl10353.c
index 2b95e8b6cd39..0e9b59af271e 100644
--- a/drivers/media/dvb/frontends/zl10353.c
+++ b/drivers/media/dvb/frontends/zl10353.c
@@ -140,6 +140,8 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
140 zl10353_single_write(fe, 0x5E, 0x00); 140 zl10353_single_write(fe, 0x5E, 0x00);
141 zl10353_single_write(fe, 0x65, 0x5A); 141 zl10353_single_write(fe, 0x65, 0x5A);
142 zl10353_single_write(fe, 0x66, 0xE9); 142 zl10353_single_write(fe, 0x66, 0xE9);
143 zl10353_single_write(fe, 0x6C, 0xCD);
144 zl10353_single_write(fe, 0x6D, 0x7E);
143 zl10353_single_write(fe, 0x62, 0x0A); 145 zl10353_single_write(fe, 0x62, 0x0A);
144 146
145 // if there is no attached secondary tuner, we call set_params to program 147 // if there is no attached secondary tuner, we call set_params to program
@@ -168,6 +170,7 @@ static int zl10353_set_parameters(struct dvb_frontend *fe,
168 // even if there isn't a PLL attached to the secondary bus 170 // even if there isn't a PLL attached to the secondary bus
169 zl10353_write(fe, pllbuf, sizeof(pllbuf)); 171 zl10353_write(fe, pllbuf, sizeof(pllbuf));
170 172
173 zl10353_single_write(fe, 0x5F, 0x13);
171 zl10353_single_write(fe, 0x70, 0x01); 174 zl10353_single_write(fe, 0x70, 0x01);
172 udelay(250); 175 udelay(250);
173 zl10353_single_write(fe, 0xE4, 0x00); 176 zl10353_single_write(fe, 0xE4, 0x00);
@@ -243,9 +246,12 @@ static int zl10353_init(struct dvb_frontend *fe)
243 246
244 if (debug_regs) 247 if (debug_regs)
245 zl10353_dump_regs(fe); 248 zl10353_dump_regs(fe);
249 if (state->config.parallel_ts)
250 zl10353_reset_attach[2] &= ~0x20;
246 251
247 /* Do a "hard" reset if not already done */ 252 /* Do a "hard" reset if not already done */
248 if (zl10353_read_register(state, 0x50) != 0x03) { 253 if (zl10353_read_register(state, 0x50) != zl10353_reset_attach[1] ||
254 zl10353_read_register(state, 0x51) != zl10353_reset_attach[2]) {
249 rc = zl10353_write(fe, zl10353_reset_attach, 255 rc = zl10353_write(fe, zl10353_reset_attach,
250 sizeof(zl10353_reset_attach)); 256 sizeof(zl10353_reset_attach));
251 if (debug_regs) 257 if (debug_regs)
@@ -258,7 +264,6 @@ static int zl10353_init(struct dvb_frontend *fe)
258static void zl10353_release(struct dvb_frontend *fe) 264static void zl10353_release(struct dvb_frontend *fe)
259{ 265{
260 struct zl10353_state *state = fe->demodulator_priv; 266 struct zl10353_state *state = fe->demodulator_priv;
261
262 kfree(state); 267 kfree(state);
263} 268}
264 269
@@ -314,6 +319,7 @@ static struct dvb_frontend_ops zl10353_ops = {
314 319
315 .init = zl10353_init, 320 .init = zl10353_init,
316 .sleep = zl10353_sleep, 321 .sleep = zl10353_sleep,
322 .write = zl10353_write,
317 323
318 .set_frontend = zl10353_set_parameters, 324 .set_frontend = zl10353_set_parameters,
319 .get_tune_settings = zl10353_get_tune_settings, 325 .get_tune_settings = zl10353_get_tune_settings,
@@ -330,4 +336,3 @@ MODULE_AUTHOR("Chris Pascoe");
330MODULE_LICENSE("GPL"); 336MODULE_LICENSE("GPL");
331 337
332EXPORT_SYMBOL(zl10353_attach); 338EXPORT_SYMBOL(zl10353_attach);
333EXPORT_SYMBOL(zl10353_write);
diff --git a/drivers/media/dvb/frontends/zl10353.h b/drivers/media/dvb/frontends/zl10353.h
index 9770cb840cfc..79a947215c4d 100644
--- a/drivers/media/dvb/frontends/zl10353.h
+++ b/drivers/media/dvb/frontends/zl10353.h
@@ -31,11 +31,21 @@ struct zl10353_config
31 31
32 /* set if no pll is connected to the secondary i2c bus */ 32 /* set if no pll is connected to the secondary i2c bus */
33 int no_tuner; 33 int no_tuner;
34
35 /* set if parallel ts output is required */
36 int parallel_ts;
34}; 37};
35 38
39#if defined(CONFIG_DVB_ZL10353) || defined(CONFIG_DVB_ZL10353_MODULE)
36extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config, 40extern struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
37 struct i2c_adapter *i2c); 41 struct i2c_adapter *i2c);
38 42#else
39extern int zl10353_write(struct dvb_frontend *fe, u8 *ibuf, int ilen); 43static inline struct dvb_frontend* zl10353_attach(const struct zl10353_config *config,
44 struct i2c_adapter *i2c)
45{
46 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __FUNCTION__);
47 return NULL;
48}
49#endif // CONFIG_DVB_ZL10353
40 50
41#endif /* ZL10353_H */ 51#endif /* ZL10353_H */